aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Hsieh <andrewhsieh@google.com>2013-12-03 09:01:20 +0800
committerAndrew Hsieh <andrewhsieh@google.com>2013-12-03 09:01:20 +0800
commit4d3bdb33401f0a3285e7b3bbedd71d915473f188 (patch)
tree68fa1ab87f4944f3bc8f48795f635e84750e5ff8
parentb11ace66c20df98818ab423fb4af5041a16b6c5f (diff)
downloadtoolchain_gcc-4d3bdb33401f0a3285e7b3bbedd71d915473f188.tar.gz
toolchain_gcc-4d3bdb33401f0a3285e7b3bbedd71d915473f188.tar.bz2
toolchain_gcc-4d3bdb33401f0a3285e7b3bbedd71d915473f188.zip
Remove *.orig; update libgo testdata
1. *.orig files are artifact after patch 2. restore 3 testdata which were reset to zero-byte in last rebase Change-Id: I32e80c33349249cb11397b57698c2a241793652c
-rw-r--r--gcc-4.2.1/gcc/c.opt.orig928
-rw-r--r--gcc-4.2.1/gcc/cp/semantics.c.orig3953
-rw-r--r--gcc-4.8/gcc/collect2.c.orig3117
-rw-r--r--gcc-4.8/gcc/config.gcc.orig3843
-rw-r--r--gcc-4.8/gcc/config/arm/arm.c.orig27441
-rw-r--r--gcc-4.8/gcc/config/i386/i386.c.orig42870
-rw-r--r--gcc-4.8/gcc/config/i386/i386.md.orig18173
-rw-r--r--gcc-4.8/gcc/configure.ac.orig5352
-rwxr-xr-xgcc-4.8/gcc/configure.orig28807
-rw-r--r--gcc-4.8/gcc/doc/invoke.texi.orig21078
-rw-r--r--gcc-4.8/libgcc/config.host.orig1170
-rw-r--r--gcc-4.8/libgo/go/archive/tar/testdata/pax.tarbin0 -> 10240 bytes
-rw-r--r--gcc-4.8/libgo/go/archive/tar/testdata/ustar.tarbin0 -> 2048 bytes
-rw-r--r--gcc-4.8/libgo/go/archive/zip/testdata/test-trailing-junk.zipbin0 -> 1184 bytes
14 files changed, 0 insertions, 156732 deletions
diff --git a/gcc-4.2.1/gcc/c.opt.orig b/gcc-4.2.1/gcc/c.opt.orig
deleted file mode 100644
index 0d26a8047..000000000
--- a/gcc-4.2.1/gcc/c.opt.orig
+++ /dev/null
@@ -1,928 +0,0 @@
-; Options for the C, ObjC, C++ and ObjC++ front ends.
-; Copyright (C) 2003, 2004, 2005, 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 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.
-
-; See the GCC internals manual for a description of this file's format.
-
-; Please try to keep this file in ASCII collating order.
-
-Language
-C
-
-Language
-ObjC
-
-Language
-C++
-
-Language
-ObjC++
-
--output-pch=
-C ObjC C++ ObjC++ Joined Separate
-
-A
-C ObjC C++ ObjC++ Joined Separate
--A<question>=<answer> Assert the <answer> to <question>. Putting '-' before <question> disables the <answer> to <question>
-
-C
-C ObjC C++ ObjC++
-Do not discard comments
-
-CC
-C ObjC C++ ObjC++
-Do not discard comments in macro expansions
-
-D
-C ObjC C++ ObjC++ Joined Separate
--D<macro>[=<val>] Define a <macro> with <val> as its value. If just <macro> is given, <val> is taken to be 1
-
-E
-C ObjC C++ ObjC++ Undocumented
-
-F
-C ObjC C++ ObjC++ Joined Separate
--F <dir> Add <dir> to the end of the main framework include path
-
-H
-C ObjC C++ ObjC++
-Print the name of header files as they are used
-
-I
-C ObjC C++ ObjC++ Joined Separate
--I <dir> Add <dir> to the end of the main include path
-
-M
-C ObjC C++ ObjC++
-Generate make dependencies
-
-MD
-C ObjC C++ ObjC++ Separate
-Generate make dependencies and compile
-
-MF
-C ObjC C++ ObjC++ Joined Separate
--MF <file> Write dependency output to the given file
-
-MG
-C ObjC C++ ObjC++
-Treat missing header files as generated files
-
-MM
-C ObjC C++ ObjC++
-Like -M but ignore system header files
-
-MMD
-C ObjC C++ ObjC++ Separate
-Like -MD but ignore system header files
-
-MP
-C ObjC C++ ObjC++
-Generate phony targets for all headers
-
-MQ
-C ObjC C++ ObjC++ Joined Separate
--MQ <target> Add a MAKE-quoted target
-
-MT
-C ObjC C++ ObjC++ Joined Separate
--MT <target> Add an unquoted target
-
-P
-C ObjC C++ ObjC++
-Do not generate #line directives
-
-U
-C ObjC C++ ObjC++ Joined Separate
--U<macro> Undefine <macro>
-
-Wabi
-C++ ObjC++ Var(warn_abi)
-Warn about things that will change when compiling with an ABI-compliant compiler
-
-Waddress
-C ObjC C++ ObjC++ Var(warn_address)
-Warn about suspicious uses of memory addresses
-
-Wall
-C ObjC C++ ObjC++
-Enable most warning messages
-
-Wassign-intercept
-ObjC ObjC++ Var(warn_assign_intercept)
-Warn whenever an Objective-C assignment is being intercepted by the garbage collector
-
-Wbad-function-cast
-C ObjC Var(warn_bad_function_cast)
-Warn about casting functions to incompatible types
-
-Wc++-compat
-C ObjC Var(warn_cxx_compat)
-Warn about C constructs that are not in the common subset of C and C++
-
-
-Wcast-qual
-C ObjC C++ ObjC++ Var(warn_cast_qual)
-Warn about casts which discard qualifiers
-
-Wchar-subscripts
-C ObjC C++ ObjC++ Var(warn_char_subscripts)
-Warn about subscripts whose type is \"char\"
-
-Wcomment
-C ObjC C++ ObjC++
-Warn about possibly nested block comments, and C++ comments spanning more than one physical line
-
-Wcomments
-C ObjC C++ ObjC++
-Synonym for -Wcomment
-
-Wconversion
-C ObjC C++ ObjC++ Var(warn_conversion)
-Warn about possibly confusing type conversions
-
-Wctor-dtor-privacy
-C++ ObjC++ Var(warn_ctor_dtor_privacy)
-Warn when all constructors and destructors are private
-
-Wdeclaration-after-statement
-C ObjC Var(warn_declaration_after_statement)
-Warn when a declaration is found after a statement
-
-Wdeprecated
-C++ ObjC++ Var(warn_deprecated) Init(1)
-Warn about deprecated compiler features
-
-Wdiv-by-zero
-C ObjC C++ ObjC++ Var(warn_div_by_zero) Init(1)
-Warn about compile-time integer division by zero
-
-Weffc++
-C++ ObjC++ Var(warn_ecpp)
-Warn about violations of Effective C++ style rules
-
-Wendif-labels
-C ObjC C++ ObjC++
-Warn about stray tokens after #elif and #endif
-
-Werror
-C ObjC C++ ObjC++
-; Documented in common.opt
-
-Werror-implicit-function-declaration
-C ObjC RejectNegative
-Make implicit function declarations an error
-
-Wfloat-equal
-C ObjC C++ ObjC++ Var(warn_float_equal)
-Warn if testing floating point numbers for equality
-
-Wformat
-C ObjC C++ ObjC++
-Warn about printf/scanf/strftime/strfmon format string anomalies
-
-Wformat-extra-args
-C ObjC C++ ObjC++ Var(warn_format_extra_args)
-Warn if passing too many arguments to a function for its format string
-
-Wformat-nonliteral
-C ObjC C++ ObjC++ Var(warn_format_nonliteral)
-Warn about format strings that are not literals
-
-Wformat-security
-C ObjC C++ ObjC++ Var(warn_format_security)
-Warn about possible security problems with format functions
-
-Wformat-y2k
-C ObjC C++ ObjC++ Var(warn_format_y2k)
-Warn about strftime formats yielding 2-digit years
-
-Wformat-zero-length
-C ObjC Var(warn_format_zero_length)
-Warn about zero-length formats
-
-Wformat=
-C ObjC C++ ObjC++ Joined
-
-Winit-self
-C ObjC C++ ObjC++ Var(warn_init_self)
-Warn about variables which are initialized to themselves
-
-Wimplicit
-C ObjC C++ ObjC++
-
-Wimplicit-function-declaration
-C ObjC Var(mesg_implicit_function_declaration) Init(-1)
-Warn about implicit function declarations
-
-Wimplicit-int
-C ObjC Var(warn_implicit_int)
-Warn when a declaration does not specify a type
-
-Wimport
-C ObjC C++ ObjC++
-Deprecated. This switch has no effect
-
-Wint-to-pointer-cast
-C ObjC Var(warn_int_to_pointer_cast) Init(1)
-Warn when there is a cast to a pointer from an integer of a different size
-
-Winvalid-offsetof
-C++ ObjC++ Var(warn_invalid_offsetof) Init(1)
-Warn about invalid uses of the \"offsetof\" macro
-
-Winvalid-pch
-C ObjC C++ ObjC++
-Warn about PCH files that are found but not used
-
-Wlong-long
-C ObjC C++ ObjC++ Var(warn_long_long) Init(1)
-Do not warn about using \"long long\" when -pedantic
-
-Wmain
-C ObjC
-Warn about suspicious declarations of \"main\"
-
-Wmissing-braces
-C ObjC C++ ObjC++ Var(warn_missing_braces)
-Warn about possibly missing braces around initializers
-
-Wmissing-declarations
-C ObjC Var(warn_missing_declarations)
-Warn about global functions without previous declarations
-
-Wmissing-field-initializers
-C ObjC C++ ObjC++ Var(warn_missing_field_initializers) Init(-1)
-Warn about missing fields in struct initializers
-
-Wmissing-format-attribute
-C ObjC C++ ObjC++ Var(warn_missing_format_attribute)
-Warn about functions which might be candidates for format attributes
-
-Wmissing-include-dirs
-C ObjC C++ ObjC++
-Warn about user-specified include directories that do not exist
-
-Wmissing-prototypes
-C ObjC Var(warn_missing_prototypes)
-Warn about global functions without prototypes
-
-Wmultichar
-C ObjC C++ ObjC++
-Warn about use of multi-character character constants
-
-Wnested-externs
-C ObjC Var(warn_nested_externs)
-Warn about \"extern\" declarations not at file scope
-
-Wnon-template-friend
-C++ ObjC++ Var(warn_nontemplate_friend) Init(1)
-Warn when non-templatized friend functions are declared within a template
-
-Wnon-virtual-dtor
-C++ ObjC++ Var(warn_nonvdtor)
-Warn about non-virtual destructors
-
-Wnonnull
-C ObjC Var(warn_nonnull)
-Warn about NULL being passed to argument slots marked as requiring non-NULL
-
-Wnormalized=
-C ObjC C++ ObjC++ Joined
--Wnormalized=<id|nfc|nfkc> Warn about non-normalised Unicode strings
-
-Wold-style-cast
-C++ ObjC++ Var(warn_old_style_cast)
-Warn if a C-style cast is used in a program
-
-Wold-style-definition
-C ObjC Var(warn_old_style_definition)
-Warn if an old-style parameter definition is used
-
-Woverlength-strings
-C ObjC C++ ObjC++ Var(warn_overlength_strings) Init(-1)
-Warn if a string is longer than the maximum portable length specified by the standard
-
-Woverloaded-virtual
-C++ ObjC++ Var(warn_overloaded_virtual)
-Warn about overloaded virtual function names
-
-Woverride-init
-C ObjC Var(warn_override_init) Init(-1)
-Warn about overriding initializers without side effects
-
-Wparentheses
-C ObjC C++ ObjC++ Var(warn_parentheses)
-Warn about possibly missing parentheses
-
-Wpmf-conversions
-C++ ObjC++ Var(warn_pmf2ptr) Init(1)
-Warn when converting the type of pointers to member functions
-
-Wpointer-arith
-C ObjC C++ ObjC++ Var(warn_pointer_arith)
-Warn about function pointer arithmetic
-
-Wpointer-to-int-cast
-C ObjC Var(warn_pointer_to_int_cast) Init(1)
-Warn when a pointer is cast to an integer of a different size
-
-Wpragmas
-C ObjC C++ ObjC++ Var(warn_pragmas) Init(1)
-Warn about misuses of pragmas
-
-Wprotocol
-ObjC ObjC++ Var(warn_protocol) Init(1)
-Warn if inherited methods are unimplemented
-
-Wredundant-decls
-C ObjC C++ ObjC++ Var(warn_redundant_decls)
-Warn about multiple declarations of the same object
-
-Wreorder
-C++ ObjC++ Var(warn_reorder)
-Warn when the compiler reorders code
-
-Wreturn-type
-C ObjC C++ ObjC++ Var(warn_return_type)
-Warn whenever a function's return type defaults to \"int\" (C), or about inconsistent return types (C++)
-
-Wselector
-ObjC ObjC++ Var(warn_selector)
-Warn if a selector has multiple methods
-
-Wsequence-point
-C ObjC C++ ObjC++ Var(warn_sequence_point)
-Warn about possible violations of sequence point rules
-
-Wsign-compare
-C ObjC C++ ObjC++ Var(warn_sign_compare) Init(-1)
-Warn about signed-unsigned comparisons
-
-Wsign-promo
-C++ ObjC++ Var(warn_sign_promo)
-Warn when overload promotes from unsigned to signed
-
-Wstrict-null-sentinel
-C++ ObjC++
-Warn about uncasted NULL used as sentinel
-
-Wstrict-prototypes
-C ObjC Var(warn_strict_prototypes)
-Warn about unprototyped function declarations
-
-Wstrict-selector-match
-ObjC ObjC++ Var(warn_strict_selector_match)
-Warn if type signatures of candidate methods do not match exactly
-
-Wsynth
-C++ ObjC++ Var(warn_synth)
-Warn when synthesis behavior differs from Cfront
-
-Wsystem-headers
-C ObjC C++ ObjC++
-Do not suppress warnings from system headers
-
-Wtraditional
-C ObjC Var(warn_traditional)
-Warn about features not present in traditional C
-
-Wtrigraphs
-C ObjC C++ ObjC++
-Warn if trigraphs are encountered that might affect the meaning of the program
-
-Wundeclared-selector
-ObjC ObjC++ Var(warn_undeclared_selector)
-Warn about @selector()s without previously declared methods
-
-Wundef
-C ObjC C++ ObjC++
-Warn if an undefined macro is used in an #if directive
-
-Wunknown-pragmas
-C ObjC C++ ObjC++
-Warn about unrecognized pragmas
-
-Wunused-macros
-C ObjC C++ ObjC++
-Warn about macros defined in the main file that are not used
-
-Wvariadic-macros
-C ObjC C++ ObjC++
-Do not warn about using variadic macros when -pedantic
-
-Wvla
-C ObjC C++ ObjC++ Var(warn_vla) Init(-1) Warning
-Warn if a variable length array is used
-
-Wwrite-strings
-C ObjC C++ ObjC++ Var(warn_write_strings)
-In C++, nonzero means warn about deprecated conversion from string literals to `char *'. In C, similar warning, except that the conversion is of course not deprecated by the ISO C standard.
-
-Wpointer-sign
-C ObjC Var(warn_pointer_sign) Init(-1)
-Warn when a pointer differs in signedness in an assignment
-
-ansi
-C ObjC C++ ObjC++
-A synonym for -std=c89 (for C) or -std=c++98 (for C++)
-
-d
-C ObjC C++ ObjC++ Joined
-; Documented in common.opt. FIXME - what about -dI, -dD, -dN and -dD?
-
-faccess-control
-C++ ObjC++
-Enforce class member access control semantics
-
-fall-virtual
-C++ ObjC++
-
-falt-external-templates
-C++ ObjC++
-Change when template instances are emitted
-
-fasm
-C ObjC C++ ObjC++
-Recognize the \"asm\" keyword
-
-fbuiltin
-C ObjC C++ ObjC++
-Recognize built-in functions
-
-fbuiltin-
-C ObjC C++ ObjC++ Joined
-
-fcheck-new
-C++ ObjC++
-Check the return value of new
-
-fcond-mismatch
-C ObjC C++ ObjC++
-Allow the arguments of the '?' operator to have different types
-
-fconserve-space
-C++ ObjC++
-Reduce the size of object files
-
-fconstant-string-class=
-ObjC ObjC++ Joined
--fconst-string-class=<name> Use class <name> for constant strings
-
-fdefault-inline
-C++ ObjC++
-Inline member functions by default
-
-fdirectives-only
-C ObjC C++ ObjC++
-Preprocess directives only.
-
-fdollars-in-identifiers
-C ObjC C++ ObjC++
-Permit '$' as an identifier character
-
-felide-constructors
-C++ ObjC++
-
-fenforce-eh-specs
-C++ ObjC++
-Generate code to check exception specifications
-
-fenum-int-equiv
-C++ ObjC++
-
-fexec-charset=
-C ObjC C++ ObjC++ Joined RejectNegative
--fexec-charset=<cset> Convert all strings and character constants to character set <cset>
-
-fextended-identifiers
-C ObjC C++ ObjC++
-Permit universal character names (\\u and \\U) in identifiers
-
-finput-charset=
-C ObjC C++ ObjC++ Joined RejectNegative
--finput-charset=<cset> Specify the default character set for source files
-
-
-fexternal-templates
-C++ ObjC++
-
-ffor-scope
-C++ ObjC++
-Scope of for-init-statement variables is local to the loop
-
-ffreestanding
-C ObjC
-Do not assume that standard C libraries and \"main\" exist
-
-fgnu-keywords
-C++ ObjC++
-Recognize GNU-defined keywords
-
-fgnu-runtime
-ObjC ObjC++
-Generate code for GNU runtime environment
-
-fgnu89-inline
-C ObjC Var(flag_gnu89_inline) Init(-1)
-Use traditional GNU semantics for inline functions
-
-fguiding-decls
-C++ ObjC++
-
-fhandle-exceptions
-C++ ObjC++
-
-fhonor-std
-C++ ObjC++
-
-fhosted
-C ObjC
-Assume normal C execution environment
-
-fhuge-objects
-C++ ObjC++
-Enable support for huge objects
-
-fimplement-inlines
-C++ ObjC++
-Export functions even if they can be inlined
-
-fimplicit-inline-templates
-C++ ObjC++
-Emit implicit instantiations of inline templates
-
-fimplicit-templates
-C++ ObjC++
-Emit implicit instantiations of templates
-
-ffriend-injection
-C++ ObjC++ Var(flag_friend_injection)
-Inject friend functions into enclosing namespace
-
-flabels-ok
-C++ ObjC++
-
-fms-extensions
-C ObjC C++ ObjC++
-Don't warn about uses of Microsoft extensions
-
-fname-mangling-version-
-C++ ObjC++ Joined
-
-fnew-abi
-C++ ObjC++
-
-fnext-runtime
-ObjC ObjC++
-Generate code for NeXT (Apple Mac OS X) runtime environment
-
-fnil-receivers
-ObjC ObjC++
-Assume that receivers of Objective-C messages may be nil
-
-fnonansi-builtins
-C++ ObjC++
-
-fnonnull-objects
-C++ ObjC++
-
-; Generate special '- .cxx_construct' and '- .cxx_destruct' methods
-; to initialize any non-POD ivars in Objective-C++ classes.
-fobjc-call-cxx-cdtors
-ObjC++ Var(flag_objc_call_cxx_cdtors)
-Generate special Objective-C methods to initialize/destroy non-POD C++ ivars, if needed
-
-fobjc-direct-dispatch
-ObjC ObjC++ Var(flag_objc_direct_dispatch)
-Allow fast jumps to the message dispatcher
-
-; Nonzero means that we will allow new ObjC exception syntax (@throw,
-; @try, etc.) in source code.
-fobjc-exceptions
-ObjC ObjC++ Var(flag_objc_exceptions)
-Enable Objective-C exception and synchronization syntax
-
-fobjc-gc
-ObjC ObjC++ Var(flag_objc_gc)
-Enable garbage collection (GC) in Objective-C/Objective-C++ programs
-
-; Nonzero means that we generate NeXT setjmp based exceptions.
-fobjc-sjlj-exceptions
-ObjC ObjC++ Var(flag_objc_sjlj_exceptions) Init(-1)
-Enable Objective-C setjmp exception handling runtime
-
-fopenmp
-C ObjC C++ ObjC++ Var(flag_openmp)
-Enable OpenMP
-
-foperator-names
-C++ ObjC++
-Recognize C++ kewords like \"compl\" and \"xor\"
-
-foptional-diags
-C++ ObjC++
-Enable optional diagnostics
-
-fpch-deps
-C ObjC C++ ObjC++
-
-fpch-preprocess
-C ObjC C++ ObjC++
-Look for and use PCH files even when preprocessing
-
-fpermissive
-C++ ObjC++
-Downgrade conformance errors to warnings
-
-fpreprocessed
-C ObjC C++ ObjC++
-Treat the input file as already preprocessed
-
-freplace-objc-classes
-ObjC ObjC++
-Used in Fix-and-Continue mode to indicate that object files may be swapped in at runtime
-
-frepo
-C++ ObjC++
-Enable automatic template instantiation
-
-frtti
-C++ ObjC++
-Generate run time type descriptor information
-
-fshort-double
-C ObjC C++ ObjC++
-Use the same size for double as for float
-
-fshort-enums
-C ObjC C++ ObjC++
-Use the narrowest integer type possible for enumeration types
-
-fshort-wchar
-C ObjC C++ ObjC++
-Force the underlying type for \"wchar_t\" to be \"unsigned short\"
-
-fsigned-bitfields
-C ObjC C++ ObjC++
-When \"signed\" or \"unsigned\" is not given make the bitfield signed
-
-fsigned-char
-C ObjC C++ ObjC++
-Make \"char\" signed by default
-
-fsquangle
-C++ ObjC++
-
-fstats
-C++ ObjC++
-Display statistics accumulated during compilation
-
-fstrict-prototype
-C++ ObjC++
-
-ftabstop=
-C ObjC C++ ObjC++ Joined RejectNegative UInteger
--ftabstop=<number> Distance between tab stops for column reporting
-
-ftemplate-depth-
-C++ ObjC++ Joined RejectNegative UInteger
--ftemplate-depth-<number> Specify maximum template instantiation depth
-
-fthis-is-variable
-C++ ObjC++
-
-fthreadsafe-statics
-C++ ObjC++
--fno-threadsafe-statics Do not generate thread-safe code for initializing local statics
-
-funsigned-bitfields
-C ObjC C++ ObjC++
-When \"signed\" or \"unsigned\" is not given make the bitfield unsigned
-
-funsigned-char
-C ObjC C++ ObjC++
-Make \"char\" unsigned by default
-
-fuse-cxa-atexit
-C++ ObjC++
-Use __cxa_atexit to register destructors
-
-fuse-cxa-get-exception-ptr
-C++ ObjC++
-Use __cxa_get_exception_ptr in exception handling
-
-fvisibility-inlines-hidden
-C++ ObjC++
-Marks all inlined methods as having hidden visibility
-
-fvtable-gc
-C++ ObjC++
-Discard unused virtual functions
-
-fvtable-thunks
-C++ ObjC++
-Implement vtables using thunks
-
-fweak
-C++ ObjC++
-Emit common-like symbols as weak symbols
-
-fwide-exec-charset=
-C ObjC C++ ObjC++ Joined RejectNegative
--fwide-exec-charset=<cset> Convert all wide strings and character constants to character set <cset>
-
-fworking-directory
-C ObjC C++ ObjC++
-Generate a #line directive pointing at the current working directory
-
-fxref
-C++ ObjC++
-Emit cross referencing information
-
-fzero-link
-ObjC ObjC++
-Generate lazy class lookup (via objc_getClass()) for use in Zero-Link mode
-
-gen-decls
-ObjC ObjC++
-Dump declarations to a .decl file
-
-femit-struct-debug-baseonly
-C ObjC C++ ObjC++
--femit-struct-debug-baseonly Aggressive reduced debug info for structs
-
-femit-struct-debug-reduced
-C ObjC C++ ObjC++
--femit-struct-debug-reduced Conservative reduced debug info for structs
-
-femit-struct-debug-detailed=
-C ObjC C++ ObjC++ Joined
--femit-struct-debug-detailed=<spec-list> Detailed reduced debug info for structs
-
-idirafter
-C ObjC C++ ObjC++ Joined Separate
--idirafter <dir> Add <dir> to the end of the system include path
-
-imacros
-C ObjC C++ ObjC++ Joined Separate
--imacros <file> Accept definition of macros in <file>
-
-imultilib
-C ObjC C++ ObjC++ Joined Separate
--imultilib <dir> Set <dir> to be the multilib include subdirectory
-
-include
-C ObjC C++ ObjC++ Joined Separate
--include <file> Include the contents of <file> before other files
-
-iprefix
-C ObjC C++ ObjC++ Joined Separate
--iprefix <path> Specify <path> as a prefix for next two options
-
-isysroot
-C ObjC C++ ObjC++ Joined Separate
--isysroot <dir> Set <dir> to be the system root directory
-
-isystem
-C ObjC C++ ObjC++ Joined Separate
--isystem <dir> Add <dir> to the start of the system include path
-
-iquote
-C ObjC C++ ObjC++ Joined Separate
--iquote <dir> Add <dir> to the end of the quote include path
-
-iwithprefix
-C ObjC C++ ObjC++ Joined Separate
--iwithprefix <dir> Add <dir> to the end of the system include path
-
-iwithprefixbefore
-C ObjC C++ ObjC++ Joined Separate
--iwithprefixbefore <dir> Add <dir> to the end of the main include path
-
-lang-asm
-C Undocumented
-
-lang-fortran
-C Undocumented
-
-lang-objc
-C ObjC C++ ObjC++ Undocumented
-
-nostdinc
-C ObjC C++ ObjC++
-Do not search standard system include directories (those specified with -isystem will still be used)
-
-nostdinc++
-C++ ObjC++
-Do not search standard system include directories for C++
-
-o
-C ObjC C++ ObjC++ Joined Separate
-; Documented in common.opt
-
-pedantic
-C ObjC C++ ObjC++
-; Documented in common.opt
-
-pedantic-errors
-C ObjC C++ ObjC++
-; Documented in common.opt
-
-print-objc-runtime-info
-ObjC ObjC++
-Generate C header of platform-specific features
-
-print-pch-checksum
-C ObjC C++ ObjC++
-Print a checksum of the executable for PCH validity checking, and stop
-
-remap
-C ObjC C++ ObjC++
-Remap file names when including files
-
-std=c++98
-C++ ObjC++
-Conform to the ISO 1998 C++ standard
-
-std=c89
-C ObjC
-Conform to the ISO 1990 C standard
-
-std=c99
-C ObjC
-Conform to the ISO 1999 C standard
-
-std=c9x
-C ObjC
-Deprecated in favor of -std=c99
-
-std=gnu++98
-C++ ObjC++
-Conform to the ISO 1998 C++ standard with GNU extensions
-
-std=gnu89
-C ObjC
-Conform to the ISO 1990 C standard with GNU extensions
-
-std=gnu99
-C ObjC
-Conform to the ISO 1999 C standard with GNU extensions
-
-std=gnu9x
-C ObjC
-Deprecated in favor of -std=gnu99
-
-std=iso9899:1990
-C ObjC
-Conform to the ISO 1990 C standard
-
-std=iso9899:199409
-C ObjC
-Conform to the ISO 1990 C standard as amended in 1994
-
-std=iso9899:1999
-C ObjC
-Conform to the ISO 1999 C standard
-
-std=iso9899:199x
-C ObjC
-Deprecated in favor of -std=iso9899:1999
-
-traditional-cpp
-C ObjC C++ ObjC++
-Enable traditional preprocessing
-
-trigraphs
-C ObjC C++ ObjC++
--trigraphs Support ISO C trigraphs
-
-undef
-C ObjC C++ ObjC++
-Do not predefine system-specific and GCC-specific macros
-
-v
-C ObjC C++ ObjC++
-Enable verbose output
-
-w
-C ObjC C++ ObjC++
-; Documented in common.opt
-
-; This comment is to ensure we retain the blank line above.
diff --git a/gcc-4.2.1/gcc/cp/semantics.c.orig b/gcc-4.2.1/gcc/cp/semantics.c.orig
deleted file mode 100644
index 7c8054f24..000000000
--- a/gcc-4.2.1/gcc/cp/semantics.c.orig
+++ /dev/null
@@ -1,3953 +0,0 @@
-/* Perform the semantic phase of parsing, i.e., the process of
- building tree structure, checking semantic consistency, and
- building RTL. These routines are used both during actual parsing
- and during the instantiation of template functions.
-
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
- Free Software Foundation, Inc.
- Written by Mark Mitchell (mmitchell@usa.net) based on code found
- formerly in parse.y and pt.c.
-
- 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. */
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "tm.h"
-#include "tree.h"
-#include "cp-tree.h"
-#include "c-common.h"
-#include "tree-inline.h"
-#include "tree-mudflap.h"
-#include "except.h"
-#include "toplev.h"
-#include "flags.h"
-#include "rtl.h"
-#include "expr.h"
-#include "output.h"
-#include "timevar.h"
-#include "debug.h"
-#include "diagnostic.h"
-#include "cgraph.h"
-#include "tree-iterator.h"
-#include "vec.h"
-#include "target.h"
-
-/* There routines provide a modular interface to perform many parsing
- operations. They may therefore be used during actual parsing, or
- during template instantiation, which may be regarded as a
- degenerate form of parsing. */
-
-static tree maybe_convert_cond (tree);
-static tree simplify_aggr_init_exprs_r (tree *, int *, void *);
-static void emit_associated_thunks (tree);
-static tree finalize_nrv_r (tree *, int *, void *);
-
-
-/* Deferred Access Checking Overview
- ---------------------------------
-
- Most C++ expressions and declarations require access checking
- to be performed during parsing. However, in several cases,
- this has to be treated differently.
-
- For member declarations, access checking has to be deferred
- until more information about the declaration is known. For
- example:
-
- class A {
- typedef int X;
- public:
- X f();
- };
-
- A::X A::f();
- A::X g();
-
- When we are parsing the function return type `A::X', we don't
- really know if this is allowed until we parse the function name.
-
- Furthermore, some contexts require that access checking is
- never performed at all. These include class heads, and template
- instantiations.
-
- Typical use of access checking functions is described here:
-
- 1. When we enter a context that requires certain access checking
- mode, the function `push_deferring_access_checks' is called with
- DEFERRING argument specifying the desired mode. Access checking
- may be performed immediately (dk_no_deferred), deferred
- (dk_deferred), or not performed (dk_no_check).
-
- 2. When a declaration such as a type, or a variable, is encountered,
- the function `perform_or_defer_access_check' is called. It
- maintains a VEC of all deferred checks.
-
- 3. The global `current_class_type' or `current_function_decl' is then
- setup by the parser. `enforce_access' relies on these information
- to check access.
-
- 4. Upon exiting the context mentioned in step 1,
- `perform_deferred_access_checks' is called to check all declaration
- stored in the VEC. `pop_deferring_access_checks' is then
- called to restore the previous access checking mode.
-
- In case of parsing error, we simply call `pop_deferring_access_checks'
- without `perform_deferred_access_checks'. */
-
-typedef struct deferred_access GTY(())
-{
- /* A VEC representing name-lookups for which we have deferred
- checking access controls. We cannot check the accessibility of
- names used in a decl-specifier-seq until we know what is being
- declared because code like:
-
- class A {
- class B {};
- B* f();
- }
-
- A::B* A::f() { return 0; }
-
- is valid, even though `A::B' is not generally accessible. */
- VEC (deferred_access_check,gc)* GTY(()) deferred_access_checks;
-
- /* The current mode of access checks. */
- enum deferring_kind deferring_access_checks_kind;
-
-} deferred_access;
-DEF_VEC_O (deferred_access);
-DEF_VEC_ALLOC_O (deferred_access,gc);
-
-/* Data for deferred access checking. */
-static GTY(()) VEC(deferred_access,gc) *deferred_access_stack;
-static GTY(()) unsigned deferred_access_no_check;
-
-/* Save the current deferred access states and start deferred
- access checking iff DEFER_P is true. */
-
-void
-push_deferring_access_checks (deferring_kind deferring)
-{
- /* For context like template instantiation, access checking
- disabling applies to all nested context. */
- if (deferred_access_no_check || deferring == dk_no_check)
- deferred_access_no_check++;
- else
- {
- deferred_access *ptr;
-
- ptr = VEC_safe_push (deferred_access, gc, deferred_access_stack, NULL);
- ptr->deferred_access_checks = NULL;
- ptr->deferring_access_checks_kind = deferring;
- }
-}
-
-/* Resume deferring access checks again after we stopped doing
- this previously. */
-
-void
-resume_deferring_access_checks (void)
-{
- if (!deferred_access_no_check)
- VEC_last (deferred_access, deferred_access_stack)
- ->deferring_access_checks_kind = dk_deferred;
-}
-
-/* Stop deferring access checks. */
-
-void
-stop_deferring_access_checks (void)
-{
- if (!deferred_access_no_check)
- VEC_last (deferred_access, deferred_access_stack)
- ->deferring_access_checks_kind = dk_no_deferred;
-}
-
-/* Discard the current deferred access checks and restore the
- previous states. */
-
-void
-pop_deferring_access_checks (void)
-{
- if (deferred_access_no_check)
- deferred_access_no_check--;
- else
- VEC_pop (deferred_access, deferred_access_stack);
-}
-
-/* Returns a TREE_LIST representing the deferred checks.
- The TREE_PURPOSE of each node is the type through which the
- access occurred; the TREE_VALUE is the declaration named.
- */
-
-VEC (deferred_access_check,gc)*
-get_deferred_access_checks (void)
-{
- if (deferred_access_no_check)
- return NULL;
- else
- return (VEC_last (deferred_access, deferred_access_stack)
- ->deferred_access_checks);
-}
-
-/* Take current deferred checks and combine with the
- previous states if we also defer checks previously.
- Otherwise perform checks now. */
-
-void
-pop_to_parent_deferring_access_checks (void)
-{
- if (deferred_access_no_check)
- deferred_access_no_check--;
- else
- {
- VEC (deferred_access_check,gc) *checks;
- deferred_access *ptr;
-
- checks = (VEC_last (deferred_access, deferred_access_stack)
- ->deferred_access_checks);
-
- VEC_pop (deferred_access, deferred_access_stack);
- ptr = VEC_last (deferred_access, deferred_access_stack);
- if (ptr->deferring_access_checks_kind == dk_no_deferred)
- {
- /* Check access. */
- perform_access_checks (checks);
- }
- else
- {
- /* Merge with parent. */
- int i, j;
- deferred_access_check *chk, *probe;
-
- for (i = 0 ;
- VEC_iterate (deferred_access_check, checks, i, chk) ;
- ++i)
- {
- for (j = 0 ;
- VEC_iterate (deferred_access_check,
- ptr->deferred_access_checks, j, probe) ;
- ++j)
- {
- if (probe->binfo == chk->binfo &&
- probe->decl == chk->decl &&
- probe->diag_decl == chk->diag_decl)
- goto found;
- }
- /* Insert into parent's checks. */
- VEC_safe_push (deferred_access_check, gc,
- ptr->deferred_access_checks, chk);
- found:;
- }
- }
- }
-}
-
-/* Perform the access checks in CHECKS. The TREE_PURPOSE of each node
- is the BINFO indicating the qualifying scope used to access the
- DECL node stored in the TREE_VALUE of the node. */
-
-void
-perform_access_checks (VEC (deferred_access_check,gc)* checks)
-{
- int i;
- deferred_access_check *chk;
-
- if (!checks)
- return;
-
- for (i = 0 ; VEC_iterate (deferred_access_check, checks, i, chk) ; ++i)
- enforce_access (chk->binfo, chk->decl, chk->diag_decl);
-}
-
-/* Perform the deferred access checks.
-
- After performing the checks, we still have to keep the list
- `deferred_access_stack->deferred_access_checks' since we may want
- to check access for them again later in a different context.
- For example:
-
- class A {
- typedef int X;
- static X a;
- };
- A::X A::a, x; // No error for `A::a', error for `x'
-
- We have to perform deferred access of `A::X', first with `A::a',
- next with `x'. */
-
-void
-perform_deferred_access_checks (void)
-{
- perform_access_checks (get_deferred_access_checks ());
-}
-
-/* Defer checking the accessibility of DECL, when looked up in
- BINFO. DIAG_DECL is the declaration to use to print diagnostics. */
-
-void
-perform_or_defer_access_check (tree binfo, tree decl, tree diag_decl)
-{
- int i;
- deferred_access *ptr;
- deferred_access_check *chk;
- deferred_access_check *new_access;
-
-
- /* Exit if we are in a context that no access checking is performed.
- */
- if (deferred_access_no_check)
- return;
-
- gcc_assert (TREE_CODE (binfo) == TREE_BINFO);
-
- ptr = VEC_last (deferred_access, deferred_access_stack);
-
- /* If we are not supposed to defer access checks, just check now. */
- if (ptr->deferring_access_checks_kind == dk_no_deferred)
- {
- enforce_access (binfo, decl, diag_decl);
- return;
- }
-
- /* See if we are already going to perform this check. */
- for (i = 0 ;
- VEC_iterate (deferred_access_check,
- ptr->deferred_access_checks, i, chk) ;
- ++i)
- {
- if (chk->decl == decl && chk->binfo == binfo &&
- chk->diag_decl == diag_decl)
- {
- return;
- }
- }
- /* If not, record the check. */
- new_access =
- VEC_safe_push (deferred_access_check, gc,
- ptr->deferred_access_checks, 0);
- new_access->binfo = binfo;
- new_access->decl = decl;
- new_access->diag_decl = diag_decl;
-}
-
-/* Returns nonzero if the current statement is a full expression,
- i.e. temporaries created during that statement should be destroyed
- at the end of the statement. */
-
-int
-stmts_are_full_exprs_p (void)
-{
- return current_stmt_tree ()->stmts_are_full_exprs_p;
-}
-
-/* T is a statement. Add it to the statement-tree. This is the C++
- version. The C/ObjC frontends have a slightly different version of
- this function. */
-
-tree
-add_stmt (tree t)
-{
- enum tree_code code = TREE_CODE (t);
-
- if (EXPR_P (t) && code != LABEL_EXPR)
- {
- if (!EXPR_HAS_LOCATION (t))
- SET_EXPR_LOCATION (t, input_location);
-
- /* When we expand a statement-tree, we must know whether or not the
- statements are full-expressions. We record that fact here. */
- STMT_IS_FULL_EXPR_P (t) = stmts_are_full_exprs_p ();
- }
-
- /* Add T to the statement-tree. Non-side-effect statements need to be
- recorded during statement expressions. */
- append_to_statement_list_force (t, &cur_stmt_list);
-
- return t;
-}
-
-/* Returns the stmt_tree (if any) to which statements are currently
- being added. If there is no active statement-tree, NULL is
- returned. */
-
-stmt_tree
-current_stmt_tree (void)
-{
- return (cfun
- ? &cfun->language->base.x_stmt_tree
- : &scope_chain->x_stmt_tree);
-}
-
-/* If statements are full expressions, wrap STMT in a CLEANUP_POINT_EXPR. */
-
-static tree
-maybe_cleanup_point_expr (tree expr)
-{
- if (!processing_template_decl && stmts_are_full_exprs_p ())
- expr = fold_build_cleanup_point_expr (TREE_TYPE (expr), expr);
- return expr;
-}
-
-/* Like maybe_cleanup_point_expr except have the type of the new expression be
- void so we don't need to create a temporary variable to hold the inner
- expression. The reason why we do this is because the original type might be
- an aggregate and we cannot create a temporary variable for that type. */
-
-static tree
-maybe_cleanup_point_expr_void (tree expr)
-{
- if (!processing_template_decl && stmts_are_full_exprs_p ())
- expr = fold_build_cleanup_point_expr (void_type_node, expr);
- return expr;
-}
-
-
-
-/* Create a declaration statement for the declaration given by the DECL. */
-
-void
-add_decl_expr (tree decl)
-{
- tree r = build_stmt (DECL_EXPR, decl);
- if (DECL_INITIAL (decl)
- || (DECL_SIZE (decl) && TREE_SIDE_EFFECTS (DECL_SIZE (decl))))
- r = maybe_cleanup_point_expr_void (r);
- add_stmt (r);
-}
-
-/* Nonzero if TYPE is an anonymous union or struct type. We have to use a
- flag for this because "A union for which objects or pointers are
- declared is not an anonymous union" [class.union]. */
-
-int
-anon_aggr_type_p (tree node)
-{
- return ANON_AGGR_TYPE_P (node);
-}
-
-/* Finish a scope. */
-
-tree
-do_poplevel (tree stmt_list)
-{
- tree block = NULL;
-
- if (stmts_are_full_exprs_p ())
- block = poplevel (kept_level_p (), 1, 0);
-
- stmt_list = pop_stmt_list (stmt_list);
-
- if (!processing_template_decl)
- {
- stmt_list = c_build_bind_expr (block, stmt_list);
- /* ??? See c_end_compound_stmt re statement expressions. */
- }
-
- return stmt_list;
-}
-
-/* Begin a new scope. */
-
-static tree
-do_pushlevel (scope_kind sk)
-{
- tree ret = push_stmt_list ();
- if (stmts_are_full_exprs_p ())
- begin_scope (sk, NULL);
- return ret;
-}
-
-/* Queue a cleanup. CLEANUP is an expression/statement to be executed
- when the current scope is exited. EH_ONLY is true when this is not
- meant to apply to normal control flow transfer. */
-
-void
-push_cleanup (tree decl, tree cleanup, bool eh_only)
-{
- tree stmt = build_stmt (CLEANUP_STMT, NULL, cleanup, decl);
- CLEANUP_EH_ONLY (stmt) = eh_only;
- add_stmt (stmt);
- CLEANUP_BODY (stmt) = push_stmt_list ();
-}
-
-/* Begin a conditional that might contain a declaration. When generating
- normal code, we want the declaration to appear before the statement
- containing the conditional. When generating template code, we want the
- conditional to be rendered as the raw DECL_EXPR. */
-
-static void
-begin_cond (tree *cond_p)
-{
- if (processing_template_decl)
- *cond_p = push_stmt_list ();
-}
-
-/* Finish such a conditional. */
-
-static void
-finish_cond (tree *cond_p, tree expr)
-{
- if (processing_template_decl)
- {
- tree cond = pop_stmt_list (*cond_p);
- if (TREE_CODE (cond) == DECL_EXPR)
- expr = cond;
- }
- *cond_p = expr;
-}
-
-/* If *COND_P specifies a conditional with a declaration, transform the
- loop such that
- while (A x = 42) { }
- for (; A x = 42;) { }
- becomes
- while (true) { A x = 42; if (!x) break; }
- for (;;) { A x = 42; if (!x) break; }
- The statement list for BODY will be empty if the conditional did
- not declare anything. */
-
-static void
-simplify_loop_decl_cond (tree *cond_p, tree body)
-{
- tree cond, if_stmt;
-
- if (!TREE_SIDE_EFFECTS (body))
- return;
-
- cond = *cond_p;
- *cond_p = boolean_true_node;
-
- if_stmt = begin_if_stmt ();
- cond = build_unary_op (TRUTH_NOT_EXPR, cond, 0);
- finish_if_stmt_cond (cond, if_stmt);
- finish_break_stmt ();
- finish_then_clause (if_stmt);
- finish_if_stmt (if_stmt);
-}
-
-/* Finish a goto-statement. */
-
-tree
-finish_goto_stmt (tree destination)
-{
- if (TREE_CODE (destination) == IDENTIFIER_NODE)
- destination = lookup_label (destination);
-
- /* We warn about unused labels with -Wunused. That means we have to
- mark the used labels as used. */
- if (TREE_CODE (destination) == LABEL_DECL)
- TREE_USED (destination) = 1;
- else
- {
- /* The DESTINATION is being used as an rvalue. */
- if (!processing_template_decl)
- destination = decay_conversion (destination);
- /* We don't inline calls to functions with computed gotos.
- Those functions are typically up to some funny business,
- and may be depending on the labels being at particular
- addresses, or some such. */
- DECL_UNINLINABLE (current_function_decl) = 1;
- }
-
- check_goto (destination);
-
- return add_stmt (build_stmt (GOTO_EXPR, destination));
-}
-
-/* COND is the condition-expression for an if, while, etc.,
- statement. Convert it to a boolean value, if appropriate. */
-
-static tree
-maybe_convert_cond (tree cond)
-{
- /* Empty conditions remain empty. */
- if (!cond)
- return NULL_TREE;
-
- /* Wait until we instantiate templates before doing conversion. */
- if (processing_template_decl)
- return cond;
-
- /* Do the conversion. */
- cond = convert_from_reference (cond);
-
- if (TREE_CODE (cond) == MODIFY_EXPR
- && !TREE_NO_WARNING (cond)
- && warn_parentheses)
- {
- warning (OPT_Wparentheses,
- "suggest parentheses around assignment used as truth value");
- TREE_NO_WARNING (cond) = 1;
- }
-
- return condition_conversion (cond);
-}
-
-/* Finish an expression-statement, whose EXPRESSION is as indicated. */
-
-tree
-finish_expr_stmt (tree expr)
-{
- tree r = NULL_TREE;
-
- if (expr != NULL_TREE)
- {
- if (!processing_template_decl)
- {
- if (warn_sequence_point)
- verify_sequence_points (expr);
- expr = convert_to_void (expr, "statement");
- }
- else if (!type_dependent_expression_p (expr))
- convert_to_void (build_non_dependent_expr (expr), "statement");
-
- /* Simplification of inner statement expressions, compound exprs,
- etc can result in us already having an EXPR_STMT. */
- if (TREE_CODE (expr) != CLEANUP_POINT_EXPR)
- {
- if (TREE_CODE (expr) != EXPR_STMT)
- expr = build_stmt (EXPR_STMT, expr);
- expr = maybe_cleanup_point_expr_void (expr);
- }
-
- r = add_stmt (expr);
- }
-
- finish_stmt ();
-
- return r;
-}
-
-
-/* Begin an if-statement. Returns a newly created IF_STMT if
- appropriate. */
-
-tree
-begin_if_stmt (void)
-{
- tree r, scope;
- scope = do_pushlevel (sk_block);
- r = build_stmt (IF_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
- TREE_CHAIN (r) = scope;
- begin_cond (&IF_COND (r));
- return r;
-}
-
-/* Process the COND of an if-statement, which may be given by
- IF_STMT. */
-
-void
-finish_if_stmt_cond (tree cond, tree if_stmt)
-{
- finish_cond (&IF_COND (if_stmt), maybe_convert_cond (cond));
- add_stmt (if_stmt);
- THEN_CLAUSE (if_stmt) = push_stmt_list ();
-}
-
-/* Finish the then-clause of an if-statement, which may be given by
- IF_STMT. */
-
-tree
-finish_then_clause (tree if_stmt)
-{
- THEN_CLAUSE (if_stmt) = pop_stmt_list (THEN_CLAUSE (if_stmt));
- return if_stmt;
-}
-
-/* Begin the else-clause of an if-statement. */
-
-void
-begin_else_clause (tree if_stmt)
-{
- ELSE_CLAUSE (if_stmt) = push_stmt_list ();
-}
-
-/* Finish the else-clause of an if-statement, which may be given by
- IF_STMT. */
-
-void
-finish_else_clause (tree if_stmt)
-{
- ELSE_CLAUSE (if_stmt) = pop_stmt_list (ELSE_CLAUSE (if_stmt));
-}
-
-/* Finish an if-statement. */
-
-void
-finish_if_stmt (tree if_stmt)
-{
- tree scope = TREE_CHAIN (if_stmt);
- TREE_CHAIN (if_stmt) = NULL;
- add_stmt (do_poplevel (scope));
- finish_stmt ();
- empty_body_warning (THEN_CLAUSE (if_stmt), ELSE_CLAUSE (if_stmt));
-}
-
-/* Begin a while-statement. Returns a newly created WHILE_STMT if
- appropriate. */
-
-tree
-begin_while_stmt (void)
-{
- tree r;
- r = build_stmt (WHILE_STMT, NULL_TREE, NULL_TREE);
- add_stmt (r);
- WHILE_BODY (r) = do_pushlevel (sk_block);
- begin_cond (&WHILE_COND (r));
- return r;
-}
-
-/* Process the COND of a while-statement, which may be given by
- WHILE_STMT. */
-
-void
-finish_while_stmt_cond (tree cond, tree while_stmt)
-{
- finish_cond (&WHILE_COND (while_stmt), maybe_convert_cond (cond));
- simplify_loop_decl_cond (&WHILE_COND (while_stmt), WHILE_BODY (while_stmt));
-}
-
-/* Finish a while-statement, which may be given by WHILE_STMT. */
-
-void
-finish_while_stmt (tree while_stmt)
-{
- WHILE_BODY (while_stmt) = do_poplevel (WHILE_BODY (while_stmt));
- finish_stmt ();
-}
-
-/* Begin a do-statement. Returns a newly created DO_STMT if
- appropriate. */
-
-tree
-begin_do_stmt (void)
-{
- tree r = build_stmt (DO_STMT, NULL_TREE, NULL_TREE);
- add_stmt (r);
- DO_BODY (r) = push_stmt_list ();
- return r;
-}
-
-/* Finish the body of a do-statement, which may be given by DO_STMT. */
-
-void
-finish_do_body (tree do_stmt)
-{
- DO_BODY (do_stmt) = pop_stmt_list (DO_BODY (do_stmt));
-}
-
-/* Finish a do-statement, which may be given by DO_STMT, and whose
- COND is as indicated. */
-
-void
-finish_do_stmt (tree cond, tree do_stmt)
-{
- cond = maybe_convert_cond (cond);
- DO_COND (do_stmt) = cond;
- finish_stmt ();
-}
-
-/* Finish a return-statement. The EXPRESSION returned, if any, is as
- indicated. */
-
-tree
-finish_return_stmt (tree expr)
-{
- tree r;
- bool no_warning;
-
- expr = check_return_expr (expr, &no_warning);
-
- if (flag_openmp && !check_omp_return ())
- return error_mark_node;
- if (!processing_template_decl)
- {
- if (DECL_DESTRUCTOR_P (current_function_decl)
- || (DECL_CONSTRUCTOR_P (current_function_decl)
- && targetm.cxx.cdtor_returns_this ()))
- {
- /* Similarly, all destructors must run destructors for
- base-classes before returning. So, all returns in a
- destructor get sent to the DTOR_LABEL; finish_function emits
- code to return a value there. */
- return finish_goto_stmt (cdtor_label);
- }
- }
-
- r = build_stmt (RETURN_EXPR, expr);
- TREE_NO_WARNING (r) |= no_warning;
- r = maybe_cleanup_point_expr_void (r);
- r = add_stmt (r);
- finish_stmt ();
-
- return r;
-}
-
-/* Begin a for-statement. Returns a new FOR_STMT if appropriate. */
-
-tree
-begin_for_stmt (void)
-{
- tree r;
-
- r = build_stmt (FOR_STMT, NULL_TREE, NULL_TREE,
- NULL_TREE, NULL_TREE);
-
- if (flag_new_for_scope > 0)
- TREE_CHAIN (r) = do_pushlevel (sk_for);
-
- if (processing_template_decl)
- FOR_INIT_STMT (r) = push_stmt_list ();
-
- return r;
-}
-
-/* Finish the for-init-statement of a for-statement, which may be
- given by FOR_STMT. */
-
-void
-finish_for_init_stmt (tree for_stmt)
-{
- if (processing_template_decl)
- FOR_INIT_STMT (for_stmt) = pop_stmt_list (FOR_INIT_STMT (for_stmt));
- add_stmt (for_stmt);
- FOR_BODY (for_stmt) = do_pushlevel (sk_block);
- begin_cond (&FOR_COND (for_stmt));
-}
-
-/* Finish the COND of a for-statement, which may be given by
- FOR_STMT. */
-
-void
-finish_for_cond (tree cond, tree for_stmt)
-{
- finish_cond (&FOR_COND (for_stmt), maybe_convert_cond (cond));
- simplify_loop_decl_cond (&FOR_COND (for_stmt), FOR_BODY (for_stmt));
-}
-
-/* Finish the increment-EXPRESSION in a for-statement, which may be
- given by FOR_STMT. */
-
-void
-finish_for_expr (tree expr, tree for_stmt)
-{
- if (!expr)
- return;
- /* If EXPR is an overloaded function, issue an error; there is no
- context available to use to perform overload resolution. */
- if (type_unknown_p (expr))
- {
- cxx_incomplete_type_error (expr, TREE_TYPE (expr));
- expr = error_mark_node;
- }
- if (!processing_template_decl)
- {
- if (warn_sequence_point)
- verify_sequence_points (expr);
- expr = convert_to_void (expr, "3rd expression in for");
- }
- else if (!type_dependent_expression_p (expr))
- convert_to_void (build_non_dependent_expr (expr), "3rd expression in for");
- expr = maybe_cleanup_point_expr_void (expr);
- FOR_EXPR (for_stmt) = expr;
-}
-
-/* Finish the body of a for-statement, which may be given by
- FOR_STMT. The increment-EXPR for the loop must be
- provided. */
-
-void
-finish_for_stmt (tree for_stmt)
-{
- FOR_BODY (for_stmt) = do_poplevel (FOR_BODY (for_stmt));
-
- /* Pop the scope for the body of the loop. */
- if (flag_new_for_scope > 0)
- {
- tree scope = TREE_CHAIN (for_stmt);
- TREE_CHAIN (for_stmt) = NULL;
- add_stmt (do_poplevel (scope));
- }
-
- finish_stmt ();
-}
-
-/* Finish a break-statement. */
-
-tree
-finish_break_stmt (void)
-{
- return add_stmt (build_stmt (BREAK_STMT));
-}
-
-/* Finish a continue-statement. */
-
-tree
-finish_continue_stmt (void)
-{
- return add_stmt (build_stmt (CONTINUE_STMT));
-}
-
-/* Begin a switch-statement. Returns a new SWITCH_STMT if
- appropriate. */
-
-tree
-begin_switch_stmt (void)
-{
- tree r, scope;
-
- r = build_stmt (SWITCH_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
-
- scope = do_pushlevel (sk_block);
- TREE_CHAIN (r) = scope;
- begin_cond (&SWITCH_STMT_COND (r));
-
- return r;
-}
-
-/* Finish the cond of a switch-statement. */
-
-void
-finish_switch_cond (tree cond, tree switch_stmt)
-{
- tree orig_type = NULL;
- if (!processing_template_decl)
- {
- tree index;
-
- /* Convert the condition to an integer or enumeration type. */
- cond = build_expr_type_conversion (WANT_INT | WANT_ENUM, cond, true);
- if (cond == NULL_TREE)
- {
- error ("switch quantity not an integer");
- cond = error_mark_node;
- }
- orig_type = TREE_TYPE (cond);
- if (cond != error_mark_node)
- {
- /* [stmt.switch]
-
- Integral promotions are performed. */
- cond = perform_integral_promotions (cond);
- cond = maybe_cleanup_point_expr (cond);
- }
-
- if (cond != error_mark_node)
- {
- index = get_unwidened (cond, NULL_TREE);
- /* We can't strip a conversion from a signed type to an unsigned,
- because if we did, int_fits_type_p would do the wrong thing
- when checking case values for being in range,
- and it's too hard to do the right thing. */
- if (TYPE_UNSIGNED (TREE_TYPE (cond))
- == TYPE_UNSIGNED (TREE_TYPE (index)))
- cond = index;
- }
- }
- finish_cond (&SWITCH_STMT_COND (switch_stmt), cond);
- SWITCH_STMT_TYPE (switch_stmt) = orig_type;
- add_stmt (switch_stmt);
- push_switch (switch_stmt);
- SWITCH_STMT_BODY (switch_stmt) = push_stmt_list ();
-}
-
-/* Finish the body of a switch-statement, which may be given by
- SWITCH_STMT. The COND to switch on is indicated. */
-
-void
-finish_switch_stmt (tree switch_stmt)
-{
- tree scope;
-
- SWITCH_STMT_BODY (switch_stmt) =
- pop_stmt_list (SWITCH_STMT_BODY (switch_stmt));
- pop_switch ();
- finish_stmt ();
-
- scope = TREE_CHAIN (switch_stmt);
- TREE_CHAIN (switch_stmt) = NULL;
- add_stmt (do_poplevel (scope));
-}
-
-/* Begin a try-block. Returns a newly-created TRY_BLOCK if
- appropriate. */
-
-tree
-begin_try_block (void)
-{
- tree r = build_stmt (TRY_BLOCK, NULL_TREE, NULL_TREE);
- add_stmt (r);
- TRY_STMTS (r) = push_stmt_list ();
- return r;
-}
-
-/* Likewise, for a function-try-block. The block returned in
- *COMPOUND_STMT is an artificial outer scope, containing the
- function-try-block. */
-
-tree
-begin_function_try_block (tree *compound_stmt)
-{
- tree r;
- /* This outer scope does not exist in the C++ standard, but we need
- a place to put __FUNCTION__ and similar variables. */
- *compound_stmt = begin_compound_stmt (0);
- r = begin_try_block ();
- FN_TRY_BLOCK_P (r) = 1;
- return r;
-}
-
-/* Finish a try-block, which may be given by TRY_BLOCK. */
-
-void
-finish_try_block (tree try_block)
-{
- TRY_STMTS (try_block) = pop_stmt_list (TRY_STMTS (try_block));
- TRY_HANDLERS (try_block) = push_stmt_list ();
-}
-
-/* Finish the body of a cleanup try-block, which may be given by
- TRY_BLOCK. */
-
-void
-finish_cleanup_try_block (tree try_block)
-{
- TRY_STMTS (try_block) = pop_stmt_list (TRY_STMTS (try_block));
-}
-
-/* Finish an implicitly generated try-block, with a cleanup is given
- by CLEANUP. */
-
-void
-finish_cleanup (tree cleanup, tree try_block)
-{
- TRY_HANDLERS (try_block) = cleanup;
- CLEANUP_P (try_block) = 1;
-}
-
-/* Likewise, for a function-try-block. */
-
-void
-finish_function_try_block (tree try_block)
-{
- finish_try_block (try_block);
- /* FIXME : something queer about CTOR_INITIALIZER somehow following
- the try block, but moving it inside. */
- in_function_try_handler = 1;
-}
-
-/* Finish a handler-sequence for a try-block, which may be given by
- TRY_BLOCK. */
-
-void
-finish_handler_sequence (tree try_block)
-{
- TRY_HANDLERS (try_block) = pop_stmt_list (TRY_HANDLERS (try_block));
- check_handlers (TRY_HANDLERS (try_block));
-}
-
-/* Finish the handler-seq for a function-try-block, given by
- TRY_BLOCK. COMPOUND_STMT is the outer block created by
- begin_function_try_block. */
-
-void
-finish_function_handler_sequence (tree try_block, tree compound_stmt)
-{
- in_function_try_handler = 0;
- finish_handler_sequence (try_block);
- finish_compound_stmt (compound_stmt);
-}
-
-/* Begin a handler. Returns a HANDLER if appropriate. */
-
-tree
-begin_handler (void)
-{
- tree r;
-
- r = build_stmt (HANDLER, NULL_TREE, NULL_TREE);
- add_stmt (r);
-
- /* Create a binding level for the eh_info and the exception object
- cleanup. */
- HANDLER_BODY (r) = do_pushlevel (sk_catch);
-
- return r;
-}
-
-/* Finish the handler-parameters for a handler, which may be given by
- HANDLER. DECL is the declaration for the catch parameter, or NULL
- if this is a `catch (...)' clause. */
-
-void
-finish_handler_parms (tree decl, tree handler)
-{
- tree type = NULL_TREE;
- if (processing_template_decl)
- {
- if (decl)
- {
- decl = pushdecl (decl);
- decl = push_template_decl (decl);
- HANDLER_PARMS (handler) = decl;
- type = TREE_TYPE (decl);
- }
- }
- else
- type = expand_start_catch_block (decl);
- HANDLER_TYPE (handler) = type;
- if (!processing_template_decl && type)
- mark_used (eh_type_info (type));
-}
-
-/* Finish a handler, which may be given by HANDLER. The BLOCKs are
- the return value from the matching call to finish_handler_parms. */
-
-void
-finish_handler (tree handler)
-{
- if (!processing_template_decl)
- expand_end_catch_block ();
- HANDLER_BODY (handler) = do_poplevel (HANDLER_BODY (handler));
-}
-
-/* Begin a compound statement. FLAGS contains some bits that control the
- behavior and context. If BCS_NO_SCOPE is set, the compound statement
- does not define a scope. If BCS_FN_BODY is set, this is the outermost
- block of a function. If BCS_TRY_BLOCK is set, this is the block
- created on behalf of a TRY statement. Returns a token to be passed to
- finish_compound_stmt. */
-
-tree
-begin_compound_stmt (unsigned int flags)
-{
- tree r;
-
- if (flags & BCS_NO_SCOPE)
- {
- r = push_stmt_list ();
- STATEMENT_LIST_NO_SCOPE (r) = 1;
-
- /* Normally, we try hard to keep the BLOCK for a statement-expression.
- But, if it's a statement-expression with a scopeless block, there's
- nothing to keep, and we don't want to accidentally keep a block
- *inside* the scopeless block. */
- keep_next_level (false);
- }
- else
- r = do_pushlevel (flags & BCS_TRY_BLOCK ? sk_try : sk_block);
-
- /* When processing a template, we need to remember where the braces were,
- so that we can set up identical scopes when instantiating the template
- later. BIND_EXPR is a handy candidate for this.
- Note that do_poplevel won't create a BIND_EXPR itself here (and thus
- result in nested BIND_EXPRs), since we don't build BLOCK nodes when
- processing templates. */
- if (processing_template_decl)
- {
- r = build3 (BIND_EXPR, NULL, NULL, r, NULL);
- BIND_EXPR_TRY_BLOCK (r) = (flags & BCS_TRY_BLOCK) != 0;
- BIND_EXPR_BODY_BLOCK (r) = (flags & BCS_FN_BODY) != 0;
- TREE_SIDE_EFFECTS (r) = 1;
- }
-
- return r;
-}
-
-/* Finish a compound-statement, which is given by STMT. */
-
-void
-finish_compound_stmt (tree stmt)
-{
- if (TREE_CODE (stmt) == BIND_EXPR)
- BIND_EXPR_BODY (stmt) = do_poplevel (BIND_EXPR_BODY (stmt));
- else if (STATEMENT_LIST_NO_SCOPE (stmt))
- stmt = pop_stmt_list (stmt);
- else
- {
- /* Destroy any ObjC "super" receivers that may have been
- created. */
- objc_clear_super_receiver ();
-
- stmt = do_poplevel (stmt);
- }
-
- /* ??? See c_end_compound_stmt wrt statement expressions. */
- add_stmt (stmt);
- finish_stmt ();
-}
-
-/* Finish an asm-statement, whose components are a STRING, some
- OUTPUT_OPERANDS, some INPUT_OPERANDS, and some CLOBBERS. Also note
- whether the asm-statement should be considered volatile. */
-
-tree
-finish_asm_stmt (int volatile_p, tree string, tree output_operands,
- tree input_operands, tree clobbers)
-{
- tree r;
- tree t;
- int ninputs = list_length (input_operands);
- int noutputs = list_length (output_operands);
-
- if (!processing_template_decl)
- {
- const char *constraint;
- const char **oconstraints;
- bool allows_mem, allows_reg, is_inout;
- tree operand;
- int i;
-
- oconstraints = (const char **) alloca (noutputs * sizeof (char *));
-
- string = resolve_asm_operand_names (string, output_operands,
- input_operands);
-
- for (i = 0, t = output_operands; t; t = TREE_CHAIN (t), ++i)
- {
- operand = TREE_VALUE (t);
-
- /* ??? Really, this should not be here. Users should be using a
- proper lvalue, dammit. But there's a long history of using
- casts in the output operands. In cases like longlong.h, this
- becomes a primitive form of typechecking -- if the cast can be
- removed, then the output operand had a type of the proper width;
- otherwise we'll get an error. Gross, but ... */
- STRIP_NOPS (operand);
-
- if (!lvalue_or_else (operand, lv_asm))
- operand = error_mark_node;
-
- if (operand != error_mark_node
- && (TREE_READONLY (operand)
- || CP_TYPE_CONST_P (TREE_TYPE (operand))
- /* Functions are not modifiable, even though they are
- lvalues. */
- || TREE_CODE (TREE_TYPE (operand)) == FUNCTION_TYPE
- || TREE_CODE (TREE_TYPE (operand)) == METHOD_TYPE
- /* If it's an aggregate and any field is const, then it is
- effectively const. */
- || (CLASS_TYPE_P (TREE_TYPE (operand))
- && C_TYPE_FIELDS_READONLY (TREE_TYPE (operand)))))
- readonly_error (operand, "assignment (via 'asm' output)", 0);
-
- constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
- oconstraints[i] = constraint;
-
- if (parse_output_constraint (&constraint, i, ninputs, noutputs,
- &allows_mem, &allows_reg, &is_inout))
- {
- /* If the operand is going to end up in memory,
- mark it addressable. */
- if (!allows_reg && !cxx_mark_addressable (operand))
- operand = error_mark_node;
- }
- else
- operand = error_mark_node;
-
- TREE_VALUE (t) = operand;
- }
-
- for (i = 0, t = input_operands; t; ++i, t = TREE_CHAIN (t))
- {
- constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
- operand = decay_conversion (TREE_VALUE (t));
-
- /* If the type of the operand hasn't been determined (e.g.,
- because it involves an overloaded function), then issue
- an error message. There's no context available to
- resolve the overloading. */
- if (TREE_TYPE (operand) == unknown_type_node)
- {
- error ("type of asm operand %qE could not be determined",
- TREE_VALUE (t));
- operand = error_mark_node;
- }
-
- if (parse_input_constraint (&constraint, i, ninputs, noutputs, 0,
- oconstraints, &allows_mem, &allows_reg))
- {
- /* If the operand is going to end up in memory,
- mark it addressable. */
- if (!allows_reg && allows_mem)
- {
- /* Strip the nops as we allow this case. FIXME, this really
- should be rejected or made deprecated. */
- STRIP_NOPS (operand);
- if (!cxx_mark_addressable (operand))
- operand = error_mark_node;
- }
- }
- else
- operand = error_mark_node;
-
- TREE_VALUE (t) = operand;
- }
- }
-
- r = build_stmt (ASM_EXPR, string,
- output_operands, input_operands,
- clobbers);
- ASM_VOLATILE_P (r) = volatile_p || noutputs == 0;
- r = maybe_cleanup_point_expr_void (r);
- return add_stmt (r);
-}
-
-/* Finish a label with the indicated NAME. */
-
-tree
-finish_label_stmt (tree name)
-{
- tree decl = define_label (input_location, name);
-
- if (decl == error_mark_node)
- return error_mark_node;
-
- return add_stmt (build_stmt (LABEL_EXPR, decl));
-}
-
-/* Finish a series of declarations for local labels. G++ allows users
- to declare "local" labels, i.e., labels with scope. This extension
- is useful when writing code involving statement-expressions. */
-
-void
-finish_label_decl (tree name)
-{
- tree decl = declare_local_label (name);
- add_decl_expr (decl);
-}
-
-/* When DECL goes out of scope, make sure that CLEANUP is executed. */
-
-void
-finish_decl_cleanup (tree decl, tree cleanup)
-{
- push_cleanup (decl, cleanup, false);
-}
-
-/* If the current scope exits with an exception, run CLEANUP. */
-
-void
-finish_eh_cleanup (tree cleanup)
-{
- push_cleanup (NULL, cleanup, true);
-}
-
-/* The MEM_INITS is a list of mem-initializers, in reverse of the
- order they were written by the user. Each node is as for
- emit_mem_initializers. */
-
-void
-finish_mem_initializers (tree mem_inits)
-{
- /* Reorder the MEM_INITS so that they are in the order they appeared
- in the source program. */
- mem_inits = nreverse (mem_inits);
-
- if (processing_template_decl)
- add_stmt (build_min_nt (CTOR_INITIALIZER, mem_inits));
- else
- emit_mem_initializers (mem_inits);
-}
-
-/* Finish a parenthesized expression EXPR. */
-
-tree
-finish_parenthesized_expr (tree expr)
-{
- if (EXPR_P (expr))
- /* This inhibits warnings in c_common_truthvalue_conversion. */
- TREE_NO_WARNING (expr) = 1;
-
- if (TREE_CODE (expr) == OFFSET_REF)
- /* [expr.unary.op]/3 The qualified id of a pointer-to-member must not be
- enclosed in parentheses. */
- PTRMEM_OK_P (expr) = 0;
-
- if (TREE_CODE (expr) == STRING_CST)
- PAREN_STRING_LITERAL_P (expr) = 1;
-
- return expr;
-}
-
-/* Finish a reference to a non-static data member (DECL) that is not
- preceded by `.' or `->'. */
-
-tree
-finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
-{
- gcc_assert (TREE_CODE (decl) == FIELD_DECL);
-
- if (!object)
- {
- if (current_function_decl
- && DECL_STATIC_FUNCTION_P (current_function_decl))
- error ("invalid use of member %q+D in static member function", decl);
- else
- error ("invalid use of non-static data member %q+D", decl);
- error ("from this location");
-
- return error_mark_node;
- }
- TREE_USED (current_class_ptr) = 1;
- if (processing_template_decl && !qualifying_scope)
- {
- tree type = TREE_TYPE (decl);
-
- if (TREE_CODE (type) == REFERENCE_TYPE)
- type = TREE_TYPE (type);
- else
- {
- /* Set the cv qualifiers. */
- int quals = cp_type_quals (TREE_TYPE (current_class_ref));
-
- if (DECL_MUTABLE_P (decl))
- quals &= ~TYPE_QUAL_CONST;
-
- quals |= cp_type_quals (TREE_TYPE (decl));
- type = cp_build_qualified_type (type, quals);
- }
-
- return build_min (COMPONENT_REF, type, object, decl, NULL_TREE);
- }
- else
- {
- tree access_type = TREE_TYPE (object);
- tree lookup_context = context_for_name_lookup (decl);
-
- while (!DERIVED_FROM_P (lookup_context, access_type))
- {
- access_type = TYPE_CONTEXT (access_type);
- while (access_type && DECL_P (access_type))
- access_type = DECL_CONTEXT (access_type);
-
- if (!access_type)
- {
- error ("object missing in reference to %q+D", decl);
- error ("from this location");
- return error_mark_node;
- }
- }
-
- /* If PROCESSING_TEMPLATE_DECL is nonzero here, then
- QUALIFYING_SCOPE is also non-null. Wrap this in a SCOPE_REF
- for now. */
- if (processing_template_decl)
- return build_qualified_name (TREE_TYPE (decl),
- qualifying_scope,
- DECL_NAME (decl),
- /*template_p=*/false);
-
- perform_or_defer_access_check (TYPE_BINFO (access_type), decl,
- decl);
-
- /* If the data member was named `C::M', convert `*this' to `C'
- first. */
- if (qualifying_scope)
- {
- tree binfo = NULL_TREE;
- object = build_scoped_ref (object, qualifying_scope,
- &binfo);
- }
-
- return build_class_member_access_expr (object, decl,
- /*access_path=*/NULL_TREE,
- /*preserve_reference=*/false);
- }
-}
-
-/* DECL was the declaration to which a qualified-id resolved. Issue
- an error message if it is not accessible. If OBJECT_TYPE is
- non-NULL, we have just seen `x->' or `x.' and OBJECT_TYPE is the
- type of `*x', or `x', respectively. If the DECL was named as
- `A::B' then NESTED_NAME_SPECIFIER is `A'. */
-
-void
-check_accessibility_of_qualified_id (tree decl,
- tree object_type,
- tree nested_name_specifier)
-{
- tree scope;
- tree qualifying_type = NULL_TREE;
-
- /* If we're not checking, return immediately. */
- if (deferred_access_no_check)
- return;
-
- /* Determine the SCOPE of DECL. */
- scope = context_for_name_lookup (decl);
- /* If the SCOPE is not a type, then DECL is not a member. */
- if (!TYPE_P (scope))
- return;
- /* Compute the scope through which DECL is being accessed. */
- if (object_type
- /* OBJECT_TYPE might not be a class type; consider:
-
- class A { typedef int I; };
- I *p;
- p->A::I::~I();
-
- In this case, we will have "A::I" as the DECL, but "I" as the
- OBJECT_TYPE. */
- && CLASS_TYPE_P (object_type)
- && DERIVED_FROM_P (scope, object_type))
- /* If we are processing a `->' or `.' expression, use the type of the
- left-hand side. */
- qualifying_type = object_type;
- else if (nested_name_specifier)
- {
- /* If the reference is to a non-static member of the
- current class, treat it as if it were referenced through
- `this'. */
- if (DECL_NONSTATIC_MEMBER_P (decl)
- && current_class_ptr
- && DERIVED_FROM_P (scope, current_class_type))
- qualifying_type = current_class_type;
- /* Otherwise, use the type indicated by the
- nested-name-specifier. */
- else
- qualifying_type = nested_name_specifier;
- }
- else
- /* Otherwise, the name must be from the current class or one of
- its bases. */
- qualifying_type = currently_open_derived_class (scope);
-
- if (qualifying_type
- /* It is possible for qualifying type to be a TEMPLATE_TYPE_PARM
- or similar in a default argument value. */
- && CLASS_TYPE_P (qualifying_type)
- && !dependent_type_p (qualifying_type))
- perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl,
- decl);
-}
-
-/* EXPR is the result of a qualified-id. The QUALIFYING_CLASS was the
- class named to the left of the "::" operator. DONE is true if this
- expression is a complete postfix-expression; it is false if this
- expression is followed by '->', '[', '(', etc. ADDRESS_P is true
- iff this expression is the operand of '&'. TEMPLATE_P is true iff
- the qualified-id was of the form "A::template B". TEMPLATE_ARG_P
- is true iff this qualified name appears as a template argument. */
-
-tree
-finish_qualified_id_expr (tree qualifying_class,
- tree expr,
- bool done,
- bool address_p,
- bool template_p,
- bool template_arg_p)
-{
- gcc_assert (TYPE_P (qualifying_class));
-
- if (error_operand_p (expr))
- return error_mark_node;
-
- if (DECL_P (expr) || BASELINK_P (expr))
- mark_used (expr);
-
- if (template_p)
- check_template_keyword (expr);
-
- /* If EXPR occurs as the operand of '&', use special handling that
- permits a pointer-to-member. */
- if (address_p && done)
- {
- if (TREE_CODE (expr) == SCOPE_REF)
- expr = TREE_OPERAND (expr, 1);
- expr = build_offset_ref (qualifying_class, expr,
- /*address_p=*/true);
- return expr;
- }
-
- /* Within the scope of a class, turn references to non-static
- members into expression of the form "this->...". */
- if (template_arg_p)
- /* But, within a template argument, we do not want make the
- transformation, as there is no "this" pointer. */
- ;
- else if (TREE_CODE (expr) == FIELD_DECL)
- expr = finish_non_static_data_member (expr, current_class_ref,
- qualifying_class);
- else if (BASELINK_P (expr) && !processing_template_decl)
- {
- tree fns;
-
- /* See if any of the functions are non-static members. */
- fns = BASELINK_FUNCTIONS (expr);
- if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
- fns = TREE_OPERAND (fns, 0);
- /* If so, the expression may be relative to the current
- class. */
- if (!shared_member_p (fns)
- && current_class_type
- && DERIVED_FROM_P (qualifying_class, current_class_type))
- expr = (build_class_member_access_expr
- (maybe_dummy_object (qualifying_class, NULL),
- expr,
- BASELINK_ACCESS_BINFO (expr),
- /*preserve_reference=*/false));
- else if (done)
- /* The expression is a qualified name whose address is not
- being taken. */
- expr = build_offset_ref (qualifying_class, expr, /*address_p=*/false);
- }
-
- return expr;
-}
-
-/* Begin a statement-expression. The value returned must be passed to
- finish_stmt_expr. */
-
-tree
-begin_stmt_expr (void)
-{
- return push_stmt_list ();
-}
-
-/* Process the final expression of a statement expression. EXPR can be
- NULL, if the final expression is empty. Return a STATEMENT_LIST
- containing all the statements in the statement-expression, or
- ERROR_MARK_NODE if there was an error. */
-
-tree
-finish_stmt_expr_expr (tree expr, tree stmt_expr)
-{
- if (error_operand_p (expr))
- return error_mark_node;
-
- /* If the last statement does not have "void" type, then the value
- of the last statement is the value of the entire expression. */
- if (expr)
- {
- tree type = TREE_TYPE (expr);
-
- if (processing_template_decl)
- {
- expr = build_stmt (EXPR_STMT, expr);
- expr = add_stmt (expr);
- /* Mark the last statement so that we can recognize it as such at
- template-instantiation time. */
- EXPR_STMT_STMT_EXPR_RESULT (expr) = 1;
- }
- else if (VOID_TYPE_P (type))
- {
- /* Just treat this like an ordinary statement. */
- expr = finish_expr_stmt (expr);
- }
- else
- {
- /* It actually has a value we need to deal with. First, force it
- to be an rvalue so that we won't need to build up a copy
- constructor call later when we try to assign it to something. */
- expr = force_rvalue (expr);
- if (error_operand_p (expr))
- return error_mark_node;
-
- /* Update for array-to-pointer decay. */
- type = TREE_TYPE (expr);
-
- /* Wrap it in a CLEANUP_POINT_EXPR and add it to the list like a
- normal statement, but don't convert to void or actually add
- the EXPR_STMT. */
- if (TREE_CODE (expr) != CLEANUP_POINT_EXPR)
- expr = maybe_cleanup_point_expr (expr);
- add_stmt (expr);
- }
-
- /* The type of the statement-expression is the type of the last
- expression. */
- TREE_TYPE (stmt_expr) = type;
- }
-
- return stmt_expr;
-}
-
-/* Finish a statement-expression. EXPR should be the value returned
- by the previous begin_stmt_expr. Returns an expression
- representing the statement-expression. */
-
-tree
-finish_stmt_expr (tree stmt_expr, bool has_no_scope)
-{
- tree type;
- tree result;
-
- if (error_operand_p (stmt_expr))
- return error_mark_node;
-
- gcc_assert (TREE_CODE (stmt_expr) == STATEMENT_LIST);
-
- type = TREE_TYPE (stmt_expr);
- result = pop_stmt_list (stmt_expr);
- TREE_TYPE (result) = type;
-
- if (processing_template_decl)
- {
- result = build_min (STMT_EXPR, type, result);
- TREE_SIDE_EFFECTS (result) = 1;
- STMT_EXPR_NO_SCOPE (result) = has_no_scope;
- }
- else if (CLASS_TYPE_P (type))
- {
- /* Wrap the statement-expression in a TARGET_EXPR so that the
- temporary object created by the final expression is destroyed at
- the end of the full-expression containing the
- statement-expression. */
- result = force_target_expr (type, result);
- }
-
- return result;
-}
-
-/* Perform Koenig lookup. FN is the postfix-expression representing
- the function (or functions) to call; ARGS are the arguments to the
- call. Returns the functions to be considered by overload
- resolution. */
-
-tree
-perform_koenig_lookup (tree fn, tree args)
-{
- tree identifier = NULL_TREE;
- tree functions = NULL_TREE;
-
- /* Find the name of the overloaded function. */
- if (TREE_CODE (fn) == IDENTIFIER_NODE)
- identifier = fn;
- else if (is_overloaded_fn (fn))
- {
- functions = fn;
- identifier = DECL_NAME (get_first_fn (functions));
- }
- else if (DECL_P (fn))
- {
- functions = fn;
- identifier = DECL_NAME (fn);
- }
-
- /* A call to a namespace-scope function using an unqualified name.
-
- Do Koenig lookup -- unless any of the arguments are
- type-dependent. */
- if (!any_type_dependent_arguments_p (args))
- {
- fn = lookup_arg_dependent (identifier, functions, args);
- if (!fn)
- /* The unqualified name could not be resolved. */
- fn = unqualified_fn_lookup_error (identifier);
- }
-
- return fn;
-}
-
-/* Generate an expression for `FN (ARGS)'.
-
- If DISALLOW_VIRTUAL is true, the call to FN will be not generated
- as a virtual call, even if FN is virtual. (This flag is set when
- encountering an expression where the function name is explicitly
- qualified. For example a call to `X::f' never generates a virtual
- call.)
-
- Returns code for the call. */
-
-tree
-finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p)
-{
- tree result;
- tree orig_fn;
- tree orig_args;
-
- if (fn == error_mark_node || args == error_mark_node)
- return error_mark_node;
-
- /* ARGS should be a list of arguments. */
- gcc_assert (!args || TREE_CODE (args) == TREE_LIST);
- gcc_assert (!TYPE_P (fn));
-
- orig_fn = fn;
- orig_args = args;
-
- if (processing_template_decl)
- {
- if (type_dependent_expression_p (fn)
- || any_type_dependent_arguments_p (args))
- {
- result = build_nt (CALL_EXPR, fn, args, NULL_TREE);
- KOENIG_LOOKUP_P (result) = koenig_p;
- return result;
- }
- if (!BASELINK_P (fn)
- && TREE_CODE (fn) != PSEUDO_DTOR_EXPR
- && TREE_TYPE (fn) != unknown_type_node)
- fn = build_non_dependent_expr (fn);
- args = build_non_dependent_args (orig_args);
- }
-
- if (is_overloaded_fn (fn))
- fn = baselink_for_fns (fn);
-
- result = NULL_TREE;
- if (BASELINK_P (fn))
- {
- tree object;
-
- /* A call to a member function. From [over.call.func]:
-
- If the keyword this is in scope and refers to the class of
- that member function, or a derived class thereof, then the
- function call is transformed into a qualified function call
- using (*this) as the postfix-expression to the left of the
- . operator.... [Otherwise] a contrived object of type T
- becomes the implied object argument.
-
- This paragraph is unclear about this situation:
-
- struct A { void f(); };
- struct B : public A {};
- struct C : public A { void g() { B::f(); }};
-
- In particular, for `B::f', this paragraph does not make clear
- whether "the class of that member function" refers to `A' or
- to `B'. We believe it refers to `B'. */
- if (current_class_type
- && DERIVED_FROM_P (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
- current_class_type)
- && current_class_ref)
- object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
- NULL);
- else
- {
- tree representative_fn;
-
- representative_fn = BASELINK_FUNCTIONS (fn);
- if (TREE_CODE (representative_fn) == TEMPLATE_ID_EXPR)
- representative_fn = TREE_OPERAND (representative_fn, 0);
- representative_fn = get_first_fn (representative_fn);
- object = build_dummy_object (DECL_CONTEXT (representative_fn));
- }
-
- if (processing_template_decl)
- {
- if (type_dependent_expression_p (object))
- return build_nt (CALL_EXPR, orig_fn, orig_args, NULL_TREE);
- object = build_non_dependent_expr (object);
- }
-
- result = build_new_method_call (object, fn, args, NULL_TREE,
- (disallow_virtual
- ? LOOKUP_NONVIRTUAL : 0),
- /*fn_p=*/NULL);
- }
- else if (is_overloaded_fn (fn))
- {
- /* If the function is an overloaded builtin, resolve it. */
- if (TREE_CODE (fn) == FUNCTION_DECL
- && (DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
- || DECL_BUILT_IN_CLASS (fn) == BUILT_IN_MD))
- result = resolve_overloaded_builtin (fn, args);
-
- if (!result)
- /* A call to a namespace-scope function. */
- result = build_new_function_call (fn, args, koenig_p);
- }
- else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR)
- {
- if (args)
- error ("arguments to destructor are not allowed");
- /* Mark the pseudo-destructor call as having side-effects so
- that we do not issue warnings about its use. */
- result = build1 (NOP_EXPR,
- void_type_node,
- TREE_OPERAND (fn, 0));
- TREE_SIDE_EFFECTS (result) = 1;
- }
- else if (CLASS_TYPE_P (TREE_TYPE (fn)))
- /* If the "function" is really an object of class type, it might
- have an overloaded `operator ()'. */
- result = build_new_op (CALL_EXPR, LOOKUP_NORMAL, fn, args, NULL_TREE,
- /*overloaded_p=*/NULL);
-
- if (!result)
- /* A call where the function is unknown. */
- result = build_function_call (fn, args);
-
- if (processing_template_decl)
- {
- result = build3 (CALL_EXPR, TREE_TYPE (result), orig_fn,
- orig_args, NULL_TREE);
- KOENIG_LOOKUP_P (result) = koenig_p;
- }
- return result;
-}
-
-/* Finish a call to a postfix increment or decrement or EXPR. (Which
- is indicated by CODE, which should be POSTINCREMENT_EXPR or
- POSTDECREMENT_EXPR.) */
-
-tree
-finish_increment_expr (tree expr, enum tree_code code)
-{
- return build_x_unary_op (code, expr);
-}
-
-/* Finish a use of `this'. Returns an expression for `this'. */
-
-tree
-finish_this_expr (void)
-{
- tree result;
-
- if (current_class_ptr)
- {
- result = current_class_ptr;
- }
- else if (current_function_decl
- && DECL_STATIC_FUNCTION_P (current_function_decl))
- {
- error ("%<this%> is unavailable for static member functions");
- result = error_mark_node;
- }
- else
- {
- if (current_function_decl)
- error ("invalid use of %<this%> in non-member function");
- else
- error ("invalid use of %<this%> at top level");
- result = error_mark_node;
- }
-
- return result;
-}
-
-/* Finish a pseudo-destructor expression. If SCOPE is NULL, the
- expression was of the form `OBJECT.~DESTRUCTOR' where DESTRUCTOR is
- the TYPE for the type given. If SCOPE is non-NULL, the expression
- was of the form `OBJECT.SCOPE::~DESTRUCTOR'. */
-
-tree
-finish_pseudo_destructor_expr (tree object, tree scope, tree destructor)
-{
- if (destructor == error_mark_node)
- return error_mark_node;
-
- gcc_assert (TYPE_P (destructor));
-
- if (!processing_template_decl)
- {
- if (scope == error_mark_node)
- {
- error ("invalid qualifying scope in pseudo-destructor name");
- return error_mark_node;
- }
- if (scope && TYPE_P (scope) && !check_dtor_name (scope, destructor))
- {
- error ("qualified type %qT does not match destructor name ~%qT",
- scope, destructor);
- return error_mark_node;
- }
-
-
- /* [expr.pseudo] says both:
-
- The type designated by the pseudo-destructor-name shall be
- the same as the object type.
-
- and:
-
- The cv-unqualified versions of the object type and of the
- type designated by the pseudo-destructor-name shall be the
- same type.
-
- We implement the more generous second sentence, since that is
- what most other compilers do. */
- if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (object),
- destructor))
- {
- error ("%qE is not of type %qT", object, destructor);
- return error_mark_node;
- }
- }
-
- return build3 (PSEUDO_DTOR_EXPR, void_type_node, object, scope, destructor);
-}
-
-/* Finish an expression of the form CODE EXPR. */
-
-tree
-finish_unary_op_expr (enum tree_code code, tree expr)
-{
- tree result = build_x_unary_op (code, expr);
- /* Inside a template, build_x_unary_op does not fold the
- expression. So check whether the result is folded before
- setting TREE_NEGATED_INT. */
- if (code == NEGATE_EXPR && TREE_CODE (expr) == INTEGER_CST
- && TREE_CODE (result) == INTEGER_CST
- && !TYPE_UNSIGNED (TREE_TYPE (result))
- && INT_CST_LT (result, integer_zero_node))
- {
- /* RESULT may be a cached INTEGER_CST, so we must copy it before
- setting TREE_NEGATED_INT. */
- result = copy_node (result);
- TREE_NEGATED_INT (result) = 1;
- }
- overflow_warning (result);
- return result;
-}
-
-/* Finish a compound-literal expression. TYPE is the type to which
- the INITIALIZER_LIST is being cast. */
-
-tree
-finish_compound_literal (tree type, VEC(constructor_elt,gc) *initializer_list)
-{
- tree var;
- tree compound_literal;
-
- if (!TYPE_OBJ_P (type))
- {
- error ("compound literal of non-object type %qT", type);
- return error_mark_node;
- }
-
- /* Build a CONSTRUCTOR for the INITIALIZER_LIST. */
- compound_literal = build_constructor (NULL_TREE, initializer_list);
- if (processing_template_decl)
- {
- TREE_TYPE (compound_literal) = type;
- /* Mark the expression as a compound literal. */
- TREE_HAS_CONSTRUCTOR (compound_literal) = 1;
- return compound_literal;
- }
-
- /* Create a temporary variable to represent the compound literal. */
- var = create_temporary_var (type);
- if (!current_function_decl)
- {
- /* If this compound-literal appears outside of a function, then
- the corresponding variable has static storage duration, just
- like the variable in whose initializer it appears. */
- TREE_STATIC (var) = 1;
- /* The variable has internal linkage, since there is no need to
- reference it from another translation unit. */
- TREE_PUBLIC (var) = 0;
- /* It must have a name, so that the name mangler can mangle it. */
- DECL_NAME (var) = make_anon_name ();
- }
- /* We must call pushdecl, since the gimplifier complains if the
- variable has not been declared via a BIND_EXPR. */
- pushdecl (var);
- /* Initialize the variable as we would any other variable with a
- brace-enclosed initializer. */
- cp_finish_decl (var, compound_literal,
- /*init_const_expr_p=*/false,
- /*asmspec_tree=*/NULL_TREE,
- LOOKUP_ONLYCONVERTING);
- return var;
-}
-
-/* Return the declaration for the function-name variable indicated by
- ID. */
-
-tree
-finish_fname (tree id)
-{
- tree decl;
-
- decl = fname_decl (C_RID_CODE (id), id);
- if (processing_template_decl)
- decl = DECL_NAME (decl);
- return decl;
-}
-
-/* Finish a translation unit. */
-
-void
-finish_translation_unit (void)
-{
- /* In case there were missing closebraces,
- get us back to the global binding level. */
- pop_everything ();
- while (current_namespace != global_namespace)
- pop_namespace ();
-
- /* Do file scope __FUNCTION__ et al. */
- finish_fname_decls ();
-}
-
-/* Finish a template type parameter, specified as AGGR IDENTIFIER.
- Returns the parameter. */
-
-tree
-finish_template_type_parm (tree aggr, tree identifier)
-{
- if (aggr != class_type_node)
- {
- pedwarn ("template type parameters must use the keyword %<class%> or %<typename%>");
- aggr = class_type_node;
- }
-
- return build_tree_list (aggr, identifier);
-}
-
-/* Finish a template template parameter, specified as AGGR IDENTIFIER.
- Returns the parameter. */
-
-tree
-finish_template_template_parm (tree aggr, tree identifier)
-{
- tree decl = build_decl (TYPE_DECL, identifier, NULL_TREE);
- tree tmpl = build_lang_decl (TEMPLATE_DECL, identifier, NULL_TREE);
- DECL_TEMPLATE_PARMS (tmpl) = current_template_parms;
- DECL_TEMPLATE_RESULT (tmpl) = decl;
- DECL_ARTIFICIAL (decl) = 1;
- end_template_decl ();
-
- gcc_assert (DECL_TEMPLATE_PARMS (tmpl));
-
- return finish_template_type_parm (aggr, tmpl);
-}
-
-/* ARGUMENT is the default-argument value for a template template
- parameter. If ARGUMENT is invalid, issue error messages and return
- the ERROR_MARK_NODE. Otherwise, ARGUMENT itself is returned. */
-
-tree
-check_template_template_default_arg (tree argument)
-{
- if (TREE_CODE (argument) != TEMPLATE_DECL
- && TREE_CODE (argument) != TEMPLATE_TEMPLATE_PARM
- && TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE)
- {
- if (TREE_CODE (argument) == TYPE_DECL)
- error ("invalid use of type %qT as a default value for a template "
- "template-parameter", TREE_TYPE (argument));
- else
- error ("invalid default argument for a template template parameter");
- return error_mark_node;
- }
-
- return argument;
-}
-
-/* Begin a class definition, as indicated by T. */
-
-tree
-begin_class_definition (tree t, tree attributes)
-{
- if (t == error_mark_node)
- return error_mark_node;
-
- if (processing_template_parmlist)
- {
- error ("definition of %q#T inside template parameter list", t);
- return error_mark_node;
- }
- /* A non-implicit typename comes from code like:
-
- template <typename T> struct A {
- template <typename U> struct A<T>::B ...
-
- This is erroneous. */
- else if (TREE_CODE (t) == TYPENAME_TYPE)
- {
- error ("invalid definition of qualified type %qT", t);
- t = error_mark_node;
- }
-
- if (t == error_mark_node || ! IS_AGGR_TYPE (t))
- {
- t = make_aggr_type (RECORD_TYPE);
- pushtag (make_anon_name (), t, /*tag_scope=*/ts_current);
- }
-
- /* Update the location of the decl. */
- DECL_SOURCE_LOCATION (TYPE_NAME (t)) = input_location;
-
- if (TYPE_BEING_DEFINED (t))
- {
- t = make_aggr_type (TREE_CODE (t));
- pushtag (TYPE_IDENTIFIER (t), t, /*tag_scope=*/ts_current);
- }
- maybe_process_partial_specialization (t);
- pushclass (t);
- TYPE_BEING_DEFINED (t) = 1;
-
- cplus_decl_attributes (&t, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
-
- if (flag_pack_struct)
- {
- tree v;
- TYPE_PACKED (t) = 1;
- /* Even though the type is being defined for the first time
- here, there might have been a forward declaration, so there
- might be cv-qualified variants of T. */
- for (v = TYPE_NEXT_VARIANT (t); v; v = TYPE_NEXT_VARIANT (v))
- TYPE_PACKED (v) = 1;
- }
- /* Reset the interface data, at the earliest possible
- moment, as it might have been set via a class foo;
- before. */
- if (! TYPE_ANONYMOUS_P (t))
- {
- struct c_fileinfo *finfo = get_fileinfo (input_filename);
- CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only;
- SET_CLASSTYPE_INTERFACE_UNKNOWN_X
- (t, finfo->interface_unknown);
- }
- reset_specialization();
-
- /* Make a declaration for this class in its own scope. */
- build_self_reference ();
-
- return t;
-}
-
-/* Finish the member declaration given by DECL. */
-
-void
-finish_member_declaration (tree decl)
-{
- if (decl == error_mark_node || decl == NULL_TREE)
- return;
-
- if (decl == void_type_node)
- /* The COMPONENT was a friend, not a member, and so there's
- nothing for us to do. */
- return;
-
- /* We should see only one DECL at a time. */
- gcc_assert (TREE_CHAIN (decl) == NULL_TREE);
-
- /* Set up access control for DECL. */
- TREE_PRIVATE (decl)
- = (current_access_specifier == access_private_node);
- TREE_PROTECTED (decl)
- = (current_access_specifier == access_protected_node);
- if (TREE_CODE (decl) == TEMPLATE_DECL)
- {
- TREE_PRIVATE (DECL_TEMPLATE_RESULT (decl)) = TREE_PRIVATE (decl);
- TREE_PROTECTED (DECL_TEMPLATE_RESULT (decl)) = TREE_PROTECTED (decl);
- }
-
- /* Mark the DECL as a member of the current class. */
- DECL_CONTEXT (decl) = current_class_type;
-
- /* [dcl.link]
-
- A C language linkage is ignored for the names of class members
- and the member function type of class member functions. */
- if (DECL_LANG_SPECIFIC (decl) && DECL_LANGUAGE (decl) == lang_c)
- SET_DECL_LANGUAGE (decl, lang_cplusplus);
-
- /* Put functions on the TYPE_METHODS list and everything else on the
- TYPE_FIELDS list. Note that these are built up in reverse order.
- We reverse them (to obtain declaration order) in finish_struct. */
- if (TREE_CODE (decl) == FUNCTION_DECL
- || DECL_FUNCTION_TEMPLATE_P (decl))
- {
- /* We also need to add this function to the
- CLASSTYPE_METHOD_VEC. */
- if (add_method (current_class_type, decl, NULL_TREE))
- {
- TREE_CHAIN (decl) = TYPE_METHODS (current_class_type);
- TYPE_METHODS (current_class_type) = decl;
-
- maybe_add_class_template_decl_list (current_class_type, decl,
- /*friend_p=*/0);
- }
- }
- /* Enter the DECL into the scope of the class. */
- else if ((TREE_CODE (decl) == USING_DECL && !DECL_DEPENDENT_P (decl))
- || pushdecl_class_level (decl))
- {
- /* All TYPE_DECLs go at the end of TYPE_FIELDS. Ordinary fields
- go at the beginning. The reason is that lookup_field_1
- searches the list in order, and we want a field name to
- override a type name so that the "struct stat hack" will
- work. In particular:
-
- struct S { enum E { }; int E } s;
- s.E = 3;
-
- is valid. In addition, the FIELD_DECLs must be maintained in
- declaration order so that class layout works as expected.
- However, we don't need that order until class layout, so we
- save a little time by putting FIELD_DECLs on in reverse order
- here, and then reversing them in finish_struct_1. (We could
- also keep a pointer to the correct insertion points in the
- list.) */
-
- if (TREE_CODE (decl) == TYPE_DECL)
- TYPE_FIELDS (current_class_type)
- = chainon (TYPE_FIELDS (current_class_type), decl);
- else
- {
- TREE_CHAIN (decl) = TYPE_FIELDS (current_class_type);
- TYPE_FIELDS (current_class_type) = decl;
- }
-
- maybe_add_class_template_decl_list (current_class_type, decl,
- /*friend_p=*/0);
- }
-
- if (pch_file)
- note_decl_for_pch (decl);
-}
-
-/* DECL has been declared while we are building a PCH file. Perform
- actions that we might normally undertake lazily, but which can be
- performed now so that they do not have to be performed in
- translation units which include the PCH file. */
-
-void
-note_decl_for_pch (tree decl)
-{
- gcc_assert (pch_file);
-
- /* There's a good chance that we'll have to mangle names at some
- point, even if only for emission in debugging information. */
- if ((TREE_CODE (decl) == VAR_DECL
- || TREE_CODE (decl) == FUNCTION_DECL)
- && !processing_template_decl)
- mangle_decl (decl);
-}
-
-/* Finish processing a complete template declaration. The PARMS are
- the template parameters. */
-
-void
-finish_template_decl (tree parms)
-{
- if (parms)
- end_template_decl ();
- else
- end_specialization ();
-}
-
-/* Finish processing a template-id (which names a type) of the form
- NAME < ARGS >. Return the TYPE_DECL for the type named by the
- template-id. If ENTERING_SCOPE is nonzero we are about to enter
- the scope of template-id indicated. */
-
-tree
-finish_template_type (tree name, tree args, int entering_scope)
-{
- tree decl;
-
- decl = lookup_template_class (name, args,
- NULL_TREE, NULL_TREE, entering_scope,
- tf_warning_or_error | tf_user);
- if (decl != error_mark_node)
- decl = TYPE_STUB_DECL (decl);
-
- return decl;
-}
-
-/* Finish processing a BASE_CLASS with the indicated ACCESS_SPECIFIER.
- Return a TREE_LIST containing the ACCESS_SPECIFIER and the
- BASE_CLASS, or NULL_TREE if an error occurred. The
- ACCESS_SPECIFIER is one of
- access_{default,public,protected_private}_node. For a virtual base
- we set TREE_TYPE. */
-
-tree
-finish_base_specifier (tree base, tree access, bool virtual_p)
-{
- tree result;
-
- if (base == error_mark_node)
- {
- error ("invalid base-class specification");
- result = NULL_TREE;
- }
- else if (! is_aggr_type (base, 1))
- result = NULL_TREE;
- else
- {
- if (cp_type_quals (base) != 0)
- {
- error ("base class %qT has cv qualifiers", base);
- base = TYPE_MAIN_VARIANT (base);
- }
- result = build_tree_list (access, base);
- if (virtual_p)
- TREE_TYPE (result) = integer_type_node;
- }
-
- return result;
-}
-
-/* Issue a diagnostic that NAME cannot be found in SCOPE. DECL is
- what we found when we tried to do the lookup. */
-
-void
-qualified_name_lookup_error (tree scope, tree name, tree decl)
-{
- if (scope == error_mark_node)
- ; /* We already complained. */
- else if (TYPE_P (scope))
- {
- if (!COMPLETE_TYPE_P (scope))
- error ("incomplete type %qT used in nested name specifier", scope);
- else if (TREE_CODE (decl) == TREE_LIST)
- {
- error ("reference to %<%T::%D%> is ambiguous", scope, name);
- print_candidates (decl);
- }
- else
- error ("%qD is not a member of %qT", name, scope);
- }
- else if (scope != global_namespace)
- error ("%qD is not a member of %qD", name, scope);
- else
- error ("%<::%D%> has not been declared", name);
-}
-
-/* If FNS is a member function, a set of member functions, or a
- template-id referring to one or more member functions, return a
- BASELINK for FNS, incorporating the current access context.
- Otherwise, return FNS unchanged. */
-
-tree
-baselink_for_fns (tree fns)
-{
- tree fn;
- tree cl;
-
- if (BASELINK_P (fns)
- || error_operand_p (fns))
- return fns;
-
- fn = fns;
- if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
- fn = TREE_OPERAND (fn, 0);
- fn = get_first_fn (fn);
- if (!DECL_FUNCTION_MEMBER_P (fn))
- return fns;
-
- cl = currently_open_derived_class (DECL_CONTEXT (fn));
- if (!cl)
- cl = DECL_CONTEXT (fn);
- cl = TYPE_BINFO (cl);
- return build_baselink (cl, cl, fns, /*optype=*/NULL_TREE);
-}
-
-/* ID_EXPRESSION is a representation of parsed, but unprocessed,
- id-expression. (See cp_parser_id_expression for details.) SCOPE,
- if non-NULL, is the type or namespace used to explicitly qualify
- ID_EXPRESSION. DECL is the entity to which that name has been
- resolved.
-
- *CONSTANT_EXPRESSION_P is true if we are presently parsing a
- constant-expression. In that case, *NON_CONSTANT_EXPRESSION_P will
- be set to true if this expression isn't permitted in a
- constant-expression, but it is otherwise not set by this function.
- *ALLOW_NON_CONSTANT_EXPRESSION_P is true if we are parsing a
- constant-expression, but a non-constant expression is also
- permissible.
-
- DONE is true if this expression is a complete postfix-expression;
- it is false if this expression is followed by '->', '[', '(', etc.
- ADDRESS_P is true iff this expression is the operand of '&'.
- TEMPLATE_P is true iff the qualified-id was of the form
- "A::template B". TEMPLATE_ARG_P is true iff this qualified name
- appears as a template argument.
-
- If an error occurs, and it is the kind of error that might cause
- the parser to abort a tentative parse, *ERROR_MSG is filled in. It
- is the caller's responsibility to issue the message. *ERROR_MSG
- will be a string with static storage duration, so the caller need
- not "free" it.
-
- Return an expression for the entity, after issuing appropriate
- diagnostics. This function is also responsible for transforming a
- reference to a non-static member into a COMPONENT_REF that makes
- the use of "this" explicit.
-
- Upon return, *IDK will be filled in appropriately. */
-
-tree
-finish_id_expression (tree id_expression,
- tree decl,
- tree scope,
- cp_id_kind *idk,
- bool integral_constant_expression_p,
- bool allow_non_integral_constant_expression_p,
- bool *non_integral_constant_expression_p,
- bool template_p,
- bool done,
- bool address_p,
- bool template_arg_p,
- const char **error_msg)
-{
- /* Initialize the output parameters. */
- *idk = CP_ID_KIND_NONE;
- *error_msg = NULL;
-
- if (id_expression == error_mark_node)
- return error_mark_node;
- /* If we have a template-id, then no further lookup is
- required. If the template-id was for a template-class, we
- will sometimes have a TYPE_DECL at this point. */
- else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
- || TREE_CODE (decl) == TYPE_DECL)
- ;
- /* Look up the name. */
- else
- {
- if (decl == error_mark_node)
- {
- /* Name lookup failed. */
- if (scope
- && (!TYPE_P (scope)
- || (!dependent_type_p (scope)
- && !(TREE_CODE (id_expression) == IDENTIFIER_NODE
- && IDENTIFIER_TYPENAME_P (id_expression)
- && dependent_type_p (TREE_TYPE (id_expression))))))
- {
- /* If the qualifying type is non-dependent (and the name
- does not name a conversion operator to a dependent
- type), issue an error. */
- qualified_name_lookup_error (scope, id_expression, decl);
- return error_mark_node;
- }
- else if (!scope)
- {
- /* It may be resolved via Koenig lookup. */
- *idk = CP_ID_KIND_UNQUALIFIED;
- return id_expression;
- }
- else
- decl = id_expression;
- }
- /* If DECL is a variable that would be out of scope under
- ANSI/ISO rules, but in scope in the ARM, name lookup
- will succeed. Issue a diagnostic here. */
- else
- decl = check_for_out_of_scope_variable (decl);
-
- /* Remember that the name was used in the definition of
- the current class so that we can check later to see if
- the meaning would have been different after the class
- was entirely defined. */
- if (!scope && decl != error_mark_node)
- maybe_note_name_used_in_class (id_expression, decl);
-
- /* Disallow uses of local variables from containing functions. */
- if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
- {
- tree context = decl_function_context (decl);
- if (context != NULL_TREE && context != current_function_decl
- && ! TREE_STATIC (decl))
- {
- error (TREE_CODE (decl) == VAR_DECL
- ? "use of %<auto%> variable from containing function"
- : "use of parameter from containing function");
- error (" %q+#D declared here", decl);
- return error_mark_node;
- }
- }
- }
-
- /* If we didn't find anything, or what we found was a type,
- then this wasn't really an id-expression. */
- if (TREE_CODE (decl) == TEMPLATE_DECL
- && !DECL_FUNCTION_TEMPLATE_P (decl))
- {
- *error_msg = "missing template arguments";
- return error_mark_node;
- }
- else if (TREE_CODE (decl) == TYPE_DECL
- || TREE_CODE (decl) == NAMESPACE_DECL)
- {
- *error_msg = "expected primary-expression";
- return error_mark_node;
- }
-
- /* If the name resolved to a template parameter, there is no
- need to look it up again later. */
- if ((TREE_CODE (decl) == CONST_DECL && DECL_TEMPLATE_PARM_P (decl))
- || TREE_CODE (decl) == TEMPLATE_PARM_INDEX)
- {
- tree r;
-
- *idk = CP_ID_KIND_NONE;
- if (TREE_CODE (decl) == TEMPLATE_PARM_INDEX)
- decl = TEMPLATE_PARM_DECL (decl);
- r = convert_from_reference (DECL_INITIAL (decl));
-
- if (integral_constant_expression_p
- && !dependent_type_p (TREE_TYPE (decl))
- && !(INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (r))))
- {
- if (!allow_non_integral_constant_expression_p)
- error ("template parameter %qD of type %qT is not allowed in "
- "an integral constant expression because it is not of "
- "integral or enumeration type", decl, TREE_TYPE (decl));
- *non_integral_constant_expression_p = true;
- }
- return r;
- }
- /* Similarly, we resolve enumeration constants to their
- underlying values. */
- else if (TREE_CODE (decl) == CONST_DECL)
- {
- *idk = CP_ID_KIND_NONE;
- if (!processing_template_decl)
- {
- used_types_insert (TREE_TYPE (decl));
- return DECL_INITIAL (decl);
- }
- return decl;
- }
- else
- {
- bool dependent_p;
-
- /* If the declaration was explicitly qualified indicate
- that. The semantics of `A::f(3)' are different than
- `f(3)' if `f' is virtual. */
- *idk = (scope
- ? CP_ID_KIND_QUALIFIED
- : (TREE_CODE (decl) == TEMPLATE_ID_EXPR
- ? CP_ID_KIND_TEMPLATE_ID
- : CP_ID_KIND_UNQUALIFIED));
-
-
- /* [temp.dep.expr]
-
- An id-expression is type-dependent if it contains an
- identifier that was declared with a dependent type.
-
- The standard is not very specific about an id-expression that
- names a set of overloaded functions. What if some of them
- have dependent types and some of them do not? Presumably,
- such a name should be treated as a dependent name. */
- /* Assume the name is not dependent. */
- dependent_p = false;
- if (!processing_template_decl)
- /* No names are dependent outside a template. */
- ;
- /* A template-id where the name of the template was not resolved
- is definitely dependent. */
- else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
- && (TREE_CODE (TREE_OPERAND (decl, 0))
- == IDENTIFIER_NODE))
- dependent_p = true;
- /* For anything except an overloaded function, just check its
- type. */
- else if (!is_overloaded_fn (decl))
- dependent_p
- = dependent_type_p (TREE_TYPE (decl));
- /* For a set of overloaded functions, check each of the
- functions. */
- else
- {
- tree fns = decl;
-
- if (BASELINK_P (fns))
- fns = BASELINK_FUNCTIONS (fns);
-
- /* For a template-id, check to see if the template
- arguments are dependent. */
- if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
- {
- tree args = TREE_OPERAND (fns, 1);
- dependent_p = any_dependent_template_arguments_p (args);
- /* The functions are those referred to by the
- template-id. */
- fns = TREE_OPERAND (fns, 0);
- }
-
- /* If there are no dependent template arguments, go through
- the overloaded functions. */
- while (fns && !dependent_p)
- {
- tree fn = OVL_CURRENT (fns);
-
- /* Member functions of dependent classes are
- dependent. */
- if (TREE_CODE (fn) == FUNCTION_DECL
- && type_dependent_expression_p (fn))
- dependent_p = true;
- else if (TREE_CODE (fn) == TEMPLATE_DECL
- && dependent_template_p (fn))
- dependent_p = true;
-
- fns = OVL_NEXT (fns);
- }
- }
-
- /* If the name was dependent on a template parameter, we will
- resolve the name at instantiation time. */
- if (dependent_p)
- {
- /* Create a SCOPE_REF for qualified names, if the scope is
- dependent. */
- if (scope)
- {
- /* Since this name was dependent, the expression isn't
- constant -- yet. No error is issued because it might
- be constant when things are instantiated. */
- if (integral_constant_expression_p)
- *non_integral_constant_expression_p = true;
- if (TYPE_P (scope))
- {
- if (address_p && done)
- decl = finish_qualified_id_expr (scope, decl,
- done, address_p,
- template_p,
- template_arg_p);
- else if (dependent_type_p (scope))
- decl = build_qualified_name (/*type=*/NULL_TREE,
- scope,
- id_expression,
- template_p);
- else if (DECL_P (decl))
- decl = build_qualified_name (TREE_TYPE (decl),
- scope,
- id_expression,
- template_p);
- }
- if (TREE_TYPE (decl))
- decl = convert_from_reference (decl);
- return decl;
- }
- /* A TEMPLATE_ID already contains all the information we
- need. */
- if (TREE_CODE (id_expression) == TEMPLATE_ID_EXPR)
- return id_expression;
- *idk = CP_ID_KIND_UNQUALIFIED_DEPENDENT;
- /* If we found a variable, then name lookup during the
- instantiation will always resolve to the same VAR_DECL
- (or an instantiation thereof). */
- if (TREE_CODE (decl) == VAR_DECL
- || TREE_CODE (decl) == PARM_DECL)
- return convert_from_reference (decl);
- /* The same is true for FIELD_DECL, but we also need to
- make sure that the syntax is correct. */
- else if (TREE_CODE (decl) == FIELD_DECL)
- {
- /* Since SCOPE is NULL here, this is an unqualified name.
- Access checking has been performed during name lookup
- already. Turn off checking to avoid duplicate errors. */
- push_deferring_access_checks (dk_no_check);
- decl = finish_non_static_data_member
- (decl, current_class_ref,
- /*qualifying_scope=*/NULL_TREE);
- pop_deferring_access_checks ();
- return decl;
- }
- return id_expression;
- }
-
- /* Only certain kinds of names are allowed in constant
- expression. Enumerators and template parameters have already
- been handled above. */
- if (integral_constant_expression_p
- && ! DECL_INTEGRAL_CONSTANT_VAR_P (decl)
- && ! builtin_valid_in_constant_expr_p (decl))
- {
- if (!allow_non_integral_constant_expression_p)
- {
- error ("%qD cannot appear in a constant-expression", decl);
- return error_mark_node;
- }
- *non_integral_constant_expression_p = true;
- }
-
- if (TREE_CODE (decl) == NAMESPACE_DECL)
- {
- error ("use of namespace %qD as expression", decl);
- return error_mark_node;
- }
- else if (DECL_CLASS_TEMPLATE_P (decl))
- {
- error ("use of class template %qT as expression", decl);
- return error_mark_node;
- }
- else if (TREE_CODE (decl) == TREE_LIST)
- {
- /* Ambiguous reference to base members. */
- error ("request for member %qD is ambiguous in "
- "multiple inheritance lattice", id_expression);
- print_candidates (decl);
- return error_mark_node;
- }
-
- /* Mark variable-like entities as used. Functions are similarly
- marked either below or after overload resolution. */
- if (TREE_CODE (decl) == VAR_DECL
- || TREE_CODE (decl) == PARM_DECL
- || TREE_CODE (decl) == RESULT_DECL)
- mark_used (decl);
-
- if (scope)
- {
- decl = (adjust_result_of_qualified_name_lookup
- (decl, scope, current_class_type));
-
- if (TREE_CODE (decl) == FUNCTION_DECL)
- mark_used (decl);
-
- if (TREE_CODE (decl) == FIELD_DECL || BASELINK_P (decl))
- decl = finish_qualified_id_expr (scope,
- decl,
- done,
- address_p,
- template_p,
- template_arg_p);
- else
- {
- tree r = convert_from_reference (decl);
-
- if (processing_template_decl && TYPE_P (scope))
- r = build_qualified_name (TREE_TYPE (r),
- scope, decl,
- template_p);
- decl = r;
- }
- }
- else if (TREE_CODE (decl) == FIELD_DECL)
- {
- /* Since SCOPE is NULL here, this is an unqualified name.
- Access checking has been performed during name lookup
- already. Turn off checking to avoid duplicate errors. */
- push_deferring_access_checks (dk_no_check);
- decl = finish_non_static_data_member (decl, current_class_ref,
- /*qualifying_scope=*/NULL_TREE);
- pop_deferring_access_checks ();
- }
- else if (is_overloaded_fn (decl))
- {
- tree first_fn;
-
- first_fn = decl;
- if (TREE_CODE (first_fn) == TEMPLATE_ID_EXPR)
- first_fn = TREE_OPERAND (first_fn, 0);
- first_fn = get_first_fn (first_fn);
- if (TREE_CODE (first_fn) == TEMPLATE_DECL)
- first_fn = DECL_TEMPLATE_RESULT (first_fn);
-
- if (!really_overloaded_fn (decl))
- mark_used (first_fn);
-
- if (!template_arg_p
- && TREE_CODE (first_fn) == FUNCTION_DECL
- && DECL_FUNCTION_MEMBER_P (first_fn)
- && !shared_member_p (decl))
- {
- /* A set of member functions. */
- decl = maybe_dummy_object (DECL_CONTEXT (first_fn), 0);
- return finish_class_member_access_expr (decl, id_expression,
- /*template_p=*/false);
- }
-
- decl = baselink_for_fns (decl);
- }
- else
- {
- if (DECL_P (decl) && DECL_NONLOCAL (decl)
- && DECL_CLASS_SCOPE_P (decl)
- && DECL_CONTEXT (decl) != current_class_type)
- {
- tree path;
-
- path = currently_open_derived_class (DECL_CONTEXT (decl));
- perform_or_defer_access_check (TYPE_BINFO (path), decl, decl);
- }
-
- decl = convert_from_reference (decl);
- }
- }
-
- if (TREE_DEPRECATED (decl))
- warn_deprecated_use (decl);
-
- return decl;
-}
-
-/* Implement the __typeof keyword: Return the type of EXPR, suitable for
- use as a type-specifier. */
-
-tree
-finish_typeof (tree expr)
-{
- tree type;
-
- if (type_dependent_expression_p (expr))
- {
- type = make_aggr_type (TYPEOF_TYPE);
- TYPEOF_TYPE_EXPR (type) = expr;
-
- return type;
- }
-
- type = unlowered_expr_type (expr);
-
- if (!type || type == unknown_type_node)
- {
- error ("type of %qE is unknown", expr);
- return error_mark_node;
- }
-
- return type;
-}
-
-/* Perform C++-specific checks for __builtin_offsetof before calling
- fold_offsetof. */
-
-tree
-finish_offsetof (tree expr)
-{
- if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR)
- {
- error ("cannot apply %<offsetof%> to destructor %<~%T%>",
- TREE_OPERAND (expr, 2));
- return error_mark_node;
- }
- if (TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE
- || TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE
- || TREE_CODE (TREE_TYPE (expr)) == UNKNOWN_TYPE)
- {
- if (TREE_CODE (expr) == COMPONENT_REF
- || TREE_CODE (expr) == COMPOUND_EXPR)
- expr = TREE_OPERAND (expr, 1);
- error ("cannot apply %<offsetof%> to member function %qD", expr);
- return error_mark_node;
- }
- return fold_offsetof (expr, NULL_TREE);
-}
-
-/* Called from expand_body via walk_tree. Replace all AGGR_INIT_EXPRs
- with equivalent CALL_EXPRs. */
-
-static tree
-simplify_aggr_init_exprs_r (tree* tp,
- int* walk_subtrees,
- void* data ATTRIBUTE_UNUSED)
-{
- /* We don't need to walk into types; there's nothing in a type that
- needs simplification. (And, furthermore, there are places we
- actively don't want to go. For example, we don't want to wander
- into the default arguments for a FUNCTION_DECL that appears in a
- CALL_EXPR.) */
- if (TYPE_P (*tp))
- {
- *walk_subtrees = 0;
- return NULL_TREE;
- }
- /* Only AGGR_INIT_EXPRs are interesting. */
- else if (TREE_CODE (*tp) != AGGR_INIT_EXPR)
- return NULL_TREE;
-
- simplify_aggr_init_expr (tp);
-
- /* Keep iterating. */
- return NULL_TREE;
-}
-
-/* Replace the AGGR_INIT_EXPR at *TP with an equivalent CALL_EXPR. This
- function is broken out from the above for the benefit of the tree-ssa
- project. */
-
-void
-simplify_aggr_init_expr (tree *tp)
-{
- tree aggr_init_expr = *tp;
-
- /* Form an appropriate CALL_EXPR. */
- tree fn = TREE_OPERAND (aggr_init_expr, 0);
- tree args = TREE_OPERAND (aggr_init_expr, 1);
- tree slot = TREE_OPERAND (aggr_init_expr, 2);
- tree type = TREE_TYPE (slot);
-
- tree call_expr;
- enum style_t { ctor, arg, pcc } style;
-
- if (AGGR_INIT_VIA_CTOR_P (aggr_init_expr))
- style = ctor;
-#ifdef PCC_STATIC_STRUCT_RETURN
- else if (1)
- style = pcc;
-#endif
- else
- {
- gcc_assert (TREE_ADDRESSABLE (type));
- style = arg;
- }
-
- if (style == ctor)
- {
- /* Replace the first argument to the ctor with the address of the
- slot. */
- tree addr;
-
- args = TREE_CHAIN (args);
- cxx_mark_addressable (slot);
- addr = build1 (ADDR_EXPR, build_pointer_type (type), slot);
- args = tree_cons (NULL_TREE, addr, args);
- }
-
- call_expr = build3 (CALL_EXPR,
- TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
- fn, args, NULL_TREE);
-
- if (style == arg)
- {
- /* Just mark it addressable here, and leave the rest to
- expand_call{,_inline}. */
- cxx_mark_addressable (slot);
- CALL_EXPR_RETURN_SLOT_OPT (call_expr) = true;
- call_expr = build2 (MODIFY_EXPR, TREE_TYPE (call_expr), slot, call_expr);
- }
- else if (style == pcc)
- {
- /* If we're using the non-reentrant PCC calling convention, then we
- need to copy the returned value out of the static buffer into the
- SLOT. */
- push_deferring_access_checks (dk_no_check);
- call_expr = build_aggr_init (slot, call_expr,
- DIRECT_BIND | LOOKUP_ONLYCONVERTING);
- pop_deferring_access_checks ();
- call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (slot), call_expr, slot);
- }
-
- *tp = call_expr;
-}
-
-/* Emit all thunks to FN that should be emitted when FN is emitted. */
-
-static void
-emit_associated_thunks (tree fn)
-{
- /* When we use vcall offsets, we emit thunks with the virtual
- functions to which they thunk. The whole point of vcall offsets
- is so that you can know statically the entire set of thunks that
- will ever be needed for a given virtual function, thereby
- enabling you to output all the thunks with the function itself. */
- if (DECL_VIRTUAL_P (fn))
- {
- tree thunk;
-
- for (thunk = DECL_THUNKS (fn); thunk; thunk = TREE_CHAIN (thunk))
- {
- if (!THUNK_ALIAS (thunk))
- {
- use_thunk (thunk, /*emit_p=*/1);
- if (DECL_RESULT_THUNK_P (thunk))
- {
- tree probe;
-
- for (probe = DECL_THUNKS (thunk);
- probe; probe = TREE_CHAIN (probe))
- use_thunk (probe, /*emit_p=*/1);
- }
- }
- else
- gcc_assert (!DECL_THUNKS (thunk));
- }
- }
-}
-
-/* Generate RTL for FN. */
-
-void
-expand_body (tree fn)
-{
- tree saved_function;
-
- /* Compute the appropriate object-file linkage for inline
- functions. */
- if (DECL_DECLARED_INLINE_P (fn))
- import_export_decl (fn);
-
- /* If FN is external, then there's no point in generating RTL for
- it. This situation can arise with an inline function under
- `-fexternal-templates'; we instantiate the function, even though
- we're not planning on emitting it, in case we get a chance to
- inline it. */
- if (DECL_EXTERNAL (fn))
- return;
-
- /* ??? When is this needed? */
- saved_function = current_function_decl;
-
- /* Emit any thunks that should be emitted at the same time as FN. */
- emit_associated_thunks (fn);
-
- /* This function is only called from cgraph, or recursively from
- emit_associated_thunks. In neither case should we be currently
- generating trees for a function. */
- gcc_assert (function_depth == 0);
-
- tree_rest_of_compilation (fn);
-
- current_function_decl = saved_function;
-
- if (DECL_CLONED_FUNCTION_P (fn))
- {
- /* If this is a clone, go through the other clones now and mark
- their parameters used. We have to do that here, as we don't
- know whether any particular clone will be expanded, and
- therefore cannot pick one arbitrarily. */
- tree probe;
-
- for (probe = TREE_CHAIN (DECL_CLONED_FUNCTION (fn));
- probe && DECL_CLONED_FUNCTION_P (probe);
- probe = TREE_CHAIN (probe))
- {
- tree parms;
-
- for (parms = DECL_ARGUMENTS (probe);
- parms; parms = TREE_CHAIN (parms))
- TREE_USED (parms) = 1;
- }
- }
-}
-
-/* Generate RTL for FN. */
-
-void
-expand_or_defer_fn (tree fn)
-{
- /* When the parser calls us after finishing the body of a template
- function, we don't really want to expand the body. */
- if (processing_template_decl)
- {
- /* Normally, collection only occurs in rest_of_compilation. So,
- if we don't collect here, we never collect junk generated
- during the processing of templates until we hit a
- non-template function. It's not safe to do this inside a
- nested class, though, as the parser may have local state that
- is not a GC root. */
- if (!function_depth)
- ggc_collect ();
- return;
- }
-
- /* Replace AGGR_INIT_EXPRs with appropriate CALL_EXPRs. */
- walk_tree_without_duplicates (&DECL_SAVED_TREE (fn),
- simplify_aggr_init_exprs_r,
- NULL);
-
- /* If this is a constructor or destructor body, we have to clone
- it. */
- if (maybe_clone_body (fn))
- {
- /* We don't want to process FN again, so pretend we've written
- it out, even though we haven't. */
- TREE_ASM_WRITTEN (fn) = 1;
- return;
- }
-
- /* If this function is marked with the constructor attribute, add it
- to the list of functions to be called along with constructors
- from static duration objects. */
- if (DECL_STATIC_CONSTRUCTOR (fn))
- static_ctors = tree_cons (NULL_TREE, fn, static_ctors);
-
- /* If this function is marked with the destructor attribute, add it
- to the list of functions to be called along with destructors from
- static duration objects. */
- if (DECL_STATIC_DESTRUCTOR (fn))
- static_dtors = tree_cons (NULL_TREE, fn, static_dtors);
-
- /* We make a decision about linkage for these functions at the end
- of the compilation. Until that point, we do not want the back
- end to output them -- but we do want it to see the bodies of
- these functions so that it can inline them as appropriate. */
- if (DECL_DECLARED_INLINE_P (fn) || DECL_IMPLICIT_INSTANTIATION (fn))
- {
- if (DECL_INTERFACE_KNOWN (fn))
- /* We've already made a decision as to how this function will
- be handled. */;
- else if (!at_eof)
- {
- DECL_EXTERNAL (fn) = 1;
- DECL_NOT_REALLY_EXTERN (fn) = 1;
- note_vague_linkage_fn (fn);
- /* A non-template inline function with external linkage will
- always be COMDAT. As we must eventually determine the
- linkage of all functions, and as that causes writes to
- the data mapped in from the PCH file, it's advantageous
- to mark the functions at this point. */
- if (!DECL_IMPLICIT_INSTANTIATION (fn))
- {
- /* This function must have external linkage, as
- otherwise DECL_INTERFACE_KNOWN would have been
- set. */
- gcc_assert (TREE_PUBLIC (fn));
- comdat_linkage (fn);
- DECL_INTERFACE_KNOWN (fn) = 1;
- }
- }
- else
- import_export_decl (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))
- mark_needed (fn);
- }
-
- /* There's no reason to do any of the work here if we're only doing
- semantic analysis; this code just generates RTL. */
- if (flag_syntax_only)
- return;
-
- function_depth++;
-
- /* Expand or defer, at the whim of the compilation unit manager. */
- cgraph_finalize_function (fn, function_depth > 1);
-
- function_depth--;
-}
-
-struct nrv_data
-{
- tree var;
- tree result;
- htab_t visited;
-};
-
-/* Helper function for walk_tree, used by finalize_nrv below. */
-
-static tree
-finalize_nrv_r (tree* tp, int* walk_subtrees, void* data)
-{
- struct nrv_data *dp = (struct nrv_data *)data;
- void **slot;
-
- /* No need to walk into types. There wouldn't be any need to walk into
- non-statements, except that we have to consider STMT_EXPRs. */
- if (TYPE_P (*tp))
- *walk_subtrees = 0;
- /* Change all returns to just refer to the RESULT_DECL; this is a nop,
- but differs from using NULL_TREE in that it indicates that we care
- about the value of the RESULT_DECL. */
- else if (TREE_CODE (*tp) == RETURN_EXPR)
- TREE_OPERAND (*tp, 0) = dp->result;
- /* Change all cleanups for the NRV to only run when an exception is
- thrown. */
- else if (TREE_CODE (*tp) == CLEANUP_STMT
- && CLEANUP_DECL (*tp) == dp->var)
- CLEANUP_EH_ONLY (*tp) = 1;
- /* Replace the DECL_EXPR for the NRV with an initialization of the
- RESULT_DECL, if needed. */
- else if (TREE_CODE (*tp) == DECL_EXPR
- && DECL_EXPR_DECL (*tp) == dp->var)
- {
- tree init;
- if (DECL_INITIAL (dp->var)
- && DECL_INITIAL (dp->var) != error_mark_node)
- {
- init = build2 (INIT_EXPR, void_type_node, dp->result,
- DECL_INITIAL (dp->var));
- DECL_INITIAL (dp->var) = error_mark_node;
- }
- else
- init = build_empty_stmt ();
- SET_EXPR_LOCUS (init, EXPR_LOCUS (*tp));
- *tp = init;
- }
- /* And replace all uses of the NRV with the RESULT_DECL. */
- else if (*tp == dp->var)
- *tp = dp->result;
-
- /* Avoid walking into the same tree more than once. Unfortunately, we
- can't just use walk_tree_without duplicates because it would only call
- us for the first occurrence of dp->var in the function body. */
- slot = htab_find_slot (dp->visited, *tp, INSERT);
- if (*slot)
- *walk_subtrees = 0;
- else
- *slot = *tp;
-
- /* Keep iterating. */
- return NULL_TREE;
-}
-
-/* Called from finish_function to implement the named return value
- optimization by overriding all the RETURN_EXPRs and pertinent
- CLEANUP_STMTs and replacing all occurrences of VAR with RESULT, the
- RESULT_DECL for the function. */
-
-void
-finalize_nrv (tree *tp, tree var, tree result)
-{
- struct nrv_data data;
-
- /* Copy debugging information from VAR to RESULT. */
- DECL_NAME (result) = DECL_NAME (var);
- DECL_ARTIFICIAL (result) = DECL_ARTIFICIAL (var);
- DECL_IGNORED_P (result) = DECL_IGNORED_P (var);
- DECL_SOURCE_LOCATION (result) = DECL_SOURCE_LOCATION (var);
- DECL_ABSTRACT_ORIGIN (result) = DECL_ABSTRACT_ORIGIN (var);
- /* Don't forget that we take its address. */
- TREE_ADDRESSABLE (result) = TREE_ADDRESSABLE (var);
-
- data.var = var;
- data.result = result;
- data.visited = htab_create (37, htab_hash_pointer, htab_eq_pointer, NULL);
- walk_tree (tp, finalize_nrv_r, &data, 0);
- htab_delete (data.visited);
-}
-
-/* For all elements of CLAUSES, validate them vs OpenMP constraints.
- Remove any elements from the list that are invalid. */
-
-tree
-finish_omp_clauses (tree clauses)
-{
- bitmap_head generic_head, firstprivate_head, lastprivate_head;
- tree c, t, *pc = &clauses;
- const char *name;
-
- bitmap_obstack_initialize (NULL);
- bitmap_initialize (&generic_head, &bitmap_default_obstack);
- bitmap_initialize (&firstprivate_head, &bitmap_default_obstack);
- bitmap_initialize (&lastprivate_head, &bitmap_default_obstack);
-
- for (pc = &clauses, c = clauses; c ; c = *pc)
- {
- bool remove = false;
-
- switch (OMP_CLAUSE_CODE (c))
- {
- case OMP_CLAUSE_SHARED:
- name = "shared";
- goto check_dup_generic;
- case OMP_CLAUSE_PRIVATE:
- name = "private";
- goto check_dup_generic;
- case OMP_CLAUSE_REDUCTION:
- name = "reduction";
- goto check_dup_generic;
- case OMP_CLAUSE_COPYPRIVATE:
- name = "copyprivate";
- goto check_dup_generic;
- case OMP_CLAUSE_COPYIN:
- name = "copyin";
- goto check_dup_generic;
- check_dup_generic:
- t = OMP_CLAUSE_DECL (c);
- if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
- {
- if (processing_template_decl)
- break;
- if (DECL_P (t))
- error ("%qD is not a variable in clause %qs", t, name);
- else
- error ("%qE is not a variable in clause %qs", t, name);
- remove = true;
- }
- else if (bitmap_bit_p (&generic_head, DECL_UID (t))
- || bitmap_bit_p (&firstprivate_head, DECL_UID (t))
- || bitmap_bit_p (&lastprivate_head, DECL_UID (t)))
- {
- error ("%qD appears more than once in data clauses", t);
- remove = true;
- }
- else
- bitmap_set_bit (&generic_head, DECL_UID (t));
- break;
-
- case OMP_CLAUSE_FIRSTPRIVATE:
- t = OMP_CLAUSE_DECL (c);
- if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
- {
- if (processing_template_decl)
- break;
- error ("%qE is not a variable in clause %<firstprivate%>", t);
- remove = true;
- }
- else if (bitmap_bit_p (&generic_head, DECL_UID (t))
- || bitmap_bit_p (&firstprivate_head, DECL_UID (t)))
- {
- error ("%qE appears more than once in data clauses", t);
- remove = true;
- }
- else
- bitmap_set_bit (&firstprivate_head, DECL_UID (t));
- break;
-
- case OMP_CLAUSE_LASTPRIVATE:
- t = OMP_CLAUSE_DECL (c);
- if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
- {
- if (processing_template_decl)
- break;
- error ("%qE is not a variable in clause %<lastprivate%>", t);
- remove = true;
- }
- else if (bitmap_bit_p (&generic_head, DECL_UID (t))
- || bitmap_bit_p (&lastprivate_head, DECL_UID (t)))
- {
- error ("%qE appears more than once in data clauses", t);
- remove = true;
- }
- else
- bitmap_set_bit (&lastprivate_head, DECL_UID (t));
- break;
-
- case OMP_CLAUSE_IF:
- t = OMP_CLAUSE_IF_EXPR (c);
- t = maybe_convert_cond (t);
- if (t == error_mark_node)
- remove = true;
- OMP_CLAUSE_IF_EXPR (c) = t;
- break;
-
- case OMP_CLAUSE_NUM_THREADS:
- t = OMP_CLAUSE_NUM_THREADS_EXPR (c);
- if (t == error_mark_node)
- remove = true;
- else if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
- && !type_dependent_expression_p (t))
- {
- error ("num_threads expression must be integral");
- remove = true;
- }
- break;
-
- case OMP_CLAUSE_SCHEDULE:
- t = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c);
- if (t == NULL)
- ;
- else if (t == error_mark_node)
- remove = true;
- else if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
- && !type_dependent_expression_p (t))
- {
- error ("schedule chunk size expression must be integral");
- remove = true;
- }
- break;
-
- case OMP_CLAUSE_NOWAIT:
- case OMP_CLAUSE_ORDERED:
- case OMP_CLAUSE_DEFAULT:
- break;
-
- default:
- gcc_unreachable ();
- }
-
- if (remove)
- *pc = OMP_CLAUSE_CHAIN (c);
- else
- pc = &OMP_CLAUSE_CHAIN (c);
- }
-
- for (pc = &clauses, c = clauses; c ; c = *pc)
- {
- enum tree_code c_kind = OMP_CLAUSE_CODE (c);
- bool remove = false;
- bool need_complete_non_reference = false;
- bool need_default_ctor = false;
- bool need_copy_ctor = false;
- bool need_copy_assignment = false;
- bool need_implicitly_determined = false;
- tree type, inner_type;
-
- switch (c_kind)
- {
- case OMP_CLAUSE_SHARED:
- name = "shared";
- need_implicitly_determined = true;
- break;
- case OMP_CLAUSE_PRIVATE:
- name = "private";
- need_complete_non_reference = true;
- need_default_ctor = true;
- need_implicitly_determined = true;
- break;
- case OMP_CLAUSE_FIRSTPRIVATE:
- name = "firstprivate";
- need_complete_non_reference = true;
- need_copy_ctor = true;
- need_implicitly_determined = true;
- break;
- case OMP_CLAUSE_LASTPRIVATE:
- name = "lastprivate";
- need_complete_non_reference = true;
- need_copy_assignment = true;
- need_implicitly_determined = true;
- break;
- case OMP_CLAUSE_REDUCTION:
- name = "reduction";
- need_implicitly_determined = true;
- break;
- case OMP_CLAUSE_COPYPRIVATE:
- name = "copyprivate";
- need_copy_assignment = true;
- break;
- case OMP_CLAUSE_COPYIN:
- name = "copyin";
- need_copy_assignment = true;
- break;
- default:
- pc = &OMP_CLAUSE_CHAIN (c);
- continue;
- }
-
- t = OMP_CLAUSE_DECL (c);
- if (processing_template_decl
- && TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
- {
- pc = &OMP_CLAUSE_CHAIN (c);
- continue;
- }
-
- switch (c_kind)
- {
- case OMP_CLAUSE_LASTPRIVATE:
- if (!bitmap_bit_p (&firstprivate_head, DECL_UID (t)))
- need_default_ctor = true;
- break;
-
- case OMP_CLAUSE_REDUCTION:
- if (AGGREGATE_TYPE_P (TREE_TYPE (t))
- || POINTER_TYPE_P (TREE_TYPE (t)))
- {
- error ("%qE has invalid type for %<reduction%>", t);
- remove = true;
- }
- else if (FLOAT_TYPE_P (TREE_TYPE (t)))
- {
- enum tree_code r_code = OMP_CLAUSE_REDUCTION_CODE (c);
- switch (r_code)
- {
- case PLUS_EXPR:
- case MULT_EXPR:
- case MINUS_EXPR:
- break;
- default:
- error ("%qE has invalid type for %<reduction(%s)%>",
- t, operator_name_info[r_code].name);
- remove = true;
- }
- }
- break;
-
- case OMP_CLAUSE_COPYIN:
- if (TREE_CODE (t) != VAR_DECL || !DECL_THREAD_LOCAL_P (t))
- {
- error ("%qE must be %<threadprivate%> for %<copyin%>", t);
- remove = true;
- }
- break;
-
- default:
- break;
- }
-
- if (need_complete_non_reference)
- {
- t = require_complete_type (t);
- if (t == error_mark_node)
- remove = true;
- else if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
- {
- error ("%qE has reference type for %qs", t, name);
- remove = true;
- }
- }
- if (need_implicitly_determined)
- {
- const char *share_name = NULL;
-
- if (TREE_CODE (t) == VAR_DECL && DECL_THREAD_LOCAL_P (t))
- share_name = "threadprivate";
- else switch (cxx_omp_predetermined_sharing (t))
- {
- case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
- break;
- case OMP_CLAUSE_DEFAULT_SHARED:
- share_name = "shared";
- break;
- case OMP_CLAUSE_DEFAULT_PRIVATE:
- share_name = "private";
- break;
- default:
- gcc_unreachable ();
- }
- if (share_name)
- {
- error ("%qE is predetermined %qs for %qs",
- t, share_name, name);
- remove = true;
- }
- }
-
- /* We're interested in the base element, not arrays. */
- inner_type = type = TREE_TYPE (t);
- while (TREE_CODE (inner_type) == ARRAY_TYPE)
- inner_type = TREE_TYPE (inner_type);
-
- /* Check for special function availability by building a call to one.
- Save the results, because later we won't be in the right context
- for making these queries. */
- if (CLASS_TYPE_P (inner_type)
- && (need_default_ctor || need_copy_ctor || need_copy_assignment)
- && !type_dependent_expression_p (t))
- {
- int save_errorcount = errorcount;
- tree info;
-
- /* Always allocate 3 elements for simplicity. These are the
- function decls for the ctor, dtor, and assignment op.
- This layout is known to the three lang hooks,
- cxx_omp_clause_default_init, cxx_omp_clause_copy_init,
- and cxx_omp_clause_assign_op. */
- info = make_tree_vec (3);
- CP_OMP_CLAUSE_INFO (c) = info;
-
- if (need_default_ctor
- || (need_copy_ctor
- && !TYPE_HAS_TRIVIAL_INIT_REF (inner_type)))
- {
- if (need_default_ctor)
- t = NULL;
- else
- {
- t = build_int_cst (build_pointer_type (inner_type), 0);
- t = build1 (INDIRECT_REF, inner_type, t);
- t = build_tree_list (NULL, t);
- }
- t = build_special_member_call (NULL_TREE,
- complete_ctor_identifier,
- t, inner_type, LOOKUP_NORMAL);
- t = get_callee_fndecl (t);
- TREE_VEC_ELT (info, 0) = t;
- }
-
- if ((need_default_ctor || need_copy_ctor)
- && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (inner_type))
- {
- t = build_int_cst (build_pointer_type (inner_type), 0);
- t = build1 (INDIRECT_REF, inner_type, t);
- t = build_special_member_call (t, complete_dtor_identifier,
- NULL, inner_type, LOOKUP_NORMAL);
- t = get_callee_fndecl (t);
- TREE_VEC_ELT (info, 1) = t;
- }
-
- if (need_copy_assignment
- && !TYPE_HAS_TRIVIAL_ASSIGN_REF (inner_type))
- {
- t = build_int_cst (build_pointer_type (inner_type), 0);
- t = build1 (INDIRECT_REF, inner_type, t);
- t = build_special_member_call (t, ansi_assopname (NOP_EXPR),
- build_tree_list (NULL, t),
- inner_type, LOOKUP_NORMAL);
-
- /* We'll have called convert_from_reference on the call, which
- may well have added an indirect_ref. It's unneeded here,
- and in the way, so kill it. */
- if (TREE_CODE (t) == INDIRECT_REF)
- t = TREE_OPERAND (t, 0);
-
- t = get_callee_fndecl (t);
- TREE_VEC_ELT (info, 2) = t;
- }
-
- if (errorcount != save_errorcount)
- remove = true;
- }
-
- if (remove)
- *pc = OMP_CLAUSE_CHAIN (c);
- else
- pc = &OMP_CLAUSE_CHAIN (c);
- }
-
- bitmap_obstack_release (NULL);
- return clauses;
-}
-
-/* For all variables in the tree_list VARS, mark them as thread local. */
-
-void
-finish_omp_threadprivate (tree vars)
-{
- tree t;
-
- /* Mark every variable in VARS to be assigned thread local storage. */
- for (t = vars; t; t = TREE_CHAIN (t))
- {
- tree v = TREE_PURPOSE (t);
-
- /* If V had already been marked threadprivate, it doesn't matter
- whether it had been used prior to this point. */
- if (TREE_USED (v)
- && (DECL_LANG_SPECIFIC (v) == NULL
- || !CP_DECL_THREADPRIVATE_P (v)))
- error ("%qE declared %<threadprivate%> after first use", v);
- else if (! TREE_STATIC (v) && ! DECL_EXTERNAL (v))
- error ("automatic variable %qE cannot be %<threadprivate%>", v);
- else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
- error ("%<threadprivate%> %qE has incomplete type", v);
- else if (TREE_STATIC (v) && TYPE_P (CP_DECL_CONTEXT (v)))
- error ("%<threadprivate%> %qE is not file, namespace "
- "or block scope variable", v);
- else
- {
- /* Allocate a LANG_SPECIFIC structure for V, if needed. */
- if (DECL_LANG_SPECIFIC (v) == NULL)
- {
- retrofit_lang_decl (v);
-
- /* Make sure that DECL_DISCRIMINATOR_P continues to be true
- after the allocation of the lang_decl structure. */
- if (DECL_DISCRIMINATOR_P (v))
- DECL_LANG_SPECIFIC (v)->decl_flags.u2sel = 1;
- }
-
- if (! DECL_THREAD_LOCAL_P (v))
- {
- DECL_TLS_MODEL (v) = decl_default_tls_model (v);
- /* If rtl has been already set for this var, call
- make_decl_rtl once again, so that encode_section_info
- has a chance to look at the new decl flags. */
- if (DECL_RTL_SET_P (v))
- make_decl_rtl (v);
- }
- CP_DECL_THREADPRIVATE_P (v) = 1;
- }
- }
-}
-
-/* Build an OpenMP structured block. */
-
-tree
-begin_omp_structured_block (void)
-{
- return do_pushlevel (sk_omp);
-}
-
-tree
-finish_omp_structured_block (tree block)
-{
- return do_poplevel (block);
-}
-
-/* Similarly, except force the retention of the BLOCK. */
-
-tree
-begin_omp_parallel (void)
-{
- keep_next_level (true);
- return begin_omp_structured_block ();
-}
-
-tree
-finish_omp_parallel (tree clauses, tree body)
-{
- tree stmt;
-
- body = finish_omp_structured_block (body);
-
- stmt = make_node (OMP_PARALLEL);
- TREE_TYPE (stmt) = void_type_node;
- OMP_PARALLEL_CLAUSES (stmt) = clauses;
- OMP_PARALLEL_BODY (stmt) = body;
-
- return add_stmt (stmt);
-}
-
-/* Build and validate an OMP_FOR statement. CLAUSES, BODY, COND, INCR
- are directly for their associated operands in the statement. DECL
- and INIT are a combo; if DECL is NULL then INIT ought to be a
- MODIFY_EXPR, and the DECL should be extracted. PRE_BODY are
- optional statements that need to go before the loop into its
- sk_omp scope. */
-
-tree
-finish_omp_for (location_t locus, tree decl, tree init, tree cond,
- tree incr, tree body, tree pre_body)
-{
- if (decl == NULL)
- {
- if (init != NULL)
- switch (TREE_CODE (init))
- {
- case MODIFY_EXPR:
- decl = TREE_OPERAND (init, 0);
- init = TREE_OPERAND (init, 1);
- break;
- case MODOP_EXPR:
- if (TREE_CODE (TREE_OPERAND (init, 1)) == NOP_EXPR)
- {
- decl = TREE_OPERAND (init, 0);
- init = TREE_OPERAND (init, 2);
- }
- break;
- default:
- break;
- }
-
- if (decl == NULL)
- {
- error ("expected iteration declaration or initialization");
- return NULL;
- }
- }
-
- if (type_dependent_expression_p (decl)
- || type_dependent_expression_p (init)
- || (cond && type_dependent_expression_p (cond))
- || (incr && type_dependent_expression_p (incr)))
- {
- tree stmt;
-
- if (cond == NULL)
- {
- error ("%Hmissing controlling predicate", &locus);
- return NULL;
- }
-
- if (incr == NULL)
- {
- error ("%Hmissing increment expression", &locus);
- return NULL;
- }
-
- stmt = make_node (OMP_FOR);
-
- /* This is really just a place-holder. We'll be decomposing this
- again and going through the build_modify_expr path below when
- we instantiate the thing. */
- init = build2 (MODIFY_EXPR, void_type_node, decl, init);
-
- TREE_TYPE (stmt) = void_type_node;
- OMP_FOR_INIT (stmt) = init;
- OMP_FOR_COND (stmt) = cond;
- OMP_FOR_INCR (stmt) = incr;
- OMP_FOR_BODY (stmt) = body;
- OMP_FOR_PRE_BODY (stmt) = pre_body;
-
- SET_EXPR_LOCATION (stmt, locus);
- return add_stmt (stmt);
- }
-
- if (!DECL_P (decl))
- {
- error ("expected iteration declaration or initialization");
- return NULL;
- }
-
- if (pre_body == NULL || IS_EMPTY_STMT (pre_body))
- pre_body = NULL;
- else if (! processing_template_decl)
- {
- add_stmt (pre_body);
- pre_body = NULL;
- }
- init = build_modify_expr (decl, NOP_EXPR, init);
- return c_finish_omp_for (locus, decl, init, cond, incr, body, pre_body);
-}
-
-void
-finish_omp_atomic (enum tree_code code, tree lhs, tree rhs)
-{
- tree orig_lhs;
- tree orig_rhs;
- bool dependent_p;
- tree stmt;
-
- orig_lhs = lhs;
- orig_rhs = rhs;
- dependent_p = false;
- stmt = NULL_TREE;
-
- /* Even in a template, we can detect invalid uses of the atomic
- pragma if neither LHS nor RHS is type-dependent. */
- if (processing_template_decl)
- {
- dependent_p = (type_dependent_expression_p (lhs)
- || type_dependent_expression_p (rhs));
- if (!dependent_p)
- {
- lhs = build_non_dependent_expr (lhs);
- rhs = build_non_dependent_expr (rhs);
- }
- }
- if (!dependent_p)
- {
- stmt = c_finish_omp_atomic (code, lhs, rhs);
- if (stmt == error_mark_node)
- return;
- }
- if (processing_template_decl)
- {
- stmt = build2 (OMP_ATOMIC, void_type_node, orig_lhs, orig_rhs);
- OMP_ATOMIC_DEPENDENT_P (stmt) = 1;
- OMP_ATOMIC_CODE (stmt) = code;
- }
- add_stmt (stmt);
-}
-
-void
-finish_omp_barrier (void)
-{
- tree fn = built_in_decls[BUILT_IN_GOMP_BARRIER];
- tree stmt = finish_call_expr (fn, NULL, false, false);
- finish_expr_stmt (stmt);
-}
-
-void
-finish_omp_flush (void)
-{
- tree fn = built_in_decls[BUILT_IN_SYNCHRONIZE];
- tree stmt = finish_call_expr (fn, NULL, false, false);
- finish_expr_stmt (stmt);
-}
-
-/* True if OpenMP sharing attribute of DECL is predetermined. */
-
-enum omp_clause_default_kind
-cxx_omp_predetermined_sharing (tree decl)
-{
- enum omp_clause_default_kind kind;
-
- kind = c_omp_predetermined_sharing (decl);
- if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
- return kind;
-
- /* Static data members are predetermined as shared. */
- if (TREE_STATIC (decl))
- {
- tree ctx = CP_DECL_CONTEXT (decl);
- if (TYPE_P (ctx) && IS_AGGR_TYPE (ctx))
- return OMP_CLAUSE_DEFAULT_SHARED;
- }
-
- return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
-}
-
-void
-init_cp_semantics (void)
-{
-}
-
-#include "gt-cp-semantics.h"
diff --git a/gcc-4.8/gcc/collect2.c.orig b/gcc-4.8/gcc/collect2.c.orig
deleted file mode 100644
index bc180eb04..000000000
--- a/gcc-4.8/gcc/collect2.c.orig
+++ /dev/null
@@ -1,3117 +0,0 @@
-/* Collect static initialization info into data structures that can be
- traversed by C++ initialization and finalization routines.
- Copyright (C) 1992-2013 Free Software Foundation, Inc.
- Contributed by Chris Smith (csmith@convex.com).
- Heavily modified by Michael Meissner (meissner@cygnus.com),
- Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 3, or (at your option) any later
-version.
-
-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
-
-
-/* Build tables of static constructors and destructors and run ld. */
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "tm.h"
-#include "filenames.h"
-#include "file-find.h"
-
-/* TARGET_64BIT may be defined to use driver specific functionality. */
-#undef TARGET_64BIT
-#define TARGET_64BIT TARGET_64BIT_DEFAULT
-
-#ifndef LIBRARY_PATH_ENV
-#define LIBRARY_PATH_ENV "LIBRARY_PATH"
-#endif
-
-#define COLLECT
-
-#include "collect2.h"
-#include "collect2-aix.h"
-#include "diagnostic.h"
-#include "demangle.h"
-#include "obstack.h"
-#include "intl.h"
-#include "version.h"
-
-/* On certain systems, we have code that works by scanning the object file
- directly. But this code uses system-specific header files and library
- functions, so turn it off in a cross-compiler. Likewise, the names of
- the utilities are not correct for a cross-compiler; we have to hope that
- cross-versions are in the proper directories. */
-
-#ifdef CROSS_DIRECTORY_STRUCTURE
-#ifndef CROSS_AIX_SUPPORT
-#undef OBJECT_FORMAT_COFF
-#endif
-#undef MD_EXEC_PREFIX
-#undef REAL_LD_FILE_NAME
-#undef REAL_NM_FILE_NAME
-#undef REAL_STRIP_FILE_NAME
-#endif
-
-/* If we cannot use a special method, use the ordinary one:
- run nm to find what symbols are present.
- In a cross-compiler, this means you need a cross nm,
- but that is not quite as unpleasant as special headers. */
-
-#if !defined (OBJECT_FORMAT_COFF)
-#define OBJECT_FORMAT_NONE
-#endif
-
-#ifdef OBJECT_FORMAT_COFF
-
-#ifndef CROSS_DIRECTORY_STRUCTURE
-#include <a.out.h>
-#include <ar.h>
-
-#ifdef UMAX
-#include <sgs.h>
-#endif
-
-/* Many versions of ldfcn.h define these. */
-#ifdef FREAD
-#undef FREAD
-#undef FWRITE
-#endif
-
-#include <ldfcn.h>
-#endif
-
-/* Some systems have an ISCOFF macro, but others do not. In some cases
- the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
- that either do not have an ISCOFF macro in /usr/include or for those
- where it is wrong. */
-
-#ifndef MY_ISCOFF
-#define MY_ISCOFF(X) ISCOFF (X)
-#endif
-
-#endif /* OBJECT_FORMAT_COFF */
-
-#ifdef OBJECT_FORMAT_NONE
-
-/* Default flags to pass to nm. */
-#ifndef NM_FLAGS
-#define NM_FLAGS "-n"
-#endif
-
-#endif /* OBJECT_FORMAT_NONE */
-
-/* Some systems use __main in a way incompatible with its use in gcc, in these
- cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
- give the same symbol without quotes for an alternative entry point. */
-#ifndef NAME__MAIN
-#define NAME__MAIN "__main"
-#endif
-
-/* This must match tree.h. */
-#define DEFAULT_INIT_PRIORITY 65535
-
-#ifndef COLLECT_SHARED_INIT_FUNC
-#define COLLECT_SHARED_INIT_FUNC(STREAM, FUNC) \
- fprintf ((STREAM), "void _GLOBAL__DI() {\n\t%s();\n}\n", (FUNC))
-#endif
-#ifndef COLLECT_SHARED_FINI_FUNC
-#define COLLECT_SHARED_FINI_FUNC(STREAM, FUNC) \
- fprintf ((STREAM), "void _GLOBAL__DD() {\n\t%s();\n}\n", (FUNC))
-#endif
-
-#ifdef LDD_SUFFIX
-#define SCAN_LIBRARIES
-#endif
-
-#ifndef SHLIB_SUFFIX
-#define SHLIB_SUFFIX ".so"
-#endif
-
-#ifdef USE_COLLECT2
-int do_collecting = 1;
-#else
-int do_collecting = 0;
-#endif
-
-/* Cook up an always defined indication of whether we proceed the
- "EXPORT_LIST" way. */
-
-#ifdef COLLECT_EXPORT_LIST
-#define DO_COLLECT_EXPORT_LIST 1
-#else
-#define DO_COLLECT_EXPORT_LIST 0
-#endif
-
-/* Nonzero if we should suppress the automatic demangling of identifiers
- in linker error messages. Set from COLLECT_NO_DEMANGLE. */
-int no_demangle;
-
-/* Linked lists of constructor and destructor names. */
-
-struct id
-{
- struct id *next;
- int sequence;
- char name[1];
-};
-
-struct head
-{
- struct id *first;
- struct id *last;
- int number;
-};
-
-bool vflag; /* true if -v or --version */
-static int rflag; /* true if -r */
-static int strip_flag; /* true if -s */
-#ifdef COLLECT_EXPORT_LIST
-static int export_flag; /* true if -bE */
-static int aix64_flag; /* true if -b64 */
-static int aixrtl_flag; /* true if -brtl */
-#endif
-
-enum lto_mode_d {
- LTO_MODE_NONE, /* Not doing LTO. */
- LTO_MODE_LTO, /* Normal LTO. */
- LTO_MODE_WHOPR /* WHOPR. */
-};
-
-/* Current LTO mode. */
-static enum lto_mode_d lto_mode = LTO_MODE_NONE;
-
-bool debug; /* true if -debug */
-bool helpflag; /* true if --help */
-
-static int shared_obj; /* true if -shared */
-
-static const char *c_file; /* <xxx>.c for constructor/destructor list. */
-static const char *o_file; /* <xxx>.o for constructor/destructor list. */
-#ifdef COLLECT_EXPORT_LIST
-static const char *export_file; /* <xxx>.x for AIX export list. */
-#endif
-static char **lto_o_files; /* Output files for LTO. */
-const char *ldout; /* File for ld stdout. */
-const char *lderrout; /* File for ld stderr. */
-static const char *output_file; /* Output file for ld. */
-static const char *nm_file_name; /* pathname of nm */
-#ifdef LDD_SUFFIX
-static const char *ldd_file_name; /* pathname of ldd (or equivalent) */
-#endif
-static const char *strip_file_name; /* pathname of strip */
-const char *c_file_name; /* pathname of gcc */
-static char *initname, *fininame; /* names of init and fini funcs */
-
-static struct head constructors; /* list of constructors found */
-static struct head destructors; /* list of destructors found */
-#ifdef COLLECT_EXPORT_LIST
-static struct head exports; /* list of exported symbols */
-#endif
-static struct head frame_tables; /* list of frame unwind info tables */
-
-static bool at_file_supplied; /* Whether to use @file arguments */
-static char *response_file; /* Name of any current response file */
-
-struct obstack temporary_obstack;
-char * temporary_firstobj;
-
-/* A string that must be prepended to a target OS path in order to find
- it on the host system. */
-#ifdef TARGET_SYSTEM_ROOT
-static const char *target_system_root = TARGET_SYSTEM_ROOT;
-#else
-static const char *target_system_root = "";
-#endif
-
-/* Whether we may unlink the output file, which should be set as soon as we
- know we have successfully produced it. This is typically useful to prevent
- blindly attempting to unlink a read-only output that the target linker
- would leave untouched. */
-bool may_unlink_output_file = false;
-
-#ifdef COLLECT_EXPORT_LIST
-/* Lists to keep libraries to be scanned for global constructors/destructors. */
-static struct head libs; /* list of libraries */
-static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */
-static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */
-static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
- &libpath_lib_dirs, NULL};
-#endif
-
-/* List of names of object files containing LTO information.
- These are a subset of the object file names appearing on the
- command line, and must be identical, in the sense of pointer
- equality, with the names passed to maybe_run_lto_and_relink(). */
-
-struct lto_object
-{
- const char *name; /* Name of object file. */
- struct lto_object *next; /* Next in linked list. */
-};
-
-struct lto_object_list
-{
- struct lto_object *first; /* First list element. */
- struct lto_object *last; /* Last list element. */
-};
-
-static struct lto_object_list lto_objects;
-
-/* Special kinds of symbols that a name may denote. */
-
-typedef enum {
- SYM_REGULAR = 0, /* nothing special */
-
- SYM_CTOR = 1, /* constructor */
- SYM_DTOR = 2, /* destructor */
- SYM_INIT = 3, /* shared object routine that calls all the ctors */
- SYM_FINI = 4, /* shared object routine that calls all the dtors */
- SYM_DWEH = 5 /* DWARF exception handling table */
-} symkind;
-
-static symkind is_ctor_dtor (const char *);
-
-static void handler (int);
-static void do_wait (const char *, struct pex_obj *);
-static void fork_execute (const char *, char **);
-static void maybe_unlink (const char *);
-static void maybe_unlink_list (char **);
-static void add_to_list (struct head *, const char *);
-static int extract_init_priority (const char *);
-static void sort_ids (struct head *);
-static void write_list (FILE *, const char *, struct id *);
-#ifdef COLLECT_EXPORT_LIST
-static void dump_list (FILE *, const char *, struct id *);
-#endif
-#if 0
-static void dump_prefix_list (FILE *, const char *, struct prefix_list *);
-#endif
-static void write_list_with_asm (FILE *, const char *, struct id *);
-static void write_c_file (FILE *, const char *);
-static void write_c_file_stat (FILE *, const char *);
-#ifndef LD_INIT_SWITCH
-static void write_c_file_glob (FILE *, const char *);
-#endif
-#ifdef SCAN_LIBRARIES
-static void scan_libraries (const char *);
-#endif
-#ifdef COLLECT_EXPORT_LIST
-#if 0
-static int is_in_list (const char *, struct id *);
-#endif
-static void write_aix_file (FILE *, struct id *);
-static char *resolve_lib_name (const char *);
-#endif
-static char *extract_string (const char **);
-static void post_ld_pass (bool);
-static void process_args (int *argcp, char **argv);
-
-/* Enumerations describing which pass this is for scanning the
- program file ... */
-
-typedef enum {
- PASS_FIRST, /* without constructors */
- PASS_OBJ, /* individual objects */
- PASS_LIB, /* looking for shared libraries */
- PASS_SECOND, /* with constructors linked in */
- PASS_LTOINFO /* looking for objects with LTO info */
-} scanpass;
-
-/* ... and which kinds of symbols are to be considered. */
-
-enum scanfilter_masks {
- SCAN_NOTHING = 0,
-
- SCAN_CTOR = 1 << SYM_CTOR,
- SCAN_DTOR = 1 << SYM_DTOR,
- SCAN_INIT = 1 << SYM_INIT,
- SCAN_FINI = 1 << SYM_FINI,
- SCAN_DWEH = 1 << SYM_DWEH,
- SCAN_ALL = ~0
-};
-
-/* This type is used for parameters and variables which hold
- combinations of the flags in enum scanfilter_masks. */
-typedef int scanfilter;
-
-/* Scan the name list of the loaded program for the symbols g++ uses for
- static constructors and destructors.
-
- The SCANPASS argument tells which collect processing pass this is for and
- the SCANFILTER argument tells which kinds of symbols to consider in this
- pass. Symbols of a special kind not in the filter mask are considered as
- regular ones.
-
- The constructor table begins at __CTOR_LIST__ and contains a count of the
- number of pointers (or -1 if the constructors are built in a separate
- section by the linker), followed by the pointers to the constructor
- functions, terminated with a null pointer. The destructor table has the
- same format, and begins at __DTOR_LIST__. */
-
-static void scan_prog_file (const char *, scanpass, scanfilter);
-
-
-/* Delete tempfiles and exit function. */
-
-void
-collect_exit (int status)
-{
- if (c_file != 0 && c_file[0])
- maybe_unlink (c_file);
-
- if (o_file != 0 && o_file[0])
- maybe_unlink (o_file);
-
-#ifdef COLLECT_EXPORT_LIST
- if (export_file != 0 && export_file[0])
- maybe_unlink (export_file);
-#endif
-
- if (lto_o_files)
- maybe_unlink_list (lto_o_files);
-
- if (ldout != 0 && ldout[0])
- {
- dump_ld_file (ldout, stdout);
- maybe_unlink (ldout);
- }
-
- if (lderrout != 0 && lderrout[0])
- {
- dump_ld_file (lderrout, stderr);
- maybe_unlink (lderrout);
- }
-
- if (status != 0 && output_file != 0 && output_file[0])
- maybe_unlink (output_file);
-
- if (response_file)
- maybe_unlink (response_file);
-
- exit (status);
-}
-
-
-/* Notify user of a non-error. */
-void
-notice (const char *cmsgid, ...)
-{
- va_list ap;
-
- va_start (ap, cmsgid);
- vfprintf (stderr, _(cmsgid), ap);
- va_end (ap);
-}
-
-/* Notify user of a non-error, without translating the format string. */
-void
-notice_translated (const char *cmsgid, ...)
-{
- va_list ap;
-
- va_start (ap, cmsgid);
- vfprintf (stderr, cmsgid, ap);
- va_end (ap);
-}
-
-static void
-handler (int signo)
-{
- if (c_file != 0 && c_file[0])
- maybe_unlink (c_file);
-
- if (o_file != 0 && o_file[0])
- maybe_unlink (o_file);
-
- if (ldout != 0 && ldout[0])
- maybe_unlink (ldout);
-
- if (lderrout != 0 && lderrout[0])
- maybe_unlink (lderrout);
-
-#ifdef COLLECT_EXPORT_LIST
- if (export_file != 0 && export_file[0])
- maybe_unlink (export_file);
-#endif
-
- if (lto_o_files)
- maybe_unlink_list (lto_o_files);
-
- if (response_file)
- maybe_unlink (response_file);
-
- signal (signo, SIG_DFL);
- raise (signo);
-}
-
-
-int
-file_exists (const char *name)
-{
- return access (name, R_OK) == 0;
-}
-
-/* Parse a reasonable subset of shell quoting syntax. */
-
-static char *
-extract_string (const char **pp)
-{
- const char *p = *pp;
- int backquote = 0;
- int inside = 0;
-
- for (;;)
- {
- char c = *p;
- if (c == '\0')
- break;
- ++p;
- if (backquote)
- obstack_1grow (&temporary_obstack, c);
- else if (! inside && c == ' ')
- break;
- else if (! inside && c == '\\')
- backquote = 1;
- else if (c == '\'')
- inside = !inside;
- else
- obstack_1grow (&temporary_obstack, c);
- }
-
- obstack_1grow (&temporary_obstack, '\0');
- *pp = p;
- return XOBFINISH (&temporary_obstack, char *);
-}
-
-void
-dump_ld_file (const char *name, FILE *to)
-{
- FILE *stream = fopen (name, "r");
-
- if (stream == 0)
- return;
- while (1)
- {
- int c;
- while (c = getc (stream),
- c != EOF && (ISIDNUM (c) || c == '$' || c == '.'))
- obstack_1grow (&temporary_obstack, c);
- if (obstack_object_size (&temporary_obstack) > 0)
- {
- const char *word, *p;
- char *result;
- obstack_1grow (&temporary_obstack, '\0');
- word = XOBFINISH (&temporary_obstack, const char *);
-
- if (*word == '.')
- ++word, putc ('.', to);
- p = word;
- if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)))
- p += strlen (USER_LABEL_PREFIX);
-
-#ifdef HAVE_LD_DEMANGLE
- result = 0;
-#else
- if (no_demangle)
- result = 0;
- else
- result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
-#endif
-
- if (result)
- {
- int diff;
- fputs (result, to);
-
- diff = strlen (word) - strlen (result);
- while (diff > 0 && c == ' ')
- --diff, putc (' ', to);
- if (diff < 0 && c == ' ')
- {
- while (diff < 0 && c == ' ')
- ++diff, c = getc (stream);
- if (!ISSPACE (c))
- {
- /* Make sure we output at least one space, or
- the demangled symbol name will run into
- whatever text follows. */
- putc (' ', to);
- }
- }
-
- free (result);
- }
- else
- fputs (word, to);
-
- fflush (to);
- obstack_free (&temporary_obstack, temporary_firstobj);
- }
- if (c == EOF)
- break;
- putc (c, to);
- }
- fclose (stream);
-}
-
-/* Return the kind of symbol denoted by name S. */
-
-static symkind
-is_ctor_dtor (const char *s)
-{
- struct names { const char *const name; const int len; symkind ret;
- const int two_underscores; };
-
- const struct names *p;
- int ch;
- const char *orig_s = s;
-
- static const struct names special[] = {
-#ifndef NO_DOLLAR_IN_LABEL
- { "GLOBAL__I$", sizeof ("GLOBAL__I$")-1, SYM_CTOR, 0 },
- { "GLOBAL__D$", sizeof ("GLOBAL__D$")-1, SYM_DTOR, 0 },
-#else
-#ifndef NO_DOT_IN_LABEL
- { "GLOBAL__I.", sizeof ("GLOBAL__I.")-1, SYM_CTOR, 0 },
- { "GLOBAL__D.", sizeof ("GLOBAL__D.")-1, SYM_DTOR, 0 },
-#endif /* NO_DOT_IN_LABEL */
-#endif /* NO_DOLLAR_IN_LABEL */
- { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, SYM_CTOR, 0 },
- { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, SYM_DTOR, 0 },
- { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, SYM_DWEH, 0 },
- { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, SYM_INIT, 0 },
- { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, SYM_FINI, 0 },
- { NULL, 0, SYM_REGULAR, 0 }
- };
-
- while ((ch = *s) == '_')
- ++s;
-
- if (s == orig_s)
- return SYM_REGULAR;
-
- for (p = &special[0]; p->len > 0; p++)
- {
- if (ch == p->name[0]
- && (!p->two_underscores || ((s - orig_s) >= 2))
- && strncmp(s, p->name, p->len) == 0)
- {
- return p->ret;
- }
- }
- return SYM_REGULAR;
-}
-
-/* We maintain two prefix lists: one from COMPILER_PATH environment variable
- and one from the PATH variable. */
-
-static struct path_prefix cpath, path;
-
-#ifdef CROSS_DIRECTORY_STRUCTURE
-/* This is the name of the target machine. We use it to form the name
- of the files to execute. */
-
-static const char *const target_machine = TARGET_MACHINE;
-#endif
-
-/* Search for NAME using prefix list PPREFIX. We only look for executable
- files.
-
- Return 0 if not found, otherwise return its name, allocated with malloc. */
-
-#ifdef OBJECT_FORMAT_NONE
-
-/* Add an entry for the object file NAME to object file list LIST.
- New entries are added at the end of the list. The original pointer
- value of NAME is preserved, i.e., no string copy is performed. */
-
-static void
-add_lto_object (struct lto_object_list *list, const char *name)
-{
- struct lto_object *n = XNEW (struct lto_object);
- n->name = name;
- n->next = NULL;
-
- if (list->last)
- list->last->next = n;
- else
- list->first = n;
-
- list->last = n;
-}
-#endif /* OBJECT_FORMAT_NONE */
-
-
-/* Perform a link-time recompilation and relink if any of the object
- files contain LTO info. The linker command line LTO_LD_ARGV
- represents the linker command that would produce a final executable
- without the use of LTO. OBJECT_LST is a vector of object file names
- appearing in LTO_LD_ARGV that are to be considered for link-time
- recompilation, where OBJECT is a pointer to the last valid element.
- (This awkward convention avoids an impedance mismatch with the
- usage of similarly-named variables in main().) The elements of
- OBJECT_LST must be identical, i.e., pointer equal, to the
- corresponding arguments in LTO_LD_ARGV.
-
- Upon entry, at least one linker run has been performed without the
- use of any LTO info that might be present. Any recompilations
- necessary for template instantiations have been performed, and
- initializer/finalizer tables have been created if needed and
- included in the linker command line LTO_LD_ARGV. If any of the
- object files contain LTO info, we run the LTO back end on all such
- files, and perform the final link with the LTO back end output
- substituted for the LTO-optimized files. In some cases, a final
- link with all link-time generated code has already been performed,
- so there is no need to relink if no LTO info is found. In other
- cases, our caller has not produced the final executable, and is
- relying on us to perform the required link whether LTO info is
- present or not. In that case, the FORCE argument should be true.
- Note that the linker command line argument LTO_LD_ARGV passed into
- this function may be modified in place. */
-
-static void
-maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
- const char **object, bool force)
-{
- const char **object_file = CONST_CAST2 (const char **, char **, object_lst);
-
- int num_lto_c_args = 1; /* Allow space for the terminating NULL. */
-
- while (object_file < object)
- {
- /* If file contains LTO info, add it to the list of LTO objects. */
- scan_prog_file (*object_file++, PASS_LTOINFO, SCAN_ALL);
-
- /* Increment the argument count by the number of object file arguments
- we will add. An upper bound suffices, so just count all of the
- object files regardless of whether they contain LTO info. */
- num_lto_c_args++;
- }
-
- if (lto_objects.first)
- {
- char **lto_c_argv;
- const char **lto_c_ptr;
- char **p;
- char **lto_o_ptr;
- struct lto_object *list;
- char *lto_wrapper = getenv ("COLLECT_LTO_WRAPPER");
- struct pex_obj *pex;
- const char *prog = "lto-wrapper";
- int lto_ld_argv_size = 0;
- char **out_lto_ld_argv;
- int out_lto_ld_argv_size;
- size_t num_files;
-
- if (!lto_wrapper)
- fatal_error ("COLLECT_LTO_WRAPPER must be set");
-
- num_lto_c_args++;
-
- /* There is at least one object file containing LTO info,
- so we need to run the LTO back end and relink.
-
- To do so we build updated ld arguments with first
- LTO object replaced by all partitions and other LTO
- objects removed. */
-
- lto_c_argv = (char **) xcalloc (sizeof (char *), num_lto_c_args);
- lto_c_ptr = CONST_CAST2 (const char **, char **, lto_c_argv);
-
- *lto_c_ptr++ = lto_wrapper;
-
- /* Add LTO objects to the wrapper command line. */
- for (list = lto_objects.first; list; list = list->next)
- *lto_c_ptr++ = list->name;
-
- *lto_c_ptr = NULL;
-
- /* Run the LTO back end. */
- pex = collect_execute (prog, lto_c_argv, NULL, NULL, PEX_SEARCH);
- {
- int c;
- FILE *stream;
- size_t i;
- char *start, *end;
-
- stream = pex_read_output (pex, 0);
- gcc_assert (stream);
-
- num_files = 0;
- while ((c = getc (stream)) != EOF)
- {
- obstack_1grow (&temporary_obstack, c);
- if (c == '\n')
- ++num_files;
- }
-
- lto_o_files = XNEWVEC (char *, num_files + 1);
- lto_o_files[num_files] = NULL;
- start = XOBFINISH (&temporary_obstack, char *);
- for (i = 0; i < num_files; ++i)
- {
- end = start;
- while (*end != '\n')
- ++end;
- *end = '\0';
-
- lto_o_files[i] = xstrdup (start);
-
- start = end + 1;
- }
-
- obstack_free (&temporary_obstack, temporary_firstobj);
- }
- do_wait (prog, pex);
- pex = NULL;
-
- /* Compute memory needed for new LD arguments. At most number of original arguemtns
- plus number of partitions. */
- for (lto_ld_argv_size = 0; lto_ld_argv[lto_ld_argv_size]; lto_ld_argv_size++)
- ;
- out_lto_ld_argv = XCNEWVEC(char *, num_files + lto_ld_argv_size + 1);
- out_lto_ld_argv_size = 0;
-
- /* After running the LTO back end, we will relink, substituting
- the LTO output for the object files that we submitted to the
- LTO. Here, we modify the linker command line for the relink. */
-
- /* Copy all arguments until we find first LTO file. */
- p = lto_ld_argv;
- while (*p != NULL)
- {
- for (list = lto_objects.first; list; list = list->next)
- if (*p == list->name) /* Note test for pointer equality! */
- break;
- if (list)
- break;
- out_lto_ld_argv[out_lto_ld_argv_size++] = *p++;
- }
-
- /* Now insert all LTO partitions. */
- lto_o_ptr = lto_o_files;
- while (*lto_o_ptr)
- out_lto_ld_argv[out_lto_ld_argv_size++] = *lto_o_ptr++;
-
- /* ... and copy the rest. */
- while (*p != NULL)
- {
- for (list = lto_objects.first; list; list = list->next)
- if (*p == list->name) /* Note test for pointer equality! */
- break;
- if (!list)
- out_lto_ld_argv[out_lto_ld_argv_size++] = *p;
- p++;
- }
- out_lto_ld_argv[out_lto_ld_argv_size++] = 0;
-
- /* Run the linker again, this time replacing the object files
- optimized by the LTO with the temporary file generated by the LTO. */
- fork_execute ("ld", out_lto_ld_argv);
- post_ld_pass (true);
- free (lto_ld_argv);
-
- maybe_unlink_list (lto_o_files);
- }
- else if (force)
- {
- /* Our caller is relying on us to do the link
- even though there is no LTO back end work to be done. */
- fork_execute ("ld", lto_ld_argv);
- post_ld_pass (false);
- }
-}
-
-/* Main program. */
-
-int
-main (int argc, char **argv)
-{
- enum linker_select
- {
- USE_DEFAULT_LD,
- USE_PLUGIN_LD,
- USE_GOLD_LD,
- USE_BFD_LD,
- USE_MCLD_LD,
- USE_LD_MAX
- } selected_linker = USE_DEFAULT_LD;
- static const char *const ld_suffixes[USE_LD_MAX] =
- {
- "ld",
- PLUGIN_LD_SUFFIX,
- "ld.gold",
- "ld.bfd",
- "ld.mcld"
- };
- static const char *const real_ld_suffix = "real-ld";
- static const char *const collect_ld_suffix = "collect-ld";
- static const char *const nm_suffix = "nm";
- static const char *const gnm_suffix = "gnm";
-#ifdef LDD_SUFFIX
- static const char *const ldd_suffix = LDD_SUFFIX;
-#endif
- static const char *const strip_suffix = "strip";
- static const char *const gstrip_suffix = "gstrip";
-
- const char *full_ld_suffixes[USE_LD_MAX];
-#ifdef CROSS_DIRECTORY_STRUCTURE
- /* If we look for a program in the compiler directories, we just use
- the short name, since these directories are already system-specific.
- But it we look for a program in the system directories, we need to
- qualify the program name with the target machine. */
-
- const char *const full_nm_suffix =
- concat (target_machine, "-", nm_suffix, NULL);
- const char *const full_gnm_suffix =
- concat (target_machine, "-", gnm_suffix, NULL);
-#ifdef LDD_SUFFIX
- const char *const full_ldd_suffix =
- concat (target_machine, "-", ldd_suffix, NULL);
-#endif
- const char *const full_strip_suffix =
- concat (target_machine, "-", strip_suffix, NULL);
- const char *const full_gstrip_suffix =
- concat (target_machine, "-", gstrip_suffix, NULL);
-#else
-#ifdef LDD_SUFFIX
- const char *const full_ldd_suffix = ldd_suffix;
-#endif
- const char *const full_nm_suffix = nm_suffix;
- const char *const full_gnm_suffix = gnm_suffix;
- const char *const full_strip_suffix = strip_suffix;
- const char *const full_gstrip_suffix = gstrip_suffix;
-#endif /* CROSS_DIRECTORY_STRUCTURE */
-
- const char *arg;
- FILE *outf;
-#ifdef COLLECT_EXPORT_LIST
- FILE *exportf;
-#endif
- const char *ld_file_name;
- const char *p;
- char **c_argv;
- const char **c_ptr;
- char **ld1_argv;
- const char **ld1;
- bool use_plugin = false;
- bool use_collect_ld = false;
-
- /* The kinds of symbols we will have to consider when scanning the
- outcome of a first pass link. This is ALL to start with, then might
- be adjusted before getting to the first pass link per se, typically on
- AIX where we perform an early scan of objects and libraries to fetch
- the list of global ctors/dtors and make sure they are not garbage
- collected. */
- scanfilter ld1_filter = SCAN_ALL;
-
- char **ld2_argv;
- const char **ld2;
- char **object_lst;
- const char **object;
-#ifdef TARGET_AIX_VERSION
- int object_nbr = argc;
-#endif
- int first_file;
- int num_c_args;
- char **old_argv;
- int i;
-
- for (i = 0; i < USE_LD_MAX; i++)
- full_ld_suffixes[i]
-#ifdef CROSS_DIRECTORY_STRUCTURE
- = concat (target_machine, "-", ld_suffixes[i], NULL);
-#else
- = ld_suffixes[i];
-#endif
-
- p = argv[0] + strlen (argv[0]);
- while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
- --p;
- progname = p;
-
- xmalloc_set_program_name (progname);
-
- old_argv = argv;
- expandargv (&argc, &argv);
- if (argv != old_argv)
- at_file_supplied = 1;
-
- process_args (&argc, argv);
-
- num_c_args = argc + 9;
-
-#ifndef HAVE_LD_DEMANGLE
- no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
-
- /* Suppress demangling by the real linker, which may be broken. */
- putenv (xstrdup ("COLLECT_NO_DEMANGLE=1"));
-#endif
-
-#if defined (COLLECT2_HOST_INITIALIZATION)
- /* Perform system dependent initialization, if necessary. */
- COLLECT2_HOST_INITIALIZATION;
-#endif
-
-#ifdef SIGCHLD
- /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
- receive the signal. A different setting is inheritable */
- signal (SIGCHLD, SIG_DFL);
-#endif
-
- /* Unlock the stdio streams. */
- unlock_std_streams ();
-
- gcc_init_libintl ();
-
- diagnostic_initialize (global_dc, 0);
-
- /* Do not invoke xcalloc before this point, since locale needs to be
- set first, in case a diagnostic is issued. */
-
- ld1_argv = XCNEWVEC (char *, argc + 4);
- ld1 = CONST_CAST2 (const char **, char **, ld1_argv);
- ld2_argv = XCNEWVEC (char *, argc + 11);
- ld2 = CONST_CAST2 (const char **, char **, ld2_argv);
- object_lst = XCNEWVEC (char *, argc);
- object = CONST_CAST2 (const char **, char **, object_lst);
-
-#ifdef DEBUG
- debug = 1;
-#endif
-
- /* Parse command line early for instances of -debug. This allows
- the debug flag to be set before functions like find_a_file()
- are called. We also look for the -flto or -flto-partition=none flag to know
- what LTO mode we are in. */
- {
- bool no_partition = false;
-
- for (i = 1; argv[i] != NULL; i ++)
- {
- if (! strcmp (argv[i], "-debug"))
- debug = true;
- else if (! strcmp (argv[i], "-flto-partition=none"))
- no_partition = true;
- else if ((! strncmp (argv[i], "-flto=", 6)
- || ! strcmp (argv[i], "-flto")) && ! use_plugin)
- lto_mode = LTO_MODE_WHOPR;
- else if (!strncmp (argv[i], "-fno-lto", 8))
- lto_mode = LTO_MODE_NONE;
- else if (! strcmp (argv[i], "-plugin"))
- {
- use_plugin = true;
- lto_mode = LTO_MODE_NONE;
- if (selected_linker == USE_DEFAULT_LD)
- selected_linker = USE_PLUGIN_LD;
- }
- else if (strcmp (argv[i], "-fuse-ld=bfd") == 0)
- selected_linker = USE_BFD_LD;
- else if (strcmp (argv[i], "-fuse-ld=gold") == 0)
- selected_linker = USE_GOLD_LD;
- else if (strcmp (argv[i], "-fuse-ld=mcld") == 0)
- selected_linker = USE_MCLD_LD;
-
-#ifdef COLLECT_EXPORT_LIST
- /* These flags are position independent, although their order
- is important - subsequent flags override earlier ones. */
- else if (strcmp (argv[i], "-b64") == 0)
- aix64_flag = 1;
- /* -bexport:filename always needs the :filename */
- else if (strncmp (argv[i], "-bE:", 4) == 0
- || strncmp (argv[i], "-bexport:", 9) == 0)
- export_flag = 1;
- else if (strcmp (argv[i], "-brtl") == 0
- || strcmp (argv[i], "-bsvr4") == 0
- || strcmp (argv[i], "-G") == 0)
- aixrtl_flag = 1;
- else if (strcmp (argv[i], "-bnortl") == 0)
- aixrtl_flag = 0;
-#endif
- }
- vflag = debug;
- find_file_set_debug (debug);
- if (no_partition && lto_mode == LTO_MODE_WHOPR)
- lto_mode = LTO_MODE_LTO;
- }
-
-#ifndef DEFAULT_A_OUT_NAME
- output_file = "a.out";
-#else
- output_file = DEFAULT_A_OUT_NAME;
-#endif
-
- obstack_begin (&temporary_obstack, 0);
- temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
-
-#ifndef HAVE_LD_DEMANGLE
- current_demangling_style = auto_demangling;
-#endif
- p = getenv ("COLLECT_GCC_OPTIONS");
- while (p && *p)
- {
- const char *q = extract_string (&p);
- if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
- num_c_args++;
- }
- obstack_free (&temporary_obstack, temporary_firstobj);
-
- /* -fno-profile-arcs -fno-test-coverage -fno-branch-probabilities
- -fno-exceptions -w -fno-whole-program */
- num_c_args += 6;
-
- c_argv = XCNEWVEC (char *, num_c_args);
- c_ptr = CONST_CAST2 (const char **, char **, c_argv);
-
- if (argc < 2)
- fatal_error ("no arguments");
-
-#ifdef SIGQUIT
- if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
- signal (SIGQUIT, handler);
-#endif
- if (signal (SIGINT, SIG_IGN) != SIG_IGN)
- signal (SIGINT, handler);
-#ifdef SIGALRM
- if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
- signal (SIGALRM, handler);
-#endif
-#ifdef SIGHUP
- if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
- signal (SIGHUP, handler);
-#endif
- if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
- signal (SIGSEGV, handler);
-#ifdef SIGBUS
- if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
- signal (SIGBUS, handler);
-#endif
-
- /* Extract COMPILER_PATH and PATH into our prefix list. */
- prefix_from_env ("COMPILER_PATH", &cpath);
- prefix_from_env ("PATH", &path);
-
- /* Try to discover a valid linker/nm/strip to use. */
-
- /* Maybe we know the right file to use (if not cross). */
- ld_file_name = 0;
-#ifdef DEFAULT_LINKER
- if (access (DEFAULT_LINKER, X_OK) == 0)
- ld_file_name = DEFAULT_LINKER;
- if (ld_file_name == 0)
-#endif
-#ifdef REAL_LD_FILE_NAME
- ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
- if (ld_file_name == 0)
-#endif
- /* Search the (target-specific) compiler dirs for ld'. */
- ld_file_name = find_a_file (&cpath, real_ld_suffix);
- /* Likewise for `collect-ld'. */
- if (ld_file_name == 0)
- {
- ld_file_name = find_a_file (&cpath, collect_ld_suffix);
- use_collect_ld = ld_file_name != 0;
- }
- /* Search the compiler directories for `ld'. We have protection against
- recursive calls in find_a_file. */
- if (ld_file_name == 0)
- ld_file_name = find_a_file (&cpath, ld_suffixes[selected_linker]);
- /* Search the ordinary system bin directories
- for `ld' (if native linking) or `TARGET-ld' (if cross). */
- if (ld_file_name == 0)
- ld_file_name = find_a_file (&path, full_ld_suffixes[selected_linker]);
-
-#ifdef REAL_NM_FILE_NAME
- nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
- if (nm_file_name == 0)
-#endif
- nm_file_name = find_a_file (&cpath, gnm_suffix);
- if (nm_file_name == 0)
- nm_file_name = find_a_file (&path, full_gnm_suffix);
- if (nm_file_name == 0)
- nm_file_name = find_a_file (&cpath, nm_suffix);
- if (nm_file_name == 0)
- nm_file_name = find_a_file (&path, full_nm_suffix);
-
-#ifdef LDD_SUFFIX
- ldd_file_name = find_a_file (&cpath, ldd_suffix);
- if (ldd_file_name == 0)
- ldd_file_name = find_a_file (&path, full_ldd_suffix);
-#endif
-
-#ifdef REAL_STRIP_FILE_NAME
- strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
- if (strip_file_name == 0)
-#endif
- strip_file_name = find_a_file (&cpath, gstrip_suffix);
- if (strip_file_name == 0)
- strip_file_name = find_a_file (&path, full_gstrip_suffix);
- if (strip_file_name == 0)
- strip_file_name = find_a_file (&cpath, strip_suffix);
- if (strip_file_name == 0)
- strip_file_name = find_a_file (&path, full_strip_suffix);
-
- /* Determine the full path name of the C compiler to use. */
- c_file_name = getenv ("COLLECT_GCC");
- if (c_file_name == 0)
- {
-#ifdef CROSS_DIRECTORY_STRUCTURE
- c_file_name = concat (target_machine, "-gcc", NULL);
-#else
- c_file_name = "gcc";
-#endif
- }
-
- p = find_a_file (&cpath, c_file_name);
-
- /* Here it should be safe to use the system search path since we should have
- already qualified the name of the compiler when it is needed. */
- if (p == 0)
- p = find_a_file (&path, c_file_name);
-
- if (p)
- c_file_name = p;
-
- *ld1++ = *ld2++ = ld_file_name;
-
- /* Make temp file names. */
- c_file = make_temp_file (".c");
- o_file = make_temp_file (".o");
-#ifdef COLLECT_EXPORT_LIST
- export_file = make_temp_file (".x");
-#endif
- ldout = make_temp_file (".ld");
- lderrout = make_temp_file (".le");
- *c_ptr++ = c_file_name;
- *c_ptr++ = "-x";
- *c_ptr++ = "c";
- *c_ptr++ = "-c";
- *c_ptr++ = "-o";
- *c_ptr++ = o_file;
-
-#ifdef COLLECT_EXPORT_LIST
- /* Generate a list of directories from LIBPATH. */
- prefix_from_env ("LIBPATH", &libpath_lib_dirs);
- /* Add to this list also two standard directories where
- AIX loader always searches for libraries. */
- add_prefix (&libpath_lib_dirs, "/lib");
- add_prefix (&libpath_lib_dirs, "/usr/lib");
-#endif
-
- /* Get any options that the upper GCC wants to pass to the sub-GCC.
-
- AIX support needs to know if -shared has been specified before
- parsing commandline arguments. */
-
- p = getenv ("COLLECT_GCC_OPTIONS");
- while (p && *p)
- {
- const char *q = extract_string (&p);
- if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
- *c_ptr++ = xstrdup (q);
- if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0)
- *c_ptr++ = xstrdup (q);
- if (strcmp (q, "-shared") == 0)
- shared_obj = 1;
- if (*q == '-' && q[1] == 'B')
- {
- *c_ptr++ = xstrdup (q);
- if (q[2] == 0)
- {
- q = extract_string (&p);
- *c_ptr++ = xstrdup (q);
- }
- }
- }
- obstack_free (&temporary_obstack, temporary_firstobj);
- *c_ptr++ = "-fno-profile-arcs";
- *c_ptr++ = "-fno-test-coverage";
- *c_ptr++ = "-fno-branch-probabilities";
- *c_ptr++ = "-fno-exceptions";
- *c_ptr++ = "-w";
- *c_ptr++ = "-fno-whole-program";
-
- /* !!! When GCC calls collect2,
- it does not know whether it is calling collect2 or ld.
- So collect2 cannot meaningfully understand any options
- except those ld understands.
- If you propose to make GCC pass some other option,
- just imagine what will happen if ld is really ld!!! */
-
- /* Parse arguments. Remember output file spec, pass the rest to ld. */
- /* After the first file, put in the c++ rt0. */
-
- first_file = 1;
- while ((arg = *++argv) != (char *) 0)
- {
- *ld1++ = *ld2++ = arg;
-
- if (arg[0] == '-')
- {
- switch (arg[1])
- {
- case 'd':
- if (!strcmp (arg, "-debug"))
- {
- /* Already parsed. */
- ld1--;
- ld2--;
- }
- if (!strcmp (arg, "-dynamic-linker") && argv[1])
- {
- ++argv;
- *ld1++ = *ld2++ = *argv;
- }
- break;
-
- case 'f':
- if (strncmp (arg, "-flto", 5) == 0)
- {
-#ifdef ENABLE_LTO
- /* Do not pass LTO flag to the linker. */
- ld1--;
- ld2--;
-#else
- error ("LTO support has not been enabled in this "
- "configuration");
-#endif
- }
- else if (!use_collect_ld
- && strncmp (arg, "-fuse-ld=", 9) == 0)
- {
- /* Do not pass -fuse-ld={bfd|gold|mcld} to the linker. */
- ld1--;
- ld2--;
- }
-#ifdef TARGET_AIX_VERSION
- else
- {
- /* File containing a list of input files to process. */
-
- FILE *stream;
- char buf[MAXPATHLEN + 2];
- /* Number of additionnal object files. */
- int add_nbr = 0;
- /* Maximum of additionnal object files before vector
- expansion. */
- int add_max = 0;
- const char *list_filename = arg + 2;
-
- /* Accept -fFILENAME and -f FILENAME. */
- if (*list_filename == '\0' && argv[1])
- {
- ++argv;
- list_filename = *argv;
- *ld1++ = *ld2++ = *argv;
- }
-
- stream = fopen (list_filename, "r");
- if (stream == NULL)
- fatal_error ("can't open %s: %m", list_filename);
-
- while (fgets (buf, sizeof buf, stream) != NULL)
- {
- /* Remove end of line. */
- int len = strlen (buf);
- if (len >= 1 && buf[len - 1] =='\n')
- buf[len - 1] = '\0';
-
- /* Put on object vector.
- Note: we only expanse vector here, so we must keep
- extra space for remaining arguments. */
- if (add_nbr >= add_max)
- {
- int pos =
- object - CONST_CAST2 (const char **, char **,
- object_lst);
- add_max = (add_max == 0) ? 16 : add_max * 2;
- object_lst = XRESIZEVEC (char *, object_lst,
- object_nbr + add_max);
- object = CONST_CAST2 (const char **, char **,
- object_lst) + pos;
- object_nbr += add_max;
- }
- *object++ = xstrdup (buf);
- add_nbr++;
- }
- fclose (stream);
- }
-#endif
- break;
-
- case 'l':
- if (first_file)
- {
- /* place o_file BEFORE this argument! */
- first_file = 0;
- ld2--;
- *ld2++ = o_file;
- *ld2++ = arg;
- }
-#ifdef COLLECT_EXPORT_LIST
- {
- /* Resolving full library name. */
- const char *s = resolve_lib_name (arg+2);
-
- /* Saving a full library name. */
- add_to_list (&libs, s);
- }
-#endif
- break;
-
-#ifdef COLLECT_EXPORT_LIST
- /* Saving directories where to search for libraries. */
- case 'L':
- add_prefix (&cmdline_lib_dirs, arg+2);
- break;
-#endif
-
- case 'o':
- if (arg[2] == '\0')
- output_file = *ld1++ = *ld2++ = *++argv;
- else
- output_file = &arg[2];
- break;
-
- case 'r':
- if (arg[2] == '\0')
- rflag = 1;
- break;
-
- case 's':
- if (arg[2] == '\0' && do_collecting)
- {
- /* We must strip after the nm run, otherwise C++ linking
- will not work. Thus we strip in the second ld run, or
- else with strip if there is no second ld run. */
- strip_flag = 1;
- ld1--;
- }
- break;
-
- case 'v':
- if (arg[2] == '\0')
- vflag = true;
- break;
-
- case '-':
- if (strcmp (arg, "--no-demangle") == 0)
- {
-#ifndef HAVE_LD_DEMANGLE
- no_demangle = 1;
- ld1--;
- ld2--;
-#endif
- }
- else if (strncmp (arg, "--demangle", 10) == 0)
- {
-#ifndef HAVE_LD_DEMANGLE
- no_demangle = 0;
- if (arg[10] == '=')
- {
- enum demangling_styles style
- = cplus_demangle_name_to_style (arg+11);
- if (style == unknown_demangling)
- error ("unknown demangling style '%s'", arg+11);
- else
- current_demangling_style = style;
- }
- ld1--;
- ld2--;
-#endif
- }
- else if (strncmp (arg, "--sysroot=", 10) == 0)
- target_system_root = arg + 10;
- else if (strcmp (arg, "--version") == 0)
- vflag = true;
- else if (strcmp (arg, "--help") == 0)
- helpflag = true;
- break;
- }
- }
- else if ((p = strrchr (arg, '.')) != (char *) 0
- && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
- || strcmp (p, ".so") == 0 || strcmp (p, ".lo") == 0
- || strcmp (p, ".obj") == 0))
- {
- if (first_file)
- {
- first_file = 0;
- if (p[1] == 'o')
- *ld2++ = o_file;
- else
- {
- /* place o_file BEFORE this argument! */
- ld2--;
- *ld2++ = o_file;
- *ld2++ = arg;
- }
- }
- if (p[1] == 'o' || p[1] == 'l')
- *object++ = arg;
-#ifdef COLLECT_EXPORT_LIST
- /* libraries can be specified directly, i.e. without -l flag. */
- else
- {
- /* Saving a full library name. */
- add_to_list (&libs, arg);
- }
-#endif
- }
- }
-
-#ifdef COLLECT_EXPORT_LIST
- /* This is added only for debugging purposes. */
- if (debug)
- {
- fprintf (stderr, "List of libraries:\n");
- dump_list (stderr, "\t", libs.first);
- }
-
- /* The AIX linker will discard static constructors in object files if
- nothing else in the file is referenced, so look at them first. Unless
- we are building a shared object, ignore the eh frame tables, as we
- would otherwise reference them all, hence drag all the corresponding
- objects even if nothing else is referenced. */
- {
- const char **export_object_lst
- = CONST_CAST2 (const char **, char **, object_lst);
-
- struct id *list = libs.first;
-
- /* Compute the filter to use from the current one, do scan, then adjust
- the "current" filter to remove what we just included here. This will
- control whether we need a first pass link later on or not, and what
- will remain to be scanned there. */
-
- scanfilter this_filter = ld1_filter;
-#if HAVE_AS_REF
- if (!shared_obj)
- this_filter &= ~SCAN_DWEH;
-#endif
-
- while (export_object_lst < object)
- scan_prog_file (*export_object_lst++, PASS_OBJ, this_filter);
-
- for (; list; list = list->next)
- scan_prog_file (list->name, PASS_FIRST, this_filter);
-
- ld1_filter = ld1_filter & ~this_filter;
- }
-
- if (exports.first)
- {
- char *buf = concat ("-bE:", export_file, NULL);
-
- *ld1++ = buf;
- *ld2++ = buf;
-
- exportf = fopen (export_file, "w");
- if (exportf == (FILE *) 0)
- fatal_error ("fopen %s: %m", export_file);
- write_aix_file (exportf, exports.first);
- if (fclose (exportf))
- fatal_error ("fclose %s: %m", export_file);
- }
-#endif
-
- *c_ptr++ = c_file;
- *c_ptr = *ld1 = *object = (char *) 0;
-
- if (vflag)
- notice ("collect2 version %s\n", version_string);
-
- if (helpflag)
- {
- printf ("Usage: collect2 [options]\n");
- printf (" Wrap linker and generate constructor code if needed.\n");
- printf (" Options:\n");
- printf (" -debug Enable debug output\n");
- printf (" --help Display this information\n");
- printf (" -v, --version Display this program's version number\n");
- printf ("\n");
- printf ("Overview: http://gcc.gnu.org/onlinedocs/gccint/Collect2.html\n");
- printf ("Report bugs: %s\n", bug_report_url);
- printf ("\n");
- }
-
- if (debug)
- {
- const char *ptr;
- fprintf (stderr, "ld_file_name = %s\n",
- (ld_file_name ? ld_file_name : "not found"));
- fprintf (stderr, "c_file_name = %s\n",
- (c_file_name ? c_file_name : "not found"));
- fprintf (stderr, "nm_file_name = %s\n",
- (nm_file_name ? nm_file_name : "not found"));
-#ifdef LDD_SUFFIX
- fprintf (stderr, "ldd_file_name = %s\n",
- (ldd_file_name ? ldd_file_name : "not found"));
-#endif
- fprintf (stderr, "strip_file_name = %s\n",
- (strip_file_name ? strip_file_name : "not found"));
- fprintf (stderr, "c_file = %s\n",
- (c_file ? c_file : "not found"));
- fprintf (stderr, "o_file = %s\n",
- (o_file ? o_file : "not found"));
-
- ptr = getenv ("COLLECT_GCC_OPTIONS");
- if (ptr)
- fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
-
- ptr = getenv ("COLLECT_GCC");
- if (ptr)
- fprintf (stderr, "COLLECT_GCC = %s\n", ptr);
-
- ptr = getenv ("COMPILER_PATH");
- if (ptr)
- fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
-
- ptr = getenv (LIBRARY_PATH_ENV);
- if (ptr)
- fprintf (stderr, "%-20s= %s\n", LIBRARY_PATH_ENV, ptr);
-
- fprintf (stderr, "\n");
- }
-
- /* Load the program, searching all libraries and attempting to provide
- undefined symbols from repository information.
-
- If -r or they will be run via some other method, do not build the
- constructor or destructor list, just return now. */
- {
- bool early_exit
- = rflag || (! DO_COLLECT_EXPORT_LIST && ! do_collecting);
-
- /* Perform the first pass link now, if we're about to exit or if we need
- to scan for things we haven't collected yet before pursuing further.
-
- On AIX, the latter typically includes nothing for shared objects or
- frame tables for an executable, out of what the required early scan on
- objects and libraries has performed above. In the !shared_obj case, we
- expect the relevant tables to be dragged together with their associated
- functions from precise cross reference insertions by the compiler. */
-
- if (early_exit || ld1_filter != SCAN_NOTHING)
- do_tlink (ld1_argv, object_lst);
-
- if (early_exit)
- {
-#ifdef COLLECT_EXPORT_LIST
- /* Make sure we delete the export file we may have created. */
- if (export_file != 0 && export_file[0])
- maybe_unlink (export_file);
-#endif
- if (lto_mode != LTO_MODE_NONE)
- maybe_run_lto_and_relink (ld1_argv, object_lst, object, false);
- else
- post_ld_pass (false);
-
- maybe_unlink (c_file);
- maybe_unlink (o_file);
- return 0;
- }
- }
-
- /* Unless we have done it all already, examine the namelist and search for
- static constructors and destructors to call. Write the constructor and
- destructor tables to a .s file and reload. */
-
- if (ld1_filter != SCAN_NOTHING)
- scan_prog_file (output_file, PASS_FIRST, ld1_filter);
-
-#ifdef SCAN_LIBRARIES
- scan_libraries (output_file);
-#endif
-
- if (debug)
- {
- notice_translated (ngettext ("%d constructor found\n",
- "%d constructors found\n",
- constructors.number),
- constructors.number);
- notice_translated (ngettext ("%d destructor found\n",
- "%d destructors found\n",
- destructors.number),
- destructors.number);
- notice_translated (ngettext("%d frame table found\n",
- "%d frame tables found\n",
- frame_tables.number),
- frame_tables.number);
- }
-
- /* If the scan exposed nothing of special interest, there's no need to
- generate the glue code and relink so return now. */
-
- if (constructors.number == 0 && destructors.number == 0
- && frame_tables.number == 0
-#if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
- /* If we will be running these functions ourselves, we want to emit
- stubs into the shared library so that we do not have to relink
- dependent programs when we add static objects. */
- && ! shared_obj
-#endif
- )
- {
- /* Do tlink without additional code generation now if we didn't
- do it earlier for scanning purposes. */
- if (ld1_filter == SCAN_NOTHING)
- do_tlink (ld1_argv, object_lst);
-
- if (lto_mode)
- maybe_run_lto_and_relink (ld1_argv, object_lst, object, false);
-
- /* Strip now if it was requested on the command line. */
- if (strip_flag)
- {
- char **real_strip_argv = XCNEWVEC (char *, 3);
- const char ** strip_argv = CONST_CAST2 (const char **, char **,
- real_strip_argv);
-
- strip_argv[0] = strip_file_name;
- strip_argv[1] = output_file;
- strip_argv[2] = (char *) 0;
- fork_execute ("strip", real_strip_argv);
- }
-
-#ifdef COLLECT_EXPORT_LIST
- maybe_unlink (export_file);
-#endif
- post_ld_pass (false);
-
- maybe_unlink (c_file);
- maybe_unlink (o_file);
- return 0;
- }
-
- /* Sort ctor and dtor lists by priority. */
- sort_ids (&constructors);
- sort_ids (&destructors);
-
- maybe_unlink(output_file);
- outf = fopen (c_file, "w");
- if (outf == (FILE *) 0)
- fatal_error ("fopen %s: %m", c_file);
-
- write_c_file (outf, c_file);
-
- if (fclose (outf))
- fatal_error ("fclose %s: %m", c_file);
-
- /* Tell the linker that we have initializer and finalizer functions. */
-#ifdef LD_INIT_SWITCH
-#ifdef COLLECT_EXPORT_LIST
- *ld2++ = concat (LD_INIT_SWITCH, ":", initname, ":", fininame, NULL);
-#else
- *ld2++ = LD_INIT_SWITCH;
- *ld2++ = initname;
- *ld2++ = LD_FINI_SWITCH;
- *ld2++ = fininame;
-#endif
-#endif
-
-#ifdef COLLECT_EXPORT_LIST
- if (shared_obj)
- {
- /* If we did not add export flag to link arguments before, add it to
- second link phase now. No new exports should have been added. */
- if (! exports.first)
- *ld2++ = concat ("-bE:", export_file, NULL);
-
-#ifndef LD_INIT_SWITCH
- add_to_list (&exports, initname);
- add_to_list (&exports, fininame);
- add_to_list (&exports, "_GLOBAL__DI");
- add_to_list (&exports, "_GLOBAL__DD");
-#endif
- exportf = fopen (export_file, "w");
- if (exportf == (FILE *) 0)
- fatal_error ("fopen %s: %m", export_file);
- write_aix_file (exportf, exports.first);
- if (fclose (exportf))
- fatal_error ("fclose %s: %m", export_file);
- }
-#endif
-
- /* End of arguments to second link phase. */
- *ld2 = (char*) 0;
-
- if (debug)
- {
- fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
- output_file, c_file);
- write_c_file (stderr, "stderr");
- fprintf (stderr, "========== end of c_file\n\n");
-#ifdef COLLECT_EXPORT_LIST
- fprintf (stderr, "\n========== export_file = %s\n", export_file);
- write_aix_file (stderr, exports.first);
- fprintf (stderr, "========== end of export_file\n\n");
-#endif
- }
-
- /* Assemble the constructor and destructor tables.
- Link the tables in with the rest of the program. */
-
- fork_execute ("gcc", c_argv);
-#ifdef COLLECT_EXPORT_LIST
- /* On AIX we must call tlink because of possible templates resolution. */
- do_tlink (ld2_argv, object_lst);
-
- if (lto_mode)
- maybe_run_lto_and_relink (ld2_argv, object_lst, object, false);
-#else
- /* Otherwise, simply call ld because tlink is already done. */
- if (lto_mode)
- maybe_run_lto_and_relink (ld2_argv, object_lst, object, true);
- else
- {
- fork_execute ("ld", ld2_argv);
- post_ld_pass (false);
- }
-
- /* Let scan_prog_file do any final mods (OSF/rose needs this for
- constructors/destructors in shared libraries. */
- scan_prog_file (output_file, PASS_SECOND, SCAN_ALL);
-#endif
-
- maybe_unlink (c_file);
- maybe_unlink (o_file);
-
-#ifdef COLLECT_EXPORT_LIST
- maybe_unlink (export_file);
-#endif
-
- return 0;
-}
-
-
-/* Wait for a process to finish, and exit if a nonzero status is found. */
-
-int
-collect_wait (const char *prog, struct pex_obj *pex)
-{
- int status;
-
- if (!pex_get_status (pex, 1, &status))
- fatal_error ("can't get program status: %m");
- pex_free (pex);
-
- if (status)
- {
- if (WIFSIGNALED (status))
- {
- int sig = WTERMSIG (status);
- error ("%s terminated with signal %d [%s]%s",
- prog, sig, strsignal(sig),
- WCOREDUMP(status) ? ", core dumped" : "");
- collect_exit (FATAL_EXIT_CODE);
- }
-
- if (WIFEXITED (status))
- return WEXITSTATUS (status);
- }
- return 0;
-}
-
-static void
-do_wait (const char *prog, struct pex_obj *pex)
-{
- int ret = collect_wait (prog, pex);
- if (ret != 0)
- {
- error ("%s returned %d exit status", prog, ret);
- collect_exit (ret);
- }
-
- if (response_file)
- {
- unlink (response_file);
- response_file = NULL;
- }
-}
-
-
-/* Execute a program, and wait for the reply. */
-
-struct pex_obj *
-collect_execute (const char *prog, char **argv, const char *outname,
- const char *errname, int flags)
-{
- struct pex_obj *pex;
- const char *errmsg;
- int err;
- char *response_arg = NULL;
- char *response_argv[3] ATTRIBUTE_UNUSED;
-
- if (HAVE_GNU_LD && at_file_supplied && argv[0] != NULL)
- {
- /* If using @file arguments, create a temporary file and put the
- contents of argv into it. Then change argv to an array corresponding
- to a single argument @FILE, where FILE is the temporary filename. */
-
- char **current_argv = argv + 1;
- char *argv0 = argv[0];
- int status;
- FILE *f;
-
- /* Note: we assume argv contains at least one element; this is
- checked above. */
-
- response_file = make_temp_file ("");
-
- f = fopen (response_file, "w");
-
- if (f == NULL)
- fatal_error ("could not open response file %s", response_file);
-
- status = writeargv (current_argv, f);
-
- if (status)
- fatal_error ("could not write to response file %s", response_file);
-
- status = fclose (f);
-
- if (EOF == status)
- fatal_error ("could not close response file %s", response_file);
-
- response_arg = concat ("@", response_file, NULL);
- response_argv[0] = argv0;
- response_argv[1] = response_arg;
- response_argv[2] = NULL;
-
- argv = response_argv;
- }
-
- if (vflag || debug)
- {
- char **p_argv;
- const char *str;
-
- if (argv[0])
- fprintf (stderr, "%s", argv[0]);
- else
- notice ("[cannot find %s]", prog);
-
- for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
- fprintf (stderr, " %s", str);
-
- fprintf (stderr, "\n");
- }
-
- fflush (stdout);
- fflush (stderr);
-
- /* If we cannot find a program we need, complain error. Do this here
- since we might not end up needing something that we could not find. */
-
- if (argv[0] == 0)
- fatal_error ("cannot find '%s'", prog);
-
- pex = pex_init (0, "collect2", NULL);
- if (pex == NULL)
- fatal_error ("pex_init failed: %m");
-
- errmsg = pex_run (pex, flags, argv[0], argv, outname,
- errname, &err);
- if (errmsg != NULL)
- {
- if (err != 0)
- {
- errno = err;
- fatal_error ("%s: %m", _(errmsg));
- }
- else
- fatal_error (errmsg);
- }
-
- free (response_arg);
-
- return pex;
-}
-
-static void
-fork_execute (const char *prog, char **argv)
-{
- struct pex_obj *pex;
-
- pex = collect_execute (prog, argv, NULL, NULL, PEX_LAST | PEX_SEARCH);
- do_wait (prog, pex);
-}
-
-/* Unlink FILE unless we are debugging or this is the output_file
- and we may not unlink it. */
-
-static void
-maybe_unlink (const char *file)
-{
- if (debug)
- {
- notice ("[Leaving %s]\n", file);
- return;
- }
-
- if (file == output_file && !may_unlink_output_file)
- return;
-
- unlink_if_ordinary (file);
-}
-
-/* Call maybe_unlink on the NULL-terminated list, FILE_LIST. */
-
-static void
-maybe_unlink_list (char **file_list)
-{
- char **tmp = file_list;
-
- while (*tmp)
- maybe_unlink (*(tmp++));
-}
-
-
-static long sequence_number = 0;
-
-/* Add a name to a linked list. */
-
-static void
-add_to_list (struct head *head_ptr, const char *name)
-{
- struct id *newid
- = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1);
- struct id *p;
- strcpy (newid->name, name);
-
- if (head_ptr->first)
- head_ptr->last->next = newid;
- else
- head_ptr->first = newid;
-
- /* Check for duplicate symbols. */
- for (p = head_ptr->first;
- strcmp (name, p->name) != 0;
- p = p->next)
- ;
- if (p != newid)
- {
- head_ptr->last->next = 0;
- free (newid);
- return;
- }
-
- newid->sequence = ++sequence_number;
- head_ptr->last = newid;
- head_ptr->number++;
-}
-
-/* Grab the init priority number from an init function name that
- looks like "_GLOBAL_.I.12345.foo". */
-
-static int
-extract_init_priority (const char *name)
-{
- int pos = 0, pri;
-
- while (name[pos] == '_')
- ++pos;
- pos += 10; /* strlen ("GLOBAL__X_") */
-
- /* Extract init_p number from ctor/dtor name. */
- pri = atoi (name + pos);
- return pri ? pri : DEFAULT_INIT_PRIORITY;
-}
-
-/* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
- ctors will be run from right to left, dtors from left to right. */
-
-static void
-sort_ids (struct head *head_ptr)
-{
- /* id holds the current element to insert. id_next holds the next
- element to insert. id_ptr iterates through the already sorted elements
- looking for the place to insert id. */
- struct id *id, *id_next, **id_ptr;
-
- id = head_ptr->first;
-
- /* We don't have any sorted elements yet. */
- head_ptr->first = NULL;
-
- for (; id; id = id_next)
- {
- id_next = id->next;
- id->sequence = extract_init_priority (id->name);
-
- for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next))
- if (*id_ptr == NULL
- /* If the sequence numbers are the same, we put the id from the
- file later on the command line later in the list. */
- || id->sequence > (*id_ptr)->sequence
- /* Hack: do lexical compare, too.
- || (id->sequence == (*id_ptr)->sequence
- && strcmp (id->name, (*id_ptr)->name) > 0) */
- )
- {
- id->next = *id_ptr;
- *id_ptr = id;
- break;
- }
- }
-
- /* Now set the sequence numbers properly so write_c_file works. */
- for (id = head_ptr->first; id; id = id->next)
- id->sequence = ++sequence_number;
-}
-
-/* Write: `prefix', the names on list LIST, `suffix'. */
-
-static void
-write_list (FILE *stream, const char *prefix, struct id *list)
-{
- while (list)
- {
- fprintf (stream, "%sx%d,\n", prefix, list->sequence);
- list = list->next;
- }
-}
-
-#ifdef COLLECT_EXPORT_LIST
-/* This function is really used only on AIX, but may be useful. */
-#if 0
-static int
-is_in_list (const char *prefix, struct id *list)
-{
- while (list)
- {
- if (!strcmp (prefix, list->name)) return 1;
- list = list->next;
- }
- return 0;
-}
-#endif
-#endif /* COLLECT_EXPORT_LIST */
-
-/* Added for debugging purpose. */
-#ifdef COLLECT_EXPORT_LIST
-static void
-dump_list (FILE *stream, const char *prefix, struct id *list)
-{
- while (list)
- {
- fprintf (stream, "%s%s,\n", prefix, list->name);
- list = list->next;
- }
-}
-#endif
-
-#if 0
-static void
-dump_prefix_list (FILE *stream, const char *prefix, struct prefix_list *list)
-{
- while (list)
- {
- fprintf (stream, "%s%s,\n", prefix, list->prefix);
- list = list->next;
- }
-}
-#endif
-
-static void
-write_list_with_asm (FILE *stream, const char *prefix, struct id *list)
-{
- while (list)
- {
- fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
- prefix, list->sequence, list->name);
- list = list->next;
- }
-}
-
-/* Write out the constructor and destructor tables statically (for a shared
- object), along with the functions to execute them. */
-
-static void
-write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED)
-{
- const char *p, *q;
- char *prefix, *r;
- int frames = (frame_tables.number > 0);
-
- /* Figure out name of output_file, stripping off .so version. */
- q = p = lbasename (output_file);
-
- while (q)
- {
- q = strchr (q,'.');
- if (q == 0)
- {
- q = p + strlen (p);
- break;
- }
- else
- {
- if (filename_ncmp (q, SHLIB_SUFFIX, strlen (SHLIB_SUFFIX)) == 0)
- {
- q += strlen (SHLIB_SUFFIX);
- break;
- }
- else
- q++;
- }
- }
- /* q points to null at end of the string (or . of the .so version) */
- prefix = XNEWVEC (char, q - p + 1);
- strncpy (prefix, p, q - p);
- prefix[q - p] = 0;
- for (r = prefix; *r; r++)
- if (!ISALNUM ((unsigned char)*r))
- *r = '_';
- if (debug)
- notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
- output_file, prefix);
-
- initname = concat ("_GLOBAL__FI_", prefix, NULL);
- fininame = concat ("_GLOBAL__FD_", prefix, NULL);
-
- free (prefix);
-
- /* Write the tables as C code. */
-
- fprintf (stream, "static int count;\n");
- fprintf (stream, "typedef void entry_pt();\n");
- write_list_with_asm (stream, "extern entry_pt ", constructors.first);
-
- if (frames)
- {
- write_list_with_asm (stream, "extern void *", frame_tables.first);
-
- fprintf (stream, "\tstatic void *frame_table[] = {\n");
- write_list (stream, "\t\t&", frame_tables.first);
- fprintf (stream, "\t0\n};\n");
-
- /* This must match what's in frame.h. */
- fprintf (stream, "struct object {\n");
- fprintf (stream, " void *pc_begin;\n");
- fprintf (stream, " void *pc_end;\n");
- fprintf (stream, " void *fde_begin;\n");
- fprintf (stream, " void *fde_array;\n");
- fprintf (stream, " __SIZE_TYPE__ count;\n");
- fprintf (stream, " struct object *next;\n");
- fprintf (stream, "};\n");
-
- fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
- fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
-
- fprintf (stream, "static void reg_frame () {\n");
- fprintf (stream, "\tstatic struct object ob;\n");
- fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
- fprintf (stream, "\t}\n");
-
- fprintf (stream, "static void dereg_frame () {\n");
- fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
- fprintf (stream, "\t}\n");
- }
-
- fprintf (stream, "void %s() {\n", initname);
- if (constructors.number > 0 || frames)
- {
- fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
- write_list (stream, "\t\t", constructors.first);
- if (frames)
- fprintf (stream, "\treg_frame,\n");
- fprintf (stream, "\t};\n");
- fprintf (stream, "\tentry_pt **p;\n");
- fprintf (stream, "\tif (count++ != 0) return;\n");
- fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames);
- fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
- }
- else
- fprintf (stream, "\t++count;\n");
- fprintf (stream, "}\n");
- write_list_with_asm (stream, "extern entry_pt ", destructors.first);
- fprintf (stream, "void %s() {\n", fininame);
- if (destructors.number > 0 || frames)
- {
- fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
- write_list (stream, "\t\t", destructors.first);
- if (frames)
- fprintf (stream, "\tdereg_frame,\n");
- fprintf (stream, "\t};\n");
- fprintf (stream, "\tentry_pt **p;\n");
- fprintf (stream, "\tif (--count != 0) return;\n");
- fprintf (stream, "\tp = dtors;\n");
- fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
- destructors.number + frames);
- }
- fprintf (stream, "}\n");
-
- if (shared_obj)
- {
- COLLECT_SHARED_INIT_FUNC(stream, initname);
- COLLECT_SHARED_FINI_FUNC(stream, fininame);
- }
-}
-
-/* Write the constructor/destructor tables. */
-
-#ifndef LD_INIT_SWITCH
-static void
-write_c_file_glob (FILE *stream, const char *name ATTRIBUTE_UNUSED)
-{
- /* Write the tables as C code. */
-
- int frames = (frame_tables.number > 0);
-
- fprintf (stream, "typedef void entry_pt();\n\n");
-
- write_list_with_asm (stream, "extern entry_pt ", constructors.first);
-
- if (frames)
- {
- write_list_with_asm (stream, "extern void *", frame_tables.first);
-
- fprintf (stream, "\tstatic void *frame_table[] = {\n");
- write_list (stream, "\t\t&", frame_tables.first);
- fprintf (stream, "\t0\n};\n");
-
- /* This must match what's in frame.h. */
- fprintf (stream, "struct object {\n");
- fprintf (stream, " void *pc_begin;\n");
- fprintf (stream, " void *pc_end;\n");
- fprintf (stream, " void *fde_begin;\n");
- fprintf (stream, " void *fde_array;\n");
- fprintf (stream, " __SIZE_TYPE__ count;\n");
- fprintf (stream, " struct object *next;\n");
- fprintf (stream, "};\n");
-
- fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
- fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
-
- fprintf (stream, "static void reg_frame () {\n");
- fprintf (stream, "\tstatic struct object ob;\n");
- fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
- fprintf (stream, "\t}\n");
-
- fprintf (stream, "static void dereg_frame () {\n");
- fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
- fprintf (stream, "\t}\n");
- }
-
- fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
- fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames);
- write_list (stream, "\t", constructors.first);
- if (frames)
- fprintf (stream, "\treg_frame,\n");
- fprintf (stream, "\t0\n};\n\n");
-
- write_list_with_asm (stream, "extern entry_pt ", destructors.first);
-
- fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
- fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames);
- write_list (stream, "\t", destructors.first);
- if (frames)
- fprintf (stream, "\tdereg_frame,\n");
- fprintf (stream, "\t0\n};\n\n");
-
- fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
- fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
-}
-#endif /* ! LD_INIT_SWITCH */
-
-static void
-write_c_file (FILE *stream, const char *name)
-{
-#ifndef LD_INIT_SWITCH
- if (! shared_obj)
- write_c_file_glob (stream, name);
- else
-#endif
- write_c_file_stat (stream, name);
-}
-
-#ifdef COLLECT_EXPORT_LIST
-static void
-write_aix_file (FILE *stream, struct id *list)
-{
- for (; list; list = list->next)
- {
- fputs (list->name, stream);
- putc ('\n', stream);
- }
-}
-#endif
-
-#ifdef OBJECT_FORMAT_NONE
-
-/* Check to make sure the file is an LTO object file. */
-
-static bool
-maybe_lto_object_file (const char *prog_name)
-{
- FILE *f;
- unsigned char buf[4];
- int i;
-
- static unsigned char elfmagic[4] = { 0x7f, 'E', 'L', 'F' };
- static unsigned char coffmagic[2] = { 0x4c, 0x01 };
- static unsigned char coffmagic_x64[2] = { 0x64, 0x86 };
- static unsigned char machomagic[4][4] = {
- { 0xcf, 0xfa, 0xed, 0xfe },
- { 0xce, 0xfa, 0xed, 0xfe },
- { 0xfe, 0xed, 0xfa, 0xcf },
- { 0xfe, 0xed, 0xfa, 0xce }
- };
-
- f = fopen (prog_name, "rb");
- if (f == NULL)
- return false;
- if (fread (buf, sizeof (buf), 1, f) != 1)
- buf[0] = 0;
- fclose (f);
-
- if (memcmp (buf, elfmagic, sizeof (elfmagic)) == 0
- || memcmp (buf, coffmagic, sizeof (coffmagic)) == 0
- || memcmp (buf, coffmagic_x64, sizeof (coffmagic_x64)) == 0)
- return true;
- for (i = 0; i < 4; i++)
- if (memcmp (buf, machomagic[i], sizeof (machomagic[i])) == 0)
- return true;
-
- return false;
-}
-
-/* Generic version to scan the name list of the loaded program for
- the symbols g++ uses for static constructors and destructors. */
-
-static void
-scan_prog_file (const char *prog_name, scanpass which_pass,
- scanfilter filter)
-{
- void (*int_handler) (int);
-#ifdef SIGQUIT
- void (*quit_handler) (int);
-#endif
- char *real_nm_argv[4];
- const char **nm_argv = CONST_CAST2 (const char **, char**, real_nm_argv);
- int argc = 0;
- struct pex_obj *pex;
- const char *errmsg;
- int err;
- char *p, buf[1024];
- FILE *inf;
- int found_lto = 0;
-
- if (which_pass == PASS_SECOND)
- return;
-
- /* LTO objects must be in a known format. This check prevents
- us from accepting an archive containing LTO objects, which
- gcc cannot currently handle. */
- if (which_pass == PASS_LTOINFO && !maybe_lto_object_file (prog_name))
- return;
-
- /* If we do not have an `nm', complain. */
- if (nm_file_name == 0)
- fatal_error ("cannot find 'nm'");
-
- nm_argv[argc++] = nm_file_name;
- if (NM_FLAGS[0] != '\0')
- nm_argv[argc++] = NM_FLAGS;
-
- nm_argv[argc++] = prog_name;
- nm_argv[argc++] = (char *) 0;
-
- /* Trace if needed. */
- if (vflag)
- {
- const char **p_argv;
- const char *str;
-
- for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
- fprintf (stderr, " %s", str);
-
- fprintf (stderr, "\n");
- }
-
- fflush (stdout);
- fflush (stderr);
-
- pex = pex_init (PEX_USE_PIPES, "collect2", NULL);
- if (pex == NULL)
- fatal_error ("pex_init failed: %m");
-
- errmsg = pex_run (pex, 0, nm_file_name, real_nm_argv, NULL, HOST_BIT_BUCKET,
- &err);
- if (errmsg != NULL)
- {
- if (err != 0)
- {
- errno = err;
- fatal_error ("%s: %m", _(errmsg));
- }
- else
- fatal_error (errmsg);
- }
-
- int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN);
-#ifdef SIGQUIT
- quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
-#endif
-
- inf = pex_read_output (pex, 0);
- if (inf == NULL)
- fatal_error ("can't open nm output: %m");
-
- if (debug)
- {
- if (which_pass == PASS_LTOINFO)
- fprintf (stderr, "\nnm output with LTO info marker symbol.\n");
- else
- fprintf (stderr, "\nnm output with constructors/destructors.\n");
- }
-
- /* Read each line of nm output. */
- while (fgets (buf, sizeof buf, inf) != (char *) 0)
- {
- int ch, ch2;
- char *name, *end;
-
- if (debug)
- fprintf (stderr, "\t%s\n", buf);
-
- if (which_pass == PASS_LTOINFO)
- {
- if (found_lto)
- continue;
-
- /* Look for the LTO info marker symbol, and add filename to
- the LTO objects list if found. */
- for (p = buf; (ch = *p) != '\0' && ch != '\n'; p++)
- if (ch == ' ' && p[1] == '_' && p[2] == '_'
- && (strncmp (p + (p[3] == '_' ? 2 : 1), "__gnu_lto_v1", 12) == 0)
- && ISSPACE (p[p[3] == '_' ? 14 : 13]))
- {
- add_lto_object (&lto_objects, prog_name);
-
- /* We need to read all the input, so we can't just
- return here. But we can avoid useless work. */
- found_lto = 1;
-
- break;
- }
-
- continue;
- }
-
- /* If it contains a constructor or destructor name, add the name
- to the appropriate list unless this is a kind of symbol we're
- not supposed to even consider. */
-
- for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
- if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
- break;
-
- if (ch != '_')
- continue;
-
- name = p;
- /* Find the end of the symbol name.
- Do not include `|', because Encore nm can tack that on the end. */
- for (end = p; (ch2 = *end) != '\0' && !ISSPACE (ch2) && ch2 != '|';
- end++)
- continue;
-
-
- *end = '\0';
- switch (is_ctor_dtor (name))
- {
- case SYM_CTOR:
- if (! (filter & SCAN_CTOR))
- break;
- if (which_pass != PASS_LIB)
- add_to_list (&constructors, name);
- break;
-
- case SYM_DTOR:
- if (! (filter & SCAN_DTOR))
- break;
- if (which_pass != PASS_LIB)
- add_to_list (&destructors, name);
- break;
-
- case SYM_INIT:
- if (! (filter & SCAN_INIT))
- break;
- if (which_pass != PASS_LIB)
- fatal_error ("init function found in object %s", prog_name);
-#ifndef LD_INIT_SWITCH
- add_to_list (&constructors, name);
-#endif
- break;
-
- case SYM_FINI:
- if (! (filter & SCAN_FINI))
- break;
- if (which_pass != PASS_LIB)
- fatal_error ("fini function found in object %s", prog_name);
-#ifndef LD_FINI_SWITCH
- add_to_list (&destructors, name);
-#endif
- break;
-
- case SYM_DWEH:
- if (! (filter & SCAN_DWEH))
- break;
- if (which_pass != PASS_LIB)
- add_to_list (&frame_tables, name);
- break;
-
- default: /* not a constructor or destructor */
- continue;
- }
- }
-
- if (debug)
- fprintf (stderr, "\n");
-
- do_wait (nm_file_name, pex);
-
- signal (SIGINT, int_handler);
-#ifdef SIGQUIT
- signal (SIGQUIT, quit_handler);
-#endif
-}
-
-#ifdef LDD_SUFFIX
-
-/* Use the List Dynamic Dependencies program to find shared libraries that
- the output file depends upon and their initialization/finalization
- routines, if any. */
-
-static void
-scan_libraries (const char *prog_name)
-{
- static struct head libraries; /* list of shared libraries found */
- struct id *list;
- void (*int_handler) (int);
-#ifdef SIGQUIT
- void (*quit_handler) (int);
-#endif
- char *real_ldd_argv[4];
- const char **ldd_argv = CONST_CAST2 (const char **, char **, real_ldd_argv);
- int argc = 0;
- struct pex_obj *pex;
- const char *errmsg;
- int err;
- char buf[1024];
- FILE *inf;
-
- /* If we do not have an `ldd', complain. */
- if (ldd_file_name == 0)
- {
- error ("cannot find 'ldd'");
- return;
- }
-
- ldd_argv[argc++] = ldd_file_name;
- ldd_argv[argc++] = prog_name;
- ldd_argv[argc++] = (char *) 0;
-
- /* Trace if needed. */
- if (vflag)
- {
- const char **p_argv;
- const char *str;
-
- for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
- fprintf (stderr, " %s", str);
-
- fprintf (stderr, "\n");
- }
-
- fflush (stdout);
- fflush (stderr);
-
- pex = pex_init (PEX_USE_PIPES, "collect2", NULL);
- if (pex == NULL)
- fatal_error ("pex_init failed: %m");
-
- errmsg = pex_run (pex, 0, ldd_file_name, real_ldd_argv, NULL, NULL, &err);
- if (errmsg != NULL)
- {
- if (err != 0)
- {
- errno = err;
- fatal_error ("%s: %m", _(errmsg));
- }
- else
- fatal_error (errmsg);
- }
-
- int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN);
-#ifdef SIGQUIT
- quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
-#endif
-
- inf = pex_read_output (pex, 0);
- if (inf == NULL)
- fatal_error ("can't open ldd output: %m");
-
- if (debug)
- notice ("\nldd output with constructors/destructors.\n");
-
- /* Read each line of ldd output. */
- while (fgets (buf, sizeof buf, inf) != (char *) 0)
- {
- int ch2;
- char *name, *end, *p = buf;
-
- /* Extract names of libraries and add to list. */
- PARSE_LDD_OUTPUT (p);
- if (p == 0)
- continue;
-
- name = p;
- if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
- fatal_error ("dynamic dependency %s not found", buf);
-
- /* Find the end of the symbol name. */
- for (end = p;
- (ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|';
- end++)
- continue;
- *end = '\0';
-
- if (access (name, R_OK) == 0)
- add_to_list (&libraries, name);
- else
- fatal_error ("unable to open dynamic dependency '%s'", buf);
-
- if (debug)
- fprintf (stderr, "\t%s\n", buf);
- }
- if (debug)
- fprintf (stderr, "\n");
-
- do_wait (ldd_file_name, pex);
-
- signal (SIGINT, int_handler);
-#ifdef SIGQUIT
- signal (SIGQUIT, quit_handler);
-#endif
-
- /* Now iterate through the library list adding their symbols to
- the list. */
- for (list = libraries.first; list; list = list->next)
- scan_prog_file (list->name, PASS_LIB, SCAN_ALL);
-}
-
-#endif /* LDD_SUFFIX */
-
-#endif /* OBJECT_FORMAT_NONE */
-
-
-/*
- * COFF specific stuff.
- */
-
-#ifdef OBJECT_FORMAT_COFF
-
-#if defined (EXTENDED_COFF)
-
-# define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
-# define GCC_SYMENT SYMR
-# define GCC_OK_SYMBOL(X) ((X).st == stProc || (X).st == stGlobal)
-# define GCC_SYMINC(X) (1)
-# define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
-# define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
-
-#else
-
-# define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
-# define GCC_SYMENT SYMENT
-# if defined (C_WEAKEXT)
-# define GCC_OK_SYMBOL(X) \
- (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
- ((X).n_scnum > N_UNDEF) && \
- (aix64_flag \
- || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
- || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
-# define GCC_UNDEF_SYMBOL(X) \
- (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
- ((X).n_scnum == N_UNDEF))
-# else
-# define GCC_OK_SYMBOL(X) \
- (((X).n_sclass == C_EXT) && \
- ((X).n_scnum > N_UNDEF) && \
- (aix64_flag \
- || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
- || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
-# define GCC_UNDEF_SYMBOL(X) \
- (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
-# endif
-# define GCC_SYMINC(X) ((X).n_numaux+1)
-# define GCC_SYMZERO(X) 0
-
-/* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */
-#if TARGET_AIX_VERSION >= 51
-# define GCC_CHECK_HDR(X) \
- (((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
- || (HEADER (X).f_magic == 0767 && aix64_flag)) \
- && !(HEADER (X).f_flags & F_LOADONLY))
-#else
-# define GCC_CHECK_HDR(X) \
- (((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
- || (HEADER (X).f_magic == 0757 && aix64_flag)) \
- && !(HEADER (X).f_flags & F_LOADONLY))
-#endif
-
-#endif
-
-#ifdef COLLECT_EXPORT_LIST
-/* Array of standard AIX libraries which should not
- be scanned for ctors/dtors. */
-static const char *const aix_std_libs[] = {
- "/unix",
- "/lib/libc.a",
- "/lib/libm.a",
- "/lib/libc_r.a",
- "/lib/libm_r.a",
- "/usr/lib/libc.a",
- "/usr/lib/libm.a",
- "/usr/lib/libc_r.a",
- "/usr/lib/libm_r.a",
- "/usr/lib/threads/libc.a",
- "/usr/ccs/lib/libc.a",
- "/usr/ccs/lib/libm.a",
- "/usr/ccs/lib/libc_r.a",
- "/usr/ccs/lib/libm_r.a",
- NULL
-};
-
-/* This function checks the filename and returns 1
- if this name matches the location of a standard AIX library. */
-static int ignore_library (const char *);
-static int
-ignore_library (const char *name)
-{
- const char *const *p;
- size_t length;
-
- if (target_system_root[0] != '\0')
- {
- length = strlen (target_system_root);
- if (strncmp (name, target_system_root, length) != 0)
- return 0;
- name += length;
- }
- for (p = &aix_std_libs[0]; *p != NULL; ++p)
- if (strcmp (name, *p) == 0)
- return 1;
- return 0;
-}
-#endif /* COLLECT_EXPORT_LIST */
-
-#if defined (HAVE_DECL_LDGETNAME) && !HAVE_DECL_LDGETNAME
-extern char *ldgetname (LDFILE *, GCC_SYMENT *);
-#endif
-
-/* COFF version to scan the name list of the loaded program for
- the symbols g++ uses for static constructors and destructors. */
-
-static void
-scan_prog_file (const char *prog_name, scanpass which_pass,
- scanfilter filter)
-{
- LDFILE *ldptr = NULL;
- int sym_index, sym_count;
- int is_shared = 0;
-
- if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
- return;
-
-#ifdef COLLECT_EXPORT_LIST
- /* We do not need scanning for some standard C libraries. */
- if (which_pass == PASS_FIRST && ignore_library (prog_name))
- return;
-
- /* On AIX we have a loop, because there is not much difference
- between an object and an archive. This trick allows us to
- eliminate scan_libraries() function. */
- do
- {
-#endif
- /* Some platforms (e.g. OSF4) declare ldopen as taking a
- non-const char * filename parameter, even though it will not
- modify that string. So we must cast away const-ness here,
- using CONST_CAST to prevent complaints from -Wcast-qual. */
- if ((ldptr = ldopen (CONST_CAST (char *, prog_name), ldptr)) != NULL)
- {
- if (! MY_ISCOFF (HEADER (ldptr).f_magic))
- fatal_error ("%s: not a COFF file", prog_name);
-
- if (GCC_CHECK_HDR (ldptr))
- {
- sym_count = GCC_SYMBOLS (ldptr);
- sym_index = GCC_SYMZERO (ldptr);
-
-#ifdef COLLECT_EXPORT_LIST
- /* Is current archive member a shared object? */
- is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
-#endif
-
- while (sym_index < sym_count)
- {
- GCC_SYMENT symbol;
-
- if (ldtbread (ldptr, sym_index, &symbol) <= 0)
- break;
- sym_index += GCC_SYMINC (symbol);
-
- if (GCC_OK_SYMBOL (symbol))
- {
- char *name;
-
- if ((name = ldgetname (ldptr, &symbol)) == NULL)
- continue; /* Should never happen. */
-
-#ifdef XCOFF_DEBUGGING_INFO
- /* All AIX function names have a duplicate entry
- beginning with a dot. */
- if (*name == '.')
- ++name;
-#endif
-
- switch (is_ctor_dtor (name))
- {
- case SYM_CTOR:
- if (! (filter & SCAN_CTOR))
- break;
- if (! is_shared)
- add_to_list (&constructors, name);
-#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
- if (which_pass == PASS_OBJ)
- add_to_list (&exports, name);
-#endif
- break;
-
- case SYM_DTOR:
- if (! (filter & SCAN_DTOR))
- break;
- if (! is_shared)
- add_to_list (&destructors, name);
-#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
- if (which_pass == PASS_OBJ)
- add_to_list (&exports, name);
-#endif
- break;
-
-#ifdef COLLECT_EXPORT_LIST
- case SYM_INIT:
- if (! (filter & SCAN_INIT))
- break;
-#ifndef LD_INIT_SWITCH
- if (is_shared)
- add_to_list (&constructors, name);
-#endif
- break;
-
- case SYM_FINI:
- if (! (filter & SCAN_FINI))
- break;
-#ifndef LD_INIT_SWITCH
- if (is_shared)
- add_to_list (&destructors, name);
-#endif
- break;
-#endif
-
- case SYM_DWEH:
- if (! (filter & SCAN_DWEH))
- break;
- if (! is_shared)
- add_to_list (&frame_tables, name);
-#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
- if (which_pass == PASS_OBJ)
- add_to_list (&exports, name);
-#endif
- break;
-
- default: /* not a constructor or destructor */
-#ifdef COLLECT_EXPORT_LIST
- /* Explicitly export all global symbols when
- building a shared object on AIX, but do not
- re-export symbols from another shared object
- and do not export symbols if the user
- provides an explicit export list. */
- if (shared_obj && !is_shared
- && which_pass == PASS_OBJ && !export_flag)
- add_to_list (&exports, name);
-#endif
- continue;
- }
-
- if (debug)
-#if !defined(EXTENDED_COFF)
- fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
- symbol.n_scnum, symbol.n_sclass,
- (symbol.n_type ? "0" : ""), symbol.n_type,
- name);
-#else
- fprintf (stderr,
- "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
- symbol.iss, (long) symbol.value, symbol.index, name);
-#endif
- }
- }
- }
-#ifdef COLLECT_EXPORT_LIST
- else
- {
- /* If archive contains both 32-bit and 64-bit objects,
- we want to skip objects in other mode so mismatch normal. */
- if (debug)
- fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n",
- prog_name, HEADER (ldptr).f_magic, aix64_flag);
- }
-#endif
- }
- else
- {
- fatal_error ("%s: cannot open as COFF file", prog_name);
- }
-#ifdef COLLECT_EXPORT_LIST
- /* On AIX loop continues while there are more members in archive. */
- }
- while (ldclose (ldptr) == FAILURE);
-#else
- /* Otherwise we simply close ldptr. */
- (void) ldclose(ldptr);
-#endif
-}
-#endif /* OBJECT_FORMAT_COFF */
-
-#ifdef COLLECT_EXPORT_LIST
-/* Given a library name without "lib" prefix, this function
- returns a full library name including a path. */
-static char *
-resolve_lib_name (const char *name)
-{
- char *lib_buf;
- int i, j, l = 0;
- /* Library extensions for AIX dynamic linking. */
- const char * const libexts[2] = {"a", "so"};
-
- for (i = 0; libpaths[i]; i++)
- if (libpaths[i]->max_len > l)
- l = libpaths[i]->max_len;
-
- lib_buf = XNEWVEC (char, l + strlen(name) + 10);
-
- for (i = 0; libpaths[i]; i++)
- {
- struct prefix_list *list = libpaths[i]->plist;
- for (; list; list = list->next)
- {
- /* The following lines are needed because path_prefix list
- may contain directories both with trailing DIR_SEPARATOR and
- without it. */
- const char *p = "";
- if (!IS_DIR_SEPARATOR (list->prefix[strlen(list->prefix)-1]))
- p = "/";
- for (j = 0; j < 2; j++)
- {
- sprintf (lib_buf, "%s%slib%s.%s",
- list->prefix, p, name,
- libexts[(j + aixrtl_flag) % 2]);
- if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
- if (file_exists (lib_buf))
- {
- if (debug) fprintf (stderr, "found: %s\n", lib_buf);
- return (lib_buf);
- }
- }
- }
- }
- if (debug)
- fprintf (stderr, "not found\n");
- else
- fatal_error ("library lib%s not found", name);
- return (NULL);
-}
-#endif /* COLLECT_EXPORT_LIST */
-
-#ifdef COLLECT_RUN_DSYMUTIL
-static int flag_dsym = false;
-static int flag_idsym = false;
-
-static void
-process_args (int *argcp, char **argv) {
- int i, j;
- int argc = *argcp;
- for (i=0; i<argc; ++i)
- {
- if (strcmp (argv[i], "-dsym") == 0)
- {
- flag_dsym = true;
- /* Remove the flag, as we handle all processing for it. */
- j = i;
- do
- argv[j] = argv[j+1];
- while (++j < argc);
- --i;
- argc = --(*argcp);
- }
- else if (strcmp (argv[i], "-idsym") == 0)
- {
- flag_idsym = true;
- /* Remove the flag, as we handle all processing for it. */
- j = i;
- do
- argv[j] = argv[j+1];
- while (++j < argc);
- --i;
- argc = --(*argcp);
- }
- }
-}
-
-static void
-do_dsymutil (const char *output_file) {
- const char *dsymutil = DSYMUTIL + 1;
- struct pex_obj *pex;
- char **real_argv = XCNEWVEC (char *, 3);
- const char ** argv = CONST_CAST2 (const char **, char **,
- real_argv);
-
- argv[0] = dsymutil;
- argv[1] = output_file;
- argv[2] = (char *) 0;
-
- pex = collect_execute (dsymutil, real_argv, NULL, NULL, PEX_LAST | PEX_SEARCH);
- do_wait (dsymutil, pex);
-}
-
-static void
-post_ld_pass (bool temp_file) {
- if (!(temp_file && flag_idsym) && !flag_dsym)
- return;
-
- do_dsymutil (output_file);
-}
-#else
-static void
-process_args (int *argcp ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) { }
-static void post_ld_pass (bool temp_file ATTRIBUTE_UNUSED) { }
-#endif
diff --git a/gcc-4.8/gcc/config.gcc.orig b/gcc-4.8/gcc/config.gcc.orig
deleted file mode 100644
index 0164a2922..000000000
--- a/gcc-4.8/gcc/config.gcc.orig
+++ /dev/null
@@ -1,3843 +0,0 @@
-# GCC target-specific configuration file.
-# Copyright (C) 1997-2013 Free Software Foundation, Inc.
-
-#This file is part of GCC.
-
-#GCC is free software; you can redistribute it and/or modify it under
-#the terms of the GNU General Public License as published by the Free
-#Software Foundation; either version 3, or (at your option) any later
-#version.
-
-#GCC is distributed in the hope that it will be useful, but WITHOUT
-#ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-#FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-#for more details.
-
-#You should have received a copy of the GNU General Public License
-#along with GCC; see the file COPYING3. If not see
-#<http://www.gnu.org/licenses/>.
-
-# This is the GCC target-specific configuration file
-# where a configuration type is mapped to different system-specific
-# definitions and files. This is invoked by the autoconf-generated
-# configure script. Putting it in a separate shell file lets us skip
-# running autoconf when modifying target-specific information.
-
-# When you change the cases in the OS or target switches, consider
-# updating ../libgcc/config.host also.
-
-# This file switches on the shell variable ${target}, and also uses the
-# following shell variables:
-#
-# with_* Various variables as set by configure.
-#
-# enable_threads Either the name, yes or no depending on whether
-# threads support was requested.
-#
-# default_use_cxa_atexit
-# The default value for the $enable___cxa_atexit
-# variable. enable___cxa_atexit needs to be set to
-# "yes" for the correct operation of C++ destructors
-# but it relies upon the presence of a non-standard C
-# library function called __cxa_atexit.
-# Since not all C libraries provide __cxa_atexit the
-# default value of $default_use_cxa_atexit is set to
-# "no" except for targets which are known to be OK.
-#
-# default_gnu_indirect_function
-# The default value for the $enable_gnu_indirect_function
-# variable. enable_gnu_indirect_function relies
-# upon the presence of a non-standard gnu ifunc support
-# in the assembler, linker and dynamic linker.
-# Since not all libraries provide the dynamic linking
-# support, the default value of
-# $default_gnu_indirect_function is set to
-# "no" except for targets which are known to be OK.
-#
-# gas_flag Either yes or no depending on whether GNU as was
-# requested.
-#
-# gnu_ld_flag Either yes or no depending on whether GNU ld was
-# requested.
-
-# This file sets the following shell variables for use by the
-# autoconf-generated configure script:
-#
-# cpu_type The name of the cpu, if different from the first
-# chunk of the canonical target name.
-#
-# tm_defines List of target macros to define for all compilations.
-#
-# tm_file A list of target macro files, if different from
-# "$cpu_type/$cpu_type.h". Usually it's constructed
-# per target in a way like this:
-# tm_file="${tm_file} dbxelf.h elfos.h ${cpu_type.h}/elf.h"
-# Note that the preferred order is:
-# - specific target header "${cpu_type}/${cpu_type.h}"
-# - generic headers like dbxelf.h elfos.h, etc.
-# - specializing target headers like ${cpu_type.h}/elf.h
-# 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.
-#
-# out_file The name of the machine description C support
-# file, if different from "$cpu_type/$cpu_type.c".
-#
-# common_out_file The name of the source file for code shared between
-# the compiler proper and the driver.
-#
-# md_file The name of the machine-description file, if
-# different from "$cpu_type/$cpu_type.md".
-#
-# tmake_file A list of machine-description-specific
-# makefile-fragments, if different from
-# "$cpu_type/t-$cpu_type".
-#
-# extra_modes The name of the file containing a list of extra
-# machine modes, if necessary and different from
-# "$cpu_type/$cpu_type-modes.def".
-#
-# extra_objs List of extra objects that should be linked into
-# the compiler proper (cc1, cc1obj, cc1plus)
-# depending on target.
-#
-# extra_gcc_objs List of extra objects that should be linked into
-# the compiler driver (gcc) depending on target.
-#
-# extra_headers List of used header files from the directory
-# config/${cpu_type}.
-#
-# user_headers_inc_next_pre
-# List of header file names of internal gcc header
-# files, which should be prefixed by an include_next.
-# user_headers_inc_next_post
-# List of header file names of internal gcc header
-# files, which should be postfixed by an include_next.
-# use_gcc_tgmath If set, add tgmath.h to the list of used header
-# files.
-#
-# use_gcc_stdint If "wrap", install a version of stdint.h that
-# wraps the system's copy for hosted compilations;
-# if "provide", provide a version of systems without
-# such a system header; otherwise "none", do not
-# provide such a header at all.
-#
-# extra_programs List of extra executables compiled for this target
-# machine, used when linking.
-#
-# extra_options List of target-dependent .opt files.
-#
-# c_target_objs List of extra target-dependent objects that be
-# linked into the C compiler only.
-#
-# cxx_target_objs List of extra target-dependent objects that be
-# linked into the C++ compiler only.
-#
-# fortran_target_objs List of extra target-dependent objects that be
-# linked into the fortran compiler only.
-#
-# target_gtfiles List of extra source files with type information.
-#
-# xm_defines List of macros to define when compiling for the
-# target machine.
-#
-# xm_file List of files to include when compiling for the
-# target machine.
-#
-# use_collect2 Set to yes or no, depending on whether collect2
-# will be used.
-#
-# target_cpu_default Set to override the default target model.
-#
-# gdb_needs_out_file_path
-# Set to yes if gdb needs a dir command with
-# `dirname $out_file`.
-#
-# thread_file Set to control which thread package to use.
-#
-# gas Set to yes or no depending on whether the target
-# system normally uses GNU as.
-#
-# need_64bit_hwint Set to yes if HOST_WIDE_INT must be 64 bits wide
-# for this target. This is true if this target
-# supports "long" or "wchar_t" wider than 32 bits,
-# or BITS_PER_WORD is wider than 32 bits.
-# The setting made here must match the one made in
-# other locations such as libcpp/configure.ac
-#
-# configure_default_options
-# Set to an initializer for configure_default_options
-# in configargs.h, based on --with-cpu et cetera.
-#
-# native_system_header_dir
-# Where system header files are found for this
-# target. This defaults to /usr/include. If
-# the --with-sysroot configure option or the
-# --sysroot command line option is used this
-# will be relative to the sysroot.
-# target_type_format_char
-# The default character to be used for formatting
-# the attribute in a
-# .type symbol_name, ${t_t_f_c}<property>
-# directive.
-
-# The following variables are used in each case-construct to build up the
-# outgoing variables:
-#
-# gnu_ld Set to yes or no depending on whether the target
-# system normally uses GNU ld.
-#
-# target_has_targetcm Set to yes or no depending on whether the target
-# has its own definition of targetcm.
-#
-# target_has_targetm_common Set to yes or no depending on whether the
-# target has its own definition of targetm_common.
-
-out_file=
-common_out_file=
-tmake_file=
-extra_headers=
-user_headers_inc_next_pre=
-user_headers_inc_next_post=
-use_gcc_tgmath=yes
-use_gcc_stdint=none
-extra_programs=
-extra_objs=
-extra_gcc_objs=
-extra_options=
-c_target_objs=
-cxx_target_objs=
-fortran_target_objs=
-target_has_targetcm=no
-target_has_targetm_common=yes
-tm_defines=
-xm_defines=
-# Set this to force installation and use of collect2.
-use_collect2=
-# Set this to override the default target model.
-target_cpu_default=
-# Set this if gdb needs a dir command with `dirname $out_file`
-gdb_needs_out_file_path=
-# Set this to control which thread package will be used.
-thread_file=
-# Reinitialize these from the flag values every loop pass, since some
-# configure entries modify them.
-gas="$gas_flag"
-gnu_ld="$gnu_ld_flag"
-default_use_cxa_atexit=no
-default_gnu_indirect_function=no
-target_gtfiles=
-need_64bit_hwint=
-need_64bit_isa=
-native_system_header_dir=/usr/include
-target_type_format_char='@'
-
-# Don't carry these over build->host->target. Please.
-xm_file=
-md_file=
-
-# Obsolete configurations.
-case ${target} in
- picochip-* \
- | score-* \
- )
- if test "x$enable_obsolete" != xyes; then
- echo "*** Configuration ${target} is obsolete." >&2
- echo "*** Specify --enable-obsolete to build it anyway." >&2
- echo "*** Support will be REMOVED in the next major release of GCC," >&2
- echo "*** unless a maintainer comes forward." >&2
- exit 1
- fi;;
-esac
-
-# Unsupported targets list. Do not put an entry in this list unless
-# it would otherwise be caught by a more permissive pattern. The list
-# should be in alphabetical order.
-case ${target} in
- # Avoid special cases that are not obsolete
- arm*-*-*eabi* \
- )
- ;;
- arm*-wince-pe* \
- | arm*-*-ecos-elf \
- | arm*-*-elf \
- | arm*-*-freebsd* \
- | arm*-*-linux* \
- | arm*-*-uclinux* \
- | i[34567]86-go32-* \
- | i[34567]86-*-go32* \
- | m68k-*-uclinuxoldabi* \
- | mips64orion*-*-rtems* \
- | pdp11-*-bsd \
- | sparc-hal-solaris2* \
- | thumb-*-* \
- | *-*-freebsd[12] | *-*-freebsd[12].* \
- | *-*-freebsd*aout* \
- | *-*-linux*aout* \
- | *-*-linux*coff* \
- | *-*-linux*libc1* \
- | *-*-linux*oldld* \
- | *-*-rtemsaout* \
- | *-*-rtemscoff* \
- | *-*-solaris2 \
- | *-*-solaris2.[0-8] \
- | *-*-solaris2.[0-8].* \
- | *-*-sysv* \
- | vax-*-vms* \
- )
- echo "*** Configuration ${target} not supported" 1>&2
- exit 1
- ;;
-esac
-
-# Set default cpu_type, tm_file, tm_p_file and xm_file so it can be
-# updated in each machine entry. Also set default extra_headers for some
-# machines.
-tm_p_file=
-cpu_type=`echo ${target} | sed 's/-.*$//'`
-cpu_is_64bit=
-case ${target} in
-m32c*-*-*)
- cpu_type=m32c
- tmake_file=m32c/t-m32c
- target_has_targetm_common=no
- ;;
-aarch64*-*-*)
- cpu_type=aarch64
- need_64bit_hwint=yes
- extra_headers="arm_neon.h"
- extra_objs="aarch64-builtins.o"
- target_has_targetm_common=yes
- ;;
-alpha*-*-*)
- cpu_type=alpha
- need_64bit_hwint=yes
- extra_options="${extra_options} g.opt"
- ;;
-am33_2.0-*-linux*)
- cpu_type=mn10300
- ;;
-arm*-*-*)
- cpu_type=arm
- extra_headers="mmintrin.h arm_neon.h"
- target_type_format_char='%'
- c_target_objs="arm-c.o"
- cxx_target_objs="arm-c.o"
- extra_options="${extra_options} arm/arm-tables.opt"
- ;;
-avr-*-*)
- cpu_type=avr
- c_target_objs="avr-c.o"
- cxx_target_objs="avr-c.o"
- extra_options="${extra_options} avr/avr-tables.opt"
- ;;
-bfin*-*)
- cpu_type=bfin
- ;;
-crisv32-*)
- cpu_type=cris
- ;;
-frv*) cpu_type=frv
- extra_options="${extra_options} g.opt"
- ;;
-moxie*) cpu_type=moxie
- target_has_targetm_common=no
- ;;
-fido-*-*)
- cpu_type=m68k
- extra_headers=math-68881.h
- extra_options="${extra_options} m68k/m68k-tables.opt"
- ;;
-i[34567]86-*-*)
- cpu_type=i386
- c_target_objs="i386-c.o"
- cxx_target_objs="i386-c.o"
- need_64bit_hwint=yes
- extra_options="${extra_options} fused-madd.opt"
- extra_headers="cpuid.h mmintrin.h mm3dnow.h xmmintrin.h emmintrin.h
- pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h
- nmmintrin.h bmmintrin.h fma4intrin.h wmmintrin.h
- immintrin.h x86intrin.h avxintrin.h xopintrin.h
- ia32intrin.h cross-stdarg.h lwpintrin.h popcntintrin.h
- lzcntintrin.h bmiintrin.h bmi2intrin.h tbmintrin.h
- avx2intrin.h fmaintrin.h f16cintrin.h rtmintrin.h
- xtestintrin.h rdseedintrin.h prfchwintrin.h adxintrin.h
- fxsrintrin.h xsaveintrin.h xsaveoptintrin.h"
- ;;
-x86_64-*-*)
- cpu_type=i386
- c_target_objs="i386-c.o"
- cxx_target_objs="i386-c.o"
- extra_options="${extra_options} fused-madd.opt"
- extra_headers="cpuid.h mmintrin.h mm3dnow.h xmmintrin.h emmintrin.h
- pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h
- nmmintrin.h bmmintrin.h fma4intrin.h wmmintrin.h
- immintrin.h x86intrin.h avxintrin.h xopintrin.h
- ia32intrin.h cross-stdarg.h lwpintrin.h popcntintrin.h
- lzcntintrin.h bmiintrin.h tbmintrin.h bmi2intrin.h
- avx2intrin.h fmaintrin.h f16cintrin.h rtmintrin.h
- xtestintrin.h rdseedintrin.h prfchwintrin.h adxintrin.h
- fxsrintrin.h xsaveintrin.h xsaveoptintrin.h"
- need_64bit_hwint=yes
- ;;
-ia64-*-*)
- extra_headers=ia64intrin.h
- need_64bit_hwint=yes
- extra_options="${extra_options} g.opt fused-madd.opt"
- ;;
-hppa*-*-*)
- cpu_type=pa
- ;;
-lm32*)
- extra_options="${extra_options} g.opt"
- ;;
-m32r*-*-*)
- cpu_type=m32r
- extra_options="${extra_options} g.opt"
- ;;
-m68k-*-*)
- extra_headers=math-68881.h
- extra_options="${extra_options} m68k/m68k-tables.opt"
- ;;
-microblaze*-*-*)
- cpu_type=microblaze
- extra_options="${extra_options} g.opt"
- ;;
-mips*-*-*)
- cpu_type=mips
- need_64bit_hwint=yes
- extra_headers="loongson.h"
- extra_options="${extra_options} g.opt mips/mips-tables.opt"
- ;;
-picochip-*-*)
- cpu_type=picochip
- ;;
-powerpc*-*-*)
- cpu_type=rs6000
- extra_headers="ppc-asm.h altivec.h spe.h ppu_intrinsics.h paired.h spu2vmx.h vec_types.h si2vmx.h"
- need_64bit_hwint=yes
- case x$with_cpu in
- xpowerpc64|xdefault64|x6[23]0|x970|xG5|xpower[345678]|xpower6x|xrs64a|xcell|xa2|xe500mc64|xe5500|Xe6500)
- cpu_is_64bit=yes
- ;;
- esac
- extra_options="${extra_options} g.opt fused-madd.opt rs6000/rs6000-tables.opt"
- ;;
-rs6000*-*-*)
- need_64bit_hwint=yes
- extra_options="${extra_options} g.opt fused-madd.opt rs6000/rs6000-tables.opt"
- ;;
-score*-*-*)
- cpu_type=score
- extra_options="${extra_options} g.opt"
- ;;
-sparc*-*-*)
- cpu_type=sparc
- c_target_objs="sparc-c.o"
- cxx_target_objs="sparc-c.o"
- extra_headers="visintrin.h"
- need_64bit_hwint=yes
- ;;
-spu*-*-*)
- cpu_type=spu
- need_64bit_hwint=yes
- ;;
-s390*-*-*)
- cpu_type=s390
- need_64bit_hwint=yes
- extra_options="${extra_options} fused-madd.opt"
- ;;
-# Note the 'l'; we need to be able to match e.g. "shle" or "shl".
-sh[123456789lbe]*-*-* | sh-*-*)
- cpu_type=sh
- need_64bit_hwint=yes
- extra_options="${extra_options} fused-madd.opt"
- ;;
-v850*-*-*)
- cpu_type=v850
- ;;
-tic6x-*-*)
- cpu_type=c6x
- extra_headers="c6x_intrinsics.h"
- extra_options="${extra_options} c6x/c6x-tables.opt"
- ;;
-xtensa*-*-*)
- extra_options="${extra_options} fused-madd.opt"
- ;;
-tilegx*-*-*)
- cpu_type=tilegx
- need_64bit_hwint=yes
- ;;
-tilepro-*-*)
- cpu_type=tilepro
- need_64bit_hwint=yes
- ;;
-esac
-
-tm_file=${cpu_type}/${cpu_type}.h
-if test -f ${srcdir}/config/${cpu_type}/${cpu_type}-protos.h
-then
- tm_p_file=${cpu_type}/${cpu_type}-protos.h
-fi
-extra_modes=
-if test -f ${srcdir}/config/${cpu_type}/${cpu_type}-modes.def
-then
- extra_modes=${cpu_type}/${cpu_type}-modes.def
-fi
-if test -f ${srcdir}/config/${cpu_type}/${cpu_type}.opt
-then
- extra_options="${extra_options} ${cpu_type}/${cpu_type}.opt"
-fi
-
-case ${target} in
-i[34567]86-*-*)
- if test "x$with_abi" != x; then
- echo "This target does not support --with-abi."
- exit 1
- fi
- if test "x$enable_cld" = xyes; then
- tm_defines="${tm_defines} USE_IX86_CLD=1"
- fi
- if test "x$enable_frame_pointer" = xyes; then
- tm_defines="${tm_defines} USE_IX86_FRAME_POINTER=1"
- fi
- tm_file="vxworks-dummy.h ${tm_file}"
- ;;
-x86_64-*-*)
- case ${with_abi} in
- "")
- if test "x$with_multilib_list" = xmx32; then
- tm_file="i386/biarchx32.h ${tm_file}"
- else
- tm_file="i386/biarch64.h ${tm_file}"
- fi
- ;;
- 64 | m64)
- tm_file="i386/biarch64.h ${tm_file}"
- ;;
- x32 | mx32)
- tm_file="i386/biarchx32.h ${tm_file}"
- ;;
- *)
- echo "Unknown ABI used in --with-abi=$with_abi"
- exit 1
- esac
- if test "x$enable_cld" = xyes; then
- tm_defines="${tm_defines} USE_IX86_CLD=1"
- fi
- if test "x$enable_frame_pointer" = xyes; then
- tm_defines="${tm_defines} USE_IX86_FRAME_POINTER=1"
- fi
- tm_file="vxworks-dummy.h ${tm_file}"
- ;;
-arm*-*-* | mips*-*-* | sh*-*-* | sparc*-*-*)
- tm_file="vxworks-dummy.h ${tm_file}"
- ;;
-esac
-
-# On a.out targets, we need to use collect2.
-case ${target} in
-*-*-*aout*)
- use_collect2=yes
- ;;
-esac
-
-# Common C libraries.
-tm_defines="$tm_defines LIBC_GLIBC=1 LIBC_UCLIBC=2 LIBC_BIONIC=3"
-
-# Common parts for widely ported systems.
-case ${target} in
-*-*-darwin*)
- tmake_file="t-darwin ${cpu_type}/t-darwin"
- tm_file="${tm_file} darwin.h"
- case ${target} in
- *-*-darwin9*)
- tm_file="${tm_file} darwin9.h"
- ;;
- *-*-darwin[12][0-9]*)
- tm_file="${tm_file} darwin9.h darwin10.h"
- ;;
- esac
- tm_file="${tm_file} ${cpu_type}/darwin.h"
- tm_p_file="${tm_p_file} darwin-protos.h"
- target_gtfiles="\$(srcdir)/config/darwin.c"
- extra_options="${extra_options} darwin.opt"
- c_target_objs="${c_target_objs} darwin-c.o"
- cxx_target_objs="${cxx_target_objs} darwin-c.o"
- fortran_target_objs="darwin-f.o"
- target_has_targetcm=yes
- extra_objs="darwin.o"
- extra_gcc_objs="darwin-driver.o"
- default_use_cxa_atexit=yes
- use_gcc_stdint=wrap
- case ${enable_threads} in
- "" | yes | posix) thread_file='posix' ;;
- esac
- ;;
-*-*-freebsd*)
- # This is the generic ELF configuration of FreeBSD. Later
- # machine-specific sections may refine and add to this
- # configuration.
- #
- # Due to tm_file entry ordering issues that vary between cpu
- # architectures, we only define fbsd_tm_file to allow the
- # machine-specific section to dictate the final order of all
- # entries of tm_file with the minor exception that components
- # of the tm_file set here will always be of the form:
- #
- # freebsd<version_number>.h [freebsd-<conf_option>.h ...] freebsd-spec.h freebsd.h
- #
- # The machine-specific section should not tamper with this
- # ordering but may order all other entries of tm_file as it
- # pleases around the provided core setting.
- gas=yes
- gnu_ld=yes
- fbsd_major=`echo ${target} | sed -e 's/.*freebsd//g' | sed -e 's/\..*//g'`
- tm_defines="${tm_defines} FBSD_MAJOR=${fbsd_major}"
- tmake_file="t-slibgcc"
- case ${enable_threads} in
- no)
- fbsd_tm_file="${fbsd_tm_file} freebsd-nthr.h"
- ;;
- "" | yes | posix)
- thread_file='posix'
- ;;
- *)
- echo 'Unknown thread configuration for FreeBSD'
- exit 1
- ;;
- esac
- fbsd_tm_file="${fbsd_tm_file} freebsd-spec.h freebsd.h freebsd-stdint.h"
- extra_options="$extra_options rpath.opt freebsd.opt"
- case ${target} in
- *-*-freebsd[345].*)
- :;;
- *)
- default_use_cxa_atexit=yes;;
- esac
- # need_64bit_hwint=yes # system compiler has this for all arch!
- use_gcc_stdint=wrap
- ;;
-*-*-linux* | frv-*-*linux* | *-*-kfreebsd*-gnu | *-*-knetbsd*-gnu | *-*-gnu* | *-*-kopensolaris*-gnu)
- extra_options="$extra_options gnu-user.opt"
- gas=yes
- gnu_ld=yes
- case ${enable_threads} in
- "" | yes | posix) thread_file='posix' ;;
- esac
- tmake_file="t-slibgcc"
- case $target in
- *-*-linux* | frv-*-*linux* | *-*-kfreebsd*-gnu | *-*-knetbsd*-gnu | *-*-kopensolaris*-gnu)
- :;;
- *-*-gnu*)
- native_system_header_dir=/include
- ;;
- esac
- # glibc / uclibc / bionic switch.
- # uclibc and bionic aren't usable for GNU/Hurd and neither for GNU/k*BSD.
- case $target in
- *linux*)
- extra_options="$extra_options linux.opt";;
- esac
- case $target in
- *-*-*android*)
- tm_defines="$tm_defines DEFAULT_LIBC=LIBC_BIONIC"
- ;;
- *-*-*uclibc*)
- tm_defines="$tm_defines DEFAULT_LIBC=LIBC_UCLIBC"
- ;;
- *)
- tm_defines="$tm_defines DEFAULT_LIBC=LIBC_GLIBC"
- ;;
- esac
- # Assume that glibc or uClibc or Bionic are being used and so __cxa_atexit
- # is provided.
- default_use_cxa_atexit=yes
- use_gcc_tgmath=no
- use_gcc_stdint=wrap
- # Add Android userspace support to Linux targets.
- case $target in
- *linux*)
- tm_file="$tm_file linux-android.h"
- extra_options="$extra_options linux-android.opt"
- ;;
- esac
- # Enable compilation for Android by default for *android* targets.
- case $target in
- *-*-*android*)
- tm_defines="$tm_defines ANDROID_DEFAULT=1"
- ;;
- *)
- tm_defines="$tm_defines ANDROID_DEFAULT=0"
- ;;
- esac
- c_target_objs="${c_target_objs} glibc-c.o"
- cxx_target_objs="${cxx_target_objs} glibc-c.o"
- tmake_file="${tmake_file} t-glibc"
- target_has_targetcm=yes
- ;;
-*-*-netbsd*)
- tmake_file="t-slibgcc"
- gas=yes
- gnu_ld=yes
-
- # NetBSD 2.0 and later get POSIX threads enabled by default.
- # Allow them to be explicitly enabled on any other version.
- case ${enable_threads} in
- "")
- case ${target} in
- *-*-netbsd[2-9]* | *-*-netbsdelf[2-9]*)
- thread_file='posix'
- tm_defines="${tm_defines} NETBSD_ENABLE_PTHREADS"
- ;;
- esac
- ;;
- yes | posix)
- thread_file='posix'
- tm_defines="${tm_defines} NETBSD_ENABLE_PTHREADS"
- ;;
- esac
-
- # NetBSD 2.0 and later provide __cxa_atexit(), which we use by
- # default (unless overridden by --disable-__cxa_atexit).
- case ${target} in
- *-*-netbsd[2-9]* | *-*-netbsdelf[2-9]*)
- default_use_cxa_atexit=yes
- ;;
- esac
- ;;
-*-*-openbsd*)
- tmake_file="t-openbsd"
- case ${enable_threads} in
- yes)
- thread_file='posix'
- ;;
- esac
- case ${target} in
- *-*-openbsd2.*|*-*-openbsd3.[012])
- tm_defines="${tm_defines} HAS_LIBC_R=1" ;;
- esac
- case ${target} in
- *-*-openbsd4.[3-9]|*-*-openbsd[5-9]*)
- default_use_cxa_atexit=yes
- ;;
- esac
- ;;
-*-*-rtems*)
- case ${enable_threads} in
- yes) thread_file='rtems' ;;
- esac
- extra_options="${extra_options} rtems.opt"
- use_gcc_stdint=wrap
- ;;
-*-*-uclinux*)
- extra_options="$extra_options gnu-user.opt"
- use_gcc_stdint=wrap
- tm_defines="$tm_defines DEFAULT_LIBC=LIBC_UCLIBC SINGLE_LIBC"
- ;;
-*-*-rdos*)
- use_gcc_stdint=wrap
- ;;
-*-*-solaris2*)
- # i?86-*-solaris2* needs to insert headers between cpu default and
- # Solaris 2 specific ones.
- sol2_tm_file="dbxelf.h elfos.h ${cpu_type}/sysv4.h sol2.h ${cpu_type}/sol2.h"
- case ${target} in
- *-*-solaris2.1[0-9]*)
- sol2_tm_file="${sol2_tm_file} sol2-10.h"
- use_gcc_stdint=wrap
- ;;
- *)
- use_gcc_stdint=provide
- ;;
- esac
- if test x$gnu_ld = xyes; then
- tm_file="usegld.h ${tm_file}"
- fi
- if test x$gas = xyes; then
- tm_file="usegas.h ${tm_file}"
- fi
- tm_p_file="${tm_p_file} sol2-protos.h"
- tmake_file="${tmake_file} t-sol2 t-slibgcc"
- c_target_objs="${c_target_objs} sol2-c.o"
- cxx_target_objs="${cxx_target_objs} sol2-c.o sol2-cxx.o"
- extra_objs="sol2.o sol2-stubs.o"
- extra_options="${extra_options} sol2.opt"
- case ${enable_threads}:${have_pthread_h}:${have_thread_h} in
- "":yes:* | yes:yes:* )
- thread_file=posix
- ;;
- esac
- ;;
-*-*-*vms*)
- extra_options="${extra_options} vms/vms.opt"
- xmake_file=vms/x-vms
- tmake_file="vms/t-vms t-slibgcc"
- extra_objs="vms.o"
- target_gtfiles="$target_gtfiles \$(srcdir)/config/vms/vms.c"
- tm_p_file="${tm_p_file} vms/vms-protos.h"
- xm_file="vms/xm-vms.h"
- c_target_objs="vms-c.o"
- cxx_target_objs="vms-c.o"
- fortran_target_objs="vms-f.o"
- use_gcc_stdint=provide
- tm_file="${tm_file} vms/vms-stdint.h"
- if test x$gnu_ld != xyes; then
- # Build wrappers for native case.
- extra_programs="ld\$(exeext) ar\$(exeext)"
- tmake_file="$tmake_file vms/t-vmsnative"
- fi
- ;;
-*-*-vxworks*)
- tmake_file=t-vxworks
- xm_defines=POSIX
- extra_options="${extra_options} vxworks.opt"
- extra_objs=vxworks.o
- case ${enable_threads} in
- no) ;;
- "" | yes | vxworks) thread_file='vxworks' ;;
- *) echo 'Unknown thread configuration for VxWorks'; exit 1 ;;
- esac
- ;;
-*-*-elf)
- # Assume that newlib is being used and so __cxa_atexit is provided.
- default_use_cxa_atexit=yes
- use_gcc_stdint=wrap
- ;;
-esac
-
-case ${target} in
-aarch64*-*-elf)
- tm_file="${tm_file} dbxelf.h elfos.h newlib-stdint.h"
- tm_file="${tm_file} aarch64/aarch64-elf.h aarch64/aarch64-elf-raw.h"
- tmake_file="${tmake_file} aarch64/t-aarch64"
- use_gcc_stdint=wrap
- case $target in
- aarch64_be-*)
- tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
- ;;
- esac
- ;;
-aarch64*-*-linux*)
- tm_file="${tm_file} dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h"
- tm_file="${tm_file} aarch64/aarch64-elf.h aarch64/aarch64-linux.h"
- tmake_file="${tmake_file} aarch64/t-aarch64 aarch64/t-aarch64-linux"
- case $target in
- aarch64_be-*)
- tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
- ;;
- esac
- ;;
-alpha*-*-linux*)
- tm_file="elfos.h ${tm_file} alpha/elf.h alpha/linux.h alpha/linux-elf.h glibc-stdint.h"
- tmake_file="${tmake_file} alpha/t-linux"
- extra_options="${extra_options} alpha/elf.opt"
- ;;
-alpha*-*-freebsd*)
- tm_file="elfos.h ${tm_file} ${fbsd_tm_file} alpha/elf.h alpha/freebsd.h"
- extra_options="${extra_options} alpha/elf.opt"
- ;;
-alpha*-*-netbsd*)
- tm_file="elfos.h ${tm_file} netbsd.h alpha/elf.h netbsd-elf.h alpha/netbsd.h"
- extra_options="${extra_options} netbsd.opt netbsd-elf.opt \
- alpha/elf.opt"
- ;;
-alpha*-*-openbsd*)
- tm_defines="${tm_defines} OBSD_HAS_DECLARE_FUNCTION_NAME OBSD_HAS_DECLARE_FUNCTION_SIZE OBSD_HAS_DECLARE_OBJECT"
- tm_file="elfos.h alpha/alpha.h alpha/elf.h openbsd.h openbsd-stdint.h alpha/openbsd.h openbsd-libpthread.h"
- extra_options="${extra_options} openbsd.opt alpha/elf.opt"
- # default x-alpha is only appropriate for dec-osf.
- ;;
-alpha*-dec-*vms*)
- tm_file="${tm_file} vms/vms.h alpha/vms.h"
- tmake_file="${tmake_file} alpha/t-vms"
- ;;
-arm-wrs-vxworks)
- tm_file="elfos.h arm/elf.h arm/aout.h ${tm_file} vx-common.h vxworks.h arm/vxworks.h"
- extra_options="${extra_options} arm/vxworks.opt"
- tmake_file="${tmake_file} arm/t-arm arm/t-vxworks"
- ;;
-arm*-*-netbsdelf*)
- tm_file="dbxelf.h elfos.h netbsd.h netbsd-elf.h arm/elf.h arm/aout.h ${tm_file} arm/netbsd-elf.h"
- extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
- tmake_file="${tmake_file} arm/t-arm"
- ;;
-arm*-*-linux-*) # ARM GNU/Linux with ELF
- tm_file="dbxelf.h elfos.h gnu-user.h linux.h linux-android.h glibc-stdint.h arm/elf.h arm/linux-gas.h arm/linux-elf.h"
- case $target in
- arm*b-*-linux*)
- tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
- ;;
- esac
- tmake_file="${tmake_file} arm/t-arm arm/t-arm-elf arm/t-bpabi arm/t-linux-eabi"
- tm_file="$tm_file arm/bpabi.h arm/linux-eabi.h arm/aout.h vxworks-dummy.h arm/arm.h"
- # Define multilib configuration for arm-linux-androideabi.
- case ${target} in
- *-androideabi)
- tmake_file="$tmake_file arm/t-linux-androideabi"
- ;;
- esac
- # 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
- with_tls=${with_tls:-gnu}
- ;;
-arm*-*-uclinux*eabi*) # ARM ucLinux
- tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/linux-gas.h arm/uclinux-elf.h glibc-stdint.h"
- tmake_file="arm/t-arm arm/t-arm-elf arm/t-bpabi"
- tm_file="$tm_file arm/bpabi.h arm/uclinux-eabi.h arm/aout.h vxworks-dummy.h arm/arm.h"
- # 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
- ;;
-arm*-*-eabi* | arm*-*-symbianelf* | arm*-*-rtems*)
- case ${target} in
- arm*eb-*-eabi*)
- tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
- esac
- # 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
- default_use_cxa_atexit=yes
- tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/bpabi.h"
- tmake_file="arm/t-arm arm/t-arm-elf"
- case ${target} in
- arm*-*-eabi*)
- tm_file="$tm_file newlib-stdint.h"
- tmake_file="${tmake_file} arm/t-bpabi"
- use_gcc_stdint=wrap
- ;;
- arm*-*-rtems*)
- tm_file="${tm_file} rtems.h arm/rtems-eabi.h newlib-stdint.h"
- tmake_file="${tmake_file} arm/t-bpabi t-rtems arm/t-rtems-eabi"
- ;;
- arm*-*-symbianelf*)
- tm_file="${tm_file} arm/symbian.h"
- # We do not include t-bpabi for Symbian OS because the system
- # provides its own implementation of the BPABI functions.
- tmake_file="${tmake_file} arm/t-symbian"
- ;;
- esac
- tm_file="${tm_file} arm/aout.h vxworks-dummy.h arm/arm.h"
- ;;
-avr-*-rtems*)
- tm_file="elfos.h avr/elf.h avr/avr-arch.h avr/avr.h dbxelf.h avr/rtems.h rtems.h newlib-stdint.h"
- tmake_file="avr/t-avr avr/t-multilib t-rtems avr/t-rtems"
- extra_gcc_objs="driver-avr.o avr-devices.o"
- extra_objs="avr-devices.o avr-log.o"
- ;;
-avr-*-*)
- tm_file="elfos.h avr/elf.h avr/avr-arch.h avr/avr.h dbxelf.h avr/avr-stdint.h"
- if test x${with_avrlibc} != xno; then
- tm_file="${tm_file} ${cpu_type}/avrlibc.h"
- tm_defines="${tm_defines} WITH_AVRLIBC"
- fi
- tmake_file="avr/t-avr avr/t-multilib"
- use_gcc_stdint=wrap
- extra_gcc_objs="driver-avr.o avr-devices.o"
- extra_objs="avr-devices.o avr-log.o"
- ;;
-bfin*-elf*)
- tm_file="${tm_file} dbxelf.h elfos.h newlib-stdint.h bfin/elf.h"
- tmake_file=bfin/t-bfin-elf
- use_collect2=no
- ;;
-bfin*-uclinux*)
- tm_file="${tm_file} dbxelf.h elfos.h bfin/elf.h gnu-user.h linux.h glibc-stdint.h bfin/uclinux.h"
- tmake_file=bfin/t-bfin-uclinux
- use_collect2=no
- ;;
-bfin*-linux-uclibc*)
- tm_file="${tm_file} dbxelf.h elfos.h bfin/elf.h gnu-user.h linux.h glibc-stdint.h bfin/linux.h ./linux-sysroot-suffix.h"
- tmake_file="bfin/t-bfin-linux t-slibgcc"
- use_collect2=no
- ;;
-bfin*-rtems*)
- tm_file="${tm_file} dbxelf.h elfos.h bfin/elf.h bfin/rtems.h rtems.h newlib-stdint.h"
- tmake_file="t-rtems bfin/t-rtems"
- ;;
-bfin*-*)
- tm_file="${tm_file} dbxelf.h elfos.h newlib-stdint.h bfin/elf.h"
- use_collect2=no
- use_gcc_stdint=wrap
- ;;
-cr16-*-elf)
- tm_file="elfos.h ${tm_file}"
- tmake_file="${tmake_file} cr16/t-cr16 "
- use_collect2=no
- ;;
-crisv32-*-elf | crisv32-*-none)
- tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
- tmake_file="cris/t-cris"
- target_cpu_default=32
- gas=yes
- extra_options="${extra_options} cris/elf.opt"
- use_gcc_stdint=wrap
- ;;
-cris-*-elf | cris-*-none)
- tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
- tmake_file="cris/t-cris cris/t-elfmulti"
- gas=yes
- extra_options="${extra_options} cris/elf.opt"
- use_gcc_stdint=wrap
- ;;
-crisv32-*-linux* | cris-*-linux*)
- tm_file="dbxelf.h elfos.h ${tm_file} gnu-user.h linux.h glibc-stdint.h cris/linux.h"
- # We need to avoid using t-linux, so override default tmake_file
- tmake_file="cris/t-cris cris/t-linux t-slibgcc"
- extra_options="${extra_options} cris/linux.opt"
- case $target in
- cris-*-*)
- target_cpu_default=10
- ;;
- crisv32-*-*)
- target_cpu_default=32
- ;;
- esac
- ;;
-epiphany-*-elf )
- tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
- tmake_file="epiphany/t-epiphany"
- extra_options="${extra_options} fused-madd.opt"
- extra_objs="$extra_objs mode-switch-use.o resolve-sw-modes.o"
- tm_defines="${tm_defines} EPIPHANY_STACK_OFFSET=${with_stack_offset:-8}"
- extra_headers="epiphany_intrinsics.h"
- ;;
-fr30-*-elf)
- tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
- ;;
-frv-*-elf)
- tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
- tmake_file=frv/t-frv
- ;;
-frv-*-*linux*)
- tm_file="dbxelf.h elfos.h ${tm_file} \
- gnu-user.h linux.h glibc-stdint.h frv/linux.h"
- tmake_file="${tmake_file} frv/t-frv frv/t-linux"
- ;;
-moxie-*-elf)
- gas=yes
- gnu_ld=yes
- tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
- tmake_file="${tmake_file} moxie/t-moxie"
- ;;
-moxie-*-uclinux*)
- gas=yes
- gnu_ld=yes
- tm_file="dbxelf.h elfos.h ${tm_file} gnu-user.h linux.h glibc-stdint.h moxie/uclinux.h"
- tmake_file="${tmake_file} moxie/t-moxie"
- ;;
-moxie-*-rtems*)
- tmake_file="${tmake_file} moxie/t-moxie t-rtems"
- tm_file="moxie/moxie.h dbxelf.h elfos.h moxie/rtems.h rtems.h newlib-stdint.h"
- ;;
-h8300-*-rtems*)
- tmake_file="h8300/t-h8300 t-rtems h8300/t-rtems"
- tm_file="h8300/h8300.h dbxelf.h elfos.h h8300/elf.h h8300/rtems.h rtems.h newlib-stdint.h"
- ;;
-h8300-*-elf*)
- tmake_file="h8300/t-h8300"
- tm_file="h8300/h8300.h dbxelf.h elfos.h newlib-stdint.h h8300/elf.h"
- ;;
-hppa*64*-*-linux*)
- target_cpu_default="MASK_PA_11|MASK_PA_20"
- tm_file="pa/pa64-start.h ${tm_file} dbxelf.h elfos.h gnu-user.h linux.h \
- glibc-stdint.h pa/pa-linux.h pa/pa64-regs.h pa/pa-64.h \
- pa/pa64-linux.h"
- tmake_file="${tmake_file} pa/t-linux"
- gas=yes gnu_ld=yes
- need_64bit_hwint=yes
- ;;
-hppa*-*-linux*)
- target_cpu_default="MASK_PA_11|MASK_NO_SPACE_REGS"
- tm_file="${tm_file} dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h pa/pa-linux.h \
- pa/pa32-regs.h pa/pa32-linux.h"
- tmake_file="${tmake_file} pa/t-linux"
- ;;
-hppa*-*-openbsd*)
- target_cpu_default="MASK_PA_11"
- tm_file="${tm_file} dbxelf.h elfos.h openbsd.h openbsd-stdint.h openbsd-libpthread.h \
- pa/pa-openbsd.h pa/pa32-regs.h pa/pa32-openbsd.h"
- tmake_file="${tmake_file} pa/t-openbsd"
- extra_options="${extra_options} openbsd.opt"
- gas=yes
- gnu_ld=yes
- ;;
-hppa[12]*-*-hpux10*)
- case ${target} in
- hppa1.1-*-* | hppa2*-*-*)
- target_cpu_default="MASK_PA_11"
- ;;
- esac
- tm_file="${tm_file} pa/pa32-regs.h dbxelf.h pa/som.h \
- pa/pa-hpux.h pa/pa-hpux10.h"
- extra_options="${extra_options} pa/pa-hpux.opt pa/pa-hpux10.opt"
- case ${target} in
- *-*-hpux10.[1-9]*)
- tm_file="${tm_file} pa/pa-hpux1010.h"
- extra_options="${extra_options} pa/pa-hpux1010.opt"
- ;;
- esac
- use_gcc_stdint=provide
- tm_file="${tm_file} hpux-stdint.h"
- tmake_file="t-slibgcc"
- case ${enable_threads} in
- "")
- if test x$have_pthread_h = xyes ; then
- tmake_file="${tmake_file} pa/t-dce-thr"
- fi
- ;;
- yes | dce)
- tmake_file="${tmake_file} pa/t-dce-thr"
- ;;
- esac
- use_collect2=yes
- gas=yes
- if test "x$with_dwarf2" != x; then
- echo "Warning: dwarf2 debug format is not supported for this target, --with-dwarf2 ignored" 1>&2
- dwarf2=no
- fi
- ;;
-hppa*64*-*-hpux11*)
- target_cpu_default="MASK_PA_11|MASK_PA_20"
- if test x$gnu_ld = xyes
- then
- target_cpu_default="${target_cpu_default}|MASK_GNU_LD"
- fi
- tm_file="pa/pa64-start.h ${tm_file} dbxelf.h elfos.h \
- pa/pa64-regs.h pa/pa-hpux.h pa/pa-hpux1010.h \
- pa/pa-hpux11.h"
- case ${target} in
- *-*-hpux11.[12]*)
- tm_file="${tm_file} pa/pa-hpux1111.h pa/pa-64.h pa/pa64-hpux.h"
- extra_options="${extra_options} pa/pa-hpux1111.opt"
- ;;
- *-*-hpux11.[3-9]*)
- tm_file="${tm_file} pa/pa-hpux1131.h pa/pa-64.h pa/pa64-hpux.h"
- extra_options="${extra_options} pa/pa-hpux1131.opt"
- ;;
- *)
- tm_file="${tm_file} pa/pa-64.h pa/pa64-hpux.h"
- ;;
- esac
- extra_options="${extra_options} pa/pa-hpux.opt \
- pa/pa-hpux1010.opt pa/pa64-hpux.opt hpux11.opt"
- need_64bit_hwint=yes
- tmake_file="t-slibgcc"
- case x${enable_threads} in
- x | xyes | xposix )
- thread_file=posix
- ;;
- esac
- gas=yes
- case ${target} in
- *-*-hpux11.[01]*)
- use_gcc_stdint=provide
- tm_file="${tm_file} hpux-stdint.h"
- ;;
- *-*-hpux11.[23]*)
- use_gcc_stdint=wrap
- tm_file="${tm_file} hpux-stdint.h"
- ;;
- esac
- ;;
-hppa[12]*-*-hpux11*)
- case ${target} in
- hppa1.1-*-* | hppa2*-*-*)
- target_cpu_default="MASK_PA_11"
- ;;
- esac
- tm_file="${tm_file} pa/pa32-regs.h dbxelf.h pa/som.h \
- pa/pa-hpux.h pa/pa-hpux1010.h pa/pa-hpux11.h"
- extra_options="${extra_options} pa/pa-hpux.opt pa/pa-hpux1010.opt \
- hpux11.opt"
- case ${target} in
- *-*-hpux11.[12]*)
- tm_file="${tm_file} pa/pa-hpux1111.h"
- extra_options="${extra_options} pa/pa-hpux1111.opt"
- ;;
- *-*-hpux11.[3-9]*)
- tm_file="${tm_file} pa/pa-hpux1131.h"
- extra_options="${extra_options} pa/pa-hpux1131.opt"
- ;;
- esac
- tmake_file="t-slibgcc"
- case x${enable_threads} in
- x | xyes | xposix )
- thread_file=posix
- ;;
- esac
- use_collect2=yes
- gas=yes
- case ${target} in
- *-*-hpux11.[01]*)
- use_gcc_stdint=provide
- tm_file="${tm_file} hpux-stdint.h"
- ;;
- *-*-hpux11.[23]*)
- use_gcc_stdint=wrap
- tm_file="${tm_file} hpux-stdint.h"
- ;;
- esac
- if test "x$with_dwarf2" != x; then
- echo "Warning: dwarf2 debug format is not supported for this target, --with-dwarf2 ignored" 1>&2
- dwarf2=no
- fi
- ;;
-i[34567]86-*-darwin*)
- need_64bit_isa=yes
- # Baseline choice for a machine that allows m64 support.
- with_cpu=${with_cpu:-core2}
- tmake_file="${tmake_file} t-slibgcc"
- ;;
-x86_64-*-darwin*)
- with_cpu=${with_cpu:-core2}
- tmake_file="${tmake_file} ${cpu_type}/t-darwin64 t-slibgcc"
- tm_file="${tm_file} ${cpu_type}/darwin64.h"
- ;;
-i[34567]86-*-elf*)
- tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h"
- ;;
-x86_64-*-elf*)
- tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h i386/x86-64.h"
- ;;
-i[34567]86-*-rdos*)
- tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h i386/rdos.h"
- ;;
-x86_64-*-rdos*)
- tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h i386/x86-64.h i386/rdos.h i386/rdos64.h"
- tmake_file="i386/t-i386elf t-svr4"
- ;;
-i[34567]86-*-freebsd*)
- tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h ${fbsd_tm_file} i386/freebsd.h"
- ;;
-x86_64-*-freebsd*)
- tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h ${fbsd_tm_file} i386/x86-64.h i386/freebsd.h i386/freebsd64.h"
- ;;
-i[34567]86-*-netbsdelf*)
- tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h netbsd.h netbsd-elf.h i386/netbsd-elf.h"
- extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
- ;;
-x86_64-*-netbsd*)
- tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h netbsd.h netbsd-elf.h i386/x86-64.h i386/netbsd64.h"
- extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
- ;;
-i[34567]86-*-openbsd2.*|i[34567]86-*openbsd3.[0123])
- tm_file="i386/i386.h i386/unix.h i386/bsd.h i386/gas.h i386/gstabs.h openbsd-oldgas.h openbsd.h i386/openbsd.h"
- extra_options="${extra_options} openbsd.opt"
- # needed to unconfuse gdb
- tmake_file="${tmake_file} t-openbsd i386/t-openbsd"
- # we need collect2 until our bug is fixed...
- use_collect2=yes
- ;;
-i[34567]86-*-openbsd*)
- tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h"
- tm_file="${tm_file} openbsd.h openbsd-stdint.h openbsd-libpthread.h i386/openbsdelf.h"
- extra_options="${extra_options} openbsd.opt"
- gas=yes
- gnu_ld=yes
- ;;
-x86_64-*-openbsd*)
- tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h"
- tm_file="${tm_file} openbsd.h openbsd-stdint.h openbsd-libpthread.h i386/x86-64.h i386/openbsdelf.h"
- extra_options="${extra_options} openbsd.opt"
- gas=yes
- gnu_ld=yes
- ;;
-i[34567]86-*-linux* | i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-knetbsd*-gnu | i[34567]86-*-gnu* | i[34567]86-*-kopensolaris*-gnu)
- # Intel 80386's running GNU/*
- # with ELF format using glibc 2
- tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h gnu-user.h glibc-stdint.h"
- case ${target} in
- i[34567]86-*-linux*)
- tm_file="${tm_file} linux.h"
- # Assume modern glibc
- default_gnu_indirect_function=yes
- if test x$enable_targets = xall; then
- tm_file="${tm_file} i386/x86-64.h i386/gnu-user-common.h i386/gnu-user64.h i386/linux-common.h i386/linux64.h"
- tm_defines="${tm_defines} TARGET_BI_ARCH=1"
- tmake_file="${tmake_file} i386/t-linux64"
- x86_multilibs="${with_multilib_list}"
- if test "$x86_multilibs" = "default"; then
- x86_multilibs="m64,m32"
- fi
- x86_multilibs=`echo $x86_multilibs | sed -e 's/,/ /g'`
- for x86_multilib in ${x86_multilibs}; do
- case ${x86_multilib} in
- m32 | m64 | mx32)
- TM_MULTILIB_CONFIG="${TM_MULTILIB_CONFIG},${x86_multilib}"
- ;;
- *)
- echo "--with-multilib-list=${x86_with_multilib} not supported."
- exit 1
- esac
- done
- TM_MULTILIB_CONFIG=`echo $TM_MULTILIB_CONFIG | sed 's/^,//'`
- need_64bit_isa=yes
- case X"${with_cpu}" in
- Xgeneric|Xatom|Xslm|Xcore2|Xcorei7|Xcorei7-avx|Xnocona|Xx86-64|Xbdver3|Xbdver2|Xbdver1|Xbtver2|Xbtver1|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx|Xathlon64-sse3|Xk8-sse3|Xopteron-sse3)
- ;;
- X)
- if test x$with_cpu_64 = x; then
- with_cpu_64=generic
- fi
- ;;
- *)
- echo "Unsupported CPU used in --with-cpu=$with_cpu, supported values:" 1>&2
- echo "generic atom slm core2 corei7 corei7-avx nocona x86-64 bdver3 bdver2 bdver1 btver2 btver1 amdfam10 barcelona k8 opteron athlon64 athlon-fx athlon64-sse3 k8-sse3 opteron-sse3" 1>&2
- exit 1
- ;;
- esac
- else
- tm_file="${tm_file} i386/gnu-user-common.h i386/gnu-user.h i386/linux-common.h i386/linux.h"
- fi
- ;;
- i[34567]86-*-knetbsd*-gnu)
- tm_file="${tm_file} i386/gnu-user-common.h i386/gnu-user.h knetbsd-gnu.h i386/knetbsd-gnu.h"
- ;;
- i[34567]86-*-kfreebsd*-gnu)
- tm_file="${tm_file} i386/gnu-user-common.h i386/gnu-user.h kfreebsd-gnu.h i386/kfreebsd-gnu.h"
- ;;
- i[34567]86-*-kopensolaris*-gnu)
- tm_file="${tm_file} i386/gnu-user-common.h i386/gnu-user.h kopensolaris-gnu.h i386/kopensolaris-gnu.h"
- ;;
- i[34567]86-*-gnu*)
- tm_file="$tm_file i386/gnu-user-common.h i386/gnu-user.h gnu.h i386/gnu.h"
- ;;
- esac
- ;;
-x86_64-*-linux* | x86_64-*-kfreebsd*-gnu | x86_64-*-knetbsd*-gnu)
- tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h gnu-user.h glibc-stdint.h \
- i386/x86-64.h i386/gnu-user-common.h i386/gnu-user64.h"
- case ${target} in
- x86_64-*-linux*)
- tm_file="${tm_file} linux.h i386/linux-common.h i386/linux64.h"
- # Assume modern glibc
- default_gnu_indirect_function=yes
- ;;
- x86_64-*-kfreebsd*-gnu)
- tm_file="${tm_file} kfreebsd-gnu.h i386/kfreebsd-gnu64.h"
- ;;
- x86_64-*-knetbsd*-gnu)
- tm_file="${tm_file} knetbsd-gnu.h"
- ;;
- esac
- tmake_file="${tmake_file} i386/t-linux64"
- x86_multilibs="${with_multilib_list}"
- if test "$x86_multilibs" = "default"; then
- case ${with_abi} in
- x32 | mx32)
- x86_multilibs="mx32"
- ;;
- *)
- x86_multilibs="m64,m32"
- ;;
- esac
- fi
- x86_multilibs=`echo $x86_multilibs | sed -e 's/,/ /g'`
- for x86_multilib in ${x86_multilibs}; do
- case ${x86_multilib} in
- m32 | m64 | mx32)
- TM_MULTILIB_CONFIG="${TM_MULTILIB_CONFIG},${x86_multilib}"
- ;;
- *)
- echo "--with-multilib-list=${x86_with_multilib} not supported."
- exit 1
- esac
- done
- TM_MULTILIB_CONFIG=`echo $TM_MULTILIB_CONFIG | sed 's/^,//'`
- ;;
-i[34567]86-pc-msdosdjgpp*)
- xm_file=i386/xm-djgpp.h
- tm_file="dbxcoff.h ${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/djgpp.h i386/djgpp-stdint.h"
- native_system_header_dir=/dev/env/DJDIR/include
- extra_options="${extra_options} i386/djgpp.opt"
- gnu_ld=yes
- gas=yes
- use_gcc_stdint=wrap
- ;;
-i[34567]86-*-lynxos*)
- xm_defines=POSIX
- tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h i386/lynx.h lynx.h"
- tmake_file="${tmake_file} t-lynx"
- extra_options="${extra_options} lynx.opt"
- thread_file=lynx
- gnu_ld=yes
- gas=yes
- ;;
-i[34567]86-*-nto-qnx*)
- tm_file="${tm_file} i386/att.h dbxelf.h tm-dwarf2.h elfos.h i386/unix.h i386/nto.h"
- extra_options="${extra_options} i386/nto.opt"
- gnu_ld=yes
- gas=yes
- ;;
-i[34567]86-*-rtems*)
- tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h i386/i386elf.h i386/rtemself.h rtems.h newlib-stdint.h"
- tmake_file="${tmake_file} i386/t-rtems t-rtems"
- ;;
-i[34567]86-*-solaris2* | x86_64-*-solaris2.1[0-9]*)
- tm_file="${tm_file} i386/unix.h i386/att.h ${sol2_tm_file}"
- # Set default arch_32 to pentium4, tune_32 to generic like the other
- # i386 targets, although config.guess defaults to i386-pc-solaris2*.
- case ${target} in
- *-*-solaris2.9*)
- # Solaris 9/x86 cannot execute SSE/SSE2 instructions by default.
- with_arch_32=${with_arch_32:-pentiumpro}
- ;;
- *)
- with_arch_32=${with_arch_32:-pentium4}
- ;;
- esac
- with_tune_32=${with_tune_32:-generic}
- case ${target} in
- *-*-solaris2.1[0-9]*)
- tm_file="${tm_file} i386/x86-64.h i386/sol2-bi.h sol2-bi.h"
- tm_defines="${tm_defines} TARGET_BI_ARCH=1"
- tmake_file="$tmake_file i386/t-sol2-64"
- need_64bit_isa=yes
- case X"${with_cpu}" in
- Xgeneric|Xatom|Xslm|Xcore2|Xcorei7|Xcorei7-avx|Xnocona|Xx86-64|Xbdver3|Xbdver2|Xbdver1|Xbtver2|Xbtver1|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx|Xathlon64-sse3|Xk8-sse3|Xopteron-sse3)
- ;;
- X)
- if test x$with_cpu_64 = x; then
- with_cpu_64=generic
- fi
- ;;
- *)
- echo "Unsupported CPU used in --with-cpu=$with_cpu, supported values:" 1>&2
- echo "generic atom slm core2 corei7 corei7-avx nocona x86-64 bdver3 bdver2 bdver1 btver2 btver1 amdfam10 barcelona k8 opteron athlon64 athlon-fx athlon64-sse3 k8-sse3 opteron-sse3" 1>&2
- exit 1
- ;;
- esac
- ;;
- esac
- ;;
-i[4567]86-wrs-vxworks|i[4567]86-wrs-vxworksae)
- tm_file="${tm_file} i386/unix.h i386/att.h elfos.h vx-common.h"
- case ${target} in
- *-vxworksae*)
- tm_file="${tm_file} vxworksae.h i386/vx-common.h i386/vxworksae.h"
- tmake_file="${tmake_file} i386/t-vxworks i386/t-vxworksae"
- ;;
- *)
- tm_file="${tm_file} vxworks.h i386/vx-common.h i386/vxworks.h"
- tmake_file="${tmake_file} i386/t-vxworks"
- ;;
- esac
- ;;
-i[34567]86-*-cygwin*)
- tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygming.h i386/cygwin.h i386/cygwin-stdint.h"
- xm_file=i386/xm-cygwin.h
- tmake_file="${tmake_file} i386/t-cygming t-slibgcc"
- target_gtfiles="\$(srcdir)/config/i386/winnt.c"
- extra_options="${extra_options} i386/cygming.opt"
- extra_objs="winnt.o winnt-stubs.o"
- c_target_objs="${c_target_objs} msformat-c.o"
- cxx_target_objs="${cxx_target_objs} winnt-cxx.o msformat-c.o"
- if test x$enable_threads = xyes; then
- thread_file='posix'
- fi
- use_gcc_stdint=wrap
- ;;
-i[34567]86-*-mingw* | x86_64-*-mingw*)
- tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygming.h"
- xm_file=i386/xm-mingw32.h
- case ${target} in
- x86_64-*-* | *-w64-*)
- need_64bit_isa=yes
- ;;
- *)
- ;;
- esac
- if test x$enable_threads = xposix ; then
- tm_file="${tm_file} i386/mingw-pthread.h"
- fi
- tm_file="${tm_file} i386/mingw32.h"
- # This makes the logic if mingw's or the w64 feature set has to be used
- case ${target} in
- *-w64-*)
- user_headers_inc_next_post="${user_headers_inc_next_post} float.h"
- user_headers_inc_next_pre="${user_headers_inc_next_pre} stddef.h stdarg.h"
- tm_file="${tm_file} i386/mingw-w64.h"
- if test x$enable_targets = xall; then
- tm_defines="${tm_defines} TARGET_BI_ARCH=1"
- case X"${with_cpu}" in
- Xgeneric|Xatom|Xslm|Xcore2|Xcorei7|Xcorei7-avx|Xnocona|Xx86-64|Xbdver3|Xbdver2|Xbdver1|Xbtver2|Xbtver1|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx|Xathlon64-sse3|Xk8-sse3|Xopteron-sse3)
- ;;
- X)
- if test x$with_cpu_64 = x; then
- with_cpu_64=generic
- fi
- ;;
- *)
- echo "Unsupported CPU used in --with-cpu=$with_cpu, supported values:" 1>&2
- echo "generic atom slm core2 corei7 Xcorei7-avx nocona x86-64 bdver3 bdver2 bdver1 btver2 btver1 amdfam10 barcelona k8 opteron athlon64 athlon-fx athlon64-sse3 k8-sse3 opteron-sse3" 1>&2
- exit 1
- ;;
- esac
- fi
- ;;
- *)
- ;;
- esac
- tm_file="${tm_file} i386/mingw-stdint.h"
- tmake_file="${tmake_file} i386/t-cygming t-slibgcc"
- case ${target} in
- x86_64-w64-*)
- tmake_file="${tmake_file} i386/t-mingw-w64"
- ;;
- i[34567]86-w64-*)
- tmake_file="${tmake_file} i386/t-mingw-w32"
- ;;
- esac
- native_system_header_dir=/mingw/include
- target_gtfiles="\$(srcdir)/config/i386/winnt.c"
- extra_options="${extra_options} i386/cygming.opt i386/mingw.opt"
- case ${target} in
- *-w64-*)
- extra_options="${extra_options} i386/mingw-w64.opt"
- ;;
- *)
- ;;
- esac
- extra_objs="winnt.o winnt-stubs.o"
- c_target_objs="${c_target_objs} msformat-c.o"
- cxx_target_objs="${cxx_target_objs} winnt-cxx.o msformat-c.o"
- gas=yes
- gnu_ld=yes
- default_use_cxa_atexit=yes
- use_gcc_stdint=wrap
- case ${enable_threads} in
- "" | yes | win32)
- thread_file='win32'
- ;;
- posix)
- thread_file='posix'
- ;;
- esac
- case ${target} in
- *mingw32crt*)
- tm_file="${tm_file} i386/crtdll.h"
- ;;
- *mingw32msv* | *mingw*)
- ;;
- esac
- ;;
-i[34567]86-*-interix[3-9]*)
- tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/i386-interix.h"
- tmake_file="${tmake_file} i386/t-interix"
- extra_options="${extra_options} rpath.opt i386/interix.opt"
- extra_objs="winnt.o winnt-stubs.o"
- target_gtfiles="\$(srcdir)/config/i386/winnt.c"
- if test x$enable_threads = xyes ; then
- thread_file='posix'
- fi
- if test x$stabs = xyes ; then
- tm_file="${tm_file} dbxcoff.h"
- fi
- ;;
-ia64*-*-elf*)
- tm_file="${tm_file} dbxelf.h elfos.h newlib-stdint.h ia64/sysv4.h ia64/elf.h"
- tmake_file="ia64/t-ia64"
- target_cpu_default="0"
- if test x$gas = xyes
- then
- target_cpu_default="${target_cpu_default}|MASK_GNU_AS"
- fi
- if test x$gnu_ld = xyes
- then
- target_cpu_default="${target_cpu_default}|MASK_GNU_LD"
- fi
- ;;
-ia64*-*-freebsd*)
- tm_file="${tm_file} dbxelf.h elfos.h ${fbsd_tm_file} ia64/sysv4.h ia64/freebsd.h"
- target_cpu_default="MASK_GNU_AS|MASK_GNU_LD"
- tmake_file="${tmake_file} ia64/t-ia64"
- ;;
-ia64*-*-linux*)
- tm_file="${tm_file} dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ia64/sysv4.h ia64/linux.h"
- tmake_file="${tmake_file} ia64/t-ia64 ia64/t-linux t-libunwind"
- target_cpu_default="MASK_GNU_AS|MASK_GNU_LD"
- ;;
-ia64*-*-hpux*)
- tm_file="${tm_file} dbxelf.h elfos.h ia64/sysv4.h ia64/hpux.h"
- tmake_file="ia64/t-ia64 ia64/t-hpux t-slibgcc"
- target_cpu_default="MASK_GNU_AS"
- case x$enable_threads in
- x | xyes | xposix )
- thread_file=posix
- ;;
- esac
- use_collect2=no
- c_target_objs="ia64-c.o"
- cxx_target_objs="ia64-c.o"
- extra_options="${extra_options} ia64/ilp32.opt hpux11.opt"
- use_gcc_stdint=wrap
- tm_file="${tm_file} hpux-stdint.h"
- case ${target} in
- *-*-hpux11.3*)
- tm_file="${tm_file} ia64/hpux-unix2003.h"
- ;;
- esac
- ;;
-ia64-hp-*vms*)
- tm_file="${tm_file} elfos.h ia64/sysv4.h vms/vms.h ia64/vms.h"
- tmake_file="${tmake_file} ia64/t-ia64"
- target_cpu_default="0"
- if test x$gas = xyes
- then
- target_cpu_default="${target_cpu_default}|MASK_GNU_AS"
- fi
- extra_options="${extra_options} ia64/vms.opt"
- ;;
-iq2000*-*-elf*)
- tm_file="elfos.h newlib-stdint.h iq2000/iq2000.h"
- out_file=iq2000/iq2000.c
- md_file=iq2000/iq2000.md
- ;;
-lm32-*-elf*)
- tm_file="dbxelf.h elfos.h ${tm_file}"
- tmake_file="${tmake_file} lm32/t-lm32"
- ;;
-lm32-*-rtems*)
- tm_file="dbxelf.h elfos.h ${tm_file} lm32/rtems.h rtems.h newlib-stdint.h"
- tmake_file="${tmake_file} lm32/t-lm32"
- tmake_file="${tmake_file} t-rtems"
- tmake_file="${tmake_file} lm32/t-rtems"
- ;;
-lm32-*-uclinux*)
- tm_file="dbxelf.h elfos.h ${tm_file} gnu-user.h linux.h lm32/uclinux-elf.h"
- tmake_file="${tmake_file} lm32/t-lm32"
- ;;
-m32r-*-elf*)
- tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
- ;;
-m32rle-*-elf*)
- tm_file="dbxelf.h elfos.h newlib-stdint.h m32r/little.h ${tm_file}"
- ;;
-m32r-*-rtems*)
- tm_file="dbxelf.h elfos.h ${tm_file} m32r/rtems.h rtems.h newlib-stdint.h"
- tmake_file="m32r/t-m32r t-rtems"
- ;;
-m32r-*-linux*)
- tm_file="dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file} m32r/linux.h"
- # We override the tmake_file for linux -- why?
- tmake_file="m32r/t-linux t-slibgcc"
- gnu_ld=yes
- if test x$enable_threads = xyes; then
- thread_file='posix'
- fi
- ;;
-m32rle-*-linux*)
- tm_file="dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h m32r/little.h ${tm_file} m32r/linux.h"
- # We override the tmake_file for linux -- why?
- tmake_file="m32r/t-linux t-slibgcc"
- gnu_ld=yes
- if test x$enable_threads = xyes; then
- thread_file='posix'
- fi
- ;;
-m68k-*-elf* | fido-*-elf*)
- case ${target} in
- fido-*-elf*)
- # Check that $with_cpu makes sense.
- case $with_cpu in
- "" | "fidoa")
- ;;
- *)
- echo "Cannot accept --with-cpu=$with_cpu"
- exit 1
- ;;
- esac
- with_cpu=fidoa
- ;;
- *)
- default_m68k_cpu=68020
- default_cf_cpu=5206
- ;;
- esac
- tm_file="${tm_file} m68k/m68k-none.h m68k/m68kelf.h dbxelf.h elfos.h newlib-stdint.h m68k/m68kemb.h m68k/m68020-elf.h"
- tm_defines="${tm_defines} MOTOROLA=1"
- tmake_file="m68k/t-floatlib m68k/t-m68kbare m68k/t-m68kelf"
- # Add multilibs for targets other than fido.
- case ${target} in
- fido-*-elf*)
- ;;
- *)
- tmake_file="$tmake_file m68k/t-mlibs"
- ;;
- esac
- ;;
-m68k*-*-netbsdelf*)
- default_m68k_cpu=68020
- default_cf_cpu=5475
- tm_file="${tm_file} dbxelf.h elfos.h netbsd.h netbsd-elf.h m68k/netbsd-elf.h"
- extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
- tm_defines="${tm_defines} MOTOROLA=1"
- ;;
-m68k*-*-openbsd*)
- default_m68k_cpu=68020
- default_cf_cpu=5475
- # needed to unconfuse gdb
- tm_defines="${tm_defines} OBSD_OLD_GAS"
- tm_file="${tm_file} openbsd.h openbsd-stdint.h openbsd-libpthread.h m68k/openbsd.h"
- extra_options="${extra_options} openbsd.opt"
- tmake_file="t-openbsd m68k/t-openbsd"
- # we need collect2 until our bug is fixed...
- use_collect2=yes
- ;;
-m68k-*-uclinux*) # Motorola m68k/ColdFire running uClinux
- # with uClibc, using the new GNU/Linux-style
- # ABI.
- default_m68k_cpu=68020
- default_cf_cpu=5206
- tm_file="${tm_file} dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h flat.h m68k/linux.h m68k/uclinux.h ./sysroot-suffix.h"
- extra_options="${extra_options} m68k/uclinux.opt"
- tm_defines="${tm_defines} MOTOROLA=1"
- tmake_file="m68k/t-floatlib m68k/t-uclinux m68k/t-mlibs"
- ;;
-m68k-*-linux*) # Motorola m68k's running GNU/Linux
- # with ELF format using glibc 2
- # aka the GNU/Linux C library 6.
- default_m68k_cpu=68020
- default_cf_cpu=5475
- with_arch=${with_arch:-m68k}
- tm_file="${tm_file} dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.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"
- ;;
-m68k-*-rtems*)
- default_m68k_cpu=68020
- default_cf_cpu=5206
- tmake_file="m68k/t-floatlib m68k/t-m68kbare m68k/t-crtstuff t-rtems m68k/t-rtems m68k/t-mlibs"
- tm_file="${tm_file} m68k/m68k-none.h m68k/m68kelf.h dbxelf.h elfos.h m68k/m68kemb.h m68k/m68020-elf.h m68k/rtemself.h rtems.h newlib-stdint.h"
- tm_defines="${tm_defines} MOTOROLA=1"
- ;;
-mcore-*-elf)
- tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file} mcore/mcore-elf.h"
- tmake_file=mcore/t-mcore
- inhibit_libc=true
- ;;
-mep-*-*)
- tm_file="dbxelf.h elfos.h ${tm_file}"
- tmake_file=mep/t-mep
- c_target_objs="mep-pragma.o"
- cxx_target_objs="mep-pragma.o"
- if test -d "${srcdir}/../newlib/libc/include" &&
- test "x$with_headers" = x; then
- with_headers=yes
- fi
- use_gcc_stdint=wrap
- ;;
-microblaze*-linux*)
- case $target in
- microblazeel-*)
- tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=0"
- ;;
- microblaze-*)
- tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=4321"
- ;;
- esac
- tm_file="${tm_file} dbxelf.h gnu-user.h linux.h microblaze/linux.h"
- tm_file="${tm_file} glibc-stdint.h"
- c_target_objs="${c_target_objs} microblaze-c.o"
- cxx_target_objs="${cxx_target_objs} microblaze-c.o"
- tmake_file="${tmake_file} microblaze/t-microblaze"
- tmake_file="${tmake_file} microblaze/t-microblaze-linux"
- ;;
-microblaze*-*-rtems*)
- tm_file="${tm_file} dbxelf.h"
- tm_file="${tm_file} microblaze/rtems.h rtems.h newlib-stdint.h"
- c_target_objs="${c_target_objs} microblaze-c.o"
- cxx_target_objs="${cxx_target_objs} microblaze-c.o"
- tmake_file="${tmake_file} microblaze/t-microblaze"
- tmake_file="${tmake_file} t-rtems microblaze/t-rtems"
- ;;
-microblaze*-*-elf)
- case $target in
- microblazeel-*)
- tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=0"
- ;;
- microblaze-*)
- tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=4321"
- ;;
- esac
- tm_file="${tm_file} dbxelf.h newlib-stdint.h"
- c_target_objs="${c_target_objs} microblaze-c.o"
- cxx_target_objs="${cxx_target_objs} microblaze-c.o"
- tmake_file="${tmake_file} microblaze/t-microblaze"
- ;;
-mips*-*-netbsd*) # NetBSD/mips, either endian.
- target_cpu_default="MASK_ABICALLS"
- tm_file="elfos.h ${tm_file} mips/elf.h netbsd.h netbsd-elf.h mips/netbsd.h"
- extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
- ;;
-mips*-mti-linux*)
- tm_file="dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file} mips/gnu-user.h mips/gnu-user64.h mips/linux64.h mips/linux-common.h mips/mti-linux.h"
- tmake_file="${tmake_file} mips/t-mti-linux"
- tm_defines="${tm_defines} MIPS_ISA_DEFAULT=33 MIPS_ABI_DEFAULT=ABI_32"
- gnu_ld=yes
- gas=yes
- test x$with_llsc != x || with_llsc=yes
- ;;
-mips64*-*-linux* | mipsisa64*-*-linux*)
- tm_file="dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file} mips/gnu-user.h mips/gnu-user64.h mips/linux64.h mips/linux-common.h"
- tmake_file="${tmake_file} mips/t-linux64"
- case ${target} in
- *android*)
- # Default to ABI_64 for MIPS64 Android
- tm_defines="${tm_defines} MIPS_ABI_DEFAULT=ABI_64"
- ;;
- *)
- tm_defines="${tm_defines} MIPS_ABI_DEFAULT=ABI_N32"
- ;;
- esac
- case ${target} in
- mips64el-st-linux-gnu)
- tm_file="${tm_file} mips/st.h"
- tmake_file="${tmake_file} mips/t-st"
- ;;
- mips64octeon*-*-linux*)
- tm_defines="${tm_defines} MIPS_CPU_STRING_DEFAULT=\\\"octeon\\\""
- target_cpu_default=MASK_SOFT_FLOAT_ABI
- ;;
- mipsisa64r2*-*-linux*)
- tm_defines="${tm_defines} MIPS_ISA_DEFAULT=65"
- ;;
- esac
- 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 gnu-user.h linux.h glibc-stdint.h ${tm_file} mips/gnu-user.h mips/linux.h"
- if test x$enable_targets = xall; then
- tm_file="${tm_file} mips/gnu-user64.h mips/linux64.h"
- tmake_file="${tmake_file} mips/t-linux64"
- fi
- tm_file="${tm_file} mips/linux-common.h"
- case ${target} in
- mipsisa32r2*)
- tm_defines="${tm_defines} MIPS_ISA_DEFAULT=33"
- ;;
- mipsisa32*)
- tm_defines="${tm_defines} MIPS_ISA_DEFAULT=32"
- esac
- case ${target} in
- *android*)
- # Default to little-endian for MIPS Android
- # tm_defines="${tm_defines} TARGET_ENDIAN_DEFAULT=0"
- tmake_file="$tmake_file mips/t-linux-android"
- esac
- test x$with_llsc != x || with_llsc=yes
- ;;
-mips*-mti-elf*)
- tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elf.h mips/sde.h mips/mti-elf.h"
- tmake_file="mips/t-mti-elf"
- tm_defines="${tm_defines} MIPS_ISA_DEFAULT=33 MIPS_ABI_DEFAULT=ABI_32"
- ;;
-mips*-sde-elf*)
- tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elf.h mips/sde.h"
- tmake_file="mips/t-sde"
- extra_options="${extra_options} mips/sde.opt"
- case "${with_newlib}" in
- yes)
- # newlib / libgloss.
- ;;
- *)
- # MIPS toolkit libraries.
- tm_file="$tm_file mips/sdemtk.h"
- tmake_file="$tmake_file mips/t-sdemtk"
- case ${enable_threads} in
- "" | yes | mipssde)
- thread_file='mipssde'
- ;;
- esac
- ;;
- esac
- case ${target} in
- mipsisa32r2*)
- tm_defines="MIPS_ISA_DEFAULT=33 MIPS_ABI_DEFAULT=ABI_32"
- ;;
- mipsisa32*)
- tm_defines="MIPS_ISA_DEFAULT=32 MIPS_ABI_DEFAULT=ABI_32"
- ;;
- mipsisa64r2*)
- tm_defines="MIPS_ISA_DEFAULT=65 MIPS_ABI_DEFAULT=ABI_N32"
- ;;
- mipsisa64*)
- tm_defines="MIPS_ISA_DEFAULT=64 MIPS_ABI_DEFAULT=ABI_N32"
- ;;
- esac
- ;;
-mipsisa32-*-elf* | mipsisa32el-*-elf* | \
-mipsisa32r2-*-elf* | mipsisa32r2el-*-elf* | \
-mipsisa64-*-elf* | mipsisa64el-*-elf* | \
-mipsisa64r2-*-elf* | mipsisa64r2el-*-elf*)
- tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elf.h"
- tmake_file="mips/t-isa3264"
- case ${target} in
- mipsisa32r2*)
- tm_defines="${tm_defines} MIPS_ISA_DEFAULT=33"
- ;;
- mipsisa32*)
- tm_defines="${tm_defines} MIPS_ISA_DEFAULT=32"
- ;;
- mipsisa64r2*)
- tm_defines="${tm_defines} MIPS_ISA_DEFAULT=65"
- ;;
- mipsisa64*)
- tm_defines="${tm_defines} MIPS_ISA_DEFAULT=64"
- ;;
- esac
- case ${target} in
- mipsisa32*-*-elfoabi*)
- tm_defines="${tm_defines} MIPS_ABI_DEFAULT=ABI_32"
- tm_file="${tm_file} mips/elfoabi.h"
- ;;
- mipsisa64*-*-elfoabi*)
- tm_defines="${tm_defines} MIPS_ABI_DEFAULT=ABI_O64"
- tm_file="${tm_file} mips/elfoabi.h"
- ;;
- *-*-elf*)
- tm_defines="${tm_defines} MIPS_ABI_DEFAULT=ABI_EABI"
- ;;
- esac
- ;;
-mipsisa64sr71k-*-elf*)
- tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elf.h"
- 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"
- ;;
-mipsisa64sb1-*-elf* | mipsisa64sb1el-*-elf*)
- tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elf.h"
- tmake_file="mips/t-elf mips/t-sb1"
- target_cpu_default="MASK_64BIT|MASK_FLOAT64"
- tm_defines="${tm_defines} MIPS_ISA_DEFAULT=64 MIPS_CPU_STRING_DEFAULT=\\\"sb1\\\" MIPS_ABI_DEFAULT=ABI_O64"
- ;;
-mips-*-elf* | mipsel-*-elf*)
- tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elf.h"
- tmake_file="mips/t-elf"
- ;;
-mips64-*-elf* | mips64el-*-elf*)
- tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elf.h"
- tmake_file="mips/t-elf"
- target_cpu_default="MASK_64BIT|MASK_FLOAT64"
- tm_defines="${tm_defines} MIPS_ISA_DEFAULT=3 MIPS_ABI_DEFAULT=ABI_O64"
- ;;
-mips64vr-*-elf* | mips64vrel-*-elf*)
- tm_file="elfos.h newlib-stdint.h ${tm_file} mips/vr.h mips/elf.h"
- tmake_file=mips/t-vr
- tm_defines="${tm_defines} MIPS_ABI_DEFAULT=ABI_EABI"
- ;;
-mips64orion-*-elf* | mips64orionel-*-elf*)
- tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elforion.h mips/elf.h"
- tmake_file="mips/t-elf"
- target_cpu_default="MASK_64BIT|MASK_FLOAT64"
- tm_defines="${tm_defines} MIPS_ISA_DEFAULT=3 MIPS_ABI_DEFAULT=ABI_O64"
- ;;
-mips*-*-rtems*)
- tm_file="elfos.h newlib-stdint.h ${tm_file} mips/elf.h mips/rtems.h rtems.h"
- tmake_file="mips/t-elf t-rtems mips/t-rtems"
- ;;
-mips-wrs-vxworks)
- tm_file="elfos.h ${tm_file} mips/elf.h vx-common.h vxworks.h mips/vxworks.h"
- tmake_file="${tmake_file} mips/t-vxworks"
- ;;
-mipstx39-*-elf* | mipstx39el-*-elf*)
- tm_file="elfos.h newlib-stdint.h ${tm_file} mips/r3900.h mips/elf.h"
- tmake_file="mips/t-r3900"
- ;;
-mmix-knuth-mmixware)
- tm_file="${tm_file} newlib-stdint.h"
- need_64bit_hwint=yes
- use_gcc_stdint=wrap
- ;;
-mn10300-*-*)
- tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
- if test x$stabs = xyes
- then
- tm_file="${tm_file} dbx.h"
- fi
- use_collect2=no
- use_gcc_stdint=wrap
- ;;
-pdp11-*-*)
- tm_file="${tm_file} newlib-stdint.h"
- use_gcc_stdint=wrap
- ;;
-picochip-*)
- tm_file="${tm_file} newlib-stdint.h"
- use_gcc_stdint=wrap
- tmake_file="picochip/t-picochip t-pnt16-warn"
- ;;
-# port not yet contributed
-#powerpc-*-openbsd*)
-# tmake_file="${tmake_file} rs6000/t-fprules"
-# extra_headers=
-# ;;
-powerpc-*-darwin*)
- extra_options="${extra_options} rs6000/darwin.opt"
- case ${target} in
- *-darwin1[0-9]* | *-darwin[8-9]*)
- tmake_file="${tmake_file} rs6000/t-darwin8"
- tm_file="${tm_file} rs6000/darwin8.h"
- ;;
- *-darwin7*)
- tm_file="${tm_file} rs6000/darwin7.h"
- ;;
- *-darwin[0-6]*)
- ;;
- esac
- tmake_file="${tmake_file} t-slibgcc"
- extra_headers=altivec.h
- ;;
-powerpc64-*-darwin*)
- extra_options="${extra_options} ${cpu_type}/darwin.opt"
- tmake_file="${tmake_file} ${cpu_type}/t-darwin64 t-slibgcc"
- tm_file="${tm_file} ${cpu_type}/darwin8.h ${cpu_type}/darwin64.h"
- extra_headers=altivec.h
- ;;
-powerpc*-*-freebsd*)
- tm_file="${tm_file} dbxelf.h elfos.h ${fbsd_tm_file} rs6000/sysv4.h"
- extra_options="${extra_options} rs6000/sysv4.opt"
- tmake_file="rs6000/t-fprules rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm"
- case ${target} in
- powerpc64*)
- tm_file="${tm_file} rs6000/default64.h rs6000/freebsd64.h"
- tmake_file="${tmake_file} rs6000/t-freebsd64"
- extra_options="${extra_options} rs6000/linux64.opt"
- ;;
- *)
- tm_file="${tm_file} rs6000/freebsd.h"
- ;;
- esac
- ;;
-powerpc-*-netbsd*)
- tm_file="${tm_file} dbxelf.h elfos.h netbsd.h netbsd-elf.h freebsd-spec.h rs6000/sysv4.h rs6000/netbsd.h"
- extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
- tmake_file="${tmake_file} rs6000/t-netbsd"
- extra_options="${extra_options} rs6000/sysv4.opt"
- ;;
-powerpc-*-eabispe*)
- tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h rs6000/eabispe.h"
- extra_options="${extra_options} rs6000/sysv4.opt"
- tmake_file="rs6000/t-spe rs6000/t-ppccomm"
- use_gcc_stdint=wrap
- ;;
-powerpc-*-eabisimaltivec*)
- tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h rs6000/eabisim.h rs6000/eabialtivec.h"
- extra_options="${extra_options} rs6000/sysv4.opt"
- tmake_file="rs6000/t-fprules rs6000/t-ppcendian rs6000/t-ppccomm"
- use_gcc_stdint=wrap
- ;;
-powerpc-*-eabisim*)
- tm_file="${tm_file} dbxelf.h elfos.h usegas.h freebsd-spec.h newlib-stdint.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-ppcgas rs6000/t-ppccomm"
- use_gcc_stdint=wrap
- ;;
-powerpc-*-elf*)
- tm_file="${tm_file} dbxelf.h elfos.h usegas.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h"
- extra_options="${extra_options} rs6000/sysv4.opt"
- tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
- ;;
-powerpc-*-eabialtivec*)
- tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h rs6000/eabialtivec.h"
- extra_options="${extra_options} rs6000/sysv4.opt"
- tmake_file="rs6000/t-fprules rs6000/t-ppcendian rs6000/t-ppccomm"
- use_gcc_stdint=wrap
- ;;
-powerpc-xilinx-eabi*)
- tm_file="${tm_file} dbxelf.h elfos.h usegas.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/eabi.h rs6000/singlefp.h rs6000/xfpu.h rs6000/xilinx.h"
- extra_options="${extra_options} rs6000/sysv4.opt rs6000/xilinx.opt"
- tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm rs6000/t-xilinx"
- use_gcc_stdint=wrap
- ;;
-powerpc-*-eabi*)
- tm_file="${tm_file} dbxelf.h elfos.h usegas.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h"
- extra_options="${extra_options} rs6000/sysv4.opt"
- tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
- use_gcc_stdint=wrap
- ;;
-powerpc-*-rtems*)
- tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h rs6000/rtems.h rtems.h"
- extra_options="${extra_options} rs6000/sysv4.opt"
- tmake_file="rs6000/t-fprules rs6000/t-rtems t-rtems rs6000/t-ppccomm"
- ;;
-powerpc-*-linux* | powerpc64-*-linux*)
- tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h rs6000/sysv4.h"
- extra_options="${extra_options} rs6000/sysv4.opt"
- tmake_file="rs6000/t-fprules rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm"
- maybe_biarch=yes
- case ${target} in
- powerpc64-*-linux*spe* | powerpc64-*-linux*paired*)
- echo "*** Configuration ${target} not supported" 1>&2
- exit 1
- ;;
- powerpc-*-linux*spe* | powerpc-*-linux*paired*)
- maybe_biarch=
- ;;
- powerpc64-*-linux*)
- test x$with_cpu != x || cpu_is_64bit=yes
- maybe_biarch=always
- ;;
- esac
- case ${maybe_biarch}:${enable_targets}:${cpu_is_64bit} in
- always:* | yes:*powerpc64* | yes:all:* | yes:*:yes)
- if test x$cpu_is_64bit = xyes; then
- tm_file="${tm_file} rs6000/default64.h"
- fi
- tm_file="rs6000/biarch64.h ${tm_file} rs6000/linux64.h glibc-stdint.h"
- tmake_file="$tmake_file rs6000/t-linux64"
- extra_options="${extra_options} rs6000/linux64.opt"
- ;;
- *)
- tm_file="${tm_file} rs6000/linux.h glibc-stdint.h"
- tmake_file="$tmake_file rs6000/t-linux"
- ;;
- esac
- case ${target} in
- powerpc*-*-linux*ppc476*)
- tm_file="${tm_file} rs6000/476.h"
- extra_options="${extra_options} rs6000/476.opt" ;;
- powerpc*-*-linux*altivec*)
- tm_file="${tm_file} rs6000/linuxaltivec.h" ;;
- powerpc*-*-linux*spe*)
- tm_file="${tm_file} rs6000/linuxspe.h rs6000/e500.h" ;;
- powerpc*-*-linux*paired*)
- tm_file="${tm_file} rs6000/750cl.h" ;;
- esac
- if test x${enable_secureplt} = xyes; then
- tm_file="rs6000/secureplt.h ${tm_file}"
- fi
- ;;
-powerpc-wrs-vxworks|powerpc-wrs-vxworksae)
- tm_file="${tm_file} elfos.h freebsd-spec.h rs6000/sysv4.h"
- tmake_file="${tmake_file} rs6000/t-fprules rs6000/t-ppccomm rs6000/t-vxworks"
- extra_options="${extra_options} rs6000/sysv4.opt"
- extra_headers=ppc-asm.h
- case ${target} in
- *-vxworksae*)
- tm_file="${tm_file} vx-common.h vxworksae.h rs6000/vxworks.h rs6000/e500.h"
- tmake_file="${tmake_file} rs6000/t-vxworksae"
- ;;
- *-vxworks*)
- tm_file="${tm_file} vx-common.h vxworks.h rs6000/vxworks.h rs6000/e500.h"
- ;;
- esac
- ;;
-powerpc-*-lynxos*)
- xm_defines=POSIX
- tm_file="${tm_file} dbxelf.h elfos.h rs6000/sysv4.h rs6000/lynx.h lynx.h"
- tmake_file="t-lynx rs6000/t-lynx"
- extra_options="${extra_options} rs6000/sysv4.opt lynx.opt"
- thread_file=lynx
- gnu_ld=yes
- gas=yes
- ;;
-powerpcle-*-elf*)
- tm_file="${tm_file} dbxelf.h elfos.h usegas.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/sysv4le.h"
- tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
- extra_options="${extra_options} rs6000/sysv4.opt"
- ;;
-powerpcle-*-eabisim*)
- tm_file="${tm_file} dbxelf.h elfos.h usegas.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/sysv4le.h rs6000/eabi.h rs6000/e500.h rs6000/eabisim.h"
- tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
- extra_options="${extra_options} rs6000/sysv4.opt"
- use_gcc_stdint=wrap
- ;;
-powerpcle-*-eabi*)
- tm_file="${tm_file} dbxelf.h elfos.h usegas.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/sysv4le.h rs6000/eabi.h rs6000/e500.h"
- tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
- extra_options="${extra_options} rs6000/sysv4.opt"
- use_gcc_stdint=wrap
- ;;
-rs6000-ibm-aix4.[3456789]* | powerpc-ibm-aix4.[3456789]*)
- tm_file="rs6000/biarch64.h ${tm_file} rs6000/aix.h rs6000/aix43.h rs6000/xcoff.h rs6000/aix-stdint.h"
- tmake_file="rs6000/t-aix43 t-slibgcc"
- extra_options="${extra_options} rs6000/aix64.opt"
- use_collect2=yes
- thread_file='aix'
- use_gcc_stdint=provide
- extra_headers=
- ;;
-rs6000-ibm-aix5.1.* | powerpc-ibm-aix5.1.*)
- tm_file="rs6000/biarch64.h ${tm_file} rs6000/aix.h rs6000/aix51.h rs6000/xcoff.h rs6000/aix-stdint.h"
- extra_options="${extra_options} rs6000/aix64.opt"
- tmake_file="rs6000/t-aix43 t-slibgcc"
- use_collect2=yes
- thread_file='aix'
- use_gcc_stdint=wrap
- extra_headers=
- ;;
-rs6000-ibm-aix5.2.* | powerpc-ibm-aix5.2.*)
- tm_file="${tm_file} rs6000/aix.h rs6000/aix52.h rs6000/xcoff.h rs6000/aix-stdint.h"
- tmake_file="rs6000/t-aix52 t-slibgcc"
- extra_options="${extra_options} rs6000/aix64.opt"
- use_collect2=yes
- thread_file='aix'
- use_gcc_stdint=wrap
- extra_headers=
- ;;
-rs6000-ibm-aix5.3.* | powerpc-ibm-aix5.3.*)
- tm_file="${tm_file} rs6000/aix.h rs6000/aix53.h rs6000/xcoff.h rs6000/aix-stdint.h"
- tmake_file="rs6000/t-aix52 t-slibgcc"
- extra_options="${extra_options} rs6000/aix64.opt"
- use_collect2=yes
- thread_file='aix'
- use_gcc_stdint=wrap
- extra_headers=altivec.h
- ;;
-rs6000-ibm-aix[6789].* | powerpc-ibm-aix[6789].*)
- tm_file="${tm_file} rs6000/aix.h rs6000/aix61.h rs6000/xcoff.h rs6000/aix-stdint.h"
- tmake_file="rs6000/t-aix52 t-slibgcc"
- extra_options="${extra_options} rs6000/aix64.opt"
- use_collect2=yes
- thread_file='aix'
- use_gcc_stdint=wrap
- extra_headers=altivec.h
- ;;
-rl78-*-elf*)
- tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
- target_has_targetm_common=no
- c_target_objs="rl78-c.o"
- cxx_target_objs="rl78-c.o"
- tmake_file="${tmake_file} rl78/t-rl78"
- ;;
-rx-*-elf*)
- tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
- tmake_file="${tmake_file} rx/t-rx"
- ;;
-s390-*-linux*)
- default_gnu_indirect_function=yes
- tm_file="s390/s390.h dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h s390/linux.h"
- if test x$enable_targets = xall; then
- tmake_file="${tmake_file} s390/t-linux64"
- fi
- ;;
-s390x-*-linux*)
- default_gnu_indirect_function=yes
- tm_file="s390/s390x.h s390/s390.h dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h s390/linux.h"
- tm_p_file=s390/s390-protos.h
- md_file=s390/s390.md
- extra_modes=s390/s390-modes.def
- out_file=s390/s390.c
- tmake_file="${tmake_file} s390/t-linux64"
- ;;
-s390x-ibm-tpf*)
- tm_file="s390/s390x.h s390/s390.h dbxelf.h elfos.h s390/tpf.h"
- tm_p_file=s390/s390-protos.h
- md_file=s390/s390.md
- extra_modes=s390/s390-modes.def
- out_file=s390/s390.c
- thread_file='tpf'
- extra_options="${extra_options} s390/tpf.opt"
- ;;
-score-*-elf)
- gas=yes
- gnu_ld=yes
- tm_file="dbxelf.h elfos.h score/elf.h score/score.h newlib-stdint.h"
- ;;
-sh-*-elf* | sh[12346l]*-*-elf* | \
- sh-*-linux* | sh[2346lbe]*-*-linux* | \
- sh-*-netbsdelf* | shl*-*-netbsdelf* | sh5-*-netbsd* | sh5l*-*-netbsd* | \
- sh64-*-netbsd* | sh64l*-*-netbsd*)
- tmake_file="${tmake_file} sh/t-sh sh/t-elf"
- if test x${with_endian} = x; then
- case ${target} in
- sh[1234]*be-*-* | sh[1234]*eb-*-*) with_endian=big ;;
- shbe-*-* | sheb-*-*) with_endian=big,little ;;
- sh[1234]l* | sh[34]*-*-linux*) with_endian=little ;;
- shl* | sh64l* | sh*-*-linux* | \
- sh5l* | sh-superh-elf) with_endian=little,big ;;
- sh[1234]*-*-*) with_endian=big ;;
- *) with_endian=big,little ;;
- esac
- fi
- # TM_ENDIAN_CONFIG is used by t-sh to determine multilibs.
- # First word : the default endian.
- # Second word: the secondary endian (optional).
- case ${with_endian} in
- big) 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
- little*) tm_file="sh/little.h ${tm_file}" ;;
- esac
- tm_file="${tm_file} dbxelf.h elfos.h sh/elf.h"
- case ${target} in
- sh*-*-linux*) tmake_file="${tmake_file} sh/t-linux"
- tm_file="${tm_file} gnu-user.h linux.h glibc-stdint.h sh/linux.h" ;;
- sh*-*-netbsd*)
- tm_file="${tm_file} netbsd.h netbsd-elf.h sh/netbsd-elf.h"
- extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
-
- ;;
- sh*-superh-elf) if test x$with_libgloss != xno; then
- with_libgloss=yes
- tm_file="${tm_file} sh/newlib.h"
- fi
- tm_file="${tm_file} sh/embed-elf.h"
- tm_file="${tm_file} sh/superh.h"
- extra_options="${extra_options} sh/superh.opt" ;;
- *) if test x$with_newlib = xyes \
- && test x$with_libgloss = xyes; then
- tm_file="${tm_file} sh/newlib.h"
- fi
- tm_file="${tm_file} sh/embed-elf.h" ;;
- esac
- case ${target} in
- sh5*-*-netbsd*)
- # SHmedia, 32-bit ABI
- tmake_file="${tmake_file} sh/t-sh64"
- ;;
- sh64*-netbsd*)
- # SHmedia, 64-bit ABI
- tmake_file="${tmake_file} sh/t-sh64 sh/t-netbsd-sh5-64"
- ;;
- *-*-netbsd)
- ;;
- sh64*-*-linux*)
- tmake_file="${tmake_file} sh/t-sh64"
- tm_file="${tm_file} sh/sh64.h"
- extra_headers="shmedia.h ushmedia.h sshmedia.h"
- ;;
- sh64*)
- tmake_file="${tmake_file} sh/t-sh64"
- tm_file="${tm_file} sh/sh64.h"
- if test x$with_newlib = xyes; then
- tm_file="${tm_file} newlib-stdint.h"
- fi
- extra_headers="shmedia.h ushmedia.h sshmedia.h"
- ;;
- *-*-elf*)
- tm_file="${tm_file} newlib-stdint.h"
- ;;
- esac
- # sed el/eb endian suffixes away to avoid confusion with sh[23]e
- case `echo ${target} | sed 's/e[lb]-/-/'` in
- sh64*-*-netbsd*) sh_cpu_target=sh5-64media ;;
- sh64* | sh5*-*-netbsd*) sh_cpu_target=sh5-32media ;;
- sh4a_single_only*) sh_cpu_target=sh4a-single-only ;;
- sh4a_single*) sh_cpu_target=sh4a-single ;;
- sh4a_nofpu*) sh_cpu_target=sh4a-nofpu ;;
- sh4al) sh_cpu_target=sh4al ;;
- sh4a*) sh_cpu_target=sh4a ;;
- sh4_single_only*) sh_cpu_target=sh4-single-only ;;
- sh4_single*) sh_cpu_target=sh4-single ;;
- sh4_nofpu*) sh_cpu_target=sh4-nofpu ;;
- sh4* | sh-superh-*) sh_cpu_target=sh4 ;;
- sh3e*) sh_cpu_target=sh3e ;;
- sh*-*-netbsd* | sh3*) sh_cpu_target=sh3 ;;
- sh2a_single_only*) sh_cpu_target=sh2a-single-only ;;
- sh2a_single*) sh_cpu_target=sh2a-single ;;
- sh2a_nofpu*) sh_cpu_target=sh2a-nofpu ;;
- sh2a*) sh_cpu_target=sh2a ;;
- sh2e*) sh_cpu_target=sh2e ;;
- sh2*) sh_cpu_target=sh2 ;;
- *) sh_cpu_target=sh1 ;;
- esac
- # did the user say --without-fp ?
- if test x$with_fp = xno; then
- case ${sh_cpu_target} in
- sh5-*media) sh_cpu_target=${sh_cpu_target}-nofpu ;;
- sh4al | sh1) ;;
- sh4a* ) sh_cpu_target=sh4a-nofpu ;;
- sh4*) sh_cpu_target=sh4-nofpu ;;
- sh3*) sh_cpu_target=sh3 ;;
- sh2a*) sh_cpu_target=sh2a-nofpu ;;
- sh2*) sh_cpu_target=sh2 ;;
- *) echo --without-fp not available for $target: ignored
- esac
- tm_defines="$tm_defines STRICT_NOFPU=1"
- fi
- sh_cpu_default="`echo $with_cpu|sed s/^m/sh/|tr A-Z_ a-z-`"
- case $sh_cpu_default in
- sh5-64media-nofpu | sh5-64media | \
- sh5-32media-nofpu | sh5-32media | sh5-compact-nofpu | sh5-compact | \
- sh2a-single-only | sh2a-single | sh2a-nofpu | sh2a | \
- sh4a-single-only | sh4a-single | sh4a-nofpu | sh4a | sh4al | \
- sh4-single-only | sh4-single | sh4-nofpu | sh4 | sh4-300 | \
- sh3e | sh3 | sh2e | sh2 | sh1) ;;
- "") sh_cpu_default=${sh_cpu_target} ;;
- *) echo "with_cpu=$with_cpu not supported"; exit 1 ;;
- esac
- sh_multilibs=${with_multilib_list}
- if test "$sh_multilibs" = "default" ; then
- case ${target} in
- sh64-superh-linux* | \
- sh[1234]*) sh_multilibs=${sh_cpu_target} ;;
- sh64* | sh5*) sh_multilibs=m5-32media,m5-32media-nofpu,m5-compact,m5-compact-nofpu,m5-64media,m5-64media-nofpu ;;
- sh-superh-*) sh_multilibs=m4,m4-single,m4-single-only,m4-nofpu ;;
- sh*-*-linux*) sh_multilibs=m1,m2,m2a,m3e,m4 ;;
- sh*-*-netbsd*) sh_multilibs=m3,m3e,m4 ;;
- *) sh_multilibs=m1,m2,m2e,m4,m4-single,m4-single-only,m2a,m2a-single ;;
- esac
- if test x$with_fp = xno; then
- sh_multilibs="`echo $sh_multilibs|sed -e s/m4/sh4-nofpu/ -e s/,m4-[^,]*//g -e s/,m[23]e// -e s/m2a,m2a-single/m2a-nofpu/ -e s/m5-..m....,//g`"
- fi
- 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/`'\"'
- 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/^[Ss][Hh]/m/' -e 's/ [Ss][Hh]/ m/g' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ_ abcdefghijklmnopqrstuvwxyz-`
- for sh_multilib in ${sh_multilibs}; do
- case ${sh_multilib} in
- m1 | m2 | m2e | m3 | m3e | \
- m4 | m4-single | m4-single-only | m4-nofpu | m4-300 |\
- m4a | m4a-single | m4a-single-only | m4a-nofpu | m4al | \
- m2a | m2a-single | m2a-single-only | m2a-nofpu | \
- m5-64media | m5-64media-nofpu | \
- m5-32media | m5-32media-nofpu | \
- m5-compact | m5-compact-nofpu)
- # TM_MULTILIB_CONFIG is used by t-sh for the non-endian multilib definition
- # It is passed to MULTIILIB_OPTIONS verbatim.
- TM_MULTILIB_CONFIG="${TM_MULTILIB_CONFIG}/${sh_multilib}"
- tm_defines="$tm_defines SUPPORT_`echo $sh_multilib | sed 's/^m/sh/' | tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_`=1"
- ;;
- \!*) # TM_MULTILIB_EXCEPTIONS_CONFIG is used by t-sh
- # It is passed the MULTILIB_EXCEPTIONS verbatim.
- TM_MULTILIB_EXCEPTIONS_CONFIG="${TM_MULTILIB_EXCEPTIONS_CONFIG} `echo $sh_multilib | sed 's/^!//'`" ;;
- *)
- echo "with_multilib_list=${sh_multilib} not supported."
- exit 1
- ;;
- esac
- done
- TM_MULTILIB_CONFIG=`echo $TM_MULTILIB_CONFIG | sed 's:^/::'`
- if test x${enable_incomplete_targets} = xyes ; then
- tm_defines="$tm_defines SUPPORT_SH1=1 SUPPORT_SH2E=1 SUPPORT_SH4=1 SUPPORT_SH4_SINGLE=1 SUPPORT_SH2A=1 SUPPORT_SH2A_SINGLE=1 SUPPORT_SH5_32MEDIA=1 SUPPORT_SH5_32MEDIA_NOFPU=1 SUPPORT_SH5_64MEDIA=1 SUPPORT_SH5_64MEDIA_NOFPU=1"
- fi
- tm_file="$tm_file ./sysroot-suffix.h"
- tmake_file="$tmake_file t-sysroot-suffix"
- ;;
-sh-*-rtems*)
- tmake_file="sh/t-sh t-rtems sh/t-rtems"
- tm_file="${tm_file} dbxelf.h elfos.h sh/elf.h sh/embed-elf.h sh/rtemself.h rtems.h newlib-stdint.h"
- ;;
-sh-wrs-vxworks)
- tmake_file="$tmake_file sh/t-sh sh/t-vxworks"
- tm_file="${tm_file} elfos.h sh/elf.h sh/embed-elf.h vx-common.h vxworks.h sh/vxworks.h"
- ;;
-sparc-*-elf*)
- tm_file="${tm_file} dbxelf.h elfos.h newlib-stdint.h sparc/sysv4.h sparc/sp-elf.h"
- case ${target} in
- *-leon-*)
- tmake_file="sparc/t-sparc sparc/t-leon"
- ;;
- *-leon[3-9]*)
- tmake_file="sparc/t-sparc sparc/t-leon3"
- ;;
- *)
- tmake_file="sparc/t-sparc sparc/t-elf"
- ;;
- esac
- ;;
-sparc-*-rtems*)
- tm_file="${tm_file} dbxelf.h elfos.h sparc/sysv4.h sparc/sp-elf.h sparc/rtemself.h rtems.h newlib-stdint.h"
- tmake_file="sparc/t-sparc sparc/t-elf sparc/t-rtems t-rtems"
- ;;
-sparc-*-linux*)
- tm_file="${tm_file} dbxelf.h elfos.h sparc/sysv4.h gnu-user.h linux.h glibc-stdint.h sparc/tso.h"
- extra_options="${extra_options} sparc/long-double-switch.opt"
- case ${target} in
- *-leon-*)
- tmake_file="${tmake_file} sparc/t-sparc sparc/t-leon"
- ;;
- *-leon[3-9]*)
- tmake_file="${tmake_file} sparc/t-sparc sparc/t-leon3"
- ;;
- *)
- tmake_file="${tmake_file} sparc/t-sparc"
- ;;
- esac
- if test x$enable_targets = xall; then
- tm_file="sparc/biarch64.h ${tm_file} sparc/linux64.h"
- tmake_file="${tmake_file} sparc/t-linux64"
- else
- tm_file="${tm_file} sparc/linux.h"
- tmake_file="${tmake_file} sparc/t-linux"
- fi
- ;;
-sparc-*-netbsdelf*)
- tm_file="${tm_file} dbxelf.h elfos.h sparc/sysv4.h netbsd.h netbsd-elf.h sparc/netbsd-elf.h"
- extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
- extra_options="${extra_options} sparc/long-double-switch.opt"
- tmake_file="${tmake_file} sparc/t-sparc"
- ;;
-sparc*-*-solaris2*)
- tm_file="sparc/biarch64.h ${tm_file} ${sol2_tm_file} sol2-bi.h sparc/tso.h"
- case ${target} in
- sparc64-*-* | sparcv9-*-*)
- tm_file="sparc/default-64.h ${tm_file}"
- ;;
- *)
- test x$with_cpu != x || with_cpu=v9
- ;;
- esac
- tmake_file="${tmake_file} sparc/t-sparc sparc/t-sol2-64"
- ;;
-sparc-wrs-vxworks)
- tm_file="${tm_file} elfos.h sparc/sysv4.h vx-common.h vxworks.h sparc/vxworks.h"
- tmake_file="${tmake_file} sparc/t-sparc sparc/t-vxworks"
- ;;
-sparc64-*-elf*)
- tm_file="${tm_file} dbxelf.h elfos.h newlib-stdint.h sparc/sysv4.h sparc/sp64-elf.h"
- extra_options="${extra_options}"
- tmake_file="${tmake_file} sparc/t-sparc"
- ;;
-sparc64-*-rtems*)
- tm_file="${tm_file} dbxelf.h elfos.h newlib-stdint.h sparc/sysv4.h sparc/sp64-elf.h sparc/rtemself.h rtems.h"
- extra_options="${extra_options}"
- tmake_file="${tmake_file} sparc/t-sparc sparc/t-rtems-64 t-rtems"
- ;;
-sparc64-*-linux*)
- tm_file="sparc/biarch64.h ${tm_file} dbxelf.h elfos.h sparc/sysv4.h gnu-user.h linux.h glibc-stdint.h sparc/default-64.h sparc/linux64.h sparc/tso.h"
- extra_options="${extra_options} sparc/long-double-switch.opt"
- tmake_file="${tmake_file} sparc/t-sparc sparc/t-linux64"
- ;;
-sparc64-*-freebsd*|ultrasparc-*-freebsd*)
- tm_file="${tm_file} ${fbsd_tm_file} dbxelf.h elfos.h sparc/sysv4.h sparc/freebsd.h"
- extra_options="${extra_options} sparc/long-double-switch.opt"
- case "x$with_cpu" in
- xultrasparc) ;;
- x) with_cpu=ultrasparc ;;
- *) echo "$with_cpu not supported for freebsd target"; exit 1 ;;
- esac
- tmake_file="${tmake_file} sparc/t-sparc"
- ;;
-sparc64-*-netbsd*)
- tm_file="sparc/biarch64.h ${tm_file}"
- tm_file="${tm_file} dbxelf.h elfos.h sparc/sysv4.h netbsd.h netbsd-elf.h sparc/netbsd-elf.h"
- extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
- extra_options="${extra_options} sparc/long-double-switch.opt"
- tmake_file="${tmake_file} sparc/t-sparc sparc/t-netbsd64"
- ;;
-sparc64-*-openbsd*)
- tm_file="sparc/openbsd1-64.h ${tm_file} dbxelf.h elfos.h sparc/sysv4.h sparc/sp64-elf.h"
- tm_file="${tm_file} openbsd.h openbsd-stdint.h openbsd-libpthread.h sparc/openbsd64.h"
- extra_options="${extra_options} openbsd.opt"
- extra_options="${extra_options}"
- gas=yes gnu_ld=yes
- with_cpu=ultrasparc
- tmake_file="${tmake_file} sparc/t-sparc"
- ;;
-spu-*-elf*)
- tm_file="dbxelf.h elfos.h spu/spu-elf.h spu/spu.h newlib-stdint.h"
- tmake_file="spu/t-spu-elf"
- native_system_header_dir=/include
- extra_headers="spu_intrinsics.h spu_internals.h vmx2spu.h spu_mfcio.h vec_types.h spu_cache.h"
- extra_modes=spu/spu-modes.def
- c_target_objs="${c_target_objs} spu-c.o"
- cxx_target_objs="${cxx_target_objs} spu-c.o"
- ;;
-tic6x-*-elf)
- tm_file="elfos.h ${tm_file} c6x/elf-common.h c6x/elf.h"
- tm_file="${tm_file} dbxelf.h tm-dwarf2.h newlib-stdint.h"
- tmake_file="c6x/t-c6x c6x/t-c6x-elf"
- use_collect2=no
- ;;
-tic6x-*-uclinux)
- tm_file="elfos.h ${tm_file} gnu-user.h linux.h c6x/elf-common.h c6x/uclinux-elf.h"
- tm_file="${tm_file} dbxelf.h tm-dwarf2.h glibc-stdint.h"
- tm_file="${tm_file} ./sysroot-suffix.h"
- tmake_file="t-sysroot-suffix t-slibgcc"
- tmake_file="${tmake_file} c6x/t-c6x c6x/t-c6x-elf c6x/t-c6x-uclinux"
- use_collect2=no
- ;;
-tilegx-*-linux*)
- tm_file="elfos.h gnu-user.h linux.h glibc-stdint.h tilegx/linux.h ${tm_file}"
- tmake_file="${tmake_file} tilegx/t-tilegx"
- extra_objs="mul-tables.o"
- c_target_objs="${c_target_objs} tilegx-c.o"
- cxx_target_objs="${cxx_target_objs} tilegx-c.o"
- extra_headers="feedback.h"
- ;;
-tilepro-*-linux*)
- tm_file="elfos.h gnu-user.h linux.h glibc-stdint.h tilepro/linux.h ${tm_file}"
- tmake_file="${tmake_file} tilepro/t-tilepro"
- extra_objs="mul-tables.o"
- c_target_objs="${c_target_objs} tilepro-c.o"
- cxx_target_objs="${cxx_target_objs} tilepro-c.o"
- extra_headers="feedback.h"
- ;;
-v850-*-rtems*)
- target_cpu_default="TARGET_CPU_generic"
- tm_file="dbxelf.h elfos.h v850/v850.h"
- tm_file="${tm_file} rtems.h v850/rtems.h newlib-stdint.h"
- tmake_file="${tmake_file} v850/t-v850"
- tmake_file="${tmake_file} t-rtems v850/t-rtems"
- use_collect2=no
- c_target_objs="v850-c.o"
- cxx_target_objs="v850-c.o"
- ;;
-v850*-*-*)
- case ${target} in
- v850e3v5-*-*)
- target_cpu_default="TARGET_CPU_v850e3v5"
- ;;
- v850e2v3-*-*)
- target_cpu_default="TARGET_CPU_v850e2v3"
- ;;
- v850e2-*-*)
- target_cpu_default="TARGET_CPU_v850e2"
- ;;
- v850e1-*-* | v850es-*-*)
- target_cpu_default="TARGET_CPU_v850e1"
- ;;
- v850e-*-*)
- target_cpu_default="TARGET_CPU_v850e"
- ;;
- v850-*-*)
- target_cpu_default="TARGET_CPU_generic"
- ;;
- esac
- tm_file="dbxelf.h elfos.h newlib-stdint.h v850/v850.h"
- if test x$stabs = xyes
- then
- tm_file="${tm_file} dbx.h"
- fi
- use_collect2=no
- c_target_objs="v850-c.o"
- cxx_target_objs="v850-c.o"
- use_gcc_stdint=wrap
- ;;
-vax-*-linux*)
- tm_file="${tm_file} dbxelf.h elfos.h gnu-user.h linux.h vax/elf.h vax/linux.h"
- extra_options="${extra_options} vax/elf.opt"
- ;;
-vax-*-netbsdelf*)
- tm_file="${tm_file} elfos.h netbsd.h netbsd-elf.h vax/elf.h vax/netbsd-elf.h"
- extra_options="${extra_options} netbsd.opt netbsd-elf.opt vax/elf.opt"
- ;;
-vax-*-openbsd*)
- tm_file="vax/vax.h vax/openbsd1.h openbsd.h openbsd-stdint.h openbsd-pthread.h vax/openbsd.h"
- extra_options="${extra_options} openbsd.opt"
- use_collect2=yes
- ;;
-xstormy16-*-elf)
- # For historical reasons, the target files omit the 'x'.
- tm_file="dbxelf.h elfos.h newlib-stdint.h stormy16/stormy16.h"
- tm_p_file=stormy16/stormy16-protos.h
- md_file=stormy16/stormy16.md
- out_file=stormy16/stormy16.c
- extra_options=stormy16/stormy16.opt
- tmake_file="stormy16/t-stormy16"
- ;;
-xtensa*-*-elf*)
- tm_file="${tm_file} dbxelf.h elfos.h newlib-stdint.h xtensa/elf.h"
- extra_options="${extra_options} xtensa/elf.opt"
- ;;
-xtensa*-*-linux*)
- tm_file="${tm_file} dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h xtensa/linux.h"
- tmake_file="${tmake_file} xtensa/t-xtensa"
- ;;
-am33_2.0-*-linux*)
- tm_file="mn10300/mn10300.h dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h mn10300/linux.h"
- gas=yes gnu_ld=yes
- use_collect2=no
- ;;
-m32c-*-rtems*)
- tm_file="dbxelf.h elfos.h ${tm_file} m32c/rtems.h rtems.h newlib-stdint.h"
- tmake_file="${tmake_file} t-rtems"
- c_target_objs="m32c-pragma.o"
- cxx_target_objs="m32c-pragma.o"
- ;;
-m32c-*-elf*)
- tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
- c_target_objs="m32c-pragma.o"
- cxx_target_objs="m32c-pragma.o"
- ;;
-*)
- echo "*** Configuration ${target} not supported" 1>&2
- exit 1
- ;;
-esac
-
-case ${target} in
-i[34567]86-*-linux* | x86_64-*-linux*)
- tmake_file="${tmake_file} i386/t-pmm_malloc i386/t-i386"
- ;;
-i[34567]86-*-* | x86_64-*-*)
- tmake_file="${tmake_file} i386/t-gmm_malloc i386/t-i386"
- ;;
-powerpc*-*-* | rs6000-*-*)
- tm_file="${tm_file} rs6000/option-defaults.h"
-esac
-
-if [ "$target_has_targetcm" = "no" ]; then
- c_target_objs="$c_target_objs default-c.o"
- cxx_target_objs="$cxx_target_objs default-c.o"
-fi
-
-if [ "$common_out_file" = "" ]; then
- if [ "$target_has_targetm_common" = "yes" ]; then
- common_out_file="$cpu_type/$cpu_type-common.c"
- else
- common_out_file="default-common.c"
- fi
-fi
-
-# Support for --with-cpu and related options (and a few unrelated options,
-# too).
-case ${with_cpu} in
- yes | no)
- echo "--with-cpu must be passed a value" 1>&2
- exit 1
- ;;
-esac
-
-# Set arch and cpu from ${target} and ${target_noncanonical}. Set cpu
-# to generic if there is no processor scheduler model for the target.
-arch=
-cpu=
-arch_without_sse2=no
-arch_without_64bit=no
-case ${target} in
- i386-*-freebsd*)
- if test $fbsd_major -ge 6; then
- arch=i486
- else
- arch=i386
- fi
- cpu=generic
- arch_without_sse2=yes
- arch_without_64bit=yes
- ;;
- i386-*-*)
- arch=i386
- cpu=i386
- arch_without_sse2=yes
- arch_without_64bit=yes
- ;;
- i486-*-*)
- arch=i486
- cpu=i486
- arch_without_sse2=yes
- arch_without_64bit=yes
- ;;
- i586-*-*)
- arch_without_sse2=yes
- arch_without_64bit=yes
- case ${target_noncanonical} in
- k6_2-*)
- arch=k6-2
- cpu=k6-2
- ;;
- k6_3-*)
- arch=k6-3
- cpu=k6-3
- ;;
- k6-*)
- arch=k6
- cpu=k6
- ;;
- pentium_mmx-*|winchip_c6-*|winchip2-*|c3-*)
- arch=pentium-mmx
- cpu=pentium-mmx
- ;;
- *)
- arch=pentium
- cpu=pentium
- ;;
- esac
- ;;
- i686-*-* | i786-*-*)
- case ${target_noncanonical} in
- bdver3-*)
- arch=bdver3
- cpu=bdver3
- ;;
- bdver2-*)
- arch=bdver2
- cpu=bdver2
- ;;
- bdver1-*)
- arch=bdver1
- cpu=bdver1
- ;;
- btver1-*)
- arch=btver1
- cpu=btver1
- ;;
- btver2-*)
- arch=btver2
- cpu=btver2
- ;;
- amdfam10-*|barcelona-*)
- arch=amdfam10
- cpu=amdfam10
- ;;
- k8_sse3-*|opteron_sse3-*|athlon64_sse3-*)
- arch=k8-sse3
- cpu=k8-sse3
- ;;
- k8-*|opteron-*|athlon64-*|athlon_fx-*)
- arch=k8
- cpu=k8
- ;;
- athlon_xp-*|athlon_mp-*|athlon_4-*)
- arch=athlon-4
- cpu=athlon-4
- arch_without_sse2=yes
- arch_without_64bit=yes
- ;;
- athlon_tbird-*|athlon-*)
- arch=athlon
- cpu=athlon
- arch_without_sse2=yes
- ;;
- geode-*)
- arch=geode
- cpu=geode
- arch_without_sse2=yes
- ;;
- pentium2-*)
- arch=pentium2
- cpu=pentium2
- arch_without_sse2=yes
- ;;
- pentium3-*|pentium3m-*)
- arch=pentium3
- cpu=pentium3
- arch_without_sse2=yes
- ;;
- pentium4-*|pentium4m-*)
- arch=pentium4
- cpu=pentium4
- ;;
- prescott-*)
- arch=prescott
- cpu=prescott
- ;;
- nocona-*)
- arch=nocona
- cpu=nocona
- ;;
- atom-*)
- arch=atom
- cpu=atom
- ;;
- slm-*)
- arch=slm
- cpu=slm
- ;;
- core2-*)
- arch=core2
- cpu=core2
- ;;
- corei7-*)
- arch=corei7
- cpu=corei7
- ;;
- corei7_avx-*)
- arch=corei7-avx
- cpu=corei7-avx
- ;;
- pentium_m-*)
- arch=pentium-m
- cpu=pentium-m
- ;;
- pentiumpro-*)
- arch=pentiumpro
- cpu=pentiumpro
- arch_without_sse2=yes
- ;;
- *)
- arch=pentiumpro
- cpu=generic
- arch_without_sse2=yes
- arch_without_64bit=yes
- ;;
- esac
- ;;
- x86_64-*-*)
- case ${target_noncanonical} in
- bdver3-*)
- arch=bdver3
- cpu=bdver3
- ;;
- bdver2-*)
- arch=bdver2
- cpu=bdver2
- ;;
- bdver1-*)
- arch=bdver1
- cpu=bdver1
- ;;
- btver1-*)
- arch=btver1
- cpu=btver1
- ;;
- btver2-*)
- arch=btver2
- cpu=btver2
- ;;
- amdfam10-*|barcelona-*)
- arch=amdfam10
- cpu=amdfam10
- ;;
- k8_sse3-*|opteron_sse3-*|athlon64_sse3-*)
- arch=k8-sse3
- cpu=k8-sse3
- ;;
- k8-*|opteron-*|athlon_64-*)
- arch=k8
- cpu=k8
- ;;
- nocona-*)
- arch=nocona
- cpu=nocona
- ;;
- atom-*)
- arch=atom
- cpu=atom
- ;;
- slm-*)
- arch=slm
- cpu=slm
- ;;
- core2-*)
- arch=core2
- cpu=core2
- ;;
- corei7-*)
- arch=corei7
- cpu=corei7
- ;;
- *)
- arch=x86-64
- cpu=generic
- ;;
- esac
- ;;
-esac
-
-# If there is no $with_cpu option, try to infer one from ${target}.
-# This block sets nothing except for with_cpu.
-if test x$with_cpu = x ; then
- case ${target} in
- i[34567]86-*-*|x86_64-*-*)
- with_cpu=$cpu
- ;;
- alphaev6[78]*-*-*)
- with_cpu=ev67
- ;;
- alphaev6*-*-*)
- with_cpu=ev6
- ;;
- alphapca56*-*-*)
- with_cpu=pca56
- ;;
- alphaev56*-*-*)
- with_cpu=ev56
- ;;
- alphaev5*-*-*)
- with_cpu=ev5
- ;;
- frv-*-*linux* | frv400-*-*linux*)
- with_cpu=fr400
- ;;
- frv550-*-*linux*)
- with_cpu=fr550
- ;;
- m68k*-*-*)
- case "$with_arch" in
- "cf")
- with_cpu=${default_cf_cpu}
- ;;
- "" | "m68k")
- with_cpu=m${default_m68k_cpu}
- ;;
- esac
- ;;
- mips*-*-vxworks)
- with_arch=mips2
- ;;
- powerpc*-*-*spe*)
- if test x$enable_e500_double = xyes; then
- with_cpu=8548
- else
- with_cpu=8540
- fi
- ;;
- sparc-leon*-*)
- with_cpu=v8;
- ;;
- sparc*-*-*)
- with_cpu="`echo ${target} | sed 's/-.*$//'`"
- ;;
- esac
-
- # Avoid overriding --with-cpu-32 and --with-cpu-64 values.
- case ${target} in
- i[34567]86-*-*|x86_64-*-*)
- if test x$with_cpu_32 != x || test x$with_cpu_64 != x; then
- if test x$with_cpu_32 = x; then
- with_cpu_32=$with_cpu
- fi
- if test x$with_cpu_64 = x; then
- with_cpu_64=$with_cpu
- fi
- with_cpu=
- fi
- ;;
- esac
-fi
-
-# Support for --with-arch and related options (and a few unrelated options,
-# too).
-case ${with_arch} in
- yes | no)
- echo "--with-arch must be passed a value" 1>&2
- exit 1
- ;;
-esac
-
-# If there is no $with_arch option, try to infer one from ${target}.
-# This block sets nothing except for with_arch.
-if test x$with_arch = x ; then
- case ${target} in
- i[34567]86-*-darwin*|x86_64-*-darwin*)
- # Default arch is set via TARGET_SUBTARGET32_ISA_DEFAULT
- # and TARGET_SUBTARGET64_ISA_DEFAULT in config/i386/darwin.h.
- ;;
- i[34567]86-*-*)
- # --with-fpmath sets the default ISA to SSE2, which is the same
- # ISA supported by Pentium 4.
- if test x$with_fpmath = x || test $arch_without_sse2 = no; then
- with_arch=$arch
- else
- with_arch=pentium4
- fi
- ;;
- x86_64-*-*)
- with_arch=$arch
- ;;
- esac
-
- # Avoid overriding --with-arch-32 and --with-arch-64 values.
- case ${target} in
- i[34567]86-*-darwin*|x86_64-*-darwin*)
- # Default arch is set via TARGET_SUBTARGET32_ISA_DEFAULT
- # and TARGET_SUBTARGET64_ISA_DEFAULT in config/i386/darwin.h.
- ;;
- i[34567]86-*-*|x86_64-*-*)
- if test x$with_arch_32 != x || test x$with_arch_64 != x; then
- if test x$with_arch_32 = x; then
- with_arch_32=$with_arch
- fi
- if test x$with_arch_64 = x; then
- if test $arch_without_64bit = yes; then
- # Set the default 64bit arch to x86-64 if the default arch
- # doesn't support 64bit.
- with_arch_64=x86-64
- else
- with_arch_64=$with_arch
- fi
- fi
- with_arch=
- elif test $arch_without_64bit$need_64bit_isa = yesyes; then
- # Set the default 64bit arch to x86-64 if the default arch
- # doesn't support 64bit and we need 64bit ISA.
- with_arch_32=$with_arch
- with_arch_64=x86-64
- with_arch=
- fi
- ;;
- esac
-fi
-
-# Support --with-fpmath.
-if test x$with_fpmath != x; then
- case ${target} in
- i[34567]86-*-* | x86_64-*-*)
- case ${with_fpmath} in
- avx)
- tm_file="${tm_file} i386/avxmath.h"
- ;;
- sse)
- tm_file="${tm_file} i386/ssemath.h"
- ;;
- *)
- echo "Invalid --with-fpmath=$with_fpmath" 1>&2
- exit 1
- ;;
- esac
- ;;
- *)
- echo "--with-fpmath isn't supported for $target." 1>&2
- exit 1
- ;;
- esac
-fi
-
-# Similarly for --with-schedule.
-if test x$with_schedule = x; then
- case ${target} in
- hppa1*)
- # Override default PA8000 scheduling model.
- with_schedule=7100LC
- ;;
- esac
-fi
-
-# Validate and mark as valid any --with options supported
-# by this target. In order to use a particular --with option
-# you must list it in supported_defaults; validating the value
-# is optional. This case statement should set nothing besides
-# supported_defaults.
-
-supported_defaults=
-case "${target}" in
- aarch64*-*-*)
- supported_defaults="cpu arch"
- for which in cpu arch; do
-
- eval "val=\$with_$which"
- base_val=`echo $val | sed -e 's/\+.*//'`
- ext_val=`echo $val | sed -e 's/[a-z0-9\-]\+//'`
-
- if [ $which = arch ]; then
- def=aarch64-arches.def
- pattern=AARCH64_ARCH
- else
- def=aarch64-cores.def
- pattern=AARCH64_CORE
- fi
-
- ext_mask=AARCH64_CPU_DEFAULT_FLAGS
-
- # Find the base CPU or ARCH id in aarch64-cores.def or
- # aarch64-arches.def
- if [ x"$base_val" = x ] \
- || grep "^$pattern(\"$base_val\"," \
- ${srcdir}/config/aarch64/$def \
- > /dev/null; then
-
- if [ $which = arch ]; then
- base_id=`grep "^$pattern(\"$base_val\"," \
- ${srcdir}/config/aarch64/$def | \
- sed -e 's/^[^,]*,[ ]*//' | \
- sed -e 's/,.*$//'`
- else
- base_id=`grep "^$pattern(\"$base_val\"," \
- ${srcdir}/config/aarch64/$def | \
- sed -e 's/^[^,]*,[ ]*//' | \
- sed -e 's/,.*$//'`
- fi
-
- while [ x"$ext_val" != x ]
- do
- ext_val=`echo $ext_val | sed -e 's/\+//'`
- ext=`echo $ext_val | sed -e 's/\+.*//'`
- base_ext=`echo $ext | sed -e 's/^no//'`
-
- if [ x"$base_ext" = x ] \
- || grep "^AARCH64_OPT_EXTENSION(\"$base_ext\"," \
- ${srcdir}/config/aarch64/aarch64-option-extensions.def \
- > /dev/null; then
-
- ext_on=`grep "^AARCH64_OPT_EXTENSION(\"$base_ext\"," \
- ${srcdir}/config/aarch64/aarch64-option-extensions.def | \
- sed -e 's/^[^,]*,[ ]*//' | \
- sed -e 's/,.*$//'`
- ext_off=`grep "^AARCH64_OPT_EXTENSION(\"$base_ext\"," \
- ${srcdir}/config/aarch64/aarch64-option-extensions.def | \
- sed -e 's/^[^,]*,[ ]*[^,]*,[ ]*//' | \
- sed -e 's/,.*$//' | \
- sed -e 's/).*$//'`
-
- if [ $ext = $base_ext ]; then
- # Adding extension
- ext_mask="("$ext_mask") | ("$ext_on")"
- else
- # Removing extension
- ext_mask="("$ext_mask") & ~("$ext_off")"
- fi
-
- true
- else
- echo "Unknown extension used in --with-$which=$val" 1>&2
- exit 1
- fi
- ext_val=`echo $ext_val | sed -e 's/[a-z0-9]\+//'`
- done
-
- ext_mask="(("$ext_mask") << 6)"
- if [ x"$base_id" != x ]; then
- target_cpu_cname="TARGET_CPU_$base_id | $ext_mask"
- fi
- true
- else
- echo "Unknown $which used in --with-$which=$val" 1>&2
- exit 1
- fi
- done
- ;;
-
- alpha*-*-*)
- supported_defaults="cpu tune"
- for which in cpu tune; do
- eval "val=\$with_$which"
- case "$val" in
- "" \
- | ev4 | ev45 | 21064 | ev5 | 21164 | ev56 | 21164a \
- | pca56 | 21164PC | 21164pc | ev6 | 21264 | ev67 \
- | 21264a)
- ;;
- *)
- echo "Unknown CPU used in --with-$which=$val" 1>&2
- exit 1
- ;;
- esac
- done
- ;;
-
- arm*-*-*)
- supported_defaults="arch cpu float tune fpu abi mode tls"
- for which in cpu tune; do
- # See if it matches any of the entries in arm-cores.def
- eval "val=\$with_$which"
- if [ x"$val" = x ] \
- || grep "^ARM_CORE(\"$val\"," \
- ${srcdir}/config/arm/arm-cores.def \
- > /dev/null; then
- # Ok
- new_val=`grep "^ARM_CORE(\"$val\"," \
- ${srcdir}/config/arm/arm-cores.def | \
- sed -e 's/^[^,]*,[ ]*//' | \
- sed -e 's/,.*$//'`
- eval "target_${which}_cname=$new_val"
- echo "For $val real value is $new_val"
- true
- else
- echo "Unknown CPU used in --with-$which=$val" 1>&2
- exit 1
- fi
- done
-
- case "$with_arch" in
- "" \
- | armv[23456] | armv2a | armv3m | armv4t | armv5t \
- | armv5te | armv6j |armv6k | armv6z | armv6zk | armv6-m \
- | armv7 | armv7-a | armv7-r | armv7-m | armv8-a \
- | iwmmxt | ep9312)
- # OK
- ;;
- *)
- echo "Unknown arch used in --with-arch=$with_arch" 1>&2
- exit 1
- ;;
- esac
-
- case "$with_float" in
- "" \
- | soft | hard | softfp)
- # OK
- ;;
- *)
- echo "Unknown floating point type used in --with-float=$with_float" 1>&2
- exit 1
- ;;
- esac
-
- case "$with_fpu" in
- "" \
- | vfp | vfp3 | vfpv3 \
- | vfpv3-fp16 | vfpv3-d16 | vfpv3-d16-fp16 | vfpv3xd \
- | vfpv3xd-fp16 | neon | neon-fp16 | vfpv4 | vfpv4-d16 \
- | fpv4-sp-d16 | neon-vfpv4 | fp-arm-v8 | neon-fp-armv8 \
- | crypto-neon-fp-armv8)
- # OK
- ;;
- *)
- echo "Unknown fpu used in --with-fpu=$with_fpu" 2>&1
- exit 1
- ;;
- esac
-
- case "$with_abi" in
- "" \
- | apcs-gnu | atpcs | aapcs | iwmmxt | aapcs-linux )
- #OK
- ;;
- *)
- echo "Unknown ABI used in --with-abi=$with_abi"
- exit 1
- ;;
- esac
-
- case "$with_mode" in
- "" \
- | arm | thumb )
- #OK
- ;;
- *)
- echo "Unknown mode used in --with-mode=$with_mode"
- exit 1
- ;;
- esac
-
- case "$with_tls" in
- "" \
- | gnu | gnu2)
- # OK
- ;;
- *)
- echo "Unknown TLS method used in --with-tls=$with_tls" 1>&2
- exit 1
- ;;
- esac
-
- if test "x$with_arch" != x && test "x$with_cpu" != x; then
- echo "Warning: --with-arch overrides --with-cpu=$with_cpu" 1>&2
- fi
- ;;
-
- fr*-*-*linux*)
- supported_defaults=cpu
- case "$with_cpu" in
- fr400) ;;
- fr550) ;;
- *)
- echo "Unknown cpu used in --with-cpu=$with_cpu" 1>&2
- exit 1
- ;;
- esac
- ;;
-
- fido-*-* | m68k*-*-*)
- supported_defaults="arch cpu"
- case "$with_arch" in
- "" | "m68k"| "cf")
- m68k_arch_family="$with_arch"
- ;;
- *)
- echo "Invalid --with-arch=$with_arch" 1>&2
- exit 1
- ;;
- esac
-
- # We always have a $with_cpu setting here.
- case "$with_cpu" in
- "m68000" | "m68010" | "m68020" | "m68030" | "m68040" | "m68060")
- m68k_cpu_ident=$with_cpu
- ;;
- "m68020-40")
- m68k_cpu_ident=m68020
- tm_defines="$tm_defines M68K_DEFAULT_TUNE=u68020_40"
- ;;
- "m68020-60")
- m68k_cpu_ident=m68020
- tm_defines="$tm_defines M68K_DEFAULT_TUNE=u68020_60"
- ;;
- *)
- # We need the C identifier rather than the string.
- m68k_cpu_ident=`awk -v arg="\"$with_cpu\"" \
- 'BEGIN { FS="[ \t]*[,()][ \t]*" }; \
- $1 == "M68K_DEVICE" && $2 == arg { print $3 }' \
- ${srcdir}/config/m68k/m68k-devices.def`
- if [ x"$m68k_cpu_ident" = x ] ; then
- echo "Unknown CPU used in --with-cpu=$with_cpu" 1>&2
- exit 1
- fi
- with_cpu="mcpu=$with_cpu"
- ;;
- esac
- ;;
-
- hppa*-*-*)
- supported_defaults="arch schedule"
-
- case "$with_arch" in
- "" | 1.0 | 1.1 | 2.0)
- # OK
- ;;
- *)
- echo "Unknown architecture used in --with-arch=$with_arch" 1>&2
- exit 1
- ;;
- esac
-
- case "$with_schedule" in
- "" | 700 | 7100 | 7100LC | 7200 | 7300 | 8000)
- # OK
- ;;
- *)
- echo "Unknown processor used in --with-schedule=$with_schedule." 1>&2
- exit 1
- ;;
- esac
- ;;
-
- i[34567]86-*-* | x86_64-*-*)
- supported_defaults="abi arch arch_32 arch_64 cpu cpu_32 cpu_64 tune tune_32 tune_64"
- for which in arch arch_32 arch_64 cpu cpu_32 cpu_64 tune tune_32 tune_64; do
- eval "val=\$with_$which"
- case ${val} in
- i386 | i486 \
- | i586 | pentium | pentium-mmx | winchip-c6 | winchip2 \
- | c3 | c3-2 | i686 | pentiumpro | pentium2 | pentium3 \
- | pentium4 | k6 | k6-2 | k6-3 | athlon | athlon-tbird \
- | athlon-4 | athlon-xp | athlon-mp | geode \
- | prescott | pentium-m | pentium4m | pentium3m)
- case "${target}" in
- x86_64-*-*)
- case "x$which" in
- *_32)
- ;;
- *)
- echo "CPU given in --with-$which=$val doesn't support 64bit mode." 1>&2
- exit 1
- ;;
- esac
- ;;
- esac
- # OK
- ;;
- "" | x86-64 | generic | native \
- | k8 | k8-sse3 | athlon64 | athlon64-sse3 | opteron \
- | opteron-sse3 | athlon-fx | bdver3 | bdver2 | bdver1 | btver2 \
- | btver1 | amdfam10 | barcelona | nocona | core2 | corei7 \
- | corei7-avx | core-avx-i | core-avx2 | atom | slm)
- # OK
- ;;
- *)
- echo "Unknown CPU given in --with-$which=$val." 1>&2
- exit 1
- ;;
- esac
- done
- ;;
-
- mips*-*-*)
- supported_defaults="abi arch arch_32 arch_64 float tune tune_32 tune_64 divide llsc mips-plt synci"
-
- case ${with_float} in
- "" | soft | hard)
- # OK
- ;;
- *)
- echo "Unknown floating point type used in --with-float=$with_float" 1>&2
- exit 1
- ;;
- esac
-
- case ${with_abi} in
- "" | 32 | o64 | n32 | 64 | eabi)
- # OK
- ;;
- *)
- echo "Unknown ABI used in --with-abi=$with_abi" 1>&2
- exit 1
- ;;
- esac
-
- case ${with_divide} in
- "" | breaks | traps)
- # OK
- ;;
- *)
- echo "Unknown division check type use in --with-divide=$with_divide" 1>&2
- exit 1
- ;;
- esac
-
- case ${with_llsc} in
- yes)
- with_llsc=llsc
- ;;
- no)
- with_llsc="no-llsc"
- ;;
- "")
- # OK
- ;;
- *)
- echo "Unknown llsc type used in --with-llsc" 1>&2
- exit 1
- ;;
- esac
-
- case ${with_mips_plt} in
- yes)
- with_mips_plt=plt
- ;;
- no)
- with_mips_plt=no-plt
- ;;
- "")
- ;;
- *)
- echo "Unknown --with-mips-plt argument: $with_mips_plt" 1>&2
- exit 1
- ;;
- esac
-
- case ${with_synci} in
- yes)
- with_synci=synci
- ;;
- no)
- with_synci=no-synci
- ;;
- "")
- ;;
- *)
- echo "Unknown synci type used in --with-synci" 1>&2
- exit 1
- ;;
- esac
- ;;
-
- powerpc*-*-* | rs6000-*-*)
- supported_defaults="cpu cpu_32 cpu_64 float tune tune_32 tune_64"
-
- for which in cpu cpu_32 cpu_64 tune tune_32 tune_64; do
- eval "val=\$with_$which"
- case ${val} in
- default32 | default64)
- case $which in
- cpu | tune)
- ;;
- *)
- echo "$val only valid for --with-cpu and --with-tune." 1>&2
- exit 1
- ;;
- esac
- with_which="with_$which"
- eval $with_which=
- ;;
- 405cr)
- tm_defines="${tm_defines} CONFIG_PPC405CR"
- eval "with_$which=405"
- ;;
- "" | common \
- | power | power[2345678] | power6x | powerpc | powerpc64 \
- | rios | rios1 | rios2 | rsc | rsc1 | rs64a \
- | 401 | 403 | 405 | 405fp | 440 | 440fp | 464 | 464fp \
- | 476 | 476fp | 505 | 601 | 602 | 603 | 603e | ec603e \
- | 604 | 604e | 620 | 630 | 740 | 750 | 7400 | 7450 \
- | a2 | e300c[23] | 854[08] | e500mc | e500mc64 | e5500 | e6500 \
- | titan | 801 | 821 | 823 | 860 | 970 | G3 | G4 | G5 | cell)
- # OK
- ;;
- *)
- echo "Unknown cpu used in --with-$which=$val." 1>&2
- exit 1
- ;;
- esac
- done
- ;;
-
- s390*-*-*)
- supported_defaults="arch mode tune"
-
- for which in arch tune; do
- eval "val=\$with_$which"
- case ${val} in
- "" | g5 | g6 | z900 | z990 | z9-109 | z9-ec | z10 | z196 | zEC12)
- # OK
- ;;
- *)
- echo "Unknown cpu used in --with-$which=$val." 1>&2
- exit 1
- ;;
- esac
- done
-
- case ${with_mode} in
- "" | esa | zarch)
- # OK
- ;;
- *)
- echo "Unknown architecture mode used in --with-mode=$with_mode." 1>&2
- exit 1
- ;;
- esac
- ;;
-
- sh[123456ble]-*-* | sh-*-*)
- supported_defaults="cpu"
- case "`echo $with_cpu | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ_ abcdefghijklmnopqrstuvwxyz- | sed s/sh/m/`" in
- "" | m1 | m2 | m2e | m3 | m3e | m4 | m4-single | m4-single-only | m4-nofpu )
- # OK
- ;;
- m2a | m2a-single | m2a-single-only | m2a-nofpu)
- ;;
- m4a | m4a-single | m4a-single-only | m4a-nofpu | m4al)
- ;;
- *)
- echo "Unknown CPU used in --with-cpu=$with_cpu, known values:" 1>&2
- echo "m1 m2 m2e m3 m3e m4 m4-single m4-single-only m4-nofpu" 1>&2
- echo "m4a m4a-single m4a-single-only m4a-nofpu m4al" 1>&2
- echo "m2a m2a-single m2a-single-only m2a-nofpu" 1>&2
- exit 1
- ;;
- esac
- ;;
- sparc*-*-*)
- supported_defaults="cpu float tune"
-
- for which in cpu tune; do
- eval "val=\$with_$which"
- case ${val} in
- "" | sparc | sparcv9 | sparc64 \
- | v7 | cypress \
- | v8 | supersparc | hypersparc | leon \
- | sparclite | f930 | f934 | sparclite86x \
- | sparclet | tsc701 \
- | v9 | ultrasparc | ultrasparc3 | niagara | niagara2 \
- | niagara3 | niagara4)
- # OK
- ;;
- *)
- echo "Unknown cpu used in --with-$which=$val" 1>&2
- exit 1
- ;;
- esac
- done
-
- case ${with_float} in
- "" | soft | hard)
- # OK
- ;;
- *)
- echo "Unknown floating point type used in --with-float=$with_float" 1>&2
- exit 1
- ;;
- esac
- ;;
-
- spu-*-*)
- supported_defaults="arch tune"
-
- for which in arch tune; do
- eval "val=\$with_$which"
- case ${val} in
- "" | cell | celledp)
- # OK
- ;;
- *)
- echo "Unknown cpu used in --with-$which=$val." 1>&2
- exit 1
- ;;
- esac
- done
- ;;
-
- tic6x-*-*)
- supported_defaults="arch"
-
- case ${with_arch} in
- "" | c62x | c64x | c64x+ | c67x | c67x+ | c674x)
- # OK
- ;;
- *)
- echo "Unknown arch used in --with-arch=$with_arch." 1>&2
- exit 1
- ;;
- esac
- ;;
-
- v850*-*-*)
- supported_defaults=cpu
- case ${with_cpu} in
- "" | v850e | v850e1 | v850e2 | v850es | v850e2v3 | v850e3v5)
- # OK
- ;;
- *)
- echo "Unknown cpu used in --with-cpu=$with_cpu" 1>&2
- exit 1
- ;;
- esac
- ;;
-esac
-
-# Set some miscellaneous flags for particular targets.
-target_cpu_default2=
-case ${target} in
- aarch64*-*-*)
- if test x$target_cpu_cname = x
- then
- target_cpu_default2=TARGET_CPU_generic
- else
- target_cpu_default2=$target_cpu_cname
- fi
- ;;
-
- arm*-*-*)
- if test x$target_cpu_cname = x
- then
- target_cpu_default2=TARGET_CPU_generic
- else
- target_cpu_default2=TARGET_CPU_$target_cpu_cname
- fi
- ;;
-
- hppa*-*-*)
- target_cpu_default2="MASK_BIG_SWITCH"
- if test x$gas = xyes
- then
- target_cpu_default2="${target_cpu_default2}|MASK_GAS|MASK_JUMP_IN_DELAY"
- fi
- ;;
-
- fido*-*-* | m68k*-*-*)
- target_cpu_default2=$m68k_cpu_ident
- tmake_file="m68k/t-opts $tmake_file"
- if [ x"$m68k_arch_family" != x ]; then
- tmake_file="m68k/t-$m68k_arch_family $tmake_file"
- fi
- ;;
-
- i[34567]86-*-darwin* | x86_64-*-darwin*)
- ;;
- i[34567]86-*-linux* | x86_64-*-linux*)
- tmake_file="$tmake_file i386/t-linux"
- ;;
- i[34567]86-*-kfreebsd*-gnu | x86_64-*-kfreebsd*-gnu)
- tmake_file="$tmake_file i386/t-kfreebsd"
- ;;
- i[34567]86-*-gnu*)
- tmake_file="$tmake_file i386/t-gnu"
- ;;
- i[34567]86-*-solaris2* | x86_64-*-solaris2.1[0-9]*)
- ;;
- i[34567]86-*-cygwin* | i[34567]86-*-mingw* | x86_64-*-mingw*)
- ;;
- i[34567]86-*-freebsd* | x86_64-*-freebsd*)
- ;;
- ia64*-*-linux*)
- ;;
-
- mips*-*-*)
- if test x$gnu_ld = xyes
- then
- target_cpu_default2="MASK_SPLIT_ADDRESSES"
- fi
- case ${target} in
- mips*el-*-*)
- tm_defines="TARGET_ENDIAN_DEFAULT=0 $tm_defines"
- ;;
- esac
- tmake_file="mips/t-mips $tmake_file"
- ;;
-
- powerpc*-*-* | rs6000-*-*)
- # FIXME: The PowerPC port uses the value set at compile time,
- # although it's only cosmetic.
- if test "x$with_cpu" != x
- then
- target_cpu_default2="\\\"$with_cpu\\\""
- fi
- out_file=rs6000/rs6000.c
- c_target_objs="${c_target_objs} rs6000-c.o"
- cxx_target_objs="${cxx_target_objs} rs6000-c.o"
- tmake_file="rs6000/t-rs6000 ${tmake_file}"
- ;;
-
- sh[123456ble]*-*-* | sh-*-*)
- c_target_objs="${c_target_objs} sh-c.o"
- cxx_target_objs="${cxx_target_objs} sh-c.o"
- ;;
-
- sparc-leon*-*)
- if test x$with_tune = x ; then
- with_tune=leon;
- fi
-
- # The SPARC port checks this value at compile-time.
- target_cpu_default2="TARGET_CPU_$with_cpu"
- ;;
-
- sparc*-*-*)
- # Some standard aliases.
- case x$with_cpu in
- xsparc)
- with_cpu=v7
- ;;
- xsparcv9 | xsparc64)
- with_cpu=v9
- ;;
- esac
-
- # The SPARC port checks this value at compile-time.
- target_cpu_default2="TARGET_CPU_$with_cpu"
- ;;
-
- v850*-*-*)
- case "x$with_cpu" in
- x)
- ;;
- xv850e | xv850e1 | xv850e2 | xv850e2v3 | xv850e3v5)
- target_cpu_default2="TARGET_CPU_$with_cpu"
- ;;
- xv850es)
- target_cpu_default2="TARGET_CPU_v850e1"
- ;;
- esac
- ;;
-esac
-
-t=
-all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 schedule float mode fpu divide llsc mips-plt synci tls"
-for option in $all_defaults
-do
- eval "val=\$with_"`echo $option | sed s/-/_/g`
- if test -n "$val"; then
- case " $supported_defaults " in
- *" $option "*)
- ;;
- *)
- echo "This target does not support --with-$option." 2>&1
- echo "Valid --with options are: $supported_defaults" 2>&1
- exit 1
- ;;
- esac
-
- if test "x$t" = x
- then
- t="{ \"$option\", \"$val\" }"
- else
- t="${t}, { \"$option\", \"$val\" }"
- fi
- fi
-done
-
-if test "x$t" = x
-then
- configure_default_options="{ { NULL, NULL} }"
-else
- configure_default_options="{ ${t} }"
-fi
-
-if test "$target_cpu_default2" != ""
-then
- if test "$target_cpu_default" != ""
- then
- target_cpu_default="(${target_cpu_default}|${target_cpu_default2})"
- else
- target_cpu_default=$target_cpu_default2
- fi
-fi
diff --git a/gcc-4.8/gcc/config/arm/arm.c.orig b/gcc-4.8/gcc/config/arm/arm.c.orig
deleted file mode 100644
index 155a52082..000000000
--- a/gcc-4.8/gcc/config/arm/arm.c.orig
+++ /dev/null
@@ -1,27441 +0,0 @@
-/* Output routines for GCC for ARM.
- Copyright (C) 1991-2013 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).
-
- This file is part of GCC.
-
- GCC is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- GCC is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING3. If not see
- <http://www.gnu.org/licenses/>. */
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "tm.h"
-#include "rtl.h"
-#include "tree.h"
-#include "obstack.h"
-#include "regs.h"
-#include "hard-reg-set.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 "diagnostic-core.h"
-#include "recog.h"
-#include "cgraph.h"
-#include "ggc.h"
-#include "except.h"
-#include "tm_p.h"
-#include "target.h"
-#include "target-def.h"
-#include "debug.h"
-#include "langhooks.h"
-#include "df.h"
-#include "intl.h"
-#include "libfuncs.h"
-#include "params.h"
-#include "opts.h"
-#include "dumpfile.h"
-
-/* Forward definitions of types. */
-typedef struct minipool_node Mnode;
-typedef struct minipool_fixup Mfix;
-
-void (*arm_lang_output_object_attributes_hook)(void);
-
-struct four_ints
-{
- int i[4];
-};
-
-/* Forward function declarations. */
-static bool arm_needs_doubleword_align (enum machine_mode, const_tree);
-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,
- HOST_WIDE_INT, rtx, rtx, int, int);
-static unsigned bit_count (unsigned long);
-static int arm_address_register_rtx_p (rtx, int);
-static int arm_legitimate_index_p (enum machine_mode, rtx, RTX_CODE, int);
-static int thumb2_legitimate_index_p (enum machine_mode, rtx, int);
-static int thumb1_base_register_rtx_p (rtx, enum machine_mode, int);
-static rtx arm_legitimize_address (rtx, rtx, enum machine_mode);
-static reg_class_t arm_preferred_reload_class (rtx, reg_class_t);
-static rtx thumb_legitimize_address (rtx, rtx, enum machine_mode);
-inline static int thumb1_index_register_rtx_p (rtx, int);
-static bool arm_legitimate_address_p (enum machine_mode, rtx, bool);
-static int thumb_far_jump_used_p (void);
-static bool thumb_force_lr_save (void);
-static unsigned arm_size_return_regs (void);
-static bool arm_assemble_integer (rtx, unsigned int, int);
-static void arm_print_operand (FILE *, rtx, int);
-static void arm_print_operand_address (FILE *, rtx);
-static bool arm_print_operand_punct_valid_p (unsigned char code);
-static const char *fp_const_from_val (REAL_VALUE_TYPE *);
-static arm_cc get_arm_condition_code (rtx);
-static HOST_WIDE_INT int_log2 (HOST_WIDE_INT);
-static rtx is_jump_table (rtx);
-static const char *output_multi_immediate (rtx *, const char *, const char *,
- int, HOST_WIDE_INT);
-static const char *shift_op (rtx, HOST_WIDE_INT *);
-static struct machine_function *arm_init_machine_status (void);
-static void thumb_exit (FILE *, int);
-static rtx is_jump_table (rtx);
-static HOST_WIDE_INT get_jump_table_size (rtx);
-static Mnode *move_minipool_fix_forward_ref (Mnode *, Mnode *, HOST_WIDE_INT);
-static Mnode *add_minipool_forward_ref (Mfix *);
-static Mnode *move_minipool_fix_backward_ref (Mnode *, Mnode *, HOST_WIDE_INT);
-static Mnode *add_minipool_backward_ref (Mfix *);
-static void assign_minipool_offsets (Mfix *);
-static void arm_print_value (FILE *, rtx);
-static void dump_minipool (rtx);
-static int arm_barrier_cost (rtx);
-static Mfix *create_fix_barrier (Mfix *, HOST_WIDE_INT);
-static void push_minipool_barrier (rtx, HOST_WIDE_INT);
-static void push_minipool_fix (rtx, HOST_WIDE_INT, rtx *, enum machine_mode,
- rtx);
-static void arm_reorg (void);
-static void note_invalid_constants (rtx, HOST_WIDE_INT, int);
-static unsigned long arm_compute_save_reg0_reg12_mask (void);
-static unsigned long arm_compute_save_reg_mask (void);
-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 *);
-#endif
-static void arm_output_function_epilogue (FILE *, HOST_WIDE_INT);
-static void arm_output_function_prologue (FILE *, HOST_WIDE_INT);
-static int arm_comp_type_attributes (const_tree, const_tree);
-static void arm_set_default_type_attributes (tree);
-static int arm_adjust_cost (rtx, rtx, rtx, int);
-static int arm_sched_reorder (FILE *, int, rtx *, int *, int);
-static int optimal_immediate_sequence (enum rtx_code code,
- unsigned HOST_WIDE_INT val,
- struct four_ints *return_sequence);
-static int optimal_immediate_sequence_1 (enum rtx_code code,
- unsigned HOST_WIDE_INT val,
- struct four_ints *return_sequence,
- int i);
-static int arm_get_strip_length (int);
-static bool arm_function_ok_for_sibcall (tree, tree);
-static enum machine_mode arm_promote_function_mode (const_tree,
- enum machine_mode, int *,
- const_tree, int);
-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_1 (enum machine_mode);
-static rtx arm_libcall_value (enum machine_mode, const_rtx);
-static bool arm_function_value_regno_p (const unsigned int);
-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 bool arm_have_conditional_execution (void);
-static bool arm_cannot_force_const_mem (enum machine_mode, rtx);
-static bool arm_legitimate_constant_p (enum machine_mode, rtx);
-static bool arm_rtx_costs_1 (rtx, enum rtx_code, int*, bool);
-static bool arm_size_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *);
-static bool arm_slowmul_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *, bool);
-static bool arm_fastmul_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *, bool);
-static bool arm_xscale_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *, bool);
-static bool arm_9e_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *, bool);
-static bool arm_rtx_costs (rtx, int, int, int, int *, bool);
-static int arm_address_cost (rtx, enum machine_mode, addr_space_t, bool);
-static int arm_register_move_cost (enum machine_mode, reg_class_t, reg_class_t);
-static int arm_memory_move_cost (enum machine_mode, reg_class_t, bool);
-static void arm_init_builtins (void);
-static void arm_init_iwmmxt_builtins (void);
-static rtx safe_vector_operand (rtx, enum machine_mode);
-static rtx arm_expand_binop_builtin (enum insn_code, tree, rtx);
-static rtx arm_expand_unop_builtin (enum insn_code, tree, rtx, int);
-static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
-static tree arm_builtin_decl (unsigned, bool);
-static void emit_constant_insn (rtx cond, rtx pattern);
-static rtx emit_set_insn (rtx, rtx);
-static int arm_arg_partial_bytes (cumulative_args_t, enum machine_mode,
- tree, bool);
-static rtx arm_function_arg (cumulative_args_t, enum machine_mode,
- const_tree, bool);
-static void arm_function_arg_advance (cumulative_args_t, enum machine_mode,
- const_tree, bool);
-static unsigned int arm_function_arg_boundary (enum machine_mode, const_tree);
-static rtx aapcs_allocate_return_reg (enum machine_mode, const_tree,
- const_tree);
-static rtx aapcs_libcall_value (enum machine_mode);
-static int aapcs_select_return_coproc (const_tree, const_tree);
-
-#ifdef OBJECT_FORMAT_ELF
-static void arm_elf_asm_constructor (rtx, int) ATTRIBUTE_UNUSED;
-static void arm_elf_asm_destructor (rtx, int) ATTRIBUTE_UNUSED;
-#endif
-#ifndef ARM_PE
-static void arm_encode_section_info (tree, rtx, int);
-#endif
-
-static void arm_file_end (void);
-static void arm_file_start (void);
-
-static void arm_setup_incoming_varargs (cumulative_args_t, enum machine_mode,
- tree, int *, int);
-static bool arm_pass_by_reference (cumulative_args_t,
- enum machine_mode, const_tree, bool);
-static bool arm_promote_prototypes (const_tree);
-static bool arm_default_short_enums (void);
-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);
-#if ARM_UNWIND_INFO
-static void arm_unwind_emit (FILE *, rtx);
-static bool arm_output_ttype (rtx);
-static void arm_asm_emit_except_personality (rtx);
-static void arm_asm_init_sections (void);
-#endif
-static rtx arm_dwarf_register_span (rtx);
-
-static tree arm_cxx_guard_type (void);
-static bool arm_cxx_guard_mask_bit (void);
-static tree arm_get_cookie_size (tree);
-static bool arm_cookie_has_size (void);
-static bool arm_cxx_cdtor_returns_this (void);
-static bool arm_cxx_key_method_may_be_inline (void);
-static void arm_cxx_determine_class_data_visibility (tree);
-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, gimple_seq *, gimple_seq *);
-static void arm_option_override (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 int arm_issue_rate (void);
-static void arm_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
-static bool arm_output_addr_const_extra (FILE *, rtx);
-static bool arm_allocate_stack_slots_for_args (void);
-static bool arm_warn_func_return (tree);
-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 bool arm_frame_pointer_required (void);
-static bool arm_can_eliminate (const int, const int);
-static void arm_asm_trampoline_template (FILE *);
-static void arm_trampoline_init (rtx, tree, rtx);
-static rtx arm_trampoline_adjust_address (rtx);
-static rtx arm_pic_static_addr (rtx orig, rtx reg);
-static bool cortex_a9_sched_adjust_cost (rtx, rtx, rtx, int *);
-static bool xscale_sched_adjust_cost (rtx, rtx, rtx, int *);
-static bool fa726te_sched_adjust_cost (rtx, rtx, rtx, int *);
-static bool arm_array_mode_supported_p (enum machine_mode,
- unsigned HOST_WIDE_INT);
-static enum machine_mode arm_preferred_simd_mode (enum machine_mode);
-static bool arm_class_likely_spilled_p (reg_class_t);
-static HOST_WIDE_INT arm_vector_alignment (const_tree type);
-static bool arm_vector_alignment_reachable (const_tree type, bool is_packed);
-static bool arm_builtin_support_vector_misalignment (enum machine_mode mode,
- const_tree type,
- int misalignment,
- bool is_packed);
-static void arm_conditional_register_usage (void);
-static reg_class_t arm_preferred_rename_class (reg_class_t rclass);
-static unsigned int arm_autovectorize_vector_sizes (void);
-static int arm_default_branch_cost (bool, bool);
-static int arm_cortex_a5_branch_cost (bool, bool);
-
-static bool arm_vectorize_vec_perm_const_ok (enum machine_mode vmode,
- const unsigned char *sel);
-
-static int arm_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
- tree vectype,
- int misalign ATTRIBUTE_UNUSED);
-static unsigned arm_add_stmt_cost (void *data, int count,
- enum vect_cost_for_stmt kind,
- struct _stmt_vec_info *stmt_info,
- int misalign,
- enum vect_cost_model_location where);
-
-static void arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
- bool op0_preserve_value);
-
-/* Table of machine attributes. */
-static const struct attribute_spec arm_attribute_table[] =
-{
- /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
- affects_type_identity } */
- /* Function calls made to this symbol must be done indirectly, because
- it may lie outside of the 26 bit addressing range of a normal function
- call. */
- { "long_call", 0, 0, false, true, true, NULL, false },
- /* Whereas these functions are always known to reside within the 26 bit
- addressing range. */
- { "short_call", 0, 0, false, true, true, NULL, false },
- /* Specify the procedure call conventions for a function. */
- { "pcs", 1, 1, false, true, true, arm_handle_pcs_attribute,
- false },
- /* Interrupt Service Routines have special prologue and epilogue requirements. */
- { "isr", 0, 1, false, false, false, arm_handle_isr_attribute,
- false },
- { "interrupt", 0, 1, false, false, false, arm_handle_isr_attribute,
- false },
- { "naked", 0, 0, true, false, false, arm_handle_fndecl_attribute,
- false },
-#ifdef ARM_PE
- /* ARM/PE has three new attributes:
- interfacearm - ?
- dllexport - for exporting a function/variable that will live in a dll
- dllimport - for importing a function/variable from a dll
-
- Microsoft allows multiple declspecs in one __declspec, separating
- them with spaces. We do NOT support this. Instead, use __declspec
- multiple times.
- */
- { "dllimport", 0, 0, true, false, false, NULL, false },
- { "dllexport", 0, 0, true, false, false, NULL, false },
- { "interfacearm", 0, 0, true, false, false, arm_handle_fndecl_attribute,
- false },
-#elif TARGET_DLLIMPORT_DECL_ATTRIBUTES
- { "dllimport", 0, 0, false, false, false, handle_dll_attribute, false },
- { "dllexport", 0, 0, false, false, false, handle_dll_attribute, false },
- { "notshared", 0, 0, false, true, false, arm_handle_notshared_attribute,
- false },
-#endif
- { NULL, 0, 0, false, false, false, NULL, false }
-};
-
-/* Initialize the GCC target structure. */
-#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
-#undef TARGET_MERGE_DECL_ATTRIBUTES
-#define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes
-#endif
-
-#undef TARGET_LEGITIMIZE_ADDRESS
-#define TARGET_LEGITIMIZE_ADDRESS arm_legitimize_address
-
-#undef TARGET_ATTRIBUTE_TABLE
-#define TARGET_ATTRIBUTE_TABLE arm_attribute_table
-
-#undef TARGET_ASM_FILE_START
-#define TARGET_ASM_FILE_START arm_file_start
-#undef TARGET_ASM_FILE_END
-#define TARGET_ASM_FILE_END arm_file_end
-
-#undef TARGET_ASM_ALIGNED_SI_OP
-#define TARGET_ASM_ALIGNED_SI_OP NULL
-#undef TARGET_ASM_INTEGER
-#define TARGET_ASM_INTEGER arm_assemble_integer
-
-#undef TARGET_PRINT_OPERAND
-#define TARGET_PRINT_OPERAND arm_print_operand
-#undef TARGET_PRINT_OPERAND_ADDRESS
-#define TARGET_PRINT_OPERAND_ADDRESS arm_print_operand_address
-#undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
-#define TARGET_PRINT_OPERAND_PUNCT_VALID_P arm_print_operand_punct_valid_p
-
-#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
-#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA arm_output_addr_const_extra
-
-#undef TARGET_ASM_FUNCTION_PROLOGUE
-#define TARGET_ASM_FUNCTION_PROLOGUE arm_output_function_prologue
-
-#undef TARGET_ASM_FUNCTION_EPILOGUE
-#define TARGET_ASM_FUNCTION_EPILOGUE arm_output_function_epilogue
-
-#undef TARGET_OPTION_OVERRIDE
-#define TARGET_OPTION_OVERRIDE arm_option_override
-
-#undef TARGET_COMP_TYPE_ATTRIBUTES
-#define TARGET_COMP_TYPE_ATTRIBUTES arm_comp_type_attributes
-
-#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
-#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES arm_set_default_type_attributes
-
-#undef TARGET_SCHED_ADJUST_COST
-#define TARGET_SCHED_ADJUST_COST arm_adjust_cost
-
-#undef TARGET_SCHED_REORDER
-#define TARGET_SCHED_REORDER arm_sched_reorder
-
-#undef TARGET_REGISTER_MOVE_COST
-#define TARGET_REGISTER_MOVE_COST arm_register_move_cost
-
-#undef TARGET_MEMORY_MOVE_COST
-#define TARGET_MEMORY_MOVE_COST arm_memory_move_cost
-
-#undef TARGET_ENCODE_SECTION_INFO
-#ifdef ARM_PE
-#define TARGET_ENCODE_SECTION_INFO arm_pe_encode_section_info
-#else
-#define TARGET_ENCODE_SECTION_INFO arm_encode_section_info
-#endif
-
-#undef TARGET_STRIP_NAME_ENCODING
-#define TARGET_STRIP_NAME_ENCODING arm_strip_name_encoding
-
-#undef TARGET_ASM_INTERNAL_LABEL
-#define TARGET_ASM_INTERNAL_LABEL arm_internal_label
-
-#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_FUNCTION_VALUE_REGNO_P
-#define TARGET_FUNCTION_VALUE_REGNO_P arm_function_value_regno_p
-
-#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
-
-#undef TARGET_RTX_COSTS
-#define TARGET_RTX_COSTS arm_rtx_costs
-#undef TARGET_ADDRESS_COST
-#define TARGET_ADDRESS_COST arm_address_cost
-
-#undef TARGET_SHIFT_TRUNCATION_MASK
-#define TARGET_SHIFT_TRUNCATION_MASK arm_shift_truncation_mask
-#undef TARGET_VECTOR_MODE_SUPPORTED_P
-#define TARGET_VECTOR_MODE_SUPPORTED_P arm_vector_mode_supported_p
-#undef TARGET_ARRAY_MODE_SUPPORTED_P
-#define TARGET_ARRAY_MODE_SUPPORTED_P arm_array_mode_supported_p
-#undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
-#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arm_preferred_simd_mode
-#undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES
-#define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES \
- arm_autovectorize_vector_sizes
-
-#undef TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG arm_reorg
-
-#undef TARGET_INIT_BUILTINS
-#define TARGET_INIT_BUILTINS arm_init_builtins
-#undef TARGET_EXPAND_BUILTIN
-#define TARGET_EXPAND_BUILTIN arm_expand_builtin
-#undef TARGET_BUILTIN_DECL
-#define TARGET_BUILTIN_DECL arm_builtin_decl
-
-#undef TARGET_INIT_LIBFUNCS
-#define TARGET_INIT_LIBFUNCS arm_init_libfuncs
-
-#undef TARGET_PROMOTE_FUNCTION_MODE
-#define TARGET_PROMOTE_FUNCTION_MODE arm_promote_function_mode
-#undef TARGET_PROMOTE_PROTOTYPES
-#define TARGET_PROMOTE_PROTOTYPES arm_promote_prototypes
-#undef TARGET_PASS_BY_REFERENCE
-#define TARGET_PASS_BY_REFERENCE arm_pass_by_reference
-#undef TARGET_ARG_PARTIAL_BYTES
-#define TARGET_ARG_PARTIAL_BYTES arm_arg_partial_bytes
-#undef TARGET_FUNCTION_ARG
-#define TARGET_FUNCTION_ARG arm_function_arg
-#undef TARGET_FUNCTION_ARG_ADVANCE
-#define TARGET_FUNCTION_ARG_ADVANCE arm_function_arg_advance
-#undef TARGET_FUNCTION_ARG_BOUNDARY
-#define TARGET_FUNCTION_ARG_BOUNDARY arm_function_arg_boundary
-
-#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_ASM_TRAMPOLINE_TEMPLATE
-#define TARGET_ASM_TRAMPOLINE_TEMPLATE arm_asm_trampoline_template
-#undef TARGET_TRAMPOLINE_INIT
-#define TARGET_TRAMPOLINE_INIT arm_trampoline_init
-#undef TARGET_TRAMPOLINE_ADJUST_ADDRESS
-#define TARGET_TRAMPOLINE_ADJUST_ADDRESS arm_trampoline_adjust_address
-
-#undef TARGET_WARN_FUNC_RETURN
-#define TARGET_WARN_FUNC_RETURN arm_warn_func_return
-
-#undef TARGET_DEFAULT_SHORT_ENUMS
-#define TARGET_DEFAULT_SHORT_ENUMS arm_default_short_enums
-
-#undef TARGET_ALIGN_ANON_BITFIELD
-#define TARGET_ALIGN_ANON_BITFIELD arm_align_anon_bitfield
-
-#undef TARGET_NARROW_VOLATILE_BITFIELD
-#define TARGET_NARROW_VOLATILE_BITFIELD hook_bool_void_false
-
-#undef TARGET_CXX_GUARD_TYPE
-#define TARGET_CXX_GUARD_TYPE arm_cxx_guard_type
-
-#undef TARGET_CXX_GUARD_MASK_BIT
-#define TARGET_CXX_GUARD_MASK_BIT arm_cxx_guard_mask_bit
-
-#undef TARGET_CXX_GET_COOKIE_SIZE
-#define TARGET_CXX_GET_COOKIE_SIZE arm_get_cookie_size
-
-#undef TARGET_CXX_COOKIE_HAS_SIZE
-#define TARGET_CXX_COOKIE_HAS_SIZE arm_cookie_has_size
-
-#undef TARGET_CXX_CDTOR_RETURNS_THIS
-#define TARGET_CXX_CDTOR_RETURNS_THIS arm_cxx_cdtor_returns_this
-
-#undef TARGET_CXX_KEY_METHOD_MAY_BE_INLINE
-#define TARGET_CXX_KEY_METHOD_MAY_BE_INLINE arm_cxx_key_method_may_be_inline
-
-#undef TARGET_CXX_USE_AEABI_ATEXIT
-#define TARGET_CXX_USE_AEABI_ATEXIT arm_cxx_use_aeabi_atexit
-
-#undef TARGET_CXX_DETERMINE_CLASS_DATA_VISIBILITY
-#define TARGET_CXX_DETERMINE_CLASS_DATA_VISIBILITY \
- arm_cxx_determine_class_data_visibility
-
-#undef TARGET_CXX_CLASS_DATA_ALWAYS_COMDAT
-#define TARGET_CXX_CLASS_DATA_ALWAYS_COMDAT arm_cxx_class_data_always_comdat
-
-#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
-
-#if ARM_UNWIND_INFO
-#undef TARGET_ASM_UNWIND_EMIT
-#define TARGET_ASM_UNWIND_EMIT arm_unwind_emit
-
-/* EABI unwinding tables use a different format for the typeinfo tables. */
-#undef TARGET_ASM_TTYPE
-#define TARGET_ASM_TTYPE arm_output_ttype
-
-#undef TARGET_ARM_EABI_UNWINDER
-#define TARGET_ARM_EABI_UNWINDER true
-
-#undef TARGET_ASM_EMIT_EXCEPT_PERSONALITY
-#define TARGET_ASM_EMIT_EXCEPT_PERSONALITY arm_asm_emit_except_personality
-
-#undef TARGET_ASM_INIT_SECTIONS
-#define TARGET_ASM_INIT_SECTIONS arm_asm_init_sections
-#endif /* ARM_UNWIND_INFO */
-
-#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
-
-#ifdef HAVE_AS_TLS
-#undef TARGET_HAVE_TLS
-#define TARGET_HAVE_TLS true
-#endif
-
-#undef TARGET_HAVE_CONDITIONAL_EXECUTION
-#define TARGET_HAVE_CONDITIONAL_EXECUTION arm_have_conditional_execution
-
-#undef TARGET_LEGITIMATE_CONSTANT_P
-#define TARGET_LEGITIMATE_CONSTANT_P arm_legitimate_constant_p
-
-#undef TARGET_CANNOT_FORCE_CONST_MEM
-#define TARGET_CANNOT_FORCE_CONST_MEM arm_cannot_force_const_mem
-
-#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_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_LEGITIMATE_ADDRESS_P
-#define TARGET_LEGITIMATE_ADDRESS_P arm_legitimate_address_p
-
-#undef TARGET_PREFERRED_RELOAD_CLASS
-#define TARGET_PREFERRED_RELOAD_CLASS arm_preferred_reload_class
-
-#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_FRAME_POINTER_REQUIRED
-#define TARGET_FRAME_POINTER_REQUIRED arm_frame_pointer_required
-
-#undef TARGET_CAN_ELIMINATE
-#define TARGET_CAN_ELIMINATE arm_can_eliminate
-
-#undef TARGET_CONDITIONAL_REGISTER_USAGE
-#define TARGET_CONDITIONAL_REGISTER_USAGE arm_conditional_register_usage
-
-#undef TARGET_CLASS_LIKELY_SPILLED_P
-#define TARGET_CLASS_LIKELY_SPILLED_P arm_class_likely_spilled_p
-
-#undef TARGET_VECTOR_ALIGNMENT
-#define TARGET_VECTOR_ALIGNMENT arm_vector_alignment
-
-#undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
-#define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE \
- arm_vector_alignment_reachable
-
-#undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
-#define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
- arm_builtin_support_vector_misalignment
-
-#undef TARGET_PREFERRED_RENAME_CLASS
-#define TARGET_PREFERRED_RENAME_CLASS \
- arm_preferred_rename_class
-
-#undef TARGET_VECTORIZE_VEC_PERM_CONST_OK
-#define TARGET_VECTORIZE_VEC_PERM_CONST_OK \
- arm_vectorize_vec_perm_const_ok
-
-#undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
-#define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
- arm_builtin_vectorization_cost
-#undef TARGET_VECTORIZE_ADD_STMT_COST
-#define TARGET_VECTORIZE_ADD_STMT_COST arm_add_stmt_cost
-
-#undef TARGET_CANONICALIZE_COMPARISON
-#define TARGET_CANONICALIZE_COMPARISON \
- arm_canonicalize_comparison
-
-struct gcc_target targetm = TARGET_INITIALIZER;
-
-/* Obstack for minipool constant handling. */
-static struct obstack minipool_obstack;
-static char * minipool_startobj;
-
-/* The maximum number of insns skipped which
- will be conditionalised if possible. */
-static int max_insns_skipped = 5;
-
-extern FILE * asm_out_file;
-
-/* True if we are currently building a constant table. */
-int making_const_table;
-
-/* The processor for which instructions should be scheduled. */
-enum processor_type arm_tune = arm_none;
-
-/* The current tuning set. */
-const struct tune_params *current_tune;
-
-/* Which floating point hardware to schedule for. */
-int arm_fpu_attr;
-
-/* Which floating popint hardware to use. */
-const struct arm_fpu_desc *arm_fpu_desc;
-
-/* Used for Thumb call_via trampolines. */
-rtx thumb_call_via_label[14];
-static int thumb_call_reg_needed;
-
-/* Bit values used to identify processor capabilities. */
-#define FL_CO_PROC (1 << 0) /* Has external co-processor bus */
-#define FL_ARCH3M (1 << 1) /* Extended multiply */
-#define FL_MODE26 (1 << 2) /* 26-bit mode support */
-#define FL_MODE32 (1 << 3) /* 32-bit mode support */
-#define FL_ARCH4 (1 << 4) /* Architecture rel 4 */
-#define FL_ARCH5 (1 << 5) /* Architecture rel 5 */
-#define FL_THUMB (1 << 6) /* Thumb aware */
-#define FL_LDSCHED (1 << 7) /* Load scheduling necessary */
-#define FL_STRONG (1 << 8) /* StrongARM */
-#define FL_ARCH5E (1 << 9) /* DSP extensions to v5 */
-#define FL_XSCALE (1 << 10) /* XScale */
-/* spare (1 << 11) */
-#define FL_ARCH6 (1 << 12) /* Architecture rel 6. Adds
- media instructions. */
-#define FL_VFPV2 (1 << 13) /* Vector Floating Point V2. */
-#define FL_WBUF (1 << 14) /* Schedule for write buffer ops.
- Note: ARM6 & 7 derivatives only. */
-#define FL_ARCH6K (1 << 15) /* Architecture rel 6 K extensions. */
-#define FL_THUMB2 (1 << 16) /* Thumb-2. */
-#define FL_NOTM (1 << 17) /* Instructions not present in the 'M'
- profile. */
-#define FL_THUMB_DIV (1 << 18) /* Hardware divide (Thumb mode). */
-#define FL_VFPV3 (1 << 19) /* Vector Floating Point V3. */
-#define FL_NEON (1 << 20) /* Neon instructions. */
-#define FL_ARCH7EM (1 << 21) /* Instructions present in the ARMv7E-M
- architecture. */
-#define FL_ARCH7 (1 << 22) /* Architecture 7. */
-#define FL_ARM_DIV (1 << 23) /* Hardware divide (ARM mode). */
-#define FL_ARCH8 (1 << 24) /* Architecture 8. */
-
-#define FL_IWMMXT (1 << 29) /* XScale v2 or "Intel Wireless MMX technology". */
-#define FL_IWMMXT2 (1 << 30) /* "Intel Wireless MMX2 technology". */
-
-/* Flags that only effect tuning, not available instructions. */
-#define FL_TUNE (FL_WBUF | FL_VFPV2 | FL_STRONG | FL_LDSCHED \
- | FL_CO_PROC)
-
-#define FL_FOR_ARCH2 FL_NOTM
-#define FL_FOR_ARCH3 (FL_FOR_ARCH2 | FL_MODE32)
-#define FL_FOR_ARCH3M (FL_FOR_ARCH3 | FL_ARCH3M)
-#define FL_FOR_ARCH4 (FL_FOR_ARCH3M | FL_ARCH4)
-#define FL_FOR_ARCH4T (FL_FOR_ARCH4 | FL_THUMB)
-#define FL_FOR_ARCH5 (FL_FOR_ARCH4 | FL_ARCH5)
-#define FL_FOR_ARCH5T (FL_FOR_ARCH5 | FL_THUMB)
-#define FL_FOR_ARCH5E (FL_FOR_ARCH5 | FL_ARCH5E)
-#define FL_FOR_ARCH5TE (FL_FOR_ARCH5E | FL_THUMB)
-#define FL_FOR_ARCH5TEJ FL_FOR_ARCH5TE
-#define FL_FOR_ARCH6 (FL_FOR_ARCH5TE | FL_ARCH6)
-#define FL_FOR_ARCH6J FL_FOR_ARCH6
-#define FL_FOR_ARCH6K (FL_FOR_ARCH6 | FL_ARCH6K)
-#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) | FL_ARCH7)
-#define FL_FOR_ARCH7A (FL_FOR_ARCH7 | FL_NOTM | FL_ARCH6K)
-#define FL_FOR_ARCH7R (FL_FOR_ARCH7A | FL_THUMB_DIV)
-#define FL_FOR_ARCH7M (FL_FOR_ARCH7 | FL_THUMB_DIV)
-#define FL_FOR_ARCH7EM (FL_FOR_ARCH7M | FL_ARCH7EM)
-#define FL_FOR_ARCH8A (FL_FOR_ARCH7 | FL_ARCH6K | FL_ARCH8 | FL_THUMB_DIV \
- | FL_ARM_DIV | FL_NOTM)
-
-/* The bits in this mask specify which
- instructions we are allowed to generate. */
-static unsigned long insn_flags = 0;
-
-/* The bits in this mask specify which instruction scheduling options should
- be used. */
-static unsigned long tune_flags = 0;
-
-/* The highest ARM architecture version supported by the
- target. */
-enum base_architecture arm_base_arch = BASE_ARCH_0;
-
-/* The following are used in the arm.md file as equivalents to bits
- in the above two flag variables. */
-
-/* Nonzero if this chip supports the ARM Architecture 3M extensions. */
-int arm_arch3m = 0;
-
-/* Nonzero if this chip supports the ARM Architecture 4 extensions. */
-int arm_arch4 = 0;
-
-/* Nonzero if this chip supports the ARM Architecture 4t extensions. */
-int arm_arch4t = 0;
-
-/* Nonzero if this chip supports the ARM Architecture 5 extensions. */
-int arm_arch5 = 0;
-
-/* Nonzero if this chip supports the ARM Architecture 5E extensions. */
-int arm_arch5e = 0;
-
-/* Nonzero if this chip supports the ARM Architecture 6 extensions. */
-int arm_arch6 = 0;
-
-/* Nonzero if this chip supports the ARM 6K extensions. */
-int arm_arch6k = 0;
-
-/* Nonzero if instructions present in ARMv6-M can be used. */
-int arm_arch6m = 0;
-
-/* Nonzero if this chip supports the ARM 7 extensions. */
-int arm_arch7 = 0;
-
-/* Nonzero if instructions not present in the 'M' profile can be used. */
-int arm_arch_notm = 0;
-
-/* Nonzero if instructions present in ARMv7E-M can be used. */
-int arm_arch7em = 0;
-
-/* Nonzero if instructions present in ARMv8 can be used. */
-int arm_arch8 = 0;
-
-/* Nonzero if this chip can benefit from load scheduling. */
-int arm_ld_sched = 0;
-
-/* Nonzero if this chip is a StrongARM. */
-int arm_tune_strongarm = 0;
-
-/* Nonzero if this chip supports Intel Wireless MMX technology. */
-int arm_arch_iwmmxt = 0;
-
-/* Nonzero if this chip supports Intel Wireless MMX2 technology. */
-int arm_arch_iwmmxt2 = 0;
-
-/* Nonzero if this chip is an XScale. */
-int arm_arch_xscale = 0;
-
-/* Nonzero if tuning for XScale */
-int arm_tune_xscale = 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 Thumb-1 instructions. */
-int thumb1_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
- problems in GLD which doesn't understand that armv5t code is
- interworking clean. */
-int arm_cpp_interwork = 0;
-
-/* Nonzero if chip supports Thumb 2. */
-int arm_arch_thumb2;
-
-/* Nonzero if chip supports integer division instruction. */
-int arm_arch_arm_hwdiv;
-int arm_arch_thumb_hwdiv;
-
-/* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference,
- we must report the mode of the memory reference from
- TARGET_PRINT_OPERAND to TARGET_PRINT_OPERAND_ADDRESS. */
-enum machine_mode output_memory_reference_mode;
-
-/* The register number to be used for the PIC offset register. */
-unsigned arm_pic_register = INVALID_REGNUM;
-
-/* Set to 1 after arm_reorg has started. Reset to start at the start of
- the next function. */
-static int after_arm_reorg = 0;
-
-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. */
-enum arm_cond_code arm_current_cc;
-
-rtx arm_target_insn;
-int arm_target_label;
-/* The number of conditionally executed insns, including the current insn. */
-int arm_condexec_count = 0;
-/* A bitmask specifying the patterns for the IT block.
- Zero means do not output an IT block before this insn. */
-int arm_condexec_mask = 0;
-/* The number of bits used in arm_condexec_mask. */
-int arm_condexec_masklen = 0;
-
-/* The condition codes of the ARM, and the inverse function. */
-static const char * const arm_condition_codes[] =
-{
- "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
- "hi", "ls", "ge", "lt", "gt", "le", "al", "nv"
-};
-
-/* The register numbers in sequence, for passing to arm_gen_load_multiple. */
-int arm_regs_in_sequence[] =
-{
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
-};
-
-#define ARM_LSL_NAME (TARGET_UNIFIED_ASM ? "lsl" : "asl")
-#define streq(string1, string2) (strcmp (string1, string2) == 0)
-
-#define THUMB2_WORK_REGS (0xff & ~( (1 << THUMB_HARD_FRAME_POINTER_REGNUM) \
- | (1 << SP_REGNUM) | (1 << PC_REGNUM) \
- | (1 << PIC_OFFSET_TABLE_REGNUM)))
-
-/* Initialization code. */
-
-struct processors
-{
- const char *const name;
- enum processor_type core;
- const char *arch;
- enum base_architecture base_arch;
- const unsigned long flags;
- const struct tune_params *const tune;
-};
-
-
-#define ARM_PREFETCH_NOT_BENEFICIAL 0, -1, -1
-#define ARM_PREFETCH_BENEFICIAL(prefetch_slots,l1_size,l1_line_size) \
- prefetch_slots, \
- l1_size, \
- l1_line_size
-
-/* arm generic vectorizer costs. */
-static const
-struct cpu_vec_costs arm_default_vec_cost = {
- 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. */
- 1, /* vec_unalign_load_cost. */
- 1, /* vec_unalign_store_cost. */
- 1, /* vec_store_cost. */
- 3, /* cond_taken_branch_cost. */
- 1, /* cond_not_taken_branch_cost. */
-};
-
-const struct tune_params arm_slowmul_tune =
-{
- arm_slowmul_rtx_costs,
- NULL,
- 3, /* Constant limit. */
- 5, /* Max cond insns. */
- ARM_PREFETCH_NOT_BENEFICIAL,
- true, /* Prefer constant pool. */
- arm_default_branch_cost,
- false, /* Prefer LDRD/STRD. */
- {true, true}, /* Prefer non short circuit. */
- &arm_default_vec_cost, /* Vectorizer costs. */
-};
-
-const struct tune_params arm_fastmul_tune =
-{
- arm_fastmul_rtx_costs,
- NULL,
- 1, /* Constant limit. */
- 5, /* Max cond insns. */
- ARM_PREFETCH_NOT_BENEFICIAL,
- true, /* Prefer constant pool. */
- arm_default_branch_cost,
- false, /* Prefer LDRD/STRD. */
- {true, true}, /* Prefer non short circuit. */
- &arm_default_vec_cost, /* Vectorizer costs. */
-};
-
-/* StrongARM has early execution of branches, so a sequence that is worth
- skipping is shorter. Set max_insns_skipped to a lower value. */
-
-const struct tune_params arm_strongarm_tune =
-{
- arm_fastmul_rtx_costs,
- NULL,
- 1, /* Constant limit. */
- 3, /* Max cond insns. */
- ARM_PREFETCH_NOT_BENEFICIAL,
- true, /* Prefer constant pool. */
- arm_default_branch_cost,
- false, /* Prefer LDRD/STRD. */
- {true, true}, /* Prefer non short circuit. */
- &arm_default_vec_cost, /* Vectorizer costs. */
-};
-
-const struct tune_params arm_xscale_tune =
-{
- arm_xscale_rtx_costs,
- xscale_sched_adjust_cost,
- 2, /* Constant limit. */
- 3, /* Max cond insns. */
- ARM_PREFETCH_NOT_BENEFICIAL,
- true, /* Prefer constant pool. */
- arm_default_branch_cost,
- false, /* Prefer LDRD/STRD. */
- {true, true}, /* Prefer non short circuit. */
- &arm_default_vec_cost, /* Vectorizer costs. */
-};
-
-const struct tune_params arm_9e_tune =
-{
- arm_9e_rtx_costs,
- NULL,
- 1, /* Constant limit. */
- 5, /* Max cond insns. */
- ARM_PREFETCH_NOT_BENEFICIAL,
- true, /* Prefer constant pool. */
- arm_default_branch_cost,
- false, /* Prefer LDRD/STRD. */
- {true, true}, /* Prefer non short circuit. */
- &arm_default_vec_cost, /* Vectorizer costs. */
-};
-
-const struct tune_params arm_v6t2_tune =
-{
- arm_9e_rtx_costs,
- NULL,
- 1, /* Constant limit. */
- 5, /* Max cond insns. */
- ARM_PREFETCH_NOT_BENEFICIAL,
- false, /* Prefer constant pool. */
- arm_default_branch_cost,
- false, /* Prefer LDRD/STRD. */
- {true, true}, /* Prefer non short circuit. */
- &arm_default_vec_cost, /* Vectorizer costs. */
-};
-
-/* Generic Cortex tuning. Use more specific tunings if appropriate. */
-const struct tune_params arm_cortex_tune =
-{
- arm_9e_rtx_costs,
- NULL,
- 1, /* Constant limit. */
- 5, /* Max cond insns. */
- ARM_PREFETCH_NOT_BENEFICIAL,
- false, /* Prefer constant pool. */
- arm_default_branch_cost,
- false, /* Prefer LDRD/STRD. */
- {true, true}, /* Prefer non short circuit. */
- &arm_default_vec_cost, /* Vectorizer costs. */
-};
-
-const struct tune_params arm_cortex_a15_tune =
-{
- arm_9e_rtx_costs,
- NULL,
- 1, /* Constant limit. */
- 5, /* Max cond insns. */
- ARM_PREFETCH_NOT_BENEFICIAL,
- false, /* Prefer constant pool. */
- arm_default_branch_cost,
- true, /* Prefer LDRD/STRD. */
- {true, true}, /* Prefer non short circuit. */
- &arm_default_vec_cost, /* Vectorizer costs. */
-};
-
-/* Branches can be dual-issued on Cortex-A5, so conditional execution is
- less appealing. Set max_insns_skipped to a low value. */
-
-const struct tune_params arm_cortex_a5_tune =
-{
- arm_9e_rtx_costs,
- NULL,
- 1, /* Constant limit. */
- 1, /* Max cond insns. */
- ARM_PREFETCH_NOT_BENEFICIAL,
- false, /* Prefer constant pool. */
- arm_cortex_a5_branch_cost,
- false, /* Prefer LDRD/STRD. */
- {false, false}, /* Prefer non short circuit. */
- &arm_default_vec_cost, /* Vectorizer costs. */
-};
-
-const struct tune_params arm_cortex_a9_tune =
-{
- arm_9e_rtx_costs,
- cortex_a9_sched_adjust_cost,
- 1, /* Constant limit. */
- 5, /* Max cond insns. */
- ARM_PREFETCH_BENEFICIAL(4,32,32),
- false, /* Prefer constant pool. */
- arm_default_branch_cost,
- false, /* Prefer LDRD/STRD. */
- {true, true}, /* Prefer non short circuit. */
- &arm_default_vec_cost, /* Vectorizer costs. */
-};
-
-/* The arm_v6m_tune is duplicated from arm_cortex_tune, rather than
- arm_v6t2_tune. It is used for cortex-m0, cortex-m1 and cortex-m0plus. */
-const struct tune_params arm_v6m_tune =
-{
- arm_9e_rtx_costs,
- NULL,
- 1, /* Constant limit. */
- 5, /* Max cond insns. */
- ARM_PREFETCH_NOT_BENEFICIAL,
- false, /* Prefer constant pool. */
- arm_default_branch_cost,
- false, /* Prefer LDRD/STRD. */
- {false, false}, /* Prefer non short circuit. */
- &arm_default_vec_cost, /* Vectorizer costs. */
-};
-
-const struct tune_params arm_fa726te_tune =
-{
- arm_9e_rtx_costs,
- fa726te_sched_adjust_cost,
- 1, /* Constant limit. */
- 5, /* Max cond insns. */
- ARM_PREFETCH_NOT_BENEFICIAL,
- true, /* Prefer constant pool. */
- arm_default_branch_cost,
- false, /* Prefer LDRD/STRD. */
- {true, true}, /* Prefer non short circuit. */
- &arm_default_vec_cost, /* Vectorizer costs. */
-};
-
-
-/* Not all of these give usefully different compilation alternatives,
- but there is no simple way of generalizing them. */
-static const struct processors all_cores[] =
-{
- /* ARM Cores */
-#define ARM_CORE(NAME, IDENT, ARCH, FLAGS, COSTS) \
- {NAME, IDENT, #ARCH, BASE_ARCH_##ARCH, \
- FLAGS | FL_FOR_ARCH##ARCH, &arm_##COSTS##_tune},
-#include "arm-cores.def"
-#undef ARM_CORE
- {NULL, arm_none, NULL, BASE_ARCH_0, 0, NULL}
-};
-
-static const struct processors all_architectures[] =
-{
- /* ARM Architectures */
- /* We don't specify tuning costs here as it will be figured out
- from the core. */
-
-#define ARM_ARCH(NAME, CORE, ARCH, FLAGS) \
- {NAME, CORE, #ARCH, BASE_ARCH_##ARCH, FLAGS, NULL},
-#include "arm-arches.def"
-#undef ARM_ARCH
- {NULL, arm_none, NULL, BASE_ARCH_0, 0, NULL}
-};
-
-
-/* These are populated as commandline arguments are processed, or NULL
- if not specified. */
-static const struct processors *arm_selected_arch;
-static const struct processors *arm_selected_cpu;
-static const struct processors *arm_selected_tune;
-
-/* The name of the preprocessor macro to define for this architecture. */
-
-char arm_arch_name[] = "__ARM_ARCH_0UNK__";
-
-/* Available values for -mfpu=. */
-
-static const struct arm_fpu_desc all_fpus[] =
-{
-#define ARM_FPU(NAME, MODEL, REV, VFP_REGS, NEON, FP16, CRYPTO) \
- { NAME, MODEL, REV, VFP_REGS, NEON, FP16, CRYPTO },
-#include "arm-fpus.def"
-#undef ARM_FPU
-};
-
-
-/* Supported TLS relocations. */
-
-enum tls_reloc {
- TLS_GD32,
- TLS_LDM32,
- TLS_LDO32,
- TLS_IE32,
- TLS_LE32,
- TLS_DESCSEQ /* GNU scheme */
-};
-
-/* The maximum number of insns to be used when loading a constant. */
-inline static int
-arm_constant_limit (bool size_p)
-{
- return size_p ? 1 : current_tune->constant_limit;
-}
-
-/* Emit an insn that's a simple single-set. Both the operands must be known
- to be valid. */
-inline static rtx
-emit_set_insn (rtx x, rtx y)
-{
- return emit_insn (gen_rtx_SET (VOIDmode, x, y));
-}
-
-/* Return the number of bits set in VALUE. */
-static unsigned
-bit_count (unsigned long value)
-{
- unsigned long count = 0;
-
- while (value)
- {
- count++;
- value &= value - 1; /* Clear the least-significant set bit. */
- }
-
- return count;
-}
-
-typedef struct
-{
- enum machine_mode mode;
- const char *name;
-} arm_fixed_mode_set;
-
-/* A small helper for setting fixed-point library libfuncs. */
-
-static void
-arm_set_fixed_optab_libfunc (optab optable, enum machine_mode mode,
- const char *funcname, const char *modename,
- int num_suffix)
-{
- char buffer[50];
-
- if (num_suffix == 0)
- sprintf (buffer, "__gnu_%s%s", funcname, modename);
- else
- sprintf (buffer, "__gnu_%s%s%d", funcname, modename, num_suffix);
-
- set_optab_libfunc (optable, mode, buffer);
-}
-
-static void
-arm_set_fixed_conv_libfunc (convert_optab optable, enum machine_mode to,
- enum machine_mode from, const char *funcname,
- const char *toname, const char *fromname)
-{
- char buffer[50];
- const char *maybe_suffix_2 = "";
-
- /* Follow the logic for selecting a "2" suffix in fixed-bit.h. */
- if (ALL_FIXED_POINT_MODE_P (from) && ALL_FIXED_POINT_MODE_P (to)
- && UNSIGNED_FIXED_POINT_MODE_P (from) == UNSIGNED_FIXED_POINT_MODE_P (to)
- && ALL_FRACT_MODE_P (from) == ALL_FRACT_MODE_P (to))
- maybe_suffix_2 = "2";
-
- sprintf (buffer, "__gnu_%s%s%s%s", funcname, fromname, toname,
- maybe_suffix_2);
-
- set_conv_libfunc (optable, to, from, buffer);
-}
-
-/* Set up library functions unique to ARM. */
-
-static void
-arm_init_libfuncs (void)
-{
- /* For Linux, we have access to kernel support for atomic operations. */
- if (arm_abi == ARM_ABI_AAPCS_LINUX)
- init_sync_libfuncs (2 * UNITS_PER_WORD);
-
- /* There are no special library functions unless we are using the
- ARM BPABI. */
- if (!TARGET_BPABI)
- return;
-
- /* The functions below are described in Section 4 of the "Run-Time
- ABI for the ARM architecture", Version 1.0. */
-
- /* Double-precision floating-point arithmetic. Table 2. */
- set_optab_libfunc (add_optab, DFmode, "__aeabi_dadd");
- set_optab_libfunc (sdiv_optab, DFmode, "__aeabi_ddiv");
- set_optab_libfunc (smul_optab, DFmode, "__aeabi_dmul");
- set_optab_libfunc (neg_optab, DFmode, "__aeabi_dneg");
- set_optab_libfunc (sub_optab, DFmode, "__aeabi_dsub");
-
- /* Double-precision comparisons. Table 3. */
- set_optab_libfunc (eq_optab, DFmode, "__aeabi_dcmpeq");
- set_optab_libfunc (ne_optab, DFmode, NULL);
- set_optab_libfunc (lt_optab, DFmode, "__aeabi_dcmplt");
- set_optab_libfunc (le_optab, DFmode, "__aeabi_dcmple");
- set_optab_libfunc (ge_optab, DFmode, "__aeabi_dcmpge");
- set_optab_libfunc (gt_optab, DFmode, "__aeabi_dcmpgt");
- set_optab_libfunc (unord_optab, DFmode, "__aeabi_dcmpun");
-
- /* Single-precision floating-point arithmetic. Table 4. */
- set_optab_libfunc (add_optab, SFmode, "__aeabi_fadd");
- set_optab_libfunc (sdiv_optab, SFmode, "__aeabi_fdiv");
- set_optab_libfunc (smul_optab, SFmode, "__aeabi_fmul");
- set_optab_libfunc (neg_optab, SFmode, "__aeabi_fneg");
- set_optab_libfunc (sub_optab, SFmode, "__aeabi_fsub");
-
- /* Single-precision comparisons. Table 5. */
- set_optab_libfunc (eq_optab, SFmode, "__aeabi_fcmpeq");
- set_optab_libfunc (ne_optab, SFmode, NULL);
- set_optab_libfunc (lt_optab, SFmode, "__aeabi_fcmplt");
- set_optab_libfunc (le_optab, SFmode, "__aeabi_fcmple");
- set_optab_libfunc (ge_optab, SFmode, "__aeabi_fcmpge");
- set_optab_libfunc (gt_optab, SFmode, "__aeabi_fcmpgt");
- set_optab_libfunc (unord_optab, SFmode, "__aeabi_fcmpun");
-
- /* Floating-point to integer conversions. Table 6. */
- set_conv_libfunc (sfix_optab, SImode, DFmode, "__aeabi_d2iz");
- set_conv_libfunc (ufix_optab, SImode, DFmode, "__aeabi_d2uiz");
- set_conv_libfunc (sfix_optab, DImode, DFmode, "__aeabi_d2lz");
- set_conv_libfunc (ufix_optab, DImode, DFmode, "__aeabi_d2ulz");
- set_conv_libfunc (sfix_optab, SImode, SFmode, "__aeabi_f2iz");
- set_conv_libfunc (ufix_optab, SImode, SFmode, "__aeabi_f2uiz");
- set_conv_libfunc (sfix_optab, DImode, SFmode, "__aeabi_f2lz");
- set_conv_libfunc (ufix_optab, DImode, SFmode, "__aeabi_f2ulz");
-
- /* Conversions between floating types. Table 7. */
- set_conv_libfunc (trunc_optab, SFmode, DFmode, "__aeabi_d2f");
- set_conv_libfunc (sext_optab, DFmode, SFmode, "__aeabi_f2d");
-
- /* Integer to floating-point conversions. Table 8. */
- set_conv_libfunc (sfloat_optab, DFmode, SImode, "__aeabi_i2d");
- set_conv_libfunc (ufloat_optab, DFmode, SImode, "__aeabi_ui2d");
- set_conv_libfunc (sfloat_optab, DFmode, DImode, "__aeabi_l2d");
- set_conv_libfunc (ufloat_optab, DFmode, DImode, "__aeabi_ul2d");
- set_conv_libfunc (sfloat_optab, SFmode, SImode, "__aeabi_i2f");
- set_conv_libfunc (ufloat_optab, SFmode, SImode, "__aeabi_ui2f");
- set_conv_libfunc (sfloat_optab, SFmode, DImode, "__aeabi_l2f");
- set_conv_libfunc (ufloat_optab, SFmode, DImode, "__aeabi_ul2f");
-
- /* Long long. Table 9. */
- set_optab_libfunc (smul_optab, DImode, "__aeabi_lmul");
- set_optab_libfunc (sdivmod_optab, DImode, "__aeabi_ldivmod");
- set_optab_libfunc (udivmod_optab, DImode, "__aeabi_uldivmod");
- set_optab_libfunc (ashl_optab, DImode, "__aeabi_llsl");
- set_optab_libfunc (lshr_optab, DImode, "__aeabi_llsr");
- set_optab_libfunc (ashr_optab, DImode, "__aeabi_lasr");
- set_optab_libfunc (cmp_optab, DImode, "__aeabi_lcmp");
- set_optab_libfunc (ucmp_optab, DImode, "__aeabi_ulcmp");
-
- /* Integer (32/32->32) division. \S 4.3.1. */
- set_optab_libfunc (sdivmod_optab, SImode, "__aeabi_idivmod");
- set_optab_libfunc (udivmod_optab, SImode, "__aeabi_uidivmod");
-
- /* The divmod functions are designed so that they can be used for
- plain division, even though they return both the quotient and the
- remainder. The quotient is returned in the usual location (i.e.,
- r0 for SImode, {r0, r1} for DImode), just as would be expected
- for an ordinary division routine. Because the AAPCS calling
- conventions specify that all of { r0, r1, r2, r3 } are
- callee-saved registers, there is no need to tell the compiler
- explicitly that those registers are clobbered by these
- routines. */
- set_optab_libfunc (sdiv_optab, DImode, "__aeabi_ldivmod");
- set_optab_libfunc (udiv_optab, DImode, "__aeabi_uldivmod");
-
- /* For SImode division the ABI provides div-without-mod routines,
- which are faster. */
- set_optab_libfunc (sdiv_optab, SImode, "__aeabi_idiv");
- set_optab_libfunc (udiv_optab, SImode, "__aeabi_uidiv");
-
- /* We don't have mod libcalls. Fortunately gcc knows how to use the
- divmod libcalls instead. */
- set_optab_libfunc (smod_optab, DImode, NULL);
- 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;
- }
-
- /* Use names prefixed with __gnu_ for fixed-point helper functions. */
- {
- const arm_fixed_mode_set fixed_arith_modes[] =
- {
- { QQmode, "qq" },
- { UQQmode, "uqq" },
- { HQmode, "hq" },
- { UHQmode, "uhq" },
- { SQmode, "sq" },
- { USQmode, "usq" },
- { DQmode, "dq" },
- { UDQmode, "udq" },
- { TQmode, "tq" },
- { UTQmode, "utq" },
- { HAmode, "ha" },
- { UHAmode, "uha" },
- { SAmode, "sa" },
- { USAmode, "usa" },
- { DAmode, "da" },
- { UDAmode, "uda" },
- { TAmode, "ta" },
- { UTAmode, "uta" }
- };
- const arm_fixed_mode_set fixed_conv_modes[] =
- {
- { QQmode, "qq" },
- { UQQmode, "uqq" },
- { HQmode, "hq" },
- { UHQmode, "uhq" },
- { SQmode, "sq" },
- { USQmode, "usq" },
- { DQmode, "dq" },
- { UDQmode, "udq" },
- { TQmode, "tq" },
- { UTQmode, "utq" },
- { HAmode, "ha" },
- { UHAmode, "uha" },
- { SAmode, "sa" },
- { USAmode, "usa" },
- { DAmode, "da" },
- { UDAmode, "uda" },
- { TAmode, "ta" },
- { UTAmode, "uta" },
- { QImode, "qi" },
- { HImode, "hi" },
- { SImode, "si" },
- { DImode, "di" },
- { TImode, "ti" },
- { SFmode, "sf" },
- { DFmode, "df" }
- };
- unsigned int i, j;
-
- for (i = 0; i < ARRAY_SIZE (fixed_arith_modes); i++)
- {
- arm_set_fixed_optab_libfunc (add_optab, fixed_arith_modes[i].mode,
- "add", fixed_arith_modes[i].name, 3);
- arm_set_fixed_optab_libfunc (ssadd_optab, fixed_arith_modes[i].mode,
- "ssadd", fixed_arith_modes[i].name, 3);
- arm_set_fixed_optab_libfunc (usadd_optab, fixed_arith_modes[i].mode,
- "usadd", fixed_arith_modes[i].name, 3);
- arm_set_fixed_optab_libfunc (sub_optab, fixed_arith_modes[i].mode,
- "sub", fixed_arith_modes[i].name, 3);
- arm_set_fixed_optab_libfunc (sssub_optab, fixed_arith_modes[i].mode,
- "sssub", fixed_arith_modes[i].name, 3);
- arm_set_fixed_optab_libfunc (ussub_optab, fixed_arith_modes[i].mode,
- "ussub", fixed_arith_modes[i].name, 3);
- arm_set_fixed_optab_libfunc (smul_optab, fixed_arith_modes[i].mode,
- "mul", fixed_arith_modes[i].name, 3);
- arm_set_fixed_optab_libfunc (ssmul_optab, fixed_arith_modes[i].mode,
- "ssmul", fixed_arith_modes[i].name, 3);
- arm_set_fixed_optab_libfunc (usmul_optab, fixed_arith_modes[i].mode,
- "usmul", fixed_arith_modes[i].name, 3);
- arm_set_fixed_optab_libfunc (sdiv_optab, fixed_arith_modes[i].mode,
- "div", fixed_arith_modes[i].name, 3);
- arm_set_fixed_optab_libfunc (udiv_optab, fixed_arith_modes[i].mode,
- "udiv", fixed_arith_modes[i].name, 3);
- arm_set_fixed_optab_libfunc (ssdiv_optab, fixed_arith_modes[i].mode,
- "ssdiv", fixed_arith_modes[i].name, 3);
- arm_set_fixed_optab_libfunc (usdiv_optab, fixed_arith_modes[i].mode,
- "usdiv", fixed_arith_modes[i].name, 3);
- arm_set_fixed_optab_libfunc (neg_optab, fixed_arith_modes[i].mode,
- "neg", fixed_arith_modes[i].name, 2);
- arm_set_fixed_optab_libfunc (ssneg_optab, fixed_arith_modes[i].mode,
- "ssneg", fixed_arith_modes[i].name, 2);
- arm_set_fixed_optab_libfunc (usneg_optab, fixed_arith_modes[i].mode,
- "usneg", fixed_arith_modes[i].name, 2);
- arm_set_fixed_optab_libfunc (ashl_optab, fixed_arith_modes[i].mode,
- "ashl", fixed_arith_modes[i].name, 3);
- arm_set_fixed_optab_libfunc (ashr_optab, fixed_arith_modes[i].mode,
- "ashr", fixed_arith_modes[i].name, 3);
- arm_set_fixed_optab_libfunc (lshr_optab, fixed_arith_modes[i].mode,
- "lshr", fixed_arith_modes[i].name, 3);
- arm_set_fixed_optab_libfunc (ssashl_optab, fixed_arith_modes[i].mode,
- "ssashl", fixed_arith_modes[i].name, 3);
- arm_set_fixed_optab_libfunc (usashl_optab, fixed_arith_modes[i].mode,
- "usashl", fixed_arith_modes[i].name, 3);
- arm_set_fixed_optab_libfunc (cmp_optab, fixed_arith_modes[i].mode,
- "cmp", fixed_arith_modes[i].name, 2);
- }
-
- for (i = 0; i < ARRAY_SIZE (fixed_conv_modes); i++)
- for (j = 0; j < ARRAY_SIZE (fixed_conv_modes); j++)
- {
- if (i == j
- || (!ALL_FIXED_POINT_MODE_P (fixed_conv_modes[i].mode)
- && !ALL_FIXED_POINT_MODE_P (fixed_conv_modes[j].mode)))
- continue;
-
- arm_set_fixed_conv_libfunc (fract_optab, fixed_conv_modes[i].mode,
- fixed_conv_modes[j].mode, "fract",
- fixed_conv_modes[i].name,
- fixed_conv_modes[j].name);
- arm_set_fixed_conv_libfunc (satfract_optab,
- fixed_conv_modes[i].mode,
- fixed_conv_modes[j].mode, "satfract",
- fixed_conv_modes[i].name,
- fixed_conv_modes[j].name);
- arm_set_fixed_conv_libfunc (fractuns_optab,
- fixed_conv_modes[i].mode,
- fixed_conv_modes[j].mode, "fractuns",
- fixed_conv_modes[i].name,
- fixed_conv_modes[j].name);
- arm_set_fixed_conv_libfunc (satfractuns_optab,
- fixed_conv_modes[i].mode,
- fixed_conv_modes[j].mode, "satfractuns",
- fixed_conv_modes[i].name,
- fixed_conv_modes[j].name);
- }
- }
-
- if (TARGET_AAPCS_BASED)
- synchronize_libfunc = init_one_libfunc ("__sync_synchronize");
-}
-
-/* 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 <stdarg.h>. */
- /* Create the type. */
- va_list_type = lang_hooks.types.make_type (RECORD_TYPE);
- /* Give it the required name. */
- va_list_name = build_decl (BUILTINS_LOCATION,
- TYPE_DECL,
- get_identifier ("__va_list"),
- va_list_type);
- DECL_ARTIFICIAL (va_list_name) = 1;
- TYPE_NAME (va_list_type) = va_list_name;
- TYPE_STUB_DECL (va_list_type) = va_list_name;
- /* Create the __ap field. */
- ap_field = build_decl (BUILTINS_LOCATION,
- 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, gimple_seq *pre_p,
- gimple_seq *post_p)
-{
- valist = arm_extract_valist_ptr (valist);
- return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
-}
-
-/* Fix up any incompatible options that the user has specified. */
-static void
-arm_option_override (void)
-{
- if (global_options_set.x_arm_arch_option)
- arm_selected_arch = &all_architectures[arm_arch_option];
-
- if (global_options_set.x_arm_cpu_option)
- arm_selected_cpu = &all_cores[(int) arm_cpu_option];
-
- if (global_options_set.x_arm_tune_option)
- arm_selected_tune = &all_cores[(int) arm_tune_option];
-
-#ifdef SUBTARGET_OVERRIDE_OPTIONS
- SUBTARGET_OVERRIDE_OPTIONS;
-#endif
-
- if (arm_selected_arch)
- {
- if (arm_selected_cpu)
- {
- /* Check for conflict between mcpu and march. */
- if ((arm_selected_cpu->flags ^ arm_selected_arch->flags) & ~FL_TUNE)
- {
- warning (0, "switch -mcpu=%s conflicts with -march=%s switch",
- arm_selected_cpu->name, arm_selected_arch->name);
- /* -march wins for code generation.
- -mcpu wins for default tuning. */
- if (!arm_selected_tune)
- arm_selected_tune = arm_selected_cpu;
-
- arm_selected_cpu = arm_selected_arch;
- }
- else
- /* -mcpu wins. */
- arm_selected_arch = NULL;
- }
- else
- /* Pick a CPU based on the architecture. */
- arm_selected_cpu = arm_selected_arch;
- }
-
- /* If the user did not specify a processor, choose one for them. */
- if (!arm_selected_cpu)
- {
- const struct processors * sel;
- unsigned int sought;
-
- arm_selected_cpu = &all_cores[TARGET_CPU_DEFAULT];
- if (!arm_selected_cpu->name)
- {
-#ifdef SUBTARGET_CPU_DEFAULT
- /* Use the subtarget default CPU if none was specified by
- configure. */
- arm_selected_cpu = &all_cores[SUBTARGET_CPU_DEFAULT];
-#endif
- /* Default to ARM6. */
- if (!arm_selected_cpu->name)
- arm_selected_cpu = &all_cores[arm6];
- }
-
- sel = arm_selected_cpu;
- insn_flags = sel->flags;
-
- /* Now check to see if the user has specified some command line
- switch that require certain abilities from the cpu. */
- sought = 0;
-
- if (TARGET_INTERWORK || TARGET_THUMB)
- {
- sought |= (FL_THUMB | FL_MODE32);
-
- /* There are no ARM processors that support both APCS-26 and
- interworking. Therefore we force FL_MODE26 to be removed
- from insn_flags here (if it was set), so that the search
- below will always be able to find a compatible processor. */
- insn_flags &= ~FL_MODE26;
- }
-
- if (sought != 0 && ((sought & insn_flags) != sought))
- {
- /* Try to locate a CPU type that supports all of the abilities
- of the default CPU, plus the extra abilities requested by
- the user. */
- for (sel = all_cores; sel->name != NULL; sel++)
- if ((sel->flags & sought) == (sought | insn_flags))
- break;
-
- if (sel->name == NULL)
- {
- unsigned current_bit_count = 0;
- const struct processors * best_fit = NULL;
-
- /* Ideally we would like to issue an error message here
- saying that it was not possible to find a CPU compatible
- with the default CPU, but which also supports the command
- line options specified by the programmer, and so they
- ought to use the -mcpu=<name> command line option to
- override the default CPU type.
-
- If we cannot find a cpu that has both the
- characteristics of the default cpu and the given
- command line options we scan the array again looking
- for a best match. */
- for (sel = all_cores; sel->name != NULL; sel++)
- if ((sel->flags & sought) == sought)
- {
- unsigned count;
-
- count = bit_count (sel->flags & insn_flags);
-
- if (count >= current_bit_count)
- {
- best_fit = sel;
- current_bit_count = count;
- }
- }
-
- gcc_assert (best_fit);
- sel = best_fit;
- }
-
- arm_selected_cpu = sel;
- }
- }
-
- gcc_assert (arm_selected_cpu);
- /* The selected cpu may be an architecture, so lookup tuning by core ID. */
- if (!arm_selected_tune)
- arm_selected_tune = &all_cores[arm_selected_cpu->core];
-
- sprintf (arm_arch_name, "__ARM_ARCH_%s__", arm_selected_cpu->arch);
- insn_flags = arm_selected_cpu->flags;
- arm_base_arch = arm_selected_cpu->base_arch;
-
- arm_tune = arm_selected_tune->core;
- tune_flags = arm_selected_tune->flags;
- current_tune = arm_selected_tune->tune;
-
- /* 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");
-
- /* 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;
- }
-
- if (TARGET_THUMB && !(insn_flags & FL_THUMB))
- {
- warning (0, "target CPU does not support THUMB instructions");
- target_flags &= ~MASK_THUMB;
- }
-
- if (TARGET_APCS_FRAME && TARGET_THUMB)
- {
- /* warning (0, "ignoring -mapcs-frame because -mthumb was used"); */
- target_flags &= ~MASK_APCS_FRAME;
- }
-
- /* Callee super interworking implies thumb interworking. Adding
- this to the flags here simplifies the logic elsewhere. */
- if (TARGET_THUMB && TARGET_CALLEE_INTERWORKING)
- target_flags |= MASK_INTERWORK;
-
- /* TARGET_BACKTRACE calls leaf_function_p, which causes a crash if done
- from here where no function is being compiled currently. */
- if ((TARGET_TPCS_FRAME || TARGET_TPCS_LEAF_FRAME) && TARGET_ARM)
- warning (0, "enabling backtrace support is only meaningful when compiling for the Thumb");
-
- if (TARGET_ARM && TARGET_CALLEE_INTERWORKING)
- warning (0, "enabling callee interworking support is only meaningful when compiling for the Thumb");
-
- if (TARGET_APCS_STACK && !TARGET_APCS_FRAME)
- {
- warning (0, "-mapcs-stack-check incompatible with -mno-apcs-frame");
- target_flags |= MASK_APCS_FRAME;
- }
-
- if (TARGET_POKE_FUNCTION_NAME)
- target_flags |= MASK_APCS_FRAME;
-
- if (TARGET_APCS_REENT && flag_pic)
- error ("-fpic and -mapcs-reent are incompatible");
-
- if (TARGET_APCS_REENT)
- warning (0, "APCS reentrant code not supported. Ignored");
-
- /* If this target is normally configured to use APCS frames, warn if they
- are turned off and debugging is turned on. */
- if (TARGET_ARM
- && write_symbols != NO_DEBUG
- && !TARGET_APCS_FRAME
- && (TARGET_DEFAULT & MASK_APCS_FRAME))
- warning (0, "-g with -mno-apcs-frame may not give sensible debugging");
-
- if (TARGET_APCS_FLOAT)
- warning (0, "passing floating point arguments in fp regs not yet supported");
-
- if (TARGET_LITTLE_WORDS)
- warning (OPT_Wdeprecated, "%<mwords-little-endian%> is deprecated and "
- "will be removed in a future release");
-
- /* Initialize boolean versions of the flags, for use in the arm.md file. */
- arm_arch3m = (insn_flags & FL_ARCH3M) != 0;
- arm_arch4 = (insn_flags & FL_ARCH4) != 0;
- arm_arch4t = arm_arch4 & ((insn_flags & FL_THUMB) != 0);
- arm_arch5 = (insn_flags & FL_ARCH5) != 0;
- arm_arch5e = (insn_flags & FL_ARCH5E) != 0;
- arm_arch6 = (insn_flags & FL_ARCH6) != 0;
- arm_arch6k = (insn_flags & FL_ARCH6K) != 0;
- arm_arch_notm = (insn_flags & FL_NOTM) != 0;
- arm_arch6m = arm_arch6 && !arm_arch_notm;
- arm_arch7 = (insn_flags & FL_ARCH7) != 0;
- arm_arch7em = (insn_flags & FL_ARCH7EM) != 0;
- arm_arch8 = (insn_flags & FL_ARCH8) != 0;
- arm_arch_thumb2 = (insn_flags & FL_THUMB2) != 0;
- arm_arch_xscale = (insn_flags & FL_XSCALE) != 0;
-
- arm_ld_sched = (tune_flags & FL_LDSCHED) != 0;
- arm_tune_strongarm = (tune_flags & FL_STRONG) != 0;
- thumb_code = TARGET_ARM == 0;
- thumb1_code = TARGET_THUMB1 != 0;
- arm_tune_wbuf = (tune_flags & FL_WBUF) != 0;
- arm_tune_xscale = (tune_flags & FL_XSCALE) != 0;
- arm_arch_iwmmxt = (insn_flags & FL_IWMMXT) != 0;
- arm_arch_iwmmxt2 = (insn_flags & FL_IWMMXT2) != 0;
- arm_arch_thumb_hwdiv = (insn_flags & FL_THUMB_DIV) != 0;
- arm_arch_arm_hwdiv = (insn_flags & FL_ARM_DIV) != 0;
- arm_tune_cortex_a9 = (arm_tune == cortexa9) != 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. */
-
- /* XXX However, we must pass the right pre-processor defines to CPP
- or GLD can get confused. This is a hack. */
- if (TARGET_INTERWORK)
- arm_cpp_interwork = 1;
-
- if (arm_arch5)
- target_flags &= ~MASK_INTERWORK;
-
- if (TARGET_IWMMXT && !ARM_DOUBLEWORD_ALIGN)
- error ("iwmmxt requires an AAPCS compatible ABI for proper operation");
-
- if (TARGET_IWMMXT_ABI && !TARGET_IWMMXT)
- error ("iwmmxt abi requires an iwmmxt capable cpu");
-
- if (!global_options_set.x_arm_fpu_index)
- {
- const char *target_fpu_name;
- bool ok;
-
-#ifdef FPUTYPE_DEFAULT
- target_fpu_name = FPUTYPE_DEFAULT;
-#else
- target_fpu_name = "vfp";
-#endif
-
- ok = opt_enum_arg_to_value (OPT_mfpu_, target_fpu_name, &arm_fpu_index,
- CL_TARGET);
- gcc_assert (ok);
- }
-
- arm_fpu_desc = &all_fpus[arm_fpu_index];
-
- switch (arm_fpu_desc->model)
- {
- case ARM_FP_MODEL_VFP:
- arm_fpu_attr = FPU_VFP;
- break;
-
- default:
- gcc_unreachable();
- }
-
- if (TARGET_AAPCS_BASED)
- {
- if (TARGET_CALLER_INTERWORKING)
- error ("AAPCS does not support -mcaller-super-interworking");
- else
- if (TARGET_CALLEE_INTERWORKING)
- error ("AAPCS does not support -mcallee-super-interworking");
- }
-
- /* iWMMXt and NEON are incompatible. */
- if (TARGET_IWMMXT && TARGET_NEON)
- error ("iWMMXt and NEON are incompatible");
-
- /* iWMMXt unsupported under Thumb mode. */
- if (TARGET_THUMB && TARGET_IWMMXT)
- error ("iWMMXt unsupported under Thumb mode");
-
- /* __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_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 we are doing
- software floating-point. */
- if (TARGET_SOFT_FLOAT && (tune_flags & FL_MODE32) == 0)
- flag_schedule_insns = flag_schedule_insns_after_reload = 0;
-
- /* Use the cp15 method if it is available. */
- if (target_thread_pointer == TP_AUTO)
- {
- if (arm_arch6k && !TARGET_THUMB1)
- target_thread_pointer = TP_CP15;
- else
- target_thread_pointer = TP_SOFT;
- }
-
- if (TARGET_HARD_TP && TARGET_THUMB1)
- error ("can not use -mtp=cp15 with 16-bit Thumb");
-
- /* Override the default structure alignment for AAPCS ABI. */
- if (!global_options_set.x_arm_structure_size_boundary)
- {
- if (TARGET_AAPCS_BASED)
- arm_structure_size_boundary = 8;
- }
- else
- {
- if (arm_structure_size_boundary != 8
- && arm_structure_size_boundary != 32
- && !(ARM_DOUBLEWORD_ALIGN && arm_structure_size_boundary == 64))
- {
- if (ARM_DOUBLEWORD_ALIGN)
- warning (0,
- "structure size boundary can only be set to 8, 32 or 64");
- else
- warning (0, "structure size boundary can only be set to 8 or 32");
- arm_structure_size_boundary
- = (TARGET_AAPCS_BASED ? 8 : DEFAULT_STRUCTURE_SIZE_BOUNDARY);
- }
- }
-
- if (!TARGET_ARM && TARGET_VXWORKS_RTP && flag_pic)
- {
- error ("RTP PIC is incompatible with Thumb");
- flag_pic = 0;
- }
-
- /* If stack checking is disabled, we can use r10 as the PIC register,
- which keeps r9 available. The EABI specifies r9 as the PIC register. */
- if (flag_pic && TARGET_SINGLE_PIC_BASE)
- {
- if (TARGET_VXWORKS_RTP)
- warning (0, "RTP PIC is incompatible with -msingle-pic-base");
- arm_pic_register = (TARGET_APCS_STACK || TARGET_AAPCS_BASED) ? 9 : 10;
- }
-
- if (flag_pic && TARGET_VXWORKS_RTP)
- arm_pic_register = 9;
-
- if (arm_pic_register_string != NULL)
- {
- int pic_register = decode_reg_name (arm_pic_register_string);
-
- if (!flag_pic)
- warning (0, "-mpic-register= is useless without -fpic");
-
- /* Prevent the user from choosing an obviously stupid PIC register. */
- else if (pic_register < 0 || call_used_regs[pic_register]
- || pic_register == HARD_FRAME_POINTER_REGNUM
- || pic_register == STACK_POINTER_REGNUM
- || pic_register >= PC_REGNUM
- || (TARGET_VXWORKS_RTP
- && (unsigned int) pic_register != arm_pic_register))
- error ("unable to use '%s' for PIC register", arm_pic_register_string);
- else
- arm_pic_register = pic_register;
- }
-
- /* Enable -mfix-cortex-m3-ldrd by default for Cortex-M3 cores. */
- if (fix_cm3_ldrd == 2)
- {
- if (arm_selected_cpu->core == cortexm3)
- fix_cm3_ldrd = 1;
- else
- fix_cm3_ldrd = 0;
- }
-
- /* Enable -munaligned-access by default for
- - all ARMv6 architecture-based processors
- - ARMv7-A, ARMv7-R, and ARMv7-M architecture-based processors.
- - ARMv8 architecture-base processors.
-
- Disable -munaligned-access by default for
- - all pre-ARMv6 architecture-based processors
- - ARMv6-M architecture-based processors. */
-
- if (unaligned_access == 2)
- {
- if (arm_arch6 && (arm_arch_notm || arm_arch7))
- unaligned_access = 1;
- else
- unaligned_access = 0;
- }
- else if (unaligned_access == 1
- && !(arm_arch6 && (arm_arch_notm || arm_arch7)))
- {
- warning (0, "target CPU does not support unaligned accesses");
- unaligned_access = 0;
- }
-
- if (TARGET_THUMB1 && flag_schedule_insns)
- {
- /* Don't warn since it's on by default in -O2. */
- flag_schedule_insns = 0;
- }
-
- if (optimize_size)
- {
- /* If optimizing for size, bump the number of instructions that we
- are prepared to conditionally execute (even on a StrongARM). */
- max_insns_skipped = 6;
- }
- else
- max_insns_skipped = current_tune->max_insns_skipped;
-
- /* Hot/Cold partitioning is not currently supported, since we can't
- handle literal pool placement in that case. */
- if (flag_reorder_blocks_and_partition)
- {
- inform (input_location,
- "-freorder-blocks-and-partition not supported on this architecture");
- flag_reorder_blocks_and_partition = 0;
- flag_reorder_blocks = 1;
- }
-
- if (flag_pic)
- /* Hoisting PIC address calculations more aggressively provides a small,
- but measurable, size reduction for PIC code. Therefore, we decrease
- the bar for unrestricted expression hoisting to the cost of PIC address
- calculation, which is 2 instructions. */
- maybe_set_param_value (PARAM_GCSE_UNRESTRICTED_COST, 2,
- global_options.x_param_values,
- global_options_set.x_param_values);
-
- /* ARM EABI defaults to strict volatile bitfields. */
- if (TARGET_AAPCS_BASED && flag_strict_volatile_bitfields < 0
- && abi_version_at_least(2))
- flag_strict_volatile_bitfields = 1;
-
- /* Enable sw prefetching at -O3 for CPUS that have prefetch, and we have deemed
- it beneficial (signified by setting num_prefetch_slots to 1 or more.) */
- if (flag_prefetch_loop_arrays < 0
- && HAVE_prefetch
- && optimize >= 3
- && current_tune->num_prefetch_slots > 0)
- flag_prefetch_loop_arrays = 1;
-
- /* Set up parameters to be used in prefetching algorithm. Do not override the
- defaults unless we are tuning for a core we have researched values for. */
- if (current_tune->num_prefetch_slots > 0)
- maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES,
- current_tune->num_prefetch_slots,
- global_options.x_param_values,
- global_options_set.x_param_values);
- if (current_tune->l1_cache_line_size >= 0)
- maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE,
- current_tune->l1_cache_line_size,
- global_options.x_param_values,
- global_options_set.x_param_values);
- if (current_tune->l1_cache_size >= 0)
- maybe_set_param_value (PARAM_L1_CACHE_SIZE,
- current_tune->l1_cache_size,
- global_options.x_param_values,
- global_options_set.x_param_values);
-
- /* Use the alternative scheduling-pressure algorithm by default. */
- maybe_set_param_value (PARAM_SCHED_PRESSURE_ALGORITHM, 2,
- global_options.x_param_values,
- global_options_set.x_param_values);
-
- /* Register global variables with the garbage collector. */
- arm_add_gc_roots ();
-}
-
-static void
-arm_add_gc_roots (void)
-{
- gcc_obstack_init(&minipool_obstack);
- minipool_startobj = (char *) obstack_alloc (&minipool_obstack, 0);
-}
-
-/* A table of known ARM exception types.
- For use with the interrupt function attribute. */
-
-typedef struct
-{
- const char *const arg;
- const unsigned long return_value;
-}
-isr_attribute_arg;
-
-static const isr_attribute_arg isr_attribute_args [] =
-{
- { "IRQ", ARM_FT_ISR },
- { "irq", ARM_FT_ISR },
- { "FIQ", ARM_FT_FIQ },
- { "fiq", ARM_FT_FIQ },
- { "ABORT", ARM_FT_ISR },
- { "abort", ARM_FT_ISR },
- { "ABORT", ARM_FT_ISR },
- { "abort", ARM_FT_ISR },
- { "UNDEF", ARM_FT_EXCEPTION },
- { "undef", ARM_FT_EXCEPTION },
- { "SWI", ARM_FT_EXCEPTION },
- { "swi", ARM_FT_EXCEPTION },
- { NULL, ARM_FT_NORMAL }
-};
-
-/* Returns the (interrupt) function type of the current
- function, or ARM_FT_UNKNOWN if the type cannot be determined. */
-
-static unsigned long
-arm_isr_value (tree argument)
-{
- const isr_attribute_arg * ptr;
- const char * arg;
-
- if (!arm_arch_notm)
- return ARM_FT_NORMAL | ARM_FT_STACKALIGN;
-
- /* No argument - default to IRQ. */
- if (argument == NULL_TREE)
- return ARM_FT_ISR;
-
- /* Get the value of the argument. */
- if (TREE_VALUE (argument) == NULL_TREE
- || TREE_CODE (TREE_VALUE (argument)) != STRING_CST)
- return ARM_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 ARM_FT_UNKNOWN;
-}
-
-/* Computes the type of the current function. */
-
-static unsigned long
-arm_compute_func_type (void)
-{
- unsigned long type = ARM_FT_UNKNOWN;
- tree a;
- tree attr;
-
- gcc_assert (TREE_CODE (current_function_decl) == FUNCTION_DECL);
-
- /* 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)
- || !(flag_unwind_tables
- || (flag_exceptions
- && arm_except_unwind_info (&global_options) != UI_SJLJ)))
- && TREE_THIS_VOLATILE (current_function_decl))
- type |= ARM_FT_VOLATILE;
-
- if (cfun->static_chain_decl != NULL)
- type |= ARM_FT_NESTED;
-
- attr = DECL_ATTRIBUTES (current_function_decl);
-
- a = lookup_attribute ("naked", attr);
- if (a != NULL_TREE)
- type |= ARM_FT_NAKED;
-
- a = lookup_attribute ("isr", attr);
- if (a == NULL_TREE)
- a = lookup_attribute ("interrupt", attr);
-
- if (a == NULL_TREE)
- type |= TARGET_INTERWORK ? ARM_FT_INTERWORKED : ARM_FT_NORMAL;
- else
- type |= arm_isr_value (TREE_VALUE (a));
-
- return type;
-}
-
-/* Returns the type of the current function. */
-
-unsigned long
-arm_current_func_type (void)
-{
- if (ARM_FUNC_TYPE (cfun->machine->func_type) == ARM_FT_UNKNOWN)
- cfun->machine->func_type = arm_compute_func_type ();
-
- 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 ());
-}
-
-static bool
-arm_warn_func_return (tree decl)
-{
- /* Naked functions are implemented entirely in assembly, including the
- return sequence, so suppress warnings about this. */
- return lookup_attribute ("naked", DECL_ATTRIBUTES (decl)) == NULL_TREE;
-}
-
-
-/* Output assembler code for a block containing the constant parts
- of a trampoline, leaving space for the variable parts.
-
- On the ARM, (if r8 is the static chain regnum, and remembering that
- referencing pc adds an offset of 8) the trampoline looks like:
- ldr r8, [pc, #0]
- ldr pc, [pc]
- .word static chain value
- .word function's address
- XXX FIXME: When the trampoline returns, r8 will be clobbered. */
-
-static void
-arm_asm_trampoline_template (FILE *f)
-{
- if (TARGET_ARM)
- {
- asm_fprintf (f, "\tldr\t%r, [%r, #0]\n", STATIC_CHAIN_REGNUM, PC_REGNUM);
- asm_fprintf (f, "\tldr\t%r, [%r, #0]\n", PC_REGNUM, PC_REGNUM);
- }
- else if (TARGET_THUMB2)
- {
- /* The Thumb-2 trampoline is similar to the arm implementation.
- Unlike 16-bit Thumb, we enter the stub in thumb mode. */
- asm_fprintf (f, "\tldr.w\t%r, [%r, #4]\n",
- STATIC_CHAIN_REGNUM, PC_REGNUM);
- asm_fprintf (f, "\tldr.w\t%r, [%r, #4]\n", PC_REGNUM, PC_REGNUM);
- }
- else
- {
- ASM_OUTPUT_ALIGN (f, 2);
- fprintf (f, "\t.code\t16\n");
- fprintf (f, ".Ltrampoline_start:\n");
- asm_fprintf (f, "\tpush\t{r0, r1}\n");
- asm_fprintf (f, "\tldr\tr0, [%r, #8]\n", PC_REGNUM);
- asm_fprintf (f, "\tmov\t%r, r0\n", STATIC_CHAIN_REGNUM);
- asm_fprintf (f, "\tldr\tr0, [%r, #8]\n", PC_REGNUM);
- asm_fprintf (f, "\tstr\tr0, [%r, #4]\n", SP_REGNUM);
- asm_fprintf (f, "\tpop\t{r0, %r}\n", PC_REGNUM);
- }
- assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
- assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
-}
-
-/* Emit RTL insns to initialize the variable parts of a trampoline. */
-
-static void
-arm_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
-{
- rtx fnaddr, mem, a_tramp;
-
- emit_block_move (m_tramp, assemble_trampoline_template (),
- GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
-
- mem = adjust_address (m_tramp, SImode, TARGET_32BIT ? 8 : 12);
- emit_move_insn (mem, chain_value);
-
- mem = adjust_address (m_tramp, SImode, TARGET_32BIT ? 12 : 16);
- fnaddr = XEXP (DECL_RTL (fndecl), 0);
- emit_move_insn (mem, fnaddr);
-
- a_tramp = XEXP (m_tramp, 0);
- emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__clear_cache"),
- LCT_NORMAL, VOIDmode, 2, a_tramp, Pmode,
- plus_constant (Pmode, a_tramp, TRAMPOLINE_SIZE), Pmode);
-}
-
-/* Thumb trampolines should be entered in thumb mode, so set
- the bottom bit of the address. */
-
-static rtx
-arm_trampoline_adjust_address (rtx addr)
-{
- if (TARGET_THUMB)
- addr = expand_simple_binop (Pmode, IOR, addr, const1_rtx,
- NULL, 0, OPTAB_LIB_WIDEN);
- return addr;
-}
-
-/* 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
- call. SIBLING is the call insn, so we can examine its register usage. */
-
-int
-use_return_insn (int iscond, rtx sibling)
-{
- int regno;
- unsigned int func_type;
- unsigned long saved_int_regs;
- unsigned HOST_WIDE_INT stack_adjust;
- arm_stack_offsets *offsets;
-
- /* Never use a return instruction before reload has run. */
- if (!reload_completed)
- return 0;
-
- func_type = arm_current_func_type ();
-
- /* Naked, volatile and stack alignment functions need special
- consideration. */
- if (func_type & (ARM_FT_VOLATILE | ARM_FT_NAKED | ARM_FT_STACKALIGN))
- return 0;
-
- /* So do interrupt functions that use the frame pointer and Thumb
- interrupt functions. */
- if (IS_INTERRUPT (func_type) && (frame_pointer_needed || TARGET_THUMB))
- return 0;
-
- offsets = arm_get_frame_offsets ();
- stack_adjust = offsets->outgoing_args - offsets->saved_regs;
-
- /* As do variadic functions. */
- if (crtl->args.pretend_args_size
- || cfun->machine->uses_anonymous_args
- /* Or if the function calls __builtin_eh_return () */
- || crtl->calls_eh_return
- /* Or if the function calls alloca */
- || cfun->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 || (TARGET_APCS_FRAME && frame_pointer_needed
- && stack_adjust == 4)))
- return 0;
-
- saved_int_regs = offsets->saved_regs_mask;
-
- /* Unfortunately, the insn
-
- ldmib sp, {..., sp, ...}
-
- triggers a bug on most SA-110 based devices, such that the stack
- pointer won't be correctly restored if the instruction takes a
- page fault. We work around this problem by popping r3 along with
- the other registers, since that is never slower than executing
- another instruction.
-
- We test for !arm_arch5 here, because code for any architecture
- less than this could potentially be run on one of the buggy
- chips. */
- if (stack_adjust == 4 && !arm_arch5 && TARGET_ARM)
- {
- /* Validate that r3 is a call-clobbered register (always true in
- the default abi) ... */
- if (!call_used_regs[3])
- return 0;
-
- /* ... that it isn't being used for a return value ... */
- if (arm_size_return_regs () >= (4 * UNITS_PER_WORD))
- return 0;
-
- /* ... or for a tail-call argument ... */
- if (sibling)
- {
- gcc_assert (CALL_P (sibling));
-
- if (find_regno_fusage (sibling, USE, 3))
- return 0;
- }
-
- /* ... and that there are no call-saved registers in r0-r2
- (always true in the default ABI). */
- if (saved_int_regs & 0x7)
- return 0;
- }
-
- /* Can't be done if interworking with Thumb, and any registers have been
- stacked. */
- if (TARGET_INTERWORK && saved_int_regs != 0 && !IS_INTERRUPT(func_type))
- return 0;
-
- /* On StrongARM, conditional returns are expensive if they aren't
- taken and multiple registers have been stacked. */
- if (iscond && arm_tune_strongarm)
- {
- /* Conditional return when just the LR is stored is a simple
- conditional-load instruction, that's not expensive. */
- if (saved_int_regs != 0 && saved_int_regs != (1 << LR_REGNUM))
- return 0;
-
- if (flag_pic
- && arm_pic_register != INVALID_REGNUM
- && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM))
- 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 << LR_REGNUM)))
- return 0;
-
- /* Can't be done if any of the VFP regs are pushed,
- since this also requires an insn. */
- if (TARGET_HARD_FLOAT && TARGET_VFP)
- for (regno = FIRST_VFP_REGNUM; regno <= LAST_VFP_REGNUM; regno++)
- if (df_regs_ever_live_p (regno) && !call_used_regs[regno])
- return 0;
-
- if (TARGET_REALLY_IWMMXT)
- for (regno = FIRST_IWMMXT_REGNUM; regno <= LAST_IWMMXT_REGNUM; regno++)
- if (df_regs_ever_live_p (regno) && ! call_used_regs[regno])
- return 0;
-
- return 1;
-}
-
-/* Return TRUE if int I is a valid immediate ARM constant. */
-
-int
-const_ok_for_arm (HOST_WIDE_INT i)
-{
- int lowbit;
-
- /* For machines with >32 bit HOST_WIDE_INT, the bits above bit 31 must
- be all zero, or all one. */
- if ((i & ~(unsigned HOST_WIDE_INT) 0xffffffff) != 0
- && ((i & ~(unsigned HOST_WIDE_INT) 0xffffffff)
- != ((~(unsigned HOST_WIDE_INT) 0)
- & ~(unsigned HOST_WIDE_INT) 0xffffffff)))
- return FALSE;
-
- i &= (unsigned HOST_WIDE_INT) 0xffffffff;
-
- /* Fast return for 0 and small values. We must do this for zero, since
- the code below can't handle that one case. */
- if ((i & ~(unsigned HOST_WIDE_INT) 0xff) == 0)
- return TRUE;
-
- /* Get the number of trailing zeros. */
- lowbit = ffs((int) i) - 1;
-
- /* Only even shifts are allowed in ARM mode so round down to the
- nearest even number. */
- if (TARGET_ARM)
- lowbit &= ~1;
-
- if ((i & ~(((unsigned HOST_WIDE_INT) 0xff) << lowbit)) == 0)
- return TRUE;
-
- if (TARGET_ARM)
- {
- /* Allow rotated constants in ARM mode. */
- if (lowbit <= 4
- && ((i & ~0xc000003f) == 0
- || (i & ~0xf000000f) == 0
- || (i & ~0xfc000003) == 0))
- return TRUE;
- }
- else
- {
- HOST_WIDE_INT v;
-
- /* Allow repeated patterns 0x00XY00XY or 0xXYXYXYXY. */
- v = i & 0xff;
- v |= v << 16;
- if (i == v || i == (v | (v << 8)))
- return TRUE;
-
- /* Allow repeated pattern 0xXY00XY00. */
- v = i & 0xff00;
- v |= v << 16;
- if (i == v)
- return TRUE;
- }
-
- return FALSE;
-}
-
-/* Return true if I is a valid constant for the operation CODE. */
-int
-const_ok_for_op (HOST_WIDE_INT i, enum rtx_code code)
-{
- if (const_ok_for_arm (i))
- return 1;
-
- switch (code)
- {
- case SET:
- /* See if we can use movw. */
- if (arm_arch_thumb2 && (i & 0xffff0000) == 0)
- return 1;
- else
- /* Otherwise, try mvn. */
- return const_ok_for_arm (ARM_SIGN_EXTEND (~i));
-
- case PLUS:
- /* See if we can use addw or subw. */
- if (TARGET_THUMB2
- && ((i & 0xfffff000) == 0
- || ((-i) & 0xfffff000) == 0))
- return 1;
- /* else fall through. */
-
- 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 */
- case XOR:
- return 0;
-
- case IOR:
- if (TARGET_THUMB2)
- return const_ok_for_arm (ARM_SIGN_EXTEND (~i));
- return 0;
-
- case AND:
- return const_ok_for_arm (ARM_SIGN_EXTEND (~i));
-
- default:
- gcc_unreachable ();
- }
-}
-
-/* Return true if I is a valid di mode constant for the operation CODE. */
-int
-const_ok_for_dimode_op (HOST_WIDE_INT i, enum rtx_code code)
-{
- HOST_WIDE_INT hi_val = (i >> 32) & 0xFFFFFFFF;
- HOST_WIDE_INT lo_val = i & 0xFFFFFFFF;
- rtx hi = GEN_INT (hi_val);
- rtx lo = GEN_INT (lo_val);
-
- if (TARGET_THUMB1)
- return 0;
-
- switch (code)
- {
- case PLUS:
- return arm_not_operand (hi, SImode) && arm_add_operand (lo, SImode);
-
- default:
- return 0;
- }
-}
-
-/* Emit a sequence of insns to handle a large constant.
- CODE is the code of the operation required, it can be any of SET, PLUS,
- IOR, AND, XOR, MINUS;
- MODE is the mode in which the operation is being performed;
- VAL is the integer to operate on;
- SOURCE is the other operand (a register, or a null-pointer for SET);
- SUBTARGETS means it is safe to create scratch registers if that will
- either produce a simpler sequence, or we will want to cse the values.
- Return value is the number of insns emitted. */
-
-/* ??? Tweak this for thumb2. */
-int
-arm_split_constant (enum rtx_code code, enum machine_mode mode, rtx insn,
- HOST_WIDE_INT val, rtx target, rtx source, int subtargets)
-{
- rtx cond;
-
- if (insn && GET_CODE (PATTERN (insn)) == COND_EXEC)
- cond = COND_EXEC_TEST (PATTERN (insn));
- else
- cond = NULL_RTX;
-
- if (subtargets || code == SET
- || (REG_P (target) && REG_P (source)
- && REGNO (target) != REGNO (source)))
- {
- /* After arm_reorg has been called, we can't fix up expensive
- constants by pushing them into memory so we must synthesize
- them in-line, regardless of the cost. This is only likely to
- be more costly on chips that have load delay slots and we are
- compiling without running the scheduler (so no splitting
- occurred before the final instruction emission).
-
- Ref: gcc -O1 -mcpu=strongarm gcc.c-torture/compile/980506-2.c
- */
- if (!after_arm_reorg
- && !cond
- && (arm_gen_constant (code, mode, NULL_RTX, val, target, source,
- 1, 0)
- > (arm_constant_limit (optimize_function_for_size_p (cfun))
- + (code != SET))))
- {
- if (code == SET)
- {
- /* Currently SET is the only monadic value for CODE, all
- the rest are diadic. */
- 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;
-
- 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)
- emit_set_insn (target, gen_rtx_MINUS (mode, temp, source));
- else
- emit_set_insn (target,
- gen_rtx_fmt_ee (code, mode, source, temp));
- return 2;
- }
- }
- }
-
- return arm_gen_constant (code, mode, cond, val, target, source, subtargets,
- 1);
-}
-
-/* Return a sequence of integers, in RETURN_SEQUENCE that fit into
- ARM/THUMB2 immediates, and add up to VAL.
- Thr function return value gives the number of insns required. */
-static int
-optimal_immediate_sequence (enum rtx_code code, unsigned HOST_WIDE_INT val,
- struct four_ints *return_sequence)
-{
- int best_consecutive_zeros = 0;
- int i;
- int best_start = 0;
- int insns1, insns2;
- struct four_ints tmp_sequence;
-
- /* If we aren't targeting ARM, the best place to start is always at
- the bottom, otherwise look more closely. */
- if (TARGET_ARM)
- {
- for (i = 0; i < 32; i += 2)
- {
- int consecutive_zeros = 0;
-
- if (!(val & (3 << i)))
- {
- while ((i < 32) && !(val & (3 << i)))
- {
- consecutive_zeros += 2;
- i += 2;
- }
- if (consecutive_zeros > best_consecutive_zeros)
- {
- best_consecutive_zeros = consecutive_zeros;
- best_start = i - consecutive_zeros;
- }
- i -= 2;
- }
- }
- }
-
- /* So long as it won't require any more insns to do so, it's
- desirable to emit a small constant (in bits 0...9) in the last
- insn. This way there is more chance that it can be combined with
- a later addressing insn to form a pre-indexed load or store
- operation. Consider:
-
- *((volatile int *)0xe0000100) = 1;
- *((volatile int *)0xe0000110) = 2;
-
- We want this to wind up as:
-
- mov rA, #0xe0000000
- mov rB, #1
- str rB, [rA, #0x100]
- mov rB, #2
- str rB, [rA, #0x110]
-
- rather than having to synthesize both large constants from scratch.
-
- Therefore, we calculate how many insns would be required to emit
- the constant starting from `best_start', and also starting from
- zero (i.e. with bit 31 first to be output). If `best_start' doesn't
- yield a shorter sequence, we may as well use zero. */
- insns1 = optimal_immediate_sequence_1 (code, val, return_sequence, best_start);
- if (best_start != 0
- && ((((unsigned HOST_WIDE_INT) 1) << best_start) < val))
- {
- insns2 = optimal_immediate_sequence_1 (code, val, &tmp_sequence, 0);
- if (insns2 <= insns1)
- {
- *return_sequence = tmp_sequence;
- insns1 = insns2;
- }
- }
-
- return insns1;
-}
-
-/* As for optimal_immediate_sequence, but starting at bit-position I. */
-static int
-optimal_immediate_sequence_1 (enum rtx_code code, unsigned HOST_WIDE_INT val,
- struct four_ints *return_sequence, int i)
-{
- int remainder = val & 0xffffffff;
- int insns = 0;
-
- /* Try and find a way of doing the job in either two or three
- instructions.
-
- In ARM mode we can use 8-bit constants, rotated to any 2-bit aligned
- location. We start at position I. This may be the MSB, or
- optimial_immediate_sequence may have positioned it at the largest block
- of zeros that are aligned on a 2-bit boundary. We then fill up the temps,
- wrapping around to the top of the word when we drop off the bottom.
- In the worst case this code should produce no more than four insns.
-
- In Thumb2 mode, we can use 32/16-bit replicated constants, and 8-bit
- constants, shifted to any arbitrary location. We should always start
- at the MSB. */
- do
- {
- int end;
- unsigned int b1, b2, b3, b4;
- unsigned HOST_WIDE_INT result;
- int loc;
-
- gcc_assert (insns < 4);
-
- if (i <= 0)
- i += 32;
-
- /* First, find the next normal 12/8-bit shifted/rotated immediate. */
- if (remainder & ((TARGET_ARM ? (3 << (i - 2)) : (1 << (i - 1)))))
- {
- loc = i;
- if (i <= 12 && TARGET_THUMB2 && code == PLUS)
- /* We can use addw/subw for the last 12 bits. */
- result = remainder;
- else
- {
- /* Use an 8-bit shifted/rotated immediate. */
- end = i - 8;
- if (end < 0)
- end += 32;
- result = remainder & ((0x0ff << end)
- | ((i < end) ? (0xff >> (32 - end))
- : 0));
- i -= 8;
- }
- }
- else
- {
- /* Arm allows rotates by a multiple of two. Thumb-2 allows
- arbitrary shifts. */
- i -= TARGET_ARM ? 2 : 1;
- continue;
- }
-
- /* Next, see if we can do a better job with a thumb2 replicated
- constant.
-
- We do it this way around to catch the cases like 0x01F001E0 where
- two 8-bit immediates would work, but a replicated constant would
- make it worse.
-
- TODO: 16-bit constants that don't clear all the bits, but still win.
- TODO: Arithmetic splitting for set/add/sub, rather than bitwise. */
- if (TARGET_THUMB2)
- {
- b1 = (remainder & 0xff000000) >> 24;
- b2 = (remainder & 0x00ff0000) >> 16;
- b3 = (remainder & 0x0000ff00) >> 8;
- b4 = remainder & 0xff;
-
- if (loc > 24)
- {
- /* The 8-bit immediate already found clears b1 (and maybe b2),
- but must leave b3 and b4 alone. */
-
- /* First try to find a 32-bit replicated constant that clears
- almost everything. We can assume that we can't do it in one,
- or else we wouldn't be here. */
- unsigned int tmp = b1 & b2 & b3 & b4;
- unsigned int tmp2 = tmp + (tmp << 8) + (tmp << 16)
- + (tmp << 24);
- unsigned int matching_bytes = (tmp == b1) + (tmp == b2)
- + (tmp == b3) + (tmp == b4);
- if (tmp
- && (matching_bytes >= 3
- || (matching_bytes == 2
- && const_ok_for_op (remainder & ~tmp2, code))))
- {
- /* At least 3 of the bytes match, and the fourth has at
- least as many bits set, or two of the bytes match
- and it will only require one more insn to finish. */
- result = tmp2;
- i = tmp != b1 ? 32
- : tmp != b2 ? 24
- : tmp != b3 ? 16
- : 8;
- }
-
- /* Second, try to find a 16-bit replicated constant that can
- leave three of the bytes clear. If b2 or b4 is already
- zero, then we can. If the 8-bit from above would not
- clear b2 anyway, then we still win. */
- else if (b1 == b3 && (!b2 || !b4
- || (remainder & 0x00ff0000 & ~result)))
- {
- result = remainder & 0xff00ff00;
- i = 24;
- }
- }
- else if (loc > 16)
- {
- /* The 8-bit immediate already found clears b2 (and maybe b3)
- and we don't get here unless b1 is alredy clear, but it will
- leave b4 unchanged. */
-
- /* If we can clear b2 and b4 at once, then we win, since the
- 8-bits couldn't possibly reach that far. */
- if (b2 == b4)
- {
- result = remainder & 0x00ff00ff;
- i = 16;
- }
- }
- }
-
- return_sequence->i[insns++] = result;
- remainder &= ~result;
-
- if (code == SET || code == MINUS)
- code = PLUS;
- }
- while (remainder);
-
- return insns;
-}
-
-/* Emit an instruction with the indicated PATTERN. If COND is
- non-NULL, conditionalize the execution of the instruction on COND
- being true. */
-
-static void
-emit_constant_insn (rtx cond, rtx pattern)
-{
- if (cond)
- pattern = gen_rtx_COND_EXEC (VOIDmode, copy_rtx (cond), pattern);
- emit_insn (pattern);
-}
-
-/* As above, but extra parameter GENERATE which, if clear, suppresses
- RTL generation. */
-
-static int
-arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
- HOST_WIDE_INT val, rtx target, rtx source, int subtargets,
- int generate)
-{
- int can_invert = 0;
- int can_negate = 0;
- int final_invert = 0;
- int i;
- int set_sign_bit_copies = 0;
- int clear_sign_bit_copies = 0;
- int clear_zero_bit_copies = 0;
- int set_zero_bit_copies = 0;
- int insns = 0, neg_insns, inv_insns;
- unsigned HOST_WIDE_INT temp1, temp2;
- unsigned HOST_WIDE_INT remainder = val & 0xffffffff;
- struct four_ints *immediates;
- struct four_ints pos_immediates, neg_immediates, inv_immediates;
-
- /* Find out which operations are safe for a given CODE. Also do a quick
- check for degenerate cases; these can occur when DImode operations
- are split. */
- switch (code)
- {
- case SET:
- can_invert = 1;
- break;
-
- case PLUS:
- can_negate = 1;
- break;
-
- case IOR:
- if (remainder == 0xffffffff)
- {
- if (generate)
- emit_constant_insn (cond,
- gen_rtx_SET (VOIDmode, target,
- GEN_INT (ARM_SIGN_EXTEND (val))));
- return 1;
- }
-
- if (remainder == 0)
- {
- if (reload_completed && rtx_equal_p (target, source))
- return 0;
-
- if (generate)
- emit_constant_insn (cond,
- gen_rtx_SET (VOIDmode, target, source));
- return 1;
- }
- break;
-
- case AND:
- if (remainder == 0)
- {
- if (generate)
- emit_constant_insn (cond,
- gen_rtx_SET (VOIDmode, target, const0_rtx));
- return 1;
- }
- if (remainder == 0xffffffff)
- {
- if (reload_completed && rtx_equal_p (target, source))
- return 0;
- if (generate)
- emit_constant_insn (cond,
- gen_rtx_SET (VOIDmode, target, source));
- return 1;
- }
- can_invert = 1;
- break;
-
- case XOR:
- if (remainder == 0)
- {
- if (reload_completed && rtx_equal_p (target, source))
- return 0;
- if (generate)
- emit_constant_insn (cond,
- gen_rtx_SET (VOIDmode, target, source));
- return 1;
- }
-
- if (remainder == 0xffffffff)
- {
- if (generate)
- emit_constant_insn (cond,
- gen_rtx_SET (VOIDmode, target,
- gen_rtx_NOT (mode, source)));
- return 1;
- }
- final_invert = 1;
- break;
-
- case MINUS:
- /* We treat MINUS as (val - source), since (source - val) is always
- passed as (source + (-val)). */
- if (remainder == 0)
- {
- if (generate)
- emit_constant_insn (cond,
- gen_rtx_SET (VOIDmode, target,
- gen_rtx_NEG (mode, source)));
- return 1;
- }
- if (const_ok_for_arm (val))
- {
- if (generate)
- emit_constant_insn (cond,
- gen_rtx_SET (VOIDmode, target,
- gen_rtx_MINUS (mode, GEN_INT (val),
- source)));
- return 1;
- }
-
- break;
-
- default:
- gcc_unreachable ();
- }
-
- /* If we can do it in one insn get out quickly. */
- if (const_ok_for_op (val, code))
- {
- if (generate)
- emit_constant_insn (cond,
- gen_rtx_SET (VOIDmode, target,
- (source
- ? gen_rtx_fmt_ee (code, mode, source,
- GEN_INT (val))
- : GEN_INT (val))));
- return 1;
- }
-
- /* On targets with UXTH/UBFX, we can deal with AND (2^N)-1 in a single
- insn. */
- if (code == AND && (i = exact_log2 (remainder + 1)) > 0
- && (arm_arch_thumb2 || (i == 16 && arm_arch6 && mode == SImode)))
- {
- if (generate)
- {
- if (mode == SImode && i == 16)
- /* Use UXTH in preference to UBFX, since on Thumb2 it's a
- smaller insn. */
- emit_constant_insn (cond,
- gen_zero_extendhisi2
- (target, gen_lowpart (HImode, source)));
- else
- /* Extz only supports SImode, but we can coerce the operands
- into that mode. */
- emit_constant_insn (cond,
- gen_extzv_t2 (gen_lowpart (SImode, target),
- gen_lowpart (SImode, source),
- GEN_INT (i), const0_rtx));
- }
-
- return 1;
- }
-
- /* Calculate a few attributes that may be useful for specific
- optimizations. */
- /* Count number of leading zeros. */
- for (i = 31; i >= 0; i--)
- {
- if ((remainder & (1 << i)) == 0)
- clear_sign_bit_copies++;
- else
- break;
- }
-
- /* Count number of leading 1's. */
- for (i = 31; i >= 0; i--)
- {
- if ((remainder & (1 << i)) != 0)
- set_sign_bit_copies++;
- else
- break;
- }
-
- /* Count number of trailing zero's. */
- for (i = 0; i <= 31; i++)
- {
- if ((remainder & (1 << i)) == 0)
- clear_zero_bit_copies++;
- else
- break;
- }
-
- /* Count number of trailing 1's. */
- for (i = 0; i <= 31; i++)
- {
- if ((remainder & (1 << i)) != 0)
- set_zero_bit_copies++;
- else
- break;
- }
-
- switch (code)
- {
- case SET:
- /* See if we can do this by sign_extending a constant that is known
- to be negative. This is a good, way of doing it, since the shift
- may well merge into a subsequent insn. */
- if (set_sign_bit_copies > 1)
- {
- if (const_ok_for_arm
- (temp1 = ARM_SIGN_EXTEND (remainder
- << (set_sign_bit_copies - 1))))
- {
- if (generate)
- {
- rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
- emit_constant_insn (cond,
- gen_rtx_SET (VOIDmode, new_src,
- GEN_INT (temp1)));
- emit_constant_insn (cond,
- gen_ashrsi3 (target, new_src,
- GEN_INT (set_sign_bit_copies - 1)));
- }
- return 2;
- }
- /* For an inverted constant, we will need to set the low bits,
- these will be shifted out of harm's way. */
- temp1 |= (1 << (set_sign_bit_copies - 1)) - 1;
- if (const_ok_for_arm (~temp1))
- {
- if (generate)
- {
- rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
- emit_constant_insn (cond,
- gen_rtx_SET (VOIDmode, new_src,
- GEN_INT (temp1)));
- emit_constant_insn (cond,
- gen_ashrsi3 (target, new_src,
- GEN_INT (set_sign_bit_copies - 1)));
- }
- return 2;
- }
- }
-
- /* See if we can calculate the value as the difference between two
- valid immediates. */
- if (clear_sign_bit_copies + clear_zero_bit_copies <= 16)
- {
- int topshift = clear_sign_bit_copies & ~1;
-
- temp1 = ARM_SIGN_EXTEND ((remainder + (0x00800000 >> topshift))
- & (0xff000000 >> topshift));
-
- /* If temp1 is zero, then that means the 9 most significant
- bits of remainder were 1 and we've caused it to overflow.
- When topshift is 0 we don't need to do anything since we
- can borrow from 'bit 32'. */
- if (temp1 == 0 && topshift != 0)
- temp1 = 0x80000000 >> (topshift - 1);
-
- temp2 = ARM_SIGN_EXTEND (temp1 - remainder);
-
- if (const_ok_for_arm (temp2))
- {
- if (generate)
- {
- rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
- emit_constant_insn (cond,
- gen_rtx_SET (VOIDmode, new_src,
- GEN_INT (temp1)));
- emit_constant_insn (cond,
- gen_addsi3 (target, new_src,
- GEN_INT (-temp2)));
- }
-
- return 2;
- }
- }
-
- /* See if we can generate this by setting the bottom (or the top)
- 16 bits, and then shifting these into the other half of the
- word. We only look for the simplest cases, to do more would cost
- too much. Be careful, however, not to generate this when the
- alternative would take fewer insns. */
- if (val & 0xffff0000)
- {
- temp1 = remainder & 0xffff0000;
- temp2 = remainder & 0x0000ffff;
-
- /* Overlaps outside this range are best done using other methods. */
- for (i = 9; i < 24; i++)
- {
- if ((((temp2 | (temp2 << i)) & 0xffffffff) == remainder)
- && !const_ok_for_arm (temp2))
- {
- rtx new_src = (subtargets
- ? (generate ? gen_reg_rtx (mode) : NULL_RTX)
- : target);
- insns = arm_gen_constant (code, mode, cond, temp2, new_src,
- source, subtargets, generate);
- source = new_src;
- if (generate)
- emit_constant_insn
- (cond,
- gen_rtx_SET
- (VOIDmode, target,
- gen_rtx_IOR (mode,
- gen_rtx_ASHIFT (mode, source,
- GEN_INT (i)),
- source)));
- return insns + 1;
- }
- }
-
- /* Don't duplicate cases already considered. */
- for (i = 17; i < 24; i++)
- {
- if (((temp1 | (temp1 >> i)) == remainder)
- && !const_ok_for_arm (temp1))
- {
- rtx new_src = (subtargets
- ? (generate ? gen_reg_rtx (mode) : NULL_RTX)
- : target);
- insns = arm_gen_constant (code, mode, cond, temp1, new_src,
- source, subtargets, generate);
- source = new_src;
- if (generate)
- emit_constant_insn
- (cond,
- gen_rtx_SET (VOIDmode, target,
- gen_rtx_IOR
- (mode,
- gen_rtx_LSHIFTRT (mode, source,
- GEN_INT (i)),
- source)));
- return insns + 1;
- }
- }
- }
- break;
-
- case IOR:
- case XOR:
- /* If we have IOR or XOR, and the constant can be loaded in a
- single instruction, and we can find a temporary to put it in,
- then this can be done in two instructions instead of 3-4. */
- if (subtargets
- /* TARGET can't be NULL if SUBTARGETS is 0 */
- || (reload_completed && !reg_mentioned_p (target, source)))
- {
- if (const_ok_for_arm (ARM_SIGN_EXTEND (~val)))
- {
- if (generate)
- {
- rtx sub = subtargets ? gen_reg_rtx (mode) : target;
-
- emit_constant_insn (cond,
- gen_rtx_SET (VOIDmode, sub,
- GEN_INT (val)));
- emit_constant_insn (cond,
- gen_rtx_SET (VOIDmode, target,
- gen_rtx_fmt_ee (code, mode,
- source, sub)));
- }
- return 2;
- }
- }
-
- if (code == XOR)
- break;
-
- /* Convert.
- x = y | constant ( which is composed of set_sign_bit_copies of leading 1s
- and the remainder 0s for e.g. 0xfff00000)
- x = ~(~(y ashift set_sign_bit_copies) lshiftrt set_sign_bit_copies)
-
- This can be done in 2 instructions by using shifts with mov or mvn.
- e.g. for
- x = x | 0xfff00000;
- we generate.
- mvn r0, r0, asl #12
- mvn r0, r0, lsr #12 */
- if (set_sign_bit_copies > 8
- && (val & (-1 << (32 - set_sign_bit_copies))) == val)
- {
- if (generate)
- {
- rtx sub = subtargets ? gen_reg_rtx (mode) : target;
- rtx shift = GEN_INT (set_sign_bit_copies);
-
- emit_constant_insn
- (cond,
- gen_rtx_SET (VOIDmode, sub,
- gen_rtx_NOT (mode,
- gen_rtx_ASHIFT (mode,
- source,
- shift))));
- emit_constant_insn
- (cond,
- gen_rtx_SET (VOIDmode, target,
- gen_rtx_NOT (mode,
- gen_rtx_LSHIFTRT (mode, sub,
- shift))));
- }
- return 2;
- }
-
- /* Convert
- x = y | constant (which has set_zero_bit_copies number of trailing ones).
- to
- x = ~((~y lshiftrt set_zero_bit_copies) ashift set_zero_bit_copies).
-
- For eg. r0 = r0 | 0xfff
- mvn r0, r0, lsr #12
- mvn r0, r0, asl #12
-
- */
- if (set_zero_bit_copies > 8
- && (remainder & ((1 << set_zero_bit_copies) - 1)) == remainder)
- {
- if (generate)
- {
- rtx sub = subtargets ? gen_reg_rtx (mode) : target;
- rtx shift = GEN_INT (set_zero_bit_copies);
-
- emit_constant_insn
- (cond,
- gen_rtx_SET (VOIDmode, sub,
- gen_rtx_NOT (mode,
- gen_rtx_LSHIFTRT (mode,
- source,
- shift))));
- emit_constant_insn
- (cond,
- gen_rtx_SET (VOIDmode, target,
- gen_rtx_NOT (mode,
- gen_rtx_ASHIFT (mode, sub,
- shift))));
- }
- return 2;
- }
-
- /* This will never be reached for Thumb2 because orn is a valid
- instruction. This is for Thumb1 and the ARM 32 bit cases.
-
- x = y | constant (such that ~constant is a valid constant)
- Transform this to
- x = ~(~y & ~constant).
- */
- if (const_ok_for_arm (temp1 = ARM_SIGN_EXTEND (~val)))
- {
- if (generate)
- {
- rtx sub = subtargets ? gen_reg_rtx (mode) : target;
- emit_constant_insn (cond,
- gen_rtx_SET (VOIDmode, sub,
- gen_rtx_NOT (mode, source)));
- source = sub;
- if (subtargets)
- sub = gen_reg_rtx (mode);
- emit_constant_insn (cond,
- gen_rtx_SET (VOIDmode, sub,
- gen_rtx_AND (mode, source,
- GEN_INT (temp1))));
- emit_constant_insn (cond,
- gen_rtx_SET (VOIDmode, target,
- gen_rtx_NOT (mode, sub)));
- }
- return 3;
- }
- break;
-
- case AND:
- /* See if two shifts will do 2 or more insn's worth of work. */
- if (clear_sign_bit_copies >= 16 && clear_sign_bit_copies < 24)
- {
- HOST_WIDE_INT shift_mask = ((0xffffffff
- << (32 - clear_sign_bit_copies))
- & 0xffffffff);
-
- if ((remainder | shift_mask) != 0xffffffff)
- {
- if (generate)
- {
- rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
- insns = arm_gen_constant (AND, mode, cond,
- remainder | shift_mask,
- new_src, source, subtargets, 1);
- source = new_src;
- }
- else
- {
- rtx targ = subtargets ? NULL_RTX : target;
- insns = arm_gen_constant (AND, mode, cond,
- remainder | shift_mask,
- targ, source, subtargets, 0);
- }
- }
-
- if (generate)
- {
- rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
- rtx shift = GEN_INT (clear_sign_bit_copies);
-
- emit_insn (gen_ashlsi3 (new_src, source, shift));
- emit_insn (gen_lshrsi3 (target, new_src, shift));
- }
-
- return insns + 2;
- }
-
- if (clear_zero_bit_copies >= 16 && clear_zero_bit_copies < 24)
- {
- HOST_WIDE_INT shift_mask = (1 << clear_zero_bit_copies) - 1;
-
- if ((remainder | shift_mask) != 0xffffffff)
- {
- if (generate)
- {
- rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
-
- insns = arm_gen_constant (AND, mode, cond,
- remainder | shift_mask,
- new_src, source, subtargets, 1);
- source = new_src;
- }
- else
- {
- rtx targ = subtargets ? NULL_RTX : target;
-
- insns = arm_gen_constant (AND, mode, cond,
- remainder | shift_mask,
- targ, source, subtargets, 0);
- }
- }
-
- if (generate)
- {
- rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
- rtx shift = GEN_INT (clear_zero_bit_copies);
-
- emit_insn (gen_lshrsi3 (new_src, source, shift));
- emit_insn (gen_ashlsi3 (target, new_src, shift));
- }
-
- return insns + 2;
- }
-
- break;
-
- default:
- break;
- }
-
- /* Calculate what the instruction sequences would be if we generated it
- normally, negated, or inverted. */
- if (code == AND)
- /* AND cannot be split into multiple insns, so invert and use BIC. */
- insns = 99;
- else
- insns = optimal_immediate_sequence (code, remainder, &pos_immediates);
-
- if (can_negate)
- neg_insns = optimal_immediate_sequence (code, (-remainder) & 0xffffffff,
- &neg_immediates);
- else
- neg_insns = 99;
-
- if (can_invert || final_invert)
- inv_insns = optimal_immediate_sequence (code, remainder ^ 0xffffffff,
- &inv_immediates);
- else
- inv_insns = 99;
-
- immediates = &pos_immediates;
-
- /* Is the negated immediate sequence more efficient? */
- if (neg_insns < insns && neg_insns <= inv_insns)
- {
- insns = neg_insns;
- immediates = &neg_immediates;
- }
- else
- can_negate = 0;
-
- /* Is the inverted immediate sequence more efficient?
- We must allow for an extra NOT instruction for XOR operations, although
- there is some chance that the final 'mvn' will get optimized later. */
- if ((inv_insns + 1) < insns || (!final_invert && inv_insns < insns))
- {
- insns = inv_insns;
- immediates = &inv_immediates;
- }
- else
- {
- can_invert = 0;
- final_invert = 0;
- }
-
- /* Now output the chosen sequence as instructions. */
- if (generate)
- {
- for (i = 0; i < insns; i++)
- {
- rtx new_src, temp1_rtx;
-
- temp1 = immediates->i[i];
-
- if (code == SET || code == MINUS)
- new_src = (subtargets ? gen_reg_rtx (mode) : target);
- else if ((final_invert || i < (insns - 1)) && subtargets)
- new_src = gen_reg_rtx (mode);
- else
- new_src = target;
-
- if (can_invert)
- temp1 = ~temp1;
- else if (can_negate)
- temp1 = -temp1;
-
- temp1 = trunc_int_for_mode (temp1, mode);
- temp1_rtx = GEN_INT (temp1);
-
- if (code == SET)
- ;
- else if (code == MINUS)
- temp1_rtx = gen_rtx_MINUS (mode, temp1_rtx, source);
- else
- temp1_rtx = gen_rtx_fmt_ee (code, mode, source, temp1_rtx);
-
- emit_constant_insn (cond,
- gen_rtx_SET (VOIDmode, new_src,
- temp1_rtx));
- source = new_src;
-
- if (code == SET)
- {
- can_negate = can_invert;
- can_invert = 0;
- code = PLUS;
- }
- else if (code == MINUS)
- code = PLUS;
- }
- }
-
- if (final_invert)
- {
- if (generate)
- emit_constant_insn (cond, gen_rtx_SET (VOIDmode, target,
- gen_rtx_NOT (mode, source)));
- insns++;
- }
-
- return insns;
-}
-
-/* Canonicalize a comparison so that we are more likely to recognize it.
- This can be done for a few constant compares, where we can make the
- immediate value easier to load. */
-
-static void
-arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
- bool op0_preserve_value)
-{
- enum machine_mode mode;
- unsigned HOST_WIDE_INT i, maxval;
-
- mode = GET_MODE (*op0);
- if (mode == VOIDmode)
- mode = GET_MODE (*op1);
-
- maxval = (((unsigned HOST_WIDE_INT) 1) << (GET_MODE_BITSIZE(mode) - 1)) - 1;
-
- /* For DImode, we have GE/LT/GEU/LTU comparisons. In ARM mode
- we can also use cmp/cmpeq for GTU/LEU. GT/LE must be either
- reversed or (for constant OP1) adjusted to GE/LT. Similarly
- for GTU/LEU in Thumb mode. */
- if (mode == DImode)
- {
- rtx tem;
-
- if (*code == GT || *code == LE
- || (!TARGET_ARM && (*code == GTU || *code == LEU)))
- {
- /* Missing comparison. First try to use an available
- comparison. */
- if (CONST_INT_P (*op1))
- {
- i = INTVAL (*op1);
- switch (*code)
- {
- case GT:
- case LE:
- if (i != maxval
- && arm_const_double_by_immediates (GEN_INT (i + 1)))
- {
- *op1 = GEN_INT (i + 1);
- *code = *code == GT ? GE : LT;
- return;
- }
- break;
- case GTU:
- case LEU:
- if (i != ~((unsigned HOST_WIDE_INT) 0)
- && arm_const_double_by_immediates (GEN_INT (i + 1)))
- {
- *op1 = GEN_INT (i + 1);
- *code = *code == GTU ? GEU : LTU;
- return;
- }
- break;
- default:
- gcc_unreachable ();
- }
- }
-
- /* If that did not work, reverse the condition. */
- if (!op0_preserve_value)
- {
- tem = *op0;
- *op0 = *op1;
- *op1 = tem;
- *code = (int)swap_condition ((enum rtx_code)*code);
- }
- }
- return;
- }
-
- /* If *op0 is (zero_extend:SI (subreg:QI (reg:SI) 0)) and comparing
- with const0_rtx, change it to (and:SI (reg:SI) (const_int 255)),
- to facilitate possible combining with a cmp into 'ands'. */
- if (mode == SImode
- && GET_CODE (*op0) == ZERO_EXTEND
- && GET_CODE (XEXP (*op0, 0)) == SUBREG
- && GET_MODE (XEXP (*op0, 0)) == QImode
- && GET_MODE (SUBREG_REG (XEXP (*op0, 0))) == SImode
- && subreg_lowpart_p (XEXP (*op0, 0))
- && *op1 == const0_rtx)
- *op0 = gen_rtx_AND (SImode, SUBREG_REG (XEXP (*op0, 0)),
- GEN_INT (255));
-
- /* Comparisons smaller than DImode. Only adjust comparisons against
- an out-of-range constant. */
- if (!CONST_INT_P (*op1)
- || const_ok_for_arm (INTVAL (*op1))
- || const_ok_for_arm (- INTVAL (*op1)))
- return;
-
- i = INTVAL (*op1);
-
- switch (*code)
- {
- case EQ:
- case NE:
- return;
-
- case GT:
- case LE:
- if (i != maxval
- && (const_ok_for_arm (i + 1) || const_ok_for_arm (-(i + 1))))
- {
- *op1 = GEN_INT (i + 1);
- *code = *code == GT ? GE : LT;
- return;
- }
- break;
-
- case GE:
- case LT:
- if (i != ~maxval
- && (const_ok_for_arm (i - 1) || const_ok_for_arm (-(i - 1))))
- {
- *op1 = GEN_INT (i - 1);
- *code = *code == GE ? GT : LE;
- return;
- }
- break;
-
- case GTU:
- case LEU:
- if (i != ~((unsigned HOST_WIDE_INT) 0)
- && (const_ok_for_arm (i + 1) || const_ok_for_arm (-(i + 1))))
- {
- *op1 = GEN_INT (i + 1);
- *code = *code == GTU ? GEU : LTU;
- return;
- }
- break;
-
- case GEU:
- case LTU:
- if (i != 0
- && (const_ok_for_arm (i - 1) || const_ok_for_arm (-(i - 1))))
- {
- *op1 = GEN_INT (i - 1);
- *code = *code == GEU ? GTU : LEU;
- return;
- }
- break;
-
- default:
- gcc_unreachable ();
- }
-}
-
-
-/* Define how to find the value returned by a function. */
-
-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))
- mode = arm_promote_function_mode (type, mode, &unsignedp, func, 1);
-
- /* Promotes small structs returned in a register to full-word size
- for big-endian AAPCS. */
- if (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 arm_libcall_value_1 (mode);
-}
-
-static int
-libcall_eq (const void *p1, const void *p2)
-{
- return rtx_equal_p ((const_rtx) p1, (const_rtx) p2);
-}
-
-static hashval_t
-libcall_hash (const void *p1)
-{
- return hash_rtx ((const_rtx) p1, VOIDmode, NULL, NULL, FALSE);
-}
-
-static void
-add_libcall (htab_t htab, rtx libcall)
-{
- *htab_find_slot (htab, libcall, INSERT) = libcall;
-}
-
-static bool
-arm_libcall_uses_aapcs_base (const_rtx libcall)
-{
- static bool init_done = false;
- static htab_t libcall_htab;
-
- if (!init_done)
- {
- init_done = true;
-
- libcall_htab = htab_create (31, libcall_hash, libcall_eq,
- NULL);
- add_libcall (libcall_htab,
- convert_optab_libfunc (sfloat_optab, SFmode, SImode));
- add_libcall (libcall_htab,
- convert_optab_libfunc (sfloat_optab, DFmode, SImode));
- add_libcall (libcall_htab,
- convert_optab_libfunc (sfloat_optab, SFmode, DImode));
- add_libcall (libcall_htab,
- convert_optab_libfunc (sfloat_optab, DFmode, DImode));
-
- add_libcall (libcall_htab,
- convert_optab_libfunc (ufloat_optab, SFmode, SImode));
- add_libcall (libcall_htab,
- convert_optab_libfunc (ufloat_optab, DFmode, SImode));
- add_libcall (libcall_htab,
- convert_optab_libfunc (ufloat_optab, SFmode, DImode));
- add_libcall (libcall_htab,
- convert_optab_libfunc (ufloat_optab, DFmode, DImode));
-
- add_libcall (libcall_htab,
- convert_optab_libfunc (sext_optab, SFmode, HFmode));
- add_libcall (libcall_htab,
- convert_optab_libfunc (trunc_optab, HFmode, SFmode));
- add_libcall (libcall_htab,
- convert_optab_libfunc (sfix_optab, SImode, DFmode));
- add_libcall (libcall_htab,
- convert_optab_libfunc (ufix_optab, SImode, DFmode));
- add_libcall (libcall_htab,
- convert_optab_libfunc (sfix_optab, DImode, DFmode));
- add_libcall (libcall_htab,
- convert_optab_libfunc (ufix_optab, DImode, DFmode));
- add_libcall (libcall_htab,
- convert_optab_libfunc (sfix_optab, DImode, SFmode));
- add_libcall (libcall_htab,
- convert_optab_libfunc (ufix_optab, DImode, SFmode));
-
- /* Values from double-precision helper functions are returned in core
- registers if the selected core only supports single-precision
- arithmetic, even if we are using the hard-float ABI. The same is
- true for single-precision helpers, but we will never be using the
- hard-float ABI on a CPU which doesn't support single-precision
- operations in hardware. */
- add_libcall (libcall_htab, optab_libfunc (add_optab, DFmode));
- add_libcall (libcall_htab, optab_libfunc (sdiv_optab, DFmode));
- add_libcall (libcall_htab, optab_libfunc (smul_optab, DFmode));
- add_libcall (libcall_htab, optab_libfunc (neg_optab, DFmode));
- add_libcall (libcall_htab, optab_libfunc (sub_optab, DFmode));
- add_libcall (libcall_htab, optab_libfunc (eq_optab, DFmode));
- add_libcall (libcall_htab, optab_libfunc (lt_optab, DFmode));
- add_libcall (libcall_htab, optab_libfunc (le_optab, DFmode));
- add_libcall (libcall_htab, optab_libfunc (ge_optab, DFmode));
- add_libcall (libcall_htab, optab_libfunc (gt_optab, DFmode));
- add_libcall (libcall_htab, optab_libfunc (unord_optab, DFmode));
- add_libcall (libcall_htab, convert_optab_libfunc (sext_optab, DFmode,
- SFmode));
- add_libcall (libcall_htab, convert_optab_libfunc (trunc_optab, SFmode,
- DFmode));
- }
-
- return libcall && htab_find (libcall_htab, libcall) != NULL;
-}
-
-static rtx
-arm_libcall_value_1 (enum machine_mode mode)
-{
- if (TARGET_AAPCS_BASED)
- return aapcs_libcall_value (mode);
- else if (TARGET_IWMMXT_ABI
- && arm_vector_mode_supported_p (mode))
- return gen_rtx_REG (mode, FIRST_IWMMXT_REGNUM);
- else
- return gen_rtx_REG (mode, ARG_REGISTER (1));
-}
-
-/* Define how to find the value returned by a library function
- assuming the value has mode MODE. */
-
-static rtx
-arm_libcall_value (enum machine_mode mode, const_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 (arm_libcall_uses_aapcs_base (libcall))
- return gen_rtx_REG (mode, ARG_REGISTER(1));
-
- }
-
- return arm_libcall_value_1 (mode);
-}
-
-/* Implement TARGET_FUNCTION_VALUE_REGNO_P. */
-
-static bool
-arm_function_value_regno_p (const unsigned int regno)
-{
- if (regno == ARG_REGISTER (1)
- || (TARGET_32BIT
- && TARGET_AAPCS_BASED
- && TARGET_VFP
- && TARGET_HARD_FLOAT
- && regno == FIRST_VFP_REGNUM)
- || (TARGET_IWMMXT_ABI
- && regno == FIRST_IWMMXT_REGNUM))
- return true;
-
- return false;
-}
-
-/* Determine the amount of memory needed to store the possible return
- registers of an untyped call. */
-int
-arm_apply_result_size (void)
-{
- int size = 16;
-
- if (TARGET_32BIT)
- {
- if (TARGET_HARD_FLOAT_ABI && TARGET_VFP)
- size += 32;
- if (TARGET_IWMMXT_ABI)
- size += 8;
- }
-
- return size;
-}
-
-/* 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); /* 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;
- }
-
- if (TREE_CODE (type) == VECTOR_TYPE)
- return (size < 0 || size > (4 * UNITS_PER_WORD));
-
- if (!AGGREGATE_TYPE_P (type) &&
- (TREE_CODE (type) != VECTOR_TYPE))
- /* All simple types are returned in registers. */
- return false;
-
- if (arm_abi != ARM_ABI_APCS)
- {
- /* ATPCS and later return aggregate types in memory only if they are
- larger than a word (or are variable size). */
- return (size < 0 || size > UNITS_PER_WORD);
- }
-
- /* For the arm-wince targets we choose to be compatible with Microsoft's
- ARM and Thumb compilers, which always return aggregates in memory. */
-#ifndef ARM_WINCE
- /* All structures/unions bigger than one word are returned in memory.
- Also catch the case where int_size_in_bytes returns -1. In this case
- 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 true;
-
- if (TREE_CODE (type) == RECORD_TYPE)
- {
- tree field;
-
- /* For a struct the APCS says that we only return in a register
- if the type is 'integer like' and every addressable element
- has an offset of zero. For practical purposes this means
- that the structure can have at most one non bit-field element
- and that this element must be the first one in the structure. */
-
- /* Find the first field, ignoring non FIELD_DECL things which will
- have been created by C++. */
- for (field = TYPE_FIELDS (type);
- field && TREE_CODE (field) != FIELD_DECL;
- field = DECL_CHAIN (field))
- continue;
-
- if (field == NULL)
- 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 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 true;
-
- /* Now check the remaining fields, if any. Only bitfields are allowed,
- since they are not addressable. */
- for (field = DECL_CHAIN (field);
- field;
- field = DECL_CHAIN (field))
- {
- if (TREE_CODE (field) != FIELD_DECL)
- continue;
-
- if (!DECL_BIT_FIELD_TYPE (field))
- return true;
- }
-
- return false;
- }
-
- if (TREE_CODE (type) == UNION_TYPE)
- {
- tree field;
-
- /* Unions can be returned in registers if every element is
- integral, or can be returned in an integer register. */
- for (field = TYPE_FIELDS (type);
- field;
- field = DECL_CHAIN (field))
- {
- if (TREE_CODE (field) != FIELD_DECL)
- continue;
-
- if (FLOAT_TYPE_P (TREE_TYPE (field)))
- return true;
-
- if (arm_return_in_memory (TREE_TYPE (field), NULL_TREE))
- return true;
- }
-
- return false;
- }
-#endif /* not ARM_WINCE */
-
- /* Return all other types in memory. */
- return true;
-}
-
-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},
-#if 0
- /* We could recognize these, but changes would be needed elsewhere
- * to implement them. */
- {"aapcs-iwmmxt", ARM_PCS_AAPCS_IWMMXT},
- {"atpcs", ARM_PCS_ATPCS},
- {"apcs", ARM_PCS_APCS},
-#endif
- {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 = stdarg_p (type);
-
- 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 = DECL_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 = DECL_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)
- {
- static bool seen_thumb1_vfp = false;
-
- if (TARGET_THUMB1 && !seen_thumb1_vfp)
- {
- sorry ("Thumb-1 hard-float VFP ABI");
- /* sorry() is not immediately fatal, so only display this once. */
- seen_thumb1_vfp = true;
- }
-
- return true;
- }
-
- if (pcs_variant != ARM_PCS_AAPCS_LOCAL)
- return false;
-
- return (TARGET_32BIT && TARGET_VFP && TARGET_HARD_FLOAT &&
- (TARGET_VFP_DOUBLE || !is_double));
-}
-
-/* Return true if an argument whose type is TYPE, or mode is MODE, is
- suitable for passing or returning in VFP registers for the PCS
- variant selected. If it is, then *BASE_MODE is updated to contain
- a machine mode describing each element of the argument's type and
- *COUNT to hold the number of such elements. */
-static bool
-aapcs_vfp_is_call_or_return_candidate (enum arm_pcs pcs_variant,
- enum machine_mode mode, const_tree type,
- enum machine_mode *base_mode, int *count)
-{
- enum machine_mode new_mode = VOIDmode;
-
- /* If we have the type information, prefer that to working things
- out from the mode. */
- if (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 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
- 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;
- enum machine_mode 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 NULL;
-
- if (mode == BLKmode || (mode == TImode && !TARGET_NEON))
- {
- int count;
- enum machine_mode 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,
- const_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;
- int unsignedp ATTRIBUTE_UNUSED;
-
- 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))
- mode = arm_promote_function_mode (type, mode, &unsignedp, fntype, 1);
-
- 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);
-}
-
-static rtx
-aapcs_libcall_value (enum machine_mode mode)
-{
- if (BYTES_BIG_ENDIAN && ALL_FIXED_POINT_MODE_P (mode)
- && GET_MODE_SIZE (mode) <= 4)
- mode = SImode;
-
- 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,
- const_tree type, bool 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,
- 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)
- {
- if (arm_libcall_uses_aapcs_base (libname))
- 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. */
-static bool
-arm_needs_doubleword_align (enum machine_mode mode, const_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).
-
- On the ARM, normally the first 16 bytes are passed in registers r0-r3; all
- other arguments are passed on the stack. If (NAMED == 0) (which happens
- only in assign_parms, since TARGET_SETUP_INCOMING_VARARGS is
- defined), say it is passed in the stack (function_prologue will
- indeed make it pass in the stack if necessary). */
-
-static rtx
-arm_function_arg (cumulative_args_t pcum_v, enum machine_mode mode,
- const_tree type, bool named)
-{
- CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
- 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
- && arm_vector_mode_supported_p (mode)
- && pcum->named_count > pcum->nargs + 1)
- {
- if (pcum->iwmmxt_nregs <= 9)
- return gen_rtx_REG (mode, pcum->iwmmxt_nregs + FIRST_IWMMXT_REGNUM);
- else
- {
- pcum->can_split = false;
- return NULL_RTX;
- }
- }
-
- /* Put doubleword aligned quantities in even register pairs. */
- if (pcum->nregs & 1
- && ARM_DOUBLEWORD_ALIGN
- && arm_needs_doubleword_align (mode, type))
- pcum->nregs++;
-
- /* Only allow splitting an arg between regs and memory if all preceding
- args were allocated to regs. For args passed by reference we only count
- the reference pointer. */
- if (pcum->can_split)
- nregs = 1;
- else
- nregs = ARM_NUM_REGS2 (mode, type);
-
- if (!named || pcum->nregs + nregs > NUM_ARG_REGS)
- return NULL_RTX;
-
- return gen_rtx_REG (mode, pcum->nregs);
-}
-
-static unsigned int
-arm_function_arg_boundary (enum machine_mode mode, const_tree type)
-{
- return (ARM_DOUBLEWORD_ALIGN && arm_needs_doubleword_align (mode, type)
- ? DOUBLEWORD_ALIGNMENT
- : PARM_BOUNDARY);
-}
-
-static int
-arm_arg_partial_bytes (cumulative_args_t pcum_v, enum machine_mode mode,
- tree type, bool named)
-{
- CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
- 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;
-
- if (NUM_ARG_REGS > nregs
- && (NUM_ARG_REGS < nregs + ARM_NUM_REGS2 (mode, type))
- && pcum->can_split)
- return (NUM_ARG_REGS - nregs) * UNITS_PER_WORD;
-
- return 0;
-}
-
-/* Update the data in PCUM to advance over an argument
- of mode MODE and data type TYPE.
- (TYPE is null for libcalls where that information may not be available.) */
-
-static void
-arm_function_arg_advance (cumulative_args_t pcum_v, enum machine_mode mode,
- const_tree type, bool named)
-{
- CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
-
- 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. */
-
-static bool
-arm_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
- enum machine_mode mode ATTRIBUTE_UNUSED,
- const_tree type, bool named ATTRIBUTE_UNUSED)
-{
- return type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST;
-}
-
-/* Encode the current state of the #pragma [no_]long_calls. */
-typedef enum
-{
- OFF, /* No #pragma [no_]long_calls is in effect. */
- LONG, /* #pragma long_calls is in effect. */
- SHORT /* #pragma no_long_calls is in effect. */
-} arm_pragma_enum;
-
-static arm_pragma_enum arm_pragma_long_calls = OFF;
-
-void
-arm_pr_long_calls (struct cpp_reader * pfile ATTRIBUTE_UNUSED)
-{
- arm_pragma_long_calls = LONG;
-}
-
-void
-arm_pr_no_long_calls (struct cpp_reader * pfile ATTRIBUTE_UNUSED)
-{
- arm_pragma_long_calls = SHORT;
-}
-
-void
-arm_pr_long_calls_off (struct cpp_reader * pfile ATTRIBUTE_UNUSED)
-{
- arm_pragma_long_calls = OFF;
-}
-
-/* Handle an attribute requiring a FUNCTION_DECL;
- arguments as in struct attribute_spec.handler. */
-static tree
-arm_handle_fndecl_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
- int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
-{
- if (TREE_CODE (*node) != FUNCTION_DECL)
- {
- warning (OPT_Wattributes, "%qE attribute only applies to functions",
- name);
- *no_add_attrs = true;
- }
-
- return NULL_TREE;
-}
-
-/* Handle an "interrupt" or "isr" attribute;
- arguments as in struct attribute_spec.handler. */
-static tree
-arm_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, "%qE attribute only applies to functions",
- 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 (arm_isr_value (args) == ARM_FT_UNKNOWN)
- {
- warning (OPT_Wattributes, "%qE attribute ignored",
- 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)
- && arm_isr_value (args) != ARM_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, "%qE attribute ignored",
- name);
- }
- }
- }
-
- 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, "%qE attribute ignored", 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
- "__declspec(notshared)"; we support the same thing via an
- attribute. */
-
-static tree
-arm_handle_notshared_attribute (tree *node,
- tree name ATTRIBUTE_UNUSED,
- tree args ATTRIBUTE_UNUSED,
- int flags ATTRIBUTE_UNUSED,
- bool *no_add_attrs)
-{
- tree decl = TYPE_NAME (*node);
-
- if (decl)
- {
- DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
- DECL_VISIBILITY_SPECIFIED (decl) = 1;
- *no_add_attrs = false;
- }
- return NULL_TREE;
-}
-#endif
-
-/* 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
-arm_comp_type_attributes (const_tree type1, const_tree type2)
-{
- int l1, l2, s1, s2;
-
- /* Check for mismatch of non-default calling convention. */
- if (TREE_CODE (type1) != FUNCTION_TYPE)
- return 1;
-
- /* Check for mismatched call attributes. */
- l1 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type1)) != NULL;
- l2 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type2)) != NULL;
- s1 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type1)) != NULL;
- s2 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type2)) != NULL;
-
- /* Only bother to check if an attribute is defined. */
- if (l1 | l2 | s1 | s2)
- {
- /* If one type has an attribute, the other must have the same attribute. */
- if ((l1 != l2) || (s1 != s2))
- return 0;
-
- /* Disallow mixed attributes. */
- if ((l1 & s2) || (l2 & s1))
- return 0;
- }
-
- /* Check for mismatched ISR attribute. */
- l1 = lookup_attribute ("isr", TYPE_ATTRIBUTES (type1)) != NULL;
- if (! l1)
- l1 = lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type1)) != NULL;
- l2 = lookup_attribute ("isr", TYPE_ATTRIBUTES (type2)) != NULL;
- if (! l2)
- l1 = lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type2)) != NULL;
- if (l1 != l2)
- return 0;
-
- return 1;
-}
-
-/* Assigns default attributes to newly defined type. This is used to
- set short_call/long_call attributes for function types of
- functions defined inside corresponding #pragma scopes. */
-static void
-arm_set_default_type_attributes (tree type)
-{
- /* Add __attribute__ ((long_call)) to all functions, when
- inside #pragma long_calls or __attribute__ ((short_call)),
- when inside #pragma no_long_calls. */
- if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE)
- {
- tree type_attr_list, attr_name;
- type_attr_list = TYPE_ATTRIBUTES (type);
-
- if (arm_pragma_long_calls == LONG)
- attr_name = get_identifier ("long_call");
- else if (arm_pragma_long_calls == SHORT)
- attr_name = get_identifier ("short_call");
- else
- return;
-
- type_attr_list = tree_cons (attr_name, NULL_TREE, type_attr_list);
- TYPE_ATTRIBUTES (type) = type_attr_list;
- }
-}
-
-/* Return true if DECL is known to be linked into section SECTION. */
-
-static bool
-arm_function_in_section_p (tree decl, section *section)
-{
- /* We can only be certain about functions defined in the same
- compilation unit. */
- if (!TREE_STATIC (decl))
- return false;
-
- /* Make sure that SYMBOL always binds to the definition in this
- compilation unit. */
- if (!targetm.binds_local_p (decl))
- return false;
-
- /* If DECL_SECTION_NAME is set, assume it is trustworthy. */
- if (!DECL_SECTION_NAME (decl))
- {
- /* Make sure that we will not create a unique section for DECL. */
- if (flag_function_sections || DECL_ONE_ONLY (decl))
- return false;
- }
-
- return function_section (decl) == section;
-}
-
-/* Return nonzero if a 32-bit "long_call" should be generated for
- a call from the current function to DECL. We generate a long_call
- if the function:
-
- a. has an __attribute__((long call))
- or b. is within the scope of a #pragma long_calls
- or c. the -mlong-calls command line switch has been specified
-
- However we do not generate a long call if the function:
-
- d. has an __attribute__ ((short_call))
- or e. is inside the scope of a #pragma no_long_calls
- or f. is defined in the same section as the current function. */
-
-bool
-arm_is_long_call_p (tree decl)
-{
- tree attrs;
-
- if (!decl)
- return TARGET_LONG_CALLS;
-
- attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
- if (lookup_attribute ("short_call", attrs))
- return false;
-
- /* For "f", be conservative, and only cater for cases in which the
- whole of the current function is placed in the same section. */
- if (!flag_reorder_blocks_and_partition
- && TREE_CODE (decl) == FUNCTION_DECL
- && arm_function_in_section_p (decl, current_function_section ()))
- return false;
-
- if (lookup_attribute ("long_call", attrs))
- return true;
-
- return TARGET_LONG_CALLS;
-}
-
-/* Return nonzero if it is ok to make a tail-call to DECL. */
-static bool
-arm_function_ok_for_sibcall (tree decl, tree exp)
-{
- unsigned long func_type;
-
- if (cfun->machine->sibcall_blocked)
- return false;
-
- /* Never tailcall something for which we have no decl, or if we
- are generating code for Thumb-1. */
- if (decl == NULL || TARGET_THUMB1)
- return false;
-
- /* The PIC register is live on entry to VxWorks PLT entries, so we
- must make the call before restoring the PIC register. */
- if (TARGET_VXWORKS_RTP && flag_pic && !targetm.binds_local_p (decl))
- return false;
-
- /* Cannot tail-call to long calls, since these are out of range of
- a branch instruction. */
- if (arm_is_long_call_p (decl))
- return false;
-
- /* If we are interworking and the function is not declared static
- then we can't tail-call it unless we know that it exists in this
- compilation unit (since it might be a Thumb routine). */
- if (TARGET_INTERWORK && TREE_PUBLIC (decl) && !TREE_ASM_WRITTEN (decl))
- return false;
-
- func_type = arm_current_func_type ();
- /* Never tailcall from an ISR routine - it needs a special exit sequence. */
- 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;
-
- /* The AAPCS says that, on bare-metal, calls to unresolved weak
- references should become a NOP. Don't convert such calls into
- sibling calls. */
- if (TARGET_AAPCS_BASED
- && arm_abi == ARM_ABI_AAPCS
- && DECL_WEAK (decl))
- return false;
-
- /* Everything else is ok. */
- return true;
-}
-
-
-/* Addressing mode support functions. */
-
-/* Return nonzero if X is a legitimate immediate operand when compiling
- for PIC. We know that X satisfies CONSTANT_P and flag_pic is true. */
-int
-legitimate_pic_operand_p (rtx x)
-{
- if (GET_CODE (x) == SYMBOL_REF
- || (GET_CODE (x) == CONST
- && GET_CODE (XEXP (x, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF))
- return 0;
-
- return 1;
-}
-
-/* Record that the current function needs a PIC register. Initialize
- cfun->machine->pic_reg if we have not already done so. */
-
-static void
-require_pic_register (void)
-{
- /* A lot of the logic here is made obscure by the fact that this
- routine gets called as part of the rtx cost estimation process.
- We don't want those calls to affect any assumptions about the real
- function; and further, we can't call entry_of_function() until we
- start the real expansion process. */
- if (!crtl->uses_pic_offset_table)
- {
- gcc_assert (can_create_pseudo_p ());
- if (arm_pic_register != INVALID_REGNUM)
- {
- if (!cfun->machine->pic_reg)
- cfun->machine->pic_reg = gen_rtx_REG (Pmode, arm_pic_register);
-
- /* Play games to avoid marking the function as needing pic
- if we are being called as part of the cost-estimation
- process. */
- if (current_ir_type () != IR_GIMPLE || currently_expanding_to_rtl)
- crtl->uses_pic_offset_table = 1;
- }
- else
- {
- rtx seq, insn;
-
- if (!cfun->machine->pic_reg)
- cfun->machine->pic_reg = gen_reg_rtx (Pmode);
-
- /* Play games to avoid marking the function as needing pic
- if we are being called as part of the cost-estimation
- process. */
- if (current_ir_type () != IR_GIMPLE || currently_expanding_to_rtl)
- {
- crtl->uses_pic_offset_table = 1;
- start_sequence ();
-
- arm_load_pic_register (0UL);
-
- seq = get_insns ();
- end_sequence ();
-
- for (insn = seq; insn; insn = NEXT_INSN (insn))
- if (INSN_P (insn))
- INSN_LOCATION (insn) = prologue_location;
-
- /* We can be called during expansion of PHI nodes, where
- we can't yet emit instructions directly in the final
- insn stream. Queue the insns on the entry edge, they will
- be committed after everything else is expanded. */
- insert_insn_on_edge (seq, single_succ_edge (ENTRY_BLOCK_PTR));
- }
- }
- }
-}
-
-rtx
-legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
-{
- if (GET_CODE (orig) == SYMBOL_REF
- || GET_CODE (orig) == LABEL_REF)
- {
- rtx insn;
-
- if (reg == 0)
- {
- gcc_assert (can_create_pseudo_p ());
- reg = gen_reg_rtx (Pmode);
- }
-
- /* VxWorks does not impose a fixed gap between segments; the run-time
- gap can be different from the object-file gap. We therefore can't
- use GOTOFF unless we are absolutely sure that the symbol is in the
- same segment as the GOT. Unfortunately, the flexibility of linker
- scripts means that we can't be sure of that in general, so assume
- that GOTOFF is never valid on VxWorks. */
- if ((GET_CODE (orig) == LABEL_REF
- || (GET_CODE (orig) == SYMBOL_REF &&
- SYMBOL_REF_LOCAL_P (orig)))
- && NEED_GOT_RELOC
- && !TARGET_VXWORKS_RTP)
- insn = arm_pic_static_addr (orig, reg);
- else
- {
- rtx pat;
- rtx mem;
-
- /* If this function doesn't have a pic register, create one now. */
- require_pic_register ();
-
- pat = gen_calculate_pic_address (reg, cfun->machine->pic_reg, orig);
-
- /* Make the MEM as close to a constant as possible. */
- mem = SET_SRC (pat);
- gcc_assert (MEM_P (mem) && !MEM_VOLATILE_P (mem));
- MEM_READONLY_P (mem) = 1;
- MEM_NOTRAP_P (mem) = 1;
-
- insn = emit_insn (pat);
- }
-
- /* 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;
- }
- else if (GET_CODE (orig) == CONST)
- {
- rtx base, offset;
-
- if (GET_CODE (XEXP (orig, 0)) == PLUS
- && 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 (CONST_INT_P (XEXP (XEXP (orig, 0), 1)));
- return orig;
- }
-
- if (reg == 0)
- {
- gcc_assert (can_create_pseudo_p ());
- reg = gen_reg_rtx (Pmode);
- }
-
- gcc_assert (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);
-
- if (CONST_INT_P (offset))
- {
- /* The base register doesn't really matter, we only want to
- test the index for the appropriate mode. */
- if (!arm_legitimate_index_p (mode, offset, SET, 0))
- {
- gcc_assert (can_create_pseudo_p ());
- offset = force_reg (Pmode, offset);
- }
-
- if (CONST_INT_P (offset))
- return plus_constant (Pmode, base, INTVAL (offset));
- }
-
- if (GET_MODE_SIZE (mode) > 4
- && (GET_MODE_CLASS (mode) == MODE_INT
- || TARGET_SOFT_FLOAT))
- {
- emit_insn (gen_addsi3 (reg, base, offset));
- return reg;
- }
-
- return gen_rtx_PLUS (Pmode, base, offset);
- }
-
- return orig;
-}
-
-
-/* Find a spare register to use during the prolog of a function. */
-
-static int
-thumb_find_work_register (unsigned long pushed_regs_mask)
-{
- int reg;
-
- /* Check the argument registers first as these are call-used. The
- register allocation order means that sometimes r3 might be used
- but earlier argument registers might not, so check them all. */
- for (reg = LAST_ARG_REGNUM; reg >= 0; reg --)
- if (!df_regs_ever_live_p (reg))
- return reg;
-
- /* Before going on to check the call-saved registers we can try a couple
- more ways of deducing that r3 is available. The first is when we are
- pushing anonymous arguments onto the stack and we have less than 4
- registers worth of fixed arguments(*). In this case r3 will be part of
- the variable argument list and so we can be sure that it will be
- pushed right at the start of the function. Hence it will be available
- for the rest of the prologue.
- (*): ie crtl->args.pretend_args_size is greater than 0. */
- if (cfun->machine->uses_anonymous_args
- && crtl->args.pretend_args_size > 0)
- return LAST_ARG_REGNUM;
-
- /* The other case is when we have fixed arguments but less than 4 registers
- worth. In this case r3 might be used in the body of the function, but
- it is not being used to convey an argument into the function. In theory
- we could just check crtl->args.size to see how many bytes are
- being passed in argument registers, but it seems that it is unreliable.
- Sometimes it will have the value 0 when in fact arguments are being
- passed. (See testcase execute/20021111-1.c for an example). So we also
- check the args_info.nregs field as well. The problem with this field is
- that it makes no allowances for arguments that are passed to the
- function but which are not used. Hence we could miss an opportunity
- when a function has an unused argument in r3. But it is better to be
- safe than to be sorry. */
- if (! cfun->machine->uses_anonymous_args
- && crtl->args.size >= 0
- && crtl->args.size <= (LAST_ARG_REGNUM * UNITS_PER_WORD)
- && (TARGET_AAPCS_BASED
- ? crtl->args.info.aapcs_ncrn < 4
- : crtl->args.info.nregs < 4))
- return LAST_ARG_REGNUM;
-
- /* Otherwise look for a call-saved register that is going to be pushed. */
- for (reg = LAST_LO_REGNUM; reg > LAST_ARG_REGNUM; reg --)
- if (pushed_regs_mask & (1 << reg))
- return reg;
-
- if (TARGET_THUMB2)
- {
- /* Thumb-2 can use high regs. */
- for (reg = FIRST_HI_REGNUM; reg < 15; reg ++)
- if (pushed_regs_mask & (1 << reg))
- return reg;
- }
- /* Something went wrong - thumb_compute_save_reg_mask()
- should have arranged for a suitable register to be pushed. */
- gcc_unreachable ();
-}
-
-static GTY(()) int pic_labelno;
-
-/* Generate code to load the PIC register. In thumb mode SCRATCH is a
- low register. */
-
-void
-arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED)
-{
- rtx l1, labelno, pic_tmp, pic_rtx, pic_reg;
-
- if (crtl->uses_pic_offset_table == 0 || TARGET_SINGLE_PIC_BASE)
- return;
-
- gcc_assert (flag_pic);
-
- pic_reg = cfun->machine->pic_reg;
- if (TARGET_VXWORKS_RTP)
- {
- pic_rtx = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
- pic_rtx = gen_rtx_CONST (Pmode, pic_rtx);
- emit_insn (gen_pic_load_addr_32bit (pic_reg, pic_rtx));
-
- emit_insn (gen_rtx_SET (Pmode, pic_reg, gen_rtx_MEM (Pmode, pic_reg)));
-
- pic_tmp = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
- emit_insn (gen_pic_offset_arm (pic_reg, pic_reg, pic_tmp));
- }
- else
- {
- /* We use an UNSPEC rather than a LABEL_REF because this label
- never appears in the code stream. */
-
- labelno = GEN_INT (pic_labelno++);
- l1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
- l1 = gen_rtx_CONST (VOIDmode, l1);
-
- /* On the ARM the PC register contains 'dot + 8' at the time of the
- addition, on the Thumb it is 'dot + 4'. */
- pic_rtx = plus_constant (Pmode, l1, TARGET_ARM ? 8 : 4);
- pic_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, pic_rtx),
- UNSPEC_GOTSYM_OFF);
- pic_rtx = gen_rtx_CONST (Pmode, pic_rtx);
-
- if (TARGET_32BIT)
- {
- emit_insn (gen_pic_load_addr_unified (pic_reg, pic_rtx, labelno));
- }
- else /* TARGET_THUMB1 */
- {
- if (arm_pic_register != INVALID_REGNUM
- && REGNO (pic_reg) > LAST_LO_REGNUM)
- {
- /* We will have pushed the pic register, so we should always be
- able to find a work register. */
- pic_tmp = gen_rtx_REG (SImode,
- thumb_find_work_register (saved_regs));
- emit_insn (gen_pic_load_addr_thumb1 (pic_tmp, pic_rtx));
- emit_insn (gen_movsi (pic_offset_table_rtx, pic_tmp));
- emit_insn (gen_pic_add_dot_plus_four (pic_reg, pic_reg, labelno));
- }
- else
- emit_insn (gen_pic_load_addr_unified (pic_reg, pic_rtx, labelno));
- }
- }
-
- /* Need to emit this whether or not we obey regdecls,
- since setjmp/longjmp can cause life info to screw up. */
- emit_use (pic_reg);
-}
-
-/* Generate code to load the address of a static var when flag_pic is set. */
-static rtx
-arm_pic_static_addr (rtx orig, rtx reg)
-{
- rtx l1, labelno, offset_rtx, insn;
-
- gcc_assert (flag_pic);
-
- /* We use an UNSPEC rather than a LABEL_REF because this label
- never appears in the code stream. */
- labelno = GEN_INT (pic_labelno++);
- l1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
- l1 = gen_rtx_CONST (VOIDmode, l1);
-
- /* On the ARM the PC register contains 'dot + 8' at the time of the
- addition, on the Thumb it is 'dot + 4'. */
- offset_rtx = plus_constant (Pmode, l1, TARGET_ARM ? 8 : 4);
- offset_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, orig, offset_rtx),
- UNSPEC_SYMBOL_OFFSET);
- offset_rtx = gen_rtx_CONST (Pmode, offset_rtx);
-
- insn = emit_insn (gen_pic_load_addr_unified (reg, offset_rtx, labelno));
- return insn;
-}
-
-/* Return nonzero if X is valid as an ARM state addressing register. */
-static int
-arm_address_register_rtx_p (rtx x, int strict_p)
-{
- int regno;
-
- if (!REG_P (x))
- return 0;
-
- regno = REGNO (x);
-
- if (strict_p)
- return ARM_REGNO_OK_FOR_BASE_P (regno);
-
- return (regno <= LAST_ARM_REGNUM
- || regno >= FIRST_PSEUDO_REGISTER
- || regno == FRAME_POINTER_REGNUM
- || regno == ARG_POINTER_REGNUM);
-}
-
-/* Return TRUE if this rtx is the difference of a symbol and a label,
- and will reduce to a PC-relative relocation in the object file.
- Expressions like this can be left alone when generating PIC, rather
- than forced through the GOT. */
-static int
-pcrel_constant_p (rtx x)
-{
- if (GET_CODE (x) == MINUS)
- return symbol_mentioned_p (XEXP (x, 0)) && label_mentioned_p (XEXP (x, 1));
-
- return FALSE;
-}
-
-/* Return true if X will surely end up in an index register after next
- splitting pass. */
-static bool
-will_be_in_index_register (const_rtx x)
-{
- /* arm.md: calculate_pic_address will split this into a register. */
- return GET_CODE (x) == UNSPEC && (XINT (x, 1) == UNSPEC_PIC_SYM);
-}
-
-/* Return nonzero if X is a valid ARM state address operand. */
-int
-arm_legitimate_address_outer_p (enum machine_mode mode, rtx x, RTX_CODE outer,
- int strict_p)
-{
- bool use_ldrd;
- enum rtx_code code = GET_CODE (x);
-
- if (arm_address_register_rtx_p (x, strict_p))
- return 1;
-
- use_ldrd = (TARGET_LDRD
- && (mode == DImode
- || (mode == DFmode && (TARGET_SOFT_FLOAT || TARGET_VFP))));
-
- if (code == POST_INC || code == PRE_DEC
- || ((code == PRE_INC || code == POST_DEC)
- && (use_ldrd || GET_MODE_SIZE (mode) <= 4)))
- return arm_address_register_rtx_p (XEXP (x, 0), strict_p);
-
- else if ((code == POST_MODIFY || code == PRE_MODIFY)
- && arm_address_register_rtx_p (XEXP (x, 0), strict_p)
- && GET_CODE (XEXP (x, 1)) == PLUS
- && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
- {
- rtx addend = XEXP (XEXP (x, 1), 1);
-
- /* Don't allow ldrd post increment by register because it's hard
- to fixup invalid register choices. */
- if (use_ldrd
- && GET_CODE (x) == POST_MODIFY
- && REG_P (addend))
- return 0;
-
- return ((use_ldrd || GET_MODE_SIZE (mode) <= 4)
- && arm_legitimate_index_p (mode, addend, outer, strict_p));
- }
-
- /* After reload constants split into minipools will have addresses
- from a LABEL_REF. */
- else if (reload_completed
- && (code == LABEL_REF
- || (code == CONST
- && GET_CODE (XEXP (x, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF
- && CONST_INT_P (XEXP (XEXP (x, 0), 1)))))
- return 1;
-
- else if (mode == TImode || (TARGET_NEON && VALID_NEON_STRUCT_MODE (mode)))
- return 0;
-
- else if (code == PLUS)
- {
- rtx xop0 = XEXP (x, 0);
- rtx xop1 = XEXP (x, 1);
-
- return ((arm_address_register_rtx_p (xop0, strict_p)
- && ((CONST_INT_P (xop1)
- && arm_legitimate_index_p (mode, xop1, outer, strict_p))
- || (!strict_p && will_be_in_index_register (xop1))))
- || (arm_address_register_rtx_p (xop1, strict_p)
- && arm_legitimate_index_p (mode, xop0, outer, strict_p)));
- }
-
-#if 0
- /* Reload currently can't handle MINUS, so disable this for now */
- else if (GET_CODE (x) == MINUS)
- {
- rtx xop0 = XEXP (x, 0);
- rtx xop1 = XEXP (x, 1);
-
- return (arm_address_register_rtx_p (xop0, strict_p)
- && arm_legitimate_index_p (mode, xop1, outer, strict_p));
- }
-#endif
-
- else if (GET_MODE_CLASS (mode) != MODE_FLOAT
- && code == SYMBOL_REF
- && CONSTANT_POOL_ADDRESS_P (x)
- && ! (flag_pic
- && symbol_mentioned_p (get_pool_constant (x))
- && ! pcrel_constant_p (get_pool_constant (x))))
- return 1;
-
- return 0;
-}
-
-/* Return nonzero if X is a valid Thumb-2 address operand. */
-static int
-thumb2_legitimate_address_p (enum machine_mode mode, rtx x, int strict_p)
-{
- bool use_ldrd;
- enum rtx_code code = GET_CODE (x);
-
- if (arm_address_register_rtx_p (x, strict_p))
- return 1;
-
- use_ldrd = (TARGET_LDRD
- && (mode == DImode
- || (mode == DFmode && (TARGET_SOFT_FLOAT || TARGET_VFP))));
-
- if (code == POST_INC || code == PRE_DEC
- || ((code == PRE_INC || code == POST_DEC)
- && (use_ldrd || GET_MODE_SIZE (mode) <= 4)))
- return arm_address_register_rtx_p (XEXP (x, 0), strict_p);
-
- else if ((code == POST_MODIFY || code == PRE_MODIFY)
- && arm_address_register_rtx_p (XEXP (x, 0), strict_p)
- && GET_CODE (XEXP (x, 1)) == PLUS
- && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
- {
- /* Thumb-2 only has autoincrement by constant. */
- rtx addend = XEXP (XEXP (x, 1), 1);
- HOST_WIDE_INT offset;
-
- if (!CONST_INT_P (addend))
- return 0;
-
- offset = INTVAL(addend);
- if (GET_MODE_SIZE (mode) <= 4)
- return (offset > -256 && offset < 256);
-
- return (use_ldrd && offset > -1024 && offset < 1024
- && (offset & 3) == 0);
- }
-
- /* After reload constants split into minipools will have addresses
- from a LABEL_REF. */
- else if (reload_completed
- && (code == LABEL_REF
- || (code == CONST
- && GET_CODE (XEXP (x, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF
- && CONST_INT_P (XEXP (XEXP (x, 0), 1)))))
- return 1;
-
- else if (mode == TImode || (TARGET_NEON && VALID_NEON_STRUCT_MODE (mode)))
- return 0;
-
- else if (code == PLUS)
- {
- rtx xop0 = XEXP (x, 0);
- rtx xop1 = XEXP (x, 1);
-
- return ((arm_address_register_rtx_p (xop0, strict_p)
- && (thumb2_legitimate_index_p (mode, xop1, strict_p)
- || (!strict_p && will_be_in_index_register (xop1))))
- || (arm_address_register_rtx_p (xop1, strict_p)
- && thumb2_legitimate_index_p (mode, xop0, strict_p)));
- }
-
- else if (GET_MODE_CLASS (mode) != MODE_FLOAT
- && code == SYMBOL_REF
- && CONSTANT_POOL_ADDRESS_P (x)
- && ! (flag_pic
- && symbol_mentioned_p (get_pool_constant (x))
- && ! pcrel_constant_p (get_pool_constant (x))))
- return 1;
-
- return 0;
-}
-
-/* Return nonzero if INDEX is valid for an address index operand in
- ARM state. */
-static int
-arm_legitimate_index_p (enum machine_mode mode, rtx index, RTX_CODE outer,
- int strict_p)
-{
- HOST_WIDE_INT range;
- enum rtx_code code = GET_CODE (index);
-
- /* Standard coprocessor addressing modes. */
- if (TARGET_HARD_FLOAT
- && TARGET_VFP
- && (mode == SFmode || mode == DFmode))
- return (code == CONST_INT && INTVAL (index) < 1024
- && INTVAL (index) > -1024
- && (INTVAL (index) & 3) == 0);
-
- /* For quad modes, we restrict the constant offset to be slightly less
- than what the instruction format permits. We do this because for
- quad mode moves, we will actually decompose them into two separate
- double-mode reads or writes. INDEX must therefore be a valid
- (double-mode) offset and so should INDEX+8. */
- if (TARGET_NEON && VALID_NEON_QREG_MODE (mode))
- return (code == CONST_INT
- && INTVAL (index) < 1016
- && INTVAL (index) > -1024
- && (INTVAL (index) & 3) == 0);
-
- /* We have no such constraint on double mode offsets, so we permit the
- full range of the instruction format. */
- if (TARGET_NEON && VALID_NEON_DREG_MODE (mode))
- return (code == CONST_INT
- && INTVAL (index) < 1024
- && INTVAL (index) > -1024
- && (INTVAL (index) & 3) == 0);
-
- if (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (mode))
- return (code == CONST_INT
- && INTVAL (index) < 1024
- && INTVAL (index) > -1024
- && (INTVAL (index) & 3) == 0);
-
- if (arm_address_register_rtx_p (index, strict_p)
- && (GET_MODE_SIZE (mode) <= 4))
- return 1;
-
- if (mode == DImode || mode == DFmode)
- {
- if (code == CONST_INT)
- {
- HOST_WIDE_INT val = INTVAL (index);
-
- if (TARGET_LDRD)
- return val > -256 && val < 256;
- else
- return val > -4096 && val < 4092;
- }
-
- return TARGET_LDRD && arm_address_register_rtx_p (index, strict_p);
- }
-
- if (GET_MODE_SIZE (mode) <= 4
- && ! (arm_arch4
- && (mode == HImode
- || mode == HFmode
- || (mode == QImode && outer == SIGN_EXTEND))))
- {
- if (code == MULT)
- {
- rtx xiop0 = XEXP (index, 0);
- rtx xiop1 = XEXP (index, 1);
-
- return ((arm_address_register_rtx_p (xiop0, strict_p)
- && power_of_two_operand (xiop1, SImode))
- || (arm_address_register_rtx_p (xiop1, strict_p)
- && power_of_two_operand (xiop0, SImode)));
- }
- else if (code == LSHIFTRT || code == ASHIFTRT
- || code == ASHIFT || code == ROTATERT)
- {
- rtx op = XEXP (index, 1);
-
- return (arm_address_register_rtx_p (XEXP (index, 0), strict_p)
- && CONST_INT_P (op)
- && INTVAL (op) > 0
- && INTVAL (op) <= 31);
- }
- }
-
- /* For ARM v4 we may be doing a sign-extend operation during the
- load. */
- if (arm_arch4)
- {
- if (mode == HImode
- || mode == HFmode
- || (outer == SIGN_EXTEND && mode == QImode))
- range = 256;
- else
- range = 4096;
- }
- else
- range = (mode == HImode || mode == HFmode) ? 4095 : 4096;
-
- return (code == CONST_INT
- && INTVAL (index) < range
- && INTVAL (index) > -range);
-}
-
-/* Return true if OP is a valid index scaling factor for Thumb-2 address
- index operand. i.e. 1, 2, 4 or 8. */
-static bool
-thumb2_index_mul_operand (rtx op)
-{
- HOST_WIDE_INT val;
-
- if (!CONST_INT_P (op))
- return false;
-
- val = INTVAL(op);
- return (val == 1 || val == 2 || val == 4 || val == 8);
-}
-
-/* Return nonzero if INDEX is a valid Thumb-2 address index operand. */
-static int
-thumb2_legitimate_index_p (enum machine_mode mode, rtx index, int strict_p)
-{
- enum rtx_code code = GET_CODE (index);
-
- /* ??? Combine arm and thumb2 coprocessor addressing modes. */
- /* Standard coprocessor addressing modes. */
- if (TARGET_HARD_FLOAT
- && TARGET_VFP
- && (mode == SFmode || mode == DFmode))
- return (code == CONST_INT && INTVAL (index) < 1024
- /* Thumb-2 allows only > -256 index range for it's core register
- load/stores. Since we allow SF/DF in core registers, we have
- to use the intersection between -256~4096 (core) and -1024~1024
- (coprocessor). */
- && INTVAL (index) > -256
- && (INTVAL (index) & 3) == 0);
-
- if (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (mode))
- {
- /* For DImode assume values will usually live in core regs
- and only allow LDRD addressing modes. */
- if (!TARGET_LDRD || mode != DImode)
- return (code == CONST_INT
- && INTVAL (index) < 1024
- && INTVAL (index) > -1024
- && (INTVAL (index) & 3) == 0);
- }
-
- /* For quad modes, we restrict the constant offset to be slightly less
- than what the instruction format permits. We do this because for
- quad mode moves, we will actually decompose them into two separate
- double-mode reads or writes. INDEX must therefore be a valid
- (double-mode) offset and so should INDEX+8. */
- if (TARGET_NEON && VALID_NEON_QREG_MODE (mode))
- return (code == CONST_INT
- && INTVAL (index) < 1016
- && INTVAL (index) > -1024
- && (INTVAL (index) & 3) == 0);
-
- /* We have no such constraint on double mode offsets, so we permit the
- full range of the instruction format. */
- if (TARGET_NEON && VALID_NEON_DREG_MODE (mode))
- return (code == CONST_INT
- && INTVAL (index) < 1024
- && INTVAL (index) > -1024
- && (INTVAL (index) & 3) == 0);
-
- if (arm_address_register_rtx_p (index, strict_p)
- && (GET_MODE_SIZE (mode) <= 4))
- return 1;
-
- if (mode == DImode || mode == DFmode)
- {
- if (code == CONST_INT)
- {
- HOST_WIDE_INT val = INTVAL (index);
- /* ??? Can we assume ldrd for thumb2? */
- /* Thumb-2 ldrd only has reg+const addressing modes. */
- /* ldrd supports offsets of +-1020.
- However the ldr fallback does not. */
- return val > -256 && val < 256 && (val & 3) == 0;
- }
- else
- return 0;
- }
-
- if (code == MULT)
- {
- rtx xiop0 = XEXP (index, 0);
- rtx xiop1 = XEXP (index, 1);
-
- return ((arm_address_register_rtx_p (xiop0, strict_p)
- && thumb2_index_mul_operand (xiop1))
- || (arm_address_register_rtx_p (xiop1, strict_p)
- && thumb2_index_mul_operand (xiop0)));
- }
- else if (code == ASHIFT)
- {
- rtx op = XEXP (index, 1);
-
- return (arm_address_register_rtx_p (XEXP (index, 0), strict_p)
- && CONST_INT_P (op)
- && INTVAL (op) > 0
- && INTVAL (op) <= 3);
- }
-
- return (code == CONST_INT
- && INTVAL (index) < 4096
- && INTVAL (index) > -256);
-}
-
-/* Return nonzero if X is valid as a 16-bit Thumb state base register. */
-static int
-thumb1_base_register_rtx_p (rtx x, enum machine_mode mode, int strict_p)
-{
- int regno;
-
- if (!REG_P (x))
- return 0;
-
- regno = REGNO (x);
-
- if (strict_p)
- return THUMB1_REGNO_MODE_OK_FOR_BASE_P (regno, mode);
-
- return (regno <= LAST_LO_REGNUM
- || regno > LAST_VIRTUAL_REGISTER
- || regno == FRAME_POINTER_REGNUM
- || (GET_MODE_SIZE (mode) >= 4
- && (regno == STACK_POINTER_REGNUM
- || regno >= FIRST_PSEUDO_REGISTER
- || x == hard_frame_pointer_rtx
- || x == arg_pointer_rtx)));
-}
-
-/* Return nonzero if x is a legitimate index register. This is the case
- for any base register that can access a QImode object. */
-inline static int
-thumb1_index_register_rtx_p (rtx x, int strict_p)
-{
- return thumb1_base_register_rtx_p (x, QImode, strict_p);
-}
-
-/* Return nonzero if x is a legitimate 16-bit Thumb-state address.
-
- The AP may be eliminated to either the SP or the FP, so we use the
- least common denominator, e.g. SImode, and offsets from 0 to 64.
-
- ??? Verify whether the above is the right approach.
-
- ??? Also, the FP may be eliminated to the SP, so perhaps that
- needs special handling also.
-
- ??? Look at how the mips16 port solves this problem. It probably uses
- better ways to solve some of these problems.
-
- Although it is not incorrect, we don't accept QImode and HImode
- addresses based on the frame pointer or arg pointer until the
- reload pass starts. This is so that eliminating such addresses
- into stack based ones won't produce impossible code. */
-int
-thumb1_legitimate_address_p (enum machine_mode mode, rtx x, int strict_p)
-{
- /* ??? Not clear if this is right. Experiment. */
- if (GET_MODE_SIZE (mode) < 4
- && !(reload_in_progress || reload_completed)
- && (reg_mentioned_p (frame_pointer_rtx, x)
- || reg_mentioned_p (arg_pointer_rtx, x)
- || reg_mentioned_p (virtual_incoming_args_rtx, x)
- || reg_mentioned_p (virtual_outgoing_args_rtx, x)
- || reg_mentioned_p (virtual_stack_dynamic_rtx, x)
- || reg_mentioned_p (virtual_stack_vars_rtx, x)))
- return 0;
-
- /* Accept any base register. SP only in SImode or larger. */
- else if (thumb1_base_register_rtx_p (x, mode, strict_p))
- return 1;
-
- /* This is PC relative data before arm_reorg runs. */
- else if (GET_MODE_SIZE (mode) >= 4 && CONSTANT_P (x)
- && GET_CODE (x) == SYMBOL_REF
- && CONSTANT_POOL_ADDRESS_P (x) && !flag_pic)
- return 1;
-
- /* This is PC relative data after arm_reorg runs. */
- 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
- && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF
- && CONST_INT_P (XEXP (XEXP (x, 0), 1)))))
- return 1;
-
- /* Post-inc indexing only supported for SImode and larger. */
- else if (GET_CODE (x) == POST_INC && GET_MODE_SIZE (mode) >= 4
- && thumb1_index_register_rtx_p (XEXP (x, 0), strict_p))
- return 1;
-
- else if (GET_CODE (x) == PLUS)
- {
- /* REG+REG address can be any two index registers. */
- /* We disallow FRAME+REG addressing since we know that FRAME
- will be replaced with STACK, and SP relative addressing only
- permits SP+OFFSET. */
- if (GET_MODE_SIZE (mode) <= 4
- && XEXP (x, 0) != frame_pointer_rtx
- && XEXP (x, 1) != frame_pointer_rtx
- && thumb1_index_register_rtx_p (XEXP (x, 0), strict_p)
- && (thumb1_index_register_rtx_p (XEXP (x, 1), strict_p)
- || (!strict_p && will_be_in_index_register (XEXP (x, 1)))))
- return 1;
-
- /* REG+const has 5-7 bit offset for non-SP registers. */
- else if ((thumb1_index_register_rtx_p (XEXP (x, 0), strict_p)
- || XEXP (x, 0) == arg_pointer_rtx)
- && CONST_INT_P (XEXP (x, 1))
- && thumb_legitimate_offset_p (mode, INTVAL (XEXP (x, 1))))
- return 1;
-
- /* REG+const has 10-bit offset for SP, but only SImode and
- larger is supported. */
- /* ??? Should probably check for DI/DFmode overflow here
- just like GO_IF_LEGITIMATE_OFFSET does. */
- else if (REG_P (XEXP (x, 0))
- && REGNO (XEXP (x, 0)) == STACK_POINTER_REGNUM
- && GET_MODE_SIZE (mode) >= 4
- && CONST_INT_P (XEXP (x, 1))
- && INTVAL (XEXP (x, 1)) >= 0
- && INTVAL (XEXP (x, 1)) + GET_MODE_SIZE (mode) <= 1024
- && (INTVAL (XEXP (x, 1)) & 3) == 0)
- return 1;
-
- else if (REG_P (XEXP (x, 0))
- && (REGNO (XEXP (x, 0)) == FRAME_POINTER_REGNUM
- || REGNO (XEXP (x, 0)) == ARG_POINTER_REGNUM
- || (REGNO (XEXP (x, 0)) >= FIRST_VIRTUAL_REGISTER
- && REGNO (XEXP (x, 0))
- <= LAST_VIRTUAL_POINTER_REGISTER))
- && GET_MODE_SIZE (mode) >= 4
- && CONST_INT_P (XEXP (x, 1))
- && (INTVAL (XEXP (x, 1)) & 3) == 0)
- return 1;
- }
-
- else if (GET_MODE_CLASS (mode) != MODE_FLOAT
- && GET_MODE_SIZE (mode) == 4
- && GET_CODE (x) == SYMBOL_REF
- && CONSTANT_POOL_ADDRESS_P (x)
- && ! (flag_pic
- && symbol_mentioned_p (get_pool_constant (x))
- && ! pcrel_constant_p (get_pool_constant (x))))
- return 1;
-
- return 0;
-}
-
-/* Return nonzero if VAL can be used as an offset in a Thumb-state address
- instruction of mode MODE. */
-int
-thumb_legitimate_offset_p (enum machine_mode mode, HOST_WIDE_INT val)
-{
- switch (GET_MODE_SIZE (mode))
- {
- case 1:
- return val >= 0 && val < 32;
-
- case 2:
- return val >= 0 && val < 64 && (val & 1) == 0;
-
- default:
- return (val >= 0
- && (val + GET_MODE_SIZE (mode)) <= 128
- && (val & 3) == 0);
- }
-}
-
-bool
-arm_legitimate_address_p (enum machine_mode mode, rtx x, bool strict_p)
-{
- if (TARGET_ARM)
- return arm_legitimate_address_outer_p (mode, x, SET, strict_p);
- else if (TARGET_THUMB2)
- return thumb2_legitimate_address_p (mode, x, strict_p);
- else /* if (TARGET_THUMB1) */
- return thumb1_legitimate_address_p (mode, x, strict_p);
-}
-
-/* Worker function for TARGET_PREFERRED_RELOAD_CLASS.
-
- Given an rtx X being reloaded into a reg required to be
- in class CLASS, return the class of reg to actually use.
- In general this is just CLASS, but for the Thumb core registers and
- immediate constants we prefer a LO_REGS class or a subset. */
-
-static reg_class_t
-arm_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, reg_class_t rclass)
-{
- if (TARGET_32BIT)
- return rclass;
- else
- {
- if (rclass == GENERAL_REGS
- || rclass == HI_REGS
- || rclass == NO_REGS
- || rclass == STACK_REG
- || rclass == CORE_REGS)
- return LO_REGS;
- else
- return rclass;
- }
-}
-
-/* Build the SYMBOL_REF for __tls_get_addr. */
-
-static GTY(()) rtx tls_get_addr_libfunc;
-
-static rtx
-get_tls_get_addr (void)
-{
- if (!tls_get_addr_libfunc)
- tls_get_addr_libfunc = init_one_libfunc ("__tls_get_addr");
- return tls_get_addr_libfunc;
-}
-
-rtx
-arm_load_tp (rtx target)
-{
- if (!target)
- target = gen_reg_rtx (SImode);
-
- if (TARGET_HARD_TP)
- {
- /* Can return in any reg. */
- emit_insn (gen_load_tp_hard (target));
- }
- else
- {
- /* Always returned in r0. Immediately copy the result into a pseudo,
- otherwise other uses of r0 (e.g. setting up function arguments) may
- clobber the value. */
-
- rtx tmp;
-
- emit_insn (gen_load_tp_soft ());
-
- tmp = gen_rtx_REG (SImode, 0);
- emit_move_insn (target, tmp);
- }
- return target;
-}
-
-static rtx
-load_tls_operand (rtx x, rtx reg)
-{
- rtx tmp;
-
- if (reg == NULL_RTX)
- reg = gen_reg_rtx (SImode);
-
- tmp = gen_rtx_CONST (SImode, x);
-
- emit_move_insn (reg, tmp);
-
- return reg;
-}
-
-static rtx
-arm_call_tls_get_addr (rtx x, rtx reg, rtx *valuep, int reloc)
-{
- rtx insns, label, labelno, sum;
-
- gcc_assert (reloc != TLS_DESCSEQ);
- start_sequence ();
-
- labelno = GEN_INT (pic_labelno++);
- label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
- label = gen_rtx_CONST (VOIDmode, label);
-
- sum = gen_rtx_UNSPEC (Pmode,
- gen_rtvec (4, x, GEN_INT (reloc), label,
- GEN_INT (TARGET_ARM ? 8 : 4)),
- UNSPEC_TLS);
- reg = load_tls_operand (sum, reg);
-
- if (TARGET_ARM)
- emit_insn (gen_pic_add_dot_plus_eight (reg, reg, labelno));
- else
- emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));
-
- *valuep = emit_library_call_value (get_tls_get_addr (), NULL_RTX,
- LCT_PURE, /* LCT_CONST? */
- Pmode, 1, reg, Pmode);
-
- insns = get_insns ();
- end_sequence ();
-
- return insns;
-}
-
-static rtx
-arm_tls_descseq_addr (rtx x, rtx reg)
-{
- rtx labelno = GEN_INT (pic_labelno++);
- rtx label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
- rtx sum = gen_rtx_UNSPEC (Pmode,
- gen_rtvec (4, x, GEN_INT (TLS_DESCSEQ),
- gen_rtx_CONST (VOIDmode, label),
- GEN_INT (!TARGET_ARM)),
- UNSPEC_TLS);
- rtx reg0 = load_tls_operand (sum, gen_rtx_REG (SImode, 0));
-
- emit_insn (gen_tlscall (x, labelno));
- if (!reg)
- reg = gen_reg_rtx (SImode);
- else
- gcc_assert (REGNO (reg) != 0);
-
- emit_move_insn (reg, reg0);
-
- return reg;
-}
-
-rtx
-legitimize_tls_address (rtx x, rtx reg)
-{
- rtx dest, tp, label, labelno, sum, insns, ret, eqv, addend;
- unsigned int model = SYMBOL_REF_TLS_MODEL (x);
-
- switch (model)
- {
- case TLS_MODEL_GLOBAL_DYNAMIC:
- if (TARGET_GNU2_TLS)
- {
- reg = arm_tls_descseq_addr (x, reg);
-
- tp = arm_load_tp (NULL_RTX);
-
- dest = gen_rtx_PLUS (Pmode, tp, reg);
- }
- else
- {
- /* Original scheme */
- insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32);
- dest = gen_reg_rtx (Pmode);
- emit_libcall_block (insns, dest, ret, x);
- }
- return dest;
-
- case TLS_MODEL_LOCAL_DYNAMIC:
- if (TARGET_GNU2_TLS)
- {
- reg = arm_tls_descseq_addr (x, reg);
-
- tp = arm_load_tp (NULL_RTX);
-
- dest = gen_rtx_PLUS (Pmode, tp, reg);
- }
- else
- {
- insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32);
-
- /* 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, const1_rtx),
- UNSPEC_TLS);
- dest = gen_reg_rtx (Pmode);
- emit_libcall_block (insns, dest, ret, eqv);
-
- /* Load the addend. */
- addend = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, x,
- GEN_INT (TLS_LDO32)),
- UNSPEC_TLS);
- addend = force_reg (SImode, gen_rtx_CONST (SImode, addend));
- dest = gen_rtx_PLUS (Pmode, dest, addend);
- }
- return dest;
-
- case TLS_MODEL_INITIAL_EXEC:
- labelno = GEN_INT (pic_labelno++);
- label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
- label = gen_rtx_CONST (VOIDmode, label);
- sum = gen_rtx_UNSPEC (Pmode,
- gen_rtvec (4, x, GEN_INT (TLS_IE32), label,
- GEN_INT (TARGET_ARM ? 8 : 4)),
- UNSPEC_TLS);
- reg = load_tls_operand (sum, reg);
-
- if (TARGET_ARM)
- emit_insn (gen_tls_load_dot_plus_eight (reg, reg, labelno));
- else if (TARGET_THUMB2)
- emit_insn (gen_tls_load_dot_plus_four (reg, NULL, reg, labelno));
- else
- {
- emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));
- emit_move_insn (reg, gen_const_mem (SImode, reg));
- }
-
- tp = arm_load_tp (NULL_RTX);
-
- return gen_rtx_PLUS (Pmode, tp, reg);
-
- case TLS_MODEL_LOCAL_EXEC:
- tp = arm_load_tp (NULL_RTX);
-
- reg = gen_rtx_UNSPEC (Pmode,
- gen_rtvec (2, x, GEN_INT (TLS_LE32)),
- UNSPEC_TLS);
- reg = force_reg (SImode, gen_rtx_CONST (SImode, reg));
-
- return gen_rtx_PLUS (Pmode, tp, reg);
-
- default:
- abort ();
- }
-}
-
-/* Try machine-dependent ways of modifying an illegitimate address
- to be legitimate. If we find one, return the new, valid address. */
-rtx
-arm_legitimize_address (rtx x, rtx orig_x, enum machine_mode mode)
-{
- if (!TARGET_ARM)
- {
- /* TODO: legitimize_address for Thumb2. */
- if (TARGET_THUMB2)
- return x;
- return thumb_legitimize_address (x, orig_x, mode);
- }
-
- if (arm_tls_symbol_p (x))
- return legitimize_tls_address (x, NULL_RTX);
-
- if (GET_CODE (x) == PLUS)
- {
- rtx xop0 = XEXP (x, 0);
- rtx xop1 = XEXP (x, 1);
-
- if (CONSTANT_P (xop0) && !symbol_mentioned_p (xop0))
- xop0 = force_reg (SImode, xop0);
-
- if (CONSTANT_P (xop1) && !symbol_mentioned_p (xop1))
- xop1 = force_reg (SImode, xop1);
-
- if (ARM_BASE_REGISTER_RTX_P (xop0)
- && CONST_INT_P (xop1))
- {
- HOST_WIDE_INT n, low_n;
- rtx base_reg, val;
- n = INTVAL (xop1);
-
- /* VFP addressing modes actually allow greater offsets, but for
- now we just stick with the lowest common denominator. */
- if (mode == DImode
- || ((TARGET_SOFT_FLOAT || TARGET_VFP) && mode == DFmode))
- {
- low_n = n & 0x0f;
- n &= ~0x0f;
- if (low_n > 4)
- {
- n += 16;
- low_n -= 16;
- }
- }
- else
- {
- low_n = ((mode) == TImode ? 0
- : n >= 0 ? (n & 0xfff) : -((-n) & 0xfff));
- n -= low_n;
- }
-
- base_reg = gen_reg_rtx (SImode);
- val = force_operand (plus_constant (Pmode, xop0, n), NULL_RTX);
- emit_move_insn (base_reg, val);
- x = plus_constant (Pmode, base_reg, low_n);
- }
- else if (xop0 != XEXP (x, 0) || xop1 != XEXP (x, 1))
- x = gen_rtx_PLUS (SImode, xop0, xop1);
- }
-
- /* XXX We don't allow MINUS any more -- see comment in
- arm_legitimate_address_outer_p (). */
- else if (GET_CODE (x) == MINUS)
- {
- rtx xop0 = XEXP (x, 0);
- rtx xop1 = XEXP (x, 1);
-
- if (CONSTANT_P (xop0))
- xop0 = force_reg (SImode, xop0);
-
- if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1))
- xop1 = force_reg (SImode, xop1);
-
- if (xop0 != XEXP (x, 0) || xop1 != XEXP (x, 1))
- x = gen_rtx_MINUS (SImode, xop0, xop1);
- }
-
- /* Make sure to take full advantage of the pre-indexed addressing mode
- with absolute addresses which often allows for the base register to
- be factorized for multiple adjacent memory references, and it might
- even allows for the mini pool to be avoided entirely. */
- else if (CONST_INT_P (x) && optimize > 0)
- {
- unsigned int bits;
- HOST_WIDE_INT mask, base, index;
- rtx base_reg;
-
- /* ldr and ldrb can use a 12-bit index, ldrsb and the rest can only
- use a 8-bit index. So let's use a 12-bit index for SImode only and
- hope that arm_gen_constant will enable ldrb to use more bits. */
- bits = (mode == SImode) ? 12 : 8;
- mask = (1 << bits) - 1;
- base = INTVAL (x) & ~mask;
- index = INTVAL (x) & mask;
- if (bit_count (base & 0xffffffff) > (32 - bits)/2)
- {
- /* It'll most probably be more efficient to generate the base
- with more bits set and use a negative index instead. */
- base |= mask;
- index -= mask;
- }
- base_reg = force_reg (SImode, GEN_INT (base));
- x = plus_constant (Pmode, base_reg, index);
- }
-
- if (flag_pic)
- {
- /* We need to find and carefully transform any SYMBOL and LABEL
- references; so go back to the original address expression. */
- rtx new_x = legitimize_pic_address (orig_x, mode, NULL_RTX);
-
- if (new_x != orig_x)
- x = new_x;
- }
-
- return x;
-}
-
-
-/* Try machine-dependent ways of modifying an illegitimate Thumb address
- to be legitimate. If we find one, return the new, valid address. */
-rtx
-thumb_legitimize_address (rtx x, rtx orig_x, enum machine_mode mode)
-{
- if (arm_tls_symbol_p (x))
- return legitimize_tls_address (x, NULL_RTX);
-
- if (GET_CODE (x) == PLUS
- && CONST_INT_P (XEXP (x, 1))
- && (INTVAL (XEXP (x, 1)) >= 32 * GET_MODE_SIZE (mode)
- || INTVAL (XEXP (x, 1)) < 0))
- {
- rtx xop0 = XEXP (x, 0);
- rtx xop1 = XEXP (x, 1);
- HOST_WIDE_INT offset = INTVAL (xop1);
-
- /* Try and fold the offset into a biasing of the base register and
- then offsetting that. Don't do this when optimizing for space
- since it can cause too many CSEs. */
- if (optimize_size && offset >= 0
- && offset < 256 + 31 * GET_MODE_SIZE (mode))
- {
- HOST_WIDE_INT delta;
-
- if (offset >= 256)
- delta = offset - (256 - GET_MODE_SIZE (mode));
- else if (offset < 32 * GET_MODE_SIZE (mode) + 8)
- delta = 31 * GET_MODE_SIZE (mode);
- else
- delta = offset & (~31 * GET_MODE_SIZE (mode));
-
- xop0 = force_operand (plus_constant (Pmode, xop0, offset - delta),
- NULL_RTX);
- x = plus_constant (Pmode, xop0, delta);
- }
- else if (offset < 0 && offset > -256)
- /* Small negative offsets are best done with a subtract before the
- dereference, forcing these into a register normally takes two
- instructions. */
- x = force_operand (x, NULL_RTX);
- else
- {
- /* For the remaining cases, force the constant into a register. */
- xop1 = force_reg (SImode, xop1);
- x = gen_rtx_PLUS (SImode, xop0, xop1);
- }
- }
- else if (GET_CODE (x) == PLUS
- && s_register_operand (XEXP (x, 1), SImode)
- && !s_register_operand (XEXP (x, 0), SImode))
- {
- rtx xop0 = force_operand (XEXP (x, 0), NULL_RTX);
-
- x = gen_rtx_PLUS (SImode, xop0, XEXP (x, 1));
- }
-
- if (flag_pic)
- {
- /* We need to find and carefully transform any SYMBOL and LABEL
- references; so go back to the original address expression. */
- rtx new_x = legitimize_pic_address (orig_x, mode, NULL_RTX);
-
- if (new_x != orig_x)
- x = new_x;
- }
-
- return x;
-}
-
-bool
-arm_legitimize_reload_address (rtx *p,
- enum machine_mode mode,
- int opnum, int type,
- int ind_levels ATTRIBUTE_UNUSED)
-{
- /* We must recognize output that we have already generated ourselves. */
- if (GET_CODE (*p) == PLUS
- && GET_CODE (XEXP (*p, 0)) == PLUS
- && REG_P (XEXP (XEXP (*p, 0), 0))
- && CONST_INT_P (XEXP (XEXP (*p, 0), 1))
- && CONST_INT_P (XEXP (*p, 1)))
- {
- push_reload (XEXP (*p, 0), NULL_RTX, &XEXP (*p, 0), NULL,
- MODE_BASE_REG_CLASS (mode), GET_MODE (*p),
- VOIDmode, 0, 0, opnum, (enum reload_type) type);
- return true;
- }
-
- if (GET_CODE (*p) == PLUS
- && REG_P (XEXP (*p, 0))
- && ARM_REGNO_OK_FOR_BASE_P (REGNO (XEXP (*p, 0)))
- /* If the base register is equivalent to a constant, let the generic
- code handle it. Otherwise we will run into problems if a future
- reload pass decides to rematerialize the constant. */
- && !reg_equiv_constant (ORIGINAL_REGNO (XEXP (*p, 0)))
- && CONST_INT_P (XEXP (*p, 1)))
- {
- HOST_WIDE_INT val = INTVAL (XEXP (*p, 1));
- HOST_WIDE_INT low, high;
-
- /* Detect coprocessor load/stores. */
- bool coproc_p = ((TARGET_HARD_FLOAT
- && TARGET_VFP
- && (mode == SFmode || mode == DFmode))
- || (TARGET_REALLY_IWMMXT
- && VALID_IWMMXT_REG_MODE (mode))
- || (TARGET_NEON
- && (VALID_NEON_DREG_MODE (mode)
- || VALID_NEON_QREG_MODE (mode))));
-
- /* For some conditions, bail out when lower two bits are unaligned. */
- if ((val & 0x3) != 0
- /* Coprocessor load/store indexes are 8-bits + '00' appended. */
- && (coproc_p
- /* For DI, and DF under soft-float: */
- || ((mode == DImode || mode == DFmode)
- /* Without ldrd, we use stm/ldm, which does not
- fair well with unaligned bits. */
- && (! TARGET_LDRD
- /* Thumb-2 ldrd/strd is [-1020,+1020] in steps of 4. */
- || TARGET_THUMB2))))
- return false;
-
- /* When breaking down a [reg+index] reload address into [(reg+high)+low],
- of which the (reg+high) gets turned into a reload add insn,
- we try to decompose the index into high/low values that can often
- also lead to better reload CSE.
- For example:
- ldr r0, [r2, #4100] // Offset too large
- ldr r1, [r2, #4104] // Offset too large
-
- is best reloaded as:
- add t1, r2, #4096
- ldr r0, [t1, #4]
- add t2, r2, #4096
- ldr r1, [t2, #8]
-
- which post-reload CSE can simplify in most cases to eliminate the
- second add instruction:
- add t1, r2, #4096
- ldr r0, [t1, #4]
- ldr r1, [t1, #8]
-
- The idea here is that we want to split out the bits of the constant
- as a mask, rather than as subtracting the maximum offset that the
- respective type of load/store used can handle.
-
- When encountering negative offsets, we can still utilize it even if
- the overall offset is positive; sometimes this may lead to an immediate
- that can be constructed with fewer instructions.
- For example:
- ldr r0, [r2, #0x3FFFFC]
-
- This is best reloaded as:
- add t1, r2, #0x400000
- ldr r0, [t1, #-4]
-
- The trick for spotting this for a load insn with N bits of offset
- (i.e. bits N-1:0) is to look at bit N; if it is set, then chose a
- negative offset that is going to make bit N and all the bits below
- it become zero in the remainder part.
-
- The SIGN_MAG_LOW_ADDR_BITS macro below implements this, with respect
- to sign-magnitude addressing (i.e. separate +- bit, or 1's complement),
- used in most cases of ARM load/store instructions. */
-
-#define SIGN_MAG_LOW_ADDR_BITS(VAL, N) \
- (((VAL) & ((1 << (N)) - 1)) \
- ? (((VAL) & ((1 << ((N) + 1)) - 1)) ^ (1 << (N))) - (1 << (N)) \
- : 0)
-
- if (coproc_p)
- {
- low = SIGN_MAG_LOW_ADDR_BITS (val, 10);
-
- /* NEON quad-word load/stores are made of two double-word accesses,
- so the valid index range is reduced by 8. Treat as 9-bit range if
- we go over it. */
- if (TARGET_NEON && VALID_NEON_QREG_MODE (mode) && low >= 1016)
- low = SIGN_MAG_LOW_ADDR_BITS (val, 9);
- }
- else if (GET_MODE_SIZE (mode) == 8)
- {
- if (TARGET_LDRD)
- low = (TARGET_THUMB2
- ? SIGN_MAG_LOW_ADDR_BITS (val, 10)
- : SIGN_MAG_LOW_ADDR_BITS (val, 8));
- else
- /* For pre-ARMv5TE (without ldrd), we use ldm/stm(db/da/ib)
- to access doublewords. The supported load/store offsets are
- -8, -4, and 4, which we try to produce here. */
- low = ((val & 0xf) ^ 0x8) - 0x8;
- }
- else if (GET_MODE_SIZE (mode) < 8)
- {
- /* NEON element load/stores do not have an offset. */
- if (TARGET_NEON_FP16 && mode == HFmode)
- return false;
-
- if (TARGET_THUMB2)
- {
- /* Thumb-2 has an asymmetrical index range of (-256,4096).
- Try the wider 12-bit range first, and re-try if the result
- is out of range. */
- low = SIGN_MAG_LOW_ADDR_BITS (val, 12);
- if (low < -255)
- low = SIGN_MAG_LOW_ADDR_BITS (val, 8);
- }
- else
- {
- if (mode == HImode || mode == HFmode)
- {
- if (arm_arch4)
- low = SIGN_MAG_LOW_ADDR_BITS (val, 8);
- else
- {
- /* The storehi/movhi_bytes fallbacks can use only
- [-4094,+4094] of the full ldrb/strb index range. */
- low = SIGN_MAG_LOW_ADDR_BITS (val, 12);
- if (low == 4095 || low == -4095)
- return false;
- }
- }
- else
- low = SIGN_MAG_LOW_ADDR_BITS (val, 12);
- }
- }
- else
- return false;
-
- high = ((((val - low) & (unsigned HOST_WIDE_INT) 0xffffffff)
- ^ (unsigned HOST_WIDE_INT) 0x80000000)
- - (unsigned HOST_WIDE_INT) 0x80000000);
- /* Check for overflow or zero */
- if (low == 0 || high == 0 || (high + low != val))
- return false;
-
- /* Reload the high part into a base reg; leave the low part
- in the mem. */
- *p = gen_rtx_PLUS (GET_MODE (*p),
- gen_rtx_PLUS (GET_MODE (*p), XEXP (*p, 0),
- GEN_INT (high)),
- GEN_INT (low));
- push_reload (XEXP (*p, 0), NULL_RTX, &XEXP (*p, 0), NULL,
- MODE_BASE_REG_CLASS (mode), GET_MODE (*p),
- VOIDmode, 0, 0, opnum, (enum reload_type) type);
- return true;
- }
-
- return false;
-}
-
-rtx
-thumb_legitimize_reload_address (rtx *x_p,
- enum machine_mode mode,
- int opnum, int type,
- int ind_levels ATTRIBUTE_UNUSED)
-{
- rtx x = *x_p;
-
- if (GET_CODE (x) == PLUS
- && GET_MODE_SIZE (mode) < 4
- && REG_P (XEXP (x, 0))
- && XEXP (x, 0) == stack_pointer_rtx
- && CONST_INT_P (XEXP (x, 1))
- && !thumb_legitimate_offset_p (mode, INTVAL (XEXP (x, 1))))
- {
- rtx orig_x = x;
-
- x = copy_rtx (x);
- push_reload (orig_x, NULL_RTX, x_p, NULL, MODE_BASE_REG_CLASS (mode),
- Pmode, VOIDmode, 0, 0, opnum, (enum reload_type) type);
- return x;
- }
-
- /* If both registers are hi-regs, then it's better to reload the
- entire expression rather than each register individually. That
- only requires one reload register rather than two. */
- if (GET_CODE (x) == PLUS
- && REG_P (XEXP (x, 0))
- && REG_P (XEXP (x, 1))
- && !REG_MODE_OK_FOR_REG_BASE_P (XEXP (x, 0), mode)
- && !REG_MODE_OK_FOR_REG_BASE_P (XEXP (x, 1), mode))
- {
- rtx orig_x = x;
-
- x = copy_rtx (x);
- push_reload (orig_x, NULL_RTX, x_p, NULL, MODE_BASE_REG_CLASS (mode),
- Pmode, VOIDmode, 0, 0, opnum, (enum reload_type) type);
- return x;
- }
-
- return NULL;
-}
-
-/* Test for various thread-local symbols. */
-
-/* Return TRUE if X is a thread-local symbol. */
-
-static bool
-arm_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 arm_tls_referenced_p. */
-
-static int
-arm_tls_operand_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_TLS)
- return -1;
-
- return 0;
-}
-
-/* Return TRUE if X contains any TLS symbol references. */
-
-bool
-arm_tls_referenced_p (rtx x)
-{
- if (! TARGET_HAVE_TLS)
- return false;
-
- return for_each_rtx (&x, arm_tls_operand_p_1, NULL);
-}
-
-/* Implement TARGET_LEGITIMATE_CONSTANT_P.
-
- On the ARM, allow any integer (invalid ones are removed later by insn
- patterns), nice doubles and symbol_refs which refer to the function's
- constant pool XXX.
-
- When generating pic allow anything. */
-
-static bool
-arm_legitimate_constant_p_1 (enum machine_mode mode, rtx x)
-{
- /* At present, we have no support for Neon structure constants, so forbid
- them here. It might be possible to handle simple cases like 0 and -1
- in future. */
- if (TARGET_NEON && VALID_NEON_STRUCT_MODE (mode))
- return false;
-
- return flag_pic || !label_mentioned_p (x);
-}
-
-static bool
-thumb_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
-{
- return (CONST_INT_P (x)
- || CONST_DOUBLE_P (x)
- || CONSTANT_ADDRESS_P (x)
- || flag_pic);
-}
-
-static bool
-arm_legitimate_constant_p (enum machine_mode mode, rtx x)
-{
- return (!arm_cannot_force_const_mem (mode, x)
- && (TARGET_32BIT
- ? arm_legitimate_constant_p_1 (mode, x)
- : thumb_legitimate_constant_p (mode, x)));
-}
-
-/* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
-
-static bool
-arm_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
-{
- rtx base, offset;
-
- if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
- {
- split_const (x, &base, &offset);
- if (GET_CODE (base) == SYMBOL_REF
- && !offset_within_block_p (base, INTVAL (offset)))
- return true;
- }
- return arm_tls_referenced_p (x);
-}
-
-#define REG_OR_SUBREG_REG(X) \
- (REG_P (X) \
- || (GET_CODE (X) == SUBREG && REG_P (SUBREG_REG (X))))
-
-#define REG_OR_SUBREG_RTX(X) \
- (REG_P (X) ? (X) : SUBREG_REG (X))
-
-static inline int
-thumb1_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer)
-{
- enum machine_mode mode = GET_MODE (x);
- int total;
-
- switch (code)
- {
- case ASHIFT:
- case ASHIFTRT:
- case LSHIFTRT:
- case ROTATERT:
- case PLUS:
- case MINUS:
- case COMPARE:
- case NEG:
- case NOT:
- return COSTS_N_INSNS (1);
-
- case MULT:
- if (CONST_INT_P (XEXP (x, 1)))
- {
- int cycles = 0;
- unsigned HOST_WIDE_INT i = INTVAL (XEXP (x, 1));
-
- while (i)
- {
- i >>= 2;
- cycles++;
- }
- return COSTS_N_INSNS (2) + cycles;
- }
- return COSTS_N_INSNS (1) + 16;
-
- case SET:
- return (COSTS_N_INSNS (1)
- + 4 * ((MEM_P (SET_SRC (x)))
- + MEM_P (SET_DEST (x))));
-
- case CONST_INT:
- if (outer == SET)
- {
- if ((unsigned HOST_WIDE_INT) INTVAL (x) < 256)
- return 0;
- if (thumb_shiftable_const (INTVAL (x)))
- return COSTS_N_INSNS (2);
- return COSTS_N_INSNS (3);
- }
- else if ((outer == PLUS || outer == COMPARE)
- && INTVAL (x) < 256 && INTVAL (x) > -256)
- return 0;
- else if ((outer == IOR || outer == XOR || outer == AND)
- && INTVAL (x) < 256 && INTVAL (x) >= -256)
- return COSTS_N_INSNS (1);
- else if (outer == AND)
- {
- int i;
- /* This duplicates the tests in the andsi3 expander. */
- for (i = 9; i <= 31; i++)
- if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (x)
- || (((HOST_WIDE_INT) 1) << i) - 1 == ~INTVAL (x))
- return COSTS_N_INSNS (2);
- }
- else if (outer == ASHIFT || outer == ASHIFTRT
- || outer == LSHIFTRT)
- return 0;
- return COSTS_N_INSNS (2);
-
- case CONST:
- case CONST_DOUBLE:
- case LABEL_REF:
- case SYMBOL_REF:
- return COSTS_N_INSNS (3);
-
- case UDIV:
- case UMOD:
- case DIV:
- case MOD:
- return 100;
-
- case TRUNCATE:
- return 99;
-
- case AND:
- case XOR:
- case IOR:
- /* XXX guess. */
- return 8;
-
- case MEM:
- /* XXX another guess. */
- /* 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));
-
- case IF_THEN_ELSE:
- /* XXX a guess. */
- if (GET_CODE (XEXP (x, 1)) == PC || GET_CODE (XEXP (x, 2)) == PC)
- return 14;
- return 2;
-
- case SIGN_EXTEND:
- case ZERO_EXTEND:
- total = mode == DImode ? COSTS_N_INSNS (1) : 0;
- total += thumb1_rtx_costs (XEXP (x, 0), GET_CODE (XEXP (x, 0)), code);
-
- if (mode == SImode)
- return total;
-
- if (arm_arch6)
- return total + COSTS_N_INSNS (1);
-
- /* Assume a two-shift sequence. Increase the cost slightly so
- we prefer actual shifts over an extend operation. */
- return total + 1 + COSTS_N_INSNS (2);
-
- default:
- return 99;
- }
-}
-
-static inline bool
-arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed)
-{
- enum machine_mode mode = GET_MODE (x);
- enum rtx_code subcode;
- rtx operand;
- enum rtx_code code = GET_CODE (x);
- *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 && !TARGET_VFP_SINGLE)
- *total = COSTS_N_INSNS (4);
- else
- *total = COSTS_N_INSNS (20);
- return false;
-
- case ROTATE:
- if (REG_P (XEXP (x, 1)))
- *total = COSTS_N_INSNS (1); /* Need to subtract from 32 */
- else if (!CONST_INT_P (XEXP (x, 1)))
- *total = rtx_cost (XEXP (x, 1), code, 1, speed);
-
- /* 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, 0, speed);
- 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 && !CONST_INT_P (XEXP (x, 1)))
- ++*total;
-
- return true;
-
- case MINUS:
- if (mode == DImode)
- {
- *total = COSTS_N_INSNS (ARM_NUM_REGS (mode));
- if (CONST_INT_P (XEXP (x, 0))
- && const_ok_for_arm (INTVAL (XEXP (x, 0))))
- {
- *total += rtx_cost (XEXP (x, 1), code, 1, speed);
- return true;
- }
-
- if (CONST_INT_P (XEXP (x, 1))
- && const_ok_for_arm (INTVAL (XEXP (x, 1))))
- {
- *total += rtx_cost (XEXP (x, 0), code, 0, speed);
- return true;
- }
-
- return false;
- }
-
- if (GET_MODE_CLASS (mode) == MODE_FLOAT)
- {
- if (TARGET_HARD_FLOAT
- && (mode == SFmode
- || (mode == DFmode && !TARGET_VFP_SINGLE)))
- {
- *total = COSTS_N_INSNS (1);
- if (CONST_DOUBLE_P (XEXP (x, 0))
- && arm_const_double_rtx (XEXP (x, 0)))
- {
- *total += rtx_cost (XEXP (x, 1), code, 1, speed);
- return true;
- }
-
- if (CONST_DOUBLE_P (XEXP (x, 1))
- && arm_const_double_rtx (XEXP (x, 1)))
- {
- *total += rtx_cost (XEXP (x, 0), code, 0, speed);
- return true;
- }
-
- return false;
- }
- *total = COSTS_N_INSNS (20);
- return false;
- }
-
- *total = COSTS_N_INSNS (1);
- if (CONST_INT_P (XEXP (x, 0))
- && const_ok_for_arm (INTVAL (XEXP (x, 0))))
- {
- *total += rtx_cost (XEXP (x, 1), code, 1, speed);
- 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, 0, speed);
- *total += rtx_cost (XEXP (XEXP (x, 1), 0), subcode, 0, speed);
- return true;
- }
-
- /* A shift as a part of RSB costs no more than RSB itself. */
- if (GET_CODE (XEXP (x, 0)) == MULT
- && power_of_two_operand (XEXP (XEXP (x, 0), 1), SImode))
- {
- *total += rtx_cost (XEXP (XEXP (x, 0), 0), code, 0, speed);
- *total += rtx_cost (XEXP (x, 1), code, 1, speed);
- return true;
- }
-
- if (subcode == MULT
- && power_of_two_operand (XEXP (XEXP (x, 1), 1), SImode))
- {
- *total += rtx_cost (XEXP (x, 0), code, 0, speed);
- *total += rtx_cost (XEXP (XEXP (x, 1), 0), subcode, 0, speed);
- return true;
- }
-
- 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, 0, speed);
- if (REG_P (XEXP (XEXP (x, 1), 0))
- && REGNO (XEXP (XEXP (x, 1), 0)) != CC_REGNUM)
- *total += COSTS_N_INSNS (1);
-
- return true;
- }
-
- /* Fall through */
-
- case PLUS:
- 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)),
- 0, speed);
- *total += rtx_cost (XEXP (x, 1), code, 1, speed);
- 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
- && !power_of_two_operand (XEXP (XEXP (x, 0), 1), SImode))
- {
- /* The cost comes from the cost of the multiply. */
- return false;
- }
-
- if (GET_MODE_CLASS (mode) == MODE_FLOAT)
- {
- if (TARGET_HARD_FLOAT
- && (mode == SFmode
- || (mode == DFmode && !TARGET_VFP_SINGLE)))
- {
- *total = COSTS_N_INSNS (1);
- if (CONST_DOUBLE_P (XEXP (x, 1))
- && arm_const_double_rtx (XEXP (x, 1)))
- {
- *total += rtx_cost (XEXP (x, 0), code, 0, speed);
- 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, 1, speed);
- if (REG_P (XEXP (XEXP (x, 0), 0))
- && REGNO (XEXP (XEXP (x, 0), 0)) != CC_REGNUM)
- *total += COSTS_N_INSNS (1);
- return true;
- }
-
- /* Fall through */
-
- case AND: case XOR: case IOR:
-
- /* Normally the frame registers will be spilt into reg+const during
- reload, so it is a bad idea to combine them with other instructions,
- since then they might not be moved outside of loops. As a compromise
- we allow integration with ops that have a constant as their second
- operand. */
- if (REG_OR_SUBREG_REG (XEXP (x, 0))
- && ARM_FRAME_RTX (REG_OR_SUBREG_RTX (XEXP (x, 0)))
- && !CONST_INT_P (XEXP (x, 1)))
- *total = COSTS_N_INSNS (1);
-
- if (mode == DImode)
- {
- *total += COSTS_N_INSNS (2);
- if (CONST_INT_P (XEXP (x, 1))
- && const_ok_for_op (INTVAL (XEXP (x, 1)), code))
- {
- *total += rtx_cost (XEXP (x, 0), code, 0, speed);
- return true;
- }
-
- return false;
- }
-
- *total += COSTS_N_INSNS (1);
- if (CONST_INT_P (XEXP (x, 1))
- && const_ok_for_op (INTVAL (XEXP (x, 1)), code))
- {
- *total += rtx_cost (XEXP (x, 0), code, 0, speed);
- 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, 1, speed);
- *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode, 0, speed);
- return true;
- }
-
- if (subcode == MULT
- && power_of_two_operand (XEXP (XEXP (x, 0), 1), SImode))
- {
- *total += rtx_cost (XEXP (x, 1), code, 1, speed);
- *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode, 0, speed);
- 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. */
- gcc_unreachable ();
-
- case TRUNCATE:
- if (arm_arch3m && mode == SImode
- && GET_CODE (XEXP (x, 0)) == LSHIFTRT
- && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
- && (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0))
- == 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))
- {
- *total = rtx_cost (XEXP (XEXP (x, 0), 0), LSHIFTRT, 0, speed);
- return true;
- }
- *total = COSTS_N_INSNS (2); /* Plus the cost of the MULT */
- return false;
-
- case NEG:
- if (GET_MODE_CLASS (mode) == MODE_FLOAT)
- {
- if (TARGET_HARD_FLOAT
- && (mode == SFmode
- || (mode == DFmode && !TARGET_VFP_SINGLE)))
- {
- *total = COSTS_N_INSNS (1);
- return false;
- }
- *total = COSTS_N_INSNS (2);
- return false;
- }
-
- /* Fall through */
- case NOT:
- *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
- && power_of_two_operand (XEXP (XEXP (x, 0), 1), SImode)))
- {
- *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode, 0, speed);
- /* Register shifts cost an extra cycle. */
- if (!CONST_INT_P (XEXP (XEXP (x, 0), 1)))
- *total += COSTS_N_INSNS (1) + rtx_cost (XEXP (XEXP (x, 0), 1),
- subcode, 1, speed);
- return true;
- }
- }
-
- return false;
-
- case IF_THEN_ELSE:
- if (GET_CODE (XEXP (x, 1)) == PC || GET_CODE (XEXP (x, 2)) == PC)
- {
- *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)
- && REG_P (XEXP (operand, 0))
- && REGNO (XEXP (operand, 0)) == CC_REGNUM))
- *total += COSTS_N_INSNS (1);
- *total += (rtx_cost (XEXP (x, 1), code, 1, speed)
- + rtx_cost (XEXP (x, 2), code, 2, speed));
- return true;
-
- case NE:
- if (mode == SImode && XEXP (x, 1) == const0_rtx)
- {
- *total = COSTS_N_INSNS (2) + rtx_cost (XEXP (x, 0), code, 0, speed);
- return true;
- }
- goto scc_insn;
-
- case GE:
- if ((!REG_P (XEXP (x, 0)) || REGNO (XEXP (x, 0)) != CC_REGNUM)
- && mode == SImode && XEXP (x, 1) == const0_rtx)
- {
- *total = COSTS_N_INSNS (2) + rtx_cost (XEXP (x, 0), code, 0, speed);
- return true;
- }
- goto scc_insn;
-
- case LT:
- if ((!REG_P (XEXP (x, 0)) || REGNO (XEXP (x, 0)) != CC_REGNUM)
- && mode == SImode && XEXP (x, 1) == const0_rtx)
- {
- *total = COSTS_N_INSNS (1) + rtx_cost (XEXP (x, 0), code, 0, speed);
- 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 (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) == CC_REGNUM)
- {
- return true;
- }
-
- /* Fall through */
- case COMPARE:
- if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) == CC_REGNUM)
- {
- *total = 0;
- return true;
- }
-
- *total += COSTS_N_INSNS (1);
- if (CONST_INT_P (XEXP (x, 1))
- && const_ok_for_op (INTVAL (XEXP (x, 1)), code))
- {
- *total += rtx_cost (XEXP (x, 0), code, 0, speed);
- 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, 1, speed);
- *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode, 0, speed);
- return true;
- }
-
- if (subcode == MULT
- && power_of_two_operand (XEXP (XEXP (x, 0), 1), SImode))
- {
- *total += rtx_cost (XEXP (x, 1), code, 1, speed);
- *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode, 0, speed);
- return true;
- }
-
- return false;
-
- case UMIN:
- case UMAX:
- case SMIN:
- case SMAX:
- *total = COSTS_N_INSNS (2) + rtx_cost (XEXP (x, 0), code, 0, speed);
- if (!CONST_INT_P (XEXP (x, 1))
- || !const_ok_for_arm (INTVAL (XEXP (x, 1))))
- *total += rtx_cost (XEXP (x, 1), code, 1, speed);
- return true;
-
- case ABS:
- if (GET_MODE_CLASS (mode) == MODE_FLOAT)
- {
- if (TARGET_HARD_FLOAT
- && (mode == SFmode
- || (mode == DFmode && !TARGET_VFP_SINGLE)))
- {
- *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:
- case ZERO_EXTEND:
- *total = 0;
- if (GET_MODE_CLASS (mode) == MODE_INT)
- {
- rtx op = XEXP (x, 0);
- enum machine_mode opmode = GET_MODE (op);
-
- if (mode == DImode)
- *total += COSTS_N_INSNS (1);
-
- if (opmode != SImode)
- {
- if (MEM_P (op))
- {
- /* If !arm_arch4, we use one of the extendhisi2_mem
- or movhi_bytes patterns for HImode. For a QImode
- sign extension, we first zero-extend from memory
- and then perform a shift sequence. */
- if (!arm_arch4 && (opmode != QImode || code == SIGN_EXTEND))
- *total += COSTS_N_INSNS (2);
- }
- else if (arm_arch6)
- *total += COSTS_N_INSNS (1);
-
- /* We don't have the necessary insn, so we need to perform some
- other operation. */
- else if (TARGET_ARM && code == ZERO_EXTEND && mode == QImode)
- /* An and with constant 255. */
- *total += COSTS_N_INSNS (1);
- else
- /* A shift sequence. Increase costs slightly to avoid
- combining two shifts into an extend operation. */
- *total += COSTS_N_INSNS (2) + 1;
- }
-
- return false;
- }
-
- switch (GET_MODE (XEXP (x, 0)))
- {
- case V8QImode:
- case V4HImode:
- case V2SImode:
- case V4QImode:
- case V2HImode:
- *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, 0, speed);
- return true;
-
- case CONST_INT:
- if (const_ok_for_arm (INTVAL (x))
- || const_ok_for_arm (~INTVAL (x)))
- *total = COSTS_N_INSNS (1);
- else
- *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:
- *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, 0, speed);
- return true;
-
- case CONST_DOUBLE:
- 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);
- return true;
-
- case SET:
- /* The vec_extract patterns accept memory operands that require an
- address reload. Account for the cost of that reload to give the
- auto-inc-dec pass an incentive to try to replace them. */
- if (TARGET_NEON && MEM_P (SET_DEST (x))
- && GET_CODE (SET_SRC (x)) == VEC_SELECT)
- {
- *total = rtx_cost (SET_DEST (x), code, 0, speed);
- if (!neon_vector_mem_operand (SET_DEST (x), 2))
- *total += COSTS_N_INSNS (1);
- return true;
- }
- /* Likewise for the vec_set patterns. */
- if (TARGET_NEON && GET_CODE (SET_SRC (x)) == VEC_MERGE
- && GET_CODE (XEXP (SET_SRC (x), 0)) == VEC_DUPLICATE
- && MEM_P (XEXP (XEXP (SET_SRC (x), 0), 0)))
- {
- rtx mem = XEXP (XEXP (SET_SRC (x), 0), 0);
- *total = rtx_cost (mem, code, 0, speed);
- if (!neon_vector_mem_operand (mem, 2))
- *total += COSTS_N_INSNS (1);
- return true;
- }
- return false;
-
- case UNSPEC:
- /* We cost this as high as our memory costs to allow this to
- be hoisted from loops. */
- if (XINT (x, 1) == UNSPEC_PIC_UNIFIED)
- {
- *total = COSTS_N_INSNS (2 + ARM_NUM_REGS (mode));
- }
- return true;
-
- case CONST_VECTOR:
- if (TARGET_NEON
- && TARGET_HARD_FLOAT
- && outer == SET
- && (VALID_NEON_DREG_MODE (mode) || VALID_NEON_QREG_MODE (mode))
- && neon_immediate_valid_for_move (x, mode, NULL, NULL))
- *total = COSTS_N_INSNS (1);
- else
- *total = COSTS_N_INSNS (4);
- return true;
-
- default:
- *total = COSTS_N_INSNS (4);
- return false;
- }
-}
-
-/* Estimates the size cost of thumb1 instructions.
- For now most of the code is copied from thumb1_rtx_costs. We need more
- fine grain tuning when we have more related test cases. */
-static inline int
-thumb1_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer)
-{
- enum machine_mode mode = GET_MODE (x);
-
- switch (code)
- {
- case ASHIFT:
- case ASHIFTRT:
- case LSHIFTRT:
- case ROTATERT:
- case PLUS:
- case MINUS:
- case COMPARE:
- case NEG:
- case NOT:
- return COSTS_N_INSNS (1);
-
- case MULT:
- if (CONST_INT_P (XEXP (x, 1)))
- {
- /* Thumb1 mul instruction can't operate on const. We must Load it
- into a register first. */
- int const_size = thumb1_size_rtx_costs (XEXP (x, 1), CONST_INT, SET);
- return COSTS_N_INSNS (1) + const_size;
- }
- return COSTS_N_INSNS (1);
-
- case SET:
- return (COSTS_N_INSNS (1)
- + 4 * ((MEM_P (SET_SRC (x)))
- + MEM_P (SET_DEST (x))));
-
- case CONST_INT:
- if (outer == SET)
- {
- if ((unsigned HOST_WIDE_INT) INTVAL (x) < 256)
- return COSTS_N_INSNS (1);
- /* See split "TARGET_THUMB1 && satisfies_constraint_J". */
- if (INTVAL (x) >= -255 && INTVAL (x) <= -1)
- return COSTS_N_INSNS (2);
- /* See split "TARGET_THUMB1 && satisfies_constraint_K". */
- if (thumb_shiftable_const (INTVAL (x)))
- return COSTS_N_INSNS (2);
- return COSTS_N_INSNS (3);
- }
- else if ((outer == PLUS || outer == COMPARE)
- && INTVAL (x) < 256 && INTVAL (x) > -256)
- return 0;
- else if ((outer == IOR || outer == XOR || outer == AND)
- && INTVAL (x) < 256 && INTVAL (x) >= -256)
- return COSTS_N_INSNS (1);
- else if (outer == AND)
- {
- int i;
- /* This duplicates the tests in the andsi3 expander. */
- for (i = 9; i <= 31; i++)
- if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (x)
- || (((HOST_WIDE_INT) 1) << i) - 1 == ~INTVAL (x))
- return COSTS_N_INSNS (2);
- }
- else if (outer == ASHIFT || outer == ASHIFTRT
- || outer == LSHIFTRT)
- return 0;
- return COSTS_N_INSNS (2);
-
- case CONST:
- case CONST_DOUBLE:
- case LABEL_REF:
- case SYMBOL_REF:
- return COSTS_N_INSNS (3);
-
- case UDIV:
- case UMOD:
- case DIV:
- case MOD:
- return 100;
-
- case TRUNCATE:
- return 99;
-
- case AND:
- case XOR:
- case IOR:
- /* XXX guess. */
- return 8;
-
- case MEM:
- /* XXX another guess. */
- /* 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));
-
- case IF_THEN_ELSE:
- /* XXX a guess. */
- if (GET_CODE (XEXP (x, 1)) == PC || GET_CODE (XEXP (x, 2)) == PC)
- return 14;
- return 2;
-
- case ZERO_EXTEND:
- /* XXX still guessing. */
- switch (GET_MODE (XEXP (x, 0)))
- {
- case QImode:
- return (1 + (mode == DImode ? 4 : 0)
- + (MEM_P (XEXP (x, 0)) ? 10 : 0));
-
- case HImode:
- return (4 + (mode == DImode ? 4 : 0)
- + (MEM_P (XEXP (x, 0)) ? 10 : 0));
-
- case SImode:
- return (1 + (MEM_P (XEXP (x, 0)) ? 10 : 0));
-
- default:
- return 99;
- }
-
- default:
- return 99;
- }
-}
-
-/* RTX costs when optimizing for size. */
-static bool
-arm_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
- int *total)
-{
- enum machine_mode mode = GET_MODE (x);
- if (TARGET_THUMB1)
- {
- *total = thumb1_size_rtx_costs (x, code, outer_code);
- return true;
- }
-
- /* FIXME: This makes no attempt to prefer narrow Thumb-2 instructions. */
- switch (code)
- {
- case MEM:
- /* A memory access costs 1 insn if the mode is small, or the address is
- a single register, otherwise it costs one insn per word. */
- if (REG_P (XEXP (x, 0)))
- *total = COSTS_N_INSNS (1);
- else if (flag_pic
- && GET_CODE (XEXP (x, 0)) == PLUS
- && will_be_in_index_register (XEXP (XEXP (x, 0), 1)))
- /* This will be split into two instructions.
- See arm.md:calculate_pic_address. */
- *total = COSTS_N_INSNS (2);
- else
- *total = COSTS_N_INSNS (ARM_NUM_REGS (mode));
- return true;
-
- case DIV:
- case MOD:
- case UDIV:
- case UMOD:
- /* Needs a libcall, so it costs about this. */
- *total = COSTS_N_INSNS (2);
- return false;
-
- case ROTATE:
- if (mode == SImode && REG_P (XEXP (x, 1)))
- {
- *total = COSTS_N_INSNS (2) + rtx_cost (XEXP (x, 0), code, 0, false);
- return true;
- }
- /* Fall through */
- case ROTATERT:
- case ASHIFT:
- case LSHIFTRT:
- case ASHIFTRT:
- if (mode == DImode && CONST_INT_P (XEXP (x, 1)))
- {
- *total = COSTS_N_INSNS (3) + rtx_cost (XEXP (x, 0), code, 0, false);
- return true;
- }
- else if (mode == SImode)
- {
- *total = COSTS_N_INSNS (1) + rtx_cost (XEXP (x, 0), code, 0, false);
- /* Slightly disparage register shifts, but not by much. */
- if (!CONST_INT_P (XEXP (x, 1)))
- *total += 1 + rtx_cost (XEXP (x, 1), code, 1, false);
- return true;
- }
-
- /* Needs a libcall. */
- *total = COSTS_N_INSNS (2);
- return false;
-
- case MINUS:
- if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT
- && (mode == SFmode || !TARGET_VFP_SINGLE))
- {
- *total = COSTS_N_INSNS (1);
- return false;
- }
-
- if (mode == SImode)
- {
- enum rtx_code subcode0 = GET_CODE (XEXP (x, 0));
- enum rtx_code subcode1 = GET_CODE (XEXP (x, 1));
-
- if (subcode0 == ROTATE || subcode0 == ROTATERT || subcode0 == ASHIFT
- || subcode0 == LSHIFTRT || subcode0 == ASHIFTRT
- || subcode1 == ROTATE || subcode1 == ROTATERT
- || subcode1 == ASHIFT || subcode1 == LSHIFTRT
- || subcode1 == ASHIFTRT)
- {
- /* It's just the cost of the two operands. */
- *total = 0;
- return false;
- }
-
- *total = COSTS_N_INSNS (1);
- return false;
- }
-
- *total = COSTS_N_INSNS (ARM_NUM_REGS (mode));
- return false;
-
- case PLUS:
- if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT
- && (mode == SFmode || !TARGET_VFP_SINGLE))
- {
- *total = COSTS_N_INSNS (1);
- return false;
- }
-
- /* A shift as a part of ADD costs nothing. */
- if (GET_CODE (XEXP (x, 0)) == MULT
- && power_of_two_operand (XEXP (XEXP (x, 0), 1), SImode))
- {
- *total = COSTS_N_INSNS (TARGET_THUMB2 ? 2 : 1);
- *total += rtx_cost (XEXP (XEXP (x, 0), 0), code, 0, false);
- *total += rtx_cost (XEXP (x, 1), code, 1, false);
- return true;
- }
-
- /* Fall through */
- case AND: case XOR: case IOR:
- if (mode == SImode)
- {
- enum rtx_code subcode = GET_CODE (XEXP (x, 0));
-
- if (subcode == ROTATE || subcode == ROTATERT || subcode == ASHIFT
- || subcode == LSHIFTRT || subcode == ASHIFTRT
- || (code == AND && subcode == NOT))
- {
- /* It's just the cost of the two operands. */
- *total = 0;
- return false;
- }
- }
-
- *total = COSTS_N_INSNS (ARM_NUM_REGS (mode));
- return false;
-
- case MULT:
- *total = COSTS_N_INSNS (ARM_NUM_REGS (mode));
- return false;
-
- case NEG:
- if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT
- && (mode == SFmode || !TARGET_VFP_SINGLE))
- {
- *total = COSTS_N_INSNS (1);
- return false;
- }
-
- /* Fall through */
- case NOT:
- *total = COSTS_N_INSNS (ARM_NUM_REGS (mode));
-
- return false;
-
- case IF_THEN_ELSE:
- *total = 0;
- return false;
-
- case COMPARE:
- if (cc_register (XEXP (x, 0), VOIDmode))
- * total = 0;
- else
- *total = COSTS_N_INSNS (1);
- return false;
-
- case ABS:
- 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));
- return false;
-
- case SIGN_EXTEND:
- case ZERO_EXTEND:
- return arm_rtx_costs_1 (x, outer_code, total, 0);
-
- case CONST_INT:
- if (const_ok_for_arm (INTVAL (x)))
- /* A multiplication by a constant requires another instruction
- to load the constant to a register. */
- *total = COSTS_N_INSNS ((outer_code == SET || outer_code == MULT)
- ? 1 : 0);
- else if (const_ok_for_arm (~INTVAL (x)))
- *total = COSTS_N_INSNS (outer_code == AND ? 0 : 1);
- else if (const_ok_for_arm (-INTVAL (x)))
- {
- if (outer_code == COMPARE || outer_code == PLUS
- || outer_code == MINUS)
- *total = 0;
- else
- *total = COSTS_N_INSNS (1);
- }
- else
- *total = COSTS_N_INSNS (2);
- return true;
-
- case CONST:
- case LABEL_REF:
- case SYMBOL_REF:
- *total = COSTS_N_INSNS (2);
- return true;
-
- case CONST_DOUBLE:
- *total = COSTS_N_INSNS (4);
- return true;
-
- case CONST_VECTOR:
- if (TARGET_NEON
- && TARGET_HARD_FLOAT
- && outer_code == SET
- && (VALID_NEON_DREG_MODE (mode) || VALID_NEON_QREG_MODE (mode))
- && neon_immediate_valid_for_move (x, mode, NULL, NULL))
- *total = COSTS_N_INSNS (1);
- else
- *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;
-
- case SET:
- return false;
-
- default:
- if (mode != VOIDmode)
- *total = COSTS_N_INSNS (ARM_NUM_REGS (mode));
- else
- *total = COSTS_N_INSNS (4); /* How knows? */
- return false;
- }
-}
-
-/* RTX costs when optimizing for size. */
-static bool
-arm_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
- int *total, bool speed)
-{
- if (!speed)
- return arm_size_rtx_costs (x, (enum rtx_code) code,
- (enum rtx_code) outer_code, total);
- else
- return current_tune->rtx_costs (x, (enum rtx_code) code,
- (enum rtx_code) outer_code,
- total, speed);
-}
-
-/* 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, enum rtx_code code, enum rtx_code outer_code,
- int *total, bool speed)
-{
- enum machine_mode mode = GET_MODE (x);
-
- if (TARGET_THUMB)
- {
- *total = thumb1_rtx_costs (x, code, outer_code);
- return true;
- }
-
- switch (code)
- {
- case MULT:
- if (GET_MODE_CLASS (mode) == MODE_FLOAT
- || mode == DImode)
- {
- *total = COSTS_N_INSNS (20);
- return false;
- }
-
- if (CONST_INT_P (XEXP (x, 1)))
- {
- unsigned HOST_WIDE_INT i = (INTVAL (XEXP (x, 1))
- & (unsigned HOST_WIDE_INT) 0xffffffff);
- int cost, const_ok = const_ok_for_arm (i);
- int j, booth_unit_size;
-
- /* Tune as appropriate. */
- cost = const_ok ? 4 : 8;
- booth_unit_size = 2;
- for (j = 0; i && j < 32; j += booth_unit_size)
- {
- i >>= booth_unit_size;
- cost++;
- }
-
- *total = COSTS_N_INSNS (cost);
- *total += rtx_cost (XEXP (x, 0), code, 0, speed);
- return true;
- }
-
- *total = COSTS_N_INSNS (20);
- return false;
-
- default:
- return arm_rtx_costs_1 (x, outer_code, total, speed);;
- }
-}
-
-
-/* RTX cost for cores with a fast multiply unit (M variants). */
-
-static bool
-arm_fastmul_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
- int *total, bool speed)
-{
- enum machine_mode mode = GET_MODE (x);
-
- if (TARGET_THUMB1)
- {
- *total = thumb1_rtx_costs (x, code, outer_code);
- return true;
- }
-
- /* ??? should thumb2 use different costs? */
- switch (code)
- {
- case MULT:
- /* There is no point basing this on the tuning, since it is always the
- fast variant if it exists at all. */
- if (mode == DImode
- && (GET_CODE (XEXP (x, 0)) == GET_CODE (XEXP (x, 1)))
- && (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
- || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND))
- {
- *total = COSTS_N_INSNS(2);
- return false;
- }
-
-
- if (mode == DImode)
- {
- *total = COSTS_N_INSNS (5);
- return false;
- }
-
- if (CONST_INT_P (XEXP (x, 1)))
- {
- unsigned HOST_WIDE_INT i = (INTVAL (XEXP (x, 1))
- & (unsigned HOST_WIDE_INT) 0xffffffff);
- int cost, const_ok = const_ok_for_arm (i);
- int j, booth_unit_size;
-
- /* Tune as appropriate. */
- cost = const_ok ? 4 : 8;
- booth_unit_size = 8;
- for (j = 0; i && j < 32; j += booth_unit_size)
- {
- i >>= booth_unit_size;
- cost++;
- }
-
- *total = COSTS_N_INSNS(cost);
- return false;
- }
-
- 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 && !TARGET_VFP_SINGLE)))
- {
- *total = COSTS_N_INSNS (1);
- return false;
- }
- }
-
- /* Requires a lib call */
- *total = COSTS_N_INSNS (20);
- return false;
-
- default:
- return arm_rtx_costs_1 (x, outer_code, total, speed);
- }
-}
-
-
-/* RTX cost for XScale CPUs. Thumb-2 is not supported on any xscale cores,
- so it can be ignored. */
-
-static bool
-arm_xscale_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
- int *total, bool speed)
-{
- enum machine_mode mode = GET_MODE (x);
-
- if (TARGET_THUMB)
- {
- *total = thumb1_rtx_costs (x, code, outer_code);
- return true;
- }
-
- switch (code)
- {
- case COMPARE:
- if (GET_CODE (XEXP (x, 0)) != MULT)
- return arm_rtx_costs_1 (x, outer_code, total, speed);
-
- /* 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. */
- if (mode == DImode
- && (GET_CODE (XEXP (x, 0)) == GET_CODE (XEXP (x, 1)))
- && (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
- || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND))
- {
- *total = COSTS_N_INSNS (2);
- return false;
- }
-
-
- if (mode == DImode)
- {
- *total = COSTS_N_INSNS (5);
- return false;
- }
-
- if (CONST_INT_P (XEXP (x, 1)))
- {
- /* 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;
-
- if (i & 0x80000000)
- i = ~i;
-
- i &= (unsigned HOST_WIDE_INT) 0xffffffff;
-
- masked_const = i & 0xffff8000;
- if (masked_const != 0)
- {
- cost++;
- masked_const = i & 0xf8000000;
- if (masked_const != 0)
- cost++;
- }
- *total = COSTS_N_INSNS (cost);
- return false;
- }
-
- if (mode == SImode)
- {
- *total = COSTS_N_INSNS (3);
- return false;
- }
-
- /* Requires a lib call */
- *total = COSTS_N_INSNS (20);
- return false;
-
- default:
- return arm_rtx_costs_1 (x, outer_code, total, speed);
- }
-}
-
-
-/* RTX costs for 9e (and later) cores. */
-
-static bool
-arm_9e_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
- int *total, bool speed)
-{
- enum machine_mode mode = GET_MODE (x);
-
- if (TARGET_THUMB1)
- {
- switch (code)
- {
- case MULT:
- *total = COSTS_N_INSNS (3);
- return true;
-
- default:
- *total = thumb1_rtx_costs (x, code, outer_code);
- return true;
- }
- }
-
- switch (code)
- {
- case MULT:
- /* There is no point basing this on the tuning, since it is always the
- fast variant if it exists at all. */
- if (mode == DImode
- && (GET_CODE (XEXP (x, 0)) == GET_CODE (XEXP (x, 1)))
- && (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
- || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND))
- {
- *total = COSTS_N_INSNS (2);
- return false;
- }
-
-
- if (mode == DImode)
- {
- *total = COSTS_N_INSNS (5);
- return false;
- }
-
- if (mode == SImode)
- {
- *total = COSTS_N_INSNS (2);
- return false;
- }
-
- if (GET_MODE_CLASS (mode) == MODE_FLOAT)
- {
- if (TARGET_HARD_FLOAT
- && (mode == SFmode
- || (mode == DFmode && !TARGET_VFP_SINGLE)))
- {
- *total = COSTS_N_INSNS (1);
- return false;
- }
- }
-
- *total = COSTS_N_INSNS (20);
- return false;
-
- default:
- return arm_rtx_costs_1 (x, outer_code, total, speed);
- }
-}
-/* All address computations that can be done are free, but rtx cost returns
- the same for practically all of them. So we weight the different types
- of address here in the order (most pref first):
- PRE/POST_INC/DEC, SHIFT or NON-INT sum, INT sum, REG, MEM or LABEL. */
-static inline int
-arm_arm_address_cost (rtx x)
-{
- enum rtx_code c = GET_CODE (x);
-
- if (c == PRE_INC || c == PRE_DEC || c == POST_INC || c == POST_DEC)
- return 0;
- if (c == MEM || c == LABEL_REF || c == SYMBOL_REF)
- return 10;
-
- if (c == PLUS)
- {
- if (CONST_INT_P (XEXP (x, 1)))
- return 2;
-
- if (ARITHMETIC_P (XEXP (x, 0)) || ARITHMETIC_P (XEXP (x, 1)))
- return 3;
-
- return 4;
- }
-
- return 6;
-}
-
-static inline int
-arm_thumb_address_cost (rtx x)
-{
- enum rtx_code c = GET_CODE (x);
-
- if (c == REG)
- return 1;
- if (c == PLUS
- && REG_P (XEXP (x, 0))
- && CONST_INT_P (XEXP (x, 1)))
- return 1;
-
- return 2;
-}
-
-static int
-arm_address_cost (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED,
- addr_space_t as ATTRIBUTE_UNUSED, bool speed ATTRIBUTE_UNUSED)
-{
- return TARGET_32BIT ? arm_arm_address_cost (x) : arm_thumb_address_cost (x);
-}
-
-/* Adjust cost hook for XScale. */
-static bool
-xscale_sched_adjust_cost (rtx insn, rtx link, rtx dep, int * cost)
-{
- /* Some true dependencies can have a higher cost depending
- on precisely how certain input operands are used. */
- if (REG_NOTE_KIND(link) == 0
- && recog_memoized (insn) >= 0
- && recog_memoized (dep) >= 0)
- {
- int shift_opnum = get_attr_shift (insn);
- enum attr_type attr_type = get_attr_type (dep);
-
- /* If nonzero, SHIFT_OPNUM contains the operand number of a shifted
- operand for INSN. If we have a shifted input operand and the
- instruction we depend on is another ALU instruction, then we may
- have to account for an additional stall. */
- if (shift_opnum != 0
- && (attr_type == TYPE_ALU_SHIFT || attr_type == TYPE_ALU_SHIFT_REG))
- {
- rtx shifted_operand;
- int opno;
-
- /* Get the shifted operand. */
- extract_insn (insn);
- shifted_operand = recog_data.operand[shift_opnum];
-
- /* Iterate over all the operands in DEP. If we write an operand
- that overlaps with SHIFTED_OPERAND, then we have increase the
- cost of this dependency. */
- extract_insn (dep);
- preprocess_constraints ();
- for (opno = 0; opno < recog_data.n_operands; opno++)
- {
- /* We can ignore strict inputs. */
- if (recog_data.operand_type[opno] == OP_IN)
- continue;
-
- if (reg_overlap_mentioned_p (recog_data.operand[opno],
- shifted_operand))
- {
- *cost = 2;
- return false;
- }
- }
- }
- }
- return true;
-}
-
-/* Adjust cost hook for Cortex A9. */
-static bool
-cortex_a9_sched_adjust_cost (rtx insn, rtx link, rtx dep, int * cost)
-{
- switch (REG_NOTE_KIND (link))
- {
- case REG_DEP_ANTI:
- *cost = 0;
- return false;
-
- case REG_DEP_TRUE:
- case REG_DEP_OUTPUT:
- if (recog_memoized (insn) >= 0
- && recog_memoized (dep) >= 0)
- {
- if (GET_CODE (PATTERN (insn)) == SET)
- {
- if (GET_MODE_CLASS
- (GET_MODE (SET_DEST (PATTERN (insn)))) == MODE_FLOAT
- || GET_MODE_CLASS
- (GET_MODE (SET_SRC (PATTERN (insn)))) == MODE_FLOAT)
- {
- enum attr_type attr_type_insn = get_attr_type (insn);
- enum attr_type attr_type_dep = get_attr_type (dep);
-
- /* By default all dependencies of the form
- s0 = s0 <op> s1
- s0 = s0 <op> s2
- have an extra latency of 1 cycle because
- of the input and output dependency in this
- case. However this gets modeled as an true
- dependency and hence all these checks. */
- if (REG_P (SET_DEST (PATTERN (insn)))
- && REG_P (SET_DEST (PATTERN (dep)))
- && reg_overlap_mentioned_p (SET_DEST (PATTERN (insn)),
- SET_DEST (PATTERN (dep))))
- {
- /* FMACS is a special case where the dependent
- instruction can be issued 3 cycles before
- the normal latency in case of an output
- dependency. */
- if ((attr_type_insn == TYPE_FMACS
- || attr_type_insn == TYPE_FMACD)
- && (attr_type_dep == TYPE_FMACS
- || attr_type_dep == TYPE_FMACD))
- {
- if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
- *cost = insn_default_latency (dep) - 3;
- else
- *cost = insn_default_latency (dep);
- return false;
- }
- else
- {
- if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
- *cost = insn_default_latency (dep) + 1;
- else
- *cost = insn_default_latency (dep);
- }
- return false;
- }
- }
- }
- }
- break;
-
- default:
- gcc_unreachable ();
- }
-
- return true;
-}
-
-/* Adjust cost hook for FA726TE. */
-static bool
-fa726te_sched_adjust_cost (rtx insn, rtx link, rtx dep, int * cost)
-{
- /* For FA726TE, true dependency on CPSR (i.e. set cond followed by predicated)
- have penalty of 3. */
- if (REG_NOTE_KIND (link) == REG_DEP_TRUE
- && recog_memoized (insn) >= 0
- && recog_memoized (dep) >= 0
- && get_attr_conds (dep) == CONDS_SET)
- {
- /* Use of carry (e.g. 64-bit arithmetic) in ALU: 3-cycle latency. */
- if (get_attr_conds (insn) == CONDS_USE
- && get_attr_type (insn) != TYPE_BRANCH)
- {
- *cost = 3;
- return false;
- }
-
- if (GET_CODE (PATTERN (insn)) == COND_EXEC
- || get_attr_conds (insn) == CONDS_USE)
- {
- *cost = 0;
- return false;
- }
- }
-
- return true;
-}
-
-/* Implement TARGET_REGISTER_MOVE_COST.
-
- 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. */
-
-int
-arm_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
- reg_class_t from, reg_class_t to)
-{
- if (TARGET_32BIT)
- {
- if ((IS_VFP_CLASS (from) && !IS_VFP_CLASS (to))
- || (!IS_VFP_CLASS (from) && IS_VFP_CLASS (to)))
- return 15;
- else if ((from == IWMMXT_REGS && to != IWMMXT_REGS)
- || (from != IWMMXT_REGS && to == IWMMXT_REGS))
- return 4;
- else if (from == IWMMXT_GR_REGS || to == IWMMXT_GR_REGS)
- return 20;
- else
- return 2;
- }
- else
- {
- if (from == HI_REGS || to == HI_REGS)
- return 4;
- else
- return 2;
- }
-}
-
-/* Implement TARGET_MEMORY_MOVE_COST. */
-
-int
-arm_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
- bool in ATTRIBUTE_UNUSED)
-{
- if (TARGET_32BIT)
- return 10;
- else
- {
- if (GET_MODE_SIZE (mode) < 4)
- return 8;
- else
- return ((2 * GET_MODE_SIZE (mode)) * (rclass == LO_REGS ? 1 : 2));
- }
-}
-
-/* Vectorizer cost model implementation. */
-
-/* Implement targetm.vectorize.builtin_vectorization_cost. */
-static int
-arm_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
- tree vectype,
- int misalign ATTRIBUTE_UNUSED)
-{
- unsigned elements;
-
- switch (type_of_cost)
- {
- case scalar_stmt:
- return current_tune->vec_costs->scalar_stmt_cost;
-
- case scalar_load:
- return current_tune->vec_costs->scalar_load_cost;
-
- case scalar_store:
- return current_tune->vec_costs->scalar_store_cost;
-
- case vector_stmt:
- return current_tune->vec_costs->vec_stmt_cost;
-
- case vector_load:
- return current_tune->vec_costs->vec_align_load_cost;
-
- case vector_store:
- return current_tune->vec_costs->vec_store_cost;
-
- case vec_to_scalar:
- return current_tune->vec_costs->vec_to_scalar_cost;
-
- case scalar_to_vec:
- return current_tune->vec_costs->scalar_to_vec_cost;
-
- case unaligned_load:
- return current_tune->vec_costs->vec_unalign_load_cost;
-
- case unaligned_store:
- return current_tune->vec_costs->vec_unalign_store_cost;
-
- case cond_branch_taken:
- return current_tune->vec_costs->cond_taken_branch_cost;
-
- case cond_branch_not_taken:
- return current_tune->vec_costs->cond_not_taken_branch_cost;
-
- case vec_perm:
- case vec_promote_demote:
- return current_tune->vec_costs->vec_stmt_cost;
-
- case vec_construct:
- elements = TYPE_VECTOR_SUBPARTS (vectype);
- return elements / 2 + 1;
-
- default:
- gcc_unreachable ();
- }
-}
-
-/* Implement targetm.vectorize.add_stmt_cost. */
-
-static unsigned
-arm_add_stmt_cost (void *data, int count, enum vect_cost_for_stmt kind,
- struct _stmt_vec_info *stmt_info, int misalign,
- enum vect_cost_model_location where)
-{
- unsigned *cost = (unsigned *) data;
- unsigned retval = 0;
-
- if (flag_vect_cost_model)
- {
- tree vectype = stmt_info ? stmt_vectype (stmt_info) : NULL_TREE;
- int stmt_cost = arm_builtin_vectorization_cost (kind, vectype, misalign);
-
- /* Statements in an inner loop relative to the loop being
- vectorized are weighted more heavily. The value here is
- arbitrary and could potentially be improved with analysis. */
- if (where == vect_body && stmt_info && stmt_in_inner_loop_p (stmt_info))
- count *= 50; /* FIXME. */
-
- retval = (unsigned) (count * stmt_cost);
- cost[where] += retval;
- }
-
- return retval;
-}
-
-/* Return true if and only if this insn can dual-issue only as older. */
-static bool
-cortexa7_older_only (rtx insn)
-{
- if (recog_memoized (insn) < 0)
- return false;
-
- if (get_attr_insn (insn) == INSN_MOV)
- return false;
-
- switch (get_attr_type (insn))
- {
- case TYPE_ALU_REG:
- case TYPE_LOAD_BYTE:
- case TYPE_LOAD1:
- case TYPE_STORE1:
- case TYPE_FFARITHS:
- case TYPE_FADDS:
- case TYPE_FFARITHD:
- case TYPE_FADDD:
- case TYPE_FCPYS:
- case TYPE_F_CVT:
- case TYPE_FCMPS:
- case TYPE_FCMPD:
- case TYPE_FCONSTS:
- case TYPE_FCONSTD:
- case TYPE_FMULS:
- case TYPE_FMACS:
- case TYPE_FMULD:
- case TYPE_FMACD:
- case TYPE_FDIVS:
- case TYPE_FDIVD:
- case TYPE_F_2_R:
- case TYPE_F_FLAG:
- case TYPE_F_LOADS:
- case TYPE_F_STORES:
- return true;
- default:
- return false;
- }
-}
-
-/* Return true if and only if this insn can dual-issue as younger. */
-static bool
-cortexa7_younger (FILE *file, int verbose, rtx insn)
-{
- if (recog_memoized (insn) < 0)
- {
- if (verbose > 5)
- fprintf (file, ";; not cortexa7_younger %d\n", INSN_UID (insn));
- return false;
- }
-
- if (get_attr_insn (insn) == INSN_MOV)
- return true;
-
- switch (get_attr_type (insn))
- {
- case TYPE_SIMPLE_ALU_IMM:
- case TYPE_SIMPLE_ALU_SHIFT:
- case TYPE_BRANCH:
- case TYPE_CALL:
- return true;
- default:
- return false;
- }
-}
-
-
-/* Look for an instruction that can dual issue only as an older
- instruction, and move it in front of any instructions that can
- dual-issue as younger, while preserving the relative order of all
- other instructions in the ready list. This is a hueuristic to help
- dual-issue in later cycles, by postponing issue of more flexible
- instructions. This heuristic may affect dual issue opportunities
- in the current cycle. */
-static void
-cortexa7_sched_reorder (FILE *file, int verbose, rtx *ready, int *n_readyp,
- int clock)
-{
- int i;
- int first_older_only = -1, first_younger = -1;
-
- if (verbose > 5)
- fprintf (file,
- ";; sched_reorder for cycle %d with %d insns in ready list\n",
- clock,
- *n_readyp);
-
- /* Traverse the ready list from the head (the instruction to issue
- first), and looking for the first instruction that can issue as
- younger and the first instruction that can dual-issue only as
- older. */
- for (i = *n_readyp - 1; i >= 0; i--)
- {
- rtx insn = ready[i];
- if (cortexa7_older_only (insn))
- {
- first_older_only = i;
- if (verbose > 5)
- fprintf (file, ";; reorder older found %d\n", INSN_UID (insn));
- break;
- }
- else if (cortexa7_younger (file, verbose, insn) && first_younger == -1)
- first_younger = i;
- }
-
- /* Nothing to reorder because either no younger insn found or insn
- that can dual-issue only as older appears before any insn that
- can dual-issue as younger. */
- if (first_younger == -1)
- {
- if (verbose > 5)
- fprintf (file, ";; sched_reorder nothing to reorder as no younger\n");
- return;
- }
-
- /* Nothing to reorder because no older-only insn in the ready list. */
- if (first_older_only == -1)
- {
- if (verbose > 5)
- fprintf (file, ";; sched_reorder nothing to reorder as no older_only\n");
- return;
- }
-
- /* Move first_older_only insn before first_younger. */
- if (verbose > 5)
- fprintf (file, ";; cortexa7_sched_reorder insn %d before %d\n",
- INSN_UID(ready [first_older_only]),
- INSN_UID(ready [first_younger]));
- rtx first_older_only_insn = ready [first_older_only];
- for (i = first_older_only; i < first_younger; i++)
- {
- ready[i] = ready[i+1];
- }
-
- ready[i] = first_older_only_insn;
- return;
-}
-
-/* Implement TARGET_SCHED_REORDER. */
-static int
-arm_sched_reorder (FILE *file, int verbose, rtx *ready, int *n_readyp,
- int clock)
-{
- switch (arm_tune)
- {
- case cortexa7:
- cortexa7_sched_reorder (file, verbose, ready, n_readyp, clock);
- break;
- default:
- /* Do nothing for other cores. */
- break;
- }
-
- return arm_issue_rate ();
-}
-
-/* This function implements the target macro TARGET_SCHED_ADJUST_COST.
- It corrects the value of COST based on the relationship between
- INSN and DEP through the dependence LINK. It returns the new
- value. There is a per-core adjust_cost hook to adjust scheduler costs
- and the per-core hook can choose to completely override the generic
- adjust_cost function. Only put bits of code into arm_adjust_cost that
- are common across all cores. */
-static int
-arm_adjust_cost (rtx insn, rtx link, rtx dep, int cost)
-{
- rtx i_pat, d_pat;
-
- /* When generating Thumb-1 code, we want to place flag-setting operations
- close to a conditional branch which depends on them, so that we can
- omit the comparison. */
- if (TARGET_THUMB1
- && REG_NOTE_KIND (link) == 0
- && recog_memoized (insn) == CODE_FOR_cbranchsi4_insn
- && recog_memoized (dep) >= 0
- && get_attr_conds (dep) == CONDS_SET)
- return 0;
-
- if (current_tune->sched_adjust_cost != NULL)
- {
- if (!current_tune->sched_adjust_cost (insn, link, dep, &cost))
- return cost;
- }
-
- /* XXX Is this strictly true? */
- if (REG_NOTE_KIND (link) == REG_DEP_ANTI
- || REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
- return 0;
-
- /* Call insns don't incur a stall, even if they follow a load. */
- if (REG_NOTE_KIND (link) == 0
- && CALL_P (insn))
- return 1;
-
- if ((i_pat = single_set (insn)) != NULL
- && MEM_P (SET_SRC (i_pat))
- && (d_pat = single_set (dep)) != NULL
- && MEM_P (SET_DEST (d_pat)))
- {
- rtx src_mem = XEXP (SET_SRC (i_pat), 0);
- /* This is a load after a store, there is no conflict if the load reads
- from a cached area. Assume that loads from the stack, and from the
- constant pool are cached, and that others will miss. This is a
- hack. */
-
- if ((GET_CODE (src_mem) == SYMBOL_REF
- && CONSTANT_POOL_ADDRESS_P (src_mem))
- || reg_mentioned_p (stack_pointer_rtx, src_mem)
- || reg_mentioned_p (frame_pointer_rtx, src_mem)
- || reg_mentioned_p (hard_frame_pointer_rtx, src_mem))
- return 1;
- }
-
- return cost;
-}
-
-static int
-arm_default_branch_cost (bool speed_p, bool predictable_p ATTRIBUTE_UNUSED)
-{
- if (TARGET_32BIT)
- return (TARGET_THUMB2 && !speed_p) ? 1 : 4;
- else
- return (optimize > 0) ? 2 : 0;
-}
-
-static int
-arm_cortex_a5_branch_cost (bool speed_p, bool predictable_p)
-{
- return speed_p ? 0 : arm_default_branch_cost (speed_p, predictable_p);
-}
-
-static bool fp_consts_inited = false;
-
-static REAL_VALUE_TYPE value_fp0;
-
-static void
-init_fp_table (void)
-{
- REAL_VALUE_TYPE r;
-
- r = REAL_VALUE_ATOF ("0", DFmode);
- value_fp0 = r;
- fp_consts_inited = true;
-}
-
-/* Return TRUE if rtx X is a valid immediate FP constant. */
-int
-arm_const_double_rtx (rtx x)
-{
- REAL_VALUE_TYPE r;
-
- if (!fp_consts_inited)
- init_fp_table ();
-
- REAL_VALUE_FROM_CONST_DOUBLE (r, x);
- if (REAL_VALUE_MINUS_ZERO (r))
- return 0;
-
- if (REAL_VALUES_EQUAL (r, value_fp0))
- return 1;
-
- return 0;
-}
-
-/* VFPv3 has a fairly wide range of representable immediates, formed from
- "quarter-precision" floating-point values. These can be evaluated using this
- formula (with ^ for exponentiation):
-
- -1^s * n * 2^-r
-
- Where 's' is a sign bit (0/1), 'n' and 'r' are integers such that
- 16 <= n <= 31 and 0 <= r <= 7.
-
- These values are mapped onto an 8-bit integer ABCDEFGH s.t.
-
- - A (most-significant) is the sign bit.
- - BCD are the exponent (encoded as r XOR 3).
- - EFGH are the mantissa (encoded as n - 16).
-*/
-
-/* Return an integer index for a VFPv3 immediate operand X suitable for the
- fconst[sd] instruction, or -1 if X isn't suitable. */
-static int
-vfp3_const_double_index (rtx x)
-{
- REAL_VALUE_TYPE r, m;
- int sign, exponent;
- unsigned HOST_WIDE_INT mantissa, mant_hi;
- unsigned HOST_WIDE_INT mask;
- HOST_WIDE_INT m1, m2;
- int point_pos = 2 * HOST_BITS_PER_WIDE_INT - 1;
-
- if (!TARGET_VFP3 || !CONST_DOUBLE_P (x))
- return -1;
-
- REAL_VALUE_FROM_CONST_DOUBLE (r, x);
-
- /* We can't represent these things, so detect them first. */
- if (REAL_VALUE_ISINF (r) || REAL_VALUE_ISNAN (r) || REAL_VALUE_MINUS_ZERO (r))
- return -1;
-
- /* Extract sign, exponent and mantissa. */
- sign = REAL_VALUE_NEGATIVE (r) ? 1 : 0;
- r = real_value_abs (&r);
- exponent = REAL_EXP (&r);
- /* For the mantissa, we expand into two HOST_WIDE_INTS, apart from the
- highest (sign) bit, with a fixed binary point at bit point_pos.
- WARNING: If there's ever a VFP version which uses more than 2 * H_W_I - 1
- bits for the mantissa, this may fail (low bits would be lost). */
- real_ldexp (&m, &r, point_pos - exponent);
- REAL_VALUE_TO_INT (&m1, &m2, m);
- mantissa = m1;
- mant_hi = m2;
-
- /* If there are bits set in the low part of the mantissa, we can't
- represent this value. */
- if (mantissa != 0)
- return -1;
-
- /* Now make it so that mantissa contains the most-significant bits, and move
- the point_pos to indicate that the least-significant bits have been
- discarded. */
- point_pos -= HOST_BITS_PER_WIDE_INT;
- mantissa = mant_hi;
-
- /* We can permit four significant bits of mantissa only, plus a high bit
- which is always 1. */
- mask = ((unsigned HOST_WIDE_INT)1 << (point_pos - 5)) - 1;
- if ((mantissa & mask) != 0)
- return -1;
-
- /* Now we know the mantissa is in range, chop off the unneeded bits. */
- mantissa >>= point_pos - 5;
-
- /* The mantissa may be zero. Disallow that case. (It's possible to load the
- floating-point immediate zero with Neon using an integer-zero load, but
- that case is handled elsewhere.) */
- if (mantissa == 0)
- return -1;
-
- gcc_assert (mantissa >= 16 && mantissa <= 31);
-
- /* The value of 5 here would be 4 if GCC used IEEE754-like encoding (where
- normalized significands are in the range [1, 2). (Our mantissa is shifted
- left 4 places at this point relative to normalized IEEE754 values). GCC
- internally uses [0.5, 1) (see real.c), so the exponent returned from
- REAL_EXP must be altered. */
- exponent = 5 - exponent;
-
- if (exponent < 0 || exponent > 7)
- return -1;
-
- /* Sign, mantissa and exponent are now in the correct form to plug into the
- formula described in the comment above. */
- return (sign << 7) | ((exponent ^ 3) << 4) | (mantissa - 16);
-}
-
-/* Return TRUE if rtx X is a valid immediate VFPv3 constant. */
-int
-vfp3_const_double_rtx (rtx x)
-{
- if (!TARGET_VFP3)
- return 0;
-
- return vfp3_const_double_index (x) != -1;
-}
-
-/* Recognize immediates which can be used in various Neon instructions. Legal
- immediates are described by the following table (for VMVN variants, the
- bitwise inverse of the constant shown is recognized. In either case, VMOV
- is output and the correct instruction to use for a given constant is chosen
- by the assembler). The constant shown is replicated across all elements of
- the destination vector.
-
- insn elems variant constant (binary)
- ---- ----- ------- -----------------
- vmov i32 0 00000000 00000000 00000000 abcdefgh
- vmov i32 1 00000000 00000000 abcdefgh 00000000
- vmov i32 2 00000000 abcdefgh 00000000 00000000
- vmov i32 3 abcdefgh 00000000 00000000 00000000
- vmov i16 4 00000000 abcdefgh
- vmov i16 5 abcdefgh 00000000
- vmvn i32 6 00000000 00000000 00000000 abcdefgh
- vmvn i32 7 00000000 00000000 abcdefgh 00000000
- vmvn i32 8 00000000 abcdefgh 00000000 00000000
- vmvn i32 9 abcdefgh 00000000 00000000 00000000
- vmvn i16 10 00000000 abcdefgh
- vmvn i16 11 abcdefgh 00000000
- vmov i32 12 00000000 00000000 abcdefgh 11111111
- vmvn i32 13 00000000 00000000 abcdefgh 11111111
- vmov i32 14 00000000 abcdefgh 11111111 11111111
- vmvn i32 15 00000000 abcdefgh 11111111 11111111
- vmov i8 16 abcdefgh
- vmov i64 17 aaaaaaaa bbbbbbbb cccccccc dddddddd
- eeeeeeee ffffffff gggggggg hhhhhhhh
- vmov f32 18 aBbbbbbc defgh000 00000000 00000000
- vmov f32 19 00000000 00000000 00000000 00000000
-
- For case 18, B = !b. Representable values are exactly those accepted by
- vfp3_const_double_index, but are output as floating-point numbers rather
- than indices.
-
- For case 19, we will change it to vmov.i32 when assembling.
-
- Variants 0-5 (inclusive) may also be used as immediates for the second
- operand of VORR/VBIC instructions.
-
- The INVERSE argument causes the bitwise inverse of the given operand to be
- recognized instead (used for recognizing legal immediates for the VAND/VORN
- pseudo-instructions). If INVERSE is true, the value placed in *MODCONST is
- *not* inverted (i.e. the pseudo-instruction forms vand/vorn should still be
- output, rather than the real insns vbic/vorr).
-
- INVERSE makes no difference to the recognition of float vectors.
-
- The return value is the variant of immediate as shown in the above table, or
- -1 if the given value doesn't match any of the listed patterns.
-*/
-static int
-neon_valid_immediate (rtx op, enum machine_mode mode, int inverse,
- rtx *modconst, int *elementwidth)
-{
-#define CHECK(STRIDE, ELSIZE, CLASS, TEST) \
- matches = 1; \
- for (i = 0; i < idx; i += (STRIDE)) \
- if (!(TEST)) \
- matches = 0; \
- if (matches) \
- { \
- immtype = (CLASS); \
- elsize = (ELSIZE); \
- break; \
- }
-
- unsigned int i, elsize = 0, idx = 0, n_elts;
- unsigned int innersize;
- unsigned char bytes[16];
- int immtype = -1, matches;
- unsigned int invmask = inverse ? 0xff : 0;
- bool vector = GET_CODE (op) == CONST_VECTOR;
-
- if (vector)
- {
- n_elts = CONST_VECTOR_NUNITS (op);
- innersize = GET_MODE_SIZE (GET_MODE_INNER (mode));
- }
- else
- {
- n_elts = 1;
- if (mode == VOIDmode)
- mode = DImode;
- innersize = GET_MODE_SIZE (mode);
- }
-
- /* Vectors of float constants. */
- if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
- {
- rtx el0 = CONST_VECTOR_ELT (op, 0);
- REAL_VALUE_TYPE r0;
-
- if (!vfp3_const_double_rtx (el0) && el0 != CONST0_RTX (GET_MODE (el0)))
- return -1;
-
- REAL_VALUE_FROM_CONST_DOUBLE (r0, el0);
-
- for (i = 1; i < n_elts; i++)
- {
- rtx elt = CONST_VECTOR_ELT (op, i);
- REAL_VALUE_TYPE re;
-
- REAL_VALUE_FROM_CONST_DOUBLE (re, elt);
-
- if (!REAL_VALUES_EQUAL (r0, re))
- return -1;
- }
-
- if (modconst)
- *modconst = CONST_VECTOR_ELT (op, 0);
-
- if (elementwidth)
- *elementwidth = 0;
-
- if (el0 == CONST0_RTX (GET_MODE (el0)))
- return 19;
- else
- return 18;
- }
-
- /* Splat vector constant out into a byte vector. */
- for (i = 0; i < n_elts; i++)
- {
- rtx el = vector ? CONST_VECTOR_ELT (op, i) : op;
- unsigned HOST_WIDE_INT elpart;
- unsigned int part, parts;
-
- if (CONST_INT_P (el))
- {
- elpart = INTVAL (el);
- parts = 1;
- }
- else if (CONST_DOUBLE_P (el))
- {
- elpart = CONST_DOUBLE_LOW (el);
- parts = 2;
- }
- else
- gcc_unreachable ();
-
- for (part = 0; part < parts; part++)
- {
- unsigned int byte;
- for (byte = 0; byte < innersize; byte++)
- {
- bytes[idx++] = (elpart & 0xff) ^ invmask;
- elpart >>= BITS_PER_UNIT;
- }
- if (CONST_DOUBLE_P (el))
- elpart = CONST_DOUBLE_HIGH (el);
- }
- }
-
- /* Sanity check. */
- gcc_assert (idx == GET_MODE_SIZE (mode));
-
- do
- {
- CHECK (4, 32, 0, bytes[i] == bytes[0] && bytes[i + 1] == 0
- && bytes[i + 2] == 0 && bytes[i + 3] == 0);
-
- CHECK (4, 32, 1, bytes[i] == 0 && bytes[i + 1] == bytes[1]
- && bytes[i + 2] == 0 && bytes[i + 3] == 0);
-
- CHECK (4, 32, 2, bytes[i] == 0 && bytes[i + 1] == 0
- && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0);
-
- CHECK (4, 32, 3, bytes[i] == 0 && bytes[i + 1] == 0
- && bytes[i + 2] == 0 && bytes[i + 3] == bytes[3]);
-
- CHECK (2, 16, 4, bytes[i] == bytes[0] && bytes[i + 1] == 0);
-
- CHECK (2, 16, 5, bytes[i] == 0 && bytes[i + 1] == bytes[1]);
-
- CHECK (4, 32, 6, bytes[i] == bytes[0] && bytes[i + 1] == 0xff
- && bytes[i + 2] == 0xff && bytes[i + 3] == 0xff);
-
- CHECK (4, 32, 7, bytes[i] == 0xff && bytes[i + 1] == bytes[1]
- && bytes[i + 2] == 0xff && bytes[i + 3] == 0xff);
-
- CHECK (4, 32, 8, bytes[i] == 0xff && bytes[i + 1] == 0xff
- && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0xff);
-
- CHECK (4, 32, 9, bytes[i] == 0xff && bytes[i + 1] == 0xff
- && bytes[i + 2] == 0xff && bytes[i + 3] == bytes[3]);
-
- CHECK (2, 16, 10, bytes[i] == bytes[0] && bytes[i + 1] == 0xff);
-
- CHECK (2, 16, 11, bytes[i] == 0xff && bytes[i + 1] == bytes[1]);
-
- CHECK (4, 32, 12, bytes[i] == 0xff && bytes[i + 1] == bytes[1]
- && bytes[i + 2] == 0 && bytes[i + 3] == 0);
-
- CHECK (4, 32, 13, bytes[i] == 0 && bytes[i + 1] == bytes[1]
- && bytes[i + 2] == 0xff && bytes[i + 3] == 0xff);
-
- CHECK (4, 32, 14, bytes[i] == 0xff && bytes[i + 1] == 0xff
- && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0);
-
- CHECK (4, 32, 15, bytes[i] == 0 && bytes[i + 1] == 0
- && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0xff);
-
- CHECK (1, 8, 16, bytes[i] == bytes[0]);
-
- CHECK (1, 64, 17, (bytes[i] == 0 || bytes[i] == 0xff)
- && bytes[i] == bytes[(i + 8) % idx]);
- }
- while (0);
-
- if (immtype == -1)
- return -1;
-
- if (elementwidth)
- *elementwidth = elsize;
-
- if (modconst)
- {
- unsigned HOST_WIDE_INT imm = 0;
-
- /* Un-invert bytes of recognized vector, if necessary. */
- if (invmask != 0)
- for (i = 0; i < idx; i++)
- bytes[i] ^= invmask;
-
- if (immtype == 17)
- {
- /* FIXME: Broken on 32-bit H_W_I hosts. */
- gcc_assert (sizeof (HOST_WIDE_INT) == 8);
-
- for (i = 0; i < 8; i++)
- imm |= (unsigned HOST_WIDE_INT) (bytes[i] ? 0xff : 0)
- << (i * BITS_PER_UNIT);
-
- *modconst = GEN_INT (imm);
- }
- else
- {
- unsigned HOST_WIDE_INT imm = 0;
-
- for (i = 0; i < elsize / BITS_PER_UNIT; i++)
- imm |= (unsigned HOST_WIDE_INT) bytes[i] << (i * BITS_PER_UNIT);
-
- *modconst = GEN_INT (imm);
- }
- }
-
- return immtype;
-#undef CHECK
-}
-
-/* Return TRUE if rtx X is legal for use as either a Neon VMOV (or, implicitly,
- VMVN) immediate. Write back width per element to *ELEMENTWIDTH (or zero for
- float elements), and a modified constant (whatever should be output for a
- VMOV) in *MODCONST. */
-
-int
-neon_immediate_valid_for_move (rtx op, enum machine_mode mode,
- rtx *modconst, int *elementwidth)
-{
- rtx tmpconst;
- int tmpwidth;
- int retval = neon_valid_immediate (op, mode, 0, &tmpconst, &tmpwidth);
-
- if (retval == -1)
- return 0;
-
- if (modconst)
- *modconst = tmpconst;
-
- if (elementwidth)
- *elementwidth = tmpwidth;
-
- return 1;
-}
-
-/* Return TRUE if rtx X is legal for use in a VORR or VBIC instruction. If
- the immediate is valid, write a constant suitable for using as an operand
- to VORR/VBIC/VAND/VORN to *MODCONST and the corresponding element width to
- *ELEMENTWIDTH. See neon_valid_immediate for description of INVERSE. */
-
-int
-neon_immediate_valid_for_logic (rtx op, enum machine_mode mode, int inverse,
- rtx *modconst, int *elementwidth)
-{
- rtx tmpconst;
- int tmpwidth;
- int retval = neon_valid_immediate (op, mode, inverse, &tmpconst, &tmpwidth);
-
- if (retval < 0 || retval > 5)
- return 0;
-
- if (modconst)
- *modconst = tmpconst;
-
- if (elementwidth)
- *elementwidth = tmpwidth;
-
- return 1;
-}
-
-/* Return TRUE if rtx OP is legal for use in a VSHR or VSHL instruction. If
- the immediate is valid, write a constant suitable for using as an operand
- to VSHR/VSHL to *MODCONST and the corresponding element width to
- *ELEMENTWIDTH. ISLEFTSHIFT is for determine left or right shift,
- because they have different limitations. */
-
-int
-neon_immediate_valid_for_shift (rtx op, enum machine_mode mode,
- rtx *modconst, int *elementwidth,
- bool isleftshift)
-{
- unsigned int innersize = GET_MODE_SIZE (GET_MODE_INNER (mode));
- unsigned int n_elts = CONST_VECTOR_NUNITS (op), i;
- unsigned HOST_WIDE_INT last_elt = 0;
- unsigned HOST_WIDE_INT maxshift;
-
- /* Split vector constant out into a byte vector. */
- for (i = 0; i < n_elts; i++)
- {
- rtx el = CONST_VECTOR_ELT (op, i);
- unsigned HOST_WIDE_INT elpart;
-
- if (CONST_INT_P (el))
- elpart = INTVAL (el);
- else if (CONST_DOUBLE_P (el))
- return 0;
- else
- gcc_unreachable ();
-
- if (i != 0 && elpart != last_elt)
- return 0;
-
- last_elt = elpart;
- }
-
- /* Shift less than element size. */
- maxshift = innersize * 8;
-
- if (isleftshift)
- {
- /* Left shift immediate value can be from 0 to <size>-1. */
- if (last_elt >= maxshift)
- return 0;
- }
- else
- {
- /* Right shift immediate value can be from 1 to <size>. */
- if (last_elt == 0 || last_elt > maxshift)
- return 0;
- }
-
- if (elementwidth)
- *elementwidth = innersize * 8;
-
- if (modconst)
- *modconst = CONST_VECTOR_ELT (op, 0);
-
- return 1;
-}
-
-/* Return a string suitable for output of Neon immediate logic operation
- MNEM. */
-
-char *
-neon_output_logic_immediate (const char *mnem, rtx *op2, enum machine_mode mode,
- int inverse, int quad)
-{
- int width, is_valid;
- static char templ[40];
-
- is_valid = neon_immediate_valid_for_logic (*op2, mode, inverse, op2, &width);
-
- gcc_assert (is_valid != 0);
-
- if (quad)
- sprintf (templ, "%s.i%d\t%%q0, %%2", mnem, width);
- else
- sprintf (templ, "%s.i%d\t%%P0, %%2", mnem, width);
-
- return templ;
-}
-
-/* Return a string suitable for output of Neon immediate shift operation
- (VSHR or VSHL) MNEM. */
-
-char *
-neon_output_shift_immediate (const char *mnem, char sign, rtx *op2,
- enum machine_mode mode, int quad,
- bool isleftshift)
-{
- int width, is_valid;
- static char templ[40];
-
- is_valid = neon_immediate_valid_for_shift (*op2, mode, op2, &width, isleftshift);
- gcc_assert (is_valid != 0);
-
- if (quad)
- sprintf (templ, "%s.%c%d\t%%q0, %%q1, %%2", mnem, sign, width);
- else
- sprintf (templ, "%s.%c%d\t%%P0, %%P1, %%2", mnem, sign, width);
-
- return templ;
-}
-
-/* Output a sequence of pairwise operations to implement a reduction.
- NOTE: We do "too much work" here, because pairwise operations work on two
- registers-worth of operands in one go. Unfortunately we can't exploit those
- extra calculations to do the full operation in fewer steps, I don't think.
- Although all vector elements of the result but the first are ignored, we
- actually calculate the same result in each of the elements. An alternative
- such as initially loading a vector with zero to use as each of the second
- operands would use up an additional register and take an extra instruction,
- for no particular gain. */
-
-void
-neon_pairwise_reduce (rtx op0, rtx op1, enum machine_mode mode,
- rtx (*reduc) (rtx, rtx, rtx))
-{
- enum machine_mode inner = GET_MODE_INNER (mode);
- unsigned int i, parts = GET_MODE_SIZE (mode) / GET_MODE_SIZE (inner);
- rtx tmpsum = op1;
-
- for (i = parts / 2; i >= 1; i /= 2)
- {
- rtx dest = (i == 1) ? op0 : gen_reg_rtx (mode);
- emit_insn (reduc (dest, tmpsum, tmpsum));
- tmpsum = dest;
- }
-}
-
-/* If VALS is a vector constant that can be loaded into a register
- using VDUP, generate instructions to do so and return an RTX to
- assign to the register. Otherwise return NULL_RTX. */
-
-static rtx
-neon_vdup_constant (rtx vals)
-{
- enum machine_mode mode = GET_MODE (vals);
- enum machine_mode inner_mode = GET_MODE_INNER (mode);
- int n_elts = GET_MODE_NUNITS (mode);
- bool all_same = true;
- rtx x;
- int i;
-
- if (GET_CODE (vals) != CONST_VECTOR || GET_MODE_SIZE (inner_mode) > 4)
- return NULL_RTX;
-
- for (i = 0; i < n_elts; ++i)
- {
- x = XVECEXP (vals, 0, i);
- if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
- all_same = false;
- }
-
- if (!all_same)
- /* The elements are not all the same. We could handle repeating
- patterns of a mode larger than INNER_MODE here (e.g. int8x8_t
- {0, C, 0, C, 0, C, 0, C} which can be loaded using
- vdup.i16). */
- return NULL_RTX;
-
- /* We can load this constant by using VDUP and a constant in a
- single ARM register. This will be cheaper than a vector
- load. */
-
- x = copy_to_mode_reg (inner_mode, XVECEXP (vals, 0, 0));
- return gen_rtx_VEC_DUPLICATE (mode, x);
-}
-
-/* Generate code to load VALS, which is a PARALLEL containing only
- constants (for vec_init) or CONST_VECTOR, efficiently into a
- register. Returns an RTX to copy into the register, or NULL_RTX
- for a PARALLEL that can not be converted into a CONST_VECTOR. */
-
-rtx
-neon_make_constant (rtx vals)
-{
- enum machine_mode mode = GET_MODE (vals);
- rtx target;
- rtx const_vec = NULL_RTX;
- int n_elts = GET_MODE_NUNITS (mode);
- int n_const = 0;
- int i;
-
- if (GET_CODE (vals) == CONST_VECTOR)
- const_vec = vals;
- else if (GET_CODE (vals) == PARALLEL)
- {
- /* A CONST_VECTOR must contain only CONST_INTs and
- CONST_DOUBLEs, but CONSTANT_P allows more (e.g. SYMBOL_REF).
- Only store valid constants in a CONST_VECTOR. */
- for (i = 0; i < n_elts; ++i)
- {
- rtx x = XVECEXP (vals, 0, i);
- if (CONST_INT_P (x) || CONST_DOUBLE_P (x))
- n_const++;
- }
- if (n_const == n_elts)
- const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
- }
- else
- gcc_unreachable ();
-
- if (const_vec != NULL
- && neon_immediate_valid_for_move (const_vec, mode, NULL, NULL))
- /* Load using VMOV. On Cortex-A8 this takes one cycle. */
- return const_vec;
- else if ((target = neon_vdup_constant (vals)) != NULL_RTX)
- /* Loaded using VDUP. On Cortex-A8 the VDUP takes one NEON
- pipeline cycle; creating the constant takes one or two ARM
- pipeline cycles. */
- return target;
- else if (const_vec != NULL_RTX)
- /* Load from constant pool. On Cortex-A8 this takes two cycles
- (for either double or quad vectors). We can not take advantage
- of single-cycle VLD1 because we need a PC-relative addressing
- mode. */
- return const_vec;
- else
- /* A PARALLEL containing something not valid inside CONST_VECTOR.
- We can not construct an initializer. */
- return NULL_RTX;
-}
-
-/* Initialize vector TARGET to VALS. */
-
-void
-neon_expand_vector_init (rtx target, rtx vals)
-{
- enum machine_mode mode = GET_MODE (target);
- enum machine_mode inner_mode = GET_MODE_INNER (mode);
- int n_elts = GET_MODE_NUNITS (mode);
- int n_var = 0, one_var = -1;
- bool all_same = true;
- rtx x, mem;
- int i;
-
- for (i = 0; i < n_elts; ++i)
- {
- x = XVECEXP (vals, 0, i);
- if (!CONSTANT_P (x))
- ++n_var, one_var = i;
-
- if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
- all_same = false;
- }
-
- if (n_var == 0)
- {
- rtx constant = neon_make_constant (vals);
- if (constant != NULL_RTX)
- {
- emit_move_insn (target, constant);
- return;
- }
- }
-
- /* Splat a single non-constant element if we can. */
- if (all_same && GET_MODE_SIZE (inner_mode) <= 4)
- {
- x = copy_to_mode_reg (inner_mode, XVECEXP (vals, 0, 0));
- emit_insn (gen_rtx_SET (VOIDmode, target,
- gen_rtx_VEC_DUPLICATE (mode, x)));
- return;
- }
-
- /* One field is non-constant. Load constant then overwrite varying
- field. This is more efficient than using the stack. */
- if (n_var == 1)
- {
- rtx copy = copy_rtx (vals);
- rtx index = GEN_INT (one_var);
-
- /* Load constant part of vector, substitute neighboring value for
- varying element. */
- XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
- neon_expand_vector_init (target, copy);
-
- /* Insert variable. */
- x = copy_to_mode_reg (inner_mode, XVECEXP (vals, 0, one_var));
- switch (mode)
- {
- case V8QImode:
- emit_insn (gen_neon_vset_lanev8qi (target, x, target, index));
- break;
- case V16QImode:
- emit_insn (gen_neon_vset_lanev16qi (target, x, target, index));
- break;
- case V4HImode:
- emit_insn (gen_neon_vset_lanev4hi (target, x, target, index));
- break;
- case V8HImode:
- emit_insn (gen_neon_vset_lanev8hi (target, x, target, index));
- break;
- case V2SImode:
- emit_insn (gen_neon_vset_lanev2si (target, x, target, index));
- break;
- case V4SImode:
- emit_insn (gen_neon_vset_lanev4si (target, x, target, index));
- break;
- case V2SFmode:
- emit_insn (gen_neon_vset_lanev2sf (target, x, target, index));
- break;
- case V4SFmode:
- emit_insn (gen_neon_vset_lanev4sf (target, x, target, index));
- break;
- case V2DImode:
- emit_insn (gen_neon_vset_lanev2di (target, x, target, index));
- break;
- default:
- gcc_unreachable ();
- }
- return;
- }
-
- /* Construct the vector in memory one field at a time
- and load the whole vector. */
- mem = assign_stack_temp (mode, GET_MODE_SIZE (mode));
- for (i = 0; i < n_elts; i++)
- emit_move_insn (adjust_address_nv (mem, inner_mode,
- i * GET_MODE_SIZE (inner_mode)),
- XVECEXP (vals, 0, i));
- emit_move_insn (target, mem);
-}
-
-/* Ensure OPERAND lies between LOW (inclusive) and HIGH (exclusive). Raise
- ERR if it doesn't. FIXME: NEON bounds checks occur late in compilation, so
- reported source locations are bogus. */
-
-static void
-bounds_check (rtx operand, HOST_WIDE_INT low, HOST_WIDE_INT high,
- const char *err)
-{
- HOST_WIDE_INT lane;
-
- gcc_assert (CONST_INT_P (operand));
-
- lane = INTVAL (operand);
-
- if (lane < low || lane >= high)
- error (err);
-}
-
-/* Bounds-check lanes. */
-
-void
-neon_lane_bounds (rtx operand, HOST_WIDE_INT low, HOST_WIDE_INT high)
-{
- bounds_check (operand, low, high, "lane out of range");
-}
-
-/* Bounds-check constants. */
-
-void
-neon_const_bounds (rtx operand, HOST_WIDE_INT low, HOST_WIDE_INT high)
-{
- bounds_check (operand, low, high, "constant out of range");
-}
-
-HOST_WIDE_INT
-neon_element_bits (enum machine_mode mode)
-{
- if (mode == DImode)
- return GET_MODE_BITSIZE (mode);
- else
- return GET_MODE_BITSIZE (GET_MODE_INNER (mode));
-}
-
-
-/* Predicates for `match_operand' and `match_operator'. */
-
-/* Return TRUE if OP is a valid coprocessor memory address pattern.
- WB is true if full writeback address modes are allowed and is false
- if limited writeback address modes (POST_INC and PRE_DEC) are
- allowed. */
-
-int
-arm_coproc_mem_operand (rtx op, bool wb)
-{
- rtx ind;
-
- /* Reject eliminable registers. */
- if (! (reload_in_progress || reload_completed)
- && ( reg_mentioned_p (frame_pointer_rtx, op)
- || reg_mentioned_p (arg_pointer_rtx, op)
- || reg_mentioned_p (virtual_incoming_args_rtx, op)
- || reg_mentioned_p (virtual_outgoing_args_rtx, op)
- || reg_mentioned_p (virtual_stack_dynamic_rtx, op)
- || reg_mentioned_p (virtual_stack_vars_rtx, op)))
- return FALSE;
-
- /* Constants are converted into offsets from labels. */
- if (!MEM_P (op))
- return FALSE;
-
- ind = XEXP (op, 0);
-
- if (reload_completed
- && (GET_CODE (ind) == LABEL_REF
- || (GET_CODE (ind) == CONST
- && GET_CODE (XEXP (ind, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (ind, 0), 0)) == LABEL_REF
- && CONST_INT_P (XEXP (XEXP (ind, 0), 1)))))
- return TRUE;
-
- /* Match: (mem (reg)). */
- if (REG_P (ind))
- return arm_address_register_rtx_p (ind, 0);
-
- /* Autoincremment addressing modes. POST_INC and PRE_DEC are
- acceptable in any case (subject to verification by
- arm_address_register_rtx_p). We need WB to be true to accept
- PRE_INC and POST_DEC. */
- if (GET_CODE (ind) == POST_INC
- || GET_CODE (ind) == PRE_DEC
- || (wb
- && (GET_CODE (ind) == PRE_INC
- || GET_CODE (ind) == POST_DEC)))
- return arm_address_register_rtx_p (XEXP (ind, 0), 0);
-
- if (wb
- && (GET_CODE (ind) == POST_MODIFY || GET_CODE (ind) == PRE_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);
-
- /* Match:
- (plus (reg)
- (const)). */
- if (GET_CODE (ind) == PLUS
- && REG_P (XEXP (ind, 0))
- && REG_MODE_OK_FOR_BASE_P (XEXP (ind, 0), VOIDmode)
- && CONST_INT_P (XEXP (ind, 1))
- && INTVAL (XEXP (ind, 1)) > -1024
- && INTVAL (XEXP (ind, 1)) < 1024
- && (INTVAL (XEXP (ind, 1)) & 3) == 0)
- return TRUE;
-
- return FALSE;
-}
-
-/* Return TRUE if OP is a memory operand which we can load or store a vector
- 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, int type)
-{
- rtx ind;
-
- /* Reject eliminable registers. */
- if (! (reload_in_progress || reload_completed)
- && ( reg_mentioned_p (frame_pointer_rtx, op)
- || reg_mentioned_p (arg_pointer_rtx, op)
- || reg_mentioned_p (virtual_incoming_args_rtx, op)
- || reg_mentioned_p (virtual_outgoing_args_rtx, op)
- || reg_mentioned_p (virtual_stack_dynamic_rtx, op)
- || reg_mentioned_p (virtual_stack_vars_rtx, op)))
- return FALSE;
-
- /* Constants are converted into offsets from labels. */
- if (!MEM_P (op))
- return FALSE;
-
- ind = XEXP (op, 0);
-
- if (reload_completed
- && (GET_CODE (ind) == LABEL_REF
- || (GET_CODE (ind) == CONST
- && GET_CODE (XEXP (ind, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (ind, 0), 0)) == LABEL_REF
- && CONST_INT_P (XEXP (XEXP (ind, 0), 1)))))
- return TRUE;
-
- /* Match: (mem (reg)). */
- if (REG_P (ind))
- return arm_address_register_rtx_p (ind, 0);
-
- /* Allow post-increment with Neon registers. */
- 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);
-
- /* FIXME: vld1 allows register post-modify. */
-
- /* Match:
- (plus (reg)
- (const)). */
- if (type == 0
- && GET_CODE (ind) == PLUS
- && REG_P (XEXP (ind, 0))
- && REG_MODE_OK_FOR_BASE_P (XEXP (ind, 0), VOIDmode)
- && CONST_INT_P (XEXP (ind, 1))
- && INTVAL (XEXP (ind, 1)) > -1024
- /* For quad modes, we restrict the constant offset to be slightly less
- than what the instruction format permits. We have no such constraint
- on double mode offsets. (This must match arm_legitimate_index_p.) */
- && (INTVAL (XEXP (ind, 1))
- < (VALID_NEON_QREG_MODE (GET_MODE (op))? 1016 : 1024))
- && (INTVAL (XEXP (ind, 1)) & 3) == 0)
- return TRUE;
-
- return FALSE;
-}
-
-/* Return TRUE if OP is a mem suitable for loading/storing a Neon struct
- type. */
-int
-neon_struct_mem_operand (rtx op)
-{
- rtx ind;
-
- /* Reject eliminable registers. */
- if (! (reload_in_progress || reload_completed)
- && ( reg_mentioned_p (frame_pointer_rtx, op)
- || reg_mentioned_p (arg_pointer_rtx, op)
- || reg_mentioned_p (virtual_incoming_args_rtx, op)
- || reg_mentioned_p (virtual_outgoing_args_rtx, op)
- || reg_mentioned_p (virtual_stack_dynamic_rtx, op)
- || reg_mentioned_p (virtual_stack_vars_rtx, op)))
- return FALSE;
-
- /* Constants are converted into offsets from labels. */
- if (!MEM_P (op))
- return FALSE;
-
- ind = XEXP (op, 0);
-
- if (reload_completed
- && (GET_CODE (ind) == LABEL_REF
- || (GET_CODE (ind) == CONST
- && GET_CODE (XEXP (ind, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (ind, 0), 0)) == LABEL_REF
- && CONST_INT_P (XEXP (XEXP (ind, 0), 1)))))
- return TRUE;
-
- /* Match: (mem (reg)). */
- if (REG_P (ind))
- return arm_address_register_rtx_p (ind, 0);
-
- /* vldm/vstm allows POST_INC (ia) and PRE_DEC (db). */
- if (GET_CODE (ind) == POST_INC
- || GET_CODE (ind) == PRE_DEC)
- return arm_address_register_rtx_p (XEXP (ind, 0), 0);
-
- return FALSE;
-}
-
-/* Return true if X is a register that will be eliminated later on. */
-int
-arm_eliminable_register (rtx x)
-{
- return REG_P (x) && (REGNO (x) == FRAME_POINTER_REGNUM
- || REGNO (x) == ARG_POINTER_REGNUM
- || (REGNO (x) >= FIRST_VIRTUAL_REGISTER
- && REGNO (x) <= LAST_VIRTUAL_REGISTER));
-}
-
-/* Return GENERAL_REGS if a scratch register required to reload x to/from
- coprocessor registers. Otherwise return NO_REGS. */
-
-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;
- }
-
- /* The neon move patterns handle all legitimate vector and struct
- addresses. */
- if (TARGET_NEON
- && (MEM_P (x) || GET_CODE (x) == CONST_VECTOR)
- && (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
- || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT
- || VALID_NEON_STRUCT_MODE (mode)))
- return NO_REGS;
-
- if (arm_coproc_mem_operand (x, wb) || s_register_operand (x, mode))
- return NO_REGS;
-
- return GENERAL_REGS;
-}
-
-/* Values which must be returned in the most-significant end of the return
- register. */
-
-static bool
-arm_return_in_msb (const_tree valtype)
-{
- return (TARGET_AAPCS_BASED
- && BYTES_BIG_ENDIAN
- && (AGGREGATE_TYPE_P (valtype)
- || TREE_CODE (valtype) == COMPLEX_TYPE
- || FIXED_POINT_TYPE_P (valtype)));
-}
-
-/* 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;
-
- /* UNSPEC_TLS entries for a symbol include the SYMBOL_REF, but they
- are constant offsets, not symbols. */
- if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLS)
- return 0;
-
- 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;
-
- /* UNSPEC_TLS entries for a symbol include a LABEL_REF for the referencing
- instruction, but they are constant offsets, not symbols. */
- if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLS)
- return 0;
-
- 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;
-}
-
-int
-tls_mentioned_p (rtx x)
-{
- switch (GET_CODE (x))
- {
- case CONST:
- return tls_mentioned_p (XEXP (x, 0));
-
- case UNSPEC:
- if (XINT (x, 1) == UNSPEC_TLS)
- return 1;
-
- default:
- return 0;
- }
-}
-
-/* Must not copy any rtx that uses a pc-relative address. */
-
-static int
-arm_note_pic_base (rtx *x, void *date ATTRIBUTE_UNUSED)
-{
- if (GET_CODE (*x) == UNSPEC
- && (XINT (*x, 1) == UNSPEC_PIC_BASE
- || XINT (*x, 1) == UNSPEC_PIC_UNIFIED))
- return 1;
- return 0;
-}
-
-static bool
-arm_cannot_copy_insn_p (rtx insn)
-{
- /* The tls call insn cannot be copied, as it is paired with a data
- word. */
- if (recog_memoized (insn) == CODE_FOR_tlscall)
- return true;
-
- return for_each_rtx (&PATTERN (insn), arm_note_pic_base, NULL);
-}
-
-enum rtx_code
-minmax_code (rtx x)
-{
- enum rtx_code code = GET_CODE (x);
-
- switch (code)
- {
- case SMAX:
- return GE;
- case SMIN:
- return LE;
- case UMIN:
- return LEU;
- case UMAX:
- return GEU;
- default:
- gcc_unreachable ();
- }
-}
-
-/* Match pair of min/max operators that can be implemented via usat/ssat. */
-
-bool
-arm_sat_operator_match (rtx lo_bound, rtx hi_bound,
- int *mask, bool *signed_sat)
-{
- /* The high bound must be a power of two minus one. */
- int log = exact_log2 (INTVAL (hi_bound) + 1);
- if (log == -1)
- return false;
-
- /* The low bound is either zero (for usat) or one less than the
- negation of the high bound (for ssat). */
- if (INTVAL (lo_bound) == 0)
- {
- if (mask)
- *mask = log;
- if (signed_sat)
- *signed_sat = false;
-
- return true;
- }
-
- if (INTVAL (lo_bound) == -INTVAL (hi_bound) - 1)
- {
- if (mask)
- *mask = log + 1;
- if (signed_sat)
- *signed_sat = true;
-
- return true;
- }
-
- return false;
-}
-
-/* Return 1 if memory locations are adjacent. */
-int
-adjacent_mem_locations (rtx a, rtx b)
-{
- /* We don't guarantee to preserve the order of these memory refs. */
- if (volatile_refs_p (a) || volatile_refs_p (b))
- return 0;
-
- if ((REG_P (XEXP (a, 0))
- || (GET_CODE (XEXP (a, 0)) == PLUS
- && CONST_INT_P (XEXP (XEXP (a, 0), 1))))
- && (REG_P (XEXP (b, 0))
- || (GET_CODE (XEXP (b, 0)) == PLUS
- && CONST_INT_P (XEXP (XEXP (b, 0), 1)))))
- {
- HOST_WIDE_INT val0 = 0, val1 = 0;
- rtx reg0, reg1;
- int val_diff;
-
- if (GET_CODE (XEXP (a, 0)) == PLUS)
- {
- reg0 = XEXP (XEXP (a, 0), 0);
- val0 = INTVAL (XEXP (XEXP (a, 0), 1));
- }
- else
- reg0 = XEXP (a, 0);
-
- if (GET_CODE (XEXP (b, 0)) == PLUS)
- {
- reg1 = XEXP (XEXP (b, 0), 0);
- val1 = INTVAL (XEXP (XEXP (b, 0), 1));
- }
- else
- reg1 = XEXP (b, 0);
-
- /* Don't accept any offset that will require multiple
- instructions to handle, since this would cause the
- arith_adjacentmem pattern to output an overlong sequence. */
- if (!const_ok_for_op (val0, PLUS) || !const_ok_for_op (val1, PLUS))
- return 0;
-
- /* Don't allow an eliminable register: register elimination can make
- the offset too large. */
- if (arm_eliminable_register (reg0))
- return 0;
-
- val_diff = val1 - val0;
-
- if (arm_ld_sched)
- {
- /* If the target has load delay slots, then there's no benefit
- to using an ldm instruction unless the offset is zero and
- we are optimizing for size. */
- return (optimize_size && (REGNO (reg0) == REGNO (reg1))
- && (val0 == 0 || val1 == 0 || val0 == 4 || val1 == 4)
- && (val_diff == 4 || val_diff == -4));
- }
-
- return ((REGNO (reg0) == REGNO (reg1))
- && (val_diff == 4 || val_diff == -4));
- }
-
- return 0;
-}
-
-/* Return true if OP is a valid load or store multiple operation. LOAD is true
- for load operations, false for store operations. CONSECUTIVE is true
- if the register numbers in the operation must be consecutive in the register
- bank. RETURN_PC is true if value is to be loaded in PC.
- The pattern we are trying to match for load is:
- [(SET (R_d0) (MEM (PLUS (addr) (offset))))
- (SET (R_d1) (MEM (PLUS (addr) (offset + <reg_increment>))))
- :
- :
- (SET (R_dn) (MEM (PLUS (addr) (offset + n * <reg_increment>))))
- ]
- where
- 1. If offset is 0, first insn should be (SET (R_d0) (MEM (src_addr))).
- 2. REGNO (R_d0) < REGNO (R_d1) < ... < REGNO (R_dn).
- 3. If consecutive is TRUE, then for kth register being loaded,
- REGNO (R_dk) = REGNO (R_d0) + k.
- The pattern for store is similar. */
-bool
-ldm_stm_operation_p (rtx op, bool load, enum machine_mode mode,
- bool consecutive, bool return_pc)
-{
- HOST_WIDE_INT count = XVECLEN (op, 0);
- rtx reg, mem, addr;
- unsigned regno;
- unsigned first_regno;
- HOST_WIDE_INT i = 1, base = 0, offset = 0;
- rtx elt;
- bool addr_reg_in_reglist = false;
- bool update = false;
- int reg_increment;
- int offset_adj;
- int regs_per_val;
-
- /* If not in SImode, then registers must be consecutive
- (e.g., VLDM instructions for DFmode). */
- gcc_assert ((mode == SImode) || consecutive);
- /* Setting return_pc for stores is illegal. */
- gcc_assert (!return_pc || load);
-
- /* Set up the increments and the regs per val based on the mode. */
- reg_increment = GET_MODE_SIZE (mode);
- regs_per_val = reg_increment / 4;
- offset_adj = return_pc ? 1 : 0;
-
- if (count <= 1
- || GET_CODE (XVECEXP (op, 0, offset_adj)) != SET
- || (load && !REG_P (SET_DEST (XVECEXP (op, 0, offset_adj)))))
- return false;
-
- /* Check if this is a write-back. */
- elt = XVECEXP (op, 0, offset_adj);
- if (GET_CODE (SET_SRC (elt)) == PLUS)
- {
- i++;
- base = 1;
- update = true;
-
- /* The offset adjustment must be the number of registers being
- popped times the size of a single register. */
- if (!REG_P (SET_DEST (elt))
- || !REG_P (XEXP (SET_SRC (elt), 0))
- || (REGNO (SET_DEST (elt)) != REGNO (XEXP (SET_SRC (elt), 0)))
- || !CONST_INT_P (XEXP (SET_SRC (elt), 1))
- || INTVAL (XEXP (SET_SRC (elt), 1)) !=
- ((count - 1 - offset_adj) * reg_increment))
- return false;
- }
-
- i = i + offset_adj;
- base = base + offset_adj;
- /* Perform a quick check so we don't blow up below. If only one reg is loaded,
- success depends on the type: VLDM can do just one reg,
- LDM must do at least two. */
- if ((count <= i) && (mode == SImode))
- return false;
-
- elt = XVECEXP (op, 0, i - 1);
- if (GET_CODE (elt) != SET)
- return false;
-
- if (load)
- {
- reg = SET_DEST (elt);
- mem = SET_SRC (elt);
- }
- else
- {
- reg = SET_SRC (elt);
- mem = SET_DEST (elt);
- }
-
- if (!REG_P (reg) || !MEM_P (mem))
- return false;
-
- regno = REGNO (reg);
- first_regno = regno;
- addr = XEXP (mem, 0);
- if (GET_CODE (addr) == PLUS)
- {
- if (!CONST_INT_P (XEXP (addr, 1)))
- return false;
-
- offset = INTVAL (XEXP (addr, 1));
- addr = XEXP (addr, 0);
- }
-
- if (!REG_P (addr))
- return false;
-
- /* Don't allow SP to be loaded unless it is also the base register. It
- guarantees that SP is reset correctly when an LDM instruction
- is interruptted. Otherwise, we might end up with a corrupt stack. */
- if (load && (REGNO (reg) == SP_REGNUM) && (REGNO (addr) != SP_REGNUM))
- return false;
-
- for (; i < count; i++)
- {
- elt = XVECEXP (op, 0, i);
- if (GET_CODE (elt) != SET)
- return false;
-
- if (load)
- {
- reg = SET_DEST (elt);
- mem = SET_SRC (elt);
- }
- else
- {
- reg = SET_SRC (elt);
- mem = SET_DEST (elt);
- }
-
- if (!REG_P (reg)
- || GET_MODE (reg) != mode
- || REGNO (reg) <= regno
- || (consecutive
- && (REGNO (reg) !=
- (unsigned int) (first_regno + regs_per_val * (i - base))))
- /* Don't allow SP to be loaded unless it is also the base register. It
- guarantees that SP is reset correctly when an LDM instruction
- is interrupted. Otherwise, we might end up with a corrupt stack. */
- || (load && (REGNO (reg) == SP_REGNUM) && (REGNO (addr) != SP_REGNUM))
- || !MEM_P (mem)
- || GET_MODE (mem) != mode
- || ((GET_CODE (XEXP (mem, 0)) != PLUS
- || !rtx_equal_p (XEXP (XEXP (mem, 0), 0), addr)
- || !CONST_INT_P (XEXP (XEXP (mem, 0), 1))
- || (INTVAL (XEXP (XEXP (mem, 0), 1)) !=
- offset + (i - base) * reg_increment))
- && (!REG_P (XEXP (mem, 0))
- || offset + (i - base) * reg_increment != 0)))
- return false;
-
- regno = REGNO (reg);
- if (regno == REGNO (addr))
- addr_reg_in_reglist = true;
- }
-
- if (load)
- {
- if (update && addr_reg_in_reglist)
- return false;
-
- /* For Thumb-1, address register is always modified - either by write-back
- or by explicit load. If the pattern does not describe an update,
- then the address register must be in the list of loaded registers. */
- if (TARGET_THUMB1)
- return update || addr_reg_in_reglist;
- }
-
- return true;
-}
-
-/* Return true iff it would be profitable to turn a sequence of NOPS loads
- or stores (depending on IS_STORE) into a load-multiple or store-multiple
- instruction. ADD_OFFSET is nonzero if the base address register needs
- to be modified with an add instruction before we can use it. */
-
-static bool
-multiple_operation_profitable_p (bool is_store ATTRIBUTE_UNUSED,
- int nops, HOST_WIDE_INT add_offset)
- {
- /* For ARM8,9 & StrongARM, 2 ldr instructions are faster than an ldm
- if the offset isn't small enough. The reason 2 ldrs are faster
- is because these ARMs are able to do more than one cache access
- in a single cycle. The ARM9 and StrongARM have Harvard caches,
- whilst the ARM8 has a double bandwidth cache. This means that
- these cores can do both an instruction fetch and a data fetch in
- a single cycle, so the trick of calculating the address into a
- scratch register (one of the result regs) and then doing a load
- multiple actually becomes slower (and no smaller in code size).
- That is the transformation
-
- ldr rd1, [rbase + offset]
- ldr rd2, [rbase + offset + 4]
-
- to
-
- add rd1, rbase, offset
- ldmia rd1, {rd1, rd2}
-
- produces worse code -- '3 cycles + any stalls on rd2' instead of
- '2 cycles + any stalls on rd2'. On ARMs with only one cache
- access per cycle, the first sequence could never complete in less
- than 6 cycles, whereas the ldm sequence would only take 5 and
- would make better use of sequential accesses if not hitting the
- cache.
-
- We cheat here and test 'arm_ld_sched' which we currently know to
- only be true for the ARM8, ARM9 and StrongARM. If this ever
- changes, then the test below needs to be reworked. */
- if (nops == 2 && arm_ld_sched && add_offset != 0)
- return false;
-
- /* XScale has load-store double instructions, but they have stricter
- alignment requirements than load-store multiple, so we cannot
- use them.
-
- For XScale ldm requires 2 + NREGS cycles to complete and blocks
- the pipeline until completion.
-
- NREGS CYCLES
- 1 3
- 2 4
- 3 5
- 4 6
-
- An ldr instruction takes 1-3 cycles, but does not block the
- pipeline.
-
- NREGS CYCLES
- 1 1-3
- 2 2-6
- 3 3-9
- 4 4-12
-
- Best case ldr will always win. However, the more ldr instructions
- we issue, the less likely we are to be able to schedule them well.
- Using ldr instructions also increases code size.
-
- As a compromise, we use ldr for counts of 1 or 2 regs, and ldm
- for counts of 3 or 4 regs. */
- if (nops <= 2 && arm_tune_xscale && !optimize_size)
- return false;
- return true;
-}
-
-/* Subroutine of load_multiple_sequence and store_multiple_sequence.
- Given an array of UNSORTED_OFFSETS, of which there are NOPS, compute
- an array ORDER which describes the sequence to use when accessing the
- offsets that produces an ascending order. In this sequence, each
- offset must be larger by exactly 4 than the previous one. ORDER[0]
- must have been filled in with the lowest offset by the caller.
- If UNSORTED_REGS is nonnull, it is an array of register numbers that
- we use to verify that ORDER produces an ascending order of registers.
- Return true if it was possible to construct such an order, false if
- not. */
-
-static bool
-compute_offset_order (int nops, HOST_WIDE_INT *unsorted_offsets, int *order,
- int *unsorted_regs)
-{
- int i;
- for (i = 1; i < nops; i++)
- {
- int j;
-
- order[i] = order[i - 1];
- for (j = 0; j < nops; j++)
- if (unsorted_offsets[j] == unsorted_offsets[order[i - 1]] + 4)
- {
- /* We must find exactly one offset that is higher than the
- previous one by 4. */
- if (order[i] != order[i - 1])
- return false;
- order[i] = j;
- }
- if (order[i] == order[i - 1])
- return false;
- /* The register numbers must be ascending. */
- if (unsorted_regs != NULL
- && unsorted_regs[order[i]] <= unsorted_regs[order[i - 1]])
- return false;
- }
- return true;
-}
-
-/* Used to determine in a peephole whether a sequence of load
- instructions can be changed into a load-multiple instruction.
- NOPS is the number of separate load instructions we are examining. The
- first NOPS entries in OPERANDS are the destination registers, the
- next NOPS entries are memory operands. If this function is
- successful, *BASE is set to the common base register of the memory
- accesses; *LOAD_OFFSET is set to the first memory location's offset
- from that base register.
- REGS is an array filled in with the destination register numbers.
- SAVED_ORDER (if nonnull), is an array filled in with an order that maps
- insn numbers to an ascending order of stores. If CHECK_REGS is true,
- the sequence of registers in REGS matches the loads from ascending memory
- locations, and the function verifies that the register numbers are
- themselves ascending. If CHECK_REGS is false, the register numbers
- are stored in the order they are found in the operands. */
-static int
-load_multiple_sequence (rtx *operands, int nops, int *regs, int *saved_order,
- int *base, HOST_WIDE_INT *load_offset, bool check_regs)
-{
- int unsorted_regs[MAX_LDM_STM_OPS];
- HOST_WIDE_INT unsorted_offsets[MAX_LDM_STM_OPS];
- int order[MAX_LDM_STM_OPS];
- rtx base_reg_rtx = NULL;
- int base_reg = -1;
- int i, ldm_case;
-
- /* Can only handle up to MAX_LDM_STM_OPS insns at present, though could be
- easily extended if required. */
- gcc_assert (nops >= 2 && nops <= MAX_LDM_STM_OPS);
-
- memset (order, 0, MAX_LDM_STM_OPS * sizeof (int));
-
- /* Loop over the operands and check that the memory references are
- suitable (i.e. immediate offsets from the same base register). At
- the same time, extract the target register, and the memory
- offsets. */
- for (i = 0; i < nops; i++)
- {
- rtx reg;
- rtx offset;
-
- /* Convert a subreg of a mem into the mem itself. */
- if (GET_CODE (operands[nops + i]) == SUBREG)
- operands[nops + i] = alter_subreg (operands + (nops + i), true);
-
- gcc_assert (MEM_P (operands[nops + i]));
-
- /* Don't reorder volatile memory references; it doesn't seem worth
- looking for the case where the order is ok anyway. */
- if (MEM_VOLATILE_P (operands[nops + i]))
- return 0;
-
- offset = const0_rtx;
-
- if ((REG_P (reg = XEXP (operands[nops + i], 0))
- || (GET_CODE (reg) == SUBREG
- && REG_P (reg = SUBREG_REG (reg))))
- || (GET_CODE (XEXP (operands[nops + i], 0)) == PLUS
- && ((REG_P (reg = XEXP (XEXP (operands[nops + i], 0), 0)))
- || (GET_CODE (reg) == SUBREG
- && REG_P (reg = SUBREG_REG (reg))))
- && (CONST_INT_P (offset
- = XEXP (XEXP (operands[nops + i], 0), 1)))))
- {
- if (i == 0)
- {
- base_reg = REGNO (reg);
- base_reg_rtx = reg;
- if (TARGET_THUMB1 && base_reg > LAST_LO_REGNUM)
- return 0;
- }
- else if (base_reg != (int) REGNO (reg))
- /* Not addressed from the same base register. */
- return 0;
-
- unsorted_regs[i] = (REG_P (operands[i])
- ? REGNO (operands[i])
- : REGNO (SUBREG_REG (operands[i])));
-
- /* If it isn't an integer register, or if it overwrites the
- base register but isn't the last insn in the list, then
- we can't do this. */
- if (unsorted_regs[i] < 0
- || (TARGET_THUMB1 && unsorted_regs[i] > LAST_LO_REGNUM)
- || unsorted_regs[i] > 14
- || (i != nops - 1 && unsorted_regs[i] == base_reg))
- return 0;
-
- /* Don't allow SP to be loaded unless it is also the base
- register. It guarantees that SP is reset correctly when
- an LDM instruction is interrupted. Otherwise, we might
- end up with a corrupt stack. */
- if (unsorted_regs[i] == SP_REGNUM && base_reg != SP_REGNUM)
- return 0;
-
- unsorted_offsets[i] = INTVAL (offset);
- if (i == 0 || unsorted_offsets[i] < unsorted_offsets[order[0]])
- order[0] = i;
- }
- else
- /* Not a suitable memory address. */
- return 0;
- }
-
- /* All the useful information has now been extracted from the
- operands into unsorted_regs and unsorted_offsets; additionally,
- order[0] has been set to the lowest offset in the list. Sort
- the offsets into order, verifying that they are adjacent, and
- check that the register numbers are ascending. */
- if (!compute_offset_order (nops, unsorted_offsets, order,
- check_regs ? unsorted_regs : NULL))
- return 0;
-
- if (saved_order)
- memcpy (saved_order, order, sizeof order);
-
- if (base)
- {
- *base = base_reg;
-
- for (i = 0; i < nops; i++)
- regs[i] = unsorted_regs[check_regs ? order[i] : i];
-
- *load_offset = unsorted_offsets[order[0]];
- }
-
- if (TARGET_THUMB1
- && !peep2_reg_dead_p (nops, base_reg_rtx))
- return 0;
-
- if (unsorted_offsets[order[0]] == 0)
- ldm_case = 1; /* ldmia */
- else if (TARGET_ARM && unsorted_offsets[order[0]] == 4)
- ldm_case = 2; /* ldmib */
- else if (TARGET_ARM && unsorted_offsets[order[nops - 1]] == 0)
- ldm_case = 3; /* ldmda */
- else if (TARGET_32BIT && unsorted_offsets[order[nops - 1]] == -4)
- ldm_case = 4; /* ldmdb */
- else if (const_ok_for_arm (unsorted_offsets[order[0]])
- || const_ok_for_arm (-unsorted_offsets[order[0]]))
- ldm_case = 5;
- else
- return 0;
-
- if (!multiple_operation_profitable_p (false, nops,
- ldm_case == 5
- ? unsorted_offsets[order[0]] : 0))
- return 0;
-
- return ldm_case;
-}
-
-/* Used to determine in a peephole whether a sequence of store instructions can
- be changed into a store-multiple instruction.
- NOPS is the number of separate store instructions we are examining.
- NOPS_TOTAL is the total number of instructions recognized by the peephole
- pattern.
- The first NOPS entries in OPERANDS are the source registers, the next
- NOPS entries are memory operands. If this function is successful, *BASE is
- set to the common base register of the memory accesses; *LOAD_OFFSET is set
- to the first memory location's offset from that base register. REGS is an
- array filled in with the source register numbers, REG_RTXS (if nonnull) is
- likewise filled with the corresponding rtx's.
- SAVED_ORDER (if nonnull), is an array filled in with an order that maps insn
- numbers to an ascending order of stores.
- If CHECK_REGS is true, the sequence of registers in *REGS matches the stores
- from ascending memory locations, and the function verifies that the register
- numbers are themselves ascending. If CHECK_REGS is false, the register
- numbers are stored in the order they are found in the operands. */
-static int
-store_multiple_sequence (rtx *operands, int nops, int nops_total,
- int *regs, rtx *reg_rtxs, int *saved_order, int *base,
- HOST_WIDE_INT *load_offset, bool check_regs)
-{
- int unsorted_regs[MAX_LDM_STM_OPS];
- rtx unsorted_reg_rtxs[MAX_LDM_STM_OPS];
- HOST_WIDE_INT unsorted_offsets[MAX_LDM_STM_OPS];
- int order[MAX_LDM_STM_OPS];
- int base_reg = -1;
- rtx base_reg_rtx = NULL;
- int i, stm_case;
-
- /* Write back of base register is currently only supported for Thumb 1. */
- int base_writeback = TARGET_THUMB1;
-
- /* Can only handle up to MAX_LDM_STM_OPS insns at present, though could be
- easily extended if required. */
- gcc_assert (nops >= 2 && nops <= MAX_LDM_STM_OPS);
-
- memset (order, 0, MAX_LDM_STM_OPS * sizeof (int));
-
- /* Loop over the operands and check that the memory references are
- suitable (i.e. immediate offsets from the same base register). At
- the same time, extract the target register, and the memory
- offsets. */
- for (i = 0; i < nops; i++)
- {
- rtx reg;
- rtx offset;
-
- /* Convert a subreg of a mem into the mem itself. */
- if (GET_CODE (operands[nops + i]) == SUBREG)
- operands[nops + i] = alter_subreg (operands + (nops + i), true);
-
- gcc_assert (MEM_P (operands[nops + i]));
-
- /* Don't reorder volatile memory references; it doesn't seem worth
- looking for the case where the order is ok anyway. */
- if (MEM_VOLATILE_P (operands[nops + i]))
- return 0;
-
- offset = const0_rtx;
-
- if ((REG_P (reg = XEXP (operands[nops + i], 0))
- || (GET_CODE (reg) == SUBREG
- && REG_P (reg = SUBREG_REG (reg))))
- || (GET_CODE (XEXP (operands[nops + i], 0)) == PLUS
- && ((REG_P (reg = XEXP (XEXP (operands[nops + i], 0), 0)))
- || (GET_CODE (reg) == SUBREG
- && REG_P (reg = SUBREG_REG (reg))))
- && (CONST_INT_P (offset
- = XEXP (XEXP (operands[nops + i], 0), 1)))))
- {
- unsorted_reg_rtxs[i] = (REG_P (operands[i])
- ? operands[i] : SUBREG_REG (operands[i]));
- unsorted_regs[i] = REGNO (unsorted_reg_rtxs[i]);
-
- if (i == 0)
- {
- base_reg = REGNO (reg);
- base_reg_rtx = reg;
- if (TARGET_THUMB1 && base_reg > LAST_LO_REGNUM)
- return 0;
- }
- else if (base_reg != (int) REGNO (reg))
- /* Not addressed from the same base register. */
- return 0;
-
- /* If it isn't an integer register, then we can't do this. */
- if (unsorted_regs[i] < 0
- || (TARGET_THUMB1 && unsorted_regs[i] > LAST_LO_REGNUM)
- /* The effects are unpredictable if the base register is
- both updated and stored. */
- || (base_writeback && unsorted_regs[i] == base_reg)
- || (TARGET_THUMB2 && unsorted_regs[i] == SP_REGNUM)
- || unsorted_regs[i] > 14)
- return 0;
-
- unsorted_offsets[i] = INTVAL (offset);
- if (i == 0 || unsorted_offsets[i] < unsorted_offsets[order[0]])
- order[0] = i;
- }
- else
- /* Not a suitable memory address. */
- return 0;
- }
-
- /* All the useful information has now been extracted from the
- operands into unsorted_regs and unsorted_offsets; additionally,
- order[0] has been set to the lowest offset in the list. Sort
- the offsets into order, verifying that they are adjacent, and
- check that the register numbers are ascending. */
- if (!compute_offset_order (nops, unsorted_offsets, order,
- check_regs ? unsorted_regs : NULL))
- return 0;
-
- if (saved_order)
- memcpy (saved_order, order, sizeof order);
-
- if (base)
- {
- *base = base_reg;
-
- for (i = 0; i < nops; i++)
- {
- regs[i] = unsorted_regs[check_regs ? order[i] : i];
- if (reg_rtxs)
- reg_rtxs[i] = unsorted_reg_rtxs[check_regs ? order[i] : i];
- }
-
- *load_offset = unsorted_offsets[order[0]];
- }
-
- if (TARGET_THUMB1
- && !peep2_reg_dead_p (nops_total, base_reg_rtx))
- return 0;
-
- if (unsorted_offsets[order[0]] == 0)
- stm_case = 1; /* stmia */
- else if (TARGET_ARM && unsorted_offsets[order[0]] == 4)
- stm_case = 2; /* stmib */
- else if (TARGET_ARM && unsorted_offsets[order[nops - 1]] == 0)
- stm_case = 3; /* stmda */
- else if (TARGET_32BIT && unsorted_offsets[order[nops - 1]] == -4)
- stm_case = 4; /* stmdb */
- else
- return 0;
-
- if (!multiple_operation_profitable_p (false, nops, 0))
- return 0;
-
- return stm_case;
-}
-
-/* Routines for use in generating RTL. */
-
-/* Generate a load-multiple instruction. COUNT is the number of loads in
- the instruction; REGS and MEMS are arrays containing the operands.
- BASEREG is the base register to be used in addressing the memory operands.
- WBACK_OFFSET is nonzero if the instruction should update the base
- register. */
-
-static rtx
-arm_gen_load_multiple_1 (int count, int *regs, rtx *mems, rtx basereg,
- HOST_WIDE_INT wback_offset)
-{
- int i = 0, j;
- rtx result;
-
- if (!multiple_operation_profitable_p (false, count, 0))
- {
- rtx seq;
-
- start_sequence ();
-
- for (i = 0; i < count; i++)
- emit_move_insn (gen_rtx_REG (SImode, regs[i]), mems[i]);
-
- if (wback_offset != 0)
- emit_move_insn (basereg, plus_constant (Pmode, basereg, wback_offset));
-
- seq = get_insns ();
- end_sequence ();
-
- return seq;
- }
-
- result = gen_rtx_PARALLEL (VOIDmode,
- rtvec_alloc (count + (wback_offset != 0 ? 1 : 0)));
- if (wback_offset != 0)
- {
- XVECEXP (result, 0, 0)
- = gen_rtx_SET (VOIDmode, basereg,
- plus_constant (Pmode, basereg, wback_offset));
- i = 1;
- count++;
- }
-
- for (j = 0; i < count; i++, j++)
- XVECEXP (result, 0, i)
- = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, regs[j]), mems[j]);
-
- return result;
-}
-
-/* Generate a store-multiple instruction. COUNT is the number of stores in
- the instruction; REGS and MEMS are arrays containing the operands.
- BASEREG is the base register to be used in addressing the memory operands.
- WBACK_OFFSET is nonzero if the instruction should update the base
- register. */
-
-static rtx
-arm_gen_store_multiple_1 (int count, int *regs, rtx *mems, rtx basereg,
- HOST_WIDE_INT wback_offset)
-{
- int i = 0, j;
- rtx result;
-
- if (GET_CODE (basereg) == PLUS)
- basereg = XEXP (basereg, 0);
-
- if (!multiple_operation_profitable_p (false, count, 0))
- {
- rtx seq;
-
- start_sequence ();
-
- for (i = 0; i < count; i++)
- emit_move_insn (mems[i], gen_rtx_REG (SImode, regs[i]));
-
- if (wback_offset != 0)
- emit_move_insn (basereg, plus_constant (Pmode, basereg, wback_offset));
-
- seq = get_insns ();
- end_sequence ();
-
- return seq;
- }
-
- result = gen_rtx_PARALLEL (VOIDmode,
- rtvec_alloc (count + (wback_offset != 0 ? 1 : 0)));
- if (wback_offset != 0)
- {
- XVECEXP (result, 0, 0)
- = gen_rtx_SET (VOIDmode, basereg,
- plus_constant (Pmode, basereg, wback_offset));
- i = 1;
- count++;
- }
-
- for (j = 0; i < count; i++, j++)
- XVECEXP (result, 0, i)
- = gen_rtx_SET (VOIDmode, mems[j], gen_rtx_REG (SImode, regs[j]));
-
- return result;
-}
-
-/* Generate either a load-multiple or a store-multiple instruction. This
- function can be used in situations where we can start with a single MEM
- rtx and adjust its address upwards.
- COUNT is the number of operations in the instruction, not counting a
- possible update of the base register. REGS is an array containing the
- register operands.
- BASEREG is the base register to be used in addressing the memory operands,
- which are constructed from BASEMEM.
- WRITE_BACK specifies whether the generated instruction should include an
- update of the base register.
- OFFSETP is used to pass an offset to and from this function; this offset
- is not used when constructing the address (instead BASEMEM should have an
- appropriate offset in its address), it is used only for setting
- MEM_OFFSET. It is updated only if WRITE_BACK is true.*/
-
-static rtx
-arm_gen_multiple_op (bool is_load, int *regs, int count, rtx basereg,
- bool write_back, rtx basemem, HOST_WIDE_INT *offsetp)
-{
- rtx mems[MAX_LDM_STM_OPS];
- HOST_WIDE_INT offset = *offsetp;
- int i;
-
- gcc_assert (count <= MAX_LDM_STM_OPS);
-
- if (GET_CODE (basereg) == PLUS)
- basereg = XEXP (basereg, 0);
-
- for (i = 0; i < count; i++)
- {
- rtx addr = plus_constant (Pmode, basereg, i * 4);
- mems[i] = adjust_automodify_address_nv (basemem, SImode, addr, offset);
- offset += 4;
- }
-
- if (write_back)
- *offsetp = offset;
-
- if (is_load)
- return arm_gen_load_multiple_1 (count, regs, mems, basereg,
- write_back ? 4 * count : 0);
- else
- return arm_gen_store_multiple_1 (count, regs, mems, basereg,
- write_back ? 4 * count : 0);
-}
-
-rtx
-arm_gen_load_multiple (int *regs, int count, rtx basereg, int write_back,
- rtx basemem, HOST_WIDE_INT *offsetp)
-{
- return arm_gen_multiple_op (TRUE, regs, count, basereg, write_back, basemem,
- offsetp);
-}
-
-rtx
-arm_gen_store_multiple (int *regs, int count, rtx basereg, int write_back,
- rtx basemem, HOST_WIDE_INT *offsetp)
-{
- return arm_gen_multiple_op (FALSE, regs, count, basereg, write_back, basemem,
- offsetp);
-}
-
-/* Called from a peephole2 expander to turn a sequence of loads into an
- LDM instruction. OPERANDS are the operands found by the peephole matcher;
- NOPS indicates how many separate loads we are trying to combine. SORT_REGS
- is true if we can reorder the registers because they are used commutatively
- subsequently.
- Returns true iff we could generate a new instruction. */
-
-bool
-gen_ldm_seq (rtx *operands, int nops, bool sort_regs)
-{
- int regs[MAX_LDM_STM_OPS], mem_order[MAX_LDM_STM_OPS];
- rtx mems[MAX_LDM_STM_OPS];
- int i, j, base_reg;
- rtx base_reg_rtx;
- HOST_WIDE_INT offset;
- int write_back = FALSE;
- int ldm_case;
- rtx addr;
-
- ldm_case = load_multiple_sequence (operands, nops, regs, mem_order,
- &base_reg, &offset, !sort_regs);
-
- if (ldm_case == 0)
- return false;
-
- if (sort_regs)
- for (i = 0; i < nops - 1; i++)
- for (j = i + 1; j < nops; j++)
- if (regs[i] > regs[j])
- {
- int t = regs[i];
- regs[i] = regs[j];
- regs[j] = t;
- }
- base_reg_rtx = gen_rtx_REG (Pmode, base_reg);
-
- if (TARGET_THUMB1)
- {
- gcc_assert (peep2_reg_dead_p (nops, base_reg_rtx));
- gcc_assert (ldm_case == 1 || ldm_case == 5);
- write_back = TRUE;
- }
-
- if (ldm_case == 5)
- {
- rtx newbase = TARGET_THUMB1 ? base_reg_rtx : gen_rtx_REG (SImode, regs[0]);
- emit_insn (gen_addsi3 (newbase, base_reg_rtx, GEN_INT (offset)));
- offset = 0;
- if (!TARGET_THUMB1)
- {
- base_reg = regs[0];
- base_reg_rtx = newbase;
- }
- }
-
- for (i = 0; i < nops; i++)
- {
- addr = plus_constant (Pmode, base_reg_rtx, offset + i * 4);
- mems[i] = adjust_automodify_address_nv (operands[nops + mem_order[i]],
- SImode, addr, 0);
- }
- emit_insn (arm_gen_load_multiple_1 (nops, regs, mems, base_reg_rtx,
- write_back ? offset + i * 4 : 0));
- return true;
-}
-
-/* Called from a peephole2 expander to turn a sequence of stores into an
- STM instruction. OPERANDS are the operands found by the peephole matcher;
- NOPS indicates how many separate stores we are trying to combine.
- Returns true iff we could generate a new instruction. */
-
-bool
-gen_stm_seq (rtx *operands, int nops)
-{
- int i;
- int regs[MAX_LDM_STM_OPS], mem_order[MAX_LDM_STM_OPS];
- rtx mems[MAX_LDM_STM_OPS];
- int base_reg;
- rtx base_reg_rtx;
- HOST_WIDE_INT offset;
- int write_back = FALSE;
- int stm_case;
- rtx addr;
- bool base_reg_dies;
-
- stm_case = store_multiple_sequence (operands, nops, nops, regs, NULL,
- mem_order, &base_reg, &offset, true);
-
- if (stm_case == 0)
- return false;
-
- base_reg_rtx = gen_rtx_REG (Pmode, base_reg);
-
- base_reg_dies = peep2_reg_dead_p (nops, base_reg_rtx);
- if (TARGET_THUMB1)
- {
- gcc_assert (base_reg_dies);
- write_back = TRUE;
- }
-
- if (stm_case == 5)
- {
- gcc_assert (base_reg_dies);
- emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, GEN_INT (offset)));
- offset = 0;
- }
-
- addr = plus_constant (Pmode, base_reg_rtx, offset);
-
- for (i = 0; i < nops; i++)
- {
- addr = plus_constant (Pmode, base_reg_rtx, offset + i * 4);
- mems[i] = adjust_automodify_address_nv (operands[nops + mem_order[i]],
- SImode, addr, 0);
- }
- emit_insn (arm_gen_store_multiple_1 (nops, regs, mems, base_reg_rtx,
- write_back ? offset + i * 4 : 0));
- return true;
-}
-
-/* Called from a peephole2 expander to turn a sequence of stores that are
- preceded by constant loads into an STM instruction. OPERANDS are the
- operands found by the peephole matcher; NOPS indicates how many
- separate stores we are trying to combine; there are 2 * NOPS
- instructions in the peephole.
- Returns true iff we could generate a new instruction. */
-
-bool
-gen_const_stm_seq (rtx *operands, int nops)
-{
- int regs[MAX_LDM_STM_OPS], sorted_regs[MAX_LDM_STM_OPS];
- int reg_order[MAX_LDM_STM_OPS], mem_order[MAX_LDM_STM_OPS];
- rtx reg_rtxs[MAX_LDM_STM_OPS], orig_reg_rtxs[MAX_LDM_STM_OPS];
- rtx mems[MAX_LDM_STM_OPS];
- int base_reg;
- rtx base_reg_rtx;
- HOST_WIDE_INT offset;
- int write_back = FALSE;
- int stm_case;
- rtx addr;
- bool base_reg_dies;
- int i, j;
- HARD_REG_SET allocated;
-
- stm_case = store_multiple_sequence (operands, nops, 2 * nops, regs, reg_rtxs,
- mem_order, &base_reg, &offset, false);
-
- if (stm_case == 0)
- return false;
-
- memcpy (orig_reg_rtxs, reg_rtxs, sizeof orig_reg_rtxs);
-
- /* If the same register is used more than once, try to find a free
- register. */
- CLEAR_HARD_REG_SET (allocated);
- for (i = 0; i < nops; i++)
- {
- for (j = i + 1; j < nops; j++)
- if (regs[i] == regs[j])
- {
- rtx t = peep2_find_free_register (0, nops * 2,
- TARGET_THUMB1 ? "l" : "r",
- SImode, &allocated);
- if (t == NULL_RTX)
- return false;
- reg_rtxs[i] = t;
- regs[i] = REGNO (t);
- }
- }
-
- /* Compute an ordering that maps the register numbers to an ascending
- sequence. */
- reg_order[0] = 0;
- for (i = 0; i < nops; i++)
- if (regs[i] < regs[reg_order[0]])
- reg_order[0] = i;
-
- for (i = 1; i < nops; i++)
- {
- int this_order = reg_order[i - 1];
- for (j = 0; j < nops; j++)
- if (regs[j] > regs[reg_order[i - 1]]
- && (this_order == reg_order[i - 1]
- || regs[j] < regs[this_order]))
- this_order = j;
- reg_order[i] = this_order;
- }
-
- /* Ensure that registers that must be live after the instruction end
- up with the correct value. */
- for (i = 0; i < nops; i++)
- {
- int this_order = reg_order[i];
- if ((this_order != mem_order[i]
- || orig_reg_rtxs[this_order] != reg_rtxs[this_order])
- && !peep2_reg_dead_p (nops * 2, orig_reg_rtxs[this_order]))
- return false;
- }
-
- /* Load the constants. */
- for (i = 0; i < nops; i++)
- {
- rtx op = operands[2 * nops + mem_order[i]];
- sorted_regs[i] = regs[reg_order[i]];
- emit_move_insn (reg_rtxs[reg_order[i]], op);
- }
-
- base_reg_rtx = gen_rtx_REG (Pmode, base_reg);
-
- base_reg_dies = peep2_reg_dead_p (nops * 2, base_reg_rtx);
- if (TARGET_THUMB1)
- {
- gcc_assert (base_reg_dies);
- write_back = TRUE;
- }
-
- if (stm_case == 5)
- {
- gcc_assert (base_reg_dies);
- emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, GEN_INT (offset)));
- offset = 0;
- }
-
- addr = plus_constant (Pmode, base_reg_rtx, offset);
-
- for (i = 0; i < nops; i++)
- {
- addr = plus_constant (Pmode, base_reg_rtx, offset + i * 4);
- mems[i] = adjust_automodify_address_nv (operands[nops + mem_order[i]],
- SImode, addr, 0);
- }
- emit_insn (arm_gen_store_multiple_1 (nops, sorted_regs, mems, base_reg_rtx,
- write_back ? offset + i * 4 : 0));
- return true;
-}
-
-/* Copy a block of memory using plain ldr/str/ldrh/strh instructions, to permit
- unaligned copies on processors which support unaligned semantics for those
- instructions. INTERLEAVE_FACTOR can be used to attempt to hide load latency
- (using more registers) by doing e.g. load/load/store/store for a factor of 2.
- An interleave factor of 1 (the minimum) will perform no interleaving.
- Load/store multiple are used for aligned addresses where possible. */
-
-static void
-arm_block_move_unaligned_straight (rtx dstbase, rtx srcbase,
- HOST_WIDE_INT length,
- unsigned int interleave_factor)
-{
- rtx *regs = XALLOCAVEC (rtx, interleave_factor);
- int *regnos = XALLOCAVEC (int, interleave_factor);
- HOST_WIDE_INT block_size_bytes = interleave_factor * UNITS_PER_WORD;
- HOST_WIDE_INT i, j;
- HOST_WIDE_INT remaining = length, words;
- rtx halfword_tmp = NULL, byte_tmp = NULL;
- rtx dst, src;
- bool src_aligned = MEM_ALIGN (srcbase) >= BITS_PER_WORD;
- bool dst_aligned = MEM_ALIGN (dstbase) >= BITS_PER_WORD;
- HOST_WIDE_INT srcoffset, dstoffset;
- HOST_WIDE_INT src_autoinc, dst_autoinc;
- rtx mem, addr;
-
- gcc_assert (1 <= interleave_factor && interleave_factor <= 4);
-
- /* Use hard registers if we have aligned source or destination so we can use
- load/store multiple with contiguous registers. */
- if (dst_aligned || src_aligned)
- for (i = 0; i < interleave_factor; i++)
- regs[i] = gen_rtx_REG (SImode, i);
- else
- for (i = 0; i < interleave_factor; i++)
- regs[i] = gen_reg_rtx (SImode);
-
- dst = copy_addr_to_reg (XEXP (dstbase, 0));
- src = copy_addr_to_reg (XEXP (srcbase, 0));
-
- srcoffset = dstoffset = 0;
-
- /* Calls to arm_gen_load_multiple and arm_gen_store_multiple update SRC/DST.
- For copying the last bytes we want to subtract this offset again. */
- src_autoinc = dst_autoinc = 0;
-
- for (i = 0; i < interleave_factor; i++)
- regnos[i] = i;
-
- /* Copy BLOCK_SIZE_BYTES chunks. */
-
- for (i = 0; i + block_size_bytes <= length; i += block_size_bytes)
- {
- /* Load words. */
- if (src_aligned && interleave_factor > 1)
- {
- emit_insn (arm_gen_load_multiple (regnos, interleave_factor, src,
- TRUE, srcbase, &srcoffset));
- src_autoinc += UNITS_PER_WORD * interleave_factor;
- }
- else
- {
- for (j = 0; j < interleave_factor; j++)
- {
- addr = plus_constant (Pmode, src, (srcoffset + j * UNITS_PER_WORD
- - src_autoinc));
- mem = adjust_automodify_address (srcbase, SImode, addr,
- srcoffset + j * UNITS_PER_WORD);
- emit_insn (gen_unaligned_loadsi (regs[j], mem));
- }
- srcoffset += block_size_bytes;
- }
-
- /* Store words. */
- if (dst_aligned && interleave_factor > 1)
- {
- emit_insn (arm_gen_store_multiple (regnos, interleave_factor, dst,
- TRUE, dstbase, &dstoffset));
- dst_autoinc += UNITS_PER_WORD * interleave_factor;
- }
- else
- {
- for (j = 0; j < interleave_factor; j++)
- {
- addr = plus_constant (Pmode, dst, (dstoffset + j * UNITS_PER_WORD
- - dst_autoinc));
- mem = adjust_automodify_address (dstbase, SImode, addr,
- dstoffset + j * UNITS_PER_WORD);
- emit_insn (gen_unaligned_storesi (mem, regs[j]));
- }
- dstoffset += block_size_bytes;
- }
-
- remaining -= block_size_bytes;
- }
-
- /* Copy any whole words left (note these aren't interleaved with any
- subsequent halfword/byte load/stores in the interests of simplicity). */
-
- words = remaining / UNITS_PER_WORD;
-
- gcc_assert (words < interleave_factor);
-
- if (src_aligned && words > 1)
- {
- emit_insn (arm_gen_load_multiple (regnos, words, src, TRUE, srcbase,
- &srcoffset));
- src_autoinc += UNITS_PER_WORD * words;
- }
- else
- {
- for (j = 0; j < words; j++)
- {
- addr = plus_constant (Pmode, src,
- srcoffset + j * UNITS_PER_WORD - src_autoinc);
- mem = adjust_automodify_address (srcbase, SImode, addr,
- srcoffset + j * UNITS_PER_WORD);
- emit_insn (gen_unaligned_loadsi (regs[j], mem));
- }
- srcoffset += words * UNITS_PER_WORD;
- }
-
- if (dst_aligned && words > 1)
- {
- emit_insn (arm_gen_store_multiple (regnos, words, dst, TRUE, dstbase,
- &dstoffset));
- dst_autoinc += words * UNITS_PER_WORD;
- }
- else
- {
- for (j = 0; j < words; j++)
- {
- addr = plus_constant (Pmode, dst,
- dstoffset + j * UNITS_PER_WORD - dst_autoinc);
- mem = adjust_automodify_address (dstbase, SImode, addr,
- dstoffset + j * UNITS_PER_WORD);
- emit_insn (gen_unaligned_storesi (mem, regs[j]));
- }
- dstoffset += words * UNITS_PER_WORD;
- }
-
- remaining -= words * UNITS_PER_WORD;
-
- gcc_assert (remaining < 4);
-
- /* Copy a halfword if necessary. */
-
- if (remaining >= 2)
- {
- halfword_tmp = gen_reg_rtx (SImode);
-
- addr = plus_constant (Pmode, src, srcoffset - src_autoinc);
- mem = adjust_automodify_address (srcbase, HImode, addr, srcoffset);
- emit_insn (gen_unaligned_loadhiu (halfword_tmp, mem));
-
- /* Either write out immediately, or delay until we've loaded the last
- byte, depending on interleave factor. */
- if (interleave_factor == 1)
- {
- addr = plus_constant (Pmode, dst, dstoffset - dst_autoinc);
- mem = adjust_automodify_address (dstbase, HImode, addr, dstoffset);
- emit_insn (gen_unaligned_storehi (mem,
- gen_lowpart (HImode, halfword_tmp)));
- halfword_tmp = NULL;
- dstoffset += 2;
- }
-
- remaining -= 2;
- srcoffset += 2;
- }
-
- gcc_assert (remaining < 2);
-
- /* Copy last byte. */
-
- if ((remaining & 1) != 0)
- {
- byte_tmp = gen_reg_rtx (SImode);
-
- addr = plus_constant (Pmode, src, srcoffset - src_autoinc);
- mem = adjust_automodify_address (srcbase, QImode, addr, srcoffset);
- emit_move_insn (gen_lowpart (QImode, byte_tmp), mem);
-
- if (interleave_factor == 1)
- {
- addr = plus_constant (Pmode, dst, dstoffset - dst_autoinc);
- mem = adjust_automodify_address (dstbase, QImode, addr, dstoffset);
- emit_move_insn (mem, gen_lowpart (QImode, byte_tmp));
- byte_tmp = NULL;
- dstoffset++;
- }
-
- remaining--;
- srcoffset++;
- }
-
- /* Store last halfword if we haven't done so already. */
-
- if (halfword_tmp)
- {
- addr = plus_constant (Pmode, dst, dstoffset - dst_autoinc);
- mem = adjust_automodify_address (dstbase, HImode, addr, dstoffset);
- emit_insn (gen_unaligned_storehi (mem,
- gen_lowpart (HImode, halfword_tmp)));
- dstoffset += 2;
- }
-
- /* Likewise for last byte. */
-
- if (byte_tmp)
- {
- addr = plus_constant (Pmode, dst, dstoffset - dst_autoinc);
- mem = adjust_automodify_address (dstbase, QImode, addr, dstoffset);
- emit_move_insn (mem, gen_lowpart (QImode, byte_tmp));
- dstoffset++;
- }
-
- gcc_assert (remaining == 0 && srcoffset == dstoffset);
-}
-
-/* From mips_adjust_block_mem:
-
- Helper function for doing a loop-based block operation on memory
- reference MEM. Each iteration of the loop will operate on LENGTH
- bytes of MEM.
-
- Create a new base register for use within the loop and point it to
- the start of MEM. Create a new memory reference that uses this
- register. Store them in *LOOP_REG and *LOOP_MEM respectively. */
-
-static void
-arm_adjust_block_mem (rtx mem, HOST_WIDE_INT length, rtx *loop_reg,
- rtx *loop_mem)
-{
- *loop_reg = copy_addr_to_reg (XEXP (mem, 0));
-
- /* Although the new mem does not refer to a known location,
- it does keep up to LENGTH bytes of alignment. */
- *loop_mem = change_address (mem, BLKmode, *loop_reg);
- set_mem_align (*loop_mem, MIN (MEM_ALIGN (mem), length * BITS_PER_UNIT));
-}
-
-/* From mips_block_move_loop:
-
- Move LENGTH bytes from SRC to DEST using a loop that moves BYTES_PER_ITER
- bytes at a time. LENGTH must be at least BYTES_PER_ITER. Assume that
- the memory regions do not overlap. */
-
-static void
-arm_block_move_unaligned_loop (rtx dest, rtx src, HOST_WIDE_INT length,
- unsigned int interleave_factor,
- HOST_WIDE_INT bytes_per_iter)
-{
- rtx label, src_reg, dest_reg, final_src, test;
- HOST_WIDE_INT leftover;
-
- leftover = length % bytes_per_iter;
- length -= leftover;
-
- /* Create registers and memory references for use within the loop. */
- arm_adjust_block_mem (src, bytes_per_iter, &src_reg, &src);
- arm_adjust_block_mem (dest, bytes_per_iter, &dest_reg, &dest);
-
- /* Calculate the value that SRC_REG should have after the last iteration of
- the loop. */
- final_src = expand_simple_binop (Pmode, PLUS, src_reg, GEN_INT (length),
- 0, 0, OPTAB_WIDEN);
-
- /* Emit the start of the loop. */
- label = gen_label_rtx ();
- emit_label (label);
-
- /* Emit the loop body. */
- arm_block_move_unaligned_straight (dest, src, bytes_per_iter,
- interleave_factor);
-
- /* Move on to the next block. */
- emit_move_insn (src_reg, plus_constant (Pmode, src_reg, bytes_per_iter));
- emit_move_insn (dest_reg, plus_constant (Pmode, dest_reg, bytes_per_iter));
-
- /* Emit the loop condition. */
- test = gen_rtx_NE (VOIDmode, src_reg, final_src);
- emit_jump_insn (gen_cbranchsi4 (test, src_reg, final_src, label));
-
- /* Mop up any left-over bytes. */
- if (leftover)
- arm_block_move_unaligned_straight (dest, src, leftover, interleave_factor);
-}
-
-/* Emit a block move when either the source or destination is unaligned (not
- aligned to a four-byte boundary). This may need further tuning depending on
- core type, optimize_size setting, etc. */
-
-static int
-arm_movmemqi_unaligned (rtx *operands)
-{
- HOST_WIDE_INT length = INTVAL (operands[2]);
-
- if (optimize_size)
- {
- bool src_aligned = MEM_ALIGN (operands[1]) >= BITS_PER_WORD;
- bool dst_aligned = MEM_ALIGN (operands[0]) >= BITS_PER_WORD;
- /* Inlined memcpy using ldr/str/ldrh/strh can be quite big: try to limit
- size of code if optimizing for size. We'll use ldm/stm if src_aligned
- or dst_aligned though: allow more interleaving in those cases since the
- resulting code can be smaller. */
- unsigned int interleave_factor = (src_aligned || dst_aligned) ? 2 : 1;
- HOST_WIDE_INT bytes_per_iter = (src_aligned || dst_aligned) ? 8 : 4;
-
- if (length > 12)
- arm_block_move_unaligned_loop (operands[0], operands[1], length,
- interleave_factor, bytes_per_iter);
- else
- arm_block_move_unaligned_straight (operands[0], operands[1], length,
- interleave_factor);
- }
- else
- {
- /* Note that the loop created by arm_block_move_unaligned_loop may be
- subject to loop unrolling, which makes tuning this condition a little
- redundant. */
- if (length > 32)
- arm_block_move_unaligned_loop (operands[0], operands[1], length, 4, 16);
- else
- arm_block_move_unaligned_straight (operands[0], operands[1], length, 4);
- }
-
- return 1;
-}
-
-int
-arm_gen_movmemqi (rtx *operands)
-{
- HOST_WIDE_INT in_words_to_go, out_words_to_go, last_bytes;
- HOST_WIDE_INT srcoffset, dstoffset;
- int i;
- rtx src, dst, srcbase, dstbase;
- rtx part_bytes_reg = NULL;
- rtx mem;
-
- if (!CONST_INT_P (operands[2])
- || !CONST_INT_P (operands[3])
- || INTVAL (operands[2]) > 64)
- return 0;
-
- if (unaligned_access && (INTVAL (operands[3]) & 3) != 0)
- return arm_movmemqi_unaligned (operands);
-
- if (INTVAL (operands[3]) & 3)
- return 0;
-
- dstbase = operands[0];
- srcbase = operands[1];
-
- dst = copy_to_mode_reg (SImode, XEXP (dstbase, 0));
- src = copy_to_mode_reg (SImode, XEXP (srcbase, 0));
-
- in_words_to_go = ARM_NUM_INTS (INTVAL (operands[2]));
- out_words_to_go = INTVAL (operands[2]) / 4;
- last_bytes = INTVAL (operands[2]) & 3;
- dstoffset = srcoffset = 0;
-
- if (out_words_to_go != in_words_to_go && ((in_words_to_go - 1) & 3) != 0)
- part_bytes_reg = gen_rtx_REG (SImode, (in_words_to_go - 1) & 3);
-
- for (i = 0; in_words_to_go >= 2; i+=4)
- {
- if (in_words_to_go > 4)
- emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, src,
- TRUE, srcbase, &srcoffset));
- else
- emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, in_words_to_go,
- src, FALSE, srcbase,
- &srcoffset));
-
- if (out_words_to_go)
- {
- if (out_words_to_go > 4)
- emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, dst,
- TRUE, dstbase, &dstoffset));
- else if (out_words_to_go != 1)
- emit_insn (arm_gen_store_multiple (arm_regs_in_sequence,
- out_words_to_go, dst,
- (last_bytes == 0
- ? FALSE : TRUE),
- dstbase, &dstoffset));
- else
- {
- mem = adjust_automodify_address (dstbase, SImode, dst, dstoffset);
- emit_move_insn (mem, gen_rtx_REG (SImode, 0));
- if (last_bytes != 0)
- {
- emit_insn (gen_addsi3 (dst, dst, GEN_INT (4)));
- dstoffset += 4;
- }
- }
- }
-
- in_words_to_go -= in_words_to_go < 4 ? in_words_to_go : 4;
- out_words_to_go -= out_words_to_go < 4 ? out_words_to_go : 4;
- }
-
- /* OUT_WORDS_TO_GO will be zero here if there are byte stores to do. */
- if (out_words_to_go)
- {
- rtx sreg;
-
- mem = adjust_automodify_address (srcbase, SImode, src, srcoffset);
- sreg = copy_to_reg (mem);
-
- mem = adjust_automodify_address (dstbase, SImode, dst, dstoffset);
- emit_move_insn (mem, sreg);
- in_words_to_go--;
-
- gcc_assert (!in_words_to_go); /* Sanity check */
- }
-
- if (in_words_to_go)
- {
- gcc_assert (in_words_to_go > 0);
-
- mem = adjust_automodify_address (srcbase, SImode, src, srcoffset);
- part_bytes_reg = copy_to_mode_reg (SImode, mem);
- }
-
- gcc_assert (!last_bytes || part_bytes_reg);
-
- if (BYTES_BIG_ENDIAN && last_bytes)
- {
- rtx tmp = gen_reg_rtx (SImode);
-
- /* The bytes we want are in the top end of the word. */
- emit_insn (gen_lshrsi3 (tmp, part_bytes_reg,
- GEN_INT (8 * (4 - last_bytes))));
- part_bytes_reg = tmp;
-
- while (last_bytes)
- {
- mem = adjust_automodify_address (dstbase, QImode,
- plus_constant (Pmode, dst,
- last_bytes - 1),
- dstoffset + last_bytes - 1);
- emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg));
-
- if (--last_bytes)
- {
- tmp = gen_reg_rtx (SImode);
- emit_insn (gen_lshrsi3 (tmp, part_bytes_reg, GEN_INT (8)));
- part_bytes_reg = tmp;
- }
- }
-
- }
- else
- {
- if (last_bytes > 1)
- {
- mem = adjust_automodify_address (dstbase, HImode, dst, dstoffset);
- emit_move_insn (mem, gen_lowpart (HImode, part_bytes_reg));
- last_bytes -= 2;
- if (last_bytes)
- {
- rtx tmp = gen_reg_rtx (SImode);
- emit_insn (gen_addsi3 (dst, dst, const2_rtx));
- emit_insn (gen_lshrsi3 (tmp, part_bytes_reg, GEN_INT (16)));
- part_bytes_reg = tmp;
- dstoffset += 2;
- }
- }
-
- if (last_bytes)
- {
- mem = adjust_automodify_address (dstbase, QImode, dst, dstoffset);
- emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg));
- }
- }
-
- return 1;
-}
-
-/* Select a dominance comparison mode if possible for a test of the general
- form (OP (COND_OR (X) (Y)) (const_int 0)). We support three forms.
- COND_OR == DOM_CC_X_AND_Y => (X && Y)
- COND_OR == DOM_CC_NX_OR_Y => ((! X) || Y)
- COND_OR == DOM_CC_X_OR_Y => (X || Y)
- In all cases OP will be either EQ or NE, but we don't need to know which
- here. If we are unable to support a dominance comparison we return
- CC mode. This will then fail to match for the RTL expressions that
- generate this call. */
-enum machine_mode
-arm_select_dominance_cc_mode (rtx x, rtx y, HOST_WIDE_INT cond_or)
-{
- enum rtx_code cond1, cond2;
- int swapped = 0;
-
- /* Currently we will probably get the wrong result if the individual
- comparisons are not simple. This also ensures that it is safe to
- reverse a comparison if necessary. */
- if ((arm_select_cc_mode (cond1 = GET_CODE (x), XEXP (x, 0), XEXP (x, 1))
- != CCmode)
- || (arm_select_cc_mode (cond2 = GET_CODE (y), XEXP (y, 0), XEXP (y, 1))
- != CCmode))
- return CCmode;
-
- /* The if_then_else variant of this tests the second condition if the
- first passes, but is true if the first fails. Reverse the first
- condition to get a true "inclusive-or" expression. */
- if (cond_or == DOM_CC_NX_OR_Y)
- cond1 = reverse_condition (cond1);
-
- /* If the comparisons are not equal, and one doesn't dominate the other,
- then we can't do this. */
- if (cond1 != cond2
- && !comparison_dominates_p (cond1, cond2)
- && (swapped = 1, !comparison_dominates_p (cond2, cond1)))
- return CCmode;
-
- if (swapped)
- {
- enum rtx_code temp = cond1;
- cond1 = cond2;
- cond2 = temp;
- }
-
- switch (cond1)
- {
- case EQ:
- if (cond_or == DOM_CC_X_AND_Y)
- return CC_DEQmode;
-
- switch (cond2)
- {
- case EQ: return CC_DEQmode;
- case LE: return CC_DLEmode;
- case LEU: return CC_DLEUmode;
- case GE: return CC_DGEmode;
- case GEU: return CC_DGEUmode;
- default: gcc_unreachable ();
- }
-
- case LT:
- if (cond_or == DOM_CC_X_AND_Y)
- return CC_DLTmode;
-
- switch (cond2)
- {
- case LT:
- return CC_DLTmode;
- case LE:
- return CC_DLEmode;
- case NE:
- return CC_DNEmode;
- default:
- gcc_unreachable ();
- }
-
- case GT:
- if (cond_or == DOM_CC_X_AND_Y)
- return CC_DGTmode;
-
- switch (cond2)
- {
- case GT:
- return CC_DGTmode;
- case GE:
- return CC_DGEmode;
- case NE:
- return CC_DNEmode;
- default:
- gcc_unreachable ();
- }
-
- case LTU:
- if (cond_or == DOM_CC_X_AND_Y)
- return CC_DLTUmode;
-
- switch (cond2)
- {
- case LTU:
- return CC_DLTUmode;
- case LEU:
- return CC_DLEUmode;
- case NE:
- return CC_DNEmode;
- default:
- gcc_unreachable ();
- }
-
- case GTU:
- if (cond_or == DOM_CC_X_AND_Y)
- return CC_DGTUmode;
-
- switch (cond2)
- {
- case GTU:
- return CC_DGTUmode;
- case GEU:
- return CC_DGEUmode;
- case NE:
- return CC_DNEmode;
- default:
- gcc_unreachable ();
- }
-
- /* The remaining cases only occur when both comparisons are the
- same. */
- case NE:
- gcc_assert (cond1 == cond2);
- return CC_DNEmode;
-
- case LE:
- gcc_assert (cond1 == cond2);
- return CC_DLEmode;
-
- case GE:
- gcc_assert (cond1 == cond2);
- return CC_DGEmode;
-
- case LEU:
- gcc_assert (cond1 == cond2);
- return CC_DLEUmode;
-
- case GEU:
- gcc_assert (cond1 == cond2);
- return CC_DGEUmode;
-
- default:
- gcc_unreachable ();
- }
-}
-
-enum machine_mode
-arm_select_cc_mode (enum rtx_code op, rtx x, rtx y)
-{
- /* All floating point compares return CCFP if it is an equality
- comparison, and CCFPE otherwise. */
- if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
- {
- switch (op)
- {
- case EQ:
- case NE:
- case UNORDERED:
- case ORDERED:
- case UNLT:
- case UNLE:
- case UNGT:
- case UNGE:
- case UNEQ:
- case LTGT:
- return CCFPmode;
-
- case LT:
- case LE:
- case GT:
- case GE:
- return CCFPEmode;
-
- default:
- gcc_unreachable ();
- }
- }
-
- /* A compare with a shifted operand. Because of canonicalization, the
- comparison will have to be swapped when we emit the assembler. */
- if (GET_MODE (y) == SImode
- && (REG_P (y) || (GET_CODE (y) == SUBREG))
- && (GET_CODE (x) == ASHIFT || GET_CODE (x) == ASHIFTRT
- || GET_CODE (x) == LSHIFTRT || GET_CODE (x) == ROTATE
- || GET_CODE (x) == ROTATERT))
- return CC_SWPmode;
-
- /* This operation is performed swapped, but since we only rely on the Z
- flag we don't need an additional mode. */
- if (GET_MODE (y) == SImode
- && (REG_P (y) || (GET_CODE (y) == SUBREG))
- && GET_CODE (x) == NEG
- && (op == EQ || op == NE))
- return CC_Zmode;
-
- /* This is a special case that is used by combine to allow a
- comparison of a shifted byte load to be split into a zero-extend
- followed by a comparison of the shifted integer (only valid for
- equalities and unsigned inequalities). */
- if (GET_MODE (x) == SImode
- && GET_CODE (x) == ASHIFT
- && CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 24
- && GET_CODE (XEXP (x, 0)) == SUBREG
- && MEM_P (SUBREG_REG (XEXP (x, 0)))
- && GET_MODE (SUBREG_REG (XEXP (x, 0))) == QImode
- && (op == EQ || op == NE
- || op == GEU || op == GTU || op == LTU || op == LEU)
- && CONST_INT_P (y))
- return CC_Zmode;
-
- /* A construct for a conditional compare, if the false arm contains
- 0, then both conditions must be true, otherwise either condition
- must be true. Not all conditions are possible, so CCmode is
- returned if it can't be done. */
- if (GET_CODE (x) == IF_THEN_ELSE
- && (XEXP (x, 2) == const0_rtx
- || XEXP (x, 2) == const1_rtx)
- && COMPARISON_P (XEXP (x, 0))
- && COMPARISON_P (XEXP (x, 1)))
- return arm_select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1),
- INTVAL (XEXP (x, 2)));
-
- /* Alternate canonicalizations of the above. These are somewhat cleaner. */
- if (GET_CODE (x) == AND
- && (op == EQ || op == NE)
- && COMPARISON_P (XEXP (x, 0))
- && COMPARISON_P (XEXP (x, 1)))
- return arm_select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1),
- DOM_CC_X_AND_Y);
-
- if (GET_CODE (x) == IOR
- && (op == EQ || op == NE)
- && COMPARISON_P (XEXP (x, 0))
- && COMPARISON_P (XEXP (x, 1)))
- return arm_select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1),
- DOM_CC_X_OR_Y);
-
- /* An operation (on Thumb) where we want to test for a single bit.
- This is done by shifting that bit up into the top bit of a
- scratch register; we can then branch on the sign bit. */
- if (TARGET_THUMB1
- && GET_MODE (x) == SImode
- && (op == EQ || op == NE)
- && GET_CODE (x) == ZERO_EXTRACT
- && XEXP (x, 1) == const1_rtx)
- return CC_Nmode;
-
- /* An operation that sets the condition codes as a side-effect, the
- V flag is not set correctly, so we can only use comparisons where
- this doesn't matter. (For LT and GE we can use "mi" and "pl"
- instead.) */
- /* ??? Does the ZERO_EXTRACT case really apply to thumb2? */
- if (GET_MODE (x) == SImode
- && y == const0_rtx
- && (op == EQ || op == NE || op == LT || op == GE)
- && (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS
- || GET_CODE (x) == AND || GET_CODE (x) == IOR
- || GET_CODE (x) == XOR || GET_CODE (x) == MULT
- || GET_CODE (x) == NOT || GET_CODE (x) == NEG
- || GET_CODE (x) == LSHIFTRT
- || GET_CODE (x) == ASHIFT || GET_CODE (x) == ASHIFTRT
- || GET_CODE (x) == ROTATERT
- || (TARGET_32BIT && GET_CODE (x) == ZERO_EXTRACT)))
- return CC_NOOVmode;
-
- if (GET_MODE (x) == QImode && (op == EQ || op == NE))
- return CC_Zmode;
-
- if (GET_MODE (x) == SImode && (op == LTU || op == GEU)
- && GET_CODE (x) == PLUS
- && (rtx_equal_p (XEXP (x, 0), y) || rtx_equal_p (XEXP (x, 1), y)))
- return CC_Cmode;
-
- if (GET_MODE (x) == DImode || GET_MODE (y) == DImode)
- {
- switch (op)
- {
- case EQ:
- case NE:
- /* A DImode comparison against zero can be implemented by
- or'ing the two halves together. */
- if (y == const0_rtx)
- return CC_Zmode;
-
- /* We can do an equality test in three Thumb instructions. */
- if (!TARGET_32BIT)
- return CC_Zmode;
-
- /* FALLTHROUGH */
-
- case LTU:
- case LEU:
- case GTU:
- case GEU:
- /* DImode unsigned comparisons can be implemented by cmp +
- cmpeq without a scratch register. Not worth doing in
- Thumb-2. */
- if (TARGET_32BIT)
- return CC_CZmode;
-
- /* FALLTHROUGH */
-
- case LT:
- case LE:
- case GT:
- case GE:
- /* DImode signed and unsigned comparisons can be implemented
- by cmp + sbcs with a scratch register, but that does not
- set the Z flag - we must reverse GT/LE/GTU/LEU. */
- gcc_assert (op != EQ && op != NE);
- return CC_NCVmode;
-
- default:
- gcc_unreachable ();
- }
- }
-
- if (GET_MODE_CLASS (GET_MODE (x)) == MODE_CC)
- return GET_MODE (x);
-
- return CCmode;
-}
-
-/* X and Y are two things to compare using CODE. Emit the compare insn and
- return the rtx for register 0 in the proper mode. FP means this is a
- floating point compare: I don't think that it is needed on the arm. */
-rtx
-arm_gen_compare_reg (enum rtx_code code, rtx x, rtx y, rtx scratch)
-{
- enum machine_mode mode;
- rtx cc_reg;
- int dimode_comparison = GET_MODE (x) == DImode || GET_MODE (y) == DImode;
-
- /* We might have X as a constant, Y as a register because of the predicates
- used for cmpdi. If so, force X to a register here. */
- if (dimode_comparison && !REG_P (x))
- x = force_reg (DImode, x);
-
- mode = SELECT_CC_MODE (code, x, y);
- cc_reg = gen_rtx_REG (mode, CC_REGNUM);
-
- if (dimode_comparison
- && mode != CC_CZmode)
- {
- rtx clobber, set;
-
- /* To compare two non-zero values for equality, XOR them and
- then compare against zero. Not used for ARM mode; there
- CC_CZmode is cheaper. */
- if (mode == CC_Zmode && y != const0_rtx)
- {
- gcc_assert (!reload_completed);
- x = expand_binop (DImode, xor_optab, x, y, NULL_RTX, 0, OPTAB_WIDEN);
- y = const0_rtx;
- }
-
- /* A scratch register is required. */
- if (reload_completed)
- gcc_assert (scratch != NULL && GET_MODE (scratch) == SImode);
- else
- scratch = gen_rtx_SCRATCH (SImode);
-
- clobber = gen_rtx_CLOBBER (VOIDmode, scratch);
- set = gen_rtx_SET (VOIDmode, cc_reg, gen_rtx_COMPARE (mode, x, y));
- emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, clobber)));
- }
- else
- emit_set_insn (cc_reg, gen_rtx_COMPARE (mode, x, y));
-
- return cc_reg;
-}
-
-/* Generate a sequence of insns that will generate the correct return
- address mask depending on the physical architecture that the program
- is running on. */
-rtx
-arm_gen_return_addr_mask (void)
-{
- rtx reg = gen_reg_rtx (Pmode);
-
- emit_insn (gen_return_addr_mask (reg));
- return reg;
-}
-
-void
-arm_reload_in_hi (rtx *operands)
-{
- rtx ref = operands[1];
- rtx base, scratch;
- HOST_WIDE_INT offset = 0;
-
- if (GET_CODE (ref) == SUBREG)
- {
- offset = SUBREG_BYTE (ref);
- ref = SUBREG_REG (ref);
- }
-
- if (REG_P (ref))
- {
- /* We have a pseudo which has been spilt onto the stack; there
- are two cases here: the first where there is a simple
- stack-slot replacement and a second where the stack-slot is
- out of range, or is used as a subreg. */
- if (reg_equiv_mem (REGNO (ref)))
- {
- ref = reg_equiv_mem (REGNO (ref));
- base = find_replacement (&XEXP (ref, 0));
- }
- else
- /* The slot is out of range, or was dressed up in a SUBREG. */
- base = reg_equiv_address (REGNO (ref));
- }
- else
- base = find_replacement (&XEXP (ref, 0));
-
- /* Handle the case where the address is too complex to be offset by 1. */
- if (GET_CODE (base) == MINUS
- || (GET_CODE (base) == PLUS && !CONST_INT_P (XEXP (base, 1))))
- {
- rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
-
- emit_set_insn (base_plus, base);
- base = base_plus;
- }
- else if (GET_CODE (base) == PLUS)
- {
- /* The addend must be CONST_INT, or we would have dealt with it above. */
- HOST_WIDE_INT hi, lo;
-
- offset += INTVAL (XEXP (base, 1));
- base = XEXP (base, 0);
-
- /* Rework the address into a legal sequence of insns. */
- /* Valid range for lo is -4095 -> 4095 */
- lo = (offset >= 0
- ? (offset & 0xfff)
- : -((-offset) & 0xfff));
-
- /* Corner case, if lo is the max offset then we would be out of range
- once we have added the additional 1 below, so bump the msb into the
- pre-loading insn(s). */
- if (lo == 4095)
- lo &= 0x7ff;
-
- hi = ((((offset - lo) & (HOST_WIDE_INT) 0xffffffff)
- ^ (HOST_WIDE_INT) 0x80000000)
- - (HOST_WIDE_INT) 0x80000000);
-
- gcc_assert (hi + lo == offset);
-
- if (hi != 0)
- {
- rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
-
- /* Get the base address; addsi3 knows how to handle constants
- that require more than one insn. */
- emit_insn (gen_addsi3 (base_plus, base, GEN_INT (hi)));
- base = base_plus;
- offset = lo;
- }
- }
-
- /* Operands[2] may overlap operands[0] (though it won't overlap
- operands[1]), that's why we asked for a DImode reg -- so we can
- use the bit that does not overlap. */
- if (REGNO (operands[2]) == REGNO (operands[0]))
- scratch = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
- else
- scratch = gen_rtx_REG (SImode, REGNO (operands[2]));
-
- emit_insn (gen_zero_extendqisi2 (scratch,
- gen_rtx_MEM (QImode,
- plus_constant (Pmode, base,
- offset))));
- emit_insn (gen_zero_extendqisi2 (gen_rtx_SUBREG (SImode, operands[0], 0),
- gen_rtx_MEM (QImode,
- plus_constant (Pmode, base,
- offset + 1))));
- if (!BYTES_BIG_ENDIAN)
- emit_set_insn (gen_rtx_SUBREG (SImode, operands[0], 0),
- gen_rtx_IOR (SImode,
- gen_rtx_ASHIFT
- (SImode,
- gen_rtx_SUBREG (SImode, operands[0], 0),
- GEN_INT (8)),
- scratch));
- else
- emit_set_insn (gen_rtx_SUBREG (SImode, operands[0], 0),
- gen_rtx_IOR (SImode,
- gen_rtx_ASHIFT (SImode, scratch,
- GEN_INT (8)),
- gen_rtx_SUBREG (SImode, operands[0], 0)));
-}
-
-/* Handle storing a half-word to memory during reload by synthesizing as two
- byte stores. Take care not to clobber the input values until after we
- have moved them somewhere safe. This code assumes that if the DImode
- scratch in operands[2] overlaps either the input value or output address
- in some way, then that value must die in this insn (we absolutely need
- two scratch registers for some corner cases). */
-void
-arm_reload_out_hi (rtx *operands)
-{
- rtx ref = operands[0];
- rtx outval = operands[1];
- rtx base, scratch;
- HOST_WIDE_INT offset = 0;
-
- if (GET_CODE (ref) == SUBREG)
- {
- offset = SUBREG_BYTE (ref);
- ref = SUBREG_REG (ref);
- }
-
- if (REG_P (ref))
- {
- /* We have a pseudo which has been spilt onto the stack; there
- are two cases here: the first where there is a simple
- stack-slot replacement and a second where the stack-slot is
- out of range, or is used as a subreg. */
- if (reg_equiv_mem (REGNO (ref)))
- {
- ref = reg_equiv_mem (REGNO (ref));
- base = find_replacement (&XEXP (ref, 0));
- }
- else
- /* The slot is out of range, or was dressed up in a SUBREG. */
- base = reg_equiv_address (REGNO (ref));
- }
- else
- base = find_replacement (&XEXP (ref, 0));
-
- scratch = gen_rtx_REG (SImode, REGNO (operands[2]));
-
- /* Handle the case where the address is too complex to be offset by 1. */
- if (GET_CODE (base) == MINUS
- || (GET_CODE (base) == PLUS && !CONST_INT_P (XEXP (base, 1))))
- {
- rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
-
- /* Be careful not to destroy OUTVAL. */
- if (reg_overlap_mentioned_p (base_plus, outval))
- {
- /* Updating base_plus might destroy outval, see if we can
- swap the scratch and base_plus. */
- if (!reg_overlap_mentioned_p (scratch, outval))
- {
- rtx tmp = scratch;
- scratch = base_plus;
- base_plus = tmp;
- }
- else
- {
- rtx scratch_hi = gen_rtx_REG (HImode, REGNO (operands[2]));
-
- /* Be conservative and copy OUTVAL into the scratch now,
- this should only be necessary if outval is a subreg
- of something larger than a word. */
- /* XXX Might this clobber base? I can't see how it can,
- since scratch is known to overlap with OUTVAL, and
- must be wider than a word. */
- emit_insn (gen_movhi (scratch_hi, outval));
- outval = scratch_hi;
- }
- }
-
- emit_set_insn (base_plus, base);
- base = base_plus;
- }
- else if (GET_CODE (base) == PLUS)
- {
- /* The addend must be CONST_INT, or we would have dealt with it above. */
- HOST_WIDE_INT hi, lo;
-
- offset += INTVAL (XEXP (base, 1));
- base = XEXP (base, 0);
-
- /* Rework the address into a legal sequence of insns. */
- /* Valid range for lo is -4095 -> 4095 */
- lo = (offset >= 0
- ? (offset & 0xfff)
- : -((-offset) & 0xfff));
-
- /* Corner case, if lo is the max offset then we would be out of range
- once we have added the additional 1 below, so bump the msb into the
- pre-loading insn(s). */
- if (lo == 4095)
- lo &= 0x7ff;
-
- hi = ((((offset - lo) & (HOST_WIDE_INT) 0xffffffff)
- ^ (HOST_WIDE_INT) 0x80000000)
- - (HOST_WIDE_INT) 0x80000000);
-
- gcc_assert (hi + lo == offset);
-
- if (hi != 0)
- {
- rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
-
- /* Be careful not to destroy OUTVAL. */
- if (reg_overlap_mentioned_p (base_plus, outval))
- {
- /* Updating base_plus might destroy outval, see if we
- can swap the scratch and base_plus. */
- if (!reg_overlap_mentioned_p (scratch, outval))
- {
- rtx tmp = scratch;
- scratch = base_plus;
- base_plus = tmp;
- }
- else
- {
- rtx scratch_hi = gen_rtx_REG (HImode, REGNO (operands[2]));
-
- /* Be conservative and copy outval into scratch now,
- this should only be necessary if outval is a
- subreg of something larger than a word. */
- /* XXX Might this clobber base? I can't see how it
- can, since scratch is known to overlap with
- outval. */
- emit_insn (gen_movhi (scratch_hi, outval));
- outval = scratch_hi;
- }
- }
-
- /* Get the base address; addsi3 knows how to handle constants
- that require more than one insn. */
- emit_insn (gen_addsi3 (base_plus, base, GEN_INT (hi)));
- base = base_plus;
- offset = lo;
- }
- }
-
- if (BYTES_BIG_ENDIAN)
- {
- emit_insn (gen_movqi (gen_rtx_MEM (QImode,
- plus_constant (Pmode, base,
- offset + 1)),
- gen_lowpart (QImode, outval)));
- emit_insn (gen_lshrsi3 (scratch,
- gen_rtx_SUBREG (SImode, outval, 0),
- GEN_INT (8)));
- emit_insn (gen_movqi (gen_rtx_MEM (QImode, plus_constant (Pmode, base,
- offset)),
- gen_lowpart (QImode, scratch)));
- }
- else
- {
- emit_insn (gen_movqi (gen_rtx_MEM (QImode, plus_constant (Pmode, base,
- offset)),
- gen_lowpart (QImode, outval)));
- emit_insn (gen_lshrsi3 (scratch,
- gen_rtx_SUBREG (SImode, outval, 0),
- GEN_INT (8)));
- emit_insn (gen_movqi (gen_rtx_MEM (QImode,
- plus_constant (Pmode, base,
- offset + 1)),
- gen_lowpart (QImode, scratch)));
- }
-}
-
-/* Return true if a type must be passed in memory. For AAPCS, small aggregates
- (padded to the size of a word) should be passed in a register. */
-
-static bool
-arm_must_pass_in_stack (enum machine_mode mode, const_tree type)
-{
- if (TARGET_AAPCS_BASED)
- return must_pass_in_stack_var_size (mode, type);
- else
- return must_pass_in_stack_var_size_or_pad (mode, type);
-}
-
-
-/* For use by FUNCTION_ARG_PADDING (MODE, TYPE).
- Return true if an argument passed on the stack should be padded upwards,
- i.e. if the least-significant byte has useful data.
- For legacy APCS ABIs we use the default. For AAPCS based ABIs small
- aggregate types are placed in the lowest memory address. */
-
-bool
-arm_pad_arg_upward (enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type)
-{
- if (!TARGET_AAPCS_BASED)
- return DEFAULT_FUNCTION_ARG_PADDING(mode, type) == upward;
-
- if (type && BYTES_BIG_ENDIAN && INTEGRAL_TYPE_P (type))
- return false;
-
- return true;
-}
-
-
-/* Similarly, for use by BLOCK_REG_PADDING (MODE, TYPE, FIRST).
- Return !BYTES_BIG_ENDIAN if the least significant byte of the
- register has useful data, and return the opposite if the most
- significant byte does. */
-
-bool
-arm_pad_reg_upward (enum machine_mode mode,
- tree type, int first ATTRIBUTE_UNUSED)
-{
- if (TARGET_AAPCS_BASED && BYTES_BIG_ENDIAN)
- {
- /* For AAPCS, small aggregates, small fixed-point types,
- and small complex types are always padded upwards. */
- if (type)
- {
- if ((AGGREGATE_TYPE_P (type)
- || TREE_CODE (type) == COMPLEX_TYPE
- || FIXED_POINT_TYPE_P (type))
- && int_size_in_bytes (type) <= 4)
- return true;
- }
- else
- {
- if ((COMPLEX_MODE_P (mode) || ALL_FIXED_POINT_MODE_P (mode))
- && GET_MODE_SIZE (mode) <= 4)
- return true;
- }
- }
-
- /* Otherwise, use default padding. */
- return !BYTES_BIG_ENDIAN;
-}
-
-/* Returns true iff OFFSET is valid for use in an LDRD/STRD instruction,
- assuming that the address in the base register is word aligned. */
-bool
-offset_ok_for_ldrd_strd (HOST_WIDE_INT offset)
-{
- HOST_WIDE_INT max_offset;
-
- /* Offset must be a multiple of 4 in Thumb mode. */
- if (TARGET_THUMB2 && ((offset & 3) != 0))
- return false;
-
- if (TARGET_THUMB2)
- max_offset = 1020;
- else if (TARGET_ARM)
- max_offset = 255;
- else
- return false;
-
- return ((offset <= max_offset) && (offset >= -max_offset));
-}
-
-/* Checks whether the operands are valid for use in an LDRD/STRD instruction.
- Assumes that RT, RT2, and RN are REG. This is guaranteed by the patterns.
- Assumes that the address in the base register RN is word aligned. Pattern
- guarantees that both memory accesses use the same base register,
- the offsets are constants within the range, and the gap between the offsets is 4.
- If preload complete then check that registers are legal. WBACK indicates whether
- address is updated. LOAD indicates whether memory access is load or store. */
-bool
-operands_ok_ldrd_strd (rtx rt, rtx rt2, rtx rn, HOST_WIDE_INT offset,
- bool wback, bool load)
-{
- unsigned int t, t2, n;
-
- if (!reload_completed)
- return true;
-
- if (!offset_ok_for_ldrd_strd (offset))
- return false;
-
- t = REGNO (rt);
- t2 = REGNO (rt2);
- n = REGNO (rn);
-
- if ((TARGET_THUMB2)
- && ((wback && (n == t || n == t2))
- || (t == SP_REGNUM)
- || (t == PC_REGNUM)
- || (t2 == SP_REGNUM)
- || (t2 == PC_REGNUM)
- || (!load && (n == PC_REGNUM))
- || (load && (t == t2))
- /* Triggers Cortex-M3 LDRD errata. */
- || (!wback && load && fix_cm3_ldrd && (n == t))))
- return false;
-
- if ((TARGET_ARM)
- && ((wback && (n == t || n == t2))
- || (t2 == PC_REGNUM)
- || (t % 2 != 0) /* First destination register is not even. */
- || (t2 != t + 1)
- /* PC can be used as base register (for offset addressing only),
- but it is depricated. */
- || (n == PC_REGNUM)))
- return false;
-
- return true;
-}
-
-
-/* Print a symbolic form of X to the debug file, F. */
-static void
-arm_print_value (FILE *f, rtx x)
-{
- switch (GET_CODE (x))
- {
- case CONST_INT:
- fprintf (f, HOST_WIDE_INT_PRINT_HEX, 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, HOST_WIDE_INT_PRINT_HEX, 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:
- arm_print_value (f, XEXP (x, 0));
- return;
-
- case PLUS:
- arm_print_value (f, XEXP (x, 0));
- fprintf (f, "+");
- arm_print_value (f, XEXP (x, 1));
- return;
-
- case PC:
- fprintf (f, "pc");
- return;
-
- default:
- fprintf (f, "????");
- return;
- }
-}
-
-/* Routines for manipulation of the constant pool. */
-
-/* Arm 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:
-
- ldr rn, L1
- ...
- b L2
- align
- L1: .long value
- L2:
- ...
-
- ldr rn, L3
- ...
- b 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. With iWMMXt enabled
- sizes > 4 also imply an alignment of 8-bytes. */
- 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) \
- (GET_MODE_SIZE ((mode)) >= 4 ? GET_MODE_SIZE ((mode)) : 4)
-
-static Mnode * minipool_vector_head;
-static Mnode * minipool_vector_tail;
-static rtx minipool_vector_label;
-static int minipool_pad;
-
-/* 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 (jump_to_label_p (insn)
- && ((table = next_real_insn (JUMP_LABEL (insn)))
- == next_real_insn (insn))
- && table != NULL
- && JUMP_P (table)
- && (GET_CODE (PATTERN (table)) == ADDR_VEC
- || GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC))
- return table;
-
- return NULL_RTX;
-}
-
-#ifndef JUMP_TABLES_IN_TEXT_SECTION
-#define JUMP_TABLES_IN_TEXT_SECTION 0
-#endif
-
-static HOST_WIDE_INT
-get_jump_table_size (rtx insn)
-{
- /* ADDR_VECs only take room if read-only data does into the text
- section. */
- if (JUMP_TABLES_IN_TEXT_SECTION || readonly_data_section == text_section)
- {
- rtx body = PATTERN (insn);
- int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0;
- HOST_WIDE_INT size;
- HOST_WIDE_INT modesize;
-
- modesize = GET_MODE_SIZE (GET_MODE (body));
- size = modesize * XVECLEN (body, elt);
- switch (modesize)
- {
- case 1:
- /* Round up size of TBB table to a halfword boundary. */
- size = (size + 1) & ~(HOST_WIDE_INT)1;
- break;
- case 2:
- /* No padding necessary for TBH. */
- break;
- case 4:
- /* Add two bytes for alignment on Thumb. */
- if (TARGET_THUMB)
- size += 2;
- break;
- default:
- gcc_unreachable ();
- }
- return size;
- }
-
- return 0;
-}
-
-/* Return the maximum amount of padding that will be inserted before
- label LABEL. */
-
-static HOST_WIDE_INT
-get_label_padding (rtx label)
-{
- HOST_WIDE_INT align, min_insn_size;
-
- align = 1 << label_to_alignment (label);
- min_insn_size = TARGET_THUMB ? 2 : 4;
- return align > min_insn_size ? align - min_insn_size : 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)
-{
- /* The code below assumes these are different. */
- gcc_assert (mp != max_mp);
-
- 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 - minipool_pad;
- Mnode * mp;
-
- /* If the minipool starts before the end of FIX->INSN then this FIX
- can not be placed into the current pool. Furthermore, adding the
- new constant pool entry may cause the pool to start FIX_SIZE bytes
- earlier. */
- if (minipool_vector_head &&
- (fix->address + get_attr_length (fix->insn)
- >= 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
- && (!LABEL_P (fix->value)
- || (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;
-
- /* 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. */
- if (ARM_DOUBLEWORD_ALIGN
- && max_mp == NULL
- && fix->fix_size >= 8
- && mp->fix_size < 8)
- {
- max_mp = mp;
- max_address = mp->max_address;
- }
- }
-
- /* 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 = XNEW (Mnode);
- 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;
-
- /* The code below assumes these are different. */
- gcc_assert (mp != min_mp);
-
- 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
- && (!LABEL_P (fix->value)
- || (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)
- {
- /* For now, we do not allow the insertion of 8-byte alignment
- requiring nodes anywhere but at the start of the pool. */
- if (ARM_DOUBLEWORD_ALIGN
- && fix->fix_size >= 8 && mp->fix_size < 8)
- return NULL;
- else
- 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. */
- 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;
- }
- }
- /* Do not insert a non-8-byte aligned quantity before 8-byte
- aligned quantities. */
- else if (ARM_DOUBLEWORD_ALIGN
- && fix->fix_size < 8
- && mp->fix_size >= 8)
- {
- min_mp = mp;
- min_address = mp->min_address + fix->fix_size;
- }
- }
- }
-
- /* We need to create a new entry. */
- mp = XNEW (Mnode);
- 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;
- }
-}
-
-/* Output the literal table */
-static void
-dump_minipool (rtx scan)
-{
- Mnode * mp;
- Mnode * nmp;
- int align64 = 0;
-
- if (ARM_DOUBLEWORD_ALIGN)
- for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
- if (mp->refcount > 0 && mp->fix_size >= 8)
- {
- align64 = 1;
- break;
- }
-
- 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, align64 ? 8 : 4);
-
- scan = emit_label_after (gen_label_rtx (), scan);
- scan = emit_insn_after (align64 ? gen_align_8 () : gen_align_4 (), scan);
- scan = emit_label_after (minipool_vector_label, scan);
-
- 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);
- arm_print_value (dump_file, mp->value);
- fputc ('\n', dump_file);
- }
-
- switch (mp->fix_size)
- {
-#ifdef HAVE_consttable_1
- case 1:
- scan = emit_insn_after (gen_consttable_1 (mp->value), scan);
- break;
-
-#endif
-#ifdef HAVE_consttable_2
- case 2:
- scan = emit_insn_after (gen_consttable_2 (mp->value), scan);
- break;
-
-#endif
-#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
- default:
- gcc_unreachable ();
- }
- }
-
- 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
-arm_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 && LABEL_P (next))
- 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;
- /* The instruction after which we will insert the jump. */
- rtx selected = NULL;
- int selected_cost;
- /* The address at which the jump instruction will be placed. */
- HOST_WIDE_INT selected_address;
- Mfix * new_fix;
- HOST_WIDE_INT max_count = max_address - fix->address;
- rtx label = gen_label_rtx ();
-
- selected_cost = arm_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. */
- gcc_assert (!BARRIER_P (from));
-
- /* Count the length of this insn. This must stay in sync with the
- code that pushes minipool fixes. */
- if (LABEL_P (from))
- count += get_label_padding (from);
- else
- 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 = arm_barrier_cost (from);
-
- if (count < max_count
- && (!selected || 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 = arm_barrier_cost (from);
-
- if (count < max_count
- && (!selected || new_cost <= selected_cost))
- {
- selected = from;
- selected_cost = new_cost;
- selected_address = fix->address + count;
- }
-
- from = NEXT_INSN (from);
- }
-
- /* Make sure that we found a place to insert the jump. */
- gcc_assert (selected);
-
- /* Make sure we do not split a call and its corresponding
- CALL_ARG_LOCATION note. */
- if (CALL_P (selected))
- {
- rtx next = NEXT_INSN (selected);
- if (next && NOTE_P (next)
- && NOTE_KIND (next) == NOTE_INSN_CALL_ARG_LOCATION)
- selected = next;
- }
-
- /* 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));
-
- fix->insn = insn;
- fix->address = address;
- fix->loc = loc;
- fix->mode = mode;
- fix->fix_size = MINIPOOL_FIX_SIZE (mode);
- fix->value = value;
- fix->forwards = get_attr_pool_range (insn);
- fix->backwards = get_attr_neg_pool_range (insn);
- 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 stop now than
- to generate duff assembly code. */
- gcc_assert (fix->forwards || fix->backwards);
-
- /* If an entry requires 8-byte alignment then assume all constant pools
- require 4 bytes of padding. Trying to do this later on a per-pool
- basis is awkward because existing pool entries have to be modified. */
- if (ARM_DOUBLEWORD_ALIGN && fix->fix_size >= 8)
- minipool_pad = 4;
-
- 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);
- arm_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;
-}
-
-/* Return the cost of synthesizing a 64-bit constant VAL inline.
- Returns the number of insns needed, or 99 if we don't know how to
- do it. */
-int
-arm_const_double_inline_cost (rtx val)
-{
- rtx lowpart, highpart;
- enum machine_mode mode;
-
- mode = GET_MODE (val);
-
- if (mode == VOIDmode)
- mode = DImode;
-
- gcc_assert (GET_MODE_SIZE (mode) == 8);
-
- lowpart = gen_lowpart (SImode, val);
- highpart = gen_highpart_mode (SImode, mode, val);
-
- gcc_assert (CONST_INT_P (lowpart));
- gcc_assert (CONST_INT_P (highpart));
-
- return (arm_gen_constant (SET, SImode, NULL_RTX, INTVAL (lowpart),
- NULL_RTX, NULL_RTX, 0, 0)
- + arm_gen_constant (SET, SImode, NULL_RTX, INTVAL (highpart),
- NULL_RTX, NULL_RTX, 0, 0));
-}
-
-/* Return true if it is worthwhile to split a 64-bit constant into two
- 32-bit operations. This is the case if optimizing for size, or
- if we have load delay slots, or if one 32-bit part can be done with
- a single data operation. */
-bool
-arm_const_double_by_parts (rtx val)
-{
- enum machine_mode mode = GET_MODE (val);
- rtx part;
-
- if (optimize_size || arm_ld_sched)
- return true;
-
- if (mode == VOIDmode)
- mode = DImode;
-
- part = gen_highpart_mode (SImode, mode, val);
-
- gcc_assert (CONST_INT_P (part));
-
- if (const_ok_for_arm (INTVAL (part))
- || const_ok_for_arm (~INTVAL (part)))
- return true;
-
- part = gen_lowpart (SImode, val);
-
- gcc_assert (CONST_INT_P (part));
-
- if (const_ok_for_arm (INTVAL (part))
- || const_ok_for_arm (~INTVAL (part)))
- return true;
-
- return false;
-}
-
-/* Return true if it is possible to inline both the high and low parts
- of a 64-bit constant into 32-bit data processing instructions. */
-bool
-arm_const_double_by_immediates (rtx val)
-{
- enum machine_mode mode = GET_MODE (val);
- rtx part;
-
- if (mode == VOIDmode)
- mode = DImode;
-
- part = gen_highpart_mode (SImode, mode, val);
-
- gcc_assert (CONST_INT_P (part));
-
- if (!const_ok_for_arm (INTVAL (part)))
- return false;
-
- part = gen_lowpart (SImode, val);
-
- gcc_assert (CONST_INT_P (part));
-
- if (!const_ok_for_arm (INTVAL (part)))
- return false;
-
- return true;
-}
-
-/* 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. */
-static void
-note_invalid_constants (rtx insn, HOST_WIDE_INT address, int do_pushes)
-{
- int opno;
-
- extract_insn (insn);
-
- if (!constrain_operands (1))
- fatal_insn_not_found (insn);
-
- if (recog_data.n_alternatives == 0)
- return;
-
- /* Fill in recog_op_alt with information about the constraints of
- this insn. */
- preprocess_constraints ();
-
- for (opno = 0; opno < recog_data.n_operands; opno++)
- {
- /* Things we need to fix can only occur in inputs. */
- if (recog_data.operand_type[opno] != OP_IN)
- continue;
-
- /* If this alternative is a memory reference, then any mention
- of constants in this alternative is really to fool reload
- into allowing us to accept one there. We need to fix them up
- now so that we output the right code. */
- if (recog_op_alt[opno][which_alternative].memory_ok)
- {
- rtx op = recog_data.operand[opno];
-
- if (CONSTANT_P (op))
- {
- if (do_pushes)
- push_minipool_fix (insn, address, recog_data.operand_loc[opno],
- recog_data.operand_mode[opno], op);
- }
- else if (MEM_P (op)
- && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
- && CONSTANT_POOL_ADDRESS_P (XEXP (op, 0)))
- {
- 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);
- }
-
- }
- }
- }
-
- return;
-}
-
-/* Rewrite move insn into subtract of 0 if the condition codes will
- be useful in next conditional jump insn. */
-
-static void
-thumb1_reorg (void)
-{
- basic_block bb;
-
- FOR_EACH_BB (bb)
- {
- rtx set, dest, src;
- rtx pat, op0;
- rtx prev, insn = BB_END (bb);
-
- while (insn != BB_HEAD (bb) && DEBUG_INSN_P (insn))
- insn = PREV_INSN (insn);
-
- /* Find the last cbranchsi4_insn in basic block BB. */
- if (INSN_CODE (insn) != CODE_FOR_cbranchsi4_insn)
- continue;
-
- /* Find the first non-note insn before INSN in basic block BB. */
- gcc_assert (insn != BB_HEAD (bb));
- prev = PREV_INSN (insn);
- while (prev != BB_HEAD (bb) && (NOTE_P (prev) || DEBUG_INSN_P (prev)))
- prev = PREV_INSN (prev);
-
- set = single_set (prev);
- if (!set)
- continue;
-
- dest = SET_DEST (set);
- src = SET_SRC (set);
- if (!low_register_operand (dest, SImode)
- || !low_register_operand (src, SImode))
- continue;
-
- pat = PATTERN (insn);
- op0 = XEXP (XEXP (SET_SRC (pat), 0), 0);
- /* Rewrite move into subtract of 0 if its operand is compared with ZERO
- in INSN. Don't need to check dest since cprop_hardreg pass propagates
- src into INSN. */
- if (REGNO (op0) == REGNO (src))
- {
- dest = copy_rtx (dest);
- src = copy_rtx (src);
- src = gen_rtx_MINUS (SImode, src, const0_rtx);
- PATTERN (prev) = gen_rtx_SET (VOIDmode, dest, src);
- INSN_CODE (prev) = -1;
- /* Set test register in INSN to dest. */
- XEXP (XEXP (SET_SRC (pat), 0), 0) = copy_rtx (dest);
- INSN_CODE (insn) = -1;
- }
- }
-}
-
-/* Convert instructions to their cc-clobbering variant if possible, since
- that allows us to use smaller encodings. */
-
-static void
-thumb2_reorg (void)
-{
- basic_block bb;
- regset_head live;
-
- INIT_REG_SET (&live);
-
- /* We are freeing block_for_insn in the toplev to keep compatibility
- with old MDEP_REORGS that are not CFG based. Recompute it now. */
- compute_bb_for_insn ();
- df_analyze ();
-
- FOR_EACH_BB (bb)
- {
- rtx insn;
-
- COPY_REG_SET (&live, DF_LR_OUT (bb));
- df_simulate_initialize_backwards (bb, &live);
- FOR_BB_INSNS_REVERSE (bb, insn)
- {
- if (NONJUMP_INSN_P (insn)
- && !REGNO_REG_SET_P (&live, CC_REGNUM)
- && GET_CODE (PATTERN (insn)) == SET)
- {
- enum {SKIP, CONV, SWAP_CONV} action = SKIP;
- rtx pat = PATTERN (insn);
- rtx dst = XEXP (pat, 0);
- rtx src = XEXP (pat, 1);
- rtx op0 = NULL_RTX, op1 = NULL_RTX;
-
- if (!OBJECT_P (src))
- op0 = XEXP (src, 0);
-
- if (BINARY_P (src))
- op1 = XEXP (src, 1);
-
- if (low_register_operand (dst, SImode))
- {
- switch (GET_CODE (src))
- {
- case PLUS:
- /* Adding two registers and storing the result
- in the first source is already a 16-bit
- operation. */
- if (rtx_equal_p (dst, op0)
- && register_operand (op1, SImode))
- break;
-
- if (low_register_operand (op0, SImode))
- {
- /* ADDS <Rd>,<Rn>,<Rm> */
- if (low_register_operand (op1, SImode))
- action = CONV;
- /* ADDS <Rdn>,#<imm8> */
- /* SUBS <Rdn>,#<imm8> */
- else if (rtx_equal_p (dst, op0)
- && CONST_INT_P (op1)
- && IN_RANGE (INTVAL (op1), -255, 255))
- action = CONV;
- /* ADDS <Rd>,<Rn>,#<imm3> */
- /* SUBS <Rd>,<Rn>,#<imm3> */
- else if (CONST_INT_P (op1)
- && IN_RANGE (INTVAL (op1), -7, 7))
- action = CONV;
- }
- break;
-
- case MINUS:
- /* RSBS <Rd>,<Rn>,#0
- Not handled here: see NEG below. */
- /* SUBS <Rd>,<Rn>,#<imm3>
- SUBS <Rdn>,#<imm8>
- Not handled here: see PLUS above. */
- /* SUBS <Rd>,<Rn>,<Rm> */
- if (low_register_operand (op0, SImode)
- && low_register_operand (op1, SImode))
- action = CONV;
- break;
-
- case MULT:
- /* MULS <Rdm>,<Rn>,<Rdm>
- As an exception to the rule, this is only used
- when optimizing for size since MULS is slow on all
- known implementations. We do not even want to use
- MULS in cold code, if optimizing for speed, so we
- test the global flag here. */
- if (!optimize_size)
- break;
- /* else fall through. */
- case AND:
- case IOR:
- case XOR:
- /* ANDS <Rdn>,<Rm> */
- if (rtx_equal_p (dst, op0)
- && low_register_operand (op1, SImode))
- action = CONV;
- else if (rtx_equal_p (dst, op1)
- && low_register_operand (op0, SImode))
- action = SWAP_CONV;
- break;
-
- case ASHIFTRT:
- case ASHIFT:
- case LSHIFTRT:
- /* ASRS <Rdn>,<Rm> */
- /* LSRS <Rdn>,<Rm> */
- /* LSLS <Rdn>,<Rm> */
- if (rtx_equal_p (dst, op0)
- && low_register_operand (op1, SImode))
- action = CONV;
- /* ASRS <Rd>,<Rm>,#<imm5> */
- /* LSRS <Rd>,<Rm>,#<imm5> */
- /* LSLS <Rd>,<Rm>,#<imm5> */
- else if (low_register_operand (op0, SImode)
- && CONST_INT_P (op1)
- && IN_RANGE (INTVAL (op1), 0, 31))
- action = CONV;
- break;
-
- case ROTATERT:
- /* RORS <Rdn>,<Rm> */
- if (rtx_equal_p (dst, op0)
- && low_register_operand (op1, SImode))
- action = CONV;
- break;
-
- case NOT:
- case NEG:
- /* MVNS <Rd>,<Rm> */
- /* NEGS <Rd>,<Rm> (a.k.a RSBS) */
- if (low_register_operand (op0, SImode))
- action = CONV;
- break;
-
- case CONST_INT:
- /* MOVS <Rd>,#<imm8> */
- if (CONST_INT_P (src)
- && IN_RANGE (INTVAL (src), 0, 255))
- action = CONV;
- break;
-
- case REG:
- /* MOVS and MOV<c> with registers have different
- encodings, so are not relevant here. */
- break;
-
- default:
- break;
- }
- }
-
- if (action != SKIP)
- {
- rtx ccreg = gen_rtx_REG (CCmode, CC_REGNUM);
- rtx clobber = gen_rtx_CLOBBER (VOIDmode, ccreg);
- rtvec vec;
-
- if (action == SWAP_CONV)
- {
- src = copy_rtx (src);
- XEXP (src, 0) = op1;
- XEXP (src, 1) = op0;
- pat = gen_rtx_SET (VOIDmode, dst, src);
- vec = gen_rtvec (2, pat, clobber);
- }
- else /* action == CONV */
- vec = gen_rtvec (2, pat, clobber);
-
- PATTERN (insn) = gen_rtx_PARALLEL (VOIDmode, vec);
- INSN_CODE (insn) = -1;
- }
- }
-
- if (NONDEBUG_INSN_P (insn))
- df_simulate_one_insn_backwards (bb, insn, &live);
- }
- }
-
- CLEAR_REG_SET (&live);
-}
-
-/* Gcc puts the pool in the wrong place for ARM, since we can only
- load addresses a limited distance around the pc. We do some
- special munging to move the constant pool values to the correct
- point in the code. */
-static void
-arm_reorg (void)
-{
- rtx insn;
- HOST_WIDE_INT address = 0;
- Mfix * fix;
-
- if (TARGET_THUMB1)
- thumb1_reorg ();
- else if (TARGET_THUMB2)
- thumb2_reorg ();
-
- /* Ensure all insns that must be split have been split at this point.
- Otherwise, the pool placement code below may compute incorrect
- insn lengths. Note that when optimizing, all insns have already
- been split at this point. */
- if (!optimize)
- split_all_insns_noflow ();
-
- 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 ();
- gcc_assert (NOTE_P (insn));
- minipool_pad = 0;
-
- /* 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 (BARRIER_P (insn))
- 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;
- }
- }
- else if (LABEL_P (insn))
- /* Add the worst-case padding due to alignment. We don't add
- the _current_ padding because the minipool insertions
- themselves might change it. */
- address += get_label_padding (insn);
- }
-
- 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 && BARRIER_P (fix->insn))
- fix = fix->next;
-
- /* No more fixes. */
- if (fix == NULL)
- break;
-
- last_added_fix = NULL;
-
- for (ftmp = fix; ftmp; ftmp = ftmp->next)
- {
- if (BARRIER_P (ftmp->insn))
- {
- 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. */
- gcc_assert (ftmp);
-
- 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. The pool itself may come just after the
- fix because create_fix_barrier also allows space for a
- jump instruction. */
- if (ftmp->address < max_address)
- max_address = ftmp->address + 1;
-
- last_barrier = create_fix_barrier (last_added_fix, max_address);
- }
-
- assign_minipool_offsets (last_barrier);
-
- while (ftmp)
- {
- if (!BARRIER_P (ftmp->insn)
- && ((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 (!BARRIER_P (this_fix->insn))
- {
- rtx addr
- = plus_constant (Pmode,
- 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;
- }
-
- /* From now on we must synthesize any constants that we can't handle
- directly. This can happen if the RTL gets split during final
- instruction generation. */
- after_arm_reorg = 1;
-
- /* Free the minipool memory. */
- obstack_free (&minipool_obstack, minipool_startobj);
-}
-
-/* Routines to output assembly language. */
-
-/* If the rtx is the correct value then return the string of the number.
- In this way we can ensure that valid double constants are generated even
- when cross compiling. */
-const char *
-fp_immediate_constant (rtx x)
-{
- REAL_VALUE_TYPE r;
-
- if (!fp_consts_inited)
- init_fp_table ();
-
- REAL_VALUE_FROM_CONST_DOUBLE (r, x);
-
- gcc_assert (REAL_VALUES_EQUAL (r, value_fp0));
- return "0";
-}
-
-/* As for fp_immediate_constant, but value is passed directly, not in rtx. */
-static const char *
-fp_const_from_val (REAL_VALUE_TYPE *r)
-{
- if (!fp_consts_inited)
- init_fp_table ();
-
- gcc_assert (REAL_VALUES_EQUAL (*r, value_fp0));
- return "0";
-}
-
-/* OPERANDS[0] is the entire list of insns that constitute pop,
- OPERANDS[1] is the base register, RETURN_PC is true iff return insn
- is in the list, UPDATE is true iff the list contains explicit
- update of base register. */
-void
-arm_output_multireg_pop (rtx *operands, bool return_pc, rtx cond, bool reverse,
- bool update)
-{
- int i;
- char pattern[100];
- int offset;
- const char *conditional;
- int num_saves = XVECLEN (operands[0], 0);
- unsigned int regno;
- unsigned int regno_base = REGNO (operands[1]);
-
- offset = 0;
- offset += update ? 1 : 0;
- offset += return_pc ? 1 : 0;
-
- /* Is the base register in the list? */
- for (i = offset; i < num_saves; i++)
- {
- regno = REGNO (XEXP (XVECEXP (operands[0], 0, i), 0));
- /* If SP is in the list, then the base register must be SP. */
- gcc_assert ((regno != SP_REGNUM) || (regno_base == SP_REGNUM));
- /* If base register is in the list, there must be no explicit update. */
- if (regno == regno_base)
- gcc_assert (!update);
- }
-
- conditional = reverse ? "%?%D0" : "%?%d0";
- if ((regno_base == SP_REGNUM) && TARGET_UNIFIED_ASM)
- {
- /* Output pop (not stmfd) because it has a shorter encoding. */
- gcc_assert (update);
- sprintf (pattern, "pop%s\t{", conditional);
- }
- else
- {
- /* Output ldmfd when the base register is SP, otherwise output ldmia.
- It's just a convention, their semantics are identical. */
- if (regno_base == SP_REGNUM)
- sprintf (pattern, "ldm%sfd\t", conditional);
- else if (TARGET_UNIFIED_ASM)
- sprintf (pattern, "ldmia%s\t", conditional);
- else
- sprintf (pattern, "ldm%sia\t", conditional);
-
- strcat (pattern, reg_names[regno_base]);
- if (update)
- strcat (pattern, "!, {");
- else
- strcat (pattern, ", {");
- }
-
- /* Output the first destination register. */
- strcat (pattern,
- reg_names[REGNO (XEXP (XVECEXP (operands[0], 0, offset), 0))]);
-
- /* Output the rest of the destination registers. */
- for (i = offset + 1; i < num_saves; i++)
- {
- strcat (pattern, ", ");
- strcat (pattern,
- reg_names[REGNO (XEXP (XVECEXP (operands[0], 0, i), 0))]);
- }
-
- strcat (pattern, "}");
-
- if (IS_INTERRUPT (arm_current_func_type ()) && return_pc)
- strcat (pattern, "^");
-
- output_asm_insn (pattern, &cond);
-}
-
-
-/* Output the assembly for a store multiple. */
-
-const char *
-vfp_output_fstmd (rtx * operands)
-{
- char pattern[100];
- int p;
- int base;
- int i;
-
- strcpy (pattern, "fstmfdd%?\t%m0!, {%P1");
- p = strlen (pattern);
-
- gcc_assert (REG_P (operands[1]));
-
- base = (REGNO (operands[1]) - FIRST_VFP_REGNUM) / 2;
- for (i = 1; i < XVECLEN (operands[2], 0); i++)
- {
- p += sprintf (&pattern[p], ", d%d", base + i);
- }
- strcpy (&pattern[p], "}");
-
- output_asm_insn (pattern, operands);
- return "";
-}
-
-
-/* Emit RTL to save block of VFP register pairs to the stack. Returns the
- number of bytes pushed. */
-
-static int
-vfp_emit_fstmd (int base_reg, int count)
-{
- rtx par;
- rtx dwarf;
- rtx tmp, reg;
- int i;
-
- /* 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. */
- if (count == 2 && !arm_arch6)
- {
- if (base_reg == LAST_VFP_REGNUM - 3)
- base_reg -= 2;
- count++;
- }
-
- /* FSTMD may not store more than 16 doubleword registers at once. Split
- larger stores into multiple parts (up to a maximum of two, in
- practice). */
- if (count > 16)
- {
- int saved;
- /* NOTE: base_reg is an internal register number, so each D register
- counts as 2. */
- saved = vfp_emit_fstmd (base_reg + 32, count - 16);
- saved += vfp_emit_fstmd (base_reg, 16);
- return saved;
- }
-
- par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
- dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (count + 1));
-
- reg = gen_rtx_REG (DFmode, base_reg);
- base_reg += 2;
-
- XVECEXP (par, 0, 0)
- = gen_rtx_SET (VOIDmode,
- gen_frame_mem
- (BLKmode,
- gen_rtx_PRE_MODIFY (Pmode,
- stack_pointer_rtx,
- plus_constant
- (Pmode, stack_pointer_rtx,
- - (count * 8)))
- ),
- gen_rtx_UNSPEC (BLKmode,
- gen_rtvec (1, reg),
- UNSPEC_PUSH_MULT));
-
- tmp = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
- plus_constant (Pmode, stack_pointer_rtx, -(count * 8)));
- RTX_FRAME_RELATED_P (tmp) = 1;
- XVECEXP (dwarf, 0, 0) = tmp;
-
- tmp = gen_rtx_SET (VOIDmode,
- gen_frame_mem (DFmode, stack_pointer_rtx),
- reg);
- RTX_FRAME_RELATED_P (tmp) = 1;
- XVECEXP (dwarf, 0, 1) = tmp;
-
- for (i = 1; i < count; i++)
- {
- reg = gen_rtx_REG (DFmode, base_reg);
- base_reg += 2;
- XVECEXP (par, 0, i) = gen_rtx_USE (VOIDmode, reg);
-
- tmp = gen_rtx_SET (VOIDmode,
- gen_frame_mem (DFmode,
- plus_constant (Pmode,
- stack_pointer_rtx,
- i * 8)),
- reg);
- RTX_FRAME_RELATED_P (tmp) = 1;
- XVECEXP (dwarf, 0, i + 1) = tmp;
- }
-
- par = emit_insn (par);
- add_reg_note (par, REG_FRAME_RELATED_EXPR, dwarf);
- RTX_FRAME_RELATED_P (par) = 1;
-
- return count * 8;
-}
-
-/* Emit a call instruction with pattern PAT. ADDR is the address of
- the call target. */
-
-void
-arm_emit_call_insn (rtx pat, rtx addr)
-{
- rtx insn;
-
- insn = emit_call_insn (pat);
-
- /* The PIC register is live on entry to VxWorks PIC PLT entries.
- If the call might use such an entry, add a use of the PIC register
- to the instruction's CALL_INSN_FUNCTION_USAGE. */
- if (TARGET_VXWORKS_RTP
- && flag_pic
- && GET_CODE (addr) == SYMBOL_REF
- && (SYMBOL_REF_DECL (addr)
- ? !targetm.binds_local_p (SYMBOL_REF_DECL (addr))
- : !SYMBOL_REF_LOCAL_P (addr)))
- {
- require_pic_register ();
- use_reg (&CALL_INSN_FUNCTION_USAGE (insn), cfun->machine->pic_reg);
- }
-}
-
-/* Output a 'call' insn. */
-const char *
-output_call (rtx *operands)
-{
- gcc_assert (!arm_arch5); /* Patterns should call blx <reg> directly. */
-
- /* Handle calls to lr using ip (which may be clobbered in subr anyway). */
- if (REGNO (operands[0]) == LR_REGNUM)
- {
- operands[0] = gen_rtx_REG (SImode, IP_REGNUM);
- output_asm_insn ("mov%?\t%0, %|lr", operands);
- }
-
- output_asm_insn ("mov%?\t%|lr, %|pc", operands);
-
- if (TARGET_INTERWORK || arm_arch4t)
- output_asm_insn ("bx%?\t%0", operands);
- else
- output_asm_insn ("mov%?\t%|pc, %0", operands);
-
- return "";
-}
-
-/* Output a 'call' insn that is a reference in memory. This is
- disabled for ARMv5 and we prefer a blx instead because otherwise
- there's a significant performance overhead. */
-const char *
-output_call_mem (rtx *operands)
-{
- gcc_assert (!arm_arch5);
- if (TARGET_INTERWORK)
- {
- output_asm_insn ("ldr%?\t%|ip, %0", operands);
- output_asm_insn ("mov%?\t%|lr, %|pc", operands);
- output_asm_insn ("bx%?\t%|ip", operands);
- }
- else if (regno_use_in (LR_REGNUM, operands[0]))
- {
- /* LR is used in the memory address. We load the address in the
- first instruction. It's safe to use IP as the target of the
- load since the call will kill it anyway. */
- output_asm_insn ("ldr%?\t%|ip, %0", operands);
- output_asm_insn ("mov%?\t%|lr, %|pc", operands);
- if (arm_arch4t)
- output_asm_insn ("bx%?\t%|ip", operands);
- else
- output_asm_insn ("mov%?\t%|pc, %|ip", operands);
- }
- else
- {
- output_asm_insn ("mov%?\t%|lr, %|pc", operands);
- output_asm_insn ("ldr%?\t%|pc, %0", operands);
- }
-
- return "";
-}
-
-
-/* Output a move from arm registers to arm registers of a long double
- OPERANDS[0] is the destination.
- OPERANDS[1] is the source. */
-const char *
-output_mov_long_double_arm_from_arm (rtx *operands)
-{
- /* We have to be careful here because the two might overlap. */
- int dest_start = REGNO (operands[0]);
- int src_start = REGNO (operands[1]);
- rtx ops[2];
- int i;
-
- if (dest_start < src_start)
- {
- for (i = 0; i < 3; i++)
- {
- ops[0] = gen_rtx_REG (SImode, dest_start + i);
- ops[1] = gen_rtx_REG (SImode, src_start + i);
- output_asm_insn ("mov%?\t%0, %1", ops);
- }
- }
- else
- {
- for (i = 2; i >= 0; i--)
- {
- ops[0] = gen_rtx_REG (SImode, dest_start + i);
- ops[1] = gen_rtx_REG (SImode, src_start + i);
- output_asm_insn ("mov%?\t%0, %1", ops);
- }
- }
-
- return "";
-}
-
-void
-arm_emit_movpair (rtx dest, rtx src)
- {
- /* If the src is an immediate, simplify it. */
- if (CONST_INT_P (src))
- {
- HOST_WIDE_INT val = INTVAL (src);
- emit_set_insn (dest, GEN_INT (val & 0x0000ffff));
- if ((val >> 16) & 0x0000ffff)
- emit_set_insn (gen_rtx_ZERO_EXTRACT (SImode, dest, GEN_INT (16),
- GEN_INT (16)),
- GEN_INT ((val >> 16) & 0x0000ffff));
- return;
- }
- emit_set_insn (dest, gen_rtx_HIGH (SImode, src));
- emit_set_insn (dest, gen_rtx_LO_SUM (SImode, dest, src));
- }
-
-/* Output a move between double words. It must be REG<-MEM
- or MEM<-REG. */
-const char *
-output_move_double (rtx *operands, bool emit, int *count)
-{
- enum rtx_code code0 = GET_CODE (operands[0]);
- enum rtx_code code1 = GET_CODE (operands[1]);
- rtx otherops[3];
- if (count)
- *count = 1;
-
- /* The only case when this might happen is when
- you are looking at the length of a DImode instruction
- that has an invalid constant in it. */
- if (code0 == REG && code1 != MEM)
- {
- gcc_assert (!emit);
- *count = 2;
- return "";
- }
-
- if (code0 == REG)
- {
- unsigned int reg0 = REGNO (operands[0]);
-
- otherops[0] = gen_rtx_REG (SImode, 1 + reg0);
-
- gcc_assert (code1 == MEM); /* Constraints should ensure this. */
-
- switch (GET_CODE (XEXP (operands[1], 0)))
- {
- case REG:
-
- if (emit)
- {
- 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:
- gcc_assert (TARGET_LDRD);
- if (emit)
- output_asm_insn ("ldr%(d%)\t%0, [%m1, #8]!", operands);
- break;
-
- case PRE_DEC:
- if (emit)
- {
- if (TARGET_LDRD)
- output_asm_insn ("ldr%(d%)\t%0, [%m1, #-8]!", operands);
- else
- output_asm_insn ("ldm%(db%)\t%m1!, %M0", operands);
- }
- break;
-
- case POST_INC:
- if (emit)
- {
- 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:
- gcc_assert (TARGET_LDRD);
- if (emit)
- output_asm_insn ("ldr%(d%)\t%0, [%m1], #-8", operands);
- break;
-
- 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);
-
- if (GET_CODE (XEXP (operands[1], 0)) == PRE_MODIFY)
- {
- if (reg_overlap_mentioned_p (otherops[0], otherops[2]))
- {
- /* Registers overlap so split out the increment. */
- if (emit)
- {
- output_asm_insn ("add%?\t%1, %1, %2", otherops);
- output_asm_insn ("ldr%(d%)\t%0, [%1] @split", otherops);
- }
- if (count)
- *count = 2;
- }
- else
- {
- /* Use a single insn if we can.
- FIXME: IWMMXT allows offsets larger than ldrd can
- handle, fix these up with a pair of ldr. */
- if (TARGET_THUMB2
- || !CONST_INT_P (otherops[2])
- || (INTVAL (otherops[2]) > -256
- && INTVAL (otherops[2]) < 256))
- {
- if (emit)
- output_asm_insn ("ldr%(d%)\t%0, [%1, %2]!", otherops);
- }
- else
- {
- if (emit)
- {
- output_asm_insn ("ldr%?\t%0, [%1, %2]!", otherops);
- output_asm_insn ("ldr%?\t%H0, [%1, #4]", otherops);
- }
- if (count)
- *count = 2;
-
- }
- }
- }
- else
- {
- /* Use a single insn if we can.
- FIXME: IWMMXT allows offsets larger than ldrd can handle,
- fix these up with a pair of ldr. */
- if (TARGET_THUMB2
- || !CONST_INT_P (otherops[2])
- || (INTVAL (otherops[2]) > -256
- && INTVAL (otherops[2]) < 256))
- {
- if (emit)
- output_asm_insn ("ldr%(d%)\t%0, [%1], %2", otherops);
- }
- else
- {
- if (emit)
- {
- output_asm_insn ("ldr%?\t%H0, [%1, #4]", otherops);
- output_asm_insn ("ldr%?\t%0, [%1], %2", otherops);
- }
- if (count)
- *count = 2;
- }
- }
- break;
-
- case LABEL_REF:
- case CONST:
- /* We might be able to use ldrd %0, %1 here. However the range is
- different to ldr/adr, and it is broken on some ARMv7-M
- implementations. */
- /* Use the second register of the pair to avoid problematic
- overlap. */
- otherops[1] = operands[1];
- if (emit)
- output_asm_insn ("adr%?\t%0, %1", otherops);
- operands[1] = otherops[0];
- if (emit)
- {
- if (TARGET_LDRD)
- output_asm_insn ("ldr%(d%)\t%0, [%1]", operands);
- else
- output_asm_insn ("ldm%(ia%)\t%1, %M0", operands);
- }
-
- if (count)
- *count = 2;
- break;
-
- /* ??? This needs checking for thumb2. */
- default:
- if (arm_add_operand (XEXP (XEXP (operands[1], 0), 1),
- GET_MODE (XEXP (XEXP (operands[1], 0), 1))))
- {
- otherops[0] = operands[0];
- otherops[1] = XEXP (XEXP (operands[1], 0), 0);
- otherops[2] = XEXP (XEXP (operands[1], 0), 1);
-
- if (GET_CODE (XEXP (operands[1], 0)) == PLUS)
- {
- if (CONST_INT_P (otherops[2]) && !TARGET_LDRD)
- {
- switch ((int) INTVAL (otherops[2]))
- {
- case -8:
- if (emit)
- output_asm_insn ("ldm%(db%)\t%1, %M0", otherops);
- return "";
- case -4:
- if (TARGET_THUMB2)
- break;
- if (emit)
- output_asm_insn ("ldm%(da%)\t%1, %M0", otherops);
- return "";
- case 4:
- if (TARGET_THUMB2)
- break;
- if (emit)
- output_asm_insn ("ldm%(ib%)\t%1, %M0", otherops);
- return "";
- }
- }
- otherops[0] = gen_rtx_REG(SImode, REGNO(operands[0]) + 1);
- operands[1] = otherops[0];
- if (TARGET_LDRD
- && (REG_P (otherops[2])
- || TARGET_THUMB2
- || (CONST_INT_P (otherops[2])
- && INTVAL (otherops[2]) > -256
- && INTVAL (otherops[2]) < 256)))
- {
- if (reg_overlap_mentioned_p (operands[0],
- otherops[2]))
- {
- rtx tmp;
- /* Swap base and index registers over to
- avoid a conflict. */
- 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 (operands[0], otherops[2])
- || (fix_cm3_ldrd && reg0 == REGNO (otherops[1])))
- {
- if (emit)
- {
- output_asm_insn ("add%?\t%0, %1, %2", otherops);
- output_asm_insn ("ldr%(d%)\t%0, [%1]", operands);
- }
- if (count)
- *count = 2;
- }
- else
- {
- otherops[0] = operands[0];
- if (emit)
- output_asm_insn ("ldr%(d%)\t%0, [%1, %2]", otherops);
- }
- return "";
- }
-
- if (CONST_INT_P (otherops[2]))
- {
- if (emit)
- {
- if (!(const_ok_for_arm (INTVAL (otherops[2]))))
- output_asm_insn ("sub%?\t%0, %1, #%n2", otherops);
- else
- output_asm_insn ("add%?\t%0, %1, %2", otherops);
- }
- }
- else
- {
- if (emit)
- output_asm_insn ("add%?\t%0, %1, %2", otherops);
- }
- }
- else
- {
- if (emit)
- output_asm_insn ("sub%?\t%0, %1, %2", otherops);
- }
-
- if (count)
- *count = 2;
-
- if (TARGET_LDRD)
- return "ldr%(d%)\t%0, [%1]";
-
- return "ldm%(ia%)\t%1, %M0";
- }
- else
- {
- otherops[1] = adjust_address (operands[1], SImode, 4);
- /* Take care of overlapping base/data reg. */
- if (reg_mentioned_p (operands[0], operands[1]))
- {
- if (emit)
- {
- output_asm_insn ("ldr%?\t%0, %1", otherops);
- output_asm_insn ("ldr%?\t%0, %1", operands);
- }
- if (count)
- *count = 2;
-
- }
- else
- {
- if (emit)
- {
- output_asm_insn ("ldr%?\t%0, %1", operands);
- output_asm_insn ("ldr%?\t%0, %1", otherops);
- }
- if (count)
- *count = 2;
- }
- }
- }
- }
- else
- {
- /* Constraints should ensure this. */
- gcc_assert (code0 == MEM && code1 == REG);
- gcc_assert (REGNO (operands[1]) != IP_REGNUM);
-
- switch (GET_CODE (XEXP (operands[0], 0)))
- {
- case REG:
- if (emit)
- {
- 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:
- gcc_assert (TARGET_LDRD);
- if (emit)
- output_asm_insn ("str%(d%)\t%1, [%m0, #8]!", operands);
- break;
-
- case PRE_DEC:
- if (emit)
- {
- if (TARGET_LDRD)
- output_asm_insn ("str%(d%)\t%1, [%m0, #-8]!", operands);
- else
- output_asm_insn ("stm%(db%)\t%m0!, %M1", operands);
- }
- break;
-
- case POST_INC:
- if (emit)
- {
- 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:
- gcc_assert (TARGET_LDRD);
- if (emit)
- output_asm_insn ("str%(d%)\t%1, [%m0], #-8", operands);
- break;
-
- case PRE_MODIFY:
- case POST_MODIFY:
- otherops[0] = operands[1];
- 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,
- fix these up with a pair of ldr. */
- if (!TARGET_THUMB2
- && CONST_INT_P (otherops[2])
- && (INTVAL(otherops[2]) <= -256
- || INTVAL(otherops[2]) >= 256))
- {
- if (GET_CODE (XEXP (operands[0], 0)) == PRE_MODIFY)
- {
- if (emit)
- {
- output_asm_insn ("str%?\t%0, [%1, %2]!", otherops);
- output_asm_insn ("str%?\t%H0, [%1, #4]", otherops);
- }
- if (count)
- *count = 2;
- }
- else
- {
- if (emit)
- {
- output_asm_insn ("str%?\t%H0, [%1, #4]", otherops);
- output_asm_insn ("str%?\t%0, [%1], %2", otherops);
- }
- if (count)
- *count = 2;
- }
- }
- else if (GET_CODE (XEXP (operands[0], 0)) == PRE_MODIFY)
- {
- if (emit)
- output_asm_insn ("str%(d%)\t%0, [%1, %2]!", otherops);
- }
- else
- {
- if (emit)
- output_asm_insn ("str%(d%)\t%0, [%1], %2", otherops);
- }
- break;
-
- case PLUS:
- otherops[2] = XEXP (XEXP (operands[0], 0), 1);
- if (CONST_INT_P (otherops[2]) && !TARGET_LDRD)
- {
- switch ((int) INTVAL (XEXP (XEXP (operands[0], 0), 1)))
- {
- case -8:
- if (emit)
- output_asm_insn ("stm%(db%)\t%m0, %M1", operands);
- return "";
-
- case -4:
- if (TARGET_THUMB2)
- break;
- if (emit)
- output_asm_insn ("stm%(da%)\t%m0, %M1", operands);
- return "";
-
- case 4:
- if (TARGET_THUMB2)
- break;
- if (emit)
- output_asm_insn ("stm%(ib%)\t%m0, %M1", operands);
- return "";
- }
- }
- if (TARGET_LDRD
- && (REG_P (otherops[2])
- || TARGET_THUMB2
- || (CONST_INT_P (otherops[2])
- && INTVAL (otherops[2]) > -256
- && INTVAL (otherops[2]) < 256)))
- {
- otherops[0] = operands[1];
- otherops[1] = XEXP (XEXP (operands[0], 0), 0);
- if (emit)
- output_asm_insn ("str%(d%)\t%0, [%1, %2]", otherops);
- return "";
- }
- /* Fall through */
-
- default:
- otherops[0] = adjust_address (operands[0], SImode, 4);
- otherops[1] = operands[1];
- if (emit)
- {
- output_asm_insn ("str%?\t%1, %0", operands);
- output_asm_insn ("str%?\t%H1, %0", otherops);
- }
- if (count)
- *count = 2;
- }
- }
-
- return "";
-}
-
-/* Output a move, load or store for quad-word vectors in ARM registers. Only
- handles MEMs accepted by neon_vector_mem_operand with TYPE=1. */
-
-const char *
-output_move_quad (rtx *operands)
-{
- if (REG_P (operands[0]))
- {
- /* Load, or reg->reg move. */
-
- if (MEM_P (operands[1]))
- {
- switch (GET_CODE (XEXP (operands[1], 0)))
- {
- case REG:
- output_asm_insn ("ldm%(ia%)\t%m1, %M0", operands);
- break;
-
- case LABEL_REF:
- case CONST:
- output_asm_insn ("adr%?\t%0, %1", operands);
- output_asm_insn ("ldm%(ia%)\t%0, %M0", operands);
- break;
-
- default:
- gcc_unreachable ();
- }
- }
- else
- {
- rtx ops[2];
- int dest, src, i;
-
- gcc_assert (REG_P (operands[1]));
-
- dest = REGNO (operands[0]);
- src = REGNO (operands[1]);
-
- /* This seems pretty dumb, but hopefully GCC won't try to do it
- very often. */
- if (dest < src)
- for (i = 0; i < 4; i++)
- {
- ops[0] = gen_rtx_REG (SImode, dest + i);
- ops[1] = gen_rtx_REG (SImode, src + i);
- output_asm_insn ("mov%?\t%0, %1", ops);
- }
- else
- for (i = 3; i >= 0; i--)
- {
- ops[0] = gen_rtx_REG (SImode, dest + i);
- ops[1] = gen_rtx_REG (SImode, src + i);
- output_asm_insn ("mov%?\t%0, %1", ops);
- }
- }
- }
- else
- {
- gcc_assert (MEM_P (operands[0]));
- gcc_assert (REG_P (operands[1]));
- gcc_assert (!reg_overlap_mentioned_p (operands[1], operands[0]));
-
- switch (GET_CODE (XEXP (operands[0], 0)))
- {
- case REG:
- output_asm_insn ("stm%(ia%)\t%m0, %M1", operands);
- break;
-
- default:
- gcc_unreachable ();
- }
- }
-
- return "";
-}
-
-/* Output a VFP load or store instruction. */
-
-const char *
-output_move_vfp (rtx *operands)
-{
- rtx reg, mem, addr, ops[2];
- int load = REG_P (operands[0]);
- int dp = GET_MODE_SIZE (GET_MODE (operands[0])) == 8;
- int integer_p = GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT;
- const char *templ;
- char buff[50];
- enum machine_mode mode;
-
- reg = operands[!load];
- mem = operands[load];
-
- mode = GET_MODE (reg);
-
- gcc_assert (REG_P (reg));
- gcc_assert (IS_VFP_REGNUM (REGNO (reg)));
- gcc_assert (mode == SFmode
- || mode == DFmode
- || mode == SImode
- || mode == DImode
- || (TARGET_NEON && VALID_NEON_DREG_MODE (mode)));
- gcc_assert (MEM_P (mem));
-
- addr = XEXP (mem, 0);
-
- switch (GET_CODE (addr))
- {
- case PRE_DEC:
- templ = "f%smdb%c%%?\t%%0!, {%%%s1}%s";
- ops[0] = XEXP (addr, 0);
- ops[1] = reg;
- break;
-
- case POST_INC:
- templ = "f%smia%c%%?\t%%0!, {%%%s1}%s";
- ops[0] = XEXP (addr, 0);
- ops[1] = reg;
- break;
-
- default:
- templ = "f%s%c%%?\t%%%s0, %%1%s";
- ops[0] = reg;
- ops[1] = mem;
- break;
- }
-
- sprintf (buff, templ,
- load ? "ld" : "st",
- dp ? 'd' : 's',
- dp ? "P" : "",
- integer_p ? "\t%@ int" : "");
- output_asm_insn (buff, ops);
-
- return "";
-}
-
-/* Output a Neon double-word or quad-word load or store, or a load
- or store for larger structure modes.
-
- WARNING: The ordering of elements is weird in big-endian mode,
- because the EABI requires that vectors stored in memory appear
- as though they were stored by a VSTM, as required by the EABI.
- GCC RTL defines element ordering based on in-memory order.
- This can be different from the architectural ordering of elements
- within a NEON register. The intrinsics defined in arm_neon.h use the
- NEON register element ordering, not the GCC RTL element ordering.
-
- For example, the in-memory ordering of a big-endian a quadword
- vector with 16-bit elements when stored from register pair {d0,d1}
- will be (lowest address first, d0[N] is NEON register element N):
-
- [d0[3], d0[2], d0[1], d0[0], d1[7], d1[6], d1[5], d1[4]]
-
- When necessary, quadword registers (dN, dN+1) are moved to ARM
- registers from rN in the order:
-
- dN -> (rN+1, rN), dN+1 -> (rN+3, rN+2)
-
- So that STM/LDM can be used on vectors in ARM registers, and the
- same memory layout will result as if VSTM/VLDM were used.
-
- Instead of VSTM/VLDM we prefer to use VST1.64/VLD1.64 where
- possible, which allows use of appropriate alignment tags.
- Note that the choice of "64" is independent of the actual vector
- element size; this size simply ensures that the behavior is
- equivalent to VSTM/VLDM in both little-endian and big-endian mode.
-
- Due to limitations of those instructions, use of VST1.64/VLD1.64
- is not possible if:
- - the address contains PRE_DEC, or
- - the mode refers to more than 4 double-word registers
-
- In those cases, it would be possible to replace VSTM/VLDM by a
- sequence of instructions; this is not currently implemented since
- this is not certain to actually improve performance. */
-
-const char *
-output_move_neon (rtx *operands)
-{
- rtx reg, mem, addr, ops[2];
- int regno, nregs, load = REG_P (operands[0]);
- const char *templ;
- char buff[50];
- enum machine_mode mode;
-
- reg = operands[!load];
- mem = operands[load];
-
- mode = GET_MODE (reg);
-
- gcc_assert (REG_P (reg));
- regno = REGNO (reg);
- nregs = HARD_REGNO_NREGS (regno, mode) / 2;
- gcc_assert (VFP_REGNO_OK_FOR_DOUBLE (regno)
- || NEON_REGNO_OK_FOR_QUAD (regno));
- gcc_assert (VALID_NEON_DREG_MODE (mode)
- || VALID_NEON_QREG_MODE (mode)
- || VALID_NEON_STRUCT_MODE (mode));
- gcc_assert (MEM_P (mem));
-
- addr = XEXP (mem, 0);
-
- /* Strip off const from addresses like (const (plus (...))). */
- if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == PLUS)
- addr = XEXP (addr, 0);
-
- switch (GET_CODE (addr))
- {
- case POST_INC:
- /* We have to use vldm / vstm for too-large modes. */
- if (nregs > 4)
- {
- templ = "v%smia%%?\t%%0!, %%h1";
- ops[0] = XEXP (addr, 0);
- }
- else
- {
- templ = "v%s1.64\t%%h1, %%A0";
- ops[0] = mem;
- }
- ops[1] = reg;
- break;
-
- case PRE_DEC:
- /* We have to use vldm / vstm in this case, since there is no
- pre-decrement form of the vld1 / vst1 instructions. */
- 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 ();
-
- case LABEL_REF:
- case PLUS:
- {
- int i;
- int overlap = -1;
- for (i = 0; i < nregs; i++)
- {
- /* 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, DImode, 8 * i);
- if (reg_overlap_mentioned_p (ops[0], mem))
- {
- gcc_assert (overlap == -1);
- overlap = i;
- }
- else
- {
- sprintf (buff, "v%sr%%?\t%%P0, %%1", load ? "ld" : "st");
- output_asm_insn (buff, ops);
- }
- }
- if (overlap != -1)
- {
- ops[0] = gen_rtx_REG (DImode, REGNO (reg) + 2 * overlap);
- ops[1] = adjust_address (mem, SImode, 8 * overlap);
- sprintf (buff, "v%sr%%?\t%%P0, %%1", load ? "ld" : "st");
- output_asm_insn (buff, ops);
- }
-
- return "";
- }
-
- default:
- /* We have to use vldm / vstm for too-large modes. */
- if (nregs > 4)
- templ = "v%smia%%?\t%%m0, %%h1";
- else
- templ = "v%s1.64\t%%h1, %%A0";
-
- ops[0] = mem;
- ops[1] = reg;
- }
-
- sprintf (buff, templ, load ? "ld" : "st");
- output_asm_insn (buff, ops);
-
- return "";
-}
-
-/* Compute and return the length of neon_mov<mode>, where <mode> is
- one of VSTRUCT modes: EI, OI, CI or XI. */
-int
-arm_attr_length_move_neon (rtx insn)
-{
- rtx reg, mem, addr;
- int load;
- enum machine_mode mode;
-
- extract_insn_cached (insn);
-
- if (REG_P (recog_data.operand[0]) && REG_P (recog_data.operand[1]))
- {
- mode = GET_MODE (recog_data.operand[0]);
- switch (mode)
- {
- case EImode:
- case OImode:
- return 8;
- case CImode:
- return 12;
- case XImode:
- return 16;
- default:
- gcc_unreachable ();
- }
- }
-
- load = REG_P (recog_data.operand[0]);
- reg = recog_data.operand[!load];
- mem = recog_data.operand[load];
-
- gcc_assert (MEM_P (mem));
-
- mode = GET_MODE (reg);
- addr = XEXP (mem, 0);
-
- /* Strip off const from addresses like (const (plus (...))). */
- if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == PLUS)
- addr = XEXP (addr, 0);
-
- if (GET_CODE (addr) == LABEL_REF || GET_CODE (addr) == PLUS)
- {
- int insns = HARD_REGNO_NREGS (REGNO (reg), mode) / 2;
- return insns * 4;
- }
- else
- return 4;
-}
-
-/* Return nonzero if the offset in the address is an immediate. Otherwise,
- return zero. */
-
-int
-arm_address_offset_is_imm (rtx insn)
-{
- rtx mem, addr;
-
- extract_insn_cached (insn);
-
- if (REG_P (recog_data.operand[0]))
- return 0;
-
- mem = recog_data.operand[0];
-
- gcc_assert (MEM_P (mem));
-
- addr = XEXP (mem, 0);
-
- if (REG_P (addr)
- || (GET_CODE (addr) == PLUS
- && REG_P (XEXP (addr, 0))
- && CONST_INT_P (XEXP (addr, 1))))
- return 1;
- else
- return 0;
-}
-
-/* Output an ADD r, s, #n where n may be too big for one instruction.
- If adding zero to one register, output nothing. */
-const char *
-output_add_immediate (rtx *operands)
-{
- HOST_WIDE_INT n = INTVAL (operands[2]);
-
- if (n != 0 || REGNO (operands[0]) != REGNO (operands[1]))
- {
- if (n < 0)
- output_multi_immediate (operands,
- "sub%?\t%0, %1, %2", "sub%?\t%0, %0, %2", 2,
- -n);
- else
- output_multi_immediate (operands,
- "add%?\t%0, %1, %2", "add%?\t%0, %0, %2", 2,
- n);
- }
-
- return "";
-}
-
-/* Output a multiple immediate operation.
- OPERANDS is the vector of operands referred to in the output patterns.
- INSTR1 is the output pattern to use for the first constant.
- INSTR2 is the output pattern to use for subsequent constants.
- IMMED_OP is the index of the constant slot in OPERANDS.
- N is the constant value. */
-static const char *
-output_multi_immediate (rtx *operands, const char *instr1, const char *instr2,
- int immed_op, HOST_WIDE_INT n)
-{
-#if HOST_BITS_PER_WIDE_INT > 32
- n &= 0xffffffff;
-#endif
-
- if (n == 0)
- {
- /* Quick and easy output. */
- operands[immed_op] = const0_rtx;
- output_asm_insn (instr1, operands);
- }
- else
- {
- int i;
- const char * instr = instr1;
-
- /* Note that n is never zero here (which would give no output). */
- for (i = 0; i < 32; i += 2)
- {
- if (n & (3 << i))
- {
- operands[immed_op] = GEN_INT (n & (255 << i));
- output_asm_insn (instr, operands);
- instr = instr2;
- i += 6;
- }
- }
- }
-
- return "";
-}
-
-/* Return the name of a shifter operation. */
-static const char *
-arm_shift_nmem(enum rtx_code code)
-{
- switch (code)
- {
- case ASHIFT:
- return ARM_LSL_NAME;
-
- case ASHIFTRT:
- return "asr";
-
- case LSHIFTRT:
- return "lsr";
-
- case ROTATERT:
- return "ror";
-
- default:
- abort();
- }
-}
-
-/* Return the appropriate ARM instruction for the operation code.
- The returned result should not be overwritten. OP is the rtx of the
- operation. SHIFT_FIRST_ARG is TRUE if the first argument of the operator
- was shifted. */
-const char *
-arithmetic_instr (rtx op, int shift_first_arg)
-{
- switch (GET_CODE (op))
- {
- case PLUS:
- return "add";
-
- case MINUS:
- return shift_first_arg ? "rsb" : "sub";
-
- case IOR:
- return "orr";
-
- case XOR:
- return "eor";
-
- case AND:
- return "and";
-
- case ASHIFT:
- case ASHIFTRT:
- case LSHIFTRT:
- case ROTATERT:
- return arm_shift_nmem(GET_CODE(op));
-
- default:
- gcc_unreachable ();
- }
-}
-
-/* Ensure valid constant shifts and return the appropriate shift mnemonic
- for the operation code. The returned result should not be overwritten.
- OP is the rtx code of the shift.
- On exit, *AMOUNTP will be -1 if the shift is by a register, or a constant
- shift. */
-static const char *
-shift_op (rtx op, HOST_WIDE_INT *amountp)
-{
- const char * mnem;
- enum rtx_code code = GET_CODE (op);
-
- switch (code)
- {
- case ROTATE:
- if (!CONST_INT_P (XEXP (op, 1)))
- {
- output_operand_lossage ("invalid shift operand");
- return NULL;
- }
-
- code = ROTATERT;
- *amountp = 32 - INTVAL (XEXP (op, 1));
- mnem = "ror";
- break;
-
- case ASHIFT:
- case ASHIFTRT:
- case LSHIFTRT:
- case ROTATERT:
- mnem = arm_shift_nmem(code);
- if (CONST_INT_P (XEXP (op, 1)))
- {
- *amountp = INTVAL (XEXP (op, 1));
- }
- else if (REG_P (XEXP (op, 1)))
- {
- *amountp = -1;
- return mnem;
- }
- else
- {
- output_operand_lossage ("invalid shift operand");
- return NULL;
- }
- break;
-
- case MULT:
- /* We never have to worry about the amount being other than a
- power of 2, since this case can never be reloaded from a reg. */
- if (!CONST_INT_P (XEXP (op, 1)))
- {
- output_operand_lossage ("invalid shift operand");
- return NULL;
- }
-
- *amountp = INTVAL (XEXP (op, 1)) & 0xFFFFFFFF;
-
- /* Amount must be a power of two. */
- if (*amountp & (*amountp - 1))
- {
- output_operand_lossage ("invalid shift operand");
- return NULL;
- }
-
- *amountp = int_log2 (*amountp);
- return ARM_LSL_NAME;
-
- default:
- output_operand_lossage ("invalid shift operand");
- return NULL;
- }
-
- /* This is not 100% correct, but follows from the desire to merge
- multiplication by a power of 2 with the recognizer for a
- shift. >=32 is not a valid shift for "lsl", so we must try and
- output a shift that produces the correct arithmetical result.
- Using lsr #32 is identical except for the fact that the carry bit
- is not set correctly if we set the flags; but we never use the
- carry bit from such an operation, so we can ignore that. */
- if (code == ROTATERT)
- /* Rotate is just modulo 32. */
- *amountp &= 31;
- else if (*amountp != (*amountp & 31))
- {
- if (code == ASHIFT)
- mnem = "lsr";
- *amountp = 32;
- }
-
- /* Shifts of 0 are no-ops. */
- if (*amountp == 0)
- return NULL;
-
- return mnem;
-}
-
-/* Obtain the shift from the POWER of two. */
-
-static HOST_WIDE_INT
-int_log2 (HOST_WIDE_INT power)
-{
- HOST_WIDE_INT shift = 0;
-
- while ((((HOST_WIDE_INT) 1 << shift) & power) == 0)
- {
- gcc_assert (shift <= 31);
- shift++;
- }
-
- return shift;
-}
-
-/* Output a .ascii pseudo-op, keeping track of lengths. This is
- because /bin/as is horribly restrictive. The judgement about
- whether or not each character is 'printable' (and can be output as
- is) or not (and must be printed with an octal escape) must be made
- with reference to the *host* character set -- the situation is
- similar to that discussed in the comments above pp_c_char in
- c-pretty-print.c. */
-
-#define MAX_ASCII_LEN 51
-
-void
-output_ascii_pseudo_op (FILE *stream, const unsigned char *p, int len)
-{
- int i;
- int len_so_far = 0;
-
- fputs ("\t.ascii\t\"", stream);
-
- for (i = 0; i < len; i++)
- {
- int c = p[i];
-
- if (len_so_far >= MAX_ASCII_LEN)
- {
- fputs ("\"\n\t.ascii\t\"", stream);
- len_so_far = 0;
- }
-
- if (ISPRINT (c))
- {
- if (c == '\\' || c == '\"')
- {
- putc ('\\', stream);
- len_so_far++;
- }
- putc (c, stream);
- len_so_far++;
- }
- else
- {
- fprintf (stream, "\\%03o", c);
- len_so_far += 4;
- }
- }
-
- fputs ("\"\n", stream);
-}
-
-/* Compute the register save mask for registers 0 through 12
- inclusive. This code is used by arm_compute_save_reg_mask. */
-
-static unsigned long
-arm_compute_save_reg0_reg12_mask (void)
-{
- unsigned long func_type = arm_current_func_type ();
- unsigned long save_reg_mask = 0;
- unsigned int reg;
-
- if (IS_INTERRUPT (func_type))
- {
- unsigned int max_reg;
- /* 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. */
- if (ARM_FUNC_TYPE (func_type) == ARM_FT_FIQ)
- /* FIQ handlers have registers r8 - r12 banked, so
- we only need to check r0 - r7, Normal ISRs only
- bank r14 and r15, so we must check up to r12.
- r13 is the stack pointer which is always preserved,
- so we do not need to consider it here. */
- max_reg = 7;
- else
- max_reg = 12;
-
- for (reg = 0; reg <= max_reg; reg++)
- if (df_regs_ever_live_p (reg)
- || (! crtl->is_leaf && call_used_regs[reg]))
- save_reg_mask |= (1 << reg);
-
- /* Also save the pic base register if necessary. */
- if (flag_pic
- && !TARGET_SINGLE_PIC_BASE
- && arm_pic_register != INVALID_REGNUM
- && crtl->uses_pic_offset_table)
- save_reg_mask |= 1 << PIC_OFFSET_TABLE_REGNUM;
- }
- else if (IS_VOLATILE(func_type))
- {
- /* For noreturn functions we historically omitted register saves
- altogether. However this really messes up debugging. As a
- compromise save just the frame pointers. Combined with the link
- register saved elsewhere this should be sufficient to get
- a backtrace. */
- if (frame_pointer_needed)
- save_reg_mask |= 1 << HARD_FRAME_POINTER_REGNUM;
- if (df_regs_ever_live_p (ARM_HARD_FRAME_POINTER_REGNUM))
- save_reg_mask |= 1 << ARM_HARD_FRAME_POINTER_REGNUM;
- if (df_regs_ever_live_p (THUMB_HARD_FRAME_POINTER_REGNUM))
- save_reg_mask |= 1 << THUMB_HARD_FRAME_POINTER_REGNUM;
- }
- else
- {
- /* 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 <= 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 (frame_pointer_needed)
- save_reg_mask |= 1 << HARD_FRAME_POINTER_REGNUM;
-
- /* If we aren't loading the PIC register,
- don't stack it even though it may be live. */
- if (flag_pic
- && !TARGET_SINGLE_PIC_BASE
- && arm_pic_register != INVALID_REGNUM
- && (df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM)
- || crtl->uses_pic_offset_table))
- save_reg_mask |= 1 << PIC_OFFSET_TABLE_REGNUM;
-
- /* The prologue will copy SP into R0, so save it. */
- if (IS_STACKALIGN (func_type))
- save_reg_mask |= 1;
- }
-
- /* Save registers so the exception handler can modify them. */
- if (crtl->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 << reg;
- }
- }
-
- return save_reg_mask;
-}
-
-
-/* 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) && crtl->args.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.
- This is used by arm_get_frame_offsets, which may add extra registers. */
-
-static unsigned long
-arm_compute_save_reg_mask (void)
-{
- unsigned int save_reg_mask = 0;
- unsigned long func_type = arm_current_func_type ();
- unsigned int reg;
-
- if (IS_NAKED (func_type))
- /* This should never really happen. */
- return 0;
-
- /* 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 (TARGET_APCS_FRAME && frame_pointer_needed && TARGET_ARM)
- save_reg_mask |=
- (1 << ARM_HARD_FRAME_POINTER_REGNUM)
- | (1 << IP_REGNUM)
- | (1 << LR_REGNUM)
- | (1 << PC_REGNUM);
-
- save_reg_mask |= arm_compute_save_reg0_reg12_mask ();
-
- /* Decide if we need to save the link register.
- Interrupt routines have their own banked link register,
- so they never need to save it.
- Otherwise if we do not use the link register we do not need to save
- it. If we are pushing other registers onto the stack however, we
- can save an instruction in the epilogue by pushing the link register
- now and then popping it back into the PC. This incurs extra memory
- accesses though, so we only do it when optimizing for size, and only
- if we know that we will not need a fancy return sequence. */
- if (df_regs_ever_live_p (LR_REGNUM)
- || (save_reg_mask
- && optimize_size
- && ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL
- && !crtl->calls_eh_return))
- save_reg_mask |= 1 << LR_REGNUM;
-
- if (cfun->machine->lr_save_eliminated)
- save_reg_mask &= ~ (1 << LR_REGNUM);
-
- if (TARGET_REALLY_IWMMXT
- && ((bit_count (save_reg_mask)
- + ARM_NUM_INTS (crtl->args.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
- is 64-bit aligned before we start to save iWMMXt registers,
- and also before we start to create locals. (A local variable
- might be a double or long long which we will load/store using
- an iWMMXt instruction). Therefore we need to push another
- ARM register, so that the stack will be 64-bit aligned. We
- try to avoid using the arg registers (r0 -r3) as they might be
- used to pass values in a tail call. */
- for (reg = 4; reg <= 12; reg++)
- if ((save_reg_mask & (1 << reg)) == 0)
- break;
-
- if (reg <= 12)
- save_reg_mask |= (1 << reg);
- else
- {
- cfun->machine->sibcall_blocked = 1;
- save_reg_mask |= (1 << 3);
- }
- }
-
- /* We may need to push an additional register for use initializing the
- PIC base register. */
- if (TARGET_THUMB2 && IS_NESTED (func_type) && flag_pic
- && (save_reg_mask & THUMB2_WORK_REGS) == 0)
- {
- reg = thumb_find_work_register (1 << 4);
- if (!call_used_regs[reg])
- save_reg_mask |= (1 << reg);
- }
-
- return save_reg_mask;
-}
-
-
-/* Compute a bit mask of which registers need to be
- saved on the stack for the current function. */
-static unsigned long
-thumb1_compute_save_reg_mask (void)
-{
- unsigned long mask;
- unsigned reg;
-
- mask = 0;
- for (reg = 0; reg < 12; reg ++)
- if (df_regs_ever_live_p (reg) && !call_used_regs[reg])
- mask |= 1 << reg;
-
- if (flag_pic
- && !TARGET_SINGLE_PIC_BASE
- && arm_pic_register != INVALID_REGNUM
- && crtl->uses_pic_offset_table)
- mask |= 1 << PIC_OFFSET_TABLE_REGNUM;
-
- /* See if we might need r11 for calls to _interwork_r11_call_via_rN(). */
- if (!frame_pointer_needed && CALLER_INTERWORKING_SLOT_SIZE > 0)
- mask |= 1 << ARM_HARD_FRAME_POINTER_REGNUM;
-
- /* LR will also be pushed if any lo regs are pushed. */
- if (mask & 0xff || thumb_force_lr_save ())
- mask |= (1 << LR_REGNUM);
-
- /* Make sure we have a low work register if we need one.
- We will need one if we are going to push a high register,
- but we are not currently intending to push a low register. */
- if ((mask & 0xff) == 0
- && ((mask & 0x0f00) || TARGET_BACKTRACE))
- {
- /* Use thumb_find_work_register to choose which register
- we will use. If the register is live then we will
- have to push it. Use LAST_LO_REGNUM as our fallback
- choice for the register to select. */
- 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 <= (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 ()) +
- crtl->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;
-}
-
-
-/* Return the number of bytes required to save VFP registers. */
-static int
-arm_get_vfp_saved_size (void)
-{
- unsigned int regno;
- int count;
- int saved;
-
- saved = 0;
- /* Space for saved VFP registers. */
- if (TARGET_HARD_FLOAT && TARGET_VFP)
- {
- count = 0;
- for (regno = FIRST_VFP_REGNUM;
- regno < LAST_VFP_REGNUM;
- regno += 2)
- {
- if ((!df_regs_ever_live_p (regno) || call_used_regs[regno])
- && (!df_regs_ever_live_p (regno + 1) || call_used_regs[regno + 1]))
- {
- if (count > 0)
- {
- /* Workaround ARM10 VFPr1 bug. */
- if (count == 2 && !arm_arch6)
- count++;
- saved += count * 8;
- }
- count = 0;
- }
- else
- count++;
- }
- if (count > 0)
- {
- if (count == 2 && !arm_arch6)
- count++;
- saved += count * 8;
- }
- }
- return saved;
-}
-
-
-/* Generate a function exit sequence. If REALLY_RETURN is false, then do
- everything bar the final return instruction. If simple_return is true,
- then do not output epilogue, because it has already been emitted in RTL. */
-const char *
-output_return_instruction (rtx operand, bool really_return, bool reverse,
- bool simple_return)
-{
- char conditional[10];
- char instr[100];
- unsigned reg;
- unsigned long live_regs_mask;
- unsigned long func_type;
- arm_stack_offsets *offsets;
-
- func_type = arm_current_func_type ();
-
- if (IS_NAKED (func_type))
- return "";
-
- if (IS_VOLATILE (func_type) && TARGET_ABORT_NORETURN)
- {
- /* If this function was declared non-returning, and we have
- found a tail call, then we have to trust that the called
- function won't return. */
- if (really_return)
- {
- rtx ops[2];
-
- /* Otherwise, trap an attempted return by aborting. */
- ops[0] = operand;
- ops[1] = gen_rtx_SYMBOL_REF (Pmode, NEED_PLT_RELOC ? "abort(PLT)"
- : "abort");
- assemble_external_libcall (ops[1]);
- output_asm_insn (reverse ? "bl%D0\t%a1" : "bl%d0\t%a1", ops);
- }
-
- return "";
- }
-
- gcc_assert (!cfun->calls_alloca || really_return);
-
- sprintf (conditional, "%%?%%%c0", reverse ? 'D' : 'd');
-
- cfun->machine->return_used_this_function = 1;
-
- offsets = arm_get_frame_offsets ();
- live_regs_mask = offsets->saved_regs_mask;
-
- if (!simple_return && live_regs_mask)
- {
- const char * return_reg;
-
- /* If we do not have any special requirements for function exit
- (e.g. interworking) then we can load the return address
- directly into the PC. Otherwise we must load it into LR. */
- if (really_return
- && (IS_INTERRUPT (func_type) || !TARGET_INTERWORK))
- return_reg = reg_names[PC_REGNUM];
- else
- return_reg = reg_names[LR_REGNUM];
-
- if ((live_regs_mask & (1 << IP_REGNUM)) == (1 << IP_REGNUM))
- {
- /* There are three possible reasons for the IP register
- being saved. 1) a stack frame was created, in which case
- IP contains the old stack pointer, or 2) an ISR routine
- corrupted it, or 3) it was saved to align the stack on
- iWMMXt. In case 1, restore IP into SP, otherwise just
- restore IP. */
- if (frame_pointer_needed)
- {
- live_regs_mask &= ~ (1 << IP_REGNUM);
- live_regs_mask |= (1 << SP_REGNUM);
- }
- else
- gcc_assert (IS_INTERRUPT (func_type) || TARGET_REALLY_IWMMXT);
- }
-
- /* On some ARM architectures it is faster to use LDR rather than
- LDM to load a single register. On other architectures, the
- cost is the same. In 26 bit mode, or for exception handlers,
- we have to use LDM to load the PC so that the CPSR is also
- restored. */
- for (reg = 0; reg <= LAST_ARM_REGNUM; reg++)
- if (live_regs_mask == (1U << reg))
- break;
-
- if (reg <= LAST_ARM_REGNUM
- && (reg != LR_REGNUM
- || ! really_return
- || ! IS_INTERRUPT (func_type)))
- {
- sprintf (instr, "ldr%s\t%%|%s, [%%|sp], #4", conditional,
- (reg == LR_REGNUM) ? return_reg : reg_names[reg]);
- }
- else
- {
- char *p;
- int first = 1;
-
- /* Generate the load multiple instruction to restore the
- registers. Note we can get here, even if
- frame_pointer_needed is true, but only if sp already
- points to the base of the saved core registers. */
- if (live_regs_mask & (1 << SP_REGNUM))
- {
- unsigned HOST_WIDE_INT stack_adjust;
-
- stack_adjust = offsets->outgoing_args - offsets->saved_regs;
- gcc_assert (stack_adjust == 0 || stack_adjust == 4);
-
- if (stack_adjust && arm_arch5 && TARGET_ARM)
- if (TARGET_UNIFIED_ASM)
- sprintf (instr, "ldmib%s\t%%|sp, {", conditional);
- else
- sprintf (instr, "ldm%sib\t%%|sp, {", conditional);
- else
- {
- /* If we can't use ldmib (SA110 bug),
- then try to pop r3 instead. */
- if (stack_adjust)
- live_regs_mask |= 1 << 3;
-
- if (TARGET_UNIFIED_ASM)
- sprintf (instr, "ldmfd%s\t%%|sp, {", conditional);
- else
- sprintf (instr, "ldm%sfd\t%%|sp, {", conditional);
- }
- }
- else
- if (TARGET_UNIFIED_ASM)
- sprintf (instr, "pop%s\t{", conditional);
- else
- sprintf (instr, "ldm%sfd\t%%|sp!, {", conditional);
-
- p = instr + strlen (instr);
-
- for (reg = 0; reg <= SP_REGNUM; reg++)
- if (live_regs_mask & (1 << reg))
- {
- int l = strlen (reg_names[reg]);
-
- if (first)
- first = 0;
- else
- {
- memcpy (p, ", ", 2);
- p += 2;
- }
-
- memcpy (p, "%|", 2);
- memcpy (p + 2, reg_names[reg], l);
- p += l + 2;
- }
-
- if (live_regs_mask & (1 << LR_REGNUM))
- {
- sprintf (p, "%s%%|%s}", first ? "" : ", ", return_reg);
- /* If returning from an interrupt, restore the CPSR. */
- if (IS_INTERRUPT (func_type))
- strcat (p, "^");
- }
- else
- strcpy (p, "}");
- }
-
- output_asm_insn (instr, & operand);
-
- /* See if we need to generate an extra instruction to
- perform the actual function return. */
- if (really_return
- && func_type != ARM_FT_INTERWORKED
- && (live_regs_mask & (1 << LR_REGNUM)) != 0)
- {
- /* The return has already been handled
- by loading the LR into the PC. */
- return "";
- }
- }
-
- if (really_return)
- {
- switch ((int) ARM_FUNC_TYPE (func_type))
- {
- case ARM_FT_ISR:
- case ARM_FT_FIQ:
- /* ??? This is wrong for unified assembly syntax. */
- sprintf (instr, "sub%ss\t%%|pc, %%|lr, #4", conditional);
- break;
-
- case ARM_FT_INTERWORKED:
- sprintf (instr, "bx%s\t%%|lr", conditional);
- break;
-
- case ARM_FT_EXCEPTION:
- /* ??? This is wrong for unified assembly syntax. */
- sprintf (instr, "mov%ss\t%%|pc, %%|lr", conditional);
- break;
-
- default:
- /* Use bx if it's available. */
- if (arm_arch5 || arm_arch4t)
- sprintf (instr, "bx%s\t%%|lr", conditional);
- else
- sprintf (instr, "mov%s\t%%|pc, %%|lr", conditional);
- break;
- }
-
- output_asm_insn (instr, & operand);
- }
-
- return "";
-}
-
-/* Write the function name into the code section, directly preceding
- the function prologue.
-
- Code will be output similar to this:
- t0
- .ascii "arm_poke_function_name", 0
- .align
- t1
- .word 0xff000000 + (t1 - t0)
- arm_poke_function_name
- mov ip, sp
- stmfd sp!, {fp, ip, lr, pc}
- sub fp, ip, #4
-
- When performing a stack backtrace, code can inspect the value
- of 'pc' stored at 'fp' + 0. If the trace function then looks
- at location pc - 12 and the top 8 bits are set, then we know
- that there is a function name embedded immediately preceding this
- location and has length ((pc[-3]) & 0xff000000).
-
- We assume that pc is declared as a pointer to an unsigned long.
-
- It is of no benefit to output the function name if we are assembling
- a leaf function. These function types will not contain a stack
- backtrace structure, therefore it is not possible to determine the
- function name. */
-void
-arm_poke_function_name (FILE *stream, const char *name)
-{
- unsigned long alignlength;
- unsigned long length;
- rtx x;
-
- length = strlen (name) + 1;
- alignlength = ROUND_UP_WORD (length);
-
- ASM_OUTPUT_ASCII (stream, name, length);
- ASM_OUTPUT_ALIGN (stream, 2);
- x = GEN_INT ((unsigned HOST_WIDE_INT) 0xff000000 + alignlength);
- assemble_aligned_integer (UNITS_PER_WORD, x);
-}
-
-/* Place some comments into the assembler stream
- describing the current function. */
-static void
-arm_output_function_prologue (FILE *f, HOST_WIDE_INT frame_size)
-{
- unsigned long func_type;
-
- /* ??? Do we want to print some of the below anyway? */
- if (TARGET_THUMB1)
- return;
-
- /* Sanity check. */
- gcc_assert (!arm_ccfsm_state && !arm_target_insn);
-
- func_type = arm_current_func_type ();
-
- switch ((int) ARM_FUNC_TYPE (func_type))
- {
- default:
- case ARM_FT_NORMAL:
- break;
- case ARM_FT_INTERWORKED:
- asm_fprintf (f, "\t%@ Function supports interworking.\n");
- break;
- case ARM_FT_ISR:
- asm_fprintf (f, "\t%@ Interrupt Service Routine.\n");
- break;
- case ARM_FT_FIQ:
- asm_fprintf (f, "\t%@ Fast Interrupt Service Routine.\n");
- break;
- case ARM_FT_EXCEPTION:
- asm_fprintf (f, "\t%@ ARM Exception Handler.\n");
- break;
- }
-
- if (IS_NAKED (func_type))
- asm_fprintf (f, "\t%@ Naked Function: prologue and epilogue provided by programmer.\n");
-
- if (IS_VOLATILE (func_type))
- asm_fprintf (f, "\t%@ Volatile: function does not return.\n");
-
- if (IS_NESTED (func_type))
- asm_fprintf (f, "\t%@ Nested: function declared inside another function.\n");
- if (IS_STACKALIGN (func_type))
- asm_fprintf (f, "\t%@ Stack Align: May be called with mis-aligned SP.\n");
-
- asm_fprintf (f, "\t%@ args = %d, pretend = %d, frame = %wd\n",
- crtl->args.size,
- crtl->args.pretend_args_size, frame_size);
-
- asm_fprintf (f, "\t%@ frame_needed = %d, uses_anonymous_args = %d\n",
- frame_pointer_needed,
- cfun->machine->uses_anonymous_args);
-
- if (cfun->machine->lr_save_eliminated)
- asm_fprintf (f, "\t%@ link register save eliminated.\n");
-
- if (crtl->calls_eh_return)
- asm_fprintf (f, "\t@ Calls __builtin_eh_return.\n");
-
-}
-
-static void
-arm_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
- HOST_WIDE_INT frame_size ATTRIBUTE_UNUSED)
-{
- arm_stack_offsets *offsets;
-
- if (TARGET_THUMB1)
- {
- int regno;
-
- /* Emit any call-via-reg trampolines that are needed for v4t support
- of call_reg and call_value_reg type insns. */
- for (regno = 0; regno < LR_REGNUM; regno++)
- {
- rtx label = cfun->machine->call_via[regno];
-
- if (label != NULL)
- {
- switch_to_section (function_section (current_function_decl));
- targetm.asm_out.internal_label (asm_out_file, "L",
- CODE_LABEL_NUMBER (label));
- asm_fprintf (asm_out_file, "\tbx\t%r\n", regno);
- }
- }
-
- /* ??? Probably not safe to set this here, since it assumes that a
- function will be emitted as assembly immediately after we generate
- RTL for it. This does not happen for inline functions. */
- cfun->machine->return_used_this_function = 0;
- }
- else /* TARGET_32BIT */
- {
- /* We need to take into account any stack-frame rounding. */
- offsets = arm_get_frame_offsets ();
-
- gcc_assert (!use_return_insn (FALSE, NULL)
- || (cfun->machine->return_used_this_function != 0)
- || offsets->saved_regs == offsets->outgoing_args
- || frame_pointer_needed);
-
- /* Reset the ARM-specific per-function variables. */
- after_arm_reorg = 0;
- }
-}
-
-/* Generate and emit a pattern that will be recognized as STRD pattern. If even
- number of registers are being pushed, multiple STRD patterns are created for
- all register pairs. If odd number of registers are pushed, emit a
- combination of STRDs and STR for the prologue saves. */
-static void
-thumb2_emit_strd_push (unsigned long saved_regs_mask)
-{
- int num_regs = 0;
- int i, j;
- rtx par = NULL_RTX;
- rtx insn = NULL_RTX;
- rtx dwarf = NULL_RTX;
- rtx tmp, reg, tmp1;
-
- for (i = 0; i <= LAST_ARM_REGNUM; i++)
- if (saved_regs_mask & (1 << i))
- num_regs++;
-
- gcc_assert (num_regs && num_regs <= 16);
-
- /* Pre-decrement the stack pointer, based on there being num_regs 4-byte
- registers to push. */
- tmp = gen_rtx_SET (VOIDmode,
- stack_pointer_rtx,
- plus_constant (Pmode, stack_pointer_rtx, -4 * num_regs));
- RTX_FRAME_RELATED_P (tmp) = 1;
- insn = emit_insn (tmp);
-
- /* Create sequence for DWARF info. */
- dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (num_regs + 1));
-
- /* RTLs cannot be shared, hence create new copy for dwarf. */
- tmp1 = gen_rtx_SET (VOIDmode,
- stack_pointer_rtx,
- plus_constant (Pmode, stack_pointer_rtx, -4 * num_regs));
- RTX_FRAME_RELATED_P (tmp1) = 1;
- XVECEXP (dwarf, 0, 0) = tmp1;
-
- gcc_assert (!(saved_regs_mask & (1 << SP_REGNUM)));
- gcc_assert (!(saved_regs_mask & (1 << PC_REGNUM)));
-
- /* Var j iterates over all the registers to gather all the registers in
- saved_regs_mask. Var i gives index of register R_j in stack frame.
- A PARALLEL RTX of register-pair is created here, so that pattern for
- STRD can be matched. If num_regs is odd, 1st register will be pushed
- using STR and remaining registers will be pushed with STRD in pairs.
- If num_regs is even, all registers are pushed with STRD in pairs.
- Hence, skip first element for odd num_regs. */
- for (i = num_regs - 1, j = LAST_ARM_REGNUM; i >= (num_regs % 2); j--)
- if (saved_regs_mask & (1 << j))
- {
- /* Create RTX for store. New RTX is created for dwarf as
- they are not sharable. */
- reg = gen_rtx_REG (SImode, j);
- tmp = gen_rtx_SET (SImode,
- gen_frame_mem
- (SImode,
- plus_constant (Pmode, stack_pointer_rtx, 4 * i)),
- reg);
-
- tmp1 = gen_rtx_SET (SImode,
- gen_frame_mem
- (SImode,
- plus_constant (Pmode, stack_pointer_rtx, 4 * i)),
- reg);
- RTX_FRAME_RELATED_P (tmp) = 1;
- RTX_FRAME_RELATED_P (tmp1) = 1;
-
- if (((i - (num_regs % 2)) % 2) == 1)
- /* When (i - (num_regs % 2)) is odd, the RTX to be emitted is yet to
- be created. Hence create it first. The STRD pattern we are
- generating is :
- [ (SET (MEM (PLUS (SP) (NUM))) (reg_t1))
- (SET (MEM (PLUS (SP) (NUM + 4))) (reg_t2)) ]
- where the target registers need not be consecutive. */
- par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
-
- /* Register R_j is added in PARALLEL RTX. If (i - (num_regs % 2)) is
- even, the reg_j is added as 0th element and if it is odd, reg_i is
- added as 1st element of STRD pattern shown above. */
- XVECEXP (par, 0, ((i - (num_regs % 2)) % 2)) = tmp;
- XVECEXP (dwarf, 0, (i + 1)) = tmp1;
-
- if (((i - (num_regs % 2)) % 2) == 0)
- /* When (i - (num_regs % 2)) is even, RTXs for both the registers
- to be loaded are generated in above given STRD pattern, and the
- pattern can be emitted now. */
- emit_insn (par);
-
- i--;
- }
-
- if ((num_regs % 2) == 1)
- {
- /* If odd number of registers are pushed, generate STR pattern to store
- lone register. */
- for (; (saved_regs_mask & (1 << j)) == 0; j--);
-
- tmp1 = gen_frame_mem (SImode, plus_constant (Pmode,
- stack_pointer_rtx, 4 * i));
- reg = gen_rtx_REG (SImode, j);
- tmp = gen_rtx_SET (SImode, tmp1, reg);
- RTX_FRAME_RELATED_P (tmp) = 1;
-
- emit_insn (tmp);
-
- tmp1 = gen_rtx_SET (SImode,
- gen_frame_mem
- (SImode,
- plus_constant (Pmode, stack_pointer_rtx, 4 * i)),
- reg);
- RTX_FRAME_RELATED_P (tmp1) = 1;
- XVECEXP (dwarf, 0, (i + 1)) = tmp1;
- }
-
- add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
- RTX_FRAME_RELATED_P (insn) = 1;
- return;
-}
-
-/* Generate and emit an insn that we will recognize as a push_multi.
- 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. */
-static rtx
-emit_multi_reg_push (unsigned long mask)
-{
- int num_regs = 0;
- int num_dwarf_regs;
- int i, j;
- rtx par;
- rtx dwarf;
- int dwarf_par_index;
- rtx tmp, reg;
-
- for (i = 0; i <= LAST_ARM_REGNUM; i++)
- if (mask & (1 << i))
- num_regs++;
-
- gcc_assert (num_regs && num_regs <= 16);
-
- /* We don't record the PC in the dwarf frame information. */
- num_dwarf_regs = num_regs;
- if (mask & (1 << PC_REGNUM))
- num_dwarf_regs--;
-
- /* For the body of the insn we are going to generate an UNSPEC in
- parallel with several USEs. This allows the insn to be recognized
- by the push_multi pattern in the arm.md file.
-
- The body of the insn looks something like this:
-
- (parallel [
- (set (mem:BLK (pre_modify:SI (reg:SI sp)
- (const_int:SI <num>)))
- (unspec:BLK [(reg:SI r4)] UNSPEC_PUSH_MULT))
- (use (reg:SI XX))
- (use (reg:SI YY))
- ...
- ])
-
- For the frame note however, we try to be more explicit and actually
- show each register being stored into the stack frame, plus a (single)
- decrement of the stack pointer. We do it this way in order to be
- friendly to the stack unwinding code, which only wants to see a single
- stack decrement per instruction. The RTL we generate for the note looks
- something like this:
-
- (sequence [
- (set (reg:SI sp) (plus:SI (reg:SI sp) (const_int -20)))
- (set (mem:SI (reg:SI sp)) (reg:SI r4))
- (set (mem:SI (plus:SI (reg:SI sp) (const_int 4))) (reg:SI XX))
- (set (mem:SI (plus:SI (reg:SI sp) (const_int 8))) (reg:SI YY))
- ...
- ])
-
- FIXME:: In an ideal world the PRE_MODIFY would not exist and
- instead we'd have a parallel expression detailing all
- the stores to the various memory addresses so that debug
- information is more up-to-date. Remember however while writing
- this to take care of the constraints with the push instruction.
-
- Note also that this has to be taken care of for the VFP registers.
-
- For more see PR43399. */
-
- par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num_regs));
- dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (num_dwarf_regs + 1));
- dwarf_par_index = 1;
-
- for (i = 0; i <= LAST_ARM_REGNUM; i++)
- {
- if (mask & (1 << i))
- {
- reg = gen_rtx_REG (SImode, i);
-
- XVECEXP (par, 0, 0)
- = gen_rtx_SET (VOIDmode,
- gen_frame_mem
- (BLKmode,
- gen_rtx_PRE_MODIFY (Pmode,
- stack_pointer_rtx,
- plus_constant
- (Pmode, stack_pointer_rtx,
- -4 * num_regs))
- ),
- gen_rtx_UNSPEC (BLKmode,
- gen_rtvec (1, reg),
- UNSPEC_PUSH_MULT));
-
- if (i != PC_REGNUM)
- {
- tmp = gen_rtx_SET (VOIDmode,
- gen_frame_mem (SImode, stack_pointer_rtx),
- reg);
- RTX_FRAME_RELATED_P (tmp) = 1;
- XVECEXP (dwarf, 0, dwarf_par_index) = tmp;
- dwarf_par_index++;
- }
-
- break;
- }
- }
-
- for (j = 1, i++; j < num_regs; i++)
- {
- if (mask & (1 << i))
- {
- reg = gen_rtx_REG (SImode, i);
-
- XVECEXP (par, 0, j) = gen_rtx_USE (VOIDmode, reg);
-
- if (i != PC_REGNUM)
- {
- tmp
- = gen_rtx_SET (VOIDmode,
- gen_frame_mem
- (SImode,
- plus_constant (Pmode, stack_pointer_rtx,
- 4 * j)),
- reg);
- RTX_FRAME_RELATED_P (tmp) = 1;
- XVECEXP (dwarf, 0, dwarf_par_index++) = tmp;
- }
-
- j++;
- }
- }
-
- par = emit_insn (par);
-
- tmp = gen_rtx_SET (VOIDmode,
- stack_pointer_rtx,
- plus_constant (Pmode, stack_pointer_rtx, -4 * num_regs));
- RTX_FRAME_RELATED_P (tmp) = 1;
- XVECEXP (dwarf, 0, 0) = tmp;
-
- add_reg_note (par, REG_FRAME_RELATED_EXPR, dwarf);
-
- return par;
-}
-
-/* Generate and emit an insn pattern that we will recognize as a pop_multi.
- SAVED_REGS_MASK shows which registers need to be restored.
-
- 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. */
-static void
-arm_emit_multi_reg_pop (unsigned long saved_regs_mask)
-{
- int num_regs = 0;
- int i, j;
- rtx par;
- rtx dwarf = NULL_RTX;
- rtx tmp, reg;
- bool return_in_pc;
- int offset_adj;
- int emit_update;
-
- return_in_pc = (saved_regs_mask & (1 << PC_REGNUM)) ? true : false;
- offset_adj = return_in_pc ? 1 : 0;
- for (i = 0; i <= LAST_ARM_REGNUM; i++)
- if (saved_regs_mask & (1 << i))
- num_regs++;
-
- gcc_assert (num_regs && num_regs <= 16);
-
- /* If SP is in reglist, then we don't emit SP update insn. */
- emit_update = (saved_regs_mask & (1 << SP_REGNUM)) ? 0 : 1;
-
- /* The parallel needs to hold num_regs SETs
- and one SET for the stack update. */
- par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num_regs + emit_update + offset_adj));
-
- if (return_in_pc)
- {
- tmp = ret_rtx;
- XVECEXP (par, 0, 0) = tmp;
- }
-
- if (emit_update)
- {
- /* Increment the stack pointer, based on there being
- num_regs 4-byte registers to restore. */
- tmp = gen_rtx_SET (VOIDmode,
- stack_pointer_rtx,
- plus_constant (Pmode,
- stack_pointer_rtx,
- 4 * num_regs));
- RTX_FRAME_RELATED_P (tmp) = 1;
- XVECEXP (par, 0, offset_adj) = tmp;
- }
-
- /* Now restore every reg, which may include PC. */
- for (j = 0, i = 0; j < num_regs; i++)
- if (saved_regs_mask & (1 << i))
- {
- reg = gen_rtx_REG (SImode, i);
- tmp = gen_rtx_SET (VOIDmode,
- reg,
- gen_frame_mem
- (SImode,
- plus_constant (Pmode, stack_pointer_rtx, 4 * j)));
- RTX_FRAME_RELATED_P (tmp) = 1;
- XVECEXP (par, 0, j + emit_update + offset_adj) = tmp;
-
- /* We need to maintain a sequence for DWARF info too. As dwarf info
- should not have PC, skip PC. */
- if (i != PC_REGNUM)
- dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
-
- j++;
- }
-
- if (return_in_pc)
- par = emit_jump_insn (par);
- else
- par = emit_insn (par);
-
- REG_NOTES (par) = dwarf;
-}
-
-/* Generate and emit an insn pattern that we will recognize as a pop_multi
- of NUM_REGS consecutive VFP regs, starting at FIRST_REG.
-
- 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. */
-static void
-arm_emit_vfp_multi_reg_pop (int first_reg, int num_regs, rtx base_reg)
-{
- int i, j;
- rtx par;
- rtx dwarf = NULL_RTX;
- rtx tmp, reg;
-
- gcc_assert (num_regs && num_regs <= 32);
-
- /* Workaround ARM10 VFPr1 bug. */
- if (num_regs == 2 && !arm_arch6)
- {
- if (first_reg == 15)
- first_reg--;
-
- num_regs++;
- }
-
- /* We can emit at most 16 D-registers in a single pop_multi instruction, and
- there could be up to 32 D-registers to restore.
- If there are more than 16 D-registers, make two recursive calls,
- each of which emits one pop_multi instruction. */
- if (num_regs > 16)
- {
- arm_emit_vfp_multi_reg_pop (first_reg, 16, base_reg);
- arm_emit_vfp_multi_reg_pop (first_reg + 16, num_regs - 16, base_reg);
- return;
- }
-
- /* The parallel needs to hold num_regs SETs
- and one SET for the stack update. */
- par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num_regs + 1));
-
- /* Increment the stack pointer, based on there being
- num_regs 8-byte registers to restore. */
- tmp = gen_rtx_SET (VOIDmode,
- base_reg,
- plus_constant (Pmode, base_reg, 8 * num_regs));
- RTX_FRAME_RELATED_P (tmp) = 1;
- XVECEXP (par, 0, 0) = tmp;
-
- /* Now show every reg that will be restored, using a SET for each. */
- for (j = 0, i=first_reg; j < num_regs; i += 2)
- {
- reg = gen_rtx_REG (DFmode, i);
-
- tmp = gen_rtx_SET (VOIDmode,
- reg,
- gen_frame_mem
- (DFmode,
- plus_constant (Pmode, base_reg, 8 * j)));
- RTX_FRAME_RELATED_P (tmp) = 1;
- XVECEXP (par, 0, j + 1) = tmp;
-
- dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
-
- j++;
- }
-
- par = emit_insn (par);
- REG_NOTES (par) = dwarf;
-}
-
-/* Generate and emit a pattern that will be recognized as LDRD pattern. If even
- number of registers are being popped, multiple LDRD patterns are created for
- all register pairs. If odd number of registers are popped, last register is
- loaded by using LDR pattern. */
-static void
-thumb2_emit_ldrd_pop (unsigned long saved_regs_mask)
-{
- int num_regs = 0;
- int i, j;
- rtx par = NULL_RTX;
- rtx dwarf = NULL_RTX;
- rtx tmp, reg, tmp1;
- bool return_in_pc;
-
- return_in_pc = (saved_regs_mask & (1 << PC_REGNUM)) ? true : false;
- for (i = 0; i <= LAST_ARM_REGNUM; i++)
- if (saved_regs_mask & (1 << i))
- num_regs++;
-
- gcc_assert (num_regs && num_regs <= 16);
-
- /* We cannot generate ldrd for PC. Hence, reduce the count if PC is
- to be popped. So, if num_regs is even, now it will become odd,
- and we can generate pop with PC. If num_regs is odd, it will be
- even now, and ldr with return can be generated for PC. */
- if (return_in_pc)
- num_regs--;
-
- gcc_assert (!(saved_regs_mask & (1 << SP_REGNUM)));
-
- /* Var j iterates over all the registers to gather all the registers in
- saved_regs_mask. Var i gives index of saved registers in stack frame.
- A PARALLEL RTX of register-pair is created here, so that pattern for
- LDRD can be matched. As PC is always last register to be popped, and
- we have already decremented num_regs if PC, we don't have to worry
- about PC in this loop. */
- for (i = 0, j = 0; i < (num_regs - (num_regs % 2)); j++)
- if (saved_regs_mask & (1 << j))
- {
- /* Create RTX for memory load. */
- reg = gen_rtx_REG (SImode, j);
- tmp = gen_rtx_SET (SImode,
- reg,
- gen_frame_mem (SImode,
- plus_constant (Pmode,
- stack_pointer_rtx, 4 * i)));
- RTX_FRAME_RELATED_P (tmp) = 1;
-
- if (i % 2 == 0)
- {
- /* When saved-register index (i) is even, the RTX to be emitted is
- yet to be created. Hence create it first. The LDRD pattern we
- are generating is :
- [ (SET (reg_t0) (MEM (PLUS (SP) (NUM))))
- (SET (reg_t1) (MEM (PLUS (SP) (NUM + 4)))) ]
- where target registers need not be consecutive. */
- par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
- dwarf = NULL_RTX;
- }
-
- /* ith register is added in PARALLEL RTX. If i is even, the reg_i is
- added as 0th element and if i is odd, reg_i is added as 1st element
- of LDRD pattern shown above. */
- XVECEXP (par, 0, (i % 2)) = tmp;
- dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
-
- if ((i % 2) == 1)
- {
- /* When saved-register index (i) is odd, RTXs for both the registers
- to be loaded are generated in above given LDRD pattern, and the
- pattern can be emitted now. */
- par = emit_insn (par);
- REG_NOTES (par) = dwarf;
- }
-
- i++;
- }
-
- /* If the number of registers pushed is odd AND return_in_pc is false OR
- number of registers are even AND return_in_pc is true, last register is
- popped using LDR. It can be PC as well. Hence, adjust the stack first and
- then LDR with post increment. */
-
- /* Increment the stack pointer, based on there being
- num_regs 4-byte registers to restore. */
- tmp = gen_rtx_SET (VOIDmode,
- stack_pointer_rtx,
- plus_constant (Pmode, stack_pointer_rtx, 4 * i));
- RTX_FRAME_RELATED_P (tmp) = 1;
- emit_insn (tmp);
-
- dwarf = NULL_RTX;
-
- if (((num_regs % 2) == 1 && !return_in_pc)
- || ((num_regs % 2) == 0 && return_in_pc))
- {
- /* Scan for the single register to be popped. Skip until the saved
- register is found. */
- for (; (saved_regs_mask & (1 << j)) == 0; j++);
-
- /* Gen LDR with post increment here. */
- tmp1 = gen_rtx_MEM (SImode,
- gen_rtx_POST_INC (SImode,
- stack_pointer_rtx));
- set_mem_alias_set (tmp1, get_frame_alias_set ());
-
- reg = gen_rtx_REG (SImode, j);
- tmp = gen_rtx_SET (SImode, reg, tmp1);
- RTX_FRAME_RELATED_P (tmp) = 1;
- dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
-
- if (return_in_pc)
- {
- /* If return_in_pc, j must be PC_REGNUM. */
- gcc_assert (j == PC_REGNUM);
- par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
- XVECEXP (par, 0, 0) = ret_rtx;
- XVECEXP (par, 0, 1) = tmp;
- par = emit_jump_insn (par);
- }
- else
- {
- par = emit_insn (tmp);
- }
-
- REG_NOTES (par) = dwarf;
- }
- else if ((num_regs % 2) == 1 && return_in_pc)
- {
- /* There are 2 registers to be popped. So, generate the pattern
- pop_multiple_with_stack_update_and_return to pop in PC. */
- arm_emit_multi_reg_pop (saved_regs_mask & (~((1 << j) - 1)));
- }
-
- return;
-}
-
-/* Calculate the size of the return value that is passed in registers. */
-static unsigned
-arm_size_return_regs (void)
-{
- enum machine_mode mode;
-
- if (crtl->return_rtx != 0)
- mode = GET_MODE (crtl->return_rtx);
- else
- mode = DECL_MODE (DECL_RESULT (current_function_decl));
-
- return GET_MODE_SIZE (mode);
-}
-
-/* Return true if the current function needs to save/restore LR. */
-static bool
-thumb_force_lr_save (void)
-{
- return !cfun->machine->lr_save_eliminated
- && (!leaf_function_p ()
- || thumb_far_jump_used_p ()
- || df_regs_ever_live_p (LR_REGNUM));
-}
-
-
-/* Return true if r3 is used by any of the tail call insns in the
- current function. */
-static bool
-any_sibcall_uses_r3 (void)
-{
- edge_iterator ei;
- edge e;
-
- if (!crtl->tail_call_emit)
- return false;
- FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
- if (e->flags & EDGE_SIBCALL)
- {
- rtx call = BB_END (e->src);
- if (!CALL_P (call))
- call = prev_nonnote_nondebug_insn (call);
- gcc_assert (CALL_P (call) && SIBLING_CALL_P (call));
- if (find_regno_fusage (call, USE, 3))
- return true;
- }
- return false;
-}
-
-
-/* Compute the distance from register FROM to register TO.
- These can be the arg pointer (26), the soft frame pointer (25),
- the stack pointer (13) or the hard frame pointer (11).
- In thumb mode r7 is used as the soft frame pointer, if needed.
- Typical stack layout looks like this:
-
- old stack pointer -> | |
- ----
- | | \
- | | saved arguments for
- | | vararg functions
- | | /
- --
- hard FP & arg pointer -> | | \
- | | stack
- | | frame
- | | /
- --
- | | \
- | | call saved
- | | registers
- soft frame pointer -> | | /
- --
- | | \
- | | local
- | | variables
- locals base pointer -> | | /
- --
- | | \
- | | outgoing
- | | arguments
- current stack pointer -> | | /
- --
-
- For a given function some or all of these stack components
- may not be needed, giving rise to the possibility of
- eliminating some of the registers.
-
- The values returned by this function must reflect the behavior
- of arm_expand_prologue() and arm_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.
-
- SFP may point just inside the local variables block to ensure correct
- alignment. */
-
-
-/* Calculate stack offsets. These are used to calculate register elimination
- offsets and in prologue/epilogue code. Also calculates which registers
- should be saved. */
-
-static arm_stack_offsets *
-arm_get_frame_offsets (void)
-{
- struct arm_stack_offsets *offsets;
- unsigned long func_type;
- int leaf;
- int saved;
- int core_saved;
- HOST_WIDE_INT frame_size;
- int i;
-
- offsets = &cfun->machine->stack_offsets;
-
- /* We need to know if we are a leaf function. Unfortunately, it
- is possible to be called after start_sequence has been called,
- which causes get_insns to return the insns for the sequence,
- not the function, which will cause leaf_function_p to return
- the incorrect result.
-
- to know about leaf functions once reload has completed, and the
- frame size cannot be changed after that time, so we can safely
- use the cached value. */
-
- if (reload_completed)
- return offsets;
-
- /* Initially this is the size of the local variables. It will translated
- into an offset once we have determined the size of preceding data. */
- frame_size = ROUND_UP_WORD (get_frame_size ());
-
- leaf = leaf_function_p ();
-
- /* Space for variadic functions. */
- offsets->saved_args = crtl->args.pretend_args_size;
-
- /* In Thumb mode this is incorrect, but never used. */
- offsets->frame = offsets->saved_args + (frame_pointer_needed ? 4 : 0) +
- arm_compute_static_chain_stack_bytes();
-
- if (TARGET_32BIT)
- {
- unsigned int regno;
-
- 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
- soft frame pointer to be doubleword aligned. */
-
- if (TARGET_REALLY_IWMMXT)
- {
- /* Check for the call-saved iWMMXt registers. */
- for (regno = FIRST_IWMMXT_REGNUM;
- regno <= LAST_IWMMXT_REGNUM;
- regno++)
- if (df_regs_ever_live_p (regno) && ! call_used_regs[regno])
- saved += 8;
- }
-
- func_type = arm_current_func_type ();
- /* Space for saved VFP registers. */
- if (! IS_VOLATILE (func_type)
- && TARGET_HARD_FLOAT && TARGET_VFP)
- saved += arm_get_vfp_saved_size ();
- }
- else /* TARGET_THUMB1 */
- {
- 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 +
- 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. */
- if (leaf && frame_size == 0
- /* However if it calls alloca(), we have a dynamically allocated
- block of BIGGEST_ALIGNMENT on stack, so still do stack alignment. */
- && ! cfun->calls_alloca)
- {
- offsets->outgoing_args = offsets->soft_frame;
- offsets->locals_base = offsets->soft_frame;
- return offsets;
- }
-
- /* Ensure SFP has the correct alignment. */
- if (ARM_DOUBLEWORD_ALIGN
- && (offsets->soft_frame & 7))
- {
- 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 + crtl->outgoing_args_size == 0)
- {
- int reg = -1;
-
- /* 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 (! any_sibcall_uses_r3 ()
- && arm_size_return_regs () <= 12
- && (offsets->saved_regs_mask & (1 << 3)) == 0)
- {
- reg = 3;
- }
- else
- for (i = 4; i <= (TARGET_THUMB1 ? LAST_LO_REGNUM : 11); i++)
- {
- /* Avoid fixed registers; they may be changed at
- arbitrary times so it's unsafe to restore them
- during the epilogue. */
- if (!fixed_regs[i]
- && (offsets->saved_regs_mask & (1 << i)) == 0)
- {
- reg = i;
- break;
- }
- }
-
- 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
- + crtl->outgoing_args_size);
-
- if (ARM_DOUBLEWORD_ALIGN)
- {
- /* Ensure SP remains doubleword aligned. */
- if (offsets->outgoing_args & 7)
- offsets->outgoing_args += 4;
- gcc_assert (!(offsets->outgoing_args & 7));
- }
-
- return offsets;
-}
-
-
-/* Calculate the relative offsets for the different stack pointers. Positive
- offsets are in the direction of stack growth. */
-
-HOST_WIDE_INT
-arm_compute_initial_elimination_offset (unsigned int from, unsigned int to)
-{
- arm_stack_offsets *offsets;
-
- offsets = arm_get_frame_offsets ();
-
- /* OK, now we have enough information to compute the distances.
- There must be an entry in these switch tables for each pair
- of registers in ELIMINABLE_REGS, even if some of the entries
- seem to be redundant or useless. */
- switch (from)
- {
- case ARG_POINTER_REGNUM:
- switch (to)
- {
- case THUMB_HARD_FRAME_POINTER_REGNUM:
- return 0;
-
- case FRAME_POINTER_REGNUM:
- /* This is the reverse of the soft frame pointer
- to hard frame pointer elimination below. */
- return offsets->soft_frame - offsets->saved_args;
-
- case ARM_HARD_FRAME_POINTER_REGNUM:
- /* 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
- then this will return -4. This *is* correct! */
- return offsets->outgoing_args - (offsets->saved_args + 4);
-
- default:
- gcc_unreachable ();
- }
- gcc_unreachable ();
-
- case FRAME_POINTER_REGNUM:
- switch (to)
- {
- case THUMB_HARD_FRAME_POINTER_REGNUM:
- return 0;
-
- case ARM_HARD_FRAME_POINTER_REGNUM:
- /* The hard frame pointer points to the top entry in the
- stack frame. The soft frame pointer to the bottom entry
- in the stack frame. If there is no stack frame at all,
- then they are identical. */
-
- return offsets->frame - offsets->soft_frame;
-
- case STACK_POINTER_REGNUM:
- return offsets->outgoing_args - offsets->soft_frame;
-
- default:
- gcc_unreachable ();
- }
- gcc_unreachable ();
-
- default:
- /* You cannot eliminate from the stack pointer.
- In theory you could eliminate from the hard frame
- pointer to the stack pointer, but this will never
- happen, since if a stack frame is not needed the
- hard frame pointer will never be used. */
- gcc_unreachable ();
- }
-}
-
-/* Given FROM and TO register numbers, say whether this elimination is
- allowed. Frame pointer elimination is automatically handled.
-
- All eliminations are permissible. Note that ARG_POINTER_REGNUM and
- HARD_FRAME_POINTER_REGNUM are in fact the same thing. If we need a frame
- pointer, we must eliminate FRAME_POINTER_REGNUM into
- HARD_FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM or
- ARG_POINTER_REGNUM. */
-
-bool
-arm_can_eliminate (const int from, const int to)
-{
- return ((to == FRAME_POINTER_REGNUM && from == ARG_POINTER_REGNUM) ? false :
- (to == STACK_POINTER_REGNUM && frame_pointer_needed) ? false :
- (to == ARM_HARD_FRAME_POINTER_REGNUM && TARGET_THUMB) ? false :
- (to == THUMB_HARD_FRAME_POINTER_REGNUM && TARGET_ARM) ? false :
- true);
-}
-
-/* Emit RTL to save coprocessor registers on function entry. Returns the
- number of bytes pushed. */
-
-static int
-arm_save_coproc_regs(void)
-{
- int saved_size = 0;
- unsigned reg;
- unsigned start_reg;
- rtx insn;
-
- for (reg = LAST_IWMMXT_REGNUM; reg >= FIRST_IWMMXT_REGNUM; reg--)
- if (df_regs_ever_live_p (reg) && ! call_used_regs[reg])
- {
- insn = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
- insn = gen_rtx_MEM (V2SImode, insn);
- insn = emit_set_insn (insn, gen_rtx_REG (V2SImode, reg));
- RTX_FRAME_RELATED_P (insn) = 1;
- saved_size += 8;
- }
-
- if (TARGET_HARD_FLOAT && TARGET_VFP)
- {
- start_reg = FIRST_VFP_REGNUM;
-
- for (reg = FIRST_VFP_REGNUM; reg < LAST_VFP_REGNUM; reg += 2)
- {
- if ((!df_regs_ever_live_p (reg) || call_used_regs[reg])
- && (!df_regs_ever_live_p (reg + 1) || call_used_regs[reg + 1]))
- {
- if (start_reg != reg)
- saved_size += vfp_emit_fstmd (start_reg,
- (reg - start_reg) / 2);
- start_reg = reg + 2;
- }
- }
- if (start_reg != reg)
- saved_size += vfp_emit_fstmd (start_reg,
- (reg - start_reg) / 2);
- }
- return saved_size;
-}
-
-
-/* Set the Thumb frame pointer from the stack pointer. */
-
-static void
-thumb_set_frame_pointer (arm_stack_offsets *offsets)
-{
- HOST_WIDE_INT amount;
- rtx insn, dwarf;
-
- amount = offsets->outgoing_args - offsets->locals_base;
- if (amount < 1024)
- insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx,
- stack_pointer_rtx, GEN_INT (amount)));
- else
- {
- emit_insn (gen_movsi (hard_frame_pointer_rtx, GEN_INT (amount)));
- /* 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 (Pmode, stack_pointer_rtx, amount));
- RTX_FRAME_RELATED_P (dwarf) = 1;
- add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
- }
-
- RTX_FRAME_RELATED_P (insn) = 1;
-}
-
-/* Generate the prologue instructions for entry into an ARM or Thumb-2
- function. */
-void
-arm_expand_prologue (void)
-{
- rtx amount;
- rtx insn;
- rtx ip_rtx;
- unsigned long live_regs_mask;
- unsigned long func_type;
- int fp_offset = 0;
- int saved_pretend_args = 0;
- int saved_regs = 0;
- unsigned HOST_WIDE_INT args_to_push;
- arm_stack_offsets *offsets;
-
- func_type = arm_current_func_type ();
-
- /* Naked functions don't have prologues. */
- if (IS_NAKED (func_type))
- return;
-
- /* Make a copy of c_f_p_a_s as we may need to modify it locally. */
- args_to_push = crtl->args.pretend_args_size;
-
- /* Compute which register we will have to save onto the stack. */
- offsets = arm_get_frame_offsets ();
- live_regs_mask = offsets->saved_regs_mask;
-
- ip_rtx = gen_rtx_REG (SImode, IP_REGNUM);
-
- if (IS_STACKALIGN (func_type))
- {
- rtx r0, r1;
-
- /* Handle a word-aligned stack pointer. We generate the following:
-
- mov r0, sp
- bic r1, r0, #7
- mov sp, r1
- <save and restore r0 in normal prologue/epilogue>
- mov sp, r0
- bx lr
-
- The unwinder doesn't need to know about the stack realignment.
- Just tell it we saved SP in r0. */
- gcc_assert (TARGET_THUMB2 && !arm_arch_notm && args_to_push == 0);
-
- r0 = gen_rtx_REG (SImode, 0);
- r1 = gen_rtx_REG (SImode, 1);
-
- insn = emit_insn (gen_movsi (r0, stack_pointer_rtx));
- RTX_FRAME_RELATED_P (insn) = 1;
- add_reg_note (insn, REG_CFA_REGISTER, NULL);
-
- emit_insn (gen_andsi3 (r1, r0, GEN_INT (~(HOST_WIDE_INT)7)));
-
- /* ??? The CFA changes here, which may cause GDB to conclude that it
- has entered a different function. That said, the unwind info is
- correct, individually, before and after this instruction because
- we've described the save of SP, which will override the default
- handling of SP as restoring from the CFA. */
- emit_insn (gen_movsi (stack_pointer_rtx, r1));
- }
-
- /* 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))
- {
- /* Interrupt functions must not corrupt any registers.
- Creating a frame pointer however, corrupts the IP
- register, so we must push it first. */
- emit_multi_reg_push (1 << IP_REGNUM);
-
- /* Do not set RTX_FRAME_RELATED_P on this insn.
- The dwarf stack unwinding code only wants to see one
- stack decrement per function, and this is not it. If
- this instruction is labeled as being part of the frame
- creation sequence then dwarf2out_frame_debug_expr will
- die when it encounters the assignment of IP to FP
- later on, since the use of SP here establishes SP as
- the CFA register and not IP.
-
- Anyway this instruction is not really part of the stack
- frame creation although it is part of the prologue. */
- }
- else if (IS_NESTED (func_type))
- {
- /* The Static chain register is the same as the IP register
- used as a scratch register during stack frame creation.
- To get around this need to find somewhere to store IP
- whilst the frame is being created. We try the following
- places in order:
-
- 1. The last argument register.
- 2. A slot on the stack above the frame. (This only
- works if the function is not a varargs function).
- 3. Register r3, after pushing the argument registers
- onto the stack.
-
- Note - we only need to tell the dwarf2 backend about the SP
- adjustment in the second variant; the static chain register
- doesn't need to be unwound, as it doesn't contain a value
- inherited from the caller. */
-
- if (df_regs_ever_live_p (3) == false)
- insn = emit_set_insn (gen_rtx_REG (SImode, 3), ip_rtx);
- else if (args_to_push == 0)
- {
- rtx dwarf;
-
- gcc_assert(arm_compute_static_chain_stack_bytes() == 4);
- saved_regs += 4;
-
- insn = gen_rtx_PRE_DEC (SImode, stack_pointer_rtx);
- insn = emit_set_insn (gen_frame_mem (SImode, insn), ip_rtx);
- fp_offset = 4;
-
- /* Just tell the dwarf backend that we adjusted SP. */
- dwarf = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
- plus_constant (Pmode, stack_pointer_rtx,
- -fp_offset));
- RTX_FRAME_RELATED_P (insn) = 1;
- add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
- }
- else
- {
- /* Store the args on the stack. */
- if (cfun->machine->uses_anonymous_args)
- insn = emit_multi_reg_push
- ((0xf0 >> (args_to_push / 4)) & 0xf);
- else
- insn = emit_insn
- (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (- args_to_push)));
-
- RTX_FRAME_RELATED_P (insn) = 1;
-
- saved_pretend_args = 1;
- fp_offset = args_to_push;
- args_to_push = 0;
-
- /* Now reuse r3 to preserve IP. */
- emit_set_insn (gen_rtx_REG (SImode, 3), ip_rtx);
- }
- }
-
- insn = emit_set_insn (ip_rtx,
- plus_constant (Pmode, stack_pointer_rtx,
- fp_offset));
- RTX_FRAME_RELATED_P (insn) = 1;
- }
-
- if (args_to_push)
- {
- /* Push the argument registers, or reserve space for them. */
- if (cfun->machine->uses_anonymous_args)
- insn = emit_multi_reg_push
- ((0xf0 >> (args_to_push / 4)) & 0xf);
- else
- insn = emit_insn
- (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (- args_to_push)));
- RTX_FRAME_RELATED_P (insn) = 1;
- }
-
- /* If this is an interrupt service routine, and the link register
- 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 && TARGET_APCS_FRAME)
- && TARGET_ARM)
- {
- rtx lr = gen_rtx_REG (SImode, LR_REGNUM);
-
- emit_set_insn (lr, plus_constant (SImode, lr, -4));
- }
-
- if (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 the 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;
- }
- }
-
- if (current_tune->prefer_ldrd_strd
- && !optimize_function_for_size_p (cfun))
- {
- if (TARGET_THUMB2)
- {
- thumb2_emit_strd_push (live_regs_mask);
- }
- else
- {
- insn = emit_multi_reg_push (live_regs_mask);
- RTX_FRAME_RELATED_P (insn) = 1;
- }
- }
- else
- {
- insn = emit_multi_reg_push (live_regs_mask);
- RTX_FRAME_RELATED_P (insn) = 1;
- }
- }
-
- if (! IS_VOLATILE (func_type))
- saved_regs += arm_save_coproc_regs ();
-
- 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));
- RTX_FRAME_RELATED_P (insn) = 1;
-
- if (IS_NESTED (func_type))
- {
- /* Recover the static chain register. */
- if (!df_regs_ever_live_p (3)
- || saved_pretend_args)
- insn = gen_rtx_REG (SImode, 3);
- else /* if (crtl->args.pretend_args_size == 0) */
- {
- insn = plus_constant (Pmode, hard_frame_pointer_rtx, 4);
- insn = gen_frame_mem (SImode, insn);
- }
- emit_set_insn (ip_rtx, insn);
- /* Add a USE to stop propagate_one_insn() from barfing. */
- emit_insn (gen_force_register_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;
- }
- }
-
- if (flag_stack_usage_info)
- current_function_static_stack_size
- = offsets->outgoing_args - offsets->saved_args;
-
- if (offsets->outgoing_args != offsets->saved_args + saved_regs)
- {
- /* This add can produce multiple insns for a large constant, so we
- need to get tricky. */
- rtx last = get_last_insn ();
-
- amount = GEN_INT (offsets->saved_args + saved_regs
- - offsets->outgoing_args);
-
- insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
- amount));
- do
- {
- last = last ? NEXT_INSN (last) : get_insns ();
- RTX_FRAME_RELATED_P (last) = 1;
- }
- while (last != insn);
-
- /* 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. */
- if (frame_pointer_needed)
- insn = emit_insn (gen_stack_tie (stack_pointer_rtx,
- hard_frame_pointer_rtx));
- }
-
-
- if (frame_pointer_needed && TARGET_THUMB2)
- thumb_set_frame_pointer (offsets);
-
- if (flag_pic && arm_pic_register != INVALID_REGNUM)
- {
- unsigned long mask;
-
- mask = live_regs_mask;
- mask &= THUMB2_WORK_REGS;
- if (!IS_NESTED (func_type))
- mask |= (1 << IP_REGNUM);
- arm_load_pic_register (mask);
- }
-
- /* If we are profiling, make sure no instructions are scheduled before
- the call to mcount. Similarly if the user has requested no
- scheduling in the prolog. Similarly if we want non-call exceptions
- using the EABI unwinder, to prevent faulting instructions from being
- swapped with a stack adjustment. */
- if (crtl->profile || !TARGET_SCHED_PROLOG
- || (arm_except_unwind_info (&global_options) == UI_TARGET
- && cfun->can_throw_non_call_exceptions))
- emit_insn (gen_blockage ());
-
- /* If the link register is being kept alive, with the return address in it,
- then make sure that it does not get reused by the ce2 pass. */
- if ((live_regs_mask & (1 << LR_REGNUM)) == 0)
- cfun->machine->lr_save_eliminated = 1;
-}
-
-/* Print condition code to STREAM. Helper function for arm_print_operand. */
-static void
-arm_print_condition (FILE *stream)
-{
- if (arm_ccfsm_state == 3 || arm_ccfsm_state == 4)
- {
- /* Branch conversion is not implemented for Thumb-2. */
- if (TARGET_THUMB)
- {
- output_operand_lossage ("predicated Thumb instruction");
- return;
- }
- if (current_insn_predicate != NULL)
- {
- output_operand_lossage
- ("predicated instruction in conditional sequence");
- return;
- }
-
- fputs (arm_condition_codes[arm_current_cc], stream);
- }
- else if (current_insn_predicate)
- {
- enum arm_cond_code code;
-
- if (TARGET_THUMB1)
- {
- output_operand_lossage ("predicated Thumb instruction");
- return;
- }
-
- code = get_arm_condition_code (current_insn_predicate);
- fputs (arm_condition_codes[code], stream);
- }
-}
-
-
-/* If CODE is 'd', then the X is a condition operand and the instruction
- should only be executed if the condition is true.
- if CODE is 'D', then the X is a condition operand and the instruction
- should only be executed if the condition is false: however, if the mode
- of the comparison is CCFPEmode, then always execute the instruction -- we
- do this because in these circumstances !GE does not necessarily imply LT;
- in these cases the instruction pattern will take care to make sure that
- an instruction containing %d will follow, thereby undoing the effects of
- doing this instruction unconditionally.
- If CODE is 'N' then X is a floating point operand that must be negated
- before output.
- If CODE is 'B' then output a bitwise inverted value of X (a const int).
- If X is a REG and CODE is `M', output a ldm/stm style multi-reg. */
-static void
-arm_print_operand (FILE *stream, rtx x, int code)
-{
- switch (code)
- {
- case '@':
- fputs (ASM_COMMENT_START, stream);
- return;
-
- case '_':
- fputs (user_label_prefix, stream);
- return;
-
- case '|':
- fputs (REGISTER_PREFIX, stream);
- return;
-
- case '?':
- arm_print_condition (stream);
- return;
-
- case '(':
- /* Nothing in unified syntax, otherwise the current condition code. */
- if (!TARGET_UNIFIED_ASM)
- arm_print_condition (stream);
- break;
-
- case ')':
- /* The current condition code in unified syntax, otherwise nothing. */
- if (TARGET_UNIFIED_ASM)
- arm_print_condition (stream);
- break;
-
- case '.':
- /* The current condition code for a condition code setting instruction.
- Preceded by 's' in unified syntax, otherwise followed by 's'. */
- if (TARGET_UNIFIED_ASM)
- {
- fputc('s', stream);
- arm_print_condition (stream);
- }
- else
- {
- arm_print_condition (stream);
- fputc('s', stream);
- }
- return;
-
- case '!':
- /* If the instruction is conditionally executed then print
- the current condition code, otherwise print 's'. */
- gcc_assert (TARGET_THUMB2 && TARGET_UNIFIED_ASM);
- if (current_insn_predicate)
- arm_print_condition (stream);
- else
- fputc('s', stream);
- break;
-
- /* %# is a "break" sequence. It doesn't output anything, but is used to
- separate e.g. operand numbers from following text, if that text consists
- of further digits which we don't want to be part of the operand
- number. */
- case '#':
- return;
-
- case 'N':
- {
- REAL_VALUE_TYPE r;
- REAL_VALUE_FROM_CONST_DOUBLE (r, x);
- r = real_value_negate (&r);
- fprintf (stream, "%s", fp_const_from_val (&r));
- }
- return;
-
- /* An integer or symbol address without a preceding # sign. */
- case 'c':
- 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;
-
- case CONST:
- if (GET_CODE (XEXP (x, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
- {
- output_addr_const (stream, x);
- break;
- }
- /* Fall through. */
-
- default:
- output_operand_lossage ("Unsupported operand for code '%c'", code);
- }
- return;
-
- /* An integer that we want to print in HEX. */
- case 'x':
- switch (GET_CODE (x))
- {
- case CONST_INT:
- fprintf (stream, "#" HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
- break;
-
- default:
- output_operand_lossage ("Unsupported operand for code '%c'", code);
- }
- return;
-
- case 'B':
- if (CONST_INT_P (x))
- {
- HOST_WIDE_INT val;
- val = ARM_SIGN_EXTEND (~INTVAL (x));
- fprintf (stream, HOST_WIDE_INT_PRINT_DEC, val);
- }
- else
- {
- putc ('~', stream);
- output_addr_const (stream, x);
- }
- return;
-
- case 'L':
- /* The low 16 bits of an immediate constant. */
- fprintf (stream, HOST_WIDE_INT_PRINT_DEC, INTVAL(x) & 0xffff);
- return;
-
- case 'i':
- fprintf (stream, "%s", arithmetic_instr (x, 1));
- return;
-
- case 'I':
- fprintf (stream, "%s", arithmetic_instr (x, 0));
- return;
-
- case 'S':
- {
- HOST_WIDE_INT val;
- const char *shift;
-
- shift = shift_op (x, &val);
-
- if (shift)
- {
- fprintf (stream, ", %s ", shift);
- if (val == -1)
- arm_print_operand (stream, XEXP (x, 1), 0);
- else
- fprintf (stream, "#" HOST_WIDE_INT_PRINT_DEC, val);
- }
- }
- return;
-
- /* An explanation of the 'Q', 'R' and 'H' register operands:
-
- In a pair of registers containing a DI or DF value the 'Q'
- operand returns the register number of the register containing
- the least significant part of the value. The 'R' operand returns
- the register number of the register containing the most
- significant part of the value.
-
- The 'H' operand returns the higher of the two register numbers.
- On a run where WORDS_BIG_ENDIAN is true the 'H' operand is the
- same as the 'Q' operand, since the most significant part of the
- value is held in the lower number register. The reverse is true
- on systems where WORDS_BIG_ENDIAN is false.
-
- The purpose of these operands is to distinguish between cases
- where the endian-ness of the values is important (for example
- when they are added together), and cases where the endian-ness
- is irrelevant, but the order of register operations is important.
- For example when loading a value from memory into a register
- pair, the endian-ness does not matter. Provided that the value
- from the lower memory address is put into the lower numbered
- register, and the value from the higher address is put into the
- higher numbered register, the load will work regardless of whether
- the value being loaded is big-wordian or little-wordian. The
- order of the two register loads can matter however, if the address
- of the memory location is actually held in one of the registers
- being overwritten by the load.
-
- The 'Q' and 'R' constraints are also available for 64-bit
- constants. */
- case 'Q':
- if (CONST_INT_P (x) || CONST_DOUBLE_P (x))
- {
- rtx part = gen_lowpart (SImode, x);
- fprintf (stream, "#" HOST_WIDE_INT_PRINT_DEC, INTVAL (part));
- return;
- }
-
- if (!REG_P (x) || REGNO (x) > LAST_ARM_REGNUM)
- {
- output_operand_lossage ("invalid operand for code '%c'", code);
- return;
- }
-
- asm_fprintf (stream, "%r", REGNO (x) + (WORDS_BIG_ENDIAN ? 1 : 0));
- return;
-
- case 'R':
- if (CONST_INT_P (x) || CONST_DOUBLE_P (x))
- {
- enum machine_mode mode = GET_MODE (x);
- rtx part;
-
- if (mode == VOIDmode)
- mode = DImode;
- part = gen_highpart_mode (SImode, mode, x);
- fprintf (stream, "#" HOST_WIDE_INT_PRINT_DEC, INTVAL (part));
- return;
- }
-
- if (!REG_P (x) || REGNO (x) > LAST_ARM_REGNUM)
- {
- output_operand_lossage ("invalid operand for code '%c'", code);
- return;
- }
-
- asm_fprintf (stream, "%r", REGNO (x) + (WORDS_BIG_ENDIAN ? 0 : 1));
- return;
-
- case 'H':
- if (!REG_P (x) || REGNO (x) > LAST_ARM_REGNUM)
- {
- output_operand_lossage ("invalid operand for code '%c'", code);
- return;
- }
-
- asm_fprintf (stream, "%r", REGNO (x) + 1);
- return;
-
- case 'J':
- if (!REG_P (x) || REGNO (x) > LAST_ARM_REGNUM)
- {
- output_operand_lossage ("invalid operand for code '%c'", code);
- return;
- }
-
- asm_fprintf (stream, "%r", REGNO (x) + (WORDS_BIG_ENDIAN ? 3 : 2));
- return;
-
- case 'K':
- if (!REG_P (x) || REGNO (x) > LAST_ARM_REGNUM)
- {
- output_operand_lossage ("invalid operand for code '%c'", code);
- return;
- }
-
- asm_fprintf (stream, "%r", REGNO (x) + (WORDS_BIG_ENDIAN ? 2 : 3));
- return;
-
- case 'm':
- asm_fprintf (stream, "%r",
- REG_P (XEXP (x, 0))
- ? REGNO (XEXP (x, 0)) : REGNO (XEXP (XEXP (x, 0), 0)));
- return;
-
- case 'M':
- asm_fprintf (stream, "{%r-%r}",
- REGNO (x),
- REGNO (x) + ARM_NUM_REGS (GET_MODE (x)) - 1);
- return;
-
- /* Like 'M', but writing doubleword vector registers, for use by Neon
- insns. */
- case 'h':
- {
- int regno = (REGNO (x) - FIRST_VFP_REGNUM) / 2;
- int numregs = ARM_NUM_REGS (GET_MODE (x)) / 2;
- if (numregs == 1)
- asm_fprintf (stream, "{d%d}", regno);
- else
- asm_fprintf (stream, "{d%d-d%d}", regno, regno + numregs - 1);
- }
- return;
-
- case 'd':
- /* CONST_TRUE_RTX means always -- that's the default. */
- if (x == const_true_rtx)
- return;
-
- if (!COMPARISON_P (x))
- {
- output_operand_lossage ("invalid operand for code '%c'", code);
- return;
- }
-
- fputs (arm_condition_codes[get_arm_condition_code (x)],
- stream);
- return;
-
- case 'D':
- /* CONST_TRUE_RTX means not always -- i.e. never. We shouldn't ever
- want to do that. */
- if (x == const_true_rtx)
- {
- output_operand_lossage ("instruction never executed");
- return;
- }
- if (!COMPARISON_P (x))
- {
- output_operand_lossage ("invalid operand for code '%c'", code);
- return;
- }
-
- fputs (arm_condition_codes[ARM_INVERSE_CONDITION_CODE
- (get_arm_condition_code (x))],
- stream);
- return;
-
- case 's':
- case 'V':
- case 'W':
- case 'X':
- case 'Y':
- case 'Z':
- /* Former Maverick support, removed after GCC-4.7. */
- output_operand_lossage ("obsolete Maverick format code '%c'", code);
- return;
-
- case 'U':
- if (!REG_P (x)
- || REGNO (x) < FIRST_IWMMXT_GR_REGNUM
- || REGNO (x) > LAST_IWMMXT_GR_REGNUM)
- /* Bad value for wCG register number. */
- {
- output_operand_lossage ("invalid operand for code '%c'", code);
- return;
- }
-
- else
- fprintf (stream, "%d", REGNO (x) - FIRST_IWMMXT_GR_REGNUM);
- return;
-
- /* Print an iWMMXt control register name. */
- case 'w':
- if (!CONST_INT_P (x)
- || INTVAL (x) < 0
- || INTVAL (x) >= 16)
- /* Bad value for wC register number. */
- {
- output_operand_lossage ("invalid operand for code '%c'", code);
- return;
- }
-
- else
- {
- static const char * wc_reg_names [16] =
- {
- "wCID", "wCon", "wCSSF", "wCASF",
- "wC4", "wC5", "wC6", "wC7",
- "wCGR0", "wCGR1", "wCGR2", "wCGR3",
- "wC12", "wC13", "wC14", "wC15"
- };
-
- fputs (wc_reg_names [INTVAL (x)], stream);
- }
- 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 || !REG_P (x))
- {
- 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':
- {
- int mode = GET_MODE (x);
- int is_quad = (code == 'q');
- int regno;
-
- if (GET_MODE_SIZE (mode) != (is_quad ? 16 : 8))
- {
- output_operand_lossage ("invalid operand for code '%c'", code);
- return;
- }
-
- if (!REG_P (x)
- || !IS_VFP_REGNUM (REGNO (x)))
- {
- output_operand_lossage ("invalid operand for code '%c'", code);
- return;
- }
-
- regno = REGNO (x);
- if ((is_quad && !NEON_REGNO_OK_FOR_QUAD (regno))
- || (!is_quad && !VFP_REGNO_OK_FOR_DOUBLE (regno)))
- {
- output_operand_lossage ("invalid operand for code '%c'", code);
- return;
- }
-
- fprintf (stream, "%c%d", is_quad ? 'q' : 'd',
- (regno - FIRST_VFP_REGNUM) >> (is_quad ? 2 : 1));
- }
- return;
-
- /* These two codes print the low/high doubleword register of a Neon quad
- register, respectively. For pair-structure types, can also print
- low/high quadword registers. */
- case 'e':
- case 'f':
- {
- int mode = GET_MODE (x);
- int regno;
-
- if ((GET_MODE_SIZE (mode) != 16
- && GET_MODE_SIZE (mode) != 32) || !REG_P (x))
- {
- output_operand_lossage ("invalid operand for code '%c'", code);
- return;
- }
-
- regno = REGNO (x);
- if (!NEON_REGNO_OK_FOR_QUAD (regno))
- {
- output_operand_lossage ("invalid operand for code '%c'", code);
- return;
- }
-
- if (GET_MODE_SIZE (mode) == 16)
- fprintf (stream, "d%d", ((regno - FIRST_VFP_REGNUM) >> 1)
- + (code == 'f' ? 1 : 0));
- else
- fprintf (stream, "q%d", ((regno - FIRST_VFP_REGNUM) >> 2)
- + (code == 'f' ? 1 : 0));
- }
- return;
-
- /* Print a VFPv3 floating-point constant, represented as an integer
- index. */
- case 'G':
- {
- int index = vfp3_const_double_index (x);
- gcc_assert (index != -1);
- fprintf (stream, "%d", index);
- }
- return;
-
- /* Print bits representing opcode features for Neon.
-
- Bit 0 is 1 for signed, 0 for unsigned. Floats count as signed
- and polynomials as unsigned.
-
- Bit 1 is 1 for floats and polynomials, 0 for ordinary integers.
-
- Bit 2 is 1 for rounding functions, 0 otherwise. */
-
- /* Identify the type as 's', 'u', 'p' or 'f'. */
- case 'T':
- {
- HOST_WIDE_INT bits = INTVAL (x);
- fputc ("uspf"[bits & 3], stream);
- }
- return;
-
- /* Likewise, but signed and unsigned integers are both 'i'. */
- case 'F':
- {
- HOST_WIDE_INT bits = INTVAL (x);
- fputc ("iipf"[bits & 3], stream);
- }
- return;
-
- /* As for 'T', but emit 'u' instead of 'p'. */
- case 't':
- {
- HOST_WIDE_INT bits = INTVAL (x);
- fputc ("usuf"[bits & 3], stream);
- }
- return;
-
- /* Bit 2: rounding (vs none). */
- case 'O':
- {
- HOST_WIDE_INT bits = INTVAL (x);
- fputs ((bits & 4) != 0 ? "r" : "", stream);
- }
- return;
-
- /* Memory operand for vld1/vst1 instruction. */
- case 'A':
- {
- rtx addr;
- bool postinc = FALSE;
- unsigned align, memsize, align_bits;
-
- gcc_assert (MEM_P (x));
- addr = XEXP (x, 0);
- if (GET_CODE (addr) == POST_INC)
- {
- postinc = 1;
- addr = XEXP (addr, 0);
- }
- asm_fprintf (stream, "[%r", REGNO (addr));
-
- /* We know the alignment of this access, so we can emit a hint in the
- instruction (for some alignments) as an aid to the memory subsystem
- of the target. */
- align = MEM_ALIGN (x) >> 3;
- memsize = MEM_SIZE (x);
-
- /* Only certain alignment specifiers are supported by the hardware. */
- /* Note that ARM EABI only guarentees 8-byte stack alignment. While GCC
- honors stricter alignment of composite type in user code, it doesn't
- observe the alignment of memory passed as an extra argument for function
- returning large composite type. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57271 */
- if (memsize == 32 && (align % 32) == 0 && !TARGET_AAPCS_BASED)
- align_bits = 256;
- else if ((memsize == 16 || memsize == 32) && (align % 16) == 0 && !TARGET_AAPCS_BASED)
- align_bits = 128;
- else if (memsize >= 8 && (align % 8) == 0)
- align_bits = 64;
- else
- align_bits = 0;
-
- if (align_bits != 0)
- asm_fprintf (stream, ":%d", align_bits);
-
- asm_fprintf (stream, "]");
-
- if (postinc)
- fputs("!", stream);
- }
- return;
-
- case 'C':
- {
- rtx addr;
-
- gcc_assert (MEM_P (x));
- addr = XEXP (x, 0);
- gcc_assert (REG_P (addr));
- asm_fprintf (stream, "[%r]", REGNO (addr));
- }
- return;
-
- /* Translate an S register number into a D register number and element index. */
- case 'y':
- {
- int mode = GET_MODE (x);
- int regno;
-
- if (GET_MODE_SIZE (mode) != 4 || !REG_P (x))
- {
- 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);
- }
- return;
-
- case 'v':
- gcc_assert (CONST_DOUBLE_P (x));
- fprintf (stream, "#%d", vfp3_const_double_for_fract_bits (x));
- 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 || !REG_P (x))
- {
- 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)
- {
- output_operand_lossage ("missing operand");
- return;
- }
-
- switch (GET_CODE (x))
- {
- case REG:
- asm_fprintf (stream, "%r", REGNO (x));
- break;
-
- case MEM:
- output_memory_reference_mode = GET_MODE (x);
- output_address (XEXP (x, 0));
- break;
-
- case CONST_DOUBLE:
- if (TARGET_NEON)
- {
- char fpstr[20];
- real_to_decimal (fpstr, CONST_DOUBLE_REAL_VALUE (x),
- sizeof (fpstr), 0, 1);
- fprintf (stream, "#%s", fpstr);
- }
- else
- fprintf (stream, "#%s", fp_immediate_constant (x));
- break;
-
- 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;
- }
- }
-}
-
-/* Target hook for printing a memory address. */
-static void
-arm_print_operand_address (FILE *stream, rtx x)
-{
- if (TARGET_32BIT)
- {
- int is_minus = GET_CODE (x) == MINUS;
-
- if (REG_P (x))
- asm_fprintf (stream, "[%r]", REGNO (x));
- else if (GET_CODE (x) == PLUS || is_minus)
- {
- rtx base = XEXP (x, 0);
- rtx index = XEXP (x, 1);
- HOST_WIDE_INT offset = 0;
- if (!REG_P (base)
- || (REG_P (index) && 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;
- }
- switch (GET_CODE (index))
- {
- case CONST_INT:
- offset = INTVAL (index);
- if (is_minus)
- offset = -offset;
- asm_fprintf (stream, "[%r, #%wd]",
- REGNO (base), offset);
- break;
-
- case REG:
- asm_fprintf (stream, "[%r, %s%r]",
- REGNO (base), is_minus ? "-" : "",
- REGNO (index));
- break;
-
- case MULT:
- case ASHIFTRT:
- case LSHIFTRT:
- case ASHIFT:
- case ROTATERT:
- {
- asm_fprintf (stream, "[%r, %s%r",
- REGNO (base), is_minus ? "-" : "",
- REGNO (XEXP (index, 0)));
- arm_print_operand (stream, index, 'S');
- fputs ("]", stream);
- break;
- }
-
- default:
- gcc_unreachable ();
- }
- }
- else if (GET_CODE (x) == PRE_INC || GET_CODE (x) == POST_INC
- || GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_DEC)
- {
- extern enum machine_mode output_memory_reference_mode;
-
- gcc_assert (REG_P (XEXP (x, 0)));
-
- if (GET_CODE (x) == PRE_DEC || GET_CODE (x) == PRE_INC)
- asm_fprintf (stream, "[%r, #%s%d]!",
- REGNO (XEXP (x, 0)),
- GET_CODE (x) == PRE_DEC ? "-" : "",
- GET_MODE_SIZE (output_memory_reference_mode));
- else
- asm_fprintf (stream, "[%r], #%s%d",
- REGNO (XEXP (x, 0)),
- GET_CODE (x) == POST_DEC ? "-" : "",
- GET_MODE_SIZE (output_memory_reference_mode));
- }
- else if (GET_CODE (x) == PRE_MODIFY)
- {
- asm_fprintf (stream, "[%r, ", REGNO (XEXP (x, 0)));
- if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
- asm_fprintf (stream, "#%wd]!",
- INTVAL (XEXP (XEXP (x, 1), 1)));
- else
- asm_fprintf (stream, "%r]!",
- REGNO (XEXP (XEXP (x, 1), 1)));
- }
- else if (GET_CODE (x) == POST_MODIFY)
- {
- asm_fprintf (stream, "[%r], ", REGNO (XEXP (x, 0)));
- if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
- asm_fprintf (stream, "#%wd",
- INTVAL (XEXP (XEXP (x, 1), 1)));
- else
- asm_fprintf (stream, "%r",
- REGNO (XEXP (XEXP (x, 1), 1)));
- }
- else output_addr_const (stream, x);
- }
- else
- {
- if (REG_P (x))
- asm_fprintf (stream, "[%r]", REGNO (x));
- else if (GET_CODE (x) == POST_INC)
- asm_fprintf (stream, "%r!", REGNO (XEXP (x, 0)));
- else if (GET_CODE (x) == PLUS)
- {
- gcc_assert (REG_P (XEXP (x, 0)));
- if (CONST_INT_P (XEXP (x, 1)))
- asm_fprintf (stream, "[%r, #%wd]",
- REGNO (XEXP (x, 0)),
- INTVAL (XEXP (x, 1)));
- else
- asm_fprintf (stream, "[%r, %r]",
- REGNO (XEXP (x, 0)),
- REGNO (XEXP (x, 1)));
- }
- else
- output_addr_const (stream, x);
- }
-}
-
-/* Target hook for indicating whether a punctuation character for
- TARGET_PRINT_OPERAND is valid. */
-static bool
-arm_print_operand_punct_valid_p (unsigned char code)
-{
- return (code == '@' || code == '|' || code == '.'
- || code == '(' || code == ')' || code == '#'
- || (TARGET_32BIT && (code == '?'))
- || (TARGET_THUMB2 && (code == '!'))
- || (TARGET_THUMB && (code == '_')));
-}
-
-/* Target hook for assembling integer objects. The ARM version needs to
- handle word-sized values specially. */
-static bool
-arm_assemble_integer (rtx x, unsigned int size, int aligned_p)
-{
- enum machine_mode mode;
-
- if (size == UNITS_PER_WORD && aligned_p)
- {
- fputs ("\t.word\t", asm_out_file);
- output_addr_const (asm_out_file, x);
-
- /* Mark symbols as position independent. We only do this in the
- .text segment, not in the .data segment. */
- if (NEED_GOT_RELOC && flag_pic && making_const_table &&
- (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF))
- {
- /* See legitimize_pic_address for an explanation of the
- TARGET_VXWORKS_RTP check. */
- if (TARGET_VXWORKS_RTP
- || (GET_CODE (x) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (x)))
- fputs ("(GOT)", asm_out_file);
- else
- fputs ("(GOTOFF)", asm_out_file);
- }
- fputc ('\n', asm_out_file);
- return true;
- }
-
- mode = GET_MODE (x);
-
- if (arm_vector_mode_supported_p (mode))
- {
- int i, units;
-
- gcc_assert (GET_CODE (x) == CONST_VECTOR);
-
- units = CONST_VECTOR_NUNITS (x);
- size = GET_MODE_SIZE (GET_MODE_INNER (mode));
-
- if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
- for (i = 0; i < units; i++)
- {
- rtx elt = CONST_VECTOR_ELT (x, i);
- assemble_integer
- (elt, size, i == 0 ? BIGGEST_ALIGNMENT : size * BITS_PER_UNIT, 1);
- }
- else
- for (i = 0; i < units; i++)
- {
- rtx elt = CONST_VECTOR_ELT (x, i);
- REAL_VALUE_TYPE rval;
-
- REAL_VALUE_FROM_CONST_DOUBLE (rval, elt);
-
- assemble_real
- (rval, GET_MODE_INNER (mode),
- i == 0 ? BIGGEST_ALIGNMENT : size * BITS_PER_UNIT);
- }
-
- return true;
- }
-
- return default_assemble_integer (x, size, aligned_p);
-}
-
-static void
-arm_elf_asm_cdtor (rtx symbol, int priority, bool is_ctor)
-{
- section *s;
-
- if (!TARGET_AAPCS_BASED)
- {
- (is_ctor ?
- default_named_section_asm_out_constructor
- : default_named_section_asm_out_destructor) (symbol, priority);
- return;
- }
-
- /* Put these in the .init_array section, using a special relocation. */
- if (priority != DEFAULT_INIT_PRIORITY)
- {
- char buf[18];
- sprintf (buf, "%s.%.5u",
- is_ctor ? ".init_array" : ".fini_array",
- priority);
- s = get_section (buf, SECTION_WRITE, NULL_TREE);
- }
- else if (is_ctor)
- s = ctors_section;
- else
- s = dtors_section;
-
- switch_to_section (s);
- assemble_align (POINTER_SIZE);
- fputs ("\t.word\t", asm_out_file);
- output_addr_const (asm_out_file, symbol);
- fputs ("(target1)\n", asm_out_file);
-}
-
-/* Add a function to the list of static constructors. */
-
-static void
-arm_elf_asm_constructor (rtx symbol, int priority)
-{
- arm_elf_asm_cdtor (symbol, priority, /*is_ctor=*/true);
-}
-
-/* Add a function to the list of static destructors. */
-
-static void
-arm_elf_asm_destructor (rtx symbol, int priority)
-{
- arm_elf_asm_cdtor (symbol, priority, /*is_ctor=*/false);
-}
-
-/* A finite state machine takes care of noticing whether or not instructions
- can be conditionally executed, and thus decrease execution time and code
- size by deleting branch instructions. The fsm is controlled by
- final_prescan_insn, and controls the actions of ASM_OUTPUT_OPCODE. */
-
-/* The state of the fsm controlling condition codes are:
- 0: normal, do nothing special
- 1: make ASM_OUTPUT_OPCODE not output this instruction
- 2: make ASM_OUTPUT_OPCODE not output this instruction
- 3: make instructions conditional
- 4: make instructions conditional
-
- State transitions (state->state by whom under condition):
- 0 -> 1 final_prescan_insn if the `target' is a label
- 0 -> 2 final_prescan_insn if the `target' is an unconditional branch
- 1 -> 3 ASM_OUTPUT_OPCODE after not having output the conditional branch
- 2 -> 4 ASM_OUTPUT_OPCODE after not having output the conditional branch
- 3 -> 0 (*targetm.asm_out.internal_label) if the `target' label is reached
- (the target label has CODE_LABEL_NUMBER equal to arm_target_label).
- 4 -> 0 final_prescan_insn if the `target' unconditional branch is reached
- (the target insn is arm_target_insn).
-
- If the jump clobbers the conditions then we use states 2 and 4.
-
- A similar thing can be done with conditional return insns.
-
- XXX In case the `target' is an unconditional branch, this conditionalising
- of the instructions always reduces code size, but not always execution
- time. But then, I want to reduce the code size to somewhere near what
- /bin/cc produces. */
-
-/* In addition to this, state is maintained for Thumb-2 COND_EXEC
- instructions. When a COND_EXEC instruction is seen the subsequent
- instructions are scanned so that multiple conditional instructions can be
- combined into a single IT block. arm_condexec_count and arm_condexec_mask
- specify the length and true/false mask for the IT block. These will be
- decremented/zeroed by arm_asm_output_opcode as the insns are output. */
-
-/* Returns the index of the ARM condition code string in
- `arm_condition_codes', or ARM_NV if the comparison is invalid.
- COMPARISON should be an rtx like `(eq (...) (...))'. */
-
-enum arm_cond_code
-maybe_get_arm_condition_code (rtx comparison)
-{
- enum machine_mode mode = GET_MODE (XEXP (comparison, 0));
- enum arm_cond_code code;
- enum rtx_code comp_code = GET_CODE (comparison);
-
- if (GET_MODE_CLASS (mode) != MODE_CC)
- mode = SELECT_CC_MODE (comp_code, XEXP (comparison, 0),
- XEXP (comparison, 1));
-
- switch (mode)
- {
- case CC_DNEmode: code = ARM_NE; goto dominance;
- case CC_DEQmode: code = ARM_EQ; goto dominance;
- case CC_DGEmode: code = ARM_GE; goto dominance;
- case CC_DGTmode: code = ARM_GT; goto dominance;
- case CC_DLEmode: code = ARM_LE; goto dominance;
- case CC_DLTmode: code = ARM_LT; goto dominance;
- case CC_DGEUmode: code = ARM_CS; goto dominance;
- case CC_DGTUmode: code = ARM_HI; goto dominance;
- case CC_DLEUmode: code = ARM_LS; goto dominance;
- case CC_DLTUmode: code = ARM_CC;
-
- dominance:
- if (comp_code == EQ)
- return ARM_INVERSE_CONDITION_CODE (code);
- if (comp_code == NE)
- return code;
- return ARM_NV;
-
- case CC_NOOVmode:
- switch (comp_code)
- {
- case NE: return ARM_NE;
- case EQ: return ARM_EQ;
- case GE: return ARM_PL;
- case LT: return ARM_MI;
- default: return ARM_NV;
- }
-
- case CC_Zmode:
- switch (comp_code)
- {
- case NE: return ARM_NE;
- case EQ: return ARM_EQ;
- default: return ARM_NV;
- }
-
- case CC_Nmode:
- switch (comp_code)
- {
- case NE: return ARM_MI;
- case EQ: return ARM_PL;
- default: return ARM_NV;
- }
-
- case CCFPEmode:
- case CCFPmode:
- /* We can handle all cases except UNEQ and LTGT. */
- switch (comp_code)
- {
- case GE: return ARM_GE;
- case GT: return ARM_GT;
- case LE: return ARM_LS;
- case LT: return ARM_MI;
- case NE: return ARM_NE;
- case EQ: return ARM_EQ;
- case ORDERED: return ARM_VC;
- case UNORDERED: return ARM_VS;
- case UNLT: return ARM_LT;
- case UNLE: return ARM_LE;
- case UNGT: return ARM_HI;
- case UNGE: return ARM_PL;
- /* UNEQ and LTGT do not have a representation. */
- case UNEQ: /* Fall through. */
- case LTGT: /* Fall through. */
- default: return ARM_NV;
- }
-
- case CC_SWPmode:
- switch (comp_code)
- {
- case NE: return ARM_NE;
- case EQ: return ARM_EQ;
- case GE: return ARM_LE;
- case GT: return ARM_LT;
- case LE: return ARM_GE;
- case LT: return ARM_GT;
- case GEU: return ARM_LS;
- case GTU: return ARM_CC;
- case LEU: return ARM_CS;
- case LTU: return ARM_HI;
- default: return ARM_NV;
- }
-
- case CC_Cmode:
- switch (comp_code)
- {
- case LTU: return ARM_CS;
- case GEU: return ARM_CC;
- default: return ARM_NV;
- }
-
- case CC_CZmode:
- switch (comp_code)
- {
- case NE: return ARM_NE;
- case EQ: return ARM_EQ;
- case GEU: return ARM_CS;
- case GTU: return ARM_HI;
- case LEU: return ARM_LS;
- case LTU: return ARM_CC;
- default: return ARM_NV;
- }
-
- case CC_NCVmode:
- switch (comp_code)
- {
- case GE: return ARM_GE;
- case LT: return ARM_LT;
- case GEU: return ARM_CS;
- case LTU: return ARM_CC;
- default: return ARM_NV;
- }
-
- case CCmode:
- switch (comp_code)
- {
- case NE: return ARM_NE;
- case EQ: return ARM_EQ;
- case GE: return ARM_GE;
- case GT: return ARM_GT;
- case LE: return ARM_LE;
- case LT: return ARM_LT;
- case GEU: return ARM_CS;
- case GTU: return ARM_HI;
- case LEU: return ARM_LS;
- case LTU: return ARM_CC;
- default: return ARM_NV;
- }
-
- default: gcc_unreachable ();
- }
-}
-
-/* Like maybe_get_arm_condition_code, but never return ARM_NV. */
-static enum arm_cond_code
-get_arm_condition_code (rtx comparison)
-{
- enum arm_cond_code code = maybe_get_arm_condition_code (comparison);
- gcc_assert (code != ARM_NV);
- return code;
-}
-
-/* Tell arm_asm_output_opcode to output IT blocks for conditionally executed
- instructions. */
-void
-thumb2_final_prescan_insn (rtx insn)
-{
- rtx first_insn = insn;
- rtx body = PATTERN (insn);
- rtx predicate;
- enum arm_cond_code code;
- int n;
- int mask;
-
- /* Remove the previous insn from the count of insns to be output. */
- if (arm_condexec_count)
- arm_condexec_count--;
-
- /* Nothing to do if we are already inside a conditional block. */
- if (arm_condexec_count)
- return;
-
- if (GET_CODE (body) != COND_EXEC)
- return;
-
- /* Conditional jumps are implemented directly. */
- if (JUMP_P (insn))
- return;
-
- predicate = COND_EXEC_TEST (body);
- arm_current_cc = get_arm_condition_code (predicate);
-
- n = get_attr_ce_count (insn);
- arm_condexec_count = 1;
- arm_condexec_mask = (1 << n) - 1;
- arm_condexec_masklen = n;
- /* See if subsequent instructions can be combined into the same block. */
- for (;;)
- {
- insn = next_nonnote_insn (insn);
-
- /* Jumping into the middle of an IT block is illegal, so a label or
- barrier terminates the block. */
- if (!NONJUMP_INSN_P (insn) && !JUMP_P (insn))
- break;
-
- body = PATTERN (insn);
- /* USE and CLOBBER aren't really insns, so just skip them. */
- if (GET_CODE (body) == USE
- || GET_CODE (body) == CLOBBER)
- continue;
-
- /* ??? Recognize conditional jumps, and combine them with IT blocks. */
- if (GET_CODE (body) != COND_EXEC)
- break;
- /* Allow up to 4 conditionally executed instructions in a block. */
- n = get_attr_ce_count (insn);
- if (arm_condexec_masklen + n > 4)
- break;
-
- predicate = COND_EXEC_TEST (body);
- code = get_arm_condition_code (predicate);
- mask = (1 << n) - 1;
- if (arm_current_cc == code)
- arm_condexec_mask |= (mask << arm_condexec_masklen);
- else if (arm_current_cc != ARM_INVERSE_CONDITION_CODE(code))
- break;
-
- arm_condexec_count++;
- arm_condexec_masklen += n;
-
- /* A jump must be the last instruction in a conditional block. */
- if (JUMP_P (insn))
- break;
- }
- /* Restore recog_data (getting the attributes of other insns can
- destroy this array, but final.c assumes that it remains intact
- across this call). */
- extract_constrain_insn_cached (first_insn);
-}
-
-void
-arm_final_prescan_insn (rtx insn)
-{
- /* BODY will hold the body of INSN. */
- rtx body = PATTERN (insn);
-
- /* This will be 1 if trying to repeat the trick, and things need to be
- reversed if it appears to fail. */
- int reverse = 0;
-
- /* If we start with a return insn, we only succeed if we find another one. */
- int seeking_return = 0;
- enum rtx_code return_code = UNKNOWN;
-
- /* START_INSN will hold the insn from where we start looking. This is the
- first insn after the following code_label if REVERSE is true. */
- rtx start_insn = insn;
-
- /* If in state 4, check if the target branch is reached, in order to
- change back to state 0. */
- if (arm_ccfsm_state == 4)
- {
- if (insn == arm_target_insn)
- {
- arm_target_insn = NULL;
- arm_ccfsm_state = 0;
- }
- return;
- }
-
- /* If in state 3, it is possible to repeat the trick, if this insn is an
- unconditional branch to a label, and immediately following this branch
- is the previous target label which is only used once, and the label this
- branch jumps to is not too far off. */
- if (arm_ccfsm_state == 3)
- {
- if (simplejump_p (insn))
- {
- start_insn = next_nonnote_insn (start_insn);
- if (BARRIER_P (start_insn))
- {
- /* XXX Isn't this always a barrier? */
- start_insn = next_nonnote_insn (start_insn);
- }
- if (LABEL_P (start_insn)
- && CODE_LABEL_NUMBER (start_insn) == arm_target_label
- && LABEL_NUSES (start_insn) == 1)
- reverse = TRUE;
- else
- return;
- }
- else if (ANY_RETURN_P (body))
- {
- start_insn = next_nonnote_insn (start_insn);
- if (BARRIER_P (start_insn))
- start_insn = next_nonnote_insn (start_insn);
- if (LABEL_P (start_insn)
- && CODE_LABEL_NUMBER (start_insn) == arm_target_label
- && LABEL_NUSES (start_insn) == 1)
- {
- reverse = TRUE;
- seeking_return = 1;
- return_code = GET_CODE (body);
- }
- else
- return;
- }
- else
- return;
- }
-
- gcc_assert (!arm_ccfsm_state || reverse);
- if (!JUMP_P (insn))
- return;
-
- /* This jump might be paralleled with a clobber of the condition codes
- the jump should always come first */
- if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
- body = XVECEXP (body, 0, 0);
-
- if (reverse
- || (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
- && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE))
- {
- int insns_skipped;
- int fail = FALSE, succeed = FALSE;
- /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
- int then_not_else = TRUE;
- rtx this_insn = start_insn, label = 0;
-
- /* Register the insn jumped to. */
- if (reverse)
- {
- if (!seeking_return)
- label = XEXP (SET_SRC (body), 0);
- }
- else if (GET_CODE (XEXP (SET_SRC (body), 1)) == LABEL_REF)
- label = XEXP (XEXP (SET_SRC (body), 1), 0);
- else if (GET_CODE (XEXP (SET_SRC (body), 2)) == LABEL_REF)
- {
- label = XEXP (XEXP (SET_SRC (body), 2), 0);
- then_not_else = FALSE;
- }
- else if (ANY_RETURN_P (XEXP (SET_SRC (body), 1)))
- {
- seeking_return = 1;
- return_code = GET_CODE (XEXP (SET_SRC (body), 1));
- }
- else if (ANY_RETURN_P (XEXP (SET_SRC (body), 2)))
- {
- seeking_return = 1;
- return_code = GET_CODE (XEXP (SET_SRC (body), 2));
- then_not_else = FALSE;
- }
- else
- gcc_unreachable ();
-
- /* See how many insns this branch skips, and what kind of insns. If all
- insns are okay, and the label or unconditional branch to the same
- label is not too far away, succeed. */
- for (insns_skipped = 0;
- !fail && !succeed && insns_skipped++ < max_insns_skipped;)
- {
- rtx scanbody;
-
- this_insn = next_nonnote_insn (this_insn);
- if (!this_insn)
- break;
-
- switch (GET_CODE (this_insn))
- {
- case CODE_LABEL:
- /* Succeed if it is the target label, otherwise fail since
- control falls in from somewhere else. */
- if (this_insn == label)
- {
- arm_ccfsm_state = 1;
- succeed = TRUE;
- }
- else
- fail = TRUE;
- break;
-
- case BARRIER:
- /* Succeed if the following insn is the target label.
- Otherwise fail.
- If return insns are used then the last insn in a function
- will be a barrier. */
- this_insn = next_nonnote_insn (this_insn);
- if (this_insn && this_insn == label)
- {
- arm_ccfsm_state = 1;
- succeed = TRUE;
- }
- else
- fail = TRUE;
- break;
-
- case CALL_INSN:
- /* The AAPCS says that conditional calls should not be
- used since they make interworking inefficient (the
- linker can't transform BL<cond> into BLX). That's
- only a problem if the machine has BLX. */
- if (arm_arch5)
- {
- fail = TRUE;
- break;
- }
-
- /* Succeed if the following insn is the target label, or
- if the following two insns are a barrier and the
- target label. */
- this_insn = next_nonnote_insn (this_insn);
- if (this_insn && BARRIER_P (this_insn))
- this_insn = next_nonnote_insn (this_insn);
-
- if (this_insn && this_insn == label
- && insns_skipped < max_insns_skipped)
- {
- arm_ccfsm_state = 1;
- succeed = TRUE;
- }
- else
- fail = TRUE;
- break;
-
- case JUMP_INSN:
- /* If this is an unconditional branch to the same label, succeed.
- If it is to another label, do nothing. If it is conditional,
- fail. */
- /* XXX Probably, the tests for SET and the PC are
- unnecessary. */
-
- scanbody = PATTERN (this_insn);
- if (GET_CODE (scanbody) == SET
- && GET_CODE (SET_DEST (scanbody)) == PC)
- {
- if (GET_CODE (SET_SRC (scanbody)) == LABEL_REF
- && XEXP (SET_SRC (scanbody), 0) == label && !reverse)
- {
- arm_ccfsm_state = 2;
- succeed = TRUE;
- }
- else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE)
- fail = TRUE;
- }
- /* Fail if a conditional return is undesirable (e.g. on a
- StrongARM), but still allow this if optimizing for size. */
- else if (GET_CODE (scanbody) == return_code
- && !use_return_insn (TRUE, NULL)
- && !optimize_size)
- fail = TRUE;
- else if (GET_CODE (scanbody) == return_code)
- {
- arm_ccfsm_state = 2;
- succeed = TRUE;
- }
- else if (GET_CODE (scanbody) == PARALLEL)
- {
- switch (get_attr_conds (this_insn))
- {
- case CONDS_NOCOND:
- break;
- default:
- fail = TRUE;
- break;
- }
- }
- else
- fail = TRUE; /* Unrecognized jump (e.g. epilogue). */
-
- break;
-
- case INSN:
- /* Instructions using or affecting the condition codes make it
- fail. */
- scanbody = PATTERN (this_insn);
- if (!(GET_CODE (scanbody) == SET
- || GET_CODE (scanbody) == PARALLEL)
- || get_attr_conds (this_insn) != CONDS_NOCOND)
- fail = TRUE;
- break;
-
- default:
- break;
- }
- }
- if (succeed)
- {
- if ((!seeking_return) && (arm_ccfsm_state == 1 || reverse))
- arm_target_label = CODE_LABEL_NUMBER (label);
- else
- {
- gcc_assert (seeking_return || arm_ccfsm_state == 2);
-
- while (this_insn && GET_CODE (PATTERN (this_insn)) == USE)
- {
- this_insn = next_nonnote_insn (this_insn);
- gcc_assert (!this_insn
- || (!BARRIER_P (this_insn)
- && !LABEL_P (this_insn)));
- }
- if (!this_insn)
- {
- /* Oh, dear! we ran off the end.. give up. */
- extract_constrain_insn_cached (insn);
- arm_ccfsm_state = 0;
- arm_target_insn = NULL;
- return;
- }
- arm_target_insn = this_insn;
- }
-
- /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
- what it was. */
- if (!reverse)
- arm_current_cc = get_arm_condition_code (XEXP (SET_SRC (body), 0));
-
- if (reverse || then_not_else)
- arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
- }
-
- /* Restore recog_data (getting the attributes of other insns can
- destroy this array, but final.c assumes that it remains intact
- across this call. */
- extract_constrain_insn_cached (insn);
- }
-}
-
-/* Output IT instructions. */
-void
-thumb2_asm_output_opcode (FILE * stream)
-{
- char buff[5];
- int n;
-
- if (arm_condexec_mask)
- {
- for (n = 0; n < arm_condexec_masklen; n++)
- buff[n] = (arm_condexec_mask & (1 << n)) ? 't' : 'e';
- buff[n] = 0;
- asm_fprintf(stream, "i%s\t%s\n\t", buff,
- arm_condition_codes[arm_current_cc]);
- arm_condexec_mask = 0;
- }
-}
-
-/* Returns true if REGNO is a valid register
- for holding a quantity of type MODE. */
-int
-arm_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
-{
- if (GET_MODE_CLASS (mode) == MODE_CC)
- return (regno == CC_REGNUM
- || (TARGET_HARD_FLOAT && TARGET_VFP
- && regno == VFPCC_REGNUM));
-
- if (TARGET_THUMB1)
- /* For the Thumb we only allow values bigger than SImode in
- registers 0 - 6, so that there is always a second low
- register available to hold the upper part of the value.
- We probably we ought to ensure that the register is the
- start of an even numbered register pair. */
- return (ARM_NUM_REGS (mode) < 2) || (regno < LAST_LO_REGNUM);
-
- if (TARGET_HARD_FLOAT && TARGET_VFP
- && IS_VFP_REGNUM (regno))
- {
- if (mode == SFmode || mode == SImode)
- return VFP_REGNO_OK_FOR_SINGLE (regno);
-
- 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)
- && NEON_REGNO_OK_FOR_QUAD (regno))
- || (mode == TImode && NEON_REGNO_OK_FOR_NREGS (regno, 2))
- || (mode == EImode && NEON_REGNO_OK_FOR_NREGS (regno, 3))
- || (mode == OImode && NEON_REGNO_OK_FOR_NREGS (regno, 4))
- || (mode == CImode && NEON_REGNO_OK_FOR_NREGS (regno, 6))
- || (mode == XImode && NEON_REGNO_OK_FOR_NREGS (regno, 8));
-
- return FALSE;
- }
-
- if (TARGET_REALLY_IWMMXT)
- {
- if (IS_IWMMXT_GR_REGNUM (regno))
- return mode == SImode;
-
- if (IS_IWMMXT_REGNUM (regno))
- return VALID_IWMMXT_REG_MODE (mode);
- }
-
- /* 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 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)
- && ARM_NUM_REGS (mode) <= 4;
-
- if (regno == FRAME_POINTER_REGNUM
- || regno == ARG_POINTER_REGNUM)
- /* We only allow integers in the fake hard registers. */
- return GET_MODE_CLASS (mode) == MODE_INT;
-
- return FALSE;
-}
-
-/* Implement MODES_TIEABLE_P. */
-
-bool
-arm_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2)
-{
- if (GET_MODE_CLASS (mode1) == GET_MODE_CLASS (mode2))
- return true;
-
- /* We specifically want to allow elements of "structure" modes to
- be tieable to the structure. This more general condition allows
- other rarer situations too. */
- if (TARGET_NEON
- && (VALID_NEON_DREG_MODE (mode1)
- || VALID_NEON_QREG_MODE (mode1)
- || VALID_NEON_STRUCT_MODE (mode1))
- && (VALID_NEON_DREG_MODE (mode2)
- || VALID_NEON_QREG_MODE (mode2)
- || VALID_NEON_STRUCT_MODE (mode2)))
- return true;
-
- return false;
-}
-
-/* For efficiency and historical reasons LO_REGS, HI_REGS and CC_REGS are
- not used in arm mode. */
-
-enum reg_class
-arm_regno_class (int regno)
-{
- if (TARGET_THUMB1)
- {
- if (regno == STACK_POINTER_REGNUM)
- return STACK_REG;
- if (regno == CC_REGNUM)
- return CC_REG;
- if (regno < 8)
- return LO_REGS;
- return HI_REGS;
- }
-
- if (TARGET_THUMB2 && regno < 8)
- return LO_REGS;
-
- if ( regno <= LAST_ARM_REGNUM
- || regno == FRAME_POINTER_REGNUM
- || regno == ARG_POINTER_REGNUM)
- return TARGET_THUMB2 ? HI_REGS : GENERAL_REGS;
-
- if (regno == CC_REGNUM || regno == VFPCC_REGNUM)
- return TARGET_THUMB2 ? CC_REG : NO_REGS;
-
- if (IS_VFP_REGNUM (regno))
- {
- if (regno <= D7_VFP_REGNUM)
- return VFP_D0_D7_REGS;
- else if (regno <= LAST_LO_VFP_REGNUM)
- return VFP_LO_REGS;
- else
- return VFP_HI_REGS;
- }
-
- if (IS_IWMMXT_REGNUM (regno))
- return IWMMXT_REGS;
-
- if (IS_IWMMXT_GR_REGNUM (regno))
- return IWMMXT_GR_REGS;
-
- return NO_REGS;
-}
-
-/* Handle a special case when computing the offset
- of an argument from the frame pointer. */
-int
-arm_debugger_arg_offset (int value, rtx addr)
-{
- rtx insn;
-
- /* We are only interested if dbxout_parms() failed to compute the offset. */
- if (value != 0)
- return 0;
-
- /* We can only cope with the case where the address is held in a register. */
- if (!REG_P (addr))
- return 0;
-
- /* If we are using the frame pointer to point at the argument, then
- an offset of 0 is correct. */
- if (REGNO (addr) == (unsigned) HARD_FRAME_POINTER_REGNUM)
- return 0;
-
- /* If we are using the stack pointer to point at the
- argument, then an offset of 0 is correct. */
- /* ??? Check this is consistent with thumb2 frame layout. */
- if ((TARGET_THUMB || !frame_pointer_needed)
- && REGNO (addr) == SP_REGNUM)
- return 0;
-
- /* Oh dear. The argument is pointed to by a register rather
- than being held in a register, or being stored at a known
- offset from the frame pointer. Since GDB only understands
- those two kinds of argument we must translate the address
- held in the register into an offset from the frame pointer.
- We do this by searching through the insns for the function
- looking to see where this register gets its value. If the
- register is initialized from the frame pointer plus an offset
- then we are in luck and we can continue, otherwise we give up.
-
- This code is exercised by producing debugging information
- for a function with arguments like this:
-
- double func (double a, double b, int c, double d) {return d;}
-
- Without this code the stab for parameter 'd' will be set to
- an offset of 0 from the frame pointer, rather than 8. */
-
- /* The if() statement says:
-
- If the insn is a normal instruction
- and if the insn is setting the value in a register
- and if the register being set is the register holding the address of the argument
- and if the address is computing by an addition
- that involves adding to a register
- which is the frame pointer
- a constant integer
-
- then... */
-
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- {
- if ( NONJUMP_INSN_P (insn)
- && GET_CODE (PATTERN (insn)) == SET
- && REGNO (XEXP (PATTERN (insn), 0)) == REGNO (addr)
- && GET_CODE (XEXP (PATTERN (insn), 1)) == PLUS
- && REG_P (XEXP (XEXP (PATTERN (insn), 1), 0))
- && REGNO (XEXP (XEXP (PATTERN (insn), 1), 0)) == (unsigned) HARD_FRAME_POINTER_REGNUM
- && CONST_INT_P (XEXP (XEXP (PATTERN (insn), 1), 1))
- )
- {
- value = INTVAL (XEXP (XEXP (PATTERN (insn), 1), 1));
-
- break;
- }
- }
-
- if (value == 0)
- {
- debug_rtx (addr);
- warning (0, "unable to compute real location of stacked parameter");
- value = 8; /* XXX magic hack */
- }
-
- return value;
-}
-
-typedef enum {
- T_V8QI,
- T_V4HI,
- T_V2SI,
- T_V2SF,
- T_DI,
- T_V16QI,
- T_V8HI,
- T_V4SI,
- T_V4SF,
- T_V2DI,
- T_TI,
- T_EI,
- T_OI,
- T_MAX /* Size of enum. Keep last. */
-} neon_builtin_type_mode;
-
-#define TYPE_MODE_BIT(X) (1 << (X))
-
-#define TB_DREG (TYPE_MODE_BIT (T_V8QI) | TYPE_MODE_BIT (T_V4HI) \
- | TYPE_MODE_BIT (T_V2SI) | TYPE_MODE_BIT (T_V2SF) \
- | TYPE_MODE_BIT (T_DI))
-#define TB_QREG (TYPE_MODE_BIT (T_V16QI) | TYPE_MODE_BIT (T_V8HI) \
- | TYPE_MODE_BIT (T_V4SI) | TYPE_MODE_BIT (T_V4SF) \
- | TYPE_MODE_BIT (T_V2DI) | TYPE_MODE_BIT (T_TI))
-
-#define v8qi_UP T_V8QI
-#define v4hi_UP T_V4HI
-#define v2si_UP T_V2SI
-#define v2sf_UP T_V2SF
-#define di_UP T_DI
-#define v16qi_UP T_V16QI
-#define v8hi_UP T_V8HI
-#define v4si_UP T_V4SI
-#define v4sf_UP T_V4SF
-#define v2di_UP T_V2DI
-#define ti_UP T_TI
-#define ei_UP T_EI
-#define oi_UP T_OI
-
-#define UP(X) X##_UP
-
-typedef enum {
- NEON_BINOP,
- NEON_TERNOP,
- NEON_UNOP,
- NEON_GETLANE,
- NEON_SETLANE,
- NEON_CREATE,
- NEON_RINT,
- NEON_DUP,
- NEON_DUPLANE,
- NEON_COMBINE,
- NEON_SPLIT,
- NEON_LANEMUL,
- NEON_LANEMULL,
- NEON_LANEMULH,
- NEON_LANEMAC,
- NEON_SCALARMUL,
- NEON_SCALARMULL,
- NEON_SCALARMULH,
- NEON_SCALARMAC,
- NEON_CONVERT,
- NEON_FIXCONV,
- NEON_SELECT,
- NEON_RESULTPAIR,
- NEON_REINTERP,
- NEON_VTBL,
- NEON_VTBX,
- NEON_LOAD1,
- NEON_LOAD1LANE,
- NEON_STORE1,
- NEON_STORE1LANE,
- NEON_LOADSTRUCT,
- NEON_LOADSTRUCTLANE,
- NEON_STORESTRUCT,
- NEON_STORESTRUCTLANE,
- NEON_LOGICBINOP,
- NEON_SHIFTINSERT,
- NEON_SHIFTIMM,
- NEON_SHIFTACC
-} neon_itype;
-
-typedef struct {
- const char *name;
- const neon_itype itype;
- const neon_builtin_type_mode mode;
- const enum insn_code code;
- unsigned int fcode;
-} neon_builtin_datum;
-
-#define CF(N,X) CODE_FOR_neon_##N##X
-
-#define VAR1(T, N, A) \
- {#N, NEON_##T, UP (A), CF (N, A), 0}
-#define VAR2(T, N, A, B) \
- VAR1 (T, N, A), \
- {#N, NEON_##T, UP (B), CF (N, B), 0}
-#define VAR3(T, N, A, B, C) \
- VAR2 (T, N, A, B), \
- {#N, NEON_##T, UP (C), CF (N, C), 0}
-#define VAR4(T, N, A, B, C, D) \
- VAR3 (T, N, A, B, C), \
- {#N, NEON_##T, UP (D), CF (N, D), 0}
-#define VAR5(T, N, A, B, C, D, E) \
- VAR4 (T, N, A, B, C, D), \
- {#N, NEON_##T, UP (E), CF (N, E), 0}
-#define VAR6(T, N, A, B, C, D, E, F) \
- VAR5 (T, N, A, B, C, D, E), \
- {#N, NEON_##T, UP (F), CF (N, F), 0}
-#define VAR7(T, N, A, B, C, D, E, F, G) \
- VAR6 (T, N, A, B, C, D, E, F), \
- {#N, NEON_##T, UP (G), CF (N, G), 0}
-#define VAR8(T, N, A, B, C, D, E, F, G, H) \
- VAR7 (T, N, A, B, C, D, E, F, G), \
- {#N, NEON_##T, UP (H), CF (N, H), 0}
-#define VAR9(T, N, A, B, C, D, E, F, G, H, I) \
- VAR8 (T, N, A, B, C, D, E, F, G, H), \
- {#N, NEON_##T, UP (I), CF (N, I), 0}
-#define VAR10(T, N, A, B, C, D, E, F, G, H, I, J) \
- VAR9 (T, N, A, B, C, D, E, F, G, H, I), \
- {#N, NEON_##T, UP (J), CF (N, J), 0}
-
-/* The mode entries in the following table correspond to the "key" type of the
- instruction variant, i.e. equivalent to that which would be specified after
- the assembler mnemonic, which usually refers to the last vector operand.
- (Signed/unsigned/polynomial types are not differentiated between though, and
- are all mapped onto the same mode for a given element size.) The modes
- listed per instruction should be the same as those defined for that
- instruction's pattern in neon.md. */
-
-static neon_builtin_datum neon_builtin_data[] =
-{
- VAR10 (BINOP, vadd,
- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
- VAR3 (BINOP, vaddl, v8qi, v4hi, v2si),
- VAR3 (BINOP, vaddw, v8qi, v4hi, v2si),
- VAR6 (BINOP, vhadd, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
- VAR8 (BINOP, vqadd, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di),
- VAR3 (BINOP, vaddhn, v8hi, v4si, v2di),
- VAR8 (BINOP, vmul, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
- VAR8 (TERNOP, vmla, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
- VAR3 (TERNOP, vmlal, v8qi, v4hi, v2si),
- VAR2 (TERNOP, vfma, v2sf, v4sf),
- VAR2 (TERNOP, vfms, v2sf, v4sf),
- VAR8 (TERNOP, vmls, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
- VAR3 (TERNOP, vmlsl, v8qi, v4hi, v2si),
- VAR4 (BINOP, vqdmulh, v4hi, v2si, v8hi, v4si),
- VAR2 (TERNOP, vqdmlal, v4hi, v2si),
- VAR2 (TERNOP, vqdmlsl, v4hi, v2si),
- VAR3 (BINOP, vmull, v8qi, v4hi, v2si),
- VAR2 (SCALARMULL, vmull_n, v4hi, v2si),
- VAR2 (LANEMULL, vmull_lane, v4hi, v2si),
- VAR2 (SCALARMULL, vqdmull_n, v4hi, v2si),
- VAR2 (LANEMULL, vqdmull_lane, v4hi, v2si),
- VAR4 (SCALARMULH, vqdmulh_n, v4hi, v2si, v8hi, v4si),
- VAR4 (LANEMULH, vqdmulh_lane, v4hi, v2si, v8hi, v4si),
- VAR2 (BINOP, vqdmull, v4hi, v2si),
- VAR8 (BINOP, vshl, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di),
- VAR8 (BINOP, vqshl, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di),
- VAR8 (SHIFTIMM, vshr_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di),
- VAR3 (SHIFTIMM, vshrn_n, v8hi, v4si, v2di),
- VAR3 (SHIFTIMM, vqshrn_n, v8hi, v4si, v2di),
- VAR3 (SHIFTIMM, vqshrun_n, v8hi, v4si, v2di),
- VAR8 (SHIFTIMM, vshl_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di),
- VAR8 (SHIFTIMM, vqshl_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di),
- VAR8 (SHIFTIMM, vqshlu_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di),
- VAR3 (SHIFTIMM, vshll_n, v8qi, v4hi, v2si),
- VAR8 (SHIFTACC, vsra_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di),
- VAR10 (BINOP, vsub,
- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
- VAR3 (BINOP, vsubl, v8qi, v4hi, v2si),
- VAR3 (BINOP, vsubw, v8qi, v4hi, v2si),
- VAR8 (BINOP, vqsub, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di),
- VAR6 (BINOP, vhsub, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
- VAR3 (BINOP, vsubhn, v8hi, v4si, v2di),
- VAR8 (BINOP, vceq, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
- VAR8 (BINOP, vcge, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
- VAR6 (BINOP, vcgeu, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
- VAR8 (BINOP, vcgt, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
- VAR6 (BINOP, vcgtu, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
- VAR2 (BINOP, vcage, v2sf, v4sf),
- VAR2 (BINOP, vcagt, v2sf, v4sf),
- VAR6 (BINOP, vtst, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
- VAR8 (BINOP, vabd, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
- VAR3 (BINOP, vabdl, v8qi, v4hi, v2si),
- VAR6 (TERNOP, vaba, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
- VAR3 (TERNOP, vabal, v8qi, v4hi, v2si),
- VAR8 (BINOP, vmax, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
- VAR8 (BINOP, vmin, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
- VAR4 (BINOP, vpadd, v8qi, v4hi, v2si, v2sf),
- VAR6 (UNOP, vpaddl, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
- VAR6 (BINOP, vpadal, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
- VAR4 (BINOP, vpmax, v8qi, v4hi, v2si, v2sf),
- VAR4 (BINOP, vpmin, v8qi, v4hi, v2si, v2sf),
- VAR2 (BINOP, vrecps, v2sf, v4sf),
- VAR2 (BINOP, vrsqrts, v2sf, v4sf),
- VAR8 (SHIFTINSERT, vsri_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di),
- VAR8 (SHIFTINSERT, vsli_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di),
- VAR8 (UNOP, vabs, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
- VAR6 (UNOP, vqabs, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
- VAR8 (UNOP, vneg, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
- VAR6 (UNOP, vqneg, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
- VAR6 (UNOP, vcls, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
- VAR6 (UNOP, vclz, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
- VAR2 (UNOP, vcnt, v8qi, v16qi),
- VAR4 (UNOP, vrecpe, v2si, v2sf, v4si, v4sf),
- VAR4 (UNOP, vrsqrte, v2si, v2sf, v4si, v4sf),
- VAR6 (UNOP, vmvn, v8qi, v4hi, v2si, v16qi, v8hi, v4si),
- /* FIXME: vget_lane supports more variants than this! */
- VAR10 (GETLANE, vget_lane,
- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
- VAR10 (SETLANE, vset_lane,
- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
- VAR5 (CREATE, vcreate, v8qi, v4hi, v2si, v2sf, di),
- VAR10 (DUP, vdup_n,
- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
- VAR10 (DUPLANE, vdup_lane,
- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
- VAR5 (COMBINE, vcombine, v8qi, v4hi, v2si, v2sf, di),
- VAR5 (SPLIT, vget_high, v16qi, v8hi, v4si, v4sf, v2di),
- VAR5 (SPLIT, vget_low, v16qi, v8hi, v4si, v4sf, v2di),
- VAR3 (UNOP, vmovn, v8hi, v4si, v2di),
- VAR3 (UNOP, vqmovn, v8hi, v4si, v2di),
- VAR3 (UNOP, vqmovun, v8hi, v4si, v2di),
- VAR3 (UNOP, vmovl, v8qi, v4hi, v2si),
- VAR6 (LANEMUL, vmul_lane, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
- VAR6 (LANEMAC, vmla_lane, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
- VAR2 (LANEMAC, vmlal_lane, v4hi, v2si),
- VAR2 (LANEMAC, vqdmlal_lane, v4hi, v2si),
- VAR6 (LANEMAC, vmls_lane, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
- VAR2 (LANEMAC, vmlsl_lane, v4hi, v2si),
- VAR2 (LANEMAC, vqdmlsl_lane, v4hi, v2si),
- VAR6 (SCALARMUL, vmul_n, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
- VAR6 (SCALARMAC, vmla_n, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
- VAR2 (SCALARMAC, vmlal_n, v4hi, v2si),
- VAR2 (SCALARMAC, vqdmlal_n, v4hi, v2si),
- VAR6 (SCALARMAC, vmls_n, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
- VAR2 (SCALARMAC, vmlsl_n, v4hi, v2si),
- VAR2 (SCALARMAC, vqdmlsl_n, v4hi, v2si),
- VAR10 (BINOP, vext,
- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
- VAR8 (UNOP, vrev64, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
- VAR4 (UNOP, vrev32, v8qi, v4hi, v16qi, v8hi),
- VAR2 (UNOP, vrev16, v8qi, v16qi),
- VAR4 (CONVERT, vcvt, v2si, v2sf, v4si, v4sf),
- VAR4 (FIXCONV, vcvt_n, v2si, v2sf, v4si, v4sf),
- VAR10 (SELECT, vbsl,
- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
- VAR2 (RINT, vrintn, v2sf, v4sf),
- VAR2 (RINT, vrinta, v2sf, v4sf),
- VAR2 (RINT, vrintp, v2sf, v4sf),
- VAR2 (RINT, vrintm, v2sf, v4sf),
- VAR2 (RINT, vrintz, v2sf, v4sf),
- VAR2 (RINT, vrintx, v2sf, v4sf),
- VAR1 (VTBL, vtbl1, v8qi),
- VAR1 (VTBL, vtbl2, v8qi),
- VAR1 (VTBL, vtbl3, v8qi),
- VAR1 (VTBL, vtbl4, v8qi),
- VAR1 (VTBX, vtbx1, v8qi),
- VAR1 (VTBX, vtbx2, v8qi),
- VAR1 (VTBX, vtbx3, v8qi),
- VAR1 (VTBX, vtbx4, v8qi),
- VAR8 (RESULTPAIR, vtrn, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
- VAR8 (RESULTPAIR, vzip, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
- VAR8 (RESULTPAIR, vuzp, v8qi, v4hi, v2si, v2sf, v16qi, v8hi, v4si, v4sf),
- VAR5 (REINTERP, vreinterpretv8qi, v8qi, v4hi, v2si, v2sf, di),
- VAR5 (REINTERP, vreinterpretv4hi, v8qi, v4hi, v2si, v2sf, di),
- VAR5 (REINTERP, vreinterpretv2si, v8qi, v4hi, v2si, v2sf, di),
- VAR5 (REINTERP, vreinterpretv2sf, v8qi, v4hi, v2si, v2sf, di),
- VAR5 (REINTERP, vreinterpretdi, v8qi, v4hi, v2si, v2sf, di),
- VAR5 (REINTERP, vreinterpretv16qi, v16qi, v8hi, v4si, v4sf, v2di),
- VAR5 (REINTERP, vreinterpretv8hi, v16qi, v8hi, v4si, v4sf, v2di),
- VAR5 (REINTERP, vreinterpretv4si, v16qi, v8hi, v4si, v4sf, v2di),
- VAR5 (REINTERP, vreinterpretv4sf, v16qi, v8hi, v4si, v4sf, v2di),
- VAR5 (REINTERP, vreinterpretv2di, v16qi, v8hi, v4si, v4sf, v2di),
- VAR10 (LOAD1, vld1,
- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
- VAR10 (LOAD1LANE, vld1_lane,
- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
- VAR10 (LOAD1, vld1_dup,
- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
- VAR10 (STORE1, vst1,
- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
- VAR10 (STORE1LANE, vst1_lane,
- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
- VAR9 (LOADSTRUCT,
- vld2, v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf),
- VAR7 (LOADSTRUCTLANE, vld2_lane,
- v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
- VAR5 (LOADSTRUCT, vld2_dup, v8qi, v4hi, v2si, v2sf, di),
- VAR9 (STORESTRUCT, vst2,
- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf),
- VAR7 (STORESTRUCTLANE, vst2_lane,
- v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
- VAR9 (LOADSTRUCT,
- vld3, v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf),
- VAR7 (LOADSTRUCTLANE, vld3_lane,
- v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
- VAR5 (LOADSTRUCT, vld3_dup, v8qi, v4hi, v2si, v2sf, di),
- VAR9 (STORESTRUCT, vst3,
- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf),
- VAR7 (STORESTRUCTLANE, vst3_lane,
- v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
- VAR9 (LOADSTRUCT, vld4,
- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf),
- VAR7 (LOADSTRUCTLANE, vld4_lane,
- v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
- VAR5 (LOADSTRUCT, vld4_dup, v8qi, v4hi, v2si, v2sf, di),
- VAR9 (STORESTRUCT, vst4,
- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf),
- VAR7 (STORESTRUCTLANE, vst4_lane,
- v8qi, v4hi, v2si, v2sf, v8hi, v4si, v4sf),
- VAR10 (LOGICBINOP, vand,
- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
- VAR10 (LOGICBINOP, vorr,
- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
- VAR10 (BINOP, veor,
- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
- VAR10 (LOGICBINOP, vbic,
- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di),
- VAR10 (LOGICBINOP, vorn,
- v8qi, v4hi, v2si, v2sf, di, v16qi, v8hi, v4si, v4sf, v2di)
-};
-
-#undef CF
-#undef VAR1
-#undef VAR2
-#undef VAR3
-#undef VAR4
-#undef VAR5
-#undef VAR6
-#undef VAR7
-#undef VAR8
-#undef VAR9
-#undef VAR10
-
-/* Neon defines builtins from ARM_BUILTIN_MAX upwards, though they don't have
- symbolic names defined here (which would require too much duplication).
- FIXME? */
-enum arm_builtins
-{
- ARM_BUILTIN_GETWCGR0,
- ARM_BUILTIN_GETWCGR1,
- ARM_BUILTIN_GETWCGR2,
- ARM_BUILTIN_GETWCGR3,
-
- ARM_BUILTIN_SETWCGR0,
- ARM_BUILTIN_SETWCGR1,
- ARM_BUILTIN_SETWCGR2,
- ARM_BUILTIN_SETWCGR3,
-
- ARM_BUILTIN_WZERO,
-
- ARM_BUILTIN_WAVG2BR,
- ARM_BUILTIN_WAVG2HR,
- ARM_BUILTIN_WAVG2B,
- ARM_BUILTIN_WAVG2H,
-
- ARM_BUILTIN_WACCB,
- ARM_BUILTIN_WACCH,
- ARM_BUILTIN_WACCW,
-
- ARM_BUILTIN_WMACS,
- ARM_BUILTIN_WMACSZ,
- ARM_BUILTIN_WMACU,
- ARM_BUILTIN_WMACUZ,
-
- ARM_BUILTIN_WSADB,
- ARM_BUILTIN_WSADBZ,
- ARM_BUILTIN_WSADH,
- ARM_BUILTIN_WSADHZ,
-
- ARM_BUILTIN_WALIGNI,
- ARM_BUILTIN_WALIGNR0,
- ARM_BUILTIN_WALIGNR1,
- ARM_BUILTIN_WALIGNR2,
- ARM_BUILTIN_WALIGNR3,
-
- ARM_BUILTIN_TMIA,
- ARM_BUILTIN_TMIAPH,
- ARM_BUILTIN_TMIABB,
- ARM_BUILTIN_TMIABT,
- ARM_BUILTIN_TMIATB,
- ARM_BUILTIN_TMIATT,
-
- ARM_BUILTIN_TMOVMSKB,
- ARM_BUILTIN_TMOVMSKH,
- ARM_BUILTIN_TMOVMSKW,
-
- ARM_BUILTIN_TBCSTB,
- ARM_BUILTIN_TBCSTH,
- ARM_BUILTIN_TBCSTW,
-
- ARM_BUILTIN_WMADDS,
- ARM_BUILTIN_WMADDU,
-
- ARM_BUILTIN_WPACKHSS,
- ARM_BUILTIN_WPACKWSS,
- ARM_BUILTIN_WPACKDSS,
- ARM_BUILTIN_WPACKHUS,
- ARM_BUILTIN_WPACKWUS,
- ARM_BUILTIN_WPACKDUS,
-
- ARM_BUILTIN_WADDB,
- ARM_BUILTIN_WADDH,
- ARM_BUILTIN_WADDW,
- ARM_BUILTIN_WADDSSB,
- ARM_BUILTIN_WADDSSH,
- ARM_BUILTIN_WADDSSW,
- ARM_BUILTIN_WADDUSB,
- ARM_BUILTIN_WADDUSH,
- ARM_BUILTIN_WADDUSW,
- ARM_BUILTIN_WSUBB,
- ARM_BUILTIN_WSUBH,
- ARM_BUILTIN_WSUBW,
- ARM_BUILTIN_WSUBSSB,
- ARM_BUILTIN_WSUBSSH,
- ARM_BUILTIN_WSUBSSW,
- ARM_BUILTIN_WSUBUSB,
- ARM_BUILTIN_WSUBUSH,
- ARM_BUILTIN_WSUBUSW,
-
- ARM_BUILTIN_WAND,
- ARM_BUILTIN_WANDN,
- ARM_BUILTIN_WOR,
- ARM_BUILTIN_WXOR,
-
- ARM_BUILTIN_WCMPEQB,
- ARM_BUILTIN_WCMPEQH,
- ARM_BUILTIN_WCMPEQW,
- ARM_BUILTIN_WCMPGTUB,
- ARM_BUILTIN_WCMPGTUH,
- ARM_BUILTIN_WCMPGTUW,
- ARM_BUILTIN_WCMPGTSB,
- ARM_BUILTIN_WCMPGTSH,
- ARM_BUILTIN_WCMPGTSW,
-
- ARM_BUILTIN_TEXTRMSB,
- ARM_BUILTIN_TEXTRMSH,
- ARM_BUILTIN_TEXTRMSW,
- ARM_BUILTIN_TEXTRMUB,
- ARM_BUILTIN_TEXTRMUH,
- ARM_BUILTIN_TEXTRMUW,
- ARM_BUILTIN_TINSRB,
- ARM_BUILTIN_TINSRH,
- ARM_BUILTIN_TINSRW,
-
- ARM_BUILTIN_WMAXSW,
- ARM_BUILTIN_WMAXSH,
- ARM_BUILTIN_WMAXSB,
- ARM_BUILTIN_WMAXUW,
- ARM_BUILTIN_WMAXUH,
- ARM_BUILTIN_WMAXUB,
- ARM_BUILTIN_WMINSW,
- ARM_BUILTIN_WMINSH,
- ARM_BUILTIN_WMINSB,
- ARM_BUILTIN_WMINUW,
- ARM_BUILTIN_WMINUH,
- ARM_BUILTIN_WMINUB,
-
- ARM_BUILTIN_WMULUM,
- ARM_BUILTIN_WMULSM,
- ARM_BUILTIN_WMULUL,
-
- ARM_BUILTIN_PSADBH,
- ARM_BUILTIN_WSHUFH,
-
- ARM_BUILTIN_WSLLH,
- ARM_BUILTIN_WSLLW,
- ARM_BUILTIN_WSLLD,
- ARM_BUILTIN_WSRAH,
- ARM_BUILTIN_WSRAW,
- ARM_BUILTIN_WSRAD,
- ARM_BUILTIN_WSRLH,
- ARM_BUILTIN_WSRLW,
- ARM_BUILTIN_WSRLD,
- ARM_BUILTIN_WRORH,
- ARM_BUILTIN_WRORW,
- ARM_BUILTIN_WRORD,
- ARM_BUILTIN_WSLLHI,
- ARM_BUILTIN_WSLLWI,
- ARM_BUILTIN_WSLLDI,
- ARM_BUILTIN_WSRAHI,
- ARM_BUILTIN_WSRAWI,
- ARM_BUILTIN_WSRADI,
- ARM_BUILTIN_WSRLHI,
- ARM_BUILTIN_WSRLWI,
- ARM_BUILTIN_WSRLDI,
- ARM_BUILTIN_WRORHI,
- ARM_BUILTIN_WRORWI,
- ARM_BUILTIN_WRORDI,
-
- ARM_BUILTIN_WUNPCKIHB,
- ARM_BUILTIN_WUNPCKIHH,
- ARM_BUILTIN_WUNPCKIHW,
- ARM_BUILTIN_WUNPCKILB,
- ARM_BUILTIN_WUNPCKILH,
- ARM_BUILTIN_WUNPCKILW,
-
- ARM_BUILTIN_WUNPCKEHSB,
- ARM_BUILTIN_WUNPCKEHSH,
- ARM_BUILTIN_WUNPCKEHSW,
- ARM_BUILTIN_WUNPCKEHUB,
- ARM_BUILTIN_WUNPCKEHUH,
- ARM_BUILTIN_WUNPCKEHUW,
- ARM_BUILTIN_WUNPCKELSB,
- ARM_BUILTIN_WUNPCKELSH,
- ARM_BUILTIN_WUNPCKELSW,
- ARM_BUILTIN_WUNPCKELUB,
- ARM_BUILTIN_WUNPCKELUH,
- ARM_BUILTIN_WUNPCKELUW,
-
- ARM_BUILTIN_WABSB,
- ARM_BUILTIN_WABSH,
- ARM_BUILTIN_WABSW,
-
- ARM_BUILTIN_WADDSUBHX,
- ARM_BUILTIN_WSUBADDHX,
-
- ARM_BUILTIN_WABSDIFFB,
- ARM_BUILTIN_WABSDIFFH,
- ARM_BUILTIN_WABSDIFFW,
-
- ARM_BUILTIN_WADDCH,
- ARM_BUILTIN_WADDCW,
-
- ARM_BUILTIN_WAVG4,
- ARM_BUILTIN_WAVG4R,
-
- ARM_BUILTIN_WMADDSX,
- ARM_BUILTIN_WMADDUX,
-
- ARM_BUILTIN_WMADDSN,
- ARM_BUILTIN_WMADDUN,
-
- ARM_BUILTIN_WMULWSM,
- ARM_BUILTIN_WMULWUM,
-
- ARM_BUILTIN_WMULWSMR,
- ARM_BUILTIN_WMULWUMR,
-
- ARM_BUILTIN_WMULWL,
-
- ARM_BUILTIN_WMULSMR,
- ARM_BUILTIN_WMULUMR,
-
- ARM_BUILTIN_WQMULM,
- ARM_BUILTIN_WQMULMR,
-
- ARM_BUILTIN_WQMULWM,
- ARM_BUILTIN_WQMULWMR,
-
- ARM_BUILTIN_WADDBHUSM,
- ARM_BUILTIN_WADDBHUSL,
-
- ARM_BUILTIN_WQMIABB,
- ARM_BUILTIN_WQMIABT,
- ARM_BUILTIN_WQMIATB,
- ARM_BUILTIN_WQMIATT,
-
- ARM_BUILTIN_WQMIABBN,
- ARM_BUILTIN_WQMIABTN,
- ARM_BUILTIN_WQMIATBN,
- ARM_BUILTIN_WQMIATTN,
-
- ARM_BUILTIN_WMIABB,
- ARM_BUILTIN_WMIABT,
- ARM_BUILTIN_WMIATB,
- ARM_BUILTIN_WMIATT,
-
- ARM_BUILTIN_WMIABBN,
- ARM_BUILTIN_WMIABTN,
- ARM_BUILTIN_WMIATBN,
- ARM_BUILTIN_WMIATTN,
-
- ARM_BUILTIN_WMIAWBB,
- ARM_BUILTIN_WMIAWBT,
- ARM_BUILTIN_WMIAWTB,
- ARM_BUILTIN_WMIAWTT,
-
- ARM_BUILTIN_WMIAWBBN,
- ARM_BUILTIN_WMIAWBTN,
- ARM_BUILTIN_WMIAWTBN,
- ARM_BUILTIN_WMIAWTTN,
-
- ARM_BUILTIN_WMERGE,
-
- ARM_BUILTIN_NEON_BASE,
-
- ARM_BUILTIN_MAX = ARM_BUILTIN_NEON_BASE + ARRAY_SIZE (neon_builtin_data)
-};
-
-static GTY(()) tree arm_builtin_decls[ARM_BUILTIN_MAX];
-
-static void
-arm_init_neon_builtins (void)
-{
- unsigned int i, fcode;
- tree decl;
-
- tree neon_intQI_type_node;
- tree neon_intHI_type_node;
- tree neon_polyQI_type_node;
- tree neon_polyHI_type_node;
- tree neon_intSI_type_node;
- tree neon_intDI_type_node;
- tree neon_float_type_node;
-
- tree intQI_pointer_node;
- tree intHI_pointer_node;
- tree intSI_pointer_node;
- tree intDI_pointer_node;
- tree float_pointer_node;
-
- tree const_intQI_node;
- tree const_intHI_node;
- tree const_intSI_node;
- tree const_intDI_node;
- tree const_float_node;
-
- tree const_intQI_pointer_node;
- tree const_intHI_pointer_node;
- tree const_intSI_pointer_node;
- tree const_intDI_pointer_node;
- tree const_float_pointer_node;
-
- tree V8QI_type_node;
- tree V4HI_type_node;
- tree V2SI_type_node;
- tree V2SF_type_node;
- tree V16QI_type_node;
- tree V8HI_type_node;
- tree V4SI_type_node;
- tree V4SF_type_node;
- tree V2DI_type_node;
-
- tree intUQI_type_node;
- tree intUHI_type_node;
- tree intUSI_type_node;
- tree intUDI_type_node;
-
- tree intEI_type_node;
- tree intOI_type_node;
- tree intCI_type_node;
- tree intXI_type_node;
-
- tree V8QI_pointer_node;
- tree V4HI_pointer_node;
- tree V2SI_pointer_node;
- tree V2SF_pointer_node;
- tree V16QI_pointer_node;
- tree V8HI_pointer_node;
- tree V4SI_pointer_node;
- tree V4SF_pointer_node;
- tree V2DI_pointer_node;
-
- tree void_ftype_pv8qi_v8qi_v8qi;
- tree void_ftype_pv4hi_v4hi_v4hi;
- tree void_ftype_pv2si_v2si_v2si;
- tree void_ftype_pv2sf_v2sf_v2sf;
- tree void_ftype_pdi_di_di;
- tree void_ftype_pv16qi_v16qi_v16qi;
- tree void_ftype_pv8hi_v8hi_v8hi;
- tree void_ftype_pv4si_v4si_v4si;
- tree void_ftype_pv4sf_v4sf_v4sf;
- tree void_ftype_pv2di_v2di_v2di;
-
- tree reinterp_ftype_dreg[5][5];
- tree reinterp_ftype_qreg[5][5];
- tree dreg_types[5], qreg_types[5];
-
- /* Create distinguished type nodes for NEON vector element types,
- and pointers to values of such types, so we can detect them later. */
- neon_intQI_type_node = make_signed_type (GET_MODE_PRECISION (QImode));
- neon_intHI_type_node = make_signed_type (GET_MODE_PRECISION (HImode));
- neon_polyQI_type_node = make_signed_type (GET_MODE_PRECISION (QImode));
- neon_polyHI_type_node = make_signed_type (GET_MODE_PRECISION (HImode));
- neon_intSI_type_node = make_signed_type (GET_MODE_PRECISION (SImode));
- neon_intDI_type_node = make_signed_type (GET_MODE_PRECISION (DImode));
- neon_float_type_node = make_node (REAL_TYPE);
- 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);
- intDI_pointer_node = build_pointer_type (neon_intDI_type_node);
- float_pointer_node = build_pointer_type (neon_float_type_node);
-
- /* Next create constant-qualified versions of the above types. */
- const_intQI_node = build_qualified_type (neon_intQI_type_node,
- TYPE_QUAL_CONST);
- const_intHI_node = build_qualified_type (neon_intHI_type_node,
- TYPE_QUAL_CONST);
- const_intSI_node = build_qualified_type (neon_intSI_type_node,
- TYPE_QUAL_CONST);
- const_intDI_node = build_qualified_type (neon_intDI_type_node,
- TYPE_QUAL_CONST);
- const_float_node = build_qualified_type (neon_float_type_node,
- TYPE_QUAL_CONST);
-
- const_intQI_pointer_node = build_pointer_type (const_intQI_node);
- const_intHI_pointer_node = build_pointer_type (const_intHI_node);
- const_intSI_pointer_node = build_pointer_type (const_intSI_node);
- const_intDI_pointer_node = build_pointer_type (const_intDI_node);
- const_float_pointer_node = build_pointer_type (const_float_node);
-
- /* Now create vector types based on our NEON element types. */
- /* 64-bit vectors. */
- V8QI_type_node =
- build_vector_type_for_mode (neon_intQI_type_node, V8QImode);
- V4HI_type_node =
- build_vector_type_for_mode (neon_intHI_type_node, V4HImode);
- V2SI_type_node =
- build_vector_type_for_mode (neon_intSI_type_node, V2SImode);
- V2SF_type_node =
- build_vector_type_for_mode (neon_float_type_node, V2SFmode);
- /* 128-bit vectors. */
- V16QI_type_node =
- build_vector_type_for_mode (neon_intQI_type_node, V16QImode);
- V8HI_type_node =
- build_vector_type_for_mode (neon_intHI_type_node, V8HImode);
- V4SI_type_node =
- build_vector_type_for_mode (neon_intSI_type_node, V4SImode);
- V4SF_type_node =
- build_vector_type_for_mode (neon_float_type_node, V4SFmode);
- V2DI_type_node =
- build_vector_type_for_mode (neon_intDI_type_node, V2DImode);
-
- /* Unsigned integer types for various mode sizes. */
- intUQI_type_node = make_unsigned_type (GET_MODE_PRECISION (QImode));
- intUHI_type_node = make_unsigned_type (GET_MODE_PRECISION (HImode));
- 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);
- V2SI_pointer_node = build_pointer_type (V2SI_type_node);
- V2SF_pointer_node = build_pointer_type (V2SF_type_node);
- V16QI_pointer_node = build_pointer_type (V16QI_type_node);
- V8HI_pointer_node = build_pointer_type (V8HI_type_node);
- V4SI_pointer_node = build_pointer_type (V4SI_type_node);
- V4SF_pointer_node = build_pointer_type (V4SF_type_node);
- V2DI_pointer_node = build_pointer_type (V2DI_type_node);
-
- /* Operations which return results as pairs. */
- void_ftype_pv8qi_v8qi_v8qi =
- build_function_type_list (void_type_node, V8QI_pointer_node, V8QI_type_node,
- V8QI_type_node, NULL);
- void_ftype_pv4hi_v4hi_v4hi =
- build_function_type_list (void_type_node, V4HI_pointer_node, V4HI_type_node,
- V4HI_type_node, NULL);
- void_ftype_pv2si_v2si_v2si =
- build_function_type_list (void_type_node, V2SI_pointer_node, V2SI_type_node,
- V2SI_type_node, NULL);
- void_ftype_pv2sf_v2sf_v2sf =
- build_function_type_list (void_type_node, V2SF_pointer_node, V2SF_type_node,
- V2SF_type_node, NULL);
- void_ftype_pdi_di_di =
- build_function_type_list (void_type_node, intDI_pointer_node,
- neon_intDI_type_node, neon_intDI_type_node, NULL);
- void_ftype_pv16qi_v16qi_v16qi =
- build_function_type_list (void_type_node, V16QI_pointer_node,
- V16QI_type_node, V16QI_type_node, NULL);
- void_ftype_pv8hi_v8hi_v8hi =
- build_function_type_list (void_type_node, V8HI_pointer_node, V8HI_type_node,
- V8HI_type_node, NULL);
- void_ftype_pv4si_v4si_v4si =
- build_function_type_list (void_type_node, V4SI_pointer_node, V4SI_type_node,
- V4SI_type_node, NULL);
- void_ftype_pv4sf_v4sf_v4sf =
- build_function_type_list (void_type_node, V4SF_pointer_node, V4SF_type_node,
- V4SF_type_node, NULL);
- void_ftype_pv2di_v2di_v2di =
- build_function_type_list (void_type_node, V2DI_pointer_node, V2DI_type_node,
- V2DI_type_node, NULL);
-
- dreg_types[0] = V8QI_type_node;
- dreg_types[1] = V4HI_type_node;
- dreg_types[2] = V2SI_type_node;
- dreg_types[3] = V2SF_type_node;
- dreg_types[4] = neon_intDI_type_node;
-
- qreg_types[0] = V16QI_type_node;
- qreg_types[1] = V8HI_type_node;
- qreg_types[2] = V4SI_type_node;
- qreg_types[3] = V4SF_type_node;
- qreg_types[4] = V2DI_type_node;
-
- for (i = 0; i < 5; i++)
- {
- int j;
- for (j = 0; j < 5; j++)
- {
- reinterp_ftype_dreg[i][j]
- = build_function_type_list (dreg_types[i], dreg_types[j], NULL);
- reinterp_ftype_qreg[i][j]
- = build_function_type_list (qreg_types[i], qreg_types[j], NULL);
- }
- }
-
- for (i = 0, fcode = ARM_BUILTIN_NEON_BASE;
- i < ARRAY_SIZE (neon_builtin_data);
- i++, fcode++)
- {
- neon_builtin_datum *d = &neon_builtin_data[i];
-
- const char* const modenames[] = {
- "v8qi", "v4hi", "v2si", "v2sf", "di",
- "v16qi", "v8hi", "v4si", "v4sf", "v2di",
- "ti", "ei", "oi"
- };
- char namebuf[60];
- tree ftype = NULL;
- int is_load = 0, is_store = 0;
-
- gcc_assert (ARRAY_SIZE (modenames) == T_MAX);
-
- d->fcode = fcode;
-
- switch (d->itype)
- {
- case NEON_LOAD1:
- case NEON_LOAD1LANE:
- case NEON_LOADSTRUCT:
- case NEON_LOADSTRUCTLANE:
- is_load = 1;
- /* Fall through. */
- case NEON_STORE1:
- case NEON_STORE1LANE:
- case NEON_STORESTRUCT:
- case NEON_STORESTRUCTLANE:
- if (!is_load)
- is_store = 1;
- /* Fall through. */
- case NEON_UNOP:
- case NEON_RINT:
- case NEON_BINOP:
- case NEON_LOGICBINOP:
- case NEON_SHIFTINSERT:
- case NEON_TERNOP:
- case NEON_GETLANE:
- case NEON_SETLANE:
- case NEON_CREATE:
- case NEON_DUP:
- case NEON_DUPLANE:
- case NEON_SHIFTIMM:
- case NEON_SHIFTACC:
- case NEON_COMBINE:
- case NEON_SPLIT:
- case NEON_CONVERT:
- case NEON_FIXCONV:
- case NEON_LANEMUL:
- case NEON_LANEMULL:
- case NEON_LANEMULH:
- case NEON_LANEMAC:
- case NEON_SCALARMUL:
- case NEON_SCALARMULL:
- case NEON_SCALARMULH:
- case NEON_SCALARMAC:
- case NEON_SELECT:
- case NEON_VTBL:
- case NEON_VTBX:
- {
- int k;
- tree return_type = void_type_node, args = void_list_node;
-
- /* Build a function type directly from the insn_data for
- this builtin. The build_function_type() function takes
- care of removing duplicates for us. */
- for (k = insn_data[d->code].n_generator_args - 1; k >= 0; k--)
- {
- tree eltype;
-
- if (is_load && k == 1)
- {
- /* Neon load patterns always have the memory
- operand in the operand 1 position. */
- gcc_assert (insn_data[d->code].operand[k].predicate
- == neon_struct_operand);
-
- switch (d->mode)
- {
- case T_V8QI:
- case T_V16QI:
- eltype = const_intQI_pointer_node;
- break;
-
- case T_V4HI:
- case T_V8HI:
- eltype = const_intHI_pointer_node;
- break;
-
- case T_V2SI:
- case T_V4SI:
- eltype = const_intSI_pointer_node;
- break;
-
- case T_V2SF:
- case T_V4SF:
- eltype = const_float_pointer_node;
- break;
-
- case T_DI:
- case T_V2DI:
- eltype = const_intDI_pointer_node;
- break;
-
- default: gcc_unreachable ();
- }
- }
- else if (is_store && k == 0)
- {
- /* Similarly, Neon store patterns use operand 0 as
- the memory location to store to. */
- gcc_assert (insn_data[d->code].operand[k].predicate
- == neon_struct_operand);
-
- switch (d->mode)
- {
- case T_V8QI:
- case T_V16QI:
- eltype = intQI_pointer_node;
- break;
-
- case T_V4HI:
- case T_V8HI:
- eltype = intHI_pointer_node;
- break;
-
- case T_V2SI:
- case T_V4SI:
- eltype = intSI_pointer_node;
- break;
-
- case T_V2SF:
- case T_V4SF:
- eltype = float_pointer_node;
- break;
-
- case T_DI:
- case T_V2DI:
- eltype = intDI_pointer_node;
- break;
-
- default: gcc_unreachable ();
- }
- }
- else
- {
- switch (insn_data[d->code].operand[k].mode)
- {
- case VOIDmode: eltype = void_type_node; break;
- /* Scalars. */
- case QImode: eltype = neon_intQI_type_node; break;
- case HImode: eltype = neon_intHI_type_node; break;
- case SImode: eltype = neon_intSI_type_node; break;
- case SFmode: eltype = neon_float_type_node; break;
- case DImode: eltype = neon_intDI_type_node; break;
- case TImode: eltype = intTI_type_node; break;
- case EImode: eltype = intEI_type_node; break;
- case OImode: eltype = intOI_type_node; break;
- case CImode: eltype = intCI_type_node; break;
- case XImode: eltype = intXI_type_node; break;
- /* 64-bit vectors. */
- case V8QImode: eltype = V8QI_type_node; break;
- case V4HImode: eltype = V4HI_type_node; break;
- case V2SImode: eltype = V2SI_type_node; break;
- case V2SFmode: eltype = V2SF_type_node; break;
- /* 128-bit vectors. */
- case V16QImode: eltype = V16QI_type_node; break;
- case V8HImode: eltype = V8HI_type_node; break;
- case V4SImode: eltype = V4SI_type_node; break;
- case V4SFmode: eltype = V4SF_type_node; break;
- case V2DImode: eltype = V2DI_type_node; break;
- default: gcc_unreachable ();
- }
- }
-
- if (k == 0 && !is_store)
- return_type = eltype;
- else
- args = tree_cons (NULL_TREE, eltype, args);
- }
-
- ftype = build_function_type (return_type, args);
- }
- break;
-
- case NEON_RESULTPAIR:
- {
- switch (insn_data[d->code].operand[1].mode)
- {
- case V8QImode: ftype = void_ftype_pv8qi_v8qi_v8qi; break;
- case V4HImode: ftype = void_ftype_pv4hi_v4hi_v4hi; break;
- case V2SImode: ftype = void_ftype_pv2si_v2si_v2si; break;
- case V2SFmode: ftype = void_ftype_pv2sf_v2sf_v2sf; break;
- case DImode: ftype = void_ftype_pdi_di_di; break;
- case V16QImode: ftype = void_ftype_pv16qi_v16qi_v16qi; break;
- case V8HImode: ftype = void_ftype_pv8hi_v8hi_v8hi; break;
- case V4SImode: ftype = void_ftype_pv4si_v4si_v4si; break;
- case V4SFmode: ftype = void_ftype_pv4sf_v4sf_v4sf; break;
- case V2DImode: ftype = void_ftype_pv2di_v2di_v2di; break;
- default: gcc_unreachable ();
- }
- }
- break;
-
- case NEON_REINTERP:
- {
- /* We iterate over 5 doubleword types, then 5 quadword
- types. */
- int rhs = d->mode % 5;
- switch (insn_data[d->code].operand[0].mode)
- {
- case V8QImode: ftype = reinterp_ftype_dreg[0][rhs]; break;
- case V4HImode: ftype = reinterp_ftype_dreg[1][rhs]; break;
- case V2SImode: ftype = reinterp_ftype_dreg[2][rhs]; break;
- case V2SFmode: ftype = reinterp_ftype_dreg[3][rhs]; break;
- case DImode: ftype = reinterp_ftype_dreg[4][rhs]; break;
- case V16QImode: ftype = reinterp_ftype_qreg[0][rhs]; break;
- case V8HImode: ftype = reinterp_ftype_qreg[1][rhs]; break;
- case V4SImode: ftype = reinterp_ftype_qreg[2][rhs]; break;
- case V4SFmode: ftype = reinterp_ftype_qreg[3][rhs]; break;
- case V2DImode: ftype = reinterp_ftype_qreg[4][rhs]; break;
- default: gcc_unreachable ();
- }
- }
- break;
-
- default:
- gcc_unreachable ();
- }
-
- gcc_assert (ftype != NULL);
-
- sprintf (namebuf, "__builtin_neon_%s%s", d->name, modenames[d->mode]);
-
- decl = add_builtin_function (namebuf, ftype, fcode, BUILT_IN_MD, NULL,
- NULL_TREE);
- arm_builtin_decls[fcode] = decl;
- }
-}
-
-#define def_mbuiltin(MASK, NAME, TYPE, CODE) \
- do \
- { \
- if ((MASK) & insn_flags) \
- { \
- tree bdecl; \
- bdecl = add_builtin_function ((NAME), (TYPE), (CODE), \
- BUILT_IN_MD, NULL, NULL_TREE); \
- arm_builtin_decls[CODE] = bdecl; \
- } \
- } \
- while (0)
-
-struct builtin_description
-{
- const unsigned int mask;
- const enum insn_code icode;
- const char * const name;
- const enum arm_builtins code;
- const enum rtx_code comparison;
- const unsigned int flag;
-};
-
-static const struct builtin_description bdesc_2arg[] =
-{
-#define IWMMXT_BUILTIN(code, string, builtin) \
- { FL_IWMMXT, CODE_FOR_##code, "__builtin_arm_" string, \
- ARM_BUILTIN_##builtin, UNKNOWN, 0 },
-
-#define IWMMXT2_BUILTIN(code, string, builtin) \
- { FL_IWMMXT2, CODE_FOR_##code, "__builtin_arm_" string, \
- ARM_BUILTIN_##builtin, UNKNOWN, 0 },
-
- IWMMXT_BUILTIN (addv8qi3, "waddb", WADDB)
- IWMMXT_BUILTIN (addv4hi3, "waddh", WADDH)
- IWMMXT_BUILTIN (addv2si3, "waddw", WADDW)
- IWMMXT_BUILTIN (subv8qi3, "wsubb", WSUBB)
- IWMMXT_BUILTIN (subv4hi3, "wsubh", WSUBH)
- IWMMXT_BUILTIN (subv2si3, "wsubw", WSUBW)
- IWMMXT_BUILTIN (ssaddv8qi3, "waddbss", WADDSSB)
- IWMMXT_BUILTIN (ssaddv4hi3, "waddhss", WADDSSH)
- IWMMXT_BUILTIN (ssaddv2si3, "waddwss", WADDSSW)
- IWMMXT_BUILTIN (sssubv8qi3, "wsubbss", WSUBSSB)
- IWMMXT_BUILTIN (sssubv4hi3, "wsubhss", WSUBSSH)
- IWMMXT_BUILTIN (sssubv2si3, "wsubwss", WSUBSSW)
- IWMMXT_BUILTIN (usaddv8qi3, "waddbus", WADDUSB)
- IWMMXT_BUILTIN (usaddv4hi3, "waddhus", WADDUSH)
- IWMMXT_BUILTIN (usaddv2si3, "waddwus", WADDUSW)
- IWMMXT_BUILTIN (ussubv8qi3, "wsubbus", WSUBUSB)
- IWMMXT_BUILTIN (ussubv4hi3, "wsubhus", WSUBUSH)
- IWMMXT_BUILTIN (ussubv2si3, "wsubwus", WSUBUSW)
- IWMMXT_BUILTIN (mulv4hi3, "wmulul", WMULUL)
- IWMMXT_BUILTIN (smulv4hi3_highpart, "wmulsm", WMULSM)
- IWMMXT_BUILTIN (umulv4hi3_highpart, "wmulum", WMULUM)
- IWMMXT_BUILTIN (eqv8qi3, "wcmpeqb", WCMPEQB)
- IWMMXT_BUILTIN (eqv4hi3, "wcmpeqh", WCMPEQH)
- IWMMXT_BUILTIN (eqv2si3, "wcmpeqw", WCMPEQW)
- IWMMXT_BUILTIN (gtuv8qi3, "wcmpgtub", WCMPGTUB)
- IWMMXT_BUILTIN (gtuv4hi3, "wcmpgtuh", WCMPGTUH)
- IWMMXT_BUILTIN (gtuv2si3, "wcmpgtuw", WCMPGTUW)
- IWMMXT_BUILTIN (gtv8qi3, "wcmpgtsb", WCMPGTSB)
- IWMMXT_BUILTIN (gtv4hi3, "wcmpgtsh", WCMPGTSH)
- IWMMXT_BUILTIN (gtv2si3, "wcmpgtsw", WCMPGTSW)
- IWMMXT_BUILTIN (umaxv8qi3, "wmaxub", WMAXUB)
- IWMMXT_BUILTIN (smaxv8qi3, "wmaxsb", WMAXSB)
- IWMMXT_BUILTIN (umaxv4hi3, "wmaxuh", WMAXUH)
- IWMMXT_BUILTIN (smaxv4hi3, "wmaxsh", WMAXSH)
- IWMMXT_BUILTIN (umaxv2si3, "wmaxuw", WMAXUW)
- IWMMXT_BUILTIN (smaxv2si3, "wmaxsw", WMAXSW)
- IWMMXT_BUILTIN (uminv8qi3, "wminub", WMINUB)
- IWMMXT_BUILTIN (sminv8qi3, "wminsb", WMINSB)
- IWMMXT_BUILTIN (uminv4hi3, "wminuh", WMINUH)
- IWMMXT_BUILTIN (sminv4hi3, "wminsh", WMINSH)
- IWMMXT_BUILTIN (uminv2si3, "wminuw", WMINUW)
- IWMMXT_BUILTIN (sminv2si3, "wminsw", WMINSW)
- IWMMXT_BUILTIN (iwmmxt_anddi3, "wand", WAND)
- IWMMXT_BUILTIN (iwmmxt_nanddi3, "wandn", WANDN)
- IWMMXT_BUILTIN (iwmmxt_iordi3, "wor", WOR)
- IWMMXT_BUILTIN (iwmmxt_xordi3, "wxor", WXOR)
- IWMMXT_BUILTIN (iwmmxt_uavgv8qi3, "wavg2b", WAVG2B)
- IWMMXT_BUILTIN (iwmmxt_uavgv4hi3, "wavg2h", WAVG2H)
- IWMMXT_BUILTIN (iwmmxt_uavgrndv8qi3, "wavg2br", WAVG2BR)
- IWMMXT_BUILTIN (iwmmxt_uavgrndv4hi3, "wavg2hr", WAVG2HR)
- IWMMXT_BUILTIN (iwmmxt_wunpckilb, "wunpckilb", WUNPCKILB)
- IWMMXT_BUILTIN (iwmmxt_wunpckilh, "wunpckilh", WUNPCKILH)
- IWMMXT_BUILTIN (iwmmxt_wunpckilw, "wunpckilw", WUNPCKILW)
- IWMMXT_BUILTIN (iwmmxt_wunpckihb, "wunpckihb", WUNPCKIHB)
- IWMMXT_BUILTIN (iwmmxt_wunpckihh, "wunpckihh", WUNPCKIHH)
- IWMMXT_BUILTIN (iwmmxt_wunpckihw, "wunpckihw", WUNPCKIHW)
- IWMMXT2_BUILTIN (iwmmxt_waddsubhx, "waddsubhx", WADDSUBHX)
- IWMMXT2_BUILTIN (iwmmxt_wsubaddhx, "wsubaddhx", WSUBADDHX)
- IWMMXT2_BUILTIN (iwmmxt_wabsdiffb, "wabsdiffb", WABSDIFFB)
- IWMMXT2_BUILTIN (iwmmxt_wabsdiffh, "wabsdiffh", WABSDIFFH)
- IWMMXT2_BUILTIN (iwmmxt_wabsdiffw, "wabsdiffw", WABSDIFFW)
- IWMMXT2_BUILTIN (iwmmxt_avg4, "wavg4", WAVG4)
- IWMMXT2_BUILTIN (iwmmxt_avg4r, "wavg4r", WAVG4R)
- IWMMXT2_BUILTIN (iwmmxt_wmulwsm, "wmulwsm", WMULWSM)
- IWMMXT2_BUILTIN (iwmmxt_wmulwum, "wmulwum", WMULWUM)
- IWMMXT2_BUILTIN (iwmmxt_wmulwsmr, "wmulwsmr", WMULWSMR)
- IWMMXT2_BUILTIN (iwmmxt_wmulwumr, "wmulwumr", WMULWUMR)
- IWMMXT2_BUILTIN (iwmmxt_wmulwl, "wmulwl", WMULWL)
- IWMMXT2_BUILTIN (iwmmxt_wmulsmr, "wmulsmr", WMULSMR)
- IWMMXT2_BUILTIN (iwmmxt_wmulumr, "wmulumr", WMULUMR)
- IWMMXT2_BUILTIN (iwmmxt_wqmulm, "wqmulm", WQMULM)
- IWMMXT2_BUILTIN (iwmmxt_wqmulmr, "wqmulmr", WQMULMR)
- IWMMXT2_BUILTIN (iwmmxt_wqmulwm, "wqmulwm", WQMULWM)
- IWMMXT2_BUILTIN (iwmmxt_wqmulwmr, "wqmulwmr", WQMULWMR)
- IWMMXT_BUILTIN (iwmmxt_walignr0, "walignr0", WALIGNR0)
- IWMMXT_BUILTIN (iwmmxt_walignr1, "walignr1", WALIGNR1)
- IWMMXT_BUILTIN (iwmmxt_walignr2, "walignr2", WALIGNR2)
- IWMMXT_BUILTIN (iwmmxt_walignr3, "walignr3", WALIGNR3)
-
-#define IWMMXT_BUILTIN2(code, builtin) \
- { FL_IWMMXT, CODE_FOR_##code, NULL, ARM_BUILTIN_##builtin, UNKNOWN, 0 },
-
-#define IWMMXT2_BUILTIN2(code, builtin) \
- { FL_IWMMXT2, CODE_FOR_##code, NULL, ARM_BUILTIN_##builtin, UNKNOWN, 0 },
-
- IWMMXT2_BUILTIN2 (iwmmxt_waddbhusm, WADDBHUSM)
- IWMMXT2_BUILTIN2 (iwmmxt_waddbhusl, WADDBHUSL)
- IWMMXT_BUILTIN2 (iwmmxt_wpackhss, WPACKHSS)
- IWMMXT_BUILTIN2 (iwmmxt_wpackwss, WPACKWSS)
- IWMMXT_BUILTIN2 (iwmmxt_wpackdss, WPACKDSS)
- IWMMXT_BUILTIN2 (iwmmxt_wpackhus, WPACKHUS)
- IWMMXT_BUILTIN2 (iwmmxt_wpackwus, WPACKWUS)
- IWMMXT_BUILTIN2 (iwmmxt_wpackdus, WPACKDUS)
- IWMMXT_BUILTIN2 (iwmmxt_wmacuz, WMACUZ)
- IWMMXT_BUILTIN2 (iwmmxt_wmacsz, WMACSZ)
-};
-
-static const struct builtin_description bdesc_1arg[] =
-{
- IWMMXT_BUILTIN (iwmmxt_tmovmskb, "tmovmskb", TMOVMSKB)
- IWMMXT_BUILTIN (iwmmxt_tmovmskh, "tmovmskh", TMOVMSKH)
- IWMMXT_BUILTIN (iwmmxt_tmovmskw, "tmovmskw", TMOVMSKW)
- IWMMXT_BUILTIN (iwmmxt_waccb, "waccb", WACCB)
- IWMMXT_BUILTIN (iwmmxt_wacch, "wacch", WACCH)
- IWMMXT_BUILTIN (iwmmxt_waccw, "waccw", WACCW)
- IWMMXT_BUILTIN (iwmmxt_wunpckehub, "wunpckehub", WUNPCKEHUB)
- IWMMXT_BUILTIN (iwmmxt_wunpckehuh, "wunpckehuh", WUNPCKEHUH)
- IWMMXT_BUILTIN (iwmmxt_wunpckehuw, "wunpckehuw", WUNPCKEHUW)
- IWMMXT_BUILTIN (iwmmxt_wunpckehsb, "wunpckehsb", WUNPCKEHSB)
- IWMMXT_BUILTIN (iwmmxt_wunpckehsh, "wunpckehsh", WUNPCKEHSH)
- IWMMXT_BUILTIN (iwmmxt_wunpckehsw, "wunpckehsw", WUNPCKEHSW)
- IWMMXT_BUILTIN (iwmmxt_wunpckelub, "wunpckelub", WUNPCKELUB)
- IWMMXT_BUILTIN (iwmmxt_wunpckeluh, "wunpckeluh", WUNPCKELUH)
- IWMMXT_BUILTIN (iwmmxt_wunpckeluw, "wunpckeluw", WUNPCKELUW)
- IWMMXT_BUILTIN (iwmmxt_wunpckelsb, "wunpckelsb", WUNPCKELSB)
- IWMMXT_BUILTIN (iwmmxt_wunpckelsh, "wunpckelsh", WUNPCKELSH)
- IWMMXT_BUILTIN (iwmmxt_wunpckelsw, "wunpckelsw", WUNPCKELSW)
- IWMMXT2_BUILTIN (iwmmxt_wabsv8qi3, "wabsb", WABSB)
- IWMMXT2_BUILTIN (iwmmxt_wabsv4hi3, "wabsh", WABSH)
- IWMMXT2_BUILTIN (iwmmxt_wabsv2si3, "wabsw", WABSW)
- IWMMXT_BUILTIN (tbcstv8qi, "tbcstb", TBCSTB)
- IWMMXT_BUILTIN (tbcstv4hi, "tbcsth", TBCSTH)
- IWMMXT_BUILTIN (tbcstv2si, "tbcstw", TBCSTW)
-};
-
-/* Set up all the iWMMXt builtins. This is not called if
- TARGET_IWMMXT is zero. */
-
-static void
-arm_init_iwmmxt_builtins (void)
-{
- const struct builtin_description * d;
- size_t i;
-
- tree V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode);
- tree V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode);
- tree V8QI_type_node = build_vector_type_for_mode (intQI_type_node, V8QImode);
-
- tree v8qi_ftype_v8qi_v8qi_int
- = build_function_type_list (V8QI_type_node,
- V8QI_type_node, V8QI_type_node,
- integer_type_node, NULL_TREE);
- tree v4hi_ftype_v4hi_int
- = build_function_type_list (V4HI_type_node,
- V4HI_type_node, integer_type_node, NULL_TREE);
- tree v2si_ftype_v2si_int
- = build_function_type_list (V2SI_type_node,
- V2SI_type_node, integer_type_node, NULL_TREE);
- tree v2si_ftype_di_di
- = build_function_type_list (V2SI_type_node,
- long_long_integer_type_node,
- long_long_integer_type_node,
- NULL_TREE);
- tree di_ftype_di_int
- = build_function_type_list (long_long_integer_type_node,
- long_long_integer_type_node,
- integer_type_node, NULL_TREE);
- tree di_ftype_di_int_int
- = build_function_type_list (long_long_integer_type_node,
- long_long_integer_type_node,
- integer_type_node,
- integer_type_node, NULL_TREE);
- tree int_ftype_v8qi
- = build_function_type_list (integer_type_node,
- V8QI_type_node, NULL_TREE);
- tree int_ftype_v4hi
- = build_function_type_list (integer_type_node,
- V4HI_type_node, NULL_TREE);
- tree int_ftype_v2si
- = build_function_type_list (integer_type_node,
- V2SI_type_node, NULL_TREE);
- tree int_ftype_v8qi_int
- = build_function_type_list (integer_type_node,
- V8QI_type_node, integer_type_node, NULL_TREE);
- tree int_ftype_v4hi_int
- = build_function_type_list (integer_type_node,
- V4HI_type_node, integer_type_node, NULL_TREE);
- tree int_ftype_v2si_int
- = build_function_type_list (integer_type_node,
- V2SI_type_node, integer_type_node, NULL_TREE);
- tree v8qi_ftype_v8qi_int_int
- = build_function_type_list (V8QI_type_node,
- V8QI_type_node, integer_type_node,
- integer_type_node, NULL_TREE);
- tree v4hi_ftype_v4hi_int_int
- = build_function_type_list (V4HI_type_node,
- V4HI_type_node, integer_type_node,
- integer_type_node, NULL_TREE);
- tree v2si_ftype_v2si_int_int
- = build_function_type_list (V2SI_type_node,
- V2SI_type_node, integer_type_node,
- integer_type_node, NULL_TREE);
- /* Miscellaneous. */
- tree v8qi_ftype_v4hi_v4hi
- = build_function_type_list (V8QI_type_node,
- V4HI_type_node, V4HI_type_node, NULL_TREE);
- tree v4hi_ftype_v2si_v2si
- = build_function_type_list (V4HI_type_node,
- V2SI_type_node, V2SI_type_node, NULL_TREE);
- tree v8qi_ftype_v4hi_v8qi
- = build_function_type_list (V8QI_type_node,
- V4HI_type_node, V8QI_type_node, NULL_TREE);
- tree v2si_ftype_v4hi_v4hi
- = build_function_type_list (V2SI_type_node,
- V4HI_type_node, V4HI_type_node, NULL_TREE);
- tree v2si_ftype_v8qi_v8qi
- = build_function_type_list (V2SI_type_node,
- V8QI_type_node, V8QI_type_node, NULL_TREE);
- tree v4hi_ftype_v4hi_di
- = build_function_type_list (V4HI_type_node,
- V4HI_type_node, long_long_integer_type_node,
- NULL_TREE);
- tree v2si_ftype_v2si_di
- = build_function_type_list (V2SI_type_node,
- V2SI_type_node, long_long_integer_type_node,
- NULL_TREE);
- tree di_ftype_void
- = build_function_type_list (long_long_unsigned_type_node, NULL_TREE);
- tree int_ftype_void
- = build_function_type_list (integer_type_node, NULL_TREE);
- tree di_ftype_v8qi
- = build_function_type_list (long_long_integer_type_node,
- V8QI_type_node, NULL_TREE);
- tree di_ftype_v4hi
- = build_function_type_list (long_long_integer_type_node,
- V4HI_type_node, NULL_TREE);
- tree di_ftype_v2si
- = build_function_type_list (long_long_integer_type_node,
- V2SI_type_node, NULL_TREE);
- tree v2si_ftype_v4hi
- = build_function_type_list (V2SI_type_node,
- V4HI_type_node, NULL_TREE);
- tree v4hi_ftype_v8qi
- = build_function_type_list (V4HI_type_node,
- V8QI_type_node, NULL_TREE);
- tree v8qi_ftype_v8qi
- = build_function_type_list (V8QI_type_node,
- V8QI_type_node, NULL_TREE);
- tree v4hi_ftype_v4hi
- = build_function_type_list (V4HI_type_node,
- V4HI_type_node, NULL_TREE);
- tree v2si_ftype_v2si
- = build_function_type_list (V2SI_type_node,
- V2SI_type_node, NULL_TREE);
-
- tree di_ftype_di_v4hi_v4hi
- = build_function_type_list (long_long_unsigned_type_node,
- long_long_unsigned_type_node,
- V4HI_type_node, V4HI_type_node,
- NULL_TREE);
-
- tree di_ftype_v4hi_v4hi
- = build_function_type_list (long_long_unsigned_type_node,
- V4HI_type_node,V4HI_type_node,
- NULL_TREE);
-
- tree v2si_ftype_v2si_v4hi_v4hi
- = build_function_type_list (V2SI_type_node,
- V2SI_type_node, V4HI_type_node,
- V4HI_type_node, NULL_TREE);
-
- tree v2si_ftype_v2si_v8qi_v8qi
- = build_function_type_list (V2SI_type_node,
- V2SI_type_node, V8QI_type_node,
- V8QI_type_node, NULL_TREE);
-
- tree di_ftype_di_v2si_v2si
- = build_function_type_list (long_long_unsigned_type_node,
- long_long_unsigned_type_node,
- V2SI_type_node, V2SI_type_node,
- NULL_TREE);
-
- tree di_ftype_di_di_int
- = build_function_type_list (long_long_unsigned_type_node,
- long_long_unsigned_type_node,
- long_long_unsigned_type_node,
- integer_type_node, NULL_TREE);
-
- tree void_ftype_int
- = build_function_type_list (void_type_node,
- integer_type_node, NULL_TREE);
-
- tree v8qi_ftype_char
- = build_function_type_list (V8QI_type_node,
- signed_char_type_node, NULL_TREE);
-
- tree v4hi_ftype_short
- = build_function_type_list (V4HI_type_node,
- short_integer_type_node, NULL_TREE);
-
- tree v2si_ftype_int
- = build_function_type_list (V2SI_type_node,
- integer_type_node, NULL_TREE);
-
- /* Normal vector binops. */
- tree v8qi_ftype_v8qi_v8qi
- = build_function_type_list (V8QI_type_node,
- V8QI_type_node, V8QI_type_node, NULL_TREE);
- tree v4hi_ftype_v4hi_v4hi
- = build_function_type_list (V4HI_type_node,
- V4HI_type_node,V4HI_type_node, NULL_TREE);
- tree v2si_ftype_v2si_v2si
- = build_function_type_list (V2SI_type_node,
- V2SI_type_node, V2SI_type_node, NULL_TREE);
- tree di_ftype_di_di
- = build_function_type_list (long_long_unsigned_type_node,
- long_long_unsigned_type_node,
- long_long_unsigned_type_node,
- NULL_TREE);
-
- /* 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. */
- enum machine_mode mode;
- tree type;
-
- if (d->name == 0)
- continue;
-
- mode = insn_data[d->icode].operand[1].mode;
-
- switch (mode)
- {
- case V8QImode:
- type = v8qi_ftype_v8qi_v8qi;
- break;
- case V4HImode:
- type = v4hi_ftype_v4hi_v4hi;
- break;
- case V2SImode:
- type = v2si_ftype_v2si_v2si;
- break;
- case DImode:
- type = di_ftype_di_di;
- break;
-
- default:
- gcc_unreachable ();
- }
-
- def_mbuiltin (d->mask, d->name, type, d->code);
- }
-
- /* Add the remaining MMX insns with somewhat more complicated types. */
-#define iwmmx_mbuiltin(NAME, TYPE, CODE) \
- def_mbuiltin (FL_IWMMXT, "__builtin_arm_" NAME, (TYPE), \
- ARM_BUILTIN_ ## CODE)
-
-#define iwmmx2_mbuiltin(NAME, TYPE, CODE) \
- def_mbuiltin (FL_IWMMXT2, "__builtin_arm_" NAME, (TYPE), \
- ARM_BUILTIN_ ## CODE)
-
- iwmmx_mbuiltin ("wzero", di_ftype_void, WZERO);
- iwmmx_mbuiltin ("setwcgr0", void_ftype_int, SETWCGR0);
- iwmmx_mbuiltin ("setwcgr1", void_ftype_int, SETWCGR1);
- iwmmx_mbuiltin ("setwcgr2", void_ftype_int, SETWCGR2);
- iwmmx_mbuiltin ("setwcgr3", void_ftype_int, SETWCGR3);
- iwmmx_mbuiltin ("getwcgr0", int_ftype_void, GETWCGR0);
- iwmmx_mbuiltin ("getwcgr1", int_ftype_void, GETWCGR1);
- iwmmx_mbuiltin ("getwcgr2", int_ftype_void, GETWCGR2);
- iwmmx_mbuiltin ("getwcgr3", int_ftype_void, GETWCGR3);
-
- iwmmx_mbuiltin ("wsllh", v4hi_ftype_v4hi_di, WSLLH);
- iwmmx_mbuiltin ("wsllw", v2si_ftype_v2si_di, WSLLW);
- iwmmx_mbuiltin ("wslld", di_ftype_di_di, WSLLD);
- iwmmx_mbuiltin ("wsllhi", v4hi_ftype_v4hi_int, WSLLHI);
- iwmmx_mbuiltin ("wsllwi", v2si_ftype_v2si_int, WSLLWI);
- iwmmx_mbuiltin ("wslldi", di_ftype_di_int, WSLLDI);
-
- iwmmx_mbuiltin ("wsrlh", v4hi_ftype_v4hi_di, WSRLH);
- iwmmx_mbuiltin ("wsrlw", v2si_ftype_v2si_di, WSRLW);
- iwmmx_mbuiltin ("wsrld", di_ftype_di_di, WSRLD);
- iwmmx_mbuiltin ("wsrlhi", v4hi_ftype_v4hi_int, WSRLHI);
- iwmmx_mbuiltin ("wsrlwi", v2si_ftype_v2si_int, WSRLWI);
- iwmmx_mbuiltin ("wsrldi", di_ftype_di_int, WSRLDI);
-
- iwmmx_mbuiltin ("wsrah", v4hi_ftype_v4hi_di, WSRAH);
- iwmmx_mbuiltin ("wsraw", v2si_ftype_v2si_di, WSRAW);
- iwmmx_mbuiltin ("wsrad", di_ftype_di_di, WSRAD);
- iwmmx_mbuiltin ("wsrahi", v4hi_ftype_v4hi_int, WSRAHI);
- iwmmx_mbuiltin ("wsrawi", v2si_ftype_v2si_int, WSRAWI);
- iwmmx_mbuiltin ("wsradi", di_ftype_di_int, WSRADI);
-
- iwmmx_mbuiltin ("wrorh", v4hi_ftype_v4hi_di, WRORH);
- iwmmx_mbuiltin ("wrorw", v2si_ftype_v2si_di, WRORW);
- iwmmx_mbuiltin ("wrord", di_ftype_di_di, WRORD);
- iwmmx_mbuiltin ("wrorhi", v4hi_ftype_v4hi_int, WRORHI);
- iwmmx_mbuiltin ("wrorwi", v2si_ftype_v2si_int, WRORWI);
- iwmmx_mbuiltin ("wrordi", di_ftype_di_int, WRORDI);
-
- iwmmx_mbuiltin ("wshufh", v4hi_ftype_v4hi_int, WSHUFH);
-
- iwmmx_mbuiltin ("wsadb", v2si_ftype_v2si_v8qi_v8qi, WSADB);
- iwmmx_mbuiltin ("wsadh", v2si_ftype_v2si_v4hi_v4hi, WSADH);
- iwmmx_mbuiltin ("wmadds", v2si_ftype_v4hi_v4hi, WMADDS);
- iwmmx2_mbuiltin ("wmaddsx", v2si_ftype_v4hi_v4hi, WMADDSX);
- iwmmx2_mbuiltin ("wmaddsn", v2si_ftype_v4hi_v4hi, WMADDSN);
- iwmmx_mbuiltin ("wmaddu", v2si_ftype_v4hi_v4hi, WMADDU);
- iwmmx2_mbuiltin ("wmaddux", v2si_ftype_v4hi_v4hi, WMADDUX);
- iwmmx2_mbuiltin ("wmaddun", v2si_ftype_v4hi_v4hi, WMADDUN);
- iwmmx_mbuiltin ("wsadbz", v2si_ftype_v8qi_v8qi, WSADBZ);
- iwmmx_mbuiltin ("wsadhz", v2si_ftype_v4hi_v4hi, WSADHZ);
-
- iwmmx_mbuiltin ("textrmsb", int_ftype_v8qi_int, TEXTRMSB);
- iwmmx_mbuiltin ("textrmsh", int_ftype_v4hi_int, TEXTRMSH);
- iwmmx_mbuiltin ("textrmsw", int_ftype_v2si_int, TEXTRMSW);
- iwmmx_mbuiltin ("textrmub", int_ftype_v8qi_int, TEXTRMUB);
- iwmmx_mbuiltin ("textrmuh", int_ftype_v4hi_int, TEXTRMUH);
- iwmmx_mbuiltin ("textrmuw", int_ftype_v2si_int, TEXTRMUW);
- iwmmx_mbuiltin ("tinsrb", v8qi_ftype_v8qi_int_int, TINSRB);
- iwmmx_mbuiltin ("tinsrh", v4hi_ftype_v4hi_int_int, TINSRH);
- iwmmx_mbuiltin ("tinsrw", v2si_ftype_v2si_int_int, TINSRW);
-
- iwmmx_mbuiltin ("waccb", di_ftype_v8qi, WACCB);
- iwmmx_mbuiltin ("wacch", di_ftype_v4hi, WACCH);
- iwmmx_mbuiltin ("waccw", di_ftype_v2si, WACCW);
-
- iwmmx_mbuiltin ("tmovmskb", int_ftype_v8qi, TMOVMSKB);
- iwmmx_mbuiltin ("tmovmskh", int_ftype_v4hi, TMOVMSKH);
- iwmmx_mbuiltin ("tmovmskw", int_ftype_v2si, TMOVMSKW);
-
- iwmmx2_mbuiltin ("waddbhusm", v8qi_ftype_v4hi_v8qi, WADDBHUSM);
- iwmmx2_mbuiltin ("waddbhusl", v8qi_ftype_v4hi_v8qi, WADDBHUSL);
-
- iwmmx_mbuiltin ("wpackhss", v8qi_ftype_v4hi_v4hi, WPACKHSS);
- iwmmx_mbuiltin ("wpackhus", v8qi_ftype_v4hi_v4hi, WPACKHUS);
- iwmmx_mbuiltin ("wpackwus", v4hi_ftype_v2si_v2si, WPACKWUS);
- iwmmx_mbuiltin ("wpackwss", v4hi_ftype_v2si_v2si, WPACKWSS);
- iwmmx_mbuiltin ("wpackdus", v2si_ftype_di_di, WPACKDUS);
- iwmmx_mbuiltin ("wpackdss", v2si_ftype_di_di, WPACKDSS);
-
- iwmmx_mbuiltin ("wunpckehub", v4hi_ftype_v8qi, WUNPCKEHUB);
- iwmmx_mbuiltin ("wunpckehuh", v2si_ftype_v4hi, WUNPCKEHUH);
- iwmmx_mbuiltin ("wunpckehuw", di_ftype_v2si, WUNPCKEHUW);
- iwmmx_mbuiltin ("wunpckehsb", v4hi_ftype_v8qi, WUNPCKEHSB);
- iwmmx_mbuiltin ("wunpckehsh", v2si_ftype_v4hi, WUNPCKEHSH);
- iwmmx_mbuiltin ("wunpckehsw", di_ftype_v2si, WUNPCKEHSW);
- iwmmx_mbuiltin ("wunpckelub", v4hi_ftype_v8qi, WUNPCKELUB);
- iwmmx_mbuiltin ("wunpckeluh", v2si_ftype_v4hi, WUNPCKELUH);
- iwmmx_mbuiltin ("wunpckeluw", di_ftype_v2si, WUNPCKELUW);
- iwmmx_mbuiltin ("wunpckelsb", v4hi_ftype_v8qi, WUNPCKELSB);
- iwmmx_mbuiltin ("wunpckelsh", v2si_ftype_v4hi, WUNPCKELSH);
- iwmmx_mbuiltin ("wunpckelsw", di_ftype_v2si, WUNPCKELSW);
-
- iwmmx_mbuiltin ("wmacs", di_ftype_di_v4hi_v4hi, WMACS);
- iwmmx_mbuiltin ("wmacsz", di_ftype_v4hi_v4hi, WMACSZ);
- iwmmx_mbuiltin ("wmacu", di_ftype_di_v4hi_v4hi, WMACU);
- iwmmx_mbuiltin ("wmacuz", di_ftype_v4hi_v4hi, WMACUZ);
-
- iwmmx_mbuiltin ("walign", v8qi_ftype_v8qi_v8qi_int, WALIGNI);
- iwmmx_mbuiltin ("tmia", di_ftype_di_int_int, TMIA);
- iwmmx_mbuiltin ("tmiaph", di_ftype_di_int_int, TMIAPH);
- iwmmx_mbuiltin ("tmiabb", di_ftype_di_int_int, TMIABB);
- iwmmx_mbuiltin ("tmiabt", di_ftype_di_int_int, TMIABT);
- iwmmx_mbuiltin ("tmiatb", di_ftype_di_int_int, TMIATB);
- iwmmx_mbuiltin ("tmiatt", di_ftype_di_int_int, TMIATT);
-
- iwmmx2_mbuiltin ("wabsb", v8qi_ftype_v8qi, WABSB);
- iwmmx2_mbuiltin ("wabsh", v4hi_ftype_v4hi, WABSH);
- iwmmx2_mbuiltin ("wabsw", v2si_ftype_v2si, WABSW);
-
- iwmmx2_mbuiltin ("wqmiabb", v2si_ftype_v2si_v4hi_v4hi, WQMIABB);
- iwmmx2_mbuiltin ("wqmiabt", v2si_ftype_v2si_v4hi_v4hi, WQMIABT);
- iwmmx2_mbuiltin ("wqmiatb", v2si_ftype_v2si_v4hi_v4hi, WQMIATB);
- iwmmx2_mbuiltin ("wqmiatt", v2si_ftype_v2si_v4hi_v4hi, WQMIATT);
-
- iwmmx2_mbuiltin ("wqmiabbn", v2si_ftype_v2si_v4hi_v4hi, WQMIABBN);
- iwmmx2_mbuiltin ("wqmiabtn", v2si_ftype_v2si_v4hi_v4hi, WQMIABTN);
- iwmmx2_mbuiltin ("wqmiatbn", v2si_ftype_v2si_v4hi_v4hi, WQMIATBN);
- iwmmx2_mbuiltin ("wqmiattn", v2si_ftype_v2si_v4hi_v4hi, WQMIATTN);
-
- iwmmx2_mbuiltin ("wmiabb", di_ftype_di_v4hi_v4hi, WMIABB);
- iwmmx2_mbuiltin ("wmiabt", di_ftype_di_v4hi_v4hi, WMIABT);
- iwmmx2_mbuiltin ("wmiatb", di_ftype_di_v4hi_v4hi, WMIATB);
- iwmmx2_mbuiltin ("wmiatt", di_ftype_di_v4hi_v4hi, WMIATT);
-
- iwmmx2_mbuiltin ("wmiabbn", di_ftype_di_v4hi_v4hi, WMIABBN);
- iwmmx2_mbuiltin ("wmiabtn", di_ftype_di_v4hi_v4hi, WMIABTN);
- iwmmx2_mbuiltin ("wmiatbn", di_ftype_di_v4hi_v4hi, WMIATBN);
- iwmmx2_mbuiltin ("wmiattn", di_ftype_di_v4hi_v4hi, WMIATTN);
-
- iwmmx2_mbuiltin ("wmiawbb", di_ftype_di_v2si_v2si, WMIAWBB);
- iwmmx2_mbuiltin ("wmiawbt", di_ftype_di_v2si_v2si, WMIAWBT);
- iwmmx2_mbuiltin ("wmiawtb", di_ftype_di_v2si_v2si, WMIAWTB);
- iwmmx2_mbuiltin ("wmiawtt", di_ftype_di_v2si_v2si, WMIAWTT);
-
- iwmmx2_mbuiltin ("wmiawbbn", di_ftype_di_v2si_v2si, WMIAWBBN);
- iwmmx2_mbuiltin ("wmiawbtn", di_ftype_di_v2si_v2si, WMIAWBTN);
- iwmmx2_mbuiltin ("wmiawtbn", di_ftype_di_v2si_v2si, WMIAWTBN);
- iwmmx2_mbuiltin ("wmiawttn", di_ftype_di_v2si_v2si, WMIAWTTN);
-
- iwmmx2_mbuiltin ("wmerge", di_ftype_di_di_int, WMERGE);
-
- iwmmx_mbuiltin ("tbcstb", v8qi_ftype_char, TBCSTB);
- iwmmx_mbuiltin ("tbcsth", v4hi_ftype_short, TBCSTH);
- iwmmx_mbuiltin ("tbcstw", v2si_ftype_int, TBCSTW);
-
-#undef iwmmx_mbuiltin
-#undef iwmmx2_mbuiltin
-}
-
-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)
-{
- if (TARGET_REALLY_IWMMXT)
- arm_init_iwmmxt_builtins ();
-
- if (TARGET_NEON)
- arm_init_neon_builtins ();
-
- if (arm_fp16_format)
- arm_init_fp16_builtins ();
-}
-
-/* Return the ARM builtin for CODE. */
-
-static tree
-arm_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
-{
- if (code >= ARM_BUILTIN_MAX)
- return error_mark_node;
-
- return arm_builtin_decls[code];
-}
-
-/* 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 if (ALL_FIXED_POINT_MODE_P (mode))
- return true;
- else
- return default_scalar_mode_supported_p (mode);
-}
-
-/* Errors in the source file can cause expand_expr to return const0_rtx
- where we expect a vector. To avoid crashing, use one of the vector
- clear instructions. */
-
-static rtx
-safe_vector_operand (rtx x, enum machine_mode mode)
-{
- if (x != const0_rtx)
- return x;
- x = gen_reg_rtx (mode);
-
- emit_insn (gen_iwmmxt_clrdi (mode == DImode ? x
- : gen_rtx_SUBREG (DImode, x, 0)));
- return x;
-}
-
-/* Subroutine of arm_expand_builtin to take care of binop insns. */
-
-static rtx
-arm_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 (VECTOR_MODE_P (mode0))
- op0 = safe_vector_operand (op0, mode0);
- if (VECTOR_MODE_P (mode1))
- op1 = safe_vector_operand (op1, mode1);
-
- if (! target
- || GET_MODE (target) != tmode
- || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
- target = gen_reg_rtx (tmode);
-
- gcc_assert ((GET_MODE (op0) == mode0 || GET_MODE (op0) == VOIDmode)
- && (GET_MODE (op1) == mode1 || GET_MODE (op1) == VOIDmode));
-
- 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);
-
- pat = GEN_FCN (icode) (target, op0, op1);
- if (! pat)
- return 0;
- emit_insn (pat);
- return target;
-}
-
-/* Subroutine of arm_expand_builtin to take care of unop insns. */
-
-static rtx
-arm_expand_unop_builtin (enum insn_code icode,
- tree exp, rtx target, int do_load)
-{
- rtx pat;
- tree arg0 = CALL_EXPR_ARG (exp, 0);
- rtx op0 = expand_normal (arg0);
- enum machine_mode tmode = insn_data[icode].operand[0].mode;
- enum machine_mode mode0 = insn_data[icode].operand[1].mode;
-
- if (! target
- || GET_MODE (target) != tmode
- || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
- target = gen_reg_rtx (tmode);
- if (do_load)
- op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
- else
- {
- if (VECTOR_MODE_P (mode0))
- op0 = safe_vector_operand (op0, mode0);
-
- if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
- }
-
- pat = GEN_FCN (icode) (target, op0);
- if (! pat)
- return 0;
- emit_insn (pat);
- return target;
-}
-
-typedef enum {
- NEON_ARG_COPY_TO_REG,
- NEON_ARG_CONSTANT,
- NEON_ARG_MEMORY,
- NEON_ARG_STOP
-} builtin_arg;
-
-#define NEON_MAX_BUILTIN_ARGS 5
-
-/* EXP is a pointer argument to a Neon load or store intrinsic. Derive
- and return an expression for the accessed memory.
-
- The intrinsic function operates on a block of registers that has
- mode REG_MODE. This block contains vectors of type TYPE_MODE. The
- function references the memory at EXP of type TYPE and in mode
- MEM_MODE; this mode may be BLKmode if no more suitable mode is
- available. */
-
-static tree
-neon_dereference_pointer (tree exp, tree type, enum machine_mode mem_mode,
- enum machine_mode reg_mode,
- neon_builtin_type_mode type_mode)
-{
- HOST_WIDE_INT reg_size, vector_size, nvectors, nelems;
- tree elem_type, upper_bound, array_type;
-
- /* Work out the size of the register block in bytes. */
- reg_size = GET_MODE_SIZE (reg_mode);
-
- /* Work out the size of each vector in bytes. */
- gcc_assert (TYPE_MODE_BIT (type_mode) & (TB_DREG | TB_QREG));
- vector_size = (TYPE_MODE_BIT (type_mode) & TB_QREG ? 16 : 8);
-
- /* Work out how many vectors there are. */
- gcc_assert (reg_size % vector_size == 0);
- nvectors = reg_size / vector_size;
-
- /* Work out the type of each element. */
- gcc_assert (POINTER_TYPE_P (type));
- elem_type = TREE_TYPE (type);
-
- /* Work out how many elements are being loaded or stored.
- MEM_MODE == REG_MODE implies a one-to-one mapping between register
- and memory elements; anything else implies a lane load or store. */
- if (mem_mode == reg_mode)
- nelems = vector_size * nvectors / int_size_in_bytes (elem_type);
- else
- nelems = nvectors;
-
- /* Create a type that describes the full access. */
- upper_bound = build_int_cst (size_type_node, nelems - 1);
- array_type = build_array_type (elem_type, build_index_type (upper_bound));
-
- /* Dereference EXP using that type. */
- return fold_build2 (MEM_REF, array_type, exp,
- build_int_cst (build_pointer_type (array_type), 0));
-}
-
-/* Expand a Neon builtin. */
-static rtx
-arm_expand_neon_args (rtx target, int icode, int have_retval,
- neon_builtin_type_mode type_mode,
- tree exp, int fcode, ...)
-{
- va_list ap;
- rtx pat;
- tree arg[NEON_MAX_BUILTIN_ARGS];
- rtx op[NEON_MAX_BUILTIN_ARGS];
- tree arg_type;
- tree formals;
- enum machine_mode tmode = insn_data[icode].operand[0].mode;
- enum machine_mode mode[NEON_MAX_BUILTIN_ARGS];
- enum machine_mode other_mode;
- int argc = 0;
- int opno;
-
- if (have_retval
- && (!target
- || GET_MODE (target) != tmode
- || !(*insn_data[icode].operand[0].predicate) (target, tmode)))
- target = gen_reg_rtx (tmode);
-
- va_start (ap, fcode);
-
- formals = TYPE_ARG_TYPES (TREE_TYPE (arm_builtin_decls[fcode]));
-
- for (;;)
- {
- builtin_arg thisarg = (builtin_arg) va_arg (ap, int);
-
- if (thisarg == NEON_ARG_STOP)
- break;
- else
- {
- opno = argc + have_retval;
- mode[argc] = insn_data[icode].operand[opno].mode;
- arg[argc] = CALL_EXPR_ARG (exp, argc);
- arg_type = TREE_VALUE (formals);
- if (thisarg == NEON_ARG_MEMORY)
- {
- other_mode = insn_data[icode].operand[1 - opno].mode;
- arg[argc] = neon_dereference_pointer (arg[argc], arg_type,
- mode[argc], other_mode,
- type_mode);
- }
-
- op[argc] = expand_normal (arg[argc]);
-
- switch (thisarg)
- {
- case NEON_ARG_COPY_TO_REG:
- /*gcc_assert (GET_MODE (op[argc]) == mode[argc]);*/
- if (!(*insn_data[icode].operand[opno].predicate)
- (op[argc], mode[argc]))
- op[argc] = copy_to_mode_reg (mode[argc], op[argc]);
- break;
-
- case NEON_ARG_CONSTANT:
- /* FIXME: This error message is somewhat unhelpful. */
- if (!(*insn_data[icode].operand[opno].predicate)
- (op[argc], mode[argc]))
- error ("argument must be a constant");
- break;
-
- case NEON_ARG_MEMORY:
- gcc_assert (MEM_P (op[argc]));
- PUT_MODE (op[argc], mode[argc]);
- /* ??? arm_neon.h uses the same built-in functions for signed
- and unsigned accesses, casting where necessary. This isn't
- alias safe. */
- set_mem_alias_set (op[argc], 0);
- if (!(*insn_data[icode].operand[opno].predicate)
- (op[argc], mode[argc]))
- op[argc] = (replace_equiv_address
- (op[argc], force_reg (Pmode, XEXP (op[argc], 0))));
- break;
-
- case NEON_ARG_STOP:
- gcc_unreachable ();
- }
-
- argc++;
- formals = TREE_CHAIN (formals);
- }
- }
-
- va_end (ap);
-
- if (have_retval)
- switch (argc)
- {
- case 1:
- pat = GEN_FCN (icode) (target, op[0]);
- break;
-
- case 2:
- pat = GEN_FCN (icode) (target, op[0], op[1]);
- break;
-
- case 3:
- pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
- break;
-
- case 4:
- pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
- break;
-
- case 5:
- pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3], op[4]);
- break;
-
- default:
- gcc_unreachable ();
- }
- else
- switch (argc)
- {
- case 1:
- pat = GEN_FCN (icode) (op[0]);
- break;
-
- case 2:
- pat = GEN_FCN (icode) (op[0], op[1]);
- break;
-
- case 3:
- pat = GEN_FCN (icode) (op[0], op[1], op[2]);
- break;
-
- case 4:
- pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
- break;
-
- case 5:
- pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4]);
- break;
-
- default:
- gcc_unreachable ();
- }
-
- if (!pat)
- return 0;
-
- emit_insn (pat);
-
- return target;
-}
-
-/* Expand a Neon builtin. These are "special" because they don't have symbolic
- constants defined per-instruction or per instruction-variant. Instead, the
- required info is looked up in the table neon_builtin_data. */
-static rtx
-arm_expand_neon_builtin (int fcode, tree exp, rtx target)
-{
- neon_builtin_datum *d = &neon_builtin_data[fcode - ARM_BUILTIN_NEON_BASE];
- neon_itype itype = d->itype;
- enum insn_code icode = d->code;
- neon_builtin_type_mode type_mode = d->mode;
-
- switch (itype)
- {
- case NEON_UNOP:
- case NEON_CONVERT:
- case NEON_DUPLANE:
- return arm_expand_neon_args (target, icode, 1, type_mode, exp, fcode,
- NEON_ARG_COPY_TO_REG, NEON_ARG_CONSTANT, NEON_ARG_STOP);
-
- case NEON_BINOP:
- case NEON_SETLANE:
- case NEON_SCALARMUL:
- case NEON_SCALARMULL:
- case NEON_SCALARMULH:
- case NEON_SHIFTINSERT:
- case NEON_LOGICBINOP:
- return arm_expand_neon_args (target, icode, 1, type_mode, exp, fcode,
- NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_CONSTANT,
- NEON_ARG_STOP);
-
- case NEON_TERNOP:
- return arm_expand_neon_args (target, icode, 1, type_mode, exp, fcode,
- NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG,
- NEON_ARG_CONSTANT, NEON_ARG_STOP);
-
- case NEON_GETLANE:
- case NEON_FIXCONV:
- case NEON_SHIFTIMM:
- return arm_expand_neon_args (target, icode, 1, type_mode, exp, fcode,
- NEON_ARG_COPY_TO_REG, NEON_ARG_CONSTANT, NEON_ARG_CONSTANT,
- NEON_ARG_STOP);
-
- case NEON_CREATE:
- return arm_expand_neon_args (target, icode, 1, type_mode, exp, fcode,
- NEON_ARG_COPY_TO_REG, NEON_ARG_STOP);
-
- case NEON_DUP:
- case NEON_RINT:
- case NEON_SPLIT:
- case NEON_REINTERP:
- return arm_expand_neon_args (target, icode, 1, type_mode, exp, fcode,
- NEON_ARG_COPY_TO_REG, NEON_ARG_STOP);
-
- case NEON_COMBINE:
- case NEON_VTBL:
- return arm_expand_neon_args (target, icode, 1, type_mode, exp, fcode,
- NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_STOP);
-
- case NEON_RESULTPAIR:
- return arm_expand_neon_args (target, icode, 0, type_mode, exp, fcode,
- NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG,
- NEON_ARG_STOP);
-
- case NEON_LANEMUL:
- case NEON_LANEMULL:
- case NEON_LANEMULH:
- return arm_expand_neon_args (target, icode, 1, type_mode, exp, fcode,
- NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_CONSTANT,
- NEON_ARG_CONSTANT, NEON_ARG_STOP);
-
- case NEON_LANEMAC:
- return arm_expand_neon_args (target, icode, 1, type_mode, exp, fcode,
- NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG,
- NEON_ARG_CONSTANT, NEON_ARG_CONSTANT, NEON_ARG_STOP);
-
- case NEON_SHIFTACC:
- return arm_expand_neon_args (target, icode, 1, type_mode, exp, fcode,
- NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_CONSTANT,
- NEON_ARG_CONSTANT, NEON_ARG_STOP);
-
- case NEON_SCALARMAC:
- return arm_expand_neon_args (target, icode, 1, type_mode, exp, fcode,
- NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG,
- NEON_ARG_CONSTANT, NEON_ARG_STOP);
-
- case NEON_SELECT:
- case NEON_VTBX:
- return arm_expand_neon_args (target, icode, 1, type_mode, exp, fcode,
- NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG, NEON_ARG_COPY_TO_REG,
- NEON_ARG_STOP);
-
- case NEON_LOAD1:
- case NEON_LOADSTRUCT:
- return arm_expand_neon_args (target, icode, 1, type_mode, exp, fcode,
- NEON_ARG_MEMORY, NEON_ARG_STOP);
-
- case NEON_LOAD1LANE:
- case NEON_LOADSTRUCTLANE:
- return arm_expand_neon_args (target, icode, 1, type_mode, exp, fcode,
- NEON_ARG_MEMORY, NEON_ARG_COPY_TO_REG, NEON_ARG_CONSTANT,
- NEON_ARG_STOP);
-
- case NEON_STORE1:
- case NEON_STORESTRUCT:
- return arm_expand_neon_args (target, icode, 0, type_mode, exp, fcode,
- NEON_ARG_MEMORY, NEON_ARG_COPY_TO_REG, NEON_ARG_STOP);
-
- case NEON_STORE1LANE:
- case NEON_STORESTRUCTLANE:
- return arm_expand_neon_args (target, icode, 0, type_mode, exp, fcode,
- NEON_ARG_MEMORY, NEON_ARG_COPY_TO_REG, NEON_ARG_CONSTANT,
- NEON_ARG_STOP);
- }
-
- gcc_unreachable ();
-}
-
-/* Emit code to reinterpret one Neon type as another, without altering bits. */
-void
-neon_reinterpret (rtx dest, rtx src)
-{
- emit_move_insn (dest, gen_lowpart (GET_MODE (dest), src));
-}
-
-/* Emit code to place a Neon pair result in memory locations (with equal
- registers). */
-void
-neon_emit_pair_result_insn (enum machine_mode mode,
- rtx (*intfn) (rtx, rtx, rtx, rtx), rtx destaddr,
- rtx op1, rtx op2)
-{
- rtx mem = gen_rtx_MEM (mode, destaddr);
- rtx tmp1 = gen_reg_rtx (mode);
- rtx tmp2 = gen_reg_rtx (mode);
-
- emit_insn (intfn (tmp1, op1, op2, tmp2));
-
- emit_move_insn (mem, tmp1);
- mem = adjust_address (mem, mode, GET_MODE_SIZE (mode));
- emit_move_insn (mem, tmp2);
-}
-
-/* Set up OPERANDS for a register copy from SRC to DEST, taking care
- not to early-clobber SRC registers in the process.
-
- We assume that the operands described by SRC and DEST represent a
- decomposed copy of OPERANDS[1] into OPERANDS[0]. COUNT is the
- number of components into which the copy has been decomposed. */
-void
-neon_disambiguate_copy (rtx *operands, rtx *dest, rtx *src, unsigned int count)
-{
- unsigned int i;
-
- if (!reg_overlap_mentioned_p (operands[0], operands[1])
- || REGNO (operands[0]) < REGNO (operands[1]))
- {
- for (i = 0; i < count; i++)
- {
- operands[2 * i] = dest[i];
- operands[2 * i + 1] = src[i];
- }
- }
- else
- {
- for (i = 0; i < count; i++)
- {
- operands[2 * i] = dest[count - i - 1];
- operands[2 * i + 1] = src[count - i - 1];
- }
- }
-}
-
-/* Split operands into moves from op[1] + op[2] into op[0]. */
-
-void
-neon_split_vcombine (rtx operands[3])
-{
- unsigned int dest = REGNO (operands[0]);
- unsigned int src1 = REGNO (operands[1]);
- unsigned int src2 = REGNO (operands[2]);
- enum machine_mode halfmode = GET_MODE (operands[1]);
- unsigned int halfregs = HARD_REGNO_NREGS (src1, halfmode);
- rtx destlo, desthi;
-
- if (src1 == dest && src2 == dest + halfregs)
- {
- /* No-op move. Can't split to nothing; emit something. */
- emit_note (NOTE_INSN_DELETED);
- return;
- }
-
- /* Preserve register attributes for variable tracking. */
- destlo = gen_rtx_REG_offset (operands[0], halfmode, dest, 0);
- desthi = gen_rtx_REG_offset (operands[0], halfmode, dest + halfregs,
- GET_MODE_SIZE (halfmode));
-
- /* Special case of reversed high/low parts. Use VSWP. */
- if (src2 == dest && src1 == dest + halfregs)
- {
- rtx x = gen_rtx_SET (VOIDmode, destlo, operands[1]);
- rtx y = gen_rtx_SET (VOIDmode, desthi, operands[2]);
- emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, x, y)));
- return;
- }
-
- if (!reg_overlap_mentioned_p (operands[2], destlo))
- {
- /* Try to avoid unnecessary moves if part of the result
- is in the right place already. */
- if (src1 != dest)
- emit_move_insn (destlo, operands[1]);
- if (src2 != dest + halfregs)
- emit_move_insn (desthi, operands[2]);
- }
- else
- {
- if (src2 != dest + halfregs)
- emit_move_insn (desthi, operands[2]);
- if (src1 != dest)
- emit_move_insn (destlo, operands[1]);
- }
-}
-
-/* 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. */
-
-static rtx
-arm_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;
- enum insn_code icode;
- tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- tree arg0;
- tree arg1;
- tree arg2;
- rtx op0;
- rtx op1;
- rtx op2;
- rtx pat;
- int fcode = DECL_FUNCTION_CODE (fndecl);
- size_t i;
- enum machine_mode tmode;
- enum machine_mode mode0;
- enum machine_mode mode1;
- enum machine_mode mode2;
- int opint;
- int selector;
- int mask;
- int imm;
-
- if (fcode >= ARM_BUILTIN_NEON_BASE)
- return arm_expand_neon_builtin (fcode, exp, target);
-
- switch (fcode)
- {
- case ARM_BUILTIN_TEXTRMSB:
- case ARM_BUILTIN_TEXTRMUB:
- case ARM_BUILTIN_TEXTRMSH:
- case ARM_BUILTIN_TEXTRMUH:
- case ARM_BUILTIN_TEXTRMSW:
- case ARM_BUILTIN_TEXTRMUW:
- icode = (fcode == ARM_BUILTIN_TEXTRMSB ? CODE_FOR_iwmmxt_textrmsb
- : fcode == ARM_BUILTIN_TEXTRMUB ? CODE_FOR_iwmmxt_textrmub
- : fcode == ARM_BUILTIN_TEXTRMSH ? CODE_FOR_iwmmxt_textrmsh
- : fcode == ARM_BUILTIN_TEXTRMUH ? CODE_FOR_iwmmxt_textrmuh
- : CODE_FOR_iwmmxt_textrmw);
-
- 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[1].predicate) (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
- if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
- {
- /* @@@ better error message */
- error ("selector must be an immediate");
- return gen_reg_rtx (tmode);
- }
-
- opint = INTVAL (op1);
- if (fcode == ARM_BUILTIN_TEXTRMSB || fcode == ARM_BUILTIN_TEXTRMUB)
- {
- if (opint > 7 || opint < 0)
- error ("the range of selector should be in 0 to 7");
- }
- else if (fcode == ARM_BUILTIN_TEXTRMSH || fcode == ARM_BUILTIN_TEXTRMUH)
- {
- if (opint > 3 || opint < 0)
- error ("the range of selector should be in 0 to 3");
- }
- else /* ARM_BUILTIN_TEXTRMSW || ARM_BUILTIN_TEXTRMUW. */
- {
- if (opint > 1 || opint < 0)
- error ("the range of selector should be in 0 to 1");
- }
-
- 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 ARM_BUILTIN_WALIGNI:
- /* If op2 is immediate, call walighi, else call walighr. */
- 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 (CONST_INT_P (op2))
- {
- icode = CODE_FOR_iwmmxt_waligni;
- tmode = insn_data[icode].operand[0].mode;
- mode0 = insn_data[icode].operand[1].mode;
- mode1 = insn_data[icode].operand[2].mode;
- mode2 = insn_data[icode].operand[3].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);
- gcc_assert ((*insn_data[icode].operand[3].predicate) (op2, mode2));
- selector = INTVAL (op2);
- if (selector > 7 || selector < 0)
- error ("the range of selector should be in 0 to 7");
- }
- else
- {
- icode = CODE_FOR_iwmmxt_walignr;
- tmode = insn_data[icode].operand[0].mode;
- mode0 = insn_data[icode].operand[1].mode;
- mode1 = insn_data[icode].operand[2].mode;
- mode2 = insn_data[icode].operand[3].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, mode2))
- op2 = copy_to_mode_reg (mode2, op2);
- }
- 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 ARM_BUILTIN_TINSRB:
- case ARM_BUILTIN_TINSRH:
- case ARM_BUILTIN_TINSRW:
- case ARM_BUILTIN_WMERGE:
- icode = (fcode == ARM_BUILTIN_TINSRB ? CODE_FOR_iwmmxt_tinsrb
- : fcode == ARM_BUILTIN_TINSRH ? CODE_FOR_iwmmxt_tinsrh
- : fcode == ARM_BUILTIN_WMERGE ? CODE_FOR_iwmmxt_wmerge
- : CODE_FOR_iwmmxt_tinsrw);
- 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;
- mode2 = insn_data[icode].operand[3].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, mode2))
- {
- error ("selector must be an immediate");
- return const0_rtx;
- }
- if (icode == CODE_FOR_iwmmxt_wmerge)
- {
- selector = INTVAL (op2);
- if (selector > 7 || selector < 0)
- error ("the range of selector should be in 0 to 7");
- }
- if ((icode == CODE_FOR_iwmmxt_tinsrb)
- || (icode == CODE_FOR_iwmmxt_tinsrh)
- || (icode == CODE_FOR_iwmmxt_tinsrw))
- {
- mask = 0x01;
- selector= INTVAL (op2);
- if (icode == CODE_FOR_iwmmxt_tinsrb && (selector < 0 || selector > 7))
- error ("the range of selector should be in 0 to 7");
- else if (icode == CODE_FOR_iwmmxt_tinsrh && (selector < 0 ||selector > 3))
- error ("the range of selector should be in 0 to 3");
- else if (icode == CODE_FOR_iwmmxt_tinsrw && (selector < 0 ||selector > 1))
- error ("the range of selector should be in 0 to 1");
- mask <<= selector;
- op2 = GEN_INT (mask);
- }
- 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 ARM_BUILTIN_SETWCGR0:
- case ARM_BUILTIN_SETWCGR1:
- case ARM_BUILTIN_SETWCGR2:
- case ARM_BUILTIN_SETWCGR3:
- icode = (fcode == ARM_BUILTIN_SETWCGR0 ? CODE_FOR_iwmmxt_setwcgr0
- : fcode == ARM_BUILTIN_SETWCGR1 ? CODE_FOR_iwmmxt_setwcgr1
- : fcode == ARM_BUILTIN_SETWCGR2 ? CODE_FOR_iwmmxt_setwcgr2
- : CODE_FOR_iwmmxt_setwcgr3);
- 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))
- op0 = copy_to_mode_reg (mode0, op0);
- pat = GEN_FCN (icode) (op0);
- if (!pat)
- return 0;
- emit_insn (pat);
- return 0;
-
- case ARM_BUILTIN_GETWCGR0:
- case ARM_BUILTIN_GETWCGR1:
- case ARM_BUILTIN_GETWCGR2:
- case ARM_BUILTIN_GETWCGR3:
- icode = (fcode == ARM_BUILTIN_GETWCGR0 ? CODE_FOR_iwmmxt_getwcgr0
- : fcode == ARM_BUILTIN_GETWCGR1 ? CODE_FOR_iwmmxt_getwcgr1
- : fcode == ARM_BUILTIN_GETWCGR2 ? CODE_FOR_iwmmxt_getwcgr2
- : CODE_FOR_iwmmxt_getwcgr3);
- 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 ARM_BUILTIN_WSHUFH:
- icode = CODE_FOR_iwmmxt_wshufh;
- 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;
- mode1 = insn_data[icode].operand[1].mode;
- mode2 = insn_data[icode].operand[2].mode;
-
- if (! (*insn_data[icode].operand[1].predicate) (op0, mode1))
- op0 = copy_to_mode_reg (mode1, op0);
- if (! (*insn_data[icode].operand[2].predicate) (op1, mode2))
- {
- error ("mask must be an immediate");
- return const0_rtx;
- }
- selector = INTVAL (op1);
- if (selector < 0 || selector > 255)
- error ("the range of mask should be in 0 to 255");
- 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 ARM_BUILTIN_WMADDS:
- return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmadds, exp, target);
- case ARM_BUILTIN_WMADDSX:
- return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsx, exp, target);
- case ARM_BUILTIN_WMADDSN:
- return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsn, exp, target);
- case ARM_BUILTIN_WMADDU:
- return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddu, exp, target);
- case ARM_BUILTIN_WMADDUX:
- return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddux, exp, target);
- case ARM_BUILTIN_WMADDUN:
- return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddun, exp, target);
- case ARM_BUILTIN_WSADBZ:
- return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadbz, exp, target);
- case ARM_BUILTIN_WSADHZ:
- return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadhz, exp, target);
-
- /* Several three-argument builtins. */
- case ARM_BUILTIN_WMACS:
- case ARM_BUILTIN_WMACU:
- case ARM_BUILTIN_TMIA:
- case ARM_BUILTIN_TMIAPH:
- case ARM_BUILTIN_TMIATT:
- case ARM_BUILTIN_TMIATB:
- case ARM_BUILTIN_TMIABT:
- case ARM_BUILTIN_TMIABB:
- case ARM_BUILTIN_WQMIABB:
- case ARM_BUILTIN_WQMIABT:
- case ARM_BUILTIN_WQMIATB:
- case ARM_BUILTIN_WQMIATT:
- case ARM_BUILTIN_WQMIABBN:
- case ARM_BUILTIN_WQMIABTN:
- case ARM_BUILTIN_WQMIATBN:
- case ARM_BUILTIN_WQMIATTN:
- case ARM_BUILTIN_WMIABB:
- case ARM_BUILTIN_WMIABT:
- case ARM_BUILTIN_WMIATB:
- case ARM_BUILTIN_WMIATT:
- case ARM_BUILTIN_WMIABBN:
- case ARM_BUILTIN_WMIABTN:
- case ARM_BUILTIN_WMIATBN:
- case ARM_BUILTIN_WMIATTN:
- case ARM_BUILTIN_WMIAWBB:
- case ARM_BUILTIN_WMIAWBT:
- case ARM_BUILTIN_WMIAWTB:
- case ARM_BUILTIN_WMIAWTT:
- case ARM_BUILTIN_WMIAWBBN:
- case ARM_BUILTIN_WMIAWBTN:
- case ARM_BUILTIN_WMIAWTBN:
- case ARM_BUILTIN_WMIAWTTN:
- case ARM_BUILTIN_WSADB:
- case ARM_BUILTIN_WSADH:
- icode = (fcode == ARM_BUILTIN_WMACS ? CODE_FOR_iwmmxt_wmacs
- : fcode == ARM_BUILTIN_WMACU ? CODE_FOR_iwmmxt_wmacu
- : fcode == ARM_BUILTIN_TMIA ? CODE_FOR_iwmmxt_tmia
- : fcode == ARM_BUILTIN_TMIAPH ? CODE_FOR_iwmmxt_tmiaph
- : fcode == ARM_BUILTIN_TMIABB ? CODE_FOR_iwmmxt_tmiabb
- : fcode == ARM_BUILTIN_TMIABT ? CODE_FOR_iwmmxt_tmiabt
- : fcode == ARM_BUILTIN_TMIATB ? CODE_FOR_iwmmxt_tmiatb
- : fcode == ARM_BUILTIN_TMIATT ? CODE_FOR_iwmmxt_tmiatt
- : fcode == ARM_BUILTIN_WQMIABB ? CODE_FOR_iwmmxt_wqmiabb
- : fcode == ARM_BUILTIN_WQMIABT ? CODE_FOR_iwmmxt_wqmiabt
- : fcode == ARM_BUILTIN_WQMIATB ? CODE_FOR_iwmmxt_wqmiatb
- : fcode == ARM_BUILTIN_WQMIATT ? CODE_FOR_iwmmxt_wqmiatt
- : fcode == ARM_BUILTIN_WQMIABBN ? CODE_FOR_iwmmxt_wqmiabbn
- : fcode == ARM_BUILTIN_WQMIABTN ? CODE_FOR_iwmmxt_wqmiabtn
- : fcode == ARM_BUILTIN_WQMIATBN ? CODE_FOR_iwmmxt_wqmiatbn
- : fcode == ARM_BUILTIN_WQMIATTN ? CODE_FOR_iwmmxt_wqmiattn
- : fcode == ARM_BUILTIN_WMIABB ? CODE_FOR_iwmmxt_wmiabb
- : fcode == ARM_BUILTIN_WMIABT ? CODE_FOR_iwmmxt_wmiabt
- : fcode == ARM_BUILTIN_WMIATB ? CODE_FOR_iwmmxt_wmiatb
- : fcode == ARM_BUILTIN_WMIATT ? CODE_FOR_iwmmxt_wmiatt
- : fcode == ARM_BUILTIN_WMIABBN ? CODE_FOR_iwmmxt_wmiabbn
- : fcode == ARM_BUILTIN_WMIABTN ? CODE_FOR_iwmmxt_wmiabtn
- : fcode == ARM_BUILTIN_WMIATBN ? CODE_FOR_iwmmxt_wmiatbn
- : fcode == ARM_BUILTIN_WMIATTN ? CODE_FOR_iwmmxt_wmiattn
- : fcode == ARM_BUILTIN_WMIAWBB ? CODE_FOR_iwmmxt_wmiawbb
- : fcode == ARM_BUILTIN_WMIAWBT ? CODE_FOR_iwmmxt_wmiawbt
- : fcode == ARM_BUILTIN_WMIAWTB ? CODE_FOR_iwmmxt_wmiawtb
- : fcode == ARM_BUILTIN_WMIAWTT ? CODE_FOR_iwmmxt_wmiawtt
- : fcode == ARM_BUILTIN_WMIAWBBN ? CODE_FOR_iwmmxt_wmiawbbn
- : fcode == ARM_BUILTIN_WMIAWBTN ? CODE_FOR_iwmmxt_wmiawbtn
- : fcode == ARM_BUILTIN_WMIAWTBN ? CODE_FOR_iwmmxt_wmiawtbn
- : fcode == ARM_BUILTIN_WMIAWTTN ? CODE_FOR_iwmmxt_wmiawttn
- : fcode == ARM_BUILTIN_WSADB ? CODE_FOR_iwmmxt_wsadb
- : CODE_FOR_iwmmxt_wsadh);
- 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;
- mode2 = insn_data[icode].operand[3].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, mode2))
- op2 = copy_to_mode_reg (mode2, op2);
- 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 ARM_BUILTIN_WZERO:
- target = gen_reg_rtx (DImode);
- emit_insn (gen_iwmmxt_clrdi (target));
- return target;
-
- case ARM_BUILTIN_WSRLHI:
- case ARM_BUILTIN_WSRLWI:
- case ARM_BUILTIN_WSRLDI:
- case ARM_BUILTIN_WSLLHI:
- case ARM_BUILTIN_WSLLWI:
- case ARM_BUILTIN_WSLLDI:
- case ARM_BUILTIN_WSRAHI:
- case ARM_BUILTIN_WSRAWI:
- case ARM_BUILTIN_WSRADI:
- case ARM_BUILTIN_WRORHI:
- case ARM_BUILTIN_WRORWI:
- case ARM_BUILTIN_WRORDI:
- case ARM_BUILTIN_WSRLH:
- case ARM_BUILTIN_WSRLW:
- case ARM_BUILTIN_WSRLD:
- case ARM_BUILTIN_WSLLH:
- case ARM_BUILTIN_WSLLW:
- case ARM_BUILTIN_WSLLD:
- case ARM_BUILTIN_WSRAH:
- case ARM_BUILTIN_WSRAW:
- case ARM_BUILTIN_WSRAD:
- case ARM_BUILTIN_WRORH:
- case ARM_BUILTIN_WRORW:
- case ARM_BUILTIN_WRORD:
- icode = (fcode == ARM_BUILTIN_WSRLHI ? CODE_FOR_lshrv4hi3_iwmmxt
- : fcode == ARM_BUILTIN_WSRLWI ? CODE_FOR_lshrv2si3_iwmmxt
- : fcode == ARM_BUILTIN_WSRLDI ? CODE_FOR_lshrdi3_iwmmxt
- : fcode == ARM_BUILTIN_WSLLHI ? CODE_FOR_ashlv4hi3_iwmmxt
- : fcode == ARM_BUILTIN_WSLLWI ? CODE_FOR_ashlv2si3_iwmmxt
- : fcode == ARM_BUILTIN_WSLLDI ? CODE_FOR_ashldi3_iwmmxt
- : fcode == ARM_BUILTIN_WSRAHI ? CODE_FOR_ashrv4hi3_iwmmxt
- : fcode == ARM_BUILTIN_WSRAWI ? CODE_FOR_ashrv2si3_iwmmxt
- : fcode == ARM_BUILTIN_WSRADI ? CODE_FOR_ashrdi3_iwmmxt
- : fcode == ARM_BUILTIN_WRORHI ? CODE_FOR_rorv4hi3
- : fcode == ARM_BUILTIN_WRORWI ? CODE_FOR_rorv2si3
- : fcode == ARM_BUILTIN_WRORDI ? CODE_FOR_rordi3
- : fcode == ARM_BUILTIN_WSRLH ? CODE_FOR_lshrv4hi3_di
- : fcode == ARM_BUILTIN_WSRLW ? CODE_FOR_lshrv2si3_di
- : fcode == ARM_BUILTIN_WSRLD ? CODE_FOR_lshrdi3_di
- : fcode == ARM_BUILTIN_WSLLH ? CODE_FOR_ashlv4hi3_di
- : fcode == ARM_BUILTIN_WSLLW ? CODE_FOR_ashlv2si3_di
- : fcode == ARM_BUILTIN_WSLLD ? CODE_FOR_ashldi3_di
- : fcode == ARM_BUILTIN_WSRAH ? CODE_FOR_ashrv4hi3_di
- : fcode == ARM_BUILTIN_WSRAW ? CODE_FOR_ashrv2si3_di
- : fcode == ARM_BUILTIN_WSRAD ? CODE_FOR_ashrdi3_di
- : fcode == ARM_BUILTIN_WRORH ? CODE_FOR_rorv4hi3_di
- : fcode == ARM_BUILTIN_WRORW ? CODE_FOR_rorv2si3_di
- : fcode == ARM_BUILTIN_WRORD ? CODE_FOR_rordi3_di
- : CODE_FOR_nothing);
- arg1 = CALL_EXPR_ARG (exp, 1);
- op1 = expand_normal (arg1);
- if (GET_MODE (op1) == VOIDmode)
- {
- imm = INTVAL (op1);
- if ((fcode == ARM_BUILTIN_WRORHI || fcode == ARM_BUILTIN_WRORWI
- || fcode == ARM_BUILTIN_WRORH || fcode == ARM_BUILTIN_WRORW)
- && (imm < 0 || imm > 32))
- {
- if (fcode == ARM_BUILTIN_WRORHI)
- error ("the range of count should be in 0 to 32. please check the intrinsic _mm_rori_pi16 in code.");
- else if (fcode == ARM_BUILTIN_WRORWI)
- error ("the range of count should be in 0 to 32. please check the intrinsic _mm_rori_pi32 in code.");
- else if (fcode == ARM_BUILTIN_WRORH)
- error ("the range of count should be in 0 to 32. please check the intrinsic _mm_ror_pi16 in code.");
- else
- error ("the range of count should be in 0 to 32. please check the intrinsic _mm_ror_pi32 in code.");
- }
- else if ((fcode == ARM_BUILTIN_WRORDI || fcode == ARM_BUILTIN_WRORD)
- && (imm < 0 || imm > 64))
- {
- if (fcode == ARM_BUILTIN_WRORDI)
- error ("the range of count should be in 0 to 64. please check the intrinsic _mm_rori_si64 in code.");
- else
- error ("the range of count should be in 0 to 64. please check the intrinsic _mm_ror_si64 in code.");
- }
- else if (imm < 0)
- {
- if (fcode == ARM_BUILTIN_WSRLHI)
- error ("the count should be no less than 0. please check the intrinsic _mm_srli_pi16 in code.");
- else if (fcode == ARM_BUILTIN_WSRLWI)
- error ("the count should be no less than 0. please check the intrinsic _mm_srli_pi32 in code.");
- else if (fcode == ARM_BUILTIN_WSRLDI)
- error ("the count should be no less than 0. please check the intrinsic _mm_srli_si64 in code.");
- else if (fcode == ARM_BUILTIN_WSLLHI)
- error ("the count should be no less than 0. please check the intrinsic _mm_slli_pi16 in code.");
- else if (fcode == ARM_BUILTIN_WSLLWI)
- error ("the count should be no less than 0. please check the intrinsic _mm_slli_pi32 in code.");
- else if (fcode == ARM_BUILTIN_WSLLDI)
- error ("the count should be no less than 0. please check the intrinsic _mm_slli_si64 in code.");
- else if (fcode == ARM_BUILTIN_WSRAHI)
- error ("the count should be no less than 0. please check the intrinsic _mm_srai_pi16 in code.");
- else if (fcode == ARM_BUILTIN_WSRAWI)
- error ("the count should be no less than 0. please check the intrinsic _mm_srai_pi32 in code.");
- else if (fcode == ARM_BUILTIN_WSRADI)
- error ("the count should be no less than 0. please check the intrinsic _mm_srai_si64 in code.");
- else if (fcode == ARM_BUILTIN_WSRLH)
- error ("the count should be no less than 0. please check the intrinsic _mm_srl_pi16 in code.");
- else if (fcode == ARM_BUILTIN_WSRLW)
- error ("the count should be no less than 0. please check the intrinsic _mm_srl_pi32 in code.");
- else if (fcode == ARM_BUILTIN_WSRLD)
- error ("the count should be no less than 0. please check the intrinsic _mm_srl_si64 in code.");
- else if (fcode == ARM_BUILTIN_WSLLH)
- error ("the count should be no less than 0. please check the intrinsic _mm_sll_pi16 in code.");
- else if (fcode == ARM_BUILTIN_WSLLW)
- error ("the count should be no less than 0. please check the intrinsic _mm_sll_pi32 in code.");
- else if (fcode == ARM_BUILTIN_WSLLD)
- error ("the count should be no less than 0. please check the intrinsic _mm_sll_si64 in code.");
- else if (fcode == ARM_BUILTIN_WSRAH)
- error ("the count should be no less than 0. please check the intrinsic _mm_sra_pi16 in code.");
- else if (fcode == ARM_BUILTIN_WSRAW)
- error ("the count should be no less than 0. please check the intrinsic _mm_sra_pi32 in code.");
- else
- error ("the count should be no less than 0. please check the intrinsic _mm_sra_si64 in code.");
- }
- }
- return arm_expand_binop_builtin (icode, exp, target);
-
- default:
- break;
- }
-
- for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
- if (d->code == (const enum arm_builtins) fcode)
- return arm_expand_binop_builtin (d->icode, exp, target);
-
- for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
- if (d->code == (const enum arm_builtins) fcode)
- return arm_expand_unop_builtin (d->icode, exp, target, 0);
-
- /* @@@ Should really do something sensible here. */
- return NULL_RTX;
-}
-
-/* Return the number (counting from 0) of
- the least significant set bit in MASK. */
-
-inline static int
-number_of_first_bit_set (unsigned mask)
-{
- return ctz_hwi (mask);
-}
-
-/* Like emit_multi_reg_push, but allowing for a different set of
- registers to be described as saved. MASK is the set of registers
- to be saved; REAL_REGS is the set of registers to be described as
- saved. If REAL_REGS is 0, only describe the stack adjustment. */
-
-static rtx
-thumb1_emit_multi_reg_push (unsigned long mask, unsigned long real_regs)
-{
- unsigned long regno;
- rtx par[10], tmp, reg, insn;
- int i, j;
-
- /* Build the parallel of the registers actually being stored. */
- for (i = 0; mask; ++i, mask &= mask - 1)
- {
- regno = ctz_hwi (mask);
- reg = gen_rtx_REG (SImode, regno);
-
- if (i == 0)
- tmp = gen_rtx_UNSPEC (BLKmode, gen_rtvec (1, reg), UNSPEC_PUSH_MULT);
- else
- tmp = gen_rtx_USE (VOIDmode, reg);
-
- par[i] = tmp;
- }
-
- tmp = plus_constant (Pmode, stack_pointer_rtx, -4 * i);
- tmp = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, tmp);
- tmp = gen_frame_mem (BLKmode, tmp);
- tmp = gen_rtx_SET (VOIDmode, tmp, par[0]);
- par[0] = tmp;
-
- tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (i, par));
- insn = emit_insn (tmp);
-
- /* Always build the stack adjustment note for unwind info. */
- tmp = plus_constant (Pmode, stack_pointer_rtx, -4 * i);
- tmp = gen_rtx_SET (VOIDmode, stack_pointer_rtx, tmp);
- par[0] = tmp;
-
- /* Build the parallel of the registers recorded as saved for unwind. */
- for (j = 0; real_regs; ++j, real_regs &= real_regs - 1)
- {
- regno = ctz_hwi (real_regs);
- reg = gen_rtx_REG (SImode, regno);
-
- tmp = plus_constant (Pmode, stack_pointer_rtx, j * 4);
- tmp = gen_frame_mem (SImode, tmp);
- tmp = gen_rtx_SET (VOIDmode, tmp, reg);
- RTX_FRAME_RELATED_P (tmp) = 1;
- par[j + 1] = tmp;
- }
-
- if (j == 0)
- tmp = par[0];
- else
- {
- RTX_FRAME_RELATED_P (par[0]) = 1;
- tmp = gen_rtx_SEQUENCE (VOIDmode, gen_rtvec_v (j + 1, par));
- }
-
- add_reg_note (insn, REG_FRAME_RELATED_EXPR, tmp);
-
- return insn;
-}
-
-/* Emit code to push or pop registers to or from the stack. F is the
- assembly file. MASK is the registers to pop. */
-static void
-thumb_pop (FILE *f, unsigned long mask)
-{
- int regno;
- int lo_mask = mask & 0xFF;
- int pushed_words = 0;
-
- gcc_assert (mask);
-
- if (lo_mask == 0 && (mask & (1 << PC_REGNUM)))
- {
- /* Special case. Do not generate a POP PC statement here, do it in
- thumb_exit() */
- thumb_exit (f, -1);
- return;
- }
-
- fprintf (f, "\tpop\t{");
-
- /* Look at the low registers first. */
- for (regno = 0; regno <= LAST_LO_REGNUM; regno++, lo_mask >>= 1)
- {
- if (lo_mask & 1)
- {
- asm_fprintf (f, "%r", regno);
-
- if ((lo_mask & ~1) != 0)
- fprintf (f, ", ");
-
- pushed_words++;
- }
- }
-
- if (mask & (1 << PC_REGNUM))
- {
- /* Catch popping the PC. */
- if (TARGET_INTERWORK || TARGET_BACKTRACE
- || crtl->calls_eh_return)
- {
- /* The PC is never poped directly, instead
- it is popped into r3 and then BX is used. */
- fprintf (f, "}\n");
-
- thumb_exit (f, -1);
-
- return;
- }
- else
- {
- if (mask & 0xFF)
- fprintf (f, ", ");
-
- asm_fprintf (f, "%r", PC_REGNUM);
- }
- }
-
- fprintf (f, "}\n");
-}
-
-/* Generate code to return from a thumb function.
- If 'reg_containing_return_addr' is -1, then the return address is
- actually on the stack, at the stack pointer. */
-static void
-thumb_exit (FILE *f, int reg_containing_return_addr)
-{
- unsigned regs_available_for_popping;
- unsigned regs_to_pop;
- int pops_needed;
- unsigned available;
- unsigned required;
- int mode;
- int size;
- int restore_a4 = FALSE;
-
- /* Compute the registers we need to pop. */
- regs_to_pop = 0;
- pops_needed = 0;
-
- if (reg_containing_return_addr == -1)
- {
- regs_to_pop |= 1 << LR_REGNUM;
- ++pops_needed;
- }
-
- if (TARGET_BACKTRACE)
- {
- /* Restore the (ARM) frame pointer and stack pointer. */
- regs_to_pop |= (1 << ARM_HARD_FRAME_POINTER_REGNUM) | (1 << SP_REGNUM);
- pops_needed += 2;
- }
-
- /* If there is nothing to pop then just emit the BX instruction and
- return. */
- if (pops_needed == 0)
- {
- if (crtl->calls_eh_return)
- asm_fprintf (f, "\tadd\t%r, %r\n", SP_REGNUM, ARM_EH_STACKADJ_REGNUM);
-
- asm_fprintf (f, "\tbx\t%r\n", reg_containing_return_addr);
- return;
- }
- /* Otherwise if we are not supporting interworking and we have not created
- a backtrace structure and the function was not entered in ARM mode then
- just pop the return address straight into the PC. */
- else if (!TARGET_INTERWORK
- && !TARGET_BACKTRACE
- && !is_called_in_ARM_mode (current_function_decl)
- && !crtl->calls_eh_return)
- {
- asm_fprintf (f, "\tpop\t{%r}\n", PC_REGNUM);
- return;
- }
-
- /* Find out how many of the (return) argument registers we can corrupt. */
- regs_available_for_popping = 0;
-
- /* If returning via __builtin_eh_return, the bottom three registers
- all contain information needed for the return. */
- if (crtl->calls_eh_return)
- size = 12;
- else
- {
- /* If we can deduce the registers used from the function's
- return value. This is more reliable that examining
- df_regs_ever_live_p () because that will be set if the register is
- ever used in the function, not just if the register is used
- to hold a return value. */
-
- if (crtl->return_rtx != 0)
- mode = GET_MODE (crtl->return_rtx);
- else
- mode = DECL_MODE (DECL_RESULT (current_function_decl));
-
- size = GET_MODE_SIZE (mode);
-
- if (size == 0)
- {
- /* In a void function we can use any argument register.
- In a function that returns a structure on the stack
- we can use the second and third argument registers. */
- if (mode == VOIDmode)
- regs_available_for_popping =
- (1 << ARG_REGISTER (1))
- | (1 << ARG_REGISTER (2))
- | (1 << ARG_REGISTER (3));
- else
- regs_available_for_popping =
- (1 << ARG_REGISTER (2))
- | (1 << ARG_REGISTER (3));
- }
- else if (size <= 4)
- regs_available_for_popping =
- (1 << ARG_REGISTER (2))
- | (1 << ARG_REGISTER (3));
- else if (size <= 8)
- regs_available_for_popping =
- (1 << ARG_REGISTER (3));
- }
-
- /* Match registers to be popped with registers into which we pop them. */
- for (available = regs_available_for_popping,
- required = regs_to_pop;
- required != 0 && available != 0;
- available &= ~(available & - available),
- required &= ~(required & - required))
- -- pops_needed;
-
- /* If we have any popping registers left over, remove them. */
- if (available > 0)
- regs_available_for_popping &= ~available;
-
- /* Otherwise if we need another popping register we can use
- the fourth argument register. */
- else if (pops_needed)
- {
- /* If we have not found any free argument registers and
- reg a4 contains the return address, we must move it. */
- if (regs_available_for_popping == 0
- && reg_containing_return_addr == LAST_ARG_REGNUM)
- {
- asm_fprintf (f, "\tmov\t%r, %r\n", LR_REGNUM, LAST_ARG_REGNUM);
- reg_containing_return_addr = LR_REGNUM;
- }
- else if (size > 12)
- {
- /* Register a4 is being used to hold part of the return value,
- but we have dire need of a free, low register. */
- restore_a4 = TRUE;
-
- asm_fprintf (f, "\tmov\t%r, %r\n",IP_REGNUM, LAST_ARG_REGNUM);
- }
-
- if (reg_containing_return_addr != LAST_ARG_REGNUM)
- {
- /* The fourth argument register is available. */
- regs_available_for_popping |= 1 << LAST_ARG_REGNUM;
-
- --pops_needed;
- }
- }
-
- /* Pop as many registers as we can. */
- thumb_pop (f, regs_available_for_popping);
-
- /* Process the registers we popped. */
- if (reg_containing_return_addr == -1)
- {
- /* The return address was popped into the lowest numbered register. */
- regs_to_pop &= ~(1 << LR_REGNUM);
-
- reg_containing_return_addr =
- number_of_first_bit_set (regs_available_for_popping);
-
- /* Remove this register for the mask of available registers, so that
- the return address will not be corrupted by further pops. */
- regs_available_for_popping &= ~(1 << reg_containing_return_addr);
- }
-
- /* If we popped other registers then handle them here. */
- if (regs_available_for_popping)
- {
- int frame_pointer;
-
- /* Work out which register currently contains the frame pointer. */
- frame_pointer = number_of_first_bit_set (regs_available_for_popping);
-
- /* Move it into the correct place. */
- asm_fprintf (f, "\tmov\t%r, %r\n",
- ARM_HARD_FRAME_POINTER_REGNUM, frame_pointer);
-
- /* (Temporarily) remove it from the mask of popped registers. */
- regs_available_for_popping &= ~(1 << frame_pointer);
- regs_to_pop &= ~(1 << ARM_HARD_FRAME_POINTER_REGNUM);
-
- if (regs_available_for_popping)
- {
- int stack_pointer;
-
- /* We popped the stack pointer as well,
- find the register that contains it. */
- stack_pointer = number_of_first_bit_set (regs_available_for_popping);
-
- /* Move it into the stack register. */
- asm_fprintf (f, "\tmov\t%r, %r\n", SP_REGNUM, stack_pointer);
-
- /* At this point we have popped all necessary registers, so
- do not worry about restoring regs_available_for_popping
- to its correct value:
-
- assert (pops_needed == 0)
- assert (regs_available_for_popping == (1 << frame_pointer))
- assert (regs_to_pop == (1 << STACK_POINTER)) */
- }
- else
- {
- /* Since we have just move the popped value into the frame
- pointer, the popping register is available for reuse, and
- we know that we still have the stack pointer left to pop. */
- regs_available_for_popping |= (1 << frame_pointer);
- }
- }
-
- /* If we still have registers left on the stack, but we no longer have
- any registers into which we can pop them, then we must move the return
- address into the link register and make available the register that
- contained it. */
- if (regs_available_for_popping == 0 && pops_needed > 0)
- {
- regs_available_for_popping |= 1 << reg_containing_return_addr;
-
- asm_fprintf (f, "\tmov\t%r, %r\n", LR_REGNUM,
- reg_containing_return_addr);
-
- reg_containing_return_addr = LR_REGNUM;
- }
-
- /* If we have registers left on the stack then pop some more.
- We know that at most we will want to pop FP and SP. */
- if (pops_needed > 0)
- {
- int popped_into;
- int move_to;
-
- thumb_pop (f, regs_available_for_popping);
-
- /* We have popped either FP or SP.
- Move whichever one it is into the correct register. */
- popped_into = number_of_first_bit_set (regs_available_for_popping);
- move_to = number_of_first_bit_set (regs_to_pop);
-
- asm_fprintf (f, "\tmov\t%r, %r\n", move_to, popped_into);
-
- regs_to_pop &= ~(1 << move_to);
-
- --pops_needed;
- }
-
- /* If we still have not popped everything then we must have only
- had one register available to us and we are now popping the SP. */
- if (pops_needed > 0)
- {
- int popped_into;
-
- thumb_pop (f, regs_available_for_popping);
-
- popped_into = number_of_first_bit_set (regs_available_for_popping);
-
- asm_fprintf (f, "\tmov\t%r, %r\n", SP_REGNUM, popped_into);
- /*
- assert (regs_to_pop == (1 << STACK_POINTER))
- assert (pops_needed == 1)
- */
- }
-
- /* If necessary restore the a4 register. */
- if (restore_a4)
- {
- if (reg_containing_return_addr != LR_REGNUM)
- {
- asm_fprintf (f, "\tmov\t%r, %r\n", LR_REGNUM, LAST_ARG_REGNUM);
- reg_containing_return_addr = LR_REGNUM;
- }
-
- asm_fprintf (f, "\tmov\t%r, %r\n", LAST_ARG_REGNUM, IP_REGNUM);
- }
-
- if (crtl->calls_eh_return)
- asm_fprintf (f, "\tadd\t%r, %r\n", SP_REGNUM, ARM_EH_STACKADJ_REGNUM);
-
- /* Return to caller. */
- asm_fprintf (f, "\tbx\t%r\n", reg_containing_return_addr);
-}
-
-/* Scan INSN just before assembler is output for it.
- For Thumb-1, we track the status of the condition codes; this
- information is used in the cbranchsi4_insn pattern. */
-void
-thumb1_final_prescan_insn (rtx insn)
-{
- if (flag_print_asm_name)
- asm_fprintf (asm_out_file, "%@ 0x%04x\n",
- INSN_ADDRESSES (INSN_UID (insn)));
- /* Don't overwrite the previous setter when we get to a cbranch. */
- if (INSN_CODE (insn) != CODE_FOR_cbranchsi4_insn)
- {
- enum attr_conds conds;
-
- if (cfun->machine->thumb1_cc_insn)
- {
- if (modified_in_p (cfun->machine->thumb1_cc_op0, insn)
- || modified_in_p (cfun->machine->thumb1_cc_op1, insn))
- CC_STATUS_INIT;
- }
- conds = get_attr_conds (insn);
- if (conds == CONDS_SET)
- {
- rtx set = single_set (insn);
- cfun->machine->thumb1_cc_insn = insn;
- cfun->machine->thumb1_cc_op0 = SET_DEST (set);
- cfun->machine->thumb1_cc_op1 = const0_rtx;
- cfun->machine->thumb1_cc_mode = CC_NOOVmode;
- if (INSN_CODE (insn) == CODE_FOR_thumb1_subsi3_insn)
- {
- rtx src1 = XEXP (SET_SRC (set), 1);
- if (src1 == const0_rtx)
- cfun->machine->thumb1_cc_mode = CCmode;
- }
- else if (REG_P (SET_DEST (set)) && REG_P (SET_SRC (set)))
- {
- /* Record the src register operand instead of dest because
- cprop_hardreg pass propagates src. */
- cfun->machine->thumb1_cc_op0 = SET_SRC (set);
- }
- }
- else if (conds != CONDS_NOCOND)
- cfun->machine->thumb1_cc_insn = NULL_RTX;
- }
-}
-
-int
-thumb_shiftable_const (unsigned HOST_WIDE_INT val)
-{
- unsigned HOST_WIDE_INT mask = 0xff;
- int i;
-
- val = val & (unsigned HOST_WIDE_INT)0xffffffffu;
- if (val == 0) /* XXX */
- return 0;
-
- for (i = 0; i < 25; i++)
- if ((val & (mask << i)) == val)
- return 1;
-
- return 0;
-}
-
-/* Returns nonzero if the current function contains,
- or might contain a far jump. */
-static int
-thumb_far_jump_used_p (void)
-{
- rtx insn;
-
- /* This test is only important for leaf functions. */
- /* assert (!leaf_function_p ()); */
-
- /* If we have already decided that far jumps may be used,
- do not bother checking again, and always return true even if
- it turns out that they are not being used. Once we have made
- the decision that far jumps are present (and that hence the link
- register will be pushed onto the stack) we cannot go back on it. */
- if (cfun->machine->far_jump_used)
- return 1;
-
- /* If this function is not being called from the prologue/epilogue
- generation code then it must be being called from the
- INITIAL_ELIMINATION_OFFSET macro. */
- if (!(ARM_DOUBLEWORD_ALIGN || reload_completed))
- {
- /* In this case we know that we are being asked about the elimination
- of the arg pointer register. If that register is not being used,
- then there are no arguments on the stack, and we do not have to
- worry that a far jump might force the prologue to push the link
- register, changing the stack offsets. In this case we can just
- return false, since the presence of far jumps in the function will
- not affect stack offsets.
-
- If the arg pointer is live (or if it was live, but has now been
- eliminated and so set to dead) then we do have to test to see if
- the function might contain a far jump. This test can lead to some
- false negatives, since before reload is completed, then length of
- branch instructions is not known, so gcc defaults to returning their
- longest length, which in turn sets the far jump attribute to true.
-
- A false negative will not result in bad code being generated, but it
- will result in a needless push and pop of the link register. We
- hope that this does not occur too often.
-
- If we need doubleword stack alignment this could affect the other
- elimination offsets so we can't risk getting it wrong. */
- if (df_regs_ever_live_p (ARG_POINTER_REGNUM))
- cfun->machine->arg_pointer_live = 1;
- else if (!cfun->machine->arg_pointer_live)
- return 0;
- }
-
- /* Check to see if the function contains a branch
- insn with the far jump attribute set. */
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- {
- if (JUMP_P (insn)
- /* Ignore tablejump patterns. */
- && GET_CODE (PATTERN (insn)) != ADDR_VEC
- && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
- && get_attr_far_jump (insn) == FAR_JUMP_YES
- )
- {
- /* Record the fact that we have decided that
- the function does use far jumps. */
- cfun->machine->far_jump_used = 1;
- return 1;
- }
- }
-
- return 0;
-}
-
-/* Return nonzero if FUNC must be entered in ARM mode. */
-int
-is_called_in_ARM_mode (tree func)
-{
- gcc_assert (TREE_CODE (func) == FUNCTION_DECL);
-
- /* Ignore the problem about functions whose address is taken. */
- if (TARGET_CALLEE_INTERWORKING && TREE_PUBLIC (func))
- return TRUE;
-
-#ifdef ARM_PE
- return lookup_attribute ("interfacearm", DECL_ATTRIBUTES (func)) != NULL_TREE;
-#else
- return FALSE;
-#endif
-}
-
-/* Given the stack offsets and register mask in OFFSETS, decide how
- many additional registers to push instead of subtracting a constant
- from SP. For epilogues the principle is the same except we use pop.
- FOR_PROLOGUE indicates which we're generating. */
-static int
-thumb1_extra_regs_pushed (arm_stack_offsets *offsets, bool for_prologue)
-{
- HOST_WIDE_INT amount;
- unsigned long live_regs_mask = offsets->saved_regs_mask;
- /* Extract a mask of the ones we can give to the Thumb's push/pop
- instruction. */
- unsigned long l_mask = live_regs_mask & (for_prologue ? 0x40ff : 0xff);
- /* Then count how many other high registers will need to be pushed. */
- unsigned long high_regs_pushed = bit_count (live_regs_mask & 0x0f00);
- int n_free, reg_base, size;
-
- if (!for_prologue && frame_pointer_needed)
- amount = offsets->locals_base - offsets->saved_regs;
- else
- amount = offsets->outgoing_args - offsets->saved_regs;
-
- /* If the stack frame size is 512 exactly, we can save one load
- instruction, which should make this a win even when optimizing
- for speed. */
- if (!optimize_size && amount != 512)
- return 0;
-
- /* Can't do this if there are high registers to push. */
- if (high_regs_pushed != 0)
- return 0;
-
- /* Shouldn't do it in the prologue if no registers would normally
- be pushed at all. In the epilogue, also allow it if we'll have
- a pop insn for the PC. */
- if (l_mask == 0
- && (for_prologue
- || TARGET_BACKTRACE
- || (live_regs_mask & 1 << LR_REGNUM) == 0
- || TARGET_INTERWORK
- || crtl->args.pretend_args_size != 0))
- return 0;
-
- /* Don't do this if thumb_expand_prologue wants to emit instructions
- between the push and the stack frame allocation. */
- if (for_prologue
- && ((flag_pic && arm_pic_register != INVALID_REGNUM)
- || (!frame_pointer_needed && CALLER_INTERWORKING_SLOT_SIZE > 0)))
- return 0;
-
- reg_base = 0;
- n_free = 0;
- if (!for_prologue)
- {
- size = arm_size_return_regs ();
- reg_base = ARM_NUM_INTS (size);
- live_regs_mask >>= reg_base;
- }
-
- while (reg_base + n_free < 8 && !(live_regs_mask & 1)
- && (for_prologue || call_used_regs[reg_base + n_free]))
- {
- live_regs_mask >>= 1;
- n_free++;
- }
-
- if (n_free == 0)
- return 0;
- gcc_assert (amount / 4 * 4 == amount);
-
- if (amount >= 512 && (amount - n_free * 4) < 512)
- return (amount - 508) / 4;
- if (amount <= n_free * 4)
- return amount / 4;
- return 0;
-}
-
-/* The bits which aren't usefully expanded as rtl. */
-const char *
-thumb1_unexpanded_epilogue (void)
-{
- arm_stack_offsets *offsets;
- int regno;
- unsigned long live_regs_mask = 0;
- int high_regs_pushed = 0;
- int extra_pop;
- int had_to_push_lr;
- int size;
-
- if (cfun->machine->return_used_this_function != 0)
- return "";
-
- if (IS_NAKED (arm_current_func_type ()))
- return "";
-
- 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.
- This is more reliable that examining df_regs_ever_live_p () because that
- will be set if the register is ever used in the function, not just if
- the register is used to hold a return value. */
- size = arm_size_return_regs ();
-
- extra_pop = thumb1_extra_regs_pushed (offsets, false);
- if (extra_pop > 0)
- {
- unsigned long extra_mask = (1 << extra_pop) - 1;
- live_regs_mask |= extra_mask << ARM_NUM_INTS (size);
- }
-
- /* The prolog may have pushed some high registers to use as
- work registers. e.g. the testsuite file:
- gcc/testsuite/gcc/gcc.c-torture/execute/complex-2.c
- compiles to produce:
- push {r4, r5, r6, r7, lr}
- mov r7, r9
- mov r6, r8
- push {r6, r7}
- as part of the prolog. We have to undo that pushing here. */
-
- if (high_regs_pushed)
- {
- unsigned long mask = live_regs_mask & 0xff;
- int next_hi_reg;
-
- /* The available low registers depend on the size of the value we are
- returning. */
- if (size <= 12)
- mask |= 1 << 3;
- if (size <= 8)
- mask |= 1 << 2;
-
- if (mask == 0)
- /* Oh dear! We have no low registers into which we can pop
- high registers! */
- internal_error
- ("no low registers available for popping high registers");
-
- for (next_hi_reg = 8; next_hi_reg < 13; next_hi_reg++)
- if (live_regs_mask & (1 << next_hi_reg))
- break;
-
- while (high_regs_pushed)
- {
- /* Find lo register(s) into which the high register(s) can
- be popped. */
- for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
- {
- if (mask & (1 << regno))
- high_regs_pushed--;
- if (high_regs_pushed == 0)
- break;
- }
-
- mask &= (2 << regno) - 1; /* A noop if regno == 8 */
-
- /* Pop the values into the low register(s). */
- thumb_pop (asm_out_file, mask);
-
- /* Move the value(s) into the high registers. */
- for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
- {
- if (mask & (1 << regno))
- {
- asm_fprintf (asm_out_file, "\tmov\t%r, %r\n", next_hi_reg,
- regno);
-
- for (next_hi_reg++; next_hi_reg < 13; next_hi_reg++)
- if (live_regs_mask & (1 << next_hi_reg))
- break;
- }
- }
- }
- live_regs_mask &= ~0x0f00;
- }
-
- had_to_push_lr = (live_regs_mask & (1 << LR_REGNUM)) != 0;
- live_regs_mask &= 0xff;
-
- if (crtl->args.pretend_args_size == 0 || TARGET_BACKTRACE)
- {
- /* Pop the return address into the PC. */
- if (had_to_push_lr)
- live_regs_mask |= 1 << PC_REGNUM;
-
- /* Either no argument registers were pushed or a backtrace
- structure was created which includes an adjusted stack
- pointer, so just pop everything. */
- if (live_regs_mask)
- thumb_pop (asm_out_file, live_regs_mask);
-
- /* We have either just popped the return address into the
- PC or it is was kept in LR for the entire function.
- Note that thumb_pop has already called thumb_exit if the
- PC was in the list. */
- if (!had_to_push_lr)
- thumb_exit (asm_out_file, LR_REGNUM);
- }
- else
- {
- /* Pop everything but the return address. */
- if (live_regs_mask)
- thumb_pop (asm_out_file, live_regs_mask);
-
- if (had_to_push_lr)
- {
- if (size > 12)
- {
- /* We have no free low regs, so save one. */
- asm_fprintf (asm_out_file, "\tmov\t%r, %r\n", IP_REGNUM,
- LAST_ARG_REGNUM);
- }
-
- /* Get the return address into a temporary register. */
- thumb_pop (asm_out_file, 1 << LAST_ARG_REGNUM);
-
- if (size > 12)
- {
- /* Move the return address to lr. */
- asm_fprintf (asm_out_file, "\tmov\t%r, %r\n", LR_REGNUM,
- LAST_ARG_REGNUM);
- /* Restore the low register. */
- asm_fprintf (asm_out_file, "\tmov\t%r, %r\n", LAST_ARG_REGNUM,
- IP_REGNUM);
- regno = LR_REGNUM;
- }
- else
- regno = LAST_ARG_REGNUM;
- }
- else
- regno = LR_REGNUM;
-
- /* Remove the argument registers that were pushed onto the stack. */
- asm_fprintf (asm_out_file, "\tadd\t%r, %r, #%d\n",
- SP_REGNUM, SP_REGNUM,
- crtl->args.pretend_args_size);
-
- thumb_exit (asm_out_file, regno);
- }
-
- return "";
-}
-
-/* Functions to save and restore machine-specific function data. */
-static struct machine_function *
-arm_init_machine_status (void)
-{
- struct machine_function *machine;
- machine = ggc_alloc_cleared_machine_function ();
-
-#if ARM_FT_UNKNOWN != 0
- machine->func_type = ARM_FT_UNKNOWN;
-#endif
- return machine;
-}
-
-/* Return an RTX indicating where the return address to the
- calling function can be found. */
-rtx
-arm_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
-{
- if (count != 0)
- return NULL_RTX;
-
- return get_hard_reg_initial_val (Pmode, LR_REGNUM);
-}
-
-/* Do anything needed before RTL is emitted for each function. */
-void
-arm_init_expanders (void)
-{
- /* Arrange to initialize and mark the machine per-function status. */
- init_machine_status = arm_init_machine_status;
-
- /* This is to stop the combine pass optimizing away the alignment
- adjustment of va_arg. */
- /* ??? It is claimed that this should not be necessary. */
- if (cfun)
- mark_reg_pointer (arg_pointer_rtx, PARM_BOUNDARY);
-}
-
-
-/* Like arm_compute_initial_elimination offset. Simpler because there
- isn't an ABI specified frame pointer for Thumb. Instead, we set it
- to point at the base of the local variables after static stack
- space for a function has been allocated. */
-
-HOST_WIDE_INT
-thumb_compute_initial_elimination_offset (unsigned int from, unsigned int to)
-{
- arm_stack_offsets *offsets;
-
- offsets = arm_get_frame_offsets ();
-
- switch (from)
- {
- case ARG_POINTER_REGNUM:
- switch (to)
- {
- case STACK_POINTER_REGNUM:
- return offsets->outgoing_args - offsets->saved_args;
-
- case FRAME_POINTER_REGNUM:
- return offsets->soft_frame - offsets->saved_args;
-
- case ARM_HARD_FRAME_POINTER_REGNUM:
- return offsets->saved_regs - offsets->saved_args;
-
- case THUMB_HARD_FRAME_POINTER_REGNUM:
- return offsets->locals_base - offsets->saved_args;
-
- default:
- gcc_unreachable ();
- }
- break;
-
- case FRAME_POINTER_REGNUM:
- switch (to)
- {
- case STACK_POINTER_REGNUM:
- return offsets->outgoing_args - offsets->soft_frame;
-
- case ARM_HARD_FRAME_POINTER_REGNUM:
- return offsets->saved_regs - offsets->soft_frame;
-
- case THUMB_HARD_FRAME_POINTER_REGNUM:
- return offsets->locals_base - offsets->soft_frame;
-
- default:
- gcc_unreachable ();
- }
- break;
-
- default:
- gcc_unreachable ();
- }
-}
-
-/* Generate the function's prologue. */
-
-void
-thumb1_expand_prologue (void)
-{
- rtx insn;
-
- HOST_WIDE_INT amount;
- arm_stack_offsets *offsets;
- unsigned long func_type;
- int regno;
- unsigned long live_regs_mask;
- unsigned long l_mask;
- unsigned high_regs_pushed = 0;
-
- func_type = arm_current_func_type ();
-
- /* Naked functions don't have prologues. */
- if (IS_NAKED (func_type))
- return;
-
- if (IS_INTERRUPT (func_type))
- {
- error ("interrupt Service Routines cannot be coded in Thumb mode");
- return;
- }
-
- if (is_called_in_ARM_mode (current_function_decl))
- emit_insn (gen_prologue_thumb1_interwork ());
-
- 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. */
- high_regs_pushed = bit_count (live_regs_mask & 0x0f00);
-
- if (crtl->args.pretend_args_size)
- {
- rtx x = GEN_INT (-crtl->args.pretend_args_size);
-
- if (cfun->machine->uses_anonymous_args)
- {
- int num_pushes = ARM_NUM_INTS (crtl->args.pretend_args_size);
- unsigned long mask;
-
- mask = 1ul << (LAST_ARG_REGNUM + 1);
- mask -= 1ul << (LAST_ARG_REGNUM + 1 - num_pushes);
-
- insn = thumb1_emit_multi_reg_push (mask, 0);
- }
- else
- {
- insn = emit_insn (gen_addsi3 (stack_pointer_rtx,
- stack_pointer_rtx, x));
- }
- RTX_FRAME_RELATED_P (insn) = 1;
- }
-
- if (TARGET_BACKTRACE)
- {
- HOST_WIDE_INT offset = 0;
- unsigned work_register;
- rtx work_reg, x, arm_hfp_rtx;
-
- /* We have been asked to create a stack backtrace structure.
- The code looks like this:
-
- 0 .align 2
- 0 func:
- 0 sub SP, #16 Reserve space for 4 registers.
- 2 push {R7} Push low registers.
- 4 add R7, SP, #20 Get the stack pointer before the push.
- 6 str R7, [SP, #8] Store the stack pointer
- (before reserving the space).
- 8 mov R7, PC Get hold of the start of this code + 12.
- 10 str R7, [SP, #16] Store it.
- 12 mov R7, FP Get hold of the current frame pointer.
- 14 str R7, [SP, #4] Store it.
- 16 mov R7, LR Get hold of the current return address.
- 18 str R7, [SP, #12] Store it.
- 20 add R7, SP, #16 Point at the start of the
- backtrace structure.
- 22 mov FP, R7 Put this value into the frame pointer. */
-
- work_register = thumb_find_work_register (live_regs_mask);
- work_reg = gen_rtx_REG (SImode, work_register);
- arm_hfp_rtx = gen_rtx_REG (SImode, ARM_HARD_FRAME_POINTER_REGNUM);
-
- insn = emit_insn (gen_addsi3 (stack_pointer_rtx,
- stack_pointer_rtx, GEN_INT (-16)));
- RTX_FRAME_RELATED_P (insn) = 1;
-
- if (l_mask)
- {
- insn = thumb1_emit_multi_reg_push (l_mask, l_mask);
- RTX_FRAME_RELATED_P (insn) = 1;
-
- offset = bit_count (l_mask) * UNITS_PER_WORD;
- }
-
- x = GEN_INT (offset + 16 + crtl->args.pretend_args_size);
- emit_insn (gen_addsi3 (work_reg, stack_pointer_rtx, x));
-
- x = plus_constant (Pmode, stack_pointer_rtx, offset + 4);
- x = gen_frame_mem (SImode, x);
- emit_move_insn (x, work_reg);
-
- /* Make sure that the instruction fetching the PC is in the right place
- to calculate "start of backtrace creation code + 12". */
- /* ??? The stores using the common WORK_REG ought to be enough to
- prevent the scheduler from doing anything weird. Failing that
- we could always move all of the following into an UNSPEC_VOLATILE. */
- if (l_mask)
- {
- x = gen_rtx_REG (SImode, PC_REGNUM);
- emit_move_insn (work_reg, x);
-
- x = plus_constant (Pmode, stack_pointer_rtx, offset + 12);
- x = gen_frame_mem (SImode, x);
- emit_move_insn (x, work_reg);
-
- emit_move_insn (work_reg, arm_hfp_rtx);
-
- x = plus_constant (Pmode, stack_pointer_rtx, offset);
- x = gen_frame_mem (SImode, x);
- emit_move_insn (x, work_reg);
- }
- else
- {
- emit_move_insn (work_reg, arm_hfp_rtx);
-
- x = plus_constant (Pmode, stack_pointer_rtx, offset);
- x = gen_frame_mem (SImode, x);
- emit_move_insn (x, work_reg);
-
- x = gen_rtx_REG (SImode, PC_REGNUM);
- emit_move_insn (work_reg, x);
-
- x = plus_constant (Pmode, stack_pointer_rtx, offset + 12);
- x = gen_frame_mem (SImode, x);
- emit_move_insn (x, work_reg);
- }
-
- x = gen_rtx_REG (SImode, LR_REGNUM);
- emit_move_insn (work_reg, x);
-
- x = plus_constant (Pmode, stack_pointer_rtx, offset + 8);
- x = gen_frame_mem (SImode, x);
- emit_move_insn (x, work_reg);
-
- x = GEN_INT (offset + 12);
- emit_insn (gen_addsi3 (work_reg, stack_pointer_rtx, x));
-
- emit_move_insn (arm_hfp_rtx, work_reg);
- }
- /* Optimization: If we are not pushing any low registers but we are going
- to push some high registers then delay our first push. This will just
- be a push of LR and we can combine it with the push of the first high
- register. */
- else if ((l_mask & 0xff) != 0
- || (high_regs_pushed == 0 && l_mask))
- {
- unsigned long mask = l_mask;
- mask |= (1 << thumb1_extra_regs_pushed (offsets, true)) - 1;
- insn = thumb1_emit_multi_reg_push (mask, mask);
- RTX_FRAME_RELATED_P (insn) = 1;
- }
-
- if (high_regs_pushed)
- {
- unsigned pushable_regs;
- unsigned next_hi_reg;
- unsigned arg_regs_num = TARGET_AAPCS_BASED ? crtl->args.info.aapcs_ncrn
- : crtl->args.info.nregs;
- unsigned arg_regs_mask = (1 << arg_regs_num) - 1;
-
- for (next_hi_reg = 12; next_hi_reg > LAST_LO_REGNUM; next_hi_reg--)
- if (live_regs_mask & (1 << next_hi_reg))
- break;
-
- /* Here we need to mask out registers used for passing arguments
- even if they can be pushed. This is to avoid using them to stash the high
- registers. Such kind of stash may clobber the use of arguments. */
- pushable_regs = l_mask & (~arg_regs_mask) & 0xff;
-
- if (pushable_regs == 0)
- pushable_regs = 1 << thumb_find_work_register (live_regs_mask);
-
- while (high_regs_pushed > 0)
- {
- unsigned long real_regs_mask = 0;
-
- for (regno = LAST_LO_REGNUM; regno >= 0; regno --)
- {
- if (pushable_regs & (1 << regno))
- {
- emit_move_insn (gen_rtx_REG (SImode, regno),
- gen_rtx_REG (SImode, next_hi_reg));
-
- high_regs_pushed --;
- real_regs_mask |= (1 << next_hi_reg);
-
- if (high_regs_pushed)
- {
- for (next_hi_reg --; next_hi_reg > LAST_LO_REGNUM;
- next_hi_reg --)
- if (live_regs_mask & (1 << next_hi_reg))
- break;
- }
- else
- {
- pushable_regs &= ~((1 << regno) - 1);
- break;
- }
- }
- }
-
- /* If we had to find a work register and we have not yet
- saved the LR then add it to the list of regs to push. */
- if (l_mask == (1 << LR_REGNUM))
- {
- pushable_regs |= l_mask;
- real_regs_mask |= l_mask;
- l_mask = 0;
- }
-
- insn = thumb1_emit_multi_reg_push (pushable_regs, real_regs_mask);
- RTX_FRAME_RELATED_P (insn) = 1;
- }
- }
-
- /* 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)
- arm_load_pic_register (live_regs_mask);
-
- if (!frame_pointer_needed && CALLER_INTERWORKING_SLOT_SIZE > 0)
- emit_move_insn (gen_rtx_REG (Pmode, ARM_HARD_FRAME_POINTER_REGNUM),
- stack_pointer_rtx);
-
- if (flag_stack_usage_info)
- current_function_static_stack_size
- = offsets->outgoing_args - offsets->saved_args;
-
- amount = offsets->outgoing_args - offsets->saved_regs;
- amount -= 4 * thumb1_extra_regs_pushed (offsets, true);
- if (amount)
- {
- if (amount < 512)
- {
- insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (- amount)));
- RTX_FRAME_RELATED_P (insn) = 1;
- }
- else
- {
- rtx reg, dwarf;
-
- /* The stack decrement is too big for an immediate value in a single
- insn. In theory we could issue multiple subtracts, but after
- three of them it becomes more space efficient to place the full
- value in the constant pool and load into a register. (Also the
- ARM debugger really likes to see only one stack decrement per
- function). So instead we look for a scratch register into which
- we can load the decrement, and then we subtract this from the
- stack pointer. Unfortunately on the thumb the only available
- scratch registers are the argument registers, and we cannot use
- these as they may hold arguments to the function. Instead we
- attempt to locate a call preserved register which is used by this
- function. If we can find one, then we know that it will have
- 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))
- break;
-
- gcc_assert(regno <= LAST_LO_REGNUM);
-
- reg = gen_rtx_REG (SImode, regno);
-
- emit_insn (gen_movsi (reg, GEN_INT (- amount)));
-
- insn = emit_insn (gen_addsi3 (stack_pointer_rtx,
- stack_pointer_rtx, reg));
-
- dwarf = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
- plus_constant (Pmode, stack_pointer_rtx,
- -amount));
- add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
- RTX_FRAME_RELATED_P (insn) = 1;
- }
- }
-
- if (frame_pointer_needed)
- thumb_set_frame_pointer (offsets);
-
- /* If we are profiling, make sure no instructions are scheduled before
- the call to mcount. Similarly if the user has requested no
- scheduling in the prolog. Similarly if we want non-call exceptions
- using the EABI unwinder, to prevent faulting instructions from being
- swapped with a stack adjustment. */
- if (crtl->profile || !TARGET_SCHED_PROLOG
- || (arm_except_unwind_info (&global_options) == UI_TARGET
- && cfun->can_throw_non_call_exceptions))
- emit_insn (gen_blockage ());
-
- cfun->machine->lr_save_eliminated = !thumb_force_lr_save ();
- if (live_regs_mask & 0xff)
- cfun->machine->lr_save_eliminated = 0;
-}
-
-/* Generate pattern *pop_multiple_with_stack_update_and_return if single
- POP instruction can be generated. LR should be replaced by PC. All
- the checks required are already done by USE_RETURN_INSN (). Hence,
- all we really need to check here is if single register is to be
- returned, or multiple register return. */
-void
-thumb2_expand_return (void)
-{
- int i, num_regs;
- unsigned long saved_regs_mask;
- arm_stack_offsets *offsets;
-
- offsets = arm_get_frame_offsets ();
- saved_regs_mask = offsets->saved_regs_mask;
-
- for (i = 0, num_regs = 0; i <= LAST_ARM_REGNUM; i++)
- if (saved_regs_mask & (1 << i))
- num_regs++;
-
- if (saved_regs_mask)
- {
- if (num_regs == 1)
- {
- rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
- rtx reg = gen_rtx_REG (SImode, PC_REGNUM);
- rtx addr = gen_rtx_MEM (SImode,
- gen_rtx_POST_INC (SImode,
- stack_pointer_rtx));
- set_mem_alias_set (addr, get_frame_alias_set ());
- XVECEXP (par, 0, 0) = ret_rtx;
- XVECEXP (par, 0, 1) = gen_rtx_SET (SImode, reg, addr);
- RTX_FRAME_RELATED_P (XVECEXP (par, 0, 1)) = 1;
- emit_jump_insn (par);
- }
- else
- {
- saved_regs_mask &= ~ (1 << LR_REGNUM);
- saved_regs_mask |= (1 << PC_REGNUM);
- arm_emit_multi_reg_pop (saved_regs_mask);
- }
- }
- else
- {
- emit_jump_insn (simple_return_rtx);
- }
-}
-
-void
-thumb1_expand_epilogue (void)
-{
- HOST_WIDE_INT amount;
- arm_stack_offsets *offsets;
- int regno;
-
- /* Naked functions don't have prologues. */
- if (IS_NAKED (arm_current_func_type ()))
- return;
-
- offsets = arm_get_frame_offsets ();
- amount = offsets->outgoing_args - offsets->saved_regs;
-
- if (frame_pointer_needed)
- {
- emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
- amount = offsets->locals_base - offsets->saved_regs;
- }
- amount -= 4 * thumb1_extra_regs_pushed (offsets, false);
-
- gcc_assert (amount >= 0);
- if (amount)
- {
- emit_insn (gen_blockage ());
-
- if (amount < 512)
- emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (amount)));
- else
- {
- /* r3 is always free in the epilogue. */
- rtx reg = gen_rtx_REG (SImode, LAST_ARG_REGNUM);
-
- emit_insn (gen_movsi (reg, GEN_INT (amount)));
- emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, reg));
- }
- }
-
- /* Emit a USE (stack_pointer_rtx), so that
- the stack adjustment will not be deleted. */
- emit_insn (gen_force_register_use (stack_pointer_rtx));
-
- if (crtl->profile || !TARGET_SCHED_PROLOG)
- emit_insn (gen_blockage ());
-
- /* Emit a clobber for each insn that will be restored in the epilogue,
- so that flow2 will get register lifetimes correct. */
- for (regno = 0; regno < 13; regno++)
- if (df_regs_ever_live_p (regno) && !call_used_regs[regno])
- emit_clobber (gen_rtx_REG (SImode, regno));
-
- if (! df_regs_ever_live_p (LR_REGNUM))
- emit_use (gen_rtx_REG (SImode, LR_REGNUM));
-}
-
-/* Epilogue code for APCS frame. */
-static void
-arm_expand_epilogue_apcs_frame (bool really_return)
-{
- unsigned long func_type;
- unsigned long saved_regs_mask;
- int num_regs = 0;
- int i;
- int floats_from_frame = 0;
- arm_stack_offsets *offsets;
-
- gcc_assert (TARGET_APCS_FRAME && frame_pointer_needed && TARGET_ARM);
- func_type = arm_current_func_type ();
-
- /* Get frame offsets for ARM. */
- offsets = arm_get_frame_offsets ();
- saved_regs_mask = offsets->saved_regs_mask;
-
- /* Find the offset of the floating-point save area in the frame. */
- floats_from_frame = offsets->saved_args - offsets->frame;
-
- /* Compute how many core registers saved and how far away the floats are. */
- for (i = 0; i <= LAST_ARM_REGNUM; i++)
- if (saved_regs_mask & (1 << i))
- {
- num_regs++;
- floats_from_frame += 4;
- }
-
- if (TARGET_HARD_FLOAT && TARGET_VFP)
- {
- int start_reg;
-
- /* The offset is from IP_REGNUM. */
- int saved_size = arm_get_vfp_saved_size ();
- if (saved_size > 0)
- {
- floats_from_frame += saved_size;
- emit_insn (gen_addsi3 (gen_rtx_REG (SImode, IP_REGNUM),
- hard_frame_pointer_rtx,
- GEN_INT (-floats_from_frame)));
- }
-
- /* Generate VFP register multi-pop. */
- start_reg = FIRST_VFP_REGNUM;
-
- for (i = FIRST_VFP_REGNUM; i < LAST_VFP_REGNUM; i += 2)
- /* Look for a case where a reg does not need restoring. */
- if ((!df_regs_ever_live_p (i) || call_used_regs[i])
- && (!df_regs_ever_live_p (i + 1)
- || call_used_regs[i + 1]))
- {
- if (start_reg != i)
- arm_emit_vfp_multi_reg_pop (start_reg,
- (i - start_reg) / 2,
- gen_rtx_REG (SImode,
- IP_REGNUM));
- start_reg = i + 2;
- }
-
- /* Restore the remaining regs that we have discovered (or possibly
- even all of them, if the conditional in the for loop never
- fired). */
- if (start_reg != i)
- arm_emit_vfp_multi_reg_pop (start_reg,
- (i - start_reg) / 2,
- gen_rtx_REG (SImode, IP_REGNUM));
- }
-
- if (TARGET_IWMMXT)
- {
- /* The frame pointer is guaranteed to be non-double-word aligned, as
- it is set to double-word-aligned old_stack_pointer - 4. */
- rtx insn;
- int lrm_count = (num_regs % 2) ? (num_regs + 2) : (num_regs + 1);
-
- for (i = LAST_IWMMXT_REGNUM; i >= FIRST_IWMMXT_REGNUM; i--)
- if (df_regs_ever_live_p (i) && !call_used_regs[i])
- {
- rtx addr = gen_frame_mem (V2SImode,
- plus_constant (Pmode, hard_frame_pointer_rtx,
- - lrm_count * 4));
- insn = emit_insn (gen_movsi (gen_rtx_REG (V2SImode, i), addr));
- REG_NOTES (insn) = alloc_reg_note (REG_CFA_RESTORE,
- gen_rtx_REG (V2SImode, i),
- NULL_RTX);
- lrm_count += 2;
- }
- }
-
- /* saved_regs_mask should contain IP which contains old stack pointer
- at the time of activation creation. Since SP and IP are adjacent registers,
- we can restore the value directly into SP. */
- gcc_assert (saved_regs_mask & (1 << IP_REGNUM));
- saved_regs_mask &= ~(1 << IP_REGNUM);
- saved_regs_mask |= (1 << SP_REGNUM);
-
- /* There are two registers left in saved_regs_mask - LR and PC. We
- only need to restore LR (the return address), but to
- save time we can load it directly into PC, unless we need a
- special function exit sequence, or we are not really returning. */
- if (really_return
- && ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL
- && !crtl->calls_eh_return)
- /* Delete LR from the register mask, so that LR on
- the stack is loaded into the PC in the register mask. */
- saved_regs_mask &= ~(1 << LR_REGNUM);
- else
- saved_regs_mask &= ~(1 << PC_REGNUM);
-
- num_regs = bit_count (saved_regs_mask);
- if ((offsets->outgoing_args != (1 + num_regs)) || cfun->calls_alloca)
- {
- /* Unwind the stack to just below the saved registers. */
- emit_insn (gen_addsi3 (stack_pointer_rtx,
- hard_frame_pointer_rtx,
- GEN_INT (- 4 * num_regs)));
- }
-
- arm_emit_multi_reg_pop (saved_regs_mask);
-
- if (IS_INTERRUPT (func_type))
- {
- /* Interrupt handlers will have pushed the
- IP onto the stack, so restore it now. */
- rtx insn;
- rtx addr = gen_rtx_MEM (SImode,
- gen_rtx_POST_INC (SImode,
- stack_pointer_rtx));
- set_mem_alias_set (addr, get_frame_alias_set ());
- insn = emit_insn (gen_movsi (gen_rtx_REG (SImode, IP_REGNUM), addr));
- REG_NOTES (insn) = alloc_reg_note (REG_CFA_RESTORE,
- gen_rtx_REG (SImode, IP_REGNUM),
- NULL_RTX);
- }
-
- if (!really_return || (saved_regs_mask & (1 << PC_REGNUM)))
- return;
-
- if (crtl->calls_eh_return)
- emit_insn (gen_addsi3 (stack_pointer_rtx,
- stack_pointer_rtx,
- GEN_INT (ARM_EH_STACKADJ_REGNUM)));
-
- if (IS_STACKALIGN (func_type))
- /* Restore the original stack pointer. Before prologue, the stack was
- realigned and the original stack pointer saved in r0. For details,
- see comment in arm_expand_prologue. */
- emit_insn (gen_movsi (stack_pointer_rtx, gen_rtx_REG (SImode, 0)));
-
- emit_jump_insn (simple_return_rtx);
-}
-
-/* Generate RTL to represent ARM epilogue. Really_return is true if the
- function is not a sibcall. */
-void
-arm_expand_epilogue (bool really_return)
-{
- unsigned long func_type;
- unsigned long saved_regs_mask;
- int num_regs = 0;
- int i;
- int amount;
- arm_stack_offsets *offsets;
-
- func_type = arm_current_func_type ();
-
- /* Naked functions don't have epilogue. Hence, generate return pattern, and
- let output_return_instruction take care of instruction emition if any. */
- if (IS_NAKED (func_type)
- || (IS_VOLATILE (func_type) && TARGET_ABORT_NORETURN))
- {
- if (really_return)
- emit_jump_insn (simple_return_rtx);
- return;
- }
-
- /* If we are throwing an exception, then we really must be doing a
- return, so we can't tail-call. */
- gcc_assert (!crtl->calls_eh_return || really_return);
-
- if (TARGET_APCS_FRAME && frame_pointer_needed && TARGET_ARM)
- {
- arm_expand_epilogue_apcs_frame (really_return);
- return;
- }
-
- /* Get frame offsets for ARM. */
- offsets = arm_get_frame_offsets ();
- saved_regs_mask = offsets->saved_regs_mask;
- num_regs = bit_count (saved_regs_mask);
-
- if (frame_pointer_needed)
- {
- /* Restore stack pointer if necessary. */
- if (TARGET_ARM)
- {
- /* In ARM mode, frame pointer points to first saved register.
- Restore stack pointer to last saved register. */
- amount = offsets->frame - offsets->saved_regs;
-
- /* Force out any pending memory operations that reference stacked data
- before stack de-allocation occurs. */
- emit_insn (gen_blockage ());
- emit_insn (gen_addsi3 (stack_pointer_rtx,
- hard_frame_pointer_rtx,
- GEN_INT (amount)));
-
- /* Emit USE(stack_pointer_rtx) to ensure that stack adjustment is not
- deleted. */
- emit_insn (gen_force_register_use (stack_pointer_rtx));
- }
- else
- {
- /* In Thumb-2 mode, the frame pointer points to the last saved
- register. */
- amount = offsets->locals_base - offsets->saved_regs;
- if (amount)
- emit_insn (gen_addsi3 (hard_frame_pointer_rtx,
- hard_frame_pointer_rtx,
- GEN_INT (amount)));
-
- /* Force out any pending memory operations that reference stacked data
- before stack de-allocation occurs. */
- emit_insn (gen_blockage ());
- emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
- /* Emit USE(stack_pointer_rtx) to ensure that stack adjustment is not
- deleted. */
- emit_insn (gen_force_register_use (stack_pointer_rtx));
- }
- }
- else
- {
- /* Pop off outgoing args and local frame to adjust stack pointer to
- last saved register. */
- amount = offsets->outgoing_args - offsets->saved_regs;
- if (amount)
- {
- /* Force out any pending memory operations that reference stacked data
- before stack de-allocation occurs. */
- emit_insn (gen_blockage ());
- emit_insn (gen_addsi3 (stack_pointer_rtx,
- stack_pointer_rtx,
- GEN_INT (amount)));
- /* Emit USE(stack_pointer_rtx) to ensure that stack adjustment is
- not deleted. */
- emit_insn (gen_force_register_use (stack_pointer_rtx));
- }
- }
-
- if (TARGET_HARD_FLOAT && TARGET_VFP)
- {
- /* Generate VFP register multi-pop. */
- int end_reg = LAST_VFP_REGNUM + 1;
-
- /* Scan the registers in reverse order. We need to match
- any groupings made in the prologue and generate matching
- vldm operations. The need to match groups is because,
- unlike pop, vldm can only do consecutive regs. */
- for (i = LAST_VFP_REGNUM - 1; i >= FIRST_VFP_REGNUM; i -= 2)
- /* Look for a case where a reg does not need restoring. */
- if ((!df_regs_ever_live_p (i) || call_used_regs[i])
- && (!df_regs_ever_live_p (i + 1)
- || call_used_regs[i + 1]))
- {
- /* Restore the regs discovered so far (from reg+2 to
- end_reg). */
- if (end_reg > i + 2)
- arm_emit_vfp_multi_reg_pop (i + 2,
- (end_reg - (i + 2)) / 2,
- stack_pointer_rtx);
- end_reg = i;
- }
-
- /* Restore the remaining regs that we have discovered (or possibly
- even all of them, if the conditional in the for loop never
- fired). */
- if (end_reg > i + 2)
- arm_emit_vfp_multi_reg_pop (i + 2,
- (end_reg - (i + 2)) / 2,
- stack_pointer_rtx);
- }
-
- if (TARGET_IWMMXT)
- for (i = FIRST_IWMMXT_REGNUM; i <= LAST_IWMMXT_REGNUM; i++)
- if (df_regs_ever_live_p (i) && !call_used_regs[i])
- {
- rtx insn;
- rtx addr = gen_rtx_MEM (V2SImode,
- gen_rtx_POST_INC (SImode,
- stack_pointer_rtx));
- set_mem_alias_set (addr, get_frame_alias_set ());
- insn = emit_insn (gen_movsi (gen_rtx_REG (V2SImode, i), addr));
- REG_NOTES (insn) = alloc_reg_note (REG_CFA_RESTORE,
- gen_rtx_REG (V2SImode, i),
- NULL_RTX);
- }
-
- if (saved_regs_mask)
- {
- rtx insn;
- bool return_in_pc = false;
-
- if (ARM_FUNC_TYPE (func_type) != ARM_FT_INTERWORKED
- && (TARGET_ARM || ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL)
- && !IS_STACKALIGN (func_type)
- && really_return
- && crtl->args.pretend_args_size == 0
- && saved_regs_mask & (1 << LR_REGNUM)
- && !crtl->calls_eh_return)
- {
- saved_regs_mask &= ~(1 << LR_REGNUM);
- saved_regs_mask |= (1 << PC_REGNUM);
- return_in_pc = true;
- }
-
- if (num_regs == 1 && (!IS_INTERRUPT (func_type) || !return_in_pc))
- {
- for (i = 0; i <= LAST_ARM_REGNUM; i++)
- if (saved_regs_mask & (1 << i))
- {
- rtx addr = gen_rtx_MEM (SImode,
- gen_rtx_POST_INC (SImode,
- stack_pointer_rtx));
- set_mem_alias_set (addr, get_frame_alias_set ());
-
- if (i == PC_REGNUM)
- {
- insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
- XVECEXP (insn, 0, 0) = ret_rtx;
- XVECEXP (insn, 0, 1) = gen_rtx_SET (SImode,
- gen_rtx_REG (SImode, i),
- addr);
- RTX_FRAME_RELATED_P (XVECEXP (insn, 0, 1)) = 1;
- insn = emit_jump_insn (insn);
- }
- else
- {
- insn = emit_insn (gen_movsi (gen_rtx_REG (SImode, i),
- addr));
- REG_NOTES (insn) = alloc_reg_note (REG_CFA_RESTORE,
- gen_rtx_REG (SImode, i),
- NULL_RTX);
- }
- }
- }
- else
- {
- if (current_tune->prefer_ldrd_strd
- && !optimize_function_for_size_p (cfun))
- {
- if (TARGET_THUMB2)
- thumb2_emit_ldrd_pop (saved_regs_mask);
- else
- arm_emit_multi_reg_pop (saved_regs_mask);
- }
- else
- arm_emit_multi_reg_pop (saved_regs_mask);
- }
-
- if (return_in_pc == true)
- return;
- }
-
- if (crtl->args.pretend_args_size)
- emit_insn (gen_addsi3 (stack_pointer_rtx,
- stack_pointer_rtx,
- GEN_INT (crtl->args.pretend_args_size)));
-
- if (!really_return)
- return;
-
- if (crtl->calls_eh_return)
- emit_insn (gen_addsi3 (stack_pointer_rtx,
- stack_pointer_rtx,
- gen_rtx_REG (SImode, ARM_EH_STACKADJ_REGNUM)));
-
- if (IS_STACKALIGN (func_type))
- /* Restore the original stack pointer. Before prologue, the stack was
- realigned and the original stack pointer saved in r0. For details,
- see comment in arm_expand_prologue. */
- emit_insn (gen_movsi (stack_pointer_rtx, gen_rtx_REG (SImode, 0)));
-
- emit_jump_insn (simple_return_rtx);
-}
-
-/* Implementation of insn prologue_thumb1_interwork. This is the first
- "instruction" of a function called in ARM mode. Swap to thumb mode. */
-
-const char *
-thumb1_output_interwork (void)
-{
- const char * name;
- FILE *f = asm_out_file;
-
- gcc_assert (MEM_P (DECL_RTL (current_function_decl)));
- gcc_assert (GET_CODE (XEXP (DECL_RTL (current_function_decl), 0))
- == SYMBOL_REF);
- name = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
-
- /* Generate code sequence to switch us into Thumb mode. */
- /* The .code 32 directive has already been emitted by
- ASM_DECLARE_FUNCTION_NAME. */
- asm_fprintf (f, "\torr\t%r, %r, #1\n", IP_REGNUM, PC_REGNUM);
- asm_fprintf (f, "\tbx\t%r\n", IP_REGNUM);
-
- /* Generate a label, so that the debugger will notice the
- change in instruction sets. This label is also used by
- the assembler to bypass the ARM code when this function
- is called from a Thumb encoded function elsewhere in the
- same file. Hence the definition of STUB_NAME here must
- agree with the definition in gas/config/tc-arm.c. */
-
-#define STUB_NAME ".real_start_of"
-
- fprintf (f, "\t.code\t16\n");
-#ifdef ARM_PE
- if (arm_dllexport_name_p (name))
- name = arm_strip_name_encoding (name);
-#endif
- asm_fprintf (f, "\t.globl %s%U%s\n", STUB_NAME, name);
- fprintf (f, "\t.thumb_func\n");
- asm_fprintf (f, "%s%U%s:\n", STUB_NAME, name);
-
- return "";
-}
-
-/* Handle the case of a double word load into a low register from
- a computed memory address. The computed address may involve a
- register which is overwritten by the load. */
-const char *
-thumb_load_double_from_address (rtx *operands)
-{
- rtx addr;
- rtx base;
- rtx offset;
- rtx arg1;
- rtx arg2;
-
- gcc_assert (REG_P (operands[0]));
- gcc_assert (MEM_P (operands[1]));
-
- /* Get the memory address. */
- addr = XEXP (operands[1], 0);
-
- /* Work out how the memory address is computed. */
- switch (GET_CODE (addr))
- {
- case REG:
- operands[2] = adjust_address (operands[1], SImode, 4);
-
- if (REGNO (operands[0]) == REGNO (addr))
- {
- output_asm_insn ("ldr\t%H0, %2", operands);
- output_asm_insn ("ldr\t%0, %1", operands);
- }
- else
- {
- output_asm_insn ("ldr\t%0, %1", operands);
- output_asm_insn ("ldr\t%H0, %2", operands);
- }
- break;
-
- case CONST:
- /* Compute <address> + 4 for the high order load. */
- operands[2] = adjust_address (operands[1], SImode, 4);
-
- output_asm_insn ("ldr\t%0, %1", operands);
- output_asm_insn ("ldr\t%H0, %2", operands);
- break;
-
- case PLUS:
- arg1 = XEXP (addr, 0);
- arg2 = XEXP (addr, 1);
-
- if (CONSTANT_P (arg1))
- base = arg2, offset = arg1;
- else
- base = arg1, offset = arg2;
-
- gcc_assert (REG_P (base));
-
- /* Catch the case of <address> = <reg> + <reg> */
- if (REG_P (offset))
- {
- int reg_offset = REGNO (offset);
- int reg_base = REGNO (base);
- int reg_dest = REGNO (operands[0]);
-
- /* Add the base and offset registers together into the
- higher destination register. */
- asm_fprintf (asm_out_file, "\tadd\t%r, %r, %r",
- reg_dest + 1, reg_base, reg_offset);
-
- /* Load the lower destination register from the address in
- the higher destination register. */
- asm_fprintf (asm_out_file, "\tldr\t%r, [%r, #0]",
- reg_dest, reg_dest + 1);
-
- /* Load the higher destination register from its own address
- plus 4. */
- asm_fprintf (asm_out_file, "\tldr\t%r, [%r, #4]",
- reg_dest + 1, reg_dest + 1);
- }
- else
- {
- /* Compute <address> + 4 for the high order load. */
- operands[2] = adjust_address (operands[1], SImode, 4);
-
- /* If the computed address is held in the low order register
- then load the high order register first, otherwise always
- load the low order register first. */
- if (REGNO (operands[0]) == REGNO (base))
- {
- output_asm_insn ("ldr\t%H0, %2", operands);
- output_asm_insn ("ldr\t%0, %1", operands);
- }
- else
- {
- output_asm_insn ("ldr\t%0, %1", operands);
- output_asm_insn ("ldr\t%H0, %2", operands);
- }
- }
- break;
-
- case LABEL_REF:
- /* With no registers to worry about we can just load the value
- directly. */
- operands[2] = adjust_address (operands[1], SImode, 4);
-
- output_asm_insn ("ldr\t%H0, %2", operands);
- output_asm_insn ("ldr\t%0, %1", operands);
- break;
-
- default:
- gcc_unreachable ();
- }
-
- return "";
-}
-
-const char *
-thumb_output_move_mem_multiple (int n, rtx *operands)
-{
- rtx tmp;
-
- switch (n)
- {
- case 2:
- if (REGNO (operands[4]) > REGNO (operands[5]))
- {
- tmp = operands[4];
- operands[4] = operands[5];
- operands[5] = tmp;
- }
- output_asm_insn ("ldmia\t%1!, {%4, %5}", operands);
- output_asm_insn ("stmia\t%0!, {%4, %5}", operands);
- break;
-
- case 3:
- if (REGNO (operands[4]) > REGNO (operands[5]))
- {
- tmp = operands[4];
- operands[4] = operands[5];
- operands[5] = tmp;
- }
- if (REGNO (operands[5]) > REGNO (operands[6]))
- {
- tmp = operands[5];
- operands[5] = operands[6];
- operands[6] = tmp;
- }
- if (REGNO (operands[4]) > REGNO (operands[5]))
- {
- tmp = operands[4];
- operands[4] = operands[5];
- operands[5] = tmp;
- }
-
- output_asm_insn ("ldmia\t%1!, {%4, %5, %6}", operands);
- output_asm_insn ("stmia\t%0!, {%4, %5, %6}", operands);
- break;
-
- default:
- gcc_unreachable ();
- }
-
- return "";
-}
-
-/* Output a call-via instruction for thumb state. */
-const char *
-thumb_call_via_reg (rtx reg)
-{
- int regno = REGNO (reg);
- rtx *labelp;
-
- gcc_assert (regno < LR_REGNUM);
-
- /* If we are in the normal text section we can use a single instance
- per compilation unit. If we are doing function sections, then we need
- an entry per section, since we can't rely on reachability. */
- if (in_section == text_section)
- {
- thumb_call_reg_needed = 1;
-
- if (thumb_call_via_label[regno] == NULL)
- thumb_call_via_label[regno] = gen_label_rtx ();
- labelp = thumb_call_via_label + regno;
- }
- else
- {
- if (cfun->machine->call_via[regno] == NULL)
- cfun->machine->call_via[regno] = gen_label_rtx ();
- labelp = cfun->machine->call_via + regno;
- }
-
- output_asm_insn ("bl\t%a0", labelp);
- return "";
-}
-
-/* Routines for generating rtl. */
-void
-thumb_expand_movmemqi (rtx *operands)
-{
- rtx out = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
- rtx in = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
- HOST_WIDE_INT len = INTVAL (operands[2]);
- HOST_WIDE_INT offset = 0;
-
- while (len >= 12)
- {
- emit_insn (gen_movmem12b (out, in, out, in));
- len -= 12;
- }
-
- if (len >= 8)
- {
- emit_insn (gen_movmem8b (out, in, out, in));
- len -= 8;
- }
-
- if (len >= 4)
- {
- rtx reg = gen_reg_rtx (SImode);
- emit_insn (gen_movsi (reg, gen_rtx_MEM (SImode, in)));
- emit_insn (gen_movsi (gen_rtx_MEM (SImode, out), reg));
- len -= 4;
- offset += 4;
- }
-
- if (len >= 2)
- {
- rtx reg = gen_reg_rtx (HImode);
- emit_insn (gen_movhi (reg, gen_rtx_MEM (HImode,
- plus_constant (Pmode, in,
- offset))));
- emit_insn (gen_movhi (gen_rtx_MEM (HImode, plus_constant (Pmode, out,
- offset)),
- reg));
- len -= 2;
- offset += 2;
- }
-
- if (len)
- {
- rtx reg = gen_reg_rtx (QImode);
- emit_insn (gen_movqi (reg, gen_rtx_MEM (QImode,
- plus_constant (Pmode, in,
- offset))));
- emit_insn (gen_movqi (gen_rtx_MEM (QImode, plus_constant (Pmode, out,
- offset)),
- reg));
- }
-}
-
-void
-thumb_reload_out_hi (rtx *operands)
-{
- emit_insn (gen_thumb_movhi_clobber (operands[0], operands[1], operands[2]));
-}
-
-/* Handle reading a half-word from memory during reload. */
-void
-thumb_reload_in_hi (rtx *operands ATTRIBUTE_UNUSED)
-{
- gcc_unreachable ();
-}
-
-/* Return the length of a function name prefix
- that starts with the character 'c'. */
-static int
-arm_get_strip_length (int c)
-{
- switch (c)
- {
- ARM_NAME_ENCODING_LENGTHS
- default: return 0;
- }
-}
-
-/* Return a pointer to a function's name with any
- and all prefix encodings stripped from it. */
-const char *
-arm_strip_name_encoding (const char *name)
-{
- int skip;
-
- while ((skip = arm_get_strip_length (* name)))
- name += skip;
-
- return name;
-}
-
-/* If there is a '*' anywhere in the name's prefix, then
- emit the stripped name verbatim, otherwise prepend an
- underscore if leading underscores are being used. */
-void
-arm_asm_output_labelref (FILE *stream, const char *name)
-{
- int skip;
- int verbatim = 0;
-
- while ((skip = arm_get_strip_length (* name)))
- {
- verbatim |= (*name == '*');
- name += skip;
- }
-
- if (verbatim)
- fputs (name, stream);
- else
- asm_fprintf (stream, "%U%s", name);
-}
-
-/* This function is used to emit an EABI tag and its associated value.
- We emit the numerical value of the tag in case the assembler does not
- support textual tags. (Eg gas prior to 2.20). If requested we include
- the tag name in a comment so that anyone reading the assembler output
- will know which tag is being set.
-
- This function is not static because arm-c.c needs it too. */
-
-void
-arm_emit_eabi_attribute (const char *name, int num, int val)
-{
- asm_fprintf (asm_out_file, "\t.eabi_attribute %d, %d", num, val);
- if (flag_verbose_asm || flag_debug_asm)
- asm_fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, name);
- asm_fprintf (asm_out_file, "\n");
-}
-
-static void
-arm_file_start (void)
-{
- int val;
-
- if (TARGET_UNIFIED_ASM)
- asm_fprintf (asm_out_file, "\t.syntax unified\n");
-
- if (TARGET_BPABI)
- {
- const char *fpu_name;
- if (arm_selected_arch)
- asm_fprintf (asm_out_file, "\t.arch %s\n", arm_selected_arch->name);
- else if (strncmp (arm_selected_cpu->name, "generic", 7) == 0)
- asm_fprintf (asm_out_file, "\t.arch %s\n", arm_selected_cpu->name + 8);
- else
- asm_fprintf (asm_out_file, "\t.cpu %s\n", arm_selected_cpu->name);
-
- if (TARGET_SOFT_FLOAT)
- {
- fpu_name = "softvfp";
- }
- else
- {
- fpu_name = arm_fpu_desc->name;
- if (arm_fpu_desc->model == ARM_FP_MODEL_VFP)
- {
- if (TARGET_HARD_FLOAT)
- arm_emit_eabi_attribute ("Tag_ABI_HardFP_use", 27, 3);
- if (TARGET_HARD_FLOAT_ABI)
- arm_emit_eabi_attribute ("Tag_ABI_VFP_args", 28, 1);
- }
- }
- asm_fprintf (asm_out_file, "\t.fpu %s\n", fpu_name);
-
- /* Some of these attributes only apply when the corresponding features
- are used. However we don't have any easy way of figuring this out.
- Conservatively record the setting that would have been used. */
-
- if (flag_rounding_math)
- arm_emit_eabi_attribute ("Tag_ABI_FP_rounding", 19, 1);
-
- if (!flag_unsafe_math_optimizations)
- {
- arm_emit_eabi_attribute ("Tag_ABI_FP_denormal", 20, 1);
- arm_emit_eabi_attribute ("Tag_ABI_FP_exceptions", 21, 1);
- }
- if (flag_signaling_nans)
- arm_emit_eabi_attribute ("Tag_ABI_FP_user_exceptions", 22, 1);
-
- arm_emit_eabi_attribute ("Tag_ABI_FP_number_model", 23,
- flag_finite_math_only ? 1 : 3);
-
- arm_emit_eabi_attribute ("Tag_ABI_align8_needed", 24, 1);
- arm_emit_eabi_attribute ("Tag_ABI_align8_preserved", 25, 1);
- arm_emit_eabi_attribute ("Tag_ABI_enum_size", 26,
- flag_short_enums ? 1 : 2);
-
- /* Tag_ABI_optimization_goals. */
- if (optimize_size)
- val = 4;
- else if (optimize >= 2)
- val = 2;
- else if (optimize)
- val = 1;
- else
- val = 6;
- arm_emit_eabi_attribute ("Tag_ABI_optimization_goals", 30, val);
-
- arm_emit_eabi_attribute ("Tag_CPU_unaligned_access", 34,
- unaligned_access);
-
- if (arm_fp16_format)
- arm_emit_eabi_attribute ("Tag_ABI_FP_16bit_format", 38,
- (int) arm_fp16_format);
-
- if (arm_lang_output_object_attributes_hook)
- arm_lang_output_object_attributes_hook();
- }
-
- default_file_start ();
-}
-
-static void
-arm_file_end (void)
-{
- int regno;
-
- if (NEED_INDICATE_EXEC_STACK)
- /* Add .note.GNU-stack. */
- file_end_indicate_exec_stack ();
-
- if (! thumb_call_reg_needed)
- return;
-
- switch_to_section (text_section);
- asm_fprintf (asm_out_file, "\t.code 16\n");
- ASM_OUTPUT_ALIGN (asm_out_file, 1);
-
- for (regno = 0; regno < LR_REGNUM; regno++)
- {
- rtx label = thumb_call_via_label[regno];
-
- if (label != 0)
- {
- targetm.asm_out.internal_label (asm_out_file, "L",
- CODE_LABEL_NUMBER (label));
- asm_fprintf (asm_out_file, "\tbx\t%r\n", regno);
- }
- }
-}
-
-#ifndef ARM_PE
-/* Symbols in the text segment can be accessed without indirecting via the
- constant pool; it may take an extra binary operation, but this is still
- faster than indirecting via memory. Don't do this when not optimizing,
- since we won't be calculating al of the offsets necessary to do this
- simplification. */
-
-static void
-arm_encode_section_info (tree decl, rtx rtl, int first)
-{
- if (optimize > 0 && TREE_CONSTANT (decl))
- SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
-
- default_encode_section_info (decl, rtl, first);
-}
-#endif /* !ARM_PE */
-
-static void
-arm_internal_label (FILE *stream, const char *prefix, unsigned long labelno)
-{
- if (arm_ccfsm_state == 3 && (unsigned) arm_target_label == labelno
- && !strcmp (prefix, "L"))
- {
- arm_ccfsm_state = 0;
- arm_target_insn = NULL;
- }
- default_internal_label (stream, prefix, labelno);
-}
-
-/* Output code to add DELTA to the first argument, and then jump
- to FUNCTION. Used for C++ multiple inheritance. */
-static void
-arm_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
- HOST_WIDE_INT delta,
- HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
- tree function)
-{
- static int thunk_label = 0;
- char label[256];
- char labelpc[256];
- int mi_delta = delta;
- const char *const mi_op = mi_delta < 0 ? "sub" : "add";
- int shift = 0;
- int this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)
- ? 1 : 0);
- if (mi_delta < 0)
- mi_delta = - mi_delta;
-
- final_start_function (emit_barrier (), file, 1);
-
- if (TARGET_THUMB1)
- {
- int labelno = thunk_label++;
- ASM_GENERATE_INTERNAL_LABEL (label, "LTHUMBFUNC", labelno);
- /* 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)
- {
- /* If we are generating PIC, the ldr instruction below loads
- "(target - 7) - .LTHUNKPCn" into r12. The pc reads as
- the address of the add + 8, so we have:
-
- r12 = (target - 7) - .LTHUNKPCn + (.LTHUNKPCn + 8)
- = target + 1.
-
- 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.
- On ARMv6M this is +4, not +8. */
- ASM_GENERATE_INTERNAL_LABEL (labelpc, "LTHUNKPC", labelno);
- assemble_name (file, labelpc);
- fputs (":\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);
- }
- if (TARGET_THUMB1_ONLY)
- {
- 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);
- fputs (":\n", file);
- if (flag_pic)
- {
- /* Output ".word .LTHUNKn-7-.LTHUNKPCn". */
- rtx tem = XEXP (DECL_RTL (function), 0);
- tem = gen_rtx_PLUS (GET_MODE (tem), tem, GEN_INT (-7));
- tem = gen_rtx_MINUS (GET_MODE (tem),
- tem,
- gen_rtx_SYMBOL_REF (Pmode,
- ggc_strdup (labelpc)));
- assemble_integer (tem, 4, BITS_PER_WORD, 1);
- }
- 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
- {
- fputs ("\tb\t", file);
- assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
- if (NEED_PLT_RELOC)
- fputs ("(PLT)", file);
- fputc ('\n', file);
- }
-
- final_end_function ();
-}
-
-int
-arm_emit_vector_const (FILE *file, rtx x)
-{
- int i;
- const char * pattern;
-
- gcc_assert (GET_CODE (x) == CONST_VECTOR);
-
- switch (GET_MODE (x))
- {
- case V2SImode: pattern = "%08x"; break;
- case V4HImode: pattern = "%04x"; break;
- case V8QImode: pattern = "%02x"; break;
- default: gcc_unreachable ();
- }
-
- fprintf (file, "0x");
- for (i = CONST_VECTOR_NUNITS (x); i--;)
- {
- rtx element;
-
- element = CONST_VECTOR_ELT (x, i);
- fprintf (file, pattern, INTVAL (element));
- }
-
- 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)
-{
- rtx reg;
- rtx offset;
- rtx wcgr;
- rtx sum;
-
- if (!MEM_P (operands [1])
- || GET_CODE (sum = XEXP (operands [1], 0)) != PLUS
- || !REG_P (reg = XEXP (sum, 0))
- || !CONST_INT_P (offset = XEXP (sum, 1))
- || ((INTVAL (offset) < 1024) && (INTVAL (offset) > -1024)))
- return "wldrw%?\t%0, %1";
-
- /* Fix up an out-of-range load of a GR register. */
- output_asm_insn ("str%?\t%0, [sp, #-4]!\t@ Start of GR load expansion", & reg);
- wcgr = operands[0];
- operands[0] = reg;
- output_asm_insn ("ldr%?\t%0, %1", operands);
-
- operands[0] = wcgr;
- operands[1] = reg;
- output_asm_insn ("tmcr%?\t%0, %1", operands);
- output_asm_insn ("ldr%?\t%0, [sp], #4\t@ End of GR load expansion", & reg);
-
- return "";
-}
-
-/* Worker function for TARGET_SETUP_INCOMING_VARARGS.
-
- On the ARM, PRETEND_SIZE is set in order to have the prologue push the last
- named arg and all anonymous args onto the stack.
- XXX I know the prologue shouldn't be pushing registers, but it is faster
- that way. */
-
-static void
-arm_setup_incoming_varargs (cumulative_args_t pcum_v,
- enum machine_mode mode,
- tree type,
- int *pretend_size,
- int second_time ATTRIBUTE_UNUSED)
-{
- CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
- 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;
-}
-
-/* Return nonzero if the CONSUMER instruction (a store) does not need
- PRODUCER's value to calculate the address. */
-
-int
-arm_no_early_store_addr_dep (rtx producer, rtx consumer)
-{
- rtx value = PATTERN (producer);
- rtx addr = PATTERN (consumer);
-
- if (GET_CODE (value) == COND_EXEC)
- value = COND_EXEC_CODE (value);
- if (GET_CODE (value) == PARALLEL)
- value = XVECEXP (value, 0, 0);
- value = XEXP (value, 0);
- if (GET_CODE (addr) == COND_EXEC)
- addr = COND_EXEC_CODE (addr);
- if (GET_CODE (addr) == PARALLEL)
- addr = XVECEXP (addr, 0, 0);
- addr = XEXP (addr, 0);
-
- return !reg_overlap_mentioned_p (value, addr);
-}
-
-/* Return nonzero if the CONSUMER instruction (a store) does need
- PRODUCER's value to calculate the address. */
-
-int
-arm_early_store_addr_dep (rtx producer, rtx consumer)
-{
- return !arm_no_early_store_addr_dep (producer, consumer);
-}
-
-/* Return nonzero if the CONSUMER instruction (a load) does need
- PRODUCER's value to calculate the address. */
-
-int
-arm_early_load_addr_dep (rtx producer, rtx consumer)
-{
- rtx value = PATTERN (producer);
- rtx addr = PATTERN (consumer);
-
- if (GET_CODE (value) == COND_EXEC)
- value = COND_EXEC_CODE (value);
- if (GET_CODE (value) == PARALLEL)
- value = XVECEXP (value, 0, 0);
- value = XEXP (value, 0);
- if (GET_CODE (addr) == COND_EXEC)
- addr = COND_EXEC_CODE (addr);
- if (GET_CODE (addr) == PARALLEL)
- {
- if (GET_CODE (XVECEXP (addr, 0, 0)) == RETURN)
- addr = XVECEXP (addr, 0, 1);
- else
- addr = XVECEXP (addr, 0, 0);
- }
- addr = XEXP (addr, 1);
-
- return reg_overlap_mentioned_p (value, addr);
-}
-
-/* Return nonzero if the CONSUMER instruction (an ALU op) does not
- have an early register shift value or amount dependency on the
- result of PRODUCER. */
-
-int
-arm_no_early_alu_shift_dep (rtx producer, rtx consumer)
-{
- rtx value = PATTERN (producer);
- rtx op = PATTERN (consumer);
- rtx early_op;
-
- if (GET_CODE (value) == COND_EXEC)
- value = COND_EXEC_CODE (value);
- if (GET_CODE (value) == PARALLEL)
- value = XVECEXP (value, 0, 0);
- value = XEXP (value, 0);
- if (GET_CODE (op) == COND_EXEC)
- op = COND_EXEC_CODE (op);
- if (GET_CODE (op) == PARALLEL)
- op = XVECEXP (op, 0, 0);
- op = XEXP (op, 1);
-
- early_op = XEXP (op, 0);
- /* This is either an actual independent shift, or a shift applied to
- the first operand of another operation. We want the whole shift
- operation. */
- if (REG_P (early_op))
- early_op = op;
-
- return !reg_overlap_mentioned_p (value, early_op);
-}
-
-/* Return nonzero if the CONSUMER instruction (an ALU op) does not
- have an early register shift value dependency on the result of
- PRODUCER. */
-
-int
-arm_no_early_alu_shift_value_dep (rtx producer, rtx consumer)
-{
- rtx value = PATTERN (producer);
- rtx op = PATTERN (consumer);
- rtx early_op;
-
- if (GET_CODE (value) == COND_EXEC)
- value = COND_EXEC_CODE (value);
- if (GET_CODE (value) == PARALLEL)
- value = XVECEXP (value, 0, 0);
- value = XEXP (value, 0);
- if (GET_CODE (op) == COND_EXEC)
- op = COND_EXEC_CODE (op);
- if (GET_CODE (op) == PARALLEL)
- op = XVECEXP (op, 0, 0);
- op = XEXP (op, 1);
-
- early_op = XEXP (op, 0);
-
- /* This is either an actual independent shift, or a shift applied to
- the first operand of another operation. We want the value being
- shifted, in either case. */
- if (!REG_P (early_op))
- early_op = XEXP (early_op, 0);
-
- return !reg_overlap_mentioned_p (value, early_op);
-}
-
-/* Return nonzero if the CONSUMER (a mul or mac op) does not
- have an early register mult dependency on the result of
- PRODUCER. */
-
-int
-arm_no_early_mul_dep (rtx producer, rtx consumer)
-{
- rtx value = PATTERN (producer);
- rtx op = PATTERN (consumer);
-
- if (GET_CODE (value) == COND_EXEC)
- value = COND_EXEC_CODE (value);
- if (GET_CODE (value) == PARALLEL)
- value = XVECEXP (value, 0, 0);
- value = XEXP (value, 0);
- if (GET_CODE (op) == COND_EXEC)
- op = COND_EXEC_CODE (op);
- if (GET_CODE (op) == PARALLEL)
- op = XVECEXP (op, 0, 0);
- op = XEXP (op, 1);
-
- 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
- using APCS or ATPCS. */
-
-static bool
-arm_promote_prototypes (const_tree t ATTRIBUTE_UNUSED)
-{
- return !TARGET_AAPCS_BASED;
-}
-
-static enum machine_mode
-arm_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
- enum machine_mode mode,
- int *punsignedp ATTRIBUTE_UNUSED,
- const_tree fntype ATTRIBUTE_UNUSED,
- int for_return ATTRIBUTE_UNUSED)
-{
- if (GET_MODE_CLASS (mode) == MODE_INT
- && GET_MODE_SIZE (mode) < 4)
- return SImode;
-
- return mode;
-}
-
-/* AAPCS based ABIs use short enums by default. */
-
-static bool
-arm_default_short_enums (void)
-{
- return TARGET_AAPCS_BASED && arm_abi != ARM_ABI_AAPCS_LINUX;
-}
-
-
-/* AAPCS requires that anonymous bitfields affect structure alignment. */
-
-static bool
-arm_align_anon_bitfield (void)
-{
- return TARGET_AAPCS_BASED;
-}
-
-
-/* The generic C++ ABI says 64-bit (long long). The EABI says 32-bit. */
-
-static tree
-arm_cxx_guard_type (void)
-{
- return TARGET_AAPCS_BASED ? integer_type_node : long_long_integer_type_node;
-}
-
-/* Return non-zero iff the consumer (a multiply-accumulate or a
- multiple-subtract instruction) has an accumulator dependency on the
- result of the producer and no other dependency on that result. It
- does not check if the producer is multiply-accumulate instruction. */
-int
-arm_mac_accumulator_is_result (rtx producer, rtx consumer)
-{
- rtx result;
- rtx op0, op1, acc;
-
- producer = PATTERN (producer);
- consumer = PATTERN (consumer);
-
- if (GET_CODE (producer) == COND_EXEC)
- producer = COND_EXEC_CODE (producer);
- if (GET_CODE (consumer) == COND_EXEC)
- consumer = COND_EXEC_CODE (consumer);
-
- if (GET_CODE (producer) != SET)
- return 0;
-
- result = XEXP (producer, 0);
-
- if (GET_CODE (consumer) != SET)
- return 0;
-
- /* Check that the consumer is of the form
- (set (...) (plus (mult ...) (...)))
- or
- (set (...) (minus (...) (mult ...))). */
- if (GET_CODE (XEXP (consumer, 1)) == PLUS)
- {
- if (GET_CODE (XEXP (XEXP (consumer, 1), 0)) != MULT)
- return 0;
-
- op0 = XEXP (XEXP (XEXP (consumer, 1), 0), 0);
- op1 = XEXP (XEXP (XEXP (consumer, 1), 0), 1);
- acc = XEXP (XEXP (consumer, 1), 1);
- }
- else if (GET_CODE (XEXP (consumer, 1)) == MINUS)
- {
- if (GET_CODE (XEXP (XEXP (consumer, 1), 1)) != MULT)
- return 0;
-
- op0 = XEXP (XEXP (XEXP (consumer, 1), 1), 0);
- op1 = XEXP (XEXP (XEXP (consumer, 1), 1), 1);
- acc = XEXP (XEXP (consumer, 1), 0);
- }
- else
- return 0;
-
- return (reg_overlap_mentioned_p (result, acc)
- && !reg_overlap_mentioned_p (result, op0)
- && !reg_overlap_mentioned_p (result, op1));
-}
-
-/* Return non-zero if the consumer (a multiply-accumulate instruction)
- has an accumulator dependency on the result of the producer (a
- multiplication instruction) and no other dependency on that result. */
-int
-arm_mac_accumulator_is_mul_result (rtx producer, rtx consumer)
-{
- rtx mul = PATTERN (producer);
- rtx mac = PATTERN (consumer);
- rtx mul_result;
- rtx mac_op0, mac_op1, mac_acc;
-
- if (GET_CODE (mul) == COND_EXEC)
- mul = COND_EXEC_CODE (mul);
- if (GET_CODE (mac) == COND_EXEC)
- mac = COND_EXEC_CODE (mac);
-
- /* Check that mul is of the form (set (...) (mult ...))
- and mla is of the form (set (...) (plus (mult ...) (...))). */
- if ((GET_CODE (mul) != SET || GET_CODE (XEXP (mul, 1)) != MULT)
- || (GET_CODE (mac) != SET || GET_CODE (XEXP (mac, 1)) != PLUS
- || GET_CODE (XEXP (XEXP (mac, 1), 0)) != MULT))
- return 0;
-
- mul_result = XEXP (mul, 0);
- mac_op0 = XEXP (XEXP (XEXP (mac, 1), 0), 0);
- mac_op1 = XEXP (XEXP (XEXP (mac, 1), 0), 1);
- mac_acc = XEXP (XEXP (mac, 1), 1);
-
- return (reg_overlap_mentioned_p (mul_result, mac_acc)
- && !reg_overlap_mentioned_p (mul_result, mac_op0)
- && !reg_overlap_mentioned_p (mul_result, mac_op1));
-}
-
-
-/* The EABI says test the least significant bit of a guard variable. */
-
-static bool
-arm_cxx_guard_mask_bit (void)
-{
- return TARGET_AAPCS_BASED;
-}
-
-
-/* The EABI specifies that all array cookies are 8 bytes long. */
-
-static tree
-arm_get_cookie_size (tree type)
-{
- tree size;
-
- if (!TARGET_AAPCS_BASED)
- return default_cxx_get_cookie_size (type);
-
- size = build_int_cst (sizetype, 8);
- return size;
-}
-
-
-/* The EABI says that array cookies should also contain the element size. */
-
-static bool
-arm_cookie_has_size (void)
-{
- return TARGET_AAPCS_BASED;
-}
-
-
-/* The EABI says constructors and destructors should return a pointer to
- the object constructed/destroyed. */
-
-static bool
-arm_cxx_cdtor_returns_this (void)
-{
- return TARGET_AAPCS_BASED;
-}
-
-/* The EABI says that an inline function may never be the key
- method. */
-
-static bool
-arm_cxx_key_method_may_be_inline (void)
-{
- return !TARGET_AAPCS_BASED;
-}
-
-static void
-arm_cxx_determine_class_data_visibility (tree decl)
-{
- if (!TARGET_AAPCS_BASED
- || !TARGET_DLLIMPORT_DECL_ATTRIBUTES)
- return;
-
- /* In general, \S 3.2.5.5 of the ARM EABI requires that class data
- is exported. However, on systems without dynamic vague linkage,
- \S 3.2.5.6 says that COMDAT class data has hidden linkage. */
- if (!TARGET_ARM_DYNAMIC_VAGUE_LINKAGE_P && DECL_COMDAT (decl))
- DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
- else
- DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
- DECL_VISIBILITY_SPECIFIED (decl) = 1;
-}
-
-static bool
-arm_cxx_class_data_always_comdat (void)
-{
- /* \S 3.2.5.4 of the ARM C++ ABI says that class data only have
- vague linkage if the class has no key function. */
- return !TARGET_AAPCS_BASED;
-}
-
-
-/* The EABI says __aeabi_atexit should be used to register static
- destructors. */
-
-static bool
-arm_cxx_use_aeabi_atexit (void)
-{
- return TARGET_AAPCS_BASED;
-}
-
-
-void
-arm_set_return_address (rtx source, rtx scratch)
-{
- arm_stack_offsets *offsets;
- HOST_WIDE_INT delta;
- rtx addr;
- unsigned long saved_regs;
-
- 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);
- else
- {
- if (frame_pointer_needed)
- addr = plus_constant (Pmode, hard_frame_pointer_rtx, -4);
- else
- {
- /* LR will be the first saved register. */
- delta = offsets->outgoing_args - (offsets->frame + 4);
-
-
- if (delta >= 4096)
- {
- emit_insn (gen_addsi3 (scratch, stack_pointer_rtx,
- GEN_INT (delta & ~4095)));
- addr = scratch;
- delta &= 4095;
- }
- else
- addr = stack_pointer_rtx;
-
- addr = plus_constant (Pmode, addr, delta);
- }
- emit_move_insn (gen_frame_mem (Pmode, addr), source);
- }
-}
-
-
-void
-thumb_set_return_address (rtx source, rtx scratch)
-{
- arm_stack_offsets *offsets;
- HOST_WIDE_INT delta;
- HOST_WIDE_INT limit;
- int reg;
- rtx addr;
- unsigned long mask;
-
- emit_use (source);
-
- offsets = arm_get_frame_offsets ();
- mask = offsets->saved_regs_mask;
- if (mask & (1 << LR_REGNUM))
- {
- limit = 1024;
- /* Find the saved regs. */
- if (frame_pointer_needed)
- {
- delta = offsets->soft_frame - offsets->saved_args;
- reg = THUMB_HARD_FRAME_POINTER_REGNUM;
- if (TARGET_THUMB1)
- limit = 128;
- }
- else
- {
- delta = offsets->outgoing_args - offsets->saved_args;
- reg = SP_REGNUM;
- }
- /* Allow for the stack frame. */
- if (TARGET_THUMB1 && TARGET_BACKTRACE)
- delta -= 16;
- /* The link register is always the first saved register. */
- delta -= 4;
-
- /* Construct the address. */
- addr = gen_rtx_REG (SImode, reg);
- if (delta > limit)
- {
- emit_insn (gen_movsi (scratch, GEN_INT (delta)));
- emit_insn (gen_addsi3 (scratch, scratch, stack_pointer_rtx));
- addr = scratch;
- }
- else
- addr = plus_constant (Pmode, addr, delta);
-
- emit_move_insn (gen_frame_mem (Pmode, addr), source);
- }
- else
- emit_move_insn (gen_rtx_REG (Pmode, LR_REGNUM), source);
-}
-
-/* Implements target hook vector_mode_supported_p. */
-bool
-arm_vector_mode_supported_p (enum machine_mode mode)
-{
- /* Neon also supports V2SImode, etc. listed in the clause below. */
- if (TARGET_NEON && (mode == V2SFmode || mode == V4SImode || mode == V8HImode
- || mode == V16QImode || mode == V4SFmode || mode == V2DImode))
- return true;
-
- if ((TARGET_NEON || TARGET_IWMMXT)
- && ((mode == V2SImode)
- || (mode == V4HImode)
- || (mode == V8QImode)))
- return true;
-
- if (TARGET_INT_SIMD && (mode == V4UQQmode || mode == V4QQmode
- || mode == V2UHQmode || mode == V2HQmode || mode == V2UHAmode
- || mode == V2HAmode))
- return true;
-
- return false;
-}
-
-/* Implements target hook array_mode_supported_p. */
-
-static bool
-arm_array_mode_supported_p (enum machine_mode mode,
- unsigned HOST_WIDE_INT nelems)
-{
- if (TARGET_NEON
- && (VALID_NEON_DREG_MODE (mode) || VALID_NEON_QREG_MODE (mode))
- && (nelems >= 2 && nelems <= 4))
- return true;
-
- return false;
-}
-
-/* Use the option -mvectorize-with-neon-double to override the use of quardword
- registers when autovectorizing for Neon, at least until multiple vector
- widths are supported properly by the middle-end. */
-
-static enum machine_mode
-arm_preferred_simd_mode (enum machine_mode mode)
-{
- if (TARGET_NEON)
- switch (mode)
- {
- case SFmode:
- return TARGET_NEON_VECTORIZE_DOUBLE ? V2SFmode : V4SFmode;
- case SImode:
- return TARGET_NEON_VECTORIZE_DOUBLE ? V2SImode : V4SImode;
- case HImode:
- return TARGET_NEON_VECTORIZE_DOUBLE ? V4HImode : V8HImode;
- case QImode:
- return TARGET_NEON_VECTORIZE_DOUBLE ? V8QImode : V16QImode;
- case DImode:
- if (!TARGET_NEON_VECTORIZE_DOUBLE)
- return V2DImode;
- break;
-
- default:;
- }
-
- if (TARGET_REALLY_IWMMXT)
- switch (mode)
- {
- case SImode:
- return V2SImode;
- case HImode:
- return V4HImode;
- case QImode:
- return V8QImode;
-
- default:;
- }
-
- return word_mode;
-}
-
-/* Implement TARGET_CLASS_LIKELY_SPILLED_P.
-
- 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. */
-static bool
-arm_class_likely_spilled_p (reg_class_t rclass)
-{
- if ((TARGET_THUMB1 && rclass == LO_REGS)
- || rclass == CC_REG)
- return true;
-
- return false;
-}
-
-/* Implements target hook small_register_classes_for_mode_p. */
-bool
-arm_small_register_classes_for_mode_p (enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- return TARGET_THUMB1;
-}
-
-/* Implement TARGET_SHIFT_TRUNCATION_MASK. SImode shifts use normal
- ARM insns and therefore guarantee that the shift count is modulo 256.
- DImode shifts (those implemented by lib1funcs.S or by optabs.c)
- guarantee no particular behavior for out-of-range counts. */
-
-static unsigned HOST_WIDE_INT
-arm_shift_truncation_mask (enum machine_mode mode)
-{
- return mode == SImode ? 255 : 0;
-}
-
-
-/* Map internal gcc register numbers to DWARF2 register numbers. */
-
-unsigned int
-arm_dbx_register_number (unsigned int regno)
-{
- if (regno < 16)
- return regno;
-
- if (IS_VFP_REGNUM (regno))
- {
- /* 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;
-
- if (IS_IWMMXT_REGNUM (regno))
- return 112 + regno - FIRST_IWMMXT_REGNUM;
-
- 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;
-
- /* XXX FIXME: The EABI defines two VFP register ranges:
- 64-95: Legacy VFPv2 numbering for S0-S31 (obsolescent)
- 256-287: D0-D31
- The recommended encoding for S0-S31 is a DW_OP_bit_piece of the
- corresponding D register. Until GDB supports this, we shall 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;
-}
-
-#if ARM_UNWIND_INFO
-/* Emit unwind directives for a store-multiple instruction or stack pointer
- push during alignment.
- These should only ever be generated by the function prologue code, so
- expect them to have a particular form. */
-
-static void
-arm_unwind_emit_sequence (FILE * asm_out_file, rtx p)
-{
- int i;
- HOST_WIDE_INT offset;
- HOST_WIDE_INT nregs;
- int reg_size;
- unsigned reg;
- unsigned lastreg;
- rtx e;
-
- e = XVECEXP (p, 0, 0);
- if (GET_CODE (e) != SET)
- abort ();
-
- /* First insn will adjust the stack pointer. */
- if (GET_CODE (e) != SET
- || !REG_P (XEXP (e, 0))
- || REGNO (XEXP (e, 0)) != SP_REGNUM
- || GET_CODE (XEXP (e, 1)) != PLUS)
- abort ();
-
- offset = -INTVAL (XEXP (XEXP (e, 1), 1));
- nregs = XVECLEN (p, 0) - 1;
-
- reg = REGNO (XEXP (XVECEXP (p, 0, 1), 1));
- if (reg < 16)
- {
- /* The function prologue may also push pc, but not annotate it as it is
- never restored. We turn this into a stack pointer adjustment. */
- if (nregs * 4 == offset - 4)
- {
- fprintf (asm_out_file, "\t.pad #4\n");
- offset -= 4;
- }
- reg_size = 4;
- fprintf (asm_out_file, "\t.save {");
- }
- else if (IS_VFP_REGNUM (reg))
- {
- reg_size = 8;
- fprintf (asm_out_file, "\t.vsave {");
- }
- else
- /* Unknown register type. */
- abort ();
-
- /* If the stack increment doesn't match the size of the saved registers,
- something has gone horribly wrong. */
- if (offset != nregs * reg_size)
- abort ();
-
- offset = 0;
- lastreg = 0;
- /* The remaining insns will describe the stores. */
- for (i = 1; i <= nregs; i++)
- {
- /* Expect (set (mem <addr>) (reg)).
- Where <addr> is (reg:SP) or (plus (reg:SP) (const_int)). */
- e = XVECEXP (p, 0, i);
- if (GET_CODE (e) != SET
- || !MEM_P (XEXP (e, 0))
- || !REG_P (XEXP (e, 1)))
- abort ();
-
- reg = REGNO (XEXP (e, 1));
- if (reg < lastreg)
- abort ();
-
- if (i != 1)
- fprintf (asm_out_file, ", ");
- /* We can't use %r for vfp because we need to use the
- double precision register names. */
- if (IS_VFP_REGNUM (reg))
- asm_fprintf (asm_out_file, "d%d", (reg - FIRST_VFP_REGNUM) / 2);
- else
- asm_fprintf (asm_out_file, "%r", reg);
-
-#ifdef ENABLE_CHECKING
- /* Check that the addresses are consecutive. */
- e = XEXP (XEXP (e, 0), 0);
- if (GET_CODE (e) == PLUS)
- {
- offset += reg_size;
- if (!REG_P (XEXP (e, 0))
- || REGNO (XEXP (e, 0)) != SP_REGNUM
- || !CONST_INT_P (XEXP (e, 1))
- || offset != INTVAL (XEXP (e, 1)))
- abort ();
- }
- else if (i != 1
- || !REG_P (e)
- || REGNO (e) != SP_REGNUM)
- abort ();
-#endif
- }
- fprintf (asm_out_file, "}\n");
-}
-
-/* Emit unwind directives for a SET. */
-
-static void
-arm_unwind_emit_set (FILE * asm_out_file, rtx p)
-{
- rtx e0;
- rtx e1;
- unsigned reg;
-
- e0 = XEXP (p, 0);
- e1 = XEXP (p, 1);
- switch (GET_CODE (e0))
- {
- case MEM:
- /* Pushing a single register. */
- if (GET_CODE (XEXP (e0, 0)) != PRE_DEC
- || !REG_P (XEXP (XEXP (e0, 0), 0))
- || REGNO (XEXP (XEXP (e0, 0), 0)) != SP_REGNUM)
- abort ();
-
- asm_fprintf (asm_out_file, "\t.save ");
- if (IS_VFP_REGNUM (REGNO (e1)))
- asm_fprintf(asm_out_file, "{d%d}\n",
- (REGNO (e1) - FIRST_VFP_REGNUM) / 2);
- else
- asm_fprintf(asm_out_file, "{%r}\n", REGNO (e1));
- break;
-
- case REG:
- if (REGNO (e0) == SP_REGNUM)
- {
- /* A stack increment. */
- if (GET_CODE (e1) != PLUS
- || !REG_P (XEXP (e1, 0))
- || REGNO (XEXP (e1, 0)) != SP_REGNUM
- || !CONST_INT_P (XEXP (e1, 1)))
- abort ();
-
- asm_fprintf (asm_out_file, "\t.pad #%wd\n",
- -INTVAL (XEXP (e1, 1)));
- }
- else if (REGNO (e0) == HARD_FRAME_POINTER_REGNUM)
- {
- HOST_WIDE_INT offset;
-
- if (GET_CODE (e1) == PLUS)
- {
- if (!REG_P (XEXP (e1, 0))
- || !CONST_INT_P (XEXP (e1, 1)))
- abort ();
- reg = REGNO (XEXP (e1, 0));
- offset = INTVAL (XEXP (e1, 1));
- asm_fprintf (asm_out_file, "\t.setfp %r, %r, #%wd\n",
- HARD_FRAME_POINTER_REGNUM, reg,
- offset);
- }
- else if (REG_P (e1))
- {
- reg = REGNO (e1);
- asm_fprintf (asm_out_file, "\t.setfp %r, %r\n",
- HARD_FRAME_POINTER_REGNUM, reg);
- }
- else
- abort ();
- }
- else if (REG_P (e1) && REGNO (e1) == SP_REGNUM)
- {
- /* Move from sp to reg. */
- asm_fprintf (asm_out_file, "\t.movsp %r\n", REGNO (e0));
- }
- else if (GET_CODE (e1) == PLUS
- && REG_P (XEXP (e1, 0))
- && REGNO (XEXP (e1, 0)) == SP_REGNUM
- && CONST_INT_P (XEXP (e1, 1)))
- {
- /* Set reg to offset from sp. */
- asm_fprintf (asm_out_file, "\t.movsp %r, #%d\n",
- REGNO (e0), (int)INTVAL(XEXP (e1, 1)));
- }
- else
- abort ();
- break;
-
- default:
- abort ();
- }
-}
-
-
-/* Emit unwind directives for the given insn. */
-
-static void
-arm_unwind_emit (FILE * asm_out_file, rtx insn)
-{
- rtx note, pat;
- bool handled_one = false;
-
- if (arm_except_unwind_info (&global_options) != UI_TARGET)
- return;
-
- if (!(flag_unwind_tables || crtl->uses_eh_lsda)
- && (TREE_NOTHROW (current_function_decl)
- || crtl->all_throwers_are_sibcalls))
- return;
-
- if (NOTE_P (insn) || !RTX_FRAME_RELATED_P (insn))
- return;
-
- for (note = REG_NOTES (insn); note ; note = XEXP (note, 1))
- {
- pat = XEXP (note, 0);
- switch (REG_NOTE_KIND (note))
- {
- case REG_FRAME_RELATED_EXPR:
- goto found;
-
- case REG_CFA_REGISTER:
- if (pat == NULL)
- {
- pat = PATTERN (insn);
- if (GET_CODE (pat) == PARALLEL)
- pat = XVECEXP (pat, 0, 0);
- }
-
- /* Only emitted for IS_STACKALIGN re-alignment. */
- {
- rtx dest, src;
- unsigned reg;
-
- src = SET_SRC (pat);
- dest = SET_DEST (pat);
-
- gcc_assert (src == stack_pointer_rtx);
- reg = REGNO (dest);
- asm_fprintf (asm_out_file, "\t.unwind_raw 0, 0x%x @ vsp = r%d\n",
- reg + 0x90, reg);
- }
- handled_one = true;
- break;
-
- case REG_CFA_DEF_CFA:
- case REG_CFA_EXPRESSION:
- case REG_CFA_ADJUST_CFA:
- case REG_CFA_OFFSET:
- /* ??? Only handling here what we actually emit. */
- gcc_unreachable ();
-
- default:
- break;
- }
- }
- if (handled_one)
- return;
- pat = PATTERN (insn);
- found:
-
- switch (GET_CODE (pat))
- {
- case SET:
- arm_unwind_emit_set (asm_out_file, pat);
- break;
-
- case SEQUENCE:
- /* Store multiple. */
- arm_unwind_emit_sequence (asm_out_file, pat);
- break;
-
- default:
- abort();
- }
-}
-
-
-/* Output a reference from a function exception table to the type_info
- object X. The EABI specifies that the symbol should be relocated by
- an R_ARM_TARGET2 relocation. */
-
-static bool
-arm_output_ttype (rtx x)
-{
- fputs ("\t.word\t", asm_out_file);
- output_addr_const (asm_out_file, x);
- /* Use special relocations for symbol references. */
- if (!CONST_INT_P (x))
- fputs ("(TARGET2)", asm_out_file);
- fputc ('\n', asm_out_file);
-
- return TRUE;
-}
-
-/* Implement TARGET_ASM_EMIT_EXCEPT_PERSONALITY. */
-
-static void
-arm_asm_emit_except_personality (rtx personality)
-{
- fputs ("\t.personality\t", asm_out_file);
- output_addr_const (asm_out_file, personality);
- fputc ('\n', asm_out_file);
-}
-
-/* Implement TARGET_ASM_INITIALIZE_SECTIONS. */
-
-static void
-arm_asm_init_sections (void)
-{
- exception_section = get_unnamed_section (0, output_section_asm_op,
- "\t.handlerdata");
-}
-#endif /* ARM_UNWIND_INFO */
-
-/* Output unwind directives for the start/end of a function. */
-
-void
-arm_output_fn_unwind (FILE * f, bool prologue)
-{
- if (arm_except_unwind_info (&global_options) != UI_TARGET)
- return;
-
- if (prologue)
- fputs ("\t.fnstart\n", f);
- else
- {
- /* 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 || crtl->uses_eh_lsda)
- && (TREE_NOTHROW (current_function_decl)
- || crtl->all_throwers_are_sibcalls))
- fputs("\t.cantunwind\n", f);
-
- fputs ("\t.fnend\n", f);
- }
-}
-
-static bool
-arm_emit_tls_decoration (FILE *fp, rtx x)
-{
- enum tls_reloc reloc;
- rtx val;
-
- val = XVECEXP (x, 0, 0);
- reloc = (enum tls_reloc) INTVAL (XVECEXP (x, 0, 1));
-
- output_addr_const (fp, val);
-
- switch (reloc)
- {
- case TLS_GD32:
- fputs ("(tlsgd)", fp);
- break;
- case TLS_LDM32:
- fputs ("(tlsldm)", fp);
- break;
- case TLS_LDO32:
- fputs ("(tlsldo)", fp);
- break;
- case TLS_IE32:
- fputs ("(gottpoff)", fp);
- break;
- case TLS_LE32:
- fputs ("(tpoff)", fp);
- break;
- case TLS_DESCSEQ:
- fputs ("(tlsdesc)", fp);
- break;
- default:
- gcc_unreachable ();
- }
-
- switch (reloc)
- {
- case TLS_GD32:
- case TLS_LDM32:
- case TLS_IE32:
- case TLS_DESCSEQ:
- fputs (" + (. - ", fp);
- output_addr_const (fp, XVECEXP (x, 0, 2));
- /* For DESCSEQ the 3rd operand encodes thumbness, and is added */
- fputs (reloc == TLS_DESCSEQ ? " + " : " - ", fp);
- output_addr_const (fp, XVECEXP (x, 0, 3));
- fputc (')', fp);
- break;
- default:
- break;
- }
-
- return TRUE;
-}
-
-/* ARM implementation of TARGET_ASM_OUTPUT_DWARF_DTPREL. */
-
-static void
-arm_output_dwarf_dtprel (FILE *file, int size, rtx x)
-{
- gcc_assert (size == 4);
- fputs ("\t.word\t", file);
- output_addr_const (file, x);
- fputs ("(tlsldo)", file);
-}
-
-/* Implement TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */
-
-static bool
-arm_output_addr_const_extra (FILE *fp, rtx x)
-{
- if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLS)
- return arm_emit_tls_decoration (fp, x);
- else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_PIC_LABEL)
- {
- char label[256];
- int labelno = INTVAL (XVECEXP (x, 0, 0));
-
- ASM_GENERATE_INTERNAL_LABEL (label, "LPIC", labelno);
- assemble_name_raw (fp, label);
-
- return TRUE;
- }
- else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_GOTSYM_OFF)
- {
- assemble_name (fp, "_GLOBAL_OFFSET_TABLE_");
- if (GOT_PCREL)
- fputs ("+.", fp);
- fputs ("-(", fp);
- output_addr_const (fp, XVECEXP (x, 0, 0));
- fputc (')', fp);
- return TRUE;
- }
- else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_SYMBOL_OFFSET)
- {
- output_addr_const (fp, XVECEXP (x, 0, 0));
- if (GOT_PCREL)
- fputs ("+.", fp);
- fputs ("-(", fp);
- output_addr_const (fp, XVECEXP (x, 0, 1));
- fputc (')', fp);
- return TRUE;
- }
- else if (GET_CODE (x) == CONST_VECTOR)
- return arm_emit_vector_const (fp, x);
-
- return FALSE;
-}
-
-/* Output assembly for a shift instruction.
- SET_FLAGS determines how the instruction modifies the condition codes.
- 0 - Do not set condition codes.
- 1 - Set condition codes.
- 2 - Use smallest instruction. */
-const char *
-arm_output_shift(rtx * operands, int set_flags)
-{
- char pattern[100];
- static const char flag_chars[3] = {'?', '.', '!'};
- const char *shift;
- HOST_WIDE_INT val;
- char c;
-
- c = flag_chars[set_flags];
- if (TARGET_UNIFIED_ASM)
- {
- shift = shift_op(operands[3], &val);
- if (shift)
- {
- if (val != -1)
- operands[2] = GEN_INT(val);
- sprintf (pattern, "%s%%%c\t%%0, %%1, %%2", shift, c);
- }
- else
- sprintf (pattern, "mov%%%c\t%%0, %%1", c);
- }
- else
- sprintf (pattern, "mov%%%c\t%%0, %%1%%S3", c);
- output_asm_insn (pattern, operands);
- return "";
-}
-
-/* Output assembly for a WMMX immediate shift instruction. */
-const char *
-arm_output_iwmmxt_shift_immediate (const char *insn_name, rtx *operands, bool wror_or_wsra)
-{
- int shift = INTVAL (operands[2]);
- char templ[50];
- enum machine_mode opmode = GET_MODE (operands[0]);
-
- gcc_assert (shift >= 0);
-
- /* If the shift value in the register versions is > 63 (for D qualifier),
- 31 (for W qualifier) or 15 (for H qualifier). */
- if (((opmode == V4HImode) && (shift > 15))
- || ((opmode == V2SImode) && (shift > 31))
- || ((opmode == DImode) && (shift > 63)))
- {
- if (wror_or_wsra)
- {
- sprintf (templ, "%s\t%%0, %%1, #%d", insn_name, 32);
- output_asm_insn (templ, operands);
- if (opmode == DImode)
- {
- sprintf (templ, "%s\t%%0, %%0, #%d", insn_name, 32);
- output_asm_insn (templ, operands);
- }
- }
- else
- {
- /* The destination register will contain all zeros. */
- sprintf (templ, "wzero\t%%0");
- output_asm_insn (templ, operands);
- }
- return "";
- }
-
- if ((opmode == DImode) && (shift > 32))
- {
- sprintf (templ, "%s\t%%0, %%1, #%d", insn_name, 32);
- output_asm_insn (templ, operands);
- sprintf (templ, "%s\t%%0, %%0, #%d", insn_name, shift - 32);
- output_asm_insn (templ, operands);
- }
- else
- {
- sprintf (templ, "%s\t%%0, %%1, #%d", insn_name, shift);
- output_asm_insn (templ, operands);
- }
- return "";
-}
-
-/* Output assembly for a WMMX tinsr instruction. */
-const char *
-arm_output_iwmmxt_tinsr (rtx *operands)
-{
- int mask = INTVAL (operands[3]);
- int i;
- char templ[50];
- int units = mode_nunits[GET_MODE (operands[0])];
- gcc_assert ((mask & (mask - 1)) == 0);
- for (i = 0; i < units; ++i)
- {
- if ((mask & 0x01) == 1)
- {
- break;
- }
- mask >>= 1;
- }
- gcc_assert (i < units);
- {
- switch (GET_MODE (operands[0]))
- {
- case V8QImode:
- sprintf (templ, "tinsrb%%?\t%%0, %%2, #%d", i);
- break;
- case V4HImode:
- sprintf (templ, "tinsrh%%?\t%%0, %%2, #%d", i);
- break;
- case V2SImode:
- sprintf (templ, "tinsrw%%?\t%%0, %%2, #%d", i);
- break;
- default:
- gcc_unreachable ();
- break;
- }
- output_asm_insn (templ, operands);
- }
- return "";
-}
-
-/* Output a Thumb-1 casesi dispatch sequence. */
-const char *
-thumb1_output_casesi (rtx *operands)
-{
- rtx diff_vec = PATTERN (next_real_insn (operands[0]));
-
- gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
-
- switch (GET_MODE(diff_vec))
- {
- case QImode:
- return (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned ?
- "bl\t%___gnu_thumb1_case_uqi" : "bl\t%___gnu_thumb1_case_sqi");
- case HImode:
- return (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned ?
- "bl\t%___gnu_thumb1_case_uhi" : "bl\t%___gnu_thumb1_case_shi");
- case SImode:
- return "bl\t%___gnu_thumb1_case_si";
- default:
- gcc_unreachable ();
- }
-}
-
-/* Output a Thumb-2 casesi instruction. */
-const char *
-thumb2_output_casesi (rtx *operands)
-{
- rtx diff_vec = PATTERN (next_real_insn (operands[2]));
-
- gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
-
- output_asm_insn ("cmp\t%0, %1", operands);
- output_asm_insn ("bhi\t%l3", operands);
- switch (GET_MODE(diff_vec))
- {
- case QImode:
- return "tbb\t[%|pc, %0]";
- case HImode:
- return "tbh\t[%|pc, %0, lsl #1]";
- case SImode:
- if (flag_pic)
- {
- output_asm_insn ("adr\t%4, %l2", operands);
- output_asm_insn ("ldr\t%5, [%4, %0, lsl #2]", operands);
- output_asm_insn ("add\t%4, %4, %5", operands);
- return "bx\t%4";
- }
- else
- {
- output_asm_insn ("adr\t%4, %l2", operands);
- return "ldr\t%|pc, [%4, %0, lsl #2]";
- }
- default:
- gcc_unreachable ();
- }
-}
-
-/* Most ARM cores are single issue, but some newer ones can dual issue.
- The scheduler descriptions rely on this being correct. */
-static int
-arm_issue_rate (void)
-{
- switch (arm_tune)
- {
- case cortexa15:
- return 3;
-
- case cortexr4:
- case cortexr4f:
- case cortexr5:
- case genericv7a:
- case cortexa5:
- case cortexa7:
- case cortexa8:
- case cortexa9:
- case fa726te:
- case marvell_pj4:
- return 2;
-
- default:
- return 1;
- }
-}
-
-/* A table and a function to perform ARM-specific name mangling for
- NEON vector types in order to conform to the AAPCS (see "Procedure
- Call Standard for the ARM Architecture", Appendix A). To qualify
- for emission with the mangled names defined in that document, a
- vector type must not only be of the correct mode but also be
- composed of NEON vector element types (e.g. __builtin_neon_qi). */
-typedef struct
-{
- enum machine_mode mode;
- const char *element_type_name;
- const char *aapcs_name;
-} arm_mangle_map_entry;
-
-static arm_mangle_map_entry arm_mangle_map[] = {
- /* 64-bit containerized types. */
- { V8QImode, "__builtin_neon_qi", "15__simd64_int8_t" },
- { V8QImode, "__builtin_neon_uqi", "16__simd64_uint8_t" },
- { V4HImode, "__builtin_neon_hi", "16__simd64_int16_t" },
- { V4HImode, "__builtin_neon_uhi", "17__simd64_uint16_t" },
- { V2SImode, "__builtin_neon_si", "16__simd64_int32_t" },
- { V2SImode, "__builtin_neon_usi", "17__simd64_uint32_t" },
- { V2SFmode, "__builtin_neon_sf", "18__simd64_float32_t" },
- { V8QImode, "__builtin_neon_poly8", "16__simd64_poly8_t" },
- { V4HImode, "__builtin_neon_poly16", "17__simd64_poly16_t" },
- /* 128-bit containerized types. */
- { V16QImode, "__builtin_neon_qi", "16__simd128_int8_t" },
- { V16QImode, "__builtin_neon_uqi", "17__simd128_uint8_t" },
- { V8HImode, "__builtin_neon_hi", "17__simd128_int16_t" },
- { V8HImode, "__builtin_neon_uhi", "18__simd128_uint16_t" },
- { V4SImode, "__builtin_neon_si", "17__simd128_int32_t" },
- { V4SImode, "__builtin_neon_usi", "18__simd128_uint32_t" },
- { V4SFmode, "__builtin_neon_sf", "19__simd128_float32_t" },
- { V16QImode, "__builtin_neon_poly8", "17__simd128_poly8_t" },
- { V8HImode, "__builtin_neon_poly16", "18__simd128_poly16_t" },
- { VOIDmode, NULL, NULL }
-};
-
-const char *
-arm_mangle_type (const_tree type)
-{
- arm_mangle_map_entry *pos = arm_mangle_map;
-
- /* The ARM ABI documents (10th October 2008) say that "__va_list"
- has to be managled as if it is in the "std" namespace. */
- if (TARGET_AAPCS_BASED
- && lang_hooks.types_compatible_p (CONST_CAST_TREE (type), va_list_type))
- {
- /* Disable this obsolete warning for Android, because none of the exposed APIs
- by NDK is impacted by this change of ARM ABI. This warning can be triggered
- very easily by compiling the following code using arm-linux-androideabi-g++:
-
- typedef __builtin_va_list __gnuc_va_list;
- typedef __gnuc_va_list va_list;
- void foo(va_list v) { }
-
- We could advise developer to add "-Wno-psabi", but doing so also categorically
- deny other cases guarded by "warn_psabi". Hence the decision to disable it
- case by case here.
-
- static bool warned;
- if (!warned && warn_psabi && !in_system_header)
- {
- warned = true;
- inform (input_location,
- "the mangling of %<va_list%> has changed in GCC 4.4");
- }
- */
- 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;
-
- /* Check the mode of the vector type, and the name of the vector
- element type, against the table. */
- while (pos->mode != VOIDmode)
- {
- tree elt_type = TREE_TYPE (type);
-
- if (pos->mode == TYPE_MODE (type)
- && TREE_CODE (TYPE_NAME (elt_type)) == TYPE_DECL
- && !strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (elt_type))),
- pos->element_type_name))
- return pos->aapcs_name;
-
- pos++;
- }
-
- /* Use the default mangling for unrecognized (possibly user-defined)
- vector types. */
- return NULL;
-}
-
-/* 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
-};
-
-/* Adjust register allocation order when compiling for Thumb. */
-
-void
-arm_order_regs_for_local_alloc (void)
-{
- const int arm_reg_alloc_order[] = REG_ALLOC_ORDER;
- memcpy(reg_alloc_order, arm_reg_alloc_order, sizeof (reg_alloc_order));
- if (TARGET_THUMB)
- memcpy (reg_alloc_order, thumb_core_reg_alloc_order,
- sizeof (thumb_core_reg_alloc_order));
-}
-
-/* Implement TARGET_FRAME_POINTER_REQUIRED. */
-
-bool
-arm_frame_pointer_required (void)
-{
- return (cfun->has_nonlocal_label
- || SUBTARGET_FRAME_POINTER_REQUIRED
- || (TARGET_ARM && TARGET_APCS_FRAME && ! leaf_function_p ()));
-}
-
-/* Only thumb1 can't support conditional execution, so return true if
- the target is not thumb1. */
-static bool
-arm_have_conditional_execution (void)
-{
- return !TARGET_THUMB1;
-}
-
-/* The AAPCS sets the maximum alignment of a vector to 64 bits. */
-static HOST_WIDE_INT
-arm_vector_alignment (const_tree type)
-{
- HOST_WIDE_INT align = tree_low_cst (TYPE_SIZE (type), 0);
-
- if (TARGET_AAPCS_BASED)
- align = MIN (align, 64);
-
- return align;
-}
-
-static unsigned int
-arm_autovectorize_vector_sizes (void)
-{
- return TARGET_NEON_VECTORIZE_DOUBLE ? 0 : (16 | 8);
-}
-
-static bool
-arm_vector_alignment_reachable (const_tree type, bool is_packed)
-{
- /* Vectors which aren't in packed structures will not be less aligned than
- the natural alignment of their element type, so this is safe. */
- if (TARGET_NEON && !BYTES_BIG_ENDIAN)
- return !is_packed;
-
- return default_builtin_vector_alignment_reachable (type, is_packed);
-}
-
-static bool
-arm_builtin_support_vector_misalignment (enum machine_mode mode,
- const_tree type, int misalignment,
- bool is_packed)
-{
- if (TARGET_NEON && !BYTES_BIG_ENDIAN)
- {
- HOST_WIDE_INT align = TYPE_ALIGN_UNIT (type);
-
- if (is_packed)
- return align == 1;
-
- /* If the misalignment is unknown, we should be able to handle the access
- so long as it is not to a member of a packed data structure. */
- if (misalignment == -1)
- return true;
-
- /* Return true if the misalignment is a multiple of the natural alignment
- of the vector's element type. This is probably always going to be
- true in practice, since we've already established that this isn't a
- packed access. */
- return ((misalignment % align) == 0);
- }
-
- return default_builtin_support_vector_misalignment (mode, type, misalignment,
- is_packed);
-}
-
-static void
-arm_conditional_register_usage (void)
-{
- int regno;
-
- 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;
- }
-
- /* The link register can be clobbered by any branch insn,
- but we have no way to track that at present, so mark
- it as unavailable. */
- if (TARGET_THUMB1)
- fixed_regs[LR_REGNUM] = call_used_regs[LR_REGNUM] = 1;
-
- if (TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP)
- {
- /* VFPv3 registers are disabled when earlier VFP
- versions are selected due to the definition of
- LAST_VFP_REGNUM. */
- for (regno = FIRST_VFP_REGNUM;
- regno <= LAST_VFP_REGNUM; ++ regno)
- {
- fixed_regs[regno] = 0;
- call_used_regs[regno] = regno < FIRST_VFP_REGNUM + 16
- || regno >= FIRST_VFP_REGNUM + 32;
- }
- }
-
- if (TARGET_REALLY_IWMMXT)
- {
- regno = FIRST_IWMMXT_GR_REGNUM;
- /* The 2002/10/09 revision of the XScale ABI has wCG0
- and wCG1 as call-preserved registers. The 2002/11/21
- revision changed this so that all wCG registers are
- scratch registers. */
- for (regno = FIRST_IWMMXT_GR_REGNUM;
- regno <= LAST_IWMMXT_GR_REGNUM; ++ regno)
- fixed_regs[regno] = 0;
- /* The XScale ABI has wR0 - wR9 as scratch registers,
- the rest as call-preserved registers. */
- for (regno = FIRST_IWMMXT_REGNUM;
- regno <= LAST_IWMMXT_REGNUM; ++ regno)
- {
- fixed_regs[regno] = 0;
- call_used_regs[regno] = regno < FIRST_IWMMXT_REGNUM + 10;
- }
- }
-
- if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
- {
- fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
- call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
- }
- else if (TARGET_APCS_STACK)
- {
- fixed_regs[10] = 1;
- call_used_regs[10] = 1;
- }
- /* -mcaller-super-interworking reserves r11 for calls to
- _interwork_r11_call_via_rN(). Making the register global
- is an easy way of ensuring that it remains valid for all
- calls. */
- if (TARGET_APCS_FRAME || TARGET_CALLER_INTERWORKING
- || TARGET_TPCS_FRAME || TARGET_TPCS_LEAF_FRAME)
- {
- fixed_regs[ARM_HARD_FRAME_POINTER_REGNUM] = 1;
- call_used_regs[ARM_HARD_FRAME_POINTER_REGNUM] = 1;
- if (TARGET_CALLER_INTERWORKING)
- global_regs[ARM_HARD_FRAME_POINTER_REGNUM] = 1;
- }
- SUBTARGET_CONDITIONAL_REGISTER_USAGE
-}
-
-static reg_class_t
-arm_preferred_rename_class (reg_class_t rclass)
-{
- /* Thumb-2 instructions using LO_REGS may be smaller than instructions
- using GENERIC_REGS. During register rename pass, we prefer LO_REGS,
- and code size can be reduced. */
- if (TARGET_THUMB2 && rclass == GENERAL_REGS)
- return LO_REGS;
- else
- return NO_REGS;
-}
-
-/* Compute the atrribute "length" of insn "*push_multi".
- So this function MUST be kept in sync with that insn pattern. */
-int
-arm_attr_length_push_multi(rtx parallel_op, rtx first_op)
-{
- int i, regno, hi_reg;
- int num_saves = XVECLEN (parallel_op, 0);
-
- /* ARM mode. */
- if (TARGET_ARM)
- return 4;
- /* Thumb1 mode. */
- if (TARGET_THUMB1)
- return 2;
-
- /* Thumb2 mode. */
- regno = REGNO (first_op);
- hi_reg = (REGNO_REG_CLASS (regno) == HI_REGS) && (regno != LR_REGNUM);
- for (i = 1; i < num_saves && !hi_reg; i++)
- {
- regno = REGNO (XEXP (XVECEXP (parallel_op, 0, i), 0));
- hi_reg |= (REGNO_REG_CLASS (regno) == HI_REGS) && (regno != LR_REGNUM);
- }
-
- if (!hi_reg)
- return 2;
- return 4;
-}
-
-/* Compute the number of instructions emitted by output_move_double. */
-int
-arm_count_output_move_double_insns (rtx *operands)
-{
- int count;
- rtx ops[2];
- /* output_move_double may modify the operands array, so call it
- here on a copy of the array. */
- ops[0] = operands[0];
- ops[1] = operands[1];
- output_move_double (ops, false, &count);
- return count;
-}
-
-int
-vfp3_const_double_for_fract_bits (rtx operand)
-{
- REAL_VALUE_TYPE r0;
-
- if (!CONST_DOUBLE_P (operand))
- return 0;
-
- REAL_VALUE_FROM_CONST_DOUBLE (r0, operand);
- if (exact_real_inverse (DFmode, &r0))
- {
- if (exact_real_truncate (DFmode, &r0))
- {
- HOST_WIDE_INT value = real_to_integer (&r0);
- value = value & 0xffffffff;
- if ((value != 0) && ( (value & (value - 1)) == 0))
- return int_log2 (value);
- }
- }
- return 0;
-}
-
-/* Emit a memory barrier around an atomic sequence according to MODEL. */
-
-static void
-arm_pre_atomic_barrier (enum memmodel model)
-{
- if (need_atomic_barrier_p (model, true))
- emit_insn (gen_memory_barrier ());
-}
-
-static void
-arm_post_atomic_barrier (enum memmodel model)
-{
- if (need_atomic_barrier_p (model, false))
- emit_insn (gen_memory_barrier ());
-}
-
-/* Emit the load-exclusive and store-exclusive instructions. */
-
-static void
-arm_emit_load_exclusive (enum machine_mode mode, rtx rval, rtx mem)
-{
- rtx (*gen) (rtx, rtx);
-
- switch (mode)
- {
- case QImode: gen = gen_arm_load_exclusiveqi; break;
- case HImode: gen = gen_arm_load_exclusivehi; break;
- case SImode: gen = gen_arm_load_exclusivesi; break;
- case DImode: gen = gen_arm_load_exclusivedi; break;
- default:
- gcc_unreachable ();
- }
-
- emit_insn (gen (rval, mem));
-}
-
-static void
-arm_emit_store_exclusive (enum machine_mode mode, rtx bval, rtx rval, rtx mem)
-{
- rtx (*gen) (rtx, rtx, rtx);
-
- switch (mode)
- {
- case QImode: gen = gen_arm_store_exclusiveqi; break;
- case HImode: gen = gen_arm_store_exclusivehi; break;
- case SImode: gen = gen_arm_store_exclusivesi; break;
- case DImode: gen = gen_arm_store_exclusivedi; break;
- default:
- gcc_unreachable ();
- }
-
- emit_insn (gen (bval, rval, mem));
-}
-
-/* Mark the previous jump instruction as unlikely. */
-
-static void
-emit_unlikely_jump (rtx insn)
-{
- rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
-
- insn = emit_jump_insn (insn);
- add_reg_note (insn, REG_BR_PROB, very_unlikely);
-}
-
-/* Expand a compare and swap pattern. */
-
-void
-arm_expand_compare_and_swap (rtx operands[])
-{
- rtx bval, rval, mem, oldval, newval, is_weak, mod_s, mod_f, x;
- enum machine_mode mode;
- rtx (*gen) (rtx, rtx, rtx, rtx, rtx, rtx, rtx);
-
- bval = operands[0];
- rval = operands[1];
- mem = operands[2];
- oldval = operands[3];
- newval = operands[4];
- is_weak = operands[5];
- mod_s = operands[6];
- mod_f = operands[7];
- mode = GET_MODE (mem);
-
- switch (mode)
- {
- case QImode:
- case HImode:
- /* For narrow modes, we're going to perform the comparison in SImode,
- so do the zero-extension now. */
- rval = gen_reg_rtx (SImode);
- oldval = convert_modes (SImode, mode, oldval, true);
- /* FALLTHRU */
-
- case SImode:
- /* Force the value into a register if needed. We waited until after
- the zero-extension above to do this properly. */
- if (!arm_add_operand (oldval, SImode))
- oldval = force_reg (SImode, oldval);
- break;
-
- case DImode:
- if (!cmpdi_operand (oldval, mode))
- oldval = force_reg (mode, oldval);
- break;
-
- default:
- gcc_unreachable ();
- }
-
- switch (mode)
- {
- case QImode: gen = gen_atomic_compare_and_swapqi_1; break;
- case HImode: gen = gen_atomic_compare_and_swaphi_1; break;
- case SImode: gen = gen_atomic_compare_and_swapsi_1; break;
- case DImode: gen = gen_atomic_compare_and_swapdi_1; break;
- default:
- gcc_unreachable ();
- }
-
- emit_insn (gen (rval, mem, oldval, newval, is_weak, mod_s, mod_f));
-
- if (mode == QImode || mode == HImode)
- emit_move_insn (operands[1], gen_lowpart (mode, rval));
-
- /* In all cases, we arrange for success to be signaled by Z set.
- This arrangement allows for the boolean result to be used directly
- in a subsequent branch, post optimization. */
- x = gen_rtx_REG (CCmode, CC_REGNUM);
- x = gen_rtx_EQ (SImode, x, const0_rtx);
- emit_insn (gen_rtx_SET (VOIDmode, bval, x));
-}
-
-/* Split a compare and swap pattern. It is IMPLEMENTATION DEFINED whether
- another memory store between the load-exclusive and store-exclusive can
- reset the monitor from Exclusive to Open state. This means we must wait
- until after reload to split the pattern, lest we get a register spill in
- the middle of the atomic sequence. */
-
-void
-arm_split_compare_and_swap (rtx operands[])
-{
- rtx rval, mem, oldval, newval, scratch;
- enum machine_mode mode;
- enum memmodel mod_s, mod_f;
- bool is_weak;
- rtx label1, label2, x, cond;
-
- rval = operands[0];
- mem = operands[1];
- oldval = operands[2];
- newval = operands[3];
- is_weak = (operands[4] != const0_rtx);
- mod_s = (enum memmodel) INTVAL (operands[5]);
- mod_f = (enum memmodel) INTVAL (operands[6]);
- scratch = operands[7];
- mode = GET_MODE (mem);
-
- arm_pre_atomic_barrier (mod_s);
-
- label1 = NULL_RTX;
- if (!is_weak)
- {
- label1 = gen_label_rtx ();
- emit_label (label1);
- }
- label2 = gen_label_rtx ();
-
- arm_emit_load_exclusive (mode, rval, mem);
-
- cond = arm_gen_compare_reg (NE, rval, oldval, scratch);
- x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
- x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
- gen_rtx_LABEL_REF (Pmode, label2), pc_rtx);
- emit_unlikely_jump (gen_rtx_SET (VOIDmode, pc_rtx, x));
-
- arm_emit_store_exclusive (mode, scratch, mem, newval);
-
- /* Weak or strong, we want EQ to be true for success, so that we
- match the flags that we got from the compare above. */
- cond = gen_rtx_REG (CCmode, CC_REGNUM);
- x = gen_rtx_COMPARE (CCmode, scratch, const0_rtx);
- emit_insn (gen_rtx_SET (VOIDmode, cond, x));
-
- if (!is_weak)
- {
- x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
- x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
- gen_rtx_LABEL_REF (Pmode, label1), pc_rtx);
- emit_unlikely_jump (gen_rtx_SET (VOIDmode, pc_rtx, x));
- }
-
- if (mod_f != MEMMODEL_RELAXED)
- emit_label (label2);
-
- arm_post_atomic_barrier (mod_s);
-
- if (mod_f == MEMMODEL_RELAXED)
- emit_label (label2);
-}
-
-void
-arm_split_atomic_op (enum rtx_code code, rtx old_out, rtx new_out, rtx mem,
- rtx value, rtx model_rtx, rtx cond)
-{
- enum memmodel model = (enum memmodel) INTVAL (model_rtx);
- enum machine_mode mode = GET_MODE (mem);
- enum machine_mode wmode = (mode == DImode ? DImode : SImode);
- rtx label, x;
-
- arm_pre_atomic_barrier (model);
-
- label = gen_label_rtx ();
- emit_label (label);
-
- if (new_out)
- new_out = gen_lowpart (wmode, new_out);
- if (old_out)
- old_out = gen_lowpart (wmode, old_out);
- else
- old_out = new_out;
- value = simplify_gen_subreg (wmode, value, mode, 0);
-
- arm_emit_load_exclusive (mode, old_out, mem);
-
- switch (code)
- {
- case SET:
- new_out = value;
- break;
-
- case NOT:
- x = gen_rtx_AND (wmode, old_out, value);
- emit_insn (gen_rtx_SET (VOIDmode, new_out, x));
- x = gen_rtx_NOT (wmode, new_out);
- emit_insn (gen_rtx_SET (VOIDmode, new_out, x));
- break;
-
- case MINUS:
- if (CONST_INT_P (value))
- {
- value = GEN_INT (-INTVAL (value));
- code = PLUS;
- }
- /* FALLTHRU */
-
- case PLUS:
- if (mode == DImode)
- {
- /* DImode plus/minus need to clobber flags. */
- /* The adddi3 and subdi3 patterns are incorrectly written so that
- they require matching operands, even when we could easily support
- three operands. Thankfully, this can be fixed up post-splitting,
- as the individual add+adc patterns do accept three operands and
- post-reload cprop can make these moves go away. */
- emit_move_insn (new_out, old_out);
- if (code == PLUS)
- x = gen_adddi3 (new_out, new_out, value);
- else
- x = gen_subdi3 (new_out, new_out, value);
- emit_insn (x);
- break;
- }
- /* FALLTHRU */
-
- default:
- x = gen_rtx_fmt_ee (code, wmode, old_out, value);
- emit_insn (gen_rtx_SET (VOIDmode, new_out, x));
- break;
- }
-
- arm_emit_store_exclusive (mode, cond, mem, gen_lowpart (mode, new_out));
-
- x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
- emit_unlikely_jump (gen_cbranchsi4 (x, cond, const0_rtx, label));
-
- arm_post_atomic_barrier (model);
-}
-
-#define MAX_VECT_LEN 16
-
-struct expand_vec_perm_d
-{
- rtx target, op0, op1;
- unsigned char perm[MAX_VECT_LEN];
- enum machine_mode vmode;
- unsigned char nelt;
- bool one_vector_p;
- bool testing_p;
-};
-
-/* Generate a variable permutation. */
-
-static void
-arm_expand_vec_perm_1 (rtx target, rtx op0, rtx op1, rtx sel)
-{
- enum machine_mode vmode = GET_MODE (target);
- bool one_vector_p = rtx_equal_p (op0, op1);
-
- gcc_checking_assert (vmode == V8QImode || vmode == V16QImode);
- gcc_checking_assert (GET_MODE (op0) == vmode);
- gcc_checking_assert (GET_MODE (op1) == vmode);
- gcc_checking_assert (GET_MODE (sel) == vmode);
- gcc_checking_assert (TARGET_NEON);
-
- if (one_vector_p)
- {
- if (vmode == V8QImode)
- emit_insn (gen_neon_vtbl1v8qi (target, op0, sel));
- else
- emit_insn (gen_neon_vtbl1v16qi (target, op0, sel));
- }
- else
- {
- rtx pair;
-
- if (vmode == V8QImode)
- {
- pair = gen_reg_rtx (V16QImode);
- emit_insn (gen_neon_vcombinev8qi (pair, op0, op1));
- pair = gen_lowpart (TImode, pair);
- emit_insn (gen_neon_vtbl2v8qi (target, pair, sel));
- }
- else
- {
- pair = gen_reg_rtx (OImode);
- emit_insn (gen_neon_vcombinev16qi (pair, op0, op1));
- emit_insn (gen_neon_vtbl2v16qi (target, pair, sel));
- }
- }
-}
-
-void
-arm_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel)
-{
- enum machine_mode vmode = GET_MODE (target);
- unsigned int i, nelt = GET_MODE_NUNITS (vmode);
- bool one_vector_p = rtx_equal_p (op0, op1);
- rtx rmask[MAX_VECT_LEN], mask;
-
- /* TODO: ARM's VTBL indexing is little-endian. In order to handle GCC's
- numbering of elements for big-endian, we must reverse the order. */
- gcc_checking_assert (!BYTES_BIG_ENDIAN);
-
- /* The VTBL instruction does not use a modulo index, so we must take care
- of that ourselves. */
- mask = GEN_INT (one_vector_p ? nelt - 1 : 2 * nelt - 1);
- for (i = 0; i < nelt; ++i)
- rmask[i] = mask;
- mask = gen_rtx_CONST_VECTOR (vmode, gen_rtvec_v (nelt, rmask));
- sel = expand_simple_binop (vmode, AND, sel, mask, NULL, 0, OPTAB_LIB_WIDEN);
-
- arm_expand_vec_perm_1 (target, op0, op1, sel);
-}
-
-/* Generate or test for an insn that supports a constant permutation. */
-
-/* Recognize patterns for the VUZP insns. */
-
-static bool
-arm_evpc_neon_vuzp (struct expand_vec_perm_d *d)
-{
- unsigned int i, odd, mask, nelt = d->nelt;
- rtx out0, out1, in0, in1, x;
- rtx (*gen)(rtx, rtx, rtx, rtx);
-
- if (GET_MODE_UNIT_SIZE (d->vmode) >= 8)
- return false;
-
- /* Note that these are little-endian tests. Adjust for big-endian later. */
- if (d->perm[0] == 0)
- odd = 0;
- else if (d->perm[0] == 1)
- odd = 1;
- else
- return false;
- mask = (d->one_vector_p ? nelt - 1 : 2 * nelt - 1);
-
- for (i = 0; i < nelt; i++)
- {
- unsigned elt = (i * 2 + odd) & mask;
- if (d->perm[i] != elt)
- return false;
- }
-
- /* Success! */
- if (d->testing_p)
- return true;
-
- switch (d->vmode)
- {
- case V16QImode: gen = gen_neon_vuzpv16qi_internal; break;
- case V8QImode: gen = gen_neon_vuzpv8qi_internal; break;
- case V8HImode: gen = gen_neon_vuzpv8hi_internal; break;
- case V4HImode: gen = gen_neon_vuzpv4hi_internal; break;
- case V4SImode: gen = gen_neon_vuzpv4si_internal; break;
- case V2SImode: gen = gen_neon_vuzpv2si_internal; break;
- case V2SFmode: gen = gen_neon_vuzpv2sf_internal; break;
- case V4SFmode: gen = gen_neon_vuzpv4sf_internal; break;
- default:
- gcc_unreachable ();
- }
-
- in0 = d->op0;
- in1 = d->op1;
- if (BYTES_BIG_ENDIAN)
- {
- x = in0, in0 = in1, in1 = x;
- odd = !odd;
- }
-
- out0 = d->target;
- out1 = gen_reg_rtx (d->vmode);
- if (odd)
- x = out0, out0 = out1, out1 = x;
-
- emit_insn (gen (out0, in0, in1, out1));
- return true;
-}
-
-/* Recognize patterns for the VZIP insns. */
-
-static bool
-arm_evpc_neon_vzip (struct expand_vec_perm_d *d)
-{
- unsigned int i, high, mask, nelt = d->nelt;
- rtx out0, out1, in0, in1, x;
- rtx (*gen)(rtx, rtx, rtx, rtx);
-
- if (GET_MODE_UNIT_SIZE (d->vmode) >= 8)
- return false;
-
- /* Note that these are little-endian tests. Adjust for big-endian later. */
- high = nelt / 2;
- if (d->perm[0] == high)
- ;
- else if (d->perm[0] == 0)
- high = 0;
- else
- return false;
- mask = (d->one_vector_p ? nelt - 1 : 2 * nelt - 1);
-
- for (i = 0; i < nelt / 2; i++)
- {
- unsigned elt = (i + high) & mask;
- if (d->perm[i * 2] != elt)
- return false;
- elt = (elt + nelt) & mask;
- if (d->perm[i * 2 + 1] != elt)
- return false;
- }
-
- /* Success! */
- if (d->testing_p)
- return true;
-
- switch (d->vmode)
- {
- case V16QImode: gen = gen_neon_vzipv16qi_internal; break;
- case V8QImode: gen = gen_neon_vzipv8qi_internal; break;
- case V8HImode: gen = gen_neon_vzipv8hi_internal; break;
- case V4HImode: gen = gen_neon_vzipv4hi_internal; break;
- case V4SImode: gen = gen_neon_vzipv4si_internal; break;
- case V2SImode: gen = gen_neon_vzipv2si_internal; break;
- case V2SFmode: gen = gen_neon_vzipv2sf_internal; break;
- case V4SFmode: gen = gen_neon_vzipv4sf_internal; break;
- default:
- gcc_unreachable ();
- }
-
- in0 = d->op0;
- in1 = d->op1;
- if (BYTES_BIG_ENDIAN)
- {
- x = in0, in0 = in1, in1 = x;
- high = !high;
- }
-
- out0 = d->target;
- out1 = gen_reg_rtx (d->vmode);
- if (high)
- x = out0, out0 = out1, out1 = x;
-
- emit_insn (gen (out0, in0, in1, out1));
- return true;
-}
-
-/* Recognize patterns for the VREV insns. */
-
-static bool
-arm_evpc_neon_vrev (struct expand_vec_perm_d *d)
-{
- unsigned int i, j, diff, nelt = d->nelt;
- rtx (*gen)(rtx, rtx, rtx);
-
- if (!d->one_vector_p)
- return false;
-
- diff = d->perm[0];
- switch (diff)
- {
- case 7:
- switch (d->vmode)
- {
- case V16QImode: gen = gen_neon_vrev64v16qi; break;
- case V8QImode: gen = gen_neon_vrev64v8qi; break;
- default:
- return false;
- }
- break;
- case 3:
- switch (d->vmode)
- {
- case V16QImode: gen = gen_neon_vrev32v16qi; break;
- case V8QImode: gen = gen_neon_vrev32v8qi; break;
- case V8HImode: gen = gen_neon_vrev64v8hi; break;
- case V4HImode: gen = gen_neon_vrev64v4hi; break;
- default:
- return false;
- }
- break;
- case 1:
- switch (d->vmode)
- {
- case V16QImode: gen = gen_neon_vrev16v16qi; break;
- case V8QImode: gen = gen_neon_vrev16v8qi; break;
- case V8HImode: gen = gen_neon_vrev32v8hi; break;
- case V4HImode: gen = gen_neon_vrev32v4hi; break;
- case V4SImode: gen = gen_neon_vrev64v4si; break;
- case V2SImode: gen = gen_neon_vrev64v2si; break;
- case V4SFmode: gen = gen_neon_vrev64v4sf; break;
- case V2SFmode: gen = gen_neon_vrev64v2sf; break;
- default:
- return false;
- }
- break;
- default:
- return false;
- }
-
- for (i = 0; i < nelt ; i += diff + 1)
- for (j = 0; j <= diff; j += 1)
- {
- /* This is guaranteed to be true as the value of diff
- is 7, 3, 1 and we should have enough elements in the
- queue to generate this. Getting a vector mask with a
- value of diff other than these values implies that
- something is wrong by the time we get here. */
- gcc_assert (i + j < nelt);
- if (d->perm[i + j] != i + diff - j)
- return false;
- }
-
- /* Success! */
- if (d->testing_p)
- return true;
-
- /* ??? The third operand is an artifact of the builtin infrastructure
- and is ignored by the actual instruction. */
- emit_insn (gen (d->target, d->op0, const0_rtx));
- return true;
-}
-
-/* Recognize patterns for the VTRN insns. */
-
-static bool
-arm_evpc_neon_vtrn (struct expand_vec_perm_d *d)
-{
- unsigned int i, odd, mask, nelt = d->nelt;
- rtx out0, out1, in0, in1, x;
- rtx (*gen)(rtx, rtx, rtx, rtx);
-
- if (GET_MODE_UNIT_SIZE (d->vmode) >= 8)
- return false;
-
- /* Note that these are little-endian tests. Adjust for big-endian later. */
- if (d->perm[0] == 0)
- odd = 0;
- else if (d->perm[0] == 1)
- odd = 1;
- else
- return false;
- mask = (d->one_vector_p ? nelt - 1 : 2 * nelt - 1);
-
- for (i = 0; i < nelt; i += 2)
- {
- if (d->perm[i] != i + odd)
- return false;
- if (d->perm[i + 1] != ((i + nelt + odd) & mask))
- return false;
- }
-
- /* Success! */
- if (d->testing_p)
- return true;
-
- switch (d->vmode)
- {
- case V16QImode: gen = gen_neon_vtrnv16qi_internal; break;
- case V8QImode: gen = gen_neon_vtrnv8qi_internal; break;
- case V8HImode: gen = gen_neon_vtrnv8hi_internal; break;
- case V4HImode: gen = gen_neon_vtrnv4hi_internal; break;
- case V4SImode: gen = gen_neon_vtrnv4si_internal; break;
- case V2SImode: gen = gen_neon_vtrnv2si_internal; break;
- case V2SFmode: gen = gen_neon_vtrnv2sf_internal; break;
- case V4SFmode: gen = gen_neon_vtrnv4sf_internal; break;
- default:
- gcc_unreachable ();
- }
-
- in0 = d->op0;
- in1 = d->op1;
- if (BYTES_BIG_ENDIAN)
- {
- x = in0, in0 = in1, in1 = x;
- odd = !odd;
- }
-
- out0 = d->target;
- out1 = gen_reg_rtx (d->vmode);
- if (odd)
- x = out0, out0 = out1, out1 = x;
-
- emit_insn (gen (out0, in0, in1, out1));
- return true;
-}
-
-/* Recognize patterns for the VEXT insns. */
-
-static bool
-arm_evpc_neon_vext (struct expand_vec_perm_d *d)
-{
- unsigned int i, nelt = d->nelt;
- rtx (*gen) (rtx, rtx, rtx, rtx);
- rtx offset;
-
- unsigned int location;
-
- unsigned int next = d->perm[0] + 1;
-
- /* TODO: Handle GCC's numbering of elements for big-endian. */
- if (BYTES_BIG_ENDIAN)
- return false;
-
- /* Check if the extracted indexes are increasing by one. */
- for (i = 1; i < nelt; next++, i++)
- {
- /* If we hit the most significant element of the 2nd vector in
- the previous iteration, no need to test further. */
- if (next == 2 * nelt)
- return false;
-
- /* If we are operating on only one vector: it could be a
- rotation. If there are only two elements of size < 64, let
- arm_evpc_neon_vrev catch it. */
- if (d->one_vector_p && (next == nelt))
- {
- if ((nelt == 2) && (d->vmode != V2DImode))
- return false;
- else
- next = 0;
- }
-
- if (d->perm[i] != next)
- return false;
- }
-
- location = d->perm[0];
-
- switch (d->vmode)
- {
- case V16QImode: gen = gen_neon_vextv16qi; break;
- case V8QImode: gen = gen_neon_vextv8qi; break;
- case V4HImode: gen = gen_neon_vextv4hi; break;
- case V8HImode: gen = gen_neon_vextv8hi; break;
- case V2SImode: gen = gen_neon_vextv2si; break;
- case V4SImode: gen = gen_neon_vextv4si; break;
- case V2SFmode: gen = gen_neon_vextv2sf; break;
- case V4SFmode: gen = gen_neon_vextv4sf; break;
- case V2DImode: gen = gen_neon_vextv2di; break;
- default:
- return false;
- }
-
- /* Success! */
- if (d->testing_p)
- return true;
-
- offset = GEN_INT (location);
- emit_insn (gen (d->target, d->op0, d->op1, offset));
- return true;
-}
-
-/* The NEON VTBL instruction is a fully variable permuation that's even
- stronger than what we expose via VEC_PERM_EXPR. What it doesn't do
- is mask the index operand as VEC_PERM_EXPR requires. Therefore we
- can do slightly better by expanding this as a constant where we don't
- have to apply a mask. */
-
-static bool
-arm_evpc_neon_vtbl (struct expand_vec_perm_d *d)
-{
- rtx rperm[MAX_VECT_LEN], sel;
- enum machine_mode vmode = d->vmode;
- unsigned int i, nelt = d->nelt;
-
- /* TODO: ARM's VTBL indexing is little-endian. In order to handle GCC's
- numbering of elements for big-endian, we must reverse the order. */
- if (BYTES_BIG_ENDIAN)
- return false;
-
- if (d->testing_p)
- return true;
-
- /* Generic code will try constant permutation twice. Once with the
- original mode and again with the elements lowered to QImode.
- So wait and don't do the selector expansion ourselves. */
- if (vmode != V8QImode && vmode != V16QImode)
- return false;
-
- for (i = 0; i < nelt; ++i)
- rperm[i] = GEN_INT (d->perm[i]);
- sel = gen_rtx_CONST_VECTOR (vmode, gen_rtvec_v (nelt, rperm));
- sel = force_reg (vmode, sel);
-
- arm_expand_vec_perm_1 (d->target, d->op0, d->op1, sel);
- return true;
-}
-
-static bool
-arm_expand_vec_perm_const_1 (struct expand_vec_perm_d *d)
-{
- /* Check if the input mask matches vext before reordering the
- operands. */
- if (TARGET_NEON)
- if (arm_evpc_neon_vext (d))
- return true;
-
- /* The pattern matching functions above are written to look for a small
- number to begin the sequence (0, 1, N/2). If we begin with an index
- from the second operand, we can swap the operands. */
- if (d->perm[0] >= d->nelt)
- {
- unsigned i, nelt = d->nelt;
- rtx x;
-
- for (i = 0; i < nelt; ++i)
- d->perm[i] = (d->perm[i] + nelt) & (2 * nelt - 1);
-
- x = d->op0;
- d->op0 = d->op1;
- d->op1 = x;
- }
-
- if (TARGET_NEON)
- {
- if (arm_evpc_neon_vuzp (d))
- return true;
- if (arm_evpc_neon_vzip (d))
- return true;
- if (arm_evpc_neon_vrev (d))
- return true;
- if (arm_evpc_neon_vtrn (d))
- return true;
- return arm_evpc_neon_vtbl (d);
- }
- return false;
-}
-
-/* Expand a vec_perm_const pattern. */
-
-bool
-arm_expand_vec_perm_const (rtx target, rtx op0, rtx op1, rtx sel)
-{
- struct expand_vec_perm_d d;
- int i, nelt, which;
-
- d.target = target;
- d.op0 = op0;
- d.op1 = op1;
-
- d.vmode = GET_MODE (target);
- gcc_assert (VECTOR_MODE_P (d.vmode));
- d.nelt = nelt = GET_MODE_NUNITS (d.vmode);
- d.testing_p = false;
-
- for (i = which = 0; i < nelt; ++i)
- {
- rtx e = XVECEXP (sel, 0, i);
- int ei = INTVAL (e) & (2 * nelt - 1);
- which |= (ei < nelt ? 1 : 2);
- d.perm[i] = ei;
- }
-
- switch (which)
- {
- default:
- gcc_unreachable();
-
- case 3:
- d.one_vector_p = false;
- if (!rtx_equal_p (op0, op1))
- break;
-
- /* The elements of PERM do not suggest that only the first operand
- is used, but both operands are identical. Allow easier matching
- of the permutation by folding the permutation into the single
- input vector. */
- /* FALLTHRU */
- case 2:
- for (i = 0; i < nelt; ++i)
- d.perm[i] &= nelt - 1;
- d.op0 = op1;
- d.one_vector_p = true;
- break;
-
- case 1:
- d.op1 = op0;
- d.one_vector_p = true;
- break;
- }
-
- return arm_expand_vec_perm_const_1 (&d);
-}
-
-/* Implement TARGET_VECTORIZE_VEC_PERM_CONST_OK. */
-
-static bool
-arm_vectorize_vec_perm_const_ok (enum machine_mode vmode,
- const unsigned char *sel)
-{
- struct expand_vec_perm_d d;
- unsigned int i, nelt, which;
- bool ret;
-
- d.vmode = vmode;
- d.nelt = nelt = GET_MODE_NUNITS (d.vmode);
- d.testing_p = true;
- memcpy (d.perm, sel, nelt);
-
- /* Categorize the set of elements in the selector. */
- for (i = which = 0; i < nelt; ++i)
- {
- unsigned char e = d.perm[i];
- gcc_assert (e < 2 * nelt);
- which |= (e < nelt ? 1 : 2);
- }
-
- /* For all elements from second vector, fold the elements to first. */
- if (which == 2)
- for (i = 0; i < nelt; ++i)
- d.perm[i] -= nelt;
-
- /* Check whether the mask can be applied to the vector type. */
- d.one_vector_p = (which != 3);
-
- d.target = gen_raw_REG (d.vmode, LAST_VIRTUAL_REGISTER + 1);
- d.op1 = d.op0 = gen_raw_REG (d.vmode, LAST_VIRTUAL_REGISTER + 2);
- if (!d.one_vector_p)
- d.op1 = gen_raw_REG (d.vmode, LAST_VIRTUAL_REGISTER + 3);
-
- start_sequence ();
- ret = arm_expand_vec_perm_const_1 (&d);
- end_sequence ();
-
- return ret;
-}
-
-bool
-arm_autoinc_modes_ok_p (enum machine_mode mode, enum arm_auto_incmodes code)
-{
- /* If we are soft float and we do not have ldrd
- then all auto increment forms are ok. */
- if (TARGET_SOFT_FLOAT && (TARGET_LDRD || GET_MODE_SIZE (mode) <= 4))
- return true;
-
- switch (code)
- {
- /* Post increment and Pre Decrement are supported for all
- instruction forms except for vector forms. */
- case ARM_POST_INC:
- case ARM_PRE_DEC:
- if (VECTOR_MODE_P (mode))
- {
- if (code != ARM_PRE_DEC)
- return true;
- else
- return false;
- }
-
- return true;
-
- case ARM_POST_DEC:
- case ARM_PRE_INC:
- /* Without LDRD and mode size greater than
- word size, there is no point in auto-incrementing
- because ldm and stm will not have these forms. */
- if (!TARGET_LDRD && GET_MODE_SIZE (mode) > 4)
- return false;
-
- /* Vector and floating point modes do not support
- these auto increment forms. */
- if (FLOAT_MODE_P (mode) || VECTOR_MODE_P (mode))
- return false;
-
- return true;
-
- default:
- return false;
-
- }
-
- return false;
-}
-
-/* The default expansion of general 64-bit shifts in core-regs is suboptimal,
- on ARM, since we know that shifts by negative amounts are no-ops.
- Additionally, the default expansion code is not available or suitable
- for post-reload insn splits (this can occur when the register allocator
- chooses not to do a shift in NEON).
-
- This function is used in both initial expand and post-reload splits, and
- handles all kinds of 64-bit shifts.
-
- Input requirements:
- - It is safe for the input and output to be the same register, but
- early-clobber rules apply for the shift amount and scratch registers.
- - Shift by register requires both scratch registers. In all other cases
- the scratch registers may be NULL.
- - Ashiftrt by a register also clobbers the CC register. */
-void
-arm_emit_coreregs_64bit_shift (enum rtx_code code, rtx out, rtx in,
- rtx amount, rtx scratch1, rtx scratch2)
-{
- rtx out_high = gen_highpart (SImode, out);
- rtx out_low = gen_lowpart (SImode, out);
- rtx in_high = gen_highpart (SImode, in);
- rtx in_low = gen_lowpart (SImode, in);
-
- /* Terminology:
- in = the register pair containing the input value.
- out = the destination register pair.
- up = the high- or low-part of each pair.
- down = the opposite part to "up".
- In a shift, we can consider bits to shift from "up"-stream to
- "down"-stream, so in a left-shift "up" is the low-part and "down"
- is the high-part of each register pair. */
-
- rtx out_up = code == ASHIFT ? out_low : out_high;
- rtx out_down = code == ASHIFT ? out_high : out_low;
- rtx in_up = code == ASHIFT ? in_low : in_high;
- rtx in_down = code == ASHIFT ? in_high : in_low;
-
- gcc_assert (code == ASHIFT || code == ASHIFTRT || code == LSHIFTRT);
- gcc_assert (out
- && (REG_P (out) || GET_CODE (out) == SUBREG)
- && GET_MODE (out) == DImode);
- gcc_assert (in
- && (REG_P (in) || GET_CODE (in) == SUBREG)
- && GET_MODE (in) == DImode);
- gcc_assert (amount
- && (((REG_P (amount) || GET_CODE (amount) == SUBREG)
- && GET_MODE (amount) == SImode)
- || CONST_INT_P (amount)));
- gcc_assert (scratch1 == NULL
- || (GET_CODE (scratch1) == SCRATCH)
- || (GET_MODE (scratch1) == SImode
- && REG_P (scratch1)));
- gcc_assert (scratch2 == NULL
- || (GET_CODE (scratch2) == SCRATCH)
- || (GET_MODE (scratch2) == SImode
- && REG_P (scratch2)));
- gcc_assert (!REG_P (out) || !REG_P (amount)
- || !HARD_REGISTER_P (out)
- || (REGNO (out) != REGNO (amount)
- && REGNO (out) + 1 != REGNO (amount)));
-
- /* Macros to make following code more readable. */
- #define SUB_32(DEST,SRC) \
- gen_addsi3 ((DEST), (SRC), GEN_INT (-32))
- #define RSB_32(DEST,SRC) \
- gen_subsi3 ((DEST), GEN_INT (32), (SRC))
- #define SUB_S_32(DEST,SRC) \
- gen_addsi3_compare0 ((DEST), (SRC), \
- GEN_INT (-32))
- #define SET(DEST,SRC) \
- gen_rtx_SET (SImode, (DEST), (SRC))
- #define SHIFT(CODE,SRC,AMOUNT) \
- gen_rtx_fmt_ee ((CODE), SImode, (SRC), (AMOUNT))
- #define LSHIFT(CODE,SRC,AMOUNT) \
- gen_rtx_fmt_ee ((CODE) == ASHIFT ? ASHIFT : LSHIFTRT, \
- SImode, (SRC), (AMOUNT))
- #define REV_LSHIFT(CODE,SRC,AMOUNT) \
- gen_rtx_fmt_ee ((CODE) == ASHIFT ? LSHIFTRT : ASHIFT, \
- SImode, (SRC), (AMOUNT))
- #define ORR(A,B) \
- gen_rtx_IOR (SImode, (A), (B))
- #define BRANCH(COND,LABEL) \
- gen_arm_cond_branch ((LABEL), \
- gen_rtx_ ## COND (CCmode, cc_reg, \
- const0_rtx), \
- cc_reg)
-
- /* Shifts by register and shifts by constant are handled separately. */
- if (CONST_INT_P (amount))
- {
- /* We have a shift-by-constant. */
-
- /* First, handle out-of-range shift amounts.
- In both cases we try to match the result an ARM instruction in a
- shift-by-register would give. This helps reduce execution
- differences between optimization levels, but it won't stop other
- parts of the compiler doing different things. This is "undefined
- behaviour, in any case. */
- if (INTVAL (amount) <= 0)
- emit_insn (gen_movdi (out, in));
- else if (INTVAL (amount) >= 64)
- {
- if (code == ASHIFTRT)
- {
- rtx const31_rtx = GEN_INT (31);
- emit_insn (SET (out_down, SHIFT (code, in_up, const31_rtx)));
- emit_insn (SET (out_up, SHIFT (code, in_up, const31_rtx)));
- }
- else
- emit_insn (gen_movdi (out, const0_rtx));
- }
-
- /* Now handle valid shifts. */
- else if (INTVAL (amount) < 32)
- {
- /* Shifts by a constant less than 32. */
- rtx reverse_amount = GEN_INT (32 - INTVAL (amount));
-
- emit_insn (SET (out_down, LSHIFT (code, in_down, amount)));
- emit_insn (SET (out_down,
- ORR (REV_LSHIFT (code, in_up, reverse_amount),
- out_down)));
- emit_insn (SET (out_up, SHIFT (code, in_up, amount)));
- }
- else
- {
- /* Shifts by a constant greater than 31. */
- rtx adj_amount = GEN_INT (INTVAL (amount) - 32);
-
- emit_insn (SET (out_down, SHIFT (code, in_up, adj_amount)));
- if (code == ASHIFTRT)
- emit_insn (gen_ashrsi3 (out_up, in_up,
- GEN_INT (31)));
- else
- emit_insn (SET (out_up, const0_rtx));
- }
- }
- else
- {
- /* We have a shift-by-register. */
- rtx cc_reg = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
-
- /* This alternative requires the scratch registers. */
- gcc_assert (scratch1 && REG_P (scratch1));
- gcc_assert (scratch2 && REG_P (scratch2));
-
- /* We will need the values "amount-32" and "32-amount" later.
- Swapping them around now allows the later code to be more general. */
- switch (code)
- {
- case ASHIFT:
- emit_insn (SUB_32 (scratch1, amount));
- emit_insn (RSB_32 (scratch2, amount));
- break;
- case ASHIFTRT:
- emit_insn (RSB_32 (scratch1, amount));
- /* Also set CC = amount > 32. */
- emit_insn (SUB_S_32 (scratch2, amount));
- break;
- case LSHIFTRT:
- emit_insn (RSB_32 (scratch1, amount));
- emit_insn (SUB_32 (scratch2, amount));
- break;
- default:
- gcc_unreachable ();
- }
-
- /* Emit code like this:
-
- arithmetic-left:
- out_down = in_down << amount;
- out_down = (in_up << (amount - 32)) | out_down;
- out_down = ((unsigned)in_up >> (32 - amount)) | out_down;
- out_up = in_up << amount;
-
- arithmetic-right:
- out_down = in_down >> amount;
- out_down = (in_up << (32 - amount)) | out_down;
- if (amount < 32)
- out_down = ((signed)in_up >> (amount - 32)) | out_down;
- out_up = in_up << amount;
-
- logical-right:
- out_down = in_down >> amount;
- out_down = (in_up << (32 - amount)) | out_down;
- if (amount < 32)
- out_down = ((unsigned)in_up >> (amount - 32)) | out_down;
- out_up = in_up << amount;
-
- The ARM and Thumb2 variants are the same but implemented slightly
- differently. If this were only called during expand we could just
- use the Thumb2 case and let combine do the right thing, but this
- can also be called from post-reload splitters. */
-
- emit_insn (SET (out_down, LSHIFT (code, in_down, amount)));
-
- if (!TARGET_THUMB2)
- {
- /* Emit code for ARM mode. */
- emit_insn (SET (out_down,
- ORR (SHIFT (ASHIFT, in_up, scratch1), out_down)));
- if (code == ASHIFTRT)
- {
- rtx done_label = gen_label_rtx ();
- emit_jump_insn (BRANCH (LT, done_label));
- emit_insn (SET (out_down, ORR (SHIFT (ASHIFTRT, in_up, scratch2),
- out_down)));
- emit_label (done_label);
- }
- else
- emit_insn (SET (out_down, ORR (SHIFT (LSHIFTRT, in_up, scratch2),
- out_down)));
- }
- else
- {
- /* Emit code for Thumb2 mode.
- Thumb2 can't do shift and or in one insn. */
- emit_insn (SET (scratch1, SHIFT (ASHIFT, in_up, scratch1)));
- emit_insn (gen_iorsi3 (out_down, out_down, scratch1));
-
- if (code == ASHIFTRT)
- {
- rtx done_label = gen_label_rtx ();
- emit_jump_insn (BRANCH (LT, done_label));
- emit_insn (SET (scratch2, SHIFT (ASHIFTRT, in_up, scratch2)));
- emit_insn (SET (out_down, ORR (out_down, scratch2)));
- emit_label (done_label);
- }
- else
- {
- emit_insn (SET (scratch2, SHIFT (LSHIFTRT, in_up, scratch2)));
- emit_insn (gen_iorsi3 (out_down, out_down, scratch2));
- }
- }
-
- emit_insn (SET (out_up, SHIFT (code, in_up, amount)));
- }
-
- #undef SUB_32
- #undef RSB_32
- #undef SUB_S_32
- #undef SET
- #undef SHIFT
- #undef LSHIFT
- #undef REV_LSHIFT
- #undef ORR
- #undef BRANCH
-}
-
-
-/* Returns true if a valid comparison operation and makes
- the operands in a form that is valid. */
-bool
-arm_validize_comparison (rtx *comparison, rtx * op1, rtx * op2)
-{
- enum rtx_code code = GET_CODE (*comparison);
- int code_int;
- enum machine_mode mode = (GET_MODE (*op1) == VOIDmode)
- ? GET_MODE (*op2) : GET_MODE (*op1);
-
- gcc_assert (GET_MODE (*op1) != VOIDmode || GET_MODE (*op2) != VOIDmode);
-
- if (code == UNEQ || code == LTGT)
- return false;
-
- code_int = (int)code;
- arm_canonicalize_comparison (&code_int, op1, op2, 0);
- PUT_CODE (*comparison, (enum rtx_code)code_int);
-
- switch (mode)
- {
- case SImode:
- if (!arm_add_operand (*op1, mode))
- *op1 = force_reg (mode, *op1);
- if (!arm_add_operand (*op2, mode))
- *op2 = force_reg (mode, *op2);
- return true;
-
- case DImode:
- if (!cmpdi_operand (*op1, mode))
- *op1 = force_reg (mode, *op1);
- if (!cmpdi_operand (*op2, mode))
- *op2 = force_reg (mode, *op2);
- return true;
-
- case SFmode:
- case DFmode:
- if (!arm_float_compare_operand (*op1, mode))
- *op1 = force_reg (mode, *op1);
- if (!arm_float_compare_operand (*op2, mode))
- *op2 = force_reg (mode, *op2);
- return true;
- default:
- break;
- }
-
- return false;
-
-}
-
-#include "gt-arm.h"
diff --git a/gcc-4.8/gcc/config/i386/i386.c.orig b/gcc-4.8/gcc/config/i386/i386.c.orig
deleted file mode 100644
index 7f61f3140..000000000
--- a/gcc-4.8/gcc/config/i386/i386.c.orig
+++ /dev/null
@@ -1,42870 +0,0 @@
-/* Subroutines used for code generation on IA-32.
- Copyright (C) 1988-2013 Free Software Foundation, Inc.
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
-
-GCC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "tm.h"
-#include "rtl.h"
-#include "tree.h"
-#include "tm_p.h"
-#include "regs.h"
-#include "hard-reg-set.h"
-#include "insn-config.h"
-#include "conditions.h"
-#include "output.h"
-#include "insn-codes.h"
-#include "insn-attr.h"
-#include "flags.h"
-#include "except.h"
-#include "function.h"
-#include "recog.h"
-#include "expr.h"
-#include "optabs.h"
-#include "diagnostic-core.h"
-#include "toplev.h"
-#include "basic-block.h"
-#include "ggc.h"
-#include "target.h"
-#include "target-def.h"
-#include "common/common-target.h"
-#include "langhooks.h"
-#include "reload.h"
-#include "cgraph.h"
-#include "gimple.h"
-#include "dwarf2.h"
-#include "df.h"
-#include "tm-constrs.h"
-#include "params.h"
-#include "cselib.h"
-#include "debug.h"
-#include "sched-int.h"
-#include "sbitmap.h"
-#include "fibheap.h"
-#include "opts.h"
-#include "diagnostic.h"
-#include "dumpfile.h"
-#include "tree-pass.h"
-#include "tree-flow.h"
-
-static rtx legitimize_dllimport_symbol (rtx, bool);
-
-#ifndef CHECK_STACK_LIMIT
-#define CHECK_STACK_LIMIT (-1)
-#endif
-
-/* Return index of given mode in mult and division cost tables. */
-#define MODE_INDEX(mode) \
- ((mode) == QImode ? 0 \
- : (mode) == HImode ? 1 \
- : (mode) == SImode ? 2 \
- : (mode) == DImode ? 3 \
- : 4)
-
-/* Processor costs (relative to an add) */
-/* We assume COSTS_N_INSNS is defined as (N)*4 and an addition is 2 bytes. */
-#define COSTS_N_BYTES(N) ((N) * 2)
-
-#define DUMMY_STRINGOP_ALGS {libcall, {{-1, libcall, false}}}
-
-const
-struct processor_costs ix86_size_cost = {/* costs for tuning for size */
- COSTS_N_BYTES (2), /* cost of an add instruction */
- COSTS_N_BYTES (3), /* cost of a lea instruction */
- COSTS_N_BYTES (2), /* variable shift costs */
- COSTS_N_BYTES (3), /* constant shift costs */
- {COSTS_N_BYTES (3), /* cost of starting multiply for QI */
- COSTS_N_BYTES (3), /* HI */
- COSTS_N_BYTES (3), /* SI */
- COSTS_N_BYTES (3), /* DI */
- COSTS_N_BYTES (5)}, /* other */
- 0, /* cost of multiply per each bit set */
- {COSTS_N_BYTES (3), /* cost of a divide/mod for QI */
- COSTS_N_BYTES (3), /* HI */
- COSTS_N_BYTES (3), /* SI */
- COSTS_N_BYTES (3), /* DI */
- COSTS_N_BYTES (5)}, /* other */
- COSTS_N_BYTES (3), /* cost of movsx */
- COSTS_N_BYTES (3), /* cost of movzx */
- 0, /* "large" insn */
- 2, /* MOVE_RATIO */
- 2, /* cost for loading QImode using movzbl */
- {2, 2, 2}, /* cost of loading integer registers
- in QImode, HImode and SImode.
- Relative to reg-reg move (2). */
- {2, 2, 2}, /* cost of storing integer registers */
- 2, /* cost of reg,reg fld/fst */
- {2, 2, 2}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {2, 2, 2}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 3, /* cost of moving MMX register */
- {3, 3}, /* cost of loading MMX registers
- in SImode and DImode */
- {3, 3}, /* cost of storing MMX registers
- in SImode and DImode */
- 3, /* cost of moving SSE register */
- {3, 3, 3}, /* cost of loading SSE registers
- in SImode, DImode and TImode */
- {3, 3, 3}, /* cost of storing SSE registers
- in SImode, DImode and TImode */
- 3, /* MMX or SSE register to integer */
- 0, /* size of l1 cache */
- 0, /* size of l2 cache */
- 0, /* size of prefetch block */
- 0, /* number of parallel prefetches */
- 2, /* Branch cost */
- COSTS_N_BYTES (2), /* cost of FADD and FSUB insns. */
- COSTS_N_BYTES (2), /* cost of FMUL instruction. */
- COSTS_N_BYTES (2), /* cost of FDIV instruction. */
- COSTS_N_BYTES (2), /* cost of FABS instruction. */
- COSTS_N_BYTES (2), /* cost of FCHS instruction. */
- COSTS_N_BYTES (2), /* cost of FSQRT instruction. */
- {{rep_prefix_1_byte, {{-1, rep_prefix_1_byte, false}}},
- {rep_prefix_1_byte, {{-1, rep_prefix_1_byte, false}}}},
- {{rep_prefix_1_byte, {{-1, rep_prefix_1_byte, false}}},
- {rep_prefix_1_byte, {{-1, rep_prefix_1_byte, false}}}},
- 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. */
- 1, /* vec_unalign_load_cost. */
- 1, /* vec_store_cost. */
- 1, /* cond_taken_branch_cost. */
- 1, /* cond_not_taken_branch_cost. */
-};
-
-/* Processor costs (relative to an add) */
-static const
-struct processor_costs i386_cost = { /* 386 specific costs */
- COSTS_N_INSNS (1), /* cost of an add instruction */
- COSTS_N_INSNS (1), /* cost of a lea instruction */
- COSTS_N_INSNS (3), /* variable shift costs */
- COSTS_N_INSNS (2), /* constant shift costs */
- {COSTS_N_INSNS (6), /* cost of starting multiply for QI */
- COSTS_N_INSNS (6), /* HI */
- COSTS_N_INSNS (6), /* SI */
- COSTS_N_INSNS (6), /* DI */
- COSTS_N_INSNS (6)}, /* other */
- COSTS_N_INSNS (1), /* cost of multiply per each bit set */
- {COSTS_N_INSNS (23), /* cost of a divide/mod for QI */
- COSTS_N_INSNS (23), /* HI */
- COSTS_N_INSNS (23), /* SI */
- COSTS_N_INSNS (23), /* DI */
- COSTS_N_INSNS (23)}, /* other */
- COSTS_N_INSNS (3), /* cost of movsx */
- COSTS_N_INSNS (2), /* cost of movzx */
- 15, /* "large" insn */
- 3, /* MOVE_RATIO */
- 4, /* cost for loading QImode using movzbl */
- {2, 4, 2}, /* cost of loading integer registers
- in QImode, HImode and SImode.
- Relative to reg-reg move (2). */
- {2, 4, 2}, /* cost of storing integer registers */
- 2, /* cost of reg,reg fld/fst */
- {8, 8, 8}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {8, 8, 8}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 2, /* cost of moving MMX register */
- {4, 8}, /* cost of loading MMX registers
- in SImode and DImode */
- {4, 8}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, /* cost of moving SSE register */
- {4, 8, 16}, /* cost of loading SSE registers
- in SImode, DImode and TImode */
- {4, 8, 16}, /* cost of storing SSE registers
- in SImode, DImode and TImode */
- 3, /* MMX or SSE register to integer */
- 0, /* size of l1 cache */
- 0, /* size of l2 cache */
- 0, /* size of prefetch block */
- 0, /* number of parallel prefetches */
- 1, /* Branch cost */
- COSTS_N_INSNS (23), /* cost of FADD and FSUB insns. */
- COSTS_N_INSNS (27), /* cost of FMUL instruction. */
- COSTS_N_INSNS (88), /* cost of FDIV instruction. */
- COSTS_N_INSNS (22), /* cost of FABS instruction. */
- COSTS_N_INSNS (24), /* cost of FCHS instruction. */
- COSTS_N_INSNS (122), /* cost of FSQRT instruction. */
- {{rep_prefix_1_byte, {{-1, rep_prefix_1_byte, false}}},
- DUMMY_STRINGOP_ALGS},
- {{rep_prefix_1_byte, {{-1, rep_prefix_1_byte, false}}},
- DUMMY_STRINGOP_ALGS},
- 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. */
-};
-
-static const
-struct processor_costs i486_cost = { /* 486 specific costs */
- COSTS_N_INSNS (1), /* cost of an add instruction */
- COSTS_N_INSNS (1), /* cost of a lea instruction */
- COSTS_N_INSNS (3), /* variable shift costs */
- COSTS_N_INSNS (2), /* constant shift costs */
- {COSTS_N_INSNS (12), /* cost of starting multiply for QI */
- COSTS_N_INSNS (12), /* HI */
- COSTS_N_INSNS (12), /* SI */
- COSTS_N_INSNS (12), /* DI */
- COSTS_N_INSNS (12)}, /* other */
- 1, /* cost of multiply per each bit set */
- {COSTS_N_INSNS (40), /* cost of a divide/mod for QI */
- COSTS_N_INSNS (40), /* HI */
- COSTS_N_INSNS (40), /* SI */
- COSTS_N_INSNS (40), /* DI */
- COSTS_N_INSNS (40)}, /* other */
- COSTS_N_INSNS (3), /* cost of movsx */
- COSTS_N_INSNS (2), /* cost of movzx */
- 15, /* "large" insn */
- 3, /* MOVE_RATIO */
- 4, /* cost for loading QImode using movzbl */
- {2, 4, 2}, /* cost of loading integer registers
- in QImode, HImode and SImode.
- Relative to reg-reg move (2). */
- {2, 4, 2}, /* cost of storing integer registers */
- 2, /* cost of reg,reg fld/fst */
- {8, 8, 8}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {8, 8, 8}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 2, /* cost of moving MMX register */
- {4, 8}, /* cost of loading MMX registers
- in SImode and DImode */
- {4, 8}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, /* cost of moving SSE register */
- {4, 8, 16}, /* cost of loading SSE registers
- in SImode, DImode and TImode */
- {4, 8, 16}, /* cost of storing SSE registers
- in SImode, DImode and TImode */
- 3, /* MMX or SSE register to integer */
- 4, /* size of l1 cache. 486 has 8kB cache
- shared for code and data, so 4kB is
- not really precise. */
- 4, /* size of l2 cache */
- 0, /* size of prefetch block */
- 0, /* number of parallel prefetches */
- 1, /* Branch cost */
- COSTS_N_INSNS (8), /* cost of FADD and FSUB insns. */
- COSTS_N_INSNS (16), /* cost of FMUL instruction. */
- COSTS_N_INSNS (73), /* cost of FDIV instruction. */
- COSTS_N_INSNS (3), /* cost of FABS instruction. */
- COSTS_N_INSNS (3), /* cost of FCHS instruction. */
- COSTS_N_INSNS (83), /* cost of FSQRT instruction. */
- {{rep_prefix_4_byte, {{-1, rep_prefix_4_byte, false}}},
- DUMMY_STRINGOP_ALGS},
- {{rep_prefix_4_byte, {{-1, rep_prefix_4_byte, false}}},
- DUMMY_STRINGOP_ALGS},
- 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. */
-};
-
-static const
-struct processor_costs pentium_cost = {
- COSTS_N_INSNS (1), /* cost of an add instruction */
- COSTS_N_INSNS (1), /* cost of a lea instruction */
- COSTS_N_INSNS (4), /* variable shift costs */
- COSTS_N_INSNS (1), /* constant shift costs */
- {COSTS_N_INSNS (11), /* cost of starting multiply for QI */
- COSTS_N_INSNS (11), /* HI */
- COSTS_N_INSNS (11), /* SI */
- COSTS_N_INSNS (11), /* DI */
- COSTS_N_INSNS (11)}, /* other */
- 0, /* cost of multiply per each bit set */
- {COSTS_N_INSNS (25), /* cost of a divide/mod for QI */
- COSTS_N_INSNS (25), /* HI */
- COSTS_N_INSNS (25), /* SI */
- COSTS_N_INSNS (25), /* DI */
- COSTS_N_INSNS (25)}, /* other */
- COSTS_N_INSNS (3), /* cost of movsx */
- COSTS_N_INSNS (2), /* cost of movzx */
- 8, /* "large" insn */
- 6, /* MOVE_RATIO */
- 6, /* cost for loading QImode using movzbl */
- {2, 4, 2}, /* cost of loading integer registers
- in QImode, HImode and SImode.
- Relative to reg-reg move (2). */
- {2, 4, 2}, /* cost of storing integer registers */
- 2, /* cost of reg,reg fld/fst */
- {2, 2, 6}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {4, 4, 6}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 8, /* 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 */
- {4, 8, 16}, /* cost of loading SSE registers
- in SImode, DImode and TImode */
- {4, 8, 16}, /* cost of storing SSE registers
- in SImode, DImode and TImode */
- 3, /* MMX or SSE register to integer */
- 8, /* size of l1 cache. */
- 8, /* size of l2 cache */
- 0, /* size of prefetch block */
- 0, /* number of parallel prefetches */
- 2, /* Branch cost */
- COSTS_N_INSNS (3), /* cost of FADD and FSUB insns. */
- COSTS_N_INSNS (3), /* cost of FMUL instruction. */
- COSTS_N_INSNS (39), /* cost of FDIV instruction. */
- COSTS_N_INSNS (1), /* cost of FABS instruction. */
- COSTS_N_INSNS (1), /* cost of FCHS instruction. */
- COSTS_N_INSNS (70), /* cost of FSQRT instruction. */
- {{libcall, {{256, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- DUMMY_STRINGOP_ALGS},
- {{libcall, {{-1, rep_prefix_4_byte, false}}},
- DUMMY_STRINGOP_ALGS},
- 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. */
-};
-
-static const
-struct processor_costs pentiumpro_cost = {
- COSTS_N_INSNS (1), /* cost of an add instruction */
- COSTS_N_INSNS (1), /* cost of a lea instruction */
- COSTS_N_INSNS (1), /* variable shift costs */
- COSTS_N_INSNS (1), /* constant shift costs */
- {COSTS_N_INSNS (4), /* cost of starting multiply for QI */
- COSTS_N_INSNS (4), /* HI */
- COSTS_N_INSNS (4), /* SI */
- COSTS_N_INSNS (4), /* DI */
- COSTS_N_INSNS (4)}, /* other */
- 0, /* cost of multiply per each bit set */
- {COSTS_N_INSNS (17), /* cost of a divide/mod for QI */
- COSTS_N_INSNS (17), /* HI */
- COSTS_N_INSNS (17), /* SI */
- COSTS_N_INSNS (17), /* DI */
- COSTS_N_INSNS (17)}, /* other */
- COSTS_N_INSNS (1), /* cost of movsx */
- COSTS_N_INSNS (1), /* cost of movzx */
- 8, /* "large" insn */
- 6, /* 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). */
- {2, 2, 2}, /* cost of storing integer registers */
- 2, /* cost of reg,reg fld/fst */
- {2, 2, 6}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {4, 4, 6}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 2, /* cost of moving MMX register */
- {2, 2}, /* cost of loading MMX registers
- in SImode and DImode */
- {2, 2}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, /* cost of moving SSE register */
- {2, 2, 8}, /* cost of loading SSE registers
- in SImode, DImode and TImode */
- {2, 2, 8}, /* cost of storing SSE registers
- in SImode, DImode and TImode */
- 3, /* MMX or SSE register to integer */
- 8, /* size of l1 cache. */
- 256, /* size of l2 cache */
- 32, /* size of prefetch block */
- 6, /* number of parallel prefetches */
- 2, /* Branch cost */
- COSTS_N_INSNS (3), /* cost of FADD and FSUB insns. */
- COSTS_N_INSNS (5), /* cost of FMUL instruction. */
- COSTS_N_INSNS (56), /* cost of FDIV instruction. */
- COSTS_N_INSNS (2), /* cost of FABS instruction. */
- COSTS_N_INSNS (2), /* cost of FCHS instruction. */
- COSTS_N_INSNS (56), /* cost of FSQRT instruction. */
- /* PentiumPro has optimized rep instructions for blocks aligned by 8 bytes
- (we ensure the alignment). For small blocks inline loop is still a
- noticeable win, for bigger blocks either rep movsl or rep movsb is
- way to go. Rep movsb has apparently more expensive startup time in CPU,
- but after 4K the difference is down in the noise. */
- {{rep_prefix_4_byte, {{128, loop, false}, {1024, unrolled_loop, false},
- {8192, rep_prefix_4_byte, false},
- {-1, rep_prefix_1_byte, false}}},
- DUMMY_STRINGOP_ALGS},
- {{rep_prefix_4_byte, {{1024, unrolled_loop, false},
- {8192, rep_prefix_4_byte, false},
- {-1, libcall, false}}},
- DUMMY_STRINGOP_ALGS},
- 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. */
-};
-
-static const
-struct processor_costs geode_cost = {
- COSTS_N_INSNS (1), /* cost of an add instruction */
- COSTS_N_INSNS (1), /* cost of a lea instruction */
- COSTS_N_INSNS (2), /* 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 (7), /* SI */
- COSTS_N_INSNS (7), /* DI */
- COSTS_N_INSNS (7)}, /* other */
- 0, /* cost of multiply per each bit set */
- {COSTS_N_INSNS (15), /* cost of a divide/mod for QI */
- COSTS_N_INSNS (23), /* HI */
- COSTS_N_INSNS (39), /* SI */
- COSTS_N_INSNS (39), /* DI */
- COSTS_N_INSNS (39)}, /* other */
- COSTS_N_INSNS (1), /* cost of movsx */
- COSTS_N_INSNS (1), /* cost of movzx */
- 8, /* "large" insn */
- 4, /* MOVE_RATIO */
- 1, /* cost for loading QImode using movzbl */
- {1, 1, 1}, /* cost of loading integer registers
- in QImode, HImode and SImode.
- Relative to reg-reg move (2). */
- {1, 1, 1}, /* cost of storing integer registers */
- 1, /* cost of reg,reg fld/fst */
- {1, 1, 1}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {4, 6, 6}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
-
- 1, /* cost of moving MMX register */
- {1, 1}, /* cost of loading MMX registers
- in SImode and DImode */
- {1, 1}, /* cost of storing MMX registers
- in SImode and DImode */
- 1, /* cost of moving SSE register */
- {1, 1, 1}, /* cost of loading SSE registers
- in SImode, DImode and TImode */
- {1, 1, 1}, /* cost of storing SSE registers
- in SImode, DImode and TImode */
- 1, /* MMX or SSE register to integer */
- 64, /* size of l1 cache. */
- 128, /* size of l2 cache. */
- 32, /* size of prefetch block */
- 1, /* number of parallel prefetches */
- 1, /* Branch cost */
- COSTS_N_INSNS (6), /* cost of FADD and FSUB insns. */
- COSTS_N_INSNS (11), /* cost of FMUL instruction. */
- COSTS_N_INSNS (47), /* cost of FDIV instruction. */
- COSTS_N_INSNS (1), /* cost of FABS instruction. */
- COSTS_N_INSNS (1), /* cost of FCHS instruction. */
- COSTS_N_INSNS (54), /* cost of FSQRT instruction. */
- {{libcall, {{256, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- DUMMY_STRINGOP_ALGS},
- {{libcall, {{256, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- DUMMY_STRINGOP_ALGS},
- 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. */
-};
-
-static const
-struct processor_costs k6_cost = {
- COSTS_N_INSNS (1), /* cost of an add instruction */
- COSTS_N_INSNS (2), /* 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 (3), /* HI */
- COSTS_N_INSNS (3), /* SI */
- COSTS_N_INSNS (3), /* DI */
- COSTS_N_INSNS (3)}, /* other */
- 0, /* cost of multiply per each bit set */
- {COSTS_N_INSNS (18), /* cost of a divide/mod for QI */
- COSTS_N_INSNS (18), /* HI */
- COSTS_N_INSNS (18), /* SI */
- COSTS_N_INSNS (18), /* DI */
- COSTS_N_INSNS (18)}, /* other */
- COSTS_N_INSNS (2), /* cost of movsx */
- COSTS_N_INSNS (2), /* cost of movzx */
- 8, /* "large" insn */
- 4, /* MOVE_RATIO */
- 3, /* cost for loading QImode using movzbl */
- {4, 5, 4}, /* cost of loading integer registers
- in QImode, HImode and SImode.
- Relative to reg-reg move (2). */
- {2, 3, 2}, /* cost of storing integer registers */
- 4, /* cost of reg,reg fld/fst */
- {6, 6, 6}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {4, 4, 4}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 2, /* cost of moving MMX register */
- {2, 2}, /* cost of loading MMX registers
- in SImode and DImode */
- {2, 2}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, /* cost of moving SSE register */
- {2, 2, 8}, /* cost of loading SSE registers
- in SImode, DImode and TImode */
- {2, 2, 8}, /* cost of storing SSE registers
- in SImode, DImode and TImode */
- 6, /* MMX or SSE register to integer */
- 32, /* size of l1 cache. */
- 32, /* size of l2 cache. Some models
- have integrated l2 cache, but
- optimizing for k6 is not important
- enough to worry about that. */
- 32, /* size of prefetch block */
- 1, /* number of parallel prefetches */
- 1, /* Branch cost */
- COSTS_N_INSNS (2), /* cost of FADD and FSUB insns. */
- COSTS_N_INSNS (2), /* cost of FMUL instruction. */
- COSTS_N_INSNS (56), /* cost of FDIV instruction. */
- COSTS_N_INSNS (2), /* cost of FABS instruction. */
- COSTS_N_INSNS (2), /* cost of FCHS instruction. */
- COSTS_N_INSNS (56), /* cost of FSQRT instruction. */
- {{libcall, {{256, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- DUMMY_STRINGOP_ALGS},
- {{libcall, {{256, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- DUMMY_STRINGOP_ALGS},
- 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. */
-};
-
-static const
-struct processor_costs athlon_cost = {
- COSTS_N_INSNS (1), /* cost of an add instruction */
- COSTS_N_INSNS (2), /* cost of a lea instruction */
- COSTS_N_INSNS (1), /* variable shift costs */
- COSTS_N_INSNS (1), /* constant shift costs */
- {COSTS_N_INSNS (5), /* cost of starting multiply for QI */
- COSTS_N_INSNS (5), /* HI */
- COSTS_N_INSNS (5), /* SI */
- COSTS_N_INSNS (5), /* DI */
- COSTS_N_INSNS (5)}, /* 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 */
- 9, /* MOVE_RATIO */
- 4, /* cost for loading QImode using movzbl */
- {3, 4, 3}, /* cost of loading integer registers
- in QImode, HImode and SImode.
- Relative to reg-reg move (2). */
- {3, 4, 3}, /* cost of storing integer registers */
- 4, /* cost of reg,reg fld/fst */
- {4, 4, 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 */
- {4, 4}, /* cost of loading MMX registers
- in SImode and DImode */
- {4, 4}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, /* cost of moving SSE register */
- {4, 4, 6}, /* cost of loading SSE registers
- in SImode, DImode and TImode */
- {4, 4, 5}, /* cost of storing SSE registers
- in SImode, DImode and TImode */
- 5, /* MMX or SSE register to integer */
- 64, /* size of l1 cache. */
- 256, /* size of l2 cache. */
- 64, /* size of prefetch block */
- 6, /* number of parallel prefetches */
- 5, /* Branch cost */
- COSTS_N_INSNS (4), /* cost of FADD and FSUB insns. */
- COSTS_N_INSNS (4), /* cost of FMUL instruction. */
- COSTS_N_INSNS (24), /* cost of FDIV instruction. */
- COSTS_N_INSNS (2), /* cost of FABS instruction. */
- COSTS_N_INSNS (2), /* cost of FCHS instruction. */
- COSTS_N_INSNS (35), /* cost of FSQRT instruction. */
- /* For some reason, Athlon deals better with REP prefix (relative to loops)
- compared to K8. Alignment becomes important after 8 bytes for memcpy and
- 128 bytes for memset. */
- {{libcall, {{2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- DUMMY_STRINGOP_ALGS},
- {{libcall, {{2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- DUMMY_STRINGOP_ALGS},
- 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. */
-};
-
-static const
-struct processor_costs k8_cost = {
- COSTS_N_INSNS (1), /* cost of an add instruction */
- COSTS_N_INSNS (2), /* 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 (5)}, /* 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 */
- 9, /* MOVE_RATIO */
- 4, /* cost for loading QImode using movzbl */
- {3, 4, 3}, /* cost of loading integer registers
- in QImode, HImode and SImode.
- Relative to reg-reg move (2). */
- {3, 4, 3}, /* cost of storing integer registers */
- 4, /* cost of reg,reg fld/fst */
- {4, 4, 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 */
- {3, 3}, /* cost of loading MMX registers
- in SImode and DImode */
- {4, 4}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, /* cost of moving SSE register */
- {4, 3, 6}, /* cost of loading SSE registers
- in SImode, DImode and TImode */
- {4, 4, 5}, /* cost of storing SSE registers
- in SImode, DImode and TImode */
- 5, /* MMX or SSE register to integer */
- 64, /* size of l1 cache. */
- 512, /* size of l2 cache. */
- 64, /* size of prefetch block */
- /* New AMD processors never drop prefetches; if they cannot be performed
- immediately, they are queued. We set number of simultaneous prefetches
- to a large constant to reflect this (it probably is not a good idea not
- to limit number of prefetches at all, as their execution also takes some
- time). */
- 100, /* number of parallel prefetches */
- 3, /* Branch cost */
- COSTS_N_INSNS (4), /* cost of FADD and FSUB insns. */
- COSTS_N_INSNS (4), /* cost of FMUL instruction. */
- COSTS_N_INSNS (19), /* cost of FDIV instruction. */
- COSTS_N_INSNS (2), /* cost of FABS instruction. */
- COSTS_N_INSNS (2), /* cost of FCHS instruction. */
- COSTS_N_INSNS (35), /* cost of FSQRT instruction. */
- /* K8 has optimized REP instruction for medium sized blocks, but for very
- small blocks it is better to use loop. For large blocks, libcall can
- do nontemporary accesses and beat inline considerably. */
- {{libcall, {{6, loop, false}, {14, unrolled_loop, false},
- {-1, rep_prefix_4_byte, false}}},
- {libcall, {{16, loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
- {{libcall, {{8, loop, false}, {24, unrolled_loop, false},
- {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- {libcall, {{48, unrolled_loop, false},
- {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}},
- 4, /* scalar_stmt_cost. */
- 2, /* scalar load_cost. */
- 2, /* scalar_store_cost. */
- 5, /* vec_stmt_cost. */
- 0, /* vec_to_scalar_cost. */
- 2, /* scalar_to_vec_cost. */
- 2, /* vec_align_load_cost. */
- 3, /* vec_unalign_load_cost. */
- 3, /* vec_store_cost. */
- 3, /* cond_taken_branch_cost. */
- 2, /* cond_not_taken_branch_cost. */
-};
-
-struct processor_costs amdfam10_cost = {
- COSTS_N_INSNS (1), /* cost of an add instruction */
- COSTS_N_INSNS (2), /* 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 (5)}, /* other */
- 0, /* cost of multiply per each bit set */
- {COSTS_N_INSNS (19), /* cost of a divide/mod for QI */
- COSTS_N_INSNS (35), /* HI */
- COSTS_N_INSNS (51), /* SI */
- COSTS_N_INSNS (83), /* DI */
- COSTS_N_INSNS (83)}, /* other */
- COSTS_N_INSNS (1), /* cost of movsx */
- COSTS_N_INSNS (1), /* cost of movzx */
- 8, /* "large" insn */
- 9, /* MOVE_RATIO */
- 4, /* cost for loading QImode using movzbl */
- {3, 4, 3}, /* cost of loading integer registers
- in QImode, HImode and SImode.
- Relative to reg-reg move (2). */
- {3, 4, 3}, /* cost of storing integer registers */
- 4, /* cost of reg,reg fld/fst */
- {4, 4, 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 */
- {3, 3}, /* cost of loading MMX registers
- in SImode and DImode */
- {4, 4}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, /* cost of moving SSE register */
- {4, 4, 3}, /* cost of loading SSE registers
- in SImode, DImode and TImode */
- {4, 4, 5}, /* cost of storing SSE registers
- in SImode, DImode and TImode */
- 3, /* MMX or SSE register to integer */
- /* On K8:
- MOVD reg64, xmmreg Double FSTORE 4
- MOVD reg32, xmmreg Double FSTORE 4
- On AMDFAM10:
- MOVD reg64, xmmreg Double FADD 3
- 1/1 1/1
- MOVD reg32, xmmreg Double FADD 3
- 1/1 1/1 */
- 64, /* size of l1 cache. */
- 512, /* size of l2 cache. */
- 64, /* size of prefetch block */
- /* New AMD processors never drop prefetches; if they cannot be performed
- immediately, they are queued. We set number of simultaneous prefetches
- to a large constant to reflect this (it probably is not a good idea not
- to limit number of prefetches at all, as their execution also takes some
- time). */
- 100, /* number of parallel prefetches */
- 2, /* Branch cost */
- COSTS_N_INSNS (4), /* cost of FADD and FSUB insns. */
- COSTS_N_INSNS (4), /* cost of FMUL instruction. */
- COSTS_N_INSNS (19), /* cost of FDIV instruction. */
- COSTS_N_INSNS (2), /* cost of FABS instruction. */
- COSTS_N_INSNS (2), /* cost of FCHS instruction. */
- COSTS_N_INSNS (35), /* cost of FSQRT instruction. */
-
- /* AMDFAM10 has optimized REP instruction for medium sized blocks, but for
- very small blocks it is better to use loop. For large blocks, libcall can
- do nontemporary accesses and beat inline considerably. */
- {{libcall, {{6, loop, false}, {14, unrolled_loop, false},
- {-1, rep_prefix_4_byte, false}}},
- {libcall, {{16, loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
- {{libcall, {{8, loop, false}, {24, unrolled_loop, false},
- {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- {libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
- 4, /* scalar_stmt_cost. */
- 2, /* scalar load_cost. */
- 2, /* scalar_store_cost. */
- 6, /* vec_stmt_cost. */
- 0, /* vec_to_scalar_cost. */
- 2, /* scalar_to_vec_cost. */
- 2, /* vec_align_load_cost. */
- 2, /* vec_unalign_load_cost. */
- 2, /* vec_store_cost. */
- 2, /* cond_taken_branch_cost. */
- 1, /* cond_not_taken_branch_cost. */
-};
-
-struct processor_costs bdver1_cost = {
- COSTS_N_INSNS (1), /* cost of an add instruction */
- COSTS_N_INSNS (1), /* cost of a lea instruction */
- COSTS_N_INSNS (1), /* variable shift costs */
- COSTS_N_INSNS (1), /* constant shift costs */
- {COSTS_N_INSNS (4), /* cost of starting multiply for QI */
- COSTS_N_INSNS (4), /* HI */
- COSTS_N_INSNS (4), /* SI */
- COSTS_N_INSNS (6), /* DI */
- COSTS_N_INSNS (6)}, /* other */
- 0, /* cost of multiply per each bit set */
- {COSTS_N_INSNS (19), /* cost of a divide/mod for QI */
- COSTS_N_INSNS (35), /* HI */
- COSTS_N_INSNS (51), /* SI */
- COSTS_N_INSNS (83), /* DI */
- COSTS_N_INSNS (83)}, /* other */
- COSTS_N_INSNS (1), /* cost of movsx */
- COSTS_N_INSNS (1), /* cost of movzx */
- 8, /* "large" insn */
- 9, /* MOVE_RATIO */
- 4, /* cost for loading QImode using movzbl */
- {5, 5, 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 */
- 2, /* cost of reg,reg fld/fst */
- {5, 5, 12}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {4, 4, 8}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 2, /* cost of moving MMX register */
- {4, 4}, /* cost of loading MMX registers
- in SImode and DImode */
- {4, 4}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, /* cost of moving SSE register */
- {4, 4, 4}, /* cost of loading SSE registers
- in SImode, DImode and TImode */
- {4, 4, 4}, /* cost of storing SSE registers
- in SImode, DImode and TImode */
- 2, /* MMX or SSE register to integer */
- /* On K8:
- MOVD reg64, xmmreg Double FSTORE 4
- MOVD reg32, xmmreg Double FSTORE 4
- On AMDFAM10:
- MOVD reg64, xmmreg Double FADD 3
- 1/1 1/1
- MOVD reg32, xmmreg Double FADD 3
- 1/1 1/1 */
- 16, /* size of l1 cache. */
- 2048, /* size of l2 cache. */
- 64, /* size of prefetch block */
- /* New AMD processors never drop prefetches; if they cannot be performed
- immediately, they are queued. We set number of simultaneous prefetches
- to a large constant to reflect this (it probably is not a good idea not
- to limit number of prefetches at all, as their execution also takes some
- time). */
- 100, /* number of parallel prefetches */
- 2, /* Branch cost */
- COSTS_N_INSNS (6), /* cost of FADD and FSUB insns. */
- COSTS_N_INSNS (6), /* cost of FMUL instruction. */
- COSTS_N_INSNS (42), /* cost of FDIV instruction. */
- COSTS_N_INSNS (2), /* cost of FABS instruction. */
- COSTS_N_INSNS (2), /* cost of FCHS instruction. */
- COSTS_N_INSNS (52), /* cost of FSQRT instruction. */
-
- /* BDVER1 has optimized REP instruction for medium sized blocks, but for
- very small blocks it is better to use loop. For large blocks, libcall
- can do nontemporary accesses and beat inline considerably. */
- {{libcall, {{6, loop, false}, {14, unrolled_loop, false},
- {-1, rep_prefix_4_byte, false}}},
- {libcall, {{16, loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
- {{libcall, {{8, loop, false}, {24, unrolled_loop, false},
- {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- {libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
- 6, /* scalar_stmt_cost. */
- 4, /* scalar load_cost. */
- 4, /* scalar_store_cost. */
- 6, /* vec_stmt_cost. */
- 0, /* vec_to_scalar_cost. */
- 2, /* scalar_to_vec_cost. */
- 4, /* vec_align_load_cost. */
- 4, /* vec_unalign_load_cost. */
- 4, /* vec_store_cost. */
- 2, /* cond_taken_branch_cost. */
- 1, /* cond_not_taken_branch_cost. */
-};
-
-struct processor_costs bdver2_cost = {
- COSTS_N_INSNS (1), /* cost of an add instruction */
- COSTS_N_INSNS (1), /* cost of a lea instruction */
- COSTS_N_INSNS (1), /* variable shift costs */
- COSTS_N_INSNS (1), /* constant shift costs */
- {COSTS_N_INSNS (4), /* cost of starting multiply for QI */
- COSTS_N_INSNS (4), /* HI */
- COSTS_N_INSNS (4), /* SI */
- COSTS_N_INSNS (6), /* DI */
- COSTS_N_INSNS (6)}, /* other */
- 0, /* cost of multiply per each bit set */
- {COSTS_N_INSNS (19), /* cost of a divide/mod for QI */
- COSTS_N_INSNS (35), /* HI */
- COSTS_N_INSNS (51), /* SI */
- COSTS_N_INSNS (83), /* DI */
- COSTS_N_INSNS (83)}, /* other */
- COSTS_N_INSNS (1), /* cost of movsx */
- COSTS_N_INSNS (1), /* cost of movzx */
- 8, /* "large" insn */
- 9, /* MOVE_RATIO */
- 4, /* cost for loading QImode using movzbl */
- {5, 5, 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 */
- 2, /* cost of reg,reg fld/fst */
- {5, 5, 12}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {4, 4, 8}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 2, /* cost of moving MMX register */
- {4, 4}, /* cost of loading MMX registers
- in SImode and DImode */
- {4, 4}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, /* cost of moving SSE register */
- {4, 4, 4}, /* cost of loading SSE registers
- in SImode, DImode and TImode */
- {4, 4, 4}, /* cost of storing SSE registers
- in SImode, DImode and TImode */
- 2, /* MMX or SSE register to integer */
- /* On K8:
- MOVD reg64, xmmreg Double FSTORE 4
- MOVD reg32, xmmreg Double FSTORE 4
- On AMDFAM10:
- MOVD reg64, xmmreg Double FADD 3
- 1/1 1/1
- MOVD reg32, xmmreg Double FADD 3
- 1/1 1/1 */
- 16, /* size of l1 cache. */
- 2048, /* size of l2 cache. */
- 64, /* size of prefetch block */
- /* New AMD processors never drop prefetches; if they cannot be performed
- immediately, they are queued. We set number of simultaneous prefetches
- to a large constant to reflect this (it probably is not a good idea not
- to limit number of prefetches at all, as their execution also takes some
- time). */
- 100, /* number of parallel prefetches */
- 2, /* Branch cost */
- COSTS_N_INSNS (6), /* cost of FADD and FSUB insns. */
- COSTS_N_INSNS (6), /* cost of FMUL instruction. */
- COSTS_N_INSNS (42), /* cost of FDIV instruction. */
- COSTS_N_INSNS (2), /* cost of FABS instruction. */
- COSTS_N_INSNS (2), /* cost of FCHS instruction. */
- COSTS_N_INSNS (52), /* cost of FSQRT instruction. */
-
- /* BDVER2 has optimized REP instruction for medium sized blocks, but for
- very small blocks it is better to use loop. For large blocks, libcall
- can do nontemporary accesses and beat inline considerably. */
- {{libcall, {{6, loop, false}, {14, unrolled_loop, false},
- {-1, rep_prefix_4_byte, false}}},
- {libcall, {{16, loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
- {{libcall, {{8, loop, false}, {24, unrolled_loop, false},
- {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- {libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
- 6, /* scalar_stmt_cost. */
- 4, /* scalar load_cost. */
- 4, /* scalar_store_cost. */
- 6, /* vec_stmt_cost. */
- 0, /* vec_to_scalar_cost. */
- 2, /* scalar_to_vec_cost. */
- 4, /* vec_align_load_cost. */
- 4, /* vec_unalign_load_cost. */
- 4, /* vec_store_cost. */
- 2, /* cond_taken_branch_cost. */
- 1, /* cond_not_taken_branch_cost. */
-};
-
-struct processor_costs bdver3_cost = {
- COSTS_N_INSNS (1), /* cost of an add instruction */
- COSTS_N_INSNS (1), /* cost of a lea instruction */
- COSTS_N_INSNS (1), /* variable shift costs */
- COSTS_N_INSNS (1), /* constant shift costs */
- {COSTS_N_INSNS (4), /* cost of starting multiply for QI */
- COSTS_N_INSNS (4), /* HI */
- COSTS_N_INSNS (4), /* SI */
- COSTS_N_INSNS (6), /* DI */
- COSTS_N_INSNS (6)}, /* other */
- 0, /* cost of multiply per each bit set */
- {COSTS_N_INSNS (19), /* cost of a divide/mod for QI */
- COSTS_N_INSNS (35), /* HI */
- COSTS_N_INSNS (51), /* SI */
- COSTS_N_INSNS (83), /* DI */
- COSTS_N_INSNS (83)}, /* other */
- COSTS_N_INSNS (1), /* cost of movsx */
- COSTS_N_INSNS (1), /* cost of movzx */
- 8, /* "large" insn */
- 9, /* MOVE_RATIO */
- 4, /* cost for loading QImode using movzbl */
- {5, 5, 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 */
- 2, /* cost of reg,reg fld/fst */
- {5, 5, 12}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {4, 4, 8}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 2, /* cost of moving MMX register */
- {4, 4}, /* cost of loading MMX registers
- in SImode and DImode */
- {4, 4}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, /* cost of moving SSE register */
- {4, 4, 4}, /* cost of loading SSE registers
- in SImode, DImode and TImode */
- {4, 4, 4}, /* cost of storing SSE registers
- in SImode, DImode and TImode */
- 2, /* MMX or SSE register to integer */
- 16, /* size of l1 cache. */
- 2048, /* size of l2 cache. */
- 64, /* size of prefetch block */
- /* New AMD processors never drop prefetches; if they cannot be performed
- immediately, they are queued. We set number of simultaneous prefetches
- to a large constant to reflect this (it probably is not a good idea not
- to limit number of prefetches at all, as their execution also takes some
- time). */
- 100, /* number of parallel prefetches */
- 2, /* Branch cost */
- COSTS_N_INSNS (6), /* cost of FADD and FSUB insns. */
- COSTS_N_INSNS (6), /* cost of FMUL instruction. */
- COSTS_N_INSNS (42), /* cost of FDIV instruction. */
- COSTS_N_INSNS (2), /* cost of FABS instruction. */
- COSTS_N_INSNS (2), /* cost of FCHS instruction. */
- COSTS_N_INSNS (52), /* cost of FSQRT instruction. */
-
- /* BDVER3 has optimized REP instruction for medium sized blocks, but for
- very small blocks it is better to use loop. For large blocks, libcall
- can do nontemporary accesses and beat inline considerably. */
- {{libcall, {{6, loop, false}, {14, unrolled_loop, false},
- {-1, rep_prefix_4_byte, false}}},
- {libcall, {{16, loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
- {{libcall, {{8, loop, false}, {24, unrolled_loop, false},
- {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- {libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
- 6, /* scalar_stmt_cost. */
- 4, /* scalar load_cost. */
- 4, /* scalar_store_cost. */
- 6, /* vec_stmt_cost. */
- 0, /* vec_to_scalar_cost. */
- 2, /* scalar_to_vec_cost. */
- 4, /* vec_align_load_cost. */
- 4, /* vec_unalign_load_cost. */
- 4, /* vec_store_cost. */
- 2, /* cond_taken_branch_cost. */
- 1, /* cond_not_taken_branch_cost. */
-};
-
-struct processor_costs btver1_cost = {
- COSTS_N_INSNS (1), /* cost of an add instruction */
- COSTS_N_INSNS (2), /* 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 (5)}, /* other */
- 0, /* cost of multiply per each bit set */
- {COSTS_N_INSNS (19), /* cost of a divide/mod for QI */
- COSTS_N_INSNS (35), /* HI */
- COSTS_N_INSNS (51), /* SI */
- COSTS_N_INSNS (83), /* DI */
- COSTS_N_INSNS (83)}, /* other */
- COSTS_N_INSNS (1), /* cost of movsx */
- COSTS_N_INSNS (1), /* cost of movzx */
- 8, /* "large" insn */
- 9, /* MOVE_RATIO */
- 4, /* cost for loading QImode using movzbl */
- {3, 4, 3}, /* cost of loading integer registers
- in QImode, HImode and SImode.
- Relative to reg-reg move (2). */
- {3, 4, 3}, /* cost of storing integer registers */
- 4, /* cost of reg,reg fld/fst */
- {4, 4, 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 */
- {3, 3}, /* cost of loading MMX registers
- in SImode and DImode */
- {4, 4}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, /* cost of moving SSE register */
- {4, 4, 3}, /* cost of loading SSE registers
- in SImode, DImode and TImode */
- {4, 4, 5}, /* cost of storing SSE registers
- in SImode, DImode and TImode */
- 3, /* MMX or SSE register to integer */
- /* On K8:
- MOVD reg64, xmmreg Double FSTORE 4
- MOVD reg32, xmmreg Double FSTORE 4
- On AMDFAM10:
- MOVD reg64, xmmreg Double FADD 3
- 1/1 1/1
- MOVD reg32, xmmreg Double FADD 3
- 1/1 1/1 */
- 32, /* size of l1 cache. */
- 512, /* size of l2 cache. */
- 64, /* size of prefetch block */
- 100, /* number of parallel prefetches */
- 2, /* Branch cost */
- COSTS_N_INSNS (4), /* cost of FADD and FSUB insns. */
- COSTS_N_INSNS (4), /* cost of FMUL instruction. */
- COSTS_N_INSNS (19), /* cost of FDIV instruction. */
- COSTS_N_INSNS (2), /* cost of FABS instruction. */
- COSTS_N_INSNS (2), /* cost of FCHS instruction. */
- COSTS_N_INSNS (35), /* cost of FSQRT instruction. */
-
- /* BTVER1 has optimized REP instruction for medium sized blocks, but for
- very small blocks it is better to use loop. For large blocks, libcall can
- do nontemporary accesses and beat inline considerably. */
- {{libcall, {{6, loop, false}, {14, unrolled_loop, false},
- {-1, rep_prefix_4_byte, false}}},
- {libcall, {{16, loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
- {{libcall, {{8, loop, false}, {24, unrolled_loop, false},
- {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- {libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
- 4, /* scalar_stmt_cost. */
- 2, /* scalar load_cost. */
- 2, /* scalar_store_cost. */
- 6, /* vec_stmt_cost. */
- 0, /* vec_to_scalar_cost. */
- 2, /* scalar_to_vec_cost. */
- 2, /* vec_align_load_cost. */
- 2, /* vec_unalign_load_cost. */
- 2, /* vec_store_cost. */
- 2, /* cond_taken_branch_cost. */
- 1, /* cond_not_taken_branch_cost. */
-};
-
-struct processor_costs btver2_cost = {
- COSTS_N_INSNS (1), /* cost of an add instruction */
- COSTS_N_INSNS (2), /* 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 (5)}, /* other */
- 0, /* cost of multiply per each bit set */
- {COSTS_N_INSNS (19), /* cost of a divide/mod for QI */
- COSTS_N_INSNS (35), /* HI */
- COSTS_N_INSNS (51), /* SI */
- COSTS_N_INSNS (83), /* DI */
- COSTS_N_INSNS (83)}, /* other */
- COSTS_N_INSNS (1), /* cost of movsx */
- COSTS_N_INSNS (1), /* cost of movzx */
- 8, /* "large" insn */
- 9, /* MOVE_RATIO */
- 4, /* cost for loading QImode using movzbl */
- {3, 4, 3}, /* cost of loading integer registers
- in QImode, HImode and SImode.
- Relative to reg-reg move (2). */
- {3, 4, 3}, /* cost of storing integer registers */
- 4, /* cost of reg,reg fld/fst */
- {4, 4, 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 */
- {3, 3}, /* cost of loading MMX registers
- in SImode and DImode */
- {4, 4}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, /* cost of moving SSE register */
- {4, 4, 3}, /* cost of loading SSE registers
- in SImode, DImode and TImode */
- {4, 4, 5}, /* cost of storing SSE registers
- in SImode, DImode and TImode */
- 3, /* MMX or SSE register to integer */
- /* On K8:
- MOVD reg64, xmmreg Double FSTORE 4
- MOVD reg32, xmmreg Double FSTORE 4
- On AMDFAM10:
- MOVD reg64, xmmreg Double FADD 3
- 1/1 1/1
- MOVD reg32, xmmreg Double FADD 3
- 1/1 1/1 */
- 32, /* size of l1 cache. */
- 2048, /* size of l2 cache. */
- 64, /* size of prefetch block */
- 100, /* number of parallel prefetches */
- 2, /* Branch cost */
- COSTS_N_INSNS (4), /* cost of FADD and FSUB insns. */
- COSTS_N_INSNS (4), /* cost of FMUL instruction. */
- COSTS_N_INSNS (19), /* cost of FDIV instruction. */
- COSTS_N_INSNS (2), /* cost of FABS instruction. */
- COSTS_N_INSNS (2), /* cost of FCHS instruction. */
- COSTS_N_INSNS (35), /* cost of FSQRT instruction. */
-
- {{libcall, {{6, loop, false}, {14, unrolled_loop, false},
- {-1, rep_prefix_4_byte, false}}},
- {libcall, {{16, loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
- {{libcall, {{8, loop, false}, {24, unrolled_loop, false},
- {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- {libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
- 4, /* scalar_stmt_cost. */
- 2, /* scalar load_cost. */
- 2, /* scalar_store_cost. */
- 6, /* vec_stmt_cost. */
- 0, /* vec_to_scalar_cost. */
- 2, /* scalar_to_vec_cost. */
- 2, /* vec_align_load_cost. */
- 2, /* vec_unalign_load_cost. */
- 2, /* vec_store_cost. */
- 2, /* cond_taken_branch_cost. */
- 1, /* cond_not_taken_branch_cost. */
-};
-
-static const
-struct processor_costs pentium4_cost = {
- COSTS_N_INSNS (1), /* cost of an add instruction */
- COSTS_N_INSNS (3), /* cost of a lea instruction */
- COSTS_N_INSNS (4), /* variable shift costs */
- COSTS_N_INSNS (4), /* constant shift costs */
- {COSTS_N_INSNS (15), /* cost of starting multiply for QI */
- COSTS_N_INSNS (15), /* HI */
- COSTS_N_INSNS (15), /* SI */
- COSTS_N_INSNS (15), /* DI */
- COSTS_N_INSNS (15)}, /* other */
- 0, /* cost of multiply per each bit set */
- {COSTS_N_INSNS (56), /* cost of a divide/mod for QI */
- COSTS_N_INSNS (56), /* HI */
- COSTS_N_INSNS (56), /* SI */
- COSTS_N_INSNS (56), /* DI */
- COSTS_N_INSNS (56)}, /* other */
- COSTS_N_INSNS (1), /* cost of movsx */
- COSTS_N_INSNS (1), /* cost of movzx */
- 16, /* "large" insn */
- 6, /* MOVE_RATIO */
- 2, /* cost for loading QImode using movzbl */
- {4, 5, 4}, /* cost of loading integer registers
- in QImode, HImode and SImode.
- Relative to reg-reg move (2). */
- {2, 3, 2}, /* cost of storing integer registers */
- 2, /* cost of reg,reg fld/fst */
- {2, 2, 6}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {4, 4, 6}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 2, /* cost of moving MMX register */
- {2, 2}, /* cost of loading MMX registers
- in SImode and DImode */
- {2, 2}, /* cost of storing MMX registers
- in SImode and DImode */
- 12, /* cost of moving SSE register */
- {12, 12, 12}, /* cost of loading SSE registers
- in SImode, DImode and TImode */
- {2, 2, 8}, /* cost of storing SSE registers
- in SImode, DImode and TImode */
- 10, /* MMX or SSE register to integer */
- 8, /* size of l1 cache. */
- 256, /* size of l2 cache. */
- 64, /* size of prefetch block */
- 6, /* number of parallel prefetches */
- 2, /* Branch cost */
- COSTS_N_INSNS (5), /* cost of FADD and FSUB insns. */
- COSTS_N_INSNS (7), /* cost of FMUL instruction. */
- COSTS_N_INSNS (43), /* cost of FDIV instruction. */
- COSTS_N_INSNS (2), /* cost of FABS instruction. */
- COSTS_N_INSNS (2), /* cost of FCHS instruction. */
- COSTS_N_INSNS (43), /* cost of FSQRT instruction. */
- {{libcall, {{12, loop_1_byte, false}, {-1, rep_prefix_4_byte, false}}},
- DUMMY_STRINGOP_ALGS},
- {{libcall, {{6, loop_1_byte, false}, {48, loop, false},
- {20480, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- DUMMY_STRINGOP_ALGS},
- 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. */
-};
-
-static const
-struct processor_costs nocona_cost = {
- COSTS_N_INSNS (1), /* cost of an add instruction */
- COSTS_N_INSNS (1), /* cost of a lea instruction */
- COSTS_N_INSNS (1), /* variable shift costs */
- COSTS_N_INSNS (1), /* constant shift costs */
- {COSTS_N_INSNS (10), /* cost of starting multiply for QI */
- COSTS_N_INSNS (10), /* HI */
- COSTS_N_INSNS (10), /* SI */
- COSTS_N_INSNS (10), /* DI */
- COSTS_N_INSNS (10)}, /* other */
- 0, /* cost of multiply per each bit set */
- {COSTS_N_INSNS (66), /* cost of a divide/mod for QI */
- COSTS_N_INSNS (66), /* HI */
- COSTS_N_INSNS (66), /* SI */
- COSTS_N_INSNS (66), /* DI */
- COSTS_N_INSNS (66)}, /* other */
- COSTS_N_INSNS (1), /* cost of movsx */
- COSTS_N_INSNS (1), /* cost of movzx */
- 16, /* "large" insn */
- 17, /* MOVE_RATIO */
- 4, /* 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 */
- 3, /* cost of reg,reg fld/fst */
- {12, 12, 12}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {4, 4, 4}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 6, /* cost of moving MMX register */
- {12, 12}, /* cost of loading MMX registers
- in SImode and DImode */
- {12, 12}, /* cost of storing MMX registers
- in SImode and DImode */
- 6, /* cost of moving SSE register */
- {12, 12, 12}, /* cost of loading SSE registers
- in SImode, DImode and TImode */
- {12, 12, 12}, /* cost of storing SSE registers
- in SImode, DImode and TImode */
- 8, /* MMX or SSE register to integer */
- 8, /* size of l1 cache. */
- 1024, /* size of l2 cache. */
- 128, /* size of prefetch block */
- 8, /* number of parallel prefetches */
- 1, /* Branch cost */
- COSTS_N_INSNS (6), /* cost of FADD and FSUB insns. */
- COSTS_N_INSNS (8), /* cost of FMUL instruction. */
- COSTS_N_INSNS (40), /* cost of FDIV instruction. */
- COSTS_N_INSNS (3), /* cost of FABS instruction. */
- COSTS_N_INSNS (3), /* cost of FCHS instruction. */
- COSTS_N_INSNS (44), /* cost of FSQRT instruction. */
- {{libcall, {{12, loop_1_byte, false}, {-1, rep_prefix_4_byte, false}}},
- {libcall, {{32, loop, false}, {20000, rep_prefix_8_byte, false},
- {100000, unrolled_loop, false}, {-1, libcall, false}}}},
- {{libcall, {{6, loop_1_byte, false}, {48, loop, false},
- {20480, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- {libcall, {{24, loop, false}, {64, unrolled_loop, false},
- {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}},
- 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. */
-};
-
-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 */
- 4, /* 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, false}, {-1, rep_prefix_4_byte, false}}},
- {libcall, {{32, loop, false}, {64, rep_prefix_4_byte, false},
- {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}},
- {{libcall, {{8, loop, false}, {15, unrolled_loop, false},
- {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- {libcall, {{24, loop, false}, {32, unrolled_loop, false},
- {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}},
- 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. */
-};
-
-static const
-struct processor_costs slm_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 */
- 4, /* 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, false}, {-1, rep_prefix_4_byte, false}}},
- {libcall, {{32, loop, false}, {64, rep_prefix_4_byte, false},
- {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}},
- {{libcall, {{8, loop, false}, {15, unrolled_loop, false},
- {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- {libcall, {{24, loop, false}, {32, unrolled_loop, false},
- {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}},
- 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 = {
- COSTS_N_INSNS (1), /* cost of an add instruction */
- /* On all chips taken into consideration lea is 2 cycles and more. With
- this cost however our current implementation of synth_mult results in
- use of unnecessary temporary registers causing regression on several
- SPECfp benchmarks. */
- 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 */
- 4, /* 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. */
- 512, /* size of l2 cache. */
- 64, /* size of prefetch block */
- 6, /* number of parallel prefetches */
- /* Benchmarks shows large regressions on K8 sixtrack benchmark when this
- value is increased to perhaps more appropriate value of 5. */
- 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. */
- {DUMMY_STRINGOP_ALGS,
- {libcall, {{32, loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
- {DUMMY_STRINGOP_ALGS,
- {libcall, {{32, loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
- 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. */
-};
-
-/* core_cost should produce code tuned for Core familly of CPUs. */
-static const
-struct processor_costs core_cost = {
- COSTS_N_INSNS (1), /* cost of an add instruction */
- /* On all chips taken into consideration lea is 2 cycles and more. With
- this cost however our current implementation of synth_mult results in
- use of unnecessary temporary registers causing regression on several
- SPECfp benchmarks. */
- 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 */
- 4, /* 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 */
- 64, /* size of l1 cache. */
- 512, /* size of l2 cache. */
- 64, /* size of prefetch block */
- 6, /* number of parallel prefetches */
- /* FIXME perhaps more appropriate value is 5. */
- 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, {{1024, rep_prefix_4_byte, true}, {-1, libcall, false}}},
- {libcall, {{24, loop, true}, {128, rep_prefix_8_byte, true},
- {-1, libcall, false}}}},
- {{libcall, {{6, loop_1_byte, true},
- {24, loop, true},
- {8192, rep_prefix_4_byte, true},
- {-1, libcall, false}}},
- {libcall, {{24, loop, true}, {512, rep_prefix_8_byte, true},
- {-1, libcall, false}}}},
- 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. */
-};
-
-/* Generic32 should produce code tuned for PPro, Pentium4, Nocona,
- Athlon and K8. */
-static const
-struct processor_costs generic32_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 */
- 4, /* 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, {{32, loop, false}, {8192, rep_prefix_4_byte, false},
- {-1, libcall, false}}},
- DUMMY_STRINGOP_ALGS},
- {{libcall, {{32, loop, false}, {8192, rep_prefix_4_byte, false},
- {-1, libcall, false}}},
- DUMMY_STRINGOP_ALGS},
- 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. */
-};
-
-/* Set by -mtune. */
-const struct processor_costs *ix86_tune_cost = &pentium_cost;
-
-/* Set by -mtune or -Os. */
-const struct processor_costs *ix86_cost = &pentium_cost;
-
-/* Processor feature/optimization bitmasks. */
-#define m_386 (1<<PROCESSOR_I386)
-#define m_486 (1<<PROCESSOR_I486)
-#define m_PENT (1<<PROCESSOR_PENTIUM)
-#define m_PPRO (1<<PROCESSOR_PENTIUMPRO)
-#define m_PENT4 (1<<PROCESSOR_PENTIUM4)
-#define m_NOCONA (1<<PROCESSOR_NOCONA)
-#define m_P4_NOCONA (m_PENT4 | m_NOCONA)
-#define m_CORE2 (1<<PROCESSOR_CORE2)
-#define m_COREI7 (1<<PROCESSOR_COREI7)
-#define m_HASWELL (1<<PROCESSOR_HASWELL)
-#define m_CORE_ALL (m_CORE2 | m_COREI7 | m_HASWELL)
-#define m_ATOM (1<<PROCESSOR_ATOM)
-#define m_SLM (1<<PROCESSOR_SLM)
-
-#define m_GEODE (1<<PROCESSOR_GEODE)
-#define m_K6 (1<<PROCESSOR_K6)
-#define m_K6_GEODE (m_K6 | m_GEODE)
-#define m_K8 (1<<PROCESSOR_K8)
-#define m_ATHLON (1<<PROCESSOR_ATHLON)
-#define m_ATHLON_K8 (m_K8 | m_ATHLON)
-#define m_AMDFAM10 (1<<PROCESSOR_AMDFAM10)
-#define m_BDVER1 (1<<PROCESSOR_BDVER1)
-#define m_BDVER2 (1<<PROCESSOR_BDVER2)
-#define m_BDVER3 (1<<PROCESSOR_BDVER3)
-#define m_BTVER1 (1<<PROCESSOR_BTVER1)
-#define m_BTVER2 (1<<PROCESSOR_BTVER2)
-#define m_BDVER (m_BDVER1 | m_BDVER2 | m_BDVER3)
-#define m_BTVER (m_BTVER1 | m_BTVER2)
-#define m_AMD_MULTIPLE (m_ATHLON_K8 | m_AMDFAM10 | m_BDVER | m_BTVER)
-
-#define m_GENERIC32 (1<<PROCESSOR_GENERIC32)
-#define m_GENERIC64 (1<<PROCESSOR_GENERIC64)
-
-/* Generic instruction choice should be common subset of supported CPUs
- (PPro/PENT4/NOCONA/CORE2/Athlon/K8). */
-#define m_GENERIC (m_GENERIC32 | m_GENERIC64)
-
-/* Feature tests against the various tunings. */
-unsigned char ix86_tune_features[X86_TUNE_LAST];
-
-/* Feature tests against the various tunings used to create ix86_tune_features
- based on the processor mask. */
-static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
- /* X86_TUNE_USE_LEAVE: Leave does not affect Nocona SPEC2000 results
- negatively, so enabling for Generic64 seems like good code size
- tradeoff. We can't enable it for 32bit generic because it does not
- work well with PPro base chips. */
- m_386 | m_CORE_ALL | m_K6_GEODE | m_AMD_MULTIPLE | m_GENERIC64,
-
- /* X86_TUNE_PUSH_MEMORY */
- m_386 | m_P4_NOCONA | m_CORE_ALL | m_K6_GEODE | m_AMD_MULTIPLE | m_GENERIC,
-
- /* X86_TUNE_ZERO_EXTEND_WITH_AND */
- m_486 | m_PENT,
-
- /* X86_TUNE_UNROLL_STRLEN */
- m_486 | m_PENT | m_PPRO | m_ATOM | m_SLM | m_CORE_ALL | m_K6 | m_AMD_MULTIPLE | m_GENERIC,
-
- /* X86_TUNE_BRANCH_PREDICTION_HINTS: Branch hints were put in P4 based
- on simulation result. But after P4 was made, no performance benefit
- was observed with branch hints. It also increases the code size.
- As a result, icc never generates branch hints. */
- 0,
-
- /* X86_TUNE_DOUBLE_WITH_ADD */
- ~m_386,
-
- /* X86_TUNE_USE_SAHF */
- m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_K6_GEODE | m_K8 | m_AMDFAM10 | m_BDVER | m_BTVER | m_GENERIC,
-
- /* X86_TUNE_MOVX: Enable to zero extend integer registers to avoid
- partial dependencies. */
- m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_GEODE | m_AMD_MULTIPLE | m_GENERIC,
-
- /* X86_TUNE_PARTIAL_REG_STALL: We probably ought to watch for partial
- register stalls on Generic32 compilation setting as well. However
- in current implementation the partial register stalls are not eliminated
- very well - they can be introduced via subregs synthesized by combine
- and can happen in caller/callee saving sequences. Because this option
- pays back little on PPro based chips and is in conflict with partial reg
- dependencies used by Athlon/P4 based chips, it is better to leave it off
- for generic32 for now. */
- m_PPRO,
-
- /* X86_TUNE_PARTIAL_FLAG_REG_STALL */
- m_CORE_ALL | m_GENERIC,
-
- /* X86_TUNE_LCP_STALL: Avoid an expensive length-changing prefix stall
- * on 16-bit immediate moves into memory on Core2 and Corei7. */
- m_CORE_ALL | m_GENERIC,
-
- /* X86_TUNE_USE_HIMODE_FIOP */
- m_386 | m_486 | m_K6_GEODE,
-
- /* X86_TUNE_USE_SIMODE_FIOP */
- ~(m_PENT | m_PPRO | m_CORE_ALL | m_ATOM | m_SLM | m_AMD_MULTIPLE | m_GENERIC),
-
- /* X86_TUNE_USE_MOV0 */
- m_K6,
-
- /* X86_TUNE_USE_CLTD */
- ~(m_PENT | m_ATOM | m_SLM | m_K6),
-
- /* X86_TUNE_USE_XCHGB: Use xchgb %rh,%rl instead of rolw/rorw $8,rx. */
- m_PENT4,
-
- /* X86_TUNE_SPLIT_LONG_MOVES */
- m_PPRO,
-
- /* X86_TUNE_READ_MODIFY_WRITE */
- ~m_PENT,
-
- /* X86_TUNE_READ_MODIFY */
- ~(m_PENT | m_PPRO),
-
- /* X86_TUNE_PROMOTE_QIMODE */
- m_386 | m_486 | m_PENT | m_CORE_ALL | m_ATOM | m_SLM | m_K6_GEODE | m_AMD_MULTIPLE | m_GENERIC,
-
- /* X86_TUNE_FAST_PREFIX */
- ~(m_386 | m_486 | m_PENT),
-
- /* X86_TUNE_SINGLE_STRINGOP */
- m_386 | m_P4_NOCONA,
-
- /* X86_TUNE_QIMODE_MATH */
- ~0,
-
- /* X86_TUNE_HIMODE_MATH: On PPro this flag is meant to avoid partial
- register stalls. Just like X86_TUNE_PARTIAL_REG_STALL this option
- might be considered for Generic32 if our scheme for avoiding partial
- stalls was more effective. */
- ~m_PPRO,
-
- /* X86_TUNE_PROMOTE_QI_REGS */
- 0,
-
- /* X86_TUNE_PROMOTE_HI_REGS */
- m_PPRO,
-
- /* X86_TUNE_SINGLE_POP: Enable if single pop insn is preferred
- over esp addition. */
- m_386 | m_486 | m_PENT | m_PPRO,
-
- /* X86_TUNE_DOUBLE_POP: Enable if double pop insn is preferred
- over esp addition. */
- m_PENT,
-
- /* X86_TUNE_SINGLE_PUSH: Enable if single push insn is preferred
- over esp subtraction. */
- m_386 | m_486 | m_PENT | m_K6_GEODE,
-
- /* X86_TUNE_DOUBLE_PUSH. Enable if double push insn is preferred
- over esp subtraction. */
- m_PENT | m_K6_GEODE,
-
- /* X86_TUNE_INTEGER_DFMODE_MOVES: Enable if integer moves are preferred
- for DFmode copies */
- ~(m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_GEODE | m_AMD_MULTIPLE | m_GENERIC),
-
- /* X86_TUNE_PARTIAL_REG_DEPENDENCY */
- m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_AMD_MULTIPLE | m_GENERIC,
-
- /* X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY: In the Generic model we have a
- conflict here in between PPro/Pentium4 based chips that thread 128bit
- SSE registers as single units versus K8 based chips that divide SSE
- registers to two 64bit halves. This knob promotes all store destinations
- to be 128bit to allow register renaming on 128bit SSE units, but usually
- results in one extra microop on 64bit SSE units. Experimental results
- shows that disabling this option on P4 brings over 20% SPECfp regression,
- while enabling it on K8 brings roughly 2.4% regression that can be partly
- masked by careful scheduling of moves. */
- m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_AMDFAM10 | m_BDVER | m_GENERIC,
-
- /* X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL */
- m_COREI7 | m_AMDFAM10 | m_BDVER | m_BTVER | m_SLM,
-
- /* X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL */
- m_COREI7 | m_BDVER | m_SLM,
-
- /* X86_TUNE_SSE_PACKED_SINGLE_INSN_OPTIMAL */
- m_BDVER ,
-
- /* X86_TUNE_SSE_SPLIT_REGS: Set for machines where the type and dependencies
- are resolved on SSE register parts instead of whole registers, so we may
- maintain just lower part of scalar values in proper format leaving the
- upper part undefined. */
- m_ATHLON_K8,
-
- /* X86_TUNE_SSE_TYPELESS_STORES */
- m_AMD_MULTIPLE,
-
- /* X86_TUNE_SSE_LOAD0_BY_PXOR */
- m_PPRO | m_P4_NOCONA,
-
- /* X86_TUNE_MEMORY_MISMATCH_STALL */
- m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_AMD_MULTIPLE | m_GENERIC,
-
- /* X86_TUNE_PROLOGUE_USING_MOVE */
- m_PPRO | m_ATHLON_K8,
-
- /* X86_TUNE_EPILOGUE_USING_MOVE */
- m_PPRO | m_ATHLON_K8,
-
- /* X86_TUNE_SHIFT1 */
- ~m_486,
-
- /* X86_TUNE_USE_FFREEP */
- m_AMD_MULTIPLE,
-
- /* X86_TUNE_INTER_UNIT_MOVES */
- ~(m_AMD_MULTIPLE | m_GENERIC),
-
- /* X86_TUNE_INTER_UNIT_CONVERSIONS */
- ~(m_AMDFAM10 | m_BDVER ),
-
- /* X86_TUNE_FOUR_JUMP_LIMIT: Some CPU cores are not able to predict more
- than 4 branch instructions in the 16 byte window. */
- m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_AMD_MULTIPLE | m_GENERIC,
-
- /* X86_TUNE_SCHEDULE */
- m_PENT | m_PPRO | m_CORE_ALL | m_ATOM | m_SLM | m_K6_GEODE | m_AMD_MULTIPLE | m_GENERIC,
-
- /* X86_TUNE_USE_BT */
- m_CORE_ALL | m_ATOM | m_SLM | m_AMD_MULTIPLE | m_GENERIC,
-
- /* X86_TUNE_USE_INCDEC */
- ~(m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_GENERIC),
-
- /* X86_TUNE_PAD_RETURNS */
- m_CORE_ALL | m_AMD_MULTIPLE | m_GENERIC,
-
- /* X86_TUNE_PAD_SHORT_FUNCTION: Pad short funtion. */
- m_ATOM,
-
- /* X86_TUNE_EXT_80387_CONSTANTS */
- m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_K6_GEODE | m_ATHLON_K8 | m_GENERIC,
-
- /* X86_TUNE_AVOID_VECTOR_DECODE */
- m_CORE_ALL | m_K8 | m_GENERIC64,
-
- /* X86_TUNE_PROMOTE_HIMODE_IMUL: Modern CPUs have same latency for HImode
- and SImode multiply, but 386 and 486 do HImode multiply faster. */
- ~(m_386 | m_486),
-
- /* X86_TUNE_SLOW_IMUL_IMM32_MEM: Imul of 32-bit constant and memory is
- vector path on AMD machines. */
- m_CORE_ALL | m_K8 | m_AMDFAM10 | m_BDVER | m_BTVER | m_GENERIC64,
-
- /* X86_TUNE_SLOW_IMUL_IMM8: Imul of 8-bit constant is vector path on AMD
- machines. */
- m_CORE_ALL | m_K8 | m_AMDFAM10 | m_BDVER | m_BTVER | m_GENERIC64,
-
- /* X86_TUNE_MOVE_M1_VIA_OR: On pentiums, it is faster to load -1 via OR
- than a MOV. */
- m_PENT,
-
- /* X86_TUNE_NOT_UNPAIRABLE: NOT is not pairable on Pentium, while XOR is,
- but one byte longer. */
- m_PENT,
-
- /* X86_TUNE_NOT_VECTORMODE: On AMD K6, NOT is vector decoded with memory
- operand that cannot be represented using a modRM byte. The XOR
- replacement is long decoded, so this split helps here as well. */
- m_K6,
-
- /* X86_TUNE_USE_VECTOR_FP_CONVERTS: Prefer vector packed SSE conversion
- from FP to FP. */
- m_CORE_ALL | m_AMDFAM10 | m_GENERIC,
-
- /* X86_TUNE_USE_VECTOR_CONVERTS: Prefer vector packed SSE conversion
- from integer to FP. */
- m_AMDFAM10,
-
- /* X86_TUNE_FUSE_CMP_AND_BRANCH: Fuse a compare or test instruction
- with a subsequent conditional jump instruction into a single
- compare-and-branch uop. */
- m_BDVER,
-
- /* X86_TUNE_OPT_AGU: Optimize for Address Generation Unit. This flag
- will impact LEA instruction selection. */
- m_ATOM | m_SLM,
-
- /* X86_TUNE_VECTORIZE_DOUBLE: Enable double precision vector
- instructions. */
- ~m_ATOM,
-
- /* X86_SOFTARE_PREFETCHING_BENEFICIAL: Enable software prefetching
- at -O3. For the moment, the prefetching seems badly tuned for Intel
- chips. */
- m_K6_GEODE | m_AMD_MULTIPLE,
-
- /* X86_TUNE_AVX128_OPTIMAL: Enable 128-bit AVX instruction generation for
- the auto-vectorizer. */
- m_BDVER | m_BTVER2,
-
- /* X86_TUNE_REASSOC_INT_TO_PARALLEL: Try to produce parallel computations
- during reassociation of integer computation. */
- m_ATOM,
-
- /* X86_TUNE_REASSOC_FP_TO_PARALLEL: Try to produce parallel computations
- during reassociation of fp computation. */
- m_ATOM | m_SLM | m_HASWELL,
-
- /* X86_TUNE_GENERAL_REGS_SSE_SPILL: Try to spill general regs to SSE
- regs instead of memory. */
- m_CORE_ALL,
-
- /* X86_TUNE_AVOID_MEM_OPND_FOR_CMOVE: Try to avoid memory operands for
- a conditional move. */
- m_ATOM,
-
- /* X86_TUNE_SPLIT_MEM_OPND_FOR_FP_CONVERTS: Try to split memory operand for
- fp converts to destination register. */
- m_SLM
-
-};
-
-/* Feature tests against the various architecture variations. */
-unsigned char ix86_arch_features[X86_ARCH_LAST];
-
-/* Feature tests against the various architecture variations, used to create
- ix86_arch_features based on the processor mask. */
-static unsigned int initial_ix86_arch_features[X86_ARCH_LAST] = {
- /* X86_ARCH_CMOV: Conditional move was added for pentiumpro. */
- ~(m_386 | m_486 | m_PENT | m_K6),
-
- /* X86_ARCH_CMPXCHG: Compare and exchange was added for 80486. */
- ~m_386,
-
- /* X86_ARCH_CMPXCHG8B: Compare and exchange 8 bytes was added for pentium. */
- ~(m_386 | m_486),
-
- /* X86_ARCH_XADD: Exchange and add was added for 80486. */
- ~m_386,
-
- /* X86_ARCH_BSWAP: Byteswap was added for 80486. */
- ~m_386,
-};
-
-static const unsigned int x86_accumulate_outgoing_args
- = m_PPRO | m_P4_NOCONA | m_ATOM | m_SLM | m_CORE_ALL | m_AMD_MULTIPLE | m_GENERIC;
-
-static const unsigned int x86_arch_always_fancy_math_387
- = m_PENT | m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_AMD_MULTIPLE | m_GENERIC;
-
-static const unsigned int x86_avx256_split_unaligned_load
- = m_COREI7 | m_GENERIC;
-
-static const unsigned int x86_avx256_split_unaligned_store
- = m_COREI7 | m_BDVER | m_GENERIC;
-
-/* In case the average insn count for single function invocation is
- lower than this constant, emit fast (but longer) prologue and
- epilogue code. */
-#define FAST_PROLOGUE_INSN_COUNT 20
-
-/* Names for 8 (low), 8 (high), and 16-bit registers, respectively. */
-static const char *const qi_reg_name[] = QI_REGISTER_NAMES;
-static const char *const qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES;
-static const char *const hi_reg_name[] = HI_REGISTER_NAMES;
-
-/* Array of the smallest class containing reg number REGNO, indexed by
- REGNO. Used by REGNO_REG_CLASS in i386.h. */
-
-enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER] =
-{
- /* ax, dx, cx, bx */
- AREG, DREG, CREG, BREG,
- /* si, di, bp, sp */
- SIREG, DIREG, NON_Q_REGS, NON_Q_REGS,
- /* FP registers */
- FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
- FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,
- /* arg pointer */
- NON_Q_REGS,
- /* flags, fpsr, fpcr, frame */
- NO_REGS, NO_REGS, NO_REGS, NON_Q_REGS,
- /* SSE registers */
- SSE_FIRST_REG, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
- SSE_REGS, SSE_REGS,
- /* MMX registers */
- MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS,
- MMX_REGS, MMX_REGS,
- /* REX registers */
- NON_Q_REGS, NON_Q_REGS, NON_Q_REGS, NON_Q_REGS,
- NON_Q_REGS, NON_Q_REGS, NON_Q_REGS, NON_Q_REGS,
- /* SSE REX registers */
- SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
- SSE_REGS, SSE_REGS,
-};
-
-/* The "default" register map used in 32bit mode. */
-
-int const dbx_register_map[FIRST_PSEUDO_REGISTER] =
-{
- 0, 2, 1, 3, 6, 7, 4, 5, /* general regs */
- 12, 13, 14, 15, 16, 17, 18, 19, /* fp regs */
- -1, -1, -1, -1, -1, /* arg, flags, fpsr, fpcr, frame */
- 21, 22, 23, 24, 25, 26, 27, 28, /* SSE */
- 29, 30, 31, 32, 33, 34, 35, 36, /* MMX */
- -1, -1, -1, -1, -1, -1, -1, -1, /* extended integer registers */
- -1, -1, -1, -1, -1, -1, -1, -1, /* extended SSE registers */
-};
-
-/* The "default" register map used in 64bit mode. */
-
-int const dbx64_register_map[FIRST_PSEUDO_REGISTER] =
-{
- 0, 1, 2, 3, 4, 5, 6, 7, /* general regs */
- 33, 34, 35, 36, 37, 38, 39, 40, /* fp regs */
- -1, -1, -1, -1, -1, /* arg, flags, fpsr, fpcr, frame */
- 17, 18, 19, 20, 21, 22, 23, 24, /* SSE */
- 41, 42, 43, 44, 45, 46, 47, 48, /* MMX */
- 8,9,10,11,12,13,14,15, /* extended integer registers */
- 25, 26, 27, 28, 29, 30, 31, 32, /* extended SSE registers */
-};
-
-/* Define the register numbers to be used in Dwarf debugging information.
- The SVR4 reference port C compiler uses the following register numbers
- in its Dwarf output code:
- 0 for %eax (gcc regno = 0)
- 1 for %ecx (gcc regno = 2)
- 2 for %edx (gcc regno = 1)
- 3 for %ebx (gcc regno = 3)
- 4 for %esp (gcc regno = 7)
- 5 for %ebp (gcc regno = 6)
- 6 for %esi (gcc regno = 4)
- 7 for %edi (gcc regno = 5)
- The following three DWARF register numbers are never generated by
- the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4
- believes these numbers have these meanings.
- 8 for %eip (no gcc equivalent)
- 9 for %eflags (gcc regno = 17)
- 10 for %trapno (no gcc equivalent)
- It is not at all clear how we should number the FP stack registers
- for the x86 architecture. If the version of SDB on x86/svr4 were
- a bit less brain dead with respect to floating-point then we would
- have a precedent to follow with respect to DWARF register numbers
- for x86 FP registers, but the SDB on x86/svr4 is so completely
- broken with respect to FP registers that it is hardly worth thinking
- of it as something to strive for compatibility with.
- The version of x86/svr4 SDB I have at the moment does (partially)
- seem to believe that DWARF register number 11 is associated with
- the x86 register %st(0), but that's about all. Higher DWARF
- register numbers don't seem to be associated with anything in
- particular, and even for DWARF regno 11, SDB only seems to under-
- stand that it should say that a variable lives in %st(0) (when
- asked via an `=' command) if we said it was in DWARF regno 11,
- but SDB still prints garbage when asked for the value of the
- variable in question (via a `/' command).
- (Also note that the labels SDB prints for various FP stack regs
- when doing an `x' command are all wrong.)
- Note that these problems generally don't affect the native SVR4
- C compiler because it doesn't allow the use of -O with -g and
- because when it is *not* optimizing, it allocates a memory
- location for each floating-point variable, and the memory
- location is what gets described in the DWARF AT_location
- attribute for the variable in question.
- Regardless of the severe mental illness of the x86/svr4 SDB, we
- do something sensible here and we use the following DWARF
- register numbers. Note that these are all stack-top-relative
- numbers.
- 11 for %st(0) (gcc regno = 8)
- 12 for %st(1) (gcc regno = 9)
- 13 for %st(2) (gcc regno = 10)
- 14 for %st(3) (gcc regno = 11)
- 15 for %st(4) (gcc regno = 12)
- 16 for %st(5) (gcc regno = 13)
- 17 for %st(6) (gcc regno = 14)
- 18 for %st(7) (gcc regno = 15)
-*/
-int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER] =
-{
- 0, 2, 1, 3, 6, 7, 5, 4, /* general regs */
- 11, 12, 13, 14, 15, 16, 17, 18, /* fp regs */
- -1, 9, -1, -1, -1, /* arg, flags, fpsr, fpcr, frame */
- 21, 22, 23, 24, 25, 26, 27, 28, /* SSE registers */
- 29, 30, 31, 32, 33, 34, 35, 36, /* MMX registers */
- -1, -1, -1, -1, -1, -1, -1, -1, /* extended integer registers */
- -1, -1, -1, -1, -1, -1, -1, -1, /* extended SSE registers */
-};
-
-/* Define parameter passing and return registers. */
-
-static int const x86_64_int_parameter_registers[6] =
-{
- DI_REG, SI_REG, DX_REG, CX_REG, R8_REG, R9_REG
-};
-
-static int const x86_64_ms_abi_int_parameter_registers[4] =
-{
- CX_REG, DX_REG, R8_REG, R9_REG
-};
-
-static int const x86_64_int_return_registers[4] =
-{
- AX_REG, DX_REG, DI_REG, SI_REG
-};
-
-/* Define the structure for the machine field in struct function. */
-
-struct GTY(()) stack_local_entry {
- unsigned short mode;
- unsigned short n;
- rtx rtl;
- struct stack_local_entry *next;
-};
-
-/* Structure describing stack frame layout.
- Stack grows downward:
-
- [arguments]
- <- ARG_POINTER
- saved pc
-
- saved static chain if ix86_static_chain_on_stack
-
- saved frame pointer if frame_pointer_needed
- <- HARD_FRAME_POINTER
- [saved regs]
- <- regs_save_offset
- [padding0]
-
- [saved SSE regs]
- <- sse_regs_save_offset
- [padding1] |
- | <- FRAME_POINTER
- [va_arg registers] |
- |
- [frame] |
- |
- [padding2] | = to_allocate
- <- STACK_POINTER
- */
-struct ix86_frame
-{
- int nsseregs;
- int nregs;
- int va_arg_size;
- int red_zone_size;
- int outgoing_arguments_size;
-
- /* The offsets relative to ARG_POINTER. */
- HOST_WIDE_INT frame_pointer_offset;
- HOST_WIDE_INT hard_frame_pointer_offset;
- HOST_WIDE_INT stack_pointer_offset;
- HOST_WIDE_INT hfp_save_offset;
- HOST_WIDE_INT reg_save_offset;
- HOST_WIDE_INT sse_reg_save_offset;
-
- /* When save_regs_using_mov is set, emit prologue using
- move instead of push instructions. */
- bool save_regs_using_mov;
-};
-
-/* Which cpu are we scheduling for. */
-enum attr_cpu ix86_schedule;
-
-/* Which cpu are we optimizing for. */
-enum processor_type ix86_tune;
-
-/* Which instruction set architecture to use. */
-enum processor_type ix86_arch;
-
-/* True if processor has SSE prefetch instruction. */
-unsigned char x86_prefetch_sse;
-
-/* -mstackrealign option */
-static const char ix86_force_align_arg_pointer_string[]
- = "force_align_arg_pointer";
-
-static rtx (*ix86_gen_leave) (void);
-static rtx (*ix86_gen_add3) (rtx, rtx, rtx);
-static rtx (*ix86_gen_sub3) (rtx, rtx, rtx);
-static rtx (*ix86_gen_sub3_carry) (rtx, rtx, rtx, rtx, rtx);
-static rtx (*ix86_gen_one_cmpl2) (rtx, rtx);
-static rtx (*ix86_gen_monitor) (rtx, rtx, rtx);
-static rtx (*ix86_gen_andsp) (rtx, rtx, rtx);
-static rtx (*ix86_gen_allocate_stack_worker) (rtx, rtx);
-static rtx (*ix86_gen_adjust_stack_and_probe) (rtx, rtx, rtx);
-static rtx (*ix86_gen_probe_stack_range) (rtx, rtx, rtx);
-static rtx (*ix86_gen_tls_global_dynamic_64) (rtx, rtx, rtx);
-static rtx (*ix86_gen_tls_local_dynamic_base_64) (rtx, rtx);
-
-/* Preferred alignment for stack boundary in bits. */
-unsigned int ix86_preferred_stack_boundary;
-
-/* Alignment for incoming stack boundary in bits specified at
- command line. */
-static unsigned int ix86_user_incoming_stack_boundary;
-
-/* Default alignment for incoming stack boundary in bits. */
-static unsigned int ix86_default_incoming_stack_boundary;
-
-/* Alignment for incoming stack boundary in bits. */
-unsigned int ix86_incoming_stack_boundary;
-
-/* Calling abi specific va_list type nodes. */
-static GTY(()) tree sysv_va_list_type_node;
-static GTY(()) tree ms_va_list_type_node;
-
-/* Prefix built by ASM_GENERATE_INTERNAL_LABEL. */
-char internal_label_prefix[16];
-int internal_label_prefix_len;
-
-/* Fence to use after loop using movnt. */
-tree x86_mfence;
-
-/* Register class used for passing given 64bit part of the argument.
- These represent classes as documented by the PS ABI, with the exception
- of SSESF, SSEDF classes, that are basically SSE class, just gcc will
- use SF or DFmode move instead of DImode to avoid reformatting penalties.
-
- Similarly we play games with INTEGERSI_CLASS to use cheaper SImode moves
- whenever possible (upper half does contain padding). */
-enum x86_64_reg_class
- {
- X86_64_NO_CLASS,
- X86_64_INTEGER_CLASS,
- X86_64_INTEGERSI_CLASS,
- X86_64_SSE_CLASS,
- X86_64_SSESF_CLASS,
- X86_64_SSEDF_CLASS,
- X86_64_SSEUP_CLASS,
- X86_64_X87_CLASS,
- X86_64_X87UP_CLASS,
- X86_64_COMPLEX_X87_CLASS,
- X86_64_MEMORY_CLASS
- };
-
-#define MAX_CLASSES 4
-
-/* Table of constants used by fldpi, fldln2, etc.... */
-static REAL_VALUE_TYPE ext_80387_constants_table [5];
-static bool ext_80387_constants_init = 0;
-
-
-static struct machine_function * ix86_init_machine_status (void);
-static rtx ix86_function_value (const_tree, const_tree, bool);
-static bool ix86_function_value_regno_p (const unsigned int);
-static unsigned int ix86_function_arg_boundary (enum machine_mode,
- const_tree);
-static rtx ix86_static_chain (const_tree, bool);
-static int ix86_function_regparm (const_tree, const_tree);
-static void ix86_compute_frame_layout (struct ix86_frame *);
-static bool ix86_expand_vector_init_one_nonzero (bool, enum machine_mode,
- rtx, rtx, int);
-static void ix86_add_new_builtins (HOST_WIDE_INT);
-static tree ix86_canonical_va_list_type (tree);
-static void predict_jump (int);
-static unsigned int split_stack_prologue_scratch_regno (void);
-static bool i386_asm_output_addr_const_extra (FILE *, rtx);
-
-enum ix86_function_specific_strings
-{
- IX86_FUNCTION_SPECIFIC_ARCH,
- IX86_FUNCTION_SPECIFIC_TUNE,
- IX86_FUNCTION_SPECIFIC_MAX
-};
-
-static char *ix86_target_string (HOST_WIDE_INT, int, const char *,
- const char *, enum fpmath_unit, bool);
-static void ix86_debug_options (void) ATTRIBUTE_UNUSED;
-static void ix86_function_specific_save (struct cl_target_option *);
-static void ix86_function_specific_restore (struct cl_target_option *);
-static void ix86_function_specific_print (FILE *, int,
- struct cl_target_option *);
-static bool ix86_valid_target_attribute_p (tree, tree, tree, int);
-static bool ix86_valid_target_attribute_inner_p (tree, char *[],
- struct gcc_options *);
-static bool ix86_can_inline_p (tree, tree);
-static void ix86_set_current_function (tree);
-static unsigned int ix86_minimum_incoming_stack_boundary (bool);
-
-static enum calling_abi ix86_function_abi (const_tree);
-
-
-#ifndef SUBTARGET32_DEFAULT_CPU
-#define SUBTARGET32_DEFAULT_CPU "i386"
-#endif
-
-/* Whether -mtune= or -march= were specified */
-static int ix86_tune_defaulted;
-static int ix86_arch_specified;
-
-/* Vectorization library interface and handlers. */
-static tree (*ix86_veclib_handler) (enum built_in_function, tree, tree);
-
-static tree ix86_veclibabi_svml (enum built_in_function, tree, tree);
-static tree ix86_veclibabi_acml (enum built_in_function, tree, tree);
-
-/* Processor target table, indexed by processor number */
-struct ptt
-{
- const struct processor_costs *cost; /* Processor costs */
- const int align_loop; /* Default alignments. */
- const int align_loop_max_skip;
- const int align_jump;
- const int align_jump_max_skip;
- const int align_func;
-};
-
-static const struct ptt processor_target_table[PROCESSOR_max] =
-{
- {&i386_cost, 4, 3, 4, 3, 4},
- {&i486_cost, 16, 15, 16, 15, 16},
- {&pentium_cost, 16, 7, 16, 7, 16},
- {&pentiumpro_cost, 16, 15, 16, 10, 16},
- {&geode_cost, 0, 0, 0, 0, 0},
- {&k6_cost, 32, 7, 32, 7, 32},
- {&athlon_cost, 16, 7, 16, 7, 16},
- {&pentium4_cost, 0, 0, 0, 0, 0},
- {&k8_cost, 16, 7, 16, 7, 16},
- {&nocona_cost, 0, 0, 0, 0, 0},
- /* Core 2 */
- {&core_cost, 16, 10, 16, 10, 16},
- /* Core i7 */
- {&core_cost, 16, 10, 16, 10, 16},
- /* Core avx2 */
- {&core_cost, 16, 10, 16, 10, 16},
- {&generic32_cost, 16, 7, 16, 7, 16},
- {&generic64_cost, 16, 10, 16, 10, 16},
- {&amdfam10_cost, 32, 24, 32, 7, 32},
- {&bdver1_cost, 32, 24, 32, 7, 32},
- {&bdver2_cost, 32, 24, 32, 7, 32},
- {&bdver3_cost, 32, 24, 32, 7, 32},
- {&btver1_cost, 32, 24, 32, 7, 32},
- {&btver2_cost, 32, 24, 32, 7, 32},
- {&atom_cost, 16, 15, 16, 7, 16},
- {&slm_cost, 16, 15, 16, 7, 16}
-};
-
-static const char *const cpu_names[TARGET_CPU_DEFAULT_max] =
-{
- "generic",
- "i386",
- "i486",
- "pentium",
- "pentium-mmx",
- "pentiumpro",
- "pentium2",
- "pentium3",
- "pentium4",
- "pentium-m",
- "prescott",
- "nocona",
- "core2",
- "corei7",
- "core-avx2",
- "atom",
- "slm",
- "geode",
- "k6",
- "k6-2",
- "k6-3",
- "athlon",
- "athlon-4",
- "k8",
- "amdfam10",
- "bdver1",
- "bdver2",
- "bdver3",
- "btver1",
- "btver2"
-};
-
-static bool
-gate_insert_vzeroupper (void)
-{
- return TARGET_VZEROUPPER;
-}
-
-static unsigned int
-rest_of_handle_insert_vzeroupper (void)
-{
- int i;
-
- /* vzeroupper instructions are inserted immediately after reload to
- account for possible spills from 256bit registers. The pass
- reuses mode switching infrastructure by re-running mode insertion
- pass, so disable entities that have already been processed. */
- for (i = 0; i < MAX_386_ENTITIES; i++)
- ix86_optimize_mode_switching[i] = 0;
-
- ix86_optimize_mode_switching[AVX_U128] = 1;
-
- /* Call optimize_mode_switching. */
- pass_mode_switching.pass.execute ();
- return 0;
-}
-
-struct rtl_opt_pass pass_insert_vzeroupper =
-{
- {
- RTL_PASS,
- "vzeroupper", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_insert_vzeroupper, /* gate */
- rest_of_handle_insert_vzeroupper, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing |
- 0, /* todo_flags_finish */
- }
-};
-
-/* Return true if a red-zone is in use. */
-
-static inline bool
-ix86_using_red_zone (void)
-{
- return TARGET_RED_ZONE && !TARGET_64BIT_MS_ABI;
-}
-
-/* Return a string that documents the current -m options. The caller is
- responsible for freeing the string. */
-
-static char *
-ix86_target_string (HOST_WIDE_INT isa, int flags, const char *arch,
- const char *tune, enum fpmath_unit fpmath,
- bool add_nl_p)
-{
- struct ix86_target_opts
- {
- const char *option; /* option string */
- HOST_WIDE_INT mask; /* isa mask options */
- };
-
- /* This table is ordered so that options like -msse4.2 that imply
- preceding options while match those first. */
- static struct ix86_target_opts isa_opts[] =
- {
- { "-mfma4", OPTION_MASK_ISA_FMA4 },
- { "-mfma", OPTION_MASK_ISA_FMA },
- { "-mxop", OPTION_MASK_ISA_XOP },
- { "-mlwp", OPTION_MASK_ISA_LWP },
- { "-msse4a", OPTION_MASK_ISA_SSE4A },
- { "-msse4.2", OPTION_MASK_ISA_SSE4_2 },
- { "-msse4.1", OPTION_MASK_ISA_SSE4_1 },
- { "-mssse3", OPTION_MASK_ISA_SSSE3 },
- { "-msse3", OPTION_MASK_ISA_SSE3 },
- { "-msse2", OPTION_MASK_ISA_SSE2 },
- { "-msse", OPTION_MASK_ISA_SSE },
- { "-m3dnow", OPTION_MASK_ISA_3DNOW },
- { "-m3dnowa", OPTION_MASK_ISA_3DNOW_A },
- { "-mmmx", OPTION_MASK_ISA_MMX },
- { "-mabm", OPTION_MASK_ISA_ABM },
- { "-mbmi", OPTION_MASK_ISA_BMI },
- { "-mbmi2", OPTION_MASK_ISA_BMI2 },
- { "-mlzcnt", OPTION_MASK_ISA_LZCNT },
- { "-mhle", OPTION_MASK_ISA_HLE },
- { "-mfxsr", OPTION_MASK_ISA_FXSR },
- { "-mrdseed", OPTION_MASK_ISA_RDSEED },
- { "-mprfchw", OPTION_MASK_ISA_PRFCHW },
- { "-madx", OPTION_MASK_ISA_ADX },
- { "-mtbm", OPTION_MASK_ISA_TBM },
- { "-mpopcnt", OPTION_MASK_ISA_POPCNT },
- { "-mmovbe", OPTION_MASK_ISA_MOVBE },
- { "-mcrc32", OPTION_MASK_ISA_CRC32 },
- { "-maes", OPTION_MASK_ISA_AES },
- { "-mpclmul", OPTION_MASK_ISA_PCLMUL },
- { "-mfsgsbase", OPTION_MASK_ISA_FSGSBASE },
- { "-mrdrnd", OPTION_MASK_ISA_RDRND },
- { "-mf16c", OPTION_MASK_ISA_F16C },
- { "-mrtm", OPTION_MASK_ISA_RTM },
- { "-mxsave", OPTION_MASK_ISA_XSAVE },
- { "-mxsaveopt", OPTION_MASK_ISA_XSAVEOPT },
- };
-
- /* Flag options. */
- static struct ix86_target_opts flag_opts[] =
- {
- { "-m128bit-long-double", MASK_128BIT_LONG_DOUBLE },
- { "-mlong-double-64", MASK_LONG_DOUBLE_64 },
- { "-m80387", MASK_80387 },
- { "-maccumulate-outgoing-args", MASK_ACCUMULATE_OUTGOING_ARGS },
- { "-malign-double", MASK_ALIGN_DOUBLE },
- { "-mcld", MASK_CLD },
- { "-mfp-ret-in-387", MASK_FLOAT_RETURNS },
- { "-mieee-fp", MASK_IEEE_FP },
- { "-minline-all-stringops", MASK_INLINE_ALL_STRINGOPS },
- { "-minline-stringops-dynamically", MASK_INLINE_STRINGOPS_DYNAMICALLY },
- { "-mms-bitfields", MASK_MS_BITFIELD_LAYOUT },
- { "-mno-align-stringops", MASK_NO_ALIGN_STRINGOPS },
- { "-mno-fancy-math-387", MASK_NO_FANCY_MATH_387 },
- { "-mno-push-args", MASK_NO_PUSH_ARGS },
- { "-mno-red-zone", MASK_NO_RED_ZONE },
- { "-momit-leaf-frame-pointer", MASK_OMIT_LEAF_FRAME_POINTER },
- { "-mrecip", MASK_RECIP },
- { "-mrtd", MASK_RTD },
- { "-msseregparm", MASK_SSEREGPARM },
- { "-mstack-arg-probe", MASK_STACK_PROBE },
- { "-mtls-direct-seg-refs", MASK_TLS_DIRECT_SEG_REFS },
- { "-mvect8-ret-in-mem", MASK_VECT8_RETURNS },
- { "-m8bit-idiv", MASK_USE_8BIT_IDIV },
- { "-mvzeroupper", MASK_VZEROUPPER },
- { "-mavx256-split-unaligned-load", MASK_AVX256_SPLIT_UNALIGNED_LOAD},
- { "-mavx256-split-unaligned-store", MASK_AVX256_SPLIT_UNALIGNED_STORE},
- { "-mprefer-avx128", MASK_PREFER_AVX128},
- };
-
- const char *opts[ARRAY_SIZE (isa_opts) + ARRAY_SIZE (flag_opts) + 6][2];
-
- char isa_other[40];
- char target_other[40];
- unsigned num = 0;
- unsigned i, j;
- char *ret;
- char *ptr;
- size_t len;
- size_t line_len;
- size_t sep_len;
- const char *abi;
-
- memset (opts, '\0', sizeof (opts));
-
- /* Add -march= option. */
- if (arch)
- {
- opts[num][0] = "-march=";
- opts[num++][1] = arch;
- }
-
- /* Add -mtune= option. */
- if (tune)
- {
- opts[num][0] = "-mtune=";
- opts[num++][1] = tune;
- }
-
- /* Add -m32/-m64/-mx32. */
- if ((isa & OPTION_MASK_ISA_64BIT) != 0)
- {
- if ((isa & OPTION_MASK_ABI_64) != 0)
- abi = "-m64";
- else
- abi = "-mx32";
- isa &= ~ (OPTION_MASK_ISA_64BIT
- | OPTION_MASK_ABI_64
- | OPTION_MASK_ABI_X32);
- }
- else
- abi = "-m32";
- opts[num++][0] = abi;
-
- /* Pick out the options in isa options. */
- for (i = 0; i < ARRAY_SIZE (isa_opts); i++)
- {
- if ((isa & isa_opts[i].mask) != 0)
- {
- opts[num++][0] = isa_opts[i].option;
- isa &= ~ isa_opts[i].mask;
- }
- }
-
- if (isa && add_nl_p)
- {
- opts[num++][0] = isa_other;
- sprintf (isa_other, "(other isa: %#" HOST_WIDE_INT_PRINT "x)",
- isa);
- }
-
- /* Add flag options. */
- for (i = 0; i < ARRAY_SIZE (flag_opts); i++)
- {
- if ((flags & flag_opts[i].mask) != 0)
- {
- opts[num++][0] = flag_opts[i].option;
- flags &= ~ flag_opts[i].mask;
- }
- }
-
- if (flags && add_nl_p)
- {
- opts[num++][0] = target_other;
- sprintf (target_other, "(other flags: %#x)", flags);
- }
-
- /* Add -fpmath= option. */
- if (fpmath)
- {
- opts[num][0] = "-mfpmath=";
- switch ((int) fpmath)
- {
- case FPMATH_387:
- opts[num++][1] = "387";
- break;
-
- case FPMATH_SSE:
- opts[num++][1] = "sse";
- break;
-
- case FPMATH_387 | FPMATH_SSE:
- opts[num++][1] = "sse+387";
- break;
-
- default:
- gcc_unreachable ();
- }
- }
-
- /* Any options? */
- if (num == 0)
- return NULL;
-
- gcc_assert (num < ARRAY_SIZE (opts));
-
- /* Size the string. */
- len = 0;
- sep_len = (add_nl_p) ? 3 : 1;
- for (i = 0; i < num; i++)
- {
- len += sep_len;
- for (j = 0; j < 2; j++)
- if (opts[i][j])
- len += strlen (opts[i][j]);
- }
-
- /* Build the string. */
- ret = ptr = (char *) xmalloc (len);
- line_len = 0;
-
- for (i = 0; i < num; i++)
- {
- size_t len2[2];
-
- for (j = 0; j < 2; j++)
- len2[j] = (opts[i][j]) ? strlen (opts[i][j]) : 0;
-
- if (i != 0)
- {
- *ptr++ = ' ';
- line_len++;
-
- if (add_nl_p && line_len + len2[0] + len2[1] > 70)
- {
- *ptr++ = '\\';
- *ptr++ = '\n';
- line_len = 0;
- }
- }
-
- for (j = 0; j < 2; j++)
- if (opts[i][j])
- {
- memcpy (ptr, opts[i][j], len2[j]);
- ptr += len2[j];
- line_len += len2[j];
- }
- }
-
- *ptr = '\0';
- gcc_assert (ret + len >= ptr);
-
- return ret;
-}
-
-/* Return true, if profiling code should be emitted before
- prologue. Otherwise it returns false.
- Note: For x86 with "hotfix" it is sorried. */
-static bool
-ix86_profile_before_prologue (void)
-{
- return flag_fentry != 0;
-}
-
-/* Function that is callable from the debugger to print the current
- options. */
-void
-ix86_debug_options (void)
-{
- char *opts = ix86_target_string (ix86_isa_flags, target_flags,
- ix86_arch_string, ix86_tune_string,
- ix86_fpmath, true);
-
- if (opts)
- {
- fprintf (stderr, "%s\n\n", opts);
- free (opts);
- }
- else
- fputs ("<no options>\n\n", stderr);
-
- return;
-}
-
-/* Override various settings based on options. If MAIN_ARGS_P, the
- options are from the command line, otherwise they are from
- attributes. */
-
-static void
-ix86_option_override_internal (bool main_args_p)
-{
- int i;
- unsigned int ix86_arch_mask, ix86_tune_mask;
- const bool ix86_tune_specified = (ix86_tune_string != NULL);
- const char *prefix;
- const char *suffix;
- const char *sw;
-
-#define PTA_3DNOW (HOST_WIDE_INT_1 << 0)
-#define PTA_3DNOW_A (HOST_WIDE_INT_1 << 1)
-#define PTA_64BIT (HOST_WIDE_INT_1 << 2)
-#define PTA_ABM (HOST_WIDE_INT_1 << 3)
-#define PTA_AES (HOST_WIDE_INT_1 << 4)
-#define PTA_AVX (HOST_WIDE_INT_1 << 5)
-#define PTA_BMI (HOST_WIDE_INT_1 << 6)
-#define PTA_CX16 (HOST_WIDE_INT_1 << 7)
-#define PTA_F16C (HOST_WIDE_INT_1 << 8)
-#define PTA_FMA (HOST_WIDE_INT_1 << 9)
-#define PTA_FMA4 (HOST_WIDE_INT_1 << 10)
-#define PTA_FSGSBASE (HOST_WIDE_INT_1 << 11)
-#define PTA_LWP (HOST_WIDE_INT_1 << 12)
-#define PTA_LZCNT (HOST_WIDE_INT_1 << 13)
-#define PTA_MMX (HOST_WIDE_INT_1 << 14)
-#define PTA_MOVBE (HOST_WIDE_INT_1 << 15)
-#define PTA_NO_SAHF (HOST_WIDE_INT_1 << 16)
-#define PTA_PCLMUL (HOST_WIDE_INT_1 << 17)
-#define PTA_POPCNT (HOST_WIDE_INT_1 << 18)
-#define PTA_PREFETCH_SSE (HOST_WIDE_INT_1 << 19)
-#define PTA_RDRND (HOST_WIDE_INT_1 << 20)
-#define PTA_SSE (HOST_WIDE_INT_1 << 21)
-#define PTA_SSE2 (HOST_WIDE_INT_1 << 22)
-#define PTA_SSE3 (HOST_WIDE_INT_1 << 23)
-#define PTA_SSE4_1 (HOST_WIDE_INT_1 << 24)
-#define PTA_SSE4_2 (HOST_WIDE_INT_1 << 25)
-#define PTA_SSE4A (HOST_WIDE_INT_1 << 26)
-#define PTA_SSSE3 (HOST_WIDE_INT_1 << 27)
-#define PTA_TBM (HOST_WIDE_INT_1 << 28)
-#define PTA_XOP (HOST_WIDE_INT_1 << 29)
-#define PTA_AVX2 (HOST_WIDE_INT_1 << 30)
-#define PTA_BMI2 (HOST_WIDE_INT_1 << 31)
-#define PTA_RTM (HOST_WIDE_INT_1 << 32)
-#define PTA_HLE (HOST_WIDE_INT_1 << 33)
-#define PTA_PRFCHW (HOST_WIDE_INT_1 << 34)
-#define PTA_RDSEED (HOST_WIDE_INT_1 << 35)
-#define PTA_ADX (HOST_WIDE_INT_1 << 36)
-#define PTA_FXSR (HOST_WIDE_INT_1 << 37)
-#define PTA_XSAVE (HOST_WIDE_INT_1 << 38)
-#define PTA_XSAVEOPT (HOST_WIDE_INT_1 << 39)
-
-/* if this reaches 64, need to widen struct pta flags below */
-
- static struct pta
- {
- const char *const name; /* processor name or nickname. */
- const enum processor_type processor;
- const enum attr_cpu schedule;
- const unsigned HOST_WIDE_INT flags;
- }
- const processor_alias_table[] =
- {
- {"i386", PROCESSOR_I386, CPU_NONE, 0},
- {"i486", PROCESSOR_I486, CPU_NONE, 0},
- {"i586", PROCESSOR_PENTIUM, CPU_PENTIUM, 0},
- {"pentium", PROCESSOR_PENTIUM, CPU_PENTIUM, 0},
- {"pentium-mmx", PROCESSOR_PENTIUM, CPU_PENTIUM, PTA_MMX},
- {"winchip-c6", PROCESSOR_I486, CPU_NONE, PTA_MMX},
- {"winchip2", PROCESSOR_I486, CPU_NONE, PTA_MMX | PTA_3DNOW | PTA_PRFCHW},
- {"c3", PROCESSOR_I486, CPU_NONE, PTA_MMX | PTA_3DNOW | PTA_PRFCHW},
- {"c3-2", PROCESSOR_PENTIUMPRO, CPU_PENTIUMPRO,
- PTA_MMX | PTA_SSE | PTA_FXSR},
- {"i686", PROCESSOR_PENTIUMPRO, CPU_PENTIUMPRO, 0},
- {"pentiumpro", PROCESSOR_PENTIUMPRO, CPU_PENTIUMPRO, 0},
- {"pentium2", PROCESSOR_PENTIUMPRO, CPU_PENTIUMPRO, PTA_MMX | PTA_FXSR},
- {"pentium3", PROCESSOR_PENTIUMPRO, CPU_PENTIUMPRO,
- PTA_MMX | PTA_SSE | PTA_FXSR},
- {"pentium3m", PROCESSOR_PENTIUMPRO, CPU_PENTIUMPRO,
- PTA_MMX | PTA_SSE | PTA_FXSR},
- {"pentium-m", PROCESSOR_PENTIUMPRO, CPU_PENTIUMPRO,
- PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_FXSR},
- {"pentium4", PROCESSOR_PENTIUM4, CPU_NONE,
- PTA_MMX |PTA_SSE | PTA_SSE2 | PTA_FXSR},
- {"pentium4m", PROCESSOR_PENTIUM4, CPU_NONE,
- PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_FXSR},
- {"prescott", PROCESSOR_NOCONA, CPU_NONE,
- PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 | PTA_FXSR},
- {"nocona", PROCESSOR_NOCONA, CPU_NONE,
- PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
- | PTA_CX16 | PTA_NO_SAHF | PTA_FXSR},
- {"core2", PROCESSOR_CORE2, CPU_CORE2,
- PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
- | PTA_SSSE3 | PTA_CX16 | PTA_FXSR},
- {"corei7", PROCESSOR_COREI7, CPU_COREI7,
- PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 | PTA_SSSE3
- | PTA_SSE4_1 | PTA_SSE4_2 | PTA_CX16 | PTA_POPCNT | PTA_FXSR},
- {"corei7-avx", PROCESSOR_COREI7, CPU_COREI7,
- PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
- | PTA_SSSE3 | PTA_SSE4_1 | PTA_SSE4_2 | PTA_AVX
- | PTA_CX16 | PTA_POPCNT | PTA_AES | PTA_PCLMUL
- | PTA_FXSR | PTA_XSAVE | PTA_XSAVEOPT},
- {"core-avx-i", PROCESSOR_COREI7, CPU_COREI7,
- PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
- | PTA_SSSE3 | PTA_SSE4_1 | PTA_SSE4_2 | PTA_AVX
- | PTA_CX16 | PTA_POPCNT | PTA_AES | PTA_PCLMUL | PTA_FSGSBASE
- | PTA_RDRND | PTA_F16C | PTA_FXSR | PTA_XSAVE | PTA_XSAVEOPT},
- {"core-avx2", PROCESSOR_HASWELL, CPU_COREI7,
- PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
- | PTA_SSSE3 | PTA_SSE4_1 | PTA_SSE4_2 | PTA_AVX | PTA_AVX2
- | PTA_CX16 | PTA_POPCNT | PTA_AES | PTA_PCLMUL | PTA_FSGSBASE
- | PTA_RDRND | PTA_F16C | PTA_BMI | PTA_BMI2 | PTA_LZCNT
- | PTA_FMA | PTA_MOVBE | PTA_RTM | PTA_HLE | PTA_FXSR | PTA_XSAVE
- | PTA_XSAVEOPT},
- {"atom", PROCESSOR_ATOM, CPU_ATOM,
- PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
- | PTA_SSSE3 | PTA_CX16 | PTA_MOVBE | PTA_FXSR},
- {"slm", PROCESSOR_SLM, CPU_SLM,
- PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
- | PTA_SSSE3 | PTA_SSE4_1 | PTA_SSE4_2 | PTA_CX16 | PTA_MOVBE
- | PTA_FXSR},
- {"geode", PROCESSOR_GEODE, CPU_GEODE,
- PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_PREFETCH_SSE | PTA_PRFCHW},
- {"k6", PROCESSOR_K6, CPU_K6, PTA_MMX},
- {"k6-2", PROCESSOR_K6, CPU_K6, PTA_MMX | PTA_3DNOW | PTA_PRFCHW},
- {"k6-3", PROCESSOR_K6, CPU_K6, PTA_MMX | PTA_3DNOW | PTA_PRFCHW},
- {"athlon", PROCESSOR_ATHLON, CPU_ATHLON,
- PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_PREFETCH_SSE | PTA_PRFCHW},
- {"athlon-tbird", PROCESSOR_ATHLON, CPU_ATHLON,
- PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_PREFETCH_SSE | PTA_PRFCHW},
- {"athlon-4", PROCESSOR_ATHLON, CPU_ATHLON,
- PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE | PTA_PRFCHW | PTA_FXSR},
- {"athlon-xp", PROCESSOR_ATHLON, CPU_ATHLON,
- PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE | PTA_PRFCHW | PTA_FXSR},
- {"athlon-mp", PROCESSOR_ATHLON, CPU_ATHLON,
- PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE | PTA_PRFCHW | PTA_FXSR},
- {"x86-64", PROCESSOR_K8, CPU_K8,
- PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_NO_SAHF | PTA_FXSR},
- {"k8", PROCESSOR_K8, CPU_K8,
- PTA_64BIT | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE
- | PTA_SSE2 | PTA_NO_SAHF | PTA_PRFCHW | PTA_FXSR},
- {"k8-sse3", PROCESSOR_K8, CPU_K8,
- PTA_64BIT | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE
- | PTA_SSE2 | PTA_SSE3 | PTA_NO_SAHF | PTA_PRFCHW | PTA_FXSR},
- {"opteron", PROCESSOR_K8, CPU_K8,
- PTA_64BIT | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE
- | PTA_SSE2 | PTA_NO_SAHF | PTA_PRFCHW | PTA_FXSR},
- {"opteron-sse3", PROCESSOR_K8, CPU_K8,
- PTA_64BIT | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE
- | PTA_SSE2 | PTA_SSE3 | PTA_NO_SAHF | PTA_PRFCHW | PTA_FXSR},
- {"athlon64", PROCESSOR_K8, CPU_K8,
- PTA_64BIT | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE
- | PTA_SSE2 | PTA_NO_SAHF | PTA_PRFCHW | PTA_FXSR},
- {"athlon64-sse3", PROCESSOR_K8, CPU_K8,
- PTA_64BIT | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE
- | PTA_SSE2 | PTA_SSE3 | PTA_NO_SAHF | PTA_PRFCHW | PTA_FXSR},
- {"athlon-fx", PROCESSOR_K8, CPU_K8,
- PTA_64BIT | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE
- | PTA_SSE2 | PTA_NO_SAHF | PTA_PRFCHW | PTA_FXSR},
- {"amdfam10", PROCESSOR_AMDFAM10, CPU_AMDFAM10,
- PTA_64BIT | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE | PTA_SSE2
- | PTA_SSE3 | PTA_SSE4A | PTA_CX16 | PTA_ABM | PTA_PRFCHW | PTA_FXSR},
- {"barcelona", PROCESSOR_AMDFAM10, CPU_AMDFAM10,
- PTA_64BIT | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE | PTA_SSE2
- | PTA_SSE3 | PTA_SSE4A | PTA_CX16 | PTA_ABM | PTA_PRFCHW | PTA_FXSR},
- {"bdver1", PROCESSOR_BDVER1, CPU_BDVER1,
- PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
- | PTA_SSE4A | PTA_CX16 | PTA_ABM | PTA_SSSE3 | PTA_SSE4_1
- | PTA_SSE4_2 | PTA_AES | PTA_PCLMUL | PTA_AVX | PTA_FMA4
- | PTA_XOP | PTA_LWP | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE},
- {"bdver2", PROCESSOR_BDVER2, CPU_BDVER2,
- PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
- | PTA_SSE4A | PTA_CX16 | PTA_ABM | PTA_SSSE3 | PTA_SSE4_1
- | PTA_SSE4_2 | PTA_AES | PTA_PCLMUL | PTA_AVX | PTA_FMA4
- | PTA_XOP | PTA_LWP | PTA_BMI | PTA_TBM | PTA_F16C
- | PTA_FMA | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE},
- {"bdver3", PROCESSOR_BDVER3, CPU_BDVER3,
- PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
- | PTA_SSE4A | PTA_CX16 | PTA_ABM | PTA_SSSE3 | PTA_SSE4_1
- | PTA_SSE4_2 | PTA_AES | PTA_PCLMUL | PTA_AVX
- | PTA_XOP | PTA_LWP | PTA_BMI | PTA_TBM | PTA_F16C
- | PTA_FMA | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE
- | PTA_XSAVEOPT},
- {"btver1", PROCESSOR_BTVER1, CPU_GENERIC64,
- PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
- | PTA_SSSE3 | PTA_SSE4A |PTA_ABM | PTA_CX16 | PTA_PRFCHW
- | PTA_FXSR | PTA_XSAVE},
- {"btver2", PROCESSOR_BTVER2, CPU_BTVER2,
- PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
- | PTA_SSSE3 | PTA_SSE4A |PTA_ABM | PTA_CX16 | PTA_SSE4_1
- | PTA_SSE4_2 | PTA_AES | PTA_PCLMUL | PTA_AVX
- | PTA_BMI | PTA_F16C | PTA_MOVBE | PTA_PRFCHW
- | PTA_FXSR | PTA_XSAVE | PTA_XSAVEOPT},
-
- {"generic32", PROCESSOR_GENERIC32, CPU_PENTIUMPRO,
- PTA_HLE /* flags are only used for -march switch. */ },
- {"generic64", PROCESSOR_GENERIC64, CPU_GENERIC64,
- PTA_64BIT
- | PTA_HLE /* flags are only used for -march switch. */ },
- };
-
- /* -mrecip options. */
- static struct
- {
- const char *string; /* option name */
- unsigned int mask; /* mask bits to set */
- }
- const recip_options[] =
- {
- { "all", RECIP_MASK_ALL },
- { "none", RECIP_MASK_NONE },
- { "div", RECIP_MASK_DIV },
- { "sqrt", RECIP_MASK_SQRT },
- { "vec-div", RECIP_MASK_VEC_DIV },
- { "vec-sqrt", RECIP_MASK_VEC_SQRT },
- };
-
- int const pta_size = ARRAY_SIZE (processor_alias_table);
-
- /* Set up prefix/suffix so the error messages refer to either the command
- line argument, or the attribute(target). */
- if (main_args_p)
- {
- prefix = "-m";
- suffix = "";
- sw = "switch";
- }
- else
- {
- prefix = "option(\"";
- suffix = "\")";
- sw = "attribute";
- }
-
- /* Turn off both OPTION_MASK_ABI_64 and OPTION_MASK_ABI_X32 if
- TARGET_64BIT_DEFAULT is true and TARGET_64BIT is false. */
- if (TARGET_64BIT_DEFAULT && !TARGET_64BIT)
- ix86_isa_flags &= ~(OPTION_MASK_ABI_64 | OPTION_MASK_ABI_X32);
-#ifdef TARGET_BI_ARCH
- else
- {
-#if TARGET_BI_ARCH == 1
- /* When TARGET_BI_ARCH == 1, by default, OPTION_MASK_ABI_64
- is on and OPTION_MASK_ABI_X32 is off. We turn off
- OPTION_MASK_ABI_64 if OPTION_MASK_ABI_X32 is turned on by
- -mx32. */
- if (TARGET_X32)
- ix86_isa_flags &= ~OPTION_MASK_ABI_64;
-#else
- /* When TARGET_BI_ARCH == 2, by default, OPTION_MASK_ABI_X32 is
- on and OPTION_MASK_ABI_64 is off. We turn off
- OPTION_MASK_ABI_X32 if OPTION_MASK_ABI_64 is turned on by
- -m64. */
- if (TARGET_LP64)
- ix86_isa_flags &= ~OPTION_MASK_ABI_X32;
-#endif
- }
-#endif
-
- if (TARGET_X32)
- {
- /* Always turn on OPTION_MASK_ISA_64BIT and turn off
- OPTION_MASK_ABI_64 for TARGET_X32. */
- ix86_isa_flags |= OPTION_MASK_ISA_64BIT;
- ix86_isa_flags &= ~OPTION_MASK_ABI_64;
- }
- else if (TARGET_LP64)
- {
- /* Always turn on OPTION_MASK_ISA_64BIT and turn off
- OPTION_MASK_ABI_X32 for TARGET_LP64. */
- ix86_isa_flags |= OPTION_MASK_ISA_64BIT;
- ix86_isa_flags &= ~OPTION_MASK_ABI_X32;
- }
-
-#ifdef SUBTARGET_OVERRIDE_OPTIONS
- SUBTARGET_OVERRIDE_OPTIONS;
-#endif
-
-#ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
- SUBSUBTARGET_OVERRIDE_OPTIONS;
-#endif
-
- /* -fPIC is the default for x86_64. */
- if (TARGET_MACHO && TARGET_64BIT)
- flag_pic = 2;
-
- /* Need to check -mtune=generic first. */
- if (ix86_tune_string)
- {
- if (!strcmp (ix86_tune_string, "generic")
- || !strcmp (ix86_tune_string, "i686")
- /* As special support for cross compilers we read -mtune=native
- as -mtune=generic. With native compilers we won't see the
- -mtune=native, as it was changed by the driver. */
- || !strcmp (ix86_tune_string, "native"))
- {
- if (TARGET_64BIT)
- ix86_tune_string = "generic64";
- else
- ix86_tune_string = "generic32";
- }
- /* If this call is for setting the option attribute, allow the
- generic32/generic64 that was previously set. */
- else if (!main_args_p
- && (!strcmp (ix86_tune_string, "generic32")
- || !strcmp (ix86_tune_string, "generic64")))
- ;
- else if (!strncmp (ix86_tune_string, "generic", 7))
- error ("bad value (%s) for %stune=%s %s",
- ix86_tune_string, prefix, suffix, sw);
- else if (!strcmp (ix86_tune_string, "x86-64"))
- warning (OPT_Wdeprecated, "%stune=x86-64%s is deprecated; use "
- "%stune=k8%s or %stune=generic%s instead as appropriate",
- prefix, suffix, prefix, suffix, prefix, suffix);
- }
- else
- {
- if (ix86_arch_string)
- ix86_tune_string = ix86_arch_string;
- if (!ix86_tune_string)
- {
- ix86_tune_string = cpu_names[TARGET_CPU_DEFAULT];
- ix86_tune_defaulted = 1;
- }
-
- /* ix86_tune_string is set to ix86_arch_string or defaulted. We
- need to use a sensible tune option. */
- if (!strcmp (ix86_tune_string, "generic")
- || !strcmp (ix86_tune_string, "x86-64")
- || !strcmp (ix86_tune_string, "i686"))
- {
- if (TARGET_64BIT)
- ix86_tune_string = "generic64";
- else
- ix86_tune_string = "generic32";
- }
- }
-
- if (ix86_stringop_alg == rep_prefix_8_byte && !TARGET_64BIT)
- {
- /* rep; movq isn't available in 32-bit code. */
- error ("-mstringop-strategy=rep_8byte not supported for 32-bit code");
- ix86_stringop_alg = no_stringop;
- }
-
- if (!ix86_arch_string)
- ix86_arch_string = TARGET_64BIT ? "x86-64" : SUBTARGET32_DEFAULT_CPU;
- else
- ix86_arch_specified = 1;
-
- if (global_options_set.x_ix86_pmode)
- {
- if ((TARGET_LP64 && ix86_pmode == PMODE_SI)
- || (!TARGET_64BIT && ix86_pmode == PMODE_DI))
- error ("address mode %qs not supported in the %s bit mode",
- TARGET_64BIT ? "short" : "long",
- TARGET_64BIT ? "64" : "32");
- }
- else
- ix86_pmode = TARGET_LP64 ? PMODE_DI : PMODE_SI;
-
- if (!global_options_set.x_ix86_abi)
- ix86_abi = DEFAULT_ABI;
-
- if (global_options_set.x_ix86_cmodel)
- {
- switch (ix86_cmodel)
- {
- case CM_SMALL:
- case CM_SMALL_PIC:
- if (flag_pic)
- ix86_cmodel = CM_SMALL_PIC;
- if (!TARGET_64BIT)
- error ("code model %qs not supported in the %s bit mode",
- "small", "32");
- break;
-
- case CM_MEDIUM:
- case CM_MEDIUM_PIC:
- if (flag_pic)
- ix86_cmodel = CM_MEDIUM_PIC;
- if (!TARGET_64BIT)
- error ("code model %qs not supported in the %s bit mode",
- "medium", "32");
- else if (TARGET_X32)
- error ("code model %qs not supported in x32 mode",
- "medium");
- break;
-
- case CM_LARGE:
- case CM_LARGE_PIC:
- if (flag_pic)
- ix86_cmodel = CM_LARGE_PIC;
- if (!TARGET_64BIT)
- error ("code model %qs not supported in the %s bit mode",
- "large", "32");
- else if (TARGET_X32)
- error ("code model %qs not supported in x32 mode",
- "large");
- break;
-
- case CM_32:
- if (flag_pic)
- error ("code model %s does not support PIC mode", "32");
- if (TARGET_64BIT)
- error ("code model %qs not supported in the %s bit mode",
- "32", "64");
- break;
-
- case CM_KERNEL:
- if (flag_pic)
- {
- error ("code model %s does not support PIC mode", "kernel");
- ix86_cmodel = CM_32;
- }
- if (!TARGET_64BIT)
- error ("code model %qs not supported in the %s bit mode",
- "kernel", "32");
- break;
-
- default:
- gcc_unreachable ();
- }
- }
- else
- {
- /* For TARGET_64BIT and MS_ABI, force pic on, in order to enable the
- use of rip-relative addressing. This eliminates fixups that
- would otherwise be needed if this object is to be placed in a
- DLL, and is essentially just as efficient as direct addressing. */
- if (TARGET_64BIT && DEFAULT_ABI == MS_ABI)
- ix86_cmodel = CM_SMALL_PIC, flag_pic = 1;
- else if (TARGET_64BIT && TARGET_RDOS)
- ix86_cmodel = CM_MEDIUM_PIC, flag_pic = 1;
- else if (TARGET_64BIT)
- ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL;
- else
- ix86_cmodel = CM_32;
- }
- if (TARGET_MACHO && ix86_asm_dialect == ASM_INTEL)
- {
- error ("-masm=intel not supported in this configuration");
- ix86_asm_dialect = ASM_ATT;
- }
- if ((TARGET_64BIT != 0) != ((ix86_isa_flags & OPTION_MASK_ISA_64BIT) != 0))
- sorry ("%i-bit mode not compiled in",
- (ix86_isa_flags & OPTION_MASK_ISA_64BIT) ? 64 : 32);
-
- for (i = 0; i < pta_size; i++)
- if (! strcmp (ix86_arch_string, processor_alias_table[i].name))
- {
- ix86_schedule = processor_alias_table[i].schedule;
- ix86_arch = processor_alias_table[i].processor;
- /* Default cpu tuning to the architecture. */
- ix86_tune = ix86_arch;
-
- if (TARGET_64BIT && !(processor_alias_table[i].flags & PTA_64BIT))
- error ("CPU you selected does not support x86-64 "
- "instruction set");
-
- if (processor_alias_table[i].flags & PTA_MMX
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_MMX))
- ix86_isa_flags |= OPTION_MASK_ISA_MMX;
- if (processor_alias_table[i].flags & PTA_3DNOW
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_3DNOW))
- ix86_isa_flags |= OPTION_MASK_ISA_3DNOW;
- if (processor_alias_table[i].flags & PTA_3DNOW_A
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_3DNOW_A))
- ix86_isa_flags |= OPTION_MASK_ISA_3DNOW_A;
- if (processor_alias_table[i].flags & PTA_SSE
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_SSE))
- ix86_isa_flags |= OPTION_MASK_ISA_SSE;
- if (processor_alias_table[i].flags & PTA_SSE2
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_SSE2))
- ix86_isa_flags |= OPTION_MASK_ISA_SSE2;
- if (processor_alias_table[i].flags & PTA_SSE3
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_SSE3))
- ix86_isa_flags |= OPTION_MASK_ISA_SSE3;
- if (processor_alias_table[i].flags & PTA_SSSE3
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_SSSE3))
- ix86_isa_flags |= OPTION_MASK_ISA_SSSE3;
- if (processor_alias_table[i].flags & PTA_SSE4_1
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_SSE4_1))
- ix86_isa_flags |= OPTION_MASK_ISA_SSE4_1;
- if (processor_alias_table[i].flags & PTA_SSE4_2
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_SSE4_2))
- ix86_isa_flags |= OPTION_MASK_ISA_SSE4_2;
- if (processor_alias_table[i].flags & PTA_AVX
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_AVX))
- ix86_isa_flags |= OPTION_MASK_ISA_AVX;
- if (processor_alias_table[i].flags & PTA_AVX2
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_AVX2))
- ix86_isa_flags |= OPTION_MASK_ISA_AVX2;
- if (processor_alias_table[i].flags & PTA_FMA
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_FMA))
- ix86_isa_flags |= OPTION_MASK_ISA_FMA;
- if (processor_alias_table[i].flags & PTA_SSE4A
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_SSE4A))
- ix86_isa_flags |= OPTION_MASK_ISA_SSE4A;
- if (processor_alias_table[i].flags & PTA_FMA4
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_FMA4))
- ix86_isa_flags |= OPTION_MASK_ISA_FMA4;
- if (processor_alias_table[i].flags & PTA_XOP
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_XOP))
- ix86_isa_flags |= OPTION_MASK_ISA_XOP;
- if (processor_alias_table[i].flags & PTA_LWP
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_LWP))
- ix86_isa_flags |= OPTION_MASK_ISA_LWP;
- if (processor_alias_table[i].flags & PTA_ABM
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_ABM))
- ix86_isa_flags |= OPTION_MASK_ISA_ABM;
- if (processor_alias_table[i].flags & PTA_BMI
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_BMI))
- ix86_isa_flags |= OPTION_MASK_ISA_BMI;
- if (processor_alias_table[i].flags & (PTA_LZCNT | PTA_ABM)
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_LZCNT))
- ix86_isa_flags |= OPTION_MASK_ISA_LZCNT;
- if (processor_alias_table[i].flags & PTA_TBM
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_TBM))
- ix86_isa_flags |= OPTION_MASK_ISA_TBM;
- if (processor_alias_table[i].flags & PTA_BMI2
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_BMI2))
- ix86_isa_flags |= OPTION_MASK_ISA_BMI2;
- if (processor_alias_table[i].flags & PTA_CX16
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_CX16))
- ix86_isa_flags |= OPTION_MASK_ISA_CX16;
- if (processor_alias_table[i].flags & (PTA_POPCNT | PTA_ABM)
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_POPCNT))
- ix86_isa_flags |= OPTION_MASK_ISA_POPCNT;
- if (!(TARGET_64BIT && (processor_alias_table[i].flags & PTA_NO_SAHF))
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_SAHF))
- ix86_isa_flags |= OPTION_MASK_ISA_SAHF;
- if (processor_alias_table[i].flags & PTA_MOVBE
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_MOVBE))
- ix86_isa_flags |= OPTION_MASK_ISA_MOVBE;
- if (processor_alias_table[i].flags & PTA_AES
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_AES))
- ix86_isa_flags |= OPTION_MASK_ISA_AES;
- if (processor_alias_table[i].flags & PTA_PCLMUL
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_PCLMUL))
- ix86_isa_flags |= OPTION_MASK_ISA_PCLMUL;
- if (processor_alias_table[i].flags & PTA_FSGSBASE
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_FSGSBASE))
- ix86_isa_flags |= OPTION_MASK_ISA_FSGSBASE;
- if (processor_alias_table[i].flags & PTA_RDRND
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_RDRND))
- ix86_isa_flags |= OPTION_MASK_ISA_RDRND;
- if (processor_alias_table[i].flags & PTA_F16C
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_F16C))
- ix86_isa_flags |= OPTION_MASK_ISA_F16C;
- if (processor_alias_table[i].flags & PTA_RTM
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_RTM))
- ix86_isa_flags |= OPTION_MASK_ISA_RTM;
- if (processor_alias_table[i].flags & PTA_HLE
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_HLE))
- ix86_isa_flags |= OPTION_MASK_ISA_HLE;
- if (processor_alias_table[i].flags & PTA_PRFCHW
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_PRFCHW))
- ix86_isa_flags |= OPTION_MASK_ISA_PRFCHW;
- if (processor_alias_table[i].flags & PTA_RDSEED
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_RDSEED))
- ix86_isa_flags |= OPTION_MASK_ISA_RDSEED;
- if (processor_alias_table[i].flags & PTA_ADX
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_ADX))
- ix86_isa_flags |= OPTION_MASK_ISA_ADX;
- if (processor_alias_table[i].flags & PTA_FXSR
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_FXSR))
- ix86_isa_flags |= OPTION_MASK_ISA_FXSR;
- if (processor_alias_table[i].flags & PTA_XSAVE
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_XSAVE))
- ix86_isa_flags |= OPTION_MASK_ISA_XSAVE;
- if (processor_alias_table[i].flags & PTA_XSAVEOPT
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_XSAVEOPT))
- ix86_isa_flags |= OPTION_MASK_ISA_XSAVEOPT;
- if (processor_alias_table[i].flags & (PTA_PREFETCH_SSE | PTA_SSE))
- x86_prefetch_sse = true;
-
- break;
- }
-
- if (!strcmp (ix86_arch_string, "generic"))
- error ("generic CPU can be used only for %stune=%s %s",
- prefix, suffix, sw);
- else if (!strncmp (ix86_arch_string, "generic", 7) || i == pta_size)
- error ("bad value (%s) for %sarch=%s %s",
- ix86_arch_string, prefix, suffix, sw);
-
- ix86_arch_mask = 1u << ix86_arch;
- for (i = 0; i < X86_ARCH_LAST; ++i)
- ix86_arch_features[i] = !!(initial_ix86_arch_features[i] & ix86_arch_mask);
-
- for (i = 0; i < pta_size; i++)
- if (! strcmp (ix86_tune_string, processor_alias_table[i].name))
- {
- ix86_schedule = processor_alias_table[i].schedule;
- ix86_tune = processor_alias_table[i].processor;
- if (TARGET_64BIT)
- {
- if (!(processor_alias_table[i].flags & PTA_64BIT))
- {
- if (ix86_tune_defaulted)
- {
- ix86_tune_string = "x86-64";
- for (i = 0; i < pta_size; i++)
- if (! strcmp (ix86_tune_string,
- processor_alias_table[i].name))
- break;
- ix86_schedule = processor_alias_table[i].schedule;
- ix86_tune = processor_alias_table[i].processor;
- }
- else
- error ("CPU you selected does not support x86-64 "
- "instruction set");
- }
- }
- else
- {
- /* Adjust tuning when compiling for 32-bit ABI. */
- switch (ix86_tune)
- {
- case PROCESSOR_GENERIC64:
- ix86_tune = PROCESSOR_GENERIC32;
- ix86_schedule = CPU_PENTIUMPRO;
- break;
-
- default:
- break;
- }
- }
- /* Intel CPUs have always interpreted SSE prefetch instructions as
- NOPs; so, we can enable SSE prefetch instructions even when
- -mtune (rather than -march) points us to a processor that has them.
- However, the VIA C3 gives a SIGILL, so we only do that for i686 and
- higher processors. */
- if (TARGET_CMOV
- && (processor_alias_table[i].flags & (PTA_PREFETCH_SSE | PTA_SSE)))
- x86_prefetch_sse = true;
- break;
- }
-
- if (ix86_tune_specified && i == pta_size)
- error ("bad value (%s) for %stune=%s %s",
- ix86_tune_string, prefix, suffix, sw);
-
- ix86_tune_mask = 1u << ix86_tune;
- for (i = 0; i < X86_TUNE_LAST; ++i)
- ix86_tune_features[i] = !!(initial_ix86_tune_features[i] & ix86_tune_mask);
-
-#ifndef USE_IX86_FRAME_POINTER
-#define USE_IX86_FRAME_POINTER 0
-#endif
-
-#ifndef USE_X86_64_FRAME_POINTER
-#define USE_X86_64_FRAME_POINTER 0
-#endif
-
- /* Set the default values for switches whose default depends on TARGET_64BIT
- in case they weren't overwritten by command line options. */
- if (TARGET_64BIT)
- {
- if (optimize >= 1 && !global_options_set.x_flag_omit_frame_pointer)
- flag_omit_frame_pointer = !USE_X86_64_FRAME_POINTER;
- if (flag_asynchronous_unwind_tables == 2)
- flag_unwind_tables = flag_asynchronous_unwind_tables = 1;
- if (flag_pcc_struct_return == 2)
- flag_pcc_struct_return = 0;
- }
- else
- {
- if (optimize >= 1 && !global_options_set.x_flag_omit_frame_pointer)
- flag_omit_frame_pointer = !(USE_IX86_FRAME_POINTER || optimize_size);
- if (flag_asynchronous_unwind_tables == 2)
- flag_asynchronous_unwind_tables = !USE_IX86_FRAME_POINTER;
- if (flag_pcc_struct_return == 2)
- flag_pcc_struct_return = DEFAULT_PCC_STRUCT_RETURN;
- }
-
- ix86_tune_cost = processor_target_table[ix86_tune].cost;
- if (optimize_size)
- ix86_cost = &ix86_size_cost;
- else
- ix86_cost = ix86_tune_cost;
-
- /* Arrange to set up i386_stack_locals for all functions. */
- init_machine_status = ix86_init_machine_status;
-
- /* Validate -mregparm= value. */
- if (global_options_set.x_ix86_regparm)
- {
- if (TARGET_64BIT)
- warning (0, "-mregparm is ignored in 64-bit mode");
- if (ix86_regparm > REGPARM_MAX)
- {
- error ("-mregparm=%d is not between 0 and %d",
- ix86_regparm, REGPARM_MAX);
- ix86_regparm = 0;
- }
- }
- if (TARGET_64BIT)
- ix86_regparm = REGPARM_MAX;
-
- /* Default align_* from the processor table. */
- if (align_loops == 0)
- {
- align_loops = processor_target_table[ix86_tune].align_loop;
- align_loops_max_skip = processor_target_table[ix86_tune].align_loop_max_skip;
- }
- if (align_jumps == 0)
- {
- align_jumps = processor_target_table[ix86_tune].align_jump;
- align_jumps_max_skip = processor_target_table[ix86_tune].align_jump_max_skip;
- }
- if (align_functions == 0)
- {
- align_functions = processor_target_table[ix86_tune].align_func;
- }
-
- /* Provide default for -mbranch-cost= value. */
- if (!global_options_set.x_ix86_branch_cost)
- ix86_branch_cost = ix86_cost->branch_cost;
-
- if (TARGET_64BIT)
- {
- target_flags |= TARGET_SUBTARGET64_DEFAULT & ~target_flags_explicit;
-
- /* Enable by default the SSE and MMX builtins. Do allow the user to
- explicitly disable any of these. In particular, disabling SSE and
- MMX for kernel code is extremely useful. */
- if (!ix86_arch_specified)
- ix86_isa_flags
- |= ((OPTION_MASK_ISA_SSE2 | OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_MMX
- | TARGET_SUBTARGET64_ISA_DEFAULT) & ~ix86_isa_flags_explicit);
-
- if (TARGET_RTD)
- warning (0, "%srtd%s is ignored in 64bit mode", prefix, suffix);
- }
- else
- {
- target_flags |= TARGET_SUBTARGET32_DEFAULT & ~target_flags_explicit;
-
- if (!ix86_arch_specified)
- ix86_isa_flags
- |= TARGET_SUBTARGET32_ISA_DEFAULT & ~ix86_isa_flags_explicit;
-
- /* i386 ABI does not specify red zone. It still makes sense to use it
- when programmer takes care to stack from being destroyed. */
- if (!(target_flags_explicit & MASK_NO_RED_ZONE))
- target_flags |= MASK_NO_RED_ZONE;
- }
-
- /* Keep nonleaf frame pointers. */
- if (flag_omit_frame_pointer)
- target_flags &= ~MASK_OMIT_LEAF_FRAME_POINTER;
- else if (TARGET_OMIT_LEAF_FRAME_POINTER)
- flag_omit_frame_pointer = 1;
-
- /* If we're doing fast math, we don't care about comparison order
- wrt NaNs. This lets us use a shorter comparison sequence. */
- if (flag_finite_math_only)
- target_flags &= ~MASK_IEEE_FP;
-
- /* If the architecture always has an FPU, turn off NO_FANCY_MATH_387,
- since the insns won't need emulation. */
- if (x86_arch_always_fancy_math_387 & ix86_arch_mask)
- target_flags &= ~MASK_NO_FANCY_MATH_387;
-
- /* Likewise, if the target doesn't have a 387, or we've specified
- software floating point, don't use 387 inline intrinsics. */
- if (!TARGET_80387)
- target_flags |= MASK_NO_FANCY_MATH_387;
-
- /* Turn on MMX builtins for -msse. */
- if (TARGET_SSE)
- ix86_isa_flags |= OPTION_MASK_ISA_MMX & ~ix86_isa_flags_explicit;
-
- /* Enable SSE prefetch. */
- if (TARGET_SSE || (TARGET_PRFCHW && !TARGET_3DNOW))
- x86_prefetch_sse = true;
-
- /* Enable prefetch{,w} instructions for -m3dnow. */
- if (TARGET_3DNOW)
- ix86_isa_flags |= OPTION_MASK_ISA_PRFCHW & ~ix86_isa_flags_explicit;
-
- /* Enable popcnt instruction for -msse4.2 or -mabm. */
- if (TARGET_SSE4_2 || TARGET_ABM)
- ix86_isa_flags |= OPTION_MASK_ISA_POPCNT & ~ix86_isa_flags_explicit;
-
- /* Enable lzcnt instruction for -mabm. */
- if (TARGET_ABM)
- ix86_isa_flags |= OPTION_MASK_ISA_LZCNT & ~ix86_isa_flags_explicit;
-
- /* Validate -mpreferred-stack-boundary= value or default it to
- PREFERRED_STACK_BOUNDARY_DEFAULT. */
- ix86_preferred_stack_boundary = PREFERRED_STACK_BOUNDARY_DEFAULT;
- if (global_options_set.x_ix86_preferred_stack_boundary_arg)
- {
- int min = (TARGET_64BIT ? (TARGET_SSE ? 4 : 3) : 2);
- int max = (TARGET_SEH ? 4 : 12);
-
- if (ix86_preferred_stack_boundary_arg < min
- || ix86_preferred_stack_boundary_arg > max)
- {
- if (min == max)
- error ("-mpreferred-stack-boundary is not supported "
- "for this target");
- else
- error ("-mpreferred-stack-boundary=%d is not between %d and %d",
- ix86_preferred_stack_boundary_arg, min, max);
- }
- else
- ix86_preferred_stack_boundary
- = (1 << ix86_preferred_stack_boundary_arg) * BITS_PER_UNIT;
- }
-
- /* Set the default value for -mstackrealign. */
- if (ix86_force_align_arg_pointer == -1)
- ix86_force_align_arg_pointer = STACK_REALIGN_DEFAULT;
-
- ix86_default_incoming_stack_boundary = PREFERRED_STACK_BOUNDARY;
-
- /* Validate -mincoming-stack-boundary= value or default it to
- MIN_STACK_BOUNDARY/PREFERRED_STACK_BOUNDARY. */
- ix86_incoming_stack_boundary = ix86_default_incoming_stack_boundary;
- if (global_options_set.x_ix86_incoming_stack_boundary_arg)
- {
- if (ix86_incoming_stack_boundary_arg < (TARGET_64BIT ? 4 : 2)
- || ix86_incoming_stack_boundary_arg > 12)
- error ("-mincoming-stack-boundary=%d is not between %d and 12",
- ix86_incoming_stack_boundary_arg, TARGET_64BIT ? 4 : 2);
- else
- {
- ix86_user_incoming_stack_boundary
- = (1 << ix86_incoming_stack_boundary_arg) * BITS_PER_UNIT;
- ix86_incoming_stack_boundary
- = ix86_user_incoming_stack_boundary;
- }
- }
-
- /* Accept -msseregparm only if at least SSE support is enabled. */
- if (TARGET_SSEREGPARM
- && ! TARGET_SSE)
- error ("%ssseregparm%s used without SSE enabled", prefix, suffix);
-
- if (global_options_set.x_ix86_fpmath)
- {
- if (ix86_fpmath & FPMATH_SSE)
- {
- if (!TARGET_SSE)
- {
- warning (0, "SSE instruction set disabled, using 387 arithmetics");
- ix86_fpmath = FPMATH_387;
- }
- else if ((ix86_fpmath & FPMATH_387) && !TARGET_80387)
- {
- warning (0, "387 instruction set disabled, using SSE arithmetics");
- ix86_fpmath = FPMATH_SSE;
- }
- }
- }
- else
- ix86_fpmath = TARGET_FPMATH_DEFAULT;
-
- /* If the i387 is disabled, then do not return values in it. */
- if (!TARGET_80387)
- target_flags &= ~MASK_FLOAT_RETURNS;
-
- /* Use external vectorized library in vectorizing intrinsics. */
- if (global_options_set.x_ix86_veclibabi_type)
- switch (ix86_veclibabi_type)
- {
- case ix86_veclibabi_type_svml:
- ix86_veclib_handler = ix86_veclibabi_svml;
- break;
-
- case ix86_veclibabi_type_acml:
- ix86_veclib_handler = ix86_veclibabi_acml;
- break;
-
- default:
- gcc_unreachable ();
- }
-
- if ((!USE_IX86_FRAME_POINTER
- || (x86_accumulate_outgoing_args & ix86_tune_mask))
- && !(target_flags_explicit & MASK_ACCUMULATE_OUTGOING_ARGS)
- && !optimize_size)
- target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS;
-
- /* ??? Unwind info is not correct around the CFG unless either a frame
- pointer is present or M_A_O_A is set. Fixing this requires rewriting
- unwind info generation to be aware of the CFG and propagating states
- around edges. */
- if ((flag_unwind_tables || flag_asynchronous_unwind_tables
- || flag_exceptions || flag_non_call_exceptions)
- && flag_omit_frame_pointer
- && !(target_flags & MASK_ACCUMULATE_OUTGOING_ARGS))
- {
- if (target_flags_explicit & MASK_ACCUMULATE_OUTGOING_ARGS)
- warning (0, "unwind tables currently require either a frame pointer "
- "or %saccumulate-outgoing-args%s for correctness",
- prefix, suffix);
- 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 %saccumulate-outgoing-args%s "
- "for correctness", prefix, suffix);
- target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS;
- }
-
- /* Figure out what ASM_GENERATE_INTERNAL_LABEL builds as a prefix. */
- {
- char *p;
- ASM_GENERATE_INTERNAL_LABEL (internal_label_prefix, "LX", 0);
- p = strchr (internal_label_prefix, 'X');
- internal_label_prefix_len = p - internal_label_prefix;
- *p = '\0';
- }
-
- /* When scheduling description is not available, disable scheduler pass
- so it won't slow down the compilation and make x87 code slower. */
- if (!TARGET_SCHEDULE)
- flag_schedule_insns_after_reload = flag_schedule_insns = 0;
-
- maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES,
- ix86_tune_cost->simultaneous_prefetches,
- global_options.x_param_values,
- global_options_set.x_param_values);
- maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE,
- ix86_tune_cost->prefetch_block,
- global_options.x_param_values,
- global_options_set.x_param_values);
- maybe_set_param_value (PARAM_L1_CACHE_SIZE,
- ix86_tune_cost->l1_cache_size,
- global_options.x_param_values,
- global_options_set.x_param_values);
- maybe_set_param_value (PARAM_L2_CACHE_SIZE,
- ix86_tune_cost->l2_cache_size,
- global_options.x_param_values,
- global_options_set.x_param_values);
-
- /* Enable sw prefetching at -O3 for CPUS that prefetching is helpful. */
- if (flag_prefetch_loop_arrays < 0
- && HAVE_prefetch
- && (optimize >= 3 || flag_profile_use)
- && TARGET_SOFTWARE_PREFETCHING_BENEFICIAL)
- flag_prefetch_loop_arrays = 1;
-
- /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
- can be optimized to ap = __builtin_next_arg (0). */
- if (!TARGET_64BIT && !flag_split_stack)
- targetm.expand_builtin_va_start = NULL;
-
- if (TARGET_64BIT)
- {
- ix86_gen_leave = gen_leave_rex64;
- if (Pmode == DImode)
- {
- ix86_gen_monitor = gen_sse3_monitor64_di;
- ix86_gen_tls_global_dynamic_64 = gen_tls_global_dynamic_64_di;
- ix86_gen_tls_local_dynamic_base_64
- = gen_tls_local_dynamic_base_64_di;
- }
- else
- {
- ix86_gen_monitor = gen_sse3_monitor64_si;
- ix86_gen_tls_global_dynamic_64 = gen_tls_global_dynamic_64_si;
- ix86_gen_tls_local_dynamic_base_64
- = gen_tls_local_dynamic_base_64_si;
- }
- }
- else
- {
- ix86_gen_leave = gen_leave;
- ix86_gen_monitor = gen_sse3_monitor;
- }
-
- if (Pmode == DImode)
- {
- ix86_gen_add3 = gen_adddi3;
- ix86_gen_sub3 = gen_subdi3;
- ix86_gen_sub3_carry = gen_subdi3_carry;
- ix86_gen_one_cmpl2 = gen_one_cmpldi2;
- ix86_gen_andsp = gen_anddi3;
- ix86_gen_allocate_stack_worker = gen_allocate_stack_worker_probe_di;
- ix86_gen_adjust_stack_and_probe = gen_adjust_stack_and_probedi;
- ix86_gen_probe_stack_range = gen_probe_stack_rangedi;
- }
- else
- {
- ix86_gen_add3 = gen_addsi3;
- ix86_gen_sub3 = gen_subsi3;
- ix86_gen_sub3_carry = gen_subsi3_carry;
- ix86_gen_one_cmpl2 = gen_one_cmplsi2;
- ix86_gen_andsp = gen_andsi3;
- ix86_gen_allocate_stack_worker = gen_allocate_stack_worker_probe_si;
- ix86_gen_adjust_stack_and_probe = gen_adjust_stack_and_probesi;
- ix86_gen_probe_stack_range = gen_probe_stack_rangesi;
- }
-
-#ifdef USE_IX86_CLD
- /* Use -mcld by default for 32-bit code if configured with --enable-cld. */
- if (!TARGET_64BIT)
- target_flags |= MASK_CLD & ~target_flags_explicit;
-#endif
-
- if (!TARGET_64BIT && flag_pic)
- {
- if (flag_fentry > 0)
- sorry ("-mfentry isn%'t supported for 32-bit in combination "
- "with -fpic");
- flag_fentry = 0;
- }
- else if (TARGET_SEH)
- {
- if (flag_fentry == 0)
- sorry ("-mno-fentry isn%'t compatible with SEH");
- flag_fentry = 1;
- }
- else if (flag_fentry < 0)
- {
-#if defined(PROFILE_BEFORE_PROLOGUE)
- flag_fentry = 1;
-#else
- flag_fentry = 0;
-#endif
- }
-
- if (TARGET_AVX)
- {
- /* When not optimize for size, enable vzeroupper optimization for
- TARGET_AVX with -fexpensive-optimizations and split 32-byte
- AVX unaligned load/store. */
- if (!optimize_size)
- {
- if (flag_expensive_optimizations
- && !(target_flags_explicit & MASK_VZEROUPPER))
- target_flags |= MASK_VZEROUPPER;
- if ((x86_avx256_split_unaligned_load & ix86_tune_mask)
- && !(target_flags_explicit & MASK_AVX256_SPLIT_UNALIGNED_LOAD))
- target_flags |= MASK_AVX256_SPLIT_UNALIGNED_LOAD;
- if ((x86_avx256_split_unaligned_store & ix86_tune_mask)
- && !(target_flags_explicit & MASK_AVX256_SPLIT_UNALIGNED_STORE))
- target_flags |= MASK_AVX256_SPLIT_UNALIGNED_STORE;
- /* Enable 128-bit AVX instruction generation
- for the auto-vectorizer. */
- if (TARGET_AVX128_OPTIMAL
- && !(target_flags_explicit & MASK_PREFER_AVX128))
- target_flags |= MASK_PREFER_AVX128;
- }
- }
- else
- {
- /* Disable vzeroupper pass if TARGET_AVX is disabled. */
- target_flags &= ~MASK_VZEROUPPER;
- }
-
- if (ix86_recip_name)
- {
- char *p = ASTRDUP (ix86_recip_name);
- char *q;
- unsigned int mask, i;
- bool invert;
-
- while ((q = strtok (p, ",")) != NULL)
- {
- p = NULL;
- if (*q == '!')
- {
- invert = true;
- q++;
- }
- else
- invert = false;
-
- if (!strcmp (q, "default"))
- mask = RECIP_MASK_ALL;
- else
- {
- for (i = 0; i < ARRAY_SIZE (recip_options); i++)
- if (!strcmp (q, recip_options[i].string))
- {
- mask = recip_options[i].mask;
- break;
- }
-
- if (i == ARRAY_SIZE (recip_options))
- {
- error ("unknown option for -mrecip=%s", q);
- invert = false;
- mask = RECIP_MASK_NONE;
- }
- }
-
- recip_mask_explicit |= mask;
- if (invert)
- recip_mask &= ~mask;
- else
- recip_mask |= mask;
- }
- }
-
- if (TARGET_RECIP)
- recip_mask |= RECIP_MASK_ALL & ~recip_mask_explicit;
- else if (target_flags_explicit & MASK_RECIP)
- recip_mask &= ~(RECIP_MASK_ALL & ~recip_mask_explicit);
-
- /* Default long double to 64-bit for Bionic. */
- if (TARGET_HAS_BIONIC
- && !(target_flags_explicit & MASK_LONG_DOUBLE_64))
- target_flags |= MASK_LONG_DOUBLE_64;
-
- /* Save the initial options in case the user does function specific
- options. */
- if (main_args_p)
- target_option_default_node = target_option_current_node
- = build_target_option_node ();
-
- /* Handle stack protector */
- if (!global_options_set.x_ix86_stack_protector_guard)
- ix86_stack_protector_guard = TARGET_HAS_BIONIC ? SSP_GLOBAL : SSP_TLS;
-}
-
-/* Implement the TARGET_OPTION_OVERRIDE hook. */
-
-static void
-ix86_option_override (void)
-{
- static struct register_pass_info insert_vzeroupper_info
- = { &pass_insert_vzeroupper.pass, "reload",
- 1, PASS_POS_INSERT_AFTER
- };
-
- ix86_option_override_internal (true);
-
-
- /* This needs to be done at start up. It's convenient to do it here. */
- register_pass (&insert_vzeroupper_info);
-}
-
-/* Update register usage after having seen the compiler flags. */
-
-static void
-ix86_conditional_register_usage (void)
-{
- int i, c_mask;
- unsigned int j;
-
- /* The PIC register, if it exists, is fixed. */
- j = PIC_OFFSET_TABLE_REGNUM;
- if (j != INVALID_REGNUM)
- fixed_regs[j] = call_used_regs[j] = 1;
-
- /* For 32-bit targets, squash the REX registers. */
- if (! TARGET_64BIT)
- {
- for (i = FIRST_REX_INT_REG; i <= LAST_REX_INT_REG; i++)
- fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = "";
- for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
- fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = "";
- }
-
- /* See the definition of CALL_USED_REGISTERS in i386.h. */
- c_mask = (TARGET_64BIT_MS_ABI ? (1 << 3)
- : TARGET_64BIT ? (1 << 2)
- : (1 << 1));
-
- CLEAR_HARD_REG_SET (reg_class_contents[(int)CLOBBERED_REGS]);
-
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- {
- /* Set/reset conditionally defined registers from
- CALL_USED_REGISTERS initializer. */
- if (call_used_regs[i] > 1)
- call_used_regs[i] = !!(call_used_regs[i] & c_mask);
-
- /* Calculate registers of CLOBBERED_REGS register set
- as call used registers from GENERAL_REGS register set. */
- if (TEST_HARD_REG_BIT (reg_class_contents[(int)GENERAL_REGS], i)
- && call_used_regs[i])
- SET_HARD_REG_BIT (reg_class_contents[(int)CLOBBERED_REGS], i);
- }
-
- /* If MMX is disabled, squash the registers. */
- if (! TARGET_MMX)
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (TEST_HARD_REG_BIT (reg_class_contents[(int)MMX_REGS], i))
- fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = "";
-
- /* If SSE is disabled, squash the registers. */
- if (! TARGET_SSE)
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (TEST_HARD_REG_BIT (reg_class_contents[(int)SSE_REGS], i))
- fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = "";
-
- /* If the FPU is disabled, squash the registers. */
- if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (TEST_HARD_REG_BIT (reg_class_contents[(int)FLOAT_REGS], i))
- fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = "";
-}
-
-
-/* Save the current options */
-
-static void
-ix86_function_specific_save (struct cl_target_option *ptr)
-{
- ptr->arch = ix86_arch;
- ptr->schedule = ix86_schedule;
- ptr->tune = ix86_tune;
- ptr->branch_cost = ix86_branch_cost;
- ptr->tune_defaulted = ix86_tune_defaulted;
- ptr->arch_specified = ix86_arch_specified;
- ptr->x_ix86_isa_flags_explicit = ix86_isa_flags_explicit;
- ptr->ix86_target_flags_explicit = target_flags_explicit;
- ptr->x_recip_mask_explicit = recip_mask_explicit;
-
- /* The fields are char but the variables are not; make sure the
- values fit in the fields. */
- gcc_assert (ptr->arch == ix86_arch);
- gcc_assert (ptr->schedule == ix86_schedule);
- gcc_assert (ptr->tune == ix86_tune);
- gcc_assert (ptr->branch_cost == ix86_branch_cost);
-}
-
-/* Restore the current options */
-
-static void
-ix86_function_specific_restore (struct cl_target_option *ptr)
-{
- enum processor_type old_tune = ix86_tune;
- enum processor_type old_arch = ix86_arch;
- unsigned int ix86_arch_mask, ix86_tune_mask;
- int i;
-
- ix86_arch = (enum processor_type) ptr->arch;
- ix86_schedule = (enum attr_cpu) ptr->schedule;
- ix86_tune = (enum processor_type) ptr->tune;
- ix86_branch_cost = ptr->branch_cost;
- ix86_tune_defaulted = ptr->tune_defaulted;
- ix86_arch_specified = ptr->arch_specified;
- ix86_isa_flags_explicit = ptr->x_ix86_isa_flags_explicit;
- target_flags_explicit = ptr->ix86_target_flags_explicit;
- recip_mask_explicit = ptr->x_recip_mask_explicit;
-
- /* Recreate the arch feature tests if the arch changed */
- if (old_arch != ix86_arch)
- {
- ix86_arch_mask = 1u << ix86_arch;
- for (i = 0; i < X86_ARCH_LAST; ++i)
- ix86_arch_features[i]
- = !!(initial_ix86_arch_features[i] & ix86_arch_mask);
- }
-
- /* Recreate the tune optimization tests */
- if (old_tune != ix86_tune)
- {
- ix86_tune_mask = 1u << ix86_tune;
- for (i = 0; i < X86_TUNE_LAST; ++i)
- ix86_tune_features[i]
- = !!(initial_ix86_tune_features[i] & ix86_tune_mask);
- }
-}
-
-/* Print the current options */
-
-static void
-ix86_function_specific_print (FILE *file, int indent,
- struct cl_target_option *ptr)
-{
- char *target_string
- = ix86_target_string (ptr->x_ix86_isa_flags, ptr->x_target_flags,
- NULL, NULL, ptr->x_ix86_fpmath, false);
-
- fprintf (file, "%*sarch = %d (%s)\n",
- indent, "",
- ptr->arch,
- ((ptr->arch < TARGET_CPU_DEFAULT_max)
- ? cpu_names[ptr->arch]
- : "<unknown>"));
-
- fprintf (file, "%*stune = %d (%s)\n",
- indent, "",
- ptr->tune,
- ((ptr->tune < TARGET_CPU_DEFAULT_max)
- ? cpu_names[ptr->tune]
- : "<unknown>"));
-
- fprintf (file, "%*sbranch_cost = %d\n", indent, "", ptr->branch_cost);
-
- if (target_string)
- {
- fprintf (file, "%*s%s\n", indent, "", target_string);
- free (target_string);
- }
-}
-
-
-/* Inner function to process the attribute((target(...))), take an argument and
- set the current options from the argument. If we have a list, recursively go
- over the list. */
-
-static bool
-ix86_valid_target_attribute_inner_p (tree args, char *p_strings[],
- struct gcc_options *enum_opts_set)
-{
- char *next_optstr;
- bool ret = true;
-
-#define IX86_ATTR_ISA(S,O) { S, sizeof (S)-1, ix86_opt_isa, O, 0 }
-#define IX86_ATTR_STR(S,O) { S, sizeof (S)-1, ix86_opt_str, O, 0 }
-#define IX86_ATTR_ENUM(S,O) { S, sizeof (S)-1, ix86_opt_enum, O, 0 }
-#define IX86_ATTR_YES(S,O,M) { S, sizeof (S)-1, ix86_opt_yes, O, M }
-#define IX86_ATTR_NO(S,O,M) { S, sizeof (S)-1, ix86_opt_no, O, M }
-
- enum ix86_opt_type
- {
- ix86_opt_unknown,
- ix86_opt_yes,
- ix86_opt_no,
- ix86_opt_str,
- ix86_opt_enum,
- ix86_opt_isa
- };
-
- static const struct
- {
- const char *string;
- size_t len;
- enum ix86_opt_type type;
- int opt;
- int mask;
- } attrs[] = {
- /* isa options */
- IX86_ATTR_ISA ("3dnow", OPT_m3dnow),
- IX86_ATTR_ISA ("abm", OPT_mabm),
- IX86_ATTR_ISA ("bmi", OPT_mbmi),
- IX86_ATTR_ISA ("bmi2", OPT_mbmi2),
- IX86_ATTR_ISA ("lzcnt", OPT_mlzcnt),
- IX86_ATTR_ISA ("tbm", OPT_mtbm),
- IX86_ATTR_ISA ("aes", OPT_maes),
- IX86_ATTR_ISA ("avx", OPT_mavx),
- IX86_ATTR_ISA ("avx2", OPT_mavx2),
- IX86_ATTR_ISA ("mmx", OPT_mmmx),
- IX86_ATTR_ISA ("pclmul", OPT_mpclmul),
- IX86_ATTR_ISA ("popcnt", OPT_mpopcnt),
- IX86_ATTR_ISA ("sse", OPT_msse),
- IX86_ATTR_ISA ("sse2", OPT_msse2),
- IX86_ATTR_ISA ("sse3", OPT_msse3),
- IX86_ATTR_ISA ("sse4", OPT_msse4),
- IX86_ATTR_ISA ("sse4.1", OPT_msse4_1),
- IX86_ATTR_ISA ("sse4.2", OPT_msse4_2),
- IX86_ATTR_ISA ("sse4a", OPT_msse4a),
- IX86_ATTR_ISA ("ssse3", OPT_mssse3),
- IX86_ATTR_ISA ("fma4", OPT_mfma4),
- IX86_ATTR_ISA ("fma", OPT_mfma),
- IX86_ATTR_ISA ("xop", OPT_mxop),
- IX86_ATTR_ISA ("lwp", OPT_mlwp),
- IX86_ATTR_ISA ("fsgsbase", OPT_mfsgsbase),
- IX86_ATTR_ISA ("rdrnd", OPT_mrdrnd),
- IX86_ATTR_ISA ("f16c", OPT_mf16c),
- IX86_ATTR_ISA ("rtm", OPT_mrtm),
- IX86_ATTR_ISA ("hle", OPT_mhle),
- IX86_ATTR_ISA ("prfchw", OPT_mprfchw),
- IX86_ATTR_ISA ("rdseed", OPT_mrdseed),
- IX86_ATTR_ISA ("adx", OPT_madx),
- IX86_ATTR_ISA ("fxsr", OPT_mfxsr),
- IX86_ATTR_ISA ("xsave", OPT_mxsave),
- IX86_ATTR_ISA ("xsaveopt", OPT_mxsaveopt),
-
- /* enum options */
- IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_),
-
- /* string options */
- IX86_ATTR_STR ("arch=", IX86_FUNCTION_SPECIFIC_ARCH),
- IX86_ATTR_STR ("tune=", IX86_FUNCTION_SPECIFIC_TUNE),
-
- /* flag options */
- IX86_ATTR_YES ("cld",
- OPT_mcld,
- MASK_CLD),
-
- IX86_ATTR_NO ("fancy-math-387",
- OPT_mfancy_math_387,
- MASK_NO_FANCY_MATH_387),
-
- IX86_ATTR_YES ("ieee-fp",
- OPT_mieee_fp,
- MASK_IEEE_FP),
-
- IX86_ATTR_YES ("inline-all-stringops",
- OPT_minline_all_stringops,
- MASK_INLINE_ALL_STRINGOPS),
-
- IX86_ATTR_YES ("inline-stringops-dynamically",
- OPT_minline_stringops_dynamically,
- MASK_INLINE_STRINGOPS_DYNAMICALLY),
-
- IX86_ATTR_NO ("align-stringops",
- OPT_mno_align_stringops,
- MASK_NO_ALIGN_STRINGOPS),
-
- IX86_ATTR_YES ("recip",
- OPT_mrecip,
- MASK_RECIP),
-
- };
-
- /* If this is a list, recurse to get the options. */
- if (TREE_CODE (args) == TREE_LIST)
- {
- bool ret = true;
-
- for (; args; args = TREE_CHAIN (args))
- if (TREE_VALUE (args)
- && !ix86_valid_target_attribute_inner_p (TREE_VALUE (args),
- p_strings, enum_opts_set))
- ret = false;
-
- return ret;
- }
-
- else if (TREE_CODE (args) != STRING_CST)
- {
- error ("attribute %<target%> argument not a string");
- return false;
- }
-
- /* Handle multiple arguments separated by commas. */
- next_optstr = ASTRDUP (TREE_STRING_POINTER (args));
-
- while (next_optstr && *next_optstr != '\0')
- {
- char *p = next_optstr;
- char *orig_p = p;
- char *comma = strchr (next_optstr, ',');
- const char *opt_string;
- size_t len, opt_len;
- int opt;
- bool opt_set_p;
- char ch;
- unsigned i;
- enum ix86_opt_type type = ix86_opt_unknown;
- int mask = 0;
-
- if (comma)
- {
- *comma = '\0';
- len = comma - next_optstr;
- next_optstr = comma + 1;
- }
- else
- {
- len = strlen (p);
- next_optstr = NULL;
- }
-
- /* Recognize no-xxx. */
- if (len > 3 && p[0] == 'n' && p[1] == 'o' && p[2] == '-')
- {
- opt_set_p = false;
- p += 3;
- len -= 3;
- }
- else
- opt_set_p = true;
-
- /* Find the option. */
- ch = *p;
- opt = N_OPTS;
- for (i = 0; i < ARRAY_SIZE (attrs); i++)
- {
- type = attrs[i].type;
- opt_len = attrs[i].len;
- if (ch == attrs[i].string[0]
- && ((type != ix86_opt_str && type != ix86_opt_enum)
- ? len == opt_len
- : len > opt_len)
- && memcmp (p, attrs[i].string, opt_len) == 0)
- {
- opt = attrs[i].opt;
- mask = attrs[i].mask;
- opt_string = attrs[i].string;
- break;
- }
- }
-
- /* Process the option. */
- if (opt == N_OPTS)
- {
- error ("attribute(target(\"%s\")) is unknown", orig_p);
- ret = false;
- }
-
- else if (type == ix86_opt_isa)
- {
- struct cl_decoded_option decoded;
-
- generate_option (opt, NULL, opt_set_p, CL_TARGET, &decoded);
- ix86_handle_option (&global_options, &global_options_set,
- &decoded, input_location);
- }
-
- else if (type == ix86_opt_yes || type == ix86_opt_no)
- {
- if (type == ix86_opt_no)
- opt_set_p = !opt_set_p;
-
- if (opt_set_p)
- target_flags |= mask;
- else
- target_flags &= ~mask;
- }
-
- else if (type == ix86_opt_str)
- {
- if (p_strings[opt])
- {
- error ("option(\"%s\") was already specified", opt_string);
- ret = false;
- }
- else
- p_strings[opt] = xstrdup (p + opt_len);
- }
-
- else if (type == ix86_opt_enum)
- {
- bool arg_ok;
- int value;
-
- arg_ok = opt_enum_arg_to_value (opt, p + opt_len, &value, CL_TARGET);
- if (arg_ok)
- set_option (&global_options, enum_opts_set, opt, value,
- p + opt_len, DK_UNSPECIFIED, input_location,
- global_dc);
- else
- {
- error ("attribute(target(\"%s\")) is unknown", orig_p);
- ret = false;
- }
- }
-
- else
- gcc_unreachable ();
- }
-
- return ret;
-}
-
-/* Return a TARGET_OPTION_NODE tree of the target options listed or NULL. */
-
-tree
-ix86_valid_target_attribute_tree (tree args)
-{
- const char *orig_arch_string = ix86_arch_string;
- const char *orig_tune_string = ix86_tune_string;
- enum fpmath_unit orig_fpmath_set = global_options_set.x_ix86_fpmath;
- int orig_tune_defaulted = ix86_tune_defaulted;
- int orig_arch_specified = ix86_arch_specified;
- char *option_strings[IX86_FUNCTION_SPECIFIC_MAX] = { NULL, NULL };
- tree t = NULL_TREE;
- int i;
- struct cl_target_option *def
- = TREE_TARGET_OPTION (target_option_default_node);
- struct gcc_options enum_opts_set;
-
- memset (&enum_opts_set, 0, sizeof (enum_opts_set));
-
- /* Process each of the options on the chain. */
- if (! ix86_valid_target_attribute_inner_p (args, option_strings,
- &enum_opts_set))
- return error_mark_node;
-
- /* If the changed options are different from the default, rerun
- ix86_option_override_internal, and then save the options away.
- The string options are are attribute options, and will be undone
- when we copy the save structure. */
- if (ix86_isa_flags != def->x_ix86_isa_flags
- || target_flags != def->x_target_flags
- || option_strings[IX86_FUNCTION_SPECIFIC_ARCH]
- || option_strings[IX86_FUNCTION_SPECIFIC_TUNE]
- || enum_opts_set.x_ix86_fpmath)
- {
- /* If we are using the default tune= or arch=, undo the string assigned,
- and use the default. */
- if (option_strings[IX86_FUNCTION_SPECIFIC_ARCH])
- ix86_arch_string = option_strings[IX86_FUNCTION_SPECIFIC_ARCH];
- else if (!orig_arch_specified)
- ix86_arch_string = NULL;
-
- if (option_strings[IX86_FUNCTION_SPECIFIC_TUNE])
- ix86_tune_string = option_strings[IX86_FUNCTION_SPECIFIC_TUNE];
- else if (orig_tune_defaulted)
- ix86_tune_string = NULL;
-
- /* If fpmath= is not set, and we now have sse2 on 32-bit, use it. */
- if (enum_opts_set.x_ix86_fpmath)
- global_options_set.x_ix86_fpmath = (enum fpmath_unit) 1;
- else if (!TARGET_64BIT && TARGET_SSE)
- {
- ix86_fpmath = (enum fpmath_unit) (FPMATH_SSE | FPMATH_387);
- global_options_set.x_ix86_fpmath = (enum fpmath_unit) 1;
- }
-
- /* Do any overrides, such as arch=xxx, or tune=xxx support. */
- ix86_option_override_internal (false);
-
- /* Add any builtin functions with the new isa if any. */
- ix86_add_new_builtins (ix86_isa_flags);
-
- /* Save the current options unless we are validating options for
- #pragma. */
- t = build_target_option_node ();
-
- ix86_arch_string = orig_arch_string;
- ix86_tune_string = orig_tune_string;
- global_options_set.x_ix86_fpmath = orig_fpmath_set;
-
- /* Free up memory allocated to hold the strings */
- for (i = 0; i < IX86_FUNCTION_SPECIFIC_MAX; i++)
- free (option_strings[i]);
- }
-
- return t;
-}
-
-/* Hook to validate attribute((target("string"))). */
-
-static bool
-ix86_valid_target_attribute_p (tree fndecl,
- tree ARG_UNUSED (name),
- tree args,
- int ARG_UNUSED (flags))
-{
- struct cl_target_option cur_target;
- bool ret = true;
-
- /* attribute((target("default"))) does nothing, beyond
- affecting multi-versioning. */
- if (TREE_VALUE (args)
- && TREE_CODE (TREE_VALUE (args)) == STRING_CST
- && TREE_CHAIN (args) == NULL_TREE
- && strcmp (TREE_STRING_POINTER (TREE_VALUE (args)), "default") == 0)
- return true;
-
- tree old_optimize = build_optimization_node ();
- tree new_target, new_optimize;
- tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
-
- /* If the function changed the optimization levels as well as setting target
- options, start with the optimizations specified. */
- if (func_optimize && func_optimize != old_optimize)
- cl_optimization_restore (&global_options,
- TREE_OPTIMIZATION (func_optimize));
-
- /* The target attributes may also change some optimization flags, so update
- the optimization options if necessary. */
- cl_target_option_save (&cur_target, &global_options);
- new_target = ix86_valid_target_attribute_tree (args);
- new_optimize = build_optimization_node ();
-
- if (new_target == error_mark_node)
- ret = false;
-
- else if (fndecl && new_target)
- {
- DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
-
- if (old_optimize != new_optimize)
- DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
- }
-
- cl_target_option_restore (&global_options, &cur_target);
-
- if (old_optimize != new_optimize)
- cl_optimization_restore (&global_options,
- TREE_OPTIMIZATION (old_optimize));
-
- return ret;
-}
-
-
-/* Hook to determine if one function can safely inline another. */
-
-static bool
-ix86_can_inline_p (tree caller, tree callee)
-{
- bool ret = false;
- tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
- tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
-
- /* If callee has no option attributes, then it is ok to inline. */
- if (!callee_tree)
- ret = true;
-
- /* If caller has no option attributes, but callee does then it is not ok to
- inline. */
- else if (!caller_tree)
- ret = false;
-
- else
- {
- struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
- struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
-
- /* Callee's isa options should a subset of the caller's, i.e. a SSE4 function
- can inline a SSE2 function but a SSE2 function can't inline a SSE4
- function. */
- if ((caller_opts->x_ix86_isa_flags & callee_opts->x_ix86_isa_flags)
- != callee_opts->x_ix86_isa_flags)
- ret = false;
-
- /* See if we have the same non-isa options. */
- else if (caller_opts->x_target_flags != callee_opts->x_target_flags)
- ret = false;
-
- /* See if arch, tune, etc. are the same. */
- else if (caller_opts->arch != callee_opts->arch)
- ret = false;
-
- else if (caller_opts->tune != callee_opts->tune)
- ret = false;
-
- else if (caller_opts->x_ix86_fpmath != callee_opts->x_ix86_fpmath)
- ret = false;
-
- else if (caller_opts->branch_cost != callee_opts->branch_cost)
- ret = false;
-
- else
- ret = true;
- }
-
- return ret;
-}
-
-
-/* Remember the last target of ix86_set_current_function. */
-static GTY(()) tree ix86_previous_fndecl;
-
-/* Establish appropriate back-end context for processing the function
- FNDECL. The argument might be NULL to indicate processing at top
- level, outside of any function scope. */
-static void
-ix86_set_current_function (tree fndecl)
-{
- /* Only change the context if the function changes. This hook is called
- several times in the course of compiling a function, and we don't want to
- slow things down too much or call target_reinit when it isn't safe. */
- if (fndecl && fndecl != ix86_previous_fndecl)
- {
- tree old_tree = (ix86_previous_fndecl
- ? DECL_FUNCTION_SPECIFIC_TARGET (ix86_previous_fndecl)
- : NULL_TREE);
-
- tree new_tree = (fndecl
- ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
- : NULL_TREE);
-
- ix86_previous_fndecl = fndecl;
- if (old_tree == new_tree)
- ;
-
- else if (new_tree)
- {
- cl_target_option_restore (&global_options,
- TREE_TARGET_OPTION (new_tree));
- target_reinit ();
- }
-
- else if (old_tree)
- {
- struct cl_target_option *def
- = TREE_TARGET_OPTION (target_option_current_node);
-
- cl_target_option_restore (&global_options, def);
- target_reinit ();
- }
- }
-}
-
-
-/* Return true if this goes in large data/bss. */
-
-static bool
-ix86_in_large_data_p (tree exp)
-{
- if (ix86_cmodel != CM_MEDIUM && ix86_cmodel != CM_MEDIUM_PIC)
- return false;
-
- /* Functions are never large data. */
- if (TREE_CODE (exp) == FUNCTION_DECL)
- return false;
-
- if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
- {
- const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
- if (strcmp (section, ".ldata") == 0
- || strcmp (section, ".lbss") == 0)
- return true;
- return false;
- }
- else
- {
- HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
-
- /* If this is an incomplete type with size 0, then we can't put it
- in data because it might be too big when completed. */
- if (!size || size > ix86_section_threshold)
- return true;
- }
-
- return false;
-}
-
-/* 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 * x86_64_elf_select_section (tree, int, unsigned HOST_WIDE_INT)
- ATTRIBUTE_UNUSED;
-
-static section *
-x86_64_elf_select_section (tree decl, int reloc,
- unsigned HOST_WIDE_INT align)
-{
- if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC)
- && ix86_in_large_data_p (decl))
- {
- const char *sname = NULL;
- unsigned int flags = SECTION_WRITE;
- switch (categorize_decl_for_section (decl, reloc))
- {
- case SECCAT_DATA:
- sname = ".ldata";
- break;
- case SECCAT_DATA_REL:
- sname = ".ldata.rel";
- break;
- case SECCAT_DATA_REL_LOCAL:
- sname = ".ldata.rel.local";
- break;
- case SECCAT_DATA_REL_RO:
- sname = ".ldata.rel.ro";
- break;
- case SECCAT_DATA_REL_RO_LOCAL:
- sname = ".ldata.rel.ro.local";
- break;
- case SECCAT_BSS:
- sname = ".lbss";
- flags |= SECTION_BSS;
- break;
- case SECCAT_RODATA:
- case SECCAT_RODATA_MERGE_STR:
- case SECCAT_RODATA_MERGE_STR_INIT:
- case SECCAT_RODATA_MERGE_CONST:
- sname = ".lrodata";
- flags = 0;
- break;
- case SECCAT_SRODATA:
- case SECCAT_SDATA:
- case SECCAT_SBSS:
- gcc_unreachable ();
- case SECCAT_TEXT:
- case SECCAT_TDATA:
- case SECCAT_TBSS:
- /* We don't split these for medium model. Place them into
- default sections and hope for best. */
- break;
- }
- if (sname)
- {
- /* We might get called with string constants, but get_named_section
- doesn't like them as they are not DECLs. Also, we need to set
- flags in that case. */
- if (!DECL_P (decl))
- return get_section (sname, flags, NULL);
- return get_named_section (decl, sname, reloc);
- }
- }
- 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 ATTRIBUTE_UNUSED
-x86_64_elf_unique_section (tree decl, int reloc)
-{
- if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC)
- && ix86_in_large_data_p (decl))
- {
- const char *prefix = NULL;
- /* We only need to use .gnu.linkonce if we don't have COMDAT groups. */
- bool one_only = DECL_ONE_ONLY (decl) && !HAVE_COMDAT_GROUP;
-
- switch (categorize_decl_for_section (decl, reloc))
- {
- case SECCAT_DATA:
- case SECCAT_DATA_REL:
- case SECCAT_DATA_REL_LOCAL:
- case SECCAT_DATA_REL_RO:
- case SECCAT_DATA_REL_RO_LOCAL:
- prefix = one_only ? ".ld" : ".ldata";
- break;
- case SECCAT_BSS:
- prefix = one_only ? ".lb" : ".lbss";
- break;
- case SECCAT_RODATA:
- case SECCAT_RODATA_MERGE_STR:
- case SECCAT_RODATA_MERGE_STR_INIT:
- case SECCAT_RODATA_MERGE_CONST:
- prefix = one_only ? ".lr" : ".lrodata";
- break;
- case SECCAT_SRODATA:
- case SECCAT_SDATA:
- case SECCAT_SBSS:
- gcc_unreachable ();
- case SECCAT_TEXT:
- case SECCAT_TDATA:
- case SECCAT_TBSS:
- /* We don't split these for medium model. Place them into
- default sections and hope for best. */
- break;
- }
- if (prefix)
- {
- const char *name, *linkonce;
- char *string;
-
- name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
- name = targetm.strip_name_encoding (name);
-
- /* If we're using one_only, then there needs to be a .gnu.linkonce
- prefix to the section name. */
- linkonce = one_only ? ".gnu.linkonce" : "";
-
- string = ACONCAT ((linkonce, prefix, ".", name, NULL));
-
- DECL_SECTION_NAME (decl) = build_string (strlen (string), string);
- return;
- }
- }
- default_unique_section (decl, reloc);
-}
-
-#ifdef COMMON_ASM_OP
-/* This says how to output assembler code to declare an
- uninitialized external linkage data object.
-
- For medium model x86-64 we need to use .largecomm opcode for
- large objects. */
-void
-x86_elf_aligned_common (FILE *file,
- const char *name, unsigned HOST_WIDE_INT size,
- int align)
-{
- if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC)
- && size > (unsigned int)ix86_section_threshold)
- fputs (".largecomm\t", file);
- else
- fputs (COMMON_ASM_OP, file);
- assemble_name (file, name);
- fprintf (file, "," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n",
- size, align / BITS_PER_UNIT);
-}
-#endif
-
-/* Utility function for targets to use in implementing
- ASM_OUTPUT_ALIGNED_BSS. */
-
-void
-x86_output_aligned_bss (FILE *file, tree decl ATTRIBUTE_UNUSED,
- const char *name, unsigned HOST_WIDE_INT size,
- int align)
-{
- if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC)
- && size > (unsigned int)ix86_section_threshold)
- switch_to_section (get_named_section (decl, ".lbss", 0));
- else
- switch_to_section (bss_section);
- ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
-#ifdef ASM_DECLARE_OBJECT_NAME
- last_assemble_variable_decl = decl;
- ASM_DECLARE_OBJECT_NAME (file, name, decl);
-#else
- /* Standard thing is just output label for the object. */
- ASM_OUTPUT_LABEL (file, name);
-#endif /* ASM_DECLARE_OBJECT_NAME */
- ASM_OUTPUT_SKIP (file, size ? size : 1);
-}
-
-/* Decide whether we must probe the stack before any space allocation
- on this target. It's essentially TARGET_STACK_PROBE except when
- -fstack-check causes the stack to be already probed differently. */
-
-bool
-ix86_target_stack_probe (void)
-{
- /* Do not probe the stack twice if static stack checking is enabled. */
- if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK)
- return false;
-
- return TARGET_STACK_PROBE;
-}
-
-/* Decide whether we can make a sibling call to a function. DECL is the
- declaration of the function being targeted by the call and EXP is the
- CALL_EXPR representing the call. */
-
-static bool
-ix86_function_ok_for_sibcall (tree decl, tree exp)
-{
- tree type, decl_or_type;
- rtx a, b;
-
- /* If we are generating position-independent code, we cannot sibcall
- optimize any indirect call, or a direct call to a global function,
- as the PLT requires %ebx be live. (Darwin does not have a PLT.) */
- if (!TARGET_MACHO
- && !TARGET_64BIT
- && flag_pic
- && (!decl || !targetm.binds_local_p (decl)))
- return false;
-
- /* If we need to align the outgoing stack, then sibcalling would
- unalign the stack, which may break the called function. */
- if (ix86_minimum_incoming_stack_boundary (true)
- < PREFERRED_STACK_BOUNDARY)
- return false;
-
- if (decl)
- {
- decl_or_type = decl;
- type = TREE_TYPE (decl);
- }
- else
- {
- /* We're looking at the CALL_EXPR, we need the type of the function. */
- type = CALL_EXPR_FN (exp); /* pointer expression */
- type = TREE_TYPE (type); /* pointer type */
- type = TREE_TYPE (type); /* function type */
- decl_or_type = type;
- }
-
- /* Check that the return value locations are the same. Like
- if we are returning floats on the 80387 register stack, we cannot
- make a sibcall from a function that doesn't return a float to a
- function that does or, conversely, from a function that does return
- a float to a function that doesn't; the necessary stack adjustment
- would not be executed. This is also the place we notice
- differences in the return value ABI. Note that it is ok for one
- of the functions to have void return type as long as the return
- value of the other is passed in a register. */
- a = ix86_function_value (TREE_TYPE (exp), decl_or_type, false);
- b = ix86_function_value (TREE_TYPE (DECL_RESULT (cfun->decl)),
- cfun->decl, false);
- if (STACK_REG_P (a) || STACK_REG_P (b))
- {
- if (!rtx_equal_p (a, b))
- return false;
- }
- else if (VOID_TYPE_P (TREE_TYPE (DECL_RESULT (cfun->decl))))
- ;
- else if (!rtx_equal_p (a, b))
- return false;
-
- if (TARGET_64BIT)
- {
- /* The SYSV ABI has more call-clobbered registers;
- disallow sibcalls from MS to SYSV. */
- if (cfun->machine->call_abi == MS_ABI
- && ix86_function_type_abi (type) == SYSV_ABI)
- return false;
- }
- else
- {
- /* If this call is indirect, we'll need to be able to use a
- call-clobbered register for the address of the target function.
- Make sure that all such registers are not used for passing
- parameters. Note that DLLIMPORT functions are indirect. */
- if (!decl
- || (TARGET_DLLIMPORT_DECL_ATTRIBUTES && DECL_DLLIMPORT_P (decl)))
- {
- if (ix86_function_regparm (type, NULL) >= 3)
- {
- /* ??? Need to count the actual number of registers to be used,
- not the possible number of registers. Fix later. */
- return false;
- }
- }
- }
-
- /* Otherwise okay. That also includes certain types of indirect calls. */
- return true;
-}
-
-/* Handle "cdecl", "stdcall", "fastcall", "regparm", "thiscall",
- and "sseregparm" calling convention attributes;
- arguments as in struct attribute_spec.handler. */
-
-static tree
-ix86_handle_cconv_attribute (tree *node, tree name,
- tree args,
- int flags ATTRIBUTE_UNUSED,
- bool *no_add_attrs)
-{
- if (TREE_CODE (*node) != FUNCTION_TYPE
- && TREE_CODE (*node) != METHOD_TYPE
- && TREE_CODE (*node) != FIELD_DECL
- && TREE_CODE (*node) != TYPE_DECL)
- {
- warning (OPT_Wattributes, "%qE attribute only applies to functions",
- name);
- *no_add_attrs = true;
- return NULL_TREE;
- }
-
- /* Can combine regparm with all attributes but fastcall, and thiscall. */
- if (is_attribute_p ("regparm", name))
- {
- tree cst;
-
- if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (*node)))
- {
- error ("fastcall and regparm attributes are not compatible");
- }
-
- if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (*node)))
- {
- error ("regparam and thiscall attributes are not compatible");
- }
-
- cst = TREE_VALUE (args);
- if (TREE_CODE (cst) != INTEGER_CST)
- {
- warning (OPT_Wattributes,
- "%qE attribute requires an integer constant argument",
- name);
- *no_add_attrs = true;
- }
- else if (compare_tree_int (cst, REGPARM_MAX) > 0)
- {
- warning (OPT_Wattributes, "argument to %qE attribute larger than %d",
- name, REGPARM_MAX);
- *no_add_attrs = true;
- }
-
- return NULL_TREE;
- }
-
- if (TARGET_64BIT)
- {
- /* Do not warn when emulating the MS ABI. */
- if ((TREE_CODE (*node) != FUNCTION_TYPE
- && TREE_CODE (*node) != METHOD_TYPE)
- || ix86_function_type_abi (*node) != MS_ABI)
- warning (OPT_Wattributes, "%qE attribute ignored",
- name);
- *no_add_attrs = true;
- return NULL_TREE;
- }
-
- /* Can combine fastcall with stdcall (redundant) and sseregparm. */
- if (is_attribute_p ("fastcall", name))
- {
- if (lookup_attribute ("cdecl", TYPE_ATTRIBUTES (*node)))
- {
- error ("fastcall and cdecl attributes are not compatible");
- }
- if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (*node)))
- {
- error ("fastcall and stdcall attributes are not compatible");
- }
- if (lookup_attribute ("regparm", TYPE_ATTRIBUTES (*node)))
- {
- error ("fastcall and regparm attributes are not compatible");
- }
- if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (*node)))
- {
- error ("fastcall and thiscall attributes are not compatible");
- }
- }
-
- /* Can combine stdcall with fastcall (redundant), regparm and
- sseregparm. */
- else if (is_attribute_p ("stdcall", name))
- {
- if (lookup_attribute ("cdecl", TYPE_ATTRIBUTES (*node)))
- {
- error ("stdcall and cdecl attributes are not compatible");
- }
- if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (*node)))
- {
- error ("stdcall and fastcall attributes are not compatible");
- }
- if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (*node)))
- {
- error ("stdcall and thiscall attributes are not compatible");
- }
- }
-
- /* Can combine cdecl with regparm and sseregparm. */
- else if (is_attribute_p ("cdecl", name))
- {
- if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (*node)))
- {
- error ("stdcall and cdecl attributes are not compatible");
- }
- if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (*node)))
- {
- error ("fastcall and cdecl attributes are not compatible");
- }
- if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (*node)))
- {
- error ("cdecl and thiscall attributes are not compatible");
- }
- }
- else if (is_attribute_p ("thiscall", name))
- {
- if (TREE_CODE (*node) != METHOD_TYPE && pedantic)
- warning (OPT_Wattributes, "%qE attribute is used for none class-method",
- name);
- if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (*node)))
- {
- error ("stdcall and thiscall attributes are not compatible");
- }
- if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (*node)))
- {
- error ("fastcall and thiscall attributes are not compatible");
- }
- if (lookup_attribute ("cdecl", TYPE_ATTRIBUTES (*node)))
- {
- error ("cdecl and thiscall attributes are not compatible");
- }
- }
-
- /* Can combine sseregparm with all attributes. */
-
- return NULL_TREE;
-}
-
-/* The transactional memory builtins are implicitly regparm or fastcall
- depending on the ABI. Override the generic do-nothing attribute that
- these builtins were declared with, and replace it with one of the two
- attributes that we expect elsewhere. */
-
-static tree
-ix86_handle_tm_regparm_attribute (tree *node, tree name ATTRIBUTE_UNUSED,
- tree args ATTRIBUTE_UNUSED,
- int flags ATTRIBUTE_UNUSED,
- bool *no_add_attrs)
-{
- tree alt;
-
- /* In no case do we want to add the placeholder attribute. */
- *no_add_attrs = true;
-
- /* The 64-bit ABI is unchanged for transactional memory. */
- if (TARGET_64BIT)
- return NULL_TREE;
-
- /* ??? Is there a better way to validate 32-bit windows? We have
- cfun->machine->call_abi, but that seems to be set only for 64-bit. */
- if (CHECK_STACK_LIMIT > 0)
- alt = tree_cons (get_identifier ("fastcall"), NULL, NULL);
- else
- {
- alt = tree_cons (NULL, build_int_cst (NULL, 2), NULL);
- alt = tree_cons (get_identifier ("regparm"), alt, NULL);
- }
- decl_attributes (node, alt, flags);
-
- return NULL_TREE;
-}
-
-/* This function determines from TYPE the calling-convention. */
-
-unsigned int
-ix86_get_callcvt (const_tree type)
-{
- unsigned int ret = 0;
- bool is_stdarg;
- tree attrs;
-
- if (TARGET_64BIT)
- return IX86_CALLCVT_CDECL;
-
- attrs = TYPE_ATTRIBUTES (type);
- if (attrs != NULL_TREE)
- {
- if (lookup_attribute ("cdecl", attrs))
- ret |= IX86_CALLCVT_CDECL;
- else if (lookup_attribute ("stdcall", attrs))
- ret |= IX86_CALLCVT_STDCALL;
- else if (lookup_attribute ("fastcall", attrs))
- ret |= IX86_CALLCVT_FASTCALL;
- else if (lookup_attribute ("thiscall", attrs))
- ret |= IX86_CALLCVT_THISCALL;
-
- /* Regparam isn't allowed for thiscall and fastcall. */
- if ((ret & (IX86_CALLCVT_THISCALL | IX86_CALLCVT_FASTCALL)) == 0)
- {
- if (lookup_attribute ("regparm", attrs))
- ret |= IX86_CALLCVT_REGPARM;
- if (lookup_attribute ("sseregparm", attrs))
- ret |= IX86_CALLCVT_SSEREGPARM;
- }
-
- if (IX86_BASE_CALLCVT(ret) != 0)
- return ret;
- }
-
- is_stdarg = stdarg_p (type);
- if (TARGET_RTD && !is_stdarg)
- return IX86_CALLCVT_STDCALL | ret;
-
- if (ret != 0
- || is_stdarg
- || TREE_CODE (type) != METHOD_TYPE
- || ix86_function_type_abi (type) != MS_ABI)
- return IX86_CALLCVT_CDECL | ret;
-
- return IX86_CALLCVT_THISCALL;
-}
-
-/* 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
-ix86_comp_type_attributes (const_tree type1, const_tree type2)
-{
- unsigned int ccvt1, ccvt2;
-
- if (TREE_CODE (type1) != FUNCTION_TYPE
- && TREE_CODE (type1) != METHOD_TYPE)
- return 1;
-
- ccvt1 = ix86_get_callcvt (type1);
- ccvt2 = ix86_get_callcvt (type2);
- if (ccvt1 != ccvt2)
- return 0;
- if (ix86_function_regparm (type1, NULL)
- != ix86_function_regparm (type2, NULL))
- return 0;
-
- return 1;
-}
-
-/* Return the regparm value for a function with the indicated TYPE and DECL.
- DECL may be NULL when calling function indirectly
- or considering a libcall. */
-
-static int
-ix86_function_regparm (const_tree type, const_tree decl)
-{
- tree attr;
- int regparm;
- unsigned int ccvt;
-
- if (TARGET_64BIT)
- return (ix86_function_type_abi (type) == SYSV_ABI
- ? X86_64_REGPARM_MAX : X86_64_MS_REGPARM_MAX);
- ccvt = ix86_get_callcvt (type);
- regparm = ix86_regparm;
-
- if ((ccvt & IX86_CALLCVT_REGPARM) != 0)
- {
- attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type));
- if (attr)
- {
- regparm = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
- return regparm;
- }
- }
- else if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
- return 2;
- else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
- return 1;
-
- /* Use register calling convention for local functions when possible. */
- if (decl
- && TREE_CODE (decl) == FUNCTION_DECL
- && optimize
- && !(profile_flag && !flag_fentry))
- {
- /* FIXME: remove this CONST_CAST when cgraph.[ch] is constified. */
- struct cgraph_local_info *i = cgraph_local_info (CONST_CAST_TREE (decl));
- if (i && i->local && i->can_change_signature)
- {
- int local_regparm, globals = 0, regno;
-
- /* Make sure no regparm register is taken by a
- fixed register variable. */
- for (local_regparm = 0; local_regparm < REGPARM_MAX; local_regparm++)
- if (fixed_regs[local_regparm])
- break;
-
- /* We don't want to use regparm(3) for nested functions as
- these use a static chain pointer in the third argument. */
- if (local_regparm == 3 && DECL_STATIC_CHAIN (decl))
- local_regparm = 2;
-
- /* In 32-bit mode save a register for the split stack. */
- if (!TARGET_64BIT && local_regparm == 3 && flag_split_stack)
- local_regparm = 2;
-
- /* Each fixed register usage increases register pressure,
- so less registers should be used for argument passing.
- This functionality can be overriden by an explicit
- regparm value. */
- for (regno = AX_REG; regno <= DI_REG; regno++)
- if (fixed_regs[regno])
- globals++;
-
- local_regparm
- = globals < local_regparm ? local_regparm - globals : 0;
-
- if (local_regparm > regparm)
- regparm = local_regparm;
- }
- }
-
- return regparm;
-}
-
-/* Return 1 or 2, if we can pass up to SSE_REGPARM_MAX SFmode (1) and
- DFmode (2) arguments in SSE registers for a function with the
- indicated TYPE and DECL. DECL may be NULL when calling function
- indirectly or considering a libcall. Otherwise return 0. */
-
-static int
-ix86_function_sseregparm (const_tree type, const_tree decl, bool warn)
-{
- gcc_assert (!TARGET_64BIT);
-
- /* Use SSE registers to pass SFmode and DFmode arguments if requested
- by the sseregparm attribute. */
- if (TARGET_SSEREGPARM
- || (type && lookup_attribute ("sseregparm", TYPE_ATTRIBUTES (type))))
- {
- if (!TARGET_SSE)
- {
- if (warn)
- {
- if (decl)
- error ("calling %qD with attribute sseregparm without "
- "SSE/SSE2 enabled", decl);
- else
- error ("calling %qT with attribute sseregparm without "
- "SSE/SSE2 enabled", type);
- }
- return 0;
- }
-
- return 2;
- }
-
- /* For local functions, pass up to SSE_REGPARM_MAX SFmode
- (and DFmode for SSE2) arguments in SSE registers. */
- if (decl && TARGET_SSE_MATH && optimize
- && !(profile_flag && !flag_fentry))
- {
- /* FIXME: remove this CONST_CAST when cgraph.[ch] is constified. */
- struct cgraph_local_info *i = cgraph_local_info (CONST_CAST_TREE(decl));
- if (i && i->local && i->can_change_signature)
- return TARGET_SSE2 ? 2 : 1;
- }
-
- return 0;
-}
-
-/* Return true if EAX is live at the start of the function. Used by
- ix86_expand_prologue to determine if we need special help before
- calling allocate_stack_worker. */
-
-static bool
-ix86_eax_live_at_start_p (void)
-{
- /* Cheat. Don't bother working forward from ix86_function_regparm
- to the function type to whether an actual argument is located in
- eax. Instead just look at cfg info, which is still close enough
- to correct at this point. This gives false positives for broken
- functions that might use uninitialized data that happens to be
- allocated in eax, but who cares? */
- return REGNO_REG_SET_P (df_get_live_out (ENTRY_BLOCK_PTR), 0);
-}
-
-static bool
-ix86_keep_aggregate_return_pointer (tree fntype)
-{
- tree attr;
-
- if (!TARGET_64BIT)
- {
- attr = lookup_attribute ("callee_pop_aggregate_return",
- TYPE_ATTRIBUTES (fntype));
- if (attr)
- return (TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr))) == 0);
-
- /* For 32-bit MS-ABI the default is to keep aggregate
- return pointer. */
- if (ix86_function_type_abi (fntype) == MS_ABI)
- return true;
- }
- return KEEP_AGGREGATE_RETURN_POINTER != 0;
-}
-
-/* Value is the number of bytes of arguments automatically
- popped when returning from a subroutine call.
- FUNDECL is the declaration node of the function (as a tree),
- FUNTYPE is the data type of the function (as a tree),
- or for a library call it is an identifier node for the subroutine name.
- SIZE is the number of bytes of arguments passed on the stack.
-
- On the 80386, the RTD insn may be used to pop them if the number
- of args is fixed, but if the number is variable then the caller
- must pop them all. RTD can't be used for library calls now
- because the library is compiled with the Unix compiler.
- Use of RTD is a selectable option, since it is incompatible with
- standard Unix calling sequences. If the option is not selected,
- the caller must always pop the args.
-
- The attribute stdcall is equivalent to RTD on a per module basis. */
-
-static int
-ix86_return_pops_args (tree fundecl, tree funtype, int size)
-{
- unsigned int ccvt;
-
- /* None of the 64-bit ABIs pop arguments. */
- if (TARGET_64BIT)
- return 0;
-
- ccvt = ix86_get_callcvt (funtype);
-
- if ((ccvt & (IX86_CALLCVT_STDCALL | IX86_CALLCVT_FASTCALL
- | IX86_CALLCVT_THISCALL)) != 0
- && ! stdarg_p (funtype))
- return size;
-
- /* Lose any fake structure return argument if it is passed on the stack. */
- if (aggregate_value_p (TREE_TYPE (funtype), fundecl)
- && !ix86_keep_aggregate_return_pointer (funtype))
- {
- int nregs = ix86_function_regparm (funtype, fundecl);
- if (nregs == 0)
- return GET_MODE_SIZE (Pmode);
- }
-
- return 0;
-}
-
-/* Implement the TARGET_LEGITIMATE_COMBINED_INSN hook. */
-
-static bool
-ix86_legitimate_combined_insn (rtx insn)
-{
- /* Check operand constraints in case hard registers were propagated
- into insn pattern. This check prevents combine pass from
- generating insn patterns with invalid hard register operands.
- These invalid insns can eventually confuse reload to error out
- with a spill failure. See also PRs 46829 and 46843. */
- if ((INSN_CODE (insn) = recog (PATTERN (insn), insn, 0)) >= 0)
- {
- int i;
-
- extract_insn (insn);
- preprocess_constraints ();
-
- for (i = 0; i < recog_data.n_operands; i++)
- {
- rtx op = recog_data.operand[i];
- enum machine_mode mode = GET_MODE (op);
- struct operand_alternative *op_alt;
- int offset = 0;
- bool win;
- int j;
-
- /* A unary operator may be accepted by the predicate, but it
- is irrelevant for matching constraints. */
- if (UNARY_P (op))
- op = XEXP (op, 0);
-
- if (GET_CODE (op) == SUBREG)
- {
- if (REG_P (SUBREG_REG (op))
- && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER)
- offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
- GET_MODE (SUBREG_REG (op)),
- SUBREG_BYTE (op),
- GET_MODE (op));
- op = SUBREG_REG (op);
- }
-
- if (!(REG_P (op) && HARD_REGISTER_P (op)))
- continue;
-
- op_alt = recog_op_alt[i];
-
- /* Operand has no constraints, anything is OK. */
- win = !recog_data.n_alternatives;
-
- for (j = 0; j < recog_data.n_alternatives; j++)
- {
- if (op_alt[j].anything_ok
- || (op_alt[j].matches != -1
- && operands_match_p
- (recog_data.operand[i],
- recog_data.operand[op_alt[j].matches]))
- || reg_fits_class_p (op, op_alt[j].cl, offset, mode))
- {
- win = true;
- break;
- }
- }
-
- if (!win)
- return false;
- }
- }
-
- return true;
-}
-
-/* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */
-
-static unsigned HOST_WIDE_INT
-ix86_asan_shadow_offset (void)
-{
- return TARGET_LP64 ? (TARGET_MACHO ? (HOST_WIDE_INT_1 << 44)
- : HOST_WIDE_INT_C (0x7fff8000))
- : (HOST_WIDE_INT_1 << 29);
-}
-
-/* Argument support functions. */
-
-/* Return true when register may be used to pass function parameters. */
-bool
-ix86_function_arg_regno_p (int regno)
-{
- int i;
- const int *parm_regs;
-
- if (!TARGET_64BIT)
- {
- if (TARGET_MACHO)
- return (regno < REGPARM_MAX
- || (TARGET_SSE && SSE_REGNO_P (regno) && !fixed_regs[regno]));
- else
- return (regno < REGPARM_MAX
- || (TARGET_MMX && MMX_REGNO_P (regno)
- && (regno < FIRST_MMX_REG + MMX_REGPARM_MAX))
- || (TARGET_SSE && SSE_REGNO_P (regno)
- && (regno < FIRST_SSE_REG + SSE_REGPARM_MAX)));
- }
-
- if (TARGET_MACHO)
- {
- if (SSE_REGNO_P (regno) && TARGET_SSE)
- return true;
- }
- else
- {
- if (TARGET_SSE && SSE_REGNO_P (regno)
- && (regno < FIRST_SSE_REG + SSE_REGPARM_MAX))
- return true;
- }
-
- /* TODO: The function should depend on current function ABI but
- builtins.c would need updating then. Therefore we use the
- default ABI. */
-
- /* RAX is used as hidden argument to va_arg functions. */
- if (ix86_abi == SYSV_ABI && regno == AX_REG)
- return true;
-
- if (ix86_abi == MS_ABI)
- parm_regs = x86_64_ms_abi_int_parameter_registers;
- else
- parm_regs = x86_64_int_parameter_registers;
- for (i = 0; i < (ix86_abi == MS_ABI
- ? X86_64_MS_REGPARM_MAX : X86_64_REGPARM_MAX); i++)
- if (regno == parm_regs[i])
- return true;
- return false;
-}
-
-/* Return if we do not know how to pass TYPE solely in registers. */
-
-static bool
-ix86_must_pass_in_stack (enum machine_mode mode, const_tree type)
-{
- if (must_pass_in_stack_var_size_or_pad (mode, type))
- return true;
-
- /* For 32-bit, we want TImode aggregates to go on the stack. But watch out!
- The layout_type routine is crafty and tries to trick us into passing
- currently unsupported vector types on the stack by using TImode. */
- return (!TARGET_64BIT && mode == TImode
- && type && TREE_CODE (type) != VECTOR_TYPE);
-}
-
-/* It returns the size, in bytes, of the area reserved for arguments passed
- in registers for the function represented by fndecl dependent to the used
- abi format. */
-int
-ix86_reg_parm_stack_space (const_tree fndecl)
-{
- enum calling_abi call_abi = SYSV_ABI;
- if (fndecl != NULL_TREE && TREE_CODE (fndecl) == FUNCTION_DECL)
- call_abi = ix86_function_abi (fndecl);
- else
- call_abi = ix86_function_type_abi (fndecl);
- if (TARGET_64BIT && call_abi == MS_ABI)
- return 32;
- return 0;
-}
-
-/* Returns value SYSV_ABI, MS_ABI dependent on fntype, specifying the
- call abi used. */
-enum calling_abi
-ix86_function_type_abi (const_tree fntype)
-{
- if (fntype != NULL_TREE && TYPE_ATTRIBUTES (fntype) != NULL_TREE)
- {
- enum calling_abi abi = ix86_abi;
- if (abi == SYSV_ABI)
- {
- if (lookup_attribute ("ms_abi", TYPE_ATTRIBUTES (fntype)))
- abi = MS_ABI;
- }
- else if (lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (fntype)))
- abi = SYSV_ABI;
- return abi;
- }
- return ix86_abi;
-}
-
-static bool
-ix86_function_ms_hook_prologue (const_tree fn)
-{
- if (fn && lookup_attribute ("ms_hook_prologue", DECL_ATTRIBUTES (fn)))
- {
- if (decl_function_context (fn) != NULL_TREE)
- error_at (DECL_SOURCE_LOCATION (fn),
- "ms_hook_prologue is not compatible with nested function");
- else
- return true;
- }
- return false;
-}
-
-static enum calling_abi
-ix86_function_abi (const_tree fndecl)
-{
- if (! fndecl)
- return ix86_abi;
- return ix86_function_type_abi (TREE_TYPE (fndecl));
-}
-
-/* Returns value SYSV_ABI, MS_ABI dependent on cfun, specifying the
- call abi used. */
-enum calling_abi
-ix86_cfun_abi (void)
-{
- if (! cfun)
- return ix86_abi;
- return cfun->machine->call_abi;
-}
-
-/* Write the extra assembler code needed to declare a function properly. */
-
-void
-ix86_asm_output_function_label (FILE *asm_out_file, const char *fname,
- tree decl)
-{
- bool is_ms_hook = ix86_function_ms_hook_prologue (decl);
-
- if (is_ms_hook)
- {
- int i, filler_count = (TARGET_64BIT ? 32 : 16);
- unsigned int filler_cc = 0xcccccccc;
-
- for (i = 0; i < filler_count; i += 4)
- fprintf (asm_out_file, ASM_LONG " %#x\n", filler_cc);
- }
-
-#ifdef SUBTARGET_ASM_UNWIND_INIT
- SUBTARGET_ASM_UNWIND_INIT (asm_out_file);
-#endif
-
- ASM_OUTPUT_LABEL (asm_out_file, fname);
-
- /* Output magic byte marker, if hot-patch attribute is set. */
- if (is_ms_hook)
- {
- if (TARGET_64BIT)
- {
- /* leaq [%rsp + 0], %rsp */
- asm_fprintf (asm_out_file, ASM_BYTE
- "0x48, 0x8d, 0xa4, 0x24, 0x00, 0x00, 0x00, 0x00\n");
- }
- else
- {
- /* movl.s %edi, %edi
- push %ebp
- movl.s %esp, %ebp */
- asm_fprintf (asm_out_file, ASM_BYTE
- "0x8b, 0xff, 0x55, 0x8b, 0xec\n");
- }
- }
-}
-
-/* regclass.c */
-extern void init_regs (void);
-
-/* Implementation of call abi switching target hook. Specific to FNDECL
- the specific call register sets are set. See also
- ix86_conditional_register_usage for more details. */
-void
-ix86_call_abi_override (const_tree fndecl)
-{
- if (fndecl == NULL_TREE)
- cfun->machine->call_abi = ix86_abi;
- else
- cfun->machine->call_abi = ix86_function_type_abi (TREE_TYPE (fndecl));
-}
-
-/* 64-bit MS and SYSV ABI have different set of call used registers. Avoid
- expensive re-initialization of init_regs each time we switch function context
- since this is needed only during RTL expansion. */
-static void
-ix86_maybe_switch_abi (void)
-{
- if (TARGET_64BIT &&
- call_used_regs[SI_REG] == (cfun->machine->call_abi == MS_ABI))
- reinit_regs ();
-}
-
-/* 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 0. */
-
-void
-init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */
- tree fntype, /* tree ptr for function decl */
- rtx libname, /* SYMBOL_REF of library name or 0 */
- tree fndecl,
- int caller)
-{
- struct cgraph_local_info *i;
-
- memset (cum, 0, sizeof (*cum));
-
- if (fndecl)
- {
- i = cgraph_local_info (fndecl);
- cum->call_abi = ix86_function_abi (fndecl);
- }
- else
- {
- i = NULL;
- cum->call_abi = ix86_function_type_abi (fntype);
- }
-
- cum->caller = caller;
-
- /* Set up the number of registers to use for passing arguments. */
-
- if (TARGET_64BIT && cum->call_abi == MS_ABI && !ACCUMULATE_OUTGOING_ARGS)
- sorry ("ms_abi attribute requires -maccumulate-outgoing-args "
- "or subtarget optimization implying it");
- cum->nregs = ix86_regparm;
- if (TARGET_64BIT)
- {
- cum->nregs = (cum->call_abi == SYSV_ABI
- ? X86_64_REGPARM_MAX
- : X86_64_MS_REGPARM_MAX);
- }
- if (TARGET_SSE)
- {
- cum->sse_nregs = SSE_REGPARM_MAX;
- if (TARGET_64BIT)
- {
- cum->sse_nregs = (cum->call_abi == SYSV_ABI
- ? X86_64_SSE_REGPARM_MAX
- : X86_64_MS_SSE_REGPARM_MAX);
- }
- }
- if (TARGET_MMX)
- cum->mmx_nregs = MMX_REGPARM_MAX;
- cum->warn_avx = true;
- cum->warn_sse = true;
- cum->warn_mmx = true;
-
- /* Because type might mismatch in between caller and callee, we need to
- use actual type of function for local calls.
- FIXME: cgraph_analyze can be told to actually record if function uses
- va_start so for local functions maybe_vaarg can be made aggressive
- helping K&R code.
- FIXME: once typesytem is fixed, we won't need this code anymore. */
- if (i && i->local && i->can_change_signature)
- fntype = TREE_TYPE (fndecl);
- cum->maybe_vaarg = (fntype
- ? (!prototype_p (fntype) || stdarg_p (fntype))
- : !libname);
-
- if (!TARGET_64BIT)
- {
- /* If there are variable arguments, then we won't pass anything
- in registers in 32-bit mode. */
- if (stdarg_p (fntype))
- {
- cum->nregs = 0;
- cum->sse_nregs = 0;
- cum->mmx_nregs = 0;
- cum->warn_avx = 0;
- cum->warn_sse = 0;
- cum->warn_mmx = 0;
- return;
- }
-
- /* Use ecx and edx registers if function has fastcall attribute,
- else look for regparm information. */
- if (fntype)
- {
- unsigned int ccvt = ix86_get_callcvt (fntype);
- if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
- {
- cum->nregs = 1;
- cum->fastcall = 1; /* Same first register as in fastcall. */
- }
- else if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
- {
- cum->nregs = 2;
- cum->fastcall = 1;
- }
- else
- cum->nregs = ix86_function_regparm (fntype, fndecl);
- }
-
- /* Set up the number of SSE registers used for passing SFmode
- and DFmode arguments. Warn for mismatching ABI. */
- cum->float_in_sse = ix86_function_sseregparm (fntype, fndecl, true);
- }
-}
-
-/* Return the "natural" mode for TYPE. In most cases, this is just TYPE_MODE.
- But in the case of vector types, it is some vector mode.
-
- When we have only some of our vector isa extensions enabled, then there
- are some modes for which vector_mode_supported_p is false. For these
- modes, the generic vector support in gcc will choose some non-vector mode
- in order to implement the type. By computing the natural mode, we'll
- select the proper ABI location for the operand and not depend on whatever
- the middle-end decides to do with these vector types.
-
- The midde-end can't deal with the vector types > 16 bytes. In this
- case, we return the original mode and warn ABI change if CUM isn't
- NULL. */
-
-static enum machine_mode
-type_natural_mode (const_tree type, const CUMULATIVE_ARGS *cum)
-{
- enum machine_mode mode = TYPE_MODE (type);
-
- if (TREE_CODE (type) == VECTOR_TYPE && !VECTOR_MODE_P (mode))
- {
- HOST_WIDE_INT size = int_size_in_bytes (type);
- if ((size == 8 || size == 16 || size == 32)
- /* ??? Generic code allows us to create width 1 vectors. Ignore. */
- && TYPE_VECTOR_SUBPARTS (type) > 1)
- {
- enum machine_mode innermode = TYPE_MODE (TREE_TYPE (type));
-
- if (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE)
- mode = MIN_MODE_VECTOR_FLOAT;
- else
- mode = MIN_MODE_VECTOR_INT;
-
- /* Get the mode which has this inner mode and number of units. */
- for (; mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode))
- if (GET_MODE_NUNITS (mode) == TYPE_VECTOR_SUBPARTS (type)
- && GET_MODE_INNER (mode) == innermode)
- {
- if (size == 32 && !TARGET_AVX)
- {
- static bool warnedavx;
-
- if (cum
- && !warnedavx
- && cum->warn_avx)
- {
- warnedavx = true;
- warning (0, "AVX vector argument without AVX "
- "enabled changes the ABI");
- }
- return TYPE_MODE (type);
- }
- else if ((size == 8 || size == 16) && !TARGET_SSE)
- {
- static bool warnedsse;
-
- if (cum
- && !warnedsse
- && cum->warn_sse)
- {
- warnedsse = true;
- warning (0, "SSE vector argument without SSE "
- "enabled changes the ABI");
- }
- return mode;
- }
- else
- return mode;
- }
-
- gcc_unreachable ();
- }
- }
-
- return mode;
-}
-
-/* We want to pass a value in REGNO whose "natural" mode is MODE. However,
- this may not agree with the mode that the type system has chosen for the
- register, which is ORIG_MODE. If ORIG_MODE is not BLKmode, then we can
- go ahead and use it. Otherwise we have to build a PARALLEL instead. */
-
-static rtx
-gen_reg_or_parallel (enum machine_mode mode, enum machine_mode orig_mode,
- unsigned int regno)
-{
- rtx tmp;
-
- if (orig_mode != BLKmode)
- tmp = gen_rtx_REG (orig_mode, regno);
- else
- {
- tmp = gen_rtx_REG (mode, regno);
- tmp = gen_rtx_EXPR_LIST (VOIDmode, tmp, const0_rtx);
- tmp = gen_rtx_PARALLEL (orig_mode, gen_rtvec (1, tmp));
- }
-
- return tmp;
-}
-
-/* x86-64 register passing implementation. See x86-64 ABI for details. Goal
- of this code is to classify each 8bytes of incoming argument by the register
- class and assign registers accordingly. */
-
-/* Return the union class of CLASS1 and CLASS2.
- See the x86-64 PS ABI for details. */
-
-static enum x86_64_reg_class
-merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
-{
- /* Rule #1: If both classes are equal, this is the resulting class. */
- if (class1 == class2)
- return class1;
-
- /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
- the other class. */
- if (class1 == X86_64_NO_CLASS)
- return class2;
- if (class2 == X86_64_NO_CLASS)
- return class1;
-
- /* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */
- if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
- return X86_64_MEMORY_CLASS;
-
- /* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */
- if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
- || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
- return X86_64_INTEGERSI_CLASS;
- if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
- || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
- return X86_64_INTEGER_CLASS;
-
- /* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87 class,
- MEMORY is used. */
- if (class1 == X86_64_X87_CLASS
- || class1 == X86_64_X87UP_CLASS
- || class1 == X86_64_COMPLEX_X87_CLASS
- || class2 == X86_64_X87_CLASS
- || class2 == X86_64_X87UP_CLASS
- || class2 == X86_64_COMPLEX_X87_CLASS)
- return X86_64_MEMORY_CLASS;
-
- /* Rule #6: Otherwise class SSE is used. */
- return X86_64_SSE_CLASS;
-}
-
-/* Classify the argument of type TYPE and mode MODE.
- CLASSES will be filled by the register class used to pass each word
- of the operand. The number of words is returned. In case the parameter
- should be passed in memory, 0 is returned. As a special case for zero
- sized containers, classes[0] will be NO_CLASS and 1 is returned.
-
- BIT_OFFSET is used internally for handling records and specifies offset
- of the offset in bits modulo 256 to avoid overflow cases.
-
- See the x86-64 PS ABI for details.
-*/
-
-static int
-classify_argument (enum machine_mode mode, const_tree type,
- enum x86_64_reg_class classes[MAX_CLASSES], int bit_offset)
-{
- HOST_WIDE_INT bytes =
- (mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
- int words
- = (bytes + (bit_offset % 64) / 8 + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
-
- /* Variable sized entities are always passed/returned in memory. */
- if (bytes < 0)
- return 0;
-
- if (mode != VOIDmode
- && targetm.calls.must_pass_in_stack (mode, type))
- return 0;
-
- if (type && AGGREGATE_TYPE_P (type))
- {
- int i;
- tree field;
- enum x86_64_reg_class subclasses[MAX_CLASSES];
-
- /* On x86-64 we pass structures larger than 32 bytes on the stack. */
- if (bytes > 32)
- return 0;
-
- for (i = 0; i < words; i++)
- classes[i] = X86_64_NO_CLASS;
-
- /* Zero sized arrays or structures are NO_CLASS. We return 0 to
- signalize memory class, so handle it as special case. */
- if (!words)
- {
- classes[0] = X86_64_NO_CLASS;
- return 1;
- }
-
- /* Classify each field of record and merge classes. */
- switch (TREE_CODE (type))
- {
- case RECORD_TYPE:
- /* And now merge the fields of structure. */
- for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
- {
- if (TREE_CODE (field) == FIELD_DECL)
- {
- int num;
-
- if (TREE_TYPE (field) == error_mark_node)
- continue;
-
- /* Bitfields are always classified as integer. Handle them
- early, since later code would consider them to be
- misaligned integers. */
- if (DECL_BIT_FIELD (field))
- {
- for (i = (int_bit_position (field)
- + (bit_offset % 64)) / 8 / 8;
- i < ((int_bit_position (field) + (bit_offset % 64))
- + tree_low_cst (DECL_SIZE (field), 0)
- + 63) / 8 / 8; i++)
- classes[i] =
- merge_classes (X86_64_INTEGER_CLASS,
- classes[i]);
- }
- else
- {
- int pos;
-
- type = TREE_TYPE (field);
-
- /* Flexible array member is ignored. */
- if (TYPE_MODE (type) == BLKmode
- && TREE_CODE (type) == ARRAY_TYPE
- && TYPE_SIZE (type) == NULL_TREE
- && TYPE_DOMAIN (type) != NULL_TREE
- && (TYPE_MAX_VALUE (TYPE_DOMAIN (type))
- == NULL_TREE))
- {
- static bool warned;
-
- if (!warned && warn_psabi)
- {
- warned = true;
- inform (input_location,
- "the ABI of passing struct with"
- " a flexible array member has"
- " changed in GCC 4.4");
- }
- continue;
- }
- num = classify_argument (TYPE_MODE (type), type,
- subclasses,
- (int_bit_position (field)
- + bit_offset) % 256);
- if (!num)
- return 0;
- pos = (int_bit_position (field)
- + (bit_offset % 64)) / 8 / 8;
- for (i = 0; i < num && (i + pos) < words; i++)
- classes[i + pos] =
- merge_classes (subclasses[i], classes[i + pos]);
- }
- }
- }
- break;
-
- case ARRAY_TYPE:
- /* Arrays are handled as small records. */
- {
- int num;
- num = classify_argument (TYPE_MODE (TREE_TYPE (type)),
- TREE_TYPE (type), subclasses, bit_offset);
- if (!num)
- return 0;
-
- /* The partial classes are now full classes. */
- if (subclasses[0] == X86_64_SSESF_CLASS && bytes != 4)
- subclasses[0] = X86_64_SSE_CLASS;
- if (subclasses[0] == X86_64_INTEGERSI_CLASS
- && !((bit_offset % 64) == 0 && bytes == 4))
- subclasses[0] = X86_64_INTEGER_CLASS;
-
- for (i = 0; i < words; i++)
- classes[i] = subclasses[i % num];
-
- break;
- }
- case UNION_TYPE:
- case QUAL_UNION_TYPE:
- /* Unions are similar to RECORD_TYPE but offset is always 0.
- */
- for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
- {
- if (TREE_CODE (field) == FIELD_DECL)
- {
- int num;
-
- if (TREE_TYPE (field) == error_mark_node)
- continue;
-
- num = classify_argument (TYPE_MODE (TREE_TYPE (field)),
- TREE_TYPE (field), subclasses,
- bit_offset);
- if (!num)
- return 0;
- for (i = 0; i < num; i++)
- classes[i] = merge_classes (subclasses[i], classes[i]);
- }
- }
- break;
-
- default:
- gcc_unreachable ();
- }
-
- if (words > 2)
- {
- /* When size > 16 bytes, if the first one isn't
- X86_64_SSE_CLASS or any other ones aren't
- X86_64_SSEUP_CLASS, everything should be passed in
- memory. */
- if (classes[0] != X86_64_SSE_CLASS)
- return 0;
-
- for (i = 1; i < words; i++)
- if (classes[i] != X86_64_SSEUP_CLASS)
- return 0;
- }
-
- /* Final merger cleanup. */
- for (i = 0; i < words; i++)
- {
- /* If one class is MEMORY, everything should be passed in
- memory. */
- if (classes[i] == X86_64_MEMORY_CLASS)
- return 0;
-
- /* The X86_64_SSEUP_CLASS should be always preceded by
- X86_64_SSE_CLASS or X86_64_SSEUP_CLASS. */
- if (classes[i] == X86_64_SSEUP_CLASS
- && classes[i - 1] != X86_64_SSE_CLASS
- && classes[i - 1] != X86_64_SSEUP_CLASS)
- {
- /* The first one should never be X86_64_SSEUP_CLASS. */
- gcc_assert (i != 0);
- classes[i] = X86_64_SSE_CLASS;
- }
-
- /* If X86_64_X87UP_CLASS isn't preceded by X86_64_X87_CLASS,
- everything should be passed in memory. */
- if (classes[i] == X86_64_X87UP_CLASS
- && (classes[i - 1] != X86_64_X87_CLASS))
- {
- static bool warned;
-
- /* The first one should never be X86_64_X87UP_CLASS. */
- gcc_assert (i != 0);
- if (!warned && warn_psabi)
- {
- warned = true;
- inform (input_location,
- "the ABI of passing union with long double"
- " has changed in GCC 4.4");
- }
- return 0;
- }
- }
- return words;
- }
-
- /* Compute alignment needed. We align all types to natural boundaries with
- exception of XFmode that is aligned to 64bits. */
- if (mode != VOIDmode && mode != BLKmode)
- {
- int mode_alignment = GET_MODE_BITSIZE (mode);
-
- if (mode == XFmode)
- mode_alignment = 128;
- else if (mode == XCmode)
- mode_alignment = 256;
- if (COMPLEX_MODE_P (mode))
- mode_alignment /= 2;
- /* Misaligned fields are always returned in memory. */
- if (bit_offset % mode_alignment)
- return 0;
- }
-
- /* for V1xx modes, just use the base mode */
- if (VECTOR_MODE_P (mode) && mode != V1DImode && mode != V1TImode
- && GET_MODE_SIZE (GET_MODE_INNER (mode)) == bytes)
- mode = GET_MODE_INNER (mode);
-
- /* Classification of atomic types. */
- switch (mode)
- {
- case SDmode:
- case DDmode:
- classes[0] = X86_64_SSE_CLASS;
- return 1;
- case TDmode:
- classes[0] = X86_64_SSE_CLASS;
- classes[1] = X86_64_SSEUP_CLASS;
- return 2;
- case DImode:
- case SImode:
- case HImode:
- case QImode:
- case CSImode:
- case CHImode:
- case CQImode:
- {
- int size = (bit_offset % 64)+ (int) GET_MODE_BITSIZE (mode);
-
- if (size <= 32)
- {
- classes[0] = X86_64_INTEGERSI_CLASS;
- return 1;
- }
- else if (size <= 64)
- {
- classes[0] = X86_64_INTEGER_CLASS;
- return 1;
- }
- else if (size <= 64+32)
- {
- classes[0] = X86_64_INTEGER_CLASS;
- classes[1] = X86_64_INTEGERSI_CLASS;
- return 2;
- }
- else if (size <= 64+64)
- {
- classes[0] = classes[1] = X86_64_INTEGER_CLASS;
- return 2;
- }
- else
- gcc_unreachable ();
- }
- case CDImode:
- case TImode:
- classes[0] = classes[1] = X86_64_INTEGER_CLASS;
- return 2;
- case COImode:
- case OImode:
- /* OImode shouldn't be used directly. */
- gcc_unreachable ();
- case CTImode:
- return 0;
- case SFmode:
- if (!(bit_offset % 64))
- classes[0] = X86_64_SSESF_CLASS;
- else
- classes[0] = X86_64_SSE_CLASS;
- return 1;
- case DFmode:
- classes[0] = X86_64_SSEDF_CLASS;
- return 1;
- case XFmode:
- classes[0] = X86_64_X87_CLASS;
- classes[1] = X86_64_X87UP_CLASS;
- return 2;
- case TFmode:
- classes[0] = X86_64_SSE_CLASS;
- classes[1] = X86_64_SSEUP_CLASS;
- return 2;
- case SCmode:
- classes[0] = X86_64_SSE_CLASS;
- if (!(bit_offset % 64))
- return 1;
- else
- {
- static bool warned;
-
- if (!warned && warn_psabi)
- {
- warned = true;
- inform (input_location,
- "the ABI of passing structure with complex float"
- " member has changed in GCC 4.4");
- }
- classes[1] = X86_64_SSESF_CLASS;
- return 2;
- }
- case DCmode:
- classes[0] = X86_64_SSEDF_CLASS;
- classes[1] = X86_64_SSEDF_CLASS;
- return 2;
- case XCmode:
- classes[0] = X86_64_COMPLEX_X87_CLASS;
- return 1;
- case TCmode:
- /* This modes is larger than 16 bytes. */
- return 0;
- case V8SFmode:
- case V8SImode:
- case V32QImode:
- case V16HImode:
- case V4DFmode:
- case V4DImode:
- classes[0] = X86_64_SSE_CLASS;
- classes[1] = X86_64_SSEUP_CLASS;
- classes[2] = X86_64_SSEUP_CLASS;
- classes[3] = X86_64_SSEUP_CLASS;
- return 4;
- case V4SFmode:
- case V4SImode:
- case V16QImode:
- case V8HImode:
- case V2DFmode:
- case V2DImode:
- classes[0] = X86_64_SSE_CLASS;
- classes[1] = X86_64_SSEUP_CLASS;
- return 2;
- case V1TImode:
- case V1DImode:
- case V2SFmode:
- case V2SImode:
- case V4HImode:
- case V8QImode:
- classes[0] = X86_64_SSE_CLASS;
- return 1;
- case BLKmode:
- case VOIDmode:
- return 0;
- default:
- gcc_assert (VECTOR_MODE_P (mode));
-
- if (bytes > 16)
- return 0;
-
- gcc_assert (GET_MODE_CLASS (GET_MODE_INNER (mode)) == MODE_INT);
-
- if (bit_offset + GET_MODE_BITSIZE (mode) <= 32)
- classes[0] = X86_64_INTEGERSI_CLASS;
- else
- classes[0] = X86_64_INTEGER_CLASS;
- classes[1] = X86_64_INTEGER_CLASS;
- return 1 + (bytes > 8);
- }
-}
-
-/* Examine the argument and return set number of register required in each
- class. Return 0 iff parameter should be passed in memory. */
-static int
-examine_argument (enum machine_mode mode, const_tree type, int in_return,
- int *int_nregs, int *sse_nregs)
-{
- enum x86_64_reg_class regclass[MAX_CLASSES];
- int n = classify_argument (mode, type, regclass, 0);
-
- *int_nregs = 0;
- *sse_nregs = 0;
- if (!n)
- return 0;
- for (n--; n >= 0; n--)
- switch (regclass[n])
- {
- case X86_64_INTEGER_CLASS:
- case X86_64_INTEGERSI_CLASS:
- (*int_nregs)++;
- break;
- case X86_64_SSE_CLASS:
- case X86_64_SSESF_CLASS:
- case X86_64_SSEDF_CLASS:
- (*sse_nregs)++;
- break;
- case X86_64_NO_CLASS:
- case X86_64_SSEUP_CLASS:
- break;
- case X86_64_X87_CLASS:
- case X86_64_X87UP_CLASS:
- if (!in_return)
- return 0;
- break;
- case X86_64_COMPLEX_X87_CLASS:
- return in_return ? 2 : 0;
- case X86_64_MEMORY_CLASS:
- gcc_unreachable ();
- }
- return 1;
-}
-
-/* Construct container for the argument used by GCC interface. See
- FUNCTION_ARG for the detailed description. */
-
-static rtx
-construct_container (enum machine_mode mode, enum machine_mode orig_mode,
- const_tree type, int in_return, int nintregs, int nsseregs,
- const int *intreg, int sse_regno)
-{
- /* The following variables hold the static issued_error state. */
- static bool issued_sse_arg_error;
- static bool issued_sse_ret_error;
- static bool issued_x87_ret_error;
-
- enum machine_mode tmpmode;
- int bytes =
- (mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
- enum x86_64_reg_class regclass[MAX_CLASSES];
- int n;
- int i;
- int nexps = 0;
- int needed_sseregs, needed_intregs;
- rtx exp[MAX_CLASSES];
- rtx ret;
-
- n = classify_argument (mode, type, regclass, 0);
- if (!n)
- return NULL;
- if (!examine_argument (mode, type, in_return, &needed_intregs,
- &needed_sseregs))
- return NULL;
- if (needed_intregs > nintregs || needed_sseregs > nsseregs)
- return NULL;
-
- /* We allowed the user to turn off SSE for kernel mode. Don't crash if
- some less clueful developer tries to use floating-point anyway. */
- if (needed_sseregs && !TARGET_SSE)
- {
- if (in_return)
- {
- if (!issued_sse_ret_error)
- {
- error ("SSE register return with SSE disabled");
- issued_sse_ret_error = true;
- }
- }
- else if (!issued_sse_arg_error)
- {
- error ("SSE register argument with SSE disabled");
- issued_sse_arg_error = true;
- }
- return NULL;
- }
-
- /* Likewise, error if the ABI requires us to return values in the
- x87 registers and the user specified -mno-80387. */
- if (!TARGET_80387 && in_return)
- for (i = 0; i < n; i++)
- if (regclass[i] == X86_64_X87_CLASS
- || regclass[i] == X86_64_X87UP_CLASS
- || regclass[i] == X86_64_COMPLEX_X87_CLASS)
- {
- if (!issued_x87_ret_error)
- {
- error ("x87 register return with x87 disabled");
- issued_x87_ret_error = true;
- }
- return NULL;
- }
-
- /* First construct simple cases. Avoid SCmode, since we want to use
- single register to pass this type. */
- if (n == 1 && mode != SCmode)
- switch (regclass[0])
- {
- case X86_64_INTEGER_CLASS:
- case X86_64_INTEGERSI_CLASS:
- return gen_rtx_REG (mode, intreg[0]);
- case X86_64_SSE_CLASS:
- case X86_64_SSESF_CLASS:
- case X86_64_SSEDF_CLASS:
- if (mode != BLKmode)
- return gen_reg_or_parallel (mode, orig_mode,
- SSE_REGNO (sse_regno));
- break;
- case X86_64_X87_CLASS:
- case X86_64_COMPLEX_X87_CLASS:
- return gen_rtx_REG (mode, FIRST_STACK_REG);
- case X86_64_NO_CLASS:
- /* Zero sized array, struct or class. */
- return NULL;
- default:
- gcc_unreachable ();
- }
- if (n == 2
- && regclass[0] == X86_64_SSE_CLASS
- && regclass[1] == X86_64_SSEUP_CLASS
- && mode != BLKmode)
- return gen_reg_or_parallel (mode, orig_mode,
- SSE_REGNO (sse_regno));
- if (n == 4
- && regclass[0] == X86_64_SSE_CLASS
- && regclass[1] == X86_64_SSEUP_CLASS
- && regclass[2] == X86_64_SSEUP_CLASS
- && regclass[3] == X86_64_SSEUP_CLASS
- && mode != BLKmode)
- return gen_reg_or_parallel (mode, orig_mode,
- SSE_REGNO (sse_regno));
- if (n == 2
- && regclass[0] == X86_64_X87_CLASS
- && regclass[1] == X86_64_X87UP_CLASS)
- return gen_rtx_REG (XFmode, FIRST_STACK_REG);
-
- if (n == 2
- && regclass[0] == X86_64_INTEGER_CLASS
- && regclass[1] == X86_64_INTEGER_CLASS
- && (mode == CDImode || mode == TImode || mode == TFmode)
- && intreg[0] + 1 == intreg[1])
- return gen_rtx_REG (mode, intreg[0]);
-
- /* Otherwise figure out the entries of the PARALLEL. */
- for (i = 0; i < n; i++)
- {
- int pos;
-
- switch (regclass[i])
- {
- case X86_64_NO_CLASS:
- break;
- case X86_64_INTEGER_CLASS:
- case X86_64_INTEGERSI_CLASS:
- /* Merge TImodes on aligned occasions here too. */
- if (i * 8 + 8 > bytes)
- tmpmode
- = mode_for_size ((bytes - i * 8) * BITS_PER_UNIT, MODE_INT, 0);
- else if (regclass[i] == X86_64_INTEGERSI_CLASS)
- tmpmode = SImode;
- else
- tmpmode = DImode;
- /* We've requested 24 bytes we
- don't have mode for. Use DImode. */
- if (tmpmode == BLKmode)
- tmpmode = DImode;
- exp [nexps++]
- = gen_rtx_EXPR_LIST (VOIDmode,
- gen_rtx_REG (tmpmode, *intreg),
- GEN_INT (i*8));
- intreg++;
- break;
- case X86_64_SSESF_CLASS:
- exp [nexps++]
- = gen_rtx_EXPR_LIST (VOIDmode,
- gen_rtx_REG (SFmode,
- SSE_REGNO (sse_regno)),
- GEN_INT (i*8));
- sse_regno++;
- break;
- case X86_64_SSEDF_CLASS:
- exp [nexps++]
- = gen_rtx_EXPR_LIST (VOIDmode,
- gen_rtx_REG (DFmode,
- SSE_REGNO (sse_regno)),
- GEN_INT (i*8));
- sse_regno++;
- break;
- case X86_64_SSE_CLASS:
- pos = i;
- switch (n)
- {
- case 1:
- tmpmode = DImode;
- break;
- case 2:
- if (i == 0 && regclass[1] == X86_64_SSEUP_CLASS)
- {
- tmpmode = TImode;
- i++;
- }
- else
- tmpmode = DImode;
- break;
- case 4:
- gcc_assert (i == 0
- && regclass[1] == X86_64_SSEUP_CLASS
- && regclass[2] == X86_64_SSEUP_CLASS
- && regclass[3] == X86_64_SSEUP_CLASS);
- tmpmode = OImode;
- i += 3;
- break;
- default:
- gcc_unreachable ();
- }
- exp [nexps++]
- = gen_rtx_EXPR_LIST (VOIDmode,
- gen_rtx_REG (tmpmode,
- SSE_REGNO (sse_regno)),
- GEN_INT (pos*8));
- sse_regno++;
- break;
- default:
- gcc_unreachable ();
- }
- }
-
- /* Empty aligned struct, union or class. */
- if (nexps == 0)
- return NULL;
-
- ret = gen_rtx_PARALLEL (mode, rtvec_alloc (nexps));
- for (i = 0; i < nexps; i++)
- XVECEXP (ret, 0, i) = exp [i];
- return ret;
-}
-
-/* Update the data in CUM to advance over an argument of mode MODE
- and data type TYPE. (TYPE is null for libcalls where that information
- may not be available.) */
-
-static void
-function_arg_advance_32 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
- const_tree type, HOST_WIDE_INT bytes,
- HOST_WIDE_INT words)
-{
- switch (mode)
- {
- default:
- break;
-
- case BLKmode:
- if (bytes < 0)
- break;
- /* FALLTHRU */
-
- case DImode:
- case SImode:
- case HImode:
- case QImode:
- cum->words += words;
- cum->nregs -= words;
- cum->regno += words;
-
- if (cum->nregs <= 0)
- {
- cum->nregs = 0;
- cum->regno = 0;
- }
- break;
-
- case OImode:
- /* OImode shouldn't be used directly. */
- gcc_unreachable ();
-
- case DFmode:
- if (cum->float_in_sse < 2)
- break;
- case SFmode:
- if (cum->float_in_sse < 1)
- break;
- /* FALLTHRU */
-
- case V8SFmode:
- case V8SImode:
- case V32QImode:
- case V16HImode:
- case V4DFmode:
- case V4DImode:
- case TImode:
- case V16QImode:
- case V8HImode:
- case V4SImode:
- case V2DImode:
- case V4SFmode:
- case V2DFmode:
- if (!type || !AGGREGATE_TYPE_P (type))
- {
- cum->sse_words += words;
- cum->sse_nregs -= 1;
- cum->sse_regno += 1;
- if (cum->sse_nregs <= 0)
- {
- cum->sse_nregs = 0;
- cum->sse_regno = 0;
- }
- }
- break;
-
- case V8QImode:
- case V4HImode:
- case V2SImode:
- case V2SFmode:
- case V1TImode:
- case V1DImode:
- if (!type || !AGGREGATE_TYPE_P (type))
- {
- cum->mmx_words += words;
- cum->mmx_nregs -= 1;
- cum->mmx_regno += 1;
- if (cum->mmx_nregs <= 0)
- {
- cum->mmx_nregs = 0;
- cum->mmx_regno = 0;
- }
- }
- break;
- }
-}
-
-static void
-function_arg_advance_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
- const_tree type, HOST_WIDE_INT words, bool named)
-{
- int int_nregs, sse_nregs;
-
- /* Unnamed 256bit vector mode parameters are passed on stack. */
- if (!named && VALID_AVX256_REG_MODE (mode))
- return;
-
- if (examine_argument (mode, type, 0, &int_nregs, &sse_nregs)
- && sse_nregs <= cum->sse_nregs && int_nregs <= cum->nregs)
- {
- cum->nregs -= int_nregs;
- cum->sse_nregs -= sse_nregs;
- cum->regno += int_nregs;
- cum->sse_regno += sse_nregs;
- }
- else
- {
- int align = ix86_function_arg_boundary (mode, type) / BITS_PER_WORD;
- cum->words = (cum->words + align - 1) & ~(align - 1);
- cum->words += words;
- }
-}
-
-static void
-function_arg_advance_ms_64 (CUMULATIVE_ARGS *cum, HOST_WIDE_INT bytes,
- HOST_WIDE_INT words)
-{
- /* Otherwise, this should be passed indirect. */
- gcc_assert (bytes == 1 || bytes == 2 || bytes == 4 || bytes == 8);
-
- cum->words += words;
- if (cum->nregs > 0)
- {
- cum->nregs -= 1;
- cum->regno += 1;
- }
-}
-
-/* Update the data in CUM to advance over an argument of mode MODE and
- data type TYPE. (TYPE is null for libcalls where that information
- may not be available.) */
-
-static void
-ix86_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
- const_tree type, bool named)
-{
- CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
- HOST_WIDE_INT bytes, words;
-
- if (mode == BLKmode)
- bytes = int_size_in_bytes (type);
- else
- bytes = GET_MODE_SIZE (mode);
- words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
-
- if (type)
- mode = type_natural_mode (type, NULL);
-
- if (TARGET_64BIT && (cum ? cum->call_abi : ix86_abi) == MS_ABI)
- function_arg_advance_ms_64 (cum, bytes, words);
- else if (TARGET_64BIT)
- function_arg_advance_64 (cum, mode, type, words, named);
- else
- function_arg_advance_32 (cum, mode, type, bytes, words);
-}
-
-/* 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.
-
- 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). */
-
-static rtx
-function_arg_32 (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
- enum machine_mode orig_mode, const_tree type,
- HOST_WIDE_INT bytes, HOST_WIDE_INT words)
-{
- static bool warnedsse, warnedmmx;
-
- /* Avoid the AL settings for the Unix64 ABI. */
- if (mode == VOIDmode)
- return constm1_rtx;
-
- switch (mode)
- {
- default:
- break;
-
- case BLKmode:
- if (bytes < 0)
- break;
- /* FALLTHRU */
- case DImode:
- case SImode:
- case HImode:
- case QImode:
- if (words <= cum->nregs)
- {
- int regno = cum->regno;
-
- /* Fastcall allocates the first two DWORD (SImode) or
- smaller arguments to ECX and EDX if it isn't an
- aggregate type . */
- if (cum->fastcall)
- {
- if (mode == BLKmode
- || mode == DImode
- || (type && AGGREGATE_TYPE_P (type)))
- break;
-
- /* ECX not EAX is the first allocated register. */
- if (regno == AX_REG)
- regno = CX_REG;
- }
- return gen_rtx_REG (mode, regno);
- }
- break;
-
- case DFmode:
- if (cum->float_in_sse < 2)
- break;
- case SFmode:
- if (cum->float_in_sse < 1)
- break;
- /* FALLTHRU */
- case TImode:
- /* In 32bit, we pass TImode in xmm registers. */
- case V16QImode:
- case V8HImode:
- case V4SImode:
- case V2DImode:
- case V4SFmode:
- case V2DFmode:
- if (!type || !AGGREGATE_TYPE_P (type))
- {
- if (!TARGET_SSE && !warnedsse && cum->warn_sse)
- {
- warnedsse = true;
- warning (0, "SSE vector argument without SSE enabled "
- "changes the ABI");
- }
- if (cum->sse_nregs)
- return gen_reg_or_parallel (mode, orig_mode,
- cum->sse_regno + FIRST_SSE_REG);
- }
- break;
-
- case OImode:
- /* OImode shouldn't be used directly. */
- gcc_unreachable ();
-
- case V8SFmode:
- case V8SImode:
- case V32QImode:
- case V16HImode:
- case V4DFmode:
- case V4DImode:
- if (!type || !AGGREGATE_TYPE_P (type))
- {
- if (cum->sse_nregs)
- return gen_reg_or_parallel (mode, orig_mode,
- cum->sse_regno + FIRST_SSE_REG);
- }
- break;
-
- case V8QImode:
- case V4HImode:
- case V2SImode:
- case V2SFmode:
- case V1TImode:
- case V1DImode:
- if (!type || !AGGREGATE_TYPE_P (type))
- {
- if (!TARGET_MMX && !warnedmmx && cum->warn_mmx)
- {
- warnedmmx = true;
- warning (0, "MMX vector argument without MMX enabled "
- "changes the ABI");
- }
- if (cum->mmx_nregs)
- return gen_reg_or_parallel (mode, orig_mode,
- cum->mmx_regno + FIRST_MMX_REG);
- }
- break;
- }
-
- return NULL_RTX;
-}
-
-static rtx
-function_arg_64 (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
- enum machine_mode orig_mode, const_tree type, bool named)
-{
- /* Handle a hidden AL argument containing number of registers
- for varargs x86-64 functions. */
- if (mode == VOIDmode)
- return GEN_INT (cum->maybe_vaarg
- ? (cum->sse_nregs < 0
- ? X86_64_SSE_REGPARM_MAX
- : cum->sse_regno)
- : -1);
-
- switch (mode)
- {
- default:
- break;
-
- case V8SFmode:
- case V8SImode:
- case V32QImode:
- case V16HImode:
- case V4DFmode:
- case V4DImode:
- /* Unnamed 256bit vector mode parameters are passed on stack. */
- if (!named)
- return NULL;
- break;
- }
-
- return construct_container (mode, orig_mode, type, 0, cum->nregs,
- cum->sse_nregs,
- &x86_64_int_parameter_registers [cum->regno],
- cum->sse_regno);
-}
-
-static rtx
-function_arg_ms_64 (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
- enum machine_mode orig_mode, bool named,
- HOST_WIDE_INT bytes)
-{
- unsigned int regno;
-
- /* We need to add clobber for MS_ABI->SYSV ABI calls in expand_call.
- We use value of -2 to specify that current function call is MSABI. */
- if (mode == VOIDmode)
- return GEN_INT (-2);
-
- /* If we've run out of registers, it goes on the stack. */
- if (cum->nregs == 0)
- return NULL_RTX;
-
- regno = x86_64_ms_abi_int_parameter_registers[cum->regno];
-
- /* Only floating point modes are passed in anything but integer regs. */
- if (TARGET_SSE && (mode == SFmode || mode == DFmode))
- {
- if (named)
- regno = cum->regno + FIRST_SSE_REG;
- else
- {
- rtx t1, t2;
-
- /* Unnamed floating parameters are passed in both the
- SSE and integer registers. */
- t1 = gen_rtx_REG (mode, cum->regno + FIRST_SSE_REG);
- t2 = gen_rtx_REG (mode, regno);
- t1 = gen_rtx_EXPR_LIST (VOIDmode, t1, const0_rtx);
- t2 = gen_rtx_EXPR_LIST (VOIDmode, t2, const0_rtx);
- return gen_rtx_PARALLEL (mode, gen_rtvec (2, t1, t2));
- }
- }
- /* Handle aggregated types passed in register. */
- if (orig_mode == BLKmode)
- {
- if (bytes > 0 && bytes <= 8)
- mode = (bytes > 4 ? DImode : SImode);
- if (mode == BLKmode)
- mode = DImode;
- }
-
- return gen_reg_or_parallel (mode, orig_mode, regno);
-}
-
-/* Return where to put the arguments to a function.
- Return 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. It is null for libcalls where that information may not be
- available. CUM gives information 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). */
-
-static rtx
-ix86_function_arg (cumulative_args_t cum_v, enum machine_mode omode,
- const_tree type, bool named)
-{
- CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
- enum machine_mode mode = omode;
- HOST_WIDE_INT bytes, words;
- rtx arg;
-
- if (mode == BLKmode)
- bytes = int_size_in_bytes (type);
- else
- bytes = GET_MODE_SIZE (mode);
- words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
-
- /* To simplify the code below, represent vector types with a vector mode
- even if MMX/SSE are not active. */
- if (type && TREE_CODE (type) == VECTOR_TYPE)
- mode = type_natural_mode (type, cum);
-
- if (TARGET_64BIT && (cum ? cum->call_abi : ix86_abi) == MS_ABI)
- arg = function_arg_ms_64 (cum, mode, omode, named, bytes);
- else if (TARGET_64BIT)
- arg = function_arg_64 (cum, mode, omode, type, named);
- else
- arg = function_arg_32 (cum, mode, omode, type, bytes, words);
-
- return arg;
-}
-
-/* A C expression that indicates when an argument must be passed by
- reference. If nonzero for an argument, a copy of that argument is
- made in memory and a pointer to the argument is passed instead of
- the argument itself. The pointer is passed in whatever way is
- appropriate for passing a pointer to that type. */
-
-static bool
-ix86_pass_by_reference (cumulative_args_t cum_v ATTRIBUTE_UNUSED,
- enum machine_mode mode ATTRIBUTE_UNUSED,
- const_tree type, bool named ATTRIBUTE_UNUSED)
-{
- CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
-
- /* See Windows x64 Software Convention. */
- if (TARGET_64BIT && (cum ? cum->call_abi : ix86_abi) == MS_ABI)
- {
- int msize = (int) GET_MODE_SIZE (mode);
- if (type)
- {
- /* Arrays are passed by reference. */
- if (TREE_CODE (type) == ARRAY_TYPE)
- return true;
-
- if (AGGREGATE_TYPE_P (type))
- {
- /* Structs/unions of sizes other than 8, 16, 32, or 64 bits
- are passed by reference. */
- msize = int_size_in_bytes (type);
- }
- }
-
- /* __m128 is passed by reference. */
- switch (msize) {
- case 1: case 2: case 4: case 8:
- break;
- default:
- return true;
- }
- }
- else if (TARGET_64BIT && type && int_size_in_bytes (type) == -1)
- return 1;
-
- return 0;
-}
-
-/* Return true when TYPE should be 128bit aligned for 32bit argument
- passing ABI. XXX: This function is obsolete and is only used for
- checking psABI compatibility with previous versions of GCC. */
-
-static bool
-ix86_compat_aligned_value_p (const_tree type)
-{
- enum machine_mode mode = TYPE_MODE (type);
- if (((TARGET_SSE && SSE_REG_MODE_P (mode))
- || mode == TDmode
- || mode == TFmode
- || mode == TCmode)
- && (!TYPE_USER_ALIGN (type) || TYPE_ALIGN (type) > 128))
- return true;
- if (TYPE_ALIGN (type) < 128)
- return false;
-
- if (AGGREGATE_TYPE_P (type))
- {
- /* Walk the aggregates recursively. */
- switch (TREE_CODE (type))
- {
- case RECORD_TYPE:
- case UNION_TYPE:
- case QUAL_UNION_TYPE:
- {
- tree field;
-
- /* Walk all the structure fields. */
- for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
- {
- if (TREE_CODE (field) == FIELD_DECL
- && ix86_compat_aligned_value_p (TREE_TYPE (field)))
- return true;
- }
- break;
- }
-
- case ARRAY_TYPE:
- /* Just for use if some languages passes arrays by value. */
- if (ix86_compat_aligned_value_p (TREE_TYPE (type)))
- return true;
- break;
-
- default:
- gcc_unreachable ();
- }
- }
- return false;
-}
-
-/* Return the alignment boundary for MODE and TYPE with alignment ALIGN.
- XXX: This function is obsolete and is only used for checking psABI
- compatibility with previous versions of GCC. */
-
-static unsigned int
-ix86_compat_function_arg_boundary (enum machine_mode mode,
- const_tree type, unsigned int align)
-{
- /* In 32bit, only _Decimal128 and __float128 are aligned to their
- natural boundaries. */
- if (!TARGET_64BIT && mode != TDmode && mode != TFmode)
- {
- /* i386 ABI defines all arguments to be 4 byte aligned. We have to
- make an exception for SSE modes since these require 128bit
- alignment.
-
- The handling here differs from field_alignment. ICC aligns MMX
- arguments to 4 byte boundaries, while structure fields are aligned
- to 8 byte boundaries. */
- if (!type)
- {
- if (!(TARGET_SSE && SSE_REG_MODE_P (mode)))
- align = PARM_BOUNDARY;
- }
- else
- {
- if (!ix86_compat_aligned_value_p (type))
- align = PARM_BOUNDARY;
- }
- }
- if (align > BIGGEST_ALIGNMENT)
- align = BIGGEST_ALIGNMENT;
- return align;
-}
-
-/* Return true when TYPE should be 128bit aligned for 32bit argument
- passing ABI. */
-
-static bool
-ix86_contains_aligned_value_p (const_tree type)
-{
- enum machine_mode mode = TYPE_MODE (type);
-
- if (mode == XFmode || mode == XCmode)
- return false;
-
- if (TYPE_ALIGN (type) < 128)
- return false;
-
- if (AGGREGATE_TYPE_P (type))
- {
- /* Walk the aggregates recursively. */
- switch (TREE_CODE (type))
- {
- case RECORD_TYPE:
- case UNION_TYPE:
- case QUAL_UNION_TYPE:
- {
- tree field;
-
- /* Walk all the structure fields. */
- for (field = TYPE_FIELDS (type);
- field;
- field = DECL_CHAIN (field))
- {
- if (TREE_CODE (field) == FIELD_DECL
- && ix86_contains_aligned_value_p (TREE_TYPE (field)))
- return true;
- }
- break;
- }
-
- case ARRAY_TYPE:
- /* Just for use if some languages passes arrays by value. */
- if (ix86_contains_aligned_value_p (TREE_TYPE (type)))
- return true;
- break;
-
- default:
- gcc_unreachable ();
- }
- }
- else
- return TYPE_ALIGN (type) >= 128;
-
- return false;
-}
-
-/* Gives the alignment boundary, in bits, of an argument with the
- specified mode and type. */
-
-static unsigned int
-ix86_function_arg_boundary (enum machine_mode mode, const_tree type)
-{
- unsigned int align;
- if (type)
- {
- /* Since the main variant type is used for call, we convert it to
- the main variant type. */
- type = TYPE_MAIN_VARIANT (type);
- align = TYPE_ALIGN (type);
- }
- else
- align = GET_MODE_ALIGNMENT (mode);
- if (align < PARM_BOUNDARY)
- align = PARM_BOUNDARY;
- else
- {
- static bool warned;
- unsigned int saved_align = align;
-
- if (!TARGET_64BIT)
- {
- /* i386 ABI defines XFmode arguments to be 4 byte aligned. */
- if (!type)
- {
- if (mode == XFmode || mode == XCmode)
- align = PARM_BOUNDARY;
- }
- else if (!ix86_contains_aligned_value_p (type))
- align = PARM_BOUNDARY;
-
- if (align < 128)
- align = PARM_BOUNDARY;
- }
-
- if (warn_psabi
- && !warned
- && align != ix86_compat_function_arg_boundary (mode, type,
- saved_align))
- {
- warned = true;
- inform (input_location,
- "The ABI for passing parameters with %d-byte"
- " alignment has changed in GCC 4.6",
- align / BITS_PER_UNIT);
- }
- }
-
- return align;
-}
-
-/* Return true if N is a possible register number of function value. */
-
-static bool
-ix86_function_value_regno_p (const unsigned int regno)
-{
- switch (regno)
- {
- case AX_REG:
- return true;
-
- case FIRST_FLOAT_REG:
- /* TODO: The function should depend on current function ABI but
- builtins.c would need updating then. Therefore we use the
- default ABI. */
- if (TARGET_64BIT && ix86_abi == MS_ABI)
- return false;
- return TARGET_FLOAT_RETURNS_IN_80387;
-
- case FIRST_SSE_REG:
- return TARGET_SSE;
-
- case FIRST_MMX_REG:
- if (TARGET_MACHO || TARGET_64BIT)
- return false;
- return TARGET_MMX;
- }
-
- return false;
-}
-
-/* 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. */
-
-static rtx
-function_value_32 (enum machine_mode orig_mode, enum machine_mode mode,
- const_tree fntype, const_tree fn)
-{
- unsigned int regno;
-
- /* 8-byte vector modes in %mm0. See ix86_return_in_memory for where
- we normally prevent this case when mmx is not available. However
- some ABIs may require the result to be returned like DImode. */
- if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 8)
- regno = FIRST_MMX_REG;
-
- /* 16-byte vector modes in %xmm0. See ix86_return_in_memory for where
- we prevent this case when sse is not available. However some ABIs
- may require the result to be returned like integer TImode. */
- else if (mode == TImode
- || (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 16))
- regno = FIRST_SSE_REG;
-
- /* 32-byte vector modes in %ymm0. */
- else if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 32)
- regno = FIRST_SSE_REG;
-
- /* Floating point return values in %st(0) (unless -mno-fp-ret-in-387). */
- else if (X87_FLOAT_MODE_P (mode) && TARGET_FLOAT_RETURNS_IN_80387)
- regno = FIRST_FLOAT_REG;
- else
- /* Most things go in %eax. */
- regno = AX_REG;
-
- /* Override FP return register with %xmm0 for local functions when
- SSE math is enabled or for functions with sseregparm attribute. */
- if ((fn || fntype) && (mode == SFmode || mode == DFmode))
- {
- int sse_level = ix86_function_sseregparm (fntype, fn, false);
- if ((sse_level >= 1 && mode == SFmode)
- || (sse_level == 2 && mode == DFmode))
- regno = FIRST_SSE_REG;
- }
-
- /* OImode shouldn't be used directly. */
- gcc_assert (mode != OImode);
-
- return gen_rtx_REG (orig_mode, regno);
-}
-
-static rtx
-function_value_64 (enum machine_mode orig_mode, enum machine_mode mode,
- const_tree valtype)
-{
- rtx ret;
-
- /* Handle libcalls, which don't provide a type node. */
- if (valtype == NULL)
- {
- unsigned int regno;
-
- switch (mode)
- {
- case SFmode:
- case SCmode:
- case DFmode:
- case DCmode:
- case TFmode:
- case SDmode:
- case DDmode:
- case TDmode:
- regno = FIRST_SSE_REG;
- break;
- case XFmode:
- case XCmode:
- regno = FIRST_FLOAT_REG;
- break;
- case TCmode:
- return NULL;
- default:
- regno = AX_REG;
- }
-
- return gen_rtx_REG (mode, regno);
- }
- else if (POINTER_TYPE_P (valtype))
- {
- /* Pointers are always returned in word_mode. */
- mode = word_mode;
- }
-
- ret = construct_container (mode, orig_mode, valtype, 1,
- X86_64_REGPARM_MAX, X86_64_SSE_REGPARM_MAX,
- x86_64_int_return_registers, 0);
-
- /* For zero sized structures, construct_container returns NULL, but we
- need to keep rest of compiler happy by returning meaningful value. */
- if (!ret)
- ret = gen_rtx_REG (orig_mode, AX_REG);
-
- return ret;
-}
-
-static rtx
-function_value_ms_64 (enum machine_mode orig_mode, enum machine_mode mode,
- const_tree valtype)
-{
- unsigned int regno = AX_REG;
-
- if (TARGET_SSE)
- {
- switch (GET_MODE_SIZE (mode))
- {
- case 16:
- if (valtype != NULL_TREE
- && !VECTOR_INTEGER_TYPE_P (valtype)
- && !VECTOR_INTEGER_TYPE_P (valtype)
- && !INTEGRAL_TYPE_P (valtype)
- && !VECTOR_FLOAT_TYPE_P (valtype))
- break;
- if ((SCALAR_INT_MODE_P (mode) || VECTOR_MODE_P (mode))
- && !COMPLEX_MODE_P (mode))
- regno = FIRST_SSE_REG;
- break;
- case 8:
- case 4:
- if (mode == SFmode || mode == DFmode)
- regno = FIRST_SSE_REG;
- break;
- default:
- break;
- }
- }
- return gen_rtx_REG (orig_mode, regno);
-}
-
-static rtx
-ix86_function_value_1 (const_tree valtype, const_tree fntype_or_decl,
- enum machine_mode orig_mode, enum machine_mode mode)
-{
- const_tree fn, fntype;
-
- fn = NULL_TREE;
- if (fntype_or_decl && DECL_P (fntype_or_decl))
- fn = fntype_or_decl;
- fntype = fn ? TREE_TYPE (fn) : fntype_or_decl;
-
- if (TARGET_64BIT && ix86_function_type_abi (fntype) == MS_ABI)
- return function_value_ms_64 (orig_mode, mode, valtype);
- else if (TARGET_64BIT)
- return function_value_64 (orig_mode, mode, valtype);
- else
- return function_value_32 (orig_mode, mode, fntype, fn);
-}
-
-static rtx
-ix86_function_value (const_tree valtype, const_tree fntype_or_decl,
- bool outgoing ATTRIBUTE_UNUSED)
-{
- enum machine_mode mode, orig_mode;
-
- orig_mode = TYPE_MODE (valtype);
- mode = type_natural_mode (valtype, NULL);
- return ix86_function_value_1 (valtype, fntype_or_decl, orig_mode, mode);
-}
-
-/* Pointer function arguments and return values are promoted to
- word_mode. */
-
-static enum machine_mode
-ix86_promote_function_mode (const_tree type, enum machine_mode mode,
- int *punsignedp, const_tree fntype,
- int for_return)
-{
- if (type != NULL_TREE && POINTER_TYPE_P (type))
- {
- *punsignedp = POINTERS_EXTEND_UNSIGNED;
- return word_mode;
- }
- return default_promote_function_mode (type, mode, punsignedp, fntype,
- for_return);
-}
-
-/* Return true if a structure, union or array with MODE containing FIELD
- should be accessed using BLKmode. */
-
-static bool
-ix86_member_type_forces_blk (const_tree field, enum machine_mode mode)
-{
- /* Union with XFmode must be in BLKmode. */
- return (mode == XFmode
- && (TREE_CODE (DECL_FIELD_CONTEXT (field)) == UNION_TYPE
- || TREE_CODE (DECL_FIELD_CONTEXT (field)) == QUAL_UNION_TYPE));
-}
-
-rtx
-ix86_libcall_value (enum machine_mode mode)
-{
- return ix86_function_value_1 (NULL, NULL, mode, mode);
-}
-
-/* Return true iff type is returned in memory. */
-
-static bool ATTRIBUTE_UNUSED
-return_in_memory_32 (const_tree type, enum machine_mode mode)
-{
- HOST_WIDE_INT size;
-
- if (mode == BLKmode)
- return true;
-
- size = int_size_in_bytes (type);
-
- if (MS_AGGREGATE_RETURN && AGGREGATE_TYPE_P (type) && size <= 8)
- return false;
-
- if (VECTOR_MODE_P (mode) || mode == TImode)
- {
- /* User-created vectors small enough to fit in EAX. */
- if (size < 8)
- return false;
-
- /* MMX/3dNow values are returned in MM0,
- except when it doesn't exits or the ABI prescribes otherwise. */
- if (size == 8)
- return !TARGET_MMX || TARGET_VECT8_RETURNS;
-
- /* SSE values are returned in XMM0, except when it doesn't exist. */
- if (size == 16)
- return !TARGET_SSE;
-
- /* AVX values are returned in YMM0, except when it doesn't exist. */
- if (size == 32)
- return !TARGET_AVX;
- }
-
- if (mode == XFmode)
- return false;
-
- if (size > 12)
- return true;
-
- /* OImode shouldn't be used directly. */
- gcc_assert (mode != OImode);
-
- return false;
-}
-
-static bool ATTRIBUTE_UNUSED
-return_in_memory_64 (const_tree type, enum machine_mode mode)
-{
- int needed_intregs, needed_sseregs;
- return !examine_argument (mode, type, 1, &needed_intregs, &needed_sseregs);
-}
-
-static bool ATTRIBUTE_UNUSED
-return_in_memory_ms_64 (const_tree type, enum machine_mode mode)
-{
- HOST_WIDE_INT size = int_size_in_bytes (type);
-
- /* __m128 is returned in xmm0. */
- if ((!type || VECTOR_INTEGER_TYPE_P (type) || INTEGRAL_TYPE_P (type)
- || VECTOR_FLOAT_TYPE_P (type))
- && (SCALAR_INT_MODE_P (mode) || VECTOR_MODE_P (mode))
- && !COMPLEX_MODE_P (mode) && (GET_MODE_SIZE (mode) == 16 || size == 16))
- return false;
-
- /* Otherwise, the size must be exactly in [1248]. */
- return size != 1 && size != 2 && size != 4 && size != 8;
-}
-
-static bool
-ix86_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
-{
-#ifdef SUBTARGET_RETURN_IN_MEMORY
- return SUBTARGET_RETURN_IN_MEMORY (type, fntype);
-#else
- const enum machine_mode mode = type_natural_mode (type, NULL);
-
- if (TARGET_64BIT)
- {
- if (ix86_function_type_abi (fntype) == MS_ABI)
- return return_in_memory_ms_64 (type, mode);
- else
- return return_in_memory_64 (type, mode);
- }
- else
- return return_in_memory_32 (type, mode);
-#endif
-}
-
-/* When returning SSE vector types, we have a choice of either
- (1) being abi incompatible with a -march switch, or
- (2) generating an error.
- Given no good solution, I think the safest thing is one warning.
- The user won't be able to use -Werror, but....
-
- Choose the STRUCT_VALUE_RTX hook because that's (at present) only
- called in response to actually generating a caller or callee that
- uses such a type. As opposed to TARGET_RETURN_IN_MEMORY, which is called
- via aggregate_value_p for general type probing from tree-ssa. */
-
-static rtx
-ix86_struct_value_rtx (tree type, int incoming ATTRIBUTE_UNUSED)
-{
- static bool warnedsse, warnedmmx;
-
- if (!TARGET_64BIT && type)
- {
- /* Look at the return type of the function, not the function type. */
- enum machine_mode mode = TYPE_MODE (TREE_TYPE (type));
-
- if (!TARGET_SSE && !warnedsse)
- {
- if (mode == TImode
- || (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 16))
- {
- warnedsse = true;
- warning (0, "SSE vector return without SSE enabled "
- "changes the ABI");
- }
- }
-
- if (!TARGET_MMX && !warnedmmx)
- {
- if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 8)
- {
- warnedmmx = true;
- warning (0, "MMX vector return without MMX enabled "
- "changes the ABI");
- }
- }
- }
-
- return NULL;
-}
-
-
-/* Create the va_list data type. */
-
-/* Returns the calling convention specific va_list date type.
- The argument ABI can be DEFAULT_ABI, MS_ABI, or SYSV_ABI. */
-
-static tree
-ix86_build_builtin_va_list_abi (enum calling_abi abi)
-{
- tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
-
- /* For i386 we use plain pointer to argument area. */
- if (!TARGET_64BIT || abi == MS_ABI)
- return build_pointer_type (char_type_node);
-
- record = lang_hooks.types.make_type (RECORD_TYPE);
- type_decl = build_decl (BUILTINS_LOCATION,
- TYPE_DECL, get_identifier ("__va_list_tag"), record);
-
- f_gpr = build_decl (BUILTINS_LOCATION,
- FIELD_DECL, get_identifier ("gp_offset"),
- unsigned_type_node);
- f_fpr = build_decl (BUILTINS_LOCATION,
- FIELD_DECL, get_identifier ("fp_offset"),
- unsigned_type_node);
- f_ovf = build_decl (BUILTINS_LOCATION,
- FIELD_DECL, get_identifier ("overflow_arg_area"),
- ptr_type_node);
- f_sav = build_decl (BUILTINS_LOCATION,
- FIELD_DECL, get_identifier ("reg_save_area"),
- ptr_type_node);
-
- va_list_gpr_counter_field = f_gpr;
- va_list_fpr_counter_field = f_fpr;
-
- DECL_FIELD_CONTEXT (f_gpr) = record;
- DECL_FIELD_CONTEXT (f_fpr) = record;
- DECL_FIELD_CONTEXT (f_ovf) = record;
- DECL_FIELD_CONTEXT (f_sav) = record;
-
- TYPE_STUB_DECL (record) = type_decl;
- TYPE_NAME (record) = type_decl;
- TYPE_FIELDS (record) = f_gpr;
- DECL_CHAIN (f_gpr) = f_fpr;
- DECL_CHAIN (f_fpr) = f_ovf;
- DECL_CHAIN (f_ovf) = f_sav;
-
- layout_type (record);
-
- /* The correct type is an array type of one element. */
- return build_array_type (record, build_index_type (size_zero_node));
-}
-
-/* Setup the builtin va_list data type and for 64-bit the additional
- calling convention specific va_list data types. */
-
-static tree
-ix86_build_builtin_va_list (void)
-{
- tree ret = ix86_build_builtin_va_list_abi (ix86_abi);
-
- /* Initialize abi specific va_list builtin types. */
- if (TARGET_64BIT)
- {
- tree t;
- if (ix86_abi == MS_ABI)
- {
- t = ix86_build_builtin_va_list_abi (SYSV_ABI);
- if (TREE_CODE (t) != RECORD_TYPE)
- t = build_variant_type_copy (t);
- sysv_va_list_type_node = t;
- }
- else
- {
- t = ret;
- if (TREE_CODE (t) != RECORD_TYPE)
- t = build_variant_type_copy (t);
- sysv_va_list_type_node = t;
- }
- if (ix86_abi != MS_ABI)
- {
- t = ix86_build_builtin_va_list_abi (MS_ABI);
- if (TREE_CODE (t) != RECORD_TYPE)
- t = build_variant_type_copy (t);
- ms_va_list_type_node = t;
- }
- else
- {
- t = ret;
- if (TREE_CODE (t) != RECORD_TYPE)
- t = build_variant_type_copy (t);
- ms_va_list_type_node = t;
- }
- }
-
- return ret;
-}
-
-/* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
-
-static void
-setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
-{
- rtx save_area, mem;
- alias_set_type set;
- int i, max;
-
- /* GPR size of varargs save area. */
- if (cfun->va_list_gpr_size)
- ix86_varargs_gpr_size = X86_64_REGPARM_MAX * UNITS_PER_WORD;
- else
- ix86_varargs_gpr_size = 0;
-
- /* FPR size of varargs save area. We don't need it if we don't pass
- anything in SSE registers. */
- if (TARGET_SSE && cfun->va_list_fpr_size)
- ix86_varargs_fpr_size = X86_64_SSE_REGPARM_MAX * 16;
- else
- ix86_varargs_fpr_size = 0;
-
- if (! ix86_varargs_gpr_size && ! ix86_varargs_fpr_size)
- return;
-
- save_area = frame_pointer_rtx;
- set = get_varargs_alias_set ();
-
- max = cum->regno + cfun->va_list_gpr_size / UNITS_PER_WORD;
- if (max > X86_64_REGPARM_MAX)
- max = X86_64_REGPARM_MAX;
-
- for (i = cum->regno; i < max; i++)
- {
- mem = gen_rtx_MEM (word_mode,
- plus_constant (Pmode, save_area, i * UNITS_PER_WORD));
- MEM_NOTRAP_P (mem) = 1;
- set_mem_alias_set (mem, set);
- emit_move_insn (mem,
- gen_rtx_REG (word_mode,
- x86_64_int_parameter_registers[i]));
- }
-
- if (ix86_varargs_fpr_size)
- {
- enum machine_mode smode;
- rtx label, test;
-
- /* Now emit code to save SSE registers. The AX parameter contains number
- of SSE parameter registers used to call this function, though all we
- actually check here is the zero/non-zero status. */
-
- label = gen_label_rtx ();
- test = gen_rtx_EQ (VOIDmode, gen_rtx_REG (QImode, AX_REG), const0_rtx);
- emit_jump_insn (gen_cbranchqi4 (test, XEXP (test, 0), XEXP (test, 1),
- label));
-
- /* ??? If !TARGET_SSE_TYPELESS_STORES, would we perform better if
- we used movdqa (i.e. TImode) instead? Perhaps even better would
- be if we could determine the real mode of the data, via a hook
- into pass_stdarg. Ignore all that for now. */
- smode = V4SFmode;
- if (crtl->stack_alignment_needed < GET_MODE_ALIGNMENT (smode))
- crtl->stack_alignment_needed = GET_MODE_ALIGNMENT (smode);
-
- max = cum->sse_regno + cfun->va_list_fpr_size / 16;
- if (max > X86_64_SSE_REGPARM_MAX)
- max = X86_64_SSE_REGPARM_MAX;
-
- for (i = cum->sse_regno; i < max; ++i)
- {
- mem = plus_constant (Pmode, save_area,
- i * 16 + ix86_varargs_gpr_size);
- mem = gen_rtx_MEM (smode, mem);
- MEM_NOTRAP_P (mem) = 1;
- set_mem_alias_set (mem, set);
- set_mem_align (mem, GET_MODE_ALIGNMENT (smode));
-
- emit_move_insn (mem, gen_rtx_REG (smode, SSE_REGNO (i)));
- }
-
- emit_label (label);
- }
-}
-
-static void
-setup_incoming_varargs_ms_64 (CUMULATIVE_ARGS *cum)
-{
- alias_set_type set = get_varargs_alias_set ();
- int i;
-
- /* Reset to zero, as there might be a sysv vaarg used
- before. */
- ix86_varargs_gpr_size = 0;
- ix86_varargs_fpr_size = 0;
-
- for (i = cum->regno; i < X86_64_MS_REGPARM_MAX; i++)
- {
- rtx reg, mem;
-
- mem = gen_rtx_MEM (Pmode,
- plus_constant (Pmode, virtual_incoming_args_rtx,
- i * UNITS_PER_WORD));
- MEM_NOTRAP_P (mem) = 1;
- set_mem_alias_set (mem, set);
-
- reg = gen_rtx_REG (Pmode, x86_64_ms_abi_int_parameter_registers[i]);
- emit_move_insn (mem, reg);
- }
-}
-
-static void
-ix86_setup_incoming_varargs (cumulative_args_t cum_v, enum machine_mode mode,
- tree type, int *pretend_size ATTRIBUTE_UNUSED,
- int no_rtl)
-{
- CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
- CUMULATIVE_ARGS next_cum;
- tree fntype;
-
- /* This argument doesn't appear to be used anymore. Which is good,
- because the old code here didn't suppress rtl generation. */
- gcc_assert (!no_rtl);
-
- if (!TARGET_64BIT)
- return;
-
- fntype = TREE_TYPE (current_function_decl);
-
- /* For varargs, we do not want to skip the dummy va_dcl argument.
- For stdargs, we do want to skip the last named argument. */
- next_cum = *cum;
- if (stdarg_p (fntype))
- ix86_function_arg_advance (pack_cumulative_args (&next_cum), mode, type,
- true);
-
- if (cum->call_abi == MS_ABI)
- setup_incoming_varargs_ms_64 (&next_cum);
- else
- setup_incoming_varargs_64 (&next_cum);
-}
-
-/* Checks if TYPE is of kind va_list char *. */
-
-static bool
-is_va_list_char_pointer (tree type)
-{
- tree canonic;
-
- /* For 32-bit it is always true. */
- if (!TARGET_64BIT)
- return true;
- canonic = ix86_canonical_va_list_type (type);
- return (canonic == ms_va_list_type_node
- || (ix86_abi == MS_ABI && canonic == va_list_type_node));
-}
-
-/* Implement va_start. */
-
-static void
-ix86_va_start (tree valist, rtx nextarg)
-{
- HOST_WIDE_INT words, n_gpr, n_fpr;
- tree f_gpr, f_fpr, f_ovf, f_sav;
- tree gpr, fpr, ovf, sav, t;
- tree type;
- rtx ovf_rtx;
-
- if (flag_split_stack
- && cfun->machine->split_stack_varargs_pointer == NULL_RTX)
- {
- unsigned int scratch_regno;
-
- /* When we are splitting the stack, we can't refer to the stack
- arguments using internal_arg_pointer, because they may be on
- the old stack. The split stack prologue will arrange to
- leave a pointer to the old stack arguments in a scratch
- register, which we here copy to a pseudo-register. The split
- stack prologue can't set the pseudo-register directly because
- it (the prologue) runs before any registers have been saved. */
-
- scratch_regno = split_stack_prologue_scratch_regno ();
- if (scratch_regno != INVALID_REGNUM)
- {
- rtx reg, seq;
-
- reg = gen_reg_rtx (Pmode);
- cfun->machine->split_stack_varargs_pointer = reg;
-
- start_sequence ();
- emit_move_insn (reg, gen_rtx_REG (Pmode, scratch_regno));
- seq = get_insns ();
- end_sequence ();
-
- push_topmost_sequence ();
- emit_insn_after (seq, entry_of_function ());
- pop_topmost_sequence ();
- }
- }
-
- /* Only 64bit target needs something special. */
- if (!TARGET_64BIT || is_va_list_char_pointer (TREE_TYPE (valist)))
- {
- if (cfun->machine->split_stack_varargs_pointer == NULL_RTX)
- std_expand_builtin_va_start (valist, nextarg);
- else
- {
- rtx va_r, next;
-
- va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
- next = expand_binop (ptr_mode, add_optab,
- cfun->machine->split_stack_varargs_pointer,
- crtl->args.arg_offset_rtx,
- NULL_RTX, 0, OPTAB_LIB_WIDEN);
- convert_move (va_r, next, 0);
- }
- return;
- }
-
- f_gpr = TYPE_FIELDS (TREE_TYPE (sysv_va_list_type_node));
- f_fpr = DECL_CHAIN (f_gpr);
- f_ovf = DECL_CHAIN (f_fpr);
- f_sav = DECL_CHAIN (f_ovf);
-
- valist = build_simple_mem_ref (valist);
- TREE_TYPE (valist) = TREE_TYPE (sysv_va_list_type_node);
- /* The following should be folded into the MEM_REF offset. */
- gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), unshare_expr (valist),
- f_gpr, NULL_TREE);
- fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
- f_fpr, NULL_TREE);
- ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
- f_ovf, NULL_TREE);
- sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
- f_sav, NULL_TREE);
-
- /* Count number of gp and fp argument registers used. */
- words = crtl->args.info.words;
- n_gpr = crtl->args.info.regno;
- n_fpr = crtl->args.info.sse_regno;
-
- if (cfun->va_list_gpr_size)
- {
- type = TREE_TYPE (gpr);
- t = build2 (MODIFY_EXPR, type,
- gpr, build_int_cst (type, n_gpr * 8));
- TREE_SIDE_EFFECTS (t) = 1;
- expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
- }
-
- if (TARGET_SSE && cfun->va_list_fpr_size)
- {
- type = TREE_TYPE (fpr);
- t = build2 (MODIFY_EXPR, type, fpr,
- build_int_cst (type, n_fpr * 16 + 8*X86_64_REGPARM_MAX));
- TREE_SIDE_EFFECTS (t) = 1;
- expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
- }
-
- /* Find the overflow area. */
- type = TREE_TYPE (ovf);
- if (cfun->machine->split_stack_varargs_pointer == NULL_RTX)
- ovf_rtx = crtl->args.internal_arg_pointer;
- else
- ovf_rtx = cfun->machine->split_stack_varargs_pointer;
- t = make_tree (type, ovf_rtx);
- if (words != 0)
- t = fold_build_pointer_plus_hwi (t, words * UNITS_PER_WORD);
- t = build2 (MODIFY_EXPR, type, ovf, t);
- TREE_SIDE_EFFECTS (t) = 1;
- expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
-
- if (ix86_varargs_gpr_size || ix86_varargs_fpr_size)
- {
- /* Find the register save area.
- Prologue of the function save it right above stack frame. */
- type = TREE_TYPE (sav);
- t = make_tree (type, frame_pointer_rtx);
- if (!ix86_varargs_gpr_size)
- t = fold_build_pointer_plus_hwi (t, -8 * X86_64_REGPARM_MAX);
- t = build2 (MODIFY_EXPR, type, sav, t);
- TREE_SIDE_EFFECTS (t) = 1;
- expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
- }
-}
-
-/* Implement va_arg. */
-
-static tree
-ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
- gimple_seq *post_p)
-{
- static const int intreg[6] = { 0, 1, 2, 3, 4, 5 };
- tree f_gpr, f_fpr, f_ovf, f_sav;
- tree gpr, fpr, ovf, sav, t;
- int size, rsize;
- tree lab_false, lab_over = NULL_TREE;
- tree addr, t2;
- rtx container;
- int indirect_p = 0;
- tree ptrtype;
- enum machine_mode nat_mode;
- unsigned int arg_boundary;
-
- /* Only 64bit target needs something special. */
- if (!TARGET_64BIT || is_va_list_char_pointer (TREE_TYPE (valist)))
- return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
-
- f_gpr = TYPE_FIELDS (TREE_TYPE (sysv_va_list_type_node));
- f_fpr = DECL_CHAIN (f_gpr);
- f_ovf = DECL_CHAIN (f_fpr);
- f_sav = DECL_CHAIN (f_ovf);
-
- gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr),
- build_va_arg_indirect_ref (valist), f_gpr, NULL_TREE);
- valist = build_va_arg_indirect_ref (valist);
- fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
- ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
- sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
-
- indirect_p = pass_by_reference (NULL, TYPE_MODE (type), type, false);
- if (indirect_p)
- type = build_pointer_type (type);
- size = int_size_in_bytes (type);
- rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
-
- nat_mode = type_natural_mode (type, NULL);
- switch (nat_mode)
- {
- case V8SFmode:
- case V8SImode:
- case V32QImode:
- case V16HImode:
- case V4DFmode:
- case V4DImode:
- /* Unnamed 256bit vector mode parameters are passed on stack. */
- if (!TARGET_64BIT_MS_ABI)
- {
- container = NULL;
- break;
- }
-
- default:
- container = construct_container (nat_mode, TYPE_MODE (type),
- type, 0, X86_64_REGPARM_MAX,
- X86_64_SSE_REGPARM_MAX, intreg,
- 0);
- break;
- }
-
- /* Pull the value out of the saved registers. */
-
- addr = create_tmp_var (ptr_type_node, "addr");
-
- if (container)
- {
- int needed_intregs, needed_sseregs;
- bool need_temp;
- tree int_addr, sse_addr;
-
- lab_false = create_artificial_label (UNKNOWN_LOCATION);
- lab_over = create_artificial_label (UNKNOWN_LOCATION);
-
- examine_argument (nat_mode, type, 0, &needed_intregs, &needed_sseregs);
-
- need_temp = (!REG_P (container)
- && ((needed_intregs && TYPE_ALIGN (type) > 64)
- || TYPE_ALIGN (type) > 128));
-
- /* In case we are passing structure, verify that it is consecutive block
- on the register save area. If not we need to do moves. */
- if (!need_temp && !REG_P (container))
- {
- /* Verify that all registers are strictly consecutive */
- if (SSE_REGNO_P (REGNO (XEXP (XVECEXP (container, 0, 0), 0))))
- {
- int i;
-
- for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++)
- {
- rtx slot = XVECEXP (container, 0, i);
- if (REGNO (XEXP (slot, 0)) != FIRST_SSE_REG + (unsigned int) i
- || INTVAL (XEXP (slot, 1)) != i * 16)
- need_temp = 1;
- }
- }
- else
- {
- int i;
-
- for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++)
- {
- rtx slot = XVECEXP (container, 0, i);
- if (REGNO (XEXP (slot, 0)) != (unsigned int) i
- || INTVAL (XEXP (slot, 1)) != i * 8)
- need_temp = 1;
- }
- }
- }
- if (!need_temp)
- {
- int_addr = addr;
- sse_addr = addr;
- }
- else
- {
- int_addr = create_tmp_var (ptr_type_node, "int_addr");
- sse_addr = create_tmp_var (ptr_type_node, "sse_addr");
- }
-
- /* First ensure that we fit completely in registers. */
- if (needed_intregs)
- {
- t = build_int_cst (TREE_TYPE (gpr),
- (X86_64_REGPARM_MAX - needed_intregs + 1) * 8);
- t = build2 (GE_EXPR, boolean_type_node, gpr, t);
- t2 = build1 (GOTO_EXPR, void_type_node, lab_false);
- t = build3 (COND_EXPR, void_type_node, t, t2, NULL_TREE);
- gimplify_and_add (t, pre_p);
- }
- if (needed_sseregs)
- {
- t = build_int_cst (TREE_TYPE (fpr),
- (X86_64_SSE_REGPARM_MAX - needed_sseregs + 1) * 16
- + X86_64_REGPARM_MAX * 8);
- t = build2 (GE_EXPR, boolean_type_node, fpr, t);
- t2 = build1 (GOTO_EXPR, void_type_node, lab_false);
- t = build3 (COND_EXPR, void_type_node, t, t2, NULL_TREE);
- gimplify_and_add (t, pre_p);
- }
-
- /* Compute index to start of area used for integer regs. */
- if (needed_intregs)
- {
- /* int_addr = gpr + sav; */
- t = fold_build_pointer_plus (sav, gpr);
- gimplify_assign (int_addr, t, pre_p);
- }
- if (needed_sseregs)
- {
- /* sse_addr = fpr + sav; */
- t = fold_build_pointer_plus (sav, fpr);
- gimplify_assign (sse_addr, t, pre_p);
- }
- if (need_temp)
- {
- int i, prev_size = 0;
- tree temp = create_tmp_var (type, "va_arg_tmp");
-
- /* addr = &temp; */
- t = build1 (ADDR_EXPR, build_pointer_type (type), temp);
- gimplify_assign (addr, t, pre_p);
-
- for (i = 0; i < XVECLEN (container, 0); i++)
- {
- rtx slot = XVECEXP (container, 0, i);
- rtx reg = XEXP (slot, 0);
- enum machine_mode mode = GET_MODE (reg);
- tree piece_type;
- tree addr_type;
- tree daddr_type;
- tree src_addr, src;
- int src_offset;
- tree dest_addr, dest;
- int cur_size = GET_MODE_SIZE (mode);
-
- gcc_assert (prev_size <= INTVAL (XEXP (slot, 1)));
- prev_size = INTVAL (XEXP (slot, 1));
- if (prev_size + cur_size > size)
- {
- cur_size = size - prev_size;
- mode = mode_for_size (cur_size * BITS_PER_UNIT, MODE_INT, 1);
- if (mode == BLKmode)
- mode = QImode;
- }
- piece_type = lang_hooks.types.type_for_mode (mode, 1);
- if (mode == GET_MODE (reg))
- addr_type = build_pointer_type (piece_type);
- else
- addr_type = build_pointer_type_for_mode (piece_type, ptr_mode,
- true);
- daddr_type = build_pointer_type_for_mode (piece_type, ptr_mode,
- true);
-
- if (SSE_REGNO_P (REGNO (reg)))
- {
- src_addr = sse_addr;
- src_offset = (REGNO (reg) - FIRST_SSE_REG) * 16;
- }
- else
- {
- src_addr = int_addr;
- src_offset = REGNO (reg) * 8;
- }
- src_addr = fold_convert (addr_type, src_addr);
- src_addr = fold_build_pointer_plus_hwi (src_addr, src_offset);
-
- dest_addr = fold_convert (daddr_type, addr);
- dest_addr = fold_build_pointer_plus_hwi (dest_addr, prev_size);
- if (cur_size == GET_MODE_SIZE (mode))
- {
- src = build_va_arg_indirect_ref (src_addr);
- dest = build_va_arg_indirect_ref (dest_addr);
-
- gimplify_assign (dest, src, pre_p);
- }
- else
- {
- tree copy
- = build_call_expr (builtin_decl_implicit (BUILT_IN_MEMCPY),
- 3, dest_addr, src_addr,
- size_int (cur_size));
- gimplify_and_add (copy, pre_p);
- }
- prev_size += cur_size;
- }
- }
-
- if (needed_intregs)
- {
- t = build2 (PLUS_EXPR, TREE_TYPE (gpr), gpr,
- build_int_cst (TREE_TYPE (gpr), needed_intregs * 8));
- gimplify_assign (gpr, t, pre_p);
- }
-
- if (needed_sseregs)
- {
- t = build2 (PLUS_EXPR, TREE_TYPE (fpr), fpr,
- build_int_cst (TREE_TYPE (fpr), needed_sseregs * 16));
- gimplify_assign (fpr, t, pre_p);
- }
-
- gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
-
- gimple_seq_add_stmt (pre_p, gimple_build_label (lab_false));
- }
-
- /* ... otherwise out of the overflow area. */
-
- /* When we align parameter on stack for caller, if the parameter
- alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
- aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee
- here with caller. */
- arg_boundary = ix86_function_arg_boundary (VOIDmode, type);
- if ((unsigned int) arg_boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
- arg_boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
-
- /* Care for on-stack alignment if needed. */
- if (arg_boundary <= 64 || size == 0)
- t = ovf;
- else
- {
- HOST_WIDE_INT align = arg_boundary / 8;
- t = fold_build_pointer_plus_hwi (ovf, align - 1);
- t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
- build_int_cst (TREE_TYPE (t), -align));
- }
-
- gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
- gimplify_assign (addr, t, pre_p);
-
- t = fold_build_pointer_plus_hwi (t, rsize * UNITS_PER_WORD);
- gimplify_assign (unshare_expr (ovf), t, pre_p);
-
- if (container)
- gimple_seq_add_stmt (pre_p, gimple_build_label (lab_over));
-
- ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
- addr = fold_convert (ptrtype, addr);
-
- if (indirect_p)
- addr = build_va_arg_indirect_ref (addr);
- return build_va_arg_indirect_ref (addr);
-}
-
-/* Return true if OPNUM's MEM should be matched
- in movabs* patterns. */
-
-bool
-ix86_check_movabs (rtx insn, int opnum)
-{
- rtx set, mem;
-
- set = PATTERN (insn);
- if (GET_CODE (set) == PARALLEL)
- set = XVECEXP (set, 0, 0);
- gcc_assert (GET_CODE (set) == SET);
- mem = XEXP (set, opnum);
- while (GET_CODE (mem) == SUBREG)
- mem = SUBREG_REG (mem);
- gcc_assert (MEM_P (mem));
- return volatile_ok || !MEM_VOLATILE_P (mem);
-}
-
-/* Initialize the table of extra 80387 mathematical constants. */
-
-static void
-init_ext_80387_constants (void)
-{
- static const char * cst[5] =
- {
- "0.3010299956639811952256464283594894482", /* 0: fldlg2 */
- "0.6931471805599453094286904741849753009", /* 1: fldln2 */
- "1.4426950408889634073876517827983434472", /* 2: fldl2e */
- "3.3219280948873623478083405569094566090", /* 3: fldl2t */
- "3.1415926535897932385128089594061862044", /* 4: fldpi */
- };
- int i;
-
- for (i = 0; i < 5; i++)
- {
- real_from_string (&ext_80387_constants_table[i], cst[i]);
- /* Ensure each constant is rounded to XFmode precision. */
- real_convert (&ext_80387_constants_table[i],
- XFmode, &ext_80387_constants_table[i]);
- }
-
- ext_80387_constants_init = 1;
-}
-
-/* Return non-zero if the constant is something that
- can be loaded with a special instruction. */
-
-int
-standard_80387_constant_p (rtx x)
-{
- enum machine_mode mode = GET_MODE (x);
-
- REAL_VALUE_TYPE r;
-
- if (!(X87_FLOAT_MODE_P (mode) && (GET_CODE (x) == CONST_DOUBLE)))
- return -1;
-
- if (x == CONST0_RTX (mode))
- return 1;
- if (x == CONST1_RTX (mode))
- return 2;
-
- REAL_VALUE_FROM_CONST_DOUBLE (r, x);
-
- /* For XFmode constants, try to find a special 80387 instruction when
- optimizing for size or on those CPUs that benefit from them. */
- if (mode == XFmode
- && (optimize_function_for_size_p (cfun) || TARGET_EXT_80387_CONSTANTS))
- {
- int i;
-
- if (! ext_80387_constants_init)
- init_ext_80387_constants ();
-
- for (i = 0; i < 5; i++)
- if (real_identical (&r, &ext_80387_constants_table[i]))
- return i + 3;
- }
-
- /* Load of the constant -0.0 or -1.0 will be split as
- fldz;fchs or fld1;fchs sequence. */
- if (real_isnegzero (&r))
- return 8;
- if (real_identical (&r, &dconstm1))
- return 9;
-
- return 0;
-}
-
-/* Return the opcode of the special instruction to be used to load
- the constant X. */
-
-const char *
-standard_80387_constant_opcode (rtx x)
-{
- switch (standard_80387_constant_p (x))
- {
- case 1:
- return "fldz";
- case 2:
- return "fld1";
- case 3:
- return "fldlg2";
- case 4:
- return "fldln2";
- case 5:
- return "fldl2e";
- case 6:
- return "fldl2t";
- case 7:
- return "fldpi";
- case 8:
- case 9:
- return "#";
- default:
- gcc_unreachable ();
- }
-}
-
-/* Return the CONST_DOUBLE representing the 80387 constant that is
- loaded by the specified special instruction. The argument IDX
- matches the return value from standard_80387_constant_p. */
-
-rtx
-standard_80387_constant_rtx (int idx)
-{
- int i;
-
- if (! ext_80387_constants_init)
- init_ext_80387_constants ();
-
- switch (idx)
- {
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- i = idx - 3;
- break;
-
- default:
- gcc_unreachable ();
- }
-
- return CONST_DOUBLE_FROM_REAL_VALUE (ext_80387_constants_table[i],
- XFmode);
-}
-
-/* Return 1 if X is all 0s and 2 if x is all 1s
- in supported SSE/AVX vector mode. */
-
-int
-standard_sse_constant_p (rtx x)
-{
- enum machine_mode mode = GET_MODE (x);
-
- if (x == const0_rtx || x == CONST0_RTX (GET_MODE (x)))
- return 1;
- if (vector_all_ones_operand (x, mode))
- switch (mode)
- {
- case V16QImode:
- case V8HImode:
- case V4SImode:
- case V2DImode:
- if (TARGET_SSE2)
- return 2;
- case V32QImode:
- case V16HImode:
- case V8SImode:
- case V4DImode:
- if (TARGET_AVX2)
- return 2;
- default:
- break;
- }
-
- return 0;
-}
-
-/* Return the opcode of the special instruction to be used to load
- the constant X. */
-
-const char *
-standard_sse_constant_opcode (rtx insn, rtx x)
-{
- switch (standard_sse_constant_p (x))
- {
- case 1:
- switch (get_attr_mode (insn))
- {
- case MODE_TI:
- return "%vpxor\t%0, %d0";
- case MODE_V2DF:
- return "%vxorpd\t%0, %d0";
- case MODE_V4SF:
- return "%vxorps\t%0, %d0";
-
- case MODE_OI:
- return "vpxor\t%x0, %x0, %x0";
- case MODE_V4DF:
- return "vxorpd\t%x0, %x0, %x0";
- case MODE_V8SF:
- return "vxorps\t%x0, %x0, %x0";
-
- default:
- break;
- }
-
- case 2:
- if (TARGET_AVX)
- return "vpcmpeqd\t%0, %0, %0";
- else
- return "pcmpeqd\t%0, %0";
-
- default:
- break;
- }
- gcc_unreachable ();
-}
-
-/* Returns true if OP contains a symbol reference */
-
-bool
-symbolic_reference_mentioned_p (rtx op)
-{
- const char *fmt;
- int i;
-
- if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
- return true;
-
- fmt = GET_RTX_FORMAT (GET_CODE (op));
- for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
- {
- if (fmt[i] == 'E')
- {
- int j;
-
- for (j = XVECLEN (op, i) - 1; j >= 0; j--)
- if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
- return true;
- }
-
- else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
- return true;
- }
-
- return false;
-}
-
-/* Return true if it is appropriate to emit `ret' instructions in the
- body of a function. Do this only if the epilogue is simple, needing a
- couple of insns. Prior to reloading, we can't tell how many registers
- must be saved, so return false then. Return false if there is no frame
- marker to de-allocate. */
-
-bool
-ix86_can_use_return_insn_p (void)
-{
- struct ix86_frame frame;
-
- if (! reload_completed || frame_pointer_needed)
- return 0;
-
- /* Don't allow more than 32k pop, since that's all we can do
- with one instruction. */
- if (crtl->args.pops_args && crtl->args.size >= 32768)
- return 0;
-
- ix86_compute_frame_layout (&frame);
- return (frame.stack_pointer_offset == UNITS_PER_WORD
- && (frame.nregs + frame.nsseregs) == 0);
-}
-
-/* Value should be nonzero if functions must have frame pointers.
- Zero means the frame pointer need not be set up (and parms may
- be accessed via the stack pointer) in functions that seem suitable. */
-
-static bool
-ix86_frame_pointer_required (void)
-{
- /* If we accessed previous frames, then the generated code expects
- to be able to access the saved ebp value in our frame. */
- if (cfun->machine->accesses_prev_frame)
- return true;
-
- /* Several x86 os'es need a frame pointer for other reasons,
- usually pertaining to setjmp. */
- if (SUBTARGET_FRAME_POINTER_REQUIRED)
- return true;
-
- /* For older 32-bit runtimes setjmp requires valid frame-pointer. */
- if (TARGET_32BIT_MS_ABI && cfun->calls_setjmp)
- return true;
-
- /* Win64 SEH, very large frames need a frame-pointer as maximum stack
- allocation is 4GB. */
- if (TARGET_64BIT_MS_ABI && get_frame_size () > SEH_MAX_FRAME_SIZE)
- return true;
-
- /* In ix86_option_override_internal, TARGET_OMIT_LEAF_FRAME_POINTER
- turns off the frame pointer by default. Turn it back on now if
- we've not got a leaf function. */
- if (TARGET_OMIT_LEAF_FRAME_POINTER
- && (!crtl->is_leaf
- || ix86_current_function_calls_tls_descriptor))
- return true;
-
- if (crtl->profile && !flag_fentry)
- return true;
-
- return false;
-}
-
-/* Record that the current function accesses previous call frames. */
-
-void
-ix86_setup_frame_addresses (void)
-{
- cfun->machine->accesses_prev_frame = 1;
-}
-
-#ifndef USE_HIDDEN_LINKONCE
-# if defined(HAVE_GAS_HIDDEN) && (SUPPORTS_ONE_ONLY - 0)
-# define USE_HIDDEN_LINKONCE 1
-# else
-# define USE_HIDDEN_LINKONCE 0
-# endif
-#endif
-
-static int pic_labels_used;
-
-/* Fills in the label name that should be used for a pc thunk for
- the given register. */
-
-static void
-get_pc_thunk_name (char name[32], unsigned int regno)
-{
- gcc_assert (!TARGET_64BIT);
-
- if (USE_HIDDEN_LINKONCE)
- sprintf (name, "__x86.get_pc_thunk.%s", reg_names[regno]);
- else
- ASM_GENERATE_INTERNAL_LABEL (name, "LPR", regno);
-}
-
-
-/* This function generates code for -fpic that loads %ebx with
- the return address of the caller and then returns. */
-
-static void
-ix86_code_end (void)
-{
- rtx xops[2];
- int regno;
-
- for (regno = AX_REG; regno <= SP_REG; regno++)
- {
- char name[32];
- tree decl;
-
- if (!(pic_labels_used & (1 << regno)))
- continue;
-
- get_pc_thunk_name (name, regno);
-
- decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
- get_identifier (name),
- build_function_type_list (void_type_node, NULL_TREE));
- DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,
- NULL_TREE, void_type_node);
- TREE_PUBLIC (decl) = 1;
- TREE_STATIC (decl) = 1;
- DECL_IGNORED_P (decl) = 1;
-
-#if TARGET_MACHO
- if (TARGET_MACHO)
- {
- switch_to_section (darwin_sections[text_coal_section]);
- fputs ("\t.weak_definition\t", asm_out_file);
- assemble_name (asm_out_file, name);
- fputs ("\n\t.private_extern\t", asm_out_file);
- assemble_name (asm_out_file, name);
- putc ('\n', asm_out_file);
- ASM_OUTPUT_LABEL (asm_out_file, name);
- DECL_WEAK (decl) = 1;
- }
- else
-#endif
- if (USE_HIDDEN_LINKONCE)
- {
- DECL_COMDAT_GROUP (decl) = DECL_ASSEMBLER_NAME (decl);
-
- targetm.asm_out.unique_section (decl, 0);
- switch_to_section (get_named_section (decl, NULL, 0));
-
- targetm.asm_out.globalize_label (asm_out_file, name);
- fputs ("\t.hidden\t", asm_out_file);
- assemble_name (asm_out_file, name);
- putc ('\n', asm_out_file);
- ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl);
- }
- else
- {
- switch_to_section (text_section);
- ASM_OUTPUT_LABEL (asm_out_file, name);
- }
-
- DECL_INITIAL (decl) = make_node (BLOCK);
- current_function_decl = decl;
- init_function_start (decl);
- first_function_block_is_cold = false;
- /* Make sure unwind info is emitted for the thunk if needed. */
- final_start_function (emit_barrier (), asm_out_file, 1);
-
- /* Pad stack IP move with 4 instructions (two NOPs count
- as one instruction). */
- if (TARGET_PAD_SHORT_FUNCTION)
- {
- int i = 8;
-
- while (i--)
- fputs ("\tnop\n", asm_out_file);
- }
-
- xops[0] = gen_rtx_REG (Pmode, regno);
- xops[1] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
- output_asm_insn ("mov%z0\t{%1, %0|%0, %1}", xops);
- fputs ("\tret\n", asm_out_file);
- final_end_function ();
- init_insn_lengths ();
- free_after_compilation (cfun);
- set_cfun (NULL);
- current_function_decl = NULL;
- }
-
- if (flag_split_stack)
- file_end_indicate_split_stack ();
-}
-
-/* Emit code for the SET_GOT patterns. */
-
-const char *
-output_set_got (rtx dest, rtx label ATTRIBUTE_UNUSED)
-{
- rtx xops[3];
-
- xops[0] = dest;
-
- if (TARGET_VXWORKS_RTP && flag_pic)
- {
- /* Load (*VXWORKS_GOTT_BASE) into the PIC register. */
- xops[2] = gen_rtx_MEM (Pmode,
- gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE));
- output_asm_insn ("mov{l}\t{%2, %0|%0, %2}", xops);
-
- /* Load (*VXWORKS_GOTT_BASE)[VXWORKS_GOTT_INDEX] into the PIC register.
- Use %P and a local symbol in order to print VXWORKS_GOTT_INDEX as
- an unadorned address. */
- xops[2] = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
- SYMBOL_REF_FLAGS (xops[2]) |= SYMBOL_FLAG_LOCAL;
- output_asm_insn ("mov{l}\t{%P2(%0), %0|%0, DWORD PTR %P2[%0]}", xops);
- return "";
- }
-
- xops[1] = gen_rtx_SYMBOL_REF (Pmode, GOT_SYMBOL_NAME);
-
- if (!flag_pic)
- {
- xops[2] = gen_rtx_LABEL_REF (Pmode, label ? label : gen_label_rtx ());
-
- output_asm_insn ("mov%z0\t{%2, %0|%0, %2}", xops);
-
-#if TARGET_MACHO
- /* Output the Mach-O "canonical" label name ("Lxx$pb") here too. This
- is what will be referenced by the Mach-O PIC subsystem. */
- if (!label)
- ASM_OUTPUT_LABEL (asm_out_file, MACHOPIC_FUNCTION_BASE_NAME);
-#endif
-
- targetm.asm_out.internal_label (asm_out_file, "L",
- CODE_LABEL_NUMBER (XEXP (xops[2], 0)));
- }
- else
- {
- char name[32];
- get_pc_thunk_name (name, REGNO (dest));
- pic_labels_used |= 1 << REGNO (dest);
-
- xops[2] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
- xops[2] = gen_rtx_MEM (QImode, xops[2]);
- output_asm_insn ("call\t%X2", xops);
- /* Output the Mach-O "canonical" label name ("Lxx$pb") here too. This
- is what will be referenced by the Mach-O PIC subsystem. */
-#if TARGET_MACHO
- if (!label)
- ASM_OUTPUT_LABEL (asm_out_file, MACHOPIC_FUNCTION_BASE_NAME);
- else
- targetm.asm_out.internal_label (asm_out_file, "L",
- CODE_LABEL_NUMBER (label));
-#endif
- }
-
- if (!TARGET_MACHO)
- output_asm_insn ("add%z0\t{%1, %0|%0, %1}", xops);
-
- return "";
-}
-
-/* Generate an "push" pattern for input ARG. */
-
-static rtx
-gen_push (rtx arg)
-{
- struct machine_function *m = cfun->machine;
-
- if (m->fs.cfa_reg == stack_pointer_rtx)
- m->fs.cfa_offset += UNITS_PER_WORD;
- m->fs.sp_offset += UNITS_PER_WORD;
-
- if (REG_P (arg) && GET_MODE (arg) != word_mode)
- arg = gen_rtx_REG (word_mode, REGNO (arg));
-
- return gen_rtx_SET (VOIDmode,
- gen_rtx_MEM (word_mode,
- gen_rtx_PRE_DEC (Pmode,
- stack_pointer_rtx)),
- arg);
-}
-
-/* Generate an "pop" pattern for input ARG. */
-
-static rtx
-gen_pop (rtx arg)
-{
- if (REG_P (arg) && GET_MODE (arg) != word_mode)
- arg = gen_rtx_REG (word_mode, REGNO (arg));
-
- return gen_rtx_SET (VOIDmode,
- arg,
- gen_rtx_MEM (word_mode,
- gen_rtx_POST_INC (Pmode,
- stack_pointer_rtx)));
-}
-
-/* Return >= 0 if there is an unused call-clobbered register available
- for the entire function. */
-
-static unsigned int
-ix86_select_alt_pic_regnum (void)
-{
- if (crtl->is_leaf
- && !crtl->profile
- && !ix86_current_function_calls_tls_descriptor)
- {
- int i, drap;
- /* Can't use the same register for both PIC and DRAP. */
- if (crtl->drap_reg)
- drap = REGNO (crtl->drap_reg);
- else
- drap = -1;
- for (i = 2; i >= 0; --i)
- if (i != drap && !df_regs_ever_live_p (i))
- return i;
- }
-
- return INVALID_REGNUM;
-}
-
-/* Return TRUE if we need to save REGNO. */
-
-static bool
-ix86_save_reg (unsigned int regno, bool maybe_eh_return)
-{
- if (pic_offset_table_rtx
- && regno == REAL_PIC_OFFSET_TABLE_REGNUM
- && (df_regs_ever_live_p (REAL_PIC_OFFSET_TABLE_REGNUM)
- || crtl->profile
- || crtl->calls_eh_return
- || crtl->uses_const_pool))
- return ix86_select_alt_pic_regnum () == INVALID_REGNUM;
-
- if (crtl->calls_eh_return && maybe_eh_return)
- {
- unsigned i;
- for (i = 0; ; i++)
- {
- unsigned test = EH_RETURN_DATA_REGNO (i);
- if (test == INVALID_REGNUM)
- break;
- if (test == regno)
- return true;
- }
- }
-
- if (crtl->drap_reg && regno == REGNO (crtl->drap_reg))
- return true;
-
- return (df_regs_ever_live_p (regno)
- && !call_used_regs[regno]
- && !fixed_regs[regno]
- && (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed));
-}
-
-/* Return number of saved general prupose registers. */
-
-static int
-ix86_nsaved_regs (void)
-{
- int nregs = 0;
- int regno;
-
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- if (!SSE_REGNO_P (regno) && ix86_save_reg (regno, true))
- nregs ++;
- return nregs;
-}
-
-/* Return number of saved SSE registrers. */
-
-static int
-ix86_nsaved_sseregs (void)
-{
- int nregs = 0;
- int regno;
-
- if (!TARGET_64BIT_MS_ABI)
- return 0;
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- if (SSE_REGNO_P (regno) && ix86_save_reg (regno, true))
- nregs ++;
- return nregs;
-}
-
-/* Given FROM and TO register numbers, say whether this elimination is
- allowed. If stack alignment is needed, we can only replace argument
- pointer with hard frame pointer, or replace frame pointer with stack
- pointer. Otherwise, frame pointer elimination is automatically
- handled and all other eliminations are valid. */
-
-static bool
-ix86_can_eliminate (const int from, const int to)
-{
- if (stack_realign_fp)
- return ((from == ARG_POINTER_REGNUM
- && to == HARD_FRAME_POINTER_REGNUM)
- || (from == FRAME_POINTER_REGNUM
- && to == STACK_POINTER_REGNUM));
- else
- return to == STACK_POINTER_REGNUM ? !frame_pointer_needed : true;
-}
-
-/* Return the offset between two registers, one to be eliminated, and the other
- its replacement, at the start of a routine. */
-
-HOST_WIDE_INT
-ix86_initial_elimination_offset (int from, int to)
-{
- struct ix86_frame frame;
- ix86_compute_frame_layout (&frame);
-
- if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
- return frame.hard_frame_pointer_offset;
- else if (from == FRAME_POINTER_REGNUM
- && to == HARD_FRAME_POINTER_REGNUM)
- return frame.hard_frame_pointer_offset - frame.frame_pointer_offset;
- else
- {
- gcc_assert (to == STACK_POINTER_REGNUM);
-
- if (from == ARG_POINTER_REGNUM)
- return frame.stack_pointer_offset;
-
- gcc_assert (from == FRAME_POINTER_REGNUM);
- return frame.stack_pointer_offset - frame.frame_pointer_offset;
- }
-}
-
-/* In a dynamically-aligned function, we can't know the offset from
- stack pointer to frame pointer, so we must ensure that setjmp
- eliminates fp against the hard fp (%ebp) rather than trying to
- index from %esp up to the top of the frame across a gap that is
- of unknown (at compile-time) size. */
-static rtx
-ix86_builtin_setjmp_frame_value (void)
-{
- return stack_realign_fp ? hard_frame_pointer_rtx : virtual_stack_vars_rtx;
-}
-
-/* When using -fsplit-stack, the allocation routines set a field in
- the TCB to the bottom of the stack plus this much space, measured
- in bytes. */
-
-#define SPLIT_STACK_AVAILABLE 256
-
-/* Fill structure ix86_frame about frame of currently computed function. */
-
-static void
-ix86_compute_frame_layout (struct ix86_frame *frame)
-{
- unsigned HOST_WIDE_INT stack_alignment_needed;
- HOST_WIDE_INT offset;
- unsigned HOST_WIDE_INT preferred_alignment;
- HOST_WIDE_INT size = get_frame_size ();
- HOST_WIDE_INT to_allocate;
-
- frame->nregs = ix86_nsaved_regs ();
- frame->nsseregs = ix86_nsaved_sseregs ();
-
- stack_alignment_needed = crtl->stack_alignment_needed / BITS_PER_UNIT;
- preferred_alignment = crtl->preferred_stack_boundary / BITS_PER_UNIT;
-
- /* 64-bit MS ABI seem to require stack alignment to be always 16 except for
- function prologues and leaf. */
- if ((TARGET_64BIT_MS_ABI && preferred_alignment < 16)
- && (!crtl->is_leaf || cfun->calls_alloca != 0
- || ix86_current_function_calls_tls_descriptor))
- {
- preferred_alignment = 16;
- stack_alignment_needed = 16;
- crtl->preferred_stack_boundary = 128;
- crtl->stack_alignment_needed = 128;
- }
-
- gcc_assert (!size || stack_alignment_needed);
- gcc_assert (preferred_alignment >= STACK_BOUNDARY / BITS_PER_UNIT);
- gcc_assert (preferred_alignment <= stack_alignment_needed);
-
- /* For SEH we have to limit the amount of code movement into the prologue.
- At present we do this via a BLOCKAGE, at which point there's very little
- scheduling that can be done, which means that there's very little point
- in doing anything except PUSHs. */
- if (TARGET_SEH)
- cfun->machine->use_fast_prologue_epilogue = false;
-
- /* During reload iteration the amount of registers saved can change.
- Recompute the value as needed. Do not recompute when amount of registers
- didn't change as reload does multiple calls to the function and does not
- expect the decision to change within single iteration. */
- else if (!optimize_function_for_size_p (cfun)
- && cfun->machine->use_fast_prologue_epilogue_nregs != frame->nregs)
- {
- int count = frame->nregs;
- struct cgraph_node *node = cgraph_get_node (current_function_decl);
-
- cfun->machine->use_fast_prologue_epilogue_nregs = count;
-
- /* The fast prologue uses move instead of push to save registers. This
- is significantly longer, but also executes faster as modern hardware
- can execute the moves in parallel, but can't do that for push/pop.
-
- Be careful about choosing what prologue to emit: When function takes
- many instructions to execute we may use slow version as well as in
- case function is known to be outside hot spot (this is known with
- feedback only). Weight the size of function by number of registers
- to save as it is cheap to use one or two push instructions but very
- slow to use many of them. */
- if (count)
- count = (count - 1) * FAST_PROLOGUE_INSN_COUNT;
- if (node->frequency < NODE_FREQUENCY_NORMAL
- || (flag_branch_probabilities
- && node->frequency < NODE_FREQUENCY_HOT))
- cfun->machine->use_fast_prologue_epilogue = false;
- else
- cfun->machine->use_fast_prologue_epilogue
- = !expensive_function_p (count);
- }
-
- frame->save_regs_using_mov
- = (TARGET_PROLOGUE_USING_MOVE && cfun->machine->use_fast_prologue_epilogue
- /* If static stack checking is enabled and done with probes,
- the registers need to be saved before allocating the frame. */
- && flag_stack_check != STATIC_BUILTIN_STACK_CHECK);
-
- /* Skip return address. */
- offset = UNITS_PER_WORD;
-
- /* Skip pushed static chain. */
- if (ix86_static_chain_on_stack)
- offset += UNITS_PER_WORD;
-
- /* Skip saved base pointer. */
- if (frame_pointer_needed)
- offset += UNITS_PER_WORD;
- frame->hfp_save_offset = offset;
-
- /* The traditional frame pointer location is at the top of the frame. */
- frame->hard_frame_pointer_offset = offset;
-
- /* Register save area */
- offset += frame->nregs * UNITS_PER_WORD;
- frame->reg_save_offset = offset;
-
- /* On SEH target, registers are pushed just before the frame pointer
- location. */
- if (TARGET_SEH)
- frame->hard_frame_pointer_offset = offset;
-
- /* Align and set SSE register save area. */
- if (frame->nsseregs)
- {
- /* The only ABI that has saved SSE registers (Win64) also has a
- 16-byte aligned default stack, and thus we don't need to be
- within the re-aligned local stack frame to save them. */
- gcc_assert (INCOMING_STACK_BOUNDARY >= 128);
- offset = (offset + 16 - 1) & -16;
- offset += frame->nsseregs * 16;
- }
- frame->sse_reg_save_offset = offset;
-
- /* The re-aligned stack starts here. Values before this point are not
- directly comparable with values below this point. In order to make
- sure that no value happens to be the same before and after, force
- the alignment computation below to add a non-zero value. */
- if (stack_realign_fp)
- offset = (offset + stack_alignment_needed) & -stack_alignment_needed;
-
- /* Va-arg area */
- frame->va_arg_size = ix86_varargs_gpr_size + ix86_varargs_fpr_size;
- offset += frame->va_arg_size;
-
- /* Align start of frame for local function. */
- if (stack_realign_fp
- || offset != frame->sse_reg_save_offset
- || size != 0
- || !crtl->is_leaf
- || cfun->calls_alloca
- || ix86_current_function_calls_tls_descriptor)
- offset = (offset + stack_alignment_needed - 1) & -stack_alignment_needed;
-
- /* Frame pointer points here. */
- frame->frame_pointer_offset = offset;
-
- offset += size;
-
- /* Add outgoing arguments area. Can be skipped if we eliminated
- all the function calls as dead code.
- Skipping is however impossible when function calls alloca. Alloca
- expander assumes that last crtl->outgoing_args_size
- of stack frame are unused. */
- if (ACCUMULATE_OUTGOING_ARGS
- && (!crtl->is_leaf || cfun->calls_alloca
- || ix86_current_function_calls_tls_descriptor))
- {
- offset += crtl->outgoing_args_size;
- frame->outgoing_arguments_size = crtl->outgoing_args_size;
- }
- else
- frame->outgoing_arguments_size = 0;
-
- /* Align stack boundary. Only needed if we're calling another function
- or using alloca. */
- if (!crtl->is_leaf || cfun->calls_alloca
- || ix86_current_function_calls_tls_descriptor)
- offset = (offset + preferred_alignment - 1) & -preferred_alignment;
-
- /* We've reached end of stack frame. */
- frame->stack_pointer_offset = offset;
-
- /* Size prologue needs to allocate. */
- to_allocate = offset - frame->sse_reg_save_offset;
-
- if ((!to_allocate && frame->nregs <= 1)
- || (TARGET_64BIT && to_allocate >= (HOST_WIDE_INT) 0x80000000))
- frame->save_regs_using_mov = false;
-
- if (ix86_using_red_zone ()
- && crtl->sp_is_unchanging
- && crtl->is_leaf
- && !ix86_current_function_calls_tls_descriptor)
- {
- frame->red_zone_size = to_allocate;
- if (frame->save_regs_using_mov)
- frame->red_zone_size += frame->nregs * UNITS_PER_WORD;
- if (frame->red_zone_size > RED_ZONE_SIZE - RED_ZONE_RESERVE)
- frame->red_zone_size = RED_ZONE_SIZE - RED_ZONE_RESERVE;
- }
- else
- frame->red_zone_size = 0;
- frame->stack_pointer_offset -= frame->red_zone_size;
-
- /* The SEH frame pointer location is near the bottom of the frame.
- This is enforced by the fact that the difference between the
- stack pointer and the frame pointer is limited to 240 bytes in
- the unwind data structure. */
- if (TARGET_SEH)
- {
- HOST_WIDE_INT diff;
-
- /* If we can leave the frame pointer where it is, do so. Also, returns
- the establisher frame for __builtin_frame_address (0). */
- diff = frame->stack_pointer_offset - frame->hard_frame_pointer_offset;
- if (diff <= SEH_MAX_FRAME_SIZE
- && (diff > 240 || (diff & 15) != 0)
- && !crtl->accesses_prior_frames)
- {
- /* Ideally we'd determine what portion of the local stack frame
- (within the constraint of the lowest 240) is most heavily used.
- But without that complication, simply bias the frame pointer
- by 128 bytes so as to maximize the amount of the local stack
- frame that is addressable with 8-bit offsets. */
- frame->hard_frame_pointer_offset = frame->stack_pointer_offset - 128;
- }
- }
-}
-
-/* This is semi-inlined memory_address_length, but simplified
- since we know that we're always dealing with reg+offset, and
- to avoid having to create and discard all that rtl. */
-
-static inline int
-choose_baseaddr_len (unsigned int regno, HOST_WIDE_INT offset)
-{
- int len = 4;
-
- if (offset == 0)
- {
- /* EBP and R13 cannot be encoded without an offset. */
- len = (regno == BP_REG || regno == R13_REG);
- }
- else if (IN_RANGE (offset, -128, 127))
- len = 1;
-
- /* ESP and R12 must be encoded with a SIB byte. */
- if (regno == SP_REG || regno == R12_REG)
- len++;
-
- return len;
-}
-
-/* Return an RTX that points to CFA_OFFSET within the stack frame.
- The valid base registers are taken from CFUN->MACHINE->FS. */
-
-static rtx
-choose_baseaddr (HOST_WIDE_INT cfa_offset)
-{
- const struct machine_function *m = cfun->machine;
- rtx base_reg = NULL;
- HOST_WIDE_INT base_offset = 0;
-
- if (m->use_fast_prologue_epilogue)
- {
- /* Choose the base register most likely to allow the most scheduling
- opportunities. Generally FP is valid throughout the function,
- while DRAP must be reloaded within the epilogue. But choose either
- over the SP due to increased encoding size. */
-
- if (m->fs.fp_valid)
- {
- base_reg = hard_frame_pointer_rtx;
- base_offset = m->fs.fp_offset - cfa_offset;
- }
- else if (m->fs.drap_valid)
- {
- base_reg = crtl->drap_reg;
- base_offset = 0 - cfa_offset;
- }
- else if (m->fs.sp_valid)
- {
- base_reg = stack_pointer_rtx;
- base_offset = m->fs.sp_offset - cfa_offset;
- }
- }
- else
- {
- HOST_WIDE_INT toffset;
- int len = 16, tlen;
-
- /* Choose the base register with the smallest address encoding.
- With a tie, choose FP > DRAP > SP. */
- if (m->fs.sp_valid)
- {
- base_reg = stack_pointer_rtx;
- base_offset = m->fs.sp_offset - cfa_offset;
- len = choose_baseaddr_len (STACK_POINTER_REGNUM, base_offset);
- }
- if (m->fs.drap_valid)
- {
- toffset = 0 - cfa_offset;
- tlen = choose_baseaddr_len (REGNO (crtl->drap_reg), toffset);
- if (tlen <= len)
- {
- base_reg = crtl->drap_reg;
- base_offset = toffset;
- len = tlen;
- }
- }
- if (m->fs.fp_valid)
- {
- toffset = m->fs.fp_offset - cfa_offset;
- tlen = choose_baseaddr_len (HARD_FRAME_POINTER_REGNUM, toffset);
- if (tlen <= len)
- {
- base_reg = hard_frame_pointer_rtx;
- base_offset = toffset;
- len = tlen;
- }
- }
- }
- gcc_assert (base_reg != NULL);
-
- return plus_constant (Pmode, base_reg, base_offset);
-}
-
-/* Emit code to save registers in the prologue. */
-
-static void
-ix86_emit_save_regs (void)
-{
- unsigned int regno;
- rtx insn;
-
- for (regno = FIRST_PSEUDO_REGISTER - 1; regno-- > 0; )
- if (!SSE_REGNO_P (regno) && ix86_save_reg (regno, true))
- {
- insn = emit_insn (gen_push (gen_rtx_REG (word_mode, regno)));
- RTX_FRAME_RELATED_P (insn) = 1;
- }
-}
-
-/* Emit a single register save at CFA - CFA_OFFSET. */
-
-static void
-ix86_emit_save_reg_using_mov (enum machine_mode mode, unsigned int regno,
- HOST_WIDE_INT cfa_offset)
-{
- struct machine_function *m = cfun->machine;
- rtx reg = gen_rtx_REG (mode, regno);
- rtx mem, addr, base, insn;
-
- addr = choose_baseaddr (cfa_offset);
- mem = gen_frame_mem (mode, addr);
-
- /* For SSE saves, we need to indicate the 128-bit alignment. */
- set_mem_align (mem, GET_MODE_ALIGNMENT (mode));
-
- insn = emit_move_insn (mem, reg);
- RTX_FRAME_RELATED_P (insn) = 1;
-
- base = addr;
- if (GET_CODE (base) == PLUS)
- base = XEXP (base, 0);
- gcc_checking_assert (REG_P (base));
-
- /* When saving registers into a re-aligned local stack frame, avoid
- any tricky guessing by dwarf2out. */
- if (m->fs.realigned)
- {
- gcc_checking_assert (stack_realign_drap);
-
- if (regno == REGNO (crtl->drap_reg))
- {
- /* A bit of a hack. We force the DRAP register to be saved in
- the re-aligned stack frame, which provides us with a copy
- of the CFA that will last past the prologue. Install it. */
- gcc_checking_assert (cfun->machine->fs.fp_valid);
- addr = plus_constant (Pmode, hard_frame_pointer_rtx,
- cfun->machine->fs.fp_offset - cfa_offset);
- mem = gen_rtx_MEM (mode, addr);
- add_reg_note (insn, REG_CFA_DEF_CFA, mem);
- }
- else
- {
- /* The frame pointer is a stable reference within the
- aligned frame. Use it. */
- gcc_checking_assert (cfun->machine->fs.fp_valid);
- addr = plus_constant (Pmode, hard_frame_pointer_rtx,
- cfun->machine->fs.fp_offset - cfa_offset);
- mem = gen_rtx_MEM (mode, addr);
- add_reg_note (insn, REG_CFA_EXPRESSION,
- gen_rtx_SET (VOIDmode, mem, reg));
- }
- }
-
- /* The memory may not be relative to the current CFA register,
- which means that we may need to generate a new pattern for
- use by the unwind info. */
- else if (base != m->fs.cfa_reg)
- {
- addr = plus_constant (Pmode, m->fs.cfa_reg,
- m->fs.cfa_offset - cfa_offset);
- mem = gen_rtx_MEM (mode, addr);
- add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (VOIDmode, mem, reg));
- }
-}
-
-/* Emit code to save registers using MOV insns.
- First register is stored at CFA - CFA_OFFSET. */
-static void
-ix86_emit_save_regs_using_mov (HOST_WIDE_INT cfa_offset)
-{
- unsigned int regno;
-
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- if (!SSE_REGNO_P (regno) && ix86_save_reg (regno, true))
- {
- ix86_emit_save_reg_using_mov (word_mode, regno, cfa_offset);
- cfa_offset -= UNITS_PER_WORD;
- }
-}
-
-/* Emit code to save SSE registers using MOV insns.
- First register is stored at CFA - CFA_OFFSET. */
-static void
-ix86_emit_save_sse_regs_using_mov (HOST_WIDE_INT cfa_offset)
-{
- unsigned int regno;
-
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- if (SSE_REGNO_P (regno) && ix86_save_reg (regno, true))
- {
- ix86_emit_save_reg_using_mov (V4SFmode, regno, cfa_offset);
- cfa_offset -= 16;
- }
-}
-
-static GTY(()) rtx queued_cfa_restores;
-
-/* Add a REG_CFA_RESTORE REG note to INSN or queue them until next stack
- manipulation insn. The value is on the stack at CFA - CFA_OFFSET.
- Don't add the note if the previously saved value will be left untouched
- within stack red-zone till return, as unwinders can find the same value
- in the register and on the stack. */
-
-static void
-ix86_add_cfa_restore_note (rtx insn, rtx reg, HOST_WIDE_INT cfa_offset)
-{
- if (!crtl->shrink_wrapped
- && cfa_offset <= cfun->machine->fs.red_zone_offset)
- return;
-
- if (insn)
- {
- add_reg_note (insn, REG_CFA_RESTORE, reg);
- RTX_FRAME_RELATED_P (insn) = 1;
- }
- else
- queued_cfa_restores
- = alloc_reg_note (REG_CFA_RESTORE, reg, queued_cfa_restores);
-}
-
-/* Add queued REG_CFA_RESTORE notes if any to INSN. */
-
-static void
-ix86_add_queued_cfa_restore_notes (rtx insn)
-{
- rtx last;
- if (!queued_cfa_restores)
- return;
- for (last = queued_cfa_restores; XEXP (last, 1); last = XEXP (last, 1))
- ;
- XEXP (last, 1) = REG_NOTES (insn);
- REG_NOTES (insn) = queued_cfa_restores;
- queued_cfa_restores = NULL_RTX;
- RTX_FRAME_RELATED_P (insn) = 1;
-}
-
-/* Expand prologue or epilogue stack adjustment.
- The pattern exist to put a dependency on all ebp-based memory accesses.
- STYLE should be negative if instructions should be marked as frame related,
- zero if %r11 register is live and cannot be freely used and positive
- otherwise. */
-
-static void
-pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset,
- int style, bool set_cfa)
-{
- struct machine_function *m = cfun->machine;
- rtx insn;
- bool add_frame_related_expr = false;
-
- if (Pmode == SImode)
- insn = gen_pro_epilogue_adjust_stack_si_add (dest, src, offset);
- else if (x86_64_immediate_operand (offset, DImode))
- insn = gen_pro_epilogue_adjust_stack_di_add (dest, src, offset);
- else
- {
- rtx tmp;
- /* r11 is used by indirect sibcall return as well, set before the
- epilogue and used after the epilogue. */
- if (style)
- tmp = gen_rtx_REG (DImode, R11_REG);
- else
- {
- gcc_assert (src != hard_frame_pointer_rtx
- && dest != hard_frame_pointer_rtx);
- tmp = hard_frame_pointer_rtx;
- }
- insn = emit_insn (gen_rtx_SET (DImode, tmp, offset));
- if (style < 0)
- add_frame_related_expr = true;
-
- insn = gen_pro_epilogue_adjust_stack_di_add (dest, src, tmp);
- }
-
- insn = emit_insn (insn);
- if (style >= 0)
- ix86_add_queued_cfa_restore_notes (insn);
-
- if (set_cfa)
- {
- rtx r;
-
- gcc_assert (m->fs.cfa_reg == src);
- m->fs.cfa_offset += INTVAL (offset);
- m->fs.cfa_reg = dest;
-
- r = gen_rtx_PLUS (Pmode, src, offset);
- r = gen_rtx_SET (VOIDmode, dest, r);
- add_reg_note (insn, REG_CFA_ADJUST_CFA, r);
- RTX_FRAME_RELATED_P (insn) = 1;
- }
- else if (style < 0)
- {
- RTX_FRAME_RELATED_P (insn) = 1;
- if (add_frame_related_expr)
- {
- rtx r = gen_rtx_PLUS (Pmode, src, offset);
- r = gen_rtx_SET (VOIDmode, dest, r);
- add_reg_note (insn, REG_FRAME_RELATED_EXPR, r);
- }
- }
-
- if (dest == stack_pointer_rtx)
- {
- HOST_WIDE_INT ooffset = m->fs.sp_offset;
- bool valid = m->fs.sp_valid;
-
- if (src == hard_frame_pointer_rtx)
- {
- valid = m->fs.fp_valid;
- ooffset = m->fs.fp_offset;
- }
- else if (src == crtl->drap_reg)
- {
- valid = m->fs.drap_valid;
- ooffset = 0;
- }
- else
- {
- /* Else there are two possibilities: SP itself, which we set
- up as the default above. Or EH_RETURN_STACKADJ_RTX, which is
- taken care of this by hand along the eh_return path. */
- gcc_checking_assert (src == stack_pointer_rtx
- || offset == const0_rtx);
- }
-
- m->fs.sp_offset = ooffset - INTVAL (offset);
- m->fs.sp_valid = valid;
- }
-}
-
-/* Find an available register to be used as dynamic realign argument
- pointer regsiter. Such a register will be written in prologue and
- used in begin of body, so it must not be
- 1. parameter passing register.
- 2. GOT pointer.
- We reuse static-chain register if it is available. Otherwise, we
- use DI for i386 and R13 for x86-64. We chose R13 since it has
- shorter encoding.
-
- Return: the regno of chosen register. */
-
-static unsigned int
-find_drap_reg (void)
-{
- tree decl = cfun->decl;
-
- if (TARGET_64BIT)
- {
- /* Use R13 for nested function or function need static chain.
- Since function with tail call may use any caller-saved
- registers in epilogue, DRAP must not use caller-saved
- register in such case. */
- if (DECL_STATIC_CHAIN (decl) || crtl->tail_call_emit)
- return R13_REG;
-
- return R10_REG;
- }
- else
- {
- /* Use DI for nested function or function need static chain.
- Since function with tail call may use any caller-saved
- registers in epilogue, DRAP must not use caller-saved
- register in such case. */
- if (DECL_STATIC_CHAIN (decl) || crtl->tail_call_emit)
- return DI_REG;
-
- /* Reuse static chain register if it isn't used for parameter
- passing. */
- if (ix86_function_regparm (TREE_TYPE (decl), decl) <= 2)
- {
- unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (decl));
- if ((ccvt & (IX86_CALLCVT_FASTCALL | IX86_CALLCVT_THISCALL)) == 0)
- return CX_REG;
- }
- return DI_REG;
- }
-}
-
-/* Return minimum incoming stack alignment. */
-
-static unsigned int
-ix86_minimum_incoming_stack_boundary (bool sibcall)
-{
- unsigned int incoming_stack_boundary;
-
- /* Prefer the one specified at command line. */
- if (ix86_user_incoming_stack_boundary)
- incoming_stack_boundary = ix86_user_incoming_stack_boundary;
- /* In 32bit, use MIN_STACK_BOUNDARY for incoming stack boundary
- if -mstackrealign is used, it isn't used for sibcall check and
- estimated stack alignment is 128bit. */
- else if (!sibcall
- && !TARGET_64BIT
- && ix86_force_align_arg_pointer
- && crtl->stack_alignment_estimated == 128)
- incoming_stack_boundary = MIN_STACK_BOUNDARY;
- else
- incoming_stack_boundary = ix86_default_incoming_stack_boundary;
-
- /* Incoming stack alignment can be changed on individual functions
- via force_align_arg_pointer attribute. We use the smallest
- incoming stack boundary. */
- if (incoming_stack_boundary > MIN_STACK_BOUNDARY
- && lookup_attribute (ix86_force_align_arg_pointer_string,
- TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
- incoming_stack_boundary = MIN_STACK_BOUNDARY;
-
- /* The incoming stack frame has to be aligned at least at
- parm_stack_boundary. */
- if (incoming_stack_boundary < crtl->parm_stack_boundary)
- incoming_stack_boundary = crtl->parm_stack_boundary;
-
- /* Stack at entrance of main is aligned by runtime. We use the
- smallest incoming stack boundary. */
- if (incoming_stack_boundary > MAIN_STACK_BOUNDARY
- && DECL_NAME (current_function_decl)
- && MAIN_NAME_P (DECL_NAME (current_function_decl))
- && DECL_FILE_SCOPE_P (current_function_decl))
- incoming_stack_boundary = MAIN_STACK_BOUNDARY;
-
- return incoming_stack_boundary;
-}
-
-/* Update incoming stack boundary and estimated stack alignment. */
-
-static void
-ix86_update_stack_boundary (void)
-{
- ix86_incoming_stack_boundary
- = ix86_minimum_incoming_stack_boundary (false);
-
- /* x86_64 vararg needs 16byte stack alignment for register save
- area. */
- if (TARGET_64BIT
- && cfun->stdarg
- && crtl->stack_alignment_estimated < 128)
- crtl->stack_alignment_estimated = 128;
-}
-
-/* Handle the TARGET_GET_DRAP_RTX hook. Return NULL if no DRAP is
- needed or an rtx for DRAP otherwise. */
-
-static rtx
-ix86_get_drap_rtx (void)
-{
- if (ix86_force_drap || !ACCUMULATE_OUTGOING_ARGS)
- crtl->need_drap = true;
-
- if (stack_realign_drap)
- {
- /* Assign DRAP to vDRAP and returns vDRAP */
- unsigned int regno = find_drap_reg ();
- rtx drap_vreg;
- rtx arg_ptr;
- rtx seq, insn;
-
- arg_ptr = gen_rtx_REG (Pmode, regno);
- crtl->drap_reg = arg_ptr;
-
- start_sequence ();
- drap_vreg = copy_to_reg (arg_ptr);
- seq = get_insns ();
- end_sequence ();
-
- insn = emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
- if (!optimize)
- {
- add_reg_note (insn, REG_CFA_SET_VDRAP, drap_vreg);
- RTX_FRAME_RELATED_P (insn) = 1;
- }
- return drap_vreg;
- }
- else
- return NULL;
-}
-
-/* Handle the TARGET_INTERNAL_ARG_POINTER hook. */
-
-static rtx
-ix86_internal_arg_pointer (void)
-{
- return virtual_incoming_args_rtx;
-}
-
-struct scratch_reg {
- rtx reg;
- bool saved;
-};
-
-/* Return a short-lived scratch register for use on function entry.
- In 32-bit mode, it is valid only after the registers are saved
- in the prologue. This register must be released by means of
- release_scratch_register_on_entry once it is dead. */
-
-static void
-get_scratch_register_on_entry (struct scratch_reg *sr)
-{
- int regno;
-
- sr->saved = false;
-
- if (TARGET_64BIT)
- {
- /* We always use R11 in 64-bit mode. */
- regno = R11_REG;
- }
- else
- {
- tree decl = current_function_decl, fntype = TREE_TYPE (decl);
- bool fastcall_p
- = lookup_attribute ("fastcall", TYPE_ATTRIBUTES (fntype)) != NULL_TREE;
- bool thiscall_p
- = lookup_attribute ("thiscall", TYPE_ATTRIBUTES (fntype)) != NULL_TREE;
- bool static_chain_p = DECL_STATIC_CHAIN (decl);
- int regparm = ix86_function_regparm (fntype, decl);
- int drap_regno
- = crtl->drap_reg ? REGNO (crtl->drap_reg) : INVALID_REGNUM;
-
- /* 'fastcall' sets regparm to 2, uses ecx/edx for arguments and eax
- for the static chain register. */
- if ((regparm < 1 || (fastcall_p && !static_chain_p))
- && drap_regno != AX_REG)
- regno = AX_REG;
- /* 'thiscall' sets regparm to 1, uses ecx for arguments and edx
- for the static chain register. */
- else if (thiscall_p && !static_chain_p && drap_regno != AX_REG)
- regno = AX_REG;
- else if (regparm < 2 && !thiscall_p && drap_regno != DX_REG)
- regno = DX_REG;
- /* ecx is the static chain register. */
- else if (regparm < 3 && !fastcall_p && !thiscall_p
- && !static_chain_p
- && drap_regno != CX_REG)
- regno = CX_REG;
- else if (ix86_save_reg (BX_REG, true))
- regno = BX_REG;
- /* esi is the static chain register. */
- else if (!(regparm == 3 && static_chain_p)
- && ix86_save_reg (SI_REG, true))
- regno = SI_REG;
- else if (ix86_save_reg (DI_REG, true))
- regno = DI_REG;
- else
- {
- regno = (drap_regno == AX_REG ? DX_REG : AX_REG);
- sr->saved = true;
- }
- }
-
- sr->reg = gen_rtx_REG (Pmode, regno);
- if (sr->saved)
- {
- rtx insn = emit_insn (gen_push (sr->reg));
- RTX_FRAME_RELATED_P (insn) = 1;
- }
-}
-
-/* Release a scratch register obtained from the preceding function. */
-
-static void
-release_scratch_register_on_entry (struct scratch_reg *sr)
-{
- if (sr->saved)
- {
- struct machine_function *m = cfun->machine;
- rtx x, insn = emit_insn (gen_pop (sr->reg));
-
- /* The RTX_FRAME_RELATED_P mechanism doesn't know about pop. */
- RTX_FRAME_RELATED_P (insn) = 1;
- x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (UNITS_PER_WORD));
- x = gen_rtx_SET (VOIDmode, stack_pointer_rtx, x);
- add_reg_note (insn, REG_FRAME_RELATED_EXPR, x);
- m->fs.sp_offset -= UNITS_PER_WORD;
- }
-}
-
-#define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
-
-/* Emit code to adjust the stack pointer by SIZE bytes while probing it. */
-
-static void
-ix86_adjust_stack_and_probe (const HOST_WIDE_INT size)
-{
- /* We skip the probe for the first interval + a small dope of 4 words and
- probe that many bytes past the specified size to maintain a protection
- area at the botton of the stack. */
- const int dope = 4 * UNITS_PER_WORD;
- rtx size_rtx = GEN_INT (size), last;
-
- /* See if we have a constant small number of probes to generate. If so,
- that's the easy case. The run-time loop is made up of 11 insns in the
- generic case while the compile-time loop is made up of 3+2*(n-1) insns
- for n # of intervals. */
- if (size <= 5 * PROBE_INTERVAL)
- {
- HOST_WIDE_INT i, adjust;
- bool first_probe = true;
-
- /* Adjust SP and probe at PROBE_INTERVAL + N * PROBE_INTERVAL for
- values of N from 1 until it exceeds SIZE. If only one probe is
- needed, this will not generate any code. Then adjust and probe
- to PROBE_INTERVAL + SIZE. */
- for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
- {
- if (first_probe)
- {
- adjust = 2 * PROBE_INTERVAL + dope;
- first_probe = false;
- }
- else
- adjust = PROBE_INTERVAL;
-
- emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx,
- plus_constant (Pmode, stack_pointer_rtx,
- -adjust)));
- emit_stack_probe (stack_pointer_rtx);
- }
-
- if (first_probe)
- adjust = size + PROBE_INTERVAL + dope;
- else
- adjust = size + PROBE_INTERVAL - i;
-
- emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx,
- plus_constant (Pmode, stack_pointer_rtx,
- -adjust)));
- emit_stack_probe (stack_pointer_rtx);
-
- /* Adjust back to account for the additional first interval. */
- last = emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx,
- plus_constant (Pmode, stack_pointer_rtx,
- PROBE_INTERVAL + dope)));
- }
-
- /* Otherwise, do the same as above, but in a loop. Note that we must be
- extra careful with variables wrapping around because we might be at
- the very top (or the very bottom) of the address space and we have
- to be able to handle this case properly; in particular, we use an
- equality test for the loop condition. */
- else
- {
- HOST_WIDE_INT rounded_size;
- struct scratch_reg sr;
-
- get_scratch_register_on_entry (&sr);
-
-
- /* Step 1: round SIZE to the previous multiple of the interval. */
-
- rounded_size = size & -PROBE_INTERVAL;
-
-
- /* Step 2: compute initial and final value of the loop counter. */
-
- /* SP = SP_0 + PROBE_INTERVAL. */
- emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx,
- plus_constant (Pmode, stack_pointer_rtx,
- - (PROBE_INTERVAL + dope))));
-
- /* LAST_ADDR = SP_0 + PROBE_INTERVAL + ROUNDED_SIZE. */
- emit_move_insn (sr.reg, GEN_INT (-rounded_size));
- emit_insn (gen_rtx_SET (VOIDmode, sr.reg,
- gen_rtx_PLUS (Pmode, sr.reg,
- stack_pointer_rtx)));
-
-
- /* Step 3: the loop
-
- while (SP != LAST_ADDR)
- {
- SP = SP + PROBE_INTERVAL
- probe at SP
- }
-
- adjusts SP and probes to PROBE_INTERVAL + N * PROBE_INTERVAL for
- values of N from 1 until it is equal to ROUNDED_SIZE. */
-
- emit_insn (ix86_gen_adjust_stack_and_probe (sr.reg, sr.reg, size_rtx));
-
-
- /* Step 4: adjust SP and probe at PROBE_INTERVAL + SIZE if we cannot
- assert at compile-time that SIZE is equal to ROUNDED_SIZE. */
-
- if (size != rounded_size)
- {
- emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx,
- plus_constant (Pmode, stack_pointer_rtx,
- rounded_size - size)));
- emit_stack_probe (stack_pointer_rtx);
- }
-
- /* Adjust back to account for the additional first interval. */
- last = emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx,
- plus_constant (Pmode, stack_pointer_rtx,
- PROBE_INTERVAL + dope)));
-
- release_scratch_register_on_entry (&sr);
- }
-
- gcc_assert (cfun->machine->fs.cfa_reg != stack_pointer_rtx);
-
- /* Even if the stack pointer isn't the CFA register, we need to correctly
- describe the adjustments made to it, in particular differentiate the
- frame-related ones from the frame-unrelated ones. */
- if (size > 0)
- {
- rtx expr = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (2));
- XVECEXP (expr, 0, 0)
- = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
- plus_constant (Pmode, stack_pointer_rtx, -size));
- XVECEXP (expr, 0, 1)
- = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
- plus_constant (Pmode, stack_pointer_rtx,
- PROBE_INTERVAL + dope + size));
- add_reg_note (last, REG_FRAME_RELATED_EXPR, expr);
- RTX_FRAME_RELATED_P (last) = 1;
-
- cfun->machine->fs.sp_offset += size;
- }
-
- /* Make sure nothing is scheduled before we are done. */
- emit_insn (gen_blockage ());
-}
-
-/* Adjust the stack pointer up to REG while probing it. */
-
-const char *
-output_adjust_stack_and_probe (rtx reg)
-{
- static int labelno = 0;
- char loop_lab[32], end_lab[32];
- rtx xops[2];
-
- ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
- ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
-
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
-
- /* Jump to END_LAB if SP == LAST_ADDR. */
- xops[0] = stack_pointer_rtx;
- xops[1] = reg;
- output_asm_insn ("cmp%z0\t{%1, %0|%0, %1}", xops);
- fputs ("\tje\t", asm_out_file);
- assemble_name_raw (asm_out_file, end_lab);
- fputc ('\n', asm_out_file);
-
- /* SP = SP + PROBE_INTERVAL. */
- xops[1] = GEN_INT (PROBE_INTERVAL);
- output_asm_insn ("sub%z0\t{%1, %0|%0, %1}", xops);
-
- /* Probe at SP. */
- xops[1] = const0_rtx;
- output_asm_insn ("or%z0\t{%1, (%0)|DWORD PTR [%0], %1}", xops);
-
- fprintf (asm_out_file, "\tjmp\t");
- assemble_name_raw (asm_out_file, loop_lab);
- fputc ('\n', asm_out_file);
-
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
-
- return "";
-}
-
-/* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
- inclusive. These are offsets from the current stack pointer. */
-
-static void
-ix86_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
-{
- /* See if we have a constant small number of probes to generate. If so,
- that's the easy case. The run-time loop is made up of 7 insns in the
- generic case while the compile-time loop is made up of n insns for n #
- of intervals. */
- if (size <= 7 * PROBE_INTERVAL)
- {
- HOST_WIDE_INT i;
-
- /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
- it exceeds SIZE. If only one probe is needed, this will not
- generate any code. Then probe at FIRST + SIZE. */
- for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
- emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
- -(first + i)));
-
- emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
- -(first + size)));
- }
-
- /* Otherwise, do the same as above, but in a loop. Note that we must be
- extra careful with variables wrapping around because we might be at
- the very top (or the very bottom) of the address space and we have
- to be able to handle this case properly; in particular, we use an
- equality test for the loop condition. */
- else
- {
- HOST_WIDE_INT rounded_size, last;
- struct scratch_reg sr;
-
- get_scratch_register_on_entry (&sr);
-
-
- /* Step 1: round SIZE to the previous multiple of the interval. */
-
- rounded_size = size & -PROBE_INTERVAL;
-
-
- /* Step 2: compute initial and final value of the loop counter. */
-
- /* TEST_OFFSET = FIRST. */
- emit_move_insn (sr.reg, GEN_INT (-first));
-
- /* LAST_OFFSET = FIRST + ROUNDED_SIZE. */
- last = first + rounded_size;
-
-
- /* Step 3: the loop
-
- while (TEST_ADDR != LAST_ADDR)
- {
- TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
- probe at TEST_ADDR
- }
-
- probes at FIRST + N * PROBE_INTERVAL for values of N from 1
- until it is equal to ROUNDED_SIZE. */
-
- emit_insn (ix86_gen_probe_stack_range (sr.reg, sr.reg, GEN_INT (-last)));
-
-
- /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
- that SIZE is equal to ROUNDED_SIZE. */
-
- if (size != rounded_size)
- emit_stack_probe (plus_constant (Pmode,
- gen_rtx_PLUS (Pmode,
- stack_pointer_rtx,
- sr.reg),
- rounded_size - size));
-
- release_scratch_register_on_entry (&sr);
- }
-
- /* Make sure nothing is scheduled before we are done. */
- emit_insn (gen_blockage ());
-}
-
-/* Probe a range of stack addresses from REG to END, inclusive. These are
- offsets from the current stack pointer. */
-
-const char *
-output_probe_stack_range (rtx reg, rtx end)
-{
- static int labelno = 0;
- char loop_lab[32], end_lab[32];
- rtx xops[3];
-
- ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
- ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
-
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
-
- /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
- xops[0] = reg;
- xops[1] = end;
- output_asm_insn ("cmp%z0\t{%1, %0|%0, %1}", xops);
- fputs ("\tje\t", asm_out_file);
- assemble_name_raw (asm_out_file, end_lab);
- fputc ('\n', asm_out_file);
-
- /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
- xops[1] = GEN_INT (PROBE_INTERVAL);
- output_asm_insn ("sub%z0\t{%1, %0|%0, %1}", xops);
-
- /* Probe at TEST_ADDR. */
- xops[0] = stack_pointer_rtx;
- xops[1] = reg;
- xops[2] = const0_rtx;
- output_asm_insn ("or%z0\t{%2, (%0,%1)|DWORD PTR [%0+%1], %2}", xops);
-
- fprintf (asm_out_file, "\tjmp\t");
- assemble_name_raw (asm_out_file, loop_lab);
- fputc ('\n', asm_out_file);
-
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
-
- return "";
-}
-
-/* Finalize stack_realign_needed flag, which will guide prologue/epilogue
- to be generated in correct form. */
-static void
-ix86_finalize_stack_realign_flags (void)
-{
- /* Check if stack realign is really needed after reload, and
- stores result in cfun */
- unsigned int incoming_stack_boundary
- = (crtl->parm_stack_boundary > ix86_incoming_stack_boundary
- ? crtl->parm_stack_boundary : ix86_incoming_stack_boundary);
- unsigned int stack_realign = (incoming_stack_boundary
- < (crtl->is_leaf
- ? crtl->max_used_stack_slot_alignment
- : crtl->stack_alignment_needed));
-
- if (crtl->stack_realign_finalized)
- {
- /* After stack_realign_needed is finalized, we can't no longer
- change it. */
- gcc_assert (crtl->stack_realign_needed == stack_realign);
- return;
- }
-
- /* If the only reason for frame_pointer_needed is that we conservatively
- assumed stack realignment might be needed, but in the end nothing that
- needed the stack alignment had been spilled, clear frame_pointer_needed
- and say we don't need stack realignment. */
- if (stack_realign
- && !crtl->need_drap
- && frame_pointer_needed
- && crtl->is_leaf
- && flag_omit_frame_pointer
- && crtl->sp_is_unchanging
- && !ix86_current_function_calls_tls_descriptor
- && !crtl->accesses_prior_frames
- && !cfun->calls_alloca
- && !crtl->calls_eh_return
- && !(flag_stack_check && STACK_CHECK_MOVING_SP)
- && !ix86_frame_pointer_required ()
- && get_frame_size () == 0
- && ix86_nsaved_sseregs () == 0
- && ix86_varargs_gpr_size + ix86_varargs_fpr_size == 0)
- {
- HARD_REG_SET set_up_by_prologue, prologue_used;
- basic_block bb;
-
- CLEAR_HARD_REG_SET (prologue_used);
- CLEAR_HARD_REG_SET (set_up_by_prologue);
- add_to_hard_reg_set (&set_up_by_prologue, Pmode, STACK_POINTER_REGNUM);
- add_to_hard_reg_set (&set_up_by_prologue, Pmode, ARG_POINTER_REGNUM);
- add_to_hard_reg_set (&set_up_by_prologue, Pmode,
- HARD_FRAME_POINTER_REGNUM);
- FOR_EACH_BB (bb)
- {
- rtx insn;
- FOR_BB_INSNS (bb, insn)
- if (NONDEBUG_INSN_P (insn)
- && requires_stack_frame_p (insn, prologue_used,
- set_up_by_prologue))
- {
- crtl->stack_realign_needed = stack_realign;
- crtl->stack_realign_finalized = true;
- return;
- }
- }
-
- frame_pointer_needed = false;
- stack_realign = false;
- crtl->max_used_stack_slot_alignment = incoming_stack_boundary;
- crtl->stack_alignment_needed = incoming_stack_boundary;
- crtl->stack_alignment_estimated = incoming_stack_boundary;
- if (crtl->preferred_stack_boundary > incoming_stack_boundary)
- crtl->preferred_stack_boundary = incoming_stack_boundary;
- df_finish_pass (true);
- df_scan_alloc (NULL);
- df_scan_blocks ();
- df_compute_regs_ever_live (true);
- df_analyze ();
- }
-
- crtl->stack_realign_needed = stack_realign;
- crtl->stack_realign_finalized = true;
-}
-
-/* Expand the prologue into a bunch of separate insns. */
-
-void
-ix86_expand_prologue (void)
-{
- struct machine_function *m = cfun->machine;
- rtx insn, t;
- bool pic_reg_used;
- struct ix86_frame frame;
- HOST_WIDE_INT allocate;
- bool int_registers_saved;
- bool sse_registers_saved;
-
- ix86_finalize_stack_realign_flags ();
-
- /* DRAP should not coexist with stack_realign_fp */
- gcc_assert (!(crtl->drap_reg && stack_realign_fp));
-
- memset (&m->fs, 0, sizeof (m->fs));
-
- /* Initialize CFA state for before the prologue. */
- m->fs.cfa_reg = stack_pointer_rtx;
- m->fs.cfa_offset = INCOMING_FRAME_SP_OFFSET;
-
- /* Track SP offset to the CFA. We continue tracking this after we've
- swapped the CFA register away from SP. In the case of re-alignment
- this is fudged; we're interested to offsets within the local frame. */
- m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET;
- m->fs.sp_valid = true;
-
- ix86_compute_frame_layout (&frame);
-
- if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl))
- {
- /* We should have already generated an error for any use of
- ms_hook on a nested function. */
- gcc_checking_assert (!ix86_static_chain_on_stack);
-
- /* Check if profiling is active and we shall use profiling before
- prologue variant. If so sorry. */
- if (crtl->profile && flag_fentry != 0)
- sorry ("ms_hook_prologue attribute isn%'t compatible "
- "with -mfentry for 32-bit");
-
- /* In ix86_asm_output_function_label we emitted:
- 8b ff movl.s %edi,%edi
- 55 push %ebp
- 8b ec movl.s %esp,%ebp
-
- This matches the hookable function prologue in Win32 API
- functions in Microsoft Windows XP Service Pack 2 and newer.
- Wine uses this to enable Windows apps to hook the Win32 API
- functions provided by Wine.
-
- What that means is that we've already set up the frame pointer. */
-
- if (frame_pointer_needed
- && !(crtl->drap_reg && crtl->stack_realign_needed))
- {
- rtx push, mov;
-
- /* We've decided to use the frame pointer already set up.
- Describe this to the unwinder by pretending that both
- push and mov insns happen right here.
-
- Putting the unwind info here at the end of the ms_hook
- is done so that we can make absolutely certain we get
- the required byte sequence at the start of the function,
- rather than relying on an assembler that can produce
- the exact encoding required.
-
- However it does mean (in the unpatched case) that we have
- a 1 insn window where the asynchronous unwind info is
- incorrect. However, if we placed the unwind info at
- its correct location we would have incorrect unwind info
- in the patched case. Which is probably all moot since
- I don't expect Wine generates dwarf2 unwind info for the
- system libraries that use this feature. */
-
- insn = emit_insn (gen_blockage ());
-
- push = gen_push (hard_frame_pointer_rtx);
- mov = gen_rtx_SET (VOIDmode, hard_frame_pointer_rtx,
- stack_pointer_rtx);
- RTX_FRAME_RELATED_P (push) = 1;
- RTX_FRAME_RELATED_P (mov) = 1;
-
- RTX_FRAME_RELATED_P (insn) = 1;
- add_reg_note (insn, REG_FRAME_RELATED_EXPR,
- gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, push, mov)));
-
- /* Note that gen_push incremented m->fs.cfa_offset, even
- though we didn't emit the push insn here. */
- m->fs.cfa_reg = hard_frame_pointer_rtx;
- m->fs.fp_offset = m->fs.cfa_offset;
- m->fs.fp_valid = true;
- }
- else
- {
- /* The frame pointer is not needed so pop %ebp again.
- This leaves us with a pristine state. */
- emit_insn (gen_pop (hard_frame_pointer_rtx));
- }
- }
-
- /* The first insn of a function that accepts its static chain on the
- stack is to push the register that would be filled in by a direct
- call. This insn will be skipped by the trampoline. */
- else if (ix86_static_chain_on_stack)
- {
- insn = emit_insn (gen_push (ix86_static_chain (cfun->decl, false)));
- emit_insn (gen_blockage ());
-
- /* We don't want to interpret this push insn as a register save,
- only as a stack adjustment. The real copy of the register as
- a save will be done later, if needed. */
- t = plus_constant (Pmode, stack_pointer_rtx, -UNITS_PER_WORD);
- t = gen_rtx_SET (VOIDmode, stack_pointer_rtx, t);
- add_reg_note (insn, REG_CFA_ADJUST_CFA, t);
- RTX_FRAME_RELATED_P (insn) = 1;
- }
-
- /* Emit prologue code to adjust stack alignment and setup DRAP, in case
- of DRAP is needed and stack realignment is really needed after reload */
- if (stack_realign_drap)
- {
- int align_bytes = crtl->stack_alignment_needed / BITS_PER_UNIT;
-
- /* Only need to push parameter pointer reg if it is caller saved. */
- if (!call_used_regs[REGNO (crtl->drap_reg)])
- {
- /* Push arg pointer reg */
- insn = emit_insn (gen_push (crtl->drap_reg));
- RTX_FRAME_RELATED_P (insn) = 1;
- }
-
- /* Grab the argument pointer. */
- t = plus_constant (Pmode, stack_pointer_rtx, m->fs.sp_offset);
- insn = emit_insn (gen_rtx_SET (VOIDmode, crtl->drap_reg, t));
- RTX_FRAME_RELATED_P (insn) = 1;
- m->fs.cfa_reg = crtl->drap_reg;
- m->fs.cfa_offset = 0;
-
- /* Align the stack. */
- insn = emit_insn (ix86_gen_andsp (stack_pointer_rtx,
- stack_pointer_rtx,
- GEN_INT (-align_bytes)));
- RTX_FRAME_RELATED_P (insn) = 1;
-
- /* Replicate the return address on the stack so that return
- address can be reached via (argp - 1) slot. This is needed
- to implement macro RETURN_ADDR_RTX and intrinsic function
- expand_builtin_return_addr etc. */
- t = plus_constant (Pmode, crtl->drap_reg, -UNITS_PER_WORD);
- t = gen_frame_mem (word_mode, t);
- insn = emit_insn (gen_push (t));
- RTX_FRAME_RELATED_P (insn) = 1;
-
- /* For the purposes of frame and register save area addressing,
- we've started over with a new frame. */
- m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET;
- m->fs.realigned = true;
- }
-
- int_registers_saved = (frame.nregs == 0);
- sse_registers_saved = (frame.nsseregs == 0);
-
- if (frame_pointer_needed && !m->fs.fp_valid)
- {
- /* Note: AT&T enter does NOT have reversed args. Enter is probably
- slower on all targets. Also sdb doesn't like it. */
- insn = emit_insn (gen_push (hard_frame_pointer_rtx));
- RTX_FRAME_RELATED_P (insn) = 1;
-
- /* Push registers now, before setting the frame pointer
- on SEH target. */
- if (!int_registers_saved
- && TARGET_SEH
- && !frame.save_regs_using_mov)
- {
- ix86_emit_save_regs ();
- int_registers_saved = true;
- gcc_assert (m->fs.sp_offset == frame.reg_save_offset);
- }
-
- if (m->fs.sp_offset == frame.hard_frame_pointer_offset)
- {
- insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
- RTX_FRAME_RELATED_P (insn) = 1;
-
- if (m->fs.cfa_reg == stack_pointer_rtx)
- m->fs.cfa_reg = hard_frame_pointer_rtx;
- m->fs.fp_offset = m->fs.sp_offset;
- m->fs.fp_valid = true;
- }
- }
-
- if (!int_registers_saved)
- {
- /* If saving registers via PUSH, do so now. */
- if (!frame.save_regs_using_mov)
- {
- ix86_emit_save_regs ();
- int_registers_saved = true;
- gcc_assert (m->fs.sp_offset == frame.reg_save_offset);
- }
-
- /* When using red zone we may start register saving before allocating
- the stack frame saving one cycle of the prologue. However, avoid
- doing this if we have to probe the stack; at least on x86_64 the
- stack probe can turn into a call that clobbers a red zone location. */
- else if (ix86_using_red_zone ()
- && (! TARGET_STACK_PROBE
- || frame.stack_pointer_offset < CHECK_STACK_LIMIT))
- {
- ix86_emit_save_regs_using_mov (frame.reg_save_offset);
- int_registers_saved = true;
- }
- }
-
- if (stack_realign_fp)
- {
- int align_bytes = crtl->stack_alignment_needed / BITS_PER_UNIT;
- gcc_assert (align_bytes > MIN_STACK_BOUNDARY / BITS_PER_UNIT);
-
- /* The computation of the size of the re-aligned stack frame means
- that we must allocate the size of the register save area before
- performing the actual alignment. Otherwise we cannot guarantee
- that there's enough storage above the realignment point. */
- if (m->fs.sp_offset != frame.sse_reg_save_offset)
- pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (m->fs.sp_offset
- - frame.sse_reg_save_offset),
- -1, false);
-
- /* Align the stack. */
- insn = emit_insn (ix86_gen_andsp (stack_pointer_rtx,
- stack_pointer_rtx,
- GEN_INT (-align_bytes)));
-
- /* For the purposes of register save area addressing, the stack
- pointer is no longer valid. As for the value of sp_offset,
- see ix86_compute_frame_layout, which we need to match in order
- to pass verification of stack_pointer_offset at the end. */
- m->fs.sp_offset = (m->fs.sp_offset + align_bytes) & -align_bytes;
- m->fs.sp_valid = false;
- }
-
- allocate = frame.stack_pointer_offset - m->fs.sp_offset;
-
- if (flag_stack_usage_info)
- {
- /* We start to count from ARG_POINTER. */
- HOST_WIDE_INT stack_size = frame.stack_pointer_offset;
-
- /* If it was realigned, take into account the fake frame. */
- if (stack_realign_drap)
- {
- if (ix86_static_chain_on_stack)
- stack_size += UNITS_PER_WORD;
-
- if (!call_used_regs[REGNO (crtl->drap_reg)])
- stack_size += UNITS_PER_WORD;
-
- /* This over-estimates by 1 minimal-stack-alignment-unit but
- mitigates that by counting in the new return address slot. */
- current_function_dynamic_stack_size
- += crtl->stack_alignment_needed / BITS_PER_UNIT;
- }
-
- current_function_static_stack_size = stack_size;
- }
-
- /* On SEH target with very large frame size, allocate an area to save
- SSE registers (as the very large allocation won't be described). */
- if (TARGET_SEH
- && frame.stack_pointer_offset > SEH_MAX_FRAME_SIZE
- && !sse_registers_saved)
- {
- HOST_WIDE_INT sse_size =
- frame.sse_reg_save_offset - frame.reg_save_offset;
-
- gcc_assert (int_registers_saved);
-
- /* No need to do stack checking as the area will be immediately
- written. */
- pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (-sse_size), -1,
- m->fs.cfa_reg == stack_pointer_rtx);
- allocate -= sse_size;
- ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
- sse_registers_saved = true;
- }
-
- /* The stack has already been decremented by the instruction calling us
- so probe if the size is non-negative to preserve the protection area. */
- if (allocate >= 0 && flag_stack_check == STATIC_BUILTIN_STACK_CHECK)
- {
- /* We expect the registers to be saved when probes are used. */
- gcc_assert (int_registers_saved);
-
- if (STACK_CHECK_MOVING_SP)
- {
- ix86_adjust_stack_and_probe (allocate);
- allocate = 0;
- }
- else
- {
- HOST_WIDE_INT size = allocate;
-
- if (TARGET_64BIT && size >= (HOST_WIDE_INT) 0x80000000)
- size = 0x80000000 - STACK_CHECK_PROTECT - 1;
-
- if (TARGET_STACK_PROBE)
- ix86_emit_probe_stack_range (0, size + STACK_CHECK_PROTECT);
- else
- ix86_emit_probe_stack_range (STACK_CHECK_PROTECT, size);
- }
- }
-
- if (allocate == 0)
- ;
- else if (!ix86_target_stack_probe ()
- || frame.stack_pointer_offset < CHECK_STACK_LIMIT)
- {
- pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (-allocate), -1,
- m->fs.cfa_reg == stack_pointer_rtx);
- }
- else
- {
- rtx eax = gen_rtx_REG (Pmode, AX_REG);
- rtx r10 = NULL;
- rtx (*adjust_stack_insn)(rtx, rtx, rtx);
- const bool sp_is_cfa_reg = (m->fs.cfa_reg == stack_pointer_rtx);
- bool eax_live = false;
- bool r10_live = false;
-
- if (TARGET_64BIT)
- r10_live = (DECL_STATIC_CHAIN (current_function_decl) != 0);
- if (!TARGET_64BIT_MS_ABI)
- eax_live = ix86_eax_live_at_start_p ();
-
- /* Note that SEH directives need to continue tracking the stack
- pointer even after the frame pointer has been set up. */
- if (eax_live)
- {
- insn = emit_insn (gen_push (eax));
- allocate -= UNITS_PER_WORD;
- if (sp_is_cfa_reg || TARGET_SEH)
- {
- if (sp_is_cfa_reg)
- m->fs.cfa_offset += UNITS_PER_WORD;
- RTX_FRAME_RELATED_P (insn) = 1;
- }
- }
-
- if (r10_live)
- {
- r10 = gen_rtx_REG (Pmode, R10_REG);
- insn = emit_insn (gen_push (r10));
- allocate -= UNITS_PER_WORD;
- if (sp_is_cfa_reg || TARGET_SEH)
- {
- if (sp_is_cfa_reg)
- m->fs.cfa_offset += UNITS_PER_WORD;
- RTX_FRAME_RELATED_P (insn) = 1;
- }
- }
-
- emit_move_insn (eax, GEN_INT (allocate));
- emit_insn (ix86_gen_allocate_stack_worker (eax, eax));
-
- /* Use the fact that AX still contains ALLOCATE. */
- adjust_stack_insn = (Pmode == DImode
- ? gen_pro_epilogue_adjust_stack_di_sub
- : gen_pro_epilogue_adjust_stack_si_sub);
-
- insn = emit_insn (adjust_stack_insn (stack_pointer_rtx,
- stack_pointer_rtx, eax));
-
- if (sp_is_cfa_reg || TARGET_SEH)
- {
- if (sp_is_cfa_reg)
- m->fs.cfa_offset += allocate;
- RTX_FRAME_RELATED_P (insn) = 1;
- add_reg_note (insn, REG_FRAME_RELATED_EXPR,
- gen_rtx_SET (VOIDmode, stack_pointer_rtx,
- plus_constant (Pmode, stack_pointer_rtx,
- -allocate)));
- }
- m->fs.sp_offset += allocate;
-
- if (r10_live && eax_live)
- {
- t = choose_baseaddr (m->fs.sp_offset - allocate);
- emit_move_insn (gen_rtx_REG (word_mode, R10_REG),
- gen_frame_mem (word_mode, t));
- t = choose_baseaddr (m->fs.sp_offset - allocate - UNITS_PER_WORD);
- emit_move_insn (gen_rtx_REG (word_mode, AX_REG),
- gen_frame_mem (word_mode, t));
- }
- else if (eax_live || r10_live)
- {
- t = choose_baseaddr (m->fs.sp_offset - allocate);
- emit_move_insn (gen_rtx_REG (word_mode,
- (eax_live ? AX_REG : R10_REG)),
- gen_frame_mem (word_mode, t));
- }
- }
- gcc_assert (m->fs.sp_offset == frame.stack_pointer_offset);
-
- /* If we havn't already set up the frame pointer, do so now. */
- if (frame_pointer_needed && !m->fs.fp_valid)
- {
- insn = ix86_gen_add3 (hard_frame_pointer_rtx, stack_pointer_rtx,
- GEN_INT (frame.stack_pointer_offset
- - frame.hard_frame_pointer_offset));
- insn = emit_insn (insn);
- RTX_FRAME_RELATED_P (insn) = 1;
- add_reg_note (insn, REG_CFA_ADJUST_CFA, NULL);
-
- if (m->fs.cfa_reg == stack_pointer_rtx)
- m->fs.cfa_reg = hard_frame_pointer_rtx;
- m->fs.fp_offset = frame.hard_frame_pointer_offset;
- m->fs.fp_valid = true;
- }
-
- if (!int_registers_saved)
- ix86_emit_save_regs_using_mov (frame.reg_save_offset);
- if (!sse_registers_saved)
- ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
-
- pic_reg_used = false;
- if (pic_offset_table_rtx
- && (df_regs_ever_live_p (REAL_PIC_OFFSET_TABLE_REGNUM)
- || crtl->profile))
- {
- unsigned int alt_pic_reg_used = ix86_select_alt_pic_regnum ();
-
- if (alt_pic_reg_used != INVALID_REGNUM)
- SET_REGNO (pic_offset_table_rtx, alt_pic_reg_used);
-
- pic_reg_used = true;
- }
-
- if (pic_reg_used)
- {
- if (TARGET_64BIT)
- {
- if (ix86_cmodel == CM_LARGE_PIC)
- {
- rtx label, tmp_reg;
-
- gcc_assert (Pmode == DImode);
- label = gen_label_rtx ();
- emit_label (label);
- LABEL_PRESERVE_P (label) = 1;
- tmp_reg = gen_rtx_REG (Pmode, R11_REG);
- gcc_assert (REGNO (pic_offset_table_rtx) != REGNO (tmp_reg));
- insn = emit_insn (gen_set_rip_rex64 (pic_offset_table_rtx,
- label));
- insn = emit_insn (gen_set_got_offset_rex64 (tmp_reg, label));
- insn = emit_insn (ix86_gen_add3 (pic_offset_table_rtx,
- pic_offset_table_rtx, tmp_reg));
- }
- else
- insn = emit_insn (gen_set_got_rex64 (pic_offset_table_rtx));
- }
- else
- {
- insn = emit_insn (gen_set_got (pic_offset_table_rtx));
- RTX_FRAME_RELATED_P (insn) = 1;
- add_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL_RTX);
- }
- }
-
- /* In the pic_reg_used case, make sure that the got load isn't deleted
- when mcount needs it. Blockage to avoid call movement across mcount
- call is emitted in generic code after the NOTE_INSN_PROLOGUE_END
- note. */
- if (crtl->profile && !flag_fentry && pic_reg_used)
- emit_insn (gen_prologue_use (pic_offset_table_rtx));
-
- if (crtl->drap_reg && !crtl->stack_realign_needed)
- {
- /* vDRAP is setup but after reload it turns out stack realign
- isn't necessary, here we will emit prologue to setup DRAP
- without stack realign adjustment */
- t = choose_baseaddr (0);
- emit_insn (gen_rtx_SET (VOIDmode, crtl->drap_reg, t));
- }
-
- /* Prevent instructions from being scheduled into register save push
- sequence when access to the redzone area is done through frame pointer.
- The offset between the frame pointer and the stack pointer is calculated
- relative to the value of the stack pointer at the end of the function
- prologue, and moving instructions that access redzone area via frame
- pointer inside push sequence violates this assumption. */
- if (frame_pointer_needed && frame.red_zone_size)
- emit_insn (gen_memory_blockage ());
-
- /* Emit cld instruction if stringops are used in the function. */
- if (TARGET_CLD && ix86_current_function_needs_cld)
- emit_insn (gen_cld ());
-
- /* SEH requires that the prologue end within 256 bytes of the start of
- the function. Prevent instruction schedules that would extend that.
- Further, prevent alloca modifications to the stack pointer from being
- combined with prologue modifications. */
- if (TARGET_SEH)
- emit_insn (gen_prologue_use (stack_pointer_rtx));
-}
-
-/* Emit code to restore REG using a POP insn. */
-
-static void
-ix86_emit_restore_reg_using_pop (rtx reg)
-{
- struct machine_function *m = cfun->machine;
- rtx insn = emit_insn (gen_pop (reg));
-
- ix86_add_cfa_restore_note (insn, reg, m->fs.sp_offset);
- m->fs.sp_offset -= UNITS_PER_WORD;
-
- if (m->fs.cfa_reg == crtl->drap_reg
- && REGNO (reg) == REGNO (crtl->drap_reg))
- {
- /* Previously we'd represented the CFA as an expression
- like *(%ebp - 8). We've just popped that value from
- the stack, which means we need to reset the CFA to
- the drap register. This will remain until we restore
- the stack pointer. */
- add_reg_note (insn, REG_CFA_DEF_CFA, reg);
- RTX_FRAME_RELATED_P (insn) = 1;
-
- /* This means that the DRAP register is valid for addressing too. */
- m->fs.drap_valid = true;
- return;
- }
-
- if (m->fs.cfa_reg == stack_pointer_rtx)
- {
- rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
- x = gen_rtx_SET (VOIDmode, stack_pointer_rtx, x);
- add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
- RTX_FRAME_RELATED_P (insn) = 1;
-
- m->fs.cfa_offset -= UNITS_PER_WORD;
- }
-
- /* When the frame pointer is the CFA, and we pop it, we are
- swapping back to the stack pointer as the CFA. This happens
- for stack frames that don't allocate other data, so we assume
- the stack pointer is now pointing at the return address, i.e.
- the function entry state, which makes the offset be 1 word. */
- if (reg == hard_frame_pointer_rtx)
- {
- m->fs.fp_valid = false;
- if (m->fs.cfa_reg == hard_frame_pointer_rtx)
- {
- m->fs.cfa_reg = stack_pointer_rtx;
- m->fs.cfa_offset -= UNITS_PER_WORD;
-
- add_reg_note (insn, REG_CFA_DEF_CFA,
- gen_rtx_PLUS (Pmode, stack_pointer_rtx,
- GEN_INT (m->fs.cfa_offset)));
- RTX_FRAME_RELATED_P (insn) = 1;
- }
- }
-}
-
-/* Emit code to restore saved registers using POP insns. */
-
-static void
-ix86_emit_restore_regs_using_pop (void)
-{
- unsigned int regno;
-
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- if (!SSE_REGNO_P (regno) && ix86_save_reg (regno, false))
- ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno));
-}
-
-/* Emit code and notes for the LEAVE instruction. */
-
-static void
-ix86_emit_leave (void)
-{
- struct machine_function *m = cfun->machine;
- rtx insn = emit_insn (ix86_gen_leave ());
-
- ix86_add_queued_cfa_restore_notes (insn);
-
- gcc_assert (m->fs.fp_valid);
- m->fs.sp_valid = true;
- m->fs.sp_offset = m->fs.fp_offset - UNITS_PER_WORD;
- m->fs.fp_valid = false;
-
- if (m->fs.cfa_reg == hard_frame_pointer_rtx)
- {
- m->fs.cfa_reg = stack_pointer_rtx;
- m->fs.cfa_offset = m->fs.sp_offset;
-
- add_reg_note (insn, REG_CFA_DEF_CFA,
- plus_constant (Pmode, stack_pointer_rtx,
- m->fs.sp_offset));
- RTX_FRAME_RELATED_P (insn) = 1;
- }
- ix86_add_cfa_restore_note (insn, hard_frame_pointer_rtx,
- m->fs.fp_offset);
-}
-
-/* Emit code to restore saved registers using MOV insns.
- First register is restored from CFA - CFA_OFFSET. */
-static void
-ix86_emit_restore_regs_using_mov (HOST_WIDE_INT cfa_offset,
- bool maybe_eh_return)
-{
- struct machine_function *m = cfun->machine;
- unsigned int regno;
-
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- if (!SSE_REGNO_P (regno) && ix86_save_reg (regno, maybe_eh_return))
- {
- rtx reg = gen_rtx_REG (word_mode, regno);
- rtx insn, mem;
-
- mem = choose_baseaddr (cfa_offset);
- mem = gen_frame_mem (word_mode, mem);
- insn = emit_move_insn (reg, mem);
-
- if (m->fs.cfa_reg == crtl->drap_reg && regno == REGNO (crtl->drap_reg))
- {
- /* Previously we'd represented the CFA as an expression
- like *(%ebp - 8). We've just popped that value from
- the stack, which means we need to reset the CFA to
- the drap register. This will remain until we restore
- the stack pointer. */
- add_reg_note (insn, REG_CFA_DEF_CFA, reg);
- RTX_FRAME_RELATED_P (insn) = 1;
-
- /* This means that the DRAP register is valid for addressing. */
- m->fs.drap_valid = true;
- }
- else
- ix86_add_cfa_restore_note (NULL_RTX, reg, cfa_offset);
-
- cfa_offset -= UNITS_PER_WORD;
- }
-}
-
-/* Emit code to restore saved registers using MOV insns.
- First register is restored from CFA - CFA_OFFSET. */
-static void
-ix86_emit_restore_sse_regs_using_mov (HOST_WIDE_INT cfa_offset,
- bool maybe_eh_return)
-{
- unsigned int regno;
-
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- if (SSE_REGNO_P (regno) && ix86_save_reg (regno, maybe_eh_return))
- {
- rtx reg = gen_rtx_REG (V4SFmode, regno);
- rtx mem;
-
- mem = choose_baseaddr (cfa_offset);
- mem = gen_rtx_MEM (V4SFmode, mem);
- set_mem_align (mem, 128);
- emit_move_insn (reg, mem);
-
- ix86_add_cfa_restore_note (NULL_RTX, reg, cfa_offset);
-
- cfa_offset -= 16;
- }
-}
-
-/* Restore function stack, frame, and registers. */
-
-void
-ix86_expand_epilogue (int style)
-{
- struct machine_function *m = cfun->machine;
- struct machine_frame_state frame_state_save = m->fs;
- struct ix86_frame frame;
- bool restore_regs_via_mov;
- bool using_drap;
-
- ix86_finalize_stack_realign_flags ();
- ix86_compute_frame_layout (&frame);
-
- m->fs.sp_valid = (!frame_pointer_needed
- || (crtl->sp_is_unchanging
- && !stack_realign_fp));
- gcc_assert (!m->fs.sp_valid
- || m->fs.sp_offset == frame.stack_pointer_offset);
-
- /* The FP must be valid if the frame pointer is present. */
- gcc_assert (frame_pointer_needed == m->fs.fp_valid);
- gcc_assert (!m->fs.fp_valid
- || m->fs.fp_offset == frame.hard_frame_pointer_offset);
-
- /* We must have *some* valid pointer to the stack frame. */
- gcc_assert (m->fs.sp_valid || m->fs.fp_valid);
-
- /* The DRAP is never valid at this point. */
- gcc_assert (!m->fs.drap_valid);
-
- /* See the comment about red zone and frame
- pointer usage in ix86_expand_prologue. */
- if (frame_pointer_needed && frame.red_zone_size)
- emit_insn (gen_memory_blockage ());
-
- using_drap = crtl->drap_reg && crtl->stack_realign_needed;
- gcc_assert (!using_drap || m->fs.cfa_reg == crtl->drap_reg);
-
- /* Determine the CFA offset of the end of the red-zone. */
- m->fs.red_zone_offset = 0;
- if (ix86_using_red_zone () && crtl->args.pops_args < 65536)
- {
- /* The red-zone begins below the return address. */
- m->fs.red_zone_offset = RED_ZONE_SIZE + UNITS_PER_WORD;
-
- /* When the register save area is in the aligned portion of
- the stack, determine the maximum runtime displacement that
- matches up with the aligned frame. */
- if (stack_realign_drap)
- m->fs.red_zone_offset -= (crtl->stack_alignment_needed / BITS_PER_UNIT
- + UNITS_PER_WORD);
- }
-
- /* Special care must be taken for the normal return case of a function
- using eh_return: the eax and edx registers are marked as saved, but
- not restored along this path. Adjust the save location to match. */
- if (crtl->calls_eh_return && style != 2)
- frame.reg_save_offset -= 2 * UNITS_PER_WORD;
-
- /* EH_RETURN requires the use of moves to function properly. */
- if (crtl->calls_eh_return)
- restore_regs_via_mov = true;
- /* SEH requires the use of pops to identify the epilogue. */
- else if (TARGET_SEH)
- restore_regs_via_mov = false;
- /* If we're only restoring one register and sp is not valid then
- using a move instruction to restore the register since it's
- less work than reloading sp and popping the register. */
- else if (!m->fs.sp_valid && frame.nregs <= 1)
- restore_regs_via_mov = true;
- else if (TARGET_EPILOGUE_USING_MOVE
- && cfun->machine->use_fast_prologue_epilogue
- && (frame.nregs > 1
- || m->fs.sp_offset != frame.reg_save_offset))
- restore_regs_via_mov = true;
- else if (frame_pointer_needed
- && !frame.nregs
- && m->fs.sp_offset != frame.reg_save_offset)
- restore_regs_via_mov = true;
- else if (frame_pointer_needed
- && TARGET_USE_LEAVE
- && cfun->machine->use_fast_prologue_epilogue
- && frame.nregs == 1)
- restore_regs_via_mov = true;
- else
- restore_regs_via_mov = false;
-
- if (restore_regs_via_mov || frame.nsseregs)
- {
- /* Ensure that the entire register save area is addressable via
- the stack pointer, if we will restore via sp. */
- if (TARGET_64BIT
- && m->fs.sp_offset > 0x7fffffff
- && !(m->fs.fp_valid || m->fs.drap_valid)
- && (frame.nsseregs + frame.nregs) != 0)
- {
- pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (m->fs.sp_offset
- - frame.sse_reg_save_offset),
- style,
- m->fs.cfa_reg == stack_pointer_rtx);
- }
- }
-
- /* If there are any SSE registers to restore, then we have to do it
- via moves, since there's obviously no pop for SSE regs. */
- if (frame.nsseregs)
- ix86_emit_restore_sse_regs_using_mov (frame.sse_reg_save_offset,
- style == 2);
-
- if (restore_regs_via_mov)
- {
- rtx t;
-
- if (frame.nregs)
- ix86_emit_restore_regs_using_mov (frame.reg_save_offset, style == 2);
-
- /* eh_return epilogues need %ecx added to the stack pointer. */
- if (style == 2)
- {
- rtx insn, sa = EH_RETURN_STACKADJ_RTX;
-
- /* Stack align doesn't work with eh_return. */
- gcc_assert (!stack_realign_drap);
- /* Neither does regparm nested functions. */
- gcc_assert (!ix86_static_chain_on_stack);
-
- if (frame_pointer_needed)
- {
- t = gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx, sa);
- t = plus_constant (Pmode, t, m->fs.fp_offset - UNITS_PER_WORD);
- emit_insn (gen_rtx_SET (VOIDmode, sa, t));
-
- t = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
- insn = emit_move_insn (hard_frame_pointer_rtx, t);
-
- /* Note that we use SA as a temporary CFA, as the return
- address is at the proper place relative to it. We
- pretend this happens at the FP restore insn because
- prior to this insn the FP would be stored at the wrong
- offset relative to SA, and after this insn we have no
- other reasonable register to use for the CFA. We don't
- bother resetting the CFA to the SP for the duration of
- the return insn. */
- add_reg_note (insn, REG_CFA_DEF_CFA,
- plus_constant (Pmode, sa, UNITS_PER_WORD));
- ix86_add_queued_cfa_restore_notes (insn);
- add_reg_note (insn, REG_CFA_RESTORE, hard_frame_pointer_rtx);
- RTX_FRAME_RELATED_P (insn) = 1;
-
- m->fs.cfa_reg = sa;
- m->fs.cfa_offset = UNITS_PER_WORD;
- m->fs.fp_valid = false;
-
- pro_epilogue_adjust_stack (stack_pointer_rtx, sa,
- const0_rtx, style, false);
- }
- else
- {
- t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, sa);
- t = plus_constant (Pmode, t, m->fs.sp_offset - UNITS_PER_WORD);
- insn = emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx, t));
- ix86_add_queued_cfa_restore_notes (insn);
-
- gcc_assert (m->fs.cfa_reg == stack_pointer_rtx);
- if (m->fs.cfa_offset != UNITS_PER_WORD)
- {
- m->fs.cfa_offset = UNITS_PER_WORD;
- add_reg_note (insn, REG_CFA_DEF_CFA,
- plus_constant (Pmode, stack_pointer_rtx,
- UNITS_PER_WORD));
- RTX_FRAME_RELATED_P (insn) = 1;
- }
- }
- m->fs.sp_offset = UNITS_PER_WORD;
- m->fs.sp_valid = true;
- }
- }
- else
- {
- /* SEH requires that the function end with (1) a stack adjustment
- if necessary, (2) a sequence of pops, and (3) a return or
- jump instruction. Prevent insns from the function body from
- being scheduled into this sequence. */
- if (TARGET_SEH)
- {
- /* Prevent a catch region from being adjacent to the standard
- epilogue sequence. Unfortuantely crtl->uses_eh_lsda nor
- several other flags that would be interesting to test are
- not yet set up. */
- if (flag_non_call_exceptions)
- emit_insn (gen_nops (const1_rtx));
- else
- emit_insn (gen_blockage ());
- }
-
- /* First step is to deallocate the stack frame so that we can
- pop the registers. Also do it on SEH target for very large
- frame as the emitted instructions aren't allowed by the ABI in
- epilogues. */
- if (!m->fs.sp_valid
- || (TARGET_SEH
- && (m->fs.sp_offset - frame.reg_save_offset
- >= SEH_MAX_FRAME_SIZE)))
- {
- pro_epilogue_adjust_stack (stack_pointer_rtx, hard_frame_pointer_rtx,
- GEN_INT (m->fs.fp_offset
- - frame.reg_save_offset),
- style, false);
- }
- else if (m->fs.sp_offset != frame.reg_save_offset)
- {
- pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (m->fs.sp_offset
- - frame.reg_save_offset),
- style,
- m->fs.cfa_reg == stack_pointer_rtx);
- }
-
- ix86_emit_restore_regs_using_pop ();
- }
-
- /* If we used a stack pointer and haven't already got rid of it,
- then do so now. */
- if (m->fs.fp_valid)
- {
- /* If the stack pointer is valid and pointing at the frame
- pointer store address, then we only need a pop. */
- if (m->fs.sp_valid && m->fs.sp_offset == frame.hfp_save_offset)
- ix86_emit_restore_reg_using_pop (hard_frame_pointer_rtx);
- /* Leave results in shorter dependency chains on CPUs that are
- able to grok it fast. */
- else if (TARGET_USE_LEAVE
- || optimize_function_for_size_p (cfun)
- || !cfun->machine->use_fast_prologue_epilogue)
- ix86_emit_leave ();
- else
- {
- pro_epilogue_adjust_stack (stack_pointer_rtx,
- hard_frame_pointer_rtx,
- const0_rtx, style, !using_drap);
- ix86_emit_restore_reg_using_pop (hard_frame_pointer_rtx);
- }
- }
-
- if (using_drap)
- {
- int param_ptr_offset = UNITS_PER_WORD;
- rtx insn;
-
- gcc_assert (stack_realign_drap);
-
- if (ix86_static_chain_on_stack)
- param_ptr_offset += UNITS_PER_WORD;
- if (!call_used_regs[REGNO (crtl->drap_reg)])
- param_ptr_offset += UNITS_PER_WORD;
-
- insn = emit_insn (gen_rtx_SET
- (VOIDmode, stack_pointer_rtx,
- gen_rtx_PLUS (Pmode,
- crtl->drap_reg,
- GEN_INT (-param_ptr_offset))));
- m->fs.cfa_reg = stack_pointer_rtx;
- m->fs.cfa_offset = param_ptr_offset;
- m->fs.sp_offset = param_ptr_offset;
- m->fs.realigned = false;
-
- add_reg_note (insn, REG_CFA_DEF_CFA,
- gen_rtx_PLUS (Pmode, stack_pointer_rtx,
- GEN_INT (param_ptr_offset)));
- RTX_FRAME_RELATED_P (insn) = 1;
-
- if (!call_used_regs[REGNO (crtl->drap_reg)])
- ix86_emit_restore_reg_using_pop (crtl->drap_reg);
- }
-
- /* At this point the stack pointer must be valid, and we must have
- restored all of the registers. We may not have deallocated the
- entire stack frame. We've delayed this until now because it may
- be possible to merge the local stack deallocation with the
- deallocation forced by ix86_static_chain_on_stack. */
- gcc_assert (m->fs.sp_valid);
- gcc_assert (!m->fs.fp_valid);
- gcc_assert (!m->fs.realigned);
- if (m->fs.sp_offset != UNITS_PER_WORD)
- {
- pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (m->fs.sp_offset - UNITS_PER_WORD),
- style, true);
- }
- else
- ix86_add_queued_cfa_restore_notes (get_last_insn ());
-
- /* Sibcall epilogues don't want a return instruction. */
- if (style == 0)
- {
- m->fs = frame_state_save;
- return;
- }
-
- if (crtl->args.pops_args && crtl->args.size)
- {
- rtx popc = GEN_INT (crtl->args.pops_args);
-
- /* i386 can only pop 64K bytes. If asked to pop more, pop return
- address, do explicit add, and jump indirectly to the caller. */
-
- if (crtl->args.pops_args >= 65536)
- {
- rtx ecx = gen_rtx_REG (SImode, CX_REG);
- rtx insn;
-
- /* There is no "pascal" calling convention in any 64bit ABI. */
- gcc_assert (!TARGET_64BIT);
-
- insn = emit_insn (gen_pop (ecx));
- m->fs.cfa_offset -= UNITS_PER_WORD;
- m->fs.sp_offset -= UNITS_PER_WORD;
-
- add_reg_note (insn, REG_CFA_ADJUST_CFA,
- copy_rtx (XVECEXP (PATTERN (insn), 0, 1)));
- add_reg_note (insn, REG_CFA_REGISTER,
- gen_rtx_SET (VOIDmode, ecx, pc_rtx));
- RTX_FRAME_RELATED_P (insn) = 1;
-
- pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
- popc, -1, true);
- emit_jump_insn (gen_simple_return_indirect_internal (ecx));
- }
- else
- emit_jump_insn (gen_simple_return_pop_internal (popc));
- }
- else
- emit_jump_insn (gen_simple_return_internal ());
-
- /* Restore the state back to the state from the prologue,
- so that it's correct for the next epilogue. */
- m->fs = frame_state_save;
-}
-
-/* Reset from the function's potential modifications. */
-
-static void
-ix86_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
- HOST_WIDE_INT size ATTRIBUTE_UNUSED)
-{
- if (pic_offset_table_rtx)
- SET_REGNO (pic_offset_table_rtx, REAL_PIC_OFFSET_TABLE_REGNUM);
-#if TARGET_MACHO
- /* Mach-O doesn't support labels at the end of objects, so if
- it looks like we might want one, insert a NOP. */
- {
- rtx insn = get_last_insn ();
- rtx deleted_debug_label = NULL_RTX;
- while (insn
- && NOTE_P (insn)
- && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
- {
- /* Don't insert a nop for NOTE_INSN_DELETED_DEBUG_LABEL
- notes only, instead set their CODE_LABEL_NUMBER to -1,
- otherwise there would be code generation differences
- in between -g and -g0. */
- if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_DELETED_DEBUG_LABEL)
- deleted_debug_label = insn;
- insn = PREV_INSN (insn);
- }
- if (insn
- && (LABEL_P (insn)
- || (NOTE_P (insn)
- && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
- fputs ("\tnop\n", file);
- else if (deleted_debug_label)
- for (insn = deleted_debug_label; insn; insn = NEXT_INSN (insn))
- if (NOTE_KIND (insn) == NOTE_INSN_DELETED_DEBUG_LABEL)
- CODE_LABEL_NUMBER (insn) = -1;
- }
-#endif
-
-}
-
-/* Return a scratch register to use in the split stack prologue. The
- split stack prologue is used for -fsplit-stack. It is the first
- instructions in the function, even before the regular prologue.
- The scratch register can be any caller-saved register which is not
- used for parameters or for the static chain. */
-
-static unsigned int
-split_stack_prologue_scratch_regno (void)
-{
- if (TARGET_64BIT)
- return R11_REG;
- else
- {
- bool is_fastcall, is_thiscall;
- int regparm;
-
- is_fastcall = (lookup_attribute ("fastcall",
- TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl)))
- != NULL);
- is_thiscall = (lookup_attribute ("thiscall",
- TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl)))
- != NULL);
- regparm = ix86_function_regparm (TREE_TYPE (cfun->decl), cfun->decl);
-
- if (is_fastcall)
- {
- if (DECL_STATIC_CHAIN (cfun->decl))
- {
- sorry ("-fsplit-stack does not support fastcall with "
- "nested function");
- return INVALID_REGNUM;
- }
- return AX_REG;
- }
- else if (is_thiscall)
- {
- if (!DECL_STATIC_CHAIN (cfun->decl))
- return DX_REG;
- return AX_REG;
- }
- else if (regparm < 3)
- {
- if (!DECL_STATIC_CHAIN (cfun->decl))
- return CX_REG;
- else
- {
- if (regparm >= 2)
- {
- sorry ("-fsplit-stack does not support 2 register "
- " parameters for a nested function");
- return INVALID_REGNUM;
- }
- return DX_REG;
- }
- }
- else
- {
- /* FIXME: We could make this work by pushing a register
- around the addition and comparison. */
- sorry ("-fsplit-stack does not support 3 register parameters");
- return INVALID_REGNUM;
- }
- }
-}
-
-/* A SYMBOL_REF for the function which allocates new stackspace for
- -fsplit-stack. */
-
-static GTY(()) rtx split_stack_fn;
-
-/* A SYMBOL_REF for the more stack function when using the large
- model. */
-
-static GTY(()) rtx split_stack_fn_large;
-
-/* Handle -fsplit-stack. These are the first instructions in the
- function, even before the regular prologue. */
-
-void
-ix86_expand_split_stack_prologue (void)
-{
- struct ix86_frame frame;
- HOST_WIDE_INT allocate;
- unsigned HOST_WIDE_INT args_size;
- rtx label, limit, current, jump_insn, allocate_rtx, call_insn, call_fusage;
- rtx scratch_reg = NULL_RTX;
- rtx varargs_label = NULL_RTX;
- rtx fn;
-
- gcc_assert (flag_split_stack && reload_completed);
-
- ix86_finalize_stack_realign_flags ();
- ix86_compute_frame_layout (&frame);
- allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET;
-
- /* This is the label we will branch to if we have enough stack
- space. We expect the basic block reordering pass to reverse this
- branch if optimizing, so that we branch in the unlikely case. */
- label = gen_label_rtx ();
-
- /* We need to compare the stack pointer minus the frame size with
- the stack boundary in the TCB. The stack boundary always gives
- us SPLIT_STACK_AVAILABLE bytes, so if we need less than that we
- can compare directly. Otherwise we need to do an addition. */
-
- limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
- UNSPEC_STACK_CHECK);
- limit = gen_rtx_CONST (Pmode, limit);
- limit = gen_rtx_MEM (Pmode, limit);
- if (allocate < SPLIT_STACK_AVAILABLE)
- current = stack_pointer_rtx;
- else
- {
- unsigned int scratch_regno;
- rtx offset;
-
- /* We need a scratch register to hold the stack pointer minus
- the required frame size. Since this is the very start of the
- function, the scratch register can be any caller-saved
- register which is not used for parameters. */
- offset = GEN_INT (- allocate);
- scratch_regno = split_stack_prologue_scratch_regno ();
- if (scratch_regno == INVALID_REGNUM)
- return;
- scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
- if (!TARGET_64BIT || x86_64_immediate_operand (offset, Pmode))
- {
- /* We don't use ix86_gen_add3 in this case because it will
- want to split to lea, but when not optimizing the insn
- will not be split after this point. */
- emit_insn (gen_rtx_SET (VOIDmode, scratch_reg,
- gen_rtx_PLUS (Pmode, stack_pointer_rtx,
- offset)));
- }
- else
- {
- emit_move_insn (scratch_reg, offset);
- emit_insn (ix86_gen_add3 (scratch_reg, scratch_reg,
- stack_pointer_rtx));
- }
- current = scratch_reg;
- }
-
- ix86_expand_branch (GEU, current, limit, label);
- jump_insn = get_last_insn ();
- JUMP_LABEL (jump_insn) = label;
-
- /* Mark the jump as very likely to be taken. */
- add_reg_note (jump_insn, REG_BR_PROB,
- GEN_INT (REG_BR_PROB_BASE - REG_BR_PROB_BASE / 100));
-
- if (split_stack_fn == NULL_RTX)
- split_stack_fn = gen_rtx_SYMBOL_REF (Pmode, "__morestack");
- fn = split_stack_fn;
-
- /* Get more stack space. We pass in the desired stack space and the
- size of the arguments to copy to the new stack. In 32-bit mode
- we push the parameters; __morestack will return on a new stack
- anyhow. In 64-bit mode we pass the parameters in r10 and
- r11. */
- allocate_rtx = GEN_INT (allocate);
- args_size = crtl->args.size >= 0 ? crtl->args.size : 0;
- call_fusage = NULL_RTX;
- if (TARGET_64BIT)
- {
- rtx reg10, reg11;
-
- reg10 = gen_rtx_REG (Pmode, R10_REG);
- reg11 = gen_rtx_REG (Pmode, R11_REG);
-
- /* If this function uses a static chain, it will be in %r10.
- Preserve it across the call to __morestack. */
- if (DECL_STATIC_CHAIN (cfun->decl))
- {
- rtx rax;
-
- rax = gen_rtx_REG (word_mode, AX_REG);
- emit_move_insn (rax, gen_rtx_REG (word_mode, R10_REG));
- use_reg (&call_fusage, rax);
- }
-
- if (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
- {
- HOST_WIDE_INT argval;
-
- gcc_assert (Pmode == DImode);
- /* When using the large model we need to load the address
- into a register, and we've run out of registers. So we
- switch to a different calling convention, and we call a
- different function: __morestack_large. We pass the
- argument size in the upper 32 bits of r10 and pass the
- frame size in the lower 32 bits. */
- gcc_assert ((allocate & (HOST_WIDE_INT) 0xffffffff) == allocate);
- gcc_assert ((args_size & 0xffffffff) == args_size);
-
- if (split_stack_fn_large == NULL_RTX)
- split_stack_fn_large =
- gen_rtx_SYMBOL_REF (Pmode, "__morestack_large_model");
-
- if (ix86_cmodel == CM_LARGE_PIC)
- {
- rtx label, x;
-
- label = gen_label_rtx ();
- emit_label (label);
- LABEL_PRESERVE_P (label) = 1;
- emit_insn (gen_set_rip_rex64 (reg10, label));
- emit_insn (gen_set_got_offset_rex64 (reg11, label));
- emit_insn (ix86_gen_add3 (reg10, reg10, reg11));
- x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, split_stack_fn_large),
- UNSPEC_GOT);
- x = gen_rtx_CONST (Pmode, x);
- emit_move_insn (reg11, x);
- x = gen_rtx_PLUS (Pmode, reg10, reg11);
- x = gen_const_mem (Pmode, x);
- emit_move_insn (reg11, x);
- }
- else
- emit_move_insn (reg11, split_stack_fn_large);
-
- fn = reg11;
-
- argval = ((args_size << 16) << 16) + allocate;
- emit_move_insn (reg10, GEN_INT (argval));
- }
- else
- {
- emit_move_insn (reg10, allocate_rtx);
- emit_move_insn (reg11, GEN_INT (args_size));
- use_reg (&call_fusage, reg11);
- }
-
- use_reg (&call_fusage, reg10);
- }
- else
- {
- emit_insn (gen_push (GEN_INT (args_size)));
- emit_insn (gen_push (allocate_rtx));
- }
- call_insn = ix86_expand_call (NULL_RTX, gen_rtx_MEM (QImode, fn),
- GEN_INT (UNITS_PER_WORD), constm1_rtx,
- NULL_RTX, false);
- add_function_usage_to (call_insn, call_fusage);
-
- /* In order to make call/return prediction work right, we now need
- to execute a return instruction. See
- libgcc/config/i386/morestack.S for the details on how this works.
-
- For flow purposes gcc must not see this as a return
- instruction--we need control flow to continue at the subsequent
- label. Therefore, we use an unspec. */
- gcc_assert (crtl->args.pops_args < 65536);
- emit_insn (gen_split_stack_return (GEN_INT (crtl->args.pops_args)));
-
- /* If we are in 64-bit mode and this function uses a static chain,
- we saved %r10 in %rax before calling _morestack. */
- if (TARGET_64BIT && DECL_STATIC_CHAIN (cfun->decl))
- emit_move_insn (gen_rtx_REG (word_mode, R10_REG),
- gen_rtx_REG (word_mode, AX_REG));
-
- /* If this function calls va_start, we need to store a pointer to
- the arguments on the old stack, because they may not have been
- all copied to the new stack. At this point the old stack can be
- found at the frame pointer value used by __morestack, because
- __morestack has set that up before calling back to us. Here we
- store that pointer in a scratch register, and in
- ix86_expand_prologue we store the scratch register in a stack
- slot. */
- if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
- {
- unsigned int scratch_regno;
- rtx frame_reg;
- int words;
-
- scratch_regno = split_stack_prologue_scratch_regno ();
- scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
- frame_reg = gen_rtx_REG (Pmode, BP_REG);
-
- /* 64-bit:
- fp -> old fp value
- return address within this function
- return address of caller of this function
- stack arguments
- So we add three words to get to the stack arguments.
-
- 32-bit:
- fp -> old fp value
- return address within this function
- first argument to __morestack
- second argument to __morestack
- return address of caller of this function
- stack arguments
- So we add five words to get to the stack arguments.
- */
- words = TARGET_64BIT ? 3 : 5;
- emit_insn (gen_rtx_SET (VOIDmode, scratch_reg,
- gen_rtx_PLUS (Pmode, frame_reg,
- GEN_INT (words * UNITS_PER_WORD))));
-
- varargs_label = gen_label_rtx ();
- emit_jump_insn (gen_jump (varargs_label));
- JUMP_LABEL (get_last_insn ()) = varargs_label;
-
- emit_barrier ();
- }
-
- emit_label (label);
- LABEL_NUSES (label) = 1;
-
- /* If this function calls va_start, we now have to set the scratch
- register for the case where we do not call __morestack. In this
- case we need to set it based on the stack pointer. */
- if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
- {
- emit_insn (gen_rtx_SET (VOIDmode, scratch_reg,
- gen_rtx_PLUS (Pmode, stack_pointer_rtx,
- GEN_INT (UNITS_PER_WORD))));
-
- emit_label (varargs_label);
- LABEL_NUSES (varargs_label) = 1;
- }
-}
-
-/* We may have to tell the dataflow pass that the split stack prologue
- is initializing a scratch register. */
-
-static void
-ix86_live_on_entry (bitmap regs)
-{
- if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
- {
- gcc_assert (flag_split_stack);
- bitmap_set_bit (regs, split_stack_prologue_scratch_regno ());
- }
-}
-
-/* Determine if op is suitable SUBREG RTX for address. */
-
-static bool
-ix86_address_subreg_operand (rtx op)
-{
- enum machine_mode mode;
-
- if (!REG_P (op))
- return false;
-
- mode = GET_MODE (op);
-
- if (GET_MODE_CLASS (mode) != MODE_INT)
- return false;
-
- /* Don't allow SUBREGs that span more than a word. It can lead to spill
- failures when the register is one word out of a two word structure. */
- if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
- return false;
-
- /* Allow only SUBREGs of non-eliminable hard registers. */
- return register_no_elim_operand (op, mode);
-}
-
-/* Extract the parts of an RTL expression that is a valid memory address
- for an instruction. Return 0 if the structure of the address is
- grossly off. Return -1 if the address contains ASHIFT, so it is not
- strictly valid, but still used for computing length of lea instruction. */
-
-int
-ix86_decompose_address (rtx addr, struct ix86_address *out)
-{
- rtx base = NULL_RTX, index = NULL_RTX, disp = NULL_RTX;
- rtx base_reg, index_reg;
- HOST_WIDE_INT scale = 1;
- rtx scale_rtx = NULL_RTX;
- rtx tmp;
- int retval = 1;
- enum ix86_address_seg seg = SEG_DEFAULT;
-
- /* Allow zero-extended SImode addresses,
- they will be emitted with addr32 prefix. */
- if (TARGET_64BIT && GET_MODE (addr) == DImode)
- {
- if (GET_CODE (addr) == ZERO_EXTEND
- && GET_MODE (XEXP (addr, 0)) == SImode)
- {
- addr = XEXP (addr, 0);
- if (CONST_INT_P (addr))
- return 0;
- }
- else if (GET_CODE (addr) == AND
- && const_32bit_mask (XEXP (addr, 1), DImode))
- {
- addr = simplify_gen_subreg (SImode, XEXP (addr, 0), DImode, 0);
- if (addr == NULL_RTX)
- return 0;
-
- if (CONST_INT_P (addr))
- return 0;
- }
- }
-
- /* Allow SImode subregs of DImode addresses,
- they will be emitted with addr32 prefix. */
- if (TARGET_64BIT && GET_MODE (addr) == SImode)
- {
- if (GET_CODE (addr) == SUBREG
- && GET_MODE (SUBREG_REG (addr)) == DImode)
- {
- addr = SUBREG_REG (addr);
- if (CONST_INT_P (addr))
- return 0;
- }
- }
-
- if (REG_P (addr))
- base = addr;
- else if (GET_CODE (addr) == SUBREG)
- {
- if (ix86_address_subreg_operand (SUBREG_REG (addr)))
- base = addr;
- else
- return 0;
- }
- else if (GET_CODE (addr) == PLUS)
- {
- rtx addends[4], op;
- int n = 0, i;
-
- op = addr;
- do
- {
- if (n >= 4)
- return 0;
- addends[n++] = XEXP (op, 1);
- op = XEXP (op, 0);
- }
- while (GET_CODE (op) == PLUS);
- if (n >= 4)
- return 0;
- addends[n] = op;
-
- for (i = n; i >= 0; --i)
- {
- op = addends[i];
- switch (GET_CODE (op))
- {
- case MULT:
- if (index)
- return 0;
- index = XEXP (op, 0);
- scale_rtx = XEXP (op, 1);
- break;
-
- case ASHIFT:
- if (index)
- return 0;
- index = XEXP (op, 0);
- tmp = XEXP (op, 1);
- if (!CONST_INT_P (tmp))
- return 0;
- scale = INTVAL (tmp);
- if ((unsigned HOST_WIDE_INT) scale > 3)
- return 0;
- scale = 1 << scale;
- break;
-
- case ZERO_EXTEND:
- op = XEXP (op, 0);
- if (GET_CODE (op) != UNSPEC)
- return 0;
- /* FALLTHRU */
-
- case UNSPEC:
- if (XINT (op, 1) == UNSPEC_TP
- && TARGET_TLS_DIRECT_SEG_REFS
- && seg == SEG_DEFAULT)
- seg = TARGET_64BIT ? SEG_FS : SEG_GS;
- else
- return 0;
- break;
-
- case SUBREG:
- if (!ix86_address_subreg_operand (SUBREG_REG (op)))
- return 0;
- /* FALLTHRU */
-
- case REG:
- if (!base)
- base = op;
- else if (!index)
- index = op;
- else
- return 0;
- break;
-
- case CONST:
- case CONST_INT:
- case SYMBOL_REF:
- case LABEL_REF:
- if (disp)
- return 0;
- disp = op;
- break;
-
- default:
- return 0;
- }
- }
- }
- else if (GET_CODE (addr) == MULT)
- {
- index = XEXP (addr, 0); /* index*scale */
- scale_rtx = XEXP (addr, 1);
- }
- else if (GET_CODE (addr) == ASHIFT)
- {
- /* We're called for lea too, which implements ashift on occasion. */
- index = XEXP (addr, 0);
- tmp = XEXP (addr, 1);
- if (!CONST_INT_P (tmp))
- return 0;
- scale = INTVAL (tmp);
- if ((unsigned HOST_WIDE_INT) scale > 3)
- return 0;
- scale = 1 << scale;
- retval = -1;
- }
- else if (CONST_INT_P (addr))
- {
- if (!x86_64_immediate_operand (addr, VOIDmode))
- return 0;
-
- /* Constant addresses are sign extended to 64bit, we have to
- prevent addresses from 0x80000000 to 0xffffffff in x32 mode. */
- if (TARGET_X32
- && val_signbit_known_set_p (SImode, INTVAL (addr)))
- return 0;
-
- disp = addr;
- }
- else
- disp = addr; /* displacement */
-
- if (index)
- {
- if (REG_P (index))
- ;
- else if (GET_CODE (index) == SUBREG
- && ix86_address_subreg_operand (SUBREG_REG (index)))
- ;
- else
- return 0;
- }
-
-/* Address override works only on the (%reg) part of %fs:(%reg). */
- if (seg != SEG_DEFAULT
- && ((base && GET_MODE (base) != word_mode)
- || (index && GET_MODE (index) != word_mode)))
- return 0;
-
- /* Extract the integral value of scale. */
- if (scale_rtx)
- {
- if (!CONST_INT_P (scale_rtx))
- return 0;
- scale = INTVAL (scale_rtx);
- }
-
- base_reg = base && GET_CODE (base) == SUBREG ? SUBREG_REG (base) : base;
- index_reg = index && GET_CODE (index) == SUBREG ? SUBREG_REG (index) : index;
-
- /* Avoid useless 0 displacement. */
- if (disp == const0_rtx && (base || index))
- disp = NULL_RTX;
-
- /* Allow arg pointer and stack pointer as index if there is not scaling. */
- if (base_reg && index_reg && scale == 1
- && (index_reg == arg_pointer_rtx
- || index_reg == frame_pointer_rtx
- || (REG_P (index_reg) && REGNO (index_reg) == STACK_POINTER_REGNUM)))
- {
- rtx tmp;
- tmp = base, base = index, index = tmp;
- tmp = base_reg, base_reg = index_reg, index_reg = tmp;
- }
-
- /* Special case: %ebp cannot be encoded as a base without a displacement.
- Similarly %r13. */
- if (!disp
- && base_reg
- && (base_reg == hard_frame_pointer_rtx
- || base_reg == frame_pointer_rtx
- || base_reg == arg_pointer_rtx
- || (REG_P (base_reg)
- && (REGNO (base_reg) == HARD_FRAME_POINTER_REGNUM
- || REGNO (base_reg) == R13_REG))))
- disp = const0_rtx;
-
- /* Special case: on K6, [%esi] makes the instruction vector decoded.
- Avoid this by transforming to [%esi+0].
- Reload calls address legitimization without cfun defined, so we need
- to test cfun for being non-NULL. */
- if (TARGET_K6 && cfun && optimize_function_for_speed_p (cfun)
- && base_reg && !index_reg && !disp
- && REG_P (base_reg) && REGNO (base_reg) == SI_REG)
- disp = const0_rtx;
-
- /* Special case: encode reg+reg instead of reg*2. */
- if (!base && index && scale == 2)
- base = index, base_reg = index_reg, scale = 1;
-
- /* Special case: scaling cannot be encoded without base or displacement. */
- if (!base && !disp && index && scale != 1)
- disp = const0_rtx;
-
- out->base = base;
- out->index = index;
- out->disp = disp;
- out->scale = scale;
- out->seg = seg;
-
- return retval;
-}
-
-/* Return cost of the memory address x.
- For i386, it is better to use a complex address than let gcc copy
- the address into a reg and make a new pseudo. But not if the address
- requires to two regs - that would mean more pseudos with longer
- lifetimes. */
-static int
-ix86_address_cost (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED,
- addr_space_t as ATTRIBUTE_UNUSED,
- bool speed ATTRIBUTE_UNUSED)
-{
- struct ix86_address parts;
- int cost = 1;
- int ok = ix86_decompose_address (x, &parts);
-
- gcc_assert (ok);
-
- if (parts.base && GET_CODE (parts.base) == SUBREG)
- parts.base = SUBREG_REG (parts.base);
- if (parts.index && GET_CODE (parts.index) == SUBREG)
- parts.index = SUBREG_REG (parts.index);
-
- /* Attempt to minimize number of registers in the address. */
- if ((parts.base
- && (!REG_P (parts.base) || REGNO (parts.base) >= FIRST_PSEUDO_REGISTER))
- || (parts.index
- && (!REG_P (parts.index)
- || REGNO (parts.index) >= FIRST_PSEUDO_REGISTER)))
- cost++;
-
- if (parts.base
- && (!REG_P (parts.base) || REGNO (parts.base) >= FIRST_PSEUDO_REGISTER)
- && parts.index
- && (!REG_P (parts.index) || REGNO (parts.index) >= FIRST_PSEUDO_REGISTER)
- && parts.base != parts.index)
- cost++;
-
- /* AMD-K6 don't like addresses with ModR/M set to 00_xxx_100b,
- since it's predecode logic can't detect the length of instructions
- and it degenerates to vector decoded. Increase cost of such
- addresses here. The penalty is minimally 2 cycles. It may be worthwhile
- to split such addresses or even refuse such addresses at all.
-
- Following addressing modes are affected:
- [base+scale*index]
- [scale*index+disp]
- [base+index]
-
- The first and last case may be avoidable by explicitly coding the zero in
- memory address, but I don't have AMD-K6 machine handy to check this
- theory. */
-
- if (TARGET_K6
- && ((!parts.disp && parts.base && parts.index && parts.scale != 1)
- || (parts.disp && !parts.base && parts.index && parts.scale != 1)
- || (!parts.disp && parts.base && parts.index && parts.scale == 1)))
- cost += 10;
-
- return cost;
-}
-
-/* Allow {LABEL | SYMBOL}_REF - SYMBOL_REF-FOR-PICBASE for Mach-O as
- this is used for to form addresses to local data when -fPIC is in
- use. */
-
-static bool
-darwin_local_data_pic (rtx disp)
-{
- return (GET_CODE (disp) == UNSPEC
- && XINT (disp, 1) == UNSPEC_MACHOPIC_OFFSET);
-}
-
-/* Determine if a given RTX is a valid constant. We already know this
- satisfies CONSTANT_P. */
-
-static bool
-ix86_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
-{
- switch (GET_CODE (x))
- {
- case CONST:
- x = XEXP (x, 0);
-
- if (GET_CODE (x) == PLUS)
- {
- if (!CONST_INT_P (XEXP (x, 1)))
- return false;
- x = XEXP (x, 0);
- }
-
- if (TARGET_MACHO && darwin_local_data_pic (x))
- return true;
-
- /* Only some unspecs are valid as "constants". */
- if (GET_CODE (x) == UNSPEC)
- switch (XINT (x, 1))
- {
- case UNSPEC_GOT:
- case UNSPEC_GOTOFF:
- case UNSPEC_PLTOFF:
- return TARGET_64BIT;
- case UNSPEC_TPOFF:
- case UNSPEC_NTPOFF:
- x = XVECEXP (x, 0, 0);
- return (GET_CODE (x) == SYMBOL_REF
- && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_EXEC);
- case UNSPEC_DTPOFF:
- x = XVECEXP (x, 0, 0);
- return (GET_CODE (x) == SYMBOL_REF
- && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC);
- default:
- return false;
- }
-
- /* We must have drilled down to a symbol. */
- if (GET_CODE (x) == LABEL_REF)
- return true;
- if (GET_CODE (x) != SYMBOL_REF)
- return false;
- /* FALLTHRU */
-
- case SYMBOL_REF:
- /* TLS symbols are never valid. */
- if (SYMBOL_REF_TLS_MODEL (x))
- return false;
-
- /* DLLIMPORT symbols are never valid. */
- if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
- && SYMBOL_REF_DLLIMPORT_P (x))
- return false;
-
-#if TARGET_MACHO
- /* mdynamic-no-pic */
- if (MACHO_DYNAMIC_NO_PIC_P)
- return machopic_symbol_defined_p (x);
-#endif
- break;
-
- case CONST_DOUBLE:
- if (GET_MODE (x) == TImode
- && x != CONST0_RTX (TImode)
- && !TARGET_64BIT)
- return false;
- break;
-
- case CONST_VECTOR:
- if (!standard_sse_constant_p (x))
- return false;
-
- default:
- break;
- }
-
- /* Otherwise we handle everything else in the move patterns. */
- return true;
-}
-
-/* Determine if it's legal to put X into the constant pool. This
- is not possible for the address of thread-local symbols, which
- is checked above. */
-
-static bool
-ix86_cannot_force_const_mem (enum machine_mode mode, rtx x)
-{
- /* We can always put integral constants and vectors in memory. */
- switch (GET_CODE (x))
- {
- case CONST_INT:
- case CONST_DOUBLE:
- case CONST_VECTOR:
- return false;
-
- default:
- break;
- }
- return !ix86_legitimate_constant_p (mode, x);
-}
-
-
-/* Nonzero if the constant value X is a legitimate general operand
- when generating PIC code. It is given that flag_pic is on and
- that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
-
-bool
-legitimate_pic_operand_p (rtx x)
-{
- rtx inner;
-
- switch (GET_CODE (x))
- {
- case CONST:
- inner = XEXP (x, 0);
- if (GET_CODE (inner) == PLUS
- && CONST_INT_P (XEXP (inner, 1)))
- inner = XEXP (inner, 0);
-
- /* Only some unspecs are valid as "constants". */
- if (GET_CODE (inner) == UNSPEC)
- switch (XINT (inner, 1))
- {
- case UNSPEC_GOT:
- case UNSPEC_GOTOFF:
- case UNSPEC_PLTOFF:
- return TARGET_64BIT;
- case UNSPEC_TPOFF:
- x = XVECEXP (inner, 0, 0);
- return (GET_CODE (x) == SYMBOL_REF
- && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_EXEC);
- case UNSPEC_MACHOPIC_OFFSET:
- return legitimate_pic_address_disp_p (x);
- default:
- return false;
- }
- /* FALLTHRU */
-
- case SYMBOL_REF:
- case LABEL_REF:
- return legitimate_pic_address_disp_p (x);
-
- default:
- return true;
- }
-}
-
-/* Determine if a given CONST RTX is a valid memory displacement
- in PIC mode. */
-
-bool
-legitimate_pic_address_disp_p (rtx disp)
-{
- bool saw_plus;
-
- /* In 64bit mode we can allow direct addresses of symbols and labels
- when they are not dynamic symbols. */
- if (TARGET_64BIT)
- {
- rtx op0 = disp, op1;
-
- switch (GET_CODE (disp))
- {
- case LABEL_REF:
- return true;
-
- case CONST:
- if (GET_CODE (XEXP (disp, 0)) != PLUS)
- break;
- op0 = XEXP (XEXP (disp, 0), 0);
- op1 = XEXP (XEXP (disp, 0), 1);
- if (!CONST_INT_P (op1)
- || INTVAL (op1) >= 16*1024*1024
- || INTVAL (op1) < -16*1024*1024)
- break;
- if (GET_CODE (op0) == LABEL_REF)
- return true;
- if (GET_CODE (op0) == CONST
- && GET_CODE (XEXP (op0, 0)) == UNSPEC
- && XINT (XEXP (op0, 0), 1) == UNSPEC_PCREL)
- return true;
- if (GET_CODE (op0) == UNSPEC
- && XINT (op0, 1) == UNSPEC_PCREL)
- return true;
- if (GET_CODE (op0) != SYMBOL_REF)
- break;
- /* FALLTHRU */
-
- case SYMBOL_REF:
- /* TLS references should always be enclosed in UNSPEC. */
- if (SYMBOL_REF_TLS_MODEL (op0))
- return false;
- if (!SYMBOL_REF_FAR_ADDR_P (op0) && SYMBOL_REF_LOCAL_P (op0)
- && ix86_cmodel != CM_LARGE_PIC)
- return true;
- break;
-
- default:
- break;
- }
- }
- if (GET_CODE (disp) != CONST)
- return false;
- disp = XEXP (disp, 0);
-
- if (TARGET_64BIT)
- {
- /* We are unsafe to allow PLUS expressions. This limit allowed distance
- of GOT tables. We should not need these anyway. */
- if (GET_CODE (disp) != UNSPEC
- || (XINT (disp, 1) != UNSPEC_GOTPCREL
- && XINT (disp, 1) != UNSPEC_GOTOFF
- && XINT (disp, 1) != UNSPEC_PCREL
- && XINT (disp, 1) != UNSPEC_PLTOFF))
- return false;
-
- if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF
- && GET_CODE (XVECEXP (disp, 0, 0)) != LABEL_REF)
- return false;
- return true;
- }
-
- saw_plus = false;
- if (GET_CODE (disp) == PLUS)
- {
- if (!CONST_INT_P (XEXP (disp, 1)))
- return false;
- disp = XEXP (disp, 0);
- saw_plus = true;
- }
-
- if (TARGET_MACHO && darwin_local_data_pic (disp))
- return true;
-
- if (GET_CODE (disp) != UNSPEC)
- return false;
-
- switch (XINT (disp, 1))
- {
- case UNSPEC_GOT:
- if (saw_plus)
- return false;
- /* We need to check for both symbols and labels because VxWorks loads
- text labels with @GOT rather than @GOTOFF. See gotoff_operand for
- details. */
- return (GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF
- || GET_CODE (XVECEXP (disp, 0, 0)) == LABEL_REF);
- case UNSPEC_GOTOFF:
- /* Refuse GOTOFF in 64bit mode since it is always 64bit when used.
- While ABI specify also 32bit relocation but we don't produce it in
- small PIC model at all. */
- if ((GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF
- || GET_CODE (XVECEXP (disp, 0, 0)) == LABEL_REF)
- && !TARGET_64BIT)
- return gotoff_operand (XVECEXP (disp, 0, 0), Pmode);
- return false;
- case UNSPEC_GOTTPOFF:
- case UNSPEC_GOTNTPOFF:
- case UNSPEC_INDNTPOFF:
- if (saw_plus)
- return false;
- disp = XVECEXP (disp, 0, 0);
- return (GET_CODE (disp) == SYMBOL_REF
- && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_INITIAL_EXEC);
- case UNSPEC_NTPOFF:
- disp = XVECEXP (disp, 0, 0);
- return (GET_CODE (disp) == SYMBOL_REF
- && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_LOCAL_EXEC);
- case UNSPEC_DTPOFF:
- disp = XVECEXP (disp, 0, 0);
- return (GET_CODE (disp) == SYMBOL_REF
- && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_LOCAL_DYNAMIC);
- }
-
- return false;
-}
-
-/* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
- replace the input X, or the original X if no replacement is called for.
- The output parameter *WIN is 1 if the calling macro should goto WIN,
- 0 if it should not. */
-
-bool
-ix86_legitimize_reload_address (rtx x,
- enum machine_mode mode ATTRIBUTE_UNUSED,
- int opnum, int type,
- int ind_levels ATTRIBUTE_UNUSED)
-{
- /* Reload can generate:
-
- (plus:DI (plus:DI (unspec:DI [(const_int 0 [0])] UNSPEC_TP)
- (reg:DI 97))
- (reg:DI 2 cx))
-
- This RTX is rejected from ix86_legitimate_address_p due to
- non-strictness of base register 97. Following this rejection,
- reload pushes all three components into separate registers,
- creating invalid memory address RTX.
-
- Following code reloads only the invalid part of the
- memory address RTX. */
-
- if (GET_CODE (x) == PLUS
- && REG_P (XEXP (x, 1))
- && GET_CODE (XEXP (x, 0)) == PLUS
- && REG_P (XEXP (XEXP (x, 0), 1)))
- {
- rtx base, index;
- bool something_reloaded = false;
-
- base = XEXP (XEXP (x, 0), 1);
- if (!REG_OK_FOR_BASE_STRICT_P (base))
- {
- push_reload (base, NULL_RTX, &XEXP (XEXP (x, 0), 1), NULL,
- BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
- opnum, (enum reload_type) type);
- something_reloaded = true;
- }
-
- index = XEXP (x, 1);
- if (!REG_OK_FOR_INDEX_STRICT_P (index))
- {
- push_reload (index, NULL_RTX, &XEXP (x, 1), NULL,
- INDEX_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
- opnum, (enum reload_type) type);
- something_reloaded = true;
- }
-
- gcc_assert (something_reloaded);
- return true;
- }
-
- return false;
-}
-
-/* Recognizes RTL expressions that are valid memory addresses for an
- instruction. The MODE argument is the machine mode for the MEM
- expression that wants to use this address.
-
- It only recognizes address in canonical form. LEGITIMIZE_ADDRESS should
- convert common non-canonical forms to canonical form so that they will
- be recognized. */
-
-static bool
-ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
- rtx addr, bool strict)
-{
- struct ix86_address parts;
- rtx base, index, disp;
- HOST_WIDE_INT scale;
-
- if (ix86_decompose_address (addr, &parts) <= 0)
- /* Decomposition failed. */
- return false;
-
- base = parts.base;
- index = parts.index;
- disp = parts.disp;
- scale = parts.scale;
-
- /* Validate base register. */
- if (base)
- {
- rtx reg;
-
- if (REG_P (base))
- reg = base;
- else if (GET_CODE (base) == SUBREG && REG_P (SUBREG_REG (base)))
- reg = SUBREG_REG (base);
- else
- /* Base is not a register. */
- return false;
-
- if (GET_MODE (base) != SImode && GET_MODE (base) != DImode)
- return false;
-
- if ((strict && ! REG_OK_FOR_BASE_STRICT_P (reg))
- || (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (reg)))
- /* Base is not valid. */
- return false;
- }
-
- /* Validate index register. */
- if (index)
- {
- rtx reg;
-
- if (REG_P (index))
- reg = index;
- else if (GET_CODE (index) == SUBREG && REG_P (SUBREG_REG (index)))
- reg = SUBREG_REG (index);
- else
- /* Index is not a register. */
- return false;
-
- if (GET_MODE (index) != SImode && GET_MODE (index) != DImode)
- return false;
-
- if ((strict && ! REG_OK_FOR_INDEX_STRICT_P (reg))
- || (! strict && ! REG_OK_FOR_INDEX_NONSTRICT_P (reg)))
- /* Index is not valid. */
- return false;
- }
-
- /* Index and base should have the same mode. */
- if (base && index
- && GET_MODE (base) != GET_MODE (index))
- return false;
-
- /* Validate scale factor. */
- if (scale != 1)
- {
- if (!index)
- /* Scale without index. */
- return false;
-
- if (scale != 2 && scale != 4 && scale != 8)
- /* Scale is not a valid multiplier. */
- return false;
- }
-
- /* Validate displacement. */
- if (disp)
- {
- if (GET_CODE (disp) == CONST
- && GET_CODE (XEXP (disp, 0)) == UNSPEC
- && XINT (XEXP (disp, 0), 1) != UNSPEC_MACHOPIC_OFFSET)
- switch (XINT (XEXP (disp, 0), 1))
- {
- /* Refuse GOTOFF and GOT in 64bit mode since it is always 64bit when
- used. While ABI specify also 32bit relocations, we don't produce
- them at all and use IP relative instead. */
- case UNSPEC_GOT:
- case UNSPEC_GOTOFF:
- gcc_assert (flag_pic);
- if (!TARGET_64BIT)
- goto is_legitimate_pic;
-
- /* 64bit address unspec. */
- return false;
-
- case UNSPEC_GOTPCREL:
- case UNSPEC_PCREL:
- gcc_assert (flag_pic);
- goto is_legitimate_pic;
-
- case UNSPEC_GOTTPOFF:
- case UNSPEC_GOTNTPOFF:
- case UNSPEC_INDNTPOFF:
- case UNSPEC_NTPOFF:
- case UNSPEC_DTPOFF:
- break;
-
- case UNSPEC_STACK_CHECK:
- gcc_assert (flag_split_stack);
- break;
-
- default:
- /* Invalid address unspec. */
- return false;
- }
-
- else if (SYMBOLIC_CONST (disp)
- && (flag_pic
- || (TARGET_MACHO
-#if TARGET_MACHO
- && MACHOPIC_INDIRECT
- && !machopic_operand_p (disp)
-#endif
- )))
- {
-
- is_legitimate_pic:
- if (TARGET_64BIT && (index || base))
- {
- /* foo@dtpoff(%rX) is ok. */
- if (GET_CODE (disp) != CONST
- || GET_CODE (XEXP (disp, 0)) != PLUS
- || GET_CODE (XEXP (XEXP (disp, 0), 0)) != UNSPEC
- || !CONST_INT_P (XEXP (XEXP (disp, 0), 1))
- || (XINT (XEXP (XEXP (disp, 0), 0), 1) != UNSPEC_DTPOFF
- && XINT (XEXP (XEXP (disp, 0), 0), 1) != UNSPEC_NTPOFF))
- /* Non-constant pic memory reference. */
- return false;
- }
- else if ((!TARGET_MACHO || flag_pic)
- && ! legitimate_pic_address_disp_p (disp))
- /* Displacement is an invalid pic construct. */
- return false;
-#if TARGET_MACHO
- else if (MACHO_DYNAMIC_NO_PIC_P
- && !ix86_legitimate_constant_p (Pmode, disp))
- /* displacment must be referenced via non_lazy_pointer */
- return false;
-#endif
-
- /* This code used to verify that a symbolic pic displacement
- includes the pic_offset_table_rtx register.
-
- While this is good idea, unfortunately these constructs may
- be created by "adds using lea" optimization for incorrect
- code like:
-
- int a;
- int foo(int i)
- {
- return *(&a+i);
- }
-
- This code is nonsensical, but results in addressing
- GOT table with pic_offset_table_rtx base. We can't
- just refuse it easily, since it gets matched by
- "addsi3" pattern, that later gets split to lea in the
- case output register differs from input. While this
- can be handled by separate addsi pattern for this case
- that never results in lea, this seems to be easier and
- correct fix for crash to disable this test. */
- }
- else if (GET_CODE (disp) != LABEL_REF
- && !CONST_INT_P (disp)
- && (GET_CODE (disp) != CONST
- || !ix86_legitimate_constant_p (Pmode, disp))
- && (GET_CODE (disp) != SYMBOL_REF
- || !ix86_legitimate_constant_p (Pmode, disp)))
- /* Displacement is not constant. */
- return false;
- else if (TARGET_64BIT
- && !x86_64_immediate_operand (disp, VOIDmode))
- /* Displacement is out of range. */
- return false;
- }
-
- /* Everything looks valid. */
- return true;
-}
-
-/* Determine if a given RTX is a valid constant address. */
-
-bool
-constant_address_p (rtx x)
-{
- return CONSTANT_P (x) && ix86_legitimate_address_p (Pmode, x, 1);
-}
-
-/* Return a unique alias set for the GOT. */
-
-static alias_set_type
-ix86_GOT_alias_set (void)
-{
- static alias_set_type set = -1;
- if (set == -1)
- set = new_alias_set ();
- return set;
-}
-
-/* Return a legitimate reference for ORIG (an address) using the
- register REG. If REG is 0, a new pseudo is generated.
-
- There are two types of references that must be handled:
-
- 1. Global data references must load the address from the GOT, via
- the PIC reg. An insn is emitted to do this load, and the reg is
- returned.
-
- 2. Static data references, constant pool addresses, and code labels
- compute the address as an offset from the GOT, whose base is in
- the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
- differentiate them from global data objects. The returned
- address is the PIC reg + an unspec constant.
-
- TARGET_LEGITIMATE_ADDRESS_P rejects symbolic references unless the PIC
- reg also appears in the address. */
-
-static rtx
-legitimize_pic_address (rtx orig, rtx reg)
-{
- rtx addr = orig;
- rtx new_rtx = orig;
-
-#if TARGET_MACHO
- if (TARGET_MACHO && !TARGET_64BIT)
- {
- if (reg == 0)
- reg = gen_reg_rtx (Pmode);
- /* Use the generic Mach-O PIC machinery. */
- return machopic_legitimize_pic_address (orig, GET_MODE (orig), reg);
- }
-#endif
-
- if (TARGET_64BIT && legitimate_pic_address_disp_p (addr))
- new_rtx = addr;
- else if (TARGET_64BIT
- && ix86_cmodel != CM_SMALL_PIC
- && gotoff_operand (addr, Pmode))
- {
- rtx tmpreg;
- /* This symbol may be referenced via a displacement from the PIC
- base address (@GOTOFF). */
-
- if (reload_in_progress)
- df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
- if (GET_CODE (addr) == CONST)
- addr = XEXP (addr, 0);
- if (GET_CODE (addr) == PLUS)
- {
- new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (addr, 0)),
- UNSPEC_GOTOFF);
- new_rtx = gen_rtx_PLUS (Pmode, new_rtx, XEXP (addr, 1));
- }
- else
- new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
- new_rtx = gen_rtx_CONST (Pmode, new_rtx);
- if (!reg)
- tmpreg = gen_reg_rtx (Pmode);
- else
- tmpreg = reg;
- emit_move_insn (tmpreg, new_rtx);
-
- if (reg != 0)
- {
- new_rtx = expand_simple_binop (Pmode, PLUS, reg, pic_offset_table_rtx,
- tmpreg, 1, OPTAB_DIRECT);
- new_rtx = reg;
- }
- else new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmpreg);
- }
- else if (!TARGET_64BIT && gotoff_operand (addr, Pmode))
- {
- /* This symbol may be referenced via a displacement from the PIC
- base address (@GOTOFF). */
-
- if (reload_in_progress)
- df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
- if (GET_CODE (addr) == CONST)
- addr = XEXP (addr, 0);
- if (GET_CODE (addr) == PLUS)
- {
- new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (addr, 0)),
- UNSPEC_GOTOFF);
- new_rtx = gen_rtx_PLUS (Pmode, new_rtx, XEXP (addr, 1));
- }
- else
- new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
- new_rtx = gen_rtx_CONST (Pmode, new_rtx);
- new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
-
- if (reg != 0)
- {
- emit_move_insn (reg, new_rtx);
- new_rtx = reg;
- }
- }
- else if ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (addr) == 0)
- /* We can't use @GOTOFF for text labels on VxWorks;
- see gotoff_operand. */
- || (TARGET_VXWORKS_RTP && GET_CODE (addr) == LABEL_REF))
- {
- if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
- {
- if (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_DLLIMPORT_P (addr))
- return legitimize_dllimport_symbol (addr, true);
- if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF
- && SYMBOL_REF_DLLIMPORT_P (XEXP (XEXP (addr, 0), 0)))
- {
- rtx t = legitimize_dllimport_symbol (XEXP (XEXP (addr, 0), 0), true);
- return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (addr, 0), 1));
- }
- }
-
- /* For x64 PE-COFF there is no GOT table. So we use address
- directly. */
- if (TARGET_64BIT && DEFAULT_ABI == MS_ABI)
- {
- new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_PCREL);
- new_rtx = gen_rtx_CONST (Pmode, new_rtx);
-
- if (reg == 0)
- reg = gen_reg_rtx (Pmode);
- emit_move_insn (reg, new_rtx);
- new_rtx = reg;
- }
- else if (TARGET_64BIT && ix86_cmodel != CM_LARGE_PIC)
- {
- new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTPCREL);
- new_rtx = gen_rtx_CONST (Pmode, new_rtx);
- new_rtx = gen_const_mem (Pmode, new_rtx);
- set_mem_alias_set (new_rtx, ix86_GOT_alias_set ());
-
- if (reg == 0)
- reg = gen_reg_rtx (Pmode);
- /* Use directly gen_movsi, otherwise the address is loaded
- into register for CSE. We don't want to CSE this addresses,
- instead we CSE addresses from the GOT table, so skip this. */
- emit_insn (gen_movsi (reg, new_rtx));
- new_rtx = reg;
- }
- else
- {
- /* This symbol must be referenced via a load from the
- Global Offset Table (@GOT). */
-
- if (reload_in_progress)
- df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
- new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
- new_rtx = gen_rtx_CONST (Pmode, new_rtx);
- if (TARGET_64BIT)
- new_rtx = force_reg (Pmode, new_rtx);
- new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
- new_rtx = gen_const_mem (Pmode, new_rtx);
- set_mem_alias_set (new_rtx, ix86_GOT_alias_set ());
-
- if (reg == 0)
- reg = gen_reg_rtx (Pmode);
- emit_move_insn (reg, new_rtx);
- new_rtx = reg;
- }
- }
- else
- {
- if (CONST_INT_P (addr)
- && !x86_64_immediate_operand (addr, VOIDmode))
- {
- if (reg)
- {
- emit_move_insn (reg, addr);
- new_rtx = reg;
- }
- else
- new_rtx = force_reg (Pmode, addr);
- }
- else if (GET_CODE (addr) == CONST)
- {
- addr = XEXP (addr, 0);
-
- /* We must match stuff we generate before. Assume the only
- unspecs that can get here are ours. Not that we could do
- anything with them anyway.... */
- if (GET_CODE (addr) == UNSPEC
- || (GET_CODE (addr) == PLUS
- && GET_CODE (XEXP (addr, 0)) == UNSPEC))
- return orig;
- gcc_assert (GET_CODE (addr) == PLUS);
- }
- if (GET_CODE (addr) == PLUS)
- {
- rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
-
- /* Check first to see if this is a constant offset from a @GOTOFF
- symbol reference. */
- if (gotoff_operand (op0, Pmode)
- && CONST_INT_P (op1))
- {
- if (!TARGET_64BIT)
- {
- if (reload_in_progress)
- df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
- new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
- UNSPEC_GOTOFF);
- new_rtx = gen_rtx_PLUS (Pmode, new_rtx, op1);
- new_rtx = gen_rtx_CONST (Pmode, new_rtx);
- new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
-
- if (reg != 0)
- {
- emit_move_insn (reg, new_rtx);
- new_rtx = reg;
- }
- }
- else
- {
- if (INTVAL (op1) < -16*1024*1024
- || INTVAL (op1) >= 16*1024*1024)
- {
- if (!x86_64_immediate_operand (op1, Pmode))
- op1 = force_reg (Pmode, op1);
- new_rtx = gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), op1);
- }
- }
- }
- else
- {
- rtx base = legitimize_pic_address (op0, reg);
- enum machine_mode mode = GET_MODE (base);
- new_rtx
- = legitimize_pic_address (op1, base == reg ? NULL_RTX : reg);
-
- if (CONST_INT_P (new_rtx))
- {
- if (INTVAL (new_rtx) < -16*1024*1024
- || INTVAL (new_rtx) >= 16*1024*1024)
- {
- if (!x86_64_immediate_operand (new_rtx, mode))
- new_rtx = force_reg (mode, new_rtx);
- new_rtx
- = gen_rtx_PLUS (mode, force_reg (mode, base), new_rtx);
- }
- else
- new_rtx = plus_constant (mode, base, INTVAL (new_rtx));
- }
- else
- {
- if (GET_CODE (new_rtx) == PLUS
- && CONSTANT_P (XEXP (new_rtx, 1)))
- {
- base = gen_rtx_PLUS (mode, base, XEXP (new_rtx, 0));
- new_rtx = XEXP (new_rtx, 1);
- }
- new_rtx = gen_rtx_PLUS (mode, base, new_rtx);
- }
- }
- }
- }
- return new_rtx;
-}
-
-/* Load the thread pointer. If TO_REG is true, force it into a register. */
-
-static rtx
-get_thread_pointer (enum machine_mode tp_mode, bool to_reg)
-{
- rtx tp = gen_rtx_UNSPEC (ptr_mode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
-
- if (GET_MODE (tp) != tp_mode)
- {
- gcc_assert (GET_MODE (tp) == SImode);
- gcc_assert (tp_mode == DImode);
-
- tp = gen_rtx_ZERO_EXTEND (tp_mode, tp);
- }
-
- if (to_reg)
- tp = copy_to_mode_reg (tp_mode, tp);
-
- return tp;
-}
-
-/* Construct the SYMBOL_REF for the tls_get_addr function. */
-
-static GTY(()) rtx ix86_tls_symbol;
-
-static rtx
-ix86_tls_get_addr (void)
-{
- if (!ix86_tls_symbol)
- {
- const char *sym
- = ((TARGET_ANY_GNU_TLS && !TARGET_64BIT)
- ? "___tls_get_addr" : "__tls_get_addr");
-
- ix86_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, sym);
- }
-
- return ix86_tls_symbol;
-}
-
-/* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol. */
-
-static GTY(()) rtx ix86_tls_module_base_symbol;
-
-rtx
-ix86_tls_module_base (void)
-{
- if (!ix86_tls_module_base_symbol)
- {
- ix86_tls_module_base_symbol
- = gen_rtx_SYMBOL_REF (Pmode, "_TLS_MODULE_BASE_");
-
- SYMBOL_REF_FLAGS (ix86_tls_module_base_symbol)
- |= TLS_MODEL_GLOBAL_DYNAMIC << SYMBOL_FLAG_TLS_SHIFT;
- }
-
- return ix86_tls_module_base_symbol;
-}
-
-/* A subroutine of ix86_legitimize_address and ix86_expand_move. FOR_MOV is
- false if we expect this to be used for a memory address and true if
- we expect to load the address into a register. */
-
-static rtx
-legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
-{
- rtx dest, base, off;
- rtx pic = NULL_RTX, tp = NULL_RTX;
- enum machine_mode tp_mode = Pmode;
- int type;
-
- switch (model)
- {
- case TLS_MODEL_GLOBAL_DYNAMIC:
- dest = gen_reg_rtx (Pmode);
-
- if (!TARGET_64BIT)
- {
- if (flag_pic)
- pic = pic_offset_table_rtx;
- else
- {
- pic = gen_reg_rtx (Pmode);
- emit_insn (gen_set_got (pic));
- }
- }
-
- if (TARGET_GNU2_TLS)
- {
- if (TARGET_64BIT)
- emit_insn (gen_tls_dynamic_gnu2_64 (dest, x));
- else
- emit_insn (gen_tls_dynamic_gnu2_32 (dest, x, pic));
-
- tp = get_thread_pointer (Pmode, true);
- dest = force_reg (Pmode, gen_rtx_PLUS (Pmode, tp, dest));
-
- if (GET_MODE (x) != Pmode)
- x = gen_rtx_ZERO_EXTEND (Pmode, x);
-
- set_unique_reg_note (get_last_insn (), REG_EQUAL, x);
- }
- else
- {
- rtx caddr = ix86_tls_get_addr ();
-
- if (TARGET_64BIT)
- {
- rtx rax = gen_rtx_REG (Pmode, AX_REG);
- rtx insns;
-
- start_sequence ();
- emit_call_insn
- (ix86_gen_tls_global_dynamic_64 (rax, x, caddr));
- insns = get_insns ();
- end_sequence ();
-
- if (GET_MODE (x) != Pmode)
- x = gen_rtx_ZERO_EXTEND (Pmode, x);
-
- RTL_CONST_CALL_P (insns) = 1;
- emit_libcall_block (insns, dest, rax, x);
- }
- else
- emit_insn (gen_tls_global_dynamic_32 (dest, x, pic, caddr));
- }
- break;
-
- case TLS_MODEL_LOCAL_DYNAMIC:
- base = gen_reg_rtx (Pmode);
-
- if (!TARGET_64BIT)
- {
- if (flag_pic)
- pic = pic_offset_table_rtx;
- else
- {
- pic = gen_reg_rtx (Pmode);
- emit_insn (gen_set_got (pic));
- }
- }
-
- if (TARGET_GNU2_TLS)
- {
- rtx tmp = ix86_tls_module_base ();
-
- if (TARGET_64BIT)
- emit_insn (gen_tls_dynamic_gnu2_64 (base, tmp));
- else
- emit_insn (gen_tls_dynamic_gnu2_32 (base, tmp, pic));
-
- tp = get_thread_pointer (Pmode, true);
- set_unique_reg_note (get_last_insn (), REG_EQUAL,
- gen_rtx_MINUS (Pmode, tmp, tp));
- }
- else
- {
- rtx caddr = ix86_tls_get_addr ();
-
- if (TARGET_64BIT)
- {
- rtx rax = gen_rtx_REG (Pmode, AX_REG);
- rtx insns, eqv;
-
- start_sequence ();
- emit_call_insn
- (ix86_gen_tls_local_dynamic_base_64 (rax, caddr));
- insns = get_insns ();
- end_sequence ();
-
- /* Attach a unique REG_EQUAL, to allow the RTL optimizers to
- share the LD_BASE result with other LD model accesses. */
- eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
- UNSPEC_TLS_LD_BASE);
-
- RTL_CONST_CALL_P (insns) = 1;
- emit_libcall_block (insns, base, rax, eqv);
- }
- else
- emit_insn (gen_tls_local_dynamic_base_32 (base, pic, caddr));
- }
-
- off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPOFF);
- off = gen_rtx_CONST (Pmode, off);
-
- dest = force_reg (Pmode, gen_rtx_PLUS (Pmode, base, off));
-
- if (TARGET_GNU2_TLS)
- {
- dest = force_reg (Pmode, gen_rtx_PLUS (Pmode, dest, tp));
-
- if (GET_MODE (x) != Pmode)
- x = gen_rtx_ZERO_EXTEND (Pmode, x);
-
- set_unique_reg_note (get_last_insn (), REG_EQUAL, x);
- }
- break;
-
- case TLS_MODEL_INITIAL_EXEC:
- if (TARGET_64BIT)
- {
- if (TARGET_SUN_TLS && !TARGET_X32)
- {
- /* The Sun linker took the AMD64 TLS spec literally
- and can only handle %rax as destination of the
- initial executable code sequence. */
-
- dest = gen_reg_rtx (DImode);
- emit_insn (gen_tls_initial_exec_64_sun (dest, x));
- return dest;
- }
-
- /* Generate DImode references to avoid %fs:(%reg32)
- problems and linker IE->LE relaxation bug. */
- tp_mode = DImode;
- pic = NULL;
- type = UNSPEC_GOTNTPOFF;
- }
- else if (flag_pic)
- {
- if (reload_in_progress)
- df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
- pic = pic_offset_table_rtx;
- type = TARGET_ANY_GNU_TLS ? UNSPEC_GOTNTPOFF : UNSPEC_GOTTPOFF;
- }
- else if (!TARGET_ANY_GNU_TLS)
- {
- pic = gen_reg_rtx (Pmode);
- emit_insn (gen_set_got (pic));
- type = UNSPEC_GOTTPOFF;
- }
- else
- {
- pic = NULL;
- type = UNSPEC_INDNTPOFF;
- }
-
- off = gen_rtx_UNSPEC (tp_mode, gen_rtvec (1, x), type);
- off = gen_rtx_CONST (tp_mode, off);
- if (pic)
- off = gen_rtx_PLUS (tp_mode, pic, off);
- off = gen_const_mem (tp_mode, off);
- set_mem_alias_set (off, ix86_GOT_alias_set ());
-
- if (TARGET_64BIT || TARGET_ANY_GNU_TLS)
- {
- base = get_thread_pointer (tp_mode,
- for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
- off = force_reg (tp_mode, off);
- return gen_rtx_PLUS (tp_mode, base, off);
- }
- else
- {
- base = get_thread_pointer (Pmode, true);
- dest = gen_reg_rtx (Pmode);
- emit_insn (ix86_gen_sub3 (dest, base, off));
- }
- break;
-
- case TLS_MODEL_LOCAL_EXEC:
- off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x),
- (TARGET_64BIT || TARGET_ANY_GNU_TLS)
- ? UNSPEC_NTPOFF : UNSPEC_TPOFF);
- off = gen_rtx_CONST (Pmode, off);
-
- if (TARGET_64BIT || TARGET_ANY_GNU_TLS)
- {
- base = get_thread_pointer (Pmode,
- for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
- return gen_rtx_PLUS (Pmode, base, off);
- }
- else
- {
- base = get_thread_pointer (Pmode, true);
- dest = gen_reg_rtx (Pmode);
- emit_insn (ix86_gen_sub3 (dest, base, off));
- }
- break;
-
- default:
- gcc_unreachable ();
- }
-
- return dest;
-}
-
-/* Create or return the unique __imp_DECL dllimport symbol corresponding
- to symbol DECL. */
-
-static GTY((if_marked ("tree_map_marked_p"), param_is (struct tree_map)))
- htab_t dllimport_map;
-
-static tree
-get_dllimport_decl (tree decl)
-{
- struct tree_map *h, in;
- void **loc;
- const char *name;
- const char *prefix;
- size_t namelen, prefixlen;
- char *imp_name;
- tree to;
- rtx rtl;
-
- if (!dllimport_map)
- dllimport_map = htab_create_ggc (512, tree_map_hash, tree_map_eq, 0);
-
- in.hash = htab_hash_pointer (decl);
- in.base.from = decl;
- loc = htab_find_slot_with_hash (dllimport_map, &in, in.hash, INSERT);
- h = (struct tree_map *) *loc;
- if (h)
- return h->to;
-
- *loc = h = ggc_alloc_tree_map ();
- h->hash = in.hash;
- h->base.from = decl;
- h->to = to = build_decl (DECL_SOURCE_LOCATION (decl),
- VAR_DECL, NULL, ptr_type_node);
- DECL_ARTIFICIAL (to) = 1;
- DECL_IGNORED_P (to) = 1;
- DECL_EXTERNAL (to) = 1;
- TREE_READONLY (to) = 1;
-
- name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
- name = targetm.strip_name_encoding (name);
- prefix = name[0] == FASTCALL_PREFIX || user_label_prefix[0] == 0
- ? "*__imp_" : "*__imp__";
- namelen = strlen (name);
- prefixlen = strlen (prefix);
- imp_name = (char *) alloca (namelen + prefixlen + 1);
- memcpy (imp_name, prefix, prefixlen);
- memcpy (imp_name + prefixlen, name, namelen + 1);
-
- name = ggc_alloc_string (imp_name, namelen + prefixlen);
- rtl = gen_rtx_SYMBOL_REF (Pmode, name);
- SET_SYMBOL_REF_DECL (rtl, to);
- SYMBOL_REF_FLAGS (rtl) = SYMBOL_FLAG_LOCAL;
-
- rtl = gen_const_mem (Pmode, rtl);
- set_mem_alias_set (rtl, ix86_GOT_alias_set ());
-
- SET_DECL_RTL (to, rtl);
- SET_DECL_ASSEMBLER_NAME (to, get_identifier (name));
-
- return to;
-}
-
-/* Expand SYMBOL into its corresponding dllimport symbol. WANT_REG is
- true if we require the result be a register. */
-
-static rtx
-legitimize_dllimport_symbol (rtx symbol, bool want_reg)
-{
- tree imp_decl;
- rtx x;
-
- gcc_assert (SYMBOL_REF_DECL (symbol));
- imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol));
-
- x = DECL_RTL (imp_decl);
- if (want_reg)
- x = force_reg (Pmode, x);
- return x;
-}
-
-/* Try machine-dependent ways of modifying an illegitimate address
- to be legitimate. If we find one, return the new, valid address.
- This macro is used in only one place: `memory_address' in explow.c.
-
- OLDX is the address as it was before break_out_memory_refs was called.
- In some cases it is useful to look at this to decide what needs to be done.
-
- It is always safe for this macro to do nothing. It exists to recognize
- opportunities to optimize the output.
-
- For the 80386, we handle X+REG by loading X into a register R and
- using R+REG. R will go in a general 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 a general reg.
-
- When -fpic is used, special handling is needed for symbolic references.
- See comments by legitimize_pic_address in i386.c for details. */
-
-static rtx
-ix86_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
- enum machine_mode mode)
-{
- int changed = 0;
- unsigned log;
-
- log = GET_CODE (x) == SYMBOL_REF ? SYMBOL_REF_TLS_MODEL (x) : 0;
- if (log)
- return legitimize_tls_address (x, (enum tls_model) log, false);
- if (GET_CODE (x) == CONST
- && GET_CODE (XEXP (x, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
- && (log = SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0))))
- {
- rtx t = legitimize_tls_address (XEXP (XEXP (x, 0), 0),
- (enum tls_model) log, false);
- return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (x, 0), 1));
- }
-
- if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
- {
- if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_DLLIMPORT_P (x))
- return legitimize_dllimport_symbol (x, true);
- if (GET_CODE (x) == CONST
- && GET_CODE (XEXP (x, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
- && SYMBOL_REF_DLLIMPORT_P (XEXP (XEXP (x, 0), 0)))
- {
- rtx t = legitimize_dllimport_symbol (XEXP (XEXP (x, 0), 0), true);
- return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (x, 0), 1));
- }
- }
-
- if (flag_pic && SYMBOLIC_CONST (x))
- return legitimize_pic_address (x, 0);
-
-#if TARGET_MACHO
- if (MACHO_DYNAMIC_NO_PIC_P && SYMBOLIC_CONST (x))
- return machopic_indirect_data_reference (x, 0);
-#endif
-
- /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
- if (GET_CODE (x) == ASHIFT
- && CONST_INT_P (XEXP (x, 1))
- && (unsigned HOST_WIDE_INT) INTVAL (XEXP (x, 1)) < 4)
- {
- changed = 1;
- log = INTVAL (XEXP (x, 1));
- x = gen_rtx_MULT (Pmode, force_reg (Pmode, XEXP (x, 0)),
- GEN_INT (1 << log));
- }
-
- if (GET_CODE (x) == PLUS)
- {
- /* Canonicalize shifts by 0, 1, 2, 3 into multiply. */
-
- if (GET_CODE (XEXP (x, 0)) == ASHIFT
- && CONST_INT_P (XEXP (XEXP (x, 0), 1))
- && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (x, 0), 1)) < 4)
- {
- changed = 1;
- log = INTVAL (XEXP (XEXP (x, 0), 1));
- XEXP (x, 0) = gen_rtx_MULT (Pmode,
- force_reg (Pmode, XEXP (XEXP (x, 0), 0)),
- GEN_INT (1 << log));
- }
-
- if (GET_CODE (XEXP (x, 1)) == ASHIFT
- && CONST_INT_P (XEXP (XEXP (x, 1), 1))
- && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (x, 1), 1)) < 4)
- {
- changed = 1;
- log = INTVAL (XEXP (XEXP (x, 1), 1));
- XEXP (x, 1) = gen_rtx_MULT (Pmode,
- force_reg (Pmode, XEXP (XEXP (x, 1), 0)),
- GEN_INT (1 << log));
- }
-
- /* Put multiply first if it isn't already. */
- if (GET_CODE (XEXP (x, 1)) == MULT)
- {
- rtx tmp = XEXP (x, 0);
- XEXP (x, 0) = XEXP (x, 1);
- XEXP (x, 1) = tmp;
- changed = 1;
- }
-
- /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
- into (plus (plus (mult (reg) (const)) (reg)) (const)). This can be
- created by virtual register instantiation, register elimination, and
- similar optimizations. */
- if (GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == PLUS)
- {
- changed = 1;
- x = gen_rtx_PLUS (Pmode,
- gen_rtx_PLUS (Pmode, XEXP (x, 0),
- XEXP (XEXP (x, 1), 0)),
- XEXP (XEXP (x, 1), 1));
- }
-
- /* Canonicalize
- (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
- into (plus (plus (mult (reg) (const)) (reg)) (const)). */
- else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
- && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
- && CONSTANT_P (XEXP (x, 1)))
- {
- rtx constant;
- rtx other = NULL_RTX;
-
- if (CONST_INT_P (XEXP (x, 1)))
- {
- constant = XEXP (x, 1);
- other = XEXP (XEXP (XEXP (x, 0), 1), 1);
- }
- else if (CONST_INT_P (XEXP (XEXP (XEXP (x, 0), 1), 1)))
- {
- constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
- other = XEXP (x, 1);
- }
- else
- constant = 0;
-
- if (constant)
- {
- changed = 1;
- x = gen_rtx_PLUS (Pmode,
- gen_rtx_PLUS (Pmode, XEXP (XEXP (x, 0), 0),
- XEXP (XEXP (XEXP (x, 0), 1), 0)),
- plus_constant (Pmode, other,
- INTVAL (constant)));
- }
- }
-
- if (changed && ix86_legitimate_address_p (mode, x, false))
- return x;
-
- if (GET_CODE (XEXP (x, 0)) == MULT)
- {
- changed = 1;
- XEXP (x, 0) = force_operand (XEXP (x, 0), 0);
- }
-
- if (GET_CODE (XEXP (x, 1)) == MULT)
- {
- changed = 1;
- XEXP (x, 1) = force_operand (XEXP (x, 1), 0);
- }
-
- if (changed
- && REG_P (XEXP (x, 1))
- && REG_P (XEXP (x, 0)))
- return x;
-
- if (flag_pic && SYMBOLIC_CONST (XEXP (x, 1)))
- {
- changed = 1;
- x = legitimize_pic_address (x, 0);
- }
-
- if (changed && ix86_legitimate_address_p (mode, x, false))
- return x;
-
- if (REG_P (XEXP (x, 0)))
- {
- rtx temp = gen_reg_rtx (Pmode);
- rtx val = force_operand (XEXP (x, 1), temp);
- if (val != temp)
- {
- val = convert_to_mode (Pmode, val, 1);
- emit_move_insn (temp, val);
- }
-
- XEXP (x, 1) = temp;
- return x;
- }
-
- else if (REG_P (XEXP (x, 1)))
- {
- rtx temp = gen_reg_rtx (Pmode);
- rtx val = force_operand (XEXP (x, 0), temp);
- if (val != temp)
- {
- val = convert_to_mode (Pmode, val, 1);
- emit_move_insn (temp, val);
- }
-
- XEXP (x, 0) = temp;
- return x;
- }
- }
-
- return x;
-}
-
-/* Print an integer constant expression in assembler syntax. Addition
- and subtraction are the only arithmetic that may appear in these
- expressions. FILE is the stdio stream to write to, X is the rtx, and
- CODE is the operand print code from the output string. */
-
-static void
-output_pic_addr_const (FILE *file, rtx x, int code)
-{
- char buf[256];
-
- switch (GET_CODE (x))
- {
- case PC:
- gcc_assert (flag_pic);
- putc ('.', file);
- break;
-
- case SYMBOL_REF:
- if (TARGET_64BIT || ! TARGET_MACHO_BRANCH_ISLANDS)
- output_addr_const (file, x);
- else
- {
- const char *name = XSTR (x, 0);
-
- /* Mark the decl as referenced so that cgraph will
- output the function. */
- if (SYMBOL_REF_DECL (x))
- mark_decl_referenced (SYMBOL_REF_DECL (x));
-
-#if TARGET_MACHO
- if (MACHOPIC_INDIRECT
- && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
- name = machopic_indirection_name (x, /*stub_p=*/true);
-#endif
- assemble_name (file, name);
- }
- if (!TARGET_MACHO && !(TARGET_64BIT && DEFAULT_ABI == MS_ABI)
- && code == 'P' && ! SYMBOL_REF_LOCAL_P (x))
- fputs ("@PLT", file);
- break;
-
- case LABEL_REF:
- x = XEXP (x, 0);
- /* FALLTHRU */
- case CODE_LABEL:
- ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
- assemble_name (asm_out_file, buf);
- break;
-
- case CONST_INT:
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
- break;
-
- case CONST:
- /* This used to output parentheses around the expression,
- but that does not work on the 386 (either ATT or BSD assembler). */
- output_pic_addr_const (file, XEXP (x, 0), code);
- break;
-
- case CONST_DOUBLE:
- if (GET_MODE (x) == VOIDmode)
- {
- /* We can use %d if the number is <32 bits and positive. */
- if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
- fprintf (file, "0x%lx%08lx",
- (unsigned long) CONST_DOUBLE_HIGH (x),
- (unsigned long) CONST_DOUBLE_LOW (x));
- else
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
- }
- else
- /* We can't handle floating point constants;
- TARGET_PRINT_OPERAND must handle them. */
- output_operand_lossage ("floating constant misused");
- break;
-
- case PLUS:
- /* Some assemblers need integer constants to appear first. */
- if (CONST_INT_P (XEXP (x, 0)))
- {
- output_pic_addr_const (file, XEXP (x, 0), code);
- putc ('+', file);
- output_pic_addr_const (file, XEXP (x, 1), code);
- }
- else
- {
- gcc_assert (CONST_INT_P (XEXP (x, 1)));
- output_pic_addr_const (file, XEXP (x, 1), code);
- putc ('+', file);
- output_pic_addr_const (file, XEXP (x, 0), code);
- }
- break;
-
- case MINUS:
- if (!TARGET_MACHO)
- putc (ASSEMBLER_DIALECT == ASM_INTEL ? '(' : '[', file);
- output_pic_addr_const (file, XEXP (x, 0), code);
- putc ('-', file);
- output_pic_addr_const (file, XEXP (x, 1), code);
- if (!TARGET_MACHO)
- putc (ASSEMBLER_DIALECT == ASM_INTEL ? ')' : ']', file);
- break;
-
- case UNSPEC:
- if (XINT (x, 1) == UNSPEC_STACK_CHECK)
- {
- bool f = i386_asm_output_addr_const_extra (file, x);
- gcc_assert (f);
- break;
- }
-
- gcc_assert (XVECLEN (x, 0) == 1);
- output_pic_addr_const (file, XVECEXP (x, 0, 0), code);
- switch (XINT (x, 1))
- {
- case UNSPEC_GOT:
- fputs ("@GOT", file);
- break;
- case UNSPEC_GOTOFF:
- fputs ("@GOTOFF", file);
- break;
- case UNSPEC_PLTOFF:
- fputs ("@PLTOFF", file);
- break;
- case UNSPEC_PCREL:
- fputs (ASSEMBLER_DIALECT == ASM_ATT ?
- "(%rip)" : "[rip]", file);
- break;
- case UNSPEC_GOTPCREL:
- fputs (ASSEMBLER_DIALECT == ASM_ATT ?
- "@GOTPCREL(%rip)" : "@GOTPCREL[rip]", file);
- break;
- case UNSPEC_GOTTPOFF:
- /* FIXME: This might be @TPOFF in Sun ld too. */
- fputs ("@gottpoff", file);
- break;
- case UNSPEC_TPOFF:
- fputs ("@tpoff", file);
- break;
- case UNSPEC_NTPOFF:
- if (TARGET_64BIT)
- fputs ("@tpoff", file);
- else
- fputs ("@ntpoff", file);
- break;
- case UNSPEC_DTPOFF:
- fputs ("@dtpoff", file);
- break;
- case UNSPEC_GOTNTPOFF:
- if (TARGET_64BIT)
- fputs (ASSEMBLER_DIALECT == ASM_ATT ?
- "@gottpoff(%rip)": "@gottpoff[rip]", file);
- else
- fputs ("@gotntpoff", file);
- break;
- case UNSPEC_INDNTPOFF:
- fputs ("@indntpoff", file);
- break;
-#if TARGET_MACHO
- case UNSPEC_MACHOPIC_OFFSET:
- putc ('-', file);
- machopic_output_function_base_name (file);
- break;
-#endif
- default:
- output_operand_lossage ("invalid UNSPEC as operand");
- break;
- }
- break;
-
- default:
- output_operand_lossage ("invalid expression as operand");
- }
-}
-
-/* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
- We need to emit DTP-relative relocations. */
-
-static void ATTRIBUTE_UNUSED
-i386_output_dwarf_dtprel (FILE *file, int size, rtx x)
-{
- fputs (ASM_LONG, file);
- output_addr_const (file, x);
- fputs ("@dtpoff", file);
- switch (size)
- {
- case 4:
- break;
- case 8:
- fputs (", 0", file);
- break;
- default:
- gcc_unreachable ();
- }
-}
-
-/* Return true if X is a representation of the PIC register. This copes
- with calls from ix86_find_base_term, where the register might have
- been replaced by a cselib value. */
-
-static bool
-ix86_pic_register_p (rtx x)
-{
- if (GET_CODE (x) == VALUE && CSELIB_VAL_PTR (x))
- return (pic_offset_table_rtx
- && rtx_equal_for_cselib_p (x, pic_offset_table_rtx));
- else
- return REG_P (x) && REGNO (x) == PIC_OFFSET_TABLE_REGNUM;
-}
-
-/* Helper function for ix86_delegitimize_address.
- Attempt to delegitimize TLS local-exec accesses. */
-
-static rtx
-ix86_delegitimize_tls_address (rtx orig_x)
-{
- rtx x = orig_x, unspec;
- struct ix86_address addr;
-
- if (!TARGET_TLS_DIRECT_SEG_REFS)
- return orig_x;
- if (MEM_P (x))
- x = XEXP (x, 0);
- if (GET_CODE (x) != PLUS || GET_MODE (x) != Pmode)
- return orig_x;
- if (ix86_decompose_address (x, &addr) == 0
- || addr.seg != (TARGET_64BIT ? SEG_FS : SEG_GS)
- || addr.disp == NULL_RTX
- || GET_CODE (addr.disp) != CONST)
- return orig_x;
- unspec = XEXP (addr.disp, 0);
- if (GET_CODE (unspec) == PLUS && CONST_INT_P (XEXP (unspec, 1)))
- unspec = XEXP (unspec, 0);
- if (GET_CODE (unspec) != UNSPEC || XINT (unspec, 1) != UNSPEC_NTPOFF)
- return orig_x;
- x = XVECEXP (unspec, 0, 0);
- gcc_assert (GET_CODE (x) == SYMBOL_REF);
- if (unspec != XEXP (addr.disp, 0))
- x = gen_rtx_PLUS (Pmode, x, XEXP (XEXP (addr.disp, 0), 1));
- if (addr.index)
- {
- rtx idx = addr.index;
- if (addr.scale != 1)
- idx = gen_rtx_MULT (Pmode, idx, GEN_INT (addr.scale));
- x = gen_rtx_PLUS (Pmode, idx, x);
- }
- if (addr.base)
- x = gen_rtx_PLUS (Pmode, addr.base, x);
- if (MEM_P (orig_x))
- x = replace_equiv_address_nv (orig_x, x);
- return x;
-}
-
-/* In the name of slightly smaller debug output, and to cater to
- general assembler lossage, recognize PIC+GOTOFF and turn it back
- into a direct symbol reference.
-
- On Darwin, this is necessary to avoid a crash, because Darwin
- has a different PIC label for each routine but the DWARF debugging
- information is not associated with any particular routine, so it's
- necessary to remove references to the PIC label from RTL stored by
- the DWARF output code. */
-
-static rtx
-ix86_delegitimize_address (rtx x)
-{
- rtx orig_x = delegitimize_mem_from_attrs (x);
- /* addend is NULL or some rtx if x is something+GOTOFF where
- something doesn't include the PIC register. */
- rtx addend = NULL_RTX;
- /* reg_addend is NULL or a multiple of some register. */
- rtx reg_addend = NULL_RTX;
- /* const_addend is NULL or a const_int. */
- rtx const_addend = NULL_RTX;
- /* This is the result, or NULL. */
- rtx result = NULL_RTX;
-
- x = orig_x;
-
- if (MEM_P (x))
- x = XEXP (x, 0);
-
- if (TARGET_64BIT)
- {
- if (GET_CODE (x) == CONST
- && GET_CODE (XEXP (x, 0)) == PLUS
- && GET_MODE (XEXP (x, 0)) == Pmode
- && CONST_INT_P (XEXP (XEXP (x, 0), 1))
- && GET_CODE (XEXP (XEXP (x, 0), 0)) == UNSPEC
- && XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_PCREL)
- {
- rtx x2 = XVECEXP (XEXP (XEXP (x, 0), 0), 0, 0);
- x = gen_rtx_PLUS (Pmode, XEXP (XEXP (x, 0), 1), x2);
- if (MEM_P (orig_x))
- x = replace_equiv_address_nv (orig_x, x);
- return x;
- }
- if (GET_CODE (x) != CONST
- || GET_CODE (XEXP (x, 0)) != UNSPEC
- || (XINT (XEXP (x, 0), 1) != UNSPEC_GOTPCREL
- && XINT (XEXP (x, 0), 1) != UNSPEC_PCREL)
- || (!MEM_P (orig_x) && XINT (XEXP (x, 0), 1) != UNSPEC_PCREL))
- return ix86_delegitimize_tls_address (orig_x);
- x = XVECEXP (XEXP (x, 0), 0, 0);
- if (GET_MODE (orig_x) != GET_MODE (x) && MEM_P (orig_x))
- {
- x = simplify_gen_subreg (GET_MODE (orig_x), x,
- GET_MODE (x), 0);
- if (x == NULL_RTX)
- return orig_x;
- }
- return x;
- }
-
- if (GET_CODE (x) != PLUS
- || GET_CODE (XEXP (x, 1)) != CONST)
- return ix86_delegitimize_tls_address (orig_x);
-
- if (ix86_pic_register_p (XEXP (x, 0)))
- /* %ebx + GOT/GOTOFF */
- ;
- else if (GET_CODE (XEXP (x, 0)) == PLUS)
- {
- /* %ebx + %reg * scale + GOT/GOTOFF */
- reg_addend = XEXP (x, 0);
- if (ix86_pic_register_p (XEXP (reg_addend, 0)))
- reg_addend = XEXP (reg_addend, 1);
- else if (ix86_pic_register_p (XEXP (reg_addend, 1)))
- reg_addend = XEXP (reg_addend, 0);
- else
- {
- reg_addend = NULL_RTX;
- addend = XEXP (x, 0);
- }
- }
- else
- addend = XEXP (x, 0);
-
- x = XEXP (XEXP (x, 1), 0);
- if (GET_CODE (x) == PLUS
- && CONST_INT_P (XEXP (x, 1)))
- {
- const_addend = XEXP (x, 1);
- x = XEXP (x, 0);
- }
-
- if (GET_CODE (x) == UNSPEC
- && ((XINT (x, 1) == UNSPEC_GOT && MEM_P (orig_x) && !addend)
- || (XINT (x, 1) == UNSPEC_GOTOFF && !MEM_P (orig_x))))
- result = XVECEXP (x, 0, 0);
-
- if (TARGET_MACHO && darwin_local_data_pic (x)
- && !MEM_P (orig_x))
- result = XVECEXP (x, 0, 0);
-
- if (! result)
- return ix86_delegitimize_tls_address (orig_x);
-
- if (const_addend)
- result = gen_rtx_CONST (Pmode, gen_rtx_PLUS (Pmode, result, const_addend));
- if (reg_addend)
- result = gen_rtx_PLUS (Pmode, reg_addend, result);
- if (addend)
- {
- /* If the rest of original X doesn't involve the PIC register, add
- addend and subtract pic_offset_table_rtx. This can happen e.g.
- for code like:
- leal (%ebx, %ecx, 4), %ecx
- ...
- movl foo@GOTOFF(%ecx), %edx
- in which case we return (%ecx - %ebx) + foo. */
- if (pic_offset_table_rtx)
- result = gen_rtx_PLUS (Pmode, gen_rtx_MINUS (Pmode, copy_rtx (addend),
- pic_offset_table_rtx),
- result);
- else
- return orig_x;
- }
- if (GET_MODE (orig_x) != Pmode && MEM_P (orig_x))
- {
- result = simplify_gen_subreg (GET_MODE (orig_x), result, Pmode, 0);
- if (result == NULL_RTX)
- return orig_x;
- }
- return result;
-}
-
-/* If X is a machine specific address (i.e. a symbol or label being
- referenced as a displacement from the GOT implemented using an
- UNSPEC), then return the base term. Otherwise return X. */
-
-rtx
-ix86_find_base_term (rtx x)
-{
- rtx term;
-
- if (TARGET_64BIT)
- {
- if (GET_CODE (x) != CONST)
- return x;
- term = XEXP (x, 0);
- if (GET_CODE (term) == PLUS
- && (CONST_INT_P (XEXP (term, 1))
- || GET_CODE (XEXP (term, 1)) == CONST_DOUBLE))
- term = XEXP (term, 0);
- if (GET_CODE (term) != UNSPEC
- || (XINT (term, 1) != UNSPEC_GOTPCREL
- && XINT (term, 1) != UNSPEC_PCREL))
- return x;
-
- return XVECEXP (term, 0, 0);
- }
-
- return ix86_delegitimize_address (x);
-}
-
-static void
-put_condition_code (enum rtx_code code, enum machine_mode mode, bool reverse,
- bool fp, FILE *file)
-{
- const char *suffix;
-
- if (mode == CCFPmode || mode == CCFPUmode)
- {
- code = ix86_fp_compare_code_to_integer (code);
- mode = CCmode;
- }
- if (reverse)
- code = reverse_condition (code);
-
- switch (code)
- {
- case EQ:
- switch (mode)
- {
- case CCAmode:
- suffix = "a";
- break;
-
- case CCCmode:
- suffix = "c";
- break;
-
- case CCOmode:
- suffix = "o";
- break;
-
- case CCSmode:
- suffix = "s";
- break;
-
- default:
- suffix = "e";
- }
- break;
- case NE:
- switch (mode)
- {
- case CCAmode:
- suffix = "na";
- break;
-
- case CCCmode:
- suffix = "nc";
- break;
-
- case CCOmode:
- suffix = "no";
- break;
-
- case CCSmode:
- suffix = "ns";
- break;
-
- default:
- suffix = "ne";
- }
- break;
- case GT:
- gcc_assert (mode == CCmode || mode == CCNOmode || mode == CCGCmode);
- suffix = "g";
- break;
- case GTU:
- /* ??? Use "nbe" instead of "a" for fcmov lossage on some assemblers.
- Those same assemblers have the same but opposite lossage on cmov. */
- if (mode == CCmode)
- suffix = fp ? "nbe" : "a";
- else if (mode == CCCmode)
- suffix = "b";
- else
- gcc_unreachable ();
- break;
- case LT:
- switch (mode)
- {
- case CCNOmode:
- case CCGOCmode:
- suffix = "s";
- break;
-
- case CCmode:
- case CCGCmode:
- suffix = "l";
- break;
-
- default:
- gcc_unreachable ();
- }
- break;
- case LTU:
- gcc_assert (mode == CCmode || mode == CCCmode);
- suffix = "b";
- break;
- case GE:
- switch (mode)
- {
- case CCNOmode:
- case CCGOCmode:
- suffix = "ns";
- break;
-
- case CCmode:
- case CCGCmode:
- suffix = "ge";
- break;
-
- default:
- gcc_unreachable ();
- }
- break;
- case GEU:
- /* ??? As above. */
- gcc_assert (mode == CCmode || mode == CCCmode);
- suffix = fp ? "nb" : "ae";
- break;
- case LE:
- gcc_assert (mode == CCmode || mode == CCGCmode || mode == CCNOmode);
- suffix = "le";
- break;
- case LEU:
- /* ??? As above. */
- if (mode == CCmode)
- suffix = "be";
- else if (mode == CCCmode)
- suffix = fp ? "nb" : "ae";
- else
- gcc_unreachable ();
- break;
- case UNORDERED:
- suffix = fp ? "u" : "p";
- break;
- case ORDERED:
- suffix = fp ? "nu" : "np";
- break;
- default:
- gcc_unreachable ();
- }
- fputs (suffix, file);
-}
-
-/* Print the name of register X to FILE based on its machine mode and number.
- If CODE is 'w', pretend the mode is HImode.
- If CODE is 'b', pretend the mode is QImode.
- If CODE is 'k', pretend the mode is SImode.
- If CODE is 'q', pretend the mode is DImode.
- If CODE is 'x', pretend the mode is V4SFmode.
- If CODE is 't', pretend the mode is V8SFmode.
- If CODE is 'h', pretend the reg is the 'high' byte register.
- If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op.
- If CODE is 'd', duplicate the operand for AVX instruction.
- */
-
-void
-print_reg (rtx x, int code, FILE *file)
-{
- const char *reg;
- unsigned int regno;
- bool duplicated = code == 'd' && TARGET_AVX;
-
- if (ASSEMBLER_DIALECT == ASM_ATT)
- putc ('%', file);
-
- if (x == pc_rtx)
- {
- gcc_assert (TARGET_64BIT);
- fputs ("rip", file);
- return;
- }
-
- regno = true_regnum (x);
- gcc_assert (regno != ARG_POINTER_REGNUM
- && regno != FRAME_POINTER_REGNUM
- && regno != FLAGS_REG
- && regno != FPSR_REG
- && regno != FPCR_REG);
-
- if (code == 'w' || MMX_REG_P (x))
- code = 2;
- else if (code == 'b')
- code = 1;
- else if (code == 'k')
- code = 4;
- else if (code == 'q')
- code = 8;
- else if (code == 'y')
- code = 3;
- else if (code == 'h')
- code = 0;
- else if (code == 'x')
- code = 16;
- else if (code == 't')
- code = 32;
- else
- code = GET_MODE_SIZE (GET_MODE (x));
-
- /* Irritatingly, AMD extended registers use different naming convention
- from the normal registers: "r%d[bwd]" */
- if (REX_INT_REGNO_P (regno))
- {
- gcc_assert (TARGET_64BIT);
- putc ('r', file);
- fprint_ul (file, regno - FIRST_REX_INT_REG + 8);
- switch (code)
- {
- case 0:
- error ("extended registers have no high halves");
- break;
- case 1:
- putc ('b', file);
- break;
- case 2:
- putc ('w', file);
- break;
- case 4:
- putc ('d', file);
- break;
- case 8:
- /* no suffix */
- break;
- default:
- error ("unsupported operand size for extended register");
- break;
- }
- return;
- }
-
- reg = NULL;
- switch (code)
- {
- case 3:
- if (STACK_TOP_P (x))
- {
- reg = "st(0)";
- break;
- }
- /* FALLTHRU */
- case 8:
- case 4:
- case 12:
- if (! ANY_FP_REG_P (x))
- putc (code == 8 && TARGET_64BIT ? 'r' : 'e', file);
- /* FALLTHRU */
- case 16:
- case 2:
- normal:
- reg = hi_reg_name[regno];
- break;
- case 1:
- if (regno >= ARRAY_SIZE (qi_reg_name))
- goto normal;
- reg = qi_reg_name[regno];
- break;
- case 0:
- if (regno >= ARRAY_SIZE (qi_high_reg_name))
- goto normal;
- reg = qi_high_reg_name[regno];
- break;
- case 32:
- if (SSE_REG_P (x))
- {
- gcc_assert (!duplicated);
- putc ('y', file);
- fputs (hi_reg_name[regno] + 1, file);
- return;
- }
- break;
- default:
- gcc_unreachable ();
- }
-
- fputs (reg, file);
- if (duplicated)
- {
- if (ASSEMBLER_DIALECT == ASM_ATT)
- fprintf (file, ", %%%s", reg);
- else
- fprintf (file, ", %s", reg);
- }
-}
-
-/* Locate some local-dynamic symbol still in use by this function
- so that we can print its name in some tls_local_dynamic_base
- pattern. */
-
-static int
-get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
-{
- rtx x = *px;
-
- if (GET_CODE (x) == SYMBOL_REF
- && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
- {
- cfun->machine->some_ld_name = XSTR (x, 0);
- return 1;
- }
-
- return 0;
-}
-
-static const char *
-get_some_local_dynamic_name (void)
-{
- rtx insn;
-
- if (cfun->machine->some_ld_name)
- return cfun->machine->some_ld_name;
-
- for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
- if (NONDEBUG_INSN_P (insn)
- && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
- return cfun->machine->some_ld_name;
-
- return NULL;
-}
-
-/* Meaning of CODE:
- L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
- C -- print opcode suffix for set/cmov insn.
- c -- like C, but print reversed condition
- F,f -- likewise, but for floating-point.
- O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
- otherwise nothing
- R -- print the prefix for register names.
- z -- print the opcode suffix for the size of the current operand.
- Z -- likewise, with special suffixes for x87 instructions.
- * -- print a star (in certain assembler syntax)
- A -- print an absolute memory reference.
- E -- print address with DImode register names if TARGET_64BIT.
- w -- print the operand as if it's a "word" (HImode) even if it isn't.
- s -- print a shift double count, followed by the assemblers argument
- delimiter.
- b -- print the QImode name of the register for the indicated operand.
- %b0 would print %al if operands[0] is reg 0.
- w -- likewise, print the HImode name of the register.
- k -- likewise, print the SImode name of the register.
- q -- likewise, print the DImode name of the register.
- x -- likewise, print the V4SFmode name of the register.
- t -- likewise, print the V8SFmode name of the register.
- h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
- y -- print "st(0)" instead of "st" as a register.
- d -- print duplicated register operand for AVX instruction.
- D -- print condition for SSE cmp instruction.
- P -- if PIC, print an @PLT suffix.
- p -- print raw symbol name.
- X -- don't print any sort of PIC '@' suffix for a symbol.
- & -- print some in-use local-dynamic symbol name.
- H -- print a memory address offset by 8; used for sse high-parts
- Y -- print condition for XOP pcom* instruction.
- + -- print a branch hint as 'cs' or 'ds' prefix
- ; -- print a semicolon (after prefixes due to bug in older gas).
- ~ -- print "i" if TARGET_AVX2, "f" otherwise.
- @ -- print a segment register of thread base pointer load
- ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
- */
-
-void
-ix86_print_operand (FILE *file, rtx x, int code)
-{
- if (code)
- {
- switch (code)
- {
- case 'A':
- switch (ASSEMBLER_DIALECT)
- {
- case ASM_ATT:
- putc ('*', file);
- break;
-
- case ASM_INTEL:
- /* Intel syntax. For absolute addresses, registers should not
- be surrounded by braces. */
- if (!REG_P (x))
- {
- putc ('[', file);
- ix86_print_operand (file, x, 0);
- putc (']', file);
- return;
- }
- break;
-
- default:
- gcc_unreachable ();
- }
-
- ix86_print_operand (file, x, 0);
- return;
-
- case 'E':
- /* Wrap address in an UNSPEC to declare special handling. */
- if (TARGET_64BIT)
- x = gen_rtx_UNSPEC (DImode, gen_rtvec (1, x), UNSPEC_LEA_ADDR);
-
- output_address (x);
- return;
-
- case 'L':
- if (ASSEMBLER_DIALECT == ASM_ATT)
- putc ('l', file);
- return;
-
- case 'W':
- if (ASSEMBLER_DIALECT == ASM_ATT)
- putc ('w', file);
- return;
-
- case 'B':
- if (ASSEMBLER_DIALECT == ASM_ATT)
- putc ('b', file);
- return;
-
- case 'Q':
- if (ASSEMBLER_DIALECT == ASM_ATT)
- putc ('l', file);
- return;
-
- case 'S':
- if (ASSEMBLER_DIALECT == ASM_ATT)
- putc ('s', file);
- return;
-
- case 'T':
- if (ASSEMBLER_DIALECT == ASM_ATT)
- putc ('t', file);
- return;
-
- case 'O':
-#ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX
- if (ASSEMBLER_DIALECT != ASM_ATT)
- return;
-
- switch (GET_MODE_SIZE (GET_MODE (x)))
- {
- case 2:
- putc ('w', file);
- break;
-
- case 4:
- putc ('l', file);
- break;
-
- case 8:
- putc ('q', file);
- break;
-
- default:
- output_operand_lossage
- ("invalid operand size for operand code 'O'");
- return;
- }
-
- putc ('.', file);
-#endif
- return;
-
- case 'z':
- if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
- {
- /* Opcodes don't get size suffixes if using Intel opcodes. */
- if (ASSEMBLER_DIALECT == ASM_INTEL)
- return;
-
- switch (GET_MODE_SIZE (GET_MODE (x)))
- {
- case 1:
- putc ('b', file);
- return;
-
- case 2:
- putc ('w', file);
- return;
-
- case 4:
- putc ('l', file);
- return;
-
- case 8:
- putc ('q', file);
- return;
-
- default:
- output_operand_lossage
- ("invalid operand size for operand code 'z'");
- return;
- }
- }
-
- if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
- warning
- (0, "non-integer operand used with operand code 'z'");
- /* FALLTHRU */
-
- case 'Z':
- /* 387 opcodes don't get size suffixes if using Intel opcodes. */
- if (ASSEMBLER_DIALECT == ASM_INTEL)
- return;
-
- if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
- {
- switch (GET_MODE_SIZE (GET_MODE (x)))
- {
- case 2:
-#ifdef HAVE_AS_IX86_FILDS
- putc ('s', file);
-#endif
- return;
-
- case 4:
- putc ('l', file);
- return;
-
- case 8:
-#ifdef HAVE_AS_IX86_FILDQ
- putc ('q', file);
-#else
- fputs ("ll", file);
-#endif
- return;
-
- default:
- break;
- }
- }
- else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
- {
- /* 387 opcodes don't get size suffixes
- if the operands are registers. */
- if (STACK_REG_P (x))
- return;
-
- switch (GET_MODE_SIZE (GET_MODE (x)))
- {
- case 4:
- putc ('s', file);
- return;
-
- case 8:
- putc ('l', file);
- return;
-
- case 12:
- case 16:
- putc ('t', file);
- return;
-
- default:
- break;
- }
- }
- else
- {
- output_operand_lossage
- ("invalid operand type used with operand code 'Z'");
- return;
- }
-
- output_operand_lossage
- ("invalid operand size for operand code 'Z'");
- return;
-
- case 'd':
- case 'b':
- case 'w':
- case 'k':
- case 'q':
- case 'h':
- case 't':
- case 'y':
- case 'x':
- case 'X':
- case 'P':
- case 'p':
- break;
-
- case 's':
- if (CONST_INT_P (x) || ! SHIFT_DOUBLE_OMITS_COUNT)
- {
- ix86_print_operand (file, x, 0);
- fputs (", ", file);
- }
- return;
-
- case 'Y':
- switch (GET_CODE (x))
- {
- case NE:
- fputs ("neq", file);
- break;
- case EQ:
- fputs ("eq", file);
- break;
- case GE:
- case GEU:
- fputs (INTEGRAL_MODE_P (GET_MODE (x)) ? "ge" : "unlt", file);
- break;
- case GT:
- case GTU:
- fputs (INTEGRAL_MODE_P (GET_MODE (x)) ? "gt" : "unle", file);
- break;
- case LE:
- case LEU:
- fputs ("le", file);
- break;
- case LT:
- case LTU:
- fputs ("lt", file);
- break;
- case UNORDERED:
- fputs ("unord", file);
- break;
- case ORDERED:
- fputs ("ord", file);
- break;
- case UNEQ:
- fputs ("ueq", file);
- break;
- case UNGE:
- fputs ("nlt", file);
- break;
- case UNGT:
- fputs ("nle", file);
- break;
- case UNLE:
- fputs ("ule", file);
- break;
- case UNLT:
- fputs ("ult", file);
- break;
- case LTGT:
- fputs ("une", file);
- break;
- default:
- output_operand_lossage ("operand is not a condition code, "
- "invalid operand code 'Y'");
- return;
- }
- return;
-
- case 'D':
- /* Little bit of braindamage here. The SSE compare instructions
- does use completely different names for the comparisons that the
- fp conditional moves. */
- switch (GET_CODE (x))
- {
- case UNEQ:
- if (TARGET_AVX)
- {
- fputs ("eq_us", file);
- break;
- }
- case EQ:
- fputs ("eq", file);
- break;
- case UNLT:
- if (TARGET_AVX)
- {
- fputs ("nge", file);
- break;
- }
- case LT:
- fputs ("lt", file);
- break;
- case UNLE:
- if (TARGET_AVX)
- {
- fputs ("ngt", file);
- break;
- }
- case LE:
- fputs ("le", file);
- break;
- case UNORDERED:
- fputs ("unord", file);
- break;
- case LTGT:
- if (TARGET_AVX)
- {
- fputs ("neq_oq", file);
- break;
- }
- case NE:
- fputs ("neq", file);
- break;
- case GE:
- if (TARGET_AVX)
- {
- fputs ("ge", file);
- break;
- }
- case UNGE:
- fputs ("nlt", file);
- break;
- case GT:
- if (TARGET_AVX)
- {
- fputs ("gt", file);
- break;
- }
- case UNGT:
- fputs ("nle", file);
- break;
- case ORDERED:
- fputs ("ord", file);
- break;
- default:
- output_operand_lossage ("operand is not a condition code, "
- "invalid operand code 'D'");
- return;
- }
- return;
-
- case 'F':
- case 'f':
-#ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX
- if (ASSEMBLER_DIALECT == ASM_ATT)
- putc ('.', file);
-#endif
-
- case 'C':
- case 'c':
- if (!COMPARISON_P (x))
- {
- output_operand_lossage ("operand is not a condition code, "
- "invalid operand code '%c'", code);
- return;
- }
- put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)),
- code == 'c' || code == 'f',
- code == 'F' || code == 'f',
- file);
- return;
-
- case 'H':
- if (!offsettable_memref_p (x))
- {
- output_operand_lossage ("operand is not an offsettable memory "
- "reference, invalid operand code 'H'");
- return;
- }
- /* It doesn't actually matter what mode we use here, as we're
- only going to use this for printing. */
- x = adjust_address_nv (x, DImode, 8);
- break;
-
- case 'K':
- gcc_assert (CONST_INT_P (x));
-
- if (INTVAL (x) & IX86_HLE_ACQUIRE)
-#ifdef HAVE_AS_IX86_HLE
- fputs ("xacquire ", file);
-#else
- fputs ("\n" ASM_BYTE "0xf2\n\t", file);
-#endif
- else if (INTVAL (x) & IX86_HLE_RELEASE)
-#ifdef HAVE_AS_IX86_HLE
- fputs ("xrelease ", file);
-#else
- fputs ("\n" ASM_BYTE "0xf3\n\t", file);
-#endif
- /* We do not want to print value of the operand. */
- return;
-
- case '*':
- if (ASSEMBLER_DIALECT == ASM_ATT)
- putc ('*', file);
- return;
-
- case '&':
- {
- const char *name = get_some_local_dynamic_name ();
- if (name == NULL)
- output_operand_lossage ("'%%&' used without any "
- "local dynamic TLS references");
- else
- assemble_name (file, name);
- return;
- }
-
- case '+':
- {
- rtx x;
-
- if (!optimize
- || optimize_function_for_size_p (cfun)
- || !TARGET_BRANCH_PREDICTION_HINTS)
- return;
-
- x = find_reg_note (current_output_insn, REG_BR_PROB, 0);
- if (x)
- {
- int pred_val = INTVAL (XEXP (x, 0));
-
- if (pred_val < REG_BR_PROB_BASE * 45 / 100
- || pred_val > REG_BR_PROB_BASE * 55 / 100)
- {
- bool taken = pred_val > REG_BR_PROB_BASE / 2;
- bool cputaken
- = final_forward_branch_p (current_output_insn) == 0;
-
- /* Emit hints only in the case default branch prediction
- heuristics would fail. */
- if (taken != cputaken)
- {
- /* We use 3e (DS) prefix for taken branches and
- 2e (CS) prefix for not taken branches. */
- if (taken)
- fputs ("ds ; ", file);
- else
- fputs ("cs ; ", file);
- }
- }
- }
- return;
- }
-
- case ';':
-#ifndef HAVE_AS_IX86_REP_LOCK_PREFIX
- putc (';', file);
-#endif
- return;
-
- case '@':
- if (ASSEMBLER_DIALECT == ASM_ATT)
- putc ('%', file);
-
- /* The kernel uses a different segment register for performance
- reasons; a system call would not have to trash the userspace
- segment register, which would be expensive. */
- if (TARGET_64BIT && ix86_cmodel != CM_KERNEL)
- fputs ("fs", file);
- else
- fputs ("gs", file);
- return;
-
- case '~':
- putc (TARGET_AVX2 ? 'i' : 'f', file);
- return;
-
- case '^':
- if (TARGET_64BIT && Pmode != word_mode)
- fputs ("addr32 ", file);
- return;
-
- default:
- output_operand_lossage ("invalid operand code '%c'", code);
- }
- }
-
- if (REG_P (x))
- print_reg (x, code, file);
-
- else if (MEM_P (x))
- {
- /* No `byte ptr' prefix for call instructions or BLKmode operands. */
- if (ASSEMBLER_DIALECT == ASM_INTEL && code != 'X' && code != 'P'
- && GET_MODE (x) != BLKmode)
- {
- const char * size;
- switch (GET_MODE_SIZE (GET_MODE (x)))
- {
- case 1: size = "BYTE"; break;
- case 2: size = "WORD"; break;
- case 4: size = "DWORD"; break;
- case 8: size = "QWORD"; break;
- case 12: size = "TBYTE"; break;
- case 16:
- if (GET_MODE (x) == XFmode)
- size = "TBYTE";
- else
- size = "XMMWORD";
- break;
- case 32: size = "YMMWORD"; break;
- default:
- gcc_unreachable ();
- }
-
- /* Check for explicit size override (codes 'b', 'w', 'k',
- 'q' and 'x') */
- if (code == 'b')
- size = "BYTE";
- else if (code == 'w')
- size = "WORD";
- else if (code == 'k')
- size = "DWORD";
- else if (code == 'q')
- size = "QWORD";
- else if (code == 'x')
- size = "XMMWORD";
-
- fputs (size, file);
- fputs (" PTR ", file);
- }
-
- x = XEXP (x, 0);
- /* Avoid (%rip) for call operands. */
- if (CONSTANT_ADDRESS_P (x) && code == 'P'
- && !CONST_INT_P (x))
- output_addr_const (file, x);
- else if (this_is_asm_operands && ! address_operand (x, VOIDmode))
- output_operand_lossage ("invalid constraints for operand");
- else
- output_address (x);
- }
-
- else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
- {
- REAL_VALUE_TYPE r;
- long l;
-
- REAL_VALUE_FROM_CONST_DOUBLE (r, x);
- REAL_VALUE_TO_TARGET_SINGLE (r, l);
-
- if (ASSEMBLER_DIALECT == ASM_ATT)
- putc ('$', file);
- /* Sign extend 32bit SFmode immediate to 8 bytes. */
- if (code == 'q')
- fprintf (file, "0x%08" HOST_LONG_LONG_FORMAT "x",
- (unsigned long long) (int) l);
- else
- fprintf (file, "0x%08x", (unsigned int) l);
- }
-
- else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
- {
- REAL_VALUE_TYPE r;
- long l[2];
-
- REAL_VALUE_FROM_CONST_DOUBLE (r, x);
- REAL_VALUE_TO_TARGET_DOUBLE (r, l);
-
- if (ASSEMBLER_DIALECT == ASM_ATT)
- putc ('$', file);
- fprintf (file, "0x%lx%08lx", l[1] & 0xffffffff, l[0] & 0xffffffff);
- }
-
- /* These float cases don't actually occur as immediate operands. */
- else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == XFmode)
- {
- char dstr[30];
-
- real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (x), sizeof (dstr), 0, 1);
- fputs (dstr, file);
- }
-
- else
- {
- /* We have patterns that allow zero sets of memory, for instance.
- In 64-bit mode, we should probably support all 8-byte vectors,
- since we can in fact encode that into an immediate. */
- if (GET_CODE (x) == CONST_VECTOR)
- {
- gcc_assert (x == CONST0_RTX (GET_MODE (x)));
- x = const0_rtx;
- }
-
- if (code != 'P' && code != 'p')
- {
- if (CONST_INT_P (x) || GET_CODE (x) == CONST_DOUBLE)
- {
- if (ASSEMBLER_DIALECT == ASM_ATT)
- putc ('$', file);
- }
- else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
- || GET_CODE (x) == LABEL_REF)
- {
- if (ASSEMBLER_DIALECT == ASM_ATT)
- putc ('$', file);
- else
- fputs ("OFFSET FLAT:", file);
- }
- }
- if (CONST_INT_P (x))
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
- else if (flag_pic || MACHOPIC_INDIRECT)
- output_pic_addr_const (file, x, code);
- else
- output_addr_const (file, x);
- }
-}
-
-static bool
-ix86_print_operand_punct_valid_p (unsigned char code)
-{
- return (code == '@' || code == '*' || code == '+' || code == '&'
- || code == ';' || code == '~' || code == '^');
-}
-
-/* Print a memory operand whose address is ADDR. */
-
-static void
-ix86_print_operand_address (FILE *file, rtx addr)
-{
- struct ix86_address parts;
- rtx base, index, disp;
- int scale;
- int ok;
- bool vsib = false;
- int code = 0;
-
- if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_VSIBADDR)
- {
- ok = ix86_decompose_address (XVECEXP (addr, 0, 0), &parts);
- gcc_assert (parts.index == NULL_RTX);
- parts.index = XVECEXP (addr, 0, 1);
- parts.scale = INTVAL (XVECEXP (addr, 0, 2));
- addr = XVECEXP (addr, 0, 0);
- vsib = true;
- }
- else if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_LEA_ADDR)
- {
- gcc_assert (TARGET_64BIT);
- ok = ix86_decompose_address (XVECEXP (addr, 0, 0), &parts);
- code = 'q';
- }
- else
- ok = ix86_decompose_address (addr, &parts);
-
- gcc_assert (ok);
-
- base = parts.base;
- index = parts.index;
- disp = parts.disp;
- scale = parts.scale;
-
- switch (parts.seg)
- {
- case SEG_DEFAULT:
- break;
- case SEG_FS:
- case SEG_GS:
- if (ASSEMBLER_DIALECT == ASM_ATT)
- putc ('%', file);
- fputs ((parts.seg == SEG_FS ? "fs:" : "gs:"), file);
- break;
- default:
- gcc_unreachable ();
- }
-
- /* Use one byte shorter RIP relative addressing for 64bit mode. */
- if (TARGET_64BIT && !base && !index)
- {
- rtx symbol = disp;
-
- if (GET_CODE (disp) == CONST
- && GET_CODE (XEXP (disp, 0)) == PLUS
- && CONST_INT_P (XEXP (XEXP (disp, 0), 1)))
- symbol = XEXP (XEXP (disp, 0), 0);
-
- if (GET_CODE (symbol) == LABEL_REF
- || (GET_CODE (symbol) == SYMBOL_REF
- && SYMBOL_REF_TLS_MODEL (symbol) == 0))
- base = pc_rtx;
- }
- if (!base && !index)
- {
- /* Displacement only requires special attention. */
-
- if (CONST_INT_P (disp))
- {
- if (ASSEMBLER_DIALECT == ASM_INTEL && parts.seg == SEG_DEFAULT)
- fputs ("ds:", file);
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (disp));
- }
- else if (flag_pic)
- output_pic_addr_const (file, disp, 0);
- else
- output_addr_const (file, disp);
- }
- else
- {
- /* Print SImode register names to force addr32 prefix. */
- if (SImode_address_operand (addr, VOIDmode))
- {
-#ifdef ENABLE_CHECKING
- gcc_assert (TARGET_64BIT);
- switch (GET_CODE (addr))
- {
- case SUBREG:
- gcc_assert (GET_MODE (addr) == SImode);
- gcc_assert (GET_MODE (SUBREG_REG (addr)) == DImode);
- break;
- case ZERO_EXTEND:
- case AND:
- gcc_assert (GET_MODE (addr) == DImode);
- break;
- default:
- gcc_unreachable ();
- }
-#endif
- gcc_assert (!code);
- code = 'k';
- }
- else if (code == 0
- && TARGET_X32
- && disp
- && CONST_INT_P (disp)
- && INTVAL (disp) < -16*1024*1024)
- {
- /* X32 runs in 64-bit mode, where displacement, DISP, in
- address DISP(%r64), is encoded as 32-bit immediate sign-
- extended from 32-bit to 64-bit. For -0x40000300(%r64),
- address is %r64 + 0xffffffffbffffd00. When %r64 <
- 0x40000300, like 0x37ffe064, address is 0xfffffffff7ffdd64,
- which is invalid for x32. The correct address is %r64
- - 0x40000300 == 0xf7ffdd64. To properly encode
- -0x40000300(%r64) for x32, we zero-extend negative
- displacement by forcing addr32 prefix which truncates
- 0xfffffffff7ffdd64 to 0xf7ffdd64. In theory, we should
- zero-extend all negative displacements, including -1(%rsp).
- However, for small negative displacements, sign-extension
- won't cause overflow. We only zero-extend negative
- displacements if they < -16*1024*1024, which is also used
- to check legitimate address displacements for PIC. */
- code = 'k';
- }
-
- if (ASSEMBLER_DIALECT == ASM_ATT)
- {
- if (disp)
- {
- if (flag_pic)
- output_pic_addr_const (file, disp, 0);
- else if (GET_CODE (disp) == LABEL_REF)
- output_asm_label (disp);
- else
- output_addr_const (file, disp);
- }
-
- putc ('(', file);
- if (base)
- print_reg (base, code, file);
- if (index)
- {
- putc (',', file);
- print_reg (index, vsib ? 0 : code, file);
- if (scale != 1 || vsib)
- fprintf (file, ",%d", scale);
- }
- putc (')', file);
- }
- else
- {
- rtx offset = NULL_RTX;
-
- if (disp)
- {
- /* Pull out the offset of a symbol; print any symbol itself. */
- if (GET_CODE (disp) == CONST
- && GET_CODE (XEXP (disp, 0)) == PLUS
- && CONST_INT_P (XEXP (XEXP (disp, 0), 1)))
- {
- offset = XEXP (XEXP (disp, 0), 1);
- disp = gen_rtx_CONST (VOIDmode,
- XEXP (XEXP (disp, 0), 0));
- }
-
- if (flag_pic)
- output_pic_addr_const (file, disp, 0);
- else if (GET_CODE (disp) == LABEL_REF)
- output_asm_label (disp);
- else if (CONST_INT_P (disp))
- offset = disp;
- else
- output_addr_const (file, disp);
- }
-
- putc ('[', file);
- if (base)
- {
- print_reg (base, code, file);
- if (offset)
- {
- if (INTVAL (offset) >= 0)
- putc ('+', file);
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (offset));
- }
- }
- else if (offset)
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (offset));
- else
- putc ('0', file);
-
- if (index)
- {
- putc ('+', file);
- print_reg (index, vsib ? 0 : code, file);
- if (scale != 1 || vsib)
- fprintf (file, "*%d", scale);
- }
- putc (']', file);
- }
- }
-}
-
-/* Implementation of TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */
-
-static bool
-i386_asm_output_addr_const_extra (FILE *file, rtx x)
-{
- rtx op;
-
- if (GET_CODE (x) != UNSPEC)
- return false;
-
- op = XVECEXP (x, 0, 0);
- switch (XINT (x, 1))
- {
- case UNSPEC_GOTTPOFF:
- output_addr_const (file, op);
- /* FIXME: This might be @TPOFF in Sun ld. */
- fputs ("@gottpoff", file);
- break;
- case UNSPEC_TPOFF:
- output_addr_const (file, op);
- fputs ("@tpoff", file);
- break;
- case UNSPEC_NTPOFF:
- output_addr_const (file, op);
- if (TARGET_64BIT)
- fputs ("@tpoff", file);
- else
- fputs ("@ntpoff", file);
- break;
- case UNSPEC_DTPOFF:
- output_addr_const (file, op);
- fputs ("@dtpoff", file);
- break;
- case UNSPEC_GOTNTPOFF:
- output_addr_const (file, op);
- if (TARGET_64BIT)
- fputs (ASSEMBLER_DIALECT == ASM_ATT ?
- "@gottpoff(%rip)" : "@gottpoff[rip]", file);
- else
- fputs ("@gotntpoff", file);
- break;
- case UNSPEC_INDNTPOFF:
- output_addr_const (file, op);
- fputs ("@indntpoff", file);
- break;
-#if TARGET_MACHO
- case UNSPEC_MACHOPIC_OFFSET:
- output_addr_const (file, op);
- putc ('-', file);
- machopic_output_function_base_name (file);
- break;
-#endif
-
- case UNSPEC_STACK_CHECK:
- {
- int offset;
-
- gcc_assert (flag_split_stack);
-
-#ifdef TARGET_THREAD_SPLIT_STACK_OFFSET
- offset = TARGET_THREAD_SPLIT_STACK_OFFSET;
-#else
- gcc_unreachable ();
-#endif
-
- fprintf (file, "%s:%d", TARGET_64BIT ? "%fs" : "%gs", offset);
- }
- break;
-
- default:
- return false;
- }
-
- return true;
-}
-
-/* Split one or more double-mode RTL references into pairs of half-mode
- references. The RTL can be REG, offsettable MEM, integer constant, or
- CONST_DOUBLE. "operands" is a pointer to an array of double-mode RTLs to
- split and "num" is its length. lo_half and hi_half are output arrays
- that parallel "operands". */
-
-void
-split_double_mode (enum machine_mode mode, rtx operands[],
- int num, rtx lo_half[], rtx hi_half[])
-{
- enum machine_mode half_mode;
- unsigned int byte;
-
- switch (mode)
- {
- case TImode:
- half_mode = DImode;
- break;
- case DImode:
- half_mode = SImode;
- break;
- default:
- gcc_unreachable ();
- }
-
- byte = GET_MODE_SIZE (half_mode);
-
- while (num--)
- {
- rtx op = operands[num];
-
- /* simplify_subreg refuse to split volatile memory addresses,
- but we still have to handle it. */
- if (MEM_P (op))
- {
- lo_half[num] = adjust_address (op, half_mode, 0);
- hi_half[num] = adjust_address (op, half_mode, byte);
- }
- else
- {
- lo_half[num] = simplify_gen_subreg (half_mode, op,
- GET_MODE (op) == VOIDmode
- ? mode : GET_MODE (op), 0);
- hi_half[num] = simplify_gen_subreg (half_mode, op,
- GET_MODE (op) == VOIDmode
- ? mode : GET_MODE (op), byte);
- }
- }
-}
-
-/* Output code to perform a 387 binary operation in INSN, one of PLUS,
- MINUS, MULT or DIV. OPERANDS are the insn operands, where operands[3]
- is the expression of the binary operation. The output may either be
- emitted here, or returned to the caller, like all output_* functions.
-
- There is no guarantee that the operands are the same mode, as they
- might be within FLOAT or FLOAT_EXTEND expressions. */
-
-#ifndef SYSV386_COMPAT
-/* Set to 1 for compatibility with brain-damaged assemblers. No-one
- wants to fix the assemblers because that causes incompatibility
- with gcc. No-one wants to fix gcc because that causes
- incompatibility with assemblers... You can use the option of
- -DSYSV386_COMPAT=0 if you recompile both gcc and gas this way. */
-#define SYSV386_COMPAT 1
-#endif
-
-const char *
-output_387_binary_op (rtx insn, rtx *operands)
-{
- static char buf[40];
- const char *p;
- const char *ssep;
- int is_sse = SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]) || SSE_REG_P (operands[2]);
-
-#ifdef ENABLE_CHECKING
- /* Even if we do not want to check the inputs, this documents input
- constraints. Which helps in understanding the following code. */
- if (STACK_REG_P (operands[0])
- && ((REG_P (operands[1])
- && REGNO (operands[0]) == REGNO (operands[1])
- && (STACK_REG_P (operands[2]) || MEM_P (operands[2])))
- || (REG_P (operands[2])
- && REGNO (operands[0]) == REGNO (operands[2])
- && (STACK_REG_P (operands[1]) || MEM_P (operands[1]))))
- && (STACK_TOP_P (operands[1]) || STACK_TOP_P (operands[2])))
- ; /* ok */
- else
- gcc_assert (is_sse);
-#endif
-
- switch (GET_CODE (operands[3]))
- {
- case PLUS:
- if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
- || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
- p = "fiadd";
- else
- p = "fadd";
- ssep = "vadd";
- break;
-
- case MINUS:
- if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
- || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
- p = "fisub";
- else
- p = "fsub";
- ssep = "vsub";
- break;
-
- case MULT:
- if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
- || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
- p = "fimul";
- else
- p = "fmul";
- ssep = "vmul";
- break;
-
- case DIV:
- if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
- || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
- p = "fidiv";
- else
- p = "fdiv";
- ssep = "vdiv";
- break;
-
- default:
- gcc_unreachable ();
- }
-
- if (is_sse)
- {
- if (TARGET_AVX)
- {
- strcpy (buf, ssep);
- if (GET_MODE (operands[0]) == SFmode)
- strcat (buf, "ss\t{%2, %1, %0|%0, %1, %2}");
- else
- strcat (buf, "sd\t{%2, %1, %0|%0, %1, %2}");
- }
- else
- {
- strcpy (buf, ssep + 1);
- if (GET_MODE (operands[0]) == SFmode)
- strcat (buf, "ss\t{%2, %0|%0, %2}");
- else
- strcat (buf, "sd\t{%2, %0|%0, %2}");
- }
- return buf;
- }
- strcpy (buf, p);
-
- switch (GET_CODE (operands[3]))
- {
- case MULT:
- case PLUS:
- if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
- {
- rtx temp = operands[2];
- operands[2] = operands[1];
- operands[1] = temp;
- }
-
- /* know operands[0] == operands[1]. */
-
- if (MEM_P (operands[2]))
- {
- p = "%Z2\t%2";
- break;
- }
-
- if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
- {
- if (STACK_TOP_P (operands[0]))
- /* How is it that we are storing to a dead operand[2]?
- Well, presumably operands[1] is dead too. We can't
- store the result to st(0) as st(0) gets popped on this
- instruction. Instead store to operands[2] (which I
- think has to be st(1)). st(1) will be popped later.
- gcc <= 2.8.1 didn't have this check and generated
- assembly code that the Unixware assembler rejected. */
- p = "p\t{%0, %2|%2, %0}"; /* st(1) = st(0) op st(1); pop */
- else
- p = "p\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0); pop */
- break;
- }
-
- if (STACK_TOP_P (operands[0]))
- p = "\t{%y2, %0|%0, %y2}"; /* st(0) = st(0) op st(r2) */
- else
- p = "\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0) */
- break;
-
- case MINUS:
- case DIV:
- if (MEM_P (operands[1]))
- {
- p = "r%Z1\t%1";
- break;
- }
-
- if (MEM_P (operands[2]))
- {
- p = "%Z2\t%2";
- break;
- }
-
- if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
- {
-#if SYSV386_COMPAT
- /* The SystemV/386 SVR3.2 assembler, and probably all AT&T
- derived assemblers, confusingly reverse the direction of
- the operation for fsub{r} and fdiv{r} when the
- destination register is not st(0). The Intel assembler
- doesn't have this brain damage. Read !SYSV386_COMPAT to
- figure out what the hardware really does. */
- if (STACK_TOP_P (operands[0]))
- p = "{p\t%0, %2|rp\t%2, %0}";
- else
- p = "{rp\t%2, %0|p\t%0, %2}";
-#else
- if (STACK_TOP_P (operands[0]))
- /* As above for fmul/fadd, we can't store to st(0). */
- p = "rp\t{%0, %2|%2, %0}"; /* st(1) = st(0) op st(1); pop */
- else
- p = "p\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0); pop */
-#endif
- break;
- }
-
- if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- {
-#if SYSV386_COMPAT
- if (STACK_TOP_P (operands[0]))
- p = "{rp\t%0, %1|p\t%1, %0}";
- else
- p = "{p\t%1, %0|rp\t%0, %1}";
-#else
- if (STACK_TOP_P (operands[0]))
- p = "p\t{%0, %1|%1, %0}"; /* st(1) = st(1) op st(0); pop */
- else
- p = "rp\t{%1, %0|%0, %1}"; /* st(r2) = st(0) op st(r2); pop */
-#endif
- break;
- }
-
- if (STACK_TOP_P (operands[0]))
- {
- if (STACK_TOP_P (operands[1]))
- p = "\t{%y2, %0|%0, %y2}"; /* st(0) = st(0) op st(r2) */
- else
- p = "r\t{%y1, %0|%0, %y1}"; /* st(0) = st(r1) op st(0) */
- break;
- }
- else if (STACK_TOP_P (operands[1]))
- {
-#if SYSV386_COMPAT
- p = "{\t%1, %0|r\t%0, %1}";
-#else
- p = "r\t{%1, %0|%0, %1}"; /* st(r2) = st(0) op st(r2) */
-#endif
- }
- else
- {
-#if SYSV386_COMPAT
- p = "{r\t%2, %0|\t%0, %2}";
-#else
- p = "\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0) */
-#endif
- }
- break;
-
- default:
- gcc_unreachable ();
- }
-
- strcat (buf, p);
- return buf;
-}
-
-/* Check if a 256bit AVX register is referenced inside of EXP. */
-
-static int
-ix86_check_avx256_register (rtx *pexp, void *data ATTRIBUTE_UNUSED)
-{
- rtx exp = *pexp;
-
- if (GET_CODE (exp) == SUBREG)
- exp = SUBREG_REG (exp);
-
- if (REG_P (exp)
- && VALID_AVX256_REG_OR_OI_MODE (GET_MODE (exp)))
- return 1;
-
- return 0;
-}
-
-/* Return needed mode for entity in optimize_mode_switching pass. */
-
-static int
-ix86_avx_u128_mode_needed (rtx insn)
-{
- if (CALL_P (insn))
- {
- rtx link;
-
- /* Needed mode is set to AVX_U128_CLEAN if there are
- no 256bit modes used in function arguments. */
- for (link = CALL_INSN_FUNCTION_USAGE (insn);
- link;
- link = XEXP (link, 1))
- {
- if (GET_CODE (XEXP (link, 0)) == USE)
- {
- rtx arg = XEXP (XEXP (link, 0), 0);
-
- if (ix86_check_avx256_register (&arg, NULL))
- return AVX_U128_ANY;
- }
- }
-
- return AVX_U128_CLEAN;
- }
-
- /* Require DIRTY mode if a 256bit AVX register is referenced. Hardware
- changes state only when a 256bit register is written to, but we need
- to prevent the compiler from moving optimal insertion point above
- eventual read from 256bit register. */
- if (for_each_rtx (&PATTERN (insn), ix86_check_avx256_register, NULL))
- return AVX_U128_DIRTY;
-
- return AVX_U128_ANY;
-}
-
-/* Return mode that i387 must be switched into
- prior to the execution of insn. */
-
-static int
-ix86_i387_mode_needed (int entity, rtx insn)
-{
- enum attr_i387_cw mode;
-
- /* The mode UNINITIALIZED is used to store control word after a
- function call or ASM pattern. The mode ANY specify that function
- has no requirements on the control word and make no changes in the
- bits we are interested in. */
-
- if (CALL_P (insn)
- || (NONJUMP_INSN_P (insn)
- && (asm_noperands (PATTERN (insn)) >= 0
- || GET_CODE (PATTERN (insn)) == ASM_INPUT)))
- return I387_CW_UNINITIALIZED;
-
- if (recog_memoized (insn) < 0)
- return I387_CW_ANY;
-
- mode = get_attr_i387_cw (insn);
-
- switch (entity)
- {
- case I387_TRUNC:
- if (mode == I387_CW_TRUNC)
- return mode;
- break;
-
- case I387_FLOOR:
- if (mode == I387_CW_FLOOR)
- return mode;
- break;
-
- case I387_CEIL:
- if (mode == I387_CW_CEIL)
- return mode;
- break;
-
- case I387_MASK_PM:
- if (mode == I387_CW_MASK_PM)
- return mode;
- break;
-
- default:
- gcc_unreachable ();
- }
-
- return I387_CW_ANY;
-}
-
-/* Return mode that entity must be switched into
- prior to the execution of insn. */
-
-int
-ix86_mode_needed (int entity, rtx insn)
-{
- switch (entity)
- {
- case AVX_U128:
- return ix86_avx_u128_mode_needed (insn);
- case I387_TRUNC:
- case I387_FLOOR:
- case I387_CEIL:
- case I387_MASK_PM:
- return ix86_i387_mode_needed (entity, insn);
- default:
- gcc_unreachable ();
- }
- return 0;
-}
-
-/* Check if a 256bit AVX register is referenced in stores. */
-
-static void
-ix86_check_avx256_stores (rtx dest, const_rtx set ATTRIBUTE_UNUSED, void *data)
- {
- if (ix86_check_avx256_register (&dest, NULL))
- {
- bool *used = (bool *) data;
- *used = true;
- }
- }
-
-/* Calculate mode of upper 128bit AVX registers after the insn. */
-
-static int
-ix86_avx_u128_mode_after (int mode, rtx insn)
-{
- rtx pat = PATTERN (insn);
-
- if (vzeroupper_operation (pat, VOIDmode)
- || vzeroall_operation (pat, VOIDmode))
- return AVX_U128_CLEAN;
-
- /* We know that state is clean after CALL insn if there are no
- 256bit registers used in the function return register. */
- if (CALL_P (insn))
- {
- bool avx_reg256_found = false;
- note_stores (pat, ix86_check_avx256_stores, &avx_reg256_found);
- if (!avx_reg256_found)
- return AVX_U128_CLEAN;
- }
-
- /* Otherwise, return current mode. Remember that if insn
- references AVX 256bit registers, the mode was already changed
- to DIRTY from MODE_NEEDED. */
- return mode;
-}
-
-/* Return the mode that an insn results in. */
-
-int
-ix86_mode_after (int entity, int mode, rtx insn)
-{
- switch (entity)
- {
- case AVX_U128:
- return ix86_avx_u128_mode_after (mode, insn);
- case I387_TRUNC:
- case I387_FLOOR:
- case I387_CEIL:
- case I387_MASK_PM:
- return mode;
- default:
- gcc_unreachable ();
- }
-}
-
-static int
-ix86_avx_u128_mode_entry (void)
-{
- tree arg;
-
- /* Entry mode is set to AVX_U128_DIRTY if there are
- 256bit modes used in function arguments. */
- for (arg = DECL_ARGUMENTS (current_function_decl); arg;
- arg = TREE_CHAIN (arg))
- {
- rtx incoming = DECL_INCOMING_RTL (arg);
-
- if (incoming && ix86_check_avx256_register (&incoming, NULL))
- return AVX_U128_DIRTY;
- }
-
- return AVX_U128_CLEAN;
-}
-
-/* Return a mode that ENTITY is assumed to be
- switched to at function entry. */
-
-int
-ix86_mode_entry (int entity)
-{
- switch (entity)
- {
- case AVX_U128:
- return ix86_avx_u128_mode_entry ();
- case I387_TRUNC:
- case I387_FLOOR:
- case I387_CEIL:
- case I387_MASK_PM:
- return I387_CW_ANY;
- default:
- gcc_unreachable ();
- }
-}
-
-static int
-ix86_avx_u128_mode_exit (void)
-{
- rtx reg = crtl->return_rtx;
-
- /* Exit mode is set to AVX_U128_DIRTY if there are
- 256bit modes used in the function return register. */
- if (reg && ix86_check_avx256_register (&reg, NULL))
- return AVX_U128_DIRTY;
-
- return AVX_U128_CLEAN;
-}
-
-/* Return a mode that ENTITY is assumed to be
- switched to at function exit. */
-
-int
-ix86_mode_exit (int entity)
-{
- switch (entity)
- {
- case AVX_U128:
- return ix86_avx_u128_mode_exit ();
- case I387_TRUNC:
- case I387_FLOOR:
- case I387_CEIL:
- case I387_MASK_PM:
- return I387_CW_ANY;
- default:
- gcc_unreachable ();
- }
-}
-
-/* Output code to initialize control word copies used by trunc?f?i and
- rounding patterns. CURRENT_MODE is set to current control word,
- while NEW_MODE is set to new control word. */
-
-static void
-emit_i387_cw_initialization (int mode)
-{
- rtx stored_mode = assign_386_stack_local (HImode, SLOT_CW_STORED);
- rtx new_mode;
-
- enum ix86_stack_slot slot;
-
- rtx reg = gen_reg_rtx (HImode);
-
- emit_insn (gen_x86_fnstcw_1 (stored_mode));
- emit_move_insn (reg, copy_rtx (stored_mode));
-
- if (TARGET_64BIT || TARGET_PARTIAL_REG_STALL
- || optimize_function_for_size_p (cfun))
- {
- switch (mode)
- {
- case I387_CW_TRUNC:
- /* round toward zero (truncate) */
- emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0c00)));
- slot = SLOT_CW_TRUNC;
- break;
-
- case I387_CW_FLOOR:
- /* round down toward -oo */
- emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
- emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0400)));
- slot = SLOT_CW_FLOOR;
- break;
-
- case I387_CW_CEIL:
- /* round up toward +oo */
- emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
- emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0800)));
- slot = SLOT_CW_CEIL;
- break;
-
- case I387_CW_MASK_PM:
- /* mask precision exception for nearbyint() */
- emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0020)));
- slot = SLOT_CW_MASK_PM;
- break;
-
- default:
- gcc_unreachable ();
- }
- }
- else
- {
- switch (mode)
- {
- case I387_CW_TRUNC:
- /* round toward zero (truncate) */
- emit_insn (gen_movsi_insv_1 (reg, GEN_INT (0xc)));
- slot = SLOT_CW_TRUNC;
- break;
-
- case I387_CW_FLOOR:
- /* round down toward -oo */
- emit_insn (gen_movsi_insv_1 (reg, GEN_INT (0x4)));
- slot = SLOT_CW_FLOOR;
- break;
-
- case I387_CW_CEIL:
- /* round up toward +oo */
- emit_insn (gen_movsi_insv_1 (reg, GEN_INT (0x8)));
- slot = SLOT_CW_CEIL;
- break;
-
- case I387_CW_MASK_PM:
- /* mask precision exception for nearbyint() */
- emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0020)));
- slot = SLOT_CW_MASK_PM;
- break;
-
- default:
- gcc_unreachable ();
- }
- }
-
- gcc_assert (slot < MAX_386_STACK_LOCALS);
-
- new_mode = assign_386_stack_local (HImode, slot);
- emit_move_insn (new_mode, reg);
-}
-
-/* Emit vzeroupper. */
-
-void
-ix86_avx_emit_vzeroupper (HARD_REG_SET regs_live)
-{
- int i;
-
- /* Cancel automatic vzeroupper insertion if there are
- live call-saved SSE registers at the insertion point. */
-
- for (i = FIRST_SSE_REG; i <= LAST_SSE_REG; i++)
- if (TEST_HARD_REG_BIT (regs_live, i) && !call_used_regs[i])
- return;
-
- if (TARGET_64BIT)
- for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
- if (TEST_HARD_REG_BIT (regs_live, i) && !call_used_regs[i])
- return;
-
- emit_insn (gen_avx_vzeroupper ());
-}
-
-/* Generate one or more insns to set ENTITY to MODE. */
-
-void
-ix86_emit_mode_set (int entity, int mode, HARD_REG_SET regs_live)
-{
- switch (entity)
- {
- case AVX_U128:
- if (mode == AVX_U128_CLEAN)
- ix86_avx_emit_vzeroupper (regs_live);
- break;
- case I387_TRUNC:
- case I387_FLOOR:
- case I387_CEIL:
- case I387_MASK_PM:
- if (mode != I387_CW_ANY
- && mode != I387_CW_UNINITIALIZED)
- emit_i387_cw_initialization (mode);
- break;
- default:
- gcc_unreachable ();
- }
-}
-
-/* Output code for INSN to convert a float to a signed int. OPERANDS
- are the insn operands. The output may be [HSD]Imode and the input
- operand may be [SDX]Fmode. */
-
-const char *
-output_fix_trunc (rtx insn, rtx *operands, bool fisttp)
-{
- int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
- int dimode_p = GET_MODE (operands[0]) == DImode;
- int round_mode = get_attr_i387_cw (insn);
-
- /* Jump through a hoop or two for DImode, since the hardware has no
- non-popping instruction. We used to do this a different way, but
- that was somewhat fragile and broke with post-reload splitters. */
- if ((dimode_p || fisttp) && !stack_top_dies)
- output_asm_insn ("fld\t%y1", operands);
-
- gcc_assert (STACK_TOP_P (operands[1]));
- gcc_assert (MEM_P (operands[0]));
- gcc_assert (GET_MODE (operands[1]) != TFmode);
-
- if (fisttp)
- output_asm_insn ("fisttp%Z0\t%0", operands);
- else
- {
- if (round_mode != I387_CW_ANY)
- output_asm_insn ("fldcw\t%3", operands);
- if (stack_top_dies || dimode_p)
- output_asm_insn ("fistp%Z0\t%0", operands);
- else
- output_asm_insn ("fist%Z0\t%0", operands);
- if (round_mode != I387_CW_ANY)
- output_asm_insn ("fldcw\t%2", operands);
- }
-
- return "";
-}
-
-/* Output code for x87 ffreep insn. The OPNO argument, which may only
- have the values zero or one, indicates the ffreep insn's operand
- from the OPERANDS array. */
-
-static const char *
-output_387_ffreep (rtx *operands ATTRIBUTE_UNUSED, int opno)
-{
- if (TARGET_USE_FFREEP)
-#ifdef HAVE_AS_IX86_FFREEP
- return opno ? "ffreep\t%y1" : "ffreep\t%y0";
-#else
- {
- static char retval[32];
- int regno = REGNO (operands[opno]);
-
- gcc_assert (STACK_REGNO_P (regno));
-
- regno -= FIRST_STACK_REG;
-
- snprintf (retval, sizeof (retval), ASM_SHORT "0xc%ddf", regno);
- return retval;
- }
-#endif
-
- return opno ? "fstp\t%y1" : "fstp\t%y0";
-}
-
-
-/* Output code for INSN to compare OPERANDS. EFLAGS_P is 1 when fcomi
- should be used. UNORDERED_P is true when fucom should be used. */
-
-const char *
-output_fp_compare (rtx insn, rtx *operands, bool eflags_p, bool unordered_p)
-{
- int stack_top_dies;
- rtx cmp_op0, cmp_op1;
- int is_sse = SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]);
-
- if (eflags_p)
- {
- cmp_op0 = operands[0];
- cmp_op1 = operands[1];
- }
- else
- {
- cmp_op0 = operands[1];
- cmp_op1 = operands[2];
- }
-
- if (is_sse)
- {
- if (GET_MODE (operands[0]) == SFmode)
- if (unordered_p)
- return "%vucomiss\t{%1, %0|%0, %1}";
- else
- return "%vcomiss\t{%1, %0|%0, %1}";
- else
- if (unordered_p)
- return "%vucomisd\t{%1, %0|%0, %1}";
- else
- return "%vcomisd\t{%1, %0|%0, %1}";
- }
-
- gcc_assert (STACK_TOP_P (cmp_op0));
-
- stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
-
- if (cmp_op1 == CONST0_RTX (GET_MODE (cmp_op1)))
- {
- if (stack_top_dies)
- {
- output_asm_insn ("ftst\n\tfnstsw\t%0", operands);
- return output_387_ffreep (operands, 1);
- }
- else
- return "ftst\n\tfnstsw\t%0";
- }
-
- if (STACK_REG_P (cmp_op1)
- && stack_top_dies
- && find_regno_note (insn, REG_DEAD, REGNO (cmp_op1))
- && REGNO (cmp_op1) != FIRST_STACK_REG)
- {
- /* If both the top of the 387 stack dies, and the other operand
- is also a stack register that dies, then this must be a
- `fcompp' float compare */
-
- if (eflags_p)
- {
- /* There is no double popping fcomi variant. Fortunately,
- eflags is immune from the fstp's cc clobbering. */
- if (unordered_p)
- output_asm_insn ("fucomip\t{%y1, %0|%0, %y1}", operands);
- else
- output_asm_insn ("fcomip\t{%y1, %0|%0, %y1}", operands);
- return output_387_ffreep (operands, 0);
- }
- else
- {
- if (unordered_p)
- return "fucompp\n\tfnstsw\t%0";
- else
- return "fcompp\n\tfnstsw\t%0";
- }
- }
- else
- {
- /* Encoded here as eflags_p | intmode | unordered_p | stack_top_dies. */
-
- static const char * const alt[16] =
- {
- "fcom%Z2\t%y2\n\tfnstsw\t%0",
- "fcomp%Z2\t%y2\n\tfnstsw\t%0",
- "fucom%Z2\t%y2\n\tfnstsw\t%0",
- "fucomp%Z2\t%y2\n\tfnstsw\t%0",
-
- "ficom%Z2\t%y2\n\tfnstsw\t%0",
- "ficomp%Z2\t%y2\n\tfnstsw\t%0",
- NULL,
- NULL,
-
- "fcomi\t{%y1, %0|%0, %y1}",
- "fcomip\t{%y1, %0|%0, %y1}",
- "fucomi\t{%y1, %0|%0, %y1}",
- "fucomip\t{%y1, %0|%0, %y1}",
-
- NULL,
- NULL,
- NULL,
- NULL
- };
-
- int mask;
- const char *ret;
-
- mask = eflags_p << 3;
- mask |= (GET_MODE_CLASS (GET_MODE (cmp_op1)) == MODE_INT) << 2;
- mask |= unordered_p << 1;
- mask |= stack_top_dies;
-
- gcc_assert (mask < 16);
- ret = alt[mask];
- gcc_assert (ret);
-
- return ret;
- }
-}
-
-void
-ix86_output_addr_vec_elt (FILE *file, int value)
-{
- const char *directive = ASM_LONG;
-
-#ifdef ASM_QUAD
- if (TARGET_LP64)
- directive = ASM_QUAD;
-#else
- gcc_assert (!TARGET_64BIT);
-#endif
-
- fprintf (file, "%s%s%d\n", directive, LPREFIX, value);
-}
-
-void
-ix86_output_addr_diff_elt (FILE *file, int value, int rel)
-{
- const char *directive = ASM_LONG;
-
-#ifdef ASM_QUAD
- if (TARGET_64BIT && CASE_VECTOR_MODE == DImode)
- directive = ASM_QUAD;
-#else
- gcc_assert (!TARGET_64BIT);
-#endif
- /* We can't use @GOTOFF for text labels on VxWorks; see gotoff_operand. */
- if (TARGET_64BIT || TARGET_VXWORKS_RTP)
- fprintf (file, "%s%s%d-%s%d\n",
- directive, LPREFIX, value, LPREFIX, rel);
- else if (HAVE_AS_GOTOFF_IN_DATA)
- fprintf (file, ASM_LONG "%s%d@GOTOFF\n", LPREFIX, value);
-#if TARGET_MACHO
- else if (TARGET_MACHO)
- {
- fprintf (file, ASM_LONG "%s%d-", LPREFIX, value);
- machopic_output_function_base_name (file);
- putc ('\n', file);
- }
-#endif
- else
- asm_fprintf (file, ASM_LONG "%U%s+[.-%s%d]\n",
- GOT_SYMBOL_NAME, LPREFIX, value);
-}
-
-/* Generate either "mov $0, reg" or "xor reg, reg", as appropriate
- for the target. */
-
-void
-ix86_expand_clear (rtx dest)
-{
- rtx tmp;
-
- /* We play register width games, which are only valid after reload. */
- gcc_assert (reload_completed);
-
- /* Avoid HImode and its attendant prefix byte. */
- if (GET_MODE_SIZE (GET_MODE (dest)) < 4)
- dest = gen_rtx_REG (SImode, REGNO (dest));
- tmp = gen_rtx_SET (VOIDmode, dest, const0_rtx);
-
- /* This predicate should match that for movsi_xor and movdi_xor_rex64. */
- if (!TARGET_USE_MOV0 || optimize_insn_for_speed_p ())
- {
- rtx clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
- tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
- }
-
- emit_insn (tmp);
-}
-
-/* X is an unchanging MEM. If it is a constant pool reference, return
- the constant pool rtx, else NULL. */
-
-rtx
-maybe_get_pool_constant (rtx x)
-{
- x = ix86_delegitimize_address (XEXP (x, 0));
-
- if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
- return get_pool_constant (x);
-
- return NULL_RTX;
-}
-
-void
-ix86_expand_move (enum machine_mode mode, rtx operands[])
-{
- rtx op0, op1;
- enum tls_model model;
-
- op0 = operands[0];
- op1 = operands[1];
-
- if (GET_CODE (op1) == SYMBOL_REF)
- {
- model = SYMBOL_REF_TLS_MODEL (op1);
- if (model)
- {
- op1 = legitimize_tls_address (op1, model, true);
- op1 = force_operand (op1, op0);
- if (op1 == op0)
- return;
- op1 = convert_to_mode (mode, op1, 1);
- }
- else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
- && SYMBOL_REF_DLLIMPORT_P (op1))
- op1 = legitimize_dllimport_symbol (op1, false);
- }
- else if (GET_CODE (op1) == CONST
- && GET_CODE (XEXP (op1, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (op1, 0), 0)) == SYMBOL_REF)
- {
- rtx addend = XEXP (XEXP (op1, 0), 1);
- rtx symbol = XEXP (XEXP (op1, 0), 0);
- rtx tmp = NULL;
-
- model = SYMBOL_REF_TLS_MODEL (symbol);
- if (model)
- tmp = legitimize_tls_address (symbol, model, true);
- else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
- && SYMBOL_REF_DLLIMPORT_P (symbol))
- tmp = legitimize_dllimport_symbol (symbol, true);
-
- if (tmp)
- {
- tmp = force_operand (tmp, NULL);
- tmp = expand_simple_binop (Pmode, PLUS, tmp, addend,
- op0, 1, OPTAB_DIRECT);
- if (tmp == op0)
- return;
- op1 = convert_to_mode (mode, tmp, 1);
- }
- }
-
- if ((flag_pic || MACHOPIC_INDIRECT)
- && symbolic_operand (op1, mode))
- {
- if (TARGET_MACHO && !TARGET_64BIT)
- {
-#if TARGET_MACHO
- /* dynamic-no-pic */
- if (MACHOPIC_INDIRECT)
- {
- rtx temp = ((reload_in_progress
- || ((op0 && REG_P (op0))
- && mode == Pmode))
- ? op0 : gen_reg_rtx (Pmode));
- op1 = machopic_indirect_data_reference (op1, temp);
- if (MACHOPIC_PURE)
- op1 = machopic_legitimize_pic_address (op1, mode,
- temp == op1 ? 0 : temp);
- }
- if (op0 != op1 && GET_CODE (op0) != MEM)
- {
- rtx insn = gen_rtx_SET (VOIDmode, op0, op1);
- emit_insn (insn);
- return;
- }
- if (GET_CODE (op0) == MEM)
- op1 = force_reg (Pmode, op1);
- else
- {
- rtx temp = op0;
- if (GET_CODE (temp) != REG)
- temp = gen_reg_rtx (Pmode);
- temp = legitimize_pic_address (op1, temp);
- if (temp == op0)
- return;
- op1 = temp;
- }
- /* dynamic-no-pic */
-#endif
- }
- else
- {
- if (MEM_P (op0))
- op1 = force_reg (mode, op1);
- else if (!(TARGET_64BIT && x86_64_movabs_operand (op1, DImode)))
- {
- rtx reg = can_create_pseudo_p () ? NULL_RTX : op0;
- op1 = legitimize_pic_address (op1, reg);
- if (op0 == op1)
- return;
- op1 = convert_to_mode (mode, op1, 1);
- }
- }
- }
- else
- {
- if (MEM_P (op0)
- && (PUSH_ROUNDING (GET_MODE_SIZE (mode)) != GET_MODE_SIZE (mode)
- || !push_operand (op0, mode))
- && MEM_P (op1))
- op1 = force_reg (mode, op1);
-
- if (push_operand (op0, mode)
- && ! general_no_elim_operand (op1, mode))
- op1 = copy_to_mode_reg (mode, op1);
-
- /* Force large constants in 64bit compilation into register
- to get them CSEed. */
- if (can_create_pseudo_p ()
- && (mode == DImode) && TARGET_64BIT
- && immediate_operand (op1, mode)
- && !x86_64_zext_immediate_operand (op1, VOIDmode)
- && !register_operand (op0, mode)
- && optimize)
- op1 = copy_to_mode_reg (mode, op1);
-
- if (can_create_pseudo_p ()
- && FLOAT_MODE_P (mode)
- && GET_CODE (op1) == CONST_DOUBLE)
- {
- /* If we are loading a floating point constant to a register,
- force the value to memory now, since we'll get better code
- out the back end. */
-
- op1 = validize_mem (force_const_mem (mode, op1));
- if (!register_operand (op0, mode))
- {
- rtx temp = gen_reg_rtx (mode);
- emit_insn (gen_rtx_SET (VOIDmode, temp, op1));
- emit_move_insn (op0, temp);
- return;
- }
- }
- }
-
- emit_insn (gen_rtx_SET (VOIDmode, op0, op1));
-}
-
-void
-ix86_expand_vector_move (enum machine_mode mode, rtx operands[])
-{
- rtx op0 = operands[0], op1 = operands[1];
- unsigned int align = GET_MODE_ALIGNMENT (mode);
-
- /* Force constants other than zero into memory. We do not know how
- the instructions used to build constants modify the upper 64 bits
- of the register, once we have that information we may be able
- to handle some of them more efficiently. */
- if (can_create_pseudo_p ()
- && register_operand (op0, mode)
- && (CONSTANT_P (op1)
- || (GET_CODE (op1) == SUBREG
- && CONSTANT_P (SUBREG_REG (op1))))
- && !standard_sse_constant_p (op1))
- op1 = validize_mem (force_const_mem (mode, op1));
-
- /* We need to check memory alignment for SSE mode since attribute
- can make operands unaligned. */
- if (can_create_pseudo_p ()
- && SSE_REG_MODE_P (mode)
- && ((MEM_P (op0) && (MEM_ALIGN (op0) < align))
- || (MEM_P (op1) && (MEM_ALIGN (op1) < align))))
- {
- rtx tmp[2];
-
- /* ix86_expand_vector_move_misalign() does not like constants ... */
- if (CONSTANT_P (op1)
- || (GET_CODE (op1) == SUBREG
- && CONSTANT_P (SUBREG_REG (op1))))
- op1 = validize_mem (force_const_mem (mode, op1));
-
- /* ... nor both arguments in memory. */
- if (!register_operand (op0, mode)
- && !register_operand (op1, mode))
- op1 = force_reg (mode, op1);
-
- tmp[0] = op0; tmp[1] = op1;
- ix86_expand_vector_move_misalign (mode, tmp);
- return;
- }
-
- /* Make operand1 a register if it isn't already. */
- if (can_create_pseudo_p ()
- && !register_operand (op0, mode)
- && !register_operand (op1, mode))
- {
- emit_move_insn (op0, force_reg (GET_MODE (op0), op1));
- return;
- }
-
- emit_insn (gen_rtx_SET (VOIDmode, op0, op1));
-}
-
-/* Split 32-byte AVX unaligned load and store if needed. */
-
-static void
-ix86_avx256_split_vector_move_misalign (rtx op0, rtx op1)
-{
- rtx m;
- rtx (*extract) (rtx, rtx, rtx);
- rtx (*load_unaligned) (rtx, rtx);
- rtx (*store_unaligned) (rtx, rtx);
- enum machine_mode mode;
-
- switch (GET_MODE (op0))
- {
- default:
- gcc_unreachable ();
- case V32QImode:
- extract = gen_avx_vextractf128v32qi;
- load_unaligned = gen_avx_loaddqu256;
- store_unaligned = gen_avx_storedqu256;
- mode = V16QImode;
- break;
- case V8SFmode:
- extract = gen_avx_vextractf128v8sf;
- load_unaligned = gen_avx_loadups256;
- store_unaligned = gen_avx_storeups256;
- mode = V4SFmode;
- break;
- case V4DFmode:
- extract = gen_avx_vextractf128v4df;
- load_unaligned = gen_avx_loadupd256;
- store_unaligned = gen_avx_storeupd256;
- mode = V2DFmode;
- break;
- }
-
- if (MEM_P (op1))
- {
- if (TARGET_AVX256_SPLIT_UNALIGNED_LOAD)
- {
- rtx r = gen_reg_rtx (mode);
- m = adjust_address (op1, mode, 0);
- emit_move_insn (r, m);
- m = adjust_address (op1, mode, 16);
- r = gen_rtx_VEC_CONCAT (GET_MODE (op0), r, m);
- emit_move_insn (op0, r);
- }
- else
- emit_insn (load_unaligned (op0, op1));
- }
- else if (MEM_P (op0))
- {
- if (TARGET_AVX256_SPLIT_UNALIGNED_STORE)
- {
- m = adjust_address (op0, mode, 0);
- emit_insn (extract (m, op1, const0_rtx));
- m = adjust_address (op0, mode, 16);
- emit_insn (extract (m, op1, const1_rtx));
- }
- else
- emit_insn (store_unaligned (op0, op1));
- }
- else
- gcc_unreachable ();
-}
-
-/* Implement the movmisalign patterns for SSE. Non-SSE modes go
- straight to ix86_expand_vector_move. */
-/* Code generation for scalar reg-reg moves of single and double precision data:
- if (x86_sse_partial_reg_dependency == true | x86_sse_split_regs == true)
- movaps reg, reg
- else
- movss reg, reg
- if (x86_sse_partial_reg_dependency == true)
- movapd reg, reg
- else
- movsd reg, reg
-
- Code generation for scalar loads of double precision data:
- if (x86_sse_split_regs == true)
- movlpd mem, reg (gas syntax)
- else
- movsd mem, reg
-
- Code generation for unaligned packed loads of single precision data
- (x86_sse_unaligned_move_optimal overrides x86_sse_partial_reg_dependency):
- if (x86_sse_unaligned_move_optimal)
- movups mem, reg
-
- if (x86_sse_partial_reg_dependency == true)
- {
- xorps reg, reg
- movlps mem, reg
- movhps mem+8, reg
- }
- else
- {
- movlps mem, reg
- movhps mem+8, reg
- }
-
- Code generation for unaligned packed loads of double precision data
- (x86_sse_unaligned_move_optimal overrides x86_sse_split_regs):
- if (x86_sse_unaligned_move_optimal)
- movupd mem, reg
-
- if (x86_sse_split_regs == true)
- {
- movlpd mem, reg
- movhpd mem+8, reg
- }
- else
- {
- movsd mem, reg
- movhpd mem+8, reg
- }
- */
-
-void
-ix86_expand_vector_move_misalign (enum machine_mode mode, rtx operands[])
-{
- rtx op0, op1, m;
-
- op0 = operands[0];
- op1 = operands[1];
-
- if (TARGET_AVX
- && GET_MODE_SIZE (mode) == 32)
- {
- switch (GET_MODE_CLASS (mode))
- {
- case MODE_VECTOR_INT:
- case MODE_INT:
- op0 = gen_lowpart (V32QImode, op0);
- op1 = gen_lowpart (V32QImode, op1);
- /* FALLTHRU */
-
- case MODE_VECTOR_FLOAT:
- ix86_avx256_split_vector_move_misalign (op0, op1);
- break;
-
- default:
- gcc_unreachable ();
- }
-
- return;
- }
-
- if (MEM_P (op1))
- {
- /* ??? If we have typed data, then it would appear that using
- movdqu is the only way to get unaligned data loaded with
- integer type. */
- if (TARGET_SSE2 && GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
- {
- op0 = gen_lowpart (V16QImode, op0);
- op1 = gen_lowpart (V16QImode, op1);
- /* We will eventually emit movups based on insn attributes. */
- emit_insn (gen_sse2_loaddqu (op0, op1));
- }
- else if (TARGET_SSE2 && mode == V2DFmode)
- {
- rtx zero;
-
- if (TARGET_AVX
- || TARGET_SSE_UNALIGNED_LOAD_OPTIMAL
- || TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL
- || optimize_function_for_size_p (cfun))
- {
- /* We will eventually emit movups based on insn attributes. */
- emit_insn (gen_sse2_loadupd (op0, op1));
- return;
- }
-
- /* When SSE registers are split into halves, we can avoid
- writing to the top half twice. */
- if (TARGET_SSE_SPLIT_REGS)
- {
- emit_clobber (op0);
- zero = op0;
- }
- else
- {
- /* ??? Not sure about the best option for the Intel chips.
- The following would seem to satisfy; the register is
- entirely cleared, breaking the dependency chain. We
- then store to the upper half, with a dependency depth
- of one. A rumor has it that Intel recommends two movsd
- followed by an unpacklpd, but this is unconfirmed. And
- given that the dependency depth of the unpacklpd would
- still be one, I'm not sure why this would be better. */
- zero = CONST0_RTX (V2DFmode);
- }
-
- m = adjust_address (op1, DFmode, 0);
- emit_insn (gen_sse2_loadlpd (op0, zero, m));
- m = adjust_address (op1, DFmode, 8);
- emit_insn (gen_sse2_loadhpd (op0, op0, m));
- }
- else
- {
- if (TARGET_AVX
- || TARGET_SSE_UNALIGNED_LOAD_OPTIMAL
- || TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL
- || optimize_function_for_size_p (cfun))
- {
- op0 = gen_lowpart (V4SFmode, op0);
- op1 = gen_lowpart (V4SFmode, op1);
- emit_insn (gen_sse_loadups (op0, op1));
- return;
- }
-
- if (TARGET_SSE_PARTIAL_REG_DEPENDENCY)
- emit_move_insn (op0, CONST0_RTX (mode));
- else
- emit_clobber (op0);
-
- if (mode != V4SFmode)
- op0 = gen_lowpart (V4SFmode, op0);
-
- m = adjust_address (op1, V2SFmode, 0);
- emit_insn (gen_sse_loadlps (op0, op0, m));
- m = adjust_address (op1, V2SFmode, 8);
- emit_insn (gen_sse_loadhps (op0, op0, m));
- }
- }
- else if (MEM_P (op0))
- {
- if (TARGET_SSE2 && GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
- {
- op0 = gen_lowpart (V16QImode, op0);
- op1 = gen_lowpart (V16QImode, op1);
- /* We will eventually emit movups based on insn attributes. */
- emit_insn (gen_sse2_storedqu (op0, op1));
- }
- else if (TARGET_SSE2 && mode == V2DFmode)
- {
- if (TARGET_AVX
- || TARGET_SSE_UNALIGNED_STORE_OPTIMAL
- || TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL
- || optimize_function_for_size_p (cfun))
- /* We will eventually emit movups based on insn attributes. */
- emit_insn (gen_sse2_storeupd (op0, op1));
- else
- {
- m = adjust_address (op0, DFmode, 0);
- emit_insn (gen_sse2_storelpd (m, op1));
- m = adjust_address (op0, DFmode, 8);
- emit_insn (gen_sse2_storehpd (m, op1));
- }
- }
- else
- {
- if (mode != V4SFmode)
- op1 = gen_lowpart (V4SFmode, op1);
-
- if (TARGET_AVX
- || TARGET_SSE_UNALIGNED_STORE_OPTIMAL
- || TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL
- || optimize_function_for_size_p (cfun))
- {
- op0 = gen_lowpart (V4SFmode, op0);
- emit_insn (gen_sse_storeups (op0, op1));
- }
- else
- {
- m = adjust_address (op0, V2SFmode, 0);
- emit_insn (gen_sse_storelps (m, op1));
- m = adjust_address (op0, V2SFmode, 8);
- emit_insn (gen_sse_storehps (m, op1));
- }
- }
- }
- else
- gcc_unreachable ();
-}
-
-/* Expand a push in MODE. This is some mode for which we do not support
- proper push instructions, at least from the registers that we expect
- the value to live in. */
-
-void
-ix86_expand_push (enum machine_mode mode, rtx x)
-{
- rtx tmp;
-
- tmp = expand_simple_binop (Pmode, PLUS, stack_pointer_rtx,
- GEN_INT (-GET_MODE_SIZE (mode)),
- stack_pointer_rtx, 1, OPTAB_DIRECT);
- if (tmp != stack_pointer_rtx)
- emit_move_insn (stack_pointer_rtx, tmp);
-
- tmp = gen_rtx_MEM (mode, stack_pointer_rtx);
-
- /* When we push an operand onto stack, it has to be aligned at least
- at the function argument boundary. However since we don't have
- the argument type, we can't determine the actual argument
- boundary. */
- emit_move_insn (tmp, x);
-}
-
-/* Helper function of ix86_fixup_binary_operands to canonicalize
- operand order. Returns true if the operands should be swapped. */
-
-static bool
-ix86_swap_binary_operands_p (enum rtx_code code, enum machine_mode mode,
- rtx operands[])
-{
- rtx dst = operands[0];
- rtx src1 = operands[1];
- rtx src2 = operands[2];
-
- /* If the operation is not commutative, we can't do anything. */
- if (GET_RTX_CLASS (code) != RTX_COMM_ARITH)
- return false;
-
- /* Highest priority is that src1 should match dst. */
- if (rtx_equal_p (dst, src1))
- return false;
- if (rtx_equal_p (dst, src2))
- return true;
-
- /* Next highest priority is that immediate constants come second. */
- if (immediate_operand (src2, mode))
- return false;
- if (immediate_operand (src1, mode))
- return true;
-
- /* Lowest priority is that memory references should come second. */
- if (MEM_P (src2))
- return false;
- if (MEM_P (src1))
- return true;
-
- return false;
-}
-
-
-/* Fix up OPERANDS to satisfy ix86_binary_operator_ok. Return the
- destination to use for the operation. If different from the true
- destination in operands[0], a copy operation will be required. */
-
-rtx
-ix86_fixup_binary_operands (enum rtx_code code, enum machine_mode mode,
- rtx operands[])
-{
- rtx dst = operands[0];
- rtx src1 = operands[1];
- rtx src2 = operands[2];
-
- /* Canonicalize operand order. */
- if (ix86_swap_binary_operands_p (code, mode, operands))
- {
- rtx temp;
-
- /* It is invalid to swap operands of different modes. */
- gcc_assert (GET_MODE (src1) == GET_MODE (src2));
-
- temp = src1;
- src1 = src2;
- src2 = temp;
- }
-
- /* Both source operands cannot be in memory. */
- if (MEM_P (src1) && MEM_P (src2))
- {
- /* Optimization: Only read from memory once. */
- if (rtx_equal_p (src1, src2))
- {
- src2 = force_reg (mode, src2);
- src1 = src2;
- }
- else
- src2 = force_reg (mode, src2);
- }
-
- /* If the destination is memory, and we do not have matching source
- operands, do things in registers. */
- if (MEM_P (dst) && !rtx_equal_p (dst, src1))
- dst = gen_reg_rtx (mode);
-
- /* Source 1 cannot be a constant. */
- if (CONSTANT_P (src1))
- src1 = force_reg (mode, src1);
-
- /* Source 1 cannot be a non-matching memory. */
- if (MEM_P (src1) && !rtx_equal_p (dst, src1))
- src1 = force_reg (mode, src1);
-
- /* Improve address combine. */
- if (code == PLUS
- && GET_MODE_CLASS (mode) == MODE_INT
- && MEM_P (src2))
- src2 = force_reg (mode, src2);
-
- operands[1] = src1;
- operands[2] = src2;
- return dst;
-}
-
-/* Similarly, but assume that the destination has already been
- set up properly. */
-
-void
-ix86_fixup_binary_operands_no_copy (enum rtx_code code,
- enum machine_mode mode, rtx operands[])
-{
- rtx dst = ix86_fixup_binary_operands (code, mode, operands);
- gcc_assert (dst == operands[0]);
-}
-
-/* Attempt to expand a binary operator. Make the expansion closer to the
- actual machine, then just general_operand, which will allow 3 separate
- memory references (one output, two input) in a single insn. */
-
-void
-ix86_expand_binary_operator (enum rtx_code code, enum machine_mode mode,
- rtx operands[])
-{
- rtx src1, src2, dst, op, clob;
-
- dst = ix86_fixup_binary_operands (code, mode, operands);
- src1 = operands[1];
- src2 = operands[2];
-
- /* Emit the instruction. */
-
- op = gen_rtx_SET (VOIDmode, dst, gen_rtx_fmt_ee (code, mode, src1, src2));
- if (reload_in_progress)
- {
- /* Reload doesn't know about the flags register, and doesn't know that
- it doesn't want to clobber it. We can only do this with PLUS. */
- gcc_assert (code == PLUS);
- emit_insn (op);
- }
- else if (reload_completed
- && code == PLUS
- && !rtx_equal_p (dst, src1))
- {
- /* This is going to be an LEA; avoid splitting it later. */
- emit_insn (op);
- }
- else
- {
- clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
- emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
- }
-
- /* Fix up the destination if needed. */
- if (dst != operands[0])
- emit_move_insn (operands[0], dst);
-}
-
-/* Expand vector logical operation CODE (AND, IOR, XOR) in MODE with
- the given OPERANDS. */
-
-void
-ix86_expand_vector_logical_operator (enum rtx_code code, enum machine_mode mode,
- rtx operands[])
-{
- rtx op1 = NULL_RTX, op2 = NULL_RTX;
- if (GET_CODE (operands[1]) == SUBREG)
- {
- op1 = operands[1];
- op2 = operands[2];
- }
- else if (GET_CODE (operands[2]) == SUBREG)
- {
- op1 = operands[2];
- op2 = operands[1];
- }
- /* Optimize (__m128i) d | (__m128i) e and similar code
- when d and e are float vectors into float vector logical
- insn. In C/C++ without using intrinsics there is no other way
- to express vector logical operation on float vectors than
- to cast them temporarily to integer vectors. */
- if (op1
- && !TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL
- && ((GET_CODE (op2) == SUBREG || GET_CODE (op2) == CONST_VECTOR))
- && GET_MODE_CLASS (GET_MODE (SUBREG_REG (op1))) == MODE_VECTOR_FLOAT
- && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op1))) == GET_MODE_SIZE (mode)
- && SUBREG_BYTE (op1) == 0
- && (GET_CODE (op2) == CONST_VECTOR
- || (GET_MODE (SUBREG_REG (op1)) == GET_MODE (SUBREG_REG (op2))
- && SUBREG_BYTE (op2) == 0))
- && can_create_pseudo_p ())
- {
- rtx dst;
- switch (GET_MODE (SUBREG_REG (op1)))
- {
- case V4SFmode:
- case V8SFmode:
- case V2DFmode:
- case V4DFmode:
- dst = gen_reg_rtx (GET_MODE (SUBREG_REG (op1)));
- if (GET_CODE (op2) == CONST_VECTOR)
- {
- op2 = gen_lowpart (GET_MODE (dst), op2);
- op2 = force_reg (GET_MODE (dst), op2);
- }
- else
- {
- op1 = operands[1];
- op2 = SUBREG_REG (operands[2]);
- if (!nonimmediate_operand (op2, GET_MODE (dst)))
- op2 = force_reg (GET_MODE (dst), op2);
- }
- op1 = SUBREG_REG (op1);
- if (!nonimmediate_operand (op1, GET_MODE (dst)))
- op1 = force_reg (GET_MODE (dst), op1);
- emit_insn (gen_rtx_SET (VOIDmode, dst,
- gen_rtx_fmt_ee (code, GET_MODE (dst),
- op1, op2)));
- emit_move_insn (operands[0], gen_lowpart (mode, dst));
- return;
- default:
- break;
- }
- }
- if (!nonimmediate_operand (operands[1], mode))
- operands[1] = force_reg (mode, operands[1]);
- if (!nonimmediate_operand (operands[2], mode))
- operands[2] = force_reg (mode, operands[2]);
- ix86_fixup_binary_operands_no_copy (code, mode, operands);
- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
- gen_rtx_fmt_ee (code, mode, operands[1],
- operands[2])));
-}
-
-/* Return TRUE or FALSE depending on whether the binary operator meets the
- appropriate constraints. */
-
-bool
-ix86_binary_operator_ok (enum rtx_code code, enum machine_mode mode,
- rtx operands[3])
-{
- rtx dst = operands[0];
- rtx src1 = operands[1];
- rtx src2 = operands[2];
-
- /* Both source operands cannot be in memory. */
- if (MEM_P (src1) && MEM_P (src2))
- return false;
-
- /* Canonicalize operand order for commutative operators. */
- if (ix86_swap_binary_operands_p (code, mode, operands))
- {
- rtx temp = src1;
- src1 = src2;
- src2 = temp;
- }
-
- /* If the destination is memory, we must have a matching source operand. */
- if (MEM_P (dst) && !rtx_equal_p (dst, src1))
- return false;
-
- /* Source 1 cannot be a constant. */
- if (CONSTANT_P (src1))
- return false;
-
- /* Source 1 cannot be a non-matching memory. */
- if (MEM_P (src1) && !rtx_equal_p (dst, src1))
- /* Support "andhi/andsi/anddi" as a zero-extending move. */
- return (code == AND
- && (mode == HImode
- || mode == SImode
- || (TARGET_64BIT && mode == DImode))
- && satisfies_constraint_L (src2));
-
- return true;
-}
-
-/* Attempt to expand a unary operator. Make the expansion closer to the
- actual machine, then just general_operand, which will allow 2 separate
- memory references (one output, one input) in a single insn. */
-
-void
-ix86_expand_unary_operator (enum rtx_code code, enum machine_mode mode,
- rtx operands[])
-{
- int matching_memory;
- rtx src, dst, op, clob;
-
- dst = operands[0];
- src = operands[1];
-
- /* If the destination is memory, and we do not have matching source
- operands, do things in registers. */
- matching_memory = 0;
- if (MEM_P (dst))
- {
- if (rtx_equal_p (dst, src))
- matching_memory = 1;
- else
- dst = gen_reg_rtx (mode);
- }
-
- /* When source operand is memory, destination must match. */
- if (MEM_P (src) && !matching_memory)
- src = force_reg (mode, src);
-
- /* Emit the instruction. */
-
- op = gen_rtx_SET (VOIDmode, dst, gen_rtx_fmt_e (code, mode, src));
- if (reload_in_progress || code == NOT)
- {
- /* Reload doesn't know about the flags register, and doesn't know that
- it doesn't want to clobber it. */
- gcc_assert (code == NOT);
- emit_insn (op);
- }
- else
- {
- clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
- emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
- }
-
- /* Fix up the destination if needed. */
- if (dst != operands[0])
- emit_move_insn (operands[0], dst);
-}
-
-/* Split 32bit/64bit divmod with 8bit unsigned divmod if dividend and
- divisor are within the range [0-255]. */
-
-void
-ix86_split_idivmod (enum machine_mode mode, rtx operands[],
- bool signed_p)
-{
- rtx end_label, qimode_label;
- rtx insn, div, mod;
- rtx scratch, tmp0, tmp1, tmp2;
- rtx (*gen_divmod4_1) (rtx, rtx, rtx, rtx);
- rtx (*gen_zero_extend) (rtx, rtx);
- rtx (*gen_test_ccno_1) (rtx, rtx);
-
- switch (mode)
- {
- case SImode:
- gen_divmod4_1 = signed_p ? gen_divmodsi4_1 : gen_udivmodsi4_1;
- gen_test_ccno_1 = gen_testsi_ccno_1;
- gen_zero_extend = gen_zero_extendqisi2;
- break;
- case DImode:
- gen_divmod4_1 = signed_p ? gen_divmoddi4_1 : gen_udivmoddi4_1;
- gen_test_ccno_1 = gen_testdi_ccno_1;
- gen_zero_extend = gen_zero_extendqidi2;
- break;
- default:
- gcc_unreachable ();
- }
-
- end_label = gen_label_rtx ();
- qimode_label = gen_label_rtx ();
-
- scratch = gen_reg_rtx (mode);
-
- /* Use 8bit unsigned divimod if dividend and divisor are within
- the range [0-255]. */
- emit_move_insn (scratch, operands[2]);
- scratch = expand_simple_binop (mode, IOR, scratch, operands[3],
- scratch, 1, OPTAB_DIRECT);
- emit_insn (gen_test_ccno_1 (scratch, GEN_INT (-0x100)));
- tmp0 = gen_rtx_REG (CCNOmode, FLAGS_REG);
- tmp0 = gen_rtx_EQ (VOIDmode, tmp0, const0_rtx);
- tmp0 = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp0,
- gen_rtx_LABEL_REF (VOIDmode, qimode_label),
- pc_rtx);
- insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp0));
- predict_jump (REG_BR_PROB_BASE * 50 / 100);
- JUMP_LABEL (insn) = qimode_label;
-
- /* Generate original signed/unsigned divimod. */
- div = gen_divmod4_1 (operands[0], operands[1],
- operands[2], operands[3]);
- emit_insn (div);
-
- /* Branch to the end. */
- emit_jump_insn (gen_jump (end_label));
- emit_barrier ();
-
- /* Generate 8bit unsigned divide. */
- emit_label (qimode_label);
- /* Don't use operands[0] for result of 8bit divide since not all
- registers support QImode ZERO_EXTRACT. */
- tmp0 = simplify_gen_subreg (HImode, scratch, mode, 0);
- tmp1 = simplify_gen_subreg (HImode, operands[2], mode, 0);
- tmp2 = simplify_gen_subreg (QImode, operands[3], mode, 0);
- emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, tmp2));
-
- if (signed_p)
- {
- div = gen_rtx_DIV (SImode, operands[2], operands[3]);
- mod = gen_rtx_MOD (SImode, operands[2], operands[3]);
- }
- else
- {
- div = gen_rtx_UDIV (SImode, operands[2], operands[3]);
- mod = gen_rtx_UMOD (SImode, operands[2], operands[3]);
- }
-
- /* Extract remainder from AH. */
- tmp1 = gen_rtx_ZERO_EXTRACT (mode, tmp0, GEN_INT (8), GEN_INT (8));
- if (REG_P (operands[1]))
- insn = emit_move_insn (operands[1], tmp1);
- else
- {
- /* Need a new scratch register since the old one has result
- of 8bit divide. */
- scratch = gen_reg_rtx (mode);
- emit_move_insn (scratch, tmp1);
- insn = emit_move_insn (operands[1], scratch);
- }
- set_unique_reg_note (insn, REG_EQUAL, mod);
-
- /* Zero extend quotient from AL. */
- tmp1 = gen_lowpart (QImode, tmp0);
- insn = emit_insn (gen_zero_extend (operands[0], tmp1));
- set_unique_reg_note (insn, REG_EQUAL, div);
-
- emit_label (end_label);
-}
-
-#define LEA_MAX_STALL (3)
-#define LEA_SEARCH_THRESHOLD (LEA_MAX_STALL << 1)
-
-/* Increase given DISTANCE in half-cycles according to
- dependencies between PREV and NEXT instructions.
- Add 1 half-cycle if there is no dependency and
- go to next cycle if there is some dependecy. */
-
-static unsigned int
-increase_distance (rtx prev, rtx next, unsigned int distance)
-{
- df_ref *use_rec;
- df_ref *def_rec;
-
- if (!prev || !next)
- return distance + (distance & 1) + 2;
-
- if (!DF_INSN_USES (next) || !DF_INSN_DEFS (prev))
- return distance + 1;
-
- for (use_rec = DF_INSN_USES (next); *use_rec; use_rec++)
- for (def_rec = DF_INSN_DEFS (prev); *def_rec; def_rec++)
- if (!DF_REF_IS_ARTIFICIAL (*def_rec)
- && DF_REF_REGNO (*use_rec) == DF_REF_REGNO (*def_rec))
- return distance + (distance & 1) + 2;
-
- return distance + 1;
-}
-
-/* Function checks if instruction INSN defines register number
- REGNO1 or REGNO2. */
-
-static bool
-insn_defines_reg (unsigned int regno1, unsigned int regno2,
- rtx insn)
-{
- df_ref *def_rec;
-
- for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
- if (DF_REF_REG_DEF_P (*def_rec)
- && !DF_REF_IS_ARTIFICIAL (*def_rec)
- && (regno1 == DF_REF_REGNO (*def_rec)
- || regno2 == DF_REF_REGNO (*def_rec)))
- {
- return true;
- }
-
- return false;
-}
-
-/* Function checks if instruction INSN uses register number
- REGNO as a part of address expression. */
-
-static bool
-insn_uses_reg_mem (unsigned int regno, rtx insn)
-{
- df_ref *use_rec;
-
- for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++)
- if (DF_REF_REG_MEM_P (*use_rec) && regno == DF_REF_REGNO (*use_rec))
- return true;
-
- return false;
-}
-
-/* Search backward for non-agu definition of register number REGNO1
- or register number REGNO2 in basic block starting from instruction
- START up to head of basic block or instruction INSN.
-
- Function puts true value into *FOUND var if definition was found
- and false otherwise.
-
- Distance in half-cycles between START and found instruction or head
- of BB is added to DISTANCE and returned. */
-
-static int
-distance_non_agu_define_in_bb (unsigned int regno1, unsigned int regno2,
- rtx insn, int distance,
- rtx start, bool *found)
-{
- basic_block bb = start ? BLOCK_FOR_INSN (start) : NULL;
- rtx prev = start;
- rtx next = NULL;
-
- *found = false;
-
- while (prev
- && prev != insn
- && distance < LEA_SEARCH_THRESHOLD)
- {
- if (NONDEBUG_INSN_P (prev) && NONJUMP_INSN_P (prev))
- {
- distance = increase_distance (prev, next, distance);
- if (insn_defines_reg (regno1, regno2, prev))
- {
- if (recog_memoized (prev) < 0
- || get_attr_type (prev) != TYPE_LEA)
- {
- *found = true;
- return distance;
- }
- }
-
- next = prev;
- }
- if (prev == BB_HEAD (bb))
- break;
-
- prev = PREV_INSN (prev);
- }
-
- return distance;
-}
-
-/* Search backward for non-agu definition of register number REGNO1
- or register number REGNO2 in INSN's basic block until
- 1. Pass LEA_SEARCH_THRESHOLD instructions, or
- 2. Reach neighbour BBs boundary, or
- 3. Reach agu definition.
- Returns the distance between the non-agu definition point and INSN.
- If no definition point, returns -1. */
-
-static int
-distance_non_agu_define (unsigned int regno1, unsigned int regno2,
- rtx insn)
-{
- basic_block bb = BLOCK_FOR_INSN (insn);
- int distance = 0;
- bool found = false;
-
- if (insn != BB_HEAD (bb))
- distance = distance_non_agu_define_in_bb (regno1, regno2, insn,
- distance, PREV_INSN (insn),
- &found);
-
- if (!found && distance < LEA_SEARCH_THRESHOLD)
- {
- edge e;
- edge_iterator ei;
- bool simple_loop = false;
-
- FOR_EACH_EDGE (e, ei, bb->preds)
- if (e->src == bb)
- {
- simple_loop = true;
- break;
- }
-
- if (simple_loop)
- distance = distance_non_agu_define_in_bb (regno1, regno2,
- insn, distance,
- BB_END (bb), &found);
- else
- {
- int shortest_dist = -1;
- bool found_in_bb = false;
-
- FOR_EACH_EDGE (e, ei, bb->preds)
- {
- int bb_dist
- = distance_non_agu_define_in_bb (regno1, regno2,
- insn, distance,
- BB_END (e->src),
- &found_in_bb);
- if (found_in_bb)
- {
- if (shortest_dist < 0)
- shortest_dist = bb_dist;
- else if (bb_dist > 0)
- shortest_dist = MIN (bb_dist, shortest_dist);
-
- found = true;
- }
- }
-
- distance = shortest_dist;
- }
- }
-
- /* get_attr_type may modify recog data. We want to make sure
- that recog data is valid for instruction INSN, on which
- distance_non_agu_define is called. INSN is unchanged here. */
- extract_insn_cached (insn);
-
- if (!found)
- return -1;
-
- return distance >> 1;
-}
-
-/* Return the distance in half-cycles between INSN and the next
- insn that uses register number REGNO in memory address added
- to DISTANCE. Return -1 if REGNO0 is set.
-
- Put true value into *FOUND if register usage was found and
- false otherwise.
- Put true value into *REDEFINED if register redefinition was
- found and false otherwise. */
-
-static int
-distance_agu_use_in_bb (unsigned int regno,
- rtx insn, int distance, rtx start,
- bool *found, bool *redefined)
-{
- basic_block bb = start ? BLOCK_FOR_INSN (start) : NULL;
- rtx next = start;
- rtx prev = NULL;
-
- *found = false;
- *redefined = false;
-
- while (next
- && next != insn
- && distance < LEA_SEARCH_THRESHOLD)
- {
- if (NONDEBUG_INSN_P (next) && NONJUMP_INSN_P (next))
- {
- distance = increase_distance(prev, next, distance);
- if (insn_uses_reg_mem (regno, next))
- {
- /* Return DISTANCE if OP0 is used in memory
- address in NEXT. */
- *found = true;
- return distance;
- }
-
- if (insn_defines_reg (regno, INVALID_REGNUM, next))
- {
- /* Return -1 if OP0 is set in NEXT. */
- *redefined = true;
- return -1;
- }
-
- prev = next;
- }
-
- if (next == BB_END (bb))
- break;
-
- next = NEXT_INSN (next);
- }
-
- return distance;
-}
-
-/* Return the distance between INSN and the next insn that uses
- register number REGNO0 in memory address. Return -1 if no such
- a use is found within LEA_SEARCH_THRESHOLD or REGNO0 is set. */
-
-static int
-distance_agu_use (unsigned int regno0, rtx insn)
-{
- basic_block bb = BLOCK_FOR_INSN (insn);
- int distance = 0;
- bool found = false;
- bool redefined = false;
-
- if (insn != BB_END (bb))
- distance = distance_agu_use_in_bb (regno0, insn, distance,
- NEXT_INSN (insn),
- &found, &redefined);
-
- if (!found && !redefined && distance < LEA_SEARCH_THRESHOLD)
- {
- edge e;
- edge_iterator ei;
- bool simple_loop = false;
-
- FOR_EACH_EDGE (e, ei, bb->succs)
- if (e->dest == bb)
- {
- simple_loop = true;
- break;
- }
-
- if (simple_loop)
- distance = distance_agu_use_in_bb (regno0, insn,
- distance, BB_HEAD (bb),
- &found, &redefined);
- else
- {
- int shortest_dist = -1;
- bool found_in_bb = false;
- bool redefined_in_bb = false;
-
- FOR_EACH_EDGE (e, ei, bb->succs)
- {
- int bb_dist
- = distance_agu_use_in_bb (regno0, insn,
- distance, BB_HEAD (e->dest),
- &found_in_bb, &redefined_in_bb);
- if (found_in_bb)
- {
- if (shortest_dist < 0)
- shortest_dist = bb_dist;
- else if (bb_dist > 0)
- shortest_dist = MIN (bb_dist, shortest_dist);
-
- found = true;
- }
- }
-
- distance = shortest_dist;
- }
- }
-
- if (!found || redefined)
- return -1;
-
- return distance >> 1;
-}
-
-/* Define this macro to tune LEA priority vs ADD, it take effect when
- there is a dilemma of choicing LEA or ADD
- Negative value: ADD is more preferred than LEA
- Zero: Netrual
- Positive value: LEA is more preferred than ADD*/
-#define IX86_LEA_PRIORITY 0
-
-/* Return true if usage of lea INSN has performance advantage
- over a sequence of instructions. Instructions sequence has
- SPLIT_COST cycles higher latency than lea latency. */
-
-static bool
-ix86_lea_outperforms (rtx insn, unsigned int regno0, unsigned int regno1,
- unsigned int regno2, int split_cost, bool has_scale)
-{
- int dist_define, dist_use;
-
- /* For Silvermont if using a 2-source or 3-source LEA for
- non-destructive destination purposes, or due to wanting
- ability to use SCALE, the use of LEA is justified. */
- if (ix86_tune == PROCESSOR_SLM)
- {
- if (has_scale)
- return true;
- if (split_cost < 1)
- return false;
- if (regno0 == regno1 || regno0 == regno2)
- return false;
- return true;
- }
-
- dist_define = distance_non_agu_define (regno1, regno2, insn);
- dist_use = distance_agu_use (regno0, insn);
-
- if (dist_define < 0 || dist_define >= LEA_MAX_STALL)
- {
- /* If there is no non AGU operand definition, no AGU
- operand usage and split cost is 0 then both lea
- and non lea variants have same priority. Currently
- we prefer lea for 64 bit code and non lea on 32 bit
- code. */
- if (dist_use < 0 && split_cost == 0)
- return TARGET_64BIT || IX86_LEA_PRIORITY;
- else
- return true;
- }
-
- /* With longer definitions distance lea is more preferable.
- Here we change it to take into account splitting cost and
- lea priority. */
- dist_define += split_cost + IX86_LEA_PRIORITY;
-
- /* If there is no use in memory addess then we just check
- that split cost exceeds AGU stall. */
- if (dist_use < 0)
- return dist_define > LEA_MAX_STALL;
-
- /* If this insn has both backward non-agu dependence and forward
- agu dependence, the one with short distance takes effect. */
- return dist_define >= dist_use;
-}
-
-/* Return true if it is legal to clobber flags by INSN and
- false otherwise. */
-
-static bool
-ix86_ok_to_clobber_flags (rtx insn)
-{
- basic_block bb = BLOCK_FOR_INSN (insn);
- df_ref *use;
- bitmap live;
-
- while (insn)
- {
- if (NONDEBUG_INSN_P (insn))
- {
- for (use = DF_INSN_USES (insn); *use; use++)
- if (DF_REF_REG_USE_P (*use) && DF_REF_REGNO (*use) == FLAGS_REG)
- return false;
-
- if (insn_defines_reg (FLAGS_REG, INVALID_REGNUM, insn))
- return true;
- }
-
- if (insn == BB_END (bb))
- break;
-
- insn = NEXT_INSN (insn);
- }
-
- live = df_get_live_out(bb);
- return !REGNO_REG_SET_P (live, FLAGS_REG);
-}
-
-/* Return true if we need to split op0 = op1 + op2 into a sequence of
- move and add to avoid AGU stalls. */
-
-bool
-ix86_avoid_lea_for_add (rtx insn, rtx operands[])
-{
- unsigned int regno0, regno1, regno2;
-
- /* Check if we need to optimize. */
- if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
- return false;
-
- /* Check it is correct to split here. */
- if (!ix86_ok_to_clobber_flags(insn))
- return false;
-
- regno0 = true_regnum (operands[0]);
- regno1 = true_regnum (operands[1]);
- regno2 = true_regnum (operands[2]);
-
- /* We need to split only adds with non destructive
- destination operand. */
- if (regno0 == regno1 || regno0 == regno2)
- return false;
- else
- return !ix86_lea_outperforms (insn, regno0, regno1, regno2, 1, false);
-}
-
-/* Return true if we should emit lea instruction instead of mov
- instruction. */
-
-bool
-ix86_use_lea_for_mov (rtx insn, rtx operands[])
-{
- unsigned int regno0, regno1;
-
- /* Check if we need to optimize. */
- if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
- return false;
-
- /* Use lea for reg to reg moves only. */
- if (!REG_P (operands[0]) || !REG_P (operands[1]))
- return false;
-
- regno0 = true_regnum (operands[0]);
- regno1 = true_regnum (operands[1]);
-
- return ix86_lea_outperforms (insn, regno0, regno1, INVALID_REGNUM, 0, false);
-}
-
-/* Return true if we need to split lea into a sequence of
- instructions to avoid AGU stalls. */
-
-bool
-ix86_avoid_lea_for_addr (rtx insn, rtx operands[])
-{
- unsigned int regno0, regno1, regno2;
- int split_cost;
- struct ix86_address parts;
- int ok;
-
- /* Check we need to optimize. */
- if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
- return false;
-
- /* Check it is correct to split here. */
- if (!ix86_ok_to_clobber_flags(insn))
- return false;
-
- ok = ix86_decompose_address (operands[1], &parts);
- gcc_assert (ok);
-
- /* There should be at least two components in the address. */
- if ((parts.base != NULL_RTX) + (parts.index != NULL_RTX)
- + (parts.disp != NULL_RTX) + (parts.scale > 1) < 2)
- return false;
-
- /* We should not split into add if non legitimate pic
- operand is used as displacement. */
- if (parts.disp && flag_pic && !LEGITIMATE_PIC_OPERAND_P (parts.disp))
- return false;
-
- regno0 = true_regnum (operands[0]) ;
- regno1 = INVALID_REGNUM;
- regno2 = INVALID_REGNUM;
-
- if (parts.base)
- regno1 = true_regnum (parts.base);
- if (parts.index)
- regno2 = true_regnum (parts.index);
-
- split_cost = 0;
-
- /* Compute how many cycles we will add to execution time
- if split lea into a sequence of instructions. */
- if (parts.base || parts.index)
- {
- /* Have to use mov instruction if non desctructive
- destination form is used. */
- if (regno1 != regno0 && regno2 != regno0)
- split_cost += 1;
-
- /* Have to add index to base if both exist. */
- if (parts.base && parts.index)
- split_cost += 1;
-
- /* Have to use shift and adds if scale is 2 or greater. */
- if (parts.scale > 1)
- {
- if (regno0 != regno1)
- split_cost += 1;
- else if (regno2 == regno0)
- split_cost += 4;
- else
- split_cost += parts.scale;
- }
-
- /* Have to use add instruction with immediate if
- disp is non zero. */
- if (parts.disp && parts.disp != const0_rtx)
- split_cost += 1;
-
- /* Subtract the price of lea. */
- split_cost -= 1;
- }
-
- return !ix86_lea_outperforms (insn, regno0, regno1, regno2, split_cost,
- parts.scale > 1);
-}
-
-/* Emit x86 binary operand CODE in mode MODE, where the first operand
- matches destination. RTX includes clobber of FLAGS_REG. */
-
-static void
-ix86_emit_binop (enum rtx_code code, enum machine_mode mode,
- rtx dst, rtx src)
-{
- rtx op, clob;
-
- op = gen_rtx_SET (VOIDmode, dst, gen_rtx_fmt_ee (code, mode, dst, src));
- clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
-
- emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
-}
-
-/* Return true if regno1 def is nearest to the insn. */
-
-static bool
-find_nearest_reg_def (rtx insn, int regno1, int regno2)
-{
- rtx prev = insn;
- rtx start = BB_HEAD (BLOCK_FOR_INSN (insn));
-
- if (insn == start)
- return false;
- while (prev && prev != start)
- {
- if (!INSN_P (prev) || !NONDEBUG_INSN_P (prev))
- {
- prev = PREV_INSN (prev);
- continue;
- }
- if (insn_defines_reg (regno1, INVALID_REGNUM, prev))
- return true;
- else if (insn_defines_reg (regno2, INVALID_REGNUM, prev))
- return false;
- prev = PREV_INSN (prev);
- }
-
- /* None of the regs is defined in the bb. */
- return false;
-}
-
-/* Split lea instructions into a sequence of instructions
- which are executed on ALU to avoid AGU stalls.
- It is assumed that it is allowed to clobber flags register
- at lea position. */
-
-void
-ix86_split_lea_for_addr (rtx insn, rtx operands[], enum machine_mode mode)
-{
- unsigned int regno0, regno1, regno2;
- struct ix86_address parts;
- rtx target, tmp;
- int ok, adds;
-
- ok = ix86_decompose_address (operands[1], &parts);
- gcc_assert (ok);
-
- target = gen_lowpart (mode, operands[0]);
-
- regno0 = true_regnum (target);
- regno1 = INVALID_REGNUM;
- regno2 = INVALID_REGNUM;
-
- if (parts.base)
- {
- parts.base = gen_lowpart (mode, parts.base);
- regno1 = true_regnum (parts.base);
- }
-
- if (parts.index)
- {
- parts.index = gen_lowpart (mode, parts.index);
- regno2 = true_regnum (parts.index);
- }
-
- if (parts.disp)
- parts.disp = gen_lowpart (mode, parts.disp);
-
- if (parts.scale > 1)
- {
- /* Case r1 = r1 + ... */
- if (regno1 == regno0)
- {
- /* If we have a case r1 = r1 + C * r1 then we
- should use multiplication which is very
- expensive. Assume cost model is wrong if we
- have such case here. */
- gcc_assert (regno2 != regno0);
-
- for (adds = parts.scale; adds > 0; adds--)
- ix86_emit_binop (PLUS, mode, target, parts.index);
- }
- else
- {
- /* r1 = r2 + r3 * C case. Need to move r3 into r1. */
- if (regno0 != regno2)
- emit_insn (gen_rtx_SET (VOIDmode, target, parts.index));
-
- /* Use shift for scaling. */
- ix86_emit_binop (ASHIFT, mode, target,
- GEN_INT (exact_log2 (parts.scale)));
-
- if (parts.base)
- ix86_emit_binop (PLUS, mode, target, parts.base);
-
- if (parts.disp && parts.disp != const0_rtx)
- ix86_emit_binop (PLUS, mode, target, parts.disp);
- }
- }
- else if (!parts.base && !parts.index)
- {
- gcc_assert(parts.disp);
- emit_insn (gen_rtx_SET (VOIDmode, target, parts.disp));
- }
- else
- {
- if (!parts.base)
- {
- if (regno0 != regno2)
- emit_insn (gen_rtx_SET (VOIDmode, target, parts.index));
- }
- else if (!parts.index)
- {
- if (regno0 != regno1)
- emit_insn (gen_rtx_SET (VOIDmode, target, parts.base));
- }
- else
- {
- if (regno0 == regno1)
- tmp = parts.index;
- else if (regno0 == regno2)
- tmp = parts.base;
- else
- {
- rtx tmp1;
-
- /* Find better operand for SET instruction, depending
- on which definition is farther from the insn. */
- if (find_nearest_reg_def (insn, regno1, regno2))
- tmp = parts.index, tmp1 = parts.base;
- else
- tmp = parts.base, tmp1 = parts.index;
-
- emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
-
- if (parts.disp && parts.disp != const0_rtx)
- ix86_emit_binop (PLUS, mode, target, parts.disp);
-
- ix86_emit_binop (PLUS, mode, target, tmp1);
- return;
- }
-
- ix86_emit_binop (PLUS, mode, target, tmp);
- }
-
- if (parts.disp && parts.disp != const0_rtx)
- ix86_emit_binop (PLUS, mode, target, parts.disp);
- }
-}
-
-/* Return true if it is ok to optimize an ADD operation to LEA
- operation to avoid flag register consumation. For most processors,
- ADD is faster than LEA. For the processors like ATOM, if the
- destination register of LEA holds an actual address which will be
- used soon, LEA is better and otherwise ADD is better. */
-
-bool
-ix86_lea_for_add_ok (rtx insn, rtx operands[])
-{
- unsigned int regno0 = true_regnum (operands[0]);
- unsigned int regno1 = true_regnum (operands[1]);
- unsigned int regno2 = true_regnum (operands[2]);
-
- /* If a = b + c, (a!=b && a!=c), must use lea form. */
- if (regno0 != regno1 && regno0 != regno2)
- return true;
-
- if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
- return false;
-
- return ix86_lea_outperforms (insn, regno0, regno1, regno2, 0, false);
-}
-
-/* Return true if destination reg of SET_BODY is shift count of
- USE_BODY. */
-
-static bool
-ix86_dep_by_shift_count_body (const_rtx set_body, const_rtx use_body)
-{
- rtx set_dest;
- rtx shift_rtx;
- int i;
-
- /* Retrieve destination of SET_BODY. */
- switch (GET_CODE (set_body))
- {
- case SET:
- set_dest = SET_DEST (set_body);
- if (!set_dest || !REG_P (set_dest))
- return false;
- break;
- case PARALLEL:
- for (i = XVECLEN (set_body, 0) - 1; i >= 0; i--)
- if (ix86_dep_by_shift_count_body (XVECEXP (set_body, 0, i),
- use_body))
- return true;
- default:
- return false;
- break;
- }
-
- /* Retrieve shift count of USE_BODY. */
- switch (GET_CODE (use_body))
- {
- case SET:
- shift_rtx = XEXP (use_body, 1);
- break;
- case PARALLEL:
- for (i = XVECLEN (use_body, 0) - 1; i >= 0; i--)
- if (ix86_dep_by_shift_count_body (set_body,
- XVECEXP (use_body, 0, i)))
- return true;
- default:
- return false;
- break;
- }
-
- if (shift_rtx
- && (GET_CODE (shift_rtx) == ASHIFT
- || GET_CODE (shift_rtx) == LSHIFTRT
- || GET_CODE (shift_rtx) == ASHIFTRT
- || GET_CODE (shift_rtx) == ROTATE
- || GET_CODE (shift_rtx) == ROTATERT))
- {
- rtx shift_count = XEXP (shift_rtx, 1);
-
- /* Return true if shift count is dest of SET_BODY. */
- if (REG_P (shift_count))
- {
- /* Add check since it can be invoked before register
- allocation in pre-reload schedule. */
- if (reload_completed
- && true_regnum (set_dest) == true_regnum (shift_count))
- return true;
- else if (REGNO(set_dest) == REGNO(shift_count))
- return true;
- }
- }
-
- return false;
-}
-
-/* Return true if destination reg of SET_INSN is shift count of
- USE_INSN. */
-
-bool
-ix86_dep_by_shift_count (const_rtx set_insn, const_rtx use_insn)
-{
- return ix86_dep_by_shift_count_body (PATTERN (set_insn),
- PATTERN (use_insn));
-}
-
-/* Return TRUE or FALSE depending on whether the unary operator meets the
- appropriate constraints. */
-
-bool
-ix86_unary_operator_ok (enum rtx_code code ATTRIBUTE_UNUSED,
- enum machine_mode mode ATTRIBUTE_UNUSED,
- rtx operands[2] ATTRIBUTE_UNUSED)
-{
- /* If one of operands is memory, source and destination must match. */
- if ((MEM_P (operands[0])
- || MEM_P (operands[1]))
- && ! rtx_equal_p (operands[0], operands[1]))
- return false;
- return true;
-}
-
-/* Return TRUE if the operands to a vec_interleave_{high,low}v2df
- are ok, keeping in mind the possible movddup alternative. */
-
-bool
-ix86_vec_interleave_v2df_operator_ok (rtx operands[3], bool high)
-{
- if (MEM_P (operands[0]))
- return rtx_equal_p (operands[0], operands[1 + high]);
- if (MEM_P (operands[1]) && MEM_P (operands[2]))
- return TARGET_SSE3 && rtx_equal_p (operands[1], operands[2]);
- return true;
-}
-
-/* Post-reload splitter for converting an SF or DFmode value in an
- SSE register into an unsigned SImode. */
-
-void
-ix86_split_convert_uns_si_sse (rtx operands[])
-{
- enum machine_mode vecmode;
- rtx value, large, zero_or_two31, input, two31, x;
-
- large = operands[1];
- zero_or_two31 = operands[2];
- input = operands[3];
- two31 = operands[4];
- vecmode = GET_MODE (large);
- value = gen_rtx_REG (vecmode, REGNO (operands[0]));
-
- /* Load up the value into the low element. We must ensure that the other
- elements are valid floats -- zero is the easiest such value. */
- if (MEM_P (input))
- {
- if (vecmode == V4SFmode)
- emit_insn (gen_vec_setv4sf_0 (value, CONST0_RTX (V4SFmode), input));
- else
- emit_insn (gen_sse2_loadlpd (value, CONST0_RTX (V2DFmode), input));
- }
- else
- {
- input = gen_rtx_REG (vecmode, REGNO (input));
- emit_move_insn (value, CONST0_RTX (vecmode));
- if (vecmode == V4SFmode)
- emit_insn (gen_sse_movss (value, value, input));
- else
- emit_insn (gen_sse2_movsd (value, value, input));
- }
-
- emit_move_insn (large, two31);
- emit_move_insn (zero_or_two31, MEM_P (two31) ? large : two31);
-
- x = gen_rtx_fmt_ee (LE, vecmode, large, value);
- emit_insn (gen_rtx_SET (VOIDmode, large, x));
-
- x = gen_rtx_AND (vecmode, zero_or_two31, large);
- emit_insn (gen_rtx_SET (VOIDmode, zero_or_two31, x));
-
- x = gen_rtx_MINUS (vecmode, value, zero_or_two31);
- emit_insn (gen_rtx_SET (VOIDmode, value, x));
-
- large = gen_rtx_REG (V4SImode, REGNO (large));
- emit_insn (gen_ashlv4si3 (large, large, GEN_INT (31)));
-
- x = gen_rtx_REG (V4SImode, REGNO (value));
- if (vecmode == V4SFmode)
- emit_insn (gen_fix_truncv4sfv4si2 (x, value));
- else
- emit_insn (gen_sse2_cvttpd2dq (x, value));
- value = x;
-
- emit_insn (gen_xorv4si3 (value, value, large));
-}
-
-/* Convert an unsigned DImode value into a DFmode, using only SSE.
- Expects the 64-bit DImode to be supplied in a pair of integral
- registers. Requires SSE2; will use SSE3 if available. For x86_32,
- -mfpmath=sse, !optimize_size only. */
-
-void
-ix86_expand_convert_uns_didf_sse (rtx target, rtx input)
-{
- REAL_VALUE_TYPE bias_lo_rvt, bias_hi_rvt;
- rtx int_xmm, fp_xmm;
- rtx biases, exponents;
- rtx x;
-
- int_xmm = gen_reg_rtx (V4SImode);
- if (TARGET_INTER_UNIT_MOVES)
- emit_insn (gen_movdi_to_sse (int_xmm, input));
- else if (TARGET_SSE_SPLIT_REGS)
- {
- emit_clobber (int_xmm);
- emit_move_insn (gen_lowpart (DImode, int_xmm), input);
- }
- else
- {
- x = gen_reg_rtx (V2DImode);
- ix86_expand_vector_init_one_nonzero (false, V2DImode, x, input, 0);
- emit_move_insn (int_xmm, gen_lowpart (V4SImode, x));
- }
-
- x = gen_rtx_CONST_VECTOR (V4SImode,
- gen_rtvec (4, GEN_INT (0x43300000UL),
- GEN_INT (0x45300000UL),
- const0_rtx, const0_rtx));
- exponents = validize_mem (force_const_mem (V4SImode, x));
-
- /* int_xmm = {0x45300000UL, fp_xmm/hi, 0x43300000, fp_xmm/lo } */
- emit_insn (gen_vec_interleave_lowv4si (int_xmm, int_xmm, exponents));
-
- /* Concatenating (juxtaposing) (0x43300000UL ## fp_value_low_xmm)
- yields a valid DF value equal to (0x1.0p52 + double(fp_value_lo_xmm)).
- Similarly (0x45300000UL ## fp_value_hi_xmm) yields
- (0x1.0p84 + double(fp_value_hi_xmm)).
- Note these exponents differ by 32. */
-
- fp_xmm = copy_to_mode_reg (V2DFmode, gen_lowpart (V2DFmode, int_xmm));
-
- /* Subtract off those 0x1.0p52 and 0x1.0p84 biases, to produce values
- in [0,2**32-1] and [0]+[2**32,2**64-1] respectively. */
- real_ldexp (&bias_lo_rvt, &dconst1, 52);
- real_ldexp (&bias_hi_rvt, &dconst1, 84);
- biases = const_double_from_real_value (bias_lo_rvt, DFmode);
- x = const_double_from_real_value (bias_hi_rvt, DFmode);
- biases = gen_rtx_CONST_VECTOR (V2DFmode, gen_rtvec (2, biases, x));
- biases = validize_mem (force_const_mem (V2DFmode, biases));
- emit_insn (gen_subv2df3 (fp_xmm, fp_xmm, biases));
-
- /* Add the upper and lower DFmode values together. */
- if (TARGET_SSE3)
- emit_insn (gen_sse3_haddv2df3 (fp_xmm, fp_xmm, fp_xmm));
- else
- {
- x = copy_to_mode_reg (V2DFmode, fp_xmm);
- emit_insn (gen_vec_interleave_highv2df (fp_xmm, fp_xmm, fp_xmm));
- emit_insn (gen_addv2df3 (fp_xmm, fp_xmm, x));
- }
-
- ix86_expand_vector_extract (false, target, fp_xmm, 0);
-}
-
-/* Not used, but eases macroization of patterns. */
-void
-ix86_expand_convert_uns_sixf_sse (rtx target ATTRIBUTE_UNUSED,
- rtx input ATTRIBUTE_UNUSED)
-{
- gcc_unreachable ();
-}
-
-/* Convert an unsigned SImode value into a DFmode. Only currently used
- for SSE, but applicable anywhere. */
-
-void
-ix86_expand_convert_uns_sidf_sse (rtx target, rtx input)
-{
- REAL_VALUE_TYPE TWO31r;
- rtx x, fp;
-
- x = expand_simple_binop (SImode, PLUS, input, GEN_INT (-2147483647 - 1),
- NULL, 1, OPTAB_DIRECT);
-
- fp = gen_reg_rtx (DFmode);
- emit_insn (gen_floatsidf2 (fp, x));
-
- real_ldexp (&TWO31r, &dconst1, 31);
- x = const_double_from_real_value (TWO31r, DFmode);
-
- x = expand_simple_binop (DFmode, PLUS, fp, x, target, 0, OPTAB_DIRECT);
- if (x != target)
- emit_move_insn (target, x);
-}
-
-/* Convert a signed DImode value into a DFmode. Only used for SSE in
- 32-bit mode; otherwise we have a direct convert instruction. */
-
-void
-ix86_expand_convert_sign_didf_sse (rtx target, rtx input)
-{
- REAL_VALUE_TYPE TWO32r;
- rtx fp_lo, fp_hi, x;
-
- fp_lo = gen_reg_rtx (DFmode);
- fp_hi = gen_reg_rtx (DFmode);
-
- emit_insn (gen_floatsidf2 (fp_hi, gen_highpart (SImode, input)));
-
- real_ldexp (&TWO32r, &dconst1, 32);
- x = const_double_from_real_value (TWO32r, DFmode);
- fp_hi = expand_simple_binop (DFmode, MULT, fp_hi, x, fp_hi, 0, OPTAB_DIRECT);
-
- ix86_expand_convert_uns_sidf_sse (fp_lo, gen_lowpart (SImode, input));
-
- x = expand_simple_binop (DFmode, PLUS, fp_hi, fp_lo, target,
- 0, OPTAB_DIRECT);
- if (x != target)
- emit_move_insn (target, x);
-}
-
-/* Convert an unsigned SImode value into a SFmode, using only SSE.
- For x86_32, -mfpmath=sse, !optimize_size only. */
-void
-ix86_expand_convert_uns_sisf_sse (rtx target, rtx input)
-{
- REAL_VALUE_TYPE ONE16r;
- rtx fp_hi, fp_lo, int_hi, int_lo, x;
-
- real_ldexp (&ONE16r, &dconst1, 16);
- x = const_double_from_real_value (ONE16r, SFmode);
- int_lo = expand_simple_binop (SImode, AND, input, GEN_INT(0xffff),
- NULL, 0, OPTAB_DIRECT);
- int_hi = expand_simple_binop (SImode, LSHIFTRT, input, GEN_INT(16),
- NULL, 0, OPTAB_DIRECT);
- fp_hi = gen_reg_rtx (SFmode);
- fp_lo = gen_reg_rtx (SFmode);
- emit_insn (gen_floatsisf2 (fp_hi, int_hi));
- emit_insn (gen_floatsisf2 (fp_lo, int_lo));
- fp_hi = expand_simple_binop (SFmode, MULT, fp_hi, x, fp_hi,
- 0, OPTAB_DIRECT);
- fp_hi = expand_simple_binop (SFmode, PLUS, fp_hi, fp_lo, target,
- 0, OPTAB_DIRECT);
- if (!rtx_equal_p (target, fp_hi))
- emit_move_insn (target, fp_hi);
-}
-
-/* floatunsv{4,8}siv{4,8}sf2 expander. Expand code to convert
- a vector of unsigned ints VAL to vector of floats TARGET. */
-
-void
-ix86_expand_vector_convert_uns_vsivsf (rtx target, rtx val)
-{
- rtx tmp[8];
- REAL_VALUE_TYPE TWO16r;
- enum machine_mode intmode = GET_MODE (val);
- enum machine_mode fltmode = GET_MODE (target);
- rtx (*cvt) (rtx, rtx);
-
- if (intmode == V4SImode)
- cvt = gen_floatv4siv4sf2;
- else
- cvt = gen_floatv8siv8sf2;
- tmp[0] = ix86_build_const_vector (intmode, 1, GEN_INT (0xffff));
- tmp[0] = force_reg (intmode, tmp[0]);
- tmp[1] = expand_simple_binop (intmode, AND, val, tmp[0], NULL_RTX, 1,
- OPTAB_DIRECT);
- tmp[2] = expand_simple_binop (intmode, LSHIFTRT, val, GEN_INT (16),
- NULL_RTX, 1, OPTAB_DIRECT);
- tmp[3] = gen_reg_rtx (fltmode);
- emit_insn (cvt (tmp[3], tmp[1]));
- tmp[4] = gen_reg_rtx (fltmode);
- emit_insn (cvt (tmp[4], tmp[2]));
- real_ldexp (&TWO16r, &dconst1, 16);
- tmp[5] = const_double_from_real_value (TWO16r, SFmode);
- tmp[5] = force_reg (fltmode, ix86_build_const_vector (fltmode, 1, tmp[5]));
- tmp[6] = expand_simple_binop (fltmode, MULT, tmp[4], tmp[5], NULL_RTX, 1,
- OPTAB_DIRECT);
- tmp[7] = expand_simple_binop (fltmode, PLUS, tmp[3], tmp[6], target, 1,
- OPTAB_DIRECT);
- if (tmp[7] != target)
- emit_move_insn (target, tmp[7]);
-}
-
-/* Adjust a V*SFmode/V*DFmode value VAL so that *sfix_trunc* resp. fix_trunc*
- pattern can be used on it instead of *ufix_trunc* resp. fixuns_trunc*.
- This is done by doing just signed conversion if < 0x1p31, and otherwise by
- subtracting 0x1p31 first and xoring in 0x80000000 from *XORP afterwards. */
-
-rtx
-ix86_expand_adjust_ufix_to_sfix_si (rtx val, rtx *xorp)
-{
- REAL_VALUE_TYPE TWO31r;
- rtx two31r, tmp[4];
- enum machine_mode mode = GET_MODE (val);
- enum machine_mode scalarmode = GET_MODE_INNER (mode);
- enum machine_mode intmode = GET_MODE_SIZE (mode) == 32 ? V8SImode : V4SImode;
- rtx (*cmp) (rtx, rtx, rtx, rtx);
- int i;
-
- for (i = 0; i < 3; i++)
- tmp[i] = gen_reg_rtx (mode);
- real_ldexp (&TWO31r, &dconst1, 31);
- two31r = const_double_from_real_value (TWO31r, scalarmode);
- two31r = ix86_build_const_vector (mode, 1, two31r);
- two31r = force_reg (mode, two31r);
- switch (mode)
- {
- case V8SFmode: cmp = gen_avx_maskcmpv8sf3; break;
- case V4SFmode: cmp = gen_sse_maskcmpv4sf3; break;
- case V4DFmode: cmp = gen_avx_maskcmpv4df3; break;
- case V2DFmode: cmp = gen_sse2_maskcmpv2df3; break;
- default: gcc_unreachable ();
- }
- tmp[3] = gen_rtx_LE (mode, two31r, val);
- emit_insn (cmp (tmp[0], two31r, val, tmp[3]));
- tmp[1] = expand_simple_binop (mode, AND, tmp[0], two31r, tmp[1],
- 0, OPTAB_DIRECT);
- if (intmode == V4SImode || TARGET_AVX2)
- *xorp = expand_simple_binop (intmode, ASHIFT,
- gen_lowpart (intmode, tmp[0]),
- GEN_INT (31), NULL_RTX, 0,
- OPTAB_DIRECT);
- else
- {
- rtx two31 = GEN_INT ((unsigned HOST_WIDE_INT) 1 << 31);
- two31 = ix86_build_const_vector (intmode, 1, two31);
- *xorp = expand_simple_binop (intmode, AND,
- gen_lowpart (intmode, tmp[0]),
- two31, NULL_RTX, 0,
- OPTAB_DIRECT);
- }
- return expand_simple_binop (mode, MINUS, val, tmp[1], tmp[2],
- 0, OPTAB_DIRECT);
-}
-
-/* A subroutine of ix86_build_signbit_mask. If VECT is true,
- then replicate the value for all elements of the vector
- register. */
-
-rtx
-ix86_build_const_vector (enum machine_mode mode, bool vect, rtx value)
-{
- int i, n_elt;
- rtvec v;
- enum machine_mode scalar_mode;
-
- switch (mode)
- {
- case V32QImode:
- case V16QImode:
- case V16HImode:
- case V8HImode:
- case V8SImode:
- case V4SImode:
- case V4DImode:
- case V2DImode:
- gcc_assert (vect);
- case V8SFmode:
- case V4SFmode:
- case V4DFmode:
- case V2DFmode:
- n_elt = GET_MODE_NUNITS (mode);
- v = rtvec_alloc (n_elt);
- scalar_mode = GET_MODE_INNER (mode);
-
- RTVEC_ELT (v, 0) = value;
-
- for (i = 1; i < n_elt; ++i)
- RTVEC_ELT (v, i) = vect ? value : CONST0_RTX (scalar_mode);
-
- return gen_rtx_CONST_VECTOR (mode, v);
-
- default:
- gcc_unreachable ();
- }
-}
-
-/* A subroutine of ix86_expand_fp_absneg_operator, copysign expanders
- and ix86_expand_int_vcond. Create a mask for the sign bit in MODE
- for an SSE register. If VECT is true, then replicate the mask for
- all elements of the vector register. If INVERT is true, then create
- a mask excluding the sign bit. */
-
-rtx
-ix86_build_signbit_mask (enum machine_mode mode, bool vect, bool invert)
-{
- enum machine_mode vec_mode, imode;
- HOST_WIDE_INT hi, lo;
- int shift = 63;
- rtx v;
- rtx mask;
-
- /* Find the sign bit, sign extended to 2*HWI. */
- switch (mode)
- {
- case V8SImode:
- case V4SImode:
- case V8SFmode:
- case V4SFmode:
- vec_mode = mode;
- mode = GET_MODE_INNER (mode);
- imode = SImode;
- lo = 0x80000000, hi = lo < 0;
- break;
-
- case V4DImode:
- case V2DImode:
- case V4DFmode:
- case V2DFmode:
- vec_mode = mode;
- mode = GET_MODE_INNER (mode);
- imode = DImode;
- if (HOST_BITS_PER_WIDE_INT >= 64)
- lo = (HOST_WIDE_INT)1 << shift, hi = -1;
- else
- lo = 0, hi = (HOST_WIDE_INT)1 << (shift - HOST_BITS_PER_WIDE_INT);
- break;
-
- case TImode:
- case TFmode:
- vec_mode = VOIDmode;
- if (HOST_BITS_PER_WIDE_INT >= 64)
- {
- imode = TImode;
- lo = 0, hi = (HOST_WIDE_INT)1 << shift;
- }
- else
- {
- rtvec vec;
-
- imode = DImode;
- lo = 0, hi = (HOST_WIDE_INT)1 << (shift - HOST_BITS_PER_WIDE_INT);
-
- if (invert)
- {
- lo = ~lo, hi = ~hi;
- v = constm1_rtx;
- }
- else
- v = const0_rtx;
-
- mask = immed_double_const (lo, hi, imode);
-
- vec = gen_rtvec (2, v, mask);
- v = gen_rtx_CONST_VECTOR (V2DImode, vec);
- v = copy_to_mode_reg (mode, gen_lowpart (mode, v));
-
- return v;
- }
- break;
-
- default:
- gcc_unreachable ();
- }
-
- if (invert)
- lo = ~lo, hi = ~hi;
-
- /* Force this value into the low part of a fp vector constant. */
- mask = immed_double_const (lo, hi, imode);
- mask = gen_lowpart (mode, mask);
-
- if (vec_mode == VOIDmode)
- return force_reg (mode, mask);
-
- v = ix86_build_const_vector (vec_mode, vect, mask);
- return force_reg (vec_mode, v);
-}
-
-/* Generate code for floating point ABS or NEG. */
-
-void
-ix86_expand_fp_absneg_operator (enum rtx_code code, enum machine_mode mode,
- rtx operands[])
-{
- rtx mask, set, dst, src;
- bool use_sse = false;
- bool vector_mode = VECTOR_MODE_P (mode);
- enum machine_mode vmode = mode;
-
- if (vector_mode)
- use_sse = true;
- else if (mode == TFmode)
- use_sse = true;
- else if (TARGET_SSE_MATH)
- {
- use_sse = SSE_FLOAT_MODE_P (mode);
- if (mode == SFmode)
- vmode = V4SFmode;
- else if (mode == DFmode)
- vmode = V2DFmode;
- }
-
- /* NEG and ABS performed with SSE use bitwise mask operations.
- Create the appropriate mask now. */
- if (use_sse)
- mask = ix86_build_signbit_mask (vmode, vector_mode, code == ABS);
- else
- mask = NULL_RTX;
-
- dst = operands[0];
- src = operands[1];
-
- set = gen_rtx_fmt_e (code, mode, src);
- set = gen_rtx_SET (VOIDmode, dst, set);
-
- if (mask)
- {
- rtx use, clob;
- rtvec par;
-
- use = gen_rtx_USE (VOIDmode, mask);
- if (vector_mode)
- par = gen_rtvec (2, set, use);
- else
- {
- clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
- par = gen_rtvec (3, set, use, clob);
- }
- emit_insn (gen_rtx_PARALLEL (VOIDmode, par));
- }
- else
- emit_insn (set);
-}
-
-/* Expand a copysign operation. Special case operand 0 being a constant. */
-
-void
-ix86_expand_copysign (rtx operands[])
-{
- enum machine_mode mode, vmode;
- rtx dest, op0, op1, mask, nmask;
-
- dest = operands[0];
- op0 = operands[1];
- op1 = operands[2];
-
- mode = GET_MODE (dest);
-
- if (mode == SFmode)
- vmode = V4SFmode;
- else if (mode == DFmode)
- vmode = V2DFmode;
- else
- vmode = mode;
-
- if (GET_CODE (op0) == CONST_DOUBLE)
- {
- rtx (*copysign_insn)(rtx, rtx, rtx, rtx);
-
- if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
- op0 = simplify_unary_operation (ABS, mode, op0, mode);
-
- if (mode == SFmode || mode == DFmode)
- {
- if (op0 == CONST0_RTX (mode))
- op0 = CONST0_RTX (vmode);
- else
- {
- rtx v = ix86_build_const_vector (vmode, false, op0);
-
- op0 = force_reg (vmode, v);
- }
- }
- else if (op0 != CONST0_RTX (mode))
- op0 = force_reg (mode, op0);
-
- mask = ix86_build_signbit_mask (vmode, 0, 0);
-
- if (mode == SFmode)
- copysign_insn = gen_copysignsf3_const;
- else if (mode == DFmode)
- copysign_insn = gen_copysigndf3_const;
- else
- copysign_insn = gen_copysigntf3_const;
-
- emit_insn (copysign_insn (dest, op0, op1, mask));
- }
- else
- {
- rtx (*copysign_insn)(rtx, rtx, rtx, rtx, rtx, rtx);
-
- nmask = ix86_build_signbit_mask (vmode, 0, 1);
- mask = ix86_build_signbit_mask (vmode, 0, 0);
-
- if (mode == SFmode)
- copysign_insn = gen_copysignsf3_var;
- else if (mode == DFmode)
- copysign_insn = gen_copysigndf3_var;
- else
- copysign_insn = gen_copysigntf3_var;
-
- emit_insn (copysign_insn (dest, NULL_RTX, op0, op1, nmask, mask));
- }
-}
-
-/* Deconstruct a copysign operation into bit masks. Operand 0 is known to
- be a constant, and so has already been expanded into a vector constant. */
-
-void
-ix86_split_copysign_const (rtx operands[])
-{
- enum machine_mode mode, vmode;
- rtx dest, op0, mask, x;
-
- dest = operands[0];
- op0 = operands[1];
- mask = operands[3];
-
- mode = GET_MODE (dest);
- vmode = GET_MODE (mask);
-
- dest = simplify_gen_subreg (vmode, dest, mode, 0);
- x = gen_rtx_AND (vmode, dest, mask);
- emit_insn (gen_rtx_SET (VOIDmode, dest, x));
-
- if (op0 != CONST0_RTX (vmode))
- {
- x = gen_rtx_IOR (vmode, dest, op0);
- emit_insn (gen_rtx_SET (VOIDmode, dest, x));
- }
-}
-
-/* Deconstruct a copysign operation into bit masks. Operand 0 is variable,
- so we have to do two masks. */
-
-void
-ix86_split_copysign_var (rtx operands[])
-{
- enum machine_mode mode, vmode;
- rtx dest, scratch, op0, op1, mask, nmask, x;
-
- dest = operands[0];
- scratch = operands[1];
- op0 = operands[2];
- op1 = operands[3];
- nmask = operands[4];
- mask = operands[5];
-
- mode = GET_MODE (dest);
- vmode = GET_MODE (mask);
-
- if (rtx_equal_p (op0, op1))
- {
- /* Shouldn't happen often (it's useless, obviously), but when it does
- we'd generate incorrect code if we continue below. */
- emit_move_insn (dest, op0);
- return;
- }
-
- if (REG_P (mask) && REGNO (dest) == REGNO (mask)) /* alternative 0 */
- {
- gcc_assert (REGNO (op1) == REGNO (scratch));
-
- x = gen_rtx_AND (vmode, scratch, mask);
- emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
-
- dest = mask;
- op0 = simplify_gen_subreg (vmode, op0, mode, 0);
- x = gen_rtx_NOT (vmode, dest);
- x = gen_rtx_AND (vmode, x, op0);
- emit_insn (gen_rtx_SET (VOIDmode, dest, x));
- }
- else
- {
- if (REGNO (op1) == REGNO (scratch)) /* alternative 1,3 */
- {
- x = gen_rtx_AND (vmode, scratch, mask);
- }
- else /* alternative 2,4 */
- {
- gcc_assert (REGNO (mask) == REGNO (scratch));
- op1 = simplify_gen_subreg (vmode, op1, mode, 0);
- x = gen_rtx_AND (vmode, scratch, op1);
- }
- emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
-
- if (REGNO (op0) == REGNO (dest)) /* alternative 1,2 */
- {
- dest = simplify_gen_subreg (vmode, op0, mode, 0);
- x = gen_rtx_AND (vmode, dest, nmask);
- }
- else /* alternative 3,4 */
- {
- gcc_assert (REGNO (nmask) == REGNO (dest));
- dest = nmask;
- op0 = simplify_gen_subreg (vmode, op0, mode, 0);
- x = gen_rtx_AND (vmode, dest, op0);
- }
- emit_insn (gen_rtx_SET (VOIDmode, dest, x));
- }
-
- x = gen_rtx_IOR (vmode, dest, scratch);
- emit_insn (gen_rtx_SET (VOIDmode, dest, x));
-}
-
-/* Return TRUE or FALSE depending on whether the first SET in INSN
- has source and destination with matching CC modes, and that the
- CC mode is at least as constrained as REQ_MODE. */
-
-bool
-ix86_match_ccmode (rtx insn, enum machine_mode req_mode)
-{
- rtx set;
- enum machine_mode set_mode;
-
- set = PATTERN (insn);
- if (GET_CODE (set) == PARALLEL)
- set = XVECEXP (set, 0, 0);
- gcc_assert (GET_CODE (set) == SET);
- gcc_assert (GET_CODE (SET_SRC (set)) == COMPARE);
-
- set_mode = GET_MODE (SET_DEST (set));
- switch (set_mode)
- {
- case CCNOmode:
- if (req_mode != CCNOmode
- && (req_mode != CCmode
- || XEXP (SET_SRC (set), 1) != const0_rtx))
- return false;
- break;
- case CCmode:
- if (req_mode == CCGCmode)
- return false;
- /* FALLTHRU */
- case CCGCmode:
- if (req_mode == CCGOCmode || req_mode == CCNOmode)
- return false;
- /* FALLTHRU */
- case CCGOCmode:
- if (req_mode == CCZmode)
- return false;
- /* FALLTHRU */
- case CCZmode:
- break;
-
- case CCAmode:
- case CCCmode:
- case CCOmode:
- case CCSmode:
- if (set_mode != req_mode)
- return false;
- break;
-
- default:
- gcc_unreachable ();
- }
-
- return GET_MODE (SET_SRC (set)) == set_mode;
-}
-
-/* Generate insn patterns to do an integer compare of OPERANDS. */
-
-static rtx
-ix86_expand_int_compare (enum rtx_code code, rtx op0, rtx op1)
-{
- enum machine_mode cmpmode;
- rtx tmp, flags;
-
- cmpmode = SELECT_CC_MODE (code, op0, op1);
- flags = gen_rtx_REG (cmpmode, FLAGS_REG);
-
- /* This is very simple, but making the interface the same as in the
- FP case makes the rest of the code easier. */
- tmp = gen_rtx_COMPARE (cmpmode, op0, op1);
- emit_insn (gen_rtx_SET (VOIDmode, flags, tmp));
-
- /* Return the test that should be put into the flags user, i.e.
- the bcc, scc, or cmov instruction. */
- return gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
-}
-
-/* Figure out whether to use ordered or unordered fp comparisons.
- Return the appropriate mode to use. */
-
-enum machine_mode
-ix86_fp_compare_mode (enum rtx_code code ATTRIBUTE_UNUSED)
-{
- /* ??? In order to make all comparisons reversible, we do all comparisons
- non-trapping when compiling for IEEE. Once gcc is able to distinguish
- all forms trapping and nontrapping comparisons, we can make inequality
- comparisons trapping again, since it results in better code when using
- FCOM based compares. */
- return TARGET_IEEE_FP ? CCFPUmode : CCFPmode;
-}
-
-enum machine_mode
-ix86_cc_mode (enum rtx_code code, rtx op0, rtx op1)
-{
- enum machine_mode mode = GET_MODE (op0);
-
- if (SCALAR_FLOAT_MODE_P (mode))
- {
- gcc_assert (!DECIMAL_FLOAT_MODE_P (mode));
- return ix86_fp_compare_mode (code);
- }
-
- switch (code)
- {
- /* Only zero flag is needed. */
- case EQ: /* ZF=0 */
- case NE: /* ZF!=0 */
- return CCZmode;
- /* Codes needing carry flag. */
- case GEU: /* CF=0 */
- case LTU: /* CF=1 */
- /* Detect overflow checks. They need just the carry flag. */
- if (GET_CODE (op0) == PLUS
- && rtx_equal_p (op1, XEXP (op0, 0)))
- return CCCmode;
- else
- return CCmode;
- case GTU: /* CF=0 & ZF=0 */
- case LEU: /* CF=1 | ZF=1 */
- /* Detect overflow checks. They need just the carry flag. */
- if (GET_CODE (op0) == MINUS
- && rtx_equal_p (op1, XEXP (op0, 0)))
- return CCCmode;
- else
- return CCmode;
- /* Codes possibly doable only with sign flag when
- comparing against zero. */
- case GE: /* SF=OF or SF=0 */
- case LT: /* SF<>OF or SF=1 */
- if (op1 == const0_rtx)
- return CCGOCmode;
- else
- /* For other cases Carry flag is not required. */
- return CCGCmode;
- /* Codes doable only with sign flag when comparing
- against zero, but we miss jump instruction for it
- so we need to use relational tests against overflow
- that thus needs to be zero. */
- case GT: /* ZF=0 & SF=OF */
- case LE: /* ZF=1 | SF<>OF */
- if (op1 == const0_rtx)
- return CCNOmode;
- else
- return CCGCmode;
- /* strcmp pattern do (use flags) and combine may ask us for proper
- mode. */
- case USE:
- return CCmode;
- default:
- gcc_unreachable ();
- }
-}
-
-/* Return the fixed registers used for condition codes. */
-
-static bool
-ix86_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
-{
- *p1 = FLAGS_REG;
- *p2 = FPSR_REG;
- return true;
-}
-
-/* If two condition code modes are compatible, return a condition code
- mode which is compatible with both. Otherwise, return
- VOIDmode. */
-
-static enum machine_mode
-ix86_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
-{
- if (m1 == m2)
- return m1;
-
- if (GET_MODE_CLASS (m1) != MODE_CC || GET_MODE_CLASS (m2) != MODE_CC)
- return VOIDmode;
-
- if ((m1 == CCGCmode && m2 == CCGOCmode)
- || (m1 == CCGOCmode && m2 == CCGCmode))
- return CCGCmode;
-
- if (m1 == CCZmode && (m2 == CCGCmode || m2 == CCGOCmode))
- return m2;
- else if (m2 == CCZmode && (m1 == CCGCmode || m1 == CCGOCmode))
- return m1;
-
- switch (m1)
- {
- default:
- gcc_unreachable ();
-
- case CCmode:
- case CCGCmode:
- case CCGOCmode:
- case CCNOmode:
- case CCAmode:
- case CCCmode:
- case CCOmode:
- case CCSmode:
- case CCZmode:
- switch (m2)
- {
- default:
- return VOIDmode;
-
- case CCmode:
- case CCGCmode:
- case CCGOCmode:
- case CCNOmode:
- case CCAmode:
- case CCCmode:
- case CCOmode:
- case CCSmode:
- case CCZmode:
- return CCmode;
- }
-
- case CCFPmode:
- case CCFPUmode:
- /* These are only compatible with themselves, which we already
- checked above. */
- return VOIDmode;
- }
-}
-
-
-/* Return a comparison we can do and that it is equivalent to
- swap_condition (code) apart possibly from orderedness.
- But, never change orderedness if TARGET_IEEE_FP, returning
- UNKNOWN in that case if necessary. */
-
-static enum rtx_code
-ix86_fp_swap_condition (enum rtx_code code)
-{
- switch (code)
- {
- case GT: /* GTU - CF=0 & ZF=0 */
- return TARGET_IEEE_FP ? UNKNOWN : UNLT;
- case GE: /* GEU - CF=0 */
- return TARGET_IEEE_FP ? UNKNOWN : UNLE;
- case UNLT: /* LTU - CF=1 */
- return TARGET_IEEE_FP ? UNKNOWN : GT;
- case UNLE: /* LEU - CF=1 | ZF=1 */
- return TARGET_IEEE_FP ? UNKNOWN : GE;
- default:
- return swap_condition (code);
- }
-}
-
-/* Return cost of comparison CODE using the best strategy for performance.
- All following functions do use number of instructions as a cost metrics.
- In future this should be tweaked to compute bytes for optimize_size and
- take into account performance of various instructions on various CPUs. */
-
-static int
-ix86_fp_comparison_cost (enum rtx_code code)
-{
- int arith_cost;
-
- /* The cost of code using bit-twiddling on %ah. */
- switch (code)
- {
- case UNLE:
- case UNLT:
- case LTGT:
- case GT:
- case GE:
- case UNORDERED:
- case ORDERED:
- case UNEQ:
- arith_cost = 4;
- break;
- case LT:
- case NE:
- case EQ:
- case UNGE:
- arith_cost = TARGET_IEEE_FP ? 5 : 4;
- break;
- case LE:
- case UNGT:
- arith_cost = TARGET_IEEE_FP ? 6 : 4;
- break;
- default:
- gcc_unreachable ();
- }
-
- switch (ix86_fp_comparison_strategy (code))
- {
- case IX86_FPCMP_COMI:
- return arith_cost > 4 ? 3 : 2;
- case IX86_FPCMP_SAHF:
- return arith_cost > 4 ? 4 : 3;
- default:
- return arith_cost;
- }
-}
-
-/* Return strategy to use for floating-point. We assume that fcomi is always
- preferrable where available, since that is also true when looking at size
- (2 bytes, vs. 3 for fnstsw+sahf and at least 5 for fnstsw+test). */
-
-enum ix86_fpcmp_strategy
-ix86_fp_comparison_strategy (enum rtx_code code ATTRIBUTE_UNUSED)
-{
- /* Do fcomi/sahf based test when profitable. */
-
- if (TARGET_CMOVE)
- return IX86_FPCMP_COMI;
-
- if (TARGET_SAHF && (TARGET_USE_SAHF || optimize_function_for_size_p (cfun)))
- return IX86_FPCMP_SAHF;
-
- return IX86_FPCMP_ARITH;
-}
-
-/* Swap, force into registers, or otherwise massage the two operands
- to a fp comparison. The operands are updated in place; the new
- comparison code is returned. */
-
-static enum rtx_code
-ix86_prepare_fp_compare_args (enum rtx_code code, rtx *pop0, rtx *pop1)
-{
- enum machine_mode fpcmp_mode = ix86_fp_compare_mode (code);
- rtx op0 = *pop0, op1 = *pop1;
- enum machine_mode op_mode = GET_MODE (op0);
- int is_sse = TARGET_SSE_MATH && SSE_FLOAT_MODE_P (op_mode);
-
- /* All of the unordered compare instructions only work on registers.
- The same is true of the fcomi compare instructions. The XFmode
- compare instructions require registers except when comparing
- against zero or when converting operand 1 from fixed point to
- floating point. */
-
- if (!is_sse
- && (fpcmp_mode == CCFPUmode
- || (op_mode == XFmode
- && ! (standard_80387_constant_p (op0) == 1
- || standard_80387_constant_p (op1) == 1)
- && GET_CODE (op1) != FLOAT)
- || ix86_fp_comparison_strategy (code) == IX86_FPCMP_COMI))
- {
- op0 = force_reg (op_mode, op0);
- op1 = force_reg (op_mode, op1);
- }
- else
- {
- /* %%% We only allow op1 in memory; op0 must be st(0). So swap
- things around if they appear profitable, otherwise force op0
- into a register. */
-
- if (standard_80387_constant_p (op0) == 0
- || (MEM_P (op0)
- && ! (standard_80387_constant_p (op1) == 0
- || MEM_P (op1))))
- {
- enum rtx_code new_code = ix86_fp_swap_condition (code);
- if (new_code != UNKNOWN)
- {
- rtx tmp;
- tmp = op0, op0 = op1, op1 = tmp;
- code = new_code;
- }
- }
-
- if (!REG_P (op0))
- op0 = force_reg (op_mode, op0);
-
- if (CONSTANT_P (op1))
- {
- int tmp = standard_80387_constant_p (op1);
- if (tmp == 0)
- op1 = validize_mem (force_const_mem (op_mode, op1));
- else if (tmp == 1)
- {
- if (TARGET_CMOVE)
- op1 = force_reg (op_mode, op1);
- }
- else
- op1 = force_reg (op_mode, op1);
- }
- }
-
- /* Try to rearrange the comparison to make it cheaper. */
- if (ix86_fp_comparison_cost (code)
- > ix86_fp_comparison_cost (swap_condition (code))
- && (REG_P (op1) || can_create_pseudo_p ()))
- {
- rtx tmp;
- tmp = op0, op0 = op1, op1 = tmp;
- code = swap_condition (code);
- if (!REG_P (op0))
- op0 = force_reg (op_mode, op0);
- }
-
- *pop0 = op0;
- *pop1 = op1;
- return code;
-}
-
-/* Convert comparison codes we use to represent FP comparison to integer
- code that will result in proper branch. Return UNKNOWN if no such code
- is available. */
-
-enum rtx_code
-ix86_fp_compare_code_to_integer (enum rtx_code code)
-{
- switch (code)
- {
- case GT:
- return GTU;
- case GE:
- return GEU;
- case ORDERED:
- case UNORDERED:
- return code;
- break;
- case UNEQ:
- return EQ;
- break;
- case UNLT:
- return LTU;
- break;
- case UNLE:
- return LEU;
- break;
- case LTGT:
- return NE;
- break;
- default:
- return UNKNOWN;
- }
-}
-
-/* Generate insn patterns to do a floating point compare of OPERANDS. */
-
-static rtx
-ix86_expand_fp_compare (enum rtx_code code, rtx op0, rtx op1, rtx scratch)
-{
- enum machine_mode fpcmp_mode, intcmp_mode;
- rtx tmp, tmp2;
-
- fpcmp_mode = ix86_fp_compare_mode (code);
- code = ix86_prepare_fp_compare_args (code, &op0, &op1);
-
- /* Do fcomi/sahf based test when profitable. */
- switch (ix86_fp_comparison_strategy (code))
- {
- case IX86_FPCMP_COMI:
- intcmp_mode = fpcmp_mode;
- tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1);
- tmp = gen_rtx_SET (VOIDmode, gen_rtx_REG (fpcmp_mode, FLAGS_REG),
- tmp);
- emit_insn (tmp);
- break;
-
- case IX86_FPCMP_SAHF:
- intcmp_mode = fpcmp_mode;
- tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1);
- tmp = gen_rtx_SET (VOIDmode, gen_rtx_REG (fpcmp_mode, FLAGS_REG),
- tmp);
-
- if (!scratch)
- scratch = gen_reg_rtx (HImode);
- tmp2 = gen_rtx_CLOBBER (VOIDmode, scratch);
- emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, tmp2)));
- break;
-
- case IX86_FPCMP_ARITH:
- /* Sadness wrt reg-stack pops killing fpsr -- gotta get fnstsw first. */
- tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1);
- tmp2 = gen_rtx_UNSPEC (HImode, gen_rtvec (1, tmp), UNSPEC_FNSTSW);
- if (!scratch)
- scratch = gen_reg_rtx (HImode);
- emit_insn (gen_rtx_SET (VOIDmode, scratch, tmp2));
-
- /* In the unordered case, we have to check C2 for NaN's, which
- doesn't happen to work out to anything nice combination-wise.
- So do some bit twiddling on the value we've got in AH to come
- up with an appropriate set of condition codes. */
-
- intcmp_mode = CCNOmode;
- switch (code)
- {
- case GT:
- case UNGT:
- if (code == GT || !TARGET_IEEE_FP)
- {
- emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x45)));
- code = EQ;
- }
- else
- {
- emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
- emit_insn (gen_addqi_ext_1 (scratch, scratch, constm1_rtx));
- emit_insn (gen_cmpqi_ext_3 (scratch, GEN_INT (0x44)));
- intcmp_mode = CCmode;
- code = GEU;
- }
- break;
- case LT:
- case UNLT:
- if (code == LT && TARGET_IEEE_FP)
- {
- emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
- emit_insn (gen_cmpqi_ext_3 (scratch, const1_rtx));
- intcmp_mode = CCmode;
- code = EQ;
- }
- else
- {
- emit_insn (gen_testqi_ext_ccno_0 (scratch, const1_rtx));
- code = NE;
- }
- break;
- case GE:
- case UNGE:
- if (code == GE || !TARGET_IEEE_FP)
- {
- emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x05)));
- code = EQ;
- }
- else
- {
- emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
- emit_insn (gen_xorqi_cc_ext_1 (scratch, scratch, const1_rtx));
- code = NE;
- }
- break;
- case LE:
- case UNLE:
- if (code == LE && TARGET_IEEE_FP)
- {
- emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
- emit_insn (gen_addqi_ext_1 (scratch, scratch, constm1_rtx));
- emit_insn (gen_cmpqi_ext_3 (scratch, GEN_INT (0x40)));
- intcmp_mode = CCmode;
- code = LTU;
- }
- else
- {
- emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x45)));
- code = NE;
- }
- break;
- case EQ:
- case UNEQ:
- if (code == EQ && TARGET_IEEE_FP)
- {
- emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
- emit_insn (gen_cmpqi_ext_3 (scratch, GEN_INT (0x40)));
- intcmp_mode = CCmode;
- code = EQ;
- }
- else
- {
- emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x40)));
- code = NE;
- }
- break;
- case NE:
- case LTGT:
- if (code == NE && TARGET_IEEE_FP)
- {
- emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
- emit_insn (gen_xorqi_cc_ext_1 (scratch, scratch,
- GEN_INT (0x40)));
- code = NE;
- }
- else
- {
- emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x40)));
- code = EQ;
- }
- break;
-
- case UNORDERED:
- emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x04)));
- code = NE;
- break;
- case ORDERED:
- emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x04)));
- code = EQ;
- break;
-
- default:
- gcc_unreachable ();
- }
- break;
-
- default:
- gcc_unreachable();
- }
-
- /* Return the test that should be put into the flags user, i.e.
- the bcc, scc, or cmov instruction. */
- return gen_rtx_fmt_ee (code, VOIDmode,
- gen_rtx_REG (intcmp_mode, FLAGS_REG),
- const0_rtx);
-}
-
-static rtx
-ix86_expand_compare (enum rtx_code code, rtx op0, rtx op1)
-{
- rtx ret;
-
- if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
- ret = gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
-
- else if (SCALAR_FLOAT_MODE_P (GET_MODE (op0)))
- {
- gcc_assert (!DECIMAL_FLOAT_MODE_P (GET_MODE (op0)));
- ret = ix86_expand_fp_compare (code, op0, op1, NULL_RTX);
- }
- else
- ret = ix86_expand_int_compare (code, op0, op1);
-
- return ret;
-}
-
-void
-ix86_expand_branch (enum rtx_code code, rtx op0, rtx op1, rtx label)
-{
- enum machine_mode mode = GET_MODE (op0);
- rtx tmp;
-
- switch (mode)
- {
- case SFmode:
- case DFmode:
- case XFmode:
- case QImode:
- case HImode:
- case SImode:
- simple:
- tmp = ix86_expand_compare (code, op0, op1);
- tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
- gen_rtx_LABEL_REF (VOIDmode, label),
- pc_rtx);
- emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
- return;
-
- case DImode:
- if (TARGET_64BIT)
- goto simple;
- case TImode:
- /* Expand DImode branch into multiple compare+branch. */
- {
- rtx lo[2], hi[2], label2;
- enum rtx_code code1, code2, code3;
- enum machine_mode submode;
-
- if (CONSTANT_P (op0) && !CONSTANT_P (op1))
- {
- tmp = op0, op0 = op1, op1 = tmp;
- code = swap_condition (code);
- }
-
- split_double_mode (mode, &op0, 1, lo+0, hi+0);
- split_double_mode (mode, &op1, 1, lo+1, hi+1);
-
- submode = mode == DImode ? SImode : DImode;
-
- /* When comparing for equality, we can use (hi0^hi1)|(lo0^lo1) to
- avoid two branches. This costs one extra insn, so disable when
- optimizing for size. */
-
- if ((code == EQ || code == NE)
- && (!optimize_insn_for_size_p ()
- || hi[1] == const0_rtx || lo[1] == const0_rtx))
- {
- rtx xor0, xor1;
-
- xor1 = hi[0];
- if (hi[1] != const0_rtx)
- xor1 = expand_binop (submode, xor_optab, xor1, hi[1],
- NULL_RTX, 0, OPTAB_WIDEN);
-
- xor0 = lo[0];
- if (lo[1] != const0_rtx)
- xor0 = expand_binop (submode, xor_optab, xor0, lo[1],
- NULL_RTX, 0, OPTAB_WIDEN);
-
- tmp = expand_binop (submode, ior_optab, xor1, xor0,
- NULL_RTX, 0, OPTAB_WIDEN);
-
- ix86_expand_branch (code, tmp, const0_rtx, label);
- return;
- }
-
- /* Otherwise, if we are doing less-than or greater-or-equal-than,
- op1 is a constant and the low word is zero, then we can just
- examine the high word. Similarly for low word -1 and
- less-or-equal-than or greater-than. */
-
- if (CONST_INT_P (hi[1]))
- switch (code)
- {
- case LT: case LTU: case GE: case GEU:
- if (lo[1] == const0_rtx)
- {
- ix86_expand_branch (code, hi[0], hi[1], label);
- return;
- }
- break;
- case LE: case LEU: case GT: case GTU:
- if (lo[1] == constm1_rtx)
- {
- ix86_expand_branch (code, hi[0], hi[1], label);
- return;
- }
- break;
- default:
- break;
- }
-
- /* Otherwise, we need two or three jumps. */
-
- label2 = gen_label_rtx ();
-
- code1 = code;
- code2 = swap_condition (code);
- code3 = unsigned_condition (code);
-
- switch (code)
- {
- case LT: case GT: case LTU: case GTU:
- break;
-
- case LE: code1 = LT; code2 = GT; break;
- case GE: code1 = GT; code2 = LT; break;
- case LEU: code1 = LTU; code2 = GTU; break;
- case GEU: code1 = GTU; code2 = LTU; break;
-
- case EQ: code1 = UNKNOWN; code2 = NE; break;
- case NE: code2 = UNKNOWN; break;
-
- default:
- gcc_unreachable ();
- }
-
- /*
- * a < b =>
- * if (hi(a) < hi(b)) goto true;
- * if (hi(a) > hi(b)) goto false;
- * if (lo(a) < lo(b)) goto true;
- * false:
- */
-
- if (code1 != UNKNOWN)
- ix86_expand_branch (code1, hi[0], hi[1], label);
- if (code2 != UNKNOWN)
- ix86_expand_branch (code2, hi[0], hi[1], label2);
-
- ix86_expand_branch (code3, lo[0], lo[1], label);
-
- if (code2 != UNKNOWN)
- emit_label (label2);
- return;
- }
-
- default:
- gcc_assert (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC);
- goto simple;
- }
-}
-
-/* Split branch based on floating point condition. */
-void
-ix86_split_fp_branch (enum rtx_code code, rtx op1, rtx op2,
- rtx target1, rtx target2, rtx tmp, rtx pushed)
-{
- rtx condition;
- rtx i;
-
- if (target2 != pc_rtx)
- {
- rtx tmp = target2;
- code = reverse_condition_maybe_unordered (code);
- target2 = target1;
- target1 = tmp;
- }
-
- condition = ix86_expand_fp_compare (code, op1, op2,
- tmp);
-
- /* Remove pushed operand from stack. */
- if (pushed)
- ix86_free_from_memory (GET_MODE (pushed));
-
- i = emit_jump_insn (gen_rtx_SET
- (VOIDmode, pc_rtx,
- gen_rtx_IF_THEN_ELSE (VOIDmode,
- condition, target1, target2)));
- if (split_branch_probability >= 0)
- add_reg_note (i, REG_BR_PROB, GEN_INT (split_branch_probability));
-}
-
-void
-ix86_expand_setcc (rtx dest, enum rtx_code code, rtx op0, rtx op1)
-{
- rtx ret;
-
- gcc_assert (GET_MODE (dest) == QImode);
-
- ret = ix86_expand_compare (code, op0, op1);
- PUT_MODE (ret, QImode);
- emit_insn (gen_rtx_SET (VOIDmode, dest, ret));
-}
-
-/* Expand comparison setting or clearing carry flag. Return true when
- successful and set pop for the operation. */
-static bool
-ix86_expand_carry_flag_compare (enum rtx_code code, rtx op0, rtx op1, rtx *pop)
-{
- enum machine_mode mode =
- GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
-
- /* Do not handle double-mode compares that go through special path. */
- if (mode == (TARGET_64BIT ? TImode : DImode))
- return false;
-
- if (SCALAR_FLOAT_MODE_P (mode))
- {
- rtx compare_op, compare_seq;
-
- gcc_assert (!DECIMAL_FLOAT_MODE_P (mode));
-
- /* Shortcut: following common codes never translate
- into carry flag compares. */
- if (code == EQ || code == NE || code == UNEQ || code == LTGT
- || code == ORDERED || code == UNORDERED)
- return false;
-
- /* These comparisons require zero flag; swap operands so they won't. */
- if ((code == GT || code == UNLE || code == LE || code == UNGT)
- && !TARGET_IEEE_FP)
- {
- rtx tmp = op0;
- op0 = op1;
- op1 = tmp;
- code = swap_condition (code);
- }
-
- /* Try to expand the comparison and verify that we end up with
- carry flag based comparison. This fails to be true only when
- we decide to expand comparison using arithmetic that is not
- too common scenario. */
- start_sequence ();
- compare_op = ix86_expand_fp_compare (code, op0, op1, NULL_RTX);
- compare_seq = get_insns ();
- end_sequence ();
-
- if (GET_MODE (XEXP (compare_op, 0)) == CCFPmode
- || GET_MODE (XEXP (compare_op, 0)) == CCFPUmode)
- code = ix86_fp_compare_code_to_integer (GET_CODE (compare_op));
- else
- code = GET_CODE (compare_op);
-
- if (code != LTU && code != GEU)
- return false;
-
- emit_insn (compare_seq);
- *pop = compare_op;
- return true;
- }
-
- if (!INTEGRAL_MODE_P (mode))
- return false;
-
- switch (code)
- {
- case LTU:
- case GEU:
- break;
-
- /* Convert a==0 into (unsigned)a<1. */
- case EQ:
- case NE:
- if (op1 != const0_rtx)
- return false;
- op1 = const1_rtx;
- code = (code == EQ ? LTU : GEU);
- break;
-
- /* Convert a>b into b<a or a>=b-1. */
- case GTU:
- case LEU:
- if (CONST_INT_P (op1))
- {
- op1 = gen_int_mode (INTVAL (op1) + 1, GET_MODE (op0));
- /* Bail out on overflow. We still can swap operands but that
- would force loading of the constant into register. */
- if (op1 == const0_rtx
- || !x86_64_immediate_operand (op1, GET_MODE (op1)))
- return false;
- code = (code == GTU ? GEU : LTU);
- }
- else
- {
- rtx tmp = op1;
- op1 = op0;
- op0 = tmp;
- code = (code == GTU ? LTU : GEU);
- }
- break;
-
- /* Convert a>=0 into (unsigned)a<0x80000000. */
- case LT:
- case GE:
- if (mode == DImode || op1 != const0_rtx)
- return false;
- op1 = gen_int_mode (1 << (GET_MODE_BITSIZE (mode) - 1), mode);
- code = (code == LT ? GEU : LTU);
- break;
- case LE:
- case GT:
- if (mode == DImode || op1 != constm1_rtx)
- return false;
- op1 = gen_int_mode (1 << (GET_MODE_BITSIZE (mode) - 1), mode);
- code = (code == LE ? GEU : LTU);
- break;
-
- default:
- return false;
- }
- /* Swapping operands may cause constant to appear as first operand. */
- if (!nonimmediate_operand (op0, VOIDmode))
- {
- if (!can_create_pseudo_p ())
- return false;
- op0 = force_reg (mode, op0);
- }
- *pop = ix86_expand_compare (code, op0, op1);
- gcc_assert (GET_CODE (*pop) == LTU || GET_CODE (*pop) == GEU);
- return true;
-}
-
-bool
-ix86_expand_int_movcc (rtx operands[])
-{
- enum rtx_code code = GET_CODE (operands[1]), compare_code;
- rtx compare_seq, compare_op;
- enum machine_mode mode = GET_MODE (operands[0]);
- bool sign_bit_compare_p = false;
- rtx op0 = XEXP (operands[1], 0);
- rtx op1 = XEXP (operands[1], 1);
-
- if (GET_MODE (op0) == TImode
- || (GET_MODE (op0) == DImode
- && !TARGET_64BIT))
- return false;
-
- start_sequence ();
- compare_op = ix86_expand_compare (code, op0, op1);
- compare_seq = get_insns ();
- end_sequence ();
-
- compare_code = GET_CODE (compare_op);
-
- if ((op1 == const0_rtx && (code == GE || code == LT))
- || (op1 == constm1_rtx && (code == GT || code == LE)))
- sign_bit_compare_p = true;
-
- /* Don't attempt mode expansion here -- if we had to expand 5 or 6
- HImode insns, we'd be swallowed in word prefix ops. */
-
- if ((mode != HImode || TARGET_FAST_PREFIX)
- && (mode != (TARGET_64BIT ? TImode : DImode))
- && CONST_INT_P (operands[2])
- && CONST_INT_P (operands[3]))
- {
- rtx out = operands[0];
- HOST_WIDE_INT ct = INTVAL (operands[2]);
- HOST_WIDE_INT cf = INTVAL (operands[3]);
- HOST_WIDE_INT diff;
-
- diff = ct - cf;
- /* Sign bit compares are better done using shifts than we do by using
- sbb. */
- if (sign_bit_compare_p
- || ix86_expand_carry_flag_compare (code, op0, op1, &compare_op))
- {
- /* Detect overlap between destination and compare sources. */
- rtx tmp = out;
-
- if (!sign_bit_compare_p)
- {
- rtx flags;
- bool fpcmp = false;
-
- compare_code = GET_CODE (compare_op);
-
- flags = XEXP (compare_op, 0);
-
- if (GET_MODE (flags) == CCFPmode
- || GET_MODE (flags) == CCFPUmode)
- {
- fpcmp = true;
- compare_code
- = ix86_fp_compare_code_to_integer (compare_code);
- }
-
- /* To simplify rest of code, restrict to the GEU case. */
- if (compare_code == LTU)
- {
- HOST_WIDE_INT tmp = ct;
- ct = cf;
- cf = tmp;
- compare_code = reverse_condition (compare_code);
- code = reverse_condition (code);
- }
- else
- {
- if (fpcmp)
- PUT_CODE (compare_op,
- reverse_condition_maybe_unordered
- (GET_CODE (compare_op)));
- else
- PUT_CODE (compare_op,
- reverse_condition (GET_CODE (compare_op)));
- }
- diff = ct - cf;
-
- if (reg_overlap_mentioned_p (out, op0)
- || reg_overlap_mentioned_p (out, op1))
- tmp = gen_reg_rtx (mode);
-
- if (mode == DImode)
- emit_insn (gen_x86_movdicc_0_m1 (tmp, flags, compare_op));
- else
- emit_insn (gen_x86_movsicc_0_m1 (gen_lowpart (SImode, tmp),
- flags, compare_op));
- }
- else
- {
- if (code == GT || code == GE)
- code = reverse_condition (code);
- else
- {
- HOST_WIDE_INT tmp = ct;
- ct = cf;
- cf = tmp;
- diff = ct - cf;
- }
- tmp = emit_store_flag (tmp, code, op0, op1, VOIDmode, 0, -1);
- }
-
- if (diff == 1)
- {
- /*
- * cmpl op0,op1
- * sbbl dest,dest
- * [addl dest, ct]
- *
- * Size 5 - 8.
- */
- if (ct)
- tmp = expand_simple_binop (mode, PLUS,
- tmp, GEN_INT (ct),
- copy_rtx (tmp), 1, OPTAB_DIRECT);
- }
- else if (cf == -1)
- {
- /*
- * cmpl op0,op1
- * sbbl dest,dest
- * orl $ct, dest
- *
- * Size 8.
- */
- tmp = expand_simple_binop (mode, IOR,
- tmp, GEN_INT (ct),
- copy_rtx (tmp), 1, OPTAB_DIRECT);
- }
- else if (diff == -1 && ct)
- {
- /*
- * cmpl op0,op1
- * sbbl dest,dest
- * notl dest
- * [addl dest, cf]
- *
- * Size 8 - 11.
- */
- tmp = expand_simple_unop (mode, NOT, tmp, copy_rtx (tmp), 1);
- if (cf)
- tmp = expand_simple_binop (mode, PLUS,
- copy_rtx (tmp), GEN_INT (cf),
- copy_rtx (tmp), 1, OPTAB_DIRECT);
- }
- else
- {
- /*
- * cmpl op0,op1
- * sbbl dest,dest
- * [notl dest]
- * andl cf - ct, dest
- * [addl dest, ct]
- *
- * Size 8 - 11.
- */
-
- if (cf == 0)
- {
- cf = ct;
- ct = 0;
- tmp = expand_simple_unop (mode, NOT, tmp, copy_rtx (tmp), 1);
- }
-
- tmp = expand_simple_binop (mode, AND,
- copy_rtx (tmp),
- gen_int_mode (cf - ct, mode),
- copy_rtx (tmp), 1, OPTAB_DIRECT);
- if (ct)
- tmp = expand_simple_binop (mode, PLUS,
- copy_rtx (tmp), GEN_INT (ct),
- copy_rtx (tmp), 1, OPTAB_DIRECT);
- }
-
- if (!rtx_equal_p (tmp, out))
- emit_move_insn (copy_rtx (out), copy_rtx (tmp));
-
- return true;
- }
-
- if (diff < 0)
- {
- enum machine_mode cmp_mode = GET_MODE (op0);
-
- HOST_WIDE_INT tmp;
- tmp = ct, ct = cf, cf = tmp;
- diff = -diff;
-
- if (SCALAR_FLOAT_MODE_P (cmp_mode))
- {
- gcc_assert (!DECIMAL_FLOAT_MODE_P (cmp_mode));
-
- /* We may be reversing unordered compare to normal compare, that
- is not valid in general (we may convert non-trapping condition
- to trapping one), however on i386 we currently emit all
- comparisons unordered. */
- compare_code = reverse_condition_maybe_unordered (compare_code);
- code = reverse_condition_maybe_unordered (code);
- }
- else
- {
- compare_code = reverse_condition (compare_code);
- code = reverse_condition (code);
- }
- }
-
- compare_code = UNKNOWN;
- if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
- && CONST_INT_P (op1))
- {
- if (op1 == const0_rtx
- && (code == LT || code == GE))
- compare_code = code;
- else if (op1 == constm1_rtx)
- {
- if (code == LE)
- compare_code = LT;
- else if (code == GT)
- compare_code = GE;
- }
- }
-
- /* Optimize dest = (op0 < 0) ? -1 : cf. */
- if (compare_code != UNKNOWN
- && GET_MODE (op0) == GET_MODE (out)
- && (cf == -1 || ct == -1))
- {
- /* If lea code below could be used, only optimize
- if it results in a 2 insn sequence. */
-
- if (! (diff == 1 || diff == 2 || diff == 4 || diff == 8
- || diff == 3 || diff == 5 || diff == 9)
- || (compare_code == LT && ct == -1)
- || (compare_code == GE && cf == -1))
- {
- /*
- * notl op1 (if necessary)
- * sarl $31, op1
- * orl cf, op1
- */
- if (ct != -1)
- {
- cf = ct;
- ct = -1;
- code = reverse_condition (code);
- }
-
- out = emit_store_flag (out, code, op0, op1, VOIDmode, 0, -1);
-
- out = expand_simple_binop (mode, IOR,
- out, GEN_INT (cf),
- out, 1, OPTAB_DIRECT);
- if (out != operands[0])
- emit_move_insn (operands[0], out);
-
- return true;
- }
- }
-
-
- if ((diff == 1 || diff == 2 || diff == 4 || diff == 8
- || diff == 3 || diff == 5 || diff == 9)
- && ((mode != QImode && mode != HImode) || !TARGET_PARTIAL_REG_STALL)
- && (mode != DImode
- || x86_64_immediate_operand (GEN_INT (cf), VOIDmode)))
- {
- /*
- * xorl dest,dest
- * cmpl op1,op2
- * setcc dest
- * lea cf(dest*(ct-cf)),dest
- *
- * Size 14.
- *
- * This also catches the degenerate setcc-only case.
- */
-
- rtx tmp;
- int nops;
-
- out = emit_store_flag (out, code, op0, op1, VOIDmode, 0, 1);
-
- nops = 0;
- /* On x86_64 the lea instruction operates on Pmode, so we need
- to get arithmetics done in proper mode to match. */
- if (diff == 1)
- tmp = copy_rtx (out);
- else
- {
- rtx out1;
- out1 = copy_rtx (out);
- tmp = gen_rtx_MULT (mode, out1, GEN_INT (diff & ~1));
- nops++;
- if (diff & 1)
- {
- tmp = gen_rtx_PLUS (mode, tmp, out1);
- nops++;
- }
- }
- if (cf != 0)
- {
- tmp = gen_rtx_PLUS (mode, tmp, GEN_INT (cf));
- nops++;
- }
- if (!rtx_equal_p (tmp, out))
- {
- if (nops == 1)
- out = force_operand (tmp, copy_rtx (out));
- else
- emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (out), copy_rtx (tmp)));
- }
- if (!rtx_equal_p (out, operands[0]))
- emit_move_insn (operands[0], copy_rtx (out));
-
- return true;
- }
-
- /*
- * General case: Jumpful:
- * xorl dest,dest cmpl op1, op2
- * cmpl op1, op2 movl ct, dest
- * setcc dest jcc 1f
- * decl dest movl cf, dest
- * andl (cf-ct),dest 1:
- * addl ct,dest
- *
- * Size 20. Size 14.
- *
- * This is reasonably steep, but branch mispredict costs are
- * high on modern cpus, so consider failing only if optimizing
- * for space.
- */
-
- if ((!TARGET_CMOVE || (mode == QImode && TARGET_PARTIAL_REG_STALL))
- && BRANCH_COST (optimize_insn_for_speed_p (),
- false) >= 2)
- {
- if (cf == 0)
- {
- enum machine_mode cmp_mode = GET_MODE (op0);
-
- cf = ct;
- ct = 0;
-
- if (SCALAR_FLOAT_MODE_P (cmp_mode))
- {
- gcc_assert (!DECIMAL_FLOAT_MODE_P (cmp_mode));
-
- /* We may be reversing unordered compare to normal compare,
- that is not valid in general (we may convert non-trapping
- condition to trapping one), however on i386 we currently
- emit all comparisons unordered. */
- code = reverse_condition_maybe_unordered (code);
- }
- else
- {
- code = reverse_condition (code);
- if (compare_code != UNKNOWN)
- compare_code = reverse_condition (compare_code);
- }
- }
-
- if (compare_code != UNKNOWN)
- {
- /* notl op1 (if needed)
- sarl $31, op1
- andl (cf-ct), op1
- addl ct, op1
-
- For x < 0 (resp. x <= -1) there will be no notl,
- so if possible swap the constants to get rid of the
- complement.
- True/false will be -1/0 while code below (store flag
- followed by decrement) is 0/-1, so the constants need
- to be exchanged once more. */
-
- if (compare_code == GE || !cf)
- {
- code = reverse_condition (code);
- compare_code = LT;
- }
- else
- {
- HOST_WIDE_INT tmp = cf;
- cf = ct;
- ct = tmp;
- }
-
- out = emit_store_flag (out, code, op0, op1, VOIDmode, 0, -1);
- }
- else
- {
- out = emit_store_flag (out, code, op0, op1, VOIDmode, 0, 1);
-
- out = expand_simple_binop (mode, PLUS, copy_rtx (out),
- constm1_rtx,
- copy_rtx (out), 1, OPTAB_DIRECT);
- }
-
- out = expand_simple_binop (mode, AND, copy_rtx (out),
- gen_int_mode (cf - ct, mode),
- copy_rtx (out), 1, OPTAB_DIRECT);
- if (ct)
- out = expand_simple_binop (mode, PLUS, copy_rtx (out), GEN_INT (ct),
- copy_rtx (out), 1, OPTAB_DIRECT);
- if (!rtx_equal_p (out, operands[0]))
- emit_move_insn (operands[0], copy_rtx (out));
-
- return true;
- }
- }
-
- if (!TARGET_CMOVE || (mode == QImode && TARGET_PARTIAL_REG_STALL))
- {
- /* Try a few things more with specific constants and a variable. */
-
- optab op;
- rtx var, orig_out, out, tmp;
-
- if (BRANCH_COST (optimize_insn_for_speed_p (), false) <= 2)
- return false;
-
- /* If one of the two operands is an interesting constant, load a
- constant with the above and mask it in with a logical operation. */
-
- if (CONST_INT_P (operands[2]))
- {
- var = operands[3];
- if (INTVAL (operands[2]) == 0 && operands[3] != constm1_rtx)
- operands[3] = constm1_rtx, op = and_optab;
- else if (INTVAL (operands[2]) == -1 && operands[3] != const0_rtx)
- operands[3] = const0_rtx, op = ior_optab;
- else
- return false;
- }
- else if (CONST_INT_P (operands[3]))
- {
- var = operands[2];
- if (INTVAL (operands[3]) == 0 && operands[2] != constm1_rtx)
- operands[2] = constm1_rtx, op = and_optab;
- else if (INTVAL (operands[3]) == -1 && operands[3] != const0_rtx)
- operands[2] = const0_rtx, op = ior_optab;
- else
- return false;
- }
- else
- return false;
-
- orig_out = operands[0];
- tmp = gen_reg_rtx (mode);
- operands[0] = tmp;
-
- /* Recurse to get the constant loaded. */
- if (ix86_expand_int_movcc (operands) == 0)
- return false;
-
- /* Mask in the interesting variable. */
- out = expand_binop (mode, op, var, tmp, orig_out, 0,
- OPTAB_WIDEN);
- if (!rtx_equal_p (out, orig_out))
- emit_move_insn (copy_rtx (orig_out), copy_rtx (out));
-
- return true;
- }
-
- /*
- * For comparison with above,
- *
- * movl cf,dest
- * movl ct,tmp
- * cmpl op1,op2
- * cmovcc tmp,dest
- *
- * Size 15.
- */
-
- if (! nonimmediate_operand (operands[2], mode))
- operands[2] = force_reg (mode, operands[2]);
- if (! nonimmediate_operand (operands[3], mode))
- operands[3] = force_reg (mode, operands[3]);
-
- if (! register_operand (operands[2], VOIDmode)
- && (mode == QImode
- || ! register_operand (operands[3], VOIDmode)))
- operands[2] = force_reg (mode, operands[2]);
-
- if (mode == QImode
- && ! register_operand (operands[3], VOIDmode))
- operands[3] = force_reg (mode, operands[3]);
-
- emit_insn (compare_seq);
- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
- gen_rtx_IF_THEN_ELSE (mode,
- compare_op, operands[2],
- operands[3])));
- return true;
-}
-
-/* Swap, force into registers, or otherwise massage the two operands
- to an sse comparison with a mask result. Thus we differ a bit from
- ix86_prepare_fp_compare_args which expects to produce a flags result.
-
- The DEST operand exists to help determine whether to commute commutative
- operators. The POP0/POP1 operands are updated in place. The new
- comparison code is returned, or UNKNOWN if not implementable. */
-
-static enum rtx_code
-ix86_prepare_sse_fp_compare_args (rtx dest, enum rtx_code code,
- rtx *pop0, rtx *pop1)
-{
- rtx tmp;
-
- switch (code)
- {
- case LTGT:
- case UNEQ:
- /* AVX supports all the needed comparisons. */
- if (TARGET_AVX)
- break;
- /* We have no LTGT as an operator. We could implement it with
- NE & ORDERED, but this requires an extra temporary. It's
- not clear that it's worth it. */
- return UNKNOWN;
-
- case LT:
- case LE:
- case UNGT:
- case UNGE:
- /* These are supported directly. */
- break;
-
- case EQ:
- case NE:
- case UNORDERED:
- case ORDERED:
- /* AVX has 3 operand comparisons, no need to swap anything. */
- if (TARGET_AVX)
- break;
- /* For commutative operators, try to canonicalize the destination
- operand to be first in the comparison - this helps reload to
- avoid extra moves. */
- if (!dest || !rtx_equal_p (dest, *pop1))
- break;
- /* FALLTHRU */
-
- case GE:
- case GT:
- case UNLE:
- case UNLT:
- /* These are not supported directly before AVX, and furthermore
- ix86_expand_sse_fp_minmax only optimizes LT/UNGE. Swap the
- comparison operands to transform into something that is
- supported. */
- tmp = *pop0;
- *pop0 = *pop1;
- *pop1 = tmp;
- code = swap_condition (code);
- break;
-
- default:
- gcc_unreachable ();
- }
-
- return code;
-}
-
-/* Detect conditional moves that exactly match min/max operational
- semantics. Note that this is IEEE safe, as long as we don't
- interchange the operands.
-
- Returns FALSE if this conditional move doesn't match a MIN/MAX,
- and TRUE if the operation is successful and instructions are emitted. */
-
-static bool
-ix86_expand_sse_fp_minmax (rtx dest, enum rtx_code code, rtx cmp_op0,
- rtx cmp_op1, rtx if_true, rtx if_false)
-{
- enum machine_mode mode;
- bool is_min;
- rtx tmp;
-
- if (code == LT)
- ;
- else if (code == UNGE)
- {
- tmp = if_true;
- if_true = if_false;
- if_false = tmp;
- }
- else
- return false;
-
- if (rtx_equal_p (cmp_op0, if_true) && rtx_equal_p (cmp_op1, if_false))
- is_min = true;
- else if (rtx_equal_p (cmp_op1, if_true) && rtx_equal_p (cmp_op0, if_false))
- is_min = false;
- else
- return false;
-
- mode = GET_MODE (dest);
-
- /* We want to check HONOR_NANS and HONOR_SIGNED_ZEROS here,
- but MODE may be a vector mode and thus not appropriate. */
- if (!flag_finite_math_only || !flag_unsafe_math_optimizations)
- {
- int u = is_min ? UNSPEC_IEEE_MIN : UNSPEC_IEEE_MAX;
- rtvec v;
-
- if_true = force_reg (mode, if_true);
- v = gen_rtvec (2, if_true, if_false);
- tmp = gen_rtx_UNSPEC (mode, v, u);
- }
- else
- {
- code = is_min ? SMIN : SMAX;
- tmp = gen_rtx_fmt_ee (code, mode, if_true, if_false);
- }
-
- emit_insn (gen_rtx_SET (VOIDmode, dest, tmp));
- return true;
-}
-
-/* Expand an sse vector comparison. Return the register with the result. */
-
-static rtx
-ix86_expand_sse_cmp (rtx dest, enum rtx_code code, rtx cmp_op0, rtx cmp_op1,
- rtx op_true, rtx op_false)
-{
- enum machine_mode mode = GET_MODE (dest);
- enum machine_mode cmp_mode = GET_MODE (cmp_op0);
- rtx x;
-
- cmp_op0 = force_reg (cmp_mode, cmp_op0);
- if (!nonimmediate_operand (cmp_op1, cmp_mode))
- cmp_op1 = force_reg (cmp_mode, cmp_op1);
-
- if (optimize
- || reg_overlap_mentioned_p (dest, op_true)
- || reg_overlap_mentioned_p (dest, op_false))
- dest = gen_reg_rtx (mode);
-
- x = gen_rtx_fmt_ee (code, cmp_mode, cmp_op0, cmp_op1);
- if (cmp_mode != mode)
- {
- x = force_reg (cmp_mode, x);
- convert_move (dest, x, false);
- }
- else
- emit_insn (gen_rtx_SET (VOIDmode, dest, x));
-
- return dest;
-}
-
-/* Expand DEST = CMP ? OP_TRUE : OP_FALSE into a sequence of logical
- operations. This is used for both scalar and vector conditional moves. */
-
-static void
-ix86_expand_sse_movcc (rtx dest, rtx cmp, rtx op_true, rtx op_false)
-{
- enum machine_mode mode = GET_MODE (dest);
- rtx t2, t3, x;
-
- if (vector_all_ones_operand (op_true, mode)
- && rtx_equal_p (op_false, CONST0_RTX (mode)))
- {
- emit_insn (gen_rtx_SET (VOIDmode, dest, cmp));
- }
- else if (op_false == CONST0_RTX (mode))
- {
- op_true = force_reg (mode, op_true);
- x = gen_rtx_AND (mode, cmp, op_true);
- emit_insn (gen_rtx_SET (VOIDmode, dest, x));
- }
- else if (op_true == CONST0_RTX (mode))
- {
- op_false = force_reg (mode, op_false);
- x = gen_rtx_NOT (mode, cmp);
- x = gen_rtx_AND (mode, x, op_false);
- emit_insn (gen_rtx_SET (VOIDmode, dest, x));
- }
- else if (INTEGRAL_MODE_P (mode) && op_true == CONSTM1_RTX (mode))
- {
- op_false = force_reg (mode, op_false);
- x = gen_rtx_IOR (mode, cmp, op_false);
- emit_insn (gen_rtx_SET (VOIDmode, dest, x));
- }
- else if (TARGET_XOP)
- {
- op_true = force_reg (mode, op_true);
-
- if (!nonimmediate_operand (op_false, mode))
- op_false = force_reg (mode, op_false);
-
- emit_insn (gen_rtx_SET (mode, dest,
- gen_rtx_IF_THEN_ELSE (mode, cmp,
- op_true,
- op_false)));
- }
- else
- {
- rtx (*gen) (rtx, rtx, rtx, rtx) = NULL;
-
- if (!nonimmediate_operand (op_true, mode))
- op_true = force_reg (mode, op_true);
-
- op_false = force_reg (mode, op_false);
-
- switch (mode)
- {
- case V4SFmode:
- if (TARGET_SSE4_1)
- gen = gen_sse4_1_blendvps;
- break;
- case V2DFmode:
- if (TARGET_SSE4_1)
- gen = gen_sse4_1_blendvpd;
- break;
- case V16QImode:
- case V8HImode:
- case V4SImode:
- case V2DImode:
- if (TARGET_SSE4_1)
- {
- gen = gen_sse4_1_pblendvb;
- dest = gen_lowpart (V16QImode, dest);
- op_false = gen_lowpart (V16QImode, op_false);
- op_true = gen_lowpart (V16QImode, op_true);
- cmp = gen_lowpart (V16QImode, cmp);
- }
- break;
- case V8SFmode:
- if (TARGET_AVX)
- gen = gen_avx_blendvps256;
- break;
- case V4DFmode:
- if (TARGET_AVX)
- gen = gen_avx_blendvpd256;
- break;
- case V32QImode:
- case V16HImode:
- case V8SImode:
- case V4DImode:
- if (TARGET_AVX2)
- {
- gen = gen_avx2_pblendvb;
- dest = gen_lowpart (V32QImode, dest);
- op_false = gen_lowpart (V32QImode, op_false);
- op_true = gen_lowpart (V32QImode, op_true);
- cmp = gen_lowpart (V32QImode, cmp);
- }
- break;
- default:
- break;
- }
-
- if (gen != NULL)
- emit_insn (gen (dest, op_false, op_true, cmp));
- else
- {
- op_true = force_reg (mode, op_true);
-
- t2 = gen_reg_rtx (mode);
- if (optimize)
- t3 = gen_reg_rtx (mode);
- else
- t3 = dest;
-
- x = gen_rtx_AND (mode, op_true, cmp);
- emit_insn (gen_rtx_SET (VOIDmode, t2, x));
-
- x = gen_rtx_NOT (mode, cmp);
- x = gen_rtx_AND (mode, x, op_false);
- emit_insn (gen_rtx_SET (VOIDmode, t3, x));
-
- x = gen_rtx_IOR (mode, t3, t2);
- emit_insn (gen_rtx_SET (VOIDmode, dest, x));
- }
- }
-}
-
-/* Expand a floating-point conditional move. Return true if successful. */
-
-bool
-ix86_expand_fp_movcc (rtx operands[])
-{
- enum machine_mode mode = GET_MODE (operands[0]);
- enum rtx_code code = GET_CODE (operands[1]);
- rtx tmp, compare_op;
- rtx op0 = XEXP (operands[1], 0);
- rtx op1 = XEXP (operands[1], 1);
-
- if (TARGET_SSE_MATH && SSE_FLOAT_MODE_P (mode))
- {
- enum machine_mode cmode;
-
- /* Since we've no cmove for sse registers, don't force bad register
- allocation just to gain access to it. Deny movcc when the
- comparison mode doesn't match the move mode. */
- cmode = GET_MODE (op0);
- if (cmode == VOIDmode)
- cmode = GET_MODE (op1);
- if (cmode != mode)
- return false;
-
- code = ix86_prepare_sse_fp_compare_args (operands[0], code, &op0, &op1);
- if (code == UNKNOWN)
- return false;
-
- if (ix86_expand_sse_fp_minmax (operands[0], code, op0, op1,
- operands[2], operands[3]))
- return true;
-
- tmp = ix86_expand_sse_cmp (operands[0], code, op0, op1,
- operands[2], operands[3]);
- ix86_expand_sse_movcc (operands[0], tmp, operands[2], operands[3]);
- return true;
- }
-
- if (GET_MODE (op0) == TImode
- || (GET_MODE (op0) == DImode
- && !TARGET_64BIT))
- return false;
-
- /* The floating point conditional move instructions don't directly
- support conditions resulting from a signed integer comparison. */
-
- compare_op = ix86_expand_compare (code, op0, op1);
- if (!fcmov_comparison_operator (compare_op, VOIDmode))
- {
- tmp = gen_reg_rtx (QImode);
- ix86_expand_setcc (tmp, code, op0, op1);
-
- compare_op = ix86_expand_compare (NE, tmp, const0_rtx);
- }
-
- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
- gen_rtx_IF_THEN_ELSE (mode, compare_op,
- operands[2], operands[3])));
-
- return true;
-}
-
-/* Expand a floating-point vector conditional move; a vcond operation
- rather than a movcc operation. */
-
-bool
-ix86_expand_fp_vcond (rtx operands[])
-{
- enum rtx_code code = GET_CODE (operands[3]);
- rtx cmp;
-
- code = ix86_prepare_sse_fp_compare_args (operands[0], code,
- &operands[4], &operands[5]);
- if (code == UNKNOWN)
- {
- rtx temp;
- switch (GET_CODE (operands[3]))
- {
- case LTGT:
- temp = ix86_expand_sse_cmp (operands[0], ORDERED, operands[4],
- operands[5], operands[0], operands[0]);
- cmp = ix86_expand_sse_cmp (operands[0], NE, operands[4],
- operands[5], operands[1], operands[2]);
- code = AND;
- break;
- case UNEQ:
- temp = ix86_expand_sse_cmp (operands[0], UNORDERED, operands[4],
- operands[5], operands[0], operands[0]);
- cmp = ix86_expand_sse_cmp (operands[0], EQ, operands[4],
- operands[5], operands[1], operands[2]);
- code = IOR;
- break;
- default:
- gcc_unreachable ();
- }
- cmp = expand_simple_binop (GET_MODE (cmp), code, temp, cmp, cmp, 1,
- OPTAB_DIRECT);
- ix86_expand_sse_movcc (operands[0], cmp, operands[1], operands[2]);
- return true;
- }
-
- if (ix86_expand_sse_fp_minmax (operands[0], code, operands[4],
- operands[5], operands[1], operands[2]))
- return true;
-
- cmp = ix86_expand_sse_cmp (operands[0], code, operands[4], operands[5],
- operands[1], operands[2]);
- ix86_expand_sse_movcc (operands[0], cmp, operands[1], operands[2]);
- return true;
-}
-
-/* Expand a signed/unsigned integral vector conditional move. */
-
-bool
-ix86_expand_int_vcond (rtx operands[])
-{
- enum machine_mode data_mode = GET_MODE (operands[0]);
- enum machine_mode mode = GET_MODE (operands[4]);
- enum rtx_code code = GET_CODE (operands[3]);
- bool negate = false;
- rtx x, cop0, cop1;
-
- cop0 = operands[4];
- cop1 = operands[5];
-
- /* Try to optimize x < 0 ? -1 : 0 into (signed) x >> 31
- and x < 0 ? 1 : 0 into (unsigned) x >> 31. */
- if ((code == LT || code == GE)
- && data_mode == mode
- && cop1 == CONST0_RTX (mode)
- && operands[1 + (code == LT)] == CONST0_RTX (data_mode)
- && GET_MODE_SIZE (GET_MODE_INNER (data_mode)) > 1
- && GET_MODE_SIZE (GET_MODE_INNER (data_mode)) <= 8
- && (GET_MODE_SIZE (data_mode) == 16
- || (TARGET_AVX2 && GET_MODE_SIZE (data_mode) == 32)))
- {
- rtx negop = operands[2 - (code == LT)];
- int shift = GET_MODE_BITSIZE (GET_MODE_INNER (data_mode)) - 1;
- if (negop == CONST1_RTX (data_mode))
- {
- rtx res = expand_simple_binop (mode, LSHIFTRT, cop0, GEN_INT (shift),
- operands[0], 1, OPTAB_DIRECT);
- if (res != operands[0])
- emit_move_insn (operands[0], res);
- return true;
- }
- else if (GET_MODE_INNER (data_mode) != DImode
- && vector_all_ones_operand (negop, data_mode))
- {
- rtx res = expand_simple_binop (mode, ASHIFTRT, cop0, GEN_INT (shift),
- operands[0], 0, OPTAB_DIRECT);
- if (res != operands[0])
- emit_move_insn (operands[0], res);
- return true;
- }
- }
-
- if (!nonimmediate_operand (cop1, mode))
- cop1 = force_reg (mode, cop1);
- if (!general_operand (operands[1], data_mode))
- operands[1] = force_reg (data_mode, operands[1]);
- if (!general_operand (operands[2], data_mode))
- operands[2] = force_reg (data_mode, operands[2]);
-
- /* XOP supports all of the comparisons on all 128-bit vector int types. */
- if (TARGET_XOP
- && (mode == V16QImode || mode == V8HImode
- || mode == V4SImode || mode == V2DImode))
- ;
- else
- {
- /* Canonicalize the comparison to EQ, GT, GTU. */
- switch (code)
- {
- case EQ:
- case GT:
- case GTU:
- break;
-
- case NE:
- case LE:
- case LEU:
- code = reverse_condition (code);
- negate = true;
- break;
-
- case GE:
- case GEU:
- code = reverse_condition (code);
- negate = true;
- /* FALLTHRU */
-
- case LT:
- case LTU:
- code = swap_condition (code);
- x = cop0, cop0 = cop1, cop1 = x;
- break;
-
- default:
- gcc_unreachable ();
- }
-
- /* Only SSE4.1/SSE4.2 supports V2DImode. */
- if (mode == V2DImode)
- {
- switch (code)
- {
- case EQ:
- /* SSE4.1 supports EQ. */
- if (!TARGET_SSE4_1)
- return false;
- break;
-
- case GT:
- case GTU:
- /* SSE4.2 supports GT/GTU. */
- if (!TARGET_SSE4_2)
- return false;
- break;
-
- default:
- gcc_unreachable ();
- }
- }
-
- /* Unsigned parallel compare is not supported by the hardware.
- Play some tricks to turn this into a signed comparison
- against 0. */
- if (code == GTU)
- {
- cop0 = force_reg (mode, cop0);
-
- switch (mode)
- {
- case V8SImode:
- case V4DImode:
- case V4SImode:
- case V2DImode:
- {
- rtx t1, t2, mask;
- rtx (*gen_sub3) (rtx, rtx, rtx);
-
- switch (mode)
- {
- case V8SImode: gen_sub3 = gen_subv8si3; break;
- case V4DImode: gen_sub3 = gen_subv4di3; break;
- case V4SImode: gen_sub3 = gen_subv4si3; break;
- case V2DImode: gen_sub3 = gen_subv2di3; break;
- default:
- gcc_unreachable ();
- }
- /* Subtract (-(INT MAX) - 1) from both operands to make
- them signed. */
- mask = ix86_build_signbit_mask (mode, true, false);
- t1 = gen_reg_rtx (mode);
- emit_insn (gen_sub3 (t1, cop0, mask));
-
- t2 = gen_reg_rtx (mode);
- emit_insn (gen_sub3 (t2, cop1, mask));
-
- cop0 = t1;
- cop1 = t2;
- code = GT;
- }
- break;
-
- case V32QImode:
- case V16HImode:
- case V16QImode:
- case V8HImode:
- /* Perform a parallel unsigned saturating subtraction. */
- x = gen_reg_rtx (mode);
- emit_insn (gen_rtx_SET (VOIDmode, x,
- gen_rtx_US_MINUS (mode, cop0, cop1)));
-
- cop0 = x;
- cop1 = CONST0_RTX (mode);
- code = EQ;
- negate = !negate;
- break;
-
- default:
- gcc_unreachable ();
- }
- }
- }
-
- /* Allow the comparison to be done in one mode, but the movcc to
- happen in another mode. */
- if (data_mode == mode)
- {
- x = ix86_expand_sse_cmp (operands[0], code, cop0, cop1,
- operands[1+negate], operands[2-negate]);
- }
- else
- {
- gcc_assert (GET_MODE_SIZE (data_mode) == GET_MODE_SIZE (mode));
- x = ix86_expand_sse_cmp (gen_lowpart (mode, operands[0]),
- code, cop0, cop1,
- operands[1+negate], operands[2-negate]);
- x = gen_lowpart (data_mode, x);
- }
-
- ix86_expand_sse_movcc (operands[0], x, operands[1+negate],
- operands[2-negate]);
- return true;
-}
-
-/* Expand a variable vector permutation. */
-
-void
-ix86_expand_vec_perm (rtx operands[])
-{
- rtx target = operands[0];
- rtx op0 = operands[1];
- rtx op1 = operands[2];
- rtx mask = operands[3];
- rtx t1, t2, t3, t4, vt, vt2, vec[32];
- enum machine_mode mode = GET_MODE (op0);
- enum machine_mode maskmode = GET_MODE (mask);
- int w, e, i;
- bool one_operand_shuffle = rtx_equal_p (op0, op1);
-
- /* Number of elements in the vector. */
- w = GET_MODE_NUNITS (mode);
- e = GET_MODE_UNIT_SIZE (mode);
- gcc_assert (w <= 32);
-
- if (TARGET_AVX2)
- {
- if (mode == V4DImode || mode == V4DFmode || mode == V16HImode)
- {
- /* Unfortunately, the VPERMQ and VPERMPD instructions only support
- an constant shuffle operand. With a tiny bit of effort we can
- use VPERMD instead. A re-interpretation stall for V4DFmode is
- unfortunate but there's no avoiding it.
- Similarly for V16HImode we don't have instructions for variable
- shuffling, while for V32QImode we can use after preparing suitable
- masks vpshufb; vpshufb; vpermq; vpor. */
-
- if (mode == V16HImode)
- {
- maskmode = mode = V32QImode;
- w = 32;
- e = 1;
- }
- else
- {
- maskmode = mode = V8SImode;
- w = 8;
- e = 4;
- }
- t1 = gen_reg_rtx (maskmode);
-
- /* Replicate the low bits of the V4DImode mask into V8SImode:
- mask = { A B C D }
- t1 = { A A B B C C D D }. */
- for (i = 0; i < w / 2; ++i)
- vec[i*2 + 1] = vec[i*2] = GEN_INT (i * 2);
- vt = gen_rtx_CONST_VECTOR (maskmode, gen_rtvec_v (w, vec));
- vt = force_reg (maskmode, vt);
- mask = gen_lowpart (maskmode, mask);
- if (maskmode == V8SImode)
- emit_insn (gen_avx2_permvarv8si (t1, mask, vt));
- else
- emit_insn (gen_avx2_pshufbv32qi3 (t1, mask, vt));
-
- /* Multiply the shuffle indicies by two. */
- t1 = expand_simple_binop (maskmode, PLUS, t1, t1, t1, 1,
- OPTAB_DIRECT);
-
- /* Add one to the odd shuffle indicies:
- t1 = { A*2, A*2+1, B*2, B*2+1, ... }. */
- for (i = 0; i < w / 2; ++i)
- {
- vec[i * 2] = const0_rtx;
- vec[i * 2 + 1] = const1_rtx;
- }
- vt = gen_rtx_CONST_VECTOR (maskmode, gen_rtvec_v (w, vec));
- vt = validize_mem (force_const_mem (maskmode, vt));
- t1 = expand_simple_binop (maskmode, PLUS, t1, vt, t1, 1,
- OPTAB_DIRECT);
-
- /* Continue as if V8SImode (resp. V32QImode) was used initially. */
- operands[3] = mask = t1;
- target = gen_lowpart (mode, target);
- op0 = gen_lowpart (mode, op0);
- op1 = gen_lowpart (mode, op1);
- }
-
- switch (mode)
- {
- case V8SImode:
- /* The VPERMD and VPERMPS instructions already properly ignore
- the high bits of the shuffle elements. No need for us to
- perform an AND ourselves. */
- if (one_operand_shuffle)
- emit_insn (gen_avx2_permvarv8si (target, op0, mask));
- else
- {
- t1 = gen_reg_rtx (V8SImode);
- t2 = gen_reg_rtx (V8SImode);
- emit_insn (gen_avx2_permvarv8si (t1, op0, mask));
- emit_insn (gen_avx2_permvarv8si (t2, op1, mask));
- goto merge_two;
- }
- return;
-
- case V8SFmode:
- mask = gen_lowpart (V8SFmode, mask);
- if (one_operand_shuffle)
- emit_insn (gen_avx2_permvarv8sf (target, op0, mask));
- else
- {
- t1 = gen_reg_rtx (V8SFmode);
- t2 = gen_reg_rtx (V8SFmode);
- emit_insn (gen_avx2_permvarv8sf (t1, op0, mask));
- emit_insn (gen_avx2_permvarv8sf (t2, op1, mask));
- goto merge_two;
- }
- return;
-
- case V4SImode:
- /* By combining the two 128-bit input vectors into one 256-bit
- input vector, we can use VPERMD and VPERMPS for the full
- two-operand shuffle. */
- t1 = gen_reg_rtx (V8SImode);
- t2 = gen_reg_rtx (V8SImode);
- emit_insn (gen_avx_vec_concatv8si (t1, op0, op1));
- emit_insn (gen_avx_vec_concatv8si (t2, mask, mask));
- emit_insn (gen_avx2_permvarv8si (t1, t1, t2));
- emit_insn (gen_avx_vextractf128v8si (target, t1, const0_rtx));
- return;
-
- case V4SFmode:
- t1 = gen_reg_rtx (V8SFmode);
- t2 = gen_reg_rtx (V8SImode);
- mask = gen_lowpart (V4SImode, mask);
- emit_insn (gen_avx_vec_concatv8sf (t1, op0, op1));
- emit_insn (gen_avx_vec_concatv8si (t2, mask, mask));
- emit_insn (gen_avx2_permvarv8sf (t1, t1, t2));
- emit_insn (gen_avx_vextractf128v8sf (target, t1, const0_rtx));
- return;
-
- case V32QImode:
- t1 = gen_reg_rtx (V32QImode);
- t2 = gen_reg_rtx (V32QImode);
- t3 = gen_reg_rtx (V32QImode);
- vt2 = GEN_INT (128);
- for (i = 0; i < 32; i++)
- vec[i] = vt2;
- vt = gen_rtx_CONST_VECTOR (V32QImode, gen_rtvec_v (32, vec));
- vt = force_reg (V32QImode, vt);
- for (i = 0; i < 32; i++)
- vec[i] = i < 16 ? vt2 : const0_rtx;
- vt2 = gen_rtx_CONST_VECTOR (V32QImode, gen_rtvec_v (32, vec));
- vt2 = force_reg (V32QImode, vt2);
- /* From mask create two adjusted masks, which contain the same
- bits as mask in the low 7 bits of each vector element.
- The first mask will have the most significant bit clear
- if it requests element from the same 128-bit lane
- and MSB set if it requests element from the other 128-bit lane.
- The second mask will have the opposite values of the MSB,
- and additionally will have its 128-bit lanes swapped.
- E.g. { 07 12 1e 09 ... | 17 19 05 1f ... } mask vector will have
- t1 { 07 92 9e 09 ... | 17 19 85 1f ... } and
- t3 { 97 99 05 9f ... | 87 12 1e 89 ... } where each ...
- stands for other 12 bytes. */
- /* The bit whether element is from the same lane or the other
- lane is bit 4, so shift it up by 3 to the MSB position. */
- emit_insn (gen_ashlv4di3 (gen_lowpart (V4DImode, t1),
- gen_lowpart (V4DImode, mask),
- GEN_INT (3)));
- /* Clear MSB bits from the mask just in case it had them set. */
- emit_insn (gen_avx2_andnotv32qi3 (t2, vt, mask));
- /* After this t1 will have MSB set for elements from other lane. */
- emit_insn (gen_xorv32qi3 (t1, t1, vt2));
- /* Clear bits other than MSB. */
- emit_insn (gen_andv32qi3 (t1, t1, vt));
- /* Or in the lower bits from mask into t3. */
- emit_insn (gen_iorv32qi3 (t3, t1, t2));
- /* And invert MSB bits in t1, so MSB is set for elements from the same
- lane. */
- emit_insn (gen_xorv32qi3 (t1, t1, vt));
- /* Swap 128-bit lanes in t3. */
- emit_insn (gen_avx2_permv4di_1 (gen_lowpart (V4DImode, t3),
- gen_lowpart (V4DImode, t3),
- const2_rtx, GEN_INT (3),
- const0_rtx, const1_rtx));
- /* And or in the lower bits from mask into t1. */
- emit_insn (gen_iorv32qi3 (t1, t1, t2));
- if (one_operand_shuffle)
- {
- /* Each of these shuffles will put 0s in places where
- element from the other 128-bit lane is needed, otherwise
- will shuffle in the requested value. */
- emit_insn (gen_avx2_pshufbv32qi3 (t3, op0, t3));
- emit_insn (gen_avx2_pshufbv32qi3 (t1, op0, t1));
- /* For t3 the 128-bit lanes are swapped again. */
- emit_insn (gen_avx2_permv4di_1 (gen_lowpart (V4DImode, t3),
- gen_lowpart (V4DImode, t3),
- const2_rtx, GEN_INT (3),
- const0_rtx, const1_rtx));
- /* And oring both together leads to the result. */
- emit_insn (gen_iorv32qi3 (target, t1, t3));
- return;
- }
-
- t4 = gen_reg_rtx (V32QImode);
- /* Similarly to the above one_operand_shuffle code,
- just for repeated twice for each operand. merge_two:
- code will merge the two results together. */
- emit_insn (gen_avx2_pshufbv32qi3 (t4, op0, t3));
- emit_insn (gen_avx2_pshufbv32qi3 (t3, op1, t3));
- emit_insn (gen_avx2_pshufbv32qi3 (t2, op0, t1));
- emit_insn (gen_avx2_pshufbv32qi3 (t1, op1, t1));
- emit_insn (gen_avx2_permv4di_1 (gen_lowpart (V4DImode, t4),
- gen_lowpart (V4DImode, t4),
- const2_rtx, GEN_INT (3),
- const0_rtx, const1_rtx));
- emit_insn (gen_avx2_permv4di_1 (gen_lowpart (V4DImode, t3),
- gen_lowpart (V4DImode, t3),
- const2_rtx, GEN_INT (3),
- const0_rtx, const1_rtx));
- emit_insn (gen_iorv32qi3 (t4, t2, t4));
- emit_insn (gen_iorv32qi3 (t3, t1, t3));
- t1 = t4;
- t2 = t3;
- goto merge_two;
-
- default:
- gcc_assert (GET_MODE_SIZE (mode) <= 16);
- break;
- }
- }
-
- if (TARGET_XOP)
- {
- /* The XOP VPPERM insn supports three inputs. By ignoring the
- one_operand_shuffle special case, we avoid creating another
- set of constant vectors in memory. */
- one_operand_shuffle = false;
-
- /* mask = mask & {2*w-1, ...} */
- vt = GEN_INT (2*w - 1);
- }
- else
- {
- /* mask = mask & {w-1, ...} */
- vt = GEN_INT (w - 1);
- }
-
- for (i = 0; i < w; i++)
- vec[i] = vt;
- vt = gen_rtx_CONST_VECTOR (maskmode, gen_rtvec_v (w, vec));
- mask = expand_simple_binop (maskmode, AND, mask, vt,
- NULL_RTX, 0, OPTAB_DIRECT);
-
- /* For non-QImode operations, convert the word permutation control
- into a byte permutation control. */
- if (mode != V16QImode)
- {
- mask = expand_simple_binop (maskmode, ASHIFT, mask,
- GEN_INT (exact_log2 (e)),
- NULL_RTX, 0, OPTAB_DIRECT);
-
- /* Convert mask to vector of chars. */
- mask = force_reg (V16QImode, gen_lowpart (V16QImode, mask));
-
- /* Replicate each of the input bytes into byte positions:
- (v2di) --> {0,0,0,0,0,0,0,0, 8,8,8,8,8,8,8,8}
- (v4si) --> {0,0,0,0, 4,4,4,4, 8,8,8,8, 12,12,12,12}
- (v8hi) --> {0,0, 2,2, 4,4, 6,6, ...}. */
- for (i = 0; i < 16; ++i)
- vec[i] = GEN_INT (i/e * e);
- vt = gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, vec));
- vt = validize_mem (force_const_mem (V16QImode, vt));
- if (TARGET_XOP)
- emit_insn (gen_xop_pperm (mask, mask, mask, vt));
- else
- emit_insn (gen_ssse3_pshufbv16qi3 (mask, mask, vt));
-
- /* Convert it into the byte positions by doing
- mask = mask + {0,1,..,16/w, 0,1,..,16/w, ...} */
- for (i = 0; i < 16; ++i)
- vec[i] = GEN_INT (i % e);
- vt = gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, vec));
- vt = validize_mem (force_const_mem (V16QImode, vt));
- emit_insn (gen_addv16qi3 (mask, mask, vt));
- }
-
- /* The actual shuffle operations all operate on V16QImode. */
- op0 = gen_lowpart (V16QImode, op0);
- op1 = gen_lowpart (V16QImode, op1);
- target = gen_lowpart (V16QImode, target);
-
- if (TARGET_XOP)
- {
- emit_insn (gen_xop_pperm (target, op0, op1, mask));
- }
- else if (one_operand_shuffle)
- {
- emit_insn (gen_ssse3_pshufbv16qi3 (target, op0, mask));
- }
- else
- {
- rtx xops[6];
- bool ok;
-
- /* Shuffle the two input vectors independently. */
- t1 = gen_reg_rtx (V16QImode);
- t2 = gen_reg_rtx (V16QImode);
- emit_insn (gen_ssse3_pshufbv16qi3 (t1, op0, mask));
- emit_insn (gen_ssse3_pshufbv16qi3 (t2, op1, mask));
-
- merge_two:
- /* Then merge them together. The key is whether any given control
- element contained a bit set that indicates the second word. */
- mask = operands[3];
- vt = GEN_INT (w);
- if (maskmode == V2DImode && !TARGET_SSE4_1)
- {
- /* Without SSE4.1, we don't have V2DImode EQ. Perform one
- more shuffle to convert the V2DI input mask into a V4SI
- input mask. At which point the masking that expand_int_vcond
- will work as desired. */
- rtx t3 = gen_reg_rtx (V4SImode);
- emit_insn (gen_sse2_pshufd_1 (t3, gen_lowpart (V4SImode, mask),
- const0_rtx, const0_rtx,
- const2_rtx, const2_rtx));
- mask = t3;
- maskmode = V4SImode;
- e = w = 4;
- }
-
- for (i = 0; i < w; i++)
- vec[i] = vt;
- vt = gen_rtx_CONST_VECTOR (maskmode, gen_rtvec_v (w, vec));
- vt = force_reg (maskmode, vt);
- mask = expand_simple_binop (maskmode, AND, mask, vt,
- NULL_RTX, 0, OPTAB_DIRECT);
-
- xops[0] = gen_lowpart (mode, operands[0]);
- xops[1] = gen_lowpart (mode, t2);
- xops[2] = gen_lowpart (mode, t1);
- xops[3] = gen_rtx_EQ (maskmode, mask, vt);
- xops[4] = mask;
- xops[5] = vt;
- ok = ix86_expand_int_vcond (xops);
- gcc_assert (ok);
- }
-}
-
-/* Unpack OP[1] into the next wider integer vector type. UNSIGNED_P is
- true if we should do zero extension, else sign extension. HIGH_P is
- true if we want the N/2 high elements, else the low elements. */
-
-void
-ix86_expand_sse_unpack (rtx dest, rtx src, bool unsigned_p, bool high_p)
-{
- enum machine_mode imode = GET_MODE (src);
- rtx tmp;
-
- if (TARGET_SSE4_1)
- {
- rtx (*unpack)(rtx, rtx);
- rtx (*extract)(rtx, rtx) = NULL;
- enum machine_mode halfmode = BLKmode;
-
- switch (imode)
- {
- case V32QImode:
- if (unsigned_p)
- unpack = gen_avx2_zero_extendv16qiv16hi2;
- else
- unpack = gen_avx2_sign_extendv16qiv16hi2;
- halfmode = V16QImode;
- extract
- = high_p ? gen_vec_extract_hi_v32qi : gen_vec_extract_lo_v32qi;
- break;
- case V16HImode:
- if (unsigned_p)
- unpack = gen_avx2_zero_extendv8hiv8si2;
- else
- unpack = gen_avx2_sign_extendv8hiv8si2;
- halfmode = V8HImode;
- extract
- = high_p ? gen_vec_extract_hi_v16hi : gen_vec_extract_lo_v16hi;
- break;
- case V8SImode:
- if (unsigned_p)
- unpack = gen_avx2_zero_extendv4siv4di2;
- else
- unpack = gen_avx2_sign_extendv4siv4di2;
- halfmode = V4SImode;
- extract
- = high_p ? gen_vec_extract_hi_v8si : gen_vec_extract_lo_v8si;
- break;
- case V16QImode:
- if (unsigned_p)
- unpack = gen_sse4_1_zero_extendv8qiv8hi2;
- else
- unpack = gen_sse4_1_sign_extendv8qiv8hi2;
- break;
- case V8HImode:
- if (unsigned_p)
- unpack = gen_sse4_1_zero_extendv4hiv4si2;
- else
- unpack = gen_sse4_1_sign_extendv4hiv4si2;
- break;
- case V4SImode:
- if (unsigned_p)
- unpack = gen_sse4_1_zero_extendv2siv2di2;
- else
- unpack = gen_sse4_1_sign_extendv2siv2di2;
- break;
- default:
- gcc_unreachable ();
- }
-
- if (GET_MODE_SIZE (imode) == 32)
- {
- tmp = gen_reg_rtx (halfmode);
- emit_insn (extract (tmp, src));
- }
- else if (high_p)
- {
- /* Shift higher 8 bytes to lower 8 bytes. */
- tmp = gen_reg_rtx (imode);
- emit_insn (gen_sse2_lshrv1ti3 (gen_lowpart (V1TImode, tmp),
- gen_lowpart (V1TImode, src),
- GEN_INT (64)));
- }
- else
- tmp = src;
-
- emit_insn (unpack (dest, tmp));
- }
- else
- {
- rtx (*unpack)(rtx, rtx, rtx);
-
- switch (imode)
- {
- case V16QImode:
- if (high_p)
- unpack = gen_vec_interleave_highv16qi;
- else
- unpack = gen_vec_interleave_lowv16qi;
- break;
- case V8HImode:
- if (high_p)
- unpack = gen_vec_interleave_highv8hi;
- else
- unpack = gen_vec_interleave_lowv8hi;
- break;
- case V4SImode:
- if (high_p)
- unpack = gen_vec_interleave_highv4si;
- else
- unpack = gen_vec_interleave_lowv4si;
- break;
- default:
- gcc_unreachable ();
- }
-
- if (unsigned_p)
- tmp = force_reg (imode, CONST0_RTX (imode));
- else
- tmp = ix86_expand_sse_cmp (gen_reg_rtx (imode), GT, CONST0_RTX (imode),
- src, pc_rtx, pc_rtx);
-
- emit_insn (unpack (gen_lowpart (imode, dest), src, tmp));
- }
-}
-
-/* Expand conditional increment or decrement using adb/sbb instructions.
- The default case using setcc followed by the conditional move can be
- done by generic code. */
-bool
-ix86_expand_int_addcc (rtx operands[])
-{
- enum rtx_code code = GET_CODE (operands[1]);
- rtx flags;
- rtx (*insn)(rtx, rtx, rtx, rtx, rtx);
- rtx compare_op;
- rtx val = const0_rtx;
- bool fpcmp = false;
- enum machine_mode mode;
- rtx op0 = XEXP (operands[1], 0);
- rtx op1 = XEXP (operands[1], 1);
-
- if (operands[3] != const1_rtx
- && operands[3] != constm1_rtx)
- return false;
- if (!ix86_expand_carry_flag_compare (code, op0, op1, &compare_op))
- return false;
- code = GET_CODE (compare_op);
-
- flags = XEXP (compare_op, 0);
-
- if (GET_MODE (flags) == CCFPmode
- || GET_MODE (flags) == CCFPUmode)
- {
- fpcmp = true;
- code = ix86_fp_compare_code_to_integer (code);
- }
-
- if (code != LTU)
- {
- val = constm1_rtx;
- if (fpcmp)
- PUT_CODE (compare_op,
- reverse_condition_maybe_unordered
- (GET_CODE (compare_op)));
- else
- PUT_CODE (compare_op, reverse_condition (GET_CODE (compare_op)));
- }
-
- mode = GET_MODE (operands[0]);
-
- /* Construct either adc or sbb insn. */
- if ((code == LTU) == (operands[3] == constm1_rtx))
- {
- switch (mode)
- {
- case QImode:
- insn = gen_subqi3_carry;
- break;
- case HImode:
- insn = gen_subhi3_carry;
- break;
- case SImode:
- insn = gen_subsi3_carry;
- break;
- case DImode:
- insn = gen_subdi3_carry;
- break;
- default:
- gcc_unreachable ();
- }
- }
- else
- {
- switch (mode)
- {
- case QImode:
- insn = gen_addqi3_carry;
- break;
- case HImode:
- insn = gen_addhi3_carry;
- break;
- case SImode:
- insn = gen_addsi3_carry;
- break;
- case DImode:
- insn = gen_adddi3_carry;
- break;
- default:
- gcc_unreachable ();
- }
- }
- emit_insn (insn (operands[0], operands[2], val, flags, compare_op));
-
- return true;
-}
-
-
-/* Split operands 0 and 1 into half-mode parts. Similar to split_double_mode,
- but works for floating pointer parameters and nonoffsetable memories.
- For pushes, it returns just stack offsets; the values will be saved
- in the right order. Maximally three parts are generated. */
-
-static int
-ix86_split_to_parts (rtx operand, rtx *parts, enum machine_mode mode)
-{
- int size;
-
- if (!TARGET_64BIT)
- size = mode==XFmode ? 3 : GET_MODE_SIZE (mode) / 4;
- else
- size = (GET_MODE_SIZE (mode) + 4) / 8;
-
- gcc_assert (!REG_P (operand) || !MMX_REGNO_P (REGNO (operand)));
- gcc_assert (size >= 2 && size <= 4);
-
- /* Optimize constant pool reference to immediates. This is used by fp
- moves, that force all constants to memory to allow combining. */
- if (MEM_P (operand) && MEM_READONLY_P (operand))
- {
- rtx tmp = maybe_get_pool_constant (operand);
- if (tmp)
- operand = tmp;
- }
-
- if (MEM_P (operand) && !offsettable_memref_p (operand))
- {
- /* The only non-offsetable memories we handle are pushes. */
- int ok = push_operand (operand, VOIDmode);
-
- gcc_assert (ok);
-
- operand = copy_rtx (operand);
- PUT_MODE (operand, word_mode);
- parts[0] = parts[1] = parts[2] = parts[3] = operand;
- return size;
- }
-
- if (GET_CODE (operand) == CONST_VECTOR)
- {
- enum machine_mode imode = int_mode_for_mode (mode);
- /* Caution: if we looked through a constant pool memory above,
- the operand may actually have a different mode now. That's
- ok, since we want to pun this all the way back to an integer. */
- operand = simplify_subreg (imode, operand, GET_MODE (operand), 0);
- gcc_assert (operand != NULL);
- mode = imode;
- }
-
- if (!TARGET_64BIT)
- {
- if (mode == DImode)
- split_double_mode (mode, &operand, 1, &parts[0], &parts[1]);
- else
- {
- int i;
-
- if (REG_P (operand))
- {
- gcc_assert (reload_completed);
- for (i = 0; i < size; i++)
- parts[i] = gen_rtx_REG (SImode, REGNO (operand) + i);
- }
- else if (offsettable_memref_p (operand))
- {
- operand = adjust_address (operand, SImode, 0);
- parts[0] = operand;
- for (i = 1; i < size; i++)
- parts[i] = adjust_address (operand, SImode, 4 * i);
- }
- else if (GET_CODE (operand) == CONST_DOUBLE)
- {
- REAL_VALUE_TYPE r;
- long l[4];
-
- REAL_VALUE_FROM_CONST_DOUBLE (r, operand);
- switch (mode)
- {
- case TFmode:
- real_to_target (l, &r, mode);
- parts[3] = gen_int_mode (l[3], SImode);
- parts[2] = gen_int_mode (l[2], SImode);
- break;
- case XFmode:
- /* We can't use REAL_VALUE_TO_TARGET_LONG_DOUBLE since
- long double may not be 80-bit. */
- real_to_target (l, &r, mode);
- parts[2] = gen_int_mode (l[2], SImode);
- break;
- case DFmode:
- REAL_VALUE_TO_TARGET_DOUBLE (r, l);
- break;
- default:
- gcc_unreachable ();
- }
- parts[1] = gen_int_mode (l[1], SImode);
- parts[0] = gen_int_mode (l[0], SImode);
- }
- else
- gcc_unreachable ();
- }
- }
- else
- {
- if (mode == TImode)
- split_double_mode (mode, &operand, 1, &parts[0], &parts[1]);
- if (mode == XFmode || mode == TFmode)
- {
- enum machine_mode upper_mode = mode==XFmode ? SImode : DImode;
- if (REG_P (operand))
- {
- gcc_assert (reload_completed);
- parts[0] = gen_rtx_REG (DImode, REGNO (operand) + 0);
- parts[1] = gen_rtx_REG (upper_mode, REGNO (operand) + 1);
- }
- else if (offsettable_memref_p (operand))
- {
- operand = adjust_address (operand, DImode, 0);
- parts[0] = operand;
- parts[1] = adjust_address (operand, upper_mode, 8);
- }
- else if (GET_CODE (operand) == CONST_DOUBLE)
- {
- REAL_VALUE_TYPE r;
- long l[4];
-
- REAL_VALUE_FROM_CONST_DOUBLE (r, operand);
- real_to_target (l, &r, mode);
-
- /* Do not use shift by 32 to avoid warning on 32bit systems. */
- if (HOST_BITS_PER_WIDE_INT >= 64)
- parts[0]
- = gen_int_mode
- ((l[0] & (((HOST_WIDE_INT) 2 << 31) - 1))
- + ((((HOST_WIDE_INT) l[1]) << 31) << 1),
- DImode);
- else
- parts[0] = immed_double_const (l[0], l[1], DImode);
-
- if (upper_mode == SImode)
- parts[1] = gen_int_mode (l[2], SImode);
- else if (HOST_BITS_PER_WIDE_INT >= 64)
- parts[1]
- = gen_int_mode
- ((l[2] & (((HOST_WIDE_INT) 2 << 31) - 1))
- + ((((HOST_WIDE_INT) l[3]) << 31) << 1),
- DImode);
- else
- parts[1] = immed_double_const (l[2], l[3], DImode);
- }
- else
- gcc_unreachable ();
- }
- }
-
- return size;
-}
-
-/* Emit insns to perform a move or push of DI, DF, XF, and TF values.
- Return false when normal moves are needed; true when all required
- insns have been emitted. Operands 2-4 contain the input values
- int the correct order; operands 5-7 contain the output values. */
-
-void
-ix86_split_long_move (rtx operands[])
-{
- rtx part[2][4];
- int nparts, i, j;
- int push = 0;
- int collisions = 0;
- enum machine_mode mode = GET_MODE (operands[0]);
- bool collisionparts[4];
-
- /* The DFmode expanders may ask us to move double.
- For 64bit target this is single move. By hiding the fact
- here we simplify i386.md splitters. */
- if (TARGET_64BIT && GET_MODE_SIZE (GET_MODE (operands[0])) == 8)
- {
- /* Optimize constant pool reference to immediates. This is used by
- fp moves, that force all constants to memory to allow combining. */
-
- if (MEM_P (operands[1])
- && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
- && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0)))
- operands[1] = get_pool_constant (XEXP (operands[1], 0));
- if (push_operand (operands[0], VOIDmode))
- {
- operands[0] = copy_rtx (operands[0]);
- PUT_MODE (operands[0], word_mode);
- }
- else
- operands[0] = gen_lowpart (DImode, operands[0]);
- operands[1] = gen_lowpart (DImode, operands[1]);
- emit_move_insn (operands[0], operands[1]);
- return;
- }
-
- /* The only non-offsettable memory we handle is push. */
- if (push_operand (operands[0], VOIDmode))
- push = 1;
- else
- gcc_assert (!MEM_P (operands[0])
- || offsettable_memref_p (operands[0]));
-
- nparts = ix86_split_to_parts (operands[1], part[1], GET_MODE (operands[0]));
- ix86_split_to_parts (operands[0], part[0], GET_MODE (operands[0]));
-
- /* When emitting push, take care for source operands on the stack. */
- if (push && MEM_P (operands[1])
- && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
- {
- rtx src_base = XEXP (part[1][nparts - 1], 0);
-
- /* Compensate for the stack decrement by 4. */
- if (!TARGET_64BIT && nparts == 3
- && mode == XFmode && TARGET_128BIT_LONG_DOUBLE)
- src_base = plus_constant (Pmode, src_base, 4);
-
- /* src_base refers to the stack pointer and is
- automatically decreased by emitted push. */
- for (i = 0; i < nparts; i++)
- part[1][i] = change_address (part[1][i],
- GET_MODE (part[1][i]), src_base);
- }
-
- /* We need to do copy in the right order in case an address register
- of the source overlaps the destination. */
- if (REG_P (part[0][0]) && MEM_P (part[1][0]))
- {
- rtx tmp;
-
- for (i = 0; i < nparts; i++)
- {
- collisionparts[i]
- = reg_overlap_mentioned_p (part[0][i], XEXP (part[1][0], 0));
- if (collisionparts[i])
- collisions++;
- }
-
- /* Collision in the middle part can be handled by reordering. */
- if (collisions == 1 && nparts == 3 && collisionparts [1])
- {
- tmp = part[0][1]; part[0][1] = part[0][2]; part[0][2] = tmp;
- tmp = part[1][1]; part[1][1] = part[1][2]; part[1][2] = tmp;
- }
- else if (collisions == 1
- && nparts == 4
- && (collisionparts [1] || collisionparts [2]))
- {
- if (collisionparts [1])
- {
- tmp = part[0][1]; part[0][1] = part[0][2]; part[0][2] = tmp;
- tmp = part[1][1]; part[1][1] = part[1][2]; part[1][2] = tmp;
- }
- else
- {
- tmp = part[0][2]; part[0][2] = part[0][3]; part[0][3] = tmp;
- tmp = part[1][2]; part[1][2] = part[1][3]; part[1][3] = tmp;
- }
- }
-
- /* If there are more collisions, we can't handle it by reordering.
- Do an lea to the last part and use only one colliding move. */
- else if (collisions > 1)
- {
- rtx base;
-
- collisions = 1;
-
- base = part[0][nparts - 1];
-
- /* Handle the case when the last part isn't valid for lea.
- Happens in 64-bit mode storing the 12-byte XFmode. */
- if (GET_MODE (base) != Pmode)
- base = gen_rtx_REG (Pmode, REGNO (base));
-
- emit_insn (gen_rtx_SET (VOIDmode, base, XEXP (part[1][0], 0)));
- part[1][0] = replace_equiv_address (part[1][0], base);
- for (i = 1; i < nparts; i++)
- {
- tmp = plus_constant (Pmode, base, UNITS_PER_WORD * i);
- part[1][i] = replace_equiv_address (part[1][i], tmp);
- }
- }
- }
-
- if (push)
- {
- if (!TARGET_64BIT)
- {
- if (nparts == 3)
- {
- if (TARGET_128BIT_LONG_DOUBLE && mode == XFmode)
- emit_insn (ix86_gen_add3 (stack_pointer_rtx,
- stack_pointer_rtx, GEN_INT (-4)));
- emit_move_insn (part[0][2], part[1][2]);
- }
- else if (nparts == 4)
- {
- emit_move_insn (part[0][3], part[1][3]);
- emit_move_insn (part[0][2], part[1][2]);
- }
- }
- else
- {
- /* In 64bit mode we don't have 32bit push available. In case this is
- register, it is OK - we will just use larger counterpart. We also
- retype memory - these comes from attempt to avoid REX prefix on
- moving of second half of TFmode value. */
- if (GET_MODE (part[1][1]) == SImode)
- {
- switch (GET_CODE (part[1][1]))
- {
- case MEM:
- part[1][1] = adjust_address (part[1][1], DImode, 0);
- break;
-
- case REG:
- part[1][1] = gen_rtx_REG (DImode, REGNO (part[1][1]));
- break;
-
- default:
- gcc_unreachable ();
- }
-
- if (GET_MODE (part[1][0]) == SImode)
- part[1][0] = part[1][1];
- }
- }
- emit_move_insn (part[0][1], part[1][1]);
- emit_move_insn (part[0][0], part[1][0]);
- return;
- }
-
- /* Choose correct order to not overwrite the source before it is copied. */
- if ((REG_P (part[0][0])
- && REG_P (part[1][1])
- && (REGNO (part[0][0]) == REGNO (part[1][1])
- || (nparts == 3
- && REGNO (part[0][0]) == REGNO (part[1][2]))
- || (nparts == 4
- && REGNO (part[0][0]) == REGNO (part[1][3]))))
- || (collisions > 0
- && reg_overlap_mentioned_p (part[0][0], XEXP (part[1][0], 0))))
- {
- for (i = 0, j = nparts - 1; i < nparts; i++, j--)
- {
- operands[2 + i] = part[0][j];
- operands[6 + i] = part[1][j];
- }
- }
- else
- {
- for (i = 0; i < nparts; i++)
- {
- operands[2 + i] = part[0][i];
- operands[6 + i] = part[1][i];
- }
- }
-
- /* If optimizing for size, attempt to locally unCSE nonzero constants. */
- if (optimize_insn_for_size_p ())
- {
- for (j = 0; j < nparts - 1; j++)
- if (CONST_INT_P (operands[6 + j])
- && operands[6 + j] != const0_rtx
- && REG_P (operands[2 + j]))
- for (i = j; i < nparts - 1; i++)
- if (CONST_INT_P (operands[7 + i])
- && INTVAL (operands[7 + i]) == INTVAL (operands[6 + j]))
- operands[7 + i] = operands[2 + j];
- }
-
- for (i = 0; i < nparts; i++)
- emit_move_insn (operands[2 + i], operands[6 + i]);
-
- return;
-}
-
-/* Helper function of ix86_split_ashl used to generate an SImode/DImode
- left shift by a constant, either using a single shift or
- a sequence of add instructions. */
-
-static void
-ix86_expand_ashl_const (rtx operand, int count, enum machine_mode mode)
-{
- rtx (*insn)(rtx, rtx, rtx);
-
- if (count == 1
- || (count * ix86_cost->add <= ix86_cost->shift_const
- && !optimize_insn_for_size_p ()))
- {
- insn = mode == DImode ? gen_addsi3 : gen_adddi3;
- while (count-- > 0)
- emit_insn (insn (operand, operand, operand));
- }
- else
- {
- insn = mode == DImode ? gen_ashlsi3 : gen_ashldi3;
- emit_insn (insn (operand, operand, GEN_INT (count)));
- }
-}
-
-void
-ix86_split_ashl (rtx *operands, rtx scratch, enum machine_mode mode)
-{
- rtx (*gen_ashl3)(rtx, rtx, rtx);
- rtx (*gen_shld)(rtx, rtx, rtx);
- int half_width = GET_MODE_BITSIZE (mode) >> 1;
-
- rtx low[2], high[2];
- int count;
-
- if (CONST_INT_P (operands[2]))
- {
- split_double_mode (mode, operands, 2, low, high);
- count = INTVAL (operands[2]) & (GET_MODE_BITSIZE (mode) - 1);
-
- if (count >= half_width)
- {
- emit_move_insn (high[0], low[1]);
- emit_move_insn (low[0], const0_rtx);
-
- if (count > half_width)
- ix86_expand_ashl_const (high[0], count - half_width, mode);
- }
- else
- {
- gen_shld = mode == DImode ? gen_x86_shld : gen_x86_64_shld;
-
- if (!rtx_equal_p (operands[0], operands[1]))
- emit_move_insn (operands[0], operands[1]);
-
- emit_insn (gen_shld (high[0], low[0], GEN_INT (count)));
- ix86_expand_ashl_const (low[0], count, mode);
- }
- return;
- }
-
- split_double_mode (mode, operands, 1, low, high);
-
- gen_ashl3 = mode == DImode ? gen_ashlsi3 : gen_ashldi3;
-
- if (operands[1] == const1_rtx)
- {
- /* Assuming we've chosen a QImode capable registers, then 1 << N
- can be done with two 32/64-bit shifts, no branches, no cmoves. */
- if (ANY_QI_REG_P (low[0]) && ANY_QI_REG_P (high[0]))
- {
- rtx s, d, flags = gen_rtx_REG (CCZmode, FLAGS_REG);
-
- ix86_expand_clear (low[0]);
- ix86_expand_clear (high[0]);
- emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (half_width)));
-
- d = gen_lowpart (QImode, low[0]);
- d = gen_rtx_STRICT_LOW_PART (VOIDmode, d);
- s = gen_rtx_EQ (QImode, flags, const0_rtx);
- emit_insn (gen_rtx_SET (VOIDmode, d, s));
-
- d = gen_lowpart (QImode, high[0]);
- d = gen_rtx_STRICT_LOW_PART (VOIDmode, d);
- s = gen_rtx_NE (QImode, flags, const0_rtx);
- emit_insn (gen_rtx_SET (VOIDmode, d, s));
- }
-
- /* Otherwise, we can get the same results by manually performing
- a bit extract operation on bit 5/6, and then performing the two
- shifts. The two methods of getting 0/1 into low/high are exactly
- the same size. Avoiding the shift in the bit extract case helps
- pentium4 a bit; no one else seems to care much either way. */
- else
- {
- enum machine_mode half_mode;
- rtx (*gen_lshr3)(rtx, rtx, rtx);
- rtx (*gen_and3)(rtx, rtx, rtx);
- rtx (*gen_xor3)(rtx, rtx, rtx);
- HOST_WIDE_INT bits;
- rtx x;
-
- if (mode == DImode)
- {
- half_mode = SImode;
- gen_lshr3 = gen_lshrsi3;
- gen_and3 = gen_andsi3;
- gen_xor3 = gen_xorsi3;
- bits = 5;
- }
- else
- {
- half_mode = DImode;
- gen_lshr3 = gen_lshrdi3;
- gen_and3 = gen_anddi3;
- gen_xor3 = gen_xordi3;
- bits = 6;
- }
-
- if (TARGET_PARTIAL_REG_STALL && !optimize_insn_for_size_p ())
- x = gen_rtx_ZERO_EXTEND (half_mode, operands[2]);
- else
- x = gen_lowpart (half_mode, operands[2]);
- emit_insn (gen_rtx_SET (VOIDmode, high[0], x));
-
- emit_insn (gen_lshr3 (high[0], high[0], GEN_INT (bits)));
- emit_insn (gen_and3 (high[0], high[0], const1_rtx));
- emit_move_insn (low[0], high[0]);
- emit_insn (gen_xor3 (low[0], low[0], const1_rtx));
- }
-
- emit_insn (gen_ashl3 (low[0], low[0], operands[2]));
- emit_insn (gen_ashl3 (high[0], high[0], operands[2]));
- return;
- }
-
- if (operands[1] == constm1_rtx)
- {
- /* For -1 << N, we can avoid the shld instruction, because we
- know that we're shifting 0...31/63 ones into a -1. */
- emit_move_insn (low[0], constm1_rtx);
- if (optimize_insn_for_size_p ())
- emit_move_insn (high[0], low[0]);
- else
- emit_move_insn (high[0], constm1_rtx);
- }
- else
- {
- gen_shld = mode == DImode ? gen_x86_shld : gen_x86_64_shld;
-
- if (!rtx_equal_p (operands[0], operands[1]))
- emit_move_insn (operands[0], operands[1]);
-
- split_double_mode (mode, operands, 1, low, high);
- emit_insn (gen_shld (high[0], low[0], operands[2]));
- }
-
- emit_insn (gen_ashl3 (low[0], low[0], operands[2]));
-
- if (TARGET_CMOVE && scratch)
- {
- rtx (*gen_x86_shift_adj_1)(rtx, rtx, rtx, rtx)
- = mode == DImode ? gen_x86_shiftsi_adj_1 : gen_x86_shiftdi_adj_1;
-
- ix86_expand_clear (scratch);
- emit_insn (gen_x86_shift_adj_1 (high[0], low[0], operands[2], scratch));
- }
- else
- {
- rtx (*gen_x86_shift_adj_2)(rtx, rtx, rtx)
- = mode == DImode ? gen_x86_shiftsi_adj_2 : gen_x86_shiftdi_adj_2;
-
- emit_insn (gen_x86_shift_adj_2 (high[0], low[0], operands[2]));
- }
-}
-
-void
-ix86_split_ashr (rtx *operands, rtx scratch, enum machine_mode mode)
-{
- rtx (*gen_ashr3)(rtx, rtx, rtx)
- = mode == DImode ? gen_ashrsi3 : gen_ashrdi3;
- rtx (*gen_shrd)(rtx, rtx, rtx);
- int half_width = GET_MODE_BITSIZE (mode) >> 1;
-
- rtx low[2], high[2];
- int count;
-
- if (CONST_INT_P (operands[2]))
- {
- split_double_mode (mode, operands, 2, low, high);
- count = INTVAL (operands[2]) & (GET_MODE_BITSIZE (mode) - 1);
-
- if (count == GET_MODE_BITSIZE (mode) - 1)
- {
- emit_move_insn (high[0], high[1]);
- emit_insn (gen_ashr3 (high[0], high[0],
- GEN_INT (half_width - 1)));
- emit_move_insn (low[0], high[0]);
-
- }
- else if (count >= half_width)
- {
- emit_move_insn (low[0], high[1]);
- emit_move_insn (high[0], low[0]);
- emit_insn (gen_ashr3 (high[0], high[0],
- GEN_INT (half_width - 1)));
-
- if (count > half_width)
- emit_insn (gen_ashr3 (low[0], low[0],
- GEN_INT (count - half_width)));
- }
- else
- {
- gen_shrd = mode == DImode ? gen_x86_shrd : gen_x86_64_shrd;
-
- if (!rtx_equal_p (operands[0], operands[1]))
- emit_move_insn (operands[0], operands[1]);
-
- emit_insn (gen_shrd (low[0], high[0], GEN_INT (count)));
- emit_insn (gen_ashr3 (high[0], high[0], GEN_INT (count)));
- }
- }
- else
- {
- gen_shrd = mode == DImode ? gen_x86_shrd : gen_x86_64_shrd;
-
- if (!rtx_equal_p (operands[0], operands[1]))
- emit_move_insn (operands[0], operands[1]);
-
- split_double_mode (mode, operands, 1, low, high);
-
- emit_insn (gen_shrd (low[0], high[0], operands[2]));
- emit_insn (gen_ashr3 (high[0], high[0], operands[2]));
-
- if (TARGET_CMOVE && scratch)
- {
- rtx (*gen_x86_shift_adj_1)(rtx, rtx, rtx, rtx)
- = mode == DImode ? gen_x86_shiftsi_adj_1 : gen_x86_shiftdi_adj_1;
-
- emit_move_insn (scratch, high[0]);
- emit_insn (gen_ashr3 (scratch, scratch,
- GEN_INT (half_width - 1)));
- emit_insn (gen_x86_shift_adj_1 (low[0], high[0], operands[2],
- scratch));
- }
- else
- {
- rtx (*gen_x86_shift_adj_3)(rtx, rtx, rtx)
- = mode == DImode ? gen_x86_shiftsi_adj_3 : gen_x86_shiftdi_adj_3;
-
- emit_insn (gen_x86_shift_adj_3 (low[0], high[0], operands[2]));
- }
- }
-}
-
-void
-ix86_split_lshr (rtx *operands, rtx scratch, enum machine_mode mode)
-{
- rtx (*gen_lshr3)(rtx, rtx, rtx)
- = mode == DImode ? gen_lshrsi3 : gen_lshrdi3;
- rtx (*gen_shrd)(rtx, rtx, rtx);
- int half_width = GET_MODE_BITSIZE (mode) >> 1;
-
- rtx low[2], high[2];
- int count;
-
- if (CONST_INT_P (operands[2]))
- {
- split_double_mode (mode, operands, 2, low, high);
- count = INTVAL (operands[2]) & (GET_MODE_BITSIZE (mode) - 1);
-
- if (count >= half_width)
- {
- emit_move_insn (low[0], high[1]);
- ix86_expand_clear (high[0]);
-
- if (count > half_width)
- emit_insn (gen_lshr3 (low[0], low[0],
- GEN_INT (count - half_width)));
- }
- else
- {
- gen_shrd = mode == DImode ? gen_x86_shrd : gen_x86_64_shrd;
-
- if (!rtx_equal_p (operands[0], operands[1]))
- emit_move_insn (operands[0], operands[1]);
-
- emit_insn (gen_shrd (low[0], high[0], GEN_INT (count)));
- emit_insn (gen_lshr3 (high[0], high[0], GEN_INT (count)));
- }
- }
- else
- {
- gen_shrd = mode == DImode ? gen_x86_shrd : gen_x86_64_shrd;
-
- if (!rtx_equal_p (operands[0], operands[1]))
- emit_move_insn (operands[0], operands[1]);
-
- split_double_mode (mode, operands, 1, low, high);
-
- emit_insn (gen_shrd (low[0], high[0], operands[2]));
- emit_insn (gen_lshr3 (high[0], high[0], operands[2]));
-
- if (TARGET_CMOVE && scratch)
- {
- rtx (*gen_x86_shift_adj_1)(rtx, rtx, rtx, rtx)
- = mode == DImode ? gen_x86_shiftsi_adj_1 : gen_x86_shiftdi_adj_1;
-
- ix86_expand_clear (scratch);
- emit_insn (gen_x86_shift_adj_1 (low[0], high[0], operands[2],
- scratch));
- }
- else
- {
- rtx (*gen_x86_shift_adj_2)(rtx, rtx, rtx)
- = mode == DImode ? gen_x86_shiftsi_adj_2 : gen_x86_shiftdi_adj_2;
-
- emit_insn (gen_x86_shift_adj_2 (low[0], high[0], operands[2]));
- }
- }
-}
-
-/* Predict just emitted jump instruction to be taken with probability PROB. */
-static void
-predict_jump (int prob)
-{
- rtx insn = get_last_insn ();
- gcc_assert (JUMP_P (insn));
- add_reg_note (insn, REG_BR_PROB, GEN_INT (prob));
-}
-
-/* Helper function for the string operations below. Dest VARIABLE whether
- it is aligned to VALUE bytes. If true, jump to the label. */
-static rtx
-ix86_expand_aligntest (rtx variable, int value, bool epilogue)
-{
- rtx label = gen_label_rtx ();
- rtx tmpcount = gen_reg_rtx (GET_MODE (variable));
- if (GET_MODE (variable) == DImode)
- emit_insn (gen_anddi3 (tmpcount, variable, GEN_INT (value)));
- else
- emit_insn (gen_andsi3 (tmpcount, variable, GEN_INT (value)));
- emit_cmp_and_jump_insns (tmpcount, const0_rtx, EQ, 0, GET_MODE (variable),
- 1, label);
- if (epilogue)
- predict_jump (REG_BR_PROB_BASE * 50 / 100);
- else
- predict_jump (REG_BR_PROB_BASE * 90 / 100);
- return label;
-}
-
-/* Adjust COUNTER by the VALUE. */
-static void
-ix86_adjust_counter (rtx countreg, HOST_WIDE_INT value)
-{
- rtx (*gen_add)(rtx, rtx, rtx)
- = GET_MODE (countreg) == DImode ? gen_adddi3 : gen_addsi3;
-
- emit_insn (gen_add (countreg, countreg, GEN_INT (-value)));
-}
-
-/* Zero extend possibly SImode EXP to Pmode register. */
-rtx
-ix86_zero_extend_to_Pmode (rtx exp)
-{
- return force_reg (Pmode, convert_to_mode (Pmode, exp, 1));
-}
-
-/* Divide COUNTREG by SCALE. */
-static rtx
-scale_counter (rtx countreg, int scale)
-{
- rtx sc;
-
- if (scale == 1)
- return countreg;
- if (CONST_INT_P (countreg))
- return GEN_INT (INTVAL (countreg) / scale);
- gcc_assert (REG_P (countreg));
-
- sc = expand_simple_binop (GET_MODE (countreg), LSHIFTRT, countreg,
- GEN_INT (exact_log2 (scale)),
- NULL, 1, OPTAB_DIRECT);
- return sc;
-}
-
-/* Return mode for the memcpy/memset loop counter. Prefer SImode over
- DImode for constant loop counts. */
-
-static enum machine_mode
-counter_mode (rtx count_exp)
-{
- if (GET_MODE (count_exp) != VOIDmode)
- return GET_MODE (count_exp);
- if (!CONST_INT_P (count_exp))
- return Pmode;
- if (TARGET_64BIT && (INTVAL (count_exp) & ~0xffffffff))
- return DImode;
- return SImode;
-}
-
-/* When SRCPTR is non-NULL, output simple loop to move memory
- pointer to SRCPTR to DESTPTR via chunks of MODE unrolled UNROLL times,
- overall size is COUNT specified in bytes. When SRCPTR is NULL, output the
- equivalent loop to set memory by VALUE (supposed to be in MODE).
-
- The size is rounded down to whole number of chunk size moved at once.
- SRCMEM and DESTMEM provide MEMrtx to feed proper aliasing info. */
-
-
-static void
-expand_set_or_movmem_via_loop (rtx destmem, rtx srcmem,
- rtx destptr, rtx srcptr, rtx value,
- rtx count, enum machine_mode mode, int unroll,
- int expected_size)
-{
- rtx out_label, top_label, iter, tmp;
- enum machine_mode iter_mode = counter_mode (count);
- rtx piece_size = GEN_INT (GET_MODE_SIZE (mode) * unroll);
- rtx piece_size_mask = GEN_INT (~((GET_MODE_SIZE (mode) * unroll) - 1));
- rtx size;
- rtx x_addr;
- rtx y_addr;
- int i;
-
- top_label = gen_label_rtx ();
- out_label = gen_label_rtx ();
- iter = gen_reg_rtx (iter_mode);
-
- size = expand_simple_binop (iter_mode, AND, count, piece_size_mask,
- NULL, 1, OPTAB_DIRECT);
- /* Those two should combine. */
- if (piece_size == const1_rtx)
- {
- emit_cmp_and_jump_insns (size, const0_rtx, EQ, NULL_RTX, iter_mode,
- true, out_label);
- predict_jump (REG_BR_PROB_BASE * 10 / 100);
- }
- emit_move_insn (iter, const0_rtx);
-
- emit_label (top_label);
-
- tmp = convert_modes (Pmode, iter_mode, iter, true);
- x_addr = gen_rtx_PLUS (Pmode, destptr, tmp);
- destmem = change_address (destmem, mode, x_addr);
-
- if (srcmem)
- {
- y_addr = gen_rtx_PLUS (Pmode, srcptr, copy_rtx (tmp));
- srcmem = change_address (srcmem, mode, y_addr);
-
- /* When unrolling for chips that reorder memory reads and writes,
- we can save registers by using single temporary.
- Also using 4 temporaries is overkill in 32bit mode. */
- if (!TARGET_64BIT && 0)
- {
- for (i = 0; i < unroll; i++)
- {
- if (i)
- {
- destmem =
- adjust_address (copy_rtx (destmem), mode, GET_MODE_SIZE (mode));
- srcmem =
- adjust_address (copy_rtx (srcmem), mode, GET_MODE_SIZE (mode));
- }
- emit_move_insn (destmem, srcmem);
- }
- }
- else
- {
- rtx tmpreg[4];
- gcc_assert (unroll <= 4);
- for (i = 0; i < unroll; i++)
- {
- tmpreg[i] = gen_reg_rtx (mode);
- if (i)
- {
- srcmem =
- adjust_address (copy_rtx (srcmem), mode, GET_MODE_SIZE (mode));
- }
- emit_move_insn (tmpreg[i], srcmem);
- }
- for (i = 0; i < unroll; i++)
- {
- if (i)
- {
- destmem =
- adjust_address (copy_rtx (destmem), mode, GET_MODE_SIZE (mode));
- }
- emit_move_insn (destmem, tmpreg[i]);
- }
- }
- }
- else
- for (i = 0; i < unroll; i++)
- {
- if (i)
- destmem =
- adjust_address (copy_rtx (destmem), mode, GET_MODE_SIZE (mode));
- emit_move_insn (destmem, value);
- }
-
- tmp = expand_simple_binop (iter_mode, PLUS, iter, piece_size, iter,
- true, OPTAB_LIB_WIDEN);
- if (tmp != iter)
- emit_move_insn (iter, tmp);
-
- emit_cmp_and_jump_insns (iter, size, LT, NULL_RTX, iter_mode,
- true, top_label);
- if (expected_size != -1)
- {
- expected_size /= GET_MODE_SIZE (mode) * unroll;
- if (expected_size == 0)
- predict_jump (0);
- else if (expected_size > REG_BR_PROB_BASE)
- predict_jump (REG_BR_PROB_BASE - 1);
- else
- predict_jump (REG_BR_PROB_BASE - (REG_BR_PROB_BASE + expected_size / 2) / expected_size);
- }
- else
- predict_jump (REG_BR_PROB_BASE * 80 / 100);
- iter = ix86_zero_extend_to_Pmode (iter);
- tmp = expand_simple_binop (Pmode, PLUS, destptr, iter, destptr,
- true, OPTAB_LIB_WIDEN);
- if (tmp != destptr)
- emit_move_insn (destptr, tmp);
- if (srcptr)
- {
- tmp = expand_simple_binop (Pmode, PLUS, srcptr, iter, srcptr,
- true, OPTAB_LIB_WIDEN);
- if (tmp != srcptr)
- emit_move_insn (srcptr, tmp);
- }
- emit_label (out_label);
-}
-
-/* Output "rep; mov" instruction.
- Arguments have same meaning as for previous function */
-static void
-expand_movmem_via_rep_mov (rtx destmem, rtx srcmem,
- rtx destptr, rtx srcptr,
- rtx count,
- enum machine_mode mode)
-{
- rtx destexp;
- rtx srcexp;
- rtx countreg;
- HOST_WIDE_INT rounded_count;
-
- /* If the size is known, it is shorter to use rep movs. */
- if (mode == QImode && CONST_INT_P (count)
- && !(INTVAL (count) & 3))
- mode = SImode;
-
- if (destptr != XEXP (destmem, 0) || GET_MODE (destmem) != BLKmode)
- destmem = adjust_automodify_address_nv (destmem, BLKmode, destptr, 0);
- if (srcptr != XEXP (srcmem, 0) || GET_MODE (srcmem) != BLKmode)
- srcmem = adjust_automodify_address_nv (srcmem, BLKmode, srcptr, 0);
- countreg = ix86_zero_extend_to_Pmode (scale_counter (count, GET_MODE_SIZE (mode)));
- if (mode != QImode)
- {
- destexp = gen_rtx_ASHIFT (Pmode, countreg,
- GEN_INT (exact_log2 (GET_MODE_SIZE (mode))));
- destexp = gen_rtx_PLUS (Pmode, destexp, destptr);
- srcexp = gen_rtx_ASHIFT (Pmode, countreg,
- GEN_INT (exact_log2 (GET_MODE_SIZE (mode))));
- srcexp = gen_rtx_PLUS (Pmode, srcexp, srcptr);
- }
- else
- {
- destexp = gen_rtx_PLUS (Pmode, destptr, countreg);
- srcexp = gen_rtx_PLUS (Pmode, srcptr, countreg);
- }
- if (CONST_INT_P (count))
- {
- rounded_count = (INTVAL (count)
- & ~((HOST_WIDE_INT) GET_MODE_SIZE (mode) - 1));
- destmem = shallow_copy_rtx (destmem);
- srcmem = shallow_copy_rtx (srcmem);
- set_mem_size (destmem, rounded_count);
- set_mem_size (srcmem, rounded_count);
- }
- else
- {
- if (MEM_SIZE_KNOWN_P (destmem))
- clear_mem_size (destmem);
- if (MEM_SIZE_KNOWN_P (srcmem))
- clear_mem_size (srcmem);
- }
- emit_insn (gen_rep_mov (destptr, destmem, srcptr, srcmem, countreg,
- destexp, srcexp));
-}
-
-/* Output "rep; stos" instruction.
- Arguments have same meaning as for previous function */
-static void
-expand_setmem_via_rep_stos (rtx destmem, rtx destptr, rtx value,
- rtx count, enum machine_mode mode,
- rtx orig_value)
-{
- rtx destexp;
- rtx countreg;
- HOST_WIDE_INT rounded_count;
-
- if (destptr != XEXP (destmem, 0) || GET_MODE (destmem) != BLKmode)
- destmem = adjust_automodify_address_nv (destmem, BLKmode, destptr, 0);
- value = force_reg (mode, gen_lowpart (mode, value));
- countreg = ix86_zero_extend_to_Pmode (scale_counter (count, GET_MODE_SIZE (mode)));
- if (mode != QImode)
- {
- destexp = gen_rtx_ASHIFT (Pmode, countreg,
- GEN_INT (exact_log2 (GET_MODE_SIZE (mode))));
- destexp = gen_rtx_PLUS (Pmode, destexp, destptr);
- }
- else
- destexp = gen_rtx_PLUS (Pmode, destptr, countreg);
- if (orig_value == const0_rtx && CONST_INT_P (count))
- {
- rounded_count = (INTVAL (count)
- & ~((HOST_WIDE_INT) GET_MODE_SIZE (mode) - 1));
- destmem = shallow_copy_rtx (destmem);
- set_mem_size (destmem, rounded_count);
- }
- else if (MEM_SIZE_KNOWN_P (destmem))
- clear_mem_size (destmem);
- emit_insn (gen_rep_stos (destptr, countreg, destmem, value, destexp));
-}
-
-static void
-emit_strmov (rtx destmem, rtx srcmem,
- rtx destptr, rtx srcptr, enum machine_mode mode, int offset)
-{
- rtx src = adjust_automodify_address_nv (srcmem, mode, srcptr, offset);
- rtx dest = adjust_automodify_address_nv (destmem, mode, destptr, offset);
- emit_insn (gen_strmov (destptr, dest, srcptr, src));
-}
-
-/* Output code to copy at most count & (max_size - 1) bytes from SRC to DEST. */
-static void
-expand_movmem_epilogue (rtx destmem, rtx srcmem,
- rtx destptr, rtx srcptr, rtx count, int max_size)
-{
- rtx src, dest;
- if (CONST_INT_P (count))
- {
- HOST_WIDE_INT countval = INTVAL (count);
- int offset = 0;
-
- if ((countval & 0x10) && max_size > 16)
- {
- if (TARGET_64BIT)
- {
- emit_strmov (destmem, srcmem, destptr, srcptr, DImode, offset);
- emit_strmov (destmem, srcmem, destptr, srcptr, DImode, offset + 8);
- }
- else
- gcc_unreachable ();
- offset += 16;
- }
- if ((countval & 0x08) && max_size > 8)
- {
- if (TARGET_64BIT)
- emit_strmov (destmem, srcmem, destptr, srcptr, DImode, offset);
- else
- {
- emit_strmov (destmem, srcmem, destptr, srcptr, SImode, offset);
- emit_strmov (destmem, srcmem, destptr, srcptr, SImode, offset + 4);
- }
- offset += 8;
- }
- if ((countval & 0x04) && max_size > 4)
- {
- emit_strmov (destmem, srcmem, destptr, srcptr, SImode, offset);
- offset += 4;
- }
- if ((countval & 0x02) && max_size > 2)
- {
- emit_strmov (destmem, srcmem, destptr, srcptr, HImode, offset);
- offset += 2;
- }
- if ((countval & 0x01) && max_size > 1)
- {
- emit_strmov (destmem, srcmem, destptr, srcptr, QImode, offset);
- offset += 1;
- }
- return;
- }
- if (max_size > 8)
- {
- count = expand_simple_binop (GET_MODE (count), AND, count, GEN_INT (max_size - 1),
- count, 1, OPTAB_DIRECT);
- expand_set_or_movmem_via_loop (destmem, srcmem, destptr, srcptr, NULL,
- count, QImode, 1, 4);
- return;
- }
-
- /* When there are stringops, we can cheaply increase dest and src pointers.
- Otherwise we save code size by maintaining offset (zero is readily
- available from preceding rep operation) and using x86 addressing modes.
- */
- if (TARGET_SINGLE_STRINGOP)
- {
- if (max_size > 4)
- {
- rtx label = ix86_expand_aligntest (count, 4, true);
- src = change_address (srcmem, SImode, srcptr);
- dest = change_address (destmem, SImode, destptr);
- emit_insn (gen_strmov (destptr, dest, srcptr, src));
- emit_label (label);
- LABEL_NUSES (label) = 1;
- }
- if (max_size > 2)
- {
- rtx label = ix86_expand_aligntest (count, 2, true);
- src = change_address (srcmem, HImode, srcptr);
- dest = change_address (destmem, HImode, destptr);
- emit_insn (gen_strmov (destptr, dest, srcptr, src));
- emit_label (label);
- LABEL_NUSES (label) = 1;
- }
- if (max_size > 1)
- {
- rtx label = ix86_expand_aligntest (count, 1, true);
- src = change_address (srcmem, QImode, srcptr);
- dest = change_address (destmem, QImode, destptr);
- emit_insn (gen_strmov (destptr, dest, srcptr, src));
- emit_label (label);
- LABEL_NUSES (label) = 1;
- }
- }
- else
- {
- rtx offset = force_reg (Pmode, const0_rtx);
- rtx tmp;
-
- if (max_size > 4)
- {
- rtx label = ix86_expand_aligntest (count, 4, true);
- src = change_address (srcmem, SImode, srcptr);
- dest = change_address (destmem, SImode, destptr);
- emit_move_insn (dest, src);
- tmp = expand_simple_binop (Pmode, PLUS, offset, GEN_INT (4), NULL,
- true, OPTAB_LIB_WIDEN);
- if (tmp != offset)
- emit_move_insn (offset, tmp);
- emit_label (label);
- LABEL_NUSES (label) = 1;
- }
- if (max_size > 2)
- {
- rtx label = ix86_expand_aligntest (count, 2, true);
- tmp = gen_rtx_PLUS (Pmode, srcptr, offset);
- src = change_address (srcmem, HImode, tmp);
- tmp = gen_rtx_PLUS (Pmode, destptr, offset);
- dest = change_address (destmem, HImode, tmp);
- emit_move_insn (dest, src);
- tmp = expand_simple_binop (Pmode, PLUS, offset, GEN_INT (2), tmp,
- true, OPTAB_LIB_WIDEN);
- if (tmp != offset)
- emit_move_insn (offset, tmp);
- emit_label (label);
- LABEL_NUSES (label) = 1;
- }
- if (max_size > 1)
- {
- rtx label = ix86_expand_aligntest (count, 1, true);
- tmp = gen_rtx_PLUS (Pmode, srcptr, offset);
- src = change_address (srcmem, QImode, tmp);
- tmp = gen_rtx_PLUS (Pmode, destptr, offset);
- dest = change_address (destmem, QImode, tmp);
- emit_move_insn (dest, src);
- emit_label (label);
- LABEL_NUSES (label) = 1;
- }
- }
-}
-
-/* Output code to set at most count & (max_size - 1) bytes starting by DEST. */
-static void
-expand_setmem_epilogue_via_loop (rtx destmem, rtx destptr, rtx value,
- rtx count, int max_size)
-{
- count =
- expand_simple_binop (counter_mode (count), AND, count,
- GEN_INT (max_size - 1), count, 1, OPTAB_DIRECT);
- expand_set_or_movmem_via_loop (destmem, NULL, destptr, NULL,
- gen_lowpart (QImode, value), count, QImode,
- 1, max_size / 2);
-}
-
-/* Output code to set at most count & (max_size - 1) bytes starting by DEST. */
-static void
-expand_setmem_epilogue (rtx destmem, rtx destptr, rtx value, rtx count, int max_size)
-{
- rtx dest;
-
- if (CONST_INT_P (count))
- {
- HOST_WIDE_INT countval = INTVAL (count);
- int offset = 0;
-
- if ((countval & 0x10) && max_size > 16)
- {
- if (TARGET_64BIT)
- {
- dest = adjust_automodify_address_nv (destmem, DImode, destptr, offset);
- emit_insn (gen_strset (destptr, dest, value));
- dest = adjust_automodify_address_nv (destmem, DImode, destptr, offset + 8);
- emit_insn (gen_strset (destptr, dest, value));
- }
- else
- gcc_unreachable ();
- offset += 16;
- }
- if ((countval & 0x08) && max_size > 8)
- {
- if (TARGET_64BIT)
- {
- dest = adjust_automodify_address_nv (destmem, DImode, destptr, offset);
- emit_insn (gen_strset (destptr, dest, value));
- }
- else
- {
- dest = adjust_automodify_address_nv (destmem, SImode, destptr, offset);
- emit_insn (gen_strset (destptr, dest, value));
- dest = adjust_automodify_address_nv (destmem, SImode, destptr, offset + 4);
- emit_insn (gen_strset (destptr, dest, value));
- }
- offset += 8;
- }
- if ((countval & 0x04) && max_size > 4)
- {
- dest = adjust_automodify_address_nv (destmem, SImode, destptr, offset);
- emit_insn (gen_strset (destptr, dest, gen_lowpart (SImode, value)));
- offset += 4;
- }
- if ((countval & 0x02) && max_size > 2)
- {
- dest = adjust_automodify_address_nv (destmem, HImode, destptr, offset);
- emit_insn (gen_strset (destptr, dest, gen_lowpart (HImode, value)));
- offset += 2;
- }
- if ((countval & 0x01) && max_size > 1)
- {
- dest = adjust_automodify_address_nv (destmem, QImode, destptr, offset);
- emit_insn (gen_strset (destptr, dest, gen_lowpart (QImode, value)));
- offset += 1;
- }
- return;
- }
- if (max_size > 32)
- {
- expand_setmem_epilogue_via_loop (destmem, destptr, value, count, max_size);
- return;
- }
- if (max_size > 16)
- {
- rtx label = ix86_expand_aligntest (count, 16, true);
- if (TARGET_64BIT)
- {
- dest = change_address (destmem, DImode, destptr);
- emit_insn (gen_strset (destptr, dest, value));
- emit_insn (gen_strset (destptr, dest, value));
- }
- else
- {
- dest = change_address (destmem, SImode, destptr);
- emit_insn (gen_strset (destptr, dest, value));
- emit_insn (gen_strset (destptr, dest, value));
- emit_insn (gen_strset (destptr, dest, value));
- emit_insn (gen_strset (destptr, dest, value));
- }
- emit_label (label);
- LABEL_NUSES (label) = 1;
- }
- if (max_size > 8)
- {
- rtx label = ix86_expand_aligntest (count, 8, true);
- if (TARGET_64BIT)
- {
- dest = change_address (destmem, DImode, destptr);
- emit_insn (gen_strset (destptr, dest, value));
- }
- else
- {
- dest = change_address (destmem, SImode, destptr);
- emit_insn (gen_strset (destptr, dest, value));
- emit_insn (gen_strset (destptr, dest, value));
- }
- emit_label (label);
- LABEL_NUSES (label) = 1;
- }
- if (max_size > 4)
- {
- rtx label = ix86_expand_aligntest (count, 4, true);
- dest = change_address (destmem, SImode, destptr);
- emit_insn (gen_strset (destptr, dest, gen_lowpart (SImode, value)));
- emit_label (label);
- LABEL_NUSES (label) = 1;
- }
- if (max_size > 2)
- {
- rtx label = ix86_expand_aligntest (count, 2, true);
- dest = change_address (destmem, HImode, destptr);
- emit_insn (gen_strset (destptr, dest, gen_lowpart (HImode, value)));
- emit_label (label);
- LABEL_NUSES (label) = 1;
- }
- if (max_size > 1)
- {
- rtx label = ix86_expand_aligntest (count, 1, true);
- dest = change_address (destmem, QImode, destptr);
- emit_insn (gen_strset (destptr, dest, gen_lowpart (QImode, value)));
- emit_label (label);
- LABEL_NUSES (label) = 1;
- }
-}
-
-/* Copy enough from DEST to SRC to align DEST known to by aligned by ALIGN to
- DESIRED_ALIGNMENT. */
-static void
-expand_movmem_prologue (rtx destmem, rtx srcmem,
- rtx destptr, rtx srcptr, rtx count,
- int align, int desired_alignment)
-{
- if (align <= 1 && desired_alignment > 1)
- {
- rtx label = ix86_expand_aligntest (destptr, 1, false);
- srcmem = change_address (srcmem, QImode, srcptr);
- destmem = change_address (destmem, QImode, destptr);
- emit_insn (gen_strmov (destptr, destmem, srcptr, srcmem));
- ix86_adjust_counter (count, 1);
- emit_label (label);
- LABEL_NUSES (label) = 1;
- }
- if (align <= 2 && desired_alignment > 2)
- {
- rtx label = ix86_expand_aligntest (destptr, 2, false);
- srcmem = change_address (srcmem, HImode, srcptr);
- destmem = change_address (destmem, HImode, destptr);
- emit_insn (gen_strmov (destptr, destmem, srcptr, srcmem));
- ix86_adjust_counter (count, 2);
- emit_label (label);
- LABEL_NUSES (label) = 1;
- }
- if (align <= 4 && desired_alignment > 4)
- {
- rtx label = ix86_expand_aligntest (destptr, 4, false);
- srcmem = change_address (srcmem, SImode, srcptr);
- destmem = change_address (destmem, SImode, destptr);
- emit_insn (gen_strmov (destptr, destmem, srcptr, srcmem));
- ix86_adjust_counter (count, 4);
- emit_label (label);
- LABEL_NUSES (label) = 1;
- }
- gcc_assert (desired_alignment <= 8);
-}
-
-/* Copy enough from DST to SRC to align DST known to DESIRED_ALIGN.
- ALIGN_BYTES is how many bytes need to be copied. */
-static rtx
-expand_constant_movmem_prologue (rtx dst, rtx *srcp, rtx destreg, rtx srcreg,
- int desired_align, int align_bytes)
-{
- rtx src = *srcp;
- rtx orig_dst = dst;
- rtx orig_src = src;
- int off = 0;
- int src_align_bytes = get_mem_align_offset (src, desired_align * BITS_PER_UNIT);
- if (src_align_bytes >= 0)
- src_align_bytes = desired_align - src_align_bytes;
- if (align_bytes & 1)
- {
- dst = adjust_automodify_address_nv (dst, QImode, destreg, 0);
- src = adjust_automodify_address_nv (src, QImode, srcreg, 0);
- off = 1;
- emit_insn (gen_strmov (destreg, dst, srcreg, src));
- }
- if (align_bytes & 2)
- {
- dst = adjust_automodify_address_nv (dst, HImode, destreg, off);
- src = adjust_automodify_address_nv (src, HImode, srcreg, off);
- if (MEM_ALIGN (dst) < 2 * BITS_PER_UNIT)
- set_mem_align (dst, 2 * BITS_PER_UNIT);
- if (src_align_bytes >= 0
- && (src_align_bytes & 1) == (align_bytes & 1)
- && MEM_ALIGN (src) < 2 * BITS_PER_UNIT)
- set_mem_align (src, 2 * BITS_PER_UNIT);
- off = 2;
- emit_insn (gen_strmov (destreg, dst, srcreg, src));
- }
- if (align_bytes & 4)
- {
- dst = adjust_automodify_address_nv (dst, SImode, destreg, off);
- src = adjust_automodify_address_nv (src, SImode, srcreg, off);
- if (MEM_ALIGN (dst) < 4 * BITS_PER_UNIT)
- set_mem_align (dst, 4 * BITS_PER_UNIT);
- if (src_align_bytes >= 0)
- {
- unsigned int src_align = 0;
- if ((src_align_bytes & 3) == (align_bytes & 3))
- src_align = 4;
- else if ((src_align_bytes & 1) == (align_bytes & 1))
- src_align = 2;
- if (MEM_ALIGN (src) < src_align * BITS_PER_UNIT)
- set_mem_align (src, src_align * BITS_PER_UNIT);
- }
- off = 4;
- emit_insn (gen_strmov (destreg, dst, srcreg, src));
- }
- dst = adjust_automodify_address_nv (dst, BLKmode, destreg, off);
- src = adjust_automodify_address_nv (src, BLKmode, srcreg, off);
- if (MEM_ALIGN (dst) < (unsigned int) desired_align * BITS_PER_UNIT)
- set_mem_align (dst, desired_align * BITS_PER_UNIT);
- if (src_align_bytes >= 0)
- {
- unsigned int src_align = 0;
- if ((src_align_bytes & 7) == (align_bytes & 7))
- src_align = 8;
- else if ((src_align_bytes & 3) == (align_bytes & 3))
- src_align = 4;
- else if ((src_align_bytes & 1) == (align_bytes & 1))
- src_align = 2;
- if (src_align > (unsigned int) desired_align)
- src_align = desired_align;
- if (MEM_ALIGN (src) < src_align * BITS_PER_UNIT)
- set_mem_align (src, src_align * BITS_PER_UNIT);
- }
- if (MEM_SIZE_KNOWN_P (orig_dst))
- set_mem_size (dst, MEM_SIZE (orig_dst) - align_bytes);
- if (MEM_SIZE_KNOWN_P (orig_src))
- set_mem_size (src, MEM_SIZE (orig_src) - align_bytes);
- *srcp = src;
- return dst;
-}
-
-/* Set enough from DEST to align DEST known to by aligned by ALIGN to
- DESIRED_ALIGNMENT. */
-static void
-expand_setmem_prologue (rtx destmem, rtx destptr, rtx value, rtx count,
- int align, int desired_alignment)
-{
- if (align <= 1 && desired_alignment > 1)
- {
- rtx label = ix86_expand_aligntest (destptr, 1, false);
- destmem = change_address (destmem, QImode, destptr);
- emit_insn (gen_strset (destptr, destmem, gen_lowpart (QImode, value)));
- ix86_adjust_counter (count, 1);
- emit_label (label);
- LABEL_NUSES (label) = 1;
- }
- if (align <= 2 && desired_alignment > 2)
- {
- rtx label = ix86_expand_aligntest (destptr, 2, false);
- destmem = change_address (destmem, HImode, destptr);
- emit_insn (gen_strset (destptr, destmem, gen_lowpart (HImode, value)));
- ix86_adjust_counter (count, 2);
- emit_label (label);
- LABEL_NUSES (label) = 1;
- }
- if (align <= 4 && desired_alignment > 4)
- {
- rtx label = ix86_expand_aligntest (destptr, 4, false);
- destmem = change_address (destmem, SImode, destptr);
- emit_insn (gen_strset (destptr, destmem, gen_lowpart (SImode, value)));
- ix86_adjust_counter (count, 4);
- emit_label (label);
- LABEL_NUSES (label) = 1;
- }
- gcc_assert (desired_alignment <= 8);
-}
-
-/* Set enough from DST to align DST known to by aligned by ALIGN to
- DESIRED_ALIGN. ALIGN_BYTES is how many bytes need to be stored. */
-static rtx
-expand_constant_setmem_prologue (rtx dst, rtx destreg, rtx value,
- int desired_align, int align_bytes)
-{
- int off = 0;
- rtx orig_dst = dst;
- if (align_bytes & 1)
- {
- dst = adjust_automodify_address_nv (dst, QImode, destreg, 0);
- off = 1;
- emit_insn (gen_strset (destreg, dst,
- gen_lowpart (QImode, value)));
- }
- if (align_bytes & 2)
- {
- dst = adjust_automodify_address_nv (dst, HImode, destreg, off);
- if (MEM_ALIGN (dst) < 2 * BITS_PER_UNIT)
- set_mem_align (dst, 2 * BITS_PER_UNIT);
- off = 2;
- emit_insn (gen_strset (destreg, dst,
- gen_lowpart (HImode, value)));
- }
- if (align_bytes & 4)
- {
- dst = adjust_automodify_address_nv (dst, SImode, destreg, off);
- if (MEM_ALIGN (dst) < 4 * BITS_PER_UNIT)
- set_mem_align (dst, 4 * BITS_PER_UNIT);
- off = 4;
- emit_insn (gen_strset (destreg, dst,
- gen_lowpart (SImode, value)));
- }
- dst = adjust_automodify_address_nv (dst, BLKmode, destreg, off);
- if (MEM_ALIGN (dst) < (unsigned int) desired_align * BITS_PER_UNIT)
- set_mem_align (dst, desired_align * BITS_PER_UNIT);
- if (MEM_SIZE_KNOWN_P (orig_dst))
- set_mem_size (dst, MEM_SIZE (orig_dst) - align_bytes);
- return dst;
-}
-
-/* Given COUNT and EXPECTED_SIZE, decide on codegen of string operation. */
-static enum stringop_alg
-decide_alg (HOST_WIDE_INT count, HOST_WIDE_INT expected_size, bool memset,
- int *dynamic_check, bool *noalign)
-{
- const struct stringop_algs * algs;
- bool optimize_for_speed;
- /* Algorithms using the rep prefix want at least edi and ecx;
- additionally, memset wants eax and memcpy wants esi. Don't
- consider such algorithms if the user has appropriated those
- registers for their own purposes. */
- bool rep_prefix_usable = !(fixed_regs[CX_REG] || fixed_regs[DI_REG]
- || (memset
- ? fixed_regs[AX_REG] : fixed_regs[SI_REG]));
- *noalign = false;
-
-#define ALG_USABLE_P(alg) (rep_prefix_usable \
- || (alg != rep_prefix_1_byte \
- && alg != rep_prefix_4_byte \
- && alg != rep_prefix_8_byte))
- const struct processor_costs *cost;
-
- /* Even if the string operation call is cold, we still might spend a lot
- of time processing large blocks. */
- if (optimize_function_for_size_p (cfun)
- || (optimize_insn_for_size_p ()
- && expected_size != -1 && expected_size < 256))
- optimize_for_speed = false;
- else
- optimize_for_speed = true;
-
- cost = optimize_for_speed ? ix86_cost : &ix86_size_cost;
-
- *dynamic_check = -1;
- if (memset)
- algs = &cost->memset[TARGET_64BIT != 0];
- else
- algs = &cost->memcpy[TARGET_64BIT != 0];
- if (ix86_stringop_alg != no_stringop && ALG_USABLE_P (ix86_stringop_alg))
- return ix86_stringop_alg;
- /* rep; movq or rep; movl is the smallest variant. */
- else if (!optimize_for_speed)
- {
- if (!count || (count & 3))
- return rep_prefix_usable ? rep_prefix_1_byte : loop_1_byte;
- else
- return rep_prefix_usable ? rep_prefix_4_byte : loop;
- }
- /* Very tiny blocks are best handled via the loop, REP is expensive to setup.
- */
- else if (expected_size != -1 && expected_size < 4)
- return loop_1_byte;
- else if (expected_size != -1)
- {
- unsigned int i;
- enum stringop_alg alg = libcall;
- for (i = 0; i < MAX_STRINGOP_ALGS; i++)
- {
- /* We get here if the algorithms that were not libcall-based
- were rep-prefix based and we are unable to use rep prefixes
- based on global register usage. Break out of the loop and
- use the heuristic below. */
- if (algs->size[i].max == 0)
- break;
- if (algs->size[i].max >= expected_size || algs->size[i].max == -1)
- {
- enum stringop_alg candidate = algs->size[i].alg;
-
- if (candidate != libcall && ALG_USABLE_P (candidate))
- alg = candidate;
- /* Honor TARGET_INLINE_ALL_STRINGOPS by picking
- last non-libcall inline algorithm. */
- if (TARGET_INLINE_ALL_STRINGOPS)
- {
- /* When the current size is best to be copied by a libcall,
- but we are still forced to inline, run the heuristic below
- that will pick code for medium sized blocks. */
- if (alg != libcall)
- return alg;
- break;
- }
- else if (ALG_USABLE_P (candidate))
- {
- *noalign = algs->size[i].noalign;
- return candidate;
- }
- }
- }
- gcc_assert (TARGET_INLINE_ALL_STRINGOPS || !rep_prefix_usable);
- }
- /* When asked to inline the call anyway, try to pick meaningful choice.
- We look for maximal size of block that is faster to copy by hand and
- take blocks of at most of that size guessing that average size will
- be roughly half of the block.
-
- If this turns out to be bad, we might simply specify the preferred
- choice in ix86_costs. */
- if ((TARGET_INLINE_ALL_STRINGOPS || TARGET_INLINE_STRINGOPS_DYNAMICALLY)
- && (algs->unknown_size == libcall || !ALG_USABLE_P (algs->unknown_size)))
- {
- int max = -1;
- enum stringop_alg alg;
- int i;
- bool any_alg_usable_p = true;
-
- for (i = 0; i < MAX_STRINGOP_ALGS; i++)
- {
- enum stringop_alg candidate = algs->size[i].alg;
- any_alg_usable_p = any_alg_usable_p && ALG_USABLE_P (candidate);
-
- if (candidate != libcall && candidate
- && ALG_USABLE_P (candidate))
- max = algs->size[i].max;
- }
- /* If there aren't any usable algorithms, then recursing on
- smaller sizes isn't going to find anything. Just return the
- simple byte-at-a-time copy loop. */
- if (!any_alg_usable_p)
- {
- /* Pick something reasonable. */
- if (TARGET_INLINE_STRINGOPS_DYNAMICALLY)
- *dynamic_check = 128;
- return loop_1_byte;
- }
- if (max == -1)
- max = 4096;
- alg = decide_alg (count, max / 2, memset, dynamic_check, noalign);
- gcc_assert (*dynamic_check == -1);
- gcc_assert (alg != libcall);
- if (TARGET_INLINE_STRINGOPS_DYNAMICALLY)
- *dynamic_check = max;
- return alg;
- }
- return ALG_USABLE_P (algs->unknown_size) ? algs->unknown_size : libcall;
-#undef ALG_USABLE_P
-}
-
-/* Decide on alignment. We know that the operand is already aligned to ALIGN
- (ALIGN can be based on profile feedback and thus it is not 100% guaranteed). */
-static int
-decide_alignment (int align,
- enum stringop_alg alg,
- int expected_size)
-{
- int desired_align = 0;
- switch (alg)
- {
- case no_stringop:
- gcc_unreachable ();
- case loop:
- case unrolled_loop:
- desired_align = GET_MODE_SIZE (Pmode);
- break;
- case rep_prefix_8_byte:
- desired_align = 8;
- break;
- case rep_prefix_4_byte:
- /* PentiumPro has special logic triggering for 8 byte aligned blocks.
- copying whole cacheline at once. */
- if (TARGET_PENTIUMPRO)
- desired_align = 8;
- else
- desired_align = 4;
- break;
- case rep_prefix_1_byte:
- /* PentiumPro has special logic triggering for 8 byte aligned blocks.
- copying whole cacheline at once. */
- if (TARGET_PENTIUMPRO)
- desired_align = 8;
- else
- desired_align = 1;
- break;
- case loop_1_byte:
- desired_align = 1;
- break;
- case libcall:
- return 0;
- }
-
- if (optimize_size)
- desired_align = 1;
- if (desired_align < align)
- desired_align = align;
- if (expected_size != -1 && expected_size < 4)
- desired_align = align;
- return desired_align;
-}
-
-/* Return the smallest power of 2 greater than VAL. */
-static int
-smallest_pow2_greater_than (int val)
-{
- int ret = 1;
- while (ret <= val)
- ret <<= 1;
- return ret;
-}
-
-/* Expand string move (memcpy) operation. Use i386 string operations
- when profitable. expand_setmem contains similar code. The code
- depends upon architecture, block size and alignment, but always has
- the same overall structure:
-
- 1) Prologue guard: Conditional that jumps up to epilogues for small
- blocks that can be handled by epilogue alone. This is faster
- but also needed for correctness, since prologue assume the block
- is larger than the desired alignment.
-
- Optional dynamic check for size and libcall for large
- blocks is emitted here too, with -minline-stringops-dynamically.
-
- 2) Prologue: copy first few bytes in order to get destination
- aligned to DESIRED_ALIGN. It is emitted only when ALIGN is less
- than DESIRED_ALIGN and up to DESIRED_ALIGN - ALIGN bytes can be
- copied. We emit either a jump tree on power of two sized
- blocks, or a byte loop.
-
- 3) Main body: the copying loop itself, copying in SIZE_NEEDED chunks
- with specified algorithm.
-
- 4) Epilogue: code copying tail of the block that is too small to be
- handled by main body (or up to size guarded by prologue guard). */
-
-bool
-ix86_expand_movmem (rtx dst, rtx src, rtx count_exp, rtx align_exp,
- rtx expected_align_exp, rtx expected_size_exp)
-{
- rtx destreg;
- rtx srcreg;
- rtx label = NULL;
- rtx tmp;
- rtx jump_around_label = NULL;
- HOST_WIDE_INT align = 1;
- unsigned HOST_WIDE_INT count = 0;
- HOST_WIDE_INT expected_size = -1;
- int size_needed = 0, epilogue_size_needed;
- int desired_align = 0, align_bytes = 0;
- enum stringop_alg alg;
- int dynamic_check;
- bool need_zero_guard = false;
- bool noalign;
-
- if (CONST_INT_P (align_exp))
- align = INTVAL (align_exp);
- /* i386 can do misaligned access on reasonably increased cost. */
- if (CONST_INT_P (expected_align_exp)
- && INTVAL (expected_align_exp) > align)
- align = INTVAL (expected_align_exp);
- /* ALIGN is the minimum of destination and source alignment, but we care here
- just about destination alignment. */
- else if (MEM_ALIGN (dst) > (unsigned HOST_WIDE_INT) align * BITS_PER_UNIT)
- align = MEM_ALIGN (dst) / BITS_PER_UNIT;
-
- if (CONST_INT_P (count_exp))
- count = expected_size = INTVAL (count_exp);
- if (CONST_INT_P (expected_size_exp) && count == 0)
- expected_size = INTVAL (expected_size_exp);
-
- /* Make sure we don't need to care about overflow later on. */
- if (count > ((unsigned HOST_WIDE_INT) 1 << 30))
- return false;
-
- /* Step 0: Decide on preferred algorithm, desired alignment and
- size of chunks to be copied by main loop. */
-
- alg = decide_alg (count, expected_size, false, &dynamic_check, &noalign);
- desired_align = decide_alignment (align, alg, expected_size);
-
- if (!TARGET_ALIGN_STRINGOPS || noalign)
- align = desired_align;
-
- if (alg == libcall)
- return false;
- gcc_assert (alg != no_stringop);
- if (!count)
- count_exp = copy_to_mode_reg (GET_MODE (count_exp), count_exp);
- destreg = copy_addr_to_reg (XEXP (dst, 0));
- srcreg = copy_addr_to_reg (XEXP (src, 0));
- switch (alg)
- {
- case libcall:
- case no_stringop:
- gcc_unreachable ();
- case loop:
- need_zero_guard = true;
- size_needed = GET_MODE_SIZE (word_mode);
- break;
- case unrolled_loop:
- need_zero_guard = true;
- size_needed = GET_MODE_SIZE (word_mode) * (TARGET_64BIT ? 4 : 2);
- break;
- case rep_prefix_8_byte:
- size_needed = 8;
- break;
- case rep_prefix_4_byte:
- size_needed = 4;
- break;
- case rep_prefix_1_byte:
- size_needed = 1;
- break;
- case loop_1_byte:
- need_zero_guard = true;
- size_needed = 1;
- break;
- }
-
- epilogue_size_needed = size_needed;
-
- /* Step 1: Prologue guard. */
-
- /* Alignment code needs count to be in register. */
- if (CONST_INT_P (count_exp) && desired_align > align)
- {
- if (INTVAL (count_exp) > desired_align
- && INTVAL (count_exp) > size_needed)
- {
- align_bytes
- = get_mem_align_offset (dst, desired_align * BITS_PER_UNIT);
- if (align_bytes <= 0)
- align_bytes = 0;
- else
- align_bytes = desired_align - align_bytes;
- }
- if (align_bytes == 0)
- count_exp = force_reg (counter_mode (count_exp), count_exp);
- }
- gcc_assert (desired_align >= 1 && align >= 1);
-
- /* Ensure that alignment prologue won't copy past end of block. */
- if (size_needed > 1 || (desired_align > 1 && desired_align > align))
- {
- epilogue_size_needed = MAX (size_needed - 1, desired_align - align);
- /* Epilogue always copies COUNT_EXP & EPILOGUE_SIZE_NEEDED bytes.
- Make sure it is power of 2. */
- epilogue_size_needed = smallest_pow2_greater_than (epilogue_size_needed);
-
- if (count)
- {
- if (count < (unsigned HOST_WIDE_INT)epilogue_size_needed)
- {
- /* If main algorithm works on QImode, no epilogue is needed.
- For small sizes just don't align anything. */
- if (size_needed == 1)
- desired_align = align;
- else
- goto epilogue;
- }
- }
- else
- {
- label = gen_label_rtx ();
- emit_cmp_and_jump_insns (count_exp,
- GEN_INT (epilogue_size_needed),
- LTU, 0, counter_mode (count_exp), 1, label);
- if (expected_size == -1 || expected_size < epilogue_size_needed)
- predict_jump (REG_BR_PROB_BASE * 60 / 100);
- else
- predict_jump (REG_BR_PROB_BASE * 20 / 100);
- }
- }
-
- /* Emit code to decide on runtime whether library call or inline should be
- used. */
- if (dynamic_check != -1)
- {
- if (CONST_INT_P (count_exp))
- {
- if (UINTVAL (count_exp) >= (unsigned HOST_WIDE_INT)dynamic_check)
- {
- emit_block_move_via_libcall (dst, src, count_exp, false);
- count_exp = const0_rtx;
- goto epilogue;
- }
- }
- else
- {
- rtx hot_label = gen_label_rtx ();
- jump_around_label = gen_label_rtx ();
- emit_cmp_and_jump_insns (count_exp, GEN_INT (dynamic_check - 1),
- LEU, 0, GET_MODE (count_exp), 1, hot_label);
- predict_jump (REG_BR_PROB_BASE * 90 / 100);
- emit_block_move_via_libcall (dst, src, count_exp, false);
- emit_jump (jump_around_label);
- emit_label (hot_label);
- }
- }
-
- /* Step 2: Alignment prologue. */
-
- if (desired_align > align)
- {
- if (align_bytes == 0)
- {
- /* Except for the first move in epilogue, we no longer know
- constant offset in aliasing info. It don't seems to worth
- the pain to maintain it for the first move, so throw away
- the info early. */
- src = change_address (src, BLKmode, srcreg);
- dst = change_address (dst, BLKmode, destreg);
- expand_movmem_prologue (dst, src, destreg, srcreg, count_exp, align,
- desired_align);
- }
- else
- {
- /* If we know how many bytes need to be stored before dst is
- sufficiently aligned, maintain aliasing info accurately. */
- dst = expand_constant_movmem_prologue (dst, &src, destreg, srcreg,
- desired_align, align_bytes);
- count_exp = plus_constant (counter_mode (count_exp),
- count_exp, -align_bytes);
- count -= align_bytes;
- }
- if (need_zero_guard
- && (count < (unsigned HOST_WIDE_INT) size_needed
- || (align_bytes == 0
- && count < ((unsigned HOST_WIDE_INT) size_needed
- + desired_align - align))))
- {
- /* It is possible that we copied enough so the main loop will not
- execute. */
- gcc_assert (size_needed > 1);
- if (label == NULL_RTX)
- label = gen_label_rtx ();
- emit_cmp_and_jump_insns (count_exp,
- GEN_INT (size_needed),
- LTU, 0, counter_mode (count_exp), 1, label);
- if (expected_size == -1
- || expected_size < (desired_align - align) / 2 + size_needed)
- predict_jump (REG_BR_PROB_BASE * 20 / 100);
- else
- predict_jump (REG_BR_PROB_BASE * 60 / 100);
- }
- }
- if (label && size_needed == 1)
- {
- emit_label (label);
- LABEL_NUSES (label) = 1;
- label = NULL;
- epilogue_size_needed = 1;
- }
- else if (label == NULL_RTX)
- epilogue_size_needed = size_needed;
-
- /* Step 3: Main loop. */
-
- switch (alg)
- {
- case libcall:
- case no_stringop:
- gcc_unreachable ();
- case loop_1_byte:
- expand_set_or_movmem_via_loop (dst, src, destreg, srcreg, NULL,
- count_exp, QImode, 1, expected_size);
- break;
- case loop:
- expand_set_or_movmem_via_loop (dst, src, destreg, srcreg, NULL,
- count_exp, word_mode, 1, expected_size);
- break;
- case unrolled_loop:
- /* Unroll only by factor of 2 in 32bit mode, since we don't have enough
- registers for 4 temporaries anyway. */
- expand_set_or_movmem_via_loop (dst, src, destreg, srcreg, NULL,
- count_exp, word_mode, TARGET_64BIT ? 4 : 2,
- expected_size);
- break;
- case rep_prefix_8_byte:
- expand_movmem_via_rep_mov (dst, src, destreg, srcreg, count_exp,
- DImode);
- break;
- case rep_prefix_4_byte:
- expand_movmem_via_rep_mov (dst, src, destreg, srcreg, count_exp,
- SImode);
- break;
- case rep_prefix_1_byte:
- expand_movmem_via_rep_mov (dst, src, destreg, srcreg, count_exp,
- QImode);
- break;
- }
- /* Adjust properly the offset of src and dest memory for aliasing. */
- if (CONST_INT_P (count_exp))
- {
- src = adjust_automodify_address_nv (src, BLKmode, srcreg,
- (count / size_needed) * size_needed);
- dst = adjust_automodify_address_nv (dst, BLKmode, destreg,
- (count / size_needed) * size_needed);
- }
- else
- {
- src = change_address (src, BLKmode, srcreg);
- dst = change_address (dst, BLKmode, destreg);
- }
-
- /* Step 4: Epilogue to copy the remaining bytes. */
- epilogue:
- if (label)
- {
- /* When the main loop is done, COUNT_EXP might hold original count,
- while we want to copy only COUNT_EXP & SIZE_NEEDED bytes.
- Epilogue code will actually copy COUNT_EXP & EPILOGUE_SIZE_NEEDED
- bytes. Compensate if needed. */
-
- if (size_needed < epilogue_size_needed)
- {
- tmp =
- expand_simple_binop (counter_mode (count_exp), AND, count_exp,
- GEN_INT (size_needed - 1), count_exp, 1,
- OPTAB_DIRECT);
- if (tmp != count_exp)
- emit_move_insn (count_exp, tmp);
- }
- emit_label (label);
- LABEL_NUSES (label) = 1;
- }
-
- if (count_exp != const0_rtx && epilogue_size_needed > 1)
- expand_movmem_epilogue (dst, src, destreg, srcreg, count_exp,
- epilogue_size_needed);
- if (jump_around_label)
- emit_label (jump_around_label);
- return true;
-}
-
-/* Helper function for memcpy. For QImode value 0xXY produce
- 0xXYXYXYXY of wide specified by MODE. This is essentially
- a * 0x10101010, but we can do slightly better than
- synth_mult by unwinding the sequence by hand on CPUs with
- slow multiply. */
-static rtx
-promote_duplicated_reg (enum machine_mode mode, rtx val)
-{
- enum machine_mode valmode = GET_MODE (val);
- rtx tmp;
- int nops = mode == DImode ? 3 : 2;
-
- gcc_assert (mode == SImode || mode == DImode);
- if (val == const0_rtx)
- return copy_to_mode_reg (mode, const0_rtx);
- if (CONST_INT_P (val))
- {
- HOST_WIDE_INT v = INTVAL (val) & 255;
-
- v |= v << 8;
- v |= v << 16;
- if (mode == DImode)
- v |= (v << 16) << 16;
- return copy_to_mode_reg (mode, gen_int_mode (v, mode));
- }
-
- if (valmode == VOIDmode)
- valmode = QImode;
- if (valmode != QImode)
- val = gen_lowpart (QImode, val);
- if (mode == QImode)
- return val;
- if (!TARGET_PARTIAL_REG_STALL)
- nops--;
- if (ix86_cost->mult_init[mode == DImode ? 3 : 2]
- + ix86_cost->mult_bit * (mode == DImode ? 8 : 4)
- <= (ix86_cost->shift_const + ix86_cost->add) * nops
- + (COSTS_N_INSNS (TARGET_PARTIAL_REG_STALL == 0)))
- {
- rtx reg = convert_modes (mode, QImode, val, true);
- tmp = promote_duplicated_reg (mode, const1_rtx);
- return expand_simple_binop (mode, MULT, reg, tmp, NULL, 1,
- OPTAB_DIRECT);
- }
- else
- {
- rtx reg = convert_modes (mode, QImode, val, true);
-
- if (!TARGET_PARTIAL_REG_STALL)
- if (mode == SImode)
- emit_insn (gen_movsi_insv_1 (reg, reg));
- else
- emit_insn (gen_movdi_insv_1 (reg, reg));
- else
- {
- tmp = expand_simple_binop (mode, ASHIFT, reg, GEN_INT (8),
- NULL, 1, OPTAB_DIRECT);
- reg =
- expand_simple_binop (mode, IOR, reg, tmp, reg, 1, OPTAB_DIRECT);
- }
- tmp = expand_simple_binop (mode, ASHIFT, reg, GEN_INT (16),
- NULL, 1, OPTAB_DIRECT);
- reg = expand_simple_binop (mode, IOR, reg, tmp, reg, 1, OPTAB_DIRECT);
- if (mode == SImode)
- return reg;
- tmp = expand_simple_binop (mode, ASHIFT, reg, GEN_INT (32),
- NULL, 1, OPTAB_DIRECT);
- reg = expand_simple_binop (mode, IOR, reg, tmp, reg, 1, OPTAB_DIRECT);
- return reg;
- }
-}
-
-/* Duplicate value VAL using promote_duplicated_reg into maximal size that will
- be needed by main loop copying SIZE_NEEDED chunks and prologue getting
- alignment from ALIGN to DESIRED_ALIGN. */
-static rtx
-promote_duplicated_reg_to_size (rtx val, int size_needed, int desired_align, int align)
-{
- rtx promoted_val;
-
- if (TARGET_64BIT
- && (size_needed > 4 || (desired_align > align && desired_align > 4)))
- promoted_val = promote_duplicated_reg (DImode, val);
- else if (size_needed > 2 || (desired_align > align && desired_align > 2))
- promoted_val = promote_duplicated_reg (SImode, val);
- else if (size_needed > 1 || (desired_align > align && desired_align > 1))
- promoted_val = promote_duplicated_reg (HImode, val);
- else
- promoted_val = val;
-
- return promoted_val;
-}
-
-/* Expand string clear operation (bzero). Use i386 string operations when
- profitable. See expand_movmem comment for explanation of individual
- steps performed. */
-bool
-ix86_expand_setmem (rtx dst, rtx count_exp, rtx val_exp, rtx align_exp,
- rtx expected_align_exp, rtx expected_size_exp)
-{
- rtx destreg;
- rtx label = NULL;
- rtx tmp;
- rtx jump_around_label = NULL;
- HOST_WIDE_INT align = 1;
- unsigned HOST_WIDE_INT count = 0;
- HOST_WIDE_INT expected_size = -1;
- int size_needed = 0, epilogue_size_needed;
- int desired_align = 0, align_bytes = 0;
- enum stringop_alg alg;
- rtx promoted_val = NULL;
- bool force_loopy_epilogue = false;
- int dynamic_check;
- bool need_zero_guard = false;
- bool noalign;
-
- if (CONST_INT_P (align_exp))
- align = INTVAL (align_exp);
- /* i386 can do misaligned access on reasonably increased cost. */
- if (CONST_INT_P (expected_align_exp)
- && INTVAL (expected_align_exp) > align)
- align = INTVAL (expected_align_exp);
- if (CONST_INT_P (count_exp))
- count = expected_size = INTVAL (count_exp);
- if (CONST_INT_P (expected_size_exp) && count == 0)
- expected_size = INTVAL (expected_size_exp);
-
- /* Make sure we don't need to care about overflow later on. */
- if (count > ((unsigned HOST_WIDE_INT) 1 << 30))
- return false;
-
- /* Step 0: Decide on preferred algorithm, desired alignment and
- size of chunks to be copied by main loop. */
-
- alg = decide_alg (count, expected_size, true, &dynamic_check, &noalign);
- desired_align = decide_alignment (align, alg, expected_size);
-
- if (!TARGET_ALIGN_STRINGOPS || noalign)
- align = desired_align;
-
- if (alg == libcall)
- return false;
- gcc_assert (alg != no_stringop);
- if (!count)
- count_exp = copy_to_mode_reg (counter_mode (count_exp), count_exp);
- destreg = copy_addr_to_reg (XEXP (dst, 0));
- switch (alg)
- {
- case libcall:
- case no_stringop:
- gcc_unreachable ();
- case loop:
- need_zero_guard = true;
- size_needed = GET_MODE_SIZE (word_mode);
- break;
- case unrolled_loop:
- need_zero_guard = true;
- size_needed = GET_MODE_SIZE (word_mode) * 4;
- break;
- case rep_prefix_8_byte:
- size_needed = 8;
- break;
- case rep_prefix_4_byte:
- size_needed = 4;
- break;
- case rep_prefix_1_byte:
- size_needed = 1;
- break;
- case loop_1_byte:
- need_zero_guard = true;
- size_needed = 1;
- break;
- }
- epilogue_size_needed = size_needed;
-
- /* Step 1: Prologue guard. */
-
- /* Alignment code needs count to be in register. */
- if (CONST_INT_P (count_exp) && desired_align > align)
- {
- if (INTVAL (count_exp) > desired_align
- && INTVAL (count_exp) > size_needed)
- {
- align_bytes
- = get_mem_align_offset (dst, desired_align * BITS_PER_UNIT);
- if (align_bytes <= 0)
- align_bytes = 0;
- else
- align_bytes = desired_align - align_bytes;
- }
- if (align_bytes == 0)
- {
- enum machine_mode mode = SImode;
- if (TARGET_64BIT && (count & ~0xffffffff))
- mode = DImode;
- count_exp = force_reg (mode, count_exp);
- }
- }
- /* Do the cheap promotion to allow better CSE across the
- main loop and epilogue (ie one load of the big constant in the
- front of all code. */
- if (CONST_INT_P (val_exp))
- promoted_val = promote_duplicated_reg_to_size (val_exp, size_needed,
- desired_align, align);
- /* Ensure that alignment prologue won't copy past end of block. */
- if (size_needed > 1 || (desired_align > 1 && desired_align > align))
- {
- epilogue_size_needed = MAX (size_needed - 1, desired_align - align);
- /* Epilogue always copies COUNT_EXP & (EPILOGUE_SIZE_NEEDED - 1) bytes.
- Make sure it is power of 2. */
- epilogue_size_needed = smallest_pow2_greater_than (epilogue_size_needed);
-
- /* To improve performance of small blocks, we jump around the VAL
- promoting mode. This mean that if the promoted VAL is not constant,
- we might not use it in the epilogue and have to use byte
- loop variant. */
- if (epilogue_size_needed > 2 && !promoted_val)
- force_loopy_epilogue = true;
- if (count)
- {
- if (count < (unsigned HOST_WIDE_INT)epilogue_size_needed)
- {
- /* If main algorithm works on QImode, no epilogue is needed.
- For small sizes just don't align anything. */
- if (size_needed == 1)
- desired_align = align;
- else
- goto epilogue;
- }
- }
- else
- {
- label = gen_label_rtx ();
- emit_cmp_and_jump_insns (count_exp,
- GEN_INT (epilogue_size_needed),
- LTU, 0, counter_mode (count_exp), 1, label);
- if (expected_size == -1 || expected_size <= epilogue_size_needed)
- predict_jump (REG_BR_PROB_BASE * 60 / 100);
- else
- predict_jump (REG_BR_PROB_BASE * 20 / 100);
- }
- }
- if (dynamic_check != -1)
- {
- rtx hot_label = gen_label_rtx ();
- jump_around_label = gen_label_rtx ();
- emit_cmp_and_jump_insns (count_exp, GEN_INT (dynamic_check - 1),
- LEU, 0, counter_mode (count_exp), 1, hot_label);
- predict_jump (REG_BR_PROB_BASE * 90 / 100);
- set_storage_via_libcall (dst, count_exp, val_exp, false);
- emit_jump (jump_around_label);
- emit_label (hot_label);
- }
-
- /* Step 2: Alignment prologue. */
-
- /* Do the expensive promotion once we branched off the small blocks. */
- if (!promoted_val)
- promoted_val = promote_duplicated_reg_to_size (val_exp, size_needed,
- desired_align, align);
- gcc_assert (desired_align >= 1 && align >= 1);
-
- if (desired_align > align)
- {
- if (align_bytes == 0)
- {
- /* Except for the first move in epilogue, we no longer know
- constant offset in aliasing info. It don't seems to worth
- the pain to maintain it for the first move, so throw away
- the info early. */
- dst = change_address (dst, BLKmode, destreg);
- expand_setmem_prologue (dst, destreg, promoted_val, count_exp, align,
- desired_align);
- }
- else
- {
- /* If we know how many bytes need to be stored before dst is
- sufficiently aligned, maintain aliasing info accurately. */
- dst = expand_constant_setmem_prologue (dst, destreg, promoted_val,
- desired_align, align_bytes);
- count_exp = plus_constant (counter_mode (count_exp),
- count_exp, -align_bytes);
- count -= align_bytes;
- }
- if (need_zero_guard
- && (count < (unsigned HOST_WIDE_INT) size_needed
- || (align_bytes == 0
- && count < ((unsigned HOST_WIDE_INT) size_needed
- + desired_align - align))))
- {
- /* It is possible that we copied enough so the main loop will not
- execute. */
- gcc_assert (size_needed > 1);
- if (label == NULL_RTX)
- label = gen_label_rtx ();
- emit_cmp_and_jump_insns (count_exp,
- GEN_INT (size_needed),
- LTU, 0, counter_mode (count_exp), 1, label);
- if (expected_size == -1
- || expected_size < (desired_align - align) / 2 + size_needed)
- predict_jump (REG_BR_PROB_BASE * 20 / 100);
- else
- predict_jump (REG_BR_PROB_BASE * 60 / 100);
- }
- }
- if (label && size_needed == 1)
- {
- emit_label (label);
- LABEL_NUSES (label) = 1;
- label = NULL;
- promoted_val = val_exp;
- epilogue_size_needed = 1;
- }
- else if (label == NULL_RTX)
- epilogue_size_needed = size_needed;
-
- /* Step 3: Main loop. */
-
- switch (alg)
- {
- case libcall:
- case no_stringop:
- gcc_unreachable ();
- case loop_1_byte:
- expand_set_or_movmem_via_loop (dst, NULL, destreg, NULL, promoted_val,
- count_exp, QImode, 1, expected_size);
- break;
- case loop:
- expand_set_or_movmem_via_loop (dst, NULL, destreg, NULL, promoted_val,
- count_exp, word_mode, 1, expected_size);
- break;
- case unrolled_loop:
- expand_set_or_movmem_via_loop (dst, NULL, destreg, NULL, promoted_val,
- count_exp, word_mode, 4, expected_size);
- break;
- case rep_prefix_8_byte:
- expand_setmem_via_rep_stos (dst, destreg, promoted_val, count_exp,
- DImode, val_exp);
- break;
- case rep_prefix_4_byte:
- expand_setmem_via_rep_stos (dst, destreg, promoted_val, count_exp,
- SImode, val_exp);
- break;
- case rep_prefix_1_byte:
- expand_setmem_via_rep_stos (dst, destreg, promoted_val, count_exp,
- QImode, val_exp);
- break;
- }
- /* Adjust properly the offset of src and dest memory for aliasing. */
- if (CONST_INT_P (count_exp))
- dst = adjust_automodify_address_nv (dst, BLKmode, destreg,
- (count / size_needed) * size_needed);
- else
- dst = change_address (dst, BLKmode, destreg);
-
- /* Step 4: Epilogue to copy the remaining bytes. */
-
- if (label)
- {
- /* When the main loop is done, COUNT_EXP might hold original count,
- while we want to copy only COUNT_EXP & SIZE_NEEDED bytes.
- Epilogue code will actually copy COUNT_EXP & EPILOGUE_SIZE_NEEDED
- bytes. Compensate if needed. */
-
- if (size_needed < epilogue_size_needed)
- {
- tmp =
- expand_simple_binop (counter_mode (count_exp), AND, count_exp,
- GEN_INT (size_needed - 1), count_exp, 1,
- OPTAB_DIRECT);
- if (tmp != count_exp)
- emit_move_insn (count_exp, tmp);
- }
- emit_label (label);
- LABEL_NUSES (label) = 1;
- }
- epilogue:
- if (count_exp != const0_rtx && epilogue_size_needed > 1)
- {
- if (force_loopy_epilogue)
- expand_setmem_epilogue_via_loop (dst, destreg, val_exp, count_exp,
- epilogue_size_needed);
- else
- expand_setmem_epilogue (dst, destreg, promoted_val, count_exp,
- epilogue_size_needed);
- }
- if (jump_around_label)
- emit_label (jump_around_label);
- return true;
-}
-
-/* Expand the appropriate insns for doing strlen if not just doing
- repnz; scasb
-
- out = result, initialized with the start address
- align_rtx = alignment of the address.
- scratch = scratch register, initialized with the startaddress when
- not aligned, otherwise undefined
-
- This is just the body. It needs the initializations mentioned above and
- some address computing at the end. These things are done in i386.md. */
-
-static void
-ix86_expand_strlensi_unroll_1 (rtx out, rtx src, rtx align_rtx)
-{
- int align;
- rtx tmp;
- rtx align_2_label = NULL_RTX;
- rtx align_3_label = NULL_RTX;
- rtx align_4_label = gen_label_rtx ();
- rtx end_0_label = gen_label_rtx ();
- rtx mem;
- rtx tmpreg = gen_reg_rtx (SImode);
- rtx scratch = gen_reg_rtx (SImode);
- rtx cmp;
-
- align = 0;
- if (CONST_INT_P (align_rtx))
- align = INTVAL (align_rtx);
-
- /* Loop to check 1..3 bytes for null to get an aligned pointer. */
-
- /* Is there a known alignment and is it less than 4? */
- if (align < 4)
- {
- rtx scratch1 = gen_reg_rtx (Pmode);
- emit_move_insn (scratch1, out);
- /* Is there a known alignment and is it not 2? */
- if (align != 2)
- {
- align_3_label = gen_label_rtx (); /* Label when aligned to 3-byte */
- align_2_label = gen_label_rtx (); /* Label when aligned to 2-byte */
-
- /* Leave just the 3 lower bits. */
- align_rtx = expand_binop (Pmode, and_optab, scratch1, GEN_INT (3),
- NULL_RTX, 0, OPTAB_WIDEN);
-
- emit_cmp_and_jump_insns (align_rtx, const0_rtx, EQ, NULL,
- Pmode, 1, align_4_label);
- emit_cmp_and_jump_insns (align_rtx, const2_rtx, EQ, NULL,
- Pmode, 1, align_2_label);
- emit_cmp_and_jump_insns (align_rtx, const2_rtx, GTU, NULL,
- Pmode, 1, align_3_label);
- }
- else
- {
- /* Since the alignment is 2, we have to check 2 or 0 bytes;
- check if is aligned to 4 - byte. */
-
- align_rtx = expand_binop (Pmode, and_optab, scratch1, const2_rtx,
- NULL_RTX, 0, OPTAB_WIDEN);
-
- emit_cmp_and_jump_insns (align_rtx, const0_rtx, EQ, NULL,
- Pmode, 1, align_4_label);
- }
-
- mem = change_address (src, QImode, out);
-
- /* Now compare the bytes. */
-
- /* Compare the first n unaligned byte on a byte per byte basis. */
- emit_cmp_and_jump_insns (mem, const0_rtx, EQ, NULL,
- QImode, 1, end_0_label);
-
- /* Increment the address. */
- emit_insn (ix86_gen_add3 (out, out, const1_rtx));
-
- /* Not needed with an alignment of 2 */
- if (align != 2)
- {
- emit_label (align_2_label);
-
- emit_cmp_and_jump_insns (mem, const0_rtx, EQ, NULL, QImode, 1,
- end_0_label);
-
- emit_insn (ix86_gen_add3 (out, out, const1_rtx));
-
- emit_label (align_3_label);
- }
-
- emit_cmp_and_jump_insns (mem, const0_rtx, EQ, NULL, QImode, 1,
- end_0_label);
-
- emit_insn (ix86_gen_add3 (out, out, const1_rtx));
- }
-
- /* Generate loop to check 4 bytes at a time. It is not a good idea to
- align this loop. It gives only huge programs, but does not help to
- speed up. */
- emit_label (align_4_label);
-
- mem = change_address (src, SImode, out);
- emit_move_insn (scratch, mem);
- emit_insn (ix86_gen_add3 (out, out, GEN_INT (4)));
-
- /* This formula yields a nonzero result iff one of the bytes is zero.
- This saves three branches inside loop and many cycles. */
-
- emit_insn (gen_addsi3 (tmpreg, scratch, GEN_INT (-0x01010101)));
- emit_insn (gen_one_cmplsi2 (scratch, scratch));
- emit_insn (gen_andsi3 (tmpreg, tmpreg, scratch));
- emit_insn (gen_andsi3 (tmpreg, tmpreg,
- gen_int_mode (0x80808080, SImode)));
- emit_cmp_and_jump_insns (tmpreg, const0_rtx, EQ, 0, SImode, 1,
- align_4_label);
-
- if (TARGET_CMOVE)
- {
- rtx reg = gen_reg_rtx (SImode);
- rtx reg2 = gen_reg_rtx (Pmode);
- emit_move_insn (reg, tmpreg);
- emit_insn (gen_lshrsi3 (reg, reg, GEN_INT (16)));
-
- /* If zero is not in the first two bytes, move two bytes forward. */
- emit_insn (gen_testsi_ccno_1 (tmpreg, GEN_INT (0x8080)));
- tmp = gen_rtx_REG (CCNOmode, FLAGS_REG);
- tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
- emit_insn (gen_rtx_SET (VOIDmode, tmpreg,
- gen_rtx_IF_THEN_ELSE (SImode, tmp,
- reg,
- tmpreg)));
- /* Emit lea manually to avoid clobbering of flags. */
- emit_insn (gen_rtx_SET (SImode, reg2,
- gen_rtx_PLUS (Pmode, out, const2_rtx)));
-
- tmp = gen_rtx_REG (CCNOmode, FLAGS_REG);
- tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
- emit_insn (gen_rtx_SET (VOIDmode, out,
- gen_rtx_IF_THEN_ELSE (Pmode, tmp,
- reg2,
- out)));
- }
- else
- {
- rtx end_2_label = gen_label_rtx ();
- /* Is zero in the first two bytes? */
-
- emit_insn (gen_testsi_ccno_1 (tmpreg, GEN_INT (0x8080)));
- tmp = gen_rtx_REG (CCNOmode, FLAGS_REG);
- tmp = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
- tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
- gen_rtx_LABEL_REF (VOIDmode, end_2_label),
- pc_rtx);
- tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
- JUMP_LABEL (tmp) = end_2_label;
-
- /* Not in the first two. Move two bytes forward. */
- emit_insn (gen_lshrsi3 (tmpreg, tmpreg, GEN_INT (16)));
- emit_insn (ix86_gen_add3 (out, out, const2_rtx));
-
- emit_label (end_2_label);
-
- }
-
- /* Avoid branch in fixing the byte. */
- tmpreg = gen_lowpart (QImode, tmpreg);
- emit_insn (gen_addqi3_cc (tmpreg, tmpreg, tmpreg));
- tmp = gen_rtx_REG (CCmode, FLAGS_REG);
- cmp = gen_rtx_LTU (VOIDmode, tmp, const0_rtx);
- emit_insn (ix86_gen_sub3_carry (out, out, GEN_INT (3), tmp, cmp));
-
- emit_label (end_0_label);
-}
-
-/* Expand strlen. */
-
-bool
-ix86_expand_strlen (rtx out, rtx src, rtx eoschar, rtx align)
-{
- rtx addr, scratch1, scratch2, scratch3, scratch4;
-
- /* The generic case of strlen expander is long. Avoid it's
- expanding unless TARGET_INLINE_ALL_STRINGOPS. */
-
- if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
- && !TARGET_INLINE_ALL_STRINGOPS
- && !optimize_insn_for_size_p ()
- && (!CONST_INT_P (align) || INTVAL (align) < 4))
- return false;
-
- addr = force_reg (Pmode, XEXP (src, 0));
- scratch1 = gen_reg_rtx (Pmode);
-
- if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
- && !optimize_insn_for_size_p ())
- {
- /* Well it seems that some optimizer does not combine a call like
- foo(strlen(bar), strlen(bar));
- when the move and the subtraction is done here. It does calculate
- the length just once when these instructions are done inside of
- output_strlen_unroll(). But I think since &bar[strlen(bar)] is
- often used and I use one fewer register for the lifetime of
- output_strlen_unroll() this is better. */
-
- emit_move_insn (out, addr);
-
- ix86_expand_strlensi_unroll_1 (out, src, align);
-
- /* strlensi_unroll_1 returns the address of the zero at the end of
- the string, like memchr(), so compute the length by subtracting
- the start address. */
- emit_insn (ix86_gen_sub3 (out, out, addr));
- }
- else
- {
- rtx unspec;
-
- /* Can't use this if the user has appropriated eax, ecx, or edi. */
- if (fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
- return false;
-
- scratch2 = gen_reg_rtx (Pmode);
- scratch3 = gen_reg_rtx (Pmode);
- scratch4 = force_reg (Pmode, constm1_rtx);
-
- emit_move_insn (scratch3, addr);
- eoschar = force_reg (QImode, eoschar);
-
- src = replace_equiv_address_nv (src, scratch3);
-
- /* If .md starts supporting :P, this can be done in .md. */
- unspec = gen_rtx_UNSPEC (Pmode, gen_rtvec (4, src, eoschar, align,
- scratch4), UNSPEC_SCAS);
- emit_insn (gen_strlenqi_1 (scratch1, scratch3, unspec));
- emit_insn (ix86_gen_one_cmpl2 (scratch2, scratch1));
- emit_insn (ix86_gen_add3 (out, scratch2, constm1_rtx));
- }
- return true;
-}
-
-/* For given symbol (function) construct code to compute address of it's PLT
- entry in large x86-64 PIC model. */
-static rtx
-construct_plt_address (rtx symbol)
-{
- rtx tmp, unspec;
-
- gcc_assert (GET_CODE (symbol) == SYMBOL_REF);
- gcc_assert (ix86_cmodel == CM_LARGE_PIC);
- gcc_assert (Pmode == DImode);
-
- tmp = gen_reg_rtx (Pmode);
- unspec = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol), UNSPEC_PLTOFF);
-
- emit_move_insn (tmp, gen_rtx_CONST (Pmode, unspec));
- emit_insn (ix86_gen_add3 (tmp, tmp, pic_offset_table_rtx));
- return tmp;
-}
-
-rtx
-ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
- rtx callarg2,
- rtx pop, bool sibcall)
-{
- /* We need to represent that SI and DI registers are clobbered
- by SYSV calls. */
- static int clobbered_registers[] = {
- XMM6_REG, XMM7_REG, XMM8_REG,
- XMM9_REG, XMM10_REG, XMM11_REG,
- XMM12_REG, XMM13_REG, XMM14_REG,
- XMM15_REG, SI_REG, DI_REG
- };
- rtx vec[ARRAY_SIZE (clobbered_registers) + 3];
- rtx use = NULL, call;
- unsigned int vec_len;
-
- if (pop == const0_rtx)
- pop = NULL;
- gcc_assert (!TARGET_64BIT || !pop);
-
- if (TARGET_MACHO && !TARGET_64BIT)
- {
-#if TARGET_MACHO
- if (flag_pic && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF)
- fnaddr = machopic_indirect_call_target (fnaddr);
-#endif
- }
- else
- {
- /* Static functions and indirect calls don't need the pic register. */
- if (flag_pic && (!TARGET_64BIT || ix86_cmodel == CM_LARGE_PIC)
- && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF
- && ! SYMBOL_REF_LOCAL_P (XEXP (fnaddr, 0)))
- use_reg (&use, pic_offset_table_rtx);
- }
-
- if (TARGET_64BIT && INTVAL (callarg2) >= 0)
- {
- rtx al = gen_rtx_REG (QImode, AX_REG);
- emit_move_insn (al, callarg2);
- use_reg (&use, al);
- }
-
- if (ix86_cmodel == CM_LARGE_PIC
- && MEM_P (fnaddr)
- && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF
- && !local_symbolic_operand (XEXP (fnaddr, 0), VOIDmode))
- fnaddr = gen_rtx_MEM (QImode, construct_plt_address (XEXP (fnaddr, 0)));
- else if (sibcall
- ? !sibcall_insn_operand (XEXP (fnaddr, 0), word_mode)
- : !call_insn_operand (XEXP (fnaddr, 0), word_mode))
- {
- fnaddr = convert_to_mode (word_mode, XEXP (fnaddr, 0), 1);
- fnaddr = gen_rtx_MEM (QImode, copy_to_mode_reg (word_mode, fnaddr));
- }
-
- vec_len = 0;
- call = gen_rtx_CALL (VOIDmode, fnaddr, callarg1);
- if (retval)
- call = gen_rtx_SET (VOIDmode, retval, call);
- vec[vec_len++] = call;
-
- if (pop)
- {
- pop = gen_rtx_PLUS (Pmode, stack_pointer_rtx, pop);
- pop = gen_rtx_SET (VOIDmode, stack_pointer_rtx, pop);
- vec[vec_len++] = pop;
- }
-
- if (TARGET_64BIT_MS_ABI
- && (!callarg2 || INTVAL (callarg2) != -2))
- {
- unsigned i;
-
- vec[vec_len++] = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, const0_rtx),
- UNSPEC_MS_TO_SYSV_CALL);
-
- for (i = 0; i < ARRAY_SIZE (clobbered_registers); i++)
- vec[vec_len++]
- = gen_rtx_CLOBBER (VOIDmode,
- gen_rtx_REG (SSE_REGNO_P (clobbered_registers[i])
- ? TImode : DImode,
- clobbered_registers[i]));
- }
-
- if (vec_len > 1)
- call = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (vec_len, vec));
- call = emit_call_insn (call);
- if (use)
- CALL_INSN_FUNCTION_USAGE (call) = use;
-
- return call;
-}
-
-/* Output the assembly for a call instruction. */
-
-const char *
-ix86_output_call_insn (rtx insn, rtx call_op)
-{
- bool direct_p = constant_call_address_operand (call_op, VOIDmode);
- bool seh_nop_p = false;
- const char *xasm;
-
- if (SIBLING_CALL_P (insn))
- {
- if (direct_p)
- xasm = "jmp\t%P0";
- /* SEH epilogue detection requires the indirect branch case
- to include REX.W. */
- else if (TARGET_SEH)
- xasm = "rex.W jmp %A0";
- else
- xasm = "jmp\t%A0";
-
- output_asm_insn (xasm, &call_op);
- return "";
- }
-
- /* SEH unwinding can require an extra nop to be emitted in several
- circumstances. Determine if we have one of those. */
- if (TARGET_SEH)
- {
- rtx i;
-
- for (i = NEXT_INSN (insn); i ; i = NEXT_INSN (i))
- {
- /* If we get to another real insn, we don't need the nop. */
- if (INSN_P (i))
- break;
-
- /* If we get to the epilogue note, prevent a catch region from
- being adjacent to the standard epilogue sequence. If non-
- call-exceptions, we'll have done this during epilogue emission. */
- if (NOTE_P (i) && NOTE_KIND (i) == NOTE_INSN_EPILOGUE_BEG
- && !flag_non_call_exceptions
- && !can_throw_internal (insn))
- {
- seh_nop_p = true;
- break;
- }
- }
-
- /* If we didn't find a real insn following the call, prevent the
- unwinder from looking into the next function. */
- if (i == NULL)
- seh_nop_p = true;
- }
-
- if (direct_p)
- xasm = "call\t%P0";
- else
- xasm = "call\t%A0";
-
- output_asm_insn (xasm, &call_op);
-
- if (seh_nop_p)
- return "nop";
-
- return "";
-}
-
-/* Clear stack slot assignments remembered from previous functions.
- This is called from INIT_EXPANDERS once before RTL is emitted for each
- function. */
-
-static struct machine_function *
-ix86_init_machine_status (void)
-{
- struct machine_function *f;
-
- f = ggc_alloc_cleared_machine_function ();
- f->use_fast_prologue_epilogue_nregs = -1;
- f->call_abi = ix86_abi;
-
- return f;
-}
-
-/* Return a MEM corresponding to a stack slot with mode MODE.
- Allocate a new slot if necessary.
-
- The RTL for a function can have several slots available: N is
- which slot to use. */
-
-rtx
-assign_386_stack_local (enum machine_mode mode, enum ix86_stack_slot n)
-{
- struct stack_local_entry *s;
-
- gcc_assert (n < MAX_386_STACK_LOCALS);
-
- for (s = ix86_stack_locals; s; s = s->next)
- if (s->mode == mode && s->n == n)
- return validize_mem (copy_rtx (s->rtl));
-
- s = ggc_alloc_stack_local_entry ();
- s->n = n;
- s->mode = mode;
- s->rtl = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
-
- s->next = ix86_stack_locals;
- ix86_stack_locals = s;
- return validize_mem (s->rtl);
-}
-
-static void
-ix86_instantiate_decls (void)
-{
- struct stack_local_entry *s;
-
- for (s = ix86_stack_locals; s; s = s->next)
- if (s->rtl != NULL_RTX)
- instantiate_decl_rtl (s->rtl);
-}
-
-/* Calculate the length of the memory address in the instruction encoding.
- Includes addr32 prefix, does not include the one-byte modrm, opcode,
- or other prefixes. We never generate addr32 prefix for LEA insn. */
-
-int
-memory_address_length (rtx addr, bool lea)
-{
- struct ix86_address parts;
- rtx base, index, disp;
- int len;
- int ok;
-
- if (GET_CODE (addr) == PRE_DEC
- || GET_CODE (addr) == POST_INC
- || GET_CODE (addr) == PRE_MODIFY
- || GET_CODE (addr) == POST_MODIFY)
- return 0;
-
- ok = ix86_decompose_address (addr, &parts);
- gcc_assert (ok);
-
- len = (parts.seg == SEG_DEFAULT) ? 0 : 1;
-
- /* If this is not LEA instruction, add the length of addr32 prefix. */
- if (TARGET_64BIT && !lea
- && (SImode_address_operand (addr, VOIDmode)
- || (parts.base && GET_MODE (parts.base) == SImode)
- || (parts.index && GET_MODE (parts.index) == SImode)))
- len++;
-
- base = parts.base;
- index = parts.index;
- disp = parts.disp;
-
- if (base && GET_CODE (base) == SUBREG)
- base = SUBREG_REG (base);
- if (index && GET_CODE (index) == SUBREG)
- index = SUBREG_REG (index);
-
- gcc_assert (base == NULL_RTX || REG_P (base));
- gcc_assert (index == NULL_RTX || REG_P (index));
-
- /* Rule of thumb:
- - esp as the base always wants an index,
- - ebp as the base always wants a displacement,
- - r12 as the base always wants an index,
- - r13 as the base always wants a displacement. */
-
- /* Register Indirect. */
- if (base && !index && !disp)
- {
- /* esp (for its index) and ebp (for its displacement) need
- the two-byte modrm form. Similarly for r12 and r13 in 64-bit
- code. */
- if (base == arg_pointer_rtx
- || base == frame_pointer_rtx
- || REGNO (base) == SP_REG
- || REGNO (base) == BP_REG
- || REGNO (base) == R12_REG
- || REGNO (base) == R13_REG)
- len++;
- }
-
- /* Direct Addressing. In 64-bit mode mod 00 r/m 5
- is not disp32, but disp32(%rip), so for disp32
- SIB byte is needed, unless print_operand_address
- optimizes it into disp32(%rip) or (%rip) is implied
- by UNSPEC. */
- else if (disp && !base && !index)
- {
- len += 4;
- if (TARGET_64BIT)
- {
- rtx symbol = disp;
-
- if (GET_CODE (disp) == CONST)
- symbol = XEXP (disp, 0);
- if (GET_CODE (symbol) == PLUS
- && CONST_INT_P (XEXP (symbol, 1)))
- symbol = XEXP (symbol, 0);
-
- if (GET_CODE (symbol) != LABEL_REF
- && (GET_CODE (symbol) != SYMBOL_REF
- || SYMBOL_REF_TLS_MODEL (symbol) != 0)
- && (GET_CODE (symbol) != UNSPEC
- || (XINT (symbol, 1) != UNSPEC_GOTPCREL
- && XINT (symbol, 1) != UNSPEC_PCREL
- && XINT (symbol, 1) != UNSPEC_GOTNTPOFF)))
- len++;
- }
- }
- else
- {
- /* Find the length of the displacement constant. */
- if (disp)
- {
- if (base && satisfies_constraint_K (disp))
- len += 1;
- else
- len += 4;
- }
- /* ebp always wants a displacement. Similarly r13. */
- else if (base && (REGNO (base) == BP_REG || REGNO (base) == R13_REG))
- len++;
-
- /* An index requires the two-byte modrm form.... */
- if (index
- /* ...like esp (or r12), which always wants an index. */
- || base == arg_pointer_rtx
- || base == frame_pointer_rtx
- || (base && (REGNO (base) == SP_REG || REGNO (base) == R12_REG)))
- len++;
- }
-
- return len;
-}
-
-/* Compute default value for "length_immediate" attribute. When SHORTFORM
- is set, expect that insn have 8bit immediate alternative. */
-int
-ix86_attr_length_immediate_default (rtx insn, bool shortform)
-{
- int len = 0;
- int i;
- extract_insn_cached (insn);
- for (i = recog_data.n_operands - 1; i >= 0; --i)
- if (CONSTANT_P (recog_data.operand[i]))
- {
- enum attr_mode mode = get_attr_mode (insn);
-
- gcc_assert (!len);
- if (shortform && CONST_INT_P (recog_data.operand[i]))
- {
- HOST_WIDE_INT ival = INTVAL (recog_data.operand[i]);
- switch (mode)
- {
- case MODE_QI:
- len = 1;
- continue;
- case MODE_HI:
- ival = trunc_int_for_mode (ival, HImode);
- break;
- case MODE_SI:
- ival = trunc_int_for_mode (ival, SImode);
- break;
- default:
- break;
- }
- if (IN_RANGE (ival, -128, 127))
- {
- len = 1;
- continue;
- }
- }
- switch (mode)
- {
- case MODE_QI:
- len = 1;
- break;
- case MODE_HI:
- len = 2;
- break;
- case MODE_SI:
- len = 4;
- break;
- /* Immediates for DImode instructions are encoded
- as 32bit sign extended values. */
- case MODE_DI:
- len = 4;
- break;
- default:
- fatal_insn ("unknown insn mode", insn);
- }
- }
- return len;
-}
-
-/* Compute default value for "length_address" attribute. */
-int
-ix86_attr_length_address_default (rtx insn)
-{
- int i;
-
- if (get_attr_type (insn) == TYPE_LEA)
- {
- rtx set = PATTERN (insn), addr;
-
- if (GET_CODE (set) == PARALLEL)
- set = XVECEXP (set, 0, 0);
-
- gcc_assert (GET_CODE (set) == SET);
-
- addr = SET_SRC (set);
-
- return memory_address_length (addr, true);
- }
-
- extract_insn_cached (insn);
- for (i = recog_data.n_operands - 1; i >= 0; --i)
- if (MEM_P (recog_data.operand[i]))
- {
- constrain_operands_cached (reload_completed);
- if (which_alternative != -1)
- {
- const char *constraints = recog_data.constraints[i];
- int alt = which_alternative;
-
- while (*constraints == '=' || *constraints == '+')
- constraints++;
- while (alt-- > 0)
- while (*constraints++ != ',')
- ;
- /* Skip ignored operands. */
- if (*constraints == 'X')
- continue;
- }
- return memory_address_length (XEXP (recog_data.operand[i], 0), false);
- }
- return 0;
-}
-
-/* Compute default value for "length_vex" attribute. It includes
- 2 or 3 byte VEX prefix and 1 opcode byte. */
-
-int
-ix86_attr_length_vex_default (rtx insn, bool has_0f_opcode, bool has_vex_w)
-{
- int i;
-
- /* Only 0f opcode can use 2 byte VEX prefix and VEX W bit uses 3
- byte VEX prefix. */
- if (!has_0f_opcode || has_vex_w)
- return 3 + 1;
-
- /* We can always use 2 byte VEX prefix in 32bit. */
- if (!TARGET_64BIT)
- return 2 + 1;
-
- extract_insn_cached (insn);
-
- for (i = recog_data.n_operands - 1; i >= 0; --i)
- if (REG_P (recog_data.operand[i]))
- {
- /* REX.W bit uses 3 byte VEX prefix. */
- if (GET_MODE (recog_data.operand[i]) == DImode
- && GENERAL_REG_P (recog_data.operand[i]))
- return 3 + 1;
- }
- else
- {
- /* REX.X or REX.B bits use 3 byte VEX prefix. */
- if (MEM_P (recog_data.operand[i])
- && x86_extended_reg_mentioned_p (recog_data.operand[i]))
- return 3 + 1;
- }
-
- return 2 + 1;
-}
-
-/* Return the maximum number of instructions a cpu can issue. */
-
-static int
-ix86_issue_rate (void)
-{
- switch (ix86_tune)
- {
- case PROCESSOR_PENTIUM:
- case PROCESSOR_ATOM:
- case PROCESSOR_SLM:
- case PROCESSOR_K6:
- case PROCESSOR_BTVER2:
- return 2;
-
- case PROCESSOR_PENTIUMPRO:
- case PROCESSOR_PENTIUM4:
- case PROCESSOR_CORE2:
- case PROCESSOR_COREI7:
- case PROCESSOR_HASWELL:
- case PROCESSOR_ATHLON:
- case PROCESSOR_K8:
- case PROCESSOR_AMDFAM10:
- case PROCESSOR_NOCONA:
- case PROCESSOR_GENERIC32:
- case PROCESSOR_GENERIC64:
- case PROCESSOR_BDVER1:
- case PROCESSOR_BDVER2:
- case PROCESSOR_BDVER3:
- case PROCESSOR_BTVER1:
- return 3;
-
- default:
- return 1;
- }
-}
-
-/* A subroutine of ix86_adjust_cost -- return TRUE iff INSN reads flags set
- by DEP_INSN and nothing set by DEP_INSN. */
-
-static bool
-ix86_flags_dependent (rtx insn, rtx dep_insn, enum attr_type insn_type)
-{
- rtx set, set2;
-
- /* Simplify the test for uninteresting insns. */
- if (insn_type != TYPE_SETCC
- && insn_type != TYPE_ICMOV
- && insn_type != TYPE_FCMOV
- && insn_type != TYPE_IBR)
- return false;
-
- if ((set = single_set (dep_insn)) != 0)
- {
- set = SET_DEST (set);
- set2 = NULL_RTX;
- }
- else if (GET_CODE (PATTERN (dep_insn)) == PARALLEL
- && XVECLEN (PATTERN (dep_insn), 0) == 2
- && GET_CODE (XVECEXP (PATTERN (dep_insn), 0, 0)) == SET
- && GET_CODE (XVECEXP (PATTERN (dep_insn), 0, 1)) == SET)
- {
- set = SET_DEST (XVECEXP (PATTERN (dep_insn), 0, 0));
- set2 = SET_DEST (XVECEXP (PATTERN (dep_insn), 0, 0));
- }
- else
- return false;
-
- if (!REG_P (set) || REGNO (set) != FLAGS_REG)
- return false;
-
- /* This test is true if the dependent insn reads the flags but
- not any other potentially set register. */
- if (!reg_overlap_mentioned_p (set, PATTERN (insn)))
- return false;
-
- if (set2 && reg_overlap_mentioned_p (set2, PATTERN (insn)))
- return false;
-
- return true;
-}
-
-/* Return true iff USE_INSN has a memory address with operands set by
- SET_INSN. */
-
-bool
-ix86_agi_dependent (rtx set_insn, rtx use_insn)
-{
- int i;
- extract_insn_cached (use_insn);
- for (i = recog_data.n_operands - 1; i >= 0; --i)
- if (MEM_P (recog_data.operand[i]))
- {
- rtx addr = XEXP (recog_data.operand[i], 0);
- return modified_in_p (addr, set_insn) != 0;
- }
- return false;
-}
-
-/* Helper function for exact_store_load_dependency.
- Return true if addr is found in insn. */
-static bool
-exact_dependency_1 (rtx addr, rtx insn)
-{
- enum rtx_code code;
- const char *format_ptr;
- int i, j;
-
- code = GET_CODE (insn);
- switch (code)
- {
- case MEM:
- if (rtx_equal_p (addr, insn))
- return true;
- break;
- case REG:
- CASE_CONST_ANY:
- case SYMBOL_REF:
- case CODE_LABEL:
- case PC:
- case CC0:
- case EXPR_LIST:
- return false;
- default:
- break;
- }
-
- format_ptr = GET_RTX_FORMAT (code);
- for (i = 0; i < GET_RTX_LENGTH (code); i++)
- {
- switch (*format_ptr++)
- {
- case 'e':
- if (exact_dependency_1 (addr, XEXP (insn, i)))
- return true;
- break;
- case 'E':
- for (j = 0; j < XVECLEN (insn, i); j++)
- if (exact_dependency_1 (addr, XVECEXP (insn, i, j)))
- return true;
- break;
- }
- }
- return false;
-}
-
-/* Return true if there exists exact dependency for store & load, i.e.
- the same memory address is used in them. */
-static bool
-exact_store_load_dependency (rtx store, rtx load)
-{
- rtx set1, set2;
-
- set1 = single_set (store);
- if (!set1)
- return false;
- if (!MEM_P (SET_DEST (set1)))
- return false;
- set2 = single_set (load);
- if (!set2)
- return false;
- if (exact_dependency_1 (SET_DEST (set1), SET_SRC (set2)))
- return true;
- return false;
-}
-
-static int
-ix86_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
-{
- enum attr_type insn_type, dep_insn_type;
- enum attr_memory memory;
- rtx set, set2;
- int dep_insn_code_number;
-
- /* Anti and output dependencies have zero cost on all CPUs. */
- if (REG_NOTE_KIND (link) != 0)
- return 0;
-
- dep_insn_code_number = recog_memoized (dep_insn);
-
- /* If we can't recognize the insns, we can't really do anything. */
- if (dep_insn_code_number < 0 || recog_memoized (insn) < 0)
- return cost;
-
- insn_type = get_attr_type (insn);
- dep_insn_type = get_attr_type (dep_insn);
-
- switch (ix86_tune)
- {
- case PROCESSOR_PENTIUM:
- /* Address Generation Interlock adds a cycle of latency. */
- if (insn_type == TYPE_LEA)
- {
- rtx addr = PATTERN (insn);
-
- if (GET_CODE (addr) == PARALLEL)
- addr = XVECEXP (addr, 0, 0);
-
- gcc_assert (GET_CODE (addr) == SET);
-
- addr = SET_SRC (addr);
- if (modified_in_p (addr, dep_insn))
- cost += 1;
- }
- else if (ix86_agi_dependent (dep_insn, insn))
- cost += 1;
-
- /* ??? Compares pair with jump/setcc. */
- if (ix86_flags_dependent (insn, dep_insn, insn_type))
- cost = 0;
-
- /* Floating point stores require value to be ready one cycle earlier. */
- if (insn_type == TYPE_FMOV
- && get_attr_memory (insn) == MEMORY_STORE
- && !ix86_agi_dependent (dep_insn, insn))
- cost += 1;
- break;
-
- case PROCESSOR_PENTIUMPRO:
- memory = get_attr_memory (insn);
-
- /* INT->FP conversion is expensive. */
- if (get_attr_fp_int_src (dep_insn))
- cost += 5;
-
- /* There is one cycle extra latency between an FP op and a store. */
- if (insn_type == TYPE_FMOV
- && (set = single_set (dep_insn)) != NULL_RTX
- && (set2 = single_set (insn)) != NULL_RTX
- && rtx_equal_p (SET_DEST (set), SET_SRC (set2))
- && MEM_P (SET_DEST (set2)))
- cost += 1;
-
- /* Show ability of reorder buffer to hide latency of load by executing
- in parallel with previous instruction in case
- previous instruction is not needed to compute the address. */
- if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
- && !ix86_agi_dependent (dep_insn, insn))
- {
- /* Claim moves to take one cycle, as core can issue one load
- at time and the next load can start cycle later. */
- if (dep_insn_type == TYPE_IMOV
- || dep_insn_type == TYPE_FMOV)
- cost = 1;
- else if (cost > 1)
- cost--;
- }
- break;
-
- case PROCESSOR_K6:
- memory = get_attr_memory (insn);
-
- /* The esp dependency is resolved before the instruction is really
- finished. */
- if ((insn_type == TYPE_PUSH || insn_type == TYPE_POP)
- && (dep_insn_type == TYPE_PUSH || dep_insn_type == TYPE_POP))
- return 1;
-
- /* INT->FP conversion is expensive. */
- if (get_attr_fp_int_src (dep_insn))
- cost += 5;
-
- /* Show ability of reorder buffer to hide latency of load by executing
- in parallel with previous instruction in case
- previous instruction is not needed to compute the address. */
- if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
- && !ix86_agi_dependent (dep_insn, insn))
- {
- /* Claim moves to take one cycle, as core can issue one load
- at time and the next load can start cycle later. */
- if (dep_insn_type == TYPE_IMOV
- || dep_insn_type == TYPE_FMOV)
- cost = 1;
- else if (cost > 2)
- cost -= 2;
- else
- cost = 1;
- }
- break;
-
- case PROCESSOR_ATHLON:
- case PROCESSOR_K8:
- case PROCESSOR_AMDFAM10:
- case PROCESSOR_BDVER1:
- case PROCESSOR_BDVER2:
- case PROCESSOR_BDVER3:
- case PROCESSOR_BTVER1:
- case PROCESSOR_BTVER2:
- case PROCESSOR_ATOM:
- case PROCESSOR_GENERIC32:
- case PROCESSOR_GENERIC64:
- memory = get_attr_memory (insn);
-
- /* Show ability of reorder buffer to hide latency of load by executing
- in parallel with previous instruction in case
- previous instruction is not needed to compute the address. */
- if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
- && !ix86_agi_dependent (dep_insn, insn))
- {
- enum attr_unit unit = get_attr_unit (insn);
- int loadcost = 3;
-
- /* Because of the difference between the length of integer and
- floating unit pipeline preparation stages, the memory operands
- for floating point are cheaper.
-
- ??? For Athlon it the difference is most probably 2. */
- if (unit == UNIT_INTEGER || unit == UNIT_UNKNOWN)
- loadcost = 3;
- else
- loadcost = TARGET_ATHLON ? 2 : 0;
-
- if (cost >= loadcost)
- cost -= loadcost;
- else
- cost = 0;
- }
- break;
-
- case PROCESSOR_SLM:
- if (!reload_completed)
- return cost;
-
- /* Increase cost of integer loads. */
- memory = get_attr_memory (dep_insn);
- if (memory == MEMORY_LOAD || memory == MEMORY_BOTH)
- {
- enum attr_unit unit = get_attr_unit (dep_insn);
- if (unit == UNIT_INTEGER && cost == 1)
- {
- if (memory == MEMORY_LOAD)
- cost = 3;
- else
- {
- /* Increase cost of ld/st for short int types only
- because of store forwarding issue. */
- rtx set = single_set (dep_insn);
- if (set && (GET_MODE (SET_DEST (set)) == QImode
- || GET_MODE (SET_DEST (set)) == HImode))
- {
- /* Increase cost of store/load insn if exact
- dependence exists and it is load insn. */
- enum attr_memory insn_memory = get_attr_memory (insn);
- if (insn_memory == MEMORY_LOAD
- && exact_store_load_dependency (dep_insn, insn))
- cost = 3;
- }
- }
- }
- }
-
- default:
- break;
- }
-
- return cost;
-}
-
-/* How many alternative schedules to try. This should be as wide as the
- scheduling freedom in the DFA, but no wider. Making this value too
- large results extra work for the scheduler. */
-
-static int
-ia32_multipass_dfa_lookahead (void)
-{
- switch (ix86_tune)
- {
- case PROCESSOR_PENTIUM:
- return 2;
-
- case PROCESSOR_PENTIUMPRO:
- case PROCESSOR_K6:
- return 1;
-
- case PROCESSOR_CORE2:
- case PROCESSOR_COREI7:
- case PROCESSOR_HASWELL:
- case PROCESSOR_ATOM:
- case PROCESSOR_SLM:
- /* Generally, we want haifa-sched:max_issue() to look ahead as far
- as many instructions can be executed on a cycle, i.e.,
- issue_rate. I wonder why tuning for many CPUs does not do this. */
- if (reload_completed)
- return ix86_issue_rate ();
- /* Don't use lookahead for pre-reload schedule to save compile time. */
- return 0;
-
- default:
- return 0;
- }
-}
-
-/* Try to reorder ready list to take advantage of Atom pipelined IMUL
- execution. It is applied if
- (1) IMUL instruction is on the top of list;
- (2) There exists the only producer of independent IMUL instruction in
- ready list.
- Return index of IMUL producer if it was found and -1 otherwise. */
-static int
-do_reorder_for_imul (rtx *ready, int n_ready)
-{
- rtx insn, set, insn1, insn2;
- sd_iterator_def sd_it;
- dep_t dep;
- int index = -1;
- int i;
-
- if (ix86_tune != PROCESSOR_ATOM)
- return index;
-
- /* Check that IMUL instruction is on the top of ready list. */
- insn = ready[n_ready - 1];
- set = single_set (insn);
- if (!set)
- return index;
- if (!(GET_CODE (SET_SRC (set)) == MULT
- && GET_MODE (SET_SRC (set)) == SImode))
- return index;
-
- /* Search for producer of independent IMUL instruction. */
- for (i = n_ready - 2; i >= 0; i--)
- {
- insn = ready[i];
- if (!NONDEBUG_INSN_P (insn))
- continue;
- /* Skip IMUL instruction. */
- insn2 = PATTERN (insn);
- if (GET_CODE (insn2) == PARALLEL)
- insn2 = XVECEXP (insn2, 0, 0);
- if (GET_CODE (insn2) == SET
- && GET_CODE (SET_SRC (insn2)) == MULT
- && GET_MODE (SET_SRC (insn2)) == SImode)
- continue;
-
- FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
- {
- rtx con;
- con = DEP_CON (dep);
- if (!NONDEBUG_INSN_P (con))
- continue;
- insn1 = PATTERN (con);
- if (GET_CODE (insn1) == PARALLEL)
- insn1 = XVECEXP (insn1, 0, 0);
-
- if (GET_CODE (insn1) == SET
- && GET_CODE (SET_SRC (insn1)) == MULT
- && GET_MODE (SET_SRC (insn1)) == SImode)
- {
- sd_iterator_def sd_it1;
- dep_t dep1;
- /* Check if there is no other dependee for IMUL. */
- index = i;
- FOR_EACH_DEP (con, SD_LIST_BACK, sd_it1, dep1)
- {
- rtx pro;
- pro = DEP_PRO (dep1);
- if (!NONDEBUG_INSN_P (pro))
- continue;
- if (pro != insn)
- index = -1;
- }
- if (index >= 0)
- break;
- }
- }
- if (index >= 0)
- break;
- }
- return index;
-}
-
-/* Try to find the best candidate on the top of ready list if two insns
- have the same priority - candidate is best if its dependees were
- scheduled earlier. Applied for Silvermont only.
- Return true if top 2 insns must be interchanged. */
-static bool
-swap_top_of_ready_list (rtx *ready, int n_ready)
-{
- rtx top = ready[n_ready - 1];
- rtx next = ready[n_ready - 2];
- rtx set;
- sd_iterator_def sd_it;
- dep_t dep;
- int clock1 = -1;
- int clock2 = -1;
- #define INSN_TICK(INSN) (HID (INSN)->tick)
-
- if (ix86_tune != PROCESSOR_SLM)
- return false;
-
- if (!NONDEBUG_INSN_P (top))
- return false;
- if (!NONJUMP_INSN_P (top))
- return false;
- if (!NONDEBUG_INSN_P (next))
- return false;
- if (!NONJUMP_INSN_P (next))
- return false;
- set = single_set (top);
- if (!set)
- return false;
- set = single_set (next);
- if (!set)
- return false;
-
- if (INSN_PRIORITY_KNOWN (top) && INSN_PRIORITY_KNOWN (next))
- {
- if (INSN_PRIORITY (top) != INSN_PRIORITY (next))
- return false;
- /* Determine winner more precise. */
- FOR_EACH_DEP (top, SD_LIST_RES_BACK, sd_it, dep)
- {
- rtx pro;
- pro = DEP_PRO (dep);
- if (!NONDEBUG_INSN_P (pro))
- continue;
- if (INSN_TICK (pro) > clock1)
- clock1 = INSN_TICK (pro);
- }
- FOR_EACH_DEP (next, SD_LIST_RES_BACK, sd_it, dep)
- {
- rtx pro;
- pro = DEP_PRO (dep);
- if (!NONDEBUG_INSN_P (pro))
- continue;
- if (INSN_TICK (pro) > clock2)
- clock2 = INSN_TICK (pro);
- }
-
- if (clock1 == clock2)
- {
- /* Determine winner - load must win. */
- enum attr_memory memory1, memory2;
- memory1 = get_attr_memory (top);
- memory2 = get_attr_memory (next);
- if (memory2 == MEMORY_LOAD && memory1 != MEMORY_LOAD)
- return true;
- }
- return (bool) (clock2 < clock1);
- }
- return false;
- #undef INSN_TICK
-}
-
-/* Perform possible reodering of ready list for Atom/Silvermont only.
- Return issue rate. */
-static int
-ix86_sched_reorder (FILE *dump, int sched_verbose, rtx *ready, int *pn_ready,
- int clock_var)
-{
- int issue_rate = -1;
- int n_ready = *pn_ready;
- int i;
- rtx insn;
- int index = -1;
-
- /* Set up issue rate. */
- issue_rate = ix86_issue_rate ();
-
- /* Do reodering for Atom/SLM only. */
- if (ix86_tune != PROCESSOR_ATOM && ix86_tune != PROCESSOR_SLM)
- return issue_rate;
-
- /* Nothing to do if ready list contains only 1 instruction. */
- if (n_ready <= 1)
- return issue_rate;
-
- /* Do reodering for post-reload scheduler only. */
- if (!reload_completed)
- return issue_rate;
-
- if ((index = do_reorder_for_imul (ready, n_ready)) >= 0)
- {
- if (sched_verbose > 1)
- fprintf (dump, ";;\tatom sched_reorder: put %d insn on top\n",
- INSN_UID (ready[index]));
-
- /* Put IMUL producer (ready[index]) at the top of ready list. */
- insn = ready[index];
- for (i = index; i < n_ready - 1; i++)
- ready[i] = ready[i + 1];
- ready[n_ready - 1] = insn;
- return issue_rate;
- }
- if (clock_var != 0 && swap_top_of_ready_list (ready, n_ready))
- {
- if (sched_verbose > 1)
- fprintf (dump, ";;\tslm sched_reorder: swap %d and %d insns\n",
- INSN_UID (ready[n_ready - 1]), INSN_UID (ready[n_ready - 2]));
- /* Swap 2 top elements of ready list. */
- insn = ready[n_ready - 1];
- ready[n_ready - 1] = ready[n_ready - 2];
- ready[n_ready - 2] = insn;
- }
- return issue_rate;
-}
-
-static bool
-ix86_class_likely_spilled_p (reg_class_t);
-
-/* Returns true if lhs of insn is HW function argument register and set up
- is_spilled to true if it is likely spilled HW register. */
-static bool
-insn_is_function_arg (rtx insn, bool* is_spilled)
-{
- rtx dst;
-
- if (!NONDEBUG_INSN_P (insn))
- return false;
- /* Call instructions are not movable, ignore it. */
- if (CALL_P (insn))
- return false;
- insn = PATTERN (insn);
- if (GET_CODE (insn) == PARALLEL)
- insn = XVECEXP (insn, 0, 0);
- if (GET_CODE (insn) != SET)
- return false;
- dst = SET_DEST (insn);
- if (REG_P (dst) && HARD_REGISTER_P (dst)
- && ix86_function_arg_regno_p (REGNO (dst)))
- {
- /* Is it likely spilled HW register? */
- if (!TEST_HARD_REG_BIT (fixed_reg_set, REGNO (dst))
- && ix86_class_likely_spilled_p (REGNO_REG_CLASS (REGNO (dst))))
- *is_spilled = true;
- return true;
- }
- return false;
-}
-
-/* Add output dependencies for chain of function adjacent arguments if only
- there is a move to likely spilled HW register. Return first argument
- if at least one dependence was added or NULL otherwise. */
-static rtx
-add_parameter_dependencies (rtx call, rtx head)
-{
- rtx insn;
- rtx last = call;
- rtx first_arg = NULL;
- bool is_spilled = false;
-
- head = PREV_INSN (head);
-
- /* Find nearest to call argument passing instruction. */
- while (true)
- {
- last = PREV_INSN (last);
- if (last == head)
- return NULL;
- if (!NONDEBUG_INSN_P (last))
- continue;
- if (insn_is_function_arg (last, &is_spilled))
- break;
- return NULL;
- }
-
- first_arg = last;
- while (true)
- {
- insn = PREV_INSN (last);
- if (!INSN_P (insn))
- break;
- if (insn == head)
- break;
- if (!NONDEBUG_INSN_P (insn))
- {
- last = insn;
- continue;
- }
- if (insn_is_function_arg (insn, &is_spilled))
- {
- /* Add output depdendence between two function arguments if chain
- of output arguments contains likely spilled HW registers. */
- if (is_spilled)
- add_dependence (first_arg, insn, REG_DEP_OUTPUT);
- first_arg = last = insn;
- }
- else
- break;
- }
- if (!is_spilled)
- return NULL;
- return first_arg;
-}
-
-/* Add output or anti dependency from insn to first_arg to restrict its code
- motion. */
-static void
-avoid_func_arg_motion (rtx first_arg, rtx insn)
-{
- rtx set;
- rtx tmp;
-
- set = single_set (insn);
- if (!set)
- return;
- tmp = SET_DEST (set);
- if (REG_P (tmp))
- {
- /* Add output dependency to the first function argument. */
- add_dependence (first_arg, insn, REG_DEP_OUTPUT);
- return;
- }
- /* Add anti dependency. */
- add_dependence (first_arg, insn, REG_DEP_ANTI);
-}
-
-/* Avoid cross block motion of function argument through adding dependency
- from the first non-jump instruction in bb. */
-static void
-add_dependee_for_func_arg (rtx arg, basic_block bb)
-{
- rtx insn = BB_END (bb);
-
- while (insn)
- {
- if (NONDEBUG_INSN_P (insn) && NONJUMP_INSN_P (insn))
- {
- rtx set = single_set (insn);
- if (set)
- {
- avoid_func_arg_motion (arg, insn);
- return;
- }
- }
- if (insn == BB_HEAD (bb))
- return;
- insn = PREV_INSN (insn);
- }
-}
-
-/* Hook for pre-reload schedule - avoid motion of function arguments
- passed in likely spilled HW registers. */
-static void
-ix86_dependencies_evaluation_hook (rtx head, rtx tail)
-{
- rtx insn;
- rtx first_arg = NULL;
- if (reload_completed)
- return;
- while (head != tail && DEBUG_INSN_P (head))
- head = NEXT_INSN (head);
- for (insn = tail; insn != head; insn = PREV_INSN (insn))
- if (INSN_P (insn) && CALL_P (insn))
- {
- first_arg = add_parameter_dependencies (insn, head);
- if (first_arg)
- {
- /* Add dependee for first argument to predecessors if only
- region contains more than one block. */
- basic_block bb = BLOCK_FOR_INSN (insn);
- int rgn = CONTAINING_RGN (bb->index);
- int nr_blks = RGN_NR_BLOCKS (rgn);
- /* Skip trivial regions and region head blocks that can have
- predecessors outside of region. */
- if (nr_blks > 1 && BLOCK_TO_BB (bb->index) != 0)
- {
- edge e;
- edge_iterator ei;
- /* Assume that region is SCC, i.e. all immediate predecessors
- of non-head block are in the same region. */
- FOR_EACH_EDGE (e, ei, bb->preds)
- {
- /* Avoid creating of loop-carried dependencies through
- using topological odering in region. */
- if (BLOCK_TO_BB (bb->index) > BLOCK_TO_BB (e->src->index))
- add_dependee_for_func_arg (first_arg, e->src);
- }
- }
- insn = first_arg;
- if (insn == head)
- break;
- }
- }
- else if (first_arg)
- avoid_func_arg_motion (first_arg, insn);
-}
-
-/* Hook for pre-reload schedule - set priority of moves from likely spilled
- HW registers to maximum, to schedule them at soon as possible. These are
- moves from function argument registers at the top of the function entry
- and moves from function return value registers after call. */
-static int
-ix86_adjust_priority (rtx insn, int priority)
-{
- rtx set;
-
- if (reload_completed)
- return priority;
-
- if (!NONDEBUG_INSN_P (insn))
- return priority;
-
- set = single_set (insn);
- if (set)
- {
- rtx tmp = SET_SRC (set);
- if (REG_P (tmp)
- && HARD_REGISTER_P (tmp)
- && !TEST_HARD_REG_BIT (fixed_reg_set, REGNO (tmp))
- && ix86_class_likely_spilled_p (REGNO_REG_CLASS (REGNO (tmp))))
- return current_sched_info->sched_max_insns_priority;
- }
-
- return priority;
-}
-
-/* Model decoder of Core 2/i7.
- Below hooks for multipass scheduling (see haifa-sched.c:max_issue)
- track the instruction fetch block boundaries and make sure that long
- (9+ bytes) instructions are assigned to D0. */
-
-/* Maximum length of an insn that can be handled by
- a secondary decoder unit. '8' for Core 2/i7. */
-static int core2i7_secondary_decoder_max_insn_size;
-
-/* Ifetch block size, i.e., number of bytes decoder reads per cycle.
- '16' for Core 2/i7. */
-static int core2i7_ifetch_block_size;
-
-/* Maximum number of instructions decoder can handle per cycle.
- '6' for Core 2/i7. */
-static int core2i7_ifetch_block_max_insns;
-
-typedef struct ix86_first_cycle_multipass_data_ *
- ix86_first_cycle_multipass_data_t;
-typedef const struct ix86_first_cycle_multipass_data_ *
- const_ix86_first_cycle_multipass_data_t;
-
-/* A variable to store target state across calls to max_issue within
- one cycle. */
-static struct ix86_first_cycle_multipass_data_ _ix86_first_cycle_multipass_data,
- *ix86_first_cycle_multipass_data = &_ix86_first_cycle_multipass_data;
-
-/* Initialize DATA. */
-static void
-core2i7_first_cycle_multipass_init (void *_data)
-{
- ix86_first_cycle_multipass_data_t data
- = (ix86_first_cycle_multipass_data_t) _data;
-
- data->ifetch_block_len = 0;
- data->ifetch_block_n_insns = 0;
- data->ready_try_change = NULL;
- data->ready_try_change_size = 0;
-}
-
-/* Advancing the cycle; reset ifetch block counts. */
-static void
-core2i7_dfa_post_advance_cycle (void)
-{
- ix86_first_cycle_multipass_data_t data = ix86_first_cycle_multipass_data;
-
- gcc_assert (data->ifetch_block_n_insns <= core2i7_ifetch_block_max_insns);
-
- data->ifetch_block_len = 0;
- data->ifetch_block_n_insns = 0;
-}
-
-static int min_insn_size (rtx);
-
-/* Filter out insns from ready_try that the core will not be able to issue
- on current cycle due to decoder. */
-static void
-core2i7_first_cycle_multipass_filter_ready_try
-(const_ix86_first_cycle_multipass_data_t data,
- char *ready_try, int n_ready, bool first_cycle_insn_p)
-{
- while (n_ready--)
- {
- rtx insn;
- int insn_size;
-
- if (ready_try[n_ready])
- continue;
-
- insn = get_ready_element (n_ready);
- insn_size = min_insn_size (insn);
-
- if (/* If this is a too long an insn for a secondary decoder ... */
- (!first_cycle_insn_p
- && insn_size > core2i7_secondary_decoder_max_insn_size)
- /* ... or it would not fit into the ifetch block ... */
- || data->ifetch_block_len + insn_size > core2i7_ifetch_block_size
- /* ... or the decoder is full already ... */
- || data->ifetch_block_n_insns + 1 > core2i7_ifetch_block_max_insns)
- /* ... mask the insn out. */
- {
- ready_try[n_ready] = 1;
-
- if (data->ready_try_change)
- bitmap_set_bit (data->ready_try_change, n_ready);
- }
- }
-}
-
-/* Prepare for a new round of multipass lookahead scheduling. */
-static void
-core2i7_first_cycle_multipass_begin (void *_data, char *ready_try, int n_ready,
- bool first_cycle_insn_p)
-{
- ix86_first_cycle_multipass_data_t data
- = (ix86_first_cycle_multipass_data_t) _data;
- const_ix86_first_cycle_multipass_data_t prev_data
- = ix86_first_cycle_multipass_data;
-
- /* Restore the state from the end of the previous round. */
- data->ifetch_block_len = prev_data->ifetch_block_len;
- data->ifetch_block_n_insns = prev_data->ifetch_block_n_insns;
-
- /* Filter instructions that cannot be issued on current cycle due to
- decoder restrictions. */
- core2i7_first_cycle_multipass_filter_ready_try (data, ready_try, n_ready,
- first_cycle_insn_p);
-}
-
-/* INSN is being issued in current solution. Account for its impact on
- the decoder model. */
-static void
-core2i7_first_cycle_multipass_issue (void *_data, char *ready_try, int n_ready,
- rtx insn, const void *_prev_data)
-{
- ix86_first_cycle_multipass_data_t data
- = (ix86_first_cycle_multipass_data_t) _data;
- const_ix86_first_cycle_multipass_data_t prev_data
- = (const_ix86_first_cycle_multipass_data_t) _prev_data;
-
- int insn_size = min_insn_size (insn);
-
- data->ifetch_block_len = prev_data->ifetch_block_len + insn_size;
- data->ifetch_block_n_insns = prev_data->ifetch_block_n_insns + 1;
- gcc_assert (data->ifetch_block_len <= core2i7_ifetch_block_size
- && data->ifetch_block_n_insns <= core2i7_ifetch_block_max_insns);
-
- /* Allocate or resize the bitmap for storing INSN's effect on ready_try. */
- if (!data->ready_try_change)
- {
- data->ready_try_change = sbitmap_alloc (n_ready);
- data->ready_try_change_size = n_ready;
- }
- else if (data->ready_try_change_size < n_ready)
- {
- data->ready_try_change = sbitmap_resize (data->ready_try_change,
- n_ready, 0);
- data->ready_try_change_size = n_ready;
- }
- bitmap_clear (data->ready_try_change);
-
- /* Filter out insns from ready_try that the core will not be able to issue
- on current cycle due to decoder. */
- core2i7_first_cycle_multipass_filter_ready_try (data, ready_try, n_ready,
- false);
-}
-
-/* Revert the effect on ready_try. */
-static void
-core2i7_first_cycle_multipass_backtrack (const void *_data,
- char *ready_try,
- int n_ready ATTRIBUTE_UNUSED)
-{
- const_ix86_first_cycle_multipass_data_t data
- = (const_ix86_first_cycle_multipass_data_t) _data;
- unsigned int i = 0;
- sbitmap_iterator sbi;
-
- gcc_assert (bitmap_last_set_bit (data->ready_try_change) < n_ready);
- EXECUTE_IF_SET_IN_BITMAP (data->ready_try_change, 0, i, sbi)
- {
- ready_try[i] = 0;
- }
-}
-
-/* Save the result of multipass lookahead scheduling for the next round. */
-static void
-core2i7_first_cycle_multipass_end (const void *_data)
-{
- const_ix86_first_cycle_multipass_data_t data
- = (const_ix86_first_cycle_multipass_data_t) _data;
- ix86_first_cycle_multipass_data_t next_data
- = ix86_first_cycle_multipass_data;
-
- if (data != NULL)
- {
- next_data->ifetch_block_len = data->ifetch_block_len;
- next_data->ifetch_block_n_insns = data->ifetch_block_n_insns;
- }
-}
-
-/* Deallocate target data. */
-static void
-core2i7_first_cycle_multipass_fini (void *_data)
-{
- ix86_first_cycle_multipass_data_t data
- = (ix86_first_cycle_multipass_data_t) _data;
-
- if (data->ready_try_change)
- {
- sbitmap_free (data->ready_try_change);
- data->ready_try_change = NULL;
- data->ready_try_change_size = 0;
- }
-}
-
-/* Prepare for scheduling pass. */
-static void
-ix86_sched_init_global (FILE *dump ATTRIBUTE_UNUSED,
- int verbose ATTRIBUTE_UNUSED,
- int max_uid ATTRIBUTE_UNUSED)
-{
- /* Install scheduling hooks for current CPU. Some of these hooks are used
- in time-critical parts of the scheduler, so we only set them up when
- they are actually used. */
- switch (ix86_tune)
- {
- case PROCESSOR_CORE2:
- case PROCESSOR_COREI7:
- case PROCESSOR_HASWELL:
- /* Do not perform multipass scheduling for pre-reload schedule
- to save compile time. */
- if (reload_completed)
- {
- targetm.sched.dfa_post_advance_cycle
- = core2i7_dfa_post_advance_cycle;
- targetm.sched.first_cycle_multipass_init
- = core2i7_first_cycle_multipass_init;
- targetm.sched.first_cycle_multipass_begin
- = core2i7_first_cycle_multipass_begin;
- targetm.sched.first_cycle_multipass_issue
- = core2i7_first_cycle_multipass_issue;
- targetm.sched.first_cycle_multipass_backtrack
- = core2i7_first_cycle_multipass_backtrack;
- targetm.sched.first_cycle_multipass_end
- = core2i7_first_cycle_multipass_end;
- targetm.sched.first_cycle_multipass_fini
- = core2i7_first_cycle_multipass_fini;
-
- /* Set decoder parameters. */
- core2i7_secondary_decoder_max_insn_size = 8;
- core2i7_ifetch_block_size = 16;
- core2i7_ifetch_block_max_insns = 6;
- break;
- }
- /* ... Fall through ... */
- default:
- targetm.sched.dfa_post_advance_cycle = NULL;
- targetm.sched.first_cycle_multipass_init = NULL;
- targetm.sched.first_cycle_multipass_begin = NULL;
- targetm.sched.first_cycle_multipass_issue = NULL;
- targetm.sched.first_cycle_multipass_backtrack = NULL;
- targetm.sched.first_cycle_multipass_end = NULL;
- targetm.sched.first_cycle_multipass_fini = NULL;
- break;
- }
-}
-
-
-/* Compute the alignment given to a constant that is being placed in memory.
- EXP is the constant and ALIGN is the alignment that the object would
- ordinarily have.
- The value of this function is used instead of that alignment to align
- the object. */
-
-int
-ix86_constant_alignment (tree exp, int align)
-{
- if (TREE_CODE (exp) == REAL_CST || TREE_CODE (exp) == VECTOR_CST
- || TREE_CODE (exp) == INTEGER_CST)
- {
- if (TYPE_MODE (TREE_TYPE (exp)) == DFmode && align < 64)
- return 64;
- else if (ALIGN_MODE_128 (TYPE_MODE (TREE_TYPE (exp))) && align < 128)
- return 128;
- }
- else if (!optimize_size && TREE_CODE (exp) == STRING_CST
- && TREE_STRING_LENGTH (exp) >= 31 && align < BITS_PER_WORD)
- return BITS_PER_WORD;
-
- return align;
-}
-
-/* Compute the alignment for a static variable.
- TYPE is the data type, and ALIGN is the alignment that
- the object would ordinarily have. The value of this function is used
- instead of that alignment to align the object. */
-
-int
-ix86_data_alignment (tree type, int align)
-{
- int max_align = optimize_size ? BITS_PER_WORD : MIN (256, MAX_OFILE_ALIGNMENT);
-
- if (AGGREGATE_TYPE_P (type)
- && TYPE_SIZE (type)
- && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
- && (TREE_INT_CST_LOW (TYPE_SIZE (type)) >= (unsigned) max_align
- || TREE_INT_CST_HIGH (TYPE_SIZE (type)))
- && align < max_align)
- align = max_align;
-
- /* x86-64 ABI requires arrays greater than 16 bytes to be aligned
- to 16byte boundary. */
- if (TARGET_64BIT)
- {
- if (AGGREGATE_TYPE_P (type)
- && TYPE_SIZE (type)
- && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
- && (TREE_INT_CST_LOW (TYPE_SIZE (type)) >= 128
- || TREE_INT_CST_HIGH (TYPE_SIZE (type))) && align < 128)
- return 128;
- }
-
- if (TREE_CODE (type) == ARRAY_TYPE)
- {
- if (TYPE_MODE (TREE_TYPE (type)) == DFmode && align < 64)
- return 64;
- if (ALIGN_MODE_128 (TYPE_MODE (TREE_TYPE (type))) && align < 128)
- return 128;
- }
- else if (TREE_CODE (type) == COMPLEX_TYPE)
- {
-
- if (TYPE_MODE (type) == DCmode && align < 64)
- return 64;
- if ((TYPE_MODE (type) == XCmode
- || TYPE_MODE (type) == TCmode) && align < 128)
- return 128;
- }
- else if ((TREE_CODE (type) == RECORD_TYPE
- || TREE_CODE (type) == UNION_TYPE
- || TREE_CODE (type) == QUAL_UNION_TYPE)
- && TYPE_FIELDS (type))
- {
- if (DECL_MODE (TYPE_FIELDS (type)) == DFmode && align < 64)
- return 64;
- if (ALIGN_MODE_128 (DECL_MODE (TYPE_FIELDS (type))) && align < 128)
- return 128;
- }
- else if (TREE_CODE (type) == REAL_TYPE || TREE_CODE (type) == VECTOR_TYPE
- || TREE_CODE (type) == INTEGER_TYPE)
- {
- if (TYPE_MODE (type) == DFmode && align < 64)
- return 64;
- if (ALIGN_MODE_128 (TYPE_MODE (type)) && align < 128)
- return 128;
- }
-
- return align;
-}
-
-/* Compute the alignment for a local variable or a stack slot. EXP is
- the data type or decl itself, MODE is the widest mode available and
- 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. */
-
-unsigned int
-ix86_local_alignment (tree exp, enum machine_mode mode,
- unsigned int align)
-{
- tree type, decl;
-
- if (exp && DECL_P (exp))
- {
- type = TREE_TYPE (exp);
- decl = exp;
- }
- else
- {
- type = exp;
- decl = NULL;
- }
-
- /* Don't do dynamic stack realignment for long long objects with
- -mpreferred-stack-boundary=2. */
- if (!TARGET_64BIT
- && align == 64
- && ix86_preferred_stack_boundary < 64
- && (mode == DImode || (type && TYPE_MODE (type) == DImode))
- && (!type || !TYPE_USER_ALIGN (type))
- && (!decl || !DECL_USER_ALIGN (decl)))
- align = 32;
-
- /* If TYPE is NULL, we are allocating a stack slot for caller-save
- register in MODE. We will return the largest alignment of XF
- and DF. */
- if (!type)
- {
- if (mode == XFmode && align < GET_MODE_ALIGNMENT (DFmode))
- align = GET_MODE_ALIGNMENT (DFmode);
- return align;
- }
-
- /* x86-64 ABI requires arrays greater than 16 bytes to be aligned
- to 16byte boundary. Exact wording is:
-
- An array uses the same alignment as its elements, except that a local or
- global array variable of length at least 16 bytes or
- a C99 variable-length array variable always has alignment of at least 16 bytes.
-
- This was added to allow use of aligned SSE instructions at arrays. This
- rule is meant for static storage (where compiler can not do the analysis
- by itself). We follow it for automatic variables only when convenient.
- We fully control everything in the function compiled and functions from
- other unit can not rely on the alignment.
-
- Exclude va_list type. It is the common case of local array where
- we can not benefit from the alignment. */
- if (TARGET_64BIT && optimize_function_for_speed_p (cfun)
- && TARGET_SSE)
- {
- if (AGGREGATE_TYPE_P (type)
- && (va_list_type_node == NULL_TREE
- || (TYPE_MAIN_VARIANT (type)
- != TYPE_MAIN_VARIANT (va_list_type_node)))
- && TYPE_SIZE (type)
- && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
- && (TREE_INT_CST_LOW (TYPE_SIZE (type)) >= 16
- || TREE_INT_CST_HIGH (TYPE_SIZE (type))) && align < 128)
- return 128;
- }
- if (TREE_CODE (type) == ARRAY_TYPE)
- {
- if (TYPE_MODE (TREE_TYPE (type)) == DFmode && align < 64)
- return 64;
- if (ALIGN_MODE_128 (TYPE_MODE (TREE_TYPE (type))) && align < 128)
- return 128;
- }
- else if (TREE_CODE (type) == COMPLEX_TYPE)
- {
- if (TYPE_MODE (type) == DCmode && align < 64)
- return 64;
- if ((TYPE_MODE (type) == XCmode
- || TYPE_MODE (type) == TCmode) && align < 128)
- return 128;
- }
- else if ((TREE_CODE (type) == RECORD_TYPE
- || TREE_CODE (type) == UNION_TYPE
- || TREE_CODE (type) == QUAL_UNION_TYPE)
- && TYPE_FIELDS (type))
- {
- if (DECL_MODE (TYPE_FIELDS (type)) == DFmode && align < 64)
- return 64;
- if (ALIGN_MODE_128 (DECL_MODE (TYPE_FIELDS (type))) && align < 128)
- return 128;
- }
- else if (TREE_CODE (type) == REAL_TYPE || TREE_CODE (type) == VECTOR_TYPE
- || TREE_CODE (type) == INTEGER_TYPE)
- {
-
- if (TYPE_MODE (type) == DFmode && align < 64)
- return 64;
- if (ALIGN_MODE_128 (TYPE_MODE (type)) && align < 128)
- return 128;
- }
- return align;
-}
-
-/* Compute the minimum required alignment for dynamic stack realignment
- purposes for a local variable, parameter or a stack slot. EXP is
- the data type or decl itself, MODE is its mode and ALIGN is the
- alignment that the object would ordinarily have. */
-
-unsigned int
-ix86_minimum_alignment (tree exp, enum machine_mode mode,
- unsigned int align)
-{
- tree type, decl;
-
- if (exp && DECL_P (exp))
- {
- type = TREE_TYPE (exp);
- decl = exp;
- }
- else
- {
- type = exp;
- decl = NULL;
- }
-
- if (TARGET_64BIT || align != 64 || ix86_preferred_stack_boundary >= 64)
- return align;
-
- /* Don't do dynamic stack realignment for long long objects with
- -mpreferred-stack-boundary=2. */
- if ((mode == DImode || (type && TYPE_MODE (type) == DImode))
- && (!type || !TYPE_USER_ALIGN (type))
- && (!decl || !DECL_USER_ALIGN (decl)))
- return 32;
-
- return align;
-}
-
-/* Find a location for the static chain incoming to a nested function.
- This is a register, unless all free registers are used by arguments. */
-
-static rtx
-ix86_static_chain (const_tree fndecl, bool incoming_p)
-{
- unsigned regno;
-
- if (!DECL_STATIC_CHAIN (fndecl))
- return NULL;
-
- if (TARGET_64BIT)
- {
- /* We always use R10 in 64-bit mode. */
- regno = R10_REG;
- }
- else
- {
- tree fntype;
- unsigned int ccvt;
-
- /* By default in 32-bit mode we use ECX to pass the static chain. */
- regno = CX_REG;
-
- fntype = TREE_TYPE (fndecl);
- ccvt = ix86_get_callcvt (fntype);
- if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
- {
- /* Fastcall functions use ecx/edx for arguments, which leaves
- us with EAX for the static chain.
- Thiscall functions use ecx for arguments, which also
- leaves us with EAX for the static chain. */
- regno = AX_REG;
- }
- else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
- {
- /* Thiscall functions use ecx for arguments, which leaves
- us with EAX and EDX for the static chain.
- We are using for abi-compatibility EAX. */
- regno = AX_REG;
- }
- else if (ix86_function_regparm (fntype, fndecl) == 3)
- {
- /* For regparm 3, we have no free call-clobbered registers in
- which to store the static chain. In order to implement this,
- we have the trampoline push the static chain to the stack.
- However, we can't push a value below the return address when
- we call the nested function directly, so we have to use an
- alternate entry point. For this we use ESI, and have the
- alternate entry point push ESI, so that things appear the
- same once we're executing the nested function. */
- if (incoming_p)
- {
- if (fndecl == current_function_decl)
- ix86_static_chain_on_stack = true;
- return gen_frame_mem (SImode,
- plus_constant (Pmode,
- arg_pointer_rtx, -8));
- }
- regno = SI_REG;
- }
- }
-
- return gen_rtx_REG (Pmode, regno);
-}
-
-/* Emit RTL insns to initialize the variable parts of a trampoline.
- FNDECL is the decl of the target address; M_TRAMP is a MEM for
- the trampoline, and CHAIN_VALUE is an RTX for the static chain
- to be passed to the target function. */
-
-static void
-ix86_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
-{
- rtx mem, fnaddr;
- int opcode;
- int offset = 0;
-
- fnaddr = XEXP (DECL_RTL (fndecl), 0);
-
- if (TARGET_64BIT)
- {
- int size;
-
- /* Load the function address to r11. Try to load address using
- the shorter movl instead of movabs. We may want to support
- movq for kernel mode, but kernel does not use trampolines at
- the moment. FNADDR is a 32bit address and may not be in
- DImode when ptr_mode == SImode. Always use movl in this
- case. */
- if (ptr_mode == SImode
- || x86_64_zext_immediate_operand (fnaddr, VOIDmode))
- {
- fnaddr = copy_addr_to_reg (fnaddr);
-
- mem = adjust_address (m_tramp, HImode, offset);
- emit_move_insn (mem, gen_int_mode (0xbb41, HImode));
-
- mem = adjust_address (m_tramp, SImode, offset + 2);
- emit_move_insn (mem, gen_lowpart (SImode, fnaddr));
- offset += 6;
- }
- else
- {
- mem = adjust_address (m_tramp, HImode, offset);
- emit_move_insn (mem, gen_int_mode (0xbb49, HImode));
-
- mem = adjust_address (m_tramp, DImode, offset + 2);
- emit_move_insn (mem, fnaddr);
- offset += 10;
- }
-
- /* Load static chain using movabs to r10. Use the shorter movl
- instead of movabs when ptr_mode == SImode. */
- if (ptr_mode == SImode)
- {
- opcode = 0xba41;
- size = 6;
- }
- else
- {
- opcode = 0xba49;
- size = 10;
- }
-
- mem = adjust_address (m_tramp, HImode, offset);
- emit_move_insn (mem, gen_int_mode (opcode, HImode));
-
- mem = adjust_address (m_tramp, ptr_mode, offset + 2);
- emit_move_insn (mem, chain_value);
- offset += size;
-
- /* Jump to r11; the last (unused) byte is a nop, only there to
- pad the write out to a single 32-bit store. */
- mem = adjust_address (m_tramp, SImode, offset);
- emit_move_insn (mem, gen_int_mode (0x90e3ff49, SImode));
- offset += 4;
- }
- else
- {
- rtx disp, chain;
-
- /* Depending on the static chain location, either load a register
- with a constant, or push the constant to the stack. All of the
- instructions are the same size. */
- chain = ix86_static_chain (fndecl, true);
- if (REG_P (chain))
- {
- switch (REGNO (chain))
- {
- case AX_REG:
- opcode = 0xb8; break;
- case CX_REG:
- opcode = 0xb9; break;
- default:
- gcc_unreachable ();
- }
- }
- else
- opcode = 0x68;
-
- mem = adjust_address (m_tramp, QImode, offset);
- emit_move_insn (mem, gen_int_mode (opcode, QImode));
-
- mem = adjust_address (m_tramp, SImode, offset + 1);
- emit_move_insn (mem, chain_value);
- offset += 5;
-
- mem = adjust_address (m_tramp, QImode, offset);
- emit_move_insn (mem, gen_int_mode (0xe9, QImode));
-
- mem = adjust_address (m_tramp, SImode, offset + 1);
-
- /* Compute offset from the end of the jmp to the target function.
- In the case in which the trampoline stores the static chain on
- the stack, we need to skip the first insn which pushes the
- (call-saved) register static chain; this push is 1 byte. */
- offset += 5;
- disp = expand_binop (SImode, sub_optab, fnaddr,
- plus_constant (Pmode, XEXP (m_tramp, 0),
- offset - (MEM_P (chain) ? 1 : 0)),
- NULL_RTX, 1, OPTAB_DIRECT);
- emit_move_insn (mem, disp);
- }
-
- gcc_assert (offset <= TRAMPOLINE_SIZE);
-
-#ifdef HAVE_ENABLE_EXECUTE_STACK
-#ifdef CHECK_EXECUTE_STACK_ENABLED
- if (CHECK_EXECUTE_STACK_ENABLED)
-#endif
- emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
- LCT_NORMAL, VOIDmode, 1, XEXP (m_tramp, 0), Pmode);
-#endif
-}
-
-/* The following file contains several enumerations and data structures
- built from the definitions in i386-builtin-types.def. */
-
-#include "i386-builtin-types.inc"
-
-/* Table for the ix86 builtin non-function types. */
-static GTY(()) tree ix86_builtin_type_tab[(int) IX86_BT_LAST_CPTR + 1];
-
-/* Retrieve an element from the above table, building some of
- the types lazily. */
-
-static tree
-ix86_get_builtin_type (enum ix86_builtin_type tcode)
-{
- unsigned int index;
- tree type, itype;
-
- gcc_assert ((unsigned)tcode < ARRAY_SIZE(ix86_builtin_type_tab));
-
- type = ix86_builtin_type_tab[(int) tcode];
- if (type != NULL)
- return type;
-
- gcc_assert (tcode > IX86_BT_LAST_PRIM);
- if (tcode <= IX86_BT_LAST_VECT)
- {
- enum machine_mode mode;
-
- index = tcode - IX86_BT_LAST_PRIM - 1;
- itype = ix86_get_builtin_type (ix86_builtin_type_vect_base[index]);
- mode = ix86_builtin_type_vect_mode[index];
-
- type = build_vector_type_for_mode (itype, mode);
- }
- else
- {
- int quals;
-
- index = tcode - IX86_BT_LAST_VECT - 1;
- if (tcode <= IX86_BT_LAST_PTR)
- quals = TYPE_UNQUALIFIED;
- else
- quals = TYPE_QUAL_CONST;
-
- itype = ix86_get_builtin_type (ix86_builtin_type_ptr_base[index]);
- if (quals != TYPE_UNQUALIFIED)
- itype = build_qualified_type (itype, quals);
-
- type = build_pointer_type (itype);
- }
-
- ix86_builtin_type_tab[(int) tcode] = type;
- return type;
-}
-
-/* Table for the ix86 builtin function types. */
-static GTY(()) tree ix86_builtin_func_type_tab[(int) IX86_BT_LAST_ALIAS + 1];
-
-/* Retrieve an element from the above table, building some of
- the types lazily. */
-
-static tree
-ix86_get_builtin_func_type (enum ix86_builtin_func_type tcode)
-{
- tree type;
-
- gcc_assert ((unsigned)tcode < ARRAY_SIZE (ix86_builtin_func_type_tab));
-
- type = ix86_builtin_func_type_tab[(int) tcode];
- if (type != NULL)
- return type;
-
- if (tcode <= IX86_BT_LAST_FUNC)
- {
- unsigned start = ix86_builtin_func_start[(int) tcode];
- unsigned after = ix86_builtin_func_start[(int) tcode + 1];
- tree rtype, atype, args = void_list_node;
- unsigned i;
-
- rtype = ix86_get_builtin_type (ix86_builtin_func_args[start]);
- for (i = after - 1; i > start; --i)
- {
- atype = ix86_get_builtin_type (ix86_builtin_func_args[i]);
- args = tree_cons (NULL, atype, args);
- }
-
- type = build_function_type (rtype, args);
- }
- else
- {
- unsigned index = tcode - IX86_BT_LAST_FUNC - 1;
- enum ix86_builtin_func_type icode;
-
- icode = ix86_builtin_func_alias_base[index];
- type = ix86_get_builtin_func_type (icode);
- }
-
- ix86_builtin_func_type_tab[(int) tcode] = type;
- return type;
-}
-
-
-/* Codes for all the SSE/MMX builtins. */
-enum ix86_builtins
-{
- IX86_BUILTIN_ADDPS,
- IX86_BUILTIN_ADDSS,
- IX86_BUILTIN_DIVPS,
- IX86_BUILTIN_DIVSS,
- IX86_BUILTIN_MULPS,
- IX86_BUILTIN_MULSS,
- IX86_BUILTIN_SUBPS,
- IX86_BUILTIN_SUBSS,
-
- IX86_BUILTIN_CMPEQPS,
- IX86_BUILTIN_CMPLTPS,
- IX86_BUILTIN_CMPLEPS,
- IX86_BUILTIN_CMPGTPS,
- IX86_BUILTIN_CMPGEPS,
- IX86_BUILTIN_CMPNEQPS,
- IX86_BUILTIN_CMPNLTPS,
- IX86_BUILTIN_CMPNLEPS,
- IX86_BUILTIN_CMPNGTPS,
- IX86_BUILTIN_CMPNGEPS,
- IX86_BUILTIN_CMPORDPS,
- IX86_BUILTIN_CMPUNORDPS,
- IX86_BUILTIN_CMPEQSS,
- IX86_BUILTIN_CMPLTSS,
- IX86_BUILTIN_CMPLESS,
- IX86_BUILTIN_CMPNEQSS,
- IX86_BUILTIN_CMPNLTSS,
- IX86_BUILTIN_CMPNLESS,
- IX86_BUILTIN_CMPNGTSS,
- IX86_BUILTIN_CMPNGESS,
- IX86_BUILTIN_CMPORDSS,
- IX86_BUILTIN_CMPUNORDSS,
-
- IX86_BUILTIN_COMIEQSS,
- IX86_BUILTIN_COMILTSS,
- IX86_BUILTIN_COMILESS,
- IX86_BUILTIN_COMIGTSS,
- IX86_BUILTIN_COMIGESS,
- IX86_BUILTIN_COMINEQSS,
- IX86_BUILTIN_UCOMIEQSS,
- IX86_BUILTIN_UCOMILTSS,
- IX86_BUILTIN_UCOMILESS,
- IX86_BUILTIN_UCOMIGTSS,
- IX86_BUILTIN_UCOMIGESS,
- IX86_BUILTIN_UCOMINEQSS,
-
- IX86_BUILTIN_CVTPI2PS,
- IX86_BUILTIN_CVTPS2PI,
- IX86_BUILTIN_CVTSI2SS,
- IX86_BUILTIN_CVTSI642SS,
- IX86_BUILTIN_CVTSS2SI,
- IX86_BUILTIN_CVTSS2SI64,
- IX86_BUILTIN_CVTTPS2PI,
- IX86_BUILTIN_CVTTSS2SI,
- IX86_BUILTIN_CVTTSS2SI64,
-
- IX86_BUILTIN_MAXPS,
- IX86_BUILTIN_MAXSS,
- IX86_BUILTIN_MINPS,
- IX86_BUILTIN_MINSS,
-
- IX86_BUILTIN_LOADUPS,
- IX86_BUILTIN_STOREUPS,
- IX86_BUILTIN_MOVSS,
-
- IX86_BUILTIN_MOVHLPS,
- IX86_BUILTIN_MOVLHPS,
- IX86_BUILTIN_LOADHPS,
- IX86_BUILTIN_LOADLPS,
- IX86_BUILTIN_STOREHPS,
- IX86_BUILTIN_STORELPS,
-
- IX86_BUILTIN_MASKMOVQ,
- IX86_BUILTIN_MOVMSKPS,
- IX86_BUILTIN_PMOVMSKB,
-
- IX86_BUILTIN_MOVNTPS,
- IX86_BUILTIN_MOVNTQ,
-
- IX86_BUILTIN_LOADDQU,
- IX86_BUILTIN_STOREDQU,
-
- IX86_BUILTIN_PACKSSWB,
- IX86_BUILTIN_PACKSSDW,
- IX86_BUILTIN_PACKUSWB,
-
- IX86_BUILTIN_PADDB,
- IX86_BUILTIN_PADDW,
- IX86_BUILTIN_PADDD,
- IX86_BUILTIN_PADDQ,
- IX86_BUILTIN_PADDSB,
- IX86_BUILTIN_PADDSW,
- IX86_BUILTIN_PADDUSB,
- IX86_BUILTIN_PADDUSW,
- IX86_BUILTIN_PSUBB,
- IX86_BUILTIN_PSUBW,
- IX86_BUILTIN_PSUBD,
- IX86_BUILTIN_PSUBQ,
- IX86_BUILTIN_PSUBSB,
- IX86_BUILTIN_PSUBSW,
- IX86_BUILTIN_PSUBUSB,
- IX86_BUILTIN_PSUBUSW,
-
- IX86_BUILTIN_PAND,
- IX86_BUILTIN_PANDN,
- IX86_BUILTIN_POR,
- IX86_BUILTIN_PXOR,
-
- IX86_BUILTIN_PAVGB,
- IX86_BUILTIN_PAVGW,
-
- IX86_BUILTIN_PCMPEQB,
- IX86_BUILTIN_PCMPEQW,
- IX86_BUILTIN_PCMPEQD,
- IX86_BUILTIN_PCMPGTB,
- IX86_BUILTIN_PCMPGTW,
- IX86_BUILTIN_PCMPGTD,
-
- IX86_BUILTIN_PMADDWD,
-
- IX86_BUILTIN_PMAXSW,
- IX86_BUILTIN_PMAXUB,
- IX86_BUILTIN_PMINSW,
- IX86_BUILTIN_PMINUB,
-
- IX86_BUILTIN_PMULHUW,
- IX86_BUILTIN_PMULHW,
- IX86_BUILTIN_PMULLW,
-
- IX86_BUILTIN_PSADBW,
- IX86_BUILTIN_PSHUFW,
-
- IX86_BUILTIN_PSLLW,
- IX86_BUILTIN_PSLLD,
- IX86_BUILTIN_PSLLQ,
- IX86_BUILTIN_PSRAW,
- IX86_BUILTIN_PSRAD,
- IX86_BUILTIN_PSRLW,
- IX86_BUILTIN_PSRLD,
- IX86_BUILTIN_PSRLQ,
- IX86_BUILTIN_PSLLWI,
- IX86_BUILTIN_PSLLDI,
- IX86_BUILTIN_PSLLQI,
- IX86_BUILTIN_PSRAWI,
- IX86_BUILTIN_PSRADI,
- IX86_BUILTIN_PSRLWI,
- IX86_BUILTIN_PSRLDI,
- IX86_BUILTIN_PSRLQI,
-
- IX86_BUILTIN_PUNPCKHBW,
- IX86_BUILTIN_PUNPCKHWD,
- IX86_BUILTIN_PUNPCKHDQ,
- IX86_BUILTIN_PUNPCKLBW,
- IX86_BUILTIN_PUNPCKLWD,
- IX86_BUILTIN_PUNPCKLDQ,
-
- IX86_BUILTIN_SHUFPS,
-
- IX86_BUILTIN_RCPPS,
- IX86_BUILTIN_RCPSS,
- IX86_BUILTIN_RSQRTPS,
- IX86_BUILTIN_RSQRTPS_NR,
- IX86_BUILTIN_RSQRTSS,
- IX86_BUILTIN_RSQRTF,
- IX86_BUILTIN_SQRTPS,
- IX86_BUILTIN_SQRTPS_NR,
- IX86_BUILTIN_SQRTSS,
-
- IX86_BUILTIN_UNPCKHPS,
- IX86_BUILTIN_UNPCKLPS,
-
- IX86_BUILTIN_ANDPS,
- IX86_BUILTIN_ANDNPS,
- IX86_BUILTIN_ORPS,
- IX86_BUILTIN_XORPS,
-
- IX86_BUILTIN_EMMS,
- IX86_BUILTIN_LDMXCSR,
- IX86_BUILTIN_STMXCSR,
- IX86_BUILTIN_SFENCE,
-
- IX86_BUILTIN_FXSAVE,
- IX86_BUILTIN_FXRSTOR,
- IX86_BUILTIN_FXSAVE64,
- IX86_BUILTIN_FXRSTOR64,
-
- IX86_BUILTIN_XSAVE,
- IX86_BUILTIN_XRSTOR,
- IX86_BUILTIN_XSAVE64,
- IX86_BUILTIN_XRSTOR64,
-
- IX86_BUILTIN_XSAVEOPT,
- IX86_BUILTIN_XSAVEOPT64,
-
- /* 3DNow! Original */
- IX86_BUILTIN_FEMMS,
- IX86_BUILTIN_PAVGUSB,
- IX86_BUILTIN_PF2ID,
- IX86_BUILTIN_PFACC,
- IX86_BUILTIN_PFADD,
- IX86_BUILTIN_PFCMPEQ,
- IX86_BUILTIN_PFCMPGE,
- IX86_BUILTIN_PFCMPGT,
- IX86_BUILTIN_PFMAX,
- IX86_BUILTIN_PFMIN,
- IX86_BUILTIN_PFMUL,
- IX86_BUILTIN_PFRCP,
- IX86_BUILTIN_PFRCPIT1,
- IX86_BUILTIN_PFRCPIT2,
- IX86_BUILTIN_PFRSQIT1,
- IX86_BUILTIN_PFRSQRT,
- IX86_BUILTIN_PFSUB,
- IX86_BUILTIN_PFSUBR,
- IX86_BUILTIN_PI2FD,
- IX86_BUILTIN_PMULHRW,
-
- /* 3DNow! Athlon Extensions */
- IX86_BUILTIN_PF2IW,
- IX86_BUILTIN_PFNACC,
- IX86_BUILTIN_PFPNACC,
- IX86_BUILTIN_PI2FW,
- IX86_BUILTIN_PSWAPDSI,
- IX86_BUILTIN_PSWAPDSF,
-
- /* SSE2 */
- IX86_BUILTIN_ADDPD,
- IX86_BUILTIN_ADDSD,
- IX86_BUILTIN_DIVPD,
- IX86_BUILTIN_DIVSD,
- IX86_BUILTIN_MULPD,
- IX86_BUILTIN_MULSD,
- IX86_BUILTIN_SUBPD,
- IX86_BUILTIN_SUBSD,
-
- IX86_BUILTIN_CMPEQPD,
- IX86_BUILTIN_CMPLTPD,
- IX86_BUILTIN_CMPLEPD,
- IX86_BUILTIN_CMPGTPD,
- IX86_BUILTIN_CMPGEPD,
- IX86_BUILTIN_CMPNEQPD,
- IX86_BUILTIN_CMPNLTPD,
- IX86_BUILTIN_CMPNLEPD,
- IX86_BUILTIN_CMPNGTPD,
- IX86_BUILTIN_CMPNGEPD,
- IX86_BUILTIN_CMPORDPD,
- IX86_BUILTIN_CMPUNORDPD,
- IX86_BUILTIN_CMPEQSD,
- IX86_BUILTIN_CMPLTSD,
- IX86_BUILTIN_CMPLESD,
- IX86_BUILTIN_CMPNEQSD,
- IX86_BUILTIN_CMPNLTSD,
- IX86_BUILTIN_CMPNLESD,
- IX86_BUILTIN_CMPORDSD,
- IX86_BUILTIN_CMPUNORDSD,
-
- IX86_BUILTIN_COMIEQSD,
- IX86_BUILTIN_COMILTSD,
- IX86_BUILTIN_COMILESD,
- IX86_BUILTIN_COMIGTSD,
- IX86_BUILTIN_COMIGESD,
- IX86_BUILTIN_COMINEQSD,
- IX86_BUILTIN_UCOMIEQSD,
- IX86_BUILTIN_UCOMILTSD,
- IX86_BUILTIN_UCOMILESD,
- IX86_BUILTIN_UCOMIGTSD,
- IX86_BUILTIN_UCOMIGESD,
- IX86_BUILTIN_UCOMINEQSD,
-
- IX86_BUILTIN_MAXPD,
- IX86_BUILTIN_MAXSD,
- IX86_BUILTIN_MINPD,
- IX86_BUILTIN_MINSD,
-
- IX86_BUILTIN_ANDPD,
- IX86_BUILTIN_ANDNPD,
- IX86_BUILTIN_ORPD,
- IX86_BUILTIN_XORPD,
-
- IX86_BUILTIN_SQRTPD,
- IX86_BUILTIN_SQRTSD,
-
- IX86_BUILTIN_UNPCKHPD,
- IX86_BUILTIN_UNPCKLPD,
-
- IX86_BUILTIN_SHUFPD,
-
- IX86_BUILTIN_LOADUPD,
- IX86_BUILTIN_STOREUPD,
- IX86_BUILTIN_MOVSD,
-
- IX86_BUILTIN_LOADHPD,
- IX86_BUILTIN_LOADLPD,
-
- IX86_BUILTIN_CVTDQ2PD,
- IX86_BUILTIN_CVTDQ2PS,
-
- IX86_BUILTIN_CVTPD2DQ,
- IX86_BUILTIN_CVTPD2PI,
- IX86_BUILTIN_CVTPD2PS,
- IX86_BUILTIN_CVTTPD2DQ,
- IX86_BUILTIN_CVTTPD2PI,
-
- IX86_BUILTIN_CVTPI2PD,
- IX86_BUILTIN_CVTSI2SD,
- IX86_BUILTIN_CVTSI642SD,
-
- IX86_BUILTIN_CVTSD2SI,
- IX86_BUILTIN_CVTSD2SI64,
- IX86_BUILTIN_CVTSD2SS,
- IX86_BUILTIN_CVTSS2SD,
- IX86_BUILTIN_CVTTSD2SI,
- IX86_BUILTIN_CVTTSD2SI64,
-
- IX86_BUILTIN_CVTPS2DQ,
- IX86_BUILTIN_CVTPS2PD,
- IX86_BUILTIN_CVTTPS2DQ,
-
- IX86_BUILTIN_MOVNTI,
- IX86_BUILTIN_MOVNTI64,
- IX86_BUILTIN_MOVNTPD,
- IX86_BUILTIN_MOVNTDQ,
-
- IX86_BUILTIN_MOVQ128,
-
- /* SSE2 MMX */
- IX86_BUILTIN_MASKMOVDQU,
- IX86_BUILTIN_MOVMSKPD,
- IX86_BUILTIN_PMOVMSKB128,
-
- IX86_BUILTIN_PACKSSWB128,
- IX86_BUILTIN_PACKSSDW128,
- IX86_BUILTIN_PACKUSWB128,
-
- IX86_BUILTIN_PADDB128,
- IX86_BUILTIN_PADDW128,
- IX86_BUILTIN_PADDD128,
- IX86_BUILTIN_PADDQ128,
- IX86_BUILTIN_PADDSB128,
- IX86_BUILTIN_PADDSW128,
- IX86_BUILTIN_PADDUSB128,
- IX86_BUILTIN_PADDUSW128,
- IX86_BUILTIN_PSUBB128,
- IX86_BUILTIN_PSUBW128,
- IX86_BUILTIN_PSUBD128,
- IX86_BUILTIN_PSUBQ128,
- IX86_BUILTIN_PSUBSB128,
- IX86_BUILTIN_PSUBSW128,
- IX86_BUILTIN_PSUBUSB128,
- IX86_BUILTIN_PSUBUSW128,
-
- IX86_BUILTIN_PAND128,
- IX86_BUILTIN_PANDN128,
- IX86_BUILTIN_POR128,
- IX86_BUILTIN_PXOR128,
-
- IX86_BUILTIN_PAVGB128,
- IX86_BUILTIN_PAVGW128,
-
- IX86_BUILTIN_PCMPEQB128,
- IX86_BUILTIN_PCMPEQW128,
- IX86_BUILTIN_PCMPEQD128,
- IX86_BUILTIN_PCMPGTB128,
- IX86_BUILTIN_PCMPGTW128,
- IX86_BUILTIN_PCMPGTD128,
-
- IX86_BUILTIN_PMADDWD128,
-
- IX86_BUILTIN_PMAXSW128,
- IX86_BUILTIN_PMAXUB128,
- IX86_BUILTIN_PMINSW128,
- IX86_BUILTIN_PMINUB128,
-
- IX86_BUILTIN_PMULUDQ,
- IX86_BUILTIN_PMULUDQ128,
- IX86_BUILTIN_PMULHUW128,
- IX86_BUILTIN_PMULHW128,
- IX86_BUILTIN_PMULLW128,
-
- IX86_BUILTIN_PSADBW128,
- IX86_BUILTIN_PSHUFHW,
- IX86_BUILTIN_PSHUFLW,
- IX86_BUILTIN_PSHUFD,
-
- IX86_BUILTIN_PSLLDQI128,
- IX86_BUILTIN_PSLLWI128,
- IX86_BUILTIN_PSLLDI128,
- IX86_BUILTIN_PSLLQI128,
- IX86_BUILTIN_PSRAWI128,
- IX86_BUILTIN_PSRADI128,
- IX86_BUILTIN_PSRLDQI128,
- IX86_BUILTIN_PSRLWI128,
- IX86_BUILTIN_PSRLDI128,
- IX86_BUILTIN_PSRLQI128,
-
- IX86_BUILTIN_PSLLDQ128,
- IX86_BUILTIN_PSLLW128,
- IX86_BUILTIN_PSLLD128,
- IX86_BUILTIN_PSLLQ128,
- IX86_BUILTIN_PSRAW128,
- IX86_BUILTIN_PSRAD128,
- IX86_BUILTIN_PSRLW128,
- IX86_BUILTIN_PSRLD128,
- IX86_BUILTIN_PSRLQ128,
-
- IX86_BUILTIN_PUNPCKHBW128,
- IX86_BUILTIN_PUNPCKHWD128,
- IX86_BUILTIN_PUNPCKHDQ128,
- IX86_BUILTIN_PUNPCKHQDQ128,
- IX86_BUILTIN_PUNPCKLBW128,
- IX86_BUILTIN_PUNPCKLWD128,
- IX86_BUILTIN_PUNPCKLDQ128,
- IX86_BUILTIN_PUNPCKLQDQ128,
-
- IX86_BUILTIN_CLFLUSH,
- IX86_BUILTIN_MFENCE,
- IX86_BUILTIN_LFENCE,
- IX86_BUILTIN_PAUSE,
-
- IX86_BUILTIN_BSRSI,
- IX86_BUILTIN_BSRDI,
- IX86_BUILTIN_RDPMC,
- IX86_BUILTIN_RDTSC,
- IX86_BUILTIN_RDTSCP,
- IX86_BUILTIN_ROLQI,
- IX86_BUILTIN_ROLHI,
- IX86_BUILTIN_RORQI,
- IX86_BUILTIN_RORHI,
-
- /* SSE3. */
- IX86_BUILTIN_ADDSUBPS,
- IX86_BUILTIN_HADDPS,
- IX86_BUILTIN_HSUBPS,
- IX86_BUILTIN_MOVSHDUP,
- IX86_BUILTIN_MOVSLDUP,
- IX86_BUILTIN_ADDSUBPD,
- IX86_BUILTIN_HADDPD,
- IX86_BUILTIN_HSUBPD,
- IX86_BUILTIN_LDDQU,
-
- IX86_BUILTIN_MONITOR,
- IX86_BUILTIN_MWAIT,
-
- /* SSSE3. */
- IX86_BUILTIN_PHADDW,
- IX86_BUILTIN_PHADDD,
- IX86_BUILTIN_PHADDSW,
- IX86_BUILTIN_PHSUBW,
- IX86_BUILTIN_PHSUBD,
- IX86_BUILTIN_PHSUBSW,
- IX86_BUILTIN_PMADDUBSW,
- IX86_BUILTIN_PMULHRSW,
- IX86_BUILTIN_PSHUFB,
- IX86_BUILTIN_PSIGNB,
- IX86_BUILTIN_PSIGNW,
- IX86_BUILTIN_PSIGND,
- IX86_BUILTIN_PALIGNR,
- IX86_BUILTIN_PABSB,
- IX86_BUILTIN_PABSW,
- IX86_BUILTIN_PABSD,
-
- IX86_BUILTIN_PHADDW128,
- IX86_BUILTIN_PHADDD128,
- IX86_BUILTIN_PHADDSW128,
- IX86_BUILTIN_PHSUBW128,
- IX86_BUILTIN_PHSUBD128,
- IX86_BUILTIN_PHSUBSW128,
- IX86_BUILTIN_PMADDUBSW128,
- IX86_BUILTIN_PMULHRSW128,
- IX86_BUILTIN_PSHUFB128,
- IX86_BUILTIN_PSIGNB128,
- IX86_BUILTIN_PSIGNW128,
- IX86_BUILTIN_PSIGND128,
- IX86_BUILTIN_PALIGNR128,
- IX86_BUILTIN_PABSB128,
- IX86_BUILTIN_PABSW128,
- IX86_BUILTIN_PABSD128,
-
- /* AMDFAM10 - SSE4A New Instructions. */
- IX86_BUILTIN_MOVNTSD,
- IX86_BUILTIN_MOVNTSS,
- IX86_BUILTIN_EXTRQI,
- IX86_BUILTIN_EXTRQ,
- IX86_BUILTIN_INSERTQI,
- IX86_BUILTIN_INSERTQ,
-
- /* SSE4.1. */
- IX86_BUILTIN_BLENDPD,
- IX86_BUILTIN_BLENDPS,
- IX86_BUILTIN_BLENDVPD,
- IX86_BUILTIN_BLENDVPS,
- IX86_BUILTIN_PBLENDVB128,
- IX86_BUILTIN_PBLENDW128,
-
- IX86_BUILTIN_DPPD,
- IX86_BUILTIN_DPPS,
-
- IX86_BUILTIN_INSERTPS128,
-
- IX86_BUILTIN_MOVNTDQA,
- IX86_BUILTIN_MPSADBW128,
- IX86_BUILTIN_PACKUSDW128,
- IX86_BUILTIN_PCMPEQQ,
- IX86_BUILTIN_PHMINPOSUW128,
-
- IX86_BUILTIN_PMAXSB128,
- IX86_BUILTIN_PMAXSD128,
- IX86_BUILTIN_PMAXUD128,
- IX86_BUILTIN_PMAXUW128,
-
- IX86_BUILTIN_PMINSB128,
- IX86_BUILTIN_PMINSD128,
- IX86_BUILTIN_PMINUD128,
- IX86_BUILTIN_PMINUW128,
-
- IX86_BUILTIN_PMOVSXBW128,
- IX86_BUILTIN_PMOVSXBD128,
- IX86_BUILTIN_PMOVSXBQ128,
- IX86_BUILTIN_PMOVSXWD128,
- IX86_BUILTIN_PMOVSXWQ128,
- IX86_BUILTIN_PMOVSXDQ128,
-
- IX86_BUILTIN_PMOVZXBW128,
- IX86_BUILTIN_PMOVZXBD128,
- IX86_BUILTIN_PMOVZXBQ128,
- IX86_BUILTIN_PMOVZXWD128,
- IX86_BUILTIN_PMOVZXWQ128,
- IX86_BUILTIN_PMOVZXDQ128,
-
- IX86_BUILTIN_PMULDQ128,
- IX86_BUILTIN_PMULLD128,
-
- IX86_BUILTIN_ROUNDSD,
- IX86_BUILTIN_ROUNDSS,
-
- IX86_BUILTIN_ROUNDPD,
- IX86_BUILTIN_ROUNDPS,
-
- IX86_BUILTIN_FLOORPD,
- IX86_BUILTIN_CEILPD,
- IX86_BUILTIN_TRUNCPD,
- IX86_BUILTIN_RINTPD,
- IX86_BUILTIN_ROUNDPD_AZ,
-
- IX86_BUILTIN_FLOORPD_VEC_PACK_SFIX,
- IX86_BUILTIN_CEILPD_VEC_PACK_SFIX,
- IX86_BUILTIN_ROUNDPD_AZ_VEC_PACK_SFIX,
-
- IX86_BUILTIN_FLOORPS,
- IX86_BUILTIN_CEILPS,
- IX86_BUILTIN_TRUNCPS,
- IX86_BUILTIN_RINTPS,
- IX86_BUILTIN_ROUNDPS_AZ,
-
- IX86_BUILTIN_FLOORPS_SFIX,
- IX86_BUILTIN_CEILPS_SFIX,
- IX86_BUILTIN_ROUNDPS_AZ_SFIX,
-
- IX86_BUILTIN_PTESTZ,
- IX86_BUILTIN_PTESTC,
- IX86_BUILTIN_PTESTNZC,
-
- IX86_BUILTIN_VEC_INIT_V2SI,
- IX86_BUILTIN_VEC_INIT_V4HI,
- IX86_BUILTIN_VEC_INIT_V8QI,
- IX86_BUILTIN_VEC_EXT_V2DF,
- IX86_BUILTIN_VEC_EXT_V2DI,
- IX86_BUILTIN_VEC_EXT_V4SF,
- IX86_BUILTIN_VEC_EXT_V4SI,
- IX86_BUILTIN_VEC_EXT_V8HI,
- IX86_BUILTIN_VEC_EXT_V2SI,
- IX86_BUILTIN_VEC_EXT_V4HI,
- IX86_BUILTIN_VEC_EXT_V16QI,
- IX86_BUILTIN_VEC_SET_V2DI,
- IX86_BUILTIN_VEC_SET_V4SF,
- IX86_BUILTIN_VEC_SET_V4SI,
- IX86_BUILTIN_VEC_SET_V8HI,
- IX86_BUILTIN_VEC_SET_V4HI,
- IX86_BUILTIN_VEC_SET_V16QI,
-
- IX86_BUILTIN_VEC_PACK_SFIX,
- IX86_BUILTIN_VEC_PACK_SFIX256,
-
- /* SSE4.2. */
- IX86_BUILTIN_CRC32QI,
- IX86_BUILTIN_CRC32HI,
- IX86_BUILTIN_CRC32SI,
- IX86_BUILTIN_CRC32DI,
-
- IX86_BUILTIN_PCMPESTRI128,
- IX86_BUILTIN_PCMPESTRM128,
- IX86_BUILTIN_PCMPESTRA128,
- IX86_BUILTIN_PCMPESTRC128,
- IX86_BUILTIN_PCMPESTRO128,
- IX86_BUILTIN_PCMPESTRS128,
- IX86_BUILTIN_PCMPESTRZ128,
- IX86_BUILTIN_PCMPISTRI128,
- IX86_BUILTIN_PCMPISTRM128,
- IX86_BUILTIN_PCMPISTRA128,
- IX86_BUILTIN_PCMPISTRC128,
- IX86_BUILTIN_PCMPISTRO128,
- IX86_BUILTIN_PCMPISTRS128,
- IX86_BUILTIN_PCMPISTRZ128,
-
- IX86_BUILTIN_PCMPGTQ,
-
- /* AES instructions */
- IX86_BUILTIN_AESENC128,
- IX86_BUILTIN_AESENCLAST128,
- IX86_BUILTIN_AESDEC128,
- IX86_BUILTIN_AESDECLAST128,
- IX86_BUILTIN_AESIMC128,
- IX86_BUILTIN_AESKEYGENASSIST128,
-
- /* PCLMUL instruction */
- IX86_BUILTIN_PCLMULQDQ128,
-
- /* AVX */
- IX86_BUILTIN_ADDPD256,
- IX86_BUILTIN_ADDPS256,
- IX86_BUILTIN_ADDSUBPD256,
- IX86_BUILTIN_ADDSUBPS256,
- IX86_BUILTIN_ANDPD256,
- IX86_BUILTIN_ANDPS256,
- IX86_BUILTIN_ANDNPD256,
- IX86_BUILTIN_ANDNPS256,
- IX86_BUILTIN_BLENDPD256,
- IX86_BUILTIN_BLENDPS256,
- IX86_BUILTIN_BLENDVPD256,
- IX86_BUILTIN_BLENDVPS256,
- IX86_BUILTIN_DIVPD256,
- IX86_BUILTIN_DIVPS256,
- IX86_BUILTIN_DPPS256,
- IX86_BUILTIN_HADDPD256,
- IX86_BUILTIN_HADDPS256,
- IX86_BUILTIN_HSUBPD256,
- IX86_BUILTIN_HSUBPS256,
- IX86_BUILTIN_MAXPD256,
- IX86_BUILTIN_MAXPS256,
- IX86_BUILTIN_MINPD256,
- IX86_BUILTIN_MINPS256,
- IX86_BUILTIN_MULPD256,
- IX86_BUILTIN_MULPS256,
- IX86_BUILTIN_ORPD256,
- IX86_BUILTIN_ORPS256,
- IX86_BUILTIN_SHUFPD256,
- IX86_BUILTIN_SHUFPS256,
- IX86_BUILTIN_SUBPD256,
- IX86_BUILTIN_SUBPS256,
- IX86_BUILTIN_XORPD256,
- IX86_BUILTIN_XORPS256,
- IX86_BUILTIN_CMPSD,
- IX86_BUILTIN_CMPSS,
- IX86_BUILTIN_CMPPD,
- IX86_BUILTIN_CMPPS,
- IX86_BUILTIN_CMPPD256,
- IX86_BUILTIN_CMPPS256,
- IX86_BUILTIN_CVTDQ2PD256,
- IX86_BUILTIN_CVTDQ2PS256,
- IX86_BUILTIN_CVTPD2PS256,
- IX86_BUILTIN_CVTPS2DQ256,
- IX86_BUILTIN_CVTPS2PD256,
- IX86_BUILTIN_CVTTPD2DQ256,
- IX86_BUILTIN_CVTPD2DQ256,
- IX86_BUILTIN_CVTTPS2DQ256,
- IX86_BUILTIN_EXTRACTF128PD256,
- IX86_BUILTIN_EXTRACTF128PS256,
- IX86_BUILTIN_EXTRACTF128SI256,
- IX86_BUILTIN_VZEROALL,
- IX86_BUILTIN_VZEROUPPER,
- IX86_BUILTIN_VPERMILVARPD,
- IX86_BUILTIN_VPERMILVARPS,
- IX86_BUILTIN_VPERMILVARPD256,
- IX86_BUILTIN_VPERMILVARPS256,
- IX86_BUILTIN_VPERMILPD,
- IX86_BUILTIN_VPERMILPS,
- IX86_BUILTIN_VPERMILPD256,
- IX86_BUILTIN_VPERMILPS256,
- IX86_BUILTIN_VPERMIL2PD,
- IX86_BUILTIN_VPERMIL2PS,
- IX86_BUILTIN_VPERMIL2PD256,
- IX86_BUILTIN_VPERMIL2PS256,
- IX86_BUILTIN_VPERM2F128PD256,
- IX86_BUILTIN_VPERM2F128PS256,
- IX86_BUILTIN_VPERM2F128SI256,
- IX86_BUILTIN_VBROADCASTSS,
- IX86_BUILTIN_VBROADCASTSD256,
- IX86_BUILTIN_VBROADCASTSS256,
- IX86_BUILTIN_VBROADCASTPD256,
- IX86_BUILTIN_VBROADCASTPS256,
- IX86_BUILTIN_VINSERTF128PD256,
- IX86_BUILTIN_VINSERTF128PS256,
- IX86_BUILTIN_VINSERTF128SI256,
- IX86_BUILTIN_LOADUPD256,
- IX86_BUILTIN_LOADUPS256,
- IX86_BUILTIN_STOREUPD256,
- IX86_BUILTIN_STOREUPS256,
- IX86_BUILTIN_LDDQU256,
- IX86_BUILTIN_MOVNTDQ256,
- IX86_BUILTIN_MOVNTPD256,
- IX86_BUILTIN_MOVNTPS256,
- IX86_BUILTIN_LOADDQU256,
- IX86_BUILTIN_STOREDQU256,
- IX86_BUILTIN_MASKLOADPD,
- IX86_BUILTIN_MASKLOADPS,
- IX86_BUILTIN_MASKSTOREPD,
- IX86_BUILTIN_MASKSTOREPS,
- IX86_BUILTIN_MASKLOADPD256,
- IX86_BUILTIN_MASKLOADPS256,
- IX86_BUILTIN_MASKSTOREPD256,
- IX86_BUILTIN_MASKSTOREPS256,
- IX86_BUILTIN_MOVSHDUP256,
- IX86_BUILTIN_MOVSLDUP256,
- IX86_BUILTIN_MOVDDUP256,
-
- IX86_BUILTIN_SQRTPD256,
- IX86_BUILTIN_SQRTPS256,
- IX86_BUILTIN_SQRTPS_NR256,
- IX86_BUILTIN_RSQRTPS256,
- IX86_BUILTIN_RSQRTPS_NR256,
-
- IX86_BUILTIN_RCPPS256,
-
- IX86_BUILTIN_ROUNDPD256,
- IX86_BUILTIN_ROUNDPS256,
-
- IX86_BUILTIN_FLOORPD256,
- IX86_BUILTIN_CEILPD256,
- IX86_BUILTIN_TRUNCPD256,
- IX86_BUILTIN_RINTPD256,
- IX86_BUILTIN_ROUNDPD_AZ256,
-
- IX86_BUILTIN_FLOORPD_VEC_PACK_SFIX256,
- IX86_BUILTIN_CEILPD_VEC_PACK_SFIX256,
- IX86_BUILTIN_ROUNDPD_AZ_VEC_PACK_SFIX256,
-
- IX86_BUILTIN_FLOORPS256,
- IX86_BUILTIN_CEILPS256,
- IX86_BUILTIN_TRUNCPS256,
- IX86_BUILTIN_RINTPS256,
- IX86_BUILTIN_ROUNDPS_AZ256,
-
- IX86_BUILTIN_FLOORPS_SFIX256,
- IX86_BUILTIN_CEILPS_SFIX256,
- IX86_BUILTIN_ROUNDPS_AZ_SFIX256,
-
- IX86_BUILTIN_UNPCKHPD256,
- IX86_BUILTIN_UNPCKLPD256,
- IX86_BUILTIN_UNPCKHPS256,
- IX86_BUILTIN_UNPCKLPS256,
-
- IX86_BUILTIN_SI256_SI,
- IX86_BUILTIN_PS256_PS,
- IX86_BUILTIN_PD256_PD,
- IX86_BUILTIN_SI_SI256,
- IX86_BUILTIN_PS_PS256,
- IX86_BUILTIN_PD_PD256,
-
- IX86_BUILTIN_VTESTZPD,
- IX86_BUILTIN_VTESTCPD,
- IX86_BUILTIN_VTESTNZCPD,
- IX86_BUILTIN_VTESTZPS,
- IX86_BUILTIN_VTESTCPS,
- IX86_BUILTIN_VTESTNZCPS,
- IX86_BUILTIN_VTESTZPD256,
- IX86_BUILTIN_VTESTCPD256,
- IX86_BUILTIN_VTESTNZCPD256,
- IX86_BUILTIN_VTESTZPS256,
- IX86_BUILTIN_VTESTCPS256,
- IX86_BUILTIN_VTESTNZCPS256,
- IX86_BUILTIN_PTESTZ256,
- IX86_BUILTIN_PTESTC256,
- IX86_BUILTIN_PTESTNZC256,
-
- IX86_BUILTIN_MOVMSKPD256,
- IX86_BUILTIN_MOVMSKPS256,
-
- /* AVX2 */
- IX86_BUILTIN_MPSADBW256,
- IX86_BUILTIN_PABSB256,
- IX86_BUILTIN_PABSW256,
- IX86_BUILTIN_PABSD256,
- IX86_BUILTIN_PACKSSDW256,
- IX86_BUILTIN_PACKSSWB256,
- IX86_BUILTIN_PACKUSDW256,
- IX86_BUILTIN_PACKUSWB256,
- IX86_BUILTIN_PADDB256,
- IX86_BUILTIN_PADDW256,
- IX86_BUILTIN_PADDD256,
- IX86_BUILTIN_PADDQ256,
- IX86_BUILTIN_PADDSB256,
- IX86_BUILTIN_PADDSW256,
- IX86_BUILTIN_PADDUSB256,
- IX86_BUILTIN_PADDUSW256,
- IX86_BUILTIN_PALIGNR256,
- IX86_BUILTIN_AND256I,
- IX86_BUILTIN_ANDNOT256I,
- IX86_BUILTIN_PAVGB256,
- IX86_BUILTIN_PAVGW256,
- IX86_BUILTIN_PBLENDVB256,
- IX86_BUILTIN_PBLENDVW256,
- IX86_BUILTIN_PCMPEQB256,
- IX86_BUILTIN_PCMPEQW256,
- IX86_BUILTIN_PCMPEQD256,
- IX86_BUILTIN_PCMPEQQ256,
- IX86_BUILTIN_PCMPGTB256,
- IX86_BUILTIN_PCMPGTW256,
- IX86_BUILTIN_PCMPGTD256,
- IX86_BUILTIN_PCMPGTQ256,
- IX86_BUILTIN_PHADDW256,
- IX86_BUILTIN_PHADDD256,
- IX86_BUILTIN_PHADDSW256,
- IX86_BUILTIN_PHSUBW256,
- IX86_BUILTIN_PHSUBD256,
- IX86_BUILTIN_PHSUBSW256,
- IX86_BUILTIN_PMADDUBSW256,
- IX86_BUILTIN_PMADDWD256,
- IX86_BUILTIN_PMAXSB256,
- IX86_BUILTIN_PMAXSW256,
- IX86_BUILTIN_PMAXSD256,
- IX86_BUILTIN_PMAXUB256,
- IX86_BUILTIN_PMAXUW256,
- IX86_BUILTIN_PMAXUD256,
- IX86_BUILTIN_PMINSB256,
- IX86_BUILTIN_PMINSW256,
- IX86_BUILTIN_PMINSD256,
- IX86_BUILTIN_PMINUB256,
- IX86_BUILTIN_PMINUW256,
- IX86_BUILTIN_PMINUD256,
- IX86_BUILTIN_PMOVMSKB256,
- IX86_BUILTIN_PMOVSXBW256,
- IX86_BUILTIN_PMOVSXBD256,
- IX86_BUILTIN_PMOVSXBQ256,
- IX86_BUILTIN_PMOVSXWD256,
- IX86_BUILTIN_PMOVSXWQ256,
- IX86_BUILTIN_PMOVSXDQ256,
- IX86_BUILTIN_PMOVZXBW256,
- IX86_BUILTIN_PMOVZXBD256,
- IX86_BUILTIN_PMOVZXBQ256,
- IX86_BUILTIN_PMOVZXWD256,
- IX86_BUILTIN_PMOVZXWQ256,
- IX86_BUILTIN_PMOVZXDQ256,
- IX86_BUILTIN_PMULDQ256,
- IX86_BUILTIN_PMULHRSW256,
- IX86_BUILTIN_PMULHUW256,
- IX86_BUILTIN_PMULHW256,
- IX86_BUILTIN_PMULLW256,
- IX86_BUILTIN_PMULLD256,
- IX86_BUILTIN_PMULUDQ256,
- IX86_BUILTIN_POR256,
- IX86_BUILTIN_PSADBW256,
- IX86_BUILTIN_PSHUFB256,
- IX86_BUILTIN_PSHUFD256,
- IX86_BUILTIN_PSHUFHW256,
- IX86_BUILTIN_PSHUFLW256,
- IX86_BUILTIN_PSIGNB256,
- IX86_BUILTIN_PSIGNW256,
- IX86_BUILTIN_PSIGND256,
- IX86_BUILTIN_PSLLDQI256,
- IX86_BUILTIN_PSLLWI256,
- IX86_BUILTIN_PSLLW256,
- IX86_BUILTIN_PSLLDI256,
- IX86_BUILTIN_PSLLD256,
- IX86_BUILTIN_PSLLQI256,
- IX86_BUILTIN_PSLLQ256,
- IX86_BUILTIN_PSRAWI256,
- IX86_BUILTIN_PSRAW256,
- IX86_BUILTIN_PSRADI256,
- IX86_BUILTIN_PSRAD256,
- IX86_BUILTIN_PSRLDQI256,
- IX86_BUILTIN_PSRLWI256,
- IX86_BUILTIN_PSRLW256,
- IX86_BUILTIN_PSRLDI256,
- IX86_BUILTIN_PSRLD256,
- IX86_BUILTIN_PSRLQI256,
- IX86_BUILTIN_PSRLQ256,
- IX86_BUILTIN_PSUBB256,
- IX86_BUILTIN_PSUBW256,
- IX86_BUILTIN_PSUBD256,
- IX86_BUILTIN_PSUBQ256,
- IX86_BUILTIN_PSUBSB256,
- IX86_BUILTIN_PSUBSW256,
- IX86_BUILTIN_PSUBUSB256,
- IX86_BUILTIN_PSUBUSW256,
- IX86_BUILTIN_PUNPCKHBW256,
- IX86_BUILTIN_PUNPCKHWD256,
- IX86_BUILTIN_PUNPCKHDQ256,
- IX86_BUILTIN_PUNPCKHQDQ256,
- IX86_BUILTIN_PUNPCKLBW256,
- IX86_BUILTIN_PUNPCKLWD256,
- IX86_BUILTIN_PUNPCKLDQ256,
- IX86_BUILTIN_PUNPCKLQDQ256,
- IX86_BUILTIN_PXOR256,
- IX86_BUILTIN_MOVNTDQA256,
- IX86_BUILTIN_VBROADCASTSS_PS,
- IX86_BUILTIN_VBROADCASTSS_PS256,
- IX86_BUILTIN_VBROADCASTSD_PD256,
- IX86_BUILTIN_VBROADCASTSI256,
- IX86_BUILTIN_PBLENDD256,
- IX86_BUILTIN_PBLENDD128,
- IX86_BUILTIN_PBROADCASTB256,
- IX86_BUILTIN_PBROADCASTW256,
- IX86_BUILTIN_PBROADCASTD256,
- IX86_BUILTIN_PBROADCASTQ256,
- IX86_BUILTIN_PBROADCASTB128,
- IX86_BUILTIN_PBROADCASTW128,
- IX86_BUILTIN_PBROADCASTD128,
- IX86_BUILTIN_PBROADCASTQ128,
- IX86_BUILTIN_VPERMVARSI256,
- IX86_BUILTIN_VPERMDF256,
- IX86_BUILTIN_VPERMVARSF256,
- IX86_BUILTIN_VPERMDI256,
- IX86_BUILTIN_VPERMTI256,
- IX86_BUILTIN_VEXTRACT128I256,
- IX86_BUILTIN_VINSERT128I256,
- IX86_BUILTIN_MASKLOADD,
- IX86_BUILTIN_MASKLOADQ,
- IX86_BUILTIN_MASKLOADD256,
- IX86_BUILTIN_MASKLOADQ256,
- IX86_BUILTIN_MASKSTORED,
- IX86_BUILTIN_MASKSTOREQ,
- IX86_BUILTIN_MASKSTORED256,
- IX86_BUILTIN_MASKSTOREQ256,
- IX86_BUILTIN_PSLLVV4DI,
- IX86_BUILTIN_PSLLVV2DI,
- IX86_BUILTIN_PSLLVV8SI,
- IX86_BUILTIN_PSLLVV4SI,
- IX86_BUILTIN_PSRAVV8SI,
- IX86_BUILTIN_PSRAVV4SI,
- IX86_BUILTIN_PSRLVV4DI,
- IX86_BUILTIN_PSRLVV2DI,
- IX86_BUILTIN_PSRLVV8SI,
- IX86_BUILTIN_PSRLVV4SI,
-
- IX86_BUILTIN_GATHERSIV2DF,
- IX86_BUILTIN_GATHERSIV4DF,
- IX86_BUILTIN_GATHERDIV2DF,
- IX86_BUILTIN_GATHERDIV4DF,
- IX86_BUILTIN_GATHERSIV4SF,
- IX86_BUILTIN_GATHERSIV8SF,
- IX86_BUILTIN_GATHERDIV4SF,
- IX86_BUILTIN_GATHERDIV8SF,
- IX86_BUILTIN_GATHERSIV2DI,
- IX86_BUILTIN_GATHERSIV4DI,
- IX86_BUILTIN_GATHERDIV2DI,
- IX86_BUILTIN_GATHERDIV4DI,
- IX86_BUILTIN_GATHERSIV4SI,
- IX86_BUILTIN_GATHERSIV8SI,
- IX86_BUILTIN_GATHERDIV4SI,
- IX86_BUILTIN_GATHERDIV8SI,
-
- /* Alternate 4 element gather for the vectorizer where
- all operands are 32-byte wide. */
- IX86_BUILTIN_GATHERALTSIV4DF,
- IX86_BUILTIN_GATHERALTDIV8SF,
- IX86_BUILTIN_GATHERALTSIV4DI,
- IX86_BUILTIN_GATHERALTDIV8SI,
-
- /* TFmode support builtins. */
- IX86_BUILTIN_INFQ,
- IX86_BUILTIN_HUGE_VALQ,
- IX86_BUILTIN_FABSQ,
- IX86_BUILTIN_COPYSIGNQ,
-
- /* Vectorizer support builtins. */
- IX86_BUILTIN_CPYSGNPS,
- IX86_BUILTIN_CPYSGNPD,
- IX86_BUILTIN_CPYSGNPS256,
- IX86_BUILTIN_CPYSGNPD256,
-
- /* FMA4 instructions. */
- IX86_BUILTIN_VFMADDSS,
- IX86_BUILTIN_VFMADDSD,
- IX86_BUILTIN_VFMADDPS,
- IX86_BUILTIN_VFMADDPD,
- IX86_BUILTIN_VFMADDPS256,
- IX86_BUILTIN_VFMADDPD256,
- IX86_BUILTIN_VFMADDSUBPS,
- IX86_BUILTIN_VFMADDSUBPD,
- IX86_BUILTIN_VFMADDSUBPS256,
- IX86_BUILTIN_VFMADDSUBPD256,
-
- /* FMA3 instructions. */
- IX86_BUILTIN_VFMADDSS3,
- IX86_BUILTIN_VFMADDSD3,
-
- /* XOP instructions. */
- IX86_BUILTIN_VPCMOV,
- IX86_BUILTIN_VPCMOV_V2DI,
- IX86_BUILTIN_VPCMOV_V4SI,
- IX86_BUILTIN_VPCMOV_V8HI,
- IX86_BUILTIN_VPCMOV_V16QI,
- IX86_BUILTIN_VPCMOV_V4SF,
- IX86_BUILTIN_VPCMOV_V2DF,
- IX86_BUILTIN_VPCMOV256,
- IX86_BUILTIN_VPCMOV_V4DI256,
- IX86_BUILTIN_VPCMOV_V8SI256,
- IX86_BUILTIN_VPCMOV_V16HI256,
- IX86_BUILTIN_VPCMOV_V32QI256,
- IX86_BUILTIN_VPCMOV_V8SF256,
- IX86_BUILTIN_VPCMOV_V4DF256,
-
- IX86_BUILTIN_VPPERM,
-
- IX86_BUILTIN_VPMACSSWW,
- IX86_BUILTIN_VPMACSWW,
- IX86_BUILTIN_VPMACSSWD,
- IX86_BUILTIN_VPMACSWD,
- IX86_BUILTIN_VPMACSSDD,
- IX86_BUILTIN_VPMACSDD,
- IX86_BUILTIN_VPMACSSDQL,
- IX86_BUILTIN_VPMACSSDQH,
- IX86_BUILTIN_VPMACSDQL,
- IX86_BUILTIN_VPMACSDQH,
- IX86_BUILTIN_VPMADCSSWD,
- IX86_BUILTIN_VPMADCSWD,
-
- IX86_BUILTIN_VPHADDBW,
- IX86_BUILTIN_VPHADDBD,
- IX86_BUILTIN_VPHADDBQ,
- IX86_BUILTIN_VPHADDWD,
- IX86_BUILTIN_VPHADDWQ,
- IX86_BUILTIN_VPHADDDQ,
- IX86_BUILTIN_VPHADDUBW,
- IX86_BUILTIN_VPHADDUBD,
- IX86_BUILTIN_VPHADDUBQ,
- IX86_BUILTIN_VPHADDUWD,
- IX86_BUILTIN_VPHADDUWQ,
- IX86_BUILTIN_VPHADDUDQ,
- IX86_BUILTIN_VPHSUBBW,
- IX86_BUILTIN_VPHSUBWD,
- IX86_BUILTIN_VPHSUBDQ,
-
- IX86_BUILTIN_VPROTB,
- IX86_BUILTIN_VPROTW,
- IX86_BUILTIN_VPROTD,
- IX86_BUILTIN_VPROTQ,
- IX86_BUILTIN_VPROTB_IMM,
- IX86_BUILTIN_VPROTW_IMM,
- IX86_BUILTIN_VPROTD_IMM,
- IX86_BUILTIN_VPROTQ_IMM,
-
- IX86_BUILTIN_VPSHLB,
- IX86_BUILTIN_VPSHLW,
- IX86_BUILTIN_VPSHLD,
- IX86_BUILTIN_VPSHLQ,
- IX86_BUILTIN_VPSHAB,
- IX86_BUILTIN_VPSHAW,
- IX86_BUILTIN_VPSHAD,
- IX86_BUILTIN_VPSHAQ,
-
- IX86_BUILTIN_VFRCZSS,
- IX86_BUILTIN_VFRCZSD,
- IX86_BUILTIN_VFRCZPS,
- IX86_BUILTIN_VFRCZPD,
- IX86_BUILTIN_VFRCZPS256,
- IX86_BUILTIN_VFRCZPD256,
-
- IX86_BUILTIN_VPCOMEQUB,
- IX86_BUILTIN_VPCOMNEUB,
- IX86_BUILTIN_VPCOMLTUB,
- IX86_BUILTIN_VPCOMLEUB,
- IX86_BUILTIN_VPCOMGTUB,
- IX86_BUILTIN_VPCOMGEUB,
- IX86_BUILTIN_VPCOMFALSEUB,
- IX86_BUILTIN_VPCOMTRUEUB,
-
- IX86_BUILTIN_VPCOMEQUW,
- IX86_BUILTIN_VPCOMNEUW,
- IX86_BUILTIN_VPCOMLTUW,
- IX86_BUILTIN_VPCOMLEUW,
- IX86_BUILTIN_VPCOMGTUW,
- IX86_BUILTIN_VPCOMGEUW,
- IX86_BUILTIN_VPCOMFALSEUW,
- IX86_BUILTIN_VPCOMTRUEUW,
-
- IX86_BUILTIN_VPCOMEQUD,
- IX86_BUILTIN_VPCOMNEUD,
- IX86_BUILTIN_VPCOMLTUD,
- IX86_BUILTIN_VPCOMLEUD,
- IX86_BUILTIN_VPCOMGTUD,
- IX86_BUILTIN_VPCOMGEUD,
- IX86_BUILTIN_VPCOMFALSEUD,
- IX86_BUILTIN_VPCOMTRUEUD,
-
- IX86_BUILTIN_VPCOMEQUQ,
- IX86_BUILTIN_VPCOMNEUQ,
- IX86_BUILTIN_VPCOMLTUQ,
- IX86_BUILTIN_VPCOMLEUQ,
- IX86_BUILTIN_VPCOMGTUQ,
- IX86_BUILTIN_VPCOMGEUQ,
- IX86_BUILTIN_VPCOMFALSEUQ,
- IX86_BUILTIN_VPCOMTRUEUQ,
-
- IX86_BUILTIN_VPCOMEQB,
- IX86_BUILTIN_VPCOMNEB,
- IX86_BUILTIN_VPCOMLTB,
- IX86_BUILTIN_VPCOMLEB,
- IX86_BUILTIN_VPCOMGTB,
- IX86_BUILTIN_VPCOMGEB,
- IX86_BUILTIN_VPCOMFALSEB,
- IX86_BUILTIN_VPCOMTRUEB,
-
- IX86_BUILTIN_VPCOMEQW,
- IX86_BUILTIN_VPCOMNEW,
- IX86_BUILTIN_VPCOMLTW,
- IX86_BUILTIN_VPCOMLEW,
- IX86_BUILTIN_VPCOMGTW,
- IX86_BUILTIN_VPCOMGEW,
- IX86_BUILTIN_VPCOMFALSEW,
- IX86_BUILTIN_VPCOMTRUEW,
-
- IX86_BUILTIN_VPCOMEQD,
- IX86_BUILTIN_VPCOMNED,
- IX86_BUILTIN_VPCOMLTD,
- IX86_BUILTIN_VPCOMLED,
- IX86_BUILTIN_VPCOMGTD,
- IX86_BUILTIN_VPCOMGED,
- IX86_BUILTIN_VPCOMFALSED,
- IX86_BUILTIN_VPCOMTRUED,
-
- IX86_BUILTIN_VPCOMEQQ,
- IX86_BUILTIN_VPCOMNEQ,
- IX86_BUILTIN_VPCOMLTQ,
- IX86_BUILTIN_VPCOMLEQ,
- IX86_BUILTIN_VPCOMGTQ,
- IX86_BUILTIN_VPCOMGEQ,
- IX86_BUILTIN_VPCOMFALSEQ,
- IX86_BUILTIN_VPCOMTRUEQ,
-
- /* LWP instructions. */
- IX86_BUILTIN_LLWPCB,
- IX86_BUILTIN_SLWPCB,
- IX86_BUILTIN_LWPVAL32,
- IX86_BUILTIN_LWPVAL64,
- IX86_BUILTIN_LWPINS32,
- IX86_BUILTIN_LWPINS64,
-
- IX86_BUILTIN_CLZS,
-
- /* RTM */
- IX86_BUILTIN_XBEGIN,
- IX86_BUILTIN_XEND,
- IX86_BUILTIN_XABORT,
- IX86_BUILTIN_XTEST,
-
- /* BMI instructions. */
- IX86_BUILTIN_BEXTR32,
- IX86_BUILTIN_BEXTR64,
- IX86_BUILTIN_CTZS,
-
- /* TBM instructions. */
- IX86_BUILTIN_BEXTRI32,
- IX86_BUILTIN_BEXTRI64,
-
- /* BMI2 instructions. */
- IX86_BUILTIN_BZHI32,
- IX86_BUILTIN_BZHI64,
- IX86_BUILTIN_PDEP32,
- IX86_BUILTIN_PDEP64,
- IX86_BUILTIN_PEXT32,
- IX86_BUILTIN_PEXT64,
-
- /* ADX instructions. */
- IX86_BUILTIN_ADDCARRYX32,
- IX86_BUILTIN_ADDCARRYX64,
-
- /* FSGSBASE instructions. */
- IX86_BUILTIN_RDFSBASE32,
- IX86_BUILTIN_RDFSBASE64,
- IX86_BUILTIN_RDGSBASE32,
- IX86_BUILTIN_RDGSBASE64,
- IX86_BUILTIN_WRFSBASE32,
- IX86_BUILTIN_WRFSBASE64,
- IX86_BUILTIN_WRGSBASE32,
- IX86_BUILTIN_WRGSBASE64,
-
- /* RDRND instructions. */
- IX86_BUILTIN_RDRAND16_STEP,
- IX86_BUILTIN_RDRAND32_STEP,
- IX86_BUILTIN_RDRAND64_STEP,
-
- /* RDSEED instructions. */
- IX86_BUILTIN_RDSEED16_STEP,
- IX86_BUILTIN_RDSEED32_STEP,
- IX86_BUILTIN_RDSEED64_STEP,
-
- /* F16C instructions. */
- IX86_BUILTIN_CVTPH2PS,
- IX86_BUILTIN_CVTPH2PS256,
- IX86_BUILTIN_CVTPS2PH,
- IX86_BUILTIN_CVTPS2PH256,
-
- /* CFString built-in for darwin */
- IX86_BUILTIN_CFSTRING,
-
- /* Builtins to get CPU type and supported features. */
- IX86_BUILTIN_CPU_INIT,
- IX86_BUILTIN_CPU_IS,
- IX86_BUILTIN_CPU_SUPPORTS,
-
- IX86_BUILTIN_MAX
-};
-
-/* Table for the ix86 builtin decls. */
-static GTY(()) tree ix86_builtins[(int) IX86_BUILTIN_MAX];
-
-/* Table of all of the builtin functions that are possible with different ISA's
- but are waiting to be built until a function is declared to use that
- ISA. */
-struct builtin_isa {
- const char *name; /* function name */
- enum ix86_builtin_func_type tcode; /* type to use in the declaration */
- HOST_WIDE_INT isa; /* isa_flags this builtin is defined for */
- bool const_p; /* true if the declaration is constant */
- bool set_and_not_built_p;
-};
-
-static struct builtin_isa ix86_builtins_isa[(int) IX86_BUILTIN_MAX];
-
-
-/* Add an ix86 target builtin function with CODE, NAME and TYPE. Save the MASK
- of which isa_flags to use in the ix86_builtins_isa array. Stores the
- function decl in the ix86_builtins array. Returns the function decl or
- NULL_TREE, if the builtin was not added.
-
- If the front end has a special hook for builtin functions, delay adding
- builtin functions that aren't in the current ISA until the ISA is changed
- with function specific optimization. Doing so, can save about 300K for the
- default compiler. When the builtin is expanded, check at that time whether
- it is valid.
-
- If the front end doesn't have a special hook, record all builtins, even if
- it isn't an instruction set in the current ISA in case the user uses
- function specific options for a different ISA, so that we don't get scope
- errors if a builtin is added in the middle of a function scope. */
-
-static inline tree
-def_builtin (HOST_WIDE_INT mask, const char *name,
- enum ix86_builtin_func_type tcode,
- enum ix86_builtins code)
-{
- tree decl = NULL_TREE;
-
- if (!(mask & OPTION_MASK_ISA_64BIT) || TARGET_64BIT)
- {
- ix86_builtins_isa[(int) code].isa = mask;
-
- mask &= ~OPTION_MASK_ISA_64BIT;
- if (mask == 0
- || (mask & ix86_isa_flags) != 0
- || (lang_hooks.builtin_function
- == lang_hooks.builtin_function_ext_scope))
-
- {
- tree type = ix86_get_builtin_func_type (tcode);
- decl = add_builtin_function (name, type, code, BUILT_IN_MD,
- NULL, NULL_TREE);
- ix86_builtins[(int) code] = decl;
- ix86_builtins_isa[(int) code].set_and_not_built_p = false;
- }
- else
- {
- ix86_builtins[(int) code] = NULL_TREE;
- ix86_builtins_isa[(int) code].tcode = tcode;
- ix86_builtins_isa[(int) code].name = name;
- ix86_builtins_isa[(int) code].const_p = false;
- ix86_builtins_isa[(int) code].set_and_not_built_p = true;
- }
- }
-
- return decl;
-}
-
-/* Like def_builtin, but also marks the function decl "const". */
-
-static inline tree
-def_builtin_const (HOST_WIDE_INT mask, const char *name,
- enum ix86_builtin_func_type tcode, enum ix86_builtins code)
-{
- tree decl = def_builtin (mask, name, tcode, code);
- if (decl)
- TREE_READONLY (decl) = 1;
- else
- ix86_builtins_isa[(int) code].const_p = true;
-
- return decl;
-}
-
-/* Add any new builtin functions for a given ISA that may not have been
- declared. This saves a bit of space compared to adding all of the
- declarations to the tree, even if we didn't use them. */
-
-static void
-ix86_add_new_builtins (HOST_WIDE_INT isa)
-{
- int i;
-
- for (i = 0; i < (int)IX86_BUILTIN_MAX; i++)
- {
- if ((ix86_builtins_isa[i].isa & isa) != 0
- && ix86_builtins_isa[i].set_and_not_built_p)
- {
- tree decl, type;
-
- /* Don't define the builtin again. */
- ix86_builtins_isa[i].set_and_not_built_p = false;
-
- type = ix86_get_builtin_func_type (ix86_builtins_isa[i].tcode);
- decl = add_builtin_function_ext_scope (ix86_builtins_isa[i].name,
- type, i, BUILT_IN_MD, NULL,
- NULL_TREE);
-
- ix86_builtins[i] = decl;
- if (ix86_builtins_isa[i].const_p)
- TREE_READONLY (decl) = 1;
- }
- }
-}
-
-/* Bits for builtin_description.flag. */
-
-/* Set when we don't support the comparison natively, and should
- swap_comparison in order to support it. */
-#define BUILTIN_DESC_SWAP_OPERANDS 1
-
-struct builtin_description
-{
- const HOST_WIDE_INT mask;
- const enum insn_code icode;
- const char *const name;
- const enum ix86_builtins code;
- const enum rtx_code comparison;
- const int flag;
-};
-
-static const struct builtin_description bdesc_comi[] =
-{
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_comi, "__builtin_ia32_comieq", IX86_BUILTIN_COMIEQSS, UNEQ, 0 },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_comi, "__builtin_ia32_comilt", IX86_BUILTIN_COMILTSS, UNLT, 0 },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_comi, "__builtin_ia32_comile", IX86_BUILTIN_COMILESS, UNLE, 0 },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_comi, "__builtin_ia32_comigt", IX86_BUILTIN_COMIGTSS, GT, 0 },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_comi, "__builtin_ia32_comige", IX86_BUILTIN_COMIGESS, GE, 0 },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_comi, "__builtin_ia32_comineq", IX86_BUILTIN_COMINEQSS, LTGT, 0 },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomieq", IX86_BUILTIN_UCOMIEQSS, UNEQ, 0 },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomilt", IX86_BUILTIN_UCOMILTSS, UNLT, 0 },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomile", IX86_BUILTIN_UCOMILESS, UNLE, 0 },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomigt", IX86_BUILTIN_UCOMIGTSS, GT, 0 },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomige", IX86_BUILTIN_UCOMIGESS, GE, 0 },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomineq", IX86_BUILTIN_UCOMINEQSS, LTGT, 0 },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdeq", IX86_BUILTIN_COMIEQSD, UNEQ, 0 },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdlt", IX86_BUILTIN_COMILTSD, UNLT, 0 },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdle", IX86_BUILTIN_COMILESD, UNLE, 0 },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdgt", IX86_BUILTIN_COMIGTSD, GT, 0 },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdge", IX86_BUILTIN_COMIGESD, GE, 0 },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdneq", IX86_BUILTIN_COMINEQSD, LTGT, 0 },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdeq", IX86_BUILTIN_UCOMIEQSD, UNEQ, 0 },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdlt", IX86_BUILTIN_UCOMILTSD, UNLT, 0 },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdle", IX86_BUILTIN_UCOMILESD, UNLE, 0 },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdgt", IX86_BUILTIN_UCOMIGTSD, GT, 0 },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdge", IX86_BUILTIN_UCOMIGESD, GE, 0 },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdneq", IX86_BUILTIN_UCOMINEQSD, LTGT, 0 },
-};
-
-static const struct builtin_description bdesc_pcmpestr[] =
-{
- /* SSE4.2 */
- { OPTION_MASK_ISA_SSE4_2, CODE_FOR_sse4_2_pcmpestr, "__builtin_ia32_pcmpestri128", IX86_BUILTIN_PCMPESTRI128, UNKNOWN, 0 },
- { OPTION_MASK_ISA_SSE4_2, CODE_FOR_sse4_2_pcmpestr, "__builtin_ia32_pcmpestrm128", IX86_BUILTIN_PCMPESTRM128, UNKNOWN, 0 },
- { OPTION_MASK_ISA_SSE4_2, CODE_FOR_sse4_2_pcmpestr, "__builtin_ia32_pcmpestria128", IX86_BUILTIN_PCMPESTRA128, UNKNOWN, (int) CCAmode },
- { OPTION_MASK_ISA_SSE4_2, CODE_FOR_sse4_2_pcmpestr, "__builtin_ia32_pcmpestric128", IX86_BUILTIN_PCMPESTRC128, UNKNOWN, (int) CCCmode },
- { OPTION_MASK_ISA_SSE4_2, CODE_FOR_sse4_2_pcmpestr, "__builtin_ia32_pcmpestrio128", IX86_BUILTIN_PCMPESTRO128, UNKNOWN, (int) CCOmode },
- { OPTION_MASK_ISA_SSE4_2, CODE_FOR_sse4_2_pcmpestr, "__builtin_ia32_pcmpestris128", IX86_BUILTIN_PCMPESTRS128, UNKNOWN, (int) CCSmode },
- { OPTION_MASK_ISA_SSE4_2, CODE_FOR_sse4_2_pcmpestr, "__builtin_ia32_pcmpestriz128", IX86_BUILTIN_PCMPESTRZ128, UNKNOWN, (int) CCZmode },
-};
-
-static const struct builtin_description bdesc_pcmpistr[] =
-{
- /* SSE4.2 */
- { OPTION_MASK_ISA_SSE4_2, CODE_FOR_sse4_2_pcmpistr, "__builtin_ia32_pcmpistri128", IX86_BUILTIN_PCMPISTRI128, UNKNOWN, 0 },
- { OPTION_MASK_ISA_SSE4_2, CODE_FOR_sse4_2_pcmpistr, "__builtin_ia32_pcmpistrm128", IX86_BUILTIN_PCMPISTRM128, UNKNOWN, 0 },
- { OPTION_MASK_ISA_SSE4_2, CODE_FOR_sse4_2_pcmpistr, "__builtin_ia32_pcmpistria128", IX86_BUILTIN_PCMPISTRA128, UNKNOWN, (int) CCAmode },
- { OPTION_MASK_ISA_SSE4_2, CODE_FOR_sse4_2_pcmpistr, "__builtin_ia32_pcmpistric128", IX86_BUILTIN_PCMPISTRC128, UNKNOWN, (int) CCCmode },
- { OPTION_MASK_ISA_SSE4_2, CODE_FOR_sse4_2_pcmpistr, "__builtin_ia32_pcmpistrio128", IX86_BUILTIN_PCMPISTRO128, UNKNOWN, (int) CCOmode },
- { OPTION_MASK_ISA_SSE4_2, CODE_FOR_sse4_2_pcmpistr, "__builtin_ia32_pcmpistris128", IX86_BUILTIN_PCMPISTRS128, UNKNOWN, (int) CCSmode },
- { OPTION_MASK_ISA_SSE4_2, CODE_FOR_sse4_2_pcmpistr, "__builtin_ia32_pcmpistriz128", IX86_BUILTIN_PCMPISTRZ128, UNKNOWN, (int) CCZmode },
-};
-
-/* Special builtins with variable number of arguments. */
-static const struct builtin_description bdesc_special_args[] =
-{
- { ~OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_rdtsc", IX86_BUILTIN_RDTSC, UNKNOWN, (int) UINT64_FTYPE_VOID },
- { ~OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_rdtscp", IX86_BUILTIN_RDTSCP, UNKNOWN, (int) UINT64_FTYPE_PUNSIGNED },
- { ~OPTION_MASK_ISA_64BIT, CODE_FOR_pause, "__builtin_ia32_pause", IX86_BUILTIN_PAUSE, UNKNOWN, (int) VOID_FTYPE_VOID },
-
- /* MMX */
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_emms, "__builtin_ia32_emms", IX86_BUILTIN_EMMS, UNKNOWN, (int) VOID_FTYPE_VOID },
-
- /* 3DNow! */
- { OPTION_MASK_ISA_3DNOW, CODE_FOR_mmx_femms, "__builtin_ia32_femms", IX86_BUILTIN_FEMMS, UNKNOWN, (int) VOID_FTYPE_VOID },
-
- /* FXSR, XSAVE and XSAVEOPT */
- { OPTION_MASK_ISA_FXSR, CODE_FOR_nothing, "__builtin_ia32_fxsave", IX86_BUILTIN_FXSAVE, UNKNOWN, (int) VOID_FTYPE_PVOID },
- { OPTION_MASK_ISA_FXSR, CODE_FOR_nothing, "__builtin_ia32_fxrstor", IX86_BUILTIN_FXRSTOR, UNKNOWN, (int) VOID_FTYPE_PVOID },
- { OPTION_MASK_ISA_XSAVE, CODE_FOR_nothing, "__builtin_ia32_xsave", IX86_BUILTIN_XSAVE, UNKNOWN, (int) VOID_FTYPE_PVOID_INT64 },
- { OPTION_MASK_ISA_XSAVE, CODE_FOR_nothing, "__builtin_ia32_xrstor", IX86_BUILTIN_XRSTOR, UNKNOWN, (int) VOID_FTYPE_PVOID_INT64 },
- { OPTION_MASK_ISA_XSAVEOPT, CODE_FOR_nothing, "__builtin_ia32_xsaveopt", IX86_BUILTIN_XSAVEOPT, UNKNOWN, (int) VOID_FTYPE_PVOID_INT64 },
-
- { OPTION_MASK_ISA_FXSR | OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_fxsave64", IX86_BUILTIN_FXSAVE64, UNKNOWN, (int) VOID_FTYPE_PVOID },
- { OPTION_MASK_ISA_FXSR | OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_fxrstor64", IX86_BUILTIN_FXRSTOR64, UNKNOWN, (int) VOID_FTYPE_PVOID },
- { OPTION_MASK_ISA_XSAVE | OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_xsave64", IX86_BUILTIN_XSAVE64, UNKNOWN, (int) VOID_FTYPE_PVOID_INT64 },
- { OPTION_MASK_ISA_XSAVE | OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_xrstor64", IX86_BUILTIN_XRSTOR64, UNKNOWN, (int) VOID_FTYPE_PVOID_INT64 },
- { OPTION_MASK_ISA_XSAVEOPT | OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_xsaveopt64", IX86_BUILTIN_XSAVEOPT64, UNKNOWN, (int) VOID_FTYPE_PVOID_INT64 },
-
- /* SSE */
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_storeups, "__builtin_ia32_storeups", IX86_BUILTIN_STOREUPS, UNKNOWN, (int) VOID_FTYPE_PFLOAT_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_movntv4sf, "__builtin_ia32_movntps", IX86_BUILTIN_MOVNTPS, UNKNOWN, (int) VOID_FTYPE_PFLOAT_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_loadups, "__builtin_ia32_loadups", IX86_BUILTIN_LOADUPS, UNKNOWN, (int) V4SF_FTYPE_PCFLOAT },
-
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_loadhps_exp, "__builtin_ia32_loadhps", IX86_BUILTIN_LOADHPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_PCV2SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_loadlps_exp, "__builtin_ia32_loadlps", IX86_BUILTIN_LOADLPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_PCV2SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_storehps, "__builtin_ia32_storehps", IX86_BUILTIN_STOREHPS, UNKNOWN, (int) VOID_FTYPE_PV2SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_storelps, "__builtin_ia32_storelps", IX86_BUILTIN_STORELPS, UNKNOWN, (int) VOID_FTYPE_PV2SF_V4SF },
-
- /* SSE or 3DNow!A */
- { OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A, CODE_FOR_sse_sfence, "__builtin_ia32_sfence", IX86_BUILTIN_SFENCE, UNKNOWN, (int) VOID_FTYPE_VOID },
- { OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A, CODE_FOR_sse_movntq, "__builtin_ia32_movntq", IX86_BUILTIN_MOVNTQ, UNKNOWN, (int) VOID_FTYPE_PULONGLONG_ULONGLONG },
-
- /* SSE2 */
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_lfence, "__builtin_ia32_lfence", IX86_BUILTIN_LFENCE, UNKNOWN, (int) VOID_FTYPE_VOID },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_mfence, 0, IX86_BUILTIN_MFENCE, UNKNOWN, (int) VOID_FTYPE_VOID },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_storeupd, "__builtin_ia32_storeupd", IX86_BUILTIN_STOREUPD, UNKNOWN, (int) VOID_FTYPE_PDOUBLE_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_storedqu, "__builtin_ia32_storedqu", IX86_BUILTIN_STOREDQU, UNKNOWN, (int) VOID_FTYPE_PCHAR_V16QI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_movntv2df, "__builtin_ia32_movntpd", IX86_BUILTIN_MOVNTPD, UNKNOWN, (int) VOID_FTYPE_PDOUBLE_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_movntv2di, "__builtin_ia32_movntdq", IX86_BUILTIN_MOVNTDQ, UNKNOWN, (int) VOID_FTYPE_PV2DI_V2DI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_movntisi, "__builtin_ia32_movnti", IX86_BUILTIN_MOVNTI, UNKNOWN, (int) VOID_FTYPE_PINT_INT },
- { OPTION_MASK_ISA_SSE2 | OPTION_MASK_ISA_64BIT, CODE_FOR_sse2_movntidi, "__builtin_ia32_movnti64", IX86_BUILTIN_MOVNTI64, UNKNOWN, (int) VOID_FTYPE_PLONGLONG_LONGLONG },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_loadupd, "__builtin_ia32_loadupd", IX86_BUILTIN_LOADUPD, UNKNOWN, (int) V2DF_FTYPE_PCDOUBLE },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_loaddqu, "__builtin_ia32_loaddqu", IX86_BUILTIN_LOADDQU, UNKNOWN, (int) V16QI_FTYPE_PCCHAR },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_loadhpd_exp, "__builtin_ia32_loadhpd", IX86_BUILTIN_LOADHPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_PCDOUBLE },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_loadlpd_exp, "__builtin_ia32_loadlpd", IX86_BUILTIN_LOADLPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_PCDOUBLE },
-
- /* SSE3 */
- { OPTION_MASK_ISA_SSE3, CODE_FOR_sse3_lddqu, "__builtin_ia32_lddqu", IX86_BUILTIN_LDDQU, UNKNOWN, (int) V16QI_FTYPE_PCCHAR },
-
- /* SSE4.1 */
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_movntdqa, "__builtin_ia32_movntdqa", IX86_BUILTIN_MOVNTDQA, UNKNOWN, (int) V2DI_FTYPE_PV2DI },
-
- /* SSE4A */
- { OPTION_MASK_ISA_SSE4A, CODE_FOR_sse4a_vmmovntv2df, "__builtin_ia32_movntsd", IX86_BUILTIN_MOVNTSD, UNKNOWN, (int) VOID_FTYPE_PDOUBLE_V2DF },
- { OPTION_MASK_ISA_SSE4A, CODE_FOR_sse4a_vmmovntv4sf, "__builtin_ia32_movntss", IX86_BUILTIN_MOVNTSS, UNKNOWN, (int) VOID_FTYPE_PFLOAT_V4SF },
-
- /* AVX */
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vzeroall, "__builtin_ia32_vzeroall", IX86_BUILTIN_VZEROALL, UNKNOWN, (int) VOID_FTYPE_VOID },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vzeroupper, "__builtin_ia32_vzeroupper", IX86_BUILTIN_VZEROUPPER, UNKNOWN, (int) VOID_FTYPE_VOID },
-
- { OPTION_MASK_ISA_AVX, CODE_FOR_vec_dupv4sf, "__builtin_ia32_vbroadcastss", IX86_BUILTIN_VBROADCASTSS, UNKNOWN, (int) V4SF_FTYPE_PCFLOAT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_vec_dupv4df, "__builtin_ia32_vbroadcastsd256", IX86_BUILTIN_VBROADCASTSD256, UNKNOWN, (int) V4DF_FTYPE_PCDOUBLE },
- { OPTION_MASK_ISA_AVX, CODE_FOR_vec_dupv8sf, "__builtin_ia32_vbroadcastss256", IX86_BUILTIN_VBROADCASTSS256, UNKNOWN, (int) V8SF_FTYPE_PCFLOAT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vbroadcastf128_v4df, "__builtin_ia32_vbroadcastf128_pd256", IX86_BUILTIN_VBROADCASTPD256, UNKNOWN, (int) V4DF_FTYPE_PCV2DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vbroadcastf128_v8sf, "__builtin_ia32_vbroadcastf128_ps256", IX86_BUILTIN_VBROADCASTPS256, UNKNOWN, (int) V8SF_FTYPE_PCV4SF },
-
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_loadupd256, "__builtin_ia32_loadupd256", IX86_BUILTIN_LOADUPD256, UNKNOWN, (int) V4DF_FTYPE_PCDOUBLE },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_loadups256, "__builtin_ia32_loadups256", IX86_BUILTIN_LOADUPS256, UNKNOWN, (int) V8SF_FTYPE_PCFLOAT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_storeupd256, "__builtin_ia32_storeupd256", IX86_BUILTIN_STOREUPD256, UNKNOWN, (int) VOID_FTYPE_PDOUBLE_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_storeups256, "__builtin_ia32_storeups256", IX86_BUILTIN_STOREUPS256, UNKNOWN, (int) VOID_FTYPE_PFLOAT_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_loaddqu256, "__builtin_ia32_loaddqu256", IX86_BUILTIN_LOADDQU256, UNKNOWN, (int) V32QI_FTYPE_PCCHAR },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_storedqu256, "__builtin_ia32_storedqu256", IX86_BUILTIN_STOREDQU256, UNKNOWN, (int) VOID_FTYPE_PCHAR_V32QI },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_lddqu256, "__builtin_ia32_lddqu256", IX86_BUILTIN_LDDQU256, UNKNOWN, (int) V32QI_FTYPE_PCCHAR },
-
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_movntv4di, "__builtin_ia32_movntdq256", IX86_BUILTIN_MOVNTDQ256, UNKNOWN, (int) VOID_FTYPE_PV4DI_V4DI },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_movntv4df, "__builtin_ia32_movntpd256", IX86_BUILTIN_MOVNTPD256, UNKNOWN, (int) VOID_FTYPE_PDOUBLE_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_movntv8sf, "__builtin_ia32_movntps256", IX86_BUILTIN_MOVNTPS256, UNKNOWN, (int) VOID_FTYPE_PFLOAT_V8SF },
-
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_maskloadpd, "__builtin_ia32_maskloadpd", IX86_BUILTIN_MASKLOADPD, UNKNOWN, (int) V2DF_FTYPE_PCV2DF_V2DI },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_maskloadps, "__builtin_ia32_maskloadps", IX86_BUILTIN_MASKLOADPS, UNKNOWN, (int) V4SF_FTYPE_PCV4SF_V4SI },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_maskloadpd256, "__builtin_ia32_maskloadpd256", IX86_BUILTIN_MASKLOADPD256, UNKNOWN, (int) V4DF_FTYPE_PCV4DF_V4DI },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_maskloadps256, "__builtin_ia32_maskloadps256", IX86_BUILTIN_MASKLOADPS256, UNKNOWN, (int) V8SF_FTYPE_PCV8SF_V8SI },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_maskstorepd, "__builtin_ia32_maskstorepd", IX86_BUILTIN_MASKSTOREPD, UNKNOWN, (int) VOID_FTYPE_PV2DF_V2DI_V2DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_maskstoreps, "__builtin_ia32_maskstoreps", IX86_BUILTIN_MASKSTOREPS, UNKNOWN, (int) VOID_FTYPE_PV4SF_V4SI_V4SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_maskstorepd256, "__builtin_ia32_maskstorepd256", IX86_BUILTIN_MASKSTOREPD256, UNKNOWN, (int) VOID_FTYPE_PV4DF_V4DI_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_maskstoreps256, "__builtin_ia32_maskstoreps256", IX86_BUILTIN_MASKSTOREPS256, UNKNOWN, (int) VOID_FTYPE_PV8SF_V8SI_V8SF },
-
- /* AVX2 */
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_movntdqa, "__builtin_ia32_movntdqa256", IX86_BUILTIN_MOVNTDQA256, UNKNOWN, (int) V4DI_FTYPE_PV4DI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_maskloadd, "__builtin_ia32_maskloadd", IX86_BUILTIN_MASKLOADD, UNKNOWN, (int) V4SI_FTYPE_PCV4SI_V4SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_maskloadq, "__builtin_ia32_maskloadq", IX86_BUILTIN_MASKLOADQ, UNKNOWN, (int) V2DI_FTYPE_PCV2DI_V2DI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_maskloadd256, "__builtin_ia32_maskloadd256", IX86_BUILTIN_MASKLOADD256, UNKNOWN, (int) V8SI_FTYPE_PCV8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_maskloadq256, "__builtin_ia32_maskloadq256", IX86_BUILTIN_MASKLOADQ256, UNKNOWN, (int) V4DI_FTYPE_PCV4DI_V4DI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_maskstored, "__builtin_ia32_maskstored", IX86_BUILTIN_MASKSTORED, UNKNOWN, (int) VOID_FTYPE_PV4SI_V4SI_V4SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_maskstoreq, "__builtin_ia32_maskstoreq", IX86_BUILTIN_MASKSTOREQ, UNKNOWN, (int) VOID_FTYPE_PV2DI_V2DI_V2DI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_maskstored256, "__builtin_ia32_maskstored256", IX86_BUILTIN_MASKSTORED256, UNKNOWN, (int) VOID_FTYPE_PV8SI_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_maskstoreq256, "__builtin_ia32_maskstoreq256", IX86_BUILTIN_MASKSTOREQ256, UNKNOWN, (int) VOID_FTYPE_PV4DI_V4DI_V4DI },
-
- { OPTION_MASK_ISA_LWP, CODE_FOR_lwp_llwpcb, "__builtin_ia32_llwpcb", IX86_BUILTIN_LLWPCB, UNKNOWN, (int) VOID_FTYPE_PVOID },
- { OPTION_MASK_ISA_LWP, CODE_FOR_lwp_slwpcb, "__builtin_ia32_slwpcb", IX86_BUILTIN_SLWPCB, UNKNOWN, (int) PVOID_FTYPE_VOID },
- { OPTION_MASK_ISA_LWP, CODE_FOR_lwp_lwpvalsi3, "__builtin_ia32_lwpval32", IX86_BUILTIN_LWPVAL32, UNKNOWN, (int) VOID_FTYPE_UINT_UINT_UINT },
- { OPTION_MASK_ISA_LWP, CODE_FOR_lwp_lwpvaldi3, "__builtin_ia32_lwpval64", IX86_BUILTIN_LWPVAL64, UNKNOWN, (int) VOID_FTYPE_UINT64_UINT_UINT },
- { OPTION_MASK_ISA_LWP, CODE_FOR_lwp_lwpinssi3, "__builtin_ia32_lwpins32", IX86_BUILTIN_LWPINS32, UNKNOWN, (int) UCHAR_FTYPE_UINT_UINT_UINT },
- { OPTION_MASK_ISA_LWP, CODE_FOR_lwp_lwpinsdi3, "__builtin_ia32_lwpins64", IX86_BUILTIN_LWPINS64, UNKNOWN, (int) UCHAR_FTYPE_UINT64_UINT_UINT },
-
- /* FSGSBASE */
- { OPTION_MASK_ISA_FSGSBASE | OPTION_MASK_ISA_64BIT, CODE_FOR_rdfsbasesi, "__builtin_ia32_rdfsbase32", IX86_BUILTIN_RDFSBASE32, UNKNOWN, (int) UNSIGNED_FTYPE_VOID },
- { OPTION_MASK_ISA_FSGSBASE | OPTION_MASK_ISA_64BIT, CODE_FOR_rdfsbasedi, "__builtin_ia32_rdfsbase64", IX86_BUILTIN_RDFSBASE64, UNKNOWN, (int) UINT64_FTYPE_VOID },
- { OPTION_MASK_ISA_FSGSBASE | OPTION_MASK_ISA_64BIT, CODE_FOR_rdgsbasesi, "__builtin_ia32_rdgsbase32", IX86_BUILTIN_RDGSBASE32, UNKNOWN, (int) UNSIGNED_FTYPE_VOID },
- { OPTION_MASK_ISA_FSGSBASE | OPTION_MASK_ISA_64BIT, CODE_FOR_rdgsbasedi, "__builtin_ia32_rdgsbase64", IX86_BUILTIN_RDGSBASE64, UNKNOWN, (int) UINT64_FTYPE_VOID },
- { OPTION_MASK_ISA_FSGSBASE | OPTION_MASK_ISA_64BIT, CODE_FOR_wrfsbasesi, "__builtin_ia32_wrfsbase32", IX86_BUILTIN_WRFSBASE32, UNKNOWN, (int) VOID_FTYPE_UNSIGNED },
- { OPTION_MASK_ISA_FSGSBASE | OPTION_MASK_ISA_64BIT, CODE_FOR_wrfsbasedi, "__builtin_ia32_wrfsbase64", IX86_BUILTIN_WRFSBASE64, UNKNOWN, (int) VOID_FTYPE_UINT64 },
- { OPTION_MASK_ISA_FSGSBASE | OPTION_MASK_ISA_64BIT, CODE_FOR_wrgsbasesi, "__builtin_ia32_wrgsbase32", IX86_BUILTIN_WRGSBASE32, UNKNOWN, (int) VOID_FTYPE_UNSIGNED },
- { OPTION_MASK_ISA_FSGSBASE | OPTION_MASK_ISA_64BIT, CODE_FOR_wrgsbasedi, "__builtin_ia32_wrgsbase64", IX86_BUILTIN_WRGSBASE64, UNKNOWN, (int) VOID_FTYPE_UINT64 },
-
- /* RTM */
- { OPTION_MASK_ISA_RTM, CODE_FOR_xbegin, "__builtin_ia32_xbegin", IX86_BUILTIN_XBEGIN, UNKNOWN, (int) UNSIGNED_FTYPE_VOID },
- { OPTION_MASK_ISA_RTM, CODE_FOR_xend, "__builtin_ia32_xend", IX86_BUILTIN_XEND, UNKNOWN, (int) VOID_FTYPE_VOID },
- { OPTION_MASK_ISA_RTM, CODE_FOR_xtest, "__builtin_ia32_xtest", IX86_BUILTIN_XTEST, UNKNOWN, (int) INT_FTYPE_VOID },
-};
-
-/* Builtins with variable number of arguments. */
-static const struct builtin_description bdesc_args[] =
-{
- { ~OPTION_MASK_ISA_64BIT, CODE_FOR_bsr, "__builtin_ia32_bsrsi", IX86_BUILTIN_BSRSI, UNKNOWN, (int) INT_FTYPE_INT },
- { OPTION_MASK_ISA_64BIT, CODE_FOR_bsr_rex64, "__builtin_ia32_bsrdi", IX86_BUILTIN_BSRDI, UNKNOWN, (int) INT64_FTYPE_INT64 },
- { ~OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_rdpmc", IX86_BUILTIN_RDPMC, UNKNOWN, (int) UINT64_FTYPE_INT },
- { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rotlqi3, "__builtin_ia32_rolqi", IX86_BUILTIN_ROLQI, UNKNOWN, (int) UINT8_FTYPE_UINT8_INT },
- { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rotlhi3, "__builtin_ia32_rolhi", IX86_BUILTIN_ROLHI, UNKNOWN, (int) UINT16_FTYPE_UINT16_INT },
- { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rotrqi3, "__builtin_ia32_rorqi", IX86_BUILTIN_RORQI, UNKNOWN, (int) UINT8_FTYPE_UINT8_INT },
- { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rotrhi3, "__builtin_ia32_rorhi", IX86_BUILTIN_RORHI, UNKNOWN, (int) UINT16_FTYPE_UINT16_INT },
-
- /* MMX */
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_addv8qi3, "__builtin_ia32_paddb", IX86_BUILTIN_PADDB, UNKNOWN, (int) V8QI_FTYPE_V8QI_V8QI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_addv4hi3, "__builtin_ia32_paddw", IX86_BUILTIN_PADDW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_addv2si3, "__builtin_ia32_paddd", IX86_BUILTIN_PADDD, UNKNOWN, (int) V2SI_FTYPE_V2SI_V2SI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_subv8qi3, "__builtin_ia32_psubb", IX86_BUILTIN_PSUBB, UNKNOWN, (int) V8QI_FTYPE_V8QI_V8QI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_subv4hi3, "__builtin_ia32_psubw", IX86_BUILTIN_PSUBW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_subv2si3, "__builtin_ia32_psubd", IX86_BUILTIN_PSUBD, UNKNOWN, (int) V2SI_FTYPE_V2SI_V2SI },
-
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_ssaddv8qi3, "__builtin_ia32_paddsb", IX86_BUILTIN_PADDSB, UNKNOWN, (int) V8QI_FTYPE_V8QI_V8QI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_ssaddv4hi3, "__builtin_ia32_paddsw", IX86_BUILTIN_PADDSW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_sssubv8qi3, "__builtin_ia32_psubsb", IX86_BUILTIN_PSUBSB, UNKNOWN, (int) V8QI_FTYPE_V8QI_V8QI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_sssubv4hi3, "__builtin_ia32_psubsw", IX86_BUILTIN_PSUBSW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_usaddv8qi3, "__builtin_ia32_paddusb", IX86_BUILTIN_PADDUSB, UNKNOWN, (int) V8QI_FTYPE_V8QI_V8QI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_usaddv4hi3, "__builtin_ia32_paddusw", IX86_BUILTIN_PADDUSW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_ussubv8qi3, "__builtin_ia32_psubusb", IX86_BUILTIN_PSUBUSB, UNKNOWN, (int) V8QI_FTYPE_V8QI_V8QI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_ussubv4hi3, "__builtin_ia32_psubusw", IX86_BUILTIN_PSUBUSW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI },
-
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_mulv4hi3, "__builtin_ia32_pmullw", IX86_BUILTIN_PMULLW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_smulv4hi3_highpart, "__builtin_ia32_pmulhw", IX86_BUILTIN_PMULHW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI },
-
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_andv2si3, "__builtin_ia32_pand", IX86_BUILTIN_PAND, UNKNOWN, (int) V2SI_FTYPE_V2SI_V2SI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_andnotv2si3, "__builtin_ia32_pandn", IX86_BUILTIN_PANDN, UNKNOWN, (int) V2SI_FTYPE_V2SI_V2SI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_iorv2si3, "__builtin_ia32_por", IX86_BUILTIN_POR, UNKNOWN, (int) V2SI_FTYPE_V2SI_V2SI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_xorv2si3, "__builtin_ia32_pxor", IX86_BUILTIN_PXOR, UNKNOWN, (int) V2SI_FTYPE_V2SI_V2SI },
-
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_eqv8qi3, "__builtin_ia32_pcmpeqb", IX86_BUILTIN_PCMPEQB, UNKNOWN, (int) V8QI_FTYPE_V8QI_V8QI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_eqv4hi3, "__builtin_ia32_pcmpeqw", IX86_BUILTIN_PCMPEQW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_eqv2si3, "__builtin_ia32_pcmpeqd", IX86_BUILTIN_PCMPEQD, UNKNOWN, (int) V2SI_FTYPE_V2SI_V2SI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_gtv8qi3, "__builtin_ia32_pcmpgtb", IX86_BUILTIN_PCMPGTB, UNKNOWN, (int) V8QI_FTYPE_V8QI_V8QI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_gtv4hi3, "__builtin_ia32_pcmpgtw", IX86_BUILTIN_PCMPGTW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_gtv2si3, "__builtin_ia32_pcmpgtd", IX86_BUILTIN_PCMPGTD, UNKNOWN, (int) V2SI_FTYPE_V2SI_V2SI },
-
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_punpckhbw, "__builtin_ia32_punpckhbw", IX86_BUILTIN_PUNPCKHBW, UNKNOWN, (int) V8QI_FTYPE_V8QI_V8QI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_punpckhwd, "__builtin_ia32_punpckhwd", IX86_BUILTIN_PUNPCKHWD, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_punpckhdq, "__builtin_ia32_punpckhdq", IX86_BUILTIN_PUNPCKHDQ, UNKNOWN, (int) V2SI_FTYPE_V2SI_V2SI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_punpcklbw, "__builtin_ia32_punpcklbw", IX86_BUILTIN_PUNPCKLBW, UNKNOWN, (int) V8QI_FTYPE_V8QI_V8QI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_punpcklwd, "__builtin_ia32_punpcklwd", IX86_BUILTIN_PUNPCKLWD, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI},
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_punpckldq, "__builtin_ia32_punpckldq", IX86_BUILTIN_PUNPCKLDQ, UNKNOWN, (int) V2SI_FTYPE_V2SI_V2SI},
-
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_packsswb, "__builtin_ia32_packsswb", IX86_BUILTIN_PACKSSWB, UNKNOWN, (int) V8QI_FTYPE_V4HI_V4HI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_packssdw, "__builtin_ia32_packssdw", IX86_BUILTIN_PACKSSDW, UNKNOWN, (int) V4HI_FTYPE_V2SI_V2SI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_packuswb, "__builtin_ia32_packuswb", IX86_BUILTIN_PACKUSWB, UNKNOWN, (int) V8QI_FTYPE_V4HI_V4HI },
-
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_pmaddwd, "__builtin_ia32_pmaddwd", IX86_BUILTIN_PMADDWD, UNKNOWN, (int) V2SI_FTYPE_V4HI_V4HI },
-
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_ashlv4hi3, "__builtin_ia32_psllwi", IX86_BUILTIN_PSLLWI, UNKNOWN, (int) V4HI_FTYPE_V4HI_SI_COUNT },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_ashlv2si3, "__builtin_ia32_pslldi", IX86_BUILTIN_PSLLDI, UNKNOWN, (int) V2SI_FTYPE_V2SI_SI_COUNT },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_ashlv1di3, "__builtin_ia32_psllqi", IX86_BUILTIN_PSLLQI, UNKNOWN, (int) V1DI_FTYPE_V1DI_SI_COUNT },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_ashlv4hi3, "__builtin_ia32_psllw", IX86_BUILTIN_PSLLW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI_COUNT },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_ashlv2si3, "__builtin_ia32_pslld", IX86_BUILTIN_PSLLD, UNKNOWN, (int) V2SI_FTYPE_V2SI_V2SI_COUNT },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_ashlv1di3, "__builtin_ia32_psllq", IX86_BUILTIN_PSLLQ, UNKNOWN, (int) V1DI_FTYPE_V1DI_V1DI_COUNT },
-
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_lshrv4hi3, "__builtin_ia32_psrlwi", IX86_BUILTIN_PSRLWI, UNKNOWN, (int) V4HI_FTYPE_V4HI_SI_COUNT },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_lshrv2si3, "__builtin_ia32_psrldi", IX86_BUILTIN_PSRLDI, UNKNOWN, (int) V2SI_FTYPE_V2SI_SI_COUNT },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_lshrv1di3, "__builtin_ia32_psrlqi", IX86_BUILTIN_PSRLQI, UNKNOWN, (int) V1DI_FTYPE_V1DI_SI_COUNT },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_lshrv4hi3, "__builtin_ia32_psrlw", IX86_BUILTIN_PSRLW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI_COUNT },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_lshrv2si3, "__builtin_ia32_psrld", IX86_BUILTIN_PSRLD, UNKNOWN, (int) V2SI_FTYPE_V2SI_V2SI_COUNT },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_lshrv1di3, "__builtin_ia32_psrlq", IX86_BUILTIN_PSRLQ, UNKNOWN, (int) V1DI_FTYPE_V1DI_V1DI_COUNT },
-
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_ashrv4hi3, "__builtin_ia32_psrawi", IX86_BUILTIN_PSRAWI, UNKNOWN, (int) V4HI_FTYPE_V4HI_SI_COUNT },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_ashrv2si3, "__builtin_ia32_psradi", IX86_BUILTIN_PSRADI, UNKNOWN, (int) V2SI_FTYPE_V2SI_SI_COUNT },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_ashrv4hi3, "__builtin_ia32_psraw", IX86_BUILTIN_PSRAW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI_COUNT },
- { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_ashrv2si3, "__builtin_ia32_psrad", IX86_BUILTIN_PSRAD, UNKNOWN, (int) V2SI_FTYPE_V2SI_V2SI_COUNT },
-
- /* 3DNow! */
- { OPTION_MASK_ISA_3DNOW, CODE_FOR_mmx_pf2id, "__builtin_ia32_pf2id", IX86_BUILTIN_PF2ID, UNKNOWN, (int) V2SI_FTYPE_V2SF },
- { OPTION_MASK_ISA_3DNOW, CODE_FOR_mmx_floatv2si2, "__builtin_ia32_pi2fd", IX86_BUILTIN_PI2FD, UNKNOWN, (int) V2SF_FTYPE_V2SI },
- { OPTION_MASK_ISA_3DNOW, CODE_FOR_mmx_rcpv2sf2, "__builtin_ia32_pfrcp", IX86_BUILTIN_PFRCP, UNKNOWN, (int) V2SF_FTYPE_V2SF },
- { OPTION_MASK_ISA_3DNOW, CODE_FOR_mmx_rsqrtv2sf2, "__builtin_ia32_pfrsqrt", IX86_BUILTIN_PFRSQRT, UNKNOWN, (int) V2SF_FTYPE_V2SF },
-
- { OPTION_MASK_ISA_3DNOW, CODE_FOR_mmx_uavgv8qi3, "__builtin_ia32_pavgusb", IX86_BUILTIN_PAVGUSB, UNKNOWN, (int) V8QI_FTYPE_V8QI_V8QI },
- { OPTION_MASK_ISA_3DNOW, CODE_FOR_mmx_haddv2sf3, "__builtin_ia32_pfacc", IX86_BUILTIN_PFACC, UNKNOWN, (int) V2SF_FTYPE_V2SF_V2SF },
- { OPTION_MASK_ISA_3DNOW, CODE_FOR_mmx_addv2sf3, "__builtin_ia32_pfadd", IX86_BUILTIN_PFADD, UNKNOWN, (int) V2SF_FTYPE_V2SF_V2SF },
- { OPTION_MASK_ISA_3DNOW, CODE_FOR_mmx_eqv2sf3, "__builtin_ia32_pfcmpeq", IX86_BUILTIN_PFCMPEQ, UNKNOWN, (int) V2SI_FTYPE_V2SF_V2SF },
- { OPTION_MASK_ISA_3DNOW, CODE_FOR_mmx_gev2sf3, "__builtin_ia32_pfcmpge", IX86_BUILTIN_PFCMPGE, UNKNOWN, (int) V2SI_FTYPE_V2SF_V2SF },
- { OPTION_MASK_ISA_3DNOW, CODE_FOR_mmx_gtv2sf3, "__builtin_ia32_pfcmpgt", IX86_BUILTIN_PFCMPGT, UNKNOWN, (int) V2SI_FTYPE_V2SF_V2SF },
- { OPTION_MASK_ISA_3DNOW, CODE_FOR_mmx_smaxv2sf3, "__builtin_ia32_pfmax", IX86_BUILTIN_PFMAX, UNKNOWN, (int) V2SF_FTYPE_V2SF_V2SF },
- { OPTION_MASK_ISA_3DNOW, CODE_FOR_mmx_sminv2sf3, "__builtin_ia32_pfmin", IX86_BUILTIN_PFMIN, UNKNOWN, (int) V2SF_FTYPE_V2SF_V2SF },
- { OPTION_MASK_ISA_3DNOW, CODE_FOR_mmx_mulv2sf3, "__builtin_ia32_pfmul", IX86_BUILTIN_PFMUL, UNKNOWN, (int) V2SF_FTYPE_V2SF_V2SF },
- { OPTION_MASK_ISA_3DNOW, CODE_FOR_mmx_rcpit1v2sf3, "__builtin_ia32_pfrcpit1", IX86_BUILTIN_PFRCPIT1, UNKNOWN, (int) V2SF_FTYPE_V2SF_V2SF },
- { OPTION_MASK_ISA_3DNOW, CODE_FOR_mmx_rcpit2v2sf3, "__builtin_ia32_pfrcpit2", IX86_BUILTIN_PFRCPIT2, UNKNOWN, (int) V2SF_FTYPE_V2SF_V2SF },
- { OPTION_MASK_ISA_3DNOW, CODE_FOR_mmx_rsqit1v2sf3, "__builtin_ia32_pfrsqit1", IX86_BUILTIN_PFRSQIT1, UNKNOWN, (int) V2SF_FTYPE_V2SF_V2SF },
- { OPTION_MASK_ISA_3DNOW, CODE_FOR_mmx_subv2sf3, "__builtin_ia32_pfsub", IX86_BUILTIN_PFSUB, UNKNOWN, (int) V2SF_FTYPE_V2SF_V2SF },
- { OPTION_MASK_ISA_3DNOW, CODE_FOR_mmx_subrv2sf3, "__builtin_ia32_pfsubr", IX86_BUILTIN_PFSUBR, UNKNOWN, (int) V2SF_FTYPE_V2SF_V2SF },
- { OPTION_MASK_ISA_3DNOW, CODE_FOR_mmx_pmulhrwv4hi3, "__builtin_ia32_pmulhrw", IX86_BUILTIN_PMULHRW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI },
-
- /* 3DNow!A */
- { OPTION_MASK_ISA_3DNOW_A, CODE_FOR_mmx_pf2iw, "__builtin_ia32_pf2iw", IX86_BUILTIN_PF2IW, UNKNOWN, (int) V2SI_FTYPE_V2SF },
- { OPTION_MASK_ISA_3DNOW_A, CODE_FOR_mmx_pi2fw, "__builtin_ia32_pi2fw", IX86_BUILTIN_PI2FW, UNKNOWN, (int) V2SF_FTYPE_V2SI },
- { OPTION_MASK_ISA_3DNOW_A, CODE_FOR_mmx_pswapdv2si2, "__builtin_ia32_pswapdsi", IX86_BUILTIN_PSWAPDSI, UNKNOWN, (int) V2SI_FTYPE_V2SI },
- { OPTION_MASK_ISA_3DNOW_A, CODE_FOR_mmx_pswapdv2sf2, "__builtin_ia32_pswapdsf", IX86_BUILTIN_PSWAPDSF, UNKNOWN, (int) V2SF_FTYPE_V2SF },
- { OPTION_MASK_ISA_3DNOW_A, CODE_FOR_mmx_hsubv2sf3, "__builtin_ia32_pfnacc", IX86_BUILTIN_PFNACC, UNKNOWN, (int) V2SF_FTYPE_V2SF_V2SF },
- { OPTION_MASK_ISA_3DNOW_A, CODE_FOR_mmx_addsubv2sf3, "__builtin_ia32_pfpnacc", IX86_BUILTIN_PFPNACC, UNKNOWN, (int) V2SF_FTYPE_V2SF_V2SF },
-
- /* SSE */
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_movmskps, "__builtin_ia32_movmskps", IX86_BUILTIN_MOVMSKPS, UNKNOWN, (int) INT_FTYPE_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_sqrtv4sf2, "__builtin_ia32_sqrtps", IX86_BUILTIN_SQRTPS, UNKNOWN, (int) V4SF_FTYPE_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sqrtv4sf2, "__builtin_ia32_sqrtps_nr", IX86_BUILTIN_SQRTPS_NR, UNKNOWN, (int) V4SF_FTYPE_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_rsqrtv4sf2, "__builtin_ia32_rsqrtps", IX86_BUILTIN_RSQRTPS, UNKNOWN, (int) V4SF_FTYPE_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_rsqrtv4sf2, "__builtin_ia32_rsqrtps_nr", IX86_BUILTIN_RSQRTPS_NR, UNKNOWN, (int) V4SF_FTYPE_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_rcpv4sf2, "__builtin_ia32_rcpps", IX86_BUILTIN_RCPPS, UNKNOWN, (int) V4SF_FTYPE_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_cvtps2pi, "__builtin_ia32_cvtps2pi", IX86_BUILTIN_CVTPS2PI, UNKNOWN, (int) V2SI_FTYPE_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_cvtss2si, "__builtin_ia32_cvtss2si", IX86_BUILTIN_CVTSS2SI, UNKNOWN, (int) INT_FTYPE_V4SF },
- { OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_64BIT, CODE_FOR_sse_cvtss2siq, "__builtin_ia32_cvtss2si64", IX86_BUILTIN_CVTSS2SI64, UNKNOWN, (int) INT64_FTYPE_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_cvttps2pi, "__builtin_ia32_cvttps2pi", IX86_BUILTIN_CVTTPS2PI, UNKNOWN, (int) V2SI_FTYPE_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_cvttss2si, "__builtin_ia32_cvttss2si", IX86_BUILTIN_CVTTSS2SI, UNKNOWN, (int) INT_FTYPE_V4SF },
- { OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_64BIT, CODE_FOR_sse_cvttss2siq, "__builtin_ia32_cvttss2si64", IX86_BUILTIN_CVTTSS2SI64, UNKNOWN, (int) INT64_FTYPE_V4SF },
-
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_shufps, "__builtin_ia32_shufps", IX86_BUILTIN_SHUFPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF_INT },
-
- { OPTION_MASK_ISA_SSE, CODE_FOR_addv4sf3, "__builtin_ia32_addps", IX86_BUILTIN_ADDPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_subv4sf3, "__builtin_ia32_subps", IX86_BUILTIN_SUBPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_mulv4sf3, "__builtin_ia32_mulps", IX86_BUILTIN_MULPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_divv4sf3, "__builtin_ia32_divps", IX86_BUILTIN_DIVPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_vmaddv4sf3, "__builtin_ia32_addss", IX86_BUILTIN_ADDSS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_vmsubv4sf3, "__builtin_ia32_subss", IX86_BUILTIN_SUBSS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_vmmulv4sf3, "__builtin_ia32_mulss", IX86_BUILTIN_MULSS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_vmdivv4sf3, "__builtin_ia32_divss", IX86_BUILTIN_DIVSS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
-
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_maskcmpv4sf3, "__builtin_ia32_cmpeqps", IX86_BUILTIN_CMPEQPS, EQ, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_maskcmpv4sf3, "__builtin_ia32_cmpltps", IX86_BUILTIN_CMPLTPS, LT, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_maskcmpv4sf3, "__builtin_ia32_cmpleps", IX86_BUILTIN_CMPLEPS, LE, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_maskcmpv4sf3, "__builtin_ia32_cmpgtps", IX86_BUILTIN_CMPGTPS, LT, (int) V4SF_FTYPE_V4SF_V4SF_SWAP },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_maskcmpv4sf3, "__builtin_ia32_cmpgeps", IX86_BUILTIN_CMPGEPS, LE, (int) V4SF_FTYPE_V4SF_V4SF_SWAP },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_maskcmpv4sf3, "__builtin_ia32_cmpunordps", IX86_BUILTIN_CMPUNORDPS, UNORDERED, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_maskcmpv4sf3, "__builtin_ia32_cmpneqps", IX86_BUILTIN_CMPNEQPS, NE, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_maskcmpv4sf3, "__builtin_ia32_cmpnltps", IX86_BUILTIN_CMPNLTPS, UNGE, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_maskcmpv4sf3, "__builtin_ia32_cmpnleps", IX86_BUILTIN_CMPNLEPS, UNGT, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_maskcmpv4sf3, "__builtin_ia32_cmpngtps", IX86_BUILTIN_CMPNGTPS, UNGE, (int) V4SF_FTYPE_V4SF_V4SF_SWAP },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_maskcmpv4sf3, "__builtin_ia32_cmpngeps", IX86_BUILTIN_CMPNGEPS, UNGT, (int) V4SF_FTYPE_V4SF_V4SF_SWAP},
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_maskcmpv4sf3, "__builtin_ia32_cmpordps", IX86_BUILTIN_CMPORDPS, ORDERED, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_vmmaskcmpv4sf3, "__builtin_ia32_cmpeqss", IX86_BUILTIN_CMPEQSS, EQ, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_vmmaskcmpv4sf3, "__builtin_ia32_cmpltss", IX86_BUILTIN_CMPLTSS, LT, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_vmmaskcmpv4sf3, "__builtin_ia32_cmpless", IX86_BUILTIN_CMPLESS, LE, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_vmmaskcmpv4sf3, "__builtin_ia32_cmpunordss", IX86_BUILTIN_CMPUNORDSS, UNORDERED, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_vmmaskcmpv4sf3, "__builtin_ia32_cmpneqss", IX86_BUILTIN_CMPNEQSS, NE, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_vmmaskcmpv4sf3, "__builtin_ia32_cmpnltss", IX86_BUILTIN_CMPNLTSS, UNGE, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_vmmaskcmpv4sf3, "__builtin_ia32_cmpnless", IX86_BUILTIN_CMPNLESS, UNGT, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_vmmaskcmpv4sf3, "__builtin_ia32_cmpngtss", IX86_BUILTIN_CMPNGTSS, UNGE, (int) V4SF_FTYPE_V4SF_V4SF_SWAP },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_vmmaskcmpv4sf3, "__builtin_ia32_cmpngess", IX86_BUILTIN_CMPNGESS, UNGT, (int) V4SF_FTYPE_V4SF_V4SF_SWAP },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_vmmaskcmpv4sf3, "__builtin_ia32_cmpordss", IX86_BUILTIN_CMPORDSS, ORDERED, (int) V4SF_FTYPE_V4SF_V4SF },
-
- { OPTION_MASK_ISA_SSE, CODE_FOR_sminv4sf3, "__builtin_ia32_minps", IX86_BUILTIN_MINPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_smaxv4sf3, "__builtin_ia32_maxps", IX86_BUILTIN_MAXPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_vmsminv4sf3, "__builtin_ia32_minss", IX86_BUILTIN_MINSS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_vmsmaxv4sf3, "__builtin_ia32_maxss", IX86_BUILTIN_MAXSS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
-
- { OPTION_MASK_ISA_SSE, CODE_FOR_andv4sf3, "__builtin_ia32_andps", IX86_BUILTIN_ANDPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_andnotv4sf3, "__builtin_ia32_andnps", IX86_BUILTIN_ANDNPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_iorv4sf3, "__builtin_ia32_orps", IX86_BUILTIN_ORPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_xorv4sf3, "__builtin_ia32_xorps", IX86_BUILTIN_XORPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
-
- { OPTION_MASK_ISA_SSE, CODE_FOR_copysignv4sf3, "__builtin_ia32_copysignps", IX86_BUILTIN_CPYSGNPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
-
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_movss, "__builtin_ia32_movss", IX86_BUILTIN_MOVSS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_movhlps_exp, "__builtin_ia32_movhlps", IX86_BUILTIN_MOVHLPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_movlhps_exp, "__builtin_ia32_movlhps", IX86_BUILTIN_MOVLHPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_vec_interleave_highv4sf, "__builtin_ia32_unpckhps", IX86_BUILTIN_UNPCKHPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_vec_interleave_lowv4sf, "__builtin_ia32_unpcklps", IX86_BUILTIN_UNPCKLPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
-
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_cvtpi2ps, "__builtin_ia32_cvtpi2ps", IX86_BUILTIN_CVTPI2PS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V2SI },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_cvtsi2ss, "__builtin_ia32_cvtsi2ss", IX86_BUILTIN_CVTSI2SS, UNKNOWN, (int) V4SF_FTYPE_V4SF_SI },
- { OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_64BIT, CODE_FOR_sse_cvtsi2ssq, "__builtin_ia32_cvtsi642ss", IX86_BUILTIN_CVTSI642SS, UNKNOWN, V4SF_FTYPE_V4SF_DI },
-
- { OPTION_MASK_ISA_SSE, CODE_FOR_rsqrtsf2, "__builtin_ia32_rsqrtf", IX86_BUILTIN_RSQRTF, UNKNOWN, (int) FLOAT_FTYPE_FLOAT },
-
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_vmsqrtv4sf2, "__builtin_ia32_sqrtss", IX86_BUILTIN_SQRTSS, UNKNOWN, (int) V4SF_FTYPE_V4SF_VEC_MERGE },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_vmrsqrtv4sf2, "__builtin_ia32_rsqrtss", IX86_BUILTIN_RSQRTSS, UNKNOWN, (int) V4SF_FTYPE_V4SF_VEC_MERGE },
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse_vmrcpv4sf2, "__builtin_ia32_rcpss", IX86_BUILTIN_RCPSS, UNKNOWN, (int) V4SF_FTYPE_V4SF_VEC_MERGE },
-
- { OPTION_MASK_ISA_SSE, CODE_FOR_abstf2, 0, IX86_BUILTIN_FABSQ, UNKNOWN, (int) FLOAT128_FTYPE_FLOAT128 },
- { OPTION_MASK_ISA_SSE, CODE_FOR_copysigntf3, 0, IX86_BUILTIN_COPYSIGNQ, UNKNOWN, (int) FLOAT128_FTYPE_FLOAT128_FLOAT128 },
-
- /* SSE MMX or 3Dnow!A */
- { OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A, CODE_FOR_mmx_uavgv8qi3, "__builtin_ia32_pavgb", IX86_BUILTIN_PAVGB, UNKNOWN, (int) V8QI_FTYPE_V8QI_V8QI },
- { OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A, CODE_FOR_mmx_uavgv4hi3, "__builtin_ia32_pavgw", IX86_BUILTIN_PAVGW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI },
- { OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A, CODE_FOR_mmx_umulv4hi3_highpart, "__builtin_ia32_pmulhuw", IX86_BUILTIN_PMULHUW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI },
-
- { OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A, CODE_FOR_mmx_umaxv8qi3, "__builtin_ia32_pmaxub", IX86_BUILTIN_PMAXUB, UNKNOWN, (int) V8QI_FTYPE_V8QI_V8QI },
- { OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A, CODE_FOR_mmx_smaxv4hi3, "__builtin_ia32_pmaxsw", IX86_BUILTIN_PMAXSW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI },
- { OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A, CODE_FOR_mmx_uminv8qi3, "__builtin_ia32_pminub", IX86_BUILTIN_PMINUB, UNKNOWN, (int) V8QI_FTYPE_V8QI_V8QI },
- { OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A, CODE_FOR_mmx_sminv4hi3, "__builtin_ia32_pminsw", IX86_BUILTIN_PMINSW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI },
-
- { OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A, CODE_FOR_mmx_psadbw, "__builtin_ia32_psadbw", IX86_BUILTIN_PSADBW, UNKNOWN, (int) V1DI_FTYPE_V8QI_V8QI },
- { OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A, CODE_FOR_mmx_pmovmskb, "__builtin_ia32_pmovmskb", IX86_BUILTIN_PMOVMSKB, UNKNOWN, (int) INT_FTYPE_V8QI },
-
- { OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A, CODE_FOR_mmx_pshufw, "__builtin_ia32_pshufw", IX86_BUILTIN_PSHUFW, UNKNOWN, (int) V4HI_FTYPE_V4HI_INT },
-
- /* SSE2 */
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_shufpd, "__builtin_ia32_shufpd", IX86_BUILTIN_SHUFPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF_INT },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_movmskpd, "__builtin_ia32_movmskpd", IX86_BUILTIN_MOVMSKPD, UNKNOWN, (int) INT_FTYPE_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_pmovmskb, "__builtin_ia32_pmovmskb128", IX86_BUILTIN_PMOVMSKB128, UNKNOWN, (int) INT_FTYPE_V16QI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sqrtv2df2, "__builtin_ia32_sqrtpd", IX86_BUILTIN_SQRTPD, UNKNOWN, (int) V2DF_FTYPE_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_cvtdq2pd, "__builtin_ia32_cvtdq2pd", IX86_BUILTIN_CVTDQ2PD, UNKNOWN, (int) V2DF_FTYPE_V4SI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_floatv4siv4sf2, "__builtin_ia32_cvtdq2ps", IX86_BUILTIN_CVTDQ2PS, UNKNOWN, (int) V4SF_FTYPE_V4SI },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_cvtpd2dq, "__builtin_ia32_cvtpd2dq", IX86_BUILTIN_CVTPD2DQ, UNKNOWN, (int) V4SI_FTYPE_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_cvtpd2pi, "__builtin_ia32_cvtpd2pi", IX86_BUILTIN_CVTPD2PI, UNKNOWN, (int) V2SI_FTYPE_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_cvtpd2ps, "__builtin_ia32_cvtpd2ps", IX86_BUILTIN_CVTPD2PS, UNKNOWN, (int) V4SF_FTYPE_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_cvttpd2dq, "__builtin_ia32_cvttpd2dq", IX86_BUILTIN_CVTTPD2DQ, UNKNOWN, (int) V4SI_FTYPE_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_cvttpd2pi, "__builtin_ia32_cvttpd2pi", IX86_BUILTIN_CVTTPD2PI, UNKNOWN, (int) V2SI_FTYPE_V2DF },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_cvtpi2pd, "__builtin_ia32_cvtpi2pd", IX86_BUILTIN_CVTPI2PD, UNKNOWN, (int) V2DF_FTYPE_V2SI },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_cvtsd2si, "__builtin_ia32_cvtsd2si", IX86_BUILTIN_CVTSD2SI, UNKNOWN, (int) INT_FTYPE_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_cvttsd2si, "__builtin_ia32_cvttsd2si", IX86_BUILTIN_CVTTSD2SI, UNKNOWN, (int) INT_FTYPE_V2DF },
- { OPTION_MASK_ISA_SSE2 | OPTION_MASK_ISA_64BIT, CODE_FOR_sse2_cvtsd2siq, "__builtin_ia32_cvtsd2si64", IX86_BUILTIN_CVTSD2SI64, UNKNOWN, (int) INT64_FTYPE_V2DF },
- { OPTION_MASK_ISA_SSE2 | OPTION_MASK_ISA_64BIT, CODE_FOR_sse2_cvttsd2siq, "__builtin_ia32_cvttsd2si64", IX86_BUILTIN_CVTTSD2SI64, UNKNOWN, (int) INT64_FTYPE_V2DF },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_cvtps2dq, "__builtin_ia32_cvtps2dq", IX86_BUILTIN_CVTPS2DQ, UNKNOWN, (int) V4SI_FTYPE_V4SF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_cvtps2pd, "__builtin_ia32_cvtps2pd", IX86_BUILTIN_CVTPS2PD, UNKNOWN, (int) V2DF_FTYPE_V4SF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_fix_truncv4sfv4si2, "__builtin_ia32_cvttps2dq", IX86_BUILTIN_CVTTPS2DQ, UNKNOWN, (int) V4SI_FTYPE_V4SF },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_addv2df3, "__builtin_ia32_addpd", IX86_BUILTIN_ADDPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_subv2df3, "__builtin_ia32_subpd", IX86_BUILTIN_SUBPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_mulv2df3, "__builtin_ia32_mulpd", IX86_BUILTIN_MULPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_divv2df3, "__builtin_ia32_divpd", IX86_BUILTIN_DIVPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_vmaddv2df3, "__builtin_ia32_addsd", IX86_BUILTIN_ADDSD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_vmsubv2df3, "__builtin_ia32_subsd", IX86_BUILTIN_SUBSD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_vmmulv2df3, "__builtin_ia32_mulsd", IX86_BUILTIN_MULSD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_vmdivv2df3, "__builtin_ia32_divsd", IX86_BUILTIN_DIVSD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_maskcmpv2df3, "__builtin_ia32_cmpeqpd", IX86_BUILTIN_CMPEQPD, EQ, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_maskcmpv2df3, "__builtin_ia32_cmpltpd", IX86_BUILTIN_CMPLTPD, LT, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_maskcmpv2df3, "__builtin_ia32_cmplepd", IX86_BUILTIN_CMPLEPD, LE, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_maskcmpv2df3, "__builtin_ia32_cmpgtpd", IX86_BUILTIN_CMPGTPD, LT, (int) V2DF_FTYPE_V2DF_V2DF_SWAP },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_maskcmpv2df3, "__builtin_ia32_cmpgepd", IX86_BUILTIN_CMPGEPD, LE, (int) V2DF_FTYPE_V2DF_V2DF_SWAP},
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_maskcmpv2df3, "__builtin_ia32_cmpunordpd", IX86_BUILTIN_CMPUNORDPD, UNORDERED, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_maskcmpv2df3, "__builtin_ia32_cmpneqpd", IX86_BUILTIN_CMPNEQPD, NE, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_maskcmpv2df3, "__builtin_ia32_cmpnltpd", IX86_BUILTIN_CMPNLTPD, UNGE, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_maskcmpv2df3, "__builtin_ia32_cmpnlepd", IX86_BUILTIN_CMPNLEPD, UNGT, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_maskcmpv2df3, "__builtin_ia32_cmpngtpd", IX86_BUILTIN_CMPNGTPD, UNGE, (int) V2DF_FTYPE_V2DF_V2DF_SWAP },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_maskcmpv2df3, "__builtin_ia32_cmpngepd", IX86_BUILTIN_CMPNGEPD, UNGT, (int) V2DF_FTYPE_V2DF_V2DF_SWAP },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_maskcmpv2df3, "__builtin_ia32_cmpordpd", IX86_BUILTIN_CMPORDPD, ORDERED, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_vmmaskcmpv2df3, "__builtin_ia32_cmpeqsd", IX86_BUILTIN_CMPEQSD, EQ, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_vmmaskcmpv2df3, "__builtin_ia32_cmpltsd", IX86_BUILTIN_CMPLTSD, LT, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_vmmaskcmpv2df3, "__builtin_ia32_cmplesd", IX86_BUILTIN_CMPLESD, LE, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_vmmaskcmpv2df3, "__builtin_ia32_cmpunordsd", IX86_BUILTIN_CMPUNORDSD, UNORDERED, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_vmmaskcmpv2df3, "__builtin_ia32_cmpneqsd", IX86_BUILTIN_CMPNEQSD, NE, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_vmmaskcmpv2df3, "__builtin_ia32_cmpnltsd", IX86_BUILTIN_CMPNLTSD, UNGE, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_vmmaskcmpv2df3, "__builtin_ia32_cmpnlesd", IX86_BUILTIN_CMPNLESD, UNGT, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_vmmaskcmpv2df3, "__builtin_ia32_cmpordsd", IX86_BUILTIN_CMPORDSD, ORDERED, (int) V2DF_FTYPE_V2DF_V2DF },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sminv2df3, "__builtin_ia32_minpd", IX86_BUILTIN_MINPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_smaxv2df3, "__builtin_ia32_maxpd", IX86_BUILTIN_MAXPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_vmsminv2df3, "__builtin_ia32_minsd", IX86_BUILTIN_MINSD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_vmsmaxv2df3, "__builtin_ia32_maxsd", IX86_BUILTIN_MAXSD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_andv2df3, "__builtin_ia32_andpd", IX86_BUILTIN_ANDPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_andnotv2df3, "__builtin_ia32_andnpd", IX86_BUILTIN_ANDNPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_iorv2df3, "__builtin_ia32_orpd", IX86_BUILTIN_ORPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_xorv2df3, "__builtin_ia32_xorpd", IX86_BUILTIN_XORPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_copysignv2df3, "__builtin_ia32_copysignpd", IX86_BUILTIN_CPYSGNPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_movsd, "__builtin_ia32_movsd", IX86_BUILTIN_MOVSD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_vec_interleave_highv2df, "__builtin_ia32_unpckhpd", IX86_BUILTIN_UNPCKHPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_vec_interleave_lowv2df, "__builtin_ia32_unpcklpd", IX86_BUILTIN_UNPCKLPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_vec_pack_sfix_v2df, "__builtin_ia32_vec_pack_sfix", IX86_BUILTIN_VEC_PACK_SFIX, UNKNOWN, (int) V4SI_FTYPE_V2DF_V2DF },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_addv16qi3, "__builtin_ia32_paddb128", IX86_BUILTIN_PADDB128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_addv8hi3, "__builtin_ia32_paddw128", IX86_BUILTIN_PADDW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_addv4si3, "__builtin_ia32_paddd128", IX86_BUILTIN_PADDD128, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_addv2di3, "__builtin_ia32_paddq128", IX86_BUILTIN_PADDQ128, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_subv16qi3, "__builtin_ia32_psubb128", IX86_BUILTIN_PSUBB128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_subv8hi3, "__builtin_ia32_psubw128", IX86_BUILTIN_PSUBW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_subv4si3, "__builtin_ia32_psubd128", IX86_BUILTIN_PSUBD128, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_subv2di3, "__builtin_ia32_psubq128", IX86_BUILTIN_PSUBQ128, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_ssaddv16qi3, "__builtin_ia32_paddsb128", IX86_BUILTIN_PADDSB128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_ssaddv8hi3, "__builtin_ia32_paddsw128", IX86_BUILTIN_PADDSW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_sssubv16qi3, "__builtin_ia32_psubsb128", IX86_BUILTIN_PSUBSB128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_sssubv8hi3, "__builtin_ia32_psubsw128", IX86_BUILTIN_PSUBSW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_usaddv16qi3, "__builtin_ia32_paddusb128", IX86_BUILTIN_PADDUSB128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_usaddv8hi3, "__builtin_ia32_paddusw128", IX86_BUILTIN_PADDUSW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_ussubv16qi3, "__builtin_ia32_psubusb128", IX86_BUILTIN_PSUBUSB128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_ussubv8hi3, "__builtin_ia32_psubusw128", IX86_BUILTIN_PSUBUSW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_mulv8hi3, "__builtin_ia32_pmullw128", IX86_BUILTIN_PMULLW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_smulv8hi3_highpart, "__builtin_ia32_pmulhw128", IX86_BUILTIN_PMULHW128, UNKNOWN,(int) V8HI_FTYPE_V8HI_V8HI },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_andv2di3, "__builtin_ia32_pand128", IX86_BUILTIN_PAND128, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_andnotv2di3, "__builtin_ia32_pandn128", IX86_BUILTIN_PANDN128, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_iorv2di3, "__builtin_ia32_por128", IX86_BUILTIN_POR128, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_xorv2di3, "__builtin_ia32_pxor128", IX86_BUILTIN_PXOR128, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_uavgv16qi3, "__builtin_ia32_pavgb128", IX86_BUILTIN_PAVGB128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_uavgv8hi3, "__builtin_ia32_pavgw128", IX86_BUILTIN_PAVGW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_eqv16qi3, "__builtin_ia32_pcmpeqb128", IX86_BUILTIN_PCMPEQB128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_eqv8hi3, "__builtin_ia32_pcmpeqw128", IX86_BUILTIN_PCMPEQW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_eqv4si3, "__builtin_ia32_pcmpeqd128", IX86_BUILTIN_PCMPEQD128, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_gtv16qi3, "__builtin_ia32_pcmpgtb128", IX86_BUILTIN_PCMPGTB128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_gtv8hi3, "__builtin_ia32_pcmpgtw128", IX86_BUILTIN_PCMPGTW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_gtv4si3, "__builtin_ia32_pcmpgtd128", IX86_BUILTIN_PCMPGTD128, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_umaxv16qi3, "__builtin_ia32_pmaxub128", IX86_BUILTIN_PMAXUB128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_smaxv8hi3, "__builtin_ia32_pmaxsw128", IX86_BUILTIN_PMAXSW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_uminv16qi3, "__builtin_ia32_pminub128", IX86_BUILTIN_PMINUB128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sminv8hi3, "__builtin_ia32_pminsw128", IX86_BUILTIN_PMINSW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_vec_interleave_highv16qi, "__builtin_ia32_punpckhbw128", IX86_BUILTIN_PUNPCKHBW128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_vec_interleave_highv8hi, "__builtin_ia32_punpckhwd128", IX86_BUILTIN_PUNPCKHWD128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_vec_interleave_highv4si, "__builtin_ia32_punpckhdq128", IX86_BUILTIN_PUNPCKHDQ128, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_vec_interleave_highv2di, "__builtin_ia32_punpckhqdq128", IX86_BUILTIN_PUNPCKHQDQ128, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_vec_interleave_lowv16qi, "__builtin_ia32_punpcklbw128", IX86_BUILTIN_PUNPCKLBW128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_vec_interleave_lowv8hi, "__builtin_ia32_punpcklwd128", IX86_BUILTIN_PUNPCKLWD128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_vec_interleave_lowv4si, "__builtin_ia32_punpckldq128", IX86_BUILTIN_PUNPCKLDQ128, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_vec_interleave_lowv2di, "__builtin_ia32_punpcklqdq128", IX86_BUILTIN_PUNPCKLQDQ128, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_packsswb, "__builtin_ia32_packsswb128", IX86_BUILTIN_PACKSSWB128, UNKNOWN, (int) V16QI_FTYPE_V8HI_V8HI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_packssdw, "__builtin_ia32_packssdw128", IX86_BUILTIN_PACKSSDW128, UNKNOWN, (int) V8HI_FTYPE_V4SI_V4SI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_packuswb, "__builtin_ia32_packuswb128", IX86_BUILTIN_PACKUSWB128, UNKNOWN, (int) V16QI_FTYPE_V8HI_V8HI },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_umulv8hi3_highpart, "__builtin_ia32_pmulhuw128", IX86_BUILTIN_PMULHUW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_psadbw, "__builtin_ia32_psadbw128", IX86_BUILTIN_PSADBW128, UNKNOWN, (int) V2DI_FTYPE_V16QI_V16QI },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_umulv1siv1di3, "__builtin_ia32_pmuludq", IX86_BUILTIN_PMULUDQ, UNKNOWN, (int) V1DI_FTYPE_V2SI_V2SI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_vec_widen_umult_even_v4si, "__builtin_ia32_pmuludq128", IX86_BUILTIN_PMULUDQ128, UNKNOWN, (int) V2DI_FTYPE_V4SI_V4SI },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_pmaddwd, "__builtin_ia32_pmaddwd128", IX86_BUILTIN_PMADDWD128, UNKNOWN, (int) V4SI_FTYPE_V8HI_V8HI },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_cvtsi2sd, "__builtin_ia32_cvtsi2sd", IX86_BUILTIN_CVTSI2SD, UNKNOWN, (int) V2DF_FTYPE_V2DF_SI },
- { OPTION_MASK_ISA_SSE2 | OPTION_MASK_ISA_64BIT, CODE_FOR_sse2_cvtsi2sdq, "__builtin_ia32_cvtsi642sd", IX86_BUILTIN_CVTSI642SD, UNKNOWN, (int) V2DF_FTYPE_V2DF_DI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_cvtsd2ss, "__builtin_ia32_cvtsd2ss", IX86_BUILTIN_CVTSD2SS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V2DF },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_cvtss2sd, "__builtin_ia32_cvtss2sd", IX86_BUILTIN_CVTSS2SD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V4SF },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_ashlv1ti3, "__builtin_ia32_pslldqi128", IX86_BUILTIN_PSLLDQI128, UNKNOWN, (int) V2DI_FTYPE_V2DI_INT_CONVERT },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_ashlv8hi3, "__builtin_ia32_psllwi128", IX86_BUILTIN_PSLLWI128, UNKNOWN, (int) V8HI_FTYPE_V8HI_SI_COUNT },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_ashlv4si3, "__builtin_ia32_pslldi128", IX86_BUILTIN_PSLLDI128, UNKNOWN, (int) V4SI_FTYPE_V4SI_SI_COUNT },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_ashlv2di3, "__builtin_ia32_psllqi128", IX86_BUILTIN_PSLLQI128, UNKNOWN, (int) V2DI_FTYPE_V2DI_SI_COUNT },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_ashlv8hi3, "__builtin_ia32_psllw128", IX86_BUILTIN_PSLLW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI_COUNT },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_ashlv4si3, "__builtin_ia32_pslld128", IX86_BUILTIN_PSLLD128, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_COUNT },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_ashlv2di3, "__builtin_ia32_psllq128", IX86_BUILTIN_PSLLQ128, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_COUNT },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_lshrv1ti3, "__builtin_ia32_psrldqi128", IX86_BUILTIN_PSRLDQI128, UNKNOWN, (int) V2DI_FTYPE_V2DI_INT_CONVERT },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_lshrv8hi3, "__builtin_ia32_psrlwi128", IX86_BUILTIN_PSRLWI128, UNKNOWN, (int) V8HI_FTYPE_V8HI_SI_COUNT },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_lshrv4si3, "__builtin_ia32_psrldi128", IX86_BUILTIN_PSRLDI128, UNKNOWN, (int) V4SI_FTYPE_V4SI_SI_COUNT },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_lshrv2di3, "__builtin_ia32_psrlqi128", IX86_BUILTIN_PSRLQI128, UNKNOWN, (int) V2DI_FTYPE_V2DI_SI_COUNT },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_lshrv8hi3, "__builtin_ia32_psrlw128", IX86_BUILTIN_PSRLW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI_COUNT },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_lshrv4si3, "__builtin_ia32_psrld128", IX86_BUILTIN_PSRLD128, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_COUNT },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_lshrv2di3, "__builtin_ia32_psrlq128", IX86_BUILTIN_PSRLQ128, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_COUNT },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_ashrv8hi3, "__builtin_ia32_psrawi128", IX86_BUILTIN_PSRAWI128, UNKNOWN, (int) V8HI_FTYPE_V8HI_SI_COUNT },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_ashrv4si3, "__builtin_ia32_psradi128", IX86_BUILTIN_PSRADI128, UNKNOWN, (int) V4SI_FTYPE_V4SI_SI_COUNT },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_ashrv8hi3, "__builtin_ia32_psraw128", IX86_BUILTIN_PSRAW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI_COUNT },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_ashrv4si3, "__builtin_ia32_psrad128", IX86_BUILTIN_PSRAD128, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_COUNT },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_pshufd, "__builtin_ia32_pshufd", IX86_BUILTIN_PSHUFD, UNKNOWN, (int) V4SI_FTYPE_V4SI_INT },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_pshuflw, "__builtin_ia32_pshuflw", IX86_BUILTIN_PSHUFLW, UNKNOWN, (int) V8HI_FTYPE_V8HI_INT },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_pshufhw, "__builtin_ia32_pshufhw", IX86_BUILTIN_PSHUFHW, UNKNOWN, (int) V8HI_FTYPE_V8HI_INT },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_vmsqrtv2df2, "__builtin_ia32_sqrtsd", IX86_BUILTIN_SQRTSD, UNKNOWN, (int) V2DF_FTYPE_V2DF_VEC_MERGE },
-
- { OPTION_MASK_ISA_SSE, CODE_FOR_sse2_movq128, "__builtin_ia32_movq128", IX86_BUILTIN_MOVQ128, UNKNOWN, (int) V2DI_FTYPE_V2DI },
-
- /* SSE2 MMX */
- { OPTION_MASK_ISA_SSE2, CODE_FOR_mmx_addv1di3, "__builtin_ia32_paddq", IX86_BUILTIN_PADDQ, UNKNOWN, (int) V1DI_FTYPE_V1DI_V1DI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_mmx_subv1di3, "__builtin_ia32_psubq", IX86_BUILTIN_PSUBQ, UNKNOWN, (int) V1DI_FTYPE_V1DI_V1DI },
-
- /* SSE3 */
- { OPTION_MASK_ISA_SSE3, CODE_FOR_sse3_movshdup, "__builtin_ia32_movshdup", IX86_BUILTIN_MOVSHDUP, UNKNOWN, (int) V4SF_FTYPE_V4SF},
- { OPTION_MASK_ISA_SSE3, CODE_FOR_sse3_movsldup, "__builtin_ia32_movsldup", IX86_BUILTIN_MOVSLDUP, UNKNOWN, (int) V4SF_FTYPE_V4SF },
-
- { OPTION_MASK_ISA_SSE3, CODE_FOR_sse3_addsubv4sf3, "__builtin_ia32_addsubps", IX86_BUILTIN_ADDSUBPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE3, CODE_FOR_sse3_addsubv2df3, "__builtin_ia32_addsubpd", IX86_BUILTIN_ADDSUBPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE3, CODE_FOR_sse3_haddv4sf3, "__builtin_ia32_haddps", IX86_BUILTIN_HADDPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE3, CODE_FOR_sse3_haddv2df3, "__builtin_ia32_haddpd", IX86_BUILTIN_HADDPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE3, CODE_FOR_sse3_hsubv4sf3, "__builtin_ia32_hsubps", IX86_BUILTIN_HSUBPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE3, CODE_FOR_sse3_hsubv2df3, "__builtin_ia32_hsubpd", IX86_BUILTIN_HSUBPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF },
-
- /* SSSE3 */
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_absv16qi2, "__builtin_ia32_pabsb128", IX86_BUILTIN_PABSB128, UNKNOWN, (int) V16QI_FTYPE_V16QI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_absv8qi2, "__builtin_ia32_pabsb", IX86_BUILTIN_PABSB, UNKNOWN, (int) V8QI_FTYPE_V8QI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_absv8hi2, "__builtin_ia32_pabsw128", IX86_BUILTIN_PABSW128, UNKNOWN, (int) V8HI_FTYPE_V8HI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_absv4hi2, "__builtin_ia32_pabsw", IX86_BUILTIN_PABSW, UNKNOWN, (int) V4HI_FTYPE_V4HI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_absv4si2, "__builtin_ia32_pabsd128", IX86_BUILTIN_PABSD128, UNKNOWN, (int) V4SI_FTYPE_V4SI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_absv2si2, "__builtin_ia32_pabsd", IX86_BUILTIN_PABSD, UNKNOWN, (int) V2SI_FTYPE_V2SI },
-
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_phaddwv8hi3, "__builtin_ia32_phaddw128", IX86_BUILTIN_PHADDW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_phaddwv4hi3, "__builtin_ia32_phaddw", IX86_BUILTIN_PHADDW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_phadddv4si3, "__builtin_ia32_phaddd128", IX86_BUILTIN_PHADDD128, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_phadddv2si3, "__builtin_ia32_phaddd", IX86_BUILTIN_PHADDD, UNKNOWN, (int) V2SI_FTYPE_V2SI_V2SI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_phaddswv8hi3, "__builtin_ia32_phaddsw128", IX86_BUILTIN_PHADDSW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_phaddswv4hi3, "__builtin_ia32_phaddsw", IX86_BUILTIN_PHADDSW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_phsubwv8hi3, "__builtin_ia32_phsubw128", IX86_BUILTIN_PHSUBW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_phsubwv4hi3, "__builtin_ia32_phsubw", IX86_BUILTIN_PHSUBW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_phsubdv4si3, "__builtin_ia32_phsubd128", IX86_BUILTIN_PHSUBD128, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_phsubdv2si3, "__builtin_ia32_phsubd", IX86_BUILTIN_PHSUBD, UNKNOWN, (int) V2SI_FTYPE_V2SI_V2SI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_phsubswv8hi3, "__builtin_ia32_phsubsw128", IX86_BUILTIN_PHSUBSW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_phsubswv4hi3, "__builtin_ia32_phsubsw", IX86_BUILTIN_PHSUBSW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_pmaddubsw128, "__builtin_ia32_pmaddubsw128", IX86_BUILTIN_PMADDUBSW128, UNKNOWN, (int) V8HI_FTYPE_V16QI_V16QI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_pmaddubsw, "__builtin_ia32_pmaddubsw", IX86_BUILTIN_PMADDUBSW, UNKNOWN, (int) V4HI_FTYPE_V8QI_V8QI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_pmulhrswv8hi3, "__builtin_ia32_pmulhrsw128", IX86_BUILTIN_PMULHRSW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_pmulhrswv4hi3, "__builtin_ia32_pmulhrsw", IX86_BUILTIN_PMULHRSW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_pshufbv16qi3, "__builtin_ia32_pshufb128", IX86_BUILTIN_PSHUFB128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_pshufbv8qi3, "__builtin_ia32_pshufb", IX86_BUILTIN_PSHUFB, UNKNOWN, (int) V8QI_FTYPE_V8QI_V8QI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_psignv16qi3, "__builtin_ia32_psignb128", IX86_BUILTIN_PSIGNB128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_psignv8qi3, "__builtin_ia32_psignb", IX86_BUILTIN_PSIGNB, UNKNOWN, (int) V8QI_FTYPE_V8QI_V8QI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_psignv8hi3, "__builtin_ia32_psignw128", IX86_BUILTIN_PSIGNW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_psignv4hi3, "__builtin_ia32_psignw", IX86_BUILTIN_PSIGNW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_psignv4si3, "__builtin_ia32_psignd128", IX86_BUILTIN_PSIGND128, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_psignv2si3, "__builtin_ia32_psignd", IX86_BUILTIN_PSIGND, UNKNOWN, (int) V2SI_FTYPE_V2SI_V2SI },
-
- /* SSSE3. */
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_palignrti, "__builtin_ia32_palignr128", IX86_BUILTIN_PALIGNR128, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_INT_CONVERT },
- { OPTION_MASK_ISA_SSSE3, CODE_FOR_ssse3_palignrdi, "__builtin_ia32_palignr", IX86_BUILTIN_PALIGNR, UNKNOWN, (int) V1DI_FTYPE_V1DI_V1DI_INT_CONVERT },
-
- /* SSE4.1 */
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_blendpd, "__builtin_ia32_blendpd", IX86_BUILTIN_BLENDPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF_INT },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_blendps, "__builtin_ia32_blendps", IX86_BUILTIN_BLENDPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF_INT },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_blendvpd, "__builtin_ia32_blendvpd", IX86_BUILTIN_BLENDVPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF_V2DF },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_blendvps, "__builtin_ia32_blendvps", IX86_BUILTIN_BLENDVPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF_V4SF },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_dppd, "__builtin_ia32_dppd", IX86_BUILTIN_DPPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF_INT },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_dpps, "__builtin_ia32_dpps", IX86_BUILTIN_DPPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF_INT },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_insertps, "__builtin_ia32_insertps128", IX86_BUILTIN_INSERTPS128, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF_INT },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_mpsadbw, "__builtin_ia32_mpsadbw128", IX86_BUILTIN_MPSADBW128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI_INT },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_pblendvb, "__builtin_ia32_pblendvb128", IX86_BUILTIN_PBLENDVB128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI_V16QI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_pblendw, "__builtin_ia32_pblendw128", IX86_BUILTIN_PBLENDW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI_INT },
-
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_sign_extendv8qiv8hi2, "__builtin_ia32_pmovsxbw128", IX86_BUILTIN_PMOVSXBW128, UNKNOWN, (int) V8HI_FTYPE_V16QI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_sign_extendv4qiv4si2, "__builtin_ia32_pmovsxbd128", IX86_BUILTIN_PMOVSXBD128, UNKNOWN, (int) V4SI_FTYPE_V16QI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_sign_extendv2qiv2di2, "__builtin_ia32_pmovsxbq128", IX86_BUILTIN_PMOVSXBQ128, UNKNOWN, (int) V2DI_FTYPE_V16QI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_sign_extendv4hiv4si2, "__builtin_ia32_pmovsxwd128", IX86_BUILTIN_PMOVSXWD128, UNKNOWN, (int) V4SI_FTYPE_V8HI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_sign_extendv2hiv2di2, "__builtin_ia32_pmovsxwq128", IX86_BUILTIN_PMOVSXWQ128, UNKNOWN, (int) V2DI_FTYPE_V8HI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_sign_extendv2siv2di2, "__builtin_ia32_pmovsxdq128", IX86_BUILTIN_PMOVSXDQ128, UNKNOWN, (int) V2DI_FTYPE_V4SI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_zero_extendv8qiv8hi2, "__builtin_ia32_pmovzxbw128", IX86_BUILTIN_PMOVZXBW128, UNKNOWN, (int) V8HI_FTYPE_V16QI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_zero_extendv4qiv4si2, "__builtin_ia32_pmovzxbd128", IX86_BUILTIN_PMOVZXBD128, UNKNOWN, (int) V4SI_FTYPE_V16QI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_zero_extendv2qiv2di2, "__builtin_ia32_pmovzxbq128", IX86_BUILTIN_PMOVZXBQ128, UNKNOWN, (int) V2DI_FTYPE_V16QI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_zero_extendv4hiv4si2, "__builtin_ia32_pmovzxwd128", IX86_BUILTIN_PMOVZXWD128, UNKNOWN, (int) V4SI_FTYPE_V8HI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_zero_extendv2hiv2di2, "__builtin_ia32_pmovzxwq128", IX86_BUILTIN_PMOVZXWQ128, UNKNOWN, (int) V2DI_FTYPE_V8HI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_zero_extendv2siv2di2, "__builtin_ia32_pmovzxdq128", IX86_BUILTIN_PMOVZXDQ128, UNKNOWN, (int) V2DI_FTYPE_V4SI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_phminposuw, "__builtin_ia32_phminposuw128", IX86_BUILTIN_PHMINPOSUW128, UNKNOWN, (int) V8HI_FTYPE_V8HI },
-
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_packusdw, "__builtin_ia32_packusdw128", IX86_BUILTIN_PACKUSDW128, UNKNOWN, (int) V8HI_FTYPE_V4SI_V4SI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_eqv2di3, "__builtin_ia32_pcmpeqq", IX86_BUILTIN_PCMPEQQ, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_smaxv16qi3, "__builtin_ia32_pmaxsb128", IX86_BUILTIN_PMAXSB128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_smaxv4si3, "__builtin_ia32_pmaxsd128", IX86_BUILTIN_PMAXSD128, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_umaxv4si3, "__builtin_ia32_pmaxud128", IX86_BUILTIN_PMAXUD128, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_umaxv8hi3, "__builtin_ia32_pmaxuw128", IX86_BUILTIN_PMAXUW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sminv16qi3, "__builtin_ia32_pminsb128", IX86_BUILTIN_PMINSB128, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sminv4si3, "__builtin_ia32_pminsd128", IX86_BUILTIN_PMINSD128, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_uminv4si3, "__builtin_ia32_pminud128", IX86_BUILTIN_PMINUD128, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_uminv8hi3, "__builtin_ia32_pminuw128", IX86_BUILTIN_PMINUW128, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_sse4_1_mulv2siv2di3, "__builtin_ia32_pmuldq128", IX86_BUILTIN_PMULDQ128, UNKNOWN, (int) V2DI_FTYPE_V4SI_V4SI },
- { OPTION_MASK_ISA_SSE4_1, CODE_FOR_mulv4si3, "__builtin_ia32_pmulld128", IX86_BUILTIN_PMULLD128, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI },
-
- /* SSE4.1 */
- { OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_roundpd, "__builtin_ia32_roundpd", IX86_BUILTIN_ROUNDPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_INT },
- { OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_roundps, "__builtin_ia32_roundps", IX86_BUILTIN_ROUNDPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_INT },
- { OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_roundsd, "__builtin_ia32_roundsd", IX86_BUILTIN_ROUNDSD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF_INT },
- { OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_roundss, "__builtin_ia32_roundss", IX86_BUILTIN_ROUNDSS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF_INT },
-
- { OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_roundpd, "__builtin_ia32_floorpd", IX86_BUILTIN_FLOORPD, (enum rtx_code) ROUND_FLOOR, (int) V2DF_FTYPE_V2DF_ROUND },
- { OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_roundpd, "__builtin_ia32_ceilpd", IX86_BUILTIN_CEILPD, (enum rtx_code) ROUND_CEIL, (int) V2DF_FTYPE_V2DF_ROUND },
- { OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_roundpd, "__builtin_ia32_truncpd", IX86_BUILTIN_TRUNCPD, (enum rtx_code) ROUND_TRUNC, (int) V2DF_FTYPE_V2DF_ROUND },
- { OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_roundpd, "__builtin_ia32_rintpd", IX86_BUILTIN_RINTPD, (enum rtx_code) ROUND_MXCSR, (int) V2DF_FTYPE_V2DF_ROUND },
-
- { OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_roundpd_vec_pack_sfix, "__builtin_ia32_floorpd_vec_pack_sfix", IX86_BUILTIN_FLOORPD_VEC_PACK_SFIX, (enum rtx_code) ROUND_FLOOR, (int) V4SI_FTYPE_V2DF_V2DF_ROUND },
- { OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_roundpd_vec_pack_sfix, "__builtin_ia32_ceilpd_vec_pack_sfix", IX86_BUILTIN_CEILPD_VEC_PACK_SFIX, (enum rtx_code) ROUND_CEIL, (int) V4SI_FTYPE_V2DF_V2DF_ROUND },
-
- { OPTION_MASK_ISA_ROUND, CODE_FOR_roundv2df2, "__builtin_ia32_roundpd_az", IX86_BUILTIN_ROUNDPD_AZ, UNKNOWN, (int) V2DF_FTYPE_V2DF },
- { OPTION_MASK_ISA_ROUND, CODE_FOR_roundv2df2_vec_pack_sfix, "__builtin_ia32_roundpd_az_vec_pack_sfix", IX86_BUILTIN_ROUNDPD_AZ_VEC_PACK_SFIX, UNKNOWN, (int) V4SI_FTYPE_V2DF_V2DF },
-
- { OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_roundps, "__builtin_ia32_floorps", IX86_BUILTIN_FLOORPS, (enum rtx_code) ROUND_FLOOR, (int) V4SF_FTYPE_V4SF_ROUND },
- { OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_roundps, "__builtin_ia32_ceilps", IX86_BUILTIN_CEILPS, (enum rtx_code) ROUND_CEIL, (int) V4SF_FTYPE_V4SF_ROUND },
- { OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_roundps, "__builtin_ia32_truncps", IX86_BUILTIN_TRUNCPS, (enum rtx_code) ROUND_TRUNC, (int) V4SF_FTYPE_V4SF_ROUND },
- { OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_roundps, "__builtin_ia32_rintps", IX86_BUILTIN_RINTPS, (enum rtx_code) ROUND_MXCSR, (int) V4SF_FTYPE_V4SF_ROUND },
-
- { OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_roundps_sfix, "__builtin_ia32_floorps_sfix", IX86_BUILTIN_FLOORPS_SFIX, (enum rtx_code) ROUND_FLOOR, (int) V4SI_FTYPE_V4SF_ROUND },
- { OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_roundps_sfix, "__builtin_ia32_ceilps_sfix", IX86_BUILTIN_CEILPS_SFIX, (enum rtx_code) ROUND_CEIL, (int) V4SI_FTYPE_V4SF_ROUND },
-
- { OPTION_MASK_ISA_ROUND, CODE_FOR_roundv4sf2, "__builtin_ia32_roundps_az", IX86_BUILTIN_ROUNDPS_AZ, UNKNOWN, (int) V4SF_FTYPE_V4SF },
- { OPTION_MASK_ISA_ROUND, CODE_FOR_roundv4sf2_sfix, "__builtin_ia32_roundps_az_sfix", IX86_BUILTIN_ROUNDPS_AZ_SFIX, UNKNOWN, (int) V4SI_FTYPE_V4SF },
-
- { OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_ptest, "__builtin_ia32_ptestz128", IX86_BUILTIN_PTESTZ, EQ, (int) INT_FTYPE_V2DI_V2DI_PTEST },
- { OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_ptest, "__builtin_ia32_ptestc128", IX86_BUILTIN_PTESTC, LTU, (int) INT_FTYPE_V2DI_V2DI_PTEST },
- { OPTION_MASK_ISA_ROUND, CODE_FOR_sse4_1_ptest, "__builtin_ia32_ptestnzc128", IX86_BUILTIN_PTESTNZC, GTU, (int) INT_FTYPE_V2DI_V2DI_PTEST },
-
- /* SSE4.2 */
- { OPTION_MASK_ISA_SSE4_2, CODE_FOR_sse4_2_gtv2di3, "__builtin_ia32_pcmpgtq", IX86_BUILTIN_PCMPGTQ, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI },
- { OPTION_MASK_ISA_SSE4_2 | OPTION_MASK_ISA_CRC32, CODE_FOR_sse4_2_crc32qi, "__builtin_ia32_crc32qi", IX86_BUILTIN_CRC32QI, UNKNOWN, (int) UINT_FTYPE_UINT_UCHAR },
- { OPTION_MASK_ISA_SSE4_2 | OPTION_MASK_ISA_CRC32, CODE_FOR_sse4_2_crc32hi, "__builtin_ia32_crc32hi", IX86_BUILTIN_CRC32HI, UNKNOWN, (int) UINT_FTYPE_UINT_USHORT },
- { OPTION_MASK_ISA_SSE4_2 | OPTION_MASK_ISA_CRC32, CODE_FOR_sse4_2_crc32si, "__builtin_ia32_crc32si", IX86_BUILTIN_CRC32SI, UNKNOWN, (int) UINT_FTYPE_UINT_UINT },
- { OPTION_MASK_ISA_SSE4_2 | OPTION_MASK_ISA_CRC32 | OPTION_MASK_ISA_64BIT, CODE_FOR_sse4_2_crc32di, "__builtin_ia32_crc32di", IX86_BUILTIN_CRC32DI, UNKNOWN, (int) UINT64_FTYPE_UINT64_UINT64 },
-
- /* SSE4A */
- { OPTION_MASK_ISA_SSE4A, CODE_FOR_sse4a_extrqi, "__builtin_ia32_extrqi", IX86_BUILTIN_EXTRQI, UNKNOWN, (int) V2DI_FTYPE_V2DI_UINT_UINT },
- { OPTION_MASK_ISA_SSE4A, CODE_FOR_sse4a_extrq, "__builtin_ia32_extrq", IX86_BUILTIN_EXTRQ, UNKNOWN, (int) V2DI_FTYPE_V2DI_V16QI },
- { OPTION_MASK_ISA_SSE4A, CODE_FOR_sse4a_insertqi, "__builtin_ia32_insertqi", IX86_BUILTIN_INSERTQI, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_UINT_UINT },
- { OPTION_MASK_ISA_SSE4A, CODE_FOR_sse4a_insertq, "__builtin_ia32_insertq", IX86_BUILTIN_INSERTQ, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI },
-
- /* AES */
- { OPTION_MASK_ISA_SSE2, CODE_FOR_aeskeygenassist, 0, IX86_BUILTIN_AESKEYGENASSIST128, UNKNOWN, (int) V2DI_FTYPE_V2DI_INT },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_aesimc, 0, IX86_BUILTIN_AESIMC128, UNKNOWN, (int) V2DI_FTYPE_V2DI },
-
- { OPTION_MASK_ISA_SSE2, CODE_FOR_aesenc, 0, IX86_BUILTIN_AESENC128, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_aesenclast, 0, IX86_BUILTIN_AESENCLAST128, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_aesdec, 0, IX86_BUILTIN_AESDEC128, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI },
- { OPTION_MASK_ISA_SSE2, CODE_FOR_aesdeclast, 0, IX86_BUILTIN_AESDECLAST128, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI },
-
- /* PCLMUL */
- { OPTION_MASK_ISA_SSE2, CODE_FOR_pclmulqdq, 0, IX86_BUILTIN_PCLMULQDQ128, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_INT },
-
- /* AVX */
- { OPTION_MASK_ISA_AVX, CODE_FOR_addv4df3, "__builtin_ia32_addpd256", IX86_BUILTIN_ADDPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_addv8sf3, "__builtin_ia32_addps256", IX86_BUILTIN_ADDPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_addsubv4df3, "__builtin_ia32_addsubpd256", IX86_BUILTIN_ADDSUBPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_addsubv8sf3, "__builtin_ia32_addsubps256", IX86_BUILTIN_ADDSUBPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_andv4df3, "__builtin_ia32_andpd256", IX86_BUILTIN_ANDPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_andv8sf3, "__builtin_ia32_andps256", IX86_BUILTIN_ANDPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_andnotv4df3, "__builtin_ia32_andnpd256", IX86_BUILTIN_ANDNPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_andnotv8sf3, "__builtin_ia32_andnps256", IX86_BUILTIN_ANDNPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_divv4df3, "__builtin_ia32_divpd256", IX86_BUILTIN_DIVPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_divv8sf3, "__builtin_ia32_divps256", IX86_BUILTIN_DIVPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_haddv4df3, "__builtin_ia32_haddpd256", IX86_BUILTIN_HADDPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_hsubv8sf3, "__builtin_ia32_hsubps256", IX86_BUILTIN_HSUBPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_hsubv4df3, "__builtin_ia32_hsubpd256", IX86_BUILTIN_HSUBPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_haddv8sf3, "__builtin_ia32_haddps256", IX86_BUILTIN_HADDPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_smaxv4df3, "__builtin_ia32_maxpd256", IX86_BUILTIN_MAXPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_smaxv8sf3, "__builtin_ia32_maxps256", IX86_BUILTIN_MAXPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_sminv4df3, "__builtin_ia32_minpd256", IX86_BUILTIN_MINPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_sminv8sf3, "__builtin_ia32_minps256", IX86_BUILTIN_MINPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_mulv4df3, "__builtin_ia32_mulpd256", IX86_BUILTIN_MULPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_mulv8sf3, "__builtin_ia32_mulps256", IX86_BUILTIN_MULPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_iorv4df3, "__builtin_ia32_orpd256", IX86_BUILTIN_ORPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_iorv8sf3, "__builtin_ia32_orps256", IX86_BUILTIN_ORPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_subv4df3, "__builtin_ia32_subpd256", IX86_BUILTIN_SUBPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_subv8sf3, "__builtin_ia32_subps256", IX86_BUILTIN_SUBPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_xorv4df3, "__builtin_ia32_xorpd256", IX86_BUILTIN_XORPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_xorv8sf3, "__builtin_ia32_xorps256", IX86_BUILTIN_XORPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF },
-
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vpermilvarv2df3, "__builtin_ia32_vpermilvarpd", IX86_BUILTIN_VPERMILVARPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DI },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vpermilvarv4sf3, "__builtin_ia32_vpermilvarps", IX86_BUILTIN_VPERMILVARPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SI },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vpermilvarv4df3, "__builtin_ia32_vpermilvarpd256", IX86_BUILTIN_VPERMILVARPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DI },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vpermilvarv8sf3, "__builtin_ia32_vpermilvarps256", IX86_BUILTIN_VPERMILVARPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SI },
-
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_blendpd256, "__builtin_ia32_blendpd256", IX86_BUILTIN_BLENDPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_blendps256, "__builtin_ia32_blendps256", IX86_BUILTIN_BLENDPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_blendvpd256, "__builtin_ia32_blendvpd256", IX86_BUILTIN_BLENDVPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_blendvps256, "__builtin_ia32_blendvps256", IX86_BUILTIN_BLENDVPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_dpps256, "__builtin_ia32_dpps256", IX86_BUILTIN_DPPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_shufpd256, "__builtin_ia32_shufpd256", IX86_BUILTIN_SHUFPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_shufps256, "__builtin_ia32_shufps256", IX86_BUILTIN_SHUFPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vmcmpv2df3, "__builtin_ia32_cmpsd", IX86_BUILTIN_CMPSD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vmcmpv4sf3, "__builtin_ia32_cmpss", IX86_BUILTIN_CMPSS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_cmpv2df3, "__builtin_ia32_cmppd", IX86_BUILTIN_CMPPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_cmpv4sf3, "__builtin_ia32_cmpps", IX86_BUILTIN_CMPPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_cmpv4df3, "__builtin_ia32_cmppd256", IX86_BUILTIN_CMPPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_cmpv8sf3, "__builtin_ia32_cmpps256", IX86_BUILTIN_CMPPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vextractf128v4df, "__builtin_ia32_vextractf128_pd256", IX86_BUILTIN_EXTRACTF128PD256, UNKNOWN, (int) V2DF_FTYPE_V4DF_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vextractf128v8sf, "__builtin_ia32_vextractf128_ps256", IX86_BUILTIN_EXTRACTF128PS256, UNKNOWN, (int) V4SF_FTYPE_V8SF_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vextractf128v8si, "__builtin_ia32_vextractf128_si256", IX86_BUILTIN_EXTRACTF128SI256, UNKNOWN, (int) V4SI_FTYPE_V8SI_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_floatv4siv4df2, "__builtin_ia32_cvtdq2pd256", IX86_BUILTIN_CVTDQ2PD256, UNKNOWN, (int) V4DF_FTYPE_V4SI },
- { OPTION_MASK_ISA_AVX, CODE_FOR_floatv8siv8sf2, "__builtin_ia32_cvtdq2ps256", IX86_BUILTIN_CVTDQ2PS256, UNKNOWN, (int) V8SF_FTYPE_V8SI },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_cvtpd2ps256, "__builtin_ia32_cvtpd2ps256", IX86_BUILTIN_CVTPD2PS256, UNKNOWN, (int) V4SF_FTYPE_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_cvtps2dq256, "__builtin_ia32_cvtps2dq256", IX86_BUILTIN_CVTPS2DQ256, UNKNOWN, (int) V8SI_FTYPE_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_cvtps2pd256, "__builtin_ia32_cvtps2pd256", IX86_BUILTIN_CVTPS2PD256, UNKNOWN, (int) V4DF_FTYPE_V4SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_fix_truncv4dfv4si2, "__builtin_ia32_cvttpd2dq256", IX86_BUILTIN_CVTTPD2DQ256, UNKNOWN, (int) V4SI_FTYPE_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_cvtpd2dq256, "__builtin_ia32_cvtpd2dq256", IX86_BUILTIN_CVTPD2DQ256, UNKNOWN, (int) V4SI_FTYPE_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_fix_truncv8sfv8si2, "__builtin_ia32_cvttps2dq256", IX86_BUILTIN_CVTTPS2DQ256, UNKNOWN, (int) V8SI_FTYPE_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vperm2f128v4df3, "__builtin_ia32_vperm2f128_pd256", IX86_BUILTIN_VPERM2F128PD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vperm2f128v8sf3, "__builtin_ia32_vperm2f128_ps256", IX86_BUILTIN_VPERM2F128PS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vperm2f128v8si3, "__builtin_ia32_vperm2f128_si256", IX86_BUILTIN_VPERM2F128SI256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vpermilv2df, "__builtin_ia32_vpermilpd", IX86_BUILTIN_VPERMILPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vpermilv4sf, "__builtin_ia32_vpermilps", IX86_BUILTIN_VPERMILPS, UNKNOWN, (int) V4SF_FTYPE_V4SF_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vpermilv4df, "__builtin_ia32_vpermilpd256", IX86_BUILTIN_VPERMILPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vpermilv8sf, "__builtin_ia32_vpermilps256", IX86_BUILTIN_VPERMILPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vinsertf128v4df, "__builtin_ia32_vinsertf128_pd256", IX86_BUILTIN_VINSERTF128PD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V2DF_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vinsertf128v8sf, "__builtin_ia32_vinsertf128_ps256", IX86_BUILTIN_VINSERTF128PS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V4SF_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vinsertf128v8si, "__builtin_ia32_vinsertf128_si256", IX86_BUILTIN_VINSERTF128SI256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V4SI_INT },
-
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_movshdup256, "__builtin_ia32_movshdup256", IX86_BUILTIN_MOVSHDUP256, UNKNOWN, (int) V8SF_FTYPE_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_movsldup256, "__builtin_ia32_movsldup256", IX86_BUILTIN_MOVSLDUP256, UNKNOWN, (int) V8SF_FTYPE_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_movddup256, "__builtin_ia32_movddup256", IX86_BUILTIN_MOVDDUP256, UNKNOWN, (int) V4DF_FTYPE_V4DF },
-
- { OPTION_MASK_ISA_AVX, CODE_FOR_sqrtv4df2, "__builtin_ia32_sqrtpd256", IX86_BUILTIN_SQRTPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_sqrtv8sf2, "__builtin_ia32_sqrtps256", IX86_BUILTIN_SQRTPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_sqrtv8sf2, "__builtin_ia32_sqrtps_nr256", IX86_BUILTIN_SQRTPS_NR256, UNKNOWN, (int) V8SF_FTYPE_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_rsqrtv8sf2, "__builtin_ia32_rsqrtps256", IX86_BUILTIN_RSQRTPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_rsqrtv8sf2, "__builtin_ia32_rsqrtps_nr256", IX86_BUILTIN_RSQRTPS_NR256, UNKNOWN, (int) V8SF_FTYPE_V8SF },
-
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_rcpv8sf2, "__builtin_ia32_rcpps256", IX86_BUILTIN_RCPPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF },
-
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_roundpd256, "__builtin_ia32_roundpd256", IX86_BUILTIN_ROUNDPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_INT },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_roundps256, "__builtin_ia32_roundps256", IX86_BUILTIN_ROUNDPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_INT },
-
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_roundpd256, "__builtin_ia32_floorpd256", IX86_BUILTIN_FLOORPD256, (enum rtx_code) ROUND_FLOOR, (int) V4DF_FTYPE_V4DF_ROUND },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_roundpd256, "__builtin_ia32_ceilpd256", IX86_BUILTIN_CEILPD256, (enum rtx_code) ROUND_CEIL, (int) V4DF_FTYPE_V4DF_ROUND },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_roundpd256, "__builtin_ia32_truncpd256", IX86_BUILTIN_TRUNCPD256, (enum rtx_code) ROUND_TRUNC, (int) V4DF_FTYPE_V4DF_ROUND },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_roundpd256, "__builtin_ia32_rintpd256", IX86_BUILTIN_RINTPD256, (enum rtx_code) ROUND_MXCSR, (int) V4DF_FTYPE_V4DF_ROUND },
-
- { OPTION_MASK_ISA_AVX, CODE_FOR_roundv4df2, "__builtin_ia32_roundpd_az256", IX86_BUILTIN_ROUNDPD_AZ256, UNKNOWN, (int) V4DF_FTYPE_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_roundv4df2_vec_pack_sfix, "__builtin_ia32_roundpd_az_vec_pack_sfix256", IX86_BUILTIN_ROUNDPD_AZ_VEC_PACK_SFIX256, UNKNOWN, (int) V8SI_FTYPE_V4DF_V4DF },
-
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_roundpd_vec_pack_sfix256, "__builtin_ia32_floorpd_vec_pack_sfix256", IX86_BUILTIN_FLOORPD_VEC_PACK_SFIX256, (enum rtx_code) ROUND_FLOOR, (int) V8SI_FTYPE_V4DF_V4DF_ROUND },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_roundpd_vec_pack_sfix256, "__builtin_ia32_ceilpd_vec_pack_sfix256", IX86_BUILTIN_CEILPD_VEC_PACK_SFIX256, (enum rtx_code) ROUND_CEIL, (int) V8SI_FTYPE_V4DF_V4DF_ROUND },
-
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_roundps256, "__builtin_ia32_floorps256", IX86_BUILTIN_FLOORPS256, (enum rtx_code) ROUND_FLOOR, (int) V8SF_FTYPE_V8SF_ROUND },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_roundps256, "__builtin_ia32_ceilps256", IX86_BUILTIN_CEILPS256, (enum rtx_code) ROUND_CEIL, (int) V8SF_FTYPE_V8SF_ROUND },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_roundps256, "__builtin_ia32_truncps256", IX86_BUILTIN_TRUNCPS256, (enum rtx_code) ROUND_TRUNC, (int) V8SF_FTYPE_V8SF_ROUND },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_roundps256, "__builtin_ia32_rintps256", IX86_BUILTIN_RINTPS256, (enum rtx_code) ROUND_MXCSR, (int) V8SF_FTYPE_V8SF_ROUND },
-
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_roundps_sfix256, "__builtin_ia32_floorps_sfix256", IX86_BUILTIN_FLOORPS_SFIX256, (enum rtx_code) ROUND_FLOOR, (int) V8SI_FTYPE_V8SF_ROUND },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_roundps_sfix256, "__builtin_ia32_ceilps_sfix256", IX86_BUILTIN_CEILPS_SFIX256, (enum rtx_code) ROUND_CEIL, (int) V8SI_FTYPE_V8SF_ROUND },
-
- { OPTION_MASK_ISA_AVX, CODE_FOR_roundv8sf2, "__builtin_ia32_roundps_az256", IX86_BUILTIN_ROUNDPS_AZ256, UNKNOWN, (int) V8SF_FTYPE_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_roundv8sf2_sfix, "__builtin_ia32_roundps_az_sfix256", IX86_BUILTIN_ROUNDPS_AZ_SFIX256, UNKNOWN, (int) V8SI_FTYPE_V8SF },
-
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_unpckhpd256, "__builtin_ia32_unpckhpd256", IX86_BUILTIN_UNPCKHPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_unpcklpd256, "__builtin_ia32_unpcklpd256", IX86_BUILTIN_UNPCKLPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_unpckhps256, "__builtin_ia32_unpckhps256", IX86_BUILTIN_UNPCKHPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_unpcklps256, "__builtin_ia32_unpcklps256", IX86_BUILTIN_UNPCKLPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF },
-
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_si256_si, "__builtin_ia32_si256_si", IX86_BUILTIN_SI256_SI, UNKNOWN, (int) V8SI_FTYPE_V4SI },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_ps256_ps, "__builtin_ia32_ps256_ps", IX86_BUILTIN_PS256_PS, UNKNOWN, (int) V8SF_FTYPE_V4SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_pd256_pd, "__builtin_ia32_pd256_pd", IX86_BUILTIN_PD256_PD, UNKNOWN, (int) V4DF_FTYPE_V2DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_vec_extract_lo_v8si, "__builtin_ia32_si_si256", IX86_BUILTIN_SI_SI256, UNKNOWN, (int) V4SI_FTYPE_V8SI },
- { OPTION_MASK_ISA_AVX, CODE_FOR_vec_extract_lo_v8sf, "__builtin_ia32_ps_ps256", IX86_BUILTIN_PS_PS256, UNKNOWN, (int) V4SF_FTYPE_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_vec_extract_lo_v4df, "__builtin_ia32_pd_pd256", IX86_BUILTIN_PD_PD256, UNKNOWN, (int) V2DF_FTYPE_V4DF },
-
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vtestpd, "__builtin_ia32_vtestzpd", IX86_BUILTIN_VTESTZPD, EQ, (int) INT_FTYPE_V2DF_V2DF_PTEST },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vtestpd, "__builtin_ia32_vtestcpd", IX86_BUILTIN_VTESTCPD, LTU, (int) INT_FTYPE_V2DF_V2DF_PTEST },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vtestpd, "__builtin_ia32_vtestnzcpd", IX86_BUILTIN_VTESTNZCPD, GTU, (int) INT_FTYPE_V2DF_V2DF_PTEST },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vtestps, "__builtin_ia32_vtestzps", IX86_BUILTIN_VTESTZPS, EQ, (int) INT_FTYPE_V4SF_V4SF_PTEST },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vtestps, "__builtin_ia32_vtestcps", IX86_BUILTIN_VTESTCPS, LTU, (int) INT_FTYPE_V4SF_V4SF_PTEST },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vtestps, "__builtin_ia32_vtestnzcps", IX86_BUILTIN_VTESTNZCPS, GTU, (int) INT_FTYPE_V4SF_V4SF_PTEST },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vtestpd256, "__builtin_ia32_vtestzpd256", IX86_BUILTIN_VTESTZPD256, EQ, (int) INT_FTYPE_V4DF_V4DF_PTEST },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vtestpd256, "__builtin_ia32_vtestcpd256", IX86_BUILTIN_VTESTCPD256, LTU, (int) INT_FTYPE_V4DF_V4DF_PTEST },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vtestpd256, "__builtin_ia32_vtestnzcpd256", IX86_BUILTIN_VTESTNZCPD256, GTU, (int) INT_FTYPE_V4DF_V4DF_PTEST },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vtestps256, "__builtin_ia32_vtestzps256", IX86_BUILTIN_VTESTZPS256, EQ, (int) INT_FTYPE_V8SF_V8SF_PTEST },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vtestps256, "__builtin_ia32_vtestcps256", IX86_BUILTIN_VTESTCPS256, LTU, (int) INT_FTYPE_V8SF_V8SF_PTEST },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_vtestps256, "__builtin_ia32_vtestnzcps256", IX86_BUILTIN_VTESTNZCPS256, GTU, (int) INT_FTYPE_V8SF_V8SF_PTEST },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_ptest256, "__builtin_ia32_ptestz256", IX86_BUILTIN_PTESTZ256, EQ, (int) INT_FTYPE_V4DI_V4DI_PTEST },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_ptest256, "__builtin_ia32_ptestc256", IX86_BUILTIN_PTESTC256, LTU, (int) INT_FTYPE_V4DI_V4DI_PTEST },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_ptest256, "__builtin_ia32_ptestnzc256", IX86_BUILTIN_PTESTNZC256, GTU, (int) INT_FTYPE_V4DI_V4DI_PTEST },
-
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_movmskpd256, "__builtin_ia32_movmskpd256", IX86_BUILTIN_MOVMSKPD256, UNKNOWN, (int) INT_FTYPE_V4DF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_avx_movmskps256, "__builtin_ia32_movmskps256", IX86_BUILTIN_MOVMSKPS256, UNKNOWN, (int) INT_FTYPE_V8SF },
-
- { OPTION_MASK_ISA_AVX, CODE_FOR_copysignv8sf3, "__builtin_ia32_copysignps256", IX86_BUILTIN_CPYSGNPS256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_copysignv4df3, "__builtin_ia32_copysignpd256", IX86_BUILTIN_CPYSGNPD256, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF },
-
- { OPTION_MASK_ISA_AVX, CODE_FOR_vec_pack_sfix_v4df, "__builtin_ia32_vec_pack_sfix256 ", IX86_BUILTIN_VEC_PACK_SFIX256, UNKNOWN, (int) V8SI_FTYPE_V4DF_V4DF },
-
- /* AVX2 */
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_mpsadbw, "__builtin_ia32_mpsadbw256", IX86_BUILTIN_MPSADBW256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI_INT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_absv32qi2, "__builtin_ia32_pabsb256", IX86_BUILTIN_PABSB256, UNKNOWN, (int) V32QI_FTYPE_V32QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_absv16hi2, "__builtin_ia32_pabsw256", IX86_BUILTIN_PABSW256, UNKNOWN, (int) V16HI_FTYPE_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_absv8si2, "__builtin_ia32_pabsd256", IX86_BUILTIN_PABSD256, UNKNOWN, (int) V8SI_FTYPE_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_packssdw, "__builtin_ia32_packssdw256", IX86_BUILTIN_PACKSSDW256, UNKNOWN, (int) V16HI_FTYPE_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_packsswb, "__builtin_ia32_packsswb256", IX86_BUILTIN_PACKSSWB256, UNKNOWN, (int) V32QI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_packusdw, "__builtin_ia32_packusdw256", IX86_BUILTIN_PACKUSDW256, UNKNOWN, (int) V16HI_FTYPE_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_packuswb, "__builtin_ia32_packuswb256", IX86_BUILTIN_PACKUSWB256, UNKNOWN, (int) V32QI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_addv32qi3, "__builtin_ia32_paddb256", IX86_BUILTIN_PADDB256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_addv16hi3, "__builtin_ia32_paddw256", IX86_BUILTIN_PADDW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_addv8si3, "__builtin_ia32_paddd256", IX86_BUILTIN_PADDD256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_addv4di3, "__builtin_ia32_paddq256", IX86_BUILTIN_PADDQ256, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_ssaddv32qi3, "__builtin_ia32_paddsb256", IX86_BUILTIN_PADDSB256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_ssaddv16hi3, "__builtin_ia32_paddsw256", IX86_BUILTIN_PADDSW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_usaddv32qi3, "__builtin_ia32_paddusb256", IX86_BUILTIN_PADDUSB256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_usaddv16hi3, "__builtin_ia32_paddusw256", IX86_BUILTIN_PADDUSW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_palignrv2ti, "__builtin_ia32_palignr256", IX86_BUILTIN_PALIGNR256, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI_INT_CONVERT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_andv4di3, "__builtin_ia32_andsi256", IX86_BUILTIN_AND256I, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_andnotv4di3, "__builtin_ia32_andnotsi256", IX86_BUILTIN_ANDNOT256I, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_uavgv32qi3, "__builtin_ia32_pavgb256", IX86_BUILTIN_PAVGB256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_uavgv16hi3, "__builtin_ia32_pavgw256", IX86_BUILTIN_PAVGW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_pblendvb, "__builtin_ia32_pblendvb256", IX86_BUILTIN_PBLENDVB256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI_V32QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_pblendw, "__builtin_ia32_pblendw256", IX86_BUILTIN_PBLENDVW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI_INT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_eqv32qi3, "__builtin_ia32_pcmpeqb256", IX86_BUILTIN_PCMPEQB256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_eqv16hi3, "__builtin_ia32_pcmpeqw256", IX86_BUILTIN_PCMPEQW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_eqv8si3, "__builtin_ia32_pcmpeqd256", IX86_BUILTIN_PCMPEQD256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_eqv4di3, "__builtin_ia32_pcmpeqq256", IX86_BUILTIN_PCMPEQQ256, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_gtv32qi3, "__builtin_ia32_pcmpgtb256", IX86_BUILTIN_PCMPGTB256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_gtv16hi3, "__builtin_ia32_pcmpgtw256", IX86_BUILTIN_PCMPGTW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_gtv8si3, "__builtin_ia32_pcmpgtd256", IX86_BUILTIN_PCMPGTD256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_gtv4di3, "__builtin_ia32_pcmpgtq256", IX86_BUILTIN_PCMPGTQ256, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_phaddwv16hi3, "__builtin_ia32_phaddw256", IX86_BUILTIN_PHADDW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_phadddv8si3, "__builtin_ia32_phaddd256", IX86_BUILTIN_PHADDD256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_phaddswv16hi3, "__builtin_ia32_phaddsw256", IX86_BUILTIN_PHADDSW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_phsubwv16hi3, "__builtin_ia32_phsubw256", IX86_BUILTIN_PHSUBW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_phsubdv8si3, "__builtin_ia32_phsubd256", IX86_BUILTIN_PHSUBD256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_phsubswv16hi3, "__builtin_ia32_phsubsw256", IX86_BUILTIN_PHSUBSW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_pmaddubsw256, "__builtin_ia32_pmaddubsw256", IX86_BUILTIN_PMADDUBSW256, UNKNOWN, (int) V16HI_FTYPE_V32QI_V32QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_pmaddwd, "__builtin_ia32_pmaddwd256", IX86_BUILTIN_PMADDWD256, UNKNOWN, (int) V8SI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_smaxv32qi3, "__builtin_ia32_pmaxsb256", IX86_BUILTIN_PMAXSB256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_smaxv16hi3, "__builtin_ia32_pmaxsw256", IX86_BUILTIN_PMAXSW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_smaxv8si3 , "__builtin_ia32_pmaxsd256", IX86_BUILTIN_PMAXSD256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_umaxv32qi3, "__builtin_ia32_pmaxub256", IX86_BUILTIN_PMAXUB256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_umaxv16hi3, "__builtin_ia32_pmaxuw256", IX86_BUILTIN_PMAXUW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_umaxv8si3 , "__builtin_ia32_pmaxud256", IX86_BUILTIN_PMAXUD256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_sminv32qi3, "__builtin_ia32_pminsb256", IX86_BUILTIN_PMINSB256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_sminv16hi3, "__builtin_ia32_pminsw256", IX86_BUILTIN_PMINSW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_sminv8si3 , "__builtin_ia32_pminsd256", IX86_BUILTIN_PMINSD256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_uminv32qi3, "__builtin_ia32_pminub256", IX86_BUILTIN_PMINUB256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_uminv16hi3, "__builtin_ia32_pminuw256", IX86_BUILTIN_PMINUW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_uminv8si3 , "__builtin_ia32_pminud256", IX86_BUILTIN_PMINUD256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_pmovmskb, "__builtin_ia32_pmovmskb256", IX86_BUILTIN_PMOVMSKB256, UNKNOWN, (int) INT_FTYPE_V32QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_sign_extendv16qiv16hi2, "__builtin_ia32_pmovsxbw256", IX86_BUILTIN_PMOVSXBW256, UNKNOWN, (int) V16HI_FTYPE_V16QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_sign_extendv8qiv8si2 , "__builtin_ia32_pmovsxbd256", IX86_BUILTIN_PMOVSXBD256, UNKNOWN, (int) V8SI_FTYPE_V16QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_sign_extendv4qiv4di2 , "__builtin_ia32_pmovsxbq256", IX86_BUILTIN_PMOVSXBQ256, UNKNOWN, (int) V4DI_FTYPE_V16QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_sign_extendv8hiv8si2 , "__builtin_ia32_pmovsxwd256", IX86_BUILTIN_PMOVSXWD256, UNKNOWN, (int) V8SI_FTYPE_V8HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_sign_extendv4hiv4di2 , "__builtin_ia32_pmovsxwq256", IX86_BUILTIN_PMOVSXWQ256, UNKNOWN, (int) V4DI_FTYPE_V8HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_sign_extendv4siv4di2 , "__builtin_ia32_pmovsxdq256", IX86_BUILTIN_PMOVSXDQ256, UNKNOWN, (int) V4DI_FTYPE_V4SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_zero_extendv16qiv16hi2, "__builtin_ia32_pmovzxbw256", IX86_BUILTIN_PMOVZXBW256, UNKNOWN, (int) V16HI_FTYPE_V16QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_zero_extendv8qiv8si2 , "__builtin_ia32_pmovzxbd256", IX86_BUILTIN_PMOVZXBD256, UNKNOWN, (int) V8SI_FTYPE_V16QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_zero_extendv4qiv4di2 , "__builtin_ia32_pmovzxbq256", IX86_BUILTIN_PMOVZXBQ256, UNKNOWN, (int) V4DI_FTYPE_V16QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_zero_extendv8hiv8si2 , "__builtin_ia32_pmovzxwd256", IX86_BUILTIN_PMOVZXWD256, UNKNOWN, (int) V8SI_FTYPE_V8HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_zero_extendv4hiv4di2 , "__builtin_ia32_pmovzxwq256", IX86_BUILTIN_PMOVZXWQ256, UNKNOWN, (int) V4DI_FTYPE_V8HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_zero_extendv4siv4di2 , "__builtin_ia32_pmovzxdq256", IX86_BUILTIN_PMOVZXDQ256, UNKNOWN, (int) V4DI_FTYPE_V4SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_vec_widen_smult_even_v8si, "__builtin_ia32_pmuldq256", IX86_BUILTIN_PMULDQ256, UNKNOWN, (int) V4DI_FTYPE_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_pmulhrswv16hi3 , "__builtin_ia32_pmulhrsw256", IX86_BUILTIN_PMULHRSW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_umulv16hi3_highpart, "__builtin_ia32_pmulhuw256" , IX86_BUILTIN_PMULHUW256 , UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_smulv16hi3_highpart, "__builtin_ia32_pmulhw256" , IX86_BUILTIN_PMULHW256 , UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_mulv16hi3, "__builtin_ia32_pmullw256" , IX86_BUILTIN_PMULLW256 , UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_mulv8si3, "__builtin_ia32_pmulld256" , IX86_BUILTIN_PMULLD256 , UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_vec_widen_umult_even_v8si, "__builtin_ia32_pmuludq256", IX86_BUILTIN_PMULUDQ256, UNKNOWN, (int) V4DI_FTYPE_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_iorv4di3, "__builtin_ia32_por256", IX86_BUILTIN_POR256, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_psadbw, "__builtin_ia32_psadbw256", IX86_BUILTIN_PSADBW256, UNKNOWN, (int) V16HI_FTYPE_V32QI_V32QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_pshufbv32qi3, "__builtin_ia32_pshufb256", IX86_BUILTIN_PSHUFB256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_pshufdv3, "__builtin_ia32_pshufd256", IX86_BUILTIN_PSHUFD256, UNKNOWN, (int) V8SI_FTYPE_V8SI_INT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_pshufhwv3, "__builtin_ia32_pshufhw256", IX86_BUILTIN_PSHUFHW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_INT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_pshuflwv3, "__builtin_ia32_pshuflw256", IX86_BUILTIN_PSHUFLW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_INT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_psignv32qi3, "__builtin_ia32_psignb256", IX86_BUILTIN_PSIGNB256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_psignv16hi3, "__builtin_ia32_psignw256", IX86_BUILTIN_PSIGNW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_psignv8si3 , "__builtin_ia32_psignd256", IX86_BUILTIN_PSIGND256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_ashlv2ti3, "__builtin_ia32_pslldqi256", IX86_BUILTIN_PSLLDQI256, UNKNOWN, (int) V4DI_FTYPE_V4DI_INT_CONVERT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_ashlv16hi3, "__builtin_ia32_psllwi256", IX86_BUILTIN_PSLLWI256 , UNKNOWN, (int) V16HI_FTYPE_V16HI_SI_COUNT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_ashlv16hi3, "__builtin_ia32_psllw256", IX86_BUILTIN_PSLLW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V8HI_COUNT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_ashlv8si3, "__builtin_ia32_pslldi256", IX86_BUILTIN_PSLLDI256, UNKNOWN, (int) V8SI_FTYPE_V8SI_SI_COUNT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_ashlv8si3, "__builtin_ia32_pslld256", IX86_BUILTIN_PSLLD256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V4SI_COUNT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_ashlv4di3, "__builtin_ia32_psllqi256", IX86_BUILTIN_PSLLQI256, UNKNOWN, (int) V4DI_FTYPE_V4DI_INT_COUNT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_ashlv4di3, "__builtin_ia32_psllq256", IX86_BUILTIN_PSLLQ256, UNKNOWN, (int) V4DI_FTYPE_V4DI_V2DI_COUNT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_ashrv16hi3, "__builtin_ia32_psrawi256", IX86_BUILTIN_PSRAWI256, UNKNOWN, (int) V16HI_FTYPE_V16HI_SI_COUNT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_ashrv16hi3, "__builtin_ia32_psraw256", IX86_BUILTIN_PSRAW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V8HI_COUNT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_ashrv8si3, "__builtin_ia32_psradi256", IX86_BUILTIN_PSRADI256, UNKNOWN, (int) V8SI_FTYPE_V8SI_SI_COUNT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_ashrv8si3, "__builtin_ia32_psrad256", IX86_BUILTIN_PSRAD256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V4SI_COUNT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_lshrv2ti3, "__builtin_ia32_psrldqi256", IX86_BUILTIN_PSRLDQI256, UNKNOWN, (int) V4DI_FTYPE_V4DI_INT_CONVERT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_lshrv16hi3, "__builtin_ia32_psrlwi256", IX86_BUILTIN_PSRLWI256 , UNKNOWN, (int) V16HI_FTYPE_V16HI_SI_COUNT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_lshrv16hi3, "__builtin_ia32_psrlw256", IX86_BUILTIN_PSRLW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V8HI_COUNT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_lshrv8si3, "__builtin_ia32_psrldi256", IX86_BUILTIN_PSRLDI256, UNKNOWN, (int) V8SI_FTYPE_V8SI_SI_COUNT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_lshrv8si3, "__builtin_ia32_psrld256", IX86_BUILTIN_PSRLD256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V4SI_COUNT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_lshrv4di3, "__builtin_ia32_psrlqi256", IX86_BUILTIN_PSRLQI256, UNKNOWN, (int) V4DI_FTYPE_V4DI_INT_COUNT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_lshrv4di3, "__builtin_ia32_psrlq256", IX86_BUILTIN_PSRLQ256, UNKNOWN, (int) V4DI_FTYPE_V4DI_V2DI_COUNT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_subv32qi3, "__builtin_ia32_psubb256", IX86_BUILTIN_PSUBB256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_subv16hi3, "__builtin_ia32_psubw256", IX86_BUILTIN_PSUBW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_subv8si3, "__builtin_ia32_psubd256", IX86_BUILTIN_PSUBD256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_subv4di3, "__builtin_ia32_psubq256", IX86_BUILTIN_PSUBQ256, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_sssubv32qi3, "__builtin_ia32_psubsb256", IX86_BUILTIN_PSUBSB256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_sssubv16hi3, "__builtin_ia32_psubsw256", IX86_BUILTIN_PSUBSW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_ussubv32qi3, "__builtin_ia32_psubusb256", IX86_BUILTIN_PSUBUSB256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_ussubv16hi3, "__builtin_ia32_psubusw256", IX86_BUILTIN_PSUBUSW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_interleave_highv32qi, "__builtin_ia32_punpckhbw256", IX86_BUILTIN_PUNPCKHBW256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_interleave_highv16hi, "__builtin_ia32_punpckhwd256", IX86_BUILTIN_PUNPCKHWD256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_interleave_highv8si, "__builtin_ia32_punpckhdq256", IX86_BUILTIN_PUNPCKHDQ256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_interleave_highv4di, "__builtin_ia32_punpckhqdq256", IX86_BUILTIN_PUNPCKHQDQ256, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_interleave_lowv32qi, "__builtin_ia32_punpcklbw256", IX86_BUILTIN_PUNPCKLBW256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_interleave_lowv16hi, "__builtin_ia32_punpcklwd256", IX86_BUILTIN_PUNPCKLWD256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_interleave_lowv8si, "__builtin_ia32_punpckldq256", IX86_BUILTIN_PUNPCKLDQ256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_interleave_lowv4di, "__builtin_ia32_punpcklqdq256", IX86_BUILTIN_PUNPCKLQDQ256, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_xorv4di3, "__builtin_ia32_pxor256", IX86_BUILTIN_PXOR256, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_vec_dupv4sf, "__builtin_ia32_vbroadcastss_ps", IX86_BUILTIN_VBROADCASTSS_PS, UNKNOWN, (int) V4SF_FTYPE_V4SF },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_vec_dupv8sf, "__builtin_ia32_vbroadcastss_ps256", IX86_BUILTIN_VBROADCASTSS_PS256, UNKNOWN, (int) V8SF_FTYPE_V4SF },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_vec_dupv4df, "__builtin_ia32_vbroadcastsd_pd256", IX86_BUILTIN_VBROADCASTSD_PD256, UNKNOWN, (int) V4DF_FTYPE_V2DF },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_vbroadcasti128_v4di, "__builtin_ia32_vbroadcastsi256", IX86_BUILTIN_VBROADCASTSI256, UNKNOWN, (int) V4DI_FTYPE_V2DI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_pblenddv4si, "__builtin_ia32_pblendd128", IX86_BUILTIN_PBLENDD128, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_INT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_pblenddv8si, "__builtin_ia32_pblendd256", IX86_BUILTIN_PBLENDD256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_INT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_pbroadcastv32qi, "__builtin_ia32_pbroadcastb256", IX86_BUILTIN_PBROADCASTB256, UNKNOWN, (int) V32QI_FTYPE_V16QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_pbroadcastv16hi, "__builtin_ia32_pbroadcastw256", IX86_BUILTIN_PBROADCASTW256, UNKNOWN, (int) V16HI_FTYPE_V8HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_pbroadcastv8si, "__builtin_ia32_pbroadcastd256", IX86_BUILTIN_PBROADCASTD256, UNKNOWN, (int) V8SI_FTYPE_V4SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_pbroadcastv4di, "__builtin_ia32_pbroadcastq256", IX86_BUILTIN_PBROADCASTQ256, UNKNOWN, (int) V4DI_FTYPE_V2DI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_pbroadcastv16qi, "__builtin_ia32_pbroadcastb128", IX86_BUILTIN_PBROADCASTB128, UNKNOWN, (int) V16QI_FTYPE_V16QI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_pbroadcastv8hi, "__builtin_ia32_pbroadcastw128", IX86_BUILTIN_PBROADCASTW128, UNKNOWN, (int) V8HI_FTYPE_V8HI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_pbroadcastv4si, "__builtin_ia32_pbroadcastd128", IX86_BUILTIN_PBROADCASTD128, UNKNOWN, (int) V4SI_FTYPE_V4SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_pbroadcastv2di, "__builtin_ia32_pbroadcastq128", IX86_BUILTIN_PBROADCASTQ128, UNKNOWN, (int) V2DI_FTYPE_V2DI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_permvarv8si, "__builtin_ia32_permvarsi256", IX86_BUILTIN_VPERMVARSI256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_permvarv8sf, "__builtin_ia32_permvarsf256", IX86_BUILTIN_VPERMVARSF256, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_permv4df, "__builtin_ia32_permdf256", IX86_BUILTIN_VPERMDF256, UNKNOWN, (int) V4DF_FTYPE_V4DF_INT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_permv4di, "__builtin_ia32_permdi256", IX86_BUILTIN_VPERMDI256, UNKNOWN, (int) V4DI_FTYPE_V4DI_INT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_permv2ti, "__builtin_ia32_permti256", IX86_BUILTIN_VPERMTI256, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI_INT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_extracti128, "__builtin_ia32_extract128i256", IX86_BUILTIN_VEXTRACT128I256, UNKNOWN, (int) V2DI_FTYPE_V4DI_INT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_inserti128, "__builtin_ia32_insert128i256", IX86_BUILTIN_VINSERT128I256, UNKNOWN, (int) V4DI_FTYPE_V4DI_V2DI_INT },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_ashlvv4di, "__builtin_ia32_psllv4di", IX86_BUILTIN_PSLLVV4DI, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_ashlvv2di, "__builtin_ia32_psllv2di", IX86_BUILTIN_PSLLVV2DI, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_ashlvv8si, "__builtin_ia32_psllv8si", IX86_BUILTIN_PSLLVV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_ashlvv4si, "__builtin_ia32_psllv4si", IX86_BUILTIN_PSLLVV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_ashrvv8si, "__builtin_ia32_psrav8si", IX86_BUILTIN_PSRAVV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_ashrvv4si, "__builtin_ia32_psrav4si", IX86_BUILTIN_PSRAVV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_lshrvv4di, "__builtin_ia32_psrlv4di", IX86_BUILTIN_PSRLVV4DI, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_lshrvv2di, "__builtin_ia32_psrlv2di", IX86_BUILTIN_PSRLVV2DI, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_lshrvv8si, "__builtin_ia32_psrlv8si", IX86_BUILTIN_PSRLVV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_lshrvv4si, "__builtin_ia32_psrlv4si", IX86_BUILTIN_PSRLVV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI },
-
- { OPTION_MASK_ISA_LZCNT, CODE_FOR_clzhi2_lzcnt, "__builtin_clzs", IX86_BUILTIN_CLZS, UNKNOWN, (int) UINT16_FTYPE_UINT16 },
-
- /* BMI */
- { OPTION_MASK_ISA_BMI, CODE_FOR_bmi_bextr_si, "__builtin_ia32_bextr_u32", IX86_BUILTIN_BEXTR32, UNKNOWN, (int) UINT_FTYPE_UINT_UINT },
- { OPTION_MASK_ISA_BMI, CODE_FOR_bmi_bextr_di, "__builtin_ia32_bextr_u64", IX86_BUILTIN_BEXTR64, UNKNOWN, (int) UINT64_FTYPE_UINT64_UINT64 },
- { OPTION_MASK_ISA_BMI, CODE_FOR_ctzhi2, "__builtin_ctzs", IX86_BUILTIN_CTZS, UNKNOWN, (int) UINT16_FTYPE_UINT16 },
-
- /* TBM */
- { OPTION_MASK_ISA_TBM, CODE_FOR_tbm_bextri_si, "__builtin_ia32_bextri_u32", IX86_BUILTIN_BEXTRI32, UNKNOWN, (int) UINT_FTYPE_UINT_UINT },
- { OPTION_MASK_ISA_TBM, CODE_FOR_tbm_bextri_di, "__builtin_ia32_bextri_u64", IX86_BUILTIN_BEXTRI64, UNKNOWN, (int) UINT64_FTYPE_UINT64_UINT64 },
-
- /* F16C */
- { OPTION_MASK_ISA_F16C, CODE_FOR_vcvtph2ps, "__builtin_ia32_vcvtph2ps", IX86_BUILTIN_CVTPH2PS, UNKNOWN, (int) V4SF_FTYPE_V8HI },
- { OPTION_MASK_ISA_F16C, CODE_FOR_vcvtph2ps256, "__builtin_ia32_vcvtph2ps256", IX86_BUILTIN_CVTPH2PS256, UNKNOWN, (int) V8SF_FTYPE_V8HI },
- { OPTION_MASK_ISA_F16C, CODE_FOR_vcvtps2ph, "__builtin_ia32_vcvtps2ph", IX86_BUILTIN_CVTPS2PH, UNKNOWN, (int) V8HI_FTYPE_V4SF_INT },
- { OPTION_MASK_ISA_F16C, CODE_FOR_vcvtps2ph256, "__builtin_ia32_vcvtps2ph256", IX86_BUILTIN_CVTPS2PH256, UNKNOWN, (int) V8HI_FTYPE_V8SF_INT },
-
- /* BMI2 */
- { OPTION_MASK_ISA_BMI2, CODE_FOR_bmi2_bzhi_si3, "__builtin_ia32_bzhi_si", IX86_BUILTIN_BZHI32, UNKNOWN, (int) UINT_FTYPE_UINT_UINT },
- { OPTION_MASK_ISA_BMI2, CODE_FOR_bmi2_bzhi_di3, "__builtin_ia32_bzhi_di", IX86_BUILTIN_BZHI64, UNKNOWN, (int) UINT64_FTYPE_UINT64_UINT64 },
- { OPTION_MASK_ISA_BMI2, CODE_FOR_bmi2_pdep_si3, "__builtin_ia32_pdep_si", IX86_BUILTIN_PDEP32, UNKNOWN, (int) UINT_FTYPE_UINT_UINT },
- { OPTION_MASK_ISA_BMI2, CODE_FOR_bmi2_pdep_di3, "__builtin_ia32_pdep_di", IX86_BUILTIN_PDEP64, UNKNOWN, (int) UINT64_FTYPE_UINT64_UINT64 },
- { OPTION_MASK_ISA_BMI2, CODE_FOR_bmi2_pext_si3, "__builtin_ia32_pext_si", IX86_BUILTIN_PEXT32, UNKNOWN, (int) UINT_FTYPE_UINT_UINT },
- { OPTION_MASK_ISA_BMI2, CODE_FOR_bmi2_pext_di3, "__builtin_ia32_pext_di", IX86_BUILTIN_PEXT64, UNKNOWN, (int) UINT64_FTYPE_UINT64_UINT64 },
-};
-
-/* FMA4 and XOP. */
-#define MULTI_ARG_4_DF2_DI_I V2DF_FTYPE_V2DF_V2DF_V2DI_INT
-#define MULTI_ARG_4_DF2_DI_I1 V4DF_FTYPE_V4DF_V4DF_V4DI_INT
-#define MULTI_ARG_4_SF2_SI_I V4SF_FTYPE_V4SF_V4SF_V4SI_INT
-#define MULTI_ARG_4_SF2_SI_I1 V8SF_FTYPE_V8SF_V8SF_V8SI_INT
-#define MULTI_ARG_3_SF V4SF_FTYPE_V4SF_V4SF_V4SF
-#define MULTI_ARG_3_DF V2DF_FTYPE_V2DF_V2DF_V2DF
-#define MULTI_ARG_3_SF2 V8SF_FTYPE_V8SF_V8SF_V8SF
-#define MULTI_ARG_3_DF2 V4DF_FTYPE_V4DF_V4DF_V4DF
-#define MULTI_ARG_3_DI V2DI_FTYPE_V2DI_V2DI_V2DI
-#define MULTI_ARG_3_SI V4SI_FTYPE_V4SI_V4SI_V4SI
-#define MULTI_ARG_3_SI_DI V4SI_FTYPE_V4SI_V4SI_V2DI
-#define MULTI_ARG_3_HI V8HI_FTYPE_V8HI_V8HI_V8HI
-#define MULTI_ARG_3_HI_SI V8HI_FTYPE_V8HI_V8HI_V4SI
-#define MULTI_ARG_3_QI V16QI_FTYPE_V16QI_V16QI_V16QI
-#define MULTI_ARG_3_DI2 V4DI_FTYPE_V4DI_V4DI_V4DI
-#define MULTI_ARG_3_SI2 V8SI_FTYPE_V8SI_V8SI_V8SI
-#define MULTI_ARG_3_HI2 V16HI_FTYPE_V16HI_V16HI_V16HI
-#define MULTI_ARG_3_QI2 V32QI_FTYPE_V32QI_V32QI_V32QI
-#define MULTI_ARG_2_SF V4SF_FTYPE_V4SF_V4SF
-#define MULTI_ARG_2_DF V2DF_FTYPE_V2DF_V2DF
-#define MULTI_ARG_2_DI V2DI_FTYPE_V2DI_V2DI
-#define MULTI_ARG_2_SI V4SI_FTYPE_V4SI_V4SI
-#define MULTI_ARG_2_HI V8HI_FTYPE_V8HI_V8HI
-#define MULTI_ARG_2_QI V16QI_FTYPE_V16QI_V16QI
-#define MULTI_ARG_2_DI_IMM V2DI_FTYPE_V2DI_SI
-#define MULTI_ARG_2_SI_IMM V4SI_FTYPE_V4SI_SI
-#define MULTI_ARG_2_HI_IMM V8HI_FTYPE_V8HI_SI
-#define MULTI_ARG_2_QI_IMM V16QI_FTYPE_V16QI_SI
-#define MULTI_ARG_2_DI_CMP V2DI_FTYPE_V2DI_V2DI_CMP
-#define MULTI_ARG_2_SI_CMP V4SI_FTYPE_V4SI_V4SI_CMP
-#define MULTI_ARG_2_HI_CMP V8HI_FTYPE_V8HI_V8HI_CMP
-#define MULTI_ARG_2_QI_CMP V16QI_FTYPE_V16QI_V16QI_CMP
-#define MULTI_ARG_2_SF_TF V4SF_FTYPE_V4SF_V4SF_TF
-#define MULTI_ARG_2_DF_TF V2DF_FTYPE_V2DF_V2DF_TF
-#define MULTI_ARG_2_DI_TF V2DI_FTYPE_V2DI_V2DI_TF
-#define MULTI_ARG_2_SI_TF V4SI_FTYPE_V4SI_V4SI_TF
-#define MULTI_ARG_2_HI_TF V8HI_FTYPE_V8HI_V8HI_TF
-#define MULTI_ARG_2_QI_TF V16QI_FTYPE_V16QI_V16QI_TF
-#define MULTI_ARG_1_SF V4SF_FTYPE_V4SF
-#define MULTI_ARG_1_DF V2DF_FTYPE_V2DF
-#define MULTI_ARG_1_SF2 V8SF_FTYPE_V8SF
-#define MULTI_ARG_1_DF2 V4DF_FTYPE_V4DF
-#define MULTI_ARG_1_DI V2DI_FTYPE_V2DI
-#define MULTI_ARG_1_SI V4SI_FTYPE_V4SI
-#define MULTI_ARG_1_HI V8HI_FTYPE_V8HI
-#define MULTI_ARG_1_QI V16QI_FTYPE_V16QI
-#define MULTI_ARG_1_SI_DI V2DI_FTYPE_V4SI
-#define MULTI_ARG_1_HI_DI V2DI_FTYPE_V8HI
-#define MULTI_ARG_1_HI_SI V4SI_FTYPE_V8HI
-#define MULTI_ARG_1_QI_DI V2DI_FTYPE_V16QI
-#define MULTI_ARG_1_QI_SI V4SI_FTYPE_V16QI
-#define MULTI_ARG_1_QI_HI V8HI_FTYPE_V16QI
-
-static const struct builtin_description bdesc_multi_arg[] =
-{
- { OPTION_MASK_ISA_FMA4, CODE_FOR_fma4i_vmfmadd_v4sf,
- "__builtin_ia32_vfmaddss", IX86_BUILTIN_VFMADDSS,
- UNKNOWN, (int)MULTI_ARG_3_SF },
- { OPTION_MASK_ISA_FMA4, CODE_FOR_fma4i_vmfmadd_v2df,
- "__builtin_ia32_vfmaddsd", IX86_BUILTIN_VFMADDSD,
- UNKNOWN, (int)MULTI_ARG_3_DF },
-
- { OPTION_MASK_ISA_FMA, CODE_FOR_fmai_vmfmadd_v4sf,
- "__builtin_ia32_vfmaddss3", IX86_BUILTIN_VFMADDSS3,
- UNKNOWN, (int)MULTI_ARG_3_SF },
- { OPTION_MASK_ISA_FMA, CODE_FOR_fmai_vmfmadd_v2df,
- "__builtin_ia32_vfmaddsd3", IX86_BUILTIN_VFMADDSD3,
- UNKNOWN, (int)MULTI_ARG_3_DF },
-
- { OPTION_MASK_ISA_FMA | OPTION_MASK_ISA_FMA4, CODE_FOR_fma4i_fmadd_v4sf,
- "__builtin_ia32_vfmaddps", IX86_BUILTIN_VFMADDPS,
- UNKNOWN, (int)MULTI_ARG_3_SF },
- { OPTION_MASK_ISA_FMA | OPTION_MASK_ISA_FMA4, CODE_FOR_fma4i_fmadd_v2df,
- "__builtin_ia32_vfmaddpd", IX86_BUILTIN_VFMADDPD,
- UNKNOWN, (int)MULTI_ARG_3_DF },
- { OPTION_MASK_ISA_FMA | OPTION_MASK_ISA_FMA4, CODE_FOR_fma4i_fmadd_v8sf,
- "__builtin_ia32_vfmaddps256", IX86_BUILTIN_VFMADDPS256,
- UNKNOWN, (int)MULTI_ARG_3_SF2 },
- { OPTION_MASK_ISA_FMA | OPTION_MASK_ISA_FMA4, CODE_FOR_fma4i_fmadd_v4df,
- "__builtin_ia32_vfmaddpd256", IX86_BUILTIN_VFMADDPD256,
- UNKNOWN, (int)MULTI_ARG_3_DF2 },
-
- { OPTION_MASK_ISA_FMA | OPTION_MASK_ISA_FMA4, CODE_FOR_fmaddsub_v4sf,
- "__builtin_ia32_vfmaddsubps", IX86_BUILTIN_VFMADDSUBPS,
- UNKNOWN, (int)MULTI_ARG_3_SF },
- { OPTION_MASK_ISA_FMA | OPTION_MASK_ISA_FMA4, CODE_FOR_fmaddsub_v2df,
- "__builtin_ia32_vfmaddsubpd", IX86_BUILTIN_VFMADDSUBPD,
- UNKNOWN, (int)MULTI_ARG_3_DF },
- { OPTION_MASK_ISA_FMA | OPTION_MASK_ISA_FMA4, CODE_FOR_fmaddsub_v8sf,
- "__builtin_ia32_vfmaddsubps256", IX86_BUILTIN_VFMADDSUBPS256,
- UNKNOWN, (int)MULTI_ARG_3_SF2 },
- { OPTION_MASK_ISA_FMA | OPTION_MASK_ISA_FMA4, CODE_FOR_fmaddsub_v4df,
- "__builtin_ia32_vfmaddsubpd256", IX86_BUILTIN_VFMADDSUBPD256,
- UNKNOWN, (int)MULTI_ARG_3_DF2 },
-
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcmov_v2di, "__builtin_ia32_vpcmov", IX86_BUILTIN_VPCMOV, UNKNOWN, (int)MULTI_ARG_3_DI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcmov_v2di, "__builtin_ia32_vpcmov_v2di", IX86_BUILTIN_VPCMOV_V2DI, UNKNOWN, (int)MULTI_ARG_3_DI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcmov_v4si, "__builtin_ia32_vpcmov_v4si", IX86_BUILTIN_VPCMOV_V4SI, UNKNOWN, (int)MULTI_ARG_3_SI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcmov_v8hi, "__builtin_ia32_vpcmov_v8hi", IX86_BUILTIN_VPCMOV_V8HI, UNKNOWN, (int)MULTI_ARG_3_HI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcmov_v16qi, "__builtin_ia32_vpcmov_v16qi",IX86_BUILTIN_VPCMOV_V16QI,UNKNOWN, (int)MULTI_ARG_3_QI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcmov_v2df, "__builtin_ia32_vpcmov_v2df", IX86_BUILTIN_VPCMOV_V2DF, UNKNOWN, (int)MULTI_ARG_3_DF },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcmov_v4sf, "__builtin_ia32_vpcmov_v4sf", IX86_BUILTIN_VPCMOV_V4SF, UNKNOWN, (int)MULTI_ARG_3_SF },
-
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcmov_v4di256, "__builtin_ia32_vpcmov256", IX86_BUILTIN_VPCMOV256, UNKNOWN, (int)MULTI_ARG_3_DI2 },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcmov_v4di256, "__builtin_ia32_vpcmov_v4di256", IX86_BUILTIN_VPCMOV_V4DI256, UNKNOWN, (int)MULTI_ARG_3_DI2 },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcmov_v8si256, "__builtin_ia32_vpcmov_v8si256", IX86_BUILTIN_VPCMOV_V8SI256, UNKNOWN, (int)MULTI_ARG_3_SI2 },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcmov_v16hi256, "__builtin_ia32_vpcmov_v16hi256", IX86_BUILTIN_VPCMOV_V16HI256, UNKNOWN, (int)MULTI_ARG_3_HI2 },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcmov_v32qi256, "__builtin_ia32_vpcmov_v32qi256", IX86_BUILTIN_VPCMOV_V32QI256, UNKNOWN, (int)MULTI_ARG_3_QI2 },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcmov_v4df256, "__builtin_ia32_vpcmov_v4df256", IX86_BUILTIN_VPCMOV_V4DF256, UNKNOWN, (int)MULTI_ARG_3_DF2 },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcmov_v8sf256, "__builtin_ia32_vpcmov_v8sf256", IX86_BUILTIN_VPCMOV_V8SF256, UNKNOWN, (int)MULTI_ARG_3_SF2 },
-
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pperm, "__builtin_ia32_vpperm", IX86_BUILTIN_VPPERM, UNKNOWN, (int)MULTI_ARG_3_QI },
-
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pmacssww, "__builtin_ia32_vpmacssww", IX86_BUILTIN_VPMACSSWW, UNKNOWN, (int)MULTI_ARG_3_HI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pmacsww, "__builtin_ia32_vpmacsww", IX86_BUILTIN_VPMACSWW, UNKNOWN, (int)MULTI_ARG_3_HI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pmacsswd, "__builtin_ia32_vpmacsswd", IX86_BUILTIN_VPMACSSWD, UNKNOWN, (int)MULTI_ARG_3_HI_SI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pmacswd, "__builtin_ia32_vpmacswd", IX86_BUILTIN_VPMACSWD, UNKNOWN, (int)MULTI_ARG_3_HI_SI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pmacssdd, "__builtin_ia32_vpmacssdd", IX86_BUILTIN_VPMACSSDD, UNKNOWN, (int)MULTI_ARG_3_SI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pmacsdd, "__builtin_ia32_vpmacsdd", IX86_BUILTIN_VPMACSDD, UNKNOWN, (int)MULTI_ARG_3_SI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pmacssdql, "__builtin_ia32_vpmacssdql", IX86_BUILTIN_VPMACSSDQL, UNKNOWN, (int)MULTI_ARG_3_SI_DI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pmacssdqh, "__builtin_ia32_vpmacssdqh", IX86_BUILTIN_VPMACSSDQH, UNKNOWN, (int)MULTI_ARG_3_SI_DI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pmacsdql, "__builtin_ia32_vpmacsdql", IX86_BUILTIN_VPMACSDQL, UNKNOWN, (int)MULTI_ARG_3_SI_DI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pmacsdqh, "__builtin_ia32_vpmacsdqh", IX86_BUILTIN_VPMACSDQH, UNKNOWN, (int)MULTI_ARG_3_SI_DI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pmadcsswd, "__builtin_ia32_vpmadcsswd", IX86_BUILTIN_VPMADCSSWD, UNKNOWN, (int)MULTI_ARG_3_HI_SI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pmadcswd, "__builtin_ia32_vpmadcswd", IX86_BUILTIN_VPMADCSWD, UNKNOWN, (int)MULTI_ARG_3_HI_SI },
-
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_vrotlv2di3, "__builtin_ia32_vprotq", IX86_BUILTIN_VPROTQ, UNKNOWN, (int)MULTI_ARG_2_DI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_vrotlv4si3, "__builtin_ia32_vprotd", IX86_BUILTIN_VPROTD, UNKNOWN, (int)MULTI_ARG_2_SI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_vrotlv8hi3, "__builtin_ia32_vprotw", IX86_BUILTIN_VPROTW, UNKNOWN, (int)MULTI_ARG_2_HI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_vrotlv16qi3, "__builtin_ia32_vprotb", IX86_BUILTIN_VPROTB, UNKNOWN, (int)MULTI_ARG_2_QI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_rotlv2di3, "__builtin_ia32_vprotqi", IX86_BUILTIN_VPROTQ_IMM, UNKNOWN, (int)MULTI_ARG_2_DI_IMM },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_rotlv4si3, "__builtin_ia32_vprotdi", IX86_BUILTIN_VPROTD_IMM, UNKNOWN, (int)MULTI_ARG_2_SI_IMM },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_rotlv8hi3, "__builtin_ia32_vprotwi", IX86_BUILTIN_VPROTW_IMM, UNKNOWN, (int)MULTI_ARG_2_HI_IMM },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_rotlv16qi3, "__builtin_ia32_vprotbi", IX86_BUILTIN_VPROTB_IMM, UNKNOWN, (int)MULTI_ARG_2_QI_IMM },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_shav2di3, "__builtin_ia32_vpshaq", IX86_BUILTIN_VPSHAQ, UNKNOWN, (int)MULTI_ARG_2_DI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_shav4si3, "__builtin_ia32_vpshad", IX86_BUILTIN_VPSHAD, UNKNOWN, (int)MULTI_ARG_2_SI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_shav8hi3, "__builtin_ia32_vpshaw", IX86_BUILTIN_VPSHAW, UNKNOWN, (int)MULTI_ARG_2_HI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_shav16qi3, "__builtin_ia32_vpshab", IX86_BUILTIN_VPSHAB, UNKNOWN, (int)MULTI_ARG_2_QI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_shlv2di3, "__builtin_ia32_vpshlq", IX86_BUILTIN_VPSHLQ, UNKNOWN, (int)MULTI_ARG_2_DI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_shlv4si3, "__builtin_ia32_vpshld", IX86_BUILTIN_VPSHLD, UNKNOWN, (int)MULTI_ARG_2_SI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_shlv8hi3, "__builtin_ia32_vpshlw", IX86_BUILTIN_VPSHLW, UNKNOWN, (int)MULTI_ARG_2_HI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_shlv16qi3, "__builtin_ia32_vpshlb", IX86_BUILTIN_VPSHLB, UNKNOWN, (int)MULTI_ARG_2_QI },
-
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_vmfrczv4sf2, "__builtin_ia32_vfrczss", IX86_BUILTIN_VFRCZSS, UNKNOWN, (int)MULTI_ARG_2_SF },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_vmfrczv2df2, "__builtin_ia32_vfrczsd", IX86_BUILTIN_VFRCZSD, UNKNOWN, (int)MULTI_ARG_2_DF },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_frczv4sf2, "__builtin_ia32_vfrczps", IX86_BUILTIN_VFRCZPS, UNKNOWN, (int)MULTI_ARG_1_SF },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_frczv2df2, "__builtin_ia32_vfrczpd", IX86_BUILTIN_VFRCZPD, UNKNOWN, (int)MULTI_ARG_1_DF },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_frczv8sf2, "__builtin_ia32_vfrczps256", IX86_BUILTIN_VFRCZPS256, UNKNOWN, (int)MULTI_ARG_1_SF2 },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_frczv4df2, "__builtin_ia32_vfrczpd256", IX86_BUILTIN_VFRCZPD256, UNKNOWN, (int)MULTI_ARG_1_DF2 },
-
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_phaddbw, "__builtin_ia32_vphaddbw", IX86_BUILTIN_VPHADDBW, UNKNOWN, (int)MULTI_ARG_1_QI_HI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_phaddbd, "__builtin_ia32_vphaddbd", IX86_BUILTIN_VPHADDBD, UNKNOWN, (int)MULTI_ARG_1_QI_SI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_phaddbq, "__builtin_ia32_vphaddbq", IX86_BUILTIN_VPHADDBQ, UNKNOWN, (int)MULTI_ARG_1_QI_DI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_phaddwd, "__builtin_ia32_vphaddwd", IX86_BUILTIN_VPHADDWD, UNKNOWN, (int)MULTI_ARG_1_HI_SI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_phaddwq, "__builtin_ia32_vphaddwq", IX86_BUILTIN_VPHADDWQ, UNKNOWN, (int)MULTI_ARG_1_HI_DI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_phadddq, "__builtin_ia32_vphadddq", IX86_BUILTIN_VPHADDDQ, UNKNOWN, (int)MULTI_ARG_1_SI_DI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_phaddubw, "__builtin_ia32_vphaddubw", IX86_BUILTIN_VPHADDUBW, UNKNOWN, (int)MULTI_ARG_1_QI_HI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_phaddubd, "__builtin_ia32_vphaddubd", IX86_BUILTIN_VPHADDUBD, UNKNOWN, (int)MULTI_ARG_1_QI_SI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_phaddubq, "__builtin_ia32_vphaddubq", IX86_BUILTIN_VPHADDUBQ, UNKNOWN, (int)MULTI_ARG_1_QI_DI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_phadduwd, "__builtin_ia32_vphadduwd", IX86_BUILTIN_VPHADDUWD, UNKNOWN, (int)MULTI_ARG_1_HI_SI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_phadduwq, "__builtin_ia32_vphadduwq", IX86_BUILTIN_VPHADDUWQ, UNKNOWN, (int)MULTI_ARG_1_HI_DI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_phaddudq, "__builtin_ia32_vphaddudq", IX86_BUILTIN_VPHADDUDQ, UNKNOWN, (int)MULTI_ARG_1_SI_DI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_phsubbw, "__builtin_ia32_vphsubbw", IX86_BUILTIN_VPHSUBBW, UNKNOWN, (int)MULTI_ARG_1_QI_HI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_phsubwd, "__builtin_ia32_vphsubwd", IX86_BUILTIN_VPHSUBWD, UNKNOWN, (int)MULTI_ARG_1_HI_SI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_phsubdq, "__builtin_ia32_vphsubdq", IX86_BUILTIN_VPHSUBDQ, UNKNOWN, (int)MULTI_ARG_1_SI_DI },
-
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv16qi3, "__builtin_ia32_vpcomeqb", IX86_BUILTIN_VPCOMEQB, EQ, (int)MULTI_ARG_2_QI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv16qi3, "__builtin_ia32_vpcomneb", IX86_BUILTIN_VPCOMNEB, NE, (int)MULTI_ARG_2_QI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv16qi3, "__builtin_ia32_vpcomneqb", IX86_BUILTIN_VPCOMNEB, NE, (int)MULTI_ARG_2_QI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv16qi3, "__builtin_ia32_vpcomltb", IX86_BUILTIN_VPCOMLTB, LT, (int)MULTI_ARG_2_QI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv16qi3, "__builtin_ia32_vpcomleb", IX86_BUILTIN_VPCOMLEB, LE, (int)MULTI_ARG_2_QI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv16qi3, "__builtin_ia32_vpcomgtb", IX86_BUILTIN_VPCOMGTB, GT, (int)MULTI_ARG_2_QI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv16qi3, "__builtin_ia32_vpcomgeb", IX86_BUILTIN_VPCOMGEB, GE, (int)MULTI_ARG_2_QI_CMP },
-
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv8hi3, "__builtin_ia32_vpcomeqw", IX86_BUILTIN_VPCOMEQW, EQ, (int)MULTI_ARG_2_HI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv8hi3, "__builtin_ia32_vpcomnew", IX86_BUILTIN_VPCOMNEW, NE, (int)MULTI_ARG_2_HI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv8hi3, "__builtin_ia32_vpcomneqw", IX86_BUILTIN_VPCOMNEW, NE, (int)MULTI_ARG_2_HI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv8hi3, "__builtin_ia32_vpcomltw", IX86_BUILTIN_VPCOMLTW, LT, (int)MULTI_ARG_2_HI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv8hi3, "__builtin_ia32_vpcomlew", IX86_BUILTIN_VPCOMLEW, LE, (int)MULTI_ARG_2_HI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv8hi3, "__builtin_ia32_vpcomgtw", IX86_BUILTIN_VPCOMGTW, GT, (int)MULTI_ARG_2_HI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv8hi3, "__builtin_ia32_vpcomgew", IX86_BUILTIN_VPCOMGEW, GE, (int)MULTI_ARG_2_HI_CMP },
-
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv4si3, "__builtin_ia32_vpcomeqd", IX86_BUILTIN_VPCOMEQD, EQ, (int)MULTI_ARG_2_SI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv4si3, "__builtin_ia32_vpcomned", IX86_BUILTIN_VPCOMNED, NE, (int)MULTI_ARG_2_SI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv4si3, "__builtin_ia32_vpcomneqd", IX86_BUILTIN_VPCOMNED, NE, (int)MULTI_ARG_2_SI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv4si3, "__builtin_ia32_vpcomltd", IX86_BUILTIN_VPCOMLTD, LT, (int)MULTI_ARG_2_SI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv4si3, "__builtin_ia32_vpcomled", IX86_BUILTIN_VPCOMLED, LE, (int)MULTI_ARG_2_SI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv4si3, "__builtin_ia32_vpcomgtd", IX86_BUILTIN_VPCOMGTD, GT, (int)MULTI_ARG_2_SI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv4si3, "__builtin_ia32_vpcomged", IX86_BUILTIN_VPCOMGED, GE, (int)MULTI_ARG_2_SI_CMP },
-
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv2di3, "__builtin_ia32_vpcomeqq", IX86_BUILTIN_VPCOMEQQ, EQ, (int)MULTI_ARG_2_DI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv2di3, "__builtin_ia32_vpcomneq", IX86_BUILTIN_VPCOMNEQ, NE, (int)MULTI_ARG_2_DI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv2di3, "__builtin_ia32_vpcomneqq", IX86_BUILTIN_VPCOMNEQ, NE, (int)MULTI_ARG_2_DI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv2di3, "__builtin_ia32_vpcomltq", IX86_BUILTIN_VPCOMLTQ, LT, (int)MULTI_ARG_2_DI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv2di3, "__builtin_ia32_vpcomleq", IX86_BUILTIN_VPCOMLEQ, LE, (int)MULTI_ARG_2_DI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv2di3, "__builtin_ia32_vpcomgtq", IX86_BUILTIN_VPCOMGTQ, GT, (int)MULTI_ARG_2_DI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmpv2di3, "__builtin_ia32_vpcomgeq", IX86_BUILTIN_VPCOMGEQ, GE, (int)MULTI_ARG_2_DI_CMP },
-
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_uns2v16qi3,"__builtin_ia32_vpcomequb", IX86_BUILTIN_VPCOMEQUB, EQ, (int)MULTI_ARG_2_QI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_uns2v16qi3,"__builtin_ia32_vpcomneub", IX86_BUILTIN_VPCOMNEUB, NE, (int)MULTI_ARG_2_QI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_uns2v16qi3,"__builtin_ia32_vpcomnequb", IX86_BUILTIN_VPCOMNEUB, NE, (int)MULTI_ARG_2_QI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_unsv16qi3, "__builtin_ia32_vpcomltub", IX86_BUILTIN_VPCOMLTUB, LTU, (int)MULTI_ARG_2_QI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_unsv16qi3, "__builtin_ia32_vpcomleub", IX86_BUILTIN_VPCOMLEUB, LEU, (int)MULTI_ARG_2_QI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_unsv16qi3, "__builtin_ia32_vpcomgtub", IX86_BUILTIN_VPCOMGTUB, GTU, (int)MULTI_ARG_2_QI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_unsv16qi3, "__builtin_ia32_vpcomgeub", IX86_BUILTIN_VPCOMGEUB, GEU, (int)MULTI_ARG_2_QI_CMP },
-
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_uns2v8hi3, "__builtin_ia32_vpcomequw", IX86_BUILTIN_VPCOMEQUW, EQ, (int)MULTI_ARG_2_HI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_uns2v8hi3, "__builtin_ia32_vpcomneuw", IX86_BUILTIN_VPCOMNEUW, NE, (int)MULTI_ARG_2_HI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_uns2v8hi3, "__builtin_ia32_vpcomnequw", IX86_BUILTIN_VPCOMNEUW, NE, (int)MULTI_ARG_2_HI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_unsv8hi3, "__builtin_ia32_vpcomltuw", IX86_BUILTIN_VPCOMLTUW, LTU, (int)MULTI_ARG_2_HI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_unsv8hi3, "__builtin_ia32_vpcomleuw", IX86_BUILTIN_VPCOMLEUW, LEU, (int)MULTI_ARG_2_HI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_unsv8hi3, "__builtin_ia32_vpcomgtuw", IX86_BUILTIN_VPCOMGTUW, GTU, (int)MULTI_ARG_2_HI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_unsv8hi3, "__builtin_ia32_vpcomgeuw", IX86_BUILTIN_VPCOMGEUW, GEU, (int)MULTI_ARG_2_HI_CMP },
-
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_uns2v4si3, "__builtin_ia32_vpcomequd", IX86_BUILTIN_VPCOMEQUD, EQ, (int)MULTI_ARG_2_SI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_uns2v4si3, "__builtin_ia32_vpcomneud", IX86_BUILTIN_VPCOMNEUD, NE, (int)MULTI_ARG_2_SI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_uns2v4si3, "__builtin_ia32_vpcomnequd", IX86_BUILTIN_VPCOMNEUD, NE, (int)MULTI_ARG_2_SI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_unsv4si3, "__builtin_ia32_vpcomltud", IX86_BUILTIN_VPCOMLTUD, LTU, (int)MULTI_ARG_2_SI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_unsv4si3, "__builtin_ia32_vpcomleud", IX86_BUILTIN_VPCOMLEUD, LEU, (int)MULTI_ARG_2_SI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_unsv4si3, "__builtin_ia32_vpcomgtud", IX86_BUILTIN_VPCOMGTUD, GTU, (int)MULTI_ARG_2_SI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_unsv4si3, "__builtin_ia32_vpcomgeud", IX86_BUILTIN_VPCOMGEUD, GEU, (int)MULTI_ARG_2_SI_CMP },
-
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_uns2v2di3, "__builtin_ia32_vpcomequq", IX86_BUILTIN_VPCOMEQUQ, EQ, (int)MULTI_ARG_2_DI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_uns2v2di3, "__builtin_ia32_vpcomneuq", IX86_BUILTIN_VPCOMNEUQ, NE, (int)MULTI_ARG_2_DI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_uns2v2di3, "__builtin_ia32_vpcomnequq", IX86_BUILTIN_VPCOMNEUQ, NE, (int)MULTI_ARG_2_DI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_unsv2di3, "__builtin_ia32_vpcomltuq", IX86_BUILTIN_VPCOMLTUQ, LTU, (int)MULTI_ARG_2_DI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_unsv2di3, "__builtin_ia32_vpcomleuq", IX86_BUILTIN_VPCOMLEUQ, LEU, (int)MULTI_ARG_2_DI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_unsv2di3, "__builtin_ia32_vpcomgtuq", IX86_BUILTIN_VPCOMGTUQ, GTU, (int)MULTI_ARG_2_DI_CMP },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_maskcmp_unsv2di3, "__builtin_ia32_vpcomgeuq", IX86_BUILTIN_VPCOMGEUQ, GEU, (int)MULTI_ARG_2_DI_CMP },
-
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcom_tfv16qi3, "__builtin_ia32_vpcomfalseb", IX86_BUILTIN_VPCOMFALSEB, (enum rtx_code) PCOM_FALSE, (int)MULTI_ARG_2_QI_TF },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcom_tfv8hi3, "__builtin_ia32_vpcomfalsew", IX86_BUILTIN_VPCOMFALSEW, (enum rtx_code) PCOM_FALSE, (int)MULTI_ARG_2_HI_TF },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcom_tfv4si3, "__builtin_ia32_vpcomfalsed", IX86_BUILTIN_VPCOMFALSED, (enum rtx_code) PCOM_FALSE, (int)MULTI_ARG_2_SI_TF },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcom_tfv2di3, "__builtin_ia32_vpcomfalseq", IX86_BUILTIN_VPCOMFALSEQ, (enum rtx_code) PCOM_FALSE, (int)MULTI_ARG_2_DI_TF },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcom_tfv16qi3, "__builtin_ia32_vpcomfalseub",IX86_BUILTIN_VPCOMFALSEUB,(enum rtx_code) PCOM_FALSE, (int)MULTI_ARG_2_QI_TF },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcom_tfv8hi3, "__builtin_ia32_vpcomfalseuw",IX86_BUILTIN_VPCOMFALSEUW,(enum rtx_code) PCOM_FALSE, (int)MULTI_ARG_2_HI_TF },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcom_tfv4si3, "__builtin_ia32_vpcomfalseud",IX86_BUILTIN_VPCOMFALSEUD,(enum rtx_code) PCOM_FALSE, (int)MULTI_ARG_2_SI_TF },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcom_tfv2di3, "__builtin_ia32_vpcomfalseuq",IX86_BUILTIN_VPCOMFALSEUQ,(enum rtx_code) PCOM_FALSE, (int)MULTI_ARG_2_DI_TF },
-
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcom_tfv16qi3, "__builtin_ia32_vpcomtrueb", IX86_BUILTIN_VPCOMTRUEB, (enum rtx_code) PCOM_TRUE, (int)MULTI_ARG_2_QI_TF },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcom_tfv8hi3, "__builtin_ia32_vpcomtruew", IX86_BUILTIN_VPCOMTRUEW, (enum rtx_code) PCOM_TRUE, (int)MULTI_ARG_2_HI_TF },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcom_tfv4si3, "__builtin_ia32_vpcomtrued", IX86_BUILTIN_VPCOMTRUED, (enum rtx_code) PCOM_TRUE, (int)MULTI_ARG_2_SI_TF },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcom_tfv2di3, "__builtin_ia32_vpcomtrueq", IX86_BUILTIN_VPCOMTRUEQ, (enum rtx_code) PCOM_TRUE, (int)MULTI_ARG_2_DI_TF },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcom_tfv16qi3, "__builtin_ia32_vpcomtrueub", IX86_BUILTIN_VPCOMTRUEUB, (enum rtx_code) PCOM_TRUE, (int)MULTI_ARG_2_QI_TF },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcom_tfv8hi3, "__builtin_ia32_vpcomtrueuw", IX86_BUILTIN_VPCOMTRUEUW, (enum rtx_code) PCOM_TRUE, (int)MULTI_ARG_2_HI_TF },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcom_tfv4si3, "__builtin_ia32_vpcomtrueud", IX86_BUILTIN_VPCOMTRUEUD, (enum rtx_code) PCOM_TRUE, (int)MULTI_ARG_2_SI_TF },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_pcom_tfv2di3, "__builtin_ia32_vpcomtrueuq", IX86_BUILTIN_VPCOMTRUEUQ, (enum rtx_code) PCOM_TRUE, (int)MULTI_ARG_2_DI_TF },
-
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_vpermil2v2df3, "__builtin_ia32_vpermil2pd", IX86_BUILTIN_VPERMIL2PD, UNKNOWN, (int)MULTI_ARG_4_DF2_DI_I },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_vpermil2v4sf3, "__builtin_ia32_vpermil2ps", IX86_BUILTIN_VPERMIL2PS, UNKNOWN, (int)MULTI_ARG_4_SF2_SI_I },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_vpermil2v4df3, "__builtin_ia32_vpermil2pd256", IX86_BUILTIN_VPERMIL2PD256, UNKNOWN, (int)MULTI_ARG_4_DF2_DI_I1 },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_vpermil2v8sf3, "__builtin_ia32_vpermil2ps256", IX86_BUILTIN_VPERMIL2PS256, UNKNOWN, (int)MULTI_ARG_4_SF2_SI_I1 },
-
-};
-
-/* TM vector builtins. */
-
-/* Reuse the existing x86-specific `struct builtin_description' cause
- we're lazy. Add casts to make them fit. */
-static const struct builtin_description bdesc_tm[] =
-{
- { OPTION_MASK_ISA_MMX, CODE_FOR_nothing, "__builtin__ITM_WM64", (enum ix86_builtins) BUILT_IN_TM_STORE_M64, UNKNOWN, VOID_FTYPE_PV2SI_V2SI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_nothing, "__builtin__ITM_WaRM64", (enum ix86_builtins) BUILT_IN_TM_STORE_WAR_M64, UNKNOWN, VOID_FTYPE_PV2SI_V2SI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_nothing, "__builtin__ITM_WaWM64", (enum ix86_builtins) BUILT_IN_TM_STORE_WAW_M64, UNKNOWN, VOID_FTYPE_PV2SI_V2SI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_nothing, "__builtin__ITM_RM64", (enum ix86_builtins) BUILT_IN_TM_LOAD_M64, UNKNOWN, V2SI_FTYPE_PCV2SI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_nothing, "__builtin__ITM_RaRM64", (enum ix86_builtins) BUILT_IN_TM_LOAD_RAR_M64, UNKNOWN, V2SI_FTYPE_PCV2SI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_nothing, "__builtin__ITM_RaWM64", (enum ix86_builtins) BUILT_IN_TM_LOAD_RAW_M64, UNKNOWN, V2SI_FTYPE_PCV2SI },
- { OPTION_MASK_ISA_MMX, CODE_FOR_nothing, "__builtin__ITM_RfWM64", (enum ix86_builtins) BUILT_IN_TM_LOAD_RFW_M64, UNKNOWN, V2SI_FTYPE_PCV2SI },
-
- { OPTION_MASK_ISA_SSE, CODE_FOR_nothing, "__builtin__ITM_WM128", (enum ix86_builtins) BUILT_IN_TM_STORE_M128, UNKNOWN, VOID_FTYPE_PV4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_nothing, "__builtin__ITM_WaRM128", (enum ix86_builtins) BUILT_IN_TM_STORE_WAR_M128, UNKNOWN, VOID_FTYPE_PV4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_nothing, "__builtin__ITM_WaWM128", (enum ix86_builtins) BUILT_IN_TM_STORE_WAW_M128, UNKNOWN, VOID_FTYPE_PV4SF_V4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_nothing, "__builtin__ITM_RM128", (enum ix86_builtins) BUILT_IN_TM_LOAD_M128, UNKNOWN, V4SF_FTYPE_PCV4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_nothing, "__builtin__ITM_RaRM128", (enum ix86_builtins) BUILT_IN_TM_LOAD_RAR_M128, UNKNOWN, V4SF_FTYPE_PCV4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_nothing, "__builtin__ITM_RaWM128", (enum ix86_builtins) BUILT_IN_TM_LOAD_RAW_M128, UNKNOWN, V4SF_FTYPE_PCV4SF },
- { OPTION_MASK_ISA_SSE, CODE_FOR_nothing, "__builtin__ITM_RfWM128", (enum ix86_builtins) BUILT_IN_TM_LOAD_RFW_M128, UNKNOWN, V4SF_FTYPE_PCV4SF },
-
- { OPTION_MASK_ISA_AVX, CODE_FOR_nothing, "__builtin__ITM_WM256", (enum ix86_builtins) BUILT_IN_TM_STORE_M256, UNKNOWN, VOID_FTYPE_PV8SF_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_nothing, "__builtin__ITM_WaRM256", (enum ix86_builtins) BUILT_IN_TM_STORE_WAR_M256, UNKNOWN, VOID_FTYPE_PV8SF_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_nothing, "__builtin__ITM_WaWM256", (enum ix86_builtins) BUILT_IN_TM_STORE_WAW_M256, UNKNOWN, VOID_FTYPE_PV8SF_V8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_nothing, "__builtin__ITM_RM256", (enum ix86_builtins) BUILT_IN_TM_LOAD_M256, UNKNOWN, V8SF_FTYPE_PCV8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_nothing, "__builtin__ITM_RaRM256", (enum ix86_builtins) BUILT_IN_TM_LOAD_RAR_M256, UNKNOWN, V8SF_FTYPE_PCV8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_nothing, "__builtin__ITM_RaWM256", (enum ix86_builtins) BUILT_IN_TM_LOAD_RAW_M256, UNKNOWN, V8SF_FTYPE_PCV8SF },
- { OPTION_MASK_ISA_AVX, CODE_FOR_nothing, "__builtin__ITM_RfWM256", (enum ix86_builtins) BUILT_IN_TM_LOAD_RFW_M256, UNKNOWN, V8SF_FTYPE_PCV8SF },
-
- { OPTION_MASK_ISA_MMX, CODE_FOR_nothing, "__builtin__ITM_LM64", (enum ix86_builtins) BUILT_IN_TM_LOG_M64, UNKNOWN, VOID_FTYPE_PCVOID },
- { OPTION_MASK_ISA_SSE, CODE_FOR_nothing, "__builtin__ITM_LM128", (enum ix86_builtins) BUILT_IN_TM_LOG_M128, UNKNOWN, VOID_FTYPE_PCVOID },
- { OPTION_MASK_ISA_AVX, CODE_FOR_nothing, "__builtin__ITM_LM256", (enum ix86_builtins) BUILT_IN_TM_LOG_M256, UNKNOWN, VOID_FTYPE_PCVOID },
-};
-
-/* TM callbacks. */
-
-/* Return the builtin decl needed to load a vector of TYPE. */
-
-static tree
-ix86_builtin_tm_load (tree type)
-{
- if (TREE_CODE (type) == VECTOR_TYPE)
- {
- switch (tree_low_cst (TYPE_SIZE (type), 1))
- {
- case 64:
- return builtin_decl_explicit (BUILT_IN_TM_LOAD_M64);
- case 128:
- return builtin_decl_explicit (BUILT_IN_TM_LOAD_M128);
- case 256:
- return builtin_decl_explicit (BUILT_IN_TM_LOAD_M256);
- }
- }
- return NULL_TREE;
-}
-
-/* Return the builtin decl needed to store a vector of TYPE. */
-
-static tree
-ix86_builtin_tm_store (tree type)
-{
- if (TREE_CODE (type) == VECTOR_TYPE)
- {
- switch (tree_low_cst (TYPE_SIZE (type), 1))
- {
- case 64:
- return builtin_decl_explicit (BUILT_IN_TM_STORE_M64);
- case 128:
- return builtin_decl_explicit (BUILT_IN_TM_STORE_M128);
- case 256:
- return builtin_decl_explicit (BUILT_IN_TM_STORE_M256);
- }
- }
- return NULL_TREE;
-}
-
-/* Initialize the transactional memory vector load/store builtins. */
-
-static void
-ix86_init_tm_builtins (void)
-{
- enum ix86_builtin_func_type ftype;
- const struct builtin_description *d;
- size_t i;
- tree decl;
- tree attrs_load, attrs_type_load, attrs_store, attrs_type_store;
- tree attrs_log, attrs_type_log;
-
- if (!flag_tm)
- return;
-
- /* If there are no builtins defined, we must be compiling in a
- language without trans-mem support. */
- if (!builtin_decl_explicit_p (BUILT_IN_TM_LOAD_1))
- return;
-
- /* Use whatever attributes a normal TM load has. */
- decl = builtin_decl_explicit (BUILT_IN_TM_LOAD_1);
- attrs_load = DECL_ATTRIBUTES (decl);
- attrs_type_load = TYPE_ATTRIBUTES (TREE_TYPE (decl));
- /* Use whatever attributes a normal TM store has. */
- decl = builtin_decl_explicit (BUILT_IN_TM_STORE_1);
- attrs_store = DECL_ATTRIBUTES (decl);
- attrs_type_store = TYPE_ATTRIBUTES (TREE_TYPE (decl));
- /* Use whatever attributes a normal TM log has. */
- decl = builtin_decl_explicit (BUILT_IN_TM_LOG);
- attrs_log = DECL_ATTRIBUTES (decl);
- attrs_type_log = TYPE_ATTRIBUTES (TREE_TYPE (decl));
-
- for (i = 0, d = bdesc_tm;
- i < ARRAY_SIZE (bdesc_tm);
- i++, d++)
- {
- if ((d->mask & ix86_isa_flags) != 0
- || (lang_hooks.builtin_function
- == lang_hooks.builtin_function_ext_scope))
- {
- tree type, attrs, attrs_type;
- enum built_in_function code = (enum built_in_function) d->code;
-
- ftype = (enum ix86_builtin_func_type) d->flag;
- type = ix86_get_builtin_func_type (ftype);
-
- if (BUILTIN_TM_LOAD_P (code))
- {
- attrs = attrs_load;
- attrs_type = attrs_type_load;
- }
- else if (BUILTIN_TM_STORE_P (code))
- {
- attrs = attrs_store;
- attrs_type = attrs_type_store;
- }
- else
- {
- attrs = attrs_log;
- attrs_type = attrs_type_log;
- }
- decl = add_builtin_function (d->name, type, code, BUILT_IN_NORMAL,
- /* The builtin without the prefix for
- calling it directly. */
- d->name + strlen ("__builtin_"),
- attrs);
- /* add_builtin_function() will set the DECL_ATTRIBUTES, now
- set the TYPE_ATTRIBUTES. */
- decl_attributes (&TREE_TYPE (decl), attrs_type, ATTR_FLAG_BUILT_IN);
-
- set_builtin_decl (code, decl, false);
- }
- }
-}
-
-/* Set up all the MMX/SSE builtins, even builtins for instructions that are not
- in the current target ISA to allow the user to compile particular modules
- with different target specific options that differ from the command line
- options. */
-static void
-ix86_init_mmx_sse_builtins (void)
-{
- const struct builtin_description * d;
- enum ix86_builtin_func_type ftype;
- size_t i;
-
- /* Add all special builtins with variable number of operands. */
- for (i = 0, d = bdesc_special_args;
- i < ARRAY_SIZE (bdesc_special_args);
- i++, d++)
- {
- if (d->name == 0)
- continue;
-
- ftype = (enum ix86_builtin_func_type) d->flag;
- def_builtin (d->mask, d->name, ftype, d->code);
- }
-
- /* Add all builtins with variable number of operands. */
- for (i = 0, d = bdesc_args;
- i < ARRAY_SIZE (bdesc_args);
- i++, d++)
- {
- if (d->name == 0)
- continue;
-
- ftype = (enum ix86_builtin_func_type) d->flag;
- def_builtin_const (d->mask, d->name, ftype, d->code);
- }
-
- /* pcmpestr[im] insns. */
- for (i = 0, d = bdesc_pcmpestr;
- i < ARRAY_SIZE (bdesc_pcmpestr);
- i++, d++)
- {
- if (d->code == IX86_BUILTIN_PCMPESTRM128)
- ftype = V16QI_FTYPE_V16QI_INT_V16QI_INT_INT;
- else
- ftype = INT_FTYPE_V16QI_INT_V16QI_INT_INT;
- def_builtin_const (d->mask, d->name, ftype, d->code);
- }
-
- /* pcmpistr[im] insns. */
- for (i = 0, d = bdesc_pcmpistr;
- i < ARRAY_SIZE (bdesc_pcmpistr);
- i++, d++)
- {
- if (d->code == IX86_BUILTIN_PCMPISTRM128)
- ftype = V16QI_FTYPE_V16QI_V16QI_INT;
- else
- ftype = INT_FTYPE_V16QI_V16QI_INT;
- def_builtin_const (d->mask, d->name, ftype, d->code);
- }
-
- /* comi/ucomi insns. */
- for (i = 0, d = bdesc_comi; i < ARRAY_SIZE (bdesc_comi); i++, d++)
- {
- if (d->mask == OPTION_MASK_ISA_SSE2)
- ftype = INT_FTYPE_V2DF_V2DF;
- else
- ftype = INT_FTYPE_V4SF_V4SF;
- def_builtin_const (d->mask, d->name, ftype, d->code);
- }
-
- /* SSE */
- def_builtin (OPTION_MASK_ISA_SSE, "__builtin_ia32_ldmxcsr",
- VOID_FTYPE_UNSIGNED, IX86_BUILTIN_LDMXCSR);
- def_builtin (OPTION_MASK_ISA_SSE, "__builtin_ia32_stmxcsr",
- UNSIGNED_FTYPE_VOID, IX86_BUILTIN_STMXCSR);
-
- /* SSE or 3DNow!A */
- def_builtin (OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A,
- "__builtin_ia32_maskmovq", VOID_FTYPE_V8QI_V8QI_PCHAR,
- IX86_BUILTIN_MASKMOVQ);
-
- /* SSE2 */
- def_builtin (OPTION_MASK_ISA_SSE2, "__builtin_ia32_maskmovdqu",
- VOID_FTYPE_V16QI_V16QI_PCHAR, IX86_BUILTIN_MASKMOVDQU);
-
- def_builtin (OPTION_MASK_ISA_SSE2, "__builtin_ia32_clflush",
- VOID_FTYPE_PCVOID, IX86_BUILTIN_CLFLUSH);
- x86_mfence = def_builtin (OPTION_MASK_ISA_SSE2, "__builtin_ia32_mfence",
- VOID_FTYPE_VOID, IX86_BUILTIN_MFENCE);
-
- /* SSE3. */
- def_builtin (OPTION_MASK_ISA_SSE3, "__builtin_ia32_monitor",
- VOID_FTYPE_PCVOID_UNSIGNED_UNSIGNED, IX86_BUILTIN_MONITOR);
- def_builtin (OPTION_MASK_ISA_SSE3, "__builtin_ia32_mwait",
- VOID_FTYPE_UNSIGNED_UNSIGNED, IX86_BUILTIN_MWAIT);
-
- /* AES */
- def_builtin_const (OPTION_MASK_ISA_AES, "__builtin_ia32_aesenc128",
- V2DI_FTYPE_V2DI_V2DI, IX86_BUILTIN_AESENC128);
- def_builtin_const (OPTION_MASK_ISA_AES, "__builtin_ia32_aesenclast128",
- V2DI_FTYPE_V2DI_V2DI, IX86_BUILTIN_AESENCLAST128);
- def_builtin_const (OPTION_MASK_ISA_AES, "__builtin_ia32_aesdec128",
- V2DI_FTYPE_V2DI_V2DI, IX86_BUILTIN_AESDEC128);
- def_builtin_const (OPTION_MASK_ISA_AES, "__builtin_ia32_aesdeclast128",
- V2DI_FTYPE_V2DI_V2DI, IX86_BUILTIN_AESDECLAST128);
- def_builtin_const (OPTION_MASK_ISA_AES, "__builtin_ia32_aesimc128",
- V2DI_FTYPE_V2DI, IX86_BUILTIN_AESIMC128);
- def_builtin_const (OPTION_MASK_ISA_AES, "__builtin_ia32_aeskeygenassist128",
- V2DI_FTYPE_V2DI_INT, IX86_BUILTIN_AESKEYGENASSIST128);
-
- /* PCLMUL */
- def_builtin_const (OPTION_MASK_ISA_PCLMUL, "__builtin_ia32_pclmulqdq128",
- V2DI_FTYPE_V2DI_V2DI_INT, IX86_BUILTIN_PCLMULQDQ128);
-
- /* RDRND */
- def_builtin (OPTION_MASK_ISA_RDRND, "__builtin_ia32_rdrand16_step",
- INT_FTYPE_PUSHORT, IX86_BUILTIN_RDRAND16_STEP);
- def_builtin (OPTION_MASK_ISA_RDRND, "__builtin_ia32_rdrand32_step",
- INT_FTYPE_PUNSIGNED, IX86_BUILTIN_RDRAND32_STEP);
- def_builtin (OPTION_MASK_ISA_RDRND | OPTION_MASK_ISA_64BIT,
- "__builtin_ia32_rdrand64_step", INT_FTYPE_PULONGLONG,
- IX86_BUILTIN_RDRAND64_STEP);
-
- /* AVX2 */
- def_builtin (OPTION_MASK_ISA_AVX2, "__builtin_ia32_gathersiv2df",
- V2DF_FTYPE_V2DF_PCDOUBLE_V4SI_V2DF_INT,
- IX86_BUILTIN_GATHERSIV2DF);
-
- def_builtin (OPTION_MASK_ISA_AVX2, "__builtin_ia32_gathersiv4df",
- V4DF_FTYPE_V4DF_PCDOUBLE_V4SI_V4DF_INT,
- IX86_BUILTIN_GATHERSIV4DF);
-
- def_builtin (OPTION_MASK_ISA_AVX2, "__builtin_ia32_gatherdiv2df",
- V2DF_FTYPE_V2DF_PCDOUBLE_V2DI_V2DF_INT,
- IX86_BUILTIN_GATHERDIV2DF);
-
- def_builtin (OPTION_MASK_ISA_AVX2, "__builtin_ia32_gatherdiv4df",
- V4DF_FTYPE_V4DF_PCDOUBLE_V4DI_V4DF_INT,
- IX86_BUILTIN_GATHERDIV4DF);
-
- def_builtin (OPTION_MASK_ISA_AVX2, "__builtin_ia32_gathersiv4sf",
- V4SF_FTYPE_V4SF_PCFLOAT_V4SI_V4SF_INT,
- IX86_BUILTIN_GATHERSIV4SF);
-
- def_builtin (OPTION_MASK_ISA_AVX2, "__builtin_ia32_gathersiv8sf",
- V8SF_FTYPE_V8SF_PCFLOAT_V8SI_V8SF_INT,
- IX86_BUILTIN_GATHERSIV8SF);
-
- def_builtin (OPTION_MASK_ISA_AVX2, "__builtin_ia32_gatherdiv4sf",
- V4SF_FTYPE_V4SF_PCFLOAT_V2DI_V4SF_INT,
- IX86_BUILTIN_GATHERDIV4SF);
-
- def_builtin (OPTION_MASK_ISA_AVX2, "__builtin_ia32_gatherdiv4sf256",
- V4SF_FTYPE_V4SF_PCFLOAT_V4DI_V4SF_INT,
- IX86_BUILTIN_GATHERDIV8SF);
-
- def_builtin (OPTION_MASK_ISA_AVX2, "__builtin_ia32_gathersiv2di",
- V2DI_FTYPE_V2DI_PCINT64_V4SI_V2DI_INT,
- IX86_BUILTIN_GATHERSIV2DI);
-
- def_builtin (OPTION_MASK_ISA_AVX2, "__builtin_ia32_gathersiv4di",
- V4DI_FTYPE_V4DI_PCINT64_V4SI_V4DI_INT,
- IX86_BUILTIN_GATHERSIV4DI);
-
- def_builtin (OPTION_MASK_ISA_AVX2, "__builtin_ia32_gatherdiv2di",
- V2DI_FTYPE_V2DI_PCINT64_V2DI_V2DI_INT,
- IX86_BUILTIN_GATHERDIV2DI);
-
- def_builtin (OPTION_MASK_ISA_AVX2, "__builtin_ia32_gatherdiv4di",
- V4DI_FTYPE_V4DI_PCINT64_V4DI_V4DI_INT,
- IX86_BUILTIN_GATHERDIV4DI);
-
- def_builtin (OPTION_MASK_ISA_AVX2, "__builtin_ia32_gathersiv4si",
- V4SI_FTYPE_V4SI_PCINT_V4SI_V4SI_INT,
- IX86_BUILTIN_GATHERSIV4SI);
-
- def_builtin (OPTION_MASK_ISA_AVX2, "__builtin_ia32_gathersiv8si",
- V8SI_FTYPE_V8SI_PCINT_V8SI_V8SI_INT,
- IX86_BUILTIN_GATHERSIV8SI);
-
- def_builtin (OPTION_MASK_ISA_AVX2, "__builtin_ia32_gatherdiv4si",
- V4SI_FTYPE_V4SI_PCINT_V2DI_V4SI_INT,
- IX86_BUILTIN_GATHERDIV4SI);
-
- def_builtin (OPTION_MASK_ISA_AVX2, "__builtin_ia32_gatherdiv4si256",
- V4SI_FTYPE_V4SI_PCINT_V4DI_V4SI_INT,
- IX86_BUILTIN_GATHERDIV8SI);
-
- def_builtin (OPTION_MASK_ISA_AVX2, "__builtin_ia32_gatheraltsiv4df ",
- V4DF_FTYPE_V4DF_PCDOUBLE_V8SI_V4DF_INT,
- IX86_BUILTIN_GATHERALTSIV4DF);
-
- def_builtin (OPTION_MASK_ISA_AVX2, "__builtin_ia32_gatheraltdiv4sf256 ",
- V8SF_FTYPE_V8SF_PCFLOAT_V4DI_V8SF_INT,
- IX86_BUILTIN_GATHERALTDIV8SF);
-
- def_builtin (OPTION_MASK_ISA_AVX2, "__builtin_ia32_gatheraltsiv4di ",
- V4DI_FTYPE_V4DI_PCINT64_V8SI_V4DI_INT,
- IX86_BUILTIN_GATHERALTSIV4DI);
-
- def_builtin (OPTION_MASK_ISA_AVX2, "__builtin_ia32_gatheraltdiv4si256 ",
- V8SI_FTYPE_V8SI_PCINT_V4DI_V8SI_INT,
- IX86_BUILTIN_GATHERALTDIV8SI);
-
- /* RTM. */
- def_builtin (OPTION_MASK_ISA_RTM, "__builtin_ia32_xabort",
- VOID_FTYPE_UNSIGNED, IX86_BUILTIN_XABORT);
-
- /* MMX access to the vec_init patterns. */
- def_builtin_const (OPTION_MASK_ISA_MMX, "__builtin_ia32_vec_init_v2si",
- V2SI_FTYPE_INT_INT, IX86_BUILTIN_VEC_INIT_V2SI);
-
- def_builtin_const (OPTION_MASK_ISA_MMX, "__builtin_ia32_vec_init_v4hi",
- V4HI_FTYPE_HI_HI_HI_HI,
- IX86_BUILTIN_VEC_INIT_V4HI);
-
- def_builtin_const (OPTION_MASK_ISA_MMX, "__builtin_ia32_vec_init_v8qi",
- V8QI_FTYPE_QI_QI_QI_QI_QI_QI_QI_QI,
- IX86_BUILTIN_VEC_INIT_V8QI);
-
- /* Access to the vec_extract patterns. */
- def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_ia32_vec_ext_v2df",
- DOUBLE_FTYPE_V2DF_INT, IX86_BUILTIN_VEC_EXT_V2DF);
- def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_ia32_vec_ext_v2di",
- DI_FTYPE_V2DI_INT, IX86_BUILTIN_VEC_EXT_V2DI);
- def_builtin_const (OPTION_MASK_ISA_SSE, "__builtin_ia32_vec_ext_v4sf",
- FLOAT_FTYPE_V4SF_INT, IX86_BUILTIN_VEC_EXT_V4SF);
- def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_ia32_vec_ext_v4si",
- SI_FTYPE_V4SI_INT, IX86_BUILTIN_VEC_EXT_V4SI);
- def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_ia32_vec_ext_v8hi",
- HI_FTYPE_V8HI_INT, IX86_BUILTIN_VEC_EXT_V8HI);
-
- def_builtin_const (OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A,
- "__builtin_ia32_vec_ext_v4hi",
- HI_FTYPE_V4HI_INT, IX86_BUILTIN_VEC_EXT_V4HI);
-
- def_builtin_const (OPTION_MASK_ISA_MMX, "__builtin_ia32_vec_ext_v2si",
- SI_FTYPE_V2SI_INT, IX86_BUILTIN_VEC_EXT_V2SI);
-
- def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_ia32_vec_ext_v16qi",
- QI_FTYPE_V16QI_INT, IX86_BUILTIN_VEC_EXT_V16QI);
-
- /* Access to the vec_set patterns. */
- def_builtin_const (OPTION_MASK_ISA_SSE4_1 | OPTION_MASK_ISA_64BIT,
- "__builtin_ia32_vec_set_v2di",
- V2DI_FTYPE_V2DI_DI_INT, IX86_BUILTIN_VEC_SET_V2DI);
-
- def_builtin_const (OPTION_MASK_ISA_SSE4_1, "__builtin_ia32_vec_set_v4sf",
- V4SF_FTYPE_V4SF_FLOAT_INT, IX86_BUILTIN_VEC_SET_V4SF);
-
- def_builtin_const (OPTION_MASK_ISA_SSE4_1, "__builtin_ia32_vec_set_v4si",
- V4SI_FTYPE_V4SI_SI_INT, IX86_BUILTIN_VEC_SET_V4SI);
-
- def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_ia32_vec_set_v8hi",
- V8HI_FTYPE_V8HI_HI_INT, IX86_BUILTIN_VEC_SET_V8HI);
-
- def_builtin_const (OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A,
- "__builtin_ia32_vec_set_v4hi",
- V4HI_FTYPE_V4HI_HI_INT, IX86_BUILTIN_VEC_SET_V4HI);
-
- def_builtin_const (OPTION_MASK_ISA_SSE4_1, "__builtin_ia32_vec_set_v16qi",
- V16QI_FTYPE_V16QI_QI_INT, IX86_BUILTIN_VEC_SET_V16QI);
-
- /* RDSEED */
- def_builtin (OPTION_MASK_ISA_RDSEED, "__builtin_ia32_rdseed_hi_step",
- INT_FTYPE_PUSHORT, IX86_BUILTIN_RDSEED16_STEP);
- def_builtin (OPTION_MASK_ISA_RDSEED, "__builtin_ia32_rdseed_si_step",
- INT_FTYPE_PUNSIGNED, IX86_BUILTIN_RDSEED32_STEP);
- def_builtin (OPTION_MASK_ISA_RDSEED | OPTION_MASK_ISA_64BIT,
- "__builtin_ia32_rdseed_di_step",
- INT_FTYPE_PULONGLONG, IX86_BUILTIN_RDSEED64_STEP);
-
- /* ADCX */
- def_builtin (0, "__builtin_ia32_addcarryx_u32",
- UCHAR_FTYPE_UCHAR_UINT_UINT_PUNSIGNED, IX86_BUILTIN_ADDCARRYX32);
- def_builtin (OPTION_MASK_ISA_64BIT,
- "__builtin_ia32_addcarryx_u64",
- UCHAR_FTYPE_UCHAR_ULONGLONG_ULONGLONG_PULONGLONG,
- IX86_BUILTIN_ADDCARRYX64);
-
- /* Add FMA4 multi-arg argument instructions */
- for (i = 0, d = bdesc_multi_arg; i < ARRAY_SIZE (bdesc_multi_arg); i++, d++)
- {
- if (d->name == 0)
- continue;
-
- ftype = (enum ix86_builtin_func_type) d->flag;
- def_builtin_const (d->mask, d->name, ftype, d->code);
- }
-}
-
-/* This adds a condition to the basic_block NEW_BB in function FUNCTION_DECL
- to return a pointer to VERSION_DECL if the outcome of the expression
- formed by PREDICATE_CHAIN is true. This function will be called during
- version dispatch to decide which function version to execute. It returns
- the basic block at the end, to which more conditions can be added. */
-
-static basic_block
-add_condition_to_bb (tree function_decl, tree version_decl,
- tree predicate_chain, basic_block new_bb)
-{
- gimple return_stmt;
- tree convert_expr, result_var;
- gimple convert_stmt;
- gimple call_cond_stmt;
- gimple if_else_stmt;
-
- basic_block bb1, bb2, bb3;
- edge e12, e23;
-
- tree cond_var, and_expr_var = NULL_TREE;
- gimple_seq gseq;
-
- tree predicate_decl, predicate_arg;
-
- push_cfun (DECL_STRUCT_FUNCTION (function_decl));
-
- gcc_assert (new_bb != NULL);
- gseq = bb_seq (new_bb);
-
-
- convert_expr = build1 (CONVERT_EXPR, ptr_type_node,
- build_fold_addr_expr (version_decl));
- result_var = create_tmp_var (ptr_type_node, NULL);
- convert_stmt = gimple_build_assign (result_var, convert_expr);
- return_stmt = gimple_build_return (result_var);
-
- if (predicate_chain == NULL_TREE)
- {
- gimple_seq_add_stmt (&gseq, convert_stmt);
- gimple_seq_add_stmt (&gseq, return_stmt);
- set_bb_seq (new_bb, gseq);
- gimple_set_bb (convert_stmt, new_bb);
- gimple_set_bb (return_stmt, new_bb);
- pop_cfun ();
- return new_bb;
- }
-
- while (predicate_chain != NULL)
- {
- cond_var = create_tmp_var (integer_type_node, NULL);
- predicate_decl = TREE_PURPOSE (predicate_chain);
- predicate_arg = TREE_VALUE (predicate_chain);
- call_cond_stmt = gimple_build_call (predicate_decl, 1, predicate_arg);
- gimple_call_set_lhs (call_cond_stmt, cond_var);
-
- gimple_set_block (call_cond_stmt, DECL_INITIAL (function_decl));
- gimple_set_bb (call_cond_stmt, new_bb);
- gimple_seq_add_stmt (&gseq, call_cond_stmt);
-
- predicate_chain = TREE_CHAIN (predicate_chain);
-
- if (and_expr_var == NULL)
- and_expr_var = cond_var;
- else
- {
- gimple assign_stmt;
- /* Use MIN_EXPR to check if any integer is zero?.
- and_expr_var = min_expr <cond_var, and_expr_var> */
- assign_stmt = gimple_build_assign (and_expr_var,
- build2 (MIN_EXPR, integer_type_node,
- cond_var, and_expr_var));
-
- gimple_set_block (assign_stmt, DECL_INITIAL (function_decl));
- gimple_set_bb (assign_stmt, new_bb);
- gimple_seq_add_stmt (&gseq, assign_stmt);
- }
- }
-
- if_else_stmt = gimple_build_cond (GT_EXPR, and_expr_var,
- integer_zero_node,
- NULL_TREE, NULL_TREE);
- gimple_set_block (if_else_stmt, DECL_INITIAL (function_decl));
- gimple_set_bb (if_else_stmt, new_bb);
- gimple_seq_add_stmt (&gseq, if_else_stmt);
-
- gimple_seq_add_stmt (&gseq, convert_stmt);
- gimple_seq_add_stmt (&gseq, return_stmt);
- set_bb_seq (new_bb, gseq);
-
- bb1 = new_bb;
- e12 = split_block (bb1, if_else_stmt);
- bb2 = e12->dest;
- e12->flags &= ~EDGE_FALLTHRU;
- e12->flags |= EDGE_TRUE_VALUE;
-
- e23 = split_block (bb2, return_stmt);
-
- gimple_set_bb (convert_stmt, bb2);
- gimple_set_bb (return_stmt, bb2);
-
- bb3 = e23->dest;
- make_edge (bb1, bb3, EDGE_FALSE_VALUE);
-
- remove_edge (e23);
- make_edge (bb2, EXIT_BLOCK_PTR, 0);
-
- pop_cfun ();
-
- return bb3;
-}
-
-/* This parses the attribute arguments to target in DECL and determines
- the right builtin to use to match the platform specification.
- It returns the priority value for this version decl. If PREDICATE_LIST
- is not NULL, it stores the list of cpu features that need to be checked
- before dispatching this function. */
-
-static unsigned int
-get_builtin_code_for_version (tree decl, tree *predicate_list)
-{
- tree attrs;
- struct cl_target_option cur_target;
- tree target_node;
- struct cl_target_option *new_target;
- const char *arg_str = NULL;
- const char *attrs_str = NULL;
- char *tok_str = NULL;
- char *token;
-
- /* Priority of i386 features, greater value is higher priority. This is
- used to decide the order in which function dispatch must happen. For
- instance, a version specialized for SSE4.2 should be checked for dispatch
- before a version for SSE3, as SSE4.2 implies SSE3. */
- enum feature_priority
- {
- P_ZERO = 0,
- P_MMX,
- P_SSE,
- P_SSE2,
- P_SSE3,
- P_SSSE3,
- P_PROC_SSSE3,
- P_SSE4_a,
- P_PROC_SSE4_a,
- P_SSE4_1,
- P_SSE4_2,
- P_PROC_SSE4_2,
- P_POPCNT,
- P_AVX,
- P_AVX2,
- P_FMA,
- P_PROC_FMA
- };
-
- enum feature_priority priority = P_ZERO;
-
- /* These are the target attribute strings for which a dispatcher is
- available, from fold_builtin_cpu. */
-
- static struct _feature_list
- {
- const char *const name;
- const enum feature_priority priority;
- }
- const feature_list[] =
- {
- {"mmx", P_MMX},
- {"sse", P_SSE},
- {"sse2", P_SSE2},
- {"sse3", P_SSE3},
- {"ssse3", P_SSSE3},
- {"sse4.1", P_SSE4_1},
- {"sse4.2", P_SSE4_2},
- {"popcnt", P_POPCNT},
- {"avx", P_AVX},
- {"avx2", P_AVX2}
- };
-
-
- static unsigned int NUM_FEATURES
- = sizeof (feature_list) / sizeof (struct _feature_list);
-
- unsigned int i;
-
- tree predicate_chain = NULL_TREE;
- tree predicate_decl, predicate_arg;
-
- attrs = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
- gcc_assert (attrs != NULL);
-
- attrs = TREE_VALUE (TREE_VALUE (attrs));
-
- gcc_assert (TREE_CODE (attrs) == STRING_CST);
- attrs_str = TREE_STRING_POINTER (attrs);
-
- /* Return priority zero for default function. */
- if (strcmp (attrs_str, "default") == 0)
- return 0;
-
- /* Handle arch= if specified. For priority, set it to be 1 more than
- the best instruction set the processor can handle. For instance, if
- there is a version for atom and a version for ssse3 (the highest ISA
- priority for atom), the atom version must be checked for dispatch
- before the ssse3 version. */
- if (strstr (attrs_str, "arch=") != NULL)
- {
- cl_target_option_save (&cur_target, &global_options);
- target_node = ix86_valid_target_attribute_tree (attrs);
-
- gcc_assert (target_node);
- new_target = TREE_TARGET_OPTION (target_node);
- gcc_assert (new_target);
-
- if (new_target->arch_specified && new_target->arch > 0)
- {
- switch (new_target->arch)
- {
- case PROCESSOR_CORE2:
- arg_str = "core2";
- priority = P_PROC_SSSE3;
- break;
- case PROCESSOR_COREI7:
- arg_str = "corei7";
- priority = P_PROC_SSE4_2;
- break;
- case PROCESSOR_ATOM:
- arg_str = "atom";
- priority = P_PROC_SSSE3;
- break;
- case PROCESSOR_AMDFAM10:
- arg_str = "amdfam10h";
- priority = P_PROC_SSE4_a;
- break;
- case PROCESSOR_BDVER1:
- arg_str = "bdver1";
- priority = P_PROC_FMA;
- break;
- case PROCESSOR_BDVER2:
- arg_str = "bdver2";
- priority = P_PROC_FMA;
- break;
- }
- }
-
- cl_target_option_restore (&global_options, &cur_target);
-
- if (predicate_list && arg_str == NULL)
- {
- error_at (DECL_SOURCE_LOCATION (decl),
- "No dispatcher found for the versioning attributes");
- return 0;
- }
-
- if (predicate_list)
- {
- predicate_decl = ix86_builtins [(int) IX86_BUILTIN_CPU_IS];
- /* For a C string literal the length includes the trailing NULL. */
- predicate_arg = build_string_literal (strlen (arg_str) + 1, arg_str);
- predicate_chain = tree_cons (predicate_decl, predicate_arg,
- predicate_chain);
- }
- }
-
- /* Process feature name. */
- tok_str = (char *) xmalloc (strlen (attrs_str) + 1);
- strcpy (tok_str, attrs_str);
- token = strtok (tok_str, ",");
- predicate_decl = ix86_builtins [(int) IX86_BUILTIN_CPU_SUPPORTS];
-
- while (token != NULL)
- {
- /* Do not process "arch=" */
- if (strncmp (token, "arch=", 5) == 0)
- {
- token = strtok (NULL, ",");
- continue;
- }
- for (i = 0; i < NUM_FEATURES; ++i)
- {
- if (strcmp (token, feature_list[i].name) == 0)
- {
- if (predicate_list)
- {
- predicate_arg = build_string_literal (
- strlen (feature_list[i].name) + 1,
- feature_list[i].name);
- predicate_chain = tree_cons (predicate_decl, predicate_arg,
- predicate_chain);
- }
- /* Find the maximum priority feature. */
- if (feature_list[i].priority > priority)
- priority = feature_list[i].priority;
-
- break;
- }
- }
- if (predicate_list && i == NUM_FEATURES)
- {
- error_at (DECL_SOURCE_LOCATION (decl),
- "No dispatcher found for %s", token);
- return 0;
- }
- token = strtok (NULL, ",");
- }
- free (tok_str);
-
- if (predicate_list && predicate_chain == NULL_TREE)
- {
- error_at (DECL_SOURCE_LOCATION (decl),
- "No dispatcher found for the versioning attributes : %s",
- attrs_str);
- return 0;
- }
- else if (predicate_list)
- {
- predicate_chain = nreverse (predicate_chain);
- *predicate_list = predicate_chain;
- }
-
- return priority;
-}
-
-/* This compares the priority of target features in function DECL1
- and DECL2. It returns positive value if DECL1 is higher priority,
- negative value if DECL2 is higher priority and 0 if they are the
- same. */
-
-static int
-ix86_compare_version_priority (tree decl1, tree decl2)
-{
- unsigned int priority1 = get_builtin_code_for_version (decl1, NULL);
- unsigned int priority2 = get_builtin_code_for_version (decl2, NULL);
-
- return (int)priority1 - (int)priority2;
-}
-
-/* V1 and V2 point to function versions with different priorities
- based on the target ISA. This function compares their priorities. */
-
-static int
-feature_compare (const void *v1, const void *v2)
-{
- typedef struct _function_version_info
- {
- tree version_decl;
- tree predicate_chain;
- unsigned int dispatch_priority;
- } function_version_info;
-
- const function_version_info c1 = *(const function_version_info *)v1;
- const function_version_info c2 = *(const function_version_info *)v2;
- return (c2.dispatch_priority - c1.dispatch_priority);
-}
-
-/* This function generates the dispatch function for
- multi-versioned functions. DISPATCH_DECL is the function which will
- contain the dispatch logic. FNDECLS are the function choices for
- dispatch, and is a tree chain. EMPTY_BB is the basic block pointer
- in DISPATCH_DECL in which the dispatch code is generated. */
-
-static int
-dispatch_function_versions (tree dispatch_decl,
- void *fndecls_p,
- basic_block *empty_bb)
-{
- tree default_decl;
- gimple ifunc_cpu_init_stmt;
- gimple_seq gseq;
- int ix;
- tree ele;
- vec<tree> *fndecls;
- unsigned int num_versions = 0;
- unsigned int actual_versions = 0;
- unsigned int i;
-
- struct _function_version_info
- {
- tree version_decl;
- tree predicate_chain;
- unsigned int dispatch_priority;
- }*function_version_info;
-
- gcc_assert (dispatch_decl != NULL
- && fndecls_p != NULL
- && empty_bb != NULL);
-
- /*fndecls_p is actually a vector. */
- fndecls = static_cast<vec<tree> *> (fndecls_p);
-
- /* At least one more version other than the default. */
- num_versions = fndecls->length ();
- gcc_assert (num_versions >= 2);
-
- function_version_info = (struct _function_version_info *)
- XNEWVEC (struct _function_version_info, (num_versions - 1));
-
- /* The first version in the vector is the default decl. */
- default_decl = (*fndecls)[0];
-
- push_cfun (DECL_STRUCT_FUNCTION (dispatch_decl));
-
- gseq = bb_seq (*empty_bb);
- /* Function version dispatch is via IFUNC. IFUNC resolvers fire before
- constructors, so explicity call __builtin_cpu_init here. */
- ifunc_cpu_init_stmt = gimple_build_call_vec (
- ix86_builtins [(int) IX86_BUILTIN_CPU_INIT], vNULL);
- gimple_seq_add_stmt (&gseq, ifunc_cpu_init_stmt);
- gimple_set_bb (ifunc_cpu_init_stmt, *empty_bb);
- set_bb_seq (*empty_bb, gseq);
-
- pop_cfun ();
-
-
- for (ix = 1; fndecls->iterate (ix, &ele); ++ix)
- {
- tree version_decl = ele;
- tree predicate_chain = NULL_TREE;
- unsigned int priority;
- /* Get attribute string, parse it and find the right predicate decl.
- The predicate function could be a lengthy combination of many
- features, like arch-type and various isa-variants. */
- priority = get_builtin_code_for_version (version_decl,
- &predicate_chain);
-
- if (predicate_chain == NULL_TREE)
- continue;
-
- actual_versions++;
- function_version_info [ix - 1].version_decl = version_decl;
- function_version_info [ix - 1].predicate_chain = predicate_chain;
- function_version_info [ix - 1].dispatch_priority = priority;
- }
-
- /* Sort the versions according to descending order of dispatch priority. The
- priority is based on the ISA. This is not a perfect solution. There
- could still be ambiguity. If more than one function version is suitable
- to execute, which one should be dispatched? In future, allow the user
- to specify a dispatch priority next to the version. */
- qsort (function_version_info, actual_versions,
- sizeof (struct _function_version_info), feature_compare);
-
- for (i = 0; i < actual_versions; ++i)
- *empty_bb = add_condition_to_bb (dispatch_decl,
- function_version_info[i].version_decl,
- function_version_info[i].predicate_chain,
- *empty_bb);
-
- /* dispatch default version at the end. */
- *empty_bb = add_condition_to_bb (dispatch_decl, default_decl,
- NULL, *empty_bb);
-
- free (function_version_info);
- return 0;
-}
-
-/* Comparator function to be used in qsort routine to sort attribute
- specification strings to "target". */
-
-static int
-attr_strcmp (const void *v1, const void *v2)
-{
- const char *c1 = *(char *const*)v1;
- const char *c2 = *(char *const*)v2;
- return strcmp (c1, c2);
-}
-
-/* ARGLIST is the argument to target attribute. This function tokenizes
- the comma separated arguments, sorts them and returns a string which
- is a unique identifier for the comma separated arguments. It also
- replaces non-identifier characters "=,-" with "_". */
-
-static char *
-sorted_attr_string (tree arglist)
-{
- tree arg;
- size_t str_len_sum = 0;
- char **args = NULL;
- char *attr_str, *ret_str;
- char *attr = NULL;
- unsigned int argnum = 1;
- unsigned int i;
-
- for (arg = arglist; arg; arg = TREE_CHAIN (arg))
- {
- const char *str = TREE_STRING_POINTER (TREE_VALUE (arg));
- size_t len = strlen (str);
- str_len_sum += len + 1;
- if (arg != arglist)
- argnum++;
- for (i = 0; i < strlen (str); i++)
- if (str[i] == ',')
- argnum++;
- }
-
- attr_str = XNEWVEC (char, str_len_sum);
- str_len_sum = 0;
- for (arg = arglist; arg; arg = TREE_CHAIN (arg))
- {
- const char *str = TREE_STRING_POINTER (TREE_VALUE (arg));
- size_t len = strlen (str);
- memcpy (attr_str + str_len_sum, str, len);
- attr_str[str_len_sum + len] = TREE_CHAIN (arg) ? ',' : '\0';
- str_len_sum += len + 1;
- }
-
- /* Replace "=,-" with "_". */
- for (i = 0; i < strlen (attr_str); i++)
- if (attr_str[i] == '=' || attr_str[i]== '-')
- attr_str[i] = '_';
-
- if (argnum == 1)
- return attr_str;
-
- args = XNEWVEC (char *, argnum);
-
- i = 0;
- attr = strtok (attr_str, ",");
- while (attr != NULL)
- {
- args[i] = attr;
- i++;
- attr = strtok (NULL, ",");
- }
-
- qsort (args, argnum, sizeof (char *), attr_strcmp);
-
- ret_str = XNEWVEC (char, str_len_sum);
- str_len_sum = 0;
- for (i = 0; i < argnum; i++)
- {
- size_t len = strlen (args[i]);
- memcpy (ret_str + str_len_sum, args[i], len);
- ret_str[str_len_sum + len] = i < argnum - 1 ? '_' : '\0';
- str_len_sum += len + 1;
- }
-
- XDELETEVEC (args);
- XDELETEVEC (attr_str);
- return ret_str;
-}
-
-/* This function changes the assembler name for functions that are
- versions. If DECL is a function version and has a "target"
- attribute, it appends the attribute string to its assembler name. */
-
-static tree
-ix86_mangle_function_version_assembler_name (tree decl, tree id)
-{
- tree version_attr;
- const char *orig_name, *version_string;
- char *attr_str, *assembler_name;
-
- if (DECL_DECLARED_INLINE_P (decl)
- && lookup_attribute ("gnu_inline",
- DECL_ATTRIBUTES (decl)))
- error_at (DECL_SOURCE_LOCATION (decl),
- "Function versions cannot be marked as gnu_inline,"
- " bodies have to be generated");
-
- if (DECL_VIRTUAL_P (decl)
- || DECL_VINDEX (decl))
- sorry ("Virtual function multiversioning not supported");
-
- version_attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
-
- /* target attribute string cannot be NULL. */
- gcc_assert (version_attr != NULL_TREE);
-
- orig_name = IDENTIFIER_POINTER (id);
- version_string
- = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (version_attr)));
-
- if (strcmp (version_string, "default") == 0)
- return id;
-
- attr_str = sorted_attr_string (TREE_VALUE (version_attr));
- assembler_name = XNEWVEC (char, strlen (orig_name) + strlen (attr_str) + 2);
-
- sprintf (assembler_name, "%s.%s", orig_name, attr_str);
-
- /* Allow assembler name to be modified if already set. */
- if (DECL_ASSEMBLER_NAME_SET_P (decl))
- SET_DECL_RTL (decl, NULL);
-
- tree ret = get_identifier (assembler_name);
- XDELETEVEC (attr_str);
- XDELETEVEC (assembler_name);
- return ret;
-}
-
-/* This function returns true if FN1 and FN2 are versions of the same function,
- that is, the target strings of the function decls are different. This assumes
- that FN1 and FN2 have the same signature. */
-
-static bool
-ix86_function_versions (tree fn1, tree fn2)
-{
- tree attr1, attr2;
- char *target1, *target2;
- bool result;
-
- if (TREE_CODE (fn1) != FUNCTION_DECL
- || TREE_CODE (fn2) != FUNCTION_DECL)
- return false;
-
- attr1 = lookup_attribute ("target", DECL_ATTRIBUTES (fn1));
- attr2 = lookup_attribute ("target", DECL_ATTRIBUTES (fn2));
-
- /* At least one function decl should have the target attribute specified. */
- if (attr1 == NULL_TREE && attr2 == NULL_TREE)
- return false;
-
- /* Diagnose missing target attribute if one of the decls is already
- multi-versioned. */
- if (attr1 == NULL_TREE || attr2 == NULL_TREE)
- {
- if (DECL_FUNCTION_VERSIONED (fn1) || DECL_FUNCTION_VERSIONED (fn2))
- {
- if (attr2 != NULL_TREE)
- {
- tree tem = fn1;
- fn1 = fn2;
- fn2 = tem;
- attr1 = attr2;
- }
- error_at (DECL_SOURCE_LOCATION (fn2),
- "missing %<target%> attribute for multi-versioned %D",
- fn2);
- error_at (DECL_SOURCE_LOCATION (fn1),
- "previous declaration of %D", fn1);
- /* Prevent diagnosing of the same error multiple times. */
- DECL_ATTRIBUTES (fn2)
- = tree_cons (get_identifier ("target"),
- copy_node (TREE_VALUE (attr1)),
- DECL_ATTRIBUTES (fn2));
- }
- return false;
- }
-
- target1 = sorted_attr_string (TREE_VALUE (attr1));
- target2 = sorted_attr_string (TREE_VALUE (attr2));
-
- /* The sorted target strings must be different for fn1 and fn2
- to be versions. */
- if (strcmp (target1, target2) == 0)
- result = false;
- else
- result = true;
-
- XDELETEVEC (target1);
- XDELETEVEC (target2);
-
- return result;
-}
-
-static tree
-ix86_mangle_decl_assembler_name (tree decl, tree id)
-{
- /* For function version, add the target suffix to the assembler name. */
- if (TREE_CODE (decl) == FUNCTION_DECL
- && DECL_FUNCTION_VERSIONED (decl))
- id = ix86_mangle_function_version_assembler_name (decl, id);
-#ifdef SUBTARGET_MANGLE_DECL_ASSEMBLER_NAME
- id = SUBTARGET_MANGLE_DECL_ASSEMBLER_NAME (decl, id);
-#endif
-
- return id;
-}
-
-/* Return a new name by appending SUFFIX to the DECL name. If make_unique
- is true, append the full path name of the source file. */
-
-static char *
-make_name (tree decl, const char *suffix, bool make_unique)
-{
- char *global_var_name;
- int name_len;
- const char *name;
- const char *unique_name = NULL;
-
- name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-
- /* Get a unique name that can be used globally without any chances
- of collision at link time. */
- if (make_unique)
- unique_name = IDENTIFIER_POINTER (get_file_function_name ("\0"));
-
- name_len = strlen (name) + strlen (suffix) + 2;
-
- if (make_unique)
- name_len += strlen (unique_name) + 1;
- global_var_name = XNEWVEC (char, name_len);
-
- /* Use '.' to concatenate names as it is demangler friendly. */
- if (make_unique)
- snprintf (global_var_name, name_len, "%s.%s.%s", name, unique_name,
- suffix);
- else
- snprintf (global_var_name, name_len, "%s.%s", name, suffix);
-
- return global_var_name;
-}
-
-#if defined (ASM_OUTPUT_TYPE_DIRECTIVE) && HAVE_GNU_INDIRECT_FUNCTION
-
-/* Make a dispatcher declaration for the multi-versioned function DECL.
- Calls to DECL function will be replaced with calls to the dispatcher
- by the front-end. Return the decl created. */
-
-static tree
-make_dispatcher_decl (const tree decl)
-{
- tree func_decl;
- char *func_name;
- tree fn_type, func_type;
- bool is_uniq = false;
-
- if (TREE_PUBLIC (decl) == 0)
- is_uniq = true;
-
- func_name = make_name (decl, "ifunc", is_uniq);
-
- fn_type = TREE_TYPE (decl);
- func_type = build_function_type (TREE_TYPE (fn_type),
- TYPE_ARG_TYPES (fn_type));
-
- func_decl = build_fn_decl (func_name, func_type);
- XDELETEVEC (func_name);
- TREE_USED (func_decl) = 1;
- DECL_CONTEXT (func_decl) = NULL_TREE;
- DECL_INITIAL (func_decl) = error_mark_node;
- DECL_ARTIFICIAL (func_decl) = 1;
- /* Mark this func as external, the resolver will flip it again if
- it gets generated. */
- DECL_EXTERNAL (func_decl) = 1;
- /* This will be of type IFUNCs have to be externally visible. */
- TREE_PUBLIC (func_decl) = 1;
-
- return func_decl;
-}
-
-#endif
-
-/* Returns true if decl is multi-versioned and DECL is the default function,
- that is it is not tagged with target specific optimization. */
-
-static bool
-is_function_default_version (const tree decl)
-{
- if (TREE_CODE (decl) != FUNCTION_DECL
- || !DECL_FUNCTION_VERSIONED (decl))
- return false;
- tree attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
- gcc_assert (attr);
- attr = TREE_VALUE (TREE_VALUE (attr));
- return (TREE_CODE (attr) == STRING_CST
- && strcmp (TREE_STRING_POINTER (attr), "default") == 0);
-}
-
-/* Make a dispatcher declaration for the multi-versioned function DECL.
- Calls to DECL function will be replaced with calls to the dispatcher
- by the front-end. Returns the decl of the dispatcher function. */
-
-static tree
-ix86_get_function_versions_dispatcher (void *decl)
-{
- tree fn = (tree) decl;
- struct cgraph_node *node = NULL;
- struct cgraph_node *default_node = NULL;
- struct cgraph_function_version_info *node_v = NULL;
- struct cgraph_function_version_info *first_v = NULL;
-
- tree dispatch_decl = NULL;
-
-#if defined (ASM_OUTPUT_TYPE_DIRECTIVE) && HAVE_GNU_INDIRECT_FUNCTION
- struct cgraph_function_version_info *it_v = NULL;
- struct cgraph_node *dispatcher_node = NULL;
- struct cgraph_function_version_info *dispatcher_version_info = NULL;
-#endif
-
- struct cgraph_function_version_info *default_version_info = NULL;
-
- gcc_assert (fn != NULL && DECL_FUNCTION_VERSIONED (fn));
-
- node = cgraph_get_node (fn);
- gcc_assert (node != NULL);
-
- node_v = get_cgraph_node_version (node);
- gcc_assert (node_v != NULL);
-
- if (node_v->dispatcher_resolver != NULL)
- return node_v->dispatcher_resolver;
-
- /* Find the default version and make it the first node. */
- first_v = node_v;
- /* Go to the beginnig of the chain. */
- while (first_v->prev != NULL)
- first_v = first_v->prev;
- default_version_info = first_v;
- while (default_version_info != NULL)
- {
- if (is_function_default_version
- (default_version_info->this_node->symbol.decl))
- break;
- default_version_info = default_version_info->next;
- }
-
- /* If there is no default node, just return NULL. */
- if (default_version_info == NULL)
- return NULL;
-
- /* Make default info the first node. */
- if (first_v != default_version_info)
- {
- default_version_info->prev->next = default_version_info->next;
- if (default_version_info->next)
- default_version_info->next->prev = default_version_info->prev;
- first_v->prev = default_version_info;
- default_version_info->next = first_v;
- default_version_info->prev = NULL;
- }
-
- default_node = default_version_info->this_node;
-
-#if defined (ASM_OUTPUT_TYPE_DIRECTIVE) && HAVE_GNU_INDIRECT_FUNCTION
- /* Right now, the dispatching is done via ifunc. */
- dispatch_decl = make_dispatcher_decl (default_node->symbol.decl);
-
- dispatcher_node = cgraph_get_create_node (dispatch_decl);
- gcc_assert (dispatcher_node != NULL);
- dispatcher_node->dispatcher_function = 1;
- dispatcher_version_info
- = insert_new_cgraph_node_version (dispatcher_node);
- dispatcher_version_info->next = default_version_info;
- dispatcher_node->local.finalized = 1;
-
- /* Set the dispatcher for all the versions. */
- it_v = default_version_info;
- while (it_v != NULL)
- {
- it_v->dispatcher_resolver = dispatch_decl;
- it_v = it_v->next;
- }
-#else
- error_at (DECL_SOURCE_LOCATION (default_node->symbol.decl),
- "multiversioning needs ifunc which is not supported "
- "in this configuration");
-#endif
- return dispatch_decl;
-}
-
-/* Makes a function attribute of the form NAME(ARG_NAME) and chains
- it to CHAIN. */
-
-static tree
-make_attribute (const char *name, const char *arg_name, tree chain)
-{
- tree attr_name;
- tree attr_arg_name;
- tree attr_args;
- tree attr;
-
- attr_name = get_identifier (name);
- attr_arg_name = build_string (strlen (arg_name), arg_name);
- attr_args = tree_cons (NULL_TREE, attr_arg_name, NULL_TREE);
- attr = tree_cons (attr_name, attr_args, chain);
- return attr;
-}
-
-/* Make the resolver function decl to dispatch the versions of
- a multi-versioned function, DEFAULT_DECL. Create an
- empty basic block in the resolver and store the pointer in
- EMPTY_BB. Return the decl of the resolver function. */
-
-static tree
-make_resolver_func (const tree default_decl,
- const tree dispatch_decl,
- basic_block *empty_bb)
-{
- char *resolver_name;
- tree decl, type, decl_name, t;
- bool is_uniq = false;
-
- /* IFUNC's have to be globally visible. So, if the default_decl is
- not, then the name of the IFUNC should be made unique. */
- if (TREE_PUBLIC (default_decl) == 0)
- is_uniq = true;
-
- /* Append the filename to the resolver function if the versions are
- not externally visible. This is because the resolver function has
- to be externally visible for the loader to find it. So, appending
- the filename will prevent conflicts with a resolver function from
- another module which is based on the same version name. */
- resolver_name = make_name (default_decl, "resolver", is_uniq);
-
- /* The resolver function should return a (void *). */
- type = build_function_type_list (ptr_type_node, NULL_TREE);
-
- decl = build_fn_decl (resolver_name, type);
- decl_name = get_identifier (resolver_name);
- SET_DECL_ASSEMBLER_NAME (decl, decl_name);
-
- DECL_NAME (decl) = decl_name;
- TREE_USED (decl) = 1;
- DECL_ARTIFICIAL (decl) = 1;
- DECL_IGNORED_P (decl) = 0;
- /* IFUNC resolvers have to be externally visible. */
- TREE_PUBLIC (decl) = 1;
- DECL_UNINLINABLE (decl) = 0;
-
- /* Resolver is not external, body is generated. */
- DECL_EXTERNAL (decl) = 0;
- DECL_EXTERNAL (dispatch_decl) = 0;
-
- DECL_CONTEXT (decl) = NULL_TREE;
- DECL_INITIAL (decl) = make_node (BLOCK);
- DECL_STATIC_CONSTRUCTOR (decl) = 0;
-
- if (DECL_COMDAT_GROUP (default_decl)
- || TREE_PUBLIC (default_decl))
- {
- /* In this case, each translation unit with a call to this
- versioned function will put out a resolver. Ensure it
- is comdat to keep just one copy. */
- DECL_COMDAT (decl) = 1;
- make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
- }
- /* Build result decl and add to function_decl. */
- t = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, ptr_type_node);
- DECL_ARTIFICIAL (t) = 1;
- DECL_IGNORED_P (t) = 1;
- DECL_RESULT (decl) = t;
-
- gimplify_function_tree (decl);
- push_cfun (DECL_STRUCT_FUNCTION (decl));
- *empty_bb = init_lowered_empty_function (decl, false);
-
- cgraph_add_new_function (decl, true);
- cgraph_call_function_insertion_hooks (cgraph_get_create_node (decl));
-
- pop_cfun ();
-
- gcc_assert (dispatch_decl != NULL);
- /* Mark dispatch_decl as "ifunc" with resolver as resolver_name. */
- DECL_ATTRIBUTES (dispatch_decl)
- = make_attribute ("ifunc", resolver_name, DECL_ATTRIBUTES (dispatch_decl));
-
- /* Create the alias for dispatch to resolver here. */
- /*cgraph_create_function_alias (dispatch_decl, decl);*/
- cgraph_same_body_alias (NULL, dispatch_decl, decl);
- XDELETEVEC (resolver_name);
- return decl;
-}
-
-/* Generate the dispatching code body to dispatch multi-versioned function
- DECL. The target hook is called to process the "target" attributes and
- provide the code to dispatch the right function at run-time. NODE points
- to the dispatcher decl whose body will be created. */
-
-static tree
-ix86_generate_version_dispatcher_body (void *node_p)
-{
- tree resolver_decl;
- basic_block empty_bb;
- vec<tree> fn_ver_vec = vNULL;
- tree default_ver_decl;
- struct cgraph_node *versn;
- struct cgraph_node *node;
-
- struct cgraph_function_version_info *node_version_info = NULL;
- struct cgraph_function_version_info *versn_info = NULL;
-
- node = (cgraph_node *)node_p;
-
- node_version_info = get_cgraph_node_version (node);
- gcc_assert (node->dispatcher_function
- && node_version_info != NULL);
-
- if (node_version_info->dispatcher_resolver)
- return node_version_info->dispatcher_resolver;
-
- /* The first version in the chain corresponds to the default version. */
- default_ver_decl = node_version_info->next->this_node->symbol.decl;
-
- /* node is going to be an alias, so remove the finalized bit. */
- node->local.finalized = false;
-
- resolver_decl = make_resolver_func (default_ver_decl,
- node->symbol.decl, &empty_bb);
-
- node_version_info->dispatcher_resolver = resolver_decl;
-
- push_cfun (DECL_STRUCT_FUNCTION (resolver_decl));
-
- fn_ver_vec.create (2);
-
- for (versn_info = node_version_info->next; versn_info;
- versn_info = versn_info->next)
- {
- versn = versn_info->this_node;
- /* Check for virtual functions here again, as by this time it should
- have been determined if this function needs a vtable index or
- not. This happens for methods in derived classes that override
- virtual methods in base classes but are not explicitly marked as
- virtual. */
- if (DECL_VINDEX (versn->symbol.decl))
- sorry ("Virtual function multiversioning not supported");
-
- fn_ver_vec.safe_push (versn->symbol.decl);
- }
-
- dispatch_function_versions (resolver_decl, &fn_ver_vec, &empty_bb);
- fn_ver_vec.release ();
- rebuild_cgraph_edges ();
- pop_cfun ();
- return resolver_decl;
-}
-/* This builds the processor_model struct type defined in
- libgcc/config/i386/cpuinfo.c */
-
-static tree
-build_processor_model_struct (void)
-{
- const char *field_name[] = {"__cpu_vendor", "__cpu_type", "__cpu_subtype",
- "__cpu_features"};
- tree field = NULL_TREE, field_chain = NULL_TREE;
- int i;
- tree type = make_node (RECORD_TYPE);
-
- /* The first 3 fields are unsigned int. */
- for (i = 0; i < 3; ++i)
- {
- field = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
- get_identifier (field_name[i]), unsigned_type_node);
- if (field_chain != NULL_TREE)
- DECL_CHAIN (field) = field_chain;
- field_chain = field;
- }
-
- /* The last field is an array of unsigned integers of size one. */
- field = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
- get_identifier (field_name[3]),
- build_array_type (unsigned_type_node,
- build_index_type (size_one_node)));
- if (field_chain != NULL_TREE)
- DECL_CHAIN (field) = field_chain;
- field_chain = field;
-
- finish_builtin_struct (type, "__processor_model", field_chain, NULL_TREE);
- return type;
-}
-
-/* Returns a extern, comdat VAR_DECL of type TYPE and name NAME. */
-
-static tree
-make_var_decl (tree type, const char *name)
-{
- tree new_decl;
-
- new_decl = build_decl (UNKNOWN_LOCATION,
- VAR_DECL,
- get_identifier(name),
- type);
-
- DECL_EXTERNAL (new_decl) = 1;
- TREE_STATIC (new_decl) = 1;
- TREE_PUBLIC (new_decl) = 1;
- DECL_INITIAL (new_decl) = 0;
- DECL_ARTIFICIAL (new_decl) = 0;
- DECL_PRESERVE_P (new_decl) = 1;
-
- make_decl_one_only (new_decl, DECL_ASSEMBLER_NAME (new_decl));
- assemble_variable (new_decl, 0, 0, 0);
-
- return new_decl;
-}
-
-/* FNDECL is a __builtin_cpu_is or a __builtin_cpu_supports call that is folded
- into an integer defined in libgcc/config/i386/cpuinfo.c */
-
-static tree
-fold_builtin_cpu (tree fndecl, tree *args)
-{
- unsigned int i;
- enum ix86_builtins fn_code = (enum ix86_builtins)
- DECL_FUNCTION_CODE (fndecl);
- tree param_string_cst = NULL;
-
- /* This is the order of bit-fields in __processor_features in cpuinfo.c */
- enum processor_features
- {
- F_CMOV = 0,
- F_MMX,
- F_POPCNT,
- F_SSE,
- F_SSE2,
- F_SSE3,
- F_SSSE3,
- F_SSE4_1,
- F_SSE4_2,
- F_AVX,
- F_AVX2,
- F_MAX
- };
-
- /* These are the values for vendor types and cpu types and subtypes
- in cpuinfo.c. Cpu types and subtypes should be subtracted by
- the corresponding start value. */
- enum processor_model
- {
- M_INTEL = 1,
- M_AMD,
- M_CPU_TYPE_START,
- M_INTEL_ATOM,
- M_INTEL_CORE2,
- M_INTEL_COREI7,
- M_AMDFAM10H,
- M_AMDFAM15H,
- M_INTEL_SLM,
- M_CPU_SUBTYPE_START,
- M_INTEL_COREI7_NEHALEM,
- M_INTEL_COREI7_WESTMERE,
- M_INTEL_COREI7_SANDYBRIDGE,
- M_AMDFAM10H_BARCELONA,
- M_AMDFAM10H_SHANGHAI,
- M_AMDFAM10H_ISTANBUL,
- M_AMDFAM15H_BDVER1,
- M_AMDFAM15H_BDVER2,
- M_AMDFAM15H_BDVER3
- };
-
- static struct _arch_names_table
- {
- const char *const name;
- const enum processor_model model;
- }
- const arch_names_table[] =
- {
- {"amd", M_AMD},
- {"intel", M_INTEL},
- {"atom", M_INTEL_ATOM},
- {"slm", M_INTEL_SLM},
- {"core2", M_INTEL_CORE2},
- {"corei7", M_INTEL_COREI7},
- {"nehalem", M_INTEL_COREI7_NEHALEM},
- {"westmere", M_INTEL_COREI7_WESTMERE},
- {"sandybridge", M_INTEL_COREI7_SANDYBRIDGE},
- {"amdfam10h", M_AMDFAM10H},
- {"barcelona", M_AMDFAM10H_BARCELONA},
- {"shanghai", M_AMDFAM10H_SHANGHAI},
- {"istanbul", M_AMDFAM10H_ISTANBUL},
- {"amdfam15h", M_AMDFAM15H},
- {"bdver1", M_AMDFAM15H_BDVER1},
- {"bdver2", M_AMDFAM15H_BDVER2},
- {"bdver3", M_AMDFAM15H_BDVER3},
- };
-
- static struct _isa_names_table
- {
- const char *const name;
- const enum processor_features feature;
- }
- const isa_names_table[] =
- {
- {"cmov", F_CMOV},
- {"mmx", F_MMX},
- {"popcnt", F_POPCNT},
- {"sse", F_SSE},
- {"sse2", F_SSE2},
- {"sse3", F_SSE3},
- {"ssse3", F_SSSE3},
- {"sse4.1", F_SSE4_1},
- {"sse4.2", F_SSE4_2},
- {"avx", F_AVX},
- {"avx2", F_AVX2}
- };
-
- tree __processor_model_type = build_processor_model_struct ();
- tree __cpu_model_var = make_var_decl (__processor_model_type,
- "__cpu_model");
-
- gcc_assert ((args != NULL) && (*args != NULL));
-
- param_string_cst = *args;
- while (param_string_cst
- && TREE_CODE (param_string_cst) != STRING_CST)
- {
- /* *args must be a expr that can contain other EXPRS leading to a
- STRING_CST. */
- if (!EXPR_P (param_string_cst))
- {
- error ("Parameter to builtin must be a string constant or literal");
- return integer_zero_node;
- }
- param_string_cst = TREE_OPERAND (EXPR_CHECK (param_string_cst), 0);
- }
-
- gcc_assert (param_string_cst);
-
- if (fn_code == IX86_BUILTIN_CPU_IS)
- {
- tree ref;
- tree field;
- tree final;
-
- unsigned int field_val = 0;
- unsigned int NUM_ARCH_NAMES
- = sizeof (arch_names_table) / sizeof (struct _arch_names_table);
-
- for (i = 0; i < NUM_ARCH_NAMES; i++)
- if (strcmp (arch_names_table[i].name,
- TREE_STRING_POINTER (param_string_cst)) == 0)
- break;
-
- if (i == NUM_ARCH_NAMES)
- {
- error ("Parameter to builtin not valid: %s",
- TREE_STRING_POINTER (param_string_cst));
- return integer_zero_node;
- }
-
- field = TYPE_FIELDS (__processor_model_type);
- field_val = arch_names_table[i].model;
-
- /* CPU types are stored in the next field. */
- if (field_val > M_CPU_TYPE_START
- && field_val < M_CPU_SUBTYPE_START)
- {
- field = DECL_CHAIN (field);
- field_val -= M_CPU_TYPE_START;
- }
-
- /* CPU subtypes are stored in the next field. */
- if (field_val > M_CPU_SUBTYPE_START)
- {
- field = DECL_CHAIN ( DECL_CHAIN (field));
- field_val -= M_CPU_SUBTYPE_START;
- }
-
- /* Get the appropriate field in __cpu_model. */
- ref = build3 (COMPONENT_REF, TREE_TYPE (field), __cpu_model_var,
- field, NULL_TREE);
-
- /* Check the value. */
- final = build2 (EQ_EXPR, unsigned_type_node, ref,
- build_int_cstu (unsigned_type_node, field_val));
- return build1 (CONVERT_EXPR, integer_type_node, final);
- }
- else if (fn_code == IX86_BUILTIN_CPU_SUPPORTS)
- {
- tree ref;
- tree array_elt;
- tree field;
- tree final;
-
- unsigned int field_val = 0;
- unsigned int NUM_ISA_NAMES
- = sizeof (isa_names_table) / sizeof (struct _isa_names_table);
-
- for (i = 0; i < NUM_ISA_NAMES; i++)
- if (strcmp (isa_names_table[i].name,
- TREE_STRING_POINTER (param_string_cst)) == 0)
- break;
-
- if (i == NUM_ISA_NAMES)
- {
- error ("Parameter to builtin not valid: %s",
- TREE_STRING_POINTER (param_string_cst));
- return integer_zero_node;
- }
-
- field = TYPE_FIELDS (__processor_model_type);
- /* Get the last field, which is __cpu_features. */
- while (DECL_CHAIN (field))
- field = DECL_CHAIN (field);
-
- /* Get the appropriate field: __cpu_model.__cpu_features */
- ref = build3 (COMPONENT_REF, TREE_TYPE (field), __cpu_model_var,
- field, NULL_TREE);
-
- /* Access the 0th element of __cpu_features array. */
- array_elt = build4 (ARRAY_REF, unsigned_type_node, ref,
- integer_zero_node, NULL_TREE, NULL_TREE);
-
- field_val = (1 << isa_names_table[i].feature);
- /* Return __cpu_model.__cpu_features[0] & field_val */
- final = build2 (BIT_AND_EXPR, unsigned_type_node, array_elt,
- build_int_cstu (unsigned_type_node, field_val));
- return build1 (CONVERT_EXPR, integer_type_node, final);
- }
- gcc_unreachable ();
-}
-
-static tree
-ix86_fold_builtin (tree fndecl, int n_args,
- tree *args, bool ignore ATTRIBUTE_UNUSED)
-{
- if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
- {
- enum ix86_builtins fn_code = (enum ix86_builtins)
- DECL_FUNCTION_CODE (fndecl);
- if (fn_code == IX86_BUILTIN_CPU_IS
- || fn_code == IX86_BUILTIN_CPU_SUPPORTS)
- {
- gcc_assert (n_args == 1);
- return fold_builtin_cpu (fndecl, args);
- }
- }
-
-#ifdef SUBTARGET_FOLD_BUILTIN
- return SUBTARGET_FOLD_BUILTIN (fndecl, n_args, args, ignore);
-#endif
-
- return NULL_TREE;
-}
-
-/* Make builtins to detect cpu type and features supported. NAME is
- the builtin name, CODE is the builtin code, and FTYPE is the function
- type of the builtin. */
-
-static void
-make_cpu_type_builtin (const char* name, int code,
- enum ix86_builtin_func_type ftype, bool is_const)
-{
- tree decl;
- tree type;
-
- type = ix86_get_builtin_func_type (ftype);
- decl = add_builtin_function (name, type, code, BUILT_IN_MD,
- NULL, NULL_TREE);
- gcc_assert (decl != NULL_TREE);
- ix86_builtins[(int) code] = decl;
- TREE_READONLY (decl) = is_const;
-}
-
-/* Make builtins to get CPU type and features supported. The created
- builtins are :
-
- __builtin_cpu_init (), to detect cpu type and features,
- __builtin_cpu_is ("<CPUNAME>"), to check if cpu is of type <CPUNAME>,
- __builtin_cpu_supports ("<FEATURE>"), to check if cpu supports <FEATURE>
- */
-
-static void
-ix86_init_platform_type_builtins (void)
-{
- make_cpu_type_builtin ("__builtin_cpu_init", IX86_BUILTIN_CPU_INIT,
- INT_FTYPE_VOID, false);
- make_cpu_type_builtin ("__builtin_cpu_is", IX86_BUILTIN_CPU_IS,
- INT_FTYPE_PCCHAR, true);
- make_cpu_type_builtin ("__builtin_cpu_supports", IX86_BUILTIN_CPU_SUPPORTS,
- INT_FTYPE_PCCHAR, true);
-}
-
-/* Internal method for ix86_init_builtins. */
-
-static void
-ix86_init_builtins_va_builtins_abi (void)
-{
- tree ms_va_ref, sysv_va_ref;
- tree fnvoid_va_end_ms, fnvoid_va_end_sysv;
- tree fnvoid_va_start_ms, fnvoid_va_start_sysv;
- tree fnvoid_va_copy_ms, fnvoid_va_copy_sysv;
- tree fnattr_ms = NULL_TREE, fnattr_sysv = NULL_TREE;
-
- if (!TARGET_64BIT)
- return;
- fnattr_ms = build_tree_list (get_identifier ("ms_abi"), NULL_TREE);
- fnattr_sysv = build_tree_list (get_identifier ("sysv_abi"), NULL_TREE);
- ms_va_ref = build_reference_type (ms_va_list_type_node);
- sysv_va_ref =
- build_pointer_type (TREE_TYPE (sysv_va_list_type_node));
-
- fnvoid_va_end_ms =
- build_function_type_list (void_type_node, ms_va_ref, NULL_TREE);
- fnvoid_va_start_ms =
- build_varargs_function_type_list (void_type_node, ms_va_ref, NULL_TREE);
- fnvoid_va_end_sysv =
- build_function_type_list (void_type_node, sysv_va_ref, NULL_TREE);
- fnvoid_va_start_sysv =
- build_varargs_function_type_list (void_type_node, sysv_va_ref,
- NULL_TREE);
- fnvoid_va_copy_ms =
- build_function_type_list (void_type_node, ms_va_ref, ms_va_list_type_node,
- NULL_TREE);
- fnvoid_va_copy_sysv =
- build_function_type_list (void_type_node, sysv_va_ref,
- sysv_va_ref, NULL_TREE);
-
- add_builtin_function ("__builtin_ms_va_start", fnvoid_va_start_ms,
- BUILT_IN_VA_START, BUILT_IN_NORMAL, NULL, fnattr_ms);
- add_builtin_function ("__builtin_ms_va_end", fnvoid_va_end_ms,
- BUILT_IN_VA_END, BUILT_IN_NORMAL, NULL, fnattr_ms);
- add_builtin_function ("__builtin_ms_va_copy", fnvoid_va_copy_ms,
- BUILT_IN_VA_COPY, BUILT_IN_NORMAL, NULL, fnattr_ms);
- add_builtin_function ("__builtin_sysv_va_start", fnvoid_va_start_sysv,
- BUILT_IN_VA_START, BUILT_IN_NORMAL, NULL, fnattr_sysv);
- add_builtin_function ("__builtin_sysv_va_end", fnvoid_va_end_sysv,
- BUILT_IN_VA_END, BUILT_IN_NORMAL, NULL, fnattr_sysv);
- add_builtin_function ("__builtin_sysv_va_copy", fnvoid_va_copy_sysv,
- BUILT_IN_VA_COPY, BUILT_IN_NORMAL, NULL, fnattr_sysv);
-}
-
-static void
-ix86_init_builtin_types (void)
-{
- tree float128_type_node, float80_type_node;
-
- /* The __float80 type. */
- float80_type_node = long_double_type_node;
- if (TYPE_MODE (float80_type_node) != XFmode)
- {
- /* The __float80 type. */
- float80_type_node = make_node (REAL_TYPE);
-
- TYPE_PRECISION (float80_type_node) = 80;
- layout_type (float80_type_node);
- }
- lang_hooks.types.register_builtin_type (float80_type_node, "__float80");
-
- /* The __float128 type. */
- float128_type_node = make_node (REAL_TYPE);
- TYPE_PRECISION (float128_type_node) = 128;
- layout_type (float128_type_node);
- lang_hooks.types.register_builtin_type (float128_type_node, "__float128");
-
- /* This macro is built by i386-builtin-types.awk. */
- DEFINE_BUILTIN_PRIMITIVE_TYPES;
-}
-
-static void
-ix86_init_builtins (void)
-{
- tree t;
-
- ix86_init_builtin_types ();
-
- /* Builtins to get CPU type and features. */
- ix86_init_platform_type_builtins ();
-
- /* TFmode support builtins. */
- def_builtin_const (0, "__builtin_infq",
- FLOAT128_FTYPE_VOID, IX86_BUILTIN_INFQ);
- def_builtin_const (0, "__builtin_huge_valq",
- FLOAT128_FTYPE_VOID, IX86_BUILTIN_HUGE_VALQ);
-
- /* We will expand them to normal call if SSE isn't available since
- they are used by libgcc. */
- t = ix86_get_builtin_func_type (FLOAT128_FTYPE_FLOAT128);
- t = add_builtin_function ("__builtin_fabsq", t, IX86_BUILTIN_FABSQ,
- BUILT_IN_MD, "__fabstf2", NULL_TREE);
- TREE_READONLY (t) = 1;
- ix86_builtins[(int) IX86_BUILTIN_FABSQ] = t;
-
- t = ix86_get_builtin_func_type (FLOAT128_FTYPE_FLOAT128_FLOAT128);
- t = add_builtin_function ("__builtin_copysignq", t, IX86_BUILTIN_COPYSIGNQ,
- BUILT_IN_MD, "__copysigntf3", NULL_TREE);
- TREE_READONLY (t) = 1;
- ix86_builtins[(int) IX86_BUILTIN_COPYSIGNQ] = t;
-
- ix86_init_tm_builtins ();
- ix86_init_mmx_sse_builtins ();
-
- if (TARGET_LP64)
- ix86_init_builtins_va_builtins_abi ();
-
-#ifdef SUBTARGET_INIT_BUILTINS
- SUBTARGET_INIT_BUILTINS;
-#endif
-}
-
-/* Return the ix86 builtin for CODE. */
-
-static tree
-ix86_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
-{
- if (code >= IX86_BUILTIN_MAX)
- return error_mark_node;
-
- return ix86_builtins[code];
-}
-
-/* Errors in the source file can cause expand_expr to return const0_rtx
- where we expect a vector. To avoid crashing, use one of the vector
- clear instructions. */
-static rtx
-safe_vector_operand (rtx x, enum machine_mode mode)
-{
- if (x == const0_rtx)
- x = CONST0_RTX (mode);
- return x;
-}
-
-/* Subroutine of ix86_expand_builtin to take care of binop insns. */
-
-static rtx
-ix86_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 (VECTOR_MODE_P (mode0))
- op0 = safe_vector_operand (op0, mode0);
- if (VECTOR_MODE_P (mode1))
- op1 = safe_vector_operand (op1, mode1);
-
- if (optimize || !target
- || GET_MODE (target) != tmode
- || !insn_data[icode].operand[0].predicate (target, tmode))
- target = gen_reg_rtx (tmode);
-
- if (GET_MODE (op1) == SImode && mode1 == TImode)
- {
- rtx x = gen_reg_rtx (V4SImode);
- emit_insn (gen_sse2_loadd (x, op1));
- op1 = gen_lowpart (TImode, x);
- }
-
- 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);
-
- pat = GEN_FCN (icode) (target, op0, op1);
- if (! pat)
- return 0;
-
- emit_insn (pat);
-
- return target;
-}
-
-/* Subroutine of ix86_expand_builtin to take care of 2-4 argument insns. */
-
-static rtx
-ix86_expand_multi_arg_builtin (enum insn_code icode, tree exp, rtx target,
- enum ix86_builtin_func_type m_type,
- enum rtx_code sub_code)
-{
- rtx pat;
- int i;
- int nargs;
- bool comparison_p = false;
- bool tf_p = false;
- bool last_arg_constant = false;
- int num_memory = 0;
- struct {
- rtx op;
- enum machine_mode mode;
- } args[4];
-
- enum machine_mode tmode = insn_data[icode].operand[0].mode;
-
- switch (m_type)
- {
- case MULTI_ARG_4_DF2_DI_I:
- case MULTI_ARG_4_DF2_DI_I1:
- case MULTI_ARG_4_SF2_SI_I:
- case MULTI_ARG_4_SF2_SI_I1:
- nargs = 4;
- last_arg_constant = true;
- break;
-
- case MULTI_ARG_3_SF:
- case MULTI_ARG_3_DF:
- case MULTI_ARG_3_SF2:
- case MULTI_ARG_3_DF2:
- case MULTI_ARG_3_DI:
- case MULTI_ARG_3_SI:
- case MULTI_ARG_3_SI_DI:
- case MULTI_ARG_3_HI:
- case MULTI_ARG_3_HI_SI:
- case MULTI_ARG_3_QI:
- case MULTI_ARG_3_DI2:
- case MULTI_ARG_3_SI2:
- case MULTI_ARG_3_HI2:
- case MULTI_ARG_3_QI2:
- nargs = 3;
- break;
-
- case MULTI_ARG_2_SF:
- case MULTI_ARG_2_DF:
- case MULTI_ARG_2_DI:
- case MULTI_ARG_2_SI:
- case MULTI_ARG_2_HI:
- case MULTI_ARG_2_QI:
- nargs = 2;
- break;
-
- case MULTI_ARG_2_DI_IMM:
- case MULTI_ARG_2_SI_IMM:
- case MULTI_ARG_2_HI_IMM:
- case MULTI_ARG_2_QI_IMM:
- nargs = 2;
- last_arg_constant = true;
- break;
-
- case MULTI_ARG_1_SF:
- case MULTI_ARG_1_DF:
- case MULTI_ARG_1_SF2:
- case MULTI_ARG_1_DF2:
- case MULTI_ARG_1_DI:
- case MULTI_ARG_1_SI:
- case MULTI_ARG_1_HI:
- case MULTI_ARG_1_QI:
- case MULTI_ARG_1_SI_DI:
- case MULTI_ARG_1_HI_DI:
- case MULTI_ARG_1_HI_SI:
- case MULTI_ARG_1_QI_DI:
- case MULTI_ARG_1_QI_SI:
- case MULTI_ARG_1_QI_HI:
- nargs = 1;
- break;
-
- case MULTI_ARG_2_DI_CMP:
- case MULTI_ARG_2_SI_CMP:
- case MULTI_ARG_2_HI_CMP:
- case MULTI_ARG_2_QI_CMP:
- nargs = 2;
- comparison_p = true;
- break;
-
- case MULTI_ARG_2_SF_TF:
- case MULTI_ARG_2_DF_TF:
- case MULTI_ARG_2_DI_TF:
- case MULTI_ARG_2_SI_TF:
- case MULTI_ARG_2_HI_TF:
- case MULTI_ARG_2_QI_TF:
- nargs = 2;
- tf_p = true;
- break;
-
- default:
- gcc_unreachable ();
- }
-
- if (optimize || !target
- || GET_MODE (target) != tmode
- || !insn_data[icode].operand[0].predicate (target, tmode))
- target = gen_reg_rtx (tmode);
-
- gcc_assert (nargs <= 4);
-
- for (i = 0; i < nargs; i++)
- {
- tree arg = CALL_EXPR_ARG (exp, i);
- rtx op = expand_normal (arg);
- int adjust = (comparison_p) ? 1 : 0;
- enum machine_mode mode = insn_data[icode].operand[i+adjust+1].mode;
-
- if (last_arg_constant && i == nargs - 1)
- {
- if (!insn_data[icode].operand[i + 1].predicate (op, mode))
- {
- enum insn_code new_icode = icode;
- switch (icode)
- {
- case CODE_FOR_xop_vpermil2v2df3:
- case CODE_FOR_xop_vpermil2v4sf3:
- case CODE_FOR_xop_vpermil2v4df3:
- case CODE_FOR_xop_vpermil2v8sf3:
- error ("the last argument must be a 2-bit immediate");
- return gen_reg_rtx (tmode);
- case CODE_FOR_xop_rotlv2di3:
- new_icode = CODE_FOR_rotlv2di3;
- goto xop_rotl;
- case CODE_FOR_xop_rotlv4si3:
- new_icode = CODE_FOR_rotlv4si3;
- goto xop_rotl;
- case CODE_FOR_xop_rotlv8hi3:
- new_icode = CODE_FOR_rotlv8hi3;
- goto xop_rotl;
- case CODE_FOR_xop_rotlv16qi3:
- new_icode = CODE_FOR_rotlv16qi3;
- xop_rotl:
- if (CONST_INT_P (op))
- {
- int mask = GET_MODE_BITSIZE (GET_MODE_INNER (tmode)) - 1;
- op = GEN_INT (INTVAL (op) & mask);
- gcc_checking_assert
- (insn_data[icode].operand[i + 1].predicate (op, mode));
- }
- else
- {
- gcc_checking_assert
- (nargs == 2
- && insn_data[new_icode].operand[0].mode == tmode
- && insn_data[new_icode].operand[1].mode == tmode
- && insn_data[new_icode].operand[2].mode == mode
- && insn_data[new_icode].operand[0].predicate
- == insn_data[icode].operand[0].predicate
- && insn_data[new_icode].operand[1].predicate
- == insn_data[icode].operand[1].predicate);
- icode = new_icode;
- goto non_constant;
- }
- break;
- default:
- gcc_unreachable ();
- }
- }
- }
- else
- {
- non_constant:
- if (VECTOR_MODE_P (mode))
- op = safe_vector_operand (op, mode);
-
- /* If we aren't optimizing, only allow one memory operand to be
- generated. */
- if (memory_operand (op, mode))
- num_memory++;
-
- gcc_assert (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode);
-
- if (optimize
- || !insn_data[icode].operand[i+adjust+1].predicate (op, mode)
- || num_memory > 1)
- op = force_reg (mode, op);
- }
-
- args[i].op = op;
- args[i].mode = mode;
- }
-
- switch (nargs)
- {
- case 1:
- pat = GEN_FCN (icode) (target, args[0].op);
- break;
-
- case 2:
- if (tf_p)
- pat = GEN_FCN (icode) (target, args[0].op, args[1].op,
- GEN_INT ((int)sub_code));
- else if (! comparison_p)
- pat = GEN_FCN (icode) (target, args[0].op, args[1].op);
- else
- {
- rtx cmp_op = gen_rtx_fmt_ee (sub_code, GET_MODE (target),
- args[0].op,
- args[1].op);
-
- pat = GEN_FCN (icode) (target, cmp_op, args[0].op, args[1].op);
- }
- break;
-
- case 3:
- pat = GEN_FCN (icode) (target, args[0].op, args[1].op, args[2].op);
- break;
-
- case 4:
- pat = GEN_FCN (icode) (target, args[0].op, args[1].op, args[2].op, args[3].op);
- break;
-
- default:
- gcc_unreachable ();
- }
-
- if (! pat)
- return 0;
-
- emit_insn (pat);
- return target;
-}
-
-/* Subroutine of ix86_expand_args_builtin to take care of scalar unop
- insns with vec_merge. */
-
-static rtx
-ix86_expand_unop_vec_merge_builtin (enum insn_code icode, tree exp,
- rtx target)
-{
- rtx pat;
- tree arg0 = CALL_EXPR_ARG (exp, 0);
- rtx op1, op0 = expand_normal (arg0);
- enum machine_mode tmode = insn_data[icode].operand[0].mode;
- enum machine_mode mode0 = insn_data[icode].operand[1].mode;
-
- if (optimize || !target
- || GET_MODE (target) != tmode
- || !insn_data[icode].operand[0].predicate (target, tmode))
- target = gen_reg_rtx (tmode);
-
- if (VECTOR_MODE_P (mode0))
- op0 = safe_vector_operand (op0, mode0);
-
- if ((optimize && !register_operand (op0, mode0))
- || !insn_data[icode].operand[1].predicate (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
-
- op1 = op0;
- if (!insn_data[icode].operand[2].predicate (op1, mode0))
- op1 = copy_to_mode_reg (mode0, op1);
-
- pat = GEN_FCN (icode) (target, op0, op1);
- if (! pat)
- return 0;
- emit_insn (pat);
- return target;
-}
-
-/* Subroutine of ix86_expand_builtin to take care of comparison insns. */
-
-static rtx
-ix86_expand_sse_compare (const struct builtin_description *d,
- tree exp, rtx target, bool swap)
-{
- 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);
- rtx op2;
- enum machine_mode tmode = insn_data[d->icode].operand[0].mode;
- enum machine_mode mode0 = insn_data[d->icode].operand[1].mode;
- enum machine_mode mode1 = insn_data[d->icode].operand[2].mode;
- enum rtx_code comparison = d->comparison;
-
- if (VECTOR_MODE_P (mode0))
- op0 = safe_vector_operand (op0, mode0);
- if (VECTOR_MODE_P (mode1))
- op1 = safe_vector_operand (op1, mode1);
-
- /* Swap operands if we have a comparison that isn't available in
- hardware. */
- if (swap)
- {
- rtx tmp = gen_reg_rtx (mode1);
- emit_move_insn (tmp, op1);
- op1 = op0;
- op0 = tmp;
- }
-
- if (optimize || !target
- || GET_MODE (target) != tmode
- || !insn_data[d->icode].operand[0].predicate (target, tmode))
- target = gen_reg_rtx (tmode);
-
- if ((optimize && !register_operand (op0, mode0))
- || !insn_data[d->icode].operand[1].predicate (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
- if ((optimize && !register_operand (op1, mode1))
- || !insn_data[d->icode].operand[2].predicate (op1, mode1))
- op1 = copy_to_mode_reg (mode1, op1);
-
- op2 = gen_rtx_fmt_ee (comparison, mode0, op0, op1);
- pat = GEN_FCN (d->icode) (target, op0, op1, op2);
- if (! pat)
- return 0;
- emit_insn (pat);
- return target;
-}
-
-/* Subroutine of ix86_expand_builtin to take care of comi insns. */
-
-static rtx
-ix86_expand_sse_comi (const struct builtin_description *d, 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 mode0 = insn_data[d->icode].operand[0].mode;
- enum machine_mode mode1 = insn_data[d->icode].operand[1].mode;
- enum rtx_code comparison = d->comparison;
-
- if (VECTOR_MODE_P (mode0))
- op0 = safe_vector_operand (op0, mode0);
- if (VECTOR_MODE_P (mode1))
- op1 = safe_vector_operand (op1, mode1);
-
- /* Swap operands if we have a comparison that isn't available in
- hardware. */
- if (d->flag & BUILTIN_DESC_SWAP_OPERANDS)
- {
- rtx tmp = op1;
- op1 = op0;
- op0 = tmp;
- }
-
- target = gen_reg_rtx (SImode);
- emit_move_insn (target, const0_rtx);
- target = gen_rtx_SUBREG (QImode, target, 0);
-
- if ((optimize && !register_operand (op0, mode0))
- || !insn_data[d->icode].operand[0].predicate (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
- if ((optimize && !register_operand (op1, mode1))
- || !insn_data[d->icode].operand[1].predicate (op1, mode1))
- op1 = copy_to_mode_reg (mode1, op1);
-
- pat = GEN_FCN (d->icode) (op0, op1);
- if (! pat)
- return 0;
- emit_insn (pat);
- emit_insn (gen_rtx_SET (VOIDmode,
- gen_rtx_STRICT_LOW_PART (VOIDmode, target),
- gen_rtx_fmt_ee (comparison, QImode,
- SET_DEST (pat),
- const0_rtx)));
-
- return SUBREG_REG (target);
-}
-
-/* Subroutines of ix86_expand_args_builtin to take care of round insns. */
-
-static rtx
-ix86_expand_sse_round (const struct builtin_description *d, tree exp,
- rtx target)
-{
- rtx pat;
- tree arg0 = CALL_EXPR_ARG (exp, 0);
- rtx op1, op0 = expand_normal (arg0);
- enum machine_mode tmode = insn_data[d->icode].operand[0].mode;
- enum machine_mode mode0 = insn_data[d->icode].operand[1].mode;
-
- if (optimize || target == 0
- || GET_MODE (target) != tmode
- || !insn_data[d->icode].operand[0].predicate (target, tmode))
- target = gen_reg_rtx (tmode);
-
- if (VECTOR_MODE_P (mode0))
- op0 = safe_vector_operand (op0, mode0);
-
- if ((optimize && !register_operand (op0, mode0))
- || !insn_data[d->icode].operand[0].predicate (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
-
- op1 = GEN_INT (d->comparison);
-
- pat = GEN_FCN (d->icode) (target, op0, op1);
- if (! pat)
- return 0;
- emit_insn (pat);
- return target;
-}
-
-static rtx
-ix86_expand_sse_round_vec_pack_sfix (const struct builtin_description *d,
- 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);
- rtx op2;
- enum machine_mode tmode = insn_data[d->icode].operand[0].mode;
- enum machine_mode mode0 = insn_data[d->icode].operand[1].mode;
- enum machine_mode mode1 = insn_data[d->icode].operand[2].mode;
-
- if (optimize || target == 0
- || GET_MODE (target) != tmode
- || !insn_data[d->icode].operand[0].predicate (target, tmode))
- target = gen_reg_rtx (tmode);
-
- op0 = safe_vector_operand (op0, mode0);
- op1 = safe_vector_operand (op1, mode1);
-
- if ((optimize && !register_operand (op0, mode0))
- || !insn_data[d->icode].operand[0].predicate (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
- if ((optimize && !register_operand (op1, mode1))
- || !insn_data[d->icode].operand[1].predicate (op1, mode1))
- op1 = copy_to_mode_reg (mode1, op1);
-
- op2 = GEN_INT (d->comparison);
-
- pat = GEN_FCN (d->icode) (target, op0, op1, op2);
- if (! pat)
- return 0;
- emit_insn (pat);
- return target;
-}
-
-/* Subroutine of ix86_expand_builtin to take care of ptest insns. */
-
-static rtx
-ix86_expand_sse_ptest (const struct builtin_description *d, 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 mode0 = insn_data[d->icode].operand[0].mode;
- enum machine_mode mode1 = insn_data[d->icode].operand[1].mode;
- enum rtx_code comparison = d->comparison;
-
- if (VECTOR_MODE_P (mode0))
- op0 = safe_vector_operand (op0, mode0);
- if (VECTOR_MODE_P (mode1))
- op1 = safe_vector_operand (op1, mode1);
-
- target = gen_reg_rtx (SImode);
- emit_move_insn (target, const0_rtx);
- target = gen_rtx_SUBREG (QImode, target, 0);
-
- if ((optimize && !register_operand (op0, mode0))
- || !insn_data[d->icode].operand[0].predicate (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
- if ((optimize && !register_operand (op1, mode1))
- || !insn_data[d->icode].operand[1].predicate (op1, mode1))
- op1 = copy_to_mode_reg (mode1, op1);
-
- pat = GEN_FCN (d->icode) (op0, op1);
- if (! pat)
- return 0;
- emit_insn (pat);
- emit_insn (gen_rtx_SET (VOIDmode,
- gen_rtx_STRICT_LOW_PART (VOIDmode, target),
- gen_rtx_fmt_ee (comparison, QImode,
- SET_DEST (pat),
- const0_rtx)));
-
- return SUBREG_REG (target);
-}
-
-/* Subroutine of ix86_expand_builtin to take care of pcmpestr[im] insns. */
-
-static rtx
-ix86_expand_sse_pcmpestr (const struct builtin_description *d,
- tree exp, rtx target)
-{
- rtx pat;
- tree arg0 = CALL_EXPR_ARG (exp, 0);
- tree arg1 = CALL_EXPR_ARG (exp, 1);
- tree arg2 = CALL_EXPR_ARG (exp, 2);
- tree arg3 = CALL_EXPR_ARG (exp, 3);
- tree arg4 = CALL_EXPR_ARG (exp, 4);
- rtx scratch0, scratch1;
- rtx op0 = expand_normal (arg0);
- rtx op1 = expand_normal (arg1);
- rtx op2 = expand_normal (arg2);
- rtx op3 = expand_normal (arg3);
- rtx op4 = expand_normal (arg4);
- enum machine_mode tmode0, tmode1, modev2, modei3, modev4, modei5, modeimm;
-
- tmode0 = insn_data[d->icode].operand[0].mode;
- tmode1 = insn_data[d->icode].operand[1].mode;
- modev2 = insn_data[d->icode].operand[2].mode;
- modei3 = insn_data[d->icode].operand[3].mode;
- modev4 = insn_data[d->icode].operand[4].mode;
- modei5 = insn_data[d->icode].operand[5].mode;
- modeimm = insn_data[d->icode].operand[6].mode;
-
- if (VECTOR_MODE_P (modev2))
- op0 = safe_vector_operand (op0, modev2);
- if (VECTOR_MODE_P (modev4))
- op2 = safe_vector_operand (op2, modev4);
-
- if (!insn_data[d->icode].operand[2].predicate (op0, modev2))
- op0 = copy_to_mode_reg (modev2, op0);
- if (!insn_data[d->icode].operand[3].predicate (op1, modei3))
- op1 = copy_to_mode_reg (modei3, op1);
- if ((optimize && !register_operand (op2, modev4))
- || !insn_data[d->icode].operand[4].predicate (op2, modev4))
- op2 = copy_to_mode_reg (modev4, op2);
- if (!insn_data[d->icode].operand[5].predicate (op3, modei5))
- op3 = copy_to_mode_reg (modei5, op3);
-
- if (!insn_data[d->icode].operand[6].predicate (op4, modeimm))
- {
- error ("the fifth argument must be an 8-bit immediate");
- return const0_rtx;
- }
-
- if (d->code == IX86_BUILTIN_PCMPESTRI128)
- {
- if (optimize || !target
- || GET_MODE (target) != tmode0
- || !insn_data[d->icode].operand[0].predicate (target, tmode0))
- target = gen_reg_rtx (tmode0);
-
- scratch1 = gen_reg_rtx (tmode1);
-
- pat = GEN_FCN (d->icode) (target, scratch1, op0, op1, op2, op3, op4);
- }
- else if (d->code == IX86_BUILTIN_PCMPESTRM128)
- {
- if (optimize || !target
- || GET_MODE (target) != tmode1
- || !insn_data[d->icode].operand[1].predicate (target, tmode1))
- target = gen_reg_rtx (tmode1);
-
- scratch0 = gen_reg_rtx (tmode0);
-
- pat = GEN_FCN (d->icode) (scratch0, target, op0, op1, op2, op3, op4);
- }
- else
- {
- gcc_assert (d->flag);
-
- scratch0 = gen_reg_rtx (tmode0);
- scratch1 = gen_reg_rtx (tmode1);
-
- pat = GEN_FCN (d->icode) (scratch0, scratch1, op0, op1, op2, op3, op4);
- }
-
- if (! pat)
- return 0;
-
- emit_insn (pat);
-
- if (d->flag)
- {
- target = gen_reg_rtx (SImode);
- emit_move_insn (target, const0_rtx);
- target = gen_rtx_SUBREG (QImode, target, 0);
-
- emit_insn
- (gen_rtx_SET (VOIDmode, gen_rtx_STRICT_LOW_PART (VOIDmode, target),
- gen_rtx_fmt_ee (EQ, QImode,
- gen_rtx_REG ((enum machine_mode) d->flag,
- FLAGS_REG),
- const0_rtx)));
- return SUBREG_REG (target);
- }
- else
- return target;
-}
-
-
-/* Subroutine of ix86_expand_builtin to take care of pcmpistr[im] insns. */
-
-static rtx
-ix86_expand_sse_pcmpistr (const struct builtin_description *d,
- tree exp, rtx target)
-{
- rtx pat;
- tree arg0 = CALL_EXPR_ARG (exp, 0);
- tree arg1 = CALL_EXPR_ARG (exp, 1);
- tree arg2 = CALL_EXPR_ARG (exp, 2);
- rtx scratch0, scratch1;
- rtx op0 = expand_normal (arg0);
- rtx op1 = expand_normal (arg1);
- rtx op2 = expand_normal (arg2);
- enum machine_mode tmode0, tmode1, modev2, modev3, modeimm;
-
- tmode0 = insn_data[d->icode].operand[0].mode;
- tmode1 = insn_data[d->icode].operand[1].mode;
- modev2 = insn_data[d->icode].operand[2].mode;
- modev3 = insn_data[d->icode].operand[3].mode;
- modeimm = insn_data[d->icode].operand[4].mode;
-
- if (VECTOR_MODE_P (modev2))
- op0 = safe_vector_operand (op0, modev2);
- if (VECTOR_MODE_P (modev3))
- op1 = safe_vector_operand (op1, modev3);
-
- if (!insn_data[d->icode].operand[2].predicate (op0, modev2))
- op0 = copy_to_mode_reg (modev2, op0);
- if ((optimize && !register_operand (op1, modev3))
- || !insn_data[d->icode].operand[3].predicate (op1, modev3))
- op1 = copy_to_mode_reg (modev3, op1);
-
- if (!insn_data[d->icode].operand[4].predicate (op2, modeimm))
- {
- error ("the third argument must be an 8-bit immediate");
- return const0_rtx;
- }
-
- if (d->code == IX86_BUILTIN_PCMPISTRI128)
- {
- if (optimize || !target
- || GET_MODE (target) != tmode0
- || !insn_data[d->icode].operand[0].predicate (target, tmode0))
- target = gen_reg_rtx (tmode0);
-
- scratch1 = gen_reg_rtx (tmode1);
-
- pat = GEN_FCN (d->icode) (target, scratch1, op0, op1, op2);
- }
- else if (d->code == IX86_BUILTIN_PCMPISTRM128)
- {
- if (optimize || !target
- || GET_MODE (target) != tmode1
- || !insn_data[d->icode].operand[1].predicate (target, tmode1))
- target = gen_reg_rtx (tmode1);
-
- scratch0 = gen_reg_rtx (tmode0);
-
- pat = GEN_FCN (d->icode) (scratch0, target, op0, op1, op2);
- }
- else
- {
- gcc_assert (d->flag);
-
- scratch0 = gen_reg_rtx (tmode0);
- scratch1 = gen_reg_rtx (tmode1);
-
- pat = GEN_FCN (d->icode) (scratch0, scratch1, op0, op1, op2);
- }
-
- if (! pat)
- return 0;
-
- emit_insn (pat);
-
- if (d->flag)
- {
- target = gen_reg_rtx (SImode);
- emit_move_insn (target, const0_rtx);
- target = gen_rtx_SUBREG (QImode, target, 0);
-
- emit_insn
- (gen_rtx_SET (VOIDmode, gen_rtx_STRICT_LOW_PART (VOIDmode, target),
- gen_rtx_fmt_ee (EQ, QImode,
- gen_rtx_REG ((enum machine_mode) d->flag,
- FLAGS_REG),
- const0_rtx)));
- return SUBREG_REG (target);
- }
- else
- return target;
-}
-
-/* Subroutine of ix86_expand_builtin to take care of insns with
- variable number of operands. */
-
-static rtx
-ix86_expand_args_builtin (const struct builtin_description *d,
- tree exp, rtx target)
-{
- rtx pat, real_target;
- unsigned int i, nargs;
- unsigned int nargs_constant = 0;
- int num_memory = 0;
- struct
- {
- rtx op;
- enum machine_mode mode;
- } args[4];
- bool last_arg_count = false;
- enum insn_code icode = d->icode;
- const struct insn_data_d *insn_p = &insn_data[icode];
- enum machine_mode tmode = insn_p->operand[0].mode;
- enum machine_mode rmode = VOIDmode;
- bool swap = false;
- enum rtx_code comparison = d->comparison;
-
- switch ((enum ix86_builtin_func_type) d->flag)
- {
- case V2DF_FTYPE_V2DF_ROUND:
- case V4DF_FTYPE_V4DF_ROUND:
- case V4SF_FTYPE_V4SF_ROUND:
- case V8SF_FTYPE_V8SF_ROUND:
- case V4SI_FTYPE_V4SF_ROUND:
- case V8SI_FTYPE_V8SF_ROUND:
- return ix86_expand_sse_round (d, exp, target);
- case V4SI_FTYPE_V2DF_V2DF_ROUND:
- case V8SI_FTYPE_V4DF_V4DF_ROUND:
- return ix86_expand_sse_round_vec_pack_sfix (d, exp, target);
- case INT_FTYPE_V8SF_V8SF_PTEST:
- case INT_FTYPE_V4DI_V4DI_PTEST:
- case INT_FTYPE_V4DF_V4DF_PTEST:
- case INT_FTYPE_V4SF_V4SF_PTEST:
- case INT_FTYPE_V2DI_V2DI_PTEST:
- case INT_FTYPE_V2DF_V2DF_PTEST:
- return ix86_expand_sse_ptest (d, exp, target);
- case FLOAT128_FTYPE_FLOAT128:
- case FLOAT_FTYPE_FLOAT:
- case INT_FTYPE_INT:
- case UINT64_FTYPE_INT:
- case UINT16_FTYPE_UINT16:
- case INT64_FTYPE_INT64:
- case INT64_FTYPE_V4SF:
- case INT64_FTYPE_V2DF:
- case INT_FTYPE_V16QI:
- case INT_FTYPE_V8QI:
- case INT_FTYPE_V8SF:
- case INT_FTYPE_V4DF:
- case INT_FTYPE_V4SF:
- case INT_FTYPE_V2DF:
- case INT_FTYPE_V32QI:
- case V16QI_FTYPE_V16QI:
- case V8SI_FTYPE_V8SF:
- case V8SI_FTYPE_V4SI:
- case V8HI_FTYPE_V8HI:
- case V8HI_FTYPE_V16QI:
- case V8QI_FTYPE_V8QI:
- case V8SF_FTYPE_V8SF:
- case V8SF_FTYPE_V8SI:
- case V8SF_FTYPE_V4SF:
- case V8SF_FTYPE_V8HI:
- case V4SI_FTYPE_V4SI:
- case V4SI_FTYPE_V16QI:
- case V4SI_FTYPE_V4SF:
- case V4SI_FTYPE_V8SI:
- case V4SI_FTYPE_V8HI:
- case V4SI_FTYPE_V4DF:
- case V4SI_FTYPE_V2DF:
- case V4HI_FTYPE_V4HI:
- case V4DF_FTYPE_V4DF:
- case V4DF_FTYPE_V4SI:
- case V4DF_FTYPE_V4SF:
- case V4DF_FTYPE_V2DF:
- case V4SF_FTYPE_V4SF:
- case V4SF_FTYPE_V4SI:
- case V4SF_FTYPE_V8SF:
- case V4SF_FTYPE_V4DF:
- case V4SF_FTYPE_V8HI:
- case V4SF_FTYPE_V2DF:
- case V2DI_FTYPE_V2DI:
- case V2DI_FTYPE_V16QI:
- case V2DI_FTYPE_V8HI:
- case V2DI_FTYPE_V4SI:
- case V2DF_FTYPE_V2DF:
- case V2DF_FTYPE_V4SI:
- case V2DF_FTYPE_V4DF:
- case V2DF_FTYPE_V4SF:
- case V2DF_FTYPE_V2SI:
- case V2SI_FTYPE_V2SI:
- case V2SI_FTYPE_V4SF:
- case V2SI_FTYPE_V2SF:
- case V2SI_FTYPE_V2DF:
- case V2SF_FTYPE_V2SF:
- case V2SF_FTYPE_V2SI:
- case V32QI_FTYPE_V32QI:
- case V32QI_FTYPE_V16QI:
- case V16HI_FTYPE_V16HI:
- case V16HI_FTYPE_V8HI:
- case V8SI_FTYPE_V8SI:
- case V16HI_FTYPE_V16QI:
- case V8SI_FTYPE_V16QI:
- case V4DI_FTYPE_V16QI:
- case V8SI_FTYPE_V8HI:
- case V4DI_FTYPE_V8HI:
- case V4DI_FTYPE_V4SI:
- case V4DI_FTYPE_V2DI:
- nargs = 1;
- break;
- case V4SF_FTYPE_V4SF_VEC_MERGE:
- case V2DF_FTYPE_V2DF_VEC_MERGE:
- return ix86_expand_unop_vec_merge_builtin (icode, exp, target);
- case FLOAT128_FTYPE_FLOAT128_FLOAT128:
- case V16QI_FTYPE_V16QI_V16QI:
- case V16QI_FTYPE_V8HI_V8HI:
- case V8QI_FTYPE_V8QI_V8QI:
- case V8QI_FTYPE_V4HI_V4HI:
- case V8HI_FTYPE_V8HI_V8HI:
- case V8HI_FTYPE_V16QI_V16QI:
- case V8HI_FTYPE_V4SI_V4SI:
- case V8SF_FTYPE_V8SF_V8SF:
- case V8SF_FTYPE_V8SF_V8SI:
- case V4SI_FTYPE_V4SI_V4SI:
- case V4SI_FTYPE_V8HI_V8HI:
- case V4SI_FTYPE_V4SF_V4SF:
- case V4SI_FTYPE_V2DF_V2DF:
- case V4HI_FTYPE_V4HI_V4HI:
- case V4HI_FTYPE_V8QI_V8QI:
- case V4HI_FTYPE_V2SI_V2SI:
- case V4DF_FTYPE_V4DF_V4DF:
- case V4DF_FTYPE_V4DF_V4DI:
- case V4SF_FTYPE_V4SF_V4SF:
- case V4SF_FTYPE_V4SF_V4SI:
- case V4SF_FTYPE_V4SF_V2SI:
- case V4SF_FTYPE_V4SF_V2DF:
- case V4SF_FTYPE_V4SF_DI:
- case V4SF_FTYPE_V4SF_SI:
- case V2DI_FTYPE_V2DI_V2DI:
- case V2DI_FTYPE_V16QI_V16QI:
- case V2DI_FTYPE_V4SI_V4SI:
- case V2UDI_FTYPE_V4USI_V4USI:
- case V2DI_FTYPE_V2DI_V16QI:
- case V2DI_FTYPE_V2DF_V2DF:
- case V2SI_FTYPE_V2SI_V2SI:
- case V2SI_FTYPE_V4HI_V4HI:
- case V2SI_FTYPE_V2SF_V2SF:
- case V2DF_FTYPE_V2DF_V2DF:
- case V2DF_FTYPE_V2DF_V4SF:
- case V2DF_FTYPE_V2DF_V2DI:
- case V2DF_FTYPE_V2DF_DI:
- case V2DF_FTYPE_V2DF_SI:
- case V2SF_FTYPE_V2SF_V2SF:
- case V1DI_FTYPE_V1DI_V1DI:
- case V1DI_FTYPE_V8QI_V8QI:
- case V1DI_FTYPE_V2SI_V2SI:
- case V32QI_FTYPE_V16HI_V16HI:
- case V16HI_FTYPE_V8SI_V8SI:
- case V32QI_FTYPE_V32QI_V32QI:
- case V16HI_FTYPE_V32QI_V32QI:
- case V16HI_FTYPE_V16HI_V16HI:
- case V8SI_FTYPE_V4DF_V4DF:
- case V8SI_FTYPE_V8SI_V8SI:
- case V8SI_FTYPE_V16HI_V16HI:
- case V4DI_FTYPE_V4DI_V4DI:
- case V4DI_FTYPE_V8SI_V8SI:
- case V4UDI_FTYPE_V8USI_V8USI:
- if (comparison == UNKNOWN)
- return ix86_expand_binop_builtin (icode, exp, target);
- nargs = 2;
- break;
- case V4SF_FTYPE_V4SF_V4SF_SWAP:
- case V2DF_FTYPE_V2DF_V2DF_SWAP:
- gcc_assert (comparison != UNKNOWN);
- nargs = 2;
- swap = true;
- break;
- case V16HI_FTYPE_V16HI_V8HI_COUNT:
- case V16HI_FTYPE_V16HI_SI_COUNT:
- case V8SI_FTYPE_V8SI_V4SI_COUNT:
- case V8SI_FTYPE_V8SI_SI_COUNT:
- case V4DI_FTYPE_V4DI_V2DI_COUNT:
- case V4DI_FTYPE_V4DI_INT_COUNT:
- case V8HI_FTYPE_V8HI_V8HI_COUNT:
- case V8HI_FTYPE_V8HI_SI_COUNT:
- case V4SI_FTYPE_V4SI_V4SI_COUNT:
- case V4SI_FTYPE_V4SI_SI_COUNT:
- case V4HI_FTYPE_V4HI_V4HI_COUNT:
- case V4HI_FTYPE_V4HI_SI_COUNT:
- case V2DI_FTYPE_V2DI_V2DI_COUNT:
- case V2DI_FTYPE_V2DI_SI_COUNT:
- case V2SI_FTYPE_V2SI_V2SI_COUNT:
- case V2SI_FTYPE_V2SI_SI_COUNT:
- case V1DI_FTYPE_V1DI_V1DI_COUNT:
- case V1DI_FTYPE_V1DI_SI_COUNT:
- nargs = 2;
- last_arg_count = true;
- break;
- case UINT64_FTYPE_UINT64_UINT64:
- case UINT_FTYPE_UINT_UINT:
- case UINT_FTYPE_UINT_USHORT:
- case UINT_FTYPE_UINT_UCHAR:
- case UINT16_FTYPE_UINT16_INT:
- case UINT8_FTYPE_UINT8_INT:
- nargs = 2;
- break;
- case V2DI_FTYPE_V2DI_INT_CONVERT:
- nargs = 2;
- rmode = V1TImode;
- nargs_constant = 1;
- break;
- case V4DI_FTYPE_V4DI_INT_CONVERT:
- nargs = 2;
- rmode = V2TImode;
- nargs_constant = 1;
- break;
- case V8HI_FTYPE_V8HI_INT:
- case V8HI_FTYPE_V8SF_INT:
- case V8HI_FTYPE_V4SF_INT:
- case V8SF_FTYPE_V8SF_INT:
- case V4SI_FTYPE_V4SI_INT:
- case V4SI_FTYPE_V8SI_INT:
- case V4HI_FTYPE_V4HI_INT:
- case V4DF_FTYPE_V4DF_INT:
- case V4SF_FTYPE_V4SF_INT:
- case V4SF_FTYPE_V8SF_INT:
- case V2DI_FTYPE_V2DI_INT:
- case V2DF_FTYPE_V2DF_INT:
- case V2DF_FTYPE_V4DF_INT:
- case V16HI_FTYPE_V16HI_INT:
- case V8SI_FTYPE_V8SI_INT:
- case V4DI_FTYPE_V4DI_INT:
- case V2DI_FTYPE_V4DI_INT:
- nargs = 2;
- nargs_constant = 1;
- break;
- case V16QI_FTYPE_V16QI_V16QI_V16QI:
- case V8SF_FTYPE_V8SF_V8SF_V8SF:
- case V4DF_FTYPE_V4DF_V4DF_V4DF:
- case V4SF_FTYPE_V4SF_V4SF_V4SF:
- case V2DF_FTYPE_V2DF_V2DF_V2DF:
- case V32QI_FTYPE_V32QI_V32QI_V32QI:
- nargs = 3;
- break;
- case V32QI_FTYPE_V32QI_V32QI_INT:
- case V16HI_FTYPE_V16HI_V16HI_INT:
- case V16QI_FTYPE_V16QI_V16QI_INT:
- case V4DI_FTYPE_V4DI_V4DI_INT:
- case V8HI_FTYPE_V8HI_V8HI_INT:
- case V8SI_FTYPE_V8SI_V8SI_INT:
- case V8SI_FTYPE_V8SI_V4SI_INT:
- case V8SF_FTYPE_V8SF_V8SF_INT:
- case V8SF_FTYPE_V8SF_V4SF_INT:
- case V4SI_FTYPE_V4SI_V4SI_INT:
- case V4DF_FTYPE_V4DF_V4DF_INT:
- case V4DF_FTYPE_V4DF_V2DF_INT:
- case V4SF_FTYPE_V4SF_V4SF_INT:
- case V2DI_FTYPE_V2DI_V2DI_INT:
- case V4DI_FTYPE_V4DI_V2DI_INT:
- case V2DF_FTYPE_V2DF_V2DF_INT:
- nargs = 3;
- nargs_constant = 1;
- break;
- case V4DI_FTYPE_V4DI_V4DI_INT_CONVERT:
- nargs = 3;
- rmode = V4DImode;
- nargs_constant = 1;
- break;
- case V2DI_FTYPE_V2DI_V2DI_INT_CONVERT:
- nargs = 3;
- rmode = V2DImode;
- nargs_constant = 1;
- break;
- case V1DI_FTYPE_V1DI_V1DI_INT_CONVERT:
- nargs = 3;
- rmode = DImode;
- nargs_constant = 1;
- break;
- case V2DI_FTYPE_V2DI_UINT_UINT:
- nargs = 3;
- nargs_constant = 2;
- break;
- case V2DF_FTYPE_V2DF_V2DF_V2DI_INT:
- case V4DF_FTYPE_V4DF_V4DF_V4DI_INT:
- case V4SF_FTYPE_V4SF_V4SF_V4SI_INT:
- case V8SF_FTYPE_V8SF_V8SF_V8SI_INT:
- nargs = 4;
- nargs_constant = 1;
- break;
- case V2DI_FTYPE_V2DI_V2DI_UINT_UINT:
- nargs = 4;
- nargs_constant = 2;
- break;
- case UCHAR_FTYPE_UCHAR_UINT_UINT_PUNSIGNED:
- case UCHAR_FTYPE_UCHAR_ULONGLONG_ULONGLONG_PULONGLONG:
- nargs = 4;
- break;
- default:
- gcc_unreachable ();
- }
-
- gcc_assert (nargs <= ARRAY_SIZE (args));
-
- if (comparison != UNKNOWN)
- {
- gcc_assert (nargs == 2);
- return ix86_expand_sse_compare (d, exp, target, swap);
- }
-
- if (rmode == VOIDmode || rmode == tmode)
- {
- if (optimize
- || target == 0
- || GET_MODE (target) != tmode
- || !insn_p->operand[0].predicate (target, tmode))
- target = gen_reg_rtx (tmode);
- real_target = target;
- }
- else
- {
- target = gen_reg_rtx (rmode);
- real_target = simplify_gen_subreg (tmode, target, rmode, 0);
- }
-
- for (i = 0; i < nargs; i++)
- {
- tree arg = CALL_EXPR_ARG (exp, i);
- rtx op = expand_normal (arg);
- enum machine_mode mode = insn_p->operand[i + 1].mode;
- bool match = insn_p->operand[i + 1].predicate (op, mode);
-
- if (last_arg_count && (i + 1) == nargs)
- {
- /* SIMD shift insns take either an 8-bit immediate or
- register as count. But builtin functions take int as
- count. If count doesn't match, we put it in register. */
- if (!match)
- {
- op = simplify_gen_subreg (SImode, op, GET_MODE (op), 0);
- if (!insn_p->operand[i + 1].predicate (op, mode))
- op = copy_to_reg (op);
- }
- }
- else if ((nargs - i) <= nargs_constant)
- {
- if (!match)
- switch (icode)
- {
- case CODE_FOR_avx2_inserti128:
- case CODE_FOR_avx2_extracti128:
- error ("the last argument must be an 1-bit immediate");
- return const0_rtx;
-
- case CODE_FOR_sse4_1_roundsd:
- case CODE_FOR_sse4_1_roundss:
-
- case CODE_FOR_sse4_1_roundpd:
- case CODE_FOR_sse4_1_roundps:
- case CODE_FOR_avx_roundpd256:
- case CODE_FOR_avx_roundps256:
-
- case CODE_FOR_sse4_1_roundpd_vec_pack_sfix:
- case CODE_FOR_sse4_1_roundps_sfix:
- case CODE_FOR_avx_roundpd_vec_pack_sfix256:
- case CODE_FOR_avx_roundps_sfix256:
-
- case CODE_FOR_sse4_1_blendps:
- case CODE_FOR_avx_blendpd256:
- case CODE_FOR_avx_vpermilv4df:
- error ("the last argument must be a 4-bit immediate");
- return const0_rtx;
-
- case CODE_FOR_sse4_1_blendpd:
- case CODE_FOR_avx_vpermilv2df:
- case CODE_FOR_xop_vpermil2v2df3:
- case CODE_FOR_xop_vpermil2v4sf3:
- case CODE_FOR_xop_vpermil2v4df3:
- case CODE_FOR_xop_vpermil2v8sf3:
- error ("the last argument must be a 2-bit immediate");
- return const0_rtx;
-
- case CODE_FOR_avx_vextractf128v4df:
- case CODE_FOR_avx_vextractf128v8sf:
- case CODE_FOR_avx_vextractf128v8si:
- case CODE_FOR_avx_vinsertf128v4df:
- case CODE_FOR_avx_vinsertf128v8sf:
- case CODE_FOR_avx_vinsertf128v8si:
- error ("the last argument must be a 1-bit immediate");
- return const0_rtx;
-
- case CODE_FOR_avx_vmcmpv2df3:
- case CODE_FOR_avx_vmcmpv4sf3:
- case CODE_FOR_avx_cmpv2df3:
- case CODE_FOR_avx_cmpv4sf3:
- case CODE_FOR_avx_cmpv4df3:
- case CODE_FOR_avx_cmpv8sf3:
- error ("the last argument must be a 5-bit immediate");
- return const0_rtx;
-
- default:
- switch (nargs_constant)
- {
- case 2:
- if ((nargs - i) == nargs_constant)
- {
- error ("the next to last argument must be an 8-bit immediate");
- break;
- }
- case 1:
- error ("the last argument must be an 8-bit immediate");
- break;
- default:
- gcc_unreachable ();
- }
- return const0_rtx;
- }
- }
- else
- {
- if (VECTOR_MODE_P (mode))
- op = safe_vector_operand (op, mode);
-
- /* If we aren't optimizing, only allow one memory operand to
- be generated. */
- if (memory_operand (op, mode))
- num_memory++;
-
- if (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode)
- {
- if (optimize || !match || num_memory > 1)
- op = copy_to_mode_reg (mode, op);
- }
- else
- {
- op = copy_to_reg (op);
- op = simplify_gen_subreg (mode, op, GET_MODE (op), 0);
- }
- }
-
- args[i].op = op;
- args[i].mode = mode;
- }
-
- switch (nargs)
- {
- case 1:
- pat = GEN_FCN (icode) (real_target, args[0].op);
- break;
- case 2:
- pat = GEN_FCN (icode) (real_target, args[0].op, args[1].op);
- break;
- case 3:
- pat = GEN_FCN (icode) (real_target, args[0].op, args[1].op,
- args[2].op);
- break;
- case 4:
- pat = GEN_FCN (icode) (real_target, args[0].op, args[1].op,
- args[2].op, args[3].op);
- break;
- default:
- gcc_unreachable ();
- }
-
- if (! pat)
- return 0;
-
- emit_insn (pat);
- return target;
-}
-
-/* Subroutine of ix86_expand_builtin to take care of special insns
- with variable number of operands. */
-
-static rtx
-ix86_expand_special_args_builtin (const struct builtin_description *d,
- tree exp, rtx target)
-{
- tree arg;
- rtx pat, op;
- unsigned int i, nargs, arg_adjust, memory;
- struct
- {
- rtx op;
- enum machine_mode mode;
- } args[3];
- enum insn_code icode = d->icode;
- bool last_arg_constant = false;
- const struct insn_data_d *insn_p = &insn_data[icode];
- enum machine_mode tmode = insn_p->operand[0].mode;
- enum { load, store } klass;
-
- switch ((enum ix86_builtin_func_type) d->flag)
- {
- case VOID_FTYPE_VOID:
- emit_insn (GEN_FCN (icode) (target));
- return 0;
- case VOID_FTYPE_UINT64:
- case VOID_FTYPE_UNSIGNED:
- nargs = 0;
- klass = store;
- memory = 0;
- break;
-
- case INT_FTYPE_VOID:
- case UINT64_FTYPE_VOID:
- case UNSIGNED_FTYPE_VOID:
- nargs = 0;
- klass = load;
- memory = 0;
- break;
- case UINT64_FTYPE_PUNSIGNED:
- case V2DI_FTYPE_PV2DI:
- case V4DI_FTYPE_PV4DI:
- case V32QI_FTYPE_PCCHAR:
- case V16QI_FTYPE_PCCHAR:
- case V8SF_FTYPE_PCV4SF:
- case V8SF_FTYPE_PCFLOAT:
- case V4SF_FTYPE_PCFLOAT:
- case V4DF_FTYPE_PCV2DF:
- case V4DF_FTYPE_PCDOUBLE:
- case V2DF_FTYPE_PCDOUBLE:
- case VOID_FTYPE_PVOID:
- nargs = 1;
- klass = load;
- memory = 0;
- break;
- case VOID_FTYPE_PV2SF_V4SF:
- case VOID_FTYPE_PV4DI_V4DI:
- case VOID_FTYPE_PV2DI_V2DI:
- case VOID_FTYPE_PCHAR_V32QI:
- case VOID_FTYPE_PCHAR_V16QI:
- case VOID_FTYPE_PFLOAT_V8SF:
- case VOID_FTYPE_PFLOAT_V4SF:
- case VOID_FTYPE_PDOUBLE_V4DF:
- case VOID_FTYPE_PDOUBLE_V2DF:
- case VOID_FTYPE_PLONGLONG_LONGLONG:
- case VOID_FTYPE_PULONGLONG_ULONGLONG:
- case VOID_FTYPE_PINT_INT:
- nargs = 1;
- klass = store;
- /* Reserve memory operand for target. */
- memory = ARRAY_SIZE (args);
- break;
- case V4SF_FTYPE_V4SF_PCV2SF:
- case V2DF_FTYPE_V2DF_PCDOUBLE:
- nargs = 2;
- klass = load;
- memory = 1;
- break;
- case V8SF_FTYPE_PCV8SF_V8SI:
- case V4DF_FTYPE_PCV4DF_V4DI:
- case V4SF_FTYPE_PCV4SF_V4SI:
- case V2DF_FTYPE_PCV2DF_V2DI:
- case V8SI_FTYPE_PCV8SI_V8SI:
- case V4DI_FTYPE_PCV4DI_V4DI:
- case V4SI_FTYPE_PCV4SI_V4SI:
- case V2DI_FTYPE_PCV2DI_V2DI:
- nargs = 2;
- klass = load;
- memory = 0;
- break;
- case VOID_FTYPE_PV8SF_V8SI_V8SF:
- case VOID_FTYPE_PV4DF_V4DI_V4DF:
- case VOID_FTYPE_PV4SF_V4SI_V4SF:
- case VOID_FTYPE_PV2DF_V2DI_V2DF:
- case VOID_FTYPE_PV8SI_V8SI_V8SI:
- case VOID_FTYPE_PV4DI_V4DI_V4DI:
- case VOID_FTYPE_PV4SI_V4SI_V4SI:
- case VOID_FTYPE_PV2DI_V2DI_V2DI:
- nargs = 2;
- klass = store;
- /* Reserve memory operand for target. */
- memory = ARRAY_SIZE (args);
- break;
- case VOID_FTYPE_UINT_UINT_UINT:
- case VOID_FTYPE_UINT64_UINT_UINT:
- case UCHAR_FTYPE_UINT_UINT_UINT:
- case UCHAR_FTYPE_UINT64_UINT_UINT:
- nargs = 3;
- klass = load;
- memory = ARRAY_SIZE (args);
- last_arg_constant = true;
- break;
- default:
- gcc_unreachable ();
- }
-
- gcc_assert (nargs <= ARRAY_SIZE (args));
-
- if (klass == store)
- {
- arg = CALL_EXPR_ARG (exp, 0);
- op = expand_normal (arg);
- gcc_assert (target == 0);
- if (memory)
- {
- op = force_reg (Pmode, convert_to_mode (Pmode, op, 1));
- target = gen_rtx_MEM (tmode, op);
- }
- else
- target = force_reg (tmode, op);
- arg_adjust = 1;
- }
- else
- {
- arg_adjust = 0;
- if (optimize
- || target == 0
- || !register_operand (target, tmode)
- || GET_MODE (target) != tmode)
- target = gen_reg_rtx (tmode);
- }
-
- for (i = 0; i < nargs; i++)
- {
- enum machine_mode mode = insn_p->operand[i + 1].mode;
- bool match;
-
- arg = CALL_EXPR_ARG (exp, i + arg_adjust);
- op = expand_normal (arg);
- match = insn_p->operand[i + 1].predicate (op, mode);
-
- if (last_arg_constant && (i + 1) == nargs)
- {
- if (!match)
- {
- if (icode == CODE_FOR_lwp_lwpvalsi3
- || icode == CODE_FOR_lwp_lwpinssi3
- || icode == CODE_FOR_lwp_lwpvaldi3
- || icode == CODE_FOR_lwp_lwpinsdi3)
- error ("the last argument must be a 32-bit immediate");
- else
- error ("the last argument must be an 8-bit immediate");
- return const0_rtx;
- }
- }
- else
- {
- if (i == memory)
- {
- /* This must be the memory operand. */
- op = force_reg (Pmode, convert_to_mode (Pmode, op, 1));
- op = gen_rtx_MEM (mode, op);
- gcc_assert (GET_MODE (op) == mode
- || GET_MODE (op) == VOIDmode);
- }
- else
- {
- /* This must be register. */
- if (VECTOR_MODE_P (mode))
- op = safe_vector_operand (op, mode);
-
- gcc_assert (GET_MODE (op) == mode
- || GET_MODE (op) == VOIDmode);
- op = copy_to_mode_reg (mode, op);
- }
- }
-
- args[i].op = op;
- args[i].mode = mode;
- }
-
- switch (nargs)
- {
- case 0:
- pat = GEN_FCN (icode) (target);
- break;
- case 1:
- pat = GEN_FCN (icode) (target, args[0].op);
- break;
- case 2:
- pat = GEN_FCN (icode) (target, args[0].op, args[1].op);
- break;
- case 3:
- pat = GEN_FCN (icode) (target, args[0].op, args[1].op, args[2].op);
- break;
- default:
- gcc_unreachable ();
- }
-
- if (! pat)
- return 0;
- emit_insn (pat);
- return klass == store ? 0 : target;
-}
-
-/* Return the integer constant in ARG. Constrain it to be in the range
- of the subparts of VEC_TYPE; issue an error if not. */
-
-static int
-get_element_number (tree vec_type, tree arg)
-{
- unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
-
- if (!host_integerp (arg, 1)
- || (elt = tree_low_cst (arg, 1), elt > max))
- {
- error ("selector must be an integer constant in the range 0..%wi", max);
- return 0;
- }
-
- return elt;
-}
-
-/* A subroutine of ix86_expand_builtin. These builtins are a wrapper around
- ix86_expand_vector_init. We DO have language-level syntax for this, in
- the form of (type){ init-list }. Except that since we can't place emms
- instructions from inside the compiler, we can't allow the use of MMX
- registers unless the user explicitly asks for it. So we do *not* define
- vec_set/vec_extract/vec_init patterns for MMX modes in mmx.md. Instead
- we have builtins invoked by mmintrin.h that gives us license to emit
- these sorts of instructions. */
-
-static rtx
-ix86_expand_vec_init_builtin (tree type, tree exp, rtx target)
-{
- enum machine_mode tmode = TYPE_MODE (type);
- enum machine_mode inner_mode = GET_MODE_INNER (tmode);
- int i, n_elt = GET_MODE_NUNITS (tmode);
- rtvec v = rtvec_alloc (n_elt);
-
- gcc_assert (VECTOR_MODE_P (tmode));
- gcc_assert (call_expr_nargs (exp) == n_elt);
-
- for (i = 0; i < n_elt; ++i)
- {
- rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
- RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
- }
-
- if (!target || !register_operand (target, tmode))
- target = gen_reg_rtx (tmode);
-
- ix86_expand_vector_init (true, target, gen_rtx_PARALLEL (tmode, v));
- return target;
-}
-
-/* A subroutine of ix86_expand_builtin. These builtins are a wrapper around
- ix86_expand_vector_extract. They would be redundant (for non-MMX) if we
- had a language-level syntax for referencing vector elements. */
-
-static rtx
-ix86_expand_vec_ext_builtin (tree exp, rtx target)
-{
- enum machine_mode tmode, mode0;
- tree arg0, arg1;
- int elt;
- rtx op0;
-
- arg0 = CALL_EXPR_ARG (exp, 0);
- arg1 = CALL_EXPR_ARG (exp, 1);
-
- op0 = expand_normal (arg0);
- elt = get_element_number (TREE_TYPE (arg0), arg1);
-
- tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
- mode0 = TYPE_MODE (TREE_TYPE (arg0));
- gcc_assert (VECTOR_MODE_P (mode0));
-
- op0 = force_reg (mode0, op0);
-
- if (optimize || !target || !register_operand (target, tmode))
- target = gen_reg_rtx (tmode);
-
- ix86_expand_vector_extract (true, target, op0, elt);
-
- return target;
-}
-
-/* A subroutine of ix86_expand_builtin. These builtins are a wrapper around
- ix86_expand_vector_set. They would be redundant (for non-MMX) if we had
- a language-level syntax for referencing vector elements. */
-
-static rtx
-ix86_expand_vec_set_builtin (tree exp)
-{
- enum machine_mode tmode, mode1;
- tree arg0, arg1, arg2;
- int elt;
- rtx op0, op1, target;
-
- arg0 = CALL_EXPR_ARG (exp, 0);
- arg1 = CALL_EXPR_ARG (exp, 1);
- arg2 = CALL_EXPR_ARG (exp, 2);
-
- tmode = TYPE_MODE (TREE_TYPE (arg0));
- mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
- gcc_assert (VECTOR_MODE_P (tmode));
-
- op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
- op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
- elt = get_element_number (TREE_TYPE (arg0), arg2);
-
- if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
- op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
-
- op0 = force_reg (tmode, op0);
- op1 = force_reg (mode1, op1);
-
- /* OP0 is the source of these builtin functions and shouldn't be
- modified. Create a copy, use it and return it as target. */
- target = gen_reg_rtx (tmode);
- emit_move_insn (target, op0);
- ix86_expand_vector_set (true, target, op1, elt);
-
- 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. */
-
-static rtx
-ix86_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;
- size_t i;
- enum insn_code icode;
- tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- tree arg0, arg1, arg2, arg3, arg4;
- rtx op0, op1, op2, op3, op4, pat, insn;
- enum machine_mode mode0, mode1, mode2, mode3, mode4;
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
-
- /* For CPU builtins that can be folded, fold first and expand the fold. */
- switch (fcode)
- {
- case IX86_BUILTIN_CPU_INIT:
- {
- /* Make it call __cpu_indicator_init in libgcc. */
- tree call_expr, fndecl, type;
- type = build_function_type_list (integer_type_node, NULL_TREE);
- fndecl = build_fn_decl ("__cpu_indicator_init", type);
- call_expr = build_call_expr (fndecl, 0);
- return expand_expr (call_expr, target, mode, EXPAND_NORMAL);
- }
- case IX86_BUILTIN_CPU_IS:
- case IX86_BUILTIN_CPU_SUPPORTS:
- {
- tree arg0 = CALL_EXPR_ARG (exp, 0);
- tree fold_expr = fold_builtin_cpu (fndecl, &arg0);
- gcc_assert (fold_expr != NULL_TREE);
- return expand_expr (fold_expr, target, mode, EXPAND_NORMAL);
- }
- }
-
- /* Determine whether the builtin function is available under the current ISA.
- Originally the builtin was not created if it wasn't applicable to the
- current ISA based on the command line switches. With function specific
- options, we need to check in the context of the function making the call
- whether it is supported. */
- if (ix86_builtins_isa[fcode].isa
- && !(ix86_builtins_isa[fcode].isa & ix86_isa_flags))
- {
- char *opts = ix86_target_string (ix86_builtins_isa[fcode].isa, 0, NULL,
- NULL, (enum fpmath_unit) 0, false);
-
- if (!opts)
- error ("%qE needs unknown isa option", fndecl);
- else
- {
- gcc_assert (opts != NULL);
- error ("%qE needs isa option %s", fndecl, opts);
- free (opts);
- }
- return const0_rtx;
- }
-
- switch (fcode)
- {
- case IX86_BUILTIN_MASKMOVQ:
- case IX86_BUILTIN_MASKMOVDQU:
- icode = (fcode == IX86_BUILTIN_MASKMOVQ
- ? CODE_FOR_mmx_maskmovq
- : CODE_FOR_sse2_maskmovdqu);
- /* Note the arg order is different from the operand order. */
- arg1 = CALL_EXPR_ARG (exp, 0);
- arg2 = CALL_EXPR_ARG (exp, 1);
- arg0 = CALL_EXPR_ARG (exp, 2);
- op0 = expand_normal (arg0);
- op1 = expand_normal (arg1);
- op2 = expand_normal (arg2);
- mode0 = insn_data[icode].operand[0].mode;
- mode1 = insn_data[icode].operand[1].mode;
- mode2 = insn_data[icode].operand[2].mode;
-
- op0 = force_reg (Pmode, convert_to_mode (Pmode, op0, 1));
- op0 = gen_rtx_MEM (mode1, op0);
-
- if (!insn_data[icode].operand[0].predicate (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
- if (!insn_data[icode].operand[1].predicate (op1, mode1))
- op1 = copy_to_mode_reg (mode1, op1);
- if (!insn_data[icode].operand[2].predicate (op2, mode2))
- op2 = copy_to_mode_reg (mode2, op2);
- pat = GEN_FCN (icode) (op0, op1, op2);
- if (! pat)
- return 0;
- emit_insn (pat);
- return 0;
-
- case IX86_BUILTIN_LDMXCSR:
- op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
- target = assign_386_stack_local (SImode, SLOT_TEMP);
- emit_move_insn (target, op0);
- emit_insn (gen_sse_ldmxcsr (target));
- return 0;
-
- case IX86_BUILTIN_STMXCSR:
- target = assign_386_stack_local (SImode, SLOT_TEMP);
- emit_insn (gen_sse_stmxcsr (target));
- return copy_to_mode_reg (SImode, target);
-
- case IX86_BUILTIN_CLFLUSH:
- arg0 = CALL_EXPR_ARG (exp, 0);
- op0 = expand_normal (arg0);
- icode = CODE_FOR_sse2_clflush;
- if (!insn_data[icode].operand[0].predicate (op0, Pmode))
- op0 = force_reg (Pmode, convert_to_mode (Pmode, op0, 1));
-
- emit_insn (gen_sse2_clflush (op0));
- return 0;
-
- case IX86_BUILTIN_MONITOR:
- 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 (!REG_P (op0))
- op0 = force_reg (Pmode, convert_to_mode (Pmode, op0, 1));
- if (!REG_P (op1))
- op1 = copy_to_mode_reg (SImode, op1);
- if (!REG_P (op2))
- op2 = copy_to_mode_reg (SImode, op2);
- emit_insn (ix86_gen_monitor (op0, op1, op2));
- return 0;
-
- case IX86_BUILTIN_MWAIT:
- arg0 = CALL_EXPR_ARG (exp, 0);
- arg1 = CALL_EXPR_ARG (exp, 1);
- op0 = expand_normal (arg0);
- op1 = expand_normal (arg1);
- if (!REG_P (op0))
- op0 = copy_to_mode_reg (SImode, op0);
- if (!REG_P (op1))
- op1 = copy_to_mode_reg (SImode, op1);
- emit_insn (gen_sse3_mwait (op0, op1));
- return 0;
-
- case IX86_BUILTIN_VEC_INIT_V2SI:
- case IX86_BUILTIN_VEC_INIT_V4HI:
- case IX86_BUILTIN_VEC_INIT_V8QI:
- return ix86_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
-
- case IX86_BUILTIN_VEC_EXT_V2DF:
- case IX86_BUILTIN_VEC_EXT_V2DI:
- case IX86_BUILTIN_VEC_EXT_V4SF:
- case IX86_BUILTIN_VEC_EXT_V4SI:
- case IX86_BUILTIN_VEC_EXT_V8HI:
- case IX86_BUILTIN_VEC_EXT_V2SI:
- case IX86_BUILTIN_VEC_EXT_V4HI:
- case IX86_BUILTIN_VEC_EXT_V16QI:
- return ix86_expand_vec_ext_builtin (exp, target);
-
- case IX86_BUILTIN_VEC_SET_V2DI:
- case IX86_BUILTIN_VEC_SET_V4SF:
- case IX86_BUILTIN_VEC_SET_V4SI:
- case IX86_BUILTIN_VEC_SET_V8HI:
- case IX86_BUILTIN_VEC_SET_V4HI:
- case IX86_BUILTIN_VEC_SET_V16QI:
- return ix86_expand_vec_set_builtin (exp);
-
- case IX86_BUILTIN_INFQ:
- case IX86_BUILTIN_HUGE_VALQ:
- {
- REAL_VALUE_TYPE inf;
- rtx tmp;
-
- real_inf (&inf);
- tmp = CONST_DOUBLE_FROM_REAL_VALUE (inf, mode);
-
- tmp = validize_mem (force_const_mem (mode, tmp));
-
- if (target == 0)
- target = gen_reg_rtx (mode);
-
- emit_move_insn (target, tmp);
- return target;
- }
-
- case IX86_BUILTIN_RDPMC:
- case IX86_BUILTIN_RDTSC:
- case IX86_BUILTIN_RDTSCP:
-
- op0 = gen_reg_rtx (DImode);
- op1 = gen_reg_rtx (DImode);
-
- if (fcode == IX86_BUILTIN_RDPMC)
- {
- arg0 = CALL_EXPR_ARG (exp, 0);
- op2 = expand_normal (arg0);
- if (!register_operand (op2, SImode))
- op2 = copy_to_mode_reg (SImode, op2);
-
- insn = (TARGET_64BIT
- ? gen_rdpmc_rex64 (op0, op1, op2)
- : gen_rdpmc (op0, op2));
- emit_insn (insn);
- }
- else if (fcode == IX86_BUILTIN_RDTSC)
- {
- insn = (TARGET_64BIT
- ? gen_rdtsc_rex64 (op0, op1)
- : gen_rdtsc (op0));
- emit_insn (insn);
- }
- else
- {
- op2 = gen_reg_rtx (SImode);
-
- insn = (TARGET_64BIT
- ? gen_rdtscp_rex64 (op0, op1, op2)
- : gen_rdtscp (op0, op2));
- emit_insn (insn);
-
- arg0 = CALL_EXPR_ARG (exp, 0);
- op4 = expand_normal (arg0);
- if (!address_operand (op4, VOIDmode))
- {
- op4 = convert_memory_address (Pmode, op4);
- op4 = copy_addr_to_reg (op4);
- }
- emit_move_insn (gen_rtx_MEM (SImode, op4), op2);
- }
-
- if (target == 0)
- target = gen_reg_rtx (mode);
-
- if (TARGET_64BIT)
- {
- op1 = expand_simple_binop (DImode, ASHIFT, op1, GEN_INT (32),
- op1, 1, OPTAB_DIRECT);
- op0 = expand_simple_binop (DImode, IOR, op0, op1,
- op0, 1, OPTAB_DIRECT);
- }
-
- emit_move_insn (target, op0);
- return target;
-
- case IX86_BUILTIN_FXSAVE:
- case IX86_BUILTIN_FXRSTOR:
- case IX86_BUILTIN_FXSAVE64:
- case IX86_BUILTIN_FXRSTOR64:
- switch (fcode)
- {
- case IX86_BUILTIN_FXSAVE:
- icode = CODE_FOR_fxsave;
- break;
- case IX86_BUILTIN_FXRSTOR:
- icode = CODE_FOR_fxrstor;
- break;
- case IX86_BUILTIN_FXSAVE64:
- icode = CODE_FOR_fxsave64;
- break;
- case IX86_BUILTIN_FXRSTOR64:
- icode = CODE_FOR_fxrstor64;
- break;
- default:
- gcc_unreachable ();
- }
-
- arg0 = CALL_EXPR_ARG (exp, 0);
- op0 = expand_normal (arg0);
-
- if (!address_operand (op0, VOIDmode))
- {
- op0 = convert_memory_address (Pmode, op0);
- op0 = copy_addr_to_reg (op0);
- }
- op0 = gen_rtx_MEM (BLKmode, op0);
-
- pat = GEN_FCN (icode) (op0);
- if (pat)
- emit_insn (pat);
- return 0;
-
- case IX86_BUILTIN_XSAVE:
- case IX86_BUILTIN_XRSTOR:
- case IX86_BUILTIN_XSAVE64:
- case IX86_BUILTIN_XRSTOR64:
- case IX86_BUILTIN_XSAVEOPT:
- case IX86_BUILTIN_XSAVEOPT64:
- arg0 = CALL_EXPR_ARG (exp, 0);
- arg1 = CALL_EXPR_ARG (exp, 1);
- op0 = expand_normal (arg0);
- op1 = expand_normal (arg1);
-
- if (!address_operand (op0, VOIDmode))
- {
- op0 = convert_memory_address (Pmode, op0);
- op0 = copy_addr_to_reg (op0);
- }
- op0 = gen_rtx_MEM (BLKmode, op0);
-
- op1 = force_reg (DImode, op1);
-
- if (TARGET_64BIT)
- {
- op2 = expand_simple_binop (DImode, LSHIFTRT, op1, GEN_INT (32),
- NULL, 1, OPTAB_DIRECT);
- switch (fcode)
- {
- case IX86_BUILTIN_XSAVE:
- icode = CODE_FOR_xsave_rex64;
- break;
- case IX86_BUILTIN_XRSTOR:
- icode = CODE_FOR_xrstor_rex64;
- break;
- case IX86_BUILTIN_XSAVE64:
- icode = CODE_FOR_xsave64;
- break;
- case IX86_BUILTIN_XRSTOR64:
- icode = CODE_FOR_xrstor64;
- break;
- case IX86_BUILTIN_XSAVEOPT:
- icode = CODE_FOR_xsaveopt_rex64;
- break;
- case IX86_BUILTIN_XSAVEOPT64:
- icode = CODE_FOR_xsaveopt64;
- break;
- default:
- gcc_unreachable ();
- }
-
- op2 = gen_lowpart (SImode, op2);
- op1 = gen_lowpart (SImode, op1);
- pat = GEN_FCN (icode) (op0, op1, op2);
- }
- else
- {
- switch (fcode)
- {
- case IX86_BUILTIN_XSAVE:
- icode = CODE_FOR_xsave;
- break;
- case IX86_BUILTIN_XRSTOR:
- icode = CODE_FOR_xrstor;
- break;
- case IX86_BUILTIN_XSAVEOPT:
- icode = CODE_FOR_xsaveopt;
- break;
- default:
- gcc_unreachable ();
- }
- pat = GEN_FCN (icode) (op0, op1);
- }
-
- if (pat)
- emit_insn (pat);
- return 0;
-
- case IX86_BUILTIN_LLWPCB:
- arg0 = CALL_EXPR_ARG (exp, 0);
- op0 = expand_normal (arg0);
- icode = CODE_FOR_lwp_llwpcb;
- if (!insn_data[icode].operand[0].predicate (op0, Pmode))
- op0 = force_reg (Pmode, convert_to_mode (Pmode, op0, 1));
- emit_insn (gen_lwp_llwpcb (op0));
- return 0;
-
- case IX86_BUILTIN_SLWPCB:
- icode = CODE_FOR_lwp_slwpcb;
- if (!target
- || !insn_data[icode].operand[0].predicate (target, Pmode))
- target = gen_reg_rtx (Pmode);
- emit_insn (gen_lwp_slwpcb (target));
- return target;
-
- case IX86_BUILTIN_BEXTRI32:
- case IX86_BUILTIN_BEXTRI64:
- arg0 = CALL_EXPR_ARG (exp, 0);
- arg1 = CALL_EXPR_ARG (exp, 1);
- op0 = expand_normal (arg0);
- op1 = expand_normal (arg1);
- icode = (fcode == IX86_BUILTIN_BEXTRI32
- ? CODE_FOR_tbm_bextri_si
- : CODE_FOR_tbm_bextri_di);
- if (!CONST_INT_P (op1))
- {
- error ("last argument must be an immediate");
- return const0_rtx;
- }
- else
- {
- unsigned char length = (INTVAL (op1) >> 8) & 0xFF;
- unsigned char lsb_index = INTVAL (op1) & 0xFF;
- op1 = GEN_INT (length);
- op2 = GEN_INT (lsb_index);
- pat = GEN_FCN (icode) (target, op0, op1, op2);
- if (pat)
- emit_insn (pat);
- return target;
- }
-
- case IX86_BUILTIN_RDRAND16_STEP:
- icode = CODE_FOR_rdrandhi_1;
- mode0 = HImode;
- goto rdrand_step;
-
- case IX86_BUILTIN_RDRAND32_STEP:
- icode = CODE_FOR_rdrandsi_1;
- mode0 = SImode;
- goto rdrand_step;
-
- case IX86_BUILTIN_RDRAND64_STEP:
- icode = CODE_FOR_rdranddi_1;
- mode0 = DImode;
-
-rdrand_step:
- op0 = gen_reg_rtx (mode0);
- emit_insn (GEN_FCN (icode) (op0));
-
- arg0 = CALL_EXPR_ARG (exp, 0);
- op1 = expand_normal (arg0);
- if (!address_operand (op1, VOIDmode))
- {
- op1 = convert_memory_address (Pmode, op1);
- op1 = copy_addr_to_reg (op1);
- }
- emit_move_insn (gen_rtx_MEM (mode0, op1), op0);
-
- op1 = gen_reg_rtx (SImode);
- emit_move_insn (op1, CONST1_RTX (SImode));
-
- /* Emit SImode conditional move. */
- if (mode0 == HImode)
- {
- op2 = gen_reg_rtx (SImode);
- emit_insn (gen_zero_extendhisi2 (op2, op0));
- }
- else if (mode0 == SImode)
- op2 = op0;
- else
- op2 = gen_rtx_SUBREG (SImode, op0, 0);
-
- if (target == 0)
- target = gen_reg_rtx (SImode);
-
- pat = gen_rtx_GEU (VOIDmode, gen_rtx_REG (CCCmode, FLAGS_REG),
- const0_rtx);
- emit_insn (gen_rtx_SET (VOIDmode, target,
- gen_rtx_IF_THEN_ELSE (SImode, pat, op2, op1)));
- return target;
-
- case IX86_BUILTIN_RDSEED16_STEP:
- icode = CODE_FOR_rdseedhi_1;
- mode0 = HImode;
- goto rdseed_step;
-
- case IX86_BUILTIN_RDSEED32_STEP:
- icode = CODE_FOR_rdseedsi_1;
- mode0 = SImode;
- goto rdseed_step;
-
- case IX86_BUILTIN_RDSEED64_STEP:
- icode = CODE_FOR_rdseeddi_1;
- mode0 = DImode;
-
-rdseed_step:
- op0 = gen_reg_rtx (mode0);
- emit_insn (GEN_FCN (icode) (op0));
-
- arg0 = CALL_EXPR_ARG (exp, 0);
- op1 = expand_normal (arg0);
- if (!address_operand (op1, VOIDmode))
- {
- op1 = convert_memory_address (Pmode, op1);
- op1 = copy_addr_to_reg (op1);
- }
- emit_move_insn (gen_rtx_MEM (mode0, op1), op0);
-
- op2 = gen_reg_rtx (QImode);
-
- pat = gen_rtx_LTU (QImode, gen_rtx_REG (CCCmode, FLAGS_REG),
- const0_rtx);
- emit_insn (gen_rtx_SET (VOIDmode, op2, pat));
-
- if (target == 0)
- target = gen_reg_rtx (SImode);
-
- emit_insn (gen_zero_extendqisi2 (target, op2));
- return target;
-
- case IX86_BUILTIN_ADDCARRYX32:
- icode = TARGET_ADX ? CODE_FOR_adcxsi3 : CODE_FOR_addsi3_carry;
- mode0 = SImode;
- goto addcarryx;
-
- case IX86_BUILTIN_ADDCARRYX64:
- icode = TARGET_ADX ? CODE_FOR_adcxdi3 : CODE_FOR_adddi3_carry;
- mode0 = DImode;
-
-addcarryx:
- arg0 = CALL_EXPR_ARG (exp, 0); /* unsigned char c_in. */
- arg1 = CALL_EXPR_ARG (exp, 1); /* unsigned int src1. */
- arg2 = CALL_EXPR_ARG (exp, 2); /* unsigned int src2. */
- arg3 = CALL_EXPR_ARG (exp, 3); /* unsigned int *sum_out. */
-
- op0 = gen_reg_rtx (QImode);
-
- /* Generate CF from input operand. */
- op1 = expand_normal (arg0);
- op1 = copy_to_mode_reg (QImode, convert_to_mode (QImode, op1, 1));
- emit_insn (gen_addqi3_cc (op0, op1, constm1_rtx));
-
- /* Gen ADCX instruction to compute X+Y+CF. */
- op2 = expand_normal (arg1);
- op3 = expand_normal (arg2);
-
- if (!REG_P (op2))
- op2 = copy_to_mode_reg (mode0, op2);
- if (!REG_P (op3))
- op3 = copy_to_mode_reg (mode0, op3);
-
- op0 = gen_reg_rtx (mode0);
-
- op4 = gen_rtx_REG (CCCmode, FLAGS_REG);
- pat = gen_rtx_LTU (VOIDmode, op4, const0_rtx);
- emit_insn (GEN_FCN (icode) (op0, op2, op3, op4, pat));
-
- /* Store the result. */
- op4 = expand_normal (arg3);
- if (!address_operand (op4, VOIDmode))
- {
- op4 = convert_memory_address (Pmode, op4);
- op4 = copy_addr_to_reg (op4);
- }
- emit_move_insn (gen_rtx_MEM (mode0, op4), op0);
-
- /* Return current CF value. */
- if (target == 0)
- target = gen_reg_rtx (QImode);
-
- PUT_MODE (pat, QImode);
- emit_insn (gen_rtx_SET (VOIDmode, target, pat));
- return target;
-
- case IX86_BUILTIN_GATHERSIV2DF:
- icode = CODE_FOR_avx2_gathersiv2df;
- goto gather_gen;
- case IX86_BUILTIN_GATHERSIV4DF:
- icode = CODE_FOR_avx2_gathersiv4df;
- goto gather_gen;
- case IX86_BUILTIN_GATHERDIV2DF:
- icode = CODE_FOR_avx2_gatherdiv2df;
- goto gather_gen;
- case IX86_BUILTIN_GATHERDIV4DF:
- icode = CODE_FOR_avx2_gatherdiv4df;
- goto gather_gen;
- case IX86_BUILTIN_GATHERSIV4SF:
- icode = CODE_FOR_avx2_gathersiv4sf;
- goto gather_gen;
- case IX86_BUILTIN_GATHERSIV8SF:
- icode = CODE_FOR_avx2_gathersiv8sf;
- goto gather_gen;
- case IX86_BUILTIN_GATHERDIV4SF:
- icode = CODE_FOR_avx2_gatherdiv4sf;
- goto gather_gen;
- case IX86_BUILTIN_GATHERDIV8SF:
- icode = CODE_FOR_avx2_gatherdiv8sf;
- goto gather_gen;
- case IX86_BUILTIN_GATHERSIV2DI:
- icode = CODE_FOR_avx2_gathersiv2di;
- goto gather_gen;
- case IX86_BUILTIN_GATHERSIV4DI:
- icode = CODE_FOR_avx2_gathersiv4di;
- goto gather_gen;
- case IX86_BUILTIN_GATHERDIV2DI:
- icode = CODE_FOR_avx2_gatherdiv2di;
- goto gather_gen;
- case IX86_BUILTIN_GATHERDIV4DI:
- icode = CODE_FOR_avx2_gatherdiv4di;
- goto gather_gen;
- case IX86_BUILTIN_GATHERSIV4SI:
- icode = CODE_FOR_avx2_gathersiv4si;
- goto gather_gen;
- case IX86_BUILTIN_GATHERSIV8SI:
- icode = CODE_FOR_avx2_gathersiv8si;
- goto gather_gen;
- case IX86_BUILTIN_GATHERDIV4SI:
- icode = CODE_FOR_avx2_gatherdiv4si;
- goto gather_gen;
- case IX86_BUILTIN_GATHERDIV8SI:
- icode = CODE_FOR_avx2_gatherdiv8si;
- goto gather_gen;
- case IX86_BUILTIN_GATHERALTSIV4DF:
- icode = CODE_FOR_avx2_gathersiv4df;
- goto gather_gen;
- case IX86_BUILTIN_GATHERALTDIV8SF:
- icode = CODE_FOR_avx2_gatherdiv8sf;
- goto gather_gen;
- case IX86_BUILTIN_GATHERALTSIV4DI:
- icode = CODE_FOR_avx2_gathersiv4di;
- goto gather_gen;
- case IX86_BUILTIN_GATHERALTDIV8SI:
- icode = CODE_FOR_avx2_gatherdiv8si;
- goto gather_gen;
-
- gather_gen:
- 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);
- /* Note the arg order is different from the operand order. */
- mode0 = insn_data[icode].operand[1].mode;
- mode2 = insn_data[icode].operand[3].mode;
- mode3 = insn_data[icode].operand[4].mode;
- mode4 = insn_data[icode].operand[5].mode;
-
- if (target == NULL_RTX
- || GET_MODE (target) != insn_data[icode].operand[0].mode)
- subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
- else
- subtarget = target;
-
- if (fcode == IX86_BUILTIN_GATHERALTSIV4DF
- || fcode == IX86_BUILTIN_GATHERALTSIV4DI)
- {
- rtx half = gen_reg_rtx (V4SImode);
- if (!nonimmediate_operand (op2, V8SImode))
- op2 = copy_to_mode_reg (V8SImode, op2);
- emit_insn (gen_vec_extract_lo_v8si (half, op2));
- op2 = half;
- }
- else if (fcode == IX86_BUILTIN_GATHERALTDIV8SF
- || fcode == IX86_BUILTIN_GATHERALTDIV8SI)
- {
- rtx (*gen) (rtx, rtx);
- rtx half = gen_reg_rtx (mode0);
- if (mode0 == V4SFmode)
- gen = gen_vec_extract_lo_v8sf;
- else
- gen = gen_vec_extract_lo_v8si;
- if (!nonimmediate_operand (op0, GET_MODE (op0)))
- op0 = copy_to_mode_reg (GET_MODE (op0), op0);
- emit_insn (gen (half, op0));
- op0 = half;
- if (!nonimmediate_operand (op3, GET_MODE (op3)))
- op3 = copy_to_mode_reg (GET_MODE (op3), op3);
- emit_insn (gen (half, op3));
- op3 = half;
- }
-
- /* Force memory operand only with base register here. But we
- don't want to do it on memory operand for other builtin
- functions. */
- op1 = force_reg (Pmode, convert_to_mode (Pmode, op1, 1));
-
- if (!insn_data[icode].operand[1].predicate (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
- if (!insn_data[icode].operand[2].predicate (op1, Pmode))
- op1 = copy_to_mode_reg (Pmode, op1);
- if (!insn_data[icode].operand[3].predicate (op2, mode2))
- op2 = copy_to_mode_reg (mode2, op2);
- if (!insn_data[icode].operand[4].predicate (op3, mode3))
- op3 = copy_to_mode_reg (mode3, op3);
- if (!insn_data[icode].operand[5].predicate (op4, mode4))
- {
- error ("last argument must be scale 1, 2, 4, 8");
- return const0_rtx;
- }
-
- /* Optimize. If mask is known to have all high bits set,
- replace op0 with pc_rtx to signal that the instruction
- overwrites the whole destination and doesn't use its
- previous contents. */
- if (optimize)
- {
- if (TREE_CODE (arg3) == VECTOR_CST)
- {
- unsigned int negative = 0;
- for (i = 0; i < VECTOR_CST_NELTS (arg3); ++i)
- {
- tree cst = VECTOR_CST_ELT (arg3, i);
- if (TREE_CODE (cst) == INTEGER_CST
- && tree_int_cst_sign_bit (cst))
- negative++;
- else if (TREE_CODE (cst) == REAL_CST
- && REAL_VALUE_NEGATIVE (TREE_REAL_CST (cst)))
- negative++;
- }
- if (negative == TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg3)))
- op0 = pc_rtx;
- }
- else if (TREE_CODE (arg3) == SSA_NAME)
- {
- /* Recognize also when mask is like:
- __v2df src = _mm_setzero_pd ();
- __v2df mask = _mm_cmpeq_pd (src, src);
- or
- __v8sf src = _mm256_setzero_ps ();
- __v8sf mask = _mm256_cmp_ps (src, src, _CMP_EQ_OQ);
- as that is a cheaper way to load all ones into
- a register than having to load a constant from
- memory. */
- gimple def_stmt = SSA_NAME_DEF_STMT (arg3);
- if (is_gimple_call (def_stmt))
- {
- tree fndecl = gimple_call_fndecl (def_stmt);
- if (fndecl
- && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
- switch ((unsigned int) DECL_FUNCTION_CODE (fndecl))
- {
- case IX86_BUILTIN_CMPPD:
- case IX86_BUILTIN_CMPPS:
- case IX86_BUILTIN_CMPPD256:
- case IX86_BUILTIN_CMPPS256:
- if (!integer_zerop (gimple_call_arg (def_stmt, 2)))
- break;
- /* FALLTHRU */
- case IX86_BUILTIN_CMPEQPD:
- case IX86_BUILTIN_CMPEQPS:
- if (initializer_zerop (gimple_call_arg (def_stmt, 0))
- && initializer_zerop (gimple_call_arg (def_stmt,
- 1)))
- op0 = pc_rtx;
- break;
- default:
- break;
- }
- }
- }
- }
-
- pat = GEN_FCN (icode) (subtarget, op0, op1, op2, op3, op4);
- if (! pat)
- return const0_rtx;
- emit_insn (pat);
-
- if (fcode == IX86_BUILTIN_GATHERDIV8SF
- || fcode == IX86_BUILTIN_GATHERDIV8SI)
- {
- enum machine_mode tmode = GET_MODE (subtarget) == V8SFmode
- ? V4SFmode : V4SImode;
- if (target == NULL_RTX)
- target = gen_reg_rtx (tmode);
- if (tmode == V4SFmode)
- emit_insn (gen_vec_extract_lo_v8sf (target, subtarget));
- else
- emit_insn (gen_vec_extract_lo_v8si (target, subtarget));
- }
- else
- target = subtarget;
-
- return target;
-
- case IX86_BUILTIN_XABORT:
- icode = CODE_FOR_xabort;
- 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))
- {
- error ("the xabort's argument must be an 8-bit immediate");
- return const0_rtx;
- }
- emit_insn (gen_xabort (op0));
- return 0;
-
- default:
- break;
- }
-
- for (i = 0, d = bdesc_special_args;
- i < ARRAY_SIZE (bdesc_special_args);
- i++, d++)
- if (d->code == fcode)
- return ix86_expand_special_args_builtin (d, exp, target);
-
- for (i = 0, d = bdesc_args;
- i < ARRAY_SIZE (bdesc_args);
- i++, d++)
- if (d->code == fcode)
- switch (fcode)
- {
- case IX86_BUILTIN_FABSQ:
- case IX86_BUILTIN_COPYSIGNQ:
- if (!TARGET_SSE)
- /* Emit a normal call if SSE isn't available. */
- return expand_call (exp, target, ignore);
- default:
- return ix86_expand_args_builtin (d, exp, target);
- }
-
- for (i = 0, d = bdesc_comi; i < ARRAY_SIZE (bdesc_comi); i++, d++)
- if (d->code == fcode)
- return ix86_expand_sse_comi (d, exp, target);
-
- for (i = 0, d = bdesc_pcmpestr;
- i < ARRAY_SIZE (bdesc_pcmpestr);
- i++, d++)
- if (d->code == fcode)
- return ix86_expand_sse_pcmpestr (d, exp, target);
-
- for (i = 0, d = bdesc_pcmpistr;
- i < ARRAY_SIZE (bdesc_pcmpistr);
- i++, d++)
- if (d->code == fcode)
- return ix86_expand_sse_pcmpistr (d, exp, target);
-
- for (i = 0, d = bdesc_multi_arg; i < ARRAY_SIZE (bdesc_multi_arg); i++, d++)
- if (d->code == fcode)
- return ix86_expand_multi_arg_builtin (d->icode, exp, target,
- (enum ix86_builtin_func_type)
- d->flag, d->comparison);
-
- gcc_unreachable ();
-}
-
-/* Returns a function decl for a vectorized version of the builtin function
- with builtin function code FN and the result vector type TYPE, or NULL_TREE
- if it is not available. */
-
-static tree
-ix86_builtin_vectorized_function (tree fndecl, tree type_out,
- tree type_in)
-{
- enum machine_mode in_mode, out_mode;
- int in_n, out_n;
- enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
-
- if (TREE_CODE (type_out) != VECTOR_TYPE
- || TREE_CODE (type_in) != VECTOR_TYPE
- || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
- return NULL_TREE;
-
- out_mode = TYPE_MODE (TREE_TYPE (type_out));
- out_n = TYPE_VECTOR_SUBPARTS (type_out);
- in_mode = TYPE_MODE (TREE_TYPE (type_in));
- in_n = TYPE_VECTOR_SUBPARTS (type_in);
-
- switch (fn)
- {
- case BUILT_IN_SQRT:
- if (out_mode == DFmode && in_mode == DFmode)
- {
- if (out_n == 2 && in_n == 2)
- return ix86_builtins[IX86_BUILTIN_SQRTPD];
- else if (out_n == 4 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_SQRTPD256];
- }
- break;
-
- case BUILT_IN_SQRTF:
- if (out_mode == SFmode && in_mode == SFmode)
- {
- if (out_n == 4 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_SQRTPS_NR];
- else if (out_n == 8 && in_n == 8)
- return ix86_builtins[IX86_BUILTIN_SQRTPS_NR256];
- }
- break;
-
- case BUILT_IN_IFLOOR:
- case BUILT_IN_LFLOOR:
- case BUILT_IN_LLFLOOR:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
- if (out_mode == SImode && in_mode == DFmode)
- {
- if (out_n == 4 && in_n == 2)
- return ix86_builtins[IX86_BUILTIN_FLOORPD_VEC_PACK_SFIX];
- else if (out_n == 8 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_FLOORPD_VEC_PACK_SFIX256];
- }
- break;
-
- case BUILT_IN_IFLOORF:
- case BUILT_IN_LFLOORF:
- case BUILT_IN_LLFLOORF:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
- if (out_mode == SImode && in_mode == SFmode)
- {
- if (out_n == 4 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_FLOORPS_SFIX];
- else if (out_n == 8 && in_n == 8)
- return ix86_builtins[IX86_BUILTIN_FLOORPS_SFIX256];
- }
- break;
-
- case BUILT_IN_ICEIL:
- case BUILT_IN_LCEIL:
- case BUILT_IN_LLCEIL:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
- if (out_mode == SImode && in_mode == DFmode)
- {
- if (out_n == 4 && in_n == 2)
- return ix86_builtins[IX86_BUILTIN_CEILPD_VEC_PACK_SFIX];
- else if (out_n == 8 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_CEILPD_VEC_PACK_SFIX256];
- }
- break;
-
- case BUILT_IN_ICEILF:
- case BUILT_IN_LCEILF:
- case BUILT_IN_LLCEILF:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
- if (out_mode == SImode && in_mode == SFmode)
- {
- if (out_n == 4 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_CEILPS_SFIX];
- else if (out_n == 8 && in_n == 8)
- return ix86_builtins[IX86_BUILTIN_CEILPS_SFIX256];
- }
- break;
-
- case BUILT_IN_IRINT:
- case BUILT_IN_LRINT:
- case BUILT_IN_LLRINT:
- if (out_mode == SImode && in_mode == DFmode)
- {
- if (out_n == 4 && in_n == 2)
- return ix86_builtins[IX86_BUILTIN_VEC_PACK_SFIX];
- else if (out_n == 8 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_VEC_PACK_SFIX256];
- }
- break;
-
- case BUILT_IN_IRINTF:
- case BUILT_IN_LRINTF:
- case BUILT_IN_LLRINTF:
- if (out_mode == SImode && in_mode == SFmode)
- {
- if (out_n == 4 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_CVTPS2DQ];
- else if (out_n == 8 && in_n == 8)
- return ix86_builtins[IX86_BUILTIN_CVTPS2DQ256];
- }
- break;
-
- case BUILT_IN_IROUND:
- case BUILT_IN_LROUND:
- case BUILT_IN_LLROUND:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
- if (out_mode == SImode && in_mode == DFmode)
- {
- if (out_n == 4 && in_n == 2)
- return ix86_builtins[IX86_BUILTIN_ROUNDPD_AZ_VEC_PACK_SFIX];
- else if (out_n == 8 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_ROUNDPD_AZ_VEC_PACK_SFIX256];
- }
- break;
-
- case BUILT_IN_IROUNDF:
- case BUILT_IN_LROUNDF:
- case BUILT_IN_LLROUNDF:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
- if (out_mode == SImode && in_mode == SFmode)
- {
- if (out_n == 4 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_ROUNDPS_AZ_SFIX];
- else if (out_n == 8 && in_n == 8)
- return ix86_builtins[IX86_BUILTIN_ROUNDPS_AZ_SFIX256];
- }
- break;
-
- case BUILT_IN_COPYSIGN:
- if (out_mode == DFmode && in_mode == DFmode)
- {
- if (out_n == 2 && in_n == 2)
- return ix86_builtins[IX86_BUILTIN_CPYSGNPD];
- else if (out_n == 4 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_CPYSGNPD256];
- }
- break;
-
- case BUILT_IN_COPYSIGNF:
- if (out_mode == SFmode && in_mode == SFmode)
- {
- if (out_n == 4 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_CPYSGNPS];
- else if (out_n == 8 && in_n == 8)
- return ix86_builtins[IX86_BUILTIN_CPYSGNPS256];
- }
- break;
-
- case BUILT_IN_FLOOR:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
- if (out_mode == DFmode && in_mode == DFmode)
- {
- if (out_n == 2 && in_n == 2)
- return ix86_builtins[IX86_BUILTIN_FLOORPD];
- else if (out_n == 4 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_FLOORPD256];
- }
- break;
-
- case BUILT_IN_FLOORF:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
- if (out_mode == SFmode && in_mode == SFmode)
- {
- if (out_n == 4 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_FLOORPS];
- else if (out_n == 8 && in_n == 8)
- return ix86_builtins[IX86_BUILTIN_FLOORPS256];
- }
- break;
-
- case BUILT_IN_CEIL:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
- if (out_mode == DFmode && in_mode == DFmode)
- {
- if (out_n == 2 && in_n == 2)
- return ix86_builtins[IX86_BUILTIN_CEILPD];
- else if (out_n == 4 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_CEILPD256];
- }
- break;
-
- case BUILT_IN_CEILF:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
- if (out_mode == SFmode && in_mode == SFmode)
- {
- if (out_n == 4 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_CEILPS];
- else if (out_n == 8 && in_n == 8)
- return ix86_builtins[IX86_BUILTIN_CEILPS256];
- }
- break;
-
- case BUILT_IN_TRUNC:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
- if (out_mode == DFmode && in_mode == DFmode)
- {
- if (out_n == 2 && in_n == 2)
- return ix86_builtins[IX86_BUILTIN_TRUNCPD];
- else if (out_n == 4 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_TRUNCPD256];
- }
- break;
-
- case BUILT_IN_TRUNCF:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
- if (out_mode == SFmode && in_mode == SFmode)
- {
- if (out_n == 4 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_TRUNCPS];
- else if (out_n == 8 && in_n == 8)
- return ix86_builtins[IX86_BUILTIN_TRUNCPS256];
- }
- break;
-
- case BUILT_IN_RINT:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
- if (out_mode == DFmode && in_mode == DFmode)
- {
- if (out_n == 2 && in_n == 2)
- return ix86_builtins[IX86_BUILTIN_RINTPD];
- else if (out_n == 4 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_RINTPD256];
- }
- break;
-
- case BUILT_IN_RINTF:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
- if (out_mode == SFmode && in_mode == SFmode)
- {
- if (out_n == 4 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_RINTPS];
- else if (out_n == 8 && in_n == 8)
- return ix86_builtins[IX86_BUILTIN_RINTPS256];
- }
- break;
-
- case BUILT_IN_ROUND:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
- if (out_mode == DFmode && in_mode == DFmode)
- {
- if (out_n == 2 && in_n == 2)
- return ix86_builtins[IX86_BUILTIN_ROUNDPD_AZ];
- else if (out_n == 4 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_ROUNDPD_AZ256];
- }
- break;
-
- case BUILT_IN_ROUNDF:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
- if (out_mode == SFmode && in_mode == SFmode)
- {
- if (out_n == 4 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_ROUNDPS_AZ];
- else if (out_n == 8 && in_n == 8)
- return ix86_builtins[IX86_BUILTIN_ROUNDPS_AZ256];
- }
- break;
-
- case BUILT_IN_FMA:
- if (out_mode == DFmode && in_mode == DFmode)
- {
- if (out_n == 2 && in_n == 2)
- return ix86_builtins[IX86_BUILTIN_VFMADDPD];
- if (out_n == 4 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_VFMADDPD256];
- }
- break;
-
- case BUILT_IN_FMAF:
- if (out_mode == SFmode && in_mode == SFmode)
- {
- if (out_n == 4 && in_n == 4)
- return ix86_builtins[IX86_BUILTIN_VFMADDPS];
- if (out_n == 8 && in_n == 8)
- return ix86_builtins[IX86_BUILTIN_VFMADDPS256];
- }
- break;
-
- default:
- break;
- }
-
- /* Dispatch to a handler for a vectorization library. */
- if (ix86_veclib_handler)
- return ix86_veclib_handler ((enum built_in_function) fn, type_out,
- type_in);
-
- return NULL_TREE;
-}
-
-/* Handler for an SVML-style interface to
- a library with vectorized intrinsics. */
-
-static tree
-ix86_veclibabi_svml (enum built_in_function fn, tree type_out, tree type_in)
-{
- char name[20];
- tree fntype, new_fndecl, args;
- unsigned arity;
- const char *bname;
- enum machine_mode el_mode, in_mode;
- int n, in_n;
-
- /* The SVML is suitable for unsafe math only. */
- if (!flag_unsafe_math_optimizations)
- return NULL_TREE;
-
- el_mode = TYPE_MODE (TREE_TYPE (type_out));
- n = TYPE_VECTOR_SUBPARTS (type_out);
- in_mode = TYPE_MODE (TREE_TYPE (type_in));
- in_n = TYPE_VECTOR_SUBPARTS (type_in);
- if (el_mode != in_mode
- || n != in_n)
- return NULL_TREE;
-
- switch (fn)
- {
- case BUILT_IN_EXP:
- case BUILT_IN_LOG:
- case BUILT_IN_LOG10:
- case BUILT_IN_POW:
- case BUILT_IN_TANH:
- case BUILT_IN_TAN:
- case BUILT_IN_ATAN:
- case BUILT_IN_ATAN2:
- case BUILT_IN_ATANH:
- case BUILT_IN_CBRT:
- case BUILT_IN_SINH:
- case BUILT_IN_SIN:
- case BUILT_IN_ASINH:
- case BUILT_IN_ASIN:
- case BUILT_IN_COSH:
- case BUILT_IN_COS:
- case BUILT_IN_ACOSH:
- case BUILT_IN_ACOS:
- if (el_mode != DFmode || n != 2)
- return NULL_TREE;
- break;
-
- case BUILT_IN_EXPF:
- case BUILT_IN_LOGF:
- case BUILT_IN_LOG10F:
- case BUILT_IN_POWF:
- case BUILT_IN_TANHF:
- case BUILT_IN_TANF:
- case BUILT_IN_ATANF:
- case BUILT_IN_ATAN2F:
- case BUILT_IN_ATANHF:
- case BUILT_IN_CBRTF:
- case BUILT_IN_SINHF:
- case BUILT_IN_SINF:
- case BUILT_IN_ASINHF:
- case BUILT_IN_ASINF:
- case BUILT_IN_COSHF:
- case BUILT_IN_COSF:
- case BUILT_IN_ACOSHF:
- case BUILT_IN_ACOSF:
- if (el_mode != SFmode || n != 4)
- return NULL_TREE;
- break;
-
- default:
- return NULL_TREE;
- }
-
- bname = IDENTIFIER_POINTER (DECL_NAME (builtin_decl_implicit (fn)));
-
- if (fn == BUILT_IN_LOGF)
- strcpy (name, "vmlsLn4");
- else if (fn == BUILT_IN_LOG)
- strcpy (name, "vmldLn2");
- else if (n == 4)
- {
- sprintf (name, "vmls%s", bname+10);
- name[strlen (name)-1] = '4';
- }
- else
- sprintf (name, "vmld%s2", bname+10);
-
- /* Convert to uppercase. */
- name[4] &= ~0x20;
-
- arity = 0;
- for (args = DECL_ARGUMENTS (builtin_decl_implicit (fn));
- args;
- args = TREE_CHAIN (args))
- arity++;
-
- if (arity == 1)
- fntype = build_function_type_list (type_out, type_in, NULL);
- else
- fntype = build_function_type_list (type_out, type_in, type_in, NULL);
-
- /* Build a function declaration for the vectorized function. */
- new_fndecl = build_decl (BUILTINS_LOCATION,
- FUNCTION_DECL, get_identifier (name), fntype);
- TREE_PUBLIC (new_fndecl) = 1;
- DECL_EXTERNAL (new_fndecl) = 1;
- DECL_IS_NOVOPS (new_fndecl) = 1;
- TREE_READONLY (new_fndecl) = 1;
-
- return new_fndecl;
-}
-
-/* Handler for an ACML-style interface to
- a library with vectorized intrinsics. */
-
-static tree
-ix86_veclibabi_acml (enum built_in_function fn, tree type_out, tree type_in)
-{
- char name[20] = "__vr.._";
- tree fntype, new_fndecl, args;
- unsigned arity;
- const char *bname;
- enum machine_mode el_mode, in_mode;
- int n, in_n;
-
- /* The ACML is 64bits only and suitable for unsafe math only as
- it does not correctly support parts of IEEE with the required
- precision such as denormals. */
- if (!TARGET_64BIT
- || !flag_unsafe_math_optimizations)
- return NULL_TREE;
-
- el_mode = TYPE_MODE (TREE_TYPE (type_out));
- n = TYPE_VECTOR_SUBPARTS (type_out);
- in_mode = TYPE_MODE (TREE_TYPE (type_in));
- in_n = TYPE_VECTOR_SUBPARTS (type_in);
- if (el_mode != in_mode
- || n != in_n)
- return NULL_TREE;
-
- switch (fn)
- {
- case BUILT_IN_SIN:
- case BUILT_IN_COS:
- case BUILT_IN_EXP:
- case BUILT_IN_LOG:
- case BUILT_IN_LOG2:
- case BUILT_IN_LOG10:
- name[4] = 'd';
- name[5] = '2';
- if (el_mode != DFmode
- || n != 2)
- return NULL_TREE;
- break;
-
- case BUILT_IN_SINF:
- case BUILT_IN_COSF:
- case BUILT_IN_EXPF:
- case BUILT_IN_POWF:
- case BUILT_IN_LOGF:
- case BUILT_IN_LOG2F:
- case BUILT_IN_LOG10F:
- name[4] = 's';
- name[5] = '4';
- if (el_mode != SFmode
- || n != 4)
- return NULL_TREE;
- break;
-
- default:
- return NULL_TREE;
- }
-
- bname = IDENTIFIER_POINTER (DECL_NAME (builtin_decl_implicit (fn)));
- sprintf (name + 7, "%s", bname+10);
-
- arity = 0;
- for (args = DECL_ARGUMENTS (builtin_decl_implicit (fn));
- args;
- args = TREE_CHAIN (args))
- arity++;
-
- if (arity == 1)
- fntype = build_function_type_list (type_out, type_in, NULL);
- else
- fntype = build_function_type_list (type_out, type_in, type_in, NULL);
-
- /* Build a function declaration for the vectorized function. */
- new_fndecl = build_decl (BUILTINS_LOCATION,
- FUNCTION_DECL, get_identifier (name), fntype);
- TREE_PUBLIC (new_fndecl) = 1;
- DECL_EXTERNAL (new_fndecl) = 1;
- DECL_IS_NOVOPS (new_fndecl) = 1;
- TREE_READONLY (new_fndecl) = 1;
-
- return new_fndecl;
-}
-
-/* Returns a decl of a function that implements gather load with
- memory type MEM_VECTYPE and index type INDEX_VECTYPE and SCALE.
- Return NULL_TREE if it is not available. */
-
-static tree
-ix86_vectorize_builtin_gather (const_tree mem_vectype,
- const_tree index_type, int scale)
-{
- bool si;
- enum ix86_builtins code;
-
- if (! TARGET_AVX2)
- return NULL_TREE;
-
- if ((TREE_CODE (index_type) != INTEGER_TYPE
- && !POINTER_TYPE_P (index_type))
- || (TYPE_MODE (index_type) != SImode
- && TYPE_MODE (index_type) != DImode))
- return NULL_TREE;
-
- if (TYPE_PRECISION (index_type) > POINTER_SIZE)
- return NULL_TREE;
-
- /* v*gather* insn sign extends index to pointer mode. */
- if (TYPE_PRECISION (index_type) < POINTER_SIZE
- && TYPE_UNSIGNED (index_type))
- return NULL_TREE;
-
- if (scale <= 0
- || scale > 8
- || (scale & (scale - 1)) != 0)
- return NULL_TREE;
-
- si = TYPE_MODE (index_type) == SImode;
- switch (TYPE_MODE (mem_vectype))
- {
- case V2DFmode:
- code = si ? IX86_BUILTIN_GATHERSIV2DF : IX86_BUILTIN_GATHERDIV2DF;
- break;
- case V4DFmode:
- code = si ? IX86_BUILTIN_GATHERALTSIV4DF : IX86_BUILTIN_GATHERDIV4DF;
- break;
- case V2DImode:
- code = si ? IX86_BUILTIN_GATHERSIV2DI : IX86_BUILTIN_GATHERDIV2DI;
- break;
- case V4DImode:
- code = si ? IX86_BUILTIN_GATHERALTSIV4DI : IX86_BUILTIN_GATHERDIV4DI;
- break;
- case V4SFmode:
- code = si ? IX86_BUILTIN_GATHERSIV4SF : IX86_BUILTIN_GATHERDIV4SF;
- break;
- case V8SFmode:
- code = si ? IX86_BUILTIN_GATHERSIV8SF : IX86_BUILTIN_GATHERALTDIV8SF;
- break;
- case V4SImode:
- code = si ? IX86_BUILTIN_GATHERSIV4SI : IX86_BUILTIN_GATHERDIV4SI;
- break;
- case V8SImode:
- code = si ? IX86_BUILTIN_GATHERSIV8SI : IX86_BUILTIN_GATHERALTDIV8SI;
- break;
- default:
- return NULL_TREE;
- }
-
- return ix86_builtins[code];
-}
-
-/* Returns a code for a target-specific builtin that implements
- reciprocal of the function, or NULL_TREE if not available. */
-
-static tree
-ix86_builtin_reciprocal (unsigned int fn, bool md_fn,
- bool sqrt ATTRIBUTE_UNUSED)
-{
- if (! (TARGET_SSE_MATH && !optimize_insn_for_size_p ()
- && flag_finite_math_only && !flag_trapping_math
- && flag_unsafe_math_optimizations))
- return NULL_TREE;
-
- if (md_fn)
- /* Machine dependent builtins. */
- switch (fn)
- {
- /* Vectorized version of sqrt to rsqrt conversion. */
- case IX86_BUILTIN_SQRTPS_NR:
- return ix86_builtins[IX86_BUILTIN_RSQRTPS_NR];
-
- case IX86_BUILTIN_SQRTPS_NR256:
- return ix86_builtins[IX86_BUILTIN_RSQRTPS_NR256];
-
- default:
- return NULL_TREE;
- }
- else
- /* Normal builtins. */
- switch (fn)
- {
- /* Sqrt to rsqrt conversion. */
- case BUILT_IN_SQRTF:
- return ix86_builtins[IX86_BUILTIN_RSQRTF];
-
- default:
- return NULL_TREE;
- }
-}
-
-/* Helper for avx_vpermilps256_operand et al. This is also used by
- the expansion functions to turn the parallel back into a mask.
- The return value is 0 for no match and the imm8+1 for a match. */
-
-int
-avx_vpermilp_parallel (rtx par, enum machine_mode mode)
-{
- unsigned i, nelt = GET_MODE_NUNITS (mode);
- unsigned mask = 0;
- unsigned char ipar[8] = {}; /* Silence -Wuninitialized warning. */
-
- if (XVECLEN (par, 0) != (int) nelt)
- return 0;
-
- /* Validate that all of the elements are constants, and not totally
- out of range. Copy the data into an integral array to make the
- subsequent checks easier. */
- for (i = 0; i < nelt; ++i)
- {
- rtx er = XVECEXP (par, 0, i);
- unsigned HOST_WIDE_INT ei;
-
- if (!CONST_INT_P (er))
- return 0;
- ei = INTVAL (er);
- if (ei >= nelt)
- return 0;
- ipar[i] = ei;
- }
-
- switch (mode)
- {
- case V4DFmode:
- /* In the 256-bit DFmode case, we can only move elements within
- a 128-bit lane. */
- for (i = 0; i < 2; ++i)
- {
- if (ipar[i] >= 2)
- return 0;
- mask |= ipar[i] << i;
- }
- for (i = 2; i < 4; ++i)
- {
- if (ipar[i] < 2)
- return 0;
- mask |= (ipar[i] - 2) << i;
- }
- break;
-
- case V8SFmode:
- /* In the 256-bit SFmode case, we have full freedom of movement
- within the low 128-bit lane, but the high 128-bit lane must
- mirror the exact same pattern. */
- for (i = 0; i < 4; ++i)
- if (ipar[i] + 4 != ipar[i + 4])
- return 0;
- nelt = 4;
- /* FALLTHRU */
-
- case V2DFmode:
- case V4SFmode:
- /* In the 128-bit case, we've full freedom in the placement of
- the elements from the source operand. */
- for (i = 0; i < nelt; ++i)
- mask |= ipar[i] << (i * (nelt / 2));
- break;
-
- default:
- gcc_unreachable ();
- }
-
- /* Make sure success has a non-zero value by adding one. */
- return mask + 1;
-}
-
-/* Helper for avx_vperm2f128_v4df_operand et al. This is also used by
- the expansion functions to turn the parallel back into a mask.
- The return value is 0 for no match and the imm8+1 for a match. */
-
-int
-avx_vperm2f128_parallel (rtx par, enum machine_mode mode)
-{
- unsigned i, nelt = GET_MODE_NUNITS (mode), nelt2 = nelt / 2;
- unsigned mask = 0;
- unsigned char ipar[8] = {}; /* Silence -Wuninitialized warning. */
-
- if (XVECLEN (par, 0) != (int) nelt)
- return 0;
-
- /* Validate that all of the elements are constants, and not totally
- out of range. Copy the data into an integral array to make the
- subsequent checks easier. */
- for (i = 0; i < nelt; ++i)
- {
- rtx er = XVECEXP (par, 0, i);
- unsigned HOST_WIDE_INT ei;
-
- if (!CONST_INT_P (er))
- return 0;
- ei = INTVAL (er);
- if (ei >= 2 * nelt)
- return 0;
- ipar[i] = ei;
- }
-
- /* Validate that the halves of the permute are halves. */
- for (i = 0; i < nelt2 - 1; ++i)
- if (ipar[i] + 1 != ipar[i + 1])
- return 0;
- for (i = nelt2; i < nelt - 1; ++i)
- if (ipar[i] + 1 != ipar[i + 1])
- return 0;
-
- /* Reconstruct the mask. */
- for (i = 0; i < 2; ++i)
- {
- unsigned e = ipar[i * nelt2];
- if (e % nelt2)
- return 0;
- e /= nelt2;
- mask |= e << (i * 4);
- }
-
- /* Make sure success has a non-zero value by adding one. */
- return mask + 1;
-}
-
-/* Store OPERAND to the memory after reload is completed. This means
- that we can't easily use assign_stack_local. */
-rtx
-ix86_force_to_memory (enum machine_mode mode, rtx operand)
-{
- rtx result;
-
- gcc_assert (reload_completed);
- if (ix86_using_red_zone ())
- {
- result = gen_rtx_MEM (mode,
- gen_rtx_PLUS (Pmode,
- stack_pointer_rtx,
- GEN_INT (-RED_ZONE_SIZE)));
- emit_move_insn (result, operand);
- }
- else if (TARGET_64BIT)
- {
- switch (mode)
- {
- case HImode:
- case SImode:
- operand = gen_lowpart (DImode, operand);
- /* FALLTHRU */
- case DImode:
- emit_insn (
- gen_rtx_SET (VOIDmode,
- gen_rtx_MEM (DImode,
- gen_rtx_PRE_DEC (DImode,
- stack_pointer_rtx)),
- operand));
- break;
- default:
- gcc_unreachable ();
- }
- result = gen_rtx_MEM (mode, stack_pointer_rtx);
- }
- else
- {
- switch (mode)
- {
- case DImode:
- {
- rtx operands[2];
- split_double_mode (mode, &operand, 1, operands, operands + 1);
- emit_insn (
- gen_rtx_SET (VOIDmode,
- gen_rtx_MEM (SImode,
- gen_rtx_PRE_DEC (Pmode,
- stack_pointer_rtx)),
- operands[1]));
- emit_insn (
- gen_rtx_SET (VOIDmode,
- gen_rtx_MEM (SImode,
- gen_rtx_PRE_DEC (Pmode,
- stack_pointer_rtx)),
- operands[0]));
- }
- break;
- case HImode:
- /* Store HImodes as SImodes. */
- operand = gen_lowpart (SImode, operand);
- /* FALLTHRU */
- case SImode:
- emit_insn (
- gen_rtx_SET (VOIDmode,
- gen_rtx_MEM (GET_MODE (operand),
- gen_rtx_PRE_DEC (SImode,
- stack_pointer_rtx)),
- operand));
- break;
- default:
- gcc_unreachable ();
- }
- result = gen_rtx_MEM (mode, stack_pointer_rtx);
- }
- return result;
-}
-
-/* Free operand from the memory. */
-void
-ix86_free_from_memory (enum machine_mode mode)
-{
- if (!ix86_using_red_zone ())
- {
- int size;
-
- if (mode == DImode || TARGET_64BIT)
- size = 8;
- else
- size = 4;
- /* Use LEA to deallocate stack space. In peephole2 it will be converted
- to pop or add instruction if registers are available. */
- emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx,
- gen_rtx_PLUS (Pmode, stack_pointer_rtx,
- GEN_INT (size))));
- }
-}
-
-/* Return a register priority for hard reg REGNO. */
-static int
-ix86_register_priority (int hard_regno)
-{
- /* ebp and r13 as the base always wants a displacement, r12 as the
- base always wants an index. So discourage their usage in an
- address. */
- if (hard_regno == R12_REG || hard_regno == R13_REG)
- return 0;
- if (hard_regno == BP_REG)
- return 1;
- /* New x86-64 int registers result in bigger code size. Discourage
- them. */
- if (FIRST_REX_INT_REG <= hard_regno && hard_regno <= LAST_REX_INT_REG)
- return 2;
- /* New x86-64 SSE registers result in bigger code size. Discourage
- them. */
- if (FIRST_REX_SSE_REG <= hard_regno && hard_regno <= LAST_REX_SSE_REG)
- return 2;
- /* Usage of AX register results in smaller code. Prefer it. */
- if (hard_regno == 0)
- return 4;
- return 3;
-}
-
-/* Implement TARGET_PREFERRED_RELOAD_CLASS.
-
- Put float CONST_DOUBLE in the constant pool instead of fp regs.
- QImode must go into class Q_REGS.
- Narrow ALL_REGS to GENERAL_REGS. This supports allowing movsf and
- movdf to do mem-to-mem moves through integer regs. */
-
-static reg_class_t
-ix86_preferred_reload_class (rtx x, reg_class_t regclass)
-{
- enum machine_mode mode = GET_MODE (x);
-
- /* We're only allowed to return a subclass of CLASS. Many of the
- following checks fail for NO_REGS, so eliminate that early. */
- if (regclass == NO_REGS)
- return NO_REGS;
-
- /* All classes can load zeros. */
- if (x == CONST0_RTX (mode))
- return regclass;
-
- /* Force constants into memory if we are loading a (nonzero) constant into
- an MMX or SSE register. This is because there are no MMX/SSE instructions
- to load from a constant. */
- if (CONSTANT_P (x)
- && (MAYBE_MMX_CLASS_P (regclass) || MAYBE_SSE_CLASS_P (regclass)))
- return NO_REGS;
-
- /* Prefer SSE regs only, if we can use them for math. */
- if (TARGET_SSE_MATH && !TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (mode))
- return SSE_CLASS_P (regclass) ? regclass : NO_REGS;
-
- /* Floating-point constants need more complex checks. */
- if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != VOIDmode)
- {
- /* General regs can load everything. */
- if (reg_class_subset_p (regclass, GENERAL_REGS))
- return regclass;
-
- /* Floats can load 0 and 1 plus some others. Note that we eliminated
- zero above. We only want to wind up preferring 80387 registers if
- we plan on doing computation with them. */
- if (TARGET_80387
- && standard_80387_constant_p (x) > 0)
- {
- /* Limit class to non-sse. */
- if (regclass == FLOAT_SSE_REGS)
- return FLOAT_REGS;
- if (regclass == FP_TOP_SSE_REGS)
- return FP_TOP_REG;
- if (regclass == FP_SECOND_SSE_REGS)
- return FP_SECOND_REG;
- if (regclass == FLOAT_INT_REGS || regclass == FLOAT_REGS)
- return regclass;
- }
-
- return NO_REGS;
- }
-
- /* Generally when we see PLUS here, it's the function invariant
- (plus soft-fp const_int). Which can only be computed into general
- regs. */
- if (GET_CODE (x) == PLUS)
- return reg_class_subset_p (regclass, GENERAL_REGS) ? regclass : NO_REGS;
-
- /* QImode constants are easy to load, but non-constant QImode data
- must go into Q_REGS. */
- if (GET_MODE (x) == QImode && !CONSTANT_P (x))
- {
- if (reg_class_subset_p (regclass, Q_REGS))
- return regclass;
- if (reg_class_subset_p (Q_REGS, regclass))
- return Q_REGS;
- return NO_REGS;
- }
-
- return regclass;
-}
-
-/* Discourage putting floating-point values in SSE registers unless
- SSE math is being used, and likewise for the 387 registers. */
-static reg_class_t
-ix86_preferred_output_reload_class (rtx x, reg_class_t regclass)
-{
- enum machine_mode mode = GET_MODE (x);
-
- /* Restrict the output reload class to the register bank that we are doing
- math on. If we would like not to return a subset of CLASS, reject this
- alternative: if reload cannot do this, it will still use its choice. */
- mode = GET_MODE (x);
- if (TARGET_SSE_MATH && SSE_FLOAT_MODE_P (mode))
- return MAYBE_SSE_CLASS_P (regclass) ? SSE_REGS : NO_REGS;
-
- if (X87_FLOAT_MODE_P (mode))
- {
- if (regclass == FP_TOP_SSE_REGS)
- return FP_TOP_REG;
- else if (regclass == FP_SECOND_SSE_REGS)
- return FP_SECOND_REG;
- else
- return FLOAT_CLASS_P (regclass) ? regclass : NO_REGS;
- }
-
- return regclass;
-}
-
-static reg_class_t
-ix86_secondary_reload (bool in_p, rtx x, reg_class_t rclass,
- enum machine_mode mode, secondary_reload_info *sri)
-{
- /* Double-word spills from general registers to non-offsettable memory
- references (zero-extended addresses) require special handling. */
- if (TARGET_64BIT
- && MEM_P (x)
- && GET_MODE_SIZE (mode) > UNITS_PER_WORD
- && rclass == GENERAL_REGS
- && !offsettable_memref_p (x))
- {
- sri->icode = (in_p
- ? CODE_FOR_reload_noff_load
- : CODE_FOR_reload_noff_store);
- /* Add the cost of moving address to a temporary. */
- sri->extra_cost = 1;
-
- return NO_REGS;
- }
-
- /* QImode spills from non-QI registers require
- intermediate register on 32bit targets. */
- if (!TARGET_64BIT
- && !in_p && mode == QImode
- && (rclass == GENERAL_REGS
- || rclass == LEGACY_REGS
- || rclass == NON_Q_REGS
- || rclass == SIREG
- || rclass == DIREG
- || rclass == INDEX_REGS))
- {
- int regno;
-
- if (REG_P (x))
- regno = REGNO (x);
- else
- regno = -1;
-
- if (regno >= FIRST_PSEUDO_REGISTER || GET_CODE (x) == SUBREG)
- regno = true_regnum (x);
-
- /* Return Q_REGS if the operand is in memory. */
- if (regno == -1)
- return Q_REGS;
- }
-
- /* This condition handles corner case where an expression involving
- pointers gets vectorized. We're trying to use the address of a
- stack slot as a vector initializer.
-
- (set (reg:V2DI 74 [ vect_cst_.2 ])
- (vec_duplicate:V2DI (reg/f:DI 20 frame)))
-
- Eventually frame gets turned into sp+offset like this:
-
- (set (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
- (vec_duplicate:V2DI (plus:DI (reg/f:DI 7 sp)
- (const_int 392 [0x188]))))
-
- That later gets turned into:
-
- (set (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
- (vec_duplicate:V2DI (plus:DI (reg/f:DI 7 sp)
- (mem/u/c/i:DI (symbol_ref/u:DI ("*.LC0") [flags 0x2]) [0 S8 A64]))))
-
- We'll have the following reload recorded:
-
- Reload 0: reload_in (DI) =
- (plus:DI (reg/f:DI 7 sp)
- (mem/u/c/i:DI (symbol_ref/u:DI ("*.LC0") [flags 0x2]) [0 S8 A64]))
- reload_out (V2DI) = (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
- SSE_REGS, RELOAD_OTHER (opnum = 0), can't combine
- reload_in_reg: (plus:DI (reg/f:DI 7 sp) (const_int 392 [0x188]))
- reload_out_reg: (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
- reload_reg_rtx: (reg:V2DI 22 xmm1)
-
- Which isn't going to work since SSE instructions can't handle scalar
- additions. Returning GENERAL_REGS forces the addition into integer
- register and reload can handle subsequent reloads without problems. */
-
- if (in_p && GET_CODE (x) == PLUS
- && SSE_CLASS_P (rclass)
- && SCALAR_INT_MODE_P (mode))
- return GENERAL_REGS;
-
- return NO_REGS;
-}
-
-/* Implement TARGET_CLASS_LIKELY_SPILLED_P. */
-
-static bool
-ix86_class_likely_spilled_p (reg_class_t rclass)
-{
- switch (rclass)
- {
- case AREG:
- case DREG:
- case CREG:
- case BREG:
- case AD_REGS:
- case SIREG:
- case DIREG:
- case SSE_FIRST_REG:
- case FP_TOP_REG:
- case FP_SECOND_REG:
- return true;
-
- default:
- break;
- }
-
- return false;
-}
-
-/* If we are copying between general and FP registers, we need a memory
- location. The same is true for SSE and MMX registers.
-
- To optimize register_move_cost performance, allow inline variant.
-
- The macro can't work reliably when one of the CLASSES is class containing
- registers from multiple units (SSE, MMX, integer). We avoid this by never
- combining those units in single alternative in the machine description.
- Ensure that this constraint holds to avoid unexpected surprises.
-
- When STRICT is false, we are being called from REGISTER_MOVE_COST, so do not
- enforce these sanity checks. */
-
-static inline bool
-inline_secondary_memory_needed (enum reg_class class1, enum reg_class class2,
- enum machine_mode mode, int strict)
-{
- if (MAYBE_FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class1)
- || MAYBE_FLOAT_CLASS_P (class2) != FLOAT_CLASS_P (class2)
- || MAYBE_SSE_CLASS_P (class1) != SSE_CLASS_P (class1)
- || MAYBE_SSE_CLASS_P (class2) != SSE_CLASS_P (class2)
- || MAYBE_MMX_CLASS_P (class1) != MMX_CLASS_P (class1)
- || MAYBE_MMX_CLASS_P (class2) != MMX_CLASS_P (class2))
- {
- gcc_assert (!strict || lra_in_progress);
- return true;
- }
-
- if (FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class2))
- return true;
-
- /* ??? This is a lie. We do have moves between mmx/general, and for
- mmx/sse2. But by saying we need secondary memory we discourage the
- register allocator from using the mmx registers unless needed. */
- if (MMX_CLASS_P (class1) != MMX_CLASS_P (class2))
- return true;
-
- if (SSE_CLASS_P (class1) != SSE_CLASS_P (class2))
- {
- /* SSE1 doesn't have any direct moves from other classes. */
- if (!TARGET_SSE2)
- return true;
-
- /* If the target says that inter-unit moves are more expensive
- than moving through memory, then don't generate them. */
- if (!TARGET_INTER_UNIT_MOVES)
- return true;
-
- /* Between SSE and general, we have moves no larger than word size. */
- if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
- return true;
- }
-
- return false;
-}
-
-bool
-ix86_secondary_memory_needed (enum reg_class class1, enum reg_class class2,
- enum machine_mode mode, int strict)
-{
- return inline_secondary_memory_needed (class1, class2, mode, strict);
-}
-
-/* Implement the TARGET_CLASS_MAX_NREGS hook.
-
- On the 80386, this is the size of MODE in words,
- except in the FP regs, where a single reg is always enough. */
-
-static unsigned char
-ix86_class_max_nregs (reg_class_t rclass, enum machine_mode mode)
-{
- if (MAYBE_INTEGER_CLASS_P (rclass))
- {
- if (mode == XFmode)
- return (TARGET_64BIT ? 2 : 3);
- else if (mode == XCmode)
- return (TARGET_64BIT ? 4 : 6);
- else
- return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
- }
- else
- {
- if (COMPLEX_MODE_P (mode))
- return 2;
- else
- return 1;
- }
-}
-
-/* Return true if the registers in CLASS cannot represent the change from
- modes FROM to TO. */
-
-bool
-ix86_cannot_change_mode_class (enum machine_mode from, enum machine_mode to,
- enum reg_class regclass)
-{
- if (from == to)
- return false;
-
- /* x87 registers can't do subreg at all, as all values are reformatted
- to extended precision. */
- if (MAYBE_FLOAT_CLASS_P (regclass))
- return true;
-
- if (MAYBE_SSE_CLASS_P (regclass) || MAYBE_MMX_CLASS_P (regclass))
- {
- /* Vector registers do not support QI or HImode loads. If we don't
- disallow a change to these modes, reload will assume it's ok to
- drop the subreg from (subreg:SI (reg:HI 100) 0). This affects
- the vec_dupv4hi pattern. */
- if (GET_MODE_SIZE (from) < 4)
- return true;
-
- /* Vector registers do not support subreg with nonzero offsets, which
- are otherwise valid for integer registers. Since we can't see
- whether we have a nonzero offset from here, prohibit all
- nonparadoxical subregs changing size. */
- if (GET_MODE_SIZE (to) < GET_MODE_SIZE (from))
- return true;
- }
-
- return false;
-}
-
-/* Return the cost of moving data of mode M between a
- register and memory. A value of 2 is the default; this cost is
- relative to those in `REGISTER_MOVE_COST'.
-
- This function is used extensively by register_move_cost that is used to
- build tables at startup. Make it inline in this case.
- When IN is 2, return maximum of in and out 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.
-
- Model also increased moving costs of QImode registers in non
- Q_REGS classes.
- */
-static inline int
-inline_memory_move_cost (enum machine_mode mode, enum reg_class regclass,
- int in)
-{
- int cost;
- if (FLOAT_CLASS_P (regclass))
- {
- int index;
- switch (mode)
- {
- case SFmode:
- index = 0;
- break;
- case DFmode:
- index = 1;
- break;
- case XFmode:
- index = 2;
- break;
- default:
- return 100;
- }
- if (in == 2)
- return MAX (ix86_cost->fp_load [index], ix86_cost->fp_store [index]);
- return in ? ix86_cost->fp_load [index] : ix86_cost->fp_store [index];
- }
- if (SSE_CLASS_P (regclass))
- {
- int index;
- switch (GET_MODE_SIZE (mode))
- {
- case 4:
- index = 0;
- break;
- case 8:
- index = 1;
- break;
- case 16:
- index = 2;
- break;
- default:
- return 100;
- }
- if (in == 2)
- return MAX (ix86_cost->sse_load [index], ix86_cost->sse_store [index]);
- return in ? ix86_cost->sse_load [index] : ix86_cost->sse_store [index];
- }
- if (MMX_CLASS_P (regclass))
- {
- int index;
- switch (GET_MODE_SIZE (mode))
- {
- case 4:
- index = 0;
- break;
- case 8:
- index = 1;
- break;
- default:
- return 100;
- }
- if (in)
- return MAX (ix86_cost->mmx_load [index], ix86_cost->mmx_store [index]);
- return in ? ix86_cost->mmx_load [index] : ix86_cost->mmx_store [index];
- }
- switch (GET_MODE_SIZE (mode))
- {
- case 1:
- if (Q_CLASS_P (regclass) || TARGET_64BIT)
- {
- if (!in)
- return ix86_cost->int_store[0];
- if (TARGET_PARTIAL_REG_DEPENDENCY
- && optimize_function_for_speed_p (cfun))
- cost = ix86_cost->movzbl_load;
- else
- cost = ix86_cost->int_load[0];
- if (in == 2)
- return MAX (cost, ix86_cost->int_store[0]);
- return cost;
- }
- else
- {
- if (in == 2)
- return MAX (ix86_cost->movzbl_load, ix86_cost->int_store[0] + 4);
- if (in)
- return ix86_cost->movzbl_load;
- else
- return ix86_cost->int_store[0] + 4;
- }
- break;
- case 2:
- if (in == 2)
- return MAX (ix86_cost->int_load[1], ix86_cost->int_store[1]);
- return in ? ix86_cost->int_load[1] : ix86_cost->int_store[1];
- default:
- /* Compute number of 32bit moves needed. TFmode is moved as XFmode. */
- if (mode == TFmode)
- mode = XFmode;
- if (in == 2)
- cost = MAX (ix86_cost->int_load[2] , ix86_cost->int_store[2]);
- else if (in)
- cost = ix86_cost->int_load[2];
- else
- cost = ix86_cost->int_store[2];
- return (cost * (((int) GET_MODE_SIZE (mode)
- + UNITS_PER_WORD - 1) / UNITS_PER_WORD));
- }
-}
-
-static int
-ix86_memory_move_cost (enum machine_mode mode, reg_class_t regclass,
- bool in)
-{
- return inline_memory_move_cost (mode, (enum reg_class) regclass, in ? 1 : 0);
-}
-
-
-/* Return the cost of moving data from a register in class CLASS1 to
- one in class CLASS2.
-
- 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. */
-
-static int
-ix86_register_move_cost (enum machine_mode mode, reg_class_t class1_i,
- reg_class_t class2_i)
-{
- enum reg_class class1 = (enum reg_class) class1_i;
- enum reg_class class2 = (enum reg_class) class2_i;
-
- /* In case we require secondary memory, compute cost of the store followed
- by load. In order to avoid bad register allocation choices, we need
- for this to be *at least* as high as the symmetric MEMORY_MOVE_COST. */
-
- if (inline_secondary_memory_needed (class1, class2, mode, 0))
- {
- int cost = 1;
-
- cost += inline_memory_move_cost (mode, class1, 2);
- cost += inline_memory_move_cost (mode, class2, 2);
-
- /* In case of copying from general_purpose_register we may emit multiple
- stores followed by single load causing memory size mismatch stall.
- Count this as arbitrarily high cost of 20. */
- if (targetm.class_max_nregs (class1, mode)
- > targetm.class_max_nregs (class2, mode))
- cost += 20;
-
- /* In the case of FP/MMX moves, the registers actually overlap, and we
- have to switch modes in order to treat them differently. */
- if ((MMX_CLASS_P (class1) && MAYBE_FLOAT_CLASS_P (class2))
- || (MMX_CLASS_P (class2) && MAYBE_FLOAT_CLASS_P (class1)))
- cost += 20;
-
- return cost;
- }
-
- /* Moves between SSE/MMX and integer unit are expensive. */
- if (MMX_CLASS_P (class1) != MMX_CLASS_P (class2)
- || SSE_CLASS_P (class1) != SSE_CLASS_P (class2))
-
- /* ??? By keeping returned value relatively high, we limit the number
- of moves between integer and MMX/SSE registers for all targets.
- Additionally, high value prevents problem with x86_modes_tieable_p(),
- where integer modes in MMX/SSE registers are not tieable
- because of missing QImode and HImode moves to, from or between
- MMX/SSE registers. */
- return MAX (8, ix86_cost->mmxsse_to_integer);
-
- if (MAYBE_FLOAT_CLASS_P (class1))
- return ix86_cost->fp_move;
- if (MAYBE_SSE_CLASS_P (class1))
- return ix86_cost->sse_move;
- if (MAYBE_MMX_CLASS_P (class1))
- return ix86_cost->mmx_move;
- return 2;
-}
-
-/* Return TRUE if hard register REGNO can hold a value of machine-mode
- MODE. */
-
-bool
-ix86_hard_regno_mode_ok (int regno, enum machine_mode mode)
-{
- /* Flags and only flags can only hold CCmode values. */
- if (CC_REGNO_P (regno))
- return GET_MODE_CLASS (mode) == MODE_CC;
- if (GET_MODE_CLASS (mode) == MODE_CC
- || GET_MODE_CLASS (mode) == MODE_RANDOM
- || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
- return false;
- if (STACK_REGNO_P (regno))
- return VALID_FP_MODE_P (mode);
- if (SSE_REGNO_P (regno))
- {
- /* We implement the move patterns for all vector modes into and
- out of SSE registers, even when no operation instructions
- are available. OImode move is available only when AVX is
- enabled. */
- return ((TARGET_AVX && mode == OImode)
- || VALID_AVX256_REG_MODE (mode)
- || VALID_SSE_REG_MODE (mode)
- || VALID_SSE2_REG_MODE (mode)
- || VALID_MMX_REG_MODE (mode)
- || VALID_MMX_REG_MODE_3DNOW (mode));
- }
- if (MMX_REGNO_P (regno))
- {
- /* We implement the move patterns for 3DNOW modes even in MMX mode,
- so if the register is available at all, then we can move data of
- the given mode into or out of it. */
- return (VALID_MMX_REG_MODE (mode)
- || VALID_MMX_REG_MODE_3DNOW (mode));
- }
-
- if (mode == QImode)
- {
- /* Take care for QImode values - they can be in non-QI regs,
- but then they do cause partial register stalls. */
- if (TARGET_64BIT || QI_REGNO_P (regno))
- return true;
- if (!TARGET_PARTIAL_REG_STALL)
- return true;
- /* LRA checks if the hard register is OK for the given mode.
- QImode values can live in non-QI regs, so we allow all
- registers here. */
- if (lra_in_progress)
- return true;
- return !can_create_pseudo_p ();
- }
- /* We handle both integer and floats in the general purpose registers. */
- else if (VALID_INT_MODE_P (mode))
- return true;
- else if (VALID_FP_MODE_P (mode))
- return true;
- else if (VALID_DFP_MODE_P (mode))
- return true;
- /* Lots of MMX code casts 8 byte vector modes to DImode. If we then go
- on to use that value in smaller contexts, this can easily force a
- pseudo to be allocated to GENERAL_REGS. Since this is no worse than
- supporting DImode, allow it. */
- else if (VALID_MMX_REG_MODE_3DNOW (mode) || VALID_MMX_REG_MODE (mode))
- return true;
-
- return false;
-}
-
-/* A subroutine of ix86_modes_tieable_p. Return true if MODE is a
- tieable integer mode. */
-
-static bool
-ix86_tieable_integer_mode_p (enum machine_mode mode)
-{
- switch (mode)
- {
- case HImode:
- case SImode:
- return true;
-
- case QImode:
- return TARGET_64BIT || !TARGET_PARTIAL_REG_STALL;
-
- case DImode:
- return TARGET_64BIT;
-
- default:
- return false;
- }
-}
-
-/* Return true if MODE1 is accessible in a register that can hold MODE2
- without copying. That is, all register classes that can hold MODE2
- can also hold MODE1. */
-
-bool
-ix86_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2)
-{
- if (mode1 == mode2)
- return true;
-
- if (ix86_tieable_integer_mode_p (mode1)
- && ix86_tieable_integer_mode_p (mode2))
- return true;
-
- /* MODE2 being XFmode implies fp stack or general regs, which means we
- can tie any smaller floating point modes to it. Note that we do not
- tie this with TFmode. */
- if (mode2 == XFmode)
- return mode1 == SFmode || mode1 == DFmode;
-
- /* MODE2 being DFmode implies fp stack, general or sse regs, which means
- that we can tie it with SFmode. */
- if (mode2 == DFmode)
- return mode1 == SFmode;
-
- /* If MODE2 is only appropriate for an SSE register, then tie with
- any other mode acceptable to SSE registers. */
- if (GET_MODE_SIZE (mode2) == 32
- && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode2))
- return (GET_MODE_SIZE (mode1) == 32
- && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode1));
- if (GET_MODE_SIZE (mode2) == 16
- && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode2))
- return (GET_MODE_SIZE (mode1) == 16
- && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode1));
-
- /* If MODE2 is appropriate for an MMX register, then tie
- with any other mode acceptable to MMX registers. */
- if (GET_MODE_SIZE (mode2) == 8
- && ix86_hard_regno_mode_ok (FIRST_MMX_REG, mode2))
- return (GET_MODE_SIZE (mode1) == 8
- && ix86_hard_regno_mode_ok (FIRST_MMX_REG, mode1));
-
- return false;
-}
-
-/* Return the cost of moving between two registers of mode MODE. */
-
-static int
-ix86_set_reg_reg_cost (enum machine_mode mode)
-{
- unsigned int units = UNITS_PER_WORD;
-
- switch (GET_MODE_CLASS (mode))
- {
- default:
- break;
-
- case MODE_CC:
- units = GET_MODE_SIZE (CCmode);
- break;
-
- case MODE_FLOAT:
- if ((TARGET_SSE && mode == TFmode)
- || (TARGET_80387 && mode == XFmode)
- || ((TARGET_80387 || TARGET_SSE2) && mode == DFmode)
- || ((TARGET_80387 || TARGET_SSE) && mode == SFmode))
- units = GET_MODE_SIZE (mode);
- break;
-
- case MODE_COMPLEX_FLOAT:
- if ((TARGET_SSE && mode == TCmode)
- || (TARGET_80387 && mode == XCmode)
- || ((TARGET_80387 || TARGET_SSE2) && mode == DCmode)
- || ((TARGET_80387 || TARGET_SSE) && mode == SCmode))
- units = GET_MODE_SIZE (mode);
- break;
-
- case MODE_VECTOR_INT:
- case MODE_VECTOR_FLOAT:
- if ((TARGET_AVX && VALID_AVX256_REG_MODE (mode))
- || (TARGET_SSE2 && VALID_SSE2_REG_MODE (mode))
- || (TARGET_SSE && VALID_SSE_REG_MODE (mode))
- || (TARGET_MMX && VALID_MMX_REG_MODE (mode)))
- units = GET_MODE_SIZE (mode);
- }
-
- /* Return the cost of moving between two registers of mode MODE,
- assuming that the move will be in pieces of at most UNITS bytes. */
- return COSTS_N_INSNS ((GET_MODE_SIZE (mode) + units - 1) / units);
-}
-
-/* Compute a (partial) cost for rtx X. Return true if the complete
- cost has been computed, and false if subexpressions should be
- scanned. In either case, *TOTAL contains the cost result. */
-
-static bool
-ix86_rtx_costs (rtx x, int code_i, int outer_code_i, int opno, int *total,
- bool speed)
-{
- enum rtx_code code = (enum rtx_code) code_i;
- enum rtx_code outer_code = (enum rtx_code) outer_code_i;
- enum machine_mode mode = GET_MODE (x);
- const struct processor_costs *cost = speed ? ix86_cost : &ix86_size_cost;
-
- switch (code)
- {
- case SET:
- if (register_operand (SET_DEST (x), VOIDmode)
- && reg_or_0_operand (SET_SRC (x), VOIDmode))
- {
- *total = ix86_set_reg_reg_cost (GET_MODE (SET_DEST (x)));
- return true;
- }
- return false;
-
- case CONST_INT:
- case CONST:
- case LABEL_REF:
- case SYMBOL_REF:
- if (TARGET_64BIT && !x86_64_immediate_operand (x, VOIDmode))
- *total = 3;
- else if (TARGET_64BIT && !x86_64_zext_immediate_operand (x, VOIDmode))
- *total = 2;
- else if (flag_pic && SYMBOLIC_CONST (x)
- && (!TARGET_64BIT
- || (!GET_CODE (x) != LABEL_REF
- && (GET_CODE (x) != SYMBOL_REF
- || !SYMBOL_REF_LOCAL_P (x)))))
- *total = 1;
- else
- *total = 0;
- return true;
-
- case CONST_DOUBLE:
- if (mode == VOIDmode)
- {
- *total = 0;
- return true;
- }
- switch (standard_80387_constant_p (x))
- {
- case 1: /* 0.0 */
- *total = 1;
- return true;
- default: /* Other constants */
- *total = 2;
- return true;
- case 0:
- case -1:
- break;
- }
- if (SSE_FLOAT_MODE_P (mode))
- {
- case CONST_VECTOR:
- switch (standard_sse_constant_p (x))
- {
- case 0:
- break;
- case 1: /* 0: xor eliminates false dependency */
- *total = 0;
- return true;
- default: /* -1: cmp contains false dependency */
- *total = 1;
- return true;
- }
- }
- /* Fall back to (MEM (SYMBOL_REF)), since that's where
- it'll probably end up. Add a penalty for size. */
- *total = (COSTS_N_INSNS (1)
- + (flag_pic != 0 && !TARGET_64BIT)
- + (mode == SFmode ? 0 : mode == DFmode ? 1 : 2));
- return true;
-
- case ZERO_EXTEND:
- /* The zero extensions is often completely free on x86_64, so make
- it as cheap as possible. */
- if (TARGET_64BIT && mode == DImode
- && GET_MODE (XEXP (x, 0)) == SImode)
- *total = 1;
- else if (TARGET_ZERO_EXTEND_WITH_AND)
- *total = cost->add;
- else
- *total = cost->movzx;
- return false;
-
- case SIGN_EXTEND:
- *total = cost->movsx;
- return false;
-
- case ASHIFT:
- if (SCALAR_INT_MODE_P (mode)
- && GET_MODE_SIZE (mode) < UNITS_PER_WORD
- && CONST_INT_P (XEXP (x, 1)))
- {
- HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
- if (value == 1)
- {
- *total = cost->add;
- return false;
- }
- if ((value == 2 || value == 3)
- && cost->lea <= cost->shift_const)
- {
- *total = cost->lea;
- return false;
- }
- }
- /* FALLTHRU */
-
- case ROTATE:
- case ASHIFTRT:
- case LSHIFTRT:
- case ROTATERT:
- if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
- {
- /* ??? Should be SSE vector operation cost. */
- /* At least for published AMD latencies, this really is the same
- as the latency for a simple fpu operation like fabs. */
- /* V*QImode is emulated with 1-11 insns. */
- if (mode == V16QImode || mode == V32QImode)
- {
- int count = 11;
- if (TARGET_XOP && mode == V16QImode)
- {
- /* For XOP we use vpshab, which requires a broadcast of the
- value to the variable shift insn. For constants this
- means a V16Q const in mem; even when we can perform the
- shift with one insn set the cost to prefer paddb. */
- if (CONSTANT_P (XEXP (x, 1)))
- {
- *total = (cost->fabs
- + rtx_cost (XEXP (x, 0), code, 0, speed)
- + (speed ? 2 : COSTS_N_BYTES (16)));
- return true;
- }
- count = 3;
- }
- else if (TARGET_SSSE3)
- count = 7;
- *total = cost->fabs * count;
- }
- else
- *total = cost->fabs;
- }
- else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
- {
- if (CONST_INT_P (XEXP (x, 1)))
- {
- if (INTVAL (XEXP (x, 1)) > 32)
- *total = cost->shift_const + COSTS_N_INSNS (2);
- else
- *total = cost->shift_const * 2;
- }
- else
- {
- if (GET_CODE (XEXP (x, 1)) == AND)
- *total = cost->shift_var * 2;
- else
- *total = cost->shift_var * 6 + COSTS_N_INSNS (2);
- }
- }
- else
- {
- if (CONST_INT_P (XEXP (x, 1)))
- *total = cost->shift_const;
- else if (GET_CODE (XEXP (x, 1)) == SUBREG
- && GET_CODE (XEXP (XEXP (x, 1), 0)) == AND)
- {
- /* Return the cost after shift-and truncation. */
- *total = cost->shift_var;
- return true;
- }
- else
- *total = cost->shift_var;
- }
- return false;
-
- case FMA:
- {
- rtx sub;
-
- gcc_assert (FLOAT_MODE_P (mode));
- gcc_assert (TARGET_FMA || TARGET_FMA4);
-
- /* ??? SSE scalar/vector cost should be used here. */
- /* ??? Bald assumption that fma has the same cost as fmul. */
- *total = cost->fmul;
- *total += rtx_cost (XEXP (x, 1), FMA, 1, speed);
-
- /* Negate in op0 or op2 is free: FMS, FNMA, FNMS. */
- sub = XEXP (x, 0);
- if (GET_CODE (sub) == NEG)
- sub = XEXP (sub, 0);
- *total += rtx_cost (sub, FMA, 0, speed);
-
- sub = XEXP (x, 2);
- if (GET_CODE (sub) == NEG)
- sub = XEXP (sub, 0);
- *total += rtx_cost (sub, FMA, 2, speed);
- return true;
- }
-
- case MULT:
- if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
- {
- /* ??? SSE scalar cost should be used here. */
- *total = cost->fmul;
- return false;
- }
- else if (X87_FLOAT_MODE_P (mode))
- {
- *total = cost->fmul;
- return false;
- }
- else if (FLOAT_MODE_P (mode))
- {
- /* ??? SSE vector cost should be used here. */
- *total = cost->fmul;
- return false;
- }
- else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
- {
- /* V*QImode is emulated with 7-13 insns. */
- if (mode == V16QImode || mode == V32QImode)
- {
- int extra = 11;
- if (TARGET_XOP && mode == V16QImode)
- extra = 5;
- else if (TARGET_SSSE3)
- extra = 6;
- *total = cost->fmul * 2 + cost->fabs * extra;
- }
- /* V*DImode is emulated with 5-8 insns. */
- else if (mode == V2DImode || mode == V4DImode)
- {
- if (TARGET_XOP && mode == V2DImode)
- *total = cost->fmul * 2 + cost->fabs * 3;
- else
- *total = cost->fmul * 3 + cost->fabs * 5;
- }
- /* Without sse4.1, we don't have PMULLD; it's emulated with 7
- insns, including two PMULUDQ. */
- else if (mode == V4SImode && !(TARGET_SSE4_1 || TARGET_AVX))
- *total = cost->fmul * 2 + cost->fabs * 5;
- else
- *total = cost->fmul;
- return false;
- }
- else
- {
- rtx op0 = XEXP (x, 0);
- rtx op1 = XEXP (x, 1);
- int nbits;
- if (CONST_INT_P (XEXP (x, 1)))
- {
- unsigned HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
- for (nbits = 0; value != 0; value &= value - 1)
- nbits++;
- }
- else
- /* This is arbitrary. */
- nbits = 7;
-
- /* Compute costs correctly for widening multiplication. */
- if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
- && GET_MODE_SIZE (GET_MODE (XEXP (op0, 0))) * 2
- == GET_MODE_SIZE (mode))
- {
- int is_mulwiden = 0;
- enum machine_mode inner_mode = GET_MODE (op0);
-
- if (GET_CODE (op0) == GET_CODE (op1))
- is_mulwiden = 1, op1 = XEXP (op1, 0);
- else if (CONST_INT_P (op1))
- {
- if (GET_CODE (op0) == SIGN_EXTEND)
- is_mulwiden = trunc_int_for_mode (INTVAL (op1), inner_mode)
- == INTVAL (op1);
- else
- is_mulwiden = !(INTVAL (op1) & ~GET_MODE_MASK (inner_mode));
- }
-
- if (is_mulwiden)
- op0 = XEXP (op0, 0), mode = GET_MODE (op0);
- }
-
- *total = (cost->mult_init[MODE_INDEX (mode)]
- + nbits * cost->mult_bit
- + rtx_cost (op0, outer_code, opno, speed)
- + rtx_cost (op1, outer_code, opno, speed));
-
- return true;
- }
-
- case DIV:
- case UDIV:
- case MOD:
- case UMOD:
- if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
- /* ??? SSE cost should be used here. */
- *total = cost->fdiv;
- else if (X87_FLOAT_MODE_P (mode))
- *total = cost->fdiv;
- else if (FLOAT_MODE_P (mode))
- /* ??? SSE vector cost should be used here. */
- *total = cost->fdiv;
- else
- *total = cost->divide[MODE_INDEX (mode)];
- return false;
-
- case PLUS:
- if (GET_MODE_CLASS (mode) == MODE_INT
- && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
- {
- if (GET_CODE (XEXP (x, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
- && CONST_INT_P (XEXP (XEXP (XEXP (x, 0), 0), 1))
- && CONSTANT_P (XEXP (x, 1)))
- {
- HOST_WIDE_INT val = INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1));
- if (val == 2 || val == 4 || val == 8)
- {
- *total = cost->lea;
- *total += rtx_cost (XEXP (XEXP (x, 0), 1),
- outer_code, opno, speed);
- *total += rtx_cost (XEXP (XEXP (XEXP (x, 0), 0), 0),
- outer_code, opno, speed);
- *total += rtx_cost (XEXP (x, 1), outer_code, opno, speed);
- return true;
- }
- }
- else if (GET_CODE (XEXP (x, 0)) == MULT
- && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
- {
- HOST_WIDE_INT val = INTVAL (XEXP (XEXP (x, 0), 1));
- if (val == 2 || val == 4 || val == 8)
- {
- *total = cost->lea;
- *total += rtx_cost (XEXP (XEXP (x, 0), 0),
- outer_code, opno, speed);
- *total += rtx_cost (XEXP (x, 1), outer_code, opno, speed);
- return true;
- }
- }
- else if (GET_CODE (XEXP (x, 0)) == PLUS)
- {
- *total = cost->lea;
- *total += rtx_cost (XEXP (XEXP (x, 0), 0),
- outer_code, opno, speed);
- *total += rtx_cost (XEXP (XEXP (x, 0), 1),
- outer_code, opno, speed);
- *total += rtx_cost (XEXP (x, 1), outer_code, opno, speed);
- return true;
- }
- }
- /* FALLTHRU */
-
- case MINUS:
- if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
- {
- /* ??? SSE cost should be used here. */
- *total = cost->fadd;
- return false;
- }
- else if (X87_FLOAT_MODE_P (mode))
- {
- *total = cost->fadd;
- return false;
- }
- else if (FLOAT_MODE_P (mode))
- {
- /* ??? SSE vector cost should be used here. */
- *total = cost->fadd;
- return false;
- }
- /* FALLTHRU */
-
- case AND:
- case IOR:
- case XOR:
- if (GET_MODE_CLASS (mode) == MODE_INT
- && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
- {
- *total = (cost->add * 2
- + (rtx_cost (XEXP (x, 0), outer_code, opno, speed)
- << (GET_MODE (XEXP (x, 0)) != DImode))
- + (rtx_cost (XEXP (x, 1), outer_code, opno, speed)
- << (GET_MODE (XEXP (x, 1)) != DImode)));
- return true;
- }
- /* FALLTHRU */
-
- case NEG:
- if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
- {
- /* ??? SSE cost should be used here. */
- *total = cost->fchs;
- return false;
- }
- else if (X87_FLOAT_MODE_P (mode))
- {
- *total = cost->fchs;
- return false;
- }
- else if (FLOAT_MODE_P (mode))
- {
- /* ??? SSE vector cost should be used here. */
- *total = cost->fchs;
- return false;
- }
- /* FALLTHRU */
-
- case NOT:
- if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
- {
- /* ??? Should be SSE vector operation cost. */
- /* At least for published AMD latencies, this really is the same
- as the latency for a simple fpu operation like fabs. */
- *total = cost->fabs;
- }
- else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
- *total = cost->add * 2;
- else
- *total = cost->add;
- return false;
-
- case COMPARE:
- if (GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT
- && XEXP (XEXP (x, 0), 1) == const1_rtx
- && CONST_INT_P (XEXP (XEXP (x, 0), 2))
- && XEXP (x, 1) == const0_rtx)
- {
- /* This kind of construct is implemented using test[bwl].
- Treat it as if we had an AND. */
- *total = (cost->add
- + rtx_cost (XEXP (XEXP (x, 0), 0), outer_code, opno, speed)
- + rtx_cost (const1_rtx, outer_code, opno, speed));
- return true;
- }
- return false;
-
- case FLOAT_EXTEND:
- if (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH))
- *total = 0;
- return false;
-
- case ABS:
- if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
- /* ??? SSE cost should be used here. */
- *total = cost->fabs;
- else if (X87_FLOAT_MODE_P (mode))
- *total = cost->fabs;
- else if (FLOAT_MODE_P (mode))
- /* ??? SSE vector cost should be used here. */
- *total = cost->fabs;
- return false;
-
- case SQRT:
- if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
- /* ??? SSE cost should be used here. */
- *total = cost->fsqrt;
- else if (X87_FLOAT_MODE_P (mode))
- *total = cost->fsqrt;
- else if (FLOAT_MODE_P (mode))
- /* ??? SSE vector cost should be used here. */
- *total = cost->fsqrt;
- return false;
-
- case UNSPEC:
- if (XINT (x, 1) == UNSPEC_TP)
- *total = 0;
- return false;
-
- case VEC_SELECT:
- case VEC_CONCAT:
- case VEC_MERGE:
- case VEC_DUPLICATE:
- /* ??? Assume all of these vector manipulation patterns are
- recognizable. In which case they all pretty much have the
- same cost. */
- *total = cost->fabs;
- return true;
-
- default:
- return false;
- }
-}
-
-#if TARGET_MACHO
-
-static int current_machopic_label_num;
-
-/* Given a symbol name and its associated stub, write out the
- definition of the stub. */
-
-void
-machopic_output_stub (FILE *file, const char *symb, const char *stub)
-{
- unsigned int length;
- char *binder_name, *symbol_name, lazy_ptr_name[32];
- int label = ++current_machopic_label_num;
-
- /* For 64-bit we shouldn't get here. */
- gcc_assert (!TARGET_64BIT);
-
- /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
- symb = targetm.strip_name_encoding (symb);
-
- length = strlen (stub);
- binder_name = XALLOCAVEC (char, length + 32);
- GEN_BINDER_NAME_FOR_STUB (binder_name, stub, length);
-
- length = strlen (symb);
- symbol_name = XALLOCAVEC (char, length + 32);
- GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
-
- sprintf (lazy_ptr_name, "L%d$lz", label);
-
- if (MACHOPIC_ATT_STUB)
- switch_to_section (darwin_sections[machopic_picsymbol_stub3_section]);
- else if (MACHOPIC_PURE)
- switch_to_section (darwin_sections[machopic_picsymbol_stub2_section]);
- else
- switch_to_section (darwin_sections[machopic_symbol_stub_section]);
-
- fprintf (file, "%s:\n", stub);
- fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
-
- if (MACHOPIC_ATT_STUB)
- {
- fprintf (file, "\thlt ; hlt ; hlt ; hlt ; hlt\n");
- }
- else if (MACHOPIC_PURE)
- {
- /* PIC stub. */
- /* 25-byte PIC stub using "CALL get_pc_thunk". */
- rtx tmp = gen_rtx_REG (SImode, 2 /* ECX */);
- output_set_got (tmp, NULL_RTX); /* "CALL ___<cpu>.get_pc_thunk.cx". */
- fprintf (file, "LPC$%d:\tmovl\t%s-LPC$%d(%%ecx),%%ecx\n",
- label, lazy_ptr_name, label);
- fprintf (file, "\tjmp\t*%%ecx\n");
- }
- else
- fprintf (file, "\tjmp\t*%s\n", lazy_ptr_name);
-
- /* The AT&T-style ("self-modifying") stub is not lazily bound, thus
- it needs no stub-binding-helper. */
- if (MACHOPIC_ATT_STUB)
- return;
-
- fprintf (file, "%s:\n", binder_name);
-
- if (MACHOPIC_PURE)
- {
- fprintf (file, "\tlea\t%s-%s(%%ecx),%%ecx\n", lazy_ptr_name, binder_name);
- fprintf (file, "\tpushl\t%%ecx\n");
- }
- else
- fprintf (file, "\tpushl\t$%s\n", lazy_ptr_name);
-
- fputs ("\tjmp\tdyld_stub_binding_helper\n", file);
-
- /* N.B. Keep the correspondence of these
- 'symbol_ptr/symbol_ptr2/symbol_ptr3' sections consistent with the
- old-pic/new-pic/non-pic stubs; altering this will break
- compatibility with existing dylibs. */
- if (MACHOPIC_PURE)
- {
- /* 25-byte PIC stub using "CALL get_pc_thunk". */
- switch_to_section (darwin_sections[machopic_lazy_symbol_ptr2_section]);
- }
- else
- /* 16-byte -mdynamic-no-pic stub. */
- switch_to_section(darwin_sections[machopic_lazy_symbol_ptr3_section]);
-
- fprintf (file, "%s:\n", lazy_ptr_name);
- fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
- fprintf (file, ASM_LONG "%s\n", binder_name);
-}
-#endif /* TARGET_MACHO */
-
-/* Order the registers for register allocator. */
-
-void
-x86_order_regs_for_local_alloc (void)
-{
- int pos = 0;
- int i;
-
- /* First allocate the local general purpose registers. */
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (GENERAL_REGNO_P (i) && call_used_regs[i])
- reg_alloc_order [pos++] = i;
-
- /* Global general purpose registers. */
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (GENERAL_REGNO_P (i) && !call_used_regs[i])
- reg_alloc_order [pos++] = i;
-
- /* x87 registers come first in case we are doing FP math
- using them. */
- if (!TARGET_SSE_MATH)
- for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
- reg_alloc_order [pos++] = i;
-
- /* SSE registers. */
- for (i = FIRST_SSE_REG; i <= LAST_SSE_REG; i++)
- reg_alloc_order [pos++] = i;
- for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
- reg_alloc_order [pos++] = i;
-
- /* x87 registers. */
- if (TARGET_SSE_MATH)
- for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
- reg_alloc_order [pos++] = i;
-
- for (i = FIRST_MMX_REG; i <= LAST_MMX_REG; i++)
- reg_alloc_order [pos++] = i;
-
- /* Initialize the rest of array as we do not allocate some registers
- at all. */
- while (pos < FIRST_PSEUDO_REGISTER)
- reg_alloc_order [pos++] = 0;
-}
-
-/* Handle a "callee_pop_aggregate_return" attribute; arguments as
- in struct attribute_spec handler. */
-static tree
-ix86_handle_callee_pop_aggregate_return (tree *node, tree name,
- tree args,
- int flags ATTRIBUTE_UNUSED,
- bool *no_add_attrs)
-{
- if (TREE_CODE (*node) != FUNCTION_TYPE
- && TREE_CODE (*node) != METHOD_TYPE
- && TREE_CODE (*node) != FIELD_DECL
- && TREE_CODE (*node) != TYPE_DECL)
- {
- warning (OPT_Wattributes, "%qE attribute only applies to functions",
- name);
- *no_add_attrs = true;
- return NULL_TREE;
- }
- if (TARGET_64BIT)
- {
- warning (OPT_Wattributes, "%qE attribute only available for 32-bit",
- name);
- *no_add_attrs = true;
- return NULL_TREE;
- }
- if (is_attribute_p ("callee_pop_aggregate_return", name))
- {
- tree cst;
-
- cst = TREE_VALUE (args);
- if (TREE_CODE (cst) != INTEGER_CST)
- {
- warning (OPT_Wattributes,
- "%qE attribute requires an integer constant argument",
- name);
- *no_add_attrs = true;
- }
- else if (compare_tree_int (cst, 0) != 0
- && compare_tree_int (cst, 1) != 0)
- {
- warning (OPT_Wattributes,
- "argument to %qE attribute is neither zero, nor one",
- name);
- *no_add_attrs = true;
- }
-
- return NULL_TREE;
- }
-
- return NULL_TREE;
-}
-
-/* Handle a "ms_abi" or "sysv" attribute; arguments as in
- struct attribute_spec.handler. */
-static tree
-ix86_handle_abi_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
- && TREE_CODE (*node) != FIELD_DECL
- && TREE_CODE (*node) != TYPE_DECL)
- {
- warning (OPT_Wattributes, "%qE attribute only applies to functions",
- name);
- *no_add_attrs = true;
- return NULL_TREE;
- }
-
- /* Can combine regparm with all attributes but fastcall. */
- if (is_attribute_p ("ms_abi", name))
- {
- if (lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (*node)))
- {
- error ("ms_abi and sysv_abi attributes are not compatible");
- }
-
- return NULL_TREE;
- }
- else if (is_attribute_p ("sysv_abi", name))
- {
- if (lookup_attribute ("ms_abi", TYPE_ATTRIBUTES (*node)))
- {
- error ("ms_abi and sysv_abi attributes are not compatible");
- }
-
- return NULL_TREE;
- }
-
- return NULL_TREE;
-}
-
-/* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
- struct attribute_spec.handler. */
-static tree
-ix86_handle_struct_attribute (tree *node, tree name,
- tree args ATTRIBUTE_UNUSED,
- int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
-{
- tree *type = NULL;
- if (DECL_P (*node))
- {
- if (TREE_CODE (*node) == TYPE_DECL)
- type = &TREE_TYPE (*node);
- }
- else
- type = node;
-
- if (!(type && RECORD_OR_UNION_TYPE_P (*type)))
- {
- warning (OPT_Wattributes, "%qE attribute ignored",
- name);
- *no_add_attrs = true;
- }
-
- else if ((is_attribute_p ("ms_struct", name)
- && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
- || ((is_attribute_p ("gcc_struct", name)
- && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
- {
- warning (OPT_Wattributes, "%qE incompatible attribute ignored",
- name);
- *no_add_attrs = true;
- }
-
- return NULL_TREE;
-}
-
-static tree
-ix86_handle_fndecl_attribute (tree *node, tree name,
- tree args ATTRIBUTE_UNUSED,
- int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
-{
- if (TREE_CODE (*node) != FUNCTION_DECL)
- {
- warning (OPT_Wattributes, "%qE attribute only applies to functions",
- name);
- *no_add_attrs = true;
- }
- return NULL_TREE;
-}
-
-static bool
-ix86_ms_bitfield_layout_p (const_tree record_type)
-{
- return ((TARGET_MS_BITFIELD_LAYOUT
- && !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
- || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type)));
-}
-
-/* Returns an expression indicating where the this parameter is
- located on entry to the FUNCTION. */
-
-static rtx
-x86_this_parameter (tree function)
-{
- tree type = TREE_TYPE (function);
- bool aggr = aggregate_value_p (TREE_TYPE (type), type) != 0;
- int nregs;
-
- if (TARGET_64BIT)
- {
- const int *parm_regs;
-
- if (ix86_function_type_abi (type) == MS_ABI)
- parm_regs = x86_64_ms_abi_int_parameter_registers;
- else
- parm_regs = x86_64_int_parameter_registers;
- return gen_rtx_REG (Pmode, parm_regs[aggr]);
- }
-
- nregs = ix86_function_regparm (type, function);
-
- if (nregs > 0 && !stdarg_p (type))
- {
- int regno;
- unsigned int ccvt = ix86_get_callcvt (type);
-
- if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
- regno = aggr ? DX_REG : CX_REG;
- else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
- {
- regno = CX_REG;
- if (aggr)
- return gen_rtx_MEM (SImode,
- plus_constant (Pmode, stack_pointer_rtx, 4));
- }
- else
- {
- regno = AX_REG;
- if (aggr)
- {
- regno = DX_REG;
- if (nregs == 1)
- return gen_rtx_MEM (SImode,
- plus_constant (Pmode,
- stack_pointer_rtx, 4));
- }
- }
- return gen_rtx_REG (SImode, regno);
- }
-
- return gen_rtx_MEM (SImode, plus_constant (Pmode, stack_pointer_rtx,
- aggr ? 8 : 4));
-}
-
-/* Determine whether x86_output_mi_thunk can succeed. */
-
-static bool
-x86_can_output_mi_thunk (const_tree thunk ATTRIBUTE_UNUSED,
- HOST_WIDE_INT delta ATTRIBUTE_UNUSED,
- HOST_WIDE_INT vcall_offset, const_tree function)
-{
- /* 64-bit can handle anything. */
- if (TARGET_64BIT)
- return true;
-
- /* For 32-bit, everything's fine if we have one free register. */
- if (ix86_function_regparm (TREE_TYPE (function), function) < 3)
- return true;
-
- /* Need a free register for vcall_offset. */
- if (vcall_offset)
- return false;
-
- /* Need a free register for GOT references. */
- if (flag_pic && !targetm.binds_local_p (function))
- return false;
-
- /* Otherwise ok. */
- return true;
-}
-
-/* Output the assembler code for a thunk function. THUNK_DECL is the
- declaration for the thunk function itself, FUNCTION is the decl for
- the target function. DELTA is an immediate constant offset to be
- added to THIS. If VCALL_OFFSET is nonzero, the word at
- *(*this + vcall_offset) should be added to THIS. */
-
-static void
-x86_output_mi_thunk (FILE *file,
- tree thunk ATTRIBUTE_UNUSED, HOST_WIDE_INT delta,
- HOST_WIDE_INT vcall_offset, tree function)
-{
- rtx this_param = x86_this_parameter (function);
- rtx this_reg, tmp, fnaddr;
- unsigned int tmp_regno;
-
- if (TARGET_64BIT)
- tmp_regno = R10_REG;
- else
- {
- unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (function));
- if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
- tmp_regno = AX_REG;
- else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
- tmp_regno = DX_REG;
- else
- tmp_regno = CX_REG;
- }
-
- emit_note (NOTE_INSN_PROLOGUE_END);
-
- /* If VCALL_OFFSET, we'll need THIS in a register. Might as well
- pull it in now and let DELTA benefit. */
- if (REG_P (this_param))
- this_reg = this_param;
- else if (vcall_offset)
- {
- /* Put the this parameter into %eax. */
- this_reg = gen_rtx_REG (Pmode, AX_REG);
- emit_move_insn (this_reg, this_param);
- }
- else
- this_reg = NULL_RTX;
-
- /* Adjust the this parameter by a fixed constant. */
- if (delta)
- {
- rtx delta_rtx = GEN_INT (delta);
- rtx delta_dst = this_reg ? this_reg : this_param;
-
- if (TARGET_64BIT)
- {
- if (!x86_64_general_operand (delta_rtx, Pmode))
- {
- tmp = gen_rtx_REG (Pmode, tmp_regno);
- emit_move_insn (tmp, delta_rtx);
- delta_rtx = tmp;
- }
- }
-
- ix86_emit_binop (PLUS, Pmode, delta_dst, delta_rtx);
- }
-
- /* Adjust the this parameter by a value stored in the vtable. */
- if (vcall_offset)
- {
- rtx vcall_addr, vcall_mem, this_mem;
-
- tmp = gen_rtx_REG (Pmode, tmp_regno);
-
- this_mem = gen_rtx_MEM (ptr_mode, this_reg);
- if (Pmode != ptr_mode)
- this_mem = gen_rtx_ZERO_EXTEND (Pmode, this_mem);
- emit_move_insn (tmp, this_mem);
-
- /* Adjust the this parameter. */
- vcall_addr = plus_constant (Pmode, tmp, vcall_offset);
- if (TARGET_64BIT
- && !ix86_legitimate_address_p (ptr_mode, vcall_addr, true))
- {
- rtx tmp2 = gen_rtx_REG (Pmode, R11_REG);
- emit_move_insn (tmp2, GEN_INT (vcall_offset));
- vcall_addr = gen_rtx_PLUS (Pmode, tmp, tmp2);
- }
-
- vcall_mem = gen_rtx_MEM (ptr_mode, vcall_addr);
- if (Pmode != ptr_mode)
- emit_insn (gen_addsi_1_zext (this_reg,
- gen_rtx_REG (ptr_mode,
- REGNO (this_reg)),
- vcall_mem));
- else
- ix86_emit_binop (PLUS, Pmode, this_reg, vcall_mem);
- }
-
- /* If necessary, drop THIS back to its stack slot. */
- if (this_reg && this_reg != this_param)
- emit_move_insn (this_param, this_reg);
-
- fnaddr = XEXP (DECL_RTL (function), 0);
- if (TARGET_64BIT)
- {
- if (!flag_pic || targetm.binds_local_p (function)
- || cfun->machine->call_abi == MS_ABI)
- ;
- else
- {
- tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, fnaddr), UNSPEC_GOTPCREL);
- tmp = gen_rtx_CONST (Pmode, tmp);
- fnaddr = gen_rtx_MEM (Pmode, tmp);
- }
- }
- else
- {
- if (!flag_pic || targetm.binds_local_p (function))
- ;
-#if TARGET_MACHO
- else if (TARGET_MACHO)
- {
- fnaddr = machopic_indirect_call_target (DECL_RTL (function));
- fnaddr = XEXP (fnaddr, 0);
- }
-#endif /* TARGET_MACHO */
- else
- {
- tmp = gen_rtx_REG (Pmode, CX_REG);
- output_set_got (tmp, NULL_RTX);
-
- fnaddr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, fnaddr), UNSPEC_GOT);
- fnaddr = gen_rtx_PLUS (Pmode, fnaddr, tmp);
- fnaddr = gen_rtx_MEM (Pmode, fnaddr);
- }
- }
-
- /* Our sibling call patterns do not allow memories, because we have no
- predicate that can distinguish between frame and non-frame memory.
- For our purposes here, we can get away with (ab)using a jump pattern,
- because we're going to do no optimization. */
- if (MEM_P (fnaddr))
- emit_jump_insn (gen_indirect_jump (fnaddr));
- else
- {
- if (ix86_cmodel == CM_LARGE_PIC && SYMBOLIC_CONST (fnaddr))
- fnaddr = legitimize_pic_address (fnaddr,
- gen_rtx_REG (Pmode, tmp_regno));
-
- if (!sibcall_insn_operand (fnaddr, word_mode))
- {
- tmp = gen_rtx_REG (word_mode, tmp_regno);
- if (GET_MODE (fnaddr) != word_mode)
- fnaddr = gen_rtx_ZERO_EXTEND (word_mode, fnaddr);
- emit_move_insn (tmp, fnaddr);
- fnaddr = tmp;
- }
-
- tmp = gen_rtx_MEM (QImode, fnaddr);
- tmp = gen_rtx_CALL (VOIDmode, tmp, const0_rtx);
- tmp = emit_call_insn (tmp);
- SIBLING_CALL_P (tmp) = 1;
- }
- emit_barrier ();
-
- /* Emit just enough of rest_of_compilation to get the insns emitted.
- Note that use_thunk calls assemble_start_function et al. */
- tmp = get_insns ();
- shorten_branches (tmp);
- final_start_function (tmp, file, 1);
- final (tmp, file, 1);
- final_end_function ();
-}
-
-static void
-x86_file_start (void)
-{
- default_file_start ();
-#if TARGET_MACHO
- darwin_file_start ();
-#endif
- if (X86_FILE_START_VERSION_DIRECTIVE)
- fputs ("\t.version\t\"01.01\"\n", asm_out_file);
- if (X86_FILE_START_FLTUSED)
- fputs ("\t.global\t__fltused\n", asm_out_file);
- if (ix86_asm_dialect == ASM_INTEL)
- fputs ("\t.intel_syntax noprefix\n", asm_out_file);
-}
-
-int
-x86_field_alignment (tree field, int computed)
-{
- enum machine_mode mode;
- tree type = TREE_TYPE (field);
-
- if (TARGET_64BIT || TARGET_ALIGN_DOUBLE)
- return computed;
- mode = TYPE_MODE (strip_array_types (type));
- if (mode == DFmode || mode == DCmode
- || GET_MODE_CLASS (mode) == MODE_INT
- || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
- return MIN (32, computed);
- return computed;
-}
-
-/* Output assembler code to FILE to increment profiler label # LABELNO
- for profiling a function entry. */
-void
-x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
-{
- const char *mcount_name = (flag_fentry ? MCOUNT_NAME_BEFORE_PROLOGUE
- : MCOUNT_NAME);
-
- if (TARGET_64BIT)
- {
-#ifndef NO_PROFILE_COUNTERS
- fprintf (file, "\tleaq\t%sP%d(%%rip),%%r11\n", LPREFIX, labelno);
-#endif
-
- if (DEFAULT_ABI == SYSV_ABI && flag_pic)
- fprintf (file, "\tcall\t*%s@GOTPCREL(%%rip)\n", mcount_name);
- else
- fprintf (file, "\tcall\t%s\n", mcount_name);
- }
- else if (flag_pic)
- {
-#ifndef NO_PROFILE_COUNTERS
- fprintf (file, "\tleal\t%sP%d@GOTOFF(%%ebx),%%" PROFILE_COUNT_REGISTER "\n",
- LPREFIX, labelno);
-#endif
- fprintf (file, "\tcall\t*%s@GOT(%%ebx)\n", mcount_name);
- }
- else
- {
-#ifndef NO_PROFILE_COUNTERS
- fprintf (file, "\tmovl\t$%sP%d,%%" PROFILE_COUNT_REGISTER "\n",
- LPREFIX, labelno);
-#endif
- fprintf (file, "\tcall\t%s\n", mcount_name);
- }
-}
-
-/* We don't have exact information about the insn sizes, but we may assume
- quite safely that we are informed about all 1 byte insns and memory
- address sizes. This is enough to eliminate unnecessary padding in
- 99% of cases. */
-
-static int
-min_insn_size (rtx insn)
-{
- int l = 0, len;
-
- if (!INSN_P (insn) || !active_insn_p (insn))
- return 0;
-
- /* Discard alignments we've emit and jump instructions. */
- if (GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
- && XINT (PATTERN (insn), 1) == UNSPECV_ALIGN)
- return 0;
- if (JUMP_TABLE_DATA_P (insn))
- return 0;
-
- /* Important case - calls are always 5 bytes.
- It is common to have many calls in the row. */
- if (CALL_P (insn)
- && symbolic_reference_mentioned_p (PATTERN (insn))
- && !SIBLING_CALL_P (insn))
- return 5;
- len = get_attr_length (insn);
- if (len <= 1)
- return 1;
-
- /* For normal instructions we rely on get_attr_length being exact,
- with a few exceptions. */
- if (!JUMP_P (insn))
- {
- enum attr_type type = get_attr_type (insn);
-
- switch (type)
- {
- case TYPE_MULTI:
- if (GET_CODE (PATTERN (insn)) == ASM_INPUT
- || asm_noperands (PATTERN (insn)) >= 0)
- return 0;
- break;
- case TYPE_OTHER:
- case TYPE_FCMP:
- break;
- default:
- /* Otherwise trust get_attr_length. */
- return len;
- }
-
- l = get_attr_length_address (insn);
- if (l < 4 && symbolic_reference_mentioned_p (PATTERN (insn)))
- l = 4;
- }
- if (l)
- return 1+l;
- else
- return 2;
-}
-
-#ifdef ASM_OUTPUT_MAX_SKIP_PAD
-
-/* AMD K8 core mispredicts jumps when there are more than 3 jumps in 16 byte
- window. */
-
-static void
-ix86_avoid_jump_mispredicts (void)
-{
- rtx insn, start = get_insns ();
- int nbytes = 0, njumps = 0;
- int isjump = 0;
-
- /* Look for all minimal intervals of instructions containing 4 jumps.
- The intervals are bounded by START and INSN. NBYTES is the total
- size of instructions in the interval including INSN and not including
- START. When the NBYTES is smaller than 16 bytes, it is possible
- that the end of START and INSN ends up in the same 16byte page.
-
- The smallest offset in the page INSN can start is the case where START
- ends on the offset 0. Offset of INSN is then NBYTES - sizeof (INSN).
- We add p2align to 16byte window with maxskip 15 - NBYTES + sizeof (INSN).
- */
- for (insn = start; insn; insn = NEXT_INSN (insn))
- {
- int min_size;
-
- if (LABEL_P (insn))
- {
- int align = label_to_alignment (insn);
- int max_skip = label_to_max_skip (insn);
-
- if (max_skip > 15)
- max_skip = 15;
- /* If align > 3, only up to 16 - max_skip - 1 bytes can be
- already in the current 16 byte page, because otherwise
- ASM_OUTPUT_MAX_SKIP_ALIGN could skip max_skip or fewer
- bytes to reach 16 byte boundary. */
- if (align <= 0
- || (align <= 3 && max_skip != (1 << align) - 1))
- max_skip = 0;
- if (dump_file)
- fprintf (dump_file, "Label %i with max_skip %i\n",
- INSN_UID (insn), max_skip);
- if (max_skip)
- {
- while (nbytes + max_skip >= 16)
- {
- start = NEXT_INSN (start);
- if ((JUMP_P (start)
- && GET_CODE (PATTERN (start)) != ADDR_VEC
- && GET_CODE (PATTERN (start)) != ADDR_DIFF_VEC)
- || CALL_P (start))
- njumps--, isjump = 1;
- else
- isjump = 0;
- nbytes -= min_insn_size (start);
- }
- }
- continue;
- }
-
- min_size = min_insn_size (insn);
- nbytes += min_size;
- if (dump_file)
- fprintf (dump_file, "Insn %i estimated to %i bytes\n",
- INSN_UID (insn), min_size);
- if ((JUMP_P (insn)
- && GET_CODE (PATTERN (insn)) != ADDR_VEC
- && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC)
- || CALL_P (insn))
- njumps++;
- else
- continue;
-
- while (njumps > 3)
- {
- start = NEXT_INSN (start);
- if ((JUMP_P (start)
- && GET_CODE (PATTERN (start)) != ADDR_VEC
- && GET_CODE (PATTERN (start)) != ADDR_DIFF_VEC)
- || CALL_P (start))
- njumps--, isjump = 1;
- else
- isjump = 0;
- nbytes -= min_insn_size (start);
- }
- gcc_assert (njumps >= 0);
- if (dump_file)
- fprintf (dump_file, "Interval %i to %i has %i bytes\n",
- INSN_UID (start), INSN_UID (insn), nbytes);
-
- if (njumps == 3 && isjump && nbytes < 16)
- {
- int padsize = 15 - nbytes + min_insn_size (insn);
-
- if (dump_file)
- fprintf (dump_file, "Padding insn %i by %i bytes!\n",
- INSN_UID (insn), padsize);
- emit_insn_before (gen_pad (GEN_INT (padsize)), insn);
- }
- }
-}
-#endif
-
-/* AMD Athlon works faster
- when RET is not destination of conditional jump or directly preceded
- by other jump instruction. We avoid the penalty by inserting NOP just
- before the RET instructions in such cases. */
-static void
-ix86_pad_returns (void)
-{
- edge e;
- edge_iterator ei;
-
- FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
- {
- basic_block bb = e->src;
- rtx ret = BB_END (bb);
- rtx prev;
- bool replace = false;
-
- if (!JUMP_P (ret) || !ANY_RETURN_P (PATTERN (ret))
- || optimize_bb_for_size_p (bb))
- continue;
- for (prev = PREV_INSN (ret); prev; prev = PREV_INSN (prev))
- if (active_insn_p (prev) || LABEL_P (prev))
- break;
- if (prev && LABEL_P (prev))
- {
- edge e;
- edge_iterator ei;
-
- FOR_EACH_EDGE (e, ei, bb->preds)
- if (EDGE_FREQUENCY (e) && e->src->index >= 0
- && !(e->flags & EDGE_FALLTHRU))
- replace = true;
- }
- if (!replace)
- {
- prev = prev_active_insn (ret);
- if (prev
- && ((JUMP_P (prev) && any_condjump_p (prev))
- || CALL_P (prev)))
- replace = true;
- /* Empty functions get branch mispredict even when
- the jump destination is not visible to us. */
- if (!prev && !optimize_function_for_size_p (cfun))
- replace = true;
- }
- if (replace)
- {
- emit_jump_insn_before (gen_simple_return_internal_long (), ret);
- delete_insn (ret);
- }
- }
-}
-
-/* Count the minimum number of instructions in BB. Return 4 if the
- number of instructions >= 4. */
-
-static int
-ix86_count_insn_bb (basic_block bb)
-{
- rtx insn;
- int insn_count = 0;
-
- /* Count number of instructions in this block. Return 4 if the number
- of instructions >= 4. */
- FOR_BB_INSNS (bb, insn)
- {
- /* Only happen in exit blocks. */
- if (JUMP_P (insn)
- && ANY_RETURN_P (PATTERN (insn)))
- break;
-
- if (NONDEBUG_INSN_P (insn)
- && GET_CODE (PATTERN (insn)) != USE
- && GET_CODE (PATTERN (insn)) != CLOBBER)
- {
- insn_count++;
- if (insn_count >= 4)
- return insn_count;
- }
- }
-
- return insn_count;
-}
-
-
-/* Count the minimum number of instructions in code path in BB.
- Return 4 if the number of instructions >= 4. */
-
-static int
-ix86_count_insn (basic_block bb)
-{
- edge e;
- edge_iterator ei;
- int min_prev_count;
-
- /* Only bother counting instructions along paths with no
- more than 2 basic blocks between entry and exit. Given
- that BB has an edge to exit, determine if a predecessor
- of BB has an edge from entry. If so, compute the number
- of instructions in the predecessor block. If there
- happen to be multiple such blocks, compute the minimum. */
- min_prev_count = 4;
- FOR_EACH_EDGE (e, ei, bb->preds)
- {
- edge prev_e;
- edge_iterator prev_ei;
-
- if (e->src == ENTRY_BLOCK_PTR)
- {
- min_prev_count = 0;
- break;
- }
- FOR_EACH_EDGE (prev_e, prev_ei, e->src->preds)
- {
- if (prev_e->src == ENTRY_BLOCK_PTR)
- {
- int count = ix86_count_insn_bb (e->src);
- if (count < min_prev_count)
- min_prev_count = count;
- break;
- }
- }
- }
-
- if (min_prev_count < 4)
- min_prev_count += ix86_count_insn_bb (bb);
-
- return min_prev_count;
-}
-
-/* Pad short function to 4 instructions. */
-
-static void
-ix86_pad_short_function (void)
-{
- edge e;
- edge_iterator ei;
-
- FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
- {
- rtx ret = BB_END (e->src);
- if (JUMP_P (ret) && ANY_RETURN_P (PATTERN (ret)))
- {
- int insn_count = ix86_count_insn (e->src);
-
- /* Pad short function. */
- if (insn_count < 4)
- {
- rtx insn = ret;
-
- /* Find epilogue. */
- while (insn
- && (!NOTE_P (insn)
- || NOTE_KIND (insn) != NOTE_INSN_EPILOGUE_BEG))
- insn = PREV_INSN (insn);
-
- if (!insn)
- insn = ret;
-
- /* Two NOPs count as one instruction. */
- insn_count = 2 * (4 - insn_count);
- emit_insn_before (gen_nops (GEN_INT (insn_count)), insn);
- }
- }
- }
-}
-
-/* Implement machine specific optimizations. We implement padding of returns
- for K8 CPUs and pass to avoid 4 jumps in the single 16 byte window. */
-static void
-ix86_reorg (void)
-{
- /* We are freeing block_for_insn in the toplev to keep compatibility
- with old MDEP_REORGS that are not CFG based. Recompute it now. */
- compute_bb_for_insn ();
-
- if (optimize && optimize_function_for_speed_p (cfun))
- {
- if (TARGET_PAD_SHORT_FUNCTION)
- ix86_pad_short_function ();
- else if (TARGET_PAD_RETURNS)
- ix86_pad_returns ();
-#ifdef ASM_OUTPUT_MAX_SKIP_PAD
- if (TARGET_FOUR_JUMP_LIMIT)
- ix86_avoid_jump_mispredicts ();
-#endif
- }
-}
-
-/* Return nonzero when QImode register that must be represented via REX prefix
- is used. */
-bool
-x86_extended_QIreg_mentioned_p (rtx insn)
-{
- int i;
- extract_insn_cached (insn);
- for (i = 0; i < recog_data.n_operands; i++)
- if (GENERAL_REG_P (recog_data.operand[i])
- && !QI_REGNO_P (REGNO (recog_data.operand[i])))
- return true;
- return false;
-}
-
-/* Return nonzero when P points to register encoded via REX prefix.
- Called via for_each_rtx. */
-static int
-extended_reg_mentioned_1 (rtx *p, void *data ATTRIBUTE_UNUSED)
-{
- unsigned int regno;
- if (!REG_P (*p))
- return 0;
- regno = REGNO (*p);
- return REX_INT_REGNO_P (regno) || REX_SSE_REGNO_P (regno);
-}
-
-/* Return true when INSN mentions register that must be encoded using REX
- prefix. */
-bool
-x86_extended_reg_mentioned_p (rtx insn)
-{
- return for_each_rtx (INSN_P (insn) ? &PATTERN (insn) : &insn,
- extended_reg_mentioned_1, NULL);
-}
-
-/* If profitable, negate (without causing overflow) integer constant
- of mode MODE at location LOC. Return true in this case. */
-bool
-x86_maybe_negate_const_int (rtx *loc, enum machine_mode mode)
-{
- HOST_WIDE_INT val;
-
- if (!CONST_INT_P (*loc))
- return false;
-
- switch (mode)
- {
- case DImode:
- /* DImode x86_64 constants must fit in 32 bits. */
- gcc_assert (x86_64_immediate_operand (*loc, mode));
-
- mode = SImode;
- break;
-
- case SImode:
- case HImode:
- case QImode:
- break;
-
- default:
- gcc_unreachable ();
- }
-
- /* Avoid overflows. */
- if (mode_signbit_p (mode, *loc))
- return false;
-
- val = INTVAL (*loc);
-
- /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
- Exceptions: -128 encodes smaller than 128, so swap sign and op. */
- if ((val < 0 && val != -128)
- || val == 128)
- {
- *loc = GEN_INT (-val);
- return true;
- }
-
- return false;
-}
-
-/* Generate an unsigned DImode/SImode to FP conversion. This is the same code
- optabs would emit if we didn't have TFmode patterns. */
-
-void
-x86_emit_floatuns (rtx operands[2])
-{
- rtx neglab, donelab, i0, i1, f0, in, out;
- enum machine_mode mode, inmode;
-
- inmode = GET_MODE (operands[1]);
- gcc_assert (inmode == SImode || inmode == DImode);
-
- out = operands[0];
- in = force_reg (inmode, operands[1]);
- mode = GET_MODE (out);
- neglab = gen_label_rtx ();
- donelab = gen_label_rtx ();
- f0 = gen_reg_rtx (mode);
-
- emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, inmode, 0, neglab);
-
- expand_float (out, in, 0);
-
- emit_jump_insn (gen_jump (donelab));
- emit_barrier ();
-
- emit_label (neglab);
-
- i0 = expand_simple_binop (inmode, LSHIFTRT, in, const1_rtx, NULL,
- 1, OPTAB_DIRECT);
- i1 = expand_simple_binop (inmode, AND, in, const1_rtx, NULL,
- 1, OPTAB_DIRECT);
- i0 = expand_simple_binop (inmode, IOR, i0, i1, i0, 1, OPTAB_DIRECT);
-
- expand_float (f0, i0, 0);
-
- emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_PLUS (mode, f0, f0)));
-
- emit_label (donelab);
-}
-
-/* AVX2 does support 32-byte integer vector operations,
- thus the longest vector we are faced with is V32QImode. */
-#define MAX_VECT_LEN 32
-
-struct expand_vec_perm_d
-{
- rtx target, op0, op1;
- unsigned char perm[MAX_VECT_LEN];
- enum machine_mode vmode;
- unsigned char nelt;
- bool one_operand_p;
- bool testing_p;
-};
-
-static bool canonicalize_perm (struct expand_vec_perm_d *d);
-static bool expand_vec_perm_1 (struct expand_vec_perm_d *d);
-static bool expand_vec_perm_broadcast_1 (struct expand_vec_perm_d *d);
-
-/* Get a vector mode of the same size as the original but with elements
- twice as wide. This is only guaranteed to apply to integral vectors. */
-
-static inline enum machine_mode
-get_mode_wider_vector (enum machine_mode o)
-{
- /* ??? Rely on the ordering that genmodes.c gives to vectors. */
- enum machine_mode n = GET_MODE_WIDER_MODE (o);
- gcc_assert (GET_MODE_NUNITS (o) == GET_MODE_NUNITS (n) * 2);
- gcc_assert (GET_MODE_SIZE (o) == GET_MODE_SIZE (n));
- return n;
-}
-
-/* A subroutine of ix86_expand_vector_init. Store into TARGET a vector
- with all elements equal to VAR. Return true if successful. */
-
-static bool
-ix86_expand_vector_init_duplicate (bool mmx_ok, enum machine_mode mode,
- rtx target, rtx val)
-{
- bool ok;
-
- switch (mode)
- {
- case V2SImode:
- case V2SFmode:
- if (!mmx_ok)
- return false;
- /* FALLTHRU */
-
- case V4DFmode:
- case V4DImode:
- case V8SFmode:
- case V8SImode:
- case V2DFmode:
- case V2DImode:
- case V4SFmode:
- case V4SImode:
- {
- rtx insn, dup;
-
- /* First attempt to recognize VAL as-is. */
- dup = gen_rtx_VEC_DUPLICATE (mode, val);
- insn = emit_insn (gen_rtx_SET (VOIDmode, target, dup));
- if (recog_memoized (insn) < 0)
- {
- rtx seq;
- /* If that fails, force VAL into a register. */
-
- start_sequence ();
- XEXP (dup, 0) = force_reg (GET_MODE_INNER (mode), val);
- seq = get_insns ();
- end_sequence ();
- if (seq)
- emit_insn_before (seq, insn);
-
- ok = recog_memoized (insn) >= 0;
- gcc_assert (ok);
- }
- }
- return true;
-
- case V4HImode:
- if (!mmx_ok)
- return false;
- if (TARGET_SSE || TARGET_3DNOW_A)
- {
- rtx x;
-
- val = gen_lowpart (SImode, val);
- x = gen_rtx_TRUNCATE (HImode, val);
- x = gen_rtx_VEC_DUPLICATE (mode, x);
- emit_insn (gen_rtx_SET (VOIDmode, target, x));
- return true;
- }
- goto widen;
-
- case V8QImode:
- if (!mmx_ok)
- return false;
- goto widen;
-
- case V8HImode:
- if (TARGET_SSE2)
- {
- struct expand_vec_perm_d dperm;
- rtx tmp1, tmp2;
-
- permute:
- memset (&dperm, 0, sizeof (dperm));
- dperm.target = target;
- dperm.vmode = mode;
- dperm.nelt = GET_MODE_NUNITS (mode);
- dperm.op0 = dperm.op1 = gen_reg_rtx (mode);
- dperm.one_operand_p = true;
-
- /* Extend to SImode using a paradoxical SUBREG. */
- tmp1 = gen_reg_rtx (SImode);
- emit_move_insn (tmp1, gen_lowpart (SImode, val));
-
- /* Insert the SImode value as low element of a V4SImode vector. */
- tmp2 = gen_lowpart (V4SImode, dperm.op0);
- emit_insn (gen_vec_setv4si_0 (tmp2, CONST0_RTX (V4SImode), tmp1));
-
- ok = (expand_vec_perm_1 (&dperm)
- || expand_vec_perm_broadcast_1 (&dperm));
- gcc_assert (ok);
- return ok;
- }
- goto widen;
-
- case V16QImode:
- if (TARGET_SSE2)
- goto permute;
- goto widen;
-
- widen:
- /* Replicate the value once into the next wider mode and recurse. */
- {
- enum machine_mode smode, wsmode, wvmode;
- rtx x;
-
- smode = GET_MODE_INNER (mode);
- wvmode = get_mode_wider_vector (mode);
- wsmode = GET_MODE_INNER (wvmode);
-
- val = convert_modes (wsmode, smode, val, true);
- x = expand_simple_binop (wsmode, ASHIFT, val,
- GEN_INT (GET_MODE_BITSIZE (smode)),
- NULL_RTX, 1, OPTAB_LIB_WIDEN);
- val = expand_simple_binop (wsmode, IOR, val, x, x, 1, OPTAB_LIB_WIDEN);
-
- x = gen_lowpart (wvmode, target);
- ok = ix86_expand_vector_init_duplicate (mmx_ok, wvmode, x, val);
- gcc_assert (ok);
- return ok;
- }
-
- case V16HImode:
- case V32QImode:
- {
- enum machine_mode hvmode = (mode == V16HImode ? V8HImode : V16QImode);
- rtx x = gen_reg_rtx (hvmode);
-
- ok = ix86_expand_vector_init_duplicate (false, hvmode, x, val);
- gcc_assert (ok);
-
- x = gen_rtx_VEC_CONCAT (mode, x, x);
- emit_insn (gen_rtx_SET (VOIDmode, target, x));
- }
- return true;
-
- default:
- return false;
- }
-}
-
-/* A subroutine of ix86_expand_vector_init. Store into TARGET a vector
- whose ONE_VAR element is VAR, and other elements are zero. Return true
- if successful. */
-
-static bool
-ix86_expand_vector_init_one_nonzero (bool mmx_ok, enum machine_mode mode,
- rtx target, rtx var, int one_var)
-{
- enum machine_mode vsimode;
- rtx new_target;
- rtx x, tmp;
- bool use_vector_set = false;
-
- switch (mode)
- {
- case V2DImode:
- /* For SSE4.1, we normally use vector set. But if the second
- element is zero and inter-unit moves are OK, we use movq
- instead. */
- use_vector_set = (TARGET_64BIT
- && TARGET_SSE4_1
- && !(TARGET_INTER_UNIT_MOVES
- && one_var == 0));
- break;
- case V16QImode:
- case V4SImode:
- case V4SFmode:
- use_vector_set = TARGET_SSE4_1;
- break;
- case V8HImode:
- use_vector_set = TARGET_SSE2;
- break;
- case V4HImode:
- use_vector_set = TARGET_SSE || TARGET_3DNOW_A;
- break;
- case V32QImode:
- case V16HImode:
- case V8SImode:
- case V8SFmode:
- case V4DFmode:
- use_vector_set = TARGET_AVX;
- break;
- case V4DImode:
- /* Use ix86_expand_vector_set in 64bit mode only. */
- use_vector_set = TARGET_AVX && TARGET_64BIT;
- break;
- default:
- break;
- }
-
- if (use_vector_set)
- {
- emit_insn (gen_rtx_SET (VOIDmode, target, CONST0_RTX (mode)));
- var = force_reg (GET_MODE_INNER (mode), var);
- ix86_expand_vector_set (mmx_ok, target, var, one_var);
- return true;
- }
-
- switch (mode)
- {
- case V2SFmode:
- case V2SImode:
- if (!mmx_ok)
- return false;
- /* FALLTHRU */
-
- case V2DFmode:
- case V2DImode:
- if (one_var != 0)
- return false;
- var = force_reg (GET_MODE_INNER (mode), var);
- x = gen_rtx_VEC_CONCAT (mode, var, CONST0_RTX (GET_MODE_INNER (mode)));
- emit_insn (gen_rtx_SET (VOIDmode, target, x));
- return true;
-
- case V4SFmode:
- case V4SImode:
- if (!REG_P (target) || REGNO (target) < FIRST_PSEUDO_REGISTER)
- new_target = gen_reg_rtx (mode);
- else
- new_target = target;
- var = force_reg (GET_MODE_INNER (mode), var);
- x = gen_rtx_VEC_DUPLICATE (mode, var);
- x = gen_rtx_VEC_MERGE (mode, x, CONST0_RTX (mode), const1_rtx);
- emit_insn (gen_rtx_SET (VOIDmode, new_target, x));
- if (one_var != 0)
- {
- /* We need to shuffle the value to the correct position, so
- create a new pseudo to store the intermediate result. */
-
- /* With SSE2, we can use the integer shuffle insns. */
- if (mode != V4SFmode && TARGET_SSE2)
- {
- emit_insn (gen_sse2_pshufd_1 (new_target, new_target,
- const1_rtx,
- GEN_INT (one_var == 1 ? 0 : 1),
- GEN_INT (one_var == 2 ? 0 : 1),
- GEN_INT (one_var == 3 ? 0 : 1)));
- if (target != new_target)
- emit_move_insn (target, new_target);
- return true;
- }
-
- /* Otherwise convert the intermediate result to V4SFmode and
- use the SSE1 shuffle instructions. */
- if (mode != V4SFmode)
- {
- tmp = gen_reg_rtx (V4SFmode);
- emit_move_insn (tmp, gen_lowpart (V4SFmode, new_target));
- }
- else
- tmp = new_target;
-
- emit_insn (gen_sse_shufps_v4sf (tmp, tmp, tmp,
- const1_rtx,
- GEN_INT (one_var == 1 ? 0 : 1),
- GEN_INT (one_var == 2 ? 0+4 : 1+4),
- GEN_INT (one_var == 3 ? 0+4 : 1+4)));
-
- if (mode != V4SFmode)
- emit_move_insn (target, gen_lowpart (V4SImode, tmp));
- else if (tmp != target)
- emit_move_insn (target, tmp);
- }
- else if (target != new_target)
- emit_move_insn (target, new_target);
- return true;
-
- case V8HImode:
- case V16QImode:
- vsimode = V4SImode;
- goto widen;
- case V4HImode:
- case V8QImode:
- if (!mmx_ok)
- return false;
- vsimode = V2SImode;
- goto widen;
- widen:
- if (one_var != 0)
- return false;
-
- /* Zero extend the variable element to SImode and recurse. */
- var = convert_modes (SImode, GET_MODE_INNER (mode), var, true);
-
- x = gen_reg_rtx (vsimode);
- if (!ix86_expand_vector_init_one_nonzero (mmx_ok, vsimode, x,
- var, one_var))
- gcc_unreachable ();
-
- emit_move_insn (target, gen_lowpart (mode, x));
- return true;
-
- default:
- return false;
- }
-}
-
-/* A subroutine of ix86_expand_vector_init. Store into TARGET a vector
- consisting of the values in VALS. It is known that all elements
- except ONE_VAR are constants. Return true if successful. */
-
-static bool
-ix86_expand_vector_init_one_var (bool mmx_ok, enum machine_mode mode,
- rtx target, rtx vals, int one_var)
-{
- rtx var = XVECEXP (vals, 0, one_var);
- enum machine_mode wmode;
- rtx const_vec, x;
-
- const_vec = copy_rtx (vals);
- XVECEXP (const_vec, 0, one_var) = CONST0_RTX (GET_MODE_INNER (mode));
- const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (const_vec, 0));
-
- switch (mode)
- {
- case V2DFmode:
- case V2DImode:
- case V2SFmode:
- case V2SImode:
- /* For the two element vectors, it's just as easy to use
- the general case. */
- return false;
-
- case V4DImode:
- /* Use ix86_expand_vector_set in 64bit mode only. */
- if (!TARGET_64BIT)
- return false;
- case V4DFmode:
- case V8SFmode:
- case V8SImode:
- case V16HImode:
- case V32QImode:
- case V4SFmode:
- case V4SImode:
- case V8HImode:
- case V4HImode:
- break;
-
- case V16QImode:
- if (TARGET_SSE4_1)
- break;
- wmode = V8HImode;
- goto widen;
- case V8QImode:
- wmode = V4HImode;
- goto widen;
- widen:
- /* There's no way to set one QImode entry easily. Combine
- the variable value with its adjacent constant value, and
- promote to an HImode set. */
- x = XVECEXP (vals, 0, one_var ^ 1);
- if (one_var & 1)
- {
- var = convert_modes (HImode, QImode, var, true);
- var = expand_simple_binop (HImode, ASHIFT, var, GEN_INT (8),
- NULL_RTX, 1, OPTAB_LIB_WIDEN);
- x = GEN_INT (INTVAL (x) & 0xff);
- }
- else
- {
- var = convert_modes (HImode, QImode, var, true);
- x = gen_int_mode (INTVAL (x) << 8, HImode);
- }
- if (x != const0_rtx)
- var = expand_simple_binop (HImode, IOR, var, x, var,
- 1, OPTAB_LIB_WIDEN);
-
- x = gen_reg_rtx (wmode);
- emit_move_insn (x, gen_lowpart (wmode, const_vec));
- ix86_expand_vector_set (mmx_ok, x, var, one_var >> 1);
-
- emit_move_insn (target, gen_lowpart (mode, x));
- return true;
-
- default:
- return false;
- }
-
- emit_move_insn (target, const_vec);
- ix86_expand_vector_set (mmx_ok, target, var, one_var);
- return true;
-}
-
-/* A subroutine of ix86_expand_vector_init_general. Use vector
- concatenate to handle the most general case: all values variable,
- and none identical. */
-
-static void
-ix86_expand_vector_init_concat (enum machine_mode mode,
- rtx target, rtx *ops, int n)
-{
- enum machine_mode cmode, hmode = VOIDmode;
- rtx first[8], second[4];
- rtvec v;
- int i, j;
-
- switch (n)
- {
- case 2:
- switch (mode)
- {
- case V8SImode:
- cmode = V4SImode;
- break;
- case V8SFmode:
- cmode = V4SFmode;
- break;
- case V4DImode:
- cmode = V2DImode;
- break;
- case V4DFmode:
- cmode = V2DFmode;
- break;
- case V4SImode:
- cmode = V2SImode;
- break;
- case V4SFmode:
- cmode = V2SFmode;
- break;
- case V2DImode:
- cmode = DImode;
- break;
- case V2SImode:
- cmode = SImode;
- break;
- case V2DFmode:
- cmode = DFmode;
- break;
- case V2SFmode:
- cmode = SFmode;
- break;
- default:
- gcc_unreachable ();
- }
-
- if (!register_operand (ops[1], cmode))
- ops[1] = force_reg (cmode, ops[1]);
- if (!register_operand (ops[0], cmode))
- ops[0] = force_reg (cmode, ops[0]);
- emit_insn (gen_rtx_SET (VOIDmode, target,
- gen_rtx_VEC_CONCAT (mode, ops[0],
- ops[1])));
- break;
-
- case 4:
- switch (mode)
- {
- case V4DImode:
- cmode = V2DImode;
- break;
- case V4DFmode:
- cmode = V2DFmode;
- break;
- case V4SImode:
- cmode = V2SImode;
- break;
- case V4SFmode:
- cmode = V2SFmode;
- break;
- default:
- gcc_unreachable ();
- }
- goto half;
-
- case 8:
- switch (mode)
- {
- case V8SImode:
- cmode = V2SImode;
- hmode = V4SImode;
- break;
- case V8SFmode:
- cmode = V2SFmode;
- hmode = V4SFmode;
- break;
- default:
- gcc_unreachable ();
- }
- goto half;
-
-half:
- /* FIXME: We process inputs backward to help RA. PR 36222. */
- i = n - 1;
- j = (n >> 1) - 1;
- for (; i > 0; i -= 2, j--)
- {
- first[j] = gen_reg_rtx (cmode);
- v = gen_rtvec (2, ops[i - 1], ops[i]);
- ix86_expand_vector_init (false, first[j],
- gen_rtx_PARALLEL (cmode, v));
- }
-
- n >>= 1;
- if (n > 2)
- {
- gcc_assert (hmode != VOIDmode);
- for (i = j = 0; i < n; i += 2, j++)
- {
- second[j] = gen_reg_rtx (hmode);
- ix86_expand_vector_init_concat (hmode, second [j],
- &first [i], 2);
- }
- n >>= 1;
- ix86_expand_vector_init_concat (mode, target, second, n);
- }
- else
- ix86_expand_vector_init_concat (mode, target, first, n);
- break;
-
- default:
- gcc_unreachable ();
- }
-}
-
-/* A subroutine of ix86_expand_vector_init_general. Use vector
- interleave to handle the most general case: all values variable,
- and none identical. */
-
-static void
-ix86_expand_vector_init_interleave (enum machine_mode mode,
- rtx target, rtx *ops, int n)
-{
- enum machine_mode first_imode, second_imode, third_imode, inner_mode;
- int i, j;
- rtx op0, op1;
- rtx (*gen_load_even) (rtx, rtx, rtx);
- rtx (*gen_interleave_first_low) (rtx, rtx, rtx);
- rtx (*gen_interleave_second_low) (rtx, rtx, rtx);
-
- switch (mode)
- {
- case V8HImode:
- gen_load_even = gen_vec_setv8hi;
- gen_interleave_first_low = gen_vec_interleave_lowv4si;
- gen_interleave_second_low = gen_vec_interleave_lowv2di;
- inner_mode = HImode;
- first_imode = V4SImode;
- second_imode = V2DImode;
- third_imode = VOIDmode;
- break;
- case V16QImode:
- gen_load_even = gen_vec_setv16qi;
- gen_interleave_first_low = gen_vec_interleave_lowv8hi;
- gen_interleave_second_low = gen_vec_interleave_lowv4si;
- inner_mode = QImode;
- first_imode = V8HImode;
- second_imode = V4SImode;
- third_imode = V2DImode;
- break;
- default:
- gcc_unreachable ();
- }
-
- for (i = 0; i < n; i++)
- {
- /* Extend the odd elment to SImode using a paradoxical SUBREG. */
- op0 = gen_reg_rtx (SImode);
- emit_move_insn (op0, gen_lowpart (SImode, ops [i + i]));
-
- /* Insert the SImode value as low element of V4SImode vector. */
- op1 = gen_reg_rtx (V4SImode);
- op0 = gen_rtx_VEC_MERGE (V4SImode,
- gen_rtx_VEC_DUPLICATE (V4SImode,
- op0),
- CONST0_RTX (V4SImode),
- const1_rtx);
- emit_insn (gen_rtx_SET (VOIDmode, op1, op0));
-
- /* Cast the V4SImode vector back to a vector in orignal mode. */
- op0 = gen_reg_rtx (mode);
- emit_move_insn (op0, gen_lowpart (mode, op1));
-
- /* Load even elements into the second positon. */
- emit_insn (gen_load_even (op0,
- force_reg (inner_mode,
- ops [i + i + 1]),
- const1_rtx));
-
- /* Cast vector to FIRST_IMODE vector. */
- ops[i] = gen_reg_rtx (first_imode);
- emit_move_insn (ops[i], gen_lowpart (first_imode, op0));
- }
-
- /* Interleave low FIRST_IMODE vectors. */
- for (i = j = 0; i < n; i += 2, j++)
- {
- op0 = gen_reg_rtx (first_imode);
- emit_insn (gen_interleave_first_low (op0, ops[i], ops[i + 1]));
-
- /* Cast FIRST_IMODE vector to SECOND_IMODE vector. */
- ops[j] = gen_reg_rtx (second_imode);
- emit_move_insn (ops[j], gen_lowpart (second_imode, op0));
- }
-
- /* Interleave low SECOND_IMODE vectors. */
- switch (second_imode)
- {
- case V4SImode:
- for (i = j = 0; i < n / 2; i += 2, j++)
- {
- op0 = gen_reg_rtx (second_imode);
- emit_insn (gen_interleave_second_low (op0, ops[i],
- ops[i + 1]));
-
- /* Cast the SECOND_IMODE vector to the THIRD_IMODE
- vector. */
- ops[j] = gen_reg_rtx (third_imode);
- emit_move_insn (ops[j], gen_lowpart (third_imode, op0));
- }
- second_imode = V2DImode;
- gen_interleave_second_low = gen_vec_interleave_lowv2di;
- /* FALLTHRU */
-
- case V2DImode:
- op0 = gen_reg_rtx (second_imode);
- emit_insn (gen_interleave_second_low (op0, ops[0],
- ops[1]));
-
- /* Cast the SECOND_IMODE vector back to a vector on original
- mode. */
- emit_insn (gen_rtx_SET (VOIDmode, target,
- gen_lowpart (mode, op0)));
- break;
-
- default:
- gcc_unreachable ();
- }
-}
-
-/* A subroutine of ix86_expand_vector_init. Handle the most general case:
- all values variable, and none identical. */
-
-static void
-ix86_expand_vector_init_general (bool mmx_ok, enum machine_mode mode,
- rtx target, rtx vals)
-{
- rtx ops[32], op0, op1;
- enum machine_mode half_mode = VOIDmode;
- int n, i;
-
- switch (mode)
- {
- case V2SFmode:
- case V2SImode:
- if (!mmx_ok && !TARGET_SSE)
- break;
- /* FALLTHRU */
-
- case V8SFmode:
- case V8SImode:
- case V4DFmode:
- case V4DImode:
- case V4SFmode:
- case V4SImode:
- case V2DFmode:
- case V2DImode:
- n = GET_MODE_NUNITS (mode);
- for (i = 0; i < n; i++)
- ops[i] = XVECEXP (vals, 0, i);
- ix86_expand_vector_init_concat (mode, target, ops, n);
- return;
-
- case V32QImode:
- half_mode = V16QImode;
- goto half;
-
- case V16HImode:
- half_mode = V8HImode;
- goto half;
-
-half:
- n = GET_MODE_NUNITS (mode);
- for (i = 0; i < n; i++)
- ops[i] = XVECEXP (vals, 0, i);
- op0 = gen_reg_rtx (half_mode);
- op1 = gen_reg_rtx (half_mode);
- ix86_expand_vector_init_interleave (half_mode, op0, ops,
- n >> 2);
- ix86_expand_vector_init_interleave (half_mode, op1,
- &ops [n >> 1], n >> 2);
- emit_insn (gen_rtx_SET (VOIDmode, target,
- gen_rtx_VEC_CONCAT (mode, op0, op1)));
- return;
-
- case V16QImode:
- if (!TARGET_SSE4_1)
- break;
- /* FALLTHRU */
-
- case V8HImode:
- if (!TARGET_SSE2)
- break;
-
- /* Don't use ix86_expand_vector_init_interleave if we can't
- move from GPR to SSE register directly. */
- if (!TARGET_INTER_UNIT_MOVES)
- break;
-
- n = GET_MODE_NUNITS (mode);
- for (i = 0; i < n; i++)
- ops[i] = XVECEXP (vals, 0, i);
- ix86_expand_vector_init_interleave (mode, target, ops, n >> 1);
- return;
-
- case V4HImode:
- case V8QImode:
- break;
-
- default:
- gcc_unreachable ();
- }
-
- {
- int i, j, n_elts, n_words, n_elt_per_word;
- enum machine_mode inner_mode;
- rtx words[4], shift;
-
- inner_mode = GET_MODE_INNER (mode);
- n_elts = GET_MODE_NUNITS (mode);
- n_words = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
- n_elt_per_word = n_elts / n_words;
- shift = GEN_INT (GET_MODE_BITSIZE (inner_mode));
-
- for (i = 0; i < n_words; ++i)
- {
- rtx word = NULL_RTX;
-
- for (j = 0; j < n_elt_per_word; ++j)
- {
- rtx elt = XVECEXP (vals, 0, (i+1)*n_elt_per_word - j - 1);
- elt = convert_modes (word_mode, inner_mode, elt, true);
-
- if (j == 0)
- word = elt;
- else
- {
- word = expand_simple_binop (word_mode, ASHIFT, word, shift,
- word, 1, OPTAB_LIB_WIDEN);
- word = expand_simple_binop (word_mode, IOR, word, elt,
- word, 1, OPTAB_LIB_WIDEN);
- }
- }
-
- words[i] = word;
- }
-
- if (n_words == 1)
- emit_move_insn (target, gen_lowpart (mode, words[0]));
- else if (n_words == 2)
- {
- rtx tmp = gen_reg_rtx (mode);
- emit_clobber (tmp);
- emit_move_insn (gen_lowpart (word_mode, tmp), words[0]);
- emit_move_insn (gen_highpart (word_mode, tmp), words[1]);
- emit_move_insn (target, tmp);
- }
- else if (n_words == 4)
- {
- rtx tmp = gen_reg_rtx (V4SImode);
- gcc_assert (word_mode == SImode);
- vals = gen_rtx_PARALLEL (V4SImode, gen_rtvec_v (4, words));
- ix86_expand_vector_init_general (false, V4SImode, tmp, vals);
- emit_move_insn (target, gen_lowpart (mode, tmp));
- }
- else
- gcc_unreachable ();
- }
-}
-
-/* Initialize vector TARGET via VALS. Suppress the use of MMX
- instructions unless MMX_OK is true. */
-
-void
-ix86_expand_vector_init (bool mmx_ok, rtx target, rtx vals)
-{
- enum machine_mode mode = GET_MODE (target);
- enum machine_mode inner_mode = GET_MODE_INNER (mode);
- int n_elts = GET_MODE_NUNITS (mode);
- int n_var = 0, one_var = -1;
- bool all_same = true, all_const_zero = true;
- int i;
- rtx x;
-
- for (i = 0; i < n_elts; ++i)
- {
- x = XVECEXP (vals, 0, i);
- if (!(CONST_INT_P (x)
- || GET_CODE (x) == CONST_DOUBLE
- || GET_CODE (x) == CONST_FIXED))
- n_var++, one_var = i;
- else if (x != CONST0_RTX (inner_mode))
- all_const_zero = false;
- if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
- all_same = false;
- }
-
- /* Constants are best loaded from the constant pool. */
- if (n_var == 0)
- {
- emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
- return;
- }
-
- /* If all values are identical, broadcast the value. */
- if (all_same
- && ix86_expand_vector_init_duplicate (mmx_ok, mode, target,
- XVECEXP (vals, 0, 0)))
- return;
-
- /* Values where only one field is non-constant are best loaded from
- the pool and overwritten via move later. */
- if (n_var == 1)
- {
- if (all_const_zero
- && ix86_expand_vector_init_one_nonzero (mmx_ok, mode, target,
- XVECEXP (vals, 0, one_var),
- one_var))
- return;
-
- if (ix86_expand_vector_init_one_var (mmx_ok, mode, target, vals, one_var))
- return;
- }
-
- ix86_expand_vector_init_general (mmx_ok, mode, target, vals);
-}
-
-void
-ix86_expand_vector_set (bool mmx_ok, rtx target, rtx val, int elt)
-{
- enum machine_mode mode = GET_MODE (target);
- enum machine_mode inner_mode = GET_MODE_INNER (mode);
- enum machine_mode half_mode;
- bool use_vec_merge = false;
- rtx tmp;
- static rtx (*gen_extract[6][2]) (rtx, rtx)
- = {
- { gen_vec_extract_lo_v32qi, gen_vec_extract_hi_v32qi },
- { gen_vec_extract_lo_v16hi, gen_vec_extract_hi_v16hi },
- { gen_vec_extract_lo_v8si, gen_vec_extract_hi_v8si },
- { gen_vec_extract_lo_v4di, gen_vec_extract_hi_v4di },
- { gen_vec_extract_lo_v8sf, gen_vec_extract_hi_v8sf },
- { gen_vec_extract_lo_v4df, gen_vec_extract_hi_v4df }
- };
- static rtx (*gen_insert[6][2]) (rtx, rtx, rtx)
- = {
- { gen_vec_set_lo_v32qi, gen_vec_set_hi_v32qi },
- { gen_vec_set_lo_v16hi, gen_vec_set_hi_v16hi },
- { gen_vec_set_lo_v8si, gen_vec_set_hi_v8si },
- { gen_vec_set_lo_v4di, gen_vec_set_hi_v4di },
- { gen_vec_set_lo_v8sf, gen_vec_set_hi_v8sf },
- { gen_vec_set_lo_v4df, gen_vec_set_hi_v4df }
- };
- int i, j, n;
-
- switch (mode)
- {
- case V2SFmode:
- case V2SImode:
- if (mmx_ok)
- {
- tmp = gen_reg_rtx (GET_MODE_INNER (mode));
- ix86_expand_vector_extract (true, tmp, target, 1 - elt);
- if (elt == 0)
- tmp = gen_rtx_VEC_CONCAT (mode, val, tmp);
- else
- tmp = gen_rtx_VEC_CONCAT (mode, tmp, val);
- emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
- return;
- }
- break;
-
- case V2DImode:
- use_vec_merge = TARGET_SSE4_1 && TARGET_64BIT;
- if (use_vec_merge)
- break;
-
- tmp = gen_reg_rtx (GET_MODE_INNER (mode));
- ix86_expand_vector_extract (false, tmp, target, 1 - elt);
- if (elt == 0)
- tmp = gen_rtx_VEC_CONCAT (mode, val, tmp);
- else
- tmp = gen_rtx_VEC_CONCAT (mode, tmp, val);
- emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
- return;
-
- case V2DFmode:
- {
- rtx op0, op1;
-
- /* For the two element vectors, we implement a VEC_CONCAT with
- the extraction of the other element. */
-
- tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, GEN_INT (1 - elt)));
- tmp = gen_rtx_VEC_SELECT (inner_mode, target, tmp);
-
- if (elt == 0)
- op0 = val, op1 = tmp;
- else
- op0 = tmp, op1 = val;
-
- tmp = gen_rtx_VEC_CONCAT (mode, op0, op1);
- emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
- }
- return;
-
- case V4SFmode:
- use_vec_merge = TARGET_SSE4_1;
- if (use_vec_merge)
- break;
-
- switch (elt)
- {
- case 0:
- use_vec_merge = true;
- break;
-
- case 1:
- /* tmp = target = A B C D */
- tmp = copy_to_reg (target);
- /* target = A A B B */
- emit_insn (gen_vec_interleave_lowv4sf (target, target, target));
- /* target = X A B B */
- ix86_expand_vector_set (false, target, val, 0);
- /* target = A X C D */
- emit_insn (gen_sse_shufps_v4sf (target, target, tmp,
- const1_rtx, const0_rtx,
- GEN_INT (2+4), GEN_INT (3+4)));
- return;
-
- case 2:
- /* tmp = target = A B C D */
- tmp = copy_to_reg (target);
- /* tmp = X B C D */
- ix86_expand_vector_set (false, tmp, val, 0);
- /* target = A B X D */
- emit_insn (gen_sse_shufps_v4sf (target, target, tmp,
- const0_rtx, const1_rtx,
- GEN_INT (0+4), GEN_INT (3+4)));
- return;
-
- case 3:
- /* tmp = target = A B C D */
- tmp = copy_to_reg (target);
- /* tmp = X B C D */
- ix86_expand_vector_set (false, tmp, val, 0);
- /* target = A B X D */
- emit_insn (gen_sse_shufps_v4sf (target, target, tmp,
- const0_rtx, const1_rtx,
- GEN_INT (2+4), GEN_INT (0+4)));
- return;
-
- default:
- gcc_unreachable ();
- }
- break;
-
- case V4SImode:
- use_vec_merge = TARGET_SSE4_1;
- if (use_vec_merge)
- break;
-
- /* Element 0 handled by vec_merge below. */
- if (elt == 0)
- {
- use_vec_merge = true;
- break;
- }
-
- if (TARGET_SSE2)
- {
- /* With SSE2, use integer shuffles to swap element 0 and ELT,
- store into element 0, then shuffle them back. */
-
- rtx order[4];
-
- order[0] = GEN_INT (elt);
- order[1] = const1_rtx;
- order[2] = const2_rtx;
- order[3] = GEN_INT (3);
- order[elt] = const0_rtx;
-
- emit_insn (gen_sse2_pshufd_1 (target, target, order[0],
- order[1], order[2], order[3]));
-
- ix86_expand_vector_set (false, target, val, 0);
-
- emit_insn (gen_sse2_pshufd_1 (target, target, order[0],
- order[1], order[2], order[3]));
- }
- else
- {
- /* For SSE1, we have to reuse the V4SF code. */
- ix86_expand_vector_set (false, gen_lowpart (V4SFmode, target),
- gen_lowpart (SFmode, val), elt);
- }
- return;
-
- case V8HImode:
- use_vec_merge = TARGET_SSE2;
- break;
- case V4HImode:
- use_vec_merge = mmx_ok && (TARGET_SSE || TARGET_3DNOW_A);
- break;
-
- case V16QImode:
- use_vec_merge = TARGET_SSE4_1;
- break;
-
- case V8QImode:
- break;
-
- case V32QImode:
- half_mode = V16QImode;
- j = 0;
- n = 16;
- goto half;
-
- case V16HImode:
- half_mode = V8HImode;
- j = 1;
- n = 8;
- goto half;
-
- case V8SImode:
- half_mode = V4SImode;
- j = 2;
- n = 4;
- goto half;
-
- case V4DImode:
- half_mode = V2DImode;
- j = 3;
- n = 2;
- goto half;
-
- case V8SFmode:
- half_mode = V4SFmode;
- j = 4;
- n = 4;
- goto half;
-
- case V4DFmode:
- half_mode = V2DFmode;
- j = 5;
- n = 2;
- goto half;
-
-half:
- /* Compute offset. */
- i = elt / n;
- elt %= n;
-
- gcc_assert (i <= 1);
-
- /* Extract the half. */
- tmp = gen_reg_rtx (half_mode);
- emit_insn (gen_extract[j][i] (tmp, target));
-
- /* Put val in tmp at elt. */
- ix86_expand_vector_set (false, tmp, val, elt);
-
- /* Put it back. */
- emit_insn (gen_insert[j][i] (target, target, tmp));
- return;
-
- default:
- break;
- }
-
- if (use_vec_merge)
- {
- tmp = gen_rtx_VEC_DUPLICATE (mode, val);
- tmp = gen_rtx_VEC_MERGE (mode, tmp, target, GEN_INT (1 << elt));
- emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
- }
- else
- {
- rtx mem = assign_stack_temp (mode, GET_MODE_SIZE (mode));
-
- emit_move_insn (mem, target);
-
- tmp = adjust_address (mem, inner_mode, elt*GET_MODE_SIZE (inner_mode));
- emit_move_insn (tmp, val);
-
- emit_move_insn (target, mem);
- }
-}
-
-void
-ix86_expand_vector_extract (bool mmx_ok, rtx target, rtx vec, int elt)
-{
- enum machine_mode mode = GET_MODE (vec);
- enum machine_mode inner_mode = GET_MODE_INNER (mode);
- bool use_vec_extr = false;
- rtx tmp;
-
- switch (mode)
- {
- case V2SImode:
- case V2SFmode:
- if (!mmx_ok)
- break;
- /* FALLTHRU */
-
- case V2DFmode:
- case V2DImode:
- use_vec_extr = true;
- break;
-
- case V4SFmode:
- use_vec_extr = TARGET_SSE4_1;
- if (use_vec_extr)
- break;
-
- switch (elt)
- {
- case 0:
- tmp = vec;
- break;
-
- case 1:
- case 3:
- tmp = gen_reg_rtx (mode);
- emit_insn (gen_sse_shufps_v4sf (tmp, vec, vec,
- GEN_INT (elt), GEN_INT (elt),
- GEN_INT (elt+4), GEN_INT (elt+4)));
- break;
-
- case 2:
- tmp = gen_reg_rtx (mode);
- emit_insn (gen_vec_interleave_highv4sf (tmp, vec, vec));
- break;
-
- default:
- gcc_unreachable ();
- }
- vec = tmp;
- use_vec_extr = true;
- elt = 0;
- break;
-
- case V4SImode:
- use_vec_extr = TARGET_SSE4_1;
- if (use_vec_extr)
- break;
-
- if (TARGET_SSE2)
- {
- switch (elt)
- {
- case 0:
- tmp = vec;
- break;
-
- case 1:
- case 3:
- tmp = gen_reg_rtx (mode);
- emit_insn (gen_sse2_pshufd_1 (tmp, vec,
- GEN_INT (elt), GEN_INT (elt),
- GEN_INT (elt), GEN_INT (elt)));
- break;
-
- case 2:
- tmp = gen_reg_rtx (mode);
- emit_insn (gen_vec_interleave_highv4si (tmp, vec, vec));
- break;
-
- default:
- gcc_unreachable ();
- }
- vec = tmp;
- use_vec_extr = true;
- elt = 0;
- }
- else
- {
- /* For SSE1, we have to reuse the V4SF code. */
- ix86_expand_vector_extract (false, gen_lowpart (SFmode, target),
- gen_lowpart (V4SFmode, vec), elt);
- return;
- }
- break;
-
- case V8HImode:
- use_vec_extr = TARGET_SSE2;
- break;
- case V4HImode:
- use_vec_extr = mmx_ok && (TARGET_SSE || TARGET_3DNOW_A);
- break;
-
- case V16QImode:
- use_vec_extr = TARGET_SSE4_1;
- break;
-
- case V8SFmode:
- if (TARGET_AVX)
- {
- tmp = gen_reg_rtx (V4SFmode);
- if (elt < 4)
- emit_insn (gen_vec_extract_lo_v8sf (tmp, vec));
- else
- emit_insn (gen_vec_extract_hi_v8sf (tmp, vec));
- ix86_expand_vector_extract (false, target, tmp, elt & 3);
- return;
- }
- break;
-
- case V4DFmode:
- if (TARGET_AVX)
- {
- tmp = gen_reg_rtx (V2DFmode);
- if (elt < 2)
- emit_insn (gen_vec_extract_lo_v4df (tmp, vec));
- else
- emit_insn (gen_vec_extract_hi_v4df (tmp, vec));
- ix86_expand_vector_extract (false, target, tmp, elt & 1);
- return;
- }
- break;
-
- case V32QImode:
- if (TARGET_AVX)
- {
- tmp = gen_reg_rtx (V16QImode);
- if (elt < 16)
- emit_insn (gen_vec_extract_lo_v32qi (tmp, vec));
- else
- emit_insn (gen_vec_extract_hi_v32qi (tmp, vec));
- ix86_expand_vector_extract (false, target, tmp, elt & 15);
- return;
- }
- break;
-
- case V16HImode:
- if (TARGET_AVX)
- {
- tmp = gen_reg_rtx (V8HImode);
- if (elt < 8)
- emit_insn (gen_vec_extract_lo_v16hi (tmp, vec));
- else
- emit_insn (gen_vec_extract_hi_v16hi (tmp, vec));
- ix86_expand_vector_extract (false, target, tmp, elt & 7);
- return;
- }
- break;
-
- case V8SImode:
- if (TARGET_AVX)
- {
- tmp = gen_reg_rtx (V4SImode);
- if (elt < 4)
- emit_insn (gen_vec_extract_lo_v8si (tmp, vec));
- else
- emit_insn (gen_vec_extract_hi_v8si (tmp, vec));
- ix86_expand_vector_extract (false, target, tmp, elt & 3);
- return;
- }
- break;
-
- case V4DImode:
- if (TARGET_AVX)
- {
- tmp = gen_reg_rtx (V2DImode);
- if (elt < 2)
- emit_insn (gen_vec_extract_lo_v4di (tmp, vec));
- else
- emit_insn (gen_vec_extract_hi_v4di (tmp, vec));
- ix86_expand_vector_extract (false, target, tmp, elt & 1);
- return;
- }
- break;
-
- case V8QImode:
- /* ??? Could extract the appropriate HImode element and shift. */
- default:
- break;
- }
-
- if (use_vec_extr)
- {
- tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, GEN_INT (elt)));
- tmp = gen_rtx_VEC_SELECT (inner_mode, vec, tmp);
-
- /* Let the rtl optimizers know about the zero extension performed. */
- if (inner_mode == QImode || inner_mode == HImode)
- {
- tmp = gen_rtx_ZERO_EXTEND (SImode, tmp);
- target = gen_lowpart (SImode, target);
- }
-
- emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
- }
- else
- {
- rtx mem = assign_stack_temp (mode, GET_MODE_SIZE (mode));
-
- emit_move_insn (mem, vec);
-
- tmp = adjust_address (mem, inner_mode, elt*GET_MODE_SIZE (inner_mode));
- emit_move_insn (target, tmp);
- }
-}
-
-/* Generate code to copy vector bits i / 2 ... i - 1 from vector SRC
- to bits 0 ... i / 2 - 1 of vector DEST, which has the same mode.
- The upper bits of DEST are undefined, though they shouldn't cause
- exceptions (some bits from src or all zeros are ok). */
-
-static void
-emit_reduc_half (rtx dest, rtx src, int i)
-{
- rtx tem;
- switch (GET_MODE (src))
- {
- case V4SFmode:
- if (i == 128)
- tem = gen_sse_movhlps (dest, src, src);
- else
- tem = gen_sse_shufps_v4sf (dest, src, src, const1_rtx, const1_rtx,
- GEN_INT (1 + 4), GEN_INT (1 + 4));
- break;
- case V2DFmode:
- tem = gen_vec_interleave_highv2df (dest, src, src);
- break;
- case V16QImode:
- case V8HImode:
- case V4SImode:
- case V2DImode:
- tem = gen_sse2_lshrv1ti3 (gen_lowpart (V1TImode, dest),
- gen_lowpart (V1TImode, src),
- GEN_INT (i / 2));
- break;
- case V8SFmode:
- if (i == 256)
- tem = gen_avx_vperm2f128v8sf3 (dest, src, src, const1_rtx);
- else
- tem = gen_avx_shufps256 (dest, src, src,
- GEN_INT (i == 128 ? 2 + (3 << 2) : 1));
- break;
- case V4DFmode:
- if (i == 256)
- tem = gen_avx_vperm2f128v4df3 (dest, src, src, const1_rtx);
- else
- tem = gen_avx_shufpd256 (dest, src, src, const1_rtx);
- break;
- case V32QImode:
- case V16HImode:
- case V8SImode:
- case V4DImode:
- if (i == 256)
- tem = gen_avx2_permv2ti (gen_lowpart (V4DImode, dest),
- gen_lowpart (V4DImode, src),
- gen_lowpart (V4DImode, src),
- const1_rtx);
- else
- tem = gen_avx2_lshrv2ti3 (gen_lowpart (V2TImode, dest),
- gen_lowpart (V2TImode, src),
- GEN_INT (i / 2));
- break;
- default:
- gcc_unreachable ();
- }
- emit_insn (tem);
-}
-
-/* Expand a vector reduction. FN is the binary pattern to reduce;
- DEST is the destination; IN is the input vector. */
-
-void
-ix86_expand_reduc (rtx (*fn) (rtx, rtx, rtx), rtx dest, rtx in)
-{
- rtx half, dst, vec = in;
- enum machine_mode mode = GET_MODE (in);
- int i;
-
- /* SSE4 has a special instruction for V8HImode UMIN reduction. */
- if (TARGET_SSE4_1
- && mode == V8HImode
- && fn == gen_uminv8hi3)
- {
- emit_insn (gen_sse4_1_phminposuw (dest, in));
- return;
- }
-
- for (i = GET_MODE_BITSIZE (mode);
- i > GET_MODE_BITSIZE (GET_MODE_INNER (mode));
- i >>= 1)
- {
- half = gen_reg_rtx (mode);
- emit_reduc_half (half, vec, i);
- if (i == GET_MODE_BITSIZE (GET_MODE_INNER (mode)) * 2)
- dst = dest;
- else
- dst = gen_reg_rtx (mode);
- emit_insn (fn (dst, half, vec));
- vec = dst;
- }
-}
-
-/* Target hook for scalar_mode_supported_p. */
-static bool
-ix86_scalar_mode_supported_p (enum machine_mode mode)
-{
- if (DECIMAL_FLOAT_MODE_P (mode))
- return default_decimal_float_supported_p ();
- else if (mode == TFmode)
- return true;
- else
- return default_scalar_mode_supported_p (mode);
-}
-
-/* Implements target hook vector_mode_supported_p. */
-static bool
-ix86_vector_mode_supported_p (enum machine_mode mode)
-{
- if (TARGET_SSE && VALID_SSE_REG_MODE (mode))
- return true;
- if (TARGET_SSE2 && VALID_SSE2_REG_MODE (mode))
- return true;
- if (TARGET_AVX && VALID_AVX256_REG_MODE (mode))
- return true;
- if (TARGET_MMX && VALID_MMX_REG_MODE (mode))
- return true;
- if (TARGET_3DNOW && VALID_MMX_REG_MODE_3DNOW (mode))
- return true;
- return false;
-}
-
-/* Target hook for c_mode_for_suffix. */
-static enum machine_mode
-ix86_c_mode_for_suffix (char suffix)
-{
- if (suffix == 'q')
- return TFmode;
- if (suffix == 'w')
- return XFmode;
-
- return VOIDmode;
-}
-
-/* Worker function for TARGET_MD_ASM_CLOBBERS.
-
- We do this in the new i386 backend to maintain source compatibility
- with the old cc0-based compiler. */
-
-static tree
-ix86_md_asm_clobbers (tree outputs ATTRIBUTE_UNUSED,
- tree inputs ATTRIBUTE_UNUSED,
- tree clobbers)
-{
- clobbers = tree_cons (NULL_TREE, build_string (5, "flags"),
- clobbers);
- clobbers = tree_cons (NULL_TREE, build_string (4, "fpsr"),
- clobbers);
- return clobbers;
-}
-
-/* Implements target vector targetm.asm.encode_section_info. */
-
-static void ATTRIBUTE_UNUSED
-ix86_encode_section_info (tree decl, rtx rtl, int first)
-{
- default_encode_section_info (decl, rtl, first);
-
- if (TREE_CODE (decl) == VAR_DECL
- && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
- && ix86_in_large_data_p (decl))
- SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_FAR_ADDR;
-}
-
-/* Worker function for REVERSE_CONDITION. */
-
-enum rtx_code
-ix86_reverse_condition (enum rtx_code code, enum machine_mode mode)
-{
- return (mode != CCFPmode && mode != CCFPUmode
- ? reverse_condition (code)
- : reverse_condition_maybe_unordered (code));
-}
-
-/* Output code to perform an x87 FP register move, from OPERANDS[1]
- to OPERANDS[0]. */
-
-const char *
-output_387_reg_move (rtx insn, rtx *operands)
-{
- if (REG_P (operands[0]))
- {
- if (REG_P (operands[1])
- && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- {
- if (REGNO (operands[0]) == FIRST_STACK_REG)
- return output_387_ffreep (operands, 0);
- return "fstp\t%y0";
- }
- if (STACK_TOP_P (operands[0]))
- return "fld%Z1\t%y1";
- return "fst\t%y0";
- }
- else if (MEM_P (operands[0]))
- {
- gcc_assert (REG_P (operands[1]));
- if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "fstp%Z0\t%y0";
- else
- {
- /* There is no non-popping store to memory for XFmode.
- So if we need one, follow the store with a load. */
- if (GET_MODE (operands[0]) == XFmode)
- return "fstp%Z0\t%y0\n\tfld%Z0\t%y0";
- else
- return "fst%Z0\t%y0";
- }
- }
- else
- gcc_unreachable();
-}
-
-/* Output code to perform a conditional jump to LABEL, if C2 flag in
- FP status register is set. */
-
-void
-ix86_emit_fp_unordered_jump (rtx label)
-{
- rtx reg = gen_reg_rtx (HImode);
- rtx temp;
-
- emit_insn (gen_x86_fnstsw_1 (reg));
-
- if (TARGET_SAHF && (TARGET_USE_SAHF || optimize_insn_for_size_p ()))
- {
- emit_insn (gen_x86_sahf_1 (reg));
-
- temp = gen_rtx_REG (CCmode, FLAGS_REG);
- temp = gen_rtx_UNORDERED (VOIDmode, temp, const0_rtx);
- }
- else
- {
- emit_insn (gen_testqi_ext_ccno_0 (reg, GEN_INT (0x04)));
-
- temp = gen_rtx_REG (CCNOmode, FLAGS_REG);
- temp = gen_rtx_NE (VOIDmode, temp, const0_rtx);
- }
-
- temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
- gen_rtx_LABEL_REF (VOIDmode, label),
- pc_rtx);
- temp = gen_rtx_SET (VOIDmode, pc_rtx, temp);
-
- emit_jump_insn (temp);
- predict_jump (REG_BR_PROB_BASE * 10 / 100);
-}
-
-/* Output code to perform a log1p XFmode calculation. */
-
-void ix86_emit_i387_log1p (rtx op0, rtx op1)
-{
- rtx label1 = gen_label_rtx ();
- rtx label2 = gen_label_rtx ();
-
- rtx tmp = gen_reg_rtx (XFmode);
- rtx tmp2 = gen_reg_rtx (XFmode);
- rtx test;
-
- emit_insn (gen_absxf2 (tmp, op1));
- test = gen_rtx_GE (VOIDmode, tmp,
- CONST_DOUBLE_FROM_REAL_VALUE (
- REAL_VALUE_ATOF ("0.29289321881345247561810596348408353", XFmode),
- XFmode));
- emit_jump_insn (gen_cbranchxf4 (test, XEXP (test, 0), XEXP (test, 1), label1));
-
- emit_move_insn (tmp2, standard_80387_constant_rtx (4)); /* fldln2 */
- emit_insn (gen_fyl2xp1xf3_i387 (op0, op1, tmp2));
- emit_jump (label2);
-
- emit_label (label1);
- emit_move_insn (tmp, CONST1_RTX (XFmode));
- emit_insn (gen_addxf3 (tmp, op1, tmp));
- emit_move_insn (tmp2, standard_80387_constant_rtx (4)); /* fldln2 */
- emit_insn (gen_fyl2xxf3_i387 (op0, tmp, tmp2));
-
- emit_label (label2);
-}
-
-/* Emit code for round calculation. */
-void ix86_emit_i387_round (rtx op0, rtx op1)
-{
- enum machine_mode inmode = GET_MODE (op1);
- enum machine_mode outmode = GET_MODE (op0);
- rtx e1, e2, res, tmp, tmp1, half;
- rtx scratch = gen_reg_rtx (HImode);
- rtx flags = gen_rtx_REG (CCNOmode, FLAGS_REG);
- rtx jump_label = gen_label_rtx ();
- rtx insn;
- rtx (*gen_abs) (rtx, rtx);
- rtx (*gen_neg) (rtx, rtx);
-
- switch (inmode)
- {
- case SFmode:
- gen_abs = gen_abssf2;
- break;
- case DFmode:
- gen_abs = gen_absdf2;
- break;
- case XFmode:
- gen_abs = gen_absxf2;
- break;
- default:
- gcc_unreachable ();
- }
-
- switch (outmode)
- {
- case SFmode:
- gen_neg = gen_negsf2;
- break;
- case DFmode:
- gen_neg = gen_negdf2;
- break;
- case XFmode:
- gen_neg = gen_negxf2;
- break;
- case HImode:
- gen_neg = gen_neghi2;
- break;
- case SImode:
- gen_neg = gen_negsi2;
- break;
- case DImode:
- gen_neg = gen_negdi2;
- break;
- default:
- gcc_unreachable ();
- }
-
- e1 = gen_reg_rtx (inmode);
- e2 = gen_reg_rtx (inmode);
- res = gen_reg_rtx (outmode);
-
- half = CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf, inmode);
-
- /* round(a) = sgn(a) * floor(fabs(a) + 0.5) */
-
- /* scratch = fxam(op1) */
- emit_insn (gen_rtx_SET (VOIDmode, scratch,
- gen_rtx_UNSPEC (HImode, gen_rtvec (1, op1),
- UNSPEC_FXAM)));
- /* e1 = fabs(op1) */
- emit_insn (gen_abs (e1, op1));
-
- /* e2 = e1 + 0.5 */
- half = force_reg (inmode, half);
- emit_insn (gen_rtx_SET (VOIDmode, e2,
- gen_rtx_PLUS (inmode, e1, half)));
-
- /* res = floor(e2) */
- if (inmode != XFmode)
- {
- tmp1 = gen_reg_rtx (XFmode);
-
- emit_insn (gen_rtx_SET (VOIDmode, tmp1,
- gen_rtx_FLOAT_EXTEND (XFmode, e2)));
- }
- else
- tmp1 = e2;
-
- switch (outmode)
- {
- case SFmode:
- case DFmode:
- {
- rtx tmp0 = gen_reg_rtx (XFmode);
-
- emit_insn (gen_frndintxf2_floor (tmp0, tmp1));
-
- emit_insn (gen_rtx_SET (VOIDmode, res,
- gen_rtx_UNSPEC (outmode, gen_rtvec (1, tmp0),
- UNSPEC_TRUNC_NOOP)));
- }
- break;
- case XFmode:
- emit_insn (gen_frndintxf2_floor (res, tmp1));
- break;
- case HImode:
- emit_insn (gen_lfloorxfhi2 (res, tmp1));
- break;
- case SImode:
- emit_insn (gen_lfloorxfsi2 (res, tmp1));
- break;
- case DImode:
- emit_insn (gen_lfloorxfdi2 (res, tmp1));
- break;
- default:
- gcc_unreachable ();
- }
-
- /* flags = signbit(a) */
- emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x02)));
-
- /* if (flags) then res = -res */
- tmp = gen_rtx_IF_THEN_ELSE (VOIDmode,
- gen_rtx_EQ (VOIDmode, flags, const0_rtx),
- gen_rtx_LABEL_REF (VOIDmode, jump_label),
- pc_rtx);
- insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
- predict_jump (REG_BR_PROB_BASE * 50 / 100);
- JUMP_LABEL (insn) = jump_label;
-
- emit_insn (gen_neg (res, res));
-
- emit_label (jump_label);
- LABEL_NUSES (jump_label) = 1;
-
- emit_move_insn (op0, res);
-}
-
-/* Output code to perform a Newton-Rhapson approximation of a single precision
- floating point divide [http://en.wikipedia.org/wiki/N-th_root_algorithm]. */
-
-void ix86_emit_swdivsf (rtx res, rtx a, rtx b, enum machine_mode mode)
-{
- rtx x0, x1, e0, e1;
-
- x0 = gen_reg_rtx (mode);
- e0 = gen_reg_rtx (mode);
- e1 = gen_reg_rtx (mode);
- x1 = gen_reg_rtx (mode);
-
- /* a / b = a * ((rcp(b) + rcp(b)) - (b * rcp(b) * rcp (b))) */
-
- b = force_reg (mode, b);
-
- /* x0 = rcp(b) estimate */
- emit_insn (gen_rtx_SET (VOIDmode, x0,
- gen_rtx_UNSPEC (mode, gen_rtvec (1, b),
- UNSPEC_RCP)));
- /* e0 = x0 * b */
- emit_insn (gen_rtx_SET (VOIDmode, e0,
- gen_rtx_MULT (mode, x0, b)));
-
- /* e0 = x0 * e0 */
- emit_insn (gen_rtx_SET (VOIDmode, e0,
- gen_rtx_MULT (mode, x0, e0)));
-
- /* e1 = x0 + x0 */
- emit_insn (gen_rtx_SET (VOIDmode, e1,
- gen_rtx_PLUS (mode, x0, x0)));
-
- /* x1 = e1 - e0 */
- emit_insn (gen_rtx_SET (VOIDmode, x1,
- gen_rtx_MINUS (mode, e1, e0)));
-
- /* res = a * x1 */
- emit_insn (gen_rtx_SET (VOIDmode, res,
- gen_rtx_MULT (mode, a, x1)));
-}
-
-/* Output code to perform a Newton-Rhapson approximation of a
- single precision floating point [reciprocal] square root. */
-
-void ix86_emit_swsqrtsf (rtx res, rtx a, enum machine_mode mode,
- bool recip)
-{
- rtx x0, e0, e1, e2, e3, mthree, mhalf;
- REAL_VALUE_TYPE r;
-
- x0 = gen_reg_rtx (mode);
- e0 = gen_reg_rtx (mode);
- e1 = gen_reg_rtx (mode);
- e2 = gen_reg_rtx (mode);
- e3 = gen_reg_rtx (mode);
-
- real_from_integer (&r, VOIDmode, -3, -1, 0);
- mthree = CONST_DOUBLE_FROM_REAL_VALUE (r, SFmode);
-
- real_arithmetic (&r, NEGATE_EXPR, &dconsthalf, NULL);
- mhalf = CONST_DOUBLE_FROM_REAL_VALUE (r, SFmode);
-
- if (VECTOR_MODE_P (mode))
- {
- mthree = ix86_build_const_vector (mode, true, mthree);
- mhalf = ix86_build_const_vector (mode, true, mhalf);
- }
-
- /* sqrt(a) = -0.5 * a * rsqrtss(a) * (a * rsqrtss(a) * rsqrtss(a) - 3.0)
- rsqrt(a) = -0.5 * rsqrtss(a) * (a * rsqrtss(a) * rsqrtss(a) - 3.0) */
-
- a = force_reg (mode, a);
-
- /* x0 = rsqrt(a) estimate */
- emit_insn (gen_rtx_SET (VOIDmode, x0,
- gen_rtx_UNSPEC (mode, gen_rtvec (1, a),
- UNSPEC_RSQRT)));
-
- /* If (a == 0.0) Filter out infinity to prevent NaN for sqrt(0.0). */
- if (!recip)
- {
- rtx zero, mask;
-
- zero = gen_reg_rtx (mode);
- mask = gen_reg_rtx (mode);
-
- zero = force_reg (mode, CONST0_RTX(mode));
- emit_insn (gen_rtx_SET (VOIDmode, mask,
- gen_rtx_NE (mode, zero, a)));
-
- emit_insn (gen_rtx_SET (VOIDmode, x0,
- gen_rtx_AND (mode, x0, mask)));
- }
-
- /* e0 = x0 * a */
- emit_insn (gen_rtx_SET (VOIDmode, e0,
- gen_rtx_MULT (mode, x0, a)));
- /* e1 = e0 * x0 */
- emit_insn (gen_rtx_SET (VOIDmode, e1,
- gen_rtx_MULT (mode, e0, x0)));
-
- /* e2 = e1 - 3. */
- mthree = force_reg (mode, mthree);
- emit_insn (gen_rtx_SET (VOIDmode, e2,
- gen_rtx_PLUS (mode, e1, mthree)));
-
- mhalf = force_reg (mode, mhalf);
- if (recip)
- /* e3 = -.5 * x0 */
- emit_insn (gen_rtx_SET (VOIDmode, e3,
- gen_rtx_MULT (mode, x0, mhalf)));
- else
- /* e3 = -.5 * e0 */
- emit_insn (gen_rtx_SET (VOIDmode, e3,
- gen_rtx_MULT (mode, e0, mhalf)));
- /* ret = e2 * e3 */
- emit_insn (gen_rtx_SET (VOIDmode, res,
- gen_rtx_MULT (mode, e2, e3)));
-}
-
-#ifdef TARGET_SOLARIS
-/* Solaris implementation of TARGET_ASM_NAMED_SECTION. */
-
-static void
-i386_solaris_elf_named_section (const char *name, unsigned int flags,
- tree decl)
-{
- /* With Binutils 2.15, the "@unwind" marker must be specified on
- every occurrence of the ".eh_frame" section, not just the first
- one. */
- if (TARGET_64BIT
- && strcmp (name, ".eh_frame") == 0)
- {
- fprintf (asm_out_file, "\t.section\t%s,\"%s\",@unwind\n", name,
- flags & SECTION_WRITE ? "aw" : "a");
- return;
- }
-
-#ifndef USE_GAS
- if (HAVE_COMDAT_GROUP && flags & SECTION_LINKONCE)
- {
- solaris_elf_asm_comdat_section (name, flags, decl);
- return;
- }
-#endif
-
- default_elf_asm_named_section (name, flags, decl);
-}
-#endif /* TARGET_SOLARIS */
-
-/* Return the mangling of TYPE if it is an extended fundamental type. */
-
-static const char *
-ix86_mangle_type (const_tree type)
-{
- type = TYPE_MAIN_VARIANT (type);
-
- if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
- && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
- return NULL;
-
- switch (TYPE_MODE (type))
- {
- case TFmode:
- /* __float128 is "g". */
- return "g";
- case XFmode:
- /* "long double" or __float80 is "e". */
- return "e";
- default:
- return NULL;
- }
-}
-
-/* For 32-bit code we can save PIC register setup by using
- __stack_chk_fail_local hidden function instead of calling
- __stack_chk_fail directly. 64-bit code doesn't need to setup any PIC
- register, so it is better to call __stack_chk_fail directly. */
-
-static tree ATTRIBUTE_UNUSED
-ix86_stack_protect_fail (void)
-{
- return TARGET_64BIT
- ? default_external_stack_protect_fail ()
- : default_hidden_stack_protect_fail ();
-}
-
-/* Select a format to encode pointers in exception handling data. 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.
-
- ??? All x86 object file formats are capable of representing this.
- After all, the relocation needed is the same as for the call insn.
- Whether or not a particular assembler allows us to enter such, I
- guess we'll have to see. */
-int
-asm_preferred_eh_data_format (int code, int global)
-{
- if (flag_pic)
- {
- int type = DW_EH_PE_sdata8;
- if (!TARGET_64BIT
- || ix86_cmodel == CM_SMALL_PIC
- || (ix86_cmodel == CM_MEDIUM_PIC && (global || code)))
- type = DW_EH_PE_sdata4;
- return (global ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | type;
- }
- if (ix86_cmodel == CM_SMALL
- || (ix86_cmodel == CM_MEDIUM && code))
- return DW_EH_PE_udata4;
- return DW_EH_PE_absptr;
-}
-
-/* Expand copysign from SIGN to the positive value ABS_VALUE
- storing in RESULT. If MASK is non-null, it shall be a mask to mask out
- the sign-bit. */
-static void
-ix86_sse_copysign_to_positive (rtx result, rtx abs_value, rtx sign, rtx mask)
-{
- enum machine_mode mode = GET_MODE (sign);
- rtx sgn = gen_reg_rtx (mode);
- if (mask == NULL_RTX)
- {
- enum machine_mode vmode;
-
- if (mode == SFmode)
- vmode = V4SFmode;
- else if (mode == DFmode)
- vmode = V2DFmode;
- else
- vmode = mode;
-
- mask = ix86_build_signbit_mask (vmode, VECTOR_MODE_P (mode), false);
- if (!VECTOR_MODE_P (mode))
- {
- /* We need to generate a scalar mode mask in this case. */
- rtx tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const0_rtx));
- tmp = gen_rtx_VEC_SELECT (mode, mask, tmp);
- mask = gen_reg_rtx (mode);
- emit_insn (gen_rtx_SET (VOIDmode, mask, tmp));
- }
- }
- else
- mask = gen_rtx_NOT (mode, mask);
- emit_insn (gen_rtx_SET (VOIDmode, sgn,
- gen_rtx_AND (mode, mask, sign)));
- emit_insn (gen_rtx_SET (VOIDmode, result,
- gen_rtx_IOR (mode, abs_value, sgn)));
-}
-
-/* Expand fabs (OP0) and return a new rtx that holds the result. The
- mask for masking out the sign-bit is stored in *SMASK, if that is
- non-null. */
-static rtx
-ix86_expand_sse_fabs (rtx op0, rtx *smask)
-{
- enum machine_mode vmode, mode = GET_MODE (op0);
- rtx xa, mask;
-
- xa = gen_reg_rtx (mode);
- if (mode == SFmode)
- vmode = V4SFmode;
- else if (mode == DFmode)
- vmode = V2DFmode;
- else
- vmode = mode;
- mask = ix86_build_signbit_mask (vmode, VECTOR_MODE_P (mode), true);
- if (!VECTOR_MODE_P (mode))
- {
- /* We need to generate a scalar mode mask in this case. */
- rtx tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const0_rtx));
- tmp = gen_rtx_VEC_SELECT (mode, mask, tmp);
- mask = gen_reg_rtx (mode);
- emit_insn (gen_rtx_SET (VOIDmode, mask, tmp));
- }
- emit_insn (gen_rtx_SET (VOIDmode, xa,
- gen_rtx_AND (mode, op0, mask)));
-
- if (smask)
- *smask = mask;
-
- return xa;
-}
-
-/* Expands a comparison of OP0 with OP1 using comparison code CODE,
- swapping the operands if SWAP_OPERANDS is true. The expanded
- code is a forward jump to a newly created label in case the
- comparison is true. The generated label rtx is returned. */
-static rtx
-ix86_expand_sse_compare_and_jump (enum rtx_code code, rtx op0, rtx op1,
- bool swap_operands)
-{
- rtx label, tmp;
-
- if (swap_operands)
- {
- tmp = op0;
- op0 = op1;
- op1 = tmp;
- }
-
- label = gen_label_rtx ();
- tmp = gen_rtx_REG (CCFPUmode, FLAGS_REG);
- emit_insn (gen_rtx_SET (VOIDmode, tmp,
- gen_rtx_COMPARE (CCFPUmode, op0, op1)));
- tmp = gen_rtx_fmt_ee (code, VOIDmode, tmp, const0_rtx);
- tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
- gen_rtx_LABEL_REF (VOIDmode, label), pc_rtx);
- tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
- JUMP_LABEL (tmp) = label;
-
- return label;
-}
-
-/* Expand a mask generating SSE comparison instruction comparing OP0 with OP1
- using comparison code CODE. Operands are swapped for the comparison if
- SWAP_OPERANDS is true. Returns a rtx for the generated mask. */
-static rtx
-ix86_expand_sse_compare_mask (enum rtx_code code, rtx op0, rtx op1,
- bool swap_operands)
-{
- rtx (*insn)(rtx, rtx, rtx, rtx);
- enum machine_mode mode = GET_MODE (op0);
- rtx mask = gen_reg_rtx (mode);
-
- if (swap_operands)
- {
- rtx tmp = op0;
- op0 = op1;
- op1 = tmp;
- }
-
- insn = mode == DFmode ? gen_setcc_df_sse : gen_setcc_sf_sse;
-
- emit_insn (insn (mask, op0, op1,
- gen_rtx_fmt_ee (code, mode, op0, op1)));
- return mask;
-}
-
-/* Generate and return a rtx of mode MODE for 2**n where n is the number
- of bits of the mantissa of MODE, which must be one of DFmode or SFmode. */
-static rtx
-ix86_gen_TWO52 (enum machine_mode mode)
-{
- REAL_VALUE_TYPE TWO52r;
- rtx TWO52;
-
- real_ldexp (&TWO52r, &dconst1, mode == DFmode ? 52 : 23);
- TWO52 = const_double_from_real_value (TWO52r, mode);
- TWO52 = force_reg (mode, TWO52);
-
- return TWO52;
-}
-
-/* Expand SSE sequence for computing lround from OP1 storing
- into OP0. */
-void
-ix86_expand_lround (rtx op0, rtx op1)
-{
- /* C code for the stuff we're doing below:
- tmp = op1 + copysign (nextafter (0.5, 0.0), op1)
- return (long)tmp;
- */
- enum machine_mode mode = GET_MODE (op1);
- const struct real_format *fmt;
- REAL_VALUE_TYPE pred_half, half_minus_pred_half;
- rtx adj;
-
- /* load nextafter (0.5, 0.0) */
- fmt = REAL_MODE_FORMAT (mode);
- real_2expN (&half_minus_pred_half, -(fmt->p) - 1, mode);
- REAL_ARITHMETIC (pred_half, MINUS_EXPR, dconsthalf, half_minus_pred_half);
-
- /* adj = copysign (0.5, op1) */
- adj = force_reg (mode, const_double_from_real_value (pred_half, mode));
- ix86_sse_copysign_to_positive (adj, adj, force_reg (mode, op1), NULL_RTX);
-
- /* adj = op1 + adj */
- adj = expand_simple_binop (mode, PLUS, adj, op1, NULL_RTX, 0, OPTAB_DIRECT);
-
- /* op0 = (imode)adj */
- expand_fix (op0, adj, 0);
-}
-
-/* Expand SSE2 sequence for computing lround from OPERAND1 storing
- into OPERAND0. */
-void
-ix86_expand_lfloorceil (rtx op0, rtx op1, bool do_floor)
-{
- /* C code for the stuff we're doing below (for do_floor):
- xi = (long)op1;
- xi -= (double)xi > op1 ? 1 : 0;
- return xi;
- */
- enum machine_mode fmode = GET_MODE (op1);
- enum machine_mode imode = GET_MODE (op0);
- rtx ireg, freg, label, tmp;
-
- /* reg = (long)op1 */
- ireg = gen_reg_rtx (imode);
- expand_fix (ireg, op1, 0);
-
- /* freg = (double)reg */
- freg = gen_reg_rtx (fmode);
- expand_float (freg, ireg, 0);
-
- /* ireg = (freg > op1) ? ireg - 1 : ireg */
- label = ix86_expand_sse_compare_and_jump (UNLE,
- freg, op1, !do_floor);
- tmp = expand_simple_binop (imode, do_floor ? MINUS : PLUS,
- ireg, const1_rtx, NULL_RTX, 0, OPTAB_DIRECT);
- emit_move_insn (ireg, tmp);
-
- emit_label (label);
- LABEL_NUSES (label) = 1;
-
- emit_move_insn (op0, ireg);
-}
-
-/* Expand rint (IEEE round to nearest) rounding OPERAND1 and storing the
- result in OPERAND0. */
-void
-ix86_expand_rint (rtx operand0, rtx operand1)
-{
- /* C code for the stuff we're doing below:
- xa = fabs (operand1);
- if (!isless (xa, 2**52))
- return operand1;
- xa = xa + 2**52 - 2**52;
- return copysign (xa, operand1);
- */
- enum machine_mode mode = GET_MODE (operand0);
- rtx res, xa, label, TWO52, mask;
-
- res = gen_reg_rtx (mode);
- emit_move_insn (res, operand1);
-
- /* xa = abs (operand1) */
- xa = ix86_expand_sse_fabs (res, &mask);
-
- /* if (!isless (xa, TWO52)) goto label; */
- TWO52 = ix86_gen_TWO52 (mode);
- label = ix86_expand_sse_compare_and_jump (UNLE, TWO52, xa, false);
-
- xa = expand_simple_binop (mode, PLUS, xa, TWO52, NULL_RTX, 0, OPTAB_DIRECT);
- xa = expand_simple_binop (mode, MINUS, xa, TWO52, xa, 0, OPTAB_DIRECT);
-
- ix86_sse_copysign_to_positive (res, xa, res, mask);
-
- emit_label (label);
- LABEL_NUSES (label) = 1;
-
- emit_move_insn (operand0, res);
-}
-
-/* Expand SSE2 sequence for computing floor or ceil from OPERAND1 storing
- into OPERAND0. */
-void
-ix86_expand_floorceildf_32 (rtx operand0, rtx operand1, bool do_floor)
-{
- /* C code for the stuff we expand below.
- double xa = fabs (x), x2;
- if (!isless (xa, TWO52))
- return x;
- xa = xa + TWO52 - TWO52;
- x2 = copysign (xa, x);
- Compensate. Floor:
- if (x2 > x)
- x2 -= 1;
- Compensate. Ceil:
- if (x2 < x)
- x2 -= -1;
- return x2;
- */
- enum machine_mode mode = GET_MODE (operand0);
- rtx xa, TWO52, tmp, label, one, res, mask;
-
- TWO52 = ix86_gen_TWO52 (mode);
-
- /* Temporary for holding the result, initialized to the input
- operand to ease control flow. */
- res = gen_reg_rtx (mode);
- emit_move_insn (res, operand1);
-
- /* xa = abs (operand1) */
- xa = ix86_expand_sse_fabs (res, &mask);
-
- /* if (!isless (xa, TWO52)) goto label; */
- label = ix86_expand_sse_compare_and_jump (UNLE, TWO52, xa, false);
-
- /* xa = xa + TWO52 - TWO52; */
- xa = expand_simple_binop (mode, PLUS, xa, TWO52, NULL_RTX, 0, OPTAB_DIRECT);
- xa = expand_simple_binop (mode, MINUS, xa, TWO52, xa, 0, OPTAB_DIRECT);
-
- /* xa = copysign (xa, operand1) */
- ix86_sse_copysign_to_positive (xa, xa, res, mask);
-
- /* generate 1.0 or -1.0 */
- one = force_reg (mode,
- const_double_from_real_value (do_floor
- ? dconst1 : dconstm1, mode));
-
- /* Compensate: xa = xa - (xa > operand1 ? 1 : 0) */
- tmp = ix86_expand_sse_compare_mask (UNGT, xa, res, !do_floor);
- emit_insn (gen_rtx_SET (VOIDmode, tmp,
- gen_rtx_AND (mode, one, tmp)));
- /* We always need to subtract here to preserve signed zero. */
- tmp = expand_simple_binop (mode, MINUS,
- xa, tmp, NULL_RTX, 0, OPTAB_DIRECT);
- emit_move_insn (res, tmp);
-
- emit_label (label);
- LABEL_NUSES (label) = 1;
-
- emit_move_insn (operand0, res);
-}
-
-/* Expand SSE2 sequence for computing floor or ceil from OPERAND1 storing
- into OPERAND0. */
-void
-ix86_expand_floorceil (rtx operand0, rtx operand1, bool do_floor)
-{
- /* C code for the stuff we expand below.
- double xa = fabs (x), x2;
- if (!isless (xa, TWO52))
- return x;
- x2 = (double)(long)x;
- Compensate. Floor:
- if (x2 > x)
- x2 -= 1;
- Compensate. Ceil:
- if (x2 < x)
- x2 += 1;
- if (HONOR_SIGNED_ZEROS (mode))
- return copysign (x2, x);
- return x2;
- */
- enum machine_mode mode = GET_MODE (operand0);
- rtx xa, xi, TWO52, tmp, label, one, res, mask;
-
- TWO52 = ix86_gen_TWO52 (mode);
-
- /* Temporary for holding the result, initialized to the input
- operand to ease control flow. */
- res = gen_reg_rtx (mode);
- emit_move_insn (res, operand1);
-
- /* xa = abs (operand1) */
- xa = ix86_expand_sse_fabs (res, &mask);
-
- /* if (!isless (xa, TWO52)) goto label; */
- label = ix86_expand_sse_compare_and_jump (UNLE, TWO52, xa, false);
-
- /* xa = (double)(long)x */
- xi = gen_reg_rtx (mode == DFmode ? DImode : SImode);
- expand_fix (xi, res, 0);
- expand_float (xa, xi, 0);
-
- /* generate 1.0 */
- one = force_reg (mode, const_double_from_real_value (dconst1, mode));
-
- /* Compensate: xa = xa - (xa > operand1 ? 1 : 0) */
- tmp = ix86_expand_sse_compare_mask (UNGT, xa, res, !do_floor);
- emit_insn (gen_rtx_SET (VOIDmode, tmp,
- gen_rtx_AND (mode, one, tmp)));
- tmp = expand_simple_binop (mode, do_floor ? MINUS : PLUS,
- xa, tmp, NULL_RTX, 0, OPTAB_DIRECT);
- emit_move_insn (res, tmp);
-
- if (HONOR_SIGNED_ZEROS (mode))
- ix86_sse_copysign_to_positive (res, res, force_reg (mode, operand1), mask);
-
- emit_label (label);
- LABEL_NUSES (label) = 1;
-
- emit_move_insn (operand0, res);
-}
-
-/* Expand SSE sequence for computing round from OPERAND1 storing
- into OPERAND0. Sequence that works without relying on DImode truncation
- via cvttsd2siq that is only available on 64bit targets. */
-void
-ix86_expand_rounddf_32 (rtx operand0, rtx operand1)
-{
- /* C code for the stuff we expand below.
- double xa = fabs (x), xa2, x2;
- if (!isless (xa, TWO52))
- return x;
- Using the absolute value and copying back sign makes
- -0.0 -> -0.0 correct.
- xa2 = xa + TWO52 - TWO52;
- Compensate.
- dxa = xa2 - xa;
- if (dxa <= -0.5)
- xa2 += 1;
- else if (dxa > 0.5)
- xa2 -= 1;
- x2 = copysign (xa2, x);
- return x2;
- */
- enum machine_mode mode = GET_MODE (operand0);
- rtx xa, xa2, dxa, TWO52, tmp, label, half, mhalf, one, res, mask;
-
- TWO52 = ix86_gen_TWO52 (mode);
-
- /* Temporary for holding the result, initialized to the input
- operand to ease control flow. */
- res = gen_reg_rtx (mode);
- emit_move_insn (res, operand1);
-
- /* xa = abs (operand1) */
- xa = ix86_expand_sse_fabs (res, &mask);
-
- /* if (!isless (xa, TWO52)) goto label; */
- label = ix86_expand_sse_compare_and_jump (UNLE, TWO52, xa, false);
-
- /* xa2 = xa + TWO52 - TWO52; */
- xa2 = expand_simple_binop (mode, PLUS, xa, TWO52, NULL_RTX, 0, OPTAB_DIRECT);
- xa2 = expand_simple_binop (mode, MINUS, xa2, TWO52, xa2, 0, OPTAB_DIRECT);
-
- /* dxa = xa2 - xa; */
- dxa = expand_simple_binop (mode, MINUS, xa2, xa, NULL_RTX, 0, OPTAB_DIRECT);
-
- /* generate 0.5, 1.0 and -0.5 */
- half = force_reg (mode, const_double_from_real_value (dconsthalf, mode));
- one = expand_simple_binop (mode, PLUS, half, half, NULL_RTX, 0, OPTAB_DIRECT);
- mhalf = expand_simple_binop (mode, MINUS, half, one, NULL_RTX,
- 0, OPTAB_DIRECT);
-
- /* Compensate. */
- tmp = gen_reg_rtx (mode);
- /* xa2 = xa2 - (dxa > 0.5 ? 1 : 0) */
- tmp = ix86_expand_sse_compare_mask (UNGT, dxa, half, false);
- emit_insn (gen_rtx_SET (VOIDmode, tmp,
- gen_rtx_AND (mode, one, tmp)));
- xa2 = expand_simple_binop (mode, MINUS, xa2, tmp, NULL_RTX, 0, OPTAB_DIRECT);
- /* xa2 = xa2 + (dxa <= -0.5 ? 1 : 0) */
- tmp = ix86_expand_sse_compare_mask (UNGE, mhalf, dxa, false);
- emit_insn (gen_rtx_SET (VOIDmode, tmp,
- gen_rtx_AND (mode, one, tmp)));
- xa2 = expand_simple_binop (mode, PLUS, xa2, tmp, NULL_RTX, 0, OPTAB_DIRECT);
-
- /* res = copysign (xa2, operand1) */
- ix86_sse_copysign_to_positive (res, xa2, force_reg (mode, operand1), mask);
-
- emit_label (label);
- LABEL_NUSES (label) = 1;
-
- emit_move_insn (operand0, res);
-}
-
-/* Expand SSE sequence for computing trunc from OPERAND1 storing
- into OPERAND0. */
-void
-ix86_expand_trunc (rtx operand0, rtx operand1)
-{
- /* C code for SSE variant we expand below.
- double xa = fabs (x), x2;
- if (!isless (xa, TWO52))
- return x;
- x2 = (double)(long)x;
- if (HONOR_SIGNED_ZEROS (mode))
- return copysign (x2, x);
- return x2;
- */
- enum machine_mode mode = GET_MODE (operand0);
- rtx xa, xi, TWO52, label, res, mask;
-
- TWO52 = ix86_gen_TWO52 (mode);
-
- /* Temporary for holding the result, initialized to the input
- operand to ease control flow. */
- res = gen_reg_rtx (mode);
- emit_move_insn (res, operand1);
-
- /* xa = abs (operand1) */
- xa = ix86_expand_sse_fabs (res, &mask);
-
- /* if (!isless (xa, TWO52)) goto label; */
- label = ix86_expand_sse_compare_and_jump (UNLE, TWO52, xa, false);
-
- /* x = (double)(long)x */
- xi = gen_reg_rtx (mode == DFmode ? DImode : SImode);
- expand_fix (xi, res, 0);
- expand_float (res, xi, 0);
-
- if (HONOR_SIGNED_ZEROS (mode))
- ix86_sse_copysign_to_positive (res, res, force_reg (mode, operand1), mask);
-
- emit_label (label);
- LABEL_NUSES (label) = 1;
-
- emit_move_insn (operand0, res);
-}
-
-/* Expand SSE sequence for computing trunc from OPERAND1 storing
- into OPERAND0. */
-void
-ix86_expand_truncdf_32 (rtx operand0, rtx operand1)
-{
- enum machine_mode mode = GET_MODE (operand0);
- rtx xa, mask, TWO52, label, one, res, smask, tmp;
-
- /* C code for SSE variant we expand below.
- double xa = fabs (x), x2;
- if (!isless (xa, TWO52))
- return x;
- xa2 = xa + TWO52 - TWO52;
- Compensate:
- if (xa2 > xa)
- xa2 -= 1.0;
- x2 = copysign (xa2, x);
- return x2;
- */
-
- TWO52 = ix86_gen_TWO52 (mode);
-
- /* Temporary for holding the result, initialized to the input
- operand to ease control flow. */
- res = gen_reg_rtx (mode);
- emit_move_insn (res, operand1);
-
- /* xa = abs (operand1) */
- xa = ix86_expand_sse_fabs (res, &smask);
-
- /* if (!isless (xa, TWO52)) goto label; */
- label = ix86_expand_sse_compare_and_jump (UNLE, TWO52, xa, false);
-
- /* res = xa + TWO52 - TWO52; */
- tmp = expand_simple_binop (mode, PLUS, xa, TWO52, NULL_RTX, 0, OPTAB_DIRECT);
- tmp = expand_simple_binop (mode, MINUS, tmp, TWO52, tmp, 0, OPTAB_DIRECT);
- emit_move_insn (res, tmp);
-
- /* generate 1.0 */
- one = force_reg (mode, const_double_from_real_value (dconst1, mode));
-
- /* Compensate: res = xa2 - (res > xa ? 1 : 0) */
- mask = ix86_expand_sse_compare_mask (UNGT, res, xa, false);
- emit_insn (gen_rtx_SET (VOIDmode, mask,
- gen_rtx_AND (mode, mask, one)));
- tmp = expand_simple_binop (mode, MINUS,
- res, mask, NULL_RTX, 0, OPTAB_DIRECT);
- emit_move_insn (res, tmp);
-
- /* res = copysign (res, operand1) */
- ix86_sse_copysign_to_positive (res, res, force_reg (mode, operand1), smask);
-
- emit_label (label);
- LABEL_NUSES (label) = 1;
-
- emit_move_insn (operand0, res);
-}
-
-/* Expand SSE sequence for computing round from OPERAND1 storing
- into OPERAND0. */
-void
-ix86_expand_round (rtx operand0, rtx operand1)
-{
- /* C code for the stuff we're doing below:
- double xa = fabs (x);
- if (!isless (xa, TWO52))
- return x;
- xa = (double)(long)(xa + nextafter (0.5, 0.0));
- return copysign (xa, x);
- */
- enum machine_mode mode = GET_MODE (operand0);
- rtx res, TWO52, xa, label, xi, half, mask;
- const struct real_format *fmt;
- REAL_VALUE_TYPE pred_half, half_minus_pred_half;
-
- /* Temporary for holding the result, initialized to the input
- operand to ease control flow. */
- res = gen_reg_rtx (mode);
- emit_move_insn (res, operand1);
-
- TWO52 = ix86_gen_TWO52 (mode);
- xa = ix86_expand_sse_fabs (res, &mask);
- label = ix86_expand_sse_compare_and_jump (UNLE, TWO52, xa, false);
-
- /* load nextafter (0.5, 0.0) */
- fmt = REAL_MODE_FORMAT (mode);
- real_2expN (&half_minus_pred_half, -(fmt->p) - 1, mode);
- REAL_ARITHMETIC (pred_half, MINUS_EXPR, dconsthalf, half_minus_pred_half);
-
- /* xa = xa + 0.5 */
- half = force_reg (mode, const_double_from_real_value (pred_half, mode));
- xa = expand_simple_binop (mode, PLUS, xa, half, NULL_RTX, 0, OPTAB_DIRECT);
-
- /* xa = (double)(int64_t)xa */
- xi = gen_reg_rtx (mode == DFmode ? DImode : SImode);
- expand_fix (xi, xa, 0);
- expand_float (xa, xi, 0);
-
- /* res = copysign (xa, operand1) */
- ix86_sse_copysign_to_positive (res, xa, force_reg (mode, operand1), mask);
-
- emit_label (label);
- LABEL_NUSES (label) = 1;
-
- emit_move_insn (operand0, res);
-}
-
-/* Expand SSE sequence for computing round
- from OP1 storing into OP0 using sse4 round insn. */
-void
-ix86_expand_round_sse4 (rtx op0, rtx op1)
-{
- enum machine_mode mode = GET_MODE (op0);
- rtx e1, e2, res, half;
- const struct real_format *fmt;
- REAL_VALUE_TYPE pred_half, half_minus_pred_half;
- rtx (*gen_copysign) (rtx, rtx, rtx);
- rtx (*gen_round) (rtx, rtx, rtx);
-
- switch (mode)
- {
- case SFmode:
- gen_copysign = gen_copysignsf3;
- gen_round = gen_sse4_1_roundsf2;
- break;
- case DFmode:
- gen_copysign = gen_copysigndf3;
- gen_round = gen_sse4_1_rounddf2;
- break;
- default:
- gcc_unreachable ();
- }
-
- /* round (a) = trunc (a + copysign (0.5, a)) */
-
- /* load nextafter (0.5, 0.0) */
- fmt = REAL_MODE_FORMAT (mode);
- real_2expN (&half_minus_pred_half, -(fmt->p) - 1, mode);
- REAL_ARITHMETIC (pred_half, MINUS_EXPR, dconsthalf, half_minus_pred_half);
- half = const_double_from_real_value (pred_half, mode);
-
- /* e1 = copysign (0.5, op1) */
- e1 = gen_reg_rtx (mode);
- emit_insn (gen_copysign (e1, half, op1));
-
- /* e2 = op1 + e1 */
- e2 = expand_simple_binop (mode, PLUS, op1, e1, NULL_RTX, 0, OPTAB_DIRECT);
-
- /* res = trunc (e2) */
- res = gen_reg_rtx (mode);
- emit_insn (gen_round (res, e2, GEN_INT (ROUND_TRUNC)));
-
- emit_move_insn (op0, res);
-}
-
-
-/* Table of valid machine attributes. */
-static const struct attribute_spec ix86_attribute_table[] =
-{
- /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
- affects_type_identity } */
- /* Stdcall attribute says callee is responsible for popping arguments
- if they are not variable. */
- { "stdcall", 0, 0, false, true, true, ix86_handle_cconv_attribute,
- true },
- /* Fastcall attribute says callee is responsible for popping arguments
- if they are not variable. */
- { "fastcall", 0, 0, false, true, true, ix86_handle_cconv_attribute,
- true },
- /* Thiscall attribute says callee is responsible for popping arguments
- if they are not variable. */
- { "thiscall", 0, 0, false, true, true, ix86_handle_cconv_attribute,
- true },
- /* Cdecl attribute says the callee is a normal C declaration */
- { "cdecl", 0, 0, false, true, true, ix86_handle_cconv_attribute,
- true },
- /* Regparm attribute specifies how many integer arguments are to be
- passed in registers. */
- { "regparm", 1, 1, false, true, true, ix86_handle_cconv_attribute,
- true },
- /* Sseregparm attribute says we are using x86_64 calling conventions
- for FP arguments. */
- { "sseregparm", 0, 0, false, true, true, ix86_handle_cconv_attribute,
- true },
- /* The transactional memory builtins are implicitly regparm or fastcall
- depending on the ABI. Override the generic do-nothing attribute that
- these builtins were declared with. */
- { "*tm regparm", 0, 0, false, true, true, ix86_handle_tm_regparm_attribute,
- true },
- /* force_align_arg_pointer says this function realigns the stack at entry. */
- { (const char *)&ix86_force_align_arg_pointer_string, 0, 0,
- false, true, true, ix86_handle_cconv_attribute, false },
-#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
- { "dllimport", 0, 0, false, false, false, handle_dll_attribute, false },
- { "dllexport", 0, 0, false, false, false, handle_dll_attribute, false },
- { "shared", 0, 0, true, false, false, ix86_handle_shared_attribute,
- false },
-#endif
- { "ms_struct", 0, 0, false, false, false, ix86_handle_struct_attribute,
- false },
- { "gcc_struct", 0, 0, false, false, false, ix86_handle_struct_attribute,
- false },
-#ifdef SUBTARGET_ATTRIBUTE_TABLE
- SUBTARGET_ATTRIBUTE_TABLE,
-#endif
- /* ms_abi and sysv_abi calling convention function attributes. */
- { "ms_abi", 0, 0, false, true, true, ix86_handle_abi_attribute, true },
- { "sysv_abi", 0, 0, false, true, true, ix86_handle_abi_attribute, true },
- { "ms_hook_prologue", 0, 0, true, false, false, ix86_handle_fndecl_attribute,
- false },
- { "callee_pop_aggregate_return", 1, 1, false, true, true,
- ix86_handle_callee_pop_aggregate_return, true },
- /* End element. */
- { NULL, 0, 0, false, false, false, NULL, false }
-};
-
-/* Implement targetm.vectorize.builtin_vectorization_cost. */
-static int
-ix86_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
- tree vectype,
- int misalign ATTRIBUTE_UNUSED)
-{
- unsigned elements;
-
- switch (type_of_cost)
- {
- case scalar_stmt:
- return ix86_cost->scalar_stmt_cost;
-
- case scalar_load:
- return ix86_cost->scalar_load_cost;
-
- case scalar_store:
- return ix86_cost->scalar_store_cost;
-
- case vector_stmt:
- return ix86_cost->vec_stmt_cost;
-
- case vector_load:
- return ix86_cost->vec_align_load_cost;
-
- case vector_store:
- return ix86_cost->vec_store_cost;
-
- case vec_to_scalar:
- return ix86_cost->vec_to_scalar_cost;
-
- case scalar_to_vec:
- return ix86_cost->scalar_to_vec_cost;
-
- case unaligned_load:
- case unaligned_store:
- return ix86_cost->vec_unalign_load_cost;
-
- case cond_branch_taken:
- return ix86_cost->cond_taken_branch_cost;
-
- case cond_branch_not_taken:
- return ix86_cost->cond_not_taken_branch_cost;
-
- case vec_perm:
- case vec_promote_demote:
- return ix86_cost->vec_stmt_cost;
-
- case vec_construct:
- elements = TYPE_VECTOR_SUBPARTS (vectype);
- return elements / 2 + 1;
-
- default:
- gcc_unreachable ();
- }
-}
-
-/* A cached (set (nil) (vselect (vconcat (nil) (nil)) (parallel [])))
- insn, so that expand_vselect{,_vconcat} doesn't have to create a fresh
- insn every time. */
-
-static GTY(()) rtx vselect_insn;
-
-/* Initialize vselect_insn. */
-
-static void
-init_vselect_insn (void)
-{
- unsigned i;
- rtx x;
-
- x = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (MAX_VECT_LEN));
- for (i = 0; i < MAX_VECT_LEN; ++i)
- XVECEXP (x, 0, i) = const0_rtx;
- x = gen_rtx_VEC_SELECT (V2DFmode, gen_rtx_VEC_CONCAT (V4DFmode, const0_rtx,
- const0_rtx), x);
- x = gen_rtx_SET (VOIDmode, const0_rtx, x);
- start_sequence ();
- vselect_insn = emit_insn (x);
- end_sequence ();
-}
-
-/* Construct (set target (vec_select op0 (parallel perm))) and
- return true if that's a valid instruction in the active ISA. */
-
-static bool
-expand_vselect (rtx target, rtx op0, const unsigned char *perm,
- unsigned nelt, bool testing_p)
-{
- unsigned int i;
- rtx x, save_vconcat;
- int icode;
-
- if (vselect_insn == NULL_RTX)
- init_vselect_insn ();
-
- x = XEXP (SET_SRC (PATTERN (vselect_insn)), 1);
- PUT_NUM_ELEM (XVEC (x, 0), nelt);
- for (i = 0; i < nelt; ++i)
- XVECEXP (x, 0, i) = GEN_INT (perm[i]);
- save_vconcat = XEXP (SET_SRC (PATTERN (vselect_insn)), 0);
- XEXP (SET_SRC (PATTERN (vselect_insn)), 0) = op0;
- PUT_MODE (SET_SRC (PATTERN (vselect_insn)), GET_MODE (target));
- SET_DEST (PATTERN (vselect_insn)) = target;
- icode = recog_memoized (vselect_insn);
-
- if (icode >= 0 && !testing_p)
- emit_insn (copy_rtx (PATTERN (vselect_insn)));
-
- SET_DEST (PATTERN (vselect_insn)) = const0_rtx;
- XEXP (SET_SRC (PATTERN (vselect_insn)), 0) = save_vconcat;
- INSN_CODE (vselect_insn) = -1;
-
- return icode >= 0;
-}
-
-/* Similar, but generate a vec_concat from op0 and op1 as well. */
-
-static bool
-expand_vselect_vconcat (rtx target, rtx op0, rtx op1,
- const unsigned char *perm, unsigned nelt,
- bool testing_p)
-{
- enum machine_mode v2mode;
- rtx x;
- bool ok;
-
- if (vselect_insn == NULL_RTX)
- init_vselect_insn ();
-
- v2mode = GET_MODE_2XWIDER_MODE (GET_MODE (op0));
- x = XEXP (SET_SRC (PATTERN (vselect_insn)), 0);
- PUT_MODE (x, v2mode);
- XEXP (x, 0) = op0;
- XEXP (x, 1) = op1;
- ok = expand_vselect (target, x, perm, nelt, testing_p);
- XEXP (x, 0) = const0_rtx;
- XEXP (x, 1) = const0_rtx;
- return ok;
-}
-
-/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to implement D
- in terms of blendp[sd] / pblendw / pblendvb / vpblendd. */
-
-static bool
-expand_vec_perm_blend (struct expand_vec_perm_d *d)
-{
- enum machine_mode vmode = d->vmode;
- unsigned i, mask, nelt = d->nelt;
- rtx target, op0, op1, x;
- rtx rperm[32], vperm;
-
- if (d->one_operand_p)
- return false;
- if (TARGET_AVX2 && GET_MODE_SIZE (vmode) == 32)
- ;
- else if (TARGET_AVX && (vmode == V4DFmode || vmode == V8SFmode))
- ;
- else if (TARGET_SSE4_1 && GET_MODE_SIZE (vmode) == 16)
- ;
- else
- return false;
-
- /* This is a blend, not a permute. Elements must stay in their
- respective lanes. */
- for (i = 0; i < nelt; ++i)
- {
- unsigned e = d->perm[i];
- if (!(e == i || e == i + nelt))
- return false;
- }
-
- if (d->testing_p)
- return true;
-
- /* ??? Without SSE4.1, we could implement this with and/andn/or. This
- decision should be extracted elsewhere, so that we only try that
- sequence once all budget==3 options have been tried. */
- target = d->target;
- op0 = d->op0;
- op1 = d->op1;
- mask = 0;
-
- switch (vmode)
- {
- case V4DFmode:
- case V8SFmode:
- case V2DFmode:
- case V4SFmode:
- case V8HImode:
- case V8SImode:
- for (i = 0; i < nelt; ++i)
- mask |= (d->perm[i] >= nelt) << i;
- break;
-
- case V2DImode:
- for (i = 0; i < 2; ++i)
- mask |= (d->perm[i] >= 2 ? 15 : 0) << (i * 4);
- vmode = V8HImode;
- goto do_subreg;
-
- case V4SImode:
- for (i = 0; i < 4; ++i)
- mask |= (d->perm[i] >= 4 ? 3 : 0) << (i * 2);
- vmode = V8HImode;
- goto do_subreg;
-
- case V16QImode:
- /* See if bytes move in pairs so we can use pblendw with
- an immediate argument, rather than pblendvb with a vector
- argument. */
- for (i = 0; i < 16; i += 2)
- if (d->perm[i] + 1 != d->perm[i + 1])
- {
- use_pblendvb:
- for (i = 0; i < nelt; ++i)
- rperm[i] = (d->perm[i] < nelt ? const0_rtx : constm1_rtx);
-
- finish_pblendvb:
- vperm = gen_rtx_CONST_VECTOR (vmode, gen_rtvec_v (nelt, rperm));
- vperm = force_reg (vmode, vperm);
-
- if (GET_MODE_SIZE (vmode) == 16)
- emit_insn (gen_sse4_1_pblendvb (target, op0, op1, vperm));
- else
- emit_insn (gen_avx2_pblendvb (target, op0, op1, vperm));
- return true;
- }
-
- for (i = 0; i < 8; ++i)
- mask |= (d->perm[i * 2] >= 16) << i;
- vmode = V8HImode;
- /* FALLTHRU */
-
- do_subreg:
- target = gen_lowpart (vmode, target);
- op0 = gen_lowpart (vmode, op0);
- op1 = gen_lowpart (vmode, op1);
- break;
-
- case V32QImode:
- /* See if bytes move in pairs. If not, vpblendvb must be used. */
- for (i = 0; i < 32; i += 2)
- if (d->perm[i] + 1 != d->perm[i + 1])
- goto use_pblendvb;
- /* See if bytes move in quadruplets. If yes, vpblendd
- with immediate can be used. */
- for (i = 0; i < 32; i += 4)
- if (d->perm[i] + 2 != d->perm[i + 2])
- break;
- if (i < 32)
- {
- /* See if bytes move the same in both lanes. If yes,
- vpblendw with immediate can be used. */
- for (i = 0; i < 16; i += 2)
- if (d->perm[i] + 16 != d->perm[i + 16])
- goto use_pblendvb;
-
- /* Use vpblendw. */
- for (i = 0; i < 16; ++i)
- mask |= (d->perm[i * 2] >= 32) << i;
- vmode = V16HImode;
- goto do_subreg;
- }
-
- /* Use vpblendd. */
- for (i = 0; i < 8; ++i)
- mask |= (d->perm[i * 4] >= 32) << i;
- vmode = V8SImode;
- goto do_subreg;
-
- case V16HImode:
- /* See if words move in pairs. If yes, vpblendd can be used. */
- for (i = 0; i < 16; i += 2)
- if (d->perm[i] + 1 != d->perm[i + 1])
- break;
- if (i < 16)
- {
- /* See if words move the same in both lanes. If not,
- vpblendvb must be used. */
- for (i = 0; i < 8; i++)
- if (d->perm[i] + 8 != d->perm[i + 8])
- {
- /* Use vpblendvb. */
- for (i = 0; i < 32; ++i)
- rperm[i] = (d->perm[i / 2] < 16 ? const0_rtx : constm1_rtx);
-
- vmode = V32QImode;
- nelt = 32;
- target = gen_lowpart (vmode, target);
- op0 = gen_lowpart (vmode, op0);
- op1 = gen_lowpart (vmode, op1);
- goto finish_pblendvb;
- }
-
- /* Use vpblendw. */
- for (i = 0; i < 16; ++i)
- mask |= (d->perm[i] >= 16) << i;
- break;
- }
-
- /* Use vpblendd. */
- for (i = 0; i < 8; ++i)
- mask |= (d->perm[i * 2] >= 16) << i;
- vmode = V8SImode;
- goto do_subreg;
-
- case V4DImode:
- /* Use vpblendd. */
- for (i = 0; i < 4; ++i)
- mask |= (d->perm[i] >= 4 ? 3 : 0) << (i * 2);
- vmode = V8SImode;
- goto do_subreg;
-
- default:
- gcc_unreachable ();
- }
-
- /* This matches five different patterns with the different modes. */
- x = gen_rtx_VEC_MERGE (vmode, op1, op0, GEN_INT (mask));
- x = gen_rtx_SET (VOIDmode, target, x);
- emit_insn (x);
-
- return true;
-}
-
-/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to implement D
- in terms of the variable form of vpermilps.
-
- Note that we will have already failed the immediate input vpermilps,
- which requires that the high and low part shuffle be identical; the
- variable form doesn't require that. */
-
-static bool
-expand_vec_perm_vpermil (struct expand_vec_perm_d *d)
-{
- rtx rperm[8], vperm;
- unsigned i;
-
- if (!TARGET_AVX || d->vmode != V8SFmode || !d->one_operand_p)
- return false;
-
- /* We can only permute within the 128-bit lane. */
- for (i = 0; i < 8; ++i)
- {
- unsigned e = d->perm[i];
- if (i < 4 ? e >= 4 : e < 4)
- return false;
- }
-
- if (d->testing_p)
- return true;
-
- for (i = 0; i < 8; ++i)
- {
- unsigned e = d->perm[i];
-
- /* Within each 128-bit lane, the elements of op0 are numbered
- from 0 and the elements of op1 are numbered from 4. */
- if (e >= 8 + 4)
- e -= 8;
- else if (e >= 4)
- e -= 4;
-
- rperm[i] = GEN_INT (e);
- }
-
- vperm = gen_rtx_CONST_VECTOR (V8SImode, gen_rtvec_v (8, rperm));
- vperm = force_reg (V8SImode, vperm);
- emit_insn (gen_avx_vpermilvarv8sf3 (d->target, d->op0, vperm));
-
- return true;
-}
-
-/* Return true if permutation D can be performed as VMODE permutation
- instead. */
-
-static bool
-valid_perm_using_mode_p (enum machine_mode vmode, struct expand_vec_perm_d *d)
-{
- unsigned int i, j, chunk;
-
- if (GET_MODE_CLASS (vmode) != MODE_VECTOR_INT
- || GET_MODE_CLASS (d->vmode) != MODE_VECTOR_INT
- || GET_MODE_SIZE (vmode) != GET_MODE_SIZE (d->vmode))
- return false;
-
- if (GET_MODE_NUNITS (vmode) >= d->nelt)
- return true;
-
- chunk = d->nelt / GET_MODE_NUNITS (vmode);
- for (i = 0; i < d->nelt; i += chunk)
- if (d->perm[i] & (chunk - 1))
- return false;
- else
- for (j = 1; j < chunk; ++j)
- if (d->perm[i] + j != d->perm[i + j])
- return false;
-
- return true;
-}
-
-/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to implement D
- in terms of pshufb, vpperm, vpermq, vpermd, vpermps or vperm2i128. */
-
-static bool
-expand_vec_perm_pshufb (struct expand_vec_perm_d *d)
-{
- unsigned i, nelt, eltsz, mask;
- unsigned char perm[32];
- enum machine_mode vmode = V16QImode;
- rtx rperm[32], vperm, target, op0, op1;
-
- nelt = d->nelt;
-
- if (!d->one_operand_p)
- {
- if (!TARGET_XOP || GET_MODE_SIZE (d->vmode) != 16)
- {
- if (TARGET_AVX2
- && valid_perm_using_mode_p (V2TImode, d))
- {
- if (d->testing_p)
- return true;
-
- /* Use vperm2i128 insn. The pattern uses
- V4DImode instead of V2TImode. */
- target = gen_lowpart (V4DImode, d->target);
- op0 = gen_lowpart (V4DImode, d->op0);
- op1 = gen_lowpart (V4DImode, d->op1);
- rperm[0]
- = GEN_INT (((d->perm[0] & (nelt / 2)) ? 1 : 0)
- || ((d->perm[nelt / 2] & (nelt / 2)) ? 2 : 0));
- emit_insn (gen_avx2_permv2ti (target, op0, op1, rperm[0]));
- return true;
- }
- return false;
- }
- }
- else
- {
- if (GET_MODE_SIZE (d->vmode) == 16)
- {
- if (!TARGET_SSSE3)
- return false;
- }
- else if (GET_MODE_SIZE (d->vmode) == 32)
- {
- if (!TARGET_AVX2)
- return false;
-
- /* V4DImode should be already handled through
- expand_vselect by vpermq instruction. */
- gcc_assert (d->vmode != V4DImode);
-
- vmode = V32QImode;
- if (d->vmode == V8SImode
- || d->vmode == V16HImode
- || d->vmode == V32QImode)
- {
- /* First see if vpermq can be used for
- V8SImode/V16HImode/V32QImode. */
- if (valid_perm_using_mode_p (V4DImode, d))
- {
- for (i = 0; i < 4; i++)
- perm[i] = (d->perm[i * nelt / 4] * 4 / nelt) & 3;
- if (d->testing_p)
- return true;
- return expand_vselect (gen_lowpart (V4DImode, d->target),
- gen_lowpart (V4DImode, d->op0),
- perm, 4, false);
- }
-
- /* Next see if vpermd can be used. */
- if (valid_perm_using_mode_p (V8SImode, d))
- vmode = V8SImode;
- }
- /* Or if vpermps can be used. */
- else if (d->vmode == V8SFmode)
- vmode = V8SImode;
-
- if (vmode == V32QImode)
- {
- /* vpshufb only works intra lanes, it is not
- possible to shuffle bytes in between the lanes. */
- for (i = 0; i < nelt; ++i)
- if ((d->perm[i] ^ i) & (nelt / 2))
- return false;
- }
- }
- else
- return false;
- }
-
- if (d->testing_p)
- return true;
-
- if (vmode == V8SImode)
- for (i = 0; i < 8; ++i)
- rperm[i] = GEN_INT ((d->perm[i * nelt / 8] * 8 / nelt) & 7);
- else
- {
- eltsz = GET_MODE_SIZE (GET_MODE_INNER (d->vmode));
- if (!d->one_operand_p)
- mask = 2 * nelt - 1;
- else if (vmode == V16QImode)
- mask = nelt - 1;
- else
- mask = nelt / 2 - 1;
-
- for (i = 0; i < nelt; ++i)
- {
- unsigned j, e = d->perm[i] & mask;
- for (j = 0; j < eltsz; ++j)
- rperm[i * eltsz + j] = GEN_INT (e * eltsz + j);
- }
- }
-
- vperm = gen_rtx_CONST_VECTOR (vmode,
- gen_rtvec_v (GET_MODE_NUNITS (vmode), rperm));
- vperm = force_reg (vmode, vperm);
-
- target = gen_lowpart (vmode, d->target);
- op0 = gen_lowpart (vmode, d->op0);
- if (d->one_operand_p)
- {
- if (vmode == V16QImode)
- emit_insn (gen_ssse3_pshufbv16qi3 (target, op0, vperm));
- else if (vmode == V32QImode)
- emit_insn (gen_avx2_pshufbv32qi3 (target, op0, vperm));
- else if (vmode == V8SFmode)
- emit_insn (gen_avx2_permvarv8sf (target, op0, vperm));
- else
- emit_insn (gen_avx2_permvarv8si (target, op0, vperm));
- }
- else
- {
- op1 = gen_lowpart (vmode, d->op1);
- emit_insn (gen_xop_pperm (target, op0, op1, vperm));
- }
-
- return true;
-}
-
-/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to instantiate D
- in a single instruction. */
-
-static bool
-expand_vec_perm_1 (struct expand_vec_perm_d *d)
-{
- unsigned i, nelt = d->nelt;
- unsigned char perm2[MAX_VECT_LEN];
-
- /* Check plain VEC_SELECT first, because AVX has instructions that could
- match both SEL and SEL+CONCAT, but the plain SEL will allow a memory
- input where SEL+CONCAT may not. */
- if (d->one_operand_p)
- {
- int mask = nelt - 1;
- bool identity_perm = true;
- bool broadcast_perm = true;
-
- for (i = 0; i < nelt; i++)
- {
- perm2[i] = d->perm[i] & mask;
- if (perm2[i] != i)
- identity_perm = false;
- if (perm2[i])
- broadcast_perm = false;
- }
-
- if (identity_perm)
- {
- if (!d->testing_p)
- emit_move_insn (d->target, d->op0);
- return true;
- }
- else if (broadcast_perm && TARGET_AVX2)
- {
- /* Use vpbroadcast{b,w,d}. */
- rtx (*gen) (rtx, rtx) = NULL;
- switch (d->vmode)
- {
- case V32QImode:
- gen = gen_avx2_pbroadcastv32qi_1;
- break;
- case V16HImode:
- gen = gen_avx2_pbroadcastv16hi_1;
- break;
- case V8SImode:
- gen = gen_avx2_pbroadcastv8si_1;
- break;
- case V16QImode:
- gen = gen_avx2_pbroadcastv16qi;
- break;
- case V8HImode:
- gen = gen_avx2_pbroadcastv8hi;
- break;
- case V8SFmode:
- gen = gen_avx2_vec_dupv8sf_1;
- break;
- /* For other modes prefer other shuffles this function creates. */
- default: break;
- }
- if (gen != NULL)
- {
- if (!d->testing_p)
- emit_insn (gen (d->target, d->op0));
- return true;
- }
- }
-
- if (expand_vselect (d->target, d->op0, perm2, nelt, d->testing_p))
- return true;
-
- /* There are plenty of patterns in sse.md that are written for
- SEL+CONCAT and are not replicated for a single op. Perhaps
- that should be changed, to avoid the nastiness here. */
-
- /* Recognize interleave style patterns, which means incrementing
- every other permutation operand. */
- for (i = 0; i < nelt; i += 2)
- {
- perm2[i] = d->perm[i] & mask;
- perm2[i + 1] = (d->perm[i + 1] & mask) + nelt;
- }
- if (expand_vselect_vconcat (d->target, d->op0, d->op0, perm2, nelt,
- d->testing_p))
- return true;
-
- /* Recognize shufps, which means adding {0, 0, nelt, nelt}. */
- if (nelt >= 4)
- {
- for (i = 0; i < nelt; i += 4)
- {
- perm2[i + 0] = d->perm[i + 0] & mask;
- perm2[i + 1] = d->perm[i + 1] & mask;
- perm2[i + 2] = (d->perm[i + 2] & mask) + nelt;
- perm2[i + 3] = (d->perm[i + 3] & mask) + nelt;
- }
-
- if (expand_vselect_vconcat (d->target, d->op0, d->op0, perm2, nelt,
- d->testing_p))
- return true;
- }
- }
-
- /* Finally, try the fully general two operand permute. */
- if (expand_vselect_vconcat (d->target, d->op0, d->op1, d->perm, nelt,
- d->testing_p))
- return true;
-
- /* Recognize interleave style patterns with reversed operands. */
- if (!d->one_operand_p)
- {
- for (i = 0; i < nelt; ++i)
- {
- unsigned e = d->perm[i];
- if (e >= nelt)
- e -= nelt;
- else
- e += nelt;
- perm2[i] = e;
- }
-
- if (expand_vselect_vconcat (d->target, d->op1, d->op0, perm2, nelt,
- d->testing_p))
- return true;
- }
-
- /* Try the SSE4.1 blend variable merge instructions. */
- if (expand_vec_perm_blend (d))
- return true;
-
- /* Try one of the AVX vpermil variable permutations. */
- if (expand_vec_perm_vpermil (d))
- return true;
-
- /* Try the SSSE3 pshufb or XOP vpperm or AVX2 vperm2i128,
- vpshufb, vpermd, vpermps or vpermq variable permutation. */
- if (expand_vec_perm_pshufb (d))
- return true;
-
- return false;
-}
-
-/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to implement D
- in terms of a pair of pshuflw + pshufhw instructions. */
-
-static bool
-expand_vec_perm_pshuflw_pshufhw (struct expand_vec_perm_d *d)
-{
- unsigned char perm2[MAX_VECT_LEN];
- unsigned i;
- bool ok;
-
- if (d->vmode != V8HImode || !d->one_operand_p)
- return false;
-
- /* The two permutations only operate in 64-bit lanes. */
- for (i = 0; i < 4; ++i)
- if (d->perm[i] >= 4)
- return false;
- for (i = 4; i < 8; ++i)
- if (d->perm[i] < 4)
- return false;
-
- if (d->testing_p)
- return true;
-
- /* Emit the pshuflw. */
- memcpy (perm2, d->perm, 4);
- for (i = 4; i < 8; ++i)
- perm2[i] = i;
- ok = expand_vselect (d->target, d->op0, perm2, 8, d->testing_p);
- gcc_assert (ok);
-
- /* Emit the pshufhw. */
- memcpy (perm2 + 4, d->perm + 4, 4);
- for (i = 0; i < 4; ++i)
- perm2[i] = i;
- ok = expand_vselect (d->target, d->target, perm2, 8, d->testing_p);
- gcc_assert (ok);
-
- return true;
-}
-
-/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to simplify
- the permutation using the SSSE3 palignr instruction. This succeeds
- when all of the elements in PERM fit within one vector and we merely
- need to shift them down so that a single vector permutation has a
- chance to succeed. */
-
-static bool
-expand_vec_perm_palignr (struct expand_vec_perm_d *d)
-{
- unsigned i, nelt = d->nelt;
- unsigned min, max;
- bool in_order, ok;
- rtx shift;
-
- /* Even with AVX, palignr only operates on 128-bit vectors. */
- if (!TARGET_SSSE3 || GET_MODE_SIZE (d->vmode) != 16)
- return false;
-
- min = nelt, max = 0;
- for (i = 0; i < nelt; ++i)
- {
- unsigned e = d->perm[i];
- if (e < min)
- min = e;
- if (e > max)
- max = e;
- }
- if (min == 0 || max - min >= nelt)
- return false;
-
- /* Given that we have SSSE3, we know we'll be able to implement the
- single operand permutation after the palignr with pshufb. */
- if (d->testing_p)
- return true;
-
- shift = GEN_INT (min * GET_MODE_BITSIZE (GET_MODE_INNER (d->vmode)));
- emit_insn (gen_ssse3_palignrti (gen_lowpart (TImode, d->target),
- gen_lowpart (TImode, d->op1),
- gen_lowpart (TImode, d->op0), shift));
-
- d->op0 = d->op1 = d->target;
- d->one_operand_p = true;
-
- in_order = true;
- for (i = 0; i < nelt; ++i)
- {
- unsigned e = d->perm[i] - min;
- if (e != i)
- in_order = false;
- d->perm[i] = e;
- }
-
- /* Test for the degenerate case where the alignment by itself
- produces the desired permutation. */
- if (in_order)
- return true;
-
- ok = expand_vec_perm_1 (d);
- gcc_assert (ok);
-
- return ok;
-}
-
-static bool expand_vec_perm_interleave3 (struct expand_vec_perm_d *d);
-
-/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to simplify
- a two vector permutation into a single vector permutation by using
- an interleave operation to merge the vectors. */
-
-static bool
-expand_vec_perm_interleave2 (struct expand_vec_perm_d *d)
-{
- struct expand_vec_perm_d dremap, dfinal;
- unsigned i, nelt = d->nelt, nelt2 = nelt / 2;
- unsigned HOST_WIDE_INT contents;
- unsigned char remap[2 * MAX_VECT_LEN];
- rtx seq;
- bool ok, same_halves = false;
-
- if (GET_MODE_SIZE (d->vmode) == 16)
- {
- if (d->one_operand_p)
- return false;
- }
- else if (GET_MODE_SIZE (d->vmode) == 32)
- {
- if (!TARGET_AVX)
- return false;
- /* For 32-byte modes allow even d->one_operand_p.
- The lack of cross-lane shuffling in some instructions
- might prevent a single insn shuffle. */
- dfinal = *d;
- dfinal.testing_p = true;
- /* If expand_vec_perm_interleave3 can expand this into
- a 3 insn sequence, give up and let it be expanded as
- 3 insn sequence. While that is one insn longer,
- it doesn't need a memory operand and in the common
- case that both interleave low and high permutations
- with the same operands are adjacent needs 4 insns
- for both after CSE. */
- if (expand_vec_perm_interleave3 (&dfinal))
- return false;
- }
- else
- return false;
-
- /* Examine from whence the elements come. */
- contents = 0;
- for (i = 0; i < nelt; ++i)
- contents |= ((unsigned HOST_WIDE_INT) 1) << d->perm[i];
-
- memset (remap, 0xff, sizeof (remap));
- dremap = *d;
-
- if (GET_MODE_SIZE (d->vmode) == 16)
- {
- unsigned HOST_WIDE_INT h1, h2, h3, h4;
-
- /* Split the two input vectors into 4 halves. */
- h1 = (((unsigned HOST_WIDE_INT) 1) << nelt2) - 1;
- h2 = h1 << nelt2;
- h3 = h2 << nelt2;
- h4 = h3 << nelt2;
-
- /* If the elements from the low halves use interleave low, and similarly
- for interleave high. If the elements are from mis-matched halves, we
- can use shufps for V4SF/V4SI or do a DImode shuffle. */
- if ((contents & (h1 | h3)) == contents)
- {
- /* punpckl* */
- for (i = 0; i < nelt2; ++i)
- {
- remap[i] = i * 2;
- remap[i + nelt] = i * 2 + 1;
- dremap.perm[i * 2] = i;
- dremap.perm[i * 2 + 1] = i + nelt;
- }
- if (!TARGET_SSE2 && d->vmode == V4SImode)
- dremap.vmode = V4SFmode;
- }
- else if ((contents & (h2 | h4)) == contents)
- {
- /* punpckh* */
- for (i = 0; i < nelt2; ++i)
- {
- remap[i + nelt2] = i * 2;
- remap[i + nelt + nelt2] = i * 2 + 1;
- dremap.perm[i * 2] = i + nelt2;
- dremap.perm[i * 2 + 1] = i + nelt + nelt2;
- }
- if (!TARGET_SSE2 && d->vmode == V4SImode)
- dremap.vmode = V4SFmode;
- }
- else if ((contents & (h1 | h4)) == contents)
- {
- /* shufps */
- for (i = 0; i < nelt2; ++i)
- {
- remap[i] = i;
- remap[i + nelt + nelt2] = i + nelt2;
- dremap.perm[i] = i;
- dremap.perm[i + nelt2] = i + nelt + nelt2;
- }
- if (nelt != 4)
- {
- /* shufpd */
- dremap.vmode = V2DImode;
- dremap.nelt = 2;
- dremap.perm[0] = 0;
- dremap.perm[1] = 3;
- }
- }
- else if ((contents & (h2 | h3)) == contents)
- {
- /* shufps */
- for (i = 0; i < nelt2; ++i)
- {
- remap[i + nelt2] = i;
- remap[i + nelt] = i + nelt2;
- dremap.perm[i] = i + nelt2;
- dremap.perm[i + nelt2] = i + nelt;
- }
- if (nelt != 4)
- {
- /* shufpd */
- dremap.vmode = V2DImode;
- dremap.nelt = 2;
- dremap.perm[0] = 1;
- dremap.perm[1] = 2;
- }
- }
- else
- return false;
- }
- else
- {
- unsigned int nelt4 = nelt / 4, nzcnt = 0;
- unsigned HOST_WIDE_INT q[8];
- unsigned int nonzero_halves[4];
-
- /* Split the two input vectors into 8 quarters. */
- q[0] = (((unsigned HOST_WIDE_INT) 1) << nelt4) - 1;
- for (i = 1; i < 8; ++i)
- q[i] = q[0] << (nelt4 * i);
- for (i = 0; i < 4; ++i)
- if (((q[2 * i] | q[2 * i + 1]) & contents) != 0)
- {
- nonzero_halves[nzcnt] = i;
- ++nzcnt;
- }
-
- if (nzcnt == 1)
- {
- gcc_assert (d->one_operand_p);
- nonzero_halves[1] = nonzero_halves[0];
- same_halves = true;
- }
- else if (d->one_operand_p)
- {
- gcc_assert (nonzero_halves[0] == 0);
- gcc_assert (nonzero_halves[1] == 1);
- }
-
- if (nzcnt <= 2)
- {
- if (d->perm[0] / nelt2 == nonzero_halves[1])
- {
- /* Attempt to increase the likelihood that dfinal
- shuffle will be intra-lane. */
- char tmph = nonzero_halves[0];
- nonzero_halves[0] = nonzero_halves[1];
- nonzero_halves[1] = tmph;
- }
-
- /* vperm2f128 or vperm2i128. */
- for (i = 0; i < nelt2; ++i)
- {
- remap[i + nonzero_halves[1] * nelt2] = i + nelt2;
- remap[i + nonzero_halves[0] * nelt2] = i;
- dremap.perm[i + nelt2] = i + nonzero_halves[1] * nelt2;
- dremap.perm[i] = i + nonzero_halves[0] * nelt2;
- }
-
- if (d->vmode != V8SFmode
- && d->vmode != V4DFmode
- && d->vmode != V8SImode)
- {
- dremap.vmode = V8SImode;
- dremap.nelt = 8;
- for (i = 0; i < 4; ++i)
- {
- dremap.perm[i] = i + nonzero_halves[0] * 4;
- dremap.perm[i + 4] = i + nonzero_halves[1] * 4;
- }
- }
- }
- else if (d->one_operand_p)
- return false;
- else if (TARGET_AVX2
- && (contents & (q[0] | q[2] | q[4] | q[6])) == contents)
- {
- /* vpunpckl* */
- for (i = 0; i < nelt4; ++i)
- {
- remap[i] = i * 2;
- remap[i + nelt] = i * 2 + 1;
- remap[i + nelt2] = i * 2 + nelt2;
- remap[i + nelt + nelt2] = i * 2 + nelt2 + 1;
- dremap.perm[i * 2] = i;
- dremap.perm[i * 2 + 1] = i + nelt;
- dremap.perm[i * 2 + nelt2] = i + nelt2;
- dremap.perm[i * 2 + nelt2 + 1] = i + nelt + nelt2;
- }
- }
- else if (TARGET_AVX2
- && (contents & (q[1] | q[3] | q[5] | q[7])) == contents)
- {
- /* vpunpckh* */
- for (i = 0; i < nelt4; ++i)
- {
- remap[i + nelt4] = i * 2;
- remap[i + nelt + nelt4] = i * 2 + 1;
- remap[i + nelt2 + nelt4] = i * 2 + nelt2;
- remap[i + nelt + nelt2 + nelt4] = i * 2 + nelt2 + 1;
- dremap.perm[i * 2] = i + nelt4;
- dremap.perm[i * 2 + 1] = i + nelt + nelt4;
- dremap.perm[i * 2 + nelt2] = i + nelt2 + nelt4;
- dremap.perm[i * 2 + nelt2 + 1] = i + nelt + nelt2 + nelt4;
- }
- }
- else
- return false;
- }
-
- /* Use the remapping array set up above to move the elements from their
- swizzled locations into their final destinations. */
- dfinal = *d;
- for (i = 0; i < nelt; ++i)
- {
- unsigned e = remap[d->perm[i]];
- gcc_assert (e < nelt);
- /* If same_halves is true, both halves of the remapped vector are the
- same. Avoid cross-lane accesses if possible. */
- if (same_halves && i >= nelt2)
- {
- gcc_assert (e < nelt2);
- dfinal.perm[i] = e + nelt2;
- }
- else
- dfinal.perm[i] = e;
- }
- dfinal.op0 = gen_reg_rtx (dfinal.vmode);
- dfinal.op1 = dfinal.op0;
- dfinal.one_operand_p = true;
- dremap.target = dfinal.op0;
-
- /* Test if the final remap can be done with a single insn. For V4SFmode or
- V4SImode this *will* succeed. For V8HImode or V16QImode it may not. */
- start_sequence ();
- ok = expand_vec_perm_1 (&dfinal);
- seq = get_insns ();
- end_sequence ();
-
- if (!ok)
- return false;
-
- if (d->testing_p)
- return true;
-
- if (dremap.vmode != dfinal.vmode)
- {
- dremap.target = gen_lowpart (dremap.vmode, dremap.target);
- dremap.op0 = gen_lowpart (dremap.vmode, dremap.op0);
- dremap.op1 = gen_lowpart (dremap.vmode, dremap.op1);
- }
-
- ok = expand_vec_perm_1 (&dremap);
- gcc_assert (ok);
-
- emit_insn (seq);
- return true;
-}
-
-/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to simplify
- a single vector cross-lane permutation into vpermq followed
- by any of the single insn permutations. */
-
-static bool
-expand_vec_perm_vpermq_perm_1 (struct expand_vec_perm_d *d)
-{
- struct expand_vec_perm_d dremap, dfinal;
- unsigned i, j, nelt = d->nelt, nelt2 = nelt / 2, nelt4 = nelt / 4;
- unsigned contents[2];
- bool ok;
-
- if (!(TARGET_AVX2
- && (d->vmode == V32QImode || d->vmode == V16HImode)
- && d->one_operand_p))
- return false;
-
- contents[0] = 0;
- contents[1] = 0;
- for (i = 0; i < nelt2; ++i)
- {
- contents[0] |= 1u << (d->perm[i] / nelt4);
- contents[1] |= 1u << (d->perm[i + nelt2] / nelt4);
- }
-
- for (i = 0; i < 2; ++i)
- {
- unsigned int cnt = 0;
- for (j = 0; j < 4; ++j)
- if ((contents[i] & (1u << j)) != 0 && ++cnt > 2)
- return false;
- }
-
- if (d->testing_p)
- return true;
-
- dremap = *d;
- dremap.vmode = V4DImode;
- dremap.nelt = 4;
- dremap.target = gen_reg_rtx (V4DImode);
- dremap.op0 = gen_lowpart (V4DImode, d->op0);
- dremap.op1 = dremap.op0;
- dremap.one_operand_p = true;
- for (i = 0; i < 2; ++i)
- {
- unsigned int cnt = 0;
- for (j = 0; j < 4; ++j)
- if ((contents[i] & (1u << j)) != 0)
- dremap.perm[2 * i + cnt++] = j;
- for (; cnt < 2; ++cnt)
- dremap.perm[2 * i + cnt] = 0;
- }
-
- dfinal = *d;
- dfinal.op0 = gen_lowpart (dfinal.vmode, dremap.target);
- dfinal.op1 = dfinal.op0;
- dfinal.one_operand_p = true;
- for (i = 0, j = 0; i < nelt; ++i)
- {
- if (i == nelt2)
- j = 2;
- dfinal.perm[i] = (d->perm[i] & (nelt4 - 1)) | (j ? nelt2 : 0);
- if ((d->perm[i] / nelt4) == dremap.perm[j])
- ;
- else if ((d->perm[i] / nelt4) == dremap.perm[j + 1])
- dfinal.perm[i] |= nelt4;
- else
- gcc_unreachable ();
- }
-
- ok = expand_vec_perm_1 (&dremap);
- gcc_assert (ok);
-
- ok = expand_vec_perm_1 (&dfinal);
- gcc_assert (ok);
-
- return true;
-}
-
-/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to expand
- a vector permutation using two instructions, vperm2f128 resp.
- vperm2i128 followed by any single in-lane permutation. */
-
-static bool
-expand_vec_perm_vperm2f128 (struct expand_vec_perm_d *d)
-{
- struct expand_vec_perm_d dfirst, dsecond;
- unsigned i, j, nelt = d->nelt, nelt2 = nelt / 2, perm;
- bool ok;
-
- if (!TARGET_AVX
- || GET_MODE_SIZE (d->vmode) != 32
- || (d->vmode != V8SFmode && d->vmode != V4DFmode && !TARGET_AVX2))
- return false;
-
- dsecond = *d;
- dsecond.one_operand_p = false;
- dsecond.testing_p = true;
-
- /* ((perm << 2)|perm) & 0x33 is the vperm2[fi]128
- immediate. For perm < 16 the second permutation uses
- d->op0 as first operand, for perm >= 16 it uses d->op1
- as first operand. The second operand is the result of
- vperm2[fi]128. */
- for (perm = 0; perm < 32; perm++)
- {
- /* Ignore permutations which do not move anything cross-lane. */
- if (perm < 16)
- {
- /* The second shuffle for e.g. V4DFmode has
- 0123 and ABCD operands.
- Ignore AB23, as 23 is already in the second lane
- of the first operand. */
- if ((perm & 0xc) == (1 << 2)) continue;
- /* And 01CD, as 01 is in the first lane of the first
- operand. */
- if ((perm & 3) == 0) continue;
- /* And 4567, as then the vperm2[fi]128 doesn't change
- anything on the original 4567 second operand. */
- if ((perm & 0xf) == ((3 << 2) | 2)) continue;
- }
- else
- {
- /* The second shuffle for e.g. V4DFmode has
- 4567 and ABCD operands.
- Ignore AB67, as 67 is already in the second lane
- of the first operand. */
- if ((perm & 0xc) == (3 << 2)) continue;
- /* And 45CD, as 45 is in the first lane of the first
- operand. */
- if ((perm & 3) == 2) continue;
- /* And 0123, as then the vperm2[fi]128 doesn't change
- anything on the original 0123 first operand. */
- if ((perm & 0xf) == (1 << 2)) continue;
- }
-
- for (i = 0; i < nelt; i++)
- {
- j = d->perm[i] / nelt2;
- if (j == ((perm >> (2 * (i >= nelt2))) & 3))
- dsecond.perm[i] = nelt + (i & nelt2) + (d->perm[i] & (nelt2 - 1));
- else if (j == (unsigned) (i >= nelt2) + 2 * (perm >= 16))
- dsecond.perm[i] = d->perm[i] & (nelt - 1);
- else
- break;
- }
-
- if (i == nelt)
- {
- start_sequence ();
- ok = expand_vec_perm_1 (&dsecond);
- end_sequence ();
- }
- else
- ok = false;
-
- if (ok)
- {
- if (d->testing_p)
- return true;
-
- /* Found a usable second shuffle. dfirst will be
- vperm2f128 on d->op0 and d->op1. */
- dsecond.testing_p = false;
- dfirst = *d;
- dfirst.target = gen_reg_rtx (d->vmode);
- for (i = 0; i < nelt; i++)
- dfirst.perm[i] = (i & (nelt2 - 1))
- + ((perm >> (2 * (i >= nelt2))) & 3) * nelt2;
-
- ok = expand_vec_perm_1 (&dfirst);
- gcc_assert (ok);
-
- /* And dsecond is some single insn shuffle, taking
- d->op0 and result of vperm2f128 (if perm < 16) or
- d->op1 and result of vperm2f128 (otherwise). */
- dsecond.op1 = dfirst.target;
- if (perm >= 16)
- dsecond.op0 = dfirst.op1;
-
- ok = expand_vec_perm_1 (&dsecond);
- gcc_assert (ok);
-
- return true;
- }
-
- /* For one operand, the only useful vperm2f128 permutation is 0x10. */
- if (d->one_operand_p)
- return false;
- }
-
- return false;
-}
-
-/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to simplify
- a two vector permutation using 2 intra-lane interleave insns
- and cross-lane shuffle for 32-byte vectors. */
-
-static bool
-expand_vec_perm_interleave3 (struct expand_vec_perm_d *d)
-{
- unsigned i, nelt;
- rtx (*gen) (rtx, rtx, rtx);
-
- if (d->one_operand_p)
- return false;
- if (TARGET_AVX2 && GET_MODE_SIZE (d->vmode) == 32)
- ;
- else if (TARGET_AVX && (d->vmode == V8SFmode || d->vmode == V4DFmode))
- ;
- else
- return false;
-
- nelt = d->nelt;
- if (d->perm[0] != 0 && d->perm[0] != nelt / 2)
- return false;
- for (i = 0; i < nelt; i += 2)
- if (d->perm[i] != d->perm[0] + i / 2
- || d->perm[i + 1] != d->perm[0] + i / 2 + nelt)
- return false;
-
- if (d->testing_p)
- return true;
-
- switch (d->vmode)
- {
- case V32QImode:
- if (d->perm[0])
- gen = gen_vec_interleave_highv32qi;
- else
- gen = gen_vec_interleave_lowv32qi;
- break;
- case V16HImode:
- if (d->perm[0])
- gen = gen_vec_interleave_highv16hi;
- else
- gen = gen_vec_interleave_lowv16hi;
- break;
- case V8SImode:
- if (d->perm[0])
- gen = gen_vec_interleave_highv8si;
- else
- gen = gen_vec_interleave_lowv8si;
- break;
- case V4DImode:
- if (d->perm[0])
- gen = gen_vec_interleave_highv4di;
- else
- gen = gen_vec_interleave_lowv4di;
- break;
- case V8SFmode:
- if (d->perm[0])
- gen = gen_vec_interleave_highv8sf;
- else
- gen = gen_vec_interleave_lowv8sf;
- break;
- case V4DFmode:
- if (d->perm[0])
- gen = gen_vec_interleave_highv4df;
- else
- gen = gen_vec_interleave_lowv4df;
- break;
- default:
- gcc_unreachable ();
- }
-
- emit_insn (gen (d->target, d->op0, d->op1));
- return true;
-}
-
-/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to implement
- a single vector permutation using a single intra-lane vector
- permutation, vperm2f128 swapping the lanes and vblend* insn blending
- the non-swapped and swapped vectors together. */
-
-static bool
-expand_vec_perm_vperm2f128_vblend (struct expand_vec_perm_d *d)
-{
- struct expand_vec_perm_d dfirst, dsecond;
- unsigned i, j, msk, nelt = d->nelt, nelt2 = nelt / 2;
- rtx seq;
- bool ok;
- rtx (*blend) (rtx, rtx, rtx, rtx) = NULL;
-
- if (!TARGET_AVX
- || TARGET_AVX2
- || (d->vmode != V8SFmode && d->vmode != V4DFmode)
- || !d->one_operand_p)
- return false;
-
- dfirst = *d;
- for (i = 0; i < nelt; i++)
- dfirst.perm[i] = 0xff;
- for (i = 0, msk = 0; i < nelt; i++)
- {
- j = (d->perm[i] & nelt2) ? i | nelt2 : i & ~nelt2;
- if (dfirst.perm[j] != 0xff && dfirst.perm[j] != d->perm[i])
- return false;
- dfirst.perm[j] = d->perm[i];
- if (j != i)
- msk |= (1 << i);
- }
- for (i = 0; i < nelt; i++)
- if (dfirst.perm[i] == 0xff)
- dfirst.perm[i] = i;
-
- if (!d->testing_p)
- dfirst.target = gen_reg_rtx (dfirst.vmode);
-
- start_sequence ();
- ok = expand_vec_perm_1 (&dfirst);
- seq = get_insns ();
- end_sequence ();
-
- if (!ok)
- return false;
-
- if (d->testing_p)
- return true;
-
- emit_insn (seq);
-
- dsecond = *d;
- dsecond.op0 = dfirst.target;
- dsecond.op1 = dfirst.target;
- dsecond.one_operand_p = true;
- dsecond.target = gen_reg_rtx (dsecond.vmode);
- for (i = 0; i < nelt; i++)
- dsecond.perm[i] = i ^ nelt2;
-
- ok = expand_vec_perm_1 (&dsecond);
- gcc_assert (ok);
-
- blend = d->vmode == V8SFmode ? gen_avx_blendps256 : gen_avx_blendpd256;
- emit_insn (blend (d->target, dfirst.target, dsecond.target, GEN_INT (msk)));
- return true;
-}
-
-/* A subroutine of ix86_expand_vec_perm_builtin_1. Implement a V4DF
- permutation using two vperm2f128, followed by a vshufpd insn blending
- the two vectors together. */
-
-static bool
-expand_vec_perm_2vperm2f128_vshuf (struct expand_vec_perm_d *d)
-{
- struct expand_vec_perm_d dfirst, dsecond, dthird;
- bool ok;
-
- if (!TARGET_AVX || (d->vmode != V4DFmode))
- return false;
-
- if (d->testing_p)
- return true;
-
- dfirst = *d;
- dsecond = *d;
- dthird = *d;
-
- dfirst.perm[0] = (d->perm[0] & ~1);
- dfirst.perm[1] = (d->perm[0] & ~1) + 1;
- dfirst.perm[2] = (d->perm[2] & ~1);
- dfirst.perm[3] = (d->perm[2] & ~1) + 1;
- dsecond.perm[0] = (d->perm[1] & ~1);
- dsecond.perm[1] = (d->perm[1] & ~1) + 1;
- dsecond.perm[2] = (d->perm[3] & ~1);
- dsecond.perm[3] = (d->perm[3] & ~1) + 1;
- dthird.perm[0] = (d->perm[0] % 2);
- dthird.perm[1] = (d->perm[1] % 2) + 4;
- dthird.perm[2] = (d->perm[2] % 2) + 2;
- dthird.perm[3] = (d->perm[3] % 2) + 6;
-
- dfirst.target = gen_reg_rtx (dfirst.vmode);
- dsecond.target = gen_reg_rtx (dsecond.vmode);
- dthird.op0 = dfirst.target;
- dthird.op1 = dsecond.target;
- dthird.one_operand_p = false;
-
- canonicalize_perm (&dfirst);
- canonicalize_perm (&dsecond);
-
- ok = expand_vec_perm_1 (&dfirst)
- && expand_vec_perm_1 (&dsecond)
- && expand_vec_perm_1 (&dthird);
-
- gcc_assert (ok);
-
- return true;
-}
-
-/* A subroutine of expand_vec_perm_even_odd_1. Implement the double-word
- permutation with two pshufb insns and an ior. We should have already
- failed all two instruction sequences. */
-
-static bool
-expand_vec_perm_pshufb2 (struct expand_vec_perm_d *d)
-{
- rtx rperm[2][16], vperm, l, h, op, m128;
- unsigned int i, nelt, eltsz;
-
- if (!TARGET_SSSE3 || GET_MODE_SIZE (d->vmode) != 16)
- return false;
- gcc_assert (!d->one_operand_p);
-
- nelt = d->nelt;
- eltsz = GET_MODE_SIZE (GET_MODE_INNER (d->vmode));
-
- /* Generate two permutation masks. If the required element is within
- the given vector it is shuffled into the proper lane. If the required
- element is in the other vector, force a zero into the lane by setting
- bit 7 in the permutation mask. */
- m128 = GEN_INT (-128);
- for (i = 0; i < nelt; ++i)
- {
- unsigned j, e = d->perm[i];
- unsigned which = (e >= nelt);
- if (e >= nelt)
- e -= nelt;
-
- for (j = 0; j < eltsz; ++j)
- {
- rperm[which][i*eltsz + j] = GEN_INT (e*eltsz + j);
- rperm[1-which][i*eltsz + j] = m128;
- }
- }
-
- vperm = gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, rperm[0]));
- vperm = force_reg (V16QImode, vperm);
-
- l = gen_reg_rtx (V16QImode);
- op = gen_lowpart (V16QImode, d->op0);
- emit_insn (gen_ssse3_pshufbv16qi3 (l, op, vperm));
-
- vperm = gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, rperm[1]));
- vperm = force_reg (V16QImode, vperm);
-
- h = gen_reg_rtx (V16QImode);
- op = gen_lowpart (V16QImode, d->op1);
- emit_insn (gen_ssse3_pshufbv16qi3 (h, op, vperm));
-
- op = gen_lowpart (V16QImode, d->target);
- emit_insn (gen_iorv16qi3 (op, l, h));
-
- return true;
-}
-
-/* Implement arbitrary permutation of one V32QImode and V16QImode operand
- with two vpshufb insns, vpermq and vpor. We should have already failed
- all two or three instruction sequences. */
-
-static bool
-expand_vec_perm_vpshufb2_vpermq (struct expand_vec_perm_d *d)
-{
- rtx rperm[2][32], vperm, l, h, hp, op, m128;
- unsigned int i, nelt, eltsz;
-
- if (!TARGET_AVX2
- || !d->one_operand_p
- || (d->vmode != V32QImode && d->vmode != V16HImode))
- return false;
-
- if (d->testing_p)
- return true;
-
- nelt = d->nelt;
- eltsz = GET_MODE_SIZE (GET_MODE_INNER (d->vmode));
-
- /* Generate two permutation masks. If the required element is within
- the same lane, it is shuffled in. If the required element from the
- other lane, force a zero by setting bit 7 in the permutation mask.
- In the other mask the mask has non-negative elements if element
- is requested from the other lane, but also moved to the other lane,
- so that the result of vpshufb can have the two V2TImode halves
- swapped. */
- m128 = GEN_INT (-128);
- for (i = 0; i < nelt; ++i)
- {
- unsigned j, e = d->perm[i] & (nelt / 2 - 1);
- unsigned which = ((d->perm[i] ^ i) & (nelt / 2)) * eltsz;
-
- for (j = 0; j < eltsz; ++j)
- {
- rperm[!!which][(i * eltsz + j) ^ which] = GEN_INT (e * eltsz + j);
- rperm[!which][(i * eltsz + j) ^ (which ^ 16)] = m128;
- }
- }
-
- vperm = gen_rtx_CONST_VECTOR (V32QImode, gen_rtvec_v (32, rperm[1]));
- vperm = force_reg (V32QImode, vperm);
-
- h = gen_reg_rtx (V32QImode);
- op = gen_lowpart (V32QImode, d->op0);
- emit_insn (gen_avx2_pshufbv32qi3 (h, op, vperm));
-
- /* Swap the 128-byte lanes of h into hp. */
- hp = gen_reg_rtx (V4DImode);
- op = gen_lowpart (V4DImode, h);
- emit_insn (gen_avx2_permv4di_1 (hp, op, const2_rtx, GEN_INT (3), const0_rtx,
- const1_rtx));
-
- vperm = gen_rtx_CONST_VECTOR (V32QImode, gen_rtvec_v (32, rperm[0]));
- vperm = force_reg (V32QImode, vperm);
-
- l = gen_reg_rtx (V32QImode);
- op = gen_lowpart (V32QImode, d->op0);
- emit_insn (gen_avx2_pshufbv32qi3 (l, op, vperm));
-
- op = gen_lowpart (V32QImode, d->target);
- emit_insn (gen_iorv32qi3 (op, l, gen_lowpart (V32QImode, hp)));
-
- return true;
-}
-
-/* A subroutine of expand_vec_perm_even_odd_1. Implement extract-even
- and extract-odd permutations of two V32QImode and V16QImode operand
- with two vpshufb insns, vpor and vpermq. We should have already
- failed all two or three instruction sequences. */
-
-static bool
-expand_vec_perm_vpshufb2_vpermq_even_odd (struct expand_vec_perm_d *d)
-{
- rtx rperm[2][32], vperm, l, h, ior, op, m128;
- unsigned int i, nelt, eltsz;
-
- if (!TARGET_AVX2
- || d->one_operand_p
- || (d->vmode != V32QImode && d->vmode != V16HImode))
- return false;
-
- for (i = 0; i < d->nelt; ++i)
- if ((d->perm[i] ^ (i * 2)) & (3 * d->nelt / 2))
- return false;
-
- if (d->testing_p)
- return true;
-
- nelt = d->nelt;
- eltsz = GET_MODE_SIZE (GET_MODE_INNER (d->vmode));
-
- /* Generate two permutation masks. In the first permutation mask
- the first quarter will contain indexes for the first half
- of the op0, the second quarter will contain bit 7 set, third quarter
- will contain indexes for the second half of the op0 and the
- last quarter bit 7 set. In the second permutation mask
- the first quarter will contain bit 7 set, the second quarter
- indexes for the first half of the op1, the third quarter bit 7 set
- and last quarter indexes for the second half of the op1.
- I.e. the first mask e.g. for V32QImode extract even will be:
- 0, 2, ..., 0xe, -128, ..., -128, 0, 2, ..., 0xe, -128, ..., -128
- (all values masked with 0xf except for -128) and second mask
- for extract even will be
- -128, ..., -128, 0, 2, ..., 0xe, -128, ..., -128, 0, 2, ..., 0xe. */
- m128 = GEN_INT (-128);
- for (i = 0; i < nelt; ++i)
- {
- unsigned j, e = d->perm[i] & (nelt / 2 - 1);
- unsigned which = d->perm[i] >= nelt;
- unsigned xorv = (i >= nelt / 4 && i < 3 * nelt / 4) ? 24 : 0;
-
- for (j = 0; j < eltsz; ++j)
- {
- rperm[which][(i * eltsz + j) ^ xorv] = GEN_INT (e * eltsz + j);
- rperm[1 - which][(i * eltsz + j) ^ xorv] = m128;
- }
- }
-
- vperm = gen_rtx_CONST_VECTOR (V32QImode, gen_rtvec_v (32, rperm[0]));
- vperm = force_reg (V32QImode, vperm);
-
- l = gen_reg_rtx (V32QImode);
- op = gen_lowpart (V32QImode, d->op0);
- emit_insn (gen_avx2_pshufbv32qi3 (l, op, vperm));
-
- vperm = gen_rtx_CONST_VECTOR (V32QImode, gen_rtvec_v (32, rperm[1]));
- vperm = force_reg (V32QImode, vperm);
-
- h = gen_reg_rtx (V32QImode);
- op = gen_lowpart (V32QImode, d->op1);
- emit_insn (gen_avx2_pshufbv32qi3 (h, op, vperm));
-
- ior = gen_reg_rtx (V32QImode);
- emit_insn (gen_iorv32qi3 (ior, l, h));
-
- /* Permute the V4DImode quarters using { 0, 2, 1, 3 } permutation. */
- op = gen_lowpart (V4DImode, d->target);
- ior = gen_lowpart (V4DImode, ior);
- emit_insn (gen_avx2_permv4di_1 (op, ior, const0_rtx, const2_rtx,
- const1_rtx, GEN_INT (3)));
-
- return true;
-}
-
-/* A subroutine of ix86_expand_vec_perm_builtin_1. Implement extract-even
- and extract-odd permutations. */
-
-static bool
-expand_vec_perm_even_odd_1 (struct expand_vec_perm_d *d, unsigned odd)
-{
- rtx t1, t2, t3;
-
- switch (d->vmode)
- {
- case V4DFmode:
- t1 = gen_reg_rtx (V4DFmode);
- t2 = gen_reg_rtx (V4DFmode);
-
- /* Shuffle the lanes around into { 0 1 4 5 } and { 2 3 6 7 }. */
- emit_insn (gen_avx_vperm2f128v4df3 (t1, d->op0, d->op1, GEN_INT (0x20)));
- emit_insn (gen_avx_vperm2f128v4df3 (t2, d->op0, d->op1, GEN_INT (0x31)));
-
- /* Now an unpck[lh]pd will produce the result required. */
- if (odd)
- t3 = gen_avx_unpckhpd256 (d->target, t1, t2);
- else
- t3 = gen_avx_unpcklpd256 (d->target, t1, t2);
- emit_insn (t3);
- break;
-
- case V8SFmode:
- {
- int mask = odd ? 0xdd : 0x88;
-
- t1 = gen_reg_rtx (V8SFmode);
- t2 = gen_reg_rtx (V8SFmode);
- t3 = gen_reg_rtx (V8SFmode);
-
- /* Shuffle within the 128-bit lanes to produce:
- { 0 2 8 a 4 6 c e } | { 1 3 9 b 5 7 d f }. */
- emit_insn (gen_avx_shufps256 (t1, d->op0, d->op1,
- GEN_INT (mask)));
-
- /* Shuffle the lanes around to produce:
- { 4 6 c e 0 2 8 a } and { 5 7 d f 1 3 9 b }. */
- emit_insn (gen_avx_vperm2f128v8sf3 (t2, t1, t1,
- GEN_INT (0x3)));
-
- /* Shuffle within the 128-bit lanes to produce:
- { 0 2 4 6 4 6 0 2 } | { 1 3 5 7 5 7 1 3 }. */
- emit_insn (gen_avx_shufps256 (t3, t1, t2, GEN_INT (0x44)));
-
- /* Shuffle within the 128-bit lanes to produce:
- { 8 a c e c e 8 a } | { 9 b d f d f 9 b }. */
- emit_insn (gen_avx_shufps256 (t2, t1, t2, GEN_INT (0xee)));
-
- /* Shuffle the lanes around to produce:
- { 0 2 4 6 8 a c e } | { 1 3 5 7 9 b d f }. */
- emit_insn (gen_avx_vperm2f128v8sf3 (d->target, t3, t2,
- GEN_INT (0x20)));
- }
- break;
-
- case V2DFmode:
- case V4SFmode:
- case V2DImode:
- case V4SImode:
- /* These are always directly implementable by expand_vec_perm_1. */
- gcc_unreachable ();
-
- case V8HImode:
- if (TARGET_SSSE3)
- return expand_vec_perm_pshufb2 (d);
- else
- {
- /* We need 2*log2(N)-1 operations to achieve odd/even
- with interleave. */
- t1 = gen_reg_rtx (V8HImode);
- t2 = gen_reg_rtx (V8HImode);
- emit_insn (gen_vec_interleave_highv8hi (t1, d->op0, d->op1));
- emit_insn (gen_vec_interleave_lowv8hi (d->target, d->op0, d->op1));
- emit_insn (gen_vec_interleave_highv8hi (t2, d->target, t1));
- emit_insn (gen_vec_interleave_lowv8hi (d->target, d->target, t1));
- if (odd)
- t3 = gen_vec_interleave_highv8hi (d->target, d->target, t2);
- else
- t3 = gen_vec_interleave_lowv8hi (d->target, d->target, t2);
- emit_insn (t3);
- }
- break;
-
- case V16QImode:
- if (TARGET_SSSE3)
- return expand_vec_perm_pshufb2 (d);
- else
- {
- t1 = gen_reg_rtx (V16QImode);
- t2 = gen_reg_rtx (V16QImode);
- t3 = gen_reg_rtx (V16QImode);
- emit_insn (gen_vec_interleave_highv16qi (t1, d->op0, d->op1));
- emit_insn (gen_vec_interleave_lowv16qi (d->target, d->op0, d->op1));
- emit_insn (gen_vec_interleave_highv16qi (t2, d->target, t1));
- emit_insn (gen_vec_interleave_lowv16qi (d->target, d->target, t1));
- emit_insn (gen_vec_interleave_highv16qi (t3, d->target, t2));
- emit_insn (gen_vec_interleave_lowv16qi (d->target, d->target, t2));
- if (odd)
- t3 = gen_vec_interleave_highv16qi (d->target, d->target, t3);
- else
- t3 = gen_vec_interleave_lowv16qi (d->target, d->target, t3);
- emit_insn (t3);
- }
- break;
-
- case V16HImode:
- case V32QImode:
- return expand_vec_perm_vpshufb2_vpermq_even_odd (d);
-
- case V4DImode:
- if (!TARGET_AVX2)
- {
- struct expand_vec_perm_d d_copy = *d;
- d_copy.vmode = V4DFmode;
- d_copy.target = gen_lowpart (V4DFmode, d->target);
- d_copy.op0 = gen_lowpart (V4DFmode, d->op0);
- d_copy.op1 = gen_lowpart (V4DFmode, d->op1);
- return expand_vec_perm_even_odd_1 (&d_copy, odd);
- }
-
- t1 = gen_reg_rtx (V4DImode);
- t2 = gen_reg_rtx (V4DImode);
-
- /* Shuffle the lanes around into { 0 1 4 5 } and { 2 3 6 7 }. */
- emit_insn (gen_avx2_permv2ti (t1, d->op0, d->op1, GEN_INT (0x20)));
- emit_insn (gen_avx2_permv2ti (t2, d->op0, d->op1, GEN_INT (0x31)));
-
- /* Now an vpunpck[lh]qdq will produce the result required. */
- if (odd)
- t3 = gen_avx2_interleave_highv4di (d->target, t1, t2);
- else
- t3 = gen_avx2_interleave_lowv4di (d->target, t1, t2);
- emit_insn (t3);
- break;
-
- case V8SImode:
- if (!TARGET_AVX2)
- {
- struct expand_vec_perm_d d_copy = *d;
- d_copy.vmode = V8SFmode;
- d_copy.target = gen_lowpart (V8SFmode, d->target);
- d_copy.op0 = gen_lowpart (V8SFmode, d->op0);
- d_copy.op1 = gen_lowpart (V8SFmode, d->op1);
- return expand_vec_perm_even_odd_1 (&d_copy, odd);
- }
-
- t1 = gen_reg_rtx (V8SImode);
- t2 = gen_reg_rtx (V8SImode);
-
- /* Shuffle the lanes around into
- { 0 1 2 3 8 9 a b } and { 4 5 6 7 c d e f }. */
- emit_insn (gen_avx2_permv2ti (gen_lowpart (V4DImode, t1),
- gen_lowpart (V4DImode, d->op0),
- gen_lowpart (V4DImode, d->op1),
- GEN_INT (0x20)));
- emit_insn (gen_avx2_permv2ti (gen_lowpart (V4DImode, t2),
- gen_lowpart (V4DImode, d->op0),
- gen_lowpart (V4DImode, d->op1),
- GEN_INT (0x31)));
-
- /* Swap the 2nd and 3rd position in each lane into
- { 0 2 1 3 8 a 9 b } and { 4 6 5 7 c e d f }. */
- emit_insn (gen_avx2_pshufdv3 (t1, t1,
- GEN_INT (2 * 4 + 1 * 16 + 3 * 64)));
- emit_insn (gen_avx2_pshufdv3 (t2, t2,
- GEN_INT (2 * 4 + 1 * 16 + 3 * 64)));
-
- /* Now an vpunpck[lh]qdq will produce
- { 0 2 4 6 8 a c e } resp. { 1 3 5 7 9 b d f }. */
- if (odd)
- t3 = gen_avx2_interleave_highv4di (gen_lowpart (V4DImode, d->target),
- gen_lowpart (V4DImode, t1),
- gen_lowpart (V4DImode, t2));
- else
- t3 = gen_avx2_interleave_lowv4di (gen_lowpart (V4DImode, d->target),
- gen_lowpart (V4DImode, t1),
- gen_lowpart (V4DImode, t2));
- emit_insn (t3);
- break;
-
- default:
- gcc_unreachable ();
- }
-
- return true;
-}
-
-/* A subroutine of ix86_expand_vec_perm_builtin_1. Pattern match
- extract-even and extract-odd permutations. */
-
-static bool
-expand_vec_perm_even_odd (struct expand_vec_perm_d *d)
-{
- unsigned i, odd, nelt = d->nelt;
-
- odd = d->perm[0];
- if (odd != 0 && odd != 1)
- return false;
-
- for (i = 1; i < nelt; ++i)
- if (d->perm[i] != 2 * i + odd)
- return false;
-
- return expand_vec_perm_even_odd_1 (d, odd);
-}
-
-/* A subroutine of ix86_expand_vec_perm_builtin_1. Implement broadcast
- permutations. We assume that expand_vec_perm_1 has already failed. */
-
-static bool
-expand_vec_perm_broadcast_1 (struct expand_vec_perm_d *d)
-{
- unsigned elt = d->perm[0], nelt2 = d->nelt / 2;
- enum machine_mode vmode = d->vmode;
- unsigned char perm2[4];
- rtx op0 = d->op0;
- bool ok;
-
- switch (vmode)
- {
- case V4DFmode:
- case V8SFmode:
- /* These are special-cased in sse.md so that we can optionally
- use the vbroadcast instruction. They expand to two insns
- if the input happens to be in a register. */
- gcc_unreachable ();
-
- case V2DFmode:
- case V2DImode:
- case V4SFmode:
- case V4SImode:
- /* These are always implementable using standard shuffle patterns. */
- gcc_unreachable ();
-
- case V8HImode:
- case V16QImode:
- /* These can be implemented via interleave. We save one insn by
- stopping once we have promoted to V4SImode and then use pshufd. */
- do
- {
- rtx dest;
- rtx (*gen) (rtx, rtx, rtx)
- = vmode == V16QImode ? gen_vec_interleave_lowv16qi
- : gen_vec_interleave_lowv8hi;
-
- if (elt >= nelt2)
- {
- gen = vmode == V16QImode ? gen_vec_interleave_highv16qi
- : gen_vec_interleave_highv8hi;
- elt -= nelt2;
- }
- nelt2 /= 2;
-
- dest = gen_reg_rtx (vmode);
- emit_insn (gen (dest, op0, op0));
- vmode = get_mode_wider_vector (vmode);
- op0 = gen_lowpart (vmode, dest);
- }
- while (vmode != V4SImode);
-
- memset (perm2, elt, 4);
- ok = expand_vselect (gen_lowpart (V4SImode, d->target), op0, perm2, 4,
- d->testing_p);
- gcc_assert (ok);
- return true;
-
- case V32QImode:
- case V16HImode:
- case V8SImode:
- case V4DImode:
- /* For AVX2 broadcasts of the first element vpbroadcast* or
- vpermq should be used by expand_vec_perm_1. */
- gcc_assert (!TARGET_AVX2 || d->perm[0]);
- return false;
-
- default:
- gcc_unreachable ();
- }
-}
-
-/* A subroutine of ix86_expand_vec_perm_builtin_1. Pattern match
- broadcast permutations. */
-
-static bool
-expand_vec_perm_broadcast (struct expand_vec_perm_d *d)
-{
- unsigned i, elt, nelt = d->nelt;
-
- if (!d->one_operand_p)
- return false;
-
- elt = d->perm[0];
- for (i = 1; i < nelt; ++i)
- if (d->perm[i] != elt)
- return false;
-
- return expand_vec_perm_broadcast_1 (d);
-}
-
-/* Implement arbitrary permutation of two V32QImode and V16QImode operands
- with 4 vpshufb insns, 2 vpermq and 3 vpor. We should have already failed
- all the shorter instruction sequences. */
-
-static bool
-expand_vec_perm_vpshufb4_vpermq2 (struct expand_vec_perm_d *d)
-{
- rtx rperm[4][32], vperm, l[2], h[2], op, m128;
- unsigned int i, nelt, eltsz;
- bool used[4];
-
- if (!TARGET_AVX2
- || d->one_operand_p
- || (d->vmode != V32QImode && d->vmode != V16HImode))
- return false;
-
- if (d->testing_p)
- return true;
-
- nelt = d->nelt;
- eltsz = GET_MODE_SIZE (GET_MODE_INNER (d->vmode));
-
- /* Generate 4 permutation masks. If the required element is within
- the same lane, it is shuffled in. If the required element from the
- other lane, force a zero by setting bit 7 in the permutation mask.
- In the other mask the mask has non-negative elements if element
- is requested from the other lane, but also moved to the other lane,
- so that the result of vpshufb can have the two V2TImode halves
- swapped. */
- m128 = GEN_INT (-128);
- for (i = 0; i < 32; ++i)
- {
- rperm[0][i] = m128;
- rperm[1][i] = m128;
- rperm[2][i] = m128;
- rperm[3][i] = m128;
- }
- used[0] = false;
- used[1] = false;
- used[2] = false;
- used[3] = false;
- for (i = 0; i < nelt; ++i)
- {
- unsigned j, e = d->perm[i] & (nelt / 2 - 1);
- unsigned xlane = ((d->perm[i] ^ i) & (nelt / 2)) * eltsz;
- unsigned int which = ((d->perm[i] & nelt) ? 2 : 0) + (xlane ? 1 : 0);
-
- for (j = 0; j < eltsz; ++j)
- rperm[which][(i * eltsz + j) ^ xlane] = GEN_INT (e * eltsz + j);
- used[which] = true;
- }
-
- for (i = 0; i < 2; ++i)
- {
- if (!used[2 * i + 1])
- {
- h[i] = NULL_RTX;
- continue;
- }
- vperm = gen_rtx_CONST_VECTOR (V32QImode,
- gen_rtvec_v (32, rperm[2 * i + 1]));
- vperm = force_reg (V32QImode, vperm);
- h[i] = gen_reg_rtx (V32QImode);
- op = gen_lowpart (V32QImode, i ? d->op1 : d->op0);
- emit_insn (gen_avx2_pshufbv32qi3 (h[i], op, vperm));
- }
-
- /* Swap the 128-byte lanes of h[X]. */
- for (i = 0; i < 2; ++i)
- {
- if (h[i] == NULL_RTX)
- continue;
- op = gen_reg_rtx (V4DImode);
- emit_insn (gen_avx2_permv4di_1 (op, gen_lowpart (V4DImode, h[i]),
- const2_rtx, GEN_INT (3), const0_rtx,
- const1_rtx));
- h[i] = gen_lowpart (V32QImode, op);
- }
-
- for (i = 0; i < 2; ++i)
- {
- if (!used[2 * i])
- {
- l[i] = NULL_RTX;
- continue;
- }
- vperm = gen_rtx_CONST_VECTOR (V32QImode, gen_rtvec_v (32, rperm[2 * i]));
- vperm = force_reg (V32QImode, vperm);
- l[i] = gen_reg_rtx (V32QImode);
- op = gen_lowpart (V32QImode, i ? d->op1 : d->op0);
- emit_insn (gen_avx2_pshufbv32qi3 (l[i], op, vperm));
- }
-
- for (i = 0; i < 2; ++i)
- {
- if (h[i] && l[i])
- {
- op = gen_reg_rtx (V32QImode);
- emit_insn (gen_iorv32qi3 (op, l[i], h[i]));
- l[i] = op;
- }
- else if (h[i])
- l[i] = h[i];
- }
-
- gcc_assert (l[0] && l[1]);
- op = gen_lowpart (V32QImode, d->target);
- emit_insn (gen_iorv32qi3 (op, l[0], l[1]));
- return true;
-}
-
-/* The guts of ix86_expand_vec_perm_const, also used by the ok hook.
- With all of the interface bits taken care of, perform the expansion
- in D and return true on success. */
-
-static bool
-ix86_expand_vec_perm_const_1 (struct expand_vec_perm_d *d)
-{
- /* Try a single instruction expansion. */
- if (expand_vec_perm_1 (d))
- return true;
-
- /* Try sequences of two instructions. */
-
- if (expand_vec_perm_pshuflw_pshufhw (d))
- return true;
-
- if (expand_vec_perm_palignr (d))
- return true;
-
- if (expand_vec_perm_interleave2 (d))
- return true;
-
- if (expand_vec_perm_broadcast (d))
- return true;
-
- if (expand_vec_perm_vpermq_perm_1 (d))
- return true;
-
- if (expand_vec_perm_vperm2f128 (d))
- return true;
-
- /* Try sequences of three instructions. */
-
- if (expand_vec_perm_2vperm2f128_vshuf (d))
- return true;
-
- if (expand_vec_perm_pshufb2 (d))
- return true;
-
- if (expand_vec_perm_interleave3 (d))
- return true;
-
- if (expand_vec_perm_vperm2f128_vblend (d))
- return true;
-
- /* Try sequences of four instructions. */
-
- if (expand_vec_perm_vpshufb2_vpermq (d))
- return true;
-
- if (expand_vec_perm_vpshufb2_vpermq_even_odd (d))
- return true;
-
- /* ??? Look for narrow permutations whose element orderings would
- allow the promotion to a wider mode. */
-
- /* ??? Look for sequences of interleave or a wider permute that place
- the data into the correct lanes for a half-vector shuffle like
- pshuf[lh]w or vpermilps. */
-
- /* ??? Look for sequences of interleave that produce the desired results.
- The combinatorics of punpck[lh] get pretty ugly... */
-
- if (expand_vec_perm_even_odd (d))
- return true;
-
- /* Even longer sequences. */
- if (expand_vec_perm_vpshufb4_vpermq2 (d))
- return true;
-
- return false;
-}
-
-/* If a permutation only uses one operand, make it clear. Returns true
- if the permutation references both operands. */
-
-static bool
-canonicalize_perm (struct expand_vec_perm_d *d)
-{
- int i, which, nelt = d->nelt;
-
- for (i = which = 0; i < nelt; ++i)
- which |= (d->perm[i] < nelt ? 1 : 2);
-
- d->one_operand_p = true;
- switch (which)
- {
- default:
- gcc_unreachable();
-
- case 3:
- if (!rtx_equal_p (d->op0, d->op1))
- {
- d->one_operand_p = false;
- break;
- }
- /* The elements of PERM do not suggest that only the first operand
- is used, but both operands are identical. Allow easier matching
- of the permutation by folding the permutation into the single
- input vector. */
- /* FALLTHRU */
-
- case 2:
- for (i = 0; i < nelt; ++i)
- d->perm[i] &= nelt - 1;
- d->op0 = d->op1;
- break;
-
- case 1:
- d->op1 = d->op0;
- break;
- }
-
- return (which == 3);
-}
-
-bool
-ix86_expand_vec_perm_const (rtx operands[4])
-{
- struct expand_vec_perm_d d;
- unsigned char perm[MAX_VECT_LEN];
- int i, nelt;
- bool two_args;
- rtx sel;
-
- d.target = operands[0];
- d.op0 = operands[1];
- d.op1 = operands[2];
- sel = operands[3];
-
- d.vmode = GET_MODE (d.target);
- gcc_assert (VECTOR_MODE_P (d.vmode));
- d.nelt = nelt = GET_MODE_NUNITS (d.vmode);
- d.testing_p = false;
-
- gcc_assert (GET_CODE (sel) == CONST_VECTOR);
- gcc_assert (XVECLEN (sel, 0) == nelt);
- gcc_checking_assert (sizeof (d.perm) == sizeof (perm));
-
- for (i = 0; i < nelt; ++i)
- {
- rtx e = XVECEXP (sel, 0, i);
- int ei = INTVAL (e) & (2 * nelt - 1);
- d.perm[i] = ei;
- perm[i] = ei;
- }
-
- two_args = canonicalize_perm (&d);
-
- if (ix86_expand_vec_perm_const_1 (&d))
- return true;
-
- /* If the selector says both arguments are needed, but the operands are the
- same, the above tried to expand with one_operand_p and flattened selector.
- If that didn't work, retry without one_operand_p; we succeeded with that
- during testing. */
- if (two_args && d.one_operand_p)
- {
- d.one_operand_p = false;
- memcpy (d.perm, perm, sizeof (perm));
- return ix86_expand_vec_perm_const_1 (&d);
- }
-
- return false;
-}
-
-/* Implement targetm.vectorize.vec_perm_const_ok. */
-
-static bool
-ix86_vectorize_vec_perm_const_ok (enum machine_mode vmode,
- const unsigned char *sel)
-{
- struct expand_vec_perm_d d;
- unsigned int i, nelt, which;
- bool ret;
-
- d.vmode = vmode;
- d.nelt = nelt = GET_MODE_NUNITS (d.vmode);
- d.testing_p = true;
-
- /* Given sufficient ISA support we can just return true here
- for selected vector modes. */
- if (GET_MODE_SIZE (d.vmode) == 16)
- {
- /* All implementable with a single vpperm insn. */
- if (TARGET_XOP)
- return true;
- /* All implementable with 2 pshufb + 1 ior. */
- if (TARGET_SSSE3)
- return true;
- /* All implementable with shufpd or unpck[lh]pd. */
- if (d.nelt == 2)
- return true;
- }
-
- /* Extract the values from the vector CST into the permutation
- array in D. */
- memcpy (d.perm, sel, nelt);
- for (i = which = 0; i < nelt; ++i)
- {
- unsigned char e = d.perm[i];
- gcc_assert (e < 2 * nelt);
- which |= (e < nelt ? 1 : 2);
- }
-
- /* For all elements from second vector, fold the elements to first. */
- if (which == 2)
- for (i = 0; i < nelt; ++i)
- d.perm[i] -= nelt;
-
- /* Check whether the mask can be applied to the vector type. */
- d.one_operand_p = (which != 3);
-
- /* Implementable with shufps or pshufd. */
- if (d.one_operand_p && (d.vmode == V4SFmode || d.vmode == V4SImode))
- return true;
-
- /* Otherwise we have to go through the motions and see if we can
- figure out how to generate the requested permutation. */
- d.target = gen_raw_REG (d.vmode, LAST_VIRTUAL_REGISTER + 1);
- d.op1 = d.op0 = gen_raw_REG (d.vmode, LAST_VIRTUAL_REGISTER + 2);
- if (!d.one_operand_p)
- d.op1 = gen_raw_REG (d.vmode, LAST_VIRTUAL_REGISTER + 3);
-
- start_sequence ();
- ret = ix86_expand_vec_perm_const_1 (&d);
- end_sequence ();
-
- return ret;
-}
-
-void
-ix86_expand_vec_extract_even_odd (rtx targ, rtx op0, rtx op1, unsigned odd)
-{
- struct expand_vec_perm_d d;
- unsigned i, nelt;
-
- d.target = targ;
- d.op0 = op0;
- d.op1 = op1;
- d.vmode = GET_MODE (targ);
- d.nelt = nelt = GET_MODE_NUNITS (d.vmode);
- d.one_operand_p = false;
- d.testing_p = false;
-
- for (i = 0; i < nelt; ++i)
- d.perm[i] = i * 2 + odd;
-
- /* We'll either be able to implement the permutation directly... */
- if (expand_vec_perm_1 (&d))
- return;
-
- /* ... or we use the special-case patterns. */
- expand_vec_perm_even_odd_1 (&d, odd);
-}
-
-static void
-ix86_expand_vec_interleave (rtx targ, rtx op0, rtx op1, bool high_p)
-{
- struct expand_vec_perm_d d;
- unsigned i, nelt, base;
- bool ok;
-
- d.target = targ;
- d.op0 = op0;
- d.op1 = op1;
- d.vmode = GET_MODE (targ);
- d.nelt = nelt = GET_MODE_NUNITS (d.vmode);
- d.one_operand_p = false;
- d.testing_p = false;
-
- base = high_p ? nelt / 2 : 0;
- for (i = 0; i < nelt / 2; ++i)
- {
- d.perm[i * 2] = i + base;
- d.perm[i * 2 + 1] = i + base + nelt;
- }
-
- /* Note that for AVX this isn't one instruction. */
- ok = ix86_expand_vec_perm_const_1 (&d);
- gcc_assert (ok);
-}
-
-
-/* Expand a vector operation CODE for a V*QImode in terms of the
- same operation on V*HImode. */
-
-void
-ix86_expand_vecop_qihi (enum rtx_code code, rtx dest, rtx op1, rtx op2)
-{
- enum machine_mode qimode = GET_MODE (dest);
- enum machine_mode himode;
- rtx (*gen_il) (rtx, rtx, rtx);
- rtx (*gen_ih) (rtx, rtx, rtx);
- rtx op1_l, op1_h, op2_l, op2_h, res_l, res_h;
- struct expand_vec_perm_d d;
- bool ok, full_interleave;
- bool uns_p = false;
- int i;
-
- switch (qimode)
- {
- case V16QImode:
- himode = V8HImode;
- gen_il = gen_vec_interleave_lowv16qi;
- gen_ih = gen_vec_interleave_highv16qi;
- break;
- case V32QImode:
- himode = V16HImode;
- gen_il = gen_avx2_interleave_lowv32qi;
- gen_ih = gen_avx2_interleave_highv32qi;
- break;
- default:
- gcc_unreachable ();
- }
-
- op2_l = op2_h = op2;
- switch (code)
- {
- case MULT:
- /* Unpack data such that we've got a source byte in each low byte of
- each word. We don't care what goes into the high byte of each word.
- Rather than trying to get zero in there, most convenient is to let
- it be a copy of the low byte. */
- op2_l = gen_reg_rtx (qimode);
- op2_h = gen_reg_rtx (qimode);
- emit_insn (gen_il (op2_l, op2, op2));
- emit_insn (gen_ih (op2_h, op2, op2));
- /* FALLTHRU */
-
- op1_l = gen_reg_rtx (qimode);
- op1_h = gen_reg_rtx (qimode);
- emit_insn (gen_il (op1_l, op1, op1));
- emit_insn (gen_ih (op1_h, op1, op1));
- full_interleave = qimode == V16QImode;
- break;
-
- case ASHIFT:
- case LSHIFTRT:
- uns_p = true;
- /* FALLTHRU */
- case ASHIFTRT:
- op1_l = gen_reg_rtx (himode);
- op1_h = gen_reg_rtx (himode);
- ix86_expand_sse_unpack (op1_l, op1, uns_p, false);
- ix86_expand_sse_unpack (op1_h, op1, uns_p, true);
- full_interleave = true;
- break;
- default:
- gcc_unreachable ();
- }
-
- /* Perform the operation. */
- res_l = expand_simple_binop (himode, code, op1_l, op2_l, NULL_RTX,
- 1, OPTAB_DIRECT);
- res_h = expand_simple_binop (himode, code, op1_h, op2_h, NULL_RTX,
- 1, OPTAB_DIRECT);
- gcc_assert (res_l && res_h);
-
- /* Merge the data back into the right place. */
- d.target = dest;
- d.op0 = gen_lowpart (qimode, res_l);
- d.op1 = gen_lowpart (qimode, res_h);
- d.vmode = qimode;
- d.nelt = GET_MODE_NUNITS (qimode);
- d.one_operand_p = false;
- d.testing_p = false;
-
- if (full_interleave)
- {
- /* For SSE2, we used an full interleave, so the desired
- results are in the even elements. */
- for (i = 0; i < 32; ++i)
- d.perm[i] = i * 2;
- }
- else
- {
- /* For AVX, the interleave used above was not cross-lane. So the
- extraction is evens but with the second and third quarter swapped.
- Happily, that is even one insn shorter than even extraction. */
- for (i = 0; i < 32; ++i)
- d.perm[i] = i * 2 + ((i & 24) == 8 ? 16 : (i & 24) == 16 ? -16 : 0);
- }
-
- ok = ix86_expand_vec_perm_const_1 (&d);
- gcc_assert (ok);
-
- set_unique_reg_note (get_last_insn (), REG_EQUAL,
- gen_rtx_fmt_ee (code, qimode, op1, op2));
-}
-
-void
-ix86_expand_mul_widen_evenodd (rtx dest, rtx op1, rtx op2,
- bool uns_p, bool odd_p)
-{
- enum machine_mode mode = GET_MODE (op1);
- enum machine_mode wmode = GET_MODE (dest);
- rtx x;
-
- /* We only play even/odd games with vectors of SImode. */
- gcc_assert (mode == V4SImode || mode == V8SImode);
-
- /* If we're looking for the odd results, shift those members down to
- the even slots. For some cpus this is faster than a PSHUFD. */
- if (odd_p)
- {
- /* For XOP use vpmacsdqh, but only for smult, as it is only
- signed. */
- if (TARGET_XOP && mode == V4SImode && !uns_p)
- {
- x = force_reg (wmode, CONST0_RTX (wmode));
- emit_insn (gen_xop_pmacsdqh (dest, op1, op2, x));
- return;
- }
-
- x = GEN_INT (GET_MODE_UNIT_BITSIZE (mode));
- op1 = expand_binop (wmode, lshr_optab, gen_lowpart (wmode, op1),
- x, NULL, 1, OPTAB_DIRECT);
- op2 = expand_binop (wmode, lshr_optab, gen_lowpart (wmode, op2),
- x, NULL, 1, OPTAB_DIRECT);
- op1 = gen_lowpart (mode, op1);
- op2 = gen_lowpart (mode, op2);
- }
-
- if (mode == V8SImode)
- {
- if (uns_p)
- x = gen_vec_widen_umult_even_v8si (dest, op1, op2);
- else
- x = gen_vec_widen_smult_even_v8si (dest, op1, op2);
- }
- else if (uns_p)
- x = gen_vec_widen_umult_even_v4si (dest, op1, op2);
- else if (TARGET_SSE4_1)
- x = gen_sse4_1_mulv2siv2di3 (dest, op1, op2);
- else
- {
- rtx s1, s2, t0, t1, t2;
-
- /* The easiest way to implement this without PMULDQ is to go through
- the motions as if we are performing a full 64-bit multiply. With
- the exception that we need to do less shuffling of the elements. */
-
- /* Compute the sign-extension, aka highparts, of the two operands. */
- s1 = ix86_expand_sse_cmp (gen_reg_rtx (mode), GT, CONST0_RTX (mode),
- op1, pc_rtx, pc_rtx);
- s2 = ix86_expand_sse_cmp (gen_reg_rtx (mode), GT, CONST0_RTX (mode),
- op2, pc_rtx, pc_rtx);
-
- /* Multiply LO(A) * HI(B), and vice-versa. */
- t1 = gen_reg_rtx (wmode);
- t2 = gen_reg_rtx (wmode);
- emit_insn (gen_vec_widen_umult_even_v4si (t1, s1, op2));
- emit_insn (gen_vec_widen_umult_even_v4si (t2, s2, op1));
-
- /* Multiply LO(A) * LO(B). */
- t0 = gen_reg_rtx (wmode);
- emit_insn (gen_vec_widen_umult_even_v4si (t0, op1, op2));
-
- /* Combine and shift the highparts into place. */
- t1 = expand_binop (wmode, add_optab, t1, t2, t1, 1, OPTAB_DIRECT);
- t1 = expand_binop (wmode, ashl_optab, t1, GEN_INT (32), t1,
- 1, OPTAB_DIRECT);
-
- /* Combine high and low parts. */
- force_expand_binop (wmode, add_optab, t0, t1, dest, 1, OPTAB_DIRECT);
- return;
- }
- emit_insn (x);
-}
-
-void
-ix86_expand_mul_widen_hilo (rtx dest, rtx op1, rtx op2,
- bool uns_p, bool high_p)
-{
- enum machine_mode wmode = GET_MODE (dest);
- enum machine_mode mode = GET_MODE (op1);
- rtx t1, t2, t3, t4, mask;
-
- switch (mode)
- {
- case V4SImode:
- t1 = gen_reg_rtx (mode);
- t2 = gen_reg_rtx (mode);
- if (TARGET_XOP && !uns_p)
- {
- /* With XOP, we have pmacsdqh, aka mul_widen_odd. In this case,
- shuffle the elements once so that all elements are in the right
- place for immediate use: { A C B D }. */
- emit_insn (gen_sse2_pshufd_1 (t1, op1, const0_rtx, const2_rtx,
- const1_rtx, GEN_INT (3)));
- emit_insn (gen_sse2_pshufd_1 (t2, op2, const0_rtx, const2_rtx,
- const1_rtx, GEN_INT (3)));
- }
- else
- {
- /* Put the elements into place for the multiply. */
- ix86_expand_vec_interleave (t1, op1, op1, high_p);
- ix86_expand_vec_interleave (t2, op2, op2, high_p);
- high_p = false;
- }
- ix86_expand_mul_widen_evenodd (dest, t1, t2, uns_p, high_p);
- break;
-
- case V8SImode:
- /* Shuffle the elements between the lanes. After this we
- have { A B E F | C D G H } for each operand. */
- t1 = gen_reg_rtx (V4DImode);
- t2 = gen_reg_rtx (V4DImode);
- emit_insn (gen_avx2_permv4di_1 (t1, gen_lowpart (V4DImode, op1),
- const0_rtx, const2_rtx,
- const1_rtx, GEN_INT (3)));
- emit_insn (gen_avx2_permv4di_1 (t2, gen_lowpart (V4DImode, op2),
- const0_rtx, const2_rtx,
- const1_rtx, GEN_INT (3)));
-
- /* Shuffle the elements within the lanes. After this we
- have { A A B B | C C D D } or { E E F F | G G H H }. */
- t3 = gen_reg_rtx (V8SImode);
- t4 = gen_reg_rtx (V8SImode);
- mask = GEN_INT (high_p
- ? 2 + (2 << 2) + (3 << 4) + (3 << 6)
- : 0 + (0 << 2) + (1 << 4) + (1 << 6));
- emit_insn (gen_avx2_pshufdv3 (t3, gen_lowpart (V8SImode, t1), mask));
- emit_insn (gen_avx2_pshufdv3 (t4, gen_lowpart (V8SImode, t2), mask));
-
- ix86_expand_mul_widen_evenodd (dest, t3, t4, uns_p, false);
- break;
-
- case V8HImode:
- case V16HImode:
- t1 = expand_binop (mode, smul_optab, op1, op2, NULL_RTX,
- uns_p, OPTAB_DIRECT);
- t2 = expand_binop (mode,
- uns_p ? umul_highpart_optab : smul_highpart_optab,
- op1, op2, NULL_RTX, uns_p, OPTAB_DIRECT);
- gcc_assert (t1 && t2);
-
- ix86_expand_vec_interleave (gen_lowpart (mode, dest), t1, t2, high_p);
- break;
-
- case V16QImode:
- case V32QImode:
- t1 = gen_reg_rtx (wmode);
- t2 = gen_reg_rtx (wmode);
- ix86_expand_sse_unpack (t1, op1, uns_p, high_p);
- ix86_expand_sse_unpack (t2, op2, uns_p, high_p);
-
- emit_insn (gen_rtx_SET (VOIDmode, dest, gen_rtx_MULT (wmode, t1, t2)));
- break;
-
- default:
- gcc_unreachable ();
- }
-}
-
-void
-ix86_expand_sse2_mulv4si3 (rtx op0, rtx op1, rtx op2)
-{
- rtx res_1, res_2;
-
- res_1 = gen_reg_rtx (V4SImode);
- res_2 = gen_reg_rtx (V4SImode);
- ix86_expand_mul_widen_evenodd (gen_lowpart (V2DImode, res_1),
- op1, op2, true, false);
- ix86_expand_mul_widen_evenodd (gen_lowpart (V2DImode, res_2),
- op1, op2, true, true);
-
- /* Move the results in element 2 down to element 1; we don't care
- what goes in elements 2 and 3. Then we can merge the parts
- back together with an interleave.
-
- Note that two other sequences were tried:
- (1) Use interleaves at the start instead of psrldq, which allows
- us to use a single shufps to merge things back at the end.
- (2) Use shufps here to combine the two vectors, then pshufd to
- put the elements in the correct order.
- In both cases the cost of the reformatting stall was too high
- and the overall sequence slower. */
-
- emit_insn (gen_sse2_pshufd_1 (res_1, res_1, const0_rtx, const2_rtx,
- const0_rtx, const0_rtx));
- emit_insn (gen_sse2_pshufd_1 (res_2, res_2, const0_rtx, const2_rtx,
- const0_rtx, const0_rtx));
- res_1 = emit_insn (gen_vec_interleave_lowv4si (op0, res_1, res_2));
-
- set_unique_reg_note (res_1, REG_EQUAL, gen_rtx_MULT (V4SImode, op1, op2));
-}
-
-void
-ix86_expand_sse2_mulvxdi3 (rtx op0, rtx op1, rtx op2)
-{
- enum machine_mode mode = GET_MODE (op0);
- rtx t1, t2, t3, t4, t5, t6;
-
- if (TARGET_XOP && mode == V2DImode)
- {
- /* op1: A,B,C,D, op2: E,F,G,H */
- op1 = gen_lowpart (V4SImode, op1);
- op2 = gen_lowpart (V4SImode, op2);
-
- t1 = gen_reg_rtx (V4SImode);
- t2 = gen_reg_rtx (V4SImode);
- t3 = gen_reg_rtx (V2DImode);
- t4 = gen_reg_rtx (V2DImode);
-
- /* t1: B,A,D,C */
- emit_insn (gen_sse2_pshufd_1 (t1, op1,
- GEN_INT (1),
- GEN_INT (0),
- GEN_INT (3),
- GEN_INT (2)));
-
- /* t2: (B*E),(A*F),(D*G),(C*H) */
- emit_insn (gen_mulv4si3 (t2, t1, op2));
-
- /* t3: (B*E)+(A*F), (D*G)+(C*H) */
- emit_insn (gen_xop_phadddq (t3, t2));
-
- /* t4: ((B*E)+(A*F))<<32, ((D*G)+(C*H))<<32 */
- emit_insn (gen_ashlv2di3 (t4, t3, GEN_INT (32)));
-
- /* op0: (((B*E)+(A*F))<<32)+(B*F), (((D*G)+(C*H))<<32)+(D*H) */
- emit_insn (gen_xop_pmacsdql (op0, op1, op2, t4));
- }
- else
- {
- enum machine_mode nmode;
- rtx (*umul) (rtx, rtx, rtx);
-
- if (mode == V2DImode)
- {
- umul = gen_vec_widen_umult_even_v4si;
- nmode = V4SImode;
- }
- else if (mode == V4DImode)
- {
- umul = gen_vec_widen_umult_even_v8si;
- nmode = V8SImode;
- }
- else
- gcc_unreachable ();
-
-
- /* Multiply low parts. */
- t1 = gen_reg_rtx (mode);
- emit_insn (umul (t1, gen_lowpart (nmode, op1), gen_lowpart (nmode, op2)));
-
- /* Shift input vectors right 32 bits so we can multiply high parts. */
- t6 = GEN_INT (32);
- t2 = expand_binop (mode, lshr_optab, op1, t6, NULL, 1, OPTAB_DIRECT);
- t3 = expand_binop (mode, lshr_optab, op2, t6, NULL, 1, OPTAB_DIRECT);
-
- /* Multiply high parts by low parts. */
- t4 = gen_reg_rtx (mode);
- t5 = gen_reg_rtx (mode);
- emit_insn (umul (t4, gen_lowpart (nmode, t2), gen_lowpart (nmode, op2)));
- emit_insn (umul (t5, gen_lowpart (nmode, t3), gen_lowpart (nmode, op1)));
-
- /* Combine and shift the highparts back. */
- t4 = expand_binop (mode, add_optab, t4, t5, t4, 1, OPTAB_DIRECT);
- t4 = expand_binop (mode, ashl_optab, t4, t6, t4, 1, OPTAB_DIRECT);
-
- /* Combine high and low parts. */
- force_expand_binop (mode, add_optab, t1, t4, op0, 1, OPTAB_DIRECT);
- }
-
- set_unique_reg_note (get_last_insn (), REG_EQUAL,
- gen_rtx_MULT (mode, op1, op2));
-}
-
-/* Expand an insert into a vector register through pinsr insn.
- Return true if successful. */
-
-bool
-ix86_expand_pinsr (rtx *operands)
-{
- rtx dst = operands[0];
- rtx src = operands[3];
-
- unsigned int size = INTVAL (operands[1]);
- unsigned int pos = INTVAL (operands[2]);
-
- if (GET_CODE (dst) == SUBREG)
- {
- pos += SUBREG_BYTE (dst) * BITS_PER_UNIT;
- dst = SUBREG_REG (dst);
- }
-
- if (GET_CODE (src) == SUBREG)
- src = SUBREG_REG (src);
-
- switch (GET_MODE (dst))
- {
- case V16QImode:
- case V8HImode:
- case V4SImode:
- case V2DImode:
- {
- enum machine_mode srcmode, dstmode;
- rtx (*pinsr)(rtx, rtx, rtx, rtx);
-
- srcmode = mode_for_size (size, MODE_INT, 0);
-
- switch (srcmode)
- {
- case QImode:
- if (!TARGET_SSE4_1)
- return false;
- dstmode = V16QImode;
- pinsr = gen_sse4_1_pinsrb;
- break;
-
- case HImode:
- if (!TARGET_SSE2)
- return false;
- dstmode = V8HImode;
- pinsr = gen_sse2_pinsrw;
- break;
-
- case SImode:
- if (!TARGET_SSE4_1)
- return false;
- dstmode = V4SImode;
- pinsr = gen_sse4_1_pinsrd;
- break;
-
- case DImode:
- gcc_assert (TARGET_64BIT);
- if (!TARGET_SSE4_1)
- return false;
- dstmode = V2DImode;
- pinsr = gen_sse4_1_pinsrq;
- break;
-
- default:
- return false;
- }
-
- dst = gen_lowpart (dstmode, dst);
- src = gen_lowpart (srcmode, src);
-
- pos /= size;
-
- emit_insn (pinsr (dst, dst, src, GEN_INT (1 << pos)));
- return true;
- }
-
- default:
- return false;
- }
-}
-
-/* This function returns the calling abi specific va_list type node.
- It returns the FNDECL specific va_list type. */
-
-static tree
-ix86_fn_abi_va_list (tree fndecl)
-{
- if (!TARGET_64BIT)
- return va_list_type_node;
- gcc_assert (fndecl != NULL_TREE);
-
- if (ix86_function_abi ((const_tree) fndecl) == MS_ABI)
- return ms_va_list_type_node;
- else
- return sysv_va_list_type_node;
-}
-
-/* Returns the canonical va_list type specified by TYPE. If there
- is no valid TYPE provided, it return NULL_TREE. */
-
-static tree
-ix86_canonical_va_list_type (tree type)
-{
- tree wtype, htype;
-
- /* Resolve references and pointers to va_list type. */
- if (TREE_CODE (type) == MEM_REF)
- type = TREE_TYPE (type);
- else if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE(type)))
- type = TREE_TYPE (type);
- else if (POINTER_TYPE_P (type) && TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
- type = TREE_TYPE (type);
-
- if (TARGET_64BIT && va_list_type_node != NULL_TREE)
- {
- wtype = va_list_type_node;
- gcc_assert (wtype != NULL_TREE);
- htype = type;
- if (TREE_CODE (wtype) == ARRAY_TYPE)
- {
- /* If va_list is an array type, the argument may have decayed
- to a pointer type, e.g. by being passed to another function.
- In that case, unwrap both types so that we can compare the
- underlying records. */
- if (TREE_CODE (htype) == ARRAY_TYPE
- || POINTER_TYPE_P (htype))
- {
- wtype = TREE_TYPE (wtype);
- htype = TREE_TYPE (htype);
- }
- }
- if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
- return va_list_type_node;
- wtype = sysv_va_list_type_node;
- gcc_assert (wtype != NULL_TREE);
- htype = type;
- if (TREE_CODE (wtype) == ARRAY_TYPE)
- {
- /* If va_list is an array type, the argument may have decayed
- to a pointer type, e.g. by being passed to another function.
- In that case, unwrap both types so that we can compare the
- underlying records. */
- if (TREE_CODE (htype) == ARRAY_TYPE
- || POINTER_TYPE_P (htype))
- {
- wtype = TREE_TYPE (wtype);
- htype = TREE_TYPE (htype);
- }
- }
- if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
- return sysv_va_list_type_node;
- wtype = ms_va_list_type_node;
- gcc_assert (wtype != NULL_TREE);
- htype = type;
- if (TREE_CODE (wtype) == ARRAY_TYPE)
- {
- /* If va_list is an array type, the argument may have decayed
- to a pointer type, e.g. by being passed to another function.
- In that case, unwrap both types so that we can compare the
- underlying records. */
- if (TREE_CODE (htype) == ARRAY_TYPE
- || POINTER_TYPE_P (htype))
- {
- wtype = TREE_TYPE (wtype);
- htype = TREE_TYPE (htype);
- }
- }
- if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
- return ms_va_list_type_node;
- return NULL_TREE;
- }
- return std_canonical_va_list_type (type);
-}
-
-/* Iterate through the target-specific builtin types for va_list.
- IDX denotes the iterator, *PTREE is set to the result type of
- the va_list builtin, and *PNAME to its internal type.
- Returns zero if there is no element for this index, otherwise
- IDX should be increased upon the next call.
- Note, do not iterate a base builtin's name like __builtin_va_list.
- Used from c_common_nodes_and_builtins. */
-
-static int
-ix86_enum_va_list (int idx, const char **pname, tree *ptree)
-{
- if (TARGET_64BIT)
- {
- switch (idx)
- {
- default:
- break;
-
- case 0:
- *ptree = ms_va_list_type_node;
- *pname = "__builtin_ms_va_list";
- return 1;
-
- case 1:
- *ptree = sysv_va_list_type_node;
- *pname = "__builtin_sysv_va_list";
- return 1;
- }
- }
-
- return 0;
-}
-
-#undef TARGET_SCHED_DISPATCH
-#define TARGET_SCHED_DISPATCH has_dispatch
-#undef TARGET_SCHED_DISPATCH_DO
-#define TARGET_SCHED_DISPATCH_DO do_dispatch
-#undef TARGET_SCHED_REASSOCIATION_WIDTH
-#define TARGET_SCHED_REASSOCIATION_WIDTH ix86_reassociation_width
-#undef TARGET_SCHED_REORDER
-#define TARGET_SCHED_REORDER ix86_sched_reorder
-#undef TARGET_SCHED_ADJUST_PRIORITY
-#define TARGET_SCHED_ADJUST_PRIORITY ix86_adjust_priority
-#undef TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK
-#define TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK \
- ix86_dependencies_evaluation_hook
-
-/* The size of the dispatch window is the total number of bytes of
- object code allowed in a window. */
-#define DISPATCH_WINDOW_SIZE 16
-
-/* Number of dispatch windows considered for scheduling. */
-#define MAX_DISPATCH_WINDOWS 3
-
-/* Maximum number of instructions in a window. */
-#define MAX_INSN 4
-
-/* Maximum number of immediate operands in a window. */
-#define MAX_IMM 4
-
-/* Maximum number of immediate bits allowed in a window. */
-#define MAX_IMM_SIZE 128
-
-/* Maximum number of 32 bit immediates allowed in a window. */
-#define MAX_IMM_32 4
-
-/* Maximum number of 64 bit immediates allowed in a window. */
-#define MAX_IMM_64 2
-
-/* Maximum total of loads or prefetches allowed in a window. */
-#define MAX_LOAD 2
-
-/* Maximum total of stores allowed in a window. */
-#define MAX_STORE 1
-
-#undef BIG
-#define BIG 100
-
-
-/* Dispatch groups. Istructions that affect the mix in a dispatch window. */
-enum dispatch_group {
- disp_no_group = 0,
- disp_load,
- disp_store,
- disp_load_store,
- disp_prefetch,
- disp_imm,
- disp_imm_32,
- disp_imm_64,
- disp_branch,
- disp_cmp,
- disp_jcc,
- disp_last
-};
-
-/* Number of allowable groups in a dispatch window. It is an array
- indexed by dispatch_group enum. 100 is used as a big number,
- because the number of these kind of operations does not have any
- effect in dispatch window, but we need them for other reasons in
- the table. */
-static unsigned int num_allowable_groups[disp_last] = {
- 0, 2, 1, 1, 2, 4, 4, 2, 1, BIG, BIG
-};
-
-char group_name[disp_last + 1][16] = {
- "disp_no_group", "disp_load", "disp_store", "disp_load_store",
- "disp_prefetch", "disp_imm", "disp_imm_32", "disp_imm_64",
- "disp_branch", "disp_cmp", "disp_jcc", "disp_last"
-};
-
-/* Instruction path. */
-enum insn_path {
- no_path = 0,
- path_single, /* Single micro op. */
- path_double, /* Double micro op. */
- path_multi, /* Instructions with more than 2 micro op.. */
- last_path
-};
-
-/* sched_insn_info defines a window to the instructions scheduled in
- the basic block. It contains a pointer to the insn_info table and
- the instruction scheduled.
-
- Windows are allocated for each basic block and are linked
- together. */
-typedef struct sched_insn_info_s {
- rtx insn;
- enum dispatch_group group;
- enum insn_path path;
- int byte_len;
- int imm_bytes;
-} sched_insn_info;
-
-/* Linked list of dispatch windows. This is a two way list of
- dispatch windows of a basic block. It contains information about
- the number of uops in the window and the total number of
- instructions and of bytes in the object code for this dispatch
- window. */
-typedef struct dispatch_windows_s {
- int num_insn; /* Number of insn in the window. */
- int num_uops; /* Number of uops in the window. */
- int window_size; /* Number of bytes in the window. */
- int window_num; /* Window number between 0 or 1. */
- int num_imm; /* Number of immediates in an insn. */
- int num_imm_32; /* Number of 32 bit immediates in an insn. */
- int num_imm_64; /* Number of 64 bit immediates in an insn. */
- int imm_size; /* Total immediates in the window. */
- int num_loads; /* Total memory loads in the window. */
- int num_stores; /* Total memory stores in the window. */
- int violation; /* Violation exists in window. */
- sched_insn_info *window; /* Pointer to the window. */
- struct dispatch_windows_s *next;
- struct dispatch_windows_s *prev;
-} dispatch_windows;
-
-/* Immediate valuse used in an insn. */
-typedef struct imm_info_s
- {
- int imm;
- int imm32;
- int imm64;
- } imm_info;
-
-static dispatch_windows *dispatch_window_list;
-static dispatch_windows *dispatch_window_list1;
-
-/* Get dispatch group of insn. */
-
-static enum dispatch_group
-get_mem_group (rtx insn)
-{
- enum attr_memory memory;
-
- if (INSN_CODE (insn) < 0)
- return disp_no_group;
- memory = get_attr_memory (insn);
- if (memory == MEMORY_STORE)
- return disp_store;
-
- if (memory == MEMORY_LOAD)
- return disp_load;
-
- if (memory == MEMORY_BOTH)
- return disp_load_store;
-
- return disp_no_group;
-}
-
-/* Return true if insn is a compare instruction. */
-
-static bool
-is_cmp (rtx insn)
-{
- enum attr_type type;
-
- type = get_attr_type (insn);
- return (type == TYPE_TEST
- || type == TYPE_ICMP
- || type == TYPE_FCMP
- || GET_CODE (PATTERN (insn)) == COMPARE);
-}
-
-/* Return true if a dispatch violation encountered. */
-
-static bool
-dispatch_violation (void)
-{
- if (dispatch_window_list->next)
- return dispatch_window_list->next->violation;
- return dispatch_window_list->violation;
-}
-
-/* Return true if insn is a branch instruction. */
-
-static bool
-is_branch (rtx insn)
-{
- return (CALL_P (insn) || JUMP_P (insn));
-}
-
-/* Return true if insn is a prefetch instruction. */
-
-static bool
-is_prefetch (rtx insn)
-{
- return NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == PREFETCH;
-}
-
-/* This function initializes a dispatch window and the list container holding a
- pointer to the window. */
-
-static void
-init_window (int window_num)
-{
- int i;
- dispatch_windows *new_list;
-
- if (window_num == 0)
- new_list = dispatch_window_list;
- else
- new_list = dispatch_window_list1;
-
- new_list->num_insn = 0;
- new_list->num_uops = 0;
- new_list->window_size = 0;
- new_list->next = NULL;
- new_list->prev = NULL;
- new_list->window_num = window_num;
- new_list->num_imm = 0;
- new_list->num_imm_32 = 0;
- new_list->num_imm_64 = 0;
- new_list->imm_size = 0;
- new_list->num_loads = 0;
- new_list->num_stores = 0;
- new_list->violation = false;
-
- for (i = 0; i < MAX_INSN; i++)
- {
- new_list->window[i].insn = NULL;
- new_list->window[i].group = disp_no_group;
- new_list->window[i].path = no_path;
- new_list->window[i].byte_len = 0;
- new_list->window[i].imm_bytes = 0;
- }
- return;
-}
-
-/* This function allocates and initializes a dispatch window and the
- list container holding a pointer to the window. */
-
-static dispatch_windows *
-allocate_window (void)
-{
- dispatch_windows *new_list = XNEW (struct dispatch_windows_s);
- new_list->window = XNEWVEC (struct sched_insn_info_s, MAX_INSN + 1);
-
- return new_list;
-}
-
-/* This routine initializes the dispatch scheduling information. It
- initiates building dispatch scheduler tables and constructs the
- first dispatch window. */
-
-static void
-init_dispatch_sched (void)
-{
- /* Allocate a dispatch list and a window. */
- dispatch_window_list = allocate_window ();
- dispatch_window_list1 = allocate_window ();
- init_window (0);
- init_window (1);
-}
-
-/* This function returns true if a branch is detected. End of a basic block
- does not have to be a branch, but here we assume only branches end a
- window. */
-
-static bool
-is_end_basic_block (enum dispatch_group group)
-{
- return group == disp_branch;
-}
-
-/* This function is called when the end of a window processing is reached. */
-
-static void
-process_end_window (void)
-{
- gcc_assert (dispatch_window_list->num_insn <= MAX_INSN);
- if (dispatch_window_list->next)
- {
- gcc_assert (dispatch_window_list1->num_insn <= MAX_INSN);
- gcc_assert (dispatch_window_list->window_size
- + dispatch_window_list1->window_size <= 48);
- init_window (1);
- }
- init_window (0);
-}
-
-/* Allocates a new dispatch window and adds it to WINDOW_LIST.
- WINDOW_NUM is either 0 or 1. A maximum of two windows are generated
- for 48 bytes of instructions. Note that these windows are not dispatch
- windows that their sizes are DISPATCH_WINDOW_SIZE. */
-
-static dispatch_windows *
-allocate_next_window (int window_num)
-{
- if (window_num == 0)
- {
- if (dispatch_window_list->next)
- init_window (1);
- init_window (0);
- return dispatch_window_list;
- }
-
- dispatch_window_list->next = dispatch_window_list1;
- dispatch_window_list1->prev = dispatch_window_list;
-
- return dispatch_window_list1;
-}
-
-/* Increment the number of immediate operands of an instruction. */
-
-static int
-find_constant_1 (rtx *in_rtx, imm_info *imm_values)
-{
- if (*in_rtx == 0)
- return 0;
-
- switch ( GET_CODE (*in_rtx))
- {
- case CONST:
- case SYMBOL_REF:
- case CONST_INT:
- (imm_values->imm)++;
- if (x86_64_immediate_operand (*in_rtx, SImode))
- (imm_values->imm32)++;
- else
- (imm_values->imm64)++;
- break;
-
- case CONST_DOUBLE:
- (imm_values->imm)++;
- (imm_values->imm64)++;
- break;
-
- case CODE_LABEL:
- if (LABEL_KIND (*in_rtx) == LABEL_NORMAL)
- {
- (imm_values->imm)++;
- (imm_values->imm32)++;
- }
- break;
-
- default:
- break;
- }
-
- return 0;
-}
-
-/* Compute number of immediate operands of an instruction. */
-
-static void
-find_constant (rtx in_rtx, imm_info *imm_values)
-{
- for_each_rtx (INSN_P (in_rtx) ? &PATTERN (in_rtx) : &in_rtx,
- (rtx_function) find_constant_1, (void *) imm_values);
-}
-
-/* Return total size of immediate operands of an instruction along with number
- of corresponding immediate-operands. It initializes its parameters to zero
- befor calling FIND_CONSTANT.
- INSN is the input instruction. IMM is the total of immediates.
- IMM32 is the number of 32 bit immediates. IMM64 is the number of 64
- bit immediates. */
-
-static int
-get_num_immediates (rtx insn, int *imm, int *imm32, int *imm64)
-{
- imm_info imm_values = {0, 0, 0};
-
- find_constant (insn, &imm_values);
- *imm = imm_values.imm;
- *imm32 = imm_values.imm32;
- *imm64 = imm_values.imm64;
- return imm_values.imm32 * 4 + imm_values.imm64 * 8;
-}
-
-/* This function indicates if an operand of an instruction is an
- immediate. */
-
-static bool
-has_immediate (rtx insn)
-{
- int num_imm_operand;
- int num_imm32_operand;
- int num_imm64_operand;
-
- if (insn)
- return get_num_immediates (insn, &num_imm_operand, &num_imm32_operand,
- &num_imm64_operand);
- return false;
-}
-
-/* Return single or double path for instructions. */
-
-static enum insn_path
-get_insn_path (rtx insn)
-{
- enum attr_amdfam10_decode path = get_attr_amdfam10_decode (insn);
-
- if ((int)path == 0)
- return path_single;
-
- if ((int)path == 1)
- return path_double;
-
- return path_multi;
-}
-
-/* Return insn dispatch group. */
-
-static enum dispatch_group
-get_insn_group (rtx insn)
-{
- enum dispatch_group group = get_mem_group (insn);
- if (group)
- return group;
-
- if (is_branch (insn))
- return disp_branch;
-
- if (is_cmp (insn))
- return disp_cmp;
-
- if (has_immediate (insn))
- return disp_imm;
-
- if (is_prefetch (insn))
- return disp_prefetch;
-
- return disp_no_group;
-}
-
-/* Count number of GROUP restricted instructions in a dispatch
- window WINDOW_LIST. */
-
-static int
-count_num_restricted (rtx insn, dispatch_windows *window_list)
-{
- enum dispatch_group group = get_insn_group (insn);
- int imm_size;
- int num_imm_operand;
- int num_imm32_operand;
- int num_imm64_operand;
-
- if (group == disp_no_group)
- return 0;
-
- if (group == disp_imm)
- {
- imm_size = get_num_immediates (insn, &num_imm_operand, &num_imm32_operand,
- &num_imm64_operand);
- if (window_list->imm_size + imm_size > MAX_IMM_SIZE
- || num_imm_operand + window_list->num_imm > MAX_IMM
- || (num_imm32_operand > 0
- && (window_list->num_imm_32 + num_imm32_operand > MAX_IMM_32
- || window_list->num_imm_64 * 2 + num_imm32_operand > MAX_IMM_32))
- || (num_imm64_operand > 0
- && (window_list->num_imm_64 + num_imm64_operand > MAX_IMM_64
- || window_list->num_imm_32 + num_imm64_operand * 2 > MAX_IMM_32))
- || (window_list->imm_size + imm_size == MAX_IMM_SIZE
- && num_imm64_operand > 0
- && ((window_list->num_imm_64 > 0
- && window_list->num_insn >= 2)
- || window_list->num_insn >= 3)))
- return BIG;
-
- return 1;
- }
-
- if ((group == disp_load_store
- && (window_list->num_loads >= MAX_LOAD
- || window_list->num_stores >= MAX_STORE))
- || ((group == disp_load
- || group == disp_prefetch)
- && window_list->num_loads >= MAX_LOAD)
- || (group == disp_store
- && window_list->num_stores >= MAX_STORE))
- return BIG;
-
- return 1;
-}
-
-/* This function returns true if insn satisfies dispatch rules on the
- last window scheduled. */
-
-static bool
-fits_dispatch_window (rtx insn)
-{
- dispatch_windows *window_list = dispatch_window_list;
- dispatch_windows *window_list_next = dispatch_window_list->next;
- unsigned int num_restrict;
- enum dispatch_group group = get_insn_group (insn);
- enum insn_path path = get_insn_path (insn);
- int sum;
-
- /* Make disp_cmp and disp_jcc get scheduled at the latest. These
- instructions should be given the lowest priority in the
- scheduling process in Haifa scheduler to make sure they will be
- scheduled in the same dispatch window as the reference to them. */
- if (group == disp_jcc || group == disp_cmp)
- return false;
-
- /* Check nonrestricted. */
- if (group == disp_no_group || group == disp_branch)
- return true;
-
- /* Get last dispatch window. */
- if (window_list_next)
- window_list = window_list_next;
-
- if (window_list->window_num == 1)
- {
- sum = window_list->prev->window_size + window_list->window_size;
-
- if (sum == 32
- || (min_insn_size (insn) + sum) >= 48)
- /* Window 1 is full. Go for next window. */
- return true;
- }
-
- num_restrict = count_num_restricted (insn, window_list);
-
- if (num_restrict > num_allowable_groups[group])
- return false;
-
- /* See if it fits in the first window. */
- if (window_list->window_num == 0)
- {
- /* The first widow should have only single and double path
- uops. */
- if (path == path_double
- && (window_list->num_uops + 2) > MAX_INSN)
- return false;
- else if (path != path_single)
- return false;
- }
- return true;
-}
-
-/* Add an instruction INSN with NUM_UOPS micro-operations to the
- dispatch window WINDOW_LIST. */
-
-static void
-add_insn_window (rtx insn, dispatch_windows *window_list, int num_uops)
-{
- int byte_len = min_insn_size (insn);
- int num_insn = window_list->num_insn;
- int imm_size;
- sched_insn_info *window = window_list->window;
- enum dispatch_group group = get_insn_group (insn);
- enum insn_path path = get_insn_path (insn);
- int num_imm_operand;
- int num_imm32_operand;
- int num_imm64_operand;
-
- if (!window_list->violation && group != disp_cmp
- && !fits_dispatch_window (insn))
- window_list->violation = true;
-
- imm_size = get_num_immediates (insn, &num_imm_operand, &num_imm32_operand,
- &num_imm64_operand);
-
- /* Initialize window with new instruction. */
- window[num_insn].insn = insn;
- window[num_insn].byte_len = byte_len;
- window[num_insn].group = group;
- window[num_insn].path = path;
- window[num_insn].imm_bytes = imm_size;
-
- window_list->window_size += byte_len;
- window_list->num_insn = num_insn + 1;
- window_list->num_uops = window_list->num_uops + num_uops;
- window_list->imm_size += imm_size;
- window_list->num_imm += num_imm_operand;
- window_list->num_imm_32 += num_imm32_operand;
- window_list->num_imm_64 += num_imm64_operand;
-
- if (group == disp_store)
- window_list->num_stores += 1;
- else if (group == disp_load
- || group == disp_prefetch)
- window_list->num_loads += 1;
- else if (group == disp_load_store)
- {
- window_list->num_stores += 1;
- window_list->num_loads += 1;
- }
-}
-
-/* Adds a scheduled instruction, INSN, to the current dispatch window.
- If the total bytes of instructions or the number of instructions in
- the window exceed allowable, it allocates a new window. */
-
-static void
-add_to_dispatch_window (rtx insn)
-{
- int byte_len;
- dispatch_windows *window_list;
- dispatch_windows *next_list;
- dispatch_windows *window0_list;
- enum insn_path path;
- enum dispatch_group insn_group;
- bool insn_fits;
- int num_insn;
- int num_uops;
- int window_num;
- int insn_num_uops;
- int sum;
-
- if (INSN_CODE (insn) < 0)
- return;
-
- byte_len = min_insn_size (insn);
- window_list = dispatch_window_list;
- next_list = window_list->next;
- path = get_insn_path (insn);
- insn_group = get_insn_group (insn);
-
- /* Get the last dispatch window. */
- if (next_list)
- window_list = dispatch_window_list->next;
-
- if (path == path_single)
- insn_num_uops = 1;
- else if (path == path_double)
- insn_num_uops = 2;
- else
- insn_num_uops = (int) path;
-
- /* If current window is full, get a new window.
- Window number zero is full, if MAX_INSN uops are scheduled in it.
- Window number one is full, if window zero's bytes plus window
- one's bytes is 32, or if the bytes of the new instruction added
- to the total makes it greater than 48, or it has already MAX_INSN
- instructions in it. */
- num_insn = window_list->num_insn;
- num_uops = window_list->num_uops;
- window_num = window_list->window_num;
- insn_fits = fits_dispatch_window (insn);
-
- if (num_insn >= MAX_INSN
- || num_uops + insn_num_uops > MAX_INSN
- || !(insn_fits))
- {
- window_num = ~window_num & 1;
- window_list = allocate_next_window (window_num);
- }
-
- if (window_num == 0)
- {
- add_insn_window (insn, window_list, insn_num_uops);
- if (window_list->num_insn >= MAX_INSN
- && insn_group == disp_branch)
- {
- process_end_window ();
- return;
- }
- }
- else if (window_num == 1)
- {
- window0_list = window_list->prev;
- sum = window0_list->window_size + window_list->window_size;
- if (sum == 32
- || (byte_len + sum) >= 48)
- {
- process_end_window ();
- window_list = dispatch_window_list;
- }
-
- add_insn_window (insn, window_list, insn_num_uops);
- }
- else
- gcc_unreachable ();
-
- if (is_end_basic_block (insn_group))
- {
- /* End of basic block is reached do end-basic-block process. */
- process_end_window ();
- return;
- }
-}
-
-/* Print the dispatch window, WINDOW_NUM, to FILE. */
-
-DEBUG_FUNCTION static void
-debug_dispatch_window_file (FILE *file, int window_num)
-{
- dispatch_windows *list;
- int i;
-
- if (window_num == 0)
- list = dispatch_window_list;
- else
- list = dispatch_window_list1;
-
- fprintf (file, "Window #%d:\n", list->window_num);
- fprintf (file, " num_insn = %d, num_uops = %d, window_size = %d\n",
- list->num_insn, list->num_uops, list->window_size);
- fprintf (file, " num_imm = %d, num_imm_32 = %d, num_imm_64 = %d, imm_size = %d\n",
- list->num_imm, list->num_imm_32, list->num_imm_64, list->imm_size);
-
- fprintf (file, " num_loads = %d, num_stores = %d\n", list->num_loads,
- list->num_stores);
- fprintf (file, " insn info:\n");
-
- for (i = 0; i < MAX_INSN; i++)
- {
- if (!list->window[i].insn)
- break;
- fprintf (file, " group[%d] = %s, insn[%d] = %p, path[%d] = %d byte_len[%d] = %d, imm_bytes[%d] = %d\n",
- i, group_name[list->window[i].group],
- i, (void *)list->window[i].insn,
- i, list->window[i].path,
- i, list->window[i].byte_len,
- i, list->window[i].imm_bytes);
- }
-}
-
-/* Print to stdout a dispatch window. */
-
-DEBUG_FUNCTION void
-debug_dispatch_window (int window_num)
-{
- debug_dispatch_window_file (stdout, window_num);
-}
-
-/* Print INSN dispatch information to FILE. */
-
-DEBUG_FUNCTION static void
-debug_insn_dispatch_info_file (FILE *file, rtx insn)
-{
- int byte_len;
- enum insn_path path;
- enum dispatch_group group;
- int imm_size;
- int num_imm_operand;
- int num_imm32_operand;
- int num_imm64_operand;
-
- if (INSN_CODE (insn) < 0)
- return;
-
- byte_len = min_insn_size (insn);
- path = get_insn_path (insn);
- group = get_insn_group (insn);
- imm_size = get_num_immediates (insn, &num_imm_operand, &num_imm32_operand,
- &num_imm64_operand);
-
- fprintf (file, " insn info:\n");
- fprintf (file, " group = %s, path = %d, byte_len = %d\n",
- group_name[group], path, byte_len);
- fprintf (file, " num_imm = %d, num_imm_32 = %d, num_imm_64 = %d, imm_size = %d\n",
- num_imm_operand, num_imm32_operand, num_imm64_operand, imm_size);
-}
-
-/* Print to STDERR the status of the ready list with respect to
- dispatch windows. */
-
-DEBUG_FUNCTION void
-debug_ready_dispatch (void)
-{
- int i;
- int no_ready = number_in_ready ();
-
- fprintf (stdout, "Number of ready: %d\n", no_ready);
-
- for (i = 0; i < no_ready; i++)
- debug_insn_dispatch_info_file (stdout, get_ready_element (i));
-}
-
-/* This routine is the driver of the dispatch scheduler. */
-
-static void
-do_dispatch (rtx insn, int mode)
-{
- if (mode == DISPATCH_INIT)
- init_dispatch_sched ();
- else if (mode == ADD_TO_DISPATCH_WINDOW)
- add_to_dispatch_window (insn);
-}
-
-/* Return TRUE if Dispatch Scheduling is supported. */
-
-static bool
-has_dispatch (rtx insn, int action)
-{
- if ((TARGET_BDVER1 || TARGET_BDVER2 || TARGET_BDVER3)
- && flag_dispatch_scheduler)
- switch (action)
- {
- default:
- return false;
-
- case IS_DISPATCH_ON:
- return true;
- break;
-
- case IS_CMP:
- return is_cmp (insn);
-
- case DISPATCH_VIOLATION:
- return dispatch_violation ();
-
- case FITS_DISPATCH_WINDOW:
- return fits_dispatch_window (insn);
- }
-
- return false;
-}
-
-/* Implementation of reassociation_width target hook used by
- reassoc phase to identify parallelism level in reassociated
- tree. Statements tree_code is passed in OPC. Arguments type
- is passed in MODE.
-
- Currently parallel reassociation is enabled for Atom
- processors only and we set reassociation width to be 2
- because Atom may issue up to 2 instructions per cycle.
-
- Return value should be fixed if parallel reassociation is
- enabled for other processors. */
-
-static int
-ix86_reassociation_width (unsigned int opc ATTRIBUTE_UNUSED,
- enum machine_mode mode)
-{
- int res = 1;
-
- if (INTEGRAL_MODE_P (mode) && TARGET_REASSOC_INT_TO_PARALLEL)
- res = 2;
- else if (FLOAT_MODE_P (mode) && TARGET_REASSOC_FP_TO_PARALLEL)
- res = 2;
-
- return res;
-}
-
-/* ??? No autovectorization into MMX or 3DNOW until we can reliably
- place emms and femms instructions. */
-
-static enum machine_mode
-ix86_preferred_simd_mode (enum machine_mode mode)
-{
- if (!TARGET_SSE)
- return word_mode;
-
- switch (mode)
- {
- case QImode:
- return (TARGET_AVX && !TARGET_PREFER_AVX128) ? V32QImode : V16QImode;
- case HImode:
- return (TARGET_AVX && !TARGET_PREFER_AVX128) ? V16HImode : V8HImode;
- case SImode:
- return (TARGET_AVX && !TARGET_PREFER_AVX128) ? V8SImode : V4SImode;
- case DImode:
- return (TARGET_AVX && !TARGET_PREFER_AVX128) ? V4DImode : V2DImode;
-
- case SFmode:
- if (TARGET_AVX && !TARGET_PREFER_AVX128)
- return V8SFmode;
- else
- return V4SFmode;
-
- case DFmode:
- if (!TARGET_VECTORIZE_DOUBLE)
- return word_mode;
- else if (TARGET_AVX && !TARGET_PREFER_AVX128)
- return V4DFmode;
- else if (TARGET_SSE2)
- return V2DFmode;
- /* FALLTHRU */
-
- default:
- return word_mode;
- }
-}
-
-/* If AVX is enabled then try vectorizing with both 256bit and 128bit
- vectors. */
-
-static unsigned int
-ix86_autovectorize_vector_sizes (void)
-{
- return (TARGET_AVX && !TARGET_PREFER_AVX128) ? 32 | 16 : 0;
-}
-
-
-
-/* Return class of registers which could be used for pseudo of MODE
- and of class RCLASS for spilling instead of memory. Return NO_REGS
- if it is not possible or non-profitable. */
-static reg_class_t
-ix86_spill_class (reg_class_t rclass, enum machine_mode mode)
-{
- if (TARGET_SSE && TARGET_GENERAL_REGS_SSE_SPILL && ! TARGET_MMX
- && (mode == SImode || (TARGET_64BIT && mode == DImode))
- && INTEGER_CLASS_P (rclass))
- return SSE_REGS;
- return NO_REGS;
-}
-
-/* Implement targetm.vectorize.init_cost. */
-
-static void *
-ix86_init_cost (struct loop *loop_info ATTRIBUTE_UNUSED)
-{
- unsigned *cost = XNEWVEC (unsigned, 3);
- cost[vect_prologue] = cost[vect_body] = cost[vect_epilogue] = 0;
- return cost;
-}
-
-/* Implement targetm.vectorize.add_stmt_cost. */
-
-static unsigned
-ix86_add_stmt_cost (void *data, int count, enum vect_cost_for_stmt kind,
- struct _stmt_vec_info *stmt_info, int misalign,
- enum vect_cost_model_location where)
-{
- unsigned *cost = (unsigned *) data;
- unsigned retval = 0;
-
- if (flag_vect_cost_model)
- {
- tree vectype = stmt_info ? stmt_vectype (stmt_info) : NULL_TREE;
- int stmt_cost = ix86_builtin_vectorization_cost (kind, vectype, misalign);
-
- /* Statements in an inner loop relative to the loop being
- vectorized are weighted more heavily. The value here is
- arbitrary and could potentially be improved with analysis. */
- if (where == vect_body && stmt_info && stmt_in_inner_loop_p (stmt_info))
- count *= 50; /* FIXME. */
-
- retval = (unsigned) (count * stmt_cost);
- cost[where] += retval;
- }
-
- return retval;
-}
-
-/* Implement targetm.vectorize.finish_cost. */
-
-static void
-ix86_finish_cost (void *data, unsigned *prologue_cost,
- unsigned *body_cost, unsigned *epilogue_cost)
-{
- unsigned *cost = (unsigned *) data;
- *prologue_cost = cost[vect_prologue];
- *body_cost = cost[vect_body];
- *epilogue_cost = cost[vect_epilogue];
-}
-
-/* Implement targetm.vectorize.destroy_cost_data. */
-
-static void
-ix86_destroy_cost_data (void *data)
-{
- free (data);
-}
-
-/* Validate target specific memory model bits in VAL. */
-
-static unsigned HOST_WIDE_INT
-ix86_memmodel_check (unsigned HOST_WIDE_INT val)
-{
- unsigned HOST_WIDE_INT model = val & MEMMODEL_MASK;
- bool strong;
-
- if (val & ~(unsigned HOST_WIDE_INT)(IX86_HLE_ACQUIRE|IX86_HLE_RELEASE
- |MEMMODEL_MASK)
- || ((val & IX86_HLE_ACQUIRE) && (val & IX86_HLE_RELEASE)))
- {
- warning (OPT_Winvalid_memory_model,
- "Unknown architecture specific memory model");
- return MEMMODEL_SEQ_CST;
- }
- strong = (model == MEMMODEL_ACQ_REL || model == MEMMODEL_SEQ_CST);
- if (val & IX86_HLE_ACQUIRE && !(model == MEMMODEL_ACQUIRE || strong))
- {
- warning (OPT_Winvalid_memory_model,
- "HLE_ACQUIRE not used with ACQUIRE or stronger memory model");
- return MEMMODEL_SEQ_CST | IX86_HLE_ACQUIRE;
- }
- if (val & IX86_HLE_RELEASE && !(model == MEMMODEL_RELEASE || strong))
- {
- warning (OPT_Winvalid_memory_model,
- "HLE_RELEASE not used with RELEASE or stronger memory model");
- return MEMMODEL_SEQ_CST | IX86_HLE_RELEASE;
- }
- return val;
-}
-
-/* Initialize the GCC target structure. */
-#undef TARGET_RETURN_IN_MEMORY
-#define TARGET_RETURN_IN_MEMORY ix86_return_in_memory
-
-#undef TARGET_LEGITIMIZE_ADDRESS
-#define TARGET_LEGITIMIZE_ADDRESS ix86_legitimize_address
-
-#undef TARGET_ATTRIBUTE_TABLE
-#define TARGET_ATTRIBUTE_TABLE ix86_attribute_table
-#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
-# undef TARGET_MERGE_DECL_ATTRIBUTES
-# define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes
-#endif
-
-#undef TARGET_COMP_TYPE_ATTRIBUTES
-#define TARGET_COMP_TYPE_ATTRIBUTES ix86_comp_type_attributes
-
-#undef TARGET_INIT_BUILTINS
-#define TARGET_INIT_BUILTINS ix86_init_builtins
-#undef TARGET_BUILTIN_DECL
-#define TARGET_BUILTIN_DECL ix86_builtin_decl
-#undef TARGET_EXPAND_BUILTIN
-#define TARGET_EXPAND_BUILTIN ix86_expand_builtin
-
-#undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
-#define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
- ix86_builtin_vectorized_function
-
-#undef TARGET_VECTORIZE_BUILTIN_TM_LOAD
-#define TARGET_VECTORIZE_BUILTIN_TM_LOAD ix86_builtin_tm_load
-
-#undef TARGET_VECTORIZE_BUILTIN_TM_STORE
-#define TARGET_VECTORIZE_BUILTIN_TM_STORE ix86_builtin_tm_store
-
-#undef TARGET_VECTORIZE_BUILTIN_GATHER
-#define TARGET_VECTORIZE_BUILTIN_GATHER ix86_vectorize_builtin_gather
-
-#undef TARGET_BUILTIN_RECIPROCAL
-#define TARGET_BUILTIN_RECIPROCAL ix86_builtin_reciprocal
-
-#undef TARGET_ASM_FUNCTION_EPILOGUE
-#define TARGET_ASM_FUNCTION_EPILOGUE ix86_output_function_epilogue
-
-#undef TARGET_ENCODE_SECTION_INFO
-#ifndef SUBTARGET_ENCODE_SECTION_INFO
-#define TARGET_ENCODE_SECTION_INFO ix86_encode_section_info
-#else
-#define TARGET_ENCODE_SECTION_INFO SUBTARGET_ENCODE_SECTION_INFO
-#endif
-
-#undef TARGET_ASM_OPEN_PAREN
-#define TARGET_ASM_OPEN_PAREN ""
-#undef TARGET_ASM_CLOSE_PAREN
-#define TARGET_ASM_CLOSE_PAREN ""
-
-#undef TARGET_ASM_BYTE_OP
-#define TARGET_ASM_BYTE_OP ASM_BYTE
-
-#undef TARGET_ASM_ALIGNED_HI_OP
-#define TARGET_ASM_ALIGNED_HI_OP ASM_SHORT
-#undef TARGET_ASM_ALIGNED_SI_OP
-#define TARGET_ASM_ALIGNED_SI_OP ASM_LONG
-#ifdef ASM_QUAD
-#undef TARGET_ASM_ALIGNED_DI_OP
-#define TARGET_ASM_ALIGNED_DI_OP ASM_QUAD
-#endif
-
-#undef TARGET_PROFILE_BEFORE_PROLOGUE
-#define TARGET_PROFILE_BEFORE_PROLOGUE ix86_profile_before_prologue
-
-#undef TARGET_MANGLE_DECL_ASSEMBLER_NAME
-#define TARGET_MANGLE_DECL_ASSEMBLER_NAME ix86_mangle_decl_assembler_name
-
-#undef TARGET_ASM_UNALIGNED_HI_OP
-#define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
-#undef TARGET_ASM_UNALIGNED_SI_OP
-#define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
-#undef TARGET_ASM_UNALIGNED_DI_OP
-#define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
-
-#undef TARGET_PRINT_OPERAND
-#define TARGET_PRINT_OPERAND ix86_print_operand
-#undef TARGET_PRINT_OPERAND_ADDRESS
-#define TARGET_PRINT_OPERAND_ADDRESS ix86_print_operand_address
-#undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
-#define TARGET_PRINT_OPERAND_PUNCT_VALID_P ix86_print_operand_punct_valid_p
-#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
-#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA i386_asm_output_addr_const_extra
-
-#undef TARGET_SCHED_INIT_GLOBAL
-#define TARGET_SCHED_INIT_GLOBAL ix86_sched_init_global
-#undef TARGET_SCHED_ADJUST_COST
-#define TARGET_SCHED_ADJUST_COST ix86_adjust_cost
-#undef TARGET_SCHED_ISSUE_RATE
-#define TARGET_SCHED_ISSUE_RATE ix86_issue_rate
-#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
-#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
- ia32_multipass_dfa_lookahead
-
-#undef TARGET_FUNCTION_OK_FOR_SIBCALL
-#define TARGET_FUNCTION_OK_FOR_SIBCALL ix86_function_ok_for_sibcall
-
-#undef TARGET_MEMMODEL_CHECK
-#define TARGET_MEMMODEL_CHECK ix86_memmodel_check
-
-#ifdef HAVE_AS_TLS
-#undef TARGET_HAVE_TLS
-#define TARGET_HAVE_TLS true
-#endif
-#undef TARGET_CANNOT_FORCE_CONST_MEM
-#define TARGET_CANNOT_FORCE_CONST_MEM ix86_cannot_force_const_mem
-#undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
-#define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true
-
-#undef TARGET_DELEGITIMIZE_ADDRESS
-#define TARGET_DELEGITIMIZE_ADDRESS ix86_delegitimize_address
-
-#undef TARGET_MS_BITFIELD_LAYOUT_P
-#define TARGET_MS_BITFIELD_LAYOUT_P ix86_ms_bitfield_layout_p
-
-#if TARGET_MACHO
-#undef TARGET_BINDS_LOCAL_P
-#define TARGET_BINDS_LOCAL_P darwin_binds_local_p
-#endif
-#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
-#undef TARGET_BINDS_LOCAL_P
-#define TARGET_BINDS_LOCAL_P i386_pe_binds_local_p
-#endif
-
-#undef TARGET_ASM_OUTPUT_MI_THUNK
-#define TARGET_ASM_OUTPUT_MI_THUNK x86_output_mi_thunk
-#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
-#define TARGET_ASM_CAN_OUTPUT_MI_THUNK x86_can_output_mi_thunk
-
-#undef TARGET_ASM_FILE_START
-#define TARGET_ASM_FILE_START x86_file_start
-
-#undef TARGET_OPTION_OVERRIDE
-#define TARGET_OPTION_OVERRIDE ix86_option_override
-
-#undef TARGET_REGISTER_MOVE_COST
-#define TARGET_REGISTER_MOVE_COST ix86_register_move_cost
-#undef TARGET_MEMORY_MOVE_COST
-#define TARGET_MEMORY_MOVE_COST ix86_memory_move_cost
-#undef TARGET_RTX_COSTS
-#define TARGET_RTX_COSTS ix86_rtx_costs
-#undef TARGET_ADDRESS_COST
-#define TARGET_ADDRESS_COST ix86_address_cost
-
-#undef TARGET_FIXED_CONDITION_CODE_REGS
-#define TARGET_FIXED_CONDITION_CODE_REGS ix86_fixed_condition_code_regs
-#undef TARGET_CC_MODES_COMPATIBLE
-#define TARGET_CC_MODES_COMPATIBLE ix86_cc_modes_compatible
-
-#undef TARGET_MACHINE_DEPENDENT_REORG
-#define TARGET_MACHINE_DEPENDENT_REORG ix86_reorg
-
-#undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
-#define TARGET_BUILTIN_SETJMP_FRAME_VALUE ix86_builtin_setjmp_frame_value
-
-#undef TARGET_BUILD_BUILTIN_VA_LIST
-#define TARGET_BUILD_BUILTIN_VA_LIST ix86_build_builtin_va_list
-
-#undef TARGET_FOLD_BUILTIN
-#define TARGET_FOLD_BUILTIN ix86_fold_builtin
-
-#undef TARGET_COMPARE_VERSION_PRIORITY
-#define TARGET_COMPARE_VERSION_PRIORITY ix86_compare_version_priority
-
-#undef TARGET_GENERATE_VERSION_DISPATCHER_BODY
-#define TARGET_GENERATE_VERSION_DISPATCHER_BODY \
- ix86_generate_version_dispatcher_body
-
-#undef TARGET_GET_FUNCTION_VERSIONS_DISPATCHER
-#define TARGET_GET_FUNCTION_VERSIONS_DISPATCHER \
- ix86_get_function_versions_dispatcher
-
-#undef TARGET_ENUM_VA_LIST_P
-#define TARGET_ENUM_VA_LIST_P ix86_enum_va_list
-
-#undef TARGET_FN_ABI_VA_LIST
-#define TARGET_FN_ABI_VA_LIST ix86_fn_abi_va_list
-
-#undef TARGET_CANONICAL_VA_LIST_TYPE
-#define TARGET_CANONICAL_VA_LIST_TYPE ix86_canonical_va_list_type
-
-#undef TARGET_EXPAND_BUILTIN_VA_START
-#define TARGET_EXPAND_BUILTIN_VA_START ix86_va_start
-
-#undef TARGET_MD_ASM_CLOBBERS
-#define TARGET_MD_ASM_CLOBBERS ix86_md_asm_clobbers
-
-#undef TARGET_PROMOTE_PROTOTYPES
-#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
-#undef TARGET_STRUCT_VALUE_RTX
-#define TARGET_STRUCT_VALUE_RTX ix86_struct_value_rtx
-#undef TARGET_SETUP_INCOMING_VARARGS
-#define TARGET_SETUP_INCOMING_VARARGS ix86_setup_incoming_varargs
-#undef TARGET_MUST_PASS_IN_STACK
-#define TARGET_MUST_PASS_IN_STACK ix86_must_pass_in_stack
-#undef TARGET_FUNCTION_ARG_ADVANCE
-#define TARGET_FUNCTION_ARG_ADVANCE ix86_function_arg_advance
-#undef TARGET_FUNCTION_ARG
-#define TARGET_FUNCTION_ARG ix86_function_arg
-#undef TARGET_FUNCTION_ARG_BOUNDARY
-#define TARGET_FUNCTION_ARG_BOUNDARY ix86_function_arg_boundary
-#undef TARGET_PASS_BY_REFERENCE
-#define TARGET_PASS_BY_REFERENCE ix86_pass_by_reference
-#undef TARGET_INTERNAL_ARG_POINTER
-#define TARGET_INTERNAL_ARG_POINTER ix86_internal_arg_pointer
-#undef TARGET_UPDATE_STACK_BOUNDARY
-#define TARGET_UPDATE_STACK_BOUNDARY ix86_update_stack_boundary
-#undef TARGET_GET_DRAP_RTX
-#define TARGET_GET_DRAP_RTX ix86_get_drap_rtx
-#undef TARGET_STRICT_ARGUMENT_NAMING
-#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
-#undef TARGET_STATIC_CHAIN
-#define TARGET_STATIC_CHAIN ix86_static_chain
-#undef TARGET_TRAMPOLINE_INIT
-#define TARGET_TRAMPOLINE_INIT ix86_trampoline_init
-#undef TARGET_RETURN_POPS_ARGS
-#define TARGET_RETURN_POPS_ARGS ix86_return_pops_args
-
-#undef TARGET_LEGITIMATE_COMBINED_INSN
-#define TARGET_LEGITIMATE_COMBINED_INSN ix86_legitimate_combined_insn
-
-#undef TARGET_ASAN_SHADOW_OFFSET
-#define TARGET_ASAN_SHADOW_OFFSET ix86_asan_shadow_offset
-
-#undef TARGET_GIMPLIFY_VA_ARG_EXPR
-#define TARGET_GIMPLIFY_VA_ARG_EXPR ix86_gimplify_va_arg
-
-#undef TARGET_SCALAR_MODE_SUPPORTED_P
-#define TARGET_SCALAR_MODE_SUPPORTED_P ix86_scalar_mode_supported_p
-
-#undef TARGET_VECTOR_MODE_SUPPORTED_P
-#define TARGET_VECTOR_MODE_SUPPORTED_P ix86_vector_mode_supported_p
-
-#undef TARGET_C_MODE_FOR_SUFFIX
-#define TARGET_C_MODE_FOR_SUFFIX ix86_c_mode_for_suffix
-
-#ifdef HAVE_AS_TLS
-#undef TARGET_ASM_OUTPUT_DWARF_DTPREL
-#define TARGET_ASM_OUTPUT_DWARF_DTPREL i386_output_dwarf_dtprel
-#endif
-
-#ifdef SUBTARGET_INSERT_ATTRIBUTES
-#undef TARGET_INSERT_ATTRIBUTES
-#define TARGET_INSERT_ATTRIBUTES SUBTARGET_INSERT_ATTRIBUTES
-#endif
-
-#undef TARGET_MANGLE_TYPE
-#define TARGET_MANGLE_TYPE ix86_mangle_type
-
-#if !TARGET_MACHO
-#undef TARGET_STACK_PROTECT_FAIL
-#define TARGET_STACK_PROTECT_FAIL ix86_stack_protect_fail
-#endif
-
-#undef TARGET_FUNCTION_VALUE
-#define TARGET_FUNCTION_VALUE ix86_function_value
-
-#undef TARGET_FUNCTION_VALUE_REGNO_P
-#define TARGET_FUNCTION_VALUE_REGNO_P ix86_function_value_regno_p
-
-#undef TARGET_PROMOTE_FUNCTION_MODE
-#define TARGET_PROMOTE_FUNCTION_MODE ix86_promote_function_mode
-
-#undef TARGET_MEMBER_TYPE_FORCES_BLK
-#define TARGET_MEMBER_TYPE_FORCES_BLK ix86_member_type_forces_blk
-
-#undef TARGET_INSTANTIATE_DECLS
-#define TARGET_INSTANTIATE_DECLS ix86_instantiate_decls
-
-#undef TARGET_SECONDARY_RELOAD
-#define TARGET_SECONDARY_RELOAD ix86_secondary_reload
-
-#undef TARGET_CLASS_MAX_NREGS
-#define TARGET_CLASS_MAX_NREGS ix86_class_max_nregs
-
-#undef TARGET_PREFERRED_RELOAD_CLASS
-#define TARGET_PREFERRED_RELOAD_CLASS ix86_preferred_reload_class
-#undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
-#define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS ix86_preferred_output_reload_class
-#undef TARGET_CLASS_LIKELY_SPILLED_P
-#define TARGET_CLASS_LIKELY_SPILLED_P ix86_class_likely_spilled_p
-
-#undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
-#define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
- ix86_builtin_vectorization_cost
-#undef TARGET_VECTORIZE_VEC_PERM_CONST_OK
-#define TARGET_VECTORIZE_VEC_PERM_CONST_OK \
- ix86_vectorize_vec_perm_const_ok
-#undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
-#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
- ix86_preferred_simd_mode
-#undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES
-#define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES \
- ix86_autovectorize_vector_sizes
-#undef TARGET_VECTORIZE_INIT_COST
-#define TARGET_VECTORIZE_INIT_COST ix86_init_cost
-#undef TARGET_VECTORIZE_ADD_STMT_COST
-#define TARGET_VECTORIZE_ADD_STMT_COST ix86_add_stmt_cost
-#undef TARGET_VECTORIZE_FINISH_COST
-#define TARGET_VECTORIZE_FINISH_COST ix86_finish_cost
-#undef TARGET_VECTORIZE_DESTROY_COST_DATA
-#define TARGET_VECTORIZE_DESTROY_COST_DATA ix86_destroy_cost_data
-
-#undef TARGET_SET_CURRENT_FUNCTION
-#define TARGET_SET_CURRENT_FUNCTION ix86_set_current_function
-
-#undef TARGET_OPTION_VALID_ATTRIBUTE_P
-#define TARGET_OPTION_VALID_ATTRIBUTE_P ix86_valid_target_attribute_p
-
-#undef TARGET_OPTION_SAVE
-#define TARGET_OPTION_SAVE ix86_function_specific_save
-
-#undef TARGET_OPTION_RESTORE
-#define TARGET_OPTION_RESTORE ix86_function_specific_restore
-
-#undef TARGET_OPTION_PRINT
-#define TARGET_OPTION_PRINT ix86_function_specific_print
-
-#undef TARGET_OPTION_FUNCTION_VERSIONS
-#define TARGET_OPTION_FUNCTION_VERSIONS ix86_function_versions
-
-#undef TARGET_CAN_INLINE_P
-#define TARGET_CAN_INLINE_P ix86_can_inline_p
-
-#undef TARGET_EXPAND_TO_RTL_HOOK
-#define TARGET_EXPAND_TO_RTL_HOOK ix86_maybe_switch_abi
-
-#undef TARGET_LEGITIMATE_ADDRESS_P
-#define TARGET_LEGITIMATE_ADDRESS_P ix86_legitimate_address_p
-
-#undef TARGET_LRA_P
-#define TARGET_LRA_P hook_bool_void_true
-
-#undef TARGET_REGISTER_PRIORITY
-#define TARGET_REGISTER_PRIORITY ix86_register_priority
-
-#undef TARGET_LEGITIMATE_CONSTANT_P
-#define TARGET_LEGITIMATE_CONSTANT_P ix86_legitimate_constant_p
-
-#undef TARGET_FRAME_POINTER_REQUIRED
-#define TARGET_FRAME_POINTER_REQUIRED ix86_frame_pointer_required
-
-#undef TARGET_CAN_ELIMINATE
-#define TARGET_CAN_ELIMINATE ix86_can_eliminate
-
-#undef TARGET_EXTRA_LIVE_ON_ENTRY
-#define TARGET_EXTRA_LIVE_ON_ENTRY ix86_live_on_entry
-
-#undef TARGET_ASM_CODE_END
-#define TARGET_ASM_CODE_END ix86_code_end
-
-#undef TARGET_CONDITIONAL_REGISTER_USAGE
-#define TARGET_CONDITIONAL_REGISTER_USAGE ix86_conditional_register_usage
-
-#if TARGET_MACHO
-#undef TARGET_INIT_LIBFUNCS
-#define TARGET_INIT_LIBFUNCS darwin_rename_builtins
-#endif
-
-#undef TARGET_SPILL_CLASS
-#define TARGET_SPILL_CLASS ix86_spill_class
-
-struct gcc_target targetm = TARGET_INITIALIZER;
-
-#include "gt-i386.h"
diff --git a/gcc-4.8/gcc/config/i386/i386.md.orig b/gcc-4.8/gcc/config/i386/i386.md.orig
deleted file mode 100644
index db71dfb0d..000000000
--- a/gcc-4.8/gcc/config/i386/i386.md.orig
+++ /dev/null
@@ -1,18173 +0,0 @@
-;; GCC machine description for IA-32 and x86-64.
-;; Copyright (C) 1988-2013 Free Software Foundation, Inc.
-;; Mostly by William Schelter.
-;; x86_64 support added by Jan Hubicka
-;;
-;; This file is part of GCC.
-;;
-;; GCC is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
-;;
-;; GCC is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with GCC; see the file COPYING3. If not see
-;; <http://www.gnu.org/licenses/>. */
-;;
-;; The original PO technology requires these to be ordered by speed,
-;; so that assigner will pick the fastest.
-;;
-;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
-;;
-;; The special asm out single letter directives following a '%' are:
-;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
-;; C -- print opcode suffix for set/cmov insn.
-;; c -- like C, but print reversed condition
-;; F,f -- likewise, but for floating-point.
-;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
-;; otherwise nothing
-;; R -- print the prefix for register names.
-;; z -- print the opcode suffix for the size of the current operand.
-;; Z -- likewise, with special suffixes for x87 instructions.
-;; * -- print a star (in certain assembler syntax)
-;; A -- print an absolute memory reference.
-;; E -- print address with DImode register names if TARGET_64BIT.
-;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
-;; s -- print a shift double count, followed by the assemblers argument
-;; delimiter.
-;; b -- print the QImode name of the register for the indicated operand.
-;; %b0 would print %al if operands[0] is reg 0.
-;; w -- likewise, print the HImode name of the register.
-;; k -- likewise, print the SImode name of the register.
-;; q -- likewise, print the DImode name of the register.
-;; x -- likewise, print the V4SFmode name of the register.
-;; t -- likewise, print the V8SFmode name of the register.
-;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
-;; y -- print "st(0)" instead of "st" as a register.
-;; d -- print duplicated register operand for AVX instruction.
-;; D -- print condition for SSE cmp instruction.
-;; P -- if PIC, print an @PLT suffix.
-;; p -- print raw symbol name.
-;; X -- don't print any sort of PIC '@' suffix for a symbol.
-;; & -- print some in-use local-dynamic symbol name.
-;; H -- print a memory address offset by 8; used for sse high-parts
-;; K -- print HLE lock prefix
-;; Y -- print condition for XOP pcom* instruction.
-;; + -- print a branch hint as 'cs' or 'ds' prefix
-;; ; -- print a semicolon (after prefixes due to bug in older gas).
-;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
-;; @ -- print a segment register of thread base pointer load
-;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
-
-(define_c_enum "unspec" [
- ;; Relocation specifiers
- UNSPEC_GOT
- UNSPEC_GOTOFF
- UNSPEC_GOTPCREL
- UNSPEC_GOTTPOFF
- UNSPEC_TPOFF
- UNSPEC_NTPOFF
- UNSPEC_DTPOFF
- UNSPEC_GOTNTPOFF
- UNSPEC_INDNTPOFF
- UNSPEC_PLTOFF
- UNSPEC_MACHOPIC_OFFSET
- UNSPEC_PCREL
-
- ;; Prologue support
- UNSPEC_STACK_ALLOC
- UNSPEC_SET_GOT
- UNSPEC_SET_RIP
- UNSPEC_SET_GOT_OFFSET
- UNSPEC_MEMORY_BLOCKAGE
- UNSPEC_STACK_CHECK
-
- ;; TLS support
- UNSPEC_TP
- UNSPEC_TLS_GD
- UNSPEC_TLS_LD_BASE
- UNSPEC_TLSDESC
- UNSPEC_TLS_IE_SUN
-
- ;; Other random patterns
- UNSPEC_SCAS
- UNSPEC_FNSTSW
- UNSPEC_SAHF
- UNSPEC_PARITY
- UNSPEC_FSTCW
- UNSPEC_ADD_CARRY
- UNSPEC_FLDCW
- UNSPEC_REP
- UNSPEC_LD_MPIC ; load_macho_picbase
- UNSPEC_TRUNC_NOOP
- UNSPEC_DIV_ALREADY_SPLIT
- UNSPEC_MS_TO_SYSV_CALL
- UNSPEC_PAUSE
- UNSPEC_LEA_ADDR
- UNSPEC_XBEGIN_ABORT
- UNSPEC_STOS
-
- ;; For SSE/MMX support:
- UNSPEC_FIX_NOTRUNC
- UNSPEC_MASKMOV
- UNSPEC_MOVMSK
- UNSPEC_RCP
- UNSPEC_RSQRT
- UNSPEC_PSADBW
-
- ;; Generic math support
- UNSPEC_COPYSIGN
- UNSPEC_IEEE_MIN ; not commutative
- UNSPEC_IEEE_MAX ; not commutative
-
- ;; x87 Floating point
- UNSPEC_SIN
- UNSPEC_COS
- UNSPEC_FPATAN
- UNSPEC_FYL2X
- UNSPEC_FYL2XP1
- UNSPEC_FRNDINT
- UNSPEC_FIST
- UNSPEC_F2XM1
- UNSPEC_TAN
- UNSPEC_FXAM
-
- ;; x87 Rounding
- UNSPEC_FRNDINT_FLOOR
- UNSPEC_FRNDINT_CEIL
- UNSPEC_FRNDINT_TRUNC
- UNSPEC_FRNDINT_MASK_PM
- UNSPEC_FIST_FLOOR
- UNSPEC_FIST_CEIL
-
- ;; x87 Double output FP
- UNSPEC_SINCOS_COS
- UNSPEC_SINCOS_SIN
- UNSPEC_XTRACT_FRACT
- UNSPEC_XTRACT_EXP
- UNSPEC_FSCALE_FRACT
- UNSPEC_FSCALE_EXP
- UNSPEC_FPREM_F
- UNSPEC_FPREM_U
- UNSPEC_FPREM1_F
- UNSPEC_FPREM1_U
-
- UNSPEC_C2_FLAG
- UNSPEC_FXAM_MEM
-
- ;; SSP patterns
- UNSPEC_SP_SET
- UNSPEC_SP_TEST
- UNSPEC_SP_TLS_SET
- UNSPEC_SP_TLS_TEST
-
- ;; For ROUND support
- UNSPEC_ROUND
-
- ;; For CRC32 support
- UNSPEC_CRC32
-
- ;; For BMI support
- UNSPEC_BEXTR
-
- ;; For BMI2 support
- UNSPEC_PDEP
- UNSPEC_PEXT
-])
-
-(define_c_enum "unspecv" [
- UNSPECV_BLOCKAGE
- UNSPECV_STACK_PROBE
- UNSPECV_PROBE_STACK_RANGE
- UNSPECV_ALIGN
- UNSPECV_PROLOGUE_USE
- UNSPECV_SPLIT_STACK_RETURN
- UNSPECV_CLD
- UNSPECV_NOPS
- UNSPECV_RDTSC
- UNSPECV_RDTSCP
- UNSPECV_RDPMC
- UNSPECV_LLWP_INTRINSIC
- UNSPECV_SLWP_INTRINSIC
- UNSPECV_LWPVAL_INTRINSIC
- UNSPECV_LWPINS_INTRINSIC
- UNSPECV_RDFSBASE
- UNSPECV_RDGSBASE
- UNSPECV_WRFSBASE
- UNSPECV_WRGSBASE
- UNSPECV_FXSAVE
- UNSPECV_FXRSTOR
- UNSPECV_FXSAVE64
- UNSPECV_FXRSTOR64
- UNSPECV_XSAVE
- UNSPECV_XRSTOR
- UNSPECV_XSAVE64
- UNSPECV_XRSTOR64
- UNSPECV_XSAVEOPT
- UNSPECV_XSAVEOPT64
-
- ;; For RDRAND support
- UNSPECV_RDRAND
-
- ;; For RDSEED support
- UNSPECV_RDSEED
-
- ;; For RTM support
- UNSPECV_XBEGIN
- UNSPECV_XEND
- UNSPECV_XABORT
- UNSPECV_XTEST
-])
-
-;; Constants to represent rounding modes in the ROUND instruction
-(define_constants
- [(ROUND_FLOOR 0x1)
- (ROUND_CEIL 0x2)
- (ROUND_TRUNC 0x3)
- (ROUND_MXCSR 0x4)
- (ROUND_NO_EXC 0x8)
- ])
-
-;; Constants to represent pcomtrue/pcomfalse variants
-(define_constants
- [(PCOM_FALSE 0)
- (PCOM_TRUE 1)
- (COM_FALSE_S 2)
- (COM_FALSE_P 3)
- (COM_TRUE_S 4)
- (COM_TRUE_P 5)
- ])
-
-;; Constants used in the XOP pperm instruction
-(define_constants
- [(PPERM_SRC 0x00) /* copy source */
- (PPERM_INVERT 0x20) /* invert source */
- (PPERM_REVERSE 0x40) /* bit reverse source */
- (PPERM_REV_INV 0x60) /* bit reverse & invert src */
- (PPERM_ZERO 0x80) /* all 0's */
- (PPERM_ONES 0xa0) /* all 1's */
- (PPERM_SIGN 0xc0) /* propagate sign bit */
- (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
- (PPERM_SRC1 0x00) /* use first source byte */
- (PPERM_SRC2 0x10) /* use second source byte */
- ])
-
-;; Registers by name.
-(define_constants
- [(AX_REG 0)
- (DX_REG 1)
- (CX_REG 2)
- (BX_REG 3)
- (SI_REG 4)
- (DI_REG 5)
- (BP_REG 6)
- (SP_REG 7)
- (ST0_REG 8)
- (ST1_REG 9)
- (ST2_REG 10)
- (ST3_REG 11)
- (ST4_REG 12)
- (ST5_REG 13)
- (ST6_REG 14)
- (ST7_REG 15)
- (FLAGS_REG 17)
- (FPSR_REG 18)
- (FPCR_REG 19)
- (XMM0_REG 21)
- (XMM1_REG 22)
- (XMM2_REG 23)
- (XMM3_REG 24)
- (XMM4_REG 25)
- (XMM5_REG 26)
- (XMM6_REG 27)
- (XMM7_REG 28)
- (MM0_REG 29)
- (MM1_REG 30)
- (MM2_REG 31)
- (MM3_REG 32)
- (MM4_REG 33)
- (MM5_REG 34)
- (MM6_REG 35)
- (MM7_REG 36)
- (R8_REG 37)
- (R9_REG 38)
- (R10_REG 39)
- (R11_REG 40)
- (R12_REG 41)
- (R13_REG 42)
- (R14_REG 43)
- (R15_REG 44)
- (XMM8_REG 45)
- (XMM9_REG 46)
- (XMM10_REG 47)
- (XMM11_REG 48)
- (XMM12_REG 49)
- (XMM13_REG 50)
- (XMM14_REG 51)
- (XMM15_REG 52)
- ])
-
-;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
-;; from i386.c.
-
-;; In C guard expressions, put expressions which may be compile-time
-;; constants first. This allows for better optimization. For
-;; example, write "TARGET_64BIT && reload_completed", not
-;; "reload_completed && TARGET_64BIT".
-
-
-;; Processor type.
-(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
- atom,slm,generic64,amdfam10,bdver1,bdver2,bdver3,btver1,btver2"
- (const (symbol_ref "ix86_schedule")))
-
-;; A basic instruction type. Refinements due to arguments to be
-;; provided in other attributes.
-(define_attr "type"
- "other,multi,
- alu,alu1,negnot,imov,imovx,lea,
- incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
- icmp,test,ibr,setcc,icmov,
- push,pop,call,callv,leave,
- str,bitmanip,
- fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
- sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
- sse,ssemov,sseadd,sseadd1,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
- sseshuf,sseshuf1,ssediv,sseins,ssemuladd,sse4arg,lwp,
- mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
- (const_string "other"))
-
-;; Main data type used by the insn
-(define_attr "mode"
- "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
- (const_string "unknown"))
-
-;; The CPU unit operations uses.
-(define_attr "unit" "integer,i387,sse,mmx,unknown"
- (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
- (const_string "i387")
- (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
- sse,ssemov,sseadd,sseadd1,ssemul,ssecmp,ssecomi,ssecvt,
- sseshuf,sseshuf1,ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
- (const_string "sse")
- (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
- (const_string "mmx")
- (eq_attr "type" "other")
- (const_string "unknown")]
- (const_string "integer")))
-
-;; The (bounding maximum) length of an instruction immediate.
-(define_attr "length_immediate" ""
- (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
- bitmanip,imulx")
- (const_int 0)
- (eq_attr "unit" "i387,sse,mmx")
- (const_int 0)
- (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
- rotate,rotatex,rotate1,imul,icmp,push,pop")
- (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
- (eq_attr "type" "imov,test")
- (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
- (eq_attr "type" "call")
- (if_then_else (match_operand 0 "constant_call_address_operand")
- (const_int 4)
- (const_int 0))
- (eq_attr "type" "callv")
- (if_then_else (match_operand 1 "constant_call_address_operand")
- (const_int 4)
- (const_int 0))
- ;; We don't know the size before shorten_branches. Expect
- ;; the instruction to fit for better scheduling.
- (eq_attr "type" "ibr")
- (const_int 1)
- ]
- (symbol_ref "/* Update immediate_length and other attributes! */
- gcc_unreachable (),1")))
-
-;; The (bounding maximum) length of an instruction address.
-(define_attr "length_address" ""
- (cond [(eq_attr "type" "str,other,multi,fxch")
- (const_int 0)
- (and (eq_attr "type" "call")
- (match_operand 0 "constant_call_address_operand"))
- (const_int 0)
- (and (eq_attr "type" "callv")
- (match_operand 1 "constant_call_address_operand"))
- (const_int 0)
- ]
- (symbol_ref "ix86_attr_length_address_default (insn)")))
-
-;; Set when length prefix is used.
-(define_attr "prefix_data16" ""
- (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
- (const_int 0)
- (eq_attr "mode" "HI")
- (const_int 1)
- (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
- (const_int 1)
- ]
- (const_int 0)))
-
-;; Set when string REP prefix is used.
-(define_attr "prefix_rep" ""
- (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
- (const_int 0)
- (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
- (const_int 1)
- ]
- (const_int 0)))
-
-;; Set when 0f opcode prefix is used.
-(define_attr "prefix_0f" ""
- (if_then_else
- (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
- (eq_attr "unit" "sse,mmx"))
- (const_int 1)
- (const_int 0)))
-
-;; Set when REX opcode prefix is used.
-(define_attr "prefix_rex" ""
- (cond [(not (match_test "TARGET_64BIT"))
- (const_int 0)
- (and (eq_attr "mode" "DI")
- (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
- (eq_attr "unit" "!mmx")))
- (const_int 1)
- (and (eq_attr "mode" "QI")
- (match_test "x86_extended_QIreg_mentioned_p (insn)"))
- (const_int 1)
- (match_test "x86_extended_reg_mentioned_p (insn)")
- (const_int 1)
- (and (eq_attr "type" "imovx")
- (match_operand:QI 1 "ext_QIreg_operand"))
- (const_int 1)
- ]
- (const_int 0)))
-
-;; There are also additional prefixes in 3DNOW, SSSE3.
-;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
-;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
-;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
-(define_attr "prefix_extra" ""
- (cond [(eq_attr "type" "ssemuladd,sse4arg")
- (const_int 2)
- (eq_attr "type" "sseiadd1,ssecvt1")
- (const_int 1)
- ]
- (const_int 0)))
-
-;; Prefix used: original, VEX or maybe VEX.
-(define_attr "prefix" "orig,vex,maybe_vex"
- (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
- (const_string "vex")
- (const_string "orig")))
-
-;; VEX W bit is used.
-(define_attr "prefix_vex_w" "" (const_int 0))
-
-;; The length of VEX prefix
-;; Only instructions with 0f prefix can have 2 byte VEX prefix,
-;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
-;; still prefix_0f 1, with prefix_extra 1.
-(define_attr "length_vex" ""
- (if_then_else (and (eq_attr "prefix_0f" "1")
- (eq_attr "prefix_extra" "0"))
- (if_then_else (eq_attr "prefix_vex_w" "1")
- (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
- (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
- (if_then_else (eq_attr "prefix_vex_w" "1")
- (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
- (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
-
-;; Set when modrm byte is used.
-(define_attr "modrm" ""
- (cond [(eq_attr "type" "str,leave")
- (const_int 0)
- (eq_attr "unit" "i387")
- (const_int 0)
- (and (eq_attr "type" "incdec")
- (and (not (match_test "TARGET_64BIT"))
- (ior (match_operand:SI 1 "register_operand")
- (match_operand:HI 1 "register_operand"))))
- (const_int 0)
- (and (eq_attr "type" "push")
- (not (match_operand 1 "memory_operand")))
- (const_int 0)
- (and (eq_attr "type" "pop")
- (not (match_operand 0 "memory_operand")))
- (const_int 0)
- (and (eq_attr "type" "imov")
- (and (not (eq_attr "mode" "DI"))
- (ior (and (match_operand 0 "register_operand")
- (match_operand 1 "immediate_operand"))
- (ior (and (match_operand 0 "ax_reg_operand")
- (match_operand 1 "memory_displacement_only_operand"))
- (and (match_operand 0 "memory_displacement_only_operand")
- (match_operand 1 "ax_reg_operand"))))))
- (const_int 0)
- (and (eq_attr "type" "call")
- (match_operand 0 "constant_call_address_operand"))
- (const_int 0)
- (and (eq_attr "type" "callv")
- (match_operand 1 "constant_call_address_operand"))
- (const_int 0)
- (and (eq_attr "type" "alu,alu1,icmp,test")
- (match_operand 0 "ax_reg_operand"))
- (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
- ]
- (const_int 1)))
-
-;; The (bounding maximum) length of an instruction in bytes.
-;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
-;; Later we may want to split them and compute proper length as for
-;; other insns.
-(define_attr "length" ""
- (cond [(eq_attr "type" "other,multi,fistp,frndint")
- (const_int 16)
- (eq_attr "type" "fcmp")
- (const_int 4)
- (eq_attr "unit" "i387")
- (plus (const_int 2)
- (plus (attr "prefix_data16")
- (attr "length_address")))
- (ior (eq_attr "prefix" "vex")
- (and (eq_attr "prefix" "maybe_vex")
- (match_test "TARGET_AVX")))
- (plus (attr "length_vex")
- (plus (attr "length_immediate")
- (plus (attr "modrm")
- (attr "length_address"))))]
- (plus (plus (attr "modrm")
- (plus (attr "prefix_0f")
- (plus (attr "prefix_rex")
- (plus (attr "prefix_extra")
- (const_int 1)))))
- (plus (attr "prefix_rep")
- (plus (attr "prefix_data16")
- (plus (attr "length_immediate")
- (attr "length_address")))))))
-
-;; The `memory' attribute is `none' if no memory is referenced, `load' or
-;; `store' if there is a simple memory reference therein, or `unknown'
-;; if the instruction is complex.
-
-(define_attr "memory" "none,load,store,both,unknown"
- (cond [(eq_attr "type" "other,multi,str,lwp")
- (const_string "unknown")
- (eq_attr "type" "lea,fcmov,fpspc")
- (const_string "none")
- (eq_attr "type" "fistp,leave")
- (const_string "both")
- (eq_attr "type" "frndint")
- (const_string "load")
- (eq_attr "type" "push")
- (if_then_else (match_operand 1 "memory_operand")
- (const_string "both")
- (const_string "store"))
- (eq_attr "type" "pop")
- (if_then_else (match_operand 0 "memory_operand")
- (const_string "both")
- (const_string "load"))
- (eq_attr "type" "setcc")
- (if_then_else (match_operand 0 "memory_operand")
- (const_string "store")
- (const_string "none"))
- (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
- (if_then_else (ior (match_operand 0 "memory_operand")
- (match_operand 1 "memory_operand"))
- (const_string "load")
- (const_string "none"))
- (eq_attr "type" "ibr")
- (if_then_else (match_operand 0 "memory_operand")
- (const_string "load")
- (const_string "none"))
- (eq_attr "type" "call")
- (if_then_else (match_operand 0 "constant_call_address_operand")
- (const_string "none")
- (const_string "load"))
- (eq_attr "type" "callv")
- (if_then_else (match_operand 1 "constant_call_address_operand")
- (const_string "none")
- (const_string "load"))
- (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
- (match_operand 1 "memory_operand"))
- (const_string "both")
- (and (match_operand 0 "memory_operand")
- (match_operand 1 "memory_operand"))
- (const_string "both")
- (match_operand 0 "memory_operand")
- (const_string "store")
- (match_operand 1 "memory_operand")
- (const_string "load")
- (and (eq_attr "type"
- "!alu1,negnot,ishift1,
- imov,imovx,icmp,test,bitmanip,
- fmov,fcmp,fsgn,
- sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
- sseshuf1,sseadd1,sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
- (match_operand 2 "memory_operand"))
- (const_string "load")
- (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
- (match_operand 3 "memory_operand"))
- (const_string "load")
- ]
- (const_string "none")))
-
-;; Indicates if an instruction has both an immediate and a displacement.
-
-(define_attr "imm_disp" "false,true,unknown"
- (cond [(eq_attr "type" "other,multi")
- (const_string "unknown")
- (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
- (and (match_operand 0 "memory_displacement_operand")
- (match_operand 1 "immediate_operand")))
- (const_string "true")
- (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
- (and (match_operand 0 "memory_displacement_operand")
- (match_operand 2 "immediate_operand")))
- (const_string "true")
- ]
- (const_string "false")))
-
-;; Indicates if an FP operation has an integer source.
-
-(define_attr "fp_int_src" "false,true"
- (const_string "false"))
-
-;; Defines rounding mode of an FP operation.
-
-(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
- (const_string "any"))
-
-;; Define attribute to classify add/sub insns that consumes carry flag (CF)
-(define_attr "use_carry" "0,1" (const_string "0"))
-
-;; Define attribute to indicate unaligned ssemov insns
-(define_attr "movu" "0,1" (const_string "0"))
-
-;; Used to control the "enabled" attribute on a per-instruction basis.
-(define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,
- avx2,noavx2,bmi2,fma4,fma"
- (const_string "base"))
-
-(define_attr "enabled" ""
- (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
- (eq_attr "isa" "sse2_noavx")
- (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
- (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
- (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
- (eq_attr "isa" "sse4_noavx")
- (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
- (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
- (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
- (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
- (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
- (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
- (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
- (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
- ]
- (const_int 1)))
-
-;; Describe a user's asm statement.
-(define_asm_attributes
- [(set_attr "length" "128")
- (set_attr "type" "multi")])
-
-(define_code_iterator plusminus [plus minus])
-
-(define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
-
-;; Base name for define_insn
-(define_code_attr plusminus_insn
- [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
- (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
-
-;; Base name for insn mnemonic.
-(define_code_attr plusminus_mnemonic
- [(plus "add") (ss_plus "adds") (us_plus "addus")
- (minus "sub") (ss_minus "subs") (us_minus "subus")])
-(define_code_attr plusminus_carry_mnemonic
- [(plus "adc") (minus "sbb")])
-
-;; Mark commutative operators as such in constraints.
-(define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
- (minus "") (ss_minus "") (us_minus "")])
-
-;; Mapping of max and min
-(define_code_iterator maxmin [smax smin umax umin])
-
-;; Mapping of signed max and min
-(define_code_iterator smaxmin [smax smin])
-
-;; Mapping of unsigned max and min
-(define_code_iterator umaxmin [umax umin])
-
-;; Base name for integer and FP insn mnemonic
-(define_code_attr maxmin_int [(smax "maxs") (smin "mins")
- (umax "maxu") (umin "minu")])
-(define_code_attr maxmin_float [(smax "max") (smin "min")])
-
-;; Mapping of logic operators
-(define_code_iterator any_logic [and ior xor])
-(define_code_iterator any_or [ior xor])
-
-;; Base name for insn mnemonic.
-(define_code_attr logic [(and "and") (ior "or") (xor "xor")])
-
-;; Mapping of logic-shift operators
-(define_code_iterator any_lshift [ashift lshiftrt])
-
-;; Mapping of shift-right operators
-(define_code_iterator any_shiftrt [lshiftrt ashiftrt])
-
-;; Mapping of all shift operators
-(define_code_iterator any_shift [ashift lshiftrt ashiftrt])
-
-;; Base name for define_insn
-(define_code_attr shift_insn
- [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
-
-;; Base name for insn mnemonic.
-(define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
-(define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
-
-;; Mapping of rotate operators
-(define_code_iterator any_rotate [rotate rotatert])
-
-;; Base name for define_insn
-(define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
-
-;; Base name for insn mnemonic.
-(define_code_attr rotate [(rotate "rol") (rotatert "ror")])
-
-;; Mapping of abs neg operators
-(define_code_iterator absneg [abs neg])
-
-;; Base name for x87 insn mnemonic.
-(define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
-
-;; Used in signed and unsigned widening multiplications.
-(define_code_iterator any_extend [sign_extend zero_extend])
-
-;; Prefix for insn menmonic.
-(define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
-
-;; Prefix for define_insn
-(define_code_attr u [(sign_extend "") (zero_extend "u")])
-(define_code_attr s [(sign_extend "s") (zero_extend "u")])
-(define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
-
-;; All integer modes.
-(define_mode_iterator SWI1248x [QI HI SI DI])
-
-;; All integer modes without QImode.
-(define_mode_iterator SWI248x [HI SI DI])
-
-;; All integer modes without QImode and HImode.
-(define_mode_iterator SWI48x [SI DI])
-
-;; All integer modes without SImode and DImode.
-(define_mode_iterator SWI12 [QI HI])
-
-;; All integer modes without DImode.
-(define_mode_iterator SWI124 [QI HI SI])
-
-;; All integer modes without QImode and DImode.
-(define_mode_iterator SWI24 [HI SI])
-
-;; Single word integer modes.
-(define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
-
-;; Single word integer modes without QImode.
-(define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
-
-;; Single word integer modes without QImode and HImode.
-(define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
-
-;; All math-dependant single and double word integer modes.
-(define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
- (HI "TARGET_HIMODE_MATH")
- SI DI (TI "TARGET_64BIT")])
-
-;; Math-dependant single word integer modes.
-(define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
- (HI "TARGET_HIMODE_MATH")
- SI (DI "TARGET_64BIT")])
-
-;; Math-dependant integer modes without DImode.
-(define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
- (HI "TARGET_HIMODE_MATH")
- SI])
-
-;; Math-dependant single word integer modes without QImode.
-(define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
- SI (DI "TARGET_64BIT")])
-
-;; Double word integer modes.
-(define_mode_iterator DWI [(DI "!TARGET_64BIT")
- (TI "TARGET_64BIT")])
-
-;; Double word integer modes as mode attribute.
-(define_mode_attr DWI [(SI "DI") (DI "TI")])
-(define_mode_attr dwi [(SI "di") (DI "ti")])
-
-;; Half mode for double word integer modes.
-(define_mode_iterator DWIH [(SI "!TARGET_64BIT")
- (DI "TARGET_64BIT")])
-
-;; Instruction suffix for integer modes.
-(define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
-
-;; Pointer size prefix for integer modes (Intel asm dialect)
-(define_mode_attr iptrsize [(QI "BYTE")
- (HI "WORD")
- (SI "DWORD")
- (DI "QWORD")])
-
-;; Register class for integer modes.
-(define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
-
-;; Immediate operand constraint for integer modes.
-(define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
-
-;; General operand constraint for word modes.
-(define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
-
-;; Immediate operand constraint for double integer modes.
-(define_mode_attr di [(SI "nF") (DI "e")])
-
-;; Immediate operand constraint for shifts.
-(define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
-
-;; General operand predicate for integer modes.
-(define_mode_attr general_operand
- [(QI "general_operand")
- (HI "general_operand")
- (SI "x86_64_general_operand")
- (DI "x86_64_general_operand")
- (TI "x86_64_general_operand")])
-
-;; General sign/zero extend operand predicate for integer modes.
-(define_mode_attr general_szext_operand
- [(QI "general_operand")
- (HI "general_operand")
- (SI "x86_64_szext_general_operand")
- (DI "x86_64_szext_general_operand")])
-
-;; Immediate operand predicate for integer modes.
-(define_mode_attr immediate_operand
- [(QI "immediate_operand")
- (HI "immediate_operand")
- (SI "x86_64_immediate_operand")
- (DI "x86_64_immediate_operand")])
-
-;; Nonmemory operand predicate for integer modes.
-(define_mode_attr nonmemory_operand
- [(QI "nonmemory_operand")
- (HI "nonmemory_operand")
- (SI "x86_64_nonmemory_operand")
- (DI "x86_64_nonmemory_operand")])
-
-;; Operand predicate for shifts.
-(define_mode_attr shift_operand
- [(QI "nonimmediate_operand")
- (HI "nonimmediate_operand")
- (SI "nonimmediate_operand")
- (DI "shiftdi_operand")
- (TI "register_operand")])
-
-;; Operand predicate for shift argument.
-(define_mode_attr shift_immediate_operand
- [(QI "const_1_to_31_operand")
- (HI "const_1_to_31_operand")
- (SI "const_1_to_31_operand")
- (DI "const_1_to_63_operand")])
-
-;; Input operand predicate for arithmetic left shifts.
-(define_mode_attr ashl_input_operand
- [(QI "nonimmediate_operand")
- (HI "nonimmediate_operand")
- (SI "nonimmediate_operand")
- (DI "ashldi_input_operand")
- (TI "reg_or_pm1_operand")])
-
-;; SSE and x87 SFmode and DFmode floating point modes
-(define_mode_iterator MODEF [SF DF])
-
-;; All x87 floating point modes
-(define_mode_iterator X87MODEF [SF DF XF])
-
-;; SSE instruction suffix for various modes
-(define_mode_attr ssemodesuffix
- [(SF "ss") (DF "sd")
- (V8SF "ps") (V4DF "pd")
- (V4SF "ps") (V2DF "pd")
- (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
- (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
-
-;; SSE vector suffix for floating point modes
-(define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
-
-;; SSE vector mode corresponding to a scalar mode
-(define_mode_attr ssevecmode
- [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
-
-;; Instruction suffix for REX 64bit operators.
-(define_mode_attr rex64suffix [(SI "") (DI "{q}")])
-
-;; This mode iterator allows :P to be used for patterns that operate on
-;; pointer-sized quantities. Exactly one of the two alternatives will match.
-(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
-
-;; This mode iterator allows :W to be used for patterns that operate on
-;; word_mode sized quantities.
-(define_mode_iterator W
- [(SI "word_mode == SImode") (DI "word_mode == DImode")])
-
-;; This mode iterator allows :PTR to be used for patterns that operate on
-;; ptr_mode sized quantities.
-(define_mode_iterator PTR
- [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
-
-;; Scheduling descriptions
-
-(include "pentium.md")
-(include "ppro.md")
-(include "k6.md")
-(include "athlon.md")
-(include "bdver1.md")
-(include "bdver3.md")
-(include "btver2.md")
-(include "geode.md")
-(include "atom.md")
-(include "slm.md")
-(include "core2.md")
-
-
-;; Operand and operator predicates and constraints
-
-(include "predicates.md")
-(include "constraints.md")
-
-
-;; Compare and branch/compare and store instructions.
-
-(define_expand "cbranch<mode>4"
- [(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
- (match_operand:SDWIM 2 "<general_operand>")))
- (set (pc) (if_then_else
- (match_operator 0 "ordered_comparison_operator"
- [(reg:CC FLAGS_REG) (const_int 0)])
- (label_ref (match_operand 3))
- (pc)))]
- ""
-{
- if (MEM_P (operands[1]) && MEM_P (operands[2]))
- operands[1] = force_reg (<MODE>mode, operands[1]);
- ix86_expand_branch (GET_CODE (operands[0]),
- operands[1], operands[2], operands[3]);
- DONE;
-})
-
-(define_expand "cstore<mode>4"
- [(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
- (match_operand:SWIM 3 "<general_operand>")))
- (set (match_operand:QI 0 "register_operand")
- (match_operator 1 "ordered_comparison_operator"
- [(reg:CC FLAGS_REG) (const_int 0)]))]
- ""
-{
- if (MEM_P (operands[2]) && MEM_P (operands[3]))
- operands[2] = force_reg (<MODE>mode, operands[2]);
- ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
- operands[2], operands[3]);
- DONE;
-})
-
-(define_expand "cmp<mode>_1"
- [(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
- (match_operand:SWI48 1 "<general_operand>")))])
-
-(define_insn "*cmp<mode>_ccno_1"
- [(set (reg FLAGS_REG)
- (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
- (match_operand:SWI 1 "const0_operand")))]
- "ix86_match_ccmode (insn, CCNOmode)"
- "@
- test{<imodesuffix>}\t%0, %0
- cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
- [(set_attr "type" "test,icmp")
- (set_attr "length_immediate" "0,1")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*cmp<mode>_1"
- [(set (reg FLAGS_REG)
- (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
- (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
- "ix86_match_ccmode (insn, CCmode)"
- "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
- [(set_attr "type" "icmp")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*cmp<mode>_minus_1"
- [(set (reg FLAGS_REG)
- (compare
- (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
- (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
- (const_int 0)))]
- "ix86_match_ccmode (insn, CCGOCmode)"
- "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
- [(set_attr "type" "icmp")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*cmpqi_ext_1"
- [(set (reg FLAGS_REG)
- (compare
- (match_operand:QI 0 "general_operand" "Qm")
- (subreg:QI
- (zero_extract:SI
- (match_operand 1 "ext_register_operand" "Q")
- (const_int 8)
- (const_int 8)) 0)))]
- "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
- "cmp{b}\t{%h1, %0|%0, %h1}"
- [(set_attr "type" "icmp")
- (set_attr "mode" "QI")])
-
-(define_insn "*cmpqi_ext_1_rex64"
- [(set (reg FLAGS_REG)
- (compare
- (match_operand:QI 0 "register_operand" "Q")
- (subreg:QI
- (zero_extract:SI
- (match_operand 1 "ext_register_operand" "Q")
- (const_int 8)
- (const_int 8)) 0)))]
- "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
- "cmp{b}\t{%h1, %0|%0, %h1}"
- [(set_attr "type" "icmp")
- (set_attr "mode" "QI")])
-
-(define_insn "*cmpqi_ext_2"
- [(set (reg FLAGS_REG)
- (compare
- (subreg:QI
- (zero_extract:SI
- (match_operand 0 "ext_register_operand" "Q")
- (const_int 8)
- (const_int 8)) 0)
- (match_operand:QI 1 "const0_operand")))]
- "ix86_match_ccmode (insn, CCNOmode)"
- "test{b}\t%h0, %h0"
- [(set_attr "type" "test")
- (set_attr "length_immediate" "0")
- (set_attr "mode" "QI")])
-
-(define_expand "cmpqi_ext_3"
- [(set (reg:CC FLAGS_REG)
- (compare:CC
- (subreg:QI
- (zero_extract:SI
- (match_operand 0 "ext_register_operand")
- (const_int 8)
- (const_int 8)) 0)
- (match_operand:QI 1 "immediate_operand")))])
-
-(define_insn "*cmpqi_ext_3_insn"
- [(set (reg FLAGS_REG)
- (compare
- (subreg:QI
- (zero_extract:SI
- (match_operand 0 "ext_register_operand" "Q")
- (const_int 8)
- (const_int 8)) 0)
- (match_operand:QI 1 "general_operand" "Qmn")))]
- "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
- "cmp{b}\t{%1, %h0|%h0, %1}"
- [(set_attr "type" "icmp")
- (set_attr "modrm" "1")
- (set_attr "mode" "QI")])
-
-(define_insn "*cmpqi_ext_3_insn_rex64"
- [(set (reg FLAGS_REG)
- (compare
- (subreg:QI
- (zero_extract:SI
- (match_operand 0 "ext_register_operand" "Q")
- (const_int 8)
- (const_int 8)) 0)
- (match_operand:QI 1 "nonmemory_operand" "Qn")))]
- "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
- "cmp{b}\t{%1, %h0|%h0, %1}"
- [(set_attr "type" "icmp")
- (set_attr "modrm" "1")
- (set_attr "mode" "QI")])
-
-(define_insn "*cmpqi_ext_4"
- [(set (reg FLAGS_REG)
- (compare
- (subreg:QI
- (zero_extract:SI
- (match_operand 0 "ext_register_operand" "Q")
- (const_int 8)
- (const_int 8)) 0)
- (subreg:QI
- (zero_extract:SI
- (match_operand 1 "ext_register_operand" "Q")
- (const_int 8)
- (const_int 8)) 0)))]
- "ix86_match_ccmode (insn, CCmode)"
- "cmp{b}\t{%h1, %h0|%h0, %h1}"
- [(set_attr "type" "icmp")
- (set_attr "mode" "QI")])
-
-;; These implement float point compares.
-;; %%% See if we can get away with VOIDmode operands on the actual insns,
-;; which would allow mix and match FP modes on the compares. Which is what
-;; the old patterns did, but with many more of them.
-
-(define_expand "cbranchxf4"
- [(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:XF 1 "nonmemory_operand")
- (match_operand:XF 2 "nonmemory_operand")))
- (set (pc) (if_then_else
- (match_operator 0 "ix86_fp_comparison_operator"
- [(reg:CC FLAGS_REG)
- (const_int 0)])
- (label_ref (match_operand 3))
- (pc)))]
- "TARGET_80387"
-{
- ix86_expand_branch (GET_CODE (operands[0]),
- operands[1], operands[2], operands[3]);
- DONE;
-})
-
-(define_expand "cstorexf4"
- [(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:XF 2 "nonmemory_operand")
- (match_operand:XF 3 "nonmemory_operand")))
- (set (match_operand:QI 0 "register_operand")
- (match_operator 1 "ix86_fp_comparison_operator"
- [(reg:CC FLAGS_REG)
- (const_int 0)]))]
- "TARGET_80387"
-{
- ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
- operands[2], operands[3]);
- DONE;
-})
-
-(define_expand "cbranch<mode>4"
- [(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
- (match_operand:MODEF 2 "cmp_fp_expander_operand")))
- (set (pc) (if_then_else
- (match_operator 0 "ix86_fp_comparison_operator"
- [(reg:CC FLAGS_REG)
- (const_int 0)])
- (label_ref (match_operand 3))
- (pc)))]
- "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
-{
- ix86_expand_branch (GET_CODE (operands[0]),
- operands[1], operands[2], operands[3]);
- DONE;
-})
-
-(define_expand "cstore<mode>4"
- [(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
- (match_operand:MODEF 3 "cmp_fp_expander_operand")))
- (set (match_operand:QI 0 "register_operand")
- (match_operator 1 "ix86_fp_comparison_operator"
- [(reg:CC FLAGS_REG)
- (const_int 0)]))]
- "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
-{
- ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
- operands[2], operands[3]);
- DONE;
-})
-
-(define_expand "cbranchcc4"
- [(set (pc) (if_then_else
- (match_operator 0 "comparison_operator"
- [(match_operand 1 "flags_reg_operand")
- (match_operand 2 "const0_operand")])
- (label_ref (match_operand 3))
- (pc)))]
- ""
-{
- ix86_expand_branch (GET_CODE (operands[0]),
- operands[1], operands[2], operands[3]);
- DONE;
-})
-
-(define_expand "cstorecc4"
- [(set (match_operand:QI 0 "register_operand")
- (match_operator 1 "comparison_operator"
- [(match_operand 2 "flags_reg_operand")
- (match_operand 3 "const0_operand")]))]
- ""
-{
- ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
- operands[2], operands[3]);
- DONE;
-})
-
-
-;; FP compares, step 1:
-;; Set the FP condition codes.
-;;
-;; CCFPmode compare with exceptions
-;; CCFPUmode compare with no exceptions
-
-;; We may not use "#" to split and emit these, since the REG_DEAD notes
-;; used to manage the reg stack popping would not be preserved.
-
-(define_insn "*cmp<mode>_0_i387"
- [(set (match_operand:HI 0 "register_operand" "=a")
- (unspec:HI
- [(compare:CCFP
- (match_operand:X87MODEF 1 "register_operand" "f")
- (match_operand:X87MODEF 2 "const0_operand"))]
- UNSPEC_FNSTSW))]
- "TARGET_80387"
- "* return output_fp_compare (insn, operands, false, false);"
- [(set_attr "type" "multi")
- (set_attr "unit" "i387")
- (set_attr "mode" "<MODE>")])
-
-(define_insn_and_split "*cmp<mode>_0_cc_i387"
- [(set (reg:CCFP FLAGS_REG)
- (compare:CCFP
- (match_operand:X87MODEF 1 "register_operand" "f")
- (match_operand:X87MODEF 2 "const0_operand")))
- (clobber (match_operand:HI 0 "register_operand" "=a"))]
- "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
- "#"
- "&& reload_completed"
- [(set (match_dup 0)
- (unspec:HI
- [(compare:CCFP (match_dup 1)(match_dup 2))]
- UNSPEC_FNSTSW))
- (set (reg:CC FLAGS_REG)
- (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
- ""
- [(set_attr "type" "multi")
- (set_attr "unit" "i387")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*cmpxf_i387"
- [(set (match_operand:HI 0 "register_operand" "=a")
- (unspec:HI
- [(compare:CCFP
- (match_operand:XF 1 "register_operand" "f")
- (match_operand:XF 2 "register_operand" "f"))]
- UNSPEC_FNSTSW))]
- "TARGET_80387"
- "* return output_fp_compare (insn, operands, false, false);"
- [(set_attr "type" "multi")
- (set_attr "unit" "i387")
- (set_attr "mode" "XF")])
-
-(define_insn_and_split "*cmpxf_cc_i387"
- [(set (reg:CCFP FLAGS_REG)
- (compare:CCFP
- (match_operand:XF 1 "register_operand" "f")
- (match_operand:XF 2 "register_operand" "f")))
- (clobber (match_operand:HI 0 "register_operand" "=a"))]
- "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
- "#"
- "&& reload_completed"
- [(set (match_dup 0)
- (unspec:HI
- [(compare:CCFP (match_dup 1)(match_dup 2))]
- UNSPEC_FNSTSW))
- (set (reg:CC FLAGS_REG)
- (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
- ""
- [(set_attr "type" "multi")
- (set_attr "unit" "i387")
- (set_attr "mode" "XF")])
-
-(define_insn "*cmp<mode>_i387"
- [(set (match_operand:HI 0 "register_operand" "=a")
- (unspec:HI
- [(compare:CCFP
- (match_operand:MODEF 1 "register_operand" "f")
- (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
- UNSPEC_FNSTSW))]
- "TARGET_80387"
- "* return output_fp_compare (insn, operands, false, false);"
- [(set_attr "type" "multi")
- (set_attr "unit" "i387")
- (set_attr "mode" "<MODE>")])
-
-(define_insn_and_split "*cmp<mode>_cc_i387"
- [(set (reg:CCFP FLAGS_REG)
- (compare:CCFP
- (match_operand:MODEF 1 "register_operand" "f")
- (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
- (clobber (match_operand:HI 0 "register_operand" "=a"))]
- "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
- "#"
- "&& reload_completed"
- [(set (match_dup 0)
- (unspec:HI
- [(compare:CCFP (match_dup 1)(match_dup 2))]
- UNSPEC_FNSTSW))
- (set (reg:CC FLAGS_REG)
- (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
- ""
- [(set_attr "type" "multi")
- (set_attr "unit" "i387")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*cmpu<mode>_i387"
- [(set (match_operand:HI 0 "register_operand" "=a")
- (unspec:HI
- [(compare:CCFPU
- (match_operand:X87MODEF 1 "register_operand" "f")
- (match_operand:X87MODEF 2 "register_operand" "f"))]
- UNSPEC_FNSTSW))]
- "TARGET_80387"
- "* return output_fp_compare (insn, operands, false, true);"
- [(set_attr "type" "multi")
- (set_attr "unit" "i387")
- (set_attr "mode" "<MODE>")])
-
-(define_insn_and_split "*cmpu<mode>_cc_i387"
- [(set (reg:CCFPU FLAGS_REG)
- (compare:CCFPU
- (match_operand:X87MODEF 1 "register_operand" "f")
- (match_operand:X87MODEF 2 "register_operand" "f")))
- (clobber (match_operand:HI 0 "register_operand" "=a"))]
- "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
- "#"
- "&& reload_completed"
- [(set (match_dup 0)
- (unspec:HI
- [(compare:CCFPU (match_dup 1)(match_dup 2))]
- UNSPEC_FNSTSW))
- (set (reg:CC FLAGS_REG)
- (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
- ""
- [(set_attr "type" "multi")
- (set_attr "unit" "i387")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
- [(set (match_operand:HI 0 "register_operand" "=a")
- (unspec:HI
- [(compare:CCFP
- (match_operand:X87MODEF 1 "register_operand" "f")
- (match_operator:X87MODEF 3 "float_operator"
- [(match_operand:SWI24 2 "memory_operand" "m")]))]
- UNSPEC_FNSTSW))]
- "TARGET_80387
- && (TARGET_USE_<SWI24:MODE>MODE_FIOP
- || optimize_function_for_size_p (cfun))"
- "* return output_fp_compare (insn, operands, false, false);"
- [(set_attr "type" "multi")
- (set_attr "unit" "i387")
- (set_attr "fp_int_src" "true")
- (set_attr "mode" "<SWI24:MODE>")])
-
-(define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
- [(set (reg:CCFP FLAGS_REG)
- (compare:CCFP
- (match_operand:X87MODEF 1 "register_operand" "f")
- (match_operator:X87MODEF 3 "float_operator"
- [(match_operand:SWI24 2 "memory_operand" "m")])))
- (clobber (match_operand:HI 0 "register_operand" "=a"))]
- "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
- && (TARGET_USE_<SWI24:MODE>MODE_FIOP
- || optimize_function_for_size_p (cfun))"
- "#"
- "&& reload_completed"
- [(set (match_dup 0)
- (unspec:HI
- [(compare:CCFP
- (match_dup 1)
- (match_op_dup 3 [(match_dup 2)]))]
- UNSPEC_FNSTSW))
- (set (reg:CC FLAGS_REG)
- (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
- ""
- [(set_attr "type" "multi")
- (set_attr "unit" "i387")
- (set_attr "fp_int_src" "true")
- (set_attr "mode" "<SWI24:MODE>")])
-
-;; FP compares, step 2
-;; Move the fpsw to ax.
-
-(define_insn "x86_fnstsw_1"
- [(set (match_operand:HI 0 "register_operand" "=a")
- (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
- "TARGET_80387"
- "fnstsw\t%0"
- [(set (attr "length")
- (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
- (set_attr "mode" "SI")
- (set_attr "unit" "i387")])
-
-;; FP compares, step 3
-;; Get ax into flags, general case.
-
-(define_insn "x86_sahf_1"
- [(set (reg:CC FLAGS_REG)
- (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
- UNSPEC_SAHF))]
- "TARGET_SAHF"
-{
-#ifndef HAVE_AS_IX86_SAHF
- if (TARGET_64BIT)
- return ASM_BYTE "0x9e";
- else
-#endif
- return "sahf";
-}
- [(set_attr "length" "1")
- (set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "direct")
- (set_attr "bdver1_decode" "direct")
- (set_attr "mode" "SI")])
-
-;; Pentium Pro can do steps 1 through 3 in one go.
-;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
-;; (these i387 instructions set flags directly)
-
-(define_mode_iterator FPCMP [CCFP CCFPU])
-(define_mode_attr unord [(CCFP "") (CCFPU "u")])
-
-(define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
- [(set (reg:FPCMP FLAGS_REG)
- (compare:FPCMP
- (match_operand:MODEF 0 "register_operand" "f,x")
- (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
- "TARGET_MIX_SSE_I387
- && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
- "* return output_fp_compare (insn, operands, true,
- <FPCMP:MODE>mode == CCFPUmode);"
- [(set_attr "type" "fcmp,ssecomi")
- (set_attr "prefix" "orig,maybe_vex")
- (set_attr "mode" "<MODEF:MODE>")
- (set (attr "prefix_rep")
- (if_then_else (eq_attr "type" "ssecomi")
- (const_string "0")
- (const_string "*")))
- (set (attr "prefix_data16")
- (cond [(eq_attr "type" "fcmp")
- (const_string "*")
- (eq_attr "mode" "DF")
- (const_string "1")
- ]
- (const_string "0")))
- (set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "direct")
- (set_attr "bdver1_decode" "double")])
-
-(define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
- [(set (reg:FPCMP FLAGS_REG)
- (compare:FPCMP
- (match_operand:MODEF 0 "register_operand" "x")
- (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
- "TARGET_SSE_MATH
- && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
- "* return output_fp_compare (insn, operands, true,
- <FPCMP:MODE>mode == CCFPUmode);"
- [(set_attr "type" "ssecomi")
- (set_attr "prefix" "maybe_vex")
- (set_attr "mode" "<MODEF:MODE>")
- (set_attr "prefix_rep" "0")
- (set (attr "prefix_data16")
- (if_then_else (eq_attr "mode" "DF")
- (const_string "1")
- (const_string "0")))
- (set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "direct")
- (set_attr "bdver1_decode" "double")])
-
-(define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
- [(set (reg:FPCMP FLAGS_REG)
- (compare:FPCMP
- (match_operand:X87MODEF 0 "register_operand" "f")
- (match_operand:X87MODEF 1 "register_operand" "f")))]
- "TARGET_80387 && TARGET_CMOVE
- && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
- "* return output_fp_compare (insn, operands, true,
- <FPCMP:MODE>mode == CCFPUmode);"
- [(set_attr "type" "fcmp")
- (set_attr "mode" "<X87MODEF:MODE>")
- (set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "direct")
- (set_attr "bdver1_decode" "double")])
-
-;; Push/pop instructions.
-
-(define_insn "*push<mode>2"
- [(set (match_operand:DWI 0 "push_operand" "=<")
- (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
- ""
- "#"
- [(set_attr "type" "multi")
- (set_attr "mode" "<MODE>")])
-
-(define_split
- [(set (match_operand:TI 0 "push_operand")
- (match_operand:TI 1 "general_operand"))]
- "TARGET_64BIT && reload_completed
- && !SSE_REG_P (operands[1])"
- [(const_int 0)]
- "ix86_split_long_move (operands); DONE;")
-
-(define_insn "*pushdi2_rex64"
- [(set (match_operand:DI 0 "push_operand" "=<,!<")
- (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
- "TARGET_64BIT"
- "@
- push{q}\t%1
- #"
- [(set_attr "type" "push,multi")
- (set_attr "mode" "DI")])
-
-;; Convert impossible pushes of immediate to existing instructions.
-;; First try to get scratch register and go through it. In case this
-;; fails, push sign extended lower part first and then overwrite
-;; upper part by 32bit move.
-(define_peephole2
- [(match_scratch:DI 2 "r")
- (set (match_operand:DI 0 "push_operand")
- (match_operand:DI 1 "immediate_operand"))]
- "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
- && !x86_64_immediate_operand (operands[1], DImode)"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (match_dup 2))])
-
-;; We need to define this as both peepholer and splitter for case
-;; peephole2 pass is not run.
-;; "&& 1" is needed to keep it from matching the previous pattern.
-(define_peephole2
- [(set (match_operand:DI 0 "push_operand")
- (match_operand:DI 1 "immediate_operand"))]
- "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
- && !x86_64_immediate_operand (operands[1], DImode) && 1"
- [(set (match_dup 0) (match_dup 1))
- (set (match_dup 2) (match_dup 3))]
-{
- split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
-
- operands[1] = gen_lowpart (DImode, operands[2]);
- operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
- GEN_INT (4)));
-})
-
-(define_split
- [(set (match_operand:DI 0 "push_operand")
- (match_operand:DI 1 "immediate_operand"))]
- "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
- ? epilogue_completed : reload_completed)
- && !symbolic_operand (operands[1], DImode)
- && !x86_64_immediate_operand (operands[1], DImode)"
- [(set (match_dup 0) (match_dup 1))
- (set (match_dup 2) (match_dup 3))]
-{
- split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
-
- operands[1] = gen_lowpart (DImode, operands[2]);
- operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
- GEN_INT (4)));
-})
-
-(define_split
- [(set (match_operand:DI 0 "push_operand")
- (match_operand:DI 1 "general_operand"))]
- "!TARGET_64BIT && reload_completed
- && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
- [(const_int 0)]
- "ix86_split_long_move (operands); DONE;")
-
-(define_insn "*pushsi2"
- [(set (match_operand:SI 0 "push_operand" "=<")
- (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
- "!TARGET_64BIT"
- "push{l}\t%1"
- [(set_attr "type" "push")
- (set_attr "mode" "SI")])
-
-;; emit_push_insn when it calls move_by_pieces requires an insn to
-;; "push a byte/word". But actually we use pushl, which has the effect
-;; of rounding the amount pushed up to a word.
-
-;; For TARGET_64BIT we always round up to 8 bytes.
-(define_insn "*push<mode>2_rex64"
- [(set (match_operand:SWI124 0 "push_operand" "=X")
- (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
- "TARGET_64BIT"
- "push{q}\t%q1"
- [(set_attr "type" "push")
- (set_attr "mode" "DI")])
-
-(define_insn "*push<mode>2"
- [(set (match_operand:SWI12 0 "push_operand" "=X")
- (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
- "!TARGET_64BIT"
- "push{l}\t%k1"
- [(set_attr "type" "push")
- (set_attr "mode" "SI")])
-
-(define_insn "*push<mode>2_prologue"
- [(set (match_operand:W 0 "push_operand" "=<")
- (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
- (clobber (mem:BLK (scratch)))]
- ""
- "push{<imodesuffix>}\t%1"
- [(set_attr "type" "push")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*pop<mode>1"
- [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
- (match_operand:W 1 "pop_operand" ">"))]
- ""
- "pop{<imodesuffix>}\t%0"
- [(set_attr "type" "pop")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*pop<mode>1_epilogue"
- [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
- (match_operand:W 1 "pop_operand" ">"))
- (clobber (mem:BLK (scratch)))]
- ""
- "pop{<imodesuffix>}\t%0"
- [(set_attr "type" "pop")
- (set_attr "mode" "<MODE>")])
-
-;; Move instructions.
-
-(define_expand "movoi"
- [(set (match_operand:OI 0 "nonimmediate_operand")
- (match_operand:OI 1 "general_operand"))]
- "TARGET_AVX"
- "ix86_expand_move (OImode, operands); DONE;")
-
-(define_expand "movti"
- [(set (match_operand:TI 0 "nonimmediate_operand")
- (match_operand:TI 1 "nonimmediate_operand"))]
- "TARGET_64BIT || TARGET_SSE"
-{
- if (TARGET_64BIT)
- ix86_expand_move (TImode, operands);
- else if (push_operand (operands[0], TImode))
- ix86_expand_push (TImode, operands[1]);
- else
- ix86_expand_vector_move (TImode, operands);
- DONE;
-})
-
-;; This expands to what emit_move_complex would generate if we didn't
-;; have a movti pattern. Having this avoids problems with reload on
-;; 32-bit targets when SSE is present, but doesn't seem to be harmful
-;; to have around all the time.
-(define_expand "movcdi"
- [(set (match_operand:CDI 0 "nonimmediate_operand")
- (match_operand:CDI 1 "general_operand"))]
- ""
-{
- if (push_operand (operands[0], CDImode))
- emit_move_complex_push (CDImode, operands[0], operands[1]);
- else
- emit_move_complex_parts (operands[0], operands[1]);
- DONE;
-})
-
-(define_expand "mov<mode>"
- [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
- (match_operand:SWI1248x 1 "general_operand"))]
- ""
- "ix86_expand_move (<MODE>mode, operands); DONE;")
-
-(define_insn "*mov<mode>_xor"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (match_operand:SWI48 1 "const0_operand"))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed"
- "xor{l}\t%k0, %k0"
- [(set_attr "type" "alu1")
- (set_attr "mode" "SI")
- (set_attr "length_immediate" "0")])
-
-(define_insn "*mov<mode>_or"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (match_operand:SWI48 1 "const_int_operand"))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed
- && operands[1] == constm1_rtx"
- "or{<imodesuffix>}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "mode" "<MODE>")
- (set_attr "length_immediate" "1")])
-
-(define_insn "*movoi_internal_avx"
- [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
- (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
- "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
-{
- switch (which_alternative)
- {
- case 0:
- return standard_sse_constant_opcode (insn, operands[1]);
- case 1:
- case 2:
- if (misaligned_operand (operands[0], OImode)
- || misaligned_operand (operands[1], OImode))
- {
- if (get_attr_mode (insn) == MODE_V8SF)
- return "vmovups\t{%1, %0|%0, %1}";
- else
- return "vmovdqu\t{%1, %0|%0, %1}";
- }
- else
- {
- if (get_attr_mode (insn) == MODE_V8SF)
- return "vmovaps\t{%1, %0|%0, %1}";
- else
- return "vmovdqa\t{%1, %0|%0, %1}";
- }
- default:
- gcc_unreachable ();
- }
-}
- [(set_attr "type" "sselog1,ssemov,ssemov")
- (set_attr "prefix" "vex")
- (set (attr "mode")
- (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
- (const_string "V8SF")
- (and (eq_attr "alternative" "2")
- (match_test "TARGET_SSE_TYPELESS_STORES"))
- (const_string "V8SF")
- ]
- (const_string "OI")))])
-
-(define_insn "*movti_internal_rex64"
- [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
- (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
- "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
-{
- switch (which_alternative)
- {
- case 0:
- case 1:
- return "#";
- case 2:
- return standard_sse_constant_opcode (insn, operands[1]);
- case 3:
- case 4:
- /* TDmode values are passed as TImode on the stack. Moving them
- to stack may result in unaligned memory access. */
- if (misaligned_operand (operands[0], TImode)
- || misaligned_operand (operands[1], TImode))
- {
- if (get_attr_mode (insn) == MODE_V4SF)
- return "%vmovups\t{%1, %0|%0, %1}";
- else
- return "%vmovdqu\t{%1, %0|%0, %1}";
- }
- else
- {
- if (get_attr_mode (insn) == MODE_V4SF)
- return "%vmovaps\t{%1, %0|%0, %1}";
- else
- return "%vmovdqa\t{%1, %0|%0, %1}";
- }
- default:
- gcc_unreachable ();
- }
-}
- [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
- (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
- (set (attr "mode")
- (cond [(eq_attr "alternative" "0,1")
- (const_string "DI")
- (not (match_test "TARGET_SSE2"))
- (const_string "V4SF")
- (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
- (const_string "V4SF")
- (and (eq_attr "alternative" "4")
- (match_test "TARGET_SSE_TYPELESS_STORES"))
- (const_string "V4SF")
- (match_test "TARGET_AVX")
- (const_string "TI")
- (match_test "optimize_function_for_size_p (cfun)")
- (const_string "V4SF")
- ]
- (const_string "TI")))])
-
-(define_split
- [(set (match_operand:TI 0 "nonimmediate_operand")
- (match_operand:TI 1 "general_operand"))]
- "reload_completed
- && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
- [(const_int 0)]
- "ix86_split_long_move (operands); DONE;")
-
-(define_insn "*movti_internal_sse"
- [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x ,m")
- (match_operand:TI 1 "vector_move_operand" "C ,xm,x"))]
- "TARGET_SSE && !TARGET_64BIT
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
-{
- switch (which_alternative)
- {
- case 0:
- return standard_sse_constant_opcode (insn, operands[1]);
- case 1:
- case 2:
- /* TDmode values are passed as TImode on the stack. Moving them
- to stack may result in unaligned memory access. */
- if (misaligned_operand (operands[0], TImode)
- || misaligned_operand (operands[1], TImode))
- {
- if (get_attr_mode (insn) == MODE_V4SF)
- return "%vmovups\t{%1, %0|%0, %1}";
- else
- return "%vmovdqu\t{%1, %0|%0, %1}";
- }
- else
- {
- if (get_attr_mode (insn) == MODE_V4SF)
- return "%vmovaps\t{%1, %0|%0, %1}";
- else
- return "%vmovdqa\t{%1, %0|%0, %1}";
- }
- default:
- gcc_unreachable ();
- }
-}
- [(set_attr "type" "sselog1,ssemov,ssemov")
- (set_attr "prefix" "maybe_vex")
- (set (attr "mode")
- (cond [(not (match_test "TARGET_SSE2"))
- (const_string "V4SF")
- (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
- (const_string "V4SF")
- (and (eq_attr "alternative" "2")
- (match_test "TARGET_SSE_TYPELESS_STORES"))
- (const_string "V4SF")
- (match_test "TARGET_AVX")
- (const_string "TI")
- (match_test "optimize_function_for_size_p (cfun)")
- (const_string "V4SF")
- ]
- (const_string "TI")))])
-
-(define_insn "*movdi_internal_rex64"
- [(set (match_operand:DI 0 "nonimmediate_operand"
- "=r,r ,r,m ,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
- (match_operand:DI 1 "general_operand"
- "Z ,rem,i,re,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
- "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_SSECVT:
- if (SSE_REG_P (operands[0]))
- return "movq2dq\t{%1, %0|%0, %1}";
- else
- return "movdq2q\t{%1, %0|%0, %1}";
-
- case TYPE_SSEMOV:
- if (get_attr_mode (insn) == MODE_V4SF)
- return "%vmovaps\t{%1, %0|%0, %1}";
- else if (get_attr_mode (insn) == MODE_TI)
- return "%vmovdqa\t{%1, %0|%0, %1}";
-
- /* Handle broken assemblers that require movd instead of movq. */
- if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
- return "%vmovd\t{%1, %0|%0, %1}";
- else
- return "%vmovq\t{%1, %0|%0, %1}";
-
- case TYPE_MMXMOV:
- /* Handle broken assemblers that require movd instead of movq. */
- if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
- return "movd\t{%1, %0|%0, %1}";
- else
- return "movq\t{%1, %0|%0, %1}";
-
- case TYPE_SSELOG1:
- return standard_sse_constant_opcode (insn, operands[1]);
-
- case TYPE_MMX:
- return "pxor\t%0, %0";
-
- case TYPE_LEA:
- return "lea{q}\t{%E1, %0|%0, %E1}";
-
- default:
- gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
- if (get_attr_mode (insn) == MODE_SI)
- return "mov{l}\t{%k1, %k0|%k0, %k1}";
- else if (which_alternative == 2)
- return "movabs{q}\t{%1, %0|%0, %1}";
- else if (ix86_use_lea_for_mov (insn, operands))
- return "lea{q}\t{%E1, %0|%0, %E1}";
- else
- return "mov{q}\t{%1, %0|%0, %1}";
- }
-}
- [(set (attr "type")
- (cond [(eq_attr "alternative" "4")
- (const_string "mmx")
- (eq_attr "alternative" "5,6,7,8")
- (const_string "mmxmov")
- (eq_attr "alternative" "9")
- (const_string "sselog1")
- (eq_attr "alternative" "10,11,12,13,14")
- (const_string "ssemov")
- (eq_attr "alternative" "15,16")
- (const_string "ssecvt")
- (match_operand 1 "pic_32bit_operand")
- (const_string "lea")
- ]
- (const_string "imov")))
- (set (attr "modrm")
- (if_then_else
- (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
- (const_string "0")
- (const_string "*")))
- (set (attr "length_immediate")
- (if_then_else
- (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
- (const_string "8")
- (const_string "*")))
- (set (attr "prefix_rex")
- (if_then_else (eq_attr "alternative" "7,8")
- (const_string "1")
- (const_string "*")))
- (set (attr "prefix_data16")
- (if_then_else (eq_attr "alternative" "10")
- (const_string "1")
- (const_string "*")))
- (set (attr "prefix")
- (if_then_else (eq_attr "alternative" "9,10,11,12,13,14")
- (const_string "maybe_vex")
- (const_string "orig")))
- (set (attr "mode")
- (cond [(eq_attr "alternative" "0")
- (const_string "SI")
- (eq_attr "alternative" "9,11")
- (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
- (const_string "V4SF")
- (match_test "TARGET_AVX")
- (const_string "TI")
- (match_test "optimize_function_for_size_p (cfun)")
- (const_string "V4SF")
- ]
- (const_string "TI"))
- ]
- (const_string "DI")))])
-
-;; Reload patterns to support multi-word load/store
-;; with non-offsetable address.
-(define_expand "reload_noff_store"
- [(parallel [(match_operand 0 "memory_operand" "=m")
- (match_operand 1 "register_operand" "r")
- (match_operand:DI 2 "register_operand" "=&r")])]
- "TARGET_64BIT"
-{
- rtx mem = operands[0];
- rtx addr = XEXP (mem, 0);
-
- emit_move_insn (operands[2], addr);
- mem = replace_equiv_address_nv (mem, operands[2]);
-
- emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
- DONE;
-})
-
-(define_expand "reload_noff_load"
- [(parallel [(match_operand 0 "register_operand" "=r")
- (match_operand 1 "memory_operand" "m")
- (match_operand:DI 2 "register_operand" "=r")])]
- "TARGET_64BIT"
-{
- rtx mem = operands[1];
- rtx addr = XEXP (mem, 0);
-
- emit_move_insn (operands[2], addr);
- mem = replace_equiv_address_nv (mem, operands[2]);
-
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
- DONE;
-})
-
-(define_insn "*movdi_internal"
- [(set (match_operand:DI 0 "nonimmediate_operand"
- "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
- (match_operand:DI 1 "general_operand"
- "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
- "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_SSECVT:
- if (SSE_REG_P (operands[0]))
- return "movq2dq\t{%1, %0|%0, %1}";
- else
- return "movdq2q\t{%1, %0|%0, %1}";
-
- case TYPE_SSEMOV:
- switch (get_attr_mode (insn))
- {
- case MODE_TI:
- return "%vmovdqa\t{%1, %0|%0, %1}";
- case MODE_DI:
- return "%vmovq\t{%1, %0|%0, %1}";
- case MODE_V4SF:
- return "%vmovaps\t{%1, %0|%0, %1}";
- case MODE_V2SF:
- return "movlps\t{%1, %0|%0, %1}";
- default:
- gcc_unreachable ();
- }
-
- case TYPE_MMXMOV:
- return "movq\t{%1, %0|%0, %1}";
-
- case TYPE_SSELOG1:
- return standard_sse_constant_opcode (insn, operands[1]);
-
- case TYPE_MMX:
- return "pxor\t%0, %0";
-
- case TYPE_MULTI:
- return "#";
-
- default:
- gcc_unreachable ();
- }
-}
- [(set (attr "isa")
- (cond [(eq_attr "alternative" "5,6,7,8,13,14")
- (const_string "sse2")
- (eq_attr "alternative" "9,10,11,12")
- (const_string "noavx")
- ]
- (const_string "*")))
- (set (attr "type")
- (cond [(eq_attr "alternative" "0,1")
- (const_string "multi")
- (eq_attr "alternative" "2")
- (const_string "mmx")
- (eq_attr "alternative" "3,4")
- (const_string "mmxmov")
- (eq_attr "alternative" "5,9")
- (const_string "sselog1")
- (eq_attr "alternative" "13,14")
- (const_string "ssecvt")
- ]
- (const_string "ssemov")))
- (set (attr "prefix")
- (if_then_else (eq_attr "alternative" "5,6,7,8")
- (const_string "maybe_vex")
- (const_string "orig")))
- (set (attr "mode")
- (cond [(eq_attr "alternative" "9,11")
- (const_string "V4SF")
- (eq_attr "alternative" "10,12")
- (const_string "V2SF")
- (eq_attr "alternative" "5,7")
- (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
- (const_string "V4SF")
- (match_test "TARGET_AVX")
- (const_string "TI")
- (match_test "optimize_function_for_size_p (cfun)")
- (const_string "V4SF")
- ]
- (const_string "TI"))
- ]
- (const_string "DI")))])
-
-(define_split
- [(set (match_operand:DI 0 "nonimmediate_operand")
- (match_operand:DI 1 "general_operand"))]
- "!TARGET_64BIT && reload_completed
- && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
- && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
- [(const_int 0)]
- "ix86_split_long_move (operands); DONE;")
-
-(define_insn "*movsi_internal"
- [(set (match_operand:SI 0 "nonimmediate_operand"
- "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
- (match_operand:SI 1 "general_operand"
- "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m"))]
- "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_SSELOG1:
- return standard_sse_constant_opcode (insn, operands[1]);
-
- case TYPE_SSEMOV:
- switch (get_attr_mode (insn))
- {
- case MODE_TI:
- return "%vmovdqa\t{%1, %0|%0, %1}";
- case MODE_V4SF:
- return "%vmovaps\t{%1, %0|%0, %1}";
- case MODE_SI:
- return "%vmovd\t{%1, %0|%0, %1}";
- case MODE_SF:
- return "%vmovss\t{%1, %0|%0, %1}";
- default:
- gcc_unreachable ();
- }
-
- case TYPE_MMX:
- return "pxor\t%0, %0";
-
- case TYPE_MMXMOV:
- if (get_attr_mode (insn) == MODE_DI)
- return "movq\t{%1, %0|%0, %1}";
- return "movd\t{%1, %0|%0, %1}";
-
- case TYPE_LEA:
- return "lea{l}\t{%E1, %0|%0, %E1}";
-
- default:
- gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
- if (ix86_use_lea_for_mov (insn, operands))
- return "lea{l}\t{%E1, %0|%0, %E1}";
- else
- return "mov{l}\t{%1, %0|%0, %1}";
- }
-}
- [(set (attr "type")
- (cond [(eq_attr "alternative" "2")
- (const_string "mmx")
- (eq_attr "alternative" "3,4,5")
- (const_string "mmxmov")
- (eq_attr "alternative" "6")
- (const_string "sselog1")
- (eq_attr "alternative" "7,8,9,10,11")
- (const_string "ssemov")
- (match_operand 1 "pic_32bit_operand")
- (const_string "lea")
- ]
- (const_string "imov")))
- (set (attr "prefix")
- (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
- (const_string "orig")
- (const_string "maybe_vex")))
- (set (attr "prefix_data16")
- (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
- (const_string "1")
- (const_string "*")))
- (set (attr "mode")
- (cond [(eq_attr "alternative" "2,3")
- (const_string "DI")
- (eq_attr "alternative" "6,7")
- (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
- (const_string "V4SF")
- (match_test "TARGET_AVX")
- (const_string "TI")
- (ior (not (match_test "TARGET_SSE2"))
- (match_test "optimize_function_for_size_p (cfun)"))
- (const_string "V4SF")
- ]
- (const_string "TI"))
- (and (eq_attr "alternative" "8,9,10,11")
- (not (match_test "TARGET_SSE2")))
- (const_string "SF")
- ]
- (const_string "SI")))])
-
-(define_insn "*movhi_internal"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m")
- (match_operand:HI 1 "general_operand" "r ,rn,rm,rn"))]
- "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_IMOVX:
- /* movzwl is faster than movw on p2 due to partial word stalls,
- though not as fast as an aligned movl. */
- return "movz{wl|x}\t{%1, %k0|%k0, %1}";
- default:
- if (get_attr_mode (insn) == MODE_SI)
- return "mov{l}\t{%k1, %k0|%k0, %k1}";
- else
- return "mov{w}\t{%1, %0|%0, %1}";
- }
-}
- [(set (attr "type")
- (cond [(match_test "optimize_function_for_size_p (cfun)")
- (const_string "imov")
- (and (eq_attr "alternative" "0")
- (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
- (not (match_test "TARGET_HIMODE_MATH"))))
- (const_string "imov")
- (and (eq_attr "alternative" "1,2")
- (match_operand:HI 1 "aligned_operand"))
- (const_string "imov")
- (and (match_test "TARGET_MOVX")
- (eq_attr "alternative" "0,2"))
- (const_string "imovx")
- ]
- (const_string "imov")))
- (set (attr "mode")
- (cond [(eq_attr "type" "imovx")
- (const_string "SI")
- (and (eq_attr "alternative" "1,2")
- (match_operand:HI 1 "aligned_operand"))
- (const_string "SI")
- (and (eq_attr "alternative" "0")
- (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
- (not (match_test "TARGET_HIMODE_MATH"))))
- (const_string "SI")
- ]
- (const_string "HI")))])
-
-;; Situation is quite tricky about when to choose full sized (SImode) move
-;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
-;; partial register dependency machines (such as AMD Athlon), where QImode
-;; moves issue extra dependency and for partial register stalls machines
-;; that don't use QImode patterns (and QImode move cause stall on the next
-;; instruction).
-;;
-;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
-;; register stall machines with, where we use QImode instructions, since
-;; partial register stall can be caused there. Then we use movzx.
-(define_insn "*movqi_internal"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
- (match_operand:QI 1 "general_operand" "q ,qn,qm,q,rn,qm,qn"))]
- "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_IMOVX:
- gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
- return "movz{bl|x}\t{%1, %k0|%k0, %1}";
- default:
- if (get_attr_mode (insn) == MODE_SI)
- return "mov{l}\t{%k1, %k0|%k0, %k1}";
- else
- return "mov{b}\t{%1, %0|%0, %1}";
- }
-}
- [(set (attr "type")
- (cond [(and (eq_attr "alternative" "5")
- (not (match_operand:QI 1 "aligned_operand")))
- (const_string "imovx")
- (match_test "optimize_function_for_size_p (cfun)")
- (const_string "imov")
- (and (eq_attr "alternative" "3")
- (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
- (not (match_test "TARGET_QIMODE_MATH"))))
- (const_string "imov")
- (eq_attr "alternative" "3,5")
- (const_string "imovx")
- (and (match_test "TARGET_MOVX")
- (eq_attr "alternative" "2"))
- (const_string "imovx")
- ]
- (const_string "imov")))
- (set (attr "mode")
- (cond [(eq_attr "alternative" "3,4,5")
- (const_string "SI")
- (eq_attr "alternative" "6")
- (const_string "QI")
- (eq_attr "type" "imovx")
- (const_string "SI")
- (and (eq_attr "type" "imov")
- (and (eq_attr "alternative" "0,1")
- (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
- (and (not (match_test "optimize_function_for_size_p (cfun)"))
- (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
- (const_string "SI")
- ;; Avoid partial register stalls when not using QImode arithmetic
- (and (eq_attr "type" "imov")
- (and (eq_attr "alternative" "0,1")
- (and (match_test "TARGET_PARTIAL_REG_STALL")
- (not (match_test "TARGET_QIMODE_MATH")))))
- (const_string "SI")
- ]
- (const_string "QI")))])
-
-;; Stores and loads of ax to arbitrary constant address.
-;; We fake an second form of instruction to force reload to load address
-;; into register when rax is not available
-(define_insn "*movabs<mode>_1"
- [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
- (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
- "TARGET_LP64 && ix86_check_movabs (insn, 0)"
- "@
- movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
- mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
- [(set_attr "type" "imov")
- (set_attr "modrm" "0,*")
- (set_attr "length_address" "8,0")
- (set_attr "length_immediate" "0,*")
- (set_attr "memory" "store")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*movabs<mode>_2"
- [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
- (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
- "TARGET_LP64 && ix86_check_movabs (insn, 1)"
- "@
- movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
- mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
- [(set_attr "type" "imov")
- (set_attr "modrm" "0,*")
- (set_attr "length_address" "8,0")
- (set_attr "length_immediate" "0")
- (set_attr "memory" "load")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "swap<mode>"
- [(set (match_operand:SWI48 0 "register_operand" "+r")
- (match_operand:SWI48 1 "register_operand" "+r"))
- (set (match_dup 1)
- (match_dup 0))]
- ""
- "xchg{<imodesuffix>}\t%1, %0"
- [(set_attr "type" "imov")
- (set_attr "mode" "<MODE>")
- (set_attr "pent_pair" "np")
- (set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "double")
- (set_attr "bdver1_decode" "double")])
-
-(define_insn "*swap<mode>_1"
- [(set (match_operand:SWI12 0 "register_operand" "+r")
- (match_operand:SWI12 1 "register_operand" "+r"))
- (set (match_dup 1)
- (match_dup 0))]
- "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
- "xchg{l}\t%k1, %k0"
- [(set_attr "type" "imov")
- (set_attr "mode" "SI")
- (set_attr "pent_pair" "np")
- (set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "double")
- (set_attr "bdver1_decode" "double")])
-
-;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
-;; is disabled for AMDFAM10
-(define_insn "*swap<mode>_2"
- [(set (match_operand:SWI12 0 "register_operand" "+<r>")
- (match_operand:SWI12 1 "register_operand" "+<r>"))
- (set (match_dup 1)
- (match_dup 0))]
- "TARGET_PARTIAL_REG_STALL"
- "xchg{<imodesuffix>}\t%1, %0"
- [(set_attr "type" "imov")
- (set_attr "mode" "<MODE>")
- (set_attr "pent_pair" "np")
- (set_attr "athlon_decode" "vector")])
-
-(define_expand "movstrict<mode>"
- [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
- (match_operand:SWI12 1 "general_operand"))]
- ""
-{
- if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
- FAIL;
- if (GET_CODE (operands[0]) == SUBREG
- && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
- FAIL;
- /* Don't generate memory->memory moves, go through a register */
- if (MEM_P (operands[0]) && MEM_P (operands[1]))
- operands[1] = force_reg (<MODE>mode, operands[1]);
-})
-
-(define_insn "*movstrict<mode>_1"
- [(set (strict_low_part
- (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
- (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
- "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
- [(set_attr "type" "imov")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*movstrict<mode>_xor"
- [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
- (match_operand:SWI12 1 "const0_operand"))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed"
- "xor{<imodesuffix>}\t%0, %0"
- [(set_attr "type" "alu1")
- (set_attr "mode" "<MODE>")
- (set_attr "length_immediate" "0")])
-
-(define_insn "*mov<mode>_extv_1"
- [(set (match_operand:SWI24 0 "register_operand" "=R")
- (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
- (const_int 8)
- (const_int 8)))]
- ""
- "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
- [(set_attr "type" "imovx")
- (set_attr "mode" "SI")])
-
-(define_insn "*movqi_extv_1_rex64"
- [(set (match_operand:QI 0 "register_operand" "=Q,?R")
- (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
- (const_int 8)
- (const_int 8)))]
- "TARGET_64BIT"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_IMOVX:
- return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
- default:
- return "mov{b}\t{%h1, %0|%0, %h1}";
- }
-}
- [(set (attr "type")
- (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
- (match_test "TARGET_MOVX"))
- (const_string "imovx")
- (const_string "imov")))
- (set (attr "mode")
- (if_then_else (eq_attr "type" "imovx")
- (const_string "SI")
- (const_string "QI")))])
-
-(define_insn "*movqi_extv_1"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
- (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
- (const_int 8)
- (const_int 8)))]
- "!TARGET_64BIT"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_IMOVX:
- return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
- default:
- return "mov{b}\t{%h1, %0|%0, %h1}";
- }
-}
- [(set (attr "type")
- (if_then_else (and (match_operand:QI 0 "register_operand")
- (ior (not (match_operand:QI 0 "QIreg_operand"))
- (match_test "TARGET_MOVX")))
- (const_string "imovx")
- (const_string "imov")))
- (set (attr "mode")
- (if_then_else (eq_attr "type" "imovx")
- (const_string "SI")
- (const_string "QI")))])
-
-(define_insn "*mov<mode>_extzv_1"
- [(set (match_operand:SWI48 0 "register_operand" "=R")
- (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
- (const_int 8)
- (const_int 8)))]
- ""
- "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
- [(set_attr "type" "imovx")
- (set_attr "mode" "SI")])
-
-(define_insn "*movqi_extzv_2_rex64"
- [(set (match_operand:QI 0 "register_operand" "=Q,?R")
- (subreg:QI
- (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
- (const_int 8)
- (const_int 8)) 0))]
- "TARGET_64BIT"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_IMOVX:
- return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
- default:
- return "mov{b}\t{%h1, %0|%0, %h1}";
- }
-}
- [(set (attr "type")
- (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
- (match_test "TARGET_MOVX"))
- (const_string "imovx")
- (const_string "imov")))
- (set (attr "mode")
- (if_then_else (eq_attr "type" "imovx")
- (const_string "SI")
- (const_string "QI")))])
-
-(define_insn "*movqi_extzv_2"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
- (subreg:QI
- (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
- (const_int 8)
- (const_int 8)) 0))]
- "!TARGET_64BIT"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_IMOVX:
- return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
- default:
- return "mov{b}\t{%h1, %0|%0, %h1}";
- }
-}
- [(set (attr "type")
- (if_then_else (and (match_operand:QI 0 "register_operand")
- (ior (not (match_operand:QI 0 "QIreg_operand"))
- (match_test "TARGET_MOVX")))
- (const_string "imovx")
- (const_string "imov")))
- (set (attr "mode")
- (if_then_else (eq_attr "type" "imovx")
- (const_string "SI")
- (const_string "QI")))])
-
-(define_expand "mov<mode>_insv_1"
- [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand")
- (const_int 8)
- (const_int 8))
- (match_operand:SWI48 1 "nonmemory_operand"))])
-
-(define_insn "*mov<mode>_insv_1_rex64"
- [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
- (const_int 8)
- (const_int 8))
- (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
- "TARGET_64BIT"
-{
- if (CONST_INT_P (operands[1]))
- operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
- return "mov{b}\t{%b1, %h0|%h0, %b1}";
-}
- [(set_attr "type" "imov")
- (set_attr "mode" "QI")])
-
-(define_insn "*movsi_insv_1"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
- (const_int 8)
- (const_int 8))
- (match_operand:SI 1 "general_operand" "Qmn"))]
- "!TARGET_64BIT"
-{
- if (CONST_INT_P (operands[1]))
- operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0);
- return "mov{b}\t{%b1, %h0|%h0, %b1}";
-}
- [(set_attr "type" "imov")
- (set_attr "mode" "QI")])
-
-(define_insn "*movqi_insv_2"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
- (const_int 8)
- (const_int 8))
- (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
- (const_int 8)))]
- ""
- "mov{b}\t{%h1, %h0|%h0, %h1}"
- [(set_attr "type" "imov")
- (set_attr "mode" "QI")])
-
-;; Floating point push instructions.
-
-(define_insn "*pushtf"
- [(set (match_operand:TF 0 "push_operand" "=<,<,<")
- (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
- "TARGET_SSE"
-{
- /* This insn should be already split before reg-stack. */
- gcc_unreachable ();
-}
- [(set_attr "type" "multi")
- (set_attr "unit" "sse,*,*")
- (set_attr "mode" "TF,SI,SI")])
-
-;; %%% Kill this when call knows how to work this out.
-(define_split
- [(set (match_operand:TF 0 "push_operand")
- (match_operand:TF 1 "sse_reg_operand"))]
- "TARGET_SSE && reload_completed"
- [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
- (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
-
-(define_insn "*pushxf"
- [(set (match_operand:XF 0 "push_operand" "=<,<")
- (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
- "optimize_function_for_speed_p (cfun)"
-{
- /* This insn should be already split before reg-stack. */
- gcc_unreachable ();
-}
- [(set_attr "type" "multi")
- (set_attr "unit" "i387,*")
- (set_attr "mode" "XF,SI")])
-
-;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
-;; Size of pushxf using integer instructions is 3+3*memory operand size
-;; Pushing using integer instructions is longer except for constants
-;; and direct memory references (assuming that any given constant is pushed
-;; only once, but this ought to be handled elsewhere).
-
-(define_insn "*pushxf_nointeger"
- [(set (match_operand:XF 0 "push_operand" "=<,<")
- (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
- "optimize_function_for_size_p (cfun)"
-{
- /* This insn should be already split before reg-stack. */
- gcc_unreachable ();
-}
- [(set_attr "type" "multi")
- (set_attr "unit" "i387,*")
- (set_attr "mode" "XF,SI")])
-
-;; %%% Kill this when call knows how to work this out.
-(define_split
- [(set (match_operand:XF 0 "push_operand")
- (match_operand:XF 1 "fp_register_operand"))]
- "reload_completed"
- [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
- (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
- "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
-
-(define_insn "*pushdf_rex64"
- [(set (match_operand:DF 0 "push_operand" "=<,<,<")
- (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
- "TARGET_64BIT"
-{
- /* This insn should be already split before reg-stack. */
- gcc_unreachable ();
-}
- [(set_attr "type" "multi")
- (set_attr "unit" "i387,*,*")
- (set_attr "mode" "DF,DI,DF")])
-
-;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
-;; Size of pushdf using integer instructions is 2+2*memory operand size
-;; On the average, pushdf using integers can be still shorter.
-
-(define_insn "*pushdf"
- [(set (match_operand:DF 0 "push_operand" "=<,<,<")
- (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
- "!TARGET_64BIT"
-{
- /* This insn should be already split before reg-stack. */
- gcc_unreachable ();
-}
- [(set_attr "isa" "*,*,sse2")
- (set_attr "type" "multi")
- (set_attr "unit" "i387,*,*")
- (set_attr "mode" "DF,DI,DF")])
-
-;; %%% Kill this when call knows how to work this out.
-(define_split
- [(set (match_operand:DF 0 "push_operand")
- (match_operand:DF 1 "any_fp_register_operand"))]
- "reload_completed"
- [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
- (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
-
-(define_insn "*pushsf_rex64"
- [(set (match_operand:SF 0 "push_operand" "=X,X,X")
- (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
- "TARGET_64BIT"
-{
- /* Anything else should be already split before reg-stack. */
- gcc_assert (which_alternative == 1);
- return "push{q}\t%q1";
-}
- [(set_attr "type" "multi,push,multi")
- (set_attr "unit" "i387,*,*")
- (set_attr "mode" "SF,DI,SF")])
-
-(define_insn "*pushsf"
- [(set (match_operand:SF 0 "push_operand" "=<,<,<")
- (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
- "!TARGET_64BIT"
-{
- /* Anything else should be already split before reg-stack. */
- gcc_assert (which_alternative == 1);
- return "push{l}\t%1";
-}
- [(set_attr "type" "multi,push,multi")
- (set_attr "unit" "i387,*,*")
- (set_attr "mode" "SF,SI,SF")])
-
-;; %%% Kill this when call knows how to work this out.
-(define_split
- [(set (match_operand:SF 0 "push_operand")
- (match_operand:SF 1 "any_fp_register_operand"))]
- "reload_completed"
- [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
- (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
- "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
-
-(define_split
- [(set (match_operand:SF 0 "push_operand")
- (match_operand:SF 1 "memory_operand"))]
- "reload_completed
- && (operands[2] = find_constant_src (insn))"
- [(set (match_dup 0) (match_dup 2))])
-
-(define_split
- [(set (match_operand 0 "push_operand")
- (match_operand 1 "general_operand"))]
- "reload_completed
- && (GET_MODE (operands[0]) == TFmode
- || GET_MODE (operands[0]) == XFmode
- || GET_MODE (operands[0]) == DFmode)
- && !ANY_FP_REG_P (operands[1])"
- [(const_int 0)]
- "ix86_split_long_move (operands); DONE;")
-
-;; Floating point move instructions.
-
-(define_expand "movtf"
- [(set (match_operand:TF 0 "nonimmediate_operand")
- (match_operand:TF 1 "nonimmediate_operand"))]
- "TARGET_64BIT || TARGET_SSE"
-{
- ix86_expand_move (TFmode, operands);
- DONE;
-})
-
-(define_expand "mov<mode>"
- [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
- (match_operand:X87MODEF 1 "general_operand"))]
- ""
- "ix86_expand_move (<MODE>mode, operands); DONE;")
-
-(define_insn "*movtf_internal_rex64"
- [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
- (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
- "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
- && (!can_create_pseudo_p ()
- || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
- || GET_CODE (operands[1]) != CONST_DOUBLE
- || (optimize_function_for_size_p (cfun)
- && standard_sse_constant_p (operands[1])
- && !memory_operand (operands[0], TFmode))
- || (!TARGET_MEMORY_MISMATCH_STALL
- && memory_operand (operands[0], TFmode)))"
-{
- switch (which_alternative)
- {
- case 0:
- return standard_sse_constant_opcode (insn, operands[1]);
- case 1:
- case 2:
- /* Handle misaligned load/store since we
- don't have movmisaligntf pattern. */
- if (misaligned_operand (operands[0], TFmode)
- || misaligned_operand (operands[1], TFmode))
- {
- if (get_attr_mode (insn) == MODE_V4SF)
- return "%vmovups\t{%1, %0|%0, %1}";
- else
- return "%vmovdqu\t{%1, %0|%0, %1}";
- }
- else
- {
- if (get_attr_mode (insn) == MODE_V4SF)
- return "%vmovaps\t{%1, %0|%0, %1}";
- else
- return "%vmovdqa\t{%1, %0|%0, %1}";
- }
-
- case 3:
- case 4:
- return "#";
-
- default:
- gcc_unreachable ();
- }
-}
- [(set_attr "type" "sselog1,ssemov,ssemov,*,*")
- (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
- (set (attr "mode")
- (cond [(eq_attr "alternative" "3,4")
- (const_string "DI")
- (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
- (const_string "V4SF")
- (and (eq_attr "alternative" "2")
- (match_test "TARGET_SSE_TYPELESS_STORES"))
- (const_string "V4SF")
- (match_test "TARGET_AVX")
- (const_string "TI")
- (ior (not (match_test "TARGET_SSE2"))
- (match_test "optimize_function_for_size_p (cfun)"))
- (const_string "V4SF")
- ]
- (const_string "TI")))])
-
-(define_insn "*movtf_internal_sse"
- [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m")
- (match_operand:TF 1 "general_operand" "C ,xm,x"))]
- "TARGET_SSE && !TARGET_64BIT
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))
- && (!can_create_pseudo_p ()
- || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
- || GET_CODE (operands[1]) != CONST_DOUBLE
- || (optimize_function_for_size_p (cfun)
- && standard_sse_constant_p (operands[1])
- && !memory_operand (operands[0], TFmode))
- || (!TARGET_MEMORY_MISMATCH_STALL
- && memory_operand (operands[0], TFmode)))"
-{
- switch (which_alternative)
- {
- case 0:
- return standard_sse_constant_opcode (insn, operands[1]);
- case 1:
- case 2:
- /* Handle misaligned load/store since we
- don't have movmisaligntf pattern. */
- if (misaligned_operand (operands[0], TFmode)
- || misaligned_operand (operands[1], TFmode))
- {
- if (get_attr_mode (insn) == MODE_V4SF)
- return "%vmovups\t{%1, %0|%0, %1}";
- else
- return "%vmovdqu\t{%1, %0|%0, %1}";
- }
- else
- {
- if (get_attr_mode (insn) == MODE_V4SF)
- return "%vmovaps\t{%1, %0|%0, %1}";
- else
- return "%vmovdqa\t{%1, %0|%0, %1}";
- }
- default:
- gcc_unreachable ();
- }
-}
- [(set_attr "type" "sselog1,ssemov,ssemov")
- (set_attr "prefix" "maybe_vex")
- (set (attr "mode")
- (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
- (const_string "V4SF")
- (and (eq_attr "alternative" "2")
- (match_test "TARGET_SSE_TYPELESS_STORES"))
- (const_string "V4SF")
- (match_test "TARGET_AVX")
- (const_string "TI")
- (ior (not (match_test "TARGET_SSE2"))
- (match_test "optimize_function_for_size_p (cfun)"))
- (const_string "V4SF")
- ]
- (const_string "TI")))])
-
-(define_insn "*movxf_internal_rex64"
- [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
- (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,Yx*rC"))]
- "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
- && (!can_create_pseudo_p ()
- || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
- || GET_CODE (operands[1]) != CONST_DOUBLE
- || (optimize_function_for_size_p (cfun)
- && standard_80387_constant_p (operands[1]) > 0
- && !memory_operand (operands[0], XFmode))
- || (!TARGET_MEMORY_MISMATCH_STALL
- && memory_operand (operands[0], XFmode)))"
-{
- switch (which_alternative)
- {
- case 0:
- case 1:
- return output_387_reg_move (insn, operands);
-
- case 2:
- return standard_80387_constant_opcode (operands[1]);
-
- case 3:
- case 4:
- return "#";
-
- default:
- gcc_unreachable ();
- }
-}
- [(set_attr "type" "fmov,fmov,fmov,multi,multi")
- (set_attr "mode" "XF,XF,XF,SI,SI")])
-
-;; Possible store forwarding (partial memory) stall in alternative 4.
-(define_insn "*movxf_internal"
- [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
- (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,Yx*rF"))]
- "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
- && (!can_create_pseudo_p ()
- || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
- || GET_CODE (operands[1]) != CONST_DOUBLE
- || (optimize_function_for_size_p (cfun)
- && standard_80387_constant_p (operands[1]) > 0
- && !memory_operand (operands[0], XFmode))
- || (!TARGET_MEMORY_MISMATCH_STALL
- && memory_operand (operands[0], XFmode)))"
-{
- switch (which_alternative)
- {
- case 0:
- case 1:
- return output_387_reg_move (insn, operands);
-
- case 2:
- return standard_80387_constant_opcode (operands[1]);
-
- case 3:
- case 4:
- return "#";
-
- default:
- gcc_unreachable ();
- }
-}
- [(set_attr "type" "fmov,fmov,fmov,multi,multi")
- (set_attr "mode" "XF,XF,XF,SI,SI")])
-
-(define_insn "*movdf_internal_rex64"
- [(set (match_operand:DF 0 "nonimmediate_operand"
- "=Yf*f,m ,Yf*f,?r,?m,?r,?r,x,x,x,m,Yi,r")
- (match_operand:DF 1 "general_operand"
- "Yf*fm,Yf*f,G ,rm,rC,C ,F ,C,x,m,x,r ,Yi"))]
- "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
- && (!can_create_pseudo_p ()
- || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
- || GET_CODE (operands[1]) != CONST_DOUBLE
- || (optimize_function_for_size_p (cfun)
- && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
- && standard_80387_constant_p (operands[1]) > 0)
- || (TARGET_SSE2 && TARGET_SSE_MATH
- && standard_sse_constant_p (operands[1]))))
- || memory_operand (operands[0], DFmode))"
-{
- switch (which_alternative)
- {
- case 0:
- case 1:
- return output_387_reg_move (insn, operands);
-
- case 2:
- return standard_80387_constant_opcode (operands[1]);
-
- case 3:
- case 4:
- return "mov{q}\t{%1, %0|%0, %1}";
-
- case 5:
- return "mov{l}\t{%1, %k0|%k0, %1}";
-
- case 6:
- return "movabs{q}\t{%1, %0|%0, %1}";
-
- case 7:
- return standard_sse_constant_opcode (insn, operands[1]);
-
- case 8:
- case 9:
- case 10:
- switch (get_attr_mode (insn))
- {
- case MODE_V2DF:
- return "%vmovapd\t{%1, %0|%0, %1}";
- case MODE_V4SF:
- return "%vmovaps\t{%1, %0|%0, %1}";
-
- case MODE_DI:
- return "%vmovq\t{%1, %0|%0, %1}";
- case MODE_DF:
- if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
- return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
- return "%vmovsd\t{%1, %0|%0, %1}";
- case MODE_V1DF:
- return "%vmovlpd\t{%1, %d0|%d0, %1}";
- case MODE_V2SF:
- return "%vmovlps\t{%1, %d0|%d0, %1}";
- default:
- gcc_unreachable ();
- }
-
- case 11:
- case 12:
- /* Handle broken assemblers that require movd instead of movq. */
- return "%vmovd\t{%1, %0|%0, %1}";
-
- default:
- gcc_unreachable();
- }
-}
- [(set (attr "type")
- (cond [(eq_attr "alternative" "0,1,2")
- (const_string "fmov")
- (eq_attr "alternative" "3,4,5,6")
- (const_string "imov")
- (eq_attr "alternative" "7")
- (const_string "sselog1")
- ]
- (const_string "ssemov")))
- (set (attr "modrm")
- (if_then_else
- (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
- (const_string "0")
- (const_string "*")))
- (set (attr "length_immediate")
- (if_then_else
- (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
- (const_string "8")
- (const_string "*")))
- (set (attr "prefix")
- (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
- (const_string "orig")
- (const_string "maybe_vex")))
- (set (attr "prefix_data16")
- (if_then_else (eq_attr "mode" "V1DF")
- (const_string "1")
- (const_string "*")))
- (set (attr "mode")
- (cond [(eq_attr "alternative" "0,1,2")
- (const_string "DF")
- (eq_attr "alternative" "3,4,6,11,12")
- (const_string "DI")
- (eq_attr "alternative" "5")
- (const_string "SI")
-
- /* xorps is one byte shorter for !TARGET_AVX. */
- (eq_attr "alternative" "7")
- (cond [(match_test "TARGET_AVX")
- (const_string "V2DF")
- (match_test "optimize_function_for_size_p (cfun)")
- (const_string "V4SF")
- (match_test "TARGET_SSE_LOAD0_BY_PXOR")
- (const_string "TI")
- ]
- (const_string "V2DF"))
-
- /* For architectures resolving dependencies on
- whole SSE registers use APD move to break dependency
- chains, otherwise use short move to avoid extra work.
-
- movaps encodes one byte shorter for !TARGET_AVX. */
- (eq_attr "alternative" "8")
- (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
- (const_string "V4SF")
- (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
- (const_string "V2DF")
- (match_test "TARGET_AVX")
- (const_string "DF")
- (match_test "optimize_function_for_size_p (cfun)")
- (const_string "V4SF")
- ]
- (const_string "DF"))
- /* For architectures resolving dependencies on register
- parts we may avoid extra work to zero out upper part
- of register. */
- (eq_attr "alternative" "9")
- (if_then_else
- (match_test "TARGET_SSE_SPLIT_REGS")
- (const_string "V1DF")
- (const_string "DF"))
- ]
- (const_string "DF")))])
-
-;; Possible store forwarding (partial memory) stall in alternative 4.
-(define_insn "*movdf_internal"
- [(set (match_operand:DF 0 "nonimmediate_operand"
- "=Yf*f,m ,Yf*f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
- (match_operand:DF 1 "general_operand"
- "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,C,x,m,x,C ,*x,m ,*x"))]
- "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
- && (!can_create_pseudo_p ()
- || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
- || GET_CODE (operands[1]) != CONST_DOUBLE
- || (optimize_function_for_size_p (cfun)
- && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
- && standard_80387_constant_p (operands[1]) > 0)
- || (TARGET_SSE2 && TARGET_SSE_MATH
- && standard_sse_constant_p (operands[1])))
- && !memory_operand (operands[0], DFmode))
- || (!TARGET_MEMORY_MISMATCH_STALL
- && memory_operand (operands[0], DFmode)))"
-{
- switch (which_alternative)
- {
- case 0:
- case 1:
- return output_387_reg_move (insn, operands);
-
- case 2:
- return standard_80387_constant_opcode (operands[1]);
-
- case 3:
- case 4:
- return "#";
-
- case 5:
- case 9:
- return standard_sse_constant_opcode (insn, operands[1]);
-
- case 6:
- case 7:
- case 8:
- case 10:
- case 11:
- case 12:
- switch (get_attr_mode (insn))
- {
- case MODE_V2DF:
- return "%vmovapd\t{%1, %0|%0, %1}";
- case MODE_V4SF:
- return "%vmovaps\t{%1, %0|%0, %1}";
-
- case MODE_DI:
- return "%vmovq\t{%1, %0|%0, %1}";
- case MODE_DF:
- if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
- return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
- return "%vmovsd\t{%1, %0|%0, %1}";
- case MODE_V1DF:
- return "%vmovlpd\t{%1, %d0|%d0, %1}";
- case MODE_V2SF:
- return "%vmovlps\t{%1, %d0|%d0, %1}";
- default:
- gcc_unreachable ();
- }
-
- default:
- gcc_unreachable ();
- }
-}
- [(set (attr "isa")
- (if_then_else (eq_attr "alternative" "5,6,7,8")
- (const_string "sse2")
- (const_string "*")))
- (set (attr "type")
- (cond [(eq_attr "alternative" "0,1,2")
- (const_string "fmov")
- (eq_attr "alternative" "3,4")
- (const_string "multi")
- (eq_attr "alternative" "5,9")
- (const_string "sselog1")
- ]
- (const_string "ssemov")))
- (set (attr "prefix")
- (if_then_else (eq_attr "alternative" "0,1,2,3,4")
- (const_string "orig")
- (const_string "maybe_vex")))
- (set (attr "prefix_data16")
- (if_then_else (eq_attr "mode" "V1DF")
- (const_string "1")
- (const_string "*")))
- (set (attr "mode")
- (cond [(eq_attr "alternative" "0,1,2")
- (const_string "DF")
- (eq_attr "alternative" "3,4")
- (const_string "SI")
-
- /* For SSE1, we have many fewer alternatives. */
- (not (match_test "TARGET_SSE2"))
- (if_then_else
- (eq_attr "alternative" "5,6,9,10")
- (const_string "V4SF")
- (const_string "V2SF"))
-
- /* xorps is one byte shorter for !TARGET_AVX. */
- (eq_attr "alternative" "5,9")
- (cond [(match_test "TARGET_AVX")
- (const_string "V2DF")
- (match_test "optimize_function_for_size_p (cfun)")
- (const_string "V4SF")
- (match_test "TARGET_SSE_LOAD0_BY_PXOR")
- (const_string "TI")
- ]
- (const_string "V2DF"))
-
- /* For architectures resolving dependencies on
- whole SSE registers use APD move to break dependency
- chains, otherwise use short move to avoid extra work.
-
- movaps encodes one byte shorter for !TARGET_AVX. */
- (eq_attr "alternative" "6,10")
- (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
- (const_string "V4SF")
- (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
- (const_string "V2DF")
- (match_test "TARGET_AVX")
- (const_string "DF")
- (match_test "optimize_function_for_size_p (cfun)")
- (const_string "V4SF")
- ]
- (const_string "DF"))
-
- /* For architectures resolving dependencies on register
- parts we may avoid extra work to zero out upper part
- of register. */
- (eq_attr "alternative" "7,11")
- (if_then_else
- (match_test "TARGET_SSE_SPLIT_REGS")
- (const_string "V1DF")
- (const_string "DF"))
- ]
- (const_string "DF")))])
-
-(define_insn "*movsf_internal"
- [(set (match_operand:SF 0 "nonimmediate_operand"
- "=Yf*f,m ,Yf*f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
- (match_operand:SF 1 "general_operand"
- "Yf*fm,Yf*f,G ,rmF,rF,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
- "!(MEM_P (operands[0]) && MEM_P (operands[1]))
- && (!can_create_pseudo_p ()
- || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
- || GET_CODE (operands[1]) != CONST_DOUBLE
- || (optimize_function_for_size_p (cfun)
- && ((!TARGET_SSE_MATH
- && standard_80387_constant_p (operands[1]) > 0)
- || (TARGET_SSE_MATH
- && standard_sse_constant_p (operands[1]))))
- || memory_operand (operands[0], SFmode))"
-{
- switch (which_alternative)
- {
- case 0:
- case 1:
- return output_387_reg_move (insn, operands);
-
- case 2:
- return standard_80387_constant_opcode (operands[1]);
-
- case 3:
- case 4:
- return "mov{l}\t{%1, %0|%0, %1}";
-
- case 5:
- return standard_sse_constant_opcode (insn, operands[1]);
-
- case 6:
- if (get_attr_mode (insn) == MODE_V4SF)
- return "%vmovaps\t{%1, %0|%0, %1}";
- if (TARGET_AVX)
- return "vmovss\t{%1, %0, %0|%0, %0, %1}";
-
- case 7:
- case 8:
- return "%vmovss\t{%1, %0|%0, %1}";
-
- case 9:
- case 10:
- case 14:
- case 15:
- return "movd\t{%1, %0|%0, %1}";
-
- case 11:
- return "movq\t{%1, %0|%0, %1}";
-
- case 12:
- case 13:
- return "%vmovd\t{%1, %0|%0, %1}";
-
- default:
- gcc_unreachable ();
- }
-}
- [(set (attr "type")
- (cond [(eq_attr "alternative" "0,1,2")
- (const_string "fmov")
- (eq_attr "alternative" "3,4")
- (const_string "imov")
- (eq_attr "alternative" "5")
- (const_string "sselog1")
- (eq_attr "alternative" "9,10,11,14,15")
- (const_string "mmxmov")
- ]
- (const_string "ssemov")))
- (set (attr "prefix")
- (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
- (const_string "maybe_vex")
- (const_string "orig")))
- (set (attr "mode")
- (cond [(eq_attr "alternative" "3,4,9,10")
- (const_string "SI")
- (eq_attr "alternative" "5")
- (cond [(match_test "TARGET_AVX")
- (const_string "V4SF")
- (ior (not (match_test "TARGET_SSE2"))
- (match_test "optimize_function_for_size_p (cfun)"))
- (const_string "V4SF")
- (match_test "TARGET_SSE_LOAD0_BY_PXOR")
- (const_string "TI")
- ]
- (const_string "V4SF"))
-
- /* For architectures resolving dependencies on
- whole SSE registers use APS move to break dependency
- chains, otherwise use short move to avoid extra work.
-
- Do the same for architectures resolving dependencies on
- the parts. While in DF mode it is better to always handle
- just register parts, the SF mode is different due to lack
- of instructions to load just part of the register. It is
- better to maintain the whole registers in single format
- to avoid problems on using packed logical operations. */
- (eq_attr "alternative" "6")
- (if_then_else
- (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
- (match_test "TARGET_SSE_SPLIT_REGS"))
- (const_string "V4SF")
- (const_string "SF"))
- (eq_attr "alternative" "11")
- (const_string "DI")]
- (const_string "SF")))])
-
-(define_split
- [(set (match_operand 0 "any_fp_register_operand")
- (match_operand 1 "memory_operand"))]
- "reload_completed
- && (GET_MODE (operands[0]) == TFmode
- || GET_MODE (operands[0]) == XFmode
- || GET_MODE (operands[0]) == DFmode
- || GET_MODE (operands[0]) == SFmode)
- && (operands[2] = find_constant_src (insn))"
- [(set (match_dup 0) (match_dup 2))]
-{
- rtx c = operands[2];
- int r = REGNO (operands[0]);
-
- if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
- || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
- FAIL;
-})
-
-(define_split
- [(set (match_operand 0 "any_fp_register_operand")
- (float_extend (match_operand 1 "memory_operand")))]
- "reload_completed
- && (GET_MODE (operands[0]) == TFmode
- || GET_MODE (operands[0]) == XFmode
- || GET_MODE (operands[0]) == DFmode)
- && (operands[2] = find_constant_src (insn))"
- [(set (match_dup 0) (match_dup 2))]
-{
- rtx c = operands[2];
- int r = REGNO (operands[0]);
-
- if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
- || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
- FAIL;
-})
-
-;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
-(define_split
- [(set (match_operand:X87MODEF 0 "fp_register_operand")
- (match_operand:X87MODEF 1 "immediate_operand"))]
- "reload_completed
- && (standard_80387_constant_p (operands[1]) == 8
- || standard_80387_constant_p (operands[1]) == 9)"
- [(set (match_dup 0)(match_dup 1))
- (set (match_dup 0)
- (neg:X87MODEF (match_dup 0)))]
-{
- REAL_VALUE_TYPE r;
-
- REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
- if (real_isnegzero (&r))
- operands[1] = CONST0_RTX (<MODE>mode);
- else
- operands[1] = CONST1_RTX (<MODE>mode);
-})
-
-(define_split
- [(set (match_operand 0 "nonimmediate_operand")
- (match_operand 1 "general_operand"))]
- "reload_completed
- && (GET_MODE (operands[0]) == TFmode
- || GET_MODE (operands[0]) == XFmode
- || GET_MODE (operands[0]) == DFmode)
- && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
- [(const_int 0)]
- "ix86_split_long_move (operands); DONE;")
-
-(define_insn "swapxf"
- [(set (match_operand:XF 0 "register_operand" "+f")
- (match_operand:XF 1 "register_operand" "+f"))
- (set (match_dup 1)
- (match_dup 0))]
- "TARGET_80387"
-{
- if (STACK_TOP_P (operands[0]))
- return "fxch\t%1";
- else
- return "fxch\t%0";
-}
- [(set_attr "type" "fxch")
- (set_attr "mode" "XF")])
-
-(define_insn "*swap<mode>"
- [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
- (match_operand:MODEF 1 "fp_register_operand" "+f"))
- (set (match_dup 1)
- (match_dup 0))]
- "TARGET_80387 || reload_completed"
-{
- if (STACK_TOP_P (operands[0]))
- return "fxch\t%1";
- else
- return "fxch\t%0";
-}
- [(set_attr "type" "fxch")
- (set_attr "mode" "<MODE>")])
-
-;; Zero extension instructions
-
-(define_expand "zero_extendsidi2"
- [(set (match_operand:DI 0 "nonimmediate_operand")
- (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
-
-(define_insn "*zero_extendsidi2_rex64"
- [(set (match_operand:DI 0 "nonimmediate_operand"
- "=r ,o,?*Ym,?!*y,?*Yi,?*x")
- (zero_extend:DI
- (match_operand:SI 1 "x86_64_zext_general_operand"
- "rmWz,0,r ,m ,r ,m")))]
- "TARGET_64BIT"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_IMOVX:
- if (ix86_use_lea_for_mov (insn, operands))
- return "lea{l}\t{%E1, %k0|%k0, %E1}";
- else
- return "mov{l}\t{%1, %k0|%k0, %1}";
-
- case TYPE_MULTI:
- return "#";
-
- case TYPE_MMXMOV:
- return "movd\t{%1, %0|%0, %1}";
-
- case TYPE_SSEMOV:
- return "%vmovd\t{%1, %0|%0, %1}";
-
- default:
- gcc_unreachable ();
- }
-}
- [(set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
- (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
- (set_attr "prefix_0f" "0,*,*,*,*,*")
- (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
-
-(define_insn "*zero_extendsidi2"
- [(set (match_operand:DI 0 "nonimmediate_operand"
- "=ro,?r,?o,?*Ym,?!*y,?*Yi,?*x")
- (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
- "0 ,rm,r ,r ,m ,r ,m")))]
- "!TARGET_64BIT"
- "@
- #
- #
- #
- movd\t{%1, %0|%0, %1}
- movd\t{%1, %0|%0, %1}
- %vmovd\t{%1, %0|%0, %1}
- %vmovd\t{%1, %0|%0, %1}"
- [(set_attr "isa" "*,*,*,*,*,*,sse2")
- (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
- (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
- (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
-
-(define_split
- [(set (match_operand:DI 0 "memory_operand")
- (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
- "reload_completed"
- [(set (match_dup 4) (const_int 0))]
- "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
-
-(define_split
- [(set (match_operand:DI 0 "register_operand")
- (zero_extend:DI (match_operand:SI 1 "register_operand")))]
- "!TARGET_64BIT && reload_completed
- && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
- && true_regnum (operands[0]) == true_regnum (operands[1])"
- [(set (match_dup 4) (const_int 0))]
- "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
-
-(define_split
- [(set (match_operand:DI 0 "nonimmediate_operand")
- (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
- "!TARGET_64BIT && reload_completed
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))
- && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
- [(set (match_dup 3) (match_dup 1))
- (set (match_dup 4) (const_int 0))]
- "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
-
-(define_insn "zero_extend<mode>di2"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
- "TARGET_64BIT"
- "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
- [(set_attr "type" "imovx")
- (set_attr "mode" "SI")])
-
-(define_expand "zero_extend<mode>si2"
- [(set (match_operand:SI 0 "register_operand")
- (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
- ""
-{
- if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
- {
- operands[1] = force_reg (<MODE>mode, operands[1]);
- emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
- DONE;
- }
-})
-
-(define_insn_and_split "zero_extend<mode>si2_and"
- [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
- (zero_extend:SI
- (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
- "#"
- "&& reload_completed"
- [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
- (clobber (reg:CC FLAGS_REG))])]
-{
- if (true_regnum (operands[0]) != true_regnum (operands[1]))
- {
- ix86_expand_clear (operands[0]);
-
- gcc_assert (!TARGET_PARTIAL_REG_STALL);
- emit_insn (gen_movstrict<mode>
- (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
- DONE;
- }
-
- operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
-}
- [(set_attr "type" "alu1")
- (set_attr "mode" "SI")])
-
-(define_insn "*zero_extend<mode>si2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (zero_extend:SI
- (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
- "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
- "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
- [(set_attr "type" "imovx")
- (set_attr "mode" "SI")])
-
-(define_expand "zero_extendqihi2"
- [(set (match_operand:HI 0 "register_operand")
- (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
- ""
-{
- if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
- {
- operands[1] = force_reg (QImode, operands[1]);
- emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
- DONE;
- }
-})
-
-(define_insn_and_split "zero_extendqihi2_and"
- [(set (match_operand:HI 0 "register_operand" "=r,?&q")
- (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
- "#"
- "&& reload_completed"
- [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
- (clobber (reg:CC FLAGS_REG))])]
-{
- if (true_regnum (operands[0]) != true_regnum (operands[1]))
- {
- ix86_expand_clear (operands[0]);
-
- gcc_assert (!TARGET_PARTIAL_REG_STALL);
- emit_insn (gen_movstrictqi
- (gen_lowpart (QImode, operands[0]), operands[1]));
- DONE;
- }
-
- operands[0] = gen_lowpart (SImode, operands[0]);
-}
- [(set_attr "type" "alu1")
- (set_attr "mode" "SI")])
-
-; zero extend to SImode to avoid partial register stalls
-(define_insn "*zero_extendqihi2"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
- "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
- "movz{bl|x}\t{%1, %k0|%k0, %1}"
- [(set_attr "type" "imovx")
- (set_attr "mode" "SI")])
-
-;; Sign extension instructions
-
-(define_expand "extendsidi2"
- [(set (match_operand:DI 0 "register_operand")
- (sign_extend:DI (match_operand:SI 1 "register_operand")))]
- ""
-{
- if (!TARGET_64BIT)
- {
- emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
- DONE;
- }
-})
-
-(define_insn "*extendsidi2_rex64"
- [(set (match_operand:DI 0 "register_operand" "=*a,r")
- (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
- "TARGET_64BIT"
- "@
- {cltq|cdqe}
- movs{lq|x}\t{%1, %0|%0, %1}"
- [(set_attr "type" "imovx")
- (set_attr "mode" "DI")
- (set_attr "prefix_0f" "0")
- (set_attr "modrm" "0,1")])
-
-(define_insn "extendsidi2_1"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
- (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
- (clobber (reg:CC FLAGS_REG))
- (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
- "!TARGET_64BIT"
- "#")
-
-;; Split the memory case. If the source register doesn't die, it will stay
-;; this way, if it does die, following peephole2s take care of it.
-(define_split
- [(set (match_operand:DI 0 "memory_operand")
- (sign_extend:DI (match_operand:SI 1 "register_operand")))
- (clobber (reg:CC FLAGS_REG))
- (clobber (match_operand:SI 2 "register_operand"))]
- "reload_completed"
- [(const_int 0)]
-{
- split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
-
- emit_move_insn (operands[3], operands[1]);
-
- /* Generate a cltd if possible and doing so it profitable. */
- if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
- && true_regnum (operands[1]) == AX_REG
- && true_regnum (operands[2]) == DX_REG)
- {
- emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
- }
- else
- {
- emit_move_insn (operands[2], operands[1]);
- emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
- }
- emit_move_insn (operands[4], operands[2]);
- DONE;
-})
-
-;; Peepholes for the case where the source register does die, after
-;; being split with the above splitter.
-(define_peephole2
- [(set (match_operand:SI 0 "memory_operand")
- (match_operand:SI 1 "register_operand"))
- (set (match_operand:SI 2 "register_operand") (match_dup 1))
- (parallel [(set (match_dup 2)
- (ashiftrt:SI (match_dup 2) (const_int 31)))
- (clobber (reg:CC FLAGS_REG))])
- (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
- "REGNO (operands[1]) != REGNO (operands[2])
- && peep2_reg_dead_p (2, operands[1])
- && peep2_reg_dead_p (4, operands[2])
- && !reg_mentioned_p (operands[2], operands[3])"
- [(set (match_dup 0) (match_dup 1))
- (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
- (clobber (reg:CC FLAGS_REG))])
- (set (match_dup 3) (match_dup 1))])
-
-(define_peephole2
- [(set (match_operand:SI 0 "memory_operand")
- (match_operand:SI 1 "register_operand"))
- (parallel [(set (match_operand:SI 2 "register_operand")
- (ashiftrt:SI (match_dup 1) (const_int 31)))
- (clobber (reg:CC FLAGS_REG))])
- (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
- "/* cltd is shorter than sarl $31, %eax */
- !optimize_function_for_size_p (cfun)
- && true_regnum (operands[1]) == AX_REG
- && true_regnum (operands[2]) == DX_REG
- && peep2_reg_dead_p (2, operands[1])
- && peep2_reg_dead_p (3, operands[2])
- && !reg_mentioned_p (operands[2], operands[3])"
- [(set (match_dup 0) (match_dup 1))
- (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
- (clobber (reg:CC FLAGS_REG))])
- (set (match_dup 3) (match_dup 1))])
-
-;; Extend to register case. Optimize case where source and destination
-;; registers match and cases where we can use cltd.
-(define_split
- [(set (match_operand:DI 0 "register_operand")
- (sign_extend:DI (match_operand:SI 1 "register_operand")))
- (clobber (reg:CC FLAGS_REG))
- (clobber (match_scratch:SI 2))]
- "reload_completed"
- [(const_int 0)]
-{
- split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
-
- if (true_regnum (operands[3]) != true_regnum (operands[1]))
- emit_move_insn (operands[3], operands[1]);
-
- /* Generate a cltd if possible and doing so it profitable. */
- if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
- && true_regnum (operands[3]) == AX_REG
- && true_regnum (operands[4]) == DX_REG)
- {
- emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
- DONE;
- }
-
- if (true_regnum (operands[4]) != true_regnum (operands[1]))
- emit_move_insn (operands[4], operands[1]);
-
- emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
- DONE;
-})
-
-(define_insn "extend<mode>di2"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (sign_extend:DI
- (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
- "TARGET_64BIT"
- "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
- [(set_attr "type" "imovx")
- (set_attr "mode" "DI")])
-
-(define_insn "extendhisi2"
- [(set (match_operand:SI 0 "register_operand" "=*a,r")
- (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
- ""
-{
- switch (get_attr_prefix_0f (insn))
- {
- case 0:
- return "{cwtl|cwde}";
- default:
- return "movs{wl|x}\t{%1, %0|%0, %1}";
- }
-}
- [(set_attr "type" "imovx")
- (set_attr "mode" "SI")
- (set (attr "prefix_0f")
- ;; movsx is short decodable while cwtl is vector decoded.
- (if_then_else (and (eq_attr "cpu" "!k6")
- (eq_attr "alternative" "0"))
- (const_string "0")
- (const_string "1")))
- (set (attr "modrm")
- (if_then_else (eq_attr "prefix_0f" "0")
- (const_string "0")
- (const_string "1")))])
-
-(define_insn "*extendhisi2_zext"
- [(set (match_operand:DI 0 "register_operand" "=*a,r")
- (zero_extend:DI
- (sign_extend:SI
- (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
- "TARGET_64BIT"
-{
- switch (get_attr_prefix_0f (insn))
- {
- case 0:
- return "{cwtl|cwde}";
- default:
- return "movs{wl|x}\t{%1, %k0|%k0, %1}";
- }
-}
- [(set_attr "type" "imovx")
- (set_attr "mode" "SI")
- (set (attr "prefix_0f")
- ;; movsx is short decodable while cwtl is vector decoded.
- (if_then_else (and (eq_attr "cpu" "!k6")
- (eq_attr "alternative" "0"))
- (const_string "0")
- (const_string "1")))
- (set (attr "modrm")
- (if_then_else (eq_attr "prefix_0f" "0")
- (const_string "0")
- (const_string "1")))])
-
-(define_insn "extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
- ""
- "movs{bl|x}\t{%1, %0|%0, %1}"
- [(set_attr "type" "imovx")
- (set_attr "mode" "SI")])
-
-(define_insn "*extendqisi2_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
- "TARGET_64BIT"
- "movs{bl|x}\t{%1, %k0|%k0, %1}"
- [(set_attr "type" "imovx")
- (set_attr "mode" "SI")])
-
-(define_insn "extendqihi2"
- [(set (match_operand:HI 0 "register_operand" "=*a,r")
- (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
- ""
-{
- switch (get_attr_prefix_0f (insn))
- {
- case 0:
- return "{cbtw|cbw}";
- default:
- return "movs{bw|x}\t{%1, %0|%0, %1}";
- }
-}
- [(set_attr "type" "imovx")
- (set_attr "mode" "HI")
- (set (attr "prefix_0f")
- ;; movsx is short decodable while cwtl is vector decoded.
- (if_then_else (and (eq_attr "cpu" "!k6")
- (eq_attr "alternative" "0"))
- (const_string "0")
- (const_string "1")))
- (set (attr "modrm")
- (if_then_else (eq_attr "prefix_0f" "0")
- (const_string "0")
- (const_string "1")))])
-
-;; Conversions between float and double.
-
-;; These are all no-ops in the model used for the 80387.
-;; So just emit moves.
-
-;; %%% Kill these when call knows how to work out a DFmode push earlier.
-(define_split
- [(set (match_operand:DF 0 "push_operand")
- (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
- "reload_completed"
- [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
- (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
-
-(define_split
- [(set (match_operand:XF 0 "push_operand")
- (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
- "reload_completed"
- [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
- (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
- "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
-
-(define_expand "extendsfdf2"
- [(set (match_operand:DF 0 "nonimmediate_operand")
- (float_extend:DF (match_operand:SF 1 "general_operand")))]
- "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
-{
- /* ??? Needed for compress_float_constant since all fp constants
- are TARGET_LEGITIMATE_CONSTANT_P. */
- if (GET_CODE (operands[1]) == CONST_DOUBLE)
- {
- if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
- && standard_80387_constant_p (operands[1]) > 0)
- {
- operands[1] = simplify_const_unary_operation
- (FLOAT_EXTEND, DFmode, operands[1], SFmode);
- emit_move_insn_1 (operands[0], operands[1]);
- DONE;
- }
- operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
- }
-})
-
-/* For converting SF(xmm2) to DF(xmm1), use the following code instead of
- cvtss2sd:
- unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
- cvtps2pd xmm2,xmm1
- We do the conversion post reload to avoid producing of 128bit spills
- that might lead to ICE on 32bit target. The sequence unlikely combine
- anyway. */
-(define_split
- [(set (match_operand:DF 0 "register_operand")
- (float_extend:DF
- (match_operand:SF 1 "nonimmediate_operand")))]
- "TARGET_USE_VECTOR_FP_CONVERTS
- && optimize_insn_for_speed_p ()
- && reload_completed && SSE_REG_P (operands[0])"
- [(set (match_dup 2)
- (float_extend:V2DF
- (vec_select:V2SF
- (match_dup 3)
- (parallel [(const_int 0) (const_int 1)]))))]
-{
- operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
- operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
- /* Use movss for loading from memory, unpcklps reg, reg for registers.
- Try to avoid move when unpacking can be done in source. */
- if (REG_P (operands[1]))
- {
- /* If it is unsafe to overwrite upper half of source, we need
- to move to destination and unpack there. */
- if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
- || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
- && true_regnum (operands[0]) != true_regnum (operands[1]))
- {
- rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
- emit_move_insn (tmp, operands[1]);
- }
- else
- operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
- emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
- operands[3]));
- }
- else
- emit_insn (gen_vec_setv4sf_0 (operands[3],
- CONST0_RTX (V4SFmode), operands[1]));
-})
-
-;; It's more profitable to split and then extend in the same register.
-(define_peephole2
- [(set (match_operand:DF 0 "register_operand")
- (float_extend:DF
- (match_operand:SF 1 "memory_operand")))]
- "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
- && optimize_insn_for_speed_p ()
- && SSE_REG_P (operands[0])"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (float_extend:DF (match_dup 2)))]
- "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
-
-(define_insn "*extendsfdf2_mixed"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
- (float_extend:DF
- (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
- "TARGET_SSE2 && TARGET_MIX_SSE_I387"
-{
- switch (which_alternative)
- {
- case 0:
- case 1:
- return output_387_reg_move (insn, operands);
-
- case 2:
- return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
-
- default:
- gcc_unreachable ();
- }
-}
- [(set_attr "type" "fmov,fmov,ssecvt")
- (set_attr "prefix" "orig,orig,maybe_vex")
- (set_attr "mode" "SF,XF,DF")])
-
-(define_insn "*extendsfdf2_sse"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
- (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
- "TARGET_SSE2 && TARGET_SSE_MATH"
- "%vcvtss2sd\t{%1, %d0|%d0, %1}"
- [(set_attr "type" "ssecvt")
- (set_attr "prefix" "maybe_vex")
- (set_attr "mode" "DF")])
-
-(define_insn "*extendsfdf2_i387"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
- (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
- "TARGET_80387"
- "* return output_387_reg_move (insn, operands);"
- [(set_attr "type" "fmov")
- (set_attr "mode" "SF,XF")])
-
-(define_expand "extend<mode>xf2"
- [(set (match_operand:XF 0 "nonimmediate_operand")
- (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
- "TARGET_80387"
-{
- /* ??? Needed for compress_float_constant since all fp constants
- are TARGET_LEGITIMATE_CONSTANT_P. */
- if (GET_CODE (operands[1]) == CONST_DOUBLE)
- {
- if (standard_80387_constant_p (operands[1]) > 0)
- {
- operands[1] = simplify_const_unary_operation
- (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
- emit_move_insn_1 (operands[0], operands[1]);
- DONE;
- }
- operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
- }
-})
-
-(define_insn "*extend<mode>xf2_i387"
- [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
- (float_extend:XF
- (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
- "TARGET_80387"
- "* return output_387_reg_move (insn, operands);"
- [(set_attr "type" "fmov")
- (set_attr "mode" "<MODE>,XF")])
-
-;; %%% This seems bad bad news.
-;; This cannot output into an f-reg because there is no way to be sure
-;; of truncating in that case. Otherwise this is just like a simple move
-;; insn. So we pretend we can output to a reg in order to get better
-;; register preferencing, but we really use a stack slot.
-
-;; Conversion from DFmode to SFmode.
-
-(define_expand "truncdfsf2"
- [(set (match_operand:SF 0 "nonimmediate_operand")
- (float_truncate:SF
- (match_operand:DF 1 "nonimmediate_operand")))]
- "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
-{
- if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
- ;
- else if (flag_unsafe_math_optimizations)
- ;
- else
- {
- rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
- emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
- DONE;
- }
-})
-
-/* For converting DF(xmm2) to SF(xmm1), use the following code instead of
- cvtsd2ss:
- unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
- cvtpd2ps xmm2,xmm1
- We do the conversion post reload to avoid producing of 128bit spills
- that might lead to ICE on 32bit target. The sequence unlikely combine
- anyway. */
-(define_split
- [(set (match_operand:SF 0 "register_operand")
- (float_truncate:SF
- (match_operand:DF 1 "nonimmediate_operand")))]
- "TARGET_USE_VECTOR_FP_CONVERTS
- && optimize_insn_for_speed_p ()
- && reload_completed && SSE_REG_P (operands[0])"
- [(set (match_dup 2)
- (vec_concat:V4SF
- (float_truncate:V2SF
- (match_dup 4))
- (match_dup 3)))]
-{
- operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
- operands[3] = CONST0_RTX (V2SFmode);
- operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
- /* Use movsd for loading from memory, unpcklpd for registers.
- Try to avoid move when unpacking can be done in source, or SSE3
- movddup is available. */
- if (REG_P (operands[1]))
- {
- if (!TARGET_SSE3
- && true_regnum (operands[0]) != true_regnum (operands[1])
- && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
- || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
- {
- rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
- emit_move_insn (tmp, operands[1]);
- operands[1] = tmp;
- }
- else if (!TARGET_SSE3)
- operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
- emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
- }
- else
- emit_insn (gen_sse2_loadlpd (operands[4],
- CONST0_RTX (V2DFmode), operands[1]));
-})
-
-;; It's more profitable to split and then extend in the same register.
-(define_peephole2
- [(set (match_operand:SF 0 "register_operand")
- (float_truncate:SF
- (match_operand:DF 1 "memory_operand")))]
- "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
- && optimize_insn_for_speed_p ()
- && SSE_REG_P (operands[0])"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
- "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
-
-(define_expand "truncdfsf2_with_temp"
- [(parallel [(set (match_operand:SF 0)
- (float_truncate:SF (match_operand:DF 1)))
- (clobber (match_operand:SF 2))])])
-
-(define_insn "*truncdfsf_fast_mixed"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
- (float_truncate:SF
- (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
- "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
-{
- switch (which_alternative)
- {
- case 0:
- return output_387_reg_move (insn, operands);
- case 1:
- return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
- default:
- gcc_unreachable ();
- }
-}
- [(set_attr "type" "fmov,ssecvt")
- (set_attr "prefix" "orig,maybe_vex")
- (set_attr "mode" "SF")])
-
-;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
-;; because nothing we do here is unsafe.
-(define_insn "*truncdfsf_fast_sse"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
- (float_truncate:SF
- (match_operand:DF 1 "nonimmediate_operand" "xm")))]
- "TARGET_SSE2 && TARGET_SSE_MATH"
- "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
- [(set_attr "type" "ssecvt")
- (set_attr "prefix" "maybe_vex")
- (set_attr "mode" "SF")])
-
-(define_insn "*truncdfsf_fast_i387"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
- (float_truncate:SF
- (match_operand:DF 1 "nonimmediate_operand" "f")))]
- "TARGET_80387 && flag_unsafe_math_optimizations"
- "* return output_387_reg_move (insn, operands);"
- [(set_attr "type" "fmov")
- (set_attr "mode" "SF")])
-
-(define_insn "*truncdfsf_mixed"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
- (float_truncate:SF
- (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
- (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
- "TARGET_MIX_SSE_I387"
-{
- switch (which_alternative)
- {
- case 0:
- return output_387_reg_move (insn, operands);
- case 1:
- return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
-
- default:
- return "#";
- }
-}
- [(set_attr "isa" "*,sse2,*,*,*")
- (set_attr "type" "fmov,ssecvt,multi,multi,multi")
- (set_attr "unit" "*,*,i387,i387,i387")
- (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
- (set_attr "mode" "SF")])
-
-(define_insn "*truncdfsf_i387"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
- (float_truncate:SF
- (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
- (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
- "TARGET_80387"
-{
- switch (which_alternative)
- {
- case 0:
- return output_387_reg_move (insn, operands);
-
- default:
- return "#";
- }
-}
- [(set_attr "type" "fmov,multi,multi,multi")
- (set_attr "unit" "*,i387,i387,i387")
- (set_attr "mode" "SF")])
-
-(define_insn "*truncdfsf2_i387_1"
- [(set (match_operand:SF 0 "memory_operand" "=m")
- (float_truncate:SF
- (match_operand:DF 1 "register_operand" "f")))]
- "TARGET_80387
- && !(TARGET_SSE2 && TARGET_SSE_MATH)
- && !TARGET_MIX_SSE_I387"
- "* return output_387_reg_move (insn, operands);"
- [(set_attr "type" "fmov")
- (set_attr "mode" "SF")])
-
-(define_split
- [(set (match_operand:SF 0 "register_operand")
- (float_truncate:SF
- (match_operand:DF 1 "fp_register_operand")))
- (clobber (match_operand 2))]
- "reload_completed"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (match_dup 2))]
- "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
-
-;; Conversion from XFmode to {SF,DF}mode
-
-(define_expand "truncxf<mode>2"
- [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
- (float_truncate:MODEF
- (match_operand:XF 1 "register_operand")))
- (clobber (match_dup 2))])]
- "TARGET_80387"
-{
- if (flag_unsafe_math_optimizations)
- {
- rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
- emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
- if (reg != operands[0])
- emit_move_insn (operands[0], reg);
- DONE;
- }
- else
- operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
-})
-
-(define_insn "*truncxfsf2_mixed"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
- (float_truncate:SF
- (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
- (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
- "TARGET_80387"
-{
- gcc_assert (!which_alternative);
- return output_387_reg_move (insn, operands);
-}
- [(set_attr "type" "fmov,multi,multi,multi")
- (set_attr "unit" "*,i387,i387,i387")
- (set_attr "mode" "SF")])
-
-(define_insn "*truncxfdf2_mixed"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
- (float_truncate:DF
- (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
- (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
- "TARGET_80387"
-{
- gcc_assert (!which_alternative);
- return output_387_reg_move (insn, operands);
-}
- [(set_attr "isa" "*,*,sse2,*")
- (set_attr "type" "fmov,multi,multi,multi")
- (set_attr "unit" "*,i387,i387,i387")
- (set_attr "mode" "DF")])
-
-(define_insn "truncxf<mode>2_i387_noop"
- [(set (match_operand:MODEF 0 "register_operand" "=f")
- (float_truncate:MODEF
- (match_operand:XF 1 "register_operand" "f")))]
- "TARGET_80387 && flag_unsafe_math_optimizations"
- "* return output_387_reg_move (insn, operands);"
- [(set_attr "type" "fmov")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*truncxf<mode>2_i387"
- [(set (match_operand:MODEF 0 "memory_operand" "=m")
- (float_truncate:MODEF
- (match_operand:XF 1 "register_operand" "f")))]
- "TARGET_80387"
- "* return output_387_reg_move (insn, operands);"
- [(set_attr "type" "fmov")
- (set_attr "mode" "<MODE>")])
-
-(define_split
- [(set (match_operand:MODEF 0 "register_operand")
- (float_truncate:MODEF
- (match_operand:XF 1 "register_operand")))
- (clobber (match_operand:MODEF 2 "memory_operand"))]
- "TARGET_80387 && reload_completed"
- [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
- (set (match_dup 0) (match_dup 2))])
-
-(define_split
- [(set (match_operand:MODEF 0 "memory_operand")
- (float_truncate:MODEF
- (match_operand:XF 1 "register_operand")))
- (clobber (match_operand:MODEF 2 "memory_operand"))]
- "TARGET_80387"
- [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
-
-;; Signed conversion to DImode.
-
-(define_expand "fix_truncxfdi2"
- [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
- (fix:DI (match_operand:XF 1 "register_operand")))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_80387"
-{
- if (TARGET_FISTTP)
- {
- emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
- DONE;
- }
-})
-
-(define_expand "fix_trunc<mode>di2"
- [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
- (fix:DI (match_operand:MODEF 1 "register_operand")))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
-{
- if (TARGET_FISTTP
- && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
- {
- emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
- DONE;
- }
- if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
- {
- rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
- emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
- if (out != operands[0])
- emit_move_insn (operands[0], out);
- DONE;
- }
-})
-
-;; Signed conversion to SImode.
-
-(define_expand "fix_truncxfsi2"
- [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
- (fix:SI (match_operand:XF 1 "register_operand")))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_80387"
-{
- if (TARGET_FISTTP)
- {
- emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
- DONE;
- }
-})
-
-(define_expand "fix_trunc<mode>si2"
- [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
- (fix:SI (match_operand:MODEF 1 "register_operand")))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
-{
- if (TARGET_FISTTP
- && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
- {
- emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
- DONE;
- }
- if (SSE_FLOAT_MODE_P (<MODE>mode))
- {
- rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
- emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
- if (out != operands[0])
- emit_move_insn (operands[0], out);
- DONE;
- }
-})
-
-;; Signed conversion to HImode.
-
-(define_expand "fix_trunc<mode>hi2"
- [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
- (fix:HI (match_operand:X87MODEF 1 "register_operand")))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_80387
- && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
-{
- if (TARGET_FISTTP)
- {
- emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
- DONE;
- }
-})
-
-;; Unsigned conversion to SImode.
-
-(define_expand "fixuns_trunc<mode>si2"
- [(parallel
- [(set (match_operand:SI 0 "register_operand")
- (unsigned_fix:SI
- (match_operand:MODEF 1 "nonimmediate_operand")))
- (use (match_dup 2))
- (clobber (match_scratch:<ssevecmode> 3))
- (clobber (match_scratch:<ssevecmode> 4))])]
- "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
-{
- enum machine_mode mode = <MODE>mode;
- enum machine_mode vecmode = <ssevecmode>mode;
- REAL_VALUE_TYPE TWO31r;
- rtx two31;
-
- if (optimize_insn_for_size_p ())
- FAIL;
-
- real_ldexp (&TWO31r, &dconst1, 31);
- two31 = const_double_from_real_value (TWO31r, mode);
- two31 = ix86_build_const_vector (vecmode, true, two31);
- operands[2] = force_reg (vecmode, two31);
-})
-
-(define_insn_and_split "*fixuns_trunc<mode>_1"
- [(set (match_operand:SI 0 "register_operand" "=&x,&x")
- (unsigned_fix:SI
- (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
- (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
- (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
- (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
- "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
- && optimize_function_for_speed_p (cfun)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
-{
- ix86_split_convert_uns_si_sse (operands);
- DONE;
-})
-
-;; Unsigned conversion to HImode.
-;; Without these patterns, we'll try the unsigned SI conversion which
-;; is complex for SSE, rather than the signed SI conversion, which isn't.
-
-(define_expand "fixuns_trunc<mode>hi2"
- [(set (match_dup 2)
- (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
- (set (match_operand:HI 0 "nonimmediate_operand")
- (subreg:HI (match_dup 2) 0))]
- "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
- "operands[2] = gen_reg_rtx (SImode);")
-
-;; When SSE is available, it is always faster to use it!
-(define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
- [(set (match_operand:SWI48 0 "register_operand" "=r,r")
- (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
- "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
- && (!TARGET_FISTTP || TARGET_SSE_MATH)"
- "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
- [(set_attr "type" "sseicvt")
- (set_attr "prefix" "maybe_vex")
- (set (attr "prefix_rex")
- (if_then_else
- (match_test "<SWI48:MODE>mode == DImode")
- (const_string "1")
- (const_string "*")))
- (set_attr "mode" "<MODEF:MODE>")
- (set_attr "athlon_decode" "double,vector")
- (set_attr "amdfam10_decode" "double,double")
- (set_attr "bdver1_decode" "double,double")])
-
-;; Avoid vector decoded forms of the instruction.
-(define_peephole2
- [(match_scratch:MODEF 2 "x")
- (set (match_operand:SWI48 0 "register_operand")
- (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
- "TARGET_AVOID_VECTOR_DECODE
- && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
- && optimize_insn_for_speed_p ()"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
-
-(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
- [(set (match_operand:SWI248x 0 "nonimmediate_operand")
- (fix:SWI248x (match_operand 1 "register_operand")))]
- "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
- && TARGET_FISTTP
- && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
- && (TARGET_64BIT || <MODE>mode != DImode))
- && TARGET_SSE_MATH)
- && can_create_pseudo_p ()"
- "#"
- "&& 1"
- [(const_int 0)]
-{
- if (memory_operand (operands[0], VOIDmode))
- emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
- else
- {
- operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
- emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
- operands[1],
- operands[2]));
- }
- DONE;
-}
- [(set_attr "type" "fisttp")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "fix_trunc<mode>_i387_fisttp"
- [(set (match_operand:SWI248x 0 "memory_operand" "=m")
- (fix:SWI248x (match_operand 1 "register_operand" "f")))
- (clobber (match_scratch:XF 2 "=&1f"))]
- "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
- && TARGET_FISTTP
- && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
- && (TARGET_64BIT || <MODE>mode != DImode))
- && TARGET_SSE_MATH)"
- "* return output_fix_trunc (insn, operands, true);"
- [(set_attr "type" "fisttp")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
- [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
- (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
- (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
- (clobber (match_scratch:XF 3 "=&1f,&1f"))]
- "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
- && TARGET_FISTTP
- && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
- && (TARGET_64BIT || <MODE>mode != DImode))
- && TARGET_SSE_MATH)"
- "#"
- [(set_attr "type" "fisttp")
- (set_attr "mode" "<MODE>")])
-
-(define_split
- [(set (match_operand:SWI248x 0 "register_operand")
- (fix:SWI248x (match_operand 1 "register_operand")))
- (clobber (match_operand:SWI248x 2 "memory_operand"))
- (clobber (match_scratch 3))]
- "reload_completed"
- [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
- (clobber (match_dup 3))])
- (set (match_dup 0) (match_dup 2))])
-
-(define_split
- [(set (match_operand:SWI248x 0 "memory_operand")
- (fix:SWI248x (match_operand 1 "register_operand")))
- (clobber (match_operand:SWI248x 2 "memory_operand"))
- (clobber (match_scratch 3))]
- "reload_completed"
- [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
- (clobber (match_dup 3))])])
-
-;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
-;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
-;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
-;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
-;; function in i386.c.
-(define_insn_and_split "*fix_trunc<mode>_i387_1"
- [(set (match_operand:SWI248x 0 "nonimmediate_operand")
- (fix:SWI248x (match_operand 1 "register_operand")))
- (clobber (reg:CC FLAGS_REG))]
- "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
- && !TARGET_FISTTP
- && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
- && (TARGET_64BIT || <MODE>mode != DImode))
- && can_create_pseudo_p ()"
- "#"
- "&& 1"
- [(const_int 0)]
-{
- ix86_optimize_mode_switching[I387_TRUNC] = 1;
-
- operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
- operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
- if (memory_operand (operands[0], VOIDmode))
- emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
- operands[2], operands[3]));
- else
- {
- operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
- emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
- operands[2], operands[3],
- operands[4]));
- }
- DONE;
-}
- [(set_attr "type" "fistp")
- (set_attr "i387_cw" "trunc")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "fix_truncdi_i387"
- [(set (match_operand:DI 0 "memory_operand" "=m")
- (fix:DI (match_operand 1 "register_operand" "f")))
- (use (match_operand:HI 2 "memory_operand" "m"))
- (use (match_operand:HI 3 "memory_operand" "m"))
- (clobber (match_scratch:XF 4 "=&1f"))]
- "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
- && !TARGET_FISTTP
- && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
- "* return output_fix_trunc (insn, operands, false);"
- [(set_attr "type" "fistp")
- (set_attr "i387_cw" "trunc")
- (set_attr "mode" "DI")])
-
-(define_insn "fix_truncdi_i387_with_temp"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
- (fix:DI (match_operand 1 "register_operand" "f,f")))
- (use (match_operand:HI 2 "memory_operand" "m,m"))
- (use (match_operand:HI 3 "memory_operand" "m,m"))
- (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
- (clobber (match_scratch:XF 5 "=&1f,&1f"))]
- "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
- && !TARGET_FISTTP
- && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
- "#"
- [(set_attr "type" "fistp")
- (set_attr "i387_cw" "trunc")
- (set_attr "mode" "DI")])
-
-(define_split
- [(set (match_operand:DI 0 "register_operand")
- (fix:DI (match_operand 1 "register_operand")))
- (use (match_operand:HI 2 "memory_operand"))
- (use (match_operand:HI 3 "memory_operand"))
- (clobber (match_operand:DI 4 "memory_operand"))
- (clobber (match_scratch 5))]
- "reload_completed"
- [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
- (use (match_dup 2))
- (use (match_dup 3))
- (clobber (match_dup 5))])
- (set (match_dup 0) (match_dup 4))])
-
-(define_split
- [(set (match_operand:DI 0 "memory_operand")
- (fix:DI (match_operand 1 "register_operand")))
- (use (match_operand:HI 2 "memory_operand"))
- (use (match_operand:HI 3 "memory_operand"))
- (clobber (match_operand:DI 4 "memory_operand"))
- (clobber (match_scratch 5))]
- "reload_completed"
- [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
- (use (match_dup 2))
- (use (match_dup 3))
- (clobber (match_dup 5))])])
-
-(define_insn "fix_trunc<mode>_i387"
- [(set (match_operand:SWI24 0 "memory_operand" "=m")
- (fix:SWI24 (match_operand 1 "register_operand" "f")))
- (use (match_operand:HI 2 "memory_operand" "m"))
- (use (match_operand:HI 3 "memory_operand" "m"))]
- "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
- && !TARGET_FISTTP
- && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
- "* return output_fix_trunc (insn, operands, false);"
- [(set_attr "type" "fistp")
- (set_attr "i387_cw" "trunc")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "fix_trunc<mode>_i387_with_temp"
- [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
- (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
- (use (match_operand:HI 2 "memory_operand" "m,m"))
- (use (match_operand:HI 3 "memory_operand" "m,m"))
- (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
- "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
- && !TARGET_FISTTP
- && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
- "#"
- [(set_attr "type" "fistp")
- (set_attr "i387_cw" "trunc")
- (set_attr "mode" "<MODE>")])
-
-(define_split
- [(set (match_operand:SWI24 0 "register_operand")
- (fix:SWI24 (match_operand 1 "register_operand")))
- (use (match_operand:HI 2 "memory_operand"))
- (use (match_operand:HI 3 "memory_operand"))
- (clobber (match_operand:SWI24 4 "memory_operand"))]
- "reload_completed"
- [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
- (use (match_dup 2))
- (use (match_dup 3))])
- (set (match_dup 0) (match_dup 4))])
-
-(define_split
- [(set (match_operand:SWI24 0 "memory_operand")
- (fix:SWI24 (match_operand 1 "register_operand")))
- (use (match_operand:HI 2 "memory_operand"))
- (use (match_operand:HI 3 "memory_operand"))
- (clobber (match_operand:SWI24 4 "memory_operand"))]
- "reload_completed"
- [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
- (use (match_dup 2))
- (use (match_dup 3))])])
-
-(define_insn "x86_fnstcw_1"
- [(set (match_operand:HI 0 "memory_operand" "=m")
- (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
- "TARGET_80387"
- "fnstcw\t%0"
- [(set (attr "length")
- (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
- (set_attr "mode" "HI")
- (set_attr "unit" "i387")
- (set_attr "bdver1_decode" "vector")])
-
-(define_insn "x86_fldcw_1"
- [(set (reg:HI FPCR_REG)
- (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
- "TARGET_80387"
- "fldcw\t%0"
- [(set (attr "length")
- (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
- (set_attr "mode" "HI")
- (set_attr "unit" "i387")
- (set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "vector")
- (set_attr "bdver1_decode" "vector")])
-
-;; Conversion between fixed point and floating point.
-
-;; Even though we only accept memory inputs, the backend _really_
-;; wants to be able to do this between registers.
-
-(define_expand "floathi<mode>2"
- [(set (match_operand:X87MODEF 0 "register_operand")
- (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
- "TARGET_80387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)")
-
-;; Pre-reload splitter to add memory clobber to the pattern.
-(define_insn_and_split "*floathi<mode>2_1"
- [(set (match_operand:X87MODEF 0 "register_operand")
- (float:X87MODEF (match_operand:HI 1 "register_operand")))]
- "TARGET_80387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && can_create_pseudo_p ()"
- "#"
- "&& 1"
- [(parallel [(set (match_dup 0)
- (float:X87MODEF (match_dup 1)))
- (clobber (match_dup 2))])]
- "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
-
-(define_insn "*floathi<mode>2_i387_with_temp"
- [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
- (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
- (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
- "TARGET_80387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)"
- "#"
- [(set_attr "type" "fmov,multi")
- (set_attr "mode" "<MODE>")
- (set_attr "unit" "*,i387")
- (set_attr "fp_int_src" "true")])
-
-(define_insn "*floathi<mode>2_i387"
- [(set (match_operand:X87MODEF 0 "register_operand" "=f")
- (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
- "TARGET_80387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)"
- "fild%Z1\t%1"
- [(set_attr "type" "fmov")
- (set_attr "mode" "<MODE>")
- (set_attr "fp_int_src" "true")])
-
-(define_split
- [(set (match_operand:X87MODEF 0 "register_operand")
- (float:X87MODEF (match_operand:HI 1 "register_operand")))
- (clobber (match_operand:HI 2 "memory_operand"))]
- "TARGET_80387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && reload_completed"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
-
-(define_split
- [(set (match_operand:X87MODEF 0 "register_operand")
- (float:X87MODEF (match_operand:HI 1 "memory_operand")))
- (clobber (match_operand:HI 2 "memory_operand"))]
- "TARGET_80387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && reload_completed"
- [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
-
-(define_expand "float<SWI48x:mode><X87MODEF:mode>2"
- [(set (match_operand:X87MODEF 0 "register_operand")
- (float:X87MODEF
- (match_operand:SWI48x 1 "nonimmediate_operand")))]
- "TARGET_80387
- || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
- && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
-{
- if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
- && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
- && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
- {
- rtx reg = gen_reg_rtx (XFmode);
- rtx (*insn)(rtx, rtx);
-
- emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
-
- if (<X87MODEF:MODE>mode == SFmode)
- insn = gen_truncxfsf2;
- else if (<X87MODEF:MODE>mode == DFmode)
- insn = gen_truncxfdf2;
- else
- gcc_unreachable ();
-
- emit_insn (insn (operands[0], reg));
- DONE;
- }
-})
-
-;; Pre-reload splitter to add memory clobber to the pattern.
-(define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
- [(set (match_operand:X87MODEF 0 "register_operand")
- (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
- "((TARGET_80387
- && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
- && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
- && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387))
- || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
- && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
- && ((<SWI48x:MODE>mode == SImode
- && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
- && optimize_function_for_speed_p (cfun)
- && flag_trapping_math)
- || !(TARGET_INTER_UNIT_CONVERSIONS
- || optimize_function_for_size_p (cfun)))))
- && can_create_pseudo_p ()"
- "#"
- "&& 1"
- [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
- (clobber (match_dup 2))])]
-{
- operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
-
- /* Avoid store forwarding (partial memory) stall penalty
- by passing DImode value through XMM registers. */
- if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
- && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
- && optimize_function_for_speed_p (cfun))
- {
- emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
- operands[1],
- operands[2]));
- DONE;
- }
-})
-
-(define_insn "*floatsi<mode>2_vector_mixed_with_temp"
- [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
- (float:MODEF
- (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
- (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
- "TARGET_SSE2 && TARGET_MIX_SSE_I387
- && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
- "#"
- [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
- (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
- (set_attr "unit" "*,i387,*,*,*")
- (set_attr "athlon_decode" "*,*,double,direct,double")
- (set_attr "amdfam10_decode" "*,*,vector,double,double")
- (set_attr "bdver1_decode" "*,*,double,direct,double")
- (set_attr "fp_int_src" "true")])
-
-(define_insn "*floatsi<mode>2_vector_mixed"
- [(set (match_operand:MODEF 0 "register_operand" "=f,x")
- (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
- "TARGET_SSE2 && TARGET_MIX_SSE_I387
- && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
- "@
- fild%Z1\t%1
- #"
- [(set_attr "type" "fmov,sseicvt")
- (set_attr "mode" "<MODE>,<ssevecmode>")
- (set_attr "unit" "i387,*")
- (set_attr "athlon_decode" "*,direct")
- (set_attr "amdfam10_decode" "*,double")
- (set_attr "bdver1_decode" "*,direct")
- (set_attr "fp_int_src" "true")])
-
-(define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_with_temp"
- [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
- (float:MODEF
- (match_operand:SWI48 1 "nonimmediate_operand" "m,?r,r,m")))
- (clobber (match_operand:SWI48 2 "memory_operand" "=X,m,m,X"))]
- "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
- "#"
- [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
- (set_attr "mode" "<MODEF:MODE>")
- (set_attr "unit" "*,i387,*,*")
- (set_attr "athlon_decode" "*,*,double,direct")
- (set_attr "amdfam10_decode" "*,*,vector,double")
- (set_attr "bdver1_decode" "*,*,double,direct")
- (set_attr "fp_int_src" "true")])
-
-(define_split
- [(set (match_operand:MODEF 0 "register_operand")
- (float:MODEF (match_operand:SWI48 1 "register_operand")))
- (clobber (match_operand:SWI48 2 "memory_operand"))]
- "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
- && TARGET_INTER_UNIT_CONVERSIONS
- && reload_completed
- && (SSE_REG_P (operands[0])
- || (GET_CODE (operands[0]) == SUBREG
- && SSE_REG_P (SUBREG_REG (operands[0]))))"
- [(set (match_dup 0) (float:MODEF (match_dup 1)))])
-
-(define_split
- [(set (match_operand:MODEF 0 "register_operand")
- (float:MODEF (match_operand:SWI48 1 "register_operand")))
- (clobber (match_operand:SWI48 2 "memory_operand"))]
- "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
- && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
- && reload_completed
- && (SSE_REG_P (operands[0])
- || (GET_CODE (operands[0]) == SUBREG
- && SSE_REG_P (SUBREG_REG (operands[0]))))"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (float:MODEF (match_dup 2)))])
-
-(define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_interunit"
- [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
- (float:MODEF
- (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
- "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
- && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
- "@
- fild%Z1\t%1
- %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
- %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
- [(set_attr "type" "fmov,sseicvt,sseicvt")
- (set_attr "prefix" "orig,maybe_vex,maybe_vex")
- (set_attr "mode" "<MODEF:MODE>")
- (set (attr "prefix_rex")
- (if_then_else
- (and (eq_attr "prefix" "maybe_vex")
- (match_test "<SWI48:MODE>mode == DImode"))
- (const_string "1")
- (const_string "*")))
- (set_attr "unit" "i387,*,*")
- (set_attr "athlon_decode" "*,double,direct")
- (set_attr "amdfam10_decode" "*,vector,double")
- (set_attr "bdver1_decode" "*,double,direct")
- (set_attr "fp_int_src" "true")])
-
-(define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_nointerunit"
- [(set (match_operand:MODEF 0 "register_operand" "=f,x")
- (float:MODEF
- (match_operand:SWI48 1 "memory_operand" "m,m")))]
- "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
- && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
- "@
- fild%Z1\t%1
- %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
- [(set_attr "type" "fmov,sseicvt")
- (set_attr "prefix" "orig,maybe_vex")
- (set_attr "mode" "<MODEF:MODE>")
- (set (attr "prefix_rex")
- (if_then_else
- (and (eq_attr "prefix" "maybe_vex")
- (match_test "<SWI48:MODE>mode == DImode"))
- (const_string "1")
- (const_string "*")))
- (set_attr "athlon_decode" "*,direct")
- (set_attr "amdfam10_decode" "*,double")
- (set_attr "bdver1_decode" "*,direct")
- (set_attr "fp_int_src" "true")])
-
-(define_insn "*floatsi<mode>2_vector_sse_with_temp"
- [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
- (float:MODEF
- (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
- (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
- "TARGET_SSE2 && TARGET_SSE_MATH
- && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
- "#"
- [(set_attr "type" "sseicvt")
- (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
- (set_attr "athlon_decode" "double,direct,double")
- (set_attr "amdfam10_decode" "vector,double,double")
- (set_attr "bdver1_decode" "double,direct,double")
- (set_attr "fp_int_src" "true")])
-
-(define_insn "*floatsi<mode>2_vector_sse"
- [(set (match_operand:MODEF 0 "register_operand" "=x")
- (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
- "TARGET_SSE2 && TARGET_SSE_MATH
- && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
- "#"
- [(set_attr "type" "sseicvt")
- (set_attr "mode" "<MODE>")
- (set_attr "athlon_decode" "direct")
- (set_attr "amdfam10_decode" "double")
- (set_attr "bdver1_decode" "direct")
- (set_attr "fp_int_src" "true")])
-
-(define_split
- [(set (match_operand:MODEF 0 "register_operand")
- (float:MODEF (match_operand:SI 1 "register_operand")))
- (clobber (match_operand:SI 2 "memory_operand"))]
- "TARGET_SSE2 && TARGET_SSE_MATH
- && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
- && reload_completed
- && (SSE_REG_P (operands[0])
- || (GET_CODE (operands[0]) == SUBREG
- && SSE_REG_P (SUBREG_REG (operands[0]))))"
- [(const_int 0)]
-{
- rtx op1 = operands[1];
-
- operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
- <MODE>mode, 0);
- if (GET_CODE (op1) == SUBREG)
- op1 = SUBREG_REG (op1);
-
- if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
- {
- operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
- emit_insn (gen_sse2_loadld (operands[4],
- CONST0_RTX (V4SImode), operands[1]));
- }
- /* We can ignore possible trapping value in the
- high part of SSE register for non-trapping math. */
- else if (SSE_REG_P (op1) && !flag_trapping_math)
- operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
- else
- {
- operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
- emit_move_insn (operands[2], operands[1]);
- emit_insn (gen_sse2_loadld (operands[4],
- CONST0_RTX (V4SImode), operands[2]));
- }
- if (<ssevecmode>mode == V4SFmode)
- emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
- else
- emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
- DONE;
-})
-
-(define_split
- [(set (match_operand:MODEF 0 "register_operand")
- (float:MODEF (match_operand:SI 1 "memory_operand")))
- (clobber (match_operand:SI 2 "memory_operand"))]
- "TARGET_SSE2 && TARGET_SSE_MATH
- && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
- && reload_completed
- && (SSE_REG_P (operands[0])
- || (GET_CODE (operands[0]) == SUBREG
- && SSE_REG_P (SUBREG_REG (operands[0]))))"
- [(const_int 0)]
-{
- operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
- <MODE>mode, 0);
- operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
-
- emit_insn (gen_sse2_loadld (operands[4],
- CONST0_RTX (V4SImode), operands[1]));
- if (<ssevecmode>mode == V4SFmode)
- emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
- else
- emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
- DONE;
-})
-
-(define_split
- [(set (match_operand:MODEF 0 "register_operand")
- (float:MODEF (match_operand:SI 1 "register_operand")))]
- "TARGET_SSE2 && TARGET_SSE_MATH
- && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
- && reload_completed
- && (SSE_REG_P (operands[0])
- || (GET_CODE (operands[0]) == SUBREG
- && SSE_REG_P (SUBREG_REG (operands[0]))))"
- [(const_int 0)]
-{
- rtx op1 = operands[1];
-
- operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
- <MODE>mode, 0);
- if (GET_CODE (op1) == SUBREG)
- op1 = SUBREG_REG (op1);
-
- if (GENERAL_REG_P (op1))
- {
- operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
- if (TARGET_INTER_UNIT_MOVES)
- emit_insn (gen_sse2_loadld (operands[4],
- CONST0_RTX (V4SImode), operands[1]));
- else
- {
- operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
- operands[1]);
- emit_insn (gen_sse2_loadld (operands[4],
- CONST0_RTX (V4SImode), operands[5]));
- ix86_free_from_memory (GET_MODE (operands[1]));
- }
- }
- /* We can ignore possible trapping value in the
- high part of SSE register for non-trapping math. */
- else if (SSE_REG_P (op1) && !flag_trapping_math)
- operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
- else
- gcc_unreachable ();
- if (<ssevecmode>mode == V4SFmode)
- emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
- else
- emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
- DONE;
-})
-
-(define_split
- [(set (match_operand:MODEF 0 "register_operand")
- (float:MODEF (match_operand:SI 1 "memory_operand")))]
- "TARGET_SSE2 && TARGET_SSE_MATH
- && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
- && reload_completed
- && (SSE_REG_P (operands[0])
- || (GET_CODE (operands[0]) == SUBREG
- && SSE_REG_P (SUBREG_REG (operands[0]))))"
- [(const_int 0)]
-{
- operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
- <MODE>mode, 0);
- operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
-
- emit_insn (gen_sse2_loadld (operands[4],
- CONST0_RTX (V4SImode), operands[1]));
- if (<ssevecmode>mode == V4SFmode)
- emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
- else
- emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
- DONE;
-})
-
-(define_insn "*float<SWI48:mode><MODEF:mode>2_sse_with_temp"
- [(set (match_operand:MODEF 0 "register_operand" "=x,x")
- (float:MODEF
- (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))
- (clobber (match_operand:SWI48 2 "memory_operand" "=m,X"))]
- "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
- "#"
- [(set_attr "type" "sseicvt")
- (set_attr "mode" "<MODEF:MODE>")
- (set_attr "athlon_decode" "double,direct")
- (set_attr "amdfam10_decode" "vector,double")
- (set_attr "bdver1_decode" "double,direct")
- (set_attr "btver2_decode" "double,double")
- (set_attr "fp_int_src" "true")])
-
-(define_insn "*float<SWI48:mode><MODEF:mode>2_sse_interunit"
- [(set (match_operand:MODEF 0 "register_operand" "=x,x")
- (float:MODEF
- (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))]
- "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
- && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
- "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
- [(set_attr "type" "sseicvt")
- (set_attr "prefix" "maybe_vex")
- (set_attr "mode" "<MODEF:MODE>")
- (set (attr "prefix_rex")
- (if_then_else
- (and (eq_attr "prefix" "maybe_vex")
- (match_test "<SWI48:MODE>mode == DImode"))
- (const_string "1")
- (const_string "*")))
- (set_attr "athlon_decode" "double,direct")
- (set_attr "amdfam10_decode" "vector,double")
- (set_attr "bdver1_decode" "double,direct")
- (set_attr "btver2_decode" "double,double")
- (set_attr "fp_int_src" "true")])
-
-(define_split
- [(set (match_operand:MODEF 0 "register_operand")
- (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))
- (clobber (match_operand:SWI48 2 "memory_operand"))]
- "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
- && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
- && reload_completed
- && (SSE_REG_P (operands[0])
- || (GET_CODE (operands[0]) == SUBREG
- && SSE_REG_P (SUBREG_REG (operands[0]))))"
- [(set (match_dup 0) (float:MODEF (match_dup 1)))])
-
-(define_insn "*float<SWI48:mode><MODEF:mode>2_sse_nointerunit"
- [(set (match_operand:MODEF 0 "register_operand" "=x")
- (float:MODEF
- (match_operand:SWI48 1 "memory_operand" "m")))]
- "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
- && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
- "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
- [(set_attr "type" "sseicvt")
- (set_attr "prefix" "maybe_vex")
- (set_attr "mode" "<MODEF:MODE>")
- (set (attr "prefix_rex")
- (if_then_else
- (and (eq_attr "prefix" "maybe_vex")
- (match_test "<SWI48:MODE>mode == DImode"))
- (const_string "1")
- (const_string "*")))
- (set_attr "athlon_decode" "direct")
- (set_attr "amdfam10_decode" "double")
- (set_attr "bdver1_decode" "direct")
- (set_attr "fp_int_src" "true")])
-
-(define_split
- [(set (match_operand:MODEF 0 "register_operand")
- (float:MODEF (match_operand:SWI48 1 "register_operand")))
- (clobber (match_operand:SWI48 2 "memory_operand"))]
- "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
- && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
- && reload_completed
- && (SSE_REG_P (operands[0])
- || (GET_CODE (operands[0]) == SUBREG
- && SSE_REG_P (SUBREG_REG (operands[0]))))"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (float:MODEF (match_dup 2)))])
-
-(define_split
- [(set (match_operand:MODEF 0 "register_operand")
- (float:MODEF (match_operand:SWI48 1 "memory_operand")))
- (clobber (match_operand:SWI48 2 "memory_operand"))]
- "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
- && reload_completed
- && (SSE_REG_P (operands[0])
- || (GET_CODE (operands[0]) == SUBREG
- && SSE_REG_P (SUBREG_REG (operands[0]))))"
- [(set (match_dup 0) (float:MODEF (match_dup 1)))])
-
-(define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
- [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
- (float:X87MODEF
- (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
- (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
- "TARGET_80387
- && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
- "@
- fild%Z1\t%1
- #"
- [(set_attr "type" "fmov,multi")
- (set_attr "mode" "<X87MODEF:MODE>")
- (set_attr "unit" "*,i387")
- (set_attr "fp_int_src" "true")])
-
-(define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
- [(set (match_operand:X87MODEF 0 "register_operand" "=f")
- (float:X87MODEF
- (match_operand:SWI48x 1 "memory_operand" "m")))]
- "TARGET_80387
- && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
- "fild%Z1\t%1"
- [(set_attr "type" "fmov")
- (set_attr "mode" "<X87MODEF:MODE>")
- (set_attr "fp_int_src" "true")])
-
-(define_split
- [(set (match_operand:X87MODEF 0 "fp_register_operand")
- (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
- (clobber (match_operand:SWI48x 2 "memory_operand"))]
- "TARGET_80387
- && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
- && reload_completed"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
-
-(define_split
- [(set (match_operand:X87MODEF 0 "fp_register_operand")
- (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
- (clobber (match_operand:SWI48x 2 "memory_operand"))]
- "TARGET_80387
- && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
- && reload_completed"
- [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
-
-;; Avoid store forwarding (partial memory) stall penalty
-;; by passing DImode value through XMM registers. */
-
-(define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
- [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
- (float:X87MODEF
- (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
- (clobber (match_scratch:V4SI 3 "=X,x"))
- (clobber (match_scratch:V4SI 4 "=X,x"))
- (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
- "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
- && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
- && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
- "#"
- [(set_attr "type" "multi")
- (set_attr "mode" "<X87MODEF:MODE>")
- (set_attr "unit" "i387")
- (set_attr "fp_int_src" "true")])
-
-(define_split
- [(set (match_operand:X87MODEF 0 "fp_register_operand")
- (float:X87MODEF (match_operand:DI 1 "register_operand")))
- (clobber (match_scratch:V4SI 3))
- (clobber (match_scratch:V4SI 4))
- (clobber (match_operand:DI 2 "memory_operand"))]
- "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
- && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
- && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
- && reload_completed"
- [(set (match_dup 2) (match_dup 3))
- (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
-{
- /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
- Assemble the 64-bit DImode value in an xmm register. */
- emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
- gen_rtx_SUBREG (SImode, operands[1], 0)));
- emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
- gen_rtx_SUBREG (SImode, operands[1], 4)));
- emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
- operands[4]));
-
- operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
-})
-
-(define_split
- [(set (match_operand:X87MODEF 0 "fp_register_operand")
- (float:X87MODEF (match_operand:DI 1 "memory_operand")))
- (clobber (match_scratch:V4SI 3))
- (clobber (match_scratch:V4SI 4))
- (clobber (match_operand:DI 2 "memory_operand"))]
- "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
- && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
- && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
- && reload_completed"
- [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
-
-;; Avoid store forwarding (partial memory) stall penalty by extending
-;; SImode value to DImode through XMM register instead of pushing two
-;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
-;; targets benefit from this optimization. Also note that fild
-;; loads from memory only.
-
-(define_insn "*floatunssi<mode>2_1"
- [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
- (unsigned_float:X87MODEF
- (match_operand:SI 1 "nonimmediate_operand" "x,m")))
- (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
- (clobber (match_scratch:SI 3 "=X,x"))]
- "!TARGET_64BIT
- && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
- && TARGET_SSE"
- "#"
- [(set_attr "type" "multi")
- (set_attr "mode" "<MODE>")])
-
-(define_split
- [(set (match_operand:X87MODEF 0 "register_operand")
- (unsigned_float:X87MODEF
- (match_operand:SI 1 "register_operand")))
- (clobber (match_operand:DI 2 "memory_operand"))
- (clobber (match_scratch:SI 3))]
- "!TARGET_64BIT
- && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
- && TARGET_SSE
- && reload_completed"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0)
- (float:X87MODEF (match_dup 2)))]
- "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
-
-(define_split
- [(set (match_operand:X87MODEF 0 "register_operand")
- (unsigned_float:X87MODEF
- (match_operand:SI 1 "memory_operand")))
- (clobber (match_operand:DI 2 "memory_operand"))
- (clobber (match_scratch:SI 3))]
- "!TARGET_64BIT
- && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
- && TARGET_SSE
- && reload_completed"
- [(set (match_dup 2) (match_dup 3))
- (set (match_dup 0)
- (float:X87MODEF (match_dup 2)))]
-{
- emit_move_insn (operands[3], operands[1]);
- operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
-})
-
-(define_expand "floatunssi<mode>2"
- [(parallel
- [(set (match_operand:X87MODEF 0 "register_operand")
- (unsigned_float:X87MODEF
- (match_operand:SI 1 "nonimmediate_operand")))
- (clobber (match_dup 2))
- (clobber (match_scratch:SI 3))])]
- "!TARGET_64BIT
- && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
- && TARGET_SSE)
- || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
-{
- if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- {
- ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
- DONE;
- }
- else
- operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
-})
-
-(define_expand "floatunsdisf2"
- [(use (match_operand:SF 0 "register_operand"))
- (use (match_operand:DI 1 "nonimmediate_operand"))]
- "TARGET_64BIT && TARGET_SSE_MATH"
- "x86_emit_floatuns (operands); DONE;")
-
-(define_expand "floatunsdidf2"
- [(use (match_operand:DF 0 "register_operand"))
- (use (match_operand:DI 1 "nonimmediate_operand"))]
- "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
- && TARGET_SSE2 && TARGET_SSE_MATH"
-{
- if (TARGET_64BIT)
- x86_emit_floatuns (operands);
- else
- ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
- DONE;
-})
-
-;; Load effective address instructions
-
-(define_insn_and_split "*lea<mode>"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (match_operand:SWI48 1 "lea_address_operand" "p"))]
- ""
-{
- if (SImode_address_operand (operands[1], VOIDmode))
- {
- gcc_assert (TARGET_64BIT);
- return "lea{l}\t{%E1, %k0|%k0, %E1}";
- }
- else
- return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
-}
- "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
- [(const_int 0)]
-{
- enum machine_mode mode = <MODE>mode;
- rtx pat;
-
- /* ix86_avoid_lea_for_addr re-recognizes insn and may
- change operands[] array behind our back. */
- pat = PATTERN (curr_insn);
-
- operands[0] = SET_DEST (pat);
- operands[1] = SET_SRC (pat);
-
- /* Emit all operations in SImode for zero-extended addresses. Recall
- that x86_64 inheretly zero-extends SImode operations to DImode. */
- if (SImode_address_operand (operands[1], VOIDmode))
- mode = SImode;
-
- ix86_split_lea_for_addr (curr_insn, operands, mode);
- DONE;
-}
- [(set_attr "type" "lea")
- (set (attr "mode")
- (if_then_else
- (match_operand 1 "SImode_address_operand")
- (const_string "SI")
- (const_string "<MODE>")))])
-
-;; Add instructions
-
-(define_expand "add<mode>3"
- [(set (match_operand:SDWIM 0 "nonimmediate_operand")
- (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
- (match_operand:SDWIM 2 "<general_operand>")))]
- ""
- "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
-
-(define_insn_and_split "*add<dwi>3_doubleword"
- [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
- (plus:<DWI>
- (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
- (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
- "#"
- "reload_completed"
- [(parallel [(set (reg:CC FLAGS_REG)
- (unspec:CC [(match_dup 1) (match_dup 2)]
- UNSPEC_ADD_CARRY))
- (set (match_dup 0)
- (plus:DWIH (match_dup 1) (match_dup 2)))])
- (parallel [(set (match_dup 3)
- (plus:DWIH
- (match_dup 4)
- (plus:DWIH
- (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
- (match_dup 5))))
- (clobber (reg:CC FLAGS_REG))])]
- "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
-
-(define_insn "*add<mode>3_cc"
- [(set (reg:CC FLAGS_REG)
- (unspec:CC
- [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
- (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
- UNSPEC_ADD_CARRY))
- (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
- (plus:SWI48 (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
- "add{<imodesuffix>}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "addqi3_cc"
- [(set (reg:CC FLAGS_REG)
- (unspec:CC
- [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
- (match_operand:QI 2 "general_operand" "qn,qm")]
- UNSPEC_ADD_CARRY))
- (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
- (plus:QI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (PLUS, QImode, operands)"
- "add{b}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "QI")])
-
-(define_insn "*add<mode>_1"
- [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
- (plus:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
- (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_LEA:
- return "#";
-
- case TYPE_INCDEC:
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
- if (operands[2] == const1_rtx)
- return "inc{<imodesuffix>}\t%0";
- else
- {
- gcc_assert (operands[2] == constm1_rtx);
- return "dec{<imodesuffix>}\t%0";
- }
-
- default:
- /* For most processors, ADD is faster than LEA. This alternative
- was added to use ADD as much as possible. */
- if (which_alternative == 2)
- {
- rtx tmp;
- tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
- }
-
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
- if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
- return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
-
- return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
- }
-}
- [(set (attr "type")
- (cond [(eq_attr "alternative" "3")
- (const_string "lea")
- (match_operand:SWI48 2 "incdec_operand")
- (const_string "incdec")
- ]
- (const_string "alu")))
- (set (attr "length_immediate")
- (if_then_else
- (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
- (const_string "1")
- (const_string "*")))
- (set_attr "mode" "<MODE>")])
-
-;; It may seem that nonimmediate operand is proper one for operand 1.
-;; The addsi_1 pattern allows nonimmediate operand at that place and
-;; we take care in ix86_binary_operator_ok to not allow two memory
-;; operands so proper swapping will be done in reload. This allow
-;; patterns constructed from addsi_1 to match.
-
-(define_insn "addsi_1_zext"
- [(set (match_operand:DI 0 "register_operand" "=r,r,r")
- (zero_extend:DI
- (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
- (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_LEA:
- return "#";
-
- case TYPE_INCDEC:
- if (operands[2] == const1_rtx)
- return "inc{l}\t%k0";
- else
- {
- gcc_assert (operands[2] == constm1_rtx);
- return "dec{l}\t%k0";
- }
-
- default:
- /* For most processors, ADD is faster than LEA. This alternative
- was added to use ADD as much as possible. */
- if (which_alternative == 1)
- {
- rtx tmp;
- tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
- }
-
- if (x86_maybe_negate_const_int (&operands[2], SImode))
- return "sub{l}\t{%2, %k0|%k0, %2}";
-
- return "add{l}\t{%2, %k0|%k0, %2}";
- }
-}
- [(set (attr "type")
- (cond [(eq_attr "alternative" "2")
- (const_string "lea")
- (match_operand:SI 2 "incdec_operand")
- (const_string "incdec")
- ]
- (const_string "alu")))
- (set (attr "length_immediate")
- (if_then_else
- (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
- (const_string "1")
- (const_string "*")))
- (set_attr "mode" "SI")])
-
-(define_insn "*addhi_1"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
- (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
- (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (PLUS, HImode, operands)"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_LEA:
- return "#";
-
- case TYPE_INCDEC:
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
- if (operands[2] == const1_rtx)
- return "inc{w}\t%0";
- else
- {
- gcc_assert (operands[2] == constm1_rtx);
- return "dec{w}\t%0";
- }
-
- default:
- /* For most processors, ADD is faster than LEA. This alternative
- was added to use ADD as much as possible. */
- if (which_alternative == 2)
- {
- rtx tmp;
- tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
- }
-
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
- if (x86_maybe_negate_const_int (&operands[2], HImode))
- return "sub{w}\t{%2, %0|%0, %2}";
-
- return "add{w}\t{%2, %0|%0, %2}";
- }
-}
- [(set (attr "type")
- (cond [(eq_attr "alternative" "3")
- (const_string "lea")
- (match_operand:HI 2 "incdec_operand")
- (const_string "incdec")
- ]
- (const_string "alu")))
- (set (attr "length_immediate")
- (if_then_else
- (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
- (const_string "1")
- (const_string "*")))
- (set_attr "mode" "HI,HI,HI,SI")])
-
-;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
-(define_insn "*addqi_1"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
- (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
- (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (PLUS, QImode, operands)"
-{
- bool widen = (which_alternative == 3 || which_alternative == 4);
-
- switch (get_attr_type (insn))
- {
- case TYPE_LEA:
- return "#";
-
- case TYPE_INCDEC:
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
- if (operands[2] == const1_rtx)
- return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
- else
- {
- gcc_assert (operands[2] == constm1_rtx);
- return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
- }
-
- default:
- /* For most processors, ADD is faster than LEA. These alternatives
- were added to use ADD as much as possible. */
- if (which_alternative == 2 || which_alternative == 4)
- {
- rtx tmp;
- tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
- }
-
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
- if (x86_maybe_negate_const_int (&operands[2], QImode))
- {
- if (widen)
- return "sub{l}\t{%2, %k0|%k0, %2}";
- else
- return "sub{b}\t{%2, %0|%0, %2}";
- }
- if (widen)
- return "add{l}\t{%k2, %k0|%k0, %k2}";
- else
- return "add{b}\t{%2, %0|%0, %2}";
- }
-}
- [(set (attr "type")
- (cond [(eq_attr "alternative" "5")
- (const_string "lea")
- (match_operand:QI 2 "incdec_operand")
- (const_string "incdec")
- ]
- (const_string "alu")))
- (set (attr "length_immediate")
- (if_then_else
- (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
- (const_string "1")
- (const_string "*")))
- (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
-
-(define_insn "*addqi_1_slp"
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
- (plus:QI (match_dup 0)
- (match_operand:QI 1 "general_operand" "qn,qm")))
- (clobber (reg:CC FLAGS_REG))]
- "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_INCDEC:
- if (operands[1] == const1_rtx)
- return "inc{b}\t%0";
- else
- {
- gcc_assert (operands[1] == constm1_rtx);
- return "dec{b}\t%0";
- }
-
- default:
- if (x86_maybe_negate_const_int (&operands[1], QImode))
- return "sub{b}\t{%1, %0|%0, %1}";
-
- return "add{b}\t{%1, %0|%0, %1}";
- }
-}
- [(set (attr "type")
- (if_then_else (match_operand:QI 1 "incdec_operand")
- (const_string "incdec")
- (const_string "alu1")))
- (set (attr "memory")
- (if_then_else (match_operand 1 "memory_operand")
- (const_string "load")
- (const_string "none")))
- (set_attr "mode" "QI")])
-
-;; Split non destructive adds if we cannot use lea.
-(define_split
- [(set (match_operand:SWI48 0 "register_operand")
- (plus:SWI48 (match_operand:SWI48 1 "register_operand")
- (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
- [(set (match_dup 0) (match_dup 1))
- (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
- (clobber (reg:CC FLAGS_REG))])])
-
-;; Convert add to the lea pattern to avoid flags dependency.
-(define_split
- [(set (match_operand:SWI 0 "register_operand")
- (plus:SWI (match_operand:SWI 1 "register_operand")
- (match_operand:SWI 2 "<nonmemory_operand>")))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed && ix86_lea_for_add_ok (insn, operands)"
- [(const_int 0)]
-{
- enum machine_mode mode = <MODE>mode;
- rtx pat;
-
- if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
- {
- mode = SImode;
- operands[0] = gen_lowpart (mode, operands[0]);
- operands[1] = gen_lowpart (mode, operands[1]);
- operands[2] = gen_lowpart (mode, operands[2]);
- }
-
- pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
-
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
- DONE;
-})
-
-;; Split non destructive adds if we cannot use lea.
-(define_split
- [(set (match_operand:DI 0 "register_operand")
- (zero_extend:DI
- (plus:SI (match_operand:SI 1 "register_operand")
- (match_operand:SI 2 "x86_64_nonmemory_operand"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT
- && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
- [(set (match_dup 3) (match_dup 1))
- (parallel [(set (match_dup 0)
- (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
- (clobber (reg:CC FLAGS_REG))])]
- "operands[3] = gen_lowpart (SImode, operands[0]);")
-
-;; Convert add to the lea pattern to avoid flags dependency.
-(define_split
- [(set (match_operand:DI 0 "register_operand")
- (zero_extend:DI
- (plus:SI (match_operand:SI 1 "register_operand")
- (match_operand:SI 2 "x86_64_nonmemory_operand"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
- [(set (match_dup 0)
- (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
-
-(define_insn "*add<mode>_2"
- [(set (reg FLAGS_REG)
- (compare
- (plus:SWI
- (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
- (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
- (const_int 0)))
- (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
- (plus:SWI (match_dup 1) (match_dup 2)))]
- "ix86_match_ccmode (insn, CCGOCmode)
- && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_INCDEC:
- if (operands[2] == const1_rtx)
- return "inc{<imodesuffix>}\t%0";
- else
- {
- gcc_assert (operands[2] == constm1_rtx);
- return "dec{<imodesuffix>}\t%0";
- }
-
- default:
- if (which_alternative == 2)
- {
- rtx tmp;
- tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
- }
-
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
- if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
- return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
-
- return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
- }
-}
- [(set (attr "type")
- (if_then_else (match_operand:SWI 2 "incdec_operand")
- (const_string "incdec")
- (const_string "alu")))
- (set (attr "length_immediate")
- (if_then_else
- (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
- (const_string "1")
- (const_string "*")))
- (set_attr "mode" "<MODE>")])
-
-;; See comment for addsi_1_zext why we do use nonimmediate_operand
-(define_insn "*addsi_2_zext"
- [(set (reg FLAGS_REG)
- (compare
- (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
- (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
- (const_int 0)))
- (set (match_operand:DI 0 "register_operand" "=r,r")
- (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
- "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
- && ix86_binary_operator_ok (PLUS, SImode, operands)"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_INCDEC:
- if (operands[2] == const1_rtx)
- return "inc{l}\t%k0";
- else
- {
- gcc_assert (operands[2] == constm1_rtx);
- return "dec{l}\t%k0";
- }
-
- default:
- if (which_alternative == 1)
- {
- rtx tmp;
- tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
- }
-
- if (x86_maybe_negate_const_int (&operands[2], SImode))
- return "sub{l}\t{%2, %k0|%k0, %2}";
-
- return "add{l}\t{%2, %k0|%k0, %2}";
- }
-}
- [(set (attr "type")
- (if_then_else (match_operand:SI 2 "incdec_operand")
- (const_string "incdec")
- (const_string "alu")))
- (set (attr "length_immediate")
- (if_then_else
- (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
- (const_string "1")
- (const_string "*")))
- (set_attr "mode" "SI")])
-
-(define_insn "*add<mode>_3"
- [(set (reg FLAGS_REG)
- (compare
- (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
- (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
- (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
- "ix86_match_ccmode (insn, CCZmode)
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_INCDEC:
- if (operands[2] == const1_rtx)
- return "inc{<imodesuffix>}\t%0";
- else
- {
- gcc_assert (operands[2] == constm1_rtx);
- return "dec{<imodesuffix>}\t%0";
- }
-
- default:
- if (which_alternative == 1)
- {
- rtx tmp;
- tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
- }
-
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
- if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
- return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
-
- return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
- }
-}
- [(set (attr "type")
- (if_then_else (match_operand:SWI 2 "incdec_operand")
- (const_string "incdec")
- (const_string "alu")))
- (set (attr "length_immediate")
- (if_then_else
- (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
- (const_string "1")
- (const_string "*")))
- (set_attr "mode" "<MODE>")])
-
-;; See comment for addsi_1_zext why we do use nonimmediate_operand
-(define_insn "*addsi_3_zext"
- [(set (reg FLAGS_REG)
- (compare
- (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
- (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
- (set (match_operand:DI 0 "register_operand" "=r,r")
- (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
- "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
- && ix86_binary_operator_ok (PLUS, SImode, operands)"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_INCDEC:
- if (operands[2] == const1_rtx)
- return "inc{l}\t%k0";
- else
- {
- gcc_assert (operands[2] == constm1_rtx);
- return "dec{l}\t%k0";
- }
-
- default:
- if (which_alternative == 1)
- {
- rtx tmp;
- tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
- }
-
- if (x86_maybe_negate_const_int (&operands[2], SImode))
- return "sub{l}\t{%2, %k0|%k0, %2}";
-
- return "add{l}\t{%2, %k0|%k0, %2}";
- }
-}
- [(set (attr "type")
- (if_then_else (match_operand:SI 2 "incdec_operand")
- (const_string "incdec")
- (const_string "alu")))
- (set (attr "length_immediate")
- (if_then_else
- (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
- (const_string "1")
- (const_string "*")))
- (set_attr "mode" "SI")])
-
-; For comparisons against 1, -1 and 128, we may generate better code
-; by converting cmp to add, inc or dec as done by peephole2. This pattern
-; is matched then. We can't accept general immediate, because for
-; case of overflows, the result is messed up.
-; Also carry flag is reversed compared to cmp, so this conversion is valid
-; only for comparisons not depending on it.
-
-(define_insn "*adddi_4"
- [(set (reg FLAGS_REG)
- (compare
- (match_operand:DI 1 "nonimmediate_operand" "0")
- (match_operand:DI 2 "x86_64_immediate_operand" "e")))
- (clobber (match_scratch:DI 0 "=rm"))]
- "TARGET_64BIT
- && ix86_match_ccmode (insn, CCGCmode)"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_INCDEC:
- if (operands[2] == constm1_rtx)
- return "inc{q}\t%0";
- else
- {
- gcc_assert (operands[2] == const1_rtx);
- return "dec{q}\t%0";
- }
-
- default:
- if (x86_maybe_negate_const_int (&operands[2], DImode))
- return "add{q}\t{%2, %0|%0, %2}";
-
- return "sub{q}\t{%2, %0|%0, %2}";
- }
-}
- [(set (attr "type")
- (if_then_else (match_operand:DI 2 "incdec_operand")
- (const_string "incdec")
- (const_string "alu")))
- (set (attr "length_immediate")
- (if_then_else
- (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
- (const_string "1")
- (const_string "*")))
- (set_attr "mode" "DI")])
-
-; For comparisons against 1, -1 and 128, we may generate better code
-; by converting cmp to add, inc or dec as done by peephole2. This pattern
-; is matched then. We can't accept general immediate, because for
-; case of overflows, the result is messed up.
-; Also carry flag is reversed compared to cmp, so this conversion is valid
-; only for comparisons not depending on it.
-
-(define_insn "*add<mode>_4"
- [(set (reg FLAGS_REG)
- (compare
- (match_operand:SWI124 1 "nonimmediate_operand" "0")
- (match_operand:SWI124 2 "const_int_operand" "n")))
- (clobber (match_scratch:SWI124 0 "=<r>m"))]
- "ix86_match_ccmode (insn, CCGCmode)"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_INCDEC:
- if (operands[2] == constm1_rtx)
- return "inc{<imodesuffix>}\t%0";
- else
- {
- gcc_assert (operands[2] == const1_rtx);
- return "dec{<imodesuffix>}\t%0";
- }
-
- default:
- if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
- return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
-
- return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
- }
-}
- [(set (attr "type")
- (if_then_else (match_operand:<MODE> 2 "incdec_operand")
- (const_string "incdec")
- (const_string "alu")))
- (set (attr "length_immediate")
- (if_then_else
- (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
- (const_string "1")
- (const_string "*")))
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*add<mode>_5"
- [(set (reg FLAGS_REG)
- (compare
- (plus:SWI
- (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
- (match_operand:SWI 2 "<general_operand>" "<g>,0"))
- (const_int 0)))
- (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
- "ix86_match_ccmode (insn, CCGOCmode)
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_INCDEC:
- if (operands[2] == const1_rtx)
- return "inc{<imodesuffix>}\t%0";
- else
- {
- gcc_assert (operands[2] == constm1_rtx);
- return "dec{<imodesuffix>}\t%0";
- }
-
- default:
- if (which_alternative == 1)
- {
- rtx tmp;
- tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
- }
-
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
- if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
- return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
-
- return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
- }
-}
- [(set (attr "type")
- (if_then_else (match_operand:SWI 2 "incdec_operand")
- (const_string "incdec")
- (const_string "alu")))
- (set (attr "length_immediate")
- (if_then_else
- (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
- (const_string "1")
- (const_string "*")))
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*addqi_ext_1_rex64"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
- (const_int 8)
- (const_int 8))
- (plus:SI
- (zero_extract:SI
- (match_operand 1 "ext_register_operand" "0")
- (const_int 8)
- (const_int 8))
- (match_operand:QI 2 "nonmemory_operand" "Qn")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_INCDEC:
- if (operands[2] == const1_rtx)
- return "inc{b}\t%h0";
- else
- {
- gcc_assert (operands[2] == constm1_rtx);
- return "dec{b}\t%h0";
- }
-
- default:
- return "add{b}\t{%2, %h0|%h0, %2}";
- }
-}
- [(set (attr "type")
- (if_then_else (match_operand:QI 2 "incdec_operand")
- (const_string "incdec")
- (const_string "alu")))
- (set_attr "modrm" "1")
- (set_attr "mode" "QI")])
-
-(define_insn "addqi_ext_1"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
- (const_int 8)
- (const_int 8))
- (plus:SI
- (zero_extract:SI
- (match_operand 1 "ext_register_operand" "0")
- (const_int 8)
- (const_int 8))
- (match_operand:QI 2 "general_operand" "Qmn")))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_64BIT"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_INCDEC:
- if (operands[2] == const1_rtx)
- return "inc{b}\t%h0";
- else
- {
- gcc_assert (operands[2] == constm1_rtx);
- return "dec{b}\t%h0";
- }
-
- default:
- return "add{b}\t{%2, %h0|%h0, %2}";
- }
-}
- [(set (attr "type")
- (if_then_else (match_operand:QI 2 "incdec_operand")
- (const_string "incdec")
- (const_string "alu")))
- (set_attr "modrm" "1")
- (set_attr "mode" "QI")])
-
-(define_insn "*addqi_ext_2"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
- (const_int 8)
- (const_int 8))
- (plus:SI
- (zero_extract:SI
- (match_operand 1 "ext_register_operand" "%0")
- (const_int 8)
- (const_int 8))
- (zero_extract:SI
- (match_operand 2 "ext_register_operand" "Q")
- (const_int 8)
- (const_int 8))))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "add{b}\t{%h2, %h0|%h0, %h2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "QI")])
-
-;; The lea patterns for modes less than 32 bits need to be matched by
-;; several insns converted to real lea by splitters.
-
-(define_insn_and_split "*lea_general_1"
- [(set (match_operand 0 "register_operand" "=r")
- (plus (plus (match_operand 1 "index_register_operand" "l")
- (match_operand 2 "register_operand" "r"))
- (match_operand 3 "immediate_operand" "i")))]
- "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
- && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && GET_MODE (operands[0]) == GET_MODE (operands[1])
- && GET_MODE (operands[0]) == GET_MODE (operands[2])
- && (GET_MODE (operands[0]) == GET_MODE (operands[3])
- || GET_MODE (operands[3]) == VOIDmode)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
-{
- enum machine_mode mode = SImode;
- rtx pat;
-
- operands[0] = gen_lowpart (mode, operands[0]);
- operands[1] = gen_lowpart (mode, operands[1]);
- operands[2] = gen_lowpart (mode, operands[2]);
- operands[3] = gen_lowpart (mode, operands[3]);
-
- pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
- operands[3]);
-
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
- DONE;
-}
- [(set_attr "type" "lea")
- (set_attr "mode" "SI")])
-
-(define_insn_and_split "*lea_general_2"
- [(set (match_operand 0 "register_operand" "=r")
- (plus (mult (match_operand 1 "index_register_operand" "l")
- (match_operand 2 "const248_operand" "n"))
- (match_operand 3 "nonmemory_operand" "ri")))]
- "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
- && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && GET_MODE (operands[0]) == GET_MODE (operands[1])
- && (GET_MODE (operands[0]) == GET_MODE (operands[3])
- || GET_MODE (operands[3]) == VOIDmode)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
-{
- enum machine_mode mode = SImode;
- rtx pat;
-
- operands[0] = gen_lowpart (mode, operands[0]);
- operands[1] = gen_lowpart (mode, operands[1]);
- operands[3] = gen_lowpart (mode, operands[3]);
-
- pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
- operands[3]);
-
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
- DONE;
-}
- [(set_attr "type" "lea")
- (set_attr "mode" "SI")])
-
-(define_insn_and_split "*lea_general_3"
- [(set (match_operand 0 "register_operand" "=r")
- (plus (plus (mult (match_operand 1 "index_register_operand" "l")
- (match_operand 2 "const248_operand" "n"))
- (match_operand 3 "register_operand" "r"))
- (match_operand 4 "immediate_operand" "i")))]
- "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
- && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && GET_MODE (operands[0]) == GET_MODE (operands[1])
- && GET_MODE (operands[0]) == GET_MODE (operands[3])"
- "#"
- "&& reload_completed"
- [(const_int 0)]
-{
- enum machine_mode mode = SImode;
- rtx pat;
-
- operands[0] = gen_lowpart (mode, operands[0]);
- operands[1] = gen_lowpart (mode, operands[1]);
- operands[3] = gen_lowpart (mode, operands[3]);
- operands[4] = gen_lowpart (mode, operands[4]);
-
- pat = gen_rtx_PLUS (mode,
- gen_rtx_PLUS (mode,
- gen_rtx_MULT (mode, operands[1],
- operands[2]),
- operands[3]),
- operands[4]);
-
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
- DONE;
-}
- [(set_attr "type" "lea")
- (set_attr "mode" "SI")])
-
-(define_insn_and_split "*lea_general_4"
- [(set (match_operand 0 "register_operand" "=r")
- (any_or (ashift
- (match_operand 1 "index_register_operand" "l")
- (match_operand 2 "const_int_operand" "n"))
- (match_operand 3 "const_int_operand" "n")))]
- "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
- && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
- || GET_MODE (operands[0]) == SImode
- || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
- && GET_MODE (operands[0]) == GET_MODE (operands[1])
- && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
- && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
- < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
- "#"
- "&& reload_completed"
- [(const_int 0)]
-{
- enum machine_mode mode = GET_MODE (operands[0]);
- rtx pat;
-
- if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
- {
- mode = SImode;
- operands[0] = gen_lowpart (mode, operands[0]);
- operands[1] = gen_lowpart (mode, operands[1]);
- }
-
- operands[2] = GEN_INT (1 << INTVAL (operands[2]));
-
- pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
- INTVAL (operands[3]));
-
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
- DONE;
-}
- [(set_attr "type" "lea")
- (set (attr "mode")
- (if_then_else (match_operand:DI 0)
- (const_string "DI")
- (const_string "SI")))])
-
-;; Subtract instructions
-
-(define_expand "sub<mode>3"
- [(set (match_operand:SDWIM 0 "nonimmediate_operand")
- (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
- (match_operand:SDWIM 2 "<general_operand>")))]
- ""
- "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
-
-(define_insn_and_split "*sub<dwi>3_doubleword"
- [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
- (minus:<DWI>
- (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
- (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
- "#"
- "reload_completed"
- [(parallel [(set (reg:CC FLAGS_REG)
- (compare:CC (match_dup 1) (match_dup 2)))
- (set (match_dup 0)
- (minus:DWIH (match_dup 1) (match_dup 2)))])
- (parallel [(set (match_dup 3)
- (minus:DWIH
- (match_dup 4)
- (plus:DWIH
- (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
- (match_dup 5))))
- (clobber (reg:CC FLAGS_REG))])]
- "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
-
-(define_insn "*sub<mode>_1"
- [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
- (minus:SWI
- (match_operand:SWI 1 "nonimmediate_operand" "0,0")
- (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
- "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*subsi_1_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (minus:SI (match_operand:SI 1 "register_operand" "0")
- (match_operand:SI 2 "x86_64_general_operand" "rme"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
- "sub{l}\t{%2, %k0|%k0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "SI")])
-
-(define_insn "*subqi_1_slp"
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
- (minus:QI (match_dup 0)
- (match_operand:QI 1 "general_operand" "qn,qm")))
- (clobber (reg:CC FLAGS_REG))]
- "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "sub{b}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "mode" "QI")])
-
-(define_insn "*sub<mode>_2"
- [(set (reg FLAGS_REG)
- (compare
- (minus:SWI
- (match_operand:SWI 1 "nonimmediate_operand" "0,0")
- (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
- (const_int 0)))
- (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
- (minus:SWI (match_dup 1) (match_dup 2)))]
- "ix86_match_ccmode (insn, CCGOCmode)
- && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
- "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*subsi_2_zext"
- [(set (reg FLAGS_REG)
- (compare
- (minus:SI (match_operand:SI 1 "register_operand" "0")
- (match_operand:SI 2 "x86_64_general_operand" "rme"))
- (const_int 0)))
- (set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (minus:SI (match_dup 1)
- (match_dup 2))))]
- "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
- && ix86_binary_operator_ok (MINUS, SImode, operands)"
- "sub{l}\t{%2, %k0|%k0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "SI")])
-
-(define_insn "*sub<mode>_3"
- [(set (reg FLAGS_REG)
- (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
- (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
- (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
- (minus:SWI (match_dup 1) (match_dup 2)))]
- "ix86_match_ccmode (insn, CCmode)
- && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
- "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*subsi_3_zext"
- [(set (reg FLAGS_REG)
- (compare (match_operand:SI 1 "register_operand" "0")
- (match_operand:SI 2 "x86_64_general_operand" "rme")))
- (set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (minus:SI (match_dup 1)
- (match_dup 2))))]
- "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
- && ix86_binary_operator_ok (MINUS, SImode, operands)"
- "sub{l}\t{%2, %1|%1, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "SI")])
-
-;; Add with carry and subtract with borrow
-
-(define_expand "<plusminus_insn><mode>3_carry"
- [(parallel
- [(set (match_operand:SWI 0 "nonimmediate_operand")
- (plusminus:SWI
- (match_operand:SWI 1 "nonimmediate_operand")
- (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
- [(match_operand 3 "flags_reg_operand")
- (const_int 0)])
- (match_operand:SWI 2 "<general_operand>"))))
- (clobber (reg:CC FLAGS_REG))])]
- "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
-
-(define_insn "*<plusminus_insn><mode>3_carry"
- [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
- (plusminus:SWI
- (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
- (plus:SWI
- (match_operator 3 "ix86_carry_flag_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
- "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*addsi3_carry_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
- (plus:SI (match_operator 3 "ix86_carry_flag_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (match_operand:SI 2 "x86_64_general_operand" "rme")))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
- "adc{l}\t{%2, %k0|%k0, %2}"
- [(set_attr "type" "alu")
- (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "mode" "SI")])
-
-(define_insn "*subsi3_carry_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (minus:SI (match_operand:SI 1 "register_operand" "0")
- (plus:SI (match_operator 3 "ix86_carry_flag_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (match_operand:SI 2 "x86_64_general_operand" "rme")))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
- "sbb{l}\t{%2, %k0|%k0, %2}"
- [(set_attr "type" "alu")
- (set_attr "pent_pair" "pu")
- (set_attr "mode" "SI")])
-
-;; ADCX instruction
-
-(define_insn "adcx<mode>3"
- [(set (reg:CCC FLAGS_REG)
- (compare:CCC
- (plus:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "%0")
- (plus:SWI48
- (match_operator 4 "ix86_carry_flag_operator"
- [(match_operand 3 "flags_reg_operand") (const_int 0)])
- (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
- (const_int 0)))
- (set (match_operand:SWI48 0 "register_operand" "=r")
- (plus:SWI48 (match_dup 1)
- (plus:SWI48 (match_op_dup 4
- [(match_dup 3) (const_int 0)])
- (match_dup 2))))]
- "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
- "adcx\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "use_carry" "1")
- (set_attr "mode" "<MODE>")])
-
-;; Overflow setting add and subtract instructions
-
-(define_insn "*add<mode>3_cconly_overflow"
- [(set (reg:CCC FLAGS_REG)
- (compare:CCC
- (plus:SWI
- (match_operand:SWI 1 "nonimmediate_operand" "%0")
- (match_operand:SWI 2 "<general_operand>" "<g>"))
- (match_dup 1)))
- (clobber (match_scratch:SWI 0 "=<r>"))]
- "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
- "add{<imodesuffix>}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*sub<mode>3_cconly_overflow"
- [(set (reg:CCC FLAGS_REG)
- (compare:CCC
- (minus:SWI
- (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
- (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
- (match_dup 0)))]
- ""
- "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
- [(set_attr "type" "icmp")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*<plusminus_insn><mode>3_cc_overflow"
- [(set (reg:CCC FLAGS_REG)
- (compare:CCC
- (plusminus:SWI
- (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
- (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
- (match_dup 1)))
- (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
- (plusminus:SWI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
- "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*<plusminus_insn>si3_zext_cc_overflow"
- [(set (reg:CCC FLAGS_REG)
- (compare:CCC
- (plusminus:SI
- (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
- (match_operand:SI 2 "x86_64_general_operand" "rme"))
- (match_dup 1)))
- (set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
- "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
- "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "SI")])
-
-;; The patterns that match these are at the end of this file.
-
-(define_expand "<plusminus_insn>xf3"
- [(set (match_operand:XF 0 "register_operand")
- (plusminus:XF
- (match_operand:XF 1 "register_operand")
- (match_operand:XF 2 "register_operand")))]
- "TARGET_80387")
-
-(define_expand "<plusminus_insn><mode>3"
- [(set (match_operand:MODEF 0 "register_operand")
- (plusminus:MODEF
- (match_operand:MODEF 1 "register_operand")
- (match_operand:MODEF 2 "nonimmediate_operand")))]
- "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
- || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
-
-;; Multiply instructions
-
-(define_expand "mul<mode>3"
- [(parallel [(set (match_operand:SWIM248 0 "register_operand")
- (mult:SWIM248
- (match_operand:SWIM248 1 "register_operand")
- (match_operand:SWIM248 2 "<general_operand>")))
- (clobber (reg:CC FLAGS_REG))])])
-
-(define_expand "mulqi3"
- [(parallel [(set (match_operand:QI 0 "register_operand")
- (mult:QI
- (match_operand:QI 1 "register_operand")
- (match_operand:QI 2 "nonimmediate_operand")))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_QIMODE_MATH")
-
-;; On AMDFAM10
-;; IMUL reg32/64, reg32/64, imm8 Direct
-;; IMUL reg32/64, mem32/64, imm8 VectorPath
-;; IMUL reg32/64, reg32/64, imm32 Direct
-;; IMUL reg32/64, mem32/64, imm32 VectorPath
-;; IMUL reg32/64, reg32/64 Direct
-;; IMUL reg32/64, mem32/64 Direct
-;;
-;; On BDVER1, all above IMULs use DirectPath
-
-(define_insn "*mul<mode>3_1"
- [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
- (mult:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
- (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
- (clobber (reg:CC FLAGS_REG))]
- "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
- "@
- imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
- imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
- imul{<imodesuffix>}\t{%2, %0|%0, %2}"
- [(set_attr "type" "imul")
- (set_attr "prefix_0f" "0,0,1")
- (set (attr "athlon_decode")
- (cond [(eq_attr "cpu" "athlon")
- (const_string "vector")
- (eq_attr "alternative" "1")
- (const_string "vector")
- (and (eq_attr "alternative" "2")
- (match_operand 1 "memory_operand"))
- (const_string "vector")]
- (const_string "direct")))
- (set (attr "amdfam10_decode")
- (cond [(and (eq_attr "alternative" "0,1")
- (match_operand 1 "memory_operand"))
- (const_string "vector")]
- (const_string "direct")))
- (set_attr "bdver1_decode" "direct")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*mulsi3_1_zext"
- [(set (match_operand:DI 0 "register_operand" "=r,r,r")
- (zero_extend:DI
- (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
- (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
- "@
- imul{l}\t{%2, %1, %k0|%k0, %1, %2}
- imul{l}\t{%2, %1, %k0|%k0, %1, %2}
- imul{l}\t{%2, %k0|%k0, %2}"
- [(set_attr "type" "imul")
- (set_attr "prefix_0f" "0,0,1")
- (set (attr "athlon_decode")
- (cond [(eq_attr "cpu" "athlon")
- (const_string "vector")
- (eq_attr "alternative" "1")
- (const_string "vector")
- (and (eq_attr "alternative" "2")
- (match_operand 1 "memory_operand"))
- (const_string "vector")]
- (const_string "direct")))
- (set (attr "amdfam10_decode")
- (cond [(and (eq_attr "alternative" "0,1")
- (match_operand 1 "memory_operand"))
- (const_string "vector")]
- (const_string "direct")))
- (set_attr "bdver1_decode" "direct")
- (set_attr "mode" "SI")])
-
-;; On AMDFAM10
-;; IMUL reg16, reg16, imm8 VectorPath
-;; IMUL reg16, mem16, imm8 VectorPath
-;; IMUL reg16, reg16, imm16 VectorPath
-;; IMUL reg16, mem16, imm16 VectorPath
-;; IMUL reg16, reg16 Direct
-;; IMUL reg16, mem16 Direct
-;;
-;; On BDVER1, all HI MULs use DoublePath
-
-(define_insn "*mulhi3_1"
- [(set (match_operand:HI 0 "register_operand" "=r,r,r")
- (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
- (match_operand:HI 2 "general_operand" "K,n,mr")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_HIMODE_MATH
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
- "@
- imul{w}\t{%2, %1, %0|%0, %1, %2}
- imul{w}\t{%2, %1, %0|%0, %1, %2}
- imul{w}\t{%2, %0|%0, %2}"
- [(set_attr "type" "imul")
- (set_attr "prefix_0f" "0,0,1")
- (set (attr "athlon_decode")
- (cond [(eq_attr "cpu" "athlon")
- (const_string "vector")
- (eq_attr "alternative" "1,2")
- (const_string "vector")]
- (const_string "direct")))
- (set (attr "amdfam10_decode")
- (cond [(eq_attr "alternative" "0,1")
- (const_string "vector")]
- (const_string "direct")))
- (set_attr "bdver1_decode" "double")
- (set_attr "mode" "HI")])
-
-;;On AMDFAM10 and BDVER1
-;; MUL reg8 Direct
-;; MUL mem8 Direct
-
-(define_insn "*mulqi3_1"
- [(set (match_operand:QI 0 "register_operand" "=a")
- (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
- (match_operand:QI 2 "nonimmediate_operand" "qm")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_QIMODE_MATH
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
- "mul{b}\t%2"
- [(set_attr "type" "imul")
- (set_attr "length_immediate" "0")
- (set (attr "athlon_decode")
- (if_then_else (eq_attr "cpu" "athlon")
- (const_string "vector")
- (const_string "direct")))
- (set_attr "amdfam10_decode" "direct")
- (set_attr "bdver1_decode" "direct")
- (set_attr "mode" "QI")])
-
-(define_expand "<u>mul<mode><dwi>3"
- [(parallel [(set (match_operand:<DWI> 0 "register_operand")
- (mult:<DWI>
- (any_extend:<DWI>
- (match_operand:DWIH 1 "nonimmediate_operand"))
- (any_extend:<DWI>
- (match_operand:DWIH 2 "register_operand"))))
- (clobber (reg:CC FLAGS_REG))])])
-
-(define_expand "<u>mulqihi3"
- [(parallel [(set (match_operand:HI 0 "register_operand")
- (mult:HI
- (any_extend:HI
- (match_operand:QI 1 "nonimmediate_operand"))
- (any_extend:HI
- (match_operand:QI 2 "register_operand"))))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_QIMODE_MATH")
-
-(define_insn "*bmi2_umulditi3_1"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (mult:DI
- (match_operand:DI 2 "nonimmediate_operand" "%d")
- (match_operand:DI 3 "nonimmediate_operand" "rm")))
- (set (match_operand:DI 1 "register_operand" "=r")
- (truncate:DI
- (lshiftrt:TI
- (mult:TI (zero_extend:TI (match_dup 2))
- (zero_extend:TI (match_dup 3)))
- (const_int 64))))]
- "TARGET_64BIT && TARGET_BMI2
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
- "mulx\t{%3, %0, %1|%1, %0, %3}"
- [(set_attr "type" "imulx")
- (set_attr "prefix" "vex")
- (set_attr "mode" "DI")])
-
-(define_insn "*bmi2_umulsidi3_1"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (mult:SI
- (match_operand:SI 2 "nonimmediate_operand" "%d")
- (match_operand:SI 3 "nonimmediate_operand" "rm")))
- (set (match_operand:SI 1 "register_operand" "=r")
- (truncate:SI
- (lshiftrt:DI
- (mult:DI (zero_extend:DI (match_dup 2))
- (zero_extend:DI (match_dup 3)))
- (const_int 32))))]
- "!TARGET_64BIT && TARGET_BMI2
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
- "mulx\t{%3, %0, %1|%1, %0, %3}"
- [(set_attr "type" "imulx")
- (set_attr "prefix" "vex")
- (set_attr "mode" "SI")])
-
-(define_insn "*umul<mode><dwi>3_1"
- [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
- (mult:<DWI>
- (zero_extend:<DWI>
- (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
- (zero_extend:<DWI>
- (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
- (clobber (reg:CC FLAGS_REG))]
- "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
- "@
- #
- mul{<imodesuffix>}\t%2"
- [(set_attr "isa" "bmi2,*")
- (set_attr "type" "imulx,imul")
- (set_attr "length_immediate" "*,0")
- (set (attr "athlon_decode")
- (cond [(eq_attr "alternative" "1")
- (if_then_else (eq_attr "cpu" "athlon")
- (const_string "vector")
- (const_string "double"))]
- (const_string "*")))
- (set_attr "amdfam10_decode" "*,double")
- (set_attr "bdver1_decode" "*,direct")
- (set_attr "prefix" "vex,orig")
- (set_attr "mode" "<MODE>")])
-
-;; Convert mul to the mulx pattern to avoid flags dependency.
-(define_split
- [(set (match_operand:<DWI> 0 "register_operand")
- (mult:<DWI>
- (zero_extend:<DWI>
- (match_operand:DWIH 1 "register_operand"))
- (zero_extend:<DWI>
- (match_operand:DWIH 2 "nonimmediate_operand"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_BMI2 && reload_completed
- && true_regnum (operands[1]) == DX_REG"
- [(parallel [(set (match_dup 3)
- (mult:DWIH (match_dup 1) (match_dup 2)))
- (set (match_dup 4)
- (truncate:DWIH
- (lshiftrt:<DWI>
- (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
- (zero_extend:<DWI> (match_dup 2)))
- (match_dup 5))))])]
-{
- split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
-
- operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
-})
-
-(define_insn "*mul<mode><dwi>3_1"
- [(set (match_operand:<DWI> 0 "register_operand" "=A")
- (mult:<DWI>
- (sign_extend:<DWI>
- (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
- (sign_extend:<DWI>
- (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
- (clobber (reg:CC FLAGS_REG))]
- "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
- "imul{<imodesuffix>}\t%2"
- [(set_attr "type" "imul")
- (set_attr "length_immediate" "0")
- (set (attr "athlon_decode")
- (if_then_else (eq_attr "cpu" "athlon")
- (const_string "vector")
- (const_string "double")))
- (set_attr "amdfam10_decode" "double")
- (set_attr "bdver1_decode" "direct")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*<u>mulqihi3_1"
- [(set (match_operand:HI 0 "register_operand" "=a")
- (mult:HI
- (any_extend:HI
- (match_operand:QI 1 "nonimmediate_operand" "%0"))
- (any_extend:HI
- (match_operand:QI 2 "nonimmediate_operand" "qm"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_QIMODE_MATH
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
- "<sgnprefix>mul{b}\t%2"
- [(set_attr "type" "imul")
- (set_attr "length_immediate" "0")
- (set (attr "athlon_decode")
- (if_then_else (eq_attr "cpu" "athlon")
- (const_string "vector")
- (const_string "direct")))
- (set_attr "amdfam10_decode" "direct")
- (set_attr "bdver1_decode" "direct")
- (set_attr "mode" "QI")])
-
-(define_expand "<s>mul<mode>3_highpart"
- [(parallel [(set (match_operand:SWI48 0 "register_operand")
- (truncate:SWI48
- (lshiftrt:<DWI>
- (mult:<DWI>
- (any_extend:<DWI>
- (match_operand:SWI48 1 "nonimmediate_operand"))
- (any_extend:<DWI>
- (match_operand:SWI48 2 "register_operand")))
- (match_dup 4))))
- (clobber (match_scratch:SWI48 3))
- (clobber (reg:CC FLAGS_REG))])]
- ""
- "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
-
-(define_insn "*<s>muldi3_highpart_1"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (truncate:DI
- (lshiftrt:TI
- (mult:TI
- (any_extend:TI
- (match_operand:DI 1 "nonimmediate_operand" "%a"))
- (any_extend:TI
- (match_operand:DI 2 "nonimmediate_operand" "rm")))
- (const_int 64))))
- (clobber (match_scratch:DI 3 "=1"))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
- "<sgnprefix>mul{q}\t%2"
- [(set_attr "type" "imul")
- (set_attr "length_immediate" "0")
- (set (attr "athlon_decode")
- (if_then_else (eq_attr "cpu" "athlon")
- (const_string "vector")
- (const_string "double")))
- (set_attr "amdfam10_decode" "double")
- (set_attr "bdver1_decode" "direct")
- (set_attr "mode" "DI")])
-
-(define_insn "*<s>mulsi3_highpart_1"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (truncate:SI
- (lshiftrt:DI
- (mult:DI
- (any_extend:DI
- (match_operand:SI 1 "nonimmediate_operand" "%a"))
- (any_extend:DI
- (match_operand:SI 2 "nonimmediate_operand" "rm")))
- (const_int 32))))
- (clobber (match_scratch:SI 3 "=1"))
- (clobber (reg:CC FLAGS_REG))]
- "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
- "<sgnprefix>mul{l}\t%2"
- [(set_attr "type" "imul")
- (set_attr "length_immediate" "0")
- (set (attr "athlon_decode")
- (if_then_else (eq_attr "cpu" "athlon")
- (const_string "vector")
- (const_string "double")))
- (set_attr "amdfam10_decode" "double")
- (set_attr "bdver1_decode" "direct")
- (set_attr "mode" "SI")])
-
-(define_insn "*<s>mulsi3_highpart_zext"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (zero_extend:DI (truncate:SI
- (lshiftrt:DI
- (mult:DI (any_extend:DI
- (match_operand:SI 1 "nonimmediate_operand" "%a"))
- (any_extend:DI
- (match_operand:SI 2 "nonimmediate_operand" "rm")))
- (const_int 32)))))
- (clobber (match_scratch:SI 3 "=1"))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
- "<sgnprefix>mul{l}\t%2"
- [(set_attr "type" "imul")
- (set_attr "length_immediate" "0")
- (set (attr "athlon_decode")
- (if_then_else (eq_attr "cpu" "athlon")
- (const_string "vector")
- (const_string "double")))
- (set_attr "amdfam10_decode" "double")
- (set_attr "bdver1_decode" "direct")
- (set_attr "mode" "SI")])
-
-;; The patterns that match these are at the end of this file.
-
-(define_expand "mulxf3"
- [(set (match_operand:XF 0 "register_operand")
- (mult:XF (match_operand:XF 1 "register_operand")
- (match_operand:XF 2 "register_operand")))]
- "TARGET_80387")
-
-(define_expand "mul<mode>3"
- [(set (match_operand:MODEF 0 "register_operand")
- (mult:MODEF (match_operand:MODEF 1 "register_operand")
- (match_operand:MODEF 2 "nonimmediate_operand")))]
- "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
- || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
-
-;; Divide instructions
-
-;; The patterns that match these are at the end of this file.
-
-(define_expand "divxf3"
- [(set (match_operand:XF 0 "register_operand")
- (div:XF (match_operand:XF 1 "register_operand")
- (match_operand:XF 2 "register_operand")))]
- "TARGET_80387")
-
-(define_expand "divdf3"
- [(set (match_operand:DF 0 "register_operand")
- (div:DF (match_operand:DF 1 "register_operand")
- (match_operand:DF 2 "nonimmediate_operand")))]
- "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
- || (TARGET_SSE2 && TARGET_SSE_MATH)")
-
-(define_expand "divsf3"
- [(set (match_operand:SF 0 "register_operand")
- (div:SF (match_operand:SF 1 "register_operand")
- (match_operand:SF 2 "nonimmediate_operand")))]
- "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
- || TARGET_SSE_MATH"
-{
- if (TARGET_SSE_MATH
- && TARGET_RECIP_DIV
- && optimize_insn_for_speed_p ()
- && flag_finite_math_only && !flag_trapping_math
- && flag_unsafe_math_optimizations)
- {
- ix86_emit_swdivsf (operands[0], operands[1],
- operands[2], SFmode);
- DONE;
- }
-})
-
-;; Divmod instructions.
-
-(define_expand "divmod<mode>4"
- [(parallel [(set (match_operand:SWIM248 0 "register_operand")
- (div:SWIM248
- (match_operand:SWIM248 1 "register_operand")
- (match_operand:SWIM248 2 "nonimmediate_operand")))
- (set (match_operand:SWIM248 3 "register_operand")
- (mod:SWIM248 (match_dup 1) (match_dup 2)))
- (clobber (reg:CC FLAGS_REG))])])
-
-;; Split with 8bit unsigned divide:
-;; if (dividend an divisor are in [0-255])
-;; use 8bit unsigned integer divide
-;; else
-;; use original integer divide
-(define_split
- [(set (match_operand:SWI48 0 "register_operand")
- (div:SWI48 (match_operand:SWI48 2 "register_operand")
- (match_operand:SWI48 3 "nonimmediate_operand")))
- (set (match_operand:SWI48 1 "register_operand")
- (mod:SWI48 (match_dup 2) (match_dup 3)))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_USE_8BIT_IDIV
- && TARGET_QIMODE_MATH
- && can_create_pseudo_p ()
- && !optimize_insn_for_size_p ()"
- [(const_int 0)]
- "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
-
-(define_insn_and_split "divmod<mode>4_1"
- [(set (match_operand:SWI48 0 "register_operand" "=a")
- (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
- (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
- (set (match_operand:SWI48 1 "register_operand" "=&d")
- (mod:SWI48 (match_dup 2) (match_dup 3)))
- (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
- (clobber (reg:CC FLAGS_REG))]
- ""
- "#"
- "reload_completed"
- [(parallel [(set (match_dup 1)
- (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
- (clobber (reg:CC FLAGS_REG))])
- (parallel [(set (match_dup 0)
- (div:SWI48 (match_dup 2) (match_dup 3)))
- (set (match_dup 1)
- (mod:SWI48 (match_dup 2) (match_dup 3)))
- (use (match_dup 1))
- (clobber (reg:CC FLAGS_REG))])]
-{
- operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
-
- if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
- operands[4] = operands[2];
- else
- {
- /* Avoid use of cltd in favor of a mov+shift. */
- emit_move_insn (operands[1], operands[2]);
- operands[4] = operands[1];
- }
-}
- [(set_attr "type" "multi")
- (set_attr "mode" "<MODE>")])
-
-(define_insn_and_split "*divmod<mode>4"
- [(set (match_operand:SWIM248 0 "register_operand" "=a")
- (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
- (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
- (set (match_operand:SWIM248 1 "register_operand" "=&d")
- (mod:SWIM248 (match_dup 2) (match_dup 3)))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "#"
- "reload_completed"
- [(parallel [(set (match_dup 1)
- (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
- (clobber (reg:CC FLAGS_REG))])
- (parallel [(set (match_dup 0)
- (div:SWIM248 (match_dup 2) (match_dup 3)))
- (set (match_dup 1)
- (mod:SWIM248 (match_dup 2) (match_dup 3)))
- (use (match_dup 1))
- (clobber (reg:CC FLAGS_REG))])]
-{
- operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
-
- if (<MODE>mode != HImode
- && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
- operands[4] = operands[2];
- else
- {
- /* Avoid use of cltd in favor of a mov+shift. */
- emit_move_insn (operands[1], operands[2]);
- operands[4] = operands[1];
- }
-}
- [(set_attr "type" "multi")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*divmod<mode>4_noext"
- [(set (match_operand:SWIM248 0 "register_operand" "=a")
- (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
- (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
- (set (match_operand:SWIM248 1 "register_operand" "=d")
- (mod:SWIM248 (match_dup 2) (match_dup 3)))
- (use (match_operand:SWIM248 4 "register_operand" "1"))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "idiv{<imodesuffix>}\t%3"
- [(set_attr "type" "idiv")
- (set_attr "mode" "<MODE>")])
-
-(define_expand "divmodqi4"
- [(parallel [(set (match_operand:QI 0 "register_operand")
- (div:QI
- (match_operand:QI 1 "register_operand")
- (match_operand:QI 2 "nonimmediate_operand")))
- (set (match_operand:QI 3 "register_operand")
- (mod:QI (match_dup 1) (match_dup 2)))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_QIMODE_MATH"
-{
- rtx div, mod, insn;
- rtx tmp0, tmp1;
-
- tmp0 = gen_reg_rtx (HImode);
- tmp1 = gen_reg_rtx (HImode);
-
- /* Extend operands[1] to HImode. Generate 8bit divide. Result is
- in AX. */
- emit_insn (gen_extendqihi2 (tmp1, operands[1]));
- emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
-
- /* Extract remainder from AH. */
- tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
- insn = emit_move_insn (operands[3], tmp1);
-
- mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
- set_unique_reg_note (insn, REG_EQUAL, mod);
-
- /* Extract quotient from AL. */
- insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
-
- div = gen_rtx_DIV (QImode, operands[1], operands[2]);
- set_unique_reg_note (insn, REG_EQUAL, div);
-
- DONE;
-})
-
-;; Divide AX by r/m8, with result stored in
-;; AL <- Quotient
-;; AH <- Remainder
-;; Change div/mod to HImode and extend the second argument to HImode
-;; so that mode of div/mod matches with mode of arguments. Otherwise
-;; combine may fail.
-(define_insn "divmodhiqi3"
- [(set (match_operand:HI 0 "register_operand" "=a")
- (ior:HI
- (ashift:HI
- (zero_extend:HI
- (truncate:QI
- (mod:HI (match_operand:HI 1 "register_operand" "0")
- (sign_extend:HI
- (match_operand:QI 2 "nonimmediate_operand" "qm")))))
- (const_int 8))
- (zero_extend:HI
- (truncate:QI
- (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_QIMODE_MATH"
- "idiv{b}\t%2"
- [(set_attr "type" "idiv")
- (set_attr "mode" "QI")])
-
-(define_expand "udivmod<mode>4"
- [(parallel [(set (match_operand:SWIM248 0 "register_operand")
- (udiv:SWIM248
- (match_operand:SWIM248 1 "register_operand")
- (match_operand:SWIM248 2 "nonimmediate_operand")))
- (set (match_operand:SWIM248 3 "register_operand")
- (umod:SWIM248 (match_dup 1) (match_dup 2)))
- (clobber (reg:CC FLAGS_REG))])])
-
-;; Split with 8bit unsigned divide:
-;; if (dividend an divisor are in [0-255])
-;; use 8bit unsigned integer divide
-;; else
-;; use original integer divide
-(define_split
- [(set (match_operand:SWI48 0 "register_operand")
- (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
- (match_operand:SWI48 3 "nonimmediate_operand")))
- (set (match_operand:SWI48 1 "register_operand")
- (umod:SWI48 (match_dup 2) (match_dup 3)))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_USE_8BIT_IDIV
- && TARGET_QIMODE_MATH
- && can_create_pseudo_p ()
- && !optimize_insn_for_size_p ()"
- [(const_int 0)]
- "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
-
-(define_insn_and_split "udivmod<mode>4_1"
- [(set (match_operand:SWI48 0 "register_operand" "=a")
- (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
- (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
- (set (match_operand:SWI48 1 "register_operand" "=&d")
- (umod:SWI48 (match_dup 2) (match_dup 3)))
- (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
- (clobber (reg:CC FLAGS_REG))]
- ""
- "#"
- "reload_completed"
- [(set (match_dup 1) (const_int 0))
- (parallel [(set (match_dup 0)
- (udiv:SWI48 (match_dup 2) (match_dup 3)))
- (set (match_dup 1)
- (umod:SWI48 (match_dup 2) (match_dup 3)))
- (use (match_dup 1))
- (clobber (reg:CC FLAGS_REG))])]
- ""
- [(set_attr "type" "multi")
- (set_attr "mode" "<MODE>")])
-
-(define_insn_and_split "*udivmod<mode>4"
- [(set (match_operand:SWIM248 0 "register_operand" "=a")
- (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
- (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
- (set (match_operand:SWIM248 1 "register_operand" "=&d")
- (umod:SWIM248 (match_dup 2) (match_dup 3)))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "#"
- "reload_completed"
- [(set (match_dup 1) (const_int 0))
- (parallel [(set (match_dup 0)
- (udiv:SWIM248 (match_dup 2) (match_dup 3)))
- (set (match_dup 1)
- (umod:SWIM248 (match_dup 2) (match_dup 3)))
- (use (match_dup 1))
- (clobber (reg:CC FLAGS_REG))])]
- ""
- [(set_attr "type" "multi")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*udivmod<mode>4_noext"
- [(set (match_operand:SWIM248 0 "register_operand" "=a")
- (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
- (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
- (set (match_operand:SWIM248 1 "register_operand" "=d")
- (umod:SWIM248 (match_dup 2) (match_dup 3)))
- (use (match_operand:SWIM248 4 "register_operand" "1"))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "div{<imodesuffix>}\t%3"
- [(set_attr "type" "idiv")
- (set_attr "mode" "<MODE>")])
-
-(define_expand "udivmodqi4"
- [(parallel [(set (match_operand:QI 0 "register_operand")
- (udiv:QI
- (match_operand:QI 1 "register_operand")
- (match_operand:QI 2 "nonimmediate_operand")))
- (set (match_operand:QI 3 "register_operand")
- (umod:QI (match_dup 1) (match_dup 2)))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_QIMODE_MATH"
-{
- rtx div, mod, insn;
- rtx tmp0, tmp1;
-
- tmp0 = gen_reg_rtx (HImode);
- tmp1 = gen_reg_rtx (HImode);
-
- /* Extend operands[1] to HImode. Generate 8bit divide. Result is
- in AX. */
- emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
- emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
-
- /* Extract remainder from AH. */
- tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
- tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
- insn = emit_move_insn (operands[3], tmp1);
-
- mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
- set_unique_reg_note (insn, REG_EQUAL, mod);
-
- /* Extract quotient from AL. */
- insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
-
- div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
- set_unique_reg_note (insn, REG_EQUAL, div);
-
- DONE;
-})
-
-(define_insn "udivmodhiqi3"
- [(set (match_operand:HI 0 "register_operand" "=a")
- (ior:HI
- (ashift:HI
- (zero_extend:HI
- (truncate:QI
- (mod:HI (match_operand:HI 1 "register_operand" "0")
- (zero_extend:HI
- (match_operand:QI 2 "nonimmediate_operand" "qm")))))
- (const_int 8))
- (zero_extend:HI
- (truncate:QI
- (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_QIMODE_MATH"
- "div{b}\t%2"
- [(set_attr "type" "idiv")
- (set_attr "mode" "QI")])
-
-;; We cannot use div/idiv for double division, because it causes
-;; "division by zero" on the overflow and that's not what we expect
-;; from truncate. Because true (non truncating) double division is
-;; never generated, we can't create this insn anyway.
-;
-;(define_insn ""
-; [(set (match_operand:SI 0 "register_operand" "=a")
-; (truncate:SI
-; (udiv:DI (match_operand:DI 1 "register_operand" "A")
-; (zero_extend:DI
-; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
-; (set (match_operand:SI 3 "register_operand" "=d")
-; (truncate:SI
-; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
-; (clobber (reg:CC FLAGS_REG))]
-; ""
-; "div{l}\t{%2, %0|%0, %2}"
-; [(set_attr "type" "idiv")])
-
-;;- Logical AND instructions
-
-;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
-;; Note that this excludes ah.
-
-(define_expand "testsi_ccno_1"
- [(set (reg:CCNO FLAGS_REG)
- (compare:CCNO
- (and:SI (match_operand:SI 0 "nonimmediate_operand")
- (match_operand:SI 1 "x86_64_nonmemory_operand"))
- (const_int 0)))])
-
-(define_expand "testqi_ccz_1"
- [(set (reg:CCZ FLAGS_REG)
- (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
- (match_operand:QI 1 "nonmemory_operand"))
- (const_int 0)))])
-
-(define_expand "testdi_ccno_1"
- [(set (reg:CCNO FLAGS_REG)
- (compare:CCNO
- (and:DI (match_operand:DI 0 "nonimmediate_operand")
- (match_operand:DI 1 "x86_64_szext_general_operand"))
- (const_int 0)))]
- "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
-
-(define_insn "*testdi_1"
- [(set (reg FLAGS_REG)
- (compare
- (and:DI
- (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
- (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
- (const_int 0)))]
- "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "@
- test{l}\t{%k1, %k0|%k0, %k1}
- test{l}\t{%k1, %k0|%k0, %k1}
- test{q}\t{%1, %0|%0, %1}
- test{q}\t{%1, %0|%0, %1}
- test{q}\t{%1, %0|%0, %1}"
- [(set_attr "type" "test")
- (set_attr "modrm" "0,1,0,1,1")
- (set_attr "mode" "SI,SI,DI,DI,DI")])
-
-(define_insn "*testqi_1_maybe_si"
- [(set (reg FLAGS_REG)
- (compare
- (and:QI
- (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
- (match_operand:QI 1 "general_operand" "n,n,qn,n"))
- (const_int 0)))]
- "!(MEM_P (operands[0]) && MEM_P (operands[1]))
- && ix86_match_ccmode (insn,
- CONST_INT_P (operands[1])
- && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
-{
- if (which_alternative == 3)
- {
- if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
- operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
- return "test{l}\t{%1, %k0|%k0, %1}";
- }
- return "test{b}\t{%1, %0|%0, %1}";
-}
- [(set_attr "type" "test")
- (set_attr "modrm" "0,1,1,1")
- (set_attr "mode" "QI,QI,QI,SI")
- (set_attr "pent_pair" "uv,np,uv,np")])
-
-(define_insn "*test<mode>_1"
- [(set (reg FLAGS_REG)
- (compare
- (and:SWI124
- (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
- (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
- (const_int 0)))]
- "ix86_match_ccmode (insn, CCNOmode)
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "test{<imodesuffix>}\t{%1, %0|%0, %1}"
- [(set_attr "type" "test")
- (set_attr "modrm" "0,1,1")
- (set_attr "mode" "<MODE>")
- (set_attr "pent_pair" "uv,np,uv")])
-
-(define_expand "testqi_ext_ccno_0"
- [(set (reg:CCNO FLAGS_REG)
- (compare:CCNO
- (and:SI
- (zero_extract:SI
- (match_operand 0 "ext_register_operand")
- (const_int 8)
- (const_int 8))
- (match_operand 1 "const_int_operand"))
- (const_int 0)))])
-
-(define_insn "*testqi_ext_0"
- [(set (reg FLAGS_REG)
- (compare
- (and:SI
- (zero_extract:SI
- (match_operand 0 "ext_register_operand" "Q")
- (const_int 8)
- (const_int 8))
- (match_operand 1 "const_int_operand" "n"))
- (const_int 0)))]
- "ix86_match_ccmode (insn, CCNOmode)"
- "test{b}\t{%1, %h0|%h0, %1}"
- [(set_attr "type" "test")
- (set_attr "mode" "QI")
- (set_attr "length_immediate" "1")
- (set_attr "modrm" "1")
- (set_attr "pent_pair" "np")])
-
-(define_insn "*testqi_ext_1_rex64"
- [(set (reg FLAGS_REG)
- (compare
- (and:SI
- (zero_extract:SI
- (match_operand 0 "ext_register_operand" "Q")
- (const_int 8)
- (const_int 8))
- (zero_extend:SI
- (match_operand:QI 1 "register_operand" "Q")))
- (const_int 0)))]
- "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
- "test{b}\t{%1, %h0|%h0, %1}"
- [(set_attr "type" "test")
- (set_attr "mode" "QI")])
-
-(define_insn "*testqi_ext_1"
- [(set (reg FLAGS_REG)
- (compare
- (and:SI
- (zero_extract:SI
- (match_operand 0 "ext_register_operand" "Q")
- (const_int 8)
- (const_int 8))
- (zero_extend:SI
- (match_operand:QI 1 "general_operand" "Qm")))
- (const_int 0)))]
- "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
- "test{b}\t{%1, %h0|%h0, %1}"
- [(set_attr "type" "test")
- (set_attr "mode" "QI")])
-
-(define_insn "*testqi_ext_2"
- [(set (reg FLAGS_REG)
- (compare
- (and:SI
- (zero_extract:SI
- (match_operand 0 "ext_register_operand" "Q")
- (const_int 8)
- (const_int 8))
- (zero_extract:SI
- (match_operand 1 "ext_register_operand" "Q")
- (const_int 8)
- (const_int 8)))
- (const_int 0)))]
- "ix86_match_ccmode (insn, CCNOmode)"
- "test{b}\t{%h1, %h0|%h0, %h1}"
- [(set_attr "type" "test")
- (set_attr "mode" "QI")])
-
-(define_insn "*testqi_ext_3_rex64"
- [(set (reg FLAGS_REG)
- (compare (zero_extract:DI
- (match_operand 0 "nonimmediate_operand" "rm")
- (match_operand:DI 1 "const_int_operand")
- (match_operand:DI 2 "const_int_operand"))
- (const_int 0)))]
- "TARGET_64BIT
- && ix86_match_ccmode (insn, CCNOmode)
- && INTVAL (operands[1]) > 0
- && INTVAL (operands[2]) >= 0
- /* Ensure that resulting mask is zero or sign extended operand. */
- && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
- || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
- && INTVAL (operands[1]) > 32))
- && (GET_MODE (operands[0]) == SImode
- || GET_MODE (operands[0]) == DImode
- || GET_MODE (operands[0]) == HImode
- || GET_MODE (operands[0]) == QImode)"
- "#")
-
-;; Combine likes to form bit extractions for some tests. Humor it.
-(define_insn "*testqi_ext_3"
- [(set (reg FLAGS_REG)
- (compare (zero_extract:SI
- (match_operand 0 "nonimmediate_operand" "rm")
- (match_operand:SI 1 "const_int_operand")
- (match_operand:SI 2 "const_int_operand"))
- (const_int 0)))]
- "ix86_match_ccmode (insn, CCNOmode)
- && INTVAL (operands[1]) > 0
- && INTVAL (operands[2]) >= 0
- && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
- && (GET_MODE (operands[0]) == SImode
- || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
- || GET_MODE (operands[0]) == HImode
- || GET_MODE (operands[0]) == QImode)"
- "#")
-
-(define_split
- [(set (match_operand 0 "flags_reg_operand")
- (match_operator 1 "compare_operator"
- [(zero_extract
- (match_operand 2 "nonimmediate_operand")
- (match_operand 3 "const_int_operand")
- (match_operand 4 "const_int_operand"))
- (const_int 0)]))]
- "ix86_match_ccmode (insn, CCNOmode)"
- [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
-{
- rtx val = operands[2];
- HOST_WIDE_INT len = INTVAL (operands[3]);
- HOST_WIDE_INT pos = INTVAL (operands[4]);
- HOST_WIDE_INT mask;
- enum machine_mode mode, submode;
-
- mode = GET_MODE (val);
- if (MEM_P (val))
- {
- /* ??? Combine likes to put non-volatile mem extractions in QImode
- no matter the size of the test. So find a mode that works. */
- if (! MEM_VOLATILE_P (val))
- {
- mode = smallest_mode_for_size (pos + len, MODE_INT);
- val = adjust_address (val, mode, 0);
- }
- }
- else if (GET_CODE (val) == SUBREG
- && (submode = GET_MODE (SUBREG_REG (val)),
- GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
- && pos + len <= GET_MODE_BITSIZE (submode)
- && GET_MODE_CLASS (submode) == MODE_INT)
- {
- /* Narrow a paradoxical subreg to prevent partial register stalls. */
- mode = submode;
- val = SUBREG_REG (val);
- }
- else if (mode == HImode && pos + len <= 8)
- {
- /* Small HImode tests can be converted to QImode. */
- mode = QImode;
- val = gen_lowpart (QImode, val);
- }
-
- if (len == HOST_BITS_PER_WIDE_INT)
- mask = -1;
- else
- mask = ((HOST_WIDE_INT)1 << len) - 1;
- mask <<= pos;
-
- operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
-})
-
-;; Convert HImode/SImode test instructions with immediate to QImode ones.
-;; i386 does not allow to encode test with 8bit sign extended immediate, so
-;; this is relatively important trick.
-;; Do the conversion only post-reload to avoid limiting of the register class
-;; to QI regs.
-(define_split
- [(set (match_operand 0 "flags_reg_operand")
- (match_operator 1 "compare_operator"
- [(and (match_operand 2 "register_operand")
- (match_operand 3 "const_int_operand"))
- (const_int 0)]))]
- "reload_completed
- && QI_REG_P (operands[2])
- && GET_MODE (operands[2]) != QImode
- && ((ix86_match_ccmode (insn, CCZmode)
- && !(INTVAL (operands[3]) & ~(255 << 8)))
- || (ix86_match_ccmode (insn, CCNOmode)
- && !(INTVAL (operands[3]) & ~(127 << 8))))"
- [(set (match_dup 0)
- (match_op_dup 1
- [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
- (match_dup 3))
- (const_int 0)]))]
-{
- operands[2] = gen_lowpart (SImode, operands[2]);
- operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
-})
-
-(define_split
- [(set (match_operand 0 "flags_reg_operand")
- (match_operator 1 "compare_operator"
- [(and (match_operand 2 "nonimmediate_operand")
- (match_operand 3 "const_int_operand"))
- (const_int 0)]))]
- "reload_completed
- && GET_MODE (operands[2]) != QImode
- && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
- && ((ix86_match_ccmode (insn, CCZmode)
- && !(INTVAL (operands[3]) & ~255))
- || (ix86_match_ccmode (insn, CCNOmode)
- && !(INTVAL (operands[3]) & ~127)))"
- [(set (match_dup 0)
- (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
- (const_int 0)]))]
-{
- operands[2] = gen_lowpart (QImode, operands[2]);
- operands[3] = gen_lowpart (QImode, operands[3]);
-})
-
-;; %%% This used to optimize known byte-wide and operations to memory,
-;; and sometimes to QImode registers. If this is considered useful,
-;; it should be done with splitters.
-
-(define_expand "and<mode>3"
- [(set (match_operand:SWIM 0 "nonimmediate_operand")
- (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
- (match_operand:SWIM 2 "<general_szext_operand>")))]
- ""
-{
- enum machine_mode mode = <MODE>mode;
- rtx (*insn) (rtx, rtx);
-
- if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
- {
- HOST_WIDE_INT ival = INTVAL (operands[2]);
-
- if (ival == (HOST_WIDE_INT) 0xffffffff)
- mode = SImode;
- else if (ival == 0xffff)
- mode = HImode;
- else if (ival == 0xff)
- mode = QImode;
- }
-
- if (mode == <MODE>mode)
- {
- ix86_expand_binary_operator (AND, <MODE>mode, operands);
- DONE;
- }
-
- if (<MODE>mode == DImode)
- insn = (mode == SImode)
- ? gen_zero_extendsidi2
- : (mode == HImode)
- ? gen_zero_extendhidi2
- : gen_zero_extendqidi2;
- else if (<MODE>mode == SImode)
- insn = (mode == HImode)
- ? gen_zero_extendhisi2
- : gen_zero_extendqisi2;
- else if (<MODE>mode == HImode)
- insn = gen_zero_extendqihi2;
- else
- gcc_unreachable ();
-
- emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
- DONE;
-})
-
-(define_insn "*anddi_1"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
- (and:DI
- (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
- (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_IMOVX:
- return "#";
-
- default:
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
- if (get_attr_mode (insn) == MODE_SI)
- return "and{l}\t{%k2, %k0|%k0, %k2}";
- else
- return "and{q}\t{%2, %0|%0, %2}";
- }
-}
- [(set_attr "type" "alu,alu,alu,imovx")
- (set_attr "length_immediate" "*,*,*,0")
- (set (attr "prefix_rex")
- (if_then_else
- (and (eq_attr "type" "imovx")
- (and (match_test "INTVAL (operands[2]) == 0xff")
- (match_operand 1 "ext_QIreg_operand")))
- (const_string "1")
- (const_string "*")))
- (set_attr "mode" "SI,DI,DI,SI")])
-
-(define_insn "*andsi_1"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
- (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
- (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (AND, SImode, operands)"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_IMOVX:
- return "#";
-
- default:
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
- return "and{l}\t{%2, %0|%0, %2}";
- }
-}
- [(set_attr "type" "alu,alu,imovx")
- (set (attr "prefix_rex")
- (if_then_else
- (and (eq_attr "type" "imovx")
- (and (match_test "INTVAL (operands[2]) == 0xff")
- (match_operand 1 "ext_QIreg_operand")))
- (const_string "1")
- (const_string "*")))
- (set_attr "length_immediate" "*,*,0")
- (set_attr "mode" "SI")])
-
-;; See comment for addsi_1_zext why we do use nonimmediate_operand
-(define_insn "*andsi_1_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
- (match_operand:SI 2 "x86_64_general_operand" "rme"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
- "and{l}\t{%2, %k0|%k0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "SI")])
-
-(define_insn "*andhi_1"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
- (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
- (match_operand:HI 2 "general_operand" "rn,rm,L")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (AND, HImode, operands)"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_IMOVX:
- return "#";
-
- default:
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
- return "and{w}\t{%2, %0|%0, %2}";
- }
-}
- [(set_attr "type" "alu,alu,imovx")
- (set_attr "length_immediate" "*,*,0")
- (set (attr "prefix_rex")
- (if_then_else
- (and (eq_attr "type" "imovx")
- (match_operand 1 "ext_QIreg_operand"))
- (const_string "1")
- (const_string "*")))
- (set_attr "mode" "HI,HI,SI")])
-
-;; %%% Potential partial reg stall on alternative 2. What to do?
-(define_insn "*andqi_1"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
- (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
- (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (AND, QImode, operands)"
- "@
- and{b}\t{%2, %0|%0, %2}
- and{b}\t{%2, %0|%0, %2}
- and{l}\t{%k2, %k0|%k0, %k2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "QI,QI,SI")])
-
-(define_insn "*andqi_1_slp"
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
- (and:QI (match_dup 0)
- (match_operand:QI 1 "general_operand" "qn,qmn")))
- (clobber (reg:CC FLAGS_REG))]
- "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "and{b}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "mode" "QI")])
-
-;; Turn *anddi_1 into *andsi_1_zext if possible.
-(define_split
- [(set (match_operand:DI 0 "register_operand")
- (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
- (match_operand:DI 2 "x86_64_zext_immediate_operand")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT"
- [(parallel [(set (match_dup 0)
- (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
- (clobber (reg:CC FLAGS_REG))])]
- "operands[2] = gen_lowpart (SImode, operands[2]);")
-
-(define_split
- [(set (match_operand:SWI248 0 "register_operand")
- (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
- (match_operand:SWI248 2 "const_int_operand")))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed
- && true_regnum (operands[0]) != true_regnum (operands[1])"
- [(const_int 0)]
-{
- HOST_WIDE_INT ival = INTVAL (operands[2]);
- enum machine_mode mode;
- rtx (*insn) (rtx, rtx);
-
- if (ival == (HOST_WIDE_INT) 0xffffffff)
- mode = SImode;
- else if (ival == 0xffff)
- mode = HImode;
- else
- {
- gcc_assert (ival == 0xff);
- mode = QImode;
- }
-
- if (<MODE>mode == DImode)
- insn = (mode == SImode)
- ? gen_zero_extendsidi2
- : (mode == HImode)
- ? gen_zero_extendhidi2
- : gen_zero_extendqidi2;
- else
- {
- if (<MODE>mode != SImode)
- /* Zero extend to SImode to avoid partial register stalls. */
- operands[0] = gen_lowpart (SImode, operands[0]);
-
- insn = (mode == HImode)
- ? gen_zero_extendhisi2
- : gen_zero_extendqisi2;
- }
- emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
- DONE;
-})
-
-(define_split
- [(set (match_operand 0 "register_operand")
- (and (match_dup 0)
- (const_int -65536)))
- (clobber (reg:CC FLAGS_REG))]
- "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
- || optimize_function_for_size_p (cfun)"
- [(set (strict_low_part (match_dup 1)) (const_int 0))]
- "operands[1] = gen_lowpart (HImode, operands[0]);")
-
-(define_split
- [(set (match_operand 0 "ext_register_operand")
- (and (match_dup 0)
- (const_int -256)))
- (clobber (reg:CC FLAGS_REG))]
- "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && reload_completed"
- [(set (strict_low_part (match_dup 1)) (const_int 0))]
- "operands[1] = gen_lowpart (QImode, operands[0]);")
-
-(define_split
- [(set (match_operand 0 "ext_register_operand")
- (and (match_dup 0)
- (const_int -65281)))
- (clobber (reg:CC FLAGS_REG))]
- "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && reload_completed"
- [(parallel [(set (zero_extract:SI (match_dup 0)
- (const_int 8)
- (const_int 8))
- (xor:SI
- (zero_extract:SI (match_dup 0)
- (const_int 8)
- (const_int 8))
- (zero_extract:SI (match_dup 0)
- (const_int 8)
- (const_int 8))))
- (clobber (reg:CC FLAGS_REG))])]
- "operands[0] = gen_lowpart (SImode, operands[0]);")
-
-(define_insn "*anddi_2"
- [(set (reg FLAGS_REG)
- (compare
- (and:DI
- (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
- (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
- (const_int 0)))
- (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
- (and:DI (match_dup 1) (match_dup 2)))]
- "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
- && ix86_binary_operator_ok (AND, DImode, operands)"
- "@
- and{l}\t{%k2, %k0|%k0, %k2}
- and{q}\t{%2, %0|%0, %2}
- and{q}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "SI,DI,DI")])
-
-(define_insn "*andqi_2_maybe_si"
- [(set (reg FLAGS_REG)
- (compare (and:QI
- (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
- (match_operand:QI 2 "general_operand" "qmn,qn,n"))
- (const_int 0)))
- (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
- (and:QI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (AND, QImode, operands)
- && ix86_match_ccmode (insn,
- CONST_INT_P (operands[2])
- && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
-{
- if (which_alternative == 2)
- {
- if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
- operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
- return "and{l}\t{%2, %k0|%k0, %2}";
- }
- return "and{b}\t{%2, %0|%0, %2}";
-}
- [(set_attr "type" "alu")
- (set_attr "mode" "QI,QI,SI")])
-
-(define_insn "*and<mode>_2"
- [(set (reg FLAGS_REG)
- (compare (and:SWI124
- (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
- (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
- (const_int 0)))
- (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
- (and:SWI124 (match_dup 1) (match_dup 2)))]
- "ix86_match_ccmode (insn, CCNOmode)
- && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
- "and{<imodesuffix>}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "<MODE>")])
-
-;; See comment for addsi_1_zext why we do use nonimmediate_operand
-(define_insn "*andsi_2_zext"
- [(set (reg FLAGS_REG)
- (compare (and:SI
- (match_operand:SI 1 "nonimmediate_operand" "%0")
- (match_operand:SI 2 "x86_64_general_operand" "rme"))
- (const_int 0)))
- (set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
- "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
- && ix86_binary_operator_ok (AND, SImode, operands)"
- "and{l}\t{%2, %k0|%k0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "SI")])
-
-(define_insn "*andqi_2_slp"
- [(set (reg FLAGS_REG)
- (compare (and:QI
- (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
- (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
- (const_int 0)))
- (set (strict_low_part (match_dup 0))
- (and:QI (match_dup 0) (match_dup 1)))]
- "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && ix86_match_ccmode (insn, CCNOmode)
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "and{b}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "mode" "QI")])
-
-;; ??? A bug in recog prevents it from recognizing a const_int as an
-;; operand to zero_extend in andqi_ext_1. It was checking explicitly
-;; for a QImode operand, which of course failed.
-(define_insn "andqi_ext_0"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
- (const_int 8)
- (const_int 8))
- (and:SI
- (zero_extract:SI
- (match_operand 1 "ext_register_operand" "0")
- (const_int 8)
- (const_int 8))
- (match_operand 2 "const_int_operand" "n")))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "and{b}\t{%2, %h0|%h0, %2}"
- [(set_attr "type" "alu")
- (set_attr "length_immediate" "1")
- (set_attr "modrm" "1")
- (set_attr "mode" "QI")])
-
-;; Generated by peephole translating test to and. This shows up
-;; often in fp comparisons.
-(define_insn "*andqi_ext_0_cc"
- [(set (reg FLAGS_REG)
- (compare
- (and:SI
- (zero_extract:SI
- (match_operand 1 "ext_register_operand" "0")
- (const_int 8)
- (const_int 8))
- (match_operand 2 "const_int_operand" "n"))
- (const_int 0)))
- (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
- (const_int 8)
- (const_int 8))
- (and:SI
- (zero_extract:SI
- (match_dup 1)
- (const_int 8)
- (const_int 8))
- (match_dup 2)))]
- "ix86_match_ccmode (insn, CCNOmode)"
- "and{b}\t{%2, %h0|%h0, %2}"
- [(set_attr "type" "alu")
- (set_attr "length_immediate" "1")
- (set_attr "modrm" "1")
- (set_attr "mode" "QI")])
-
-(define_insn "*andqi_ext_1_rex64"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
- (const_int 8)
- (const_int 8))
- (and:SI
- (zero_extract:SI
- (match_operand 1 "ext_register_operand" "0")
- (const_int 8)
- (const_int 8))
- (zero_extend:SI
- (match_operand 2 "ext_register_operand" "Q"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT"
- "and{b}\t{%2, %h0|%h0, %2}"
- [(set_attr "type" "alu")
- (set_attr "length_immediate" "0")
- (set_attr "mode" "QI")])
-
-(define_insn "*andqi_ext_1"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
- (const_int 8)
- (const_int 8))
- (and:SI
- (zero_extract:SI
- (match_operand 1 "ext_register_operand" "0")
- (const_int 8)
- (const_int 8))
- (zero_extend:SI
- (match_operand:QI 2 "general_operand" "Qm"))))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_64BIT"
- "and{b}\t{%2, %h0|%h0, %2}"
- [(set_attr "type" "alu")
- (set_attr "length_immediate" "0")
- (set_attr "mode" "QI")])
-
-(define_insn "*andqi_ext_2"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
- (const_int 8)
- (const_int 8))
- (and:SI
- (zero_extract:SI
- (match_operand 1 "ext_register_operand" "%0")
- (const_int 8)
- (const_int 8))
- (zero_extract:SI
- (match_operand 2 "ext_register_operand" "Q")
- (const_int 8)
- (const_int 8))))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "and{b}\t{%h2, %h0|%h0, %h2}"
- [(set_attr "type" "alu")
- (set_attr "length_immediate" "0")
- (set_attr "mode" "QI")])
-
-;; Convert wide AND instructions with immediate operand to shorter QImode
-;; equivalents when possible.
-;; Don't do the splitting with memory operands, since it introduces risk
-;; of memory mismatch stalls. We may want to do the splitting for optimizing
-;; for size, but that can (should?) be handled by generic code instead.
-(define_split
- [(set (match_operand 0 "register_operand")
- (and (match_operand 1 "register_operand")
- (match_operand 2 "const_int_operand")))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed
- && QI_REG_P (operands[0])
- && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && !(~INTVAL (operands[2]) & ~(255 << 8))
- && GET_MODE (operands[0]) != QImode"
- [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
- (and:SI (zero_extract:SI (match_dup 1)
- (const_int 8) (const_int 8))
- (match_dup 2)))
- (clobber (reg:CC FLAGS_REG))])]
-{
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
-})
-
-;; Since AND can be encoded with sign extended immediate, this is only
-;; profitable when 7th bit is not set.
-(define_split
- [(set (match_operand 0 "register_operand")
- (and (match_operand 1 "general_operand")
- (match_operand 2 "const_int_operand")))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed
- && ANY_QI_REG_P (operands[0])
- && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && !(~INTVAL (operands[2]) & ~255)
- && !(INTVAL (operands[2]) & 128)
- && GET_MODE (operands[0]) != QImode"
- [(parallel [(set (strict_low_part (match_dup 0))
- (and:QI (match_dup 1)
- (match_dup 2)))
- (clobber (reg:CC FLAGS_REG))])]
-{
- operands[0] = gen_lowpart (QImode, operands[0]);
- operands[1] = gen_lowpart (QImode, operands[1]);
- operands[2] = gen_lowpart (QImode, operands[2]);
-})
-
-;; Logical inclusive and exclusive OR instructions
-
-;; %%% This used to optimize known byte-wide and operations to memory.
-;; If this is considered useful, it should be done with splitters.
-
-(define_expand "<code><mode>3"
- [(set (match_operand:SWIM 0 "nonimmediate_operand")
- (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
- (match_operand:SWIM 2 "<general_operand>")))]
- ""
- "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
-
-(define_insn "*<code><mode>_1"
- [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
- (any_or:SWI248
- (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
- (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
- "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "<MODE>")])
-
-;; %%% Potential partial reg stall on alternative 2. What to do?
-(define_insn "*<code>qi_1"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
- (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
- (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (<CODE>, QImode, operands)"
- "@
- <logic>{b}\t{%2, %0|%0, %2}
- <logic>{b}\t{%2, %0|%0, %2}
- <logic>{l}\t{%k2, %k0|%k0, %k2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "QI,QI,SI")])
-
-;; See comment for addsi_1_zext why we do use nonimmediate_operand
-(define_insn "*<code>si_1_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
- (match_operand:SI 2 "x86_64_general_operand" "rme"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
- "<logic>{l}\t{%2, %k0|%k0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "SI")])
-
-(define_insn "*<code>si_1_zext_imm"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (any_or:DI
- (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
- (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
- "<logic>{l}\t{%2, %k0|%k0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "SI")])
-
-(define_insn "*<code>qi_1_slp"
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
- (any_or:QI (match_dup 0)
- (match_operand:QI 1 "general_operand" "qmn,qn")))
- (clobber (reg:CC FLAGS_REG))]
- "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "<logic>{b}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "mode" "QI")])
-
-(define_insn "*<code><mode>_2"
- [(set (reg FLAGS_REG)
- (compare (any_or:SWI
- (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
- (const_int 0)))
- (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
- (any_or:SWI (match_dup 1) (match_dup 2)))]
- "ix86_match_ccmode (insn, CCNOmode)
- && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
- "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "<MODE>")])
-
-;; See comment for addsi_1_zext why we do use nonimmediate_operand
-;; ??? Special case for immediate operand is missing - it is tricky.
-(define_insn "*<code>si_2_zext"
- [(set (reg FLAGS_REG)
- (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
- (match_operand:SI 2 "x86_64_general_operand" "rme"))
- (const_int 0)))
- (set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
- "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
- && ix86_binary_operator_ok (<CODE>, SImode, operands)"
- "<logic>{l}\t{%2, %k0|%k0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "SI")])
-
-(define_insn "*<code>si_2_zext_imm"
- [(set (reg FLAGS_REG)
- (compare (any_or:SI
- (match_operand:SI 1 "nonimmediate_operand" "%0")
- (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
- (const_int 0)))
- (set (match_operand:DI 0 "register_operand" "=r")
- (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
- "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
- && ix86_binary_operator_ok (<CODE>, SImode, operands)"
- "<logic>{l}\t{%2, %k0|%k0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "SI")])
-
-(define_insn "*<code>qi_2_slp"
- [(set (reg FLAGS_REG)
- (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
- (match_operand:QI 1 "general_operand" "qmn,qn"))
- (const_int 0)))
- (set (strict_low_part (match_dup 0))
- (any_or:QI (match_dup 0) (match_dup 1)))]
- "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && ix86_match_ccmode (insn, CCNOmode)
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "<logic>{b}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "mode" "QI")])
-
-(define_insn "*<code><mode>_3"
- [(set (reg FLAGS_REG)
- (compare (any_or:SWI
- (match_operand:SWI 1 "nonimmediate_operand" "%0")
- (match_operand:SWI 2 "<general_operand>" "<g>"))
- (const_int 0)))
- (clobber (match_scratch:SWI 0 "=<r>"))]
- "ix86_match_ccmode (insn, CCNOmode)
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
- "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*<code>qi_ext_0"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
- (const_int 8)
- (const_int 8))
- (any_or:SI
- (zero_extract:SI
- (match_operand 1 "ext_register_operand" "0")
- (const_int 8)
- (const_int 8))
- (match_operand 2 "const_int_operand" "n")))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
- "<logic>{b}\t{%2, %h0|%h0, %2}"
- [(set_attr "type" "alu")
- (set_attr "length_immediate" "1")
- (set_attr "modrm" "1")
- (set_attr "mode" "QI")])
-
-(define_insn "*<code>qi_ext_1_rex64"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
- (const_int 8)
- (const_int 8))
- (any_or:SI
- (zero_extract:SI
- (match_operand 1 "ext_register_operand" "0")
- (const_int 8)
- (const_int 8))
- (zero_extend:SI
- (match_operand 2 "ext_register_operand" "Q"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT
- && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
- "<logic>{b}\t{%2, %h0|%h0, %2}"
- [(set_attr "type" "alu")
- (set_attr "length_immediate" "0")
- (set_attr "mode" "QI")])
-
-(define_insn "*<code>qi_ext_1"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
- (const_int 8)
- (const_int 8))
- (any_or:SI
- (zero_extract:SI
- (match_operand 1 "ext_register_operand" "0")
- (const_int 8)
- (const_int 8))
- (zero_extend:SI
- (match_operand:QI 2 "general_operand" "Qm"))))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_64BIT
- && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
- "<logic>{b}\t{%2, %h0|%h0, %2}"
- [(set_attr "type" "alu")
- (set_attr "length_immediate" "0")
- (set_attr "mode" "QI")])
-
-(define_insn "*<code>qi_ext_2"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
- (const_int 8)
- (const_int 8))
- (any_or:SI
- (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
- (const_int 8)
- (const_int 8))
- (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
- (const_int 8)
- (const_int 8))))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
- "<logic>{b}\t{%h2, %h0|%h0, %h2}"
- [(set_attr "type" "alu")
- (set_attr "length_immediate" "0")
- (set_attr "mode" "QI")])
-
-(define_split
- [(set (match_operand 0 "register_operand")
- (any_or (match_operand 1 "register_operand")
- (match_operand 2 "const_int_operand")))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed
- && QI_REG_P (operands[0])
- && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && !(INTVAL (operands[2]) & ~(255 << 8))
- && GET_MODE (operands[0]) != QImode"
- [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
- (any_or:SI (zero_extract:SI (match_dup 1)
- (const_int 8) (const_int 8))
- (match_dup 2)))
- (clobber (reg:CC FLAGS_REG))])]
-{
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
-})
-
-;; Since OR can be encoded with sign extended immediate, this is only
-;; profitable when 7th bit is set.
-(define_split
- [(set (match_operand 0 "register_operand")
- (any_or (match_operand 1 "general_operand")
- (match_operand 2 "const_int_operand")))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed
- && ANY_QI_REG_P (operands[0])
- && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && !(INTVAL (operands[2]) & ~255)
- && (INTVAL (operands[2]) & 128)
- && GET_MODE (operands[0]) != QImode"
- [(parallel [(set (strict_low_part (match_dup 0))
- (any_or:QI (match_dup 1)
- (match_dup 2)))
- (clobber (reg:CC FLAGS_REG))])]
-{
- operands[0] = gen_lowpart (QImode, operands[0]);
- operands[1] = gen_lowpart (QImode, operands[1]);
- operands[2] = gen_lowpart (QImode, operands[2]);
-})
-
-(define_expand "xorqi_cc_ext_1"
- [(parallel [
- (set (reg:CCNO FLAGS_REG)
- (compare:CCNO
- (xor:SI
- (zero_extract:SI
- (match_operand 1 "ext_register_operand")
- (const_int 8)
- (const_int 8))
- (match_operand:QI 2 "general_operand"))
- (const_int 0)))
- (set (zero_extract:SI (match_operand 0 "ext_register_operand")
- (const_int 8)
- (const_int 8))
- (xor:SI
- (zero_extract:SI
- (match_dup 1)
- (const_int 8)
- (const_int 8))
- (match_dup 2)))])])
-
-(define_insn "*xorqi_cc_ext_1_rex64"
- [(set (reg FLAGS_REG)
- (compare
- (xor:SI
- (zero_extract:SI
- (match_operand 1 "ext_register_operand" "0")
- (const_int 8)
- (const_int 8))
- (match_operand:QI 2 "nonmemory_operand" "Qn"))
- (const_int 0)))
- (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
- (const_int 8)
- (const_int 8))
- (xor:SI
- (zero_extract:SI
- (match_dup 1)
- (const_int 8)
- (const_int 8))
- (match_dup 2)))]
- "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
- "xor{b}\t{%2, %h0|%h0, %2}"
- [(set_attr "type" "alu")
- (set_attr "modrm" "1")
- (set_attr "mode" "QI")])
-
-(define_insn "*xorqi_cc_ext_1"
- [(set (reg FLAGS_REG)
- (compare
- (xor:SI
- (zero_extract:SI
- (match_operand 1 "ext_register_operand" "0")
- (const_int 8)
- (const_int 8))
- (match_operand:QI 2 "general_operand" "qmn"))
- (const_int 0)))
- (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
- (const_int 8)
- (const_int 8))
- (xor:SI
- (zero_extract:SI
- (match_dup 1)
- (const_int 8)
- (const_int 8))
- (match_dup 2)))]
- "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
- "xor{b}\t{%2, %h0|%h0, %2}"
- [(set_attr "type" "alu")
- (set_attr "modrm" "1")
- (set_attr "mode" "QI")])
-
-;; Negation instructions
-
-(define_expand "neg<mode>2"
- [(set (match_operand:SDWIM 0 "nonimmediate_operand")
- (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
- ""
- "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
-
-(define_insn_and_split "*neg<dwi>2_doubleword"
- [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
- (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
- "#"
- "reload_completed"
- [(parallel
- [(set (reg:CCZ FLAGS_REG)
- (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
- (set (match_dup 0) (neg:DWIH (match_dup 1)))])
- (parallel
- [(set (match_dup 2)
- (plus:DWIH (match_dup 3)
- (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
- (const_int 0))))
- (clobber (reg:CC FLAGS_REG))])
- (parallel
- [(set (match_dup 2)
- (neg:DWIH (match_dup 2)))
- (clobber (reg:CC FLAGS_REG))])]
- "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
-
-(define_insn "*neg<mode>2_1"
- [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
- (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
- "neg{<imodesuffix>}\t%0"
- [(set_attr "type" "negnot")
- (set_attr "mode" "<MODE>")])
-
-;; Combine is quite creative about this pattern.
-(define_insn "*negsi2_1_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (lshiftrt:DI
- (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
- (const_int 32)))
- (const_int 32)))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
- "neg{l}\t%k0"
- [(set_attr "type" "negnot")
- (set_attr "mode" "SI")])
-
-;; The problem with neg is that it does not perform (compare x 0),
-;; it really performs (compare 0 x), which leaves us with the zero
-;; flag being the only useful item.
-
-(define_insn "*neg<mode>2_cmpz"
- [(set (reg:CCZ FLAGS_REG)
- (compare:CCZ
- (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
- (const_int 0)))
- (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
- (neg:SWI (match_dup 1)))]
- "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
- "neg{<imodesuffix>}\t%0"
- [(set_attr "type" "negnot")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*negsi2_cmpz_zext"
- [(set (reg:CCZ FLAGS_REG)
- (compare:CCZ
- (lshiftrt:DI
- (neg:DI (ashift:DI
- (match_operand:DI 1 "register_operand" "0")
- (const_int 32)))
- (const_int 32))
- (const_int 0)))
- (set (match_operand:DI 0 "register_operand" "=r")
- (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
- (const_int 32)))
- (const_int 32)))]
- "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
- "neg{l}\t%k0"
- [(set_attr "type" "negnot")
- (set_attr "mode" "SI")])
-
-;; Changing of sign for FP values is doable using integer unit too.
-
-(define_expand "<code><mode>2"
- [(set (match_operand:X87MODEF 0 "register_operand")
- (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
- "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
- "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
-
-(define_insn "*absneg<mode>2_mixed"
- [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
- (match_operator:MODEF 3 "absneg_operator"
- [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
- (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
- "#")
-
-(define_insn "*absneg<mode>2_sse"
- [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
- (match_operator:MODEF 3 "absneg_operator"
- [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
- (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
- (clobber (reg:CC FLAGS_REG))]
- "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
- "#")
-
-(define_insn "*absneg<mode>2_i387"
- [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
- (match_operator:X87MODEF 3 "absneg_operator"
- [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
- (use (match_operand 2))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
- "#")
-
-(define_expand "<code>tf2"
- [(set (match_operand:TF 0 "register_operand")
- (absneg:TF (match_operand:TF 1 "register_operand")))]
- "TARGET_SSE"
- "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
-
-(define_insn "*absnegtf2_sse"
- [(set (match_operand:TF 0 "register_operand" "=x,x")
- (match_operator:TF 3 "absneg_operator"
- [(match_operand:TF 1 "register_operand" "0,x")]))
- (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_SSE"
- "#")
-
-;; Splitters for fp abs and neg.
-
-(define_split
- [(set (match_operand 0 "fp_register_operand")
- (match_operator 1 "absneg_operator" [(match_dup 0)]))
- (use (match_operand 2))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed"
- [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
-
-(define_split
- [(set (match_operand 0 "register_operand")
- (match_operator 3 "absneg_operator"
- [(match_operand 1 "register_operand")]))
- (use (match_operand 2 "nonimmediate_operand"))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed && SSE_REG_P (operands[0])"
- [(set (match_dup 0) (match_dup 3))]
-{
- enum machine_mode mode = GET_MODE (operands[0]);
- enum machine_mode vmode = GET_MODE (operands[2]);
- rtx tmp;
-
- operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
- operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
- if (operands_match_p (operands[0], operands[2]))
- {
- tmp = operands[1];
- operands[1] = operands[2];
- operands[2] = tmp;
- }
- if (GET_CODE (operands[3]) == ABS)
- tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
- else
- tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
- operands[3] = tmp;
-})
-
-(define_split
- [(set (match_operand:SF 0 "register_operand")
- (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
- (use (match_operand:V4SF 2))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed"
- [(parallel [(set (match_dup 0) (match_dup 1))
- (clobber (reg:CC FLAGS_REG))])]
-{
- rtx tmp;
- operands[0] = gen_lowpart (SImode, operands[0]);
- if (GET_CODE (operands[1]) == ABS)
- {
- tmp = gen_int_mode (0x7fffffff, SImode);
- tmp = gen_rtx_AND (SImode, operands[0], tmp);
- }
- else
- {
- tmp = gen_int_mode (0x80000000, SImode);
- tmp = gen_rtx_XOR (SImode, operands[0], tmp);
- }
- operands[1] = tmp;
-})
-
-(define_split
- [(set (match_operand:DF 0 "register_operand")
- (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
- (use (match_operand 2))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed"
- [(parallel [(set (match_dup 0) (match_dup 1))
- (clobber (reg:CC FLAGS_REG))])]
-{
- rtx tmp;
- if (TARGET_64BIT)
- {
- tmp = gen_lowpart (DImode, operands[0]);
- tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
- operands[0] = tmp;
-
- if (GET_CODE (operands[1]) == ABS)
- tmp = const0_rtx;
- else
- tmp = gen_rtx_NOT (DImode, tmp);
- }
- else
- {
- operands[0] = gen_highpart (SImode, operands[0]);
- if (GET_CODE (operands[1]) == ABS)
- {
- tmp = gen_int_mode (0x7fffffff, SImode);
- tmp = gen_rtx_AND (SImode, operands[0], tmp);
- }
- else
- {
- tmp = gen_int_mode (0x80000000, SImode);
- tmp = gen_rtx_XOR (SImode, operands[0], tmp);
- }
- }
- operands[1] = tmp;
-})
-
-(define_split
- [(set (match_operand:XF 0 "register_operand")
- (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
- (use (match_operand 2))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed"
- [(parallel [(set (match_dup 0) (match_dup 1))
- (clobber (reg:CC FLAGS_REG))])]
-{
- rtx tmp;
- operands[0] = gen_rtx_REG (SImode,
- true_regnum (operands[0])
- + (TARGET_64BIT ? 1 : 2));
- if (GET_CODE (operands[1]) == ABS)
- {
- tmp = GEN_INT (0x7fff);
- tmp = gen_rtx_AND (SImode, operands[0], tmp);
- }
- else
- {
- tmp = GEN_INT (0x8000);
- tmp = gen_rtx_XOR (SImode, operands[0], tmp);
- }
- operands[1] = tmp;
-})
-
-;; Conditionalize these after reload. If they match before reload, we
-;; lose the clobber and ability to use integer instructions.
-
-(define_insn "*<code><mode>2_1"
- [(set (match_operand:X87MODEF 0 "register_operand" "=f")
- (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
- "TARGET_80387
- && (reload_completed
- || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
- "f<absneg_mnemonic>"
- [(set_attr "type" "fsgn")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*<code>extendsfdf2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (absneg:DF (float_extend:DF
- (match_operand:SF 1 "register_operand" "0"))))]
- "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
- "f<absneg_mnemonic>"
- [(set_attr "type" "fsgn")
- (set_attr "mode" "DF")])
-
-(define_insn "*<code>extendsfxf2"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (absneg:XF (float_extend:XF
- (match_operand:SF 1 "register_operand" "0"))))]
- "TARGET_80387"
- "f<absneg_mnemonic>"
- [(set_attr "type" "fsgn")
- (set_attr "mode" "XF")])
-
-(define_insn "*<code>extenddfxf2"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (absneg:XF (float_extend:XF
- (match_operand:DF 1 "register_operand" "0"))))]
- "TARGET_80387"
- "f<absneg_mnemonic>"
- [(set_attr "type" "fsgn")
- (set_attr "mode" "XF")])
-
-;; Copysign instructions
-
-(define_mode_iterator CSGNMODE [SF DF TF])
-(define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
-
-(define_expand "copysign<mode>3"
- [(match_operand:CSGNMODE 0 "register_operand")
- (match_operand:CSGNMODE 1 "nonmemory_operand")
- (match_operand:CSGNMODE 2 "register_operand")]
- "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || (TARGET_SSE && (<MODE>mode == TFmode))"
- "ix86_expand_copysign (operands); DONE;")
-
-(define_insn_and_split "copysign<mode>3_const"
- [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
- (unspec:CSGNMODE
- [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
- (match_operand:CSGNMODE 2 "register_operand" "0")
- (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
- UNSPEC_COPYSIGN))]
- "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || (TARGET_SSE && (<MODE>mode == TFmode))"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_copysign_const (operands); DONE;")
-
-(define_insn "copysign<mode>3_var"
- [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
- (unspec:CSGNMODE
- [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
- (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
- (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
- (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
- UNSPEC_COPYSIGN))
- (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
- "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || (TARGET_SSE && (<MODE>mode == TFmode))"
- "#")
-
-(define_split
- [(set (match_operand:CSGNMODE 0 "register_operand")
- (unspec:CSGNMODE
- [(match_operand:CSGNMODE 2 "register_operand")
- (match_operand:CSGNMODE 3 "register_operand")
- (match_operand:<CSGNVMODE> 4)
- (match_operand:<CSGNVMODE> 5)]
- UNSPEC_COPYSIGN))
- (clobber (match_scratch:<CSGNVMODE> 1))]
- "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || (TARGET_SSE && (<MODE>mode == TFmode)))
- && reload_completed"
- [(const_int 0)]
- "ix86_split_copysign_var (operands); DONE;")
-
-;; One complement instructions
-
-(define_expand "one_cmpl<mode>2"
- [(set (match_operand:SWIM 0 "nonimmediate_operand")
- (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
- ""
- "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
-
-(define_insn "*one_cmpl<mode>2_1"
- [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
- (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
- "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
- "not{<imodesuffix>}\t%0"
- [(set_attr "type" "negnot")
- (set_attr "mode" "<MODE>")])
-
-;; %%% Potential partial reg stall on alternative 1. What to do?
-(define_insn "*one_cmplqi2_1"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
- (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
- "ix86_unary_operator_ok (NOT, QImode, operands)"
- "@
- not{b}\t%0
- not{l}\t%k0"
- [(set_attr "type" "negnot")
- (set_attr "mode" "QI,SI")])
-
-;; ??? Currently never generated - xor is used instead.
-(define_insn "*one_cmplsi2_1_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (not:SI (match_operand:SI 1 "register_operand" "0"))))]
- "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
- "not{l}\t%k0"
- [(set_attr "type" "negnot")
- (set_attr "mode" "SI")])
-
-(define_insn "*one_cmpl<mode>2_2"
- [(set (reg FLAGS_REG)
- (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
- (const_int 0)))
- (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
- (not:SWI (match_dup 1)))]
- "ix86_match_ccmode (insn, CCNOmode)
- && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
- "#"
- [(set_attr "type" "alu1")
- (set_attr "mode" "<MODE>")])
-
-(define_split
- [(set (match_operand 0 "flags_reg_operand")
- (match_operator 2 "compare_operator"
- [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
- (const_int 0)]))
- (set (match_operand:SWI 1 "nonimmediate_operand")
- (not:SWI (match_dup 3)))]
- "ix86_match_ccmode (insn, CCNOmode)"
- [(parallel [(set (match_dup 0)
- (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
- (const_int 0)]))
- (set (match_dup 1)
- (xor:SWI (match_dup 3) (const_int -1)))])])
-
-;; ??? Currently never generated - xor is used instead.
-(define_insn "*one_cmplsi2_2_zext"
- [(set (reg FLAGS_REG)
- (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
- (const_int 0)))
- (set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI (not:SI (match_dup 1))))]
- "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
- && ix86_unary_operator_ok (NOT, SImode, operands)"
- "#"
- [(set_attr "type" "alu1")
- (set_attr "mode" "SI")])
-
-(define_split
- [(set (match_operand 0 "flags_reg_operand")
- (match_operator 2 "compare_operator"
- [(not:SI (match_operand:SI 3 "register_operand"))
- (const_int 0)]))
- (set (match_operand:DI 1 "register_operand")
- (zero_extend:DI (not:SI (match_dup 3))))]
- "ix86_match_ccmode (insn, CCNOmode)"
- [(parallel [(set (match_dup 0)
- (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
- (const_int 0)]))
- (set (match_dup 1)
- (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
-
-;; Shift instructions
-
-;; DImode shifts are implemented using the i386 "shift double" opcode,
-;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
-;; is variable, then the count is in %cl and the "imm" operand is dropped
-;; from the assembler input.
-;;
-;; This instruction shifts the target reg/mem as usual, but instead of
-;; shifting in zeros, bits are shifted in from reg operand. If the insn
-;; is a left shift double, bits are taken from the high order bits of
-;; reg, else if the insn is a shift right double, bits are taken from the
-;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
-;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
-;;
-;; Since sh[lr]d does not change the `reg' operand, that is done
-;; separately, making all shifts emit pairs of shift double and normal
-;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
-;; support a 63 bit shift, each shift where the count is in a reg expands
-;; to a pair of shifts, a branch, a shift by 32 and a label.
-;;
-;; If the shift count is a constant, we need never emit more than one
-;; shift pair, instead using moves and sign extension for counts greater
-;; than 31.
-
-(define_expand "ashl<mode>3"
- [(set (match_operand:SDWIM 0 "<shift_operand>")
- (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
- (match_operand:QI 2 "nonmemory_operand")))]
- ""
- "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
-
-(define_insn "*ashl<mode>3_doubleword"
- [(set (match_operand:DWI 0 "register_operand" "=&r,r")
- (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
- (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "#"
- [(set_attr "type" "multi")])
-
-(define_split
- [(set (match_operand:DWI 0 "register_operand")
- (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
- (match_operand:QI 2 "nonmemory_operand")))
- (clobber (reg:CC FLAGS_REG))]
- "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
- [(const_int 0)]
- "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
-
-;; By default we don't ask for a scratch register, because when DWImode
-;; values are manipulated, registers are already at a premium. But if
-;; we have one handy, we won't turn it away.
-
-(define_peephole2
- [(match_scratch:DWIH 3 "r")
- (parallel [(set (match_operand:<DWI> 0 "register_operand")
- (ashift:<DWI>
- (match_operand:<DWI> 1 "nonmemory_operand")
- (match_operand:QI 2 "nonmemory_operand")))
- (clobber (reg:CC FLAGS_REG))])
- (match_dup 3)]
- "TARGET_CMOVE"
- [(const_int 0)]
- "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
-
-(define_insn "x86_64_shld"
- [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
- (ior:DI (ashift:DI (match_dup 0)
- (match_operand:QI 2 "nonmemory_operand" "Jc"))
- (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
- (minus:QI (const_int 64) (match_dup 2)))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT"
- "shld{q}\t{%s2%1, %0|%0, %1, %2}"
- [(set_attr "type" "ishift")
- (set_attr "prefix_0f" "1")
- (set_attr "mode" "DI")
- (set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "vector")
- (set_attr "bdver1_decode" "vector")])
-
-(define_insn "x86_shld"
- [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
- (ior:SI (ashift:SI (match_dup 0)
- (match_operand:QI 2 "nonmemory_operand" "Ic"))
- (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
- (minus:QI (const_int 32) (match_dup 2)))))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "shld{l}\t{%s2%1, %0|%0, %1, %2}"
- [(set_attr "type" "ishift")
- (set_attr "prefix_0f" "1")
- (set_attr "mode" "SI")
- (set_attr "pent_pair" "np")
- (set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "vector")
- (set_attr "bdver1_decode" "vector")])
-
-(define_expand "x86_shift<mode>_adj_1"
- [(set (reg:CCZ FLAGS_REG)
- (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
- (match_dup 4))
- (const_int 0)))
- (set (match_operand:SWI48 0 "register_operand")
- (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
- (match_operand:SWI48 1 "register_operand")
- (match_dup 0)))
- (set (match_dup 1)
- (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
- (match_operand:SWI48 3 "register_operand")
- (match_dup 1)))]
- "TARGET_CMOVE"
- "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
-
-(define_expand "x86_shift<mode>_adj_2"
- [(use (match_operand:SWI48 0 "register_operand"))
- (use (match_operand:SWI48 1 "register_operand"))
- (use (match_operand:QI 2 "register_operand"))]
- ""
-{
- rtx label = gen_label_rtx ();
- rtx tmp;
-
- emit_insn (gen_testqi_ccz_1 (operands[2],
- GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
-
- tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
- tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
- tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
- gen_rtx_LABEL_REF (VOIDmode, label),
- pc_rtx);
- tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
- JUMP_LABEL (tmp) = label;
-
- emit_move_insn (operands[0], operands[1]);
- ix86_expand_clear (operands[1]);
-
- emit_label (label);
- LABEL_NUSES (label) = 1;
-
- DONE;
-})
-
-;; Avoid useless masking of count operand.
-(define_insn "*ashl<mode>3_mask"
- [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
- (ashift:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "0")
- (subreg:QI
- (and:SI
- (match_operand:SI 2 "register_operand" "c")
- (match_operand:SI 3 "const_int_operand" "n")) 0)))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
- && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
- == GET_MODE_BITSIZE (<MODE>mode)-1"
-{
- return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
-}
- [(set_attr "type" "ishift")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*bmi2_ashl<mode>3_1"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
- (match_operand:SWI48 2 "register_operand" "r")))]
- "TARGET_BMI2"
- "shlx\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "type" "ishiftx")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*ashl<mode>3_1"
- [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
- (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
- (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_LEA:
- case TYPE_ISHIFTX:
- return "#";
-
- case TYPE_ALU:
- gcc_assert (operands[2] == const1_rtx);
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
- return "add{<imodesuffix>}\t%0, %0";
-
- default:
- if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "sal{<imodesuffix>}\t%0";
- else
- return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
- }
-}
- [(set_attr "isa" "*,*,bmi2")
- (set (attr "type")
- (cond [(eq_attr "alternative" "1")
- (const_string "lea")
- (eq_attr "alternative" "2")
- (const_string "ishiftx")
- (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
- (match_operand 0 "register_operand"))
- (match_operand 2 "const1_operand"))
- (const_string "alu")
- ]
- (const_string "ishift")))
- (set (attr "length_immediate")
- (if_then_else
- (ior (eq_attr "type" "alu")
- (and (eq_attr "type" "ishift")
- (and (match_operand 2 "const1_operand")
- (ior (match_test "TARGET_SHIFT1")
- (match_test "optimize_function_for_size_p (cfun)")))))
- (const_string "0")
- (const_string "*")))
- (set_attr "mode" "<MODE>")])
-
-;; Convert shift to the shiftx pattern to avoid flags dependency.
-(define_split
- [(set (match_operand:SWI48 0 "register_operand")
- (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
- (match_operand:QI 2 "register_operand")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_BMI2 && reload_completed"
- [(set (match_dup 0)
- (ashift:SWI48 (match_dup 1) (match_dup 2)))]
- "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
-
-(define_insn "*bmi2_ashlsi3_1_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
- (match_operand:SI 2 "register_operand" "r"))))]
- "TARGET_64BIT && TARGET_BMI2"
- "shlx\t{%2, %1, %k0|%k0, %1, %2}"
- [(set_attr "type" "ishiftx")
- (set_attr "mode" "SI")])
-
-(define_insn "*ashlsi3_1_zext"
- [(set (match_operand:DI 0 "register_operand" "=r,r,r")
- (zero_extend:DI
- (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
- (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_LEA:
- case TYPE_ISHIFTX:
- return "#";
-
- case TYPE_ALU:
- gcc_assert (operands[2] == const1_rtx);
- return "add{l}\t%k0, %k0";
-
- default:
- if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "sal{l}\t%k0";
- else
- return "sal{l}\t{%2, %k0|%k0, %2}";
- }
-}
- [(set_attr "isa" "*,*,bmi2")
- (set (attr "type")
- (cond [(eq_attr "alternative" "1")
- (const_string "lea")
- (eq_attr "alternative" "2")
- (const_string "ishiftx")
- (and (match_test "TARGET_DOUBLE_WITH_ADD")
- (match_operand 2 "const1_operand"))
- (const_string "alu")
- ]
- (const_string "ishift")))
- (set (attr "length_immediate")
- (if_then_else
- (ior (eq_attr "type" "alu")
- (and (eq_attr "type" "ishift")
- (and (match_operand 2 "const1_operand")
- (ior (match_test "TARGET_SHIFT1")
- (match_test "optimize_function_for_size_p (cfun)")))))
- (const_string "0")
- (const_string "*")))
- (set_attr "mode" "SI")])
-
-;; Convert shift to the shiftx pattern to avoid flags dependency.
-(define_split
- [(set (match_operand:DI 0 "register_operand")
- (zero_extend:DI
- (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
- (match_operand:QI 2 "register_operand"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && TARGET_BMI2 && reload_completed"
- [(set (match_dup 0)
- (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
- "operands[2] = gen_lowpart (SImode, operands[2]);")
-
-(define_insn "*ashlhi3_1"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
- (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
- (match_operand:QI 2 "nonmemory_operand" "cI,M")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_LEA:
- return "#";
-
- case TYPE_ALU:
- gcc_assert (operands[2] == const1_rtx);
- return "add{w}\t%0, %0";
-
- default:
- if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "sal{w}\t%0";
- else
- return "sal{w}\t{%2, %0|%0, %2}";
- }
-}
- [(set (attr "type")
- (cond [(eq_attr "alternative" "1")
- (const_string "lea")
- (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
- (match_operand 0 "register_operand"))
- (match_operand 2 "const1_operand"))
- (const_string "alu")
- ]
- (const_string "ishift")))
- (set (attr "length_immediate")
- (if_then_else
- (ior (eq_attr "type" "alu")
- (and (eq_attr "type" "ishift")
- (and (match_operand 2 "const1_operand")
- (ior (match_test "TARGET_SHIFT1")
- (match_test "optimize_function_for_size_p (cfun)")))))
- (const_string "0")
- (const_string "*")))
- (set_attr "mode" "HI,SI")])
-
-;; %%% Potential partial reg stall on alternative 1. What to do?
-(define_insn "*ashlqi3_1"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
- (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
- (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_LEA:
- return "#";
-
- case TYPE_ALU:
- gcc_assert (operands[2] == const1_rtx);
- if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
- return "add{l}\t%k0, %k0";
- else
- return "add{b}\t%0, %0";
-
- default:
- if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- {
- if (get_attr_mode (insn) == MODE_SI)
- return "sal{l}\t%k0";
- else
- return "sal{b}\t%0";
- }
- else
- {
- if (get_attr_mode (insn) == MODE_SI)
- return "sal{l}\t{%2, %k0|%k0, %2}";
- else
- return "sal{b}\t{%2, %0|%0, %2}";
- }
- }
-}
- [(set (attr "type")
- (cond [(eq_attr "alternative" "2")
- (const_string "lea")
- (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
- (match_operand 0 "register_operand"))
- (match_operand 2 "const1_operand"))
- (const_string "alu")
- ]
- (const_string "ishift")))
- (set (attr "length_immediate")
- (if_then_else
- (ior (eq_attr "type" "alu")
- (and (eq_attr "type" "ishift")
- (and (match_operand 2 "const1_operand")
- (ior (match_test "TARGET_SHIFT1")
- (match_test "optimize_function_for_size_p (cfun)")))))
- (const_string "0")
- (const_string "*")))
- (set_attr "mode" "QI,SI,SI")])
-
-(define_insn "*ashlqi3_1_slp"
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
- (ashift:QI (match_dup 0)
- (match_operand:QI 1 "nonmemory_operand" "cI")))
- (clobber (reg:CC FLAGS_REG))]
- "(optimize_function_for_size_p (cfun)
- || !TARGET_PARTIAL_FLAG_REG_STALL
- || (operands[1] == const1_rtx
- && (TARGET_SHIFT1
- || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_ALU:
- gcc_assert (operands[1] == const1_rtx);
- return "add{b}\t%0, %0";
-
- default:
- if (operands[1] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "sal{b}\t%0";
- else
- return "sal{b}\t{%1, %0|%0, %1}";
- }
-}
- [(set (attr "type")
- (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
- (match_operand 0 "register_operand"))
- (match_operand 1 "const1_operand"))
- (const_string "alu")
- ]
- (const_string "ishift1")))
- (set (attr "length_immediate")
- (if_then_else
- (ior (eq_attr "type" "alu")
- (and (eq_attr "type" "ishift1")
- (and (match_operand 1 "const1_operand")
- (ior (match_test "TARGET_SHIFT1")
- (match_test "optimize_function_for_size_p (cfun)")))))
- (const_string "0")
- (const_string "*")))
- (set_attr "mode" "QI")])
-
-;; Convert ashift to the lea pattern to avoid flags dependency.
-(define_split
- [(set (match_operand 0 "register_operand")
- (ashift (match_operand 1 "index_register_operand")
- (match_operand:QI 2 "const_int_operand")))
- (clobber (reg:CC FLAGS_REG))]
- "GET_MODE (operands[0]) == GET_MODE (operands[1])
- && reload_completed
- && true_regnum (operands[0]) != true_regnum (operands[1])"
- [(const_int 0)]
-{
- enum machine_mode mode = GET_MODE (operands[0]);
- rtx pat;
-
- if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
- {
- mode = SImode;
- operands[0] = gen_lowpart (mode, operands[0]);
- operands[1] = gen_lowpart (mode, operands[1]);
- }
-
- operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
-
- pat = gen_rtx_MULT (mode, operands[1], operands[2]);
-
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
- DONE;
-})
-
-;; Convert ashift to the lea pattern to avoid flags dependency.
-(define_split
- [(set (match_operand:DI 0 "register_operand")
- (zero_extend:DI
- (ashift:SI (match_operand:SI 1 "index_register_operand")
- (match_operand:QI 2 "const_int_operand"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && reload_completed
- && true_regnum (operands[0]) != true_regnum (operands[1])"
- [(set (match_dup 0)
- (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
-{
- operands[1] = gen_lowpart (SImode, operands[1]);
- operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
-})
-
-;; This pattern can't accept a variable shift count, since shifts by
-;; zero don't affect the flags. We assume that shifts by constant
-;; zero are optimized away.
-(define_insn "*ashl<mode>3_cmp"
- [(set (reg FLAGS_REG)
- (compare
- (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
- (const_int 0)))
- (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
- (ashift:SWI (match_dup 1) (match_dup 2)))]
- "(optimize_function_for_size_p (cfun)
- || !TARGET_PARTIAL_FLAG_REG_STALL
- || (operands[2] == const1_rtx
- && (TARGET_SHIFT1
- || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
- && ix86_match_ccmode (insn, CCGOCmode)
- && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_ALU:
- gcc_assert (operands[2] == const1_rtx);
- return "add{<imodesuffix>}\t%0, %0";
-
- default:
- if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "sal{<imodesuffix>}\t%0";
- else
- return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
- }
-}
- [(set (attr "type")
- (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
- (match_operand 0 "register_operand"))
- (match_operand 2 "const1_operand"))
- (const_string "alu")
- ]
- (const_string "ishift")))
- (set (attr "length_immediate")
- (if_then_else
- (ior (eq_attr "type" "alu")
- (and (eq_attr "type" "ishift")
- (and (match_operand 2 "const1_operand")
- (ior (match_test "TARGET_SHIFT1")
- (match_test "optimize_function_for_size_p (cfun)")))))
- (const_string "0")
- (const_string "*")))
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*ashlsi3_cmp_zext"
- [(set (reg FLAGS_REG)
- (compare
- (ashift:SI (match_operand:SI 1 "register_operand" "0")
- (match_operand:QI 2 "const_1_to_31_operand" "I"))
- (const_int 0)))
- (set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
- "TARGET_64BIT
- && (optimize_function_for_size_p (cfun)
- || !TARGET_PARTIAL_FLAG_REG_STALL
- || (operands[2] == const1_rtx
- && (TARGET_SHIFT1
- || TARGET_DOUBLE_WITH_ADD)))
- && ix86_match_ccmode (insn, CCGOCmode)
- && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_ALU:
- gcc_assert (operands[2] == const1_rtx);
- return "add{l}\t%k0, %k0";
-
- default:
- if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "sal{l}\t%k0";
- else
- return "sal{l}\t{%2, %k0|%k0, %2}";
- }
-}
- [(set (attr "type")
- (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
- (match_operand 2 "const1_operand"))
- (const_string "alu")
- ]
- (const_string "ishift")))
- (set (attr "length_immediate")
- (if_then_else
- (ior (eq_attr "type" "alu")
- (and (eq_attr "type" "ishift")
- (and (match_operand 2 "const1_operand")
- (ior (match_test "TARGET_SHIFT1")
- (match_test "optimize_function_for_size_p (cfun)")))))
- (const_string "0")
- (const_string "*")))
- (set_attr "mode" "SI")])
-
-(define_insn "*ashl<mode>3_cconly"
- [(set (reg FLAGS_REG)
- (compare
- (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
- (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
- (const_int 0)))
- (clobber (match_scratch:SWI 0 "=<r>"))]
- "(optimize_function_for_size_p (cfun)
- || !TARGET_PARTIAL_FLAG_REG_STALL
- || (operands[2] == const1_rtx
- && (TARGET_SHIFT1
- || TARGET_DOUBLE_WITH_ADD)))
- && ix86_match_ccmode (insn, CCGOCmode)"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_ALU:
- gcc_assert (operands[2] == const1_rtx);
- return "add{<imodesuffix>}\t%0, %0";
-
- default:
- if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "sal{<imodesuffix>}\t%0";
- else
- return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
- }
-}
- [(set (attr "type")
- (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
- (match_operand 0 "register_operand"))
- (match_operand 2 "const1_operand"))
- (const_string "alu")
- ]
- (const_string "ishift")))
- (set (attr "length_immediate")
- (if_then_else
- (ior (eq_attr "type" "alu")
- (and (eq_attr "type" "ishift")
- (and (match_operand 2 "const1_operand")
- (ior (match_test "TARGET_SHIFT1")
- (match_test "optimize_function_for_size_p (cfun)")))))
- (const_string "0")
- (const_string "*")))
- (set_attr "mode" "<MODE>")])
-
-;; See comment above `ashl<mode>3' about how this works.
-
-(define_expand "<shift_insn><mode>3"
- [(set (match_operand:SDWIM 0 "<shift_operand>")
- (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
- (match_operand:QI 2 "nonmemory_operand")))]
- ""
- "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
-
-;; Avoid useless masking of count operand.
-(define_insn "*<shift_insn><mode>3_mask"
- [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
- (any_shiftrt:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "0")
- (subreg:QI
- (and:SI
- (match_operand:SI 2 "register_operand" "c")
- (match_operand:SI 3 "const_int_operand" "n")) 0)))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
- && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
- == GET_MODE_BITSIZE (<MODE>mode)-1"
-{
- return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
-}
- [(set_attr "type" "ishift")
- (set_attr "mode" "<MODE>")])
-
-(define_insn_and_split "*<shift_insn><mode>3_doubleword"
- [(set (match_operand:DWI 0 "register_operand" "=r")
- (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
- (match_operand:QI 2 "nonmemory_operand" "<S>c")))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "#"
- "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
- [(const_int 0)]
- "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
- [(set_attr "type" "multi")])
-
-;; By default we don't ask for a scratch register, because when DWImode
-;; values are manipulated, registers are already at a premium. But if
-;; we have one handy, we won't turn it away.
-
-(define_peephole2
- [(match_scratch:DWIH 3 "r")
- (parallel [(set (match_operand:<DWI> 0 "register_operand")
- (any_shiftrt:<DWI>
- (match_operand:<DWI> 1 "register_operand")
- (match_operand:QI 2 "nonmemory_operand")))
- (clobber (reg:CC FLAGS_REG))])
- (match_dup 3)]
- "TARGET_CMOVE"
- [(const_int 0)]
- "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
-
-(define_insn "x86_64_shrd"
- [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
- (ior:DI (ashiftrt:DI (match_dup 0)
- (match_operand:QI 2 "nonmemory_operand" "Jc"))
- (ashift:DI (match_operand:DI 1 "register_operand" "r")
- (minus:QI (const_int 64) (match_dup 2)))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT"
- "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
- [(set_attr "type" "ishift")
- (set_attr "prefix_0f" "1")
- (set_attr "mode" "DI")
- (set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "vector")
- (set_attr "bdver1_decode" "vector")])
-
-(define_insn "x86_shrd"
- [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
- (ior:SI (ashiftrt:SI (match_dup 0)
- (match_operand:QI 2 "nonmemory_operand" "Ic"))
- (ashift:SI (match_operand:SI 1 "register_operand" "r")
- (minus:QI (const_int 32) (match_dup 2)))))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
- [(set_attr "type" "ishift")
- (set_attr "prefix_0f" "1")
- (set_attr "mode" "SI")
- (set_attr "pent_pair" "np")
- (set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "vector")
- (set_attr "bdver1_decode" "vector")])
-
-(define_insn "ashrdi3_cvt"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
- (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
- (match_operand:QI 2 "const_int_operand")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && INTVAL (operands[2]) == 63
- && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
- && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
- "@
- {cqto|cqo}
- sar{q}\t{%2, %0|%0, %2}"
- [(set_attr "type" "imovx,ishift")
- (set_attr "prefix_0f" "0,*")
- (set_attr "length_immediate" "0,*")
- (set_attr "modrm" "0,1")
- (set_attr "mode" "DI")])
-
-(define_insn "ashrsi3_cvt"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
- (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
- (match_operand:QI 2 "const_int_operand")))
- (clobber (reg:CC FLAGS_REG))]
- "INTVAL (operands[2]) == 31
- && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
- && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
- "@
- {cltd|cdq}
- sar{l}\t{%2, %0|%0, %2}"
- [(set_attr "type" "imovx,ishift")
- (set_attr "prefix_0f" "0,*")
- (set_attr "length_immediate" "0,*")
- (set_attr "modrm" "0,1")
- (set_attr "mode" "SI")])
-
-(define_insn "*ashrsi3_cvt_zext"
- [(set (match_operand:DI 0 "register_operand" "=*d,r")
- (zero_extend:DI
- (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
- (match_operand:QI 2 "const_int_operand"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && INTVAL (operands[2]) == 31
- && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
- && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
- "@
- {cltd|cdq}
- sar{l}\t{%2, %k0|%k0, %2}"
- [(set_attr "type" "imovx,ishift")
- (set_attr "prefix_0f" "0,*")
- (set_attr "length_immediate" "0,*")
- (set_attr "modrm" "0,1")
- (set_attr "mode" "SI")])
-
-(define_expand "x86_shift<mode>_adj_3"
- [(use (match_operand:SWI48 0 "register_operand"))
- (use (match_operand:SWI48 1 "register_operand"))
- (use (match_operand:QI 2 "register_operand"))]
- ""
-{
- rtx label = gen_label_rtx ();
- rtx tmp;
-
- emit_insn (gen_testqi_ccz_1 (operands[2],
- GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
-
- tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
- tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
- tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
- gen_rtx_LABEL_REF (VOIDmode, label),
- pc_rtx);
- tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
- JUMP_LABEL (tmp) = label;
-
- emit_move_insn (operands[0], operands[1]);
- emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
- GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
- emit_label (label);
- LABEL_NUSES (label) = 1;
-
- DONE;
-})
-
-(define_insn "*bmi2_<shift_insn><mode>3_1"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
- (match_operand:SWI48 2 "register_operand" "r")))]
- "TARGET_BMI2"
- "<shift>x\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "type" "ishiftx")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*<shift_insn><mode>3_1"
- [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
- (any_shiftrt:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
- (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_ISHIFTX:
- return "#";
-
- default:
- if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "<shift>{<imodesuffix>}\t%0";
- else
- return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
- }
-}
- [(set_attr "isa" "*,bmi2")
- (set_attr "type" "ishift,ishiftx")
- (set (attr "length_immediate")
- (if_then_else
- (and (match_operand 2 "const1_operand")
- (ior (match_test "TARGET_SHIFT1")
- (match_test "optimize_function_for_size_p (cfun)")))
- (const_string "0")
- (const_string "*")))
- (set_attr "mode" "<MODE>")])
-
-;; Convert shift to the shiftx pattern to avoid flags dependency.
-(define_split
- [(set (match_operand:SWI48 0 "register_operand")
- (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
- (match_operand:QI 2 "register_operand")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_BMI2 && reload_completed"
- [(set (match_dup 0)
- (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
- "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
-
-(define_insn "*bmi2_<shift_insn>si3_1_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
- (match_operand:SI 2 "register_operand" "r"))))]
- "TARGET_64BIT && TARGET_BMI2"
- "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
- [(set_attr "type" "ishiftx")
- (set_attr "mode" "SI")])
-
-(define_insn "*<shift_insn>si3_1_zext"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (zero_extend:DI
- (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
- (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_ISHIFTX:
- return "#";
-
- default:
- if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "<shift>{l}\t%k0";
- else
- return "<shift>{l}\t{%2, %k0|%k0, %2}";
- }
-}
- [(set_attr "isa" "*,bmi2")
- (set_attr "type" "ishift,ishiftx")
- (set (attr "length_immediate")
- (if_then_else
- (and (match_operand 2 "const1_operand")
- (ior (match_test "TARGET_SHIFT1")
- (match_test "optimize_function_for_size_p (cfun)")))
- (const_string "0")
- (const_string "*")))
- (set_attr "mode" "SI")])
-
-;; Convert shift to the shiftx pattern to avoid flags dependency.
-(define_split
- [(set (match_operand:DI 0 "register_operand")
- (zero_extend:DI
- (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
- (match_operand:QI 2 "register_operand"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && TARGET_BMI2 && reload_completed"
- [(set (match_dup 0)
- (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
- "operands[2] = gen_lowpart (SImode, operands[2]);")
-
-(define_insn "*<shift_insn><mode>3_1"
- [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
- (any_shiftrt:SWI12
- (match_operand:SWI12 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "nonmemory_operand" "c<S>")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
-{
- if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "<shift>{<imodesuffix>}\t%0";
- else
- return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
-}
- [(set_attr "type" "ishift")
- (set (attr "length_immediate")
- (if_then_else
- (and (match_operand 2 "const1_operand")
- (ior (match_test "TARGET_SHIFT1")
- (match_test "optimize_function_for_size_p (cfun)")))
- (const_string "0")
- (const_string "*")))
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*<shift_insn>qi3_1_slp"
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
- (any_shiftrt:QI (match_dup 0)
- (match_operand:QI 1 "nonmemory_operand" "cI")))
- (clobber (reg:CC FLAGS_REG))]
- "(optimize_function_for_size_p (cfun)
- || !TARGET_PARTIAL_REG_STALL
- || (operands[1] == const1_rtx
- && TARGET_SHIFT1))"
-{
- if (operands[1] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "<shift>{b}\t%0";
- else
- return "<shift>{b}\t{%1, %0|%0, %1}";
-}
- [(set_attr "type" "ishift1")
- (set (attr "length_immediate")
- (if_then_else
- (and (match_operand 1 "const1_operand")
- (ior (match_test "TARGET_SHIFT1")
- (match_test "optimize_function_for_size_p (cfun)")))
- (const_string "0")
- (const_string "*")))
- (set_attr "mode" "QI")])
-
-;; This pattern can't accept a variable shift count, since shifts by
-;; zero don't affect the flags. We assume that shifts by constant
-;; zero are optimized away.
-(define_insn "*<shift_insn><mode>3_cmp"
- [(set (reg FLAGS_REG)
- (compare
- (any_shiftrt:SWI
- (match_operand:SWI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
- (const_int 0)))
- (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
- (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
- "(optimize_function_for_size_p (cfun)
- || !TARGET_PARTIAL_FLAG_REG_STALL
- || (operands[2] == const1_rtx
- && TARGET_SHIFT1))
- && ix86_match_ccmode (insn, CCGOCmode)
- && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
-{
- if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "<shift>{<imodesuffix>}\t%0";
- else
- return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
-}
- [(set_attr "type" "ishift")
- (set (attr "length_immediate")
- (if_then_else
- (and (match_operand 2 "const1_operand")
- (ior (match_test "TARGET_SHIFT1")
- (match_test "optimize_function_for_size_p (cfun)")))
- (const_string "0")
- (const_string "*")))
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*<shift_insn>si3_cmp_zext"
- [(set (reg FLAGS_REG)
- (compare
- (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
- (match_operand:QI 2 "const_1_to_31_operand" "I"))
- (const_int 0)))
- (set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
- "TARGET_64BIT
- && (optimize_function_for_size_p (cfun)
- || !TARGET_PARTIAL_FLAG_REG_STALL
- || (operands[2] == const1_rtx
- && TARGET_SHIFT1))
- && ix86_match_ccmode (insn, CCGOCmode)
- && ix86_binary_operator_ok (<CODE>, SImode, operands)"
-{
- if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "<shift>{l}\t%k0";
- else
- return "<shift>{l}\t{%2, %k0|%k0, %2}";
-}
- [(set_attr "type" "ishift")
- (set (attr "length_immediate")
- (if_then_else
- (and (match_operand 2 "const1_operand")
- (ior (match_test "TARGET_SHIFT1")
- (match_test "optimize_function_for_size_p (cfun)")))
- (const_string "0")
- (const_string "*")))
- (set_attr "mode" "SI")])
-
-(define_insn "*<shift_insn><mode>3_cconly"
- [(set (reg FLAGS_REG)
- (compare
- (any_shiftrt:SWI
- (match_operand:SWI 1 "register_operand" "0")
- (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
- (const_int 0)))
- (clobber (match_scratch:SWI 0 "=<r>"))]
- "(optimize_function_for_size_p (cfun)
- || !TARGET_PARTIAL_FLAG_REG_STALL
- || (operands[2] == const1_rtx
- && TARGET_SHIFT1))
- && ix86_match_ccmode (insn, CCGOCmode)"
-{
- if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "<shift>{<imodesuffix>}\t%0";
- else
- return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
-}
- [(set_attr "type" "ishift")
- (set (attr "length_immediate")
- (if_then_else
- (and (match_operand 2 "const1_operand")
- (ior (match_test "TARGET_SHIFT1")
- (match_test "optimize_function_for_size_p (cfun)")))
- (const_string "0")
- (const_string "*")))
- (set_attr "mode" "<MODE>")])
-
-;; Rotate instructions
-
-(define_expand "<rotate_insn>ti3"
- [(set (match_operand:TI 0 "register_operand")
- (any_rotate:TI (match_operand:TI 1 "register_operand")
- (match_operand:QI 2 "nonmemory_operand")))]
- "TARGET_64BIT"
-{
- if (const_1_to_63_operand (operands[2], VOIDmode))
- emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
- (operands[0], operands[1], operands[2]));
- else
- FAIL;
-
- DONE;
-})
-
-(define_expand "<rotate_insn>di3"
- [(set (match_operand:DI 0 "shiftdi_operand")
- (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
- (match_operand:QI 2 "nonmemory_operand")))]
- ""
-{
- if (TARGET_64BIT)
- ix86_expand_binary_operator (<CODE>, DImode, operands);
- else if (const_1_to_31_operand (operands[2], VOIDmode))
- emit_insn (gen_ix86_<rotate_insn>di3_doubleword
- (operands[0], operands[1], operands[2]));
- else
- FAIL;
-
- DONE;
-})
-
-(define_expand "<rotate_insn><mode>3"
- [(set (match_operand:SWIM124 0 "nonimmediate_operand")
- (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
- (match_operand:QI 2 "nonmemory_operand")))]
- ""
- "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
-
-;; Avoid useless masking of count operand.
-(define_insn "*<rotate_insn><mode>3_mask"
- [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
- (any_rotate:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "0")
- (subreg:QI
- (and:SI
- (match_operand:SI 2 "register_operand" "c")
- (match_operand:SI 3 "const_int_operand" "n")) 0)))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
- && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
- == GET_MODE_BITSIZE (<MODE>mode)-1"
-{
- return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
-}
- [(set_attr "type" "rotate")
- (set_attr "mode" "<MODE>")])
-
-;; Implement rotation using two double-precision
-;; shift instructions and a scratch register.
-
-(define_insn_and_split "ix86_rotl<dwi>3_doubleword"
- [(set (match_operand:<DWI> 0 "register_operand" "=r")
- (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
- (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
- (clobber (reg:CC FLAGS_REG))
- (clobber (match_scratch:DWIH 3 "=&r"))]
- ""
- "#"
- "reload_completed"
- [(set (match_dup 3) (match_dup 4))
- (parallel
- [(set (match_dup 4)
- (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
- (lshiftrt:DWIH (match_dup 5)
- (minus:QI (match_dup 6) (match_dup 2)))))
- (clobber (reg:CC FLAGS_REG))])
- (parallel
- [(set (match_dup 5)
- (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
- (lshiftrt:DWIH (match_dup 3)
- (minus:QI (match_dup 6) (match_dup 2)))))
- (clobber (reg:CC FLAGS_REG))])]
-{
- operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
-
- split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
-})
-
-(define_insn_and_split "ix86_rotr<dwi>3_doubleword"
- [(set (match_operand:<DWI> 0 "register_operand" "=r")
- (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
- (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
- (clobber (reg:CC FLAGS_REG))
- (clobber (match_scratch:DWIH 3 "=&r"))]
- ""
- "#"
- "reload_completed"
- [(set (match_dup 3) (match_dup 4))
- (parallel
- [(set (match_dup 4)
- (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
- (ashift:DWIH (match_dup 5)
- (minus:QI (match_dup 6) (match_dup 2)))))
- (clobber (reg:CC FLAGS_REG))])
- (parallel
- [(set (match_dup 5)
- (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
- (ashift:DWIH (match_dup 3)
- (minus:QI (match_dup 6) (match_dup 2)))))
- (clobber (reg:CC FLAGS_REG))])]
-{
- operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
-
- split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
-})
-
-(define_insn "*bmi2_rorx<mode>3_1"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
- (match_operand:QI 2 "immediate_operand" "<S>")))]
- "TARGET_BMI2"
- "rorx\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "type" "rotatex")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*<rotate_insn><mode>3_1"
- [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
- (any_rotate:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
- (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_ROTATEX:
- return "#";
-
- default:
- if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "<rotate>{<imodesuffix>}\t%0";
- else
- return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
- }
-}
- [(set_attr "isa" "*,bmi2")
- (set_attr "type" "rotate,rotatex")
- (set (attr "length_immediate")
- (if_then_else
- (and (eq_attr "type" "rotate")
- (and (match_operand 2 "const1_operand")
- (ior (match_test "TARGET_SHIFT1")
- (match_test "optimize_function_for_size_p (cfun)"))))
- (const_string "0")
- (const_string "*")))
- (set_attr "mode" "<MODE>")])
-
-;; Convert rotate to the rotatex pattern to avoid flags dependency.
-(define_split
- [(set (match_operand:SWI48 0 "register_operand")
- (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
- (match_operand:QI 2 "immediate_operand")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_BMI2 && reload_completed"
- [(set (match_dup 0)
- (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
-{
- operands[2]
- = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
-})
-
-(define_split
- [(set (match_operand:SWI48 0 "register_operand")
- (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
- (match_operand:QI 2 "immediate_operand")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_BMI2 && reload_completed"
- [(set (match_dup 0)
- (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
-
-(define_insn "*bmi2_rorxsi3_1_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
- (match_operand:QI 2 "immediate_operand" "I"))))]
- "TARGET_64BIT && TARGET_BMI2"
- "rorx\t{%2, %1, %k0|%k0, %1, %2}"
- [(set_attr "type" "rotatex")
- (set_attr "mode" "SI")])
-
-(define_insn "*<rotate_insn>si3_1_zext"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (zero_extend:DI
- (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
- (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_ROTATEX:
- return "#";
-
- default:
- if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "<rotate>{l}\t%k0";
- else
- return "<rotate>{l}\t{%2, %k0|%k0, %2}";
- }
-}
- [(set_attr "isa" "*,bmi2")
- (set_attr "type" "rotate,rotatex")
- (set (attr "length_immediate")
- (if_then_else
- (and (eq_attr "type" "rotate")
- (and (match_operand 2 "const1_operand")
- (ior (match_test "TARGET_SHIFT1")
- (match_test "optimize_function_for_size_p (cfun)"))))
- (const_string "0")
- (const_string "*")))
- (set_attr "mode" "SI")])
-
-;; Convert rotate to the rotatex pattern to avoid flags dependency.
-(define_split
- [(set (match_operand:DI 0 "register_operand")
- (zero_extend:DI
- (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
- (match_operand:QI 2 "immediate_operand"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && TARGET_BMI2 && reload_completed"
- [(set (match_dup 0)
- (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
-{
- operands[2]
- = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
-})
-
-(define_split
- [(set (match_operand:DI 0 "register_operand")
- (zero_extend:DI
- (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
- (match_operand:QI 2 "immediate_operand"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && TARGET_BMI2 && reload_completed"
- [(set (match_dup 0)
- (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
-
-(define_insn "*<rotate_insn><mode>3_1"
- [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
- (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "nonmemory_operand" "c<S>")))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
-{
- if (operands[2] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "<rotate>{<imodesuffix>}\t%0";
- else
- return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
-}
- [(set_attr "type" "rotate")
- (set (attr "length_immediate")
- (if_then_else
- (and (match_operand 2 "const1_operand")
- (ior (match_test "TARGET_SHIFT1")
- (match_test "optimize_function_for_size_p (cfun)")))
- (const_string "0")
- (const_string "*")))
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*<rotate_insn>qi3_1_slp"
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
- (any_rotate:QI (match_dup 0)
- (match_operand:QI 1 "nonmemory_operand" "cI")))
- (clobber (reg:CC FLAGS_REG))]
- "(optimize_function_for_size_p (cfun)
- || !TARGET_PARTIAL_REG_STALL
- || (operands[1] == const1_rtx
- && TARGET_SHIFT1))"
-{
- if (operands[1] == const1_rtx
- && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "<rotate>{b}\t%0";
- else
- return "<rotate>{b}\t{%1, %0|%0, %1}";
-}
- [(set_attr "type" "rotate1")
- (set (attr "length_immediate")
- (if_then_else
- (and (match_operand 1 "const1_operand")
- (ior (match_test "TARGET_SHIFT1")
- (match_test "optimize_function_for_size_p (cfun)")))
- (const_string "0")
- (const_string "*")))
- (set_attr "mode" "QI")])
-
-(define_split
- [(set (match_operand:HI 0 "register_operand")
- (any_rotate:HI (match_dup 0) (const_int 8)))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed
- && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
- [(parallel [(set (strict_low_part (match_dup 0))
- (bswap:HI (match_dup 0)))
- (clobber (reg:CC FLAGS_REG))])])
-
-;; Bit set / bit test instructions
-
-(define_expand "extv"
- [(set (match_operand:SI 0 "register_operand")
- (sign_extract:SI (match_operand:SI 1 "register_operand")
- (match_operand:SI 2 "const8_operand")
- (match_operand:SI 3 "const8_operand")))]
- ""
-{
- /* Handle extractions from %ah et al. */
- if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
- FAIL;
-
- /* From mips.md: extract_bit_field doesn't verify that our source
- matches the predicate, so check it again here. */
- if (! ext_register_operand (operands[1], VOIDmode))
- FAIL;
-})
-
-(define_expand "extzv"
- [(set (match_operand:SI 0 "register_operand")
- (zero_extract:SI (match_operand 1 "ext_register_operand")
- (match_operand:SI 2 "const8_operand")
- (match_operand:SI 3 "const8_operand")))]
- ""
-{
- /* Handle extractions from %ah et al. */
- if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
- FAIL;
-
- /* From mips.md: extract_bit_field doesn't verify that our source
- matches the predicate, so check it again here. */
- if (! ext_register_operand (operands[1], VOIDmode))
- FAIL;
-})
-
-(define_expand "insv"
- [(set (zero_extract (match_operand 0 "register_operand")
- (match_operand 1 "const_int_operand")
- (match_operand 2 "const_int_operand"))
- (match_operand 3 "register_operand"))]
- ""
-{
- rtx (*gen_mov_insv_1) (rtx, rtx);
-
- if (ix86_expand_pinsr (operands))
- DONE;
-
- /* Handle insertions to %ah et al. */
- if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
- FAIL;
-
- /* From mips.md: insert_bit_field doesn't verify that our source
- matches the predicate, so check it again here. */
- if (! ext_register_operand (operands[0], VOIDmode))
- FAIL;
-
- gen_mov_insv_1 = (TARGET_64BIT
- ? gen_movdi_insv_1 : gen_movsi_insv_1);
-
- emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
- DONE;
-})
-
-;; %%% bts, btr, btc, bt.
-;; In general these instructions are *slow* when applied to memory,
-;; since they enforce atomic operation. When applied to registers,
-;; it depends on the cpu implementation. They're never faster than
-;; the corresponding and/ior/xor operations, so with 32-bit there's
-;; no point. But in 64-bit, we can't hold the relevant immediates
-;; within the instruction itself, so operating on bits in the high
-;; 32-bits of a register becomes easier.
-;;
-;; These are slow on Nocona, but fast on Athlon64. We do require the use
-;; of btrq and btcq for corner cases of post-reload expansion of absdf and
-;; negdf respectively, so they can never be disabled entirely.
-
-(define_insn "*btsq"
- [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
- (const_int 1)
- (match_operand:DI 1 "const_0_to_63_operand"))
- (const_int 1))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
- "bts{q}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "prefix_0f" "1")
- (set_attr "mode" "DI")])
-
-(define_insn "*btrq"
- [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
- (const_int 1)
- (match_operand:DI 1 "const_0_to_63_operand"))
- (const_int 0))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
- "btr{q}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "prefix_0f" "1")
- (set_attr "mode" "DI")])
-
-(define_insn "*btcq"
- [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
- (const_int 1)
- (match_operand:DI 1 "const_0_to_63_operand"))
- (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
- "btc{q}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "prefix_0f" "1")
- (set_attr "mode" "DI")])
-
-;; Allow Nocona to avoid these instructions if a register is available.
-
-(define_peephole2
- [(match_scratch:DI 2 "r")
- (parallel [(set (zero_extract:DI
- (match_operand:DI 0 "register_operand")
- (const_int 1)
- (match_operand:DI 1 "const_0_to_63_operand"))
- (const_int 1))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_64BIT && !TARGET_USE_BT"
- [(const_int 0)]
-{
- HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
- rtx op1;
-
- if (HOST_BITS_PER_WIDE_INT >= 64)
- lo = (HOST_WIDE_INT)1 << i, hi = 0;
- else if (i < HOST_BITS_PER_WIDE_INT)
- lo = (HOST_WIDE_INT)1 << i, hi = 0;
- else
- lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
-
- op1 = immed_double_const (lo, hi, DImode);
- if (i >= 31)
- {
- emit_move_insn (operands[2], op1);
- op1 = operands[2];
- }
-
- emit_insn (gen_iordi3 (operands[0], operands[0], op1));
- DONE;
-})
-
-(define_peephole2
- [(match_scratch:DI 2 "r")
- (parallel [(set (zero_extract:DI
- (match_operand:DI 0 "register_operand")
- (const_int 1)
- (match_operand:DI 1 "const_0_to_63_operand"))
- (const_int 0))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_64BIT && !TARGET_USE_BT"
- [(const_int 0)]
-{
- HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
- rtx op1;
-
- if (HOST_BITS_PER_WIDE_INT >= 64)
- lo = (HOST_WIDE_INT)1 << i, hi = 0;
- else if (i < HOST_BITS_PER_WIDE_INT)
- lo = (HOST_WIDE_INT)1 << i, hi = 0;
- else
- lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
-
- op1 = immed_double_const (~lo, ~hi, DImode);
- if (i >= 32)
- {
- emit_move_insn (operands[2], op1);
- op1 = operands[2];
- }
-
- emit_insn (gen_anddi3 (operands[0], operands[0], op1));
- DONE;
-})
-
-(define_peephole2
- [(match_scratch:DI 2 "r")
- (parallel [(set (zero_extract:DI
- (match_operand:DI 0 "register_operand")
- (const_int 1)
- (match_operand:DI 1 "const_0_to_63_operand"))
- (not:DI (zero_extract:DI
- (match_dup 0) (const_int 1) (match_dup 1))))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_64BIT && !TARGET_USE_BT"
- [(const_int 0)]
-{
- HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
- rtx op1;
-
- if (HOST_BITS_PER_WIDE_INT >= 64)
- lo = (HOST_WIDE_INT)1 << i, hi = 0;
- else if (i < HOST_BITS_PER_WIDE_INT)
- lo = (HOST_WIDE_INT)1 << i, hi = 0;
- else
- lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
-
- op1 = immed_double_const (lo, hi, DImode);
- if (i >= 31)
- {
- emit_move_insn (operands[2], op1);
- op1 = operands[2];
- }
-
- emit_insn (gen_xordi3 (operands[0], operands[0], op1));
- DONE;
-})
-
-(define_insn "*bt<mode>"
- [(set (reg:CCC FLAGS_REG)
- (compare:CCC
- (zero_extract:SWI48
- (match_operand:SWI48 0 "register_operand" "r")
- (const_int 1)
- (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
- (const_int 0)))]
- "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
- "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "prefix_0f" "1")
- (set_attr "mode" "<MODE>")])
-
-;; Store-flag instructions.
-
-;; For all sCOND expanders, also expand the compare or test insn that
-;; generates cc0. Generate an equality comparison if `seq' or `sne'.
-
-(define_insn_and_split "*setcc_di_1"
- [(set (match_operand:DI 0 "register_operand" "=q")
- (match_operator:DI 1 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)]))]
- "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
- "#"
- "&& reload_completed"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
-{
- PUT_MODE (operands[1], QImode);
- operands[2] = gen_lowpart (QImode, operands[0]);
-})
-
-(define_insn_and_split "*setcc_si_1_and"
- [(set (match_operand:SI 0 "register_operand" "=q")
- (match_operator:SI 1 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)]))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_PARTIAL_REG_STALL
- && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
- "#"
- "&& reload_completed"
- [(set (match_dup 2) (match_dup 1))
- (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
- (clobber (reg:CC FLAGS_REG))])]
-{
- PUT_MODE (operands[1], QImode);
- operands[2] = gen_lowpart (QImode, operands[0]);
-})
-
-(define_insn_and_split "*setcc_si_1_movzbl"
- [(set (match_operand:SI 0 "register_operand" "=q")
- (match_operator:SI 1 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)]))]
- "!TARGET_PARTIAL_REG_STALL
- && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
- "#"
- "&& reload_completed"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
-{
- PUT_MODE (operands[1], QImode);
- operands[2] = gen_lowpart (QImode, operands[0]);
-})
-
-(define_insn "*setcc_qi"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
- (match_operator:QI 1 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)]))]
- ""
- "set%C1\t%0"
- [(set_attr "type" "setcc")
- (set_attr "mode" "QI")])
-
-(define_insn "*setcc_qi_slp"
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
- (match_operator:QI 1 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)]))]
- ""
- "set%C1\t%0"
- [(set_attr "type" "setcc")
- (set_attr "mode" "QI")])
-
-;; In general it is not safe to assume too much about CCmode registers,
-;; so simplify-rtx stops when it sees a second one. Under certain
-;; conditions this is safe on x86, so help combine not create
-;;
-;; seta %al
-;; testb %al, %al
-;; sete %al
-
-(define_split
- [(set (match_operand:QI 0 "nonimmediate_operand")
- (ne:QI (match_operator 1 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (const_int 0)))]
- ""
- [(set (match_dup 0) (match_dup 1))]
- "PUT_MODE (operands[1], QImode);")
-
-(define_split
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
- (ne:QI (match_operator 1 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (const_int 0)))]
- ""
- [(set (match_dup 0) (match_dup 1))]
- "PUT_MODE (operands[1], QImode);")
-
-(define_split
- [(set (match_operand:QI 0 "nonimmediate_operand")
- (eq:QI (match_operator 1 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (const_int 0)))]
- ""
- [(set (match_dup 0) (match_dup 1))]
-{
- rtx new_op1 = copy_rtx (operands[1]);
- operands[1] = new_op1;
- PUT_MODE (new_op1, QImode);
- PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
- GET_MODE (XEXP (new_op1, 0))));
-
- /* Make sure that (a) the CCmode we have for the flags is strong
- enough for the reversed compare or (b) we have a valid FP compare. */
- if (! ix86_comparison_operator (new_op1, VOIDmode))
- FAIL;
-})
-
-(define_split
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
- (eq:QI (match_operator 1 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (const_int 0)))]
- ""
- [(set (match_dup 0) (match_dup 1))]
-{
- rtx new_op1 = copy_rtx (operands[1]);
- operands[1] = new_op1;
- PUT_MODE (new_op1, QImode);
- PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
- GET_MODE (XEXP (new_op1, 0))));
-
- /* Make sure that (a) the CCmode we have for the flags is strong
- enough for the reversed compare or (b) we have a valid FP compare. */
- if (! ix86_comparison_operator (new_op1, VOIDmode))
- FAIL;
-})
-
-;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
-;; subsequent logical operations are used to imitate conditional moves.
-;; 0xffffffff is NaN, but not in normalized form, so we can't represent
-;; it directly.
-
-(define_insn "setcc_<mode>_sse"
- [(set (match_operand:MODEF 0 "register_operand" "=x,x")
- (match_operator:MODEF 3 "sse_comparison_operator"
- [(match_operand:MODEF 1 "register_operand" "0,x")
- (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
- "SSE_FLOAT_MODE_P (<MODE>mode)"
- "@
- cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
- vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "isa" "noavx,avx")
- (set_attr "type" "ssecmp")
- (set_attr "length_immediate" "1")
- (set_attr "prefix" "orig,vex")
- (set_attr "mode" "<MODE>")])
-
-;; Basic conditional jump instructions.
-;; We ignore the overflow flag for signed branch instructions.
-
-(define_insn "*jcc_1"
- [(set (pc)
- (if_then_else (match_operator 1 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (label_ref (match_operand 0))
- (pc)))]
- ""
- "%+j%C1\t%l0"
- [(set_attr "type" "ibr")
- (set_attr "modrm" "0")
- (set (attr "length")
- (if_then_else (and (ge (minus (match_dup 0) (pc))
- (const_int -126))
- (lt (minus (match_dup 0) (pc))
- (const_int 128)))
- (const_int 2)
- (const_int 6)))])
-
-(define_insn "*jcc_2"
- [(set (pc)
- (if_then_else (match_operator 1 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (pc)
- (label_ref (match_operand 0))))]
- ""
- "%+j%c1\t%l0"
- [(set_attr "type" "ibr")
- (set_attr "modrm" "0")
- (set (attr "length")
- (if_then_else (and (ge (minus (match_dup 0) (pc))
- (const_int -126))
- (lt (minus (match_dup 0) (pc))
- (const_int 128)))
- (const_int 2)
- (const_int 6)))])
-
-;; In general it is not safe to assume too much about CCmode registers,
-;; so simplify-rtx stops when it sees a second one. Under certain
-;; conditions this is safe on x86, so help combine not create
-;;
-;; seta %al
-;; testb %al, %al
-;; je Lfoo
-
-(define_split
- [(set (pc)
- (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (const_int 0))
- (label_ref (match_operand 1))
- (pc)))]
- ""
- [(set (pc)
- (if_then_else (match_dup 0)
- (label_ref (match_dup 1))
- (pc)))]
- "PUT_MODE (operands[0], VOIDmode);")
-
-(define_split
- [(set (pc)
- (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (const_int 0))
- (label_ref (match_operand 1))
- (pc)))]
- ""
- [(set (pc)
- (if_then_else (match_dup 0)
- (label_ref (match_dup 1))
- (pc)))]
-{
- rtx new_op0 = copy_rtx (operands[0]);
- operands[0] = new_op0;
- PUT_MODE (new_op0, VOIDmode);
- PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
- GET_MODE (XEXP (new_op0, 0))));
-
- /* Make sure that (a) the CCmode we have for the flags is strong
- enough for the reversed compare or (b) we have a valid FP compare. */
- if (! ix86_comparison_operator (new_op0, VOIDmode))
- FAIL;
-})
-
-;; zero_extend in SImode is correct also for DImode, since this is what combine
-;; pass generates from shift insn with QImode operand. Actually, the mode
-;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
-;; appropriate modulo of the bit offset value.
-
-(define_insn_and_split "*jcc_bt<mode>"
- [(set (pc)
- (if_then_else (match_operator 0 "bt_comparison_operator"
- [(zero_extract:SWI48
- (match_operand:SWI48 1 "register_operand" "r")
- (const_int 1)
- (zero_extend:SI
- (match_operand:QI 2 "register_operand" "r")))
- (const_int 0)])
- (label_ref (match_operand 3))
- (pc)))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
- "#"
- "&& 1"
- [(set (reg:CCC FLAGS_REG)
- (compare:CCC
- (zero_extract:SWI48
- (match_dup 1)
- (const_int 1)
- (match_dup 2))
- (const_int 0)))
- (set (pc)
- (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
- (label_ref (match_dup 3))
- (pc)))]
-{
- operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
-
- PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
-})
-
-;; Avoid useless masking of bit offset operand. "and" in SImode is correct
-;; also for DImode, this is what combine produces.
-(define_insn_and_split "*jcc_bt<mode>_mask"
- [(set (pc)
- (if_then_else (match_operator 0 "bt_comparison_operator"
- [(zero_extract:SWI48
- (match_operand:SWI48 1 "register_operand" "r")
- (const_int 1)
- (and:SI
- (match_operand:SI 2 "register_operand" "r")
- (match_operand:SI 3 "const_int_operand" "n")))])
- (label_ref (match_operand 4))
- (pc)))
- (clobber (reg:CC FLAGS_REG))]
- "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
- && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
- == GET_MODE_BITSIZE (<MODE>mode)-1"
- "#"
- "&& 1"
- [(set (reg:CCC FLAGS_REG)
- (compare:CCC
- (zero_extract:SWI48
- (match_dup 1)
- (const_int 1)
- (match_dup 2))
- (const_int 0)))
- (set (pc)
- (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
- (label_ref (match_dup 4))
- (pc)))]
-{
- operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
-
- PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
-})
-
-(define_insn_and_split "*jcc_btsi_1"
- [(set (pc)
- (if_then_else (match_operator 0 "bt_comparison_operator"
- [(and:SI
- (lshiftrt:SI
- (match_operand:SI 1 "register_operand" "r")
- (match_operand:QI 2 "register_operand" "r"))
- (const_int 1))
- (const_int 0)])
- (label_ref (match_operand 3))
- (pc)))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
- "#"
- "&& 1"
- [(set (reg:CCC FLAGS_REG)
- (compare:CCC
- (zero_extract:SI
- (match_dup 1)
- (const_int 1)
- (match_dup 2))
- (const_int 0)))
- (set (pc)
- (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
- (label_ref (match_dup 3))
- (pc)))]
-{
- operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
-
- PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
-})
-
-;; avoid useless masking of bit offset operand
-(define_insn_and_split "*jcc_btsi_mask_1"
- [(set (pc)
- (if_then_else
- (match_operator 0 "bt_comparison_operator"
- [(and:SI
- (lshiftrt:SI
- (match_operand:SI 1 "register_operand" "r")
- (subreg:QI
- (and:SI
- (match_operand:SI 2 "register_operand" "r")
- (match_operand:SI 3 "const_int_operand" "n")) 0))
- (const_int 1))
- (const_int 0)])
- (label_ref (match_operand 4))
- (pc)))
- (clobber (reg:CC FLAGS_REG))]
- "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
- && (INTVAL (operands[3]) & 0x1f) == 0x1f"
- "#"
- "&& 1"
- [(set (reg:CCC FLAGS_REG)
- (compare:CCC
- (zero_extract:SI
- (match_dup 1)
- (const_int 1)
- (match_dup 2))
- (const_int 0)))
- (set (pc)
- (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
- (label_ref (match_dup 4))
- (pc)))]
- "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
-
-;; Define combination compare-and-branch fp compare instructions to help
-;; combine.
-
-(define_insn "*jcc<mode>_0_i387"
- [(set (pc)
- (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
- [(match_operand:X87MODEF 1 "register_operand" "f")
- (match_operand:X87MODEF 2 "const0_operand")])
- (label_ref (match_operand 3))
- (pc)))
- (clobber (reg:CCFP FPSR_REG))
- (clobber (reg:CCFP FLAGS_REG))
- (clobber (match_scratch:HI 4 "=a"))]
- "TARGET_80387 && !TARGET_CMOVE"
- "#")
-
-(define_insn "*jcc<mode>_0_r_i387"
- [(set (pc)
- (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
- [(match_operand:X87MODEF 1 "register_operand" "f")
- (match_operand:X87MODEF 2 "const0_operand")])
- (pc)
- (label_ref (match_operand 3))))
- (clobber (reg:CCFP FPSR_REG))
- (clobber (reg:CCFP FLAGS_REG))
- (clobber (match_scratch:HI 4 "=a"))]
- "TARGET_80387 && !TARGET_CMOVE"
- "#")
-
-(define_insn "*jccxf_i387"
- [(set (pc)
- (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
- [(match_operand:XF 1 "register_operand" "f")
- (match_operand:XF 2 "register_operand" "f")])
- (label_ref (match_operand 3))
- (pc)))
- (clobber (reg:CCFP FPSR_REG))
- (clobber (reg:CCFP FLAGS_REG))
- (clobber (match_scratch:HI 4 "=a"))]
- "TARGET_80387 && !TARGET_CMOVE"
- "#")
-
-(define_insn "*jccxf_r_i387"
- [(set (pc)
- (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
- [(match_operand:XF 1 "register_operand" "f")
- (match_operand:XF 2 "register_operand" "f")])
- (pc)
- (label_ref (match_operand 3))))
- (clobber (reg:CCFP FPSR_REG))
- (clobber (reg:CCFP FLAGS_REG))
- (clobber (match_scratch:HI 4 "=a"))]
- "TARGET_80387 && !TARGET_CMOVE"
- "#")
-
-(define_insn "*jcc<mode>_i387"
- [(set (pc)
- (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
- [(match_operand:MODEF 1 "register_operand" "f")
- (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
- (label_ref (match_operand 3))
- (pc)))
- (clobber (reg:CCFP FPSR_REG))
- (clobber (reg:CCFP FLAGS_REG))
- (clobber (match_scratch:HI 4 "=a"))]
- "TARGET_80387 && !TARGET_CMOVE"
- "#")
-
-(define_insn "*jcc<mode>_r_i387"
- [(set (pc)
- (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
- [(match_operand:MODEF 1 "register_operand" "f")
- (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
- (pc)
- (label_ref (match_operand 3))))
- (clobber (reg:CCFP FPSR_REG))
- (clobber (reg:CCFP FLAGS_REG))
- (clobber (match_scratch:HI 4 "=a"))]
- "TARGET_80387 && !TARGET_CMOVE"
- "#")
-
-(define_insn "*jccu<mode>_i387"
- [(set (pc)
- (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
- [(match_operand:X87MODEF 1 "register_operand" "f")
- (match_operand:X87MODEF 2 "register_operand" "f")])
- (label_ref (match_operand 3))
- (pc)))
- (clobber (reg:CCFP FPSR_REG))
- (clobber (reg:CCFP FLAGS_REG))
- (clobber (match_scratch:HI 4 "=a"))]
- "TARGET_80387 && !TARGET_CMOVE"
- "#")
-
-(define_insn "*jccu<mode>_r_i387"
- [(set (pc)
- (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
- [(match_operand:X87MODEF 1 "register_operand" "f")
- (match_operand:X87MODEF 2 "register_operand" "f")])
- (pc)
- (label_ref (match_operand 3))))
- (clobber (reg:CCFP FPSR_REG))
- (clobber (reg:CCFP FLAGS_REG))
- (clobber (match_scratch:HI 4 "=a"))]
- "TARGET_80387 && !TARGET_CMOVE"
- "#")
-
-(define_split
- [(set (pc)
- (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
- [(match_operand:X87MODEF 1 "register_operand")
- (match_operand:X87MODEF 2 "nonimmediate_operand")])
- (match_operand 3)
- (match_operand 4)))
- (clobber (reg:CCFP FPSR_REG))
- (clobber (reg:CCFP FLAGS_REG))]
- "TARGET_80387 && !TARGET_CMOVE
- && reload_completed"
- [(const_int 0)]
-{
- ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
- operands[3], operands[4], NULL_RTX, NULL_RTX);
- DONE;
-})
-
-(define_split
- [(set (pc)
- (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
- [(match_operand:X87MODEF 1 "register_operand")
- (match_operand:X87MODEF 2 "general_operand")])
- (match_operand 3)
- (match_operand 4)))
- (clobber (reg:CCFP FPSR_REG))
- (clobber (reg:CCFP FLAGS_REG))
- (clobber (match_scratch:HI 5))]
- "TARGET_80387 && !TARGET_CMOVE
- && reload_completed"
- [(const_int 0)]
-{
- ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
- operands[3], operands[4], operands[5], NULL_RTX);
- DONE;
-})
-
-;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
-;; simplify_comparison () function. Float operator is treated as RTX_OBJ
-;; with a precedence over other operators and is always put in the first
-;; place. Swap condition and operands to match ficom instruction.
-
-(define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
- [(set (pc)
- (if_then_else
- (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
- [(match_operator:X87MODEF 1 "float_operator"
- [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
- (match_operand:X87MODEF 3 "register_operand" "f,f")])
- (label_ref (match_operand 4))
- (pc)))
- (clobber (reg:CCFP FPSR_REG))
- (clobber (reg:CCFP FLAGS_REG))
- (clobber (match_scratch:HI 5 "=a,a"))]
- "TARGET_80387 && !TARGET_CMOVE
- && (TARGET_USE_<SWI24:MODE>MODE_FIOP
- || optimize_function_for_size_p (cfun))"
- "#")
-
-(define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
- [(set (pc)
- (if_then_else
- (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
- [(match_operator:X87MODEF 1 "float_operator"
- [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
- (match_operand:X87MODEF 3 "register_operand" "f,f")])
- (pc)
- (label_ref (match_operand 4))))
- (clobber (reg:CCFP FPSR_REG))
- (clobber (reg:CCFP FLAGS_REG))
- (clobber (match_scratch:HI 5 "=a,a"))]
- "TARGET_80387 && !TARGET_CMOVE
- && (TARGET_USE_<SWI24:MODE>MODE_FIOP
- || optimize_function_for_size_p (cfun))"
- "#")
-
-(define_split
- [(set (pc)
- (if_then_else
- (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
- [(match_operator:X87MODEF 1 "float_operator"
- [(match_operand:SWI24 2 "memory_operand")])
- (match_operand:X87MODEF 3 "register_operand")])
- (match_operand 4)
- (match_operand 5)))
- (clobber (reg:CCFP FPSR_REG))
- (clobber (reg:CCFP FLAGS_REG))
- (clobber (match_scratch:HI 6))]
- "TARGET_80387 && !TARGET_CMOVE
- && reload_completed"
- [(const_int 0)]
-{
- ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
- gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
- operands[4], operands[5], operands[6], NULL_RTX);
- DONE;
-})
-
-;; %%% Kill this when reload knows how to do it.
-(define_split
- [(set (pc)
- (if_then_else
- (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
- [(match_operator:X87MODEF 1 "float_operator"
- [(match_operand:SWI24 2 "register_operand")])
- (match_operand:X87MODEF 3 "register_operand")])
- (match_operand 4)
- (match_operand 5)))
- (clobber (reg:CCFP FPSR_REG))
- (clobber (reg:CCFP FLAGS_REG))
- (clobber (match_scratch:HI 6))]
- "TARGET_80387 && !TARGET_CMOVE
- && reload_completed"
- [(const_int 0)]
-{
- operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
-
- ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
- gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]),
- operands[4], operands[5], operands[6], operands[2]);
- DONE;
-})
-
-;; Unconditional and other jump instructions
-
-(define_insn "jump"
- [(set (pc)
- (label_ref (match_operand 0)))]
- ""
- "jmp\t%l0"
- [(set_attr "type" "ibr")
- (set (attr "length")
- (if_then_else (and (ge (minus (match_dup 0) (pc))
- (const_int -126))
- (lt (minus (match_dup 0) (pc))
- (const_int 128)))
- (const_int 2)
- (const_int 5)))
- (set_attr "modrm" "0")])
-
-(define_expand "indirect_jump"
- [(set (pc) (match_operand 0 "indirect_branch_operand"))]
- ""
-{
- if (TARGET_X32)
- operands[0] = convert_memory_address (word_mode, operands[0]);
-})
-
-(define_insn "*indirect_jump"
- [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
- ""
- "jmp\t%A0"
- [(set_attr "type" "ibr")
- (set_attr "length_immediate" "0")])
-
-(define_expand "tablejump"
- [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
- (use (label_ref (match_operand 1)))])]
- ""
-{
- /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
- relative. Convert the relative address to an absolute address. */
- if (flag_pic)
- {
- rtx op0, op1;
- enum rtx_code code;
-
- /* We can't use @GOTOFF for text labels on VxWorks;
- see gotoff_operand. */
- if (TARGET_64BIT || TARGET_VXWORKS_RTP)
- {
- code = PLUS;
- op0 = operands[0];
- op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
- }
- else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
- {
- code = PLUS;
- op0 = operands[0];
- op1 = pic_offset_table_rtx;
- }
- else
- {
- code = MINUS;
- op0 = pic_offset_table_rtx;
- op1 = operands[0];
- }
-
- operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
- OPTAB_DIRECT);
- }
-
- if (TARGET_X32)
- operands[0] = convert_memory_address (word_mode, operands[0]);
-})
-
-(define_insn "*tablejump_1"
- [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
- (use (label_ref (match_operand 1)))]
- ""
- "jmp\t%A0"
- [(set_attr "type" "ibr")
- (set_attr "length_immediate" "0")])
-
-;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
-
-(define_peephole2
- [(set (reg FLAGS_REG) (match_operand 0))
- (set (match_operand:QI 1 "register_operand")
- (match_operator:QI 2 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)]))
- (set (match_operand 3 "q_regs_operand")
- (zero_extend (match_dup 1)))]
- "(peep2_reg_dead_p (3, operands[1])
- || operands_match_p (operands[1], operands[3]))
- && ! reg_overlap_mentioned_p (operands[3], operands[0])"
- [(set (match_dup 4) (match_dup 0))
- (set (strict_low_part (match_dup 5))
- (match_dup 2))]
-{
- operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
- operands[5] = gen_lowpart (QImode, operands[3]);
- ix86_expand_clear (operands[3]);
-})
-
-(define_peephole2
- [(parallel [(set (reg FLAGS_REG) (match_operand 0))
- (match_operand 4)])
- (set (match_operand:QI 1 "register_operand")
- (match_operator:QI 2 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)]))
- (set (match_operand 3 "q_regs_operand")
- (zero_extend (match_dup 1)))]
- "(peep2_reg_dead_p (3, operands[1])
- || operands_match_p (operands[1], operands[3]))
- && ! reg_overlap_mentioned_p (operands[3], operands[0])"
- [(parallel [(set (match_dup 5) (match_dup 0))
- (match_dup 4)])
- (set (strict_low_part (match_dup 6))
- (match_dup 2))]
-{
- operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
- operands[6] = gen_lowpart (QImode, operands[3]);
- ix86_expand_clear (operands[3]);
-})
-
-;; Similar, but match zero extend with andsi3.
-
-(define_peephole2
- [(set (reg FLAGS_REG) (match_operand 0))
- (set (match_operand:QI 1 "register_operand")
- (match_operator:QI 2 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)]))
- (parallel [(set (match_operand:SI 3 "q_regs_operand")
- (and:SI (match_dup 3) (const_int 255)))
- (clobber (reg:CC FLAGS_REG))])]
- "REGNO (operands[1]) == REGNO (operands[3])
- && ! reg_overlap_mentioned_p (operands[3], operands[0])"
- [(set (match_dup 4) (match_dup 0))
- (set (strict_low_part (match_dup 5))
- (match_dup 2))]
-{
- operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
- operands[5] = gen_lowpart (QImode, operands[3]);
- ix86_expand_clear (operands[3]);
-})
-
-(define_peephole2
- [(parallel [(set (reg FLAGS_REG) (match_operand 0))
- (match_operand 4)])
- (set (match_operand:QI 1 "register_operand")
- (match_operator:QI 2 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)]))
- (parallel [(set (match_operand 3 "q_regs_operand")
- (zero_extend (match_dup 1)))
- (clobber (reg:CC FLAGS_REG))])]
- "(peep2_reg_dead_p (3, operands[1])
- || operands_match_p (operands[1], operands[3]))
- && ! reg_overlap_mentioned_p (operands[3], operands[0])"
- [(parallel [(set (match_dup 5) (match_dup 0))
- (match_dup 4)])
- (set (strict_low_part (match_dup 6))
- (match_dup 2))]
-{
- operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
- operands[6] = gen_lowpart (QImode, operands[3]);
- ix86_expand_clear (operands[3]);
-})
-
-;; Call instructions.
-
-;; The predicates normally associated with named expanders are not properly
-;; checked for calls. This is a bug in the generic code, but it isn't that
-;; easy to fix. Ignore it for now and be prepared to fix things up.
-
-;; P6 processors will jump to the address after the decrement when %esp
-;; is used as a call operand, so they will execute return address as a code.
-;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
-
-;; Register constraint for call instruction.
-(define_mode_attr c [(SI "l") (DI "r")])
-
-;; Call subroutine returning no value.
-
-(define_expand "call"
- [(call (match_operand:QI 0)
- (match_operand 1))
- (use (match_operand 2))]
- ""
-{
- ix86_expand_call (NULL, operands[0], operands[1],
- operands[2], NULL, false);
- DONE;
-})
-
-(define_expand "sibcall"
- [(call (match_operand:QI 0)
- (match_operand 1))
- (use (match_operand 2))]
- ""
-{
- ix86_expand_call (NULL, operands[0], operands[1],
- operands[2], NULL, true);
- DONE;
-})
-
-(define_insn "*call"
- [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
- (match_operand 1))]
- "!SIBLING_CALL_P (insn)"
- "* return ix86_output_call_insn (insn, operands[0]);"
- [(set_attr "type" "call")])
-
-(define_insn "*call_rex64_ms_sysv"
- [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
- (match_operand 1))
- (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
- (clobber (reg:TI XMM6_REG))
- (clobber (reg:TI XMM7_REG))
- (clobber (reg:TI XMM8_REG))
- (clobber (reg:TI XMM9_REG))
- (clobber (reg:TI XMM10_REG))
- (clobber (reg:TI XMM11_REG))
- (clobber (reg:TI XMM12_REG))
- (clobber (reg:TI XMM13_REG))
- (clobber (reg:TI XMM14_REG))
- (clobber (reg:TI XMM15_REG))
- (clobber (reg:DI SI_REG))
- (clobber (reg:DI DI_REG))]
- "TARGET_64BIT && !SIBLING_CALL_P (insn)"
- "* return ix86_output_call_insn (insn, operands[0]);"
- [(set_attr "type" "call")])
-
-(define_insn "*sibcall"
- [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
- (match_operand 1))]
- "SIBLING_CALL_P (insn)"
- "* return ix86_output_call_insn (insn, operands[0]);"
- [(set_attr "type" "call")])
-
-(define_expand "call_pop"
- [(parallel [(call (match_operand:QI 0)
- (match_operand:SI 1))
- (set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG)
- (match_operand:SI 3)))])]
- "!TARGET_64BIT"
-{
- ix86_expand_call (NULL, operands[0], operands[1],
- operands[2], operands[3], false);
- DONE;
-})
-
-(define_insn "*call_pop"
- [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
- (match_operand 1))
- (set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG)
- (match_operand:SI 2 "immediate_operand" "i")))]
- "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
- "* return ix86_output_call_insn (insn, operands[0]);"
- [(set_attr "type" "call")])
-
-(define_insn "*sibcall_pop"
- [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
- (match_operand 1))
- (set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG)
- (match_operand:SI 2 "immediate_operand" "i")))]
- "!TARGET_64BIT && SIBLING_CALL_P (insn)"
- "* return ix86_output_call_insn (insn, operands[0]);"
- [(set_attr "type" "call")])
-
-;; Call subroutine, returning value in operand 0
-
-(define_expand "call_value"
- [(set (match_operand 0)
- (call (match_operand:QI 1)
- (match_operand 2)))
- (use (match_operand 3))]
- ""
-{
- ix86_expand_call (operands[0], operands[1], operands[2],
- operands[3], NULL, false);
- DONE;
-})
-
-(define_expand "sibcall_value"
- [(set (match_operand 0)
- (call (match_operand:QI 1)
- (match_operand 2)))
- (use (match_operand 3))]
- ""
-{
- ix86_expand_call (operands[0], operands[1], operands[2],
- operands[3], NULL, true);
- DONE;
-})
-
-(define_insn "*call_value"
- [(set (match_operand 0)
- (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
- (match_operand 2)))]
- "!SIBLING_CALL_P (insn)"
- "* return ix86_output_call_insn (insn, operands[1]);"
- [(set_attr "type" "callv")])
-
-(define_insn "*sibcall_value"
- [(set (match_operand 0)
- (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
- (match_operand 2)))]
- "SIBLING_CALL_P (insn)"
- "* return ix86_output_call_insn (insn, operands[1]);"
- [(set_attr "type" "callv")])
-
-(define_insn "*call_value_rex64_ms_sysv"
- [(set (match_operand 0)
- (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
- (match_operand 2)))
- (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
- (clobber (reg:TI XMM6_REG))
- (clobber (reg:TI XMM7_REG))
- (clobber (reg:TI XMM8_REG))
- (clobber (reg:TI XMM9_REG))
- (clobber (reg:TI XMM10_REG))
- (clobber (reg:TI XMM11_REG))
- (clobber (reg:TI XMM12_REG))
- (clobber (reg:TI XMM13_REG))
- (clobber (reg:TI XMM14_REG))
- (clobber (reg:TI XMM15_REG))
- (clobber (reg:DI SI_REG))
- (clobber (reg:DI DI_REG))]
- "TARGET_64BIT && !SIBLING_CALL_P (insn)"
- "* return ix86_output_call_insn (insn, operands[1]);"
- [(set_attr "type" "callv")])
-
-(define_expand "call_value_pop"
- [(parallel [(set (match_operand 0)
- (call (match_operand:QI 1)
- (match_operand:SI 2)))
- (set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG)
- (match_operand:SI 4)))])]
- "!TARGET_64BIT"
-{
- ix86_expand_call (operands[0], operands[1], operands[2],
- operands[3], operands[4], false);
- DONE;
-})
-
-(define_insn "*call_value_pop"
- [(set (match_operand 0)
- (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
- (match_operand 2)))
- (set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG)
- (match_operand:SI 3 "immediate_operand" "i")))]
- "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
- "* return ix86_output_call_insn (insn, operands[1]);"
- [(set_attr "type" "callv")])
-
-(define_insn "*sibcall_value_pop"
- [(set (match_operand 0)
- (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
- (match_operand 2)))
- (set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG)
- (match_operand:SI 3 "immediate_operand" "i")))]
- "!TARGET_64BIT && SIBLING_CALL_P (insn)"
- "* return ix86_output_call_insn (insn, operands[1]);"
- [(set_attr "type" "callv")])
-
-;; Call subroutine returning any type.
-
-(define_expand "untyped_call"
- [(parallel [(call (match_operand 0)
- (const_int 0))
- (match_operand 1)
- (match_operand 2)])]
- ""
-{
- int i;
-
- /* In order to give reg-stack an easier job in validating two
- coprocessor registers as containing a possible return value,
- simply pretend the untyped call returns a complex long double
- value.
-
- We can't use SSE_REGPARM_MAX here since callee is unprototyped
- and should have the default ABI. */
-
- ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
- ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
- operands[0], const0_rtx,
- GEN_INT ((TARGET_64BIT
- ? (ix86_abi == SYSV_ABI
- ? X86_64_SSE_REGPARM_MAX
- : X86_64_MS_SSE_REGPARM_MAX)
- : X86_32_SSE_REGPARM_MAX)
- - 1),
- NULL, false);
-
- 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;
-})
-
-;; Prologue and epilogue instructions
-
-;; 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)] UNSPECV_BLOCKAGE)]
- ""
- ""
- [(set_attr "length" "0")])
-
-;; Do not schedule instructions accessing memory across this point.
-
-(define_expand "memory_blockage"
- [(set (match_dup 0)
- (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
- ""
-{
- operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
- MEM_VOLATILE_P (operands[0]) = 1;
-})
-
-(define_insn "*memory_blockage"
- [(set (match_operand:BLK 0)
- (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
- ""
- ""
- [(set_attr "length" "0")])
-
-;; As USE insns aren't meaningful after reload, this is used instead
-;; to prevent deleting instructions setting registers for PIC code
-(define_insn "prologue_use"
- [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
- ""
- ""
- [(set_attr "length" "0")])
-
-;; Insn emitted into the body of a function to return from a function.
-;; This is only done if the function's epilogue is known to be simple.
-;; See comments for ix86_can_use_return_insn_p in i386.c.
-
-(define_expand "return"
- [(simple_return)]
- "ix86_can_use_return_insn_p ()"
-{
- if (crtl->args.pops_args)
- {
- rtx popc = GEN_INT (crtl->args.pops_args);
- emit_jump_insn (gen_simple_return_pop_internal (popc));
- DONE;
- }
-})
-
-;; We need to disable this for TARGET_SEH, as otherwise
-;; shrink-wrapped prologue gets enabled too. This might exceed
-;; the maximum size of prologue in unwind information.
-
-(define_expand "simple_return"
- [(simple_return)]
- "!TARGET_SEH"
-{
- if (crtl->args.pops_args)
- {
- rtx popc = GEN_INT (crtl->args.pops_args);
- emit_jump_insn (gen_simple_return_pop_internal (popc));
- DONE;
- }
-})
-
-(define_insn "simple_return_internal"
- [(simple_return)]
- "reload_completed"
- "ret"
- [(set_attr "length" "1")
- (set_attr "atom_unit" "jeu")
- (set_attr "length_immediate" "0")
- (set_attr "modrm" "0")])
-
-;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
-;; instruction Athlon and K8 have.
-
-(define_insn "simple_return_internal_long"
- [(simple_return)
- (unspec [(const_int 0)] UNSPEC_REP)]
- "reload_completed"
- "rep%; ret"
- [(set_attr "length" "2")
- (set_attr "atom_unit" "jeu")
- (set_attr "length_immediate" "0")
- (set_attr "prefix_rep" "1")
- (set_attr "modrm" "0")])
-
-(define_insn "simple_return_pop_internal"
- [(simple_return)
- (use (match_operand:SI 0 "const_int_operand"))]
- "reload_completed"
- "ret\t%0"
- [(set_attr "length" "3")
- (set_attr "atom_unit" "jeu")
- (set_attr "length_immediate" "2")
- (set_attr "modrm" "0")])
-
-(define_insn "simple_return_indirect_internal"
- [(simple_return)
- (use (match_operand:SI 0 "register_operand" "r"))]
- "reload_completed"
- "jmp\t%A0"
- [(set_attr "type" "ibr")
- (set_attr "length_immediate" "0")])
-
-(define_insn "nop"
- [(const_int 0)]
- ""
- "nop"
- [(set_attr "length" "1")
- (set_attr "length_immediate" "0")
- (set_attr "modrm" "0")])
-
-;; Generate nops. Operand 0 is the number of nops, up to 8.
-(define_insn "nops"
- [(unspec_volatile [(match_operand 0 "const_int_operand")]
- UNSPECV_NOPS)]
- "reload_completed"
-{
- int num = INTVAL (operands[0]);
-
- gcc_assert (IN_RANGE (num, 1, 8));
-
- while (num--)
- fputs ("\tnop\n", asm_out_file);
-
- return "";
-}
- [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
- (set_attr "length_immediate" "0")
- (set_attr "modrm" "0")])
-
-;; Pad to 16-byte boundary, max skip in op0. Used to avoid
-;; branch prediction penalty for the third jump in a 16-byte
-;; block on K8.
-
-(define_insn "pad"
- [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
- ""
-{
-#ifdef ASM_OUTPUT_MAX_SKIP_PAD
- ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
-#else
- /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
- The align insn is used to avoid 3 jump instructions in the row to improve
- branch prediction and the benefits hardly outweigh the cost of extra 8
- nops on the average inserted by full alignment pseudo operation. */
-#endif
- return "";
-}
- [(set_attr "length" "16")])
-
-(define_expand "prologue"
- [(const_int 0)]
- ""
- "ix86_expand_prologue (); DONE;")
-
-(define_insn "set_got"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_64BIT"
- "* return output_set_got (operands[0], NULL_RTX);"
- [(set_attr "type" "multi")
- (set_attr "length" "12")])
-
-(define_insn "set_got_labelled"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (unspec:SI [(label_ref (match_operand 1))]
- UNSPEC_SET_GOT))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_64BIT"
- "* return output_set_got (operands[0], operands[1]);"
- [(set_attr "type" "multi")
- (set_attr "length" "12")])
-
-(define_insn "set_got_rex64"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
- "TARGET_64BIT"
- "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
- [(set_attr "type" "lea")
- (set_attr "length_address" "4")
- (set_attr "mode" "DI")])
-
-(define_insn "set_rip_rex64"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
- "TARGET_64BIT"
- "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
- [(set_attr "type" "lea")
- (set_attr "length_address" "4")
- (set_attr "mode" "DI")])
-
-(define_insn "set_got_offset_rex64"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (unspec:DI
- [(label_ref (match_operand 1))]
- UNSPEC_SET_GOT_OFFSET))]
- "TARGET_LP64"
- "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
- [(set_attr "type" "imov")
- (set_attr "length_immediate" "0")
- (set_attr "length_address" "8")
- (set_attr "mode" "DI")])
-
-(define_expand "epilogue"
- [(const_int 0)]
- ""
- "ix86_expand_epilogue (1); DONE;")
-
-(define_expand "sibcall_epilogue"
- [(const_int 0)]
- ""
- "ix86_expand_epilogue (0); DONE;")
-
-(define_expand "eh_return"
- [(use (match_operand 0 "register_operand"))]
- ""
-{
- rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
-
- /* Tricky bit: we write the address of the handler to which we will
- be returning into someone else's stack frame, one word below the
- stack address we wish to restore. */
- tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
- tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
- tmp = gen_rtx_MEM (Pmode, tmp);
- emit_move_insn (tmp, ra);
-
- emit_jump_insn (gen_eh_return_internal ());
- emit_barrier ();
- DONE;
-})
-
-(define_insn_and_split "eh_return_internal"
- [(eh_return)]
- ""
- "#"
- "epilogue_completed"
- [(const_int 0)]
- "ix86_expand_epilogue (2); DONE;")
-
-(define_insn "leave"
- [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
- (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
- (clobber (mem:BLK (scratch)))]
- "!TARGET_64BIT"
- "leave"
- [(set_attr "type" "leave")])
-
-(define_insn "leave_rex64"
- [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
- (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
- (clobber (mem:BLK (scratch)))]
- "TARGET_64BIT"
- "leave"
- [(set_attr "type" "leave")])
-
-;; Handle -fsplit-stack.
-
-(define_expand "split_stack_prologue"
- [(const_int 0)]
- ""
-{
- ix86_expand_split_stack_prologue ();
- DONE;
-})
-
-;; In order to support the call/return predictor, we use a return
-;; instruction which the middle-end doesn't see.
-(define_insn "split_stack_return"
- [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
- UNSPECV_SPLIT_STACK_RETURN)]
- ""
-{
- if (operands[0] == const0_rtx)
- return "ret";
- else
- return "ret\t%0";
-}
- [(set_attr "atom_unit" "jeu")
- (set_attr "modrm" "0")
- (set (attr "length")
- (if_then_else (match_operand:SI 0 "const0_operand")
- (const_int 1)
- (const_int 3)))
- (set (attr "length_immediate")
- (if_then_else (match_operand:SI 0 "const0_operand")
- (const_int 0)
- (const_int 2)))])
-
-;; If there are operand 0 bytes available on the stack, jump to
-;; operand 1.
-
-(define_expand "split_stack_space_check"
- [(set (pc) (if_then_else
- (ltu (minus (reg SP_REG)
- (match_operand 0 "register_operand"))
- (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
- (label_ref (match_operand 1))
- (pc)))]
- ""
-{
- rtx reg, size, limit;
-
- reg = gen_reg_rtx (Pmode);
- size = force_reg (Pmode, operands[0]);
- emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
- limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
- UNSPEC_STACK_CHECK);
- limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
- ix86_expand_branch (GEU, reg, limit, operands[1]);
-
- DONE;
-})
-
-;; Bit manipulation instructions.
-
-(define_expand "ffs<mode>2"
- [(set (match_dup 2) (const_int -1))
- (parallel [(set (match_dup 3) (match_dup 4))
- (set (match_operand:SWI48 0 "register_operand")
- (ctz:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand")))])
- (set (match_dup 0) (if_then_else:SWI48
- (eq (match_dup 3) (const_int 0))
- (match_dup 2)
- (match_dup 0)))
- (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
- (clobber (reg:CC FLAGS_REG))])]
- ""
-{
- enum machine_mode flags_mode;
-
- if (<MODE>mode == SImode && !TARGET_CMOVE)
- {
- emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
- DONE;
- }
-
- flags_mode = TARGET_BMI ? CCCmode : CCZmode;
-
- operands[2] = gen_reg_rtx (<MODE>mode);
- operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
- operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
-})
-
-(define_insn_and_split "ffssi2_no_cmove"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
- (clobber (match_scratch:SI 2 "=&q"))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_CMOVE"
- "#"
- "&& reload_completed"
- [(parallel [(set (match_dup 4) (match_dup 5))
- (set (match_dup 0) (ctz:SI (match_dup 1)))])
- (set (strict_low_part (match_dup 3))
- (eq:QI (match_dup 4) (const_int 0)))
- (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
- (clobber (reg:CC FLAGS_REG))])
- (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
- (clobber (reg:CC FLAGS_REG))])
- (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
- (clobber (reg:CC FLAGS_REG))])]
-{
- enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
-
- operands[3] = gen_lowpart (QImode, operands[2]);
- operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
- operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
-
- ix86_expand_clear (operands[2]);
-})
-
-(define_insn "*tzcnt<mode>_1"
- [(set (reg:CCC FLAGS_REG)
- (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
- (const_int 0)))
- (set (match_operand:SWI48 0 "register_operand" "=r")
- (ctz:SWI48 (match_dup 1)))]
- "TARGET_BMI"
- "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "prefix_0f" "1")
- (set_attr "prefix_rep" "1")
- (set_attr "btver2_decode" "double")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*bsf<mode>_1"
- [(set (reg:CCZ FLAGS_REG)
- (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
- (const_int 0)))
- (set (match_operand:SWI48 0 "register_operand" "=r")
- (ctz:SWI48 (match_dup 1)))]
- ""
- "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "prefix_0f" "1")
- (set_attr "btver2_decode" "double")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "ctz<mode>2"
- [(set (match_operand:SWI248 0 "register_operand" "=r")
- (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
- (clobber (reg:CC FLAGS_REG))]
- ""
-{
- if (TARGET_BMI)
- return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
- else if (optimize_function_for_size_p (cfun))
- ;
- else if (TARGET_GENERIC)
- /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
- return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
-
- return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
-}
- [(set_attr "type" "alu1")
- (set_attr "prefix_0f" "1")
- (set (attr "prefix_rep")
- (if_then_else
- (ior (match_test "TARGET_BMI")
- (and (not (match_test "optimize_function_for_size_p (cfun)"))
- (match_test "TARGET_GENERIC")))
- (const_string "1")
- (const_string "0")))
- (set_attr "mode" "<MODE>")])
-
-(define_expand "clz<mode>2"
- [(parallel
- [(set (match_operand:SWI248 0 "register_operand")
- (minus:SWI248
- (match_dup 2)
- (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
- (clobber (reg:CC FLAGS_REG))])
- (parallel
- [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
- (clobber (reg:CC FLAGS_REG))])]
- ""
-{
- if (TARGET_LZCNT)
- {
- emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
- DONE;
- }
- operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
-})
-
-(define_insn "clz<mode>2_lzcnt"
- [(set (match_operand:SWI248 0 "register_operand" "=r")
- (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_LZCNT"
- "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
- [(set_attr "prefix_rep" "1")
- (set_attr "type" "bitmanip")
- (set_attr "mode" "<MODE>")])
-
-;; BMI instructions.
-(define_insn "*bmi_andn_<mode>"
- [(set (match_operand:SWI48 0 "register_operand" "=r,r")
- (and:SWI48
- (not:SWI48
- (match_operand:SWI48 1 "register_operand" "r,r"))
- (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_BMI"
- "andn\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "type" "bitmanip")
- (set_attr "btver2_decode" "direct, double")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "bmi_bextr_<mode>"
- [(set (match_operand:SWI48 0 "register_operand" "=r,r")
- (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r,r")
- (match_operand:SWI48 2 "nonimmediate_operand" "r,m")]
- UNSPEC_BEXTR))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_BMI"
- "bextr\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "type" "bitmanip")
- (set_attr "btver2_decode" "direct, double")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*bmi_blsi_<mode>"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (and:SWI48
- (neg:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
- (match_dup 1)))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_BMI"
- "blsi\t{%1, %0|%0, %1}"
- [(set_attr "type" "bitmanip")
- (set_attr "btver2_decode" "double")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*bmi_blsmsk_<mode>"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (xor:SWI48
- (plus:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "rm")
- (const_int -1))
- (match_dup 1)))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_BMI"
- "blsmsk\t{%1, %0|%0, %1}"
- [(set_attr "type" "bitmanip")
- (set_attr "btver2_decode" "double")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*bmi_blsr_<mode>"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (and:SWI48
- (plus:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "rm")
- (const_int -1))
- (match_dup 1)))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_BMI"
- "blsr\t{%1, %0|%0, %1}"
- [(set_attr "type" "bitmanip")
- (set_attr "btver2_decode" "double")
- (set_attr "mode" "<MODE>")])
-
-;; BMI2 instructions.
-(define_insn "bmi2_bzhi_<mode>3"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
- (lshiftrt:SWI48 (const_int -1)
- (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_BMI2"
- "bzhi\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "type" "bitmanip")
- (set_attr "prefix" "vex")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "bmi2_pdep_<mode>3"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
- (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
- UNSPEC_PDEP))]
- "TARGET_BMI2"
- "pdep\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "type" "bitmanip")
- (set_attr "prefix" "vex")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "bmi2_pext_<mode>3"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
- (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
- UNSPEC_PEXT))]
- "TARGET_BMI2"
- "pext\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "type" "bitmanip")
- (set_attr "prefix" "vex")
- (set_attr "mode" "<MODE>")])
-
-;; TBM instructions.
-(define_insn "tbm_bextri_<mode>"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (zero_extract:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "rm")
- (match_operand:SWI48 2 "const_0_to_255_operand" "n")
- (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_TBM"
-{
- operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
- return "bextr\t{%2, %1, %0|%0, %1, %2}";
-}
- [(set_attr "type" "bitmanip")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*tbm_blcfill_<mode>"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (and:SWI48
- (plus:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "rm")
- (const_int 1))
- (match_dup 1)))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_TBM"
- "blcfill\t{%1, %0|%0, %1}"
- [(set_attr "type" "bitmanip")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*tbm_blci_<mode>"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (ior:SWI48
- (not:SWI48
- (plus:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "rm")
- (const_int 1)))
- (match_dup 1)))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_TBM"
- "blci\t{%1, %0|%0, %1}"
- [(set_attr "type" "bitmanip")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*tbm_blcic_<mode>"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (and:SWI48
- (plus:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "rm")
- (const_int 1))
- (not:SWI48
- (match_dup 1))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_TBM"
- "blcic\t{%1, %0|%0, %1}"
- [(set_attr "type" "bitmanip")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*tbm_blcmsk_<mode>"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (xor:SWI48
- (plus:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "rm")
- (const_int 1))
- (match_dup 1)))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_TBM"
- "blcmsk\t{%1, %0|%0, %1}"
- [(set_attr "type" "bitmanip")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*tbm_blcs_<mode>"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (ior:SWI48
- (plus:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "rm")
- (const_int 1))
- (match_dup 1)))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_TBM"
- "blcs\t{%1, %0|%0, %1}"
- [(set_attr "type" "bitmanip")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*tbm_blsfill_<mode>"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (ior:SWI48
- (plus:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "rm")
- (const_int -1))
- (match_dup 1)))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_TBM"
- "blsfill\t{%1, %0|%0, %1}"
- [(set_attr "type" "bitmanip")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*tbm_blsic_<mode>"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (ior:SWI48
- (plus:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "rm")
- (const_int -1))
- (not:SWI48
- (match_dup 1))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_TBM"
- "blsic\t{%1, %0|%0, %1}"
- [(set_attr "type" "bitmanip")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*tbm_t1mskc_<mode>"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (ior:SWI48
- (plus:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "rm")
- (const_int 1))
- (not:SWI48
- (match_dup 1))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_TBM"
- "t1mskc\t{%1, %0|%0, %1}"
- [(set_attr "type" "bitmanip")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*tbm_tzmsk_<mode>"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (and:SWI48
- (plus:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "rm")
- (const_int -1))
- (not:SWI48
- (match_dup 1))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_TBM"
- "tzmsk\t{%1, %0|%0, %1}"
- [(set_attr "type" "bitmanip")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "bsr_rex64"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (minus:DI (const_int 63)
- (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT"
- "bsr{q}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "prefix_0f" "1")
- (set_attr "mode" "DI")])
-
-(define_insn "bsr"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (const_int 31)
- (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "bsr{l}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "prefix_0f" "1")
- (set_attr "mode" "SI")])
-
-(define_insn "*bsrhi"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (minus:HI (const_int 15)
- (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "bsr{w}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "prefix_0f" "1")
- (set_attr "mode" "HI")])
-
-(define_insn "popcount<mode>2"
- [(set (match_operand:SWI248 0 "register_operand" "=r")
- (popcount:SWI248
- (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_POPCNT"
-{
-#if TARGET_MACHO
- return "popcnt\t{%1, %0|%0, %1}";
-#else
- return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
-#endif
-}
- [(set_attr "prefix_rep" "1")
- (set_attr "type" "bitmanip")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*popcount<mode>2_cmp"
- [(set (reg FLAGS_REG)
- (compare
- (popcount:SWI248
- (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
- (const_int 0)))
- (set (match_operand:SWI248 0 "register_operand" "=r")
- (popcount:SWI248 (match_dup 1)))]
- "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
-{
-#if TARGET_MACHO
- return "popcnt\t{%1, %0|%0, %1}";
-#else
- return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
-#endif
-}
- [(set_attr "prefix_rep" "1")
- (set_attr "type" "bitmanip")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*popcountsi2_cmp_zext"
- [(set (reg FLAGS_REG)
- (compare
- (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
- (const_int 0)))
- (set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI(popcount:SI (match_dup 1))))]
- "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
-{
-#if TARGET_MACHO
- return "popcnt\t{%1, %0|%0, %1}";
-#else
- return "popcnt{l}\t{%1, %0|%0, %1}";
-#endif
-}
- [(set_attr "prefix_rep" "1")
- (set_attr "type" "bitmanip")
- (set_attr "mode" "SI")])
-
-(define_expand "bswapdi2"
- [(set (match_operand:DI 0 "register_operand")
- (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
- "TARGET_64BIT"
-{
- if (!TARGET_MOVBE)
- operands[1] = force_reg (DImode, operands[1]);
-})
-
-(define_expand "bswapsi2"
- [(set (match_operand:SI 0 "register_operand")
- (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
- ""
-{
- if (TARGET_MOVBE)
- ;
- else if (TARGET_BSWAP)
- operands[1] = force_reg (SImode, operands[1]);
- else
- {
- rtx x = operands[0];
-
- emit_move_insn (x, operands[1]);
- emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
- emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
- emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
- DONE;
- }
-})
-
-(define_insn "*bswap<mode>2_movbe"
- [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
- (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
- "TARGET_MOVBE
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "@
- bswap\t%0
- movbe\t{%1, %0|%0, %1}
- movbe\t{%1, %0|%0, %1}"
- [(set_attr "type" "bitmanip,imov,imov")
- (set_attr "modrm" "0,1,1")
- (set_attr "prefix_0f" "*,1,1")
- (set_attr "prefix_extra" "*,1,1")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*bswap<mode>2"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
- "TARGET_BSWAP"
- "bswap\t%0"
- [(set_attr "type" "bitmanip")
- (set_attr "modrm" "0")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*bswaphi_lowpart_1"
- [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
- (bswap:HI (match_dup 0)))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
- "@
- xchg{b}\t{%h0, %b0|%b0, %h0}
- rol{w}\t{$8, %0|%0, 8}"
- [(set_attr "length" "2,4")
- (set_attr "mode" "QI,HI")])
-
-(define_insn "bswaphi_lowpart"
- [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
- (bswap:HI (match_dup 0)))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "rol{w}\t{$8, %0|%0, 8}"
- [(set_attr "length" "4")
- (set_attr "mode" "HI")])
-
-(define_expand "paritydi2"
- [(set (match_operand:DI 0 "register_operand")
- (parity:DI (match_operand:DI 1 "register_operand")))]
- "! TARGET_POPCNT"
-{
- rtx scratch = gen_reg_rtx (QImode);
- rtx cond;
-
- emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
- NULL_RTX, operands[1]));
-
- cond = gen_rtx_fmt_ee (ORDERED, QImode,
- gen_rtx_REG (CCmode, FLAGS_REG),
- const0_rtx);
- emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
-
- if (TARGET_64BIT)
- emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
- else
- {
- rtx tmp = gen_reg_rtx (SImode);
-
- emit_insn (gen_zero_extendqisi2 (tmp, scratch));
- emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
- }
- DONE;
-})
-
-(define_expand "paritysi2"
- [(set (match_operand:SI 0 "register_operand")
- (parity:SI (match_operand:SI 1 "register_operand")))]
- "! TARGET_POPCNT"
-{
- rtx scratch = gen_reg_rtx (QImode);
- rtx cond;
-
- emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
-
- cond = gen_rtx_fmt_ee (ORDERED, QImode,
- gen_rtx_REG (CCmode, FLAGS_REG),
- const0_rtx);
- emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
-
- emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
- DONE;
-})
-
-(define_insn_and_split "paritydi2_cmp"
- [(set (reg:CC FLAGS_REG)
- (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
- UNSPEC_PARITY))
- (clobber (match_scratch:DI 0 "=r"))
- (clobber (match_scratch:SI 1 "=&r"))
- (clobber (match_scratch:HI 2 "=Q"))]
- "! TARGET_POPCNT"
- "#"
- "&& reload_completed"
- [(parallel
- [(set (match_dup 1)
- (xor:SI (match_dup 1) (match_dup 4)))
- (clobber (reg:CC FLAGS_REG))])
- (parallel
- [(set (reg:CC FLAGS_REG)
- (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
- (clobber (match_dup 1))
- (clobber (match_dup 2))])]
-{
- operands[4] = gen_lowpart (SImode, operands[3]);
-
- if (TARGET_64BIT)
- {
- emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
- emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
- }
- else
- operands[1] = gen_highpart (SImode, operands[3]);
-})
-
-(define_insn_and_split "paritysi2_cmp"
- [(set (reg:CC FLAGS_REG)
- (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
- UNSPEC_PARITY))
- (clobber (match_scratch:SI 0 "=r"))
- (clobber (match_scratch:HI 1 "=&Q"))]
- "! TARGET_POPCNT"
- "#"
- "&& reload_completed"
- [(parallel
- [(set (match_dup 1)
- (xor:HI (match_dup 1) (match_dup 3)))
- (clobber (reg:CC FLAGS_REG))])
- (parallel
- [(set (reg:CC FLAGS_REG)
- (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
- (clobber (match_dup 1))])]
-{
- operands[3] = gen_lowpart (HImode, operands[2]);
-
- emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
- emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
-})
-
-(define_insn "*parityhi2_cmp"
- [(set (reg:CC FLAGS_REG)
- (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
- UNSPEC_PARITY))
- (clobber (match_scratch:HI 0 "=Q"))]
- "! TARGET_POPCNT"
- "xor{b}\t{%h0, %b0|%b0, %h0}"
- [(set_attr "length" "2")
- (set_attr "mode" "HI")])
-
-
-;; Thread-local storage patterns for ELF.
-;;
-;; Note that these code sequences must appear exactly as shown
-;; in order to allow linker relaxation.
-
-(define_insn "*tls_global_dynamic_32_gnu"
- [(set (match_operand:SI 0 "register_operand" "=a")
- (unspec:SI
- [(match_operand:SI 1 "register_operand" "b")
- (match_operand 2 "tls_symbolic_operand")
- (match_operand 3 "constant_call_address_operand" "z")]
- UNSPEC_TLS_GD))
- (clobber (match_scratch:SI 4 "=d"))
- (clobber (match_scratch:SI 5 "=c"))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_64BIT && TARGET_GNU_TLS"
-{
- output_asm_insn
- ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
- if (TARGET_SUN_TLS)
-#ifdef HAVE_AS_IX86_TLSGDPLT
- return "call\t%a2@tlsgdplt";
-#else
- return "call\t%p3@plt";
-#endif
- return "call\t%P3";
-}
- [(set_attr "type" "multi")
- (set_attr "length" "12")])
-
-(define_expand "tls_global_dynamic_32"
- [(parallel
- [(set (match_operand:SI 0 "register_operand")
- (unspec:SI [(match_operand:SI 2 "register_operand")
- (match_operand 1 "tls_symbolic_operand")
- (match_operand 3 "constant_call_address_operand")]
- UNSPEC_TLS_GD))
- (clobber (match_scratch:SI 4))
- (clobber (match_scratch:SI 5))
- (clobber (reg:CC FLAGS_REG))])])
-
-(define_insn "*tls_global_dynamic_64_<mode>"
- [(set (match_operand:P 0 "register_operand" "=a")
- (call:P
- (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
- (match_operand 3)))
- (unspec:P [(match_operand 1 "tls_symbolic_operand")]
- UNSPEC_TLS_GD)]
- "TARGET_64BIT"
-{
- if (!TARGET_X32)
- fputs (ASM_BYTE "0x66\n", asm_out_file);
- output_asm_insn
- ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
- fputs (ASM_SHORT "0x6666\n", asm_out_file);
- fputs ("\trex64\n", asm_out_file);
- if (TARGET_SUN_TLS)
- return "call\t%p2@plt";
- return "call\t%P2";
-}
- [(set_attr "type" "multi")
- (set (attr "length")
- (symbol_ref "TARGET_X32 ? 15 : 16"))])
-
-(define_expand "tls_global_dynamic_64_<mode>"
- [(parallel
- [(set (match_operand:P 0 "register_operand")
- (call:P
- (mem:QI (match_operand 2 "constant_call_address_operand"))
- (const_int 0)))
- (unspec:P [(match_operand 1 "tls_symbolic_operand")]
- UNSPEC_TLS_GD)])]
- "TARGET_64BIT")
-
-(define_insn "*tls_local_dynamic_base_32_gnu"
- [(set (match_operand:SI 0 "register_operand" "=a")
- (unspec:SI
- [(match_operand:SI 1 "register_operand" "b")
- (match_operand 2 "constant_call_address_operand" "z")]
- UNSPEC_TLS_LD_BASE))
- (clobber (match_scratch:SI 3 "=d"))
- (clobber (match_scratch:SI 4 "=c"))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_64BIT && TARGET_GNU_TLS"
-{
- output_asm_insn
- ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
- if (TARGET_SUN_TLS)
-#ifdef HAVE_AS_IX86_TLSLDMPLT
- return "call\t%&@tlsldmplt";
-#else
- return "call\t%p2@plt";
-#endif
- return "call\t%P2";
-}
- [(set_attr "type" "multi")
- (set_attr "length" "11")])
-
-(define_expand "tls_local_dynamic_base_32"
- [(parallel
- [(set (match_operand:SI 0 "register_operand")
- (unspec:SI
- [(match_operand:SI 1 "register_operand")
- (match_operand 2 "constant_call_address_operand")]
- UNSPEC_TLS_LD_BASE))
- (clobber (match_scratch:SI 3))
- (clobber (match_scratch:SI 4))
- (clobber (reg:CC FLAGS_REG))])])
-
-(define_insn "*tls_local_dynamic_base_64_<mode>"
- [(set (match_operand:P 0 "register_operand" "=a")
- (call:P
- (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
- (match_operand 2)))
- (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
- "TARGET_64BIT"
-{
- output_asm_insn
- ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
- if (TARGET_SUN_TLS)
- return "call\t%p1@plt";
- return "call\t%P1";
-}
- [(set_attr "type" "multi")
- (set_attr "length" "12")])
-
-(define_expand "tls_local_dynamic_base_64_<mode>"
- [(parallel
- [(set (match_operand:P 0 "register_operand")
- (call:P
- (mem:QI (match_operand 1 "constant_call_address_operand"))
- (const_int 0)))
- (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
- "TARGET_64BIT")
-
-;; Local dynamic of a single variable is a lose. Show combine how
-;; to convert that back to global dynamic.
-
-(define_insn_and_split "*tls_local_dynamic_32_once"
- [(set (match_operand:SI 0 "register_operand" "=a")
- (plus:SI
- (unspec:SI [(match_operand:SI 1 "register_operand" "b")
- (match_operand 2 "constant_call_address_operand" "z")]
- UNSPEC_TLS_LD_BASE)
- (const:SI (unspec:SI
- [(match_operand 3 "tls_symbolic_operand")]
- UNSPEC_DTPOFF))))
- (clobber (match_scratch:SI 4 "=d"))
- (clobber (match_scratch:SI 5 "=c"))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "#"
- ""
- [(parallel
- [(set (match_dup 0)
- (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
- UNSPEC_TLS_GD))
- (clobber (match_dup 4))
- (clobber (match_dup 5))
- (clobber (reg:CC FLAGS_REG))])])
-
-;; Segment register for the thread base ptr load
-(define_mode_attr tp_seg [(SI "gs") (DI "fs")])
-
-;; Load and add the thread base pointer from %<tp_seg>:0.
-(define_insn "*load_tp_x32"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (unspec:SI [(const_int 0)] UNSPEC_TP))]
- "TARGET_X32"
- "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
- [(set_attr "type" "imov")
- (set_attr "modrm" "0")
- (set_attr "length" "7")
- (set_attr "memory" "load")
- (set_attr "imm_disp" "false")])
-
-(define_insn "*load_tp_x32_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
- "TARGET_X32"
- "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
- [(set_attr "type" "imov")
- (set_attr "modrm" "0")
- (set_attr "length" "7")
- (set_attr "memory" "load")
- (set_attr "imm_disp" "false")])
-
-(define_insn "*load_tp_<mode>"
- [(set (match_operand:P 0 "register_operand" "=r")
- (unspec:P [(const_int 0)] UNSPEC_TP))]
- "!TARGET_X32"
- "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
- [(set_attr "type" "imov")
- (set_attr "modrm" "0")
- (set_attr "length" "7")
- (set_attr "memory" "load")
- (set_attr "imm_disp" "false")])
-
-(define_insn "*add_tp_x32"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
- (match_operand:SI 1 "register_operand" "0")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_X32"
- "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
- [(set_attr "type" "alu")
- (set_attr "modrm" "0")
- (set_attr "length" "7")
- (set_attr "memory" "load")
- (set_attr "imm_disp" "false")])
-
-(define_insn "*add_tp_x32_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
- (match_operand:SI 1 "register_operand" "0"))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_X32"
- "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
- [(set_attr "type" "alu")
- (set_attr "modrm" "0")
- (set_attr "length" "7")
- (set_attr "memory" "load")
- (set_attr "imm_disp" "false")])
-
-(define_insn "*add_tp_<mode>"
- [(set (match_operand:P 0 "register_operand" "=r")
- (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
- (match_operand:P 1 "register_operand" "0")))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_X32"
- "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
- [(set_attr "type" "alu")
- (set_attr "modrm" "0")
- (set_attr "length" "7")
- (set_attr "memory" "load")
- (set_attr "imm_disp" "false")])
-
-;; The Sun linker took the AMD64 TLS spec literally and can only handle
-;; %rax as destination of the initial executable code sequence.
-(define_insn "tls_initial_exec_64_sun"
- [(set (match_operand:DI 0 "register_operand" "=a")
- (unspec:DI
- [(match_operand 1 "tls_symbolic_operand")]
- UNSPEC_TLS_IE_SUN))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && TARGET_SUN_TLS"
-{
- output_asm_insn
- ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
- return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
-}
- [(set_attr "type" "multi")])
-
-;; GNU2 TLS patterns can be split.
-
-(define_expand "tls_dynamic_gnu2_32"
- [(set (match_dup 3)
- (plus:SI (match_operand:SI 2 "register_operand")
- (const:SI
- (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
- UNSPEC_TLSDESC))))
- (parallel
- [(set (match_operand:SI 0 "register_operand")
- (unspec:SI [(match_dup 1) (match_dup 3)
- (match_dup 2) (reg:SI SP_REG)]
- UNSPEC_TLSDESC))
- (clobber (reg:CC FLAGS_REG))])]
- "!TARGET_64BIT && TARGET_GNU2_TLS"
-{
- operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
- ix86_tls_descriptor_calls_expanded_in_cfun = true;
-})
-
-(define_insn "*tls_dynamic_gnu2_lea_32"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (plus:SI (match_operand:SI 1 "register_operand" "b")
- (const:SI
- (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
- UNSPEC_TLSDESC))))]
- "!TARGET_64BIT && TARGET_GNU2_TLS"
- "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
- [(set_attr "type" "lea")
- (set_attr "mode" "SI")
- (set_attr "length" "6")
- (set_attr "length_address" "4")])
-
-(define_insn "*tls_dynamic_gnu2_call_32"
- [(set (match_operand:SI 0 "register_operand" "=a")
- (unspec:SI [(match_operand 1 "tls_symbolic_operand")
- (match_operand:SI 2 "register_operand" "0")
- ;; we have to make sure %ebx still points to the GOT
- (match_operand:SI 3 "register_operand" "b")
- (reg:SI SP_REG)]
- UNSPEC_TLSDESC))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_64BIT && TARGET_GNU2_TLS"
- "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
- [(set_attr "type" "call")
- (set_attr "length" "2")
- (set_attr "length_address" "0")])
-
-(define_insn_and_split "*tls_dynamic_gnu2_combine_32"
- [(set (match_operand:SI 0 "register_operand" "=&a")
- (plus:SI
- (unspec:SI [(match_operand 3 "tls_modbase_operand")
- (match_operand:SI 4)
- (match_operand:SI 2 "register_operand" "b")
- (reg:SI SP_REG)]
- UNSPEC_TLSDESC)
- (const:SI (unspec:SI
- [(match_operand 1 "tls_symbolic_operand")]
- UNSPEC_DTPOFF))))
- (clobber (reg:CC FLAGS_REG))]
- "!TARGET_64BIT && TARGET_GNU2_TLS"
- "#"
- ""
- [(set (match_dup 0) (match_dup 5))]
-{
- operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
- emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
-})
-
-(define_expand "tls_dynamic_gnu2_64"
- [(set (match_dup 2)
- (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
- UNSPEC_TLSDESC))
- (parallel
- [(set (match_operand:DI 0 "register_operand")
- (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
- UNSPEC_TLSDESC))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_64BIT && TARGET_GNU2_TLS"
-{
- operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
- ix86_tls_descriptor_calls_expanded_in_cfun = true;
-})
-
-(define_insn "*tls_dynamic_gnu2_lea_64"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
- UNSPEC_TLSDESC))]
- "TARGET_64BIT && TARGET_GNU2_TLS"
- "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
- [(set_attr "type" "lea")
- (set_attr "mode" "DI")
- (set_attr "length" "7")
- (set_attr "length_address" "4")])
-
-(define_insn "*tls_dynamic_gnu2_call_64"
- [(set (match_operand:DI 0 "register_operand" "=a")
- (unspec:DI [(match_operand 1 "tls_symbolic_operand")
- (match_operand:DI 2 "register_operand" "0")
- (reg:DI SP_REG)]
- UNSPEC_TLSDESC))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && TARGET_GNU2_TLS"
- "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
- [(set_attr "type" "call")
- (set_attr "length" "2")
- (set_attr "length_address" "0")])
-
-(define_insn_and_split "*tls_dynamic_gnu2_combine_64"
- [(set (match_operand:DI 0 "register_operand" "=&a")
- (plus:DI
- (unspec:DI [(match_operand 2 "tls_modbase_operand")
- (match_operand:DI 3)
- (reg:DI SP_REG)]
- UNSPEC_TLSDESC)
- (const:DI (unspec:DI
- [(match_operand 1 "tls_symbolic_operand")]
- UNSPEC_DTPOFF))))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && TARGET_GNU2_TLS"
- "#"
- ""
- [(set (match_dup 0) (match_dup 4))]
-{
- operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
- emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
-})
-
-;; These patterns match the binary 387 instructions for addM3, subM3,
-;; mulM3 and divM3. There are three patterns for each of DFmode and
-;; SFmode. The first is the normal insn, the second the same insn but
-;; with one operand a conversion, and the third the same insn but with
-;; the other operand a conversion. The conversion may be SFmode or
-;; SImode if the target mode DFmode, but only SImode if the target mode
-;; is SFmode.
-
-;; Gcc is slightly more smart about handling normal two address instructions
-;; so use special patterns for add and mull.
-
-(define_insn "*fop_<mode>_comm_mixed"
- [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
- (match_operator:MODEF 3 "binary_fp_operator"
- [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
- (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
- "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
- && COMMUTATIVE_ARITH_P (operands[3])
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (if_then_else (eq_attr "alternative" "1,2")
- (if_then_else (match_operand:MODEF 3 "mult_operator")
- (const_string "ssemul")
- (const_string "sseadd"))
- (if_then_else (match_operand:MODEF 3 "mult_operator")
- (const_string "fmul")
- (const_string "fop"))))
- (set_attr "isa" "*,noavx,avx")
- (set_attr "prefix" "orig,orig,vex")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*fop_<mode>_comm_sse"
- [(set (match_operand:MODEF 0 "register_operand" "=x,x")
- (match_operator:MODEF 3 "binary_fp_operator"
- [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
- (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
- "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
- && COMMUTATIVE_ARITH_P (operands[3])
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (if_then_else (match_operand:MODEF 3 "mult_operator")
- (const_string "ssemul")
- (const_string "sseadd")))
- (set_attr "isa" "noavx,avx")
- (set_attr "prefix" "orig,vex")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*fop_<mode>_comm_i387"
- [(set (match_operand:MODEF 0 "register_operand" "=f")
- (match_operator:MODEF 3 "binary_fp_operator"
- [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
- (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
- "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
- && COMMUTATIVE_ARITH_P (operands[3])
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (if_then_else (match_operand:MODEF 3 "mult_operator")
- (const_string "fmul")
- (const_string "fop")))
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*fop_<mode>_1_mixed"
- [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
- (match_operator:MODEF 3 "binary_fp_operator"
- [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
- (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
- "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
- && !COMMUTATIVE_ARITH_P (operands[3])
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(and (eq_attr "alternative" "2,3")
- (match_operand:MODEF 3 "mult_operator"))
- (const_string "ssemul")
- (and (eq_attr "alternative" "2,3")
- (match_operand:MODEF 3 "div_operator"))
- (const_string "ssediv")
- (eq_attr "alternative" "2,3")
- (const_string "sseadd")
- (match_operand:MODEF 3 "mult_operator")
- (const_string "fmul")
- (match_operand:MODEF 3 "div_operator")
- (const_string "fdiv")
- ]
- (const_string "fop")))
- (set_attr "isa" "*,*,noavx,avx")
- (set_attr "prefix" "orig,orig,orig,vex")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*rcpsf2_sse"
- [(set (match_operand:SF 0 "register_operand" "=x")
- (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
- UNSPEC_RCP))]
- "TARGET_SSE_MATH"
- "%vrcpss\t{%1, %d0|%d0, %1}"
- [(set_attr "type" "sse")
- (set_attr "atom_sse_attr" "rcp")
- (set_attr "btver2_sse_attr" "rcp")
- (set_attr "prefix" "maybe_vex")
- (set_attr "mode" "SF")])
-
-(define_insn "*fop_<mode>_1_sse"
- [(set (match_operand:MODEF 0 "register_operand" "=x,x")
- (match_operator:MODEF 3 "binary_fp_operator"
- [(match_operand:MODEF 1 "register_operand" "0,x")
- (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
- "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
- && !COMMUTATIVE_ARITH_P (operands[3])"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:MODEF 3 "mult_operator")
- (const_string "ssemul")
- (match_operand:MODEF 3 "div_operator")
- (const_string "ssediv")
- ]
- (const_string "sseadd")))
- (set_attr "isa" "noavx,avx")
- (set_attr "prefix" "orig,vex")
- (set_attr "mode" "<MODE>")])
-
-;; This pattern is not fully shadowed by the pattern above.
-(define_insn "*fop_<mode>_1_i387"
- [(set (match_operand:MODEF 0 "register_operand" "=f,f")
- (match_operator:MODEF 3 "binary_fp_operator"
- [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
- (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
- "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
- && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- && !COMMUTATIVE_ARITH_P (operands[3])
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:MODEF 3 "mult_operator")
- (const_string "fmul")
- (match_operand:MODEF 3 "div_operator")
- (const_string "fdiv")
- ]
- (const_string "fop")))
- (set_attr "mode" "<MODE>")])
-
-;; ??? Add SSE splitters for these!
-(define_insn "*fop_<MODEF:mode>_2_i387"
- [(set (match_operand:MODEF 0 "register_operand" "=f,f")
- (match_operator:MODEF 3 "binary_fp_operator"
- [(float:MODEF
- (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
- (match_operand:MODEF 2 "register_operand" "0,0")]))]
- "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
- && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
- && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
- "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:MODEF 3 "mult_operator")
- (const_string "fmul")
- (match_operand:MODEF 3 "div_operator")
- (const_string "fdiv")
- ]
- (const_string "fop")))
- (set_attr "fp_int_src" "true")
- (set_attr "mode" "<SWI24:MODE>")])
-
-(define_insn "*fop_<MODEF:mode>_3_i387"
- [(set (match_operand:MODEF 0 "register_operand" "=f,f")
- (match_operator:MODEF 3 "binary_fp_operator"
- [(match_operand:MODEF 1 "register_operand" "0,0")
- (float:MODEF
- (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
- "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
- && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
- && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
- "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:MODEF 3 "mult_operator")
- (const_string "fmul")
- (match_operand:MODEF 3 "div_operator")
- (const_string "fdiv")
- ]
- (const_string "fop")))
- (set_attr "fp_int_src" "true")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*fop_df_4_i387"
- [(set (match_operand:DF 0 "register_operand" "=f,f")
- (match_operator:DF 3 "binary_fp_operator"
- [(float_extend:DF
- (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
- (match_operand:DF 2 "register_operand" "0,f")]))]
- "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
- && !(TARGET_SSE2 && TARGET_SSE_MATH)
- && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:DF 3 "mult_operator")
- (const_string "fmul")
- (match_operand:DF 3 "div_operator")
- (const_string "fdiv")
- ]
- (const_string "fop")))
- (set_attr "mode" "SF")])
-
-(define_insn "*fop_df_5_i387"
- [(set (match_operand:DF 0 "register_operand" "=f,f")
- (match_operator:DF 3 "binary_fp_operator"
- [(match_operand:DF 1 "register_operand" "0,f")
- (float_extend:DF
- (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
- "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
- && !(TARGET_SSE2 && TARGET_SSE_MATH)"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:DF 3 "mult_operator")
- (const_string "fmul")
- (match_operand:DF 3 "div_operator")
- (const_string "fdiv")
- ]
- (const_string "fop")))
- (set_attr "mode" "SF")])
-
-(define_insn "*fop_df_6_i387"
- [(set (match_operand:DF 0 "register_operand" "=f,f")
- (match_operator:DF 3 "binary_fp_operator"
- [(float_extend:DF
- (match_operand:SF 1 "register_operand" "0,f"))
- (float_extend:DF
- (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
- "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
- && !(TARGET_SSE2 && TARGET_SSE_MATH)"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:DF 3 "mult_operator")
- (const_string "fmul")
- (match_operand:DF 3 "div_operator")
- (const_string "fdiv")
- ]
- (const_string "fop")))
- (set_attr "mode" "SF")])
-
-(define_insn "*fop_xf_comm_i387"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (match_operator:XF 3 "binary_fp_operator"
- [(match_operand:XF 1 "register_operand" "%0")
- (match_operand:XF 2 "register_operand" "f")]))]
- "TARGET_80387
- && COMMUTATIVE_ARITH_P (operands[3])"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (if_then_else (match_operand:XF 3 "mult_operator")
- (const_string "fmul")
- (const_string "fop")))
- (set_attr "mode" "XF")])
-
-(define_insn "*fop_xf_1_i387"
- [(set (match_operand:XF 0 "register_operand" "=f,f")
- (match_operator:XF 3 "binary_fp_operator"
- [(match_operand:XF 1 "register_operand" "0,f")
- (match_operand:XF 2 "register_operand" "f,0")]))]
- "TARGET_80387
- && !COMMUTATIVE_ARITH_P (operands[3])"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:XF 3 "mult_operator")
- (const_string "fmul")
- (match_operand:XF 3 "div_operator")
- (const_string "fdiv")
- ]
- (const_string "fop")))
- (set_attr "mode" "XF")])
-
-(define_insn "*fop_xf_2_i387"
- [(set (match_operand:XF 0 "register_operand" "=f,f")
- (match_operator:XF 3 "binary_fp_operator"
- [(float:XF
- (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
- (match_operand:XF 2 "register_operand" "0,0")]))]
- "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
- "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:XF 3 "mult_operator")
- (const_string "fmul")
- (match_operand:XF 3 "div_operator")
- (const_string "fdiv")
- ]
- (const_string "fop")))
- (set_attr "fp_int_src" "true")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*fop_xf_3_i387"
- [(set (match_operand:XF 0 "register_operand" "=f,f")
- (match_operator:XF 3 "binary_fp_operator"
- [(match_operand:XF 1 "register_operand" "0,0")
- (float:XF
- (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
- "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
- "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:XF 3 "mult_operator")
- (const_string "fmul")
- (match_operand:XF 3 "div_operator")
- (const_string "fdiv")
- ]
- (const_string "fop")))
- (set_attr "fp_int_src" "true")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*fop_xf_4_i387"
- [(set (match_operand:XF 0 "register_operand" "=f,f")
- (match_operator:XF 3 "binary_fp_operator"
- [(float_extend:XF
- (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
- (match_operand:XF 2 "register_operand" "0,f")]))]
- "TARGET_80387"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:XF 3 "mult_operator")
- (const_string "fmul")
- (match_operand:XF 3 "div_operator")
- (const_string "fdiv")
- ]
- (const_string "fop")))
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*fop_xf_5_i387"
- [(set (match_operand:XF 0 "register_operand" "=f,f")
- (match_operator:XF 3 "binary_fp_operator"
- [(match_operand:XF 1 "register_operand" "0,f")
- (float_extend:XF
- (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
- "TARGET_80387"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:XF 3 "mult_operator")
- (const_string "fmul")
- (match_operand:XF 3 "div_operator")
- (const_string "fdiv")
- ]
- (const_string "fop")))
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*fop_xf_6_i387"
- [(set (match_operand:XF 0 "register_operand" "=f,f")
- (match_operator:XF 3 "binary_fp_operator"
- [(float_extend:XF
- (match_operand:MODEF 1 "register_operand" "0,f"))
- (float_extend:XF
- (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
- "TARGET_80387"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:XF 3 "mult_operator")
- (const_string "fmul")
- (match_operand:XF 3 "div_operator")
- (const_string "fdiv")
- ]
- (const_string "fop")))
- (set_attr "mode" "<MODE>")])
-
-(define_split
- [(set (match_operand 0 "register_operand")
- (match_operator 3 "binary_fp_operator"
- [(float (match_operand:SWI24 1 "register_operand"))
- (match_operand 2 "register_operand")]))]
- "reload_completed
- && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
- && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
- [(const_int 0)]
-{
- operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
- operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
- gen_rtx_fmt_ee (GET_CODE (operands[3]),
- GET_MODE (operands[3]),
- operands[4],
- operands[2])));
- ix86_free_from_memory (GET_MODE (operands[1]));
- DONE;
-})
-
-(define_split
- [(set (match_operand 0 "register_operand")
- (match_operator 3 "binary_fp_operator"
- [(match_operand 1 "register_operand")
- (float (match_operand:SWI24 2 "register_operand"))]))]
- "reload_completed
- && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
- && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
- [(const_int 0)]
-{
- operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
- operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
- gen_rtx_fmt_ee (GET_CODE (operands[3]),
- GET_MODE (operands[3]),
- operands[1],
- operands[4])));
- ix86_free_from_memory (GET_MODE (operands[2]));
- DONE;
-})
-
-;; FPU special functions.
-
-;; This pattern implements a no-op XFmode truncation for
-;; all fancy i386 XFmode math functions.
-
-(define_insn "truncxf<mode>2_i387_noop_unspec"
- [(set (match_operand:MODEF 0 "register_operand" "=f")
- (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
- UNSPEC_TRUNC_NOOP))]
- "TARGET_USE_FANCY_MATH_387"
- "* return output_387_reg_move (insn, operands);"
- [(set_attr "type" "fmov")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "sqrtxf2"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
- "TARGET_USE_FANCY_MATH_387"
- "fsqrt"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")
- (set_attr "athlon_decode" "direct")
- (set_attr "amdfam10_decode" "direct")
- (set_attr "bdver1_decode" "direct")])
-
-(define_insn "sqrt_extend<mode>xf2_i387"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (sqrt:XF
- (float_extend:XF
- (match_operand:MODEF 1 "register_operand" "0"))))]
- "TARGET_USE_FANCY_MATH_387"
- "fsqrt"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")
- (set_attr "athlon_decode" "direct")
- (set_attr "amdfam10_decode" "direct")
- (set_attr "bdver1_decode" "direct")])
-
-(define_insn "*rsqrtsf2_sse"
- [(set (match_operand:SF 0 "register_operand" "=x")
- (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
- UNSPEC_RSQRT))]
- "TARGET_SSE_MATH"
- "%vrsqrtss\t{%1, %d0|%d0, %1}"
- [(set_attr "type" "sse")
- (set_attr "atom_sse_attr" "rcp")
- (set_attr "btver2_sse_attr" "rcp")
- (set_attr "prefix" "maybe_vex")
- (set_attr "mode" "SF")])
-
-(define_expand "rsqrtsf2"
- [(set (match_operand:SF 0 "register_operand")
- (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
- UNSPEC_RSQRT))]
- "TARGET_SSE_MATH"
-{
- ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
- DONE;
-})
-
-(define_insn "*sqrt<mode>2_sse"
- [(set (match_operand:MODEF 0 "register_operand" "=x")
- (sqrt:MODEF
- (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
- "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
- "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
- [(set_attr "type" "sse")
- (set_attr "atom_sse_attr" "sqrt")
- (set_attr "btver2_sse_attr" "sqrt")
- (set_attr "prefix" "maybe_vex")
- (set_attr "mode" "<MODE>")
- (set_attr "athlon_decode" "*")
- (set_attr "amdfam10_decode" "*")
- (set_attr "bdver1_decode" "*")])
-
-(define_expand "sqrt<mode>2"
- [(set (match_operand:MODEF 0 "register_operand")
- (sqrt:MODEF
- (match_operand:MODEF 1 "nonimmediate_operand")))]
- "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
- || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
-{
- if (<MODE>mode == SFmode
- && TARGET_SSE_MATH
- && TARGET_RECIP_SQRT
- && !optimize_function_for_size_p (cfun)
- && flag_finite_math_only && !flag_trapping_math
- && flag_unsafe_math_optimizations)
- {
- ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
- DONE;
- }
-
- if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
- {
- rtx op0 = gen_reg_rtx (XFmode);
- rtx op1 = force_reg (<MODE>mode, operands[1]);
-
- emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
- emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
- DONE;
- }
-})
-
-(define_insn "fpremxf4_i387"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (unspec:XF [(match_operand:XF 2 "register_operand" "0")
- (match_operand:XF 3 "register_operand" "1")]
- UNSPEC_FPREM_F))
- (set (match_operand:XF 1 "register_operand" "=u")
- (unspec:XF [(match_dup 2) (match_dup 3)]
- UNSPEC_FPREM_U))
- (set (reg:CCFP FPSR_REG)
- (unspec:CCFP [(match_dup 2) (match_dup 3)]
- UNSPEC_C2_FLAG))]
- "TARGET_USE_FANCY_MATH_387"
- "fprem"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")])
-
-(define_expand "fmodxf3"
- [(use (match_operand:XF 0 "register_operand"))
- (use (match_operand:XF 1 "general_operand"))
- (use (match_operand:XF 2 "general_operand"))]
- "TARGET_USE_FANCY_MATH_387"
-{
- rtx label = gen_label_rtx ();
-
- rtx op1 = gen_reg_rtx (XFmode);
- rtx op2 = gen_reg_rtx (XFmode);
-
- emit_move_insn (op2, operands[2]);
- emit_move_insn (op1, operands[1]);
-
- emit_label (label);
- emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
- ix86_emit_fp_unordered_jump (label);
- LABEL_NUSES (label) = 1;
-
- emit_move_insn (operands[0], op1);
- DONE;
-})
-
-(define_expand "fmod<mode>3"
- [(use (match_operand:MODEF 0 "register_operand"))
- (use (match_operand:MODEF 1 "general_operand"))
- (use (match_operand:MODEF 2 "general_operand"))]
- "TARGET_USE_FANCY_MATH_387"
-{
- rtx (*gen_truncxf) (rtx, rtx);
-
- rtx label = gen_label_rtx ();
-
- rtx op1 = gen_reg_rtx (XFmode);
- rtx op2 = gen_reg_rtx (XFmode);
-
- emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
- emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
-
- emit_label (label);
- emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
- ix86_emit_fp_unordered_jump (label);
- LABEL_NUSES (label) = 1;
-
- /* Truncate the result properly for strict SSE math. */
- if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
- && !TARGET_MIX_SSE_I387)
- gen_truncxf = gen_truncxf<mode>2;
- else
- gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
-
- emit_insn (gen_truncxf (operands[0], op1));
- DONE;
-})
-
-(define_insn "fprem1xf4_i387"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (unspec:XF [(match_operand:XF 2 "register_operand" "0")
- (match_operand:XF 3 "register_operand" "1")]
- UNSPEC_FPREM1_F))
- (set (match_operand:XF 1 "register_operand" "=u")
- (unspec:XF [(match_dup 2) (match_dup 3)]
- UNSPEC_FPREM1_U))
- (set (reg:CCFP FPSR_REG)
- (unspec:CCFP [(match_dup 2) (match_dup 3)]
- UNSPEC_C2_FLAG))]
- "TARGET_USE_FANCY_MATH_387"
- "fprem1"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")])
-
-(define_expand "remainderxf3"
- [(use (match_operand:XF 0 "register_operand"))
- (use (match_operand:XF 1 "general_operand"))
- (use (match_operand:XF 2 "general_operand"))]
- "TARGET_USE_FANCY_MATH_387"
-{
- rtx label = gen_label_rtx ();
-
- rtx op1 = gen_reg_rtx (XFmode);
- rtx op2 = gen_reg_rtx (XFmode);
-
- emit_move_insn (op2, operands[2]);
- emit_move_insn (op1, operands[1]);
-
- emit_label (label);
- emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
- ix86_emit_fp_unordered_jump (label);
- LABEL_NUSES (label) = 1;
-
- emit_move_insn (operands[0], op1);
- DONE;
-})
-
-(define_expand "remainder<mode>3"
- [(use (match_operand:MODEF 0 "register_operand"))
- (use (match_operand:MODEF 1 "general_operand"))
- (use (match_operand:MODEF 2 "general_operand"))]
- "TARGET_USE_FANCY_MATH_387"
-{
- rtx (*gen_truncxf) (rtx, rtx);
-
- rtx label = gen_label_rtx ();
-
- rtx op1 = gen_reg_rtx (XFmode);
- rtx op2 = gen_reg_rtx (XFmode);
-
- emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
- emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
-
- emit_label (label);
-
- emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
- ix86_emit_fp_unordered_jump (label);
- LABEL_NUSES (label) = 1;
-
- /* Truncate the result properly for strict SSE math. */
- if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
- && !TARGET_MIX_SSE_I387)
- gen_truncxf = gen_truncxf<mode>2;
- else
- gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
-
- emit_insn (gen_truncxf (operands[0], op1));
- DONE;
-})
-
-(define_int_iterator SINCOS
- [UNSPEC_SIN
- UNSPEC_COS])
-
-(define_int_attr sincos
- [(UNSPEC_SIN "sin")
- (UNSPEC_COS "cos")])
-
-(define_insn "*<sincos>xf2_i387"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
- SINCOS))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
- "f<sincos>"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")])
-
-(define_insn "*<sincos>_extend<mode>xf2_i387"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (unspec:XF [(float_extend:XF
- (match_operand:MODEF 1 "register_operand" "0"))]
- SINCOS))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
- "f<sincos>"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")])
-
-;; When sincos pattern is defined, sin and cos builtin functions will be
-;; expanded to sincos pattern with one of its outputs left unused.
-;; CSE pass will figure out if two sincos patterns can be combined,
-;; otherwise sincos pattern will be split back to sin or cos pattern,
-;; depending on the unused output.
-
-(define_insn "sincosxf3"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
- UNSPEC_SINCOS_COS))
- (set (match_operand:XF 1 "register_operand" "=u")
- (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
- "fsincos"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")])
-
-(define_split
- [(set (match_operand:XF 0 "register_operand")
- (unspec:XF [(match_operand:XF 2 "register_operand")]
- UNSPEC_SINCOS_COS))
- (set (match_operand:XF 1 "register_operand")
- (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
- "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
- && can_create_pseudo_p ()"
- [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
-
-(define_split
- [(set (match_operand:XF 0 "register_operand")
- (unspec:XF [(match_operand:XF 2 "register_operand")]
- UNSPEC_SINCOS_COS))
- (set (match_operand:XF 1 "register_operand")
- (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
- "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
- && can_create_pseudo_p ()"
- [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
-
-(define_insn "sincos_extend<mode>xf3_i387"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (unspec:XF [(float_extend:XF
- (match_operand:MODEF 2 "register_operand" "0"))]
- UNSPEC_SINCOS_COS))
- (set (match_operand:XF 1 "register_operand" "=u")
- (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
- "fsincos"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")])
-
-(define_split
- [(set (match_operand:XF 0 "register_operand")
- (unspec:XF [(float_extend:XF
- (match_operand:MODEF 2 "register_operand"))]
- UNSPEC_SINCOS_COS))
- (set (match_operand:XF 1 "register_operand")
- (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
- "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
- && can_create_pseudo_p ()"
- [(set (match_dup 1)
- (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
-
-(define_split
- [(set (match_operand:XF 0 "register_operand")
- (unspec:XF [(float_extend:XF
- (match_operand:MODEF 2 "register_operand"))]
- UNSPEC_SINCOS_COS))
- (set (match_operand:XF 1 "register_operand")
- (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
- "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
- && can_create_pseudo_p ()"
- [(set (match_dup 0)
- (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
-
-(define_expand "sincos<mode>3"
- [(use (match_operand:MODEF 0 "register_operand"))
- (use (match_operand:MODEF 1 "register_operand"))
- (use (match_operand:MODEF 2 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
-{
- rtx op0 = gen_reg_rtx (XFmode);
- rtx op1 = gen_reg_rtx (XFmode);
-
- emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
- DONE;
-})
-
-(define_insn "fptanxf4_i387"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (match_operand:XF 3 "const_double_operand" "F"))
- (set (match_operand:XF 1 "register_operand" "=u")
- (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
- UNSPEC_TAN))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations
- && standard_80387_constant_p (operands[3]) == 2"
- "fptan"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")])
-
-(define_insn "fptan_extend<mode>xf4_i387"
- [(set (match_operand:MODEF 0 "register_operand" "=f")
- (match_operand:MODEF 3 "const_double_operand" "F"))
- (set (match_operand:XF 1 "register_operand" "=u")
- (unspec:XF [(float_extend:XF
- (match_operand:MODEF 2 "register_operand" "0"))]
- UNSPEC_TAN))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations
- && standard_80387_constant_p (operands[3]) == 2"
- "fptan"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")])
-
-(define_expand "tanxf2"
- [(use (match_operand:XF 0 "register_operand"))
- (use (match_operand:XF 1 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
-{
- rtx one = gen_reg_rtx (XFmode);
- rtx op2 = CONST1_RTX (XFmode); /* fld1 */
-
- emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
- DONE;
-})
-
-(define_expand "tan<mode>2"
- [(use (match_operand:MODEF 0 "register_operand"))
- (use (match_operand:MODEF 1 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
-{
- rtx op0 = gen_reg_rtx (XFmode);
-
- rtx one = gen_reg_rtx (<MODE>mode);
- rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
-
- emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
- operands[1], op2));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
- DONE;
-})
-
-(define_insn "*fpatanxf3_i387"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (unspec:XF [(match_operand:XF 1 "register_operand" "0")
- (match_operand:XF 2 "register_operand" "u")]
- UNSPEC_FPATAN))
- (clobber (match_scratch:XF 3 "=2"))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
- "fpatan"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")])
-
-(define_insn "fpatan_extend<mode>xf3_i387"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (unspec:XF [(float_extend:XF
- (match_operand:MODEF 1 "register_operand" "0"))
- (float_extend:XF
- (match_operand:MODEF 2 "register_operand" "u"))]
- UNSPEC_FPATAN))
- (clobber (match_scratch:XF 3 "=2"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
- "fpatan"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")])
-
-(define_expand "atan2xf3"
- [(parallel [(set (match_operand:XF 0 "register_operand")
- (unspec:XF [(match_operand:XF 2 "register_operand")
- (match_operand:XF 1 "register_operand")]
- UNSPEC_FPATAN))
- (clobber (match_scratch:XF 3))])]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations")
-
-(define_expand "atan2<mode>3"
- [(use (match_operand:MODEF 0 "register_operand"))
- (use (match_operand:MODEF 1 "register_operand"))
- (use (match_operand:MODEF 2 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
-{
- rtx op0 = gen_reg_rtx (XFmode);
-
- emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
- DONE;
-})
-
-(define_expand "atanxf2"
- [(parallel [(set (match_operand:XF 0 "register_operand")
- (unspec:XF [(match_dup 2)
- (match_operand:XF 1 "register_operand")]
- UNSPEC_FPATAN))
- (clobber (match_scratch:XF 3))])]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
-{
- operands[2] = gen_reg_rtx (XFmode);
- emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
-})
-
-(define_expand "atan<mode>2"
- [(use (match_operand:MODEF 0 "register_operand"))
- (use (match_operand:MODEF 1 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
-{
- rtx op0 = gen_reg_rtx (XFmode);
-
- rtx op2 = gen_reg_rtx (<MODE>mode);
- emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
-
- emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
- DONE;
-})
-
-(define_expand "asinxf2"
- [(set (match_dup 2)
- (mult:XF (match_operand:XF 1 "register_operand")
- (match_dup 1)))
- (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
- (set (match_dup 5) (sqrt:XF (match_dup 4)))
- (parallel [(set (match_operand:XF 0 "register_operand")
- (unspec:XF [(match_dup 5) (match_dup 1)]
- UNSPEC_FPATAN))
- (clobber (match_scratch:XF 6))])]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
-{
- int i;
-
- if (optimize_insn_for_size_p ())
- FAIL;
-
- for (i = 2; i < 6; i++)
- operands[i] = gen_reg_rtx (XFmode);
-
- emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
-})
-
-(define_expand "asin<mode>2"
- [(use (match_operand:MODEF 0 "register_operand"))
- (use (match_operand:MODEF 1 "general_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
-{
- rtx op0 = gen_reg_rtx (XFmode);
- rtx op1 = gen_reg_rtx (XFmode);
-
- if (optimize_insn_for_size_p ())
- FAIL;
-
- emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
- emit_insn (gen_asinxf2 (op0, op1));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
- DONE;
-})
-
-(define_expand "acosxf2"
- [(set (match_dup 2)
- (mult:XF (match_operand:XF 1 "register_operand")
- (match_dup 1)))
- (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
- (set (match_dup 5) (sqrt:XF (match_dup 4)))
- (parallel [(set (match_operand:XF 0 "register_operand")
- (unspec:XF [(match_dup 1) (match_dup 5)]
- UNSPEC_FPATAN))
- (clobber (match_scratch:XF 6))])]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
-{
- int i;
-
- if (optimize_insn_for_size_p ())
- FAIL;
-
- for (i = 2; i < 6; i++)
- operands[i] = gen_reg_rtx (XFmode);
-
- emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
-})
-
-(define_expand "acos<mode>2"
- [(use (match_operand:MODEF 0 "register_operand"))
- (use (match_operand:MODEF 1 "general_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
-{
- rtx op0 = gen_reg_rtx (XFmode);
- rtx op1 = gen_reg_rtx (XFmode);
-
- if (optimize_insn_for_size_p ())
- FAIL;
-
- emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
- emit_insn (gen_acosxf2 (op0, op1));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
- DONE;
-})
-
-(define_insn "fyl2xxf3_i387"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (unspec:XF [(match_operand:XF 1 "register_operand" "0")
- (match_operand:XF 2 "register_operand" "u")]
- UNSPEC_FYL2X))
- (clobber (match_scratch:XF 3 "=2"))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
- "fyl2x"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")])
-
-(define_insn "fyl2x_extend<mode>xf3_i387"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (unspec:XF [(float_extend:XF
- (match_operand:MODEF 1 "register_operand" "0"))
- (match_operand:XF 2 "register_operand" "u")]
- UNSPEC_FYL2X))
- (clobber (match_scratch:XF 3 "=2"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
- "fyl2x"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")])
-
-(define_expand "logxf2"
- [(parallel [(set (match_operand:XF 0 "register_operand")
- (unspec:XF [(match_operand:XF 1 "register_operand")
- (match_dup 2)] UNSPEC_FYL2X))
- (clobber (match_scratch:XF 3))])]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
-{
- operands[2] = gen_reg_rtx (XFmode);
- emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
-})
-
-(define_expand "log<mode>2"
- [(use (match_operand:MODEF 0 "register_operand"))
- (use (match_operand:MODEF 1 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
-{
- rtx op0 = gen_reg_rtx (XFmode);
-
- rtx op2 = gen_reg_rtx (XFmode);
- emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
-
- emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
- DONE;
-})
-
-(define_expand "log10xf2"
- [(parallel [(set (match_operand:XF 0 "register_operand")
- (unspec:XF [(match_operand:XF 1 "register_operand")
- (match_dup 2)] UNSPEC_FYL2X))
- (clobber (match_scratch:XF 3))])]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
-{
- operands[2] = gen_reg_rtx (XFmode);
- emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
-})
-
-(define_expand "log10<mode>2"
- [(use (match_operand:MODEF 0 "register_operand"))
- (use (match_operand:MODEF 1 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
-{
- rtx op0 = gen_reg_rtx (XFmode);
-
- rtx op2 = gen_reg_rtx (XFmode);
- emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
-
- emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
- DONE;
-})
-
-(define_expand "log2xf2"
- [(parallel [(set (match_operand:XF 0 "register_operand")
- (unspec:XF [(match_operand:XF 1 "register_operand")
- (match_dup 2)] UNSPEC_FYL2X))
- (clobber (match_scratch:XF 3))])]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
-{
- operands[2] = gen_reg_rtx (XFmode);
- emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
-})
-
-(define_expand "log2<mode>2"
- [(use (match_operand:MODEF 0 "register_operand"))
- (use (match_operand:MODEF 1 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
-{
- rtx op0 = gen_reg_rtx (XFmode);
-
- rtx op2 = gen_reg_rtx (XFmode);
- emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
-
- emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
- DONE;
-})
-
-(define_insn "fyl2xp1xf3_i387"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (unspec:XF [(match_operand:XF 1 "register_operand" "0")
- (match_operand:XF 2 "register_operand" "u")]
- UNSPEC_FYL2XP1))
- (clobber (match_scratch:XF 3 "=2"))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
- "fyl2xp1"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")])
-
-(define_insn "fyl2xp1_extend<mode>xf3_i387"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (unspec:XF [(float_extend:XF
- (match_operand:MODEF 1 "register_operand" "0"))
- (match_operand:XF 2 "register_operand" "u")]
- UNSPEC_FYL2XP1))
- (clobber (match_scratch:XF 3 "=2"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
- "fyl2xp1"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")])
-
-(define_expand "log1pxf2"
- [(use (match_operand:XF 0 "register_operand"))
- (use (match_operand:XF 1 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
-{
- if (optimize_insn_for_size_p ())
- FAIL;
-
- ix86_emit_i387_log1p (operands[0], operands[1]);
- DONE;
-})
-
-(define_expand "log1p<mode>2"
- [(use (match_operand:MODEF 0 "register_operand"))
- (use (match_operand:MODEF 1 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
-{
- rtx op0;
-
- if (optimize_insn_for_size_p ())
- FAIL;
-
- op0 = gen_reg_rtx (XFmode);
-
- operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
-
- ix86_emit_i387_log1p (op0, operands[1]);
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
- DONE;
-})
-
-(define_insn "fxtractxf3_i387"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
- UNSPEC_XTRACT_FRACT))
- (set (match_operand:XF 1 "register_operand" "=u")
- (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
- "fxtract"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")])
-
-(define_insn "fxtract_extend<mode>xf3_i387"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (unspec:XF [(float_extend:XF
- (match_operand:MODEF 2 "register_operand" "0"))]
- UNSPEC_XTRACT_FRACT))
- (set (match_operand:XF 1 "register_operand" "=u")
- (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
- "fxtract"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")])
-
-(define_expand "logbxf2"
- [(parallel [(set (match_dup 2)
- (unspec:XF [(match_operand:XF 1 "register_operand")]
- UNSPEC_XTRACT_FRACT))
- (set (match_operand:XF 0 "register_operand")
- (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
- "operands[2] = gen_reg_rtx (XFmode);")
-
-(define_expand "logb<mode>2"
- [(use (match_operand:MODEF 0 "register_operand"))
- (use (match_operand:MODEF 1 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
-{
- rtx op0 = gen_reg_rtx (XFmode);
- rtx op1 = gen_reg_rtx (XFmode);
-
- emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
- DONE;
-})
-
-(define_expand "ilogbxf2"
- [(use (match_operand:SI 0 "register_operand"))
- (use (match_operand:XF 1 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
-{
- rtx op0, op1;
-
- if (optimize_insn_for_size_p ())
- FAIL;
-
- op0 = gen_reg_rtx (XFmode);
- op1 = gen_reg_rtx (XFmode);
-
- emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
- emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
- DONE;
-})
-
-(define_expand "ilogb<mode>2"
- [(use (match_operand:SI 0 "register_operand"))
- (use (match_operand:MODEF 1 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
-{
- rtx op0, op1;
-
- if (optimize_insn_for_size_p ())
- FAIL;
-
- op0 = gen_reg_rtx (XFmode);
- op1 = gen_reg_rtx (XFmode);
-
- emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
- emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
- DONE;
-})
-
-(define_insn "*f2xm1xf2_i387"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
- UNSPEC_F2XM1))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
- "f2xm1"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")])
-
-(define_insn "*fscalexf4_i387"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (unspec:XF [(match_operand:XF 2 "register_operand" "0")
- (match_operand:XF 3 "register_operand" "1")]
- UNSPEC_FSCALE_FRACT))
- (set (match_operand:XF 1 "register_operand" "=u")
- (unspec:XF [(match_dup 2) (match_dup 3)]
- UNSPEC_FSCALE_EXP))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
- "fscale"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")])
-
-(define_expand "expNcorexf3"
- [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
- (match_operand:XF 2 "register_operand")))
- (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
- (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
- (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
- (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
- (parallel [(set (match_operand:XF 0 "register_operand")
- (unspec:XF [(match_dup 8) (match_dup 4)]
- UNSPEC_FSCALE_FRACT))
- (set (match_dup 9)
- (unspec:XF [(match_dup 8) (match_dup 4)]
- UNSPEC_FSCALE_EXP))])]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
-{
- int i;
-
- if (optimize_insn_for_size_p ())
- FAIL;
-
- for (i = 3; i < 10; i++)
- operands[i] = gen_reg_rtx (XFmode);
-
- emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
-})
-
-(define_expand "expxf2"
- [(use (match_operand:XF 0 "register_operand"))
- (use (match_operand:XF 1 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
-{
- rtx op2;
-
- if (optimize_insn_for_size_p ())
- FAIL;
-
- op2 = gen_reg_rtx (XFmode);
- emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
-
- emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
- DONE;
-})
-
-(define_expand "exp<mode>2"
- [(use (match_operand:MODEF 0 "register_operand"))
- (use (match_operand:MODEF 1 "general_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
-{
- rtx op0, op1;
-
- if (optimize_insn_for_size_p ())
- FAIL;
-
- op0 = gen_reg_rtx (XFmode);
- op1 = gen_reg_rtx (XFmode);
-
- emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
- emit_insn (gen_expxf2 (op0, op1));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
- DONE;
-})
-
-(define_expand "exp10xf2"
- [(use (match_operand:XF 0 "register_operand"))
- (use (match_operand:XF 1 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
-{
- rtx op2;
-
- if (optimize_insn_for_size_p ())
- FAIL;
-
- op2 = gen_reg_rtx (XFmode);
- emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
-
- emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
- DONE;
-})
-
-(define_expand "exp10<mode>2"
- [(use (match_operand:MODEF 0 "register_operand"))
- (use (match_operand:MODEF 1 "general_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
-{
- rtx op0, op1;
-
- if (optimize_insn_for_size_p ())
- FAIL;
-
- op0 = gen_reg_rtx (XFmode);
- op1 = gen_reg_rtx (XFmode);
-
- emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
- emit_insn (gen_exp10xf2 (op0, op1));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
- DONE;
-})
-
-(define_expand "exp2xf2"
- [(use (match_operand:XF 0 "register_operand"))
- (use (match_operand:XF 1 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
-{
- rtx op2;
-
- if (optimize_insn_for_size_p ())
- FAIL;
-
- op2 = gen_reg_rtx (XFmode);
- emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
-
- emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
- DONE;
-})
-
-(define_expand "exp2<mode>2"
- [(use (match_operand:MODEF 0 "register_operand"))
- (use (match_operand:MODEF 1 "general_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
-{
- rtx op0, op1;
-
- if (optimize_insn_for_size_p ())
- FAIL;
-
- op0 = gen_reg_rtx (XFmode);
- op1 = gen_reg_rtx (XFmode);
-
- emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
- emit_insn (gen_exp2xf2 (op0, op1));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
- DONE;
-})
-
-(define_expand "expm1xf2"
- [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
- (match_dup 2)))
- (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
- (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
- (set (match_dup 9) (float_extend:XF (match_dup 13)))
- (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
- (parallel [(set (match_dup 7)
- (unspec:XF [(match_dup 6) (match_dup 4)]
- UNSPEC_FSCALE_FRACT))
- (set (match_dup 8)
- (unspec:XF [(match_dup 6) (match_dup 4)]
- UNSPEC_FSCALE_EXP))])
- (parallel [(set (match_dup 10)
- (unspec:XF [(match_dup 9) (match_dup 8)]
- UNSPEC_FSCALE_FRACT))
- (set (match_dup 11)
- (unspec:XF [(match_dup 9) (match_dup 8)]
- UNSPEC_FSCALE_EXP))])
- (set (match_dup 12) (minus:XF (match_dup 10)
- (float_extend:XF (match_dup 13))))
- (set (match_operand:XF 0 "register_operand")
- (plus:XF (match_dup 12) (match_dup 7)))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
-{
- int i;
-
- if (optimize_insn_for_size_p ())
- FAIL;
-
- for (i = 2; i < 13; i++)
- operands[i] = gen_reg_rtx (XFmode);
-
- operands[13]
- = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
-
- emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
-})
-
-(define_expand "expm1<mode>2"
- [(use (match_operand:MODEF 0 "register_operand"))
- (use (match_operand:MODEF 1 "general_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
-{
- rtx op0, op1;
-
- if (optimize_insn_for_size_p ())
- FAIL;
-
- op0 = gen_reg_rtx (XFmode);
- op1 = gen_reg_rtx (XFmode);
-
- emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
- emit_insn (gen_expm1xf2 (op0, op1));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
- DONE;
-})
-
-(define_expand "ldexpxf3"
- [(set (match_dup 3)
- (float:XF (match_operand:SI 2 "register_operand")))
- (parallel [(set (match_operand:XF 0 " register_operand")
- (unspec:XF [(match_operand:XF 1 "register_operand")
- (match_dup 3)]
- UNSPEC_FSCALE_FRACT))
- (set (match_dup 4)
- (unspec:XF [(match_dup 1) (match_dup 3)]
- UNSPEC_FSCALE_EXP))])]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
-{
- if (optimize_insn_for_size_p ())
- FAIL;
-
- operands[3] = gen_reg_rtx (XFmode);
- operands[4] = gen_reg_rtx (XFmode);
-})
-
-(define_expand "ldexp<mode>3"
- [(use (match_operand:MODEF 0 "register_operand"))
- (use (match_operand:MODEF 1 "general_operand"))
- (use (match_operand:SI 2 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
-{
- rtx op0, op1;
-
- if (optimize_insn_for_size_p ())
- FAIL;
-
- op0 = gen_reg_rtx (XFmode);
- op1 = gen_reg_rtx (XFmode);
-
- emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
- emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
- DONE;
-})
-
-(define_expand "scalbxf3"
- [(parallel [(set (match_operand:XF 0 " register_operand")
- (unspec:XF [(match_operand:XF 1 "register_operand")
- (match_operand:XF 2 "register_operand")]
- UNSPEC_FSCALE_FRACT))
- (set (match_dup 3)
- (unspec:XF [(match_dup 1) (match_dup 2)]
- UNSPEC_FSCALE_EXP))])]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
-{
- if (optimize_insn_for_size_p ())
- FAIL;
-
- operands[3] = gen_reg_rtx (XFmode);
-})
-
-(define_expand "scalb<mode>3"
- [(use (match_operand:MODEF 0 "register_operand"))
- (use (match_operand:MODEF 1 "general_operand"))
- (use (match_operand:MODEF 2 "general_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
-{
- rtx op0, op1, op2;
-
- if (optimize_insn_for_size_p ())
- FAIL;
-
- op0 = gen_reg_rtx (XFmode);
- op1 = gen_reg_rtx (XFmode);
- op2 = gen_reg_rtx (XFmode);
-
- emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
- emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
- emit_insn (gen_scalbxf3 (op0, op1, op2));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
- DONE;
-})
-
-(define_expand "significandxf2"
- [(parallel [(set (match_operand:XF 0 "register_operand")
- (unspec:XF [(match_operand:XF 1 "register_operand")]
- UNSPEC_XTRACT_FRACT))
- (set (match_dup 2)
- (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
- "operands[2] = gen_reg_rtx (XFmode);")
-
-(define_expand "significand<mode>2"
- [(use (match_operand:MODEF 0 "register_operand"))
- (use (match_operand:MODEF 1 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
-{
- rtx op0 = gen_reg_rtx (XFmode);
- rtx op1 = gen_reg_rtx (XFmode);
-
- emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
- DONE;
-})
-
-
-(define_insn "sse4_1_round<mode>2"
- [(set (match_operand:MODEF 0 "register_operand" "=x")
- (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
- (match_operand:SI 2 "const_0_to_15_operand" "n")]
- UNSPEC_ROUND))]
- "TARGET_ROUND"
- "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
- [(set_attr "type" "ssecvt")
- (set_attr "prefix_extra" "1")
- (set_attr "prefix" "maybe_vex")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "rintxf2"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
- UNSPEC_FRNDINT))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
- "frndint"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")])
-
-(define_expand "rint<mode>2"
- [(use (match_operand:MODEF 0 "register_operand"))
- (use (match_operand:MODEF 1 "register_operand"))]
- "(TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations)
- || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
- && !flag_trapping_math)"
-{
- if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
- && !flag_trapping_math)
- {
- if (TARGET_ROUND)
- emit_insn (gen_sse4_1_round<mode>2
- (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
- else if (optimize_insn_for_size_p ())
- FAIL;
- else
- ix86_expand_rint (operands[0], operands[1]);
- }
- else
- {
- rtx op0 = gen_reg_rtx (XFmode);
- rtx op1 = gen_reg_rtx (XFmode);
-
- emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
- emit_insn (gen_rintxf2 (op0, op1));
-
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
- }
- DONE;
-})
-
-(define_expand "round<mode>2"
- [(match_operand:X87MODEF 0 "register_operand")
- (match_operand:X87MODEF 1 "nonimmediate_operand")]
- "(TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations)
- || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
- && !flag_trapping_math && !flag_rounding_math)"
-{
- if (optimize_insn_for_size_p ())
- FAIL;
-
- if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
- && !flag_trapping_math && !flag_rounding_math)
- {
- if (TARGET_ROUND)
- {
- operands[1] = force_reg (<MODE>mode, operands[1]);
- ix86_expand_round_sse4 (operands[0], operands[1]);
- }
- else if (TARGET_64BIT || (<MODE>mode != DFmode))
- ix86_expand_round (operands[0], operands[1]);
- else
- ix86_expand_rounddf_32 (operands[0], operands[1]);
- }
- else
- {
- operands[1] = force_reg (<MODE>mode, operands[1]);
- ix86_emit_i387_round (operands[0], operands[1]);
- }
- DONE;
-})
-
-(define_insn_and_split "*fistdi2_1"
- [(set (match_operand:DI 0 "nonimmediate_operand")
- (unspec:DI [(match_operand:XF 1 "register_operand")]
- UNSPEC_FIST))]
- "TARGET_USE_FANCY_MATH_387
- && can_create_pseudo_p ()"
- "#"
- "&& 1"
- [(const_int 0)]
-{
- if (memory_operand (operands[0], VOIDmode))
- emit_insn (gen_fistdi2 (operands[0], operands[1]));
- else
- {
- operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
- emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
- operands[2]));
- }
- DONE;
-}
- [(set_attr "type" "fpspc")
- (set_attr "mode" "DI")])
-
-(define_insn "fistdi2"
- [(set (match_operand:DI 0 "memory_operand" "=m")
- (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
- UNSPEC_FIST))
- (clobber (match_scratch:XF 2 "=&1f"))]
- "TARGET_USE_FANCY_MATH_387"
- "* return output_fix_trunc (insn, operands, false);"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "DI")])
-
-(define_insn "fistdi2_with_temp"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
- (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
- UNSPEC_FIST))
- (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
- (clobber (match_scratch:XF 3 "=&1f,&1f"))]
- "TARGET_USE_FANCY_MATH_387"
- "#"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "DI")])
-
-(define_split
- [(set (match_operand:DI 0 "register_operand")
- (unspec:DI [(match_operand:XF 1 "register_operand")]
- UNSPEC_FIST))
- (clobber (match_operand:DI 2 "memory_operand"))
- (clobber (match_scratch 3))]
- "reload_completed"
- [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
- (clobber (match_dup 3))])
- (set (match_dup 0) (match_dup 2))])
-
-(define_split
- [(set (match_operand:DI 0 "memory_operand")
- (unspec:DI [(match_operand:XF 1 "register_operand")]
- UNSPEC_FIST))
- (clobber (match_operand:DI 2 "memory_operand"))
- (clobber (match_scratch 3))]
- "reload_completed"
- [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
- (clobber (match_dup 3))])])
-
-(define_insn_and_split "*fist<mode>2_1"
- [(set (match_operand:SWI24 0 "register_operand")
- (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
- UNSPEC_FIST))]
- "TARGET_USE_FANCY_MATH_387
- && can_create_pseudo_p ()"
- "#"
- "&& 1"
- [(const_int 0)]
-{
- operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
- emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
- operands[2]));
- DONE;
-}
- [(set_attr "type" "fpspc")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "fist<mode>2"
- [(set (match_operand:SWI24 0 "memory_operand" "=m")
- (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
- UNSPEC_FIST))]
- "TARGET_USE_FANCY_MATH_387"
- "* return output_fix_trunc (insn, operands, false);"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "fist<mode>2_with_temp"
- [(set (match_operand:SWI24 0 "register_operand" "=r")
- (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
- UNSPEC_FIST))
- (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
- "TARGET_USE_FANCY_MATH_387"
- "#"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "<MODE>")])
-
-(define_split
- [(set (match_operand:SWI24 0 "register_operand")
- (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
- UNSPEC_FIST))
- (clobber (match_operand:SWI24 2 "memory_operand"))]
- "reload_completed"
- [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
- (set (match_dup 0) (match_dup 2))])
-
-(define_split
- [(set (match_operand:SWI24 0 "memory_operand")
- (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
- UNSPEC_FIST))
- (clobber (match_operand:SWI24 2 "memory_operand"))]
- "reload_completed"
- [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
-
-(define_expand "lrintxf<mode>2"
- [(set (match_operand:SWI248x 0 "nonimmediate_operand")
- (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
- UNSPEC_FIST))]
- "TARGET_USE_FANCY_MATH_387")
-
-(define_expand "lrint<MODEF:mode><SWI48:mode>2"
- [(set (match_operand:SWI48 0 "nonimmediate_operand")
- (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
- UNSPEC_FIX_NOTRUNC))]
- "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
-
-(define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
- [(match_operand:SWI248x 0 "nonimmediate_operand")
- (match_operand:X87MODEF 1 "register_operand")]
- "(TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations)
- || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
- && <SWI248x:MODE>mode != HImode
- && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
- && !flag_trapping_math && !flag_rounding_math)"
-{
- if (optimize_insn_for_size_p ())
- FAIL;
-
- if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
- && <SWI248x:MODE>mode != HImode
- && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
- && !flag_trapping_math && !flag_rounding_math)
- ix86_expand_lround (operands[0], operands[1]);
- else
- ix86_emit_i387_round (operands[0], operands[1]);
- DONE;
-})
-
-(define_int_iterator FRNDINT_ROUNDING
- [UNSPEC_FRNDINT_FLOOR
- UNSPEC_FRNDINT_CEIL
- UNSPEC_FRNDINT_TRUNC])
-
-(define_int_iterator FIST_ROUNDING
- [UNSPEC_FIST_FLOOR
- UNSPEC_FIST_CEIL])
-
-;; Base name for define_insn
-(define_int_attr rounding_insn
- [(UNSPEC_FRNDINT_FLOOR "floor")
- (UNSPEC_FRNDINT_CEIL "ceil")
- (UNSPEC_FRNDINT_TRUNC "btrunc")
- (UNSPEC_FIST_FLOOR "floor")
- (UNSPEC_FIST_CEIL "ceil")])
-
-(define_int_attr rounding
- [(UNSPEC_FRNDINT_FLOOR "floor")
- (UNSPEC_FRNDINT_CEIL "ceil")
- (UNSPEC_FRNDINT_TRUNC "trunc")
- (UNSPEC_FIST_FLOOR "floor")
- (UNSPEC_FIST_CEIL "ceil")])
-
-(define_int_attr ROUNDING
- [(UNSPEC_FRNDINT_FLOOR "FLOOR")
- (UNSPEC_FRNDINT_CEIL "CEIL")
- (UNSPEC_FRNDINT_TRUNC "TRUNC")
- (UNSPEC_FIST_FLOOR "FLOOR")
- (UNSPEC_FIST_CEIL "CEIL")])
-
-;; Rounding mode control word calculation could clobber FLAGS_REG.
-(define_insn_and_split "frndintxf2_<rounding>"
- [(set (match_operand:XF 0 "register_operand")
- (unspec:XF [(match_operand:XF 1 "register_operand")]
- FRNDINT_ROUNDING))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations
- && can_create_pseudo_p ()"
- "#"
- "&& 1"
- [(const_int 0)]
-{
- ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
-
- operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
- operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
-
- emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
- operands[2], operands[3]));
- DONE;
-}
- [(set_attr "type" "frndint")
- (set_attr "i387_cw" "<rounding>")
- (set_attr "mode" "XF")])
-
-(define_insn "frndintxf2_<rounding>_i387"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
- FRNDINT_ROUNDING))
- (use (match_operand:HI 2 "memory_operand" "m"))
- (use (match_operand:HI 3 "memory_operand" "m"))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
- "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
- [(set_attr "type" "frndint")
- (set_attr "i387_cw" "<rounding>")
- (set_attr "mode" "XF")])
-
-(define_expand "<rounding_insn>xf2"
- [(parallel [(set (match_operand:XF 0 "register_operand")
- (unspec:XF [(match_operand:XF 1 "register_operand")]
- FRNDINT_ROUNDING))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations
- && !optimize_insn_for_size_p ()")
-
-(define_expand "<rounding_insn><mode>2"
- [(parallel [(set (match_operand:MODEF 0 "register_operand")
- (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
- FRNDINT_ROUNDING))
- (clobber (reg:CC FLAGS_REG))])]
- "(TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations)
- || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
- && !flag_trapping_math)"
-{
- if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
- && !flag_trapping_math)
- {
- if (TARGET_ROUND)
- emit_insn (gen_sse4_1_round<mode>2
- (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
- else if (optimize_insn_for_size_p ())
- FAIL;
- else if (TARGET_64BIT || (<MODE>mode != DFmode))
- {
- if (ROUND_<ROUNDING> == ROUND_FLOOR)
- ix86_expand_floorceil (operands[0], operands[1], true);
- else if (ROUND_<ROUNDING> == ROUND_CEIL)
- ix86_expand_floorceil (operands[0], operands[1], false);
- else if (ROUND_<ROUNDING> == ROUND_TRUNC)
- ix86_expand_trunc (operands[0], operands[1]);
- else
- gcc_unreachable ();
- }
- else
- {
- if (ROUND_<ROUNDING> == ROUND_FLOOR)
- ix86_expand_floorceildf_32 (operands[0], operands[1], true);
- else if (ROUND_<ROUNDING> == ROUND_CEIL)
- ix86_expand_floorceildf_32 (operands[0], operands[1], false);
- else if (ROUND_<ROUNDING> == ROUND_TRUNC)
- ix86_expand_truncdf_32 (operands[0], operands[1]);
- else
- gcc_unreachable ();
- }
- }
- else
- {
- rtx op0, op1;
-
- if (optimize_insn_for_size_p ())
- FAIL;
-
- op0 = gen_reg_rtx (XFmode);
- op1 = gen_reg_rtx (XFmode);
- emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
- emit_insn (gen_frndintxf2_<rounding> (op0, op1));
-
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
- }
- DONE;
-})
-
-;; Rounding mode control word calculation could clobber FLAGS_REG.
-(define_insn_and_split "frndintxf2_mask_pm"
- [(set (match_operand:XF 0 "register_operand")
- (unspec:XF [(match_operand:XF 1 "register_operand")]
- UNSPEC_FRNDINT_MASK_PM))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations
- && can_create_pseudo_p ()"
- "#"
- "&& 1"
- [(const_int 0)]
-{
- ix86_optimize_mode_switching[I387_MASK_PM] = 1;
-
- operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
- operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
-
- emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
- operands[2], operands[3]));
- DONE;
-}
- [(set_attr "type" "frndint")
- (set_attr "i387_cw" "mask_pm")
- (set_attr "mode" "XF")])
-
-(define_insn "frndintxf2_mask_pm_i387"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
- UNSPEC_FRNDINT_MASK_PM))
- (use (match_operand:HI 2 "memory_operand" "m"))
- (use (match_operand:HI 3 "memory_operand" "m"))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
- "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
- [(set_attr "type" "frndint")
- (set_attr "i387_cw" "mask_pm")
- (set_attr "mode" "XF")])
-
-(define_expand "nearbyintxf2"
- [(parallel [(set (match_operand:XF 0 "register_operand")
- (unspec:XF [(match_operand:XF 1 "register_operand")]
- UNSPEC_FRNDINT_MASK_PM))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations")
-
-(define_expand "nearbyint<mode>2"
- [(use (match_operand:MODEF 0 "register_operand"))
- (use (match_operand:MODEF 1 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations"
-{
- rtx op0 = gen_reg_rtx (XFmode);
- rtx op1 = gen_reg_rtx (XFmode);
-
- emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
- emit_insn (gen_frndintxf2_mask_pm (op0, op1));
-
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
- DONE;
-})
-
-;; Rounding mode control word calculation could clobber FLAGS_REG.
-(define_insn_and_split "*fist<mode>2_<rounding>_1"
- [(set (match_operand:SWI248x 0 "nonimmediate_operand")
- (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
- FIST_ROUNDING))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations
- && can_create_pseudo_p ()"
- "#"
- "&& 1"
- [(const_int 0)]
-{
- ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
-
- operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
- operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
- if (memory_operand (operands[0], VOIDmode))
- emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
- operands[2], operands[3]));
- else
- {
- operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
- emit_insn (gen_fist<mode>2_<rounding>_with_temp
- (operands[0], operands[1], operands[2],
- operands[3], operands[4]));
- }
- DONE;
-}
- [(set_attr "type" "fistp")
- (set_attr "i387_cw" "<rounding>")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "fistdi2_<rounding>"
- [(set (match_operand:DI 0 "memory_operand" "=m")
- (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
- FIST_ROUNDING))
- (use (match_operand:HI 2 "memory_operand" "m"))
- (use (match_operand:HI 3 "memory_operand" "m"))
- (clobber (match_scratch:XF 4 "=&1f"))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
- "* return output_fix_trunc (insn, operands, false);"
- [(set_attr "type" "fistp")
- (set_attr "i387_cw" "<rounding>")
- (set_attr "mode" "DI")])
-
-(define_insn "fistdi2_<rounding>_with_temp"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
- (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
- FIST_ROUNDING))
- (use (match_operand:HI 2 "memory_operand" "m,m"))
- (use (match_operand:HI 3 "memory_operand" "m,m"))
- (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
- (clobber (match_scratch:XF 5 "=&1f,&1f"))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
- "#"
- [(set_attr "type" "fistp")
- (set_attr "i387_cw" "<rounding>")
- (set_attr "mode" "DI")])
-
-(define_split
- [(set (match_operand:DI 0 "register_operand")
- (unspec:DI [(match_operand:XF 1 "register_operand")]
- FIST_ROUNDING))
- (use (match_operand:HI 2 "memory_operand"))
- (use (match_operand:HI 3 "memory_operand"))
- (clobber (match_operand:DI 4 "memory_operand"))
- (clobber (match_scratch 5))]
- "reload_completed"
- [(parallel [(set (match_dup 4)
- (unspec:DI [(match_dup 1)] FIST_ROUNDING))
- (use (match_dup 2))
- (use (match_dup 3))
- (clobber (match_dup 5))])
- (set (match_dup 0) (match_dup 4))])
-
-(define_split
- [(set (match_operand:DI 0 "memory_operand")
- (unspec:DI [(match_operand:XF 1 "register_operand")]
- FIST_ROUNDING))
- (use (match_operand:HI 2 "memory_operand"))
- (use (match_operand:HI 3 "memory_operand"))
- (clobber (match_operand:DI 4 "memory_operand"))
- (clobber (match_scratch 5))]
- "reload_completed"
- [(parallel [(set (match_dup 0)
- (unspec:DI [(match_dup 1)] FIST_ROUNDING))
- (use (match_dup 2))
- (use (match_dup 3))
- (clobber (match_dup 5))])])
-
-(define_insn "fist<mode>2_<rounding>"
- [(set (match_operand:SWI24 0 "memory_operand" "=m")
- (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
- FIST_ROUNDING))
- (use (match_operand:HI 2 "memory_operand" "m"))
- (use (match_operand:HI 3 "memory_operand" "m"))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
- "* return output_fix_trunc (insn, operands, false);"
- [(set_attr "type" "fistp")
- (set_attr "i387_cw" "<rounding>")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "fist<mode>2_<rounding>_with_temp"
- [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
- (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
- FIST_ROUNDING))
- (use (match_operand:HI 2 "memory_operand" "m,m"))
- (use (match_operand:HI 3 "memory_operand" "m,m"))
- (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
- "#"
- [(set_attr "type" "fistp")
- (set_attr "i387_cw" "<rounding>")
- (set_attr "mode" "<MODE>")])
-
-(define_split
- [(set (match_operand:SWI24 0 "register_operand")
- (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
- FIST_ROUNDING))
- (use (match_operand:HI 2 "memory_operand"))
- (use (match_operand:HI 3 "memory_operand"))
- (clobber (match_operand:SWI24 4 "memory_operand"))]
- "reload_completed"
- [(parallel [(set (match_dup 4)
- (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
- (use (match_dup 2))
- (use (match_dup 3))])
- (set (match_dup 0) (match_dup 4))])
-
-(define_split
- [(set (match_operand:SWI24 0 "memory_operand")
- (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
- FIST_ROUNDING))
- (use (match_operand:HI 2 "memory_operand"))
- (use (match_operand:HI 3 "memory_operand"))
- (clobber (match_operand:SWI24 4 "memory_operand"))]
- "reload_completed"
- [(parallel [(set (match_dup 0)
- (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
- (use (match_dup 2))
- (use (match_dup 3))])])
-
-(define_expand "l<rounding_insn>xf<mode>2"
- [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
- (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
- FIST_ROUNDING))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_USE_FANCY_MATH_387
- && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
- && flag_unsafe_math_optimizations")
-
-(define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
- [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
- (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
- FIST_ROUNDING))
- (clobber (reg:CC FLAGS_REG))])]
- "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
- && !flag_trapping_math"
-{
- if (TARGET_64BIT && optimize_insn_for_size_p ())
- FAIL;
-
- if (ROUND_<ROUNDING> == ROUND_FLOOR)
- ix86_expand_lfloorceil (operands[0], operands[1], true);
- else if (ROUND_<ROUNDING> == ROUND_CEIL)
- ix86_expand_lfloorceil (operands[0], operands[1], false);
- else
- gcc_unreachable ();
-
- DONE;
-})
-
-(define_insn "fxam<mode>2_i387"
- [(set (match_operand:HI 0 "register_operand" "=a")
- (unspec:HI
- [(match_operand:X87MODEF 1 "register_operand" "f")]
- UNSPEC_FXAM))]
- "TARGET_USE_FANCY_MATH_387"
- "fxam\n\tfnstsw\t%0"
- [(set_attr "type" "multi")
- (set_attr "length" "4")
- (set_attr "unit" "i387")
- (set_attr "mode" "<MODE>")])
-
-(define_insn_and_split "fxam<mode>2_i387_with_temp"
- [(set (match_operand:HI 0 "register_operand")
- (unspec:HI
- [(match_operand:MODEF 1 "memory_operand")]
- UNSPEC_FXAM_MEM))]
- "TARGET_USE_FANCY_MATH_387
- && can_create_pseudo_p ()"
- "#"
- "&& 1"
- [(set (match_dup 2)(match_dup 1))
- (set (match_dup 0)
- (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
-{
- operands[2] = gen_reg_rtx (<MODE>mode);
-
- MEM_VOLATILE_P (operands[1]) = 1;
-}
- [(set_attr "type" "multi")
- (set_attr "unit" "i387")
- (set_attr "mode" "<MODE>")])
-
-(define_expand "isinfxf2"
- [(use (match_operand:SI 0 "register_operand"))
- (use (match_operand:XF 1 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && TARGET_C99_FUNCTIONS"
-{
- rtx mask = GEN_INT (0x45);
- rtx val = GEN_INT (0x05);
-
- rtx cond;
-
- rtx scratch = gen_reg_rtx (HImode);
- rtx res = gen_reg_rtx (QImode);
-
- emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
-
- emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
- emit_insn (gen_cmpqi_ext_3 (scratch, val));
- cond = gen_rtx_fmt_ee (EQ, QImode,
- gen_rtx_REG (CCmode, FLAGS_REG),
- const0_rtx);
- emit_insn (gen_rtx_SET (VOIDmode, res, cond));
- emit_insn (gen_zero_extendqisi2 (operands[0], res));
- DONE;
-})
-
-(define_expand "isinf<mode>2"
- [(use (match_operand:SI 0 "register_operand"))
- (use (match_operand:MODEF 1 "nonimmediate_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && TARGET_C99_FUNCTIONS
- && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
-{
- rtx mask = GEN_INT (0x45);
- rtx val = GEN_INT (0x05);
-
- rtx cond;
-
- rtx scratch = gen_reg_rtx (HImode);
- rtx res = gen_reg_rtx (QImode);
-
- /* Remove excess precision by forcing value through memory. */
- if (memory_operand (operands[1], VOIDmode))
- emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
- else
- {
- rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
-
- emit_move_insn (temp, operands[1]);
- emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
- }
-
- emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
- emit_insn (gen_cmpqi_ext_3 (scratch, val));
- cond = gen_rtx_fmt_ee (EQ, QImode,
- gen_rtx_REG (CCmode, FLAGS_REG),
- const0_rtx);
- emit_insn (gen_rtx_SET (VOIDmode, res, cond));
- emit_insn (gen_zero_extendqisi2 (operands[0], res));
- DONE;
-})
-
-(define_expand "signbitxf2"
- [(use (match_operand:SI 0 "register_operand"))
- (use (match_operand:XF 1 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387"
-{
- rtx scratch = gen_reg_rtx (HImode);
-
- emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
- emit_insn (gen_andsi3 (operands[0],
- gen_lowpart (SImode, scratch), GEN_INT (0x200)));
- DONE;
-})
-
-(define_insn "movmsk_df"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (unspec:SI
- [(match_operand:DF 1 "register_operand" "x")]
- UNSPEC_MOVMSK))]
- "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
- "%vmovmskpd\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssemov")
- (set_attr "prefix" "maybe_vex")
- (set_attr "mode" "DF")])
-
-;; Use movmskpd in SSE mode to avoid store forwarding stall
-;; for 32bit targets and movq+shrq sequence for 64bit targets.
-(define_expand "signbitdf2"
- [(use (match_operand:SI 0 "register_operand"))
- (use (match_operand:DF 1 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387
- || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
-{
- if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
- {
- emit_insn (gen_movmsk_df (operands[0], operands[1]));
- emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
- }
- else
- {
- rtx scratch = gen_reg_rtx (HImode);
-
- emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
- emit_insn (gen_andsi3 (operands[0],
- gen_lowpart (SImode, scratch), GEN_INT (0x200)));
- }
- DONE;
-})
-
-(define_expand "signbitsf2"
- [(use (match_operand:SI 0 "register_operand"))
- (use (match_operand:SF 1 "register_operand"))]
- "TARGET_USE_FANCY_MATH_387
- && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
-{
- rtx scratch = gen_reg_rtx (HImode);
-
- emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
- emit_insn (gen_andsi3 (operands[0],
- gen_lowpart (SImode, scratch), GEN_INT (0x200)));
- DONE;
-})
-
-;; Block operation instructions
-
-(define_insn "cld"
- [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
- ""
- "cld"
- [(set_attr "length" "1")
- (set_attr "length_immediate" "0")
- (set_attr "modrm" "0")])
-
-(define_expand "movmem<mode>"
- [(use (match_operand:BLK 0 "memory_operand"))
- (use (match_operand:BLK 1 "memory_operand"))
- (use (match_operand:SWI48 2 "nonmemory_operand"))
- (use (match_operand:SWI48 3 "const_int_operand"))
- (use (match_operand:SI 4 "const_int_operand"))
- (use (match_operand:SI 5 "const_int_operand"))]
- ""
-{
- if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
- operands[4], operands[5]))
- DONE;
- else
- FAIL;
-})
-
-;; Most CPUs don't like single string operations
-;; Handle this case here to simplify previous expander.
-
-(define_expand "strmov"
- [(set (match_dup 4) (match_operand 3 "memory_operand"))
- (set (match_operand 1 "memory_operand") (match_dup 4))
- (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
- (clobber (reg:CC FLAGS_REG))])
- (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
- (clobber (reg:CC FLAGS_REG))])]
- ""
-{
- rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
-
- /* If .md ever supports :P for Pmode, these can be directly
- in the pattern above. */
- operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
- operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
-
- /* Can't use this if the user has appropriated esi or edi. */
- if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
- && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
- {
- emit_insn (gen_strmov_singleop (operands[0], operands[1],
- operands[2], operands[3],
- operands[5], operands[6]));
- DONE;
- }
-
- operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
-})
-
-(define_expand "strmov_singleop"
- [(parallel [(set (match_operand 1 "memory_operand")
- (match_operand 3 "memory_operand"))
- (set (match_operand 0 "register_operand")
- (match_operand 4))
- (set (match_operand 2 "register_operand")
- (match_operand 5))])]
- ""
- "ix86_current_function_needs_cld = 1;")
-
-(define_insn "*strmovdi_rex_1"
- [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
- (mem:DI (match_operand:P 3 "register_operand" "1")))
- (set (match_operand:P 0 "register_operand" "=D")
- (plus:P (match_dup 2)
- (const_int 8)))
- (set (match_operand:P 1 "register_operand" "=S")
- (plus:P (match_dup 3)
- (const_int 8)))]
- "TARGET_64BIT
- && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
- "%^movsq"
- [(set_attr "type" "str")
- (set_attr "memory" "both")
- (set_attr "mode" "DI")])
-
-(define_insn "*strmovsi_1"
- [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
- (mem:SI (match_operand:P 3 "register_operand" "1")))
- (set (match_operand:P 0 "register_operand" "=D")
- (plus:P (match_dup 2)
- (const_int 4)))
- (set (match_operand:P 1 "register_operand" "=S")
- (plus:P (match_dup 3)
- (const_int 4)))]
- "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
- "%^movs{l|d}"
- [(set_attr "type" "str")
- (set_attr "memory" "both")
- (set_attr "mode" "SI")])
-
-(define_insn "*strmovhi_1"
- [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
- (mem:HI (match_operand:P 3 "register_operand" "1")))
- (set (match_operand:P 0 "register_operand" "=D")
- (plus:P (match_dup 2)
- (const_int 2)))
- (set (match_operand:P 1 "register_operand" "=S")
- (plus:P (match_dup 3)
- (const_int 2)))]
- "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
- "%^movsw"
- [(set_attr "type" "str")
- (set_attr "memory" "both")
- (set_attr "mode" "HI")])
-
-(define_insn "*strmovqi_1"
- [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
- (mem:QI (match_operand:P 3 "register_operand" "1")))
- (set (match_operand:P 0 "register_operand" "=D")
- (plus:P (match_dup 2)
- (const_int 1)))
- (set (match_operand:P 1 "register_operand" "=S")
- (plus:P (match_dup 3)
- (const_int 1)))]
- "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
- "%^movsb"
- [(set_attr "type" "str")
- (set_attr "memory" "both")
- (set (attr "prefix_rex")
- (if_then_else
- (match_test "<P:MODE>mode == DImode")
- (const_string "0")
- (const_string "*")))
- (set_attr "mode" "QI")])
-
-(define_expand "rep_mov"
- [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
- (set (match_operand 0 "register_operand")
- (match_operand 5))
- (set (match_operand 2 "register_operand")
- (match_operand 6))
- (set (match_operand 1 "memory_operand")
- (match_operand 3 "memory_operand"))
- (use (match_dup 4))])]
- ""
- "ix86_current_function_needs_cld = 1;")
-
-(define_insn "*rep_movdi_rex64"
- [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
- (set (match_operand:P 0 "register_operand" "=D")
- (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
- (const_int 3))
- (match_operand:P 3 "register_operand" "0")))
- (set (match_operand:P 1 "register_operand" "=S")
- (plus:P (ashift:P (match_dup 5) (const_int 3))
- (match_operand:P 4 "register_operand" "1")))
- (set (mem:BLK (match_dup 3))
- (mem:BLK (match_dup 4)))
- (use (match_dup 5))]
- "TARGET_64BIT
- && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
- "%^rep{%;} movsq"
- [(set_attr "type" "str")
- (set_attr "prefix_rep" "1")
- (set_attr "memory" "both")
- (set_attr "mode" "DI")])
-
-(define_insn "*rep_movsi"
- [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
- (set (match_operand:P 0 "register_operand" "=D")
- (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
- (const_int 2))
- (match_operand:P 3 "register_operand" "0")))
- (set (match_operand:P 1 "register_operand" "=S")
- (plus:P (ashift:P (match_dup 5) (const_int 2))
- (match_operand:P 4 "register_operand" "1")))
- (set (mem:BLK (match_dup 3))
- (mem:BLK (match_dup 4)))
- (use (match_dup 5))]
- "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
- "%^rep{%;} movs{l|d}"
- [(set_attr "type" "str")
- (set_attr "prefix_rep" "1")
- (set_attr "memory" "both")
- (set_attr "mode" "SI")])
-
-(define_insn "*rep_movqi"
- [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
- (set (match_operand:P 0 "register_operand" "=D")
- (plus:P (match_operand:P 3 "register_operand" "0")
- (match_operand:P 5 "register_operand" "2")))
- (set (match_operand:P 1 "register_operand" "=S")
- (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
- (set (mem:BLK (match_dup 3))
- (mem:BLK (match_dup 4)))
- (use (match_dup 5))]
- "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
- "%^rep{%;} movsb"
- [(set_attr "type" "str")
- (set_attr "prefix_rep" "1")
- (set_attr "memory" "both")
- (set_attr "mode" "QI")])
-
-(define_expand "setmem<mode>"
- [(use (match_operand:BLK 0 "memory_operand"))
- (use (match_operand:SWI48 1 "nonmemory_operand"))
- (use (match_operand:QI 2 "nonmemory_operand"))
- (use (match_operand 3 "const_int_operand"))
- (use (match_operand:SI 4 "const_int_operand"))
- (use (match_operand:SI 5 "const_int_operand"))]
- ""
-{
- if (ix86_expand_setmem (operands[0], operands[1],
- operands[2], operands[3],
- operands[4], operands[5]))
- DONE;
- else
- FAIL;
-})
-
-;; Most CPUs don't like single string operations
-;; Handle this case here to simplify previous expander.
-
-(define_expand "strset"
- [(set (match_operand 1 "memory_operand")
- (match_operand 2 "register_operand"))
- (parallel [(set (match_operand 0 "register_operand")
- (match_dup 3))
- (clobber (reg:CC FLAGS_REG))])]
- ""
-{
- if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
- operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
-
- /* If .md ever supports :P for Pmode, this can be directly
- in the pattern above. */
- operands[3] = gen_rtx_PLUS (Pmode, operands[0],
- GEN_INT (GET_MODE_SIZE (GET_MODE
- (operands[2]))));
- /* Can't use this if the user has appropriated eax or edi. */
- if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
- && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
- {
- emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
- operands[3]));
- DONE;
- }
-})
-
-(define_expand "strset_singleop"
- [(parallel [(set (match_operand 1 "memory_operand")
- (match_operand 2 "register_operand"))
- (set (match_operand 0 "register_operand")
- (match_operand 3))
- (unspec [(const_int 0)] UNSPEC_STOS)])]
- ""
- "ix86_current_function_needs_cld = 1;")
-
-(define_insn "*strsetdi_rex_1"
- [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
- (match_operand:DI 2 "register_operand" "a"))
- (set (match_operand:P 0 "register_operand" "=D")
- (plus:P (match_dup 1)
- (const_int 8)))
- (unspec [(const_int 0)] UNSPEC_STOS)]
- "TARGET_64BIT
- && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
- "%^stosq"
- [(set_attr "type" "str")
- (set_attr "memory" "store")
- (set_attr "mode" "DI")])
-
-(define_insn "*strsetsi_1"
- [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
- (match_operand:SI 2 "register_operand" "a"))
- (set (match_operand:P 0 "register_operand" "=D")
- (plus:P (match_dup 1)
- (const_int 4)))
- (unspec [(const_int 0)] UNSPEC_STOS)]
- "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
- "%^stos{l|d}"
- [(set_attr "type" "str")
- (set_attr "memory" "store")
- (set_attr "mode" "SI")])
-
-(define_insn "*strsethi_1"
- [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
- (match_operand:HI 2 "register_operand" "a"))
- (set (match_operand:P 0 "register_operand" "=D")
- (plus:P (match_dup 1)
- (const_int 2)))
- (unspec [(const_int 0)] UNSPEC_STOS)]
- "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
- "%^stosw"
- [(set_attr "type" "str")
- (set_attr "memory" "store")
- (set_attr "mode" "HI")])
-
-(define_insn "*strsetqi_1"
- [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
- (match_operand:QI 2 "register_operand" "a"))
- (set (match_operand:P 0 "register_operand" "=D")
- (plus:P (match_dup 1)
- (const_int 1)))
- (unspec [(const_int 0)] UNSPEC_STOS)]
- "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
- "%^stosb"
- [(set_attr "type" "str")
- (set_attr "memory" "store")
- (set (attr "prefix_rex")
- (if_then_else
- (match_test "<P:MODE>mode == DImode")
- (const_string "0")
- (const_string "*")))
- (set_attr "mode" "QI")])
-
-(define_expand "rep_stos"
- [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
- (set (match_operand 0 "register_operand")
- (match_operand 4))
- (set (match_operand 2 "memory_operand") (const_int 0))
- (use (match_operand 3 "register_operand"))
- (use (match_dup 1))])]
- ""
- "ix86_current_function_needs_cld = 1;")
-
-(define_insn "*rep_stosdi_rex64"
- [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
- (set (match_operand:P 0 "register_operand" "=D")
- (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
- (const_int 3))
- (match_operand:P 3 "register_operand" "0")))
- (set (mem:BLK (match_dup 3))
- (const_int 0))
- (use (match_operand:DI 2 "register_operand" "a"))
- (use (match_dup 4))]
- "TARGET_64BIT
- && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
- "%^rep{%;} stosq"
- [(set_attr "type" "str")
- (set_attr "prefix_rep" "1")
- (set_attr "memory" "store")
- (set_attr "mode" "DI")])
-
-(define_insn "*rep_stossi"
- [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
- (set (match_operand:P 0 "register_operand" "=D")
- (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
- (const_int 2))
- (match_operand:P 3 "register_operand" "0")))
- (set (mem:BLK (match_dup 3))
- (const_int 0))
- (use (match_operand:SI 2 "register_operand" "a"))
- (use (match_dup 4))]
- "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
- "%^rep{%;} stos{l|d}"
- [(set_attr "type" "str")
- (set_attr "prefix_rep" "1")
- (set_attr "memory" "store")
- (set_attr "mode" "SI")])
-
-(define_insn "*rep_stosqi"
- [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
- (set (match_operand:P 0 "register_operand" "=D")
- (plus:P (match_operand:P 3 "register_operand" "0")
- (match_operand:P 4 "register_operand" "1")))
- (set (mem:BLK (match_dup 3))
- (const_int 0))
- (use (match_operand:QI 2 "register_operand" "a"))
- (use (match_dup 4))]
- "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
- "%^rep{%;} stosb"
- [(set_attr "type" "str")
- (set_attr "prefix_rep" "1")
- (set_attr "memory" "store")
- (set (attr "prefix_rex")
- (if_then_else
- (match_test "<P:MODE>mode == DImode")
- (const_string "0")
- (const_string "*")))
- (set_attr "mode" "QI")])
-
-(define_expand "cmpstrnsi"
- [(set (match_operand:SI 0 "register_operand")
- (compare:SI (match_operand:BLK 1 "general_operand")
- (match_operand:BLK 2 "general_operand")))
- (use (match_operand 3 "general_operand"))
- (use (match_operand 4 "immediate_operand"))]
- ""
-{
- rtx addr1, addr2, out, outlow, count, countreg, align;
-
- if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
- FAIL;
-
- /* Can't use this if the user has appropriated ecx, esi or edi. */
- if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
- FAIL;
-
- out = operands[0];
- if (!REG_P (out))
- out = gen_reg_rtx (SImode);
-
- addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
- addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
- if (addr1 != XEXP (operands[1], 0))
- operands[1] = replace_equiv_address_nv (operands[1], addr1);
- if (addr2 != XEXP (operands[2], 0))
- operands[2] = replace_equiv_address_nv (operands[2], addr2);
-
- count = operands[3];
- countreg = ix86_zero_extend_to_Pmode (count);
-
- /* %%% Iff we are testing strict equality, we can use known alignment
- to good advantage. This may be possible with combine, particularly
- once cc0 is dead. */
- align = operands[4];
-
- if (CONST_INT_P (count))
- {
- if (INTVAL (count) == 0)
- {
- emit_move_insn (operands[0], const0_rtx);
- DONE;
- }
- emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
- operands[1], operands[2]));
- }
- else
- {
- rtx (*gen_cmp) (rtx, rtx);
-
- gen_cmp = (TARGET_64BIT
- ? gen_cmpdi_1 : gen_cmpsi_1);
-
- emit_insn (gen_cmp (countreg, countreg));
- emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
- operands[1], operands[2]));
- }
-
- outlow = gen_lowpart (QImode, out);
- emit_insn (gen_cmpintqi (outlow));
- emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
-
- if (operands[0] != out)
- emit_move_insn (operands[0], out);
-
- DONE;
-})
-
-;; Produce a tri-state integer (-1, 0, 1) from condition codes.
-
-(define_expand "cmpintqi"
- [(set (match_dup 1)
- (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
- (set (match_dup 2)
- (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
- (parallel [(set (match_operand:QI 0 "register_operand")
- (minus:QI (match_dup 1)
- (match_dup 2)))
- (clobber (reg:CC FLAGS_REG))])]
- ""
-{
- operands[1] = gen_reg_rtx (QImode);
- operands[2] = gen_reg_rtx (QImode);
-})
-
-;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
-;; zero. Emit extra code to make sure that a zero-length compare is EQ.
-
-(define_expand "cmpstrnqi_nz_1"
- [(parallel [(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand 4 "memory_operand")
- (match_operand 5 "memory_operand")))
- (use (match_operand 2 "register_operand"))
- (use (match_operand:SI 3 "immediate_operand"))
- (clobber (match_operand 0 "register_operand"))
- (clobber (match_operand 1 "register_operand"))
- (clobber (match_dup 2))])]
- ""
- "ix86_current_function_needs_cld = 1;")
-
-(define_insn "*cmpstrnqi_nz_1"
- [(set (reg:CC FLAGS_REG)
- (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
- (mem:BLK (match_operand:P 5 "register_operand" "1"))))
- (use (match_operand:P 6 "register_operand" "2"))
- (use (match_operand:SI 3 "immediate_operand" "i"))
- (clobber (match_operand:P 0 "register_operand" "=S"))
- (clobber (match_operand:P 1 "register_operand" "=D"))
- (clobber (match_operand:P 2 "register_operand" "=c"))]
- "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
- "%^repz{%;} cmpsb"
- [(set_attr "type" "str")
- (set_attr "mode" "QI")
- (set (attr "prefix_rex")
- (if_then_else
- (match_test "<P:MODE>mode == DImode")
- (const_string "0")
- (const_string "*")))
- (set_attr "prefix_rep" "1")])
-
-;; The same, but the count is not known to not be zero.
-
-(define_expand "cmpstrnqi_1"
- [(parallel [(set (reg:CC FLAGS_REG)
- (if_then_else:CC (ne (match_operand 2 "register_operand")
- (const_int 0))
- (compare:CC (match_operand 4 "memory_operand")
- (match_operand 5 "memory_operand"))
- (const_int 0)))
- (use (match_operand:SI 3 "immediate_operand"))
- (use (reg:CC FLAGS_REG))
- (clobber (match_operand 0 "register_operand"))
- (clobber (match_operand 1 "register_operand"))
- (clobber (match_dup 2))])]
- ""
- "ix86_current_function_needs_cld = 1;")
-
-(define_insn "*cmpstrnqi_1"
- [(set (reg:CC FLAGS_REG)
- (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
- (const_int 0))
- (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
- (mem:BLK (match_operand:P 5 "register_operand" "1")))
- (const_int 0)))
- (use (match_operand:SI 3 "immediate_operand" "i"))
- (use (reg:CC FLAGS_REG))
- (clobber (match_operand:P 0 "register_operand" "=S"))
- (clobber (match_operand:P 1 "register_operand" "=D"))
- (clobber (match_operand:P 2 "register_operand" "=c"))]
- "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
- "%^repz{%;} cmpsb"
- [(set_attr "type" "str")
- (set_attr "mode" "QI")
- (set (attr "prefix_rex")
- (if_then_else
- (match_test "<P:MODE>mode == DImode")
- (const_string "0")
- (const_string "*")))
- (set_attr "prefix_rep" "1")])
-
-(define_expand "strlen<mode>"
- [(set (match_operand:P 0 "register_operand")
- (unspec:P [(match_operand:BLK 1 "general_operand")
- (match_operand:QI 2 "immediate_operand")
- (match_operand 3 "immediate_operand")]
- UNSPEC_SCAS))]
- ""
-{
- if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
- DONE;
- else
- FAIL;
-})
-
-(define_expand "strlenqi_1"
- [(parallel [(set (match_operand 0 "register_operand")
- (match_operand 2))
- (clobber (match_operand 1 "register_operand"))
- (clobber (reg:CC FLAGS_REG))])]
- ""
- "ix86_current_function_needs_cld = 1;")
-
-(define_insn "*strlenqi_1"
- [(set (match_operand:P 0 "register_operand" "=&c")
- (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
- (match_operand:QI 2 "register_operand" "a")
- (match_operand:P 3 "immediate_operand" "i")
- (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
- (clobber (match_operand:P 1 "register_operand" "=D"))
- (clobber (reg:CC FLAGS_REG))]
- "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
- "%^repnz{%;} scasb"
- [(set_attr "type" "str")
- (set_attr "mode" "QI")
- (set (attr "prefix_rex")
- (if_then_else
- (match_test "<P:MODE>mode == DImode")
- (const_string "0")
- (const_string "*")))
- (set_attr "prefix_rep" "1")])
-
-;; Peephole optimizations to clean up after cmpstrn*. This should be
-;; handled in combine, but it is not currently up to the task.
-;; When used for their truth value, the cmpstrn* expanders generate
-;; code like this:
-;;
-;; repz cmpsb
-;; seta %al
-;; setb %dl
-;; cmpb %al, %dl
-;; jcc label
-;;
-;; The intermediate three instructions are unnecessary.
-
-;; This one handles cmpstrn*_nz_1...
-(define_peephole2
- [(parallel[
- (set (reg:CC FLAGS_REG)
- (compare:CC (mem:BLK (match_operand 4 "register_operand"))
- (mem:BLK (match_operand 5 "register_operand"))))
- (use (match_operand 6 "register_operand"))
- (use (match_operand:SI 3 "immediate_operand"))
- (clobber (match_operand 0 "register_operand"))
- (clobber (match_operand 1 "register_operand"))
- (clobber (match_operand 2 "register_operand"))])
- (set (match_operand:QI 7 "register_operand")
- (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
- (set (match_operand:QI 8 "register_operand")
- (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
- (set (reg FLAGS_REG)
- (compare (match_dup 7) (match_dup 8)))
- ]
- "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
- [(parallel[
- (set (reg:CC FLAGS_REG)
- (compare:CC (mem:BLK (match_dup 4))
- (mem:BLK (match_dup 5))))
- (use (match_dup 6))
- (use (match_dup 3))
- (clobber (match_dup 0))
- (clobber (match_dup 1))
- (clobber (match_dup 2))])])
-
-;; ...and this one handles cmpstrn*_1.
-(define_peephole2
- [(parallel[
- (set (reg:CC FLAGS_REG)
- (if_then_else:CC (ne (match_operand 6 "register_operand")
- (const_int 0))
- (compare:CC (mem:BLK (match_operand 4 "register_operand"))
- (mem:BLK (match_operand 5 "register_operand")))
- (const_int 0)))
- (use (match_operand:SI 3 "immediate_operand"))
- (use (reg:CC FLAGS_REG))
- (clobber (match_operand 0 "register_operand"))
- (clobber (match_operand 1 "register_operand"))
- (clobber (match_operand 2 "register_operand"))])
- (set (match_operand:QI 7 "register_operand")
- (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
- (set (match_operand:QI 8 "register_operand")
- (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
- (set (reg FLAGS_REG)
- (compare (match_dup 7) (match_dup 8)))
- ]
- "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
- [(parallel[
- (set (reg:CC FLAGS_REG)
- (if_then_else:CC (ne (match_dup 6)
- (const_int 0))
- (compare:CC (mem:BLK (match_dup 4))
- (mem:BLK (match_dup 5)))
- (const_int 0)))
- (use (match_dup 3))
- (use (reg:CC FLAGS_REG))
- (clobber (match_dup 0))
- (clobber (match_dup 1))
- (clobber (match_dup 2))])])
-
-;; Conditional move instructions.
-
-(define_expand "mov<mode>cc"
- [(set (match_operand:SWIM 0 "register_operand")
- (if_then_else:SWIM (match_operand 1 "comparison_operator")
- (match_operand:SWIM 2 "<general_operand>")
- (match_operand:SWIM 3 "<general_operand>")))]
- ""
- "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
-
-;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
-;; the register first winds up with `sbbl $0,reg', which is also weird.
-;; So just document what we're doing explicitly.
-
-(define_expand "x86_mov<mode>cc_0_m1"
- [(parallel
- [(set (match_operand:SWI48 0 "register_operand")
- (if_then_else:SWI48
- (match_operator:SWI48 2 "ix86_carry_flag_operator"
- [(match_operand 1 "flags_reg_operand")
- (const_int 0)])
- (const_int -1)
- (const_int 0)))
- (clobber (reg:CC FLAGS_REG))])])
-
-(define_insn "*x86_mov<mode>cc_0_m1"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (const_int -1)
- (const_int 0)))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "sbb{<imodesuffix>}\t%0, %0"
- ; Since we don't have the proper number of operands for an alu insn,
- ; fill in all the blanks.
- [(set_attr "type" "alu")
- (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "memory" "none")
- (set_attr "imm_disp" "false")
- (set_attr "mode" "<MODE>")
- (set_attr "length_immediate" "0")])
-
-(define_insn "*x86_mov<mode>cc_0_m1_se"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (const_int 1)
- (const_int 0)))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "sbb{<imodesuffix>}\t%0, %0"
- [(set_attr "type" "alu")
- (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "memory" "none")
- (set_attr "imm_disp" "false")
- (set_attr "mode" "<MODE>")
- (set_attr "length_immediate" "0")])
-
-(define_insn "*x86_mov<mode>cc_0_m1_neg"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
- [(reg FLAGS_REG) (const_int 0)])))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "sbb{<imodesuffix>}\t%0, %0"
- [(set_attr "type" "alu")
- (set_attr "use_carry" "1")
- (set_attr "pent_pair" "pu")
- (set_attr "memory" "none")
- (set_attr "imm_disp" "false")
- (set_attr "mode" "<MODE>")
- (set_attr "length_immediate" "0")])
-
-(define_insn "*mov<mode>cc_noc"
- [(set (match_operand:SWI248 0 "register_operand" "=r,r")
- (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
- (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
- "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
- "@
- cmov%O2%C1\t{%2, %0|%0, %2}
- cmov%O2%c1\t{%3, %0|%0, %3}"
- [(set_attr "type" "icmov")
- (set_attr "mode" "<MODE>")])
-
-;; Don't do conditional moves with memory inputs. This splitter helps
-;; register starved x86_32 by forcing inputs into registers before reload.
-(define_split
- [(set (match_operand:SWI248 0 "register_operand")
- (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (match_operand:SWI248 2 "nonimmediate_operand")
- (match_operand:SWI248 3 "nonimmediate_operand")))]
- "!TARGET_64BIT && TARGET_CMOVE
- && TARGET_AVOID_MEM_OPND_FOR_CMOVE
- && (MEM_P (operands[2]) || MEM_P (operands[3]))
- && can_create_pseudo_p ()
- && optimize_insn_for_speed_p ()"
- [(set (match_dup 0)
- (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
-{
- if (MEM_P (operands[2]))
- operands[2] = force_reg (<MODE>mode, operands[2]);
- if (MEM_P (operands[3]))
- operands[3] = force_reg (<MODE>mode, operands[3]);
-})
-
-(define_insn "*movqicc_noc"
- [(set (match_operand:QI 0 "register_operand" "=r,r")
- (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (match_operand:QI 2 "register_operand" "r,0")
- (match_operand:QI 3 "register_operand" "0,r")))]
- "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
- "#"
- [(set_attr "type" "icmov")
- (set_attr "mode" "QI")])
-
-(define_split
- [(set (match_operand:SWI12 0 "register_operand")
- (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (match_operand:SWI12 2 "register_operand")
- (match_operand:SWI12 3 "register_operand")))]
- "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
- && reload_completed"
- [(set (match_dup 0)
- (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
-{
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- operands[3] = gen_lowpart (SImode, operands[3]);
-})
-
-;; Don't do conditional moves with memory inputs
-(define_peephole2
- [(match_scratch:SWI248 2 "r")
- (set (match_operand:SWI248 0 "register_operand")
- (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (match_dup 0)
- (match_operand:SWI248 3 "memory_operand")))]
- "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
- && optimize_insn_for_speed_p ()"
- [(set (match_dup 2) (match_dup 3))
- (set (match_dup 0)
- (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
-
-(define_peephole2
- [(match_scratch:SWI248 2 "r")
- (set (match_operand:SWI248 0 "register_operand")
- (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (match_operand:SWI248 3 "memory_operand")
- (match_dup 0)))]
- "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
- && optimize_insn_for_speed_p ()"
- [(set (match_dup 2) (match_dup 3))
- (set (match_dup 0)
- (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
-
-(define_expand "mov<mode>cc"
- [(set (match_operand:X87MODEF 0 "register_operand")
- (if_then_else:X87MODEF
- (match_operand 1 "comparison_operator")
- (match_operand:X87MODEF 2 "register_operand")
- (match_operand:X87MODEF 3 "register_operand")))]
- "(TARGET_80387 && TARGET_CMOVE)
- || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
- "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
-
-(define_insn "*movxfcc_1"
- [(set (match_operand:XF 0 "register_operand" "=f,f")
- (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (match_operand:XF 2 "register_operand" "f,0")
- (match_operand:XF 3 "register_operand" "0,f")))]
- "TARGET_80387 && TARGET_CMOVE"
- "@
- fcmov%F1\t{%2, %0|%0, %2}
- fcmov%f1\t{%3, %0|%0, %3}"
- [(set_attr "type" "fcmov")
- (set_attr "mode" "XF")])
-
-(define_insn "*movdfcc_1_rex64"
- [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
- (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
- (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
- "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
- && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
- "@
- fcmov%F1\t{%2, %0|%0, %2}
- fcmov%f1\t{%3, %0|%0, %3}
- cmov%O2%C1\t{%2, %0|%0, %2}
- cmov%O2%c1\t{%3, %0|%0, %3}"
- [(set_attr "type" "fcmov,fcmov,icmov,icmov")
- (set_attr "mode" "DF,DF,DI,DI")])
-
-(define_insn "*movdfcc_1"
- [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
- (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
- (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
- "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
- && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
- "@
- fcmov%F1\t{%2, %0|%0, %2}
- fcmov%f1\t{%3, %0|%0, %3}
- #
- #"
- [(set_attr "type" "fcmov,fcmov,multi,multi")
- (set_attr "mode" "DF,DF,DI,DI")])
-
-(define_split
- [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
- (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (match_operand:DF 2 "nonimmediate_operand")
- (match_operand:DF 3 "nonimmediate_operand")))]
- "!TARGET_64BIT && reload_completed"
- [(set (match_dup 2)
- (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
- (set (match_dup 3)
- (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
-{
- split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
- split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
-})
-
-(define_insn "*movsfcc_1_387"
- [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
- (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
- (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
- "TARGET_80387 && TARGET_CMOVE
- && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
- "@
- fcmov%F1\t{%2, %0|%0, %2}
- fcmov%f1\t{%3, %0|%0, %3}
- cmov%O2%C1\t{%2, %0|%0, %2}
- cmov%O2%c1\t{%3, %0|%0, %3}"
- [(set_attr "type" "fcmov,fcmov,icmov,icmov")
- (set_attr "mode" "SF,SF,SI,SI")])
-
-;; Don't do conditional moves with memory inputs. This splitter helps
-;; register starved x86_32 by forcing inputs into registers before reload.
-(define_split
- [(set (match_operand:MODEF 0 "register_operand")
- (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (match_operand:MODEF 2 "nonimmediate_operand")
- (match_operand:MODEF 3 "nonimmediate_operand")))]
- "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
- && TARGET_AVOID_MEM_OPND_FOR_CMOVE
- && (MEM_P (operands[2]) || MEM_P (operands[3]))
- && can_create_pseudo_p ()
- && optimize_insn_for_speed_p ()"
- [(set (match_dup 0)
- (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
-{
- if (MEM_P (operands[2]))
- operands[2] = force_reg (<MODE>mode, operands[2]);
- if (MEM_P (operands[3]))
- operands[3] = force_reg (<MODE>mode, operands[3]);
-})
-
-;; Don't do conditional moves with memory inputs
-(define_peephole2
- [(match_scratch:MODEF 2 "r")
- (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
- (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (match_dup 0)
- (match_operand:MODEF 3 "memory_operand")))]
- "(<MODE>mode != DFmode || TARGET_64BIT)
- && TARGET_80387 && TARGET_CMOVE
- && TARGET_AVOID_MEM_OPND_FOR_CMOVE
- && optimize_insn_for_speed_p ()"
- [(set (match_dup 2) (match_dup 3))
- (set (match_dup 0)
- (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
-
-(define_peephole2
- [(match_scratch:MODEF 2 "r")
- (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
- (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (match_operand:MODEF 3 "memory_operand")
- (match_dup 0)))]
- "(<MODE>mode != DFmode || TARGET_64BIT)
- && TARGET_80387 && TARGET_CMOVE
- && TARGET_AVOID_MEM_OPND_FOR_CMOVE
- && optimize_insn_for_speed_p ()"
- [(set (match_dup 2) (match_dup 3))
- (set (match_dup 0)
- (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
-
-;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
-;; the scalar versions to have only XMM registers as operands.
-
-;; XOP conditional move
-(define_insn "*xop_pcmov_<mode>"
- [(set (match_operand:MODEF 0 "register_operand" "=x")
- (if_then_else:MODEF
- (match_operand:MODEF 1 "register_operand" "x")
- (match_operand:MODEF 2 "register_operand" "x")
- (match_operand:MODEF 3 "register_operand" "x")))]
- "TARGET_XOP"
- "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
- [(set_attr "type" "sse4arg")])
-
-;; These versions of the min/max patterns are intentionally ignorant of
-;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
-;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
-;; are undefined in this condition, we're certain this is correct.
-
-(define_insn "<code><mode>3"
- [(set (match_operand:MODEF 0 "register_operand" "=x,x")
- (smaxmin:MODEF
- (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
- (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
- "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
- "@
- <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
- v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "isa" "noavx,avx")
- (set_attr "prefix" "orig,vex")
- (set_attr "type" "sseadd")
- (set_attr "mode" "<MODE>")])
-
-;; These versions of the min/max patterns implement exactly the operations
-;; min = (op1 < op2 ? op1 : op2)
-;; max = (!(op1 < op2) ? op1 : op2)
-;; Their operands are not commutative, and thus they may be used in the
-;; presence of -0.0 and NaN.
-
-(define_int_iterator IEEE_MAXMIN
- [UNSPEC_IEEE_MAX
- UNSPEC_IEEE_MIN])
-
-(define_int_attr ieee_maxmin
- [(UNSPEC_IEEE_MAX "max")
- (UNSPEC_IEEE_MIN "min")])
-
-(define_insn "*ieee_s<ieee_maxmin><mode>3"
- [(set (match_operand:MODEF 0 "register_operand" "=x,x")
- (unspec:MODEF
- [(match_operand:MODEF 1 "register_operand" "0,x")
- (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
- IEEE_MAXMIN))]
- "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
- "@
- <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
- v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "isa" "noavx,avx")
- (set_attr "prefix" "orig,vex")
- (set_attr "type" "sseadd")
- (set_attr "mode" "<MODE>")])
-
-;; Make two stack loads independent:
-;; fld aa fld aa
-;; fld %st(0) -> fld bb
-;; fmul bb fmul %st(1), %st
-;;
-;; Actually we only match the last two instructions for simplicity.
-(define_peephole2
- [(set (match_operand 0 "fp_register_operand")
- (match_operand 1 "fp_register_operand"))
- (set (match_dup 0)
- (match_operator 2 "binary_fp_operator"
- [(match_dup 0)
- (match_operand 3 "memory_operand")]))]
- "REGNO (operands[0]) != REGNO (operands[1])"
- [(set (match_dup 0) (match_dup 3))
- (set (match_dup 0) (match_dup 4))]
-
- ;; The % modifier is not operational anymore in peephole2's, so we have to
- ;; swap the operands manually in the case of addition and multiplication.
-{
- rtx op0, op1;
-
- if (COMMUTATIVE_ARITH_P (operands[2]))
- op0 = operands[0], op1 = operands[1];
- else
- op0 = operands[1], op1 = operands[0];
-
- operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
- GET_MODE (operands[2]),
- op0, op1);
-})
-
-;; Conditional addition patterns
-(define_expand "add<mode>cc"
- [(match_operand:SWI 0 "register_operand")
- (match_operand 1 "ordered_comparison_operator")
- (match_operand:SWI 2 "register_operand")
- (match_operand:SWI 3 "const_int_operand")]
- ""
- "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
-
-;; Misc patterns (?)
-
-;; This pattern exists to put a dependency on all ebp-based memory accesses.
-;; Otherwise there will be nothing to keep
-;;
-;; [(set (reg ebp) (reg esp))]
-;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
-;; (clobber (eflags)]
-;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
-;;
-;; in proper program order.
-
-(define_insn "pro_epilogue_adjust_stack_<mode>_add"
- [(set (match_operand:P 0 "register_operand" "=r,r")
- (plus:P (match_operand:P 1 "register_operand" "0,r")
- (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
- (clobber (reg:CC FLAGS_REG))
- (clobber (mem:BLK (scratch)))]
- ""
-{
- switch (get_attr_type (insn))
- {
- case TYPE_IMOV:
- return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
-
- case TYPE_ALU:
- gcc_assert (rtx_equal_p (operands[0], operands[1]));
- if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
- return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
-
- return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
-
- default:
- operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
- return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
- }
-}
- [(set (attr "type")
- (cond [(and (eq_attr "alternative" "0")
- (not (match_test "TARGET_OPT_AGU")))
- (const_string "alu")
- (match_operand:<MODE> 2 "const0_operand")
- (const_string "imov")
- ]
- (const_string "lea")))
- (set (attr "length_immediate")
- (cond [(eq_attr "type" "imov")
- (const_string "0")
- (and (eq_attr "type" "alu")
- (match_operand 2 "const128_operand"))
- (const_string "1")
- ]
- (const_string "*")))
- (set_attr "mode" "<MODE>")])
-
-(define_insn "pro_epilogue_adjust_stack_<mode>_sub"
- [(set (match_operand:P 0 "register_operand" "=r")
- (minus:P (match_operand:P 1 "register_operand" "0")
- (match_operand:P 2 "register_operand" "r")))
- (clobber (reg:CC FLAGS_REG))
- (clobber (mem:BLK (scratch)))]
- ""
- "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "allocate_stack_worker_probe_<mode>"
- [(set (match_operand:P 0 "register_operand" "=a")
- (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
- UNSPECV_STACK_PROBE))
- (clobber (reg:CC FLAGS_REG))]
- "ix86_target_stack_probe ()"
- "call\t___chkstk_ms"
- [(set_attr "type" "multi")
- (set_attr "length" "5")])
-
-(define_expand "allocate_stack"
- [(match_operand 0 "register_operand")
- (match_operand 1 "general_operand")]
- "ix86_target_stack_probe ()"
-{
- rtx x;
-
-#ifndef CHECK_STACK_LIMIT
-#define CHECK_STACK_LIMIT 0
-#endif
-
- if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
- && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
- x = operands[1];
- else
- {
- rtx (*insn) (rtx, rtx);
-
- x = copy_to_mode_reg (Pmode, operands[1]);
-
- insn = (TARGET_64BIT
- ? gen_allocate_stack_worker_probe_di
- : gen_allocate_stack_worker_probe_si);
-
- emit_insn (insn (x, x));
- }
-
- x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
- stack_pointer_rtx, 0, OPTAB_DIRECT);
-
- if (x != stack_pointer_rtx)
- emit_move_insn (stack_pointer_rtx, x);
-
- emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
- DONE;
-})
-
-;; Use IOR for stack probes, this is shorter.
-(define_expand "probe_stack"
- [(match_operand 0 "memory_operand")]
- ""
-{
- rtx (*gen_ior3) (rtx, rtx, rtx);
-
- gen_ior3 = (GET_MODE (operands[0]) == DImode
- ? gen_iordi3 : gen_iorsi3);
-
- emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
- DONE;
-})
-
-(define_insn "adjust_stack_and_probe<mode>"
- [(set (match_operand:P 0 "register_operand" "=r")
- (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
- UNSPECV_PROBE_STACK_RANGE))
- (set (reg:P SP_REG)
- (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
- (clobber (reg:CC FLAGS_REG))
- (clobber (mem:BLK (scratch)))]
- ""
- "* return output_adjust_stack_and_probe (operands[0]);"
- [(set_attr "type" "multi")])
-
-(define_insn "probe_stack_range<mode>"
- [(set (match_operand:P 0 "register_operand" "=r")
- (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
- (match_operand:P 2 "const_int_operand" "n")]
- UNSPECV_PROBE_STACK_RANGE))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "* return output_probe_stack_range (operands[0], operands[2]);"
- [(set_attr "type" "multi")])
-
-(define_expand "builtin_setjmp_receiver"
- [(label_ref (match_operand 0))]
- "!TARGET_64BIT && flag_pic"
-{
-#if TARGET_MACHO
- if (TARGET_MACHO)
- {
- rtx xops[3];
- rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
- rtx label_rtx = gen_label_rtx ();
- emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
- xops[0] = xops[1] = picreg;
- xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
- ix86_expand_binary_operator (MINUS, SImode, xops);
- }
- else
-#endif
- emit_insn (gen_set_got (pic_offset_table_rtx));
- DONE;
-})
-
-;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
-
-(define_split
- [(set (match_operand 0 "register_operand")
- (match_operator 3 "promotable_binary_operator"
- [(match_operand 1 "register_operand")
- (match_operand 2 "aligned_operand")]))
- (clobber (reg:CC FLAGS_REG))]
- "! TARGET_PARTIAL_REG_STALL && reload_completed
- && ((GET_MODE (operands[0]) == HImode
- && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
- /* ??? next two lines just !satisfies_constraint_K (...) */
- || !CONST_INT_P (operands[2])
- || satisfies_constraint_K (operands[2])))
- || (GET_MODE (operands[0]) == QImode
- && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
- [(parallel [(set (match_dup 0)
- (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
- (clobber (reg:CC FLAGS_REG))])]
-{
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- if (GET_CODE (operands[3]) != ASHIFT)
- operands[2] = gen_lowpart (SImode, operands[2]);
- PUT_MODE (operands[3], SImode);
-})
-
-; Promote the QImode tests, as i386 has encoding of the AND
-; instruction with 32-bit sign-extended immediate and thus the
-; instruction size is unchanged, except in the %eax case for
-; which it is increased by one byte, hence the ! optimize_size.
-(define_split
- [(set (match_operand 0 "flags_reg_operand")
- (match_operator 2 "compare_operator"
- [(and (match_operand 3 "aligned_operand")
- (match_operand 4 "const_int_operand"))
- (const_int 0)]))
- (set (match_operand 1 "register_operand")
- (and (match_dup 3) (match_dup 4)))]
- "! TARGET_PARTIAL_REG_STALL && reload_completed
- && optimize_insn_for_speed_p ()
- && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
- || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
- /* Ensure that the operand will remain sign-extended immediate. */
- && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
- [(parallel [(set (match_dup 0)
- (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
- (const_int 0)]))
- (set (match_dup 1)
- (and:SI (match_dup 3) (match_dup 4)))])]
-{
- operands[4]
- = gen_int_mode (INTVAL (operands[4])
- & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
- operands[1] = gen_lowpart (SImode, operands[1]);
- operands[3] = gen_lowpart (SImode, operands[3]);
-})
-
-; Don't promote the QImode tests, as i386 doesn't have encoding of
-; the TEST instruction with 32-bit sign-extended immediate and thus
-; the instruction size would at least double, which is not what we
-; want even with ! optimize_size.
-(define_split
- [(set (match_operand 0 "flags_reg_operand")
- (match_operator 1 "compare_operator"
- [(and (match_operand:HI 2 "aligned_operand")
- (match_operand:HI 3 "const_int_operand"))
- (const_int 0)]))]
- "! TARGET_PARTIAL_REG_STALL && reload_completed
- && ! TARGET_FAST_PREFIX
- && optimize_insn_for_speed_p ()
- /* Ensure that the operand will remain sign-extended immediate. */
- && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
- [(set (match_dup 0)
- (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
- (const_int 0)]))]
-{
- operands[3]
- = gen_int_mode (INTVAL (operands[3])
- & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
- operands[2] = gen_lowpart (SImode, operands[2]);
-})
-
-(define_split
- [(set (match_operand 0 "register_operand")
- (neg (match_operand 1 "register_operand")))
- (clobber (reg:CC FLAGS_REG))]
- "! TARGET_PARTIAL_REG_STALL && reload_completed
- && (GET_MODE (operands[0]) == HImode
- || (GET_MODE (operands[0]) == QImode
- && (TARGET_PROMOTE_QImode
- || optimize_insn_for_size_p ())))"
- [(parallel [(set (match_dup 0)
- (neg:SI (match_dup 1)))
- (clobber (reg:CC FLAGS_REG))])]
-{
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (SImode, operands[1]);
-})
-
-(define_split
- [(set (match_operand 0 "register_operand")
- (not (match_operand 1 "register_operand")))]
- "! TARGET_PARTIAL_REG_STALL && reload_completed
- && (GET_MODE (operands[0]) == HImode
- || (GET_MODE (operands[0]) == QImode
- && (TARGET_PROMOTE_QImode
- || optimize_insn_for_size_p ())))"
- [(set (match_dup 0)
- (not:SI (match_dup 1)))]
-{
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (SImode, operands[1]);
-})
-
-;; RTL Peephole optimizations, run before sched2. These primarily look to
-;; transform a complex memory operation into two memory to register operations.
-
-;; Don't push memory operands
-(define_peephole2
- [(set (match_operand:SWI 0 "push_operand")
- (match_operand:SWI 1 "memory_operand"))
- (match_scratch:SWI 2 "<r>")]
- "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
- && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (match_dup 2))])
-
-;; We need to handle SFmode only, because DFmode and XFmode are split to
-;; SImode pushes.
-(define_peephole2
- [(set (match_operand:SF 0 "push_operand")
- (match_operand:SF 1 "memory_operand"))
- (match_scratch:SF 2 "r")]
- "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
- && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (match_dup 2))])
-
-;; Don't move an immediate directly to memory when the instruction
-;; gets too big, or if LCP stalls are a problem for 16-bit moves.
-(define_peephole2
- [(match_scratch:SWI124 1 "<r>")
- (set (match_operand:SWI124 0 "memory_operand")
- (const_int 0))]
- "optimize_insn_for_speed_p ()
- && ((<MODE>mode == HImode
- && TARGET_LCP_STALL)
- || (!TARGET_USE_MOV0
- && TARGET_SPLIT_LONG_MOVES
- && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
- && peep2_regno_dead_p (0, FLAGS_REG)"
- [(parallel [(set (match_dup 2) (const_int 0))
- (clobber (reg:CC FLAGS_REG))])
- (set (match_dup 0) (match_dup 1))]
- "operands[2] = gen_lowpart (SImode, operands[1]);")
-
-(define_peephole2
- [(match_scratch:SWI124 2 "<r>")
- (set (match_operand:SWI124 0 "memory_operand")
- (match_operand:SWI124 1 "immediate_operand"))]
- "optimize_insn_for_speed_p ()
- && ((<MODE>mode == HImode
- && TARGET_LCP_STALL)
- || (TARGET_SPLIT_LONG_MOVES
- && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (match_dup 2))])
-
-;; Don't compare memory with zero, load and use a test instead.
-(define_peephole2
- [(set (match_operand 0 "flags_reg_operand")
- (match_operator 1 "compare_operator"
- [(match_operand:SI 2 "memory_operand")
- (const_int 0)]))
- (match_scratch:SI 3 "r")]
- "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
- [(set (match_dup 3) (match_dup 2))
- (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
-
-;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
-;; Don't split NOTs with a displacement operand, because resulting XOR
-;; will not be pairable anyway.
-;;
-;; On AMD K6, NOT is vector decoded with memory operand that cannot be
-;; represented using a modRM byte. The XOR replacement is long decoded,
-;; so this split helps here as well.
-;;
-;; Note: Can't do this as a regular split because we can't get proper
-;; lifetime information then.
-
-(define_peephole2
- [(set (match_operand:SWI124 0 "nonimmediate_operand")
- (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
- "optimize_insn_for_speed_p ()
- && ((TARGET_NOT_UNPAIRABLE
- && (!MEM_P (operands[0])
- || !memory_displacement_operand (operands[0], <MODE>mode)))
- || (TARGET_NOT_VECTORMODE
- && long_memory_operand (operands[0], <MODE>mode)))
- && peep2_regno_dead_p (0, FLAGS_REG)"
- [(parallel [(set (match_dup 0)
- (xor:SWI124 (match_dup 1) (const_int -1)))
- (clobber (reg:CC FLAGS_REG))])])
-
-;; Non pairable "test imm, reg" instructions can be translated to
-;; "and imm, reg" if reg dies. The "and" form is also shorter (one
-;; byte opcode instead of two, have a short form for byte operands),
-;; so do it for other CPUs as well. Given that the value was dead,
-;; this should not create any new dependencies. Pass on the sub-word
-;; versions if we're concerned about partial register stalls.
-
-(define_peephole2
- [(set (match_operand 0 "flags_reg_operand")
- (match_operator 1 "compare_operator"
- [(and:SI (match_operand:SI 2 "register_operand")
- (match_operand:SI 3 "immediate_operand"))
- (const_int 0)]))]
- "ix86_match_ccmode (insn, CCNOmode)
- && (true_regnum (operands[2]) != AX_REG
- || satisfies_constraint_K (operands[3]))
- && peep2_reg_dead_p (1, operands[2])"
- [(parallel
- [(set (match_dup 0)
- (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
- (const_int 0)]))
- (set (match_dup 2)
- (and:SI (match_dup 2) (match_dup 3)))])])
-
-;; We don't need to handle HImode case, because it will be promoted to SImode
-;; on ! TARGET_PARTIAL_REG_STALL
-
-(define_peephole2
- [(set (match_operand 0 "flags_reg_operand")
- (match_operator 1 "compare_operator"
- [(and:QI (match_operand:QI 2 "register_operand")
- (match_operand:QI 3 "immediate_operand"))
- (const_int 0)]))]
- "! TARGET_PARTIAL_REG_STALL
- && ix86_match_ccmode (insn, CCNOmode)
- && true_regnum (operands[2]) != AX_REG
- && peep2_reg_dead_p (1, operands[2])"
- [(parallel
- [(set (match_dup 0)
- (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
- (const_int 0)]))
- (set (match_dup 2)
- (and:QI (match_dup 2) (match_dup 3)))])])
-
-(define_peephole2
- [(set (match_operand 0 "flags_reg_operand")
- (match_operator 1 "compare_operator"
- [(and:SI
- (zero_extract:SI
- (match_operand 2 "ext_register_operand")
- (const_int 8)
- (const_int 8))
- (match_operand 3 "const_int_operand"))
- (const_int 0)]))]
- "! TARGET_PARTIAL_REG_STALL
- && ix86_match_ccmode (insn, CCNOmode)
- && true_regnum (operands[2]) != AX_REG
- && peep2_reg_dead_p (1, operands[2])"
- [(parallel [(set (match_dup 0)
- (match_op_dup 1
- [(and:SI
- (zero_extract:SI
- (match_dup 2)
- (const_int 8)
- (const_int 8))
- (match_dup 3))
- (const_int 0)]))
- (set (zero_extract:SI (match_dup 2)
- (const_int 8)
- (const_int 8))
- (and:SI
- (zero_extract:SI
- (match_dup 2)
- (const_int 8)
- (const_int 8))
- (match_dup 3)))])])
-
-;; Don't do logical operations with memory inputs.
-(define_peephole2
- [(match_scratch:SI 2 "r")
- (parallel [(set (match_operand:SI 0 "register_operand")
- (match_operator:SI 3 "arith_or_logical_operator"
- [(match_dup 0)
- (match_operand:SI 1 "memory_operand")]))
- (clobber (reg:CC FLAGS_REG))])]
- "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
- [(set (match_dup 2) (match_dup 1))
- (parallel [(set (match_dup 0)
- (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
- (clobber (reg:CC FLAGS_REG))])])
-
-(define_peephole2
- [(match_scratch:SI 2 "r")
- (parallel [(set (match_operand:SI 0 "register_operand")
- (match_operator:SI 3 "arith_or_logical_operator"
- [(match_operand:SI 1 "memory_operand")
- (match_dup 0)]))
- (clobber (reg:CC FLAGS_REG))])]
- "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
- [(set (match_dup 2) (match_dup 1))
- (parallel [(set (match_dup 0)
- (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
- (clobber (reg:CC FLAGS_REG))])])
-
-;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
-;; refers to the destination of the load!
-
-(define_peephole2
- [(set (match_operand:SI 0 "register_operand")
- (match_operand:SI 1 "register_operand"))
- (parallel [(set (match_dup 0)
- (match_operator:SI 3 "commutative_operator"
- [(match_dup 0)
- (match_operand:SI 2 "memory_operand")]))
- (clobber (reg:CC FLAGS_REG))])]
- "REGNO (operands[0]) != REGNO (operands[1])
- && GENERAL_REGNO_P (REGNO (operands[0]))
- && GENERAL_REGNO_P (REGNO (operands[1]))"
- [(set (match_dup 0) (match_dup 4))
- (parallel [(set (match_dup 0)
- (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
- (clobber (reg:CC FLAGS_REG))])]
- "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
-
-(define_peephole2
- [(set (match_operand 0 "register_operand")
- (match_operand 1 "register_operand"))
- (set (match_dup 0)
- (match_operator 3 "commutative_operator"
- [(match_dup 0)
- (match_operand 2 "memory_operand")]))]
- "REGNO (operands[0]) != REGNO (operands[1])
- && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
- || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
- [(set (match_dup 0) (match_dup 2))
- (set (match_dup 0)
- (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
-
-; Don't do logical operations with memory outputs
-;
-; These two don't make sense for PPro/PII -- we're expanding a 4-uop
-; instruction into two 1-uop insns plus a 2-uop insn. That last has
-; the same decoder scheduling characteristics as the original.
-
-(define_peephole2
- [(match_scratch:SI 2 "r")
- (parallel [(set (match_operand:SI 0 "memory_operand")
- (match_operator:SI 3 "arith_or_logical_operator"
- [(match_dup 0)
- (match_operand:SI 1 "nonmemory_operand")]))
- (clobber (reg:CC FLAGS_REG))])]
- "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
- /* Do not split stack checking probes. */
- && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
- [(set (match_dup 2) (match_dup 0))
- (parallel [(set (match_dup 2)
- (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
- (clobber (reg:CC FLAGS_REG))])
- (set (match_dup 0) (match_dup 2))])
-
-(define_peephole2
- [(match_scratch:SI 2 "r")
- (parallel [(set (match_operand:SI 0 "memory_operand")
- (match_operator:SI 3 "arith_or_logical_operator"
- [(match_operand:SI 1 "nonmemory_operand")
- (match_dup 0)]))
- (clobber (reg:CC FLAGS_REG))])]
- "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
- /* Do not split stack checking probes. */
- && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
- [(set (match_dup 2) (match_dup 0))
- (parallel [(set (match_dup 2)
- (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
- (clobber (reg:CC FLAGS_REG))])
- (set (match_dup 0) (match_dup 2))])
-
-;; Attempt to use arith or logical operations with memory outputs with
-;; setting of flags.
-(define_peephole2
- [(set (match_operand:SWI 0 "register_operand")
- (match_operand:SWI 1 "memory_operand"))
- (parallel [(set (match_dup 0)
- (match_operator:SWI 3 "plusminuslogic_operator"
- [(match_dup 0)
- (match_operand:SWI 2 "<nonmemory_operand>")]))
- (clobber (reg:CC FLAGS_REG))])
- (set (match_dup 1) (match_dup 0))
- (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
- "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
- && peep2_reg_dead_p (4, operands[0])
- && !reg_overlap_mentioned_p (operands[0], operands[1])
- && (<MODE>mode != QImode
- || immediate_operand (operands[2], QImode)
- || q_regs_operand (operands[2], QImode))
- && ix86_match_ccmode (peep2_next_insn (3),
- (GET_CODE (operands[3]) == PLUS
- || GET_CODE (operands[3]) == MINUS)
- ? CCGOCmode : CCNOmode)"
- [(parallel [(set (match_dup 4) (match_dup 5))
- (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
- (match_dup 2)]))])]
-{
- operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
- operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
- copy_rtx (operands[1]),
- copy_rtx (operands[2]));
- operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
- operands[5], const0_rtx);
-})
-
-(define_peephole2
- [(parallel [(set (match_operand:SWI 0 "register_operand")
- (match_operator:SWI 2 "plusminuslogic_operator"
- [(match_dup 0)
- (match_operand:SWI 1 "memory_operand")]))
- (clobber (reg:CC FLAGS_REG))])
- (set (match_dup 1) (match_dup 0))
- (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
- "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
- && GET_CODE (operands[2]) != MINUS
- && peep2_reg_dead_p (3, operands[0])
- && !reg_overlap_mentioned_p (operands[0], operands[1])
- && ix86_match_ccmode (peep2_next_insn (2),
- GET_CODE (operands[2]) == PLUS
- ? CCGOCmode : CCNOmode)"
- [(parallel [(set (match_dup 3) (match_dup 4))
- (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
- (match_dup 0)]))])]
-{
- operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
- operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
- copy_rtx (operands[1]),
- copy_rtx (operands[0]));
- operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
- operands[4], const0_rtx);
-})
-
-(define_peephole2
- [(set (match_operand:SWI12 0 "register_operand")
- (match_operand:SWI12 1 "memory_operand"))
- (parallel [(set (match_operand:SI 4 "register_operand")
- (match_operator:SI 3 "plusminuslogic_operator"
- [(match_dup 4)
- (match_operand:SI 2 "nonmemory_operand")]))
- (clobber (reg:CC FLAGS_REG))])
- (set (match_dup 1) (match_dup 0))
- (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
- "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
- && REG_P (operands[0]) && REG_P (operands[4])
- && REGNO (operands[0]) == REGNO (operands[4])
- && peep2_reg_dead_p (4, operands[0])
- && (<MODE>mode != QImode
- || immediate_operand (operands[2], SImode)
- || q_regs_operand (operands[2], SImode))
- && !reg_overlap_mentioned_p (operands[0], operands[1])
- && ix86_match_ccmode (peep2_next_insn (3),
- (GET_CODE (operands[3]) == PLUS
- || GET_CODE (operands[3]) == MINUS)
- ? CCGOCmode : CCNOmode)"
- [(parallel [(set (match_dup 4) (match_dup 5))
- (set (match_dup 1) (match_dup 6))])]
-{
- operands[2] = gen_lowpart (<MODE>mode, operands[2]);
- operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
- operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
- copy_rtx (operands[1]), operands[2]);
- operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
- operands[5], const0_rtx);
- operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
- copy_rtx (operands[1]),
- copy_rtx (operands[2]));
-})
-
-;; Attempt to always use XOR for zeroing registers.
-(define_peephole2
- [(set (match_operand 0 "register_operand")
- (match_operand 1 "const0_operand"))]
- "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
- && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
- && GENERAL_REG_P (operands[0])
- && peep2_regno_dead_p (0, FLAGS_REG)"
- [(parallel [(set (match_dup 0) (const_int 0))
- (clobber (reg:CC FLAGS_REG))])]
- "operands[0] = gen_lowpart (word_mode, operands[0]);")
-
-(define_peephole2
- [(set (strict_low_part (match_operand 0 "register_operand"))
- (const_int 0))]
- "(GET_MODE (operands[0]) == QImode
- || GET_MODE (operands[0]) == HImode)
- && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
- && peep2_regno_dead_p (0, FLAGS_REG)"
- [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
- (clobber (reg:CC FLAGS_REG))])])
-
-;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
-(define_peephole2
- [(set (match_operand:SWI248 0 "register_operand")
- (const_int -1))]
- "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
- && peep2_regno_dead_p (0, FLAGS_REG)"
- [(parallel [(set (match_dup 0) (const_int -1))
- (clobber (reg:CC FLAGS_REG))])]
-{
- if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
- operands[0] = gen_lowpart (SImode, operands[0]);
-})
-
-;; Attempt to convert simple lea to add/shift.
-;; These can be created by move expanders.
-;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
-;; relevant lea instructions were already split.
-
-(define_peephole2
- [(set (match_operand:SWI48 0 "register_operand")
- (plus:SWI48 (match_dup 0)
- (match_operand:SWI48 1 "<nonmemory_operand>")))]
- "!TARGET_OPT_AGU
- && peep2_regno_dead_p (0, FLAGS_REG)"
- [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
- (clobber (reg:CC FLAGS_REG))])])
-
-(define_peephole2
- [(set (match_operand:SWI48 0 "register_operand")
- (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
- (match_dup 0)))]
- "!TARGET_OPT_AGU
- && peep2_regno_dead_p (0, FLAGS_REG)"
- [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
- (clobber (reg:CC FLAGS_REG))])])
-
-(define_peephole2
- [(set (match_operand:DI 0 "register_operand")
- (zero_extend:DI
- (plus:SI (match_operand:SI 1 "register_operand")
- (match_operand:SI 2 "nonmemory_operand"))))]
- "TARGET_64BIT && !TARGET_OPT_AGU
- && REGNO (operands[0]) == REGNO (operands[1])
- && peep2_regno_dead_p (0, FLAGS_REG)"
- [(parallel [(set (match_dup 0)
- (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
- (clobber (reg:CC FLAGS_REG))])])
-
-(define_peephole2
- [(set (match_operand:DI 0 "register_operand")
- (zero_extend:DI
- (plus:SI (match_operand:SI 1 "nonmemory_operand")
- (match_operand:SI 2 "register_operand"))))]
- "TARGET_64BIT && !TARGET_OPT_AGU
- && REGNO (operands[0]) == REGNO (operands[2])
- && peep2_regno_dead_p (0, FLAGS_REG)"
- [(parallel [(set (match_dup 0)
- (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
- (clobber (reg:CC FLAGS_REG))])])
-
-(define_peephole2
- [(set (match_operand:SWI48 0 "register_operand")
- (mult:SWI48 (match_dup 0)
- (match_operand:SWI48 1 "const_int_operand")))]
- "exact_log2 (INTVAL (operands[1])) >= 0
- && peep2_regno_dead_p (0, FLAGS_REG)"
- [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
- (clobber (reg:CC FLAGS_REG))])]
- "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
-
-(define_peephole2
- [(set (match_operand:DI 0 "register_operand")
- (zero_extend:DI
- (mult:SI (match_operand:SI 1 "register_operand")
- (match_operand:SI 2 "const_int_operand"))))]
- "TARGET_64BIT
- && exact_log2 (INTVAL (operands[2])) >= 0
- && REGNO (operands[0]) == REGNO (operands[1])
- && peep2_regno_dead_p (0, FLAGS_REG)"
- [(parallel [(set (match_dup 0)
- (zero_extend (ashift:SI (match_dup 1) (match_dup 2))))
- (clobber (reg:CC FLAGS_REG))])]
- "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
-
-;; The ESP adjustments can be done by the push and pop instructions. Resulting
-;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
-;; On many CPUs it is also faster, since special hardware to avoid esp
-;; dependencies is present.
-
-;; While some of these conversions may be done using splitters, we use
-;; peepholes in order to allow combine_stack_adjustments pass to see
-;; nonobfuscated RTL.
-
-;; Convert prologue esp subtractions to push.
-;; We need register to push. In order to keep verify_flow_info happy we have
-;; two choices
-;; - use scratch and clobber it in order to avoid dependencies
-;; - use already live register
-;; We can't use the second way right now, since there is no reliable way how to
-;; verify that given register is live. First choice will also most likely in
-;; fewer dependencies. On the place of esp adjustments it is very likely that
-;; call clobbered registers are dead. We may want to use base pointer as an
-;; alternative when no register is available later.
-
-(define_peephole2
- [(match_scratch:W 1 "r")
- (parallel [(set (reg:P SP_REG)
- (plus:P (reg:P SP_REG)
- (match_operand:P 0 "const_int_operand")))
- (clobber (reg:CC FLAGS_REG))
- (clobber (mem:BLK (scratch)))])]
- "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
- && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
- [(clobber (match_dup 1))
- (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
- (clobber (mem:BLK (scratch)))])])
-
-(define_peephole2
- [(match_scratch:W 1 "r")
- (parallel [(set (reg:P SP_REG)
- (plus:P (reg:P SP_REG)
- (match_operand:P 0 "const_int_operand")))
- (clobber (reg:CC FLAGS_REG))
- (clobber (mem:BLK (scratch)))])]
- "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
- && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
- [(clobber (match_dup 1))
- (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
- (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
- (clobber (mem:BLK (scratch)))])])
-
-;; Convert esp subtractions to push.
-(define_peephole2
- [(match_scratch:W 1 "r")
- (parallel [(set (reg:P SP_REG)
- (plus:P (reg:P SP_REG)
- (match_operand:P 0 "const_int_operand")))
- (clobber (reg:CC FLAGS_REG))])]
- "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
- && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
- [(clobber (match_dup 1))
- (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
-
-(define_peephole2
- [(match_scratch:W 1 "r")
- (parallel [(set (reg:P SP_REG)
- (plus:P (reg:P SP_REG)
- (match_operand:P 0 "const_int_operand")))
- (clobber (reg:CC FLAGS_REG))])]
- "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
- && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
- [(clobber (match_dup 1))
- (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
- (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
-
-;; Convert epilogue deallocator to pop.
-(define_peephole2
- [(match_scratch:W 1 "r")
- (parallel [(set (reg:P SP_REG)
- (plus:P (reg:P SP_REG)
- (match_operand:P 0 "const_int_operand")))
- (clobber (reg:CC FLAGS_REG))
- (clobber (mem:BLK (scratch)))])]
- "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
- && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
- [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
- (clobber (mem:BLK (scratch)))])])
-
-;; Two pops case is tricky, since pop causes dependency
-;; on destination register. We use two registers if available.
-(define_peephole2
- [(match_scratch:W 1 "r")
- (match_scratch:W 2 "r")
- (parallel [(set (reg:P SP_REG)
- (plus:P (reg:P SP_REG)
- (match_operand:P 0 "const_int_operand")))
- (clobber (reg:CC FLAGS_REG))
- (clobber (mem:BLK (scratch)))])]
- "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
- && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
- [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
- (clobber (mem:BLK (scratch)))])
- (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
-
-(define_peephole2
- [(match_scratch:W 1 "r")
- (parallel [(set (reg:P SP_REG)
- (plus:P (reg:P SP_REG)
- (match_operand:P 0 "const_int_operand")))
- (clobber (reg:CC FLAGS_REG))
- (clobber (mem:BLK (scratch)))])]
- "optimize_insn_for_size_p ()
- && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
- [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
- (clobber (mem:BLK (scratch)))])
- (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
-
-;; Convert esp additions to pop.
-(define_peephole2
- [(match_scratch:W 1 "r")
- (parallel [(set (reg:P SP_REG)
- (plus:P (reg:P SP_REG)
- (match_operand:P 0 "const_int_operand")))
- (clobber (reg:CC FLAGS_REG))])]
- "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
- [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
-
-;; Two pops case is tricky, since pop causes dependency
-;; on destination register. We use two registers if available.
-(define_peephole2
- [(match_scratch:W 1 "r")
- (match_scratch:W 2 "r")
- (parallel [(set (reg:P SP_REG)
- (plus:P (reg:P SP_REG)
- (match_operand:P 0 "const_int_operand")))
- (clobber (reg:CC FLAGS_REG))])]
- "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
- [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
- (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
-
-(define_peephole2
- [(match_scratch:W 1 "r")
- (parallel [(set (reg:P SP_REG)
- (plus:P (reg:P SP_REG)
- (match_operand:P 0 "const_int_operand")))
- (clobber (reg:CC FLAGS_REG))])]
- "optimize_insn_for_size_p ()
- && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
- [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
- (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
-
-;; Convert compares with 1 to shorter inc/dec operations when CF is not
-;; required and register dies. Similarly for 128 to -128.
-(define_peephole2
- [(set (match_operand 0 "flags_reg_operand")
- (match_operator 1 "compare_operator"
- [(match_operand 2 "register_operand")
- (match_operand 3 "const_int_operand")]))]
- "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
- && incdec_operand (operands[3], GET_MODE (operands[3])))
- || (!TARGET_FUSE_CMP_AND_BRANCH
- && INTVAL (operands[3]) == 128))
- && ix86_match_ccmode (insn, CCGCmode)
- && peep2_reg_dead_p (1, operands[2])"
- [(parallel [(set (match_dup 0)
- (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
- (clobber (match_dup 2))])])
-
-;; Convert imul by three, five and nine into lea
-(define_peephole2
- [(parallel
- [(set (match_operand:SWI48 0 "register_operand")
- (mult:SWI48 (match_operand:SWI48 1 "register_operand")
- (match_operand:SWI48 2 "const359_operand")))
- (clobber (reg:CC FLAGS_REG))])]
- "!TARGET_PARTIAL_REG_STALL
- || <MODE>mode == SImode
- || optimize_function_for_size_p (cfun)"
- [(set (match_dup 0)
- (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
- (match_dup 1)))]
- "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
-
-(define_peephole2
- [(parallel
- [(set (match_operand:SWI48 0 "register_operand")
- (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
- (match_operand:SWI48 2 "const359_operand")))
- (clobber (reg:CC FLAGS_REG))])]
- "optimize_insn_for_speed_p ()
- && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
- [(set (match_dup 0) (match_dup 1))
- (set (match_dup 0)
- (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
- (match_dup 0)))]
- "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
-
-;; imul $32bit_imm, mem, reg is vector decoded, while
-;; imul $32bit_imm, reg, reg is direct decoded.
-(define_peephole2
- [(match_scratch:SWI48 3 "r")
- (parallel [(set (match_operand:SWI48 0 "register_operand")
- (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
- (match_operand:SWI48 2 "immediate_operand")))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
- && !satisfies_constraint_K (operands[2])"
- [(set (match_dup 3) (match_dup 1))
- (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
- (clobber (reg:CC FLAGS_REG))])])
-
-(define_peephole2
- [(match_scratch:SI 3 "r")
- (parallel [(set (match_operand:DI 0 "register_operand")
- (zero_extend:DI
- (mult:SI (match_operand:SI 1 "memory_operand")
- (match_operand:SI 2 "immediate_operand"))))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_64BIT
- && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
- && !satisfies_constraint_K (operands[2])"
- [(set (match_dup 3) (match_dup 1))
- (parallel [(set (match_dup 0)
- (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
- (clobber (reg:CC FLAGS_REG))])])
-
-;; imul $8/16bit_imm, regmem, reg is vector decoded.
-;; Convert it into imul reg, reg
-;; It would be better to force assembler to encode instruction using long
-;; immediate, but there is apparently no way to do so.
-(define_peephole2
- [(parallel [(set (match_operand:SWI248 0 "register_operand")
- (mult:SWI248
- (match_operand:SWI248 1 "nonimmediate_operand")
- (match_operand:SWI248 2 "const_int_operand")))
- (clobber (reg:CC FLAGS_REG))])
- (match_scratch:SWI248 3 "r")]
- "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
- && satisfies_constraint_K (operands[2])"
- [(set (match_dup 3) (match_dup 2))
- (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
- (clobber (reg:CC FLAGS_REG))])]
-{
- if (!rtx_equal_p (operands[0], operands[1]))
- emit_move_insn (operands[0], operands[1]);
-})
-
-;; After splitting up read-modify operations, array accesses with memory
-;; operands might end up in form:
-;; sall $2, %eax
-;; movl 4(%esp), %edx
-;; addl %edx, %eax
-;; instead of pre-splitting:
-;; sall $2, %eax
-;; addl 4(%esp), %eax
-;; Turn it into:
-;; movl 4(%esp), %edx
-;; leal (%edx,%eax,4), %eax
-
-(define_peephole2
- [(match_scratch:W 5 "r")
- (parallel [(set (match_operand 0 "register_operand")
- (ashift (match_operand 1 "register_operand")
- (match_operand 2 "const_int_operand")))
- (clobber (reg:CC FLAGS_REG))])
- (parallel [(set (match_operand 3 "register_operand")
- (plus (match_dup 0)
- (match_operand 4 "x86_64_general_operand")))
- (clobber (reg:CC FLAGS_REG))])]
- "IN_RANGE (INTVAL (operands[2]), 1, 3)
- /* Validate MODE for lea. */
- && ((!TARGET_PARTIAL_REG_STALL
- && (GET_MODE (operands[0]) == QImode
- || GET_MODE (operands[0]) == HImode))
- || GET_MODE (operands[0]) == SImode
- || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
- && (rtx_equal_p (operands[0], operands[3])
- || peep2_reg_dead_p (2, operands[0]))
- /* We reorder load and the shift. */
- && !reg_overlap_mentioned_p (operands[0], operands[4])"
- [(set (match_dup 5) (match_dup 4))
- (set (match_dup 0) (match_dup 1))]
-{
- enum machine_mode op1mode = GET_MODE (operands[1]);
- enum machine_mode mode = op1mode == DImode ? DImode : SImode;
- int scale = 1 << INTVAL (operands[2]);
- rtx index = gen_lowpart (word_mode, operands[1]);
- rtx base = gen_lowpart (word_mode, operands[5]);
- rtx dest = gen_lowpart (mode, operands[3]);
-
- operands[1] = gen_rtx_PLUS (word_mode, base,
- gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
- operands[5] = base;
- if (mode != word_mode)
- operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
- if (op1mode != word_mode)
- operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
- operands[0] = dest;
-})
-
-;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
-;; That, however, is usually mapped by the OS to SIGSEGV, which is often
-;; caught for use by garbage collectors and the like. Using an insn that
-;; maps to SIGILL makes it more likely the program will rightfully die.
-;; Keeping with tradition, "6" is in honor of #UD.
-(define_insn "trap"
- [(trap_if (const_int 1) (const_int 6))]
- ""
- { return ASM_SHORT "0x0b0f"; }
- [(set_attr "length" "2")])
-
-(define_expand "prefetch"
- [(prefetch (match_operand 0 "address_operand")
- (match_operand:SI 1 "const_int_operand")
- (match_operand:SI 2 "const_int_operand"))]
- "TARGET_PREFETCH_SSE || TARGET_PRFCHW"
-{
- bool write = INTVAL (operands[1]) != 0;
- int locality = INTVAL (operands[2]);
-
- gcc_assert (IN_RANGE (locality, 0, 3));
-
- /* Use 3dNOW prefetch in case we are asking for write prefetch not
- supported by SSE counterpart or the SSE prefetch is not available
- (K6 machines). Otherwise use SSE prefetch as it allows specifying
- of locality. */
- if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
- operands[2] = GEN_INT (3);
- else
- operands[1] = const0_rtx;
-})
-
-(define_insn "*prefetch_sse"
- [(prefetch (match_operand 0 "address_operand" "p")
- (const_int 0)
- (match_operand:SI 1 "const_int_operand"))]
- "TARGET_PREFETCH_SSE"
-{
- static const char * const patterns[4] = {
- "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
- };
-
- int locality = INTVAL (operands[1]);
- gcc_assert (IN_RANGE (locality, 0, 3));
-
- return patterns[locality];
-}
- [(set_attr "type" "sse")
- (set_attr "atom_sse_attr" "prefetch")
- (set (attr "length_address")
- (symbol_ref "memory_address_length (operands[0], false)"))
- (set_attr "memory" "none")])
-
-(define_insn "*prefetch_3dnow"
- [(prefetch (match_operand 0 "address_operand" "p")
- (match_operand:SI 1 "const_int_operand" "n")
- (const_int 3))]
- "TARGET_PRFCHW"
-{
- if (INTVAL (operands[1]) == 0)
- return "prefetch\t%a0";
- else
- return "prefetchw\t%a0";
-}
- [(set_attr "type" "mmx")
- (set (attr "length_address")
- (symbol_ref "memory_address_length (operands[0], false)"))
- (set_attr "memory" "none")])
-
-(define_expand "stack_protect_set"
- [(match_operand 0 "memory_operand")
- (match_operand 1 "memory_operand")]
- "TARGET_SSP_TLS_GUARD"
-{
- rtx (*insn)(rtx, rtx);
-
-#ifdef TARGET_THREAD_SSP_OFFSET
- operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
- insn = (TARGET_LP64
- ? gen_stack_tls_protect_set_di
- : gen_stack_tls_protect_set_si);
-#else
- insn = (TARGET_LP64
- ? gen_stack_protect_set_di
- : gen_stack_protect_set_si);
-#endif
-
- emit_insn (insn (operands[0], operands[1]));
- DONE;
-})
-
-(define_insn "stack_protect_set_<mode>"
- [(set (match_operand:PTR 0 "memory_operand" "=m")
- (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
- UNSPEC_SP_SET))
- (set (match_scratch:PTR 2 "=&r") (const_int 0))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_SSP_TLS_GUARD"
- "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
- [(set_attr "type" "multi")])
-
-(define_insn "stack_tls_protect_set_<mode>"
- [(set (match_operand:PTR 0 "memory_operand" "=m")
- (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
- UNSPEC_SP_TLS_SET))
- (set (match_scratch:PTR 2 "=&r") (const_int 0))
- (clobber (reg:CC FLAGS_REG))]
- ""
- "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
- [(set_attr "type" "multi")])
-
-(define_expand "stack_protect_test"
- [(match_operand 0 "memory_operand")
- (match_operand 1 "memory_operand")
- (match_operand 2)]
- "TARGET_SSP_TLS_GUARD"
-{
- rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
-
- rtx (*insn)(rtx, rtx, rtx);
-
-#ifdef TARGET_THREAD_SSP_OFFSET
- operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
- insn = (TARGET_LP64
- ? gen_stack_tls_protect_test_di
- : gen_stack_tls_protect_test_si);
-#else
- insn = (TARGET_LP64
- ? gen_stack_protect_test_di
- : gen_stack_protect_test_si);
-#endif
-
- emit_insn (insn (flags, operands[0], operands[1]));
-
- emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
- flags, const0_rtx, operands[2]));
- DONE;
-})
-
-(define_insn "stack_protect_test_<mode>"
- [(set (match_operand:CCZ 0 "flags_reg_operand")
- (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
- (match_operand:PTR 2 "memory_operand" "m")]
- UNSPEC_SP_TEST))
- (clobber (match_scratch:PTR 3 "=&r"))]
- "TARGET_SSP_TLS_GUARD"
- "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
- [(set_attr "type" "multi")])
-
-(define_insn "stack_tls_protect_test_<mode>"
- [(set (match_operand:CCZ 0 "flags_reg_operand")
- (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
- (match_operand:PTR 2 "const_int_operand" "i")]
- UNSPEC_SP_TLS_TEST))
- (clobber (match_scratch:PTR 3 "=r"))]
- ""
- "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
- [(set_attr "type" "multi")])
-
-(define_insn "sse4_2_crc32<mode>"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (unspec:SI
- [(match_operand:SI 1 "register_operand" "0")
- (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
- UNSPEC_CRC32))]
- "TARGET_SSE4_2 || TARGET_CRC32"
- "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
- [(set_attr "type" "sselog1")
- (set_attr "prefix_rep" "1")
- (set_attr "prefix_extra" "1")
- (set (attr "prefix_data16")
- (if_then_else (match_operand:HI 2)
- (const_string "1")
- (const_string "*")))
- (set (attr "prefix_rex")
- (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
- (const_string "1")
- (const_string "*")))
- (set_attr "mode" "SI")])
-
-(define_insn "sse4_2_crc32di"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (unspec:DI
- [(match_operand:DI 1 "register_operand" "0")
- (match_operand:DI 2 "nonimmediate_operand" "rm")]
- UNSPEC_CRC32))]
- "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
- "crc32{q}\t{%2, %0|%0, %2}"
- [(set_attr "type" "sselog1")
- (set_attr "prefix_rep" "1")
- (set_attr "prefix_extra" "1")
- (set_attr "mode" "DI")])
-
-(define_insn "rdpmc"
- [(set (match_operand:DI 0 "register_operand" "=A")
- (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
- UNSPECV_RDPMC))]
- "!TARGET_64BIT"
- "rdpmc"
- [(set_attr "type" "other")
- (set_attr "length" "2")])
-
-(define_insn "rdpmc_rex64"
- [(set (match_operand:DI 0 "register_operand" "=a")
- (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
- UNSPECV_RDPMC))
- (set (match_operand:DI 1 "register_operand" "=d")
- (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
- "TARGET_64BIT"
- "rdpmc"
- [(set_attr "type" "other")
- (set_attr "length" "2")])
-
-(define_insn "rdtsc"
- [(set (match_operand:DI 0 "register_operand" "=A")
- (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
- "!TARGET_64BIT"
- "rdtsc"
- [(set_attr "type" "other")
- (set_attr "length" "2")])
-
-(define_insn "rdtsc_rex64"
- [(set (match_operand:DI 0 "register_operand" "=a")
- (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
- (set (match_operand:DI 1 "register_operand" "=d")
- (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
- "TARGET_64BIT"
- "rdtsc"
- [(set_attr "type" "other")
- (set_attr "length" "2")])
-
-(define_insn "rdtscp"
- [(set (match_operand:DI 0 "register_operand" "=A")
- (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
- (set (match_operand:SI 1 "register_operand" "=c")
- (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
- "!TARGET_64BIT"
- "rdtscp"
- [(set_attr "type" "other")
- (set_attr "length" "3")])
-
-(define_insn "rdtscp_rex64"
- [(set (match_operand:DI 0 "register_operand" "=a")
- (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
- (set (match_operand:DI 1 "register_operand" "=d")
- (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
- (set (match_operand:SI 2 "register_operand" "=c")
- (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
- "TARGET_64BIT"
- "rdtscp"
- [(set_attr "type" "other")
- (set_attr "length" "3")])
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; FXSR, XSAVE and XSAVEOPT instructions
-;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(define_insn "fxsave"
- [(set (match_operand:BLK 0 "memory_operand" "=m")
- (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
- "TARGET_FXSR"
- "fxsave\t%0"
- [(set_attr "type" "other")
- (set_attr "memory" "store")
- (set (attr "length")
- (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
-
-(define_insn "fxsave64"
- [(set (match_operand:BLK 0 "memory_operand" "=m")
- (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
- "TARGET_64BIT && TARGET_FXSR"
- "fxsave64\t%0"
- [(set_attr "type" "other")
- (set_attr "memory" "store")
- (set (attr "length")
- (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
-
-(define_insn "fxrstor"
- [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
- UNSPECV_FXRSTOR)]
- "TARGET_FXSR"
- "fxrstor\t%0"
- [(set_attr "type" "other")
- (set_attr "memory" "load")
- (set (attr "length")
- (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
-
-(define_insn "fxrstor64"
- [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
- UNSPECV_FXRSTOR64)]
- "TARGET_64BIT && TARGET_FXSR"
- "fxrstor64\t%0"
- [(set_attr "type" "other")
- (set_attr "memory" "load")
- (set (attr "length")
- (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
-
-(define_int_iterator ANY_XSAVE
- [UNSPECV_XSAVE
- (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
-
-(define_int_iterator ANY_XSAVE64
- [UNSPECV_XSAVE64
- (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
-
-(define_int_attr xsave
- [(UNSPECV_XSAVE "xsave")
- (UNSPECV_XSAVE64 "xsave64")
- (UNSPECV_XSAVEOPT "xsaveopt")
- (UNSPECV_XSAVEOPT64 "xsaveopt64")])
-
-(define_insn "<xsave>"
- [(set (match_operand:BLK 0 "memory_operand" "=m")
- (unspec_volatile:BLK
- [(match_operand:DI 1 "register_operand" "A")]
- ANY_XSAVE))]
- "!TARGET_64BIT && TARGET_XSAVE"
- "<xsave>\t%0"
- [(set_attr "type" "other")
- (set_attr "memory" "store")
- (set (attr "length")
- (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
-
-(define_insn "<xsave>_rex64"
- [(set (match_operand:BLK 0 "memory_operand" "=m")
- (unspec_volatile:BLK
- [(match_operand:SI 1 "register_operand" "a")
- (match_operand:SI 2 "register_operand" "d")]
- ANY_XSAVE))]
- "TARGET_64BIT && TARGET_XSAVE"
- "<xsave>\t%0"
- [(set_attr "type" "other")
- (set_attr "memory" "store")
- (set (attr "length")
- (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
-
-(define_insn "<xsave>"
- [(set (match_operand:BLK 0 "memory_operand" "=m")
- (unspec_volatile:BLK
- [(match_operand:SI 1 "register_operand" "a")
- (match_operand:SI 2 "register_operand" "d")]
- ANY_XSAVE64))]
- "TARGET_64BIT && TARGET_XSAVE"
- "<xsave>\t%0"
- [(set_attr "type" "other")
- (set_attr "memory" "store")
- (set (attr "length")
- (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
-
-(define_insn "xrstor"
- [(unspec_volatile:BLK
- [(match_operand:BLK 0 "memory_operand" "m")
- (match_operand:DI 1 "register_operand" "A")]
- UNSPECV_XRSTOR)]
- "!TARGET_64BIT && TARGET_XSAVE"
- "xrstor\t%0"
- [(set_attr "type" "other")
- (set_attr "memory" "load")
- (set (attr "length")
- (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
-
-(define_insn "xrstor_rex64"
- [(unspec_volatile:BLK
- [(match_operand:BLK 0 "memory_operand" "m")
- (match_operand:SI 1 "register_operand" "a")
- (match_operand:SI 2 "register_operand" "d")]
- UNSPECV_XRSTOR)]
- "TARGET_64BIT && TARGET_XSAVE"
- "xrstor\t%0"
- [(set_attr "type" "other")
- (set_attr "memory" "load")
- (set (attr "length")
- (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
-
-(define_insn "xrstor64"
- [(unspec_volatile:BLK
- [(match_operand:BLK 0 "memory_operand" "m")
- (match_operand:SI 1 "register_operand" "a")
- (match_operand:SI 2 "register_operand" "d")]
- UNSPECV_XRSTOR64)]
- "TARGET_64BIT && TARGET_XSAVE"
- "xrstor64\t%0"
- [(set_attr "type" "other")
- (set_attr "memory" "load")
- (set (attr "length")
- (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; LWP instructions
-;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(define_expand "lwp_llwpcb"
- [(unspec_volatile [(match_operand 0 "register_operand" "r")]
- UNSPECV_LLWP_INTRINSIC)]
- "TARGET_LWP")
-
-(define_insn "*lwp_llwpcb<mode>1"
- [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
- UNSPECV_LLWP_INTRINSIC)]
- "TARGET_LWP"
- "llwpcb\t%0"
- [(set_attr "type" "lwp")
- (set_attr "mode" "<MODE>")
- (set_attr "length" "5")])
-
-(define_expand "lwp_slwpcb"
- [(set (match_operand 0 "register_operand" "=r")
- (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
- "TARGET_LWP"
-{
- rtx (*insn)(rtx);
-
- insn = (Pmode == DImode
- ? gen_lwp_slwpcbdi
- : gen_lwp_slwpcbsi);
-
- emit_insn (insn (operands[0]));
- DONE;
-})
-
-(define_insn "lwp_slwpcb<mode>"
- [(set (match_operand:P 0 "register_operand" "=r")
- (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
- "TARGET_LWP"
- "slwpcb\t%0"
- [(set_attr "type" "lwp")
- (set_attr "mode" "<MODE>")
- (set_attr "length" "5")])
-
-(define_expand "lwp_lwpval<mode>3"
- [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
- (match_operand:SI 2 "nonimmediate_operand" "rm")
- (match_operand:SI 3 "const_int_operand" "i")]
- UNSPECV_LWPVAL_INTRINSIC)]
- "TARGET_LWP"
- ;; Avoid unused variable warning.
- "(void) operands[0];")
-
-(define_insn "*lwp_lwpval<mode>3_1"
- [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
- (match_operand:SI 1 "nonimmediate_operand" "rm")
- (match_operand:SI 2 "const_int_operand" "i")]
- UNSPECV_LWPVAL_INTRINSIC)]
- "TARGET_LWP"
- "lwpval\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "type" "lwp")
- (set_attr "mode" "<MODE>")
- (set (attr "length")
- (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
-
-(define_expand "lwp_lwpins<mode>3"
- [(set (reg:CCC FLAGS_REG)
- (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
- (match_operand:SI 2 "nonimmediate_operand" "rm")
- (match_operand:SI 3 "const_int_operand" "i")]
- UNSPECV_LWPINS_INTRINSIC))
- (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
- (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
- "TARGET_LWP")
-
-(define_insn "*lwp_lwpins<mode>3_1"
- [(set (reg:CCC FLAGS_REG)
- (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
- (match_operand:SI 1 "nonimmediate_operand" "rm")
- (match_operand:SI 2 "const_int_operand" "i")]
- UNSPECV_LWPINS_INTRINSIC))]
- "TARGET_LWP"
- "lwpins\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "type" "lwp")
- (set_attr "mode" "<MODE>")
- (set (attr "length")
- (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
-
-(define_int_iterator RDFSGSBASE
- [UNSPECV_RDFSBASE
- UNSPECV_RDGSBASE])
-
-(define_int_iterator WRFSGSBASE
- [UNSPECV_WRFSBASE
- UNSPECV_WRGSBASE])
-
-(define_int_attr fsgs
- [(UNSPECV_RDFSBASE "fs")
- (UNSPECV_RDGSBASE "gs")
- (UNSPECV_WRFSBASE "fs")
- (UNSPECV_WRGSBASE "gs")])
-
-(define_insn "rd<fsgs>base<mode>"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
- "TARGET_64BIT && TARGET_FSGSBASE"
- "rd<fsgs>base\t%0"
- [(set_attr "type" "other")
- (set_attr "prefix_extra" "2")])
-
-(define_insn "wr<fsgs>base<mode>"
- [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
- WRFSGSBASE)]
- "TARGET_64BIT && TARGET_FSGSBASE"
- "wr<fsgs>base\t%0"
- [(set_attr "type" "other")
- (set_attr "prefix_extra" "2")])
-
-(define_insn "rdrand<mode>_1"
- [(set (match_operand:SWI248 0 "register_operand" "=r")
- (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
- (set (reg:CCC FLAGS_REG)
- (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
- "TARGET_RDRND"
- "rdrand\t%0"
- [(set_attr "type" "other")
- (set_attr "prefix_extra" "1")])
-
-(define_insn "rdseed<mode>_1"
- [(set (match_operand:SWI248 0 "register_operand" "=r")
- (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
- (set (reg:CCC FLAGS_REG)
- (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
- "TARGET_RDSEED"
- "rdseed\t%0"
- [(set_attr "type" "other")
- (set_attr "prefix_extra" "1")])
-
-(define_expand "pause"
- [(set (match_dup 0)
- (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
- ""
-{
- operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
- MEM_VOLATILE_P (operands[0]) = 1;
-})
-
-;; Use "rep; nop", instead of "pause", to support older assemblers.
-;; They have the same encoding.
-(define_insn "*pause"
- [(set (match_operand:BLK 0)
- (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
- ""
- "rep%; nop"
- [(set_attr "length" "2")
- (set_attr "memory" "unknown")])
-
-(define_expand "xbegin"
- [(set (match_operand:SI 0 "register_operand")
- (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
- "TARGET_RTM"
-{
- rtx label = gen_label_rtx ();
-
- /* xbegin is emitted as jump_insn, so reload won't be able
- to reload its operand. Force the value into AX hard register. */
- rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
- emit_move_insn (ax_reg, constm1_rtx);
-
- emit_jump_insn (gen_xbegin_1 (ax_reg, label));
-
- emit_label (label);
- LABEL_NUSES (label) = 1;
-
- emit_move_insn (operands[0], ax_reg);
-
- DONE;
-})
-
-(define_insn "xbegin_1"
- [(set (pc)
- (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
- (const_int 0))
- (label_ref (match_operand 1))
- (pc)))
- (set (match_operand:SI 0 "register_operand" "+a")
- (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
- "TARGET_RTM"
- "xbegin\t%l1"
- [(set_attr "type" "other")
- (set_attr "length" "6")])
-
-(define_insn "xend"
- [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
- "TARGET_RTM"
- "xend"
- [(set_attr "type" "other")
- (set_attr "length" "3")])
-
-(define_insn "xabort"
- [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
- UNSPECV_XABORT)]
- "TARGET_RTM"
- "xabort\t%0"
- [(set_attr "type" "other")
- (set_attr "length" "3")])
-
-(define_expand "xtest"
- [(set (match_operand:QI 0 "register_operand")
- (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
- "TARGET_RTM"
-{
- emit_insn (gen_xtest_1 ());
-
- ix86_expand_setcc (operands[0], NE,
- gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
- DONE;
-})
-
-(define_insn "xtest_1"
- [(set (reg:CCZ FLAGS_REG)
- (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
- "TARGET_RTM"
- "xtest"
- [(set_attr "type" "other")
- (set_attr "length" "3")])
-
-(include "mmx.md")
-(include "sse.md")
-(include "sync.md")
diff --git a/gcc-4.8/gcc/configure.ac.orig b/gcc-4.8/gcc/configure.ac.orig
deleted file mode 100644
index 6dd0b7e46..000000000
--- a/gcc-4.8/gcc/configure.ac.orig
+++ /dev/null
@@ -1,5352 +0,0 @@
-# configure.ac for GCC
-# Process this file with autoconf to generate a configuration script.
-
-# Copyright (C) 1997-2013 Free Software Foundation, Inc.
-
-#This file is part of GCC.
-
-#GCC is free software; you can redistribute it and/or modify it under
-#the terms of the GNU General Public License as published by the Free
-#Software Foundation; either version 3, or (at your option) any later
-#version.
-
-#GCC is distributed in the hope that it will be useful, but WITHOUT
-#ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-#FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-#for more details.
-
-#You should have received a copy of the GNU General Public License
-#along with GCC; see the file COPYING3. If not see
-#<http://www.gnu.org/licenses/>.
-
-# --------------------------------
-# Initialization and sanity checks
-# --------------------------------
-
-AC_PREREQ(2.64)
-AC_INIT
-AC_CONFIG_SRCDIR(tree.c)
-AC_CONFIG_HEADER(auto-host.h:config.in)
-
-gcc_version=`cat $srcdir/BASE-VER`
-
-# Determine the host, build, and target systems
-AC_CANONICAL_BUILD
-AC_CANONICAL_HOST
-AC_CANONICAL_TARGET
-
-# Determine the noncanonical target name, for directory use.
-ACX_NONCANONICAL_TARGET
-
-# Determine the target- and build-specific subdirectories
-GCC_TOPLEV_SUBDIRS
-
-# Set program_transform_name
-AC_ARG_PROGRAM
-
-# Check for bogus environment variables.
-# Test if LIBRARY_PATH contains the notation for the current directory
-# since this would lead to problems installing/building glibc.
-# LIBRARY_PATH contains the current directory if one of the following
-# is true:
-# - one of the terminals (":" and ";") is the first or last sign
-# - two terminals occur directly after each other
-# - the path contains an element with a dot in it
-AC_MSG_CHECKING(LIBRARY_PATH variable)
-changequote(,)dnl
-case ${LIBRARY_PATH} in
- [:\;]* | *[:\;] | *[:\;][:\;]* | *[:\;]. | .[:\;]*| . | *[:\;].[:\;]* )
- library_path_setting="contains current directory"
- ;;
- *)
- library_path_setting="ok"
- ;;
-esac
-changequote([,])dnl
-AC_MSG_RESULT($library_path_setting)
-if test "$library_path_setting" != "ok"; then
-AC_MSG_ERROR([
-*** LIBRARY_PATH shouldn't contain the current directory when
-*** building gcc. Please change the environment variable
-*** and run configure again.])
-fi
-
-# Test if GCC_EXEC_PREFIX contains the notation for the current directory
-# since this would lead to problems installing/building glibc.
-# GCC_EXEC_PREFIX contains the current directory if one of the following
-# is true:
-# - one of the terminals (":" and ";") is the first or last sign
-# - two terminals occur directly after each other
-# - the path contains an element with a dot in it
-AC_MSG_CHECKING(GCC_EXEC_PREFIX variable)
-changequote(,)dnl
-case ${GCC_EXEC_PREFIX} in
- [:\;]* | *[:\;] | *[:\;][:\;]* | *[:\;]. | .[:\;]*| . | *[:\;].[:\;]* )
- gcc_exec_prefix_setting="contains current directory"
- ;;
- *)
- gcc_exec_prefix_setting="ok"
- ;;
-esac
-changequote([,])dnl
-AC_MSG_RESULT($gcc_exec_prefix_setting)
-if test "$gcc_exec_prefix_setting" != "ok"; then
-AC_MSG_ERROR([
-*** GCC_EXEC_PREFIX shouldn't contain the current directory when
-*** building gcc. Please change the environment variable
-*** and run configure again.])
-fi
-
-# -----------
-# Directories
-# -----------
-
-# Specify the local prefix
-local_prefix=
-AC_ARG_WITH(local-prefix,
-[AS_HELP_STRING([--with-local-prefix=DIR],
- [specifies directory to put local include])],
-[case "${withval}" in
-yes) AC_MSG_ERROR(bad value ${withval} given for local include directory prefix) ;;
-no) ;;
-*) local_prefix=$with_local_prefix ;;
-esac])
-
-# Default local prefix if it is empty
-if test x$local_prefix = x; then
- local_prefix=/usr/local
-fi
-
-# Don't set gcc_gxx_include_dir to gxx_include_dir since that's only
-# passed in by the toplevel make and thus we'd get different behavior
-# depending on where we built the sources.
-gcc_gxx_include_dir=
-# Specify the g++ header file directory
-AC_ARG_WITH(gxx-include-dir,
-[AS_HELP_STRING([--with-gxx-include-dir=DIR],
- [specifies directory to put g++ header files])],
-[case "${withval}" in
-yes) AC_MSG_ERROR(bad value ${withval} given for g++ include directory) ;;
-no) ;;
-*) gcc_gxx_include_dir=$with_gxx_include_dir ;;
-esac])
-
-# This logic must match libstdc++-v3/acinclude.m4:GLIBCXX_EXPORT_INSTALL_INFO.
-if test x${gcc_gxx_include_dir} = x; then
- if test x${enable_version_specific_runtime_libs} = xyes; then
- gcc_gxx_include_dir='${libsubdir}/include/c++'
- else
- libstdcxx_incdir='include/c++/$(version)'
- if test x$host != x$target; then
- libstdcxx_incdir="$target_alias/$libstdcxx_incdir"
- fi
- gcc_gxx_include_dir="\$(libsubdir)/\$(libsubdir_to_prefix)$libstdcxx_incdir"
- fi
-fi
-
-gcc_gxx_include_dir_add_sysroot=0
-if test "${with_sysroot+set}" = set; then
- gcc_gxx_without_sysroot=`expr "${gcc_gxx_include_dir}" : "${with_sysroot}"'\(.*\)'`
- if test "${gcc_gxx_without_sysroot}"; then
- gcc_gxx_include_dir="${gcc_gxx_without_sysroot}"
- gcc_gxx_include_dir_add_sysroot=1
- fi
-fi
-
-AC_ARG_WITH(cpp_install_dir,
-[AC_HELP_STRING([--with-cpp-install-dir=DIR],
- [install the user visible C preprocessor in DIR
- (relative to PREFIX) as well as PREFIX/bin])],
-[if test x$withval = xyes; then
- AC_MSG_ERROR([option --with-cpp-install-dir requires an argument])
-elif test x$withval != xno; then
- cpp_install_dir=$withval
-fi])
-
-# We would like to our source tree to be readonly. However when releases or
-# pre-releases are generated, the flex/bison generated files as well as the
-# various formats of manuals need to be included along with the rest of the
-# sources. Therefore we have --enable-generated-files-in-srcdir to do
-# just that.
-
-AC_MSG_CHECKING([whether to place generated files in the source directory])
- dnl generated-files-in-srcdir is disabled by default
- AC_ARG_ENABLE(generated-files-in-srcdir,
- [AS_HELP_STRING([--enable-generated-files-in-srcdir],
- [put copies of generated files in source dir
- intended for creating source tarballs for users
- without texinfo bison or flex])],
- generated_files_in_srcdir=$enableval,
- generated_files_in_srcdir=no)
-
-AC_MSG_RESULT($generated_files_in_srcdir)
-
-if test "$generated_files_in_srcdir" = "yes"; then
- GENINSRC=''
-else
- GENINSRC='#'
-fi
-AC_SUBST(GENINSRC)
-
-# -------------------
-# Find default linker
-# -------------------
-
-# With GNU ld
-AC_ARG_WITH(gnu-ld,
-[AS_HELP_STRING([--with-gnu-ld], [arrange to work with GNU ld])],
-gnu_ld_flag="$with_gnu_ld",
-gnu_ld_flag=no)
-
-# With pre-defined ld
-AC_ARG_WITH(ld,
-[AS_HELP_STRING([--with-ld], [arrange to use the specified ld (full pathname)])],
-DEFAULT_LINKER="$with_ld")
-if test x"${DEFAULT_LINKER+set}" = x"set"; then
- if test ! -x "$DEFAULT_LINKER"; then
- AC_MSG_ERROR([cannot execute: $DEFAULT_LINKER: check --with-ld or env. var. DEFAULT_LINKER])
- elif $DEFAULT_LINKER -v < /dev/null 2>&1 | grep GNU > /dev/null; then
- gnu_ld_flag=yes
- fi
- AC_DEFINE_UNQUOTED(DEFAULT_LINKER,"$DEFAULT_LINKER",
- [Define to enable the use of a default linker.])
-fi
-
-AC_MSG_CHECKING([whether a default linker was specified])
-if test x"${DEFAULT_LINKER+set}" = x"set"; then
- if test x"$gnu_ld_flag" = x"no"; then
- AC_MSG_RESULT([yes ($DEFAULT_LINKER)])
- else
- AC_MSG_RESULT([yes ($DEFAULT_LINKER - GNU ld)])
- fi
-else
- AC_MSG_RESULT(no)
-fi
-
-# With demangler in GNU ld
-AC_ARG_WITH(demangler-in-ld,
-[AS_HELP_STRING([--with-demangler-in-ld], [try to use demangler in GNU ld])],
-demangler_in_ld="$with_demangler_in_ld",
-demangler_in_ld=yes)
-
-# ----------------------
-# Find default assembler
-# ----------------------
-
-# With GNU as
-AC_ARG_WITH(gnu-as,
-[AS_HELP_STRING([--with-gnu-as], [arrange to work with GNU as])],
-gas_flag="$with_gnu_as",
-gas_flag=no)
-
-AC_ARG_WITH(as,
-[AS_HELP_STRING([--with-as], [arrange to use the specified as (full pathname)])],
-DEFAULT_ASSEMBLER="$with_as")
-if test x"${DEFAULT_ASSEMBLER+set}" = x"set"; then
- if test ! -x "$DEFAULT_ASSEMBLER"; then
- AC_MSG_ERROR([cannot execute: $DEFAULT_ASSEMBLER: check --with-as or env. var. DEFAULT_ASSEMBLER])
- elif $DEFAULT_ASSEMBLER -v < /dev/null 2>&1 | grep GNU > /dev/null; then
- gas_flag=yes
- fi
- AC_DEFINE_UNQUOTED(DEFAULT_ASSEMBLER,"$DEFAULT_ASSEMBLER",
- [Define to enable the use of a default assembler.])
-fi
-
-AC_MSG_CHECKING([whether a default assembler was specified])
-if test x"${DEFAULT_ASSEMBLER+set}" = x"set"; then
- if test x"$gas_flag" = x"no"; then
- AC_MSG_RESULT([yes ($DEFAULT_ASSEMBLER)])
- else
- AC_MSG_RESULT([yes ($DEFAULT_ASSEMBLER - GNU as)])
- fi
-else
- AC_MSG_RESULT(no)
-fi
-
-# ---------------
-# Find C compiler
-# ---------------
-
-# If a non-executable a.out is present (e.g. created by GNU as above even if
-# invoked with -v only), the IRIX 6 native ld just overwrites the existing
-# file, even when creating an executable, so an execution test fails.
-# Remove possible default executable files to avoid this.
-#
-# FIXME: This really belongs into AC_PROG_CC and can be removed once
-# Autoconf includes it.
-rm -f a.out a.exe b.out
-
-# Find the native compiler
-AC_PROG_CC
-AM_PROG_CC_C_O
-AC_PROG_CXX
-ACX_PROG_GNAT([-I"$srcdir"/ada])
-
-# autoconf is lame and doesn't give us any substitution variable for this.
-if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" = no"; then
- NO_MINUS_C_MINUS_O=yes
-else
- OUTPUT_OPTION='-o $@'
-fi
-AC_SUBST(NO_MINUS_C_MINUS_O)
-AC_SUBST(OUTPUT_OPTION)
-
-# Remove the -O2: for historical reasons, unless bootstrapping we prefer
-# optimizations to be activated explicitly by the toplevel.
-case "$CC" in
- */prev-gcc/xgcc*) ;;
- *) CFLAGS=`echo "$CFLAGS " | sed -e "s/-Ofast[[ ]]//" -e "s/-O[[gs]][[ ]]//" -e "s/-O[[0-9]]*[[ ]]//" `
- CXXFLAGS=`echo "$CXXFLAGS " | sed -e "s/-Ofast[[ ]]//" -e "s/-O[[gs]][[ ]]//" -e "s/-O[[0-9]]*[[ ]]//" ` ;;
-esac
-AC_SUBST(CFLAGS)
-AC_SUBST(CXXFLAGS)
-
-# Determine PICFLAG for target gnatlib.
-GCC_PICFLAG_FOR_TARGET
-AC_SUBST(PICFLAG_FOR_TARGET)
-
-# -------------------------
-# Check C compiler features
-# -------------------------
-
-AC_USE_SYSTEM_EXTENSIONS
-AC_PROG_CPP
-AC_C_INLINE
-
-AC_SYS_LARGEFILE
-
-# sizeof(char) is 1 by definition.
-AC_CHECK_SIZEOF(void *)
-AC_CHECK_SIZEOF(short)
-AC_CHECK_SIZEOF(int)
-AC_CHECK_SIZEOF(long)
-AC_CHECK_TYPES([long long], [AC_CHECK_SIZEOF(long long)])
-AC_CHECK_TYPES([__int64], [AC_CHECK_SIZEOF(__int64)])
-GCC_STDINT_TYPES
-
-# ---------------------
-# Warnings and checking
-# ---------------------
-
-# Check $CC warning features (if it's GCC).
-# We want to use -pedantic, but we don't want warnings about
-# * 'long long'
-# * variadic macros
-# * overlong strings
-# * C++11 narrowing conversions in { }
-# So, we only use -pedantic if we can disable those warnings.
-
-ACX_PROG_CC_WARNING_OPTS(
- m4_quote(m4_do([-W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual])), [loose_warn])
-ACX_PROG_CC_WARNING_OPTS(
- m4_quote(m4_do([-Wstrict-prototypes -Wmissing-prototypes])),
- [c_loose_warn])
-ACX_PROG_CC_WARNING_OPTS(
- m4_quote(m4_do([-Wmissing-format-attribute])), [strict_warn])
-ACX_PROG_CC_WARNING_OPTS(
- m4_quote(m4_do([-Wold-style-definition -Wc++-compat])), [c_strict_warn])
-ACX_PROG_CC_WARNING_ALMOST_PEDANTIC(
- m4_quote(m4_do([-Wno-long-long -Wno-variadic-macros ],
- [-Wno-overlength-strings])), [strict_warn])
-ACX_PROG_CC_WARNINGS_ARE_ERRORS([manual], [strict_warn])
-
-# The above macros do nothing if the compiler is not GCC. However, the
-# Makefile has more goo to add other flags, so these variables are used
-# to enable warnings only for GCC.
-warn_cflags=
-warn_cxxflags=
-if test "x$GCC" = "xyes"; then
- warn_cflags='$(GCC_WARN_CFLAGS)'
- warn_cxxflags='$(GCC_WARN_CXXFLAGS)'
-fi
-AC_SUBST(warn_cflags)
-AC_SUBST(warn_cxxflags)
-
-# Disable exceptions and RTTI if building with g++
-ACX_PROG_CC_WARNING_OPTS(
- m4_quote(m4_do([-fno-exceptions -fno-rtti -fasynchronous-unwind-tables])),
- [noexception_flags])
-
-# Enable expensive internal checks
-is_release=
-if test x"`cat $srcdir/DEV-PHASE`" != xexperimental; then
- is_release=yes
-fi
-
-AC_ARG_ENABLE(checking,
-[AS_HELP_STRING([[--enable-checking[=LIST]]],
- [enable expensive run-time checks. With LIST,
- enable only specific categories of checks.
- Categories are: yes,no,all,none,release.
- Flags are: assert,df,fold,gc,gcac,gimple,misc,
- rtlflag,rtl,runtime,tree,valgrind,types])],
-[ac_checking_flags="${enableval}"],[
-# Determine the default checks.
-if test x$is_release = x ; then
- ac_checking_flags=yes
-else
- ac_checking_flags=release
-fi])
-IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="$IFS,"
-for check in release $ac_checking_flags
-do
- case $check in
- # these set all the flags to specific states
- yes) ac_assert_checking=1 ; ac_checking=1 ; ac_df_checking= ;
- ac_fold_checking= ; ac_gc_checking=1 ;
- ac_gc_always_collect= ; ac_gimple_checking=1 ; ac_rtl_checking= ;
- ac_rtlflag_checking=1 ; ac_runtime_checking=1 ;
- ac_tree_checking=1 ; ac_valgrind_checking= ;
- ac_types_checking=1 ;;
- no|none) ac_assert_checking= ; ac_checking= ; ac_df_checking= ;
- ac_fold_checking= ; ac_gc_checking= ;
- ac_gc_always_collect= ; ac_gimple_checking= ; ac_rtl_checking= ;
- ac_rtlflag_checking= ; ac_runtime_checking= ;
- ac_tree_checking= ; ac_valgrind_checking= ;
- ac_types_checking= ;;
- all) ac_assert_checking=1 ; ac_checking=1 ; ac_df_checking=1 ;
- ac_fold_checking=1 ; ac_gc_checking=1 ;
- ac_gc_always_collect=1 ; ac_gimple_checking=1 ; ac_rtl_checking=1 ;
- ac_rtlflag_checking=1 ; ac_runtime_checking=1 ;
- ac_tree_checking=1 ; ac_valgrind_checking= ;
- ac_types_checking=1 ;;
- release) ac_assert_checking=1 ; ac_checking= ; ac_df_checking= ;
- ac_fold_checking= ; ac_gc_checking= ;
- ac_gc_always_collect= ; ac_gimple_checking= ; ac_rtl_checking= ;
- ac_rtlflag_checking= ; ac_runtime_checking=1 ;
- ac_tree_checking= ; ac_valgrind_checking= ;
- ac_types_checking= ;;
- # these enable particular checks
- assert) ac_assert_checking=1 ;;
- df) ac_df_checking=1 ;;
- fold) ac_fold_checking=1 ;;
- gc) ac_gc_checking=1 ;;
- gcac) ac_gc_always_collect=1 ;;
- gimple) ac_gimple_checking=1 ;;
- misc) ac_checking=1 ;;
- rtl) ac_rtl_checking=1 ;;
- rtlflag) ac_rtlflag_checking=1 ;;
- runtime) ac_runtime_checking=1 ;;
- tree) ac_tree_checking=1 ;;
- types) ac_types_checking=1 ;;
- valgrind) ac_valgrind_checking=1 ;;
- *) AC_MSG_ERROR(unknown check category $check) ;;
- esac
-done
-IFS="$ac_save_IFS"
-
-nocommon_flag=""
-if test x$ac_checking != x ; then
- AC_DEFINE(ENABLE_CHECKING, 1,
-[Define if you want more run-time sanity checks. This one gets a grab
- bag of miscellaneous but relatively cheap checks.])
- nocommon_flag=-fno-common
-fi
-AC_SUBST(nocommon_flag)
-if test x$ac_df_checking != x ; then
- AC_DEFINE(ENABLE_DF_CHECKING, 1,
-[Define if you want more run-time sanity checks for dataflow.])
-fi
-if test x$ac_assert_checking != x ; then
- AC_DEFINE(ENABLE_ASSERT_CHECKING, 1,
-[Define if you want assertions enabled. This is a cheap check.])
-fi
-if test x$ac_gimple_checking != x ; then
- AC_DEFINE(ENABLE_GIMPLE_CHECKING, 1,
-[Define if you want operations on GIMPLE (the basic data structure of
-the high-level optimizers) to be checked for dynamic type safety at
-runtime. This is moderately expensive.])
-fi
-GCC_TARGET_TEMPLATE(ENABLE_RUNTIME_CHECKING)
-if test x$ac_runtime_checking != x ; then
- AC_DEFINE(ENABLE_RUNTIME_CHECKING, 1,
-[Define if you want runtime assertions enabled. This is a cheap check.])
-fi
-if test x$ac_tree_checking != x ; then
- AC_DEFINE(ENABLE_TREE_CHECKING, 1,
-[Define if you want all operations on trees (the basic data
- structure of the front ends) to be checked for dynamic type safety
- at runtime. This is moderately expensive. The tree browser debugging
- routines will also be enabled by this option.
- ])
- TREEBROWSER=tree-browser.o
- TREECHECKING=yes
-fi
-if test x$ac_types_checking != x ; then
- AC_DEFINE(ENABLE_TYPES_CHECKING, 1,
-[Define if you want all gimple types to be verified after gimplifiation.
- This is cheap.
- ])
-fi
-AC_SUBST(TREEBROWSER)
-AC_SUBST(TREECHECKING)
-if test x$ac_rtl_checking != x ; then
- AC_DEFINE(ENABLE_RTL_CHECKING, 1,
-[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.])
-fi
-if test x$ac_rtlflag_checking != x ; then
- AC_DEFINE(ENABLE_RTL_FLAG_CHECKING, 1,
-[Define if you want RTL flag accesses to be checked against the RTL
- codes that are supported for each access macro. This is relatively
- cheap.])
-fi
-if test x$ac_gc_checking != x ; then
- AC_DEFINE(ENABLE_GC_CHECKING, 1,
-[Define if you want the garbage collector to do object poisoning and
- other memory allocation checks. This is quite expensive.])
-fi
-if test x$ac_gc_always_collect != x ; then
- AC_DEFINE(ENABLE_GC_ALWAYS_COLLECT, 1,
-[Define if you want the garbage collector to operate in maximally
- paranoid mode, validating the entire heap and collecting garbage at
- every opportunity. This is extremely expensive.])
-fi
-if test x$ac_fold_checking != x ; then
- AC_DEFINE(ENABLE_FOLD_CHECKING, 1,
-[Define if you want fold checked that it never destructs its argument.
- This is quite expensive.])
-fi
-valgrind_path_defines=
-valgrind_command=
-
-dnl # This check AC_REQUIREs various stuff, so it *must not* be inside
-dnl # an if statement. This was the source of very frustrating bugs
-dnl # in converting to autoconf 2.5x!
-AC_CHECK_HEADER(valgrind.h, have_valgrind_h=yes, have_valgrind_h=no)
-
-if test x$ac_valgrind_checking != x ; then
- # It is certainly possible that there's valgrind but no valgrind.h.
- # GCC relies on making annotations so we must have both.
- AC_MSG_CHECKING(for VALGRIND_DISCARD in <valgrind/memcheck.h>)
- AC_PREPROC_IFELSE([AC_LANG_SOURCE(
- [[#include <valgrind/memcheck.h>
-#ifndef VALGRIND_DISCARD
-#error VALGRIND_DISCARD not defined
-#endif]])],
- [gcc_cv_header_valgrind_memcheck_h=yes],
- [gcc_cv_header_valgrind_memcheck_h=no])
- AC_MSG_RESULT($gcc_cv_header_valgrind_memcheck_h)
- AC_MSG_CHECKING(for VALGRIND_DISCARD in <memcheck.h>)
- AC_PREPROC_IFELSE([AC_LANG_SOURCE(
- [[#include <memcheck.h>
-#ifndef VALGRIND_DISCARD
-#error VALGRIND_DISCARD not defined
-#endif]])],
- [gcc_cv_header_memcheck_h=yes],
- [gcc_cv_header_memcheck_h=no])
- AC_MSG_RESULT($gcc_cv_header_memcheck_h)
- AM_PATH_PROG_WITH_TEST(valgrind_path, valgrind,
- [$ac_dir/$ac_word --version | grep valgrind- >/dev/null 2>&1])
- if test "x$valgrind_path" = "x" \
- || (test $have_valgrind_h = no \
- && test $gcc_cv_header_memcheck_h = no \
- && test $gcc_cv_header_valgrind_memcheck_h = no); then
- AC_MSG_ERROR([*** Can't find both valgrind and valgrind/memcheck.h, memcheck.h or valgrind.h])
- fi
- valgrind_path_defines=-DVALGRIND_PATH='\"'$valgrind_path'\"'
- valgrind_command="$valgrind_path -q"
- AC_DEFINE(ENABLE_VALGRIND_CHECKING, 1,
-[Define if you want to run subprograms and generated programs
- through valgrind (a memory checker). This is extremely expensive.])
- if test $gcc_cv_header_valgrind_memcheck_h = yes; then
- AC_DEFINE(HAVE_VALGRIND_MEMCHECK_H, 1,
- [Define if valgrind's valgrind/memcheck.h header is installed.])
- fi
- if test $gcc_cv_header_memcheck_h = yes; then
- AC_DEFINE(HAVE_MEMCHECK_H, 1,
- [Define if valgrind's memcheck.h header is installed.])
- fi
-fi
-AC_SUBST(valgrind_path_defines)
-AC_SUBST(valgrind_command)
-
-# Enable code coverage collection
-AC_ARG_ENABLE(coverage,
-[AS_HELP_STRING([[--enable-coverage[=LEVEL]]],
- [enable compiler's code coverage collection.
- Use to measure compiler performance and locate
- unused parts of the compiler. With LEVEL, specify
- optimization. Values are opt, noopt,
- default is noopt])],
-[case "${enableval}" in
- yes|noopt)
- coverage_flags="-fprofile-arcs -ftest-coverage -frandom-seed=\$@ -O0"
- ;;
- opt)
- coverage_flags="-fprofile-arcs -ftest-coverage -frandom-seed=\$@ -O2"
- ;;
- no)
- # a.k.a. --disable-coverage
- coverage_flags=""
- ;;
- *)
- AC_MSG_ERROR(unknown coverage setting $enableval)
- ;;
-esac],
-[coverage_flags=""])
-AC_SUBST(coverage_flags)
-
-AC_ARG_ENABLE(gather-detailed-mem-stats,
-[AS_HELP_STRING([--enable-gather-detailed-mem-stats],
- [enable detailed memory allocation stats gathering])], [],
-[enable_gather_detailed_mem_stats=no])
-gather_stats=`if test $enable_gather_detailed_mem_stats != no; then echo 1; else echo 0; fi`
-AC_DEFINE_UNQUOTED(GATHER_STATISTICS, $gather_stats,
-[Define to enable detailed memory allocation stats gathering.])
-
-# -------------------------------
-# Miscenalleous configure options
-# -------------------------------
-
-# With stabs
-AC_ARG_WITH(stabs,
-[AS_HELP_STRING([--with-stabs],
- [arrange to use stabs instead of host debug format])],
-stabs="$with_stabs",
-stabs=no)
-
-# Determine whether or not multilibs are enabled.
-AC_ARG_ENABLE(multilib,
-[AS_HELP_STRING([--enable-multilib],
- [enable library support for multiple ABIs])],
-[], [enable_multilib=yes])
-AC_SUBST(enable_multilib)
-
-# Determine whether or not multiarch is enabled.
-AC_ARG_ENABLE(multiarch,
-[AS_HELP_STRING([--enable-multiarch],
- [enable support for multiarch paths])],
-[case "${enableval}" in
-yes|no|auto) enable_multiarch=$enableval;;
-*) AC_MSG_ERROR(bad value ${enableval} given for --enable-multiarch option) ;;
-esac], [enable_multiarch=auto])
-if test x${enable_multiarch} = xauto; then
- if test x${with_native_system_header_dir} != x; then
- ma_msg_suffix=", disabled auto check (configured with --native-system-header-dir)"
- enable_multiarch=no
- fi
- if test x$host != x$target && test "x$with_sysroot" = x; then
- ma_msg_suffix=", disabled auto check (cross build configured without --with-sysroot)"
- enable_multiarch=no
- fi
-fi
-AC_MSG_CHECKING(for multiarch configuration)
-AC_SUBST(enable_multiarch)
-AC_MSG_RESULT($enable_multiarch$ma_msg_suffix)
-
-# needed for setting the multiarch name for soft-float/hard-float ABIs
-AC_SUBST(with_cpu)
-AC_SUBST(with_float)
-
-# Enable __cxa_atexit for C++.
-AC_ARG_ENABLE(__cxa_atexit,
-[AS_HELP_STRING([--enable-__cxa_atexit], [enable __cxa_atexit for C++])],
-[], [])
-
-# Enable C extension for decimal float if target supports it.
-GCC_AC_ENABLE_DECIMAL_FLOAT([$target])
-
-dfp=`if test $enable_decimal_float != no; then echo 1; else echo 0; fi`
-AC_DEFINE_UNQUOTED(ENABLE_DECIMAL_FLOAT, $dfp,
-[Define to 1 to enable decimal float extension to C.])
-
-# Use default_decimal_float for dependency.
-enable_decimal_float=$default_decimal_float
-
-bid=`if test $enable_decimal_float = bid; then echo 1; else echo 0; fi`
-AC_DEFINE_UNQUOTED(ENABLE_DECIMAL_BID_FORMAT, $bid,
-[Define to 1 to specify that we are using the BID decimal floating
-point format instead of DPD])
-
-# Enable C extension for fixed-point arithmetic.
-AC_ARG_ENABLE(fixed-point,
-[AS_HELP_STRING([--enable-fixed-point],
- [enable fixed-point arithmetic extension to C])],
-[],
-[
- case $target in
- arm*)
- enable_fixed_point=yes
- ;;
-
- mips*-*-*)
- enable_fixed_point=yes
- ;;
- *)
- AC_MSG_WARN([fixed-point is not supported for this target, ignored])
- enable_fixed_point=no
- ;;
- esac
-])
-AC_SUBST(enable_fixed_point)
-
-fixedpoint=`if test $enable_fixed_point = yes; then echo 1; else echo 0; fi`
-AC_DEFINE_UNQUOTED(ENABLE_FIXED_POINT, $fixedpoint,
-[Define to 1 to enable fixed-point arithmetic extension to C.])
-
-# Enable threads
-# Pass with no value to take the default
-# Pass with a value to specify a thread package
-AC_ARG_ENABLE(threads,
-[AS_HELP_STRING([[--enable-threads[=LIB]]],
- [enable thread usage for target GCC,
- using LIB thread package])],,
-[enable_threads=''])
-
-AC_ARG_ENABLE(tls,
-[AS_HELP_STRING([--enable-tls],
- [enable or disable generation of tls code
- overriding the assembler check for tls support])],
-[
- case $enable_tls in
- yes | no) ;;
- *) AC_MSG_ERROR(['$enable_tls' is an invalid value for --enable-tls.
-Valid choices are 'yes' and 'no'.]) ;;
- esac
-], [enable_tls=''])
-
-AC_ARG_ENABLE(objc-gc,
-[AS_HELP_STRING([--enable-objc-gc],
- [enable the use of Boehm's garbage collector with
- the GNU Objective-C runtime])],
-if test x$enable_objc_gc = xno; then
- objc_boehm_gc=''
-else
- objc_boehm_gc=1
-fi,
-objc_boehm_gc='')
-
-AC_ARG_WITH(dwarf2,
-[AS_HELP_STRING([--with-dwarf2], [force the default debug format to be DWARF 2])],
-dwarf2="$with_dwarf2",
-dwarf2=no)
-
-AC_ARG_ENABLE(shared,
-[AS_HELP_STRING([--disable-shared], [don't provide a shared libgcc])],
-[
- case $enable_shared in
- yes | no) ;;
- *)
- enable_shared=no
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
- for pkg in $enableval; do
- if test "X$pkg" = "Xgcc" || test "X$pkg" = "Xlibgcc"; then
- enable_shared=yes
- fi
- done
- IFS="$ac_save_ifs"
- ;;
- esac
-], [enable_shared=yes])
-AC_SUBST(enable_shared)
-
-AC_ARG_WITH([native-system-header-dir],
- [ --with-native-system-header-dir=dir
- use dir as the directory to look for standard
- system header files in. Defaults to /usr/include.],
-[
- case ${with_native_system_header_dir} in
- yes|no) AC_MSG_ERROR([bad value ${withval} given for --with-native-system-header-dir]) ;;
- /* | [[A-Za-z]]:[[\\/]]*) ;;
- *) AC_MSG_ERROR([--with-native-system-header-dir argument ${withval} must be an absolute directory]) ;;
- esac
- configured_native_system_header_dir="${withval}"
-], [configured_native_system_header_dir=])
-
-AC_ARG_WITH(build-sysroot,
- [AS_HELP_STRING([--with-build-sysroot=sysroot],
- [use sysroot as the system root during the build])],
- [if test x"$withval" != x ; then
- SYSROOT_CFLAGS_FOR_TARGET="--sysroot=$withval"
- fi],
- [SYSROOT_CFLAGS_FOR_TARGET=])
-AC_SUBST(SYSROOT_CFLAGS_FOR_TARGET)
-
-if test "x$prefix" = xNONE; then
- test_prefix=/usr/local
-else
- test_prefix=$prefix
-fi
-if test "x$exec_prefix" = xNONE; then
- test_exec_prefix=$test_prefix
-else
- test_exec_prefix=$exec_prefix
-fi
-
-AC_ARG_WITH(sysroot,
-[AS_HELP_STRING([[--with-sysroot[=DIR]]],
- [search for usr/lib, usr/include, et al, within DIR])],
-[
- case ${with_sysroot} in
- yes) TARGET_SYSTEM_ROOT='${exec_prefix}/${target_noncanonical}/sys-root' ;;
- *) TARGET_SYSTEM_ROOT=$with_sysroot ;;
- esac
-
- TARGET_SYSTEM_ROOT_DEFINE='-DTARGET_SYSTEM_ROOT=\"$(TARGET_SYSTEM_ROOT)\"'
- CROSS_SYSTEM_HEADER_DIR='$(TARGET_SYSTEM_ROOT)$${sysroot_headers_suffix}$(NATIVE_SYSTEM_HEADER_DIR)'
-
- case ${TARGET_SYSTEM_ROOT} in
- "${test_prefix}"|"${test_prefix}/"*|\
- "${test_exec_prefix}"|"${test_exec_prefix}/"*|\
- '${prefix}'|'${prefix}/'*|\
- '${exec_prefix}'|'${exec_prefix}/'*)
- t="$TARGET_SYSTEM_ROOT_DEFINE -DTARGET_SYSTEM_ROOT_RELOCATABLE"
- TARGET_SYSTEM_ROOT_DEFINE="$t"
- ;;
- esac
-], [
- TARGET_SYSTEM_ROOT=
- TARGET_SYSTEM_ROOT_DEFINE=
- CROSS_SYSTEM_HEADER_DIR='$(gcc_tooldir)/sys-include'
-])
-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)
-
-ACX_PKGVERSION([GCC])
-ACX_BUGURL([http://gcc.gnu.org/bugs.html])
-
-# Sanity check enable_languages in case someone does not run the toplevel
-# configure # script.
-AC_ARG_ENABLE(languages,
-[AS_HELP_STRING([--enable-languages=LIST], [specify which front-ends to build])],
-[case ,${enable_languages}, in
- ,,|,yes,)
- # go safe -- we cannot be much sure without the toplevel
- # configure's
- # analysis of which target libs are present and usable
- enable_languages=c
- ;;
- *,all,*)
- AC_MSG_ERROR([only the toplevel supports --enable-languages=all])
- ;;
- *,c,*)
- ;;
- *)
- enable_languages=c,${enable_languages}
- ;;
-esac],
-[enable_languages=c])
-
-AC_ARG_WITH(multilib-list,
-[AS_HELP_STRING([--with-multilib-list], [select multilibs (SH and x86-64 only)])],
-:,
-with_multilib_list=default)
-
-# -------------------------
-# Checks for other programs
-# -------------------------
-
-AC_PROG_MAKE_SET
-
-# Find some useful tools
-AC_PROG_AWK
-# We need awk to create options.c and options.h.
-# Bail out if it's missing.
-case ${AWK} in
- "") AC_MSG_ERROR([can't build without awk, bailing out]) ;;
-esac
-
-gcc_AC_PROG_LN_S
-ACX_PROG_LN($LN_S)
-AC_PROG_RANLIB
-ranlib_flags=""
-AC_SUBST(ranlib_flags)
-
-gcc_AC_PROG_INSTALL
-
-# See if cmp has --ignore-initial.
-gcc_AC_PROG_CMP_IGNORE_INITIAL
-
-# See if we have the mktemp command.
-AC_CHECK_PROG(have_mktemp_command, mktemp, yes, no)
-
-# See if makeinfo has been installed and is modern enough
-# that we can use it.
-ACX_CHECK_PROG_VER(MAKEINFO, makeinfo, --version,
- [GNU texinfo.* \([0-9][0-9.]*\)],
- [4.[7-9]*|4.[1-9][0-9]*|[5-9]*|[1-9][0-9]*])
-if test $gcc_cv_prog_makeinfo_modern = no; then
- AC_MSG_WARN([
-*** Makeinfo is missing or too old.
-*** Info documentation will not be built.])
- BUILD_INFO=
-else
- BUILD_INFO=info
-fi
-AC_SUBST(BUILD_INFO)
-
-# Is pod2man recent enough to regenerate manpages?
-AC_MSG_CHECKING([for recent Pod::Man])
-if (perl -e 'use 1.10 Pod::Man') >/dev/null 2>&1; then
- AC_MSG_RESULT(yes)
- GENERATED_MANPAGES=generated-manpages
-else
- AC_MSG_RESULT(no)
- GENERATED_MANPAGES=
-fi
-AC_SUBST(GENERATED_MANPAGES)
-
-MISSING="${CONFIG_SHELL-/bin/sh} $ac_aux_dir/missing"
-
-# How about lex?
-dnl Don't use AC_PROG_LEX; we insist on flex.
-dnl LEXLIB is not useful in gcc.
-AC_CHECK_PROGS([FLEX], flex, [$MISSING flex])
-
-# Bison?
-AC_CHECK_PROGS([BISON], bison, [$MISSING bison])
-
-# Binutils are not build modules, unlike bison/flex/makeinfo. So we
-# check for build == host before using them.
-
-# NM
-if test x${build} = x${host} && test -f $srcdir/../binutils/nm.c \
- && test -d ../binutils ; then
- NM='${objdir}/../binutils/nm-new'
-else
- AC_CHECK_PROG(NM, nm, nm, ${CONFIG_SHELL-/bin/sh} ${srcdir}/../missing nm)
-fi
-
-# AR
-if test x${build} = x${host} && test -f $srcdir/../binutils/ar.c \
- && test -d ../binutils ; then
- AR='${objdir}/../binutils/ar'
-else
- AC_CHECK_PROG(AR, ar, ar, ${CONFIG_SHELL-/bin/sh} ${srcdir}/../missing ar)
-fi
-
-
-# --------------------
-# Checks for C headers
-# --------------------
-
-# Need to reject headers which give warnings, so that the -Werror bootstrap
-# works later. *sigh* This needs to come before all header checks.
-AC_PROG_CPP_WERROR
-
-AC_HEADER_STDC
-AC_HEADER_TIME
-ACX_HEADER_STRING
-AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS(limits.h stddef.h string.h strings.h stdlib.h time.h iconv.h \
- fcntl.h unistd.h sys/file.h sys/time.h sys/mman.h \
- sys/resource.h sys/param.h sys/times.h sys/stat.h \
- direct.h malloc.h langinfo.h ldfcn.h locale.h wchar.h)
-
-# Check for thread headers.
-AC_CHECK_HEADER(thread.h, [have_thread_h=yes], [have_thread_h=])
-AC_CHECK_HEADER(pthread.h, [have_pthread_h=yes], [have_pthread_h=])
-
-# These tests can't be done till we know if we have limits.h.
-gcc_AC_C_CHAR_BIT
-AC_C_BIGENDIAN
-
-# ----------------------
-# Checks for C++ headers
-# ----------------------
-
-dnl Autoconf will give an error in the configure script if there is no
-dnl C++ preprocessor. Hack to prevent that.
-m4_pushdef([AC_MSG_ERROR], m4_defn([AC_MSG_WARN]))[]dnl
-AC_PROG_CXXCPP
-m4_popdef([AC_MSG_ERROR])[]dnl
-
-AC_LANG_PUSH(C++)
-
-AC_CHECK_HEADERS(unordered_map)
-AC_CHECK_HEADERS(tr1/unordered_map)
-AC_CHECK_HEADERS(ext/hash_map)
-
-AC_LANG_POP(C++)
-
-# --------
-# UNSORTED
-# --------
-
-
-# These libraries may be used by collect2.
-# We may need a special search path to get them linked.
-AC_CACHE_CHECK(for collect2 libraries, gcc_cv_collect2_libs,
-[save_LIBS="$LIBS"
-for libs in '' -lld -lmld \
- '-L/usr/lib/cmplrs/cc2.11 -lmld' \
- '-L/usr/lib/cmplrs/cc3.11 -lmld'
-do
- LIBS="$libs"
- AC_TRY_LINK_FUNC(ldopen,
- [gcc_cv_collect2_libs="$libs"; break])
-done
-LIBS="$save_LIBS"
-test -z "$gcc_cv_collect2_libs" && gcc_cv_collect2_libs='none required'])
-case $gcc_cv_collect2_libs in
- "none required") ;;
- *) COLLECT2_LIBS=$gcc_cv_collect2_libs ;;
-esac
-AC_SUBST(COLLECT2_LIBS)
-
-# When building Ada code on Alpha, we need exc_resume which is usually in
-# -lexc. So test for it.
-save_LIBS="$LIBS"
-LIBS=
-AC_SEARCH_LIBS(exc_resume, exc)
-GNAT_LIBEXC="$LIBS"
-LIBS="$save_LIBS"
-AC_SUBST(GNAT_LIBEXC)
-
-# To support -mcpu=native on Solaris/SPARC, we need libkstat.
-save_LIBS="$LIBS"
-LIBS=
-AC_SEARCH_LIBS(kstat_open, kstat)
-EXTRA_GCC_LIBS="$LIBS"
-LIBS="$save_LIBS"
-AC_SUBST(EXTRA_GCC_LIBS)
-
-# Some systems put ldexp and frexp in libm instead of libc; assume
-# they're both in the same place. jcf-dump needs them.
-save_LIBS="$LIBS"
-LIBS=
-AC_SEARCH_LIBS(ldexp, m)
-LDEXP_LIB="$LIBS"
-LIBS="$save_LIBS"
-AC_SUBST(LDEXP_LIB)
-
-# Use <inttypes.h> only if it exists,
-# doesn't clash with <sys/types.h>, and declares intmax_t.
-AC_MSG_CHECKING(for inttypes.h)
-AC_CACHE_VAL(gcc_cv_header_inttypes_h,
-[AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
-[[#include <sys/types.h>
-#include <inttypes.h>]],
- [[intmax_t i = -1;]])],
- [gcc_cv_header_inttypes_h=yes],
- [gcc_cv_header_inttypes_h=no])])
-AC_MSG_RESULT($gcc_cv_header_inttypes_h)
-if test $gcc_cv_header_inttypes_h = yes; then
- AC_DEFINE(HAVE_INTTYPES_H, 1,
- [Define if you have a working <inttypes.h> header file.])
-fi
-
-dnl Disabled until we have a complete test for buggy enum bitfields.
-dnl gcc_AC_C_ENUM_BF_UNSIGNED
-
-define(gcc_UNLOCKED_FUNCS, clearerr_unlocked feof_unlocked dnl
- ferror_unlocked fflush_unlocked fgetc_unlocked fgets_unlocked dnl
- fileno_unlocked fprintf_unlocked fputc_unlocked fputs_unlocked dnl
- fread_unlocked fwrite_unlocked getchar_unlocked getc_unlocked dnl
- putchar_unlocked putc_unlocked)
-AC_CHECK_FUNCS(times clock kill getrlimit setrlimit atoll atoq \
- sysconf strsignal getrusage nl_langinfo \
- gettimeofday mbstowcs wcswidth mmap setlocale \
- gcc_UNLOCKED_FUNCS madvise)
-
-if test x$ac_cv_func_mbstowcs = xyes; then
- AC_CACHE_CHECK(whether mbstowcs works, gcc_cv_func_mbstowcs_works,
-[ AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <stdlib.h>
-int main()
-{
- mbstowcs(0, "", 0);
- return 0;
-}]])],
- [gcc_cv_func_mbstowcs_works=yes],
- [gcc_cv_func_mbstowcs_works=no],
- [gcc_cv_func_mbstowcs_works=yes])])
- if test x$gcc_cv_func_mbstowcs_works = xyes; then
- AC_DEFINE(HAVE_WORKING_MBSTOWCS, 1,
- [Define this macro if mbstowcs does not crash when its
- first argument is NULL.])
- fi
-fi
-
-AC_CHECK_TYPE(ssize_t, int)
-AC_CHECK_TYPE(caddr_t, char *)
-
-GCC_AC_FUNC_MMAP_BLACKLIST
-
-case "${host}" in
-*-*-*vms*)
- # Under VMS, vfork works very differently than on Unix. The standard test
- # won't work, and it isn't easily adaptable. It makes more sense to
- # just force it.
- ac_cv_func_vfork_works=yes
- ;;
-esac
-AC_FUNC_FORK
-
-# g++ on Solaris 10+ defines _XOPEN_SOURCE=600, which exposes a different
-# iconv() prototype.
-AC_LANG_PUSH([C++])
-AM_ICONV
-AC_LANG_POP([C++])
-
-# Until we have in-tree GNU iconv:
-LIBICONV_DEP=
-AC_SUBST(LIBICONV_DEP)
-
-AM_LC_MESSAGES
-
-AM_LANGINFO_CODESET
-
-# We will need to find libiberty.h and ansidecl.h
-saved_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS -I${srcdir} -I${srcdir}/../include $GMPINC"
-saved_CXXFLAGS="$CXXFLAGS"
-CXXFLAGS="$CXXFLAGS -I${srcdir} -I${srcdir}/../include $GMPINC"
-gcc_AC_CHECK_DECLS(getenv atol asprintf sbrk abort atof getcwd getwd \
- strsignal strstr stpcpy strverscmp \
- errno snprintf vsnprintf vasprintf malloc realloc calloc \
- free basename getopt clock getpagesize ffs gcc_UNLOCKED_FUNCS, , ,[
-#include "ansidecl.h"
-#include "system.h"])
-
-gcc_AC_CHECK_DECLS(getrlimit setrlimit getrusage, , ,[
-#include "ansidecl.h"
-#include "system.h"
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/resource.h>
-#endif
-])
-
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
-#include "ansidecl.h"
-#include "system.h"
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/resource.h>
-#endif
-]], [[rlim_t l = 0;]])],[],[AC_DEFINE([rlim_t],[long],
-[Define to `long' if <sys/resource.h> doesn't define.])])
-
-# On AIX 5.2, <ldfcn.h> conflicts with <fcntl.h>, as both define incompatible
-# FREAD and FWRITE macros. Fortunately, for GCC's single usage of ldgetname
-# in collect2.c, <fcntl.h> isn't visible, but the configure test below needs
-# to undef these macros to get the correct value for HAVE_DECL_LDGETNAME.
-gcc_AC_CHECK_DECLS(ldgetname, , ,[
-#include "ansidecl.h"
-#include "system.h"
-#ifdef HAVE_LDFCN_H
-#undef FREAD
-#undef FWRITE
-#include <ldfcn.h>
-#endif
-])
-
-gcc_AC_CHECK_DECLS(times, , ,[
-#include "ansidecl.h"
-#include "system.h"
-#ifdef HAVE_SYS_TIMES_H
-#include <sys/times.h>
-#endif
-])
-
-gcc_AC_CHECK_DECLS(sigaltstack, , ,[
-#include "ansidecl.h"
-#include "system.h"
-#include <signal.h>
-])
-
-# g++ on Solaris 10+ defines _XOPEN_SOURCE=600, which hides the madvise()
-# prototype.
-AC_LANG_PUSH([C++])
-gcc_AC_CHECK_DECLS(madvise, , ,[
- #include "ansidecl.h"
- #include "system.h"
-])
-AC_LANG_POP([C++])
-
-# More time-related stuff.
-AC_CACHE_CHECK(for struct tms, ac_cv_struct_tms, [
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
-#include "ansidecl.h"
-#include "system.h"
-#ifdef HAVE_SYS_TIMES_H
-#include <sys/times.h>
-#endif
-]], [[struct tms tms;]])],[ac_cv_struct_tms=yes],[ac_cv_struct_tms=no])])
-if test $ac_cv_struct_tms = yes; then
- AC_DEFINE(HAVE_STRUCT_TMS, 1,
- [Define if <sys/times.h> defines struct tms.])
-fi
-
-# use gcc_cv_* here because this doesn't match the behavior of AC_CHECK_TYPE.
-# revisit after autoconf 2.50.
-AC_CACHE_CHECK(for clock_t, gcc_cv_type_clock_t, [
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
-#include "ansidecl.h"
-#include "system.h"
-]], [[clock_t x;]])],[gcc_cv_type_clock_t=yes],[gcc_cv_type_clock_t=no])])
-if test $gcc_cv_type_clock_t = yes; then
- AC_DEFINE(HAVE_CLOCK_T, 1,
- [Define if <time.h> defines clock_t.])
-fi
-
-# Check if F_SETLKW is supported by fcntl.
-AC_CACHE_CHECK(for F_SETLKW, ac_cv_f_setlkw, [
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
-#include <fcntl.h>]], [[
-struct flock fl;
-fl.l_whence = 0;
-fl.l_start = 0;
-fl.l_len = 0;
-fl.l_pid = 0;
-return fcntl (1, F_SETLKW, &fl);]])],
-[ac_cv_f_setlkw=yes],[ac_cv_f_setlkw=no])])
-if test $ac_cv_f_setlkw = yes; then
- AC_DEFINE(HOST_HAS_F_SETLKW, 1,
- [Define if F_SETLKW supported by fcntl.])
-fi
-
-# Restore CFLAGS, CXXFLAGS from before the gcc_AC_NEED_DECLARATIONS tests.
-CFLAGS="$saved_CFLAGS"
-CXXFLAGS="$saved_CXXFLAGS"
-
-# mkdir takes a single argument on some systems.
-gcc_AC_FUNC_MKDIR_TAKES_ONE_ARG
-
-# File extensions
-manext='.1'
-objext='.o'
-AC_SUBST(manext)
-AC_SUBST(objext)
-
-# With Setjmp/Longjmp based exception handling.
-AC_ARG_ENABLE(sjlj-exceptions,
-[AS_HELP_STRING([--enable-sjlj-exceptions],
- [arrange to use setjmp/longjmp exception handling])],
-[case $target in
- *-*-hpux10*)
- if test $enableval != yes; then
- AC_MSG_WARN([dwarf2 exceptions not supported, sjlj exceptions forced])
- enableval=yes
- fi
- ;;
-esac
-force_sjlj_exceptions=yes],
-[case $target in
- *-*-hpux10*)
- force_sjlj_exceptions=yes
- enableval=yes
- ;;
- *)
- force_sjlj_exceptions=no
- ;;
-esac])
-if test $force_sjlj_exceptions = yes; then
- sjlj=`if test $enableval = yes; then echo 1; else echo 0; fi`
- AC_DEFINE_UNQUOTED(CONFIG_SJLJ_EXCEPTIONS, $sjlj,
- [Define 0/1 to force the choice for exception handling model.])
-fi
-
-# --------------------------------------------------------
-# Build, host, and target specific configuration fragments
-# --------------------------------------------------------
-
-# Collect build-machine-specific information.
-. ${srcdir}/config.build
-
-# Collect host-machine-specific information.
-. ${srcdir}/config.host
-
-target_gtfiles=
-
-# Collect target-machine-specific information.
-. ${srcdir}/config.gcc
-
-extra_objs="${host_extra_objs} ${extra_objs}"
-extra_gcc_objs="${host_extra_gcc_objs} ${extra_gcc_objs}"
-
-# Default the target-machine variables that were not explicitly set.
-if test x"$tm_file" = x
-then tm_file=$cpu_type/$cpu_type.h; fi
-
-if test x"$extra_headers" = x
-then extra_headers=; fi
-
-if test x$md_file = x
-then md_file=$cpu_type/$cpu_type.md; fi
-
-if test x$out_file = x
-then out_file=$cpu_type/$cpu_type.c; fi
-
-if test x"$tmake_file" = x
-then tmake_file=$cpu_type/t-$cpu_type
-fi
-
-# Support --enable-initfini-array.
-if test x$enable_initfini_array != xno; then
- tm_file="${tm_file} initfini-array.h"
-fi
-
-if test x"$dwarf2" = xyes
-then tm_file="$tm_file tm-dwarf2.h"
-fi
-
-# Say what files are being used for the output code and MD file.
-echo "Using \`$srcdir/config/$out_file' for machine-specific logic."
-echo "Using \`$srcdir/config/$md_file' as machine description file."
-
-# If any of the xm_file variables contain nonexistent files, warn
-# about them and drop them.
-
-bx=
-for x in $build_xm_file; do
- if test -f $srcdir/config/$x
- then bx="$bx $x"
- else AC_MSG_WARN($srcdir/config/$x does not exist.)
- fi
-done
-build_xm_file="$bx"
-
-hx=
-for x in $host_xm_file; do
- if test -f $srcdir/config/$x
- then hx="$hx $x"
- else AC_MSG_WARN($srcdir/config/$x does not exist.)
- fi
-done
-host_xm_file="$hx"
-
-tx=
-for x in $xm_file; do
- if test -f $srcdir/config/$x
- then tx="$tx $x"
- else AC_MSG_WARN($srcdir/config/$x does not exist.)
- fi
-done
-xm_file="$tx"
-
-count=a
-for f in $tm_file; do
- count=${count}x
-done
-if test $count = ax; then
- echo "Using \`$srcdir/config/$tm_file' as target machine macro file."
-else
- echo "Using the following target machine macro files:"
- for f in $tm_file; do
- echo " $srcdir/config/$f"
- done
-fi
-
-if test x$need_64bit_hwint = xyes; then
- AC_DEFINE(NEED_64BIT_HOST_WIDE_INT, 1,
-[Define to 1 if HOST_WIDE_INT must be 64 bits wide (see hwint.h).])
-fi
-
-if test x$use_long_long_for_widest_fast_int = xyes; then
- AC_DEFINE(USE_LONG_LONG_FOR_WIDEST_FAST_INT, 1,
-[Define to 1 if the 'long long' (or '__int64') is wider than 'long' but still
-efficiently supported by the host hardware.])
-fi
-
-gnu_ld_bool=`if test x"$gnu_ld" = x"yes"; then echo 1; else echo 0; fi`
-AC_DEFINE_UNQUOTED(HAVE_GNU_LD, $gnu_ld_bool, [Define to 1 if using GNU ld.])
-
-gnu_as_bool=`if test x"$gas" = x"yes"; then echo 1; else echo 0; fi`
-AC_DEFINE_UNQUOTED(HAVE_GNU_AS, $gnu_as_bool, [Define to 1 if using GNU as.])
-
-count=a
-for f in $host_xm_file; do
- count=${count}x
-done
-if test $count = a; then
- :
-elif test $count = ax; then
- echo "Using \`$srcdir/config/$host_xm_file' as host machine macro file."
-else
- echo "Using the following host machine macro files:"
- for f in $host_xm_file; do
- echo " $srcdir/config/$f"
- done
-fi
-echo "Using ${out_host_hook_obj} for host machine hooks."
-
-if test "$host_xm_file" != "$build_xm_file"; then
- count=a
- for f in $build_xm_file; do
- count=${count}x
- done
- if test $count = a; then
- :
- elif test $count = ax; then
- echo "Using \`$srcdir/config/$build_xm_file' as build machine macro file."
- else
- echo "Using the following build machine macro files:"
- for f in $build_xm_file; do
- echo " $srcdir/config/$f"
- done
- fi
-fi
-
-if test -n "$configured_native_system_header_dir"; then
- native_system_header_dir=$configured_native_system_header_dir
-fi
-NATIVE_SYSTEM_HEADER_DIR="$native_system_header_dir"
-AC_SUBST(NATIVE_SYSTEM_HEADER_DIR)
-
-case ${host} in
- powerpc*-*-darwin*)
- AC_CACHE_CHECK([whether mcontext_t fields have underscores],
- gcc_cv_mcontext_underscores,
- AC_COMPILE_IFELSE([
-#include <sys/cdefs.h>
-#include <sys/signal.h>
-#include <ucontext.h>
-int main() { mcontext_t m; if (m->ss.srr0) return 0; return 0; }
-],
- gcc_cv_mcontext_underscores=no, gcc_cv_mcontext_underscores=yes))
- if test $gcc_cv_mcontext_underscores = yes; then
- AC_DEFINE(HAS_MCONTEXT_T_UNDERSCORES,,dnl
- [mcontext_t fields start with __])
- fi
- ;;
-esac
-
-# ---------
-# Threading
-# ---------
-
-# Check if a valid thread package
-case ${enable_threads} in
- "" | no)
- # No threads
- target_thread_file='single'
- ;;
- yes)
- # default
- target_thread_file='single'
- ;;
- aix | dce | lynx | mipssde | posix | rtems | \
- single | tpf | vxworks | win32)
- target_thread_file=${enable_threads}
- ;;
- *)
- echo "${enable_threads} is an unknown thread package" 1>&2
- exit 1
- ;;
-esac
-
-if test x${thread_file} = x; then
- # No thread file set by target-specific clauses in config.gcc,
- # so use file chosen by default logic above
- thread_file=${target_thread_file}
-fi
-
-# --------
-# UNSORTED
-# --------
-
-use_cxa_atexit=no
-if test x$enable___cxa_atexit = xyes || \
- test x$enable___cxa_atexit = x -a x$default_use_cxa_atexit = xyes; then
- if test x$host = x$target; then
- case $host in
- # mingw32 doesn't have __cxa_atexit but uses atexit registration
- # keyed to flag_use_cxa_atexit
- *-*-mingw32*)
- use_cxa_atexit=yes
- ;;
- powerpc-ibm-aix*)
- use_cxa_atexit=yes
- ;;
- *)
- AC_CHECK_FUNC(__cxa_atexit,[use_cxa_atexit=yes],
- [echo "__cxa_atexit can't be enabled on this target"])
- ;;
- esac
- else
- # We can't check for __cxa_atexit when building a cross, so assume
- # it is available
- use_cxa_atexit=yes
- fi
- if test x$use_cxa_atexit = xyes; then
- AC_DEFINE(DEFAULT_USE_CXA_ATEXIT, 2,
- [Define if you want to use __cxa_atexit, rather than atexit, to
- register C++ destructors for local statics and global objects.
- This is essential for fully standards-compliant handling of
- destructors, but requires __cxa_atexit in libc.])
- fi
-fi
-
-# Look for a file containing extra machine modes.
-if test -n "$extra_modes" && test -f $srcdir/config/$extra_modes; then
- extra_modes_file='$(srcdir)'/config/${extra_modes}
- AC_SUBST(extra_modes_file)
- AC_DEFINE_UNQUOTED(EXTRA_MODES_FILE, "config/$extra_modes",
- [Define to the name of a file containing a list of extra machine modes
- for this architecture.])
-fi
-
-# Convert extra_options into a form suitable for Makefile use.
-extra_opt_files=
-all_opt_files=
-for f in $extra_options; do
- extra_opt_files="$extra_opt_files \$(srcdir)/config/$f"
- all_opt_files="$all_opt_files $srcdir/config/$f"
-done
-AC_SUBST(extra_opt_files)
-
-# auto-host.h is the file containing items generated by autoconf and is
-# the first file included by config.h.
-# If host=build, it is correct to have bconfig include auto-host.h
-# as well. If host!=build, we are in error and need to do more
-# work to find out the build config parameters.
-if test x$host = x$build
-then
- build_auto=auto-host.h
-else
- # We create a subdir, then run autoconf in the subdir.
- # To prevent recursion we set host and build for the new
- # invocation of configure to the build for this invocation
- # of configure.
- tempdir=build.$$
- rm -rf $tempdir
- mkdir $tempdir
- cd $tempdir
- case ${srcdir} in
- /* | [A-Za-z]:[\\/]* ) realsrcdir=${srcdir};;
- *) realsrcdir=../${srcdir};;
- esac
- saved_CFLAGS="${CFLAGS}"
- CC="${CC_FOR_BUILD}" CFLAGS="${CFLAGS_FOR_BUILD}" \
- LDFLAGS="${LDFLAGS_FOR_BUILD}" \
- ${realsrcdir}/configure \
- --enable-languages=${enable_languages-all} \
- --target=$target_alias --host=$build_alias --build=$build_alias
- CFLAGS="${saved_CFLAGS}"
-
- # We just finished tests for the build machine, so rename
- # the file auto-build.h in the gcc directory.
- mv auto-host.h ../auto-build.h
- cd ..
- rm -rf $tempdir
- build_auto=auto-build.h
-fi
-AC_SUBST(build_subdir)
-
-tm_file="${tm_file} defaults.h"
-tm_p_file="${tm_p_file} tm-preds.h"
-host_xm_file="auto-host.h ansidecl.h ${host_xm_file}"
-build_xm_file="${build_auto} ansidecl.h ${build_xm_file}"
-# We don't want ansidecl.h in target files, write code there in ISO/GNU C.
-# put this back in temporarily.
-xm_file="auto-host.h ansidecl.h ${xm_file}"
-
-# --------
-# UNSORTED
-# --------
-
-changequote(,)dnl
-# Compile in configure arguments.
-if test -f configargs.h ; then
- # Being re-configured.
- gcc_config_arguments=`grep configuration_arguments configargs.h | sed -e 's/.*"\([^"]*\)".*/\1/'`
- gcc_config_arguments="$gcc_config_arguments : (reconfigured) $TOPLEVEL_CONFIGURE_ARGUMENTS"
-else
- gcc_config_arguments="$TOPLEVEL_CONFIGURE_ARGUMENTS"
-fi
-
-# Double all backslashes and backslash all quotes to turn
-# gcc_config_arguments into a C string.
-sed -e 's/\\/\\\\/g; s/"/\\"/g' <<EOF >conftest.out
-$gcc_config_arguments
-EOF
-gcc_config_arguments_str=`cat conftest.out`
-rm -f conftest.out
-
-cat > configargs.h <<EOF
-/* Generated automatically. */
-static const char configuration_arguments[] = "$gcc_config_arguments_str";
-static const char thread_model[] = "$thread_file";
-
-static const struct {
- const char *name, *value;
-} configure_default_options[] = $configure_default_options;
-EOF
-changequote([,])dnl
-
-changequote(,)dnl
-gcc_BASEVER=`cat $srcdir/BASE-VER`
-gcc_DEVPHASE=`cat $srcdir/DEV-PHASE`
-gcc_DATESTAMP=`cat $srcdir/DATESTAMP`
-if test -f $srcdir/REVISION ; then
- gcc_REVISION=`cat $srcdir/REVISION`
-else
- gcc_REVISION=""
-fi
-cat > plugin-version.h <<EOF
-#include "configargs.h"
-
-#define GCCPLUGIN_VERSION_MAJOR `echo $gcc_BASEVER | sed -e 's/^\([0-9]*\).*$/\1/'`
-#define GCCPLUGIN_VERSION_MINOR `echo $gcc_BASEVER | sed -e 's/^[0-9]*\.\([0-9]*\).*$/\1/'`
-#define GCCPLUGIN_VERSION_PATCHLEVEL `echo $gcc_BASEVER | sed -e 's/^[0-9]*\.[0-9]*\.\([0-9]*\)$/\1/'`
-#define GCCPLUGIN_VERSION (GCCPLUGIN_VERSION_MAJOR*1000 + GCCPLUGIN_VERSION_MINOR)
-
-static char basever[] = "$gcc_BASEVER";
-static char datestamp[] = "$gcc_DATESTAMP";
-static char devphase[] = "$gcc_DEVPHASE";
-static char revision[] = "$gcc_REVISION";
-
-/* FIXME plugins: We should make the version information more precise.
- One way to do is to add a checksum. */
-
-static struct plugin_gcc_version gcc_version = {basever, datestamp,
- devphase, revision,
- configuration_arguments};
-EOF
-changequote([,])dnl
-
-# Internationalization
-ZW_GNU_GETTEXT_SISTER_DIR
-
-# If LIBINTL contains LIBICONV, then clear LIBICONV so we don't get
-# -liconv on the link line twice.
-case "$LIBINTL" in *$LIBICONV*)
- LIBICONV= ;;
-esac
-
-AC_ARG_ENABLE(secureplt,
-[AS_HELP_STRING([--enable-secureplt],
- [enable -msecure-plt by default for PowerPC])],
-[], [])
-
-AC_ARG_ENABLE(leading-mingw64-underscores,
- AS_HELP_STRING([--enable-leading-mingw64-underscores],
- [enable leading underscores on 64 bit mingw targets]),
- [],[])
-AS_IF([ test x"$enable_leading_mingw64_underscores" = xyes ],
- [AC_DEFINE(USE_MINGW64_LEADING_UNDERSCORES, 1,
- [Define if we should use leading underscore on 64 bit mingw targets])])
-
-AC_ARG_ENABLE(cld,
-[AS_HELP_STRING([--enable-cld], [enable -mcld by default for 32bit x86])], [],
-[enable_cld=no])
-
-AC_ARG_ENABLE(frame-pointer,
-[AS_HELP_STRING([--enable-frame-pointer],
- [enable -fno-omit-frame-pointer by default for 32bit x86])], [],
-[
-case $target_os in
-linux* | darwin[[8912]]*)
- # Enable -fomit-frame-pointer by default for Linux and Darwin with
- # DWARF2.
- enable_frame_pointer=no
- ;;
-*)
- enable_frame_pointer=yes
- ;;
-esac
-])
-
-# Windows32 Registry support for specifying GCC installation paths.
-AC_ARG_ENABLE(win32-registry,
-[AS_HELP_STRING([--disable-win32-registry],
- [disable lookup of installation paths in the
- Registry on Windows hosts])
-AS_HELP_STRING([--enable-win32-registry], [enable registry lookup (default)])
-AS_HELP_STRING([--enable-win32-registry=KEY],
- [use KEY instead of GCC version as the last portion
- of the registry key])],,)
-
-case $host_os in
- win32 | pe | cygwin* | mingw32* | uwin*)
- if test "x$enable_win32_registry" != xno; then
- AC_SEARCH_LIBS(RegOpenKeyExA, advapi32,, [enable_win32_registry=no])
- fi
-
- if test "x$enable_win32_registry" != xno; then
- AC_DEFINE(ENABLE_WIN32_REGISTRY, 1,
- [Define to 1 if installation paths should be looked up in the Windows
- Registry. Ignored on non-Windows hosts.])
-
- if test "x$enable_win32_registry" != xyes \
- && test "x$enable_win32_registry" != x; then
- AC_DEFINE_UNQUOTED(WIN32_REGISTRY_KEY, "$enable_win32_registry",
- [Define to be the last component of the Windows registry key under which
- to look for installation paths. The full key used will be
- HKEY_LOCAL_MACHINE/SOFTWARE/Free Software Foundation/{WIN32_REGISTRY_KEY}.
- The default is the GCC version number.])
- fi
- fi
- ;;
-esac
-
-# Get an absolute path to the GCC top-level source directory
-holddir=`${PWDCMD-pwd}`
-cd $srcdir
-topdir=`${PWDCMD-pwd}`
-cd $holddir
-
-# Conditionalize the makefile for this host machine.
-xmake_file=
-for f in ${host_xmake_file}
-do
- if test -f ${srcdir}/config/$f
- then
- xmake_file="${xmake_file} \$(srcdir)/config/$f"
- fi
-done
-
-# Conditionalize the makefile for this target machine.
-tmake_file_=
-for f in ${tmake_file}
-do
- if test -f ${srcdir}/config/$f
- then
- tmake_file_="${tmake_file_} \$(srcdir)/config/$f"
- fi
-done
-tmake_file="${tmake_file_}"
-
-out_object_file=`basename $out_file .c`.o
-common_out_object_file=`basename $common_out_file .c`.o
-
-tm_file_list="options.h"
-tm_include_list="options.h insn-constants.h"
-for f in $tm_file; do
- case $f in
- ./* )
- f=`echo $f | sed 's/^..//'`
- tm_file_list="${tm_file_list} $f"
- tm_include_list="${tm_include_list} $f"
- ;;
- defaults.h )
- tm_file_list="${tm_file_list} \$(srcdir)/$f"
- tm_include_list="${tm_include_list} $f"
- ;;
- * )
- tm_file_list="${tm_file_list} \$(srcdir)/config/$f"
- tm_include_list="${tm_include_list} config/$f"
- ;;
- esac
-done
-
-tm_p_file_list=
-tm_p_include_list=
-for f in $tm_p_file; do
- case $f in
- tm-preds.h )
- tm_p_file_list="${tm_p_file_list} $f"
- tm_p_include_list="${tm_p_include_list} $f"
- ;;
- * )
- tm_p_file_list="${tm_p_file_list} \$(srcdir)/config/$f"
- tm_p_include_list="${tm_p_include_list} config/$f"
- esac
-done
-
-xm_file_list=
-xm_include_list=
-for f in $xm_file; do
- case $f in
- ansidecl.h )
- xm_file_list="${xm_file_list} \$(srcdir)/../include/$f"
- xm_include_list="${xm_include_list} $f"
- ;;
- auto-host.h )
- xm_file_list="${xm_file_list} $f"
- xm_include_list="${xm_include_list} $f"
- ;;
- * )
- xm_file_list="${xm_file_list} \$(srcdir)/config/$f"
- xm_include_list="${xm_include_list} config/$f"
- ;;
- esac
-done
-
-host_xm_file_list=
-host_xm_include_list=
-for f in $host_xm_file; do
- case $f in
- ansidecl.h )
- host_xm_file_list="${host_xm_file_list} \$(srcdir)/../include/$f"
- host_xm_include_list="${host_xm_include_list} $f"
- ;;
- auto-host.h )
- host_xm_file_list="${host_xm_file_list} $f"
- host_xm_include_list="${host_xm_include_list} $f"
- ;;
- * )
- host_xm_file_list="${host_xm_file_list} \$(srcdir)/config/$f"
- host_xm_include_list="${host_xm_include_list} config/$f"
- ;;
- esac
-done
-
-build_xm_file_list=
-for f in $build_xm_file; do
- case $f in
- ansidecl.h )
- build_xm_file_list="${build_xm_file_list} \$(srcdir)/../include/$f"
- build_xm_include_list="${build_xm_include_list} $f"
- ;;
- auto-build.h | auto-host.h )
- build_xm_file_list="${build_xm_file_list} $f"
- build_xm_include_list="${build_xm_include_list} $f"
- ;;
- * )
- build_xm_file_list="${build_xm_file_list} \$(srcdir)/config/$f"
- build_xm_include_list="${build_xm_include_list} config/$f"
- ;;
- esac
-done
-
-# Define macro CROSS_DIRECTORY_STRUCTURE in compilation if this is a
-# cross-compiler which does not use the native headers and libraries.
-# Also use all.cross instead of all.internal and adjust SYSTEM_HEADER_DIR.
-CROSS= AC_SUBST(CROSS)
-ALL=all.internal AC_SUBST(ALL)
-SYSTEM_HEADER_DIR='$(NATIVE_SYSTEM_HEADER_DIR)' AC_SUBST(SYSTEM_HEADER_DIR)
-
-if test "x$with_build_sysroot" != x; then
- build_system_header_dir=$with_build_sysroot'$${sysroot_headers_suffix}$(NATIVE_SYSTEM_HEADER_DIR)'
-else
- # This value is used, even on a native system, because
- # CROSS_SYSTEM_HEADER_DIR is just
- # $(TARGET_SYSTEM_ROOT)$(NATIVE_SYSTEM_HEADER_DIR).
- build_system_header_dir='$(CROSS_SYSTEM_HEADER_DIR)'
-fi
-
-if test x$host != x$target
-then
- CROSS="-DCROSS_DIRECTORY_STRUCTURE"
- ALL=all.cross
- SYSTEM_HEADER_DIR=$build_system_header_dir
- case "$host","$target" in
- # Darwin crosses can use the host system's libraries and headers,
- # because of the fat library support. Of course, it must be the
- # same version of Darwin on both sides. Allow the user to
- # just say --target=foo-darwin without a version number to mean
- # "the version on this system".
- *-*-darwin*,*-*-darwin*)
- hostos=`echo $host | sed 's/.*-darwin/darwin/'`
- targetos=`echo $target | sed 's/.*-darwin/darwin/'`
- if test $hostos = $targetos -o $targetos = darwin ; then
- CROSS=
- SYSTEM_HEADER_DIR='$(NATIVE_SYSTEM_HEADER_DIR)'
- with_headers=yes
- fi
- ;;
-
- i?86-*-*,x86_64-*-* \
- | powerpc*-*-*,powerpc64*-*-*)
- CROSS="$CROSS -DNATIVE_CROSS" ;;
- esac
-
- case $target in
- *-*-mingw*)
- if test "x$with_headers" = x; then
- with_headers=yes
- fi
- ;;
- *)
- ;;
- esac
-elif test "x$TARGET_SYSTEM_ROOT" != x; then
- SYSTEM_HEADER_DIR=$build_system_header_dir
-fi
-
-# If this is a cross-compiler that does not
-# have its own set of headers then define
-# inhibit_libc
-
-# If this is using newlib, without having the headers available now,
-# then define inhibit_libc in LIBGCC2_CFLAGS.
-# This prevents libgcc2 from containing any code which requires libc
-# support.
-: ${inhibit_libc=false}
-if { { test x$host != x$target && test "x$with_sysroot" = x ; } ||
- test x$with_newlib = xyes ; } &&
- { test "x$with_headers" = x || test "x$with_headers" = xno ; } ; then
- inhibit_libc=true
-fi
-AC_SUBST(inhibit_libc)
-
-# When building gcc with a cross-compiler, we need to adjust things so
-# that the generator programs are still built with the native compiler.
-# Also, we cannot run fixincludes.
-
-# These are the normal (build=host) settings:
-CC_FOR_BUILD='$(CC)' AC_SUBST(CC_FOR_BUILD)
-CXX_FOR_BUILD='$(CXX)' AC_SUBST(CXX_FOR_BUILD)
-BUILD_CFLAGS='$(ALL_CFLAGS)' AC_SUBST(BUILD_CFLAGS)
-BUILD_CXXFLAGS='$(ALL_CXXFLAGS)' AC_SUBST(BUILD_CXXFLAGS)
-BUILD_LDFLAGS='$(LDFLAGS)' AC_SUBST(BUILD_LDFLAGS)
-STMP_FIXINC=stmp-fixinc AC_SUBST(STMP_FIXINC)
-
-# And these apply if build != host, or we are generating coverage data
-if test x$build != x$host || test "x$coverage_flags" != x
-then
- BUILD_CFLAGS='$(INTERNAL_CFLAGS) $(T_CFLAGS) $(CFLAGS_FOR_BUILD)'
- BUILD_LDFLAGS='$(LDFLAGS_FOR_BUILD)'
-fi
-
-# Expand extra_headers to include complete path.
-# This substitutes for lots of t-* files.
-extra_headers_list=
-# Prepend $(srcdir)/config/${cpu_type}/ to every entry in extra_headers.
-for file in ${extra_headers} ; do
- extra_headers_list="${extra_headers_list} \$(srcdir)/config/${cpu_type}/${file}"
-done
-
-# If use_gcc_tgmath is set, append ginclude/tgmath.h.
-if test x"$use_gcc_tgmath" = xyes
-then extra_headers_list="${extra_headers_list} \$(srcdir)/ginclude/tgmath.h"
-fi
-
-# Define collect2 in Makefile.
-case $host_can_use_collect2 in
- no) collect2= ;;
- *) collect2='collect2$(exeext)' ;;
-esac
-AC_SUBST([collect2])
-
-# Add a definition of USE_COLLECT2 if system wants one.
-case $use_collect2 in
- no) use_collect2= ;;
- "") ;;
- *)
- host_xm_defines="${host_xm_defines} USE_COLLECT2"
- xm_defines="${xm_defines} USE_COLLECT2"
- case $host_can_use_collect2 in
- no)
- AC_MSG_ERROR([collect2 is required but cannot be built on this system])
- ;;
- esac
- ;;
-esac
-
-AC_DEFINE_UNQUOTED(LTOPLUGINSONAME,"${host_lto_plugin_soname}",
-[Define to the name of the LTO plugin DSO that must be
- passed to the linker's -plugin=LIB option.])
-
-# ---------------------------
-# Assembler & linker features
-# ---------------------------
-
-# During stage 2, ld is actually gcc/collect-ld, which is a small script to
-# discern between when to use prev-ld/ld-new and when to use ld/ld-new.
-# However when ld-new is first executed from the build tree, libtool will
-# relink it as .libs/lt-ld-new, so that it can give it an RPATH that refers
-# to the build tree. While doing this we need to use the previous-stage
-# linker, or we have an infinite loop. The presence of a shell script as
-# ld/ld-new, and the fact that the script *uses ld itself*, is what confuses
-# the gcc/collect-ld script. So we need to know how libtool works, or
-# exec-tool will fail.
-
-m4_defun([_LT_CONFIG_COMMANDS], [])
-AC_PROG_LIBTOOL
-AC_SUBST(objdir)
-AC_SUBST(enable_fast_install)
-
-# Identify the assembler which will work hand-in-glove with the newly
-# built GCC, so that we can examine its features. This is the assembler
-# which will be driven by the driver program.
-#
-# If build != host, and we aren't building gas in-tree, we identify a
-# build->target assembler and hope that it will have the same features
-# as the host->target assembler we'll be using.
-gcc_cv_gas_major_version=
-gcc_cv_gas_minor_version=
-gcc_cv_as_gas_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/gas
-
-m4_pattern_allow([AS_FOR_TARGET])dnl
-AS_VAR_SET_IF(gcc_cv_as,, [
-if test -x "$DEFAULT_ASSEMBLER"; then
- gcc_cv_as="$DEFAULT_ASSEMBLER"
-elif test -f $gcc_cv_as_gas_srcdir/configure.in \
- && test -f ../gas/Makefile \
- && test x$build = x$host; then
- gcc_cv_as=../gas/as-new$build_exeext
-elif test -x as$build_exeext; then
- # Build using assembler in the current directory.
- gcc_cv_as=./as$build_exeext
-elif ( set dummy $AS_FOR_TARGET; test -x $[2] ); then
- gcc_cv_as="$AS_FOR_TARGET"
-else
- AC_PATH_PROG(gcc_cv_as, $AS_FOR_TARGET)
-fi])
-
-ORIGINAL_AS_FOR_TARGET=$gcc_cv_as
-AC_SUBST(ORIGINAL_AS_FOR_TARGET)
-case "$ORIGINAL_AS_FOR_TARGET" in
- ./as | ./as$build_exeext) ;;
- *) AC_CONFIG_FILES(as:exec-tool.in, [chmod +x as]) ;;
-esac
-
-AC_MSG_CHECKING(what assembler to use)
-if test "$gcc_cv_as" = ../gas/as-new$build_exeext; then
- # Single tree build which includes gas. We want to prefer it
- # over whatever linker top-level may have detected, since
- # we'll use what we're building after installation anyway.
- AC_MSG_RESULT(newly built gas)
- in_tree_gas=yes
- _gcc_COMPUTE_GAS_VERSION
- in_tree_gas_is_elf=no
- if grep 'obj_format = elf' ../gas/Makefile > /dev/null \
- || (grep 'obj_format = multi' ../gas/Makefile \
- && grep 'extra_objects =.* obj-elf' ../gas/Makefile) > /dev/null
- then
- in_tree_gas_is_elf=yes
- fi
-else
- AC_MSG_RESULT($gcc_cv_as)
- in_tree_gas=no
-fi
-
-# Identify the linker which will work hand-in-glove with the newly
-# built GCC, so that we can examine its features. This is the linker
-# which will be driven by the driver program.
-#
-# If build != host, and we aren't building gas in-tree, we identify a
-# build->target linker and hope that it will have the same features
-# as the host->target linker we'll be using.
-gcc_cv_gld_major_version=
-gcc_cv_gld_minor_version=
-gcc_cv_ld_gld_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/ld
-gcc_cv_ld_bfd_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/bfd
-
-AS_VAR_SET_IF(gcc_cv_ld,, [
-if test -x "$DEFAULT_LINKER"; then
- gcc_cv_ld="$DEFAULT_LINKER"
-elif test -f $gcc_cv_ld_gld_srcdir/configure.in \
- && test -f ../ld/Makefile \
- && test x$build = x$host; then
- gcc_cv_ld=../ld/ld-new$build_exeext
-elif test -x collect-ld$build_exeext; then
- # Build using linker in the current directory.
- gcc_cv_ld=./collect-ld$build_exeext
-elif ( set dummy $LD_FOR_TARGET; test -x $[2] ); then
- gcc_cv_ld="$LD_FOR_TARGET"
-else
- AC_PATH_PROG(gcc_cv_ld, $LD_FOR_TARGET)
-fi])
-
-ORIGINAL_PLUGIN_LD_FOR_TARGET=$gcc_cv_ld
-PLUGIN_LD_SUFFIX=`basename $gcc_cv_ld | sed -e "s,$target_alias-,,"`
-# if the PLUGIN_LD is set ld-new, just have it as ld
-# as that is the installed named.
-if test x$PLUGIN_LD_SUFFIX = xld-new \
- || test x$PLUGIN_LD_SUFFIX = xcollect-ld ; then
- PLUGIN_LD_SUFFIX=ld
-fi
-AC_ARG_WITH(plugin-ld,
-[AS_HELP_STRING([[--with-plugin-ld=[ARG]]], [specify the plugin linker])],
-[if test x"$withval" != x; then
- ORIGINAL_PLUGIN_LD_FOR_TARGET="$withval"
- PLUGIN_LD_SUFFIX=`echo $withval | sed -e "s,$target_alias-,,"`
- fi])
-AC_SUBST(ORIGINAL_PLUGIN_LD_FOR_TARGET)
-AC_DEFINE_UNQUOTED(PLUGIN_LD_SUFFIX, "$PLUGIN_LD_SUFFIX", [Specify plugin linker])
-
-# Check to see if we are using gold instead of ld
-AC_MSG_CHECKING(whether we are using gold)
-ld_is_gold=no
-if test x$gcc_cv_ld != x; then
- if $gcc_cv_ld --version 2>/dev/null | sed 1q \
- | grep "GNU gold" > /dev/null; then
- ld_is_gold=yes
- fi
-fi
-AC_MSG_RESULT($ld_is_gold)
-
-ORIGINAL_LD_FOR_TARGET=$gcc_cv_ld
-AC_SUBST(ORIGINAL_LD_FOR_TARGET)
-case "$ORIGINAL_LD_FOR_TARGET" in
- ./collect-ld | ./collect-ld$build_exeext) ;;
- *) AC_CONFIG_FILES(collect-ld:exec-tool.in, [chmod +x collect-ld]) ;;
-esac
-
-AC_MSG_CHECKING(what linker to use)
-if test "$gcc_cv_ld" = ../ld/ld-new$build_exeext \
- || test "$gcc_cv_ld" = ../gold/ld-new$build_exeext; then
- # Single tree build which includes ld. We want to prefer it
- # over whatever linker top-level may have detected, since
- # we'll use what we're building after installation anyway.
- AC_MSG_RESULT(newly built ld)
- in_tree_ld=yes
- in_tree_ld_is_elf=no
- if (grep 'EMUL = .*elf' ../ld/Makefile \
- || grep 'EMUL = .*linux' ../ld/Makefile \
- || grep 'EMUL = .*lynx' ../ld/Makefile) > /dev/null; then
- in_tree_ld_is_elf=yes
- elif test "$ld_is_gold" = yes; then
- in_tree_ld_is_elf=yes
- fi
- for f in $gcc_cv_ld_bfd_srcdir/configure $gcc_cv_ld_gld_srcdir/configure $gcc_cv_ld_gld_srcdir/configure.in $gcc_cv_ld_gld_srcdir/Makefile.in
- do
-changequote(,)dnl
- gcc_cv_gld_version=`sed -n -e 's/^[ ]*VERSION=[^0-9A-Za-z_]*\([0-9]*\.[0-9]*.*\)/VERSION=\1/p' < $f`
- if test x$gcc_cv_gld_version != x; then
- break
- fi
- done
- case $gcc_cv_gld_version in
- VERSION=[0-9]*) ;;
-changequote([,])dnl
- *) AC_MSG_ERROR([[cannot find version of in-tree linker]]) ;;
-changequote(,)dnl
- esac
- gcc_cv_gld_major_version=`expr "$gcc_cv_gld_version" : "VERSION=\([0-9]*\)"`
- gcc_cv_gld_minor_version=`expr "$gcc_cv_gld_version" : "VERSION=[0-9]*\.\([0-9]*\)"`
-changequote([,])dnl
-else
- AC_MSG_RESULT($gcc_cv_ld)
- in_tree_ld=no
-fi
-
-# Figure out what nm we will be using.
-gcc_cv_binutils_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/binutils
-AS_VAR_SET_IF(gcc_cv_nm,, [
-if test -f $gcc_cv_binutils_srcdir/configure.in \
- && test -f ../binutils/Makefile \
- && test x$build = x$host; then
- gcc_cv_nm=../binutils/nm-new$build_exeext
-elif test -x nm$build_exeext; then
- gcc_cv_nm=./nm$build_exeext
-elif ( set dummy $NM_FOR_TARGET; test -x $[2] ); then
- gcc_cv_nm="$NM_FOR_TARGET"
-else
- AC_PATH_PROG(gcc_cv_nm, $NM_FOR_TARGET)
-fi])
-
-AC_MSG_CHECKING(what nm to use)
-if test "$gcc_cv_nm" = ../binutils/nm-new$build_exeext; then
- # Single tree build which includes binutils.
- AC_MSG_RESULT(newly built nm)
- in_tree_nm=yes
-else
- AC_MSG_RESULT($gcc_cv_nm)
- in_tree_nm=no
-fi
-
-ORIGINAL_NM_FOR_TARGET=$gcc_cv_nm
-AC_SUBST(ORIGINAL_NM_FOR_TARGET)
-case "$ORIGINAL_NM_FOR_TARGET" in
- ./nm | ./nm$build_exeext) ;;
- *) AC_CONFIG_FILES(nm:exec-tool.in, [chmod +x nm]) ;;
-esac
-
-
-# Figure out what objdump we will be using.
-AS_VAR_SET_IF(gcc_cv_objdump,, [
-if test -f $gcc_cv_binutils_srcdir/configure.in \
- && test -f ../binutils/Makefile \
- && test x$build = x$host; then
- # Single tree build which includes binutils.
- gcc_cv_objdump=../binutils/objdump$build_exeext
-elif test -x objdump$build_exeext; then
- gcc_cv_objdump=./objdump$build_exeext
-elif ( set dummy $OBJDUMP_FOR_TARGET; test -x $[2] ); then
- gcc_cv_objdump="$OBJDUMP_FOR_TARGET"
-else
- AC_PATH_PROG(gcc_cv_objdump, $OBJDUMP_FOR_TARGET)
-fi])
-
-AC_MSG_CHECKING(what objdump to use)
-if test "$gcc_cv_objdump" = ../binutils/objdump$build_exeext; then
- # Single tree build which includes binutils.
- AC_MSG_RESULT(newly built objdump)
-elif test x$gcc_cv_objdump = x; then
- AC_MSG_RESULT(not found)
-else
- AC_MSG_RESULT($gcc_cv_objdump)
-fi
-
-# Figure out what readelf we will be using.
-AS_VAR_SET_IF(gcc_cv_readelf,, [
-if test -f $gcc_cv_binutils_srcdir/configure.in \
- && test -f ../binutils/Makefile \
- && test x$build = x$host; then
- # Single tree build which includes binutils.
- gcc_cv_readelf=../binutils/readelf$build_exeext
-elif test -x readelf$build_exeext; then
- gcc_cv_readelf=./readelf$build_exeext
-elif ( set dummy $READELF_FOR_TARGET; test -x $[2] ); then
- gcc_cv_readelf="$READELF_FOR_TARGET"
-else
- AC_PATH_PROG(gcc_cv_readelf, $READELF_FOR_TARGET)
-fi])
-
-AC_MSG_CHECKING(what readelf to use)
-if test "$gcc_cv_readelf" = ../binutils/readelf$build_exeext; then
- # Single tree build which includes binutils.
- AC_MSG_RESULT(newly built readelf)
-elif test x$gcc_cv_readelf = x; then
- AC_MSG_RESULT(not found)
-else
- AC_MSG_RESULT($gcc_cv_readelf)
-fi
-
-# Figure out what assembler alignment features are present.
-gcc_GAS_CHECK_FEATURE([.balign and .p2align], gcc_cv_as_balign_and_p2align,
- [2,6,0],,
-[.balign 4
-.p2align 2],,
-[AC_DEFINE(HAVE_GAS_BALIGN_AND_P2ALIGN, 1,
- [Define if your assembler supports .balign and .p2align.])])
-
-gcc_GAS_CHECK_FEATURE([.p2align with maximum skip], gcc_cv_as_max_skip_p2align,
- [2,8,0],,
- [.p2align 4,,7],,
-[AC_DEFINE(HAVE_GAS_MAX_SKIP_P2ALIGN, 1,
- [Define if your assembler supports specifying the maximum number
- of bytes to skip when using the GAS .p2align command.])])
-
-gcc_GAS_CHECK_FEATURE([.literal16], gcc_cv_as_literal16,
- [2,8,0],,
- [.literal16],,
-[AC_DEFINE(HAVE_GAS_LITERAL16, 1,
- [Define if your assembler supports .literal16.])])
-
-gcc_GAS_CHECK_FEATURE([working .subsection -1], gcc_cv_as_subsection_m1,
- [elf,2,9,0],,
- [conftest_label1: .word 0
-.subsection -1
-conftest_label2: .word 0
-.previous],
- [if test x$gcc_cv_nm != x; then
- $gcc_cv_nm conftest.o | grep conftest_label1 > conftest.nm1
- $gcc_cv_nm conftest.o | grep conftest_label2 | sed -e 's/label2/label1/' > conftest.nm2
- if cmp conftest.nm1 conftest.nm2 > /dev/null 2>&1
- then :
- else gcc_cv_as_subsection_m1=yes
- fi
- rm -f conftest.nm1 conftest.nm2
- fi],
- [AC_DEFINE(HAVE_GAS_SUBSECTION_ORDERING, 1,
- [Define if your assembler supports .subsection and .subsection -1 starts
- emitting at the beginning of your section.])])
-
-gcc_GAS_CHECK_FEATURE([.weak], gcc_cv_as_weak,
- [2,2,0],,
- [ .weak foobar],,
-[AC_DEFINE(HAVE_GAS_WEAK, 1, [Define if your assembler supports .weak.])])
-
-gcc_GAS_CHECK_FEATURE([.weakref], gcc_cv_as_weakref,
- [2,17,0],,
- [ .weakref foobar, barfnot],,
-[AC_DEFINE(HAVE_GAS_WEAKREF, 1, [Define if your assembler supports .weakref.])])
-
-gcc_GAS_CHECK_FEATURE([.nsubspa comdat], gcc_cv_as_nsubspa_comdat,
- [2,15,91],,
- [ .SPACE $TEXT$
- .NSUBSPA $CODE$,COMDAT],,
-[AC_DEFINE(HAVE_GAS_NSUBSPA_COMDAT, 1, [Define if your assembler supports .nsubspa comdat option.])])
-
-# .hidden needs to be supported in both the assembler and the linker,
-# because GNU LD versions before 2.12.1 have buggy support for STV_HIDDEN.
-# This is irritatingly difficult to feature test for; we have to check the
-# date string after the version number. If we've got an in-tree
-# ld, we don't know its patchlevel version, so we set the baseline at 2.13
-# to be safe.
-# The gcc_GAS_CHECK_FEATURE call just sets a cache variable.
-gcc_GAS_CHECK_FEATURE([.hidden], gcc_cv_as_hidden,
- [elf,2,13,0],,
-[ .hidden foobar
-foobar:],[
-# Solaris 9/x86 as incorrectly emits an alias for a hidden symbol with
-# STV_HIDDEN, so disable .hidden support if so.
-case "${target}" in
- i?86-*-solaris2* | x86_64-*-solaris2.1[[0-9]]*)
- if test x$gcc_cv_as != x && test x$gcc_cv_objdump != x; then
- cat > conftest.s <<EOF
-.globl hidden
- .hidden hidden
-hidden:
-.globl default
- .set default,hidden
-EOF
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1 \
- && $gcc_cv_objdump -t conftest.o 2>/dev/null | \
- grep '\.hidden default' > /dev/null; then
- gcc_cv_as_hidden=no
- else
- gcc_cv_as_hidden=yes
- fi
- else
- # Assume bug is present if objdump is missing.
- gcc_cv_as_hidden=no
- fi
- ;;
- *)
- gcc_cv_as_hidden=yes
- ;;
-esac])
-case "${target}" in
- *-*-darwin*)
- # Darwin as has some visibility support, though with a different syntax.
- gcc_cv_as_hidden=yes
- ;;
-esac
-
-# gnu_indirect_function type is an extension proposed at
-# http://groups.google/com/group/generic-abi/files. It allows dynamic runtime
-# selection of function implementation
-AC_ARG_ENABLE(gnu-indirect-function,
- [AS_HELP_STRING([--enable-gnu-indirect-function],
- [enable the use of the @gnu_indirect_function to glibc systems])],
- [case $enable_gnu_indirect_function in
- yes | no) ;;
- *) AC_MSG_ERROR(['$enable_gnu_indirect_function' is an invalid value for --enable-gnu-indirect-function.
-Valid choices are 'yes' and 'no'.]) ;;
- esac],
- [enable_gnu_indirect_function="$default_gnu_indirect_function"])
-if test x$enable_gnu_indirect_function = xyes; then
- AC_DEFINE(HAVE_GNU_INDIRECT_FUNCTION, 1,
- [Define if your system supports gnu indirect functions.])
-fi
-
-changequote(,)dnl
-if test $in_tree_ld != yes ; then
- ld_ver=`$gcc_cv_ld --version 2>/dev/null | sed 1q`
- if echo "$ld_ver" | grep GNU > /dev/null; then
- if test x"$ld_is_gold" = xyes; then
- # GNU gold --version looks like this:
- #
- # GNU gold (GNU Binutils 2.21.51.20110225) 1.11
- #
- # We extract the binutils version which is more familiar and specific
- # than the gold version.
- ld_vers=`echo $ld_ver | sed -n \
- -e 's,^[^)]*[ ]\([0-9][0-9]*\.[0-9][0-9]*[^)]*\)) .*$,\1,p'`
- else
- # GNU ld --version looks like this:
- #
- # GNU ld (GNU Binutils) 2.21.51.20110225
- ld_vers=`echo $ld_ver | sed -n \
- -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*.*\)$,\1,p'`
- fi
- ld_date=`echo $ld_ver | sed -n 's,^.*\([2-9][0-9][0-9][0-9]\)[-]*\([01][0-9]\)[-]*\([0-3][0-9]\).*$,\1\2\3,p'`
- ld_vers_major=`expr "$ld_vers" : '\([0-9]*\)'`
- ld_vers_minor=`expr "$ld_vers" : '[0-9]*\.\([0-9]*\)'`
- ld_vers_patch=`expr "$ld_vers" : '[0-9]*\.[0-9]*\.\([0-9]*\)'`
- else
- case "${target}" in
- *-*-solaris2*)
- # See acinclude.m4 (gcc_SUN_LD_VERSION) for the version number
- # format.
- #
- # Don't reuse gcc_gv_sun_ld_vers_* in case a linker other than
- # /usr/ccs/bin/ld has been configured.
- ld_ver=`$gcc_cv_ld -V 2>&1`
- if echo "$ld_ver" | grep 'Solaris Link Editors' > /dev/null; then
- ld_vers=`echo $ld_ver | sed -n \
- -e 's,^.*: 5\.[0-9][0-9]*-\([0-9]\.[0-9][0-9]*\).*$,\1,p'`
- ld_vers_major=`expr "$ld_vers" : '\([0-9]*\)'`
- ld_vers_minor=`expr "$ld_vers" : '[0-9]*\.\([0-9]*\)'`
- fi
- ;;
- esac
- fi
-fi
-changequote([,])dnl
-
-AC_CACHE_CHECK(linker for .hidden support, gcc_cv_ld_hidden,
-[[if test $in_tree_ld = yes ; then
- gcc_cv_ld_hidden=no
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 13 -o "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes; then
- gcc_cv_ld_hidden=yes
- fi
-else
- gcc_cv_ld_hidden=yes
- if test x"$ld_is_gold" = xyes; then
- :
- elif echo "$ld_ver" | grep GNU > /dev/null; then
- case "${target}" in
- mmix-knuth-mmixware)
- # The linker emits by default mmo, not ELF, so "no" is appropriate.
- gcc_cv_ld_hidden=no
- ;;
- esac
- if test 0"$ld_date" -lt 20020404; then
- if test -n "$ld_date"; then
- # If there was date string, but was earlier than 2002-04-04, fail
- gcc_cv_ld_hidden=no
- elif test -z "$ld_vers"; then
- # If there was no date string nor ld version number, something is wrong
- gcc_cv_ld_hidden=no
- else
- test -z "$ld_vers_patch" && ld_vers_patch=0
- if test "$ld_vers_major" -lt 2; then
- gcc_cv_ld_hidden=no
- elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -lt 12; then
- gcc_cv_ld_hidden="no"
- elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -eq 12 -a "$ld_vers_patch" -eq 0; then
- gcc_cv_ld_hidden=no
- fi
- fi
- fi
- else
- case "${target}" in
- *-*-darwin*)
- # Darwin ld has some visibility support.
- gcc_cv_ld_hidden=yes
- ;;
- hppa64*-*-hpux* | ia64*-*-hpux*)
- gcc_cv_ld_hidden=yes
- ;;
- *-*-solaris2.9* | *-*-solaris2.1[0-9]*)
- # Support for .hidden in Sun ld appeared in Solaris 9 FCS, but
- # .symbolic was only added in Solaris 9 12/02.
- gcc_cv_ld_hidden=yes
- ;;
- *)
- gcc_cv_ld_hidden=no
- ;;
- esac
- fi
-fi]])
-libgcc_visibility=no
-AC_SUBST(libgcc_visibility)
-GCC_TARGET_TEMPLATE([HAVE_GAS_HIDDEN])
-if test $gcc_cv_as_hidden = yes && test $gcc_cv_ld_hidden = yes; then
- libgcc_visibility=yes
- AC_DEFINE(HAVE_GAS_HIDDEN, 1,
- [Define if your assembler and linker support .hidden.])
-fi
-
-AC_MSG_CHECKING(linker read-only and read-write section mixing)
-gcc_cv_ld_ro_rw_mix=unknown
-if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 10 -o "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes; then
- gcc_cv_ld_ro_rw_mix=read-write
- fi
-elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x -a x$gcc_cv_objdump != x ; then
- echo '.section myfoosect, "a"' > conftest1.s
- echo '.section myfoosect, "aw"' > conftest2.s
- echo '.byte 1' >> conftest2.s
- echo '.section myfoosect, "a"' > conftest3.s
- echo '.byte 0' >> conftest3.s
- if $gcc_cv_as -o conftest1.o conftest1.s > /dev/null 2>&1 \
- && $gcc_cv_as -o conftest2.o conftest2.s > /dev/null 2>&1 \
- && $gcc_cv_as -o conftest3.o conftest3.s > /dev/null 2>&1 \
- && $gcc_cv_ld -shared -o conftest1.so conftest1.o \
- conftest2.o conftest3.o > /dev/null 2>&1; then
- gcc_cv_ld_ro_rw_mix=`$gcc_cv_objdump -h conftest1.so \
- | sed -e '/myfoosect/!d' -e N`
- if echo "$gcc_cv_ld_ro_rw_mix" | grep CONTENTS > /dev/null; then
- if echo "$gcc_cv_ld_ro_rw_mix" | grep READONLY > /dev/null; then
- gcc_cv_ld_ro_rw_mix=read-only
- else
- gcc_cv_ld_ro_rw_mix=read-write
- fi
- fi
- fi
-changequote(,)dnl
- rm -f conftest.* conftest[123].*
-changequote([,])dnl
-fi
-if test x$gcc_cv_ld_ro_rw_mix = xread-write; then
- AC_DEFINE(HAVE_LD_RO_RW_SECTION_MIXING, 1,
- [Define if your linker links a mix of read-only
- and read-write sections into a read-write section.])
-fi
-AC_MSG_RESULT($gcc_cv_ld_ro_rw_mix)
-
-gcc_AC_INITFINI_ARRAY
-
-# Check if we have .[us]leb128, and support symbol arithmetic with it.
-gcc_GAS_CHECK_FEATURE([.sleb128 and .uleb128], gcc_cv_as_leb128,
- [elf,2,11,0],,
-[ .data
- .uleb128 L2 - L1
-L1:
- .uleb128 1280
- .sleb128 -1010
-L2:],
-[[# GAS versions before 2.11 do not support uleb128,
- # despite appearing to.
- # ??? There exists an elf-specific test that will crash
- # the assembler. Perhaps it's better to figure out whether
- # arbitrary sections are supported and try the test.
- as_ver=`$gcc_cv_as --version 2>/dev/null | sed 1q`
- if echo "$as_ver" | grep GNU > /dev/null; then
- 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]*\)'`
- if test $as_major -eq 2 && test $as_minor -lt 11
- then :
- else gcc_cv_as_leb128=yes
- fi
- fi]],
- [AC_DEFINE(HAVE_AS_LEB128, 1,
- [Define if your assembler supports .sleb128 and .uleb128.])])
-
-# Check if we have assembler support for unwind directives.
-gcc_GAS_CHECK_FEATURE([cfi directives], gcc_cv_as_cfi_directive,
- ,,
-[ .text
- .cfi_startproc
- .cfi_offset 0, 0
- .cfi_same_value 1
- .cfi_def_cfa 1, 2
- .cfi_escape 1, 2, 3, 4, 5
- .cfi_endproc],
-[case "$target" in
- *-*-solaris*)
- # If the linker used on Solaris (like Sun ld) isn't capable of merging
- # read-only and read-write sections, we need to make sure that the
- # assembler used emits read-write .eh_frame sections.
- if test "x$gcc_cv_ld_ro_rw_mix" != xread-write; then
- if test "x$gcc_cv_objdump" != x; then
- if $gcc_cv_objdump -h conftest.o 2>/dev/null | \
- sed -e /.eh_frame/!d -e N | grep READONLY > /dev/null; then
- gcc_cv_as_cfi_directive=no
- else
- case "$target" in
- i?86-*-solaris2.1[[0-9]]* | x86_64-*-solaris2.1[[0-9]]*)
- # On Solaris/x86, make sure that GCC and gas agree on using
- # read-only .eh_frame sections for 64-bit.
- if $gcc_cv_as --64 -o conftest.o conftest.s > /dev/null 2>&1 && \
- $gcc_cv_objdump -h conftest.o 2>/dev/null | \
- sed -e /.eh_frame/!d -e N | \
- grep READONLY > /dev/null; then
- gcc_cv_as_cfi_directive=yes
- else
- gcc_cv_as_cfi_directive=no
- fi
- ;;
- *)
- gcc_cv_as_cfi_directive=yes
- ;;
- esac
- fi
- else
- # no objdump, err on the side of caution
- gcc_cv_as_cfi_directive=no
- fi
- else
- gcc_cv_as_cfi_directive=yes
- fi
- ;;
- *-*-*)
- gcc_cv_as_cfi_directive=yes
- ;;
-esac])
-if test $gcc_cv_as_cfi_directive = yes && test x$gcc_cv_objdump != x; then
-gcc_GAS_CHECK_FEATURE([working cfi advance], gcc_cv_as_cfi_advance_working,
- ,,
-[ .text
- .cfi_startproc
- .cfi_adjust_cfa_offset 64
- .skip 75040, 0
- .cfi_adjust_cfa_offset 128
- .cfi_endproc],
-[[
-if $gcc_cv_objdump -Wf conftest.o 2>/dev/null \
- | grep 'DW_CFA_advance_loc[24]:[ ][ ]*75040[ ]' >/dev/null; then
- gcc_cv_as_cfi_advance_working=yes
-fi
-]])
-else
- # no objdump, err on the side of caution
- gcc_cv_as_cfi_advance_working=no
-fi
-GCC_TARGET_TEMPLATE(HAVE_GAS_CFI_DIRECTIVE)
-AC_DEFINE_UNQUOTED(HAVE_GAS_CFI_DIRECTIVE,
- [`if test $gcc_cv_as_cfi_directive = yes \
- && test $gcc_cv_as_cfi_advance_working = yes; then echo 1; else echo 0; fi`],
- [Define 0/1 if your assembler supports CFI directives.])
-
-GCC_TARGET_TEMPLATE(HAVE_GAS_CFI_PERSONALITY_DIRECTIVE)
-gcc_GAS_CHECK_FEATURE([cfi personality directive],
- gcc_cv_as_cfi_personality_directive, ,,
-[ .text
- .cfi_startproc
- .cfi_personality 0, symbol
- .cfi_endproc])
-AC_DEFINE_UNQUOTED(HAVE_GAS_CFI_PERSONALITY_DIRECTIVE,
- [`if test $gcc_cv_as_cfi_personality_directive = yes;
- then echo 1; else echo 0; fi`],
- [Define 0/1 if your assembler supports .cfi_personality.])
-
-gcc_GAS_CHECK_FEATURE([cfi sections directive],
- gcc_cv_as_cfi_sections_directive, ,,
-[ .text
- .cfi_sections .debug_frame, .eh_frame
- .cfi_startproc
- .cfi_endproc],
-[case $target_os in
- win32 | pe | cygwin* | mingw32* | uwin*)
- # Need to check that we generated the correct relocation for the
- # .debug_frame section. This was fixed for binutils 2.21.
- gcc_cv_as_cfi_sections_directive=no
- if test "x$gcc_cv_objdump" != x; then
- if $gcc_cv_objdump -j .debug_frame -r conftest.o 2>/dev/null | \
- grep secrel > /dev/null; then
- gcc_cv_as_cfi_sections_directive=yes
- fi
- fi
- ;;
- *)
- gcc_cv_as_cfi_sections_directive=yes
- ;;
-esac])
-GCC_TARGET_TEMPLATE(HAVE_GAS_CFI_SECTIONS_DIRECTIVE)
-AC_DEFINE_UNQUOTED(HAVE_GAS_CFI_SECTIONS_DIRECTIVE,
- [`if test $gcc_cv_as_cfi_sections_directive = yes;
- then echo 1; else echo 0; fi`],
- [Define 0/1 if your assembler supports .cfi_sections.])
-
-# GAS versions up to and including 2.11.0 may mis-optimize
-# .eh_frame data.
-gcc_GAS_CHECK_FEATURE(eh_frame optimization, gcc_cv_as_eh_frame,
- [elf,2,12,0],,
-[ .text
-.LFB1:
- .4byte 0
-.L1:
- .4byte 0
-.LFE1:
- .section .eh_frame,"aw",@progbits
-__FRAME_BEGIN__:
- .4byte .LECIE1-.LSCIE1
-.LSCIE1:
- .4byte 0x0
- .byte 0x1
- .ascii "z\0"
- .byte 0x1
- .byte 0x78
- .byte 0x1a
- .byte 0x0
- .byte 0x4
- .4byte 1
- .p2align 1
-.LECIE1:
-.LSFDE1:
- .4byte .LEFDE1-.LASFDE1
-.LASFDE1:
- .4byte .LASFDE1-__FRAME_BEGIN__
- .4byte .LFB1
- .4byte .LFE1-.LFB1
- .byte 0x4
- .4byte .LFE1-.LFB1
- .byte 0x4
- .4byte .L1-.LFB1
-.LEFDE1:],
-[ dnl # For autoconf 2.5x, must protect trailing spaces with @&t@.
-cat > conftest.lit <<EOF
- 0000 10000000 00000000 017a0001 781a0004 .........z..x...
- 0010 01000000 12000000 18000000 00000000 ................
- 0020 08000000 04080000 0044 .........D @&t@
-EOF
-cat > conftest.big <<EOF
- 0000 00000010 00000000 017a0001 781a0004 .........z..x...
- 0010 00000001 00000012 00000018 00000000 ................
- 0020 00000008 04000000 0844 .........D @&t@
-EOF
- # If the assembler didn't choke, and we can objdump,
- # and we got the correct data, then succeed.
- # The text in the here-document typically retains its unix-style line
- # endings, while the output of objdump will use host line endings.
- # Therefore, use diff -b for the comparisons.
- if test x$gcc_cv_objdump != x \
- && $gcc_cv_objdump -s -j .eh_frame conftest.o 2>/dev/null \
- | tail -3 > conftest.got \
- && { diff -b conftest.lit conftest.got > /dev/null 2>&1 \
- || diff -b conftest.big conftest.got > /dev/null 2>&1; }
- then
- gcc_cv_as_eh_frame=yes
- elif AC_TRY_COMMAND($gcc_cv_as -o conftest.o --traditional-format /dev/null); then
- gcc_cv_as_eh_frame=buggy
- else
- # Uh oh, what do we do now?
- gcc_cv_as_eh_frame=no
- fi])
-
-if test $gcc_cv_as_eh_frame = buggy; then
- AC_DEFINE(USE_AS_TRADITIONAL_FORMAT, 1,
- [Define if your assembler mis-optimizes .eh_frame data.])
-fi
-
-gcc_GAS_CHECK_FEATURE(section merging support, gcc_cv_as_shf_merge,
- [elf,2,12,0], [--fatal-warnings],
- [.section .rodata.str, "aMS", @progbits, 1])
-if test $gcc_cv_as_shf_merge = no; then
- gcc_GAS_CHECK_FEATURE(section merging support, gcc_cv_as_shf_merge,
- [elf,2,12,0], [--fatal-warnings],
- [.section .rodata.str, "aMS", %progbits, 1])
-fi
-AC_DEFINE_UNQUOTED(HAVE_GAS_SHF_MERGE,
- [`if test $gcc_cv_as_shf_merge = yes; then echo 1; else echo 0; fi`],
-[Define 0/1 if your assembler supports marking sections with SHF_MERGE flag.])
-
-gcc_GAS_CHECK_FEATURE([COMDAT group support (GNU as)],
- gcc_cv_as_comdat_group,
- [elf,2,16,0], [--fatal-warnings],
- [.section .text,"axG",@progbits,.foo,comdat])
-if test $gcc_cv_as_comdat_group = yes; then
- gcc_cv_as_comdat_group_percent=no
- gcc_cv_as_comdat_group_group=no
-else
- gcc_GAS_CHECK_FEATURE([COMDAT group support (GNU as, %type)],
- gcc_cv_as_comdat_group_percent,
- [elf,2,16,0], [--fatal-warnings],
- [.section .text,"axG",%progbits,.foo,comdat])
- if test $gcc_cv_as_comdat_group_percent = yes; then
- gcc_cv_as_comdat_group_group=no
- else
- if test -z "${gcc_cv_as_comdat_group_group+set}"; then
- gcc_cv_as_comdat_group_group=no
- fi
- case "${target}" in
- # Sun as uses a completely different syntax.
- *-*-solaris2*)
- case "${target}" in
- sparc*-*-solaris2*)
- conftest_s='
- .group foo,".text%foo",#comdat
- .section ".text%foo", #alloc,#execinstr,#progbits
- .globl foo
- foo:
- '
- ;;
- i?86-*-solaris2* | x86_64-*-solaris2.1[[0-9]]*)
- conftest_s='
- .group foo,.text%foo,#comdat
- .section .text%foo, "ax", @progbits
- .globl foo
- foo:
- '
- ;;
- esac
- gcc_GAS_CHECK_FEATURE([COMDAT group support (Sun as, .group)],
- gcc_cv_as_comdat_group_group,
- ,, [$conftest_s])
- ;;
- esac
- fi
-fi
-if test x"$ld_is_gold" = xyes; then
- comdat_group=yes
-elif test $in_tree_ld = yes ; then
- comdat_group=no
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes; then
- comdat_group=yes
- fi
-elif echo "$ld_ver" | grep GNU > /dev/null; then
- comdat_group=yes
- if test 0"$ld_date" -lt 20050308; then
- if test -n "$ld_date"; then
- # If there was date string, but was earlier than 2005-03-08, fail
- comdat_group=no
- elif test "$ld_vers_major" -lt 2; then
- comdat_group=no
- elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -lt 16; then
- comdat_group=no
- fi
- fi
-else
-changequote(,)dnl
- case "${target}" in
- *-*-solaris2.1[1-9]*)
- comdat_group=no
- # Sun ld has COMDAT group support since Solaris 9, but it doesn't
- # interoperate with GNU as until Solaris 11 build 130, i.e. ld
- # version 1.688.
- #
- # If using Sun as for COMDAT group as emitted by GCC, one needs at
- # least ld version 1.2267.
- if test "$ld_vers_major" -gt 1; then
- comdat_group=yes
- elif test "x$gas_flag" = xyes && test "$ld_vers_minor" -ge 1688; then
- comdat_group=yes
- elif test "$ld_vers_minor" -ge 2267; then
- comdat_group=yes
- fi
- ;;
- *)
- # Assume linkers other than GNU ld don't support COMDAT group.
- comdat_group=no
- ;;
- esac
-changequote([,])dnl
-fi
-# Allow overriding the automatic COMDAT group tests above.
-AC_ARG_ENABLE(comdat,
- [AS_HELP_STRING([--enable-comdat], [enable COMDAT group support])],
- [comdat_group="$enable_comdat"])
-if test $comdat_group = no; then
- gcc_cv_as_comdat_group=no
- gcc_cv_as_comdat_group_percent=no
- gcc_cv_as_comdat_group_group=no
-fi
-AC_DEFINE_UNQUOTED(HAVE_COMDAT_GROUP,
- [`if test $gcc_cv_as_comdat_group = yes \
- || test $gcc_cv_as_comdat_group_percent = yes \
- || test $gcc_cv_as_comdat_group_group = yes; then echo 1; else echo 0; fi`],
-[Define 0/1 if your assembler and linker support COMDAT groups.])
-
-gcc_GAS_CHECK_FEATURE([line table discriminator support],
- gcc_cv_as_discriminator,
- [2,19,51],,
-[ .text
- .file 1 "conf.c"
- .loc 1 1 0 discriminator 1],,
-[AC_DEFINE(HAVE_GAS_DISCRIMINATOR, 1,
- [Define if your assembler supports the .loc discriminator sub-directive.])])
-
-# Thread-local storage - the check is heavily parameterized.
-conftest_s=
-tls_first_major=
-tls_first_minor=
-tls_as_opt=
-case "$target" in
-changequote(,)dnl
- alpha*-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-foo: .long 25
- .text
- ldq $27,__tls_get_addr($29) !literal!1
- lda $16,foo($29) !tlsgd!1
- jsr $26,($27),__tls_get_addr !lituse_tlsgd!1
- ldq $27,__tls_get_addr($29) !literal!2
- lda $16,foo($29) !tlsldm!2
- jsr $26,($27),__tls_get_addr !lituse_tlsldm!2
- ldq $1,foo($29) !gotdtprel
- ldah $2,foo($29) !dtprelhi
- lda $3,foo($2) !dtprello
- lda $4,foo($29) !dtprel
- ldq $1,foo($29) !gottprel
- ldah $2,foo($29) !tprelhi
- lda $3,foo($2) !tprello
- lda $4,foo($29) !tprel'
- tls_first_major=2
- tls_first_minor=13
- tls_as_opt=--fatal-warnings
- ;;
- cris-*-*|crisv32-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-x: .long 25
- .text
- move.d x:IE,$r10
- nop'
- tls_first_major=2
- tls_first_minor=20
- tls_as_opt=--fatal-warnings
- ;;
- frv*-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-x: .long 25
- .text
- call #gettlsoff(x)'
- tls_first_major=2
- tls_first_minor=14
- ;;
- hppa*-*-linux*)
- conftest_s='
-t1: .reg %r20
-t2: .reg %r21
-gp: .reg %r19
- .section ".tdata","awT",@progbits
-foo: .long 25
- .text
- .align 4
- addil LT%foo-$tls_gdidx$,gp
- ldo RT%foo-$tls_gdidx$(%r1),%arg0
- b __tls_get_addr
- nop
- addil LT%foo-$tls_ldidx$,gp
- b __tls_get_addr
- ldo RT%foo-$tls_ldidx$(%r1),%arg0
- addil LR%foo-$tls_dtpoff$,%ret0
- ldo RR%foo-$tls_dtpoff$(%r1),%t1
- mfctl %cr27,%t1
- addil LT%foo-$tls_ieoff$,gp
- ldw RT%foo-$tls_ieoff$(%r1),%t2
- add %t1,%t2,%t3
- mfctl %cr27,%t1
- addil LR%foo-$tls_leoff$,%t1
- ldo RR%foo-$tls_leoff$(%r1),%t2'
- tls_first_major=2
- tls_first_minor=15
- tls_as_opt=--fatal-warnings
- ;;
- arm*-*-*)
- conftest_s='
- .section ".tdata","awT",%progbits
-foo: .long 25
- .text
-.word foo(gottpoff)
-.word foo(tpoff)
-.word foo(tlsgd)
-.word foo(tlsldm)
-.word foo(tlsldo)'
- tls_first_major=2
- tls_first_minor=17
- ;;
- i[34567]86-*-* | x86_64-*-solaris2.1[0-9]*)
- case "$target" in
- i[34567]86-*-solaris2.*)
- on_solaris=yes
- tga_func=___tls_get_addr
- ;;
- x86_64-*-solaris2.1[0-9]*)
- on_solaris=yes
- tga_func=__tls_get_addr
- ;;
- *)
- on_solaris=no
- ;;
- esac
- if test x$on_solaris = xyes && test x$gas_flag = xno; then
- conftest_s='
- .section .tdata,"awt",@progbits'
- tls_first_major=0
- tls_first_minor=0
-changequote([,])dnl
- AC_DEFINE(TLS_SECTION_ASM_FLAG, 't',
-[Define to the flag used to mark TLS sections if the default (`T') doesn't work.])
-changequote(,)dnl
- else
- conftest_s='
- .section ".tdata","awT",@progbits'
- tls_first_major=2
- tls_first_minor=14
- tls_as_opt="--fatal-warnings"
- fi
- conftest_s="$conftest_s
-foo: .long 25
- .text
- movl %gs:0, %eax
- leal foo@tlsgd(,%ebx,1), %eax
- leal foo@tlsldm(%ebx), %eax
- leal foo@dtpoff(%eax), %edx
- movl foo@gottpoff(%ebx), %eax
- subl foo@gottpoff(%ebx), %eax
- addl foo@gotntpoff(%ebx), %eax
- movl foo@indntpoff, %eax
- movl \$foo@tpoff, %eax
- subl \$foo@tpoff, %eax
- leal foo@ntpoff(%ecx), %eax"
- ;;
- x86_64-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-foo: .long 25
- .text
- movq %fs:0, %rax
- leaq foo@TLSGD(%rip), %rdi
- leaq foo@TLSLD(%rip), %rdi
- leaq foo@DTPOFF(%rax), %rdx
- movq foo@GOTTPOFF(%rip), %rax
- movq $foo@TPOFF, %rax'
- tls_first_major=2
- tls_first_minor=14
- tls_as_opt=--fatal-warnings
- ;;
- ia64-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-foo: data8 25
- .text
- addl r16 = @ltoff(@dtpmod(foo#)), gp
- addl r17 = @ltoff(@dtprel(foo#)), gp
- addl r18 = @ltoff(@tprel(foo#)), gp
- addl r19 = @dtprel(foo#), gp
- adds r21 = @dtprel(foo#), r13
- movl r23 = @dtprel(foo#)
- addl r20 = @tprel(foo#), gp
- adds r22 = @tprel(foo#), r13
- movl r24 = @tprel(foo#)'
- tls_first_major=2
- tls_first_minor=13
- tls_as_opt=--fatal-warnings
- ;;
- microblaze*-*-*)
- conftest_s='
- .section .tdata,"awT",@progbits
-x:
- .word 2
- .text
- addik r5,r20,x@TLSGD
- addik r5,r20,x@TLSLDM'
- tls_first_major=2
- tls_first_minor=20
- tls_as_opt='--fatal-warnings'
- ;;
- mips*-*-*)
- conftest_s='
- .section .tdata,"awT",@progbits
-x:
- .word 2
- .text
- addiu $4, $28, %tlsgd(x)
- addiu $4, $28, %tlsldm(x)
- lui $4, %dtprel_hi(x)
- addiu $4, $4, %dtprel_lo(x)
- lw $4, %gottprel(x)($28)
- lui $4, %tprel_hi(x)
- addiu $4, $4, %tprel_lo(x)'
- tls_first_major=2
- 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'
- ;;
- aarch64*-*-*)
- conftest_s='
- .section ".tdata","awT",%progbits
-foo: .long 25
- .text
- adrp x0, :tlsgd:x
- add x0, x0, #:tlsgd_lo12:x
- bl __tls_get_addr
- nop'
- tls_first_major=2
- tls_first_minor=20
- tls_as_opt='--fatal-warnings'
- ;;
- powerpc-ibm-aix*)
- conftest_s='
- .extern __get_tpointer
- .toc
-LC..1:
- .tc a[TC],a[TL]@le
- .csect .text[PR]
-.tlstest:
- lwz 9,LC..1(2)
- bla __get_tpointer
- lwzx 3,9,3
- .globl a
- .csect a[TL],4
-a:
- .space 4'
- tls_first_major=0
- tls_first_minor=0
- ;;
- powerpc-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
- .align 2
-ld0: .space 4
-ld1: .space 4
-x1: .space 4
-x2: .space 4
-x3: .space 4
- .text
- addi 3,31,ld0@got@tlsgd
- bl __tls_get_addr
- addi 3,31,x1@got@tlsld
- bl __tls_get_addr
- addi 9,3,x1@dtprel
- addis 9,3,x2@dtprel@ha
- addi 9,9,x2@dtprel@l
- lwz 9,x3@got@tprel(31)
- add 9,9,x@tls
- addi 9,2,x1@tprel
- addis 9,2,x2@tprel@ha
- addi 9,9,x2@tprel@l'
- tls_first_major=2
- tls_first_minor=14
- tls_as_opt="-a32 --fatal-warnings"
- ;;
- powerpc64-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
- .align 3
-ld0: .space 8
-ld1: .space 8
-x1: .space 8
-x2: .space 8
-x3: .space 8
- .text
- addi 3,2,ld0@got@tlsgd
- bl .__tls_get_addr
- nop
- addi 3,2,ld1@toc
- bl .__tls_get_addr
- nop
- addi 3,2,x1@got@tlsld
- bl .__tls_get_addr
- nop
- addi 9,3,x1@dtprel
- bl .__tls_get_addr
- nop
- addis 9,3,x2@dtprel@ha
- addi 9,9,x2@dtprel@l
- bl .__tls_get_addr
- nop
- ld 9,x3@got@dtprel(2)
- add 9,9,3
- bl .__tls_get_addr
- nop'
- tls_first_major=2
- tls_first_minor=14
- tls_as_opt="-a64 --fatal-warnings"
- ;;
- s390-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-foo: .long 25
- .text
- .long foo@TLSGD
- .long foo@TLSLDM
- .long foo@DTPOFF
- .long foo@NTPOFF
- .long foo@GOTNTPOFF
- .long foo@INDNTPOFF
- l %r1,foo@GOTNTPOFF(%r12)
- l %r1,0(%r1):tls_load:foo
- bas %r14,0(%r1,%r13):tls_gdcall:foo
- bas %r14,0(%r1,%r13):tls_ldcall:foo'
- tls_first_major=2
- tls_first_minor=14
- tls_as_opt="-m31 --fatal-warnings"
- ;;
- s390x-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-foo: .long 25
- .text
- .quad foo@TLSGD
- .quad foo@TLSLDM
- .quad foo@DTPOFF
- .quad foo@NTPOFF
- .quad foo@GOTNTPOFF
- lg %r1,foo@GOTNTPOFF(%r12)
- larl %r1,foo@INDNTPOFF
- brasl %r14,__tls_get_offset@PLT:tls_gdcall:foo
- brasl %r14,__tls_get_offset@PLT:tls_ldcall:foo'
- tls_first_major=2
- tls_first_minor=14
- tls_as_opt="-m64 -Aesame --fatal-warnings"
- ;;
- sh-*-* | sh[34]-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-foo: .long 25
- .text
- .long foo@TLSGD
- .long foo@TLSLDM
- .long foo@DTPOFF
- .long foo@GOTTPOFF
- .long foo@TPOFF'
- tls_first_major=2
- tls_first_minor=13
- tls_as_opt=--fatal-warnings
- ;;
- sparc*-*-*)
- case "$target" in
- sparc*-sun-solaris2.*)
- on_solaris=yes
- tga_func=__tls_get_addr
- ;;
- *)
- on_solaris=no
- ;;
- esac
- if test x$on_solaris = xyes && test x$gas_flag = xno; then
- conftest_s='
- .section ".tdata",#alloc,#write,#tls'
- tls_first_major=0
- tls_first_minor=0
- else
- conftest_s='
- .section ".tdata","awT",@progbits'
- tls_first_major=2
- tls_first_minor=14
- tls_as_opt="-32 --fatal-warnings"
- fi
- conftest_s="$conftest_s
-foo: .long 25
- .text
- sethi %tgd_hi22(foo), %o0
- add %o0, %tgd_lo10(foo), %o1
- add %l7, %o1, %o0, %tgd_add(foo)
- call __tls_get_addr, %tgd_call(foo)
- sethi %tldm_hi22(foo), %l1
- add %l1, %tldm_lo10(foo), %l2
- add %l7, %l2, %o0, %tldm_add(foo)
- call __tls_get_addr, %tldm_call(foo)
- sethi %tldo_hix22(foo), %l3
- xor %l3, %tldo_lox10(foo), %l4
- add %o0, %l4, %l5, %tldo_add(foo)
- sethi %tie_hi22(foo), %o3
- add %o3, %tie_lo10(foo), %o3
- ld [%l7 + %o3], %o2, %tie_ld(foo)
- add %g7, %o2, %o4, %tie_add(foo)
- sethi %tle_hix22(foo), %l1
- xor %l1, %tle_lox10(foo), %o5
- ld [%g7 + %o5], %o1"
- ;;
- tilepro*-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-foo: .long 25
- .text
- addli r0, zero, tls_gd(foo)
- auli r0, zero, tls_gd_ha16(foo)
- addli r0, r0, tls_gd_lo16(foo)
- jal __tls_get_addr
- addli r0, zero, tls_ie(foo)
- auli r0, r0, tls_ie_ha16(foo)
- addli r0, r0, tls_ie_lo16(foo)'
- tls_first_major=2
- tls_first_minor=22
- tls_as_opt="--fatal-warnings"
- ;;
- tilegx*-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-foo: .long 25
- .text
- shl16insli r0, zero, hw0_last_tls_gd(foo)
- shl16insli r0, zero, hw1_last_tls_gd(foo)
- shl16insli r0, r0, hw0_tls_gd(foo)
- jal __tls_get_addr
- shl16insli r0, zero, hw1_last_tls_ie(foo)
- shl16insli r0, r0, hw0_tls_ie(foo)'
- tls_first_major=2
- tls_first_minor=22
- tls_as_opt="--fatal-warnings"
- ;;
- xtensa*-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-foo: .long 25
- .text
- movi a8, foo@TLSFUNC
- movi a10, foo@TLSARG
- callx8.tls a8, foo@TLSCALL'
- tls_first_major=2
- tls_first_minor=19
- ;;
-changequote([,])dnl
-esac
-set_have_as_tls=no
-if test "x$enable_tls" = xno ; then
- : # TLS explicitly disabled.
-elif test "x$enable_tls" = xyes ; then
- set_have_as_tls=yes # TLS explicitly enabled.
-elif test -z "$tls_first_major"; then
- : # If we don't have a check, assume no support.
-else
- gcc_GAS_CHECK_FEATURE(thread-local storage support, gcc_cv_as_tls,
- [$tls_first_major,$tls_first_minor,0], [$tls_as_opt], [$conftest_s],,
- [set_have_as_tls=yes])
-fi
-case "$target" in
- # TLS was introduced in the Solaris 9 FCS release. Support for GNU-style
- # TLS on x86 was only introduced in Solaris 9 4/04, replacing the earlier
- # Sun style that Sun ld and GCC don't support any longer.
- *-*-solaris2.*)
- AC_MSG_CHECKING(linker and ld.so.1 TLS support)
- ld_tls_support=no
- # Check ld and ld.so.1 TLS support.
- if echo "$ld_ver" | grep GNU > /dev/null; then
- # Assume all interesting versions of GNU ld have TLS support.
- # FIXME: still need ld.so.1 support, i.e. ld version checks below.
- ld_tls_support=yes
- else
- case "$target" in
- # Solaris 9/x86 ld has GNU style TLS support since version 1.374.
- i?86-*-solaris2.9)
- min_tls_ld_vers_minor=374
- ;;
- # Solaris 9/SPARC and Solaris 10+ ld have TLS support since FCS.
- sparc*-*-solaris2.9 | *-*-solaris2.1[[0-9]]*)
- min_tls_ld_vers_minor=343
- ;;
- esac
- if test "$ld_vers_major" -gt 1 || \
- test "$ld_vers_minor" -ge "$min_tls_ld_vers_minor"; then
- ld_tls_support=yes
- else
- set_have_as_tls=no
- fi
- fi
- AC_MSG_RESULT($ld_tls_support)
-
- save_LIBS="$LIBS"
- save_LDFLAGS="$LDFLAGS"
- LIBS=
- LDFLAGS=
-
- AC_MSG_CHECKING(library containing $tga_func)
- # Before Solaris 10, __tls_get_addr (SPARC/x64) resp. ___tls_get_addr
- # (32-bit x86) only lived in libthread, so check for that. Keep
- # set_have_as_tls if found, disable if not.
- AC_SEARCH_LIBS([$tga_func], [thread],, [set_have_as_tls=no])
- # Clear LIBS if we cannot support TLS.
- if test $set_have_as_tls = no; then
- LIBS=
- fi
- # Always define LIB_TLS_SPEC, even without TLS support.
- AC_DEFINE_UNQUOTED(LIB_TLS_SPEC, "$LIBS",
- [Define to the library containing __tls_get_addr/___tls_get_addr.])
- AC_MSG_RESULT($LIBS)
-
- LIBS="$save_LIBS"
- LDFLAGS="$save_LDFLAGS"
- ;;
-esac
-if test $set_have_as_tls = yes ; then
- AC_DEFINE(HAVE_AS_TLS, 1,
- [Define if your assembler and linker support thread-local storage.])
-fi
-
-# Target-specific assembler checks.
-
-AC_MSG_CHECKING(linker -Bstatic/-Bdynamic option)
-gcc_cv_ld_static_dynamic=no
-gcc_cv_ld_static_option='-Bstatic'
-gcc_cv_ld_dynamic_option='-Bdynamic'
-if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 10 -o "$gcc_cv_gld_major_version" -gt 2; then
- gcc_cv_ld_static_dynamic=yes
- fi
-elif test x$gcc_cv_ld != x; then
- # Check if linker supports -Bstatic/-Bdynamic option
- if $gcc_cv_ld --help 2>/dev/null | grep -- -Bstatic > /dev/null \
- && $gcc_cv_ld --help 2>/dev/null | grep -- -Bdynamic > /dev/null; then
- gcc_cv_ld_static_dynamic=yes
- else
- case "$target" in
- # AIX ld uses -b flags
- *-*-aix4.[[23]]* | *-*-aix[[5-9]]*)
- gcc_cv_ld_static_dynamic=yes
- gcc_cv_ld_static_option="-bstatic"
- gcc_cv_ld_dynamic_option="-bdynamic"
- ;;
- # HP-UX ld uses -a flags to select between shared and archive.
- *-*-hpux*)
- if test x"$gnu_ld" = xno; then
- gcc_cv_ld_static_dynamic=yes
- gcc_cv_ld_static_option="-aarchive_shared"
- gcc_cv_ld_dynamic_option="-adefault"
- fi
- ;;
- # Solaris 2 ld always supports -Bstatic/-Bdynamic.
- *-*-solaris2*)
- gcc_cv_ld_static_dynamic=yes
- ;;
- esac
- fi
-fi
-if test x"$gcc_cv_ld_static_dynamic" = xyes; then
- AC_DEFINE(HAVE_LD_STATIC_DYNAMIC, 1,
-[Define if your linker supports -Bstatic/-Bdynamic or equivalent options.])
- AC_DEFINE_UNQUOTED(LD_STATIC_OPTION, "$gcc_cv_ld_static_option",
-[Define to the linker option to disable use of shared objects.])
- AC_DEFINE_UNQUOTED(LD_DYNAMIC_OPTION, "$gcc_cv_ld_dynamic_option",
-[Define to the linker option to enable use of shared objects.])
-fi
-AC_MSG_RESULT($gcc_cv_ld_static_dynamic)
-
-if test x"$demangler_in_ld" = xyes; then
- AC_MSG_CHECKING(linker --demangle support)
- gcc_cv_ld_demangle=no
- if test $in_tree_ld = yes; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 14 -o "$gcc_cv_gld_major_version" -gt 2; then \
- gcc_cv_ld_demangle=yes
- fi
- elif test x$gcc_cv_ld != x -a x"$gnu_ld" = xyes; then
- # Check if the GNU linker supports --demangle option
- if $gcc_cv_ld --help 2>/dev/null | grep no-demangle > /dev/null; then
- gcc_cv_ld_demangle=yes
- fi
- fi
- if test x"$gcc_cv_ld_demangle" = xyes; then
- AC_DEFINE(HAVE_LD_DEMANGLE, 1,
-[Define if your linker supports --demangle option.])
- fi
- AC_MSG_RESULT($gcc_cv_ld_demangle)
-fi
-
-AC_MSG_CHECKING(linker plugin support)
-gcc_cv_lto_plugin=0
-if test -f liblto_plugin.la; then
- save_ld_ver="$ld_ver"
- save_ld_vers_major="$ld_vers_major"
- save_ld_vers_minor="$ld_vers_minor"
- save_ld_is_gold="$ld_is_gold"
-
- ld_is_gold=no
-
- if test $in_tree_ld = yes -a x"$ORIGINAL_PLUGIN_LD_FOR_TARGET" = x"$gcc_cv_ld"; then
- ld_ver="GNU ld"
- # FIXME: ld_is_gold?
- ld_vers_major="$gcc_cv_gld_major_version"
- ld_vers_minor="$gcc_cv_gld_minor_version"
- else
- # Determine plugin linker version.
- # FIXME: Partial duplicate from above, generalize.
-changequote(,)dnl
- ld_ver=`$ORIGINAL_PLUGIN_LD_FOR_TARGET --version 2>/dev/null | sed 1q`
- if echo "$ld_ver" | grep GNU > /dev/null; then
- if echo "$ld_ver" | grep "GNU gold" > /dev/null; then
- ld_is_gold=yes
- ld_vers=`echo $ld_ver | sed -n \
- -e 's,^[^)]*[ ]\([0-9][0-9]*\.[0-9][0-9]*[^)]*\)) .*$,\1,p'`
- else
- ld_vers=`echo $ld_ver | sed -n \
- -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*.*\)$,\1,p'`
- fi
- ld_vers_major=`expr "$ld_vers" : '\([0-9]*\)'`
- ld_vers_minor=`expr "$ld_vers" : '[0-9]*\.\([0-9]*\)'`
- fi
-changequote([,])dnl
- fi
-
- # Determine plugin support.
- if echo "$ld_ver" | grep GNU > /dev/null; then
- # Require GNU ld or gold 2.21+ for plugin support by default.
- if test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -ge 21; then
- gcc_cv_lto_plugin=2
- # Allow -fuse-linker-plugin to enable plugin support in GNU gold 2.20.
- elif test "$ld_is_gold" = yes -a "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -eq 20; then
- gcc_cv_lto_plugin=1
- fi
- fi
-
- ld_ver="$save_ld_ver"
- ld_vers_major="$save_ld_vers_major"
- ld_vers_minor="$save_ld_vers_minor"
- ld_is_gold="$save_ld_is_gold"
-fi
-AC_DEFINE_UNQUOTED(HAVE_LTO_PLUGIN, $gcc_cv_lto_plugin,
- [Define to the level of your linker's plugin support.])
-AC_MSG_RESULT($gcc_cv_lto_plugin)
-
-case "$target" in
- # All TARGET_ABI_OSF targets.
- alpha*-*-linux* | alpha*-*-*bsd*)
- gcc_GAS_CHECK_FEATURE([explicit relocation support],
- gcc_cv_as_alpha_explicit_relocs, [2,12,0],,
-[ .set nomacro
- .text
- extbl $3, $2, $3 !lituse_bytoff!1
- ldq $2, a($29) !literal!1
- ldq $4, b($29) !literal!2
- ldq_u $3, 0($2) !lituse_base!1
- ldq $27, f($29) !literal!5
- jsr $26, ($27), f !lituse_jsr!5
- ldah $29, 0($26) !gpdisp!3
- lda $0, c($29) !gprel
- ldah $1, d($29) !gprelhigh
- lda $1, d($1) !gprellow
- lda $29, 0($29) !gpdisp!3],,
- [AC_DEFINE(HAVE_AS_EXPLICIT_RELOCS, 1,
- [Define if your assembler supports explicit relocations.])])
- gcc_GAS_CHECK_FEATURE([jsrdirect relocation support],
- gcc_cv_as_alpha_jsrdirect_relocs, [2,16,90],,
-[ .set nomacro
- .text
- ldq $27, a($29) !literal!1
- jsr $26, ($27), a !lituse_jsrdirect!1],,
- [AC_DEFINE(HAVE_AS_JSRDIRECT_RELOCS, 1,
- [Define if your assembler supports the lituse_jsrdirect relocation.])])
- ;;
-
- cris-*-*)
- gcc_GAS_CHECK_FEATURE([-no-mul-bug-abort option],
- gcc_cv_as_cris_no_mul_bug,[2,15,91],
- [-no-mul-bug-abort], [.text],,
- [AC_DEFINE(HAVE_AS_NO_MUL_BUG_ABORT_OPTION, 1,
- [Define if your assembler supports the -no-mul-bug-abort option.])])
- ;;
-
- sparc*-*-*)
- gcc_GAS_CHECK_FEATURE([.register], gcc_cv_as_sparc_register_op,,,
- [.register %g2, #scratch],,
- [AC_DEFINE(HAVE_AS_REGISTER_PSEUDO_OP, 1,
- [Define if your assembler supports .register.])])
-
- gcc_GAS_CHECK_FEATURE([@%:@nobits], gcc_cv_as_sparc_nobits,,,
- [.section "nobits",#alloc,#write,#nobits
- .section "progbits",#alloc,#write,#progbits])
- AC_DEFINE_UNQUOTED(HAVE_AS_SPARC_NOBITS,
- [`if test $gcc_cv_as_sparc_nobits = yes; then echo 1; else echo 0; fi`],
- [Define to 1 if your assembler supports #nobits, 0 otherwise.])
-
- gcc_GAS_CHECK_FEATURE([-relax option], gcc_cv_as_sparc_relax,,
- [-relax], [.text],,
- [AC_DEFINE(HAVE_AS_RELAX_OPTION, 1,
- [Define if your assembler supports -relax option.])])
-
- gcc_GAS_CHECK_FEATURE([GOTDATA_OP relocs],
- gcc_cv_as_sparc_gotdata_op,,
- [-K PIC],
-[.text
-.align 4
-foo:
- nop
-bar:
- sethi %gdop_hix22(foo), %g1
- xor %g1, %gdop_lox10(foo), %g1
- ld [[%l7 + %g1]], %g2, %gdop(foo)],
- [if test x$gcc_cv_ld != x \
- && $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1; then
- if test x$gcc_cv_objdump != x; then
- if $gcc_cv_objdump -s -j .text conftest 2> /dev/null \
- | grep ' 03000004 82186004 c405c001'> /dev/null 2>&1; then
- gcc_cv_as_sparc_gotdata_op=no
- else
- gcc_cv_as_sparc_gotdata_op=yes
- fi
- fi
- fi
- rm -f conftest],
- [AC_DEFINE(HAVE_AS_SPARC_GOTDATA_OP, 1,
- [Define if your assembler and linker support GOTDATA_OP relocs.])])
-
- gcc_GAS_CHECK_FEATURE([unaligned pcrel relocs],
- gcc_cv_as_sparc_ua_pcrel,,
- [-K PIC],
-[.text
-foo:
- nop
-.data
-.align 4
-.byte 0
-.uaword %r_disp32(foo)],
- [if test x$gcc_cv_ld != x \
- && $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1; then
- gcc_cv_as_sparc_ua_pcrel=yes
- fi
- rm -f conftest],
- [AC_DEFINE(HAVE_AS_SPARC_UA_PCREL, 1,
- [Define if your assembler and linker support unaligned PC relative relocs.])
-
- gcc_GAS_CHECK_FEATURE([unaligned pcrel relocs against hidden symbols],
- gcc_cv_as_sparc_ua_pcrel_hidden,,
- [-K PIC],
-[.data
-.align 4
-.byte 0x31
-.uaword %r_disp32(foo)
-.byte 0x32, 0x33, 0x34
-.global foo
-.hidden foo
-foo:
-.skip 4],
- [if test x$gcc_cv_ld != x && test x$gcc_cv_objdump != x \
- && $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1 \
- && $gcc_cv_objdump -s -j .data conftest 2> /dev/null \
- | grep ' 31000000 07323334' > /dev/null 2>&1; then
- if $gcc_cv_objdump -R conftest 2> /dev/null \
- | grep 'DISP32' > /dev/null 2>&1; then
- :
- else
- gcc_cv_as_sparc_ua_pcrel_hidden=yes
- fi
- fi
- rm -f conftest],
- [AC_DEFINE(HAVE_AS_SPARC_UA_PCREL_HIDDEN, 1,
- [Define if your assembler and linker support unaligned PC relative relocs against hidden symbols.])])
- ]) # unaligned pcrel relocs
-
- gcc_GAS_CHECK_FEATURE([offsetable %lo()],
- gcc_cv_as_sparc_offsetable_lo10,,
- [-xarch=v9],
-[.text
- or %g1, %lo(ab) + 12, %g1
- or %g1, %lo(ab + 12), %g1],
- [if test x$gcc_cv_objdump != x \
- && $gcc_cv_objdump -s -j .text conftest.o 2> /dev/null \
- | grep ' 82106000 82106000' > /dev/null 2>&1; then
- gcc_cv_as_sparc_offsetable_lo10=yes
- fi],
- [AC_DEFINE(HAVE_AS_OFFSETABLE_LO10, 1,
- [Define if your assembler supports offsetable %lo().])])
-
- gcc_GAS_CHECK_FEATURE([FMAF, HPC, and VIS 3.0 instructions],
- gcc_cv_as_sparc_fmaf,,
- [-xarch=v9d],
- [.text
- .register %g2, #scratch
- .register %g3, #scratch
- .align 4
- fmaddd %f0, %f2, %f4, %f6
- addxccc %g1, %g2, %g3
- fsrl32 %f2, %f4, %f8
- fnaddd %f10, %f12, %f14],,
- [AC_DEFINE(HAVE_AS_FMAF_HPC_VIS3, 1,
- [Define if your assembler supports FMAF, HPC, and VIS 3.0 instructions.])])
-
- gcc_GAS_CHECK_FEATURE([SPARC4 instructions],
- gcc_cv_as_sparc_sparc4,,
- [-xarch=sparc4],
- [.text
- .register %g2, #scratch
- .register %g3, #scratch
- .align 4
- cxbe %g2, %g3, 1f
-1: cwbneg %g2, %g3, 1f
-1: sha1
- md5
- aes_kexpand0 %f4, %f6, %f8
- des_round %f38, %f40, %f42, %f44
- camellia_f %f54, %f56, %f58, %f60
- kasumi_fi_xor %f46, %f48, %f50, %f52],,
- [AC_DEFINE(HAVE_AS_SPARC4, 1,
- [Define if your assembler supports SPARC4 instructions.])])
- ;;
-
-changequote(,)dnl
- i[34567]86-*-* | x86_64-*-*)
-changequote([,])dnl
- case $target_os in
- cygwin*)
- # Full C++ conformance when using a shared libstdc++-v3 requires some
- # support from the Cygwin DLL, which in more recent versions exports
- # wrappers to aid in interposing and redirecting operators new, delete,
- # etc., as per n2800 #17.6.4.6 [replacement.functions]. Check if we
- # are configuring for a version of Cygwin that exports the wrappers.
- if test x$host = x$target; then
- AC_CHECK_FUNC([__wrap__Znaj],[gcc_ac_cygwin_dll_wrappers=yes],[gcc_ac_cygwin_dll_wrappers=no])
- else
- # Can't check presence of libc functions during cross-compile, so
- # we just have to assume we're building for an up-to-date target.
- gcc_ac_cygwin_dll_wrappers=yes
- fi
- AC_DEFINE_UNQUOTED(USE_CYGWIN_LIBSTDCXX_WRAPPERS,
- [`if test $gcc_ac_cygwin_dll_wrappers = yes; then echo 1; else echo 0; fi`],
- [Define if you want to generate code by default that assumes that the
- Cygwin DLL exports wrappers to support libstdc++ function replacement.])
- esac
- case $target_os in
- cygwin* | pe | mingw32* | interix*)
- # Recent binutils allows the three-operand form of ".comm" on PE. This
- # definition is used unconditionally to initialise the default state of
- # the target option variable that governs usage of the feature.
- gcc_GAS_CHECK_FEATURE([.comm with alignment], gcc_cv_as_comm_has_align,
- [2,19,52],,[.comm foo,1,32])
- AC_DEFINE_UNQUOTED(HAVE_GAS_ALIGNED_COMM,
- [`if test $gcc_cv_as_comm_has_align = yes; then echo 1; else echo 0; fi`],
- [Define if your assembler supports specifying the alignment
- of objects allocated using the GAS .comm command.])
- # Used for DWARF 2 in PE
- gcc_GAS_CHECK_FEATURE([.secrel32 relocs],
- gcc_cv_as_ix86_pe_secrel32,
- [2,15,91],,
-[.text
-foo: nop
-.data
- .secrel32 foo],
- [if test x$gcc_cv_ld != x \
- && $gcc_cv_ld -o conftest conftest.o > /dev/null 2>&1; then
- gcc_cv_as_ix86_pe_secrel32=yes
- fi
- rm -f conftest],
- [AC_DEFINE(HAVE_GAS_PE_SECREL32_RELOC, 1,
- [Define if your assembler and linker support 32-bit section relative relocs via '.secrel32 label'.])])
- # Test if the assembler supports the extended form of the .section
- # directive that specifies section alignment. LTO support uses this,
- # but normally only after installation, so we warn but don't fail the
- # configure if LTO is enabled but the assembler does not support it.
- gcc_GAS_CHECK_FEATURE([.section with alignment], gcc_cv_as_section_has_align,
- [2,20,1],-fatal-warnings,[.section lto_test,"dr0"])
- if test x$gcc_cv_as_section_has_align != xyes; then
- case ",$enable_languages," in
- *,lto,*)
- AC_MSG_WARN([LTO for $target requires binutils >= 2.20.1, but version found appears insufficient; LTO will not work until binutils is upgraded.])
- ;;
- esac
- fi
- # Test if the assembler supports the section flag 'e' for specifying
- # an excluded section.
- gcc_GAS_CHECK_FEATURE([.section with e], gcc_cv_as_section_has_e,
- [2,22,51],,
-[.section foo1,"e"
-.byte 0,0,0,0])
- AC_DEFINE_UNQUOTED(HAVE_GAS_SECTION_EXCLUDE,
- [`if test $gcc_cv_as_section_has_e = yes; then echo 1; else echo 0; fi`],
- [Define if your assembler supports specifying the section flag e.])
- ;;
- esac
-
- gcc_GAS_CHECK_FEATURE([filds and fists mnemonics],
- gcc_cv_as_ix86_filds,,,
- [filds mem; fists mem],,
- [AC_DEFINE(HAVE_AS_IX86_FILDS, 1,
- [Define if your assembler uses filds and fists mnemonics.])])
-
- gcc_GAS_CHECK_FEATURE([fildq and fistpq mnemonics],
- gcc_cv_as_ix86_fildq,,,
- [fildq mem; fistpq mem],,
- [AC_DEFINE(HAVE_AS_IX86_FILDQ, 1,
- [Define if your assembler uses fildq and fistq mnemonics.])])
-
- gcc_GAS_CHECK_FEATURE([cmov syntax],
- gcc_cv_as_ix86_cmov_sun_syntax,,,
- [cmovl.l %edx, %eax],,
- [AC_DEFINE(HAVE_AS_IX86_CMOV_SUN_SYNTAX, 1,
- [Define if your assembler supports the Sun syntax for cmov.])])
-
- gcc_GAS_CHECK_FEATURE([ffreep mnemonic],
- gcc_cv_as_ix86_ffreep,,,
- [ffreep %st(1)],,
- [AC_DEFINE(HAVE_AS_IX86_FFREEP, 1,
- [Define if your assembler supports the ffreep mnemonic.])])
-
- gcc_GAS_CHECK_FEATURE([.quad directive],
- gcc_cv_as_ix86_quad,,,
- [.quad 0],,
- [AC_DEFINE(HAVE_AS_IX86_QUAD, 1,
- [Define if your assembler supports the .quad directive.])])
-
- gcc_GAS_CHECK_FEATURE([sahf mnemonic],
- gcc_cv_as_ix86_sahf,,,
- [.code64
- sahf],,
- [AC_DEFINE(HAVE_AS_IX86_SAHF, 1,
- [Define if your assembler supports the sahf mnemonic in 64bit mode.])])
-
- gcc_GAS_CHECK_FEATURE([hle prefixes],
- gcc_cv_as_ix86_hle,,,
- [lock xacquire cmpxchg %esi, (%ecx)],,
- [AC_DEFINE(HAVE_AS_IX86_HLE, 1,
- [Define if your assembler supports HLE prefixes.])])
-
- gcc_GAS_CHECK_FEATURE([swap suffix],
- gcc_cv_as_ix86_swap,,,
- [movl.s %esp, %ebp],,
- [AC_DEFINE(HAVE_AS_IX86_SWAP, 1,
- [Define if your assembler supports the swap suffix.])])
-
- gcc_GAS_CHECK_FEATURE([different section symbol subtraction],
- gcc_cv_as_ix86_diff_sect_delta,,,
- [.section .rodata
-.L1:
- .long .L2-.L1
- .long .L3-.L1
- .text
-.L3: nop
-.L2: nop],,
- [AC_DEFINE(HAVE_AS_IX86_DIFF_SECT_DELTA, 1,
- [Define if your assembler supports the subtraction of symbols in different sections.])])
-
- # These two are used unconditionally by i386.[ch]; it is to be defined
- # to 1 if the feature is present, 0 otherwise.
- gcc_GAS_CHECK_FEATURE([GOTOFF in data],
- gcc_cv_as_ix86_gotoff_in_data, [2,11,0],,
-[ .text
-.L0:
- nop
- .data
- .long .L0@GOTOFF])
- AC_DEFINE_UNQUOTED(HAVE_AS_GOTOFF_IN_DATA,
- [`if test $gcc_cv_as_ix86_gotoff_in_data = yes; then echo 1; else echo 0; fi`],
- [Define true if the assembler supports '.long foo@GOTOFF'.])
-
- gcc_GAS_CHECK_FEATURE([rep and lock prefix],
- gcc_cv_as_ix86_rep_lock_prefix,,,
- [rep movsl
- rep ret
- rep nop
- rep bsf %ecx, %eax
- rep bsr %ecx, %eax
- lock addl %edi, (%eax,%esi)
- lock orl $0, (%esp)],,
- [AC_DEFINE(HAVE_AS_IX86_REP_LOCK_PREFIX, 1,
- [Define if the assembler supports 'rep <insn>, lock <insn>'.])])
-
- gcc_GAS_CHECK_FEATURE([R_386_TLS_GD_PLT reloc],
- gcc_cv_as_ix86_tlsgdplt,,,
- [call tls_gd@tlsgdplt],
- [if test x$gcc_cv_ld != x \
- && $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1; then
- gcc_cv_as_ix86_tlsgdplt=yes
- fi
- rm -f conftest],
- [AC_DEFINE(HAVE_AS_IX86_TLSGDPLT, 1,
- [Define if your assembler and linker support @tlsgdplt.])])
-
- gcc_GAS_CHECK_FEATURE([R_386_TLS_LDM_PLT reloc],
- gcc_cv_as_ix86_tlsldmplt,,,
- [tls_ld:
- call tls_ld@tlsldmplt],
- [if test x$gcc_cv_ld != x \
- && $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1; then
- gcc_cv_as_ix86_tlsldmplt=yes
- fi
- rm -f conftest],
- [AC_DEFINE(HAVE_AS_IX86_TLSLDMPLT, 1,
- [Define if your assembler and linker support @tlsldmplt.])])
-
- ;;
-
- ia64*-*-*)
- gcc_GAS_CHECK_FEATURE([ltoffx and ldxmov relocs],
- gcc_cv_as_ia64_ltoffx_ldxmov_relocs, [2,14,0],,
-[ .text
- addl r15 = @ltoffx(x#), gp
- ;;
- ld8.mov r16 = [[r15]], x#],,
- [AC_DEFINE(HAVE_AS_LTOFFX_LDXMOV_RELOCS, 1,
- [Define if your assembler supports ltoffx and ldxmov relocations.])])
-
- ;;
-
- powerpc*-*-*)
- case $target in
- *-*-aix*) conftest_s=' .machine "pwr5"
- .csect .text[[PR]]
- mfcr 3,128';;
- *-*-darwin*)
- gcc_GAS_CHECK_FEATURE([.machine directive support],
- gcc_cv_as_machine_directive,,,
- [ .machine ppc7400])
- if test x$gcc_cv_as_machine_directive != xyes; then
- echo "*** This target requires an assembler supporting \".machine\"" >&2
- echo you can get it from: ftp://gcc.gnu.org/pub/gcc/infrastructure/cctools-528.5.dmg >&2
- test x$build = x$target && exit 1
- fi
- conftest_s=' .text
- mfcr r3,128';;
- *) conftest_s=' .machine power4
- .text
- mfcr 3,128';;
- esac
-
- gcc_GAS_CHECK_FEATURE([mfcr field support],
- gcc_cv_as_powerpc_mfcrf, [2,14,0],,
- [$conftest_s],,
- [AC_DEFINE(HAVE_AS_MFCRF, 1,
- [Define if your assembler supports mfcr field.])])
-
- case $target in
- *-*-aix*) conftest_s=' .machine "pwr5"
- .csect .text[[PR]]
- popcntb 3,3';;
- *) conftest_s=' .machine power5
- .text
- popcntb 3,3';;
- esac
-
- gcc_GAS_CHECK_FEATURE([popcntb support],
- gcc_cv_as_powerpc_popcntb, [2,17,0],,
- [$conftest_s],,
- [AC_DEFINE(HAVE_AS_POPCNTB, 1,
- [Define if your assembler supports popcntb field.])])
-
- case $target in
- *-*-aix*) conftest_s=' .machine "pwr5x"
- .csect .text[[PR]]
- frin 1,1';;
- *) conftest_s=' .machine power5
- .text
- frin 1,1';;
- esac
-
- gcc_GAS_CHECK_FEATURE([fp round support],
- gcc_cv_as_powerpc_fprnd, [2,17,0],,
- [$conftest_s],,
- [AC_DEFINE(HAVE_AS_FPRND, 1,
- [Define if your assembler supports fprnd.])])
-
- case $target in
- *-*-aix*) conftest_s=' .machine "pwr6"
- .csect .text[[PR]]
- mffgpr 1,3';;
- *) conftest_s=' .machine power6
- .text
- mffgpr 1,3';;
- esac
-
- gcc_GAS_CHECK_FEATURE([move fp gpr support],
- gcc_cv_as_powerpc_mfpgpr, [2,19,2],,
- [$conftest_s],,
- [AC_DEFINE(HAVE_AS_MFPGPR, 1,
- [Define if your assembler supports mffgpr and mftgpr.])])
-
- case $target in
- *-*-aix*) conftest_s=' .csect .text[[PR]]
-LCF..0:
- addis 11,30,_GLOBAL_OFFSET_TABLE_-LCF..0@ha';;
- *-*-darwin*)
- conftest_s=' .text
-LCF0:
- addis r11,r30,_GLOBAL_OFFSET_TABLE_-LCF0@ha';;
- *) conftest_s=' .text
-.LCF0:
- addis 11,30,_GLOBAL_OFFSET_TABLE_-.LCF0@ha';;
- esac
-
- gcc_GAS_CHECK_FEATURE([rel16 relocs],
- gcc_cv_as_powerpc_rel16, [2,17,0], -a32,
- [$conftest_s],,
- [AC_DEFINE(HAVE_AS_REL16, 1,
- [Define if your assembler supports R_PPC_REL16 relocs.])])
-
- case $target in
- *-*-aix*) conftest_s=' .machine "pwr6"
- .csect .text[[PR]]
- cmpb 3,4,5';;
- *) conftest_s=' .machine power6
- .text
- cmpb 3,4,5';;
- esac
-
- gcc_GAS_CHECK_FEATURE([compare bytes support],
- gcc_cv_as_powerpc_cmpb, [2,19,2], -a32,
- [$conftest_s],,
- [AC_DEFINE(HAVE_AS_CMPB, 1,
- [Define if your assembler supports cmpb.])])
-
- case $target in
- *-*-aix*) conftest_s=' .machine "pwr6"
- .csect .text[[PR]]
- dadd 1,2,3';;
- *) conftest_s=' .machine power6
- .text
- dadd 1,2,3';;
- esac
-
- gcc_GAS_CHECK_FEATURE([decimal float support],
- gcc_cv_as_powerpc_dfp, [2,19,2], -a32,
- [$conftest_s],,
- [AC_DEFINE(HAVE_AS_DFP, 1,
- [Define if your assembler supports DFP instructions.])])
-
- case $target in
- *-*-aix*) conftest_s=' .machine "pwr7"
- .csect .text[[PR]]
- lxvd2x 1,2,3';;
- *) conftest_s=' .machine power7
- .text
- lxvd2x 1,2,3';;
- esac
-
- gcc_GAS_CHECK_FEATURE([vector-scalar support],
- gcc_cv_as_powerpc_vsx, [2,19,2], -a32,
- [$conftest_s],,
- [AC_DEFINE(HAVE_AS_VSX, 1,
- [Define if your assembler supports VSX instructions.])])
-
- case $target in
- *-*-aix*) conftest_s=' .machine "pwr7"
- .csect .text[[PR]]
- popcntd 3,3';;
- *) conftest_s=' .machine power7
- .text
- popcntd 3,3';;
- esac
-
- gcc_GAS_CHECK_FEATURE([popcntd support],
- gcc_cv_as_powerpc_popcntd, [2,19,2], -a32,
- [$conftest_s],,
- [AC_DEFINE(HAVE_AS_POPCNTD, 1,
- [Define if your assembler supports POPCNTD instructions.])])
-
- case $target in
- *-*-aix*) conftest_s=' .machine "pwr8"
- .csect .text[[PR]]';;
- *) conftest_s=' .machine power8
- .text';;
- esac
-
- gcc_GAS_CHECK_FEATURE([power8 support],
- gcc_cv_as_powerpc_power8, [2,19,2], -a32,
- [$conftest_s],,
- [AC_DEFINE(HAVE_AS_POWER8, 1,
- [Define if your assembler supports POWER8 instructions.])])
-
- case $target in
- *-*-aix*) conftest_s=' .csect .text[[PR]]
- lwsync';;
- *) conftest_s=' .text
- lwsync';;
- esac
-
- gcc_GAS_CHECK_FEATURE([lwsync support],
- gcc_cv_as_powerpc_lwsync, [2,19,2], -a32,
- [$conftest_s],,
- [AC_DEFINE(HAVE_AS_LWSYNC, 1,
- [Define if your assembler supports LWSYNC instructions.])])
-
- case $target in
- *-*-aix*) conftest_s=' .machine "476"
- .csect .text[[PR]]
- dci 0';;
- *) conftest_s=' .machine "476"
- .text
- dci 0';;
- esac
-
- gcc_GAS_CHECK_FEATURE([data cache invalidate support],
- gcc_cv_as_powerpc_dci, [9,99,0], -a32,
- [$conftest_s],,
- [AC_DEFINE(HAVE_AS_DCI, 1,
- [Define if your assembler supports the DCI/ICI instructions.])])
-
- gcc_GAS_CHECK_FEATURE([.gnu_attribute support],
- gcc_cv_as_powerpc_gnu_attribute, [2,18,0],,
- [.gnu_attribute 4,1],,
- [AC_DEFINE(HAVE_AS_GNU_ATTRIBUTE, 1,
- [Define if your assembler supports .gnu_attribute.])])
-
- gcc_GAS_CHECK_FEATURE([tls marker support],
- gcc_cv_as_powerpc_tls_markers, [2,20,0],,
- [ bl __tls_get_addr(x@tlsgd)],,
- [AC_DEFINE(HAVE_AS_TLS_MARKERS, 1,
- [Define if your assembler supports arg info for __tls_get_addr.])])
-
- case $target in
- *-*-aix*)
- gcc_GAS_CHECK_FEATURE([.ref support],
- gcc_cv_as_aix_ref, [2,21,0],,
- [ .csect stuff[[rw]]
- stuff:
- .long 1
- .extern sym
- .ref sym
- ],,
- [AC_DEFINE(HAVE_AS_REF, 1,
- [Define if your assembler supports .ref])])
- ;;
- esac
- ;;
-
- mips*-*-*)
- gcc_GAS_CHECK_FEATURE([explicit relocation support],
- gcc_cv_as_mips_explicit_relocs, [2,14,0],,
-[ lw $4,%gp_rel(foo)($4)],,
- [if test x$target_cpu_default = x
- then target_cpu_default=MASK_EXPLICIT_RELOCS
- else target_cpu_default="($target_cpu_default)|MASK_EXPLICIT_RELOCS"
- fi])
- gcc_GAS_CHECK_FEATURE([-mno-shared support],
- gcc_cv_as_mips_no_shared, [2,16,0], [-mno-shared], [nop],,
- [AC_DEFINE(HAVE_AS_NO_SHARED, 1,
- [Define if the assembler understands -mno-shared.])])
-
- gcc_GAS_CHECK_FEATURE([.gnu_attribute support],
- gcc_cv_as_mips_gnu_attribute, [2,18,0],,
- [.gnu_attribute 4,1],,
- [AC_DEFINE(HAVE_AS_GNU_ATTRIBUTE, 1,
- [Define if your assembler supports .gnu_attribute.])])
-
- gcc_GAS_CHECK_FEATURE([.dtprelword support],
- gcc_cv_as_mips_dtprelword, [2,18,0],,
- [.section .tdata,"awT",@progbits
-x:
- .word 2
- .text
- .dtprelword x+0x8000],,
- [AC_DEFINE(HAVE_AS_DTPRELWORD, 1,
- [Define if your assembler supports .dtprelword.])])
-
- gcc_GAS_CHECK_FEATURE([DSPR1 mult with four accumulators support],
- gcc_cv_as_mips_dspr1_mult,,,
-[ .set mips32r2
- .set nodspr2
- .set dsp
- madd $ac3,$4,$5
- maddu $ac3,$4,$5
- msub $ac3,$4,$5
- msubu $ac3,$4,$5
- mult $ac3,$4,$5
- multu $ac3,$4,$5],,
- [AC_DEFINE(HAVE_AS_DSPR1_MULT, 1,
- [Define if your assembler supports DSPR1 mult.])])
-
- AC_MSG_CHECKING(assembler and linker for explicit JALR relocation)
- gcc_cv_as_ld_jalr_reloc=no
- if test $gcc_cv_as_mips_explicit_relocs = yes; then
- if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 20 -o "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes; then
- gcc_cv_as_ld_jalr_reloc=yes
- fi
- elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x -a x$gcc_cv_objdump != x; then
- echo ' .ent x' > conftest.s
- echo 'x: ld $2,%got_disp(y)($3)' >> conftest.s
- echo ' ld $25,%call16(y)($28)' >> conftest.s
- echo ' .reloc 1f,R_MIPS_JALR,y' >> conftest.s
- echo '1: jalr $25' >> conftest.s
- echo ' .reloc 1f,R_MIPS_JALR,x' >> conftest.s
- echo '1: jalr $25' >> conftest.s
- echo ' .end x' >> conftest.s
- if $gcc_cv_as -o conftest.o conftest.s >/dev/null 2>&AS_MESSAGE_LOG_FD \
- && $gcc_cv_ld -shared -o conftest.so conftest.o >/dev/null 2>&AS_MESSAGE_LOG_FD; then
- if $gcc_cv_objdump -d conftest.so | grep jalr >/dev/null 2>&1 \
- && $gcc_cv_objdump -d conftest.so | grep "bal.*<x>" >/dev/null 2>&1; then
- gcc_cv_as_ld_jalr_reloc=yes
- fi
- fi
- rm -f conftest.*
- fi
- fi
- if test $gcc_cv_as_ld_jalr_reloc = yes; then
- if test x$target_cpu_default = x; then
- target_cpu_default=MASK_RELAX_PIC_CALLS
- else
- target_cpu_default="($target_cpu_default)|MASK_RELAX_PIC_CALLS"
- fi
- fi
- AC_MSG_RESULT($gcc_cv_as_ld_jalr_reloc)
-
- AC_CACHE_CHECK([linker for .eh_frame personality relaxation],
- [gcc_cv_ld_mips_personality_relaxation],
- [gcc_cv_ld_mips_personality_relaxation=no
- if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 \
- -a "$gcc_cv_gld_minor_version" -ge 21 \
- -o "$gcc_cv_gld_major_version" -gt 2; then
- gcc_cv_ld_mips_personality_relaxation=yes
- fi
- elif test x$gcc_cv_as != x \
- -a x$gcc_cv_ld != x \
- -a x$gcc_cv_readelf != x ; then
- cat > conftest.s <<EOF
- .cfi_startproc
- .cfi_personality 0x80,indirect_ptr
- .ent test
-test:
- nop
- .end test
- .cfi_endproc
-
- .section .data,"aw",@progbits
-indirect_ptr:
- .dc.a personality
-EOF
- if $gcc_cv_as -KPIC -o conftest.o conftest.s > /dev/null 2>&1 \
- && $gcc_cv_ld -o conftest conftest.o -shared > /dev/null 2>&1; then
- if $gcc_cv_readelf -d conftest 2>&1 \
- | grep TEXTREL > /dev/null 2>&1; then
- :
- elif $gcc_cv_readelf --relocs conftest 2>&1 \
- | grep 'R_MIPS_REL32 *$' > /dev/null 2>&1; then
- :
- else
- gcc_cv_ld_mips_personality_relaxation=yes
- fi
- fi
- fi
- rm -f conftest.s conftest.o conftest])
- if test x$gcc_cv_ld_mips_personality_relaxation = xyes; then
- AC_DEFINE(HAVE_LD_PERSONALITY_RELAXATION, 1,
- [Define if your linker can relax absolute .eh_frame personality
-pointers into PC-relative form.])
- fi
- ;;
-esac
-
-# Mips and HP-UX need the GNU assembler.
-# Linux on IA64 might be able to use the Intel assembler.
-
-case "$target" in
- mips*-*-* | *-*-hpux* )
- if test x$gas_flag = xyes \
- || test x"$host" != x"$build" \
- || test ! -x "$gcc_cv_as" \
- || "$gcc_cv_as" -v < /dev/null 2>&1 | grep GNU > /dev/null; then
- :
- else
- echo "*** This configuration requires the GNU assembler" >&2
- exit 1
- fi
- ;;
-esac
-
-# ??? Not all targets support dwarf2 debug_line, even within a version
-# of gas. Moreover, we need to emit a valid instruction to trigger any
-# info to the output file. So, as supported targets are added to gas 2.11,
-# add some instruction here to (also) show we expect this might work.
-# ??? Once 2.11 is released, probably need to add first known working
-# version to the per-target configury.
-case "$cpu_type" in
- alpha | arm | avr | bfin | cris | i386 | m32c | m68k | microblaze | mips \
- | pa | rs6000 | score | sparc | spu | tilegx | tilepro | xstormy16 | xtensa)
- insn="nop"
- ;;
- ia64 | s390)
- insn="nop 0"
- ;;
- mmix)
- insn="swym 0"
- ;;
-esac
-if test x"$insn" != x; then
- conftest_s="\
- .file 1 \"conftest.s\"
- .loc 1 3 0
- $insn"
- gcc_GAS_CHECK_FEATURE([dwarf2 debug_line support],
- gcc_cv_as_dwarf2_debug_line,
- [elf,2,11,0],, [$conftest_s],
- [if test x$gcc_cv_objdump != x \
- && $gcc_cv_objdump -h conftest.o 2> /dev/null \
- | grep debug_line > /dev/null 2>&1; then
- gcc_cv_as_dwarf2_debug_line=yes
- fi])
-
-# The .debug_line file table must be in the exact order that
-# we specified the files, since these indices are also used
-# by DW_AT_decl_file. Approximate this test by testing if
-# the assembler bitches if the same index is assigned twice.
- gcc_GAS_CHECK_FEATURE([buggy dwarf2 .file directive],
- gcc_cv_as_dwarf2_file_buggy,,,
-[ .file 1 "foo.s"
- .file 1 "bar.s"])
-
- if test $gcc_cv_as_dwarf2_debug_line = yes \
- && test $gcc_cv_as_dwarf2_file_buggy = no; then
- AC_DEFINE(HAVE_AS_DWARF2_DEBUG_LINE, 1,
- [Define if your assembler supports dwarf2 .file/.loc directives,
- and preserves file table indices exactly as given.])
- fi
-
- gcc_GAS_CHECK_FEATURE([--gdwarf2 option],
- gcc_cv_as_gdwarf2_flag,
- [elf,2,11,0], [--gdwarf2], [$insn],,
- [AC_DEFINE(HAVE_AS_GDWARF2_DEBUG_FLAG, 1,
-[Define if your assembler supports the --gdwarf2 option.])])
-
- gcc_GAS_CHECK_FEATURE([--gstabs option],
- gcc_cv_as_gstabs_flag,
- [elf,2,11,0], [--gstabs], [$insn],
- [# The native Solaris 9/Intel assembler doesn't understand --gstabs
- # and warns about it, but still exits successfully. So check for
- # this.
- if AC_TRY_COMMAND([$gcc_cv_as --gstabs -o conftest.o conftest.s 2>&1 | grep -i warning > /dev/null])
- then :
- else gcc_cv_as_gstabs_flag=yes
- fi],
- [AC_DEFINE(HAVE_AS_GSTABS_DEBUG_FLAG, 1,
-[Define if your assembler supports the --gstabs option.])])
-
- gcc_GAS_CHECK_FEATURE([--debug-prefix-map option],
- gcc_cv_as_debug_prefix_map_flag,
- [2,18,0], [--debug-prefix-map /a=/b], [$insn],,
- [AC_DEFINE(HAVE_AS_DEBUG_PREFIX_MAP, 1,
-[Define if your assembler supports the --debug-prefix-map option.])])
-fi
-
-gcc_GAS_CHECK_FEATURE([.lcomm with alignment], gcc_cv_as_lcomm_with_alignment,
- ,,
-[.lcomm bar,4,16],,
-[AC_DEFINE(HAVE_GAS_LCOMM_WITH_ALIGNMENT, 1,
- [Define if your assembler supports .lcomm with an alignment field.])])
-
-AC_ARG_ENABLE(gnu-unique-object,
- [AS_HELP_STRING([--enable-gnu-unique-object],
- [enable the use of the @gnu_unique_object ELF extension on glibc systems])],
- [case $enable_gnu_unique_object in
- yes | no) ;;
- *) AC_MSG_ERROR(['$enable_gnu_unique_object' is an invalid value for --enable-gnu-unique-object.
-Valid choices are 'yes' and 'no'.]) ;;
- esac],
- [gcc_GAS_CHECK_FEATURE([gnu_unique_object], gcc_cv_as_gnu_unique_object,
- [elf,2,19,52],,
- [.type foo, '$target_type_format_char'gnu_unique_object],,
-# We need to unquote above to to use the definition from config.gcc.
-# Also check for ld.so support, i.e. glibc 2.11 or higher.
- [[if test x$host = x$build -a x$host = x$target &&
- ldd --version 2>/dev/null &&
- glibcver=`ldd --version 2>/dev/null | sed 's/.* //;q'`; then
- glibcmajor=`expr "$glibcver" : "\([0-9]*\)"`
- glibcminor=`expr "$glibcver" : "[2-9]*\.\([0-9]*\)"`
- glibcnum=`expr $glibcmajor \* 1000 + $glibcminor`
- if test "$glibcnum" -ge 2011 ; then
- enable_gnu_unique_object=yes
- fi
- fi]])])
-if test x$enable_gnu_unique_object = xyes; then
- AC_DEFINE(HAVE_GAS_GNU_UNIQUE_OBJECT, 1,
- [Define if your assembler supports @gnu_unique_object.])
-fi
-
-AC_CACHE_CHECK([assembler for tolerance to line number 0],
- [gcc_cv_as_line_zero],
- [gcc_cv_as_line_zero=no
- if test $in_tree_gas = yes; then
- gcc_GAS_VERSION_GTE_IFELSE(2, 16, 91, [gcc_cv_as_line_zero=yes])
- elif test "x$gcc_cv_as" != x; then
- { echo '# 1 "test.s" 1'; echo '# 0 "" 2'; } > conftest.s
- if AC_TRY_COMMAND([$gcc_cv_as -o conftest.o conftest.s >&AS_MESSAGE_LOG_FD 2>conftest.out]) &&
- test "x`cat conftest.out`" = x
- then
- gcc_cv_as_line_zero=yes
- else
- echo "configure: failed program was" >&AS_MESSAGE_LOG_FD
- cat conftest.s >&AS_MESSAGE_LOG_FD
- echo "configure: error output was" >&AS_MESSAGE_LOG_FD
- cat conftest.out >&AS_MESSAGE_LOG_FD
- fi
- rm -f conftest.o conftest.s conftest.out
- fi])
-if test "x$gcc_cv_as_line_zero" = xyes; then
- AC_DEFINE([HAVE_AS_LINE_ZERO], 1,
-[Define if the assembler won't complain about a line such as # 0 "" 2.])
-fi
-
-AC_MSG_CHECKING(linker PT_GNU_EH_FRAME support)
-gcc_cv_ld_eh_frame_hdr=no
-if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 12 -o "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes; then
- gcc_cv_ld_eh_frame_hdr=yes
- fi
-elif test x$gcc_cv_ld != x; then
- if echo "$ld_ver" | grep GNU > /dev/null; then
- # Check if linker supports --eh-frame-hdr option
- if $gcc_cv_ld --help 2>/dev/null | grep eh-frame-hdr > /dev/null; then
- gcc_cv_ld_eh_frame_hdr=yes
- fi
- else
- case "$target" in
- *-*-solaris2*)
- # Sun ld has various bugs in .eh_frame_hdr support before version 1.2251.
- if test "$ld_vers_major" -gt 1 || test "$ld_vers_minor" -ge 2251; then
- gcc_cv_ld_eh_frame_hdr=yes
- fi
- ;;
- esac
- fi
-fi
-GCC_TARGET_TEMPLATE([HAVE_LD_EH_FRAME_HDR])
-if test x"$gcc_cv_ld_eh_frame_hdr" = xyes; then
- AC_DEFINE(HAVE_LD_EH_FRAME_HDR, 1,
-[Define if your linker supports .eh_frame_hdr.])
- AC_ARG_ENABLE(eh-frame-hdr-for-static,
- [AS_HELP_STRING([--enable-eh-frame-hdr-for-static],
- [enable linker PT_GNU_EH_FRAME support for static executable])],
- [case $enable_eh_frame_hdr_for_static in
- yes | no) ;;
- *) AC_MSG_ERROR(['$enable_eh_frame_hdr_for_static' is an invalid
-value for --enable-eh-frame-hdr-for-static.
-Valid choices are 'yes' and 'no'.]) ;;
- esac],
-# Only support for glibc 2.3.0 or higher with AT_PHDR/AT_PHNUM from
-# Linux kernel.
- [[if test x$host = x$build -a x$host = x$target &&
- ldd --version 2>&1 >/dev/null &&
- glibcver=`ldd --version 2>/dev/null | sed 's/.* //;q'`; then
- glibcmajor=`expr "$glibcver" : "\([0-9]*\)"`
- glibcminor=`expr "$glibcver" : "[2-9]*\.\([0-9]*\)"`
- glibcnum=`expr $glibcmajor \* 1000 + $glibcminor`
- if test "$glibcnum" -ge 2003 ; then
- auvx=`LD_SHOW_AUXV=1 ldd 2>/dev/null`
- if echo "$auvx" | grep AT_PHDR > /dev/null &&
- echo "$auvx" | grep AT_PHNUM > /dev/null; then
- enable_eh_frame_hdr_for_static=yes
- fi
- fi
- fi]])
- if test x$enable_eh_frame_hdr_for_static = xyes; then
- AC_DEFINE(USE_EH_FRAME_HDR_FOR_STATIC, 1,
-[Define if your system supports PT_GNU_EH_FRAME for static executable.])
- fi
-fi
-AC_MSG_RESULT($gcc_cv_ld_eh_frame_hdr)
-
-AC_MSG_CHECKING(linker position independent executable support)
-gcc_cv_ld_pie=no
-if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 15 -o "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes; then
- gcc_cv_ld_pie=yes
- fi
-elif test x$gcc_cv_ld != x; then
- # Check if linker supports -pie option
- if $gcc_cv_ld --help 2>/dev/null | grep -- -pie > /dev/null; then
- gcc_cv_ld_pie=yes
- fi
-fi
-if test x"$gcc_cv_ld_pie" = xyes; then
- AC_DEFINE(HAVE_LD_PIE, 1,
-[Define if your linker supports -pie option.])
-fi
-AC_MSG_RESULT($gcc_cv_ld_pie)
-
-AC_MSG_CHECKING(linker EH-compatible garbage collection of sections)
-gcc_cv_ld_eh_gc_sections=no
-if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 17 -o "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes; then
- gcc_cv_ld_eh_gc_sections=yes
- fi
-elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x -a x$gcc_cv_objdump != x ; then
- cat > conftest.s <<EOF
- .section .text
-.globl _start
- .type _start, @function
-_start:
- .long foo
- .size _start, .-_start
- .section .text.foo,"ax",@progbits
- .type foo, @function
-foo:
- .long 0
- .size foo, .-foo
- .section .gcc_except_table.foo,"a",@progbits
-.L0:
- .long 0
- .section .eh_frame,"a",@progbits
- .long .L0
-EOF
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then
- if $gcc_cv_ld -o conftest conftest.o --entry=_start --gc-sections 2>&1 \
- | grep "gc-sections option ignored" > /dev/null; then
- gcc_cv_ld_eh_gc_sections=no
- elif $gcc_cv_objdump -h conftest 2> /dev/null \
- | grep gcc_except_table > /dev/null; then
- gcc_cv_ld_eh_gc_sections=yes
- # If no COMDAT groups, the compiler will emit .gnu.linkonce.t. sections.
- if test x$gcc_cv_as_comdat_group != xyes; then
- gcc_cv_ld_eh_gc_sections=no
- cat > conftest.s <<EOF
- .section .text
-.globl _start
- .type _start, @function
-_start:
- .long foo
- .size _start, .-_start
- .section .gnu.linkonce.t.foo,"ax",@progbits
- .type foo, @function
-foo:
- .long 0
- .size foo, .-foo
- .section .gcc_except_table.foo,"a",@progbits
-.L0:
- .long 0
- .section .eh_frame,"a",@progbits
- .long .L0
-EOF
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then
- if $gcc_cv_ld -o conftest conftest.o --entry=_start --gc-sections 2>&1 \
- | grep "gc-sections option ignored" > /dev/null; then
- gcc_cv_ld_eh_gc_sections=no
- elif $gcc_cv_objdump -h conftest 2> /dev/null \
- | grep gcc_except_table > /dev/null; then
- gcc_cv_ld_eh_gc_sections=yes
- fi
- fi
- fi
- fi
- fi
- rm -f conftest.s conftest.o conftest
-fi
-case "$target" in
- hppa*-*-linux*)
- # ??? This apparently exposes a binutils bug with PC-relative relocations.
- gcc_cv_ld_eh_gc_sections=no
- ;;
-esac
-if test x$gcc_cv_ld_eh_gc_sections = xyes; then
- AC_DEFINE(HAVE_LD_EH_GC_SECTIONS, 1,
- [Define if your linker supports garbage collection of
- sections in presence of EH frames.])
-fi
-AC_MSG_RESULT($gcc_cv_ld_eh_gc_sections)
-
-AC_MSG_CHECKING(linker EH garbage collection of sections bug)
-gcc_cv_ld_eh_gc_sections_bug=no
-if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -lt 19 -o "$gcc_cv_gld_major_version" -lt 2 \
- && test $in_tree_ld_is_elf = yes; then
- gcc_cv_ld_eh_gc_sections_bug=yes
- fi
-elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x -a x$gcc_cv_objdump != x -a x$gcc_cv_as_comdat_group = xyes; then
- gcc_cv_ld_eh_gc_sections_bug=yes
- cat > conftest.s <<EOF
- .section .text
-.globl _start
- .type _start, @function
-_start:
- .long foo
- .size _start, .-_start
- .section .text.startup.foo,"ax",@progbits
- .type foo, @function
-foo:
- .long 0
- .size foo, .-foo
- .section .gcc_except_table.foo,"a",@progbits
-.L0:
- .long 0
- .section .eh_frame,"a",@progbits
- .long .L0
-EOF
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then
- if $gcc_cv_ld -o conftest conftest.o --entry=_start --gc-sections 2>&1 \
- | grep "gc-sections option ignored" > /dev/null; then
- :
- elif $gcc_cv_objdump -h conftest 2> /dev/null \
- | grep gcc_except_table > /dev/null; then
- gcc_cv_ld_eh_gc_sections_bug=no
- fi
- fi
- rm -f conftest.s conftest.o conftest
-fi
-if test x$gcc_cv_ld_eh_gc_sections_bug = xyes; then
- AC_DEFINE(HAVE_LD_EH_GC_SECTIONS_BUG, 1,
- [Define if your linker has buggy garbage collection of
- sections support when .text.startup.foo like sections are used.])
-fi
-AC_MSG_RESULT($gcc_cv_ld_eh_gc_sections_bug)
-
-# --------
-# UNSORTED
-# --------
-
-AC_CACHE_CHECK(linker --as-needed support,
-gcc_cv_ld_as_needed,
-[gcc_cv_ld_as_needed=no
-if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes; then
- gcc_cv_ld_as_needed=yes
- fi
-elif test x$gcc_cv_ld != x; then
- # Check if linker supports --as-needed and --no-as-needed options
- if $gcc_cv_ld --help 2>/dev/null | grep as-needed > /dev/null; then
- gcc_cv_ld_as_needed=yes
- fi
-fi
-])
-if test x"$gcc_cv_ld_as_needed" = xyes; then
- AC_DEFINE(HAVE_LD_AS_NEEDED, 1,
-[Define if your linker supports --as-needed and --no-as-needed options.])
-fi
-
-case "$target:$tm_file" in
- powerpc64-*-freebsd* | powerpc64*-*-linux* | powerpc*-*-linux*rs6000/biarch64.h*)
- case "$target" in
- *-*-linux*)
- emul_name="-melf64ppc"
- ;;
- *-*-freebsd*)
- emul_name="-melf64ppc_fbsd"
- ;;
- esac
- AC_CACHE_CHECK(linker support for omitting dot symbols,
- gcc_cv_ld_no_dot_syms,
- [gcc_cv_ld_no_dot_syms=no
- if test x"$ld_is_gold" = xyes; then
- gcc_cv_ld_no_dot_syms=yes
- elif test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2; then
- gcc_cv_ld_no_dot_syms=yes
- fi
- elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x ; then
- cat > conftest1.s <<EOF
- .text
- bl .foo
-EOF
- cat > conftest2.s <<EOF
- .section ".opd","aw"
- .align 3
- .globl foo
- .type foo,@function
-foo:
- .quad .LEfoo,.TOC.@tocbase,0
- .text
-.LEfoo:
- blr
- .size foo,.-.LEfoo
-EOF
- if $gcc_cv_as -a64 -o conftest1.o conftest1.s > /dev/null 2>&1 \
- && $gcc_cv_as -a64 -o conftest2.o conftest2.s > /dev/null 2>&1 \
- && $gcc_cv_ld $emul_name -o conftest conftest1.o conftest2.o > /dev/null 2>&1; then
- gcc_cv_ld_no_dot_syms=yes
- fi
- rm -f conftest conftest1.o conftest2.o conftest1.s conftest2.s
- fi
- ])
- if test x"$gcc_cv_ld_no_dot_syms" = xyes; then
- AC_DEFINE(HAVE_LD_NO_DOT_SYMS, 1,
- [Define if your PowerPC64 linker only needs function descriptor syms.])
- fi
-
- AC_CACHE_CHECK(linker large toc support,
- gcc_cv_ld_large_toc,
- [gcc_cv_ld_large_toc=no
- if test x"$ld_is_gold" = xyes; then
- gcc_cv_ld_large_toc=yes
- elif test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 21 -o "$gcc_cv_gld_major_version" -gt 2; then
- gcc_cv_ld_large_toc=yes
- fi
- elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x ; then
- cat > conftest.s <<EOF
- .section ".tbss","awT",@nobits
- .align 3
-ie0: .space 8
- .global _start
- .text
-_start:
- addis 9,13,ie0@got@tprel@ha
- ld 9,ie0@got@tprel@l(9)
-EOF
- if $gcc_cv_as -a64 -o conftest.o conftest.s > /dev/null 2>&1 \
- && $gcc_cv_ld $emul_name --no-toc-sort -o conftest conftest.o > /dev/null 2>&1; then
- gcc_cv_ld_large_toc=yes
- fi
- rm -f conftest conftest.o conftest.s
- fi
- ])
- if test x"$gcc_cv_ld_large_toc" = xyes; then
- AC_DEFINE(HAVE_LD_LARGE_TOC, 1,
- [Define if your PowerPC64 linker supports a large TOC.])
- fi
- ;;
-esac
-
-case "$target" in
- *-*-aix*)
- AC_CACHE_CHECK(linker large toc support,
- gcc_cv_ld_large_toc,
- [gcc_cv_ld_large_toc=no
- if test x$gcc_cv_as != x ; then
- cat > conftest.s <<EOF
- .toc
-LC..1:
- .tc a[[TC]],a[[RW]]
- .extern a[[RW]]
- .csect .text[[PR]]
-.largetoctest:
- addis 9,LC..1@u(2)
- ld 3,LC..1@l(9)
-EOF
- if $gcc_cv_as -a64 -o conftest.o conftest.s > /dev/null 2>&1; then
- gcc_cv_ld_large_toc=yes
- fi
- rm -f conftest conftest.o conftest.s
- fi
- ])
- if test x"$gcc_cv_ld_large_toc" = xyes; then
- AC_DEFINE(HAVE_LD_LARGE_TOC, 1,
- [Define if your AIX linker supports a large TOC.])
- fi
- ;;
-esac
-
-AC_CACHE_CHECK(linker --build-id support,
- gcc_cv_ld_buildid,
- [gcc_cv_ld_buildid=no
- if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a \
- "$gcc_cv_gld_minor_version" -ge 18 -o \
- "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes; then
- gcc_cv_ld_buildid=yes
- fi
- elif test x$gcc_cv_ld != x; then
- if $gcc_cv_ld --help 2>/dev/null | grep build-id > /dev/null; then
- gcc_cv_ld_buildid=yes
- fi
- fi])
-if test x"$gcc_cv_ld_buildid" = xyes; then
- AC_DEFINE(HAVE_LD_BUILDID, 1,
- [Define if your linker supports --build-id.])
-fi
-
-AC_ARG_ENABLE(linker-build-id,
-[AS_HELP_STRING([--enable-linker-build-id],
- [compiler will always pass --build-id to linker])],
-[],
-enable_linker_build_id=no)
-
-if test x"$enable_linker_build_id" = xyes; then
- if test x"$gcc_cv_ld_buildid" = xyes; then
- AC_DEFINE(ENABLE_LD_BUILDID, 1,
- [Define if gcc should always pass --build-id to linker.])
- else
- AC_MSG_WARN(--build-id is not supported by your linker; --enable-linker-build-id ignored)
- fi
-fi
-
-# In binutils 2.21, GNU ld gained support for new emulations fully
-# supporting the Solaris 2 ABI. Detect their presence in the linker used.
-AC_CACHE_CHECK(linker *_sol2 emulation support,
- gcc_cv_ld_sol2_emulation,
- [gcc_cv_ld_sol2_emulation=no
- if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a \
- "$gcc_cv_gld_minor_version" -ge 21 -o \
- "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes; then
- gcc_cv_ld_sol2_emulation=yes
- fi
- elif test x$gcc_cv_ld != x; then
- if $gcc_cv_ld -V 2>/dev/null | sed -e '1,/Supported emulations/d;q' | \
- grep _sol2 > /dev/null; then
- gcc_cv_ld_sol2_emulation=yes
- fi
- fi])
-if test x"$gcc_cv_ld_sol2_emulation" = xyes; then
- AC_DEFINE(HAVE_LD_SOL2_EMULATION, 1,
- [Define if your linker supports the *_sol2 emulations.])
-fi
-
-AC_CACHE_CHECK(linker --sysroot support,
- gcc_cv_ld_sysroot,
- [gcc_cv_ld_sysroot=no
- if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2 ; then
- gcc_cv_ld_sysroot=yes
- fi
- elif test x$gcc_cv_ld != x; then
- if $gcc_cv_ld --help 2>/dev/null | grep sysroot > /dev/null; then
- gcc_cv_ld_sysroot=yes
- fi
- fi])
-if test x"$gcc_cv_ld_sysroot" = xyes; then
- AC_DEFINE(HAVE_LD_SYSROOT, 1,
- [Define if your linker supports --sysroot.])
-fi
-
-if test x$with_sysroot = x && test x$host = x$target \
- && test "$prefix" != "/usr" && test "x$prefix" != "x$local_prefix" \
- && test "$prefix" != "NONE"; then
- AC_DEFINE_UNQUOTED(PREFIX_INCLUDE_DIR, "$prefix/include",
-[Define to PREFIX/include if cpp should also search that directory.])
-fi
-
-if test x$host != x$target || test "x$TARGET_SYSTEM_ROOT" != x; then
- if test "x$with_headers" != x; then
- target_header_dir=$with_headers
- elif test "x$with_sysroot" = x; then
- target_header_dir="${test_exec_prefix}/${target_noncanonical}/sys-include"
- elif test "x$with_build_sysroot" != "x"; then
- target_header_dir="${with_build_sysroot}${native_system_header_dir}"
- elif test "x$with_sysroot" = xyes; then
- target_header_dir="${test_exec_prefix}/${target_noncanonical}/sys-root${native_system_header_dir}"
- else
- target_header_dir="${with_sysroot}${native_system_header_dir}"
- fi
-else
- target_header_dir=${native_system_header_dir}
-fi
-
-# Test for stack protector support in target C library.
-AC_CACHE_CHECK(__stack_chk_fail in target C library,
- gcc_cv_libc_provides_ssp,
- [gcc_cv_libc_provides_ssp=no
- case "$target" in
- *-*-linux* | *-*-kfreebsd*-gnu | *-*-knetbsd*-gnu)
- [# glibc 2.4 and later provides __stack_chk_fail and
- # either __stack_chk_guard, or TLS access to stack guard canary.
- if test -f $target_header_dir/features.h \
- && $EGREP '^[ ]*#[ ]*define[ ]+__GNU_LIBRARY__[ ]+([1-9][0-9]|[6-9])' \
- $target_header_dir/features.h > /dev/null; then
- if $EGREP '^[ ]*#[ ]*define[ ]+__GLIBC__[ ]+([1-9][0-9]|[3-9])' \
- $target_header_dir/features.h > /dev/null; then
- gcc_cv_libc_provides_ssp=yes
- elif $EGREP '^[ ]*#[ ]*define[ ]+__GLIBC__[ ]+2' \
- $target_header_dir/features.h > /dev/null \
- && $EGREP '^[ ]*#[ ]*define[ ]+__GLIBC_MINOR__[ ]+([1-9][0-9]|[4-9])' \
- $target_header_dir/features.h > /dev/null; then
- gcc_cv_libc_provides_ssp=yes
- elif $EGREP '^[ ]*#[ ]*define[ ]+__UCLIBC__[ ]+1' \
- $target_header_dir/features.h > /dev/null && \
- test -f $target_header_dir/bits/uClibc_config.h && \
- $EGREP '^[ ]*#[ ]*define[ ]+__UCLIBC_HAS_SSP__[ ]+1' \
- $target_header_dir/bits/uClibc_config.h > /dev/null; then
- gcc_cv_libc_provides_ssp=yes
- fi
- # all versions of Bionic support stack protector
- elif test -f $target_header_dir/sys/cdefs.h \
- && $EGREP '^[ ]*#[ ]*define[ ]+__BIONIC__[ ]+1' \
- $target_header_dir/sys/cdefs.h > /dev/null; then
- gcc_cv_libc_provides_ssp=yes
- fi]
- ;;
- *-*-gnu*)
- # Avoid complicated tests (see
- # <http://gcc.gnu.org/ml/gcc/2008-10/msg00130.html>) and for now
- # simply assert that glibc does provide this, which is true for all
- # realistically usable GNU/Hurd configurations.
- gcc_cv_libc_provides_ssp=yes;;
- *-*-darwin* | *-*-freebsd*)
- AC_CHECK_FUNC(__stack_chk_fail,[gcc_cv_libc_provides_ssp=yes],
- [echo "no __stack_chk_fail on this target"])
- ;;
- *) gcc_cv_libc_provides_ssp=no ;;
- esac])
-
-if test x$gcc_cv_libc_provides_ssp = xyes; then
- AC_DEFINE(TARGET_LIBC_PROVIDES_SSP, 1,
- [Define if your target C library provides stack protector support])
-fi
-
-# Test for <sys/sdt.h> on the target.
-GCC_TARGET_TEMPLATE([HAVE_SYS_SDT_H])
-AC_MSG_CHECKING(sys/sdt.h in the target C library)
-have_sys_sdt_h=no
-if test -f $target_header_dir/sys/sdt.h; then
- have_sys_sdt_h=yes
- AC_DEFINE(HAVE_SYS_SDT_H, 1,
- [Define if your target C library provides sys/sdt.h])
-fi
-AC_MSG_RESULT($have_sys_sdt_h)
-
-# Check if TFmode long double should be used by default or not.
-# Some glibc targets used DFmode long double, but with glibc 2.4
-# and later they can use TFmode.
-case "$target" in
- powerpc*-*-linux* | \
- sparc*-*-linux* | \
- s390*-*-linux* | \
- alpha*-*-linux*)
- AC_ARG_WITH(long-double-128,
- [AS_HELP_STRING([--with-long-double-128],
- [use 128-bit long double by default])],
- gcc_cv_target_ldbl128="$with_long_double_128",
- [[gcc_cv_target_ldbl128=no
- grep '^[ ]*#[ ]*define[ ][ ]*__LONG_DOUBLE_MATH_OPTIONAL' \
- $target_header_dir/bits/wordsize.h > /dev/null 2>&1 \
- && gcc_cv_target_ldbl128=yes
- ]])
- ;;
-esac
-if test x$gcc_cv_target_ldbl128 = xyes; then
- AC_DEFINE(TARGET_DEFAULT_LONG_DOUBLE_128, 1,
- [Define if TFmode long double should be the default])
-fi
-
-AC_MSG_CHECKING(dl_iterate_phdr in target C library)
-gcc_cv_target_dl_iterate_phdr=unknown
-case "$target" in
- # Restrict to Solaris 11+. While most of the Solaris 11 linker changes
- # were backported to Solaris 10 Update 10, dl_iterate_phdr only lives in
- # libdl there, both complicating its use and breaking compatibility
- # between Solaris 10 updates.
- *-*-solaris2.1[[1-9]]*)
- # <link.h> needs both a dl_iterate_phdr declaration and support for
- # compilation with largefile support.
- if grep dl_iterate_phdr $target_header_dir/link.h > /dev/null 2>&1 \
- && grep 'large file capable' $target_header_dir/link.h > /dev/null 2>&1; then
- gcc_cv_target_dl_iterate_phdr=yes
- else
- gcc_cv_target_dl_iterate_phdr=no
- fi
- ;;
-esac
-GCC_TARGET_TEMPLATE([TARGET_DL_ITERATE_PHDR])
-if test x$gcc_cv_target_dl_iterate_phdr = xyes; then
- AC_DEFINE(TARGET_DL_ITERATE_PHDR, 1,
-[Define if your target C library provides the `dl_iterate_phdr' function.])
-fi
-AC_MSG_RESULT($gcc_cv_target_dl_iterate_phdr)
-
-# We no longer support different GC mechanisms. Emit an error if
-# the user configures with --with-gc.
-AC_ARG_WITH(gc,
-[AS_HELP_STRING([--with-gc={page,zone}],
- [this option is not supported anymore. It used to choose
- the garbage collection mechanism to use with the compiler])],
-[AC_MSG_ERROR([Configure option --with-gc is only supported up to GCC 4.7.x])],
-[])
-
-# Libraries to use on the host. This will normally be set by the top
-# level Makefile. Here we simply capture the value for our Makefile.
-if test -z "${HOST_LIBS+set}"; then
- HOST_LIBS=
-fi
-AC_SUBST(HOST_LIBS)
-
-# Use the system's zlib library.
-zlibdir=-L../zlib
-zlibinc="-I\$(srcdir)/../zlib"
-AC_ARG_WITH(system-zlib,
-[AS_HELP_STRING([--with-system-zlib], [use installed libz])],
-zlibdir=
-zlibinc=
-)
-AC_SUBST(zlibdir)
-AC_SUBST(zlibinc)
-
-dnl Very limited version of automake's enable-maintainer-mode
-
-AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
- dnl maintainer-mode is disabled by default
- AC_ARG_ENABLE(maintainer-mode,
-[AS_HELP_STRING([--enable-maintainer-mode],
- [enable make rules and dependencies not useful
- (and sometimes confusing) to the casual installer])],
- maintainer_mode=$enableval,
- maintainer_mode=no)
-
-AC_MSG_RESULT($maintainer_mode)
-
-if test "$maintainer_mode" = "yes"; then
- MAINT=''
-else
- MAINT='#'
-fi
-AC_SUBST(MAINT)dnl
-
-# --------------
-# Language hooks
-# --------------
-
-# Make empty files to contain the specs and options for each language.
-# Then add #include lines to for a compiler that has specs and/or options.
-
-subdirs=
-lang_opt_files=
-lang_specs_files=
-lang_tree_files=
-# These (without "all_") are set in each config-lang.in.
-# `language' must be a single word so is spelled singularly.
-all_languages=
-all_compilers=
-all_outputs='Makefile'
-# List of language makefile fragments.
-all_lang_makefrags=
-# Additional files for gengtype
-all_gtfiles="$target_gtfiles"
-
-# These are the languages that are set in --enable-languages,
-# and are available in the GCC tree.
-all_selected_languages=
-
-# Add the language fragments.
-# Languages are added via two mechanisms. Some information must be
-# recorded in makefile variables, these are defined in config-lang.in.
-# We accumulate them and plug them into the main Makefile.
-# The other mechanism is a set of hooks for each of the main targets
-# like `clean', `install', etc.
-
-language_hooks="Make-hooks"
-
-for lang in ${srcdir}/*/config-lang.in
-do
-changequote(,)dnl
- test "$lang" = "${srcdir}/*/config-lang.in" && continue
-
- lang_alias=`sed -n -e 's,^language=['"'"'"'"]\(.*\)["'"'"'"'].*$,\1,p' -e 's,^language=\([^ ]*\).*$,\1,p' $lang`
- if test "x$lang_alias" = x
- then
- echo "$lang doesn't set \$language." 1>&2
- exit 1
- fi
- subdir="`echo $lang | sed -e 's,^.*/\([^/]*\)/config-lang.in$,\1,'`"
- subdirs="$subdirs $subdir"
-
- # $gcc_subdir is where the gcc integration files are to be found
- # for a language, both for internal compiler purposes (compiler
- # sources implementing front-end to GCC tree converters), and for
- # build infrastructure purposes (Make-lang.in, etc.)
- #
- # This will be <subdir> (relative to $srcdir) if a line like
- # gcc_subdir="<subdir>" or gcc_subdir=<subdir>
- # is found in <langdir>/config-lang.in, and will remain <langdir>
- # otherwise.
- #
- # Except for the language alias (fetched above), the regular
- # "config-lang.in" contents are always retrieved from $gcc_subdir,
- # so a <langdir>/config-lang.in setting gcc_subdir typically sets
- # only this and the language alias.
-
- gcc_subdir=`sed -n -e 's,^gcc_subdir=['"'"'"'"]\(.*\)["'"'"'"'].*$,\1,p' -e 's,^gcc_subdir=\([^ ]*\).*$,\1,p' $lang`
- if [ "$gcc_subdir" = "" ]; then
- gcc_subdir="$subdir"
- fi
-
- case ",$enable_languages," in
- *,$lang_alias,*)
- all_selected_languages="$all_selected_languages $lang_alias"
- if test -f $srcdir/$gcc_subdir/lang-specs.h; then
- lang_specs_files="$lang_specs_files $srcdir/$gcc_subdir/lang-specs.h"
- fi
- ;;
- esac
-changequote([,])dnl
-
- language=
- boot_language=
- compilers=
- outputs=
- gtfiles=
- subdir_requires=
- . ${srcdir}/$gcc_subdir/config-lang.in
- if test "x$language" = x
- then
- echo "${srcdir}/$gcc_subdir/config-lang.in doesn't set \$language." 1>&2
- exit 1
- fi
-
- ok=:
- case ",$enable_languages," in
- *,$lang_alias,*) ;;
- *)
- for i in $subdir_requires; do
- test -f "${srcdir}/$i/config-lang.in" && continue
- ok=false
- break
- done
- ;;
- esac
- $ok || continue
-
- all_lang_makefrags="$all_lang_makefrags \$(srcdir)/$gcc_subdir/Make-lang.in"
- if test -f $srcdir/$gcc_subdir/lang.opt; then
- lang_opt_files="$lang_opt_files $srcdir/$gcc_subdir/lang.opt"
- all_opt_files="$all_opt_files $srcdir/$gcc_subdir/lang.opt"
- fi
- if test -f $srcdir/$gcc_subdir/$subdir-tree.def; then
- lang_tree_files="$lang_tree_files $srcdir/$gcc_subdir/$subdir-tree.def"
- fi
- all_languages="$all_languages $language"
- all_compilers="$all_compilers $compilers"
- all_outputs="$all_outputs $outputs"
- all_gtfiles="$all_gtfiles [[$subdir]] $gtfiles"
- case ",$enable_languages," in
- *,lto,*)
- AC_DEFINE(ENABLE_LTO, 1, [Define to enable LTO support.])
- enable_lto=yes
- AC_SUBST(enable_lto)
- ;;
- *) ;;
- esac
-done
-
-check_languages=
-for language in $all_selected_languages
-do
- check_languages="$check_languages check-$language"
-done
-
-# We link each language in with a set of hooks, reached indirectly via
-# lang.${target}. Only do so for selected languages.
-
-rm -f Make-hooks
-touch Make-hooks
-target_list="all.cross start.encap rest.encap tags \
- install-common install-man install-info install-pdf install-html dvi \
- pdf html uninstall info man srcextra srcman srcinfo \
- mostlyclean clean distclean maintainer-clean install-plugin"
-
-for t in $target_list
-do
- x=
- for lang in $all_selected_languages
- do
- x="$x $lang.$t"
- done
- echo "lang.$t: $x" >> Make-hooks
-done
-
-# --------
-# Option include files
-# --------
-
-${AWK} -f $srcdir/opt-include.awk $all_opt_files > option-includes.mk
-option_includes="option-includes.mk"
-AC_SUBST_FILE(option_includes)
-
-# --------
-# UNSORTED
-# --------
-
-# Create .gdbinit.
-
-echo "dir ." > .gdbinit
-echo "dir ${srcdir}" >> .gdbinit
-if test x$gdb_needs_out_file_path = xyes
-then
- echo "dir ${srcdir}/config/"`dirname ${out_file}` >> .gdbinit
-fi
-if test "x$subdirs" != x; then
- for s in $subdirs
- do
- echo "dir ${srcdir}/$s" >> .gdbinit
- done
-fi
-echo "source ${srcdir}/gdbinit.in" >> .gdbinit
-
-gcc_tooldir='$(libsubdir)/$(libsubdir_to_prefix)$(target_noncanonical)'
-AC_SUBST(gcc_tooldir)
-AC_SUBST(dollar)
-
-# Find a directory in which to install a shared libgcc.
-
-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])])
-
-# Substitute configuration variables
-AC_SUBST(subdirs)
-AC_SUBST(srcdir)
-AC_SUBST(all_compilers)
-AC_SUBST(all_gtfiles)
-AC_SUBST(all_lang_makefrags)
-AC_SUBST(all_languages)
-AC_SUBST(all_selected_languages)
-AC_SUBST(build_exeext)
-AC_SUBST(build_install_headers_dir)
-AC_SUBST(build_xm_file_list)
-AC_SUBST(build_xm_include_list)
-AC_SUBST(build_xm_defines)
-AC_SUBST(build_file_translate)
-AC_SUBST(check_languages)
-AC_SUBST(cpp_install_dir)
-AC_SUBST(xmake_file)
-AC_SUBST(tmake_file)
-AC_SUBST(TM_ENDIAN_CONFIG)
-AC_SUBST(TM_MULTILIB_CONFIG)
-AC_SUBST(TM_MULTILIB_EXCEPTIONS_CONFIG)
-AC_SUBST(extra_gcc_objs)
-AC_SUBST(user_headers_inc_next_pre)
-AC_SUBST(user_headers_inc_next_post)
-AC_SUBST(extra_headers_list)
-AC_SUBST(extra_objs)
-AC_SUBST(extra_programs)
-AC_SUBST(float_h_file)
-AC_SUBST(gcc_config_arguments)
-AC_SUBST(gcc_gxx_include_dir)
-AC_SUBST(gcc_gxx_include_dir_add_sysroot)
-AC_SUBST(host_exeext)
-AC_SUBST(host_xm_file_list)
-AC_SUBST(host_xm_include_list)
-AC_SUBST(host_xm_defines)
-AC_SUBST(out_host_hook_obj)
-AC_SUBST(install)
-AC_SUBST(lang_opt_files)
-AC_SUBST(lang_specs_files)
-AC_SUBST(lang_tree_files)
-AC_SUBST(local_prefix)
-AC_SUBST(md_file)
-AC_SUBST(objc_boehm_gc)
-AC_SUBST(out_file)
-AC_SUBST(out_object_file)
-AC_SUBST(common_out_file)
-AC_SUBST(common_out_object_file)
-AC_SUBST(tm_file_list)
-AC_SUBST(tm_include_list)
-AC_SUBST(tm_defines)
-AC_SUBST(tm_p_file_list)
-AC_SUBST(tm_p_include_list)
-AC_SUBST(xm_file_list)
-AC_SUBST(xm_include_list)
-AC_SUBST(xm_defines)
-AC_SUBST(use_gcc_stdint)
-AC_SUBST(c_target_objs)
-AC_SUBST(cxx_target_objs)
-AC_SUBST(fortran_target_objs)
-AC_SUBST(target_cpu_default)
-
-AC_SUBST_FILE(language_hooks)
-
-# Echo link setup.
-if test x${build} = x${host} ; then
- if test x${host} = x${target} ; then
- echo "Links are now set up to build a native compiler for ${target}." 1>&2
- else
- echo "Links are now set up to build a cross-compiler" 1>&2
- echo " from ${host} to ${target}." 1>&2
- fi
-else
- if test x${host} = x${target} ; then
- echo "Links are now set up to build (on ${build}) a native compiler" 1>&2
- echo " for ${target}." 1>&2
- else
- echo "Links are now set up to build (on ${build}) a cross-compiler" 1>&2
- echo " from ${host} to ${target}." 1>&2
- fi
-fi
-
-AC_ARG_VAR(GMPLIBS,[How to link GMP])
-AC_ARG_VAR(GMPINC,[How to find GMP include files])
-
-AC_ARG_VAR(ISLLIBS,[How to link ISL])
-AC_ARG_VAR(ISLINC,[How to find ISL include files])
-
-AC_ARG_VAR(CLOOGLIBS,[How to link CLOOG])
-AC_ARG_VAR(CLOOGINC,[How to find CLOOG include files])
-if test "x${CLOOGLIBS}" != "x" ; then
- AC_DEFINE(HAVE_cloog, 1, [Define if cloog is in use.])
-fi
-
-# Check for plugin support
-AC_ARG_ENABLE(plugin,
-[AS_HELP_STRING([--enable-plugin], [enable plugin support])],
-enable_plugin=$enableval,
-enable_plugin=yes; default_plugin=yes)
-
-pluginlibs=
-
-case "${host}" in
- *-*-darwin*)
- if test x$build = x$host; then
- export_sym_check="nm${exeext} -g"
- elif test x$host = x$target; then
- export_sym_check="$gcc_cv_nm -g"
- else
- export_sym_check=
- fi
- ;;
- *)
- if test x$build = x$host; then
- export_sym_check="objdump${exeext} -T"
- elif test x$host = x$target; then
- export_sym_check="$gcc_cv_objdump -T"
- else
- export_sym_check=
- fi
- ;;
-esac
-
-if test x"$enable_plugin" = x"yes"; then
-
- AC_MSG_CHECKING([for exported symbols])
- if test "x$export_sym_check" != x; then
- echo "int main() {return 0;} int foobar() {return 0;}" > conftest.c
- ${CC} ${CFLAGS} ${LDFLAGS} conftest.c -o conftest > /dev/null 2>&1
- if $export_sym_check conftest | grep foobar > /dev/null; then
- : # No need to use a flag
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([yes])
- AC_MSG_CHECKING([for -rdynamic])
- ${CC} ${CFLAGS} ${LDFLAGS} -rdynamic conftest.c -o conftest > /dev/null 2>&1
- if $export_sym_check conftest | grep foobar > /dev/null; then
- plugin_rdynamic=yes
- pluginlibs="-rdynamic"
- else
- plugin_rdynamic=no
- enable_plugin=no
- fi
- AC_MSG_RESULT([$plugin_rdynamic])
- fi
- else
- AC_MSG_RESULT([unable to check])
- fi
-
- # Check -ldl
- saved_LIBS="$LIBS"
- AC_SEARCH_LIBS([dlopen], [dl])
- if test x"$ac_cv_search_dlopen" = x"-ldl"; then
- pluginlibs="$pluginlibs -ldl"
- fi
- LIBS="$saved_LIBS"
-
- # Check that we can build shared objects with -fPIC -shared
- saved_LDFLAGS="$LDFLAGS"
- saved_CFLAGS="$CFLAGS"
- case "${host}" in
- *-*-darwin*)
- CFLAGS=`echo $CFLAGS | sed s/-mdynamic-no-pic//g`
- CFLAGS="$CFLAGS -fPIC"
- LDFLAGS="$LDFLAGS -shared -undefined dynamic_lookup"
- ;;
- *)
- CFLAGS="$CFLAGS -fPIC"
- LDFLAGS="$LDFLAGS -fPIC -shared"
- ;;
- esac
- AC_MSG_CHECKING([for -fPIC -shared])
- AC_TRY_LINK(
- [extern int X;],[return X == 0;],
- [AC_MSG_RESULT([yes]); have_pic_shared=yes],
- [AC_MSG_RESULT([no]); have_pic_shared=no])
- if test x"$have_pic_shared" != x"yes" -o x"$ac_cv_search_dlopen" = x"no"; then
- pluginlibs=
- enable_plugin=no
- fi
- LDFLAGS="$saved_LDFLAGS"
- CFLAGS="$saved_CFLAGS"
-
- # If plugin support had been requested but not available, fail.
- if test x"$enable_plugin" = x"no" ; then
- if test x"$default_plugin" != x"yes"; then
- AC_MSG_ERROR([
-Building GCC with plugin support requires a host that supports
--fPIC, -shared, -ldl and -rdynamic.])
- fi
- fi
-fi
-
-AC_SUBST(pluginlibs)
-AC_SUBST(enable_plugin)
-if test x"$enable_plugin" = x"yes"; then
- AC_DEFINE(ENABLE_PLUGIN, 1, [Define to enable plugin support.])
-fi
-
-
-AC_ARG_ENABLE(libquadmath-support,
-[AS_HELP_STRING([--disable-libquadmath-support],
- [disable libquadmath support for Fortran])],
-ENABLE_LIBQUADMATH_SUPPORT=$enableval,
-ENABLE_LIBQUADMATH_SUPPORT=yes)
-if test "${ENABLE_LIBQUADMATH_SUPPORT}" != "no" ; then
- AC_DEFINE(ENABLE_LIBQUADMATH_SUPPORT, 1,
- [Define to 1 to enable libquadmath support])
-fi
-
-
-# Specify what hash style to use by default.
-AC_ARG_WITH([linker-hash-style],
-[AC_HELP_STRING([--with-linker-hash-style={sysv,gnu,both}],
- [specify the linker hash style])],
-[case x"$withval" in
- xsysv)
- LINKER_HASH_STYLE=sysv
- ;;
- xgnu)
- LINKER_HASH_STYLE=gnu
- ;;
- xboth)
- LINKER_HASH_STYLE=both
- ;;
- *)
- AC_MSG_ERROR([$withval is an invalid option to --with-linker-hash-style])
- ;;
- esac],
-[LINKER_HASH_STYLE=''])
-if test x"${LINKER_HASH_STYLE}" != x; then
- AC_DEFINE_UNQUOTED(LINKER_HASH_STYLE, "$LINKER_HASH_STYLE",
- [The linker hash style])
-fi
-
-# Configure the subdirectories
-# AC_CONFIG_SUBDIRS($subdirs)
-
-# Create the Makefile
-# and configure language subdirectories
-AC_CONFIG_FILES($all_outputs)
-
-AC_CONFIG_COMMANDS([default],
-[
-case ${CONFIG_HEADERS} in
- *auto-host.h:config.in*)
- echo > cstamp-h ;;
-esac
-# Make sure all the subdirs exist.
-for d in $subdirs doc build common c-family
-do
- test -d $d || mkdir $d
-done
-],
-[subdirs='$subdirs'])
-AC_OUTPUT
-
diff --git a/gcc-4.8/gcc/configure.orig b/gcc-4.8/gcc/configure.orig
deleted file mode 100755
index 1e9bfd184..000000000
--- a/gcc-4.8/gcc/configure.orig
+++ /dev/null
@@ -1,28807 +0,0 @@
-#! /bin/sh
-# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.64.
-#
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software
-# Foundation, Inc.
-#
-# This configure script is free software; the Free Software Foundation
-# gives unlimited permission to copy, distribute and modify it.
-## -------------------- ##
-## M4sh Initialization. ##
-## -------------------- ##
-
-# Be more Bourne compatible
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
- emulate sh
- NULLCMD=:
- # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in #(
- *posix*) :
- set -o posix ;; #(
- *) :
- ;;
-esac
-fi
-
-
-as_nl='
-'
-export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
- && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
- as_echo='print -r --'
- as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
- as_echo='printf %s\n'
- as_echo_n='printf %s'
-else
- if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
- as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
- as_echo_n='/usr/ucb/echo -n'
- else
- as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
- as_echo_n_body='eval
- arg=$1;
- case $arg in #(
- *"$as_nl"*)
- expr "X$arg" : "X\\(.*\\)$as_nl";
- arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
- esac;
- expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
- '
- export as_echo_n_body
- as_echo_n='sh -c $as_echo_n_body as_echo'
- fi
- export as_echo_body
- as_echo='sh -c $as_echo_body as_echo'
-fi
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- PATH_SEPARATOR=:
- (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
- (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
- PATH_SEPARATOR=';'
- }
-fi
-
-
-# IFS
-# We need space, tab and new line, in precisely that order. Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" "" $as_nl"
-
-# Find who we are. Look in the path if we contain no directory separator.
-case $0 in #((
- *[\\/]* ) as_myself=$0 ;;
- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
- done
-IFS=$as_save_IFS
-
- ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
- as_myself=$0
-fi
-if test ! -f "$as_myself"; then
- $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
- exit 1
-fi
-
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there. '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
- && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-if test "x$CONFIG_SHELL" = x; then
- as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
- emulate sh
- NULLCMD=:
- # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '\${1+\"\$@\"}'='\"\$@\"'
- setopt NO_GLOB_SUBST
-else
- case \`(set -o) 2>/dev/null\` in #(
- *posix*) :
- set -o posix ;; #(
- *) :
- ;;
-esac
-fi
-"
- as_required="as_fn_return () { (exit \$1); }
-as_fn_success () { as_fn_return 0; }
-as_fn_failure () { as_fn_return 1; }
-as_fn_ret_success () { return 0; }
-as_fn_ret_failure () { return 1; }
-
-exitcode=0
-as_fn_success || { exitcode=1; echo as_fn_success failed.; }
-as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
-as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
-as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
-if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
-
-else
- exitcode=1; echo positional parameters were not saved.
-fi
-test x\$exitcode = x0 || exit 1"
- as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
- as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
- eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
- test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
-test \$(( 1 + 1 )) = 2 || exit 1
-
- test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
- ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
- ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
- ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
- PATH=/empty FPATH=/empty; export PATH FPATH
- test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
- || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1"
- if (eval "$as_required") 2>/dev/null; then :
- as_have_required=yes
-else
- as_have_required=no
-fi
- if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
-
-else
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-as_found=false
-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- as_found=:
- case $as_dir in #(
- /*)
- for as_base in sh bash ksh sh5; do
- # Try only shells that exist, to save several forks.
- as_shell=$as_dir/$as_base
- if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
- { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
- CONFIG_SHELL=$as_shell as_have_required=yes
- if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
- break 2
-fi
-fi
- done;;
- esac
- as_found=false
-done
-$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
- { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
- CONFIG_SHELL=$SHELL as_have_required=yes
-fi; }
-IFS=$as_save_IFS
-
-
- if test "x$CONFIG_SHELL" != x; then :
- # We cannot yet assume a decent shell, so we have to provide a
- # neutralization value for shells without unset; and this also
- # works around shells that cannot unset nonexistent variables.
- BASH_ENV=/dev/null
- ENV=/dev/null
- (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
- export CONFIG_SHELL
- exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
-fi
-
- if test x$as_have_required = xno; then :
- $as_echo "$0: This script requires a shell more modern than all"
- $as_echo "$0: the shells that I found on your system."
- if test x${ZSH_VERSION+set} = xset ; then
- $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
- $as_echo "$0: be upgraded to zsh 4.3.4 or later."
- else
- $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
-$0: including any error possibly output before this
-$0: message. Then install a modern shell, or manually run
-$0: the script under such a shell if you do have one."
- fi
- exit 1
-fi
-fi
-fi
-SHELL=${CONFIG_SHELL-/bin/sh}
-export SHELL
-# Unset more variables known to interfere with behavior of common tools.
-CLICOLOR_FORCE= GREP_OPTIONS=
-unset CLICOLOR_FORCE GREP_OPTIONS
-
-## --------------------- ##
-## M4sh Shell Functions. ##
-## --------------------- ##
-# as_fn_unset VAR
-# ---------------
-# Portably unset VAR.
-as_fn_unset ()
-{
- { eval $1=; unset $1;}
-}
-as_unset=as_fn_unset
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-
-# as_fn_mkdir_p
-# -------------
-# Create "$as_dir" as a directory, including parents if necessary.
-as_fn_mkdir_p ()
-{
-
- case $as_dir in #(
- -*) as_dir=./$as_dir;;
- esac
- test -d "$as_dir" || eval $as_mkdir_p || {
- as_dirs=
- while :; do
- case $as_dir in #(
- *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
- *) as_qdir=$as_dir;;
- esac
- as_dirs="'$as_qdir' $as_dirs"
- as_dir=`$as_dirname -- "$as_dir" ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_dir" : 'X\(//\)[^/]' \| \
- X"$as_dir" : 'X\(//\)$' \| \
- X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- test -d "$as_dir" && break
- done
- test -z "$as_dirs" || eval "mkdir $as_dirs"
- } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
-
-
-} # as_fn_mkdir_p
-# as_fn_append VAR VALUE
-# ----------------------
-# Append the text in VALUE to the end of the definition contained in VAR. Take
-# advantage of any shell optimizations that allow amortized linear growth over
-# repeated appends, instead of the typical quadratic growth present in naive
-# implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
- eval 'as_fn_append ()
- {
- eval $1+=\$2
- }'
-else
- as_fn_append ()
- {
- eval $1=\$$1\$2
- }
-fi # as_fn_append
-
-# as_fn_arith ARG...
-# ------------------
-# Perform arithmetic evaluation on the ARGs, and store the result in the
-# global $as_val. Take advantage of shells that can avoid forks. The arguments
-# must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
- eval 'as_fn_arith ()
- {
- as_val=$(( $* ))
- }'
-else
- as_fn_arith ()
- {
- as_val=`expr "$@" || test $? -eq 1`
- }
-fi # as_fn_arith
-
-
-# as_fn_error ERROR [LINENO LOG_FD]
-# ---------------------------------
-# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
-# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with status $?, using 1 if that was 0.
-as_fn_error ()
-{
- as_status=$?; test $as_status -eq 0 && as_status=1
- if test "$3"; then
- as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
- fi
- $as_echo "$as_me: error: $1" >&2
- as_fn_exit $as_status
-} # as_fn_error
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
- as_dirname=dirname
-else
- as_dirname=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-
- as_lineno_1=$LINENO as_lineno_1a=$LINENO
- as_lineno_2=$LINENO as_lineno_2a=$LINENO
- eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
- test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
- # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in #(((((
--n*)
- case `echo 'xy\c'` in
- *c*) ECHO_T=' ';; # ECHO_T is single tab character.
- xy) ECHO_C='\c';;
- *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
- ECHO_T=' ';;
- esac;;
-*)
- ECHO_N='-n';;
-esac
-
-rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
- rm -f conf$$.dir/conf$$.file
-else
- rm -f conf$$.dir
- mkdir conf$$.dir 2>/dev/null
-fi
-if (echo >conf$$.file) 2>/dev/null; then
- if ln -s conf$$.file conf$$ 2>/dev/null; then
- as_ln_s='ln -s'
- # ... but there are two gotchas:
- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
- elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
- else
- as_ln_s='cp -p'
- fi
-else
- as_ln_s='cp -p'
-fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
-
-if mkdir -p . 2>/dev/null; then
- as_mkdir_p='mkdir -p "$as_dir"'
-else
- test -d ./-p && rmdir ./-p
- as_mkdir_p=false
-fi
-
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-
-exec 7<&0 </dev/null 6>&1
-
-# Name of the host.
-# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
-# so uname gets run too.
-ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
-
-#
-# Initializations.
-#
-ac_default_prefix=/usr/local
-ac_clean_files=
-ac_config_libobj_dir=.
-LIBOBJS=
-cross_compiling=no
-subdirs=
-MFLAGS=
-MAKEFLAGS=
-
-# Identity of this package.
-PACKAGE_NAME=
-PACKAGE_TARNAME=
-PACKAGE_VERSION=
-PACKAGE_STRING=
-PACKAGE_BUGREPORT=
-PACKAGE_URL=
-
-ac_unique_file="tree.c"
-# Factoring default headers for most tests.
-ac_includes_default="\
-#include <stdio.h>
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#ifdef STDC_HEADERS
-# include <stdlib.h>
-# include <stddef.h>
-#else
-# ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-# endif
-#endif
-#ifdef HAVE_STRING_H
-# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
-# include <memory.h>
-# endif
-# include <string.h>
-#endif
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#ifdef HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif"
-
-ac_subst_vars='LTLIBOBJS
-LIBOBJS
-enable_plugin
-pluginlibs
-CLOOGINC
-CLOOGLIBS
-ISLINC
-ISLLIBS
-GMPINC
-GMPLIBS
-target_cpu_default
-fortran_target_objs
-cxx_target_objs
-c_target_objs
-use_gcc_stdint
-xm_defines
-xm_include_list
-xm_file_list
-tm_p_include_list
-tm_p_file_list
-tm_defines
-tm_include_list
-tm_file_list
-common_out_object_file
-common_out_file
-out_object_file
-out_file
-objc_boehm_gc
-md_file
-local_prefix
-lang_tree_files
-lang_specs_files
-lang_opt_files
-install
-out_host_hook_obj
-host_xm_defines
-host_xm_include_list
-host_xm_file_list
-host_exeext
-gcc_gxx_include_dir_add_sysroot
-gcc_gxx_include_dir
-gcc_config_arguments
-float_h_file
-extra_programs
-extra_objs
-extra_headers_list
-user_headers_inc_next_post
-user_headers_inc_next_pre
-extra_gcc_objs
-TM_MULTILIB_EXCEPTIONS_CONFIG
-TM_MULTILIB_CONFIG
-TM_ENDIAN_CONFIG
-tmake_file
-xmake_file
-cpp_install_dir
-check_languages
-build_file_translate
-build_xm_defines
-build_xm_include_list
-build_xm_file_list
-build_install_headers_dir
-build_exeext
-all_selected_languages
-all_languages
-all_lang_makefrags
-all_gtfiles
-all_compilers
-srcdir
-subdirs
-dollar
-gcc_tooldir
-enable_lto
-MAINT
-zlibinc
-zlibdir
-HOST_LIBS
-libgcc_visibility
-gcc_cv_readelf
-gcc_cv_objdump
-ORIGINAL_NM_FOR_TARGET
-gcc_cv_nm
-ORIGINAL_LD_FOR_TARGET
-ORIGINAL_PLUGIN_LD_FOR_TARGET
-gcc_cv_ld
-ORIGINAL_AS_FOR_TARGET
-gcc_cv_as
-enable_fast_install
-objdir
-OTOOL64
-OTOOL
-LIPO
-NMEDIT
-DSYMUTIL
-STRIP
-OBJDUMP
-ac_ct_DUMPBIN
-DUMPBIN
-LD
-FGREP
-SED
-LIBTOOL
-collect2
-STMP_FIXINC
-BUILD_LDFLAGS
-BUILD_CXXFLAGS
-BUILD_CFLAGS
-CXX_FOR_BUILD
-CC_FOR_BUILD
-inhibit_libc
-SYSTEM_HEADER_DIR
-ALL
-CROSS
-CATOBJEXT
-GENCAT
-INSTOBJEXT
-DATADIRNAME
-CATALOGS
-POSUB
-GMSGFMT
-XGETTEXT
-INCINTL
-LIBINTL_DEP
-LIBINTL
-USE_NLS
-extra_opt_files
-extra_modes_file
-NATIVE_SYSTEM_HEADER_DIR
-objext
-manext
-LIBICONV_DEP
-LTLIBICONV
-LIBICONV
-LDEXP_LIB
-EXTRA_GCC_LIBS
-GNAT_LIBEXC
-COLLECT2_LIBS
-CXXCPP
-AR
-NM
-BISON
-FLEX
-GENERATED_MANPAGES
-BUILD_INFO
-MAKEINFO
-have_mktemp_command
-make_compare_target
-INSTALL_DATA
-INSTALL_PROGRAM
-INSTALL
-ranlib_flags
-RANLIB
-LN
-LN_S
-AWK
-SET_MAKE
-REPORT_BUGS_TEXI
-REPORT_BUGS_TO
-PKGVERSION
-CONFIGURE_SPECS
-CROSS_SYSTEM_HEADER_DIR
-TARGET_SYSTEM_ROOT_DEFINE
-TARGET_SYSTEM_ROOT
-SYSROOT_CFLAGS_FOR_TARGET
-enable_shared
-enable_fixed_point
-enable_decimal_float
-with_float
-with_cpu
-enable_multiarch
-enable_multilib
-coverage_flags
-valgrind_command
-valgrind_path_defines
-valgrind_path
-TREECHECKING
-TREEBROWSER
-nocommon_flag
-noexception_flags
-warn_cxxflags
-warn_cflags
-c_strict_warn
-strict_warn
-c_loose_warn
-loose_warn
-EGREP
-GREP
-CPP
-PICFLAG_FOR_TARGET
-OUTPUT_OPTION
-NO_MINUS_C_MINUS_O
-GNATMAKE
-GNATBIND
-ac_ct_CXX
-CXXFLAGS
-CXX
-OBJEXT
-EXEEXT
-ac_ct_CC
-CPPFLAGS
-LDFLAGS
-CFLAGS
-CC
-GENINSRC
-target_subdir
-host_subdir
-build_subdir
-build_libsubdir
-target_noncanonical
-target_os
-target_vendor
-target_cpu
-target
-host_os
-host_vendor
-host_cpu
-host
-build_os
-build_vendor
-build_cpu
-build
-target_alias
-host_alias
-build_alias
-LIBS
-ECHO_T
-ECHO_N
-ECHO_C
-DEFS
-mandir
-localedir
-libdir
-psdir
-pdfdir
-dvidir
-htmldir
-infodir
-docdir
-oldincludedir
-includedir
-localstatedir
-sharedstatedir
-sysconfdir
-datadir
-datarootdir
-libexecdir
-sbindir
-bindir
-program_transform_name
-prefix
-exec_prefix
-PACKAGE_URL
-PACKAGE_BUGREPORT
-PACKAGE_STRING
-PACKAGE_VERSION
-PACKAGE_TARNAME
-PACKAGE_NAME
-PATH_SEPARATOR
-SHELL'
-ac_subst_files='option_includes
-language_hooks'
-ac_user_opts='
-enable_option_checking
-with_build_libsubdir
-with_local_prefix
-with_gxx_include_dir
-with_cpp_install_dir
-enable_generated_files_in_srcdir
-with_gnu_ld
-with_ld
-with_demangler_in_ld
-with_gnu_as
-with_as
-enable_largefile
-enable_werror_always
-enable_checking
-enable_coverage
-enable_gather_detailed_mem_stats
-with_stabs
-enable_multilib
-enable_multiarch
-enable___cxa_atexit
-enable_decimal_float
-enable_fixed_point
-enable_threads
-enable_tls
-enable_objc_gc
-with_dwarf2
-enable_shared
-with_native_system_header_dir
-with_build_sysroot
-with_sysroot
-with_specs
-with_pkgversion
-with_bugurl
-enable_languages
-with_multilib_list
-enable_rpath
-with_libiconv_prefix
-enable_sjlj_exceptions
-enable_secureplt
-enable_leading_mingw64_underscores
-enable_cld
-enable_frame_pointer
-enable_win32_registry
-enable_static
-with_pic
-enable_fast_install
-enable_libtool_lock
-with_plugin_ld
-enable_gnu_indirect_function
-enable_initfini_array
-enable_comdat
-enable_gnu_unique_object
-enable_eh_frame_hdr_for_static
-enable_linker_build_id
-with_long_double_128
-with_gc
-with_system_zlib
-enable_maintainer_mode
-enable_version_specific_runtime_libs
-enable_plugin
-enable_libquadmath_support
-with_linker_hash_style
-'
- ac_precious_vars='build_alias
-host_alias
-target_alias
-CC
-CFLAGS
-LDFLAGS
-LIBS
-CPPFLAGS
-CXX
-CXXFLAGS
-CCC
-CPP
-CXXCPP
-GMPLIBS
-GMPINC
-ISLLIBS
-ISLINC
-CLOOGLIBS
-CLOOGINC'
-
-
-# Initialize some variables set by options.
-ac_init_help=
-ac_init_version=false
-ac_unrecognized_opts=
-ac_unrecognized_sep=
-# The variables have the same names as the options, with
-# dashes changed to underlines.
-cache_file=/dev/null
-exec_prefix=NONE
-no_create=
-no_recursion=
-prefix=NONE
-program_prefix=NONE
-program_suffix=NONE
-program_transform_name=s,x,x,
-silent=
-site=
-srcdir=
-verbose=
-x_includes=NONE
-x_libraries=NONE
-
-# Installation directory options.
-# These are left unexpanded so users can "make install exec_prefix=/foo"
-# and all the variables that are supposed to be based on exec_prefix
-# by default will actually change.
-# Use braces instead of parens because sh, perl, etc. also accept them.
-# (The list follows the same order as the GNU Coding Standards.)
-bindir='${exec_prefix}/bin'
-sbindir='${exec_prefix}/sbin'
-libexecdir='${exec_prefix}/libexec'
-datarootdir='${prefix}/share'
-datadir='${datarootdir}'
-sysconfdir='${prefix}/etc'
-sharedstatedir='${prefix}/com'
-localstatedir='${prefix}/var'
-includedir='${prefix}/include'
-oldincludedir='/usr/include'
-docdir='${datarootdir}/doc/${PACKAGE}'
-infodir='${datarootdir}/info'
-htmldir='${docdir}'
-dvidir='${docdir}'
-pdfdir='${docdir}'
-psdir='${docdir}'
-libdir='${exec_prefix}/lib'
-localedir='${datarootdir}/locale'
-mandir='${datarootdir}/man'
-
-ac_prev=
-ac_dashdash=
-for ac_option
-do
- # If the previous option needs an argument, assign it.
- if test -n "$ac_prev"; then
- eval $ac_prev=\$ac_option
- ac_prev=
- continue
- fi
-
- case $ac_option in
- *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
- *) ac_optarg=yes ;;
- esac
-
- # Accept the important Cygnus configure options, so we can diagnose typos.
-
- case $ac_dashdash$ac_option in
- --)
- ac_dashdash=yes ;;
-
- -bindir | --bindir | --bindi | --bind | --bin | --bi)
- ac_prev=bindir ;;
- -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
- bindir=$ac_optarg ;;
-
- -build | --build | --buil | --bui | --bu)
- ac_prev=build_alias ;;
- -build=* | --build=* | --buil=* | --bui=* | --bu=*)
- build_alias=$ac_optarg ;;
-
- -cache-file | --cache-file | --cache-fil | --cache-fi \
- | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
- ac_prev=cache_file ;;
- -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
- | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
- cache_file=$ac_optarg ;;
-
- --config-cache | -C)
- cache_file=config.cache ;;
-
- -datadir | --datadir | --datadi | --datad)
- ac_prev=datadir ;;
- -datadir=* | --datadir=* | --datadi=* | --datad=*)
- datadir=$ac_optarg ;;
-
- -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
- | --dataroo | --dataro | --datar)
- ac_prev=datarootdir ;;
- -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
- | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
- datarootdir=$ac_optarg ;;
-
- -disable-* | --disable-*)
- ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error "invalid feature name: $ac_useropt"
- ac_useropt_orig=$ac_useropt
- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
- case $ac_user_opts in
- *"
-"enable_$ac_useropt"
-"*) ;;
- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
- ac_unrecognized_sep=', ';;
- esac
- eval enable_$ac_useropt=no ;;
-
- -docdir | --docdir | --docdi | --doc | --do)
- ac_prev=docdir ;;
- -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
- docdir=$ac_optarg ;;
-
- -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
- ac_prev=dvidir ;;
- -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
- dvidir=$ac_optarg ;;
-
- -enable-* | --enable-*)
- ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error "invalid feature name: $ac_useropt"
- ac_useropt_orig=$ac_useropt
- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
- case $ac_user_opts in
- *"
-"enable_$ac_useropt"
-"*) ;;
- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
- ac_unrecognized_sep=', ';;
- esac
- eval enable_$ac_useropt=\$ac_optarg ;;
-
- -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
- | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
- | --exec | --exe | --ex)
- ac_prev=exec_prefix ;;
- -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
- | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
- | --exec=* | --exe=* | --ex=*)
- exec_prefix=$ac_optarg ;;
-
- -gas | --gas | --ga | --g)
- # Obsolete; use --with-gas.
- with_gas=yes ;;
-
- -help | --help | --hel | --he | -h)
- ac_init_help=long ;;
- -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
- ac_init_help=recursive ;;
- -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
- ac_init_help=short ;;
-
- -host | --host | --hos | --ho)
- ac_prev=host_alias ;;
- -host=* | --host=* | --hos=* | --ho=*)
- host_alias=$ac_optarg ;;
-
- -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
- ac_prev=htmldir ;;
- -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
- | --ht=*)
- htmldir=$ac_optarg ;;
-
- -includedir | --includedir | --includedi | --included | --include \
- | --includ | --inclu | --incl | --inc)
- ac_prev=includedir ;;
- -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
- | --includ=* | --inclu=* | --incl=* | --inc=*)
- includedir=$ac_optarg ;;
-
- -infodir | --infodir | --infodi | --infod | --info | --inf)
- ac_prev=infodir ;;
- -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
- infodir=$ac_optarg ;;
-
- -libdir | --libdir | --libdi | --libd)
- ac_prev=libdir ;;
- -libdir=* | --libdir=* | --libdi=* | --libd=*)
- libdir=$ac_optarg ;;
-
- -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
- | --libexe | --libex | --libe)
- ac_prev=libexecdir ;;
- -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
- | --libexe=* | --libex=* | --libe=*)
- libexecdir=$ac_optarg ;;
-
- -localedir | --localedir | --localedi | --localed | --locale)
- ac_prev=localedir ;;
- -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
- localedir=$ac_optarg ;;
-
- -localstatedir | --localstatedir | --localstatedi | --localstated \
- | --localstate | --localstat | --localsta | --localst | --locals)
- ac_prev=localstatedir ;;
- -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
- | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
- localstatedir=$ac_optarg ;;
-
- -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
- ac_prev=mandir ;;
- -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
- mandir=$ac_optarg ;;
-
- -nfp | --nfp | --nf)
- # Obsolete; use --without-fp.
- with_fp=no ;;
-
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c | -n)
- no_create=yes ;;
-
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
- no_recursion=yes ;;
-
- -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
- | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
- | --oldin | --oldi | --old | --ol | --o)
- ac_prev=oldincludedir ;;
- -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
- | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
- | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
- oldincludedir=$ac_optarg ;;
-
- -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
- ac_prev=prefix ;;
- -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
- prefix=$ac_optarg ;;
-
- -program-prefix | --program-prefix | --program-prefi | --program-pref \
- | --program-pre | --program-pr | --program-p)
- ac_prev=program_prefix ;;
- -program-prefix=* | --program-prefix=* | --program-prefi=* \
- | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
- program_prefix=$ac_optarg ;;
-
- -program-suffix | --program-suffix | --program-suffi | --program-suff \
- | --program-suf | --program-su | --program-s)
- ac_prev=program_suffix ;;
- -program-suffix=* | --program-suffix=* | --program-suffi=* \
- | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
- program_suffix=$ac_optarg ;;
-
- -program-transform-name | --program-transform-name \
- | --program-transform-nam | --program-transform-na \
- | --program-transform-n | --program-transform- \
- | --program-transform | --program-transfor \
- | --program-transfo | --program-transf \
- | --program-trans | --program-tran \
- | --progr-tra | --program-tr | --program-t)
- ac_prev=program_transform_name ;;
- -program-transform-name=* | --program-transform-name=* \
- | --program-transform-nam=* | --program-transform-na=* \
- | --program-transform-n=* | --program-transform-=* \
- | --program-transform=* | --program-transfor=* \
- | --program-transfo=* | --program-transf=* \
- | --program-trans=* | --program-tran=* \
- | --progr-tra=* | --program-tr=* | --program-t=*)
- program_transform_name=$ac_optarg ;;
-
- -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
- ac_prev=pdfdir ;;
- -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
- pdfdir=$ac_optarg ;;
-
- -psdir | --psdir | --psdi | --psd | --ps)
- ac_prev=psdir ;;
- -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
- psdir=$ac_optarg ;;
-
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- silent=yes ;;
-
- -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
- ac_prev=sbindir ;;
- -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
- | --sbi=* | --sb=*)
- sbindir=$ac_optarg ;;
-
- -sharedstatedir | --sharedstatedir | --sharedstatedi \
- | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
- | --sharedst | --shareds | --shared | --share | --shar \
- | --sha | --sh)
- ac_prev=sharedstatedir ;;
- -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
- | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
- | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
- | --sha=* | --sh=*)
- sharedstatedir=$ac_optarg ;;
-
- -site | --site | --sit)
- ac_prev=site ;;
- -site=* | --site=* | --sit=*)
- site=$ac_optarg ;;
-
- -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
- ac_prev=srcdir ;;
- -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
- srcdir=$ac_optarg ;;
-
- -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
- | --syscon | --sysco | --sysc | --sys | --sy)
- ac_prev=sysconfdir ;;
- -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
- | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
- sysconfdir=$ac_optarg ;;
-
- -target | --target | --targe | --targ | --tar | --ta | --t)
- ac_prev=target_alias ;;
- -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
- target_alias=$ac_optarg ;;
-
- -v | -verbose | --verbose | --verbos | --verbo | --verb)
- verbose=yes ;;
-
- -version | --version | --versio | --versi | --vers | -V)
- ac_init_version=: ;;
-
- -with-* | --with-*)
- ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error "invalid package name: $ac_useropt"
- ac_useropt_orig=$ac_useropt
- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
- case $ac_user_opts in
- *"
-"with_$ac_useropt"
-"*) ;;
- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
- ac_unrecognized_sep=', ';;
- esac
- eval with_$ac_useropt=\$ac_optarg ;;
-
- -without-* | --without-*)
- ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error "invalid package name: $ac_useropt"
- ac_useropt_orig=$ac_useropt
- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
- case $ac_user_opts in
- *"
-"with_$ac_useropt"
-"*) ;;
- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
- ac_unrecognized_sep=', ';;
- esac
- eval with_$ac_useropt=no ;;
-
- --x)
- # Obsolete; use --with-x.
- with_x=yes ;;
-
- -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
- | --x-incl | --x-inc | --x-in | --x-i)
- ac_prev=x_includes ;;
- -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
- | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
- x_includes=$ac_optarg ;;
-
- -x-libraries | --x-libraries | --x-librarie | --x-librari \
- | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
- ac_prev=x_libraries ;;
- -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
- | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
- x_libraries=$ac_optarg ;;
-
- -*) as_fn_error "unrecognized option: \`$ac_option'
-Try \`$0 --help' for more information."
- ;;
-
- *=*)
- ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
- # Reject names that are not valid shell variable names.
- case $ac_envvar in #(
- '' | [0-9]* | *[!_$as_cr_alnum]* )
- as_fn_error "invalid variable name: \`$ac_envvar'" ;;
- esac
- eval $ac_envvar=\$ac_optarg
- export $ac_envvar ;;
-
- *)
- # FIXME: should be removed in autoconf 3.0.
- $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
- expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
- $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
- : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
- ;;
-
- esac
-done
-
-if test -n "$ac_prev"; then
- ac_option=--`echo $ac_prev | sed 's/_/-/g'`
- as_fn_error "missing argument to $ac_option"
-fi
-
-if test -n "$ac_unrecognized_opts"; then
- case $enable_option_checking in
- no) ;;
- fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
- *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
- esac
-fi
-
-# Check all directory arguments for consistency.
-for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
- datadir sysconfdir sharedstatedir localstatedir includedir \
- oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
- libdir localedir mandir
-do
- eval ac_val=\$$ac_var
- # Remove trailing slashes.
- case $ac_val in
- */ )
- ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
- eval $ac_var=\$ac_val;;
- esac
- # Be sure to have absolute directory names.
- case $ac_val in
- [\\/$]* | ?:[\\/]* ) continue;;
- NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
- esac
- as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
-done
-
-# There might be people who depend on the old broken behavior: `$host'
-# used to hold the argument of --host etc.
-# FIXME: To remove some day.
-build=$build_alias
-host=$host_alias
-target=$target_alias
-
-# FIXME: To remove some day.
-if test "x$host_alias" != x; then
- if test "x$build_alias" = x; then
- cross_compiling=maybe
- $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
- If a cross compiler is detected then cross compile mode will be used." >&2
- elif test "x$build_alias" != "x$host_alias"; then
- cross_compiling=yes
- fi
-fi
-
-ac_tool_prefix=
-test -n "$host_alias" && ac_tool_prefix=$host_alias-
-
-test "$silent" = yes && exec 6>/dev/null
-
-
-ac_pwd=`pwd` && test -n "$ac_pwd" &&
-ac_ls_di=`ls -di .` &&
-ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
- as_fn_error "working directory cannot be determined"
-test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
- as_fn_error "pwd does not report name of working directory"
-
-
-# Find the source files, if location was not specified.
-if test -z "$srcdir"; then
- ac_srcdir_defaulted=yes
- # Try the directory containing this script, then the parent directory.
- ac_confdir=`$as_dirname -- "$as_myself" ||
-$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_myself" : 'X\(//\)[^/]' \| \
- X"$as_myself" : 'X\(//\)$' \| \
- X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_myself" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- srcdir=$ac_confdir
- if test ! -r "$srcdir/$ac_unique_file"; then
- srcdir=..
- fi
-else
- ac_srcdir_defaulted=no
-fi
-if test ! -r "$srcdir/$ac_unique_file"; then
- test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
- as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
-fi
-ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
-ac_abs_confdir=`(
- cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
- pwd)`
-# When building in place, set srcdir=.
-if test "$ac_abs_confdir" = "$ac_pwd"; then
- srcdir=.
-fi
-# Remove unnecessary trailing slashes from srcdir.
-# Double slashes in file names in object file debugging info
-# mess up M-x gdb in Emacs.
-case $srcdir in
-*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
-esac
-for ac_var in $ac_precious_vars; do
- eval ac_env_${ac_var}_set=\${${ac_var}+set}
- eval ac_env_${ac_var}_value=\$${ac_var}
- eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
- eval ac_cv_env_${ac_var}_value=\$${ac_var}
-done
-
-#
-# Report the --help message.
-#
-if test "$ac_init_help" = "long"; then
- # Omit some internal or obsolete options to make the list less imposing.
- # This message is too long to be a string in the A/UX 3.1 sh.
- cat <<_ACEOF
-\`configure' configures this package to adapt to many kinds of systems.
-
-Usage: $0 [OPTION]... [VAR=VALUE]...
-
-To assign environment variables (e.g., CC, CFLAGS...), specify them as
-VAR=VALUE. See below for descriptions of some of the useful variables.
-
-Defaults for the options are specified in brackets.
-
-Configuration:
- -h, --help display this help and exit
- --help=short display options specific to this package
- --help=recursive display the short help of all the included packages
- -V, --version display version information and exit
- -q, --quiet, --silent do not print \`checking...' messages
- --cache-file=FILE cache test results in FILE [disabled]
- -C, --config-cache alias for \`--cache-file=config.cache'
- -n, --no-create do not create output files
- --srcdir=DIR find the sources in DIR [configure dir or \`..']
-
-Installation directories:
- --prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [PREFIX]
-
-By default, \`make install' will install all the files in
-\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
-an installation prefix other than \`$ac_default_prefix' using \`--prefix',
-for instance \`--prefix=\$HOME'.
-
-For better control, use the options below.
-
-Fine tuning of the installation directories:
- --bindir=DIR user executables [EPREFIX/bin]
- --sbindir=DIR system admin executables [EPREFIX/sbin]
- --libexecdir=DIR program executables [EPREFIX/libexec]
- --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
- --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
- --localstatedir=DIR modifiable single-machine data [PREFIX/var]
- --libdir=DIR object code libraries [EPREFIX/lib]
- --includedir=DIR C header files [PREFIX/include]
- --oldincludedir=DIR C header files for non-gcc [/usr/include]
- --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
- --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
- --infodir=DIR info documentation [DATAROOTDIR/info]
- --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
- --mandir=DIR man documentation [DATAROOTDIR/man]
- --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE]
- --htmldir=DIR html documentation [DOCDIR]
- --dvidir=DIR dvi documentation [DOCDIR]
- --pdfdir=DIR pdf documentation [DOCDIR]
- --psdir=DIR ps documentation [DOCDIR]
-_ACEOF
-
- cat <<\_ACEOF
-
-Program names:
- --program-prefix=PREFIX prepend PREFIX to installed program names
- --program-suffix=SUFFIX append SUFFIX to installed program names
- --program-transform-name=PROGRAM run sed PROGRAM on installed program names
-
-System types:
- --build=BUILD configure for building on BUILD [guessed]
- --host=HOST cross-compile to build programs to run on HOST [BUILD]
- --target=TARGET configure for building compilers for TARGET [HOST]
-_ACEOF
-fi
-
-if test -n "$ac_init_help"; then
-
- cat <<\_ACEOF
-
-Optional Features:
- --disable-option-checking ignore unrecognized --enable/--with options
- --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
- --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --enable-generated-files-in-srcdir
- put copies of generated files in source dir intended
- for creating source tarballs for users without
- texinfo bison or flex
- --disable-largefile omit support for large files
- --enable-werror-always enable -Werror despite compiler version
- --enable-checking[=LIST]
- enable expensive run-time checks. With LIST, enable
- only specific categories of checks. Categories are:
- yes,no,all,none,release. Flags are:
- assert,df,fold,gc,gcac,gimple,misc,
- rtlflag,rtl,runtime,tree,valgrind,types
- --enable-coverage[=LEVEL]
- enable compiler's code coverage collection. Use to
- measure compiler performance and locate unused parts
- of the compiler. With LEVEL, specify optimization.
- Values are opt, noopt, default is noopt
- --enable-gather-detailed-mem-stats
- enable detailed memory allocation stats gathering
- --enable-multilib enable library support for multiple ABIs
- --enable-multiarch enable support for multiarch paths
- --enable-__cxa_atexit enable __cxa_atexit for C++
- --enable-decimal-float={no,yes,bid,dpd}
- enable decimal float extension to C. Selecting 'bid'
- or 'dpd' choses which decimal floating point format
- to use
- --enable-fixed-point enable fixed-point arithmetic extension to C
- --enable-threads[=LIB] enable thread usage for target GCC, using LIB thread
- package
- --enable-tls enable or disable generation of tls code overriding
- the assembler check for tls support
- --enable-objc-gc enable the use of Boehm's garbage collector with the
- GNU Objective-C runtime
- --disable-shared don't provide a shared libgcc
- --enable-languages=LIST specify which front-ends to build
- --disable-rpath do not hardcode runtime library paths
- --enable-sjlj-exceptions
- arrange to use setjmp/longjmp exception handling
- --enable-secureplt enable -msecure-plt by default for PowerPC
- --enable-leading-mingw64-underscores
- enable leading underscores on 64 bit mingw targets
- --enable-cld enable -mcld by default for 32bit x86
- --enable-frame-pointer enable -fno-omit-frame-pointer by default for 32bit
- x86
- --disable-win32-registry
- disable lookup of installation paths in the Registry
- on Windows hosts
- --enable-win32-registry enable registry lookup (default)
- --enable-win32-registry=KEY
- use KEY instead of GCC version as the last portion
- of the registry key
- --enable-shared[=PKGS] build shared libraries [default=yes]
- --enable-static[=PKGS] build static libraries [default=yes]
- --enable-fast-install[=PKGS]
- optimize for fast installation [default=yes]
- --disable-libtool-lock avoid locking (might break parallel builds)
- --enable-gnu-indirect-function
- enable the use of the @gnu_indirect_function to
- glibc systems
- --enable-initfini-array use .init_array/.fini_array sections
- --enable-comdat enable COMDAT group support
- --enable-gnu-unique-object
- enable the use of the @gnu_unique_object ELF
- extension on glibc systems
- --enable-eh-frame-hdr-for-static
- enable linker PT_GNU_EH_FRAME support for static
- executable
- --enable-linker-build-id
- compiler will always pass --build-id to linker
- --enable-maintainer-mode
- enable make rules and dependencies not useful (and
- sometimes confusing) to the casual installer
- --enable-version-specific-runtime-libs
- specify that runtime libraries should be installed
- in a compiler-specific directory
- --enable-plugin enable plugin support
- --disable-libquadmath-support
- disable libquadmath support for Fortran
-
-Optional Packages:
- --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
- --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
- --with-build-libsubdir=DIR Directory where to find libraries for build system
- --with-local-prefix=DIR specifies directory to put local include
- --with-gxx-include-dir=DIR
- specifies directory to put g++ header files
- --with-cpp-install-dir=DIR
- install the user visible C preprocessor in DIR
- (relative to PREFIX) as well as PREFIX/bin
- --with-gnu-ld arrange to work with GNU ld
- --with-ld arrange to use the specified ld (full pathname)
- --with-demangler-in-ld try to use demangler in GNU ld
- --with-gnu-as arrange to work with GNU as
- --with-as arrange to use the specified as (full pathname)
- --with-stabs arrange to use stabs instead of host debug format
- --with-dwarf2 force the default debug format to be DWARF 2
- --with-native-system-header-dir=dir
- use dir as the directory to look for standard
- system header files in. Defaults to /usr/include.
- --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-pkgversion=PKG Use PKG in the version string in place of "GCC"
- --with-bugurl=URL Direct users to URL to report a bug
- --with-multilib-list select multilibs (SH and x86-64 only)
- --with-gnu-ld assume the C compiler uses GNU ld default=no
- --with-libiconv-prefix[=DIR] search for libiconv in DIR/include and DIR/lib
- --without-libiconv-prefix don't search for libiconv in includedir and libdir
- --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]
- --with-plugin-ld=[ARG] specify the plugin linker
- --with-long-double-128 use 128-bit long double by default
- --with-gc={page,zone} this option is not supported anymore. It used to
- choose the garbage collection mechanism to use with
- the compiler
- --with-system-zlib use installed libz
- --with-linker-hash-style={sysv,gnu,both}
- specify the linker hash style
-
-Some influential environment variables:
- CC C compiler command
- CFLAGS C compiler flags
- LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
- nonstandard directory <lib dir>
- LIBS libraries to pass to the linker, e.g. -l<library>
- CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
- you have headers in a nonstandard directory <include dir>
- CXX C++ compiler command
- CXXFLAGS C++ compiler flags
- CPP C preprocessor
- CXXCPP C++ preprocessor
- GMPLIBS How to link GMP
- GMPINC How to find GMP include files
- ISLLIBS How to link ISL
- ISLINC How to find ISL include files
- CLOOGLIBS How to link CLOOG
- CLOOGINC How to find CLOOG include files
-
-Use these variables to override the choices made by `configure' or to help
-it to find libraries and programs with nonstandard names/locations.
-
-Report bugs to the package provider.
-_ACEOF
-ac_status=$?
-fi
-
-if test "$ac_init_help" = "recursive"; then
- # If there are subdirs, report their specific --help.
- for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
- test -d "$ac_dir" ||
- { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
- continue
- ac_builddir=.
-
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
- ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
- # A ".." for each directory in $ac_dir_suffix.
- ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
- case $ac_top_builddir_sub in
- "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
- *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
- esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
-
-case $srcdir in
- .) # We are building in place.
- ac_srcdir=.
- ac_top_srcdir=$ac_top_builddir_sub
- ac_abs_top_srcdir=$ac_pwd ;;
- [\\/]* | ?:[\\/]* ) # Absolute name.
- ac_srcdir=$srcdir$ac_dir_suffix;
- ac_top_srcdir=$srcdir
- ac_abs_top_srcdir=$srcdir ;;
- *) # Relative name.
- ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
- ac_top_srcdir=$ac_top_build_prefix$srcdir
- ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
-esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
- cd "$ac_dir" || { ac_status=$?; continue; }
- # Check for guested configure.
- if test -f "$ac_srcdir/configure.gnu"; then
- echo &&
- $SHELL "$ac_srcdir/configure.gnu" --help=recursive
- elif test -f "$ac_srcdir/configure"; then
- echo &&
- $SHELL "$ac_srcdir/configure" --help=recursive
- else
- $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
- fi || ac_status=$?
- cd "$ac_pwd" || { ac_status=$?; break; }
- done
-fi
-
-test -n "$ac_init_help" && exit $ac_status
-if $ac_init_version; then
- cat <<\_ACEOF
-configure
-generated by GNU Autoconf 2.64
-
-Copyright (C) 2009 Free Software Foundation, Inc.
-This configure script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it.
-_ACEOF
- exit
-fi
-
-## ------------------------ ##
-## Autoconf initialization. ##
-## ------------------------ ##
-
-# ac_fn_c_try_compile LINENO
-# --------------------------
-# Try to compile conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_compile ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext
- if { { ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compile") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- return $ac_retval
-
-} # ac_fn_c_try_compile
-
-# ac_fn_cxx_try_compile LINENO
-# ----------------------------
-# Try to compile conftest.$ac_ext, and return whether this succeeded.
-ac_fn_cxx_try_compile ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext
- if { { ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compile") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- return $ac_retval
-
-} # ac_fn_cxx_try_compile
-
-# ac_fn_c_try_cpp LINENO
-# ----------------------
-# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_cpp ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- if { { ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- return $ac_retval
-
-} # ac_fn_c_try_cpp
-
-# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists, giving a warning if it cannot be compiled using
-# the include files in INCLUDES and setting the cache variable VAR
-# accordingly.
-ac_fn_c_check_header_mongrel ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-else
- # Is the header compilable?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
-$as_echo_n "checking $2 usability... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_header_compiler=yes
-else
- ac_header_compiler=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
-$as_echo "$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
-$as_echo_n "checking $2 presence... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <$2>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
- ac_header_preproc=yes
-else
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
-$as_echo "$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
- yes:no: )
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
-$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
- ;;
- no:yes:* )
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
-$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
-$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
-$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
-$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
- ;;
-esac
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- eval "$3=\$ac_header_compiler"
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-
-} # ac_fn_c_check_header_mongrel
-
-# ac_fn_c_try_run LINENO
-# ----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
-# that executables *can* be run.
-ac_fn_c_try_run ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- if { { ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
- { { case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }; then :
- ac_retval=0
-else
- $as_echo "$as_me: program exited with status $ac_status" >&5
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=$ac_status
-fi
- rm -rf conftest.dSYM conftest_ipa8_conftest.oo
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- return $ac_retval
-
-} # ac_fn_c_try_run
-
-# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists and can be compiled using the include files in
-# INCLUDES, setting the cache variable VAR accordingly.
-ac_fn_c_check_header_compile ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- eval "$3=yes"
-else
- eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-
-} # ac_fn_c_check_header_compile
-
-# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
-# --------------------------------------------
-# Tries to find the compile-time value of EXPR in a program that includes
-# INCLUDES, setting VAR accordingly. Returns whether the value could be
-# computed
-ac_fn_c_compute_int ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- if test "$cross_compiling" = yes; then
- # Depending upon the size, compute the lo and hi bounds.
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-int
-main ()
-{
-static int test_array [1 - 2 * !(($2) >= 0)];
-test_array [0] = 0
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_lo=0 ac_mid=0
- while :; do
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-int
-main ()
-{
-static int test_array [1 - 2 * !(($2) <= $ac_mid)];
-test_array [0] = 0
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_hi=$ac_mid; break
-else
- as_fn_arith $ac_mid + 1 && ac_lo=$as_val
- if test $ac_lo -le $ac_mid; then
- ac_lo= ac_hi=
- break
- fi
- as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- done
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-int
-main ()
-{
-static int test_array [1 - 2 * !(($2) < 0)];
-test_array [0] = 0
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_hi=-1 ac_mid=-1
- while :; do
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-int
-main ()
-{
-static int test_array [1 - 2 * !(($2) >= $ac_mid)];
-test_array [0] = 0
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_lo=$ac_mid; break
-else
- as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
- if test $ac_mid -le $ac_hi; then
- ac_lo= ac_hi=
- break
- fi
- as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- done
-else
- ac_lo= ac_hi=
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-# Binary search between lo and hi bounds.
-while test "x$ac_lo" != "x$ac_hi"; do
- as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-int
-main ()
-{
-static int test_array [1 - 2 * !(($2) <= $ac_mid)];
-test_array [0] = 0
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_hi=$ac_mid
-else
- as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-done
-case $ac_lo in #((
-?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
-'') ac_retval=1 ;;
-esac
- else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-static long int longval () { return $2; }
-static unsigned long int ulongval () { return $2; }
-#include <stdio.h>
-#include <stdlib.h>
-int
-main ()
-{
-
- FILE *f = fopen ("conftest.val", "w");
- if (! f)
- return 1;
- if (($2) < 0)
- {
- long int i = longval ();
- if (i != ($2))
- return 1;
- fprintf (f, "%ld", i);
- }
- else
- {
- unsigned long int i = ulongval ();
- if (i != ($2))
- return 1;
- fprintf (f, "%lu", i);
- }
- /* Do not output a trailing newline, as this causes \r\n confusion
- on some platforms. */
- return ferror (f) || fclose (f) != 0;
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
- echo >>conftest.val; read $3 <conftest.val; ac_retval=0
-else
- ac_retval=1
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-rm -f conftest.val
-
- fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- return $ac_retval
-
-} # ac_fn_c_compute_int
-
-# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
-# -------------------------------------------
-# Tests whether TYPE exists after having included INCLUDES, setting cache
-# variable VAR accordingly.
-ac_fn_c_check_type ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- eval "$3=no"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-int
-main ()
-{
-if (sizeof ($2))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-int
-main ()
-{
-if (sizeof (($2)))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
- eval "$3=yes"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-
-} # ac_fn_c_check_type
-
-# ac_fn_c_find_intX_t LINENO BITS VAR
-# -----------------------------------
-# Finds a signed integer type with width BITS, setting cache variable VAR
-# accordingly.
-ac_fn_c_find_intX_t ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5
-$as_echo_n "checking for int$2_t... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- eval "$3=no"
- for ac_type in int$2_t 'int' 'long int' \
- 'long long int' 'short int' 'signed char'; do
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-static int test_array [1 - 2 * !(0 < ($ac_type) (((($ac_type) 1 << ($2 - 2)) - 1) * 2 + 1))];
-test_array [0] = 0
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-static int test_array [1 - 2 * !(($ac_type) (((($ac_type) 1 << ($2 - 2)) - 1) * 2 + 1)
- < ($ac_type) (((($ac_type) 1 << ($2 - 2)) - 1) * 2 + 2))];
-test_array [0] = 0
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
- case $ac_type in #(
- int$2_t) :
- eval "$3=yes" ;; #(
- *) :
- eval "$3=\$ac_type" ;;
-esac
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- eval as_val=\$$3
- if test "x$as_val" = x""no; then :
-
-else
- break
-fi
- done
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-
-} # ac_fn_c_find_intX_t
-
-# ac_fn_c_try_link LINENO
-# -----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_link ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext conftest$ac_exeext
- if { { ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext && {
- test "$cross_compiling" = yes ||
- $as_test_x conftest$ac_exeext
- }; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
- # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
- # interfere with the next link command; also delete a directory that is
- # left behind by Apple's compiler. We do this before executing the actions.
- rm -rf conftest.dSYM conftest_ipa8_conftest.oo
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- return $ac_retval
-
-} # ac_fn_c_try_link
-
-# ac_fn_c_find_uintX_t LINENO BITS VAR
-# ------------------------------------
-# Finds an unsigned integer type with width BITS, setting cache variable VAR
-# accordingly.
-ac_fn_c_find_uintX_t ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5
-$as_echo_n "checking for uint$2_t... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- eval "$3=no"
- for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \
- 'unsigned long long int' 'unsigned short int' 'unsigned char'; do
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-static int test_array [1 - 2 * !(($ac_type) -1 >> ($2 - 1) == 1)];
-test_array [0] = 0
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- case $ac_type in #(
- uint$2_t) :
- eval "$3=yes" ;; #(
- *) :
- eval "$3=\$ac_type" ;;
-esac
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- eval as_val=\$$3
- if test "x$as_val" = x""no; then :
-
-else
- break
-fi
- done
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-
-} # ac_fn_c_find_uintX_t
-
-# ac_fn_c_check_header_preproc LINENO HEADER VAR
-# ----------------------------------------------
-# Tests whether HEADER is present, setting the cache variable VAR accordingly.
-ac_fn_c_check_header_preproc ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <$2>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
- eval "$3=yes"
-else
- eval "$3=no"
-fi
-rm -f conftest.err conftest.$ac_ext
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-
-} # ac_fn_c_check_header_preproc
-
-# ac_fn_cxx_try_cpp LINENO
-# ------------------------
-# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
-ac_fn_cxx_try_cpp ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- if { { ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } >/dev/null && {
- test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- }; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- return $ac_retval
-
-} # ac_fn_cxx_try_cpp
-
-# ac_fn_cxx_check_header_preproc LINENO HEADER VAR
-# ------------------------------------------------
-# Tests whether HEADER is present, setting the cache variable VAR accordingly.
-ac_fn_cxx_check_header_preproc ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <$2>
-_ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
- eval "$3=yes"
-else
- eval "$3=no"
-fi
-rm -f conftest.err conftest.$ac_ext
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-
-} # ac_fn_cxx_check_header_preproc
-
-# ac_fn_c_check_func LINENO FUNC VAR
-# ----------------------------------
-# Tests whether FUNC exists, setting the cache variable VAR accordingly
-ac_fn_c_check_func ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $2 innocuous_$2
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $2 (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $2
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $2 ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined __stub_$2 || defined __stub___$2
-choke me
-#endif
-
-int
-main ()
-{
-return $2 ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- eval "$3=yes"
-else
- eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-
-} # ac_fn_c_check_func
-
-# ac_fn_cxx_try_link LINENO
-# -------------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded.
-ac_fn_cxx_try_link ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext conftest$ac_exeext
- if { { ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext && {
- test "$cross_compiling" = yes ||
- $as_test_x conftest$ac_exeext
- }; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
- # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
- # interfere with the next link command; also delete a directory that is
- # left behind by Apple's compiler. We do this before executing the actions.
- rm -rf conftest.dSYM conftest_ipa8_conftest.oo
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- return $ac_retval
-
-} # ac_fn_cxx_try_link
-cat >config.log <<_ACEOF
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-
-It was created by $as_me, which was
-generated by GNU Autoconf 2.64. Invocation command line was
-
- $ $0 $@
-
-_ACEOF
-exec 5>>config.log
-{
-cat <<_ASUNAME
-## --------- ##
-## Platform. ##
-## --------- ##
-
-hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
-
-/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
-/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
-/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
-/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
-
-_ASUNAME
-
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- $as_echo "PATH: $as_dir"
- done
-IFS=$as_save_IFS
-
-} >&5
-
-cat >&5 <<_ACEOF
-
-
-## ----------- ##
-## Core tests. ##
-## ----------- ##
-
-_ACEOF
-
-
-# Keep a trace of the command line.
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Strip out --silent because we don't want to record it for future runs.
-# Also quote any args containing shell meta-characters.
-# Make two passes to allow for proper duplicate-argument suppression.
-ac_configure_args=
-ac_configure_args0=
-ac_configure_args1=
-ac_must_keep_next=false
-for ac_pass in 1 2
-do
- for ac_arg
- do
- case $ac_arg in
- -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- continue ;;
- *\'*)
- ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
- esac
- case $ac_pass in
- 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
- 2)
- as_fn_append ac_configure_args1 " '$ac_arg'"
- if test $ac_must_keep_next = true; then
- ac_must_keep_next=false # Got value, back to normal.
- else
- case $ac_arg in
- *=* | --config-cache | -C | -disable-* | --disable-* \
- | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
- | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
- | -with-* | --with-* | -without-* | --without-* | --x)
- case "$ac_configure_args0 " in
- "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
- esac
- ;;
- -* ) ac_must_keep_next=true ;;
- esac
- fi
- as_fn_append ac_configure_args " '$ac_arg'"
- ;;
- esac
- done
-done
-{ ac_configure_args0=; unset ac_configure_args0;}
-{ ac_configure_args1=; unset ac_configure_args1;}
-
-# When interrupted or exit'd, cleanup temporary files, and complete
-# config.log. We remove comments because anyway the quotes in there
-# would cause problems or look ugly.
-# WARNING: Use '\'' to represent an apostrophe within the trap.
-# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
-trap 'exit_status=$?
- # Save into config.log some information that might help in debugging.
- {
- echo
-
- cat <<\_ASBOX
-## ---------------- ##
-## Cache variables. ##
-## ---------------- ##
-_ASBOX
- echo
- # The following way of writing the cache mishandles newlines in values,
-(
- for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
- eval ac_val=\$$ac_var
- case $ac_val in #(
- *${as_nl}*)
- case $ac_var in #(
- *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
- esac
- case $ac_var in #(
- _ | IFS | as_nl) ;; #(
- BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
- *) { eval $ac_var=; unset $ac_var;} ;;
- esac ;;
- esac
- done
- (set) 2>&1 |
- case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
- *${as_nl}ac_space=\ *)
- sed -n \
- "s/'\''/'\''\\\\'\'''\''/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
- ;; #(
- *)
- sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
- ;;
- esac |
- sort
-)
- echo
-
- cat <<\_ASBOX
-## ----------------- ##
-## Output variables. ##
-## ----------------- ##
-_ASBOX
- echo
- for ac_var in $ac_subst_vars
- do
- eval ac_val=\$$ac_var
- case $ac_val in
- *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
- esac
- $as_echo "$ac_var='\''$ac_val'\''"
- done | sort
- echo
-
- if test -n "$ac_subst_files"; then
- cat <<\_ASBOX
-## ------------------- ##
-## File substitutions. ##
-## ------------------- ##
-_ASBOX
- echo
- for ac_var in $ac_subst_files
- do
- eval ac_val=\$$ac_var
- case $ac_val in
- *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
- esac
- $as_echo "$ac_var='\''$ac_val'\''"
- done | sort
- echo
- fi
-
- if test -s confdefs.h; then
- cat <<\_ASBOX
-## ----------- ##
-## confdefs.h. ##
-## ----------- ##
-_ASBOX
- echo
- cat confdefs.h
- echo
- fi
- test "$ac_signal" != 0 &&
- $as_echo "$as_me: caught signal $ac_signal"
- $as_echo "$as_me: exit $exit_status"
- } >&5
- rm -f core *.core core.conftest.* &&
- rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
- exit $exit_status
-' 0
-for ac_signal in 1 2 13 15; do
- trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
-done
-ac_signal=0
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -f -r conftest* confdefs.h
-
-$as_echo "/* confdefs.h */" > confdefs.h
-
-# Predefined preprocessor variables.
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_NAME "$PACKAGE_NAME"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_VERSION "$PACKAGE_VERSION"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_STRING "$PACKAGE_STRING"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_URL "$PACKAGE_URL"
-_ACEOF
-
-
-# Let the site file select an alternate cache file if it wants to.
-# Prefer an explicitly selected file to automatically selected ones.
-ac_site_file1=NONE
-ac_site_file2=NONE
-if test -n "$CONFIG_SITE"; then
- ac_site_file1=$CONFIG_SITE
-elif test "x$prefix" != xNONE; then
- ac_site_file1=$prefix/share/config.site
- ac_site_file2=$prefix/etc/config.site
-else
- ac_site_file1=$ac_default_prefix/share/config.site
- ac_site_file2=$ac_default_prefix/etc/config.site
-fi
-for ac_site_file in "$ac_site_file1" "$ac_site_file2"
-do
- test "x$ac_site_file" = xNONE && continue
- if test -r "$ac_site_file"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
-$as_echo "$as_me: loading site script $ac_site_file" >&6;}
- sed 's/^/| /' "$ac_site_file" >&5
- . "$ac_site_file"
- fi
-done
-
-if test -r "$cache_file"; then
- # Some versions of bash will fail to source /dev/null (special
- # files actually), so we avoid doing that.
- if test -f "$cache_file"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
-$as_echo "$as_me: loading cache $cache_file" >&6;}
- case $cache_file in
- [\\/]* | ?:[\\/]* ) . "$cache_file";;
- *) . "./$cache_file";;
- esac
- fi
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
-$as_echo "$as_me: creating cache $cache_file" >&6;}
- >$cache_file
-fi
-
-# Check that the precious variables saved in the cache have kept the same
-# value.
-ac_cache_corrupted=false
-for ac_var in $ac_precious_vars; do
- eval ac_old_set=\$ac_cv_env_${ac_var}_set
- eval ac_new_set=\$ac_env_${ac_var}_set
- eval ac_old_val=\$ac_cv_env_${ac_var}_value
- eval ac_new_val=\$ac_env_${ac_var}_value
- case $ac_old_set,$ac_new_set in
- set,)
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
- ac_cache_corrupted=: ;;
- ,set)
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
- ac_cache_corrupted=: ;;
- ,);;
- *)
- if test "x$ac_old_val" != "x$ac_new_val"; then
- # differences in whitespace do not lead to failure.
- ac_old_val_w=`echo x $ac_old_val`
- ac_new_val_w=`echo x $ac_new_val`
- if test "$ac_old_val_w" != "$ac_new_val_w"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
-$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
- ac_cache_corrupted=:
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
-$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
- eval $ac_var=\$ac_old_val
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
-$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
-$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
- fi;;
- esac
- # Pass precious variables to config.status.
- if test "$ac_new_set" = set; then
- case $ac_new_val in
- *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
- *) ac_arg=$ac_var=$ac_new_val ;;
- esac
- case " $ac_configure_args " in
- *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
- *) as_fn_append ac_configure_args " '$ac_arg'" ;;
- esac
- fi
-done
-if $ac_cache_corrupted; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
-$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
- as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
-fi
-## -------------------- ##
-## Main body of script. ##
-## -------------------- ##
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-
-
-
-ac_config_headers="$ac_config_headers auto-host.h:config.in"
-
-
-gcc_version=`cat $srcdir/BASE-VER`
-
-# Determine the host, build, and target systems
-ac_aux_dir=
-for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
- for ac_t in install-sh install.sh shtool; do
- if test -f "$ac_dir/$ac_t"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/$ac_t -c"
- break 2
- fi
- done
-done
-if test -z "$ac_aux_dir"; then
- as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
-fi
-
-# These three variables are undocumented and unsupported,
-# and are intended to be withdrawn in a future Autoconf release.
-# They can cause serious problems if a builder's source tree is in a directory
-# whose full name contains unusual characters.
-ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
-ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
-ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
-
-
-# Make sure we can run config.sub.
-$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
- as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
-$as_echo_n "checking build system type... " >&6; }
-if test "${ac_cv_build+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_build_alias=$build_alias
-test "x$ac_build_alias" = x &&
- ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
-test "x$ac_build_alias" = x &&
- as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5
-ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
- as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
-$as_echo "$ac_cv_build" >&6; }
-case $ac_cv_build in
-*-*-*) ;;
-*) as_fn_error "invalid value of canonical build" "$LINENO" 5;;
-esac
-build=$ac_cv_build
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_build
-shift
-build_cpu=$1
-build_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-build_os=$*
-IFS=$ac_save_IFS
-case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
-$as_echo_n "checking host system type... " >&6; }
-if test "${ac_cv_host+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test "x$host_alias" = x; then
- ac_cv_host=$ac_cv_build
-else
- ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
- as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
-$as_echo "$ac_cv_host" >&6; }
-case $ac_cv_host in
-*-*-*) ;;
-*) as_fn_error "invalid value of canonical host" "$LINENO" 5;;
-esac
-host=$ac_cv_host
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_host
-shift
-host_cpu=$1
-host_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-host_os=$*
-IFS=$ac_save_IFS
-case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
-$as_echo_n "checking target system type... " >&6; }
-if test "${ac_cv_target+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test "x$target_alias" = x; then
- ac_cv_target=$ac_cv_host
-else
- ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` ||
- as_fn_error "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5
-$as_echo "$ac_cv_target" >&6; }
-case $ac_cv_target in
-*-*-*) ;;
-*) as_fn_error "invalid value of canonical target" "$LINENO" 5;;
-esac
-target=$ac_cv_target
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_target
-shift
-target_cpu=$1
-target_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-target_os=$*
-IFS=$ac_save_IFS
-case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac
-
-
-# The aliases save the names the user supplied, while $host etc.
-# will get canonicalized.
-test -n "$target_alias" &&
- test "$program_prefix$program_suffix$program_transform_name" = \
- NONENONEs,x,x, &&
- program_prefix=${target_alias}-
-
-# Determine the noncanonical target name, for directory use.
- case ${build_alias} in
- "") build_noncanonical=${build} ;;
- *) build_noncanonical=${build_alias} ;;
-esac
-
- 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
-
-
-
-
-# Determine the target- and build-specific subdirectories
-
-# post-stage1 host modules use a different CC_FOR_BUILD so, in order to
-# have matching libraries, they should use host libraries: Makefile.tpl
-# arranges to pass --with-build-libsubdir=$(HOST_SUBDIR).
-# However, they still use the build modules, because the corresponding
-# host modules (e.g. bison) are only built for the host when bootstrap
-# finishes. So:
-# - build_subdir is where we find build modules, and never changes.
-# - build_libsubdir is where we find build libraries, and can be overridden.
-
-# Prefix 'build-' so this never conflicts with target_subdir.
-build_subdir="build-${build_noncanonical}"
-
-# Check whether --with-build-libsubdir was given.
-if test "${with_build_libsubdir+set}" = set; then :
- withval=$with_build_libsubdir; build_libsubdir="$withval"
-else
- build_libsubdir="$build_subdir"
-fi
-
-# --srcdir=. covers the toplevel, while "test -d" covers the subdirectories
-if ( test $srcdir = . && test -d gcc ) \
- || test -d $srcdir/../host-${host_noncanonical}; then
- host_subdir="host-${host_noncanonical}"
-else
- host_subdir=.
-fi
-# No prefix.
-target_subdir=${target_noncanonical}
-
-
-# Set program_transform_name
-test "$program_prefix" != NONE &&
- program_transform_name="s&^&$program_prefix&;$program_transform_name"
-# Use a double $ so make ignores it.
-test "$program_suffix" != NONE &&
- program_transform_name="s&\$&$program_suffix&;$program_transform_name"
-# Double any \ or $.
-# By default was `s,x,x', remove it if useless.
-ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
-program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
-
-
-# Check for bogus environment variables.
-# Test if LIBRARY_PATH contains the notation for the current directory
-# since this would lead to problems installing/building glibc.
-# LIBRARY_PATH contains the current directory if one of the following
-# is true:
-# - one of the terminals (":" and ";") is the first or last sign
-# - two terminals occur directly after each other
-# - the path contains an element with a dot in it
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking LIBRARY_PATH variable" >&5
-$as_echo_n "checking LIBRARY_PATH variable... " >&6; }
-case ${LIBRARY_PATH} in
- [:\;]* | *[:\;] | *[:\;][:\;]* | *[:\;]. | .[:\;]*| . | *[:\;].[:\;]* )
- library_path_setting="contains current directory"
- ;;
- *)
- library_path_setting="ok"
- ;;
-esac
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $library_path_setting" >&5
-$as_echo "$library_path_setting" >&6; }
-if test "$library_path_setting" != "ok"; then
-as_fn_error "
-*** LIBRARY_PATH shouldn't contain the current directory when
-*** building gcc. Please change the environment variable
-*** and run configure again." "$LINENO" 5
-fi
-
-# Test if GCC_EXEC_PREFIX contains the notation for the current directory
-# since this would lead to problems installing/building glibc.
-# GCC_EXEC_PREFIX contains the current directory if one of the following
-# is true:
-# - one of the terminals (":" and ";") is the first or last sign
-# - two terminals occur directly after each other
-# - the path contains an element with a dot in it
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking GCC_EXEC_PREFIX variable" >&5
-$as_echo_n "checking GCC_EXEC_PREFIX variable... " >&6; }
-case ${GCC_EXEC_PREFIX} in
- [:\;]* | *[:\;] | *[:\;][:\;]* | *[:\;]. | .[:\;]*| . | *[:\;].[:\;]* )
- gcc_exec_prefix_setting="contains current directory"
- ;;
- *)
- gcc_exec_prefix_setting="ok"
- ;;
-esac
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_exec_prefix_setting" >&5
-$as_echo "$gcc_exec_prefix_setting" >&6; }
-if test "$gcc_exec_prefix_setting" != "ok"; then
-as_fn_error "
-*** GCC_EXEC_PREFIX shouldn't contain the current directory when
-*** building gcc. Please change the environment variable
-*** and run configure again." "$LINENO" 5
-fi
-
-# -----------
-# Directories
-# -----------
-
-# Specify the local prefix
-local_prefix=
-
-# Check whether --with-local-prefix was given.
-if test "${with_local_prefix+set}" = set; then :
- withval=$with_local_prefix; case "${withval}" in
-yes) as_fn_error "bad value ${withval} given for local include directory prefix" "$LINENO" 5 ;;
-no) ;;
-*) local_prefix=$with_local_prefix ;;
-esac
-fi
-
-
-# Default local prefix if it is empty
-if test x$local_prefix = x; then
- local_prefix=/usr/local
-fi
-
-# Don't set gcc_gxx_include_dir to gxx_include_dir since that's only
-# passed in by the toplevel make and thus we'd get different behavior
-# depending on where we built the sources.
-gcc_gxx_include_dir=
-# Specify the g++ header file directory
-
-# Check whether --with-gxx-include-dir was given.
-if test "${with_gxx_include_dir+set}" = set; then :
- withval=$with_gxx_include_dir; case "${withval}" in
-yes) as_fn_error "bad value ${withval} given for g++ include directory" "$LINENO" 5 ;;
-no) ;;
-*) gcc_gxx_include_dir=$with_gxx_include_dir ;;
-esac
-fi
-
-
-# This logic must match libstdc++-v3/acinclude.m4:GLIBCXX_EXPORT_INSTALL_INFO.
-if test x${gcc_gxx_include_dir} = x; then
- if test x${enable_version_specific_runtime_libs} = xyes; then
- gcc_gxx_include_dir='${libsubdir}/include/c++'
- else
- libstdcxx_incdir='include/c++/$(version)'
- if test x$host != x$target; then
- libstdcxx_incdir="$target_alias/$libstdcxx_incdir"
- fi
- gcc_gxx_include_dir="\$(libsubdir)/\$(libsubdir_to_prefix)$libstdcxx_incdir"
- fi
-fi
-
-gcc_gxx_include_dir_add_sysroot=0
-if test "${with_sysroot+set}" = set; then
- gcc_gxx_without_sysroot=`expr "${gcc_gxx_include_dir}" : "${with_sysroot}"'\(.*\)'`
- if test "${gcc_gxx_without_sysroot}"; then
- gcc_gxx_include_dir="${gcc_gxx_without_sysroot}"
- gcc_gxx_include_dir_add_sysroot=1
- fi
-fi
-
-
-# Check whether --with-cpp_install_dir was given.
-if test "${with_cpp_install_dir+set}" = set; then :
- withval=$with_cpp_install_dir; if test x$withval = xyes; then
- as_fn_error "option --with-cpp-install-dir requires an argument" "$LINENO" 5
-elif test x$withval != xno; then
- cpp_install_dir=$withval
-fi
-fi
-
-
-# We would like to our source tree to be readonly. However when releases or
-# pre-releases are generated, the flex/bison generated files as well as the
-# various formats of manuals need to be included along with the rest of the
-# sources. Therefore we have --enable-generated-files-in-srcdir to do
-# just that.
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to place generated files in the source directory" >&5
-$as_echo_n "checking whether to place generated files in the source directory... " >&6; }
- # Check whether --enable-generated-files-in-srcdir was given.
-if test "${enable_generated_files_in_srcdir+set}" = set; then :
- enableval=$enable_generated_files_in_srcdir; generated_files_in_srcdir=$enableval
-else
- generated_files_in_srcdir=no
-fi
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $generated_files_in_srcdir" >&5
-$as_echo "$generated_files_in_srcdir" >&6; }
-
-if test "$generated_files_in_srcdir" = "yes"; then
- GENINSRC=''
-else
- GENINSRC='#'
-fi
-
-
-# -------------------
-# Find default linker
-# -------------------
-
-# With GNU ld
-
-# Check whether --with-gnu-ld was given.
-if test "${with_gnu_ld+set}" = set; then :
- withval=$with_gnu_ld; gnu_ld_flag="$with_gnu_ld"
-else
- gnu_ld_flag=no
-fi
-
-
-# With pre-defined ld
-
-# Check whether --with-ld was given.
-if test "${with_ld+set}" = set; then :
- withval=$with_ld; DEFAULT_LINKER="$with_ld"
-fi
-
-if test x"${DEFAULT_LINKER+set}" = x"set"; then
- if test ! -x "$DEFAULT_LINKER"; then
- as_fn_error "cannot execute: $DEFAULT_LINKER: check --with-ld or env. var. DEFAULT_LINKER" "$LINENO" 5
- elif $DEFAULT_LINKER -v < /dev/null 2>&1 | grep GNU > /dev/null; then
- gnu_ld_flag=yes
- fi
-
-cat >>confdefs.h <<_ACEOF
-#define DEFAULT_LINKER "$DEFAULT_LINKER"
-_ACEOF
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a default linker was specified" >&5
-$as_echo_n "checking whether a default linker was specified... " >&6; }
-if test x"${DEFAULT_LINKER+set}" = x"set"; then
- if test x"$gnu_ld_flag" = x"no"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($DEFAULT_LINKER)" >&5
-$as_echo "yes ($DEFAULT_LINKER)" >&6; }
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($DEFAULT_LINKER - GNU ld)" >&5
-$as_echo "yes ($DEFAULT_LINKER - GNU ld)" >&6; }
- fi
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-# With demangler in GNU ld
-
-# Check whether --with-demangler-in-ld was given.
-if test "${with_demangler_in_ld+set}" = set; then :
- withval=$with_demangler_in_ld; demangler_in_ld="$with_demangler_in_ld"
-else
- demangler_in_ld=yes
-fi
-
-
-# ----------------------
-# Find default assembler
-# ----------------------
-
-# With GNU as
-
-# Check whether --with-gnu-as was given.
-if test "${with_gnu_as+set}" = set; then :
- withval=$with_gnu_as; gas_flag="$with_gnu_as"
-else
- gas_flag=no
-fi
-
-
-
-# Check whether --with-as was given.
-if test "${with_as+set}" = set; then :
- withval=$with_as; DEFAULT_ASSEMBLER="$with_as"
-fi
-
-if test x"${DEFAULT_ASSEMBLER+set}" = x"set"; then
- if test ! -x "$DEFAULT_ASSEMBLER"; then
- as_fn_error "cannot execute: $DEFAULT_ASSEMBLER: check --with-as or env. var. DEFAULT_ASSEMBLER" "$LINENO" 5
- elif $DEFAULT_ASSEMBLER -v < /dev/null 2>&1 | grep GNU > /dev/null; then
- gas_flag=yes
- fi
-
-cat >>confdefs.h <<_ACEOF
-#define DEFAULT_ASSEMBLER "$DEFAULT_ASSEMBLER"
-_ACEOF
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a default assembler was specified" >&5
-$as_echo_n "checking whether a default assembler was specified... " >&6; }
-if test x"${DEFAULT_ASSEMBLER+set}" = x"set"; then
- if test x"$gas_flag" = x"no"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($DEFAULT_ASSEMBLER)" >&5
-$as_echo "yes ($DEFAULT_ASSEMBLER)" >&6; }
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($DEFAULT_ASSEMBLER - GNU as)" >&5
-$as_echo "yes ($DEFAULT_ASSEMBLER - GNU as)" >&6; }
- fi
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-# ---------------
-# Find C compiler
-# ---------------
-
-# If a non-executable a.out is present (e.g. created by GNU as above even if
-# invoked with -v only), the IRIX 6 native ld just overwrites the existing
-# file, even when creating an executable, so an execution test fails.
-# Remove possible default executable files to avoid this.
-#
-# FIXME: This really belongs into AC_PROG_CC and can be removed once
-# Autoconf includes it.
-rm -f a.out a.exe b.out
-
-# Find the native compiler
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CC="${ac_tool_prefix}gcc"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_CC"; then
- ac_ct_CC=$CC
- # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_CC="gcc"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_CC" = x; then
- CC=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- CC=$ac_ct_CC
- fi
-else
- CC="$ac_cv_prog_CC"
-fi
-
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CC="${ac_tool_prefix}cc"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- fi
-fi
-if test -z "$CC"; then
- # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
- ac_prog_rejected=yes
- continue
- fi
- ac_cv_prog_CC="cc"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-if test $ac_prog_rejected = yes; then
- # We found a bogon in the path, so make sure we never use it.
- set dummy $ac_cv_prog_CC
- shift
- if test $# != 0; then
- # We chose a different compiler from the bogus one.
- # However, it has the same basename, so the bogon will be chosen
- # first if we set CC to just the basename; use the full file name.
- shift
- ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
- fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- for ac_prog in cl.exe
- do
- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$CC" && break
- done
-fi
-if test -z "$CC"; then
- ac_ct_CC=$CC
- for ac_prog in cl.exe
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_CC="$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$ac_ct_CC" && break
-done
-
- if test "x$ac_ct_CC" = x; then
- CC=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- CC=$ac_ct_CC
- fi
-fi
-
-fi
-
-
-test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "no acceptable C compiler found in \$PATH
-See \`config.log' for more details." "$LINENO" 5; }
-
-# Provide some information about the compiler.
-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
-set X $ac_compile
-ac_compiler=$2
-for ac_option in --version -v -V -qversion; do
- { { ac_try="$ac_compiler $ac_option >&5"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compiler $ac_option >&5") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- sed '10a\
-... rest of stderr output deleted ...
- 10q' conftest.err >conftest.er1
- cat conftest.er1 >&5
- rm -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }
-done
-
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out conftest.out"
-# Try to create an executable without -o first, disregard a.out.
-# It will help us diagnose broken compilers, and finding out an intuition
-# of exeext.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
-$as_echo_n "checking for C compiler default output file name... " >&6; }
-ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-
-# The possible output files:
-ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
-
-ac_rmfiles=
-for ac_file in $ac_files
-do
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
- * ) ac_rmfiles="$ac_rmfiles $ac_file";;
- esac
-done
-rm -f $ac_rmfiles
-
-if { { ac_try="$ac_link_default"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link_default") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then :
- # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
-# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
-# in a Makefile. We should not override ac_cv_exeext if it was cached,
-# so that the user can short-circuit this test for compilers unknown to
-# Autoconf.
-for ac_file in $ac_files ''
-do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
- ;;
- [ab].out )
- # We found the default executable, but exeext='' is most
- # certainly right.
- break;;
- *.* )
- if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
- then :; else
- ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- fi
- # We set ac_cv_exeext here because the later test for it is not
- # safe: cross compilers may not add the suffix if given an `-o'
- # argument, so we may need to know it at that point already.
- # Even if this section looks crufty: it has the advantage of
- # actually working.
- break;;
- * )
- break;;
- esac
-done
-test "$ac_cv_exeext" = no && ac_cv_exeext=
-
-else
- ac_file=''
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
-$as_echo "$ac_file" >&6; }
-if test -z "$ac_file"; then :
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "C compiler cannot create executables
-See \`config.log' for more details." "$LINENO" 5; }; }
-fi
-ac_exeext=$ac_cv_exeext
-
-# Check that the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
-$as_echo_n "checking whether the C compiler works... " >&6; }
-# If not cross compiling, check that we can run a simple program.
-if test "$cross_compiling" != yes; then
- if { ac_try='./$ac_file'
- { { case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }; then
- cross_compiling=no
- else
- if test "$cross_compiling" = maybe; then
- cross_compiling=yes
- else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." "$LINENO" 5; }
- fi
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-
-rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out conftest.out
-ac_clean_files=$ac_clean_files_save
-# Check that the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
-$as_echo_n "checking whether we are cross compiling... " >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
-$as_echo "$cross_compiling" >&6; }
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
-$as_echo_n "checking for suffix of executables... " >&6; }
-if { { ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then :
- # If both `conftest.exe' and `conftest' are `present' (well, observable)
-# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
-# work properly (i.e., refer to `conftest.exe'), while it won't with
-# `rm'.
-for ac_file in conftest.exe conftest conftest.*; do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
- *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- break;;
- * ) break;;
- esac
-done
-else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." "$LINENO" 5; }
-fi
-rm -f conftest$ac_cv_exeext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
-$as_echo "$ac_cv_exeext" >&6; }
-
-rm -f conftest.$ac_ext
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
-$as_echo_n "checking for suffix of object files... " >&6; }
-if test "${ac_cv_objext+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.o conftest.obj
-if { { ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compile") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then :
- for ac_file in conftest.o conftest.obj conftest.*; do
- test -f "$ac_file" || continue;
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
- *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
- break;;
- esac
-done
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." "$LINENO" 5; }
-fi
-rm -f conftest.$ac_cv_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
-$as_echo "$ac_cv_objext" >&6; }
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
-$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if test "${ac_cv_c_compiler_gnu+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-#ifndef __GNUC__
- choke me
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_compiler_gnu=yes
-else
- ac_compiler_gnu=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
-$as_echo "$ac_cv_c_compiler_gnu" >&6; }
-if test $ac_compiler_gnu = yes; then
- GCC=yes
-else
- GCC=
-fi
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
-$as_echo_n "checking whether $CC accepts -g... " >&6; }
-if test "${ac_cv_prog_cc_g+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_save_c_werror_flag=$ac_c_werror_flag
- ac_c_werror_flag=yes
- ac_cv_prog_cc_g=no
- CFLAGS="-g"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_prog_cc_g=yes
-else
- CFLAGS=""
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
- ac_c_werror_flag=$ac_save_c_werror_flag
- CFLAGS="-g"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_prog_cc_g=yes
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_c_werror_flag=$ac_save_c_werror_flag
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
-$as_echo "$ac_cv_prog_cc_g" >&6; }
-if test "$ac_test_CFLAGS" = set; then
- CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
- if test "$GCC" = yes; then
- CFLAGS="-g -O2"
- else
- CFLAGS="-g"
- fi
-else
- if test "$GCC" = yes; then
- CFLAGS="-O2"
- else
- CFLAGS=
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
-$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if test "${ac_cv_prog_cc_c89+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_cv_prog_cc_c89=no
-ac_save_CC=$CC
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
- char **p;
- int i;
-{
- return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
- char *s;
- va_list v;
- va_start (v,p);
- s = g (p, va_arg (v,int));
- va_end (v);
- return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
- function prototypes and stuff, but not '\xHH' hex character constants.
- These don't provoke an error unfortunately, instead are silently treated
- as 'x'. The following induces an error, until -std is added to get
- proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
- array size at least. It's necessary to write '\x00'==0 to get something
- that's true only with -std. */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
- inside strings and character constants. */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
- ;
- return 0;
-}
-_ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
- -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
- CC="$ac_save_CC $ac_arg"
- if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_prog_cc_c89=$ac_arg
-fi
-rm -f core conftest.err conftest.$ac_objext
- test "x$ac_cv_prog_cc_c89" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-
-fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
- x)
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-$as_echo "none needed" >&6; } ;;
- xno)
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-$as_echo "unsupported" >&6; } ;;
- *)
- CC="$CC $ac_cv_prog_cc_c89"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
-$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-if test "x$ac_cv_prog_cc_c89" != xno; then :
-
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-if test "x$CC" != xcc; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5
-$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5
-$as_echo_n "checking whether cc understands -c and -o together... " >&6; }
-fi
-set dummy $CC; ac_cc=`$as_echo "$2" |
- sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
-if { as_var=ac_cv_prog_cc_${ac_cc}_c_o; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-# Make sure it works both with $CC and with simple cc.
-# We do the test twice because some compilers refuse to overwrite an
-# existing .o file with -o, though they will create one.
-ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
-rm -f conftest2.*
-if { { case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } &&
- test -f conftest2.$ac_objext && { { case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; };
-then
- eval ac_cv_prog_cc_${ac_cc}_c_o=yes
- if test "x$CC" != xcc; then
- # Test first that cc exists at all.
- if { ac_try='cc -c conftest.$ac_ext >&5'
- { { case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }; then
- ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
- rm -f conftest2.*
- if { { case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } &&
- test -f conftest2.$ac_objext && { { case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; };
- then
- # cc works too.
- :
- else
- # cc exists but doesn't like -o.
- eval ac_cv_prog_cc_${ac_cc}_c_o=no
- fi
- fi
- fi
-else
- eval ac_cv_prog_cc_${ac_cc}_c_o=no
-fi
-rm -f core conftest*
-
-fi
-if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-
-$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h
-
-fi
-
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
-
-# FIXME: we rely on the cache variable name because
-# there is no other way.
-set dummy $CC
-am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
-eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
-if test "$am_t" != yes; then
- # Losing compiler, so override with the script.
- # FIXME: It is wrong to rewrite CC.
- # But if we don't then we get into trouble of one sort or another.
- # A longer-term fix would be to have automake use am__CC in this case,
- # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
- CC="$am_aux_dir/compile $CC"
-fi
-
-
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-if test -z "$CXX"; then
- if test -n "$CCC"; then
- CXX=$CCC
- else
- if test -n "$ac_tool_prefix"; then
- for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
- do
- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CXX+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$CXX"; then
- ac_cv_prog_CXX="$CXX" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-CXX=$ac_cv_prog_CXX
-if test -n "$CXX"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
-$as_echo "$CXX" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$CXX" && break
- done
-fi
-if test -z "$CXX"; then
- ac_ct_CXX=$CXX
- for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_CXX"; then
- ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_CXX="$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
-if test -n "$ac_ct_CXX"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
-$as_echo "$ac_ct_CXX" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$ac_ct_CXX" && break
-done
-
- if test "x$ac_ct_CXX" = x; then
- CXX="g++"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- CXX=$ac_ct_CXX
- fi
-fi
-
- fi
-fi
-# Provide some information about the compiler.
-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
-set X $ac_compile
-ac_compiler=$2
-for ac_option in --version -v -V -qversion; do
- { { ac_try="$ac_compiler $ac_option >&5"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compiler $ac_option >&5") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- sed '10a\
-... rest of stderr output deleted ...
- 10q' conftest.err >conftest.er1
- cat conftest.er1 >&5
- rm -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }
-done
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
-$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
-if test "${ac_cv_cxx_compiler_gnu+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-#ifndef __GNUC__
- choke me
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
- ac_compiler_gnu=yes
-else
- ac_compiler_gnu=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
-$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
-if test $ac_compiler_gnu = yes; then
- GXX=yes
-else
- GXX=
-fi
-ac_test_CXXFLAGS=${CXXFLAGS+set}
-ac_save_CXXFLAGS=$CXXFLAGS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
-$as_echo_n "checking whether $CXX accepts -g... " >&6; }
-if test "${ac_cv_prog_cxx_g+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_save_cxx_werror_flag=$ac_cxx_werror_flag
- ac_cxx_werror_flag=yes
- ac_cv_prog_cxx_g=no
- CXXFLAGS="-g"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
- ac_cv_prog_cxx_g=yes
-else
- CXXFLAGS=""
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
-
-else
- ac_cxx_werror_flag=$ac_save_cxx_werror_flag
- CXXFLAGS="-g"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
- ac_cv_prog_cxx_g=yes
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_cxx_werror_flag=$ac_save_cxx_werror_flag
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
-$as_echo "$ac_cv_prog_cxx_g" >&6; }
-if test "$ac_test_CXXFLAGS" = set; then
- CXXFLAGS=$ac_save_CXXFLAGS
-elif test $ac_cv_prog_cxx_g = yes; then
- if test "$GXX" = yes; then
- CXXFLAGS="-g -O2"
- else
- CXXFLAGS="-g"
- fi
-else
- if test "$GXX" = yes; then
- CXXFLAGS="-O2"
- else
- CXXFLAGS=
- fi
-fi
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}gnatbind", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gnatbind; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_GNATBIND+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$GNATBIND"; then
- ac_cv_prog_GNATBIND="$GNATBIND" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_GNATBIND="${ac_tool_prefix}gnatbind"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-GNATBIND=$ac_cv_prog_GNATBIND
-if test -n "$GNATBIND"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GNATBIND" >&5
-$as_echo "$GNATBIND" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_GNATBIND"; then
- ac_ct_GNATBIND=$GNATBIND
- # Extract the first word of "gnatbind", so it can be a program name with args.
-set dummy gnatbind; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_GNATBIND+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_GNATBIND"; then
- ac_cv_prog_ac_ct_GNATBIND="$ac_ct_GNATBIND" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_GNATBIND="gnatbind"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_GNATBIND=$ac_cv_prog_ac_ct_GNATBIND
-if test -n "$ac_ct_GNATBIND"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_GNATBIND" >&5
-$as_echo "$ac_ct_GNATBIND" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_GNATBIND" = x; then
- GNATBIND="no"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- GNATBIND=$ac_ct_GNATBIND
- fi
-else
- GNATBIND="$ac_cv_prog_GNATBIND"
-fi
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}gnatmake", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gnatmake; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_GNATMAKE+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$GNATMAKE"; then
- ac_cv_prog_GNATMAKE="$GNATMAKE" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_GNATMAKE="${ac_tool_prefix}gnatmake"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-GNATMAKE=$ac_cv_prog_GNATMAKE
-if test -n "$GNATMAKE"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GNATMAKE" >&5
-$as_echo "$GNATMAKE" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_GNATMAKE"; then
- ac_ct_GNATMAKE=$GNATMAKE
- # Extract the first word of "gnatmake", so it can be a program name with args.
-set dummy gnatmake; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_GNATMAKE+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_GNATMAKE"; then
- ac_cv_prog_ac_ct_GNATMAKE="$ac_ct_GNATMAKE" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_GNATMAKE="gnatmake"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_GNATMAKE=$ac_cv_prog_ac_ct_GNATMAKE
-if test -n "$ac_ct_GNATMAKE"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_GNATMAKE" >&5
-$as_echo "$ac_ct_GNATMAKE" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_GNATMAKE" = x; then
- GNATMAKE="no"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- GNATMAKE=$ac_ct_GNATMAKE
- fi
-else
- GNATMAKE="$ac_cv_prog_GNATMAKE"
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler driver understands Ada" >&5
-$as_echo_n "checking whether compiler driver understands Ada... " >&6; }
-if test "${acx_cv_cc_gcc_supports_ada+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat >conftest.adb <<EOF
-procedure conftest is begin null; end conftest;
-EOF
-acx_cv_cc_gcc_supports_ada=no
-# There is a bug in old released versions of GCC which causes the
-# driver to exit successfully when the appropriate language module
-# has not been installed. This is fixed in 2.95.4, 3.0.2, and 3.1.
-# Therefore we must check for the error message as well as an
-# unsuccessful exit.
-# Other compilers, like HP Tru64 UNIX cc, exit successfully when
-# given a .adb file, but produce no object file. So we must check
-# if an object file was really produced to guard against this.
-errors=`(${CC} -I"$srcdir"/ada -c conftest.adb) 2>&1 || echo failure`
-if test x"$errors" = x && test -f conftest.$ac_objext; then
- acx_cv_cc_gcc_supports_ada=yes
-fi
-rm -f conftest.*
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_cv_cc_gcc_supports_ada" >&5
-$as_echo "$acx_cv_cc_gcc_supports_ada" >&6; }
-
-if test "x$GNATBIND" != xno && test "x$GNATMAKE" != xno && test x$acx_cv_cc_gcc_supports_ada != xno; then
- have_gnat=yes
-else
- have_gnat=no
-fi
-
-
-# autoconf is lame and doesn't give us any substitution variable for this.
-if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" = no"; then
- NO_MINUS_C_MINUS_O=yes
-else
- OUTPUT_OPTION='-o $@'
-fi
-
-
-
-# Remove the -O2: for historical reasons, unless bootstrapping we prefer
-# optimizations to be activated explicitly by the toplevel.
-case "$CC" in
- */prev-gcc/xgcc*) ;;
- *) CFLAGS=`echo "$CFLAGS " | sed -e "s/-Ofast[ ]//" -e "s/-O[gs][ ]//" -e "s/-O[0-9]*[ ]//" `
- CXXFLAGS=`echo "$CXXFLAGS " | sed -e "s/-Ofast[ ]//" -e "s/-O[gs][ ]//" -e "s/-O[0-9]*[ ]//" ` ;;
-esac
-
-
-
-# Determine PICFLAG for target gnatlib.
-
-
-
-
-case "${target}" in
- # PIC is the default on some targets or must not be used.
- *-*-darwin*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- PICFLAG_FOR_TARGET=-fno-common
- ;;
- alpha*-dec-osf5*)
- # PIC is the default.
- ;;
- hppa*64*-*-hpux*)
- # PIC is the default for 64-bit PA HP-UX.
- ;;
- i[34567]86-*-cygwin* | i[34567]86-*-mingw* | x86_64-*-mingw*)
- ;;
- i[34567]86-*-interix[3-9]*)
- # Interix 3.x gcc -fpic/-fPIC options generate broken code.
- # Instead, we relocate shared libraries at runtime.
- ;;
- i[34567]86-*-nto-qnx*)
- # QNX uses GNU C++, but need to define -shared option too, otherwise
- # it will coredump.
- PICFLAG_FOR_TARGET='-fPIC -shared'
- ;;
- i[34567]86-pc-msdosdjgpp*)
- # DJGPP does not support shared libraries at all.
- ;;
- ia64*-*-hpux*)
- # On IA64 HP-UX, PIC is the default but the pic flag
- # sets the default TLS model and affects inlining.
- PICFLAG_FOR_TARGET=-fPIC
- ;;
- mips-sgi-irix6*)
- # PIC is the default.
- ;;
- rs6000-ibm-aix* | powerpc-ibm-aix*)
- # All AIX code is PIC.
- ;;
-
- # Some targets support both -fPIC and -fpic, but prefer the latter.
- # FIXME: Why?
- i[34567]86-*-* | x86_64-*-*)
- PICFLAG_FOR_TARGET=-fpic
- ;;
- m68k-*-*)
- PICFLAG_FOR_TARGET=-fpic
- ;;
- # FIXME: Override -fPIC default in libgcc only?
- sh-*-linux* | sh[2346lbe]*-*-linux*)
- PICFLAG_FOR_TARGET=-fpic
- ;;
- # FIXME: Simplify to sh*-*-netbsd*?
- sh-*-netbsdelf* | shl*-*-netbsdelf* | sh5-*-netbsd* | sh5l*-*-netbsd* | \
- sh64-*-netbsd* | sh64l*-*-netbsd*)
- PICFLAG_FOR_TARGET=-fpic
- ;;
- # Default to -fPIC unless specified otherwise.
- *)
- PICFLAG_FOR_TARGET=-fPIC
- ;;
-esac
-
-# If the user explicitly uses -fpic/-fPIC, keep that.
-case "${CFLAGS_FOR_TARGET}" in
- *-fpic*)
- PICFLAG_FOR_TARGET=-fpic
- ;;
- *-fPIC*)
- PICFLAG_FOR_TARGET=-fPIC
- ;;
-esac
-
-
-
-# -------------------------
-# Check C compiler features
-# -------------------------
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
-$as_echo_n "checking how to run the C preprocessor... " >&6; }
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
-fi
-if test -z "$CPP"; then
- if test "${ac_cv_prog_CPP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- # Double quotes because CPP needs to be expanded
- for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
- do
- ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
- # Broken: success on invalid input.
-continue
-else
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
- break
-fi
-
- done
- ac_cv_prog_CPP=$CPP
-
-fi
- CPP=$ac_cv_prog_CPP
-else
- ac_cv_prog_CPP=$CPP
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
-$as_echo "$CPP" >&6; }
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
- # Broken: success on invalid input.
-continue
-else
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-
-else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." "$LINENO" 5; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
-$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
-if test "${ac_cv_path_GREP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -z "$GREP"; then
- ac_path_GREP_found=false
- # Loop through the user's path and test for each of PROGNAME-LIST
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in grep ggrep; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
-# Check for GNU ac_path_GREP and select it if it is found.
- # Check for GNU $ac_path_GREP
-case `"$ac_path_GREP" --version 2>&1` in
-*GNU*)
- ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
-*)
- ac_count=0
- $as_echo_n 0123456789 >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- $as_echo 'GREP' >> "conftest.nl"
- "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
- as_fn_arith $ac_count + 1 && ac_count=$as_val
- if test $ac_count -gt ${ac_path_GREP_max-0}; then
- # Best one so far, save it but keep looking for a better one
- ac_cv_path_GREP="$ac_path_GREP"
- ac_path_GREP_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
- $ac_path_GREP_found && break 3
- done
- done
- done
-IFS=$as_save_IFS
- if test -z "$ac_cv_path_GREP"; then
- as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
- fi
-else
- ac_cv_path_GREP=$GREP
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
-$as_echo "$ac_cv_path_GREP" >&6; }
- GREP="$ac_cv_path_GREP"
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
-$as_echo_n "checking for egrep... " >&6; }
-if test "${ac_cv_path_EGREP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
- then ac_cv_path_EGREP="$GREP -E"
- else
- if test -z "$EGREP"; then
- ac_path_EGREP_found=false
- # Loop through the user's path and test for each of PROGNAME-LIST
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in egrep; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
-# Check for GNU ac_path_EGREP and select it if it is found.
- # Check for GNU $ac_path_EGREP
-case `"$ac_path_EGREP" --version 2>&1` in
-*GNU*)
- ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
-*)
- ac_count=0
- $as_echo_n 0123456789 >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- $as_echo 'EGREP' >> "conftest.nl"
- "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
- as_fn_arith $ac_count + 1 && ac_count=$as_val
- if test $ac_count -gt ${ac_path_EGREP_max-0}; then
- # Best one so far, save it but keep looking for a better one
- ac_cv_path_EGREP="$ac_path_EGREP"
- ac_path_EGREP_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
- $ac_path_EGREP_found && break 3
- done
- done
- done
-IFS=$as_save_IFS
- if test -z "$ac_cv_path_EGREP"; then
- as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
- fi
-else
- ac_cv_path_EGREP=$EGREP
-fi
-
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
-$as_echo "$ac_cv_path_EGREP" >&6; }
- EGREP="$ac_cv_path_EGREP"
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
-$as_echo_n "checking for ANSI C header files... " >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_header_stdc=yes
-else
- ac_cv_header_stdc=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
- # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "memchr" >/dev/null 2>&1; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "free" >/dev/null 2>&1; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
- if test "$cross_compiling" = yes; then :
- :
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
- (('a' <= (c) && (c) <= 'i') \
- || ('j' <= (c) && (c) <= 'r') \
- || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
- int i;
- for (i = 0; i < 256; i++)
- if (XOR (islower (i), ISLOWER (i))
- || toupper (i) != TOUPPER (i))
- return 2;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
-$as_echo "$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-$as_echo "#define STDC_HEADERS 1" >>confdefs.h
-
-fi
-
-# On IRIX 5.3, sys/types and inttypes.h are conflicting.
-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
- inttypes.h stdint.h unistd.h
-do :
- as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
-"
-eval as_val=\$$as_ac_Header
- if test "x$as_val" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-
- ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default"
-if test "x$ac_cv_header_minix_config_h" = x""yes; then :
- MINIX=yes
-else
- MINIX=
-fi
-
-
- if test "$MINIX" = yes; then
-
-$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h
-
-
-$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h
-
-
-$as_echo "#define _MINIX 1" >>confdefs.h
-
- fi
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
-$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; }
-if test "${ac_cv_safe_to_define___extensions__+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-# define __EXTENSIONS__ 1
- $ac_includes_default
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_safe_to_define___extensions__=yes
-else
- ac_cv_safe_to_define___extensions__=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5
-$as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
- test $ac_cv_safe_to_define___extensions__ = yes &&
- $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h
-
- $as_echo "#define _ALL_SOURCE 1" >>confdefs.h
-
- $as_echo "#define _GNU_SOURCE 1" >>confdefs.h
-
- $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
-
- $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
-$as_echo_n "checking how to run the C preprocessor... " >&6; }
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
-fi
-if test -z "$CPP"; then
- if test "${ac_cv_prog_CPP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- # Double quotes because CPP needs to be expanded
- for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
- do
- ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
- # Broken: success on invalid input.
-continue
-else
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
- break
-fi
-
- done
- ac_cv_prog_CPP=$CPP
-
-fi
- CPP=$ac_cv_prog_CPP
-else
- ac_cv_prog_CPP=$CPP
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
-$as_echo "$CPP" >&6; }
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
- # Broken: success on invalid input.
-continue
-else
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-
-else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." "$LINENO" 5; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
-$as_echo_n "checking for inline... " >&6; }
-if test "${ac_cv_c_inline+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_cv_c_inline=no
-for ac_kw in inline __inline__ __inline; do
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifndef __cplusplus
-typedef int foo_t;
-static $ac_kw foo_t static_foo () {return 0; }
-$ac_kw foo_t foo () {return 0; }
-#endif
-
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_c_inline=$ac_kw
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- test "$ac_cv_c_inline" != no && break
-done
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
-$as_echo "$ac_cv_c_inline" >&6; }
-
-case $ac_cv_c_inline in
- inline | yes) ;;
- *)
- case $ac_cv_c_inline in
- no) ac_val=;;
- *) ac_val=$ac_cv_c_inline;;
- esac
- cat >>confdefs.h <<_ACEOF
-#ifndef __cplusplus
-#define inline $ac_val
-#endif
-_ACEOF
- ;;
-esac
-
-
-# Check whether --enable-largefile was given.
-if test "${enable_largefile+set}" = set; then :
- enableval=$enable_largefile;
-fi
-
-if test "$enable_largefile" != no; then
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
-$as_echo_n "checking for special C compiler options needed for large files... " >&6; }
-if test "${ac_cv_sys_largefile_CC+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_cv_sys_largefile_CC=no
- if test "$GCC" != yes; then
- ac_save_CC=$CC
- while :; do
- # IRIX 6.2 and later do not support large files by default,
- # so use the C compiler's -n32 option if that helps.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
- if ac_fn_c_try_compile "$LINENO"; then :
- break
-fi
-rm -f core conftest.err conftest.$ac_objext
- CC="$CC -n32"
- if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_sys_largefile_CC=' -n32'; break
-fi
-rm -f core conftest.err conftest.$ac_objext
- break
- done
- CC=$ac_save_CC
- rm -f conftest.$ac_ext
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5
-$as_echo "$ac_cv_sys_largefile_CC" >&6; }
- if test "$ac_cv_sys_largefile_CC" != no; then
- CC=$CC$ac_cv_sys_largefile_CC
- fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
-$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
-if test "${ac_cv_sys_file_offset_bits+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- while :; do
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_sys_file_offset_bits=no; break
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#define _FILE_OFFSET_BITS 64
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_sys_file_offset_bits=64; break
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_cv_sys_file_offset_bits=unknown
- break
-done
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5
-$as_echo "$ac_cv_sys_file_offset_bits" >&6; }
-case $ac_cv_sys_file_offset_bits in #(
- no | unknown) ;;
- *)
-cat >>confdefs.h <<_ACEOF
-#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
-_ACEOF
-;;
-esac
-rm -rf conftest*
- if test $ac_cv_sys_file_offset_bits = unknown; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5
-$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; }
-if test "${ac_cv_sys_large_files+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- while :; do
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_sys_large_files=no; break
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#define _LARGE_FILES 1
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_sys_large_files=1; break
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_cv_sys_large_files=unknown
- break
-done
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5
-$as_echo "$ac_cv_sys_large_files" >&6; }
-case $ac_cv_sys_large_files in #(
- no | unknown) ;;
- *)
-cat >>confdefs.h <<_ACEOF
-#define _LARGE_FILES $ac_cv_sys_large_files
-_ACEOF
-;;
-esac
-rm -rf conftest*
- fi
-fi
-
-
-# sizeof(char) is 1 by definition.
-# The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
-# This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5
-$as_echo_n "checking size of void *... " >&6; }
-if test "${ac_cv_sizeof_void_p+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then :
-
-else
- if test "$ac_cv_type_void_p" = yes; then
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (void *)
-See \`config.log' for more details." "$LINENO" 5; }; }
- else
- ac_cv_sizeof_void_p=0
- fi
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5
-$as_echo "$ac_cv_sizeof_void_p" >&6; }
-
-
-
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_VOID_P $ac_cv_sizeof_void_p
-_ACEOF
-
-
-# The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
-# This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5
-$as_echo_n "checking size of short... " >&6; }
-if test "${ac_cv_sizeof_short+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default"; then :
-
-else
- if test "$ac_cv_type_short" = yes; then
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (short)
-See \`config.log' for more details." "$LINENO" 5; }; }
- else
- ac_cv_sizeof_short=0
- fi
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5
-$as_echo "$ac_cv_sizeof_short" >&6; }
-
-
-
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_SHORT $ac_cv_sizeof_short
-_ACEOF
-
-
-# The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
-# This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5
-$as_echo_n "checking size of int... " >&6; }
-if test "${ac_cv_sizeof_int+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then :
-
-else
- if test "$ac_cv_type_int" = yes; then
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (int)
-See \`config.log' for more details." "$LINENO" 5; }; }
- else
- ac_cv_sizeof_int=0
- fi
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5
-$as_echo "$ac_cv_sizeof_int" >&6; }
-
-
-
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_INT $ac_cv_sizeof_int
-_ACEOF
-
-
-# The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
-# This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
-$as_echo_n "checking size of long... " >&6; }
-if test "${ac_cv_sizeof_long+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then :
-
-else
- if test "$ac_cv_type_long" = yes; then
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (long)
-See \`config.log' for more details." "$LINENO" 5; }; }
- else
- ac_cv_sizeof_long=0
- fi
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
-$as_echo "$ac_cv_sizeof_long" >&6; }
-
-
-
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_LONG $ac_cv_sizeof_long
-_ACEOF
-
-
-ac_fn_c_check_type "$LINENO" "long long" "ac_cv_type_long_long" "$ac_includes_default"
-if test "x$ac_cv_type_long_long" = x""yes; then :
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_LONG_LONG 1
-_ACEOF
-
-# The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
-# This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5
-$as_echo_n "checking size of long long... " >&6; }
-if test "${ac_cv_sizeof_long_long+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default"; then :
-
-else
- if test "$ac_cv_type_long_long" = yes; then
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (long long)
-See \`config.log' for more details." "$LINENO" 5; }; }
- else
- ac_cv_sizeof_long_long=0
- fi
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5
-$as_echo "$ac_cv_sizeof_long_long" >&6; }
-
-
-
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
-_ACEOF
-
-
-fi
-
-ac_fn_c_check_type "$LINENO" "__int64" "ac_cv_type___int64" "$ac_includes_default"
-if test "x$ac_cv_type___int64" = x""yes; then :
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE___INT64 1
-_ACEOF
-
-# The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
-# This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of __int64" >&5
-$as_echo_n "checking size of __int64... " >&6; }
-if test "${ac_cv_sizeof___int64+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (__int64))" "ac_cv_sizeof___int64" "$ac_includes_default"; then :
-
-else
- if test "$ac_cv_type___int64" = yes; then
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (__int64)
-See \`config.log' for more details." "$LINENO" 5; }; }
- else
- ac_cv_sizeof___int64=0
- fi
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof___int64" >&5
-$as_echo "$ac_cv_sizeof___int64" >&6; }
-
-
-
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF___INT64 $ac_cv_sizeof___int64
-_ACEOF
-
-
-fi
-
-ac_fn_c_find_intX_t "$LINENO" "8" "ac_cv_c_int8_t"
-case $ac_cv_c_int8_t in #(
- no|yes) ;; #(
- *)
-
-cat >>confdefs.h <<_ACEOF
-#define int8_t $ac_cv_c_int8_t
-_ACEOF
-;;
-esac
-
-ac_fn_c_find_intX_t "$LINENO" "16" "ac_cv_c_int16_t"
-case $ac_cv_c_int16_t in #(
- no|yes) ;; #(
- *)
-
-cat >>confdefs.h <<_ACEOF
-#define int16_t $ac_cv_c_int16_t
-_ACEOF
-;;
-esac
-
-ac_fn_c_find_intX_t "$LINENO" "32" "ac_cv_c_int32_t"
-case $ac_cv_c_int32_t in #(
- no|yes) ;; #(
- *)
-
-cat >>confdefs.h <<_ACEOF
-#define int32_t $ac_cv_c_int32_t
-_ACEOF
-;;
-esac
-
-ac_fn_c_find_intX_t "$LINENO" "64" "ac_cv_c_int64_t"
-case $ac_cv_c_int64_t in #(
- no|yes) ;; #(
- *)
-
-cat >>confdefs.h <<_ACEOF
-#define int64_t $ac_cv_c_int64_t
-_ACEOF
-;;
-esac
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long int" >&5
-$as_echo_n "checking for long long int... " >&6; }
-if test "${ac_cv_type_long_long_int+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
- /* For now, do not test the preprocessor; as of 2007 there are too many
- implementations with broken preprocessors. Perhaps this can
- be revisited in 2012. In the meantime, code should not expect
- #if to work with literals wider than 32 bits. */
- /* Test literals. */
- long long int ll = 9223372036854775807ll;
- long long int nll = -9223372036854775807LL;
- unsigned long long int ull = 18446744073709551615ULL;
- /* Test constant expressions. */
- typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
- ? 1 : -1)];
- typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1
- ? 1 : -1)];
- int i = 63;
-int
-main ()
-{
-/* Test availability of runtime routines for shift and division. */
- long long int llmax = 9223372036854775807ll;
- unsigned long long int ullmax = 18446744073709551615ull;
- return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
- | (llmax / ll) | (llmax % ll)
- | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i)
- | (ullmax / ull) | (ullmax % ull));
- ;
- return 0;
-}
-
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- if test "$cross_compiling" = yes; then :
- ac_cv_type_long_long_int=yes
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <limits.h>
- #ifndef LLONG_MAX
- # define HALF \
- (1LL << (sizeof (long long int) * CHAR_BIT - 2))
- # define LLONG_MAX (HALF - 1 + HALF)
- #endif
-int
-main ()
-{
-long long int n = 1;
- int i;
- for (i = 0; ; i++)
- {
- long long int m = n << i;
- if (m >> i != n)
- return 1;
- if (LLONG_MAX / 2 < m)
- break;
- }
- return 0;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
- ac_cv_type_long_long_int=yes
-else
- ac_cv_type_long_long_int=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-else
- ac_cv_type_long_long_int=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_long_int" >&5
-$as_echo "$ac_cv_type_long_long_int" >&6; }
- if test $ac_cv_type_long_long_int = yes; then
-
-$as_echo "#define HAVE_LONG_LONG_INT 1" >>confdefs.h
-
- fi
-
-
-
- ac_fn_c_check_type "$LINENO" "intmax_t" "ac_cv_type_intmax_t" "$ac_includes_default"
-if test "x$ac_cv_type_intmax_t" = x""yes; then :
-
-$as_echo "#define HAVE_INTMAX_T 1" >>confdefs.h
-
-else
- test $ac_cv_type_long_long_int = yes \
- && ac_type='long long int' \
- || ac_type='long int'
-
-cat >>confdefs.h <<_ACEOF
-#define intmax_t $ac_type
-_ACEOF
-
-fi
-
-
-
- ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default"
-if test "x$ac_cv_type_intptr_t" = x""yes; then :
-
-$as_echo "#define HAVE_INTPTR_T 1" >>confdefs.h
-
-else
- for ac_type in 'int' 'long int' 'long long int'; do
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))];
-test_array [0] = 0
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-cat >>confdefs.h <<_ACEOF
-#define intptr_t $ac_type
-_ACEOF
-
- ac_type=
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- test -z "$ac_type" && break
- done
-fi
-
-
-ac_fn_c_find_uintX_t "$LINENO" "8" "ac_cv_c_uint8_t"
-case $ac_cv_c_uint8_t in #(
- no|yes) ;; #(
- *)
-
-$as_echo "#define _UINT8_T 1" >>confdefs.h
-
-
-cat >>confdefs.h <<_ACEOF
-#define uint8_t $ac_cv_c_uint8_t
-_ACEOF
-;;
- esac
-
-ac_fn_c_find_uintX_t "$LINENO" "16" "ac_cv_c_uint16_t"
-case $ac_cv_c_uint16_t in #(
- no|yes) ;; #(
- *)
-
-
-cat >>confdefs.h <<_ACEOF
-#define uint16_t $ac_cv_c_uint16_t
-_ACEOF
-;;
- esac
-
-ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t"
-case $ac_cv_c_uint32_t in #(
- no|yes) ;; #(
- *)
-
-$as_echo "#define _UINT32_T 1" >>confdefs.h
-
-
-cat >>confdefs.h <<_ACEOF
-#define uint32_t $ac_cv_c_uint32_t
-_ACEOF
-;;
- esac
-
-ac_fn_c_find_uintX_t "$LINENO" "64" "ac_cv_c_uint64_t"
-case $ac_cv_c_uint64_t in #(
- no|yes) ;; #(
- *)
-
-$as_echo "#define _UINT64_T 1" >>confdefs.h
-
-
-cat >>confdefs.h <<_ACEOF
-#define uint64_t $ac_cv_c_uint64_t
-_ACEOF
-;;
- esac
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned long long int" >&5
-$as_echo_n "checking for unsigned long long int... " >&6; }
-if test "${ac_cv_type_unsigned_long_long_int+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
- /* For now, do not test the preprocessor; as of 2007 there are too many
- implementations with broken preprocessors. Perhaps this can
- be revisited in 2012. In the meantime, code should not expect
- #if to work with literals wider than 32 bits. */
- /* Test literals. */
- long long int ll = 9223372036854775807ll;
- long long int nll = -9223372036854775807LL;
- unsigned long long int ull = 18446744073709551615ULL;
- /* Test constant expressions. */
- typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
- ? 1 : -1)];
- typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1
- ? 1 : -1)];
- int i = 63;
-int
-main ()
-{
-/* Test availability of runtime routines for shift and division. */
- long long int llmax = 9223372036854775807ll;
- unsigned long long int ullmax = 18446744073709551615ull;
- return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
- | (llmax / ll) | (llmax % ll)
- | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i)
- | (ullmax / ull) | (ullmax % ull));
- ;
- return 0;
-}
-
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_type_unsigned_long_long_int=yes
-else
- ac_cv_type_unsigned_long_long_int=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_unsigned_long_long_int" >&5
-$as_echo "$ac_cv_type_unsigned_long_long_int" >&6; }
- if test $ac_cv_type_unsigned_long_long_int = yes; then
-
-$as_echo "#define HAVE_UNSIGNED_LONG_LONG_INT 1" >>confdefs.h
-
- fi
-
-
-
- ac_fn_c_check_type "$LINENO" "uintmax_t" "ac_cv_type_uintmax_t" "$ac_includes_default"
-if test "x$ac_cv_type_uintmax_t" = x""yes; then :
-
-$as_echo "#define HAVE_UINTMAX_T 1" >>confdefs.h
-
-else
- test $ac_cv_type_unsigned_long_long_int = yes \
- && ac_type='unsigned long long int' \
- || ac_type='unsigned long int'
-
-cat >>confdefs.h <<_ACEOF
-#define uintmax_t $ac_type
-_ACEOF
-
-fi
-
-
-
- ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default"
-if test "x$ac_cv_type_uintptr_t" = x""yes; then :
-
-$as_echo "#define HAVE_UINTPTR_T 1" >>confdefs.h
-
-else
- for ac_type in 'unsigned int' 'unsigned long int' \
- 'unsigned long long int'; do
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))];
-test_array [0] = 0
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-cat >>confdefs.h <<_ACEOF
-#define uintptr_t $ac_type
-_ACEOF
-
- ac_type=
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- test -z "$ac_type" && break
- done
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# ---------------------
-# Warnings and checking
-# ---------------------
-
-# Check $CC warning features (if it's GCC).
-# We want to use -pedantic, but we don't want warnings about
-# * 'long long'
-# * variadic macros
-# * overlong strings
-# * C++11 narrowing conversions in { }
-# So, we only use -pedantic if we can disable those warnings.
-
-loose_warn=
-save_CFLAGS="$CFLAGS"
-for real_option in -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual; do
- # Do the check with the no- prefix removed since gcc silently
- # accepts any -Wno-* option on purpose
- case $real_option in
- -Wno-*) option=-W`expr x$real_option : 'x-Wno-\(.*\)'` ;;
- *) option=$real_option ;;
- esac
- as_acx_Woption=`$as_echo "acx_cv_prog_cc_warning_$option" | $as_tr_sh`
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports $option" >&5
-$as_echo_n "checking whether $CC supports $option... " >&6; }
-if { as_var=$as_acx_Woption; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- CFLAGS="$option"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- eval "$as_acx_Woption=yes"
-else
- eval "$as_acx_Woption=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-fi
-eval ac_res=\$$as_acx_Woption
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- if test `eval 'as_val=${'$as_acx_Woption'};$as_echo "$as_val"'` = yes; then :
- loose_warn="$loose_warn${loose_warn:+ }$real_option"
-fi
- done
-CFLAGS="$save_CFLAGS"
-
-c_loose_warn=
-save_CFLAGS="$CFLAGS"
-for real_option in -Wstrict-prototypes -Wmissing-prototypes; do
- # Do the check with the no- prefix removed since gcc silently
- # accepts any -Wno-* option on purpose
- case $real_option in
- -Wno-*) option=-W`expr x$real_option : 'x-Wno-\(.*\)'` ;;
- *) option=$real_option ;;
- esac
- as_acx_Woption=`$as_echo "acx_cv_prog_cc_warning_$option" | $as_tr_sh`
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports $option" >&5
-$as_echo_n "checking whether $CC supports $option... " >&6; }
-if { as_var=$as_acx_Woption; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- CFLAGS="$option"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- eval "$as_acx_Woption=yes"
-else
- eval "$as_acx_Woption=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-fi
-eval ac_res=\$$as_acx_Woption
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- if test `eval 'as_val=${'$as_acx_Woption'};$as_echo "$as_val"'` = yes; then :
- c_loose_warn="$c_loose_warn${c_loose_warn:+ }$real_option"
-fi
- done
-CFLAGS="$save_CFLAGS"
-
-strict_warn=
-save_CFLAGS="$CFLAGS"
-for real_option in -Wmissing-format-attribute; do
- # Do the check with the no- prefix removed since gcc silently
- # accepts any -Wno-* option on purpose
- case $real_option in
- -Wno-*) option=-W`expr x$real_option : 'x-Wno-\(.*\)'` ;;
- *) option=$real_option ;;
- esac
- as_acx_Woption=`$as_echo "acx_cv_prog_cc_warning_$option" | $as_tr_sh`
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports $option" >&5
-$as_echo_n "checking whether $CC supports $option... " >&6; }
-if { as_var=$as_acx_Woption; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- CFLAGS="$option"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- eval "$as_acx_Woption=yes"
-else
- eval "$as_acx_Woption=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-fi
-eval ac_res=\$$as_acx_Woption
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- if test `eval 'as_val=${'$as_acx_Woption'};$as_echo "$as_val"'` = yes; then :
- strict_warn="$strict_warn${strict_warn:+ }$real_option"
-fi
- done
-CFLAGS="$save_CFLAGS"
-
-c_strict_warn=
-save_CFLAGS="$CFLAGS"
-for real_option in -Wold-style-definition -Wc++-compat; do
- # Do the check with the no- prefix removed since gcc silently
- # accepts any -Wno-* option on purpose
- case $real_option in
- -Wno-*) option=-W`expr x$real_option : 'x-Wno-\(.*\)'` ;;
- *) option=$real_option ;;
- esac
- as_acx_Woption=`$as_echo "acx_cv_prog_cc_warning_$option" | $as_tr_sh`
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports $option" >&5
-$as_echo_n "checking whether $CC supports $option... " >&6; }
-if { as_var=$as_acx_Woption; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- CFLAGS="$option"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- eval "$as_acx_Woption=yes"
-else
- eval "$as_acx_Woption=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-fi
-eval ac_res=\$$as_acx_Woption
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- if test `eval 'as_val=${'$as_acx_Woption'};$as_echo "$as_val"'` = yes; then :
- c_strict_warn="$c_strict_warn${c_strict_warn:+ }$real_option"
-fi
- done
-CFLAGS="$save_CFLAGS"
-
-# Do the check with the no- prefix removed from the warning options
-# since gcc silently accepts any -Wno-* option on purpose
-if test "$GCC" = yes; then :
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -pedantic -Wlong-long -Wvariadic-macros -Woverlength-strings" >&5
-$as_echo_n "checking whether $CC supports -pedantic -Wlong-long -Wvariadic-macros -Woverlength-strings... " >&6; }
-if test "${acx_cv_prog_cc_pedantic__Wlong_long__Wvariadic_macros__Woverlength_strings+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- save_CFLAGS="$CFLAGS"
-CFLAGS="-pedantic -Wlong-long -Wvariadic-macros -Woverlength-strings"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- acx_cv_prog_cc_pedantic__Wlong_long__Wvariadic_macros__Woverlength_strings=yes
-else
- acx_cv_prog_cc_pedantic__Wlong_long__Wvariadic_macros__Woverlength_strings=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-CFLAGS="$save_CFLAGS"
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_cv_prog_cc_pedantic__Wlong_long__Wvariadic_macros__Woverlength_strings" >&5
-$as_echo "$acx_cv_prog_cc_pedantic__Wlong_long__Wvariadic_macros__Woverlength_strings" >&6; }
-if test $acx_cv_prog_cc_pedantic__Wlong_long__Wvariadic_macros__Woverlength_strings = yes; then :
- strict_warn="$strict_warn${strict_warn:+ }-pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings"
-fi
-
-fi
-
-# Check whether --enable-werror-always was given.
-if test "${enable_werror_always+set}" = set; then :
- enableval=$enable_werror_always;
-else
- enable_werror_always=no
-fi
-
-if test $enable_werror_always = yes; then :
- strict_warn="$strict_warn${strict_warn:+ }-Werror"
-fi
-
-
-
-# The above macros do nothing if the compiler is not GCC. However, the
-# Makefile has more goo to add other flags, so these variables are used
-# to enable warnings only for GCC.
-warn_cflags=
-warn_cxxflags=
-if test "x$GCC" = "xyes"; then
- warn_cflags='$(GCC_WARN_CFLAGS)'
- warn_cxxflags='$(GCC_WARN_CXXFLAGS)'
-fi
-
-
-
-# Disable exceptions and RTTI if building with g++
-noexception_flags=
-save_CFLAGS="$CFLAGS"
-for real_option in -fno-exceptions -fno-rtti -fasynchronous-unwind-tables; do
- # Do the check with the no- prefix removed since gcc silently
- # accepts any -Wno-* option on purpose
- case $real_option in
- -Wno-*) option=-W`expr x$real_option : 'x-Wno-\(.*\)'` ;;
- *) option=$real_option ;;
- esac
- as_acx_Woption=`$as_echo "acx_cv_prog_cc_warning_$option" | $as_tr_sh`
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports $option" >&5
-$as_echo_n "checking whether $CC supports $option... " >&6; }
-if { as_var=$as_acx_Woption; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- CFLAGS="$option"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- eval "$as_acx_Woption=yes"
-else
- eval "$as_acx_Woption=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-fi
-eval ac_res=\$$as_acx_Woption
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- if test `eval 'as_val=${'$as_acx_Woption'};$as_echo "$as_val"'` = yes; then :
- noexception_flags="$noexception_flags${noexception_flags:+ }$real_option"
-fi
- done
-CFLAGS="$save_CFLAGS"
-
-
-# Enable expensive internal checks
-is_release=
-if test x"`cat $srcdir/DEV-PHASE`" != xexperimental; then
- is_release=yes
-fi
-
-# Check whether --enable-checking was given.
-if test "${enable_checking+set}" = set; then :
- enableval=$enable_checking; ac_checking_flags="${enableval}"
-else
-
-# Determine the default checks.
-if test x$is_release = x ; then
- ac_checking_flags=yes
-else
- ac_checking_flags=release
-fi
-fi
-
-IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="$IFS,"
-for check in release $ac_checking_flags
-do
- case $check in
- # these set all the flags to specific states
- yes) ac_assert_checking=1 ; ac_checking=1 ; ac_df_checking= ;
- ac_fold_checking= ; ac_gc_checking=1 ;
- ac_gc_always_collect= ; ac_gimple_checking=1 ; ac_rtl_checking= ;
- ac_rtlflag_checking=1 ; ac_runtime_checking=1 ;
- ac_tree_checking=1 ; ac_valgrind_checking= ;
- ac_types_checking=1 ;;
- no|none) ac_assert_checking= ; ac_checking= ; ac_df_checking= ;
- ac_fold_checking= ; ac_gc_checking= ;
- ac_gc_always_collect= ; ac_gimple_checking= ; ac_rtl_checking= ;
- ac_rtlflag_checking= ; ac_runtime_checking= ;
- ac_tree_checking= ; ac_valgrind_checking= ;
- ac_types_checking= ;;
- all) ac_assert_checking=1 ; ac_checking=1 ; ac_df_checking=1 ;
- ac_fold_checking=1 ; ac_gc_checking=1 ;
- ac_gc_always_collect=1 ; ac_gimple_checking=1 ; ac_rtl_checking=1 ;
- ac_rtlflag_checking=1 ; ac_runtime_checking=1 ;
- ac_tree_checking=1 ; ac_valgrind_checking= ;
- ac_types_checking=1 ;;
- release) ac_assert_checking=1 ; ac_checking= ; ac_df_checking= ;
- ac_fold_checking= ; ac_gc_checking= ;
- ac_gc_always_collect= ; ac_gimple_checking= ; ac_rtl_checking= ;
- ac_rtlflag_checking= ; ac_runtime_checking=1 ;
- ac_tree_checking= ; ac_valgrind_checking= ;
- ac_types_checking= ;;
- # these enable particular checks
- assert) ac_assert_checking=1 ;;
- df) ac_df_checking=1 ;;
- fold) ac_fold_checking=1 ;;
- gc) ac_gc_checking=1 ;;
- gcac) ac_gc_always_collect=1 ;;
- gimple) ac_gimple_checking=1 ;;
- misc) ac_checking=1 ;;
- rtl) ac_rtl_checking=1 ;;
- rtlflag) ac_rtlflag_checking=1 ;;
- runtime) ac_runtime_checking=1 ;;
- tree) ac_tree_checking=1 ;;
- types) ac_types_checking=1 ;;
- valgrind) ac_valgrind_checking=1 ;;
- *) as_fn_error "unknown check category $check" "$LINENO" 5 ;;
- esac
-done
-IFS="$ac_save_IFS"
-
-nocommon_flag=""
-if test x$ac_checking != x ; then
-
-$as_echo "#define ENABLE_CHECKING 1" >>confdefs.h
-
- nocommon_flag=-fno-common
-fi
-
-if test x$ac_df_checking != x ; then
-
-$as_echo "#define ENABLE_DF_CHECKING 1" >>confdefs.h
-
-fi
-if test x$ac_assert_checking != x ; then
-
-$as_echo "#define ENABLE_ASSERT_CHECKING 1" >>confdefs.h
-
-fi
-if test x$ac_gimple_checking != x ; then
-
-$as_echo "#define ENABLE_GIMPLE_CHECKING 1" >>confdefs.h
-
-fi
-
-if test x$ac_runtime_checking != x ; then
-
-$as_echo "#define ENABLE_RUNTIME_CHECKING 1" >>confdefs.h
-
-fi
-if test x$ac_tree_checking != x ; then
-
-$as_echo "#define ENABLE_TREE_CHECKING 1" >>confdefs.h
-
- TREEBROWSER=tree-browser.o
- TREECHECKING=yes
-fi
-if test x$ac_types_checking != x ; then
-
-$as_echo "#define ENABLE_TYPES_CHECKING 1" >>confdefs.h
-
-fi
-
-
-if test x$ac_rtl_checking != x ; then
-
-$as_echo "#define ENABLE_RTL_CHECKING 1" >>confdefs.h
-
-fi
-if test x$ac_rtlflag_checking != x ; then
-
-$as_echo "#define ENABLE_RTL_FLAG_CHECKING 1" >>confdefs.h
-
-fi
-if test x$ac_gc_checking != x ; then
-
-$as_echo "#define ENABLE_GC_CHECKING 1" >>confdefs.h
-
-fi
-if test x$ac_gc_always_collect != x ; then
-
-$as_echo "#define ENABLE_GC_ALWAYS_COLLECT 1" >>confdefs.h
-
-fi
-if test x$ac_fold_checking != x ; then
-
-$as_echo "#define ENABLE_FOLD_CHECKING 1" >>confdefs.h
-
-fi
-valgrind_path_defines=
-valgrind_command=
-
-ac_fn_c_check_header_mongrel "$LINENO" "valgrind.h" "ac_cv_header_valgrind_h" "$ac_includes_default"
-if test "x$ac_cv_header_valgrind_h" = x""yes; then :
- have_valgrind_h=yes
-else
- have_valgrind_h=no
-fi
-
-
-
-if test x$ac_valgrind_checking != x ; then
- # It is certainly possible that there's valgrind but no valgrind.h.
- # GCC relies on making annotations so we must have both.
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for VALGRIND_DISCARD in <valgrind/memcheck.h>" >&5
-$as_echo_n "checking for VALGRIND_DISCARD in <valgrind/memcheck.h>... " >&6; }
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <valgrind/memcheck.h>
-#ifndef VALGRIND_DISCARD
-#error VALGRIND_DISCARD not defined
-#endif
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
- gcc_cv_header_valgrind_memcheck_h=yes
-else
- gcc_cv_header_valgrind_memcheck_h=no
-fi
-rm -f conftest.err conftest.$ac_ext
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_header_valgrind_memcheck_h" >&5
-$as_echo "$gcc_cv_header_valgrind_memcheck_h" >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for VALGRIND_DISCARD in <memcheck.h>" >&5
-$as_echo_n "checking for VALGRIND_DISCARD in <memcheck.h>... " >&6; }
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <memcheck.h>
-#ifndef VALGRIND_DISCARD
-#error VALGRIND_DISCARD not defined
-#endif
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
- gcc_cv_header_memcheck_h=yes
-else
- gcc_cv_header_memcheck_h=no
-fi
-rm -f conftest.err conftest.$ac_ext
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_header_memcheck_h" >&5
-$as_echo "$gcc_cv_header_memcheck_h" >&6; }
-
-# Prepare PATH_SEPARATOR.
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- echo "#! /bin/sh" >conf$$.sh
- echo "exit 0" >>conf$$.sh
- chmod +x conf$$.sh
- if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
- PATH_SEPARATOR=';'
- else
- PATH_SEPARATOR=:
- fi
- rm -f conf$$.sh
-fi
-
-# Find out how to test for executable files. Don't use a zero-byte file,
-# as systems may use methods other than mode bits to determine executability.
-cat >conf$$.file <<_ASEOF
-#! /bin/sh
-exit 0
-_ASEOF
-chmod +x conf$$.file
-if test -x conf$$.file >/dev/null 2>&1; then
- ac_executable_p="test -x"
-else
- ac_executable_p="test -f"
-fi
-rm -f conf$$.file
-
-# Extract the first word of "valgrind", so it can be a program name with args.
-set dummy valgrind; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_valgrind_path+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- case "$valgrind_path" in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_valgrind_path="$valgrind_path" # Let the user override the test with a path.
- ;;
- *)
- ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in $PATH; do
- IFS="$ac_save_IFS"
- test -z "$ac_dir" && ac_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
- if $ac_dir/$ac_word --version | grep valgrind- >/dev/null 2>&1; then
- ac_cv_path_valgrind_path="$ac_dir/$ac_word$ac_exec_ext"
- break 2
- fi
- fi
- done
- done
- IFS="$ac_save_IFS"
- ;;
-esac
-fi
-valgrind_path="$ac_cv_path_valgrind_path"
-if test -n "$valgrind_path"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $valgrind_path" >&5
-$as_echo "$valgrind_path" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$valgrind_path" = "x" \
- || (test $have_valgrind_h = no \
- && test $gcc_cv_header_memcheck_h = no \
- && test $gcc_cv_header_valgrind_memcheck_h = no); then
- as_fn_error "*** Can't find both valgrind and valgrind/memcheck.h, memcheck.h or valgrind.h" "$LINENO" 5
- fi
- valgrind_path_defines=-DVALGRIND_PATH='\"'$valgrind_path'\"'
- valgrind_command="$valgrind_path -q"
-
-$as_echo "#define ENABLE_VALGRIND_CHECKING 1" >>confdefs.h
-
- if test $gcc_cv_header_valgrind_memcheck_h = yes; then
-
-$as_echo "#define HAVE_VALGRIND_MEMCHECK_H 1" >>confdefs.h
-
- fi
- if test $gcc_cv_header_memcheck_h = yes; then
-
-$as_echo "#define HAVE_MEMCHECK_H 1" >>confdefs.h
-
- fi
-fi
-
-
-
-# Enable code coverage collection
-# Check whether --enable-coverage was given.
-if test "${enable_coverage+set}" = set; then :
- enableval=$enable_coverage; case "${enableval}" in
- yes|noopt)
- coverage_flags="-fprofile-arcs -ftest-coverage -frandom-seed=\$@ -O0"
- ;;
- opt)
- coverage_flags="-fprofile-arcs -ftest-coverage -frandom-seed=\$@ -O2"
- ;;
- no)
- # a.k.a. --disable-coverage
- coverage_flags=""
- ;;
- *)
- as_fn_error "unknown coverage setting $enableval" "$LINENO" 5
- ;;
-esac
-else
- coverage_flags=""
-fi
-
-
-
-# Check whether --enable-gather-detailed-mem-stats was given.
-if test "${enable_gather_detailed_mem_stats+set}" = set; then :
- enableval=$enable_gather_detailed_mem_stats;
-else
- enable_gather_detailed_mem_stats=no
-fi
-
-gather_stats=`if test $enable_gather_detailed_mem_stats != no; then echo 1; else echo 0; fi`
-
-cat >>confdefs.h <<_ACEOF
-#define GATHER_STATISTICS $gather_stats
-_ACEOF
-
-
-# -------------------------------
-# Miscenalleous configure options
-# -------------------------------
-
-# With stabs
-
-# Check whether --with-stabs was given.
-if test "${with_stabs+set}" = set; then :
- withval=$with_stabs; stabs="$with_stabs"
-else
- stabs=no
-fi
-
-
-# Determine whether or not multilibs are enabled.
-# Check whether --enable-multilib was given.
-if test "${enable_multilib+set}" = set; then :
- enableval=$enable_multilib;
-else
- enable_multilib=yes
-fi
-
-
-
-# Determine whether or not multiarch is enabled.
-# Check whether --enable-multiarch was given.
-if test "${enable_multiarch+set}" = set; then :
- enableval=$enable_multiarch; case "${enableval}" in
-yes|no|auto) enable_multiarch=$enableval;;
-*) as_fn_error "bad value ${enableval} given for --enable-multiarch option" "$LINENO" 5 ;;
-esac
-else
- enable_multiarch=auto
-fi
-
-if test x${enable_multiarch} = xauto; then
- if test x${with_native_system_header_dir} != x; then
- ma_msg_suffix=", disabled auto check (configured with --native-system-header-dir)"
- enable_multiarch=no
- fi
- if test x$host != x$target && test "x$with_sysroot" = x; then
- ma_msg_suffix=", disabled auto check (cross build configured without --with-sysroot)"
- enable_multiarch=no
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for multiarch configuration" >&5
-$as_echo_n "checking for multiarch configuration... " >&6; }
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_multiarch$ma_msg_suffix" >&5
-$as_echo "$enable_multiarch$ma_msg_suffix" >&6; }
-
-# needed for setting the multiarch name for soft-float/hard-float ABIs
-
-
-
-# Enable __cxa_atexit for C++.
-# Check whether --enable-__cxa_atexit was given.
-if test "${enable___cxa_atexit+set}" = set; then :
- enableval=$enable___cxa_atexit;
-fi
-
-
-# Enable C extension for decimal float if target supports it.
-
-# Check whether --enable-decimal-float was given.
-if test "${enable_decimal_float+set}" = set; then :
- enableval=$enable_decimal_float;
- case $enable_decimal_float in
- yes | no | bid | dpd) default_decimal_float=$enable_decimal_float ;;
- *) as_fn_error "'$enable_decimal_float' is an invalid value for --enable-decimal-float.
-Valid choices are 'yes', 'bid', 'dpd', and 'no'." "$LINENO" 5 ;;
- esac
-
-else
-
- case $target in
- powerpc*-*-linux* | i?86*-*-linux* | x86_64*-*-linux* | s390*-*-linux* | \
- i?86*-*-gnu* | \
- i?86*-*-mingw* | x86_64*-*-mingw* | \
- i?86*-*-cygwin*)
- enable_decimal_float=yes
- ;;
- *)
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: decimal float is not supported for this target, ignored" >&5
-$as_echo "$as_me: WARNING: decimal float is not supported for this target, ignored" >&2;}
- enable_decimal_float=no
- ;;
- esac
-
-fi
-
-
-# x86's use BID format instead of DPD
-case x$enable_decimal_float in
- xyes)
- case $target in
- i?86*-*-* | x86_64*-*-*)
- enable_decimal_float=bid
- ;;
- *)
- enable_decimal_float=dpd
- ;;
- esac
- default_decimal_float=$enable_decimal_float
- ;;
- xno)
- # ENABLE_DECIMAL_FLOAT is set to 0. But we have to have proper
- # dependency on libdecnumber.
- default_decimal_float=dpd
- ;;
-esac
-
-
-
-
-dfp=`if test $enable_decimal_float != no; then echo 1; else echo 0; fi`
-
-cat >>confdefs.h <<_ACEOF
-#define ENABLE_DECIMAL_FLOAT $dfp
-_ACEOF
-
-
-# Use default_decimal_float for dependency.
-enable_decimal_float=$default_decimal_float
-
-bid=`if test $enable_decimal_float = bid; then echo 1; else echo 0; fi`
-
-cat >>confdefs.h <<_ACEOF
-#define ENABLE_DECIMAL_BID_FORMAT $bid
-_ACEOF
-
-
-# Enable C extension for fixed-point arithmetic.
-# Check whether --enable-fixed-point was given.
-if test "${enable_fixed_point+set}" = set; then :
- enableval=$enable_fixed_point;
-else
-
- case $target in
- arm*)
- enable_fixed_point=yes
- ;;
-
- mips*-*-*)
- enable_fixed_point=yes
- ;;
- *)
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: fixed-point is not supported for this target, ignored" >&5
-$as_echo "$as_me: WARNING: fixed-point is not supported for this target, ignored" >&2;}
- enable_fixed_point=no
- ;;
- esac
-
-fi
-
-
-
-fixedpoint=`if test $enable_fixed_point = yes; then echo 1; else echo 0; fi`
-
-cat >>confdefs.h <<_ACEOF
-#define ENABLE_FIXED_POINT $fixedpoint
-_ACEOF
-
-
-# Enable threads
-# Pass with no value to take the default
-# Pass with a value to specify a thread package
-# Check whether --enable-threads was given.
-if test "${enable_threads+set}" = set; then :
- enableval=$enable_threads;
-else
- enable_threads=''
-fi
-
-
-# Check whether --enable-tls was given.
-if test "${enable_tls+set}" = set; then :
- enableval=$enable_tls;
- case $enable_tls in
- yes | no) ;;
- *) as_fn_error "'$enable_tls' is an invalid value for --enable-tls.
-Valid choices are 'yes' and 'no'." "$LINENO" 5 ;;
- esac
-
-else
- enable_tls=''
-fi
-
-
-# Check whether --enable-objc-gc was given.
-if test "${enable_objc_gc+set}" = set; then :
- enableval=$enable_objc_gc; if test x$enable_objc_gc = xno; then
- objc_boehm_gc=''
-else
- objc_boehm_gc=1
-fi
-else
- objc_boehm_gc=''
-fi
-
-
-
-# Check whether --with-dwarf2 was given.
-if test "${with_dwarf2+set}" = set; then :
- withval=$with_dwarf2; dwarf2="$with_dwarf2"
-else
- dwarf2=no
-fi
-
-
-# Check whether --enable-shared was given.
-if test "${enable_shared+set}" = set; then :
- enableval=$enable_shared;
- case $enable_shared in
- yes | no) ;;
- *)
- enable_shared=no
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
- for pkg in $enableval; do
- if test "X$pkg" = "Xgcc" || test "X$pkg" = "Xlibgcc"; then
- enable_shared=yes
- fi
- done
- IFS="$ac_save_ifs"
- ;;
- esac
-
-else
- enable_shared=yes
-fi
-
-
-
-
-# Check whether --with-native-system-header-dir was given.
-if test "${with_native_system_header_dir+set}" = set; then :
- withval=$with_native_system_header_dir;
- case ${with_native_system_header_dir} in
- yes|no) as_fn_error "bad value ${withval} given for --with-native-system-header-dir" "$LINENO" 5 ;;
- /* | [A-Za-z]:[\\/]*) ;;
- *) as_fn_error "--with-native-system-header-dir argument ${withval} must be an absolute directory" "$LINENO" 5 ;;
- esac
- configured_native_system_header_dir="${withval}"
-
-else
- configured_native_system_header_dir=
-fi
-
-
-
-# Check whether --with-build-sysroot was given.
-if test "${with_build_sysroot+set}" = set; then :
- withval=$with_build_sysroot; if test x"$withval" != x ; then
- SYSROOT_CFLAGS_FOR_TARGET="--sysroot=$withval"
- fi
-else
- SYSROOT_CFLAGS_FOR_TARGET=
-fi
-
-
-
-if test "x$prefix" = xNONE; then
- test_prefix=/usr/local
-else
- test_prefix=$prefix
-fi
-if test "x$exec_prefix" = xNONE; then
- test_exec_prefix=$test_prefix
-else
- test_exec_prefix=$exec_prefix
-fi
-
-
-# Check whether --with-sysroot was given.
-if test "${with_sysroot+set}" = set; then :
- withval=$with_sysroot;
- case ${with_sysroot} in
- yes) TARGET_SYSTEM_ROOT='${exec_prefix}/${target_noncanonical}/sys-root' ;;
- *) TARGET_SYSTEM_ROOT=$with_sysroot ;;
- esac
-
- TARGET_SYSTEM_ROOT_DEFINE='-DTARGET_SYSTEM_ROOT=\"$(TARGET_SYSTEM_ROOT)\"'
- CROSS_SYSTEM_HEADER_DIR='$(TARGET_SYSTEM_ROOT)$${sysroot_headers_suffix}$(NATIVE_SYSTEM_HEADER_DIR)'
-
- case ${TARGET_SYSTEM_ROOT} in
- "${test_prefix}"|"${test_prefix}/"*|\
- "${test_exec_prefix}"|"${test_exec_prefix}/"*|\
- '${prefix}'|'${prefix}/'*|\
- '${exec_prefix}'|'${exec_prefix}/'*)
- t="$TARGET_SYSTEM_ROOT_DEFINE -DTARGET_SYSTEM_ROOT_RELOCATABLE"
- TARGET_SYSTEM_ROOT_DEFINE="$t"
- ;;
- esac
-
-else
-
- TARGET_SYSTEM_ROOT=
- TARGET_SYSTEM_ROOT_DEFINE=
- CROSS_SYSTEM_HEADER_DIR='$(gcc_tooldir)/sys-include'
-
-fi
-
-
-
-
-
-
-# Check whether --with-specs was given.
-if test "${with_specs+set}" = set; then :
- withval=$with_specs; CONFIGURE_SPECS=$withval
-else
- CONFIGURE_SPECS=
-
-fi
-
-
-
-
-
-# Check whether --with-pkgversion was given.
-if test "${with_pkgversion+set}" = set; then :
- withval=$with_pkgversion; case "$withval" in
- yes) as_fn_error "package version not specified" "$LINENO" 5 ;;
- no) PKGVERSION= ;;
- *) PKGVERSION="($withval) " ;;
- esac
-else
- PKGVERSION="(GCC) "
-
-fi
-
-
-
-
-
-# Check whether --with-bugurl was given.
-if test "${with_bugurl+set}" = set; then :
- withval=$with_bugurl; case "$withval" in
- yes) as_fn_error "bug URL not specified" "$LINENO" 5 ;;
- no) BUGURL=
- ;;
- *) BUGURL="$withval"
- ;;
- esac
-else
- BUGURL="http://gcc.gnu.org/bugs.html"
-
-fi
-
- case ${BUGURL} in
- "")
- REPORT_BUGS_TO=
- REPORT_BUGS_TEXI=
- ;;
- *)
- REPORT_BUGS_TO="<$BUGURL>"
- REPORT_BUGS_TEXI=@uref{`echo "$BUGURL" | sed 's/@/@@/g'`}
- ;;
- esac;
-
-
-
-
-# Sanity check enable_languages in case someone does not run the toplevel
-# configure # script.
-# Check whether --enable-languages was given.
-if test "${enable_languages+set}" = set; then :
- enableval=$enable_languages; case ,${enable_languages}, in
- ,,|,yes,)
- # go safe -- we cannot be much sure without the toplevel
- # configure's
- # analysis of which target libs are present and usable
- enable_languages=c
- ;;
- *,all,*)
- as_fn_error "only the toplevel supports --enable-languages=all" "$LINENO" 5
- ;;
- *,c,*)
- ;;
- *)
- enable_languages=c,${enable_languages}
- ;;
-esac
-else
- enable_languages=c
-fi
-
-
-
-# Check whether --with-multilib-list was given.
-if test "${with_multilib_list+set}" = set; then :
- withval=$with_multilib_list; :
-else
- with_multilib_list=default
-fi
-
-
-# -------------------------
-# Checks for other programs
-# -------------------------
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
-$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
-set x ${MAKE-make}
-ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
-if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- cat >conftest.make <<\_ACEOF
-SHELL = /bin/sh
-all:
- @echo '@@@%%%=$(MAKE)=@@@%%%'
-_ACEOF
-# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
-case `${MAKE-make} -f conftest.make 2>/dev/null` in
- *@@@%%%=?*=@@@%%%*)
- eval ac_cv_prog_make_${ac_make}_set=yes;;
- *)
- eval ac_cv_prog_make_${ac_make}_set=no;;
-esac
-rm -f conftest.make
-fi
-if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- SET_MAKE=
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
- SET_MAKE="MAKE=${MAKE-make}"
-fi
-
-
-# Find some useful tools
-for ac_prog in gawk mawk nawk awk
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_AWK+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$AWK"; then
- ac_cv_prog_AWK="$AWK" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_AWK="$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-AWK=$ac_cv_prog_AWK
-if test -n "$AWK"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
-$as_echo "$AWK" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$AWK" && break
-done
-
-# We need awk to create options.c and options.h.
-# Bail out if it's missing.
-case ${AWK} in
- "") as_fn_error "can't build without awk, bailing out" "$LINENO" 5 ;;
-esac
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
-$as_echo_n "checking whether ln -s works... " >&6; }
-if test "${gcc_cv_prog_LN_S+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- rm -f conftestdata_t
-echo >conftestdata_f
-if ln -s conftestdata_f conftestdata_t 2>/dev/null
-then
- gcc_cv_prog_LN_S="ln -s"
-else
- if ln conftestdata_f conftestdata_t 2>/dev/null
- then
- gcc_cv_prog_LN_S=ln
- else
- if cp -p conftestdata_f conftestdata_t 2>/dev/null
- then
- gcc_cv_prog_LN_S="cp -p"
- else
- gcc_cv_prog_LN_S=cp
- fi
- fi
-fi
-rm -f conftestdata_f conftestdata_t
-
-fi
-LN_S="$gcc_cv_prog_LN_S"
-if test "$gcc_cv_prog_LN_S" = "ln -s"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-else
- if test "$gcc_cv_prog_LN_S" = "ln"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using ln" >&5
-$as_echo "no, using ln" >&6; }
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, and neither does ln, so using $gcc_cv_prog_LN_S" >&5
-$as_echo "no, and neither does ln, so using $gcc_cv_prog_LN_S" >&6; }
- fi
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln works" >&5
-$as_echo_n "checking whether ln works... " >&6; }
-if test "${acx_cv_prog_LN+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- rm -f conftestdata_t
-echo >conftestdata_f
-if ln conftestdata_f conftestdata_t 2>/dev/null
-then
- acx_cv_prog_LN=ln
-else
- acx_cv_prog_LN=no
-fi
-rm -f conftestdata_f conftestdata_t
-
-fi
-if test $acx_cv_prog_LN = no; then
- LN="$LN_S"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN" >&5
-$as_echo "no, using $LN" >&6; }
-else
- LN="$acx_cv_prog_LN"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-fi
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ranlib; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_RANLIB+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$RANLIB"; then
- ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-RANLIB=$ac_cv_prog_RANLIB
-if test -n "$RANLIB"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
-$as_echo "$RANLIB" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_RANLIB"; then
- ac_ct_RANLIB=$RANLIB
- # Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_RANLIB"; then
- ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_RANLIB="ranlib"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
-if test -n "$ac_ct_RANLIB"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
-$as_echo "$ac_ct_RANLIB" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_RANLIB" = x; then
- RANLIB=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- RANLIB=$ac_ct_RANLIB
- fi
-else
- RANLIB="$ac_cv_prog_RANLIB"
-fi
-
-ranlib_flags=""
-
-
-# Find a good install program. We prefer a C program (faster),
-# so one script is as good as another. But avoid the broken or
-# incompatible versions:
-# SysV /etc/install, /usr/sbin/install
-# SunOS /usr/etc/install
-# IRIX /sbin/install
-# AIX /bin/install
-# AFS /usr/afsws/bin/install, which mishandles nonexistent args
-# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
-# ./install, which can be erroneously created by make from ./install.sh.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD compatible install" >&5
-$as_echo_n "checking for a BSD compatible install... " >&6; }
-if test -z "$INSTALL"; then
-if test "${ac_cv_path_install+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
- # Account for people who put trailing slashes in PATH elements.
- case "$ac_dir/" in
- /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
- *)
- # OSF1 and SCO ODT 3.0 have their own names for install.
- for ac_prog in ginstall scoinst install; do
- if test -f $ac_dir/$ac_prog; then
- if test $ac_prog = install &&
- grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
- # AIX install. It has an incompatible calling convention.
- # OSF/1 installbsd also uses dspmsg, but is usable.
- :
- else
- ac_cv_path_install="$ac_dir/$ac_prog -c"
- break 2
- fi
- fi
- done
- ;;
- esac
- done
- IFS="$ac_save_IFS"
-
-fi
- if test "${ac_cv_path_install+set}" = set; then
- INSTALL="$ac_cv_path_install"
- else
- # As a last resort, use the slow shell script. We don't cache a
- # path for INSTALL within a source directory, because that will
- # break other packages using the cache if that directory is
- # removed, or if the path is relative.
- INSTALL="$ac_install_sh"
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
-$as_echo "$INSTALL" >&6; }
-
-# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
-# It thinks the first close brace ends the variable substitution.
-test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
-
-test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
-
-
-# See if cmp has --ignore-initial.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cmp's capabilities" >&5
-$as_echo_n "checking for cmp's capabilities... " >&6; }
-if test "${gcc_cv_prog_cmp_skip+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- echo abfoo >t1
- echo cdfoo >t2
- gcc_cv_prog_cmp_skip=slowcompare
- if cmp --ignore-initial=2 t1 t2 > /dev/null 2>&1; then
- if cmp --ignore-initial=1 t1 t2 > /dev/null 2>&1; then
- :
- else
- gcc_cv_prog_cmp_skip=gnucompare
- fi
- fi
- if test $gcc_cv_prog_cmp_skip = slowcompare ; then
- if cmp t1 t2 2 2 > /dev/null 2>&1; then
- if cmp t1 t2 1 1 > /dev/null 2>&1; then
- :
- else
- gcc_cv_prog_cmp_skip=fastcompare
- fi
- fi
- fi
- rm t1 t2
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_prog_cmp_skip" >&5
-$as_echo "$gcc_cv_prog_cmp_skip" >&6; }
-make_compare_target=$gcc_cv_prog_cmp_skip
-
-
-
-# See if we have the mktemp command.
-# Extract the first word of "mktemp", so it can be a program name with args.
-set dummy mktemp; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_have_mktemp_command+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$have_mktemp_command"; then
- ac_cv_prog_have_mktemp_command="$have_mktemp_command" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_have_mktemp_command="yes"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
- test -z "$ac_cv_prog_have_mktemp_command" && ac_cv_prog_have_mktemp_command="no"
-fi
-fi
-have_mktemp_command=$ac_cv_prog_have_mktemp_command
-if test -n "$have_mktemp_command"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_mktemp_command" >&5
-$as_echo "$have_mktemp_command" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-
-# See if makeinfo has been installed and is modern enough
-# that we can use it.
-
- # Extract the first word of "makeinfo", so it can be a program name with args.
-set dummy makeinfo; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_MAKEINFO+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$MAKEINFO"; then
- ac_cv_prog_MAKEINFO="$MAKEINFO" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_MAKEINFO="makeinfo"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-MAKEINFO=$ac_cv_prog_MAKEINFO
-if test -n "$MAKEINFO"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKEINFO" >&5
-$as_echo "$MAKEINFO" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- if test -n "$MAKEINFO"; then
- # Found it, now check the version.
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for modern makeinfo" >&5
-$as_echo_n "checking for modern makeinfo... " >&6; }
-if test "${gcc_cv_prog_makeinfo_modern+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_prog_version=`eval $MAKEINFO --version 2>&1 |
- sed -n 's/^.*GNU texinfo.* \([0-9][0-9.]*\).*$/\1/p'`
-
- case $ac_prog_version in
- '') gcc_cv_prog_makeinfo_modern=no;;
- 4.[7-9]*|4.[1-9][0-9]*|[5-9]*|[1-9][0-9]*) gcc_cv_prog_makeinfo_modern=yes;;
- *) gcc_cv_prog_makeinfo_modern=no;;
- esac
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_prog_makeinfo_modern" >&5
-$as_echo "$gcc_cv_prog_makeinfo_modern" >&6; }
- else
- gcc_cv_prog_makeinfo_modern=no
- fi
- if test $gcc_cv_prog_makeinfo_modern = no; then
- MAKEINFO="${CONFIG_SHELL-/bin/sh} $ac_aux_dir/missing makeinfo"
- fi
-
-if test $gcc_cv_prog_makeinfo_modern = no; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
-*** Makeinfo is missing or too old.
-*** Info documentation will not be built." >&5
-$as_echo "$as_me: WARNING:
-*** Makeinfo is missing or too old.
-*** Info documentation will not be built." >&2;}
- BUILD_INFO=
-else
- BUILD_INFO=info
-fi
-
-
-# Is pod2man recent enough to regenerate manpages?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for recent Pod::Man" >&5
-$as_echo_n "checking for recent Pod::Man... " >&6; }
-if (perl -e 'use 1.10 Pod::Man') >/dev/null 2>&1; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- GENERATED_MANPAGES=generated-manpages
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
- GENERATED_MANPAGES=
-fi
-
-
-MISSING="${CONFIG_SHELL-/bin/sh} $ac_aux_dir/missing"
-
-# How about lex?
-for ac_prog in flex
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_FLEX+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$FLEX"; then
- ac_cv_prog_FLEX="$FLEX" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_FLEX="$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-FLEX=$ac_cv_prog_FLEX
-if test -n "$FLEX"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FLEX" >&5
-$as_echo "$FLEX" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$FLEX" && break
-done
-test -n "$FLEX" || FLEX="$MISSING flex"
-
-
-# Bison?
-for ac_prog in bison
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_BISON+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$BISON"; then
- ac_cv_prog_BISON="$BISON" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_BISON="$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-BISON=$ac_cv_prog_BISON
-if test -n "$BISON"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BISON" >&5
-$as_echo "$BISON" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$BISON" && break
-done
-test -n "$BISON" || BISON="$MISSING bison"
-
-
-# Binutils are not build modules, unlike bison/flex/makeinfo. So we
-# check for build == host before using them.
-
-# NM
-if test x${build} = x${host} && test -f $srcdir/../binutils/nm.c \
- && test -d ../binutils ; then
- NM='${objdir}/../binutils/nm-new'
-else
- # Extract the first word of "nm", so it can be a program name with args.
-set dummy nm; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_NM+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$NM"; then
- ac_cv_prog_NM="$NM" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_NM="nm"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
- test -z "$ac_cv_prog_NM" && ac_cv_prog_NM="${CONFIG_SHELL-/bin/sh} ${srcdir}/../missing nm"
-fi
-fi
-NM=$ac_cv_prog_NM
-if test -n "$NM"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NM" >&5
-$as_echo "$NM" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-
-# AR
-if test x${build} = x${host} && test -f $srcdir/../binutils/ar.c \
- && test -d ../binutils ; then
- AR='${objdir}/../binutils/ar'
-else
- # Extract the first word of "ar", so it can be a program name with args.
-set dummy ar; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_AR+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$AR"; then
- ac_cv_prog_AR="$AR" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_AR="ar"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
- test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="${CONFIG_SHELL-/bin/sh} ${srcdir}/../missing ar"
-fi
-fi
-AR=$ac_cv_prog_AR
-if test -n "$AR"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
-$as_echo "$AR" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-
-
-# --------------------
-# Checks for C headers
-# --------------------
-
-# Need to reject headers which give warnings, so that the -Werror bootstrap
-# works later. *sigh* This needs to come before all header checks.
-
-ac_c_preproc_warn_flag=yes
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
-$as_echo_n "checking for ANSI C header files... " >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_header_stdc=yes
-else
- ac_cv_header_stdc=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
- # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "memchr" >/dev/null 2>&1; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "free" >/dev/null 2>&1; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
- if test "$cross_compiling" = yes; then :
- :
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
- (('a' <= (c) && (c) <= 'i') \
- || ('j' <= (c) && (c) <= 'r') \
- || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
- int i;
- for (i = 0; i < 256; i++)
- if (XOR (islower (i), ISLOWER (i))
- || toupper (i) != TOUPPER (i))
- return 2;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
-$as_echo "$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-$as_echo "#define STDC_HEADERS 1" >>confdefs.h
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
-$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
-if test "${ac_cv_header_time+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
-#include <sys/time.h>
-#include <time.h>
-
-int
-main ()
-{
-if ((struct tm *) 0)
-return 0;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_header_time=yes
-else
- ac_cv_header_time=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
-$as_echo "$ac_cv_header_time" >&6; }
-if test $ac_cv_header_time = yes; then
-
-$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether string.h and strings.h may both be included" >&5
-$as_echo_n "checking whether string.h and strings.h may both be included... " >&6; }
-if test "${gcc_cv_header_string+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <string.h>
-#include <strings.h>
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- gcc_cv_header_string=yes
-else
- gcc_cv_header_string=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_header_string" >&5
-$as_echo "$gcc_cv_header_string" >&6; }
-if test $gcc_cv_header_string = yes; then
-
-$as_echo "#define STRING_WITH_STRINGS 1" >>confdefs.h
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5
-$as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; }
-if test "${ac_cv_header_sys_wait_h+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
-#include <sys/wait.h>
-#ifndef WEXITSTATUS
-# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8)
-#endif
-#ifndef WIFEXITED
-# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
-#endif
-
-int
-main ()
-{
- int s;
- wait (&s);
- s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_header_sys_wait_h=yes
-else
- ac_cv_header_sys_wait_h=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5
-$as_echo "$ac_cv_header_sys_wait_h" >&6; }
-if test $ac_cv_header_sys_wait_h = yes; then
-
-$as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h
-
-fi
-
-for ac_header in limits.h stddef.h string.h strings.h stdlib.h time.h iconv.h \
- fcntl.h unistd.h sys/file.h sys/time.h sys/mman.h \
- sys/resource.h sys/param.h sys/times.h sys/stat.h \
- direct.h malloc.h langinfo.h ldfcn.h locale.h wchar.h
-do :
- as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_preproc "$LINENO" "$ac_header" "$as_ac_Header"
-eval as_val=\$$as_ac_Header
- if test "x$as_val" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-done
-
-
-# Check for thread headers.
-ac_fn_c_check_header_preproc "$LINENO" "thread.h" "ac_cv_header_thread_h"
-if test "x$ac_cv_header_thread_h" = x""yes; then :
- have_thread_h=yes
-else
- have_thread_h=
-fi
-
-ac_fn_c_check_header_preproc "$LINENO" "pthread.h" "ac_cv_header_pthread_h"
-if test "x$ac_cv_header_pthread_h" = x""yes; then :
- have_pthread_h=yes
-else
- have_pthread_h=
-fi
-
-
-# These tests can't be done till we know if we have limits.h.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CHAR_BIT" >&5
-$as_echo_n "checking for CHAR_BIT... " >&6; }
-if test "${gcc_cv_decl_char_bit+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-#ifdef CHAR_BIT
-found
-#endif
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "found" >/dev/null 2>&1; then :
- gcc_cv_decl_char_bit=yes
-else
- gcc_cv_decl_char_bit=no
-fi
-rm -f conftest*
-
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_decl_char_bit" >&5
-$as_echo "$gcc_cv_decl_char_bit" >&6; }
-if test $gcc_cv_decl_char_bit = no; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking number of bits in a byte" >&5
-$as_echo_n "checking number of bits in a byte... " >&6; }
-if test "${gcc_cv_c_nbby+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- i=8
- gcc_cv_c_nbby=
- while test $i -lt 65; do
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-switch(0) {
- case (unsigned char)((unsigned long)1 << $i) == ((unsigned long)1 << $i):
- case (unsigned char)((unsigned long)1<<($i-1)) == ((unsigned long)1<<($i-1)):
- ; }
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- gcc_cv_c_nbby=$i; break
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- i=`expr $i + 1`
- done
- test -z "$gcc_cv_c_nbby" && gcc_cv_c_nbby=failed
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_c_nbby" >&5
-$as_echo "$gcc_cv_c_nbby" >&6; }
-if test $gcc_cv_c_nbby = failed; then
- as_fn_error "cannot determine number of bits in a byte" "$LINENO" 5
-else
-
-cat >>confdefs.h <<_ACEOF
-#define CHAR_BIT $gcc_cv_c_nbby
-_ACEOF
-
-fi
-fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
-$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
-if test "${ac_cv_c_bigendian+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_cv_c_bigendian=unknown
- # See if we're dealing with a universal compiler.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifndef __APPLE_CC__
- not a universal capable compiler
- #endif
- typedef int dummy;
-
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
- # Check for potential -arch flags. It is not universal unless
- # there are at least two -arch flags with different values.
- ac_arch=
- ac_prev=
- for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
- if test -n "$ac_prev"; then
- case $ac_word in
- i?86 | x86_64 | ppc | ppc64)
- if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
- ac_arch=$ac_word
- else
- ac_cv_c_bigendian=universal
- break
- fi
- ;;
- esac
- ac_prev=
- elif test "x$ac_word" = "x-arch"; then
- ac_prev=arch
- fi
- done
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- if test $ac_cv_c_bigendian = unknown; then
- # See if sys/param.h defines the BYTE_ORDER macro.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
- #include <sys/param.h>
-
-int
-main ()
-{
-#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
- && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
- && LITTLE_ENDIAN)
- bogus endian macros
- #endif
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- # It does; now see whether it defined to BIG_ENDIAN or not.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
- #include <sys/param.h>
-
-int
-main ()
-{
-#if BYTE_ORDER != BIG_ENDIAN
- not big endian
- #endif
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_c_bigendian=yes
-else
- ac_cv_c_bigendian=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- fi
- if test $ac_cv_c_bigendian = unknown; then
- # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <limits.h>
-
-int
-main ()
-{
-#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
- bogus endian macros
- #endif
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- # It does; now see whether it defined to _BIG_ENDIAN or not.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <limits.h>
-
-int
-main ()
-{
-#ifndef _BIG_ENDIAN
- not big endian
- #endif
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_c_bigendian=yes
-else
- ac_cv_c_bigendian=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- fi
- if test $ac_cv_c_bigendian = unknown; then
- # Compile a test program.
- if test "$cross_compiling" = yes; then :
- # Try to guess by grepping values from an object file.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-short int ascii_mm[] =
- { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
- short int ascii_ii[] =
- { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
- int use_ascii (int i) {
- return ascii_mm[i] + ascii_ii[i];
- }
- short int ebcdic_ii[] =
- { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
- short int ebcdic_mm[] =
- { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
- int use_ebcdic (int i) {
- return ebcdic_mm[i] + ebcdic_ii[i];
- }
- extern int foo;
-
-int
-main ()
-{
-return use_ascii (foo) == use_ebcdic (foo);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
- ac_cv_c_bigendian=yes
- fi
- if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
- if test "$ac_cv_c_bigendian" = unknown; then
- ac_cv_c_bigendian=no
- else
- # finding both strings is unlikely to happen, but who knows?
- ac_cv_c_bigendian=unknown
- fi
- fi
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-
- /* Are we little or big endian? From Harbison&Steele. */
- union
- {
- long int l;
- char c[sizeof (long int)];
- } u;
- u.l = 1;
- return u.c[sizeof (long int) - 1] == 1;
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
- ac_cv_c_bigendian=no
-else
- ac_cv_c_bigendian=yes
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
-$as_echo "$ac_cv_c_bigendian" >&6; }
- case $ac_cv_c_bigendian in #(
- yes)
- $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
-;; #(
- no)
- ;; #(
- universal)
-
-$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
-
- ;; #(
- *)
- as_fn_error "unknown endianness
- presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
- esac
-
-
-# ----------------------
-# Checks for C++ headers
-# ----------------------
-
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
-$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
-if test -z "$CXXCPP"; then
- if test "${ac_cv_prog_CXXCPP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- # Double quotes because CXXCPP needs to be expanded
- for CXXCPP in "$CXX -E" "/lib/cpp"
- do
- ac_preproc_ok=false
-for ac_cxx_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
-
-else
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
- # Broken: success on invalid input.
-continue
-else
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
- break
-fi
-
- done
- ac_cv_prog_CXXCPP=$CXXCPP
-
-fi
- CXXCPP=$ac_cv_prog_CXXCPP
-else
- ac_cv_prog_CXXCPP=$CXXCPP
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
-$as_echo "$CXXCPP" >&6; }
-ac_preproc_ok=false
-for ac_cxx_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
-
-else
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
- # Broken: success on invalid input.
-continue
-else
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-
-else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: C++ preprocessor \"$CXXCPP\" fails sanity check
-See \`config.log' for more details." >&5
-$as_echo "$as_me: WARNING: C++ preprocessor \"$CXXCPP\" fails sanity check
-See \`config.log' for more details." >&2;}; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-
-
-
-for ac_header in unordered_map
-do :
- ac_fn_cxx_check_header_preproc "$LINENO" "unordered_map" "ac_cv_header_unordered_map"
-if test "x$ac_cv_header_unordered_map" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_UNORDERED_MAP 1
-_ACEOF
-
-fi
-done
-
-for ac_header in tr1/unordered_map
-do :
- ac_fn_cxx_check_header_preproc "$LINENO" "tr1/unordered_map" "ac_cv_header_tr1_unordered_map"
-if test "x$ac_cv_header_tr1_unordered_map" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_TR1_UNORDERED_MAP 1
-_ACEOF
-
-fi
-done
-
-for ac_header in ext/hash_map
-do :
- ac_fn_cxx_check_header_preproc "$LINENO" "ext/hash_map" "ac_cv_header_ext_hash_map"
-if test "x$ac_cv_header_ext_hash_map" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_EXT_HASH_MAP 1
-_ACEOF
-
-fi
-done
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-# --------
-# UNSORTED
-# --------
-
-
-# These libraries may be used by collect2.
-# We may need a special search path to get them linked.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for collect2 libraries" >&5
-$as_echo_n "checking for collect2 libraries... " >&6; }
-if test "${gcc_cv_collect2_libs+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- save_LIBS="$LIBS"
-for libs in '' -lld -lmld \
- '-L/usr/lib/cmplrs/cc2.11 -lmld' \
- '-L/usr/lib/cmplrs/cc3.11 -lmld'
-do
- LIBS="$libs"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char ldopen ();
-int
-main ()
-{
-return ldopen ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- gcc_cv_collect2_libs="$libs"; break
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-done
-LIBS="$save_LIBS"
-test -z "$gcc_cv_collect2_libs" && gcc_cv_collect2_libs='none required'
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_collect2_libs" >&5
-$as_echo "$gcc_cv_collect2_libs" >&6; }
-case $gcc_cv_collect2_libs in
- "none required") ;;
- *) COLLECT2_LIBS=$gcc_cv_collect2_libs ;;
-esac
-
-
-# When building Ada code on Alpha, we need exc_resume which is usually in
-# -lexc. So test for it.
-save_LIBS="$LIBS"
-LIBS=
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing exc_resume" >&5
-$as_echo_n "checking for library containing exc_resume... " >&6; }
-if test "${ac_cv_search_exc_resume+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char exc_resume ();
-int
-main ()
-{
-return exc_resume ();
- ;
- return 0;
-}
-_ACEOF
-for ac_lib in '' exc; do
- if test -z "$ac_lib"; then
- ac_res="none required"
- else
- ac_res=-l$ac_lib
- LIBS="-l$ac_lib $ac_func_search_save_LIBS"
- fi
- if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_search_exc_resume=$ac_res
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext
- if test "${ac_cv_search_exc_resume+set}" = set; then :
- break
-fi
-done
-if test "${ac_cv_search_exc_resume+set}" = set; then :
-
-else
- ac_cv_search_exc_resume=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_exc_resume" >&5
-$as_echo "$ac_cv_search_exc_resume" >&6; }
-ac_res=$ac_cv_search_exc_resume
-if test "$ac_res" != no; then :
- test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
-fi
-
-GNAT_LIBEXC="$LIBS"
-LIBS="$save_LIBS"
-
-
-# To support -mcpu=native on Solaris/SPARC, we need libkstat.
-save_LIBS="$LIBS"
-LIBS=
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing kstat_open" >&5
-$as_echo_n "checking for library containing kstat_open... " >&6; }
-if test "${ac_cv_search_kstat_open+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char kstat_open ();
-int
-main ()
-{
-return kstat_open ();
- ;
- return 0;
-}
-_ACEOF
-for ac_lib in '' kstat; do
- if test -z "$ac_lib"; then
- ac_res="none required"
- else
- ac_res=-l$ac_lib
- LIBS="-l$ac_lib $ac_func_search_save_LIBS"
- fi
- if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_search_kstat_open=$ac_res
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext
- if test "${ac_cv_search_kstat_open+set}" = set; then :
- break
-fi
-done
-if test "${ac_cv_search_kstat_open+set}" = set; then :
-
-else
- ac_cv_search_kstat_open=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_kstat_open" >&5
-$as_echo "$ac_cv_search_kstat_open" >&6; }
-ac_res=$ac_cv_search_kstat_open
-if test "$ac_res" != no; then :
- test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
-fi
-
-EXTRA_GCC_LIBS="$LIBS"
-LIBS="$save_LIBS"
-
-
-# Some systems put ldexp and frexp in libm instead of libc; assume
-# they're both in the same place. jcf-dump needs them.
-save_LIBS="$LIBS"
-LIBS=
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ldexp" >&5
-$as_echo_n "checking for library containing ldexp... " >&6; }
-if test "${ac_cv_search_ldexp+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char ldexp ();
-int
-main ()
-{
-return ldexp ();
- ;
- return 0;
-}
-_ACEOF
-for ac_lib in '' m; do
- if test -z "$ac_lib"; then
- ac_res="none required"
- else
- ac_res=-l$ac_lib
- LIBS="-l$ac_lib $ac_func_search_save_LIBS"
- fi
- if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_search_ldexp=$ac_res
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext
- if test "${ac_cv_search_ldexp+set}" = set; then :
- break
-fi
-done
-if test "${ac_cv_search_ldexp+set}" = set; then :
-
-else
- ac_cv_search_ldexp=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ldexp" >&5
-$as_echo "$ac_cv_search_ldexp" >&6; }
-ac_res=$ac_cv_search_ldexp
-if test "$ac_res" != no; then :
- test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
-fi
-
-LDEXP_LIB="$LIBS"
-LIBS="$save_LIBS"
-
-
-# Use <inttypes.h> only if it exists,
-# doesn't clash with <sys/types.h>, and declares intmax_t.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inttypes.h" >&5
-$as_echo_n "checking for inttypes.h... " >&6; }
-if test "${gcc_cv_header_inttypes_h+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
-#include <inttypes.h>
-int
-main ()
-{
-intmax_t i = -1;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- gcc_cv_header_inttypes_h=yes
-else
- gcc_cv_header_inttypes_h=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_header_inttypes_h" >&5
-$as_echo "$gcc_cv_header_inttypes_h" >&6; }
-if test $gcc_cv_header_inttypes_h = yes; then
-
-$as_echo "#define HAVE_INTTYPES_H 1" >>confdefs.h
-
-fi
-
-
-
-for ac_func in times clock kill getrlimit setrlimit atoll atoq \
- sysconf strsignal getrusage nl_langinfo \
- gettimeofday mbstowcs wcswidth mmap setlocale \
- clearerr_unlocked feof_unlocked ferror_unlocked fflush_unlocked fgetc_unlocked fgets_unlocked fileno_unlocked fprintf_unlocked fputc_unlocked fputs_unlocked fread_unlocked fwrite_unlocked getchar_unlocked getc_unlocked putchar_unlocked putc_unlocked madvise
-do :
- as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-eval as_val=\$$as_ac_var
- if test "x$as_val" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-done
-
-
-if test x$ac_cv_func_mbstowcs = xyes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mbstowcs works" >&5
-$as_echo_n "checking whether mbstowcs works... " >&6; }
-if test "${gcc_cv_func_mbstowcs_works+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test "$cross_compiling" = yes; then :
- gcc_cv_func_mbstowcs_works=yes
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-int main()
-{
- mbstowcs(0, "", 0);
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
- gcc_cv_func_mbstowcs_works=yes
-else
- gcc_cv_func_mbstowcs_works=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_func_mbstowcs_works" >&5
-$as_echo "$gcc_cv_func_mbstowcs_works" >&6; }
- if test x$gcc_cv_func_mbstowcs_works = xyes; then
-
-$as_echo "#define HAVE_WORKING_MBSTOWCS 1" >>confdefs.h
-
- fi
-fi
-
-ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default"
-if test "x$ac_cv_type_ssize_t" = x""yes; then :
-
-else
-
-cat >>confdefs.h <<_ACEOF
-#define ssize_t int
-_ACEOF
-
-fi
-
-ac_fn_c_check_type "$LINENO" "caddr_t" "ac_cv_type_caddr_t" "$ac_includes_default"
-if test "x$ac_cv_type_caddr_t" = x""yes; then :
-
-else
-
-cat >>confdefs.h <<_ACEOF
-#define caddr_t char *
-_ACEOF
-
-fi
-
-
-
-ac_fn_c_check_header_preproc "$LINENO" "sys/mman.h" "ac_cv_header_sys_mman_h"
-if test "x$ac_cv_header_sys_mman_h" = x""yes; then :
- gcc_header_sys_mman_h=yes
-else
- gcc_header_sys_mman_h=no
-fi
-
-ac_fn_c_check_func "$LINENO" "mmap" "ac_cv_func_mmap"
-if test "x$ac_cv_func_mmap" = x""yes; then :
- gcc_func_mmap=yes
-else
- gcc_func_mmap=no
-fi
-
-if test "$gcc_header_sys_mman_h" != yes \
- || test "$gcc_func_mmap" != yes; then
- gcc_cv_func_mmap_file=no
- gcc_cv_func_mmap_dev_zero=no
- gcc_cv_func_mmap_anon=no
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether read-only mmap of a plain file works" >&5
-$as_echo_n "checking whether read-only mmap of a plain file works... " >&6; }
-if test "${gcc_cv_func_mmap_file+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- # Add a system to this blacklist if
- # mmap(0, stat_size, PROT_READ, MAP_PRIVATE, fd, 0) doesn't return a
- # memory area containing the same data that you'd get if you applied
- # read() to the same fd. The only system known to have a problem here
- # is VMS, where text files have record structure.
- case "$host_os" in
- *vms* | ultrix*)
- gcc_cv_func_mmap_file=no ;;
- *)
- gcc_cv_func_mmap_file=yes;;
- esac
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_func_mmap_file" >&5
-$as_echo "$gcc_cv_func_mmap_file" >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mmap from /dev/zero works" >&5
-$as_echo_n "checking whether mmap from /dev/zero works... " >&6; }
-if test "${gcc_cv_func_mmap_dev_zero+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- # Add a system to this blacklist if it has mmap() but /dev/zero
- # does not exist, or if mmapping /dev/zero does not give anonymous
- # zeroed pages with both the following properties:
- # 1. If you map N consecutive pages in with one call, and then
- # unmap any subset of those pages, the pages that were not
- # explicitly unmapped remain accessible.
- # 2. If you map two adjacent blocks of memory and then unmap them
- # both at once, they must both go away.
- # Systems known to be in this category are Windows (all variants),
- # VMS, and Darwin.
- case "$host_os" in
- *vms* | cygwin* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00)
- gcc_cv_func_mmap_dev_zero=no ;;
- *)
- gcc_cv_func_mmap_dev_zero=yes;;
- esac
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_func_mmap_dev_zero" >&5
-$as_echo "$gcc_cv_func_mmap_dev_zero" >&6; }
-
- # Unlike /dev/zero, the MAP_ANON(YMOUS) defines can be probed for.
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for MAP_ANON(YMOUS)" >&5
-$as_echo_n "checking for MAP_ANON(YMOUS)... " >&6; }
-if test "${gcc_cv_decl_map_anon+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <unistd.h>
-
-#ifndef MAP_ANONYMOUS
-#define MAP_ANONYMOUS MAP_ANON
-#endif
-
-int
-main ()
-{
-int n = MAP_ANONYMOUS;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- gcc_cv_decl_map_anon=yes
-else
- gcc_cv_decl_map_anon=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_decl_map_anon" >&5
-$as_echo "$gcc_cv_decl_map_anon" >&6; }
-
- if test $gcc_cv_decl_map_anon = no; then
- gcc_cv_func_mmap_anon=no
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mmap with MAP_ANON(YMOUS) works" >&5
-$as_echo_n "checking whether mmap with MAP_ANON(YMOUS) works... " >&6; }
-if test "${gcc_cv_func_mmap_anon+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- # Add a system to this blacklist if it has mmap() and MAP_ANON or
- # MAP_ANONYMOUS, but using mmap(..., MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
- # doesn't give anonymous zeroed pages with the same properties listed
- # above for use of /dev/zero.
- # Systems known to be in this category are Windows, VMS, and SCO Unix.
- case "$host_os" in
- *vms* | cygwin* | pe | mingw* | sco* | udk* )
- gcc_cv_func_mmap_anon=no ;;
- *)
- gcc_cv_func_mmap_anon=yes;;
- esac
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_func_mmap_anon" >&5
-$as_echo "$gcc_cv_func_mmap_anon" >&6; }
- fi
-fi
-
-if test $gcc_cv_func_mmap_file = yes; then
-
-$as_echo "#define HAVE_MMAP_FILE 1" >>confdefs.h
-
-fi
-if test $gcc_cv_func_mmap_dev_zero = yes; then
-
-$as_echo "#define HAVE_MMAP_DEV_ZERO 1" >>confdefs.h
-
-fi
-if test $gcc_cv_func_mmap_anon = yes; then
-
-$as_echo "#define HAVE_MMAP_ANON 1" >>confdefs.h
-
-fi
-
-
-case "${host}" in
-*-*-*vms*)
- # Under VMS, vfork works very differently than on Unix. The standard test
- # won't work, and it isn't easily adaptable. It makes more sense to
- # just force it.
- ac_cv_func_vfork_works=yes
- ;;
-esac
-ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
-if test "x$ac_cv_type_pid_t" = x""yes; then :
-
-else
-
-cat >>confdefs.h <<_ACEOF
-#define pid_t int
-_ACEOF
-
-fi
-
-for ac_header in vfork.h
-do :
- ac_fn_c_check_header_preproc "$LINENO" "vfork.h" "ac_cv_header_vfork_h"
-if test "x$ac_cv_header_vfork_h" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_VFORK_H 1
-_ACEOF
-
-fi
-done
-
-for ac_func in fork vfork
-do :
- as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-eval as_val=\$$as_ac_var
- if test "x$as_val" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-done
-
-if test "x$ac_cv_func_fork" = xyes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5
-$as_echo_n "checking for working fork... " >&6; }
-if test "${ac_cv_func_fork_works+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test "$cross_compiling" = yes; then :
- ac_cv_func_fork_works=cross
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-
- /* By Ruediger Kuhlmann. */
- return fork () < 0;
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
- ac_cv_func_fork_works=yes
-else
- ac_cv_func_fork_works=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5
-$as_echo "$ac_cv_func_fork_works" >&6; }
-
-else
- ac_cv_func_fork_works=$ac_cv_func_fork
-fi
-if test "x$ac_cv_func_fork_works" = xcross; then
- case $host in
- *-*-amigaos* | *-*-msdosdjgpp*)
- # Override, as these systems have only a dummy fork() stub
- ac_cv_func_fork_works=no
- ;;
- *)
- ac_cv_func_fork_works=yes
- ;;
- esac
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5
-$as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;}
-fi
-ac_cv_func_vfork_works=$ac_cv_func_vfork
-if test "x$ac_cv_func_vfork" = xyes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5
-$as_echo_n "checking for working vfork... " >&6; }
-if test "${ac_cv_func_vfork_works+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test "$cross_compiling" = yes; then :
- ac_cv_func_vfork_works=cross
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-/* Thanks to Paul Eggert for this test. */
-$ac_includes_default
-#include <sys/wait.h>
-#ifdef HAVE_VFORK_H
-# include <vfork.h>
-#endif
-/* On some sparc systems, changes by the child to local and incoming
- argument registers are propagated back to the parent. The compiler
- is told about this with #include <vfork.h>, but some compilers
- (e.g. gcc -O) don't grok <vfork.h>. Test for this by using a
- static variable whose address is put into a register that is
- clobbered by the vfork. */
-static void
-#ifdef __cplusplus
-sparc_address_test (int arg)
-# else
-sparc_address_test (arg) int arg;
-#endif
-{
- static pid_t child;
- if (!child) {
- child = vfork ();
- if (child < 0) {
- perror ("vfork");
- _exit(2);
- }
- if (!child) {
- arg = getpid();
- write(-1, "", 0);
- _exit (arg);
- }
- }
-}
-
-int
-main ()
-{
- pid_t parent = getpid ();
- pid_t child;
-
- sparc_address_test (0);
-
- child = vfork ();
-
- if (child == 0) {
- /* Here is another test for sparc vfork register problems. This
- test uses lots of local variables, at least as many local
- variables as main has allocated so far including compiler
- temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris
- 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should
- reuse the register of parent for one of the local variables,
- since it will think that parent can't possibly be used any more
- in this routine. Assigning to the local variable will thus
- munge parent in the parent process. */
- pid_t
- p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
- p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
- /* Convince the compiler that p..p7 are live; otherwise, it might
- use the same hardware register for all 8 local variables. */
- if (p != p1 || p != p2 || p != p3 || p != p4
- || p != p5 || p != p6 || p != p7)
- _exit(1);
-
- /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent
- from child file descriptors. If the child closes a descriptor
- before it execs or exits, this munges the parent's descriptor
- as well. Test for this by closing stdout in the child. */
- _exit(close(fileno(stdout)) != 0);
- } else {
- int status;
- struct stat st;
-
- while (wait(&status) != child)
- ;
- return (
- /* Was there some problem with vforking? */
- child < 0
-
- /* Did the child fail? (This shouldn't happen.) */
- || status
-
- /* Did the vfork/compiler bug occur? */
- || parent != getpid()
-
- /* Did the file descriptor bug occur? */
- || fstat(fileno(stdout), &st) != 0
- );
- }
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
- ac_cv_func_vfork_works=yes
-else
- ac_cv_func_vfork_works=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5
-$as_echo "$ac_cv_func_vfork_works" >&6; }
-
-fi;
-if test "x$ac_cv_func_fork_works" = xcross; then
- ac_cv_func_vfork_works=$ac_cv_func_vfork
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5
-$as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;}
-fi
-
-if test "x$ac_cv_func_vfork_works" = xyes; then
-
-$as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h
-
-else
-
-$as_echo "#define vfork fork" >>confdefs.h
-
-fi
-if test "x$ac_cv_func_fork_works" = xyes; then
-
-$as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h
-
-fi
-
-
-# g++ on Solaris 10+ defines _XOPEN_SOURCE=600, which exposes a different
-# iconv() prototype.
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-
- if test "X$prefix" = "XNONE"; then
- acl_final_prefix="$ac_default_prefix"
- else
- acl_final_prefix="$prefix"
- fi
- if test "X$exec_prefix" = "XNONE"; then
- acl_final_exec_prefix='${prefix}'
- else
- acl_final_exec_prefix="$exec_prefix"
- fi
- acl_save_prefix="$prefix"
- prefix="$acl_final_prefix"
- eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
- prefix="$acl_save_prefix"
-
-
-# Check whether --with-gnu-ld was given.
-if test "${with_gnu_ld+set}" = set; then :
- withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
-else
- with_gnu_ld=no
-fi
-
-# Prepare PATH_SEPARATOR.
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- echo "#! /bin/sh" >conf$$.sh
- echo "exit 0" >>conf$$.sh
- chmod +x conf$$.sh
- if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
- PATH_SEPARATOR=';'
- else
- PATH_SEPARATOR=:
- fi
- rm -f conf$$.sh
-fi
-ac_prog=ld
-if test "$GCC" = yes; then
- # Check if gcc -print-prog-name=ld gives a path.
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by GCC" >&5
-$as_echo_n "checking for ld used by GCC... " >&6; }
- case $host in
- *-*-mingw*)
- # gcc leaves a trailing carriage return which upsets mingw
- ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
- *)
- ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
- esac
- case $ac_prog in
- # Accept absolute paths.
- [\\/]* | [A-Za-z]:[\\/]*)
- re_direlt='/[^/][^/]*/\.\./'
- # Canonicalize the path of ld
- ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
- while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
- ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
- done
- test -z "$LD" && LD="$ac_prog"
- ;;
- "")
- # If it fails, then pretend we aren't using GCC.
- ac_prog=ld
- ;;
- *)
- # If it is relative, then search for the first ld in PATH.
- with_gnu_ld=unknown
- ;;
- esac
-elif test "$with_gnu_ld" = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
-$as_echo_n "checking for GNU ld... " >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
-$as_echo_n "checking for non-GNU ld... " >&6; }
-fi
-if test "${acl_cv_path_LD+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -z "$LD"; then
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
- acl_cv_path_LD="$ac_dir/$ac_prog"
- # Check to see if the program is GNU ld. I'd rather use --version,
- # but apparently some GNU ld's only accept -v.
- # Break only if it was the GNU/non-GNU ld that we prefer.
- if "$acl_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
- test "$with_gnu_ld" != no && break
- else
- test "$with_gnu_ld" != yes && break
- fi
- fi
- done
- IFS="$ac_save_ifs"
-else
- acl_cv_path_LD="$LD" # Let the user override the test with a path.
-fi
-fi
-
-LD="$acl_cv_path_LD"
-if test -n "$LD"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
-$as_echo "$LD" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
-$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
-if test "${acl_cv_prog_gnu_ld+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- # I'd rather use --version here, but apparently some GNU ld's only accept -v.
-if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
- acl_cv_prog_gnu_ld=yes
-else
- acl_cv_prog_gnu_ld=no
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_prog_gnu_ld" >&5
-$as_echo "$acl_cv_prog_gnu_ld" >&6; }
-with_gnu_ld=$acl_cv_prog_gnu_ld
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5
-$as_echo_n "checking for shared library run path origin... " >&6; }
-if test "${acl_cv_rpath+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
-
- CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \
- ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh
- . ./conftest.sh
- rm -f ./conftest.sh
- acl_cv_rpath=done
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_rpath" >&5
-$as_echo "$acl_cv_rpath" >&6; }
- wl="$acl_cv_wl"
- libext="$acl_cv_libext"
- shlibext="$acl_cv_shlibext"
- hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
- hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
- hardcode_direct="$acl_cv_hardcode_direct"
- hardcode_minus_L="$acl_cv_hardcode_minus_L"
- # Check whether --enable-rpath was given.
-if test "${enable_rpath+set}" = set; then :
- enableval=$enable_rpath; :
-else
- enable_rpath=yes
-fi
-
-
-
-
-
-
-
-
- use_additional=yes
-
- acl_save_prefix="$prefix"
- prefix="$acl_final_prefix"
- acl_save_exec_prefix="$exec_prefix"
- exec_prefix="$acl_final_exec_prefix"
-
- eval additional_includedir=\"$includedir\"
- eval additional_libdir=\"$libdir\"
-
- exec_prefix="$acl_save_exec_prefix"
- prefix="$acl_save_prefix"
-
-
-# Check whether --with-libiconv-prefix was given.
-if test "${with_libiconv_prefix+set}" = set; then :
- withval=$with_libiconv_prefix;
- if test "X$withval" = "Xno"; then
- use_additional=no
- else
- if test "X$withval" = "X"; then
-
- acl_save_prefix="$prefix"
- prefix="$acl_final_prefix"
- acl_save_exec_prefix="$exec_prefix"
- exec_prefix="$acl_final_exec_prefix"
-
- eval additional_includedir=\"$includedir\"
- eval additional_libdir=\"$libdir\"
-
- exec_prefix="$acl_save_exec_prefix"
- prefix="$acl_save_prefix"
-
- else
- additional_includedir="$withval/include"
- additional_libdir="$withval/lib"
- fi
- fi
-
-fi
-
- LIBICONV=
- LTLIBICONV=
- INCICONV=
- rpathdirs=
- ltrpathdirs=
- names_already_handled=
- names_next_round='iconv '
- while test -n "$names_next_round"; do
- names_this_round="$names_next_round"
- names_next_round=
- for name in $names_this_round; do
- already_handled=
- for n in $names_already_handled; do
- if test "$n" = "$name"; then
- already_handled=yes
- break
- fi
- done
- if test -z "$already_handled"; then
- names_already_handled="$names_already_handled $name"
- uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
- eval value=\"\$HAVE_LIB$uppername\"
- if test -n "$value"; then
- if test "$value" = yes; then
- eval value=\"\$LIB$uppername\"
- test -z "$value" || LIBICONV="${LIBICONV}${LIBICONV:+ }$value"
- eval value=\"\$LTLIB$uppername\"
- test -z "$value" || LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$value"
- else
- :
- fi
- else
- found_dir=
- found_la=
- found_so=
- found_a=
- if test $use_additional = yes; then
- if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then
- found_dir="$additional_libdir"
- found_so="$additional_libdir/lib$name.$shlibext"
- if test -f "$additional_libdir/lib$name.la"; then
- found_la="$additional_libdir/lib$name.la"
- fi
- else
- if test -f "$additional_libdir/lib$name.$libext"; then
- found_dir="$additional_libdir"
- found_a="$additional_libdir/lib$name.$libext"
- if test -f "$additional_libdir/lib$name.la"; then
- found_la="$additional_libdir/lib$name.la"
- fi
- fi
- fi
- fi
- if test "X$found_dir" = "X"; then
- for x in $LDFLAGS $LTLIBICONV; 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"
-
- case "$x" in
- -L*)
- dir=`echo "X$x" | sed -e 's/^X-L//'`
- if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then
- found_dir="$dir"
- found_so="$dir/lib$name.$shlibext"
- if test -f "$dir/lib$name.la"; then
- found_la="$dir/lib$name.la"
- fi
- else
- if test -f "$dir/lib$name.$libext"; then
- found_dir="$dir"
- found_a="$dir/lib$name.$libext"
- if test -f "$dir/lib$name.la"; then
- found_la="$dir/lib$name.la"
- fi
- fi
- fi
- ;;
- esac
- if test "X$found_dir" != "X"; then
- break
- fi
- done
- fi
- if test "X$found_dir" != "X"; then
- LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$found_dir -l$name"
- if test "X$found_so" != "X"; then
- if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then
- LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so"
- else
- haveit=
- for x in $ltrpathdirs; do
- if test "X$x" = "X$found_dir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- ltrpathdirs="$ltrpathdirs $found_dir"
- fi
- if test "$hardcode_direct" = yes; then
- LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so"
- else
- if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then
- LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so"
- haveit=
- for x in $rpathdirs; do
- if test "X$x" = "X$found_dir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- rpathdirs="$rpathdirs $found_dir"
- fi
- else
- haveit=
- for x in $LDFLAGS $LIBICONV; 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-L$found_dir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir"
- fi
- if test "$hardcode_minus_L" != no; then
- LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so"
- else
- LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name"
- fi
- fi
- fi
- fi
- else
- if test "X$found_a" != "X"; then
- LIBICONV="${LIBICONV}${LIBICONV:+ }$found_a"
- else
- LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir -l$name"
- fi
- fi
- additional_includedir=
- case "$found_dir" in
- */lib | */lib/)
- basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'`
- additional_includedir="$basedir/include"
- ;;
- esac
- if test "X$additional_includedir" != "X"; then
- if test "X$additional_includedir" != "X/usr/include"; then
- haveit=
- if test "X$additional_includedir" = "X/usr/local/include"; then
- if test -n "$GCC"; then
- case $host_os in
- linux*) haveit=yes;;
- esac
- fi
- fi
- if test -z "$haveit"; then
- for x in $CPPFLAGS $INCICONV; 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-I$additional_includedir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- if test -d "$additional_includedir"; then
- INCICONV="${INCICONV}${INCICONV:+ }-I$additional_includedir"
- fi
- fi
- fi
- fi
- fi
- if test -n "$found_la"; then
- save_libdir="$libdir"
- case "$found_la" in
- */* | *\\*) . "$found_la" ;;
- *) . "./$found_la" ;;
- esac
- libdir="$save_libdir"
- for dep in $dependency_libs; do
- case "$dep" in
- -L*)
- additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
- if test "X$additional_libdir" != "X/usr/lib"; then
- haveit=
- if test "X$additional_libdir" = "X/usr/local/lib"; then
- if test -n "$GCC"; then
- case $host_os in
- linux*) haveit=yes;;
- esac
- fi
- fi
- if test -z "$haveit"; then
- haveit=
- for x in $LDFLAGS $LIBICONV; 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-L$additional_libdir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- if test -d "$additional_libdir"; then
- LIBICONV="${LIBICONV}${LIBICONV:+ }-L$additional_libdir"
- fi
- fi
- haveit=
- for x in $LDFLAGS $LTLIBICONV; 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-L$additional_libdir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- if test -d "$additional_libdir"; then
- LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$additional_libdir"
- fi
- fi
- fi
- fi
- ;;
- -R*)
- dir=`echo "X$dep" | sed -e 's/^X-R//'`
- if test "$enable_rpath" != no; then
- haveit=
- for x in $rpathdirs; do
- if test "X$x" = "X$dir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- rpathdirs="$rpathdirs $dir"
- fi
- haveit=
- for x in $ltrpathdirs; do
- if test "X$x" = "X$dir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- ltrpathdirs="$ltrpathdirs $dir"
- fi
- fi
- ;;
- -l*)
- names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
- ;;
- *.la)
- names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
- ;;
- *)
- LIBICONV="${LIBICONV}${LIBICONV:+ }$dep"
- LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$dep"
- ;;
- esac
- done
- fi
- else
- LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name"
- LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-l$name"
- fi
- fi
- fi
- done
- done
- if test "X$rpathdirs" != "X"; then
- if test -n "$hardcode_libdir_separator"; then
- alldirs=
- for found_dir in $rpathdirs; do
- alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir"
- done
- acl_save_libdir="$libdir"
- libdir="$alldirs"
- eval flag=\"$hardcode_libdir_flag_spec\"
- libdir="$acl_save_libdir"
- LIBICONV="${LIBICONV}${LIBICONV:+ }$flag"
- else
- for found_dir in $rpathdirs; do
- acl_save_libdir="$libdir"
- libdir="$found_dir"
- eval flag=\"$hardcode_libdir_flag_spec\"
- libdir="$acl_save_libdir"
- LIBICONV="${LIBICONV}${LIBICONV:+ }$flag"
- done
- fi
- fi
- if test "X$ltrpathdirs" != "X"; then
- for found_dir in $ltrpathdirs; do
- LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-R$found_dir"
- done
- fi
-
-
-
-
-
-
-
- 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
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5
-$as_echo_n "checking for iconv... " >&6; }
-if test "${am_cv_func_iconv+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
-
- am_cv_func_iconv="no, consider installing GNU libiconv"
- am_cv_lib_iconv=no
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <iconv.h>
-int
-main ()
-{
-iconv_t cd = iconv_open("","");
- iconv(cd,NULL,NULL,NULL,NULL);
- iconv_close(cd);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_link "$LINENO"; then :
- am_cv_func_iconv=yes
-fi
-rm -f core 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"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <iconv.h>
-int
-main ()
-{
-iconv_t cd = iconv_open("","");
- iconv(cd,NULL,NULL,NULL,NULL);
- iconv_close(cd);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_link "$LINENO"; then :
- am_cv_lib_iconv=yes
- am_cv_func_iconv=yes
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- LIBS="$am_save_LIBS"
- fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv" >&5
-$as_echo "$am_cv_func_iconv" >&6; }
- if test "$am_cv_func_iconv" = yes; then
-
-$as_echo "#define HAVE_ICONV 1" >>confdefs.h
-
- fi
- if test "$am_cv_lib_iconv" = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libiconv" >&5
-$as_echo_n "checking how to link with libiconv... " >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBICONV" >&5
-$as_echo "$LIBICONV" >&6; }
- else
- CPPFLAGS="$am_save_CPPFLAGS"
- LIBICONV=
- LTLIBICONV=
- fi
-
-
-
- if test "$am_cv_func_iconv" = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv declaration" >&5
-$as_echo_n "checking for iconv declaration... " >&6; }
- if test "${am_cv_proto_iconv+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
-
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-#include <stdlib.h>
-#include <iconv.h>
-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
-if ac_fn_cxx_try_compile "$LINENO"; then :
- am_cv_proto_iconv_arg1=""
-else
- am_cv_proto_iconv_arg1="const"
-fi
-rm -f core 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/( /(/'`
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ac_t:-
- }$am_cv_proto_iconv" >&5
-$as_echo "${ac_t:-
- }$am_cv_proto_iconv" >&6; }
-
-cat >>confdefs.h <<_ACEOF
-#define ICONV_CONST $am_cv_proto_iconv_arg1
-_ACEOF
-
- fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-# Until we have in-tree GNU iconv:
-LIBICONV_DEP=
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LC_MESSAGES" >&5
-$as_echo_n "checking for LC_MESSAGES... " >&6; }
-if test "${am_cv_val_LC_MESSAGES+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <locale.h>
-int
-main ()
-{
-return LC_MESSAGES
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- am_cv_val_LC_MESSAGES=yes
-else
- am_cv_val_LC_MESSAGES=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_val_LC_MESSAGES" >&5
-$as_echo "$am_cv_val_LC_MESSAGES" >&6; }
- if test $am_cv_val_LC_MESSAGES = yes; then
-
-$as_echo "#define HAVE_LC_MESSAGES 1" >>confdefs.h
-
- fi
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_langinfo and CODESET" >&5
-$as_echo_n "checking for nl_langinfo and CODESET... " >&6; }
-if test "${am_cv_langinfo_codeset+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <langinfo.h>
-int
-main ()
-{
-char* cs = nl_langinfo(CODESET);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- am_cv_langinfo_codeset=yes
-else
- am_cv_langinfo_codeset=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_langinfo_codeset" >&5
-$as_echo "$am_cv_langinfo_codeset" >&6; }
- if test $am_cv_langinfo_codeset = yes; then
-
-$as_echo "#define HAVE_LANGINFO_CODESET 1" >>confdefs.h
-
- fi
-
-
-# We will need to find libiberty.h and ansidecl.h
-saved_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS -I${srcdir} -I${srcdir}/../include $GMPINC"
-saved_CXXFLAGS="$CXXFLAGS"
-CXXFLAGS="$CXXFLAGS -I${srcdir} -I${srcdir}/../include $GMPINC"
-for ac_func in getenv atol asprintf sbrk abort atof getcwd getwd \
- strsignal strstr stpcpy strverscmp \
- errno snprintf vsnprintf vasprintf malloc realloc calloc \
- free basename getopt clock getpagesize ffs clearerr_unlocked feof_unlocked ferror_unlocked fflush_unlocked fgetc_unlocked fgets_unlocked fileno_unlocked fprintf_unlocked fputc_unlocked fputs_unlocked fread_unlocked fwrite_unlocked getchar_unlocked getc_unlocked putchar_unlocked putc_unlocked
-do
- ac_tr_decl=`$as_echo "HAVE_DECL_$ac_func" | $as_tr_cpp`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $ac_func is declared" >&5
-$as_echo_n "checking whether $ac_func is declared... " >&6; }
-if { as_var=gcc_cv_have_decl_$ac_func; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#undef $ac_tr_decl
-#define $ac_tr_decl 1
-
-#include "ansidecl.h"
-#include "system.h"
-
-int
-main ()
-{
-#ifndef $ac_func
-char *(*pfn) = (char *(*)) $ac_func ;
-#endif
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- eval "gcc_cv_have_decl_$ac_func=yes"
-else
- eval "gcc_cv_have_decl_$ac_func=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-if eval "test \"`echo '$gcc_cv_have_decl_'$ac_func`\" = yes"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; } ; cat >>confdefs.h <<_ACEOF
-#define $ac_tr_decl 1
-_ACEOF
-
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; } ; cat >>confdefs.h <<_ACEOF
-#define $ac_tr_decl 0
-_ACEOF
-
-fi
-
-done
-
-
-for ac_func in getrlimit setrlimit getrusage
-do
- ac_tr_decl=`$as_echo "HAVE_DECL_$ac_func" | $as_tr_cpp`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $ac_func is declared" >&5
-$as_echo_n "checking whether $ac_func is declared... " >&6; }
-if { as_var=gcc_cv_have_decl_$ac_func; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#undef $ac_tr_decl
-#define $ac_tr_decl 1
-
-#include "ansidecl.h"
-#include "system.h"
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/resource.h>
-#endif
-
-
-int
-main ()
-{
-#ifndef $ac_func
-char *(*pfn) = (char *(*)) $ac_func ;
-#endif
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- eval "gcc_cv_have_decl_$ac_func=yes"
-else
- eval "gcc_cv_have_decl_$ac_func=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-if eval "test \"`echo '$gcc_cv_have_decl_'$ac_func`\" = yes"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; } ; cat >>confdefs.h <<_ACEOF
-#define $ac_tr_decl 1
-_ACEOF
-
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; } ; cat >>confdefs.h <<_ACEOF
-#define $ac_tr_decl 0
-_ACEOF
-
-fi
-
-done
-
-
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-#include "ansidecl.h"
-#include "system.h"
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/resource.h>
-#endif
-
-int
-main ()
-{
-rlim_t l = 0;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
-
-$as_echo "#define rlim_t long" >>confdefs.h
-
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-# On AIX 5.2, <ldfcn.h> conflicts with <fcntl.h>, as both define incompatible
-# FREAD and FWRITE macros. Fortunately, for GCC's single usage of ldgetname
-# in collect2.c, <fcntl.h> isn't visible, but the configure test below needs
-# to undef these macros to get the correct value for HAVE_DECL_LDGETNAME.
-for ac_func in ldgetname
-do
- ac_tr_decl=`$as_echo "HAVE_DECL_$ac_func" | $as_tr_cpp`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $ac_func is declared" >&5
-$as_echo_n "checking whether $ac_func is declared... " >&6; }
-if { as_var=gcc_cv_have_decl_$ac_func; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#undef $ac_tr_decl
-#define $ac_tr_decl 1
-
-#include "ansidecl.h"
-#include "system.h"
-#ifdef HAVE_LDFCN_H
-#undef FREAD
-#undef FWRITE
-#include <ldfcn.h>
-#endif
-
-
-int
-main ()
-{
-#ifndef $ac_func
-char *(*pfn) = (char *(*)) $ac_func ;
-#endif
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- eval "gcc_cv_have_decl_$ac_func=yes"
-else
- eval "gcc_cv_have_decl_$ac_func=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-if eval "test \"`echo '$gcc_cv_have_decl_'$ac_func`\" = yes"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; } ; cat >>confdefs.h <<_ACEOF
-#define $ac_tr_decl 1
-_ACEOF
-
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; } ; cat >>confdefs.h <<_ACEOF
-#define $ac_tr_decl 0
-_ACEOF
-
-fi
-
-done
-
-
-for ac_func in times
-do
- ac_tr_decl=`$as_echo "HAVE_DECL_$ac_func" | $as_tr_cpp`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $ac_func is declared" >&5
-$as_echo_n "checking whether $ac_func is declared... " >&6; }
-if { as_var=gcc_cv_have_decl_$ac_func; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#undef $ac_tr_decl
-#define $ac_tr_decl 1
-
-#include "ansidecl.h"
-#include "system.h"
-#ifdef HAVE_SYS_TIMES_H
-#include <sys/times.h>
-#endif
-
-
-int
-main ()
-{
-#ifndef $ac_func
-char *(*pfn) = (char *(*)) $ac_func ;
-#endif
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- eval "gcc_cv_have_decl_$ac_func=yes"
-else
- eval "gcc_cv_have_decl_$ac_func=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-if eval "test \"`echo '$gcc_cv_have_decl_'$ac_func`\" = yes"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; } ; cat >>confdefs.h <<_ACEOF
-#define $ac_tr_decl 1
-_ACEOF
-
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; } ; cat >>confdefs.h <<_ACEOF
-#define $ac_tr_decl 0
-_ACEOF
-
-fi
-
-done
-
-
-for ac_func in sigaltstack
-do
- ac_tr_decl=`$as_echo "HAVE_DECL_$ac_func" | $as_tr_cpp`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $ac_func is declared" >&5
-$as_echo_n "checking whether $ac_func is declared... " >&6; }
-if { as_var=gcc_cv_have_decl_$ac_func; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#undef $ac_tr_decl
-#define $ac_tr_decl 1
-
-#include "ansidecl.h"
-#include "system.h"
-#include <signal.h>
-
-
-int
-main ()
-{
-#ifndef $ac_func
-char *(*pfn) = (char *(*)) $ac_func ;
-#endif
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- eval "gcc_cv_have_decl_$ac_func=yes"
-else
- eval "gcc_cv_have_decl_$ac_func=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-if eval "test \"`echo '$gcc_cv_have_decl_'$ac_func`\" = yes"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; } ; cat >>confdefs.h <<_ACEOF
-#define $ac_tr_decl 1
-_ACEOF
-
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; } ; cat >>confdefs.h <<_ACEOF
-#define $ac_tr_decl 0
-_ACEOF
-
-fi
-
-done
-
-
-# g++ on Solaris 10+ defines _XOPEN_SOURCE=600, which hides the madvise()
-# prototype.
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-for ac_func in madvise
-do
- ac_tr_decl=`$as_echo "HAVE_DECL_$ac_func" | $as_tr_cpp`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $ac_func is declared" >&5
-$as_echo_n "checking whether $ac_func is declared... " >&6; }
-if { as_var=gcc_cv_have_decl_$ac_func; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#undef $ac_tr_decl
-#define $ac_tr_decl 1
-
- #include "ansidecl.h"
- #include "system.h"
-
-
-int
-main ()
-{
-#ifndef $ac_func
-char *(*pfn) = (char *(*)) $ac_func ;
-#endif
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
- eval "gcc_cv_have_decl_$ac_func=yes"
-else
- eval "gcc_cv_have_decl_$ac_func=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-if eval "test \"`echo '$gcc_cv_have_decl_'$ac_func`\" = yes"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; } ; cat >>confdefs.h <<_ACEOF
-#define $ac_tr_decl 1
-_ACEOF
-
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; } ; cat >>confdefs.h <<_ACEOF
-#define $ac_tr_decl 0
-_ACEOF
-
-fi
-
-done
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-# More time-related stuff.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct tms" >&5
-$as_echo_n "checking for struct tms... " >&6; }
-if test "${ac_cv_struct_tms+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
-
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-#include "ansidecl.h"
-#include "system.h"
-#ifdef HAVE_SYS_TIMES_H
-#include <sys/times.h>
-#endif
-
-int
-main ()
-{
-struct tms tms;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_struct_tms=yes
-else
- ac_cv_struct_tms=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tms" >&5
-$as_echo "$ac_cv_struct_tms" >&6; }
-if test $ac_cv_struct_tms = yes; then
-
-$as_echo "#define HAVE_STRUCT_TMS 1" >>confdefs.h
-
-fi
-
-# use gcc_cv_* here because this doesn't match the behavior of AC_CHECK_TYPE.
-# revisit after autoconf 2.50.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_t" >&5
-$as_echo_n "checking for clock_t... " >&6; }
-if test "${gcc_cv_type_clock_t+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
-
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-#include "ansidecl.h"
-#include "system.h"
-
-int
-main ()
-{
-clock_t x;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- gcc_cv_type_clock_t=yes
-else
- gcc_cv_type_clock_t=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_type_clock_t" >&5
-$as_echo "$gcc_cv_type_clock_t" >&6; }
-if test $gcc_cv_type_clock_t = yes; then
-
-$as_echo "#define HAVE_CLOCK_T 1" >>confdefs.h
-
-fi
-
-# Check if F_SETLKW is supported by fcntl.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for F_SETLKW" >&5
-$as_echo_n "checking for F_SETLKW... " >&6; }
-if test "${ac_cv_f_setlkw+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
-
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-#include <fcntl.h>
-int
-main ()
-{
-
-struct flock fl;
-fl.l_whence = 0;
-fl.l_start = 0;
-fl.l_len = 0;
-fl.l_pid = 0;
-return fcntl (1, F_SETLKW, &fl);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_f_setlkw=yes
-else
- ac_cv_f_setlkw=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_f_setlkw" >&5
-$as_echo "$ac_cv_f_setlkw" >&6; }
-if test $ac_cv_f_setlkw = yes; then
-
-$as_echo "#define HOST_HAS_F_SETLKW 1" >>confdefs.h
-
-fi
-
-# Restore CFLAGS, CXXFLAGS from before the gcc_AC_NEED_DECLARATIONS tests.
-CFLAGS="$saved_CFLAGS"
-CXXFLAGS="$saved_CXXFLAGS"
-
-# mkdir takes a single argument on some systems.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if mkdir takes one argument" >&5
-$as_echo_n "checking if mkdir takes one argument... " >&6; }
-if test "${gcc_cv_mkdir_takes_one_arg+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-#include <sys/types.h>
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#ifdef HAVE_DIRECT_H
-# include <direct.h>
-#endif
-int
-main ()
-{
-mkdir ("foo", 0);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- gcc_cv_mkdir_takes_one_arg=no
-else
- gcc_cv_mkdir_takes_one_arg=yes
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_mkdir_takes_one_arg" >&5
-$as_echo "$gcc_cv_mkdir_takes_one_arg" >&6; }
-if test $gcc_cv_mkdir_takes_one_arg = yes ; then
-
-$as_echo "#define MKDIR_TAKES_ONE_ARG 1" >>confdefs.h
-
-fi
-
-
-# File extensions
-manext='.1'
-objext='.o'
-
-
-
-# With Setjmp/Longjmp based exception handling.
-# Check whether --enable-sjlj-exceptions was given.
-if test "${enable_sjlj_exceptions+set}" = set; then :
- enableval=$enable_sjlj_exceptions; case $target in
- *-*-hpux10*)
- if test $enableval != yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: dwarf2 exceptions not supported, sjlj exceptions forced" >&5
-$as_echo "$as_me: WARNING: dwarf2 exceptions not supported, sjlj exceptions forced" >&2;}
- enableval=yes
- fi
- ;;
-esac
-force_sjlj_exceptions=yes
-else
- case $target in
- *-*-hpux10*)
- force_sjlj_exceptions=yes
- enableval=yes
- ;;
- *)
- force_sjlj_exceptions=no
- ;;
-esac
-fi
-
-if test $force_sjlj_exceptions = yes; then
- sjlj=`if test $enableval = yes; then echo 1; else echo 0; fi`
-
-cat >>confdefs.h <<_ACEOF
-#define CONFIG_SJLJ_EXCEPTIONS $sjlj
-_ACEOF
-
-fi
-
-# --------------------------------------------------------
-# Build, host, and target specific configuration fragments
-# --------------------------------------------------------
-
-# Collect build-machine-specific information.
-. ${srcdir}/config.build
-
-# Collect host-machine-specific information.
-. ${srcdir}/config.host
-
-target_gtfiles=
-
-# Collect target-machine-specific information.
-. ${srcdir}/config.gcc
-
-extra_objs="${host_extra_objs} ${extra_objs}"
-extra_gcc_objs="${host_extra_gcc_objs} ${extra_gcc_objs}"
-
-# Default the target-machine variables that were not explicitly set.
-if test x"$tm_file" = x
-then tm_file=$cpu_type/$cpu_type.h; fi
-
-if test x"$extra_headers" = x
-then extra_headers=; fi
-
-if test x$md_file = x
-then md_file=$cpu_type/$cpu_type.md; fi
-
-if test x$out_file = x
-then out_file=$cpu_type/$cpu_type.c; fi
-
-if test x"$tmake_file" = x
-then tmake_file=$cpu_type/t-$cpu_type
-fi
-
-# Support --enable-initfini-array.
-if test x$enable_initfini_array != xno; then
- tm_file="${tm_file} initfini-array.h"
-fi
-
-if test x"$dwarf2" = xyes
-then tm_file="$tm_file tm-dwarf2.h"
-fi
-
-# Say what files are being used for the output code and MD file.
-echo "Using \`$srcdir/config/$out_file' for machine-specific logic."
-echo "Using \`$srcdir/config/$md_file' as machine description file."
-
-# If any of the xm_file variables contain nonexistent files, warn
-# about them and drop them.
-
-bx=
-for x in $build_xm_file; do
- if test -f $srcdir/config/$x
- then bx="$bx $x"
- else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $srcdir/config/$x does not exist." >&5
-$as_echo "$as_me: WARNING: $srcdir/config/$x does not exist." >&2;}
- fi
-done
-build_xm_file="$bx"
-
-hx=
-for x in $host_xm_file; do
- if test -f $srcdir/config/$x
- then hx="$hx $x"
- else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $srcdir/config/$x does not exist." >&5
-$as_echo "$as_me: WARNING: $srcdir/config/$x does not exist." >&2;}
- fi
-done
-host_xm_file="$hx"
-
-tx=
-for x in $xm_file; do
- if test -f $srcdir/config/$x
- then tx="$tx $x"
- else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $srcdir/config/$x does not exist." >&5
-$as_echo "$as_me: WARNING: $srcdir/config/$x does not exist." >&2;}
- fi
-done
-xm_file="$tx"
-
-count=a
-for f in $tm_file; do
- count=${count}x
-done
-if test $count = ax; then
- echo "Using \`$srcdir/config/$tm_file' as target machine macro file."
-else
- echo "Using the following target machine macro files:"
- for f in $tm_file; do
- echo " $srcdir/config/$f"
- done
-fi
-
-if test x$need_64bit_hwint = xyes; then
-
-$as_echo "#define NEED_64BIT_HOST_WIDE_INT 1" >>confdefs.h
-
-fi
-
-if test x$use_long_long_for_widest_fast_int = xyes; then
-
-$as_echo "#define USE_LONG_LONG_FOR_WIDEST_FAST_INT 1" >>confdefs.h
-
-fi
-
-gnu_ld_bool=`if test x"$gnu_ld" = x"yes"; then echo 1; else echo 0; fi`
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_GNU_LD $gnu_ld_bool
-_ACEOF
-
-
-gnu_as_bool=`if test x"$gas" = x"yes"; then echo 1; else echo 0; fi`
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_GNU_AS $gnu_as_bool
-_ACEOF
-
-
-count=a
-for f in $host_xm_file; do
- count=${count}x
-done
-if test $count = a; then
- :
-elif test $count = ax; then
- echo "Using \`$srcdir/config/$host_xm_file' as host machine macro file."
-else
- echo "Using the following host machine macro files:"
- for f in $host_xm_file; do
- echo " $srcdir/config/$f"
- done
-fi
-echo "Using ${out_host_hook_obj} for host machine hooks."
-
-if test "$host_xm_file" != "$build_xm_file"; then
- count=a
- for f in $build_xm_file; do
- count=${count}x
- done
- if test $count = a; then
- :
- elif test $count = ax; then
- echo "Using \`$srcdir/config/$build_xm_file' as build machine macro file."
- else
- echo "Using the following build machine macro files:"
- for f in $build_xm_file; do
- echo " $srcdir/config/$f"
- done
- fi
-fi
-
-if test -n "$configured_native_system_header_dir"; then
- native_system_header_dir=$configured_native_system_header_dir
-fi
-NATIVE_SYSTEM_HEADER_DIR="$native_system_header_dir"
-
-
-case ${host} in
- powerpc*-*-darwin*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mcontext_t fields have underscores" >&5
-$as_echo_n "checking whether mcontext_t fields have underscores... " >&6; }
-if test "${gcc_cv_mcontext_underscores+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-#include <sys/cdefs.h>
-#include <sys/signal.h>
-#include <ucontext.h>
-int main() { mcontext_t m; if (m->ss.srr0) return 0; return 0; }
-
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- gcc_cv_mcontext_underscores=no
-else
- gcc_cv_mcontext_underscores=yes
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_mcontext_underscores" >&5
-$as_echo "$gcc_cv_mcontext_underscores" >&6; }
- if test $gcc_cv_mcontext_underscores = yes; then
-
-$as_echo "#define HAS_MCONTEXT_T_UNDERSCORES /**/" >>confdefs.h
-
- fi
- ;;
-esac
-
-# ---------
-# Threading
-# ---------
-
-# Check if a valid thread package
-case ${enable_threads} in
- "" | no)
- # No threads
- target_thread_file='single'
- ;;
- yes)
- # default
- target_thread_file='single'
- ;;
- aix | dce | lynx | mipssde | posix | rtems | \
- single | tpf | vxworks | win32)
- target_thread_file=${enable_threads}
- ;;
- *)
- echo "${enable_threads} is an unknown thread package" 1>&2
- exit 1
- ;;
-esac
-
-if test x${thread_file} = x; then
- # No thread file set by target-specific clauses in config.gcc,
- # so use file chosen by default logic above
- thread_file=${target_thread_file}
-fi
-
-# --------
-# UNSORTED
-# --------
-
-use_cxa_atexit=no
-if test x$enable___cxa_atexit = xyes || \
- test x$enable___cxa_atexit = x -a x$default_use_cxa_atexit = xyes; then
- if test x$host = x$target; then
- case $host in
- # mingw32 doesn't have __cxa_atexit but uses atexit registration
- # keyed to flag_use_cxa_atexit
- *-*-mingw32*)
- use_cxa_atexit=yes
- ;;
- powerpc-ibm-aix*)
- use_cxa_atexit=yes
- ;;
- *)
- ac_fn_c_check_func "$LINENO" "__cxa_atexit" "ac_cv_func___cxa_atexit"
-if test "x$ac_cv_func___cxa_atexit" = x""yes; then :
- use_cxa_atexit=yes
-else
- echo "__cxa_atexit can't be enabled on this target"
-fi
-
- ;;
- esac
- else
- # We can't check for __cxa_atexit when building a cross, so assume
- # it is available
- use_cxa_atexit=yes
- fi
- if test x$use_cxa_atexit = xyes; then
-
-$as_echo "#define DEFAULT_USE_CXA_ATEXIT 2" >>confdefs.h
-
- fi
-fi
-
-# Look for a file containing extra machine modes.
-if test -n "$extra_modes" && test -f $srcdir/config/$extra_modes; then
- extra_modes_file='$(srcdir)'/config/${extra_modes}
-
-
-cat >>confdefs.h <<_ACEOF
-#define EXTRA_MODES_FILE "config/$extra_modes"
-_ACEOF
-
-fi
-
-# Convert extra_options into a form suitable for Makefile use.
-extra_opt_files=
-all_opt_files=
-for f in $extra_options; do
- extra_opt_files="$extra_opt_files \$(srcdir)/config/$f"
- all_opt_files="$all_opt_files $srcdir/config/$f"
-done
-
-
-# auto-host.h is the file containing items generated by autoconf and is
-# the first file included by config.h.
-# If host=build, it is correct to have bconfig include auto-host.h
-# as well. If host!=build, we are in error and need to do more
-# work to find out the build config parameters.
-if test x$host = x$build
-then
- build_auto=auto-host.h
-else
- # We create a subdir, then run autoconf in the subdir.
- # To prevent recursion we set host and build for the new
- # invocation of configure to the build for this invocation
- # of configure.
- tempdir=build.$$
- rm -rf $tempdir
- mkdir $tempdir
- cd $tempdir
- case ${srcdir} in
- /* | A-Za-z:\\/* ) realsrcdir=${srcdir};;
- *) realsrcdir=../${srcdir};;
- esac
- saved_CFLAGS="${CFLAGS}"
- CC="${CC_FOR_BUILD}" CFLAGS="${CFLAGS_FOR_BUILD}" \
- LDFLAGS="${LDFLAGS_FOR_BUILD}" \
- ${realsrcdir}/configure \
- --enable-languages=${enable_languages-all} \
- --target=$target_alias --host=$build_alias --build=$build_alias
- CFLAGS="${saved_CFLAGS}"
-
- # We just finished tests for the build machine, so rename
- # the file auto-build.h in the gcc directory.
- mv auto-host.h ../auto-build.h
- cd ..
- rm -rf $tempdir
- build_auto=auto-build.h
-fi
-
-
-tm_file="${tm_file} defaults.h"
-tm_p_file="${tm_p_file} tm-preds.h"
-host_xm_file="auto-host.h ansidecl.h ${host_xm_file}"
-build_xm_file="${build_auto} ansidecl.h ${build_xm_file}"
-# We don't want ansidecl.h in target files, write code there in ISO/GNU C.
-# put this back in temporarily.
-xm_file="auto-host.h ansidecl.h ${xm_file}"
-
-# --------
-# UNSORTED
-# --------
-
-# Compile in configure arguments.
-if test -f configargs.h ; then
- # Being re-configured.
- gcc_config_arguments=`grep configuration_arguments configargs.h | sed -e 's/.*"\([^"]*\)".*/\1/'`
- gcc_config_arguments="$gcc_config_arguments : (reconfigured) $TOPLEVEL_CONFIGURE_ARGUMENTS"
-else
- gcc_config_arguments="$TOPLEVEL_CONFIGURE_ARGUMENTS"
-fi
-
-# Double all backslashes and backslash all quotes to turn
-# gcc_config_arguments into a C string.
-sed -e 's/\\/\\\\/g; s/"/\\"/g' <<EOF >conftest.out
-$gcc_config_arguments
-EOF
-gcc_config_arguments_str=`cat conftest.out`
-rm -f conftest.out
-
-cat > configargs.h <<EOF
-/* Generated automatically. */
-static const char configuration_arguments[] = "$gcc_config_arguments_str";
-static const char thread_model[] = "$thread_file";
-
-static const struct {
- const char *name, *value;
-} configure_default_options[] = $configure_default_options;
-EOF
-
-gcc_BASEVER=`cat $srcdir/BASE-VER`
-gcc_DEVPHASE=`cat $srcdir/DEV-PHASE`
-gcc_DATESTAMP=`cat $srcdir/DATESTAMP`
-if test -f $srcdir/REVISION ; then
- gcc_REVISION=`cat $srcdir/REVISION`
-else
- gcc_REVISION=""
-fi
-cat > plugin-version.h <<EOF
-#include "configargs.h"
-
-#define GCCPLUGIN_VERSION_MAJOR `echo $gcc_BASEVER | sed -e 's/^\([0-9]*\).*$/\1/'`
-#define GCCPLUGIN_VERSION_MINOR `echo $gcc_BASEVER | sed -e 's/^[0-9]*\.\([0-9]*\).*$/\1/'`
-#define GCCPLUGIN_VERSION_PATCHLEVEL `echo $gcc_BASEVER | sed -e 's/^[0-9]*\.[0-9]*\.\([0-9]*\)$/\1/'`
-#define GCCPLUGIN_VERSION (GCCPLUGIN_VERSION_MAJOR*1000 + GCCPLUGIN_VERSION_MINOR)
-
-static char basever[] = "$gcc_BASEVER";
-static char datestamp[] = "$gcc_DATESTAMP";
-static char devphase[] = "$gcc_DEVPHASE";
-static char revision[] = "$gcc_REVISION";
-
-/* FIXME plugins: We should make the version information more precise.
- One way to do is to add a checksum. */
-
-static struct plugin_gcc_version gcc_version = {basever, datestamp,
- devphase, revision,
- configuration_arguments};
-EOF
-
-# Internationalization
-# If we haven't got the data from the intl directory,
-# assume NLS is disabled.
-USE_NLS=no
-LIBINTL=
-LIBINTL_DEP=
-INCINTL=
-XGETTEXT=
-GMSGFMT=
-POSUB=
-
-if test -f ../intl/config.intl; then
- . ../intl/config.intl
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5
-$as_echo_n "checking whether NLS is requested... " >&6; }
-if test x"$USE_NLS" != xyes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-
-$as_echo "#define ENABLE_NLS 1" >>confdefs.h
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for catalogs to be installed" >&5
-$as_echo_n "checking for catalogs to be installed... " >&6; }
- # Look for .po and .gmo files in the source directory.
- CATALOGS=
- XLINGUAS=
- for cat in $srcdir/po/*.gmo $srcdir/po/*.po; do
- # If there aren't any .gmo files the shell will give us the
- # literal string "../path/to/srcdir/po/*.gmo" which has to be
- # weeded out.
- case "$cat" in *\**)
- continue;;
- esac
- # The quadruple backslash is collapsed to a double backslash
- # by the backticks, then collapsed again by the double quotes,
- # leaving us with one backslash in the sed expression (right
- # before the dot that mustn't act as a wildcard).
- cat=`echo $cat | sed -e "s!$srcdir/po/!!" -e "s!\\\\.po!.gmo!"`
- lang=`echo $cat | sed -e "s!\\\\.gmo!!"`
- # The user is allowed to set LINGUAS to a list of languages to
- # install catalogs for. If it's empty that means "all of them."
- if test "x$LINGUAS" = x; then
- CATALOGS="$CATALOGS $cat"
- XLINGUAS="$XLINGUAS $lang"
- else
- case "$LINGUAS" in *$lang*)
- CATALOGS="$CATALOGS $cat"
- XLINGUAS="$XLINGUAS $lang"
- ;;
- esac
- fi
- done
- LINGUAS="$XLINGUAS"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LINGUAS" >&5
-$as_echo "$LINGUAS" >&6; }
-
-
- DATADIRNAME=share
-
- INSTOBJEXT=.mo
-
- GENCAT=gencat
-
- CATOBJEXT=.gmo
-
-fi
-
-# If LIBINTL contains LIBICONV, then clear LIBICONV so we don't get
-# -liconv on the link line twice.
-case "$LIBINTL" in *$LIBICONV*)
- LIBICONV= ;;
-esac
-
-# Check whether --enable-secureplt was given.
-if test "${enable_secureplt+set}" = set; then :
- enableval=$enable_secureplt;
-fi
-
-
-# Check whether --enable-leading-mingw64-underscores was given.
-if test "${enable_leading_mingw64_underscores+set}" = set; then :
- enableval=$enable_leading_mingw64_underscores;
-fi
-
-if test x"$enable_leading_mingw64_underscores" = xyes ; then :
-
-$as_echo "#define USE_MINGW64_LEADING_UNDERSCORES 1" >>confdefs.h
-
-fi
-
-# Check whether --enable-cld was given.
-if test "${enable_cld+set}" = set; then :
- enableval=$enable_cld;
-else
- enable_cld=no
-fi
-
-
-# Check whether --enable-frame-pointer was given.
-if test "${enable_frame_pointer+set}" = set; then :
- enableval=$enable_frame_pointer;
-else
-
-case $target_os in
-linux* | darwin[8912]*)
- # Enable -fomit-frame-pointer by default for Linux and Darwin with
- # DWARF2.
- enable_frame_pointer=no
- ;;
-*)
- enable_frame_pointer=yes
- ;;
-esac
-
-fi
-
-
-# Windows32 Registry support for specifying GCC installation paths.
-# Check whether --enable-win32-registry was given.
-if test "${enable_win32_registry+set}" = set; then :
- enableval=$enable_win32_registry;
-fi
-
-
-case $host_os in
- win32 | pe | cygwin* | mingw32* | uwin*)
- if test "x$enable_win32_registry" != xno; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing RegOpenKeyExA" >&5
-$as_echo_n "checking for library containing RegOpenKeyExA... " >&6; }
-if test "${ac_cv_search_RegOpenKeyExA+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char RegOpenKeyExA ();
-int
-main ()
-{
-return RegOpenKeyExA ();
- ;
- return 0;
-}
-_ACEOF
-for ac_lib in '' advapi32; do
- if test -z "$ac_lib"; then
- ac_res="none required"
- else
- ac_res=-l$ac_lib
- LIBS="-l$ac_lib $ac_func_search_save_LIBS"
- fi
- if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_search_RegOpenKeyExA=$ac_res
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext
- if test "${ac_cv_search_RegOpenKeyExA+set}" = set; then :
- break
-fi
-done
-if test "${ac_cv_search_RegOpenKeyExA+set}" = set; then :
-
-else
- ac_cv_search_RegOpenKeyExA=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_RegOpenKeyExA" >&5
-$as_echo "$ac_cv_search_RegOpenKeyExA" >&6; }
-ac_res=$ac_cv_search_RegOpenKeyExA
-if test "$ac_res" != no; then :
- test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
-else
- enable_win32_registry=no
-fi
-
- fi
-
- if test "x$enable_win32_registry" != xno; then
-
-$as_echo "#define ENABLE_WIN32_REGISTRY 1" >>confdefs.h
-
-
- if test "x$enable_win32_registry" != xyes \
- && test "x$enable_win32_registry" != x; then
-
-cat >>confdefs.h <<_ACEOF
-#define WIN32_REGISTRY_KEY "$enable_win32_registry"
-_ACEOF
-
- fi
- fi
- ;;
-esac
-
-# Get an absolute path to the GCC top-level source directory
-holddir=`${PWDCMD-pwd}`
-cd $srcdir
-topdir=`${PWDCMD-pwd}`
-cd $holddir
-
-# Conditionalize the makefile for this host machine.
-xmake_file=
-for f in ${host_xmake_file}
-do
- if test -f ${srcdir}/config/$f
- then
- xmake_file="${xmake_file} \$(srcdir)/config/$f"
- fi
-done
-
-# Conditionalize the makefile for this target machine.
-tmake_file_=
-for f in ${tmake_file}
-do
- if test -f ${srcdir}/config/$f
- then
- tmake_file_="${tmake_file_} \$(srcdir)/config/$f"
- fi
-done
-tmake_file="${tmake_file_}"
-
-out_object_file=`basename $out_file .c`.o
-common_out_object_file=`basename $common_out_file .c`.o
-
-tm_file_list="options.h"
-tm_include_list="options.h insn-constants.h"
-for f in $tm_file; do
- case $f in
- ./* )
- f=`echo $f | sed 's/^..//'`
- tm_file_list="${tm_file_list} $f"
- tm_include_list="${tm_include_list} $f"
- ;;
- defaults.h )
- tm_file_list="${tm_file_list} \$(srcdir)/$f"
- tm_include_list="${tm_include_list} $f"
- ;;
- * )
- tm_file_list="${tm_file_list} \$(srcdir)/config/$f"
- tm_include_list="${tm_include_list} config/$f"
- ;;
- esac
-done
-
-tm_p_file_list=
-tm_p_include_list=
-for f in $tm_p_file; do
- case $f in
- tm-preds.h )
- tm_p_file_list="${tm_p_file_list} $f"
- tm_p_include_list="${tm_p_include_list} $f"
- ;;
- * )
- tm_p_file_list="${tm_p_file_list} \$(srcdir)/config/$f"
- tm_p_include_list="${tm_p_include_list} config/$f"
- esac
-done
-
-xm_file_list=
-xm_include_list=
-for f in $xm_file; do
- case $f in
- ansidecl.h )
- xm_file_list="${xm_file_list} \$(srcdir)/../include/$f"
- xm_include_list="${xm_include_list} $f"
- ;;
- auto-host.h )
- xm_file_list="${xm_file_list} $f"
- xm_include_list="${xm_include_list} $f"
- ;;
- * )
- xm_file_list="${xm_file_list} \$(srcdir)/config/$f"
- xm_include_list="${xm_include_list} config/$f"
- ;;
- esac
-done
-
-host_xm_file_list=
-host_xm_include_list=
-for f in $host_xm_file; do
- case $f in
- ansidecl.h )
- host_xm_file_list="${host_xm_file_list} \$(srcdir)/../include/$f"
- host_xm_include_list="${host_xm_include_list} $f"
- ;;
- auto-host.h )
- host_xm_file_list="${host_xm_file_list} $f"
- host_xm_include_list="${host_xm_include_list} $f"
- ;;
- * )
- host_xm_file_list="${host_xm_file_list} \$(srcdir)/config/$f"
- host_xm_include_list="${host_xm_include_list} config/$f"
- ;;
- esac
-done
-
-build_xm_file_list=
-for f in $build_xm_file; do
- case $f in
- ansidecl.h )
- build_xm_file_list="${build_xm_file_list} \$(srcdir)/../include/$f"
- build_xm_include_list="${build_xm_include_list} $f"
- ;;
- auto-build.h | auto-host.h )
- build_xm_file_list="${build_xm_file_list} $f"
- build_xm_include_list="${build_xm_include_list} $f"
- ;;
- * )
- build_xm_file_list="${build_xm_file_list} \$(srcdir)/config/$f"
- build_xm_include_list="${build_xm_include_list} config/$f"
- ;;
- esac
-done
-
-# Define macro CROSS_DIRECTORY_STRUCTURE in compilation if this is a
-# cross-compiler which does not use the native headers and libraries.
-# Also use all.cross instead of all.internal and adjust SYSTEM_HEADER_DIR.
-CROSS=
-ALL=all.internal
-SYSTEM_HEADER_DIR='$(NATIVE_SYSTEM_HEADER_DIR)'
-
-if test "x$with_build_sysroot" != x; then
- build_system_header_dir=$with_build_sysroot'$${sysroot_headers_suffix}$(NATIVE_SYSTEM_HEADER_DIR)'
-else
- # This value is used, even on a native system, because
- # CROSS_SYSTEM_HEADER_DIR is just
- # $(TARGET_SYSTEM_ROOT)$(NATIVE_SYSTEM_HEADER_DIR).
- build_system_header_dir='$(CROSS_SYSTEM_HEADER_DIR)'
-fi
-
-if test x$host != x$target
-then
- CROSS="-DCROSS_DIRECTORY_STRUCTURE"
- ALL=all.cross
- SYSTEM_HEADER_DIR=$build_system_header_dir
- case "$host","$target" in
- # Darwin crosses can use the host system's libraries and headers,
- # because of the fat library support. Of course, it must be the
- # same version of Darwin on both sides. Allow the user to
- # just say --target=foo-darwin without a version number to mean
- # "the version on this system".
- *-*-darwin*,*-*-darwin*)
- hostos=`echo $host | sed 's/.*-darwin/darwin/'`
- targetos=`echo $target | sed 's/.*-darwin/darwin/'`
- if test $hostos = $targetos -o $targetos = darwin ; then
- CROSS=
- SYSTEM_HEADER_DIR='$(NATIVE_SYSTEM_HEADER_DIR)'
- with_headers=yes
- fi
- ;;
-
- i?86-*-*,x86_64-*-* \
- | powerpc*-*-*,powerpc64*-*-*)
- CROSS="$CROSS -DNATIVE_CROSS" ;;
- esac
-
- case $target in
- *-*-mingw*)
- if test "x$with_headers" = x; then
- with_headers=yes
- fi
- ;;
- *)
- ;;
- esac
-elif test "x$TARGET_SYSTEM_ROOT" != x; then
- SYSTEM_HEADER_DIR=$build_system_header_dir
-fi
-
-# If this is a cross-compiler that does not
-# have its own set of headers then define
-# inhibit_libc
-
-# If this is using newlib, without having the headers available now,
-# then define inhibit_libc in LIBGCC2_CFLAGS.
-# This prevents libgcc2 from containing any code which requires libc
-# support.
-: ${inhibit_libc=false}
-if { { test x$host != x$target && test "x$with_sysroot" = x ; } ||
- test x$with_newlib = xyes ; } &&
- { test "x$with_headers" = x || test "x$with_headers" = xno ; } ; then
- inhibit_libc=true
-fi
-
-
-# When building gcc with a cross-compiler, we need to adjust things so
-# that the generator programs are still built with the native compiler.
-# Also, we cannot run fixincludes.
-
-# These are the normal (build=host) settings:
-CC_FOR_BUILD='$(CC)'
-CXX_FOR_BUILD='$(CXX)'
-BUILD_CFLAGS='$(ALL_CFLAGS)'
-BUILD_CXXFLAGS='$(ALL_CXXFLAGS)'
-BUILD_LDFLAGS='$(LDFLAGS)'
-STMP_FIXINC=stmp-fixinc
-
-# And these apply if build != host, or we are generating coverage data
-if test x$build != x$host || test "x$coverage_flags" != x
-then
- BUILD_CFLAGS='$(INTERNAL_CFLAGS) $(T_CFLAGS) $(CFLAGS_FOR_BUILD)'
- BUILD_LDFLAGS='$(LDFLAGS_FOR_BUILD)'
-fi
-
-# Expand extra_headers to include complete path.
-# This substitutes for lots of t-* files.
-extra_headers_list=
-# Prepend $(srcdir)/config/${cpu_type}/ to every entry in extra_headers.
-for file in ${extra_headers} ; do
- extra_headers_list="${extra_headers_list} \$(srcdir)/config/${cpu_type}/${file}"
-done
-
-# If use_gcc_tgmath is set, append ginclude/tgmath.h.
-if test x"$use_gcc_tgmath" = xyes
-then extra_headers_list="${extra_headers_list} \$(srcdir)/ginclude/tgmath.h"
-fi
-
-# Define collect2 in Makefile.
-case $host_can_use_collect2 in
- no) collect2= ;;
- *) collect2='collect2$(exeext)' ;;
-esac
-
-
-# Add a definition of USE_COLLECT2 if system wants one.
-case $use_collect2 in
- no) use_collect2= ;;
- "") ;;
- *)
- host_xm_defines="${host_xm_defines} USE_COLLECT2"
- xm_defines="${xm_defines} USE_COLLECT2"
- case $host_can_use_collect2 in
- no)
- as_fn_error "collect2 is required but cannot be built on this system" "$LINENO" 5
- ;;
- esac
- ;;
-esac
-
-
-cat >>confdefs.h <<_ACEOF
-#define LTOPLUGINSONAME "${host_lto_plugin_soname}"
-_ACEOF
-
-
-# ---------------------------
-# Assembler & linker features
-# ---------------------------
-
-# During stage 2, ld is actually gcc/collect-ld, which is a small script to
-# discern between when to use prev-ld/ld-new and when to use ld/ld-new.
-# However when ld-new is first executed from the build tree, libtool will
-# relink it as .libs/lt-ld-new, so that it can give it an RPATH that refers
-# to the build tree. While doing this we need to use the previous-stage
-# linker, or we have an infinite loop. The presence of a shell script as
-# ld/ld-new, and the fact that the script *uses ld itself*, is what confuses
-# the gcc/collect-ld script. So we need to know how libtool works, or
-# exec-tool will fail.
-
-
-case `pwd` in
- *\ * | *\ *)
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
-$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
-esac
-
-
-
-macro_version='2.2.7a'
-macro_revision='1.3134'
-
-
-
-
-
-
-
-
-
-
-
-
-
-ltmain="$ac_aux_dir/ltmain.sh"
-
-# Backslashify metacharacters that are still active within
-# double-quoted strings.
-sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
-
-# Same as above, but do not quote variable references.
-double_quote_subst='s/\(["`\\]\)/\\\1/g'
-
-# Sed substitution to delay expansion of an escaped shell variable in a
-# double_quote_subst'ed string.
-delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
-
-# Sed substitution to delay expansion of an escaped single quote.
-delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
-
-# Sed substitution to avoid accidental globbing in evaled expressions
-no_glob_subst='s/\*/\\\*/g'
-
-ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
-ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
-$as_echo_n "checking how to print strings... " >&6; }
-# Test print first, because it will be a builtin if present.
-if test "X`print -r -- -n 2>/dev/null`" = X-n && \
- test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
- ECHO='print -r --'
-elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
- ECHO='printf %s\n'
-else
- # Use this function as a fallback that always works.
- func_fallback_echo ()
- {
- eval 'cat <<_LTECHO_EOF
-$1
-_LTECHO_EOF'
- }
- ECHO='func_fallback_echo'
-fi
-
-# func_echo_all arg...
-# Invoke $ECHO with all args, space-separated.
-func_echo_all ()
-{
- $ECHO ""
-}
-
-case "$ECHO" in
- printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
-$as_echo "printf" >&6; } ;;
- print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
-$as_echo "print -r" >&6; } ;;
- *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
-$as_echo "cat" >&6; } ;;
-esac
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
-$as_echo_n "checking for a sed that does not truncate output... " >&6; }
-if test "${ac_cv_path_SED+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
- for ac_i in 1 2 3 4 5 6 7; do
- ac_script="$ac_script$as_nl$ac_script"
- done
- echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
- { ac_script=; unset ac_script;}
- if test -z "$SED"; then
- ac_path_SED_found=false
- # Loop through the user's path and test for each of PROGNAME-LIST
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in sed gsed; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
-# Check for GNU ac_path_SED and select it if it is found.
- # Check for GNU $ac_path_SED
-case `"$ac_path_SED" --version 2>&1` in
-*GNU*)
- ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
-*)
- ac_count=0
- $as_echo_n 0123456789 >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- $as_echo '' >> "conftest.nl"
- "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
- as_fn_arith $ac_count + 1 && ac_count=$as_val
- if test $ac_count -gt ${ac_path_SED_max-0}; then
- # Best one so far, save it but keep looking for a better one
- ac_cv_path_SED="$ac_path_SED"
- ac_path_SED_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
- $ac_path_SED_found && break 3
- done
- done
- done
-IFS=$as_save_IFS
- if test -z "$ac_cv_path_SED"; then
- as_fn_error "no acceptable sed could be found in \$PATH" "$LINENO" 5
- fi
-else
- ac_cv_path_SED=$SED
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
-$as_echo "$ac_cv_path_SED" >&6; }
- SED="$ac_cv_path_SED"
- rm -f conftest.sed
-
-test -z "$SED" && SED=sed
-Xsed="$SED -e 1s/^X//"
-
-
-
-
-
-
-
-
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
-$as_echo_n "checking for fgrep... " >&6; }
-if test "${ac_cv_path_FGREP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
- then ac_cv_path_FGREP="$GREP -F"
- else
- if test -z "$FGREP"; then
- ac_path_FGREP_found=false
- # Loop through the user's path and test for each of PROGNAME-LIST
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in fgrep; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue
-# Check for GNU ac_path_FGREP and select it if it is found.
- # Check for GNU $ac_path_FGREP
-case `"$ac_path_FGREP" --version 2>&1` in
-*GNU*)
- ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
-*)
- ac_count=0
- $as_echo_n 0123456789 >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- $as_echo 'FGREP' >> "conftest.nl"
- "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
- as_fn_arith $ac_count + 1 && ac_count=$as_val
- if test $ac_count -gt ${ac_path_FGREP_max-0}; then
- # Best one so far, save it but keep looking for a better one
- ac_cv_path_FGREP="$ac_path_FGREP"
- ac_path_FGREP_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
- $ac_path_FGREP_found && break 3
- done
- done
- done
-IFS=$as_save_IFS
- if test -z "$ac_cv_path_FGREP"; then
- as_fn_error "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
- fi
-else
- ac_cv_path_FGREP=$FGREP
-fi
-
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
-$as_echo "$ac_cv_path_FGREP" >&6; }
- FGREP="$ac_cv_path_FGREP"
-
-
-test -z "$GREP" && GREP=grep
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# Check whether --with-gnu-ld was given.
-if test "${with_gnu_ld+set}" = set; then :
- withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
-else
- with_gnu_ld=no
-fi
-
-ac_prog=ld
-if test "$GCC" = yes; then
- # Check if gcc -print-prog-name=ld gives a path.
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
-$as_echo_n "checking for ld used by $CC... " >&6; }
- case $host in
- *-*-mingw*)
- # gcc leaves a trailing carriage return which upsets mingw
- ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
- *)
- ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
- esac
- case $ac_prog in
- # Accept absolute paths.
- [\\/]* | ?:[\\/]*)
- re_direlt='/[^/][^/]*/\.\./'
- # Canonicalize the pathname of ld
- ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
- while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
- ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
- done
- test -z "$LD" && LD="$ac_prog"
- ;;
- "")
- # If it fails, then pretend we aren't using GCC.
- ac_prog=ld
- ;;
- *)
- # If it is relative, then search for the first ld in PATH.
- with_gnu_ld=unknown
- ;;
- esac
-elif test "$with_gnu_ld" = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
-$as_echo_n "checking for GNU ld... " >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
-$as_echo_n "checking for non-GNU ld... " >&6; }
-fi
-if test "${lt_cv_path_LD+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -z "$LD"; then
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in $PATH; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
- lt_cv_path_LD="$ac_dir/$ac_prog"
- # Check to see if the program is GNU ld. I'd rather use --version,
- # but apparently some variants of GNU ld only accept -v.
- # Break only if it was the GNU/non-GNU ld that we prefer.
- case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
- *GNU* | *'with BFD'*)
- test "$with_gnu_ld" != no && break
- ;;
- *)
- test "$with_gnu_ld" != yes && break
- ;;
- esac
- fi
- done
- IFS="$lt_save_ifs"
-else
- lt_cv_path_LD="$LD" # Let the user override the test with a path.
-fi
-fi
-
-LD="$lt_cv_path_LD"
-if test -n "$LD"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
-$as_echo "$LD" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
-$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
-if test "${lt_cv_prog_gnu_ld+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- # I'd rather use --version here, but apparently some GNU lds only accept -v.
-case `$LD -v 2>&1 </dev/null` in
-*GNU* | *'with BFD'*)
- lt_cv_prog_gnu_ld=yes
- ;;
-*)
- lt_cv_prog_gnu_ld=no
- ;;
-esac
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
-$as_echo "$lt_cv_prog_gnu_ld" >&6; }
-with_gnu_ld=$lt_cv_prog_gnu_ld
-
-
-
-
-
-
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
-$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
-if test "${lt_cv_path_NM+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$NM"; then
- # Let the user override the test.
- lt_cv_path_NM="$NM"
-else
- lt_nm_to_check="${ac_tool_prefix}nm"
- if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
- lt_nm_to_check="$lt_nm_to_check nm"
- fi
- for lt_tmp_nm in $lt_nm_to_check; do
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- tmp_nm="$ac_dir/$lt_tmp_nm"
- if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
- # Check to see if the nm accepts a BSD-compat flag.
- # Adding the `sed 1q' prevents false positives on HP-UX, which says:
- # nm: unknown option "B" ignored
- # Tru64's nm complains that /dev/null is an invalid object file
- case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
- */dev/null* | *'Invalid file or object type'*)
- lt_cv_path_NM="$tmp_nm -B"
- break
- ;;
- *)
- case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
- */dev/null*)
- lt_cv_path_NM="$tmp_nm -p"
- break
- ;;
- *)
- lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
- continue # so that we can try to find one that supports BSD flags
- ;;
- esac
- ;;
- esac
- fi
- done
- IFS="$lt_save_ifs"
- done
- : ${lt_cv_path_NM=no}
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
-$as_echo "$lt_cv_path_NM" >&6; }
-if test "$lt_cv_path_NM" != "no"; then
- NM="$lt_cv_path_NM"
-else
- # Didn't find any BSD compatible name lister, look for dumpbin.
- if test -n "$DUMPBIN"; then :
- # Let the user override the test.
- else
- if test -n "$ac_tool_prefix"; then
- for ac_prog in dumpbin "link -dump"
- do
- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_DUMPBIN+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$DUMPBIN"; then
- ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-DUMPBIN=$ac_cv_prog_DUMPBIN
-if test -n "$DUMPBIN"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
-$as_echo "$DUMPBIN" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$DUMPBIN" && break
- done
-fi
-if test -z "$DUMPBIN"; then
- ac_ct_DUMPBIN=$DUMPBIN
- for ac_prog in dumpbin "link -dump"
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_DUMPBIN"; then
- ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
-if test -n "$ac_ct_DUMPBIN"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
-$as_echo "$ac_ct_DUMPBIN" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$ac_ct_DUMPBIN" && break
-done
-
- if test "x$ac_ct_DUMPBIN" = x; then
- DUMPBIN=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- DUMPBIN=$ac_ct_DUMPBIN
- fi
-fi
-
- case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
- *COFF*)
- DUMPBIN="$DUMPBIN -symbols"
- ;;
- *)
- DUMPBIN=:
- ;;
- esac
- fi
-
- if test "$DUMPBIN" != ":"; then
- NM="$DUMPBIN"
- fi
-fi
-test -z "$NM" && NM=nm
-
-
-
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
-$as_echo_n "checking the name lister ($NM) interface... " >&6; }
-if test "${lt_cv_nm_interface+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_nm_interface="BSD nm"
- echo "int some_variable = 0;" > conftest.$ac_ext
- (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
- (eval "$ac_compile" 2>conftest.err)
- cat conftest.err >&5
- (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
- (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
- cat conftest.err >&5
- (eval echo "\"\$as_me:$LINENO: output\"" >&5)
- cat conftest.out >&5
- if $GREP 'External.*some_variable' conftest.out > /dev/null; then
- lt_cv_nm_interface="MS dumpbin"
- fi
- rm -f conftest*
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
-$as_echo "$lt_cv_nm_interface" >&6; }
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
-$as_echo_n "checking whether ln -s works... " >&6; }
-LN_S=$as_ln_s
-if test "$LN_S" = "ln -s"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
-$as_echo "no, using $LN_S" >&6; }
-fi
-
-# find the maximum length of command line arguments
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
-$as_echo_n "checking the maximum length of command line arguments... " >&6; }
-if test "${lt_cv_sys_max_cmd_len+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- i=0
- teststring="ABCD"
-
- case $build_os in
- msdosdjgpp*)
- # On DJGPP, this test can blow up pretty badly due to problems in libc
- # (any single argument exceeding 2000 bytes causes a buffer overrun
- # during glob expansion). Even if it were fixed, the result of this
- # check would be larger than it should be.
- lt_cv_sys_max_cmd_len=12288; # 12K is about right
- ;;
-
- gnu*)
- # Under GNU Hurd, this test is not required because there is
- # no limit to the length of command line arguments.
- # Libtool will interpret -1 as no limit whatsoever
- lt_cv_sys_max_cmd_len=-1;
- ;;
-
- cygwin* | mingw* | cegcc*)
- # On Win9x/ME, this test blows up -- it succeeds, but takes
- # about 5 minutes as the teststring grows exponentially.
- # Worse, since 9x/ME are not pre-emptively multitasking,
- # you end up with a "frozen" computer, even though with patience
- # the test eventually succeeds (with a max line length of 256k).
- # Instead, let's just punt: use the minimum linelength reported by
- # all of the supported platforms: 8192 (on NT/2K/XP).
- lt_cv_sys_max_cmd_len=8192;
- ;;
-
- mint*)
- # On MiNT this can take a long time and run out of memory.
- lt_cv_sys_max_cmd_len=8192;
- ;;
-
- amigaos*)
- # On AmigaOS with pdksh, this test takes hours, literally.
- # So we just punt and use a minimum line length of 8192.
- lt_cv_sys_max_cmd_len=8192;
- ;;
-
- netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
- # This has been around since 386BSD, at least. Likely further.
- if test -x /sbin/sysctl; then
- lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
- elif test -x /usr/sbin/sysctl; then
- lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
- else
- lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
- fi
- # And add a safety zone
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
- ;;
-
- interix*)
- # We know the value 262144 and hardcode it with a safety zone (like BSD)
- lt_cv_sys_max_cmd_len=196608
- ;;
-
- osf*)
- # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
- # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
- # nice to cause kernel panics so lets avoid the loop below.
- # First set a reasonable default.
- lt_cv_sys_max_cmd_len=16384
- #
- if test -x /sbin/sysconfig; then
- case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
- *1*) lt_cv_sys_max_cmd_len=-1 ;;
- esac
- fi
- ;;
- sco3.2v5*)
- lt_cv_sys_max_cmd_len=102400
- ;;
- sysv5* | sco5v6* | sysv4.2uw2*)
- kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
- if test -n "$kargmax"; then
- lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
- else
- lt_cv_sys_max_cmd_len=32768
- fi
- ;;
- *)
- lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
- if test -n "$lt_cv_sys_max_cmd_len"; then
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
- else
- # Make teststring a little bigger before we do anything with it.
- # a 1K string should be a reasonable start.
- for i in 1 2 3 4 5 6 7 8 ; do
- teststring=$teststring$teststring
- done
- SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
- # If test is not a shell built-in, we'll probably end up computing a
- # maximum length that is only half of the actual maximum length, but
- # we can't tell.
- while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \
- = "X$teststring$teststring"; } >/dev/null 2>&1 &&
- test $i != 17 # 1/2 MB should be enough
- do
- i=`expr $i + 1`
- teststring=$teststring$teststring
- done
- # Only check the string length outside the loop.
- lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
- teststring=
- # Add a significant safety factor because C++ compilers can tack on
- # massive amounts of additional arguments before passing them to the
- # linker. It appears as though 1/2 is a usable value.
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
- fi
- ;;
- esac
-
-fi
-
-if test -n $lt_cv_sys_max_cmd_len ; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
-$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
-$as_echo "none" >&6; }
-fi
-max_cmd_len=$lt_cv_sys_max_cmd_len
-
-
-
-
-
-
-: ${CP="cp -f"}
-: ${MV="mv -f"}
-: ${RM="rm -f"}
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
-$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
-# Try some XSI features
-xsi_shell=no
-( _lt_dummy="a/b/c"
- test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
- = c,a/b,, \
- && eval 'test $(( 1 + 1 )) -eq 2 \
- && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
- && xsi_shell=yes
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
-$as_echo "$xsi_shell" >&6; }
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
-$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
-lt_shell_append=no
-( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
- >/dev/null 2>&1 \
- && lt_shell_append=yes
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
-$as_echo "$lt_shell_append" >&6; }
-
-
-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
- lt_unset=unset
-else
- lt_unset=false
-fi
-
-
-
-
-
-# test EBCDIC or ASCII
-case `echo X|tr X '\101'` in
- A) # ASCII based system
- # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
- lt_SP2NL='tr \040 \012'
- lt_NL2SP='tr \015\012 \040\040'
- ;;
- *) # EBCDIC based system
- lt_SP2NL='tr \100 \n'
- lt_NL2SP='tr \r\n \100\100'
- ;;
-esac
-
-
-
-
-
-
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
-$as_echo_n "checking for $LD option to reload object files... " >&6; }
-if test "${lt_cv_ld_reload_flag+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_ld_reload_flag='-r'
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
-$as_echo "$lt_cv_ld_reload_flag" >&6; }
-reload_flag=$lt_cv_ld_reload_flag
-case $reload_flag in
-"" | " "*) ;;
-*) reload_flag=" $reload_flag" ;;
-esac
-reload_cmds='$LD$reload_flag -o $output$reload_objs'
-case $host_os in
- darwin*)
- if test "$GCC" = yes; then
- reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
- else
- reload_cmds='$LD$reload_flag -o $output$reload_objs'
- fi
- ;;
-esac
-
-
-
-
-
-
-
-
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
-set dummy ${ac_tool_prefix}objdump; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_OBJDUMP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$OBJDUMP"; then
- ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-OBJDUMP=$ac_cv_prog_OBJDUMP
-if test -n "$OBJDUMP"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
-$as_echo "$OBJDUMP" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_OBJDUMP"; then
- ac_ct_OBJDUMP=$OBJDUMP
- # Extract the first word of "objdump", so it can be a program name with args.
-set dummy objdump; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_OBJDUMP"; then
- ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_OBJDUMP="objdump"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
-if test -n "$ac_ct_OBJDUMP"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
-$as_echo "$ac_ct_OBJDUMP" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_OBJDUMP" = x; then
- OBJDUMP="false"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- OBJDUMP=$ac_ct_OBJDUMP
- fi
-else
- OBJDUMP="$ac_cv_prog_OBJDUMP"
-fi
-
-test -z "$OBJDUMP" && OBJDUMP=objdump
-
-
-
-
-
-
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
-$as_echo_n "checking how to recognize dependent libraries... " >&6; }
-if test "${lt_cv_deplibs_check_method+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_file_magic_cmd='$MAGIC_CMD'
-lt_cv_file_magic_test_file=
-lt_cv_deplibs_check_method='unknown'
-# Need to set the preceding variable on all platforms that support
-# interlibrary dependencies.
-# 'none' -- dependencies not supported.
-# `unknown' -- same as none, but documents that we really don't know.
-# 'pass_all' -- all dependencies passed with no checks.
-# 'test_compile' -- check by making test program.
-# 'file_magic [[regex]]' -- check by looking for files in library path
-# which responds to the $file_magic_cmd with a given extended regex.
-# If you have `file' or equivalent on your system and you're not sure
-# whether `pass_all' will *always* work, you probably want this one.
-
-case $host_os in
-aix[4-9]*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-beos*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-bsdi[45]*)
- lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
- lt_cv_file_magic_cmd='/usr/bin/file -L'
- lt_cv_file_magic_test_file=/shlib/libc.so
- ;;
-
-cygwin*)
- # func_win32_libid is a shell function defined in ltmain.sh
- lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
- lt_cv_file_magic_cmd='func_win32_libid'
- ;;
-
-mingw* | pw32*)
- # Base MSYS/MinGW do not provide the 'file' command needed by
- # func_win32_libid shell function, so use a weaker test based on 'objdump',
- # unless we find 'file', for example because we are cross-compiling.
- # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
- if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
- lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
- lt_cv_file_magic_cmd='func_win32_libid'
- else
- lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
- lt_cv_file_magic_cmd='$OBJDUMP -f'
- fi
- ;;
-
-cegcc*)
- # use the weaker test based on 'objdump'. See mingw*.
- lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
- lt_cv_file_magic_cmd='$OBJDUMP -f'
- ;;
-
-darwin* | rhapsody*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-freebsd* | dragonfly*)
- if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
- case $host_cpu in
- i*86 )
- # Not sure whether the presence of OpenBSD here was a mistake.
- # Let's accept both of them until this is cleared up.
- lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
- lt_cv_file_magic_cmd=/usr/bin/file
- lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
- ;;
- esac
- else
- lt_cv_deplibs_check_method=pass_all
- fi
- ;;
-
-gnu*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-haiku*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-hpux10.20* | hpux11*)
- lt_cv_file_magic_cmd=/usr/bin/file
- case $host_cpu in
- ia64*)
- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
- lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
- ;;
- hppa*64*)
- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
- lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
- ;;
- *)
- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
- lt_cv_file_magic_test_file=/usr/lib/libc.sl
- ;;
- esac
- ;;
-
-interix[3-9]*)
- # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
- ;;
-
-irix5* | irix6* | nonstopux*)
- case $LD in
- *-32|*"-32 ") libmagic=32-bit;;
- *-n32|*"-n32 ") libmagic=N32;;
- *-64|*"-64 ") libmagic=64-bit;;
- *) libmagic=never-match;;
- esac
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-# This must be Linux ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-netbsd*)
- if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
- else
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
- fi
- ;;
-
-newos6*)
- lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
- lt_cv_file_magic_cmd=/usr/bin/file
- lt_cv_file_magic_test_file=/usr/lib/libnls.so
- ;;
-
-*nto* | *qnx*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-openbsd*)
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
- else
- lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
- fi
- ;;
-
-osf3* | osf4* | osf5*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-rdos*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-solaris*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-sysv4 | sysv4.3*)
- case $host_vendor in
- motorola)
- lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
- lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
- ;;
- ncr)
- lt_cv_deplibs_check_method=pass_all
- ;;
- sequent)
- lt_cv_file_magic_cmd='/bin/file'
- lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
- ;;
- sni)
- lt_cv_file_magic_cmd='/bin/file'
- lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
- lt_cv_file_magic_test_file=/lib/libc.so
- ;;
- siemens)
- lt_cv_deplibs_check_method=pass_all
- ;;
- pc)
- lt_cv_deplibs_check_method=pass_all
- ;;
- esac
- ;;
-
-tpf*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-esac
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
-$as_echo "$lt_cv_deplibs_check_method" >&6; }
-file_magic_cmd=$lt_cv_file_magic_cmd
-deplibs_check_method=$lt_cv_deplibs_check_method
-test -z "$deplibs_check_method" && deplibs_check_method=unknown
-
-
-
-
-
-
-
-
-
-
-
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ar; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_AR+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$AR"; then
- ac_cv_prog_AR="$AR" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_AR="${ac_tool_prefix}ar"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-AR=$ac_cv_prog_AR
-if test -n "$AR"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
-$as_echo "$AR" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_AR"; then
- ac_ct_AR=$AR
- # Extract the first word of "ar", so it can be a program name with args.
-set dummy ar; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_AR+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_AR"; then
- ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_AR="ar"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_AR=$ac_cv_prog_ac_ct_AR
-if test -n "$ac_ct_AR"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
-$as_echo "$ac_ct_AR" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_AR" = x; then
- AR="false"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- AR=$ac_ct_AR
- fi
-else
- AR="$ac_cv_prog_AR"
-fi
-
-test -z "$AR" && AR=ar
-test -z "$AR_FLAGS" && AR_FLAGS=cru
-
-
-
-
-
-
-
-
-
-
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
-set dummy ${ac_tool_prefix}strip; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_STRIP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$STRIP"; then
- ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_STRIP="${ac_tool_prefix}strip"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-STRIP=$ac_cv_prog_STRIP
-if test -n "$STRIP"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
-$as_echo "$STRIP" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_STRIP"; then
- ac_ct_STRIP=$STRIP
- # Extract the first word of "strip", so it can be a program name with args.
-set dummy strip; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_STRIP"; then
- ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_STRIP="strip"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
-if test -n "$ac_ct_STRIP"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
-$as_echo "$ac_ct_STRIP" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_STRIP" = x; then
- STRIP=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- STRIP=$ac_ct_STRIP
- fi
-else
- STRIP="$ac_cv_prog_STRIP"
-fi
-
-test -z "$STRIP" && STRIP=:
-
-
-
-
-
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ranlib; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_RANLIB+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$RANLIB"; then
- ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-RANLIB=$ac_cv_prog_RANLIB
-if test -n "$RANLIB"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
-$as_echo "$RANLIB" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_RANLIB"; then
- ac_ct_RANLIB=$RANLIB
- # Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_RANLIB"; then
- ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_RANLIB="ranlib"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
-if test -n "$ac_ct_RANLIB"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
-$as_echo "$ac_ct_RANLIB" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_RANLIB" = x; then
- RANLIB=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- RANLIB=$ac_ct_RANLIB
- fi
-else
- RANLIB="$ac_cv_prog_RANLIB"
-fi
-
-test -z "$RANLIB" && RANLIB=:
-
-
-
-
-
-
-# Determine commands to create old-style static archives.
-old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
-old_postinstall_cmds='chmod 644 $oldlib'
-old_postuninstall_cmds=
-
-if test -n "$RANLIB"; then
- case $host_os in
- openbsd*)
- old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
- ;;
- *)
- old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
- ;;
- esac
- old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
-fi
-
-case $host_os in
- darwin*)
- lock_old_archive_extraction=yes ;;
- *)
- lock_old_archive_extraction=no ;;
-esac
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
-
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
-
-# Allow CC to be a program name with arguments.
-compiler=$CC
-
-
-# Check for command to grab the raw symbol name followed by C symbol from nm.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
-$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
-if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
-
-# These are sane defaults that work on at least a few old systems.
-# [They come from Ultrix. What could be older than Ultrix?!! ;)]
-
-# Character class describing NM global symbol codes.
-symcode='[BCDEGRST]'
-
-# Regexp to match symbols that can be accessed directly from C.
-sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
-
-# Define system-specific variables.
-case $host_os in
-aix*)
- symcode='[BCDT]'
- ;;
-cygwin* | mingw* | pw32* | cegcc*)
- symcode='[ABCDGISTW]'
- ;;
-hpux*)
- if test "$host_cpu" = ia64; then
- symcode='[ABCDEGRST]'
- fi
- ;;
-irix* | nonstopux*)
- symcode='[BCDEGRST]'
- ;;
-osf*)
- symcode='[BCDEGQRST]'
- ;;
-solaris*)
- symcode='[BDRT]'
- ;;
-sco3.2v5*)
- symcode='[DT]'
- ;;
-sysv4.2uw2*)
- symcode='[DT]'
- ;;
-sysv5* | sco5v6* | unixware* | OpenUNIX*)
- symcode='[ABDT]'
- ;;
-sysv4)
- symcode='[DFNSTU]'
- ;;
-esac
-
-# If we're using GNU nm, then use its standard symbol codes.
-case `$NM -V 2>&1` in
-*GNU* | *'with BFD'*)
- symcode='[ABCDGIRSTW]' ;;
-esac
-
-# Transform an extracted symbol line into a proper C declaration.
-# Some systems (esp. on ia64) link data and code symbols differently,
-# so use this general approach.
-lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
-
-# Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'"
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
-
-# Handle CRLF in mingw tool chain
-opt_cr=
-case $build_os in
-mingw*)
- opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
- ;;
-esac
-
-# Try without a prefix underscore, then with it.
-for ac_symprfx in "" "_"; do
-
- # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
- symxfrm="\\1 $ac_symprfx\\2 \\2"
-
- # Write the raw and C identifiers.
- if test "$lt_cv_nm_interface" = "MS dumpbin"; then
- # Fake it for dumpbin and say T for any non-static function
- # and D for any global variable.
- # Also find C++ and __fastcall symbols from MSVC++,
- # which start with @ or ?.
- lt_cv_sys_global_symbol_pipe="$AWK '"\
-" {last_section=section; section=\$ 3};"\
-" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
-" \$ 0!~/External *\|/{next};"\
-" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
-" {if(hide[section]) next};"\
-" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
-" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
-" s[1]~/^[@?]/{print s[1], s[1]; next};"\
-" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
-" ' prfx=^$ac_symprfx"
- else
- lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
- fi
-
- # Check to see that the pipe works correctly.
- pipe_works=no
-
- rm -f conftest*
- cat > conftest.$ac_ext <<_LT_EOF
-#ifdef __cplusplus
-extern "C" {
-#endif
-char nm_test_var;
-void nm_test_func(void);
-void nm_test_func(void){}
-#ifdef __cplusplus
-}
-#endif
-int main(){nm_test_var='a';nm_test_func();return(0);}
-_LT_EOF
-
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- # Now try to grab the symbols.
- nlist=conftest.nm
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
- (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && test -s "$nlist"; then
- # Try sorting and uniquifying the output.
- if sort "$nlist" | uniq > "$nlist"T; then
- mv -f "$nlist"T "$nlist"
- else
- rm -f "$nlist"T
- fi
-
- # Make sure that we snagged all the symbols we need.
- if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
- if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
- cat <<_LT_EOF > conftest.$ac_ext
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-_LT_EOF
- # Now generate the symbol file.
- eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
-
- cat <<_LT_EOF >> conftest.$ac_ext
-
-/* The mapping between symbol names and symbols. */
-const struct {
- const char *name;
- void *address;
-}
-lt__PROGRAM__LTX_preloaded_symbols[] =
-{
- { "@PROGRAM@", (void *) 0 },
-_LT_EOF
- $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
- cat <<\_LT_EOF >> conftest.$ac_ext
- {0, (void *) 0}
-};
-
-/* This works around a problem in FreeBSD linker */
-#ifdef FREEBSD_WORKAROUND
-static const void *lt_preloaded_setup() {
- return lt__PROGRAM__LTX_preloaded_symbols;
-}
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-_LT_EOF
- # Now try linking the two files.
- mv conftest.$ac_objext conftstm.$ac_objext
- lt_save_LIBS="$LIBS"
- lt_save_CFLAGS="$CFLAGS"
- LIBS="conftstm.$ac_objext"
- CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && test -s conftest${ac_exeext}; then
- pipe_works=yes
- fi
- LIBS="$lt_save_LIBS"
- CFLAGS="$lt_save_CFLAGS"
- else
- echo "cannot find nm_test_func in $nlist" >&5
- fi
- else
- echo "cannot find nm_test_var in $nlist" >&5
- fi
- else
- echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
- fi
- else
- echo "$progname: failed program was:" >&5
- cat conftest.$ac_ext >&5
- fi
- rm -rf conftest* conftst*
-
- # Do not use the global_symbol_pipe unless it works.
- if test "$pipe_works" = yes; then
- break
- else
- lt_cv_sys_global_symbol_pipe=
- fi
-done
-
-fi
-
-if test -z "$lt_cv_sys_global_symbol_pipe"; then
- lt_cv_sys_global_symbol_to_cdecl=
-fi
-if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
-$as_echo "failed" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
-$as_echo "ok" >&6; }
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# Check whether --enable-libtool-lock was given.
-if test "${enable_libtool_lock+set}" = set; then :
- enableval=$enable_libtool_lock;
-fi
-
-test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
-
-# Some flags need to be propagated to the compiler or linker for good
-# libtool support.
-case $host in
-ia64-*-hpux*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- case `/usr/bin/file conftest.$ac_objext` in
- *ELF-32*)
- HPUX_IA64_MODE="32"
- ;;
- *ELF-64*)
- HPUX_IA64_MODE="64"
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-*-*-irix6*)
- # Find out which ABI we are using.
- echo '#line '$LINENO' "configure"' > conftest.$ac_ext
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- if test "$lt_cv_prog_gnu_ld" = yes; then
- case `/usr/bin/file conftest.$ac_objext` in
- *32-bit*)
- LD="${LD-ld} -melf32bsmip"
- ;;
- *N32*)
- LD="${LD-ld} -melf32bmipn32"
- ;;
- *64-bit*)
- LD="${LD-ld} -melf64bmip"
- ;;
- esac
- else
- case `/usr/bin/file conftest.$ac_objext` in
- *32-bit*)
- LD="${LD-ld} -32"
- ;;
- *N32*)
- LD="${LD-ld} -n32"
- ;;
- *64-bit*)
- LD="${LD-ld} -64"
- ;;
- esac
- fi
- fi
- rm -rf conftest*
- ;;
-
-x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
-s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- case `/usr/bin/file conftest.o` in
- *32-bit*)
- case $host in
- x86_64-*kfreebsd*-gnu)
- LD="${LD-ld} -m elf_i386_fbsd"
- ;;
- x86_64-*linux*)
- case `/usr/bin/file conftest.o` in
- *x86-64*)
- LD="${LD-ld} -m elf32_x86_64"
- ;;
- *)
- LD="${LD-ld} -m elf_i386"
- ;;
- esac
- ;;
- ppc64-*linux*|powerpc64-*linux*)
- LD="${LD-ld} -m elf32ppclinux"
- ;;
- s390x-*linux*)
- LD="${LD-ld} -m elf_s390"
- ;;
- sparc64-*linux*)
- LD="${LD-ld} -m elf32_sparc"
- ;;
- esac
- ;;
- *64-bit*)
- case $host in
- x86_64-*kfreebsd*-gnu)
- LD="${LD-ld} -m elf_x86_64_fbsd"
- ;;
- x86_64-*linux*)
- LD="${LD-ld} -m elf_x86_64"
- ;;
- ppc*-*linux*|powerpc*-*linux*)
- LD="${LD-ld} -m elf64ppc"
- ;;
- s390*-*linux*|s390*-*tpf*)
- LD="${LD-ld} -m elf64_s390"
- ;;
- sparc*-*linux*)
- LD="${LD-ld} -m elf64_sparc"
- ;;
- esac
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-
-*-*-sco3.2v5*)
- # On SCO OpenServer 5, we need -belf to get full-featured binaries.
- SAVE_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -belf"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
-$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
-if test "${lt_cv_cc_needs_belf+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- lt_cv_cc_needs_belf=yes
-else
- lt_cv_cc_needs_belf=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
-$as_echo "$lt_cv_cc_needs_belf" >&6; }
- if test x"$lt_cv_cc_needs_belf" != x"yes"; then
- # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
- CFLAGS="$SAVE_CFLAGS"
- fi
- ;;
-sparc*-*solaris*)
- # Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- case `/usr/bin/file conftest.o` in
- *64-bit*)
- case $lt_cv_prog_gnu_ld in
- yes*) LD="${LD-ld} -m elf64_sparc" ;;
- *)
- if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
- LD="${LD-ld} -64"
- fi
- ;;
- esac
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
-esac
-
-need_locks="$enable_libtool_lock"
-
-
- case $host_os in
- rhapsody* | darwin*)
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
-set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_DSYMUTIL+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$DSYMUTIL"; then
- ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-DSYMUTIL=$ac_cv_prog_DSYMUTIL
-if test -n "$DSYMUTIL"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
-$as_echo "$DSYMUTIL" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_DSYMUTIL"; then
- ac_ct_DSYMUTIL=$DSYMUTIL
- # Extract the first word of "dsymutil", so it can be a program name with args.
-set dummy dsymutil; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_DSYMUTIL"; then
- ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
-if test -n "$ac_ct_DSYMUTIL"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
-$as_echo "$ac_ct_DSYMUTIL" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_DSYMUTIL" = x; then
- DSYMUTIL=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- DSYMUTIL=$ac_ct_DSYMUTIL
- fi
-else
- DSYMUTIL="$ac_cv_prog_DSYMUTIL"
-fi
-
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
-set dummy ${ac_tool_prefix}nmedit; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_NMEDIT+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$NMEDIT"; then
- ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-NMEDIT=$ac_cv_prog_NMEDIT
-if test -n "$NMEDIT"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
-$as_echo "$NMEDIT" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_NMEDIT"; then
- ac_ct_NMEDIT=$NMEDIT
- # Extract the first word of "nmedit", so it can be a program name with args.
-set dummy nmedit; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_NMEDIT"; then
- ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_NMEDIT="nmedit"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
-if test -n "$ac_ct_NMEDIT"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
-$as_echo "$ac_ct_NMEDIT" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_NMEDIT" = x; then
- NMEDIT=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- NMEDIT=$ac_ct_NMEDIT
- fi
-else
- NMEDIT="$ac_cv_prog_NMEDIT"
-fi
-
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
-set dummy ${ac_tool_prefix}lipo; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_LIPO+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$LIPO"; then
- ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-LIPO=$ac_cv_prog_LIPO
-if test -n "$LIPO"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
-$as_echo "$LIPO" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_LIPO"; then
- ac_ct_LIPO=$LIPO
- # Extract the first word of "lipo", so it can be a program name with args.
-set dummy lipo; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_LIPO"; then
- ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_LIPO="lipo"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
-if test -n "$ac_ct_LIPO"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
-$as_echo "$ac_ct_LIPO" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_LIPO" = x; then
- LIPO=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- LIPO=$ac_ct_LIPO
- fi
-else
- LIPO="$ac_cv_prog_LIPO"
-fi
-
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
-set dummy ${ac_tool_prefix}otool; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_OTOOL+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$OTOOL"; then
- ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-OTOOL=$ac_cv_prog_OTOOL
-if test -n "$OTOOL"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
-$as_echo "$OTOOL" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_OTOOL"; then
- ac_ct_OTOOL=$OTOOL
- # Extract the first word of "otool", so it can be a program name with args.
-set dummy otool; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_OTOOL"; then
- ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_OTOOL="otool"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
-if test -n "$ac_ct_OTOOL"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
-$as_echo "$ac_ct_OTOOL" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_OTOOL" = x; then
- OTOOL=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- OTOOL=$ac_ct_OTOOL
- fi
-else
- OTOOL="$ac_cv_prog_OTOOL"
-fi
-
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
-set dummy ${ac_tool_prefix}otool64; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_OTOOL64+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$OTOOL64"; then
- ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-OTOOL64=$ac_cv_prog_OTOOL64
-if test -n "$OTOOL64"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
-$as_echo "$OTOOL64" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_OTOOL64"; then
- ac_ct_OTOOL64=$OTOOL64
- # Extract the first word of "otool64", so it can be a program name with args.
-set dummy otool64; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_OTOOL64"; then
- ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_prog_ac_ct_OTOOL64="otool64"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
-if test -n "$ac_ct_OTOOL64"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
-$as_echo "$ac_ct_OTOOL64" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_OTOOL64" = x; then
- OTOOL64=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- OTOOL64=$ac_ct_OTOOL64
- fi
-else
- OTOOL64="$ac_cv_prog_OTOOL64"
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
-$as_echo_n "checking for -single_module linker flag... " >&6; }
-if test "${lt_cv_apple_cc_single_mod+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_apple_cc_single_mod=no
- if test -z "${LT_MULTI_MODULE}"; then
- # By default we will add the -single_module flag. You can override
- # by either setting the environment variable LT_MULTI_MODULE
- # non-empty at configure time, or by adding -multi_module to the
- # link flags.
- rm -rf libconftest.dylib*
- echo "int foo(void){return 1;}" > conftest.c
- echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
--dynamiclib -Wl,-single_module conftest.c" >&5
- $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
- -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
- _lt_result=$?
- if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
- lt_cv_apple_cc_single_mod=yes
- else
- cat conftest.err >&5
- fi
- rm -rf libconftest.dylib*
- rm -f conftest.*
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
-$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
-$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
-if test "${lt_cv_ld_exported_symbols_list+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_ld_exported_symbols_list=no
- save_LDFLAGS=$LDFLAGS
- echo "_main" > conftest.sym
- LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- lt_cv_ld_exported_symbols_list=yes
-else
- lt_cv_ld_exported_symbols_list=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- LDFLAGS="$save_LDFLAGS"
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
-$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
-$as_echo_n "checking for -force_load linker flag... " >&6; }
-if test "${lt_cv_ld_force_load+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_ld_force_load=no
- cat > conftest.c << _LT_EOF
-int forced_loaded() { return 2;}
-_LT_EOF
- echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
- $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
- echo "$AR cru libconftest.a conftest.o" >&5
- $AR cru libconftest.a conftest.o 2>&5
- cat > conftest.c << _LT_EOF
-int main() { return 0;}
-_LT_EOF
- echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
- $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
- _lt_result=$?
- if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then
- lt_cv_ld_force_load=yes
- else
- cat conftest.err >&5
- fi
- rm -f conftest.err libconftest.a conftest conftest.c
- rm -rf conftest.dSYM
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
-$as_echo "$lt_cv_ld_force_load" >&6; }
- case $host_os in
- rhapsody* | darwin1.[012])
- _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
- darwin1.*)
- _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
- darwin*) # darwin 5.x on
- # if running on 10.5 or later, the deployment target defaults
- # to the OS version, if on x86, and 10.4, the deployment
- # target defaults to 10.4. Don't you love it?
- case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
- 10.0,*86*-darwin8*|10.0,*-darwin[91]*)
- _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
- 10.[012]*)
- _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
- 10.*)
- _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
- esac
- ;;
- esac
- if test "$lt_cv_apple_cc_single_mod" = "yes"; then
- _lt_dar_single_mod='$single_module'
- fi
- if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
- _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
- else
- _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
- fi
- if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
- _lt_dsymutil='~$DSYMUTIL $lib || :'
- else
- _lt_dsymutil=
- fi
- ;;
- esac
-
-for ac_header in dlfcn.h
-do :
- ac_fn_c_check_header_preproc "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h"
-if test "x$ac_cv_header_dlfcn_h" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_DLFCN_H 1
-_ACEOF
-
-fi
-done
-
-
-
-
-
-# Set options
-
-
-
- enable_dlopen=no
-
-
- enable_win32_dll=no
-
-
- # Check whether --enable-shared was given.
-if test "${enable_shared+set}" = set; then :
- enableval=$enable_shared; p=${PACKAGE-default}
- case $enableval in
- yes) enable_shared=yes ;;
- no) enable_shared=no ;;
- *)
- enable_shared=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_shared=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac
-else
- enable_shared=yes
-fi
-
-
-
-
-
-
-
-
-
- # Check whether --enable-static was given.
-if test "${enable_static+set}" = set; then :
- enableval=$enable_static; p=${PACKAGE-default}
- case $enableval in
- yes) enable_static=yes ;;
- no) enable_static=no ;;
- *)
- enable_static=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_static=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac
-else
- enable_static=yes
-fi
-
-
-
-
-
-
-
-
-
-
-# Check whether --with-pic was given.
-if test "${with_pic+set}" = set; then :
- withval=$with_pic; pic_mode="$withval"
-else
- pic_mode=default
-fi
-
-
-test -z "$pic_mode" && pic_mode=default
-
-
-
-
-
-
-
- # Check whether --enable-fast-install was given.
-if test "${enable_fast_install+set}" = set; then :
- enableval=$enable_fast_install; p=${PACKAGE-default}
- case $enableval in
- yes) enable_fast_install=yes ;;
- no) enable_fast_install=no ;;
- *)
- enable_fast_install=no
- # Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
- for pkg in $enableval; do
- IFS="$lt_save_ifs"
- if test "X$pkg" = "X$p"; then
- enable_fast_install=yes
- fi
- done
- IFS="$lt_save_ifs"
- ;;
- esac
-else
- enable_fast_install=yes
-fi
-
-
-
-
-
-
-
-
-
-
-
-# This can be used to rebuild libtool when needed
-LIBTOOL_DEPS="$ltmain"
-
-# Always use our own libtool.
-LIBTOOL='$(SHELL) $(top_builddir)/libtool'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-test -z "$LN_S" && LN_S="ln -s"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-if test -n "${ZSH_VERSION+set}" ; then
- setopt NO_GLOB_SUBST
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
-$as_echo_n "checking for objdir... " >&6; }
-if test "${lt_cv_objdir+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- rm -f .libs 2>/dev/null
-mkdir .libs 2>/dev/null
-if test -d .libs; then
- lt_cv_objdir=.libs
-else
- # MS-DOS does not allow filenames that begin with a dot.
- lt_cv_objdir=_libs
-fi
-rmdir .libs 2>/dev/null
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
-$as_echo "$lt_cv_objdir" >&6; }
-objdir=$lt_cv_objdir
-
-
-
-
-
-cat >>confdefs.h <<_ACEOF
-#define LT_OBJDIR "$lt_cv_objdir/"
-_ACEOF
-
-
-
-
-case $host_os in
-aix3*)
- # AIX sometimes has problems with the GCC collect2 program. For some
- # reason, if we set the COLLECT_NAMES environment variable, the problems
- # vanish in a puff of smoke.
- if test "X${COLLECT_NAMES+set}" != Xset; then
- COLLECT_NAMES=
- export COLLECT_NAMES
- fi
- ;;
-esac
-
-# Global variables:
-ofile=libtool
-can_build_shared=yes
-
-# All known linkers require a `.a' archive for static linking (except MSVC,
-# which needs '.lib').
-libext=a
-
-with_gnu_ld="$lt_cv_prog_gnu_ld"
-
-old_CC="$CC"
-old_CFLAGS="$CFLAGS"
-
-# Set sane defaults for various variables
-test -z "$CC" && CC=cc
-test -z "$LTCC" && LTCC=$CC
-test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
-test -z "$LD" && LD=ld
-test -z "$ac_objext" && ac_objext=o
-
-for cc_temp in $compiler""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
-
-
-# Only perform the check for file, if the check method requires it
-test -z "$MAGIC_CMD" && MAGIC_CMD=file
-case $deplibs_check_method in
-file_magic*)
- if test "$file_magic_cmd" = '$MAGIC_CMD'; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
-$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
-if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- case $MAGIC_CMD in
-[\\/*] | ?:[\\/]*)
- lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
- ;;
-*)
- lt_save_MAGIC_CMD="$MAGIC_CMD"
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
- for ac_dir in $ac_dummy; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/${ac_tool_prefix}file; then
- lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
- if test -n "$file_magic_test_file"; then
- case $deplibs_check_method in
- "file_magic "*)
- file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
- MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
- if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
- $EGREP "$file_magic_regex" > /dev/null; then
- :
- else
- cat <<_LT_EOF 1>&2
-
-*** Warning: the command libtool uses to detect shared libraries,
-*** $file_magic_cmd, produces output that libtool cannot recognize.
-*** The result is that libtool may fail to recognize shared libraries
-*** as such. This will affect the creation of libtool libraries that
-*** depend on shared libraries, but programs linked with such libtool
-*** libraries will work regardless of this problem. Nevertheless, you
-*** may want to report the problem to your system manager and/or to
-*** bug-libtool@gnu.org
-
-_LT_EOF
- fi ;;
- esac
- fi
- break
- fi
- done
- IFS="$lt_save_ifs"
- MAGIC_CMD="$lt_save_MAGIC_CMD"
- ;;
-esac
-fi
-
-MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
-if test -n "$MAGIC_CMD"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
-$as_echo "$MAGIC_CMD" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-
-
-
-if test -z "$lt_cv_path_MAGIC_CMD"; then
- if test -n "$ac_tool_prefix"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
-$as_echo_n "checking for file... " >&6; }
-if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- case $MAGIC_CMD in
-[\\/*] | ?:[\\/]*)
- lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
- ;;
-*)
- lt_save_MAGIC_CMD="$MAGIC_CMD"
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
- for ac_dir in $ac_dummy; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/file; then
- lt_cv_path_MAGIC_CMD="$ac_dir/file"
- if test -n "$file_magic_test_file"; then
- case $deplibs_check_method in
- "file_magic "*)
- file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
- MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
- if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
- $EGREP "$file_magic_regex" > /dev/null; then
- :
- else
- cat <<_LT_EOF 1>&2
-
-*** Warning: the command libtool uses to detect shared libraries,
-*** $file_magic_cmd, produces output that libtool cannot recognize.
-*** The result is that libtool may fail to recognize shared libraries
-*** as such. This will affect the creation of libtool libraries that
-*** depend on shared libraries, but programs linked with such libtool
-*** libraries will work regardless of this problem. Nevertheless, you
-*** may want to report the problem to your system manager and/or to
-*** bug-libtool@gnu.org
-
-_LT_EOF
- fi ;;
- esac
- fi
- break
- fi
- done
- IFS="$lt_save_ifs"
- MAGIC_CMD="$lt_save_MAGIC_CMD"
- ;;
-esac
-fi
-
-MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
-if test -n "$MAGIC_CMD"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
-$as_echo "$MAGIC_CMD" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- else
- MAGIC_CMD=:
- fi
-fi
-
- fi
- ;;
-esac
-
-# Use C for the default configuration in the libtool script
-
-lt_save_CC="$CC"
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-# Source file extension for C test sources.
-ac_ext=c
-
-# Object file extension for compiled C test sources.
-objext=o
-objext=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code="int some_variable = 0;"
-
-# Code to be used in simple link tests
-lt_simple_link_test_code='int main(){return(0);}'
-
-
-
-
-
-
-
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
-
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
-
-# Allow CC to be a program name with arguments.
-compiler=$CC
-
-# Save the default compiler, since it gets overwritten when the other
-# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
-compiler_DEFAULT=$CC
-
-# save warnings/boilerplate of simple test code
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_compiler_boilerplate=`cat conftest.err`
-$RM conftest*
-
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_linker_boilerplate=`cat conftest.err`
-$RM -r conftest*
-
-
-## CAVEAT EMPTOR:
-## There is no encapsulation within the following macros, do not change
-## the running order or otherwise move them around unless you know exactly
-## what you are doing...
-if test -n "$compiler"; then
-
-lt_prog_compiler_no_builtin_flag=
-
-if test "$GCC" = yes; then
- case $cc_basename in
- nvcc*)
- lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
- *)
- lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
- esac
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
-$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
-if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_prog_compiler_rtti_exceptions=no
- ac_outfile=conftest.$ac_objext
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="-fno-rtti -fno-exceptions"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- # The option is referenced via a variable to avoid confusing sed.
- lt_compile=`echo "$ac_compile" | $SED \
- -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:$LINENO: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $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.
- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_rtti_exceptions=yes
- fi
- fi
- $RM conftest*
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
-$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
-
-if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
- lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
-else
- :
-fi
-
-fi
-
-
-
-
-
-
- lt_prog_compiler_wl=
-lt_prog_compiler_pic=
-lt_prog_compiler_static=
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
-$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
-
- if test "$GCC" = yes; then
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_static='-static'
-
- case $host_os in
- aix*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static='-Bstatic'
- fi
- lt_prog_compiler_pic='-fPIC'
- ;;
-
- amigaos*)
- case $host_cpu in
- powerpc)
- # see comment about AmigaOS4 .so support
- lt_prog_compiler_pic='-fPIC'
- ;;
- m68k)
- # FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
- lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
- ;;
- esac
- ;;
-
- beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
- # PIC is the default for these OSes.
- ;;
-
- mingw* | cygwin* | pw32* | os2* | cegcc*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- # Although the cygwin gcc ignores -fPIC, still need this for old-style
- # (--disable-auto-import) libraries
- lt_prog_compiler_pic='-DDLL_EXPORT'
- ;;
-
- darwin* | rhapsody*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- lt_prog_compiler_pic='-fno-common'
- ;;
-
- haiku*)
- # PIC is the default for Haiku.
- # The "-static" flag exists, but is broken.
- lt_prog_compiler_static=
- ;;
-
- hpux*)
- # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
- # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
- # sets the default TLS model and affects inlining.
- case $host_cpu in
- hppa*64*)
- # +Z the default
- ;;
- *)
- lt_prog_compiler_pic='-fPIC'
- ;;
- esac
- ;;
-
- interix[3-9]*)
- # Interix 3.x gcc -fpic/-fPIC options generate broken code.
- # Instead, we relocate shared libraries at runtime.
- ;;
-
- msdosdjgpp*)
- # Just because we use GCC doesn't mean we suddenly get shared libraries
- # on systems that don't support them.
- lt_prog_compiler_can_build_shared=no
- enable_shared=no
- ;;
-
- *nto* | *qnx*)
- # QNX uses GNU C++, but need to define -shared option too, otherwise
- # it will coredump.
- lt_prog_compiler_pic='-fPIC -shared'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- lt_prog_compiler_pic=-Kconform_pic
- fi
- ;;
-
- *)
- lt_prog_compiler_pic='-fPIC'
- ;;
- esac
-
- case $cc_basename in
- nvcc*) # Cuda Compiler Driver 2.2
- lt_prog_compiler_wl='-Xlinker '
- lt_prog_compiler_pic='-Xcompiler -fPIC'
- ;;
- esac
- else
- # PORTME Check for flag to pass linker flags through the system compiler.
- case $host_os in
- aix*)
- lt_prog_compiler_wl='-Wl,'
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static='-Bstatic'
- else
- lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
- fi
- ;;
-
- mingw* | cygwin* | pw32* | os2* | cegcc*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- lt_prog_compiler_pic='-DDLL_EXPORT'
- ;;
-
- hpux9* | hpux10* | hpux11*)
- lt_prog_compiler_wl='-Wl,'
- # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
- # not for PA HP-UX.
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- lt_prog_compiler_pic='+Z'
- ;;
- esac
- # Is there a better lt_prog_compiler_static that works with the bundled CC?
- lt_prog_compiler_static='${wl}-a ${wl}archive'
- ;;
-
- irix5* | irix6* | nonstopux*)
- lt_prog_compiler_wl='-Wl,'
- # PIC (with -KPIC) is the default.
- lt_prog_compiler_static='-non_shared'
- ;;
-
- linux* | k*bsd*-gnu | kopensolaris*-gnu)
- case $cc_basename in
- # old Intel for x86_64 which still supported -KPIC.
- ecc*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-static'
- ;;
- # icc used to be incompatible with GCC.
- # ICC 10 doesn't accept -KPIC any more.
- icc* | ifort*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-fPIC'
- lt_prog_compiler_static='-static'
- ;;
- # Lahey Fortran 8.1.
- lf95*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='--shared'
- lt_prog_compiler_static='--static'
- ;;
- pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
- # Portland Group compilers (*not* the Pentium gcc compiler,
- # which looks to be a dead project)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-fpic'
- lt_prog_compiler_static='-Bstatic'
- ;;
- ccc*)
- lt_prog_compiler_wl='-Wl,'
- # All Alpha code is PIC.
- lt_prog_compiler_static='-non_shared'
- ;;
- xl* | bgxl* | bgf* | mpixl*)
- # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-qpic'
- lt_prog_compiler_static='-qstaticlink'
- ;;
- *)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ F* | *Sun*Fortran*)
- # Sun Fortran 8.3 passes all unrecognized flags to the linker
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- lt_prog_compiler_wl=''
- ;;
- *Sun\ C*)
- # Sun C 5.9
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- lt_prog_compiler_wl='-Wl,'
- ;;
- esac
- ;;
- esac
- ;;
-
- newsos6)
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- *nto* | *qnx*)
- # QNX uses GNU C++, but need to define -shared option too, otherwise
- # it will coredump.
- lt_prog_compiler_pic='-fPIC -shared'
- ;;
-
- osf3* | osf4* | osf5*)
- lt_prog_compiler_wl='-Wl,'
- # All OSF/1 code is PIC.
- lt_prog_compiler_static='-non_shared'
- ;;
-
- rdos*)
- lt_prog_compiler_static='-non_shared'
- ;;
-
- solaris*)
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- case $cc_basename in
- f77* | f90* | f95*)
- lt_prog_compiler_wl='-Qoption ld ';;
- *)
- lt_prog_compiler_wl='-Wl,';;
- esac
- ;;
-
- sunos4*)
- lt_prog_compiler_wl='-Qoption ld '
- lt_prog_compiler_pic='-PIC'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- sysv4 | sysv4.2uw2* | sysv4.3*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec ;then
- lt_prog_compiler_pic='-Kconform_pic'
- lt_prog_compiler_static='-Bstatic'
- fi
- ;;
-
- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_pic='-KPIC'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- unicos*)
- lt_prog_compiler_wl='-Wl,'
- lt_prog_compiler_can_build_shared=no
- ;;
-
- uts4*)
- lt_prog_compiler_pic='-pic'
- lt_prog_compiler_static='-Bstatic'
- ;;
-
- *)
- lt_prog_compiler_can_build_shared=no
- ;;
- esac
- fi
-
-case $host_os in
- # For platforms which do not support PIC, -DPIC is meaningless:
- *djgpp*)
- lt_prog_compiler_pic=
- ;;
- *)
- lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
- ;;
-esac
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5
-$as_echo "$lt_prog_compiler_pic" >&6; }
-
-
-
-
-
-
-#
-# Check to make sure the PIC flag actually works.
-#
-if test -n "$lt_prog_compiler_pic"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
-$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
-if test "${lt_cv_prog_compiler_pic_works+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_prog_compiler_pic_works=no
- ac_outfile=conftest.$ac_objext
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- # The option is referenced via a variable to avoid confusing sed.
- lt_compile=`echo "$ac_compile" | $SED \
- -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:$LINENO: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $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.
- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_pic_works=yes
- fi
- fi
- $RM conftest*
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
-$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
-
-if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
- case $lt_prog_compiler_pic in
- "" | " "*) ;;
- *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
- esac
-else
- lt_prog_compiler_pic=
- lt_prog_compiler_can_build_shared=no
-fi
-
-fi
-
-
-
-
-
-
-#
-# Check to make sure the static flag actually works.
-#
-wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
-$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
-if test "${lt_cv_prog_compiler_static_works+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_prog_compiler_static_works=no
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
- echo "$lt_simple_link_test_code" > conftest.$ac_ext
- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
- # The linker can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test -s conftest.err; then
- # Append any errors to the config.log.
- cat conftest.err 1>&5
- $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_static_works=yes
- fi
- else
- lt_cv_prog_compiler_static_works=yes
- fi
- fi
- $RM -r conftest*
- LDFLAGS="$save_LDFLAGS"
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
-$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
-
-if test x"$lt_cv_prog_compiler_static_works" = xyes; then
- :
-else
- lt_prog_compiler_static=
-fi
-
-
-
-
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
-$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
-if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_prog_compiler_c_o=no
- $RM -r conftest 2>/dev/null
- mkdir conftest
- cd conftest
- mkdir out
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- lt_compiler_flag="-o out/conftest2.$ac_objext"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- lt_compile=`echo "$ac_compile" | $SED \
- -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:$LINENO: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
- echo "$as_me:$LINENO: \$? = $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
- # So say no if there are warnings
- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
- $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
- if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_c_o=yes
- fi
- fi
- chmod u+w . 2>&5
- $RM conftest*
- # SGI C++ compiler will create directory out/ii_files/ for
- # template instantiation
- test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
- $RM out/* && rmdir out
- cd ..
- $RM -r conftest
- $RM conftest*
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
-$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
-
-
-
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
-$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
-if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_prog_compiler_c_o=no
- $RM -r conftest 2>/dev/null
- mkdir conftest
- cd conftest
- mkdir out
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- lt_compiler_flag="-o out/conftest2.$ac_objext"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- lt_compile=`echo "$ac_compile" | $SED \
- -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:$LINENO: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
- echo "$as_me:$LINENO: \$? = $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
- # So say no if there are warnings
- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
- $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
- if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_c_o=yes
- fi
- fi
- chmod u+w . 2>&5
- $RM conftest*
- # SGI C++ compiler will create directory out/ii_files/ for
- # template instantiation
- test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
- $RM out/* && rmdir out
- cd ..
- $RM -r conftest
- $RM conftest*
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
-$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
-
-
-
-
-hard_links="nottested"
-if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
- # do not overwrite the value of need_locks provided by the user
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
-$as_echo_n "checking if we can lock with hard links... " >&6; }
- hard_links=yes
- $RM conftest*
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- touch conftest.a
- ln conftest.a conftest.b 2>&5 || hard_links=no
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
-$as_echo "$hard_links" >&6; }
- if test "$hard_links" = no; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
-$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
- need_locks=warn
- fi
-else
- need_locks=no
-fi
-
-
-
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
-$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
-
- runpath_var=
- allow_undefined_flag=
- always_export_symbols=no
- archive_cmds=
- archive_expsym_cmds=
- compiler_needs_object=no
- enable_shared_with_static_runtimes=no
- export_dynamic_flag_spec=
- export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- hardcode_automatic=no
- hardcode_direct=no
- hardcode_direct_absolute=no
- hardcode_libdir_flag_spec=
- hardcode_libdir_flag_spec_ld=
- hardcode_libdir_separator=
- hardcode_minus_L=no
- hardcode_shlibpath_var=unsupported
- inherit_rpath=no
- link_all_deplibs=unknown
- module_cmds=
- module_expsym_cmds=
- old_archive_from_new_cmds=
- old_archive_from_expsyms_cmds=
- thread_safe_flag_spec=
- whole_archive_flag_spec=
- # include_expsyms should be a list of space-separated symbols to be *always*
- # included in the symbol list
- include_expsyms=
- # exclude_expsyms can be an extended regexp of symbols to exclude
- # it will be wrapped by ` (' and `)$', so one must not match beginning or
- # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
- # as well as any symbol that contains `d'.
- exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
- # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
- # platforms (ab)use it in PIC code, but their linkers get confused if
- # the symbol is explicitly referenced. Since portable code cannot
- # rely on this symbol name, it's probably fine to never include it in
- # preloaded symbol tables.
- # Exclude shared library initialization/finalization symbols.
- extract_expsyms_cmds=
-
- case $host_os in
- cygwin* | mingw* | pw32* | cegcc*)
- # FIXME: the MSVC++ port hasn't been tested in a loooong time
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- if test "$GCC" != yes; then
- with_gnu_ld=no
- fi
- ;;
- interix*)
- # we just hope/assume this is gcc and not c89 (= MSVC++)
- with_gnu_ld=yes
- ;;
- openbsd*)
- with_gnu_ld=no
- ;;
- esac
-
- ld_shlibs=yes
-
- # On some targets, GNU ld is compatible enough with the native linker
- # that we're better off using the native interface for both.
- lt_use_gnu_ld_interface=no
- if test "$with_gnu_ld" = yes; then
- case $host_os in
- aix*)
- # The AIX port of GNU ld has always aspired to compatibility
- # with the native linker. However, as the warning in the GNU ld
- # block says, versions before 2.19.5* couldn't really create working
- # shared libraries, regardless of the interface used.
- case `$LD -v 2>&1` in
- *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
- *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
- *\ \(GNU\ Binutils\)\ [3-9]*) ;;
- *)
- lt_use_gnu_ld_interface=yes
- ;;
- esac
- ;;
- *)
- lt_use_gnu_ld_interface=yes
- ;;
- esac
- fi
-
- if test "$lt_use_gnu_ld_interface" = yes; then
- # If archive_cmds runs LD, not CC, wlarc should be empty
- wlarc='${wl}'
-
- # Set some defaults for GNU ld with shared library support. These
- # are reset later if shared libraries are not supported. Putting them
- # here allows them to be overridden if necessary.
- runpath_var=LD_RUN_PATH
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- export_dynamic_flag_spec='${wl}--export-dynamic'
- # ancient GNU ld didn't support --whole-archive et. al.
- if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
- whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- else
- whole_archive_flag_spec=
- fi
- supports_anon_versioning=no
- case `$LD -v 2>&1` in
- *GNU\ gold*) supports_anon_versioning=yes ;;
- *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
- *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
- *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
- *\ 2.11.*) ;; # other 2.11 versions
- *) supports_anon_versioning=yes ;;
- esac
-
- # See if GNU ld supports shared libraries.
- case $host_os in
- aix[3-9]*)
- # On AIX/PPC, the GNU linker is very broken
- if test "$host_cpu" != ia64; then
- ld_shlibs=no
- cat <<_LT_EOF 1>&2
-
-*** Warning: the GNU linker, at least up to release 2.19, is reported
-*** to be unable to reliably create shared libraries on AIX.
-*** Therefore, libtool is disabling shared libraries support. If you
-*** really care for shared libraries, you may want to install binutils
-*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
-*** You will then need to restart the configuration process.
-
-_LT_EOF
- fi
- ;;
-
- amigaos*)
- case $host_cpu in
- powerpc)
- # see comment about AmigaOS4 .so support
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds=''
- ;;
- m68k)
- archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- ;;
- esac
- ;;
-
- beos*)
- if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- allow_undefined_flag=unsupported
- # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
- # support --undefined. This deserves some investigation. FIXME
- archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- else
- ld_shlibs=no
- fi
- ;;
-
- cygwin* | mingw* | pw32* | cegcc*)
- # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
- # as there is no search path for DLLs.
- hardcode_libdir_flag_spec='-L$libdir'
- export_dynamic_flag_spec='${wl}--export-all-symbols'
- allow_undefined_flag=unsupported
- always_export_symbols=no
- enable_shared_with_static_runtimes=yes
- export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
-
- if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file (1st line
- # is EXPORTS), use it as is; otherwise, prepend...
- archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- else
- ld_shlibs=no
- fi
- ;;
-
- haiku*)
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- link_all_deplibs=yes
- ;;
-
- interix[3-9]*)
- hardcode_direct=no
- hardcode_shlibpath_var=no
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- export_dynamic_flag_spec='${wl}-E'
- # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
- # Instead, shared libraries are loaded at an image base (0x10000000 by
- # default) and relocated if they conflict, which is a slow very memory
- # consuming and fragmenting process. To avoid this, we pick a random,
- # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
- # time. Moving up from 0x10000000 also allows more sbrk(2) space.
- archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- ;;
-
- gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
- tmp_diet=no
- if test "$host_os" = linux-dietlibc; then
- case $cc_basename in
- diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
- esac
- fi
- if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
- && test "$tmp_diet" = no
- then
- tmp_addflag=
- tmp_sharedflag='-shared'
- case $cc_basename,$host_cpu in
- pgcc*) # Portland Group C compiler
- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag'
- ;;
- pgf77* | pgf90* | pgf95* | pgfortran*)
- # Portland Group f77 and f90 compilers
- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
- tmp_addflag=' $pic_flag -Mnomain' ;;
- ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
- tmp_addflag=' -i_dynamic' ;;
- efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
- tmp_addflag=' -i_dynamic -nofor_main' ;;
- ifc* | ifort*) # Intel Fortran compiler
- tmp_addflag=' -nofor_main' ;;
- lf95*) # Lahey Fortran 8.1
- whole_archive_flag_spec=
- tmp_sharedflag='--shared' ;;
- xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
- tmp_sharedflag='-qmkshrobj'
- tmp_addflag= ;;
- nvcc*) # Cuda Compiler Driver 2.2
- whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
- compiler_needs_object=yes
- ;;
- esac
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*) # Sun C 5.9
- whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
- compiler_needs_object=yes
- tmp_sharedflag='-G' ;;
- *Sun\ F*) # Sun Fortran 8.3
- tmp_sharedflag='-G' ;;
- esac
- archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-
- if test "x$supports_anon_versioning" = xyes; then
- archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
- fi
-
- case $cc_basename in
- xlf* | bgf* | bgxlf* | mpixlf*)
- # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
- whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
- hardcode_libdir_flag_spec=
- hardcode_libdir_flag_spec_ld='-rpath $libdir'
- archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
- if test "x$supports_anon_versioning" = xyes; then
- archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- echo "local: *; };" >> $output_objdir/$libname.ver~
- $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
- fi
- ;;
- esac
- else
- ld_shlibs=no
- fi
- ;;
-
- netbsd*)
- if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
- archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
- wlarc=
- else
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- fi
- ;;
-
- solaris*)
- if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
- ld_shlibs=no
- cat <<_LT_EOF 1>&2
-
-*** Warning: The releases 2.8.* of the GNU linker cannot reliably
-*** create shared libraries on Solaris systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.9.1 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-_LT_EOF
- elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- ld_shlibs=no
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
- case `$LD -v 2>&1` in
- *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
- ld_shlibs=no
- cat <<_LT_EOF 1>&2
-
-*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
-*** reliably create shared libraries on SCO systems. Therefore, libtool
-*** is disabling shared libraries support. We urge you to upgrade GNU
-*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
-
-_LT_EOF
- ;;
- *)
- # For security reasons, it is highly recommended that you always
- # use absolute paths for naming shared libraries, and exclude the
- # DT_RUNPATH tag from executables and libraries. But doing so
- # requires that you compile everything twice, which is a pain.
- if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- ld_shlibs=no
- fi
- ;;
- esac
- ;;
-
- sunos4*)
- archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- wlarc=
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- *)
- if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- else
- ld_shlibs=no
- fi
- ;;
- esac
-
- if test "$ld_shlibs" = no; then
- runpath_var=
- hardcode_libdir_flag_spec=
- export_dynamic_flag_spec=
- whole_archive_flag_spec=
- fi
- else
- # PORTME fill in a description of your system's linker (not GNU ld)
- case $host_os in
- aix3*)
- allow_undefined_flag=unsupported
- always_export_symbols=yes
- archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
- # Note: this linker hardcodes the directories in LIBPATH if there
- # are no directories specified by -L.
- hardcode_minus_L=yes
- if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
- # Neither direct hardcoding nor static linking is supported with a
- # broken collect2.
- hardcode_direct=unsupported
- fi
- ;;
-
- aix[4-9]*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- exp_sym_flag='-Bexport'
- no_entry_flag=""
- else
- # If we're using GNU nm, then we don't want the "-C" option.
- # -C means demangle to AIX nm, but means don't demangle with GNU nm
- # Also, AIX nm treats weak defined symbols like other global
- # defined symbols, whereas GNU nm marks them as "W".
- if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
- export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
- else
- export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
- fi
- aix_use_runtimelinking=no
-
- # Test if we are trying to use run time linking or normal
- # AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
- case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
- for ld_flag in $LDFLAGS; do
- if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
- aix_use_runtimelinking=yes
- break
- fi
- done
- ;;
- esac
-
- exp_sym_flag='-bexport'
- no_entry_flag='-bnoentry'
- fi
-
- # When large executables or shared objects are built, AIX ld can
- # have problems creating the table of contents. If linking a library
- # or program results in "error TOC overflow" add -mminimal-toc to
- # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
- # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
-
- archive_cmds=''
- hardcode_direct=yes
- hardcode_direct_absolute=yes
- hardcode_libdir_separator=':'
- link_all_deplibs=yes
- file_list_spec='${wl}-f,'
-
- if test "$GCC" = yes; then
- case $host_os in aix4.[012]|aix4.[012].*)
- # We only want to do this on AIX 4.2 and lower, the check
- # below for broken collect2 doesn't work under 4.3+
- collect2name=`${CC} -print-prog-name=collect2`
- if test -f "$collect2name" &&
- strings "$collect2name" | $GREP resolve_lib_name >/dev/null
- then
- # We have reworked collect2
- :
- else
- # We have old collect2
- hardcode_direct=unsupported
- # It fails to find uninstalled libraries when the uninstalled
- # path is not listed in the libpath. Setting hardcode_minus_L
- # to unsupported forces relinking
- hardcode_minus_L=yes
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_libdir_separator=
- fi
- ;;
- esac
- shared_flag='-shared'
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag="$shared_flag "'${wl}-G'
- fi
- else
- # not using gcc
- if test "$host_cpu" = ia64; then
- # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
- # chokes on -Wl,-G. The following line is correct:
- shared_flag='-G'
- else
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag='${wl}-G'
- else
- shared_flag='${wl}-bM:SRE'
- fi
- fi
- fi
-
- export_dynamic_flag_spec='${wl}-bexpall'
- # It seems that -bexpall does not export symbols beginning with
- # underscore (_), so it is better to generate a list of symbols to export.
- always_export_symbols=yes
- if test "$aix_use_runtimelinking" = yes; then
- # Warning - without using the other runtime loading flags (-brtl),
- # -berok will link without error, but may produce a broken library.
- allow_undefined_flag='-berok'
- # Determine the default libpath from the value encoded in an
- # empty executable.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then
- aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-fi
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
-
- hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
- archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
- else
- if test "$host_cpu" = ia64; then
- hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
- allow_undefined_flag="-z nodefs"
- archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
- else
- # Determine the default libpath from the value encoded in an
- # empty executable.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then
- aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-fi
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
-
- hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
- # Warning - without using the other run time loading flags,
- # -berok will link without error, but may produce a broken library.
- no_undefined_flag=' ${wl}-bernotok'
- allow_undefined_flag=' ${wl}-berok'
- if test "$with_gnu_ld" = yes; then
- # We only use this code for GNU lds that support --whole-archive.
- whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
- else
- # Exported symbols can be pulled into shared objects from archives
- whole_archive_flag_spec='$convenience'
- fi
- archive_cmds_need_lc=yes
- # This is similar to how AIX traditionally builds its shared libraries.
- archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
- fi
- fi
- ;;
-
- amigaos*)
- case $host_cpu in
- powerpc)
- # see comment about AmigaOS4 .so support
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds=''
- ;;
- m68k)
- archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- ;;
- esac
- ;;
-
- bsdi[45]*)
- export_dynamic_flag_spec=-rdynamic
- ;;
-
- cygwin* | mingw* | pw32* | cegcc*)
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- # hardcode_libdir_flag_spec is actually meaningless, as there is
- # no search path for DLLs.
- hardcode_libdir_flag_spec=' '
- allow_undefined_flag=unsupported
- # Tell ltmain to make .lib files, not .a files.
- libext=lib
- # Tell ltmain to make .dll files, not .so files.
- shrext_cmds=".dll"
- # FIXME: Setting linknames here is a bad hack.
- archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
- # The linker will automatically build a .lib file if we build a DLL.
- old_archive_from_new_cmds='true'
- # FIXME: Should let the user specify the lib program.
- old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
- fix_srcfile_path='`cygpath -w "$srcfile"`'
- enable_shared_with_static_runtimes=yes
- ;;
-
- darwin* | rhapsody*)
-
-
- archive_cmds_need_lc=no
- hardcode_direct=no
- hardcode_automatic=yes
- hardcode_shlibpath_var=unsupported
- if test "$lt_cv_ld_force_load" = "yes"; then
- whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
- else
- whole_archive_flag_spec=''
- fi
- link_all_deplibs=yes
- allow_undefined_flag="$_lt_dar_allow_undefined"
- case $cc_basename in
- ifort*) _lt_dar_can_shared=yes ;;
- *) _lt_dar_can_shared=$GCC ;;
- esac
- if test "$_lt_dar_can_shared" = "yes"; then
- output_verbose_link_cmd=func_echo_all
- archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
- module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
- archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
- module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
-
- else
- ld_shlibs=no
- fi
-
- ;;
-
- dgux*)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_shlibpath_var=no
- ;;
-
- # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
- # support. Future versions do this automatically, but an explicit c++rt0.o
- # does not break anything, and helps significantly (at the cost of a little
- # extra space).
- freebsd2.2*)
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- # Unfortunately, older versions of FreeBSD 2 do not have this feature.
- freebsd2.*)
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=yes
- hardcode_minus_L=yes
- hardcode_shlibpath_var=no
- ;;
-
- # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
- freebsd* | dragonfly*)
- archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- hpux9*)
- if test "$GCC" = yes; then
- archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- else
- archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- fi
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
- hardcode_direct=yes
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- export_dynamic_flag_spec='${wl}-E'
- ;;
-
- hpux10*)
- if test "$GCC" = yes && test "$with_gnu_ld" = no; then
- archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
- fi
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_flag_spec_ld='+b $libdir'
- hardcode_libdir_separator=:
- hardcode_direct=yes
- hardcode_direct_absolute=yes
- export_dynamic_flag_spec='${wl}-E'
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- fi
- ;;
-
- hpux11*)
- if test "$GCC" = yes && test "$with_gnu_ld" = no; then
- case $host_cpu in
- hppa*64*)
- archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- else
- case $host_cpu in
- hppa*64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- ia64*)
- archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
-
- # Older versions of the 11.00 compiler do not understand -b yet
- # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
-$as_echo_n "checking if $CC understands -b... " >&6; }
-if test "${lt_cv_prog_compiler__b+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_prog_compiler__b=no
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS -b"
- echo "$lt_simple_link_test_code" > conftest.$ac_ext
- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
- # The linker can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test -s conftest.err; then
- # Append any errors to the config.log.
- cat conftest.err 1>&5
- $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler__b=yes
- fi
- else
- lt_cv_prog_compiler__b=yes
- fi
- fi
- $RM -r conftest*
- LDFLAGS="$save_LDFLAGS"
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
-$as_echo "$lt_cv_prog_compiler__b" >&6; }
-
-if test x"$lt_cv_prog_compiler__b" = xyes; then
- archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
-else
- archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
-fi
-
- ;;
- esac
- fi
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
-
- case $host_cpu in
- hppa*64*|ia64*)
- hardcode_direct=no
- hardcode_shlibpath_var=no
- ;;
- *)
- hardcode_direct=yes
- hardcode_direct_absolute=yes
- export_dynamic_flag_spec='${wl}-E'
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- ;;
- esac
- fi
- ;;
-
- irix5* | irix6* | nonstopux*)
- if test "$GCC" = yes; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- # Try to use the -exported_symbol ld option, if it does not
- # work, assume that -exports_file does not work either and
- # implicitly export all symbols.
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-int foo(void) {}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
-
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- LDFLAGS="$save_LDFLAGS"
- else
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
- archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
- fi
- archive_cmds_need_lc='no'
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- inherit_rpath=yes
- link_all_deplibs=yes
- ;;
-
- netbsd*)
- if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
- else
- archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
- fi
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- ;;
-
- newsos6)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=yes
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- hardcode_shlibpath_var=no
- ;;
-
- *nto* | *qnx*)
- ;;
-
- openbsd*)
- if test -f /usr/libexec/ld.so; then
- hardcode_direct=yes
- hardcode_shlibpath_var=no
- hardcode_direct_absolute=yes
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- export_dynamic_flag_spec='${wl}-E'
- else
- case $host_os in
- openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
- archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec='-R$libdir'
- ;;
- *)
- archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- ;;
- esac
- fi
- else
- ld_shlibs=no
- fi
- ;;
-
- os2*)
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- allow_undefined_flag=unsupported
- archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
- old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
- ;;
-
- osf3*)
- if test "$GCC" = yes; then
- allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- allow_undefined_flag=' -expect_unresolved \*'
- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
- fi
- archive_cmds_need_lc='no'
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- ;;
-
- osf4* | osf5*) # as osf3* with the addition of -msym flag
- if test "$GCC" = yes; then
- allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- else
- allow_undefined_flag=' -expect_unresolved \*'
- archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
- archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
- $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
-
- # Both c and cxx compiler support -rpath directly
- hardcode_libdir_flag_spec='-rpath $libdir'
- fi
- archive_cmds_need_lc='no'
- hardcode_libdir_separator=:
- ;;
-
- solaris*)
- no_undefined_flag=' -z defs'
- if test "$GCC" = yes; then
- wlarc='${wl}'
- archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
- else
- case `$CC -V 2>&1` in
- *"Compilers 5.0"*)
- wlarc=''
- archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
- archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
- ;;
- *)
- wlarc='${wl}'
- archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
- ;;
- esac
- fi
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_shlibpath_var=no
- case $host_os in
- solaris2.[0-5] | solaris2.[0-5].*) ;;
- *)
- # The compiler driver will combine and reorder linker options,
- # but understands `-z linker_flag'. GCC discards it without `$wl',
- # but is careful enough not to reorder.
- # Supported since Solaris 2.6 (maybe 2.5.1?)
- if test "$GCC" = yes; then
- whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
- else
- whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
- fi
- ;;
- esac
- link_all_deplibs=yes
- ;;
-
- sunos4*)
- if test "x$host_vendor" = xsequent; then
- # Use $CC to link under sequent, because it throws in some extra .o
- # files that make .init and .fini sections work.
- archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
- fi
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_direct=yes
- hardcode_minus_L=yes
- hardcode_shlibpath_var=no
- ;;
-
- sysv4)
- case $host_vendor in
- sni)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=yes # is this really true???
- ;;
- siemens)
- ## LD is ld it makes a PLAMLIB
- ## CC just makes a GrossModule.
- archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
- reload_cmds='$CC -r -o $output$reload_objs'
- hardcode_direct=no
- ;;
- motorola)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=no #Motorola manual says yes, but my tests say they lie
- ;;
- esac
- runpath_var='LD_RUN_PATH'
- hardcode_shlibpath_var=no
- ;;
-
- sysv4.3*)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var=no
- export_dynamic_flag_spec='-Bexport'
- ;;
-
- sysv4*MP*)
- if test -d /usr/nec; then
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var=no
- runpath_var=LD_RUN_PATH
- hardcode_runpath_var=yes
- ld_shlibs=yes
- fi
- ;;
-
- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
- no_undefined_flag='${wl}-z,text'
- archive_cmds_need_lc=no
- hardcode_shlibpath_var=no
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- sysv5* | sco3.2v5* | sco5v6*)
- # Note: We can NOT use -z defs as we might desire, because we do not
- # link with -lc, and that would cause any symbols used from libc to
- # always be unresolved, which means just about no library would
- # ever link correctly. If we're not using GNU ld we use -z text
- # though, which does catch some bad symbols but isn't as heavy-handed
- # as -z defs.
- no_undefined_flag='${wl}-z,text'
- allow_undefined_flag='${wl}-z,nodefs'
- archive_cmds_need_lc=no
- hardcode_shlibpath_var=no
- hardcode_libdir_flag_spec='${wl}-R,$libdir'
- hardcode_libdir_separator=':'
- link_all_deplibs=yes
- export_dynamic_flag_spec='${wl}-Bexport'
- runpath_var='LD_RUN_PATH'
-
- if test "$GCC" = yes; then
- archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- else
- archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- fi
- ;;
-
- uts4*)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_shlibpath_var=no
- ;;
-
- *)
- ld_shlibs=no
- ;;
- esac
-
- if test x$host_vendor = xsni; then
- case $host in
- sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
- export_dynamic_flag_spec='${wl}-Blargedynsym'
- ;;
- esac
- fi
- fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
-$as_echo "$ld_shlibs" >&6; }
-test "$ld_shlibs" = no && can_build_shared=no
-
-with_gnu_ld=$with_gnu_ld
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#
-# Do we need to explicitly link libc?
-#
-case "x$archive_cmds_need_lc" in
-x|xyes)
- # Assume -lc should be added
- archive_cmds_need_lc=yes
-
- if test "$enable_shared" = yes && test "$GCC" = yes; then
- case $archive_cmds in
- *'~'*)
- # FIXME: we may have to deal with multi-command sequences.
- ;;
- '$CC '*)
- # Test whether the compiler implicitly links with -lc since on some
- # systems, -lgcc has to come before -lc. If gcc already passes -lc
- # to ld, don't add -lc before -lgcc.
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
-$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
-if test "${lt_cv_archive_cmds_need_lc+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- $RM conftest*
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } 2>conftest.err; then
- soname=conftest
- lib=conftest
- libobjs=conftest.$ac_objext
- deplibs=
- wl=$lt_prog_compiler_wl
- pic_flag=$lt_prog_compiler_pic
- compiler_flags=-v
- linker_flags=-v
- verstring=
- output_objdir=.
- libname=conftest
- lt_save_allow_undefined_flag=$allow_undefined_flag
- allow_undefined_flag=
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
- (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }
- then
- lt_cv_archive_cmds_need_lc=no
- else
- lt_cv_archive_cmds_need_lc=yes
- fi
- allow_undefined_flag=$lt_save_allow_undefined_flag
- else
- cat conftest.err 1>&5
- fi
- $RM conftest*
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
-$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
- archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
- ;;
- esac
- fi
- ;;
-esac
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
-$as_echo_n "checking dynamic linker characteristics... " >&6; }
-
-if test "$GCC" = yes; then
- case $host_os in
- darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
- *) lt_awk_arg="/^libraries:/" ;;
- esac
- case $host_os in
- mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
- *) lt_sed_strip_eq="s,=/,/,g" ;;
- esac
- lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
- case $lt_search_path_spec in
- *\;*)
- # if the path contains ";" then we assume it to be the separator
- # otherwise default to the standard path separator (i.e. ":") - it is
- # assumed that no part of a normal pathname contains ";" but that should
- # okay in the real world where ";" in dirpaths is itself problematic.
- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
- ;;
- *)
- lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
- ;;
- esac
- # Ok, now we have the path, separated by spaces, we can step through it
- # and add multilib dir if necessary.
- lt_tmp_lt_search_path_spec=
- lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
- for lt_sys_path in $lt_search_path_spec; do
- if test -d "$lt_sys_path/$lt_multi_os_dir"; then
- lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
- else
- test -d "$lt_sys_path" && \
- lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
- fi
- done
- lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
-BEGIN {RS=" "; FS="/|\n";} {
- lt_foo="";
- lt_count=0;
- for (lt_i = NF; lt_i > 0; lt_i--) {
- if ($lt_i != "" && $lt_i != ".") {
- if ($lt_i == "..") {
- lt_count++;
- } else {
- if (lt_count == 0) {
- lt_foo="/" $lt_i lt_foo;
- } else {
- lt_count--;
- }
- }
- }
- }
- if (lt_foo != "") { lt_freq[lt_foo]++; }
- if (lt_freq[lt_foo] == 1) { print lt_foo; }
-}'`
- # AWK program above erroneously prepends '/' to C:/dos/paths
- # for these hosts.
- case $host_os in
- mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
- $SED 's,/\([A-Za-z]:\),\1,g'` ;;
- esac
- sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
-else
- sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-fi
-library_names_spec=
-libname_spec='lib$name'
-soname_spec=
-shrext_cmds=".so"
-postinstall_cmds=
-postuninstall_cmds=
-finish_cmds=
-finish_eval=
-shlibpath_var=
-shlibpath_overrides_runpath=unknown
-version_type=none
-dynamic_linker="$host_os ld.so"
-sys_lib_dlsearch_path_spec="/lib /usr/lib"
-need_lib_prefix=unknown
-hardcode_into_libs=no
-
-# when you set need_version to no, make sure it does not cause -set_version
-# flags to be left without arguments
-need_version=unknown
-
-case $host_os in
-aix3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
- shlibpath_var=LIBPATH
-
- # AIX 3 has no versioning support, so we append a major version to the name.
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
-
-aix[4-9]*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- hardcode_into_libs=yes
- if test "$host_cpu" = ia64; then
- # AIX 5 supports IA64
- library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- else
- # With GCC up to 2.95.x, collect2 would create an import file
- # for dependence libraries. The import file would start with
- # the line `#! .'. This would cause the generated library to
- # depend on `.', always an invalid library. This was fixed in
- # development snapshots of GCC prior to 3.0.
- case $host_os in
- aix4 | aix4.[01] | aix4.[01].*)
- if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
- echo ' yes '
- echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
- :
- else
- can_build_shared=no
- fi
- ;;
- esac
- # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
- # soname into executable. Probably we can add versioning support to
- # collect2, so additional links can be useful in future.
- if test "$aix_use_runtimelinking" = yes; then
- # If using run time linking (on AIX 4.2 or later) use lib<name>.so
- # instead of lib<name>.a to let people know that these are not
- # typical AIX shared libraries.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- else
- # We preserve .a as extension for shared libraries through AIX4.2
- # and later when we are not doing run time linking.
- library_names_spec='${libname}${release}.a $libname.a'
- soname_spec='${libname}${release}${shared_ext}$major'
- fi
- shlibpath_var=LIBPATH
- fi
- ;;
-
-amigaos*)
- case $host_cpu in
- powerpc)
- # Since July 2007 AmigaOS4 officially supports .so libraries.
- # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- ;;
- m68k)
- library_names_spec='$libname.ixlibrary $libname.a'
- # Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
- ;;
- esac
- ;;
-
-beos*)
- library_names_spec='${libname}${shared_ext}'
- dynamic_linker="$host_os ld.so"
- shlibpath_var=LIBRARY_PATH
- ;;
-
-bsdi[45]*)
- version_type=linux
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
- sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
- # the default ld.so.conf also contains /usr/contrib/lib and
- # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
- # libtool to hard-code these into programs
- ;;
-
-cygwin* | mingw* | pw32* | cegcc*)
- version_type=windows
- shrext_cmds=".dll"
- need_version=no
- need_lib_prefix=no
-
- case $GCC,$host_os in
- yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
- library_names_spec='$libname.dll.a'
- # DLL is installed to $(libdir)/../bin by postinstall_cmds
- postinstall_cmds='base_file=`basename \${file}`~
- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
- dldir=$destdir/`dirname \$dlpath`~
- test -d \$dldir || mkdir -p \$dldir~
- $install_prog $dir/$dlname \$dldir/$dlname~
- chmod a+x \$dldir/$dlname~
- if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
- eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
- fi'
- postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
- dlpath=$dir/\$dldll~
- $RM \$dlpath'
- shlibpath_overrides_runpath=yes
-
- case $host_os in
- cygwin*)
- # Cygwin DLLs use 'cyg' prefix rather than 'lib'
- soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
-
- sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
- ;;
- mingw* | cegcc*)
- # MinGW DLLs use traditional 'lib' prefix
- soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- ;;
- pw32*)
- # pw32 DLLs use 'pw' prefix rather than 'lib'
- library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- ;;
- esac
- ;;
-
- *)
- library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
- ;;
- esac
- dynamic_linker='Win32 ld.exe'
- # FIXME: first we should search . and the directory the executable is in
- shlibpath_var=PATH
- ;;
-
-darwin* | rhapsody*)
- dynamic_linker="$host_os dyld"
- version_type=darwin
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
- soname_spec='${libname}${release}${major}$shared_ext'
- shlibpath_overrides_runpath=yes
- shlibpath_var=DYLD_LIBRARY_PATH
- shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
-
- sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
- sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
- ;;
-
-dgux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-freebsd* | dragonfly*)
- # DragonFly does not have aout. When/if they implement a new
- # versioning mechanism, adjust this.
- if test -x /usr/bin/objformat; then
- objformat=`/usr/bin/objformat`
- else
- case $host_os in
- freebsd[23].*) objformat=aout ;;
- *) objformat=elf ;;
- esac
- fi
- version_type=freebsd-$objformat
- case $version_type in
- freebsd-elf*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- need_version=no
- need_lib_prefix=no
- ;;
- freebsd-*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
- need_version=yes
- ;;
- esac
- shlibpath_var=LD_LIBRARY_PATH
- case $host_os in
- freebsd2.*)
- shlibpath_overrides_runpath=yes
- ;;
- freebsd3.[01]* | freebsdelf3.[01]*)
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
- freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
- *) # from 4.6 on, and DragonFly
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- esac
- ;;
-
-gnu*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- ;;
-
-haiku*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- dynamic_linker="$host_os runtime_loader"
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib'
- hardcode_into_libs=yes
- ;;
-
-hpux9* | hpux10* | hpux11*)
- # Give a soname corresponding to the major version so that dld.sl refuses to
- # link against other versions.
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- case $host_cpu in
- ia64*)
- shrext_cmds='.so'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.so"
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- if test "X$HPUX_IA64_MODE" = X32; then
- sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
- else
- sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
- fi
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- hppa*64*)
- shrext_cmds='.sl'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- *)
- shrext_cmds='.sl'
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=SHLIB_PATH
- shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
- esac
- # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
- postinstall_cmds='chmod 555 $lib'
- # or fails outright, so override atomically:
- install_override_mode=555
- ;;
-
-interix[3-9]*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
-irix5* | irix6* | nonstopux*)
- case $host_os in
- nonstopux*) version_type=nonstopux ;;
- *)
- if test "$lt_cv_prog_gnu_ld" = yes; then
- version_type=linux
- else
- version_type=irix
- fi ;;
- esac
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
- case $host_os in
- irix5* | nonstopux*)
- libsuff= shlibsuff=
- ;;
- *)
- case $LD in # libtool.m4 will add one of these switches to LD
- *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
- libsuff= shlibsuff= libmagic=32-bit;;
- *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
- libsuff=32 shlibsuff=N32 libmagic=N32;;
- *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
- libsuff=64 shlibsuff=64 libmagic=64-bit;;
- *) libsuff= shlibsuff= libmagic=never-match;;
- esac
- ;;
- esac
- shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
- sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
- hardcode_into_libs=yes
- ;;
-
-# No shared lib support for Linux oldld, aout, or coff.
-linux*oldld* | linux*aout* | linux*coff*)
- dynamic_linker=no
- ;;
-
-# This must be Linux ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
-
- # Some binutils ld are patched to set DT_RUNPATH
- if test "${lt_cv_shlibpath_overrides_runpath+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_shlibpath_overrides_runpath=no
- save_LDFLAGS=$LDFLAGS
- save_libdir=$libdir
- eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
- LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
- lt_cv_shlibpath_overrides_runpath=yes
-fi
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- LDFLAGS=$save_LDFLAGS
- libdir=$save_libdir
-
-fi
-
- shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
-
- # This implies no fast_install, which is unacceptable.
- # Some rework will be needed to allow for fast_install
- # before this can be enabled.
- hardcode_into_libs=yes
-
- # Append ld.so.conf contents to the search path
- if test -f /etc/ld.so.conf; then
- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
- sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
- fi
-
- # We used to test for /lib/ld.so.1 and disable shared libraries on
- # powerpc, because MkLinux only supported shared libraries with the
- # GNU dynamic linker. Since this was broken with cross compilers,
- # most powerpc-linux boxes support dynamic linking these days and
- # people can always --disable-shared, the test was removed, and we
- # assume the GNU/Linux dynamic linker is in use.
- dynamic_linker='GNU/Linux ld.so'
- ;;
-
-netbsd*)
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- dynamic_linker='NetBSD (a.out) ld.so'
- else
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='NetBSD ld.elf_so'
- fi
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
-
-newsos6)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-*nto* | *qnx*)
- version_type=qnx
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- dynamic_linker='ldqnx.so'
- ;;
-
-openbsd*)
- version_type=sunos
- sys_lib_dlsearch_path_spec="/usr/lib"
- need_lib_prefix=no
- # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
- case $host_os in
- openbsd3.3 | openbsd3.3.*) need_version=yes ;;
- *) need_version=no ;;
- esac
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- case $host_os in
- openbsd2.[89] | openbsd2.[89].*)
- shlibpath_overrides_runpath=no
- ;;
- *)
- shlibpath_overrides_runpath=yes
- ;;
- esac
- else
- shlibpath_overrides_runpath=yes
- fi
- ;;
-
-os2*)
- libname_spec='$name'
- shrext_cmds=".dll"
- need_lib_prefix=no
- library_names_spec='$libname${shared_ext} $libname.a'
- dynamic_linker='OS/2 ld.exe'
- shlibpath_var=LIBPATH
- ;;
-
-osf3* | osf4* | osf5*)
- version_type=osf
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
- sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
- ;;
-
-rdos*)
- dynamic_linker=no
- ;;
-
-solaris*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- # ldd complains unless libraries are executable
- postinstall_cmds='chmod +x $lib'
- ;;
-
-sunos4*)
- version_type=sunos
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- if test "$with_gnu_ld" = yes; then
- need_lib_prefix=no
- fi
- need_version=yes
- ;;
-
-sysv4 | sysv4.3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- case $host_vendor in
- sni)
- shlibpath_overrides_runpath=no
- need_lib_prefix=no
- runpath_var=LD_RUN_PATH
- ;;
- siemens)
- need_lib_prefix=no
- ;;
- motorola)
- need_lib_prefix=no
- need_version=no
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
- ;;
- esac
- ;;
-
-sysv4*MP*)
- if test -d /usr/nec ;then
- version_type=linux
- library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
- soname_spec='$libname${shared_ext}.$major'
- shlibpath_var=LD_LIBRARY_PATH
- fi
- ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- version_type=freebsd-elf
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- if test "$with_gnu_ld" = yes; then
- sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
- else
- sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
- case $host_os in
- sco3.2v5*)
- sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
- ;;
- esac
- fi
- sys_lib_dlsearch_path_spec='/usr/lib'
- ;;
-
-tpf*)
- # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
-uts4*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-*)
- dynamic_linker=no
- ;;
-esac
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
-$as_echo "$dynamic_linker" >&6; }
-test "$dynamic_linker" = no && can_build_shared=no
-
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
- variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
-if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
- sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
-fi
-if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
- sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
-$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
-hardcode_action=
-if test -n "$hardcode_libdir_flag_spec" ||
- test -n "$runpath_var" ||
- test "X$hardcode_automatic" = "Xyes" ; then
-
- # We can hardcode non-existent directories.
- if test "$hardcode_direct" != no &&
- # If the only mechanism to avoid hardcoding is shlibpath_var, we
- # have to relink, otherwise we might link with an installed library
- # when we should be linking with a yet-to-be-installed one
- ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
- test "$hardcode_minus_L" != no; then
- # Linking always hardcodes the temporary library directory.
- hardcode_action=relink
- else
- # We can link without hardcoding, and we can hardcode nonexisting dirs.
- hardcode_action=immediate
- fi
-else
- # We cannot hardcode anything, or else we can only hardcode existing
- # directories.
- hardcode_action=unsupported
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
-$as_echo "$hardcode_action" >&6; }
-
-if test "$hardcode_action" = relink ||
- test "$inherit_rpath" = yes; then
- # Fast installation is not supported
- enable_fast_install=no
-elif test "$shlibpath_overrides_runpath" = yes ||
- test "$enable_shared" = no; then
- # Fast installation is not necessary
- enable_fast_install=needless
-fi
-
-
-
-
-
-
- if test "x$enable_dlopen" != xyes; then
- enable_dlopen=unknown
- enable_dlopen_self=unknown
- enable_dlopen_self_static=unknown
-else
- lt_cv_dlopen=no
- lt_cv_dlopen_libs=
-
- case $host_os in
- beos*)
- lt_cv_dlopen="load_add_on"
- lt_cv_dlopen_libs=
- lt_cv_dlopen_self=yes
- ;;
-
- mingw* | pw32* | cegcc*)
- lt_cv_dlopen="LoadLibrary"
- lt_cv_dlopen_libs=
- ;;
-
- cygwin*)
- lt_cv_dlopen="dlopen"
- lt_cv_dlopen_libs=
- ;;
-
- darwin*)
- # if libdl is installed we need to link against it
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
-$as_echo_n "checking for dlopen in -ldl... " >&6; }
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldl $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dlopen ();
-int
-main ()
-{
-return dlopen ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_dl_dlopen=yes
-else
- ac_cv_lib_dl_dlopen=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
-$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
-if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
- lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
-else
-
- lt_cv_dlopen="dyld"
- lt_cv_dlopen_libs=
- lt_cv_dlopen_self=yes
-
-fi
-
- ;;
-
- *)
- ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
-if test "x$ac_cv_func_shl_load" = x""yes; then :
- lt_cv_dlopen="shl_load"
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
-$as_echo_n "checking for shl_load in -ldld... " >&6; }
-if test "${ac_cv_lib_dld_shl_load+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldld $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char shl_load ();
-int
-main ()
-{
-return shl_load ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_dld_shl_load=yes
-else
- ac_cv_lib_dld_shl_load=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
-$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
-if test "x$ac_cv_lib_dld_shl_load" = x""yes; then :
- lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
-else
- ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
-if test "x$ac_cv_func_dlopen" = x""yes; then :
- lt_cv_dlopen="dlopen"
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
-$as_echo_n "checking for dlopen in -ldl... " >&6; }
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldl $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dlopen ();
-int
-main ()
-{
-return dlopen ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_dl_dlopen=yes
-else
- ac_cv_lib_dl_dlopen=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
-$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
-if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
- lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
-$as_echo_n "checking for dlopen in -lsvld... " >&6; }
-if test "${ac_cv_lib_svld_dlopen+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsvld $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dlopen ();
-int
-main ()
-{
-return dlopen ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_svld_dlopen=yes
-else
- ac_cv_lib_svld_dlopen=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
-$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
-if test "x$ac_cv_lib_svld_dlopen" = x""yes; then :
- lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
-$as_echo_n "checking for dld_link in -ldld... " >&6; }
-if test "${ac_cv_lib_dld_dld_link+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldld $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dld_link ();
-int
-main ()
-{
-return dld_link ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_dld_dld_link=yes
-else
- ac_cv_lib_dld_dld_link=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
-$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
-if test "x$ac_cv_lib_dld_dld_link" = x""yes; then :
- lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
- ;;
- esac
-
- if test "x$lt_cv_dlopen" != xno; then
- enable_dlopen=yes
- else
- enable_dlopen=no
- fi
-
- case $lt_cv_dlopen in
- dlopen)
- save_CPPFLAGS="$CPPFLAGS"
- test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
-
- save_LDFLAGS="$LDFLAGS"
- wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
-
- save_LIBS="$LIBS"
- LIBS="$lt_cv_dlopen_libs $LIBS"
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
-$as_echo_n "checking whether a program can dlopen itself... " >&6; }
-if test "${lt_cv_dlopen_self+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test "$cross_compiling" = yes; then :
- lt_cv_dlopen_self=cross
-else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<_LT_EOF
-#line 17831 "configure"
-#include "confdefs.h"
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-# define LT_DLGLOBAL RTLD_GLOBAL
-#else
-# ifdef DL_GLOBAL
-# define LT_DLGLOBAL DL_GLOBAL
-# else
-# define LT_DLGLOBAL 0
-# endif
-#endif
-
-/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
- find out it does not work in some platform. */
-#ifndef LT_DLLAZY_OR_NOW
-# ifdef RTLD_LAZY
-# define LT_DLLAZY_OR_NOW RTLD_LAZY
-# else
-# ifdef DL_LAZY
-# define LT_DLLAZY_OR_NOW DL_LAZY
-# else
-# ifdef RTLD_NOW
-# define LT_DLLAZY_OR_NOW RTLD_NOW
-# else
-# ifdef DL_NOW
-# define LT_DLLAZY_OR_NOW DL_NOW
-# else
-# define LT_DLLAZY_OR_NOW 0
-# endif
-# endif
-# endif
-# endif
-#endif
-
-/* When -fvisbility=hidden is used, assume the code has been annotated
- correspondingly for the symbols needed. */
-#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
-void fnord () __attribute__((visibility("default")));
-#endif
-
-void fnord () { int i=42; }
-int main ()
-{
- void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
- int status = $lt_dlunknown;
-
- if (self)
- {
- if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
- else
- {
- if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
- else puts (dlerror ());
- }
- /* dlclose (self); */
- }
- else
- puts (dlerror ());
-
- return status;
-}
-_LT_EOF
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
- (./conftest; exit; ) >&5 2>/dev/null
- lt_status=$?
- case x$lt_status in
- x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
- x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
- x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
- esac
- else :
- # compilation failed
- lt_cv_dlopen_self=no
- fi
-fi
-rm -fr conftest*
-
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
-$as_echo "$lt_cv_dlopen_self" >&6; }
-
- if test "x$lt_cv_dlopen_self" = xyes; then
- wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
-$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
-if test "${lt_cv_dlopen_self_static+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test "$cross_compiling" = yes; then :
- lt_cv_dlopen_self_static=cross
-else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<_LT_EOF
-#line 17937 "configure"
-#include "confdefs.h"
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-# define LT_DLGLOBAL RTLD_GLOBAL
-#else
-# ifdef DL_GLOBAL
-# define LT_DLGLOBAL DL_GLOBAL
-# else
-# define LT_DLGLOBAL 0
-# endif
-#endif
-
-/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
- find out it does not work in some platform. */
-#ifndef LT_DLLAZY_OR_NOW
-# ifdef RTLD_LAZY
-# define LT_DLLAZY_OR_NOW RTLD_LAZY
-# else
-# ifdef DL_LAZY
-# define LT_DLLAZY_OR_NOW DL_LAZY
-# else
-# ifdef RTLD_NOW
-# define LT_DLLAZY_OR_NOW RTLD_NOW
-# else
-# ifdef DL_NOW
-# define LT_DLLAZY_OR_NOW DL_NOW
-# else
-# define LT_DLLAZY_OR_NOW 0
-# endif
-# endif
-# endif
-# endif
-#endif
-
-/* When -fvisbility=hidden is used, assume the code has been annotated
- correspondingly for the symbols needed. */
-#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
-void fnord () __attribute__((visibility("default")));
-#endif
-
-void fnord () { int i=42; }
-int main ()
-{
- void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
- int status = $lt_dlunknown;
-
- if (self)
- {
- if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
- else
- {
- if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
- else puts (dlerror ());
- }
- /* dlclose (self); */
- }
- else
- puts (dlerror ());
-
- return status;
-}
-_LT_EOF
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
- (./conftest; exit; ) >&5 2>/dev/null
- lt_status=$?
- case x$lt_status in
- x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
- x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
- x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
- esac
- else :
- # compilation failed
- lt_cv_dlopen_self_static=no
- fi
-fi
-rm -fr conftest*
-
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
-$as_echo "$lt_cv_dlopen_self_static" >&6; }
- fi
-
- CPPFLAGS="$save_CPPFLAGS"
- LDFLAGS="$save_LDFLAGS"
- LIBS="$save_LIBS"
- ;;
- esac
-
- case $lt_cv_dlopen_self in
- yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
- *) enable_dlopen_self=unknown ;;
- esac
-
- case $lt_cv_dlopen_self_static in
- yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
- *) enable_dlopen_self_static=unknown ;;
- esac
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-striplib=
-old_striplib=
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
-$as_echo_n "checking whether stripping libraries is possible... " >&6; }
-if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
- test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
- test -z "$striplib" && striplib="$STRIP --strip-unneeded"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-else
-# FIXME - insert some real tests, host_os isn't really good enough
- case $host_os in
- darwin*)
- if test -n "$STRIP" ; then
- striplib="$STRIP -x"
- old_striplib="$STRIP -S"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
- fi
- ;;
- *)
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
- ;;
- esac
-fi
-
-
-
-
-
-
-
-
-
-
-
-
- # Report which library types will actually be built
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
-$as_echo_n "checking if libtool supports shared libraries... " >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
-$as_echo "$can_build_shared" >&6; }
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
-$as_echo_n "checking whether to build shared libraries... " >&6; }
- test "$can_build_shared" = "no" && enable_shared=no
-
- # On AIX, shared libraries and static libraries use the same namespace, and
- # are all built from PIC.
- case $host_os in
- aix3*)
- test "$enable_shared" = yes && enable_static=no
- if test -n "$RANLIB"; then
- archive_cmds="$archive_cmds~\$RANLIB \$lib"
- postinstall_cmds='$RANLIB $lib'
- fi
- ;;
-
- aix[4-9]*)
- if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
- test "$enable_shared" = yes && enable_static=no
- fi
- ;;
- esac
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
-$as_echo "$enable_shared" >&6; }
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
-$as_echo_n "checking whether to build static libraries... " >&6; }
- # Make sure either enable_shared or enable_static is yes.
- test "$enable_shared" = yes || enable_static=yes
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
-$as_echo "$enable_static" >&6; }
-
-
-
-
-fi
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-CC="$lt_save_CC"
-
- if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
- ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
- (test "X$CXX" != "Xg++"))) ; then
- ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
-$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
-if test -z "$CXXCPP"; then
- if test "${ac_cv_prog_CXXCPP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- # Double quotes because CXXCPP needs to be expanded
- for CXXCPP in "$CXX -E" "/lib/cpp"
- do
- ac_preproc_ok=false
-for ac_cxx_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
-
-else
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
- # Broken: success on invalid input.
-continue
-else
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
- break
-fi
-
- done
- ac_cv_prog_CXXCPP=$CXXCPP
-
-fi
- CXXCPP=$ac_cv_prog_CXXCPP
-else
- ac_cv_prog_CXXCPP=$CXXCPP
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
-$as_echo "$CXXCPP" >&6; }
-ac_preproc_ok=false
-for ac_cxx_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
-
-else
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_cxx_try_cpp "$LINENO"; then :
- # Broken: success on invalid input.
-continue
-else
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-
-else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "C++ preprocessor \"$CXXCPP\" fails sanity check
-See \`config.log' for more details." "$LINENO" 5; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-else
- _lt_caught_CXX_error=yes
-fi
-
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-archive_cmds_need_lc_CXX=no
-allow_undefined_flag_CXX=
-always_export_symbols_CXX=no
-archive_expsym_cmds_CXX=
-compiler_needs_object_CXX=no
-export_dynamic_flag_spec_CXX=
-hardcode_direct_CXX=no
-hardcode_direct_absolute_CXX=no
-hardcode_libdir_flag_spec_CXX=
-hardcode_libdir_flag_spec_ld_CXX=
-hardcode_libdir_separator_CXX=
-hardcode_minus_L_CXX=no
-hardcode_shlibpath_var_CXX=unsupported
-hardcode_automatic_CXX=no
-inherit_rpath_CXX=no
-module_cmds_CXX=
-module_expsym_cmds_CXX=
-link_all_deplibs_CXX=unknown
-old_archive_cmds_CXX=$old_archive_cmds
-reload_flag_CXX=$reload_flag
-reload_cmds_CXX=$reload_cmds
-no_undefined_flag_CXX=
-whole_archive_flag_spec_CXX=
-enable_shared_with_static_runtimes_CXX=no
-
-# Source file extension for C++ test sources.
-ac_ext=cpp
-
-# Object file extension for compiled C++ test sources.
-objext=o
-objext_CXX=$objext
-
-# No sense in running all these tests if we already determined that
-# the CXX compiler isn't working. Some variables (like enable_shared)
-# are currently assumed to apply to all compilers on this platform,
-# and will be corrupted by setting them based on a non-working compiler.
-if test "$_lt_caught_CXX_error" != yes; then
- # Code to be used in simple compile tests
- lt_simple_compile_test_code="int some_variable = 0;"
-
- # Code to be used in simple link tests
- lt_simple_link_test_code='int main(int, char *[]) { return(0); }'
-
- # ltmain only uses $CC for tagged configurations so make sure $CC is set.
-
-
-
-
-
-
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
-
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
-
-# Allow CC to be a program name with arguments.
-compiler=$CC
-
-
- # save warnings/boilerplate of simple test code
- ac_outfile=conftest.$ac_objext
-echo "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_compiler_boilerplate=`cat conftest.err`
-$RM conftest*
-
- ac_outfile=conftest.$ac_objext
-echo "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_linker_boilerplate=`cat conftest.err`
-$RM -r conftest*
-
-
- # Allow CC to be a program name with arguments.
- lt_save_CC=$CC
- lt_save_LD=$LD
- lt_save_GCC=$GCC
- GCC=$GXX
- lt_save_with_gnu_ld=$with_gnu_ld
- lt_save_path_LD=$lt_cv_path_LD
- if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
- lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
- else
- $as_unset lt_cv_prog_gnu_ld
- fi
- if test -n "${lt_cv_path_LDCXX+set}"; then
- lt_cv_path_LD=$lt_cv_path_LDCXX
- else
- $as_unset lt_cv_path_LD
- fi
- test -z "${LDCXX+set}" || LD=$LDCXX
- CC=${CXX-"c++"}
- compiler=$CC
- compiler_CXX=$CC
- for cc_temp in $compiler""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
-
-
- if test -n "$compiler"; then
- # We don't want -fno-exception when compiling C++ code, so set the
- # no_builtin_flag separately
- if test "$GXX" = yes; then
- lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
- else
- lt_prog_compiler_no_builtin_flag_CXX=
- fi
-
- if test "$GXX" = yes; then
- # Set up default GNU C++ configuration
-
-
-
-# Check whether --with-gnu-ld was given.
-if test "${with_gnu_ld+set}" = set; then :
- withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
-else
- with_gnu_ld=no
-fi
-
-ac_prog=ld
-if test "$GCC" = yes; then
- # Check if gcc -print-prog-name=ld gives a path.
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
-$as_echo_n "checking for ld used by $CC... " >&6; }
- case $host in
- *-*-mingw*)
- # gcc leaves a trailing carriage return which upsets mingw
- ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
- *)
- ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
- esac
- case $ac_prog in
- # Accept absolute paths.
- [\\/]* | ?:[\\/]*)
- re_direlt='/[^/][^/]*/\.\./'
- # Canonicalize the pathname of ld
- ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
- while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
- ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
- done
- test -z "$LD" && LD="$ac_prog"
- ;;
- "")
- # If it fails, then pretend we aren't using GCC.
- ac_prog=ld
- ;;
- *)
- # If it is relative, then search for the first ld in PATH.
- with_gnu_ld=unknown
- ;;
- esac
-elif test "$with_gnu_ld" = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
-$as_echo_n "checking for GNU ld... " >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
-$as_echo_n "checking for non-GNU ld... " >&6; }
-fi
-if test "${lt_cv_path_LD+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -z "$LD"; then
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in $PATH; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
- lt_cv_path_LD="$ac_dir/$ac_prog"
- # Check to see if the program is GNU ld. I'd rather use --version,
- # but apparently some variants of GNU ld only accept -v.
- # Break only if it was the GNU/non-GNU ld that we prefer.
- case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
- *GNU* | *'with BFD'*)
- test "$with_gnu_ld" != no && break
- ;;
- *)
- test "$with_gnu_ld" != yes && break
- ;;
- esac
- fi
- done
- IFS="$lt_save_ifs"
-else
- lt_cv_path_LD="$LD" # Let the user override the test with a path.
-fi
-fi
-
-LD="$lt_cv_path_LD"
-if test -n "$LD"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
-$as_echo "$LD" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
-$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
-if test "${lt_cv_prog_gnu_ld+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- # I'd rather use --version here, but apparently some GNU lds only accept -v.
-case `$LD -v 2>&1 </dev/null` in
-*GNU* | *'with BFD'*)
- lt_cv_prog_gnu_ld=yes
- ;;
-*)
- lt_cv_prog_gnu_ld=no
- ;;
-esac
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
-$as_echo "$lt_cv_prog_gnu_ld" >&6; }
-with_gnu_ld=$lt_cv_prog_gnu_ld
-
-
-
-
-
-
-
- # Check if GNU C++ uses GNU ld as the underlying linker, since the
- # archiving commands below assume that GNU ld is being used.
- if test "$with_gnu_ld" = yes; then
- archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
-
- hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
- export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
-
- # If archive_cmds runs LD, not CC, wlarc should be empty
- # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
- # investigate it a little bit more. (MM)
- wlarc='${wl}'
-
- # ancient GNU ld didn't support --whole-archive et. al.
- if eval "`$CC -print-prog-name=ld` --help 2>&1" |
- $GREP 'no-whole-archive' > /dev/null; then
- whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- else
- whole_archive_flag_spec_CXX=
- fi
- else
- with_gnu_ld=no
- wlarc=
-
- # A generic and very simple default shared library creation
- # command for GNU C++ for the case where it uses the native
- # linker, instead of GNU ld. If possible, this setting should
- # overridden to take advantage of the native linker features on
- # the platform it is being used on.
- archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
- fi
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
-
- else
- GXX=no
- with_gnu_ld=no
- wlarc=
- fi
-
- # PORTME: fill in a description of your system's C++ link characteristics
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
-$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
- ld_shlibs_CXX=yes
- case $host_os in
- aix3*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- aix[4-9]*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- exp_sym_flag='-Bexport'
- no_entry_flag=""
- else
- aix_use_runtimelinking=no
-
- # Test if we are trying to use run time linking or normal
- # AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
- case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
- for ld_flag in $LDFLAGS; do
- case $ld_flag in
- *-brtl*)
- aix_use_runtimelinking=yes
- break
- ;;
- esac
- done
- ;;
- esac
-
- exp_sym_flag='-bexport'
- no_entry_flag='-bnoentry'
- fi
-
- # When large executables or shared objects are built, AIX ld can
- # have problems creating the table of contents. If linking a library
- # or program results in "error TOC overflow" add -mminimal-toc to
- # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
- # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
-
- archive_cmds_CXX=''
- hardcode_direct_CXX=yes
- hardcode_direct_absolute_CXX=yes
- hardcode_libdir_separator_CXX=':'
- link_all_deplibs_CXX=yes
- file_list_spec_CXX='${wl}-f,'
-
- if test "$GXX" = yes; then
- case $host_os in aix4.[012]|aix4.[012].*)
- # We only want to do this on AIX 4.2 and lower, the check
- # below for broken collect2 doesn't work under 4.3+
- collect2name=`${CC} -print-prog-name=collect2`
- if test -f "$collect2name" &&
- strings "$collect2name" | $GREP resolve_lib_name >/dev/null
- then
- # We have reworked collect2
- :
- else
- # We have old collect2
- hardcode_direct_CXX=unsupported
- # It fails to find uninstalled libraries when the uninstalled
- # path is not listed in the libpath. Setting hardcode_minus_L
- # to unsupported forces relinking
- hardcode_minus_L_CXX=yes
- hardcode_libdir_flag_spec_CXX='-L$libdir'
- hardcode_libdir_separator_CXX=
- fi
- esac
- shared_flag='-shared'
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag="$shared_flag "'${wl}-G'
- fi
- else
- # not using gcc
- if test "$host_cpu" = ia64; then
- # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
- # chokes on -Wl,-G. The following line is correct:
- shared_flag='-G'
- else
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag='${wl}-G'
- else
- shared_flag='${wl}-bM:SRE'
- fi
- fi
- fi
-
- export_dynamic_flag_spec_CXX='${wl}-bexpall'
- # It seems that -bexpall does not export symbols beginning with
- # underscore (_), so it is better to generate a list of symbols to
- # export.
- always_export_symbols_CXX=yes
- if test "$aix_use_runtimelinking" = yes; then
- # Warning - without using the other runtime loading flags (-brtl),
- # -berok will link without error, but may produce a broken library.
- allow_undefined_flag_CXX='-berok'
- # Determine the default libpath from the value encoded in an empty
- # executable.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_link "$LINENO"; then :
-
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then
- aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-fi
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
-
- hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
-
- archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
- else
- if test "$host_cpu" = ia64; then
- hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
- allow_undefined_flag_CXX="-z nodefs"
- archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
- else
- # Determine the default libpath from the value encoded in an
- # empty executable.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_link "$LINENO"; then :
-
-lt_aix_libpath_sed='
- /Import File Strings/,/^$/ {
- /^0/ {
- s/^0 *\(.*\)$/\1/
- p
- }
- }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then
- aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-fi
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
-
- hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
- # Warning - without using the other run time loading flags,
- # -berok will link without error, but may produce a broken library.
- no_undefined_flag_CXX=' ${wl}-bernotok'
- allow_undefined_flag_CXX=' ${wl}-berok'
- if test "$with_gnu_ld" = yes; then
- # We only use this code for GNU lds that support --whole-archive.
- whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
- else
- # Exported symbols can be pulled into shared objects from archives
- whole_archive_flag_spec_CXX='$convenience'
- fi
- archive_cmds_need_lc_CXX=yes
- # This is similar to how AIX traditionally builds its shared
- # libraries.
- archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
- fi
- fi
- ;;
-
- beos*)
- if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- allow_undefined_flag_CXX=unsupported
- # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
- # support --undefined. This deserves some investigation. FIXME
- archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- else
- ld_shlibs_CXX=no
- fi
- ;;
-
- chorus*)
- case $cc_basename in
- *)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- esac
- ;;
-
- cygwin* | mingw* | pw32* | cegcc*)
- # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
- # as there is no search path for DLLs.
- hardcode_libdir_flag_spec_CXX='-L$libdir'
- export_dynamic_flag_spec_CXX='${wl}--export-all-symbols'
- allow_undefined_flag_CXX=unsupported
- always_export_symbols_CXX=no
- enable_shared_with_static_runtimes_CXX=yes
-
- if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
- archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file (1st line
- # is EXPORTS), use it as is; otherwise, prepend...
- archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- else
- ld_shlibs_CXX=no
- fi
- ;;
- darwin* | rhapsody*)
-
-
- archive_cmds_need_lc_CXX=no
- hardcode_direct_CXX=no
- hardcode_automatic_CXX=yes
- hardcode_shlibpath_var_CXX=unsupported
- if test "$lt_cv_ld_force_load" = "yes"; then
- whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
- else
- whole_archive_flag_spec_CXX=''
- fi
- link_all_deplibs_CXX=yes
- allow_undefined_flag_CXX="$_lt_dar_allow_undefined"
- case $cc_basename in
- ifort*) _lt_dar_can_shared=yes ;;
- *) _lt_dar_can_shared=$GCC ;;
- esac
- if test "$_lt_dar_can_shared" = "yes"; then
- output_verbose_link_cmd=func_echo_all
- archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
- module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
- archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
- module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
- if test "$lt_cv_apple_cc_single_mod" != "yes"; then
- archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
- archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
- fi
-
- else
- ld_shlibs_CXX=no
- fi
-
- ;;
-
- dgux*)
- case $cc_basename in
- ec++*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- ghcx*)
- # Green Hills C++ Compiler
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- esac
- ;;
-
- freebsd2.*)
- # C++ shared libraries reported to be fairly broken before
- # switch to ELF
- ld_shlibs_CXX=no
- ;;
-
- freebsd-elf*)
- archive_cmds_need_lc_CXX=no
- ;;
-
- freebsd* | dragonfly*)
- # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
- # conventions
- ld_shlibs_CXX=yes
- ;;
-
- gnu*)
- ;;
-
- haiku*)
- archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- link_all_deplibs_CXX=yes
- ;;
-
- hpux9*)
- hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator_CXX=:
- export_dynamic_flag_spec_CXX='${wl}-E'
- hardcode_direct_CXX=yes
- hardcode_minus_L_CXX=yes # Not in the search PATH,
- # but as the default
- # location of the library.
-
- case $cc_basename in
- CC*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- aCC*)
- archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
- ;;
- *)
- if test "$GXX" = yes; then
- archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
- else
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- fi
- ;;
- esac
- ;;
-
- hpux10*|hpux11*)
- if test $with_gnu_ld = no; then
- hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator_CXX=:
-
- case $host_cpu in
- hppa*64*|ia64*)
- ;;
- *)
- export_dynamic_flag_spec_CXX='${wl}-E'
- ;;
- esac
- fi
- case $host_cpu in
- hppa*64*|ia64*)
- hardcode_direct_CXX=no
- hardcode_shlibpath_var_CXX=no
- ;;
- *)
- hardcode_direct_CXX=yes
- hardcode_direct_absolute_CXX=yes
- hardcode_minus_L_CXX=yes # Not in the search PATH,
- # but as the default
- # location of the library.
- ;;
- esac
-
- case $cc_basename in
- CC*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- aCC*)
- case $host_cpu in
- hppa*64*)
- archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- ia64*)
- archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- *)
- archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- esac
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
- ;;
- *)
- if test "$GXX" = yes; then
- if test $with_gnu_ld = no; then
- case $host_cpu in
- hppa*64*)
- archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- ia64*)
- archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- *)
- archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- ;;
- esac
- fi
- else
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- fi
- ;;
- esac
- ;;
-
- interix[3-9]*)
- hardcode_direct_CXX=no
- hardcode_shlibpath_var_CXX=no
- hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
- export_dynamic_flag_spec_CXX='${wl}-E'
- # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
- # Instead, shared libraries are loaded at an image base (0x10000000 by
- # default) and relocated if they conflict, which is a slow very memory
- # consuming and fragmenting process. To avoid this, we pick a random,
- # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
- # time. Moving up from 0x10000000 also allows more sbrk(2) space.
- archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- ;;
- irix5* | irix6*)
- case $cc_basename in
- CC*)
- # SGI C++
- archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
-
- # Archives containing C++ object files must be created using
- # "CC -ar", where "CC" is the IRIX C++ compiler. This is
- # necessary to make sure instantiated templates are included
- # in the archive.
- old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
- ;;
- *)
- if test "$GXX" = yes; then
- if test "$with_gnu_ld" = no; then
- archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- else
- archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
- fi
- fi
- link_all_deplibs_CXX=yes
- ;;
- esac
- hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator_CXX=:
- inherit_rpath_CXX=yes
- ;;
-
- linux* | k*bsd*-gnu | kopensolaris*-gnu)
- case $cc_basename in
- KCC*)
- # Kuck and Associates, Inc. (KAI) C++ Compiler
-
- # KCC will only create a shared library if the output file
- # ends with ".so" (or ".sl" for HP-UX), so rename the library
- # to its proper name (with version) after linking.
- archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
- archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
-
- hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
- export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
-
- # Archives containing C++ object files must be created using
- # "CC -Bstatic", where "CC" is the KAI C++ compiler.
- old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
- ;;
- icpc* | ecpc* )
- # Intel C++
- with_gnu_ld=yes
- # version 8.0 and above of icpc choke on multiply defined symbols
- # if we add $predep_objects and $postdep_objects, however 7.1 and
- # earlier do not add the objects themselves.
- case `$CC -V 2>&1` in
- *"Version 7."*)
- archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- ;;
- *) # Version 8.0 or newer
- tmp_idyn=
- case $host_cpu in
- ia64*) tmp_idyn=' -i_dynamic';;
- esac
- archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
- ;;
- esac
- archive_cmds_need_lc_CXX=no
- hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
- export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
- whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
- ;;
- pgCC* | pgcpp*)
- # Portland Group C++ compiler
- case `$CC -V` in
- *pgCC\ [1-5].* | *pgcpp\ [1-5].*)
- prelink_cmds_CXX='tpldir=Template.dir~
- rm -rf $tpldir~
- $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
- compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"'
- old_archive_cmds_CXX='tpldir=Template.dir~
- rm -rf $tpldir~
- $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
- $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~
- $RANLIB $oldlib'
- archive_cmds_CXX='tpldir=Template.dir~
- rm -rf $tpldir~
- $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
- $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
- archive_expsym_cmds_CXX='tpldir=Template.dir~
- rm -rf $tpldir~
- $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
- $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
- ;;
- *) # Version 6 and above use weak symbols
- archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
- archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
- ;;
- esac
-
- hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
- export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
- whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
- ;;
- cxx*)
- # Compaq C++
- archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
-
- runpath_var=LD_RUN_PATH
- hardcode_libdir_flag_spec_CXX='-rpath $libdir'
- hardcode_libdir_separator_CXX=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
- ;;
- xl* | mpixl* | bgxl*)
- # IBM XL 8.0 on PPC, with GNU ld
- hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
- export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
- archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- if test "x$supports_anon_versioning" = xyes; then
- archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
- fi
- ;;
- *)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- # Sun C++ 5.9
- no_undefined_flag_CXX=' -zdefs'
- archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
- hardcode_libdir_flag_spec_CXX='-R$libdir'
- whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
- compiler_needs_object_CXX=yes
-
- # Not sure whether something based on
- # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
- # would be better.
- output_verbose_link_cmd='func_echo_all'
-
- # Archives containing C++ object files must be created using
- # "CC -xar", where "CC" is the Sun C++ compiler. This is
- # necessary to make sure instantiated templates are included
- # in the archive.
- old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
- ;;
- esac
- ;;
- esac
- ;;
-
- lynxos*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
-
- m88k*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
-
- mvs*)
- case $cc_basename in
- cxx*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- esac
- ;;
-
- netbsd*)
- if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
- archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
- wlarc=
- hardcode_libdir_flag_spec_CXX='-R$libdir'
- hardcode_direct_CXX=yes
- hardcode_shlibpath_var_CXX=no
- fi
- # Workaround some broken pre-1.5 toolchains
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
- ;;
-
- *nto* | *qnx*)
- ld_shlibs_CXX=yes
- ;;
-
- openbsd2*)
- # C++ shared libraries are fairly broken
- ld_shlibs_CXX=no
- ;;
-
- openbsd*)
- if test -f /usr/libexec/ld.so; then
- hardcode_direct_CXX=yes
- hardcode_shlibpath_var_CXX=no
- hardcode_direct_absolute_CXX=yes
- archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
- hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
- export_dynamic_flag_spec_CXX='${wl}-E'
- whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- fi
- output_verbose_link_cmd=func_echo_all
- else
- ld_shlibs_CXX=no
- fi
- ;;
-
- osf3* | osf4* | osf5*)
- case $cc_basename in
- KCC*)
- # Kuck and Associates, Inc. (KAI) C++ Compiler
-
- # KCC will only create a shared library if the output file
- # ends with ".so" (or ".sl" for HP-UX), so rename the library
- # to its proper name (with version) after linking.
- archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
-
- hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
- hardcode_libdir_separator_CXX=:
-
- # Archives containing C++ object files must be created using
- # the KAI C++ compiler.
- case $host in
- osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;;
- *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;;
- esac
- ;;
- RCC*)
- # Rational C++ 2.4.1
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- cxx*)
- case $host in
- osf3*)
- allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
- hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
- ;;
- *)
- allow_undefined_flag_CXX=' -expect_unresolved \*'
- archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
- archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
- echo "-hidden">> $lib.exp~
- $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
- $RM $lib.exp'
- hardcode_libdir_flag_spec_CXX='-rpath $libdir'
- ;;
- esac
-
- hardcode_libdir_separator_CXX=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
- ;;
- *)
- if test "$GXX" = yes && test "$with_gnu_ld" = no; then
- allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
- case $host in
- osf3*)
- archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- ;;
- *)
- archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- ;;
- esac
-
- hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator_CXX=:
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
-
- else
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- fi
- ;;
- esac
- ;;
-
- psos*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
-
- sunos4*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.x
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- lcc*)
- # Lucid
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- esac
- ;;
-
- solaris*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.2, 5.x and Centerline C++
- archive_cmds_need_lc_CXX=yes
- no_undefined_flag_CXX=' -zdefs'
- archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
-
- hardcode_libdir_flag_spec_CXX='-R$libdir'
- hardcode_shlibpath_var_CXX=no
- case $host_os in
- solaris2.[0-5] | solaris2.[0-5].*) ;;
- *)
- # The compiler driver will combine and reorder linker options,
- # but understands `-z linker_flag'.
- # Supported since Solaris 2.6 (maybe 2.5.1?)
- whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract'
- ;;
- esac
- link_all_deplibs_CXX=yes
-
- output_verbose_link_cmd='func_echo_all'
-
- # Archives containing C++ object files must be created using
- # "CC -xar", where "CC" is the Sun C++ compiler. This is
- # necessary to make sure instantiated templates are included
- # in the archive.
- old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
- ;;
- gcx*)
- # Green Hills C++ Compiler
- archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
-
- # The C++ compiler must be used to create the archive.
- old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
- ;;
- *)
- # GNU C++ compiler with Solaris linker
- if test "$GXX" = yes && test "$with_gnu_ld" = no; then
- no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
- if $CC --version | $GREP -v '^2\.7' > /dev/null; then
- archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
- archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
- else
- # g++ 2.7 appears to require `-G' NOT `-shared' on this
- # platform.
- archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
- archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
-
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
- fi
-
- hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
- case $host_os in
- solaris2.[0-5] | solaris2.[0-5].*) ;;
- *)
- whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
- ;;
- esac
- fi
- ;;
- esac
- ;;
-
- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
- no_undefined_flag_CXX='${wl}-z,text'
- archive_cmds_need_lc_CXX=no
- hardcode_shlibpath_var_CXX=no
- runpath_var='LD_RUN_PATH'
-
- case $cc_basename in
- CC*)
- archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- *)
- archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- ;;
-
- sysv5* | sco3.2v5* | sco5v6*)
- # Note: We can NOT use -z defs as we might desire, because we do not
- # link with -lc, and that would cause any symbols used from libc to
- # always be unresolved, which means just about no library would
- # ever link correctly. If we're not using GNU ld we use -z text
- # though, which does catch some bad symbols but isn't as heavy-handed
- # as -z defs.
- no_undefined_flag_CXX='${wl}-z,text'
- allow_undefined_flag_CXX='${wl}-z,nodefs'
- archive_cmds_need_lc_CXX=no
- hardcode_shlibpath_var_CXX=no
- hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir'
- hardcode_libdir_separator_CXX=':'
- link_all_deplibs_CXX=yes
- export_dynamic_flag_spec_CXX='${wl}-Bexport'
- runpath_var='LD_RUN_PATH'
-
- case $cc_basename in
- CC*)
- archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~
- '"$old_archive_cmds_CXX"
- reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~
- '"$reload_cmds_CXX"
- ;;
- *)
- archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- ;;
- esac
- ;;
-
- tandem*)
- case $cc_basename in
- NCC*)
- # NonStop-UX NCC 3.20
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- esac
- ;;
-
- vxworks*)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
-
- *)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- esac
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
-$as_echo "$ld_shlibs_CXX" >&6; }
- test "$ld_shlibs_CXX" = no && can_build_shared=no
-
- GCC_CXX="$GXX"
- LD_CXX="$LD"
-
- ## CAVEAT EMPTOR:
- ## There is no encapsulation within the following macros, do not change
- ## the running order or otherwise move them around unless you know exactly
- ## what you are doing...
- # Dependencies to place before and after the object being linked:
-predep_objects_CXX=
-postdep_objects_CXX=
-predeps_CXX=
-postdeps_CXX=
-compiler_lib_search_path_CXX=
-
-cat > conftest.$ac_ext <<_LT_EOF
-class Foo
-{
-public:
- Foo (void) { a = 0; }
-private:
- int a;
-};
-_LT_EOF
-
-if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- # Parse the compiler output and extract the necessary
- # objects, libraries and library flags.
-
- # Sentinel used to keep track of whether or not we are before
- # the conftest object file.
- pre_test_object_deps_done=no
-
- for p in `eval "$output_verbose_link_cmd"`; do
- case $p in
-
- -L* | -R* | -l*)
- # Some compilers place space between "-{L,R}" and the path.
- # Remove the space.
- if test $p = "-L" ||
- test $p = "-R"; then
- prev=$p
- continue
- else
- prev=
- fi
-
- if test "$pre_test_object_deps_done" = no; then
- case $p in
- -L* | -R*)
- # Internal compiler library paths should come after those
- # provided the user. The postdeps already come after the
- # user supplied libs so there is no need to process them.
- if test -z "$compiler_lib_search_path_CXX"; then
- compiler_lib_search_path_CXX="${prev}${p}"
- else
- compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}"
- fi
- ;;
- # The "-l" case would never come before the object being
- # linked, so don't bother handling this case.
- esac
- else
- if test -z "$postdeps_CXX"; then
- postdeps_CXX="${prev}${p}"
- else
- postdeps_CXX="${postdeps_CXX} ${prev}${p}"
- fi
- fi
- ;;
-
- *.$objext)
- # This assumes that the test object file only shows up
- # once in the compiler output.
- if test "$p" = "conftest.$objext"; then
- pre_test_object_deps_done=yes
- continue
- fi
-
- if test "$pre_test_object_deps_done" = no; then
- if test -z "$predep_objects_CXX"; then
- predep_objects_CXX="$p"
- else
- predep_objects_CXX="$predep_objects_CXX $p"
- fi
- else
- if test -z "$postdep_objects_CXX"; then
- postdep_objects_CXX="$p"
- else
- postdep_objects_CXX="$postdep_objects_CXX $p"
- fi
- fi
- ;;
-
- *) ;; # Ignore the rest.
-
- esac
- done
-
- # Clean up.
- rm -f a.out a.exe
-else
- echo "libtool.m4: error: problem compiling CXX test program"
-fi
-
-$RM -f confest.$objext
-
-# PORTME: override above test on systems where it is broken
-case $host_os in
-interix[3-9]*)
- # Interix 3.5 installs completely hosed .la files for C++, so rather than
- # hack all around it, let's just trust "g++" to DTRT.
- predep_objects_CXX=
- postdep_objects_CXX=
- postdeps_CXX=
- ;;
-
-linux*)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- # Sun C++ 5.9
-
- # The more standards-conforming stlport4 library is
- # incompatible with the Cstd library. Avoid specifying
- # it if it's in CXXFLAGS. Ignore libCrun as
- # -library=stlport4 depends on it.
- case " $CXX $CXXFLAGS " in
- *" -library=stlport4 "*)
- solaris_use_stlport4=yes
- ;;
- esac
-
- if test "$solaris_use_stlport4" != yes; then
- postdeps_CXX='-library=Cstd -library=Crun'
- fi
- ;;
- esac
- ;;
-
-solaris*)
- case $cc_basename in
- CC*)
- # The more standards-conforming stlport4 library is
- # incompatible with the Cstd library. Avoid specifying
- # it if it's in CXXFLAGS. Ignore libCrun as
- # -library=stlport4 depends on it.
- case " $CXX $CXXFLAGS " in
- *" -library=stlport4 "*)
- solaris_use_stlport4=yes
- ;;
- esac
-
- # Adding this requires a known-good setup of shared libraries for
- # Sun compiler versions before 5.6, else PIC objects from an old
- # archive will be linked into the output, leading to subtle bugs.
- if test "$solaris_use_stlport4" != yes; then
- postdeps_CXX='-library=Cstd -library=Crun'
- fi
- ;;
- esac
- ;;
-esac
-
-
-case " $postdeps_CXX " in
-*" -lc "*) archive_cmds_need_lc_CXX=no ;;
-esac
- compiler_lib_search_dirs_CXX=
-if test -n "${compiler_lib_search_path_CXX}"; then
- compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- lt_prog_compiler_wl_CXX=
-lt_prog_compiler_pic_CXX=
-lt_prog_compiler_static_CXX=
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
-$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
-
- # C++ specific cases for pic, static, wl, etc.
- if test "$GXX" = yes; then
- lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_static_CXX='-static'
-
- case $host_os in
- aix*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static_CXX='-Bstatic'
- fi
- lt_prog_compiler_pic_CXX='-fPIC'
- ;;
-
- amigaos*)
- case $host_cpu in
- powerpc)
- # see comment about AmigaOS4 .so support
- lt_prog_compiler_pic_CXX='-fPIC'
- ;;
- m68k)
- # FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
- lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'
- ;;
- esac
- ;;
-
- beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
- # PIC is the default for these OSes.
- ;;
- mingw* | cygwin* | os2* | pw32* | cegcc*)
- # This hack is so that the source file can tell whether it is being
- # built for inclusion in a dll (and should export symbols for example).
- # Although the cygwin gcc ignores -fPIC, still need this for old-style
- # (--disable-auto-import) libraries
- lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
- ;;
- darwin* | rhapsody*)
- # PIC is the default on this platform
- # Common symbols not allowed in MH_DYLIB files
- lt_prog_compiler_pic_CXX='-fno-common'
- ;;
- *djgpp*)
- # DJGPP does not support shared libraries at all
- lt_prog_compiler_pic_CXX=
- ;;
- haiku*)
- # PIC is the default for Haiku.
- # The "-static" flag exists, but is broken.
- lt_prog_compiler_static_CXX=
- ;;
- interix[3-9]*)
- # Interix 3.x gcc -fpic/-fPIC options generate broken code.
- # Instead, we relocate shared libraries at runtime.
- ;;
- sysv4*MP*)
- if test -d /usr/nec; then
- lt_prog_compiler_pic_CXX=-Kconform_pic
- fi
- ;;
- hpux*)
- # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
- # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
- # sets the default TLS model and affects inlining.
- case $host_cpu in
- hppa*64*)
- ;;
- *)
- lt_prog_compiler_pic_CXX='-fPIC'
- ;;
- esac
- ;;
- *qnx* | *nto*)
- # QNX uses GNU C++, but need to define -shared option too, otherwise
- # it will coredump.
- lt_prog_compiler_pic_CXX='-fPIC -shared'
- ;;
- *)
- lt_prog_compiler_pic_CXX='-fPIC'
- ;;
- esac
- else
- case $host_os in
- aix[4-9]*)
- # All AIX code is PIC.
- if test "$host_cpu" = ia64; then
- # AIX 5 now supports IA64 processor
- lt_prog_compiler_static_CXX='-Bstatic'
- else
- lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
- fi
- ;;
- chorus*)
- case $cc_basename in
- cxch68*)
- # Green Hills C++ Compiler
- # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
- ;;
- esac
- ;;
- dgux*)
- case $cc_basename in
- ec++*)
- lt_prog_compiler_pic_CXX='-KPIC'
- ;;
- ghcx*)
- # Green Hills C++ Compiler
- lt_prog_compiler_pic_CXX='-pic'
- ;;
- *)
- ;;
- esac
- ;;
- freebsd* | dragonfly*)
- # FreeBSD uses GNU C++
- ;;
- hpux9* | hpux10* | hpux11*)
- case $cc_basename in
- CC*)
- lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
- if test "$host_cpu" != ia64; then
- lt_prog_compiler_pic_CXX='+Z'
- fi
- ;;
- aCC*)
- lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
- case $host_cpu in
- hppa*64*|ia64*)
- # +Z the default
- ;;
- *)
- lt_prog_compiler_pic_CXX='+Z'
- ;;
- esac
- ;;
- *)
- ;;
- esac
- ;;
- interix*)
- # This is c89, which is MS Visual C++ (no shared libs)
- # Anyone wants to do a port?
- ;;
- irix5* | irix6* | nonstopux*)
- case $cc_basename in
- CC*)
- lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_static_CXX='-non_shared'
- # CC pic flag -KPIC is the default.
- ;;
- *)
- ;;
- esac
- ;;
- linux* | k*bsd*-gnu | kopensolaris*-gnu)
- case $cc_basename in
- KCC*)
- # KAI C++ Compiler
- lt_prog_compiler_wl_CXX='--backend -Wl,'
- lt_prog_compiler_pic_CXX='-fPIC'
- ;;
- ecpc* )
- # old Intel C++ for x86_64 which still supported -KPIC.
- lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_pic_CXX='-KPIC'
- lt_prog_compiler_static_CXX='-static'
- ;;
- icpc* )
- # Intel C++, used to be incompatible with GCC.
- # ICC 10 doesn't accept -KPIC any more.
- lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_pic_CXX='-fPIC'
- lt_prog_compiler_static_CXX='-static'
- ;;
- pgCC* | pgcpp*)
- # Portland Group C++ compiler
- lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_pic_CXX='-fpic'
- lt_prog_compiler_static_CXX='-Bstatic'
- ;;
- cxx*)
- # Compaq C++
- # Make sure the PIC flag is empty. It appears that all Alpha
- # Linux and Compaq Tru64 Unix objects are PIC.
- lt_prog_compiler_pic_CXX=
- lt_prog_compiler_static_CXX='-non_shared'
- ;;
- xlc* | xlC* | bgxl[cC]* | mpixl[cC]*)
- # IBM XL 8.0, 9.0 on PPC and BlueGene
- lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_pic_CXX='-qpic'
- lt_prog_compiler_static_CXX='-qstaticlink'
- ;;
- *)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- # Sun C++ 5.9
- lt_prog_compiler_pic_CXX='-KPIC'
- lt_prog_compiler_static_CXX='-Bstatic'
- lt_prog_compiler_wl_CXX='-Qoption ld '
- ;;
- esac
- ;;
- esac
- ;;
- lynxos*)
- ;;
- m88k*)
- ;;
- mvs*)
- case $cc_basename in
- cxx*)
- lt_prog_compiler_pic_CXX='-W c,exportall'
- ;;
- *)
- ;;
- esac
- ;;
- netbsd*)
- ;;
- *qnx* | *nto*)
- # QNX uses GNU C++, but need to define -shared option too, otherwise
- # it will coredump.
- lt_prog_compiler_pic_CXX='-fPIC -shared'
- ;;
- osf3* | osf4* | osf5*)
- case $cc_basename in
- KCC*)
- lt_prog_compiler_wl_CXX='--backend -Wl,'
- ;;
- RCC*)
- # Rational C++ 2.4.1
- lt_prog_compiler_pic_CXX='-pic'
- ;;
- cxx*)
- # Digital/Compaq C++
- lt_prog_compiler_wl_CXX='-Wl,'
- # Make sure the PIC flag is empty. It appears that all Alpha
- # Linux and Compaq Tru64 Unix objects are PIC.
- lt_prog_compiler_pic_CXX=
- lt_prog_compiler_static_CXX='-non_shared'
- ;;
- *)
- ;;
- esac
- ;;
- psos*)
- ;;
- solaris*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.2, 5.x and Centerline C++
- lt_prog_compiler_pic_CXX='-KPIC'
- lt_prog_compiler_static_CXX='-Bstatic'
- lt_prog_compiler_wl_CXX='-Qoption ld '
- ;;
- gcx*)
- # Green Hills C++ Compiler
- lt_prog_compiler_pic_CXX='-PIC'
- ;;
- *)
- ;;
- esac
- ;;
- sunos4*)
- case $cc_basename in
- CC*)
- # Sun C++ 4.x
- lt_prog_compiler_pic_CXX='-pic'
- lt_prog_compiler_static_CXX='-Bstatic'
- ;;
- lcc*)
- # Lucid
- lt_prog_compiler_pic_CXX='-pic'
- ;;
- *)
- ;;
- esac
- ;;
- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
- case $cc_basename in
- CC*)
- lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_pic_CXX='-KPIC'
- lt_prog_compiler_static_CXX='-Bstatic'
- ;;
- esac
- ;;
- tandem*)
- case $cc_basename in
- NCC*)
- # NonStop-UX NCC 3.20
- lt_prog_compiler_pic_CXX='-KPIC'
- ;;
- *)
- ;;
- esac
- ;;
- vxworks*)
- ;;
- *)
- lt_prog_compiler_can_build_shared_CXX=no
- ;;
- esac
- fi
-
-case $host_os in
- # For platforms which do not support PIC, -DPIC is meaningless:
- *djgpp*)
- lt_prog_compiler_pic_CXX=
- ;;
- *)
- lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
- ;;
-esac
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic_CXX" >&5
-$as_echo "$lt_prog_compiler_pic_CXX" >&6; }
-
-
-
-#
-# Check to make sure the PIC flag actually works.
-#
-if test -n "$lt_prog_compiler_pic_CXX"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
-$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; }
-if test "${lt_cv_prog_compiler_pic_works_CXX+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_prog_compiler_pic_works_CXX=no
- ac_outfile=conftest.$ac_objext
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- # The option is referenced via a variable to avoid confusing sed.
- lt_compile=`echo "$ac_compile" | $SED \
- -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:$LINENO: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $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.
- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_pic_works_CXX=yes
- fi
- fi
- $RM conftest*
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5
-$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; }
-
-if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then
- case $lt_prog_compiler_pic_CXX in
- "" | " "*) ;;
- *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
- esac
-else
- lt_prog_compiler_pic_CXX=
- lt_prog_compiler_can_build_shared_CXX=no
-fi
-
-fi
-
-
-
-#
-# Check to make sure the static flag actually works.
-#
-wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
-$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
-if test "${lt_cv_prog_compiler_static_works_CXX+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_prog_compiler_static_works_CXX=no
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
- echo "$lt_simple_link_test_code" > conftest.$ac_ext
- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
- # The linker can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test -s conftest.err; then
- # Append any errors to the config.log.
- cat conftest.err 1>&5
- $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
- $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
- if diff conftest.exp conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_static_works_CXX=yes
- fi
- else
- lt_cv_prog_compiler_static_works_CXX=yes
- fi
- fi
- $RM -r conftest*
- LDFLAGS="$save_LDFLAGS"
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5
-$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; }
-
-if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then
- :
-else
- lt_prog_compiler_static_CXX=
-fi
-
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
-$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
-if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_prog_compiler_c_o_CXX=no
- $RM -r conftest 2>/dev/null
- mkdir conftest
- cd conftest
- mkdir out
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- lt_compiler_flag="-o out/conftest2.$ac_objext"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- lt_compile=`echo "$ac_compile" | $SED \
- -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:$LINENO: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
- echo "$as_me:$LINENO: \$? = $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
- # So say no if there are warnings
- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
- $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
- if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_c_o_CXX=yes
- fi
- fi
- chmod u+w . 2>&5
- $RM conftest*
- # SGI C++ compiler will create directory out/ii_files/ for
- # template instantiation
- test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
- $RM out/* && rmdir out
- cd ..
- $RM -r conftest
- $RM conftest*
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
-$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
-$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
-if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_prog_compiler_c_o_CXX=no
- $RM -r conftest 2>/dev/null
- mkdir conftest
- cd conftest
- mkdir out
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- lt_compiler_flag="-o out/conftest2.$ac_objext"
- # Insert the option either (1) after the last *FLAGS variable, or
- # (2) before a word containing "conftest.", or (3) at the end.
- # Note that $ac_compile itself does not contain backslashes and begins
- # with a dollar sign (not a hyphen), so the echo should work correctly.
- lt_compile=`echo "$ac_compile" | $SED \
- -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:$LINENO: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
- echo "$as_me:$LINENO: \$? = $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
- # So say no if there are warnings
- $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
- $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
- if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
- lt_cv_prog_compiler_c_o_CXX=yes
- fi
- fi
- chmod u+w . 2>&5
- $RM conftest*
- # SGI C++ compiler will create directory out/ii_files/ for
- # template instantiation
- test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
- $RM out/* && rmdir out
- cd ..
- $RM -r conftest
- $RM conftest*
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
-$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
-
-
-
-
-hard_links="nottested"
-if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then
- # do not overwrite the value of need_locks provided by the user
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
-$as_echo_n "checking if we can lock with hard links... " >&6; }
- hard_links=yes
- $RM conftest*
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- touch conftest.a
- ln conftest.a conftest.b 2>&5 || hard_links=no
- ln conftest.a conftest.b 2>/dev/null && hard_links=no
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
-$as_echo "$hard_links" >&6; }
- if test "$hard_links" = no; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
-$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
- need_locks=warn
- fi
-else
- need_locks=no
-fi
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
-$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
-
- export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- case $host_os in
- aix[4-9]*)
- # If we're using GNU nm, then we don't want the "-C" option.
- # -C means demangle to AIX nm, but means don't demangle with GNU nm
- # Also, AIX nm treats weak defined symbols like other global defined
- # symbols, whereas GNU nm marks them as "W".
- if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
- export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
- else
- export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
- fi
- ;;
- pw32*)
- export_symbols_cmds_CXX="$ltdll_cmds"
- ;;
- cygwin* | mingw* | cegcc*)
- export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
- ;;
- *)
- export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
- ;;
- esac
- exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
-$as_echo "$ld_shlibs_CXX" >&6; }
-test "$ld_shlibs_CXX" = no && can_build_shared=no
-
-with_gnu_ld_CXX=$with_gnu_ld
-
-
-
-
-
-
-#
-# Do we need to explicitly link libc?
-#
-case "x$archive_cmds_need_lc_CXX" in
-x|xyes)
- # Assume -lc should be added
- archive_cmds_need_lc_CXX=yes
-
- if test "$enable_shared" = yes && test "$GCC" = yes; then
- case $archive_cmds_CXX in
- *'~'*)
- # FIXME: we may have to deal with multi-command sequences.
- ;;
- '$CC '*)
- # Test whether the compiler implicitly links with -lc since on some
- # systems, -lgcc has to come before -lc. If gcc already passes -lc
- # to ld, don't add -lc before -lgcc.
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
-$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
-if test "${lt_cv_archive_cmds_need_lc_CXX+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- $RM conftest*
- echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } 2>conftest.err; then
- soname=conftest
- lib=conftest
- libobjs=conftest.$ac_objext
- deplibs=
- wl=$lt_prog_compiler_wl_CXX
- pic_flag=$lt_prog_compiler_pic_CXX
- compiler_flags=-v
- linker_flags=-v
- verstring=
- output_objdir=.
- libname=conftest
- lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
- allow_undefined_flag_CXX=
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
- (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }
- then
- lt_cv_archive_cmds_need_lc_CXX=no
- else
- lt_cv_archive_cmds_need_lc_CXX=yes
- fi
- allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
- else
- cat conftest.err 1>&5
- fi
- $RM conftest*
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5
-$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; }
- archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX
- ;;
- esac
- fi
- ;;
-esac
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
-$as_echo_n "checking dynamic linker characteristics... " >&6; }
-
-library_names_spec=
-libname_spec='lib$name'
-soname_spec=
-shrext_cmds=".so"
-postinstall_cmds=
-postuninstall_cmds=
-finish_cmds=
-finish_eval=
-shlibpath_var=
-shlibpath_overrides_runpath=unknown
-version_type=none
-dynamic_linker="$host_os ld.so"
-sys_lib_dlsearch_path_spec="/lib /usr/lib"
-need_lib_prefix=unknown
-hardcode_into_libs=no
-
-# when you set need_version to no, make sure it does not cause -set_version
-# flags to be left without arguments
-need_version=unknown
-
-case $host_os in
-aix3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
- shlibpath_var=LIBPATH
-
- # AIX 3 has no versioning support, so we append a major version to the name.
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
-
-aix[4-9]*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- hardcode_into_libs=yes
- if test "$host_cpu" = ia64; then
- # AIX 5 supports IA64
- library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- else
- # With GCC up to 2.95.x, collect2 would create an import file
- # for dependence libraries. The import file would start with
- # the line `#! .'. This would cause the generated library to
- # depend on `.', always an invalid library. This was fixed in
- # development snapshots of GCC prior to 3.0.
- case $host_os in
- aix4 | aix4.[01] | aix4.[01].*)
- if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
- echo ' yes '
- echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
- :
- else
- can_build_shared=no
- fi
- ;;
- esac
- # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
- # soname into executable. Probably we can add versioning support to
- # collect2, so additional links can be useful in future.
- if test "$aix_use_runtimelinking" = yes; then
- # If using run time linking (on AIX 4.2 or later) use lib<name>.so
- # instead of lib<name>.a to let people know that these are not
- # typical AIX shared libraries.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- else
- # We preserve .a as extension for shared libraries through AIX4.2
- # and later when we are not doing run time linking.
- library_names_spec='${libname}${release}.a $libname.a'
- soname_spec='${libname}${release}${shared_ext}$major'
- fi
- shlibpath_var=LIBPATH
- fi
- ;;
-
-amigaos*)
- case $host_cpu in
- powerpc)
- # Since July 2007 AmigaOS4 officially supports .so libraries.
- # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- ;;
- m68k)
- library_names_spec='$libname.ixlibrary $libname.a'
- # Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
- ;;
- esac
- ;;
-
-beos*)
- library_names_spec='${libname}${shared_ext}'
- dynamic_linker="$host_os ld.so"
- shlibpath_var=LIBRARY_PATH
- ;;
-
-bsdi[45]*)
- version_type=linux
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
- sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
- # the default ld.so.conf also contains /usr/contrib/lib and
- # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
- # libtool to hard-code these into programs
- ;;
-
-cygwin* | mingw* | pw32* | cegcc*)
- version_type=windows
- shrext_cmds=".dll"
- need_version=no
- need_lib_prefix=no
-
- case $GCC,$host_os in
- yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
- library_names_spec='$libname.dll.a'
- # DLL is installed to $(libdir)/../bin by postinstall_cmds
- postinstall_cmds='base_file=`basename \${file}`~
- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
- dldir=$destdir/`dirname \$dlpath`~
- test -d \$dldir || mkdir -p \$dldir~
- $install_prog $dir/$dlname \$dldir/$dlname~
- chmod a+x \$dldir/$dlname~
- if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
- eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
- fi'
- postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
- dlpath=$dir/\$dldll~
- $RM \$dlpath'
- shlibpath_overrides_runpath=yes
-
- case $host_os in
- cygwin*)
- # Cygwin DLLs use 'cyg' prefix rather than 'lib'
- soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
-
- ;;
- mingw* | cegcc*)
- # MinGW DLLs use traditional 'lib' prefix
- soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- ;;
- pw32*)
- # pw32 DLLs use 'pw' prefix rather than 'lib'
- library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- ;;
- esac
- ;;
-
- *)
- library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
- ;;
- esac
- dynamic_linker='Win32 ld.exe'
- # FIXME: first we should search . and the directory the executable is in
- shlibpath_var=PATH
- ;;
-
-darwin* | rhapsody*)
- dynamic_linker="$host_os dyld"
- version_type=darwin
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
- soname_spec='${libname}${release}${major}$shared_ext'
- shlibpath_overrides_runpath=yes
- shlibpath_var=DYLD_LIBRARY_PATH
- shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
-
- sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
- ;;
-
-dgux*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-freebsd* | dragonfly*)
- # DragonFly does not have aout. When/if they implement a new
- # versioning mechanism, adjust this.
- if test -x /usr/bin/objformat; then
- objformat=`/usr/bin/objformat`
- else
- case $host_os in
- freebsd[23].*) objformat=aout ;;
- *) objformat=elf ;;
- esac
- fi
- version_type=freebsd-$objformat
- case $version_type in
- freebsd-elf*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- need_version=no
- need_lib_prefix=no
- ;;
- freebsd-*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
- need_version=yes
- ;;
- esac
- shlibpath_var=LD_LIBRARY_PATH
- case $host_os in
- freebsd2.*)
- shlibpath_overrides_runpath=yes
- ;;
- freebsd3.[01]* | freebsdelf3.[01]*)
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
- freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
- *) # from 4.6 on, and DragonFly
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
- esac
- ;;
-
-gnu*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- hardcode_into_libs=yes
- ;;
-
-haiku*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- dynamic_linker="$host_os runtime_loader"
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib'
- hardcode_into_libs=yes
- ;;
-
-hpux9* | hpux10* | hpux11*)
- # Give a soname corresponding to the major version so that dld.sl refuses to
- # link against other versions.
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- case $host_cpu in
- ia64*)
- shrext_cmds='.so'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.so"
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- if test "X$HPUX_IA64_MODE" = X32; then
- sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
- else
- sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
- fi
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- hppa*64*)
- shrext_cmds='.sl'
- hardcode_into_libs=yes
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
- shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
- ;;
- *)
- shrext_cmds='.sl'
- dynamic_linker="$host_os dld.sl"
- shlibpath_var=SHLIB_PATH
- shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- ;;
- esac
- # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
- postinstall_cmds='chmod 555 $lib'
- # or fails outright, so override atomically:
- install_override_mode=555
- ;;
-
-interix[3-9]*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
-irix5* | irix6* | nonstopux*)
- case $host_os in
- nonstopux*) version_type=nonstopux ;;
- *)
- if test "$lt_cv_prog_gnu_ld" = yes; then
- version_type=linux
- else
- version_type=irix
- fi ;;
- esac
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
- case $host_os in
- irix5* | nonstopux*)
- libsuff= shlibsuff=
- ;;
- *)
- case $LD in # libtool.m4 will add one of these switches to LD
- *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
- libsuff= shlibsuff= libmagic=32-bit;;
- *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
- libsuff=32 shlibsuff=N32 libmagic=N32;;
- *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
- libsuff=64 shlibsuff=64 libmagic=64-bit;;
- *) libsuff= shlibsuff= libmagic=never-match;;
- esac
- ;;
- esac
- shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
- sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
- hardcode_into_libs=yes
- ;;
-
-# No shared lib support for Linux oldld, aout, or coff.
-linux*oldld* | linux*aout* | linux*coff*)
- dynamic_linker=no
- ;;
-
-# This must be Linux ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
-
- # Some binutils ld are patched to set DT_RUNPATH
- if test "${lt_cv_shlibpath_overrides_runpath+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- lt_cv_shlibpath_overrides_runpath=no
- save_LDFLAGS=$LDFLAGS
- save_libdir=$libdir
- eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \
- LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\""
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_link "$LINENO"; then :
- if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
- lt_cv_shlibpath_overrides_runpath=yes
-fi
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- LDFLAGS=$save_LDFLAGS
- libdir=$save_libdir
-
-fi
-
- shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
-
- # This implies no fast_install, which is unacceptable.
- # Some rework will be needed to allow for fast_install
- # before this can be enabled.
- hardcode_into_libs=yes
-
- # Append ld.so.conf contents to the search path
- if test -f /etc/ld.so.conf; then
- lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
- sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
- fi
-
- # We used to test for /lib/ld.so.1 and disable shared libraries on
- # powerpc, because MkLinux only supported shared libraries with the
- # GNU dynamic linker. Since this was broken with cross compilers,
- # most powerpc-linux boxes support dynamic linking these days and
- # people can always --disable-shared, the test was removed, and we
- # assume the GNU/Linux dynamic linker is in use.
- dynamic_linker='GNU/Linux ld.so'
- ;;
-
-netbsd*)
- version_type=sunos
- need_lib_prefix=no
- need_version=no
- if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- dynamic_linker='NetBSD (a.out) ld.so'
- else
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- dynamic_linker='NetBSD ld.elf_so'
- fi
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- ;;
-
-newsos6)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- ;;
-
-*nto* | *qnx*)
- version_type=qnx
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- dynamic_linker='ldqnx.so'
- ;;
-
-openbsd*)
- version_type=sunos
- sys_lib_dlsearch_path_spec="/usr/lib"
- need_lib_prefix=no
- # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
- case $host_os in
- openbsd3.3 | openbsd3.3.*) need_version=yes ;;
- *) need_version=no ;;
- esac
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- case $host_os in
- openbsd2.[89] | openbsd2.[89].*)
- shlibpath_overrides_runpath=no
- ;;
- *)
- shlibpath_overrides_runpath=yes
- ;;
- esac
- else
- shlibpath_overrides_runpath=yes
- fi
- ;;
-
-os2*)
- libname_spec='$name'
- shrext_cmds=".dll"
- need_lib_prefix=no
- library_names_spec='$libname${shared_ext} $libname.a'
- dynamic_linker='OS/2 ld.exe'
- shlibpath_var=LIBPATH
- ;;
-
-osf3* | osf4* | osf5*)
- version_type=osf
- need_lib_prefix=no
- need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
- sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
- ;;
-
-rdos*)
- dynamic_linker=no
- ;;
-
-solaris*)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- # ldd complains unless libraries are executable
- postinstall_cmds='chmod +x $lib'
- ;;
-
-sunos4*)
- version_type=sunos
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- if test "$with_gnu_ld" = yes; then
- need_lib_prefix=no
- fi
- need_version=yes
- ;;
-
-sysv4 | sysv4.3*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- case $host_vendor in
- sni)
- shlibpath_overrides_runpath=no
- need_lib_prefix=no
- runpath_var=LD_RUN_PATH
- ;;
- siemens)
- need_lib_prefix=no
- ;;
- motorola)
- need_lib_prefix=no
- need_version=no
- shlibpath_overrides_runpath=no
- sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
- ;;
- esac
- ;;
-
-sysv4*MP*)
- if test -d /usr/nec ;then
- version_type=linux
- library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
- soname_spec='$libname${shared_ext}.$major'
- shlibpath_var=LD_LIBRARY_PATH
- fi
- ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- version_type=freebsd-elf
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=yes
- hardcode_into_libs=yes
- if test "$with_gnu_ld" = yes; then
- sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
- else
- sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
- case $host_os in
- sco3.2v5*)
- sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
- ;;
- esac
- fi
- sys_lib_dlsearch_path_spec='/usr/lib'
- ;;
-
-tpf*)
- # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
-uts4*)
- version_type=linux
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
-*)
- dynamic_linker=no
- ;;
-esac
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
-$as_echo "$dynamic_linker" >&6; }
-test "$dynamic_linker" = no && can_build_shared=no
-
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
- variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
-if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
- sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
-fi
-if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
- sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
-$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
-hardcode_action_CXX=
-if test -n "$hardcode_libdir_flag_spec_CXX" ||
- test -n "$runpath_var_CXX" ||
- test "X$hardcode_automatic_CXX" = "Xyes" ; then
-
- # We can hardcode non-existent directories.
- if test "$hardcode_direct_CXX" != no &&
- # If the only mechanism to avoid hardcoding is shlibpath_var, we
- # have to relink, otherwise we might link with an installed library
- # when we should be linking with a yet-to-be-installed one
- ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no &&
- test "$hardcode_minus_L_CXX" != no; then
- # Linking always hardcodes the temporary library directory.
- hardcode_action_CXX=relink
- else
- # We can link without hardcoding, and we can hardcode nonexisting dirs.
- hardcode_action_CXX=immediate
- fi
-else
- # We cannot hardcode anything, or else we can only hardcode existing
- # directories.
- hardcode_action_CXX=unsupported
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5
-$as_echo "$hardcode_action_CXX" >&6; }
-
-if test "$hardcode_action_CXX" = relink ||
- test "$inherit_rpath_CXX" = yes; then
- # Fast installation is not supported
- enable_fast_install=no
-elif test "$shlibpath_overrides_runpath" = yes ||
- test "$enable_shared" = no; then
- # Fast installation is not necessary
- enable_fast_install=needless
-fi
-
-
-
-
-
-
-
- fi # test -n "$compiler"
-
- CC=$lt_save_CC
- LDCXX=$LD
- LD=$lt_save_LD
- GCC=$lt_save_GCC
- with_gnu_ld=$lt_save_with_gnu_ld
- lt_cv_path_LDCXX=$lt_cv_path_LD
- lt_cv_path_LD=$lt_save_path_LD
- lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
- lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
-fi # test "$_lt_caught_CXX_error" != yes
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# Only expand once:
-
-
-
-
-
-# Identify the assembler which will work hand-in-glove with the newly
-# built GCC, so that we can examine its features. This is the assembler
-# which will be driven by the driver program.
-#
-# If build != host, and we aren't building gas in-tree, we identify a
-# build->target assembler and hope that it will have the same features
-# as the host->target assembler we'll be using.
-gcc_cv_gas_major_version=
-gcc_cv_gas_minor_version=
-gcc_cv_as_gas_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/gas
-
-if test "${gcc_cv_as+set}" = set; then :
-
-else
-
-if test -x "$DEFAULT_ASSEMBLER"; then
- gcc_cv_as="$DEFAULT_ASSEMBLER"
-elif test -f $gcc_cv_as_gas_srcdir/configure.in \
- && test -f ../gas/Makefile \
- && test x$build = x$host; then
- gcc_cv_as=../gas/as-new$build_exeext
-elif test -x as$build_exeext; then
- # Build using assembler in the current directory.
- gcc_cv_as=./as$build_exeext
-elif ( set dummy $AS_FOR_TARGET; test -x $2 ); then
- gcc_cv_as="$AS_FOR_TARGET"
-else
- # Extract the first word of "$AS_FOR_TARGET", so it can be a program name with args.
-set dummy $AS_FOR_TARGET; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_gcc_cv_as+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- case $gcc_cv_as in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_gcc_cv_as="$gcc_cv_as" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_gcc_cv_as="$as_dir/$ac_word$ac_exec_ext"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-gcc_cv_as=$ac_cv_path_gcc_cv_as
-if test -n "$gcc_cv_as"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as" >&5
-$as_echo "$gcc_cv_as" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-fi
-
-ORIGINAL_AS_FOR_TARGET=$gcc_cv_as
-
-case "$ORIGINAL_AS_FOR_TARGET" in
- ./as | ./as$build_exeext) ;;
- *) ac_config_files="$ac_config_files as:exec-tool.in"
- ;;
-esac
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking what assembler to use" >&5
-$as_echo_n "checking what assembler to use... " >&6; }
-if test "$gcc_cv_as" = ../gas/as-new$build_exeext; then
- # Single tree build which includes gas. We want to prefer it
- # over whatever linker top-level may have detected, since
- # we'll use what we're building after installation anyway.
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: newly built gas" >&5
-$as_echo "newly built gas" >&6; }
- in_tree_gas=yes
- gcc_cv_as_bfd_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/bfd
-for f in $gcc_cv_as_bfd_srcdir/configure \
- $gcc_cv_as_gas_srcdir/configure \
- $gcc_cv_as_gas_srcdir/configure.in \
- $gcc_cv_as_gas_srcdir/Makefile.in ; do
- gcc_cv_gas_version=`sed -n -e 's/^[ ]*VERSION=[^0-9A-Za-z_]*\([0-9]*\.[0-9]*.*\)/VERSION=\1/p' < $f`
- if test x$gcc_cv_gas_version != x; then
- break
- fi
-done
-case $gcc_cv_gas_version in
- VERSION=[0-9]*) ;;
- *) as_fn_error "cannot find version of in-tree assembler" "$LINENO" 5;;
-esac
-gcc_cv_gas_major_version=`expr "$gcc_cv_gas_version" : "VERSION=\([0-9]*\)"`
-gcc_cv_gas_minor_version=`expr "$gcc_cv_gas_version" : "VERSION=[0-9]*\.\([0-9]*\)"`
-gcc_cv_gas_patch_version=`expr "$gcc_cv_gas_version" : "VERSION=[0-9]*\.[0-9]*\.\([0-9]*\)"`
-case $gcc_cv_gas_patch_version in
- "") gcc_cv_gas_patch_version="0" ;;
-esac
-gcc_cv_gas_vers=`expr \( \( $gcc_cv_gas_major_version \* 1000 \) \
- + $gcc_cv_gas_minor_version \) \* 1000 \
- + $gcc_cv_gas_patch_version`
-
- in_tree_gas_is_elf=no
- if grep 'obj_format = elf' ../gas/Makefile > /dev/null \
- || (grep 'obj_format = multi' ../gas/Makefile \
- && grep 'extra_objects =.* obj-elf' ../gas/Makefile) > /dev/null
- then
- in_tree_gas_is_elf=yes
- fi
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as" >&5
-$as_echo "$gcc_cv_as" >&6; }
- in_tree_gas=no
-fi
-
-# Identify the linker which will work hand-in-glove with the newly
-# built GCC, so that we can examine its features. This is the linker
-# which will be driven by the driver program.
-#
-# If build != host, and we aren't building gas in-tree, we identify a
-# build->target linker and hope that it will have the same features
-# as the host->target linker we'll be using.
-gcc_cv_gld_major_version=
-gcc_cv_gld_minor_version=
-gcc_cv_ld_gld_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/ld
-gcc_cv_ld_bfd_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/bfd
-
-if test "${gcc_cv_ld+set}" = set; then :
-
-else
-
-if test -x "$DEFAULT_LINKER"; then
- gcc_cv_ld="$DEFAULT_LINKER"
-elif test -f $gcc_cv_ld_gld_srcdir/configure.in \
- && test -f ../ld/Makefile \
- && test x$build = x$host; then
- gcc_cv_ld=../ld/ld-new$build_exeext
-elif test -x collect-ld$build_exeext; then
- # Build using linker in the current directory.
- gcc_cv_ld=./collect-ld$build_exeext
-elif ( set dummy $LD_FOR_TARGET; test -x $2 ); then
- gcc_cv_ld="$LD_FOR_TARGET"
-else
- # Extract the first word of "$LD_FOR_TARGET", so it can be a program name with args.
-set dummy $LD_FOR_TARGET; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_gcc_cv_ld+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- case $gcc_cv_ld in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_gcc_cv_ld="$gcc_cv_ld" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_gcc_cv_ld="$as_dir/$ac_word$ac_exec_ext"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-gcc_cv_ld=$ac_cv_path_gcc_cv_ld
-if test -n "$gcc_cv_ld"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld" >&5
-$as_echo "$gcc_cv_ld" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-fi
-
-ORIGINAL_PLUGIN_LD_FOR_TARGET=$gcc_cv_ld
-PLUGIN_LD_SUFFIX=`basename $gcc_cv_ld | sed -e "s,$target_alias-,,"`
-# if the PLUGIN_LD is set ld-new, just have it as ld
-# as that is the installed named.
-if test x$PLUGIN_LD_SUFFIX = xld-new \
- || test x$PLUGIN_LD_SUFFIX = xcollect-ld ; then
- PLUGIN_LD_SUFFIX=ld
-fi
-
-# Check whether --with-plugin-ld was given.
-if test "${with_plugin_ld+set}" = set; then :
- withval=$with_plugin_ld; if test x"$withval" != x; then
- ORIGINAL_PLUGIN_LD_FOR_TARGET="$withval"
- PLUGIN_LD_SUFFIX=`echo $withval | sed -e "s,$target_alias-,,"`
- fi
-fi
-
-
-
-cat >>confdefs.h <<_ACEOF
-#define PLUGIN_LD_SUFFIX "$PLUGIN_LD_SUFFIX"
-_ACEOF
-
-
-# Check to see if we are using gold instead of ld
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using gold" >&5
-$as_echo_n "checking whether we are using gold... " >&6; }
-ld_is_gold=no
-if test x$gcc_cv_ld != x; then
- if $gcc_cv_ld --version 2>/dev/null | sed 1q \
- | grep "GNU gold" > /dev/null; then
- ld_is_gold=yes
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_is_gold" >&5
-$as_echo "$ld_is_gold" >&6; }
-
-ORIGINAL_LD_FOR_TARGET=$gcc_cv_ld
-
-case "$ORIGINAL_LD_FOR_TARGET" in
- ./collect-ld | ./collect-ld$build_exeext) ;;
- *) ac_config_files="$ac_config_files collect-ld:exec-tool.in"
- ;;
-esac
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking what linker to use" >&5
-$as_echo_n "checking what linker to use... " >&6; }
-if test "$gcc_cv_ld" = ../ld/ld-new$build_exeext \
- || test "$gcc_cv_ld" = ../gold/ld-new$build_exeext; then
- # Single tree build which includes ld. We want to prefer it
- # over whatever linker top-level may have detected, since
- # we'll use what we're building after installation anyway.
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: newly built ld" >&5
-$as_echo "newly built ld" >&6; }
- in_tree_ld=yes
- in_tree_ld_is_elf=no
- if (grep 'EMUL = .*elf' ../ld/Makefile \
- || grep 'EMUL = .*linux' ../ld/Makefile \
- || grep 'EMUL = .*lynx' ../ld/Makefile) > /dev/null; then
- in_tree_ld_is_elf=yes
- elif test "$ld_is_gold" = yes; then
- in_tree_ld_is_elf=yes
- fi
- for f in $gcc_cv_ld_bfd_srcdir/configure $gcc_cv_ld_gld_srcdir/configure $gcc_cv_ld_gld_srcdir/configure.in $gcc_cv_ld_gld_srcdir/Makefile.in
- do
- gcc_cv_gld_version=`sed -n -e 's/^[ ]*VERSION=[^0-9A-Za-z_]*\([0-9]*\.[0-9]*.*\)/VERSION=\1/p' < $f`
- if test x$gcc_cv_gld_version != x; then
- break
- fi
- done
- case $gcc_cv_gld_version in
- VERSION=[0-9]*) ;;
- *) as_fn_error "cannot find version of in-tree linker" "$LINENO" 5 ;;
- esac
- gcc_cv_gld_major_version=`expr "$gcc_cv_gld_version" : "VERSION=\([0-9]*\)"`
- gcc_cv_gld_minor_version=`expr "$gcc_cv_gld_version" : "VERSION=[0-9]*\.\([0-9]*\)"`
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld" >&5
-$as_echo "$gcc_cv_ld" >&6; }
- in_tree_ld=no
-fi
-
-# Figure out what nm we will be using.
-gcc_cv_binutils_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/binutils
-if test "${gcc_cv_nm+set}" = set; then :
-
-else
-
-if test -f $gcc_cv_binutils_srcdir/configure.in \
- && test -f ../binutils/Makefile \
- && test x$build = x$host; then
- gcc_cv_nm=../binutils/nm-new$build_exeext
-elif test -x nm$build_exeext; then
- gcc_cv_nm=./nm$build_exeext
-elif ( set dummy $NM_FOR_TARGET; test -x $2 ); then
- gcc_cv_nm="$NM_FOR_TARGET"
-else
- # Extract the first word of "$NM_FOR_TARGET", so it can be a program name with args.
-set dummy $NM_FOR_TARGET; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_gcc_cv_nm+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- case $gcc_cv_nm in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_gcc_cv_nm="$gcc_cv_nm" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_gcc_cv_nm="$as_dir/$ac_word$ac_exec_ext"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-gcc_cv_nm=$ac_cv_path_gcc_cv_nm
-if test -n "$gcc_cv_nm"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_nm" >&5
-$as_echo "$gcc_cv_nm" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking what nm to use" >&5
-$as_echo_n "checking what nm to use... " >&6; }
-if test "$gcc_cv_nm" = ../binutils/nm-new$build_exeext; then
- # Single tree build which includes binutils.
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: newly built nm" >&5
-$as_echo "newly built nm" >&6; }
- in_tree_nm=yes
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_nm" >&5
-$as_echo "$gcc_cv_nm" >&6; }
- in_tree_nm=no
-fi
-
-ORIGINAL_NM_FOR_TARGET=$gcc_cv_nm
-
-case "$ORIGINAL_NM_FOR_TARGET" in
- ./nm | ./nm$build_exeext) ;;
- *) ac_config_files="$ac_config_files nm:exec-tool.in"
- ;;
-esac
-
-
-# Figure out what objdump we will be using.
-if test "${gcc_cv_objdump+set}" = set; then :
-
-else
-
-if test -f $gcc_cv_binutils_srcdir/configure.in \
- && test -f ../binutils/Makefile \
- && test x$build = x$host; then
- # Single tree build which includes binutils.
- gcc_cv_objdump=../binutils/objdump$build_exeext
-elif test -x objdump$build_exeext; then
- gcc_cv_objdump=./objdump$build_exeext
-elif ( set dummy $OBJDUMP_FOR_TARGET; test -x $2 ); then
- gcc_cv_objdump="$OBJDUMP_FOR_TARGET"
-else
- # Extract the first word of "$OBJDUMP_FOR_TARGET", so it can be a program name with args.
-set dummy $OBJDUMP_FOR_TARGET; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_gcc_cv_objdump+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- case $gcc_cv_objdump in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_gcc_cv_objdump="$gcc_cv_objdump" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_gcc_cv_objdump="$as_dir/$ac_word$ac_exec_ext"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-gcc_cv_objdump=$ac_cv_path_gcc_cv_objdump
-if test -n "$gcc_cv_objdump"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_objdump" >&5
-$as_echo "$gcc_cv_objdump" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking what objdump to use" >&5
-$as_echo_n "checking what objdump to use... " >&6; }
-if test "$gcc_cv_objdump" = ../binutils/objdump$build_exeext; then
- # Single tree build which includes binutils.
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: newly built objdump" >&5
-$as_echo "newly built objdump" >&6; }
-elif test x$gcc_cv_objdump = x; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_objdump" >&5
-$as_echo "$gcc_cv_objdump" >&6; }
-fi
-
-# Figure out what readelf we will be using.
-if test "${gcc_cv_readelf+set}" = set; then :
-
-else
-
-if test -f $gcc_cv_binutils_srcdir/configure.in \
- && test -f ../binutils/Makefile \
- && test x$build = x$host; then
- # Single tree build which includes binutils.
- gcc_cv_readelf=../binutils/readelf$build_exeext
-elif test -x readelf$build_exeext; then
- gcc_cv_readelf=./readelf$build_exeext
-elif ( set dummy $READELF_FOR_TARGET; test -x $2 ); then
- gcc_cv_readelf="$READELF_FOR_TARGET"
-else
- # Extract the first word of "$READELF_FOR_TARGET", so it can be a program name with args.
-set dummy $READELF_FOR_TARGET; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_gcc_cv_readelf+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- case $gcc_cv_readelf in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_gcc_cv_readelf="$gcc_cv_readelf" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
- ac_cv_path_gcc_cv_readelf="$as_dir/$ac_word$ac_exec_ext"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-gcc_cv_readelf=$ac_cv_path_gcc_cv_readelf
-if test -n "$gcc_cv_readelf"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_readelf" >&5
-$as_echo "$gcc_cv_readelf" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking what readelf to use" >&5
-$as_echo_n "checking what readelf to use... " >&6; }
-if test "$gcc_cv_readelf" = ../binutils/readelf$build_exeext; then
- # Single tree build which includes binutils.
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: newly built readelf" >&5
-$as_echo "newly built readelf" >&6; }
-elif test x$gcc_cv_readelf = x; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_readelf" >&5
-$as_echo "$gcc_cv_readelf" >&6; }
-fi
-
-# Figure out what assembler alignment features are present.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler flags" >&5
-$as_echo_n "checking assembler flags... " >&6; }
-if test "${gcc_cv_as_flags+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- case "$target" in
- i[34567]86-*-linux*)
- gcc_cv_as_flags="--32"
- ;;
- powerpc*-*-darwin*)
- gcc_cv_as_flags="-arch ppc"
- ;;
- *)
- gcc_cv_as_flags=" "
- ;;
- esac
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_flags" >&5
-$as_echo "$gcc_cv_as_flags" >&6; }
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .balign and .p2align" >&5
-$as_echo_n "checking assembler for .balign and .p2align... " >&6; }
-if test "${gcc_cv_as_balign_and_p2align+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_balign_and_p2align=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 6 \) \* 1000 + 0`
- then gcc_cv_as_balign_and_p2align=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo '.balign 4
-.p2align 2' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_balign_and_p2align=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_balign_and_p2align" >&5
-$as_echo "$gcc_cv_as_balign_and_p2align" >&6; }
-if test $gcc_cv_as_balign_and_p2align = yes; then
-
-$as_echo "#define HAVE_GAS_BALIGN_AND_P2ALIGN 1" >>confdefs.h
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .p2align with maximum skip" >&5
-$as_echo_n "checking assembler for .p2align with maximum skip... " >&6; }
-if test "${gcc_cv_as_max_skip_p2align+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_max_skip_p2align=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 8 \) \* 1000 + 0`
- then gcc_cv_as_max_skip_p2align=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo '.p2align 4,,7' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_max_skip_p2align=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_max_skip_p2align" >&5
-$as_echo "$gcc_cv_as_max_skip_p2align" >&6; }
-if test $gcc_cv_as_max_skip_p2align = yes; then
-
-$as_echo "#define HAVE_GAS_MAX_SKIP_P2ALIGN 1" >>confdefs.h
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .literal16" >&5
-$as_echo_n "checking assembler for .literal16... " >&6; }
-if test "${gcc_cv_as_literal16+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_literal16=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 8 \) \* 1000 + 0`
- then gcc_cv_as_literal16=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo '.literal16' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_literal16=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_literal16" >&5
-$as_echo "$gcc_cv_as_literal16" >&6; }
-if test $gcc_cv_as_literal16 = yes; then
-
-$as_echo "#define HAVE_GAS_LITERAL16 1" >>confdefs.h
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for working .subsection -1" >&5
-$as_echo_n "checking assembler for working .subsection -1... " >&6; }
-if test "${gcc_cv_as_subsection_m1+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_subsection_m1=no
- if test $in_tree_gas = yes; then
- if test $in_tree_gas_is_elf = yes \
- && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 9 \) \* 1000 + 0`
- then gcc_cv_as_subsection_m1=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo 'conftest_label1: .word 0
-.subsection -1
-conftest_label2: .word 0
-.previous' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- if test x$gcc_cv_nm != x; then
- $gcc_cv_nm conftest.o | grep conftest_label1 > conftest.nm1
- $gcc_cv_nm conftest.o | grep conftest_label2 | sed -e 's/label2/label1/' > conftest.nm2
- if cmp conftest.nm1 conftest.nm2 > /dev/null 2>&1
- then :
- else gcc_cv_as_subsection_m1=yes
- fi
- rm -f conftest.nm1 conftest.nm2
- fi
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_subsection_m1" >&5
-$as_echo "$gcc_cv_as_subsection_m1" >&6; }
-if test $gcc_cv_as_subsection_m1 = yes; then
-
-$as_echo "#define HAVE_GAS_SUBSECTION_ORDERING 1" >>confdefs.h
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .weak" >&5
-$as_echo_n "checking assembler for .weak... " >&6; }
-if test "${gcc_cv_as_weak+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_weak=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 2 \) \* 1000 + 0`
- then gcc_cv_as_weak=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo ' .weak foobar' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_weak=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_weak" >&5
-$as_echo "$gcc_cv_as_weak" >&6; }
-if test $gcc_cv_as_weak = yes; then
-
-$as_echo "#define HAVE_GAS_WEAK 1" >>confdefs.h
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .weakref" >&5
-$as_echo_n "checking assembler for .weakref... " >&6; }
-if test "${gcc_cv_as_weakref+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_weakref=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 17 \) \* 1000 + 0`
- then gcc_cv_as_weakref=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo ' .weakref foobar, barfnot' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_weakref=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_weakref" >&5
-$as_echo "$gcc_cv_as_weakref" >&6; }
-if test $gcc_cv_as_weakref = yes; then
-
-$as_echo "#define HAVE_GAS_WEAKREF 1" >>confdefs.h
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .nsubspa comdat" >&5
-$as_echo_n "checking assembler for .nsubspa comdat... " >&6; }
-if test "${gcc_cv_as_nsubspa_comdat+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_nsubspa_comdat=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 15 \) \* 1000 + 91`
- then gcc_cv_as_nsubspa_comdat=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo ' .SPACE $TEXT$
- .NSUBSPA $CODE$,COMDAT' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_nsubspa_comdat=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_nsubspa_comdat" >&5
-$as_echo "$gcc_cv_as_nsubspa_comdat" >&6; }
-if test $gcc_cv_as_nsubspa_comdat = yes; then
-
-$as_echo "#define HAVE_GAS_NSUBSPA_COMDAT 1" >>confdefs.h
-
-fi
-
-# .hidden needs to be supported in both the assembler and the linker,
-# because GNU LD versions before 2.12.1 have buggy support for STV_HIDDEN.
-# This is irritatingly difficult to feature test for; we have to check the
-# date string after the version number. If we've got an in-tree
-# ld, we don't know its patchlevel version, so we set the baseline at 2.13
-# to be safe.
-# The gcc_GAS_CHECK_FEATURE call just sets a cache variable.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .hidden" >&5
-$as_echo_n "checking assembler for .hidden... " >&6; }
-if test "${gcc_cv_as_hidden+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_hidden=no
- if test $in_tree_gas = yes; then
- if test $in_tree_gas_is_elf = yes \
- && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 13 \) \* 1000 + 0`
- then gcc_cv_as_hidden=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo ' .hidden foobar
-foobar:' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
-
-# Solaris 9/x86 as incorrectly emits an alias for a hidden symbol with
-# STV_HIDDEN, so disable .hidden support if so.
-case "${target}" in
- i?86-*-solaris2* | x86_64-*-solaris2.1[0-9]*)
- if test x$gcc_cv_as != x && test x$gcc_cv_objdump != x; then
- cat > conftest.s <<EOF
-.globl hidden
- .hidden hidden
-hidden:
-.globl default
- .set default,hidden
-EOF
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1 \
- && $gcc_cv_objdump -t conftest.o 2>/dev/null | \
- grep '\.hidden default' > /dev/null; then
- gcc_cv_as_hidden=no
- else
- gcc_cv_as_hidden=yes
- fi
- else
- # Assume bug is present if objdump is missing.
- gcc_cv_as_hidden=no
- fi
- ;;
- *)
- gcc_cv_as_hidden=yes
- ;;
-esac
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_hidden" >&5
-$as_echo "$gcc_cv_as_hidden" >&6; }
-
-case "${target}" in
- *-*-darwin*)
- # Darwin as has some visibility support, though with a different syntax.
- gcc_cv_as_hidden=yes
- ;;
-esac
-
-# gnu_indirect_function type is an extension proposed at
-# http://groups.google/com/group/generic-abi/files. It allows dynamic runtime
-# selection of function implementation
-# Check whether --enable-gnu-indirect-function was given.
-if test "${enable_gnu_indirect_function+set}" = set; then :
- enableval=$enable_gnu_indirect_function; case $enable_gnu_indirect_function in
- yes | no) ;;
- *) as_fn_error "'$enable_gnu_indirect_function' is an invalid value for --enable-gnu-indirect-function.
-Valid choices are 'yes' and 'no'." "$LINENO" 5 ;;
- esac
-else
- enable_gnu_indirect_function="$default_gnu_indirect_function"
-fi
-
-if test x$enable_gnu_indirect_function = xyes; then
-
-$as_echo "#define HAVE_GNU_INDIRECT_FUNCTION 1" >>confdefs.h
-
-fi
-
-if test $in_tree_ld != yes ; then
- ld_ver=`$gcc_cv_ld --version 2>/dev/null | sed 1q`
- if echo "$ld_ver" | grep GNU > /dev/null; then
- if test x"$ld_is_gold" = xyes; then
- # GNU gold --version looks like this:
- #
- # GNU gold (GNU Binutils 2.21.51.20110225) 1.11
- #
- # We extract the binutils version which is more familiar and specific
- # than the gold version.
- ld_vers=`echo $ld_ver | sed -n \
- -e 's,^[^)]*[ ]\([0-9][0-9]*\.[0-9][0-9]*[^)]*\)) .*$,\1,p'`
- else
- # GNU ld --version looks like this:
- #
- # GNU ld (GNU Binutils) 2.21.51.20110225
- ld_vers=`echo $ld_ver | sed -n \
- -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*.*\)$,\1,p'`
- fi
- ld_date=`echo $ld_ver | sed -n 's,^.*\([2-9][0-9][0-9][0-9]\)[-]*\([01][0-9]\)[-]*\([0-3][0-9]\).*$,\1\2\3,p'`
- ld_vers_major=`expr "$ld_vers" : '\([0-9]*\)'`
- ld_vers_minor=`expr "$ld_vers" : '[0-9]*\.\([0-9]*\)'`
- ld_vers_patch=`expr "$ld_vers" : '[0-9]*\.[0-9]*\.\([0-9]*\)'`
- else
- case "${target}" in
- *-*-solaris2*)
- # See acinclude.m4 (gcc_SUN_LD_VERSION) for the version number
- # format.
- #
- # Don't reuse gcc_gv_sun_ld_vers_* in case a linker other than
- # /usr/ccs/bin/ld has been configured.
- ld_ver=`$gcc_cv_ld -V 2>&1`
- if echo "$ld_ver" | grep 'Solaris Link Editors' > /dev/null; then
- ld_vers=`echo $ld_ver | sed -n \
- -e 's,^.*: 5\.[0-9][0-9]*-\([0-9]\.[0-9][0-9]*\).*$,\1,p'`
- ld_vers_major=`expr "$ld_vers" : '\([0-9]*\)'`
- ld_vers_minor=`expr "$ld_vers" : '[0-9]*\.\([0-9]*\)'`
- fi
- ;;
- esac
- fi
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker for .hidden support" >&5
-$as_echo_n "checking linker for .hidden support... " >&6; }
-if test "${gcc_cv_ld_hidden+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test $in_tree_ld = yes ; then
- gcc_cv_ld_hidden=no
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 13 -o "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes; then
- gcc_cv_ld_hidden=yes
- fi
-else
- gcc_cv_ld_hidden=yes
- if test x"$ld_is_gold" = xyes; then
- :
- elif echo "$ld_ver" | grep GNU > /dev/null; then
- case "${target}" in
- mmix-knuth-mmixware)
- # The linker emits by default mmo, not ELF, so "no" is appropriate.
- gcc_cv_ld_hidden=no
- ;;
- esac
- if test 0"$ld_date" -lt 20020404; then
- if test -n "$ld_date"; then
- # If there was date string, but was earlier than 2002-04-04, fail
- gcc_cv_ld_hidden=no
- elif test -z "$ld_vers"; then
- # If there was no date string nor ld version number, something is wrong
- gcc_cv_ld_hidden=no
- else
- test -z "$ld_vers_patch" && ld_vers_patch=0
- if test "$ld_vers_major" -lt 2; then
- gcc_cv_ld_hidden=no
- elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -lt 12; then
- gcc_cv_ld_hidden="no"
- elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -eq 12 -a "$ld_vers_patch" -eq 0; then
- gcc_cv_ld_hidden=no
- fi
- fi
- fi
- else
- case "${target}" in
- *-*-darwin*)
- # Darwin ld has some visibility support.
- gcc_cv_ld_hidden=yes
- ;;
- hppa64*-*-hpux* | ia64*-*-hpux*)
- gcc_cv_ld_hidden=yes
- ;;
- *-*-solaris2.9* | *-*-solaris2.1[0-9]*)
- # Support for .hidden in Sun ld appeared in Solaris 9 FCS, but
- # .symbolic was only added in Solaris 9 12/02.
- gcc_cv_ld_hidden=yes
- ;;
- *)
- gcc_cv_ld_hidden=no
- ;;
- esac
- fi
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_hidden" >&5
-$as_echo "$gcc_cv_ld_hidden" >&6; }
-libgcc_visibility=no
-
-
-if test $gcc_cv_as_hidden = yes && test $gcc_cv_ld_hidden = yes; then
- libgcc_visibility=yes
-
-$as_echo "#define HAVE_GAS_HIDDEN 1" >>confdefs.h
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker read-only and read-write section mixing" >&5
-$as_echo_n "checking linker read-only and read-write section mixing... " >&6; }
-gcc_cv_ld_ro_rw_mix=unknown
-if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 10 -o "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes; then
- gcc_cv_ld_ro_rw_mix=read-write
- fi
-elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x -a x$gcc_cv_objdump != x ; then
- echo '.section myfoosect, "a"' > conftest1.s
- echo '.section myfoosect, "aw"' > conftest2.s
- echo '.byte 1' >> conftest2.s
- echo '.section myfoosect, "a"' > conftest3.s
- echo '.byte 0' >> conftest3.s
- if $gcc_cv_as -o conftest1.o conftest1.s > /dev/null 2>&1 \
- && $gcc_cv_as -o conftest2.o conftest2.s > /dev/null 2>&1 \
- && $gcc_cv_as -o conftest3.o conftest3.s > /dev/null 2>&1 \
- && $gcc_cv_ld -shared -o conftest1.so conftest1.o \
- conftest2.o conftest3.o > /dev/null 2>&1; then
- gcc_cv_ld_ro_rw_mix=`$gcc_cv_objdump -h conftest1.so \
- | sed -e '/myfoosect/!d' -e N`
- if echo "$gcc_cv_ld_ro_rw_mix" | grep CONTENTS > /dev/null; then
- if echo "$gcc_cv_ld_ro_rw_mix" | grep READONLY > /dev/null; then
- gcc_cv_ld_ro_rw_mix=read-only
- else
- gcc_cv_ld_ro_rw_mix=read-write
- fi
- fi
- fi
- rm -f conftest.* conftest[123].*
-fi
-if test x$gcc_cv_ld_ro_rw_mix = xread-write; then
-
-$as_echo "#define HAVE_LD_RO_RW_SECTION_MIXING 1" >>confdefs.h
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_ro_rw_mix" >&5
-$as_echo "$gcc_cv_ld_ro_rw_mix" >&6; }
-
-if test "x${build}" = "x${target}" && test "x${build}" = "x${host}"; then
- case "${target}" in
- *-*-solaris2*)
- #
- # Solaris 2 ld -V output looks like this for a regular version:
- #
- # ld: Software Generation Utilities - Solaris Link Editors: 5.11-1.1699
- #
- # but test versions add stuff at the end:
- #
- # ld: Software Generation Utilities - Solaris Link Editors: 5.11-1.1701:onnv-ab196087-6931056-03/25/10
- #
- gcc_cv_sun_ld_ver=`/usr/ccs/bin/ld -V 2>&1`
- if echo "$gcc_cv_sun_ld_ver" | grep 'Solaris Link Editors' > /dev/null; then
- gcc_cv_sun_ld_vers=`echo $gcc_cv_sun_ld_ver | sed -n \
- -e 's,^.*: 5\.[0-9][0-9]*-\([0-9]\.[0-9][0-9]*\).*$,\1,p'`
- gcc_cv_sun_ld_vers_major=`expr "$gcc_cv_sun_ld_vers" : '\([0-9]*\)'`
- gcc_cv_sun_ld_vers_minor=`expr "$gcc_cv_sun_ld_vers" : '[0-9]*\.\([0-9]*\)'`
- fi
- ;;
- esac
-fi
-
-# Check whether --enable-initfini-array was given.
-if test "${enable_initfini_array+set}" = set; then :
- enableval=$enable_initfini_array;
-else
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for .preinit_array/.init_array/.fini_array support" >&5
-$as_echo_n "checking for .preinit_array/.init_array/.fini_array support... " >&6; }
-if test "${gcc_cv_initfini_array+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test "x${build}" = "x${target}" && test "x${build}" = "x${host}"; then
- case "${target}" in
- ia64-*)
- if test "$cross_compiling" = yes; then :
- gcc_cv_initfini_array=no
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-#ifndef __ELF__
-#error Not an ELF OS
-#endif
-/* We turn on .preinit_array/.init_array/.fini_array support for ia64
- if it can be used. */
-static int x = -1;
-int main (void) { return x; }
-int foo (void) { x = 0; }
-int (*fp) (void) __attribute__ ((section (".init_array"))) = foo;
-
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
- gcc_cv_initfini_array=yes
-else
- gcc_cv_initfini_array=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-;;
- *)
- gcc_cv_initfini_array=no
- if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 \
- -a "$gcc_cv_gld_minor_version" -ge 22 \
- -o "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes; then
- gcc_cv_initfini_array=yes
- fi
- elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x -a x$gcc_cv_objdump != x ; then
- cat > conftest.s <<\EOF
-.section .dtors,"a",%progbits
-.balign 4
-.byte 'A', 'A', 'A', 'A'
-.section .ctors,"a",%progbits
-.balign 4
-.byte 'B', 'B', 'B', 'B'
-.section .fini_array.65530,"a",%progbits
-.balign 4
-.byte 'C', 'C', 'C', 'C'
-.section .init_array.65530,"a",%progbits
-.balign 4
-.byte 'D', 'D', 'D', 'D'
-.section .dtors.64528,"a",%progbits
-.balign 4
-.byte 'E', 'E', 'E', 'E'
-.section .ctors.64528,"a",%progbits
-.balign 4
-.byte 'F', 'F', 'F', 'F'
-.section .fini_array.01005,"a",%progbits
-.balign 4
-.byte 'G', 'G', 'G', 'G'
-.section .init_array.01005,"a",%progbits
-.balign 4
-.byte 'H', 'H', 'H', 'H'
-.text
-.globl _start
-_start:
-EOF
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1 \
- && $gcc_cv_ld -o conftest conftest.o > /dev/null 2>&1 \
- && $gcc_cv_objdump -s -j .init_array conftest \
- | grep HHHHFFFFDDDDBBBB > /dev/null 2>&1 \
- && $gcc_cv_objdump -s -j .fini_array conftest \
- | grep GGGGEEEECCCCAAAA > /dev/null 2>&1; then
- gcc_cv_initfini_array=yes
- fi
- rm -f conftest conftest.*
- fi
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-#ifndef __ELF__
-# error Not an ELF OS
-#endif
-#include <stdlib.h>
-#if defined __GLIBC_PREREQ
-# if __GLIBC_PREREQ (2, 4)
-# else
-# error GLIBC 2.4 required
-# endif
-#else
-# if defined __sun__ && defined __svr4__
- /* Solaris ld.so.1 supports .init_array/.fini_array since Solaris 8. */
-# else
-# error The C library not known to support .init_array/.fini_array
-# endif
-#endif
-
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
- gcc_cv_initfini_array=no
-fi
-rm -f conftest.err conftest.$ac_ext;;
- esac
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking cross compile... guessing" >&5
-$as_echo_n "checking cross compile... guessing... " >&6; }
- gcc_cv_initfini_array=no
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_initfini_array" >&5
-$as_echo "$gcc_cv_initfini_array" >&6; }
- enable_initfini_array=$gcc_cv_initfini_array
-
-fi
-
-if test $enable_initfini_array = yes; then
-
-$as_echo "#define HAVE_INITFINI_ARRAY_SUPPORT 1" >>confdefs.h
-
-fi
-
-# Check if we have .[us]leb128, and support symbol arithmetic with it.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .sleb128 and .uleb128" >&5
-$as_echo_n "checking assembler for .sleb128 and .uleb128... " >&6; }
-if test "${gcc_cv_as_leb128+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_leb128=no
- if test $in_tree_gas = yes; then
- if test $in_tree_gas_is_elf = yes \
- && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 11 \) \* 1000 + 0`
- then gcc_cv_as_leb128=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo ' .data
- .uleb128 L2 - L1
-L1:
- .uleb128 1280
- .sleb128 -1010
-L2:' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- # GAS versions before 2.11 do not support uleb128,
- # despite appearing to.
- # ??? There exists an elf-specific test that will crash
- # the assembler. Perhaps it's better to figure out whether
- # arbitrary sections are supported and try the test.
- as_ver=`$gcc_cv_as --version 2>/dev/null | sed 1q`
- if echo "$as_ver" | grep GNU > /dev/null; then
- 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]*\)'`
- if test $as_major -eq 2 && test $as_minor -lt 11
- then :
- else gcc_cv_as_leb128=yes
- fi
- fi
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_leb128" >&5
-$as_echo "$gcc_cv_as_leb128" >&6; }
-if test $gcc_cv_as_leb128 = yes; then
-
-$as_echo "#define HAVE_AS_LEB128 1" >>confdefs.h
-
-fi
-
-# Check if we have assembler support for unwind directives.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for cfi directives" >&5
-$as_echo_n "checking assembler for cfi directives... " >&6; }
-if test "${gcc_cv_as_cfi_directive+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_cfi_directive=no
- if test x$gcc_cv_as != x; then
- $as_echo ' .text
- .cfi_startproc
- .cfi_offset 0, 0
- .cfi_same_value 1
- .cfi_def_cfa 1, 2
- .cfi_escape 1, 2, 3, 4, 5
- .cfi_endproc' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- case "$target" in
- *-*-solaris*)
- # If the linker used on Solaris (like Sun ld) isn't capable of merging
- # read-only and read-write sections, we need to make sure that the
- # assembler used emits read-write .eh_frame sections.
- if test "x$gcc_cv_ld_ro_rw_mix" != xread-write; then
- if test "x$gcc_cv_objdump" != x; then
- if $gcc_cv_objdump -h conftest.o 2>/dev/null | \
- sed -e /.eh_frame/!d -e N | grep READONLY > /dev/null; then
- gcc_cv_as_cfi_directive=no
- else
- case "$target" in
- i?86-*-solaris2.1[0-9]* | x86_64-*-solaris2.1[0-9]*)
- # On Solaris/x86, make sure that GCC and gas agree on using
- # read-only .eh_frame sections for 64-bit.
- if $gcc_cv_as --64 -o conftest.o conftest.s > /dev/null 2>&1 && \
- $gcc_cv_objdump -h conftest.o 2>/dev/null | \
- sed -e /.eh_frame/!d -e N | \
- grep READONLY > /dev/null; then
- gcc_cv_as_cfi_directive=yes
- else
- gcc_cv_as_cfi_directive=no
- fi
- ;;
- *)
- gcc_cv_as_cfi_directive=yes
- ;;
- esac
- fi
- else
- # no objdump, err on the side of caution
- gcc_cv_as_cfi_directive=no
- fi
- else
- gcc_cv_as_cfi_directive=yes
- fi
- ;;
- *-*-*)
- gcc_cv_as_cfi_directive=yes
- ;;
-esac
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_cfi_directive" >&5
-$as_echo "$gcc_cv_as_cfi_directive" >&6; }
-
-if test $gcc_cv_as_cfi_directive = yes && test x$gcc_cv_objdump != x; then
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for working cfi advance" >&5
-$as_echo_n "checking assembler for working cfi advance... " >&6; }
-if test "${gcc_cv_as_cfi_advance_working+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_cfi_advance_working=no
- if test x$gcc_cv_as != x; then
- $as_echo ' .text
- .cfi_startproc
- .cfi_adjust_cfa_offset 64
- .skip 75040, 0
- .cfi_adjust_cfa_offset 128
- .cfi_endproc' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
-
-if $gcc_cv_objdump -Wf conftest.o 2>/dev/null \
- | grep 'DW_CFA_advance_loc[24]:[ ][ ]*75040[ ]' >/dev/null; then
- gcc_cv_as_cfi_advance_working=yes
-fi
-
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_cfi_advance_working" >&5
-$as_echo "$gcc_cv_as_cfi_advance_working" >&6; }
-
-else
- # no objdump, err on the side of caution
- gcc_cv_as_cfi_advance_working=no
-fi
-
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_GAS_CFI_DIRECTIVE `if test $gcc_cv_as_cfi_directive = yes \
- && test $gcc_cv_as_cfi_advance_working = yes; then echo 1; else echo 0; fi`
-_ACEOF
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for cfi personality directive" >&5
-$as_echo_n "checking assembler for cfi personality directive... " >&6; }
-if test "${gcc_cv_as_cfi_personality_directive+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_cfi_personality_directive=no
- if test x$gcc_cv_as != x; then
- $as_echo ' .text
- .cfi_startproc
- .cfi_personality 0, symbol
- .cfi_endproc' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_cfi_personality_directive=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_cfi_personality_directive" >&5
-$as_echo "$gcc_cv_as_cfi_personality_directive" >&6; }
-
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_GAS_CFI_PERSONALITY_DIRECTIVE `if test $gcc_cv_as_cfi_personality_directive = yes;
- then echo 1; else echo 0; fi`
-_ACEOF
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for cfi sections directive" >&5
-$as_echo_n "checking assembler for cfi sections directive... " >&6; }
-if test "${gcc_cv_as_cfi_sections_directive+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_cfi_sections_directive=no
- if test x$gcc_cv_as != x; then
- $as_echo ' .text
- .cfi_sections .debug_frame, .eh_frame
- .cfi_startproc
- .cfi_endproc' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- case $target_os in
- win32 | pe | cygwin* | mingw32* | uwin*)
- # Need to check that we generated the correct relocation for the
- # .debug_frame section. This was fixed for binutils 2.21.
- gcc_cv_as_cfi_sections_directive=no
- if test "x$gcc_cv_objdump" != x; then
- if $gcc_cv_objdump -j .debug_frame -r conftest.o 2>/dev/null | \
- grep secrel > /dev/null; then
- gcc_cv_as_cfi_sections_directive=yes
- fi
- fi
- ;;
- *)
- gcc_cv_as_cfi_sections_directive=yes
- ;;
-esac
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_cfi_sections_directive" >&5
-$as_echo "$gcc_cv_as_cfi_sections_directive" >&6; }
-
-
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_GAS_CFI_SECTIONS_DIRECTIVE `if test $gcc_cv_as_cfi_sections_directive = yes;
- then echo 1; else echo 0; fi`
-_ACEOF
-
-
-# GAS versions up to and including 2.11.0 may mis-optimize
-# .eh_frame data.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for eh_frame optimization" >&5
-$as_echo_n "checking assembler for eh_frame optimization... " >&6; }
-if test "${gcc_cv_as_eh_frame+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_eh_frame=no
- if test $in_tree_gas = yes; then
- if test $in_tree_gas_is_elf = yes \
- && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 12 \) \* 1000 + 0`
- then gcc_cv_as_eh_frame=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo ' .text
-.LFB1:
- .4byte 0
-.L1:
- .4byte 0
-.LFE1:
- .section .eh_frame,"aw",@progbits
-__FRAME_BEGIN__:
- .4byte .LECIE1-.LSCIE1
-.LSCIE1:
- .4byte 0x0
- .byte 0x1
- .ascii "z\0"
- .byte 0x1
- .byte 0x78
- .byte 0x1a
- .byte 0x0
- .byte 0x4
- .4byte 1
- .p2align 1
-.LECIE1:
-.LSFDE1:
- .4byte .LEFDE1-.LASFDE1
-.LASFDE1:
- .4byte .LASFDE1-__FRAME_BEGIN__
- .4byte .LFB1
- .4byte .LFE1-.LFB1
- .byte 0x4
- .4byte .LFE1-.LFB1
- .byte 0x4
- .4byte .L1-.LFB1
-.LEFDE1:' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- cat > conftest.lit <<EOF
- 0000 10000000 00000000 017a0001 781a0004 .........z..x...
- 0010 01000000 12000000 18000000 00000000 ................
- 0020 08000000 04080000 0044 .........D
-EOF
-cat > conftest.big <<EOF
- 0000 00000010 00000000 017a0001 781a0004 .........z..x...
- 0010 00000001 00000012 00000018 00000000 ................
- 0020 00000008 04000000 0844 .........D
-EOF
- # If the assembler didn't choke, and we can objdump,
- # and we got the correct data, then succeed.
- # The text in the here-document typically retains its unix-style line
- # endings, while the output of objdump will use host line endings.
- # Therefore, use diff -b for the comparisons.
- if test x$gcc_cv_objdump != x \
- && $gcc_cv_objdump -s -j .eh_frame conftest.o 2>/dev/null \
- | tail -3 > conftest.got \
- && { diff -b conftest.lit conftest.got > /dev/null 2>&1 \
- || diff -b conftest.big conftest.got > /dev/null 2>&1; }
- then
- gcc_cv_as_eh_frame=yes
- elif { ac_try='$gcc_cv_as -o conftest.o --traditional-format /dev/null'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }; then
- gcc_cv_as_eh_frame=buggy
- else
- # Uh oh, what do we do now?
- gcc_cv_as_eh_frame=no
- fi
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_eh_frame" >&5
-$as_echo "$gcc_cv_as_eh_frame" >&6; }
-
-
-if test $gcc_cv_as_eh_frame = buggy; then
-
-$as_echo "#define USE_AS_TRADITIONAL_FORMAT 1" >>confdefs.h
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for section merging support" >&5
-$as_echo_n "checking assembler for section merging support... " >&6; }
-if test "${gcc_cv_as_shf_merge+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_shf_merge=no
- if test $in_tree_gas = yes; then
- if test $in_tree_gas_is_elf = yes \
- && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 12 \) \* 1000 + 0`
- then gcc_cv_as_shf_merge=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo '.section .rodata.str, "aMS", @progbits, 1' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags --fatal-warnings -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_shf_merge=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_shf_merge" >&5
-$as_echo "$gcc_cv_as_shf_merge" >&6; }
-
-if test $gcc_cv_as_shf_merge = no; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for section merging support" >&5
-$as_echo_n "checking assembler for section merging support... " >&6; }
-if test "${gcc_cv_as_shf_merge+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_shf_merge=no
- if test $in_tree_gas = yes; then
- if test $in_tree_gas_is_elf = yes \
- && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 12 \) \* 1000 + 0`
- then gcc_cv_as_shf_merge=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo '.section .rodata.str, "aMS", %progbits, 1' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags --fatal-warnings -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_shf_merge=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_shf_merge" >&5
-$as_echo "$gcc_cv_as_shf_merge" >&6; }
-
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_GAS_SHF_MERGE `if test $gcc_cv_as_shf_merge = yes; then echo 1; else echo 0; fi`
-_ACEOF
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for COMDAT group support (GNU as)" >&5
-$as_echo_n "checking assembler for COMDAT group support (GNU as)... " >&6; }
-if test "${gcc_cv_as_comdat_group+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_comdat_group=no
- if test $in_tree_gas = yes; then
- if test $in_tree_gas_is_elf = yes \
- && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 16 \) \* 1000 + 0`
- then gcc_cv_as_comdat_group=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo '.section .text,"axG",@progbits,.foo,comdat' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags --fatal-warnings -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_comdat_group=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_comdat_group" >&5
-$as_echo "$gcc_cv_as_comdat_group" >&6; }
-
-if test $gcc_cv_as_comdat_group = yes; then
- gcc_cv_as_comdat_group_percent=no
- gcc_cv_as_comdat_group_group=no
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for COMDAT group support (GNU as, %type)" >&5
-$as_echo_n "checking assembler for COMDAT group support (GNU as, %type)... " >&6; }
-if test "${gcc_cv_as_comdat_group_percent+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_comdat_group_percent=no
- if test $in_tree_gas = yes; then
- if test $in_tree_gas_is_elf = yes \
- && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 16 \) \* 1000 + 0`
- then gcc_cv_as_comdat_group_percent=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo '.section .text,"axG",%progbits,.foo,comdat' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags --fatal-warnings -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_comdat_group_percent=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_comdat_group_percent" >&5
-$as_echo "$gcc_cv_as_comdat_group_percent" >&6; }
-
- if test $gcc_cv_as_comdat_group_percent = yes; then
- gcc_cv_as_comdat_group_group=no
- else
- if test -z "${gcc_cv_as_comdat_group_group+set}"; then
- gcc_cv_as_comdat_group_group=no
- fi
- case "${target}" in
- # Sun as uses a completely different syntax.
- *-*-solaris2*)
- case "${target}" in
- sparc*-*-solaris2*)
- conftest_s='
- .group foo,".text%foo",#comdat
- .section ".text%foo", #alloc,#execinstr,#progbits
- .globl foo
- foo:
- '
- ;;
- i?86-*-solaris2* | x86_64-*-solaris2.1[0-9]*)
- conftest_s='
- .group foo,.text%foo,#comdat
- .section .text%foo, "ax", @progbits
- .globl foo
- foo:
- '
- ;;
- esac
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for COMDAT group support (Sun as, .group)" >&5
-$as_echo_n "checking assembler for COMDAT group support (Sun as, .group)... " >&6; }
-if test "${gcc_cv_as_comdat_group_group+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_comdat_group_group=no
- if test x$gcc_cv_as != x; then
- $as_echo "$conftest_s" > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_comdat_group_group=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_comdat_group_group" >&5
-$as_echo "$gcc_cv_as_comdat_group_group" >&6; }
-
- ;;
- esac
- fi
-fi
-if test x"$ld_is_gold" = xyes; then
- comdat_group=yes
-elif test $in_tree_ld = yes ; then
- comdat_group=no
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes; then
- comdat_group=yes
- fi
-elif echo "$ld_ver" | grep GNU > /dev/null; then
- comdat_group=yes
- if test 0"$ld_date" -lt 20050308; then
- if test -n "$ld_date"; then
- # If there was date string, but was earlier than 2005-03-08, fail
- comdat_group=no
- elif test "$ld_vers_major" -lt 2; then
- comdat_group=no
- elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -lt 16; then
- comdat_group=no
- fi
- fi
-else
- case "${target}" in
- *-*-solaris2.1[1-9]*)
- comdat_group=no
- # Sun ld has COMDAT group support since Solaris 9, but it doesn't
- # interoperate with GNU as until Solaris 11 build 130, i.e. ld
- # version 1.688.
- #
- # If using Sun as for COMDAT group as emitted by GCC, one needs at
- # least ld version 1.2267.
- if test "$ld_vers_major" -gt 1; then
- comdat_group=yes
- elif test "x$gas_flag" = xyes && test "$ld_vers_minor" -ge 1688; then
- comdat_group=yes
- elif test "$ld_vers_minor" -ge 2267; then
- comdat_group=yes
- fi
- ;;
- *)
- # Assume linkers other than GNU ld don't support COMDAT group.
- comdat_group=no
- ;;
- esac
-fi
-# Allow overriding the automatic COMDAT group tests above.
-# Check whether --enable-comdat was given.
-if test "${enable_comdat+set}" = set; then :
- enableval=$enable_comdat; comdat_group="$enable_comdat"
-fi
-
-if test $comdat_group = no; then
- gcc_cv_as_comdat_group=no
- gcc_cv_as_comdat_group_percent=no
- gcc_cv_as_comdat_group_group=no
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_COMDAT_GROUP `if test $gcc_cv_as_comdat_group = yes \
- || test $gcc_cv_as_comdat_group_percent = yes \
- || test $gcc_cv_as_comdat_group_group = yes; then echo 1; else echo 0; fi`
-_ACEOF
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for line table discriminator support" >&5
-$as_echo_n "checking assembler for line table discriminator support... " >&6; }
-if test "${gcc_cv_as_discriminator+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_discriminator=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 51`
- then gcc_cv_as_discriminator=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo ' .text
- .file 1 "conf.c"
- .loc 1 1 0 discriminator 1' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_discriminator=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_discriminator" >&5
-$as_echo "$gcc_cv_as_discriminator" >&6; }
-if test $gcc_cv_as_discriminator = yes; then
-
-$as_echo "#define HAVE_GAS_DISCRIMINATOR 1" >>confdefs.h
-
-fi
-
-# Thread-local storage - the check is heavily parameterized.
-conftest_s=
-tls_first_major=
-tls_first_minor=
-tls_as_opt=
-case "$target" in
- alpha*-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-foo: .long 25
- .text
- ldq $27,__tls_get_addr($29) !literal!1
- lda $16,foo($29) !tlsgd!1
- jsr $26,($27),__tls_get_addr !lituse_tlsgd!1
- ldq $27,__tls_get_addr($29) !literal!2
- lda $16,foo($29) !tlsldm!2
- jsr $26,($27),__tls_get_addr !lituse_tlsldm!2
- ldq $1,foo($29) !gotdtprel
- ldah $2,foo($29) !dtprelhi
- lda $3,foo($2) !dtprello
- lda $4,foo($29) !dtprel
- ldq $1,foo($29) !gottprel
- ldah $2,foo($29) !tprelhi
- lda $3,foo($2) !tprello
- lda $4,foo($29) !tprel'
- tls_first_major=2
- tls_first_minor=13
- tls_as_opt=--fatal-warnings
- ;;
- cris-*-*|crisv32-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-x: .long 25
- .text
- move.d x:IE,$r10
- nop'
- tls_first_major=2
- tls_first_minor=20
- tls_as_opt=--fatal-warnings
- ;;
- frv*-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-x: .long 25
- .text
- call #gettlsoff(x)'
- tls_first_major=2
- tls_first_minor=14
- ;;
- hppa*-*-linux*)
- conftest_s='
-t1: .reg %r20
-t2: .reg %r21
-gp: .reg %r19
- .section ".tdata","awT",@progbits
-foo: .long 25
- .text
- .align 4
- addil LT%foo-$tls_gdidx$,gp
- ldo RT%foo-$tls_gdidx$(%r1),%arg0
- b __tls_get_addr
- nop
- addil LT%foo-$tls_ldidx$,gp
- b __tls_get_addr
- ldo RT%foo-$tls_ldidx$(%r1),%arg0
- addil LR%foo-$tls_dtpoff$,%ret0
- ldo RR%foo-$tls_dtpoff$(%r1),%t1
- mfctl %cr27,%t1
- addil LT%foo-$tls_ieoff$,gp
- ldw RT%foo-$tls_ieoff$(%r1),%t2
- add %t1,%t2,%t3
- mfctl %cr27,%t1
- addil LR%foo-$tls_leoff$,%t1
- ldo RR%foo-$tls_leoff$(%r1),%t2'
- tls_first_major=2
- tls_first_minor=15
- tls_as_opt=--fatal-warnings
- ;;
- arm*-*-*)
- conftest_s='
- .section ".tdata","awT",%progbits
-foo: .long 25
- .text
-.word foo(gottpoff)
-.word foo(tpoff)
-.word foo(tlsgd)
-.word foo(tlsldm)
-.word foo(tlsldo)'
- tls_first_major=2
- tls_first_minor=17
- ;;
- i[34567]86-*-* | x86_64-*-solaris2.1[0-9]*)
- case "$target" in
- i[34567]86-*-solaris2.*)
- on_solaris=yes
- tga_func=___tls_get_addr
- ;;
- x86_64-*-solaris2.1[0-9]*)
- on_solaris=yes
- tga_func=__tls_get_addr
- ;;
- *)
- on_solaris=no
- ;;
- esac
- if test x$on_solaris = xyes && test x$gas_flag = xno; then
- conftest_s='
- .section .tdata,"awt",@progbits'
- tls_first_major=0
- tls_first_minor=0
-
-$as_echo "#define TLS_SECTION_ASM_FLAG 't'" >>confdefs.h
-
- else
- conftest_s='
- .section ".tdata","awT",@progbits'
- tls_first_major=2
- tls_first_minor=14
- tls_as_opt="--fatal-warnings"
- fi
- conftest_s="$conftest_s
-foo: .long 25
- .text
- movl %gs:0, %eax
- leal foo@tlsgd(,%ebx,1), %eax
- leal foo@tlsldm(%ebx), %eax
- leal foo@dtpoff(%eax), %edx
- movl foo@gottpoff(%ebx), %eax
- subl foo@gottpoff(%ebx), %eax
- addl foo@gotntpoff(%ebx), %eax
- movl foo@indntpoff, %eax
- movl \$foo@tpoff, %eax
- subl \$foo@tpoff, %eax
- leal foo@ntpoff(%ecx), %eax"
- ;;
- x86_64-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-foo: .long 25
- .text
- movq %fs:0, %rax
- leaq foo@TLSGD(%rip), %rdi
- leaq foo@TLSLD(%rip), %rdi
- leaq foo@DTPOFF(%rax), %rdx
- movq foo@GOTTPOFF(%rip), %rax
- movq $foo@TPOFF, %rax'
- tls_first_major=2
- tls_first_minor=14
- tls_as_opt=--fatal-warnings
- ;;
- ia64-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-foo: data8 25
- .text
- addl r16 = @ltoff(@dtpmod(foo#)), gp
- addl r17 = @ltoff(@dtprel(foo#)), gp
- addl r18 = @ltoff(@tprel(foo#)), gp
- addl r19 = @dtprel(foo#), gp
- adds r21 = @dtprel(foo#), r13
- movl r23 = @dtprel(foo#)
- addl r20 = @tprel(foo#), gp
- adds r22 = @tprel(foo#), r13
- movl r24 = @tprel(foo#)'
- tls_first_major=2
- tls_first_minor=13
- tls_as_opt=--fatal-warnings
- ;;
- microblaze*-*-*)
- conftest_s='
- .section .tdata,"awT",@progbits
-x:
- .word 2
- .text
- addik r5,r20,x@TLSGD
- addik r5,r20,x@TLSLDM'
- tls_first_major=2
- tls_first_minor=20
- tls_as_opt='--fatal-warnings'
- ;;
- mips*-*-*)
- conftest_s='
- .section .tdata,"awT",@progbits
-x:
- .word 2
- .text
- addiu $4, $28, %tlsgd(x)
- addiu $4, $28, %tlsldm(x)
- lui $4, %dtprel_hi(x)
- addiu $4, $4, %dtprel_lo(x)
- lw $4, %gottprel(x)($28)
- lui $4, %tprel_hi(x)
- addiu $4, $4, %tprel_lo(x)'
- tls_first_major=2
- 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'
- ;;
- aarch64*-*-*)
- conftest_s='
- .section ".tdata","awT",%progbits
-foo: .long 25
- .text
- adrp x0, :tlsgd:x
- add x0, x0, #:tlsgd_lo12:x
- bl __tls_get_addr
- nop'
- tls_first_major=2
- tls_first_minor=20
- tls_as_opt='--fatal-warnings'
- ;;
- powerpc-ibm-aix*)
- conftest_s='
- .extern __get_tpointer
- .toc
-LC..1:
- .tc a[TC],a[TL]@le
- .csect .text[PR]
-.tlstest:
- lwz 9,LC..1(2)
- bla __get_tpointer
- lwzx 3,9,3
- .globl a
- .csect a[TL],4
-a:
- .space 4'
- tls_first_major=0
- tls_first_minor=0
- ;;
- powerpc-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
- .align 2
-ld0: .space 4
-ld1: .space 4
-x1: .space 4
-x2: .space 4
-x3: .space 4
- .text
- addi 3,31,ld0@got@tlsgd
- bl __tls_get_addr
- addi 3,31,x1@got@tlsld
- bl __tls_get_addr
- addi 9,3,x1@dtprel
- addis 9,3,x2@dtprel@ha
- addi 9,9,x2@dtprel@l
- lwz 9,x3@got@tprel(31)
- add 9,9,x@tls
- addi 9,2,x1@tprel
- addis 9,2,x2@tprel@ha
- addi 9,9,x2@tprel@l'
- tls_first_major=2
- tls_first_minor=14
- tls_as_opt="-a32 --fatal-warnings"
- ;;
- powerpc64-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
- .align 3
-ld0: .space 8
-ld1: .space 8
-x1: .space 8
-x2: .space 8
-x3: .space 8
- .text
- addi 3,2,ld0@got@tlsgd
- bl .__tls_get_addr
- nop
- addi 3,2,ld1@toc
- bl .__tls_get_addr
- nop
- addi 3,2,x1@got@tlsld
- bl .__tls_get_addr
- nop
- addi 9,3,x1@dtprel
- bl .__tls_get_addr
- nop
- addis 9,3,x2@dtprel@ha
- addi 9,9,x2@dtprel@l
- bl .__tls_get_addr
- nop
- ld 9,x3@got@dtprel(2)
- add 9,9,3
- bl .__tls_get_addr
- nop'
- tls_first_major=2
- tls_first_minor=14
- tls_as_opt="-a64 --fatal-warnings"
- ;;
- s390-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-foo: .long 25
- .text
- .long foo@TLSGD
- .long foo@TLSLDM
- .long foo@DTPOFF
- .long foo@NTPOFF
- .long foo@GOTNTPOFF
- .long foo@INDNTPOFF
- l %r1,foo@GOTNTPOFF(%r12)
- l %r1,0(%r1):tls_load:foo
- bas %r14,0(%r1,%r13):tls_gdcall:foo
- bas %r14,0(%r1,%r13):tls_ldcall:foo'
- tls_first_major=2
- tls_first_minor=14
- tls_as_opt="-m31 --fatal-warnings"
- ;;
- s390x-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-foo: .long 25
- .text
- .quad foo@TLSGD
- .quad foo@TLSLDM
- .quad foo@DTPOFF
- .quad foo@NTPOFF
- .quad foo@GOTNTPOFF
- lg %r1,foo@GOTNTPOFF(%r12)
- larl %r1,foo@INDNTPOFF
- brasl %r14,__tls_get_offset@PLT:tls_gdcall:foo
- brasl %r14,__tls_get_offset@PLT:tls_ldcall:foo'
- tls_first_major=2
- tls_first_minor=14
- tls_as_opt="-m64 -Aesame --fatal-warnings"
- ;;
- sh-*-* | sh[34]-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-foo: .long 25
- .text
- .long foo@TLSGD
- .long foo@TLSLDM
- .long foo@DTPOFF
- .long foo@GOTTPOFF
- .long foo@TPOFF'
- tls_first_major=2
- tls_first_minor=13
- tls_as_opt=--fatal-warnings
- ;;
- sparc*-*-*)
- case "$target" in
- sparc*-sun-solaris2.*)
- on_solaris=yes
- tga_func=__tls_get_addr
- ;;
- *)
- on_solaris=no
- ;;
- esac
- if test x$on_solaris = xyes && test x$gas_flag = xno; then
- conftest_s='
- .section ".tdata",#alloc,#write,#tls'
- tls_first_major=0
- tls_first_minor=0
- else
- conftest_s='
- .section ".tdata","awT",@progbits'
- tls_first_major=2
- tls_first_minor=14
- tls_as_opt="-32 --fatal-warnings"
- fi
- conftest_s="$conftest_s
-foo: .long 25
- .text
- sethi %tgd_hi22(foo), %o0
- add %o0, %tgd_lo10(foo), %o1
- add %l7, %o1, %o0, %tgd_add(foo)
- call __tls_get_addr, %tgd_call(foo)
- sethi %tldm_hi22(foo), %l1
- add %l1, %tldm_lo10(foo), %l2
- add %l7, %l2, %o0, %tldm_add(foo)
- call __tls_get_addr, %tldm_call(foo)
- sethi %tldo_hix22(foo), %l3
- xor %l3, %tldo_lox10(foo), %l4
- add %o0, %l4, %l5, %tldo_add(foo)
- sethi %tie_hi22(foo), %o3
- add %o3, %tie_lo10(foo), %o3
- ld [%l7 + %o3], %o2, %tie_ld(foo)
- add %g7, %o2, %o4, %tie_add(foo)
- sethi %tle_hix22(foo), %l1
- xor %l1, %tle_lox10(foo), %o5
- ld [%g7 + %o5], %o1"
- ;;
- tilepro*-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-foo: .long 25
- .text
- addli r0, zero, tls_gd(foo)
- auli r0, zero, tls_gd_ha16(foo)
- addli r0, r0, tls_gd_lo16(foo)
- jal __tls_get_addr
- addli r0, zero, tls_ie(foo)
- auli r0, r0, tls_ie_ha16(foo)
- addli r0, r0, tls_ie_lo16(foo)'
- tls_first_major=2
- tls_first_minor=22
- tls_as_opt="--fatal-warnings"
- ;;
- tilegx*-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-foo: .long 25
- .text
- shl16insli r0, zero, hw0_last_tls_gd(foo)
- shl16insli r0, zero, hw1_last_tls_gd(foo)
- shl16insli r0, r0, hw0_tls_gd(foo)
- jal __tls_get_addr
- shl16insli r0, zero, hw1_last_tls_ie(foo)
- shl16insli r0, r0, hw0_tls_ie(foo)'
- tls_first_major=2
- tls_first_minor=22
- tls_as_opt="--fatal-warnings"
- ;;
- xtensa*-*-*)
- conftest_s='
- .section ".tdata","awT",@progbits
-foo: .long 25
- .text
- movi a8, foo@TLSFUNC
- movi a10, foo@TLSARG
- callx8.tls a8, foo@TLSCALL'
- tls_first_major=2
- tls_first_minor=19
- ;;
-esac
-set_have_as_tls=no
-if test "x$enable_tls" = xno ; then
- : # TLS explicitly disabled.
-elif test "x$enable_tls" = xyes ; then
- set_have_as_tls=yes # TLS explicitly enabled.
-elif test -z "$tls_first_major"; then
- : # If we don't have a check, assume no support.
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for thread-local storage support" >&5
-$as_echo_n "checking assembler for thread-local storage support... " >&6; }
-if test "${gcc_cv_as_tls+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_tls=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( $tls_first_major \* 1000 \) + $tls_first_minor \) \* 1000 + 0`
- then gcc_cv_as_tls=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo "$conftest_s" > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags $tls_as_opt -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_tls=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_tls" >&5
-$as_echo "$gcc_cv_as_tls" >&6; }
-if test $gcc_cv_as_tls = yes; then
- set_have_as_tls=yes
-fi
-fi
-case "$target" in
- # TLS was introduced in the Solaris 9 FCS release. Support for GNU-style
- # TLS on x86 was only introduced in Solaris 9 4/04, replacing the earlier
- # Sun style that Sun ld and GCC don't support any longer.
- *-*-solaris2.*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker and ld.so.1 TLS support" >&5
-$as_echo_n "checking linker and ld.so.1 TLS support... " >&6; }
- ld_tls_support=no
- # Check ld and ld.so.1 TLS support.
- if echo "$ld_ver" | grep GNU > /dev/null; then
- # Assume all interesting versions of GNU ld have TLS support.
- # FIXME: still need ld.so.1 support, i.e. ld version checks below.
- ld_tls_support=yes
- else
- case "$target" in
- # Solaris 9/x86 ld has GNU style TLS support since version 1.374.
- i?86-*-solaris2.9)
- min_tls_ld_vers_minor=374
- ;;
- # Solaris 9/SPARC and Solaris 10+ ld have TLS support since FCS.
- sparc*-*-solaris2.9 | *-*-solaris2.1[0-9]*)
- min_tls_ld_vers_minor=343
- ;;
- esac
- if test "$ld_vers_major" -gt 1 || \
- test "$ld_vers_minor" -ge "$min_tls_ld_vers_minor"; then
- ld_tls_support=yes
- else
- set_have_as_tls=no
- fi
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_tls_support" >&5
-$as_echo "$ld_tls_support" >&6; }
-
- save_LIBS="$LIBS"
- save_LDFLAGS="$LDFLAGS"
- LIBS=
- LDFLAGS=
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking library containing $tga_func" >&5
-$as_echo_n "checking library containing $tga_func... " >&6; }
- # Before Solaris 10, __tls_get_addr (SPARC/x64) resp. ___tls_get_addr
- # (32-bit x86) only lived in libthread, so check for that. Keep
- # set_have_as_tls if found, disable if not.
- as_ac_Search=`$as_echo "ac_cv_search_$tga_func" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing $tga_func" >&5
-$as_echo_n "checking for library containing $tga_func... " >&6; }
-if { as_var=$as_ac_Search; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $tga_func ();
-int
-main ()
-{
-return $tga_func ();
- ;
- return 0;
-}
-_ACEOF
-for ac_lib in '' thread; do
- if test -z "$ac_lib"; then
- ac_res="none required"
- else
- ac_res=-l$ac_lib
- LIBS="-l$ac_lib $ac_func_search_save_LIBS"
- fi
- if ac_fn_c_try_link "$LINENO"; then :
- eval "$as_ac_Search=\$ac_res"
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext
- if { as_var=$as_ac_Search; eval "test \"\${$as_var+set}\" = set"; }; then :
- break
-fi
-done
-if { as_var=$as_ac_Search; eval "test \"\${$as_var+set}\" = set"; }; then :
-
-else
- eval "$as_ac_Search=no"
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-eval ac_res=\$$as_ac_Search
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-eval ac_res=\$$as_ac_Search
-if test "$ac_res" != no; then :
- test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
-else
- set_have_as_tls=no
-fi
-
- # Clear LIBS if we cannot support TLS.
- if test $set_have_as_tls = no; then
- LIBS=
- fi
- # Always define LIB_TLS_SPEC, even without TLS support.
-
-cat >>confdefs.h <<_ACEOF
-#define LIB_TLS_SPEC "$LIBS"
-_ACEOF
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBS" >&5
-$as_echo "$LIBS" >&6; }
-
- LIBS="$save_LIBS"
- LDFLAGS="$save_LDFLAGS"
- ;;
-esac
-if test $set_have_as_tls = yes ; then
-
-$as_echo "#define HAVE_AS_TLS 1" >>confdefs.h
-
-fi
-
-# Target-specific assembler checks.
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker -Bstatic/-Bdynamic option" >&5
-$as_echo_n "checking linker -Bstatic/-Bdynamic option... " >&6; }
-gcc_cv_ld_static_dynamic=no
-gcc_cv_ld_static_option='-Bstatic'
-gcc_cv_ld_dynamic_option='-Bdynamic'
-if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 10 -o "$gcc_cv_gld_major_version" -gt 2; then
- gcc_cv_ld_static_dynamic=yes
- fi
-elif test x$gcc_cv_ld != x; then
- # Check if linker supports -Bstatic/-Bdynamic option
- if $gcc_cv_ld --help 2>/dev/null | grep -- -Bstatic > /dev/null \
- && $gcc_cv_ld --help 2>/dev/null | grep -- -Bdynamic > /dev/null; then
- gcc_cv_ld_static_dynamic=yes
- else
- case "$target" in
- # AIX ld uses -b flags
- *-*-aix4.[23]* | *-*-aix[5-9]*)
- gcc_cv_ld_static_dynamic=yes
- gcc_cv_ld_static_option="-bstatic"
- gcc_cv_ld_dynamic_option="-bdynamic"
- ;;
- # HP-UX ld uses -a flags to select between shared and archive.
- *-*-hpux*)
- if test x"$gnu_ld" = xno; then
- gcc_cv_ld_static_dynamic=yes
- gcc_cv_ld_static_option="-aarchive_shared"
- gcc_cv_ld_dynamic_option="-adefault"
- fi
- ;;
- # Solaris 2 ld always supports -Bstatic/-Bdynamic.
- *-*-solaris2*)
- gcc_cv_ld_static_dynamic=yes
- ;;
- esac
- fi
-fi
-if test x"$gcc_cv_ld_static_dynamic" = xyes; then
-
-$as_echo "#define HAVE_LD_STATIC_DYNAMIC 1" >>confdefs.h
-
-
-cat >>confdefs.h <<_ACEOF
-#define LD_STATIC_OPTION "$gcc_cv_ld_static_option"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define LD_DYNAMIC_OPTION "$gcc_cv_ld_dynamic_option"
-_ACEOF
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_static_dynamic" >&5
-$as_echo "$gcc_cv_ld_static_dynamic" >&6; }
-
-if test x"$demangler_in_ld" = xyes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker --demangle support" >&5
-$as_echo_n "checking linker --demangle support... " >&6; }
- gcc_cv_ld_demangle=no
- if test $in_tree_ld = yes; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 14 -o "$gcc_cv_gld_major_version" -gt 2; then \
- gcc_cv_ld_demangle=yes
- fi
- elif test x$gcc_cv_ld != x -a x"$gnu_ld" = xyes; then
- # Check if the GNU linker supports --demangle option
- if $gcc_cv_ld --help 2>/dev/null | grep no-demangle > /dev/null; then
- gcc_cv_ld_demangle=yes
- fi
- fi
- if test x"$gcc_cv_ld_demangle" = xyes; then
-
-$as_echo "#define HAVE_LD_DEMANGLE 1" >>confdefs.h
-
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_demangle" >&5
-$as_echo "$gcc_cv_ld_demangle" >&6; }
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker plugin support" >&5
-$as_echo_n "checking linker plugin support... " >&6; }
-gcc_cv_lto_plugin=0
-if test -f liblto_plugin.la; then
- save_ld_ver="$ld_ver"
- save_ld_vers_major="$ld_vers_major"
- save_ld_vers_minor="$ld_vers_minor"
- save_ld_is_gold="$ld_is_gold"
-
- ld_is_gold=no
-
- if test $in_tree_ld = yes -a x"$ORIGINAL_PLUGIN_LD_FOR_TARGET" = x"$gcc_cv_ld"; then
- ld_ver="GNU ld"
- # FIXME: ld_is_gold?
- ld_vers_major="$gcc_cv_gld_major_version"
- ld_vers_minor="$gcc_cv_gld_minor_version"
- else
- # Determine plugin linker version.
- # FIXME: Partial duplicate from above, generalize.
- ld_ver=`$ORIGINAL_PLUGIN_LD_FOR_TARGET --version 2>/dev/null | sed 1q`
- if echo "$ld_ver" | grep GNU > /dev/null; then
- if echo "$ld_ver" | grep "GNU gold" > /dev/null; then
- ld_is_gold=yes
- ld_vers=`echo $ld_ver | sed -n \
- -e 's,^[^)]*[ ]\([0-9][0-9]*\.[0-9][0-9]*[^)]*\)) .*$,\1,p'`
- else
- ld_vers=`echo $ld_ver | sed -n \
- -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*.*\)$,\1,p'`
- fi
- ld_vers_major=`expr "$ld_vers" : '\([0-9]*\)'`
- ld_vers_minor=`expr "$ld_vers" : '[0-9]*\.\([0-9]*\)'`
- fi
- fi
-
- # Determine plugin support.
- if echo "$ld_ver" | grep GNU > /dev/null; then
- # Require GNU ld or gold 2.21+ for plugin support by default.
- if test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -ge 21; then
- gcc_cv_lto_plugin=2
- # Allow -fuse-linker-plugin to enable plugin support in GNU gold 2.20.
- elif test "$ld_is_gold" = yes -a "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -eq 20; then
- gcc_cv_lto_plugin=1
- fi
- fi
-
- ld_ver="$save_ld_ver"
- ld_vers_major="$save_ld_vers_major"
- ld_vers_minor="$save_ld_vers_minor"
- ld_is_gold="$save_ld_is_gold"
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_LTO_PLUGIN $gcc_cv_lto_plugin
-_ACEOF
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_lto_plugin" >&5
-$as_echo "$gcc_cv_lto_plugin" >&6; }
-
-case "$target" in
- # All TARGET_ABI_OSF targets.
- alpha*-*-linux* | alpha*-*-*bsd*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for explicit relocation support" >&5
-$as_echo_n "checking assembler for explicit relocation support... " >&6; }
-if test "${gcc_cv_as_alpha_explicit_relocs+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_alpha_explicit_relocs=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 12 \) \* 1000 + 0`
- then gcc_cv_as_alpha_explicit_relocs=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo ' .set nomacro
- .text
- extbl $3, $2, $3 !lituse_bytoff!1
- ldq $2, a($29) !literal!1
- ldq $4, b($29) !literal!2
- ldq_u $3, 0($2) !lituse_base!1
- ldq $27, f($29) !literal!5
- jsr $26, ($27), f !lituse_jsr!5
- ldah $29, 0($26) !gpdisp!3
- lda $0, c($29) !gprel
- ldah $1, d($29) !gprelhigh
- lda $1, d($1) !gprellow
- lda $29, 0($29) !gpdisp!3' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_alpha_explicit_relocs=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_alpha_explicit_relocs" >&5
-$as_echo "$gcc_cv_as_alpha_explicit_relocs" >&6; }
-if test $gcc_cv_as_alpha_explicit_relocs = yes; then
-
-$as_echo "#define HAVE_AS_EXPLICIT_RELOCS 1" >>confdefs.h
-
-fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for jsrdirect relocation support" >&5
-$as_echo_n "checking assembler for jsrdirect relocation support... " >&6; }
-if test "${gcc_cv_as_alpha_jsrdirect_relocs+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_alpha_jsrdirect_relocs=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 16 \) \* 1000 + 90`
- then gcc_cv_as_alpha_jsrdirect_relocs=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo ' .set nomacro
- .text
- ldq $27, a($29) !literal!1
- jsr $26, ($27), a !lituse_jsrdirect!1' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_alpha_jsrdirect_relocs=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_alpha_jsrdirect_relocs" >&5
-$as_echo "$gcc_cv_as_alpha_jsrdirect_relocs" >&6; }
-if test $gcc_cv_as_alpha_jsrdirect_relocs = yes; then
-
-$as_echo "#define HAVE_AS_JSRDIRECT_RELOCS 1" >>confdefs.h
-
-fi
- ;;
-
- cris-*-*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for -no-mul-bug-abort option" >&5
-$as_echo_n "checking assembler for -no-mul-bug-abort option... " >&6; }
-if test "${gcc_cv_as_cris_no_mul_bug+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_cris_no_mul_bug=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 15 \) \* 1000 + 91`
- then gcc_cv_as_cris_no_mul_bug=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo '.text' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -no-mul-bug-abort -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_cris_no_mul_bug=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_cris_no_mul_bug" >&5
-$as_echo "$gcc_cv_as_cris_no_mul_bug" >&6; }
-if test $gcc_cv_as_cris_no_mul_bug = yes; then
-
-$as_echo "#define HAVE_AS_NO_MUL_BUG_ABORT_OPTION 1" >>confdefs.h
-
-fi
- ;;
-
- sparc*-*-*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .register" >&5
-$as_echo_n "checking assembler for .register... " >&6; }
-if test "${gcc_cv_as_sparc_register_op+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_sparc_register_op=no
- if test x$gcc_cv_as != x; then
- $as_echo '.register %g2, #scratch' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_sparc_register_op=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_sparc_register_op" >&5
-$as_echo "$gcc_cv_as_sparc_register_op" >&6; }
-if test $gcc_cv_as_sparc_register_op = yes; then
-
-$as_echo "#define HAVE_AS_REGISTER_PSEUDO_OP 1" >>confdefs.h
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for #nobits" >&5
-$as_echo_n "checking assembler for #nobits... " >&6; }
-if test "${gcc_cv_as_sparc_nobits+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_sparc_nobits=no
- if test x$gcc_cv_as != x; then
- $as_echo '.section "nobits",#alloc,#write,#nobits
- .section "progbits",#alloc,#write,#progbits' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_sparc_nobits=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_sparc_nobits" >&5
-$as_echo "$gcc_cv_as_sparc_nobits" >&6; }
-
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_AS_SPARC_NOBITS `if test $gcc_cv_as_sparc_nobits = yes; then echo 1; else echo 0; fi`
-_ACEOF
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for -relax option" >&5
-$as_echo_n "checking assembler for -relax option... " >&6; }
-if test "${gcc_cv_as_sparc_relax+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_sparc_relax=no
- if test x$gcc_cv_as != x; then
- $as_echo '.text' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -relax -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_sparc_relax=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_sparc_relax" >&5
-$as_echo "$gcc_cv_as_sparc_relax" >&6; }
-if test $gcc_cv_as_sparc_relax = yes; then
-
-$as_echo "#define HAVE_AS_RELAX_OPTION 1" >>confdefs.h
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for GOTDATA_OP relocs" >&5
-$as_echo_n "checking assembler for GOTDATA_OP relocs... " >&6; }
-if test "${gcc_cv_as_sparc_gotdata_op+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_sparc_gotdata_op=no
- if test x$gcc_cv_as != x; then
- $as_echo '.text
-.align 4
-foo:
- nop
-bar:
- sethi %gdop_hix22(foo), %g1
- xor %g1, %gdop_lox10(foo), %g1
- ld [%l7 + %g1], %g2, %gdop(foo)' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -K PIC -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- if test x$gcc_cv_ld != x \
- && $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1; then
- if test x$gcc_cv_objdump != x; then
- if $gcc_cv_objdump -s -j .text conftest 2> /dev/null \
- | grep ' 03000004 82186004 c405c001'> /dev/null 2>&1; then
- gcc_cv_as_sparc_gotdata_op=no
- else
- gcc_cv_as_sparc_gotdata_op=yes
- fi
- fi
- fi
- rm -f conftest
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_sparc_gotdata_op" >&5
-$as_echo "$gcc_cv_as_sparc_gotdata_op" >&6; }
-if test $gcc_cv_as_sparc_gotdata_op = yes; then
-
-$as_echo "#define HAVE_AS_SPARC_GOTDATA_OP 1" >>confdefs.h
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for unaligned pcrel relocs" >&5
-$as_echo_n "checking assembler for unaligned pcrel relocs... " >&6; }
-if test "${gcc_cv_as_sparc_ua_pcrel+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_sparc_ua_pcrel=no
- if test x$gcc_cv_as != x; then
- $as_echo '.text
-foo:
- nop
-.data
-.align 4
-.byte 0
-.uaword %r_disp32(foo)' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -K PIC -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- if test x$gcc_cv_ld != x \
- && $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1; then
- gcc_cv_as_sparc_ua_pcrel=yes
- fi
- rm -f conftest
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_sparc_ua_pcrel" >&5
-$as_echo "$gcc_cv_as_sparc_ua_pcrel" >&6; }
-if test $gcc_cv_as_sparc_ua_pcrel = yes; then
-
-$as_echo "#define HAVE_AS_SPARC_UA_PCREL 1" >>confdefs.h
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for unaligned pcrel relocs against hidden symbols" >&5
-$as_echo_n "checking assembler for unaligned pcrel relocs against hidden symbols... " >&6; }
-if test "${gcc_cv_as_sparc_ua_pcrel_hidden+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_sparc_ua_pcrel_hidden=no
- if test x$gcc_cv_as != x; then
- $as_echo '.data
-.align 4
-.byte 0x31
-.uaword %r_disp32(foo)
-.byte 0x32, 0x33, 0x34
-.global foo
-.hidden foo
-foo:
-.skip 4' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -K PIC -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- if test x$gcc_cv_ld != x && test x$gcc_cv_objdump != x \
- && $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1 \
- && $gcc_cv_objdump -s -j .data conftest 2> /dev/null \
- | grep ' 31000000 07323334' > /dev/null 2>&1; then
- if $gcc_cv_objdump -R conftest 2> /dev/null \
- | grep 'DISP32' > /dev/null 2>&1; then
- :
- else
- gcc_cv_as_sparc_ua_pcrel_hidden=yes
- fi
- fi
- rm -f conftest
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_sparc_ua_pcrel_hidden" >&5
-$as_echo "$gcc_cv_as_sparc_ua_pcrel_hidden" >&6; }
-if test $gcc_cv_as_sparc_ua_pcrel_hidden = yes; then
-
-$as_echo "#define HAVE_AS_SPARC_UA_PCREL_HIDDEN 1" >>confdefs.h
-
-fi
-
-fi # unaligned pcrel relocs
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for offsetable %lo()" >&5
-$as_echo_n "checking assembler for offsetable %lo()... " >&6; }
-if test "${gcc_cv_as_sparc_offsetable_lo10+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_sparc_offsetable_lo10=no
- if test x$gcc_cv_as != x; then
- $as_echo '.text
- or %g1, %lo(ab) + 12, %g1
- or %g1, %lo(ab + 12), %g1' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -xarch=v9 -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- if test x$gcc_cv_objdump != x \
- && $gcc_cv_objdump -s -j .text conftest.o 2> /dev/null \
- | grep ' 82106000 82106000' > /dev/null 2>&1; then
- gcc_cv_as_sparc_offsetable_lo10=yes
- fi
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_sparc_offsetable_lo10" >&5
-$as_echo "$gcc_cv_as_sparc_offsetable_lo10" >&6; }
-if test $gcc_cv_as_sparc_offsetable_lo10 = yes; then
-
-$as_echo "#define HAVE_AS_OFFSETABLE_LO10 1" >>confdefs.h
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for FMAF, HPC, and VIS 3.0 instructions" >&5
-$as_echo_n "checking assembler for FMAF, HPC, and VIS 3.0 instructions... " >&6; }
-if test "${gcc_cv_as_sparc_fmaf+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_sparc_fmaf=no
- if test x$gcc_cv_as != x; then
- $as_echo '.text
- .register %g2, #scratch
- .register %g3, #scratch
- .align 4
- fmaddd %f0, %f2, %f4, %f6
- addxccc %g1, %g2, %g3
- fsrl32 %f2, %f4, %f8
- fnaddd %f10, %f12, %f14' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -xarch=v9d -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_sparc_fmaf=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_sparc_fmaf" >&5
-$as_echo "$gcc_cv_as_sparc_fmaf" >&6; }
-if test $gcc_cv_as_sparc_fmaf = yes; then
-
-$as_echo "#define HAVE_AS_FMAF_HPC_VIS3 1" >>confdefs.h
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for SPARC4 instructions" >&5
-$as_echo_n "checking assembler for SPARC4 instructions... " >&6; }
-if test "${gcc_cv_as_sparc_sparc4+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_sparc_sparc4=no
- if test x$gcc_cv_as != x; then
- $as_echo '.text
- .register %g2, #scratch
- .register %g3, #scratch
- .align 4
- cxbe %g2, %g3, 1f
-1: cwbneg %g2, %g3, 1f
-1: sha1
- md5
- aes_kexpand0 %f4, %f6, %f8
- des_round %f38, %f40, %f42, %f44
- camellia_f %f54, %f56, %f58, %f60
- kasumi_fi_xor %f46, %f48, %f50, %f52' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -xarch=sparc4 -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_sparc_sparc4=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_sparc_sparc4" >&5
-$as_echo "$gcc_cv_as_sparc_sparc4" >&6; }
-if test $gcc_cv_as_sparc_sparc4 = yes; then
-
-$as_echo "#define HAVE_AS_SPARC4 1" >>confdefs.h
-
-fi
- ;;
-
- i[34567]86-*-* | x86_64-*-*)
- case $target_os in
- cygwin*)
- # Full C++ conformance when using a shared libstdc++-v3 requires some
- # support from the Cygwin DLL, which in more recent versions exports
- # wrappers to aid in interposing and redirecting operators new, delete,
- # etc., as per n2800 #17.6.4.6 [replacement.functions]. Check if we
- # are configuring for a version of Cygwin that exports the wrappers.
- if test x$host = x$target; then
- ac_fn_c_check_func "$LINENO" "__wrap__Znaj" "ac_cv_func___wrap__Znaj"
-if test "x$ac_cv_func___wrap__Znaj" = x""yes; then :
- gcc_ac_cygwin_dll_wrappers=yes
-else
- gcc_ac_cygwin_dll_wrappers=no
-fi
-
- else
- # Can't check presence of libc functions during cross-compile, so
- # we just have to assume we're building for an up-to-date target.
- gcc_ac_cygwin_dll_wrappers=yes
- fi
-
-cat >>confdefs.h <<_ACEOF
-#define USE_CYGWIN_LIBSTDCXX_WRAPPERS `if test $gcc_ac_cygwin_dll_wrappers = yes; then echo 1; else echo 0; fi`
-_ACEOF
-
- esac
- case $target_os in
- cygwin* | pe | mingw32* | interix*)
- # Recent binutils allows the three-operand form of ".comm" on PE. This
- # definition is used unconditionally to initialise the default state of
- # the target option variable that governs usage of the feature.
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .comm with alignment" >&5
-$as_echo_n "checking assembler for .comm with alignment... " >&6; }
-if test "${gcc_cv_as_comm_has_align+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_comm_has_align=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 52`
- then gcc_cv_as_comm_has_align=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo '.comm foo,1,32' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_comm_has_align=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_comm_has_align" >&5
-$as_echo "$gcc_cv_as_comm_has_align" >&6; }
-
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_GAS_ALIGNED_COMM `if test $gcc_cv_as_comm_has_align = yes; then echo 1; else echo 0; fi`
-_ACEOF
-
- # Used for DWARF 2 in PE
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .secrel32 relocs" >&5
-$as_echo_n "checking assembler for .secrel32 relocs... " >&6; }
-if test "${gcc_cv_as_ix86_pe_secrel32+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_ix86_pe_secrel32=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 15 \) \* 1000 + 91`
- then gcc_cv_as_ix86_pe_secrel32=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo '.text
-foo: nop
-.data
- .secrel32 foo' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- if test x$gcc_cv_ld != x \
- && $gcc_cv_ld -o conftest conftest.o > /dev/null 2>&1; then
- gcc_cv_as_ix86_pe_secrel32=yes
- fi
- rm -f conftest
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_ix86_pe_secrel32" >&5
-$as_echo "$gcc_cv_as_ix86_pe_secrel32" >&6; }
-if test $gcc_cv_as_ix86_pe_secrel32 = yes; then
-
-$as_echo "#define HAVE_GAS_PE_SECREL32_RELOC 1" >>confdefs.h
-
-fi
- # Test if the assembler supports the extended form of the .section
- # directive that specifies section alignment. LTO support uses this,
- # but normally only after installation, so we warn but don't fail the
- # configure if LTO is enabled but the assembler does not support it.
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .section with alignment" >&5
-$as_echo_n "checking assembler for .section with alignment... " >&6; }
-if test "${gcc_cv_as_section_has_align+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_section_has_align=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 20 \) \* 1000 + 1`
- then gcc_cv_as_section_has_align=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo '.section lto_test,"dr0"' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -fatal-warnings -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_section_has_align=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_section_has_align" >&5
-$as_echo "$gcc_cv_as_section_has_align" >&6; }
-
- if test x$gcc_cv_as_section_has_align != xyes; then
- case ",$enable_languages," in
- *,lto,*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: LTO for $target requires binutils >= 2.20.1, but version found appears insufficient; LTO will not work until binutils is upgraded." >&5
-$as_echo "$as_me: WARNING: LTO for $target requires binutils >= 2.20.1, but version found appears insufficient; LTO will not work until binutils is upgraded." >&2;}
- ;;
- esac
- fi
- # Test if the assembler supports the section flag 'e' for specifying
- # an excluded section.
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .section with e" >&5
-$as_echo_n "checking assembler for .section with e... " >&6; }
-if test "${gcc_cv_as_section_has_e+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_section_has_e=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 22 \) \* 1000 + 51`
- then gcc_cv_as_section_has_e=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo '.section foo1,"e"
-.byte 0,0,0,0' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_section_has_e=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_section_has_e" >&5
-$as_echo "$gcc_cv_as_section_has_e" >&6; }
-
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_GAS_SECTION_EXCLUDE `if test $gcc_cv_as_section_has_e = yes; then echo 1; else echo 0; fi`
-_ACEOF
-
- ;;
- esac
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for filds and fists mnemonics" >&5
-$as_echo_n "checking assembler for filds and fists mnemonics... " >&6; }
-if test "${gcc_cv_as_ix86_filds+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_ix86_filds=no
- if test x$gcc_cv_as != x; then
- $as_echo 'filds mem; fists mem' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_ix86_filds=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_ix86_filds" >&5
-$as_echo "$gcc_cv_as_ix86_filds" >&6; }
-if test $gcc_cv_as_ix86_filds = yes; then
-
-$as_echo "#define HAVE_AS_IX86_FILDS 1" >>confdefs.h
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for fildq and fistpq mnemonics" >&5
-$as_echo_n "checking assembler for fildq and fistpq mnemonics... " >&6; }
-if test "${gcc_cv_as_ix86_fildq+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_ix86_fildq=no
- if test x$gcc_cv_as != x; then
- $as_echo 'fildq mem; fistpq mem' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_ix86_fildq=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_ix86_fildq" >&5
-$as_echo "$gcc_cv_as_ix86_fildq" >&6; }
-if test $gcc_cv_as_ix86_fildq = yes; then
-
-$as_echo "#define HAVE_AS_IX86_FILDQ 1" >>confdefs.h
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for cmov syntax" >&5
-$as_echo_n "checking assembler for cmov syntax... " >&6; }
-if test "${gcc_cv_as_ix86_cmov_sun_syntax+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_ix86_cmov_sun_syntax=no
- if test x$gcc_cv_as != x; then
- $as_echo 'cmovl.l %edx, %eax' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_ix86_cmov_sun_syntax=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_ix86_cmov_sun_syntax" >&5
-$as_echo "$gcc_cv_as_ix86_cmov_sun_syntax" >&6; }
-if test $gcc_cv_as_ix86_cmov_sun_syntax = yes; then
-
-$as_echo "#define HAVE_AS_IX86_CMOV_SUN_SYNTAX 1" >>confdefs.h
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for ffreep mnemonic" >&5
-$as_echo_n "checking assembler for ffreep mnemonic... " >&6; }
-if test "${gcc_cv_as_ix86_ffreep+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_ix86_ffreep=no
- if test x$gcc_cv_as != x; then
- $as_echo 'ffreep %st(1)' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_ix86_ffreep=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_ix86_ffreep" >&5
-$as_echo "$gcc_cv_as_ix86_ffreep" >&6; }
-if test $gcc_cv_as_ix86_ffreep = yes; then
-
-$as_echo "#define HAVE_AS_IX86_FFREEP 1" >>confdefs.h
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .quad directive" >&5
-$as_echo_n "checking assembler for .quad directive... " >&6; }
-if test "${gcc_cv_as_ix86_quad+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_ix86_quad=no
- if test x$gcc_cv_as != x; then
- $as_echo '.quad 0' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_ix86_quad=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_ix86_quad" >&5
-$as_echo "$gcc_cv_as_ix86_quad" >&6; }
-if test $gcc_cv_as_ix86_quad = yes; then
-
-$as_echo "#define HAVE_AS_IX86_QUAD 1" >>confdefs.h
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for sahf mnemonic" >&5
-$as_echo_n "checking assembler for sahf mnemonic... " >&6; }
-if test "${gcc_cv_as_ix86_sahf+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_ix86_sahf=no
- if test x$gcc_cv_as != x; then
- $as_echo '.code64
- sahf' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_ix86_sahf=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_ix86_sahf" >&5
-$as_echo "$gcc_cv_as_ix86_sahf" >&6; }
-if test $gcc_cv_as_ix86_sahf = yes; then
-
-$as_echo "#define HAVE_AS_IX86_SAHF 1" >>confdefs.h
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for hle prefixes" >&5
-$as_echo_n "checking assembler for hle prefixes... " >&6; }
-if test "${gcc_cv_as_ix86_hle+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_ix86_hle=no
- if test x$gcc_cv_as != x; then
- $as_echo 'lock xacquire cmpxchg %esi, (%ecx)' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_ix86_hle=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_ix86_hle" >&5
-$as_echo "$gcc_cv_as_ix86_hle" >&6; }
-if test $gcc_cv_as_ix86_hle = yes; then
-
-$as_echo "#define HAVE_AS_IX86_HLE 1" >>confdefs.h
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for swap suffix" >&5
-$as_echo_n "checking assembler for swap suffix... " >&6; }
-if test "${gcc_cv_as_ix86_swap+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_ix86_swap=no
- if test x$gcc_cv_as != x; then
- $as_echo 'movl.s %esp, %ebp' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_ix86_swap=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_ix86_swap" >&5
-$as_echo "$gcc_cv_as_ix86_swap" >&6; }
-if test $gcc_cv_as_ix86_swap = yes; then
-
-$as_echo "#define HAVE_AS_IX86_SWAP 1" >>confdefs.h
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for different section symbol subtraction" >&5
-$as_echo_n "checking assembler for different section symbol subtraction... " >&6; }
-if test "${gcc_cv_as_ix86_diff_sect_delta+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_ix86_diff_sect_delta=no
- if test x$gcc_cv_as != x; then
- $as_echo '.section .rodata
-.L1:
- .long .L2-.L1
- .long .L3-.L1
- .text
-.L3: nop
-.L2: nop' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_ix86_diff_sect_delta=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_ix86_diff_sect_delta" >&5
-$as_echo "$gcc_cv_as_ix86_diff_sect_delta" >&6; }
-if test $gcc_cv_as_ix86_diff_sect_delta = yes; then
-
-$as_echo "#define HAVE_AS_IX86_DIFF_SECT_DELTA 1" >>confdefs.h
-
-fi
-
- # These two are used unconditionally by i386.[ch]; it is to be defined
- # to 1 if the feature is present, 0 otherwise.
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for GOTOFF in data" >&5
-$as_echo_n "checking assembler for GOTOFF in data... " >&6; }
-if test "${gcc_cv_as_ix86_gotoff_in_data+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_ix86_gotoff_in_data=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 11 \) \* 1000 + 0`
- then gcc_cv_as_ix86_gotoff_in_data=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo ' .text
-.L0:
- nop
- .data
- .long .L0@GOTOFF' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_ix86_gotoff_in_data=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_ix86_gotoff_in_data" >&5
-$as_echo "$gcc_cv_as_ix86_gotoff_in_data" >&6; }
-
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_AS_GOTOFF_IN_DATA `if test $gcc_cv_as_ix86_gotoff_in_data = yes; then echo 1; else echo 0; fi`
-_ACEOF
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for rep and lock prefix" >&5
-$as_echo_n "checking assembler for rep and lock prefix... " >&6; }
-if test "${gcc_cv_as_ix86_rep_lock_prefix+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_ix86_rep_lock_prefix=no
- if test x$gcc_cv_as != x; then
- $as_echo 'rep movsl
- rep ret
- rep nop
- rep bsf %ecx, %eax
- rep bsr %ecx, %eax
- lock addl %edi, (%eax,%esi)
- lock orl $0, (%esp)' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_ix86_rep_lock_prefix=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_ix86_rep_lock_prefix" >&5
-$as_echo "$gcc_cv_as_ix86_rep_lock_prefix" >&6; }
-if test $gcc_cv_as_ix86_rep_lock_prefix = yes; then
-
-$as_echo "#define HAVE_AS_IX86_REP_LOCK_PREFIX 1" >>confdefs.h
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for R_386_TLS_GD_PLT reloc" >&5
-$as_echo_n "checking assembler for R_386_TLS_GD_PLT reloc... " >&6; }
-if test "${gcc_cv_as_ix86_tlsgdplt+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_ix86_tlsgdplt=no
- if test x$gcc_cv_as != x; then
- $as_echo 'call tls_gd@tlsgdplt' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- if test x$gcc_cv_ld != x \
- && $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1; then
- gcc_cv_as_ix86_tlsgdplt=yes
- fi
- rm -f conftest
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_ix86_tlsgdplt" >&5
-$as_echo "$gcc_cv_as_ix86_tlsgdplt" >&6; }
-if test $gcc_cv_as_ix86_tlsgdplt = yes; then
-
-$as_echo "#define HAVE_AS_IX86_TLSGDPLT 1" >>confdefs.h
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for R_386_TLS_LDM_PLT reloc" >&5
-$as_echo_n "checking assembler for R_386_TLS_LDM_PLT reloc... " >&6; }
-if test "${gcc_cv_as_ix86_tlsldmplt+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_ix86_tlsldmplt=no
- if test x$gcc_cv_as != x; then
- $as_echo 'tls_ld:
- call tls_ld@tlsldmplt' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- if test x$gcc_cv_ld != x \
- && $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1; then
- gcc_cv_as_ix86_tlsldmplt=yes
- fi
- rm -f conftest
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_ix86_tlsldmplt" >&5
-$as_echo "$gcc_cv_as_ix86_tlsldmplt" >&6; }
-if test $gcc_cv_as_ix86_tlsldmplt = yes; then
-
-$as_echo "#define HAVE_AS_IX86_TLSLDMPLT 1" >>confdefs.h
-
-fi
-
- ;;
-
- ia64*-*-*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for ltoffx and ldxmov relocs" >&5
-$as_echo_n "checking assembler for ltoffx and ldxmov relocs... " >&6; }
-if test "${gcc_cv_as_ia64_ltoffx_ldxmov_relocs+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_ia64_ltoffx_ldxmov_relocs=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 14 \) \* 1000 + 0`
- then gcc_cv_as_ia64_ltoffx_ldxmov_relocs=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo ' .text
- addl r15 = @ltoffx(x#), gp
- ;;
- ld8.mov r16 = [r15], x#' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_ia64_ltoffx_ldxmov_relocs=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_ia64_ltoffx_ldxmov_relocs" >&5
-$as_echo "$gcc_cv_as_ia64_ltoffx_ldxmov_relocs" >&6; }
-if test $gcc_cv_as_ia64_ltoffx_ldxmov_relocs = yes; then
-
-$as_echo "#define HAVE_AS_LTOFFX_LDXMOV_RELOCS 1" >>confdefs.h
-
-fi
-
- ;;
-
- powerpc*-*-*)
- case $target in
- *-*-aix*) conftest_s=' .machine "pwr5"
- .csect .text[PR]
- mfcr 3,128';;
- *-*-darwin*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .machine directive support" >&5
-$as_echo_n "checking assembler for .machine directive support... " >&6; }
-if test "${gcc_cv_as_machine_directive+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_machine_directive=no
- if test x$gcc_cv_as != x; then
- $as_echo ' .machine ppc7400' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_machine_directive=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_machine_directive" >&5
-$as_echo "$gcc_cv_as_machine_directive" >&6; }
-
- if test x$gcc_cv_as_machine_directive != xyes; then
- echo "*** This target requires an assembler supporting \".machine\"" >&2
- echo you can get it from: ftp://gcc.gnu.org/pub/gcc/infrastructure/cctools-528.5.dmg >&2
- test x$build = x$target && exit 1
- fi
- conftest_s=' .text
- mfcr r3,128';;
- *) conftest_s=' .machine power4
- .text
- mfcr 3,128';;
- esac
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for mfcr field support" >&5
-$as_echo_n "checking assembler for mfcr field support... " >&6; }
-if test "${gcc_cv_as_powerpc_mfcrf+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_powerpc_mfcrf=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 14 \) \* 1000 + 0`
- then gcc_cv_as_powerpc_mfcrf=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo "$conftest_s" > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_powerpc_mfcrf=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_powerpc_mfcrf" >&5
-$as_echo "$gcc_cv_as_powerpc_mfcrf" >&6; }
-if test $gcc_cv_as_powerpc_mfcrf = yes; then
-
-$as_echo "#define HAVE_AS_MFCRF 1" >>confdefs.h
-
-fi
-
- case $target in
- *-*-aix*) conftest_s=' .machine "pwr5"
- .csect .text[PR]
- popcntb 3,3';;
- *) conftest_s=' .machine power5
- .text
- popcntb 3,3';;
- esac
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for popcntb support" >&5
-$as_echo_n "checking assembler for popcntb support... " >&6; }
-if test "${gcc_cv_as_powerpc_popcntb+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_powerpc_popcntb=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 17 \) \* 1000 + 0`
- then gcc_cv_as_powerpc_popcntb=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo "$conftest_s" > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_powerpc_popcntb=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_powerpc_popcntb" >&5
-$as_echo "$gcc_cv_as_powerpc_popcntb" >&6; }
-if test $gcc_cv_as_powerpc_popcntb = yes; then
-
-$as_echo "#define HAVE_AS_POPCNTB 1" >>confdefs.h
-
-fi
-
- case $target in
- *-*-aix*) conftest_s=' .machine "pwr5x"
- .csect .text[PR]
- frin 1,1';;
- *) conftest_s=' .machine power5
- .text
- frin 1,1';;
- esac
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for fp round support" >&5
-$as_echo_n "checking assembler for fp round support... " >&6; }
-if test "${gcc_cv_as_powerpc_fprnd+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_powerpc_fprnd=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 17 \) \* 1000 + 0`
- then gcc_cv_as_powerpc_fprnd=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo "$conftest_s" > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_powerpc_fprnd=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_powerpc_fprnd" >&5
-$as_echo "$gcc_cv_as_powerpc_fprnd" >&6; }
-if test $gcc_cv_as_powerpc_fprnd = yes; then
-
-$as_echo "#define HAVE_AS_FPRND 1" >>confdefs.h
-
-fi
-
- case $target in
- *-*-aix*) conftest_s=' .machine "pwr6"
- .csect .text[PR]
- mffgpr 1,3';;
- *) conftest_s=' .machine power6
- .text
- mffgpr 1,3';;
- esac
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for move fp gpr support" >&5
-$as_echo_n "checking assembler for move fp gpr support... " >&6; }
-if test "${gcc_cv_as_powerpc_mfpgpr+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_powerpc_mfpgpr=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 2`
- then gcc_cv_as_powerpc_mfpgpr=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo "$conftest_s" > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_powerpc_mfpgpr=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_powerpc_mfpgpr" >&5
-$as_echo "$gcc_cv_as_powerpc_mfpgpr" >&6; }
-if test $gcc_cv_as_powerpc_mfpgpr = yes; then
-
-$as_echo "#define HAVE_AS_MFPGPR 1" >>confdefs.h
-
-fi
-
- case $target in
- *-*-aix*) conftest_s=' .csect .text[PR]
-LCF..0:
- addis 11,30,_GLOBAL_OFFSET_TABLE_-LCF..0@ha';;
- *-*-darwin*)
- conftest_s=' .text
-LCF0:
- addis r11,r30,_GLOBAL_OFFSET_TABLE_-LCF0@ha';;
- *) conftest_s=' .text
-.LCF0:
- addis 11,30,_GLOBAL_OFFSET_TABLE_-.LCF0@ha';;
- esac
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for rel16 relocs" >&5
-$as_echo_n "checking assembler for rel16 relocs... " >&6; }
-if test "${gcc_cv_as_powerpc_rel16+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_powerpc_rel16=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 17 \) \* 1000 + 0`
- then gcc_cv_as_powerpc_rel16=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo "$conftest_s" > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -a32 -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_powerpc_rel16=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_powerpc_rel16" >&5
-$as_echo "$gcc_cv_as_powerpc_rel16" >&6; }
-if test $gcc_cv_as_powerpc_rel16 = yes; then
-
-$as_echo "#define HAVE_AS_REL16 1" >>confdefs.h
-
-fi
-
- case $target in
- *-*-aix*) conftest_s=' .machine "pwr6"
- .csect .text[PR]
- cmpb 3,4,5';;
- *) conftest_s=' .machine power6
- .text
- cmpb 3,4,5';;
- esac
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for compare bytes support" >&5
-$as_echo_n "checking assembler for compare bytes support... " >&6; }
-if test "${gcc_cv_as_powerpc_cmpb+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_powerpc_cmpb=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 2`
- then gcc_cv_as_powerpc_cmpb=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo "$conftest_s" > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -a32 -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_powerpc_cmpb=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_powerpc_cmpb" >&5
-$as_echo "$gcc_cv_as_powerpc_cmpb" >&6; }
-if test $gcc_cv_as_powerpc_cmpb = yes; then
-
-$as_echo "#define HAVE_AS_CMPB 1" >>confdefs.h
-
-fi
-
- case $target in
- *-*-aix*) conftest_s=' .machine "pwr6"
- .csect .text[PR]
- dadd 1,2,3';;
- *) conftest_s=' .machine power6
- .text
- dadd 1,2,3';;
- esac
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for decimal float support" >&5
-$as_echo_n "checking assembler for decimal float support... " >&6; }
-if test "${gcc_cv_as_powerpc_dfp+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_powerpc_dfp=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 2`
- then gcc_cv_as_powerpc_dfp=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo "$conftest_s" > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -a32 -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_powerpc_dfp=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_powerpc_dfp" >&5
-$as_echo "$gcc_cv_as_powerpc_dfp" >&6; }
-if test $gcc_cv_as_powerpc_dfp = yes; then
-
-$as_echo "#define HAVE_AS_DFP 1" >>confdefs.h
-
-fi
-
- case $target in
- *-*-aix*) conftest_s=' .machine "pwr7"
- .csect .text[PR]
- lxvd2x 1,2,3';;
- *) conftest_s=' .machine power7
- .text
- lxvd2x 1,2,3';;
- esac
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for vector-scalar support" >&5
-$as_echo_n "checking assembler for vector-scalar support... " >&6; }
-if test "${gcc_cv_as_powerpc_vsx+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_powerpc_vsx=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 2`
- then gcc_cv_as_powerpc_vsx=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo "$conftest_s" > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -a32 -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_powerpc_vsx=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_powerpc_vsx" >&5
-$as_echo "$gcc_cv_as_powerpc_vsx" >&6; }
-if test $gcc_cv_as_powerpc_vsx = yes; then
-
-$as_echo "#define HAVE_AS_VSX 1" >>confdefs.h
-
-fi
-
- case $target in
- *-*-aix*) conftest_s=' .machine "pwr7"
- .csect .text[PR]
- popcntd 3,3';;
- *) conftest_s=' .machine power7
- .text
- popcntd 3,3';;
- esac
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for popcntd support" >&5
-$as_echo_n "checking assembler for popcntd support... " >&6; }
-if test "${gcc_cv_as_powerpc_popcntd+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_powerpc_popcntd=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 2`
- then gcc_cv_as_powerpc_popcntd=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo "$conftest_s" > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -a32 -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_powerpc_popcntd=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_powerpc_popcntd" >&5
-$as_echo "$gcc_cv_as_powerpc_popcntd" >&6; }
-if test $gcc_cv_as_powerpc_popcntd = yes; then
-
-$as_echo "#define HAVE_AS_POPCNTD 1" >>confdefs.h
-
-fi
-
- case $target in
- *-*-aix*) conftest_s=' .machine "pwr8"
- .csect .text[PR]';;
- *) conftest_s=' .machine power8
- .text';;
- esac
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for power8 support" >&5
-$as_echo_n "checking assembler for power8 support... " >&6; }
-if test "${gcc_cv_as_powerpc_power8+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_powerpc_power8=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 2`
- then gcc_cv_as_powerpc_power8=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo "$conftest_s" > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -a32 -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_powerpc_power8=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_powerpc_power8" >&5
-$as_echo "$gcc_cv_as_powerpc_power8" >&6; }
-if test $gcc_cv_as_powerpc_power8 = yes; then
-
-$as_echo "#define HAVE_AS_POWER8 1" >>confdefs.h
-
-fi
-
- case $target in
- *-*-aix*) conftest_s=' .csect .text[PR]
- lwsync';;
- *) conftest_s=' .text
- lwsync';;
- esac
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for lwsync support" >&5
-$as_echo_n "checking assembler for lwsync support... " >&6; }
-if test "${gcc_cv_as_powerpc_lwsync+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_powerpc_lwsync=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 2`
- then gcc_cv_as_powerpc_lwsync=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo "$conftest_s" > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -a32 -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_powerpc_lwsync=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_powerpc_lwsync" >&5
-$as_echo "$gcc_cv_as_powerpc_lwsync" >&6; }
-if test $gcc_cv_as_powerpc_lwsync = yes; then
-
-$as_echo "#define HAVE_AS_LWSYNC 1" >>confdefs.h
-
-fi
-
- case $target in
- *-*-aix*) conftest_s=' .machine "476"
- .csect .text[PR]
- dci 0';;
- *) conftest_s=' .machine "476"
- .text
- dci 0';;
- esac
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for data cache invalidate support" >&5
-$as_echo_n "checking assembler for data cache invalidate support... " >&6; }
-if test "${gcc_cv_as_powerpc_dci+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_powerpc_dci=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 9 \* 1000 \) + 99 \) \* 1000 + 0`
- then gcc_cv_as_powerpc_dci=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo "$conftest_s" > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -a32 -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_powerpc_dci=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_powerpc_dci" >&5
-$as_echo "$gcc_cv_as_powerpc_dci" >&6; }
-if test $gcc_cv_as_powerpc_dci = yes; then
-
-$as_echo "#define HAVE_AS_DCI 1" >>confdefs.h
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .gnu_attribute support" >&5
-$as_echo_n "checking assembler for .gnu_attribute support... " >&6; }
-if test "${gcc_cv_as_powerpc_gnu_attribute+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_powerpc_gnu_attribute=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 18 \) \* 1000 + 0`
- then gcc_cv_as_powerpc_gnu_attribute=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo '.gnu_attribute 4,1' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_powerpc_gnu_attribute=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_powerpc_gnu_attribute" >&5
-$as_echo "$gcc_cv_as_powerpc_gnu_attribute" >&6; }
-if test $gcc_cv_as_powerpc_gnu_attribute = yes; then
-
-$as_echo "#define HAVE_AS_GNU_ATTRIBUTE 1" >>confdefs.h
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for tls marker support" >&5
-$as_echo_n "checking assembler for tls marker support... " >&6; }
-if test "${gcc_cv_as_powerpc_tls_markers+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_powerpc_tls_markers=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 20 \) \* 1000 + 0`
- then gcc_cv_as_powerpc_tls_markers=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo ' bl __tls_get_addr(x@tlsgd)' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_powerpc_tls_markers=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_powerpc_tls_markers" >&5
-$as_echo "$gcc_cv_as_powerpc_tls_markers" >&6; }
-if test $gcc_cv_as_powerpc_tls_markers = yes; then
-
-$as_echo "#define HAVE_AS_TLS_MARKERS 1" >>confdefs.h
-
-fi
-
- case $target in
- *-*-aix*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .ref support" >&5
-$as_echo_n "checking assembler for .ref support... " >&6; }
-if test "${gcc_cv_as_aix_ref+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_aix_ref=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 21 \) \* 1000 + 0`
- then gcc_cv_as_aix_ref=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo ' .csect stuff[rw]
- stuff:
- .long 1
- .extern sym
- .ref sym
- ' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_aix_ref=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_aix_ref" >&5
-$as_echo "$gcc_cv_as_aix_ref" >&6; }
-if test $gcc_cv_as_aix_ref = yes; then
-
-$as_echo "#define HAVE_AS_REF 1" >>confdefs.h
-
-fi
- ;;
- esac
- ;;
-
- mips*-*-*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for explicit relocation support" >&5
-$as_echo_n "checking assembler for explicit relocation support... " >&6; }
-if test "${gcc_cv_as_mips_explicit_relocs+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_mips_explicit_relocs=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 14 \) \* 1000 + 0`
- then gcc_cv_as_mips_explicit_relocs=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo ' lw $4,%gp_rel(foo)($4)' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_mips_explicit_relocs=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_mips_explicit_relocs" >&5
-$as_echo "$gcc_cv_as_mips_explicit_relocs" >&6; }
-if test $gcc_cv_as_mips_explicit_relocs = yes; then
- if test x$target_cpu_default = x
- then target_cpu_default=MASK_EXPLICIT_RELOCS
- else target_cpu_default="($target_cpu_default)|MASK_EXPLICIT_RELOCS"
- fi
-fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for -mno-shared support" >&5
-$as_echo_n "checking assembler for -mno-shared support... " >&6; }
-if test "${gcc_cv_as_mips_no_shared+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_mips_no_shared=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 16 \) \* 1000 + 0`
- then gcc_cv_as_mips_no_shared=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo 'nop' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -mno-shared -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_mips_no_shared=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_mips_no_shared" >&5
-$as_echo "$gcc_cv_as_mips_no_shared" >&6; }
-if test $gcc_cv_as_mips_no_shared = yes; then
-
-$as_echo "#define HAVE_AS_NO_SHARED 1" >>confdefs.h
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .gnu_attribute support" >&5
-$as_echo_n "checking assembler for .gnu_attribute support... " >&6; }
-if test "${gcc_cv_as_mips_gnu_attribute+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_mips_gnu_attribute=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 18 \) \* 1000 + 0`
- then gcc_cv_as_mips_gnu_attribute=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo '.gnu_attribute 4,1' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_mips_gnu_attribute=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_mips_gnu_attribute" >&5
-$as_echo "$gcc_cv_as_mips_gnu_attribute" >&6; }
-if test $gcc_cv_as_mips_gnu_attribute = yes; then
-
-$as_echo "#define HAVE_AS_GNU_ATTRIBUTE 1" >>confdefs.h
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .dtprelword support" >&5
-$as_echo_n "checking assembler for .dtprelword support... " >&6; }
-if test "${gcc_cv_as_mips_dtprelword+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_mips_dtprelword=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 18 \) \* 1000 + 0`
- then gcc_cv_as_mips_dtprelword=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo '.section .tdata,"awT",@progbits
-x:
- .word 2
- .text
- .dtprelword x+0x8000' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_mips_dtprelword=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_mips_dtprelword" >&5
-$as_echo "$gcc_cv_as_mips_dtprelword" >&6; }
-if test $gcc_cv_as_mips_dtprelword = yes; then
-
-$as_echo "#define HAVE_AS_DTPRELWORD 1" >>confdefs.h
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for DSPR1 mult with four accumulators support" >&5
-$as_echo_n "checking assembler for DSPR1 mult with four accumulators support... " >&6; }
-if test "${gcc_cv_as_mips_dspr1_mult+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_mips_dspr1_mult=no
- if test x$gcc_cv_as != x; then
- $as_echo ' .set mips32r2
- .set nodspr2
- .set dsp
- madd $ac3,$4,$5
- maddu $ac3,$4,$5
- msub $ac3,$4,$5
- msubu $ac3,$4,$5
- mult $ac3,$4,$5
- multu $ac3,$4,$5' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_mips_dspr1_mult=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_mips_dspr1_mult" >&5
-$as_echo "$gcc_cv_as_mips_dspr1_mult" >&6; }
-if test $gcc_cv_as_mips_dspr1_mult = yes; then
-
-$as_echo "#define HAVE_AS_DSPR1_MULT 1" >>confdefs.h
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler and linker for explicit JALR relocation" >&5
-$as_echo_n "checking assembler and linker for explicit JALR relocation... " >&6; }
- gcc_cv_as_ld_jalr_reloc=no
- if test $gcc_cv_as_mips_explicit_relocs = yes; then
- if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 20 -o "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes; then
- gcc_cv_as_ld_jalr_reloc=yes
- fi
- elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x -a x$gcc_cv_objdump != x; then
- echo ' .ent x' > conftest.s
- echo 'x: ld $2,%got_disp(y)($3)' >> conftest.s
- echo ' ld $25,%call16(y)($28)' >> conftest.s
- echo ' .reloc 1f,R_MIPS_JALR,y' >> conftest.s
- echo '1: jalr $25' >> conftest.s
- echo ' .reloc 1f,R_MIPS_JALR,x' >> conftest.s
- echo '1: jalr $25' >> conftest.s
- echo ' .end x' >> conftest.s
- if $gcc_cv_as -o conftest.o conftest.s >/dev/null 2>&5 \
- && $gcc_cv_ld -shared -o conftest.so conftest.o >/dev/null 2>&5; then
- if $gcc_cv_objdump -d conftest.so | grep jalr >/dev/null 2>&1 \
- && $gcc_cv_objdump -d conftest.so | grep "bal.*<x>" >/dev/null 2>&1; then
- gcc_cv_as_ld_jalr_reloc=yes
- fi
- fi
- rm -f conftest.*
- fi
- fi
- if test $gcc_cv_as_ld_jalr_reloc = yes; then
- if test x$target_cpu_default = x; then
- target_cpu_default=MASK_RELAX_PIC_CALLS
- else
- target_cpu_default="($target_cpu_default)|MASK_RELAX_PIC_CALLS"
- fi
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_ld_jalr_reloc" >&5
-$as_echo "$gcc_cv_as_ld_jalr_reloc" >&6; }
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker for .eh_frame personality relaxation" >&5
-$as_echo_n "checking linker for .eh_frame personality relaxation... " >&6; }
-if test "${gcc_cv_ld_mips_personality_relaxation+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_ld_mips_personality_relaxation=no
- if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 \
- -a "$gcc_cv_gld_minor_version" -ge 21 \
- -o "$gcc_cv_gld_major_version" -gt 2; then
- gcc_cv_ld_mips_personality_relaxation=yes
- fi
- elif test x$gcc_cv_as != x \
- -a x$gcc_cv_ld != x \
- -a x$gcc_cv_readelf != x ; then
- cat > conftest.s <<EOF
- .cfi_startproc
- .cfi_personality 0x80,indirect_ptr
- .ent test
-test:
- nop
- .end test
- .cfi_endproc
-
- .section .data,"aw",@progbits
-indirect_ptr:
- .dc.a personality
-EOF
- if $gcc_cv_as -KPIC -o conftest.o conftest.s > /dev/null 2>&1 \
- && $gcc_cv_ld -o conftest conftest.o -shared > /dev/null 2>&1; then
- if $gcc_cv_readelf -d conftest 2>&1 \
- | grep TEXTREL > /dev/null 2>&1; then
- :
- elif $gcc_cv_readelf --relocs conftest 2>&1 \
- | grep 'R_MIPS_REL32 *$' > /dev/null 2>&1; then
- :
- else
- gcc_cv_ld_mips_personality_relaxation=yes
- fi
- fi
- fi
- rm -f conftest.s conftest.o conftest
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_mips_personality_relaxation" >&5
-$as_echo "$gcc_cv_ld_mips_personality_relaxation" >&6; }
- if test x$gcc_cv_ld_mips_personality_relaxation = xyes; then
-
-$as_echo "#define HAVE_LD_PERSONALITY_RELAXATION 1" >>confdefs.h
-
- fi
- ;;
-esac
-
-# Mips and HP-UX need the GNU assembler.
-# Linux on IA64 might be able to use the Intel assembler.
-
-case "$target" in
- mips*-*-* | *-*-hpux* )
- if test x$gas_flag = xyes \
- || test x"$host" != x"$build" \
- || test ! -x "$gcc_cv_as" \
- || "$gcc_cv_as" -v < /dev/null 2>&1 | grep GNU > /dev/null; then
- :
- else
- echo "*** This configuration requires the GNU assembler" >&2
- exit 1
- fi
- ;;
-esac
-
-# ??? Not all targets support dwarf2 debug_line, even within a version
-# of gas. Moreover, we need to emit a valid instruction to trigger any
-# info to the output file. So, as supported targets are added to gas 2.11,
-# add some instruction here to (also) show we expect this might work.
-# ??? Once 2.11 is released, probably need to add first known working
-# version to the per-target configury.
-case "$cpu_type" in
- alpha | arm | avr | bfin | cris | i386 | m32c | m68k | microblaze | mips \
- | pa | rs6000 | score | sparc | spu | tilegx | tilepro | xstormy16 | xtensa)
- insn="nop"
- ;;
- ia64 | s390)
- insn="nop 0"
- ;;
- mmix)
- insn="swym 0"
- ;;
-esac
-if test x"$insn" != x; then
- conftest_s="\
- .file 1 \"conftest.s\"
- .loc 1 3 0
- $insn"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for dwarf2 debug_line support" >&5
-$as_echo_n "checking assembler for dwarf2 debug_line support... " >&6; }
-if test "${gcc_cv_as_dwarf2_debug_line+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_dwarf2_debug_line=no
- if test $in_tree_gas = yes; then
- if test $in_tree_gas_is_elf = yes \
- && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 11 \) \* 1000 + 0`
- then gcc_cv_as_dwarf2_debug_line=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo "$conftest_s" > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- if test x$gcc_cv_objdump != x \
- && $gcc_cv_objdump -h conftest.o 2> /dev/null \
- | grep debug_line > /dev/null 2>&1; then
- gcc_cv_as_dwarf2_debug_line=yes
- fi
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_dwarf2_debug_line" >&5
-$as_echo "$gcc_cv_as_dwarf2_debug_line" >&6; }
-
-
-# The .debug_line file table must be in the exact order that
-# we specified the files, since these indices are also used
-# by DW_AT_decl_file. Approximate this test by testing if
-# the assembler bitches if the same index is assigned twice.
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for buggy dwarf2 .file directive" >&5
-$as_echo_n "checking assembler for buggy dwarf2 .file directive... " >&6; }
-if test "${gcc_cv_as_dwarf2_file_buggy+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_dwarf2_file_buggy=no
- if test x$gcc_cv_as != x; then
- $as_echo ' .file 1 "foo.s"
- .file 1 "bar.s"' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_dwarf2_file_buggy=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_dwarf2_file_buggy" >&5
-$as_echo "$gcc_cv_as_dwarf2_file_buggy" >&6; }
-
-
- if test $gcc_cv_as_dwarf2_debug_line = yes \
- && test $gcc_cv_as_dwarf2_file_buggy = no; then
-
-$as_echo "#define HAVE_AS_DWARF2_DEBUG_LINE 1" >>confdefs.h
-
- fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for --gdwarf2 option" >&5
-$as_echo_n "checking assembler for --gdwarf2 option... " >&6; }
-if test "${gcc_cv_as_gdwarf2_flag+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_gdwarf2_flag=no
- if test $in_tree_gas = yes; then
- if test $in_tree_gas_is_elf = yes \
- && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 11 \) \* 1000 + 0`
- then gcc_cv_as_gdwarf2_flag=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo "$insn" > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags --gdwarf2 -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_gdwarf2_flag=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_gdwarf2_flag" >&5
-$as_echo "$gcc_cv_as_gdwarf2_flag" >&6; }
-if test $gcc_cv_as_gdwarf2_flag = yes; then
-
-$as_echo "#define HAVE_AS_GDWARF2_DEBUG_FLAG 1" >>confdefs.h
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for --gstabs option" >&5
-$as_echo_n "checking assembler for --gstabs option... " >&6; }
-if test "${gcc_cv_as_gstabs_flag+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_gstabs_flag=no
- if test $in_tree_gas = yes; then
- if test $in_tree_gas_is_elf = yes \
- && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 11 \) \* 1000 + 0`
- then gcc_cv_as_gstabs_flag=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo "$insn" > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags --gstabs -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- # The native Solaris 9/Intel assembler doesn't understand --gstabs
- # and warns about it, but still exits successfully. So check for
- # this.
- if { ac_try='$gcc_cv_as --gstabs -o conftest.o conftest.s 2>&1 | grep -i warning > /dev/null'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then :
- else gcc_cv_as_gstabs_flag=yes
- fi
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_gstabs_flag" >&5
-$as_echo "$gcc_cv_as_gstabs_flag" >&6; }
-if test $gcc_cv_as_gstabs_flag = yes; then
-
-$as_echo "#define HAVE_AS_GSTABS_DEBUG_FLAG 1" >>confdefs.h
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for --debug-prefix-map option" >&5
-$as_echo_n "checking assembler for --debug-prefix-map option... " >&6; }
-if test "${gcc_cv_as_debug_prefix_map_flag+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_debug_prefix_map_flag=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 18 \) \* 1000 + 0`
- then gcc_cv_as_debug_prefix_map_flag=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo "$insn" > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags --debug-prefix-map /a=/b -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_debug_prefix_map_flag=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_debug_prefix_map_flag" >&5
-$as_echo "$gcc_cv_as_debug_prefix_map_flag" >&6; }
-if test $gcc_cv_as_debug_prefix_map_flag = yes; then
-
-$as_echo "#define HAVE_AS_DEBUG_PREFIX_MAP 1" >>confdefs.h
-
-fi
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .lcomm with alignment" >&5
-$as_echo_n "checking assembler for .lcomm with alignment... " >&6; }
-if test "${gcc_cv_as_lcomm_with_alignment+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_lcomm_with_alignment=no
- if test x$gcc_cv_as != x; then
- $as_echo '.lcomm bar,4,16' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_lcomm_with_alignment=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_lcomm_with_alignment" >&5
-$as_echo "$gcc_cv_as_lcomm_with_alignment" >&6; }
-if test $gcc_cv_as_lcomm_with_alignment = yes; then
-
-$as_echo "#define HAVE_GAS_LCOMM_WITH_ALIGNMENT 1" >>confdefs.h
-
-fi
-
-# Check whether --enable-gnu-unique-object was given.
-if test "${enable_gnu_unique_object+set}" = set; then :
- enableval=$enable_gnu_unique_object; case $enable_gnu_unique_object in
- yes | no) ;;
- *) as_fn_error "'$enable_gnu_unique_object' is an invalid value for --enable-gnu-unique-object.
-Valid choices are 'yes' and 'no'." "$LINENO" 5 ;;
- esac
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for gnu_unique_object" >&5
-$as_echo_n "checking assembler for gnu_unique_object... " >&6; }
-if test "${gcc_cv_as_gnu_unique_object+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_gnu_unique_object=no
- if test $in_tree_gas = yes; then
- if test $in_tree_gas_is_elf = yes \
- && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 52`
- then gcc_cv_as_gnu_unique_object=yes
-fi
- elif test x$gcc_cv_as != x; then
- $as_echo '.type foo, '$target_type_format_char'gnu_unique_object' > conftest.s
- if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }
- then
- gcc_cv_as_gnu_unique_object=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- fi
- rm -f conftest.o conftest.s
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_gnu_unique_object" >&5
-$as_echo "$gcc_cv_as_gnu_unique_object" >&6; }
-if test $gcc_cv_as_gnu_unique_object = yes; then
- # We need to unquote above to to use the definition from config.gcc.
-# Also check for ld.so support, i.e. glibc 2.11 or higher.
- if test x$host = x$build -a x$host = x$target &&
- ldd --version 2>/dev/null &&
- glibcver=`ldd --version 2>/dev/null | sed 's/.* //;q'`; then
- glibcmajor=`expr "$glibcver" : "\([0-9]*\)"`
- glibcminor=`expr "$glibcver" : "[2-9]*\.\([0-9]*\)"`
- glibcnum=`expr $glibcmajor \* 1000 + $glibcminor`
- if test "$glibcnum" -ge 2011 ; then
- enable_gnu_unique_object=yes
- fi
- fi
-fi
-fi
-
-if test x$enable_gnu_unique_object = xyes; then
-
-$as_echo "#define HAVE_GAS_GNU_UNIQUE_OBJECT 1" >>confdefs.h
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for tolerance to line number 0" >&5
-$as_echo_n "checking assembler for tolerance to line number 0... " >&6; }
-if test "${gcc_cv_as_line_zero+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_as_line_zero=no
- if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 16 \) \* 1000 + 91`
- then gcc_cv_as_line_zero=yes
-fi
- elif test "x$gcc_cv_as" != x; then
- { echo '# 1 "test.s" 1'; echo '# 0 "" 2'; } > conftest.s
- if { ac_try='$gcc_cv_as -o conftest.o conftest.s >&5 2>conftest.out'
- { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; } &&
- test "x`cat conftest.out`" = x
- then
- gcc_cv_as_line_zero=yes
- else
- echo "configure: failed program was" >&5
- cat conftest.s >&5
- echo "configure: error output was" >&5
- cat conftest.out >&5
- fi
- rm -f conftest.o conftest.s conftest.out
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_line_zero" >&5
-$as_echo "$gcc_cv_as_line_zero" >&6; }
-if test "x$gcc_cv_as_line_zero" = xyes; then
-
-$as_echo "#define HAVE_AS_LINE_ZERO 1" >>confdefs.h
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker PT_GNU_EH_FRAME support" >&5
-$as_echo_n "checking linker PT_GNU_EH_FRAME support... " >&6; }
-gcc_cv_ld_eh_frame_hdr=no
-if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 12 -o "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes; then
- gcc_cv_ld_eh_frame_hdr=yes
- fi
-elif test x$gcc_cv_ld != x; then
- if echo "$ld_ver" | grep GNU > /dev/null; then
- # Check if linker supports --eh-frame-hdr option
- if $gcc_cv_ld --help 2>/dev/null | grep eh-frame-hdr > /dev/null; then
- gcc_cv_ld_eh_frame_hdr=yes
- fi
- else
- case "$target" in
- *-*-solaris2*)
- # Sun ld has various bugs in .eh_frame_hdr support before version 1.2251.
- if test "$ld_vers_major" -gt 1 || test "$ld_vers_minor" -ge 2251; then
- gcc_cv_ld_eh_frame_hdr=yes
- fi
- ;;
- esac
- fi
-fi
-
-if test x"$gcc_cv_ld_eh_frame_hdr" = xyes; then
-
-$as_echo "#define HAVE_LD_EH_FRAME_HDR 1" >>confdefs.h
-
- # Check whether --enable-eh-frame-hdr-for-static was given.
-if test "${enable_eh_frame_hdr_for_static+set}" = set; then :
- enableval=$enable_eh_frame_hdr_for_static; case $enable_eh_frame_hdr_for_static in
- yes | no) ;;
- *) as_fn_error "'$enable_eh_frame_hdr_for_static' is an invalid
-value for --enable-eh-frame-hdr-for-static.
-Valid choices are 'yes' and 'no'." "$LINENO" 5 ;;
- esac
-else
- # Only support for glibc 2.3.0 or higher with AT_PHDR/AT_PHNUM from
-# Linux kernel.
- if test x$host = x$build -a x$host = x$target &&
- ldd --version 2>&1 >/dev/null &&
- glibcver=`ldd --version 2>/dev/null | sed 's/.* //;q'`; then
- glibcmajor=`expr "$glibcver" : "\([0-9]*\)"`
- glibcminor=`expr "$glibcver" : "[2-9]*\.\([0-9]*\)"`
- glibcnum=`expr $glibcmajor \* 1000 + $glibcminor`
- if test "$glibcnum" -ge 2003 ; then
- auvx=`LD_SHOW_AUXV=1 ldd 2>/dev/null`
- if echo "$auvx" | grep AT_PHDR > /dev/null &&
- echo "$auvx" | grep AT_PHNUM > /dev/null; then
- enable_eh_frame_hdr_for_static=yes
- fi
- fi
- fi
-fi
-
- if test x$enable_eh_frame_hdr_for_static = xyes; then
-
-$as_echo "#define USE_EH_FRAME_HDR_FOR_STATIC 1" >>confdefs.h
-
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_eh_frame_hdr" >&5
-$as_echo "$gcc_cv_ld_eh_frame_hdr" >&6; }
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker position independent executable support" >&5
-$as_echo_n "checking linker position independent executable support... " >&6; }
-gcc_cv_ld_pie=no
-if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 15 -o "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes; then
- gcc_cv_ld_pie=yes
- fi
-elif test x$gcc_cv_ld != x; then
- # Check if linker supports -pie option
- if $gcc_cv_ld --help 2>/dev/null | grep -- -pie > /dev/null; then
- gcc_cv_ld_pie=yes
- fi
-fi
-if test x"$gcc_cv_ld_pie" = xyes; then
-
-$as_echo "#define HAVE_LD_PIE 1" >>confdefs.h
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_pie" >&5
-$as_echo "$gcc_cv_ld_pie" >&6; }
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker EH-compatible garbage collection of sections" >&5
-$as_echo_n "checking linker EH-compatible garbage collection of sections... " >&6; }
-gcc_cv_ld_eh_gc_sections=no
-if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 17 -o "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes; then
- gcc_cv_ld_eh_gc_sections=yes
- fi
-elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x -a x$gcc_cv_objdump != x ; then
- cat > conftest.s <<EOF
- .section .text
-.globl _start
- .type _start, @function
-_start:
- .long foo
- .size _start, .-_start
- .section .text.foo,"ax",@progbits
- .type foo, @function
-foo:
- .long 0
- .size foo, .-foo
- .section .gcc_except_table.foo,"a",@progbits
-.L0:
- .long 0
- .section .eh_frame,"a",@progbits
- .long .L0
-EOF
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then
- if $gcc_cv_ld -o conftest conftest.o --entry=_start --gc-sections 2>&1 \
- | grep "gc-sections option ignored" > /dev/null; then
- gcc_cv_ld_eh_gc_sections=no
- elif $gcc_cv_objdump -h conftest 2> /dev/null \
- | grep gcc_except_table > /dev/null; then
- gcc_cv_ld_eh_gc_sections=yes
- # If no COMDAT groups, the compiler will emit .gnu.linkonce.t. sections.
- if test x$gcc_cv_as_comdat_group != xyes; then
- gcc_cv_ld_eh_gc_sections=no
- cat > conftest.s <<EOF
- .section .text
-.globl _start
- .type _start, @function
-_start:
- .long foo
- .size _start, .-_start
- .section .gnu.linkonce.t.foo,"ax",@progbits
- .type foo, @function
-foo:
- .long 0
- .size foo, .-foo
- .section .gcc_except_table.foo,"a",@progbits
-.L0:
- .long 0
- .section .eh_frame,"a",@progbits
- .long .L0
-EOF
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then
- if $gcc_cv_ld -o conftest conftest.o --entry=_start --gc-sections 2>&1 \
- | grep "gc-sections option ignored" > /dev/null; then
- gcc_cv_ld_eh_gc_sections=no
- elif $gcc_cv_objdump -h conftest 2> /dev/null \
- | grep gcc_except_table > /dev/null; then
- gcc_cv_ld_eh_gc_sections=yes
- fi
- fi
- fi
- fi
- fi
- rm -f conftest.s conftest.o conftest
-fi
-case "$target" in
- hppa*-*-linux*)
- # ??? This apparently exposes a binutils bug with PC-relative relocations.
- gcc_cv_ld_eh_gc_sections=no
- ;;
-esac
-if test x$gcc_cv_ld_eh_gc_sections = xyes; then
-
-$as_echo "#define HAVE_LD_EH_GC_SECTIONS 1" >>confdefs.h
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_eh_gc_sections" >&5
-$as_echo "$gcc_cv_ld_eh_gc_sections" >&6; }
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker EH garbage collection of sections bug" >&5
-$as_echo_n "checking linker EH garbage collection of sections bug... " >&6; }
-gcc_cv_ld_eh_gc_sections_bug=no
-if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -lt 19 -o "$gcc_cv_gld_major_version" -lt 2 \
- && test $in_tree_ld_is_elf = yes; then
- gcc_cv_ld_eh_gc_sections_bug=yes
- fi
-elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x -a x$gcc_cv_objdump != x -a x$gcc_cv_as_comdat_group = xyes; then
- gcc_cv_ld_eh_gc_sections_bug=yes
- cat > conftest.s <<EOF
- .section .text
-.globl _start
- .type _start, @function
-_start:
- .long foo
- .size _start, .-_start
- .section .text.startup.foo,"ax",@progbits
- .type foo, @function
-foo:
- .long 0
- .size foo, .-foo
- .section .gcc_except_table.foo,"a",@progbits
-.L0:
- .long 0
- .section .eh_frame,"a",@progbits
- .long .L0
-EOF
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then
- if $gcc_cv_ld -o conftest conftest.o --entry=_start --gc-sections 2>&1 \
- | grep "gc-sections option ignored" > /dev/null; then
- :
- elif $gcc_cv_objdump -h conftest 2> /dev/null \
- | grep gcc_except_table > /dev/null; then
- gcc_cv_ld_eh_gc_sections_bug=no
- fi
- fi
- rm -f conftest.s conftest.o conftest
-fi
-if test x$gcc_cv_ld_eh_gc_sections_bug = xyes; then
-
-$as_echo "#define HAVE_LD_EH_GC_SECTIONS_BUG 1" >>confdefs.h
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_eh_gc_sections_bug" >&5
-$as_echo "$gcc_cv_ld_eh_gc_sections_bug" >&6; }
-
-# --------
-# UNSORTED
-# --------
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker --as-needed support" >&5
-$as_echo_n "checking linker --as-needed support... " >&6; }
-if test "${gcc_cv_ld_as_needed+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_ld_as_needed=no
-if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes; then
- gcc_cv_ld_as_needed=yes
- fi
-elif test x$gcc_cv_ld != x; then
- # Check if linker supports --as-needed and --no-as-needed options
- if $gcc_cv_ld --help 2>/dev/null | grep as-needed > /dev/null; then
- gcc_cv_ld_as_needed=yes
- fi
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_as_needed" >&5
-$as_echo "$gcc_cv_ld_as_needed" >&6; }
-if test x"$gcc_cv_ld_as_needed" = xyes; then
-
-$as_echo "#define HAVE_LD_AS_NEEDED 1" >>confdefs.h
-
-fi
-
-case "$target:$tm_file" in
- powerpc64-*-freebsd* | powerpc64*-*-linux* | powerpc*-*-linux*rs6000/biarch64.h*)
- case "$target" in
- *-*-linux*)
- emul_name="-melf64ppc"
- ;;
- *-*-freebsd*)
- emul_name="-melf64ppc_fbsd"
- ;;
- esac
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker support for omitting dot symbols" >&5
-$as_echo_n "checking linker support for omitting dot symbols... " >&6; }
-if test "${gcc_cv_ld_no_dot_syms+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_ld_no_dot_syms=no
- if test x"$ld_is_gold" = xyes; then
- gcc_cv_ld_no_dot_syms=yes
- elif test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2; then
- gcc_cv_ld_no_dot_syms=yes
- fi
- elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x ; then
- cat > conftest1.s <<EOF
- .text
- bl .foo
-EOF
- cat > conftest2.s <<EOF
- .section ".opd","aw"
- .align 3
- .globl foo
- .type foo,@function
-foo:
- .quad .LEfoo,.TOC.@tocbase,0
- .text
-.LEfoo:
- blr
- .size foo,.-.LEfoo
-EOF
- if $gcc_cv_as -a64 -o conftest1.o conftest1.s > /dev/null 2>&1 \
- && $gcc_cv_as -a64 -o conftest2.o conftest2.s > /dev/null 2>&1 \
- && $gcc_cv_ld $emul_name -o conftest conftest1.o conftest2.o > /dev/null 2>&1; then
- gcc_cv_ld_no_dot_syms=yes
- fi
- rm -f conftest conftest1.o conftest2.o conftest1.s conftest2.s
- fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_no_dot_syms" >&5
-$as_echo "$gcc_cv_ld_no_dot_syms" >&6; }
- if test x"$gcc_cv_ld_no_dot_syms" = xyes; then
-
-$as_echo "#define HAVE_LD_NO_DOT_SYMS 1" >>confdefs.h
-
- fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker large toc support" >&5
-$as_echo_n "checking linker large toc support... " >&6; }
-if test "${gcc_cv_ld_large_toc+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_ld_large_toc=no
- if test x"$ld_is_gold" = xyes; then
- gcc_cv_ld_large_toc=yes
- elif test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 21 -o "$gcc_cv_gld_major_version" -gt 2; then
- gcc_cv_ld_large_toc=yes
- fi
- elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x ; then
- cat > conftest.s <<EOF
- .section ".tbss","awT",@nobits
- .align 3
-ie0: .space 8
- .global _start
- .text
-_start:
- addis 9,13,ie0@got@tprel@ha
- ld 9,ie0@got@tprel@l(9)
-EOF
- if $gcc_cv_as -a64 -o conftest.o conftest.s > /dev/null 2>&1 \
- && $gcc_cv_ld $emul_name --no-toc-sort -o conftest conftest.o > /dev/null 2>&1; then
- gcc_cv_ld_large_toc=yes
- fi
- rm -f conftest conftest.o conftest.s
- fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_large_toc" >&5
-$as_echo "$gcc_cv_ld_large_toc" >&6; }
- if test x"$gcc_cv_ld_large_toc" = xyes; then
-
-$as_echo "#define HAVE_LD_LARGE_TOC 1" >>confdefs.h
-
- fi
- ;;
-esac
-
-case "$target" in
- *-*-aix*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker large toc support" >&5
-$as_echo_n "checking linker large toc support... " >&6; }
-if test "${gcc_cv_ld_large_toc+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_ld_large_toc=no
- if test x$gcc_cv_as != x ; then
- cat > conftest.s <<EOF
- .toc
-LC..1:
- .tc a[TC],a[RW]
- .extern a[RW]
- .csect .text[PR]
-.largetoctest:
- addis 9,LC..1@u(2)
- ld 3,LC..1@l(9)
-EOF
- if $gcc_cv_as -a64 -o conftest.o conftest.s > /dev/null 2>&1; then
- gcc_cv_ld_large_toc=yes
- fi
- rm -f conftest conftest.o conftest.s
- fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_large_toc" >&5
-$as_echo "$gcc_cv_ld_large_toc" >&6; }
- if test x"$gcc_cv_ld_large_toc" = xyes; then
-
-$as_echo "#define HAVE_LD_LARGE_TOC 1" >>confdefs.h
-
- fi
- ;;
-esac
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker --build-id support" >&5
-$as_echo_n "checking linker --build-id support... " >&6; }
-if test "${gcc_cv_ld_buildid+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_ld_buildid=no
- if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a \
- "$gcc_cv_gld_minor_version" -ge 18 -o \
- "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes; then
- gcc_cv_ld_buildid=yes
- fi
- elif test x$gcc_cv_ld != x; then
- if $gcc_cv_ld --help 2>/dev/null | grep build-id > /dev/null; then
- gcc_cv_ld_buildid=yes
- fi
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_buildid" >&5
-$as_echo "$gcc_cv_ld_buildid" >&6; }
-if test x"$gcc_cv_ld_buildid" = xyes; then
-
-$as_echo "#define HAVE_LD_BUILDID 1" >>confdefs.h
-
-fi
-
-# Check whether --enable-linker-build-id was given.
-if test "${enable_linker_build_id+set}" = set; then :
- enableval=$enable_linker_build_id;
-else
- enable_linker_build_id=no
-fi
-
-
-if test x"$enable_linker_build_id" = xyes; then
- if test x"$gcc_cv_ld_buildid" = xyes; then
-
-$as_echo "#define ENABLE_LD_BUILDID 1" >>confdefs.h
-
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --build-id is not supported by your linker; --enable-linker-build-id ignored" >&5
-$as_echo "$as_me: WARNING: --build-id is not supported by your linker; --enable-linker-build-id ignored" >&2;}
- fi
-fi
-
-# In binutils 2.21, GNU ld gained support for new emulations fully
-# supporting the Solaris 2 ABI. Detect their presence in the linker used.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker *_sol2 emulation support" >&5
-$as_echo_n "checking linker *_sol2 emulation support... " >&6; }
-if test "${gcc_cv_ld_sol2_emulation+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_ld_sol2_emulation=no
- if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a \
- "$gcc_cv_gld_minor_version" -ge 21 -o \
- "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes; then
- gcc_cv_ld_sol2_emulation=yes
- fi
- elif test x$gcc_cv_ld != x; then
- if $gcc_cv_ld -V 2>/dev/null | sed -e '1,/Supported emulations/d;q' | \
- grep _sol2 > /dev/null; then
- gcc_cv_ld_sol2_emulation=yes
- fi
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_sol2_emulation" >&5
-$as_echo "$gcc_cv_ld_sol2_emulation" >&6; }
-if test x"$gcc_cv_ld_sol2_emulation" = xyes; then
-
-$as_echo "#define HAVE_LD_SOL2_EMULATION 1" >>confdefs.h
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker --sysroot support" >&5
-$as_echo_n "checking linker --sysroot support... " >&6; }
-if test "${gcc_cv_ld_sysroot+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_ld_sysroot=no
- if test $in_tree_ld = yes ; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2 ; then
- gcc_cv_ld_sysroot=yes
- fi
- elif test x$gcc_cv_ld != x; then
- if $gcc_cv_ld --help 2>/dev/null | grep sysroot > /dev/null; then
- gcc_cv_ld_sysroot=yes
- fi
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_sysroot" >&5
-$as_echo "$gcc_cv_ld_sysroot" >&6; }
-if test x"$gcc_cv_ld_sysroot" = xyes; then
-
-$as_echo "#define HAVE_LD_SYSROOT 1" >>confdefs.h
-
-fi
-
-if test x$with_sysroot = x && test x$host = x$target \
- && test "$prefix" != "/usr" && test "x$prefix" != "x$local_prefix" \
- && test "$prefix" != "NONE"; then
-
-cat >>confdefs.h <<_ACEOF
-#define PREFIX_INCLUDE_DIR "$prefix/include"
-_ACEOF
-
-fi
-
-if test x$host != x$target || test "x$TARGET_SYSTEM_ROOT" != x; then
- if test "x$with_headers" != x; then
- target_header_dir=$with_headers
- elif test "x$with_sysroot" = x; then
- target_header_dir="${test_exec_prefix}/${target_noncanonical}/sys-include"
- elif test "x$with_build_sysroot" != "x"; then
- target_header_dir="${with_build_sysroot}${native_system_header_dir}"
- elif test "x$with_sysroot" = xyes; then
- target_header_dir="${test_exec_prefix}/${target_noncanonical}/sys-root${native_system_header_dir}"
- else
- target_header_dir="${with_sysroot}${native_system_header_dir}"
- fi
-else
- target_header_dir=${native_system_header_dir}
-fi
-
-# Test for stack protector support in target C library.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking __stack_chk_fail in target C library" >&5
-$as_echo_n "checking __stack_chk_fail in target C library... " >&6; }
-if test "${gcc_cv_libc_provides_ssp+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- gcc_cv_libc_provides_ssp=no
- case "$target" in
- *-*-linux* | *-*-kfreebsd*-gnu | *-*-knetbsd*-gnu)
- # glibc 2.4 and later provides __stack_chk_fail and
- # either __stack_chk_guard, or TLS access to stack guard canary.
- if test -f $target_header_dir/features.h \
- && $EGREP '^[ ]*#[ ]*define[ ]+__GNU_LIBRARY__[ ]+([1-9][0-9]|[6-9])' \
- $target_header_dir/features.h > /dev/null; then
- if $EGREP '^[ ]*#[ ]*define[ ]+__GLIBC__[ ]+([1-9][0-9]|[3-9])' \
- $target_header_dir/features.h > /dev/null; then
- gcc_cv_libc_provides_ssp=yes
- elif $EGREP '^[ ]*#[ ]*define[ ]+__GLIBC__[ ]+2' \
- $target_header_dir/features.h > /dev/null \
- && $EGREP '^[ ]*#[ ]*define[ ]+__GLIBC_MINOR__[ ]+([1-9][0-9]|[4-9])' \
- $target_header_dir/features.h > /dev/null; then
- gcc_cv_libc_provides_ssp=yes
- elif $EGREP '^[ ]*#[ ]*define[ ]+__UCLIBC__[ ]+1' \
- $target_header_dir/features.h > /dev/null && \
- test -f $target_header_dir/bits/uClibc_config.h && \
- $EGREP '^[ ]*#[ ]*define[ ]+__UCLIBC_HAS_SSP__[ ]+1' \
- $target_header_dir/bits/uClibc_config.h > /dev/null; then
- gcc_cv_libc_provides_ssp=yes
- fi
- # all versions of Bionic support stack protector
- elif test -f $target_header_dir/sys/cdefs.h \
- && $EGREP '^[ ]*#[ ]*define[ ]+__BIONIC__[ ]+1' \
- $target_header_dir/sys/cdefs.h > /dev/null; then
- gcc_cv_libc_provides_ssp=yes
- fi
- ;;
- *-*-gnu*)
- # Avoid complicated tests (see
- # <http://gcc.gnu.org/ml/gcc/2008-10/msg00130.html>) and for now
- # simply assert that glibc does provide this, which is true for all
- # realistically usable GNU/Hurd configurations.
- gcc_cv_libc_provides_ssp=yes;;
- *-*-darwin* | *-*-freebsd*)
- ac_fn_c_check_func "$LINENO" "__stack_chk_fail" "ac_cv_func___stack_chk_fail"
-if test "x$ac_cv_func___stack_chk_fail" = x""yes; then :
- gcc_cv_libc_provides_ssp=yes
-else
- echo "no __stack_chk_fail on this target"
-fi
-
- ;;
- *) gcc_cv_libc_provides_ssp=no ;;
- esac
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_libc_provides_ssp" >&5
-$as_echo "$gcc_cv_libc_provides_ssp" >&6; }
-
-if test x$gcc_cv_libc_provides_ssp = xyes; then
-
-$as_echo "#define TARGET_LIBC_PROVIDES_SSP 1" >>confdefs.h
-
-fi
-
-# Test for <sys/sdt.h> on the target.
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking sys/sdt.h in the target C library" >&5
-$as_echo_n "checking sys/sdt.h in the target C library... " >&6; }
-have_sys_sdt_h=no
-if test -f $target_header_dir/sys/sdt.h; then
- have_sys_sdt_h=yes
-
-$as_echo "#define HAVE_SYS_SDT_H 1" >>confdefs.h
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_sys_sdt_h" >&5
-$as_echo "$have_sys_sdt_h" >&6; }
-
-# Check if TFmode long double should be used by default or not.
-# Some glibc targets used DFmode long double, but with glibc 2.4
-# and later they can use TFmode.
-case "$target" in
- powerpc*-*-linux* | \
- sparc*-*-linux* | \
- s390*-*-linux* | \
- alpha*-*-linux*)
-
-# Check whether --with-long-double-128 was given.
-if test "${with_long_double_128+set}" = set; then :
- withval=$with_long_double_128; gcc_cv_target_ldbl128="$with_long_double_128"
-else
- gcc_cv_target_ldbl128=no
- grep '^[ ]*#[ ]*define[ ][ ]*__LONG_DOUBLE_MATH_OPTIONAL' \
- $target_header_dir/bits/wordsize.h > /dev/null 2>&1 \
- && gcc_cv_target_ldbl128=yes
-
-fi
-
- ;;
-esac
-if test x$gcc_cv_target_ldbl128 = xyes; then
-
-$as_echo "#define TARGET_DEFAULT_LONG_DOUBLE_128 1" >>confdefs.h
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dl_iterate_phdr in target C library" >&5
-$as_echo_n "checking dl_iterate_phdr in target C library... " >&6; }
-gcc_cv_target_dl_iterate_phdr=unknown
-case "$target" in
- # Restrict to Solaris 11+. While most of the Solaris 11 linker changes
- # were backported to Solaris 10 Update 10, dl_iterate_phdr only lives in
- # libdl there, both complicating its use and breaking compatibility
- # between Solaris 10 updates.
- *-*-solaris2.1[1-9]*)
- # <link.h> needs both a dl_iterate_phdr declaration and support for
- # compilation with largefile support.
- if grep dl_iterate_phdr $target_header_dir/link.h > /dev/null 2>&1 \
- && grep 'large file capable' $target_header_dir/link.h > /dev/null 2>&1; then
- gcc_cv_target_dl_iterate_phdr=yes
- else
- gcc_cv_target_dl_iterate_phdr=no
- fi
- ;;
-esac
-
-if test x$gcc_cv_target_dl_iterate_phdr = xyes; then
-
-$as_echo "#define TARGET_DL_ITERATE_PHDR 1" >>confdefs.h
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_target_dl_iterate_phdr" >&5
-$as_echo "$gcc_cv_target_dl_iterate_phdr" >&6; }
-
-# We no longer support different GC mechanisms. Emit an error if
-# the user configures with --with-gc.
-
-# Check whether --with-gc was given.
-if test "${with_gc+set}" = set; then :
- withval=$with_gc; as_fn_error "Configure option --with-gc is only supported up to GCC 4.7.x" "$LINENO" 5
-fi
-
-
-# Libraries to use on the host. This will normally be set by the top
-# level Makefile. Here we simply capture the value for our Makefile.
-if test -z "${HOST_LIBS+set}"; then
- HOST_LIBS=
-fi
-
-
-# Use the system's zlib library.
-zlibdir=-L../zlib
-zlibinc="-I\$(srcdir)/../zlib"
-
-# Check whether --with-system-zlib was given.
-if test "${with_system_zlib+set}" = set; then :
- withval=$with_system_zlib; zlibdir=
-zlibinc=
-
-fi
-
-
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
-$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
- # Check whether --enable-maintainer-mode was given.
-if test "${enable_maintainer_mode+set}" = set; then :
- enableval=$enable_maintainer_mode; maintainer_mode=$enableval
-else
- maintainer_mode=no
-fi
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $maintainer_mode" >&5
-$as_echo "$maintainer_mode" >&6; }
-
-if test "$maintainer_mode" = "yes"; then
- MAINT=''
-else
- MAINT='#'
-fi
-
-# --------------
-# Language hooks
-# --------------
-
-# Make empty files to contain the specs and options for each language.
-# Then add #include lines to for a compiler that has specs and/or options.
-
-subdirs=
-lang_opt_files=
-lang_specs_files=
-lang_tree_files=
-# These (without "all_") are set in each config-lang.in.
-# `language' must be a single word so is spelled singularly.
-all_languages=
-all_compilers=
-all_outputs='Makefile'
-# List of language makefile fragments.
-all_lang_makefrags=
-# Additional files for gengtype
-all_gtfiles="$target_gtfiles"
-
-# These are the languages that are set in --enable-languages,
-# and are available in the GCC tree.
-all_selected_languages=
-
-# Add the language fragments.
-# Languages are added via two mechanisms. Some information must be
-# recorded in makefile variables, these are defined in config-lang.in.
-# We accumulate them and plug them into the main Makefile.
-# The other mechanism is a set of hooks for each of the main targets
-# like `clean', `install', etc.
-
-language_hooks="Make-hooks"
-
-for lang in ${srcdir}/*/config-lang.in
-do
- test "$lang" = "${srcdir}/*/config-lang.in" && continue
-
- lang_alias=`sed -n -e 's,^language=['"'"'"'"]\(.*\)["'"'"'"'].*$,\1,p' -e 's,^language=\([^ ]*\).*$,\1,p' $lang`
- if test "x$lang_alias" = x
- then
- echo "$lang doesn't set \$language." 1>&2
- exit 1
- fi
- subdir="`echo $lang | sed -e 's,^.*/\([^/]*\)/config-lang.in$,\1,'`"
- subdirs="$subdirs $subdir"
-
- # $gcc_subdir is where the gcc integration files are to be found
- # for a language, both for internal compiler purposes (compiler
- # sources implementing front-end to GCC tree converters), and for
- # build infrastructure purposes (Make-lang.in, etc.)
- #
- # This will be <subdir> (relative to $srcdir) if a line like
- # gcc_subdir="<subdir>" or gcc_subdir=<subdir>
- # is found in <langdir>/config-lang.in, and will remain <langdir>
- # otherwise.
- #
- # Except for the language alias (fetched above), the regular
- # "config-lang.in" contents are always retrieved from $gcc_subdir,
- # so a <langdir>/config-lang.in setting gcc_subdir typically sets
- # only this and the language alias.
-
- gcc_subdir=`sed -n -e 's,^gcc_subdir=['"'"'"'"]\(.*\)["'"'"'"'].*$,\1,p' -e 's,^gcc_subdir=\([^ ]*\).*$,\1,p' $lang`
- if [ "$gcc_subdir" = "" ]; then
- gcc_subdir="$subdir"
- fi
-
- case ",$enable_languages," in
- *,$lang_alias,*)
- all_selected_languages="$all_selected_languages $lang_alias"
- if test -f $srcdir/$gcc_subdir/lang-specs.h; then
- lang_specs_files="$lang_specs_files $srcdir/$gcc_subdir/lang-specs.h"
- fi
- ;;
- esac
-
- language=
- boot_language=
- compilers=
- outputs=
- gtfiles=
- subdir_requires=
- . ${srcdir}/$gcc_subdir/config-lang.in
- if test "x$language" = x
- then
- echo "${srcdir}/$gcc_subdir/config-lang.in doesn't set \$language." 1>&2
- exit 1
- fi
-
- ok=:
- case ",$enable_languages," in
- *,$lang_alias,*) ;;
- *)
- for i in $subdir_requires; do
- test -f "${srcdir}/$i/config-lang.in" && continue
- ok=false
- break
- done
- ;;
- esac
- $ok || continue
-
- all_lang_makefrags="$all_lang_makefrags \$(srcdir)/$gcc_subdir/Make-lang.in"
- if test -f $srcdir/$gcc_subdir/lang.opt; then
- lang_opt_files="$lang_opt_files $srcdir/$gcc_subdir/lang.opt"
- all_opt_files="$all_opt_files $srcdir/$gcc_subdir/lang.opt"
- fi
- if test -f $srcdir/$gcc_subdir/$subdir-tree.def; then
- lang_tree_files="$lang_tree_files $srcdir/$gcc_subdir/$subdir-tree.def"
- fi
- all_languages="$all_languages $language"
- all_compilers="$all_compilers $compilers"
- all_outputs="$all_outputs $outputs"
- all_gtfiles="$all_gtfiles [$subdir] $gtfiles"
- case ",$enable_languages," in
- *,lto,*)
-
-$as_echo "#define ENABLE_LTO 1" >>confdefs.h
-
- enable_lto=yes
-
- ;;
- *) ;;
- esac
-done
-
-check_languages=
-for language in $all_selected_languages
-do
- check_languages="$check_languages check-$language"
-done
-
-# We link each language in with a set of hooks, reached indirectly via
-# lang.${target}. Only do so for selected languages.
-
-rm -f Make-hooks
-touch Make-hooks
-target_list="all.cross start.encap rest.encap tags \
- install-common install-man install-info install-pdf install-html dvi \
- pdf html uninstall info man srcextra srcman srcinfo \
- mostlyclean clean distclean maintainer-clean install-plugin"
-
-for t in $target_list
-do
- x=
- for lang in $all_selected_languages
- do
- x="$x $lang.$t"
- done
- echo "lang.$t: $x" >> Make-hooks
-done
-
-# --------
-# Option include files
-# --------
-
-${AWK} -f $srcdir/opt-include.awk $all_opt_files > option-includes.mk
-option_includes="option-includes.mk"
-
-
-# --------
-# UNSORTED
-# --------
-
-# Create .gdbinit.
-
-echo "dir ." > .gdbinit
-echo "dir ${srcdir}" >> .gdbinit
-if test x$gdb_needs_out_file_path = xyes
-then
- echo "dir ${srcdir}/config/"`dirname ${out_file}` >> .gdbinit
-fi
-if test "x$subdirs" != x; then
- for s in $subdirs
- do
- echo "dir ${srcdir}/$s" >> .gdbinit
- done
-fi
-echo "source ${srcdir}/gdbinit.in" >> .gdbinit
-
-gcc_tooldir='$(libsubdir)/$(libsubdir_to_prefix)$(target_noncanonical)'
-
-
-
-# Find a directory in which to install a shared libgcc.
-
-# Check whether --enable-version-specific-runtime-libs was given.
-if test "${enable_version_specific_runtime_libs+set}" = set; then :
- enableval=$enable_version_specific_runtime_libs;
-fi
-
-
-# Substitute configuration variables
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# Echo link setup.
-if test x${build} = x${host} ; then
- if test x${host} = x${target} ; then
- echo "Links are now set up to build a native compiler for ${target}." 1>&2
- else
- echo "Links are now set up to build a cross-compiler" 1>&2
- echo " from ${host} to ${target}." 1>&2
- fi
-else
- if test x${host} = x${target} ; then
- echo "Links are now set up to build (on ${build}) a native compiler" 1>&2
- echo " for ${target}." 1>&2
- else
- echo "Links are now set up to build (on ${build}) a cross-compiler" 1>&2
- echo " from ${host} to ${target}." 1>&2
- fi
-fi
-
-
-
-
-
-
-
-
-
-if test "x${CLOOGLIBS}" != "x" ; then
-
-$as_echo "#define HAVE_cloog 1" >>confdefs.h
-
-fi
-
-# Check for plugin support
-# Check whether --enable-plugin was given.
-if test "${enable_plugin+set}" = set; then :
- enableval=$enable_plugin; enable_plugin=$enableval
-else
- enable_plugin=yes; default_plugin=yes
-fi
-
-
-pluginlibs=
-
-case "${host}" in
- *-*-darwin*)
- if test x$build = x$host; then
- export_sym_check="nm${exeext} -g"
- elif test x$host = x$target; then
- export_sym_check="$gcc_cv_nm -g"
- else
- export_sym_check=
- fi
- ;;
- *)
- if test x$build = x$host; then
- export_sym_check="objdump${exeext} -T"
- elif test x$host = x$target; then
- export_sym_check="$gcc_cv_objdump -T"
- else
- export_sym_check=
- fi
- ;;
-esac
-
-if test x"$enable_plugin" = x"yes"; then
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for exported symbols" >&5
-$as_echo_n "checking for exported symbols... " >&6; }
- if test "x$export_sym_check" != x; then
- echo "int main() {return 0;} int foobar() {return 0;}" > conftest.c
- ${CC} ${CFLAGS} ${LDFLAGS} conftest.c -o conftest > /dev/null 2>&1
- if $export_sym_check conftest | grep foobar > /dev/null; then
- : # No need to use a flag
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -rdynamic" >&5
-$as_echo_n "checking for -rdynamic... " >&6; }
- ${CC} ${CFLAGS} ${LDFLAGS} -rdynamic conftest.c -o conftest > /dev/null 2>&1
- if $export_sym_check conftest | grep foobar > /dev/null; then
- plugin_rdynamic=yes
- pluginlibs="-rdynamic"
- else
- plugin_rdynamic=no
- enable_plugin=no
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $plugin_rdynamic" >&5
-$as_echo "$plugin_rdynamic" >&6; }
- fi
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: unable to check" >&5
-$as_echo "unable to check" >&6; }
- fi
-
- # Check -ldl
- saved_LIBS="$LIBS"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5
-$as_echo_n "checking for library containing dlopen... " >&6; }
-if test "${ac_cv_search_dlopen+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dlopen ();
-int
-main ()
-{
-return dlopen ();
- ;
- return 0;
-}
-_ACEOF
-for ac_lib in '' dl; do
- if test -z "$ac_lib"; then
- ac_res="none required"
- else
- ac_res=-l$ac_lib
- LIBS="-l$ac_lib $ac_func_search_save_LIBS"
- fi
- if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_search_dlopen=$ac_res
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext
- if test "${ac_cv_search_dlopen+set}" = set; then :
- break
-fi
-done
-if test "${ac_cv_search_dlopen+set}" = set; then :
-
-else
- ac_cv_search_dlopen=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5
-$as_echo "$ac_cv_search_dlopen" >&6; }
-ac_res=$ac_cv_search_dlopen
-if test "$ac_res" != no; then :
- test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
-fi
-
- if test x"$ac_cv_search_dlopen" = x"-ldl"; then
- pluginlibs="$pluginlibs -ldl"
- fi
- LIBS="$saved_LIBS"
-
- # Check that we can build shared objects with -fPIC -shared
- saved_LDFLAGS="$LDFLAGS"
- saved_CFLAGS="$CFLAGS"
- case "${host}" in
- *-*-darwin*)
- CFLAGS=`echo $CFLAGS | sed s/-mdynamic-no-pic//g`
- CFLAGS="$CFLAGS -fPIC"
- LDFLAGS="$LDFLAGS -shared -undefined dynamic_lookup"
- ;;
- *)
- CFLAGS="$CFLAGS -fPIC"
- LDFLAGS="$LDFLAGS -fPIC -shared"
- ;;
- esac
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fPIC -shared" >&5
-$as_echo_n "checking for -fPIC -shared... " >&6; }
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-extern int X;
-int
-main ()
-{
-return X == 0;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }; have_pic_shared=yes
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }; have_pic_shared=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- if test x"$have_pic_shared" != x"yes" -o x"$ac_cv_search_dlopen" = x"no"; then
- pluginlibs=
- enable_plugin=no
- fi
- LDFLAGS="$saved_LDFLAGS"
- CFLAGS="$saved_CFLAGS"
-
- # If plugin support had been requested but not available, fail.
- if test x"$enable_plugin" = x"no" ; then
- if test x"$default_plugin" != x"yes"; then
- as_fn_error "
-Building GCC with plugin support requires a host that supports
--fPIC, -shared, -ldl and -rdynamic." "$LINENO" 5
- fi
- fi
-fi
-
-
-
-if test x"$enable_plugin" = x"yes"; then
-
-$as_echo "#define ENABLE_PLUGIN 1" >>confdefs.h
-
-fi
-
-
-# Check whether --enable-libquadmath-support was given.
-if test "${enable_libquadmath_support+set}" = set; then :
- enableval=$enable_libquadmath_support; ENABLE_LIBQUADMATH_SUPPORT=$enableval
-else
- ENABLE_LIBQUADMATH_SUPPORT=yes
-fi
-
-if test "${ENABLE_LIBQUADMATH_SUPPORT}" != "no" ; then
-
-$as_echo "#define ENABLE_LIBQUADMATH_SUPPORT 1" >>confdefs.h
-
-fi
-
-
-# Specify what hash style to use by default.
-
-# Check whether --with-linker-hash-style was given.
-if test "${with_linker_hash_style+set}" = set; then :
- withval=$with_linker_hash_style; case x"$withval" in
- xsysv)
- LINKER_HASH_STYLE=sysv
- ;;
- xgnu)
- LINKER_HASH_STYLE=gnu
- ;;
- xboth)
- LINKER_HASH_STYLE=both
- ;;
- *)
- as_fn_error "$withval is an invalid option to --with-linker-hash-style" "$LINENO" 5
- ;;
- esac
-else
- LINKER_HASH_STYLE=''
-fi
-
-if test x"${LINKER_HASH_STYLE}" != x; then
-
-cat >>confdefs.h <<_ACEOF
-#define LINKER_HASH_STYLE "$LINKER_HASH_STYLE"
-_ACEOF
-
-fi
-
-# Configure the subdirectories
-# AC_CONFIG_SUBDIRS($subdirs)
-
-# Create the Makefile
-# and configure language subdirectories
-ac_config_files="$ac_config_files $all_outputs"
-
-
-ac_config_commands="$ac_config_commands default"
-
-cat >confcache <<\_ACEOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs, see configure's option --config-cache.
-# It is not useful on other systems. If it contains results you don't
-# want to keep, you may remove or edit it.
-#
-# config.status only pays attention to the cache file if you give it
-# the --recheck option to rerun configure.
-#
-# `ac_cv_env_foo' variables (set or unset) will be overridden when
-# loading this file, other *unset* `ac_cv_foo' will be assigned the
-# following values.
-
-_ACEOF
-
-# The following way of writing the cache mishandles newlines in values,
-# but we know of no workaround that is simple, portable, and efficient.
-# So, we kill variables containing newlines.
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-(
- for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
- eval ac_val=\$$ac_var
- case $ac_val in #(
- *${as_nl}*)
- case $ac_var in #(
- *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
- esac
- case $ac_var in #(
- _ | IFS | as_nl) ;; #(
- BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
- *) { eval $ac_var=; unset $ac_var;} ;;
- esac ;;
- esac
- done
-
- (set) 2>&1 |
- case $as_nl`(ac_space=' '; set) 2>&1` in #(
- *${as_nl}ac_space=\ *)
- # `set' does not quote correctly, so add quotes: double-quote
- # substitution turns \\\\ into \\, and sed turns \\ into \.
- sed -n \
- "s/'/'\\\\''/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
- ;; #(
- *)
- # `set' quotes correctly as required by POSIX, so do not add quotes.
- sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
- ;;
- esac |
- sort
-) |
- sed '
- /^ac_cv_env_/b end
- t clear
- :clear
- s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
- t end
- s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
- :end' >>confcache
-if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
- if test -w "$cache_file"; then
- test "x$cache_file" != "x/dev/null" &&
- { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
-$as_echo "$as_me: updating cache $cache_file" >&6;}
- cat confcache >$cache_file
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
-$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
- fi
-fi
-rm -f confcache
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-
-DEFS=-DHAVE_CONFIG_H
-
-ac_libobjs=
-ac_ltlibobjs=
-for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
- # 1. Remove the extension, and $U if already installed.
- ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
- ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
- # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
- # will be set to the directory where LIBOBJS objects are built.
- as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
- as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
-done
-LIBOBJS=$ac_libobjs
-
-LTLIBOBJS=$ac_ltlibobjs
-
-
-
-
-: ${CONFIG_STATUS=./config.status}
-ac_write_fail=0
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
-$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
-as_write_fail=0
-cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
-#! $SHELL
-# Generated by $as_me.
-# Run this file to recreate the current configuration.
-# Compiler output produced by configure, useful for debugging
-# configure, is in config.log if it exists.
-
-debug=false
-ac_cs_recheck=false
-ac_cs_silent=false
-
-SHELL=\${CONFIG_SHELL-$SHELL}
-export SHELL
-_ASEOF
-cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
-## -------------------- ##
-## M4sh Initialization. ##
-## -------------------- ##
-
-# Be more Bourne compatible
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
- emulate sh
- NULLCMD=:
- # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in #(
- *posix*) :
- set -o posix ;; #(
- *) :
- ;;
-esac
-fi
-
-
-as_nl='
-'
-export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
- && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
- as_echo='print -r --'
- as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
- as_echo='printf %s\n'
- as_echo_n='printf %s'
-else
- if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
- as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
- as_echo_n='/usr/ucb/echo -n'
- else
- as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
- as_echo_n_body='eval
- arg=$1;
- case $arg in #(
- *"$as_nl"*)
- expr "X$arg" : "X\\(.*\\)$as_nl";
- arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
- esac;
- expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
- '
- export as_echo_n_body
- as_echo_n='sh -c $as_echo_n_body as_echo'
- fi
- export as_echo_body
- as_echo='sh -c $as_echo_body as_echo'
-fi
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- PATH_SEPARATOR=:
- (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
- (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
- PATH_SEPARATOR=';'
- }
-fi
-
-
-# IFS
-# We need space, tab and new line, in precisely that order. Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" "" $as_nl"
-
-# Find who we are. Look in the path if we contain no directory separator.
-case $0 in #((
- *[\\/]* ) as_myself=$0 ;;
- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
- done
-IFS=$as_save_IFS
-
- ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
- as_myself=$0
-fi
-if test ! -f "$as_myself"; then
- $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
- exit 1
-fi
-
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there. '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
- && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-
-# as_fn_error ERROR [LINENO LOG_FD]
-# ---------------------------------
-# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
-# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with status $?, using 1 if that was 0.
-as_fn_error ()
-{
- as_status=$?; test $as_status -eq 0 && as_status=1
- if test "$3"; then
- as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
- fi
- $as_echo "$as_me: error: $1" >&2
- as_fn_exit $as_status
-} # as_fn_error
-
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-
-# as_fn_unset VAR
-# ---------------
-# Portably unset VAR.
-as_fn_unset ()
-{
- { eval $1=; unset $1;}
-}
-as_unset=as_fn_unset
-# as_fn_append VAR VALUE
-# ----------------------
-# Append the text in VALUE to the end of the definition contained in VAR. Take
-# advantage of any shell optimizations that allow amortized linear growth over
-# repeated appends, instead of the typical quadratic growth present in naive
-# implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
- eval 'as_fn_append ()
- {
- eval $1+=\$2
- }'
-else
- as_fn_append ()
- {
- eval $1=\$$1\$2
- }
-fi # as_fn_append
-
-# as_fn_arith ARG...
-# ------------------
-# Perform arithmetic evaluation on the ARGs, and store the result in the
-# global $as_val. Take advantage of shells that can avoid forks. The arguments
-# must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
- eval 'as_fn_arith ()
- {
- as_val=$(( $* ))
- }'
-else
- as_fn_arith ()
- {
- as_val=`expr "$@" || test $? -eq 1`
- }
-fi # as_fn_arith
-
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
- as_dirname=dirname
-else
- as_dirname=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in #(((((
--n*)
- case `echo 'xy\c'` in
- *c*) ECHO_T=' ';; # ECHO_T is single tab character.
- xy) ECHO_C='\c';;
- *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
- ECHO_T=' ';;
- esac;;
-*)
- ECHO_N='-n';;
-esac
-
-rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
- rm -f conf$$.dir/conf$$.file
-else
- rm -f conf$$.dir
- mkdir conf$$.dir 2>/dev/null
-fi
-if (echo >conf$$.file) 2>/dev/null; then
- if ln -s conf$$.file conf$$ 2>/dev/null; then
- as_ln_s='ln -s'
- # ... but there are two gotchas:
- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
- elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
- else
- as_ln_s='cp -p'
- fi
-else
- as_ln_s='cp -p'
-fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
-
-
-# as_fn_mkdir_p
-# -------------
-# Create "$as_dir" as a directory, including parents if necessary.
-as_fn_mkdir_p ()
-{
-
- case $as_dir in #(
- -*) as_dir=./$as_dir;;
- esac
- test -d "$as_dir" || eval $as_mkdir_p || {
- as_dirs=
- while :; do
- case $as_dir in #(
- *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
- *) as_qdir=$as_dir;;
- esac
- as_dirs="'$as_qdir' $as_dirs"
- as_dir=`$as_dirname -- "$as_dir" ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_dir" : 'X\(//\)[^/]' \| \
- X"$as_dir" : 'X\(//\)$' \| \
- X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- test -d "$as_dir" && break
- done
- test -z "$as_dirs" || eval "mkdir $as_dirs"
- } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
-
-
-} # as_fn_mkdir_p
-if mkdir -p . 2>/dev/null; then
- as_mkdir_p='mkdir -p "$as_dir"'
-else
- test -d ./-p && rmdir ./-p
- as_mkdir_p=false
-fi
-
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-exec 6>&1
-## ----------------------------------- ##
-## Main body of $CONFIG_STATUS script. ##
-## ----------------------------------- ##
-_ASEOF
-test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-# Save the log message, to keep $0 and so on meaningful, and to
-# report actual input values of CONFIG_FILES etc. instead of their
-# values after options handling.
-ac_log="
-This file was extended by $as_me, which was
-generated by GNU Autoconf 2.64. Invocation command line was
-
- CONFIG_FILES = $CONFIG_FILES
- CONFIG_HEADERS = $CONFIG_HEADERS
- CONFIG_LINKS = $CONFIG_LINKS
- CONFIG_COMMANDS = $CONFIG_COMMANDS
- $ $0 $@
-
-on `(hostname || uname -n) 2>/dev/null | sed 1q`
-"
-
-_ACEOF
-
-case $ac_config_files in *"
-"*) set x $ac_config_files; shift; ac_config_files=$*;;
-esac
-
-case $ac_config_headers in *"
-"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
-esac
-
-
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-# Files that config.status was made for.
-config_files="$ac_config_files"
-config_headers="$ac_config_headers"
-config_commands="$ac_config_commands"
-
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-ac_cs_usage="\
-\`$as_me' instantiates files and other configuration actions
-from templates according to the current configuration. Unless the files
-and actions are specified as TAGs, all are instantiated by default.
-
-Usage: $0 [OPTION]... [TAG]...
-
- -h, --help print this help, then exit
- -V, --version print version number and configuration settings, then exit
- -q, --quiet, --silent
- do not print progress messages
- -d, --debug don't remove temporary files
- --recheck update $as_me by reconfiguring in the same conditions
- --file=FILE[:TEMPLATE]
- instantiate the configuration file FILE
- --header=FILE[:TEMPLATE]
- instantiate the configuration header FILE
-
-Configuration files:
-$config_files
-
-Configuration headers:
-$config_headers
-
-Configuration commands:
-$config_commands
-
-Report bugs to the package provider."
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-ac_cs_version="\\
-config.status
-configured by $0, generated by GNU Autoconf 2.64,
- with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
-
-Copyright (C) 2009 Free Software Foundation, Inc.
-This config.status script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it."
-
-ac_pwd='$ac_pwd'
-srcdir='$srcdir'
-AWK='$AWK'
-test -n "\$AWK" || AWK=awk
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-# The default lists apply if the user does not specify any file.
-ac_need_defaults=:
-while test $# != 0
-do
- case $1 in
- --*=*)
- ac_option=`expr "X$1" : 'X\([^=]*\)='`
- ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
- ac_shift=:
- ;;
- *)
- ac_option=$1
- ac_optarg=$2
- ac_shift=shift
- ;;
- esac
-
- case $ac_option in
- # Handling of the options.
- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
- ac_cs_recheck=: ;;
- --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
- $as_echo "$ac_cs_version"; exit ;;
- --debug | --debu | --deb | --de | --d | -d )
- debug=: ;;
- --file | --fil | --fi | --f )
- $ac_shift
- case $ac_optarg in
- *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
- esac
- as_fn_append CONFIG_FILES " '$ac_optarg'"
- ac_need_defaults=false;;
- --header | --heade | --head | --hea )
- $ac_shift
- case $ac_optarg in
- *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
- esac
- as_fn_append CONFIG_HEADERS " '$ac_optarg'"
- ac_need_defaults=false;;
- --he | --h)
- # Conflict between --help and --header
- as_fn_error "ambiguous option: \`$1'
-Try \`$0 --help' for more information.";;
- --help | --hel | -h )
- $as_echo "$ac_cs_usage"; exit ;;
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil | --si | --s)
- ac_cs_silent=: ;;
-
- # This is an error.
- -*) as_fn_error "unrecognized option: \`$1'
-Try \`$0 --help' for more information." ;;
-
- *) as_fn_append ac_config_targets " $1"
- ac_need_defaults=false ;;
-
- esac
- shift
-done
-
-ac_configure_extra_args=
-
-if $ac_cs_silent; then
- exec 6>/dev/null
- ac_configure_extra_args="$ac_configure_extra_args --silent"
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-if \$ac_cs_recheck; then
- set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
- shift
- \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
- CONFIG_SHELL='$SHELL'
- export CONFIG_SHELL
- exec "\$@"
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-exec 5>>config.log
-{
- echo
- sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
-## Running $as_me. ##
-_ASBOX
- $as_echo "$ac_log"
-} >&5
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-#
-# INIT-COMMANDS
-#
-subdirs='$subdirs'
-
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-
-# Handling of arguments.
-for ac_config_target in $ac_config_targets
-do
- case $ac_config_target in
- "auto-host.h") CONFIG_HEADERS="$CONFIG_HEADERS auto-host.h:config.in" ;;
- "as") CONFIG_FILES="$CONFIG_FILES as:exec-tool.in" ;;
- "collect-ld") CONFIG_FILES="$CONFIG_FILES collect-ld:exec-tool.in" ;;
- "nm") CONFIG_FILES="$CONFIG_FILES nm:exec-tool.in" ;;
- "$all_outputs") CONFIG_FILES="$CONFIG_FILES $all_outputs" ;;
- "default") CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;;
-
- *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
- esac
-done
-
-
-# If the user did not use the arguments to specify the items to instantiate,
-# then the envvar interface is used. Set only those that are not.
-# We use the long form for the default assignment because of an extremely
-# bizarre bug on SunOS 4.1.3.
-if $ac_need_defaults; then
- test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
- test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
- test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
-fi
-
-# Have a temporary directory for convenience. Make it in the build tree
-# simply because there is no reason against having it here, and in addition,
-# creating and moving files from /tmp can sometimes cause problems.
-# Hook for its removal unless debugging.
-# Note that there is a small window in which the directory will not be cleaned:
-# after its creation but before its name has been assigned to `$tmp'.
-$debug ||
-{
- tmp=
- trap 'exit_status=$?
- { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
-' 0
- trap 'as_fn_exit 1' 1 2 13 15
-}
-# Create a (secure) tmp directory for tmp files.
-
-{
- tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
- test -n "$tmp" && test -d "$tmp"
-} ||
-{
- tmp=./conf$$-$RANDOM
- (umask 077 && mkdir "$tmp")
-} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
-
-# Set up the scripts for CONFIG_FILES section.
-# No need to generate them if there are no CONFIG_FILES.
-# This happens for instance with `./config.status config.h'.
-if test -n "$CONFIG_FILES"; then
-
-if $AWK 'BEGIN { getline <"/dev/null" }' </dev/null 2>/dev/null; then
- ac_cs_awk_getline=:
- ac_cs_awk_pipe_init=
- ac_cs_awk_read_file='
- while ((getline aline < (F[key])) > 0)
- print(aline)
- close(F[key])'
- ac_cs_awk_pipe_fini=
-else
- ac_cs_awk_getline=false
- ac_cs_awk_pipe_init="print \"cat <<'|#_!!_#|' &&\""
- ac_cs_awk_read_file='
- print "|#_!!_#|"
- print "cat " F[key] " &&"
- '$ac_cs_awk_pipe_init
- # The final `:' finishes the AND list.
- ac_cs_awk_pipe_fini='END { print "|#_!!_#|"; print ":" }'
-fi
-ac_cr=`echo X | tr X '\015'`
-# On cygwin, bash can eat \r inside `` if the user requested igncr.
-# But we know of no other shell where ac_cr would be empty at this
-# point, so we can use a bashism as a fallback.
-if test "x$ac_cr" = x; then
- eval ac_cr=\$\'\\r\'
-fi
-ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
-if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
- ac_cs_awk_cr='\r'
-else
- ac_cs_awk_cr=$ac_cr
-fi
-
-echo 'BEGIN {' >"$tmp/subs1.awk" &&
-_ACEOF
-
-# Create commands to substitute file output variables.
-{
- echo "cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1" &&
- echo 'cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&' &&
- echo "$ac_subst_files" | sed 's/.*/F["&"]="$&"/' &&
- echo "_ACAWK" &&
- echo "_ACEOF"
-} >conf$$files.sh &&
-. ./conf$$files.sh ||
- as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
-rm -f conf$$files.sh
-
-{
- echo "cat >conf$$subs.awk <<_ACEOF" &&
- echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
- echo "_ACEOF"
-} >conf$$subs.sh ||
- as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
-ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
-ac_delim='%!_!# '
-for ac_last_try in false false false false false :; do
- . ./conf$$subs.sh ||
- as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
-
- ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
- if test $ac_delim_n = $ac_delim_num; then
- break
- elif $ac_last_try; then
- as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
- else
- ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
- fi
-done
-rm -f conf$$subs.sh
-
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
-_ACEOF
-sed -n '
-h
-s/^/S["/; s/!.*/"]=/
-p
-g
-s/^[^!]*!//
-:repl
-t repl
-s/'"$ac_delim"'$//
-t delim
-:nl
-h
-s/\(.\{148\}\).*/\1/
-t more1
-s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
-p
-n
-b repl
-:more1
-s/["\\]/\\&/g; s/^/"/; s/$/"\\/
-p
-g
-s/.\{148\}//
-t nl
-:delim
-h
-s/\(.\{148\}\).*/\1/
-t more2
-s/["\\]/\\&/g; s/^/"/; s/$/"/
-p
-b
-:more2
-s/["\\]/\\&/g; s/^/"/; s/$/"\\/
-p
-g
-s/.\{148\}//
-t delim
-' <conf$$subs.awk | sed '
-/^[^""]/{
- N
- s/\n//
-}
-' >>$CONFIG_STATUS || ac_write_fail=1
-rm -f conf$$subs.awk
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-_ACAWK
-cat >>"\$tmp/subs1.awk" <<_ACAWK &&
- for (key in S) S_is_set[key] = 1
- FS = ""
- \$ac_cs_awk_pipe_init
-}
-{
- line = $ 0
- nfields = split(line, field, "@")
- substed = 0
- len = length(field[1])
- for (i = 2; i < nfields; i++) {
- key = field[i]
- keylen = length(key)
- if (S_is_set[key]) {
- value = S[key]
- line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
- len += length(value) + length(field[++i])
- substed = 1
- } else
- len += 1 + keylen
- }
- if (nfields == 3 && !substed) {
- key = field[2]
- if (F[key] != "" && line ~ /^[ ]*@.*@[ ]*$/) {
- \$ac_cs_awk_read_file
- next
- }
- }
- print line
-}
-\$ac_cs_awk_pipe_fini
-_ACAWK
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
- sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
-else
- cat
-fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
- || as_fn_error "could not setup config files machinery" "$LINENO" 5
-_ACEOF
-
-# VPATH may cause trouble with some makes, so we remove $(srcdir),
-# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
-# trailing colons and then remove the whole line if VPATH becomes empty
-# (actually we leave an empty line to preserve line numbers).
-if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=/{
-s/:*\$(srcdir):*/:/
-s/:*\${srcdir}:*/:/
-s/:*@srcdir@:*/:/
-s/^\([^=]*=[ ]*\):*/\1/
-s/:*$//
-s/^[^=]*=[ ]*$//
-}'
-fi
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-fi # test -n "$CONFIG_FILES"
-
-# Set up the scripts for CONFIG_HEADERS section.
-# No need to generate them if there are no CONFIG_HEADERS.
-# This happens for instance with `./config.status Makefile'.
-if test -n "$CONFIG_HEADERS"; then
-cat >"$tmp/defines.awk" <<\_ACAWK ||
-BEGIN {
-_ACEOF
-
-# Transform confdefs.h into an awk script `defines.awk', embedded as
-# here-document in config.status, that substitutes the proper values into
-# config.h.in to produce config.h.
-
-# Create a delimiter string that does not exist in confdefs.h, to ease
-# handling of long lines.
-ac_delim='%!_!# '
-for ac_last_try in false false :; do
- ac_t=`sed -n "/$ac_delim/p" confdefs.h`
- if test -z "$ac_t"; then
- break
- elif $ac_last_try; then
- as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5
- else
- ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
- fi
-done
-
-# For the awk script, D is an array of macro values keyed by name,
-# likewise P contains macro parameters if any. Preserve backslash
-# newline sequences.
-
-ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
-sed -n '
-s/.\{148\}/&'"$ac_delim"'/g
-t rset
-:rset
-s/^[ ]*#[ ]*define[ ][ ]*/ /
-t def
-d
-:def
-s/\\$//
-t bsnl
-s/["\\]/\\&/g
-s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
-D["\1"]=" \3"/p
-s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
-d
-:bsnl
-s/["\\]/\\&/g
-s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
-D["\1"]=" \3\\\\\\n"\\/p
-t cont
-s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
-t cont
-d
-:cont
-n
-s/.\{148\}/&'"$ac_delim"'/g
-t clear
-:clear
-s/\\$//
-t bsnlc
-s/["\\]/\\&/g; s/^/"/; s/$/"/p
-d
-:bsnlc
-s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
-b cont
-' <confdefs.h | sed '
-s/'"$ac_delim"'/"\\\
-"/g' >>$CONFIG_STATUS || ac_write_fail=1
-
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
- for (key in D) D_is_set[key] = 1
- FS = ""
-}
-/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
- line = \$ 0
- split(line, arg, " ")
- if (arg[1] == "#") {
- defundef = arg[2]
- mac1 = arg[3]
- } else {
- defundef = substr(arg[1], 2)
- mac1 = arg[2]
- }
- split(mac1, mac2, "(") #)
- macro = mac2[1]
- prefix = substr(line, 1, index(line, defundef) - 1)
- if (D_is_set[macro]) {
- # Preserve the white space surrounding the "#".
- print prefix "define", macro P[macro] D[macro]
- next
- } else {
- # Replace #undef with comments. This is necessary, for example,
- # in the case of _POSIX_SOURCE, which is predefined and required
- # on some systems where configure will not decide to define it.
- if (defundef == "undef") {
- print "/*", prefix defundef, macro, "*/"
- next
- }
- }
-}
-{ print }
-_ACAWK
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
- as_fn_error "could not setup config headers machinery" "$LINENO" 5
-fi # test -n "$CONFIG_HEADERS"
-
-
-eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS"
-shift
-for ac_tag
-do
- case $ac_tag in
- :[FHLC]) ac_mode=$ac_tag; continue;;
- esac
- case $ac_mode$ac_tag in
- :[FHL]*:*);;
- :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
- :[FH]-) ac_tag=-:-;;
- :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
- esac
- ac_save_IFS=$IFS
- IFS=:
- set x $ac_tag
- IFS=$ac_save_IFS
- shift
- ac_file=$1
- shift
-
- case $ac_mode in
- :L) ac_source=$1;;
- :[FH])
- ac_file_inputs=
- for ac_f
- do
- case $ac_f in
- -) ac_f="$tmp/stdin";;
- *) # Look for the file first in the build tree, then in the source tree
- # (if the path is not absolute). The absolute path cannot be DOS-style,
- # because $ac_f cannot contain `:'.
- test -f "$ac_f" ||
- case $ac_f in
- [\\/$]*) false;;
- *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
- esac ||
- as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
- esac
- case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
- as_fn_append ac_file_inputs " '$ac_f'"
- done
-
- # Let's still pretend it is `configure' which instantiates (i.e., don't
- # use $as_me), people would be surprised to read:
- # /* config.h. Generated by config.status. */
- configure_input='Generated from '`
- $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
- `' by configure.'
- if test x"$ac_file" != x-; then
- configure_input="$ac_file. $configure_input"
- { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
-$as_echo "$as_me: creating $ac_file" >&6;}
- fi
- # Neutralize special characters interpreted by sed in replacement strings.
- case $configure_input in #(
- *\&* | *\|* | *\\* )
- ac_sed_conf_input=`$as_echo "$configure_input" |
- sed 's/[\\\\&|]/\\\\&/g'`;; #(
- *) ac_sed_conf_input=$configure_input;;
- esac
-
- case $ac_tag in
- *:-:* | *:-) cat >"$tmp/stdin" \
- || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
- esac
- ;;
- esac
-
- ac_dir=`$as_dirname -- "$ac_file" ||
-$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$ac_file" : 'X\(//\)[^/]' \| \
- X"$ac_file" : 'X\(//\)$' \| \
- X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$ac_file" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- as_dir="$ac_dir"; as_fn_mkdir_p
- ac_builddir=.
-
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
- ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
- # A ".." for each directory in $ac_dir_suffix.
- ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
- case $ac_top_builddir_sub in
- "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
- *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
- esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
-
-case $srcdir in
- .) # We are building in place.
- ac_srcdir=.
- ac_top_srcdir=$ac_top_builddir_sub
- ac_abs_top_srcdir=$ac_pwd ;;
- [\\/]* | ?:[\\/]* ) # Absolute name.
- ac_srcdir=$srcdir$ac_dir_suffix;
- ac_top_srcdir=$srcdir
- ac_abs_top_srcdir=$srcdir ;;
- *) # Relative name.
- ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
- ac_top_srcdir=$ac_top_build_prefix$srcdir
- ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
-esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
-
- case $ac_mode in
- :F)
- #
- # CONFIG_FILE
- #
-
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-# If the template does not know about datarootdir, expand it.
-# FIXME: This hack should be removed a few years after 2.60.
-ac_datarootdir_hack=; ac_datarootdir_seen=
-ac_sed_dataroot='
-/datarootdir/ {
- p
- q
-}
-/@datadir@/p
-/@docdir@/p
-/@infodir@/p
-/@localedir@/p
-/@mandir@/p'
-case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
-*datarootdir*) ac_datarootdir_seen=yes;;
-*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
-$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
- ac_datarootdir_hack='
- s&@datadir@&$datadir&g
- s&@docdir@&$docdir&g
- s&@infodir@&$infodir&g
- s&@localedir@&$localedir&g
- s&@mandir@&$mandir&g
- s&\\\${datarootdir}&$datarootdir&g' ;;
-esac
-_ACEOF
-
-# Neutralize VPATH when `$srcdir' = `.'.
-# Shell code in configure.ac might set extrasub.
-# FIXME: do we really want to maintain this feature?
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-ac_sed_extra="$ac_vpsub
-$extrasub
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-:t
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
-s|@configure_input@|$ac_sed_conf_input|;t t
-s&@top_builddir@&$ac_top_builddir_sub&;t t
-s&@top_build_prefix@&$ac_top_build_prefix&;t t
-s&@srcdir@&$ac_srcdir&;t t
-s&@abs_srcdir@&$ac_abs_srcdir&;t t
-s&@top_srcdir@&$ac_top_srcdir&;t t
-s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
-s&@builddir@&$ac_builddir&;t t
-s&@abs_builddir@&$ac_abs_builddir&;t t
-s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
-$ac_datarootdir_hack
-"
-eval sed \"\$ac_sed_extra\" "$ac_file_inputs" |
-if $ac_cs_awk_getline; then
- $AWK -f "$tmp/subs.awk"
-else
- $AWK -f "$tmp/subs.awk" | $SHELL
-fi >$tmp/out \
- || as_fn_error "could not create $ac_file" "$LINENO" 5
-
-test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
- { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
- { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined. Please make sure it is defined." >&5
-$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined. Please make sure it is defined." >&2;}
-
- rm -f "$tmp/stdin"
- case $ac_file in
- -) cat "$tmp/out" && rm -f "$tmp/out";;
- *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
- esac \
- || as_fn_error "could not create $ac_file" "$LINENO" 5
- ;;
- :H)
- #
- # CONFIG_HEADER
- #
- if test x"$ac_file" != x-; then
- {
- $as_echo "/* $configure_input */" \
- && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
- } >"$tmp/config.h" \
- || as_fn_error "could not create $ac_file" "$LINENO" 5
- if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
-$as_echo "$as_me: $ac_file is unchanged" >&6;}
- else
- rm -f "$ac_file"
- mv "$tmp/config.h" "$ac_file" \
- || as_fn_error "could not create $ac_file" "$LINENO" 5
- fi
- else
- $as_echo "/* $configure_input */" \
- && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
- || as_fn_error "could not create -" "$LINENO" 5
- fi
- ;;
-
- :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
-$as_echo "$as_me: executing $ac_file commands" >&6;}
- ;;
- esac
-
-
- case $ac_file$ac_mode in
- "as":F) chmod +x as ;;
- "collect-ld":F) chmod +x collect-ld ;;
- "nm":F) chmod +x nm ;;
- "default":C)
-case ${CONFIG_HEADERS} in
- *auto-host.h:config.in*)
- echo > cstamp-h ;;
-esac
-# Make sure all the subdirs exist.
-for d in $subdirs doc build common c-family
-do
- test -d $d || mkdir $d
-done
- ;;
-
- esac
-done # for ac_tag
-
-
-as_fn_exit 0
-_ACEOF
-ac_clean_files=$ac_clean_files_save
-
-test $ac_write_fail = 0 ||
- as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
-
-
-# configure is writing to config.log, and then calls config.status.
-# config.status does its own redirection, appending to config.log.
-# Unfortunately, on DOS this fails, as config.log is still kept open
-# by configure, so config.status won't be able to write to it; its
-# output is simply discarded. So we exec the FD to /dev/null,
-# effectively closing config.log, so it can be properly (re)opened and
-# appended to by config.status. When coming back to configure, we
-# need to make the FD available again.
-if test "$no_create" != yes; then
- ac_cs_success=:
- ac_config_status_args=
- test "$silent" = yes &&
- ac_config_status_args="$ac_config_status_args --quiet"
- exec 5>/dev/null
- $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
- exec 5>>config.log
- # Use ||, not &&, to avoid exiting from the if with $? = 1, which
- # would make configure fail if this is the last instruction.
- $ac_cs_success || as_fn_exit $?
-fi
-if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
-$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
-fi
-
-
diff --git a/gcc-4.8/gcc/doc/invoke.texi.orig b/gcc-4.8/gcc/doc/invoke.texi.orig
deleted file mode 100644
index dbe2ad369..000000000
--- a/gcc-4.8/gcc/doc/invoke.texi.orig
+++ /dev/null
@@ -1,21078 +0,0 @@
-@c Copyright (C) 1988-2013 Free Software Foundation, Inc.
-@c This is part of the GCC manual.
-@c For copying conditions, see the file gcc.texi.
-
-@ignore
-@c man begin INCLUDE
-@include gcc-vers.texi
-@c man end
-
-@c man begin COPYRIGHT
-Copyright @copyright{} 1988-2013 Free Software Foundation, Inc.
-
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.3 or
-any later version published by the Free Software Foundation; with the
-Invariant Sections being ``GNU General Public License'' and ``Funding
-Free Software'', the Front-Cover texts being (a) (see below), and with
-the Back-Cover Texts being (b) (see below). A copy of the license is
-included in the gfdl(7) man page.
-
-(a) The FSF's Front-Cover Text is:
-
- A GNU Manual
-
-(b) The FSF's Back-Cover Text is:
-
- You have freedom to copy and modify this GNU Manual, like GNU
- software. Copies published by the Free Software Foundation raise
- funds for GNU development.
-@c man end
-@c Set file name and title for the man page.
-@setfilename gcc
-@settitle GNU project C and C++ compiler
-@c man begin SYNOPSIS
-gcc [@option{-c}|@option{-S}|@option{-E}] [@option{-std=}@var{standard}]
- [@option{-g}] [@option{-pg}] [@option{-O}@var{level}]
- [@option{-W}@var{warn}@dots{}] [@option{-Wpedantic}]
- [@option{-I}@var{dir}@dots{}] [@option{-L}@var{dir}@dots{}]
- [@option{-D}@var{macro}[=@var{defn}]@dots{}] [@option{-U}@var{macro}]
- [@option{-f}@var{option}@dots{}] [@option{-m}@var{machine-option}@dots{}]
- [@option{-o} @var{outfile}] [@@@var{file}] @var{infile}@dots{}
-
-Only the most useful options are listed here; see below for the
-remainder. @samp{g++} accepts mostly the same options as @samp{gcc}.
-@c man end
-@c man begin SEEALSO
-gpl(7), gfdl(7), fsf-funding(7),
-cpp(1), gcov(1), as(1), ld(1), gdb(1), adb(1), dbx(1), sdb(1)
-and the Info entries for @file{gcc}, @file{cpp}, @file{as},
-@file{ld}, @file{binutils} and @file{gdb}.
-@c man end
-@c man begin BUGS
-For instructions on reporting bugs, see
-@w{@value{BUGURL}}.
-@c man end
-@c man begin AUTHOR
-See the Info entry for @command{gcc}, or
-@w{@uref{http://gcc.gnu.org/onlinedocs/gcc/Contributors.html}},
-for contributors to GCC@.
-@c man end
-@end ignore
-
-@node Invoking GCC
-@chapter GCC Command Options
-@cindex GCC command options
-@cindex command options
-@cindex options, GCC command
-
-@c man begin DESCRIPTION
-When you invoke GCC, it normally does preprocessing, compilation,
-assembly and linking. The ``overall options'' allow you to stop this
-process at an intermediate stage. For example, the @option{-c} option
-says not to run the linker. Then the output consists of object files
-output by the assembler.
-
-Other options are passed on to one stage of processing. Some options
-control the preprocessor and others the compiler itself. Yet other
-options control the assembler and linker; most of these are not
-documented here, since you rarely need to use any of them.
-
-@cindex C compilation options
-Most of the command-line options that you can use with GCC are useful
-for C programs; when an option is only useful with another language
-(usually C++), the explanation says so explicitly. If the description
-for a particular option does not mention a source language, you can use
-that option with all supported languages.
-
-@cindex C++ compilation options
-@xref{Invoking G++,,Compiling C++ Programs}, for a summary of special
-options for compiling C++ programs.
-
-@cindex grouping options
-@cindex options, grouping
-The @command{gcc} program accepts options and file names as operands. Many
-options have multi-letter names; therefore multiple single-letter options
-may @emph{not} be grouped: @option{-dv} is very different from @w{@samp{-d
--v}}.
-
-@cindex order of options
-@cindex options, order
-You can mix options and other arguments. For the most part, the order
-you use doesn't matter. Order does matter when you use several
-options of the same kind; for example, if you specify @option{-L} more
-than once, the directories are searched in the order specified. Also,
-the placement of the @option{-l} option is significant.
-
-Many options have long names starting with @samp{-f} or with
-@samp{-W}---for example,
-@option{-fmove-loop-invariants}, @option{-Wformat} and so on. Most of
-these have both positive and negative forms; the negative form of
-@option{-ffoo} is @option{-fno-foo}. This manual documents
-only one of these two forms, whichever one is not the default.
-
-@c man end
-
-@xref{Option Index}, for an index to GCC's options.
-
-@menu
-* 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.
-* 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
- and Objective-C++.
-* Language Independent Options:: Controlling how diagnostics should be
- formatted.
-* Warning Options:: How picky should the compiler be?
-* Debugging Options:: Symbol tables, measurements, and debugging dumps.
-* Optimize Options:: How much optimization?
-* Preprocessor Options:: Controlling header files and macro definitions.
- Also, getting dependency information for Make.
-* Assembler Options:: Passing options to the assembler.
-* Link Options:: Specifying libraries and so on.
-* Directory Options:: Where to find header files and libraries.
- Where to find the compiler executable files.
-* Spec Files:: How to pass switches to sub-processes.
-* Target Options:: Running a cross-compiler, or an old version of GCC.
-* Submodel Options:: Specifying minor hardware or convention variations,
- such as 68010 vs 68020.
-* Code Gen Options:: Specifying conventions for function calls, data layout
- and register usage.
-* Environment Variables:: Env vars that affect GCC.
-* Precompiled Headers:: Compiling a header once, and using it many times.
-@end menu
-
-@c man begin OPTIONS
-
-@node Option Summary
-@section Option Summary
-
-Here is a summary of all the options, grouped by type. Explanations are
-in the following sections.
-
-@table @emph
-@item Overall Options
-@xref{Overall Options,,Options Controlling the Kind of Output}.
-@gccoptlist{-c -S -E -o @var{file} -no-canonical-prefixes @gol
--pipe -pass-exit-codes @gol
--x @var{language} -v -### --help@r{[}=@var{class}@r{[},@dots{}@r{]]} --target-help @gol
---version -wrapper @@@var{file} -fplugin=@var{file} -fplugin-arg-@var{name}=@var{arg} @gol
--fdump-ada-spec@r{[}-slim@r{]} -fada-spec-parent=@var{arg} -fdump-go-spec=@var{file}}
-
-@item C Language Options
-@xref{C Dialect Options,,Options Controlling C Dialect}.
-@gccoptlist{-ansi -std=@var{standard} -fgnu89-inline @gol
--aux-info @var{filename} -fallow-parameterless-variadic-functions @gol
--fno-asm -fno-builtin -fno-builtin-@var{function} @gol
--fhosted -ffreestanding -fopenmp -fms-extensions -fplan9-extensions @gol
--trigraphs -traditional -traditional-cpp @gol
--fallow-single-precision -fcond-mismatch -flax-vector-conversions @gol
--fsigned-bitfields -fsigned-char @gol
--funsigned-bitfields -funsigned-char}
-
-@item C++ Language Options
-@xref{C++ Dialect Options,,Options Controlling C++ Dialect}.
-@gccoptlist{-fabi-version=@var{n} -fno-access-control -fcheck-new @gol
--fconstexpr-depth=@var{n} -ffriend-injection @gol
--fno-elide-constructors @gol
--fno-enforce-eh-specs @gol
--ffor-scope -fno-for-scope -fno-gnu-keywords @gol
--fno-implicit-templates @gol
--fno-implicit-inline-templates @gol
--fno-implement-inlines -fms-extensions @gol
--fno-nonansi-builtins -fnothrow-opt -fno-operator-names @gol
--fno-optional-diags -fpermissive @gol
--fno-pretty-templates @gol
--frepo -fno-rtti -fstats -ftemplate-backtrace-limit=@var{n} @gol
--ftemplate-depth=@var{n} @gol
--fno-threadsafe-statics -fuse-cxa-atexit -fno-weak -nostdinc++ @gol
--fno-default-inline -fvisibility-inlines-hidden @gol
--fvisibility-ms-compat @gol
--fext-numeric-literals @gol
--Wabi -Wconversion-null -Wctor-dtor-privacy @gol
--Wdelete-non-virtual-dtor -Wliteral-suffix -Wnarrowing @gol
--Wnoexcept -Wnon-virtual-dtor -Wreorder @gol
--Weffc++ -Wstrict-null-sentinel @gol
--Wno-non-template-friend -Wold-style-cast @gol
--Woverloaded-virtual -Wno-pmf-conversions @gol
--Wsign-promo}
-
-@item Objective-C and Objective-C++ Language Options
-@xref{Objective-C and Objective-C++ Dialect Options,,Options Controlling
-Objective-C and Objective-C++ Dialects}.
-@gccoptlist{-fconstant-string-class=@var{class-name} @gol
--fgnu-runtime -fnext-runtime @gol
--fno-nil-receivers @gol
--fobjc-abi-version=@var{n} @gol
--fobjc-call-cxx-cdtors @gol
--fobjc-direct-dispatch @gol
--fobjc-exceptions @gol
--fobjc-gc @gol
--fobjc-nilcheck @gol
--fobjc-std=objc1 @gol
--freplace-objc-classes @gol
--fzero-link @gol
--gen-decls @gol
--Wassign-intercept @gol
--Wno-protocol -Wselector @gol
--Wstrict-selector-match @gol
--Wundeclared-selector}
-
-@item Language Independent Options
-@xref{Language Independent Options,,Options to Control Diagnostic Messages Formatting}.
-@gccoptlist{-fmessage-length=@var{n} @gol
--fdiagnostics-show-location=@r{[}once@r{|}every-line@r{]} @gol
--fdiagnostics-color=@r{[}auto@r{|}never@r{|}always@r{]} @gol
--fno-diagnostics-show-option -fno-diagnostics-show-caret}
-
-@item Warning Options
-@xref{Warning Options,,Options to Request or Suppress Warnings}.
-@gccoptlist{-fsyntax-only -fmax-errors=@var{n} -Wpedantic @gol
--pedantic-errors @gol
--w -Wextra -Wall -Waddress -Waggregate-return @gol
--Waggressive-loop-optimizations -Warray-bounds @gol
--Wno-attributes -Wno-builtin-macro-redefined @gol
--Wc++-compat -Wc++11-compat -Wcast-align -Wcast-qual @gol
--Wchar-subscripts -Wclobbered -Wcomment @gol
--Wconversion -Wcoverage-mismatch -Wno-cpp -Wno-deprecated @gol
--Wno-deprecated-declarations -Wdisabled-optimization @gol
--Wno-div-by-zero -Wdouble-promotion -Wempty-body -Wenum-compare @gol
--Wno-endif-labels -Werror -Werror=* @gol
--Wfatal-errors -Wfloat-equal -Wformat -Wformat=2 @gol
--Wno-format-contains-nul -Wno-format-extra-args -Wformat-nonliteral @gol
--Wformat-security -Wformat-y2k @gol
--Wframe-larger-than=@var{len} -Wno-free-nonheap-object -Wjump-misses-init @gol
--Wignored-qualifiers @gol
--Wimplicit -Wimplicit-function-declaration -Wimplicit-int @gol
--Winit-self -Winline -Wmaybe-uninitialized @gol
--Wno-int-to-pointer-cast -Wno-invalid-offsetof @gol
--Winvalid-pch -Wlarger-than=@var{len} -Wunsafe-loop-optimizations @gol
--Wlogical-op -Wlong-long @gol
--Wmain -Wmaybe-uninitialized -Wmissing-braces -Wmissing-field-initializers @gol
--Wmissing-include-dirs @gol
--Wno-mudflap @gol
--Wno-multichar -Wnonnull -Wno-overflow @gol
--Woverlength-strings -Wpacked -Wpacked-bitfield-compat -Wpadded @gol
--Wparentheses -Wpedantic-ms-format -Wno-pedantic-ms-format @gol
--Wpointer-arith -Wno-pointer-to-int-cast @gol
--Wredundant-decls -Wno-return-local-addr @gol
--Wreturn-type -Wsequence-point -Wshadow @gol
--Wsign-compare -Wsign-conversion -Wsizeof-pointer-memaccess @gol
--Wstack-protector -Wstack-usage=@var{len} -Wstrict-aliasing @gol
--Wstrict-aliasing=n @gol -Wstrict-overflow -Wstrict-overflow=@var{n} @gol
--Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{]} @gol
--Wmissing-format-attribute @gol
--Wswitch -Wswitch-default -Wswitch-enum -Wsync-nand @gol
--Wsystem-headers -Wtrampolines -Wtrigraphs -Wtype-limits -Wundef @gol
--Wuninitialized -Wunknown-pragmas -Wno-pragmas @gol
--Wunsuffixed-float-constants -Wunused -Wunused-function @gol
--Wunused-label -Wunused-local-typedefs -Wunused-parameter @gol
--Wno-unused-result -Wunused-value @gol -Wunused-variable @gol
--Wunused-but-set-parameter -Wunused-but-set-variable @gol
--Wuseless-cast -Wvariadic-macros -Wvector-operation-performance @gol
--Wvla -Wvolatile-register-var -Wwrite-strings -Wzero-as-null-pointer-constant}
-
-@item C and Objective-C-only Warning Options
-@gccoptlist{-Wbad-function-cast -Wmissing-declarations @gol
--Wmissing-parameter-type -Wmissing-prototypes -Wnested-externs @gol
--Wold-style-declaration -Wold-style-definition @gol
--Wstrict-prototypes -Wtraditional -Wtraditional-conversion @gol
--Wdeclaration-after-statement -Wpointer-sign}
-
-@item Debugging Options
-@xref{Debugging Options,,Options for Debugging Your Program or GCC}.
-@gccoptlist{-d@var{letters} -dumpspecs -dumpmachine -dumpversion @gol
--fsanitize=@var{style} @gol
--fdbg-cnt-list -fdbg-cnt=@var{counter-value-list} @gol
--fdisable-ipa-@var{pass_name} @gol
--fdisable-rtl-@var{pass_name} @gol
--fdisable-rtl-@var{pass-name}=@var{range-list} @gol
--fdisable-tree-@var{pass_name} @gol
--fdisable-tree-@var{pass-name}=@var{range-list} @gol
--fdump-noaddr -fdump-unnumbered -fdump-unnumbered-links @gol
--fdump-translation-unit@r{[}-@var{n}@r{]} @gol
--fdump-class-hierarchy@r{[}-@var{n}@r{]} @gol
--fdump-ipa-all -fdump-ipa-cgraph -fdump-ipa-inline @gol
--fdump-passes @gol
--fdump-statistics @gol
--fdump-tree-all @gol
--fdump-tree-original@r{[}-@var{n}@r{]} @gol
--fdump-tree-optimized@r{[}-@var{n}@r{]} @gol
--fdump-tree-cfg -fdump-tree-alias @gol
--fdump-tree-ch @gol
--fdump-tree-ssa@r{[}-@var{n}@r{]} -fdump-tree-pre@r{[}-@var{n}@r{]} @gol
--fdump-tree-ccp@r{[}-@var{n}@r{]} -fdump-tree-dce@r{[}-@var{n}@r{]} @gol
--fdump-tree-gimple@r{[}-raw@r{]} -fdump-tree-mudflap@r{[}-@var{n}@r{]} @gol
--fdump-tree-dom@r{[}-@var{n}@r{]} @gol
--fdump-tree-dse@r{[}-@var{n}@r{]} @gol
--fdump-tree-phiprop@r{[}-@var{n}@r{]} @gol
--fdump-tree-phiopt@r{[}-@var{n}@r{]} @gol
--fdump-tree-forwprop@r{[}-@var{n}@r{]} @gol
--fdump-tree-copyrename@r{[}-@var{n}@r{]} @gol
--fdump-tree-nrv -fdump-tree-vect @gol
--fdump-tree-sink @gol
--fdump-tree-sra@r{[}-@var{n}@r{]} @gol
--fdump-tree-forwprop@r{[}-@var{n}@r{]} @gol
--fdump-tree-fre@r{[}-@var{n}@r{]} @gol
--fdump-tree-vrp@r{[}-@var{n}@r{]} @gol
--ftree-vectorizer-verbose=@var{n} @gol
--fdump-tree-storeccp@r{[}-@var{n}@r{]} @gol
--fdump-final-insns=@var{file} @gol
--fcompare-debug@r{[}=@var{opts}@r{]} -fcompare-debug-second @gol
--feliminate-dwarf2-dups -fno-eliminate-unused-debug-types @gol
--feliminate-unused-debug-symbols -femit-class-debug-always @gol
--fenable-@var{kind}-@var{pass} @gol
--fenable-@var{kind}-@var{pass}=@var{range-list} @gol
--fdebug-types-section -fmem-report-wpa @gol
--fmem-report -fpre-ipa-mem-report -fpost-ipa-mem-report -fprofile-arcs @gol
--fopt-info @gol
--fopt-info-@var{options}@r{[}=@var{file}@r{]} @gol
--frandom-seed=@var{string} -fsched-verbose=@var{n} @gol
--fsel-sched-verbose -fsel-sched-dump-cfg -fsel-sched-pipelining-verbose @gol
--fstack-usage -ftest-coverage -ftime-report -fvar-tracking @gol
--fvar-tracking-assignments -fvar-tracking-assignments-toggle @gol
--g -g@var{level} -gtoggle -gcoff -gdwarf-@var{version} @gol
--ggdb -grecord-gcc-switches -gno-record-gcc-switches @gol
--gstabs -gstabs+ -gstrict-dwarf -gno-strict-dwarf @gol
--gvms -gxcoff -gxcoff+ @gol
--fno-merge-debug-strings -fno-dwarf2-cfi-asm @gol
--fdebug-prefix-map=@var{old}=@var{new} @gol
--femit-struct-debug-baseonly -femit-struct-debug-reduced @gol
--femit-struct-debug-detailed@r{[}=@var{spec-list}@r{]} @gol
--p -pg -print-file-name=@var{library} -print-libgcc-file-name @gol
--print-multi-directory -print-multi-lib -print-multi-os-directory @gol
--print-prog-name=@var{program} -print-search-dirs -Q @gol
--print-sysroot -print-sysroot-headers-suffix @gol
--save-temps -save-temps=cwd -save-temps=obj -time@r{[}=@var{file}@r{]}}
-
-@item Optimization Options
-@xref{Optimize Options,,Options that Control Optimization}.
-@gccoptlist{-faggressive-loop-optimizations -falign-functions[=@var{n}] @gol
--falign-jumps[=@var{n}] @gol
--falign-labels[=@var{n}] -falign-loops[=@var{n}] @gol
--fassociative-math -fauto-inc-dec -fbranch-probabilities @gol
--fbranch-target-load-optimize -fbranch-target-load-optimize2 @gol
--fbtr-bb-exclusive -fcaller-saves @gol
--fcheck-data-deps -fcombine-stack-adjustments -fconserve-stack @gol
--fcompare-elim -fcprop-registers -fcrossjumping @gol
--fcse-follow-jumps -fcse-skip-blocks -fcx-fortran-rules @gol
--fcx-limited-range @gol
--fdata-sections -fdce -fdelayed-branch @gol
--fdelete-null-pointer-checks -fdevirtualize -fdse @gol
--fearly-inlining -fipa-sra -fexpensive-optimizations -ffat-lto-objects @gol
--ffast-math -ffinite-math-only -ffloat-store -fexcess-precision=@var{style} @gol
--fforward-propagate -ffp-contract=@var{style} -ffunction-sections @gol
--fgcse -fgcse-after-reload -fgcse-las -fgcse-lm -fgraphite-identity @gol
--fgcse-sm -fhoist-adjacent-loads -fif-conversion @gol
--fif-conversion2 -findirect-inlining @gol
--finline-functions -finline-functions-called-once -finline-limit=@var{n} @gol
--finline-small-functions -fipa-cp -fipa-cp-clone @gol
--fipa-pta -fipa-profile -fipa-pure-const -fipa-reference @gol
--fira-algorithm=@var{algorithm} @gol
--fira-region=@var{region} -fira-hoist-pressure @gol
--fira-loop-pressure -fno-ira-share-save-slots @gol
--fno-ira-share-spill-slots -fira-verbose=@var{n} @gol
--fivopts -fkeep-inline-functions -fkeep-static-consts @gol
--floop-block -floop-interchange -floop-strip-mine -floop-nest-optimize @gol
--floop-parallelize-all -flto -flto-compression-level @gol
--flto-partition=@var{alg} -flto-report -fmerge-all-constants @gol
--fmerge-constants -fmodulo-sched -fmodulo-sched-allow-regmoves @gol
--fmove-loop-invariants fmudflap -fmudflapir -fmudflapth -fno-branch-count-reg @gol
--fno-default-inline @gol
--fno-defer-pop -fno-function-cse -fno-guess-branch-probability @gol
--fno-inline -fno-math-errno -fno-peephole -fno-peephole2 @gol
--fno-sched-interblock -fno-sched-spec -fno-signed-zeros @gol
--fno-toplevel-reorder -fno-trapping-math -fno-zero-initialized-in-bss @gol
--fomit-frame-pointer -foptimize-register-move -foptimize-sibling-calls @gol
--fpartial-inlining -fpeel-loops -fpredictive-commoning @gol
--fprefetch-loop-arrays -fprofile-report @gol
--fprofile-correction -fprofile-dir=@var{path} -fprofile-generate @gol
--fprofile-generate=@var{path} @gol
--fprofile-use -fprofile-use=@var{path} -fprofile-values @gol
--freciprocal-math -free -fregmove -frename-registers -freorder-blocks @gol
--freorder-blocks-and-partition -freorder-functions @gol
--frerun-cse-after-loop -freschedule-modulo-scheduled-loops @gol
--frounding-math -fsched2-use-superblocks -fsched-pressure @gol
--fsched-spec-load -fsched-spec-load-dangerous @gol
--fsched-stalled-insns-dep[=@var{n}] -fsched-stalled-insns[=@var{n}] @gol
--fsched-group-heuristic -fsched-critical-path-heuristic @gol
--fsched-spec-insn-heuristic -fsched-rank-heuristic @gol
--fsched-last-insn-heuristic -fsched-dep-count-heuristic @gol
--fschedule-insns -fschedule-insns2 -fsection-anchors @gol
--fselective-scheduling -fselective-scheduling2 @gol
--fsel-sched-pipelining -fsel-sched-pipelining-outer-loops @gol
--fshrink-wrap -fsignaling-nans -fsingle-precision-constant @gol
--fsplit-ivs-in-unroller -fsplit-wide-types -fstack-protector @gol
--fstack-protector-all -fstrict-aliasing -fstrict-overflow @gol
--fthread-jumps -ftracer -ftree-bit-ccp @gol
--ftree-builtin-call-dce -ftree-ccp -ftree-ch @gol
--ftree-coalesce-inline-vars -ftree-coalesce-vars -ftree-copy-prop @gol
--ftree-copyrename -ftree-dce -ftree-dominator-opts -ftree-dse @gol
--ftree-forwprop -ftree-fre -ftree-loop-if-convert @gol
--ftree-loop-if-convert-stores -ftree-loop-im @gol
--ftree-phiprop -ftree-loop-distribution -ftree-loop-distribute-patterns @gol
--ftree-loop-ivcanon -ftree-loop-linear -ftree-loop-optimize @gol
--ftree-parallelize-loops=@var{n} -ftree-pre -ftree-partial-pre -ftree-pta @gol
--ftree-reassoc -ftree-sink -ftree-slsr -ftree-sra @gol
--ftree-switch-conversion -ftree-tail-merge @gol
--ftree-ter -ftree-vect-loop-version -ftree-vectorize -ftree-vrp @gol
--funit-at-a-time -funroll-all-loops -funroll-loops @gol
--funsafe-loop-optimizations -funsafe-math-optimizations -funswitch-loops @gol
--fvariable-expansion-in-unroller -fvect-cost-model -fvpt -fweb @gol
--fwhole-program -fwpa -fuse-ld=@var{linker} -fuse-linker-plugin @gol
---param @var{name}=@var{value}
--O -O0 -O1 -O2 -O3 -Os -Ofast -Og}
-
-@item Preprocessor Options
-@xref{Preprocessor Options,,Options Controlling the Preprocessor}.
-@gccoptlist{-A@var{question}=@var{answer} @gol
--A-@var{question}@r{[}=@var{answer}@r{]} @gol
--C -dD -dI -dM -dN @gol
--D@var{macro}@r{[}=@var{defn}@r{]} -E -H @gol
--idirafter @var{dir} @gol
--include @var{file} -imacros @var{file} @gol
--iprefix @var{file} -iwithprefix @var{dir} @gol
--iwithprefixbefore @var{dir} -isystem @var{dir} @gol
--imultilib @var{dir} -isysroot @var{dir} @gol
--M -MM -MF -MG -MP -MQ -MT -nostdinc @gol
--P -fdebug-cpp -ftrack-macro-expansion -fworking-directory @gol
--remap -trigraphs -undef -U@var{macro} @gol
--Wp,@var{option} -Xpreprocessor @var{option} -no-integrated-cpp}
-
-@item Assembler Option
-@xref{Assembler Options,,Passing Options to the Assembler}.
-@gccoptlist{-Wa,@var{option} -Xassembler @var{option}}
-
-@item Linker Options
-@xref{Link Options,,Options for Linking}.
-@gccoptlist{@var{object-file-name} -l@var{library} @gol
--nostartfiles -nodefaultlibs -nostdlib -pie -rdynamic @gol
--s -static -static-libgcc -static-libstdc++ @gol
--static-libasan -static-libtsan @gol
--shared -shared-libgcc -symbolic @gol
--T @var{script} -Wl,@var{option} -Xlinker @var{option} @gol
--u @var{symbol}}
-
-@item Directory Options
-@xref{Directory Options,,Options for Directory Search}.
-@gccoptlist{-B@var{prefix} -I@var{dir} -iplugindir=@var{dir} @gol
--iquote@var{dir} -L@var{dir} -specs=@var{file} -I- @gol
---sysroot=@var{dir} --no-sysroot-suffix}
-
-@item Machine Dependent Options
-@xref{Submodel Options,,Hardware Models and Configurations}.
-@c This list is ordered alphanumerically by subsection name.
-@c Try and put the significant identifier (CPU or system) first,
-@c so users have a clue at guessing where the ones they want will be.
-
-@emph{AArch64 Options}
-@gccoptlist{-mbig-endian -mlittle-endian @gol
--mgeneral-regs-only @gol
--mcmodel=tiny -mcmodel=small -mcmodel=large @gol
--mstrict-align @gol
--momit-leaf-frame-pointer -mno-omit-leaf-frame-pointer @gol
--mtls-dialect=desc -mtls-dialect=traditional @gol
--march=@var{name} -mcpu=@var{name} -mtune=@var{name}}
-
-@emph{Adapteva Epiphany Options}
-@gccoptlist{-mhalf-reg-file -mprefer-short-insn-regs @gol
--mbranch-cost=@var{num} -mcmove -mnops=@var{num} -msoft-cmpsf @gol
--msplit-lohi -mpost-inc -mpost-modify -mstack-offset=@var{num} @gol
--mround-nearest -mlong-calls -mshort-calls -msmall16 @gol
--mfp-mode=@var{mode} -mvect-double -max-vect-align=@var{num} @gol
--msplit-vecmove-early -m1reg-@var{reg}}
-
-@emph{ARM Options}
-@gccoptlist{-mapcs-frame -mno-apcs-frame @gol
--mabi=@var{name} @gol
--mapcs-stack-check -mno-apcs-stack-check @gol
--mapcs-float -mno-apcs-float @gol
--mapcs-reentrant -mno-apcs-reentrant @gol
--msched-prolog -mno-sched-prolog @gol
--mlittle-endian -mbig-endian -mwords-little-endian @gol
--mfloat-abi=@var{name} @gol
--mfp16-format=@var{name}
--mthumb-interwork -mno-thumb-interwork @gol
--mcpu=@var{name} -march=@var{name} -mfpu=@var{name} @gol
--mstructure-size-boundary=@var{n} @gol
--mabort-on-noreturn @gol
--mlong-calls -mno-long-calls @gol
--msingle-pic-base -mno-single-pic-base @gol
--mpic-register=@var{reg} @gol
--mnop-fun-dllimport @gol
--mpoke-function-name @gol
--mthumb -marm @gol
--mtpcs-frame -mtpcs-leaf-frame @gol
--mcaller-super-interworking -mcallee-super-interworking @gol
--mtp=@var{name} -mtls-dialect=@var{dialect} @gol
--mword-relocations @gol
--mfix-cortex-m3-ldrd @gol
--munaligned-access}
-
-@emph{AVR Options}
-@gccoptlist{-mmcu=@var{mcu} -maccumulate-args -mbranch-cost=@var{cost} @gol
--mcall-prologues -mint8 -mno-interrupts -mrelax @gol
--mstrict-X -mtiny-stack -Waddr-space-convert}
-
-@emph{Blackfin Options}
-@gccoptlist{-mcpu=@var{cpu}@r{[}-@var{sirevision}@r{]} @gol
--msim -momit-leaf-frame-pointer -mno-omit-leaf-frame-pointer @gol
--mspecld-anomaly -mno-specld-anomaly -mcsync-anomaly -mno-csync-anomaly @gol
--mlow-64k -mno-low64k -mstack-check-l1 -mid-shared-library @gol
--mno-id-shared-library -mshared-library-id=@var{n} @gol
--mleaf-id-shared-library -mno-leaf-id-shared-library @gol
--msep-data -mno-sep-data -mlong-calls -mno-long-calls @gol
--mfast-fp -minline-plt -mmulticore -mcorea -mcoreb -msdram @gol
--micplb}
-
-@emph{C6X Options}
-@gccoptlist{-mbig-endian -mlittle-endian -march=@var{cpu} @gol
--msim -msdata=@var{sdata-type}}
-
-@emph{CRIS Options}
-@gccoptlist{-mcpu=@var{cpu} -march=@var{cpu} -mtune=@var{cpu} @gol
--mmax-stack-frame=@var{n} -melinux-stacksize=@var{n} @gol
--metrax4 -metrax100 -mpdebug -mcc-init -mno-side-effects @gol
--mstack-align -mdata-align -mconst-align @gol
--m32-bit -m16-bit -m8-bit -mno-prologue-epilogue -mno-gotplt @gol
--melf -maout -melinux -mlinux -sim -sim2 @gol
--mmul-bug-workaround -mno-mul-bug-workaround}
-
-@emph{CR16 Options}
-@gccoptlist{-mmac @gol
--mcr16cplus -mcr16c @gol
--msim -mint32 -mbit-ops
--mdata-model=@var{model}}
-
-@emph{Darwin Options}
-@gccoptlist{-all_load -allowable_client -arch -arch_errors_fatal @gol
--arch_only -bind_at_load -bundle -bundle_loader @gol
--client_name -compatibility_version -current_version @gol
--dead_strip @gol
--dependency-file -dylib_file -dylinker_install_name @gol
--dynamic -dynamiclib -exported_symbols_list @gol
--filelist -flat_namespace -force_cpusubtype_ALL @gol
--force_flat_namespace -headerpad_max_install_names @gol
--iframework @gol
--image_base -init -install_name -keep_private_externs @gol
--multi_module -multiply_defined -multiply_defined_unused @gol
--noall_load -no_dead_strip_inits_and_terms @gol
--nofixprebinding -nomultidefs -noprebind -noseglinkedit @gol
--pagezero_size -prebind -prebind_all_twolevel_modules @gol
--private_bundle -read_only_relocs -sectalign @gol
--sectobjectsymbols -whyload -seg1addr @gol
--sectcreate -sectobjectsymbols -sectorder @gol
--segaddr -segs_read_only_addr -segs_read_write_addr @gol
--seg_addr_table -seg_addr_table_filename -seglinkedit @gol
--segprot -segs_read_only_addr -segs_read_write_addr @gol
--single_module -static -sub_library -sub_umbrella @gol
--twolevel_namespace -umbrella -undefined @gol
--unexported_symbols_list -weak_reference_mismatches @gol
--whatsloaded -F -gused -gfull -mmacosx-version-min=@var{version} @gol
--mkernel -mone-byte-bool}
-
-@emph{DEC Alpha Options}
-@gccoptlist{-mno-fp-regs -msoft-float @gol
--mieee -mieee-with-inexact -mieee-conformant @gol
--mfp-trap-mode=@var{mode} -mfp-rounding-mode=@var{mode} @gol
--mtrap-precision=@var{mode} -mbuild-constants @gol
--mcpu=@var{cpu-type} -mtune=@var{cpu-type} @gol
--mbwx -mmax -mfix -mcix @gol
--mfloat-vax -mfloat-ieee @gol
--mexplicit-relocs -msmall-data -mlarge-data @gol
--msmall-text -mlarge-text @gol
--mmemory-latency=@var{time}}
-
-@emph{FR30 Options}
-@gccoptlist{-msmall-model -mno-lsim}
-
-@emph{FRV Options}
-@gccoptlist{-mgpr-32 -mgpr-64 -mfpr-32 -mfpr-64 @gol
--mhard-float -msoft-float @gol
--malloc-cc -mfixed-cc -mdword -mno-dword @gol
--mdouble -mno-double @gol
--mmedia -mno-media -mmuladd -mno-muladd @gol
--mfdpic -minline-plt -mgprel-ro -multilib-library-pic @gol
--mlinked-fp -mlong-calls -malign-labels @gol
--mlibrary-pic -macc-4 -macc-8 @gol
--mpack -mno-pack -mno-eflags -mcond-move -mno-cond-move @gol
--moptimize-membar -mno-optimize-membar @gol
--mscc -mno-scc -mcond-exec -mno-cond-exec @gol
--mvliw-branch -mno-vliw-branch @gol
--mmulti-cond-exec -mno-multi-cond-exec -mnested-cond-exec @gol
--mno-nested-cond-exec -mtomcat-stats @gol
--mTLS -mtls @gol
--mcpu=@var{cpu}}
-
-@emph{GNU/Linux Options}
-@gccoptlist{-mglibc -muclibc -mbionic -mandroid @gol
--tno-android-cc -tno-android-ld}
-
-@emph{H8/300 Options}
-@gccoptlist{-mrelax -mh -ms -mn -mexr -mno-exr -mint32 -malign-300}
-
-@emph{HPPA Options}
-@gccoptlist{-march=@var{architecture-type} @gol
--mbig-switch -mdisable-fpregs -mdisable-indexing @gol
--mfast-indirect-calls -mgas -mgnu-ld -mhp-ld @gol
--mfixed-range=@var{register-range} @gol
--mjump-in-delay -mlinker-opt -mlong-calls @gol
--mlong-load-store -mno-big-switch -mno-disable-fpregs @gol
--mno-disable-indexing -mno-fast-indirect-calls -mno-gas @gol
--mno-jump-in-delay -mno-long-load-store @gol
--mno-portable-runtime -mno-soft-float @gol
--mno-space-regs -msoft-float -mpa-risc-1-0 @gol
--mpa-risc-1-1 -mpa-risc-2-0 -mportable-runtime @gol
--mschedule=@var{cpu-type} -mspace-regs -msio -mwsio @gol
--munix=@var{unix-std} -nolibdld -static -threads}
-
-@emph{i386 and x86-64 Options}
-@gccoptlist{-mtune=@var{cpu-type} -march=@var{cpu-type} @gol
--mfpmath=@var{unit} @gol
--masm=@var{dialect} -mno-fancy-math-387 @gol
--mno-fp-ret-in-387 -msoft-float @gol
--mno-wide-multiply -mrtd -malign-double @gol
--mpreferred-stack-boundary=@var{num} @gol
--mincoming-stack-boundary=@var{num} @gol
--mcld -mcx16 -msahf -mmovbe -mcrc32 @gol
--mrecip -mrecip=@var{opt} @gol
--mvzeroupper -mprefer-avx128 @gol
--mmmx -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -msse4 -mavx @gol
--mavx2 -maes -mpclmul -mfsgsbase -mrdrnd -mf16c -mfma @gol
--msse4a -m3dnow -mpopcnt -mabm -mbmi -mtbm -mfma4 -mxop -mlzcnt @gol
--mbmi2 -mrtm -mlwp -mthreads @gol
--mno-align-stringops -minline-all-stringops @gol
--minline-stringops-dynamically -mstringop-strategy=@var{alg} @gol
--mpush-args -maccumulate-outgoing-args -m128bit-long-double @gol
--m96bit-long-double -mlong-double-64 -mlong-double-80 @gol
--mregparm=@var{num} -msseregparm @gol
--mveclibabi=@var{type} -mvect8-ret-in-mem @gol
--mpc32 -mpc64 -mpc80 -mstackrealign @gol
--momit-leaf-frame-pointer -mno-red-zone -mno-tls-direct-seg-refs @gol
--mcmodel=@var{code-model} -mabi=@var{name} -maddress-mode=@var{mode} @gol
--m32 -m64 -mx32 -mlarge-data-threshold=@var{num} @gol
--msse2avx -mfentry -m8bit-idiv @gol
--mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol
--mstack-protector-guard=@var{guard}}
-
-@emph{i386 and x86-64 Windows Options}
-@gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol
--mnop-fun-dllimport -mthread @gol
--municode -mwin32 -mwindows -fno-set-stack-executable}
-
-@emph{IA-64 Options}
-@gccoptlist{-mbig-endian -mlittle-endian -mgnu-as -mgnu-ld -mno-pic @gol
--mvolatile-asm-stop -mregister-names -msdata -mno-sdata @gol
--mconstant-gp -mauto-pic -mfused-madd @gol
--minline-float-divide-min-latency @gol
--minline-float-divide-max-throughput @gol
--mno-inline-float-divide @gol
--minline-int-divide-min-latency @gol
--minline-int-divide-max-throughput @gol
--mno-inline-int-divide @gol
--minline-sqrt-min-latency -minline-sqrt-max-throughput @gol
--mno-inline-sqrt @gol
--mdwarf2-asm -mearly-stop-bits @gol
--mfixed-range=@var{register-range} -mtls-size=@var{tls-size} @gol
--mtune=@var{cpu-type} -milp32 -mlp64 @gol
--msched-br-data-spec -msched-ar-data-spec -msched-control-spec @gol
--msched-br-in-data-spec -msched-ar-in-data-spec -msched-in-control-spec @gol
--msched-spec-ldc -msched-spec-control-ldc @gol
--msched-prefer-non-data-spec-insns -msched-prefer-non-control-spec-insns @gol
--msched-stop-bits-after-every-cycle -msched-count-spec-in-critical-path @gol
--msel-sched-dont-check-control-spec -msched-fp-mem-deps-zero-cost @gol
--msched-max-memory-insns-hard-limit -msched-max-memory-insns=@var{max-insns}}
-
-@emph{LM32 Options}
-@gccoptlist{-mbarrel-shift-enabled -mdivide-enabled -mmultiply-enabled @gol
--msign-extend-enabled -muser-enabled}
-
-@emph{M32R/D Options}
-@gccoptlist{-m32r2 -m32rx -m32r @gol
--mdebug @gol
--malign-loops -mno-align-loops @gol
--missue-rate=@var{number} @gol
--mbranch-cost=@var{number} @gol
--mmodel=@var{code-size-model-type} @gol
--msdata=@var{sdata-type} @gol
--mno-flush-func -mflush-func=@var{name} @gol
--mno-flush-trap -mflush-trap=@var{number} @gol
--G @var{num}}
-
-@emph{M32C Options}
-@gccoptlist{-mcpu=@var{cpu} -msim -memregs=@var{number}}
-
-@emph{M680x0 Options}
-@gccoptlist{-march=@var{arch} -mcpu=@var{cpu} -mtune=@var{tune}
--m68000 -m68020 -m68020-40 -m68020-60 -m68030 -m68040 @gol
--m68060 -mcpu32 -m5200 -m5206e -m528x -m5307 -m5407 @gol
--mcfv4e -mbitfield -mno-bitfield -mc68000 -mc68020 @gol
--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 @gol
--mxgot -mno-xgot}
-
-@emph{MCore Options}
-@gccoptlist{-mhardlit -mno-hardlit -mdiv -mno-div -mrelax-immediates @gol
--mno-relax-immediates -mwide-bitfields -mno-wide-bitfields @gol
--m4byte-functions -mno-4byte-functions -mcallgraph-data @gol
--mno-callgraph-data -mslow-bytes -mno-slow-bytes -mno-lsim @gol
--mlittle-endian -mbig-endian -m210 -m340 -mstack-increment}
-
-@emph{MeP Options}
-@gccoptlist{-mabsdiff -mall-opts -maverage -mbased=@var{n} -mbitops @gol
--mc=@var{n} -mclip -mconfig=@var{name} -mcop -mcop32 -mcop64 -mivc2 @gol
--mdc -mdiv -meb -mel -mio-volatile -ml -mleadz -mm -mminmax @gol
--mmult -mno-opts -mrepeat -ms -msatur -msdram -msim -msimnovec -mtf @gol
--mtiny=@var{n}}
-
-@emph{MicroBlaze Options}
-@gccoptlist{-msoft-float -mhard-float -msmall-divides -mcpu=@var{cpu} @gol
--mmemcpy -mxl-soft-mul -mxl-soft-div -mxl-barrel-shift @gol
--mxl-pattern-compare -mxl-stack-check -mxl-gp-opt -mno-clearbss @gol
--mxl-multiply-high -mxl-float-convert -mxl-float-sqrt @gol
--mbig-endian -mlittle-endian -mxl-reorder -mxl-mode-@var{app-model}}
-
-@emph{MIPS Options}
-@gccoptlist{-EL -EB -march=@var{arch} -mtune=@var{arch} @gol
--mips1 -mips2 -mips3 -mips4 -mips32 -mips32r2 @gol
--mips64 -mips64r2 @gol
--mips16 -mno-mips16 -mflip-mips16 @gol
--minterlink-mips16 -mno-interlink-mips16 @gol
--mabi=@var{abi} -mabicalls -mno-abicalls @gol
--mshared -mno-shared -mplt -mno-plt -mxgot -mno-xgot @gol
--mgp32 -mgp64 -mfp32 -mfp64 -mhard-float -msoft-float @gol
--mno-float -msingle-float -mdouble-float @gol
--mdsp -mno-dsp -mdspr2 -mno-dspr2 @gol
--mmcu -mmno-mcu @gol
--mfpu=@var{fpu-type} @gol
--msmartmips -mno-smartmips @gol
--mpaired-single -mno-paired-single -mdmx -mno-mdmx @gol
--mips3d -mno-mips3d -mmt -mno-mt -mllsc -mno-llsc @gol
--mlong64 -mlong32 -msym32 -mno-sym32 @gol
--G@var{num} -mlocal-sdata -mno-local-sdata @gol
--mextern-sdata -mno-extern-sdata -mgpopt -mno-gopt @gol
--membedded-data -mno-embedded-data @gol
--muninit-const-in-rodata -mno-uninit-const-in-rodata @gol
--mcode-readable=@var{setting} @gol
--msplit-addresses -mno-split-addresses @gol
--mexplicit-relocs -mno-explicit-relocs @gol
--mcheck-zero-division -mno-check-zero-division @gol
--mdivide-traps -mdivide-breaks @gol
--mmemcpy -mno-memcpy -mlong-calls -mno-long-calls @gol
--mmad -mno-mad -mfused-madd -mno-fused-madd -nocpp @gol
--mfix-24k -mno-fix-24k @gol
--mfix-r4000 -mno-fix-r4000 -mfix-r4400 -mno-fix-r4400 @gol
--mfix-r10000 -mno-fix-r10000 -mfix-vr4120 -mno-fix-vr4120 @gol
--mfix-vr4130 -mno-fix-vr4130 -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 -msynci -mno-synci @gol
--mrelax-pic-calls -mno-relax-pic-calls -mmcount-ra-address}
-
-@emph{MMIX Options}
-@gccoptlist{-mlibfuncs -mno-libfuncs -mepsilon -mno-epsilon -mabi=gnu @gol
--mabi=mmixware -mzero-extend -mknuthdiv -mtoplevel-symbols @gol
--melf -mbranch-predict -mno-branch-predict -mbase-addresses @gol
--mno-base-addresses -msingle-exit -mno-single-exit}
-
-@emph{MN10300 Options}
-@gccoptlist{-mmult-bug -mno-mult-bug @gol
--mno-am33 -mam33 -mam33-2 -mam34 @gol
--mtune=@var{cpu-type} @gol
--mreturn-pointer-on-d0 @gol
--mno-crt0 -mrelax -mliw -msetlb}
-
-@emph{Moxie Options}
-@gccoptlist{-meb -mel -mno-crt0}
-
-@emph{PDP-11 Options}
-@gccoptlist{-mfpu -msoft-float -mac0 -mno-ac0 -m40 -m45 -m10 @gol
--mbcopy -mbcopy-builtin -mint32 -mno-int16 @gol
--mint16 -mno-int32 -mfloat32 -mno-float64 @gol
--mfloat64 -mno-float32 -mabshi -mno-abshi @gol
--mbranch-expensive -mbranch-cheap @gol
--munix-asm -mdec-asm}
-
-@emph{picoChip Options}
-@gccoptlist{-mae=@var{ae_type} -mvliw-lookahead=@var{N} @gol
--msymbol-as-address -mno-inefficient-warnings}
-
-@emph{PowerPC Options}
-See RS/6000 and PowerPC Options.
-
-@emph{RL78 Options}
-@gccoptlist{-msim -mmul=none -mmul=g13 -mmul=rl78}
-
-@emph{RS/6000 and PowerPC Options}
-@gccoptlist{-mcpu=@var{cpu-type} @gol
--mtune=@var{cpu-type} @gol
--mcmodel=@var{code-model} @gol
--mpowerpc64 @gol
--maltivec -mno-altivec @gol
--mpowerpc-gpopt -mno-powerpc-gpopt @gol
--mpowerpc-gfxopt -mno-powerpc-gfxopt @gol
--mmfcrf -mno-mfcrf -mpopcntb -mno-popcntb -mpopcntd -mno-popcntd @gol
--mfprnd -mno-fprnd @gol
--mcmpb -mno-cmpb -mmfpgpr -mno-mfpgpr -mhard-dfp -mno-hard-dfp @gol
--mfull-toc -mminimal-toc -mno-fp-in-toc -mno-sum-in-toc @gol
--m64 -m32 -mxl-compat -mno-xl-compat -mpe @gol
--malign-power -malign-natural @gol
--msoft-float -mhard-float -mmultiple -mno-multiple @gol
--msingle-float -mdouble-float -msimple-fpu @gol
--mstring -mno-string -mupdate -mno-update @gol
--mavoid-indexed-addresses -mno-avoid-indexed-addresses @gol
--mfused-madd -mno-fused-madd -mbit-align -mno-bit-align @gol
--mstrict-align -mno-strict-align -mrelocatable @gol
--mno-relocatable -mrelocatable-lib -mno-relocatable-lib @gol
--mtoc -mno-toc -mlittle -mlittle-endian -mbig -mbig-endian @gol
--mdynamic-no-pic -maltivec -mswdiv -msingle-pic-base @gol
--mprioritize-restricted-insns=@var{priority} @gol
--msched-costly-dep=@var{dependence_type} @gol
--minsert-sched-nops=@var{scheme} @gol
--mcall-sysv -mcall-netbsd @gol
--maix-struct-return -msvr4-struct-return @gol
--mabi=@var{abi-type} -msecure-plt -mbss-plt @gol
--mblock-move-inline-limit=@var{num} @gol
--misel -mno-isel @gol
--misel=yes -misel=no @gol
--mspe -mno-spe @gol
--mspe=yes -mspe=no @gol
--mpaired @gol
--mgen-cell-microcode -mwarn-cell-microcode @gol
--mvrsave -mno-vrsave @gol
--mmulhw -mno-mulhw @gol
--mdlmzb -mno-dlmzb @gol
--mfloat-gprs=yes -mfloat-gprs=no -mfloat-gprs=single -mfloat-gprs=double @gol
--mprototype -mno-prototype @gol
--msim -mmvme -mads -myellowknife -memb -msdata @gol
--msdata=@var{opt} -mvxworks -G @var{num} -pthread @gol
--mrecip -mrecip=@var{opt} -mno-recip -mrecip-precision @gol
--mno-recip-precision @gol
--mveclibabi=@var{type} -mfriz -mno-friz @gol
--mpointers-to-nested-functions -mno-pointers-to-nested-functions @gol
--msave-toc-indirect -mno-save-toc-indirect}
-
-@emph{RX Options}
-@gccoptlist{-m64bit-doubles -m32bit-doubles -fpu -nofpu@gol
--mcpu=@gol
--mbig-endian-data -mlittle-endian-data @gol
--msmall-data @gol
--msim -mno-sim@gol
--mas100-syntax -mno-as100-syntax@gol
--mrelax@gol
--mmax-constant-size=@gol
--mint-register=@gol
--mpid@gol
--mno-warn-multiple-fast-interrupts@gol
--msave-acc-in-interrupts}
-
-@emph{S/390 and zSeries Options}
-@gccoptlist{-mtune=@var{cpu-type} -march=@var{cpu-type} @gol
--mhard-float -msoft-float -mhard-dfp -mno-hard-dfp @gol
--mlong-double-64 -mlong-double-128 @gol
--mbackchain -mno-backchain -mpacked-stack -mno-packed-stack @gol
--msmall-exec -mno-small-exec -mmvcle -mno-mvcle @gol
--m64 -m31 -mdebug -mno-debug -mesa -mzarch @gol
--mtpf-trace -mno-tpf-trace -mfused-madd -mno-fused-madd @gol
--mwarn-framesize -mwarn-dynamicstack -mstack-size -mstack-guard}
-
-@emph{Score Options}
-@gccoptlist{-meb -mel @gol
--mnhwloop @gol
--muls @gol
--mmac @gol
--mscore5 -mscore5u -mscore7 -mscore7d}
-
-@emph{SH Options}
-@gccoptlist{-m1 -m2 -m2e @gol
--m2a-nofpu -m2a-single-only -m2a-single -m2a @gol
--m3 -m3e @gol
--m4-nofpu -m4-single-only -m4-single -m4 @gol
--m4a-nofpu -m4a-single-only -m4a-single -m4a -m4al @gol
--m5-64media -m5-64media-nofpu @gol
--m5-32media -m5-32media-nofpu @gol
--m5-compact -m5-compact-nofpu @gol
--mb -ml -mdalign -mrelax @gol
--mbigtable -mfmovd -mhitachi -mrenesas -mno-renesas -mnomacsave @gol
--mieee -mno-ieee -mbitops -misize -minline-ic_invalidate -mpadstruct @gol
--mspace -mprefergot -musermode -multcost=@var{number} -mdiv=@var{strategy} @gol
--mdivsi3_libfunc=@var{name} -mfixed-range=@var{register-range} @gol
--mindexed-addressing -mgettrcost=@var{number} -mpt-fixed @gol
--maccumulate-outgoing-args -minvalid-symbols @gol
--matomic-model=@var{atomic-model} @gol
--mbranch-cost=@var{num} -mzdcbranch -mno-zdcbranch -mcbranchdi -mcmpeqdi @gol
--mfused-madd -mno-fused-madd -mfsca -mno-fsca -mfsrra -mno-fsrra @gol
--mpretend-cmove -mtas}
-
-@emph{Solaris 2 Options}
-@gccoptlist{-mimpure-text -mno-impure-text @gol
--pthreads -pthread}
-
-@emph{SPARC Options}
-@gccoptlist{-mcpu=@var{cpu-type} @gol
--mtune=@var{cpu-type} @gol
--mcmodel=@var{code-model} @gol
--mmemory-model=@var{mem-model} @gol
--m32 -m64 -mapp-regs -mno-app-regs @gol
--mfaster-structs -mno-faster-structs -mflat -mno-flat @gol
--mfpu -mno-fpu -mhard-float -msoft-float @gol
--mhard-quad-float -msoft-quad-float @gol
--mstack-bias -mno-stack-bias @gol
--munaligned-doubles -mno-unaligned-doubles @gol
--mv8plus -mno-v8plus -mvis -mno-vis @gol
--mvis2 -mno-vis2 -mvis3 -mno-vis3 @gol
--mcbcond -mno-cbcond @gol
--mfmaf -mno-fmaf -mpopc -mno-popc @gol
--mfix-at697f}
-
-@emph{SPU Options}
-@gccoptlist{-mwarn-reloc -merror-reloc @gol
--msafe-dma -munsafe-dma @gol
--mbranch-hints @gol
--msmall-mem -mlarge-mem -mstdmain @gol
--mfixed-range=@var{register-range} @gol
--mea32 -mea64 @gol
--maddress-space-conversion -mno-address-space-conversion @gol
--mcache-size=@var{cache-size} @gol
--matomic-updates -mno-atomic-updates}
-
-@emph{System V Options}
-@gccoptlist{-Qy -Qn -YP,@var{paths} -Ym,@var{dir}}
-
-@emph{TILE-Gx Options}
-@gccoptlist{-mcpu=@var{cpu} -m32 -m64 -mcmodel=@var{code-model}}
-
-@emph{TILEPro Options}
-@gccoptlist{-mcpu=@var{cpu} -m32}
-
-@emph{V850 Options}
-@gccoptlist{-mlong-calls -mno-long-calls -mep -mno-ep @gol
--mprolog-function -mno-prolog-function -mspace @gol
--mtda=@var{n} -msda=@var{n} -mzda=@var{n} @gol
--mapp-regs -mno-app-regs @gol
--mdisable-callt -mno-disable-callt @gol
--mv850e2v3 -mv850e2 -mv850e1 -mv850es @gol
--mv850e -mv850 -mv850e3v5 @gol
--mloop @gol
--mrelax @gol
--mlong-jumps @gol
--msoft-float @gol
--mhard-float @gol
--mgcc-abi @gol
--mrh850-abi @gol
--mbig-switch}
-
-@emph{VAX Options}
-@gccoptlist{-mg -mgnu -munix}
-
-@emph{VMS Options}
-@gccoptlist{-mvms-return-codes -mdebug-main=@var{prefix} -mmalloc64 @gol
--mpointer-size=@var{size}}
-
-@emph{VxWorks Options}
-@gccoptlist{-mrtp -non-static -Bstatic -Bdynamic @gol
--Xbind-lazy -Xbind-now}
-
-@emph{x86-64 Options}
-See i386 and x86-64 Options.
-
-@emph{Xstormy16 Options}
-@gccoptlist{-msim}
-
-@emph{Xtensa Options}
-@gccoptlist{-mconst16 -mno-const16 @gol
--mfused-madd -mno-fused-madd @gol
--mforce-no-pic @gol
--mserialize-volatile -mno-serialize-volatile @gol
--mtext-section-literals -mno-text-section-literals @gol
--mtarget-align -mno-target-align @gol
--mlongcalls -mno-longcalls}
-
-@emph{zSeries Options}
-See S/390 and zSeries Options.
-
-@item Code Generation Options
-@xref{Code Gen Options,,Options for Code Generation Conventions}.
-@gccoptlist{-fcall-saved-@var{reg} -fcall-used-@var{reg} @gol
--ffixed-@var{reg} -fexceptions @gol
--fnon-call-exceptions -fdelete-dead-exceptions -funwind-tables @gol
--fasynchronous-unwind-tables @gol
--finhibit-size-directive -finstrument-functions @gol
--finstrument-functions-exclude-function-list=@var{sym},@var{sym},@dots{} @gol
--finstrument-functions-exclude-file-list=@var{file},@var{file},@dots{} @gol
--fno-common -fno-ident @gol
--fpcc-struct-return -fpic -fPIC -fpie -fPIE @gol
--fno-jump-tables @gol
--frecord-gcc-switches @gol
--freg-struct-return -fshort-enums @gol
--fshort-double -fshort-wchar @gol
--fverbose-asm -fpack-struct[=@var{n}] -fstack-check @gol
--fstack-limit-register=@var{reg} -fstack-limit-symbol=@var{sym} @gol
--fno-stack-limit -fsplit-stack @gol
--fleading-underscore -ftls-model=@var{model} @gol
--fstack-reuse=@var{reuse_level} @gol
--ftrapv -fwrapv -fbounds-check @gol
--fvisibility -fstrict-volatile-bitfields -fsync-libcalls}
-@end table
-
-@menu
-* Overall Options:: Controlling the kind of output:
- an executable, object files, assembler files,
- or preprocessed source.
-* 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
- and Objective-C++.
-* Language Independent Options:: Controlling how diagnostics should be
- formatted.
-* Warning Options:: How picky should the compiler be?
-* Debugging Options:: Symbol tables, measurements, and debugging dumps.
-* Optimize Options:: How much optimization?
-* Preprocessor Options:: Controlling header files and macro definitions.
- Also, getting dependency information for Make.
-* Assembler Options:: Passing options to the assembler.
-* Link Options:: Specifying libraries and so on.
-* Directory Options:: Where to find header files and libraries.
- Where to find the compiler executable files.
-* Spec Files:: How to pass switches to sub-processes.
-* Target Options:: Running a cross-compiler, or an old version of GCC.
-@end menu
-
-@node Overall Options
-@section Options Controlling the Kind of Output
-
-Compilation can involve up to four stages: preprocessing, compilation
-proper, assembly and linking, always in that order. GCC is capable of
-preprocessing and compiling several files either into several
-assembler input files, or into one assembler input file; then each
-assembler input file produces an object file, and linking combines all
-the object files (those newly compiled, and those specified as input)
-into an executable file.
-
-@cindex file name suffix
-For any given input file, the file name suffix determines what kind of
-compilation is done:
-
-@table @gcctabopt
-@item @var{file}.c
-C source code that must be preprocessed.
-
-@item @var{file}.i
-C source code that should not be preprocessed.
-
-@item @var{file}.ii
-C++ source code that should not be preprocessed.
-
-@item @var{file}.m
-Objective-C source code. Note that you must link with the @file{libobjc}
-library to make an Objective-C program work.
-
-@item @var{file}.mi
-Objective-C source code that should not be preprocessed.
-
-@item @var{file}.mm
-@itemx @var{file}.M
-Objective-C++ source code. Note that you must link with the @file{libobjc}
-library to make an Objective-C++ program work. Note that @samp{.M} refers
-to a literal capital M@.
-
-@item @var{file}.mii
-Objective-C++ source code that should not be preprocessed.
-
-@item @var{file}.h
-C, C++, Objective-C or Objective-C++ header file to be turned into a
-precompiled header (default), or C, C++ header file to be turned into an
-Ada spec (via the @option{-fdump-ada-spec} switch).
-
-@item @var{file}.cc
-@itemx @var{file}.cp
-@itemx @var{file}.cxx
-@itemx @var{file}.cpp
-@itemx @var{file}.CPP
-@itemx @var{file}.c++
-@itemx @var{file}.C
-C++ source code that must be preprocessed. Note that in @samp{.cxx},
-the last two letters must both be literally @samp{x}. Likewise,
-@samp{.C} refers to a literal capital C@.
-
-@item @var{file}.mm
-@itemx @var{file}.M
-Objective-C++ source code that must be preprocessed.
-
-@item @var{file}.mii
-Objective-C++ source code that should not be preprocessed.
-
-@item @var{file}.hh
-@itemx @var{file}.H
-@itemx @var{file}.hp
-@itemx @var{file}.hxx
-@itemx @var{file}.hpp
-@itemx @var{file}.HPP
-@itemx @var{file}.h++
-@itemx @var{file}.tcc
-C++ header file to be turned into a precompiled header or Ada spec.
-
-@item @var{file}.f
-@itemx @var{file}.for
-@itemx @var{file}.ftn
-Fixed form Fortran source code that should not be preprocessed.
-
-@item @var{file}.F
-@itemx @var{file}.FOR
-@itemx @var{file}.fpp
-@itemx @var{file}.FPP
-@itemx @var{file}.FTN
-Fixed form Fortran source code that must be preprocessed (with the traditional
-preprocessor).
-
-@item @var{file}.f90
-@itemx @var{file}.f95
-@itemx @var{file}.f03
-@itemx @var{file}.f08
-Free form Fortran source code that should not be preprocessed.
-
-@item @var{file}.F90
-@itemx @var{file}.F95
-@itemx @var{file}.F03
-@itemx @var{file}.F08
-Free form Fortran source code that must be preprocessed (with the
-traditional preprocessor).
-
-@item @var{file}.go
-Go source code.
-
-@c FIXME: Descriptions of Java file types.
-@c @var{file}.java
-@c @var{file}.class
-@c @var{file}.zip
-@c @var{file}.jar
-
-@item @var{file}.ads
-Ada source code file that contains a library unit declaration (a
-declaration of a package, subprogram, or generic, or a generic
-instantiation), or a library unit renaming declaration (a package,
-generic, or subprogram renaming declaration). Such files are also
-called @dfn{specs}.
-
-@item @var{file}.adb
-Ada source code file containing a library unit body (a subprogram or
-package body). Such files are also called @dfn{bodies}.
-
-@c GCC also knows about some suffixes for languages not yet included:
-@c Pascal:
-@c @var{file}.p
-@c @var{file}.pas
-@c Ratfor:
-@c @var{file}.r
-
-@item @var{file}.s
-Assembler code.
-
-@item @var{file}.S
-@itemx @var{file}.sx
-Assembler code that must be preprocessed.
-
-@item @var{other}
-An object file to be fed straight into linking.
-Any file name with no recognized suffix is treated this way.
-@end table
-
-@opindex x
-You can specify the input language explicitly with the @option{-x} option:
-
-@table @gcctabopt
-@item -x @var{language}
-Specify explicitly the @var{language} for the following input files
-(rather than letting the compiler choose a default based on the file
-name suffix). This option applies to all following input files until
-the next @option{-x} option. Possible values for @var{language} are:
-@smallexample
-c c-header cpp-output
-c++ c++-header c++-cpp-output
-objective-c objective-c-header objective-c-cpp-output
-objective-c++ objective-c++-header objective-c++-cpp-output
-assembler assembler-with-cpp
-ada
-f77 f77-cpp-input f95 f95-cpp-input
-go
-java
-@end smallexample
-
-@item -x none
-Turn off any specification of a language, so that subsequent files are
-handled according to their file name suffixes (as they are if @option{-x}
-has not been used at all).
-
-@item -pass-exit-codes
-@opindex pass-exit-codes
-Normally the @command{gcc} program exits with the code of 1 if any
-phase of the compiler returns a non-success return code. If you specify
-@option{-pass-exit-codes}, the @command{gcc} program instead returns with
-the numerically highest error produced by any phase returning an error
-indication. The C, C++, and Fortran front ends return 4 if an internal
-compiler error is encountered.
-@end table
-
-If you only want some of the stages of compilation, you can use
-@option{-x} (or filename suffixes) to tell @command{gcc} where to start, and
-one of the options @option{-c}, @option{-S}, or @option{-E} to say where
-@command{gcc} is to stop. Note that some combinations (for example,
-@samp{-x cpp-output -E}) instruct @command{gcc} to do nothing at all.
-
-@table @gcctabopt
-@item -c
-@opindex c
-Compile or assemble the source files, but do not link. The linking
-stage simply is not done. The ultimate output is in the form of an
-object file for each source file.
-
-By default, the object file name for a source file is made by replacing
-the suffix @samp{.c}, @samp{.i}, @samp{.s}, etc., with @samp{.o}.
-
-Unrecognized input files, not requiring compilation or assembly, are
-ignored.
-
-@item -S
-@opindex S
-Stop after the stage of compilation proper; do not assemble. The output
-is in the form of an assembler code file for each non-assembler input
-file specified.
-
-By default, the assembler file name for a source file is made by
-replacing the suffix @samp{.c}, @samp{.i}, etc., with @samp{.s}.
-
-Input files that don't require compilation are ignored.
-
-@item -E
-@opindex E
-Stop after the preprocessing stage; do not run the compiler proper. The
-output is in the form of preprocessed source code, which is sent to the
-standard output.
-
-Input files that don't require preprocessing are ignored.
-
-@cindex output file option
-@item -o @var{file}
-@opindex o
-Place output in file @var{file}. This applies to whatever
-sort of output is being produced, whether it be an executable file,
-an object file, an assembler file or preprocessed C code.
-
-If @option{-o} is not specified, the default is to put an executable
-file in @file{a.out}, the object file for
-@file{@var{source}.@var{suffix}} in @file{@var{source}.o}, its
-assembler file in @file{@var{source}.s}, a precompiled header file in
-@file{@var{source}.@var{suffix}.gch}, and all preprocessed C source on
-standard output.
-
-@item -v
-@opindex v
-Print (on standard error output) the commands executed to run the stages
-of compilation. Also print the version number of the compiler driver
-program and of the preprocessor and the compiler proper.
-
-@item -###
-@opindex ###
-Like @option{-v} except the commands are not executed and arguments
-are quoted unless they contain only alphanumeric characters or @code{./-_}.
-This is useful for shell scripts to capture the driver-generated command lines.
-
-@item -pipe
-@opindex pipe
-Use pipes rather than temporary files for communication between the
-various stages of compilation. This fails to work on some systems where
-the assembler is unable to read from a pipe; but the GNU assembler has
-no trouble.
-
-@item --help
-@opindex help
-Print (on the standard output) a description of the command-line options
-understood by @command{gcc}. If the @option{-v} option is also specified
-then @option{--help} is also passed on to the various processes
-invoked by @command{gcc}, so that they can display the command-line options
-they accept. If the @option{-Wextra} option has also been specified
-(prior to the @option{--help} option), then command-line options that
-have no documentation associated with them are also displayed.
-
-@item --target-help
-@opindex target-help
-Print (on the standard output) a description of target-specific command-line
-options for each tool. For some targets extra target-specific
-information may also be printed.
-
-@item --help=@{@var{class}@r{|[}^@r{]}@var{qualifier}@}@r{[},@dots{}@r{]}
-Print (on the standard output) a description of the command-line
-options understood by the compiler that fit into all specified classes
-and qualifiers. These are the supported classes:
-
-@table @asis
-@item @samp{optimizers}
-Display all of the optimization options supported by the
-compiler.
-
-@item @samp{warnings}
-Display all of the options controlling warning messages
-produced by the compiler.
-
-@item @samp{target}
-Display target-specific options. Unlike the
-@option{--target-help} option however, target-specific options of the
-linker and assembler are not displayed. This is because those
-tools do not currently support the extended @option{--help=} syntax.
-
-@item @samp{params}
-Display the values recognized by the @option{--param}
-option.
-
-@item @var{language}
-Display the options supported for @var{language}, where
-@var{language} is the name of one of the languages supported in this
-version of GCC@.
-
-@item @samp{common}
-Display the options that are common to all languages.
-@end table
-
-These are the supported qualifiers:
-
-@table @asis
-@item @samp{undocumented}
-Display only those options that are undocumented.
-
-@item @samp{joined}
-Display options taking an argument that appears after an equal
-sign in the same continuous piece of text, such as:
-@samp{--help=target}.
-
-@item @samp{separate}
-Display options taking an argument that appears as a separate word
-following the original option, such as: @samp{-o output-file}.
-@end table
-
-Thus for example to display all the undocumented target-specific
-switches supported by the compiler, use:
-
-@smallexample
---help=target,undocumented
-@end smallexample
-
-The sense of a qualifier can be inverted by prefixing it with the
-@samp{^} character, so for example to display all binary warning
-options (i.e., ones that are either on or off and that do not take an
-argument) that have a description, use:
-
-@smallexample
---help=warnings,^joined,^undocumented
-@end smallexample
-
-The argument to @option{--help=} should not consist solely of inverted
-qualifiers.
-
-Combining several classes is possible, although this usually
-restricts the output so much that there is nothing to display. One
-case where it does work, however, is when one of the classes is
-@var{target}. For example, to display all the target-specific
-optimization options, use:
-
-@smallexample
---help=target,optimizers
-@end smallexample
-
-The @option{--help=} option can be repeated on the command line. Each
-successive use displays its requested class of options, skipping
-those that have already been displayed.
-
-If the @option{-Q} option appears on the command line before the
-@option{--help=} option, then the descriptive text displayed by
-@option{--help=} is changed. Instead of describing the displayed
-options, an indication is given as to whether the option is enabled,
-disabled or set to a specific value (assuming that the compiler
-knows this at the point where the @option{--help=} option is used).
-
-Here is a truncated example from the ARM port of @command{gcc}:
-
-@smallexample
- % gcc -Q -mabi=2 --help=target -c
- The following options are target specific:
- -mabi= 2
- -mabort-on-noreturn [disabled]
- -mapcs [disabled]
-@end smallexample
-
-The output is sensitive to the effects of previous command-line
-options, so for example it is possible to find out which optimizations
-are enabled at @option{-O2} by using:
-
-@smallexample
--Q -O2 --help=optimizers
-@end smallexample
-
-Alternatively you can discover which binary optimizations are enabled
-by @option{-O3} by using:
-
-@smallexample
-gcc -c -Q -O3 --help=optimizers > /tmp/O3-opts
-gcc -c -Q -O2 --help=optimizers > /tmp/O2-opts
-diff /tmp/O2-opts /tmp/O3-opts | grep enabled
-@end smallexample
-
-@item -no-canonical-prefixes
-@opindex no-canonical-prefixes
-Do not expand any symbolic links, resolve references to @samp{/../}
-or @samp{/./}, or make the path absolute when generating a relative
-prefix.
-
-@item --version
-@opindex version
-Display the version number and copyrights of the invoked GCC@.
-
-@item -wrapper
-@opindex wrapper
-Invoke all subcommands under a wrapper program. The name of the
-wrapper program and its parameters are passed as a comma separated
-list.
-
-@smallexample
-gcc -c t.c -wrapper gdb,--args
-@end smallexample
-
-@noindent
-This invokes all subprograms of @command{gcc} under
-@samp{gdb --args}, thus the invocation of @command{cc1} is
-@samp{gdb --args cc1 @dots{}}.
-
-@item -fplugin=@var{name}.so
-Load the plugin code in file @var{name}.so, assumed to be a
-shared object to be dlopen'd by the compiler. The base name of
-the shared object file is used to identify the plugin for the
-purposes of argument parsing (See
-@option{-fplugin-arg-@var{name}-@var{key}=@var{value}} below).
-Each plugin should define the callback functions specified in the
-Plugins API.
-
-@item -fplugin-arg-@var{name}-@var{key}=@var{value}
-Define an argument called @var{key} with a value of @var{value}
-for the plugin called @var{name}.
-
-@item -fdump-ada-spec@r{[}-slim@r{]}
-For C and C++ source and include files, generate corresponding Ada
-specs. @xref{Generating Ada Bindings for C and C++ headers,,, gnat_ugn,
-GNAT User's Guide}, which provides detailed documentation on this feature.
-
-@item -fdump-go-spec=@var{file}
-For input files in any language, generate corresponding Go
-declarations in @var{file}. This generates Go @code{const},
-@code{type}, @code{var}, and @code{func} declarations which may be a
-useful way to start writing a Go interface to code written in some
-other language.
-
-@include @value{srcdir}/../libiberty/at-file.texi
-@end table
-
-@node Invoking G++
-@section Compiling C++ Programs
-
-@cindex suffixes for C++ source
-@cindex C++ source file suffixes
-C++ source files conventionally use one of the suffixes @samp{.C},
-@samp{.cc}, @samp{.cpp}, @samp{.CPP}, @samp{.c++}, @samp{.cp}, or
-@samp{.cxx}; C++ header files often use @samp{.hh}, @samp{.hpp},
-@samp{.H}, or (for shared template code) @samp{.tcc}; and
-preprocessed C++ files use the suffix @samp{.ii}. GCC recognizes
-files with these names and compiles them as C++ programs even if you
-call the compiler the same way as for compiling C programs (usually
-with the name @command{gcc}).
-
-@findex g++
-@findex c++
-However, the use of @command{gcc} does not add the C++ library.
-@command{g++} is a program that calls GCC and automatically specifies linking
-against the C++ library. It treats @samp{.c},
-@samp{.h} and @samp{.i} files as C++ source files instead of C source
-files unless @option{-x} is used. This program is also useful when
-precompiling a C header file with a @samp{.h} extension for use in C++
-compilations. On many systems, @command{g++} is also installed with
-the name @command{c++}.
-
-@cindex invoking @command{g++}
-When you compile C++ programs, you may specify many of the same
-command-line options that you use for compiling programs in any
-language; or command-line options meaningful for C and related
-languages; or options that are meaningful only for C++ programs.
-@xref{C Dialect Options,,Options Controlling C Dialect}, for
-explanations of options for languages related to C@.
-@xref{C++ Dialect Options,,Options Controlling C++ Dialect}, for
-explanations of options that are meaningful only for C++ programs.
-
-@node C Dialect Options
-@section Options Controlling C Dialect
-@cindex dialect options
-@cindex language dialect options
-@cindex options, dialect
-
-The following options control the dialect of C (or languages derived
-from C, such as C++, Objective-C and Objective-C++) that the compiler
-accepts:
-
-@table @gcctabopt
-@cindex ANSI support
-@cindex ISO support
-@item -ansi
-@opindex ansi
-In C mode, this is equivalent to @option{-std=c90}. In C++ mode, it is
-equivalent to @option{-std=c++98}.
-
-This turns off certain features of GCC that are incompatible with ISO
-C90 (when compiling C code), or of standard C++ (when compiling C++ code),
-such as the @code{asm} and @code{typeof} keywords, and
-predefined macros such as @code{unix} and @code{vax} that identify the
-type of system you are using. It also enables the undesirable and
-rarely used ISO trigraph feature. For the C compiler,
-it disables recognition of C++ style @samp{//} comments as well as
-the @code{inline} keyword.
-
-The alternate keywords @code{__asm__}, @code{__extension__},
-@code{__inline__} and @code{__typeof__} continue to work despite
-@option{-ansi}. You would not want to use them in an ISO C program, of
-course, but it is useful to put them in header files that might be included
-in compilations done with @option{-ansi}. Alternate predefined macros
-such as @code{__unix__} and @code{__vax__} are also available, with or
-without @option{-ansi}.
-
-The @option{-ansi} option does not cause non-ISO programs to be
-rejected gratuitously. For that, @option{-Wpedantic} is required in
-addition to @option{-ansi}. @xref{Warning Options}.
-
-The macro @code{__STRICT_ANSI__} is predefined when the @option{-ansi}
-option is used. Some header files may notice this macro and refrain
-from declaring certain functions or defining certain macros that the
-ISO standard doesn't call for; this is to avoid interfering with any
-programs that might use these names for other things.
-
-Functions that are normally built in but do not have semantics
-defined by ISO C (such as @code{alloca} and @code{ffs}) are not built-in
-functions when @option{-ansi} is used. @xref{Other Builtins,,Other
-built-in functions provided by GCC}, for details of the functions
-affected.
-
-@item -std=
-@opindex std
-Determine the language standard. @xref{Standards,,Language Standards
-Supported by GCC}, for details of these standard versions. This option
-is currently only supported when compiling C or C++.
-
-The compiler can accept several base standards, such as @samp{c90} or
-@samp{c++98}, and GNU dialects of those standards, such as
-@samp{gnu90} or @samp{gnu++98}. When a base standard is specified, the
-compiler accepts all programs following that standard plus those
-using GNU extensions that do not contradict it. For example,
-@option{-std=c90} turns off certain features of GCC that are
-incompatible with ISO C90, such as the @code{asm} and @code{typeof}
-keywords, but not other GNU extensions that do not have a meaning in
-ISO C90, such as omitting the middle term of a @code{?:}
-expression. On the other hand, when a GNU dialect of a standard is
-specified, all features supported by the compiler are enabled, even when
-those features change the meaning of the base standard. As a result, some
-strict-conforming programs may be rejected. The particular standard
-is used by @option{-Wpedantic} to identify which features are GNU
-extensions given that version of the standard. For example
-@option{-std=gnu90 -Wpedantic} warns about C++ style @samp{//}
-comments, while @option{-std=gnu99 -Wpedantic} does not.
-
-A value for this option must be provided; possible values are
-
-@table @samp
-@item c90
-@itemx c89
-@itemx iso9899:1990
-Support all ISO C90 programs (certain GNU extensions that conflict
-with ISO C90 are disabled). Same as @option{-ansi} for C code.
-
-@item iso9899:199409
-ISO C90 as modified in amendment 1.
-
-@item c99
-@itemx c9x
-@itemx iso9899:1999
-@itemx iso9899:199x
-ISO C99. Note that this standard is not yet fully supported; see
-@w{@uref{http://gcc.gnu.org/c99status.html}} for more information. The
-names @samp{c9x} and @samp{iso9899:199x} are deprecated.
-
-@item c11
-@itemx c1x
-@itemx iso9899:2011
-ISO C11, the 2011 revision of the ISO C standard.
-Support is incomplete and experimental. The name @samp{c1x} is
-deprecated.
-
-@item gnu90
-@itemx gnu89
-GNU dialect of ISO C90 (including some C99 features). This
-is the default for C code.
-
-@item gnu99
-@itemx gnu9x
-GNU dialect of ISO C99. When ISO C99 is fully implemented in GCC,
-this will become the default. The name @samp{gnu9x} is deprecated.
-
-@item gnu11
-@itemx gnu1x
-GNU dialect of ISO C11. Support is incomplete and experimental. The
-name @samp{gnu1x} is deprecated.
-
-@item c++98
-@itemx c++03
-The 1998 ISO C++ standard plus the 2003 technical corrigendum and some
-additional defect reports. Same as @option{-ansi} for C++ code.
-
-@item gnu++98
-@itemx gnu++03
-GNU dialect of @option{-std=c++98}. This is the default for
-C++ code.
-
-@item c++11
-@itemx c++0x
-The 2011 ISO C++ standard plus amendments. Support for C++11 is still
-experimental, and may change in incompatible ways in future releases.
-The name @samp{c++0x} is deprecated.
-
-@item gnu++11
-@itemx gnu++0x
-GNU dialect of @option{-std=c++11}. Support for C++11 is still
-experimental, and may change in incompatible ways in future releases.
-The name @samp{gnu++0x} is deprecated.
-
-@item c++1y
-The next revision of the ISO C++ standard, tentatively planned for
-2017. Support is highly experimental, and will almost certainly
-change in incompatible ways in future releases.
-
-@item gnu++1y
-GNU dialect of @option{-std=c++1y}. Support is highly experimental,
-and will almost certainly change in incompatible ways in future
-releases.
-@end table
-
-@item -fgnu89-inline
-@opindex fgnu89-inline
-The option @option{-fgnu89-inline} tells GCC to use the traditional
-GNU semantics for @code{inline} functions when in C99 mode.
-@xref{Inline,,An Inline Function is As Fast As a Macro}. This option
-is accepted and ignored by GCC versions 4.1.3 up to but not including
-4.3. In GCC versions 4.3 and later it changes the behavior of GCC in
-C99 mode. Using this option is roughly equivalent to adding the
-@code{gnu_inline} function attribute to all inline functions
-(@pxref{Function Attributes}).
-
-The option @option{-fno-gnu89-inline} explicitly tells GCC to use the
-C99 semantics for @code{inline} when in C99 or gnu99 mode (i.e., it
-specifies the default behavior). This option was first supported in
-GCC 4.3. This option is not supported in @option{-std=c90} or
-@option{-std=gnu90} mode.
-
-The preprocessor macros @code{__GNUC_GNU_INLINE__} and
-@code{__GNUC_STDC_INLINE__} may be used to check which semantics are
-in effect for @code{inline} functions. @xref{Common Predefined
-Macros,,,cpp,The C Preprocessor}.
-
-@item -aux-info @var{filename}
-@opindex aux-info
-Output to the given filename prototyped declarations for all functions
-declared and/or defined in a translation unit, including those in header
-files. This option is silently ignored in any language other than C@.
-
-Besides declarations, the file indicates, in comments, the origin of
-each declaration (source file and line), whether the declaration was
-implicit, prototyped or unprototyped (@samp{I}, @samp{N} for new or
-@samp{O} for old, respectively, in the first character after the line
-number and the colon), and whether it came from a declaration or a
-definition (@samp{C} or @samp{F}, respectively, in the following
-character). In the case of function definitions, a K&R-style list of
-arguments followed by their declarations is also provided, inside
-comments, after the declaration.
-
-@item -fallow-parameterless-variadic-functions
-Accept variadic functions without named parameters.
-
-Although it is possible to define such a function, this is not very
-useful as it is not possible to read the arguments. This is only
-supported for C as this construct is allowed by C++.
-
-@item -fno-asm
-@opindex fno-asm
-Do not recognize @code{asm}, @code{inline} or @code{typeof} as a
-keyword, so that code can use these words as identifiers. You can use
-the keywords @code{__asm__}, @code{__inline__} and @code{__typeof__}
-instead. @option{-ansi} implies @option{-fno-asm}.
-
-In C++, this switch only affects the @code{typeof} keyword, since
-@code{asm} and @code{inline} are standard keywords. You may want to
-use the @option{-fno-gnu-keywords} flag instead, which has the same
-effect. In C99 mode (@option{-std=c99} or @option{-std=gnu99}), this
-switch only affects the @code{asm} and @code{typeof} keywords, since
-@code{inline} is a standard keyword in ISO C99.
-
-@item -fno-builtin
-@itemx -fno-builtin-@var{function}
-@opindex fno-builtin
-@cindex built-in functions
-Don't recognize built-in functions that do not begin with
-@samp{__builtin_} as prefix. @xref{Other Builtins,,Other built-in
-functions provided by GCC}, for details of the functions affected,
-including those which are not built-in functions when @option{-ansi} or
-@option{-std} options for strict ISO C conformance are used because they
-do not have an ISO standard meaning.
-
-GCC normally generates special code to handle certain built-in functions
-more efficiently; for instance, calls to @code{alloca} may become single
-instructions which adjust the stack directly, and calls to @code{memcpy}
-may become inline copy loops. The resulting code is often both smaller
-and faster, but since the function calls no longer appear as such, you
-cannot set a breakpoint on those calls, nor can you change the behavior
-of the functions by linking with a different library. In addition,
-when a function is recognized as a built-in function, GCC may use
-information about that function to warn about problems with calls to
-that function, or to generate more efficient code, even if the
-resulting code still contains calls to that function. For example,
-warnings are given with @option{-Wformat} for bad calls to
-@code{printf} when @code{printf} is built in and @code{strlen} is
-known not to modify global memory.
-
-With the @option{-fno-builtin-@var{function}} option
-only the built-in function @var{function} is
-disabled. @var{function} must not begin with @samp{__builtin_}. If a
-function is named that is not built-in in this version of GCC, this
-option is ignored. There is no corresponding
-@option{-fbuiltin-@var{function}} option; if you wish to enable
-built-in functions selectively when using @option{-fno-builtin} or
-@option{-ffreestanding}, you may define macros such as:
-
-@smallexample
-#define abs(n) __builtin_abs ((n))
-#define strcpy(d, s) __builtin_strcpy ((d), (s))
-@end smallexample
-
-@item -fhosted
-@opindex fhosted
-@cindex hosted environment
-
-Assert that compilation targets a hosted environment. This implies
-@option{-fbuiltin}. A hosted environment is one in which the
-entire standard library is available, and in which @code{main} has a return
-type of @code{int}. Examples are nearly everything except a kernel.
-This is equivalent to @option{-fno-freestanding}.
-
-@item -ffreestanding
-@opindex ffreestanding
-@cindex hosted environment
-
-Assert that compilation targets a freestanding environment. This
-implies @option{-fno-builtin}. A freestanding environment
-is one in which the standard library may not exist, and program startup may
-not necessarily be at @code{main}. The most obvious example is an OS kernel.
-This is equivalent to @option{-fno-hosted}.
-
-@xref{Standards,,Language Standards Supported by GCC}, for details of
-freestanding and hosted environments.
-
-@item -fopenmp
-@opindex fopenmp
-@cindex OpenMP parallel
-Enable handling of OpenMP directives @code{#pragma omp} in C/C++ and
-@code{!$omp} in Fortran. When @option{-fopenmp} is specified, the
-compiler generates parallel code according to the OpenMP Application
-Program Interface v3.0 @w{@uref{http://www.openmp.org/}}. This option
-implies @option{-pthread}, and thus is only supported on targets that
-have support for @option{-pthread}.
-
-@item -fgnu-tm
-@opindex fgnu-tm
-When the option @option{-fgnu-tm} is specified, the compiler
-generates code for the Linux variant of Intel's current Transactional
-Memory ABI specification document (Revision 1.1, May 6 2009). This is
-an experimental feature whose interface may change in future versions
-of GCC, as the official specification changes. Please note that not
-all architectures are supported for this feature.
-
-For more information on GCC's support for transactional memory,
-@xref{Enabling libitm,,The GNU Transactional Memory Library,libitm,GNU
-Transactional Memory Library}.
-
-Note that the transactional memory feature is not supported with
-non-call exceptions (@option{-fnon-call-exceptions}).
-
-@item -fms-extensions
-@opindex fms-extensions
-Accept some non-standard constructs used in Microsoft header files.
-
-In C++ code, this allows member names in structures to be similar
-to previous types declarations.
-
-@smallexample
-typedef int UOW;
-struct ABC @{
- UOW UOW;
-@};
-@end smallexample
-
-Some cases of unnamed fields in structures and unions are only
-accepted with this option. @xref{Unnamed Fields,,Unnamed struct/union
-fields within structs/unions}, for details.
-
-@item -fplan9-extensions
-Accept some non-standard constructs used in Plan 9 code.
-
-This enables @option{-fms-extensions}, permits passing pointers to
-structures with anonymous fields to functions that expect pointers to
-elements of the type of the field, and permits referring to anonymous
-fields declared using a typedef. @xref{Unnamed Fields,,Unnamed
-struct/union fields within structs/unions}, for details. This is only
-supported for C, not C++.
-
-@item -trigraphs
-@opindex trigraphs
-Support ISO C trigraphs. The @option{-ansi} option (and @option{-std}
-options for strict ISO C conformance) implies @option{-trigraphs}.
-
-@cindex traditional C language
-@cindex C language, traditional
-@item -traditional
-@itemx -traditional-cpp
-@opindex traditional-cpp
-@opindex traditional
-Formerly, these options caused GCC to attempt to emulate a pre-standard
-C compiler. They are now only supported with the @option{-E} switch.
-The preprocessor continues to support a pre-standard mode. See the GNU
-CPP manual for details.
-
-@item -fcond-mismatch
-@opindex fcond-mismatch
-Allow conditional expressions with mismatched types in the second and
-third arguments. The value of such an expression is void. This option
-is not supported for C++.
-
-@item -flax-vector-conversions
-@opindex flax-vector-conversions
-Allow implicit conversions between vectors with differing numbers of
-elements and/or incompatible element types. This option should not be
-used for new code.
-
-@item -funsigned-char
-@opindex funsigned-char
-Let the type @code{char} be unsigned, like @code{unsigned char}.
-
-Each kind of machine has a default for what @code{char} should
-be. It is either like @code{unsigned char} by default or like
-@code{signed char} by default.
-
-Ideally, a portable program should always use @code{signed char} or
-@code{unsigned char} when it depends on the signedness of an object.
-But many programs have been written to use plain @code{char} and
-expect it to be signed, or expect it to be unsigned, depending on the
-machines they were written for. This option, and its inverse, let you
-make such a program work with the opposite default.
-
-The type @code{char} is always a distinct type from each of
-@code{signed char} or @code{unsigned char}, even though its behavior
-is always just like one of those two.
-
-@item -fsigned-char
-@opindex fsigned-char
-Let the type @code{char} be signed, like @code{signed char}.
-
-Note that this is equivalent to @option{-fno-unsigned-char}, which is
-the negative form of @option{-funsigned-char}. Likewise, the option
-@option{-fno-signed-char} is equivalent to @option{-funsigned-char}.
-
-@item -fsigned-bitfields
-@itemx -funsigned-bitfields
-@itemx -fno-signed-bitfields
-@itemx -fno-unsigned-bitfields
-@opindex fsigned-bitfields
-@opindex funsigned-bitfields
-@opindex fno-signed-bitfields
-@opindex fno-unsigned-bitfields
-These options control whether a bit-field is signed or unsigned, when the
-declaration does not use either @code{signed} or @code{unsigned}. By
-default, such a bit-field is signed, because this is consistent: the
-basic integer types such as @code{int} are signed types.
-@end table
-
-@node C++ Dialect Options
-@section Options Controlling C++ Dialect
-
-@cindex compiler options, C++
-@cindex C++ options, command-line
-@cindex options, C++
-This section describes the command-line options that are only meaningful
-for C++ programs. You can also use most of the GNU compiler options
-regardless of what language your program is in. For example, you
-might compile a file @code{firstClass.C} like this:
-
-@smallexample
-g++ -g -frepo -O -c firstClass.C
-@end smallexample
-
-@noindent
-In this example, only @option{-frepo} is an option meant
-only for C++ programs; you can use the other options with any
-language supported by GCC@.
-
-Here is a list of options that are @emph{only} for compiling C++ programs:
-
-@table @gcctabopt
-
-@item -fabi-version=@var{n}
-@opindex fabi-version
-Use version @var{n} of the C++ ABI@. The default is version 2.
-
-Version 0 refers to the version conforming most closely to
-the C++ ABI specification. Therefore, the ABI obtained using version 0
-will change in different versions of G++ as ABI bugs are fixed.
-
-Version 1 is the version of the C++ ABI that first appeared in G++ 3.2.
-
-Version 2 is the version of the C++ ABI that first appeared in G++ 3.4.
-
-Version 3 corrects an error in mangling a constant address as a
-template argument.
-
-Version 4, which first appeared in G++ 4.5, implements a standard
-mangling for vector types.
-
-Version 5, which first appeared in G++ 4.6, corrects the mangling of
-attribute const/volatile on function pointer types, decltype of a
-plain decl, and use of a function parameter in the declaration of
-another parameter.
-
-Version 6, which first appeared in G++ 4.7, corrects the promotion
-behavior of C++11 scoped enums and the mangling of template argument
-packs, const/static_cast, prefix ++ and --, and a class scope function
-used as a template argument.
-
-See also @option{-Wabi}.
-
-@item -fno-access-control
-@opindex fno-access-control
-Turn off all access checking. This switch is mainly useful for working
-around bugs in the access control code.
-
-@item -fcheck-new
-@opindex fcheck-new
-Check that the pointer returned by @code{operator new} is non-null
-before attempting to modify the storage allocated. This check is
-normally unnecessary because the C++ standard specifies that
-@code{operator new} only returns @code{0} if it is declared
-@samp{throw()}, in which case the compiler always checks the
-return value even without this option. In all other cases, when
-@code{operator new} has a non-empty exception specification, memory
-exhaustion is signalled by throwing @code{std::bad_alloc}. See also
-@samp{new (nothrow)}.
-
-@item -fconstexpr-depth=@var{n}
-@opindex fconstexpr-depth
-Set the maximum nested evaluation depth for C++11 constexpr functions
-to @var{n}. A limit is needed to detect endless recursion during
-constant expression evaluation. The minimum specified by the standard
-is 512.
-
-@item -fdeduce-init-list
-@opindex fdeduce-init-list
-Enable deduction of a template type parameter as
-@code{std::initializer_list} from a brace-enclosed initializer list, i.e.@:
-
-@smallexample
-template <class T> auto forward(T t) -> decltype (realfn (t))
-@{
- return realfn (t);
-@}
-
-void f()
-@{
- forward(@{1,2@}); // call forward<std::initializer_list<int>>
-@}
-@end smallexample
-
-This deduction was implemented as a possible extension to the
-originally proposed semantics for the C++11 standard, but was not part
-of the final standard, so it is disabled by default. This option is
-deprecated, and may be removed in a future version of G++.
-
-@item -ffriend-injection
-@opindex ffriend-injection
-Inject friend functions into the enclosing namespace, so that they are
-visible outside the scope of the class in which they are declared.
-Friend functions were documented to work this way in the old Annotated
-C++ Reference Manual, and versions of G++ before 4.1 always worked
-that way. However, in ISO C++ a friend function that is not declared
-in an enclosing scope can only be found using argument dependent
-lookup. This option causes friends to be injected as they were in
-earlier releases.
-
-This option is for compatibility, and may be removed in a future
-release of G++.
-
-@item -fno-elide-constructors
-@opindex fno-elide-constructors
-The C++ standard allows an implementation to omit creating a temporary
-that is only used to initialize another object of the same type.
-Specifying this option disables that optimization, and forces G++ to
-call the copy constructor in all cases.
-
-@item -fno-enforce-eh-specs
-@opindex fno-enforce-eh-specs
-Don't generate code to check for violation of exception specifications
-at run time. This option violates the C++ standard, but may be useful
-for reducing code size in production builds, much like defining
-@samp{NDEBUG}. This does not give user code permission to throw
-exceptions in violation of the exception specifications; the compiler
-still optimizes based on the specifications, so throwing an
-unexpected exception results in undefined behavior at run time.
-
-@item -fextern-tls-init
-@itemx -fno-extern-tls-init
-@opindex fextern-tls-init
-@opindex fno-extern-tls-init
-The C++11 and OpenMP standards allow @samp{thread_local} and
-@samp{threadprivate} variables to have dynamic (runtime)
-initialization. To support this, any use of such a variable goes
-through a wrapper function that performs any necessary initialization.
-When the use and definition of the variable are in the same
-translation unit, this overhead can be optimized away, but when the
-use is in a different translation unit there is significant overhead
-even if the variable doesn't actually need dynamic initialization. If
-the programmer can be sure that no use of the variable in a
-non-defining TU needs to trigger dynamic initialization (either
-because the variable is statically initialized, or a use of the
-variable in the defining TU will be executed before any uses in
-another TU), they can avoid this overhead with the
-@option{-fno-extern-tls-init} option.
-
-On targets that support symbol aliases, the default is
-@option{-fextern-tls-init}. On targets that do not support symbol
-aliases, the default is @option{-fno-extern-tls-init}.
-
-@item -ffor-scope
-@itemx -fno-for-scope
-@opindex ffor-scope
-@opindex fno-for-scope
-If @option{-ffor-scope} is specified, the scope of variables declared in
-a @i{for-init-statement} is limited to the @samp{for} loop itself,
-as specified by the C++ standard.
-If @option{-fno-for-scope} is specified, the scope of variables declared in
-a @i{for-init-statement} extends to the end of the enclosing scope,
-as was the case in old versions of G++, and other (traditional)
-implementations of C++.
-
-If neither flag is given, the default is to follow the standard,
-but to allow and give a warning for old-style code that would
-otherwise be invalid, or have different behavior.
-
-@item -fno-gnu-keywords
-@opindex fno-gnu-keywords
-Do not recognize @code{typeof} as a keyword, so that code can use this
-word as an identifier. You can use the keyword @code{__typeof__} instead.
-@option{-ansi} implies @option{-fno-gnu-keywords}.
-
-@item -fno-implicit-templates
-@opindex fno-implicit-templates
-Never emit code for non-inline templates that are instantiated
-implicitly (i.e.@: by use); only emit code for explicit instantiations.
-@xref{Template Instantiation}, for more information.
-
-@item -fno-implicit-inline-templates
-@opindex fno-implicit-inline-templates
-Don't emit code for implicit instantiations of inline templates, either.
-The default is to handle inlines differently so that compiles with and
-without optimization need the same set of explicit instantiations.
-
-@item -fno-implement-inlines
-@opindex fno-implement-inlines
-To save space, do not emit out-of-line copies of inline functions
-controlled by @samp{#pragma implementation}. This causes linker
-errors if these functions are not inlined everywhere they are called.
-
-@item -fms-extensions
-@opindex fms-extensions
-Disable Wpedantic warnings about constructs used in MFC, such as implicit
-int and getting a pointer to member function via non-standard syntax.
-
-@item -fno-nonansi-builtins
-@opindex fno-nonansi-builtins
-Disable built-in declarations of functions that are not mandated by
-ANSI/ISO C@. These include @code{ffs}, @code{alloca}, @code{_exit},
-@code{index}, @code{bzero}, @code{conjf}, and other related functions.
-
-@item -fnothrow-opt
-@opindex fnothrow-opt
-Treat a @code{throw()} exception specification as if it were a
-@code{noexcept} specification to reduce or eliminate the text size
-overhead relative to a function with no exception specification. If
-the function has local variables of types with non-trivial
-destructors, the exception specification actually makes the
-function smaller because the EH cleanups for those variables can be
-optimized away. The semantic effect is that an exception thrown out of
-a function with such an exception specification results in a call
-to @code{terminate} rather than @code{unexpected}.
-
-@item -fno-operator-names
-@opindex fno-operator-names
-Do not treat the operator name keywords @code{and}, @code{bitand},
-@code{bitor}, @code{compl}, @code{not}, @code{or} and @code{xor} as
-synonyms as keywords.
-
-@item -fno-optional-diags
-@opindex fno-optional-diags
-Disable diagnostics that the standard says a compiler does not need to
-issue. Currently, the only such diagnostic issued by G++ is the one for
-a name having multiple meanings within a class.
-
-@item -fpermissive
-@opindex fpermissive
-Downgrade some diagnostics about nonconformant code from errors to
-warnings. Thus, using @option{-fpermissive} allows some
-nonconforming code to compile.
-
-@item -fno-pretty-templates
-@opindex fno-pretty-templates
-When an error message refers to a specialization of a function
-template, the compiler normally prints the signature of the
-template followed by the template arguments and any typedefs or
-typenames in the signature (e.g. @code{void f(T) [with T = int]}
-rather than @code{void f(int)}) so that it's clear which template is
-involved. When an error message refers to a specialization of a class
-template, the compiler omits any template arguments that match
-the default template arguments for that template. If either of these
-behaviors make it harder to understand the error message rather than
-easier, you can use @option{-fno-pretty-templates} to disable them.
-
-@item -frepo
-@opindex frepo
-Enable automatic template instantiation at link time. This option also
-implies @option{-fno-implicit-templates}. @xref{Template
-Instantiation}, for more information.
-
-@item -fno-rtti
-@opindex fno-rtti
-Disable generation of information about every class with virtual
-functions for use by the C++ run-time type identification features
-(@samp{dynamic_cast} and @samp{typeid}). If you don't use those parts
-of the language, you can save some space by using this flag. Note that
-exception handling uses the same information, but G++ generates it as
-needed. The @samp{dynamic_cast} operator can still be used for casts that
-do not require run-time type information, i.e.@: casts to @code{void *} or to
-unambiguous base classes.
-
-@item -fstats
-@opindex fstats
-Emit statistics about front-end processing at the end of the compilation.
-This information is generally only useful to the G++ development team.
-
-@item -fstrict-enums
-@opindex fstrict-enums
-Allow the compiler to optimize using the assumption that a value of
-enumerated type can only be one of the values of the enumeration (as
-defined in the C++ standard; basically, a value that can be
-represented in the minimum number of bits needed to represent all the
-enumerators). This assumption may not be valid if the program uses a
-cast to convert an arbitrary integer value to the enumerated type.
-
-@item -ftemplate-backtrace-limit=@var{n}
-@opindex ftemplate-backtrace-limit
-Set the maximum number of template instantiation notes for a single
-warning or error to @var{n}. The default value is 10.
-
-@item -ftemplate-depth=@var{n}
-@opindex ftemplate-depth
-Set the maximum instantiation depth for template classes to @var{n}.
-A limit on the template instantiation depth is needed to detect
-endless recursions during template class instantiation. ANSI/ISO C++
-conforming programs must not rely on a maximum depth greater than 17
-(changed to 1024 in C++11). The default value is 900, as the compiler
-can run out of stack space before hitting 1024 in some situations.
-
-@item -fno-threadsafe-statics
-@opindex fno-threadsafe-statics
-Do not emit the extra code to use the routines specified in the C++
-ABI for thread-safe initialization of local statics. You can use this
-option to reduce code size slightly in code that doesn't need to be
-thread-safe.
-
-@item -fuse-cxa-atexit
-@opindex fuse-cxa-atexit
-Register destructors for objects with static storage duration with the
-@code{__cxa_atexit} function rather than the @code{atexit} function.
-This option is required for fully standards-compliant handling of static
-destructors, but only works if your C library supports
-@code{__cxa_atexit}.
-
-@item -fno-use-cxa-get-exception-ptr
-@opindex fno-use-cxa-get-exception-ptr
-Don't use the @code{__cxa_get_exception_ptr} runtime routine. This
-causes @code{std::uncaught_exception} to be incorrect, but is necessary
-if the runtime routine is not available.
-
-@item -fvisibility-inlines-hidden
-@opindex fvisibility-inlines-hidden
-This switch declares that the user does not attempt to compare
-pointers to inline functions or methods where the addresses of the two functions
-are taken in different shared objects.
-
-The effect of this is that GCC may, effectively, mark inline methods with
-@code{__attribute__ ((visibility ("hidden")))} so that they do not
-appear in the export table of a DSO and do not require a PLT indirection
-when used within the DSO@. Enabling this option can have a dramatic effect
-on load and link times of a DSO as it massively reduces the size of the
-dynamic export table when the library makes heavy use of templates.
-
-The behavior of this switch is not quite the same as marking the
-methods as hidden directly, because it does not affect static variables
-local to the function or cause the compiler to deduce that
-the function is defined in only one shared object.
-
-You may mark a method as having a visibility explicitly to negate the
-effect of the switch for that method. For example, if you do want to
-compare pointers to a particular inline method, you might mark it as
-having default visibility. Marking the enclosing class with explicit
-visibility has no effect.
-
-Explicitly instantiated inline methods are unaffected by this option
-as their linkage might otherwise cross a shared library boundary.
-@xref{Template Instantiation}.
-
-@item -fvisibility-ms-compat
-@opindex fvisibility-ms-compat
-This flag attempts to use visibility settings to make GCC's C++
-linkage model compatible with that of Microsoft Visual Studio.
-
-The flag makes these changes to GCC's linkage model:
-
-@enumerate
-@item
-It sets the default visibility to @code{hidden}, like
-@option{-fvisibility=hidden}.
-
-@item
-Types, but not their members, are not hidden by default.
-
-@item
-The One Definition Rule is relaxed for types without explicit
-visibility specifications that are defined in more than one
-shared object: those declarations are permitted if they are
-permitted when this option is not used.
-@end enumerate
-
-In new code it is better to use @option{-fvisibility=hidden} and
-export those classes that are intended to be externally visible.
-Unfortunately it is possible for code to rely, perhaps accidentally,
-on the Visual Studio behavior.
-
-Among the consequences of these changes are that static data members
-of the same type with the same name but defined in different shared
-objects are different, so changing one does not change the other;
-and that pointers to function members defined in different shared
-objects may not compare equal. When this flag is given, it is a
-violation of the ODR to define types with the same name differently.
-
-@item -fno-weak
-@opindex fno-weak
-Do not use weak symbol support, even if it is provided by the linker.
-By default, G++ uses weak symbols if they are available. This
-option exists only for testing, and should not be used by end-users;
-it results in inferior code and has no benefits. This option may
-be removed in a future release of G++.
-
-@item -nostdinc++
-@opindex nostdinc++
-Do not search for header files in the standard directories specific to
-C++, but do still search the other standard directories. (This option
-is used when building the C++ library.)
-@end table
-
-In addition, these optimization, warning, and code generation options
-have meanings only for C++ programs:
-
-@table @gcctabopt
-@item -fno-default-inline
-@opindex fno-default-inline
-Do not assume @samp{inline} for functions defined inside a class scope.
-@xref{Optimize Options,,Options That Control Optimization}. Note that these
-functions have linkage like inline functions; they just aren't
-inlined by default.
-
-@item -Wabi @r{(C, Objective-C, C++ and Objective-C++ only)}
-@opindex Wabi
-@opindex Wno-abi
-Warn when G++ generates code that is probably not compatible with the
-vendor-neutral C++ ABI@. Although an effort has been made to warn about
-all such cases, there are probably some cases that are not warned about,
-even though G++ is generating incompatible code. There may also be
-cases where warnings are emitted even though the code that is generated
-is compatible.
-
-You should rewrite your code to avoid these warnings if you are
-concerned about the fact that code generated by G++ may not be binary
-compatible with code generated by other compilers.
-
-The known incompatibilities in @option{-fabi-version=2} (the default) include:
-
-@itemize @bullet
-
-@item
-A template with a non-type template parameter of reference type is
-mangled incorrectly:
-@smallexample
-extern int N;
-template <int &> struct S @{@};
-void n (S<N>) @{2@}
-@end smallexample
-
-This is fixed in @option{-fabi-version=3}.
-
-@item
-SIMD vector types declared using @code{__attribute ((vector_size))} are
-mangled in a non-standard way that does not allow for overloading of
-functions taking vectors of different sizes.
-
-The mangling is changed in @option{-fabi-version=4}.
-@end itemize
-
-The known incompatibilities in @option{-fabi-version=1} include:
-
-@itemize @bullet
-
-@item
-Incorrect handling of tail-padding for bit-fields. G++ may attempt to
-pack data into the same byte as a base class. For example:
-
-@smallexample
-struct A @{ virtual void f(); int f1 : 1; @};
-struct B : public A @{ int f2 : 1; @};
-@end smallexample
-
-@noindent
-In this case, G++ places @code{B::f2} into the same byte
-as @code{A::f1}; other compilers do not. You can avoid this problem
-by explicitly padding @code{A} so that its size is a multiple of the
-byte size on your platform; that causes G++ and other compilers to
-lay out @code{B} identically.
-
-@item
-Incorrect handling of tail-padding for virtual bases. G++ does not use
-tail padding when laying out virtual bases. For example:
-
-@smallexample
-struct A @{ virtual void f(); char c1; @};
-struct B @{ B(); char c2; @};
-struct C : public A, public virtual B @{@};
-@end smallexample
-
-@noindent
-In this case, G++ does not place @code{B} into the tail-padding for
-@code{A}; other compilers do. You can avoid this problem by
-explicitly padding @code{A} so that its size is a multiple of its
-alignment (ignoring virtual base classes); that causes G++ and other
-compilers to lay out @code{C} identically.
-
-@item
-Incorrect handling of bit-fields with declared widths greater than that
-of their underlying types, when the bit-fields appear in a union. For
-example:
-
-@smallexample
-union U @{ int i : 4096; @};
-@end smallexample
-
-@noindent
-Assuming that an @code{int} does not have 4096 bits, G++ makes the
-union too small by the number of bits in an @code{int}.
-
-@item
-Empty classes can be placed at incorrect offsets. For example:
-
-@smallexample
-struct A @{@};
-
-struct B @{
- A a;
- virtual void f ();
-@};
-
-struct C : public B, public A @{@};
-@end smallexample
-
-@noindent
-G++ places the @code{A} base class of @code{C} at a nonzero offset;
-it should be placed at offset zero. G++ mistakenly believes that the
-@code{A} data member of @code{B} is already at offset zero.
-
-@item
-Names of template functions whose types involve @code{typename} or
-template template parameters can be mangled incorrectly.
-
-@smallexample
-template <typename Q>
-void f(typename Q::X) @{@}
-
-template <template <typename> class Q>
-void f(typename Q<int>::X) @{@}
-@end smallexample
-
-@noindent
-Instantiations of these templates may be mangled incorrectly.
-
-@end itemize
-
-It also warns about psABI-related changes. The known psABI changes at this
-point include:
-
-@itemize @bullet
-
-@item
-For SysV/x86-64, unions with @code{long double} members are
-passed in memory as specified in psABI. For example:
-
-@smallexample
-union U @{
- long double ld;
- int i;
-@};
-@end smallexample
-
-@noindent
-@code{union U} is always passed in memory.
-
-@end itemize
-
-@item -Wctor-dtor-privacy @r{(C++ and Objective-C++ only)}
-@opindex Wctor-dtor-privacy
-@opindex Wno-ctor-dtor-privacy
-Warn when a class seems unusable because all the constructors or
-destructors in that class are private, and it has neither friends nor
-public static member functions. Also warn if there are no non-private
-methods, and there's at least one private member function that isn't
-a constructor or destructor.
-
-@item -Wdelete-non-virtual-dtor @r{(C++ and Objective-C++ only)}
-@opindex Wdelete-non-virtual-dtor
-@opindex Wno-delete-non-virtual-dtor
-Warn when @samp{delete} is used to destroy an instance of a class that
-has virtual functions and non-virtual destructor. It is unsafe to delete
-an instance of a derived class through a pointer to a base class if the
-base class does not have a virtual destructor. This warning is enabled
-by @option{-Wall}.
-
-@item -Wliteral-suffix @r{(C++ and Objective-C++ only)}
-@opindex Wliteral-suffix
-@opindex Wno-literal-suffix
-Warn when a string or character literal is followed by a ud-suffix which does
-not begin with an underscore. As a conforming extension, GCC treats such
-suffixes as separate preprocessing tokens in order to maintain backwards
-compatibility with code that uses formatting macros from @code{<inttypes.h>}.
-For example:
-
-@smallexample
-#define __STDC_FORMAT_MACROS
-#include <inttypes.h>
-#include <stdio.h>
-
-int main() @{
- int64_t i64 = 123;
- printf("My int64: %"PRId64"\n", i64);
-@}
-@end smallexample
-
-In this case, @code{PRId64} is treated as a separate preprocessing token.
-
-This warning is enabled by default.
-
-@item -Wnarrowing @r{(C++ and Objective-C++ only)}
-@opindex Wnarrowing
-@opindex Wno-narrowing
-Warn when a narrowing conversion prohibited by C++11 occurs within
-@samp{@{ @}}, e.g.
-
-@smallexample
-int i = @{ 2.2 @}; // error: narrowing from double to int
-@end smallexample
-
-This flag is included in @option{-Wall} and @option{-Wc++11-compat}.
-
-With @option{-std=c++11}, @option{-Wno-narrowing} suppresses the diagnostic
-required by the standard. Note that this does not affect the meaning
-of well-formed code; narrowing conversions are still considered
-ill-formed in SFINAE context.
-
-@item -Wnoexcept @r{(C++ and Objective-C++ only)}
-@opindex Wnoexcept
-@opindex Wno-noexcept
-Warn when a noexcept-expression evaluates to false because of a call
-to a function that does not have a non-throwing exception
-specification (i.e. @samp{throw()} or @samp{noexcept}) but is known by
-the compiler to never throw an exception.
-
-@item -Wnon-virtual-dtor @r{(C++ and Objective-C++ only)}
-@opindex Wnon-virtual-dtor
-@opindex Wno-non-virtual-dtor
-Warn when a class has virtual functions and an accessible non-virtual
-destructor, in which case it is possible but unsafe to delete
-an instance of a derived class through a pointer to the base class.
-This warning is also enabled if @option{-Weffc++} is specified.
-
-@item -Wreorder @r{(C++ and Objective-C++ only)}
-@opindex Wreorder
-@opindex Wno-reorder
-@cindex reordering, warning
-@cindex warning for reordering of member initializers
-Warn when the order of member initializers given in the code does not
-match the order in which they must be executed. For instance:
-
-@smallexample
-struct A @{
- int i;
- int j;
- A(): j (0), i (1) @{ @}
-@};
-@end smallexample
-
-@noindent
-The compiler rearranges the member initializers for @samp{i}
-and @samp{j} to match the declaration order of the members, emitting
-a warning to that effect. This warning is enabled by @option{-Wall}.
-
-@item -fext-numeric-literals @r{(C++ and Objective-C++ only)}
-@opindex fext-numeric-literals
-@opindex fno-ext-numeric-literals
-Accept imaginary, fixed-point, or machine-defined
-literal number suffixes as GNU extensions.
-When this option is turned off these suffixes are treated
-as C++11 user-defined literal numeric suffixes.
-This is on by default for all pre-C++11 dialects and all GNU dialects:
-@option{-std=c++98}, @option{-std=gnu++98}, @option{-std=gnu++11},
-@option{-std=gnu++1y}.
-This option is off by default
-for ISO C++11 onwards (@option{-std=c++11}, ...).
-@end table
-
-The following @option{-W@dots{}} options are not affected by @option{-Wall}.
-
-@table @gcctabopt
-@item -Weffc++ @r{(C++ and Objective-C++ only)}
-@opindex Weffc++
-@opindex Wno-effc++
-Warn about violations of the following style guidelines from Scott Meyers'
-@cite{Effective C++, Second Edition} book:
-
-@itemize @bullet
-@item
-Item 11: Define a copy constructor and an assignment operator for classes
-with dynamically-allocated memory.
-
-@item
-Item 12: Prefer initialization to assignment in constructors.
-
-@item
-Item 14: Make destructors virtual in base classes.
-
-@item
-Item 15: Have @code{operator=} return a reference to @code{*this}.
-
-@item
-Item 23: Don't try to return a reference when you must return an object.
-
-@end itemize
-
-Also warn about violations of the following style guidelines from
-Scott Meyers' @cite{More Effective C++} book:
-
-@itemize @bullet
-@item
-Item 6: Distinguish between prefix and postfix forms of increment and
-decrement operators.
-
-@item
-Item 7: Never overload @code{&&}, @code{||}, or @code{,}.
-
-@end itemize
-
-When selecting this option, be aware that the standard library
-headers do not obey all of these guidelines; use @samp{grep -v}
-to filter out those warnings.
-
-@item -Wstrict-null-sentinel @r{(C++ and Objective-C++ only)}
-@opindex Wstrict-null-sentinel
-@opindex Wno-strict-null-sentinel
-Warn about the use of an uncasted @code{NULL} as sentinel. When
-compiling only with GCC this is a valid sentinel, as @code{NULL} is defined
-to @code{__null}. Although it is a null pointer constant rather than a
-null pointer, it is guaranteed to be of the same size as a pointer.
-But this use is not portable across different compilers.
-
-@item -Wno-non-template-friend @r{(C++ and Objective-C++ only)}
-@opindex Wno-non-template-friend
-@opindex Wnon-template-friend
-Disable warnings when non-templatized friend functions are declared
-within a template. Since the advent of explicit template specification
-support in G++, if the name of the friend is an unqualified-id (i.e.,
-@samp{friend foo(int)}), the C++ language specification demands that the
-friend declare or define an ordinary, nontemplate function. (Section
-14.5.3). Before G++ implemented explicit specification, unqualified-ids
-could be interpreted as a particular specialization of a templatized
-function. Because this non-conforming behavior is no longer the default
-behavior for G++, @option{-Wnon-template-friend} allows the compiler to
-check existing code for potential trouble spots and is on by default.
-This new compiler behavior can be turned off with
-@option{-Wno-non-template-friend}, which keeps the conformant compiler code
-but disables the helpful warning.
-
-@item -Wold-style-cast @r{(C++ and Objective-C++ only)}
-@opindex Wold-style-cast
-@opindex Wno-old-style-cast
-Warn if an old-style (C-style) cast to a non-void type is used within
-a C++ program. The new-style casts (@samp{dynamic_cast},
-@samp{static_cast}, @samp{reinterpret_cast}, and @samp{const_cast}) are
-less vulnerable to unintended effects and much easier to search for.
-
-@item -Woverloaded-virtual @r{(C++ and Objective-C++ only)}
-@opindex Woverloaded-virtual
-@opindex Wno-overloaded-virtual
-@cindex overloaded virtual function, warning
-@cindex warning for overloaded virtual function
-Warn when a function declaration hides virtual functions from a
-base class. For example, in:
-
-@smallexample
-struct A @{
- virtual void f();
-@};
-
-struct B: public A @{
- void f(int);
-@};
-@end smallexample
-
-the @code{A} class version of @code{f} is hidden in @code{B}, and code
-like:
-
-@smallexample
-B* b;
-b->f();
-@end smallexample
-
-@noindent
-fails to compile.
-
-@item -Wno-pmf-conversions @r{(C++ and Objective-C++ only)}
-@opindex Wno-pmf-conversions
-@opindex Wpmf-conversions
-Disable the diagnostic for converting a bound pointer to member function
-to a plain pointer.
-
-@item -Wsign-promo @r{(C++ and Objective-C++ only)}
-@opindex Wsign-promo
-@opindex Wno-sign-promo
-Warn when overload resolution chooses a promotion from unsigned or
-enumerated type to a signed type, over a conversion to an unsigned type of
-the same size. Previous versions of G++ tried to preserve
-unsignedness, but the standard mandates the current behavior.
-@end table
-
-@node Objective-C and Objective-C++ Dialect Options
-@section Options Controlling Objective-C and Objective-C++ Dialects
-
-@cindex compiler options, Objective-C and Objective-C++
-@cindex Objective-C and Objective-C++ options, command-line
-@cindex options, Objective-C and Objective-C++
-(NOTE: This manual does not describe the Objective-C and Objective-C++
-languages themselves. @xref{Standards,,Language Standards
-Supported by GCC}, for references.)
-
-This section describes the command-line options that are only meaningful
-for Objective-C and Objective-C++ programs. You can also use most of
-the language-independent GNU compiler options.
-For example, you might compile a file @code{some_class.m} like this:
-
-@smallexample
-gcc -g -fgnu-runtime -O -c some_class.m
-@end smallexample
-
-@noindent
-In this example, @option{-fgnu-runtime} is an option meant only for
-Objective-C and Objective-C++ programs; you can use the other options with
-any language supported by GCC@.
-
-Note that since Objective-C is an extension of the C language, Objective-C
-compilations may also use options specific to the C front-end (e.g.,
-@option{-Wtraditional}). Similarly, Objective-C++ compilations may use
-C++-specific options (e.g., @option{-Wabi}).
-
-Here is a list of options that are @emph{only} for compiling Objective-C
-and Objective-C++ programs:
-
-@table @gcctabopt
-@item -fconstant-string-class=@var{class-name}
-@opindex fconstant-string-class
-Use @var{class-name} as the name of the class to instantiate for each
-literal string specified with the syntax @code{@@"@dots{}"}. The default
-class name is @code{NXConstantString} if the GNU runtime is being used, and
-@code{NSConstantString} if the NeXT runtime is being used (see below). The
-@option{-fconstant-cfstrings} option, if also present, overrides the
-@option{-fconstant-string-class} setting and cause @code{@@"@dots{}"} literals
-to be laid out as constant CoreFoundation strings.
-
-@item -fgnu-runtime
-@opindex fgnu-runtime
-Generate object code compatible with the standard GNU Objective-C
-runtime. This is the default for most types of systems.
-
-@item -fnext-runtime
-@opindex fnext-runtime
-Generate output compatible with the NeXT runtime. This is the default
-for NeXT-based systems, including Darwin and Mac OS X@. The macro
-@code{__NEXT_RUNTIME__} is predefined if (and only if) this option is
-used.
-
-@item -fno-nil-receivers
-@opindex fno-nil-receivers
-Assume that all Objective-C message dispatches (@code{[receiver
-message:arg]}) in this translation unit ensure that the receiver is
-not @code{nil}. This allows for more efficient entry points in the
-runtime to be used. This option is only available in conjunction with
-the NeXT runtime and ABI version 0 or 1.
-
-@item -fobjc-abi-version=@var{n}
-@opindex fobjc-abi-version
-Use version @var{n} of the Objective-C ABI for the selected runtime.
-This option is currently supported only for the NeXT runtime. In that
-case, Version 0 is the traditional (32-bit) ABI without support for
-properties and other Objective-C 2.0 additions. Version 1 is the
-traditional (32-bit) ABI with support for properties and other
-Objective-C 2.0 additions. Version 2 is the modern (64-bit) ABI. If
-nothing is specified, the default is Version 0 on 32-bit target
-machines, and Version 2 on 64-bit target machines.
-
-@item -fobjc-call-cxx-cdtors
-@opindex fobjc-call-cxx-cdtors
-For each Objective-C class, check if any of its instance variables is a
-C++ object with a non-trivial default constructor. If so, synthesize a
-special @code{- (id) .cxx_construct} instance method which runs
-non-trivial default constructors on any such instance variables, in order,
-and then return @code{self}. Similarly, check if any instance variable
-is a C++ object with a non-trivial destructor, and if so, synthesize a
-special @code{- (void) .cxx_destruct} method which runs
-all such default destructors, in reverse order.
-
-The @code{- (id) .cxx_construct} and @code{- (void) .cxx_destruct}
-methods thusly generated only operate on instance variables
-declared in the current Objective-C class, and not those inherited
-from superclasses. It is the responsibility of the Objective-C
-runtime to invoke all such methods in an object's inheritance
-hierarchy. The @code{- (id) .cxx_construct} methods are invoked
-by the runtime immediately after a new object instance is allocated;
-the @code{- (void) .cxx_destruct} methods are invoked immediately
-before the runtime deallocates an object instance.
-
-As of this writing, only the NeXT runtime on Mac OS X 10.4 and later has
-support for invoking the @code{- (id) .cxx_construct} and
-@code{- (void) .cxx_destruct} methods.
-
-@item -fobjc-direct-dispatch
-@opindex fobjc-direct-dispatch
-Allow fast jumps to the message dispatcher. On Darwin this is
-accomplished via the comm page.
-
-@item -fobjc-exceptions
-@opindex fobjc-exceptions
-Enable syntactic support for structured exception handling in
-Objective-C, similar to what is offered by C++ and Java. This option
-is required to use the Objective-C keywords @code{@@try},
-@code{@@throw}, @code{@@catch}, @code{@@finally} and
-@code{@@synchronized}. This option is available with both the GNU
-runtime and the NeXT runtime (but not available in conjunction with
-the NeXT runtime on Mac OS X 10.2 and earlier).
-
-@item -fobjc-gc
-@opindex fobjc-gc
-Enable garbage collection (GC) in Objective-C and Objective-C++
-programs. This option is only available with the NeXT runtime; the
-GNU runtime has a different garbage collection implementation that
-does not require special compiler flags.
-
-@item -fobjc-nilcheck
-@opindex fobjc-nilcheck
-For the NeXT runtime with version 2 of the ABI, check for a nil
-receiver in method invocations before doing the actual method call.
-This is the default and can be disabled using
-@option{-fno-objc-nilcheck}. Class methods and super calls are never
-checked for nil in this way no matter what this flag is set to.
-Currently this flag does nothing when the GNU runtime, or an older
-version of the NeXT runtime ABI, is used.
-
-@item -fobjc-std=objc1
-@opindex fobjc-std
-Conform to the language syntax of Objective-C 1.0, the language
-recognized by GCC 4.0. This only affects the Objective-C additions to
-the C/C++ language; it does not affect conformance to C/C++ standards,
-which is controlled by the separate C/C++ dialect option flags. When
-this option is used with the Objective-C or Objective-C++ compiler,
-any Objective-C syntax that is not recognized by GCC 4.0 is rejected.
-This is useful if you need to make sure that your Objective-C code can
-be compiled with older versions of GCC@.
-
-@item -freplace-objc-classes
-@opindex freplace-objc-classes
-Emit a special marker instructing @command{ld(1)} not to statically link in
-the resulting object file, and allow @command{dyld(1)} to load it in at
-run time instead. This is used in conjunction with the Fix-and-Continue
-debugging mode, where the object file in question may be recompiled and
-dynamically reloaded in the course of program execution, without the need
-to restart the program itself. Currently, Fix-and-Continue functionality
-is only available in conjunction with the NeXT runtime on Mac OS X 10.3
-and later.
-
-@item -fzero-link
-@opindex fzero-link
-When compiling for the NeXT runtime, the compiler ordinarily replaces calls
-to @code{objc_getClass("@dots{}")} (when the name of the class is known at
-compile time) with static class references that get initialized at load time,
-which improves run-time performance. Specifying the @option{-fzero-link} flag
-suppresses this behavior and causes calls to @code{objc_getClass("@dots{}")}
-to be retained. This is useful in Zero-Link debugging mode, since it allows
-for individual class implementations to be modified during program execution.
-The GNU runtime currently always retains calls to @code{objc_get_class("@dots{}")}
-regardless of command-line options.
-
-@item -gen-decls
-@opindex gen-decls
-Dump interface declarations for all classes seen in the source file to a
-file named @file{@var{sourcename}.decl}.
-
-@item -Wassign-intercept @r{(Objective-C and Objective-C++ only)}
-@opindex Wassign-intercept
-@opindex Wno-assign-intercept
-Warn whenever an Objective-C assignment is being intercepted by the
-garbage collector.
-
-@item -Wno-protocol @r{(Objective-C and Objective-C++ only)}
-@opindex Wno-protocol
-@opindex Wprotocol
-If a class is declared to implement a protocol, a warning is issued for
-every method in the protocol that is not implemented by the class. The
-default behavior is to issue a warning for every method not explicitly
-implemented in the class, even if a method implementation is inherited
-from the superclass. If you use the @option{-Wno-protocol} option, then
-methods inherited from the superclass are considered to be implemented,
-and no warning is issued for them.
-
-@item -Wselector @r{(Objective-C and Objective-C++ only)}
-@opindex Wselector
-@opindex Wno-selector
-Warn if multiple methods of different types for the same selector are
-found during compilation. The check is performed on the list of methods
-in the final stage of compilation. Additionally, a check is performed
-for each selector appearing in a @code{@@selector(@dots{})}
-expression, and a corresponding method for that selector has been found
-during compilation. Because these checks scan the method table only at
-the end of compilation, these warnings are not produced if the final
-stage of compilation is not reached, for example because an error is
-found during compilation, or because the @option{-fsyntax-only} option is
-being used.
-
-@item -Wstrict-selector-match @r{(Objective-C and Objective-C++ only)}
-@opindex Wstrict-selector-match
-@opindex Wno-strict-selector-match
-Warn if multiple methods with differing argument and/or return types are
-found for a given selector when attempting to send a message using this
-selector to a receiver of type @code{id} or @code{Class}. When this flag
-is off (which is the default behavior), the compiler omits such warnings
-if any differences found are confined to types that share the same size
-and alignment.
-
-@item -Wundeclared-selector @r{(Objective-C and Objective-C++ only)}
-@opindex Wundeclared-selector
-@opindex Wno-undeclared-selector
-Warn if a @code{@@selector(@dots{})} expression referring to an
-undeclared selector is found. A selector is considered undeclared if no
-method with that name has been declared before the
-@code{@@selector(@dots{})} expression, either explicitly in an
-@code{@@interface} or @code{@@protocol} declaration, or implicitly in
-an @code{@@implementation} section. This option always performs its
-checks as soon as a @code{@@selector(@dots{})} expression is found,
-while @option{-Wselector} only performs its checks in the final stage of
-compilation. This also enforces the coding style convention
-that methods and selectors must be declared before being used.
-
-@item -print-objc-runtime-info
-@opindex print-objc-runtime-info
-Generate C header describing the largest structure that is passed by
-value, if any.
-
-@end table
-
-@node Language Independent Options
-@section Options to Control Diagnostic Messages Formatting
-@cindex options to control diagnostics formatting
-@cindex diagnostic messages
-@cindex message formatting
-
-Traditionally, diagnostic messages have been formatted irrespective of
-the output device's aspect (e.g.@: its width, @dots{}). You can use the
-options described below
-to control the formatting algorithm for diagnostic messages,
-e.g.@: how many characters per line, how often source location
-information should be reported. Note that some language front ends may not
-honor these options.
-
-@table @gcctabopt
-@item -fmessage-length=@var{n}
-@opindex fmessage-length
-Try to format error messages so that they fit on lines of about @var{n}
-characters. The default is 72 characters for @command{g++} and 0 for the rest of
-the front ends supported by GCC@. If @var{n} is zero, then no
-line-wrapping is done; each error message appears on a single
-line.
-
-@item -fdiagnostics-show-location=once
-@opindex fdiagnostics-show-location
-Only meaningful in line-wrapping mode. Instructs the diagnostic messages
-reporter to emit source location information @emph{once}; that is, in
-case the message is too long to fit on a single physical line and has to
-be wrapped, the source location won't be emitted (as prefix) again,
-over and over, in subsequent continuation lines. This is the default
-behavior.
-
-@item -fdiagnostics-show-location=every-line
-Only meaningful in line-wrapping mode. Instructs the diagnostic
-messages reporter to emit the same source location information (as
-prefix) for physical lines that result from the process of breaking
-a message which is too long to fit on a single line.
-
-@item -fdiagnostics-color[=@var{WHEN}]
-@itemx -fno-diagnostics-color
-@opindex fdiagnostics-color
-@cindex highlight, color, colour
-@vindex GCC_COLORS @r{environment variable}
-Use color in diagnostics. @var{WHEN} is @samp{never}, @samp{always},
-or @samp{auto}. The default is @samp{never} if @env{GCC_COLORS} environment
-variable isn't present in the environment, and @samp{auto} otherwise.
-@samp{auto} means to use color only when the standard error is a terminal.
-The forms @option{-fdiagnostics-color} and @option{-fno-diagnostics-color} are
-aliases for @option{-fdiagnostics-color=always} and
-@option{-fdiagnostics-color=never}, respectively.
-
-The colors are defined by the environment variable @env{GCC_COLORS}.
-Its value is a colon-separated list of capabilities and Select Graphic
-Rendition (SGR) substrings. SGR commands are interpreted by the
-terminal or terminal emulator. (See the section in the documentation
-of your text terminal for permitted values and their meanings as
-character attributes.) These substring values are integers in decimal
-representation and can be concatenated with semicolons.
-Common values to concatenate include
-@samp{1} for bold,
-@samp{4} for underline,
-@samp{5} for blink,
-@samp{7} for inverse,
-@samp{39} for default foreground color,
-@samp{30} to @samp{37} for foreground colors,
-@samp{90} to @samp{97} for 16-color mode foreground colors,
-@samp{38;5;0} to @samp{38;5;255}
-for 88-color and 256-color modes foreground colors,
-@samp{49} for default background color,
-@samp{40} to @samp{47} for background colors,
-@samp{100} to @samp{107} for 16-color mode background colors,
-and @samp{48;5;0} to @samp{48;5;255}
-for 88-color and 256-color modes background colors.
-
-The default @env{GCC_COLORS} is
-@samp{error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01}
-where @samp{01;31} is bold red, @samp{01;35} is bold magenta,
-@samp{01;36} is bold cyan, @samp{01;32} is bold green and
-@samp{01} is bold. Setting @env{GCC_COLORS} to the empty
-string disables colors.
-Supported capabilities are as follows.
-
-@table @code
-@item error=
-@vindex error GCC_COLORS @r{capability}
-SGR substring for error: markers.
-
-@item warning=
-@vindex warning GCC_COLORS @r{capability}
-SGR substring for warning: markers.
-
-@item note=
-@vindex note GCC_COLORS @r{capability}
-SGR substring for note: markers.
-
-@item caret=
-@vindex caret GCC_COLORS @r{capability}
-SGR substring for caret line.
-
-@item locus=
-@vindex locus GCC_COLORS @r{capability}
-SGR substring for location information, @samp{file:line} or
-@samp{file:line:column} etc.
-
-@item quote=
-@vindex quote GCC_COLORS @r{capability}
-SGR substring for information printed within quotes.
-@end table
-
-@item -fno-diagnostics-show-option
-@opindex fno-diagnostics-show-option
-@opindex fdiagnostics-show-option
-By default, each diagnostic emitted includes text indicating the
-command-line option that directly controls the diagnostic (if such an
-option is known to the diagnostic machinery). Specifying the
-@option{-fno-diagnostics-show-option} flag suppresses that behavior.
-
-@item -fno-diagnostics-show-caret
-@opindex fno-diagnostics-show-caret
-@opindex fdiagnostics-show-caret
-By default, each diagnostic emitted includes the original source line
-and a caret '^' indicating the column. This option suppresses this
-information.
-
-@end table
-
-@node Warning Options
-@section Options to Request or Suppress Warnings
-@cindex options to control warnings
-@cindex warning messages
-@cindex messages, warning
-@cindex suppressing warnings
-
-Warnings are diagnostic messages that report constructions that
-are not inherently erroneous but that are risky or suggest there
-may have been an error.
-
-The following language-independent options do not enable specific
-warnings but control the kinds of diagnostics produced by GCC@.
-
-@table @gcctabopt
-@cindex syntax checking
-@item -fsyntax-only
-@opindex fsyntax-only
-Check the code for syntax errors, but don't do anything beyond that.
-
-@item -fmax-errors=@var{n}
-@opindex fmax-errors
-Limits the maximum number of error messages to @var{n}, at which point
-GCC bails out rather than attempting to continue processing the source
-code. If @var{n} is 0 (the default), there is no limit on the number
-of error messages produced. If @option{-Wfatal-errors} is also
-specified, then @option{-Wfatal-errors} takes precedence over this
-option.
-
-@item -w
-@opindex w
-Inhibit all warning messages.
-
-@item -Werror
-@opindex Werror
-@opindex Wno-error
-Make all warnings into errors.
-
-@item -Werror=
-@opindex Werror=
-@opindex Wno-error=
-Make the specified warning into an error. The specifier for a warning
-is appended; for example @option{-Werror=switch} turns the warnings
-controlled by @option{-Wswitch} into errors. This switch takes a
-negative form, to be used to negate @option{-Werror} for specific
-warnings; for example @option{-Wno-error=switch} makes
-@option{-Wswitch} warnings not be errors, even when @option{-Werror}
-is in effect.
-
-The warning message for each controllable warning includes the
-option that controls the warning. That option can then be used with
-@option{-Werror=} and @option{-Wno-error=} as described above.
-(Printing of the option in the warning message can be disabled using the
-@option{-fno-diagnostics-show-option} flag.)
-
-Note that specifying @option{-Werror=}@var{foo} automatically implies
-@option{-W}@var{foo}. However, @option{-Wno-error=}@var{foo} does not
-imply anything.
-
-@item -Wfatal-errors
-@opindex Wfatal-errors
-@opindex Wno-fatal-errors
-This option causes the compiler to abort compilation on the first error
-occurred rather than trying to keep going and printing further error
-messages.
-
-@end table
-
-You can request many specific warnings with options beginning with
-@samp{-W}, for example @option{-Wimplicit} to request warnings on
-implicit declarations. Each of these specific warning options also
-has a negative form beginning @samp{-Wno-} to turn off warnings; for
-example, @option{-Wno-implicit}. This manual lists only one of the
-two forms, whichever is not the default. For further
-language-specific options also refer to @ref{C++ Dialect Options} and
-@ref{Objective-C and Objective-C++ Dialect Options}.
-
-When an unrecognized warning option is requested (e.g.,
-@option{-Wunknown-warning}), GCC emits a diagnostic stating
-that the option is not recognized. However, if the @option{-Wno-} form
-is used, the behavior is slightly different: no diagnostic is
-produced for @option{-Wno-unknown-warning} unless other diagnostics
-are being produced. This allows the use of new @option{-Wno-} options
-with old compilers, but if something goes wrong, the compiler
-warns that an unrecognized option is present.
-
-@table @gcctabopt
-@item -Wpedantic
-@itemx -pedantic
-@opindex pedantic
-@opindex Wpedantic
-Issue all the warnings demanded by strict ISO C and ISO C++;
-reject all programs that use forbidden extensions, and some other
-programs that do not follow ISO C and ISO C++. For ISO C, follows the
-version of the ISO C standard specified by any @option{-std} option used.
-
-Valid ISO C and ISO C++ programs should compile properly with or without
-this option (though a rare few require @option{-ansi} or a
-@option{-std} option specifying the required version of ISO C)@. However,
-without this option, certain GNU extensions and traditional C and C++
-features are supported as well. With this option, they are rejected.
-
-@option{-Wpedantic} does not cause warning messages for use of the
-alternate keywords whose names begin and end with @samp{__}. Pedantic
-warnings are also disabled in the expression that follows
-@code{__extension__}. However, only system header files should use
-these escape routes; application programs should avoid them.
-@xref{Alternate Keywords}.
-
-Some users try to use @option{-Wpedantic} to check programs for strict ISO
-C conformance. They soon find that it does not do quite what they want:
-it finds some non-ISO practices, but not all---only those for which
-ISO C @emph{requires} a diagnostic, and some others for which
-diagnostics have been added.
-
-A feature to report any failure to conform to ISO C might be useful in
-some instances, but would require considerable additional work and would
-be quite different from @option{-Wpedantic}. We don't have plans to
-support such a feature in the near future.
-
-Where the standard specified with @option{-std} represents a GNU
-extended dialect of C, such as @samp{gnu90} or @samp{gnu99}, there is a
-corresponding @dfn{base standard}, the version of ISO C on which the GNU
-extended dialect is based. Warnings from @option{-Wpedantic} are given
-where they are required by the base standard. (It does not make sense
-for such warnings to be given only for features not in the specified GNU
-C dialect, since by definition the GNU dialects of C include all
-features the compiler supports with the given option, and there would be
-nothing to warn about.)
-
-@item -pedantic-errors
-@opindex pedantic-errors
-Like @option{-Wpedantic}, except that errors are produced rather than
-warnings.
-
-@item -Wall
-@opindex Wall
-@opindex Wno-all
-This enables all the warnings about constructions that some users
-consider questionable, and that are easy to avoid (or modify to
-prevent the warning), even in conjunction with macros. This also
-enables some language-specific warnings described in @ref{C++ Dialect
-Options} and @ref{Objective-C and Objective-C++ Dialect Options}.
-
-@option{-Wall} turns on the following warning flags:
-
-@gccoptlist{-Waddress @gol
--Warray-bounds @r{(only with} @option{-O2}@r{)} @gol
--Wc++11-compat @gol
--Wchar-subscripts @gol
--Wenum-compare @r{(in C/ObjC; this is on by default in C++)} @gol
--Wimplicit-int @r{(C and Objective-C only)} @gol
--Wimplicit-function-declaration @r{(C and Objective-C only)} @gol
--Wcomment @gol
--Wformat @gol
--Wmain @r{(only for C/ObjC and unless} @option{-ffreestanding}@r{)} @gol
--Wmaybe-uninitialized @gol
--Wmissing-braces @r{(only for C/ObjC)} @gol
--Wnonnull @gol
--Wparentheses @gol
--Wpointer-sign @gol
--Wreorder @gol
--Wreturn-type @gol
--Wsequence-point @gol
--Wsign-compare @r{(only in C++)} @gol
--Wstrict-aliasing @gol
--Wstrict-overflow=1 @gol
--Wswitch @gol
--Wtrigraphs @gol
--Wuninitialized @gol
--Wunknown-pragmas @gol
--Wunused-function @gol
--Wunused-label @gol
--Wunused-value @gol
--Wunused-variable @gol
--Wvolatile-register-var @gol
-}
-
-Note that some warning flags are not implied by @option{-Wall}. Some of
-them warn about constructions that users generally do not consider
-questionable, but which occasionally you might wish to check for;
-others warn about constructions that are necessary or hard to avoid in
-some cases, and there is no simple way to modify the code to suppress
-the warning. Some of them are enabled by @option{-Wextra} but many of
-them must be enabled individually.
-
-@item -Wextra
-@opindex W
-@opindex Wextra
-@opindex Wno-extra
-This enables some extra warning flags that are not enabled by
-@option{-Wall}. (This option used to be called @option{-W}. The older
-name is still supported, but the newer name is more descriptive.)
-
-@gccoptlist{-Wclobbered @gol
--Wempty-body @gol
--Wignored-qualifiers @gol
--Wmissing-field-initializers @gol
--Wmissing-parameter-type @r{(C only)} @gol
--Wold-style-declaration @r{(C only)} @gol
--Woverride-init @gol
--Wsign-compare @gol
--Wtype-limits @gol
--Wuninitialized @gol
--Wunused-parameter @r{(only with} @option{-Wunused} @r{or} @option{-Wall}@r{)} @gol
--Wunused-but-set-parameter @r{(only with} @option{-Wunused} @r{or} @option{-Wall}@r{)} @gol
-}
-
-The option @option{-Wextra} also prints warning messages for the
-following cases:
-
-@itemize @bullet
-
-@item
-A pointer is compared against integer zero with @samp{<}, @samp{<=},
-@samp{>}, or @samp{>=}.
-
-@item
-(C++ only) An enumerator and a non-enumerator both appear in a
-conditional expression.
-
-@item
-(C++ only) Ambiguous virtual bases.
-
-@item
-(C++ only) Subscripting an array that has been declared @samp{register}.
-
-@item
-(C++ only) Taking the address of a variable that has been declared
-@samp{register}.
-
-@item
-(C++ only) A base class is not initialized in a derived class's copy
-constructor.
-
-@end itemize
-
-@item -Wchar-subscripts
-@opindex Wchar-subscripts
-@opindex Wno-char-subscripts
-Warn if an array subscript has type @code{char}. This is a common cause
-of error, as programmers often forget that this type is signed on some
-machines.
-This warning is enabled by @option{-Wall}.
-
-@item -Wcomment
-@opindex Wcomment
-@opindex Wno-comment
-Warn whenever a comment-start sequence @samp{/*} appears in a @samp{/*}
-comment, or whenever a Backslash-Newline appears in a @samp{//} comment.
-This warning is enabled by @option{-Wall}.
-
-@item -Wno-coverage-mismatch
-@opindex Wno-coverage-mismatch
-Warn if feedback profiles do not match when using the
-@option{-fprofile-use} option.
-If a source file is changed between compiling with @option{-fprofile-gen} and
-with @option{-fprofile-use}, the files with the profile feedback can fail
-to match the source file and GCC cannot use the profile feedback
-information. By default, this warning is enabled and is treated as an
-error. @option{-Wno-coverage-mismatch} can be used to disable the
-warning or @option{-Wno-error=coverage-mismatch} can be used to
-disable the error. Disabling the error for this warning can result in
-poorly optimized code and is useful only in the
-case of very minor changes such as bug fixes to an existing code-base.
-Completely disabling the warning is not recommended.
-
-@item -Wno-cpp
-@r{(C, Objective-C, C++, Objective-C++ and Fortran only)}
-
-Suppress warning messages emitted by @code{#warning} directives.
-
-@item -Wdouble-promotion @r{(C, C++, Objective-C and Objective-C++ only)}
-@opindex Wdouble-promotion
-@opindex Wno-double-promotion
-Give a warning when a value of type @code{float} is implicitly
-promoted to @code{double}. CPUs with a 32-bit ``single-precision''
-floating-point unit implement @code{float} in hardware, but emulate
-@code{double} in software. On such a machine, doing computations
-using @code{double} values is much more expensive because of the
-overhead required for software emulation.
-
-It is easy to accidentally do computations with @code{double} because
-floating-point literals are implicitly of type @code{double}. For
-example, in:
-@smallexample
-@group
-float area(float radius)
-@{
- return 3.14159 * radius * radius;
-@}
-@end group
-@end smallexample
-the compiler performs the entire computation with @code{double}
-because the floating-point literal is a @code{double}.
-
-@item -Wformat
-@itemx -Wformat=@var{n}
-@opindex Wformat
-@opindex Wno-format
-@opindex ffreestanding
-@opindex fno-builtin
-@opindex Wformat=
-Check calls to @code{printf} and @code{scanf}, etc., to make sure that
-the arguments supplied have types appropriate to the format string
-specified, and that the conversions specified in the format string make
-sense. This includes standard functions, and others specified by format
-attributes (@pxref{Function Attributes}), in the @code{printf},
-@code{scanf}, @code{strftime} and @code{strfmon} (an X/Open extension,
-not in the C standard) families (or other target-specific families).
-Which functions are checked without format attributes having been
-specified depends on the standard version selected, and such checks of
-functions without the attribute specified are disabled by
-@option{-ffreestanding} or @option{-fno-builtin}.
-
-The formats are checked against the format features supported by GNU
-libc version 2.2. These include all ISO C90 and C99 features, as well
-as features from the Single Unix Specification and some BSD and GNU
-extensions. Other library implementations may not support all these
-features; GCC does not support warning about features that go beyond a
-particular library's limitations. However, if @option{-Wpedantic} is used
-with @option{-Wformat}, warnings are given about format features not
-in the selected standard version (but not for @code{strfmon} formats,
-since those are not in any version of the C standard). @xref{C Dialect
-Options,,Options Controlling C Dialect}.
-
-@table @gcctabopt
-@item -Wformat=1
-@itemx -Wformat
-Option @option{-Wformat} is equivalent to @option{-Wformat=1}, and
-@option{-Wno-format} is equivalent to @option{-Wformat=0}. Since
-@option{-Wformat} also checks for null format arguments for several
-functions, @option{-Wformat} also implies @option{-Wnonnull}. Some
-aspects of this level of format checking can be disabled by the
-options: @option{-Wno-format-contains-nul},
-@option{-Wno-format-extra-args}, and @option{-Wno-format-zero-length}.
-@option{-Wformat} is enabled by @option{-Wall}.
-
-@item -Wno-format-contains-nul
-@opindex Wno-format-contains-nul
-@opindex Wformat-contains-nul
-If @option{-Wformat} is specified, do not warn about format strings that
-contain NUL bytes.
-
-@item -Wno-format-extra-args
-@opindex Wno-format-extra-args
-@opindex Wformat-extra-args
-If @option{-Wformat} is specified, do not warn about excess arguments to a
-@code{printf} or @code{scanf} format function. The C standard specifies
-that such arguments are ignored.
-
-Where the unused arguments lie between used arguments that are
-specified with @samp{$} operand number specifications, normally
-warnings are still given, since the implementation could not know what
-type to pass to @code{va_arg} to skip the unused arguments. However,
-in the case of @code{scanf} formats, this option suppresses the
-warning if the unused arguments are all pointers, since the Single
-Unix Specification says that such unused arguments are allowed.
-
-@item -Wno-format-zero-length
-@opindex Wno-format-zero-length
-@opindex Wformat-zero-length
-If @option{-Wformat} is specified, do not warn about zero-length formats.
-The C standard specifies that zero-length formats are allowed.
-
-
-@item -Wformat=2
-Enable @option{-Wformat} plus additional format checks. Currently
-equivalent to @option{-Wformat -Wformat-nonliteral -Wformat-security
--Wformat-y2k}.
-
-@item -Wformat-nonliteral
-@opindex Wformat-nonliteral
-@opindex Wno-format-nonliteral
-If @option{-Wformat} is specified, also warn if the format string is not a
-string literal and so cannot be checked, unless the format function
-takes its format arguments as a @code{va_list}.
-
-@item -Wformat-security
-@opindex Wformat-security
-@opindex Wno-format-security
-If @option{-Wformat} is specified, also warn about uses of format
-functions that represent possible security problems. At present, this
-warns about calls to @code{printf} and @code{scanf} functions where the
-format string is not a string literal and there are no format arguments,
-as in @code{printf (foo);}. This may be a security hole if the format
-string came from untrusted input and contains @samp{%n}. (This is
-currently a subset of what @option{-Wformat-nonliteral} warns about, but
-in future warnings may be added to @option{-Wformat-security} that are not
-included in @option{-Wformat-nonliteral}.)
-
-@item -Wformat-y2k
-@opindex Wformat-y2k
-@opindex Wno-format-y2k
-If @option{-Wformat} is specified, also warn about @code{strftime}
-formats that may yield only a two-digit year.
-@end table
-
-@item -Wnonnull
-@opindex Wnonnull
-@opindex Wno-nonnull
-Warn about passing a null pointer for arguments marked as
-requiring a non-null value by the @code{nonnull} function attribute.
-
-@option{-Wnonnull} is included in @option{-Wall} and @option{-Wformat}. It
-can be disabled with the @option{-Wno-nonnull} option.
-
-@item -Winit-self @r{(C, C++, Objective-C and Objective-C++ only)}
-@opindex Winit-self
-@opindex Wno-init-self
-Warn about uninitialized variables that are initialized with themselves.
-Note this option can only be used with the @option{-Wuninitialized} option.
-
-For example, GCC warns about @code{i} being uninitialized in the
-following snippet only when @option{-Winit-self} has been specified:
-@smallexample
-@group
-int f()
-@{
- int i = i;
- return i;
-@}
-@end group
-@end smallexample
-
-This warning is enabled by @option{-Wall} in C++.
-
-@item -Wimplicit-int @r{(C and Objective-C only)}
-@opindex Wimplicit-int
-@opindex Wno-implicit-int
-Warn when a declaration does not specify a type.
-This warning is enabled by @option{-Wall}.
-
-@item -Wimplicit-function-declaration @r{(C and Objective-C only)}
-@opindex Wimplicit-function-declaration
-@opindex Wno-implicit-function-declaration
-Give a warning whenever a function is used before being declared. In
-C99 mode (@option{-std=c99} or @option{-std=gnu99}), this warning is
-enabled by default and it is made into an error by
-@option{-pedantic-errors}. This warning is also enabled by
-@option{-Wall}.
-
-@item -Wimplicit @r{(C and Objective-C only)}
-@opindex Wimplicit
-@opindex Wno-implicit
-Same as @option{-Wimplicit-int} and @option{-Wimplicit-function-declaration}.
-This warning is enabled by @option{-Wall}.
-
-@item -Wignored-qualifiers @r{(C and C++ only)}
-@opindex Wignored-qualifiers
-@opindex Wno-ignored-qualifiers
-Warn if the return type of a function has a type qualifier
-such as @code{const}. For ISO C such a type qualifier has no effect,
-since the value returned by a function is not an lvalue.
-For C++, the warning is only emitted for scalar types or @code{void}.
-ISO C prohibits qualified @code{void} return types on function
-definitions, so such return types always receive a warning
-even without this option.
-
-This warning is also enabled by @option{-Wextra}.
-
-@item -Wmain
-@opindex Wmain
-@opindex Wno-main
-Warn if the type of @samp{main} is suspicious. @samp{main} should be
-a function with external linkage, returning int, taking either zero
-arguments, two, or three arguments of appropriate types. This warning
-is enabled by default in C++ and is enabled by either @option{-Wall}
-or @option{-Wpedantic}.
-
-@item -Wmissing-braces
-@opindex Wmissing-braces
-@opindex Wno-missing-braces
-Warn if an aggregate or union initializer is not fully bracketed. In
-the following example, the initializer for @samp{a} is not fully
-bracketed, but that for @samp{b} is fully bracketed. This warning is
-enabled by @option{-Wall} in C.
-
-@smallexample
-int a[2][2] = @{ 0, 1, 2, 3 @};
-int b[2][2] = @{ @{ 0, 1 @}, @{ 2, 3 @} @};
-@end smallexample
-
-This warning is enabled by @option{-Wall}.
-
-@item -Wmissing-include-dirs @r{(C, C++, Objective-C and Objective-C++ only)}
-@opindex Wmissing-include-dirs
-@opindex Wno-missing-include-dirs
-Warn if a user-supplied include directory does not exist.
-
-@item -Wparentheses
-@opindex Wparentheses
-@opindex Wno-parentheses
-Warn if parentheses are omitted in certain contexts, such
-as when there is an assignment in a context where a truth value
-is expected, or when operators are nested whose precedence people
-often get confused about.
-
-Also warn if a comparison like @samp{x<=y<=z} appears; this is
-equivalent to @samp{(x<=y ? 1 : 0) <= z}, which is a different
-interpretation from that of ordinary mathematical notation.
-
-Also warn about constructions where there may be confusion to which
-@code{if} statement an @code{else} branch belongs. Here is an example of
-such a case:
-
-@smallexample
-@group
-@{
- if (a)
- if (b)
- foo ();
- else
- bar ();
-@}
-@end group
-@end smallexample
-
-In C/C++, every @code{else} branch belongs to the innermost possible
-@code{if} statement, which in this example is @code{if (b)}. This is
-often not what the programmer expected, as illustrated in the above
-example by indentation the programmer chose. When there is the
-potential for this confusion, GCC issues a warning when this flag
-is specified. To eliminate the warning, add explicit braces around
-the innermost @code{if} statement so there is no way the @code{else}
-can belong to the enclosing @code{if}. The resulting code
-looks like this:
-
-@smallexample
-@group
-@{
- if (a)
- @{
- if (b)
- foo ();
- else
- bar ();
- @}
-@}
-@end group
-@end smallexample
-
-Also warn for dangerous uses of the GNU extension to
-@code{?:} with omitted middle operand. When the condition
-in the @code{?}: operator is a boolean expression, the omitted value is
-always 1. Often programmers expect it to be a value computed
-inside the conditional expression instead.
-
-This warning is enabled by @option{-Wall}.
-
-@item -Wsequence-point
-@opindex Wsequence-point
-@opindex Wno-sequence-point
-Warn about code that may have undefined semantics because of violations
-of sequence point rules in the C and C++ standards.
-
-The C and C++ standards define the order in which expressions in a C/C++
-program are evaluated in terms of @dfn{sequence points}, which represent
-a partial ordering between the execution of parts of the program: those
-executed before the sequence point, and those executed after it. These
-occur after the evaluation of a full expression (one which is not part
-of a larger expression), after the evaluation of the first operand of a
-@code{&&}, @code{||}, @code{? :} or @code{,} (comma) operator, before a
-function is called (but after the evaluation of its arguments and the
-expression denoting the called function), and in certain other places.
-Other than as expressed by the sequence point rules, the order of
-evaluation of subexpressions of an expression is not specified. All
-these rules describe only a partial order rather than a total order,
-since, for example, if two functions are called within one expression
-with no sequence point between them, the order in which the functions
-are called is not specified. However, the standards committee have
-ruled that function calls do not overlap.
-
-It is not specified when between sequence points modifications to the
-values of objects take effect. Programs whose behavior depends on this
-have undefined behavior; the C and C++ standards specify that ``Between
-the previous and next sequence point an object shall have its stored
-value modified at most once by the evaluation of an expression.
-Furthermore, the prior value shall be read only to determine the value
-to be stored.''. If a program breaks these rules, the results on any
-particular implementation are entirely unpredictable.
-
-Examples of code with undefined behavior are @code{a = a++;}, @code{a[n]
-= b[n++]} and @code{a[i++] = i;}. Some more complicated cases are not
-diagnosed by this option, and it may give an occasional false positive
-result, but in general it has been found fairly effective at detecting
-this sort of problem in programs.
-
-The standard is worded confusingly, therefore there is some debate
-over the precise meaning of the sequence point rules in subtle cases.
-Links to discussions of the problem, including proposed formal
-definitions, may be found on the GCC readings page, at
-@uref{http://gcc.gnu.org/@/readings.html}.
-
-This warning is enabled by @option{-Wall} for C and C++.
-
-@item -Wno-return-local-addr
-@opindex Wno-return-local-addr
-@opindex Wreturn-local-addr
-Do not warn about returning a pointer (or in C++, a reference) to a
-variable that goes out of scope after the function returns.
-
-@item -Wreturn-type
-@opindex Wreturn-type
-@opindex Wno-return-type
-Warn whenever a function is defined with a return type that defaults
-to @code{int}. Also warn about any @code{return} statement with no
-return value in a function whose return type is not @code{void}
-(falling off the end of the function body is considered returning
-without a value), and about a @code{return} statement with an
-expression in a function whose return type is @code{void}.
-
-For C++, a function without return type always produces a diagnostic
-message, even when @option{-Wno-return-type} is specified. The only
-exceptions are @samp{main} and functions defined in system headers.
-
-This warning is enabled by @option{-Wall}.
-
-@item -Wswitch
-@opindex Wswitch
-@opindex Wno-switch
-Warn whenever a @code{switch} statement has an index of enumerated type
-and lacks a @code{case} for one or more of the named codes of that
-enumeration. (The presence of a @code{default} label prevents this
-warning.) @code{case} labels outside the enumeration range also
-provoke warnings when this option is used (even if there is a
-@code{default} label).
-This warning is enabled by @option{-Wall}.
-
-@item -Wswitch-default
-@opindex Wswitch-default
-@opindex Wno-switch-default
-Warn whenever a @code{switch} statement does not have a @code{default}
-case.
-
-@item -Wswitch-enum
-@opindex Wswitch-enum
-@opindex Wno-switch-enum
-Warn whenever a @code{switch} statement has an index of enumerated type
-and lacks a @code{case} for one or more of the named codes of that
-enumeration. @code{case} labels outside the enumeration range also
-provoke warnings when this option is used. The only difference
-between @option{-Wswitch} and this option is that this option gives a
-warning about an omitted enumeration code even if there is a
-@code{default} label.
-
-@item -Wsync-nand @r{(C and C++ only)}
-@opindex Wsync-nand
-@opindex Wno-sync-nand
-Warn when @code{__sync_fetch_and_nand} and @code{__sync_nand_and_fetch}
-built-in functions are used. These functions changed semantics in GCC 4.4.
-
-@item -Wtrigraphs
-@opindex Wtrigraphs
-@opindex Wno-trigraphs
-Warn if any trigraphs are encountered that might change the meaning of
-the program (trigraphs within comments are not warned about).
-This warning is enabled by @option{-Wall}.
-
-@item -Wunused-but-set-parameter
-@opindex Wunused-but-set-parameter
-@opindex Wno-unused-but-set-parameter
-Warn whenever a function parameter is assigned to, but otherwise unused
-(aside from its declaration).
-
-To suppress this warning use the @samp{unused} attribute
-(@pxref{Variable Attributes}).
-
-This warning is also enabled by @option{-Wunused} together with
-@option{-Wextra}.
-
-@item -Wunused-but-set-variable
-@opindex Wunused-but-set-variable
-@opindex Wno-unused-but-set-variable
-Warn whenever a local variable is assigned to, but otherwise unused
-(aside from its declaration).
-This warning is enabled by @option{-Wall}.
-
-To suppress this warning use the @samp{unused} attribute
-(@pxref{Variable Attributes}).
-
-This warning is also enabled by @option{-Wunused}, which is enabled
-by @option{-Wall}.
-
-@item -Wunused-function
-@opindex Wunused-function
-@opindex Wno-unused-function
-Warn whenever a static function is declared but not defined or a
-non-inline static function is unused.
-This warning is enabled by @option{-Wall}.
-
-@item -Wunused-label
-@opindex Wunused-label
-@opindex Wno-unused-label
-Warn whenever a label is declared but not used.
-This warning is enabled by @option{-Wall}.
-
-To suppress this warning use the @samp{unused} attribute
-(@pxref{Variable Attributes}).
-
-@item -Wunused-local-typedefs @r{(C, Objective-C, C++ and Objective-C++ only)}
-@opindex Wunused-local-typedefs
-Warn when a typedef locally defined in a function is not used.
-This warning is enabled by @option{-Wall}.
-
-@item -Wunused-parameter
-@opindex Wunused-parameter
-@opindex Wno-unused-parameter
-Warn whenever a function parameter is unused aside from its declaration.
-
-To suppress this warning use the @samp{unused} attribute
-(@pxref{Variable Attributes}).
-
-@item -Wno-unused-result
-@opindex Wunused-result
-@opindex Wno-unused-result
-Do not warn if a caller of a function marked with attribute
-@code{warn_unused_result} (@pxref{Function Attributes}) does not use
-its return value. The default is @option{-Wunused-result}.
-
-@item -Wunused-variable
-@opindex Wunused-variable
-@opindex Wno-unused-variable
-Warn whenever a local variable or non-constant static variable is unused
-aside from its declaration.
-This warning is enabled by @option{-Wall}.
-
-To suppress this warning use the @samp{unused} attribute
-(@pxref{Variable Attributes}).
-
-@item -Wunused-value
-@opindex Wunused-value
-@opindex Wno-unused-value
-Warn whenever a statement computes a result that is explicitly not
-used. To suppress this warning cast the unused expression to
-@samp{void}. This includes an expression-statement or the left-hand
-side of a comma expression that contains no side effects. For example,
-an expression such as @samp{x[i,j]} causes a warning, while
-@samp{x[(void)i,j]} does not.
-
-This warning is enabled by @option{-Wall}.
-
-@item -Wunused
-@opindex Wunused
-@opindex Wno-unused
-All the above @option{-Wunused} options combined.
-
-In order to get a warning about an unused function parameter, you must
-either specify @option{-Wextra -Wunused} (note that @option{-Wall} implies
-@option{-Wunused}), or separately specify @option{-Wunused-parameter}.
-
-@item -Wuninitialized
-@opindex Wuninitialized
-@opindex Wno-uninitialized
-Warn if an automatic variable is used without first being initialized
-or if a variable may be clobbered by a @code{setjmp} call. In C++,
-warn if a non-static reference or non-static @samp{const} member
-appears in a class without constructors.
-
-If you want to warn about code that 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 that 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 depends on the precise optimization
-options and version of GCC used.
-
-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
-computations may be deleted by data flow analysis before the warnings
-are printed.
-
-@item -Wmaybe-uninitialized
-@opindex Wmaybe-uninitialized
-@opindex Wno-maybe-uninitialized
-For an automatic variable, if there exists a path from the function
-entry to a use of the variable that is initialized, but there exist
-some other paths for which the variable is not initialized, the compiler
-emits a warning if it cannot prove the uninitialized paths are not
-executed at run time. These warnings are made optional because GCC is
-not smart enough to see all the reasons why the code might be correct
-in spite of appearing to have an error. Here is one example of how
-this can happen:
-
-@smallexample
-@group
-@{
- int x;
- switch (y)
- @{
- case 1: x = 1;
- break;
- case 2: x = 4;
- break;
- case 3: x = 5;
- @}
- foo (x);
-@}
-@end group
-@end smallexample
-
-@noindent
-If the value of @code{y} is always 1, 2 or 3, then @code{x} is
-always initialized, but GCC doesn't know this. To suppress the
-warning, you need to provide a default case with assert(0) or
-similar code.
-
-@cindex @code{longjmp} warnings
-This option also warns when a non-volatile automatic variable might be
-changed by a call to @code{longjmp}. These warnings as well are possible
-only in optimizing compilation.
-
-The compiler sees only the calls to @code{setjmp}. It cannot know
-where @code{longjmp} will be called; in fact, a signal handler could
-call it at any point in the code. As a result, you may get a warning
-even when there is in fact no problem because @code{longjmp} cannot
-in fact be called at the place that would cause a problem.
-
-Some spurious warnings can be avoided if you declare all the functions
-you use that never return as @code{noreturn}. @xref{Function
-Attributes}.
-
-This warning is enabled by @option{-Wall} or @option{-Wextra}.
-
-@item -Wunknown-pragmas
-@opindex Wunknown-pragmas
-@opindex Wno-unknown-pragmas
-@cindex warning for unknown pragmas
-@cindex unknown pragmas, warning
-@cindex pragmas, warning of unknown
-Warn when a @code{#pragma} directive is encountered that is not understood by
-GCC@. If this command-line option is used, warnings are even issued
-for unknown pragmas in system header files. This is not the case if
-the warnings are only enabled by the @option{-Wall} command-line option.
-
-@item -Wno-pragmas
-@opindex Wno-pragmas
-@opindex Wpragmas
-Do not warn about misuses of pragmas, such as incorrect parameters,
-invalid syntax, or conflicts between pragmas. See also
-@option{-Wunknown-pragmas}.
-
-@item -Wstrict-aliasing
-@opindex Wstrict-aliasing
-@opindex Wno-strict-aliasing
-This option is only active when @option{-fstrict-aliasing} is active.
-It warns about code that might break the strict aliasing rules that the
-compiler is using for optimization. The warning does not catch all
-cases, but does attempt to catch the more common pitfalls. It is
-included in @option{-Wall}.
-It is equivalent to @option{-Wstrict-aliasing=3}
-
-@item -Wstrict-aliasing=n
-@opindex Wstrict-aliasing=n
-This option is only active when @option{-fstrict-aliasing} is active.
-It warns about code that might break the strict aliasing rules that the
-compiler is using for optimization.
-Higher levels correspond to higher accuracy (fewer false positives).
-Higher levels also correspond to more effort, similar to the way @option{-O}
-works.
-@option{-Wstrict-aliasing} is equivalent to @option{-Wstrict-aliasing=3}.
-
-Level 1: Most aggressive, quick, least accurate.
-Possibly useful when higher levels
-do not warn but @option{-fstrict-aliasing} still breaks the code, as it has very few
-false negatives. However, it has many false positives.
-Warns for all pointer conversions between possibly incompatible types,
-even if never dereferenced. Runs in the front end only.
-
-Level 2: Aggressive, quick, not too precise.
-May still have many false positives (not as many as level 1 though),
-and few false negatives (but possibly more than level 1).
-Unlike level 1, it only warns when an address is taken. Warns about
-incomplete types. Runs in the front end only.
-
-Level 3 (default for @option{-Wstrict-aliasing}):
-Should have very few false positives and few false
-negatives. Slightly slower than levels 1 or 2 when optimization is enabled.
-Takes care of the common pun+dereference pattern in the front end:
-@code{*(int*)&some_float}.
-If optimization is enabled, it also runs in the back end, where it deals
-with multiple statement cases using flow-sensitive points-to information.
-Only warns when the converted pointer is dereferenced.
-Does not warn about incomplete types.
-
-@item -Wstrict-overflow
-@itemx -Wstrict-overflow=@var{n}
-@opindex Wstrict-overflow
-@opindex Wno-strict-overflow
-This option is only active when @option{-fstrict-overflow} is active.
-It warns about cases where the compiler optimizes based on the
-assumption that signed overflow does not occur. Note that it does not
-warn about all cases where the code might overflow: it only warns
-about cases where the compiler implements some optimization. Thus
-this warning depends on the optimization level.
-
-An optimization that assumes that signed overflow does not occur is
-perfectly safe if the values of the variables involved are such that
-overflow never does, in fact, occur. Therefore this warning can
-easily give a false positive: a warning about code that is not
-actually a problem. To help focus on important issues, several
-warning levels are defined. No warnings are issued for the use of
-undefined signed overflow when estimating how many iterations a loop
-requires, in particular when determining whether a loop will be
-executed at all.
-
-@table @gcctabopt
-@item -Wstrict-overflow=1
-Warn about cases that are both questionable and easy to avoid. For
-example, with @option{-fstrict-overflow}, the compiler simplifies
-@code{x + 1 > x} to @code{1}. This level of
-@option{-Wstrict-overflow} is enabled by @option{-Wall}; higher levels
-are not, and must be explicitly requested.
-
-@item -Wstrict-overflow=2
-Also warn about other cases where a comparison is simplified to a
-constant. For example: @code{abs (x) >= 0}. This can only be
-simplified when @option{-fstrict-overflow} is in effect, because
-@code{abs (INT_MIN)} overflows to @code{INT_MIN}, which is less than
-zero. @option{-Wstrict-overflow} (with no level) is the same as
-@option{-Wstrict-overflow=2}.
-
-@item -Wstrict-overflow=3
-Also warn about other cases where a comparison is simplified. For
-example: @code{x + 1 > 1} is simplified to @code{x > 0}.
-
-@item -Wstrict-overflow=4
-Also warn about other simplifications not covered by the above cases.
-For example: @code{(x * 10) / 5} is simplified to @code{x * 2}.
-
-@item -Wstrict-overflow=5
-Also warn about cases where the compiler reduces the magnitude of a
-constant involved in a comparison. For example: @code{x + 2 > y} is
-simplified to @code{x + 1 >= y}. This is reported only at the
-highest warning level because this simplification applies to many
-comparisons, so this warning level gives a very large number of
-false positives.
-@end table
-
-@item -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{]}
-@opindex Wsuggest-attribute=
-@opindex Wno-suggest-attribute=
-Warn for cases where adding an attribute may be beneficial. The
-attributes currently supported are listed below.
-
-@table @gcctabopt
-@item -Wsuggest-attribute=pure
-@itemx -Wsuggest-attribute=const
-@itemx -Wsuggest-attribute=noreturn
-@opindex Wsuggest-attribute=pure
-@opindex Wno-suggest-attribute=pure
-@opindex Wsuggest-attribute=const
-@opindex Wno-suggest-attribute=const
-@opindex Wsuggest-attribute=noreturn
-@opindex Wno-suggest-attribute=noreturn
-
-Warn about functions that might be candidates for attributes
-@code{pure}, @code{const} or @code{noreturn}. The compiler only warns for
-functions visible in other compilation units or (in the case of @code{pure} and
-@code{const}) if it cannot prove that the function returns normally. A function
-returns normally if it doesn't contain an infinite loop or return abnormally
-by throwing, calling @code{abort()} or trapping. This analysis requires option
-@option{-fipa-pure-const}, which is enabled by default at @option{-O} and
-higher. Higher optimization levels improve the accuracy of the analysis.
-
-@item -Wsuggest-attribute=format
-@itemx -Wmissing-format-attribute
-@opindex Wsuggest-attribute=format
-@opindex Wmissing-format-attribute
-@opindex Wno-suggest-attribute=format
-@opindex Wno-missing-format-attribute
-@opindex Wformat
-@opindex Wno-format
-
-Warn about function pointers that might be candidates for @code{format}
-attributes. Note these are only possible candidates, not absolute ones.
-GCC guesses that function pointers with @code{format} attributes that
-are used in assignment, initialization, parameter passing or return
-statements should have a corresponding @code{format} attribute in the
-resulting type. I.e.@: the left-hand side of the assignment or
-initialization, the type of the parameter variable, or the return type
-of the containing function respectively should also have a @code{format}
-attribute to avoid the warning.
-
-GCC also warns about function definitions that might be
-candidates for @code{format} attributes. Again, these are only
-possible candidates. GCC guesses that @code{format} attributes
-might be appropriate for any function that calls a function like
-@code{vprintf} or @code{vscanf}, but this might not always be the
-case, and some functions for which @code{format} attributes are
-appropriate may not be detected.
-@end table
-
-@item -Warray-bounds
-@opindex Wno-array-bounds
-@opindex Warray-bounds
-This option is only active when @option{-ftree-vrp} is active
-(default for @option{-O2} and above). It warns about subscripts to arrays
-that are always out of bounds. This warning is enabled by @option{-Wall}.
-
-@item -Wno-div-by-zero
-@opindex Wno-div-by-zero
-@opindex Wdiv-by-zero
-Do not warn about compile-time integer division by zero. Floating-point
-division by zero is not warned about, as it can be a legitimate way of
-obtaining infinities and NaNs.
-
-@item -Wsystem-headers
-@opindex Wsystem-headers
-@opindex Wno-system-headers
-@cindex warnings from system headers
-@cindex system headers, warnings from
-Print warning messages for constructs found in system header files.
-Warnings from system headers are normally suppressed, on the assumption
-that they usually do not indicate real problems and would only make the
-compiler output harder to read. Using this command-line option tells
-GCC to emit warnings from system headers as if they occurred in user
-code. However, note that using @option{-Wall} in conjunction with this
-option does @emph{not} warn about unknown pragmas in system
-headers---for that, @option{-Wunknown-pragmas} must also be used.
-
-@item -Wtrampolines
-@opindex Wtrampolines
-@opindex Wno-trampolines
- Warn about trampolines generated for pointers to nested functions.
-
- A trampoline is a small piece of data or code that is created at run
- time on the stack when the address of a nested function is taken, and
- is used to call the nested function indirectly. For some targets, it
- is made up of data only and thus requires no special treatment. But,
- for most targets, it is made up of code and thus requires the stack
- to be made executable in order for the program to work properly.
-
-@item -Wfloat-equal
-@opindex Wfloat-equal
-@opindex Wno-float-equal
-Warn if floating-point values are used in equality comparisons.
-
-The idea behind this is that sometimes it is convenient (for the
-programmer) to consider floating-point values as approximations to
-infinitely precise real numbers. If you are doing this, then you need
-to compute (by analyzing the code, or in some other way) the maximum or
-likely maximum error that the computation introduces, and allow for it
-when performing comparisons (and when producing output, but that's a
-different problem). In particular, instead of testing for equality, you
-should check to see whether the two values have ranges that overlap; and
-this is done with the relational operators, so equality comparisons are
-probably mistaken.
-
-@item -Wtraditional @r{(C and Objective-C only)}
-@opindex Wtraditional
-@opindex Wno-traditional
-Warn about certain constructs that behave differently in traditional and
-ISO C@. Also warn about ISO C constructs that have no traditional C
-equivalent, and/or problematic constructs that should be avoided.
-
-@itemize @bullet
-@item
-Macro parameters that appear within string literals in the macro body.
-In traditional C macro replacement takes place within string literals,
-but in ISO C it does not.
-
-@item
-In traditional C, some preprocessor directives did not exist.
-Traditional preprocessors only considered a line to be a directive
-if the @samp{#} appeared in column 1 on the line. Therefore
-@option{-Wtraditional} warns about directives that traditional C
-understands but ignores because the @samp{#} does not appear as the
-first character on the line. It also suggests you hide directives like
-@samp{#pragma} not understood by traditional C by indenting them. Some
-traditional implementations do not recognize @samp{#elif}, so this option
-suggests avoiding it altogether.
-
-@item
-A function-like macro that appears without arguments.
-
-@item
-The unary plus operator.
-
-@item
-The @samp{U} integer constant suffix, or the @samp{F} or @samp{L} floating-point
-constant suffixes. (Traditional C does support the @samp{L} suffix on integer
-constants.) Note, these suffixes appear in macros defined in the system
-headers of most modern systems, e.g.@: the @samp{_MIN}/@samp{_MAX} macros in @code{<limits.h>}.
-Use of these macros in user code might normally lead to spurious
-warnings, however GCC's integrated preprocessor has enough context to
-avoid warning in these cases.
-
-@item
-A function declared external in one block and then used after the end of
-the block.
-
-@item
-A @code{switch} statement has an operand of type @code{long}.
-
-@item
-A non-@code{static} function declaration follows a @code{static} one.
-This construct is not accepted by some traditional C compilers.
-
-@item
-The ISO type of an integer constant has a different width or
-signedness from its traditional type. This warning is only issued if
-the base of the constant is ten. I.e.@: hexadecimal or octal values, which
-typically represent bit patterns, are not warned about.
-
-@item
-Usage of ISO string concatenation is detected.
-
-@item
-Initialization of automatic aggregates.
-
-@item
-Identifier conflicts with labels. Traditional C lacks a separate
-namespace for labels.
-
-@item
-Initialization of unions. If the initializer is zero, the warning is
-omitted. This is done under the assumption that the zero initializer in
-user code appears conditioned on e.g.@: @code{__STDC__} to avoid missing
-initializer warnings and relies on default initialization to zero in the
-traditional C case.
-
-@item
-Conversions by prototypes between fixed/floating-point values and vice
-versa. The absence of these prototypes when compiling with traditional
-C causes serious problems. This is a subset of the possible
-conversion warnings; for the full set use @option{-Wtraditional-conversion}.
-
-@item
-Use of ISO C style function definitions. This warning intentionally is
-@emph{not} issued for prototype declarations or variadic functions
-because these ISO C features appear in your code when using
-libiberty's traditional C compatibility macros, @code{PARAMS} and
-@code{VPARAMS}. This warning is also bypassed for nested functions
-because that feature is already a GCC extension and thus not relevant to
-traditional C compatibility.
-@end itemize
-
-@item -Wtraditional-conversion @r{(C and Objective-C only)}
-@opindex Wtraditional-conversion
-@opindex Wno-traditional-conversion
-Warn if a prototype causes a type conversion that is different from what
-would happen to the same argument in the absence of a prototype. This
-includes conversions of fixed point to floating and vice versa, and
-conversions changing the width or signedness of a fixed-point argument
-except when the same as the default promotion.
-
-@item -Wdeclaration-after-statement @r{(C and Objective-C only)}
-@opindex Wdeclaration-after-statement
-@opindex Wno-declaration-after-statement
-Warn when a declaration is found after a statement in a block. This
-construct, known from C++, was introduced with ISO C99 and is by default
-allowed in GCC@. It is not supported by ISO C90 and was not supported by
-GCC versions before GCC 3.0. @xref{Mixed Declarations}.
-
-@item -Wundef
-@opindex Wundef
-@opindex Wno-undef
-Warn if an undefined identifier is evaluated in an @samp{#if} directive.
-
-@item -Wno-endif-labels
-@opindex Wno-endif-labels
-@opindex Wendif-labels
-Do not warn whenever an @samp{#else} or an @samp{#endif} are followed by text.
-
-@item -Wshadow
-@opindex Wshadow
-@opindex Wno-shadow
-Warn whenever a local variable or type declaration shadows another variable,
-parameter, type, or class member (in C++), or whenever a built-in function
-is shadowed. Note that in C++, the compiler warns if a local variable
-shadows an explicit typedef, but not if it shadows a struct/class/enum.
-
-@item -Wlarger-than=@var{len}
-@opindex Wlarger-than=@var{len}
-@opindex Wlarger-than-@var{len}
-Warn whenever an object of larger than @var{len} bytes is defined.
-
-@item -Wframe-larger-than=@var{len}
-@opindex Wframe-larger-than
-Warn if the size of a function frame is larger than @var{len} bytes.
-The computation done to determine the stack frame size is approximate
-and not conservative.
-The actual requirements may be somewhat greater than @var{len}
-even if you do not get a warning. In addition, any space allocated
-via @code{alloca}, variable-length arrays, or related constructs
-is not included by the compiler when determining
-whether or not to issue a warning.
-
-@item -Wno-free-nonheap-object
-@opindex Wno-free-nonheap-object
-@opindex Wfree-nonheap-object
-Do not warn when attempting to free an object that was not allocated
-on the heap.
-
-@item -Wstack-usage=@var{len}
-@opindex Wstack-usage
-Warn if the stack usage of a function might be larger than @var{len} bytes.
-The computation done to determine the stack usage is conservative.
-Any space allocated via @code{alloca}, variable-length arrays, or related
-constructs is included by the compiler when determining whether or not to
-issue a warning.
-
-The message is in keeping with the output of @option{-fstack-usage}.
-
-@itemize
-@item
-If the stack usage is fully static but exceeds the specified amount, it's:
-
-@smallexample
- warning: stack usage is 1120 bytes
-@end smallexample
-@item
-If the stack usage is (partly) dynamic but bounded, it's:
-
-@smallexample
- warning: stack usage might be 1648 bytes
-@end smallexample
-@item
-If the stack usage is (partly) dynamic and not bounded, it's:
-
-@smallexample
- warning: stack usage might be unbounded
-@end smallexample
-@end itemize
-
-@item -Wunsafe-loop-optimizations
-@opindex Wunsafe-loop-optimizations
-@opindex Wno-unsafe-loop-optimizations
-Warn if the loop cannot be optimized because the compiler cannot
-assume anything on the bounds of the loop indices. With
-@option{-funsafe-loop-optimizations} warn if the compiler makes
-such assumptions.
-
-@item -Wno-pedantic-ms-format @r{(MinGW targets only)}
-@opindex Wno-pedantic-ms-format
-@opindex Wpedantic-ms-format
-When used in combination with @option{-Wformat}
-and @option{-pedantic} without GNU extensions, this option
-disables the warnings about non-ISO @code{printf} / @code{scanf} format
-width specifiers @code{I32}, @code{I64}, and @code{I} used on Windows targets,
-which depend on the MS runtime.
-
-@item -Wpointer-arith
-@opindex Wpointer-arith
-@opindex Wno-pointer-arith
-Warn about anything that depends on the ``size of'' a function type or
-of @code{void}. GNU C assigns these types a size of 1, for
-convenience in calculations with @code{void *} pointers and pointers
-to functions. In C++, warn also when an arithmetic operation involves
-@code{NULL}. This warning is also enabled by @option{-Wpedantic}.
-
-@item -Wtype-limits
-@opindex Wtype-limits
-@opindex Wno-type-limits
-Warn if a comparison is always true or always false due to the limited
-range of the data type, but do not warn for constant expressions. For
-example, warn if an unsigned variable is compared against zero with
-@samp{<} or @samp{>=}. This warning is also enabled by
-@option{-Wextra}.
-
-@item -Wbad-function-cast @r{(C and Objective-C only)}
-@opindex Wbad-function-cast
-@opindex Wno-bad-function-cast
-Warn whenever a function call is cast to a non-matching type.
-For example, warn if @code{int malloc()} is cast to @code{anything *}.
-
-@item -Wc++-compat @r{(C and Objective-C only)}
-Warn about ISO C constructs that are outside of the common subset of
-ISO C and ISO C++, e.g.@: request for implicit conversion from
-@code{void *} to a pointer to non-@code{void} type.
-
-@item -Wc++11-compat @r{(C++ and Objective-C++ only)}
-Warn about C++ constructs whose meaning differs between ISO C++ 1998
-and ISO C++ 2011, e.g., identifiers in ISO C++ 1998 that are keywords
-in ISO C++ 2011. This warning turns on @option{-Wnarrowing} and is
-enabled by @option{-Wall}.
-
-@item -Wcast-qual
-@opindex Wcast-qual
-@opindex Wno-cast-qual
-Warn whenever a pointer is cast so as to remove a type qualifier from
-the target type. For example, warn if a @code{const char *} is cast
-to an ordinary @code{char *}.
-
-Also warn when making a cast that introduces a type qualifier in an
-unsafe way. For example, casting @code{char **} to @code{const char **}
-is unsafe, as in this example:
-
-@smallexample
- /* p is char ** value. */
- const char **q = (const char **) p;
- /* Assignment of readonly string to const char * is OK. */
- *q = "string";
- /* Now char** pointer points to read-only memory. */
- **p = 'b';
-@end smallexample
-
-@item -Wcast-align
-@opindex Wcast-align
-@opindex Wno-cast-align
-Warn whenever a pointer is cast such that the required alignment of the
-target is increased. For example, warn if a @code{char *} is cast to
-an @code{int *} on machines where integers can only be accessed at
-two- or four-byte boundaries.
-
-@item -Wwrite-strings
-@opindex Wwrite-strings
-@opindex Wno-write-strings
-When compiling C, give string constants the type @code{const
-char[@var{length}]} so that copying the address of one into a
-non-@code{const} @code{char *} pointer produces a warning. These
-warnings help you find at compile time code that can try to write
-into a string constant, but only if you have been very careful about
-using @code{const} in declarations and prototypes. Otherwise, it is
-just a nuisance. This is why we did not make @option{-Wall} request
-these warnings.
-
-When compiling C++, warn about the deprecated conversion from string
-literals to @code{char *}. This warning is enabled by default for C++
-programs.
-
-@item -Wclobbered
-@opindex Wclobbered
-@opindex Wno-clobbered
-Warn for variables that might be changed by @samp{longjmp} or
-@samp{vfork}. This warning is also enabled by @option{-Wextra}.
-
-@item -Wconversion
-@opindex Wconversion
-@opindex Wno-conversion
-Warn for implicit conversions that may alter a value. This includes
-conversions between real and integer, like @code{abs (x)} when
-@code{x} is @code{double}; conversions between signed and unsigned,
-like @code{unsigned ui = -1}; and conversions to smaller types, like
-@code{sqrtf (M_PI)}. Do not warn for explicit casts like @code{abs
-((int) x)} and @code{ui = (unsigned) -1}, or if the value is not
-changed by the conversion like in @code{abs (2.0)}. Warnings about
-conversions between signed and unsigned integers can be disabled by
-using @option{-Wno-sign-conversion}.
-
-For C++, also warn for confusing overload resolution for user-defined
-conversions; and conversions that never use a type conversion
-operator: conversions to @code{void}, the same type, a base class or a
-reference to them. Warnings about conversions between signed and
-unsigned integers are disabled by default in C++ unless
-@option{-Wsign-conversion} is explicitly enabled.
-
-@item -Wno-conversion-null @r{(C++ and Objective-C++ only)}
-@opindex Wconversion-null
-@opindex Wno-conversion-null
-Do not warn for conversions between @code{NULL} and non-pointer
-types. @option{-Wconversion-null} is enabled by default.
-
-@item -Wzero-as-null-pointer-constant @r{(C++ and Objective-C++ only)}
-@opindex Wzero-as-null-pointer-constant
-@opindex Wno-zero-as-null-pointer-constant
-Warn when a literal '0' is used as null pointer constant. This can
-be useful to facilitate the conversion to @code{nullptr} in C++11.
-
-@item -Wuseless-cast @r{(C++ and Objective-C++ only)}
-@opindex Wuseless-cast
-@opindex Wno-useless-cast
-Warn when an expression is casted to its own type.
-
-@item -Wempty-body
-@opindex Wempty-body
-@opindex Wno-empty-body
-Warn if an empty body occurs in an @samp{if}, @samp{else} or @samp{do
-while} statement. This warning is also enabled by @option{-Wextra}.
-
-@item -Wenum-compare
-@opindex Wenum-compare
-@opindex Wno-enum-compare
-Warn about a comparison between values of different enumerated types.
-In C++ enumeral mismatches in conditional expressions are also
-diagnosed and the warning is enabled by default. In C this warning is
-enabled by @option{-Wall}.
-
-@item -Wjump-misses-init @r{(C, Objective-C only)}
-@opindex Wjump-misses-init
-@opindex Wno-jump-misses-init
-Warn if a @code{goto} statement or a @code{switch} statement jumps
-forward across the initialization of a variable, or jumps backward to a
-label after the variable has been initialized. This only warns about
-variables that are initialized when they are declared. This warning is
-only supported for C and Objective-C; in C++ this sort of branch is an
-error in any case.
-
-@option{-Wjump-misses-init} is included in @option{-Wc++-compat}. It
-can be disabled with the @option{-Wno-jump-misses-init} option.
-
-@item -Wsign-compare
-@opindex Wsign-compare
-@opindex Wno-sign-compare
-@cindex warning for comparison of signed and unsigned values
-@cindex comparison of signed and unsigned values, warning
-@cindex signed and unsigned values, comparison warning
-Warn when a comparison between signed and unsigned values could produce
-an incorrect result when the signed value is converted to unsigned.
-This warning is also enabled by @option{-Wextra}; to get the other warnings
-of @option{-Wextra} without this warning, use @option{-Wextra -Wno-sign-compare}.
-
-@item -Wsign-conversion
-@opindex Wsign-conversion
-@opindex Wno-sign-conversion
-Warn for implicit conversions that may change the sign of an integer
-value, like assigning a signed integer expression to an unsigned
-integer variable. An explicit cast silences the warning. In C, this
-option is enabled also by @option{-Wconversion}.
-
-@item -Wsizeof-pointer-memaccess
-@opindex Wsizeof-pointer-memaccess
-@opindex Wno-sizeof-pointer-memaccess
-Warn for suspicious length parameters to certain string and memory built-in
-functions if the argument uses @code{sizeof}. This warning warns e.g.@:
-about @code{memset (ptr, 0, sizeof (ptr));} if @code{ptr} is not an array,
-but a pointer, and suggests a possible fix, or about
-@code{memcpy (&foo, ptr, sizeof (&foo));}. This warning is enabled by
-@option{-Wall}.
-
-@item -Waddress
-@opindex Waddress
-@opindex Wno-address
-Warn about suspicious uses of memory addresses. These include using
-the address of a function in a conditional expression, such as
-@code{void func(void); if (func)}, and comparisons against the memory
-address of a string literal, such as @code{if (x == "abc")}. Such
-uses typically indicate a programmer error: the address of a function
-always evaluates to true, so their use in a conditional usually
-indicate that the programmer forgot the parentheses in a function
-call; and comparisons against string literals result in unspecified
-behavior and are not portable in C, so they usually indicate that the
-programmer intended to use @code{strcmp}. This warning is enabled by
-@option{-Wall}.
-
-@item -Wlogical-op
-@opindex Wlogical-op
-@opindex Wno-logical-op
-Warn about suspicious uses of logical operators in expressions.
-This includes using logical operators in contexts where a
-bit-wise operator is likely to be expected.
-
-@item -Waggregate-return
-@opindex Waggregate-return
-@opindex Wno-aggregate-return
-Warn if any functions that return structures or unions are defined or
-called. (In languages where you can return an array, this also elicits
-a warning.)
-
-@item -Wno-aggressive-loop-optimizations
-@opindex Wno-aggressive-loop-optimizations
-@opindex Waggressive-loop-optimizations
-Warn if in a loop with constant number of iterations the compiler detects
-undefined behavior in some statement during one or more of the iterations.
-
-@item -Wno-attributes
-@opindex Wno-attributes
-@opindex Wattributes
-Do not warn if an unexpected @code{__attribute__} is used, such as
-unrecognized attributes, function attributes applied to variables,
-etc. This does not stop errors for incorrect use of supported
-attributes.
-
-@item -Wno-builtin-macro-redefined
-@opindex Wno-builtin-macro-redefined
-@opindex Wbuiltin-macro-redefined
-Do not warn if certain built-in macros are redefined. This suppresses
-warnings for redefinition of @code{__TIMESTAMP__}, @code{__TIME__},
-@code{__DATE__}, @code{__FILE__}, and @code{__BASE_FILE__}.
-
-@item -Wstrict-prototypes @r{(C and Objective-C only)}
-@opindex Wstrict-prototypes
-@opindex Wno-strict-prototypes
-Warn if a function is declared or defined without specifying the
-argument types. (An old-style function definition is permitted without
-a warning if preceded by a declaration that specifies the argument
-types.)
-
-@item -Wold-style-declaration @r{(C and Objective-C only)}
-@opindex Wold-style-declaration
-@opindex Wno-old-style-declaration
-Warn for obsolescent usages, according to the C Standard, in a
-declaration. For example, warn if storage-class specifiers like
-@code{static} are not the first things in a declaration. This warning
-is also enabled by @option{-Wextra}.
-
-@item -Wold-style-definition @r{(C and Objective-C only)}
-@opindex Wold-style-definition
-@opindex Wno-old-style-definition
-Warn if an old-style function definition is used. A warning is given
-even if there is a previous prototype.
-
-@item -Wmissing-parameter-type @r{(C and Objective-C only)}
-@opindex Wmissing-parameter-type
-@opindex Wno-missing-parameter-type
-A function parameter is declared without a type specifier in K&R-style
-functions:
-
-@smallexample
-void foo(bar) @{ @}
-@end smallexample
-
-This warning is also enabled by @option{-Wextra}.
-
-@item -Wmissing-prototypes @r{(C and Objective-C only)}
-@opindex Wmissing-prototypes
-@opindex Wno-missing-prototypes
-Warn if a global function is defined without a previous prototype
-declaration. This warning is issued even if the definition itself
-provides a prototype. Use this option to detect global functions
-that do not have a matching prototype declaration in a header file.
-This option is not valid for C++ because all function declarations
-provide prototypes and a non-matching declaration will declare an
-overload rather than conflict with an earlier declaration.
-Use @option{-Wmissing-declarations} to detect missing declarations in C++.
-
-@item -Wmissing-declarations
-@opindex Wmissing-declarations
-@opindex Wno-missing-declarations
-Warn if a global function is defined without a previous declaration.
-Do so even if the definition itself provides a prototype.
-Use this option to detect global functions that are not declared in
-header files. In C, no warnings are issued for functions with previous
-non-prototype declarations; use @option{-Wmissing-prototype} to detect
-missing prototypes. In C++, no warnings are issued for function templates,
-or for inline functions, or for functions in anonymous namespaces.
-
-@item -Wmissing-field-initializers
-@opindex Wmissing-field-initializers
-@opindex Wno-missing-field-initializers
-@opindex W
-@opindex Wextra
-@opindex Wno-extra
-Warn if a structure's initializer has some fields missing. For
-example, the following code causes such a warning, because
-@code{x.h} is implicitly zero:
-
-@smallexample
-struct s @{ int f, g, h; @};
-struct s x = @{ 3, 4 @};
-@end smallexample
-
-This option does not warn about designated initializers, so the following
-modification does not trigger a warning:
-
-@smallexample
-struct s @{ int f, g, h; @};
-struct s x = @{ .f = 3, .g = 4 @};
-@end smallexample
-
-This warning is included in @option{-Wextra}. To get other @option{-Wextra}
-warnings without this one, use @option{-Wextra -Wno-missing-field-initializers}.
-
-@item -Wno-multichar
-@opindex Wno-multichar
-@opindex Wmultichar
-Do not warn if a multicharacter constant (@samp{'FOOF'}) is used.
-Usually they indicate a typo in the user's code, as they have
-implementation-defined values, and should not be used in portable code.
-
-@item -Wnormalized=<none|id|nfc|nfkc>
-@opindex Wnormalized=
-@cindex NFC
-@cindex NFKC
-@cindex character set, input normalization
-In ISO C and ISO C++, two identifiers are different if they are
-different sequences of characters. However, sometimes when characters
-outside the basic ASCII character set are used, you can have two
-different character sequences that look the same. To avoid confusion,
-the ISO 10646 standard sets out some @dfn{normalization rules} which
-when applied ensure that two sequences that look the same are turned into
-the same sequence. GCC can warn you if you are using identifiers that
-have not been normalized; this option controls that warning.
-
-There are four levels of warning supported by GCC@. The default is
-@option{-Wnormalized=nfc}, which warns about any identifier that is
-not in the ISO 10646 ``C'' normalized form, @dfn{NFC}. NFC is the
-recommended form for most uses.
-
-Unfortunately, there are some characters allowed in identifiers by
-ISO C and ISO C++ that, when turned into NFC, are not allowed in
-identifiers. That is, there's no way to use these symbols in portable
-ISO C or C++ and have all your identifiers in NFC@.
-@option{-Wnormalized=id} suppresses the warning for these characters.
-It is hoped that future versions of the standards involved will correct
-this, which is why this option is not the default.
-
-You can switch the warning off for all characters by writing
-@option{-Wnormalized=none}. You should only do this if you
-are using some other normalization scheme (like ``D''), because
-otherwise you can easily create bugs that are literally impossible to see.
-
-Some characters in ISO 10646 have distinct meanings but look identical
-in some fonts or display methodologies, especially once formatting has
-been applied. For instance @code{\u207F}, ``SUPERSCRIPT LATIN SMALL
-LETTER N'', displays just like a regular @code{n} that has been
-placed in a superscript. ISO 10646 defines the @dfn{NFKC}
-normalization scheme to convert all these into a standard form as
-well, and GCC warns if your code is not in NFKC if you use
-@option{-Wnormalized=nfkc}. This warning is comparable to warning
-about every identifier that contains the letter O because it might be
-confused with the digit 0, and so is not the default, but may be
-useful as a local coding convention if the programming environment
-cannot be fixed to display these characters distinctly.
-
-@item -Wno-deprecated
-@opindex Wno-deprecated
-@opindex Wdeprecated
-Do not warn about usage of deprecated features. @xref{Deprecated Features}.
-
-@item -Wno-deprecated-declarations
-@opindex Wno-deprecated-declarations
-@opindex Wdeprecated-declarations
-Do not warn about uses of functions (@pxref{Function Attributes}),
-variables (@pxref{Variable Attributes}), and types (@pxref{Type
-Attributes}) marked as deprecated by using the @code{deprecated}
-attribute.
-
-@item -Wno-overflow
-@opindex Wno-overflow
-@opindex Woverflow
-Do not warn about compile-time overflow in constant expressions.
-
-@item -Woverride-init @r{(C and Objective-C only)}
-@opindex Woverride-init
-@opindex Wno-override-init
-@opindex W
-@opindex Wextra
-@opindex Wno-extra
-Warn if an initialized field without side effects is overridden when
-using designated initializers (@pxref{Designated Inits, , Designated
-Initializers}).
-
-This warning is included in @option{-Wextra}. To get other
-@option{-Wextra} warnings without this one, use @option{-Wextra
--Wno-override-init}.
-
-@item -Wpacked
-@opindex Wpacked
-@opindex Wno-packed
-Warn if a structure is given the packed attribute, but the packed
-attribute has no effect on the layout or size of the structure.
-Such structures may be mis-aligned for little benefit. For
-instance, in this code, the variable @code{f.x} in @code{struct bar}
-is misaligned even though @code{struct bar} does not itself
-have the packed attribute:
-
-@smallexample
-@group
-struct foo @{
- int x;
- char a, b, c, d;
-@} __attribute__((packed));
-struct bar @{
- char z;
- struct foo f;
-@};
-@end group
-@end smallexample
-
-@item -Wpacked-bitfield-compat
-@opindex Wpacked-bitfield-compat
-@opindex Wno-packed-bitfield-compat
-The 4.1, 4.2 and 4.3 series of GCC ignore the @code{packed} attribute
-on bit-fields of type @code{char}. This has been fixed in GCC 4.4 but
-the change can lead to differences in the structure layout. GCC
-informs you when the offset of such a field has changed in GCC 4.4.
-For example there is no longer a 4-bit padding between field @code{a}
-and @code{b} in this structure:
-
-@smallexample
-struct foo
-@{
- char a:4;
- char b:8;
-@} __attribute__ ((packed));
-@end smallexample
-
-This warning is enabled by default. Use
-@option{-Wno-packed-bitfield-compat} to disable this warning.
-
-@item -Wpadded
-@opindex Wpadded
-@opindex Wno-padded
-Warn if padding is included in a structure, either to align an element
-of the structure or to align the whole structure. Sometimes when this
-happens it is possible to rearrange the fields of the structure to
-reduce the padding and so make the structure smaller.
-
-@item -Wredundant-decls
-@opindex Wredundant-decls
-@opindex Wno-redundant-decls
-Warn if anything is declared more than once in the same scope, even in
-cases where multiple declaration is valid and changes nothing.
-
-@item -Wnested-externs @r{(C and Objective-C only)}
-@opindex Wnested-externs
-@opindex Wno-nested-externs
-Warn if an @code{extern} declaration is encountered within a function.
-
-@item -Wno-inherited-variadic-ctor
-@opindex Winherited-variadic-ctor
-@opindex Wno-inherited-variadic-ctor
-Suppress warnings about use of C++11 inheriting constructors when the
-base class inherited from has a C variadic constructor; the warning is
-on by default because the ellipsis is not inherited.
-
-@item -Winline
-@opindex Winline
-@opindex Wno-inline
-Warn if a function that is declared as inline cannot be inlined.
-Even with this option, the compiler does not warn about failures to
-inline functions declared in system headers.
-
-The compiler uses a variety of heuristics to determine whether or not
-to inline a function. For example, the compiler takes into account
-the size of the function being inlined and the amount of inlining
-that has already been done in the current function. Therefore,
-seemingly insignificant changes in the source program can cause the
-warnings produced by @option{-Winline} to appear or disappear.
-
-@item -Wno-invalid-offsetof @r{(C++ and Objective-C++ only)}
-@opindex Wno-invalid-offsetof
-@opindex Winvalid-offsetof
-Suppress warnings from applying the @samp{offsetof} macro to a non-POD
-type. According to the 1998 ISO C++ standard, applying @samp{offsetof}
-to a non-POD type is undefined. In existing C++ implementations,
-however, @samp{offsetof} typically gives meaningful results even when
-applied to certain kinds of non-POD types (such as a simple
-@samp{struct} that fails to be a POD type only by virtue of having a
-constructor). This flag is for users who are aware that they are
-writing nonportable code and who have deliberately chosen to ignore the
-warning about it.
-
-The restrictions on @samp{offsetof} may be relaxed in a future version
-of the C++ standard.
-
-@item -Wno-int-to-pointer-cast
-@opindex Wno-int-to-pointer-cast
-@opindex Wint-to-pointer-cast
-Suppress warnings from casts to pointer type of an integer of a
-different size. In C++, casting to a pointer type of smaller size is
-an error. @option{Wint-to-pointer-cast} is enabled by default.
-
-
-@item -Wno-pointer-to-int-cast @r{(C and Objective-C only)}
-@opindex Wno-pointer-to-int-cast
-@opindex Wpointer-to-int-cast
-Suppress warnings from casts from a pointer to an integer type of a
-different size.
-
-@item -Winvalid-pch
-@opindex Winvalid-pch
-@opindex Wno-invalid-pch
-Warn if a precompiled header (@pxref{Precompiled Headers}) is found in
-the search path but can't be used.
-
-@item -Wlong-long
-@opindex Wlong-long
-@opindex Wno-long-long
-Warn if @samp{long long} type is used. This is enabled by either
-@option{-Wpedantic} or @option{-Wtraditional} in ISO C90 and C++98
-modes. To inhibit the warning messages, use @option{-Wno-long-long}.
-
-@item -Wvariadic-macros
-@opindex Wvariadic-macros
-@opindex Wno-variadic-macros
-Warn if variadic macros are used in pedantic ISO C90 mode, or the GNU
-alternate syntax when in pedantic ISO C99 mode. This is default.
-To inhibit the warning messages, use @option{-Wno-variadic-macros}.
-
-@item -Wvarargs
-@opindex Wvarargs
-@opindex Wno-varargs
-Warn upon questionable usage of the macros used to handle variable
-arguments like @samp{va_start}. This is default. To inhibit the
-warning messages, use @option{-Wno-varargs}.
-
-@item -Wvector-operation-performance
-@opindex Wvector-operation-performance
-@opindex Wno-vector-operation-performance
-Warn if vector operation is not implemented via SIMD capabilities of the
-architecture. Mainly useful for the performance tuning.
-Vector operation can be implemented @code{piecewise}, which means that the
-scalar operation is performed on every vector element;
-@code{in parallel}, which means that the vector operation is implemented
-using scalars of wider type, which normally is more performance efficient;
-and @code{as a single scalar}, which means that vector fits into a
-scalar type.
-
-@item -Wno-virtual-move-assign
-@opindex Wvirtual-move-assign
-@opindex Wno-virtual-move-assign
-Suppress warnings about inheriting from a virtual base with a
-non-trivial C++11 move assignment operator. This is dangerous because
-if the virtual base is reachable along more than one path, it will be
-moved multiple times, which can mean both objects end up in the
-moved-from state. If the move assignment operator is written to avoid
-moving from a moved-from object, this warning can be disabled.
-
-@item -Wvla
-@opindex Wvla
-@opindex Wno-vla
-Warn if variable length array is used in the code.
-@option{-Wno-vla} prevents the @option{-Wpedantic} warning of
-the variable length array.
-
-@item -Wvolatile-register-var
-@opindex Wvolatile-register-var
-@opindex Wno-volatile-register-var
-Warn if a register variable is declared volatile. The volatile
-modifier does not inhibit all optimizations that may eliminate reads
-and/or writes to register variables. This warning is enabled by
-@option{-Wall}.
-
-@item -Wdisabled-optimization
-@opindex Wdisabled-optimization
-@opindex Wno-disabled-optimization
-Warn if a requested optimization pass is disabled. This warning does
-not generally indicate that there is anything wrong with your code; it
-merely indicates that GCC's optimizers are unable to handle the code
-effectively. Often, the problem is that your code is too big or too
-complex; GCC refuses to optimize programs when the optimization
-itself is likely to take inordinate amounts of time.
-
-@item -Wpointer-sign @r{(C and Objective-C only)}
-@opindex Wpointer-sign
-@opindex Wno-pointer-sign
-Warn for pointer argument passing or assignment with different signedness.
-This option is only supported for C and Objective-C@. It is implied by
-@option{-Wall} and by @option{-Wpedantic}, which can be disabled with
-@option{-Wno-pointer-sign}.
-
-@item -Wstack-protector
-@opindex Wstack-protector
-@opindex Wno-stack-protector
-This option is only active when @option{-fstack-protector} is active. It
-warns about functions that are not protected against stack smashing.
-
-@item -Wno-mudflap
-@opindex Wno-mudflap
-Suppress warnings about constructs that cannot be instrumented by
-@option{-fmudflap}.
-
-@item -Woverlength-strings
-@opindex Woverlength-strings
-@opindex Wno-overlength-strings
-Warn about string constants that are longer than the ``minimum
-maximum'' length specified in the C standard. Modern compilers
-generally allow string constants that are much longer than the
-standard's minimum limit, but very portable programs should avoid
-using longer strings.
-
-The limit applies @emph{after} string constant concatenation, and does
-not count the trailing NUL@. In C90, the limit was 509 characters; in
-C99, it was raised to 4095. C++98 does not specify a normative
-minimum maximum, so we do not diagnose overlength strings in C++@.
-
-This option is implied by @option{-Wpedantic}, and can be disabled with
-@option{-Wno-overlength-strings}.
-
-@item -Wunsuffixed-float-constants @r{(C and Objective-C only)}
-@opindex Wunsuffixed-float-constants
-
-Issue a warning for any floating constant that does not have
-a suffix. When used together with @option{-Wsystem-headers} it
-warns about such constants in system header files. This can be useful
-when preparing code to use with the @code{FLOAT_CONST_DECIMAL64} pragma
-from the decimal floating-point extension to C99.
-@end table
-
-@node Debugging Options
-@section Options for Debugging Your Program or GCC
-@cindex options, debugging
-@cindex debugging information options
-
-GCC has various special options that are used for debugging
-either your program or GCC:
-
-@table @gcctabopt
-@item -g
-@opindex g
-Produce debugging information in the operating system's native format
-(stabs, COFF, XCOFF, or DWARF 2)@. GDB can work with this debugging
-information.
-
-On most systems that use stabs format, @option{-g} enables use of extra
-debugging information that only GDB can use; this extra information
-makes debugging work better in GDB but probably makes other debuggers
-crash or
-refuse to read the program. If you want to control for certain whether
-to generate the extra information, use @option{-gstabs+}, @option{-gstabs},
-@option{-gxcoff+}, @option{-gxcoff}, or @option{-gvms} (see below).
-
-GCC allows you to use @option{-g} with
-@option{-O}. The shortcuts taken by optimized code may occasionally
-produce surprising results: some variables you declared may not exist
-at all; flow of control may briefly move where you did not expect it;
-some statements may not be executed because they compute constant
-results or their values are already at hand; some statements may
-execute in different places because they have been moved out of loops.
-
-Nevertheless it proves possible to debug optimized output. This makes
-it reasonable to use the optimizer for programs that might have bugs.
-
-The following options are useful when GCC is generated with the
-capability for more than one debugging format.
-
-@item -gsplit-dwarf
-@opindex gsplit-dwarf
-Separate as much dwarf debugging information as possible into a
-separate output file with the extension .dwo. This option allows
-the build system to avoid linking files with debug information. To
-be useful, this option requires a debugger capable of reading .dwo
-files.
-
-@item -ggdb
-@opindex ggdb
-Produce debugging information for use by GDB@. This means to use the
-most expressive format available (DWARF 2, stabs, or the native format
-if neither of those are supported), including GDB extensions if at all
-possible.
-
-@item -gpubnames
-@opindex gpubnames
-Generate dwarf .debug_pubnames and .debug_pubtypes sections.
-
-@item -gstabs
-@opindex gstabs
-Produce debugging information in stabs format (if that is supported),
-without GDB extensions. This is the format used by DBX on most BSD
-systems. On MIPS, Alpha and System V Release 4 systems this option
-produces stabs debugging output that is not understood by DBX or SDB@.
-On System V Release 4 systems this option requires the GNU assembler.
-
-@item -feliminate-unused-debug-symbols
-@opindex feliminate-unused-debug-symbols
-Produce debugging information in stabs format (if that is supported),
-for only symbols that are actually used.
-
-@item -femit-class-debug-always
-Instead of emitting debugging information for a C++ class in only one
-object file, emit it in all object files using the class. This option
-should be used only with debuggers that are unable to handle the way GCC
-normally emits debugging information for classes because using this
-option increases the size of debugging information by as much as a
-factor of two.
-
-@item -fdebug-types-section
-@opindex fdebug-types-section
-@opindex fno-debug-types-section
-When using DWARF Version 4 or higher, type DIEs can be put into
-their own @code{.debug_types} section instead of making them part of the
-@code{.debug_info} section. It is more efficient to put them in a separate
-comdat sections since the linker can then remove duplicates.
-But not all DWARF consumers support @code{.debug_types} sections yet
-and on some objects @code{.debug_types} produces larger instead of smaller
-debugging information.
-
-@item -gstabs+
-@opindex gstabs+
-Produce debugging information in stabs format (if that is supported),
-using GNU extensions understood only by the GNU debugger (GDB)@. The
-use of these extensions is likely to make other debuggers crash or
-refuse to read the program.
-
-@item -gcoff
-@opindex gcoff
-Produce debugging information in COFF format (if that is supported).
-This is the format used by SDB on most System V systems prior to
-System V Release 4.
-
-@item -gxcoff
-@opindex gxcoff
-Produce debugging information in XCOFF format (if that is supported).
-This is the format used by the DBX debugger on IBM RS/6000 systems.
-
-@item -gxcoff+
-@opindex gxcoff+
-Produce debugging information in XCOFF format (if that is supported),
-using GNU extensions understood only by the GNU debugger (GDB)@. The
-use of these extensions is likely to make other debuggers crash or
-refuse to read the program, and may cause assemblers other than the GNU
-assembler (GAS) to fail with an error.
-
-@item -gdwarf-@var{version}
-@opindex gdwarf-@var{version}
-Produce debugging information in DWARF format (if that is supported).
-The value of @var{version} may be either 2, 3 or 4; the default version
-for most targets is 4.
-
-Note that with DWARF Version 2, some ports require and always
-use some non-conflicting DWARF 3 extensions in the unwind tables.
-
-Version 4 may require GDB 7.0 and @option{-fvar-tracking-assignments}
-for maximum benefit.
-
-@item -grecord-gcc-switches
-@opindex grecord-gcc-switches
-This switch causes the command-line options used to invoke the
-compiler that may affect code generation to be appended to the
-DW_AT_producer attribute in DWARF debugging information. The options
-are concatenated with spaces separating them from each other and from
-the compiler version. See also @option{-frecord-gcc-switches} for another
-way of storing compiler options into the object file. This is the default.
-
-@item -gno-record-gcc-switches
-@opindex gno-record-gcc-switches
-Disallow appending command-line options to the DW_AT_producer attribute
-in DWARF debugging information.
-
-@item -gstrict-dwarf
-@opindex gstrict-dwarf
-Disallow using extensions of later DWARF standard version than selected
-with @option{-gdwarf-@var{version}}. On most targets using non-conflicting
-DWARF extensions from later standard versions is allowed.
-
-@item -gno-strict-dwarf
-@opindex gno-strict-dwarf
-Allow using extensions of later DWARF standard version than selected with
-@option{-gdwarf-@var{version}}.
-
-@item -gvms
-@opindex gvms
-Produce debugging information in Alpha/VMS debug format (if that is
-supported). This is the format used by DEBUG on Alpha/VMS systems.
-
-@item -g@var{level}
-@itemx -ggdb@var{level}
-@itemx -gstabs@var{level}
-@itemx -gcoff@var{level}
-@itemx -gxcoff@var{level}
-@itemx -gvms@var{level}
-Request debugging information and also use @var{level} to specify how
-much information. The default level is 2.
-
-Level 0 produces no debug information at all. Thus, @option{-g0} negates
-@option{-g}.
-
-Level 1 produces minimal information, enough for making backtraces in
-parts of the program that you don't plan to debug. This includes
-descriptions of functions and external variables, but no information
-about local variables and no line numbers.
-
-Level 3 includes extra information, such as all the macro definitions
-present in the program. Some debuggers support macro expansion when
-you use @option{-g3}.
-
-@option{-gdwarf-2} does not accept a concatenated debug level, because
-GCC used to support an option @option{-gdwarf} that meant to generate
-debug information in version 1 of the DWARF format (which is very
-different from version 2), and it would have been too confusing. That
-debug format is long obsolete, but the option cannot be changed now.
-Instead use an additional @option{-g@var{level}} option to change the
-debug level for DWARF.
-
-@item -gtoggle
-@opindex gtoggle
-Turn off generation of debug info, if leaving out this option
-generates it, or turn it on at level 2 otherwise. The position of this
-argument in the command line does not matter; it takes effect after all
-other options are processed, and it does so only once, no matter how
-many times it is given. This is mainly intended to be used with
-@option{-fcompare-debug}.
-
-@item -fsanitize=address
-Enable AddressSanitizer, a fast memory error detector.
-Memory access instructions will be instrumented to detect
-out-of-bounds and use-after-free bugs.
-See @uref{http://code.google.com/p/address-sanitizer/} for more details.
-
-@item -fsanitize=thread
-Enable ThreadSanitizer, a fast data race detector.
-Memory access instructions will be instrumented to detect
-data race bugs.
-See @uref{http://code.google.com/p/data-race-test/wiki/ThreadSanitizer} for more details.
-
-@item -fdump-final-insns@r{[}=@var{file}@r{]}
-@opindex fdump-final-insns
-Dump the final internal representation (RTL) to @var{file}. If the
-optional argument is omitted (or if @var{file} is @code{.}), the name
-of the dump file is determined by appending @code{.gkd} to the
-compilation output file name.
-
-@item -fcompare-debug@r{[}=@var{opts}@r{]}
-@opindex fcompare-debug
-@opindex fno-compare-debug
-If no error occurs during compilation, run the compiler a second time,
-adding @var{opts} and @option{-fcompare-debug-second} to the arguments
-passed to the second compilation. Dump the final internal
-representation in both compilations, and print an error if they differ.
-
-If the equal sign is omitted, the default @option{-gtoggle} is used.
-
-The environment variable @env{GCC_COMPARE_DEBUG}, if defined, non-empty
-and nonzero, implicitly enables @option{-fcompare-debug}. If
-@env{GCC_COMPARE_DEBUG} is defined to a string starting with a dash,
-then it is used for @var{opts}, otherwise the default @option{-gtoggle}
-is used.
-
-@option{-fcompare-debug=}, with the equal sign but without @var{opts},
-is equivalent to @option{-fno-compare-debug}, which disables the dumping
-of the final representation and the second compilation, preventing even
-@env{GCC_COMPARE_DEBUG} from taking effect.
-
-To verify full coverage during @option{-fcompare-debug} testing, set
-@env{GCC_COMPARE_DEBUG} to say @samp{-fcompare-debug-not-overridden},
-which GCC rejects as an invalid option in any actual compilation
-(rather than preprocessing, assembly or linking). To get just a
-warning, setting @env{GCC_COMPARE_DEBUG} to @samp{-w%n-fcompare-debug
-not overridden} will do.
-
-@item -fcompare-debug-second
-@opindex fcompare-debug-second
-This option is implicitly passed to the compiler for the second
-compilation requested by @option{-fcompare-debug}, along with options to
-silence warnings, and omitting other options that would cause
-side-effect compiler outputs to files or to the standard output. Dump
-files and preserved temporary files are renamed so as to contain the
-@code{.gk} additional extension during the second compilation, to avoid
-overwriting those generated by the first.
-
-When this option is passed to the compiler driver, it causes the
-@emph{first} compilation to be skipped, which makes it useful for little
-other than debugging the compiler proper.
-
-@item -feliminate-dwarf2-dups
-@opindex feliminate-dwarf2-dups
-Compress DWARF 2 debugging information by eliminating duplicated
-information about each symbol. This option only makes sense when
-generating DWARF 2 debugging information with @option{-gdwarf-2}.
-
-@item -femit-struct-debug-baseonly
-Emit debug information for struct-like types
-only when the base name of the compilation source file
-matches the base name of file in which the struct is defined.
-
-This option substantially reduces the size of debugging information,
-but at significant potential loss in type information to the debugger.
-See @option{-femit-struct-debug-reduced} for a less aggressive option.
-See @option{-femit-struct-debug-detailed} for more detailed control.
-
-This option works only with DWARF 2.
-
-@item -femit-struct-debug-reduced
-Emit debug information for struct-like types
-only when the base name of the compilation source file
-matches the base name of file in which the type is defined,
-unless the struct is a template or defined in a system header.
-
-This option significantly reduces the size of debugging information,
-with some potential loss in type information to the debugger.
-See @option{-femit-struct-debug-baseonly} for a more aggressive option.
-See @option{-femit-struct-debug-detailed} for more detailed control.
-
-This option works only with DWARF 2.
-
-@item -femit-struct-debug-detailed@r{[}=@var{spec-list}@r{]}
-Specify the struct-like types
-for which the compiler generates debug information.
-The intent is to reduce duplicate struct debug information
-between different object files within the same program.
-
-This option is a detailed version of
-@option{-femit-struct-debug-reduced} and @option{-femit-struct-debug-baseonly},
-which serves for most needs.
-
-A specification has the syntax@*
-[@samp{dir:}|@samp{ind:}][@samp{ord:}|@samp{gen:}](@samp{any}|@samp{sys}|@samp{base}|@samp{none})
-
-The optional first word limits the specification to
-structs that are used directly (@samp{dir:}) or used indirectly (@samp{ind:}).
-A struct type is used directly when it is the type of a variable, member.
-Indirect uses arise through pointers to structs.
-That is, when use of an incomplete struct is valid, the use is indirect.
-An example is
-@samp{struct one direct; struct two * indirect;}.
-
-The optional second word limits the specification to
-ordinary structs (@samp{ord:}) or generic structs (@samp{gen:}).
-Generic structs are a bit complicated to explain.
-For C++, these are non-explicit specializations of template classes,
-or non-template classes within the above.
-Other programming languages have generics,
-but @option{-femit-struct-debug-detailed} does not yet implement them.
-
-The third word specifies the source files for those
-structs for which the compiler should emit debug information.
-The values @samp{none} and @samp{any} have the normal meaning.
-The value @samp{base} means that
-the base of name of the file in which the type declaration appears
-must match the base of the name of the main compilation file.
-In practice, this means that when compiling @file{foo.c}, debug information
-is generated for types declared in that file and @file{foo.h},
-but not other header files.
-The value @samp{sys} means those types satisfying @samp{base}
-or declared in system or compiler headers.
-
-You may need to experiment to determine the best settings for your application.
-
-The default is @option{-femit-struct-debug-detailed=all}.
-
-This option works only with DWARF 2.
-
-@item -fno-merge-debug-strings
-@opindex fmerge-debug-strings
-@opindex fno-merge-debug-strings
-Direct the linker to not merge together strings in the debugging
-information that are identical in different object files. Merging is
-not supported by all assemblers or linkers. Merging decreases the size
-of the debug information in the output file at the cost of increasing
-link processing time. Merging is enabled by default.
-
-@item -fdebug-prefix-map=@var{old}=@var{new}
-@opindex fdebug-prefix-map
-When compiling files in directory @file{@var{old}}, record debugging
-information describing them as in @file{@var{new}} instead.
-
-@item -fno-dwarf2-cfi-asm
-@opindex fdwarf2-cfi-asm
-@opindex fno-dwarf2-cfi-asm
-Emit DWARF 2 unwind info as compiler generated @code{.eh_frame} section
-instead of using GAS @code{.cfi_*} directives.
-
-@cindex @command{prof}
-@item -p
-@opindex p
-Generate extra code to write profile information suitable for the
-analysis program @command{prof}. You must use this option when compiling
-the source files you want data about, and you must also use it when
-linking.
-
-@cindex @command{gprof}
-@item -pg
-@opindex pg
-Generate extra code to write profile information suitable for the
-analysis program @command{gprof}. You must use this option when compiling
-the source files you want data about, and you must also use it when
-linking.
-
-@item -Q
-@opindex Q
-Makes the compiler print out each function name as it is compiled, and
-print some statistics about each pass when it finishes.
-
-@item -ftime-report
-@opindex ftime-report
-Makes the compiler print some statistics about the time consumed by each
-pass when it finishes.
-
-@item -fmem-report
-@opindex fmem-report
-Makes the compiler print some statistics about permanent memory
-allocation when it finishes.
-
-@item -fmem-report-wpa
-@opindex fmem-report-wpa
-Makes the compiler print some statistics about permanent memory
-allocation for the WPA phase only.
-
-@item -fpre-ipa-mem-report
-@opindex fpre-ipa-mem-report
-@item -fpost-ipa-mem-report
-@opindex fpost-ipa-mem-report
-Makes the compiler print some statistics about permanent memory
-allocation before or after interprocedural optimization.
-
-@item -fprofile-report
-@opindex fprofile-report
-Makes the compiler print some statistics about consistency of the
-(estimated) profile and effect of individual passes.
-
-@item -fstack-usage
-@opindex fstack-usage
-Makes the compiler output stack usage information for the program, on a
-per-function basis. The filename for the dump is made by appending
-@file{.su} to the @var{auxname}. @var{auxname} is generated from the name of
-the output file, if explicitly specified and it is not an executable,
-otherwise it is the basename of the source file. An entry is made up
-of three fields:
-
-@itemize
-@item
-The name of the function.
-@item
-A number of bytes.
-@item
-One or more qualifiers: @code{static}, @code{dynamic}, @code{bounded}.
-@end itemize
-
-The qualifier @code{static} means that the function manipulates the stack
-statically: a fixed number of bytes are allocated for the frame on function
-entry and released on function exit; no stack adjustments are otherwise made
-in the function. The second field is this fixed number of bytes.
-
-The qualifier @code{dynamic} means that the function manipulates the stack
-dynamically: in addition to the static allocation described above, stack
-adjustments are made in the body of the function, for example to push/pop
-arguments around function calls. If the qualifier @code{bounded} is also
-present, the amount of these adjustments is bounded at compile time and
-the second field is an upper bound of the total amount of stack used by
-the function. If it is not present, the amount of these adjustments is
-not bounded at compile time and the second field only represents the
-bounded part.
-
-@item -fprofile-arcs
-@opindex fprofile-arcs
-Add code so that program flow @dfn{arcs} are instrumented. During
-execution the program records how many times each branch and call is
-executed and how many times it is taken or returns. When the compiled
-program exits it saves this data to a file called
-@file{@var{auxname}.gcda} for each source file. The data may be used for
-profile-directed optimizations (@option{-fbranch-probabilities}), or for
-test coverage analysis (@option{-ftest-coverage}). Each object file's
-@var{auxname} is generated from the name of the output file, if
-explicitly specified and it is not the final executable, otherwise it is
-the basename of the source file. In both cases any suffix is removed
-(e.g.@: @file{foo.gcda} for input file @file{dir/foo.c}, or
-@file{dir/foo.gcda} for output file specified as @option{-o dir/foo.o}).
-@xref{Cross-profiling}.
-
-@cindex @command{gcov}
-@item --coverage
-@opindex coverage
-
-This option is used to compile and link code instrumented for coverage
-analysis. The option is a synonym for @option{-fprofile-arcs}
-@option{-ftest-coverage} (when compiling) and @option{-lgcov} (when
-linking). See the documentation for those options for more details.
-
-@itemize
-
-@item
-Compile the source files with @option{-fprofile-arcs} plus optimization
-and code generation options. For test coverage analysis, use the
-additional @option{-ftest-coverage} option. You do not need to profile
-every source file in a program.
-
-@item
-Link your object files with @option{-lgcov} or @option{-fprofile-arcs}
-(the latter implies the former).
-
-@item
-Run the program on a representative workload to generate the arc profile
-information. This may be repeated any number of times. You can run
-concurrent instances of your program, and provided that the file system
-supports locking, the data files will be correctly updated. Also
-@code{fork} calls are detected and correctly handled (double counting
-will not happen).
-
-@item
-For profile-directed optimizations, compile the source files again with
-the same optimization and code generation options plus
-@option{-fbranch-probabilities} (@pxref{Optimize Options,,Options that
-Control Optimization}).
-
-@item
-For test coverage analysis, use @command{gcov} to produce human readable
-information from the @file{.gcno} and @file{.gcda} files. Refer to the
-@command{gcov} documentation for further information.
-
-@end itemize
-
-With @option{-fprofile-arcs}, for each function of your program GCC
-creates a program flow graph, then finds a spanning tree for the graph.
-Only arcs that are not on the spanning tree have to be instrumented: the
-compiler adds code to count the number of times that these arcs are
-executed. When an arc is the only exit or only entrance to a block, the
-instrumentation code can be added to the block; otherwise, a new basic
-block must be created to hold the instrumentation code.
-
-@need 2000
-@item -ftest-coverage
-@opindex ftest-coverage
-Produce a notes file that the @command{gcov} code-coverage utility
-(@pxref{Gcov,, @command{gcov}---a Test Coverage Program}) can use to
-show program coverage. Each source file's note file is called
-@file{@var{auxname}.gcno}. Refer to the @option{-fprofile-arcs} option
-above for a description of @var{auxname} and instructions on how to
-generate test coverage data. Coverage data matches the source files
-more closely if you do not optimize.
-
-@item -fdbg-cnt-list
-@opindex fdbg-cnt-list
-Print the name and the counter upper bound for all debug counters.
-
-
-@item -fdbg-cnt=@var{counter-value-list}
-@opindex fdbg-cnt
-Set the internal debug counter upper bound. @var{counter-value-list}
-is a comma-separated list of @var{name}:@var{value} pairs
-which sets the upper bound of each debug counter @var{name} to @var{value}.
-All debug counters have the initial upper bound of @code{UINT_MAX};
-thus @code{dbg_cnt()} returns true always unless the upper bound
-is set by this option.
-For example, with @option{-fdbg-cnt=dce:10,tail_call:0},
-@code{dbg_cnt(dce)} returns true only for first 10 invocations.
-
-@item -fenable-@var{kind}-@var{pass}
-@itemx -fdisable-@var{kind}-@var{pass}=@var{range-list}
-@opindex fdisable-
-@opindex fenable-
-
-This is a set of options that are used to explicitly disable/enable
-optimization passes. These options are intended for use for debugging GCC.
-Compiler users should use regular options for enabling/disabling
-passes instead.
-
-@table @gcctabopt
-
-@item -fdisable-ipa-@var{pass}
-Disable IPA pass @var{pass}. @var{pass} is the pass name. If the same pass is
-statically invoked in the compiler multiple times, the pass name should be
-appended with a sequential number starting from 1.
-
-@item -fdisable-rtl-@var{pass}
-@itemx -fdisable-rtl-@var{pass}=@var{range-list}
-Disable RTL pass @var{pass}. @var{pass} is the pass name. If the same pass is
-statically invoked in the compiler multiple times, the pass name should be
-appended with a sequential number starting from 1. @var{range-list} is a
-comma-separated list of function ranges or assembler names. Each range is a number
-pair separated by a colon. The range is inclusive in both ends. If the range
-is trivial, the number pair can be simplified as a single number. If the
-function's call graph node's @var{uid} falls within one of the specified ranges,
-the @var{pass} is disabled for that function. The @var{uid} is shown in the
-function header of a dump file, and the pass names can be dumped by using
-option @option{-fdump-passes}.
-
-@item -fdisable-tree-@var{pass}
-@itemx -fdisable-tree-@var{pass}=@var{range-list}
-Disable tree pass @var{pass}. See @option{-fdisable-rtl} for the description of
-option arguments.
-
-@item -fenable-ipa-@var{pass}
-Enable IPA pass @var{pass}. @var{pass} is the pass name. If the same pass is
-statically invoked in the compiler multiple times, the pass name should be
-appended with a sequential number starting from 1.
-
-@item -fenable-rtl-@var{pass}
-@itemx -fenable-rtl-@var{pass}=@var{range-list}
-Enable RTL pass @var{pass}. See @option{-fdisable-rtl} for option argument
-description and examples.
-
-@item -fenable-tree-@var{pass}
-@itemx -fenable-tree-@var{pass}=@var{range-list}
-Enable tree pass @var{pass}. See @option{-fdisable-rtl} for the description
-of option arguments.
-
-@end table
-
-Here are some examples showing uses of these options.
-
-@smallexample
-
-# disable ccp1 for all functions
- -fdisable-tree-ccp1
-# disable complete unroll for function whose cgraph node uid is 1
- -fenable-tree-cunroll=1
-# disable gcse2 for functions at the following ranges [1,1],
-# [300,400], and [400,1000]
-# disable gcse2 for functions foo and foo2
- -fdisable-rtl-gcse2=foo,foo2
-# disable early inlining
- -fdisable-tree-einline
-# disable ipa inlining
- -fdisable-ipa-inline
-# enable tree full unroll
- -fenable-tree-unroll
-
-@end smallexample
-
-@item -d@var{letters}
-@itemx -fdump-rtl-@var{pass}
-@itemx -fdump-rtl-@var{pass}=@var{filename}
-@opindex d
-Says to make debugging dumps during compilation at times specified by
-@var{letters}. This is used for debugging the RTL-based passes of the
-compiler. The file names for most of the dumps are made by appending
-a pass number and a word to the @var{dumpname}, and the files are
-created in the directory of the output file. In case of
-@option{=@var{filename}} option, the dump is output on the given file
-instead of the pass numbered dump files. Note that the pass number is
-computed statically as passes get registered into the pass manager.
-Thus the numbering is not related to the dynamic order of execution of
-passes. In particular, a pass installed by a plugin could have a
-number over 200 even if it executed quite early. @var{dumpname} is
-generated from the name of the output file, if explicitly specified
-and it is not an executable, otherwise it is the basename of the
-source file. These switches may have different effects when
-@option{-E} is used for preprocessing.
-
-Debug dumps can be enabled with a @option{-fdump-rtl} switch or some
-@option{-d} option @var{letters}. Here are the possible
-letters for use in @var{pass} and @var{letters}, and their meanings:
-
-@table @gcctabopt
-
-@item -fdump-rtl-alignments
-@opindex fdump-rtl-alignments
-Dump after branch alignments have been computed.
-
-@item -fdump-rtl-asmcons
-@opindex fdump-rtl-asmcons
-Dump after fixing rtl statements that have unsatisfied in/out constraints.
-
-@item -fdump-rtl-auto_inc_dec
-@opindex fdump-rtl-auto_inc_dec
-Dump after auto-inc-dec discovery. This pass is only run on
-architectures that have auto inc or auto dec instructions.
-
-@item -fdump-rtl-barriers
-@opindex fdump-rtl-barriers
-Dump after cleaning up the barrier instructions.
-
-@item -fdump-rtl-bbpart
-@opindex fdump-rtl-bbpart
-Dump after partitioning hot and cold basic blocks.
-
-@item -fdump-rtl-bbro
-@opindex fdump-rtl-bbro
-Dump after block reordering.
-
-@item -fdump-rtl-btl1
-@itemx -fdump-rtl-btl2
-@opindex fdump-rtl-btl2
-@opindex fdump-rtl-btl2
-@option{-fdump-rtl-btl1} and @option{-fdump-rtl-btl2} enable dumping
-after the two branch
-target load optimization passes.
-
-@item -fdump-rtl-bypass
-@opindex fdump-rtl-bypass
-Dump after jump bypassing and control flow optimizations.
-
-@item -fdump-rtl-combine
-@opindex fdump-rtl-combine
-Dump after the RTL instruction combination pass.
-
-@item -fdump-rtl-compgotos
-@opindex fdump-rtl-compgotos
-Dump after duplicating the computed gotos.
-
-@item -fdump-rtl-ce1
-@itemx -fdump-rtl-ce2
-@itemx -fdump-rtl-ce3
-@opindex fdump-rtl-ce1
-@opindex fdump-rtl-ce2
-@opindex fdump-rtl-ce3
-@option{-fdump-rtl-ce1}, @option{-fdump-rtl-ce2}, and
-@option{-fdump-rtl-ce3} enable dumping after the three
-if conversion passes.
-
-@item -fdump-rtl-cprop_hardreg
-@opindex fdump-rtl-cprop_hardreg
-Dump after hard register copy propagation.
-
-@item -fdump-rtl-csa
-@opindex fdump-rtl-csa
-Dump after combining stack adjustments.
-
-@item -fdump-rtl-cse1
-@itemx -fdump-rtl-cse2
-@opindex fdump-rtl-cse1
-@opindex fdump-rtl-cse2
-@option{-fdump-rtl-cse1} and @option{-fdump-rtl-cse2} enable dumping after
-the two common subexpression elimination passes.
-
-@item -fdump-rtl-dce
-@opindex fdump-rtl-dce
-Dump after the standalone dead code elimination passes.
-
-@item -fdump-rtl-dbr
-@opindex fdump-rtl-dbr
-Dump after delayed branch scheduling.
-
-@item -fdump-rtl-dce1
-@itemx -fdump-rtl-dce2
-@opindex fdump-rtl-dce1
-@opindex fdump-rtl-dce2
-@option{-fdump-rtl-dce1} and @option{-fdump-rtl-dce2} enable dumping after
-the two dead store elimination passes.
-
-@item -fdump-rtl-eh
-@opindex fdump-rtl-eh
-Dump after finalization of EH handling code.
-
-@item -fdump-rtl-eh_ranges
-@opindex fdump-rtl-eh_ranges
-Dump after conversion of EH handling range regions.
-
-@item -fdump-rtl-expand
-@opindex fdump-rtl-expand
-Dump after RTL generation.
-
-@item -fdump-rtl-fwprop1
-@itemx -fdump-rtl-fwprop2
-@opindex fdump-rtl-fwprop1
-@opindex fdump-rtl-fwprop2
-@option{-fdump-rtl-fwprop1} and @option{-fdump-rtl-fwprop2} enable
-dumping after the two forward propagation passes.
-
-@item -fdump-rtl-gcse1
-@itemx -fdump-rtl-gcse2
-@opindex fdump-rtl-gcse1
-@opindex fdump-rtl-gcse2
-@option{-fdump-rtl-gcse1} and @option{-fdump-rtl-gcse2} enable dumping
-after global common subexpression elimination.
-
-@item -fdump-rtl-init-regs
-@opindex fdump-rtl-init-regs
-Dump after the initialization of the registers.
-
-@item -fdump-rtl-initvals
-@opindex fdump-rtl-initvals
-Dump after the computation of the initial value sets.
-
-@item -fdump-rtl-into_cfglayout
-@opindex fdump-rtl-into_cfglayout
-Dump after converting to cfglayout mode.
-
-@item -fdump-rtl-ira
-@opindex fdump-rtl-ira
-Dump after iterated register allocation.
-
-@item -fdump-rtl-jump
-@opindex fdump-rtl-jump
-Dump after the second jump optimization.
-
-@item -fdump-rtl-loop2
-@opindex fdump-rtl-loop2
-@option{-fdump-rtl-loop2} enables dumping after the rtl
-loop optimization passes.
-
-@item -fdump-rtl-mach
-@opindex fdump-rtl-mach
-Dump after performing the machine dependent reorganization pass, if that
-pass exists.
-
-@item -fdump-rtl-mode_sw
-@opindex fdump-rtl-mode_sw
-Dump after removing redundant mode switches.
-
-@item -fdump-rtl-rnreg
-@opindex fdump-rtl-rnreg
-Dump after register renumbering.
-
-@item -fdump-rtl-outof_cfglayout
-@opindex fdump-rtl-outof_cfglayout
-Dump after converting from cfglayout mode.
-
-@item -fdump-rtl-peephole2
-@opindex fdump-rtl-peephole2
-Dump after the peephole pass.
-
-@item -fdump-rtl-postreload
-@opindex fdump-rtl-postreload
-Dump after post-reload optimizations.
-
-@item -fdump-rtl-pro_and_epilogue
-@opindex fdump-rtl-pro_and_epilogue
-Dump after generating the function prologues and epilogues.
-
-@item -fdump-rtl-regmove
-@opindex fdump-rtl-regmove
-Dump after the register move pass.
-
-@item -fdump-rtl-sched1
-@itemx -fdump-rtl-sched2
-@opindex fdump-rtl-sched1
-@opindex fdump-rtl-sched2
-@option{-fdump-rtl-sched1} and @option{-fdump-rtl-sched2} enable dumping
-after the basic block scheduling passes.
-
-@item -fdump-rtl-see
-@opindex fdump-rtl-see
-Dump after sign extension elimination.
-
-@item -fdump-rtl-seqabstr
-@opindex fdump-rtl-seqabstr
-Dump after common sequence discovery.
-
-@item -fdump-rtl-shorten
-@opindex fdump-rtl-shorten
-Dump after shortening branches.
-
-@item -fdump-rtl-sibling
-@opindex fdump-rtl-sibling
-Dump after sibling call optimizations.
-
-@item -fdump-rtl-split1
-@itemx -fdump-rtl-split2
-@itemx -fdump-rtl-split3
-@itemx -fdump-rtl-split4
-@itemx -fdump-rtl-split5
-@opindex fdump-rtl-split1
-@opindex fdump-rtl-split2
-@opindex fdump-rtl-split3
-@opindex fdump-rtl-split4
-@opindex fdump-rtl-split5
-@option{-fdump-rtl-split1}, @option{-fdump-rtl-split2},
-@option{-fdump-rtl-split3}, @option{-fdump-rtl-split4} and
-@option{-fdump-rtl-split5} enable dumping after five rounds of
-instruction splitting.
-
-@item -fdump-rtl-sms
-@opindex fdump-rtl-sms
-Dump after modulo scheduling. This pass is only run on some
-architectures.
-
-@item -fdump-rtl-stack
-@opindex fdump-rtl-stack
-Dump after conversion from GCC's ``flat register file'' registers to the
-x87's stack-like registers. This pass is only run on x86 variants.
-
-@item -fdump-rtl-subreg1
-@itemx -fdump-rtl-subreg2
-@opindex fdump-rtl-subreg1
-@opindex fdump-rtl-subreg2
-@option{-fdump-rtl-subreg1} and @option{-fdump-rtl-subreg2} enable dumping after
-the two subreg expansion passes.
-
-@item -fdump-rtl-unshare
-@opindex fdump-rtl-unshare
-Dump after all rtl has been unshared.
-
-@item -fdump-rtl-vartrack
-@opindex fdump-rtl-vartrack
-Dump after variable tracking.
-
-@item -fdump-rtl-vregs
-@opindex fdump-rtl-vregs
-Dump after converting virtual registers to hard registers.
-
-@item -fdump-rtl-web
-@opindex fdump-rtl-web
-Dump after live range splitting.
-
-@item -fdump-rtl-regclass
-@itemx -fdump-rtl-subregs_of_mode_init
-@itemx -fdump-rtl-subregs_of_mode_finish
-@itemx -fdump-rtl-dfinit
-@itemx -fdump-rtl-dfinish
-@opindex fdump-rtl-regclass
-@opindex fdump-rtl-subregs_of_mode_init
-@opindex fdump-rtl-subregs_of_mode_finish
-@opindex fdump-rtl-dfinit
-@opindex fdump-rtl-dfinish
-These dumps are defined but always produce empty files.
-
-@item -da
-@itemx -fdump-rtl-all
-@opindex da
-@opindex fdump-rtl-all
-Produce all the dumps listed above.
-
-@item -dA
-@opindex dA
-Annotate the assembler output with miscellaneous debugging information.
-
-@item -dD
-@opindex dD
-Dump all macro definitions, at the end of preprocessing, in addition to
-normal output.
-
-@item -dH
-@opindex dH
-Produce a core dump whenever an error occurs.
-
-@item -dp
-@opindex dp
-Annotate the assembler output with a comment indicating which
-pattern and alternative is used. The length of each instruction is
-also printed.
-
-@item -dP
-@opindex dP
-Dump the RTL in the assembler output as a comment before each instruction.
-Also turns on @option{-dp} annotation.
-
-@item -dx
-@opindex dx
-Just generate RTL for a function instead of compiling it. Usually used
-with @option{-fdump-rtl-expand}.
-@end table
-
-@item -fdump-noaddr
-@opindex fdump-noaddr
-When doing debugging dumps, suppress address output. This makes it more
-feasible to use diff on debugging dumps for compiler invocations with
-different compiler binaries and/or different
-text / bss / data / heap / stack / dso start locations.
-
-@item -fdump-unnumbered
-@opindex fdump-unnumbered
-When doing debugging dumps, suppress instruction numbers and address output.
-This makes it more feasible to use diff on debugging dumps for compiler
-invocations with different options, in particular with and without
-@option{-g}.
-
-@item -fdump-unnumbered-links
-@opindex fdump-unnumbered-links
-When doing debugging dumps (see @option{-d} option above), suppress
-instruction numbers for the links to the previous and next instructions
-in a sequence.
-
-@item -fdump-translation-unit @r{(C++ only)}
-@itemx -fdump-translation-unit-@var{options} @r{(C++ only)}
-@opindex fdump-translation-unit
-Dump a representation of the tree structure for the entire translation
-unit to a file. The file name is made by appending @file{.tu} to the
-source file name, and the file is created in the same directory as the
-output file. If the @samp{-@var{options}} form is used, @var{options}
-controls the details of the dump as described for the
-@option{-fdump-tree} options.
-
-@item -fdump-class-hierarchy @r{(C++ only)}
-@itemx -fdump-class-hierarchy-@var{options} @r{(C++ only)}
-@opindex fdump-class-hierarchy
-Dump a representation of each class's hierarchy and virtual function
-table layout to a file. The file name is made by appending
-@file{.class} to the source file name, and the file is created in the
-same directory as the output file. If the @samp{-@var{options}} form
-is used, @var{options} controls the details of the dump as described
-for the @option{-fdump-tree} options.
-
-@item -fdump-ipa-@var{switch}
-@opindex fdump-ipa
-Control the dumping at various stages of inter-procedural analysis
-language tree to a file. The file name is generated by appending a
-switch specific suffix to the source file name, and the file is created
-in the same directory as the output file. The following dumps are
-possible:
-
-@table @samp
-@item all
-Enables all inter-procedural analysis dumps.
-
-@item cgraph
-Dumps information about call-graph optimization, unused function removal,
-and inlining decisions.
-
-@item inline
-Dump after function inlining.
-
-@end table
-
-@item -fdump-passes
-@opindex fdump-passes
-Dump the list of optimization passes that are turned on and off by
-the current command-line options.
-
-@item -fdump-statistics-@var{option}
-@opindex fdump-statistics
-Enable and control dumping of pass statistics in a separate file. The
-file name is generated by appending a suffix ending in
-@samp{.statistics} to the source file name, and the file is created in
-the same directory as the output file. If the @samp{-@var{option}}
-form is used, @samp{-stats} causes counters to be summed over the
-whole compilation unit while @samp{-details} dumps every event as
-the passes generate them. The default with no option is to sum
-counters for each function compiled.
-
-@item -fdump-tree-@var{switch}
-@itemx -fdump-tree-@var{switch}-@var{options}
-@itemx -fdump-tree-@var{switch}-@var{options}=@var{filename}
-@opindex fdump-tree
-Control the dumping at various stages of processing the intermediate
-language tree to a file. The file name is generated by appending a
-switch-specific suffix to the source file name, and the file is
-created in the same directory as the output file. In case of
-@option{=@var{filename}} option, the dump is output on the given file
-instead of the auto named dump files. If the @samp{-@var{options}}
-form is used, @var{options} is a list of @samp{-} separated options
-which control the details of the dump. Not all options are applicable
-to all dumps; those that are not meaningful are ignored. The
-following options are available
-
-@table @samp
-@item address
-Print the address of each node. Usually this is not meaningful as it
-changes according to the environment and source file. Its primary use
-is for tying up a dump file with a debug environment.
-@item asmname
-If @code{DECL_ASSEMBLER_NAME} has been set for a given decl, use that
-in the dump instead of @code{DECL_NAME}. Its primary use is ease of
-use working backward from mangled names in the assembly file.
-@item slim
-When dumping front-end intermediate representations, inhibit dumping
-of members of a scope or body of a function merely because that scope
-has been reached. Only dump such items when they are directly reachable
-by some other path.
-
-When dumping pretty-printed trees, this option inhibits dumping the
-bodies of control structures.
-
-When dumping RTL, print the RTL in slim (condensed) form instead of
-the default LISP-like representation.
-@item raw
-Print a raw representation of the tree. By default, trees are
-pretty-printed into a C-like representation.
-@item details
-Enable more detailed dumps (not honored by every dump option). Also
-include information from the optimization passes.
-@item stats
-Enable dumping various statistics about the pass (not honored by every dump
-option).
-@item blocks
-Enable showing basic block boundaries (disabled in raw dumps).
-@item graph
-For each of the other indicated dump files (@option{-fdump-rtl-@var{pass}}),
-dump a representation of the control flow graph suitable for viewing with
-GraphViz to @file{@var{file}.@var{passid}.@var{pass}.dot}. Each function in
-the file is pretty-printed as a subgraph, so that GraphViz can render them
-all in a single plot.
-
-This option currently only works for RTL dumps, and the RTL is always
-dumped in slim form.
-@item vops
-Enable showing virtual operands for every statement.
-@item lineno
-Enable showing line numbers for statements.
-@item uid
-Enable showing the unique ID (@code{DECL_UID}) for each variable.
-@item verbose
-Enable showing the tree dump for each statement.
-@item eh
-Enable showing the EH region number holding each statement.
-@item scev
-Enable showing scalar evolution analysis details.
-@item optimized
-Enable showing optimization information (only available in certain
-passes).
-@item missed
-Enable showing missed optimization information (only available in certain
-passes).
-@item notes
-Enable other detailed optimization information (only available in
-certain passes).
-@item =@var{filename}
-Instead of an auto named dump file, output into the given file
-name. The file names @file{stdout} and @file{stderr} are treated
-specially and are considered already open standard streams. For
-example,
-
-@smallexample
-gcc -O2 -ftree-vectorize -fdump-tree-vect-blocks=foo.dump
- -fdump-tree-pre=stderr file.c
-@end smallexample
-
-outputs vectorizer dump into @file{foo.dump}, while the PRE dump is
-output on to @file{stderr}. If two conflicting dump filenames are
-given for the same pass, then the latter option overrides the earlier
-one.
-
-@item all
-Turn on all options, except @option{raw}, @option{slim}, @option{verbose}
-and @option{lineno}.
-
-@item optall
-Turn on all optimization options, i.e., @option{optimized},
-@option{missed}, and @option{note}.
-@end table
-
-The following tree dumps are possible:
-@table @samp
-
-@item original
-@opindex fdump-tree-original
-Dump before any tree based optimization, to @file{@var{file}.original}.
-
-@item optimized
-@opindex fdump-tree-optimized
-Dump after all tree based optimization, to @file{@var{file}.optimized}.
-
-@item gimple
-@opindex fdump-tree-gimple
-Dump each function before and after the gimplification pass to a file. The
-file name is made by appending @file{.gimple} to the source file name.
-
-@item cfg
-@opindex fdump-tree-cfg
-Dump the control flow graph of each function to a file. The file name is
-made by appending @file{.cfg} to the source file name.
-
-@item ch
-@opindex fdump-tree-ch
-Dump each function after copying loop headers. The file name is made by
-appending @file{.ch} to the source file name.
-
-@item ssa
-@opindex fdump-tree-ssa
-Dump SSA related information to a file. The file name is made by appending
-@file{.ssa} to the source file name.
-
-@item alias
-@opindex fdump-tree-alias
-Dump aliasing information for each function. The file name is made by
-appending @file{.alias} to the source file name.
-
-@item ccp
-@opindex fdump-tree-ccp
-Dump each function after CCP@. The file name is made by appending
-@file{.ccp} to the source file name.
-
-@item storeccp
-@opindex fdump-tree-storeccp
-Dump each function after STORE-CCP@. The file name is made by appending
-@file{.storeccp} to the source file name.
-
-@item pre
-@opindex fdump-tree-pre
-Dump trees after partial redundancy elimination. The file name is made
-by appending @file{.pre} to the source file name.
-
-@item fre
-@opindex fdump-tree-fre
-Dump trees after full redundancy elimination. The file name is made
-by appending @file{.fre} to the source file name.
-
-@item copyprop
-@opindex fdump-tree-copyprop
-Dump trees after copy propagation. The file name is made
-by appending @file{.copyprop} to the source file name.
-
-@item store_copyprop
-@opindex fdump-tree-store_copyprop
-Dump trees after store copy-propagation. The file name is made
-by appending @file{.store_copyprop} to the source file name.
-
-@item dce
-@opindex fdump-tree-dce
-Dump each function after dead code elimination. The file name is made by
-appending @file{.dce} to the source file name.
-
-@item mudflap
-@opindex fdump-tree-mudflap
-Dump each function after adding mudflap instrumentation. The file name is
-made by appending @file{.mudflap} to the source file name.
-
-@item sra
-@opindex fdump-tree-sra
-Dump each function after performing scalar replacement of aggregates. The
-file name is made by appending @file{.sra} to the source file name.
-
-@item sink
-@opindex fdump-tree-sink
-Dump each function after performing code sinking. The file name is made
-by appending @file{.sink} to the source file name.
-
-@item dom
-@opindex fdump-tree-dom
-Dump each function after applying dominator tree optimizations. The file
-name is made by appending @file{.dom} to the source file name.
-
-@item dse
-@opindex fdump-tree-dse
-Dump each function after applying dead store elimination. The file
-name is made by appending @file{.dse} to the source file name.
-
-@item phiopt
-@opindex fdump-tree-phiopt
-Dump each function after optimizing PHI nodes into straightline code. The file
-name is made by appending @file{.phiopt} to the source file name.
-
-@item forwprop
-@opindex fdump-tree-forwprop
-Dump each function after forward propagating single use variables. The file
-name is made by appending @file{.forwprop} to the source file name.
-
-@item copyrename
-@opindex fdump-tree-copyrename
-Dump each function after applying the copy rename optimization. The file
-name is made by appending @file{.copyrename} to the source file name.
-
-@item nrv
-@opindex fdump-tree-nrv
-Dump each function after applying the named return value optimization on
-generic trees. The file name is made by appending @file{.nrv} to the source
-file name.
-
-@item vect
-@opindex fdump-tree-vect
-Dump each function after applying vectorization of loops. The file name is
-made by appending @file{.vect} to the source file name.
-
-@item slp
-@opindex fdump-tree-slp
-Dump each function after applying vectorization of basic blocks. The file name
-is made by appending @file{.slp} to the source file name.
-
-@item vrp
-@opindex fdump-tree-vrp
-Dump each function after Value Range Propagation (VRP). The file name
-is made by appending @file{.vrp} to the source file name.
-
-@item all
-@opindex fdump-tree-all
-Enable all the available tree dumps with the flags provided in this option.
-@end table
-
-@item -fopt-info
-@itemx -fopt-info-@var{options}
-@itemx -fopt-info-@var{options}=@var{filename}
-@opindex fopt-info
-Controls optimization dumps from various optimization passes. If the
-@samp{-@var{options}} form is used, @var{options} is a list of
-@samp{-} separated options to select the dump details and
-optimizations. If @var{options} is not specified, it defaults to
-@option{all} for details and @option{optall} for optimization
-groups. If the @var{filename} is not specified, it defaults to
-@file{stderr}. Note that the output @var{filename} will be overwritten
-in case of multiple translation units. If a combined output from
-multiple translation units is desired, @file{stderr} should be used
-instead.
-
-The options can be divided into two groups, 1) options describing the
-verbosity of the dump, and 2) options describing which optimizations
-should be included. The options from both the groups can be freely
-mixed as they are non-overlapping. However, in case of any conflicts,
-the latter options override the earlier options on the command
-line. Though multiple -fopt-info options are accepted, only one of
-them can have @option{=filename}. If other filenames are provided then
-all but the first one are ignored.
-
-The dump verbosity has the following options
-
-@table @samp
-@item optimized
-Print information when an optimization is successfully applied. It is
-up to a pass to decide which information is relevant. For example, the
-vectorizer passes print the source location of loops which got
-successfully vectorized.
-@item missed
-Print information about missed optimizations. Individual passes
-control which information to include in the output. For example,
-
-@smallexample
-gcc -O2 -ftree-vectorize -fopt-info-vec-missed
-@end smallexample
-
-will print information about missed optimization opportunities from
-vectorization passes on stderr.
-@item note
-Print verbose information about optimizations, such as certain
-transformations, more detailed messages about decisions etc.
-@item all
-Print detailed optimization information. This includes
-@var{optimized}, @var{missed}, and @var{note}.
-@end table
-
-The second set of options describes a group of optimizations and may
-include one or more of the following.
-
-@table @samp
-@item ipa
-Enable dumps from all interprocedural optimizations.
-@item loop
-Enable dumps from all loop optimizations.
-@item inline
-Enable dumps from all inlining optimizations.
-@item vec
-Enable dumps from all vectorization optimizations.
-@end table
-
-For example,
-@smallexample
-gcc -O3 -fopt-info-missed=missed.all
-@end smallexample
-
-outputs missed optimization report from all the passes into
-@file{missed.all}.
-
-As another example,
-@smallexample
-gcc -O3 -fopt-info-inline-optimized-missed=inline.txt
-@end smallexample
-
-will output information about missed optimizations as well as
-optimized locations from all the inlining passes into
-@file{inline.txt}.
-
-If the @var{filename} is provided, then the dumps from all the
-applicable optimizations are concatenated into the @file{filename}.
-Otherwise the dump is output onto @file{stderr}. If @var{options} is
-omitted, it defaults to @option{all-optall}, which means dump all
-available optimization info from all the passes. In the following
-example, all optimization info is output on to @file{stderr}.
-
-@smallexample
-gcc -O3 -fopt-info
-@end smallexample
-
-Note that @option{-fopt-info-vec-missed} behaves the same as
-@option{-fopt-info-missed-vec}.
-
-As another example, consider
-
-@smallexample
-gcc -fopt-info-vec-missed=vec.miss -fopt-info-loop-optimized=loop.opt
-@end smallexample
-
-Here the two output filenames @file{vec.miss} and @file{loop.opt} are
-in conflict since only one output file is allowed. In this case, only
-the first option takes effect and the subsequent options are
-ignored. Thus only the @file{vec.miss} is produced which cotaints
-dumps from the vectorizer about missed opportunities.
-
-@item -ftree-vectorizer-verbose=@var{n}
-@opindex ftree-vectorizer-verbose
-This option is deprecated and is implemented in terms of
-@option{-fopt-info}. Please use @option{-fopt-info-@var{kind}} form
-instead, where @var{kind} is one of the valid opt-info options. It
-prints additional optimization information. For @var{n}=0 no
-diagnostic information is reported. If @var{n}=1 the vectorizer
-reports each loop that got vectorized, and the total number of loops
-that got vectorized. If @var{n}=2 the vectorizer reports locations
-which could not be vectorized and the reasons for those. For any
-higher verbosity levels all the analysis and transformation
-information from the vectorizer is reported.
-
-Note that the information output by @option{-ftree-vectorizer-verbose}
-option is sent to @file{stderr}. If the equivalent form
-@option{-fopt-info-@var{options}=@var{filename}} is used then the
-output is sent into @var{filename} instead.
-
-@item -frandom-seed=@var{string}
-@opindex frandom-seed
-This option provides a seed that GCC uses in place of
-random numbers in generating certain symbol names
-that have to be different in every compiled file. It is also used to
-place unique stamps in coverage data files and the object files that
-produce them. You can use the @option{-frandom-seed} option to produce
-reproducibly identical object files.
-
-The @var{string} should be different for every file you compile.
-
-@item -fsched-verbose=@var{n}
-@opindex fsched-verbose
-On targets that use instruction scheduling, this option controls the
-amount of debugging output the scheduler prints. This information is
-written to standard error, unless @option{-fdump-rtl-sched1} or
-@option{-fdump-rtl-sched2} is specified, in which case it is output
-to the usual dump listing file, @file{.sched1} or @file{.sched2}
-respectively. However for @var{n} greater than nine, the output is
-always printed to standard error.
-
-For @var{n} greater than zero, @option{-fsched-verbose} outputs the
-same information as @option{-fdump-rtl-sched1} and @option{-fdump-rtl-sched2}.
-For @var{n} greater than one, it also output basic block probabilities,
-detailed ready list information and unit/insn info. For @var{n} greater
-than two, it includes RTL at abort point, control-flow and regions info.
-And for @var{n} over four, @option{-fsched-verbose} also includes
-dependence info.
-
-@item -save-temps
-@itemx -save-temps=cwd
-@opindex save-temps
-Store the usual ``temporary'' intermediate files permanently; place them
-in the current directory and name them based on the source file. Thus,
-compiling @file{foo.c} with @option{-c -save-temps} produces files
-@file{foo.i} and @file{foo.s}, as well as @file{foo.o}. This creates a
-preprocessed @file{foo.i} output file even though the compiler now
-normally uses an integrated preprocessor.
-
-When used in combination with the @option{-x} command-line option,
-@option{-save-temps} is sensible enough to avoid over writing an
-input source file with the same extension as an intermediate file.
-The corresponding intermediate file may be obtained by renaming the
-source file before using @option{-save-temps}.
-
-If you invoke GCC in parallel, compiling several different source
-files that share a common base name in different subdirectories or the
-same source file compiled for multiple output destinations, it is
-likely that the different parallel compilers will interfere with each
-other, and overwrite the temporary files. For instance:
-
-@smallexample
-gcc -save-temps -o outdir1/foo.o indir1/foo.c&
-gcc -save-temps -o outdir2/foo.o indir2/foo.c&
-@end smallexample
-
-may result in @file{foo.i} and @file{foo.o} being written to
-simultaneously by both compilers.
-
-@item -save-temps=obj
-@opindex save-temps=obj
-Store the usual ``temporary'' intermediate files permanently. If the
-@option{-o} option is used, the temporary files are based on the
-object file. If the @option{-o} option is not used, the
-@option{-save-temps=obj} switch behaves like @option{-save-temps}.
-
-For example:
-
-@smallexample
-gcc -save-temps=obj -c foo.c
-gcc -save-temps=obj -c bar.c -o dir/xbar.o
-gcc -save-temps=obj foobar.c -o dir2/yfoobar
-@end smallexample
-
-@noindent
-creates @file{foo.i}, @file{foo.s}, @file{dir/xbar.i},
-@file{dir/xbar.s}, @file{dir2/yfoobar.i}, @file{dir2/yfoobar.s}, and
-@file{dir2/yfoobar.o}.
-
-@item -time@r{[}=@var{file}@r{]}
-@opindex time
-Report the CPU time taken by each subprocess in the compilation
-sequence. For C source files, this is the compiler proper and assembler
-(plus the linker if linking is done).
-
-Without the specification of an output file, the output looks like this:
-
-@smallexample
-# cc1 0.12 0.01
-# as 0.00 0.01
-@end smallexample
-
-The first number on each line is the ``user time'', that is time spent
-executing the program itself. The second number is ``system time'',
-time spent executing operating system routines on behalf of the program.
-Both numbers are in seconds.
-
-With the specification of an output file, the output is appended to the
-named file, and it looks like this:
-
-@smallexample
-0.12 0.01 cc1 @var{options}
-0.00 0.01 as @var{options}
-@end smallexample
-
-The ``user time'' and the ``system time'' are moved before the program
-name, and the options passed to the program are displayed, so that one
-can later tell what file was being compiled, and with which options.
-
-@item -fvar-tracking
-@opindex fvar-tracking
-Run variable tracking pass. It computes where variables are stored at each
-position in code. Better debugging information is then generated
-(if the debugging information format supports this information).
-
-It is enabled by default when compiling with optimization (@option{-Os},
-@option{-O}, @option{-O2}, @dots{}), debugging information (@option{-g}) and
-the debug info format supports it.
-
-@item -fvar-tracking-assignments
-@opindex fvar-tracking-assignments
-@opindex fno-var-tracking-assignments
-Annotate assignments to user variables early in the compilation and
-attempt to carry the annotations over throughout the compilation all the
-way to the end, in an attempt to improve debug information while
-optimizing. Use of @option{-gdwarf-4} is recommended along with it.
-
-It can be enabled even if var-tracking is disabled, in which case
-annotations are created and maintained, but discarded at the end.
-
-@item -fvar-tracking-assignments-toggle
-@opindex fvar-tracking-assignments-toggle
-@opindex fno-var-tracking-assignments-toggle
-Toggle @option{-fvar-tracking-assignments}, in the same way that
-@option{-gtoggle} toggles @option{-g}.
-
-@item -print-file-name=@var{library}
-@opindex print-file-name
-Print the full absolute name of the library file @var{library} that
-would be used when linking---and don't do anything else. With this
-option, GCC does not compile or link anything; it just prints the
-file name.
-
-@item -print-multi-directory
-@opindex print-multi-directory
-Print the directory name corresponding to the multilib selected by any
-other switches present in the command line. This directory is supposed
-to exist in @env{GCC_EXEC_PREFIX}.
-
-@item -print-multi-lib
-@opindex print-multi-lib
-Print the mapping from multilib directory names to compiler switches
-that enable them. The directory name is separated from the switches by
-@samp{;}, and each switch starts with an @samp{@@} instead of the
-@samp{-}, without spaces between multiple switches. This is supposed to
-ease shell processing.
-
-@item -print-multi-os-directory
-@opindex print-multi-os-directory
-Print the path to OS libraries for the selected
-multilib, relative to some @file{lib} subdirectory. If OS libraries are
-present in the @file{lib} subdirectory and no multilibs are used, this is
-usually just @file{.}, if OS libraries are present in @file{lib@var{suffix}}
-sibling directories this prints e.g.@: @file{../lib64}, @file{../lib} or
-@file{../lib32}, or if OS libraries are present in @file{lib/@var{subdir}}
-subdirectories it prints e.g.@: @file{amd64}, @file{sparcv9} or @file{ev6}.
-
-@item -print-multiarch
-@opindex print-multiarch
-Print the path to OS libraries for the selected multiarch,
-relative to some @file{lib} subdirectory.
-
-@item -print-prog-name=@var{program}
-@opindex print-prog-name
-Like @option{-print-file-name}, but searches for a program such as @samp{cpp}.
-
-@item -print-libgcc-file-name
-@opindex print-libgcc-file-name
-Same as @option{-print-file-name=libgcc.a}.
-
-This is useful when you use @option{-nostdlib} or @option{-nodefaultlibs}
-but you do want to link with @file{libgcc.a}. You can do:
-
-@smallexample
-gcc -nostdlib @var{files}@dots{} `gcc -print-libgcc-file-name`
-@end smallexample
-
-@item -print-search-dirs
-@opindex print-search-dirs
-Print the name of the configured installation directory and a list of
-program and library directories @command{gcc} searches---and don't do anything else.
-
-This is useful when @command{gcc} prints the error message
-@samp{installation problem, cannot exec cpp0: No such file or directory}.
-To resolve this you either need to put @file{cpp0} and the other compiler
-components where @command{gcc} expects to find them, or you can set the environment
-variable @env{GCC_EXEC_PREFIX} to the directory where you installed them.
-Don't forget the trailing @samp{/}.
-@xref{Environment Variables}.
-
-@item -print-sysroot
-@opindex print-sysroot
-Print the target sysroot directory that is used during
-compilation. This is the target sysroot specified either at configure
-time or using the @option{--sysroot} option, possibly with an extra
-suffix that depends on compilation options. If no target sysroot is
-specified, the option prints nothing.
-
-@item -print-sysroot-headers-suffix
-@opindex print-sysroot-headers-suffix
-Print the suffix added to the target sysroot when searching for
-headers, or give an error if the compiler is not configured with such
-a suffix---and don't do anything else.
-
-@item -dumpmachine
-@opindex dumpmachine
-Print the compiler's target machine (for example,
-@samp{i686-pc-linux-gnu})---and don't do anything else.
-
-@item -dumpversion
-@opindex dumpversion
-Print the compiler version (for example, @samp{3.0})---and don't do
-anything else.
-
-@item -dumpspecs
-@opindex dumpspecs
-Print the compiler's built-in specs---and don't do anything else. (This
-is used when GCC itself is being built.) @xref{Spec Files}.
-
-@item -fno-eliminate-unused-debug-types
-@opindex feliminate-unused-debug-types
-@opindex fno-eliminate-unused-debug-types
-Normally, when producing DWARF 2 output, GCC avoids producing debug symbol
-output for types that are nowhere used in the source file being compiled.
-Sometimes it is useful to have GCC emit debugging
-information for all types declared in a compilation
-unit, regardless of whether or not they are actually used
-in that compilation unit, for example
-if, in the debugger, you want to cast a value to a type that is
-not actually used in your program (but is declared). More often,
-however, this results in a significant amount of wasted space.
-@end table
-
-@node Optimize Options
-@section Options That Control Optimization
-@cindex optimize options
-@cindex options, optimization
-
-These options control various sorts of optimizations.
-
-Without any optimization option, the compiler's goal is to reduce the
-cost of compilation and to make debugging produce the expected
-results. Statements are independent: if you stop the program with a
-breakpoint between statements, you can then assign a new value to any
-variable or change the program counter to any other statement in the
-function and get exactly the results you expect from the source
-code.
-
-Turning on optimization flags makes the compiler attempt to improve
-the performance and/or code size at the expense of compilation time
-and possibly the ability to debug the program.
-
-The compiler performs optimization based on the knowledge it has of the
-program. Compiling multiple files at once to a single output file mode allows
-the compiler to use information gained from all of the files when compiling
-each of them.
-
-Not all optimizations are controlled directly by a flag. Only
-optimizations that have a flag are listed in this section.
-
-Most optimizations are only enabled if an @option{-O} level is set on
-the command line. Otherwise they are disabled, even if individual
-optimization flags are specified.
-
-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 @option{-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
-@itemx -O1
-@opindex O
-@opindex O1
-Optimize. Optimizing compilation takes somewhat more time, and a lot
-more memory for a large function.
-
-With @option{-O}, the compiler tries to reduce code size and execution
-time, without performing any optimizations that take a great deal of
-compilation time.
-
-@option{-O} turns on the following optimization flags:
-@gccoptlist{
--fauto-inc-dec @gol
--fcompare-elim @gol
--fcprop-registers @gol
--fdce @gol
--fdefer-pop @gol
--fdelayed-branch @gol
--fdse @gol
--fguess-branch-probability @gol
--fif-conversion2 @gol
--fif-conversion @gol
--fipa-pure-const @gol
--fipa-profile @gol
--fipa-reference @gol
--fmerge-constants
--fsplit-wide-types @gol
--ftree-bit-ccp @gol
--ftree-builtin-call-dce @gol
--ftree-ccp @gol
--ftree-ch @gol
--ftree-copyrename @gol
--ftree-dce @gol
--ftree-dominator-opts @gol
--ftree-dse @gol
--ftree-forwprop @gol
--ftree-fre @gol
--ftree-phiprop @gol
--ftree-slsr @gol
--ftree-sra @gol
--ftree-pta @gol
--ftree-ter @gol
--funit-at-a-time}
-
-@option{-O} also turns on @option{-fomit-frame-pointer} on machines
-where doing so does not interfere with debugging.
-
-@item -O2
-@opindex O2
-Optimize even more. GCC performs nearly all supported optimizations
-that do not involve a space-speed tradeoff.
-As compared to @option{-O}, this option increases both compilation time
-and the performance of the generated code.
-
-@option{-O2} turns on all optimization flags specified by @option{-O}. It
-also turns on the following optimization flags:
-@gccoptlist{-fthread-jumps @gol
--falign-functions -falign-jumps @gol
--falign-loops -falign-labels @gol
--fcaller-saves @gol
--fcrossjumping @gol
--fcse-follow-jumps -fcse-skip-blocks @gol
--fdelete-null-pointer-checks @gol
--fdevirtualize @gol
--fexpensive-optimizations @gol
--fgcse -fgcse-lm @gol
--fhoist-adjacent-loads @gol
--finline-small-functions @gol
--findirect-inlining @gol
--fipa-sra @gol
--foptimize-sibling-calls @gol
--fpartial-inlining @gol
--fpeephole2 @gol
--fregmove @gol
--freorder-blocks -freorder-functions @gol
--frerun-cse-after-loop @gol
--fsched-interblock -fsched-spec @gol
--fschedule-insns -fschedule-insns2 @gol
--fstrict-aliasing -fstrict-overflow @gol
--ftree-switch-conversion -ftree-tail-merge @gol
--ftree-pre @gol
--ftree-vrp}
-
-Please note the warning under @option{-fgcse} about
-invoking @option{-O2} on programs that use computed gotos.
-
-@item -O3
-@opindex O3
-Optimize yet more. @option{-O3} turns on all optimizations specified
-by @option{-O2} and also turns on the @option{-finline-functions},
-@option{-funswitch-loops}, @option{-fpredictive-commoning},
-@option{-fgcse-after-reload}, @option{-ftree-vectorize},
-@option{-fvect-cost-model},
-@option{-ftree-partial-pre} and @option{-fipa-cp-clone} options.
-
-@item -O0
-@opindex O0
-Reduce compilation time and make debugging produce the expected
-results. This is the default.
-
-@item -Os
-@opindex Os
-Optimize for size. @option{-Os} enables all @option{-O2} optimizations that
-do not typically increase code size. It also performs further
-optimizations designed to reduce code size.
-
-@option{-Os} disables the following optimization flags:
-@gccoptlist{-falign-functions -falign-jumps -falign-loops @gol
--falign-labels -freorder-blocks -freorder-blocks-and-partition @gol
--fprefetch-loop-arrays -ftree-vect-loop-version}
-
-@item -Ofast
-@opindex Ofast
-Disregard strict standards compliance. @option{-Ofast} enables all
-@option{-O3} optimizations. It also enables optimizations that are not
-valid for all standard-compliant programs.
-It turns on @option{-ffast-math} and the Fortran-specific
-@option{-fno-protect-parens} and @option{-fstack-arrays}.
-
-@item -Og
-@opindex Og
-Optimize debugging experience. @option{-Og} enables optimizations
-that do not interfere with debugging. It should be the optimization
-level of choice for the standard edit-compile-debug cycle, offering
-a reasonable level of optimization while maintaining fast compilation
-and a good debugging experience.
-
-If you use multiple @option{-O} options, with or without level numbers,
-the last such option is the one that is effective.
-@end table
-
-Options of the form @option{-f@var{flag}} specify machine-independent
-flags. Most flags have both positive and negative forms; the negative
-form of @option{-ffoo} is @option{-fno-foo}. In the table
-below, only one of the forms is listed---the one you typically
-use. You can figure out the other form by either removing @samp{no-}
-or adding it.
-
-The following options control specific optimizations. They are either
-activated by @option{-O} options or are related to ones that are. You
-can use the following flags in the rare cases when ``fine-tuning'' of
-optimizations to be performed is desired.
-
-@table @gcctabopt
-@item -fno-default-inline
-@opindex fno-default-inline
-Do not make member functions inline by default merely because they are
-defined inside the class scope (C++ only). Otherwise, when you specify
-@w{@option{-O}}, member functions defined inside class scope are compiled
-inline by default; i.e., you don't need to add @samp{inline} in front of
-the member function name.
-
-@item -fno-defer-pop
-@opindex fno-defer-pop
-Always pop the arguments to each function call as soon as that function
-returns. For machines that must pop arguments after a function call,
-the compiler normally lets arguments accumulate on the stack for several
-function calls and pops them all at once.
-
-Disabled at levels @option{-O}, @option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -fforward-propagate
-@opindex fforward-propagate
-Perform a forward propagation pass on RTL@. The pass tries to combine two
-instructions and checks if the result can be simplified. If loop unrolling
-is active, two passes are performed and the second is scheduled after
-loop unrolling.
-
-This option is enabled by default at optimization levels @option{-O},
-@option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -ffp-contract=@var{style}
-@opindex ffp-contract
-@option{-ffp-contract=off} disables floating-point expression contraction.
-@option{-ffp-contract=fast} enables floating-point expression contraction
-such as forming of fused multiply-add operations if the target has
-native support for them.
-@option{-ffp-contract=on} enables floating-point expression contraction
-if allowed by the language standard. This is currently not implemented
-and treated equal to @option{-ffp-contract=off}.
-
-The default is @option{-ffp-contract=fast}.
-
-@item -fomit-frame-pointer
-@opindex fomit-frame-pointer
-Don't keep the frame pointer in a register for functions that
-don't need one. This avoids the instructions to save, set up and
-restore frame pointers; it also makes an extra register available
-in many functions. @strong{It also makes debugging impossible on
-some machines.}
-
-On some machines, such as the VAX, this flag has no effect, because
-the standard calling sequence automatically handles the frame pointer
-and nothing is saved by pretending it doesn't exist. The
-machine-description macro @code{FRAME_POINTER_REQUIRED} controls
-whether a target machine supports this flag. @xref{Registers,,Register
-Usage, gccint, GNU Compiler Collection (GCC) Internals}.
-
-Starting with GCC version 4.6, the default setting (when not optimizing for
-size) for 32-bit GNU/Linux x86 and 32-bit Darwin x86 targets has been changed to
-@option{-fomit-frame-pointer}. The default can be reverted to
-@option{-fno-omit-frame-pointer} by configuring GCC with the
-@option{--enable-frame-pointer} configure option.
-
-Enabled at levels @option{-O}, @option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -foptimize-sibling-calls
-@opindex foptimize-sibling-calls
-Optimize sibling and tail recursive calls.
-
-Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -fno-inline
-@opindex fno-inline
-Do not expand any functions inline apart from those marked with
-the @code{always_inline} attribute. This is the default when not
-optimizing.
-
-Single functions can be exempted from inlining by marking them
-with the @code{noinline} attribute.
-
-@item -finline-small-functions
-@opindex finline-small-functions
-Integrate functions into their callers when their body is smaller than expected
-function call code (so overall size of program gets smaller). The compiler
-heuristically decides which functions are simple enough to be worth integrating
-in this way. This inlining applies to all functions, even those not declared
-inline.
-
-Enabled at level @option{-O2}.
-
-@item -findirect-inlining
-@opindex findirect-inlining
-Inline also indirect calls that are discovered to be known at compile
-time thanks to previous inlining. This option has any effect only
-when inlining itself is turned on by the @option{-finline-functions}
-or @option{-finline-small-functions} options.
-
-Enabled at level @option{-O2}.
-
-@item -finline-functions
-@opindex finline-functions
-Consider all functions for inlining, even if they are not declared inline.
-The compiler heuristically decides which functions are worth integrating
-in this way.
-
-If all calls to a given function are integrated, and the function is
-declared @code{static}, then the function is normally not output as
-assembler code in its own right.
-
-Enabled at level @option{-O3}.
-
-@item -finline-functions-called-once
-@opindex finline-functions-called-once
-Consider all @code{static} functions called once for inlining into their
-caller even if they are not marked @code{inline}. If a call to a given
-function is integrated, then the function is not output as assembler code
-in its own right.
-
-Enabled at levels @option{-O1}, @option{-O2}, @option{-O3} and @option{-Os}.
-
-@item -fearly-inlining
-@opindex fearly-inlining
-Inline functions marked by @code{always_inline} and functions whose body seems
-smaller than the function call overhead early before doing
-@option{-fprofile-generate} instrumentation and real inlining pass. Doing so
-makes profiling significantly cheaper and usually inlining faster on programs
-having large chains of nested wrapper functions.
-
-Enabled by default.
-
-@item -fipa-sra
-@opindex fipa-sra
-Perform interprocedural scalar replacement of aggregates, removal of
-unused parameters and replacement of parameters passed by reference
-by parameters passed by value.
-
-Enabled at levels @option{-O2}, @option{-O3} and @option{-Os}.
-
-@item -finline-limit=@var{n}
-@opindex finline-limit
-By default, GCC limits the size of functions that can be inlined. This flag
-allows coarse control of this limit. @var{n} is the size of functions that
-can be inlined in number of pseudo instructions.
-
-Inlining is actually controlled by a number of parameters, which may be
-specified individually by using @option{--param @var{name}=@var{value}}.
-The @option{-finline-limit=@var{n}} option sets some of these parameters
-as follows:
-
-@table @gcctabopt
-@item max-inline-insns-single
-is set to @var{n}/2.
-@item max-inline-insns-auto
-is set to @var{n}/2.
-@end table
-
-See below for a documentation of the individual
-parameters controlling inlining and for the defaults of these parameters.
-
-@emph{Note:} there may be no value to @option{-finline-limit} that results
-in default behavior.
-
-@emph{Note:} pseudo instruction represents, in this particular context, an
-abstract measurement of function's size. In no way does it represent a count
-of assembly instructions and as such its exact meaning might change from one
-release to an another.
-
-@item -fno-keep-inline-dllexport
-@opindex -fno-keep-inline-dllexport
-This is a more fine-grained version of @option{-fkeep-inline-functions},
-which applies only to functions that are declared using the @code{dllexport}
-attribute or declspec (@xref{Function Attributes,,Declaring Attributes of
-Functions}.)
-
-@item -fkeep-inline-functions
-@opindex fkeep-inline-functions
-In C, emit @code{static} functions that are declared @code{inline}
-into the object file, even if the function has been inlined into all
-of its callers. This switch does not affect functions using the
-@code{extern inline} extension in GNU C90@. In C++, emit any and all
-inline functions into the object file.
-
-@item -fkeep-static-consts
-@opindex fkeep-static-consts
-Emit variables declared @code{static const} when optimization isn't turned
-on, even if the variables aren't referenced.
-
-GCC enables this option by default. If you want to force the compiler to
-check if a variable is referenced, regardless of whether or not
-optimization is turned on, use the @option{-fno-keep-static-consts} option.
-
-@item -fmerge-constants
-@opindex fmerge-constants
-Attempt to merge identical constants (string constants and floating-point
-constants) across compilation units.
-
-This option is the default for optimized compilation if the assembler and
-linker support it. Use @option{-fno-merge-constants} to inhibit this
-behavior.
-
-Enabled at levels @option{-O}, @option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -fmerge-all-constants
-@opindex fmerge-all-constants
-Attempt to merge identical constants and identical variables.
-
-This option implies @option{-fmerge-constants}. In addition to
-@option{-fmerge-constants} this considers e.g.@: even constant initialized
-arrays or initialized constant variables with integral or floating-point
-types. Languages like C or C++ require each variable, including multiple
-instances of the same variable in recursive calls, to have distinct locations,
-so using this option results in non-conforming
-behavior.
-
-@item -fmodulo-sched
-@opindex fmodulo-sched
-Perform swing modulo scheduling immediately before the first scheduling
-pass. This pass looks at innermost loops and reorders their
-instructions by overlapping different iterations.
-
-@item -fmodulo-sched-allow-regmoves
-@opindex fmodulo-sched-allow-regmoves
-Perform more aggressive SMS-based modulo scheduling with register moves
-allowed. By setting this flag certain anti-dependences edges are
-deleted, which triggers the generation of reg-moves based on the
-life-range analysis. This option is effective only with
-@option{-fmodulo-sched} enabled.
-
-@item -fno-branch-count-reg
-@opindex fno-branch-count-reg
-Do not use ``decrement and branch'' instructions on a count register,
-but instead generate a sequence of instructions that decrement a
-register, compare it against zero, then branch based upon the result.
-This option is only meaningful on architectures that support such
-instructions, which include x86, PowerPC, IA-64 and S/390.
-
-The default is @option{-fbranch-count-reg}.
-
-@item -fno-function-cse
-@opindex fno-function-cse
-Do not put function addresses in registers; make each instruction that
-calls a constant function contain the function's address explicitly.
-
-This option results in less efficient code, but some strange hacks
-that alter the assembler output may be confused by the optimizations
-performed when this option is not used.
-
-The default is @option{-ffunction-cse}
-
-@item -fno-zero-initialized-in-bss
-@opindex fno-zero-initialized-in-bss
-If the target supports a BSS section, GCC by default puts variables that
-are initialized to zero into BSS@. This can save space in the resulting
-code.
-
-This option turns off this behavior because some programs explicitly
-rely on variables going to the data section---e.g., so that the
-resulting executable can find the beginning of that section and/or make
-assumptions based on that.
-
-The default is @option{-fzero-initialized-in-bss}.
-
-@item -fmudflap -fmudflapth -fmudflapir
-@opindex fmudflap
-@opindex fmudflapth
-@opindex fmudflapir
-@cindex bounds checking
-@cindex mudflap
-For front-ends that support it (C and C++), instrument all risky
-pointer/array dereferencing operations, some standard library
-string/heap functions, and some other associated constructs with
-range/validity tests. Modules so instrumented should be immune to
-buffer overflows, invalid heap use, and some other classes of C/C++
-programming errors. The instrumentation relies on a separate runtime
-library (@file{libmudflap}), which is linked into a program if
-@option{-fmudflap} is given at link time. Run-time behavior of the
-instrumented program is controlled by the @env{MUDFLAP_OPTIONS}
-environment variable. See @code{env MUDFLAP_OPTIONS=-help a.out}
-for its options.
-
-Use @option{-fmudflapth} instead of @option{-fmudflap} to compile and to
-link if your program is multi-threaded. Use @option{-fmudflapir}, in
-addition to @option{-fmudflap} or @option{-fmudflapth}, if
-instrumentation should ignore pointer reads. This produces less
-instrumentation (and therefore faster execution) and still provides
-some protection against outright memory corrupting writes, but allows
-erroneously read data to propagate within a program.
-
-@item -fthread-jumps
-@opindex fthread-jumps
-Perform optimizations that check to see if a jump branches to a
-location where another comparison subsumed by the first is found. If
-so, the first branch is redirected to either the destination of the
-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}.
-
-@item -fsplit-wide-types
-@opindex fsplit-wide-types
-When using a type that occupies multiple registers, such as @code{long
-long} on a 32-bit system, split the registers apart and allocate them
-independently. This normally generates better code for those types,
-but may make debugging more difficult.
-
-Enabled at levels @option{-O}, @option{-O2}, @option{-O3},
-@option{-Os}.
-
-@item -fcse-follow-jumps
-@opindex fcse-follow-jumps
-In common subexpression elimination (CSE), scan through jump instructions
-when the target of the jump is not reached by any other path. For
-example, when CSE encounters an @code{if} statement with an
-@code{else} clause, CSE follows the jump when the condition
-tested is false.
-
-Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -fcse-skip-blocks
-@opindex fcse-skip-blocks
-This is similar to @option{-fcse-follow-jumps}, but causes CSE to
-follow jumps that conditionally skip over blocks. When CSE
-encounters a simple @code{if} statement with no else clause,
-@option{-fcse-skip-blocks} causes CSE to follow the jump around the
-body of the @code{if}.
-
-Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -frerun-cse-after-loop
-@opindex frerun-cse-after-loop
-Re-run common subexpression elimination after loop optimizations are
-performed.
-
-Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -fgcse
-@opindex fgcse
-Perform a global common subexpression elimination pass.
-This pass also performs global constant and copy propagation.
-
-@emph{Note:} When compiling a program using computed gotos, a GCC
-extension, you may get better run-time performance if you disable
-the global common subexpression elimination pass by adding
-@option{-fno-gcse} to the command line.
-
-Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -fgcse-lm
-@opindex fgcse-lm
-When @option{-fgcse-lm} is enabled, global common subexpression elimination
-attempts to move loads that are only killed by stores into themselves. This
-allows a loop containing a load/store sequence to be changed to a load outside
-the loop, and a copy/store within the loop.
-
-Enabled by default when @option{-fgcse} is enabled.
-
-@item -fgcse-sm
-@opindex fgcse-sm
-When @option{-fgcse-sm} is enabled, a store motion pass is run after
-global common subexpression elimination. This pass attempts to move
-stores out of loops. When used in conjunction with @option{-fgcse-lm},
-loops containing a load/store sequence can be changed to a load before
-the loop and a store after the loop.
-
-Not enabled at any optimization level.
-
-@item -fgcse-las
-@opindex fgcse-las
-When @option{-fgcse-las} is enabled, the global common subexpression
-elimination pass eliminates redundant loads that come after stores to the
-same memory location (both partial and full redundancies).
-
-Not enabled at any optimization level.
-
-@item -fgcse-after-reload
-@opindex fgcse-after-reload
-When @option{-fgcse-after-reload} is enabled, a redundant load elimination
-pass is performed after reload. The purpose of this pass is to clean up
-redundant spilling.
-
-@item -faggressive-loop-optimizations
-@opindex faggressive-loop-optimizations
-This option tells the loop optimizer to use language constraints to
-derive bounds for the number of iterations of a loop. This assumes that
-loop code does not invoke undefined behavior by for example causing signed
-integer overflows or out-of-bound array accesses. The bounds for the
-number of iterations of a loop are used to guide loop unrolling and peeling
-and loop exit test optimizations.
-This option is enabled by default.
-
-@item -funsafe-loop-optimizations
-@opindex funsafe-loop-optimizations
-This option tells the loop optimizer to assume that loop indices do not
-overflow, and that loops with nontrivial exit condition are not
-infinite. This enables a wider range of loop optimizations even if
-the loop optimizer itself cannot prove that these assumptions are valid.
-If you use @option{-Wunsafe-loop-optimizations}, the compiler warns you
-if it finds this kind of loop.
-
-@item -fcrossjumping
-@opindex fcrossjumping
-Perform cross-jumping transformation.
-This transformation unifies equivalent code and saves code size. The
-resulting code may or may not perform better than without cross-jumping.
-
-Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -fauto-inc-dec
-@opindex fauto-inc-dec
-Combine increments or decrements of addresses with memory accesses.
-This pass is always skipped on architectures that do not have
-instructions to support this. Enabled by default at @option{-O} and
-higher on architectures that support this.
-
-@item -fdce
-@opindex fdce
-Perform dead code elimination (DCE) on RTL@.
-Enabled by default at @option{-O} and higher.
-
-@item -fdse
-@opindex fdse
-Perform dead store elimination (DSE) on RTL@.
-Enabled by default at @option{-O} and higher.
-
-@item -fif-conversion
-@opindex fif-conversion
-Attempt to transform conditional jumps into branch-less equivalents. This
-includes use of conditional moves, min, max, set flags and abs instructions, and
-some tricks doable by standard arithmetics. The use of conditional execution
-on chips where it is available is controlled by @code{if-conversion2}.
-
-Enabled at levels @option{-O}, @option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -fif-conversion2
-@opindex fif-conversion2
-Use conditional execution (where available) to transform conditional jumps into
-branch-less equivalents.
-
-Enabled at levels @option{-O}, @option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -fdelete-null-pointer-checks
-@opindex fdelete-null-pointer-checks
-Assume that programs cannot safely dereference null pointers, and that
-no code or data element resides there. This enables simple constant
-folding optimizations at all optimization levels. In addition, other
-optimization passes in GCC use this flag to control global dataflow
-analyses that eliminate useless checks for null pointers; these assume
-that if a pointer is checked after it has already been dereferenced,
-it cannot be null.
-
-Note however that in some environments this assumption is not true.
-Use @option{-fno-delete-null-pointer-checks} to disable this optimization
-for programs that depend on that behavior.
-
-Some targets, especially embedded ones, disable this option at all levels.
-Otherwise it is enabled at all levels: @option{-O0}, @option{-O1},
-@option{-O2}, @option{-O3}, @option{-Os}. Passes that use the information
-are enabled independently at different optimization levels.
-
-@item -fdevirtualize
-@opindex fdevirtualize
-Attempt to convert calls to virtual functions to direct calls. This
-is done both within a procedure and interprocedurally as part of
-indirect inlining (@code{-findirect-inlining}) and interprocedural constant
-propagation (@option{-fipa-cp}).
-Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -fexpensive-optimizations
-@opindex fexpensive-optimizations
-Perform a number of minor optimizations that are relatively expensive.
-
-Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -free
-@opindex free
-Attempt to remove redundant extension instructions. This is especially
-helpful for the x86-64 architecture, which implicitly zero-extends in 64-bit
-registers after writing to their lower 32-bit half.
-
-Enabled for x86 at levels @option{-O2}, @option{-O3}.
-
-@item -foptimize-register-move
-@itemx -fregmove
-@opindex foptimize-register-move
-@opindex fregmove
-Attempt to reassign register numbers in move instructions and as
-operands of other simple instructions in order to maximize the amount of
-register tying. This is especially helpful on machines with two-operand
-instructions.
-
-Note @option{-fregmove} and @option{-foptimize-register-move} are the same
-optimization.
-
-Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -fira-algorithm=@var{algorithm}
-Use the specified coloring algorithm for the integrated register
-allocator. The @var{algorithm} argument can be @samp{priority}, which
-specifies Chow's priority coloring, or @samp{CB}, which specifies
-Chaitin-Briggs coloring. Chaitin-Briggs coloring is not implemented
-for all architectures, but for those targets that do support it, it is
-the default because it generates better code.
-
-@item -fira-region=@var{region}
-Use specified regions for the integrated register allocator. The
-@var{region} argument should be one of the following:
-
-@table @samp
-
-@item all
-Use all loops as register allocation regions.
-This can give the best results for machines with a small and/or
-irregular register set.
-
-@item mixed
-Use all loops except for loops with small register pressure
-as the regions. This value usually gives
-the best results in most cases and for most architectures,
-and is enabled by default when compiling with optimization for speed
-(@option{-O}, @option{-O2}, @dots{}).
-
-@item one
-Use all functions as a single region.
-This typically results in the smallest code size, and is enabled by default for
-@option{-Os} or @option{-O0}.
-
-@end table
-
-@item -fira-hoist-pressure
-@opindex fira-hoist-pressure
-Use IRA to evaluate register pressure in the code hoisting pass for
-decisions to hoist expressions. This option usually results in smaller
-code, but it can slow the compiler down.
-
-This option is enabled at level @option{-Os} for all targets.
-
-@item -fira-loop-pressure
-@opindex fira-loop-pressure
-Use IRA to evaluate register pressure in loops for decisions to move
-loop invariants. This option usually results in generation
-of faster and smaller code on machines with large register files (>= 32
-registers), but it can slow the compiler down.
-
-This option is enabled at level @option{-O3} for some targets.
-
-@item -fno-ira-share-save-slots
-@opindex fno-ira-share-save-slots
-Disable sharing of stack slots used for saving call-used hard
-registers living through a call. Each hard register gets a
-separate stack slot, and as a result function stack frames are
-larger.
-
-@item -fno-ira-share-spill-slots
-@opindex fno-ira-share-spill-slots
-Disable sharing of stack slots allocated for pseudo-registers. Each
-pseudo-register that does not get a hard register gets a separate
-stack slot, and as a result function stack frames are larger.
-
-@item -fira-verbose=@var{n}
-@opindex fira-verbose
-Control the verbosity of the dump file for the integrated register allocator.
-The default value is 5. If the value @var{n} is greater or equal to 10,
-the dump output is sent to stderr using the same format as @var{n} minus 10.
-
-@item -fdelayed-branch
-@opindex fdelayed-branch
-If supported for the target machine, attempt to reorder instructions
-to exploit instruction slots available after delayed branch
-instructions.
-
-Enabled at levels @option{-O}, @option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -fschedule-insns
-@opindex fschedule-insns
-If supported for the target machine, attempt to reorder instructions to
-eliminate execution stalls due to required data being unavailable. This
-helps machines that have slow floating point or memory load instructions
-by allowing other instructions to be issued until the result of the load
-or floating-point instruction is required.
-
-Enabled at levels @option{-O2}, @option{-O3}.
-
-@item -fschedule-insns2
-@opindex fschedule-insns2
-Similar to @option{-fschedule-insns}, but requests an additional pass of
-instruction scheduling after register allocation has been done. This is
-especially useful on machines with a relatively small number of
-registers and where memory load instructions take more than one cycle.
-
-Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -fno-sched-interblock
-@opindex fno-sched-interblock
-Don't schedule instructions across basic blocks. This is normally
-enabled by default when scheduling before register allocation, i.e.@:
-with @option{-fschedule-insns} or at @option{-O2} or higher.
-
-@item -fno-sched-spec
-@opindex fno-sched-spec
-Don't allow speculative motion of non-load instructions. This is normally
-enabled by default when scheduling before register allocation, i.e.@:
-with @option{-fschedule-insns} or at @option{-O2} or higher.
-
-@item -fsched-pressure
-@opindex fsched-pressure
-Enable register pressure sensitive insn scheduling before register
-allocation. This only makes sense when scheduling before register
-allocation is enabled, i.e.@: with @option{-fschedule-insns} or at
-@option{-O2} or higher. Usage of this option can improve the
-generated code and decrease its size by preventing register pressure
-increase above the number of available hard registers and subsequent
-spills in register allocation.
-
-@item -fsched-spec-load
-@opindex fsched-spec-load
-Allow speculative motion of some load instructions. This only makes
-sense when scheduling before register allocation, i.e.@: with
-@option{-fschedule-insns} or at @option{-O2} or higher.
-
-@item -fsched-spec-load-dangerous
-@opindex fsched-spec-load-dangerous
-Allow speculative motion of more load instructions. This only makes
-sense when scheduling before register allocation, i.e.@: with
-@option{-fschedule-insns} or at @option{-O2} or higher.
-
-@item -fsched-stalled-insns
-@itemx -fsched-stalled-insns=@var{n}
-@opindex fsched-stalled-insns
-Define how many insns (if any) can be moved prematurely from the queue
-of stalled insns into the ready list during the second scheduling pass.
-@option{-fno-sched-stalled-insns} means that no insns are moved
-prematurely, @option{-fsched-stalled-insns=0} means there is no limit
-on how many queued insns can be moved prematurely.
-@option{-fsched-stalled-insns} without a value is equivalent to
-@option{-fsched-stalled-insns=1}.
-
-@item -fsched-stalled-insns-dep
-@itemx -fsched-stalled-insns-dep=@var{n}
-@opindex fsched-stalled-insns-dep
-Define how many insn groups (cycles) are examined for a dependency
-on a stalled insn that is a candidate for premature removal from the queue
-of stalled insns. This has an effect only during the second scheduling pass,
-and only if @option{-fsched-stalled-insns} is used.
-@option{-fno-sched-stalled-insns-dep} is equivalent to
-@option{-fsched-stalled-insns-dep=0}.
-@option{-fsched-stalled-insns-dep} without a value is equivalent to
-@option{-fsched-stalled-insns-dep=1}.
-
-@item -fsched2-use-superblocks
-@opindex fsched2-use-superblocks
-When scheduling after register allocation, use superblock scheduling.
-This allows motion across basic block boundaries,
-resulting in faster schedules. This option is experimental, as not all machine
-descriptions used by GCC model the CPU closely enough to avoid unreliable
-results from the algorithm.
-
-This only makes sense when scheduling after register allocation, i.e.@: with
-@option{-fschedule-insns2} or at @option{-O2} or higher.
-
-@item -fsched-group-heuristic
-@opindex fsched-group-heuristic
-Enable the group heuristic in the scheduler. This heuristic favors
-the instruction that belongs to a schedule group. This is enabled
-by default when scheduling is enabled, i.e.@: with @option{-fschedule-insns}
-or @option{-fschedule-insns2} or at @option{-O2} or higher.
-
-@item -fsched-critical-path-heuristic
-@opindex fsched-critical-path-heuristic
-Enable the critical-path heuristic in the scheduler. This heuristic favors
-instructions on the critical path. This is enabled by default when
-scheduling is enabled, i.e.@: with @option{-fschedule-insns}
-or @option{-fschedule-insns2} or at @option{-O2} or higher.
-
-@item -fsched-spec-insn-heuristic
-@opindex fsched-spec-insn-heuristic
-Enable the speculative instruction heuristic in the scheduler. This
-heuristic favors speculative instructions with greater dependency weakness.
-This is enabled by default when scheduling is enabled, i.e.@:
-with @option{-fschedule-insns} or @option{-fschedule-insns2}
-or at @option{-O2} or higher.
-
-@item -fsched-rank-heuristic
-@opindex fsched-rank-heuristic
-Enable the rank heuristic in the scheduler. This heuristic favors
-the instruction belonging to a basic block with greater size or frequency.
-This is enabled by default when scheduling is enabled, i.e.@:
-with @option{-fschedule-insns} or @option{-fschedule-insns2} or
-at @option{-O2} or higher.
-
-@item -fsched-last-insn-heuristic
-@opindex fsched-last-insn-heuristic
-Enable the last-instruction heuristic in the scheduler. This heuristic
-favors the instruction that is less dependent on the last instruction
-scheduled. This is enabled by default when scheduling is enabled,
-i.e.@: with @option{-fschedule-insns} or @option{-fschedule-insns2} or
-at @option{-O2} or higher.
-
-@item -fsched-dep-count-heuristic
-@opindex fsched-dep-count-heuristic
-Enable the dependent-count heuristic in the scheduler. This heuristic
-favors the instruction that has more instructions depending on it.
-This is enabled by default when scheduling is enabled, i.e.@:
-with @option{-fschedule-insns} or @option{-fschedule-insns2} or
-at @option{-O2} or higher.
-
-@item -freschedule-modulo-scheduled-loops
-@opindex freschedule-modulo-scheduled-loops
-Modulo scheduling is performed before traditional scheduling. If a loop
-is modulo scheduled, later scheduling passes may change its schedule.
-Use this option to control that behavior.
-
-@item -fselective-scheduling
-@opindex fselective-scheduling
-Schedule instructions using selective scheduling algorithm. Selective
-scheduling runs instead of the first scheduler pass.
-
-@item -fselective-scheduling2
-@opindex fselective-scheduling2
-Schedule instructions using selective scheduling algorithm. Selective
-scheduling runs instead of the second scheduler pass.
-
-@item -fsel-sched-pipelining
-@opindex fsel-sched-pipelining
-Enable software pipelining of innermost loops during selective scheduling.
-This option has no effect unless one of @option{-fselective-scheduling} or
-@option{-fselective-scheduling2} is turned on.
-
-@item -fsel-sched-pipelining-outer-loops
-@opindex fsel-sched-pipelining-outer-loops
-When pipelining loops during selective scheduling, also pipeline outer loops.
-This option has no effect unless @option{-fsel-sched-pipelining} is turned on.
-
-@item -fshrink-wrap
-@opindex fshrink-wrap
-Emit function prologues only before parts of the function that need it,
-rather than at the top of the function. This flag is enabled by default at
-@option{-O} and higher.
-
-@item -fcaller-saves
-@opindex fcaller-saves
-Enable allocation of values to registers that are clobbered by
-function calls, by emitting extra instructions to save and restore the
-registers around such calls. Such allocation is done only when it
-seems to result in better code.
-
-This option is always enabled by default on certain machines, usually
-those which have no call-preserved registers to use instead.
-
-Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -fcombine-stack-adjustments
-@opindex fcombine-stack-adjustments
-Tracks stack adjustments (pushes and pops) and stack memory references
-and then tries to find ways to combine them.
-
-Enabled by default at @option{-O1} and higher.
-
-@item -fconserve-stack
-@opindex fconserve-stack
-Attempt to minimize stack usage. The compiler attempts to use less
-stack space, even if that makes the program slower. This option
-implies setting the @option{large-stack-frame} parameter to 100
-and the @option{large-stack-frame-growth} parameter to 400.
-
-@item -ftree-reassoc
-@opindex ftree-reassoc
-Perform reassociation on trees. This flag is enabled by default
-at @option{-O} and higher.
-
-@item -ftree-pre
-@opindex ftree-pre
-Perform partial redundancy elimination (PRE) on trees. This flag is
-enabled by default at @option{-O2} and @option{-O3}.
-
-@item -ftree-partial-pre
-@opindex ftree-partial-pre
-Make partial redundancy elimination (PRE) more aggressive. This flag is
-enabled by default at @option{-O3}.
-
-@item -ftree-forwprop
-@opindex ftree-forwprop
-Perform forward propagation on trees. This flag is enabled by default
-at @option{-O} and higher.
-
-@item -ftree-fre
-@opindex ftree-fre
-Perform full redundancy elimination (FRE) on trees. The difference
-between FRE and PRE is that FRE only considers expressions
-that are computed on all paths leading to the redundant computation.
-This analysis is faster than PRE, though it exposes fewer redundancies.
-This flag is enabled by default at @option{-O} and higher.
-
-@item -ftree-phiprop
-@opindex ftree-phiprop
-Perform hoisting of loads from conditional pointers on trees. This
-pass is enabled by default at @option{-O} and higher.
-
-@item -fhoist-adjacent-loads
-@opindex hoist-adjacent-loads
-Speculatively hoist loads from both branches of an if-then-else if the
-loads are from adjacent locations in the same structure and the target
-architecture has a conditional move instruction. This flag is enabled
-by default at @option{-O2} and higher.
-
-@item -ftree-copy-prop
-@opindex ftree-copy-prop
-Perform copy propagation on trees. This pass eliminates unnecessary
-copy operations. This flag is enabled by default at @option{-O} and
-higher.
-
-@item -fipa-pure-const
-@opindex fipa-pure-const
-Discover which functions are pure or constant.
-Enabled by default at @option{-O} and higher.
-
-@item -fipa-reference
-@opindex fipa-reference
-Discover which static variables do not escape the
-compilation unit.
-Enabled by default at @option{-O} and higher.
-
-@item -fipa-pta
-@opindex fipa-pta
-Perform interprocedural pointer analysis and interprocedural modification
-and reference analysis. This option can cause excessive memory and
-compile-time usage on large compilation units. It is not enabled by
-default at any optimization level.
-
-@item -fipa-profile
-@opindex fipa-profile
-Perform interprocedural profile propagation. The functions called only from
-cold functions are marked as cold. Also functions executed once (such as
-@code{cold}, @code{noreturn}, static constructors or destructors) are identified. Cold
-functions and loop less parts of functions executed once are then optimized for
-size.
-Enabled by default at @option{-O} and higher.
-
-@item -fipa-cp
-@opindex fipa-cp
-Perform interprocedural constant propagation.
-This optimization analyzes the program to determine when values passed
-to functions are constants and then optimizes accordingly.
-This optimization can substantially increase performance
-if the application has constants passed to functions.
-This flag is enabled by default at @option{-O2}, @option{-Os} and @option{-O3}.
-
-@item -fipa-cp-clone
-@opindex fipa-cp-clone
-Perform function cloning to make interprocedural constant propagation stronger.
-When enabled, interprocedural constant propagation performs function cloning
-when externally visible function can be called with constant arguments.
-Because this optimization can create multiple copies of functions,
-it may significantly increase code size
-(see @option{--param ipcp-unit-growth=@var{value}}).
-This flag is enabled by default at @option{-O3}.
-
-@item -ftree-sink
-@opindex ftree-sink
-Perform forward store motion on trees. This flag is
-enabled by default at @option{-O} and higher.
-
-@item -ftree-bit-ccp
-@opindex ftree-bit-ccp
-Perform sparse conditional bit constant propagation on trees and propagate
-pointer alignment information.
-This pass only operates on local scalar variables and is enabled by default
-at @option{-O} and higher. It requires that @option{-ftree-ccp} is enabled.
-
-@item -ftree-ccp
-@opindex ftree-ccp
-Perform sparse conditional constant propagation (CCP) on trees. This
-pass only operates on local scalar variables and is enabled by default
-at @option{-O} and higher.
-
-@item -ftree-switch-conversion
-Perform conversion of simple initializations in a switch to
-initializations from a scalar array. This flag is enabled by default
-at @option{-O2} and higher.
-
-@item -ftree-tail-merge
-Look for identical code sequences. When found, replace one with a jump to the
-other. This optimization is known as tail merging or cross jumping. This flag
-is enabled by default at @option{-O2} and higher. The compilation time
-in this pass can
-be limited using @option{max-tail-merge-comparisons} parameter and
-@option{max-tail-merge-iterations} parameter.
-
-@item -ftree-dce
-@opindex ftree-dce
-Perform dead code elimination (DCE) on trees. This flag is enabled by
-default at @option{-O} and higher.
-
-@item -ftree-builtin-call-dce
-@opindex ftree-builtin-call-dce
-Perform conditional dead code elimination (DCE) for calls to built-in functions
-that may set @code{errno} but are otherwise side-effect free. This flag is
-enabled by default at @option{-O2} and higher if @option{-Os} is not also
-specified.
-
-@item -ftree-dominator-opts
-@opindex ftree-dominator-opts
-Perform a variety of simple scalar cleanups (constant/copy
-propagation, redundancy elimination, range propagation and expression
-simplification) based on a dominator tree traversal. This also
-performs jump threading (to reduce jumps to jumps). This flag is
-enabled by default at @option{-O} and higher.
-
-@item -ftree-dse
-@opindex ftree-dse
-Perform dead store elimination (DSE) on trees. A dead store is a store into
-a memory location that is later overwritten by another store without
-any intervening loads. In this case the earlier store can be deleted. This
-flag is enabled by default at @option{-O} and higher.
-
-@item -ftree-ch
-@opindex ftree-ch
-Perform loop header copying on trees. This is beneficial since it increases
-effectiveness of code motion optimizations. It also saves one jump. This flag
-is enabled by default at @option{-O} and higher. It is not enabled
-for @option{-Os}, since it usually increases code size.
-
-@item -ftree-loop-optimize
-@opindex ftree-loop-optimize
-Perform loop optimizations on trees. This flag is enabled by default
-at @option{-O} and higher.
-
-@item -ftree-loop-linear
-@opindex ftree-loop-linear
-Perform loop interchange transformations on tree. Same as
-@option{-floop-interchange}. To use this code transformation, GCC has
-to be configured with @option{--with-ppl} and @option{--with-cloog} to
-enable the Graphite loop transformation infrastructure.
-
-@item -floop-interchange
-@opindex floop-interchange
-Perform loop interchange transformations on loops. Interchanging two
-nested loops switches the inner and outer loops. For example, given a
-loop like:
-@smallexample
-DO J = 1, M
- DO I = 1, N
- A(J, I) = A(J, I) * C
- ENDDO
-ENDDO
-@end smallexample
-loop interchange transforms the loop as if it were written:
-@smallexample
-DO I = 1, N
- DO J = 1, M
- A(J, I) = A(J, I) * C
- ENDDO
-ENDDO
-@end smallexample
-which can be beneficial when @code{N} is larger than the caches,
-because in Fortran, the elements of an array are stored in memory
-contiguously by column, and the original loop iterates over rows,
-potentially creating at each access a cache miss. This optimization
-applies to all the languages supported by GCC and is not limited to
-Fortran. To use this code transformation, GCC has to be configured
-with @option{--with-ppl} and @option{--with-cloog} to enable the
-Graphite loop transformation infrastructure.
-
-@item -floop-strip-mine
-@opindex floop-strip-mine
-Perform loop strip mining transformations on loops. Strip mining
-splits a loop into two nested loops. The outer loop has strides
-equal to the strip size and the inner loop has strides of the
-original loop within a strip. The strip length can be changed
-using the @option{loop-block-tile-size} parameter. For example,
-given a loop like:
-@smallexample
-DO I = 1, N
- A(I) = A(I) + C
-ENDDO
-@end smallexample
-loop strip mining transforms the loop as if it were written:
-@smallexample
-DO II = 1, N, 51
- DO I = II, min (II + 50, N)
- A(I) = A(I) + C
- ENDDO
-ENDDO
-@end smallexample
-This optimization applies to all the languages supported by GCC and is
-not limited to Fortran. To use this code transformation, GCC has to
-be configured with @option{--with-ppl} and @option{--with-cloog} to
-enable the Graphite loop transformation infrastructure.
-
-@item -floop-block
-@opindex floop-block
-Perform loop blocking transformations on loops. Blocking strip mines
-each loop in the loop nest such that the memory accesses of the
-element loops fit inside caches. The strip length can be changed
-using the @option{loop-block-tile-size} parameter. For example, given
-a loop like:
-@smallexample
-DO I = 1, N
- DO J = 1, M
- A(J, I) = B(I) + C(J)
- ENDDO
-ENDDO
-@end smallexample
-loop blocking transforms the loop as if it were written:
-@smallexample
-DO II = 1, N, 51
- DO JJ = 1, M, 51
- DO I = II, min (II + 50, N)
- DO J = JJ, min (JJ + 50, M)
- A(J, I) = B(I) + C(J)
- ENDDO
- ENDDO
- ENDDO
-ENDDO
-@end smallexample
-which can be beneficial when @code{M} is larger than the caches,
-because the innermost loop iterates over a smaller amount of data
-which can be kept in the caches. This optimization applies to all the
-languages supported by GCC and is not limited to Fortran. To use this
-code transformation, GCC has to be configured with @option{--with-ppl}
-and @option{--with-cloog} to enable the Graphite loop transformation
-infrastructure.
-
-@item -fgraphite-identity
-@opindex fgraphite-identity
-Enable the identity transformation for graphite. For every SCoP we generate
-the polyhedral representation and transform it back to gimple. Using
-@option{-fgraphite-identity} we can check the costs or benefits of the
-GIMPLE -> GRAPHITE -> GIMPLE transformation. Some minimal optimizations
-are also performed by the code generator CLooG, like index splitting and
-dead code elimination in loops.
-
-@item -floop-nest-optimize
-@opindex floop-nest-optimize
-Enable the ISL based loop nest optimizer. This is a generic loop nest
-optimizer based on the Pluto optimization algorithms. It calculates a loop
-structure optimized for data-locality and parallelism. This option
-is experimental.
-
-@item -floop-parallelize-all
-@opindex floop-parallelize-all
-Use the Graphite data dependence analysis to identify loops that can
-be parallelized. Parallelize all the loops that can be analyzed to
-not contain loop carried dependences without checking that it is
-profitable to parallelize the loops.
-
-@item -fcheck-data-deps
-@opindex fcheck-data-deps
-Compare the results of several data dependence analyzers. This option
-is used for debugging the data dependence analyzers.
-
-@item -ftree-loop-if-convert
-Attempt to transform conditional jumps in the innermost loops to
-branch-less equivalents. The intent is to remove control-flow from
-the innermost loops in order to improve the ability of the
-vectorization pass to handle these loops. This is enabled by default
-if vectorization is enabled.
-
-@item -ftree-loop-if-convert-stores
-Attempt to also if-convert conditional jumps containing memory writes.
-This transformation can be unsafe for multi-threaded programs as it
-transforms conditional memory writes into unconditional memory writes.
-For example,
-@smallexample
-for (i = 0; i < N; i++)
- if (cond)
- A[i] = expr;
-@end smallexample
-is transformed to
-@smallexample
-for (i = 0; i < N; i++)
- A[i] = cond ? expr : A[i];
-@end smallexample
-potentially producing data races.
-
-@item -ftree-loop-distribution
-Perform loop distribution. This flag can improve cache performance on
-big loop bodies and allow further loop optimizations, like
-parallelization or vectorization, to take place. For example, the loop
-@smallexample
-DO I = 1, N
- A(I) = B(I) + C
- D(I) = E(I) * F
-ENDDO
-@end smallexample
-is transformed to
-@smallexample
-DO I = 1, N
- A(I) = B(I) + C
-ENDDO
-DO I = 1, N
- D(I) = E(I) * F
-ENDDO
-@end smallexample
-
-@item -ftree-loop-distribute-patterns
-Perform loop distribution of patterns that can be code generated with
-calls to a library. This flag is enabled by default at @option{-O3}.
-
-This pass distributes the initialization loops and generates a call to
-memset zero. For example, the loop
-@smallexample
-DO I = 1, N
- A(I) = 0
- B(I) = A(I) + I
-ENDDO
-@end smallexample
-is transformed to
-@smallexample
-DO I = 1, N
- A(I) = 0
-ENDDO
-DO I = 1, N
- B(I) = A(I) + I
-ENDDO
-@end smallexample
-and the initialization loop is transformed into a call to memset zero.
-
-@item -ftree-loop-im
-@opindex ftree-loop-im
-Perform loop invariant motion on trees. This pass moves only invariants that
-are hard to handle at RTL level (function calls, operations that expand to
-nontrivial sequences of insns). With @option{-funswitch-loops} it also moves
-operands of conditions that are invariant out of the loop, so that we can use
-just trivial invariantness analysis in loop unswitching. The pass also includes
-store motion.
-
-@item -ftree-loop-ivcanon
-@opindex ftree-loop-ivcanon
-Create a canonical counter for number of iterations in loops for which
-determining number of iterations requires complicated analysis. Later
-optimizations then may determine the number easily. Useful especially
-in connection with unrolling.
-
-@item -fivopts
-@opindex fivopts
-Perform induction variable optimizations (strength reduction, induction
-variable merging and induction variable elimination) on trees.
-
-@item -ftree-parallelize-loops=n
-@opindex ftree-parallelize-loops
-Parallelize loops, i.e., split their iteration space to run in n threads.
-This is only possible for loops whose iterations are independent
-and can be arbitrarily reordered. The optimization is only
-profitable on multiprocessor machines, for loops that are CPU-intensive,
-rather than constrained e.g.@: by memory bandwidth. This option
-implies @option{-pthread}, and thus is only supported on targets
-that have support for @option{-pthread}.
-
-@item -ftree-pta
-@opindex ftree-pta
-Perform function-local points-to analysis on trees. This flag is
-enabled by default at @option{-O} and higher.
-
-@item -ftree-sra
-@opindex ftree-sra
-Perform scalar replacement of aggregates. This pass replaces structure
-references with scalars to prevent committing structures to memory too
-early. This flag is enabled by default at @option{-O} and higher.
-
-@item -ftree-copyrename
-@opindex ftree-copyrename
-Perform copy renaming on trees. This pass attempts to rename compiler
-temporaries to other variables at copy locations, usually resulting in
-variable names which more closely resemble the original variables. This flag
-is enabled by default at @option{-O} and higher.
-
-@item -ftree-coalesce-inlined-vars
-Tell the copyrename pass (see @option{-ftree-copyrename}) to attempt to
-combine small user-defined variables too, but only if they were inlined
-from other functions. It is a more limited form of
-@option{-ftree-coalesce-vars}. This may harm debug information of such
-inlined variables, but it will keep variables of the inlined-into
-function apart from each other, such that they are more likely to
-contain the expected values in a debugging session. This was the
-default in GCC versions older than 4.7.
-
-@item -ftree-coalesce-vars
-Tell the copyrename pass (see @option{-ftree-copyrename}) to attempt to
-combine small user-defined variables too, instead of just compiler
-temporaries. This may severely limit the ability to debug an optimized
-program compiled with @option{-fno-var-tracking-assignments}. In the
-negated form, this flag prevents SSA coalescing of user variables,
-including inlined ones. This option is enabled by default.
-
-@item -ftree-ter
-@opindex ftree-ter
-Perform temporary expression replacement during the SSA->normal phase. Single
-use/single def temporaries are replaced at their use location with their
-defining expression. This results in non-GIMPLE code, but gives the expanders
-much more complex trees to work on resulting in better RTL generation. This is
-enabled by default at @option{-O} and higher.
-
-@item -ftree-slsr
-@opindex ftree-slsr
-Perform straight-line strength reduction on trees. This recognizes related
-expressions involving multiplications and replaces them by less expensive
-calculations when possible. This is enabled by default at @option{-O} and
-higher.
-
-@item -ftree-vectorize
-@opindex ftree-vectorize
-Perform loop vectorization on trees. This flag is enabled by default at
-@option{-O3}.
-
-@item -ftree-slp-vectorize
-@opindex ftree-slp-vectorize
-Perform basic block vectorization on trees. This flag is enabled by default at
-@option{-O3} and when @option{-ftree-vectorize} is enabled.
-
-@item -ftree-vect-loop-version
-@opindex ftree-vect-loop-version
-Perform loop versioning when doing loop vectorization on trees. When a loop
-appears to be vectorizable except that data alignment or data dependence cannot
-be determined at compile time, then vectorized and non-vectorized versions of
-the loop are generated along with run-time checks for alignment or dependence
-to control which version is executed. This option is enabled by default
-except at level @option{-Os} where it is disabled.
-
-@item -fvect-cost-model
-@opindex fvect-cost-model
-Enable cost model for vectorization. This option is enabled by default at
-@option{-O3}.
-
-@item -ftree-vrp
-@opindex ftree-vrp
-Perform Value Range Propagation on trees. This is similar to the
-constant propagation pass, but instead of values, ranges of values are
-propagated. This allows the optimizers to remove unnecessary range
-checks like array bound checks and null pointer checks. This is
-enabled by default at @option{-O2} and higher. Null pointer check
-elimination is only done if @option{-fdelete-null-pointer-checks} is
-enabled.
-
-@item -ftracer
-@opindex ftracer
-Perform tail duplication to enlarge superblock size. This transformation
-simplifies the control flow of the function allowing other optimizations to do
-a better job.
-
-@item -funroll-loops
-@opindex funroll-loops
-Unroll loops whose number of iterations can be determined at compile
-time or upon entry to the loop. @option{-funroll-loops} implies
-@option{-frerun-cse-after-loop}. This option makes code larger,
-and may or may not make it run faster.
-
-@item -funroll-all-loops
-@opindex funroll-all-loops
-Unroll all loops, even if their number of iterations is uncertain when
-the loop is entered. This usually makes programs run more slowly.
-@option{-funroll-all-loops} implies the same options as
-@option{-funroll-loops},
-
-@item -fsplit-ivs-in-unroller
-@opindex fsplit-ivs-in-unroller
-Enables expression of values of induction variables in later iterations
-of the unrolled loop using the value in the first iteration. This breaks
-long dependency chains, thus improving efficiency of the scheduling passes.
-
-A combination of @option{-fweb} and CSE is often sufficient to obtain the
-same effect. However, that is not reliable in cases where the loop body
-is more complicated than a single basic block. It also does not work at all
-on some architectures due to restrictions in the CSE pass.
-
-This optimization is enabled by default.
-
-@item -fvariable-expansion-in-unroller
-@opindex fvariable-expansion-in-unroller
-With this option, the compiler creates multiple copies of some
-local variables when unrolling a loop, which can result in superior code.
-
-@item -fpartial-inlining
-@opindex fpartial-inlining
-Inline parts of functions. This option has any effect only
-when inlining itself is turned on by the @option{-finline-functions}
-or @option{-finline-small-functions} options.
-
-Enabled at level @option{-O2}.
-
-@item -fpredictive-commoning
-@opindex fpredictive-commoning
-Perform predictive commoning optimization, i.e., reusing computations
-(especially memory loads and stores) performed in previous
-iterations of loops.
-
-This option is enabled at level @option{-O3}.
-
-@item -fprefetch-loop-arrays
-@opindex fprefetch-loop-arrays
-If supported by the target machine, generate instructions to prefetch
-memory to improve the performance of loops that access large arrays.
-
-This option may generate better or worse code; results are highly
-dependent on the structure of loops within the source code.
-
-Disabled at level @option{-Os}.
-
-@item -fno-peephole
-@itemx -fno-peephole2
-@opindex fno-peephole
-@opindex fno-peephole2
-Disable any machine-specific peephole optimizations. The difference
-between @option{-fno-peephole} and @option{-fno-peephole2} is in how they
-are implemented in the compiler; some targets use one, some use the
-other, a few use both.
-
-@option{-fpeephole} is enabled by default.
-@option{-fpeephole2} enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -fno-guess-branch-probability
-@opindex fno-guess-branch-probability
-Do not guess branch probabilities using heuristics.
-
-GCC uses heuristics to guess branch probabilities if they are
-not provided by profiling feedback (@option{-fprofile-arcs}). These
-heuristics are based on the control flow graph. If some branch probabilities
-are specified by @samp{__builtin_expect}, then the heuristics are
-used to guess branch probabilities for the rest of the control flow graph,
-taking the @samp{__builtin_expect} info into account. The interactions
-between the heuristics and @samp{__builtin_expect} can be complex, and in
-some cases, it may be useful to disable the heuristics so that the effects
-of @samp{__builtin_expect} are easier to understand.
-
-The default is @option{-fguess-branch-probability} at levels
-@option{-O}, @option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -freorder-blocks
-@opindex freorder-blocks
-Reorder basic blocks in the compiled function in order to reduce number of
-taken branches and improve code locality.
-
-Enabled at levels @option{-O2}, @option{-O3}.
-
-@item -freorder-blocks-and-partition
-@opindex freorder-blocks-and-partition
-In addition to reordering basic blocks in the compiled function, in order
-to reduce number of taken branches, partitions hot and cold basic blocks
-into separate sections of the assembly and .o files, to improve
-paging and cache locality performance.
-
-This optimization is automatically turned off in the presence of
-exception handling, for linkonce sections, for functions with a user-defined
-section attribute and on any architecture that does not support named
-sections.
-
-@item -freorder-functions
-@opindex freorder-functions
-Reorder functions in the object file in order to
-improve code locality. This is implemented by using special
-subsections @code{.text.hot} for most frequently executed functions and
-@code{.text.unlikely} for unlikely executed functions. Reordering is done by
-the linker so object file format must support named sections and linker must
-place them in a reasonable way.
-
-Also profile feedback must be available to make this option effective. See
-@option{-fprofile-arcs} for details.
-
-Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -fstrict-aliasing
-@opindex fstrict-aliasing
-Allow the compiler to assume the strictest aliasing rules applicable to
-the language being compiled. For C (and C++), this activates
-optimizations based on the type of expressions. In particular, an
-object of one type is assumed never to reside at the same address as an
-object of a different type, unless the types are almost the same. For
-example, an @code{unsigned int} can alias an @code{int}, but not a
-@code{void*} or a @code{double}. A character type may alias any other
-type.
-
-@anchor{Type-punning}Pay special attention to code like this:
-@smallexample
-union a_union @{
- int i;
- double d;
-@};
-
-int f() @{
- union a_union t;
- t.d = 3.0;
- return t.i;
-@}
-@end smallexample
-The practice of reading from a different union member than the one most
-recently written to (called ``type-punning'') is common. Even with
-@option{-fstrict-aliasing}, type-punning is allowed, provided the memory
-is accessed through the union type. So, the code above works as
-expected. @xref{Structures unions enumerations and bit-fields
-implementation}. However, this code might not:
-@smallexample
-int f() @{
- union a_union t;
- int* ip;
- t.d = 3.0;
- ip = &t.i;
- return *ip;
-@}
-@end smallexample
-
-Similarly, access by taking the address, casting the resulting pointer
-and dereferencing the result has undefined behavior, even if the cast
-uses a union type, e.g.:
-@smallexample
-int f() @{
- double d = 3.0;
- return ((union a_union *) &d)->i;
-@}
-@end smallexample
-
-The @option{-fstrict-aliasing} option is enabled at levels
-@option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -fstrict-overflow
-@opindex fstrict-overflow
-Allow the compiler to assume strict signed overflow rules, depending
-on the language being compiled. For C (and C++) this means that
-overflow when doing arithmetic with signed numbers is undefined, which
-means that the compiler may assume that it does not happen. This
-permits various optimizations. For example, the compiler assumes
-that an expression like @code{i + 10 > i} is always true for
-signed @code{i}. This assumption is only valid if signed overflow is
-undefined, as the expression is false if @code{i + 10} overflows when
-using twos complement arithmetic. When this option is in effect any
-attempt to determine whether an operation on signed numbers
-overflows must be written carefully to not actually involve overflow.
-
-This option also allows the compiler to assume strict pointer
-semantics: given a pointer to an object, if adding an offset to that
-pointer does not produce a pointer to the same object, the addition is
-undefined. This permits the compiler to conclude that @code{p + u >
-p} is always true for a pointer @code{p} and unsigned integer
-@code{u}. This assumption is only valid because pointer wraparound is
-undefined, as the expression is false if @code{p + u} overflows using
-twos complement arithmetic.
-
-See also the @option{-fwrapv} option. Using @option{-fwrapv} means
-that integer signed overflow is fully defined: it wraps. When
-@option{-fwrapv} is used, there is no difference between
-@option{-fstrict-overflow} and @option{-fno-strict-overflow} for
-integers. With @option{-fwrapv} certain types of overflow are
-permitted. For example, if the compiler gets an overflow when doing
-arithmetic on constants, the overflowed value can still be used with
-@option{-fwrapv}, but not otherwise.
-
-The @option{-fstrict-overflow} option is enabled at levels
-@option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -falign-functions
-@itemx -falign-functions=@var{n}
-@opindex falign-functions
-Align the start of functions to the next power-of-two greater than
-@var{n}, skipping up to @var{n} bytes. For instance,
-@option{-falign-functions=32} aligns functions to the next 32-byte
-boundary, but @option{-falign-functions=24} aligns to the next
-32-byte boundary only if this can be done by skipping 23 bytes or less.
-
-@option{-fno-align-functions} and @option{-falign-functions=1} are
-equivalent and mean that functions are not aligned.
-
-Some assemblers only support this flag when @var{n} is a power of two;
-in that case, it is rounded up.
-
-If @var{n} is not specified or is zero, use a machine-dependent default.
-
-Enabled at levels @option{-O2}, @option{-O3}.
-
-@item -falign-labels
-@itemx -falign-labels=@var{n}
-@opindex falign-labels
-Align all branch targets to a power-of-two boundary, skipping up to
-@var{n} bytes like @option{-falign-functions}. This option can easily
-make code slower, because it must insert dummy operations for when the
-branch target is reached in the usual flow of the code.
-
-@option{-fno-align-labels} and @option{-falign-labels=1} are
-equivalent and mean that labels are not aligned.
-
-If @option{-falign-loops} or @option{-falign-jumps} are applicable and
-are greater than this value, then their values are used instead.
-
-If @var{n} is not specified or is zero, use a machine-dependent default
-which is very likely to be @samp{1}, meaning no alignment.
-
-Enabled at levels @option{-O2}, @option{-O3}.
-
-@item -falign-loops
-@itemx -falign-loops=@var{n}
-@opindex falign-loops
-Align loops to a power-of-two boundary, skipping up to @var{n} bytes
-like @option{-falign-functions}. If the loops are
-executed many times, this makes up for any execution of the dummy
-operations.
-
-@option{-fno-align-loops} and @option{-falign-loops=1} are
-equivalent and mean that loops are not aligned.
-
-If @var{n} is not specified or is zero, use a machine-dependent default.
-
-Enabled at levels @option{-O2}, @option{-O3}.
-
-@item -falign-jumps
-@itemx -falign-jumps=@var{n}
-@opindex falign-jumps
-Align branch targets to a power-of-two boundary, for branch targets
-where the targets can only be reached by jumping, skipping up to @var{n}
-bytes like @option{-falign-functions}. In this case, no dummy operations
-need be executed.
-
-@option{-fno-align-jumps} and @option{-falign-jumps=1} are
-equivalent and mean that loops are not aligned.
-
-If @var{n} is not specified or is zero, use a machine-dependent default.
-
-Enabled at levels @option{-O2}, @option{-O3}.
-
-@item -funit-at-a-time
-@opindex funit-at-a-time
-This option is left for compatibility reasons. @option{-funit-at-a-time}
-has no effect, while @option{-fno-unit-at-a-time} implies
-@option{-fno-toplevel-reorder} and @option{-fno-section-anchors}.
-
-Enabled by default.
-
-@item -fno-toplevel-reorder
-@opindex fno-toplevel-reorder
-Do not reorder top-level functions, variables, and @code{asm}
-statements. Output them in the same order that they appear in the
-input file. When this option is used, unreferenced static variables
-are not removed. This option is intended to support existing code
-that relies on a particular ordering. For new code, it is better to
-use attributes.
-
-Enabled at level @option{-O0}. When disabled explicitly, it also implies
-@option{-fno-section-anchors}, which is otherwise enabled at @option{-O0} on some
-targets.
-
-@item -fweb
-@opindex fweb
-Constructs webs as commonly used for register allocation purposes and assign
-each web individual pseudo register. This allows the register allocation pass
-to operate on pseudos directly, but also strengthens several other optimization
-passes, such as CSE, loop optimizer and trivial dead code remover. It can,
-however, make debugging impossible, since variables no longer stay in a
-``home register''.
-
-Enabled by default with @option{-funroll-loops}.
-
-@item -fwhole-program
-@opindex fwhole-program
-Assume that the current compilation unit represents the whole program being
-compiled. All public functions and variables with the exception of @code{main}
-and those merged by attribute @code{externally_visible} become static functions
-and in effect are optimized more aggressively by interprocedural optimizers.
-
-This option should not be used in combination with @code{-flto}.
-Instead relying on a linker plugin should provide safer and more precise
-information.
-
-@item -flto[=@var{n}]
-@opindex flto
-This option runs the standard link-time optimizer. When invoked
-with source code, it generates GIMPLE (one of GCC's internal
-representations) and writes it to special ELF sections in the object
-file. When the object files are linked together, all the function
-bodies are read from these ELF sections and instantiated as if they
-had been part of the same translation unit.
-
-To use the link-time optimizer, @option{-flto} needs to be specified at
-compile time and during the final link. For example:
-
-@smallexample
-gcc -c -O2 -flto foo.c
-gcc -c -O2 -flto bar.c
-gcc -o myprog -flto -O2 foo.o bar.o
-@end smallexample
-
-The first two invocations to GCC save a bytecode representation
-of GIMPLE into special ELF sections inside @file{foo.o} and
-@file{bar.o}. The final invocation reads the GIMPLE bytecode from
-@file{foo.o} and @file{bar.o}, merges the two files into a single
-internal image, and compiles the result as usual. Since both
-@file{foo.o} and @file{bar.o} are merged into a single image, this
-causes all the interprocedural analyses and optimizations in GCC to
-work across the two files as if they were a single one. This means,
-for example, that the inliner is able to inline functions in
-@file{bar.o} into functions in @file{foo.o} and vice-versa.
-
-Another (simpler) way to enable link-time optimization is:
-
-@smallexample
-gcc -o myprog -flto -O2 foo.c bar.c
-@end smallexample
-
-The above generates bytecode for @file{foo.c} and @file{bar.c},
-merges them together into a single GIMPLE representation and optimizes
-them as usual to produce @file{myprog}.
-
-The only important thing to keep in mind is that to enable link-time
-optimizations the @option{-flto} flag needs to be passed to both the
-compile and the link commands.
-
-To make whole program optimization effective, it is necessary to make
-certain whole program assumptions. The compiler needs to know
-what functions and variables can be accessed by libraries and runtime
-outside of the link-time optimized unit. When supported by the linker,
-the linker plugin (see @option{-fuse-linker-plugin}) passes information
-to the compiler about used and externally visible symbols. When
-the linker plugin is not available, @option{-fwhole-program} should be
-used to allow the compiler to make these assumptions, which leads
-to more aggressive optimization decisions.
-
-Note that when a file is compiled with @option{-flto}, the generated
-object file is larger than a regular object file because it
-contains GIMPLE bytecodes and the usual final code. This means that
-object files with LTO information can be linked as normal object
-files; if @option{-flto} is not passed to the linker, no
-interprocedural optimizations are applied.
-
-Additionally, the optimization flags used to compile individual files
-are not necessarily related to those used at link time. For instance,
-
-@smallexample
-gcc -c -O0 -flto foo.c
-gcc -c -O0 -flto bar.c
-gcc -o myprog -flto -O3 foo.o bar.o
-@end smallexample
-
-This produces individual object files with unoptimized assembler
-code, but the resulting binary @file{myprog} is optimized at
-@option{-O3}. If, instead, the final binary is generated without
-@option{-flto}, then @file{myprog} is not optimized.
-
-When producing the final binary with @option{-flto}, GCC only
-applies link-time optimizations to those files that contain bytecode.
-Therefore, you can mix and match object files and libraries with
-GIMPLE bytecodes and final object code. GCC automatically selects
-which files to optimize in LTO mode and which files to link without
-further processing.
-
-There are some code generation flags preserved by GCC when
-generating bytecodes, as they need to be used during the final link
-stage. Currently, the following options are saved into the GIMPLE
-bytecode files: @option{-fPIC}, @option{-fcommon} and all the
-@option{-m} target flags.
-
-At link time, these options are read in and reapplied. Note that the
-current implementation makes no attempt to recognize conflicting
-values for these options. If different files have conflicting option
-values (e.g., one file is compiled with @option{-fPIC} and another
-isn't), the compiler simply uses the last value read from the
-bytecode files. It is recommended, then, that you compile all the files
-participating in the same link with the same options.
-
-If LTO encounters objects with C linkage declared with incompatible
-types in separate translation units to be linked together (undefined
-behavior according to ISO C99 6.2.7), a non-fatal diagnostic may be
-issued. The behavior is still undefined at run time.
-
-Another feature of LTO is that it is possible to apply interprocedural
-optimizations on files written in different languages. This requires
-support in the language front end. Currently, the C, C++ and
-Fortran front ends are capable of emitting GIMPLE bytecodes, so
-something like this should work:
-
-@smallexample
-gcc -c -flto foo.c
-g++ -c -flto bar.cc
-gfortran -c -flto baz.f90
-g++ -o myprog -flto -O3 foo.o bar.o baz.o -lgfortran
-@end smallexample
-
-Notice that the final link is done with @command{g++} to get the C++
-runtime libraries and @option{-lgfortran} is added to get the Fortran
-runtime libraries. In general, when mixing languages in LTO mode, you
-should use the same link command options as when mixing languages in a
-regular (non-LTO) compilation; all you need to add is @option{-flto} to
-all the compile and link commands.
-
-If object files containing GIMPLE bytecode are stored in a library archive, say
-@file{libfoo.a}, it is possible to extract and use them in an LTO link if you
-are using a linker with plugin support. To enable this feature, use
-the flag @option{-fuse-linker-plugin} at link time:
-
-@smallexample
-gcc -o myprog -O2 -flto -fuse-linker-plugin a.o b.o -lfoo
-@end smallexample
-
-With the linker plugin enabled, the linker extracts the needed
-GIMPLE files from @file{libfoo.a} and passes them on to the running GCC
-to make them part of the aggregated GIMPLE image to be optimized.
-
-If you are not using a linker with plugin support and/or do not
-enable the linker plugin, then the objects inside @file{libfoo.a}
-are extracted and linked as usual, but they do not participate
-in the LTO optimization process.
-
-Link-time optimizations do not require the presence of the whole program to
-operate. If the program does not require any symbols to be exported, it is
-possible to combine @option{-flto} and @option{-fwhole-program} to allow
-the interprocedural optimizers to use more aggressive assumptions which may
-lead to improved optimization opportunities.
-Use of @option{-fwhole-program} is not needed when linker plugin is
-active (see @option{-fuse-linker-plugin}).
-
-The current implementation of LTO makes no
-attempt to generate bytecode that is portable between different
-types of hosts. The bytecode files are versioned and there is a
-strict version check, so bytecode files generated in one version of
-GCC will not work with an older/newer version of GCC@.
-
-Link-time optimization does not work well with generation of debugging
-information. Combining @option{-flto} with
-@option{-g} is currently experimental and expected to produce wrong
-results.
-
-If you specify the optional @var{n}, the optimization and code
-generation done at link time is executed in parallel using @var{n}
-parallel jobs by utilizing an installed @command{make} program. The
-environment variable @env{MAKE} may be used to override the program
-used. The default value for @var{n} is 1.
-
-You can also specify @option{-flto=jobserver} to use GNU make's
-job server mode to determine the number of parallel jobs. This
-is useful when the Makefile calling GCC is already executing in parallel.
-You must prepend a @samp{+} to the command recipe in the parent Makefile
-for this to work. This option likely only works if @env{MAKE} is
-GNU make.
-
-This option is disabled by default.
-
-@item -flto-partition=@var{alg}
-@opindex flto-partition
-Specify the partitioning algorithm used by the link-time optimizer.
-The value is either @code{1to1} to specify a partitioning mirroring
-the original source files or @code{balanced} to specify partitioning
-into equally sized chunks (whenever possible) or @code{max} to create
-new partition for every symbol where possible. Specifying @code{none}
-as an algorithm disables partitioning and streaming completely.
-The default value is @code{balanced}. While @code{1to1} can be used
-as an workaround for various code ordering issues, the @code{max}
-partitioning is intended for internal testing only.
-
-@item -flto-compression-level=@var{n}
-This option specifies the level of compression used for intermediate
-language written to LTO object files, and is only meaningful in
-conjunction with LTO mode (@option{-flto}). Valid
-values are 0 (no compression) to 9 (maximum compression). Values
-outside this range are clamped to either 0 or 9. If the option is not
-given, a default balanced compression setting is used.
-
-@item -flto-report
-Prints a report with internal details on the workings of the link-time
-optimizer. The contents of this report vary from version to version.
-It is meant to be useful to GCC developers when processing object
-files in LTO mode (via @option{-flto}).
-
-Disabled by default.
-
-@item -fuse-linker-plugin
-Enables the use of a linker plugin during link-time optimization. This
-option relies on plugin support in the linker, which is available in gold
-or in GNU ld 2.21 or newer.
-
-This option enables the extraction of object files with GIMPLE bytecode out
-of library archives. This improves the quality of optimization by exposing
-more code to the link-time optimizer. This information specifies what
-symbols can be accessed externally (by non-LTO object or during dynamic
-linking). Resulting code quality improvements on binaries (and shared
-libraries that use hidden visibility) are similar to @code{-fwhole-program}.
-See @option{-flto} for a description of the effect of this flag and how to
-use it.
-
-This option is enabled by default when LTO support in GCC is enabled
-and GCC was configured for use with
-a linker supporting plugins (GNU ld 2.21 or newer or gold).
-
-@item -ffat-lto-objects
-@opindex ffat-lto-objects
-Fat LTO objects are object files that contain both the intermediate language
-and the object code. This makes them usable for both LTO linking and normal
-linking. This option is effective only when compiling with @option{-flto}
-and is ignored at link time.
-
-@option{-fno-fat-lto-objects} improves compilation time over plain LTO, but
-requires the complete toolchain to be aware of LTO. It requires a linker with
-linker plugin support for basic functionality. Additionally,
-@command{nm}, @command{ar} and @command{ranlib}
-need to support linker plugins to allow a full-featured build environment
-(capable of building static libraries etc). GCC provides the @command{gcc-ar},
-@command{gcc-nm}, @command{gcc-ranlib} wrappers to pass the right options
-to these tools. With non fat LTO makefiles need to be modified to use them.
-
-The default is @option{-ffat-lto-objects} but this default is intended to
-change in future releases when linker plugin enabled environments become more
-common.
-
-@item -fcompare-elim
-@opindex fcompare-elim
-After register allocation and post-register allocation instruction splitting,
-identify arithmetic instructions that compute processor flags similar to a
-comparison operation based on that arithmetic. If possible, eliminate the
-explicit comparison operation.
-
-This pass only applies to certain targets that cannot explicitly represent
-the comparison operation before register allocation is complete.
-
-Enabled at levels @option{-O}, @option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -fuse-ld=bfd
-Use the @command{bfd} linker instead of the default linker.
-
-@item -fuse-ld=gold
-Use the @command{gold} linker instead of the default linker.
-
-@item -fuse-ld=mcld
-Use the @command{mcld} linker instead of the default linker.
-
-@item -fcprop-registers
-@opindex fcprop-registers
-After register allocation and post-register allocation instruction splitting,
-perform a copy-propagation pass to try to reduce scheduling dependencies
-and occasionally eliminate the copy.
-
-Enabled at levels @option{-O}, @option{-O2}, @option{-O3}, @option{-Os}.
-
-@item -fprofile-correction
-@opindex fprofile-correction
-Profiles collected using an instrumented binary for multi-threaded programs may
-be inconsistent due to missed counter updates. When this option is specified,
-GCC uses heuristics to correct or smooth out such inconsistencies. By
-default, GCC emits an error message when an inconsistent profile is detected.
-
-@item -fprofile-dir=@var{path}
-@opindex fprofile-dir
-
-Set the directory to search for the profile data files in to @var{path}.
-This option affects only the profile data generated by
-@option{-fprofile-generate}, @option{-ftest-coverage}, @option{-fprofile-arcs}
-and used by @option{-fprofile-use} and @option{-fbranch-probabilities}
-and its related options. Both absolute and relative paths can be used.
-By default, GCC uses the current directory as @var{path}, thus the
-profile data file appears in the same directory as the object file.
-
-@item -fprofile-generate
-@itemx -fprofile-generate=@var{path}
-@opindex fprofile-generate
-
-Enable options usually used for instrumenting application to produce
-profile useful for later recompilation with profile feedback based
-optimization. You must use @option{-fprofile-generate} both when
-compiling and when linking your program.
-
-The following options are enabled: @code{-fprofile-arcs}, @code{-fprofile-values}, @code{-fvpt}.
-
-If @var{path} is specified, GCC looks at the @var{path} to find
-the profile feedback data files. See @option{-fprofile-dir}.
-
-@item -fprofile-use
-@itemx -fprofile-use=@var{path}
-@opindex fprofile-use
-Enable profile feedback directed optimizations, and optimizations
-generally profitable only with profile feedback available.
-
-The following options are enabled: @code{-fbranch-probabilities}, @code{-fvpt},
-@code{-funroll-loops}, @code{-fpeel-loops}, @code{-ftracer}, @code{-ftree-vectorize},
-@code{ftree-loop-distribute-patterns}
-
-By default, GCC emits an error message if the feedback profiles do not
-match the source code. This error can be turned into a warning by using
-@option{-Wcoverage-mismatch}. Note this may result in poorly optimized
-code.
-
-If @var{path} is specified, GCC looks at the @var{path} to find
-the profile feedback data files. See @option{-fprofile-dir}.
-@end table
-
-The following options control compiler behavior regarding floating-point
-arithmetic. These options trade off between speed and
-correctness. All must be specifically enabled.
-
-@table @gcctabopt
-@item -ffloat-store
-@opindex ffloat-store
-Do not store floating-point variables in registers, and inhibit other
-options that might change whether a floating-point value is taken from a
-register or memory.
-
-@cindex floating-point precision
-This option prevents undesirable excess precision on machines such as
-the 68000 where the floating registers (of the 68881) keep more
-precision than a @code{double} is supposed to have. Similarly for the
-x86 architecture. For most programs, the excess precision does only
-good, but a few programs rely on the precise definition of IEEE floating
-point. Use @option{-ffloat-store} for such programs, after modifying
-them to store all pertinent intermediate computations into variables.
-
-@item -fexcess-precision=@var{style}
-@opindex fexcess-precision
-This option allows further control over excess precision on machines
-where floating-point registers have more precision than the IEEE
-@code{float} and @code{double} types and the processor does not
-support operations rounding to those types. By default,
-@option{-fexcess-precision=fast} is in effect; this means that
-operations are carried out in the precision of the registers and that
-it is unpredictable when rounding to the types specified in the source
-code takes place. When compiling C, if
-@option{-fexcess-precision=standard} is specified then excess
-precision follows the rules specified in ISO C99; in particular,
-both casts and assignments cause values to be rounded to their
-semantic types (whereas @option{-ffloat-store} only affects
-assignments). This option is enabled by default for C if a strict
-conformance option such as @option{-std=c99} is used.
-
-@opindex mfpmath
-@option{-fexcess-precision=standard} is not implemented for languages
-other than C, and has no effect if
-@option{-funsafe-math-optimizations} or @option{-ffast-math} is
-specified. On the x86, it also has no effect if @option{-mfpmath=sse}
-or @option{-mfpmath=sse+387} is specified; in the former case, IEEE
-semantics apply without excess precision, and in the latter, rounding
-is unpredictable.
-
-@item -ffast-math
-@opindex ffast-math
-Sets @option{-fno-math-errno}, @option{-funsafe-math-optimizations},
-@option{-ffinite-math-only}, @option{-fno-rounding-math},
-@option{-fno-signaling-nans} and @option{-fcx-limited-range}.
-
-This option causes the preprocessor macro @code{__FAST_MATH__} to be defined.
-
-This option is not turned on by any @option{-O} option besides
-@option{-Ofast} since it can result in incorrect output for programs
-that depend on an exact implementation of IEEE or ISO rules/specifications
-for math functions. It may, however, yield faster code for programs
-that do not require the guarantees of these specifications.
-
-@item -fno-math-errno
-@opindex fno-math-errno
-Do not set @code{errno} after calling math functions that are executed
-with a single instruction, e.g., @code{sqrt}. A program that relies on
-IEEE exceptions for math error handling may want to use this flag
-for speed while maintaining IEEE arithmetic compatibility.
-
-This option is not turned on by any @option{-O} option since
-it can result in incorrect output for programs that depend on
-an exact implementation of IEEE or ISO rules/specifications for
-math functions. It may, however, yield faster code for programs
-that do not require the guarantees of these specifications.
-
-The default is @option{-fmath-errno}.
-
-On Darwin systems, the math library never sets @code{errno}. There is
-therefore no reason for the compiler to consider the possibility that
-it might, and @option{-fno-math-errno} is the default.
-
-@item -funsafe-math-optimizations
-@opindex funsafe-math-optimizations
-
-Allow optimizations for floating-point arithmetic that (a) assume
-that arguments and results are valid and (b) may violate IEEE or
-ANSI standards. When used at link-time, it may include libraries
-or startup files that change the default FPU control word or other
-similar optimizations.
-
-This option is not turned on by any @option{-O} option since
-it can result in incorrect output for programs that depend on
-an exact implementation of IEEE or ISO rules/specifications for
-math functions. It may, however, yield faster code for programs
-that do not require the guarantees of these specifications.
-Enables @option{-fno-signed-zeros}, @option{-fno-trapping-math},
-@option{-fassociative-math} and @option{-freciprocal-math}.
-
-The default is @option{-fno-unsafe-math-optimizations}.
-
-@item -fassociative-math
-@opindex fassociative-math
-
-Allow re-association of operands in series of floating-point operations.
-This violates the ISO C and C++ language standard by possibly changing
-computation result. NOTE: re-ordering may change the sign of zero as
-well as ignore NaNs and inhibit or create underflow or overflow (and
-thus cannot be used on code that relies on rounding behavior like
-@code{(x + 2**52) - 2**52}. May also reorder floating-point comparisons
-and thus may not be used when ordered comparisons are required.
-This option requires that both @option{-fno-signed-zeros} and
-@option{-fno-trapping-math} be in effect. Moreover, it doesn't make
-much sense with @option{-frounding-math}. For Fortran the option
-is automatically enabled when both @option{-fno-signed-zeros} and
-@option{-fno-trapping-math} are in effect.
-
-The default is @option{-fno-associative-math}.
-
-@item -freciprocal-math
-@opindex freciprocal-math
-
-Allow the reciprocal of a value to be used instead of dividing by
-the value if this enables optimizations. For example @code{x / y}
-can be replaced with @code{x * (1/y)}, which is useful if @code{(1/y)}
-is subject to common subexpression elimination. Note that this loses
-precision and increases the number of flops operating on the value.
-
-The default is @option{-fno-reciprocal-math}.
-
-@item -ffinite-math-only
-@opindex ffinite-math-only
-Allow optimizations for floating-point arithmetic that assume
-that arguments and results are not NaNs or +-Infs.
-
-This option is not turned on by any @option{-O} option since
-it can result in incorrect output for programs that depend on
-an exact implementation of IEEE or ISO rules/specifications for
-math functions. It may, however, yield faster code for programs
-that do not require the guarantees of these specifications.
-
-The default is @option{-fno-finite-math-only}.
-
-@item -fno-signed-zeros
-@opindex fno-signed-zeros
-Allow optimizations for floating-point arithmetic that ignore the
-signedness of zero. IEEE arithmetic specifies the behavior of
-distinct +0.0 and @minus{}0.0 values, which then prohibits simplification
-of expressions such as x+0.0 or 0.0*x (even with @option{-ffinite-math-only}).
-This option implies that the sign of a zero result isn't significant.
-
-The default is @option{-fsigned-zeros}.
-
-@item -fno-trapping-math
-@opindex fno-trapping-math
-Compile code assuming that floating-point operations cannot generate
-user-visible traps. These traps include division by zero, overflow,
-underflow, inexact result and invalid operation. This option requires
-that @option{-fno-signaling-nans} be in effect. Setting this option may
-allow faster code if one relies on ``non-stop'' IEEE arithmetic, for example.
-
-This option should never be turned on by any @option{-O} option since
-it can result in incorrect output for programs that depend on
-an exact implementation of IEEE or ISO rules/specifications for
-math functions.
-
-The default is @option{-ftrapping-math}.
-
-@item -frounding-math
-@opindex frounding-math
-Disable transformations and optimizations that assume default floating-point
-rounding behavior. This is round-to-zero for all floating point
-to integer conversions, and round-to-nearest for all other arithmetic
-truncations. This option should be specified for programs that change
-the FP rounding mode dynamically, or that may be executed with a
-non-default rounding mode. This option disables constant folding of
-floating-point expressions at compile time (which may be affected by
-rounding mode) and arithmetic transformations that are unsafe in the
-presence of sign-dependent rounding modes.
-
-The default is @option{-fno-rounding-math}.
-
-This option is experimental and does not currently guarantee to
-disable all GCC optimizations that are affected by rounding mode.
-Future versions of GCC may provide finer control of this setting
-using C99's @code{FENV_ACCESS} pragma. This command-line option
-will be used to specify the default state for @code{FENV_ACCESS}.
-
-@item -fsignaling-nans
-@opindex fsignaling-nans
-Compile code assuming that IEEE signaling NaNs may generate user-visible
-traps during floating-point operations. Setting this option disables
-optimizations that may change the number of exceptions visible with
-signaling NaNs. This option implies @option{-ftrapping-math}.
-
-This option causes the preprocessor macro @code{__SUPPORT_SNAN__} to
-be defined.
-
-The default is @option{-fno-signaling-nans}.
-
-This option is experimental and does not currently guarantee to
-disable all GCC optimizations that affect signaling NaN behavior.
-
-@item -fsingle-precision-constant
-@opindex fsingle-precision-constant
-Treat floating-point constants as single precision instead of
-implicitly converting them to double-precision constants.
-
-@item -fcx-limited-range
-@opindex fcx-limited-range
-When enabled, this option states that a range reduction step is not
-needed when performing complex division. Also, there is no checking
-whether the result of a complex multiplication or division is @code{NaN
-+ I*NaN}, with an attempt to rescue the situation in that case. The
-default is @option{-fno-cx-limited-range}, but is enabled by
-@option{-ffast-math}.
-
-This option controls the default setting of the ISO C99
-@code{CX_LIMITED_RANGE} pragma. Nevertheless, the option applies to
-all languages.
-
-@item -fcx-fortran-rules
-@opindex fcx-fortran-rules
-Complex multiplication and division follow Fortran rules. Range
-reduction is done as part of complex division, but there is no checking
-whether the result of a complex multiplication or division is @code{NaN
-+ I*NaN}, with an attempt to rescue the situation in that case.
-
-The default is @option{-fno-cx-fortran-rules}.
-
-@end table
-
-The following options control optimizations that may improve
-performance, but are not enabled by any @option{-O} options. This
-section includes experimental options that may produce broken code.
-
-@table @gcctabopt
-@item -fbranch-probabilities
-@opindex fbranch-probabilities
-After running a program compiled with @option{-fprofile-arcs}
-(@pxref{Debugging Options,, Options for Debugging Your Program or
-@command{gcc}}), you can compile it a second time using
-@option{-fbranch-probabilities}, to improve optimizations based on
-the number of times each branch was taken. When a program
-compiled with @option{-fprofile-arcs} exits, it saves arc execution
-counts to a file called @file{@var{sourcename}.gcda} for each source
-file. The information in this data file is very dependent on the
-structure of the generated code, so you must use the same source code
-and the same optimization options for both compilations.
-
-With @option{-fbranch-probabilities}, GCC puts a
-@samp{REG_BR_PROB} note on each @samp{JUMP_INSN} and @samp{CALL_INSN}.
-These can be used to improve optimization. Currently, they are only
-used in one place: in @file{reorg.c}, instead of guessing which path a
-branch is most likely to take, the @samp{REG_BR_PROB} values are used to
-exactly determine which path is taken more often.
-
-@item -fprofile-values
-@opindex fprofile-values
-If combined with @option{-fprofile-arcs}, it adds code so that some
-data about values of expressions in the program is gathered.
-
-With @option{-fbranch-probabilities}, it reads back the data gathered
-from profiling values of expressions for usage in optimizations.
-
-Enabled with @option{-fprofile-generate} and @option{-fprofile-use}.
-
-@item -fvpt
-@opindex fvpt
-If combined with @option{-fprofile-arcs}, this option instructs the compiler
-to add code to gather information about values of expressions.
-
-With @option{-fbranch-probabilities}, it reads back the data gathered
-and actually performs the optimizations based on them.
-Currently the optimizations include specialization of division operations
-using the knowledge about the value of the denominator.
-
-@item -frename-registers
-@opindex frename-registers
-Attempt to avoid false dependencies in scheduled code by making use
-of registers left over after register allocation. This optimization
-most benefits processors with lots of registers. Depending on the
-debug information format adopted by the target, however, it can
-make debugging impossible, since variables no longer stay in
-a ``home register''.
-
-Enabled by default with @option{-funroll-loops} and @option{-fpeel-loops}.
-
-@item -ftracer
-@opindex ftracer
-Perform tail duplication to enlarge superblock size. This transformation
-simplifies the control flow of the function allowing other optimizations to do
-a better job.
-
-Enabled with @option{-fprofile-use}.
-
-@item -funroll-loops
-@opindex funroll-loops
-Unroll loops whose number of iterations can be determined at compile time or
-upon entry to the loop. @option{-funroll-loops} implies
-@option{-frerun-cse-after-loop}, @option{-fweb} and @option{-frename-registers}.
-It also turns on complete loop peeling (i.e.@: complete removal of loops with
-a small constant number of iterations). This option makes code larger, and may
-or may not make it run faster.
-
-Enabled with @option{-fprofile-use}.
-
-@item -funroll-all-loops
-@opindex funroll-all-loops
-Unroll all loops, even if their number of iterations is uncertain when
-the loop is entered. This usually makes programs run more slowly.
-@option{-funroll-all-loops} implies the same options as
-@option{-funroll-loops}.
-
-@item -fpeel-loops
-@opindex fpeel-loops
-Peels loops for which there is enough information that they do not
-roll much (from profile feedback). It also turns on complete loop peeling
-(i.e.@: complete removal of loops with small constant number of iterations).
-
-Enabled with @option{-fprofile-use}.
-
-@item -fmove-loop-invariants
-@opindex fmove-loop-invariants
-Enables the loop invariant motion pass in the RTL loop optimizer. Enabled
-at level @option{-O1}
-
-@item -funswitch-loops
-@opindex funswitch-loops
-Move branches with loop invariant conditions out of the loop, with duplicates
-of the loop on both branches (modified according to result of the condition).
-
-@item -ffunction-sections
-@itemx -fdata-sections
-@opindex ffunction-sections
-@opindex fdata-sections
-Place each function or data item into its own section in the output
-file if the target supports arbitrary sections. The name of the
-function or the name of the data item determines the section's name
-in the output file.
-
-Use these options on systems where the linker can perform optimizations
-to improve locality of reference in the instruction space. Most systems
-using the ELF object format and SPARC processors running Solaris 2 have
-linkers with such optimizations. AIX may have these optimizations in
-the future.
-
-Only use these options when there are significant benefits from doing
-so. When you specify these options, the assembler and linker
-create larger object and executable files and are also slower.
-You cannot use @code{gprof} on all systems if you
-specify this option, and you may have problems with debugging if
-you specify both this option and @option{-g}.
-
-@item -fbranch-target-load-optimize
-@opindex fbranch-target-load-optimize
-Perform branch target register load optimization before prologue / epilogue
-threading.
-The use of target registers can typically be exposed only during reload,
-thus hoisting loads out of loops and doing inter-block scheduling needs
-a separate optimization pass.
-
-@item -fbranch-target-load-optimize2
-@opindex fbranch-target-load-optimize2
-Perform branch target register load optimization after prologue / epilogue
-threading.
-
-@item -fbtr-bb-exclusive
-@opindex fbtr-bb-exclusive
-When performing branch target register load optimization, don't reuse
-branch target registers within any basic block.
-
-@item -fstack-protector
-@opindex fstack-protector
-Emit extra code to check for buffer overflows, such as stack smashing
-attacks. This is done by adding a guard variable to functions with
-vulnerable objects. This includes functions that call @code{alloca}, and
-functions with buffers larger than 8 bytes. The guards are initialized
-when a function is entered and then checked when the function exits.
-If a guard check fails, an error message is printed and the program exits.
-
-@item -fstack-protector-all
-@opindex fstack-protector-all
-Like @option{-fstack-protector} except that all functions are protected.
-
-@item -fsection-anchors
-@opindex fsection-anchors
-Try to reduce the number of symbolic address calculations by using
-shared ``anchor'' symbols to address nearby objects. This transformation
-can help to reduce the number of GOT entries and GOT accesses on some
-targets.
-
-For example, the implementation of the following function @code{foo}:
-
-@smallexample
-static int a, b, c;
-int foo (void) @{ return a + b + c; @}
-@end smallexample
-
-@noindent
-usually calculates the addresses of all three variables, but if you
-compile it with @option{-fsection-anchors}, it accesses the variables
-from a common anchor point instead. The effect is similar to the
-following pseudocode (which isn't valid C):
-
-@smallexample
-int foo (void)
-@{
- register int *xr = &x;
- return xr[&a - &x] + xr[&b - &x] + xr[&c - &x];
-@}
-@end smallexample
-
-Not all targets support this option.
-
-@item --param @var{name}=@var{value}
-@opindex param
-In some places, GCC uses various constants to control the amount of
-optimization that is done. For example, GCC does not inline functions
-that contain more than a certain number of instructions. You can
-control some of these constants on the command line using the
-@option{--param} option.
-
-The names of specific parameters, and the meaning of the values, are
-tied to the internals of the compiler, and are subject to change
-without notice in future releases.
-
-In each case, the @var{value} is an integer. The allowable choices for
-@var{name} are:
-
-@table @gcctabopt
-@item predictable-branch-outcome
-When branch is predicted to be taken with probability lower than this threshold
-(in percent), then it is considered well predictable. The default is 10.
-
-@item max-crossjump-edges
-The maximum number of incoming edges to consider for cross-jumping.
-The algorithm used by @option{-fcrossjumping} is @math{O(N^2)} in
-the number of edges incoming to each block. Increasing values mean
-more aggressive optimization, making the compilation time increase with
-probably small improvement in executable size.
-
-@item min-crossjump-insns
-The minimum number of instructions that must be matched at the end
-of two blocks before cross-jumping is performed on them. This
-value is ignored in the case where all instructions in the block being
-cross-jumped from are matched. The default value is 5.
-
-@item max-grow-copy-bb-insns
-The maximum code size expansion factor when copying basic blocks
-instead of jumping. The expansion is relative to a jump instruction.
-The default value is 8.
-
-@item max-goto-duplication-insns
-The maximum number of instructions to duplicate to a block that jumps
-to a computed goto. To avoid @math{O(N^2)} behavior in a number of
-passes, GCC factors computed gotos early in the compilation process,
-and unfactors them as late as possible. Only computed jumps at the
-end of a basic blocks with no more than max-goto-duplication-insns are
-unfactored. The default value is 8.
-
-@item max-delay-slot-insn-search
-The maximum number of instructions to consider when looking for an
-instruction to fill a delay slot. If more than this arbitrary number of
-instructions are searched, the time savings from filling the delay slot
-are minimal, so stop searching. Increasing values mean more
-aggressive optimization, making the compilation time increase with probably
-small improvement in execution time.
-
-@item max-delay-slot-live-search
-When trying to fill delay slots, the maximum number of instructions to
-consider when searching for a block with valid live register
-information. Increasing this arbitrarily chosen value means more
-aggressive optimization, increasing the compilation time. This parameter
-should be removed when the delay slot code is rewritten to maintain the
-control-flow graph.
-
-@item max-gcse-memory
-The approximate maximum amount of memory that can be allocated in
-order to perform the global common subexpression elimination
-optimization. If more memory than specified is required, the
-optimization is not done.
-
-@item max-gcse-insertion-ratio
-If the ratio of expression insertions to deletions is larger than this value
-for any expression, then RTL PRE inserts or removes the expression and thus
-leaves partially redundant computations in the instruction stream. The default value is 20.
-
-@item max-pending-list-length
-The maximum number of pending dependencies scheduling allows
-before flushing the current state and starting over. Large functions
-with few branches or calls can create excessively large lists which
-needlessly consume memory and resources.
-
-@item max-modulo-backtrack-attempts
-The maximum number of backtrack attempts the scheduler should make
-when modulo scheduling a loop. Larger values can exponentially increase
-compilation time.
-
-@item max-inline-insns-single
-Several parameters control the tree inliner used in GCC@.
-This number sets the maximum number of instructions (counted in GCC's
-internal representation) in a single function that the tree inliner
-considers for inlining. This only affects functions declared
-inline and methods implemented in a class declaration (C++).
-The default value is 400.
-
-@item max-inline-insns-auto
-When you use @option{-finline-functions} (included in @option{-O3}),
-a lot of functions that would otherwise not be considered for inlining
-by the compiler are investigated. To those functions, a different
-(more restrictive) limit compared to functions declared inline can
-be applied.
-The default value is 40.
-
-@item inline-min-speedup
-When estimated performance improvement of caller + callee runtime exceeds this
-threshold (in precent), the function can be inlined regardless the limit on
-@option{--param max-inline-insns-single} and @option{--param
-max-inline-insns-auto}.
-
-@item large-function-insns
-The limit specifying really large functions. For functions larger than this
-limit after inlining, inlining is constrained by
-@option{--param large-function-growth}. This parameter is useful primarily
-to avoid extreme compilation time caused by non-linear algorithms used by the
-back end.
-The default value is 2700.
-
-@item large-function-growth
-Specifies maximal growth of large function caused by inlining in percents.
-The default value is 100 which limits large function growth to 2.0 times
-the original size.
-
-@item large-unit-insns
-The limit specifying large translation unit. Growth caused by inlining of
-units larger than this limit is limited by @option{--param inline-unit-growth}.
-For small units this might be too tight.
-For example, consider a unit consisting of function A
-that is inline and B that just calls A three times. If B is small relative to
-A, the growth of unit is 300\% and yet such inlining is very sane. For very
-large units consisting of small inlineable functions, however, the overall unit
-growth limit is needed to avoid exponential explosion of code size. Thus for
-smaller units, the size is increased to @option{--param large-unit-insns}
-before applying @option{--param inline-unit-growth}. The default is 10000.
-
-@item inline-unit-growth
-Specifies maximal overall growth of the compilation unit caused by inlining.
-The default value is 30 which limits unit growth to 1.3 times the original
-size.
-
-@item ipcp-unit-growth
-Specifies maximal overall growth of the compilation unit caused by
-interprocedural constant propagation. The default value is 10 which limits
-unit growth to 1.1 times the original size.
-
-@item large-stack-frame
-The limit specifying large stack frames. While inlining the algorithm is trying
-to not grow past this limit too much. The default value is 256 bytes.
-
-@item large-stack-frame-growth
-Specifies maximal growth of large stack frames caused by inlining in percents.
-The default value is 1000 which limits large stack frame growth to 11 times
-the original size.
-
-@item max-inline-insns-recursive
-@itemx max-inline-insns-recursive-auto
-Specifies the maximum number of instructions an out-of-line copy of a
-self-recursive inline
-function can grow into by performing recursive inlining.
-
-For functions declared inline, @option{--param max-inline-insns-recursive} is
-taken into account. For functions not declared inline, recursive inlining
-happens only when @option{-finline-functions} (included in @option{-O3}) is
-enabled and @option{--param max-inline-insns-recursive-auto} is used. The
-default value is 450.
-
-@item max-inline-recursive-depth
-@itemx max-inline-recursive-depth-auto
-Specifies the maximum recursion depth used for recursive inlining.
-
-For functions declared inline, @option{--param max-inline-recursive-depth} is
-taken into account. For functions not declared inline, recursive inlining
-happens only when @option{-finline-functions} (included in @option{-O3}) is
-enabled and @option{--param max-inline-recursive-depth-auto} is used. The
-default value is 8.
-
-@item min-inline-recursive-probability
-Recursive inlining is profitable only for function having deep recursion
-in average and can hurt for function having little recursion depth by
-increasing the prologue size or complexity of function body to other
-optimizers.
-
-When profile feedback is available (see @option{-fprofile-generate}) the actual
-recursion depth can be guessed from probability that function recurses via a
-given call expression. This parameter limits inlining only to call expressions
-whose probability exceeds the given threshold (in percents).
-The default value is 10.
-
-@item early-inlining-insns
-Specify growth that the early inliner can make. In effect it increases
-the amount of inlining for code having a large abstraction penalty.
-The default value is 10.
-
-@item max-early-inliner-iterations
-@itemx max-early-inliner-iterations
-Limit of iterations of the early inliner. This basically bounds
-the number of nested indirect calls the early inliner can resolve.
-Deeper chains are still handled by late inlining.
-
-@item comdat-sharing-probability
-@itemx comdat-sharing-probability
-Probability (in percent) that C++ inline function with comdat visibility
-are shared across multiple compilation units. The default value is 20.
-
-@item min-vect-loop-bound
-The minimum number of iterations under which loops are not vectorized
-when @option{-ftree-vectorize} is used. The number of iterations after
-vectorization needs to be greater than the value specified by this option
-to allow vectorization. The default value is 0.
-
-@item gcse-cost-distance-ratio
-Scaling factor in calculation of maximum distance an expression
-can be moved by GCSE optimizations. This is currently supported only in the
-code hoisting pass. The bigger the ratio, the more aggressive code hoisting
-is with simple expressions, i.e., the expressions that have cost
-less than @option{gcse-unrestricted-cost}. Specifying 0 disables
-hoisting of simple expressions. The default value is 10.
-
-@item gcse-unrestricted-cost
-Cost, roughly measured as the cost of a single typical machine
-instruction, at which GCSE optimizations do not constrain
-the distance an expression can travel. This is currently
-supported only in the code hoisting pass. The lesser the cost,
-the more aggressive code hoisting is. Specifying 0
-allows all expressions to travel unrestricted distances.
-The default value is 3.
-
-@item max-hoist-depth
-The depth of search in the dominator tree for expressions to hoist.
-This is used to avoid quadratic behavior in hoisting algorithm.
-The value of 0 does not limit on the search, but may slow down compilation
-of huge functions. The default value is 30.
-
-@item max-tail-merge-comparisons
-The maximum amount of similar bbs to compare a bb with. This is used to
-avoid quadratic behavior in tree tail merging. The default value is 10.
-
-@item max-tail-merge-iterations
-The maximum amount of iterations of the pass over the function. This is used to
-limit compilation time in tree tail merging. The default value is 2.
-
-@item max-unrolled-insns
-The maximum number of instructions that a loop may have to be unrolled.
-If a loop is unrolled, this parameter also determines how many times
-the loop code is unrolled.
-
-@item max-average-unrolled-insns
-The maximum number of instructions biased by probabilities of their execution
-that a loop may have to be unrolled. If a loop is unrolled,
-this parameter also determines how many times the loop code is unrolled.
-
-@item max-unroll-times
-The maximum number of unrollings of a single loop.
-
-@item max-peeled-insns
-The maximum number of instructions that a loop may have to be peeled.
-If a loop is peeled, this parameter also determines how many times
-the loop code is peeled.
-
-@item max-peel-times
-The maximum number of peelings of a single loop.
-
-@item max-peel-branches
-The maximum number of branches on the hot path through the peeled sequence.
-
-@item max-completely-peeled-insns
-The maximum number of insns of a completely peeled loop.
-
-@item max-completely-peel-times
-The maximum number of iterations of a loop to be suitable for complete peeling.
-
-@item max-completely-peel-loop-nest-depth
-The maximum depth of a loop nest suitable for complete peeling.
-
-@item max-unswitch-insns
-The maximum number of insns of an unswitched loop.
-
-@item max-unswitch-level
-The maximum number of branches unswitched in a single loop.
-
-@item lim-expensive
-The minimum cost of an expensive expression in the loop invariant motion.
-
-@item iv-consider-all-candidates-bound
-Bound on number of candidates for induction variables, below which
-all candidates are considered for each use in induction variable
-optimizations. If there are more candidates than this,
-only the most relevant ones are considered to avoid quadratic time complexity.
-
-@item iv-max-considered-uses
-The induction variable optimizations give up on loops that contain more
-induction variable uses.
-
-@item iv-always-prune-cand-set-bound
-If the number of candidates in the set is smaller than this value,
-always try to remove unnecessary ivs from the set
-when adding a new one.
-
-@item scev-max-expr-size
-Bound on size of expressions used in the scalar evolutions analyzer.
-Large expressions slow the analyzer.
-
-@item scev-max-expr-complexity
-Bound on the complexity of the expressions in the scalar evolutions analyzer.
-Complex expressions slow the analyzer.
-
-@item omega-max-vars
-The maximum number of variables in an Omega constraint system.
-The default value is 128.
-
-@item omega-max-geqs
-The maximum number of inequalities in an Omega constraint system.
-The default value is 256.
-
-@item omega-max-eqs
-The maximum number of equalities in an Omega constraint system.
-The default value is 128.
-
-@item omega-max-wild-cards
-The maximum number of wildcard variables that the Omega solver is
-able to insert. The default value is 18.
-
-@item omega-hash-table-size
-The size of the hash table in the Omega solver. The default value is
-550.
-
-@item omega-max-keys
-The maximal number of keys used by the Omega solver. The default
-value is 500.
-
-@item omega-eliminate-redundant-constraints
-When set to 1, use expensive methods to eliminate all redundant
-constraints. The default value is 0.
-
-@item vect-max-version-for-alignment-checks
-The maximum number of run-time checks that can be performed when
-doing loop versioning for alignment in the vectorizer. See option
-@option{-ftree-vect-loop-version} for more information.
-
-@item vect-max-version-for-alias-checks
-The maximum number of run-time checks that can be performed when
-doing loop versioning for alias in the vectorizer. See option
-@option{-ftree-vect-loop-version} for more information.
-
-@item max-iterations-to-track
-The maximum number of iterations of a loop the brute-force algorithm
-for analysis of the number of iterations of the loop tries to evaluate.
-
-@item hot-bb-count-ws-permille
-A basic block profile count is considered hot if it contributes to
-the given permillage (i.e. 0...1000) of the entire profiled execution.
-
-@item hot-bb-frequency-fraction
-Select fraction of the entry block frequency of executions of basic block in
-function given basic block needs to have to be considered hot.
-
-@item max-predicted-iterations
-The maximum number of loop iterations we predict statically. This is useful
-in cases where a function contains a single loop with known bound and
-another loop with unknown bound.
-The known number of iterations is predicted correctly, while
-the unknown number of iterations average to roughly 10. This means that the
-loop without bounds appears artificially cold relative to the other one.
-
-@item align-threshold
-
-Select fraction of the maximal frequency of executions of a basic block in
-a function to align the basic block.
-
-@item align-loop-iterations
-
-A loop expected to iterate at least the selected number of iterations is
-aligned.
-
-@item tracer-dynamic-coverage
-@itemx tracer-dynamic-coverage-feedback
-
-This value is used to limit superblock formation once the given percentage of
-executed instructions is covered. This limits unnecessary code size
-expansion.
-
-The @option{tracer-dynamic-coverage-feedback} is used only when profile
-feedback is available. The real profiles (as opposed to statically estimated
-ones) are much less balanced allowing the threshold to be larger value.
-
-@item tracer-max-code-growth
-Stop tail duplication once code growth has reached given percentage. This is
-a rather artificial limit, as most of the duplicates are eliminated later in
-cross jumping, so it may be set to much higher values than is the desired code
-growth.
-
-@item tracer-min-branch-ratio
-
-Stop reverse growth when the reverse probability of best edge is less than this
-threshold (in percent).
-
-@item tracer-min-branch-ratio
-@itemx tracer-min-branch-ratio-feedback
-
-Stop forward growth if the best edge has probability lower than this
-threshold.
-
-Similarly to @option{tracer-dynamic-coverage} two values are present, one for
-compilation for profile feedback and one for compilation without. The value
-for compilation with profile feedback needs to be more conservative (higher) in
-order to make tracer effective.
-
-@item max-cse-path-length
-
-The maximum number of basic blocks on path that CSE considers.
-The default is 10.
-
-@item max-cse-insns
-The maximum number of instructions CSE processes before flushing.
-The default is 1000.
-
-@item ggc-min-expand
-
-GCC uses a garbage collector to manage its own memory allocation. This
-parameter specifies the minimum percentage by which the garbage
-collector's heap should be allowed to expand between collections.
-Tuning this may improve compilation speed; it has no effect on code
-generation.
-
-The default is 30% + 70% * (RAM/1GB) with an upper bound of 100% when
-RAM >= 1GB@. If @code{getrlimit} is available, the notion of ``RAM'' is
-the smallest of actual RAM and @code{RLIMIT_DATA} or @code{RLIMIT_AS}. If
-GCC is not able to calculate RAM on a particular platform, the lower
-bound of 30% is used. Setting this parameter and
-@option{ggc-min-heapsize} to zero causes a full collection to occur at
-every opportunity. This is extremely slow, but can be useful for
-debugging.
-
-@item ggc-min-heapsize
-
-Minimum size of the garbage collector's heap before it begins bothering
-to collect garbage. The first collection occurs after the heap expands
-by @option{ggc-min-expand}% beyond @option{ggc-min-heapsize}. Again,
-tuning this may improve compilation speed, and has no effect on code
-generation.
-
-The default is the smaller of RAM/8, RLIMIT_RSS, or a limit that
-tries to ensure that RLIMIT_DATA or RLIMIT_AS are not exceeded, but
-with a lower bound of 4096 (four megabytes) and an upper bound of
-131072 (128 megabytes). If GCC is not able to calculate RAM on a
-particular platform, the lower bound is used. Setting this parameter
-very large effectively disables garbage collection. Setting this
-parameter and @option{ggc-min-expand} to zero causes a full collection
-to occur at every opportunity.
-
-@item max-reload-search-insns
-The maximum number of instruction reload should look backward for equivalent
-register. Increasing values mean more aggressive optimization, making the
-compilation time increase with probably slightly better performance.
-The default value is 100.
-
-@item max-cselib-memory-locations
-The maximum number of memory locations cselib should take into account.
-Increasing values mean more aggressive optimization, making the compilation time
-increase with probably slightly better performance. The default value is 500.
-
-@item reorder-blocks-duplicate
-@itemx reorder-blocks-duplicate-feedback
-
-Used by the basic block reordering pass to decide whether to use unconditional
-branch or duplicate the code on its destination. Code is duplicated when its
-estimated size is smaller than this value multiplied by the estimated size of
-unconditional jump in the hot spots of the program.
-
-The @option{reorder-block-duplicate-feedback} is used only when profile
-feedback is available. It may be set to higher values than
-@option{reorder-block-duplicate} since information about the hot spots is more
-accurate.
-
-@item max-sched-ready-insns
-The maximum number of instructions ready to be issued the scheduler should
-consider at any given time during the first scheduling pass. Increasing
-values mean more thorough searches, making the compilation time increase
-with probably little benefit. The default value is 100.
-
-@item max-sched-region-blocks
-The maximum number of blocks in a region to be considered for
-interblock scheduling. The default value is 10.
-
-@item max-pipeline-region-blocks
-The maximum number of blocks in a region to be considered for
-pipelining in the selective scheduler. The default value is 15.
-
-@item max-sched-region-insns
-The maximum number of insns in a region to be considered for
-interblock scheduling. The default value is 100.
-
-@item max-pipeline-region-insns
-The maximum number of insns in a region to be considered for
-pipelining in the selective scheduler. The default value is 200.
-
-@item min-spec-prob
-The minimum probability (in percents) of reaching a source block
-for interblock speculative scheduling. The default value is 40.
-
-@item max-sched-extend-regions-iters
-The maximum number of iterations through CFG to extend regions.
-A value of 0 (the default) disables region extensions.
-
-@item max-sched-insn-conflict-delay
-The maximum conflict delay for an insn to be considered for speculative motion.
-The default value is 3.
-
-@item sched-spec-prob-cutoff
-The minimal probability of speculation success (in percents), so that
-speculative insns are scheduled.
-The default value is 40.
-
-@item sched-spec-state-edge-prob-cutoff
-The minimum probability an edge must have for the scheduler to save its
-state across it.
-The default value is 10.
-
-@item sched-mem-true-dep-cost
-Minimal distance (in CPU cycles) between store and load targeting same
-memory locations. The default value is 1.
-
-@item selsched-max-lookahead
-The maximum size of the lookahead window of selective scheduling. It is a
-depth of search for available instructions.
-The default value is 50.
-
-@item selsched-max-sched-times
-The maximum number of times that an instruction is scheduled during
-selective scheduling. This is the limit on the number of iterations
-through which the instruction may be pipelined. The default value is 2.
-
-@item selsched-max-insns-to-rename
-The maximum number of best instructions in the ready list that are considered
-for renaming in the selective scheduler. The default value is 2.
-
-@item sms-min-sc
-The minimum value of stage count that swing modulo scheduler
-generates. The default value is 2.
-
-@item max-last-value-rtl
-The maximum size measured as number of RTLs that can be recorded in an expression
-in combiner for a pseudo register as last known value of that register. The default
-is 10000.
-
-@item integer-share-limit
-Small integer constants can use a shared data structure, reducing the
-compiler's memory usage and increasing its speed. This sets the maximum
-value of a shared integer constant. The default value is 256.
-
-@item ssp-buffer-size
-The minimum size of buffers (i.e.@: arrays) that receive stack smashing
-protection when @option{-fstack-protection} is used.
-
-@item max-jump-thread-duplication-stmts
-Maximum number of statements allowed in a block that needs to be
-duplicated when threading jumps.
-
-@item max-fields-for-field-sensitive
-Maximum number of fields in a structure treated in
-a field sensitive manner during pointer analysis. The default is zero
-for @option{-O0} and @option{-O1},
-and 100 for @option{-Os}, @option{-O2}, and @option{-O3}.
-
-@item prefetch-latency
-Estimate on average number of instructions that are executed before
-prefetch finishes. The distance prefetched ahead is proportional
-to this constant. Increasing this number may also lead to less
-streams being prefetched (see @option{simultaneous-prefetches}).
-
-@item simultaneous-prefetches
-Maximum number of prefetches that can run at the same time.
-
-@item l1-cache-line-size
-The size of cache line in L1 cache, in bytes.
-
-@item l1-cache-size
-The size of L1 cache, in kilobytes.
-
-@item l2-cache-size
-The size of L2 cache, in kilobytes.
-
-@item min-insn-to-prefetch-ratio
-The minimum ratio between the number of instructions and the
-number of prefetches to enable prefetching in a loop.
-
-@item prefetch-min-insn-to-mem-ratio
-The minimum ratio between the number of instructions and the
-number of memory references to enable prefetching in a loop.
-
-@item use-canonical-types
-Whether the compiler should use the ``canonical'' type system. By
-default, this should always be 1, which uses a more efficient internal
-mechanism for comparing types in C++ and Objective-C++. However, if
-bugs in the canonical type system are causing compilation failures,
-set this value to 0 to disable canonical types.
-
-@item switch-conversion-max-branch-ratio
-Switch initialization conversion refuses to create arrays that are
-bigger than @option{switch-conversion-max-branch-ratio} times the number of
-branches in the switch.
-
-@item max-partial-antic-length
-Maximum length of the partial antic set computed during the tree
-partial redundancy elimination optimization (@option{-ftree-pre}) when
-optimizing at @option{-O3} and above. For some sorts of source code
-the enhanced partial redundancy elimination optimization can run away,
-consuming all of the memory available on the host machine. This
-parameter sets a limit on the length of the sets that are computed,
-which prevents the runaway behavior. Setting a value of 0 for
-this parameter allows an unlimited set length.
-
-@item sccvn-max-scc-size
-Maximum size of a strongly connected component (SCC) during SCCVN
-processing. If this limit is hit, SCCVN processing for the whole
-function is not done and optimizations depending on it are
-disabled. The default maximum SCC size is 10000.
-
-@item sccvn-max-alias-queries-per-access
-Maximum number of alias-oracle queries we perform when looking for
-redundancies for loads and stores. If this limit is hit the search
-is aborted and the load or store is not considered redundant. The
-number of queries is algorithmically limited to the number of
-stores on all paths from the load to the function entry.
-The default maxmimum number of queries is 1000.
-
-@item ira-max-loops-num
-IRA uses regional register allocation by default. If a function
-contains more loops than the number given by this parameter, only at most
-the given number of the most frequently-executed loops form regions
-for regional register allocation. The default value of the
-parameter is 100.
-
-@item ira-max-conflict-table-size
-Although IRA uses a sophisticated algorithm to compress the conflict
-table, the table can still require excessive amounts of memory for
-huge functions. If the conflict table for a function could be more
-than the size in MB given by this parameter, the register allocator
-instead uses a faster, simpler, and lower-quality
-algorithm that does not require building a pseudo-register conflict table.
-The default value of the parameter is 2000.
-
-@item ira-loop-reserved-regs
-IRA can be used to evaluate more accurate register pressure in loops
-for decisions to move loop invariants (see @option{-O3}). The number
-of available registers reserved for some other purposes is given
-by this parameter. The default value of the parameter is 2, which is
-the minimal number of registers needed by typical instructions.
-This value is the best found from numerous experiments.
-
-@item loop-invariant-max-bbs-in-loop
-Loop invariant motion can be very expensive, both in compilation time and
-in amount of needed compile-time memory, with very large loops. Loops
-with more basic blocks than this parameter won't have loop invariant
-motion optimization performed on them. The default value of the
-parameter is 1000 for @option{-O1} and 10000 for @option{-O2} and above.
-
-@item loop-max-datarefs-for-datadeps
-Building data dapendencies is expensive for very large loops. This
-parameter limits the number of data references in loops that are
-considered for data dependence analysis. These large loops are no
-handled by the optimizations using loop data dependencies.
-The default value is 1000.
-
-@item max-vartrack-size
-Sets a maximum number of hash table slots to use during variable
-tracking dataflow analysis of any function. If this limit is exceeded
-with variable tracking at assignments enabled, analysis for that
-function is retried without it, after removing all debug insns from
-the function. If the limit is exceeded even without debug insns, var
-tracking analysis is completely disabled for the function. Setting
-the parameter to zero makes it unlimited.
-
-@item max-vartrack-expr-depth
-Sets a maximum number of recursion levels when attempting to map
-variable names or debug temporaries to value expressions. This trades
-compilation time for more complete debug information. If this is set too
-low, value expressions that are available and could be represented in
-debug information may end up not being used; setting this higher may
-enable the compiler to find more complex debug expressions, but compile
-time and memory use may grow. The default is 12.
-
-@item min-nondebug-insn-uid
-Use uids starting at this parameter for nondebug insns. The range below
-the parameter is reserved exclusively for debug insns created by
-@option{-fvar-tracking-assignments}, but debug insns may get
-(non-overlapping) uids above it if the reserved range is exhausted.
-
-@item ipa-sra-ptr-growth-factor
-IPA-SRA replaces a pointer to an aggregate with one or more new
-parameters only when their cumulative size is less or equal to
-@option{ipa-sra-ptr-growth-factor} times the size of the original
-pointer parameter.
-
-@item tm-max-aggregate-size
-When making copies of thread-local variables in a transaction, this
-parameter specifies the size in bytes after which variables are
-saved with the logging functions as opposed to save/restore code
-sequence pairs. This option only applies when using
-@option{-fgnu-tm}.
-
-@item graphite-max-nb-scop-params
-To avoid exponential effects in the Graphite loop transforms, the
-number of parameters in a Static Control Part (SCoP) is bounded. The
-default value is 10 parameters. A variable whose value is unknown at
-compilation time and defined outside a SCoP is a parameter of the SCoP.
-
-@item graphite-max-bbs-per-function
-To avoid exponential effects in the detection of SCoPs, the size of
-the functions analyzed by Graphite is bounded. The default value is
-100 basic blocks.
-
-@item loop-block-tile-size
-Loop blocking or strip mining transforms, enabled with
-@option{-floop-block} or @option{-floop-strip-mine}, strip mine each
-loop in the loop nest by a given number of iterations. The strip
-length can be changed using the @option{loop-block-tile-size}
-parameter. The default value is 51 iterations.
-
-@item ipa-cp-value-list-size
-IPA-CP attempts to track all possible values and types passed to a function's
-parameter in order to propagate them and perform devirtualization.
-@option{ipa-cp-value-list-size} is the maximum number of values and types it
-stores per one formal parameter of a function.
-
-@item lto-partitions
-Specify desired number of partitions produced during WHOPR compilation.
-The number of partitions should exceed the number of CPUs used for compilation.
-The default value is 32.
-
-@item lto-minpartition
-Size of minimal partition for WHOPR (in estimated instructions).
-This prevents expenses of splitting very small programs into too many
-partitions.
-
-@item cxx-max-namespaces-for-diagnostic-help
-The maximum number of namespaces to consult for suggestions when C++
-name lookup fails for an identifier. The default is 1000.
-
-@item sink-frequency-threshold
-The maximum relative execution frequency (in percents) of the target block
-relative to a statement's original block to allow statement sinking of a
-statement. Larger numbers result in more aggressive statement sinking.
-The default value is 75. A small positive adjustment is applied for
-statements with memory operands as those are even more profitable so sink.
-
-@item max-stores-to-sink
-The maximum number of conditional stores paires that can be sunk. Set to 0
-if either vectorization (@option{-ftree-vectorize}) or if-conversion
-(@option{-ftree-loop-if-convert}) is disabled. The default is 2.
-
-@item allow-load-data-races
-Allow optimizers to introduce new data races on loads.
-Set to 1 to allow, otherwise to 0. This option is enabled by default
-unless implicitly set by the @option{-fmemory-model=} option.
-
-@item allow-store-data-races
-Allow optimizers to introduce new data races on stores.
-Set to 1 to allow, otherwise to 0. This option is enabled by default
-unless implicitly set by the @option{-fmemory-model=} option.
-
-@item allow-packed-load-data-races
-Allow optimizers to introduce new data races on packed data loads.
-Set to 1 to allow, otherwise to 0. This option is enabled by default
-unless implicitly set by the @option{-fmemory-model=} option.
-
-@item allow-packed-store-data-races
-Allow optimizers to introduce new data races on packed data stores.
-Set to 1 to allow, otherwise to 0. This option is enabled by default
-unless implicitly set by the @option{-fmemory-model=} option.
-
-@item case-values-threshold
-The smallest number of different values for which it is best to use a
-jump-table instead of a tree of conditional branches. If the value is
-0, use the default for the machine. The default is 0.
-
-@item tree-reassoc-width
-Set the maximum number of instructions executed in parallel in
-reassociated tree. This parameter overrides target dependent
-heuristics used by default if has non zero value.
-
-@item sched-pressure-algorithm
-Choose between the two available implementations of
-@option{-fsched-pressure}. Algorithm 1 is the original implementation
-and is the more likely to prevent instructions from being reordered.
-Algorithm 2 was designed to be a compromise between the relatively
-conservative approach taken by algorithm 1 and the rather aggressive
-approach taken by the default scheduler. It relies more heavily on
-having a regular register file and accurate register pressure classes.
-See @file{haifa-sched.c} in the GCC sources for more details.
-
-The default choice depends on the target.
-
-@item max-slsr-cand-scan
-Set the maximum number of existing candidates that will be considered when
-seeking a basis for a new straight-line strength reduction candidate.
-
-@end table
-@end table
-
-@node Preprocessor Options
-@section Options Controlling the Preprocessor
-@cindex preprocessor options
-@cindex options, preprocessor
-
-These options control the C preprocessor, which is run on each C source
-file before actual compilation.
-
-If you use the @option{-E} option, nothing is done except preprocessing.
-Some of these options make sense only together with @option{-E} because
-they cause the preprocessor output to be unsuitable for actual
-compilation.
-
-@table @gcctabopt
-@item -Wp,@var{option}
-@opindex Wp
-You can use @option{-Wp,@var{option}} to bypass the compiler driver
-and pass @var{option} directly through to the preprocessor. If
-@var{option} contains commas, it is split into multiple options at the
-commas. However, many options are modified, translated or interpreted
-by the compiler driver before being passed to the preprocessor, and
-@option{-Wp} forcibly bypasses this phase. The preprocessor's direct
-interface is undocumented and subject to change, so whenever possible
-you should avoid using @option{-Wp} and let the driver handle the
-options instead.
-
-@item -Xpreprocessor @var{option}
-@opindex Xpreprocessor
-Pass @var{option} as an option to the preprocessor. You can use this to
-supply system-specific preprocessor options that GCC does not
-recognize.
-
-If you want to pass an option that takes an argument, you must use
-@option{-Xpreprocessor} twice, once for the option and once for the argument.
-
-@item -no-integrated-cpp
-@opindex no-integrated-cpp
-Perform preprocessing as a separate pass before compilation.
-By default, GCC performs preprocessing as an integrated part of
-input tokenization and parsing.
-If this option is provided, the appropriate language front end
-(@command{cc1}, @command{cc1plus}, or @command{cc1obj} for C, C++,
-and Objective-C, respectively) is instead invoked twice,
-once for preprocessing only and once for actual compilation
-of the preprocessed input.
-This option may be useful in conjunction with the @option{-B} or
-@option{-wrapper} options to specify an alternate preprocessor or
-perform additional processing of the program source between
-normal preprocessing and compilation.
-@end table
-
-@include cppopts.texi
-
-@node Assembler Options
-@section Passing Options to the Assembler
-
-@c prevent bad page break with this line
-You can pass options to the assembler.
-
-@table @gcctabopt
-@item -Wa,@var{option}
-@opindex Wa
-Pass @var{option} as an option to the assembler. If @var{option}
-contains commas, it is split into multiple options at the commas.
-
-@item -Xassembler @var{option}
-@opindex Xassembler
-Pass @var{option} as an option to the assembler. You can use this to
-supply system-specific assembler options that GCC does not
-recognize.
-
-If you want to pass an option that takes an argument, you must use
-@option{-Xassembler} twice, once for the option and once for the argument.
-
-@end table
-
-@node Link Options
-@section Options for Linking
-@cindex link options
-@cindex options, linking
-
-These options come into play when the compiler links object files into
-an executable output file. They are meaningless if the compiler is
-not doing a link step.
-
-@table @gcctabopt
-@cindex file names
-@item @var{object-file-name}
-A file name that does not end in a special recognized suffix is
-considered to name an object file or library. (Object files are
-distinguished from libraries by the linker according to the file
-contents.) If linking is done, these object files are used as input
-to the linker.
-
-@item -c
-@itemx -S
-@itemx -E
-@opindex c
-@opindex S
-@opindex E
-If any of these options is used, then the linker is not run, and
-object file names should not be used as arguments. @xref{Overall
-Options}.
-
-@cindex Libraries
-@item -l@var{library}
-@itemx -l @var{library}
-@opindex l
-Search the library named @var{library} when linking. (The second
-alternative with the library as a separate argument is only for
-POSIX compliance and is not recommended.)
-
-It makes a difference where in the command you write this option; the
-linker searches and processes libraries and object files in the order they
-are specified. Thus, @samp{foo.o -lz bar.o} searches library @samp{z}
-after file @file{foo.o} but before @file{bar.o}. If @file{bar.o} refers
-to functions in @samp{z}, those functions may not be loaded.
-
-The linker searches a standard list of directories for the library,
-which is actually a file named @file{lib@var{library}.a}. The linker
-then uses this file as if it had been specified precisely by name.
-
-The directories searched include several standard system directories
-plus any that you specify with @option{-L}.
-
-Normally the files found this way are library files---archive files
-whose members are object files. The linker handles an archive file by
-scanning through it for members which define symbols that have so far
-been referenced but not defined. But if the file that is found is an
-ordinary object file, it is linked in the usual fashion. The only
-difference between using an @option{-l} option and specifying a file name
-is that @option{-l} surrounds @var{library} with @samp{lib} and @samp{.a}
-and searches several directories.
-
-@item -lobjc
-@opindex lobjc
-You need this special case of the @option{-l} option in order to
-link an Objective-C or Objective-C++ program.
-
-@item -nostartfiles
-@opindex nostartfiles
-Do not use the standard system startup files when linking.
-The standard system libraries are used normally, unless @option{-nostdlib}
-or @option{-nodefaultlibs} is used.
-
-@item -nodefaultlibs
-@opindex nodefaultlibs
-Do not use the standard system libraries when linking.
-Only the libraries you specify are passed to the linker, and options
-specifying linkage of the system libraries, such as @code{-static-libgcc}
-or @code{-shared-libgcc}, are ignored.
-The standard startup files are used normally, unless @option{-nostartfiles}
-is used.
-
-The compiler may generate calls to @code{memcmp},
-@code{memset}, @code{memcpy} and @code{memmove}.
-These entries are usually resolved by entries in
-libc. These entry points should be supplied through some other
-mechanism when this option is specified.
-
-@item -nostdlib
-@opindex nostdlib
-Do not use the standard system startup files or libraries when linking.
-No startup files and only the libraries you specify are passed to
-the linker, and options specifying linkage of the system libraries, such as
-@code{-static-libgcc} or @code{-shared-libgcc}, are ignored.
-
-The compiler may generate calls to @code{memcmp}, @code{memset},
-@code{memcpy} and @code{memmove}.
-These entries are usually resolved by entries in
-libc. These entry points should be supplied through some other
-mechanism when this option is specified.
-
-@cindex @option{-lgcc}, use with @option{-nostdlib}
-@cindex @option{-nostdlib} and unresolved references
-@cindex unresolved references and @option{-nostdlib}
-@cindex @option{-lgcc}, use with @option{-nodefaultlibs}
-@cindex @option{-nodefaultlibs} and unresolved references
-@cindex unresolved references and @option{-nodefaultlibs}
-One of the standard libraries bypassed by @option{-nostdlib} and
-@option{-nodefaultlibs} is @file{libgcc.a}, a library of internal subroutines
-which GCC uses to overcome shortcomings of particular machines, or special
-needs for some languages.
-(@xref{Interface,,Interfacing to GCC Output,gccint,GNU Compiler
-Collection (GCC) Internals},
-for more discussion of @file{libgcc.a}.)
-In most cases, you need @file{libgcc.a} even when you want to avoid
-other standard libraries. In other words, when you specify @option{-nostdlib}
-or @option{-nodefaultlibs} you should usually specify @option{-lgcc} as well.
-This ensures that you have no unresolved references to internal GCC
-library subroutines.
-(An example of such an internal subroutine is @samp{__main}, used to ensure C++
-constructors are called; @pxref{Collect2,,@code{collect2}, gccint,
-GNU Compiler Collection (GCC) Internals}.)
-
-@item -pie
-@opindex pie
-Produce a position independent executable on targets that support it.
-For predictable results, you must also specify the same set of options
-used for compilation (@option{-fpie}, @option{-fPIE},
-or model suboptions) when you specify this linker option.
-
-@item -rdynamic
-@opindex rdynamic
-Pass the flag @option{-export-dynamic} to the ELF linker, on targets
-that support it. This instructs the linker to add all symbols, not
-only used ones, to the dynamic symbol table. This option is needed
-for some uses of @code{dlopen} or to allow obtaining backtraces
-from within a program.
-
-@item -s
-@opindex s
-Remove all symbol table and relocation information from the executable.
-
-@item -static
-@opindex static
-On systems that support dynamic linking, this prevents linking with the shared
-libraries. On other systems, this option has no effect.
-
-@item -shared
-@opindex shared
-Produce a shared object which can then be linked with other objects to
-form an executable. Not all systems support this option. For predictable
-results, you must also specify the same set of options used for compilation
-(@option{-fpic}, @option{-fPIC}, or model suboptions) when
-you specify this linker option.@footnote{On some systems, @samp{gcc -shared}
-needs to build supplementary stub code for constructors to work. On
-multi-libbed systems, @samp{gcc -shared} must select the correct support
-libraries to link against. Failing to supply the correct flags may lead
-to subtle defects. Supplying them in cases where they are not necessary
-is innocuous.}
-
-@item -shared-libgcc
-@itemx -static-libgcc
-@opindex shared-libgcc
-@opindex static-libgcc
-On systems that provide @file{libgcc} as a shared library, these options
-force the use of either the shared or static version, respectively.
-If no shared version of @file{libgcc} was built when the compiler was
-configured, these options have no effect.
-
-There are several situations in which an application should use the
-shared @file{libgcc} instead of the static version. The most common
-of these is when the application wishes to throw and catch exceptions
-across different shared libraries. In that case, each of the libraries
-as well as the application itself should use the shared @file{libgcc}.
-
-Therefore, the G++ and GCJ drivers automatically add
-@option{-shared-libgcc} whenever you build a shared library or a main
-executable, because C++ and Java programs typically use exceptions, so
-this is the right thing to do.
-
-If, instead, you use the GCC driver to create shared libraries, you may
-find that they are not always linked with the shared @file{libgcc}.
-If GCC finds, at its configuration time, that you have a non-GNU linker
-or a GNU linker that does not support option @option{--eh-frame-hdr},
-it links the shared version of @file{libgcc} into shared libraries
-by default. Otherwise, it takes advantage of the linker and optimizes
-away the linking with the shared version of @file{libgcc}, linking with
-the static version of libgcc by default. This allows exceptions to
-propagate through such shared libraries, without incurring relocation
-costs at library load time.
-
-However, if a library or main executable is supposed to throw or catch
-exceptions, you must link it using the G++ or GCJ driver, as appropriate
-for the languages used in the program, or using the option
-@option{-shared-libgcc}, such that it is linked with the shared
-@file{libgcc}.
-
-@item -static-libasan
-When the @option{-fsanitize=address} option is used to link a program,
-the GCC driver automatically links against @option{libasan}. If
-@file{libasan} is available as a shared library, and the @option{-static}
-option is not used, then this links against the shared version of
-@file{libasan}. The @option{-static-libasan} option directs the GCC
-driver to link @file{libasan} statically, without necessarily linking
-other libraries statically.
-
-@item -static-libtsan
-When the @option{-fsanitize=thread} option is used to link a program,
-the GCC driver automatically links against @option{libtsan}. If
-@file{libtsan} is available as a shared library, and the @option{-static}
-option is not used, then this links against the shared version of
-@file{libtsan}. The @option{-static-libtsan} option directs the GCC
-driver to link @file{libtsan} statically, without necessarily linking
-other libraries statically.
-
-@item -static-libstdc++
-When the @command{g++} program is used to link a C++ program, it
-normally automatically links against @option{libstdc++}. If
-@file{libstdc++} is available as a shared library, and the
-@option{-static} option is not used, then this links against the
-shared version of @file{libstdc++}. That is normally fine. However, it
-is sometimes useful to freeze the version of @file{libstdc++} used by
-the program without going all the way to a fully static link. The
-@option{-static-libstdc++} option directs the @command{g++} driver to
-link @file{libstdc++} statically, without necessarily linking other
-libraries statically.
-
-@item -symbolic
-@opindex symbolic
-Bind references to global symbols when building a shared object. Warn
-about any unresolved references (unless overridden by the link editor
-option @option{-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 that GCC does not recognize.
-
-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
-@option{-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
-@option{-Xlinker -Map=output.map} rather than
-@option{-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. You can use this
-syntax to pass an argument to the option.
-For example, @option{-Wl,-Map,output.map} passes @option{-Map output.map} to the
-linker. When using the GNU linker, you can also get the same effect with
-@option{-Wl,-Map=output.map}.
-
-@item -u @var{symbol}
-@opindex u
-Pretend the symbol @var{symbol} is undefined, to force linking of
-library modules to define it. You can use @option{-u} multiple times with
-different symbols to force loading of additional library modules.
-@end table
-
-@node Directory Options
-@section Options for Directory Search
-@cindex directory options
-@cindex options, directory search
-@cindex search path
-
-These options specify directories to search for header files, for
-libraries and for parts of the compiler:
-
-@table @gcctabopt
-@item -I@var{dir}
-@opindex I
-Add the directory @var{dir} to the head of the list of directories to be
-searched for header files. This can be used to override a system header
-file, substituting your own version, since these directories are
-searched before the system header file directories. However, you should
-not use this option to add directories that contain vendor-supplied
-system header files (use @option{-isystem} for that). If you use more than
-one @option{-I} option, the directories are scanned in left-to-right
-order; the standard system directories come after.
-
-If a standard system include directory, or a directory specified with
-@option{-isystem}, is also specified with @option{-I}, the @option{-I}
-option is ignored. The directory is still searched but as a
-system directory at its normal position in the system include chain.
-This is to ensure that GCC's procedure to fix buggy system headers and
-the ordering for the @code{include_next} directive are not inadvertently changed.
-If you really need to change the search order for system directories,
-use the @option{-nostdinc} and/or @option{-isystem} options.
-
-@item -iplugindir=@var{dir}
-Set the directory to search for plugins that are passed
-by @option{-fplugin=@var{name}} instead of
-@option{-fplugin=@var{path}/@var{name}.so}. This option is not meant
-to be used by the user, but only passed by the driver.
-
-@item -iquote@var{dir}
-@opindex iquote
-Add the directory @var{dir} to the head of the list of directories to
-be searched for header files only for the case of @samp{#include
-"@var{file}"}; they are not searched for @samp{#include <@var{file}>},
-otherwise just like @option{-I}.
-
-@item -L@var{dir}
-@opindex L
-Add directory @var{dir} to the list of directories to be searched
-for @option{-l}.
-
-@item -B@var{prefix}
-@opindex B
-This option specifies where to find the executables, libraries,
-include files, and data files of the compiler itself.
-
-The compiler driver program runs one or more of the subprograms
-@command{cpp}, @command{cc1}, @command{as} and @command{ld}. It tries
-@var{prefix} as a prefix for each program it tries to run, both with and
-without @samp{@var{machine}/@var{version}/} (@pxref{Target Options}).
-
-For each subprogram to be run, the compiler driver first tries the
-@option{-B} prefix, if any. If that name is not found, or if @option{-B}
-is not specified, the driver tries two standard prefixes,
-@file{/usr/lib/gcc/} and @file{/usr/local/lib/gcc/}. If neither of
-those results in a file name that is found, the unmodified program
-name is searched for using the directories specified in your
-@env{PATH} environment variable.
-
-The compiler checks to see if the path provided by the @option{-B}
-refers to a directory, and if necessary it adds a directory
-separator character at the end of the path.
-
-@option{-B} prefixes that effectively specify directory names also apply
-to libraries in the linker, because the compiler translates these
-options into @option{-L} options for the linker. They also apply to
-includes files in the preprocessor, because the compiler translates these
-options into @option{-isystem} options for the preprocessor. In this case,
-the compiler appends @samp{include} to the prefix.
-
-The runtime support file @file{libgcc.a} can also be searched for using
-the @option{-B} prefix, if needed. If it is not found there, the two
-standard prefixes above are tried, and that is all. The file is left
-out of the link if it is not found by those means.
-
-Another way to specify a prefix much like the @option{-B} prefix is to use
-the environment variable @env{GCC_EXEC_PREFIX}. @xref{Environment
-Variables}.
-
-As a special kludge, if the path provided by @option{-B} is
-@file{[dir/]stage@var{N}/}, where @var{N} is a number in the range 0 to
-9, then it is replaced by @file{[dir/]include}. This is to help
-with boot-strapping the compiler.
-
-@item -specs=@var{file}
-@opindex specs
-Process @var{file} after the compiler reads in the standard @file{specs}
-file, in order to override the defaults which the @command{gcc} driver
-program uses when determining what switches to pass to @command{cc1},
-@command{cc1plus}, @command{as}, @command{ld}, etc. More than one
-@option{-specs=@var{file}} can be specified on the command line, and they
-are processed in order, from left to right.
-
-@item --sysroot=@var{dir}
-@opindex sysroot
-Use @var{dir} as the logical root directory for headers and libraries.
-For example, if the compiler normally searches for headers in
-@file{/usr/include} and libraries in @file{/usr/lib}, it instead
-searches @file{@var{dir}/usr/include} and @file{@var{dir}/usr/lib}.
-
-If you use both this option and the @option{-isysroot} option, then
-the @option{--sysroot} option applies to libraries, but the
-@option{-isysroot} option applies to header files.
-
-The GNU linker (beginning with version 2.16) has the necessary support
-for this option. If your linker does not support this option, the
-header file aspect of @option{--sysroot} still works, but the
-library aspect does not.
-
-@item --no-sysroot-suffix
-@opindex no-sysroot-suffix
-For some targets, a suffix is added to the root directory specified
-with @option{--sysroot}, depending on the other options used, so that
-headers may for example be found in
-@file{@var{dir}/@var{suffix}/usr/include} instead of
-@file{@var{dir}/usr/include}. This option disables the addition of
-such a suffix.
-
-@item -I-
-@opindex I-
-This option has been deprecated. Please use @option{-iquote} instead for
-@option{-I} directories before the @option{-I-} and remove the @option{-I-}.
-Any directories you specify with @option{-I} options before the @option{-I-}
-option are searched only for the case of @samp{#include "@var{file}"};
-they are not searched for @samp{#include <@var{file}>}.
-
-If additional directories are specified with @option{-I} options after
-the @option{-I-}, these directories are searched for all @samp{#include}
-directives. (Ordinarily @emph{all} @option{-I} directories are used
-this way.)
-
-In addition, the @option{-I-} option inhibits the use of the current
-directory (where the current input file came from) as the first search
-directory for @samp{#include "@var{file}"}. There is no way to
-override this effect of @option{-I-}. With @option{-I.} you can specify
-searching the directory that is current when the compiler is
-invoked. That is not exactly the same as what the preprocessor does
-by default, but it is often satisfactory.
-
-@option{-I-} does not inhibit the use of the standard system directories
-for header files. Thus, @option{-I-} and @option{-nostdinc} are
-independent.
-@end table
-
-@c man end
-
-@node Spec Files
-@section Specifying subprocesses and the switches to pass to them
-@cindex Spec Files
-
-@command{gcc} is a driver program. It performs its job by invoking a
-sequence of other programs to do the work of compiling, assembling and
-linking. GCC interprets its command-line parameters and uses these to
-deduce which programs it should invoke, and which command-line options
-it ought to place on their command lines. This behavior is controlled
-by @dfn{spec strings}. In most cases there is one spec string for each
-program that GCC can invoke, but a few programs have multiple spec
-strings to control their behavior. The spec strings built into GCC can
-be overridden by using the @option{-specs=} command-line switch to specify
-a spec file.
-
-@dfn{Spec files} are plaintext files that are used to construct spec
-strings. They consist of a sequence of directives separated by blank
-lines. The type of directive is determined by the first non-whitespace
-character on the line, which can be one of the following:
-
-@table @code
-@item %@var{command}
-Issues a @var{command} to the spec file processor. The commands that can
-appear here are:
-
-@table @code
-@item %include <@var{file}>
-@cindex @code{%include}
-Search for @var{file} and insert its text at the current point in the
-specs file.
-
-@item %include_noerr <@var{file}>
-@cindex @code{%include_noerr}
-Just like @samp{%include}, but do not generate an error message if the include
-file cannot be found.
-
-@item %rename @var{old_name} @var{new_name}
-@cindex @code{%rename}
-Rename the spec string @var{old_name} to @var{new_name}.
-
-@end table
-
-@item *[@var{spec_name}]:
-This tells the compiler to create, override or delete the named spec
-string. All lines after this directive up to the next directive or
-blank line are considered to be the text for the spec string. If this
-results in an empty string then the spec is deleted. (Or, if the
-spec did not exist, then nothing happens.) Otherwise, if the spec
-does not currently exist a new spec is created. If the spec does
-exist then its contents are overridden by the text of this
-directive, unless the first character of that text is the @samp{+}
-character, in which case the text is appended to the spec.
-
-@item [@var{suffix}]:
-Creates a new @samp{[@var{suffix}] spec} pair. All lines after this directive
-and up to the next directive or blank line are considered to make up the
-spec string for the indicated suffix. When the compiler encounters an
-input file with the named suffix, it processes the spec string in
-order to work out how to compile that file. For example:
-
-@smallexample
-.ZZ:
-z-compile -input %i
-@end smallexample
-
-This says that any input file whose name ends in @samp{.ZZ} should be
-passed to the program @samp{z-compile}, which should be invoked with the
-command-line switch @option{-input} and with the result of performing the
-@samp{%i} substitution. (See below.)
-
-As an alternative to providing a spec string, the text following a
-suffix directive can be one of the following:
-
-@table @code
-@item @@@var{language}
-This says that the suffix is an alias for a known @var{language}. This is
-similar to using the @option{-x} command-line switch to GCC to specify a
-language explicitly. For example:
-
-@smallexample
-.ZZ:
-@@c++
-@end smallexample
-
-Says that .ZZ files are, in fact, C++ source files.
-
-@item #@var{name}
-This causes an error messages saying:
-
-@smallexample
-@var{name} compiler not installed on this system.
-@end smallexample
-@end table
-
-GCC already has an extensive list of suffixes built into it.
-This directive adds an entry to the end of the list of suffixes, but
-since the list is searched from the end backwards, it is effectively
-possible to override earlier entries using this technique.
-
-@end table
-
-GCC has the following spec strings built into it. Spec files can
-override these strings or create their own. Note that individual
-targets can also add their own spec strings to this list.
-
-@smallexample
-asm Options to pass to the assembler
-asm_final Options to pass to the assembler post-processor
-cpp Options to pass to the C preprocessor
-cc1 Options to pass to the C compiler
-cc1plus Options to pass to the C++ compiler
-endfile Object files to include at the end of the link
-link Options to pass to the linker
-lib Libraries to include on the command line to the linker
-libgcc Decides which GCC support library to pass to the linker
-linker Sets the name of the linker
-predefines Defines to be passed to the C preprocessor
-signed_char Defines to pass to CPP to say whether @code{char} is signed
- by default
-startfile Object files to include at the start of the link
-@end smallexample
-
-Here is a small example of a spec file:
-
-@smallexample
-%rename lib old_lib
-
-*lib:
---start-group -lgcc -lc -leval1 --end-group %(old_lib)
-@end smallexample
-
-This example renames the spec called @samp{lib} to @samp{old_lib} and
-then overrides the previous definition of @samp{lib} with a new one.
-The new definition adds in some extra command-line options before
-including the text of the old definition.
-
-@dfn{Spec strings} are a list of command-line options to be passed to their
-corresponding program. In addition, the spec strings can contain
-@samp{%}-prefixed sequences to substitute variable text or to
-conditionally insert text into the command line. Using these constructs
-it is possible to generate quite complex command lines.
-
-Here is a table of all defined @samp{%}-sequences for spec
-strings. Note that spaces are not generated automatically around the
-results of expanding these sequences. Therefore you can concatenate them
-together or combine them with constant text in a single argument.
-
-@table @code
-@item %%
-Substitute one @samp{%} into the program name or argument.
-
-@item %i
-Substitute the name of the input file being processed.
-
-@item %b
-Substitute the basename of the input file being processed.
-This is the substring up to (and not including) the last period
-and not including the directory.
-
-@item %B
-This is the same as @samp{%b}, but include the file suffix (text after
-the last period).
-
-@item %d
-Marks the argument containing or following the @samp{%d} as a
-temporary file name, so that that file is deleted if GCC exits
-successfully. Unlike @samp{%g}, this contributes no text to the
-argument.
-
-@item %g@var{suffix}
-Substitute a file name that has suffix @var{suffix} and is chosen
-once per compilation, and mark the argument in the same way as
-@samp{%d}. To reduce exposure to denial-of-service attacks, the file
-name is now chosen in a way that is hard to predict even when previously
-chosen file names are known. For example, @samp{%g.s @dots{} %g.o @dots{} %g.s}
-might turn into @samp{ccUVUUAU.s ccXYAXZ12.o ccUVUUAU.s}. @var{suffix} matches
-the regexp @samp{[.A-Za-z]*} or the special string @samp{%O}, which is
-treated exactly as if @samp{%O} had been preprocessed. Previously, @samp{%g}
-was simply substituted with a file name chosen once per compilation,
-without regard to any appended suffix (which was therefore treated
-just like ordinary text), making such attacks more likely to succeed.
-
-@item %u@var{suffix}
-Like @samp{%g}, but generates a new temporary file name
-each time it appears instead of once per compilation.
-
-@item %U@var{suffix}
-Substitutes the last file name generated with @samp{%u@var{suffix}}, generating a
-new one if there is no such last file name. In the absence of any
-@samp{%u@var{suffix}}, this is just like @samp{%g@var{suffix}}, except they don't share
-the same suffix @emph{space}, so @samp{%g.s @dots{} %U.s @dots{} %g.s @dots{} %U.s}
-involves the generation of two distinct file names, one
-for each @samp{%g.s} and another for each @samp{%U.s}. Previously, @samp{%U} was
-simply substituted with a file name chosen for the previous @samp{%u},
-without regard to any appended suffix.
-
-@item %j@var{suffix}
-Substitutes the name of the @code{HOST_BIT_BUCKET}, if any, and if it is
-writable, and if @option{-save-temps} is not used;
-otherwise, substitute the name
-of a temporary file, just like @samp{%u}. This temporary file is not
-meant for communication between processes, but rather as a junk
-disposal mechanism.
-
-@item %|@var{suffix}
-@itemx %m@var{suffix}
-Like @samp{%g}, except if @option{-pipe} is in effect. In that case
-@samp{%|} substitutes a single dash and @samp{%m} substitutes nothing at
-all. These are the two most common ways to instruct a program that it
-should read from standard input or write to standard output. If you
-need something more elaborate you can use an @samp{%@{pipe:@code{X}@}}
-construct: see for example @file{f/lang-specs.h}.
-
-@item %.@var{SUFFIX}
-Substitutes @var{.SUFFIX} for the suffixes of a matched switch's args
-when it is subsequently output with @samp{%*}. @var{SUFFIX} is
-terminated by the next space or %.
-
-@item %w
-Marks the argument containing or following the @samp{%w} as the
-designated output file of this compilation. This puts the argument
-into the sequence of arguments that @samp{%o} substitutes.
-
-@item %o
-Substitutes the names of all the output files, with spaces
-automatically placed around them. You should write spaces
-around the @samp{%o} as well or the results are undefined.
-@samp{%o} is for use in the specs for running the linker.
-Input files whose names have no recognized suffix are not compiled
-at all, but they are included among the output files, so they are
-linked.
-
-@item %O
-Substitutes the suffix for object files. Note that this is
-handled specially when it immediately follows @samp{%g, %u, or %U},
-because of the need for those to form complete file names. The
-handling is such that @samp{%O} is treated exactly as if it had already
-been substituted, except that @samp{%g, %u, and %U} do not currently
-support additional @var{suffix} characters following @samp{%O} as they do
-following, for example, @samp{.o}.
-
-@item %p
-Substitutes the standard macro predefinitions for the
-current target machine. Use this when running @code{cpp}.
-
-@item %P
-Like @samp{%p}, but puts @samp{__} before and after the name of each
-predefined macro, except for macros that start with @samp{__} or with
-@samp{_@var{L}}, where @var{L} is an uppercase letter. This is for ISO
-C@.
-
-@item %I
-Substitute any of @option{-iprefix} (made from @env{GCC_EXEC_PREFIX}),
-@option{-isysroot} (made from @env{TARGET_SYSTEM_ROOT}),
-@option{-isystem} (made from @env{COMPILER_PATH} and @option{-B} options)
-and @option{-imultilib} as necessary.
-
-@item %s
-Current argument is the name of a library or startup file of some sort.
-Search for that file in a standard list of directories and substitute
-the full name found. The current working directory is included in the
-list of directories scanned.
-
-@item %T
-Current argument is the name of a linker script. Search for that file
-in the current list of directories to scan for libraries. If the file
-is located insert a @option{--script} option into the command line
-followed by the full path name found. If the file is not found then
-generate an error message. Note: the current working directory is not
-searched.
-
-@item %e@var{str}
-Print @var{str} as an error message. @var{str} is terminated by a newline.
-Use this when inconsistent options are detected.
-
-@item %(@var{name})
-Substitute the contents of spec string @var{name} at this point.
-
-@item %x@{@var{option}@}
-Accumulate an option for @samp{%X}.
-
-@item %X
-Output the accumulated linker options specified by @option{-Wl} or a @samp{%x}
-spec string.
-
-@item %Y
-Output the accumulated assembler options specified by @option{-Wa}.
-
-@item %Z
-Output the accumulated preprocessor options specified by @option{-Wp}.
-
-@item %a
-Process the @code{asm} spec. This is used to compute the
-switches to be passed to the assembler.
-
-@item %A
-Process the @code{asm_final} spec. This is a spec string for
-passing switches to an assembler post-processor, if such a program is
-needed.
-
-@item %l
-Process the @code{link} spec. This is the spec for computing the
-command line passed to the linker. Typically it makes use of the
-@samp{%L %G %S %D and %E} sequences.
-
-@item %D
-Dump out a @option{-L} option for each directory that GCC believes might
-contain startup files. If the target supports multilibs then the
-current multilib directory is prepended to each of these paths.
-
-@item %L
-Process the @code{lib} spec. This is a spec string for deciding which
-libraries are included on the command line to the linker.
-
-@item %G
-Process the @code{libgcc} spec. This is a spec string for deciding
-which GCC support library is included on the command line to the linker.
-
-@item %S
-Process the @code{startfile} spec. This is a spec for deciding which
-object files are the first ones passed to the linker. Typically
-this might be a file named @file{crt0.o}.
-
-@item %E
-Process the @code{endfile} spec. This is a spec string that specifies
-the last object files that are passed to the linker.
-
-@item %C
-Process the @code{cpp} spec. This is used to construct the arguments
-to be passed to the C preprocessor.
-
-@item %1
-Process the @code{cc1} spec. This is used to construct the options to be
-passed to the actual C compiler (@samp{cc1}).
-
-@item %2
-Process the @code{cc1plus} spec. This is used to construct the options to be
-passed to the actual C++ compiler (@samp{cc1plus}).
-
-@item %*
-Substitute the variable part of a matched option. See below.
-Note that each comma in the substituted string is replaced by
-a single space.
-
-@item %<@code{S}
-Remove all occurrences of @code{-S} from the command line. Note---this
-command is position dependent. @samp{%} commands in the spec string
-before this one see @code{-S}, @samp{%} commands in the spec string
-after this one do not.
-
-@item %:@var{function}(@var{args})
-Call the named function @var{function}, passing it @var{args}.
-@var{args} is first processed as a nested spec string, then split
-into an argument vector in the usual fashion. The function returns
-a string which is processed as if it had appeared literally as part
-of the current spec.
-
-The following built-in spec functions are provided:
-
-@table @code
-@item @code{getenv}
-The @code{getenv} spec function takes two arguments: an environment
-variable name and a string. If the environment variable is not
-defined, a fatal error is issued. Otherwise, the return value is the
-value of the environment variable concatenated with the string. For
-example, if @env{TOPDIR} is defined as @file{/path/to/top}, then:
-
-@smallexample
-%:getenv(TOPDIR /include)
-@end smallexample
-
-expands to @file{/path/to/top/include}.
-
-@item @code{if-exists}
-The @code{if-exists} spec function takes one argument, an absolute
-pathname to a file. If the file exists, @code{if-exists} returns the
-pathname. Here is a small example of its usage:
-
-@smallexample
-*startfile:
-crt0%O%s %:if-exists(crti%O%s) crtbegin%O%s
-@end smallexample
-
-@item @code{if-exists-else}
-The @code{if-exists-else} spec function is similar to the @code{if-exists}
-spec function, except that it takes two arguments. The first argument is
-an absolute pathname to a file. If the file exists, @code{if-exists-else}
-returns the pathname. If it does not exist, it returns the second argument.
-This way, @code{if-exists-else} can be used to select one file or another,
-based on the existence of the first. Here is a small example of its usage:
-
-@smallexample
-*startfile:
-crt0%O%s %:if-exists(crti%O%s) \
-%:if-exists-else(crtbeginT%O%s crtbegin%O%s)
-@end smallexample
-
-@item @code{replace-outfile}
-The @code{replace-outfile} spec function takes two arguments. It looks for the
-first argument in the outfiles array and replaces it with the second argument. Here
-is a small example of its usage:
-
-@smallexample
-%@{fgnu-runtime:%:replace-outfile(-lobjc -lobjc-gnu)@}
-@end smallexample
-
-@item @code{remove-outfile}
-The @code{remove-outfile} spec function takes one argument. It looks for the
-first argument in the outfiles array and removes it. Here is a small example
-its usage:
-
-@smallexample
-%:remove-outfile(-lm)
-@end smallexample
-
-@item @code{pass-through-libs}
-The @code{pass-through-libs} spec function takes any number of arguments. It
-finds any @option{-l} options and any non-options ending in @file{.a} (which it
-assumes are the names of linker input library archive files) and returns a
-result containing all the found arguments each prepended by
-@option{-plugin-opt=-pass-through=} and joined by spaces. This list is
-intended to be passed to the LTO linker plugin.
-
-@smallexample
-%:pass-through-libs(%G %L %G)
-@end smallexample
-
-@item @code{print-asm-header}
-The @code{print-asm-header} function takes no arguments and simply
-prints a banner like:
-
-@smallexample
-Assembler options
-=================
-
-Use "-Wa,OPTION" to pass "OPTION" to the assembler.
-@end smallexample
-
-It is used to separate compiler options from assembler options
-in the @option{--target-help} output.
-@end table
-
-@item %@{@code{S}@}
-Substitutes the @code{-S} switch, if that switch is given to GCC@.
-If that switch is not specified, this substitutes nothing. Note that
-the leading dash is omitted when specifying this option, and it is
-automatically inserted if the substitution is performed. Thus the spec
-string @samp{%@{foo@}} matches the command-line option @option{-foo}
-and outputs the command-line option @option{-foo}.
-
-@item %W@{@code{S}@}
-Like %@{@code{S}@} but mark last argument supplied within as a file to be
-deleted on failure.
-
-@item %@{@code{S}*@}
-Substitutes all the switches specified to GCC whose names start
-with @code{-S}, but which also take an argument. This is used for
-switches like @option{-o}, @option{-D}, @option{-I}, etc.
-GCC considers @option{-o foo} as being
-one switch whose name starts with @samp{o}. %@{o*@} substitutes this
-text, including the space. Thus two arguments are generated.
-
-@item %@{@code{S}*&@code{T}*@}
-Like %@{@code{S}*@}, but preserve order of @code{S} and @code{T} options
-(the order of @code{S} and @code{T} in the spec is not significant).
-There can be any number of ampersand-separated variables; for each the
-wild card is optional. Useful for CPP as @samp{%@{D*&U*&A*@}}.
-
-@item %@{@code{S}:@code{X}@}
-Substitutes @code{X}, if the @option{-S} switch is given to GCC@.
-
-@item %@{!@code{S}:@code{X}@}
-Substitutes @code{X}, if the @option{-S} switch is @emph{not} given to GCC@.
-
-@item %@{@code{S}*:@code{X}@}
-Substitutes @code{X} if one or more switches whose names start with
-@code{-S} are specified to GCC@. Normally @code{X} is substituted only
-once, no matter how many such switches appeared. However, if @code{%*}
-appears somewhere in @code{X}, then @code{X} is substituted once
-for each matching switch, with the @code{%*} replaced by the part of
-that switch matching the @code{*}.
-
-@item %@{.@code{S}:@code{X}@}
-Substitutes @code{X}, if processing a file with suffix @code{S}.
-
-@item %@{!.@code{S}:@code{X}@}
-Substitutes @code{X}, if @emph{not} processing a file with suffix @code{S}.
-
-@item %@{,@code{S}:@code{X}@}
-Substitutes @code{X}, if processing a file for language @code{S}.
-
-@item %@{!,@code{S}:@code{X}@}
-Substitutes @code{X}, if not processing a file for language @code{S}.
-
-@item %@{@code{S}|@code{P}:@code{X}@}
-Substitutes @code{X} if either @code{-S} or @code{-P} is given to
-GCC@. This may be combined with @samp{!}, @samp{.}, @samp{,}, and
-@code{*} sequences as well, although they have a stronger binding than
-the @samp{|}. If @code{%*} appears in @code{X}, all of the
-alternatives must be starred, and only the first matching alternative
-is substituted.
-
-For example, a spec string like this:
-
-@smallexample
-%@{.c:-foo@} %@{!.c:-bar@} %@{.c|d:-baz@} %@{!.c|d:-boggle@}
-@end smallexample
-
-@noindent
-outputs the following command-line options from the following input
-command-line options:
-
-@smallexample
-fred.c -foo -baz
-jim.d -bar -boggle
--d fred.c -foo -baz -boggle
--d jim.d -bar -baz -boggle
-@end smallexample
-
-@item %@{S:X; T:Y; :D@}
-
-If @code{S} is given to GCC, substitutes @code{X}; else if @code{T} is
-given to GCC, substitutes @code{Y}; else substitutes @code{D}. There can
-be as many clauses as you need. This may be combined with @code{.},
-@code{,}, @code{!}, @code{|}, and @code{*} as needed.
-
-
-@end table
-
-The conditional text @code{X} in a %@{@code{S}:@code{X}@} or similar
-construct may contain other nested @samp{%} constructs or spaces, or
-even newlines. They are processed as usual, as described above.
-Trailing white space in @code{X} is ignored. White space may also
-appear anywhere on the left side of the colon in these constructs,
-except between @code{.} or @code{*} and the corresponding word.
-
-The @option{-O}, @option{-f}, @option{-m}, and @option{-W} switches are
-handled specifically in these constructs. If another value of
-@option{-O} or the negated form of a @option{-f}, @option{-m}, or
-@option{-W} switch is found later in the command line, the earlier
-switch value is ignored, except with @{@code{S}*@} where @code{S} is
-just one letter, which passes all matching options.
-
-The character @samp{|} at the beginning of the predicate text is used to
-indicate that a command should be piped to the following command, but
-only if @option{-pipe} is specified.
-
-It is built into GCC which switches take arguments and which do not.
-(You might think it would be useful to generalize this to allow each
-compiler's spec to say which switches take arguments. But this cannot
-be done in a consistent fashion. GCC cannot even decide which input
-files have been specified without knowing which switches take arguments,
-and it must know which input files to compile in order to tell which
-compilers to run).
-
-GCC also knows implicitly that arguments starting in @option{-l} are to be
-treated as compiler output files, and passed to the linker in their
-proper position among the other output files.
-
-@c man begin OPTIONS
-
-@node Target Options
-@section Specifying Target Machine and Compiler Version
-@cindex target options
-@cindex cross compiling
-@cindex specifying machine version
-@cindex specifying compiler version and target machine
-@cindex compiler version, specifying
-@cindex target machine, specifying
-
-The usual way to run GCC is to run the executable called @command{gcc}, or
-@command{@var{machine}-gcc} when cross-compiling, or
-@command{@var{machine}-gcc-@var{version}} to run a version other than the
-one that was installed last.
-
-@node Submodel Options
-@section Hardware Models and Configurations
-@cindex submodel options
-@cindex specifying hardware config
-@cindex hardware models and configurations, specifying
-@cindex machine dependent options
-
-Each target machine types can have its own
-special options, starting with @samp{-m}, to choose among various
-hardware models or configurations---for example, 68010 vs 68020,
-floating coprocessor or none. A single installed version of the
-compiler can compile for any model or configuration, according to the
-options specified.
-
-Some configurations of the compiler also support additional special
-options, usually for compatibility with other compilers on the same
-platform.
-
-@c This list is ordered alphanumerically by subsection name.
-@c It should be the same order and spelling as these options are listed
-@c in Machine Dependent Options
-
-@menu
-* AArch64 Options::
-* Adapteva Epiphany Options::
-* ARM Options::
-* AVR Options::
-* Blackfin Options::
-* C6X Options::
-* CRIS Options::
-* CR16 Options::
-* Darwin Options::
-* DEC Alpha Options::
-* FR30 Options::
-* FRV Options::
-* GNU/Linux Options::
-* H8/300 Options::
-* HPPA Options::
-* i386 and x86-64 Options::
-* i386 and x86-64 Windows Options::
-* IA-64 Options::
-* LM32 Options::
-* M32C Options::
-* M32R/D Options::
-* M680x0 Options::
-* MCore Options::
-* MeP Options::
-* MicroBlaze Options::
-* MIPS Options::
-* MMIX Options::
-* MN10300 Options::
-* Moxie Options::
-* PDP-11 Options::
-* picoChip Options::
-* PowerPC Options::
-* RL78 Options::
-* RS/6000 and PowerPC Options::
-* RX Options::
-* S/390 and zSeries Options::
-* Score Options::
-* SH Options::
-* Solaris 2 Options::
-* SPARC Options::
-* SPU Options::
-* System V Options::
-* TILE-Gx Options::
-* TILEPro Options::
-* V850 Options::
-* VAX Options::
-* VMS Options::
-* VxWorks Options::
-* x86-64 Options::
-* Xstormy16 Options::
-* Xtensa Options::
-* zSeries Options::
-@end menu
-
-@node AArch64 Options
-@subsection AArch64 Options
-@cindex AArch64 Options
-
-These options are defined for AArch64 implementations:
-
-@table @gcctabopt
-
-@item -mbig-endian
-@opindex mbig-endian
-Generate big-endian code. This is the default when GCC is configured for an
-@samp{aarch64_be-*-*} target.
-
-@item -mgeneral-regs-only
-@opindex mgeneral-regs-only
-Generate code which uses only the general registers.
-
-@item -mlittle-endian
-@opindex mlittle-endian
-Generate little-endian code. This is the default when GCC is configured for an
-@samp{aarch64-*-*} but not an @samp{aarch64_be-*-*} target.
-
-@item -mcmodel=tiny
-@opindex mcmodel=tiny
-Generate code for the tiny code model. The program and its statically defined
-symbols must be within 1GB of each other. Pointers are 64 bits. Programs can
-be statically or dynamically linked. This model is not fully implemented and
-mostly treated as @samp{small}.
-
-@item -mcmodel=small
-@opindex mcmodel=small
-Generate code for the small code model. The program and its statically defined
-symbols must be within 4GB of each other. Pointers are 64 bits. Programs can
-be statically or dynamically linked. This is the default code model.
-
-@item -mcmodel=large
-@opindex mcmodel=large
-Generate code for the large code model. This makes no assumptions about
-addresses and sizes of sections. Pointers are 64 bits. Programs can be
-statically linked only.
-
-@item -mstrict-align
-@opindex mstrict-align
-Do not assume that unaligned memory references will be handled by the system.
-
-@item -momit-leaf-frame-pointer
-@itemx -mno-omit-leaf-frame-pointer
-@opindex momit-leaf-frame-pointer
-@opindex mno-omit-leaf-frame-pointer
-Omit or keep the frame pointer in leaf functions. The former behaviour is the
-default.
-
-@item -mtls-dialect=desc
-@opindex mtls-dialect=desc
-Use TLS descriptors as the thread-local storage mechanism for dynamic accesses
-of TLS variables. This is the default.
-
-@item -mtls-dialect=traditional
-@opindex mtls-dialect=traditional
-Use traditional TLS as the thread-local storage mechanism for dynamic accesses
-of TLS variables.
-
-@item -march=@var{name}
-@opindex march
-Specify the name of the target architecture, optionally suffixed by one or
-more feature modifiers. This option has the form
-@option{-march=@var{arch}@r{@{}+@r{[}no@r{]}@var{feature}@r{@}*}}, where the
-only value for @var{arch} is @samp{armv8-a}. The possible values for
-@var{feature} are documented in the sub-section below.
-
-Where conflicting feature modifiers are specified, the right-most feature is
-used.
-
-GCC uses this name to determine what kind of instructions it can emit when
-generating assembly code. This option can be used in conjunction with or
-instead of the @option{-mcpu=} option.
-
-@item -mcpu=@var{name}
-@opindex mcpu
-Specify the name of the target processor, optionally suffixed by one or more
-feature modifiers. This option has the form
-@option{-mcpu=@var{cpu}@r{@{}+@r{[}no@r{]}@var{feature}@r{@}*}}, where the
-possible values for @var{cpu} are @samp{generic}, @samp{large}. The
-possible values for @var{feature} are documented in the sub-section
-below.
-
-Where conflicting feature modifiers are specified, the right-most feature is
-used.
-
-GCC uses this name to determine what kind of instructions it can emit when
-generating assembly code.
-
-@item -mtune=@var{name}
-@opindex mtune
-Specify the name of the processor to tune the performance for. The code will
-be tuned as if the target processor were of the type specified in this option,
-but still using instructions compatible with the target processor specified
-by a @option{-mcpu=} option. This option cannot be suffixed by feature
-modifiers.
-
-@end table
-
-@subsubsection @option{-march} and @option{-mcpu} feature modifiers
-@cindex @option{-march} feature modifiers
-@cindex @option{-mcpu} feature modifiers
-Feature modifiers used with @option{-march} and @option{-mcpu} can be one
-the following:
-
-@table @samp
-@item crypto
-Enable Crypto extension. This implies Advanced SIMD is enabled.
-@item fp
-Enable floating-point instructions.
-@item simd
-Enable Advanced SIMD instructions. This implies floating-point instructions
-are enabled. This is the default for all current possible values for options
-@option{-march} and @option{-mcpu=}.
-@end table
-
-@node Adapteva Epiphany Options
-@subsection Adapteva Epiphany Options
-
-These @samp{-m} options are defined for Adapteva Epiphany:
-
-@table @gcctabopt
-@item -mhalf-reg-file
-@opindex mhalf-reg-file
-Don't allocate any register in the range @code{r32}@dots{}@code{r63}.
-That allows code to run on hardware variants that lack these registers.
-
-@item -mprefer-short-insn-regs
-@opindex mprefer-short-insn-regs
-Preferrentially allocate registers that allow short instruction generation.
-This can result in increased instruction count, so this may either reduce or
-increase overall code size.
-
-@item -mbranch-cost=@var{num}
-@opindex mbranch-cost
-Set the cost of branches to roughly @var{num} ``simple'' instructions.
-This cost is only a heuristic and is not guaranteed to produce
-consistent results across releases.
-
-@item -mcmove
-@opindex mcmove
-Enable the generation of conditional moves.
-
-@item -mnops=@var{num}
-@opindex mnops
-Emit @var{num} NOPs before every other generated instruction.
-
-@item -mno-soft-cmpsf
-@opindex mno-soft-cmpsf
-For single-precision floating-point comparisons, emit an @code{fsub} instruction
-and test the flags. This is faster than a software comparison, but can
-get incorrect results in the presence of NaNs, or when two different small
-numbers are compared such that their difference is calculated as zero.
-The default is @option{-msoft-cmpsf}, which uses slower, but IEEE-compliant,
-software comparisons.
-
-@item -mstack-offset=@var{num}
-@opindex mstack-offset
-Set the offset between the top of the stack and the stack pointer.
-E.g., a value of 8 means that the eight bytes in the range @code{sp+0@dots{}sp+7}
-can be used by leaf functions without stack allocation.
-Values other than @samp{8} or @samp{16} are untested and unlikely to work.
-Note also that this option changes the ABI; compiling a program with a
-different stack offset than the libraries have been compiled with
-generally does not work.
-This option can be useful if you want to evaluate if a different stack
-offset would give you better code, but to actually use a different stack
-offset to build working programs, it is recommended to configure the
-toolchain with the appropriate @option{--with-stack-offset=@var{num}} option.
-
-@item -mno-round-nearest
-@opindex mno-round-nearest
-Make the scheduler assume that the rounding mode has been set to
-truncating. The default is @option{-mround-nearest}.
-
-@item -mlong-calls
-@opindex mlong-calls
-If not otherwise specified by an attribute, assume all calls might be beyond
-the offset range of the @code{b} / @code{bl} instructions, and therefore load the
-function address into a register before performing a (otherwise direct) call.
-This is the default.
-
-@item -mshort-calls
-@opindex short-calls
-If not otherwise specified by an attribute, assume all direct calls are
-in the range of the @code{b} / @code{bl} instructions, so use these instructions
-for direct calls. The default is @option{-mlong-calls}.
-
-@item -msmall16
-@opindex msmall16
-Assume addresses can be loaded as 16-bit unsigned values. This does not
-apply to function addresses for which @option{-mlong-calls} semantics
-are in effect.
-
-@item -mfp-mode=@var{mode}
-@opindex mfp-mode
-Set the prevailing mode of the floating-point unit.
-This determines the floating-point mode that is provided and expected
-at function call and return time. Making this mode match the mode you
-predominantly need at function start can make your programs smaller and
-faster by avoiding unnecessary mode switches.
-
-@var{mode} can be set to one the following values:
-
-@table @samp
-@item caller
-Any mode at function entry is valid, and retained or restored when
-the function returns, and when it calls other functions.
-This mode is useful for compiling libraries or other compilation units
-you might want to incorporate into different programs with different
-prevailing FPU modes, and the convenience of being able to use a single
-object file outweighs the size and speed overhead for any extra
-mode switching that might be needed, compared with what would be needed
-with a more specific choice of prevailing FPU mode.
-
-@item truncate
-This is the mode used for floating-point calculations with
-truncating (i.e.@: round towards zero) rounding mode. That includes
-conversion from floating point to integer.
-
-@item round-nearest
-This is the mode used for floating-point calculations with
-round-to-nearest-or-even rounding mode.
-
-@item int
-This is the mode used to perform integer calculations in the FPU, e.g.@:
-integer multiply, or integer multiply-and-accumulate.
-@end table
-
-The default is @option{-mfp-mode=caller}
-
-@item -mnosplit-lohi
-@itemx -mno-postinc
-@itemx -mno-postmodify
-@opindex mnosplit-lohi
-@opindex mno-postinc
-@opindex mno-postmodify
-Code generation tweaks that disable, respectively, splitting of 32-bit
-loads, generation of post-increment addresses, and generation of
-post-modify addresses. The defaults are @option{msplit-lohi},
-@option{-mpost-inc}, and @option{-mpost-modify}.
-
-@item -mnovect-double
-@opindex mno-vect-double
-Change the preferred SIMD mode to SImode. The default is
-@option{-mvect-double}, which uses DImode as preferred SIMD mode.
-
-@item -max-vect-align=@var{num}
-@opindex max-vect-align
-The maximum alignment for SIMD vector mode types.
-@var{num} may be 4 or 8. The default is 8.
-Note that this is an ABI change, even though many library function
-interfaces are unaffected if they don't use SIMD vector modes
-in places that affect size and/or alignment of relevant types.
-
-@item -msplit-vecmove-early
-@opindex msplit-vecmove-early
-Split vector moves into single word moves before reload. In theory this
-can give better register allocation, but so far the reverse seems to be
-generally the case.
-
-@item -m1reg-@var{reg}
-@opindex m1reg-
-Specify a register to hold the constant @minus{}1, which makes loading small negative
-constants and certain bitmasks faster.
-Allowable values for @var{reg} are @samp{r43} and @samp{r63},
-which specify use of that register as a fixed register,
-and @samp{none}, which means that no register is used for this
-purpose. The default is @option{-m1reg-none}.
-
-@end table
-
-@node ARM Options
-@subsection ARM Options
-@cindex ARM options
-
-These @samp{-m} options are defined for Advanced RISC Machines (ARM)
-architectures:
-
-@table @gcctabopt
-@item -mabi=@var{name}
-@opindex mabi
-Generate code for the specified ABI@. Permissible values are: @samp{apcs-gnu},
-@samp{atpcs}, @samp{aapcs}, @samp{aapcs-linux} and @samp{iwmmxt}.
-
-@item -mapcs-frame
-@opindex mapcs-frame
-Generate a stack frame that is compliant with the ARM Procedure Call
-Standard for all functions, even if this is not strictly necessary for
-correct execution of the code. Specifying @option{-fomit-frame-pointer}
-with this option causes the stack frames not to be generated for
-leaf functions. The default is @option{-mno-apcs-frame}.
-
-@item -mapcs
-@opindex mapcs
-This is a synonym for @option{-mapcs-frame}.
-
-@ignore
-@c not currently implemented
-@item -mapcs-stack-check
-@opindex mapcs-stack-check
-Generate code to check the amount of stack space available upon entry to
-every function (that actually uses some stack space). If there is
-insufficient space available then either the function
-@samp{__rt_stkovf_split_small} or @samp{__rt_stkovf_split_big} is
-called, depending upon the amount of stack space required. The runtime
-system is required to provide these functions. The default is
-@option{-mno-apcs-stack-check}, since this produces smaller code.
-
-@c not currently implemented
-@item -mapcs-float
-@opindex mapcs-float
-Pass floating-point arguments using the floating-point registers. This is
-one of the variants of the APCS@. This option is recommended if the
-target hardware has a floating-point unit or if a lot of floating-point
-arithmetic is going to be performed by the code. The default is
-@option{-mno-apcs-float}, since the size of integer-only code is
-slightly increased if @option{-mapcs-float} is used.
-
-@c not currently implemented
-@item -mapcs-reentrant
-@opindex mapcs-reentrant
-Generate reentrant, position-independent code. The default is
-@option{-mno-apcs-reentrant}.
-@end ignore
-
-@item -mthumb-interwork
-@opindex mthumb-interwork
-Generate code that supports calling between the ARM and Thumb
-instruction sets. Without this option, on pre-v5 architectures, the
-two instruction sets cannot be reliably used inside one program. The
-default is @option{-mno-thumb-interwork}, since slightly larger code
-is generated when @option{-mthumb-interwork} is specified. In AAPCS
-configurations this option is meaningless.
-
-@item -mno-sched-prolog
-@opindex mno-sched-prolog
-Prevent the reordering of instructions in the function prologue, or the
-merging of those instruction with the instructions in the function's
-body. This means that all functions start with a recognizable set
-of instructions (or in fact one of a choice from a small set of
-different function prologues), and this information can be used to
-locate the start of 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 -mlittle-endian
-@opindex mlittle-endian
-Generate code for a processor running in little-endian mode. This is
-the default for all standard configurations.
-
-@item -mbig-endian
-@opindex mbig-endian
-Generate code for a processor running in big-endian mode; the default is
-to compile code for a little-endian processor.
-
-@item -mwords-little-endian
-@opindex mwords-little-endian
-This option only applies when generating code for big-endian processors.
-Generate code for a little-endian word order but a big-endian byte
-order. That is, a byte order of the form @samp{32107654}. Note: this
-option should only be used if you require compatibility with code for
-big-endian ARM processors generated by versions of the compiler prior to
-2.8. This option is now deprecated.
-
-@item -mcpu=@var{name}
-@opindex mcpu
-This specifies the name of the target ARM processor. GCC uses this name
-to determine what kind of instructions it can emit when generating
-assembly code. Permissible names are: @samp{arm2}, @samp{arm250},
-@samp{arm3}, @samp{arm6}, @samp{arm60}, @samp{arm600}, @samp{arm610},
-@samp{arm620}, @samp{arm7}, @samp{arm7m}, @samp{arm7d}, @samp{arm7dm},
-@samp{arm7di}, @samp{arm7dmi}, @samp{arm70}, @samp{arm700},
-@samp{arm700i}, @samp{arm710}, @samp{arm710c}, @samp{arm7100},
-@samp{arm720},
-@samp{arm7500}, @samp{arm7500fe}, @samp{arm7tdmi}, @samp{arm7tdmi-s},
-@samp{arm710t}, @samp{arm720t}, @samp{arm740t},
-@samp{strongarm}, @samp{strongarm110}, @samp{strongarm1100},
-@samp{strongarm1110},
-@samp{arm8}, @samp{arm810}, @samp{arm9}, @samp{arm9e}, @samp{arm920},
-@samp{arm920t}, @samp{arm922t}, @samp{arm946e-s}, @samp{arm966e-s},
-@samp{arm968e-s}, @samp{arm926ej-s}, @samp{arm940t}, @samp{arm9tdmi},
-@samp{arm10tdmi}, @samp{arm1020t}, @samp{arm1026ej-s},
-@samp{arm10e}, @samp{arm1020e}, @samp{arm1022e},
-@samp{arm1136j-s}, @samp{arm1136jf-s}, @samp{mpcore}, @samp{mpcorenovfp},
-@samp{arm1156t2-s}, @samp{arm1156t2f-s}, @samp{arm1176jz-s}, @samp{arm1176jzf-s},
-@samp{cortex-a5}, @samp{cortex-a7}, @samp{cortex-a8}, @samp{cortex-a9},
-@samp{cortex-a15}, @samp{cortex-r4}, @samp{cortex-r4f}, @samp{cortex-r5},
-@samp{cortex-m4}, @samp{cortex-m3},
-@samp{cortex-m1},
-@samp{cortex-m0},
-@samp{cortex-m0plus},
-@samp{marvell-pj4},
-@samp{xscale}, @samp{iwmmxt}, @samp{iwmmxt2}, @samp{ep9312},
-@samp{fa526}, @samp{fa626},
-@samp{fa606te}, @samp{fa626te}, @samp{fmp626}, @samp{fa726te}.
-
-
-@option{-mcpu=generic-@var{arch}} is also permissible, and is
-equivalent to @option{-march=@var{arch} -mtune=generic-@var{arch}}.
-See @option{-mtune} for more information.
-
-@option{-mcpu=native} causes the compiler to auto-detect the CPU
-of the build computer. At present, this feature is only supported on
-Linux, and not all architectures are recognized. If the auto-detect is
-unsuccessful the option has no effect.
-
-@item -mtune=@var{name}
-@opindex mtune
-This option is very similar to the @option{-mcpu=} option, except that
-instead of specifying the actual target processor type, and hence
-restricting which instructions can be used, it specifies that GCC should
-tune the performance of the code as if the target were of the type
-specified in this option, but still choosing the instructions it
-generates based on the CPU specified by a @option{-mcpu=} option.
-For some ARM implementations better performance can be obtained by using
-this option.
-
-@option{-mtune=generic-@var{arch}} specifies that GCC should tune the
-performance for a blend of processors within architecture @var{arch}.
-The aim is to generate code that run well on the current most popular
-processors, balancing between optimizations that benefit some CPUs in the
-range, and avoiding performance pitfalls of other CPUs. The effects of
-this option may change in future GCC versions as CPU models come and go.
-
-@option{-mtune=native} causes the compiler to auto-detect the CPU
-of the build computer. At present, this feature is only supported on
-Linux, and not all architectures are recognized. If the auto-detect is
-unsuccessful the option has no effect.
-
-@item -march=@var{name}
-@opindex march
-This specifies the name of the target ARM architecture. GCC uses this
-name to determine what kind of instructions it can emit when generating
-assembly code. This option can be used in conjunction with or instead
-of the @option{-mcpu=} option. Permissible names are: @samp{armv2},
-@samp{armv2a}, @samp{armv3}, @samp{armv3m}, @samp{armv4}, @samp{armv4t},
-@samp{armv5}, @samp{armv5t}, @samp{armv5e}, @samp{armv5te},
-@samp{armv6}, @samp{armv6j},
-@samp{armv6t2}, @samp{armv6z}, @samp{armv6zk}, @samp{armv6-m},
-@samp{armv7}, @samp{armv7-a}, @samp{armv7-r}, @samp{armv7-m},
-@samp{armv8-a},
-@samp{iwmmxt}, @samp{iwmmxt2}, @samp{ep9312}.
-
-@option{-march=native} causes the compiler to auto-detect the architecture
-of the build computer. At present, this feature is only supported on
-Linux, and not all architectures are recognized. If the auto-detect is
-unsuccessful the option has no effect.
-
-@item -mfpu=@var{name}
-@opindex mfpu
-This specifies what floating-point hardware (or hardware emulation) is
-available on the target. Permissible names are: @samp{vfp}, @samp{vfpv3},
-@samp{vfpv3-fp16}, @samp{vfpv3-d16}, @samp{vfpv3-d16-fp16}, @samp{vfpv3xd},
-@samp{vfpv3xd-fp16}, @samp{neon}, @samp{neon-fp16}, @samp{vfpv4},
-@samp{vfpv4-d16}, @samp{fpv4-sp-d16}, @samp{neon-vfpv4},
-@samp{fp-armv8}, @samp{neon-fp-armv8}, and @samp{crypto-neon-fp-armv8}.
-
-If @option{-msoft-float} is specified this specifies the format of
-floating-point values.
-
-If the selected floating-point hardware includes the NEON extension
-(e.g. @option{-mfpu}=@samp{neon}), note that floating-point
-operations are not generated by GCC's auto-vectorization pass unless
-@option{-funsafe-math-optimizations} is also specified. This is
-because NEON hardware does not fully implement the IEEE 754 standard for
-floating-point arithmetic (in particular denormal values are treated as
-zero), so the use of NEON instructions may lead to a loss of precision.
-
-@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. @xref{Half-Precision}, for more information.
-
-@item -mstructure-size-boundary=@var{n}
-@opindex mstructure-size-boundary
-The sizes of all structures and unions are rounded up to a multiple
-of the number of bits set by this option. Permissible values are 8, 32
-and 64. The default value varies for different toolchains. For the COFF
-targeted toolchain the default value is 8. A value of 64 is only allowed
-if the underlying ABI supports it.
-
-Specifying a larger number can produce faster, more efficient code, but
-can also increase the size of the program. Different values are potentially
-incompatible. Code compiled with one value cannot necessarily expect to
-work with code or libraries compiled with another value, if they exchange
-information using structures or unions.
-
-@item -mabort-on-noreturn
-@opindex mabort-on-noreturn
-Generate a call to the function @code{abort} at the end of a
-@code{noreturn} function. It is executed if the function tries to
-return.
-
-@item -mlong-calls
-@itemx -mno-long-calls
-@opindex mlong-calls
-@opindex mno-long-calls
-Tells the compiler to perform function calls by first loading the
-address of the function into a register and then performing a subroutine
-call on this register. This switch is needed if the target function
-lies outside of the 64-megabyte addressing range of the offset-based
-version of subroutine call instruction.
-
-Even if this switch is enabled, not all function calls are turned
-into long calls. The heuristic is that static functions, functions
-that have the @samp{short-call} attribute, functions that are inside
-the scope of a @samp{#pragma no_long_calls} directive, and functions whose
-definitions have already been compiled within the current compilation
-unit are not turned into long calls. The exceptions to this rule are
-that weak function definitions, functions with the @samp{long-call}
-attribute or the @samp{section} attribute, and functions that are within
-the scope of a @samp{#pragma long_calls} directive are always
-turned into long calls.
-
-This feature is not enabled by default. Specifying
-@option{-mno-long-calls} restores the default behavior, as does
-placing the function calls within the scope of a @samp{#pragma
-long_calls_off} directive. Note these switches have no effect on how
-the compiler generates code to handle function calls via function
-pointers.
-
-@item -msingle-pic-base
-@opindex msingle-pic-base
-Treat the register used for PIC addressing as read-only, rather than
-loading it in the prologue for each function. The runtime system is
-responsible for initializing this register with an appropriate value
-before execution begins.
-
-@item -mpic-register=@var{reg}
-@opindex mpic-register
-Specify the register to be used for PIC addressing. The default is R10
-unless stack-checking is enabled, when R9 is used.
-
-@item -mpoke-function-name
-@opindex mpoke-function-name
-Write the name of each function into the text section, directly
-preceding the function prologue. The generated code is similar to this:
-
-@smallexample
- t0
- .ascii "arm_poke_function_name", 0
- .align
- t1
- .word 0xff000000 + (t1 - t0)
- arm_poke_function_name
- mov ip, sp
- stmfd sp!, @{fp, ip, lr, pc@}
- sub fp, ip, #4
-@end smallexample
-
-When performing a stack backtrace, code can inspect the value of
-@code{pc} stored at @code{fp + 0}. If the trace function then looks at
-location @code{pc - 12} and the top 8 bits are set, then we know that
-there is a function name embedded immediately preceding this location
-and has length @code{((pc[-3]) & 0xff000000)}.
-
-@item -mthumb
-@itemx -marm
-@opindex marm
-@opindex mthumb
-
-Select between generating code that executes in ARM and Thumb
-states. The default for most configurations is to generate code
-that executes in ARM state, but the default can be changed by
-configuring GCC with the @option{--with-mode=}@var{state}
-configure option.
-
-@item -mtpcs-frame
-@opindex mtpcs-frame
-Generate a stack frame that is compliant with the Thumb Procedure Call
-Standard for all non-leaf functions. (A leaf function is one that does
-not call any other functions.) The default is @option{-mno-tpcs-frame}.
-
-@item -mtpcs-leaf-frame
-@opindex mtpcs-leaf-frame
-Generate a stack frame that is compliant with the Thumb Procedure Call
-Standard for all leaf functions. (A leaf function is one that does
-not call any other functions.) The default is @option{-mno-apcs-leaf-frame}.
-
-@item -mcallee-super-interworking
-@opindex mcallee-super-interworking
-Gives all externally visible functions in the file being compiled an ARM
-instruction set header which switches to Thumb mode before executing the
-rest of the function. This allows these functions to be called from
-non-interworking code. This option is not valid in AAPCS configurations
-because interworking is enabled by default.
-
-@item -mcaller-super-interworking
-@opindex mcaller-super-interworking
-Allows calls via function pointers (including virtual functions) to
-execute correctly regardless of whether the target code has been
-compiled for interworking or not. There is a small overhead in the cost
-of executing a function pointer if this option is enabled. This option
-is not valid in AAPCS configurations because interworking is enabled
-by default.
-
-@item -mtp=@var{name}
-@opindex mtp
-Specify the access model for the thread local storage pointer. The valid
-models are @option{soft}, which generates calls to @code{__aeabi_read_tp},
-@option{cp15}, which fetches the thread pointer from @code{cp15} directly
-(supported in the arm6k architecture), and @option{auto}, which uses the
-best available method for the selected processor. The default setting is
-@option{auto}.
-
-@item -mtls-dialect=@var{dialect}
-@opindex mtls-dialect
-Specify the dialect to use for accessing thread local storage. Two
-@var{dialect}s are supported---@samp{gnu} and @samp{gnu2}. The
-@samp{gnu} dialect selects the original GNU scheme for supporting
-local and global dynamic TLS models. The @samp{gnu2} dialect
-selects the GNU descriptor scheme, which provides better performance
-for shared libraries. The GNU descriptor scheme is compatible with
-the original scheme, but does require new assembler, linker and
-library support. Initial and local exec TLS models are unaffected by
-this option and always use the original scheme.
-
-@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, and when @option{-fpic} or @option{-fPIC}
-is specified.
-
-@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.
-
-@item -munaligned-access
-@itemx -mno-unaligned-access
-@opindex munaligned-access
-@opindex mno-unaligned-access
-Enables (or disables) reading and writing of 16- and 32- bit values
-from addresses that are not 16- or 32- bit aligned. By default
-unaligned access is disabled for all pre-ARMv6 and all ARMv6-M
-architectures, and enabled for all other architectures. If unaligned
-access is not enabled then words in packed data structures will be
-accessed a byte at a time.
-
-The ARM attribute @code{Tag_CPU_unaligned_access} will be set in the
-generated object file to either true or false, depending upon the
-setting of this option. If unaligned access is enabled then the
-preprocessor symbol @code{__ARM_FEATURE_UNALIGNED} will also be
-defined.
-
-@end table
-
-@node AVR Options
-@subsection AVR Options
-@cindex AVR Options
-
-These options are defined for AVR implementations:
-
-@table @gcctabopt
-@item -mmcu=@var{mcu}
-@opindex mmcu
-Specify Atmel AVR instruction set architectures (ISA) or MCU type.
-
-The default for this option is@tie{}@code{avr2}.
-
-GCC supports the following AVR devices and ISAs:
-
-@include avr-mmcu.texi
-
-@item -maccumulate-args
-@opindex maccumulate-args
-Accumulate outgoing function arguments and acquire/release the needed
-stack space for outgoing function arguments once in function
-prologue/epilogue. Without this option, outgoing arguments are pushed
-before calling a function and popped afterwards.
-
-Popping the arguments after the function call can be expensive on
-AVR so that accumulating the stack space might lead to smaller
-executables because arguments need not to be removed from the
-stack after such a function call.
-
-This option can lead to reduced code size for functions that perform
-several calls to functions that get their arguments on the stack like
-calls to printf-like functions.
-
-@item -mbranch-cost=@var{cost}
-@opindex mbranch-cost
-Set the branch costs for conditional branch instructions to
-@var{cost}. Reasonable values for @var{cost} are small, non-negative
-integers. The default branch cost is 0.
-
-@item -mcall-prologues
-@opindex mcall-prologues
-Functions prologues/epilogues are expanded as calls to appropriate
-subroutines. Code size is smaller.
-
-@item -mint8
-@opindex mint8
-Assume @code{int} to be 8-bit integer. This affects the sizes of all types: a
-@code{char} is 1 byte, an @code{int} is 1 byte, a @code{long} is 2 bytes,
-and @code{long long} is 4 bytes. Please note that this option does not
-conform to the C standards, but it results in smaller code
-size.
-
-@item -mno-interrupts
-@opindex mno-interrupts
-Generated code is not compatible with hardware interrupts.
-Code size is smaller.
-
-@item -mrelax
-@opindex mrelax
-Try to replace @code{CALL} resp.@: @code{JMP} instruction by the shorter
-@code{RCALL} resp.@: @code{RJMP} instruction if applicable.
-Setting @code{-mrelax} just adds the @code{--relax} option to the
-linker command line when the linker is called.
-
-Jump relaxing is performed by the linker because jump offsets are not
-known before code is located. Therefore, the assembler code generated by the
-compiler is the same, but the instructions in the executable may
-differ from instructions in the assembler code.
-
-Relaxing must be turned on if linker stubs are needed, see the
-section on @code{EIND} and linker stubs below.
-
-@item -msp8
-@opindex msp8
-Treat the stack pointer register as an 8-bit register,
-i.e.@: assume the high byte of the stack pointer is zero.
-In general, you don't need to set this option by hand.
-
-This option is used internally by the compiler to select and
-build multilibs for architectures @code{avr2} and @code{avr25}.
-These architectures mix devices with and without @code{SPH}.
-For any setting other than @code{-mmcu=avr2} or @code{-mmcu=avr25}
-the compiler driver will add or remove this option from the compiler
-proper's command line, because the compiler then knows if the device
-or architecture has an 8-bit stack pointer and thus no @code{SPH}
-register or not.
-
-@item -mstrict-X
-@opindex mstrict-X
-Use address register @code{X} in a way proposed by the hardware. This means
-that @code{X} is only used in indirect, post-increment or
-pre-decrement addressing.
-
-Without this option, the @code{X} register may be used in the same way
-as @code{Y} or @code{Z} which then is emulated by additional
-instructions.
-For example, loading a value with @code{X+const} addressing with a
-small non-negative @code{const < 64} to a register @var{Rn} is
-performed as
-
-@example
-adiw r26, const ; X += const
-ld @var{Rn}, X ; @var{Rn} = *X
-sbiw r26, const ; X -= const
-@end example
-
-@item -mtiny-stack
-@opindex mtiny-stack
-Only change the lower 8@tie{}bits of the stack pointer.
-
-@item -Waddr-space-convert
-@opindex Waddr-space-convert
-Warn about conversions between address spaces in the case where the
-resulting address space is not contained in the incoming address space.
-@end table
-
-@subsubsection @code{EIND} and Devices with more than 128 Ki Bytes of Flash
-@cindex @code{EIND}
-Pointers in the implementation are 16@tie{}bits wide.
-The address of a function or label is represented as word address so
-that indirect jumps and calls can target any code address in the
-range of 64@tie{}Ki words.
-
-In order to facilitate indirect jump on devices with more than 128@tie{}Ki
-bytes of program memory space, there is a special function register called
-@code{EIND} that serves as most significant part of the target address
-when @code{EICALL} or @code{EIJMP} instructions are used.
-
-Indirect jumps and calls on these devices are handled as follows by
-the compiler and are subject to some limitations:
-
-@itemize @bullet
-
-@item
-The compiler never sets @code{EIND}.
-
-@item
-The compiler uses @code{EIND} implicitely in @code{EICALL}/@code{EIJMP}
-instructions or might read @code{EIND} directly in order to emulate an
-indirect call/jump by means of a @code{RET} instruction.
-
-@item
-The compiler assumes that @code{EIND} never changes during the startup
-code or during the application. In particular, @code{EIND} is not
-saved/restored in function or interrupt service routine
-prologue/epilogue.
-
-@item
-For indirect calls to functions and computed goto, the linker
-generates @emph{stubs}. Stubs are jump pads sometimes also called
-@emph{trampolines}. Thus, the indirect call/jump jumps to such a stub.
-The stub contains a direct jump to the desired address.
-
-@item
-Linker relaxation must be turned on so that the linker will generate
-the stubs correctly an all situaltion. See the compiler option
-@code{-mrelax} and the linler option @code{--relax}.
-There are corner cases where the linker is supposed to generate stubs
-but aborts without relaxation and without a helpful error message.
-
-@item
-The default linker script is arranged for code with @code{EIND = 0}.
-If code is supposed to work for a setup with @code{EIND != 0}, a custom
-linker script has to be used in order to place the sections whose
-name start with @code{.trampolines} into the segment where @code{EIND}
-points to.
-
-@item
-The startup code from libgcc never sets @code{EIND}.
-Notice that startup code is a blend of code from libgcc and AVR-LibC.
-For the impact of AVR-LibC on @code{EIND}, see the
-@w{@uref{http://nongnu.org/avr-libc/user-manual/,AVR-LibC user manual}}.
-
-@item
-It is legitimate for user-specific startup code to set up @code{EIND}
-early, for example by means of initialization code located in
-section @code{.init3}. Such code runs prior to general startup code
-that initializes RAM and calls constructors, but after the bit
-of startup code from AVR-LibC that sets @code{EIND} to the segment
-where the vector table is located.
-@example
-#include <avr/io.h>
-
-static void
-__attribute__((section(".init3"),naked,used,no_instrument_function))
-init3_set_eind (void)
-@{
- __asm volatile ("ldi r24,pm_hh8(__trampolines_start)\n\t"
- "out %i0,r24" :: "n" (&EIND) : "r24","memory");
-@}
-@end example
-
-@noindent
-The @code{__trampolines_start} symbol is defined in the linker script.
-
-@item
-Stubs are generated automatically by the linker if
-the following two conditions are met:
-@itemize @minus
-
-@item The address of a label is taken by means of the @code{gs} modifier
-(short for @emph{generate stubs}) like so:
-@example
-LDI r24, lo8(gs(@var{func}))
-LDI r25, hi8(gs(@var{func}))
-@end example
-@item The final location of that label is in a code segment
-@emph{outside} the segment where the stubs are located.
-@end itemize
-
-@item
-The compiler emits such @code{gs} modifiers for code labels in the
-following situations:
-@itemize @minus
-@item Taking address of a function or code label.
-@item Computed goto.
-@item If prologue-save function is used, see @option{-mcall-prologues}
-command-line option.
-@item Switch/case dispatch tables. If you do not want such dispatch
-tables you can specify the @option{-fno-jump-tables} command-line option.
-@item C and C++ constructors/destructors called during startup/shutdown.
-@item If the tools hit a @code{gs()} modifier explained above.
-@end itemize
-
-@item
-Jumping to non-symbolic addresses like so is @emph{not} supported:
-
-@example
-int main (void)
-@{
- /* Call function at word address 0x2 */
- return ((int(*)(void)) 0x2)();
-@}
-@end example
-
-Instead, a stub has to be set up, i.e.@: the function has to be called
-through a symbol (@code{func_4} in the example):
-
-@example
-int main (void)
-@{
- extern int func_4 (void);
-
- /* Call function at byte address 0x4 */
- return func_4();
-@}
-@end example
-
-and the application be linked with @code{-Wl,--defsym,func_4=0x4}.
-Alternatively, @code{func_4} can be defined in the linker script.
-@end itemize
-
-@subsubsection Handling of the @code{RAMPD}, @code{RAMPX}, @code{RAMPY} and @code{RAMPZ} Special Function Registers
-@cindex @code{RAMPD}
-@cindex @code{RAMPX}
-@cindex @code{RAMPY}
-@cindex @code{RAMPZ}
-Some AVR devices support memories larger than the 64@tie{}KiB range
-that can be accessed with 16-bit pointers. To access memory locations
-outside this 64@tie{}KiB range, the contentent of a @code{RAMP}
-register is used as high part of the address:
-The @code{X}, @code{Y}, @code{Z} address register is concatenated
-with the @code{RAMPX}, @code{RAMPY}, @code{RAMPZ} special function
-register, respectively, to get a wide address. Similarly,
-@code{RAMPD} is used together with direct addressing.
-
-@itemize
-@item
-The startup code initializes the @code{RAMP} special function
-registers with zero.
-
-@item
-If a @ref{AVR Named Address Spaces,named address space} other than
-generic or @code{__flash} is used, then @code{RAMPZ} is set
-as needed before the operation.
-
-@item
-If the device supports RAM larger than 64@tie{KiB} and the compiler
-needs to change @code{RAMPZ} to accomplish an operation, @code{RAMPZ}
-is reset to zero after the operation.
-
-@item
-If the device comes with a specific @code{RAMP} register, the ISR
-prologue/epilogue saves/restores that SFR and initializes it with
-zero in case the ISR code might (implicitly) use it.
-
-@item
-RAM larger than 64@tie{KiB} is not supported by GCC for AVR targets.
-If you use inline assembler to read from locations outside the
-16-bit address range and change one of the @code{RAMP} registers,
-you must reset it to zero after the access.
-
-@end itemize
-
-@subsubsection AVR Built-in Macros
-
-GCC defines several built-in macros so that the user code can test
-for the presence or absence of features. Almost any of the following
-built-in macros are deduced from device capabilities and thus
-triggered by the @code{-mmcu=} command-line option.
-
-For even more AVR-specific built-in macros see
-@ref{AVR Named Address Spaces} and @ref{AVR Built-in Functions}.
-
-@table @code
-
-@item __AVR_ARCH__
-Build-in macro that resolves to a decimal number that identifies the
-architecture and depends on the @code{-mmcu=@var{mcu}} option.
-Possible values are:
-
-@code{2}, @code{25}, @code{3}, @code{31}, @code{35},
-@code{4}, @code{5}, @code{51}, @code{6}, @code{102}, @code{104},
-@code{105}, @code{106}, @code{107}
-
-for @var{mcu}=@code{avr2}, @code{avr25}, @code{avr3},
-@code{avr31}, @code{avr35}, @code{avr4}, @code{avr5}, @code{avr51},
-@code{avr6}, @code{avrxmega2}, @code{avrxmega4}, @code{avrxmega5},
-@code{avrxmega6}, @code{avrxmega7}, respectively.
-If @var{mcu} specifies a device, this built-in macro is set
-accordingly. For example, with @code{-mmcu=atmega8} the macro will be
-defined to @code{4}.
-
-@item __AVR_@var{Device}__
-Setting @code{-mmcu=@var{device}} defines this built-in macro which reflects
-the device's name. For example, @code{-mmcu=atmega8} defines the
-built-in macro @code{__AVR_ATmega8__}, @code{-mmcu=attiny261a} defines
-@code{__AVR_ATtiny261A__}, etc.
-
-The built-in macros' names follow
-the scheme @code{__AVR_@var{Device}__} where @var{Device} is
-the device name as from the AVR user manual. The difference between
-@var{Device} in the built-in macro and @var{device} in
-@code{-mmcu=@var{device}} is that the latter is always lowercase.
-
-If @var{device} is not a device but only a core architecture like
-@code{avr51}, this macro will not be defined.
-
-@item __AVR_XMEGA__
-The device / architecture belongs to the XMEGA family of devices.
-
-@item __AVR_HAVE_ELPM__
-The device has the the @code{ELPM} instruction.
-
-@item __AVR_HAVE_ELPMX__
-The device has the @code{ELPM R@var{n},Z} and @code{ELPM
-R@var{n},Z+} instructions.
-
-@item __AVR_HAVE_MOVW__
-The device has the @code{MOVW} instruction to perform 16-bit
-register-register moves.
-
-@item __AVR_HAVE_LPMX__
-The device has the @code{LPM R@var{n},Z} and
-@code{LPM R@var{n},Z+} instructions.
-
-@item __AVR_HAVE_MUL__
-The device has a hardware multiplier.
-
-@item __AVR_HAVE_JMP_CALL__
-The device has the @code{JMP} and @code{CALL} instructions.
-This is the case for devices with at least 16@tie{}KiB of program
-memory.
-
-@item __AVR_HAVE_EIJMP_EICALL__
-@itemx __AVR_3_BYTE_PC__
-The device has the @code{EIJMP} and @code{EICALL} instructions.
-This is the case for devices with more than 128@tie{}KiB of program memory.
-This also means that the program counter
-(PC) is 3@tie{}bytes wide.
-
-@item __AVR_2_BYTE_PC__
-The program counter (PC) is 2@tie{}bytes wide. This is the case for devices
-with up to 128@tie{}KiB of program memory.
-
-@item __AVR_HAVE_8BIT_SP__
-@itemx __AVR_HAVE_16BIT_SP__
-The stack pointer (SP) register is treated as 8-bit respectively
-16-bit register by the compiler.
-The definition of these macros is affected by @code{-mtiny-stack}.
-
-@item __AVR_HAVE_SPH__
-@itemx __AVR_SP8__
-The device has the SPH (high part of stack pointer) special function
-register or has an 8-bit stack pointer, respectively.
-The definition of these macros is affected by @code{-mmcu=} and
-in the cases of @code{-mmcu=avr2} and @code{-mmcu=avr25} also
-by @code{-msp8}.
-
-@item __AVR_HAVE_RAMPD__
-@itemx __AVR_HAVE_RAMPX__
-@itemx __AVR_HAVE_RAMPY__
-@itemx __AVR_HAVE_RAMPZ__
-The device has the @code{RAMPD}, @code{RAMPX}, @code{RAMPY},
-@code{RAMPZ} special function register, respectively.
-
-@item __NO_INTERRUPTS__
-This macro reflects the @code{-mno-interrupts} command line option.
-
-@item __AVR_ERRATA_SKIP__
-@itemx __AVR_ERRATA_SKIP_JMP_CALL__
-Some AVR devices (AT90S8515, ATmega103) must not skip 32-bit
-instructions because of a hardware erratum. Skip instructions are
-@code{SBRS}, @code{SBRC}, @code{SBIS}, @code{SBIC} and @code{CPSE}.
-The second macro is only defined if @code{__AVR_HAVE_JMP_CALL__} is also
-set.
-
-@item __AVR_SFR_OFFSET__=@var{offset}
-Instructions that can address I/O special function registers directly
-like @code{IN}, @code{OUT}, @code{SBI}, etc.@: may use a different
-address as if addressed by an instruction to access RAM like @code{LD}
-or @code{STS}. This offset depends on the device architecture and has
-to be subtracted from the RAM address in order to get the
-respective I/O@tie{}address.
-
-@item __WITH_AVRLIBC__
-The compiler is configured to be used together with AVR-Libc.
-See the @code{--with-avrlibc} configure option.
-
-@end table
-
-@node Blackfin Options
-@subsection Blackfin Options
-@cindex Blackfin Options
-
-@table @gcctabopt
-@item -mcpu=@var{cpu}@r{[}-@var{sirevision}@r{]}
-@opindex mcpu=
-Specifies the name of the target Blackfin processor. Currently, @var{cpu}
-can be one of @samp{bf512}, @samp{bf514}, @samp{bf516}, @samp{bf518},
-@samp{bf522}, @samp{bf523}, @samp{bf524}, @samp{bf525}, @samp{bf526},
-@samp{bf527}, @samp{bf531}, @samp{bf532}, @samp{bf533},
-@samp{bf534}, @samp{bf536}, @samp{bf537}, @samp{bf538}, @samp{bf539},
-@samp{bf542}, @samp{bf544}, @samp{bf547}, @samp{bf548}, @samp{bf549},
-@samp{bf542m}, @samp{bf544m}, @samp{bf547m}, @samp{bf548m}, @samp{bf549m},
-@samp{bf561}, @samp{bf592}.
-
-The optional @var{sirevision} specifies the silicon revision of the target
-Blackfin processor. Any workarounds available for the targeted silicon revision
-are enabled. If @var{sirevision} is @samp{none}, no workarounds are enabled.
-If @var{sirevision} is @samp{any}, all workarounds for the targeted processor
-are enabled. The @code{__SILICON_REVISION__} macro is defined to two
-hexadecimal digits representing the major and minor numbers in the silicon
-revision. If @var{sirevision} is @samp{none}, the @code{__SILICON_REVISION__}
-is not defined. If @var{sirevision} is @samp{any}, the
-@code{__SILICON_REVISION__} is defined to be @code{0xffff}.
-If this optional @var{sirevision} is not used, GCC assumes the latest known
-silicon revision of the targeted Blackfin processor.
-
-GCC defines a preprocessor macro for the specified @var{cpu}.
-For the @samp{bfin-elf} toolchain, this option causes the hardware BSP
-provided by libgloss to be linked in if @option{-msim} is not given.
-
-Without this option, @samp{bf532} is used as the processor by default.
-
-Note that support for @samp{bf561} is incomplete. For @samp{bf561},
-only the preprocessor macro is defined.
-
-@item -msim
-@opindex msim
-Specifies that the program will be run on the simulator. This causes
-the simulator BSP provided by libgloss to be linked in. This option
-has effect only for @samp{bfin-elf} toolchain.
-Certain other options, such as @option{-mid-shared-library} and
-@option{-mfdpic}, imply @option{-msim}.
-
-@item -momit-leaf-frame-pointer
-@opindex momit-leaf-frame-pointer
-Don't keep the frame pointer in a register for leaf functions. This
-avoids the instructions to save, set up and restore frame pointers and
-makes an extra register available in leaf functions. The option
-@option{-fomit-frame-pointer} removes the frame pointer for all functions,
-which might make debugging harder.
-
-@item -mspecld-anomaly
-@opindex mspecld-anomaly
-When enabled, the compiler ensures that the generated code does not
-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 ensures 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
-Do stack checking using information placed into L1 scratchpad memory by the
-uClinux kernel.
-
-@item -mid-shared-library
-@opindex mid-shared-library
-Generate code that supports shared libraries via the library ID method.
-This allows for execute in place and shared libraries in an environment
-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,
-but assumes that this library or executable won't link against any other
-ID shared libraries. That allows the compiler to use faster code for jumps
-and calls.
-
-@item -mno-leaf-id-shared-library
-@opindex mno-leaf-id-shared-library
-Do not assume that the code being compiled won't link against any ID shared
-libraries. Slower code is generated for jump and call insns.
-
-@item -mshared-library-id=n
-@opindex mshared-library-id
-Specifies the identification number of the ID-based shared library being
-compiled. Specifying a value of 0 generates more compact code; specifying
-other values forces the allocation of that number to the current
-library but is no more space- or time-efficient than omitting this option.
-
-@item -msep-data
-@opindex msep-data
-Generate code that allows the data segment to be located in a different
-area of memory from the text segment. This allows for execute in place in
-an environment without virtual memory management by eliminating relocations
-against the text section.
-
-@item -mno-sep-data
-@opindex mno-sep-data
-Generate code that assumes that the data segment follows the text segment.
-This is the default.
-
-@item -mlong-calls
-@itemx -mno-long-calls
-@opindex mlong-calls
-@opindex mno-long-calls
-Tells the compiler to perform function calls by first loading the
-address of the function into a register and then performing a subroutine
-call on this register. This switch is needed if the target function
-lies 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} restores 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
-the IEEE floating-point standard's rules for checking inputs against
-Not-a-Number (NAN), in the interest of performance.
-
-@item -minline-plt
-@opindex minline-plt
-Enable inlining of PLT entries in function calls to functions that are
-not known to bind locally. It has no effect without @option{-mfdpic}.
-
-@item -mmulticore
-@opindex mmulticore
-Build a standalone application for multicore Blackfin processors.
-This option causes proper start files and link scripts supporting
-multicore to be used, and defines the macro @code{__BFIN_MULTICORE}.
-It can only be used with @option{-mcpu=bf561@r{[}-@var{sirevision}@r{]}}.
-
-This option can be used with @option{-mcorea} or @option{-mcoreb}, which
-selects the one-application-per-core programming model. Without
-@option{-mcorea} or @option{-mcoreb}, the single-application/dual-core
-programming model is used. In this model, the main function of Core B
-should be named as @code{coreb_main}.
-
-If this option is not used, the single-core application programming
-model is used.
-
-@item -mcorea
-@opindex mcorea
-Build a standalone application for Core A of BF561 when using
-the one-application-per-core programming model. Proper start files
-and link scripts are used to support Core A, and the macro
-@code{__BFIN_COREA} is defined.
-This option can only be used in conjunction with @option{-mmulticore}.
-
-@item -mcoreb
-@opindex mcoreb
-Build a standalone application for Core B of BF561 when using
-the one-application-per-core programming model. Proper start files
-and link scripts are used to support Core B, and the macro
-@code{__BFIN_COREB} is defined. When this option is used, @code{coreb_main}
-should be used instead of @code{main}.
-This option can only be used in conjunction with @option{-mmulticore}.
-
-@item -msdram
-@opindex msdram
-Build a standalone application for SDRAM. Proper start files and
-link scripts are used to put the application into SDRAM, and the macro
-@code{__BFIN_SDRAM} is defined.
-The loader should initialize SDRAM before loading the application.
-
-@item -micplb
-@opindex micplb
-Assume that ICPLBs are enabled at run time. This has an effect on certain
-anomaly workarounds. For Linux targets, the default is to assume ICPLBs
-are enabled; for standalone applications the default is off.
-@end table
-
-@node C6X Options
-@subsection C6X Options
-@cindex C6X Options
-
-@table @gcctabopt
-@item -march=@var{name}
-@opindex march
-This specifies the name of the target architecture. GCC uses this
-name to determine what kind of instructions it can emit when generating
-assembly code. Permissible names are: @samp{c62x},
-@samp{c64x}, @samp{c64x+}, @samp{c67x}, @samp{c67x+}, @samp{c674x}.
-
-@item -mbig-endian
-@opindex mbig-endian
-Generate code for a big-endian target.
-
-@item -mlittle-endian
-@opindex mlittle-endian
-Generate code for a little-endian target. This is the default.
-
-@item -msim
-@opindex msim
-Choose startup files and linker script suitable for the simulator.
-
-@item -msdata=default
-@opindex msdata=default
-Put small global and static data in the @samp{.neardata} section,
-which is pointed to by register @code{B14}. Put small uninitialized
-global and static data in the @samp{.bss} section, which is adjacent
-to the @samp{.neardata} section. Put small read-only data into the
-@samp{.rodata} section. The corresponding sections used for large
-pieces of data are @samp{.fardata}, @samp{.far} and @samp{.const}.
-
-@item -msdata=all
-@opindex msdata=all
-Put all data, not just small objects, into the sections reserved for
-small data, and use addressing relative to the @code{B14} register to
-access them.
-
-@item -msdata=none
-@opindex msdata=none
-Make no use of the sections reserved for small data, and use absolute
-addresses to access all data. Put all initialized global and static
-data in the @samp{.fardata} section, and all uninitialized data in the
-@samp{.far} section. Put all constant data into the @samp{.const}
-section.
-@end table
-
-@node CRIS Options
-@subsection CRIS Options
-@cindex CRIS Options
-
-These options are defined specifically for the CRIS ports.
-
-@table @gcctabopt
-@item -march=@var{architecture-type}
-@itemx -mcpu=@var{architecture-type}
-@opindex march
-@opindex mcpu
-Generate code for the specified architecture. The choices for
-@var{architecture-type} are @samp{v3}, @samp{v8} and @samp{v10} for
-respectively ETRAX@w{ }4, ETRAX@w{ }100, and ETRAX@w{ }100@w{ }LX@.
-Default is @samp{v0} except for cris-axis-linux-gnu, where the default is
-@samp{v10}.
-
-@item -mtune=@var{architecture-type}
-@opindex mtune
-Tune to @var{architecture-type} everything applicable about the generated
-code, except for the ABI and the set of available instructions. The
-choices for @var{architecture-type} are the same as for
-@option{-march=@var{architecture-type}}.
-
-@item -mmax-stack-frame=@var{n}
-@opindex mmax-stack-frame
-Warn when the stack frame of a function exceeds @var{n} bytes.
-
-@item -metrax4
-@itemx -metrax100
-@opindex metrax4
-@opindex metrax100
-The options @option{-metrax4} and @option{-metrax100} are synonyms for
-@option{-march=v3} and @option{-march=v8} respectively.
-
-@item -mmul-bug-workaround
-@itemx -mno-mul-bug-workaround
-@opindex mmul-bug-workaround
-@opindex mno-mul-bug-workaround
-Work around a bug in the @code{muls} and @code{mulu} instructions for CPU
-models where it applies. This option is active by default.
-
-@item -mpdebug
-@opindex mpdebug
-Enable CRIS-specific verbose debug-related information in the assembly
-code. This option also has the effect of turning off the @samp{#NO_APP}
-formatted-code indicator to the assembler at the beginning of the
-assembly file.
-
-@item -mcc-init
-@opindex mcc-init
-Do not use condition-code results from previous instruction; always emit
-compare and test instructions before use of condition codes.
-
-@item -mno-side-effects
-@opindex mno-side-effects
-Do not emit instructions with side effects in addressing modes other than
-post-increment.
-
-@item -mstack-align
-@itemx -mno-stack-align
-@itemx -mdata-align
-@itemx -mno-data-align
-@itemx -mconst-align
-@itemx -mno-const-align
-@opindex mstack-align
-@opindex mno-stack-align
-@opindex mdata-align
-@opindex mno-data-align
-@opindex mconst-align
-@opindex mno-const-align
-These options (@samp{no-} options) arrange (eliminate arrangements) for the
-stack frame, individual data and constants to be aligned for the maximum
-single data access size for the chosen CPU model. The default is to
-arrange for 32-bit alignment. ABI details such as structure layout are
-not affected by these options.
-
-@item -m32-bit
-@itemx -m16-bit
-@itemx -m8-bit
-@opindex m32-bit
-@opindex m16-bit
-@opindex m8-bit
-Similar to the stack- data- and const-align options above, these options
-arrange for stack frame, writable data and constants to all be 32-bit,
-16-bit or 8-bit aligned. The default is 32-bit alignment.
-
-@item -mno-prologue-epilogue
-@itemx -mprologue-epilogue
-@opindex mno-prologue-epilogue
-@opindex mprologue-epilogue
-With @option{-mno-prologue-epilogue}, the normal function prologue and
-epilogue which set up the stack frame are omitted and no return
-instructions or return sequences are generated in the code. Use this
-option only together with visual inspection of the compiled code: no
-warnings or errors are generated when call-saved registers must be saved,
-or storage for local variables needs to be allocated.
-
-@item -mno-gotplt
-@itemx -mgotplt
-@opindex mno-gotplt
-@opindex mgotplt
-With @option{-fpic} and @option{-fPIC}, don't generate (do generate)
-instruction sequences that load addresses for functions from the PLT part
-of the GOT rather than (traditional on other architectures) calls to the
-PLT@. The default is @option{-mgotplt}.
-
-@item -melf
-@opindex melf
-Legacy no-op option only recognized with the cris-axis-elf and
-cris-axis-linux-gnu targets.
-
-@item -mlinux
-@opindex mlinux
-Legacy no-op option only recognized with the cris-axis-linux-gnu target.
-
-@item -sim
-@opindex sim
-This option, recognized for the cris-axis-elf, arranges
-to link with input-output functions from a simulator library. Code,
-initialized data and zero-initialized data are allocated consecutively.
-
-@item -sim2
-@opindex sim2
-Like @option{-sim}, but pass linker options to locate initialized data at
-0x40000000 and zero-initialized data at 0x80000000.
-@end table
-
-@node CR16 Options
-@subsection CR16 Options
-@cindex CR16 Options
-
-These options are defined specifically for the CR16 ports.
-
-@table @gcctabopt
-
-@item -mmac
-@opindex mmac
-Enable the use of multiply-accumulate instructions. Disabled by default.
-
-@item -mcr16cplus
-@itemx -mcr16c
-@opindex mcr16cplus
-@opindex mcr16c
-Generate code for CR16C or CR16C+ architecture. CR16C+ architecture
-is default.
-
-@item -msim
-@opindex msim
-Links the library libsim.a which is in compatible with simulator. Applicable
-to ELF compiler only.
-
-@item -mint32
-@opindex mint32
-Choose integer type as 32-bit wide.
-
-@item -mbit-ops
-@opindex mbit-ops
-Generates @code{sbit}/@code{cbit} instructions for bit manipulations.
-
-@item -mdata-model=@var{model}
-@opindex mdata-model
-Choose a data model. The choices for @var{model} are @samp{near},
-@samp{far} or @samp{medium}. @samp{medium} is default.
-However, @samp{far} is not valid with @option{-mcr16c}, as the
-CR16C architecture does not support the far data model.
-@end table
-
-@node Darwin Options
-@subsection Darwin Options
-@cindex Darwin options
-
-These options are defined for all architectures running the Darwin operating
-system.
-
-FSF GCC on Darwin does not create ``fat'' object files; it creates
-an object file for the single architecture that GCC was built to
-target. Apple's GCC on Darwin does create ``fat'' files if multiple
-@option{-arch} options are used; it does so by running the compiler or
-linker multiple times and joining the results together with
-@file{lipo}.
-
-The subtype of the file created (like @samp{ppc7400} or @samp{ppc970} or
-@samp{i686}) is determined by the flags that specify the ISA
-that GCC is targeting, like @option{-mcpu} or @option{-march}. The
-@option{-force_cpusubtype_ALL} option can be used to override this.
-
-The Darwin tools vary in their behavior when presented with an ISA
-mismatch. The assembler, @file{as}, only permits instructions to
-be used that are valid for the subtype of the file it is generating,
-so you cannot put 64-bit instructions in a @samp{ppc750} object file.
-The linker for shared libraries, @file{/usr/bin/libtool}, fails
-and prints an error if asked to create a shared library with a less
-restrictive subtype than its input files (for instance, trying to put
-a @samp{ppc970} object file in a @samp{ppc7400} library). The linker
-for executables, @command{ld}, quietly gives the executable the most
-restrictive subtype of any of its input files.
-
-@table @gcctabopt
-@item -F@var{dir}
-@opindex F
-Add the framework directory @var{dir} to the head of the list of
-directories to be searched for header files. These directories are
-interleaved with those specified by @option{-I} options and are
-scanned in a left-to-right order.
-
-A framework directory is a directory with frameworks in it. A
-framework is a directory with a @file{Headers} and/or
-@file{PrivateHeaders} directory contained directly in it that ends
-in @file{.framework}. The name of a framework is the name of this
-directory excluding the @file{.framework}. Headers associated with
-the framework are found in one of those two directories, with
-@file{Headers} being searched first. A subframework is a framework
-directory that is in a framework's @file{Frameworks} directory.
-Includes of subframework headers can only appear in a header of a
-framework that contains the subframework, or in a sibling subframework
-header. Two subframeworks are siblings if they occur in the same
-framework. A subframework should not have the same name as a
-framework; a warning is issued if this is violated. Currently a
-subframework cannot have subframeworks; in the future, the mechanism
-may be extended to support this. The standard frameworks can be found
-in @file{/System/Library/Frameworks} and
-@file{/Library/Frameworks}. An example include looks like
-@code{#include <Framework/header.h>}, where @file{Framework} denotes
-the name of the framework and @file{header.h} is found in the
-@file{PrivateHeaders} or @file{Headers} directory.
-
-@item -iframework@var{dir}
-@opindex iframework
-Like @option{-F} except the directory is a treated as a system
-directory. The main difference between this @option{-iframework} and
-@option{-F} is that with @option{-iframework} the compiler does not
-warn about constructs contained within header files found via
-@var{dir}. This option is valid only for the C family of languages.
-
-@item -gused
-@opindex gused
-Emit debugging information for symbols that are used. For stabs
-debugging format, this enables @option{-feliminate-unused-debug-symbols}.
-This is by default ON@.
-
-@item -gfull
-@opindex gfull
-Emit debugging information for all symbols and types.
-
-@item -mmacosx-version-min=@var{version}
-The earliest version of MacOS X that this executable will run on
-is @var{version}. Typical values of @var{version} include @code{10.1},
-@code{10.2}, and @code{10.3.9}.
-
-If the compiler was built to use the system's headers by default,
-then the default for this option is the system version on which the
-compiler is running, otherwise the default is to make choices that
-are compatible with as many systems and code bases as possible.
-
-@item -mkernel
-@opindex mkernel
-Enable kernel development mode. The @option{-mkernel} option sets
-@option{-static}, @option{-fno-common}, @option{-fno-cxa-atexit},
-@option{-fno-exceptions}, @option{-fno-non-call-exceptions},
-@option{-fapple-kext}, @option{-fno-weak} and @option{-fno-rtti} where
-applicable. This mode also sets @option{-mno-altivec},
-@option{-msoft-float}, @option{-fno-builtin} and
-@option{-mlong-branch} for PowerPC targets.
-
-@item -mone-byte-bool
-@opindex mone-byte-bool
-Override the defaults for @samp{bool} so that @samp{sizeof(bool)==1}.
-By default @samp{sizeof(bool)} is @samp{4} when compiling for
-Darwin/PowerPC and @samp{1} when compiling for Darwin/x86, so this
-option has no effect on x86.
-
-@strong{Warning:} The @option{-mone-byte-bool} switch causes GCC
-to generate code that is not binary compatible with code generated
-without that switch. Using this switch may require recompiling all
-other modules in a program, including system libraries. Use this
-switch to conform to a non-default data model.
-
-@item -mfix-and-continue
-@itemx -ffix-and-continue
-@itemx -findirect-data
-@opindex mfix-and-continue
-@opindex ffix-and-continue
-@opindex findirect-data
-Generate code suitable for fast turnaround development, such as to
-allow GDB to dynamically load @code{.o} files into already-running
-programs. @option{-findirect-data} and @option{-ffix-and-continue}
-are provided for backwards compatibility.
-
-@item -all_load
-@opindex all_load
-Loads all members of static archive libraries.
-See man ld(1) for more information.
-
-@item -arch_errors_fatal
-@opindex arch_errors_fatal
-Cause the errors having to do with files that have the wrong architecture
-to be fatal.
-
-@item -bind_at_load
-@opindex bind_at_load
-Causes the output file to be marked such that the dynamic linker will
-bind all undefined references when the file is loaded or launched.
-
-@item -bundle
-@opindex bundle
-Produce a Mach-o bundle format file.
-See man ld(1) for more information.
-
-@item -bundle_loader @var{executable}
-@opindex bundle_loader
-This option specifies the @var{executable} that will load the build
-output file being linked. See man ld(1) for more information.
-
-@item -dynamiclib
-@opindex dynamiclib
-When passed this option, GCC produces a dynamic library instead of
-an executable when linking, using the Darwin @file{libtool} command.
-
-@item -force_cpusubtype_ALL
-@opindex force_cpusubtype_ALL
-This causes GCC's output file to have the @var{ALL} subtype, instead of
-one controlled by the @option{-mcpu} or @option{-march} option.
-
-@item -allowable_client @var{client_name}
-@itemx -client_name
-@itemx -compatibility_version
-@itemx -current_version
-@itemx -dead_strip
-@itemx -dependency-file
-@itemx -dylib_file
-@itemx -dylinker_install_name
-@itemx -dynamic
-@itemx -exported_symbols_list
-@itemx -filelist
-@need 800
-@itemx -flat_namespace
-@itemx -force_flat_namespace
-@itemx -headerpad_max_install_names
-@itemx -image_base
-@itemx -init
-@itemx -install_name
-@itemx -keep_private_externs
-@itemx -multi_module
-@itemx -multiply_defined
-@itemx -multiply_defined_unused
-@need 800
-@itemx -noall_load
-@itemx -no_dead_strip_inits_and_terms
-@itemx -nofixprebinding
-@itemx -nomultidefs
-@itemx -noprebind
-@itemx -noseglinkedit
-@itemx -pagezero_size
-@itemx -prebind
-@itemx -prebind_all_twolevel_modules
-@itemx -private_bundle
-@need 800
-@itemx -read_only_relocs
-@itemx -sectalign
-@itemx -sectobjectsymbols
-@itemx -whyload
-@itemx -seg1addr
-@itemx -sectcreate
-@itemx -sectobjectsymbols
-@itemx -sectorder
-@itemx -segaddr
-@itemx -segs_read_only_addr
-@need 800
-@itemx -segs_read_write_addr
-@itemx -seg_addr_table
-@itemx -seg_addr_table_filename
-@itemx -seglinkedit
-@itemx -segprot
-@itemx -segs_read_only_addr
-@itemx -segs_read_write_addr
-@itemx -single_module
-@itemx -static
-@itemx -sub_library
-@need 800
-@itemx -sub_umbrella
-@itemx -twolevel_namespace
-@itemx -umbrella
-@itemx -undefined
-@itemx -unexported_symbols_list
-@itemx -weak_reference_mismatches
-@itemx -whatsloaded
-@opindex allowable_client
-@opindex client_name
-@opindex compatibility_version
-@opindex current_version
-@opindex dead_strip
-@opindex dependency-file
-@opindex dylib_file
-@opindex dylinker_install_name
-@opindex dynamic
-@opindex exported_symbols_list
-@opindex filelist
-@opindex flat_namespace
-@opindex force_flat_namespace
-@opindex headerpad_max_install_names
-@opindex image_base
-@opindex init
-@opindex install_name
-@opindex keep_private_externs
-@opindex multi_module
-@opindex multiply_defined
-@opindex multiply_defined_unused
-@opindex noall_load
-@opindex no_dead_strip_inits_and_terms
-@opindex nofixprebinding
-@opindex nomultidefs
-@opindex noprebind
-@opindex noseglinkedit
-@opindex pagezero_size
-@opindex prebind
-@opindex prebind_all_twolevel_modules
-@opindex private_bundle
-@opindex read_only_relocs
-@opindex sectalign
-@opindex sectobjectsymbols
-@opindex whyload
-@opindex seg1addr
-@opindex sectcreate
-@opindex sectobjectsymbols
-@opindex sectorder
-@opindex segaddr
-@opindex segs_read_only_addr
-@opindex segs_read_write_addr
-@opindex seg_addr_table
-@opindex seg_addr_table_filename
-@opindex seglinkedit
-@opindex segprot
-@opindex segs_read_only_addr
-@opindex segs_read_write_addr
-@opindex single_module
-@opindex static
-@opindex sub_library
-@opindex sub_umbrella
-@opindex twolevel_namespace
-@opindex umbrella
-@opindex undefined
-@opindex unexported_symbols_list
-@opindex weak_reference_mismatches
-@opindex whatsloaded
-These options are passed to the Darwin linker. The Darwin linker man page
-describes them in detail.
-@end table
-
-@node DEC Alpha Options
-@subsection DEC Alpha Options
-
-These @samp{-m} options are defined for the DEC Alpha implementations:
-
-@table @gcctabopt
-@item -mno-soft-float
-@itemx -msoft-float
-@opindex mno-soft-float
-@opindex msoft-float
-Use (do not use) the hardware floating-point instructions for
-floating-point operations. When @option{-msoft-float} is specified,
-functions in @file{libgcc.a} are used to perform floating-point
-operations. Unless they are replaced by routines that emulate the
-floating-point operations, or compiled in such a way as to call such
-emulations routines, these routines issue floating-point
-operations. If you are compiling for an Alpha without floating-point
-operations, you must ensure that the library is built so as not to call
-them.
-
-Note that Alpha implementations without floating-point operations are
-required to have floating-point registers.
-
-@item -mfp-reg
-@itemx -mno-fp-regs
-@opindex mfp-reg
-@opindex mno-fp-regs
-Generate code that uses (does not use) the floating-point register set.
-@option{-mno-fp-regs} implies @option{-msoft-float}. If the floating-point
-register set is not used, floating-point operands are passed in integer
-registers as if they were integers and floating-point results are passed
-in @code{$0} instead of @code{$f0}. This is a non-standard calling sequence,
-so any function with a floating-point argument or return value called by code
-compiled with @option{-mno-fp-regs} must also be compiled with that
-option.
-
-A typical use of this option is building a kernel that does not use,
-and hence need not save and restore, any floating-point registers.
-
-@item -mieee
-@opindex mieee
-The Alpha architecture implements floating-point hardware optimized for
-maximum performance. It is mostly compliant with the IEEE floating-point
-standard. However, for full compliance, software assistance is
-required. This option generates code fully IEEE-compliant code
-@emph{except} that the @var{inexact-flag} is not maintained (see below).
-If this option is turned on, the preprocessor macro @code{_IEEE_FP} is
-defined during compilation. The resulting code is less efficient but is
-able to correctly support denormalized numbers and exceptional IEEE
-values such as not-a-number and plus/minus infinity. Other Alpha
-compilers call this option @option{-ieee_with_no_inexact}.
-
-@item -mieee-with-inexact
-@opindex mieee-with-inexact
-This is like @option{-mieee} except the generated code also maintains
-the IEEE @var{inexact-flag}. Turning on this option causes the
-generated code to implement fully-compliant IEEE math. In addition to
-@code{_IEEE_FP}, @code{_IEEE_FP_EXACT} is defined as a preprocessor
-macro. On some Alpha implementations the resulting code may execute
-significantly slower than the code generated by default. Since there is
-very little code that depends on the @var{inexact-flag}, you should
-normally not specify this option. Other Alpha compilers call this
-option @option{-ieee_with_inexact}.
-
-@item -mfp-trap-mode=@var{trap-mode}
-@opindex mfp-trap-mode
-This option controls what floating-point related traps are enabled.
-Other Alpha compilers call this option @option{-fptm @var{trap-mode}}.
-The trap mode can be set to one of four values:
-
-@table @samp
-@item n
-This is the default (normal) setting. The only traps that are enabled
-are the ones that cannot be disabled in software (e.g., division by zero
-trap).
-
-@item u
-In addition to the traps enabled by @samp{n}, underflow traps are enabled
-as well.
-
-@item su
-Like @samp{u}, but the instructions are marked to be safe for software
-completion (see Alpha architecture manual for details).
-
-@item sui
-Like @samp{su}, but inexact traps are enabled as well.
-@end table
-
-@item -mfp-rounding-mode=@var{rounding-mode}
-@opindex mfp-rounding-mode
-Selects the IEEE rounding mode. Other Alpha compilers call this option
-@option{-fprm @var{rounding-mode}}. The @var{rounding-mode} can be one
-of:
-
-@table @samp
-@item n
-Normal IEEE rounding mode. Floating-point numbers are rounded towards
-the nearest machine number or towards the even machine number in case
-of a tie.
-
-@item m
-Round towards minus infinity.
-
-@item c
-Chopped rounding mode. Floating-point numbers are rounded towards zero.
-
-@item d
-Dynamic rounding mode. A field in the floating-point control register
-(@var{fpcr}, see Alpha architecture reference manual) controls the
-rounding mode in effect. The C library initializes this register for
-rounding towards plus infinity. Thus, unless your program modifies the
-@var{fpcr}, @samp{d} corresponds to round towards plus infinity.
-@end table
-
-@item -mtrap-precision=@var{trap-precision}
-@opindex mtrap-precision
-In the Alpha architecture, floating-point traps are imprecise. This
-means without software assistance it is impossible to recover from a
-floating trap and program execution normally needs to be terminated.
-GCC can generate code that can assist operating system trap handlers
-in determining the exact location that caused a floating-point trap.
-Depending on the requirements of an application, different levels of
-precisions can be selected:
-
-@table @samp
-@item p
-Program precision. This option is the default and means a trap handler
-can only identify which program caused a floating-point exception.
-
-@item f
-Function precision. The trap handler can determine the function that
-caused a floating-point exception.
-
-@item i
-Instruction precision. The trap handler can determine the exact
-instruction that caused a floating-point exception.
-@end table
-
-Other Alpha compilers provide the equivalent options called
-@option{-scope_safe} and @option{-resumption_safe}.
-
-@item -mieee-conformant
-@opindex mieee-conformant
-This option marks the generated code as IEEE conformant. You must not
-use this option unless you also specify @option{-mtrap-precision=i} and either
-@option{-mfp-trap-mode=su} or @option{-mfp-trap-mode=sui}. Its only effect
-is to emit the line @samp{.eflag 48} in the function prologue of the
-generated assembly file.
-
-@item -mbuild-constants
-@opindex mbuild-constants
-Normally GCC examines a 32- or 64-bit integer constant to
-see if it can construct it from smaller constants in two or three
-instructions. If it cannot, it outputs the constant as a literal and
-generates code to load it from the data segment at run time.
-
-Use this option to require GCC to construct @emph{all} integer constants
-using code, even if it takes more instructions (the maximum is six).
-
-You typically use this option to build a shared library dynamic
-loader. Itself a shared library, it must relocate itself in memory
-before it can find the variables and constants in its own data segment.
-
-@item -mbwx
-@itemx -mno-bwx
-@itemx -mcix
-@itemx -mno-cix
-@itemx -mfix
-@itemx -mno-fix
-@itemx -mmax
-@itemx -mno-max
-@opindex mbwx
-@opindex mno-bwx
-@opindex mcix
-@opindex mno-cix
-@opindex mfix
-@opindex mno-fix
-@opindex mmax
-@opindex mno-max
-Indicate whether GCC should generate code to use the optional BWX,
-CIX, FIX and MAX instruction sets. The default is to use the instruction
-sets supported by the CPU type specified via @option{-mcpu=} option or that
-of the CPU on which GCC was built if none is specified.
-
-@item -mfloat-vax
-@itemx -mfloat-ieee
-@opindex mfloat-vax
-@opindex mfloat-ieee
-Generate code that uses (does not use) VAX F and G floating-point
-arithmetic instead of IEEE single and double precision.
-
-@item -mexplicit-relocs
-@itemx -mno-explicit-relocs
-@opindex mexplicit-relocs
-@opindex mno-explicit-relocs
-Older Alpha assemblers provided no way to generate symbol relocations
-except via assembler macros. Use of these macros does not allow
-optimal instruction scheduling. GNU binutils as of version 2.12
-supports a new syntax that allows the compiler to explicitly mark
-which relocations should apply to which instructions. This option
-is mostly useful for debugging, as GCC detects the capabilities of
-the assembler when it is built and sets the default accordingly.
-
-@item -msmall-data
-@itemx -mlarge-data
-@opindex msmall-data
-@opindex mlarge-data
-When @option{-mexplicit-relocs} is in effect, static data is
-accessed via @dfn{gp-relative} relocations. When @option{-msmall-data}
-is used, objects 8 bytes long or smaller are placed in a @dfn{small data area}
-(the @code{.sdata} and @code{.sbss} sections) and are accessed via
-16-bit relocations off of the @code{$gp} register. This limits the
-size of the small data area to 64KB, but allows the variables to be
-directly accessed via a single instruction.
-
-The default is @option{-mlarge-data}. With this option the data area
-is limited to just below 2GB@. Programs that require more than 2GB of
-data must use @code{malloc} or @code{mmap} to allocate the data in the
-heap instead of in the program's data segment.
-
-When generating code for shared libraries, @option{-fpic} implies
-@option{-msmall-data} and @option{-fPIC} implies @option{-mlarge-data}.
-
-@item -msmall-text
-@itemx -mlarge-text
-@opindex msmall-text
-@opindex mlarge-text
-When @option{-msmall-text} is used, the compiler assumes that the
-code of the entire program (or shared library) fits in 4MB, and is
-thus reachable with a branch instruction. When @option{-msmall-data}
-is used, the compiler can assume that all local symbols share the
-same @code{$gp} value, and thus reduce the number of instructions
-required for a function call from 4 to 1.
-
-The default is @option{-mlarge-text}.
-
-@item -mcpu=@var{cpu_type}
-@opindex mcpu
-Set the instruction set and instruction scheduling parameters for
-machine type @var{cpu_type}. You can specify either the @samp{EV}
-style name or the corresponding chip number. GCC supports scheduling
-parameters for the EV4, EV5 and EV6 family of processors and
-chooses the default values for the instruction set from the processor
-you specify. If you do not specify a processor type, GCC defaults
-to the processor on which the compiler was built.
-
-Supported values for @var{cpu_type} are
-
-@table @samp
-@item ev4
-@itemx ev45
-@itemx 21064
-Schedules as an EV4 and has no instruction set extensions.
-
-@item ev5
-@itemx 21164
-Schedules as an EV5 and has no instruction set extensions.
-
-@item ev56
-@itemx 21164a
-Schedules as an EV5 and supports the BWX extension.
-
-@item pca56
-@itemx 21164pc
-@itemx 21164PC
-Schedules as an EV5 and supports the BWX and MAX extensions.
-
-@item ev6
-@itemx 21264
-Schedules as an EV6 and supports the BWX, FIX, and MAX extensions.
-
-@item ev67
-@itemx 21264a
-Schedules as an EV6 and supports the BWX, CIX, FIX, and MAX extensions.
-@end table
-
-Native toolchains also support the value @samp{native},
-which selects the best architecture option for the host processor.
-@option{-mcpu=native} has no effect if GCC does not recognize
-the processor.
-
-@item -mtune=@var{cpu_type}
-@opindex mtune
-Set only the instruction scheduling parameters for machine type
-@var{cpu_type}. The instruction set is not changed.
-
-Native toolchains also support the value @samp{native},
-which selects the best architecture option for the host processor.
-@option{-mtune=native} has no effect if GCC does not recognize
-the processor.
-
-@item -mmemory-latency=@var{time}
-@opindex mmemory-latency
-Sets the latency the scheduler should assume for typical memory
-references as seen by the application. This number is highly
-dependent on the memory access patterns used by the application
-and the size of the external cache on the machine.
-
-Valid options for @var{time} are
-
-@table @samp
-@item @var{number}
-A decimal number representing clock cycles.
-
-@item L1
-@itemx L2
-@itemx L3
-@itemx main
-The compiler contains estimates of the number of clock cycles for
-``typical'' EV4 & EV5 hardware for the Level 1, 2 & 3 caches
-(also called Dcache, Scache, and Bcache), as well as to main memory.
-Note that L3 is only valid for EV5.
-
-@end table
-@end table
-
-@node FR30 Options
-@subsection FR30 Options
-@cindex FR30 Options
-
-These options are defined specifically for the FR30 port.
-
-@table @gcctabopt
-
-@item -msmall-model
-@opindex msmall-model
-Use the small address space model. This can produce smaller code, but
-it does assume that all symbolic values and addresses fit into a
-20-bit range.
-
-@item -mno-lsim
-@opindex mno-lsim
-Assume that runtime support has been provided and so there is no need
-to include the simulator library (@file{libsim.a}) on the linker
-command line.
-
-@end table
-
-@node FRV Options
-@subsection FRV Options
-@cindex FRV Options
-
-@table @gcctabopt
-@item -mgpr-32
-@opindex mgpr-32
-
-Only use the first 32 general-purpose registers.
-
-@item -mgpr-64
-@opindex mgpr-64
-
-Use all 64 general-purpose registers.
-
-@item -mfpr-32
-@opindex mfpr-32
-
-Use only the first 32 floating-point registers.
-
-@item -mfpr-64
-@opindex mfpr-64
-
-Use all 64 floating-point registers.
-
-@item -mhard-float
-@opindex mhard-float
-
-Use hardware instructions for floating-point operations.
-
-@item -msoft-float
-@opindex msoft-float
-
-Use library routines for floating-point operations.
-
-@item -malloc-cc
-@opindex malloc-cc
-
-Dynamically allocate condition code registers.
-
-@item -mfixed-cc
-@opindex mfixed-cc
-
-Do not try to dynamically allocate condition code registers, only
-use @code{icc0} and @code{fcc0}.
-
-@item -mdword
-@opindex mdword
-
-Change ABI to use double word insns.
-
-@item -mno-dword
-@opindex mno-dword
-
-Do not use double word instructions.
-
-@item -mdouble
-@opindex mdouble
-
-Use floating-point double instructions.
-
-@item -mno-double
-@opindex mno-double
-
-Do not use floating-point double instructions.
-
-@item -mmedia
-@opindex mmedia
-
-Use media instructions.
-
-@item -mno-media
-@opindex mno-media
-
-Do not use media instructions.
-
-@item -mmuladd
-@opindex mmuladd
-
-Use multiply and add/subtract instructions.
-
-@item -mno-muladd
-@opindex mno-muladd
-
-Do not use multiply and add/subtract instructions.
-
-@item -mfdpic
-@opindex mfdpic
-
-Select the FDPIC ABI, which uses function descriptors to represent
-pointers to functions. Without any PIC/PIE-related options, it
-implies @option{-fPIE}. With @option{-fpic} or @option{-fpie}, it
-assumes GOT entries and small data are within a 12-bit range from the
-GOT base address; with @option{-fPIC} or @option{-fPIE}, GOT offsets
-are computed with 32 bits.
-With a @samp{bfin-elf} target, this option implies @option{-msim}.
-
-@item -minline-plt
-@opindex minline-plt
-
-Enable inlining of PLT entries in function calls to functions that are
-not known to bind locally. It has no effect without @option{-mfdpic}.
-It's enabled by default if optimizing for speed and compiling for
-shared libraries (i.e., @option{-fPIC} or @option{-fpic}), or when an
-optimization option such as @option{-O3} or above is present in the
-command line.
-
-@item -mTLS
-@opindex mTLS
-
-Assume a large TLS segment when generating thread-local code.
-
-@item -mtls
-@opindex mtls
-
-Do not assume a large TLS segment when generating thread-local code.
-
-@item -mgprel-ro
-@opindex mgprel-ro
-
-Enable the use of @code{GPREL} relocations in the FDPIC ABI for data
-that is known to be in read-only sections. It's enabled by default,
-except for @option{-fpic} or @option{-fpie}: even though it may help
-make the global offset table smaller, it trades 1 instruction for 4.
-With @option{-fPIC} or @option{-fPIE}, it trades 3 instructions for 4,
-one of which may be shared by multiple symbols, and it avoids the need
-for a GOT entry for the referenced symbol, so it's more likely to be a
-win. If it is not, @option{-mno-gprel-ro} can be used to disable it.
-
-@item -multilib-library-pic
-@opindex multilib-library-pic
-
-Link with the (library, not FD) pic libraries. It's implied by
-@option{-mlibrary-pic}, as well as by @option{-fPIC} and
-@option{-fpic} without @option{-mfdpic}. You should never have to use
-it explicitly.
-
-@item -mlinked-fp
-@opindex mlinked-fp
-
-Follow the EABI requirement of always creating a frame pointer whenever
-a stack frame is allocated. This option is enabled by default and can
-be disabled with @option{-mno-linked-fp}.
-
-@item -mlong-calls
-@opindex mlong-calls
-
-Use indirect addressing to call functions outside the current
-compilation unit. This allows the functions to be placed anywhere
-within the 32-bit address space.
-
-@item -malign-labels
-@opindex malign-labels
-
-Try to align labels to an 8-byte boundary by inserting NOPs into the
-previous packet. This option only has an effect when VLIW packing
-is enabled. It doesn't create new packets; it merely adds NOPs to
-existing ones.
-
-@item -mlibrary-pic
-@opindex mlibrary-pic
-
-Generate position-independent EABI code.
-
-@item -macc-4
-@opindex macc-4
-
-Use only the first four media accumulator registers.
-
-@item -macc-8
-@opindex macc-8
-
-Use all eight media accumulator registers.
-
-@item -mpack
-@opindex mpack
-
-Pack VLIW instructions.
-
-@item -mno-pack
-@opindex mno-pack
-
-Do not pack VLIW instructions.
-
-@item -mno-eflags
-@opindex mno-eflags
-
-Do not mark ABI switches in e_flags.
-
-@item -mcond-move
-@opindex mcond-move
-
-Enable the use of conditional-move instructions (default).
-
-This switch is mainly for debugging the compiler and will likely be removed
-in a future version.
-
-@item -mno-cond-move
-@opindex mno-cond-move
-
-Disable the use of conditional-move instructions.
-
-This switch is mainly for debugging the compiler and will likely be removed
-in a future version.
-
-@item -mscc
-@opindex mscc
-
-Enable the use of conditional set instructions (default).
-
-This switch is mainly for debugging the compiler and will likely be removed
-in a future version.
-
-@item -mno-scc
-@opindex mno-scc
-
-Disable the use of conditional set instructions.
-
-This switch is mainly for debugging the compiler and will likely be removed
-in a future version.
-
-@item -mcond-exec
-@opindex mcond-exec
-
-Enable the use of conditional execution (default).
-
-This switch is mainly for debugging the compiler and will likely be removed
-in a future version.
-
-@item -mno-cond-exec
-@opindex mno-cond-exec
-
-Disable the use of conditional execution.
-
-This switch is mainly for debugging the compiler and will likely be removed
-in a future version.
-
-@item -mvliw-branch
-@opindex mvliw-branch
-
-Run a pass to pack branches into VLIW instructions (default).
-
-This switch is mainly for debugging the compiler and will likely be removed
-in a future version.
-
-@item -mno-vliw-branch
-@opindex mno-vliw-branch
-
-Do not run a pass to pack branches into VLIW instructions.
-
-This switch is mainly for debugging the compiler and will likely be removed
-in a future version.
-
-@item -mmulti-cond-exec
-@opindex mmulti-cond-exec
-
-Enable optimization of @code{&&} and @code{||} in conditional execution
-(default).
-
-This switch is mainly for debugging the compiler and will likely be removed
-in a future version.
-
-@item -mno-multi-cond-exec
-@opindex mno-multi-cond-exec
-
-Disable optimization of @code{&&} and @code{||} in conditional execution.
-
-This switch is mainly for debugging the compiler and will likely be removed
-in a future version.
-
-@item -mnested-cond-exec
-@opindex mnested-cond-exec
-
-Enable nested conditional execution optimizations (default).
-
-This switch is mainly for debugging the compiler and will likely be removed
-in a future version.
-
-@item -mno-nested-cond-exec
-@opindex mno-nested-cond-exec
-
-Disable nested conditional execution optimizations.
-
-This switch is mainly for debugging the compiler and will likely be removed
-in a future version.
-
-@item -moptimize-membar
-@opindex moptimize-membar
-
-This switch removes redundant @code{membar} instructions from the
-compiler-generated code. It is enabled by default.
-
-@item -mno-optimize-membar
-@opindex mno-optimize-membar
-
-This switch disables the automatic removal of redundant @code{membar}
-instructions from the generated code.
-
-@item -mtomcat-stats
-@opindex mtomcat-stats
-
-Cause gas to print out tomcat statistics.
-
-@item -mcpu=@var{cpu}
-@opindex mcpu
-
-Select the processor type for which to generate code. Possible values are
-@samp{frv}, @samp{fr550}, @samp{tomcat}, @samp{fr500}, @samp{fr450},
-@samp{fr405}, @samp{fr400}, @samp{fr300} and @samp{simple}.
-
-@end table
-
-@node GNU/Linux Options
-@subsection GNU/Linux Options
-
-These @samp{-m} options are defined for GNU/Linux targets:
-
-@table @gcctabopt
-@item -mglibc
-@opindex mglibc
-Use the GNU C library. This is the default except
-on @samp{*-*-linux-*uclibc*} and @samp{*-*-linux-*android*} targets.
-
-@item -muclibc
-@opindex muclibc
-Use uClibc C library. This is the default on
-@samp{*-*-linux-*uclibc*} targets.
-
-@item -mbionic
-@opindex mbionic
-Use Bionic C library. This is the default on
-@samp{*-*-linux-*android*} targets.
-
-@item -mandroid
-@opindex mandroid
-Compile code compatible with Android platform. This is the default on
-@samp{*-*-linux-*android*} targets.
-
-When compiling, this option enables @option{-mbionic}, @option{-fPIC},
-@option{-fno-exceptions} and @option{-fno-rtti} by default. When linking,
-this option makes the GCC driver pass Android-specific options to the linker.
-Finally, this option causes the preprocessor macro @code{__ANDROID__}
-to be defined.
-
-@item -tno-android-cc
-@opindex tno-android-cc
-Disable compilation effects of @option{-mandroid}, i.e., do not enable
-@option{-mbionic}, @option{-fPIC}, @option{-fno-exceptions} and
-@option{-fno-rtti} by default.
-
-@item -tno-android-ld
-@opindex tno-android-ld
-Disable linking effects of @option{-mandroid}, i.e., pass standard Linux
-linking options to the linker.
-
-@end table
-
-@node H8/300 Options
-@subsection H8/300 Options
-
-These @samp{-m} options are defined for the H8/300 implementations:
-
-@table @gcctabopt
-@item -mrelax
-@opindex mrelax
-Shorten some address references at link time, when possible; uses the
-linker option @option{-relax}. @xref{H8/300,, @code{ld} and the H8/300,
-ld, Using ld}, for a fuller description.
-
-@item -mh
-@opindex mh
-Generate code for the H8/300H@.
-
-@item -ms
-@opindex ms
-Generate code for the H8S@.
-
-@item -mn
-@opindex mn
-Generate code for the H8S and H8/300H in the normal mode. This switch
-must be used either with @option{-mh} or @option{-ms}.
-
-@item -ms2600
-@opindex ms2600
-Generate code for the H8S/2600. This switch must be used with @option{-ms}.
-
-@item -mexr
-@opindex mexr
-Extended registers are stored on stack before execution of function
-with monitor attribute. Default option is @option{-mexr}.
-This option is valid only for H8S targets.
-
-@item -mno-exr
-@opindex mno-exr
-Extended registers are not stored on stack before execution of function
-with monitor attribute. Default option is @option{-mno-exr}.
-This option is valid only for H8S targets.
-
-@item -mint32
-@opindex mint32
-Make @code{int} data 32 bits by default.
-
-@item -malign-300
-@opindex malign-300
-On the H8/300H and H8S, use the same alignment rules as for the H8/300.
-The default for the H8/300H and H8S is to align longs and floats on
-4-byte boundaries.
-@option{-malign-300} causes them to be aligned on 2-byte boundaries.
-This option has no effect on the H8/300.
-@end table
-
-@node HPPA Options
-@subsection HPPA Options
-@cindex HPPA Options
-
-These @samp{-m} options are defined for the HPPA family of computers:
-
-@table @gcctabopt
-@item -march=@var{architecture-type}
-@opindex march
-Generate code for the specified architecture. The choices for
-@var{architecture-type} are @samp{1.0} for PA 1.0, @samp{1.1} for PA
-1.1, and @samp{2.0} for PA 2.0 processors. Refer to
-@file{/usr/lib/sched.models} on an HP-UX system to determine the proper
-architecture option for your machine. Code compiled for lower numbered
-architectures runs on higher numbered architectures, but not the
-other way around.
-
-@item -mpa-risc-1-0
-@itemx -mpa-risc-1-1
-@itemx -mpa-risc-2-0
-@opindex mpa-risc-1-0
-@opindex mpa-risc-1-1
-@opindex mpa-risc-2-0
-Synonyms for @option{-march=1.0}, @option{-march=1.1}, and @option{-march=2.0} respectively.
-
-@item -mbig-switch
-@opindex mbig-switch
-Generate code suitable for big switch tables. Use this option only if
-the assembler/linker complain about out-of-range branches within a switch
-table.
-
-@item -mjump-in-delay
-@opindex mjump-in-delay
-Fill delay slots of function calls with unconditional jump instructions
-by modifying the return pointer for the function call to be the target
-of the conditional jump.
-
-@item -mdisable-fpregs
-@opindex mdisable-fpregs
-Prevent floating-point registers from being used in any manner. This is
-necessary for compiling kernels that perform lazy context switching of
-floating-point registers. If you use this option and attempt to perform
-floating-point operations, the compiler aborts.
-
-@item -mdisable-indexing
-@opindex mdisable-indexing
-Prevent the compiler from using indexing address modes. This avoids some
-rather obscure problems when compiling MIG generated code under MACH@.
-
-@item -mno-space-regs
-@opindex mno-space-regs
-Generate code that assumes the target has no space registers. This allows
-GCC to generate faster indirect calls and use unscaled index address modes.
-
-Such code is suitable for level 0 PA systems and kernels.
-
-@item -mfast-indirect-calls
-@opindex mfast-indirect-calls
-Generate code that assumes calls never cross space boundaries. This
-allows GCC to emit code that performs faster indirect calls.
-
-This option does not work in the presence of shared libraries or nested
-functions.
-
-@item -mfixed-range=@var{register-range}
-@opindex mfixed-range
-Generate code treating the given register range as fixed registers.
-A fixed register is one that the register allocator cannot use. This is
-useful when compiling kernel code. A register range is specified as
-two registers separated by a dash. Multiple register ranges can be
-specified separated by a comma.
-
-@item -mlong-load-store
-@opindex mlong-load-store
-Generate 3-instruction load and store sequences as sometimes required by
-the HP-UX 10 linker. This is equivalent to the @samp{+k} option to
-the HP compilers.
-
-@item -mportable-runtime
-@opindex mportable-runtime
-Use the portable calling conventions proposed by HP for ELF systems.
-
-@item -mgas
-@opindex mgas
-Enable the use of assembler directives only GAS understands.
-
-@item -mschedule=@var{cpu-type}
-@opindex mschedule
-Schedule code according to the constraints for the machine type
-@var{cpu-type}. The choices for @var{cpu-type} are @samp{700}
-@samp{7100}, @samp{7100LC}, @samp{7200}, @samp{7300} and @samp{8000}. Refer
-to @file{/usr/lib/sched.models} on an HP-UX system to determine the
-proper scheduling option for your machine. The default scheduling is
-@samp{8000}.
-
-@item -mlinker-opt
-@opindex mlinker-opt
-Enable the optimization pass in the HP-UX linker. Note this makes symbolic
-debugging impossible. It also triggers a bug in the HP-UX 8 and HP-UX 9
-linkers in which they give bogus error messages when linking some programs.
-
-@item -msoft-float
-@opindex msoft-float
-Generate output containing library calls for floating point.
-@strong{Warning:} the requisite libraries are not available for all HPPA
-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 -msio
-@opindex msio
-Generate the predefine, @code{_SIO}, for server IO@. The default is
-@option{-mwsio}. This generates the predefines, @code{__hp9000s700},
-@code{__hp9000s700__} and @code{_WSIO}, for workstation IO@. These
-options are available under HP-UX and HI-UX@.
-
-@item -mgnu-ld
-@opindex mgnu-ld
-Use options specific to GNU @command{ld}.
-This passes @option{-shared} to @command{ld} when
-building a shared library. It is the default when GCC is configured,
-explicitly or implicitly, with the GNU linker. This option does not
-affect which @command{ld} is called; it only changes what parameters
-are passed to that @command{ld}.
-The @command{ld} that is called is determined by the
-@option{--with-ld} configure option, GCC's program search path, and
-finally by the user's @env{PATH}. The linker used by GCC can be printed
-using @samp{which `gcc -print-prog-name=ld`}. This option is only available
-on the 64-bit HP-UX GCC, i.e.@: configured with @samp{hppa*64*-*-hpux*}.
-
-@item -mhp-ld
-@opindex mhp-ld
-Use options specific to HP @command{ld}.
-This passes @option{-b} to @command{ld} when building
-a shared library and passes @option{+Accept TypeMismatch} to @command{ld} on all
-links. It is the default when GCC is configured, explicitly or
-implicitly, with the HP linker. This option does not affect
-which @command{ld} is called; it only changes what parameters are passed to that
-@command{ld}.
-The @command{ld} that is called is determined by the @option{--with-ld}
-configure option, GCC's program search path, and finally by the user's
-@env{PATH}. The linker used by GCC can be printed using @samp{which
-`gcc -print-prog-name=ld`}. This option is only available on the 64-bit
-HP-UX GCC, i.e.@: configured with @samp{hppa*64*-*-hpux*}.
-
-@item -mlong-calls
-@opindex mno-long-calls
-Generate code that uses long call sequences. This ensures that a call
-is always able to reach linker generated stubs. The default is to generate
-long calls only when the distance from the call site to the beginning
-of the function or translation unit, as the case may be, exceeds a
-predefined limit set by the branch type being used. The limits for
-normal calls are 7,600,000 and 240,000 bytes, respectively for the
-PA 2.0 and PA 1.X architectures. Sibcalls are always limited at
-240,000 bytes.
-
-Distances are measured from the beginning of functions when using the
-@option{-ffunction-sections} option, or when using the @option{-mgas}
-and @option{-mno-portable-runtime} options together under HP-UX with
-the SOM linker.
-
-It is normally not desirable to use this option as it degrades
-performance. However, it may be useful in large applications,
-particularly when partial linking is used to build the application.
-
-The types of long calls used depends on the capabilities of the
-assembler and linker, and the type of code being generated. The
-impact on systems that support long absolute calls, and long pic
-symbol-difference or pc-relative calls should be relatively small.
-However, an indirect call is used on 32-bit ELF systems in pic code
-and it is quite long.
-
-@item -munix=@var{unix-std}
-@opindex march
-Generate compiler predefines and select a startfile for the specified
-UNIX standard. The choices for @var{unix-std} are @samp{93}, @samp{95}
-and @samp{98}. @samp{93} is supported on all HP-UX versions. @samp{95}
-is available on HP-UX 10.10 and later. @samp{98} is available on HP-UX
-11.11 and later. The default values are @samp{93} for HP-UX 10.00,
-@samp{95} for HP-UX 10.10 though to 11.00, and @samp{98} for HP-UX 11.11
-and later.
-
-@option{-munix=93} provides the same predefines as GCC 3.3 and 3.4.
-@option{-munix=95} provides additional predefines for @code{XOPEN_UNIX}
-and @code{_XOPEN_SOURCE_EXTENDED}, and the startfile @file{unix95.o}.
-@option{-munix=98} provides additional predefines for @code{_XOPEN_UNIX},
-@code{_XOPEN_SOURCE_EXTENDED}, @code{_INCLUDE__STDC_A1_SOURCE} and
-@code{_INCLUDE_XOPEN_SOURCE_500}, and the startfile @file{unix98.o}.
-
-It is @emph{important} to note that this option changes the interfaces
-for various library routines. It also affects the operational behavior
-of the C library. Thus, @emph{extreme} care is needed in using this
-option.
-
-Library code that is intended to operate with more than one UNIX
-standard must test, set and restore the variable @var{__xpg4_extended_mask}
-as appropriate. Most GNU software doesn't provide this capability.
-
-@item -nolibdld
-@opindex nolibdld
-Suppress the generation of link options to search libdld.sl when the
-@option{-static} option is specified on HP-UX 10 and later.
-
-@item -static
-@opindex static
-The HP-UX implementation of setlocale in libc has a dependency on
-libdld.sl. There isn't an archive version of libdld.sl. Thus,
-when the @option{-static} option is specified, special link options
-are needed to resolve this dependency.
-
-On HP-UX 10 and later, the GCC driver adds the necessary options to
-link with libdld.sl when the @option{-static} option is specified.
-This causes the resulting binary to be dynamic. On the 64-bit port,
-the linkers generate dynamic binaries by default in any case. The
-@option{-nolibdld} option can be used to prevent the GCC driver from
-adding these link options.
-
-@item -threads
-@opindex threads
-Add support for multithreading with the @dfn{dce thread} library
-under HP-UX@. This option sets flags for both the preprocessor and
-linker.
-@end table
-
-@node i386 and x86-64 Options
-@subsection Intel 386 and AMD x86-64 Options
-@cindex i386 Options
-@cindex x86-64 Options
-@cindex Intel 386 Options
-@cindex AMD x86-64 Options
-
-These @samp{-m} options are defined for the i386 and x86-64 family of
-computers:
-
-@table @gcctabopt
-
-@item -march=@var{cpu-type}
-@opindex march
-Generate instructions for the machine type @var{cpu-type}. In contrast to
-@option{-mtune=@var{cpu-type}}, which merely tunes the generated code
-for the specified @var{cpu-type}, @option{-march=@var{cpu-type}} allows GCC
-to generate code that may not run at all on processors other than the one
-indicated. Specifying @option{-march=@var{cpu-type}} implies
-@option{-mtune=@var{cpu-type}}.
-
-The choices for @var{cpu-type} are:
-
-@table @samp
-@item native
-This selects the CPU to generate code for at compilation time by determining
-the processor type of the compiling machine. Using @option{-march=native}
-enables all instruction subsets supported by the local machine (hence
-the result might not run on different machines). Using @option{-mtune=native}
-produces code optimized for the local machine under the constraints
-of the selected instruction set.
-
-@item i386
-Original Intel i386 CPU@.
-
-@item i486
-Intel i486 CPU@. (No scheduling is implemented for this chip.)
-
-@item i586
-@itemx pentium
-Intel Pentium CPU with no MMX support.
-
-@item pentium-mmx
-Intel Pentium MMX CPU, based on Pentium core with MMX instruction set support.
-
-@item pentiumpro
-Intel Pentium Pro CPU@.
-
-@item i686
-When used with @option{-march}, the Pentium Pro
-instruction set is used, so the code runs on all i686 family chips.
-When used with @option{-mtune}, it has the same meaning as @samp{generic}.
-
-@item pentium2
-Intel Pentium II CPU, based on Pentium Pro core with MMX instruction set
-support.
-
-@item pentium3
-@itemx pentium3m
-Intel Pentium III CPU, based on Pentium Pro core with MMX and SSE instruction
-set support.
-
-@item pentium-m
-Intel Pentium M; low-power version of Intel Pentium III CPU
-with MMX, SSE and SSE2 instruction set support. Used by Centrino notebooks.
-
-@item pentium4
-@itemx pentium4m
-Intel Pentium 4 CPU with MMX, SSE and SSE2 instruction set support.
-
-@item prescott
-Improved version of Intel Pentium 4 CPU with MMX, SSE, SSE2 and SSE3 instruction
-set support.
-
-@item nocona
-Improved version of Intel Pentium 4 CPU with 64-bit extensions, MMX, SSE,
-SSE2 and SSE3 instruction set support.
-
-@item core2
-Intel Core 2 CPU with 64-bit extensions, MMX, SSE, SSE2, SSE3 and SSSE3
-instruction set support.
-
-@item corei7
-Intel Core i7 CPU with 64-bit extensions, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1
-and SSE4.2 instruction set support.
-
-@item corei7-avx
-Intel Core i7 CPU with 64-bit extensions, MMX, SSE, SSE2, SSE3, SSSE3,
-SSE4.1, SSE4.2, AVX, AES and PCLMUL instruction set support.
-
-@item core-avx-i
-Intel Core CPU with 64-bit extensions, MMX, SSE, SSE2, SSE3, SSSE3,
-SSE4.1, SSE4.2, AVX, AES, PCLMUL, FSGSBASE, RDRND and F16C instruction
-set support.
-
-@item atom
-Intel Atom CPU with 64-bit extensions, MMX, SSE, SSE2, SSE3 and SSSE3
-instruction set support.
-
-@item k6
-AMD K6 CPU with MMX instruction set support.
-
-@item k6-2
-@itemx k6-3
-Improved versions of AMD K6 CPU with MMX and 3DNow!@: instruction set support.
-
-@item athlon
-@itemx athlon-tbird
-AMD Athlon CPU with MMX, 3dNOW!, enhanced 3DNow!@: and SSE prefetch instructions
-support.
-
-@item athlon-4
-@itemx athlon-xp
-@itemx athlon-mp
-Improved AMD Athlon CPU with MMX, 3DNow!, enhanced 3DNow!@: and full SSE
-instruction set support.
-
-@item k8
-@itemx opteron
-@itemx athlon64
-@itemx athlon-fx
-Processors based on the AMD K8 core with x86-64 instruction set support,
-including the AMD Opteron, Athlon 64, and Athlon 64 FX processors.
-(This supersets MMX, SSE, SSE2, 3DNow!, enhanced 3DNow!@: and 64-bit
-instruction set extensions.)
-
-@item k8-sse3
-@itemx opteron-sse3
-@itemx athlon64-sse3
-Improved versions of AMD K8 cores with SSE3 instruction set support.
-
-@item amdfam10
-@itemx barcelona
-CPUs based on AMD Family 10h cores with x86-64 instruction set support. (This
-supersets MMX, SSE, SSE2, SSE3, SSE4A, 3DNow!, enhanced 3DNow!, ABM and 64-bit
-instruction set extensions.)
-
-@item bdver1
-CPUs based on AMD Family 15h cores with x86-64 instruction set support. (This
-supersets FMA4, AVX, XOP, LWP, AES, PCL_MUL, CX16, MMX, SSE, SSE2, SSE3, SSE4A,
-SSSE3, SSE4.1, SSE4.2, ABM and 64-bit instruction set extensions.)
-@item bdver2
-AMD Family 15h core based CPUs with x86-64 instruction set support. (This
-supersets BMI, TBM, F16C, FMA, AVX, XOP, LWP, AES, PCL_MUL, CX16, MMX, SSE,
-SSE2, SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM and 64-bit instruction set
-extensions.)
-@item bdver3
-AMD Family 15h core based CPUs with x86-64 instruction set support. (This
-supersets BMI, TBM, F16C, FMA, AVX, XOP, LWP, AES, PCL_MUL, CX16, MMX, SSE,
-SSE2, SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM and 64-bit instruction set
-extensions.
-
-@item btver1
-CPUs based on AMD Family 14h cores with x86-64 instruction set support. (This
-supersets MMX, SSE, SSE2, SSE3, SSSE3, SSE4A, CX16, ABM and 64-bit
-instruction set extensions.)
-
-@item btver2
-CPUs based on AMD Family 16h cores with x86-64 instruction set support. This
-includes MOVBE, F16C, BMI, AVX, PCL_MUL, AES, SSE4.2, SSE4.1, CX16, ABM,
-SSE4A, SSSE3, SSE3, SSE2, SSE, MMX and 64-bit instruction set extensions.
-
-@item winchip-c6
-IDT WinChip C6 CPU, dealt in same way as i486 with additional MMX instruction
-set support.
-
-@item winchip2
-IDT WinChip 2 CPU, dealt in same way as i486 with additional MMX and 3DNow!@:
-instruction set support.
-
-@item c3
-VIA C3 CPU with MMX and 3DNow!@: instruction set support. (No scheduling is
-implemented for this chip.)
-
-@item c3-2
-VIA C3-2 (Nehemiah/C5XL) CPU with MMX and SSE instruction set support.
-(No scheduling is
-implemented for this chip.)
-
-@item geode
-AMD Geode embedded processor with MMX and 3DNow!@: instruction set support.
-@end table
-
-@item -mtune=@var{cpu-type}
-@opindex mtune
-Tune to @var{cpu-type} everything applicable about the generated code, except
-for the ABI and the set of available instructions.
-While picking a specific @var{cpu-type} schedules things appropriately
-for that particular chip, the compiler does not generate any code that
-cannot run on the default machine type unless you use a
-@option{-march=@var{cpu-type}} option.
-For example, if GCC is configured for i686-pc-linux-gnu
-then @option{-mtune=pentium4} generates code that is tuned for Pentium 4
-but still runs on i686 machines.
-
-The choices for @var{cpu-type} are the same as for @option{-march}.
-In addition, @option{-mtune} supports an extra choice for @var{cpu-type}:
-
-@table @samp
-@item generic
-Produce code optimized for the most common IA32/@/AMD64/@/EM64T processors.
-If you know the CPU on which your code will run, then you should use
-the corresponding @option{-mtune} or @option{-march} option instead of
-@option{-mtune=generic}. But, if you do not know exactly what CPU users
-of your application will have, then you should use this option.
-
-As new processors are deployed in the marketplace, the behavior of this
-option will change. Therefore, if you upgrade to a newer version of
-GCC, code generation controlled by this option will change to reflect
-the processors
-that are most common at the time that version of GCC is released.
-
-There is no @option{-march=generic} option because @option{-march}
-indicates the instruction set the compiler can use, and there is no
-generic instruction set applicable to all processors. In contrast,
-@option{-mtune} indicates the processor (or, in this case, collection of
-processors) for which the code is optimized.
-@end table
-
-@item -mcpu=@var{cpu-type}
-@opindex mcpu
-A deprecated synonym for @option{-mtune}.
-
-@item -mfpmath=@var{unit}
-@opindex mfpmath
-Generate floating-point arithmetic for selected unit @var{unit}. The choices
-for @var{unit} are:
-
-@table @samp
-@item 387
-Use the standard 387 floating-point coprocessor present on the majority of chips and
-emulated otherwise. Code compiled with this option runs almost everywhere.
-The temporary results are computed in 80-bit precision instead of the precision
-specified by the type, resulting in slightly different results compared to most
-of other chips. See @option{-ffloat-store} for more detailed description.
-
-This is the default choice for i386 compiler.
-
-@item sse
-Use scalar floating-point instructions present in the SSE instruction set.
-This instruction set is supported by Pentium III and newer chips,
-and in the AMD line
-by Athlon-4, Athlon XP and Athlon MP chips. The earlier version of the SSE
-instruction set supports only single-precision arithmetic, thus the double and
-extended-precision arithmetic are still done using 387. A later version, present
-only in Pentium 4 and AMD x86-64 chips, supports double-precision
-arithmetic too.
-
-For the i386 compiler, you must use @option{-march=@var{cpu-type}}, @option{-msse}
-or @option{-msse2} switches to enable SSE extensions and make this option
-effective. For the x86-64 compiler, these extensions are enabled by default.
-
-The resulting code should be considerably faster in the majority of cases and avoid
-the numerical instability problems of 387 code, but may break some existing
-code that expects temporaries to be 80 bits.
-
-This is the default choice for the x86-64 compiler.
-
-@item sse,387
-@itemx sse+387
-@itemx both
-Attempt to utilize both instruction sets at once. This effectively doubles the
-amount of available registers, and on chips with separate execution units for
-387 and SSE the execution resources too. Use this option with care, as it is
-still experimental, because the GCC register allocator does not model separate
-functional units well, resulting in unstable performance.
-@end table
-
-@item -masm=@var{dialect}
-@opindex masm=@var{dialect}
-Output assembly instructions using selected @var{dialect}. Supported
-choices are @samp{intel} or @samp{att} (the default). Darwin does
-not support @samp{intel}.
-
-@item -mieee-fp
-@itemx -mno-ieee-fp
-@opindex mieee-fp
-@opindex mno-ieee-fp
-Control whether or not the compiler uses IEEE floating-point
-comparisons. These correctly handle the case where the result of a
-comparison is unordered.
-
-@item -msoft-float
-@opindex msoft-float
-Generate output containing library calls for floating point.
-
-@strong{Warning:} the requisite libraries are not part of GCC@.
-Normally the facilities of the machine's usual C compiler are used, but
-this can't be done directly in cross-compilation. You must make your
-own arrangements to provide suitable library functions for
-cross-compilation.
-
-On machines where a function returns floating-point results in the 80387
-register stack, some floating-point opcodes may be emitted even if
-@option{-msoft-float} is used.
-
-@item -mno-fp-ret-in-387
-@opindex mno-fp-ret-in-387
-Do not use the FPU registers for return values of functions.
-
-The usual calling convention has functions return values of types
-@code{float} and @code{double} in an FPU register, even if there
-is no FPU@. The idea is that the operating system should emulate
-an FPU@.
-
-The option @option{-mno-fp-ret-in-387} causes such values to be returned
-in ordinary CPU registers instead.
-
-@item -mno-fancy-math-387
-@opindex mno-fancy-math-387
-Some 387 emulators do not support the @code{sin}, @code{cos} and
-@code{sqrt} instructions for the 387. Specify this option to avoid
-generating those instructions. This option is the default on FreeBSD,
-OpenBSD and NetBSD@. This option is overridden when @option{-march}
-indicates that the target CPU always has an FPU and so the
-instruction does not need emulation. These
-instructions are not generated unless you also use the
-@option{-funsafe-math-optimizations} switch.
-
-@item -malign-double
-@itemx -mno-align-double
-@opindex malign-double
-@opindex mno-align-double
-Control whether GCC aligns @code{double}, @code{long double}, and
-@code{long long} variables on a two-word boundary or a one-word
-boundary. Aligning @code{double} variables on a two-word boundary
-produces code that runs somewhat faster on a Pentium at the
-expense of more memory.
-
-On x86-64, @option{-malign-double} is enabled by default.
-
-@strong{Warning:} if you use the @option{-malign-double} switch,
-structures containing the above types are aligned differently than
-the published application binary interface specifications for the 386
-and are not binary compatible with structures in code compiled
-without that switch.
-
-@item -m96bit-long-double
-@itemx -m128bit-long-double
-@opindex m96bit-long-double
-@opindex m128bit-long-double
-These switches control the size of @code{long double} type. The i386
-application binary interface specifies the size to be 96 bits,
-so @option{-m96bit-long-double} is the default in 32-bit mode.
-
-Modern architectures (Pentium and newer) prefer @code{long double}
-to be aligned to an 8- or 16-byte boundary. In arrays or structures
-conforming to the ABI, this is not possible. So specifying
-@option{-m128bit-long-double} aligns @code{long double}
-to a 16-byte boundary by padding the @code{long double} with an additional
-32-bit zero.
-
-In the x86-64 compiler, @option{-m128bit-long-double} is the default choice as
-its ABI specifies that @code{long double} is aligned on 16-byte boundary.
-
-Notice that neither of these options enable any extra precision over the x87
-standard of 80 bits for a @code{long double}.
-
-@strong{Warning:} if you override the default value for your target ABI, this
-changes the size of
-structures and arrays containing @code{long double} variables,
-as well as modifying the function calling convention for functions taking
-@code{long double}. Hence they are not binary-compatible
-with code compiled without that switch.
-
-@item -mlong-double-64
-@itemx -mlong-double-80
-@opindex mlong-double-64
-@opindex mlong-double-80
-These switches control the size of @code{long double} type. A size
-of 64 bits makes the @code{long double} type equivalent to the @code{double}
-type. This is the default for Bionic C library.
-
-@strong{Warning:} if you override the default value for your target ABI, this
-changes the size of
-structures and arrays containing @code{long double} variables,
-as well as modifying the function calling convention for functions taking
-@code{long double}. Hence they are not binary-compatible
-with code compiled without that switch.
-
-@item -mlarge-data-threshold=@var{threshold}
-@opindex mlarge-data-threshold
-When @option{-mcmodel=medium} is specified, data objects larger than
-@var{threshold} are placed in the large data section. This value must be the
-same across all objects linked into the binary, and defaults to 65535.
-
-@item -mrtd
-@opindex mrtd
-Use a different function-calling convention, in which functions that
-take a fixed number of arguments return with the @code{ret @var{num}}
-instruction, which pops their arguments while returning. This saves one
-instruction in the caller since there is no need to pop the arguments
-there.
-
-You can specify that an individual function is called with this calling
-sequence with the function attribute @samp{stdcall}. You can also
-override the @option{-mrtd} option by using the function attribute
-@samp{cdecl}. @xref{Function Attributes}.
-
-@strong{Warning:} this calling convention is incompatible with the one
-normally used on Unix, so you cannot use it if you need to call
-libraries compiled with the Unix compiler.
-
-Also, you must provide function prototypes for all functions that
-take variable numbers of arguments (including @code{printf});
-otherwise incorrect code is generated for calls to those
-functions.
-
-In addition, seriously incorrect code results if you call a
-function with too many arguments. (Normally, extra arguments are
-harmlessly ignored.)
-
-@item -mregparm=@var{num}
-@opindex mregparm
-Control how many registers are used to pass integer arguments. By
-default, no registers are used to pass arguments, and at most 3
-registers can be used. You can control this behavior for a specific
-function by using the function attribute @samp{regparm}.
-@xref{Function Attributes}.
-
-@strong{Warning:} if you use this switch, and
-@var{num} is nonzero, then you must build all modules with the same
-value, including any libraries. This includes the system libraries and
-startup modules.
-
-@item -msseregparm
-@opindex msseregparm
-Use SSE register passing conventions for float and double arguments
-and return values. You can control this behavior for a specific
-function by using the function attribute @samp{sseregparm}.
-@xref{Function Attributes}.
-
-@strong{Warning:} if you use this switch then you must build all
-modules with the same value, including any libraries. This includes
-the system libraries and startup modules.
-
-@item -mvect8-ret-in-mem
-@opindex mvect8-ret-in-mem
-Return 8-byte vectors in memory instead of MMX registers. This is the
-default on Solaris@tie{}8 and 9 and VxWorks to match the ABI of the Sun
-Studio compilers until version 12. Later compiler versions (starting
-with Studio 12 Update@tie{}1) follow the ABI used by other x86 targets, which
-is the default on Solaris@tie{}10 and later. @emph{Only} use this option if
-you need to remain compatible with existing code produced by those
-previous compiler versions or older versions of GCC@.
-
-@item -mpc32
-@itemx -mpc64
-@itemx -mpc80
-@opindex mpc32
-@opindex mpc64
-@opindex mpc80
-
-Set 80387 floating-point precision to 32, 64 or 80 bits. When @option{-mpc32}
-is specified, the significands of results of floating-point operations are
-rounded to 24 bits (single precision); @option{-mpc64} rounds the
-significands of results of floating-point operations to 53 bits (double
-precision) and @option{-mpc80} rounds the significands of results of
-floating-point operations to 64 bits (extended double precision), which is
-the default. When this option is used, floating-point operations in higher
-precisions are not available to the programmer without setting the FPU
-control word explicitly.
-
-Setting the rounding of floating-point operations to less than the default
-80 bits can speed some programs by 2% or more. Note that some mathematical
-libraries assume that extended-precision (80-bit) floating-point operations
-are enabled by default; routines in such libraries could suffer significant
-loss of accuracy, typically through so-called ``catastrophic cancellation'',
-when this option is used to set the precision to less than extended precision.
-
-@item -mstackrealign
-@opindex mstackrealign
-Realign the stack at entry. On the Intel x86, the @option{-mstackrealign}
-option generates an alternate prologue and epilogue that realigns the
-run-time stack if necessary. This supports mixing legacy codes that keep
-4-byte stack alignment with modern codes that keep 16-byte stack alignment for
-SSE compatibility. See also the attribute @code{force_align_arg_pointer},
-applicable to individual functions.
-
-@item -mpreferred-stack-boundary=@var{num}
-@opindex mpreferred-stack-boundary
-Attempt to keep the stack boundary aligned to a 2 raised to @var{num}
-byte boundary. If @option{-mpreferred-stack-boundary} is not specified,
-the default is 4 (16 bytes or 128 bits).
-
-@strong{Warning:} When generating code for the x86-64 architecture with
-SSE extensions disabled, @option{-mpreferred-stack-boundary=3} can be
-used to keep the stack boundary aligned to 8 byte boundary. Since
-x86-64 ABI require 16 byte stack alignment, this is ABI incompatible and
-intended to be used in controlled environment where stack space is
-important limitation. This option will lead to wrong code when functions
-compiled with 16 byte stack alignment (such as functions from a standard
-library) are called with misaligned stack. In this case, SSE
-instructions may lead to misaligned memory access traps. In addition,
-variable arguments will be handled incorrectly for 16 byte aligned
-objects (including x87 long double and __int128), leading to wrong
-results. You must build all modules with
-@option{-mpreferred-stack-boundary=3}, including any libraries. This
-includes the system libraries and startup modules.
-
-@item -mincoming-stack-boundary=@var{num}
-@opindex mincoming-stack-boundary
-Assume the incoming stack is aligned to a 2 raised to @var{num} byte
-boundary. If @option{-mincoming-stack-boundary} is not specified,
-the one specified by @option{-mpreferred-stack-boundary} is used.
-
-On Pentium and Pentium Pro, @code{double} and @code{long double} values
-should be aligned to an 8-byte boundary (see @option{-malign-double}) or
-suffer significant run time performance penalties. On Pentium III, the
-Streaming SIMD Extension (SSE) data type @code{__m128} may not work
-properly if it is not 16-byte aligned.
-
-To ensure proper alignment of this values on the stack, the stack boundary
-must be as aligned as that required by any value stored on the stack.
-Further, every function must be generated such that it keeps the stack
-aligned. Thus calling a function compiled with a higher preferred
-stack boundary from a function compiled with a lower preferred stack
-boundary most likely misaligns the stack. It is recommended that
-libraries that use callbacks always use the default setting.
-
-This extra alignment does consume extra stack space, and generally
-increases code size. Code that is sensitive to stack space usage, such
-as embedded systems and operating system kernels, may want to reduce the
-preferred alignment to @option{-mpreferred-stack-boundary=2}.
-
-@item -mmmx
-@itemx -mno-mmx
-@itemx -msse
-@itemx -mno-sse
-@itemx -msse2
-@itemx -mno-sse2
-@itemx -msse3
-@itemx -mno-sse3
-@itemx -mssse3
-@itemx -mno-ssse3
-@itemx -msse4.1
-@need 800
-@itemx -mno-sse4.1
-@itemx -msse4.2
-@itemx -mno-sse4.2
-@itemx -msse4
-@itemx -mno-sse4
-@itemx -mavx
-@itemx -mno-avx
-@itemx -mavx2
-@itemx -mno-avx2
-@itemx -maes
-@itemx -mno-aes
-@itemx -mpclmul
-@need 800
-@itemx -mno-pclmul
-@itemx -mfsgsbase
-@itemx -mno-fsgsbase
-@itemx -mrdrnd
-@itemx -mno-rdrnd
-@itemx -mf16c
-@itemx -mno-f16c
-@itemx -mfma
-@itemx -mno-fma
-@itemx -msse4a
-@itemx -mno-sse4a
-@itemx -mfma4
-@need 800
-@itemx -mno-fma4
-@itemx -mxop
-@itemx -mno-xop
-@itemx -mlwp
-@itemx -mno-lwp
-@itemx -m3dnow
-@itemx -mno-3dnow
-@itemx -mpopcnt
-@itemx -mno-popcnt
-@itemx -mabm
-@itemx -mno-abm
-@itemx -mbmi
-@itemx -mbmi2
-@itemx -mno-bmi
-@itemx -mno-bmi2
-@itemx -mlzcnt
-@itemx -mno-lzcnt
-@itemx -mrtm
-@itemx -mtbm
-@itemx -mno-tbm
-@opindex mmmx
-@opindex mno-mmx
-@opindex msse
-@opindex mno-sse
-@opindex m3dnow
-@opindex mno-3dnow
-These switches enable or disable the use of instructions in the MMX, SSE,
-SSE2, SSE3, SSSE3, SSE4.1, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, F16C,
-FMA, SSE4A, FMA4, XOP, LWP, ABM, BMI, BMI2, LZCNT, RTM or 3DNow!@:
-extended instruction sets.
-These extensions are also available as built-in functions: see
-@ref{X86 Built-in Functions}, for details of the functions enabled and
-disabled by these switches.
-
-To generate SSE/SSE2 instructions automatically from floating-point
-code (as opposed to 387 instructions), see @option{-mfpmath=sse}.
-
-GCC depresses SSEx instructions when @option{-mavx} is used. Instead, it
-generates new AVX instructions or AVX equivalence for all SSEx instructions
-when needed.
-
-These options enable GCC to use these extended instructions in
-generated code, even without @option{-mfpmath=sse}. Applications that
-perform run-time CPU detection must compile separate files for each
-supported architecture, using the appropriate flags. In particular,
-the file containing the CPU detection code should be compiled without
-these options.
-
-@item -mcld
-@opindex mcld
-This option instructs GCC to emit a @code{cld} instruction in the prologue
-of functions that use string instructions. String instructions depend on
-the DF flag to select between autoincrement or autodecrement mode. While the
-ABI specifies the DF flag to be cleared on function entry, some operating
-systems violate this specification by not clearing the DF flag in their
-exception dispatchers. The exception handler can be invoked with the DF flag
-set, which leads to wrong direction mode when string instructions are used.
-This option can be enabled by default on 32-bit x86 targets by configuring
-GCC with the @option{--enable-cld} configure option. Generation of @code{cld}
-instructions can be suppressed with the @option{-mno-cld} compiler option
-in this case.
-
-@item -mvzeroupper
-@opindex mvzeroupper
-This option instructs GCC to emit a @code{vzeroupper} instruction
-before a transfer of control flow out of the function to minimize
-the AVX to SSE transition penalty as well as remove unnecessary @code{zeroupper}
-intrinsics.
-
-@item -mprefer-avx128
-@opindex mprefer-avx128
-This option instructs GCC to use 128-bit AVX instructions instead of
-256-bit AVX instructions in the auto-vectorizer.
-
-@item -mcx16
-@opindex mcx16
-This option enables GCC to generate @code{CMPXCHG16B} instructions.
-@code{CMPXCHG16B} allows for atomic operations on 128-bit double quadword
-(or oword) data types.
-This is useful for high-resolution counters that can be updated
-by multiple processors (or cores). This instruction is generated as part of
-atomic built-in functions: see @ref{__sync Builtins} or
-@ref{__atomic Builtins} for details.
-
-@item -msahf
-@opindex msahf
-This option enables generation of @code{SAHF} instructions in 64-bit code.
-Early Intel Pentium 4 CPUs with Intel 64 support,
-prior to the introduction of Pentium 4 G1 step in December 2005,
-lacked the @code{LAHF} and @code{SAHF} instructions
-which were supported by AMD64.
-These are load and store instructions, respectively, for certain status flags.
-In 64-bit mode, the @code{SAHF} instruction is used to optimize @code{fmod},
-@code{drem}, and @code{remainder} built-in functions;
-see @ref{Other Builtins} for details.
-
-@item -mmovbe
-@opindex mmovbe
-This option enables use of the @code{movbe} instruction to implement
-@code{__builtin_bswap32} and @code{__builtin_bswap64}.
-
-@item -mcrc32
-@opindex mcrc32
-This option enables built-in functions @code{__builtin_ia32_crc32qi},
-@code{__builtin_ia32_crc32hi}, @code{__builtin_ia32_crc32si} and
-@code{__builtin_ia32_crc32di} to generate the @code{crc32} machine instruction.
-
-@item -mrecip
-@opindex mrecip
-This option enables use of @code{RCPSS} and @code{RSQRTSS} instructions
-(and their vectorized variants @code{RCPPS} and @code{RSQRTPS})
-with an additional Newton-Raphson step
-to increase precision instead of @code{DIVSS} and @code{SQRTSS}
-(and their vectorized
-variants) for single-precision floating-point arguments. These instructions
-are generated only when @option{-funsafe-math-optimizations} is enabled
-together with @option{-finite-math-only} and @option{-fno-trapping-math}.
-Note that while the throughput of the sequence is higher than the throughput
-of the non-reciprocal instruction, the precision of the sequence can be
-decreased by up to 2 ulp (i.e. the inverse of 1.0 equals 0.99999994).
-
-Note that GCC implements @code{1.0f/sqrtf(@var{x})} in terms of @code{RSQRTSS}
-(or @code{RSQRTPS}) already with @option{-ffast-math} (or the above option
-combination), and doesn't need @option{-mrecip}.
-
-Also note that GCC emits the above sequence with additional Newton-Raphson step
-for vectorized single-float division and vectorized @code{sqrtf(@var{x})}
-already with @option{-ffast-math} (or the above option combination), and
-doesn't need @option{-mrecip}.
-
-@item -mrecip=@var{opt}
-@opindex mrecip=opt
-This option controls which reciprocal estimate instructions
-may be used. @var{opt} is a comma-separated list of options, which may
-be preceded by a @samp{!} to invert the option:
-
-@table @samp
-@item all
-Enable all estimate instructions.
-
-@item default
-Enable the default instructions, equivalent to @option{-mrecip}.
-
-@item none
-Disable all estimate instructions, equivalent to @option{-mno-recip}.
-
-@item div
-Enable the approximation for scalar division.
-
-@item vec-div
-Enable the approximation for vectorized division.
-
-@item sqrt
-Enable the approximation for scalar square root.
-
-@item vec-sqrt
-Enable the approximation for vectorized square root.
-@end table
-
-So, for example, @option{-mrecip=all,!sqrt} enables
-all of the reciprocal approximations, except for square root.
-
-@item -mveclibabi=@var{type}
-@opindex mveclibabi
-Specifies the ABI type to use for vectorizing intrinsics using an
-external library. Supported values for @var{type} are @samp{svml}
-for the Intel short
-vector math library and @samp{acml} for the AMD math core library.
-To use this option, both @option{-ftree-vectorize} and
-@option{-funsafe-math-optimizations} have to be enabled, and an SVML or ACML
-ABI-compatible library must be specified at link time.
-
-GCC currently emits calls to @code{vmldExp2},
-@code{vmldLn2}, @code{vmldLog102}, @code{vmldLog102}, @code{vmldPow2},
-@code{vmldTanh2}, @code{vmldTan2}, @code{vmldAtan2}, @code{vmldAtanh2},
-@code{vmldCbrt2}, @code{vmldSinh2}, @code{vmldSin2}, @code{vmldAsinh2},
-@code{vmldAsin2}, @code{vmldCosh2}, @code{vmldCos2}, @code{vmldAcosh2},
-@code{vmldAcos2}, @code{vmlsExp4}, @code{vmlsLn4}, @code{vmlsLog104},
-@code{vmlsLog104}, @code{vmlsPow4}, @code{vmlsTanh4}, @code{vmlsTan4},
-@code{vmlsAtan4}, @code{vmlsAtanh4}, @code{vmlsCbrt4}, @code{vmlsSinh4},
-@code{vmlsSin4}, @code{vmlsAsinh4}, @code{vmlsAsin4}, @code{vmlsCosh4},
-@code{vmlsCos4}, @code{vmlsAcosh4} and @code{vmlsAcos4} for corresponding
-function type when @option{-mveclibabi=svml} is used, and @code{__vrd2_sin},
-@code{__vrd2_cos}, @code{__vrd2_exp}, @code{__vrd2_log}, @code{__vrd2_log2},
-@code{__vrd2_log10}, @code{__vrs4_sinf}, @code{__vrs4_cosf},
-@code{__vrs4_expf}, @code{__vrs4_logf}, @code{__vrs4_log2f},
-@code{__vrs4_log10f} and @code{__vrs4_powf} for the corresponding function type
-when @option{-mveclibabi=acml} is used.
-
-@item -mabi=@var{name}
-@opindex mabi
-Generate code for the specified calling convention. Permissible values
-are @samp{sysv} for the ABI used on GNU/Linux and other systems, and
-@samp{ms} for the Microsoft ABI. The default is to use the Microsoft
-ABI when targeting Microsoft Windows and the SysV ABI on all other systems.
-You can control this behavior for a specific function by
-using the function attribute @samp{ms_abi}/@samp{sysv_abi}.
-@xref{Function Attributes}.
-
-@item -mtls-dialect=@var{type}
-@opindex mtls-dialect
-Generate code to access thread-local storage using the @samp{gnu} or
-@samp{gnu2} conventions. @samp{gnu} is the conservative default;
-@samp{gnu2} is more efficient, but it may add compile- and run-time
-requirements that cannot be satisfied on all systems.
-
-@item -mpush-args
-@itemx -mno-push-args
-@opindex mpush-args
-@opindex mno-push-args
-Use PUSH operations to store outgoing parameters. This method is shorter
-and usually equally fast as method using SUB/MOV operations and is enabled
-by default. In some cases disabling it may improve performance because of
-improved scheduling and reduced dependencies.
-
-@item -maccumulate-outgoing-args
-@opindex maccumulate-outgoing-args
-If enabled, the maximum amount of space required for outgoing arguments is
-computed in the function prologue. This is faster on most modern CPUs
-because of reduced dependencies, improved scheduling and reduced stack usage
-when the preferred stack boundary is not equal to 2. The drawback is a notable
-increase in code size. This switch implies @option{-mno-push-args}.
-
-@item -mthreads
-@opindex mthreads
-Support thread-safe exception handling on MinGW. Programs that rely
-on thread-safe exception handling must compile and link all code with the
-@option{-mthreads} option. When compiling, @option{-mthreads} defines
-@code{-D_MT}; when linking, it links in a special thread helper library
-@option{-lmingwthrd} which cleans up per-thread exception-handling data.
-
-@item -mno-align-stringops
-@opindex mno-align-stringops
-Do not align the destination of inlined string operations. This switch reduces
-code size and improves performance in case the destination is already aligned,
-but GCC doesn't know about it.
-
-@item -minline-all-stringops
-@opindex minline-all-stringops
-By default GCC inlines string operations only when the destination is
-known to be aligned to least a 4-byte boundary.
-This enables more inlining and increases code
-size, but may improve performance of code that depends on fast
-@code{memcpy}, @code{strlen},
-and @code{memset} for short lengths.
-
-@item -minline-stringops-dynamically
-@opindex minline-stringops-dynamically
-For string operations of unknown size, use run-time checks with
-inline code for small blocks and a library call for large blocks.
-
-@item -mstringop-strategy=@var{alg}
-@opindex mstringop-strategy=@var{alg}
-Override the internal decision heuristic for the particular algorithm to use
-for inlining string operations. The allowed values for @var{alg} are:
-
-@table @samp
-@item rep_byte
-@itemx rep_4byte
-@itemx rep_8byte
-Expand using i386 @code{rep} prefix of the specified size.
-
-@item byte_loop
-@itemx loop
-@itemx unrolled_loop
-Expand into an inline loop.
-
-@item libcall
-Always use a library call.
-@end table
-
-@item -momit-leaf-frame-pointer
-@opindex momit-leaf-frame-pointer
-Don't keep the frame pointer in a register for leaf functions. This
-avoids the instructions to save, set up, and restore frame pointers and
-makes an extra register available in leaf functions. The option
-@option{-fomit-leaf-frame-pointer} removes the frame pointer for leaf functions,
-which might make debugging harder.
-
-@item -mtls-direct-seg-refs
-@itemx -mno-tls-direct-seg-refs
-@opindex mtls-direct-seg-refs
-Controls whether TLS variables may be accessed with offsets from the
-TLS segment register (@code{%gs} for 32-bit, @code{%fs} for 64-bit),
-or whether the thread base pointer must be added. Whether or not this
-is valid depends on the operating system, and whether it maps the
-segment to cover the entire TLS area.
-
-For systems that use the GNU C Library, the default is on.
-
-@item -msse2avx
-@itemx -mno-sse2avx
-@opindex msse2avx
-Specify that the assembler should encode SSE instructions with VEX
-prefix. The option @option{-mavx} turns this on by default.
-
-@item -mfentry
-@itemx -mno-fentry
-@opindex mfentry
-If profiling is active (@option{-pg}), put the profiling
-counter call before the prologue.
-Note: On x86 architectures the attribute @code{ms_hook_prologue}
-isn't possible at the moment for @option{-mfentry} and @option{-pg}.
-
-@item -m8bit-idiv
-@itemx -mno-8bit-idiv
-@opindex 8bit-idiv
-On some processors, like Intel Atom, 8-bit unsigned integer divide is
-much faster than 32-bit/64-bit integer divide. This option generates a
-run-time check. If both dividend and divisor are within range of 0
-to 255, 8-bit unsigned integer divide is used instead of
-32-bit/64-bit integer divide.
-
-@item -mavx256-split-unaligned-load
-@itemx -mavx256-split-unaligned-store
-@opindex avx256-split-unaligned-load
-@opindex avx256-split-unaligned-store
-Split 32-byte AVX unaligned load and store.
-
-@item -mstack-protector-guard=@var{guard}
-@opindex mstack-protector-guard=@var{guard}
-Generate stack protection code using canary at @var{guard}. Supported
-locations are @samp{global} or @samp{tls} per thread at %gs:20 (the default).
-This option has effect only when @option{-fstack-protector}
-or @option{-fstack-protector-all} is also specified.
-
-@end table
-
-These @samp{-m} switches are supported in addition to the above
-on x86-64 processors in 64-bit environments.
-
-@table @gcctabopt
-@item -m32
-@itemx -m64
-@itemx -mx32
-@opindex m32
-@opindex m64
-@opindex mx32
-Generate code for a 32-bit or 64-bit environment.
-The @option{-m32} option sets @code{int}, @code{long}, and pointer types
-to 32 bits, and
-generates code that runs on any i386 system.
-
-The @option{-m64} option sets @code{int} to 32 bits and @code{long} and pointer
-types to 64 bits, and generates code for the x86-64 architecture.
-For Darwin only the @option{-m64} option also turns off the @option{-fno-pic}
-and @option{-mdynamic-no-pic} options.
-
-The @option{-mx32} option sets @code{int}, @code{long}, and pointer types
-to 32 bits, and
-generates code for the x86-64 architecture.
-
-@item -mno-red-zone
-@opindex mno-red-zone
-Do not use a so-called ``red zone'' for x86-64 code. The red zone is mandated
-by the x86-64 ABI; it is a 128-byte area beyond the location of the
-stack pointer that is not modified by signal or interrupt handlers
-and therefore can be used for temporary data without adjusting the stack
-pointer. The flag @option{-mno-red-zone} disables this red zone.
-
-@item -mcmodel=small
-@opindex mcmodel=small
-Generate code for the small code model: the program and its symbols must
-be linked in the lower 2 GB of the address space. Pointers are 64 bits.
-Programs can be statically or dynamically linked. This is the default
-code model.
-
-@item -mcmodel=kernel
-@opindex mcmodel=kernel
-Generate code for the kernel code model. The kernel runs in the
-negative 2 GB of the address space.
-This model has to be used for Linux kernel code.
-
-@item -mcmodel=medium
-@opindex mcmodel=medium
-Generate code for the medium model: the program is linked in the lower 2
-GB of the address space. Small symbols are also placed there. Symbols
-with sizes larger than @option{-mlarge-data-threshold} are put into
-large data or BSS sections and can be located above 2GB. Programs can
-be statically or dynamically linked.
-
-@item -mcmodel=large
-@opindex mcmodel=large
-Generate code for the large model. This model makes no assumptions
-about addresses and sizes of sections.
-
-@item -maddress-mode=long
-@opindex maddress-mode=long
-Generate code for long address mode. This is only supported for 64-bit
-and x32 environments. It is the default address mode for 64-bit
-environments.
-
-@item -maddress-mode=short
-@opindex maddress-mode=short
-Generate code for short address mode. This is only supported for 32-bit
-and x32 environments. It is the default address mode for 32-bit and
-x32 environments.
-@end table
-
-@node i386 and x86-64 Windows Options
-@subsection i386 and x86-64 Windows Options
-@cindex i386 and x86-64 Windows Options
-
-These additional options are available for Microsoft Windows targets:
-
-@table @gcctabopt
-@item -mconsole
-@opindex mconsole
-This option
-specifies that a console application is to be generated, by
-instructing the linker to set the PE header subsystem type
-required for console applications.
-This option is available for Cygwin and MinGW targets and is
-enabled by default on those targets.
-
-@item -mdll
-@opindex mdll
-This option is available for Cygwin and MinGW targets. It
-specifies that a DLL---a dynamic link library---is to be
-generated, enabling the selection of the required runtime
-startup object and entry point.
-
-@item -mnop-fun-dllimport
-@opindex mnop-fun-dllimport
-This option is available for Cygwin and MinGW targets. It
-specifies that the @code{dllimport} attribute should be ignored.
-
-@item -mthread
-@opindex mthread
-This option is available for MinGW targets. It specifies
-that MinGW-specific thread support is to be used.
-
-@item -municode
-@opindex municode
-This option is available for MinGW-w64 targets. It causes
-the @code{UNICODE} preprocessor macro to be predefined, and
-chooses Unicode-capable runtime startup code.
-
-@item -mwin32
-@opindex mwin32
-This option is available for Cygwin and MinGW targets. It
-specifies that the typical Microsoft Windows predefined macros are to
-be set in the pre-processor, but does not influence the choice
-of runtime library/startup code.
-
-@item -mwindows
-@opindex mwindows
-This option is available for Cygwin and MinGW targets. It
-specifies that a GUI application is to be generated by
-instructing the linker to set the PE header subsystem type
-appropriately.
-
-@item -fno-set-stack-executable
-@opindex fno-set-stack-executable
-This option is available for MinGW targets. It specifies that
-the executable flag for the stack used by nested functions isn't
-set. This is necessary for binaries running in kernel mode of
-Microsoft Windows, as there the User32 API, which is used to set executable
-privileges, isn't available.
-
-@item -fwritable-relocated-rdata
-@opindex fno-writable-relocated-rdata
-This option is available for MinGW and Cygwin targets. It specifies
-that relocated-data in read-only section is put into .data
-section. This is a necessary for older runtimes not supporting
-modification of .rdata sections for pseudo-relocation.
-
-@item -mpe-aligned-commons
-@opindex mpe-aligned-commons
-This option is available for Cygwin and MinGW targets. It
-specifies that the GNU extension to the PE file format that
-permits the correct alignment of COMMON variables should be
-used when generating code. It is enabled by default if
-GCC detects that the target assembler found during configuration
-supports the feature.
-@end table
-
-See also under @ref{i386 and x86-64 Options} for standard options.
-
-@node IA-64 Options
-@subsection IA-64 Options
-@cindex IA-64 Options
-
-These are the @samp{-m} options defined for the Intel IA-64 architecture.
-
-@table @gcctabopt
-@item -mbig-endian
-@opindex mbig-endian
-Generate code for a big-endian target. This is the default for HP-UX@.
-
-@item -mlittle-endian
-@opindex mlittle-endian
-Generate code for a little-endian target. This is the default for AIX5
-and GNU/Linux.
-
-@item -mgnu-as
-@itemx -mno-gnu-as
-@opindex mgnu-as
-@opindex mno-gnu-as
-Generate (or don't) code for the GNU assembler. This is the default.
-@c Also, this is the default if the configure option @option{--with-gnu-as}
-@c is used.
-
-@item -mgnu-ld
-@itemx -mno-gnu-ld
-@opindex mgnu-ld
-@opindex mno-gnu-ld
-Generate (or don't) code for the GNU linker. This is the default.
-@c Also, this is the default if the configure option @option{--with-gnu-ld}
-@c is used.
-
-@item -mno-pic
-@opindex mno-pic
-Generate code that does not use a global pointer register. The result
-is not position independent code, and violates the IA-64 ABI@.
-
-@item -mvolatile-asm-stop
-@itemx -mno-volatile-asm-stop
-@opindex mvolatile-asm-stop
-@opindex mno-volatile-asm-stop
-Generate (or don't) a stop bit immediately before and after volatile asm
-statements.
-
-@item -mregister-names
-@itemx -mno-register-names
-@opindex mregister-names
-@opindex mno-register-names
-Generate (or don't) @samp{in}, @samp{loc}, and @samp{out} register names for
-the stacked registers. This may make assembler output more readable.
-
-@item -mno-sdata
-@itemx -msdata
-@opindex mno-sdata
-@opindex msdata
-Disable (or enable) optimizations that use the small data section. This may
-be useful for working around optimizer bugs.
-
-@item -mconstant-gp
-@opindex mconstant-gp
-Generate code that uses a single constant global pointer value. This is
-useful when compiling kernel code.
-
-@item -mauto-pic
-@opindex mauto-pic
-Generate code that is self-relocatable. This implies @option{-mconstant-gp}.
-This is useful when compiling firmware code.
-
-@item -minline-float-divide-min-latency
-@opindex minline-float-divide-min-latency
-Generate code for inline divides of floating-point values
-using the minimum latency algorithm.
-
-@item -minline-float-divide-max-throughput
-@opindex minline-float-divide-max-throughput
-Generate code for inline divides of floating-point values
-using the maximum throughput algorithm.
-
-@item -mno-inline-float-divide
-@opindex mno-inline-float-divide
-Do not generate inline code for divides of floating-point values.
-
-@item -minline-int-divide-min-latency
-@opindex minline-int-divide-min-latency
-Generate code for inline divides of integer values
-using the minimum latency algorithm.
-
-@item -minline-int-divide-max-throughput
-@opindex minline-int-divide-max-throughput
-Generate code for inline divides of integer values
-using the maximum throughput algorithm.
-
-@item -mno-inline-int-divide
-@opindex mno-inline-int-divide
-Do not generate inline code for divides of integer values.
-
-@item -minline-sqrt-min-latency
-@opindex minline-sqrt-min-latency
-Generate code for inline square roots
-using the minimum latency algorithm.
-
-@item -minline-sqrt-max-throughput
-@opindex minline-sqrt-max-throughput
-Generate code for inline square roots
-using the maximum throughput algorithm.
-
-@item -mno-inline-sqrt
-@opindex mno-inline-sqrt
-Do not generate inline code for @code{sqrt}.
-
-@item -mfused-madd
-@itemx -mno-fused-madd
-@opindex mfused-madd
-@opindex mno-fused-madd
-Do (don't) generate code that uses the fused multiply/add or multiply/subtract
-instructions. The default is to use these instructions.
-
-@item -mno-dwarf2-asm
-@itemx -mdwarf2-asm
-@opindex mno-dwarf2-asm
-@opindex mdwarf2-asm
-Don't (or do) generate assembler code for the DWARF 2 line number debugging
-info. This may be useful when not using the GNU assembler.
-
-@item -mearly-stop-bits
-@itemx -mno-early-stop-bits
-@opindex mearly-stop-bits
-@opindex mno-early-stop-bits
-Allow stop bits to be placed earlier than immediately preceding the
-instruction that triggered the stop bit. This can improve instruction
-scheduling, but does not always do so.
-
-@item -mfixed-range=@var{register-range}
-@opindex mfixed-range
-Generate code treating the given register range as fixed registers.
-A fixed register is one that the register allocator cannot use. This is
-useful when compiling kernel code. A register range is specified as
-two registers separated by a dash. Multiple register ranges can be
-specified separated by a comma.
-
-@item -mtls-size=@var{tls-size}
-@opindex mtls-size
-Specify bit size of immediate TLS offsets. Valid values are 14, 22, and
-64.
-
-@item -mtune=@var{cpu-type}
-@opindex mtune
-Tune the instruction scheduling for a particular CPU, Valid values are
-@samp{itanium}, @samp{itanium1}, @samp{merced}, @samp{itanium2},
-and @samp{mckinley}.
-
-@item -milp32
-@itemx -mlp64
-@opindex milp32
-@opindex mlp64
-Generate code for a 32-bit or 64-bit environment.
-The 32-bit environment sets int, long and pointer to 32 bits.
-The 64-bit environment sets int to 32 bits and long and pointer
-to 64 bits. These are HP-UX specific flags.
-
-@item -mno-sched-br-data-spec
-@itemx -msched-br-data-spec
-@opindex mno-sched-br-data-spec
-@opindex msched-br-data-spec
-(Dis/En)able data speculative scheduling before reload.
-This results in generation of @code{ld.a} instructions and
-the corresponding check instructions (@code{ld.c} / @code{chk.a}).
-The default is 'disable'.
-
-@item -msched-ar-data-spec
-@itemx -mno-sched-ar-data-spec
-@opindex msched-ar-data-spec
-@opindex mno-sched-ar-data-spec
-(En/Dis)able data speculative scheduling after reload.
-This results in generation of @code{ld.a} instructions and
-the corresponding check instructions (@code{ld.c} / @code{chk.a}).
-The default is 'enable'.
-
-@item -mno-sched-control-spec
-@itemx -msched-control-spec
-@opindex mno-sched-control-spec
-@opindex msched-control-spec
-(Dis/En)able control speculative scheduling. This feature is
-available only during region scheduling (i.e.@: before reload).
-This results in generation of the @code{ld.s} instructions and
-the corresponding check instructions @code{chk.s}.
-The default is 'disable'.
-
-@item -msched-br-in-data-spec
-@itemx -mno-sched-br-in-data-spec
-@opindex msched-br-in-data-spec
-@opindex mno-sched-br-in-data-spec
-(En/Dis)able speculative scheduling of the instructions that
-are dependent on the data speculative loads before reload.
-This is effective only with @option{-msched-br-data-spec} enabled.
-The default is 'enable'.
-
-@item -msched-ar-in-data-spec
-@itemx -mno-sched-ar-in-data-spec
-@opindex msched-ar-in-data-spec
-@opindex mno-sched-ar-in-data-spec
-(En/Dis)able speculative scheduling of the instructions that
-are dependent on the data speculative loads after reload.
-This is effective only with @option{-msched-ar-data-spec} enabled.
-The default is 'enable'.
-
-@item -msched-in-control-spec
-@itemx -mno-sched-in-control-spec
-@opindex msched-in-control-spec
-@opindex mno-sched-in-control-spec
-(En/Dis)able speculative scheduling of the instructions that
-are dependent on the control speculative loads.
-This is effective only with @option{-msched-control-spec} enabled.
-The default is 'enable'.
-
-@item -mno-sched-prefer-non-data-spec-insns
-@itemx -msched-prefer-non-data-spec-insns
-@opindex mno-sched-prefer-non-data-spec-insns
-@opindex msched-prefer-non-data-spec-insns
-If enabled, data-speculative instructions are chosen for schedule
-only if there are no other choices at the moment. This makes
-the use of the data speculation much more conservative.
-The default is 'disable'.
-
-@item -mno-sched-prefer-non-control-spec-insns
-@itemx -msched-prefer-non-control-spec-insns
-@opindex mno-sched-prefer-non-control-spec-insns
-@opindex msched-prefer-non-control-spec-insns
-If enabled, control-speculative instructions are chosen for schedule
-only if there are no other choices at the moment. This makes
-the use of the control speculation much more conservative.
-The default is 'disable'.
-
-@item -mno-sched-count-spec-in-critical-path
-@itemx -msched-count-spec-in-critical-path
-@opindex mno-sched-count-spec-in-critical-path
-@opindex msched-count-spec-in-critical-path
-If enabled, speculative dependencies are considered during
-computation of the instructions priorities. This makes the use of the
-speculation a bit more conservative.
-The default is 'disable'.
-
-@item -msched-spec-ldc
-@opindex msched-spec-ldc
-Use a simple data speculation check. This option is on by default.
-
-@item -msched-control-spec-ldc
-@opindex msched-spec-ldc
-Use a simple check for control speculation. This option is on by default.
-
-@item -msched-stop-bits-after-every-cycle
-@opindex msched-stop-bits-after-every-cycle
-Place a stop bit after every cycle when scheduling. This option is on
-by default.
-
-@item -msched-fp-mem-deps-zero-cost
-@opindex msched-fp-mem-deps-zero-cost
-Assume that floating-point stores and loads are not likely to cause a conflict
-when placed into the same instruction group. This option is disabled by
-default.
-
-@item -msel-sched-dont-check-control-spec
-@opindex msel-sched-dont-check-control-spec
-Generate checks for control speculation in selective scheduling.
-This flag is disabled by default.
-
-@item -msched-max-memory-insns=@var{max-insns}
-@opindex msched-max-memory-insns
-Limit on the number of memory insns per instruction group, giving lower
-priority to subsequent memory insns attempting to schedule in the same
-instruction group. Frequently useful to prevent cache bank conflicts.
-The default value is 1.
-
-@item -msched-max-memory-insns-hard-limit
-@opindex msched-max-memory-insns-hard-limit
-Makes the limit specified by @option{msched-max-memory-insns} a hard limit,
-disallowing more than that number in an instruction group.
-Otherwise, the limit is ``soft'', meaning that non-memory operations
-are preferred when the limit is reached, but memory operations may still
-be scheduled.
-
-@end table
-
-@node LM32 Options
-@subsection LM32 Options
-@cindex LM32 options
-
-These @option{-m} options are defined for the LatticeMico32 architecture:
-
-@table @gcctabopt
-@item -mbarrel-shift-enabled
-@opindex mbarrel-shift-enabled
-Enable barrel-shift instructions.
-
-@item -mdivide-enabled
-@opindex mdivide-enabled
-Enable divide and modulus instructions.
-
-@item -mmultiply-enabled
-@opindex multiply-enabled
-Enable multiply instructions.
-
-@item -msign-extend-enabled
-@opindex msign-extend-enabled
-Enable sign extend instructions.
-
-@item -muser-enabled
-@opindex muser-enabled
-Enable user-defined instructions.
-
-@end table
-
-@node M32C Options
-@subsection M32C Options
-@cindex M32C options
-
-@table @gcctabopt
-@item -mcpu=@var{name}
-@opindex mcpu=
-Select the CPU for which code is generated. @var{name} may be one of
-@samp{r8c} for the R8C/Tiny series, @samp{m16c} for the M16C (up to
-/60) series, @samp{m32cm} for the M16C/80 series, or @samp{m32c} for
-the M32C/80 series.
-
-@item -msim
-@opindex msim
-Specifies that the program will be run on the simulator. This causes
-an alternate runtime library to be linked in which supports, for
-example, file I/O@. You must not use this option when generating
-programs that will run on real hardware; you must provide your own
-runtime library for whatever I/O functions are needed.
-
-@item -memregs=@var{number}
-@opindex memregs=
-Specifies the number of memory-based pseudo-registers GCC uses
-during code generation. These pseudo-registers are used like real
-registers, so there is a tradeoff between GCC's ability to fit the
-code into available registers, and the performance penalty of using
-memory instead of registers. Note that all modules in a program must
-be compiled with the same value for this option. Because of that, you
-must not use this option with GCC's default runtime libraries.
-
-@end table
-
-@node M32R/D Options
-@subsection M32R/D Options
-@cindex M32R/D options
-
-These @option{-m} options are defined for Renesas M32R/D architectures:
-
-@table @gcctabopt
-@item -m32r2
-@opindex m32r2
-Generate code for the M32R/2@.
-
-@item -m32rx
-@opindex m32rx
-Generate code for the M32R/X@.
-
-@item -m32r
-@opindex m32r
-Generate code for the M32R@. This is the default.
-
-@item -mmodel=small
-@opindex mmodel=small
-Assume all objects live in the lower 16MB of memory (so that their addresses
-can be loaded with the @code{ld24} instruction), and assume all subroutines
-are reachable with the @code{bl} instruction.
-This is the default.
-
-The addressability of a particular object can be set with the
-@code{model} attribute.
-
-@item -mmodel=medium
-@opindex mmodel=medium
-Assume objects may be anywhere in the 32-bit address space (the compiler
-generates @code{seth/add3} instructions to load their addresses), and
-assume all subroutines are reachable with the @code{bl} instruction.
-
-@item -mmodel=large
-@opindex mmodel=large
-Assume objects may be anywhere in the 32-bit address space (the compiler
-generates @code{seth/add3} instructions to load their addresses), and
-assume subroutines may not be reachable with the @code{bl} instruction
-(the compiler generates the much slower @code{seth/add3/jl}
-instruction sequence).
-
-@item -msdata=none
-@opindex msdata=none
-Disable use of the small data area. Variables are put into
-one of @samp{.data}, @samp{.bss}, or @samp{.rodata} (unless the
-@code{section} attribute has been specified).
-This is the default.
-
-The small data area consists of sections @samp{.sdata} and @samp{.sbss}.
-Objects may be explicitly put in the small data area with the
-@code{section} attribute using one of these sections.
-
-@item -msdata=sdata
-@opindex msdata=sdata
-Put small global and static data in the small data area, but do not
-generate special code to reference them.
-
-@item -msdata=use
-@opindex msdata=use
-Put small global and static data in the small data area, and generate
-special instructions to reference them.
-
-@item -G @var{num}
-@opindex G
-@cindex smaller data references
-Put global and static objects less than or equal to @var{num} bytes
-into the small data or BSS sections instead of the normal data or BSS
-sections. The default value of @var{num} is 8.
-The @option{-msdata} option must be set to one of @samp{sdata} or @samp{use}
-for this option to have any effect.
-
-All modules should be compiled with the same @option{-G @var{num}} value.
-Compiling with different values of @var{num} may or may not work; if it
-doesn't the linker gives an error message---incorrect code is not
-generated.
-
-@item -mdebug
-@opindex mdebug
-Makes the M32R-specific code in the compiler display some statistics
-that might help in debugging programs.
-
-@item -malign-loops
-@opindex malign-loops
-Align all loops to a 32-byte boundary.
-
-@item -mno-align-loops
-@opindex mno-align-loops
-Do not enforce a 32-byte alignment for loops. This is the default.
-
-@item -missue-rate=@var{number}
-@opindex missue-rate=@var{number}
-Issue @var{number} instructions per cycle. @var{number} can only be 1
-or 2.
-
-@item -mbranch-cost=@var{number}
-@opindex mbranch-cost=@var{number}
-@var{number} can only be 1 or 2. If it is 1 then branches are
-preferred over conditional code, if it is 2, then the opposite applies.
-
-@item -mflush-trap=@var{number}
-@opindex mflush-trap=@var{number}
-Specifies the trap number to use to flush the cache. The default is
-12. Valid numbers are between 0 and 15 inclusive.
-
-@item -mno-flush-trap
-@opindex mno-flush-trap
-Specifies that the cache cannot be flushed by using a trap.
-
-@item -mflush-func=@var{name}
-@opindex mflush-func=@var{name}
-Specifies the name of the operating system function to call to flush
-the cache. The default is @emph{_flush_cache}, but a function call
-is only used if a trap is not available.
-
-@item -mno-flush-func
-@opindex mno-flush-func
-Indicates that there is no OS function for flushing the cache.
-
-@end table
-
-@node M680x0 Options
-@subsection M680x0 Options
-@cindex M680x0 options
-
-These are the @samp{-m} options defined for M680x0 and ColdFire processors.
-The default settings depend on which architecture was selected when
-the compiler was configured; the defaults for the most common choices
-are given below.
-
-@table @gcctabopt
-@item -march=@var{arch}
-@opindex march
-Generate code for a specific M680x0 or ColdFire instruction set
-architecture. Permissible values of @var{arch} for M680x0
-architectures are: @samp{68000}, @samp{68010}, @samp{68020},
-@samp{68030}, @samp{68040}, @samp{68060} and @samp{cpu32}. ColdFire
-architectures are selected according to Freescale's ISA classification
-and the permissible values are: @samp{isaa}, @samp{isaaplus},
-@samp{isab} and @samp{isac}.
-
-GCC defines a macro @samp{__mcf@var{arch}__} whenever it is generating
-code for a ColdFire target. The @var{arch} in this macro is one of the
-@option{-march} arguments given above.
-
-When used together, @option{-march} and @option{-mtune} select code
-that runs on a family of similar processors but that is optimized
-for a particular microarchitecture.
-
-@item -mcpu=@var{cpu}
-@opindex mcpu
-Generate code for a specific M680x0 or ColdFire processor.
-The M680x0 @var{cpu}s are: @samp{68000}, @samp{68010}, @samp{68020},
-@samp{68030}, @samp{68040}, @samp{68060}, @samp{68302}, @samp{68332}
-and @samp{cpu32}. The ColdFire @var{cpu}s are given by the table
-below, which also classifies the CPUs into families:
-
-@multitable @columnfractions 0.20 0.80
-@item @strong{Family} @tab @strong{@samp{-mcpu} arguments}
-@item @samp{51} @tab @samp{51} @samp{51ac} @samp{51ag} @samp{51cn} @samp{51em} @samp{51je} @samp{51jf} @samp{51jg} @samp{51jm} @samp{51mm} @samp{51qe} @samp{51qm}
-@item @samp{5206} @tab @samp{5202} @samp{5204} @samp{5206}
-@item @samp{5206e} @tab @samp{5206e}
-@item @samp{5208} @tab @samp{5207} @samp{5208}
-@item @samp{5211a} @tab @samp{5210a} @samp{5211a}
-@item @samp{5213} @tab @samp{5211} @samp{5212} @samp{5213}
-@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}
-@item @samp{5271} @tab @samp{5270} @samp{5271}
-@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}
-@item @samp{5407} @tab @samp{5407}
-@item @samp{5475} @tab @samp{5470} @samp{5471} @samp{5472} @samp{5473} @samp{5474} @samp{5475} @samp{547x} @samp{5480} @samp{5481} @samp{5482} @samp{5483} @samp{5484} @samp{5485}
-@end multitable
-
-@option{-mcpu=@var{cpu}} overrides @option{-march=@var{arch}} if
-@var{arch} is compatible with @var{cpu}. Other combinations of
-@option{-mcpu} and @option{-march} are rejected.
-
-GCC defines the macro @samp{__mcf_cpu_@var{cpu}} when ColdFire target
-@var{cpu} is selected. It also defines @samp{__mcf_family_@var{family}},
-where the value of @var{family} is given by the table above.
-
-@item -mtune=@var{tune}
-@opindex mtune
-Tune the code for a particular microarchitecture within the
-constraints set by @option{-march} and @option{-mcpu}.
-The M680x0 microarchitectures are: @samp{68000}, @samp{68010},
-@samp{68020}, @samp{68030}, @samp{68040}, @samp{68060}
-and @samp{cpu32}. The ColdFire microarchitectures
-are: @samp{cfv1}, @samp{cfv2}, @samp{cfv3}, @samp{cfv4} and @samp{cfv4e}.
-
-You can also use @option{-mtune=68020-40} for code that needs
-to run relatively well on 68020, 68030 and 68040 targets.
-@option{-mtune=68020-60} is similar but includes 68060 targets
-as well. These two options select the same tuning decisions as
-@option{-m68020-40} and @option{-m68020-60} respectively.
-
-GCC defines the macros @samp{__mc@var{arch}} and @samp{__mc@var{arch}__}
-when tuning for 680x0 architecture @var{arch}. It also defines
-@samp{mc@var{arch}} unless either @option{-ansi} or a non-GNU @option{-std}
-option is used. If GCC is tuning for a range of architectures,
-as selected by @option{-mtune=68020-40} or @option{-mtune=68020-60},
-it defines the macros for every architecture in the range.
-
-GCC also defines the macro @samp{__m@var{uarch}__} when tuning for
-ColdFire microarchitecture @var{uarch}, where @var{uarch} is one
-of the arguments given above.
-
-@item -m68000
-@itemx -mc68000
-@opindex m68000
-@opindex mc68000
-Generate output for a 68000. This is the default
-when the compiler is configured for 68000-based systems.
-It is equivalent to @option{-march=68000}.
-
-Use this option for microcontrollers with a 68000 or EC000 core,
-including the 68008, 68302, 68306, 68307, 68322, 68328 and 68356.
-
-@item -m68010
-@opindex m68010
-Generate output for a 68010. This is the default
-when the compiler is configured for 68010-based systems.
-It is equivalent to @option{-march=68010}.
-
-@item -m68020
-@itemx -mc68020
-@opindex m68020
-@opindex mc68020
-Generate output for a 68020. This is the default
-when the compiler is configured for 68020-based systems.
-It is equivalent to @option{-march=68020}.
-
-@item -m68030
-@opindex m68030
-Generate output for a 68030. This is the default when the compiler is
-configured for 68030-based systems. It is equivalent to
-@option{-march=68030}.
-
-@item -m68040
-@opindex m68040
-Generate output for a 68040. This is the default when the compiler is
-configured for 68040-based systems. It is equivalent to
-@option{-march=68040}.
-
-This option inhibits the use of 68881/68882 instructions that have to be
-emulated by software on the 68040. Use this option if your 68040 does not
-have code to emulate those instructions.
-
-@item -m68060
-@opindex m68060
-Generate output for a 68060. This is the default when the compiler is
-configured for 68060-based systems. It is equivalent to
-@option{-march=68060}.
-
-This option inhibits the use of 68020 and 68881/68882 instructions that
-have to be emulated by software on the 68060. Use this option if your 68060
-does not have code to emulate those instructions.
-
-@item -mcpu32
-@opindex mcpu32
-Generate output for a CPU32. This is the default
-when the compiler is configured for CPU32-based systems.
-It is equivalent to @option{-march=cpu32}.
-
-Use this option for microcontrollers with a
-CPU32 or CPU32+ core, including the 68330, 68331, 68332, 68333, 68334,
-68336, 68340, 68341, 68349 and 68360.
-
-@item -m5200
-@opindex m5200
-Generate output for a 520X ColdFire CPU@. This is the default
-when the compiler is configured for 520X-based systems.
-It is equivalent to @option{-mcpu=5206}, and is now deprecated
-in favor of that option.
-
-Use this option for microcontroller with a 5200 core, including
-the MCF5202, MCF5203, MCF5204 and MCF5206.
-
-@item -m5206e
-@opindex m5206e
-Generate output for a 5206e ColdFire CPU@. The option is now
-deprecated in favor of the equivalent @option{-mcpu=5206e}.
-
-@item -m528x
-@opindex m528x
-Generate output for a member of the ColdFire 528X family.
-The option is now deprecated in favor of the equivalent
-@option{-mcpu=528x}.
-
-@item -m5307
-@opindex m5307
-Generate output for a ColdFire 5307 CPU@. The option is now deprecated
-in favor of the equivalent @option{-mcpu=5307}.
-
-@item -m5407
-@opindex m5407
-Generate output for a ColdFire 5407 CPU@. The option is now deprecated
-in favor of the equivalent @option{-mcpu=5407}.
-
-@item -mcfv4e
-@opindex mcfv4e
-Generate output for a ColdFire V4e family CPU (e.g.@: 547x/548x).
-This includes use of hardware floating-point instructions.
-The option is equivalent to @option{-mcpu=547x}, and is now
-deprecated in favor of that option.
-
-@item -m68020-40
-@opindex m68020-40
-Generate output for a 68040, without using any of the new instructions.
-This results in code that can run relatively efficiently on either a
-68020/68881 or a 68030 or a 68040. The generated code does use the
-68881 instructions that are emulated on the 68040.
-
-The option is equivalent to @option{-march=68020} @option{-mtune=68020-40}.
-
-@item -m68020-60
-@opindex m68020-60
-Generate output for a 68060, without using any of the new instructions.
-This results in code that can run relatively efficiently on either a
-68020/68881 or a 68030 or a 68040. The generated code does use the
-68881 instructions that are emulated on the 68060.
-
-The option is equivalent to @option{-march=68020} @option{-mtune=68020-60}.
-
-@item -mhard-float
-@itemx -m68881
-@opindex mhard-float
-@opindex m68881
-Generate floating-point instructions. This is the default for 68020
-and above, and for ColdFire devices that have an FPU@. It defines the
-macro @samp{__HAVE_68881__} on M680x0 targets and @samp{__mcffpu__}
-on ColdFire targets.
-
-@item -msoft-float
-@opindex msoft-float
-Do not generate floating-point instructions; use library calls instead.
-This is the default for 68000, 68010, and 68832 targets. It is also
-the default for ColdFire devices that have no FPU.
-
-@item -mdiv
-@itemx -mno-div
-@opindex mdiv
-@opindex mno-div
-Generate (do not generate) ColdFire hardware divide and remainder
-instructions. If @option{-march} is used without @option{-mcpu},
-the default is ``on'' for ColdFire architectures and ``off'' for M680x0
-architectures. Otherwise, the default is taken from the target CPU
-(either the default CPU, or the one specified by @option{-mcpu}). For
-example, the default is ``off'' for @option{-mcpu=5206} and ``on'' for
-@option{-mcpu=5206e}.
-
-GCC defines the macro @samp{__mcfhwdiv__} when this option is enabled.
-
-@item -mshort
-@opindex mshort
-Consider type @code{int} to be 16 bits wide, like @code{short int}.
-Additionally, parameters passed on the stack are also aligned to a
-16-bit boundary even on targets whose API mandates promotion to 32-bit.
-
-@item -mno-short
-@opindex mno-short
-Do not consider type @code{int} to be 16 bits wide. This is the default.
-
-@item -mnobitfield
-@itemx -mno-bitfield
-@opindex mnobitfield
-@opindex mno-bitfield
-Do not use the bit-field instructions. The @option{-m68000}, @option{-mcpu32}
-and @option{-m5200} options imply @w{@option{-mnobitfield}}.
-
-@item -mbitfield
-@opindex mbitfield
-Do use the bit-field instructions. The @option{-m68020} option implies
-@option{-mbitfield}. This is the default if you use a configuration
-designed for a 68020.
-
-@item -mrtd
-@opindex mrtd
-Use a different function-calling convention, in which functions
-that take a fixed number of arguments return with the @code{rtd}
-instruction, which pops their arguments while returning. This
-saves one instruction in the caller since there is no need to pop
-the arguments there.
-
-This calling convention is incompatible with the one normally
-used on Unix, so you cannot use it if you need to call libraries
-compiled with the Unix compiler.
-
-Also, you must provide function prototypes for all functions that
-take variable numbers of arguments (including @code{printf});
-otherwise incorrect code is generated for calls to those
-functions.
-
-In addition, seriously incorrect code results if you call a
-function with too many arguments. (Normally, extra arguments are
-harmlessly ignored.)
-
-The @code{rtd} instruction is supported by the 68010, 68020, 68030,
-68040, 68060 and CPU32 processors, but not by the 68000 or 5200.
-
-@item -mno-rtd
-@opindex mno-rtd
-Do not use the calling conventions selected by @option{-mrtd}.
-This is the default.
-
-@item -malign-int
-@itemx -mno-align-int
-@opindex malign-int
-@opindex mno-align-int
-Control whether GCC aligns @code{int}, @code{long}, @code{long long},
-@code{float}, @code{double}, and @code{long double} variables on a 32-bit
-boundary (@option{-malign-int}) or a 16-bit boundary (@option{-mno-align-int}).
-Aligning variables on 32-bit boundaries produces code that runs somewhat
-faster on processors with 32-bit busses at the expense of more memory.
-
-@strong{Warning:} if you use the @option{-malign-int} switch, GCC
-aligns structures containing the above types differently than
-most published application binary interface specifications for the m68k.
-
-@item -mpcrel
-@opindex mpcrel
-Use the pc-relative addressing mode of the 68000 directly, instead of
-using a global offset table. At present, this option implies @option{-fpic},
-allowing at most a 16-bit offset for pc-relative addressing. @option{-fPIC} is
-not presently supported with @option{-mpcrel}, though this could be supported for
-68020 and higher processors.
-
-@item -mno-strict-align
-@itemx -mstrict-align
-@opindex mno-strict-align
-@opindex mstrict-align
-Do not (do) assume that unaligned memory references are handled by
-the system.
-
-@item -msep-data
-Generate code that allows the data segment to be located in a different
-area of memory from the text segment. This allows for execute-in-place in
-an environment without virtual memory management. This option implies
-@option{-fPIC}.
-
-@item -mno-sep-data
-Generate code that assumes that the data segment follows the text segment.
-This is the default.
-
-@item -mid-shared-library
-Generate code that supports shared libraries via the library ID method.
-This allows for execute-in-place and shared libraries in an environment
-without virtual memory management. This option implies @option{-fPIC}.
-
-@item -mno-id-shared-library
-Generate code that doesn't assume ID-based shared libraries are being used.
-This is the default.
-
-@item -mshared-library-id=n
-Specifies the identification number of the ID-based shared library being
-compiled. Specifying a value of 0 generates more compact code; specifying
-other values forces 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 MCore Options
-@subsection MCore Options
-@cindex MCore options
-
-These are the @samp{-m} options defined for the Motorola M*Core
-processors.
-
-@table @gcctabopt
-
-@item -mhardlit
-@itemx -mno-hardlit
-@opindex mhardlit
-@opindex mno-hardlit
-Inline constants into the code stream if it can be done in two
-instructions or less.
-
-@item -mdiv
-@itemx -mno-div
-@opindex mdiv
-@opindex mno-div
-Use the divide instruction. (Enabled by default).
-
-@item -mrelax-immediate
-@itemx -mno-relax-immediate
-@opindex mrelax-immediate
-@opindex mno-relax-immediate
-Allow arbitrary-sized immediates in bit operations.
-
-@item -mwide-bitfields
-@itemx -mno-wide-bitfields
-@opindex mwide-bitfields
-@opindex mno-wide-bitfields
-Always treat bit-fields as @code{int}-sized.
-
-@item -m4byte-functions
-@itemx -mno-4byte-functions
-@opindex m4byte-functions
-@opindex mno-4byte-functions
-Force all functions to be aligned to a 4-byte boundary.
-
-@item -mcallgraph-data
-@itemx -mno-callgraph-data
-@opindex mcallgraph-data
-@opindex mno-callgraph-data
-Emit callgraph information.
-
-@item -mslow-bytes
-@itemx -mno-slow-bytes
-@opindex mslow-bytes
-@opindex mno-slow-bytes
-Prefer word access when reading byte quantities.
-
-@item -mlittle-endian
-@itemx -mbig-endian
-@opindex mlittle-endian
-@opindex mbig-endian
-Generate code for a little-endian target.
-
-@item -m210
-@itemx -m340
-@opindex m210
-@opindex m340
-Generate code for the 210 processor.
-
-@item -mno-lsim
-@opindex mno-lsim
-Assume that runtime support has been provided and so omit the
-simulator library (@file{libsim.a)} from the linker command line.
-
-@item -mstack-increment=@var{size}
-@opindex mstack-increment
-Set the maximum amount for a single stack increment operation. Large
-values can increase the speed of programs that contain functions
-that need a large amount of stack space, but they can also trigger a
-segmentation fault if the stack is extended too much. The default
-value is 0x1000.
-
-@end table
-
-@node MeP Options
-@subsection MeP Options
-@cindex MeP options
-
-@table @gcctabopt
-
-@item -mabsdiff
-@opindex mabsdiff
-Enables the @code{abs} instruction, which is the absolute difference
-between two registers.
-
-@item -mall-opts
-@opindex mall-opts
-Enables all the optional instructions---average, multiply, divide, bit
-operations, leading zero, absolute difference, min/max, clip, and
-saturation.
-
-
-@item -maverage
-@opindex maverage
-Enables the @code{ave} instruction, which computes the average of two
-registers.
-
-@item -mbased=@var{n}
-@opindex mbased=
-Variables of size @var{n} bytes or smaller are placed in the
-@code{.based} section by default. Based variables use the @code{$tp}
-register as a base register, and there is a 128-byte limit to the
-@code{.based} section.
-
-@item -mbitops
-@opindex mbitops
-Enables the bit operation instructions---bit test (@code{btstm}), set
-(@code{bsetm}), clear (@code{bclrm}), invert (@code{bnotm}), and
-test-and-set (@code{tas}).
-
-@item -mc=@var{name}
-@opindex mc=
-Selects which section constant data is placed in. @var{name} may
-be @code{tiny}, @code{near}, or @code{far}.
-
-@item -mclip
-@opindex mclip
-Enables the @code{clip} instruction. Note that @code{-mclip} is not
-useful unless you also provide @code{-mminmax}.
-
-@item -mconfig=@var{name}
-@opindex mconfig=
-Selects one of the built-in core configurations. Each MeP chip has
-one or more modules in it; each module has a core CPU and a variety of
-coprocessors, optional instructions, and peripherals. The
-@code{MeP-Integrator} tool, not part of GCC, provides these
-configurations through this option; using this option is the same as
-using all the corresponding command-line options. The default
-configuration is @code{default}.
-
-@item -mcop
-@opindex mcop
-Enables the coprocessor instructions. By default, this is a 32-bit
-coprocessor. Note that the coprocessor is normally enabled via the
-@code{-mconfig=} option.
-
-@item -mcop32
-@opindex mcop32
-Enables the 32-bit coprocessor's instructions.
-
-@item -mcop64
-@opindex mcop64
-Enables the 64-bit coprocessor's instructions.
-
-@item -mivc2
-@opindex mivc2
-Enables IVC2 scheduling. IVC2 is a 64-bit VLIW coprocessor.
-
-@item -mdc
-@opindex mdc
-Causes constant variables to be placed in the @code{.near} section.
-
-@item -mdiv
-@opindex mdiv
-Enables the @code{div} and @code{divu} instructions.
-
-@item -meb
-@opindex meb
-Generate big-endian code.
-
-@item -mel
-@opindex mel
-Generate little-endian code.
-
-@item -mio-volatile
-@opindex mio-volatile
-Tells the compiler that any variable marked with the @code{io}
-attribute is to be considered volatile.
-
-@item -ml
-@opindex ml
-Causes variables to be assigned to the @code{.far} section by default.
-
-@item -mleadz
-@opindex mleadz
-Enables the @code{leadz} (leading zero) instruction.
-
-@item -mm
-@opindex mm
-Causes variables to be assigned to the @code{.near} section by default.
-
-@item -mminmax
-@opindex mminmax
-Enables the @code{min} and @code{max} instructions.
-
-@item -mmult
-@opindex mmult
-Enables the multiplication and multiply-accumulate instructions.
-
-@item -mno-opts
-@opindex mno-opts
-Disables all the optional instructions enabled by @code{-mall-opts}.
-
-@item -mrepeat
-@opindex mrepeat
-Enables the @code{repeat} and @code{erepeat} instructions, used for
-low-overhead looping.
-
-@item -ms
-@opindex ms
-Causes all variables to default to the @code{.tiny} section. Note
-that there is a 65536-byte limit to this section. Accesses to these
-variables use the @code{%gp} base register.
-
-@item -msatur
-@opindex msatur
-Enables the saturation instructions. Note that the compiler does not
-currently generate these itself, but this option is included for
-compatibility with other tools, like @code{as}.
-
-@item -msdram
-@opindex msdram
-Link the SDRAM-based runtime instead of the default ROM-based runtime.
-
-@item -msim
-@opindex msim
-Link the simulator runtime libraries.
-
-@item -msimnovec
-@opindex msimnovec
-Link the simulator runtime libraries, excluding built-in support
-for reset and exception vectors and tables.
-
-@item -mtf
-@opindex mtf
-Causes all functions to default to the @code{.far} section. Without
-this option, functions default to the @code{.near} section.
-
-@item -mtiny=@var{n}
-@opindex mtiny=
-Variables that are @var{n} bytes or smaller are allocated to the
-@code{.tiny} section. These variables use the @code{$gp} base
-register. The default for this option is 4, but note that there's a
-65536-byte limit to the @code{.tiny} section.
-
-@end table
-
-@node MicroBlaze Options
-@subsection MicroBlaze Options
-@cindex MicroBlaze Options
-
-@table @gcctabopt
-
-@item -msoft-float
-@opindex msoft-float
-Use software emulation for floating point (default).
-
-@item -mhard-float
-@opindex mhard-float
-Use hardware floating-point instructions.
-
-@item -mmemcpy
-@opindex mmemcpy
-Do not optimize block moves, use @code{memcpy}.
-
-@item -mno-clearbss
-@opindex mno-clearbss
-This option is deprecated. Use @option{-fno-zero-initialized-in-bss} instead.
-
-@item -mcpu=@var{cpu-type}
-@opindex mcpu=
-Use features of, and schedule code for, the given CPU.
-Supported values are in the format @samp{v@var{X}.@var{YY}.@var{Z}},
-where @var{X} is a major version, @var{YY} is the minor version, and
-@var{Z} is compatibility code. Example values are @samp{v3.00.a},
-@samp{v4.00.b}, @samp{v5.00.a}, @samp{v5.00.b}, @samp{v5.00.b}, @samp{v6.00.a}.
-
-@item -mxl-soft-mul
-@opindex mxl-soft-mul
-Use software multiply emulation (default).
-
-@item -mxl-soft-div
-@opindex mxl-soft-div
-Use software emulation for divides (default).
-
-@item -mxl-barrel-shift
-@opindex mxl-barrel-shift
-Use the hardware barrel shifter.
-
-@item -mxl-pattern-compare
-@opindex mxl-pattern-compare
-Use pattern compare instructions.
-
-@item -msmall-divides
-@opindex msmall-divides
-Use table lookup optimization for small signed integer divisions.
-
-@item -mxl-stack-check
-@opindex mxl-stack-check
-This option is deprecated. Use @option{-fstack-check} instead.
-
-@item -mxl-gp-opt
-@opindex mxl-gp-opt
-Use GP-relative @code{.sdata}/@code{.sbss} sections.
-
-@item -mxl-multiply-high
-@opindex mxl-multiply-high
-Use multiply high instructions for high part of 32x32 multiply.
-
-@item -mxl-float-convert
-@opindex mxl-float-convert
-Use hardware floating-point conversion instructions.
-
-@item -mxl-float-sqrt
-@opindex mxl-float-sqrt
-Use hardware floating-point square root instruction.
-
-@item -mbig-endian
-@opindex mbig-endian
-Generate code for a big-endian target.
-
-@item -mlittle-endian
-@opindex mlittle-endian
-Generate code for a little-endian target.
-
-@item -mxl-reorder
-@opindex mxl-reorder
-Use reorder instructions (swap and byte reversed load/store).
-
-@item -mxl-mode-@var{app-model}
-Select application model @var{app-model}. Valid models are
-@table @samp
-@item executable
-normal executable (default), uses startup code @file{crt0.o}.
-
-@item xmdstub
-for use with Xilinx Microprocessor Debugger (XMD) based
-software intrusive debug agent called xmdstub. This uses startup file
-@file{crt1.o} and sets the start address of the program to 0x800.
-
-@item bootstrap
-for applications that are loaded using a bootloader.
-This model uses startup file @file{crt2.o} which does not contain a processor
-reset vector handler. This is suitable for transferring control on a
-processor reset to the bootloader rather than the application.
-
-@item novectors
-for applications that do not require any of the
-MicroBlaze vectors. This option may be useful for applications running
-within a monitoring application. This model uses @file{crt3.o} as a startup file.
-@end table
-
-Option @option{-xl-mode-@var{app-model}} is a deprecated alias for
-@option{-mxl-mode-@var{app-model}}.
-
-@end table
-
-@node MIPS Options
-@subsection MIPS Options
-@cindex MIPS options
-
-@table @gcctabopt
-
-@item -EB
-@opindex EB
-Generate big-endian code.
-
-@item -EL
-@opindex EL
-Generate little-endian code. This is the default for @samp{mips*el-*-*}
-configurations.
-
-@item -march=@var{arch}
-@opindex march
-Generate code that runs on @var{arch}, which can be the name of a
-generic MIPS ISA, or the name of a particular processor.
-The ISA names are:
-@samp{mips1}, @samp{mips2}, @samp{mips3}, @samp{mips4},
-@samp{mips32}, @samp{mips32r2}, @samp{mips64} and @samp{mips64r2}.
-The processor names are:
-@samp{4kc}, @samp{4km}, @samp{4kp}, @samp{4ksc},
-@samp{4kec}, @samp{4kem}, @samp{4kep}, @samp{4ksd},
-@samp{5kc}, @samp{5kf},
-@samp{20kc},
-@samp{24kc}, @samp{24kf2_1}, @samp{24kf1_1},
-@samp{24kec}, @samp{24kef2_1}, @samp{24kef1_1},
-@samp{34kc}, @samp{34kf2_1}, @samp{34kf1_1}, @samp{34kn},
-@samp{74kc}, @samp{74kf2_1}, @samp{74kf1_1}, @samp{74kf3_2},
-@samp{1004kc}, @samp{1004kf2_1}, @samp{1004kf1_1},
-@samp{loongson2e}, @samp{loongson2f}, @samp{loongson3a},
-@samp{m4k},
-@samp{octeon}, @samp{octeon+}, @samp{octeon2},
-@samp{orion},
-@samp{r2000}, @samp{r3000}, @samp{r3900}, @samp{r4000}, @samp{r4400},
-@samp{r4600}, @samp{r4650}, @samp{r4700}, @samp{r6000}, @samp{r8000},
-@samp{rm7000}, @samp{rm9000},
-@samp{r10000}, @samp{r12000}, @samp{r14000}, @samp{r16000},
-@samp{sb1},
-@samp{sr71000},
-@samp{vr4100}, @samp{vr4111}, @samp{vr4120}, @samp{vr4130}, @samp{vr4300},
-@samp{vr5000}, @samp{vr5400}, @samp{vr5500},
-@samp{xlr} and @samp{xlp}.
-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)@.
-
-The native Linux/GNU toolchain also supports the value @samp{native},
-which selects the best architecture option for the host processor.
-@option{-march=native} has no effect if GCC does not recognize
-the processor.
-
-In processor names, a final @samp{000} can be abbreviated as @samp{k}
-(for example, @option{-march=r2k}). Prefixes are optional, and
-@samp{vr} may be written @samp{r}.
-
-Names of the form @samp{@var{n}f2_1} refer to processors with
-FPUs clocked at half the rate of the core, names of the form
-@samp{@var{n}f1_1} refer to processors with FPUs clocked at the same
-rate as the core, and names of the form @samp{@var{n}f3_2} refer to
-processors with FPUs clocked a ratio of 3:2 with respect to the core.
-For compatibility reasons, @samp{@var{n}f} is accepted as a synonym
-for @samp{@var{n}f2_1} while @samp{@var{n}x} and @samp{@var{b}fx} are
-accepted as synonyms for @samp{@var{n}f1_1}.
-
-GCC defines two macros based on the value of this option. The first
-is @samp{_MIPS_ARCH}, which gives the name of target architecture, as
-a string. The second has the form @samp{_MIPS_ARCH_@var{foo}},
-where @var{foo} is the capitalized value of @samp{_MIPS_ARCH}@.
-For example, @option{-march=r2000} sets @samp{_MIPS_ARCH}
-to @samp{"r2000"} and defines the macro @samp{_MIPS_ARCH_R2000}.
-
-Note that the @samp{_MIPS_ARCH} macro uses the processor names given
-above. In other words, it has the full prefix and does not
-abbreviate @samp{000} as @samp{k}. In the case of @samp{from-abi},
-the macro names the resolved architecture (either @samp{"mips1"} or
-@samp{"mips3"}). It names the default architecture when no
-@option{-march} option is given.
-
-@item -mtune=@var{arch}
-@opindex mtune
-Optimize for @var{arch}. Among other things, this option controls
-the way instructions are scheduled, and the perceived cost of arithmetic
-operations. The list of @var{arch} values is the same as for
-@option{-march}.
-
-When this option is not used, GCC optimizes for the processor
-specified by @option{-march}. By using @option{-march} and
-@option{-mtune} together, it is possible to generate code that
-runs on a family of processors, but optimize the code for one
-particular member of that family.
-
-@option{-mtune} defines the macros @samp{_MIPS_TUNE} and
-@samp{_MIPS_TUNE_@var{foo}}, which work in the same way as the
-@option{-march} ones described above.
-
-@item -mips1
-@opindex mips1
-Equivalent to @option{-march=mips1}.
-
-@item -mips2
-@opindex mips2
-Equivalent to @option{-march=mips2}.
-
-@item -mips3
-@opindex mips3
-Equivalent to @option{-march=mips3}.
-
-@item -mips4
-@opindex mips4
-Equivalent to @option{-march=mips4}.
-
-@item -mips32
-@opindex mips32
-Equivalent to @option{-march=mips32}.
-
-@item -mips32r2
-@opindex mips32r2
-Equivalent to @option{-march=mips32r2}.
-
-@item -mips64
-@opindex mips64
-Equivalent to @option{-march=mips64}.
-
-@item -mips64r2
-@opindex mips64r2
-Equivalent to @option{-march=mips64r2}.
-
-@item -mips16
-@itemx -mno-mips16
-@opindex mips16
-@opindex mno-mips16
-Generate (do not generate) MIPS16 code. If GCC is targeting a
-MIPS32 or MIPS64 architecture, it makes use of the MIPS16e ASE@.
-
-MIPS16 code generation can also be controlled on a per-function basis
-by means of @code{mips16} and @code{nomips16} attributes.
-@xref{Function Attributes}, for more information.
-
-@item -mflip-mips16
-@opindex mflip-mips16
-Generate MIPS16 code on alternating functions. This option is provided
-for regression testing of mixed MIPS16/non-MIPS16 code generation, and is
-not intended for ordinary use in compiling user code.
-
-@item -minterlink-mips16
-@itemx -mno-interlink-mips16
-@opindex minterlink-mips16
-@opindex mno-interlink-mips16
-Require (do not require) that non-MIPS16 code be link-compatible with
-MIPS16 code.
-
-For example, non-MIPS16 code cannot jump directly to MIPS16 code;
-it must either use a call or an indirect jump. @option{-minterlink-mips16}
-therefore disables direct jumps unless GCC knows that the target of the
-jump is not MIPS16.
-
-@item -mabi=32
-@itemx -mabi=o64
-@itemx -mabi=n32
-@itemx -mabi=64
-@itemx -mabi=eabi
-@opindex mabi=32
-@opindex mabi=o64
-@opindex mabi=n32
-@opindex mabi=64
-@opindex mabi=eabi
-Generate code for the given ABI@.
-
-Note that the EABI has a 32-bit and a 64-bit variant. GCC normally
-generates 64-bit code when you select a 64-bit architecture, but you
-can use @option{-mgp32} to get 32-bit code instead.
-
-For information about the O64 ABI, see
-@uref{http://gcc.gnu.org/@/projects/@/mipso64-abi.html}.
-
-GCC supports a variant of the o32 ABI in which floating-point registers
-are 64 rather than 32 bits wide. You can select this combination with
-@option{-mabi=32} @option{-mfp64}. This ABI relies on the @code{mthc1}
-and @code{mfhc1} instructions and is therefore only supported for
-MIPS32R2 processors.
-
-The register assignments for arguments and return values remain the
-same, but each scalar value is passed in a single 64-bit register
-rather than a pair of 32-bit registers. For example, scalar
-floating-point values are returned in @samp{$f0} only, not a
-@samp{$f0}/@samp{$f1} pair. The set of call-saved registers also
-remains the same, but all 64 bits are saved.
-
-@item -mabicalls
-@itemx -mno-abicalls
-@opindex mabicalls
-@opindex mno-abicalls
-Generate (do not generate) code that is suitable for SVR4-style
-dynamic objects. @option{-mabicalls} is the default for SVR4-based
-systems.
-
-@item -mshared
-@itemx -mno-shared
-Generate (do not generate) code that is fully position-independent,
-and that can therefore be linked into shared libraries. This option
-only affects @option{-mabicalls}.
-
-All @option{-mabicalls} code has traditionally been position-independent,
-regardless of options like @option{-fPIC} and @option{-fpic}. However,
-as an extension, the GNU toolchain allows executables to use absolute
-accesses for locally-binding symbols. It can also use shorter GP
-initialization sequences and generate direct calls to locally-defined
-functions. This mode is selected by @option{-mno-shared}.
-
-@option{-mno-shared} depends on binutils 2.16 or higher and generates
-objects that can only be linked by the GNU linker. However, the option
-does not affect the ABI of the final executable; it only affects the ABI
-of relocatable objects. Using @option{-mno-shared} generally makes
-executables both smaller and quicker.
-
-@option{-mshared} is the default.
-
-@item -mplt
-@itemx -mno-plt
-@opindex mplt
-@opindex mno-plt
-Assume (do not assume) that the static and dynamic linkers
-support PLTs and copy relocations. This option only affects
-@option{-mno-shared -mabicalls}. For the n64 ABI, this option
-has no effect without @option{-msym32}.
-
-You can make @option{-mplt} the default by configuring
-GCC with @option{--with-mips-plt}. The default is
-@option{-mno-plt} otherwise.
-
-@item -mxgot
-@itemx -mno-xgot
-@opindex mxgot
-@opindex mno-xgot
-Lift (do not lift) the usual restrictions on the size of the global
-offset table.
-
-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 (MIPS)
-@smallexample
-relocation truncated to fit: R_MIPS_GOT16 foobar
-@end smallexample
-
-If this happens, you should recompile your code with @option{-mxgot}.
-This works with very large GOTs, although the code is also
-less efficient, since it takes three instructions to fetch the
-value of a global symbol.
-
-Note that some linkers can create multiple GOTs. If you have such a
-linker, you should only need to use @option{-mxgot} when a single object
-file accesses more than 64k's worth of GOT entries. Very few do.
-
-These options have no effect unless GCC is generating position
-independent code.
-
-@item -mgp32
-@opindex mgp32
-Assume that general-purpose registers are 32 bits wide.
-
-@item -mgp64
-@opindex mgp64
-Assume that general-purpose registers are 64 bits wide.
-
-@item -mfp32
-@opindex mfp32
-Assume that floating-point registers are 32 bits wide.
-
-@item -mfp64
-@opindex mfp64
-Assume that floating-point registers are 64 bits wide.
-
-@item -mhard-float
-@opindex mhard-float
-Use floating-point coprocessor instructions.
-
-@item -msoft-float
-@opindex msoft-float
-Do not use floating-point coprocessor instructions. Implement
-floating-point calculations using library calls instead.
-
-@item -mno-float
-@opindex mno-float
-Equivalent to @option{-msoft-float}, but additionally asserts that the
-program being compiled does not perform any floating-point operations.
-This option is presently supported only by some bare-metal MIPS
-configurations, where it may select a special set of libraries
-that lack all floating-point support (including, for example, the
-floating-point @code{printf} formats).
-If code compiled with @code{-mno-float} accidentally contains
-floating-point operations, it is likely to suffer a link-time
-or run-time failure.
-
-@item -msingle-float
-@opindex msingle-float
-Assume that the floating-point coprocessor only supports single-precision
-operations.
-
-@item -mdouble-float
-@opindex mdouble-float
-Assume that the floating-point coprocessor supports double-precision
-operations. This is the default.
-
-@item -mllsc
-@itemx -mno-llsc
-@opindex mllsc
-@opindex mno-llsc
-Use (do not use) @samp{ll}, @samp{sc}, and @samp{sync} instructions to
-implement atomic memory built-in functions. When neither option is
-specified, GCC uses the instructions if the target architecture
-supports them.
-
-@option{-mllsc} is useful if the runtime environment can emulate the
-instructions and @option{-mno-llsc} can be useful when compiling for
-nonstandard ISAs. You can make either option the default by
-configuring GCC with @option{--with-llsc} and @option{--without-llsc}
-respectively. @option{--with-llsc} is the default for some
-configurations; see the installation documentation for details.
-
-@item -mdsp
-@itemx -mno-dsp
-@opindex mdsp
-@opindex mno-dsp
-Use (do not use) revision 1 of the MIPS DSP ASE@.
-@xref{MIPS DSP Built-in Functions}. This option defines the
-preprocessor macro @samp{__mips_dsp}. It also defines
-@samp{__mips_dsp_rev} to 1.
-
-@item -mdspr2
-@itemx -mno-dspr2
-@opindex mdspr2
-@opindex mno-dspr2
-Use (do not use) revision 2 of the MIPS DSP ASE@.
-@xref{MIPS DSP Built-in Functions}. This option defines the
-preprocessor macros @samp{__mips_dsp} and @samp{__mips_dspr2}.
-It also defines @samp{__mips_dsp_rev} to 2.
-
-@item -msmartmips
-@itemx -mno-smartmips
-@opindex msmartmips
-@opindex mno-smartmips
-Use (do not use) the MIPS SmartMIPS ASE.
-
-@item -mpaired-single
-@itemx -mno-paired-single
-@opindex mpaired-single
-@opindex mno-paired-single
-Use (do not use) paired-single floating-point instructions.
-@xref{MIPS Paired-Single Support}. This option requires
-hardware floating-point support to be enabled.
-
-@item -mdmx
-@itemx -mno-mdmx
-@opindex mdmx
-@opindex mno-mdmx
-Use (do not use) MIPS Digital Media Extension instructions.
-This option can only be used when generating 64-bit code and requires
-hardware floating-point support to be enabled.
-
-@item -mips3d
-@itemx -mno-mips3d
-@opindex mips3d
-@opindex mno-mips3d
-Use (do not use) the MIPS-3D ASE@. @xref{MIPS-3D Built-in Functions}.
-The option @option{-mips3d} implies @option{-mpaired-single}.
-
-@item -mmt
-@itemx -mno-mt
-@opindex mmt
-@opindex mno-mt
-Use (do not use) MT Multithreading instructions.
-
-@item -mmcu
-@itemx -mno-mcu
-@opindex mmcu
-@opindex mno-mcu
-Use (do not use) the MIPS MCU ASE instructions.
-
-@item -mlong64
-@opindex mlong64
-Force @code{long} types to be 64 bits wide. See @option{-mlong32} for
-an explanation of the default and the way that the pointer size is
-determined.
-
-@item -mlong32
-@opindex mlong32
-Force @code{long}, @code{int}, and pointer types to be 32 bits wide.
-
-The default size of @code{int}s, @code{long}s and pointers depends on
-the ABI@. All the supported ABIs use 32-bit @code{int}s. The n64 ABI
-uses 64-bit @code{long}s, as does the 64-bit EABI; the others use
-32-bit @code{long}s. Pointers are the same size as @code{long}s,
-or the same size as integer registers, whichever is smaller.
-
-@item -msym32
-@itemx -mno-sym32
-@opindex msym32
-@opindex mno-sym32
-Assume (do not assume) that all symbols have 32-bit values, regardless
-of the selected ABI@. This option is useful in combination with
-@option{-mabi=64} and @option{-mno-abicalls} because it allows GCC
-to generate shorter and faster references to symbolic addresses.
-
-@item -G @var{num}
-@opindex G
-Put definitions of externally-visible data in a small data section
-if that data is no bigger than @var{num} bytes. GCC can then generate
-more efficient accesses to the data; see @option{-mgpopt} for details.
-
-The default @option{-G} option depends on the configuration.
-
-@item -mlocal-sdata
-@itemx -mno-local-sdata
-@opindex mlocal-sdata
-@opindex mno-local-sdata
-Extend (do not extend) the @option{-G} behavior to local data too,
-such as to static variables in C@. @option{-mlocal-sdata} is the
-default for all configurations.
-
-If the linker complains that an application is using too much small data,
-you might want to try rebuilding the less performance-critical parts with
-@option{-mno-local-sdata}. You might also want to build large
-libraries with @option{-mno-local-sdata}, so that the libraries leave
-more room for the main program.
-
-@item -mextern-sdata
-@itemx -mno-extern-sdata
-@opindex mextern-sdata
-@opindex mno-extern-sdata
-Assume (do not assume) that externally-defined data is in
-a small data section if the size of that data is within the @option{-G} limit.
-@option{-mextern-sdata} is the default for all configurations.
-
-If you compile a module @var{Mod} with @option{-mextern-sdata} @option{-G
-@var{num}} @option{-mgpopt}, and @var{Mod} references a variable @var{Var}
-that is no bigger than @var{num} bytes, you must make sure that @var{Var}
-is placed in a small data section. If @var{Var} is defined by another
-module, you must either compile that module with a high-enough
-@option{-G} setting or attach a @code{section} attribute to @var{Var}'s
-definition. If @var{Var} is common, you must link the application
-with a high-enough @option{-G} setting.
-
-The easiest way of satisfying these restrictions is to compile
-and link every module with the same @option{-G} option. However,
-you may wish to build a library that supports several different
-small data limits. You can do this by compiling the library with
-the highest supported @option{-G} setting and additionally using
-@option{-mno-extern-sdata} to stop the library from making assumptions
-about externally-defined data.
-
-@item -mgpopt
-@itemx -mno-gpopt
-@opindex mgpopt
-@opindex mno-gpopt
-Use (do not use) GP-relative accesses for symbols that are known to be
-in a small data section; see @option{-G}, @option{-mlocal-sdata} and
-@option{-mextern-sdata}. @option{-mgpopt} is the default for all
-configurations.
-
-@option{-mno-gpopt} is useful for cases where the @code{$gp} register
-might not hold the value of @code{_gp}. For example, if the code is
-part of a library that might be used in a boot monitor, programs that
-call boot monitor routines pass an unknown value in @code{$gp}.
-(In such situations, the boot monitor itself is usually compiled
-with @option{-G0}.)
-
-@option{-mno-gpopt} implies @option{-mno-local-sdata} and
-@option{-mno-extern-sdata}.
-
-@item -membedded-data
-@itemx -mno-embedded-data
-@opindex membedded-data
-@opindex mno-embedded-data
-Allocate variables to the read-only data section first if possible, then
-next in the small data section if possible, otherwise in data. This gives
-slightly slower code than the default, but reduces the amount of RAM required
-when executing, and thus may be preferred for some embedded systems.
-
-@item -muninit-const-in-rodata
-@itemx -mno-uninit-const-in-rodata
-@opindex muninit-const-in-rodata
-@opindex mno-uninit-const-in-rodata
-Put uninitialized @code{const} variables in the read-only data section.
-This option is only meaningful in conjunction with @option{-membedded-data}.
-
-@item -mcode-readable=@var{setting}
-@opindex mcode-readable
-Specify whether GCC may generate code that reads from executable sections.
-There are three possible settings:
-
-@table @gcctabopt
-@item -mcode-readable=yes
-Instructions may freely access executable sections. This is the
-default setting.
-
-@item -mcode-readable=pcrel
-MIPS16 PC-relative load instructions can access executable sections,
-but other instructions must not do so. This option is useful on 4KSc
-and 4KSd processors when the code TLBs have the Read Inhibit bit set.
-It is also useful on processors that can be configured to have a dual
-instruction/data SRAM interface and that, like the M4K, automatically
-redirect PC-relative loads to the instruction RAM.
-
-@item -mcode-readable=no
-Instructions must not access executable sections. This option can be
-useful on targets that are configured to have a dual instruction/data
-SRAM interface but that (unlike the M4K) do not automatically redirect
-PC-relative loads to the instruction RAM.
-@end table
-
-@item -msplit-addresses
-@itemx -mno-split-addresses
-@opindex msplit-addresses
-@opindex mno-split-addresses
-Enable (disable) use of the @code{%hi()} and @code{%lo()} assembler
-relocation operators. This option has been superseded by
-@option{-mexplicit-relocs} but is retained for backwards compatibility.
-
-@item -mexplicit-relocs
-@itemx -mno-explicit-relocs
-@opindex mexplicit-relocs
-@opindex mno-explicit-relocs
-Use (do not use) assembler relocation operators when dealing with symbolic
-addresses. The alternative, selected by @option{-mno-explicit-relocs},
-is to use assembler macros instead.
-
-@option{-mexplicit-relocs} is the default if GCC was configured
-to use an assembler that supports relocation operators.
-
-@item -mcheck-zero-division
-@itemx -mno-check-zero-division
-@opindex mcheck-zero-division
-@opindex mno-check-zero-division
-Trap (do not trap) on integer division by zero.
-
-The default is @option{-mcheck-zero-division}.
-
-@item -mdivide-traps
-@itemx -mdivide-breaks
-@opindex mdivide-traps
-@opindex mdivide-breaks
-MIPS systems check for division by zero by generating either a
-conditional trap or a break instruction. Using traps results in
-smaller code, but is only supported on MIPS II and later. Also, some
-versions of the Linux kernel have a bug that prevents trap from
-generating the proper signal (@code{SIGFPE}). Use @option{-mdivide-traps} to
-allow conditional traps on architectures that support them and
-@option{-mdivide-breaks} to force the use of breaks.
-
-The default is usually @option{-mdivide-traps}, but this can be
-overridden at configure time using @option{--with-divide=breaks}.
-Divide-by-zero checks can be completely disabled using
-@option{-mno-check-zero-division}.
-
-@item -mmemcpy
-@itemx -mno-memcpy
-@opindex mmemcpy
-@opindex mno-memcpy
-Force (do not force) the use of @code{memcpy()} for non-trivial block
-moves. The default is @option{-mno-memcpy}, which allows GCC to inline
-most constant-sized copies.
-
-@item -mlong-calls
-@itemx -mno-long-calls
-@opindex mlong-calls
-@opindex mno-long-calls
-Disable (do not disable) use of the @code{jal} instruction. Calling
-functions using @code{jal} is more efficient but requires the caller
-and callee to be in the same 256 megabyte segment.
-
-This option has no effect on abicalls code. The default is
-@option{-mno-long-calls}.
-
-@item -mmad
-@itemx -mno-mad
-@opindex mmad
-@opindex mno-mad
-Enable (disable) use of the @code{mad}, @code{madu} and @code{mul}
-instructions, as provided by the R4650 ISA@.
-
-@item -mfused-madd
-@itemx -mno-fused-madd
-@opindex mfused-madd
-@opindex mno-fused-madd
-Enable (disable) use of the floating-point multiply-accumulate
-instructions, when they are available. The default is
-@option{-mfused-madd}.
-
-On the R8000 CPU when multiply-accumulate instructions are used,
-the intermediate product is calculated to infinite precision
-and is not subject to the FCSR Flush to Zero bit. This may be
-undesirable in some circumstances. On other processors the result
-is numerically identical to the equivalent computation using
-separate multiply, add, subtract and negate instructions.
-
-@item -nocpp
-@opindex nocpp
-Tell the MIPS assembler to not run its preprocessor over user
-assembler files (with a @samp{.s} suffix) when assembling them.
-
-@item -mfix-24k
-@item -mno-fix-24k
-@opindex mfix-24k
-@opindex mno-fix-24k
-Work around the 24K E48 (lost data on stores during refill) errata.
-The workarounds are implemented by the assembler rather than by GCC@.
-
-@item -mfix-r4000
-@itemx -mno-fix-r4000
-@opindex mfix-r4000
-@opindex mno-fix-r4000
-Work around certain R4000 CPU errata:
-@itemize @minus
-@item
-A double-word or a variable shift may give an incorrect result if executed
-immediately after starting an integer division.
-@item
-A double-word or a variable shift may give an incorrect result if executed
-while an integer multiplication is in progress.
-@item
-An integer division may give an incorrect result if started in a delay slot
-of a taken branch or a jump.
-@end itemize
-
-@item -mfix-r4400
-@itemx -mno-fix-r4400
-@opindex mfix-r4400
-@opindex mno-fix-r4400
-Work around certain R4400 CPU errata:
-@itemize @minus
-@item
-A double-word or a variable shift may give an incorrect result if executed
-immediately after starting an integer division.
-@end itemize
-
-@item -mfix-r10000
-@itemx -mno-fix-r10000
-@opindex mfix-r10000
-@opindex mno-fix-r10000
-Work around certain R10000 errata:
-@itemize @minus
-@item
-@code{ll}/@code{sc} sequences may not behave atomically on revisions
-prior to 3.0. They may deadlock on revisions 2.6 and earlier.
-@end itemize
-
-This option can only be used if the target architecture supports
-branch-likely instructions. @option{-mfix-r10000} is the default when
-@option{-march=r10000} is used; @option{-mno-fix-r10000} is the default
-otherwise.
-
-@item -mfix-vr4120
-@itemx -mno-fix-vr4120
-@opindex mfix-vr4120
-Work around certain VR4120 errata:
-@itemize @minus
-@item
-@code{dmultu} does not always produce the correct result.
-@item
-@code{div} and @code{ddiv} do not always produce the correct result if one
-of the operands is negative.
-@end itemize
-The workarounds for the division errata rely on special functions in
-@file{libgcc.a}. At present, these functions are only provided by
-the @code{mips64vr*-elf} configurations.
-
-Other VR4120 errata require a NOP to be inserted between certain pairs of
-instructions. These errata are handled by the assembler, not by GCC itself.
-
-@item -mfix-vr4130
-@opindex mfix-vr4130
-Work around the VR4130 @code{mflo}/@code{mfhi} errata. The
-workarounds are implemented by the assembler rather than by GCC,
-although GCC avoids using @code{mflo} and @code{mfhi} if the
-VR4130 @code{macc}, @code{macchi}, @code{dmacc} and @code{dmacchi}
-instructions are available instead.
-
-@item -mfix-sb1
-@itemx -mno-fix-sb1
-@opindex mfix-sb1
-Work around certain SB-1 CPU core errata.
-(This flag currently works around the SB-1 revision 2
-``F1'' and ``F2'' floating-point errata.)
-
-@item -mr10k-cache-barrier=@var{setting}
-@opindex mr10k-cache-barrier
-Specify whether GCC should insert cache barriers to avoid the
-side-effects of speculation on R10K processors.
-
-In common with many processors, the R10K tries to predict the outcome
-of a conditional branch and speculatively executes instructions from
-the ``taken'' branch. It later aborts these instructions if the
-predicted outcome is wrong. However, on the R10K, even aborted
-instructions can have side effects.
-
-This problem only affects kernel stores and, depending on the system,
-kernel loads. As an example, a speculatively-executed store may load
-the target memory into cache and mark the cache line as dirty, even if
-the store itself is later aborted. If a DMA operation writes to the
-same area of memory before the ``dirty'' line is flushed, the cached
-data overwrites the DMA-ed data. See the R10K processor manual
-for a full description, including other potential problems.
-
-One workaround is to insert cache barrier instructions before every memory
-access that might be speculatively executed and that might have side
-effects even if aborted. @option{-mr10k-cache-barrier=@var{setting}}
-controls GCC's implementation of this workaround. It assumes that
-aborted accesses to any byte in the following regions does not have
-side effects:
-
-@enumerate
-@item
-the memory occupied by the current function's stack frame;
-
-@item
-the memory occupied by an incoming stack argument;
-
-@item
-the memory occupied by an object with a link-time-constant address.
-@end enumerate
-
-It is the kernel's responsibility to ensure that speculative
-accesses to these regions are indeed safe.
-
-If the input program contains a function declaration such as:
-
-@smallexample
-void foo (void);
-@end smallexample
-
-then the implementation of @code{foo} must allow @code{j foo} and
-@code{jal foo} to be executed speculatively. GCC honors this
-restriction for functions it compiles itself. It expects non-GCC
-functions (such as hand-written assembly code) to do the same.
-
-The option has three forms:
-
-@table @gcctabopt
-@item -mr10k-cache-barrier=load-store
-Insert a cache barrier before a load or store that might be
-speculatively executed and that might have side effects even
-if aborted.
-
-@item -mr10k-cache-barrier=store
-Insert a cache barrier before a store that might be speculatively
-executed and that might have side effects even if aborted.
-
-@item -mr10k-cache-barrier=none
-Disable the insertion of cache barriers. This is the default setting.
-@end table
-
-@item -mflush-func=@var{func}
-@itemx -mno-flush-func
-@opindex mflush-func
-Specifies the function to call to flush the I and D caches, or to not
-call any such function. If called, the function must take the same
-arguments as the common @code{_flush_func()}, that is, the address of the
-memory range for which the cache is being flushed, the size of the
-memory range, and the number 3 (to flush both caches). The default
-depends on the target GCC was configured for, but commonly is either
-@samp{_flush_func} or @samp{__cpu_flush}.
-
-@item mbranch-cost=@var{num}
-@opindex mbranch-cost
-Set the cost of branches to roughly @var{num} ``simple'' instructions.
-This cost is only a heuristic and is not guaranteed to produce
-consistent results across releases. A zero cost redundantly selects
-the default, which is based on the @option{-mtune} setting.
-
-@item -mbranch-likely
-@itemx -mno-branch-likely
-@opindex mbranch-likely
-@opindex mno-branch-likely
-Enable or disable use of Branch Likely instructions, regardless of the
-default for the selected architecture. By default, Branch Likely
-instructions may be generated if they are supported by the selected
-architecture. An exception is for the MIPS32 and MIPS64 architectures
-and processors that implement those architectures; for those, Branch
-Likely instructions are not be generated by default because the MIPS32
-and MIPS64 architectures specifically deprecate their use.
-
-@item -mfp-exceptions
-@itemx -mno-fp-exceptions
-@opindex mfp-exceptions
-Specifies whether FP exceptions are enabled. This affects how
-FP instructions are scheduled for some processors.
-The default is that FP exceptions are
-enabled.
-
-For instance, on the SB-1, if FP exceptions are disabled, and we are emitting
-64-bit code, then we can use both FP pipes. Otherwise, we can only use one
-FP pipe.
-
-@item -mvr4130-align
-@itemx -mno-vr4130-align
-@opindex mvr4130-align
-The VR4130 pipeline is two-way superscalar, but can only issue two
-instructions together if the first one is 8-byte aligned. When this
-option is enabled, GCC aligns pairs of instructions that it
-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 -msynci
-@itemx -mno-synci
-@opindex msynci
-Enable (disable) generation of @code{synci} instructions on
-architectures that support it. The @code{synci} instructions (if
-enabled) are generated when @code{__builtin___clear_cache()} is
-compiled.
-
-This option defaults to @code{-mno-synci}, but the default can be
-overridden by configuring with @code{--with-synci}.
-
-When compiling code for single processor systems, it is generally safe
-to use @code{synci}. However, on many multi-core (SMP) systems, it
-does not invalidate the instruction caches on all cores and may lead
-to undefined behavior.
-
-@item -mrelax-pic-calls
-@itemx -mno-relax-pic-calls
-@opindex mrelax-pic-calls
-Try to turn PIC calls that are normally dispatched via register
-@code{$25} into direct calls. This is only possible if the linker can
-resolve the destination at link-time and if the destination is within
-range for a direct call.
-
-@option{-mrelax-pic-calls} is the default if GCC was configured to use
-an assembler and a linker that support the @code{.reloc} assembly
-directive and @code{-mexplicit-relocs} is in effect. With
-@code{-mno-explicit-relocs}, this optimization can be performed by the
-assembler and the linker alone without help from the compiler.
-
-@item -mmcount-ra-address
-@itemx -mno-mcount-ra-address
-@opindex mmcount-ra-address
-@opindex mno-mcount-ra-address
-Emit (do not emit) code that allows @code{_mcount} to modify the
-calling function's return address. When enabled, this option extends
-the usual @code{_mcount} interface with a new @var{ra-address}
-parameter, which has type @code{intptr_t *} and is passed in register
-@code{$12}. @code{_mcount} can then modify the return address by
-doing both of the following:
-@itemize
-@item
-Returning the new address in register @code{$31}.
-@item
-Storing the new address in @code{*@var{ra-address}},
-if @var{ra-address} is nonnull.
-@end itemize
-
-The default is @option{-mno-mcount-ra-address}.
-
-@end table
-
-@node MMIX Options
-@subsection MMIX Options
-@cindex MMIX Options
-
-These options are defined for the MMIX:
-
-@table @gcctabopt
-@item -mlibfuncs
-@itemx -mno-libfuncs
-@opindex mlibfuncs
-@opindex mno-libfuncs
-Specify that intrinsic library functions are being compiled, passing all
-values in registers, no matter the size.
-
-@item -mepsilon
-@itemx -mno-epsilon
-@opindex mepsilon
-@opindex mno-epsilon
-Generate floating-point comparison instructions that compare with respect
-to the @code{rE} epsilon register.
-
-@item -mabi=mmixware
-@itemx -mabi=gnu
-@opindex mabi=mmixware
-@opindex mabi=gnu
-Generate code that passes function parameters and return values that (in
-the called function) are seen as registers @code{$0} and up, as opposed to
-the GNU ABI which uses global registers @code{$231} and up.
-
-@item -mzero-extend
-@itemx -mno-zero-extend
-@opindex mzero-extend
-@opindex mno-zero-extend
-When reading data from memory in sizes shorter than 64 bits, use (do not
-use) zero-extending load instructions by default, rather than
-sign-extending ones.
-
-@item -mknuthdiv
-@itemx -mno-knuthdiv
-@opindex mknuthdiv
-@opindex mno-knuthdiv
-Make the result of a division yielding a remainder have the same sign as
-the divisor. With the default, @option{-mno-knuthdiv}, the sign of the
-remainder follows the sign of the dividend. Both methods are
-arithmetically valid, the latter being almost exclusively used.
-
-@item -mtoplevel-symbols
-@itemx -mno-toplevel-symbols
-@opindex mtoplevel-symbols
-@opindex mno-toplevel-symbols
-Prepend (do not prepend) a @samp{:} to all global symbols, so the assembly
-code can be used with the @code{PREFIX} assembly directive.
-
-@item -melf
-@opindex melf
-Generate an executable in the ELF format, rather than the default
-@samp{mmo} format used by the @command{mmix} simulator.
-
-@item -mbranch-predict
-@itemx -mno-branch-predict
-@opindex mbranch-predict
-@opindex mno-branch-predict
-Use (do not use) the probable-branch instructions, when static branch
-prediction indicates a probable branch.
-
-@item -mbase-addresses
-@itemx -mno-base-addresses
-@opindex mbase-addresses
-@opindex mno-base-addresses
-Generate (do not generate) code that uses @emph{base addresses}. Using a
-base address automatically generates a request (handled by the assembler
-and the linker) for a constant to be set up in a global register. The
-register is used for one or more base address requests within the range 0
-to 255 from the value held in the register. The generally leads to short
-and fast code, but the number of different data items that can be
-addressed is limited. This means that a program that uses lots of static
-data may require @option{-mno-base-addresses}.
-
-@item -msingle-exit
-@itemx -mno-single-exit
-@opindex msingle-exit
-@opindex mno-single-exit
-Force (do not force) generated code to have a single exit point in each
-function.
-@end table
-
-@node MN10300 Options
-@subsection MN10300 Options
-@cindex MN10300 options
-
-These @option{-m} options are defined for Matsushita MN10300 architectures:
-
-@table @gcctabopt
-@item -mmult-bug
-@opindex mmult-bug
-Generate code to avoid bugs in the multiply instructions for the MN10300
-processors. This is the default.
-
-@item -mno-mult-bug
-@opindex mno-mult-bug
-Do not generate code to avoid bugs in the multiply instructions for the
-MN10300 processors.
-
-@item -mam33
-@opindex mam33
-Generate code using features specific to the AM33 processor.
-
-@item -mno-am33
-@opindex mno-am33
-Do not generate code using features specific to the AM33 processor. This
-is the default.
-
-@item -mam33-2
-@opindex mam33-2
-Generate code using features specific to the AM33/2.0 processor.
-
-@item -mam34
-@opindex mam34
-Generate code using features specific to the AM34 processor.
-
-@item -mtune=@var{cpu-type}
-@opindex mtune
-Use the timing characteristics of the indicated CPU type when
-scheduling instructions. This does not change the targeted processor
-type. The CPU type must be one of @samp{mn10300}, @samp{am33},
-@samp{am33-2} or @samp{am34}.
-
-@item -mreturn-pointer-on-d0
-@opindex mreturn-pointer-on-d0
-When generating a function that returns a pointer, return the pointer
-in both @code{a0} and @code{d0}. Otherwise, the pointer is returned
-only in @code{a0}, and attempts to call such functions without a prototype
-result in errors. Note that this option is on by default; use
-@option{-mno-return-pointer-on-d0} to disable it.
-
-@item -mno-crt0
-@opindex mno-crt0
-Do not link in the C run-time initialization object file.
-
-@item -mrelax
-@opindex mrelax
-Indicate to the linker that it should perform a relaxation optimization pass
-to shorten branches, calls and absolute memory addresses. This option only
-has an effect when used on the command line for the final link step.
-
-This option makes symbolic debugging impossible.
-
-@item -mliw
-@opindex mliw
-Allow the compiler to generate @emph{Long Instruction Word}
-instructions if the target is the @samp{AM33} or later. This is the
-default. This option defines the preprocessor macro @samp{__LIW__}.
-
-@item -mnoliw
-@opindex mnoliw
-Do not allow the compiler to generate @emph{Long Instruction Word}
-instructions. This option defines the preprocessor macro
-@samp{__NO_LIW__}.
-
-@item -msetlb
-@opindex msetlb
-Allow the compiler to generate the @emph{SETLB} and @emph{Lcc}
-instructions if the target is the @samp{AM33} or later. This is the
-default. This option defines the preprocessor macro @samp{__SETLB__}.
-
-@item -mnosetlb
-@opindex mnosetlb
-Do not allow the compiler to generate @emph{SETLB} or @emph{Lcc}
-instructions. This option defines the preprocessor macro
-@samp{__NO_SETLB__}.
-
-@end table
-
-@node Moxie Options
-@subsection Moxie Options
-@cindex Moxie Options
-
-@table @gcctabopt
-
-@item -meb
-@opindex meb
-Generate big-endian code. This is the default for @samp{moxie-*-*}
-configurations.
-
-@item -mel
-@opindex mel
-Generate little-endian code.
-
-@item -mno-crt0
-@opindex mno-crt0
-Do not link in the C run-time initialization object file.
-
-@end table
-
-@node PDP-11 Options
-@subsection PDP-11 Options
-@cindex PDP-11 Options
-
-These options are defined for the PDP-11:
-
-@table @gcctabopt
-@item -mfpu
-@opindex mfpu
-Use hardware FPP floating point. This is the default. (FIS floating
-point on the PDP-11/40 is not supported.)
-
-@item -msoft-float
-@opindex msoft-float
-Do not use hardware floating point.
-
-@item -mac0
-@opindex mac0
-Return floating-point results in ac0 (fr0 in Unix assembler syntax).
-
-@item -mno-ac0
-@opindex mno-ac0
-Return floating-point results in memory. This is the default.
-
-@item -m40
-@opindex m40
-Generate code for a PDP-11/40.
-
-@item -m45
-@opindex m45
-Generate code for a PDP-11/45. This is the default.
-
-@item -m10
-@opindex m10
-Generate code for a PDP-11/10.
-
-@item -mbcopy-builtin
-@opindex mbcopy-builtin
-Use inline @code{movmemhi} patterns for copying memory. This is the
-default.
-
-@item -mbcopy
-@opindex mbcopy
-Do not use inline @code{movmemhi} patterns for copying memory.
-
-@item -mint16
-@itemx -mno-int32
-@opindex mint16
-@opindex mno-int32
-Use 16-bit @code{int}. This is the default.
-
-@item -mint32
-@itemx -mno-int16
-@opindex mint32
-@opindex mno-int16
-Use 32-bit @code{int}.
-
-@item -mfloat64
-@itemx -mno-float32
-@opindex mfloat64
-@opindex mno-float32
-Use 64-bit @code{float}. This is the default.
-
-@item -mfloat32
-@itemx -mno-float64
-@opindex mfloat32
-@opindex mno-float64
-Use 32-bit @code{float}.
-
-@item -mabshi
-@opindex mabshi
-Use @code{abshi2} pattern. This is the default.
-
-@item -mno-abshi
-@opindex mno-abshi
-Do not use @code{abshi2} pattern.
-
-@item -mbranch-expensive
-@opindex mbranch-expensive
-Pretend that branches are expensive. This is for experimenting with
-code generation only.
-
-@item -mbranch-cheap
-@opindex mbranch-cheap
-Do not pretend that branches are expensive. This is the default.
-
-@item -munix-asm
-@opindex munix-asm
-Use Unix assembler syntax. This is the default when configured for
-@samp{pdp11-*-bsd}.
-
-@item -mdec-asm
-@opindex mdec-asm
-Use DEC assembler syntax. This is the default when configured for any
-PDP-11 target other than @samp{pdp11-*-bsd}.
-@end table
-
-@node picoChip Options
-@subsection picoChip Options
-@cindex picoChip options
-
-These @samp{-m} options are defined for picoChip implementations:
-
-@table @gcctabopt
-
-@item -mae=@var{ae_type}
-@opindex mcpu
-Set the instruction set, register set, and instruction scheduling
-parameters for array element type @var{ae_type}. Supported values
-for @var{ae_type} are @samp{ANY}, @samp{MUL}, and @samp{MAC}.
-
-@option{-mae=ANY} selects a completely generic AE type. Code
-generated with this option runs on any of the other AE types. The
-code is not as efficient as it would be if compiled for a specific
-AE type, and some types of operation (e.g., multiplication) do not
-work properly on all types of AE.
-
-@option{-mae=MUL} selects a MUL AE type. This is the most useful AE type
-for compiled code, and is the default.
-
-@option{-mae=MAC} selects a DSP-style MAC AE. Code compiled with this
-option may suffer from poor performance of byte (char) manipulation,
-since the DSP AE does not provide hardware support for byte load/stores.
-
-@item -msymbol-as-address
-Enable the compiler to directly use a symbol name as an address in a
-load/store instruction, without first loading it into a
-register. Typically, the use of this option generates larger
-programs, which run faster than when the option isn't used. However, the
-results vary from program to program, so it is left as a user option,
-rather than being permanently enabled.
-
-@item -mno-inefficient-warnings
-Disables warnings about the generation of inefficient code. These
-warnings can be generated, for example, when compiling code that
-performs byte-level memory operations on the MAC AE type. The MAC AE has
-no hardware support for byte-level memory operations, so all byte
-load/stores must be synthesized from word load/store operations. This is
-inefficient and a warning is generated to indicate
-that you should rewrite the code to avoid byte operations, or to target
-an AE type that has the necessary hardware support. This option disables
-these warnings.
-
-@end table
-
-@node PowerPC Options
-@subsection PowerPC Options
-@cindex PowerPC options
-
-These are listed under @xref{RS/6000 and PowerPC Options}.
-
-@node RL78 Options
-@subsection RL78 Options
-@cindex RL78 Options
-
-@table @gcctabopt
-
-@item -msim
-@opindex msim
-Links in additional target libraries to support operation within a
-simulator.
-
-@item -mmul=none
-@itemx -mmul=g13
-@itemx -mmul=rl78
-@opindex mmul
-Specifies the type of hardware multiplication support to be used. The
-default is @code{none}, which uses software multiplication functions.
-The @code{g13} option is for the hardware multiply/divide peripheral
-only on the RL78/G13 targets. The @code{rl78} option is for the
-standard hardware multiplication defined in the RL78 software manual.
-
-@end table
-
-@node RS/6000 and PowerPC Options
-@subsection IBM RS/6000 and PowerPC Options
-@cindex RS/6000 and PowerPC Options
-@cindex IBM RS/6000 and PowerPC Options
-
-These @samp{-m} options are defined for the IBM RS/6000 and PowerPC:
-@table @gcctabopt
-@item -mpowerpc-gpopt
-@itemx -mno-powerpc-gpopt
-@itemx -mpowerpc-gfxopt
-@itemx -mno-powerpc-gfxopt
-@need 800
-@itemx -mpowerpc64
-@itemx -mno-powerpc64
-@itemx -mmfcrf
-@itemx -mno-mfcrf
-@itemx -mpopcntb
-@itemx -mno-popcntb
-@itemx -mpopcntd
-@itemx -mno-popcntd
-@itemx -mfprnd
-@itemx -mno-fprnd
-@need 800
-@itemx -mcmpb
-@itemx -mno-cmpb
-@itemx -mmfpgpr
-@itemx -mno-mfpgpr
-@itemx -mhard-dfp
-@itemx -mno-hard-dfp
-@opindex mpowerpc-gpopt
-@opindex mno-powerpc-gpopt
-@opindex mpowerpc-gfxopt
-@opindex mno-powerpc-gfxopt
-@opindex mpowerpc64
-@opindex mno-powerpc64
-@opindex mmfcrf
-@opindex mno-mfcrf
-@opindex mpopcntb
-@opindex mno-popcntb
-@opindex mpopcntd
-@opindex mno-popcntd
-@opindex mfprnd
-@opindex mno-fprnd
-@opindex mcmpb
-@opindex mno-cmpb
-@opindex mmfpgpr
-@opindex mno-mfpgpr
-@opindex mhard-dfp
-@opindex mno-hard-dfp
-You use these options to specify which instructions are available on the
-processor you are using. The default value of these options is
-determined when configuring GCC@. Specifying the
-@option{-mcpu=@var{cpu_type}} overrides the specification of these
-options. We recommend you use the @option{-mcpu=@var{cpu_type}} option
-rather than the options listed above.
-
-Specifying @option{-mpowerpc-gpopt} allows
-GCC to use the optional PowerPC architecture instructions in the
-General Purpose group, including floating-point square root. Specifying
-@option{-mpowerpc-gfxopt} allows GCC to
-use the optional PowerPC architecture instructions in the Graphics
-group, including floating-point select.
-
-The @option{-mmfcrf} option allows GCC to generate the move from
-condition register field instruction implemented on the POWER4
-processor and other processors that support the PowerPC V2.01
-architecture.
-The @option{-mpopcntb} option allows GCC to generate the popcount and
-double-precision FP reciprocal estimate instruction implemented on the
-POWER5 processor and other processors that support the PowerPC V2.02
-architecture.
-The @option{-mpopcntd} option allows GCC to generate the popcount
-instruction implemented on the POWER7 processor and other processors
-that support the PowerPC V2.06 architecture.
-The @option{-mfprnd} option allows GCC to generate the FP round to
-integer instructions implemented on the POWER5+ processor and other
-processors that support the PowerPC V2.03 architecture.
-The @option{-mcmpb} option allows GCC to generate the compare bytes
-instruction implemented on the POWER6 processor and other processors
-that support the PowerPC V2.05 architecture.
-The @option{-mmfpgpr} option allows GCC to generate the FP move to/from
-general-purpose register instructions implemented on the POWER6X
-processor and other processors that support the extended PowerPC V2.05
-architecture.
-The @option{-mhard-dfp} option allows GCC to generate the decimal
-floating-point instructions implemented on some POWER processors.
-
-The @option{-mpowerpc64} option allows GCC to generate the additional
-64-bit instructions that are found in the full PowerPC64 architecture
-and to treat GPRs as 64-bit, doubleword quantities. GCC defaults to
-@option{-mno-powerpc64}.
-
-@item -mcpu=@var{cpu_type}
-@opindex mcpu
-Set architecture type, register usage, and
-instruction scheduling parameters for machine type @var{cpu_type}.
-Supported values for @var{cpu_type} are @samp{401}, @samp{403},
-@samp{405}, @samp{405fp}, @samp{440}, @samp{440fp}, @samp{464}, @samp{464fp},
-@samp{476}, @samp{476fp}, @samp{505}, @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{a2}, @samp{e300c2},
-@samp{e300c3}, @samp{e500mc}, @samp{e500mc64}, @samp{e5500},
-@samp{e6500}, @samp{ec603e}, @samp{G3}, @samp{G4}, @samp{G5},
-@samp{titan}, @samp{power3}, @samp{power4}, @samp{power5}, @samp{power5+},
-@samp{power6}, @samp{power6x}, @samp{power7}, @samp{power8}, @samp{powerpc},
-@samp{powerpc64}, and @samp{rs64}.
-
-@option{-mcpu=powerpc}, and @option{-mcpu=powerpc64} specify pure 32-bit
-PowerPC and 64-bit PowerPC architecture machine
-types, with an appropriate, generic processor model assumed for
-scheduling purposes.
-
-The other options specify a specific processor. Code generated under
-those options runs best on that processor, and may not run at all on
-others.
-
-The @option{-mcpu} options automatically enable or disable the
-following options:
-
-@gccoptlist{-maltivec -mfprnd -mhard-float -mmfcrf -mmultiple @gol
--mpopcntb -mpopcntd -mpowerpc64 @gol
--mpowerpc-gpopt -mpowerpc-gfxopt -msingle-float -mdouble-float @gol
--msimple-fpu -mstring -mmulhw -mdlmzb -mmfpgpr -mvsx}
-
-The particular options set for any particular CPU varies between
-compiler versions, depending on what setting seems to produce optimal
-code for that CPU; it doesn't necessarily reflect the actual hardware's
-capabilities. If you wish to set an individual option to a particular
-value, you may specify it after the @option{-mcpu} option, like
-@option{-mcpu=970 -mno-altivec}.
-
-On AIX, the @option{-maltivec} and @option{-mpowerpc64} options are
-not enabled or disabled by the @option{-mcpu} option at present because
-AIX does not have full support for these options. You may still
-enable or disable them individually if you're sure it'll work in your
-environment.
-
-@item -mtune=@var{cpu_type}
-@opindex mtune
-Set the instruction scheduling parameters for machine type
-@var{cpu_type}, but do not set the architecture type or register usage,
-as @option{-mcpu=@var{cpu_type}} does. The same
-values for @var{cpu_type} are used for @option{-mtune} as for
-@option{-mcpu}. If both are specified, the code generated uses the
-architecture and registers set by @option{-mcpu}, but the
-scheduling parameters set by @option{-mtune}.
-
-@item -mcmodel=small
-@opindex mcmodel=small
-Generate PowerPC64 code for the small model: The TOC is limited to
-64k.
-
-@item -mcmodel=medium
-@opindex mcmodel=medium
-Generate PowerPC64 code for the medium model: The TOC and other static
-data may be up to a total of 4G in size.
-
-@item -mcmodel=large
-@opindex mcmodel=large
-Generate PowerPC64 code for the large model: The TOC may be up to 4G
-in size. Other data and code is only limited by the 64-bit address
-space.
-
-@item -maltivec
-@itemx -mno-altivec
-@opindex maltivec
-@opindex mno-altivec
-Generate code that uses (does not use) AltiVec instructions, and also
-enable the use of built-in functions that allow more direct access to
-the AltiVec instruction set. You may also need to set
-@option{-mabi=altivec} to adjust the current ABI with AltiVec ABI
-enhancements.
-
-@item -mvrsave
-@itemx -mno-vrsave
-@opindex mvrsave
-@opindex mno-vrsave
-Generate VRSAVE instructions when generating AltiVec code.
-
-@item -mgen-cell-microcode
-@opindex mgen-cell-microcode
-Generate Cell microcode instructions.
-
-@item -mwarn-cell-microcode
-@opindex mwarn-cell-microcode
-Warn when a Cell microcode instruction is emitted. An example
-of a Cell microcode instruction is a variable shift.
-
-@item -msecure-plt
-@opindex msecure-plt
-Generate code that allows @command{ld} and @command{ld.so}
-to build executables and shared
-libraries with non-executable @code{.plt} and @code{.got} sections.
-This is a PowerPC
-32-bit SYSV ABI option.
-
-@item -mbss-plt
-@opindex mbss-plt
-Generate code that uses a BSS @code{.plt} section that @command{ld.so}
-fills in, and
-requires @code{.plt} and @code{.got}
-sections that are both writable and executable.
-This is a PowerPC 32-bit SYSV ABI option.
-
-@item -misel
-@itemx -mno-isel
-@opindex misel
-@opindex mno-isel
-This switch enables or disables the generation of ISEL instructions.
-
-@item -misel=@var{yes/no}
-This switch has been deprecated. Use @option{-misel} and
-@option{-mno-isel} instead.
-
-@item -mspe
-@itemx -mno-spe
-@opindex mspe
-@opindex mno-spe
-This switch enables or disables the generation of SPE simd
-instructions.
-
-@item -mpaired
-@itemx -mno-paired
-@opindex mpaired
-@opindex mno-paired
-This switch enables or disables the generation of PAIRED simd
-instructions.
-
-@item -mspe=@var{yes/no}
-This option has been deprecated. Use @option{-mspe} and
-@option{-mno-spe} instead.
-
-@item -mvsx
-@itemx -mno-vsx
-@opindex mvsx
-@opindex mno-vsx
-Generate code that uses (does not use) vector/scalar (VSX)
-instructions, and also enable the use of built-in functions that allow
-more direct access to the VSX instruction set.
-
-@item -mfloat-gprs=@var{yes/single/double/no}
-@itemx -mfloat-gprs
-@opindex mfloat-gprs
-This switch enables or disables the generation of floating-point
-operations on the general-purpose registers for architectures that
-support it.
-
-The argument @var{yes} or @var{single} enables the use of
-single-precision floating-point operations.
-
-The argument @var{double} enables the use of single and
-double-precision floating-point operations.
-
-The argument @var{no} disables floating-point operations on the
-general-purpose registers.
-
-This option is currently only available on the MPC854x.
-
-@item -m32
-@itemx -m64
-@opindex m32
-@opindex m64
-Generate code for 32-bit or 64-bit environments of Darwin and SVR4
-targets (including GNU/Linux). The 32-bit environment sets int, long
-and pointer to 32 bits and generates code that runs on any PowerPC
-variant. The 64-bit environment sets int to 32 bits and long and
-pointer to 64 bits, and generates code for PowerPC64, as for
-@option{-mpowerpc64}.
-
-@item -mfull-toc
-@itemx -mno-fp-in-toc
-@itemx -mno-sum-in-toc
-@itemx -mminimal-toc
-@opindex mfull-toc
-@opindex mno-fp-in-toc
-@opindex mno-sum-in-toc
-@opindex mminimal-toc
-Modify generation of the TOC (Table Of Contents), which is created for
-every executable file. The @option{-mfull-toc} option is selected by
-default. In that case, GCC allocates at least one TOC entry for
-each unique non-automatic variable reference in your program. GCC
-also places floating-point constants in the TOC@. However, only
-16,384 entries are available in the TOC@.
-
-If you receive a linker error message that saying you have overflowed
-the available TOC space, you can reduce the amount of TOC space used
-with the @option{-mno-fp-in-toc} and @option{-mno-sum-in-toc} options.
-@option{-mno-fp-in-toc} prevents GCC from putting floating-point
-constants in the TOC and @option{-mno-sum-in-toc} forces GCC to
-generate code to calculate the sum of an address and a constant at
-run time instead of putting that sum into the TOC@. You may specify one
-or both of these options. Each causes GCC to produce very slightly
-slower and larger code at the expense of conserving TOC space.
-
-If you still run out of space in the TOC even when you specify both of
-these options, specify @option{-mminimal-toc} instead. This option causes
-GCC to make only one TOC entry for every file. When you specify this
-option, GCC produces code that is slower and larger but which
-uses extremely little TOC space. You may wish to use this option
-only on files that contain less frequently-executed code.
-
-@item -maix64
-@itemx -maix32
-@opindex maix64
-@opindex maix32
-Enable 64-bit AIX ABI and calling convention: 64-bit pointers, 64-bit
-@code{long} type, and the infrastructure needed to support them.
-Specifying @option{-maix64} implies @option{-mpowerpc64},
-while @option{-maix32} disables the 64-bit ABI and
-implies @option{-mno-powerpc64}. GCC defaults to @option{-maix32}.
-
-@item -mxl-compat
-@itemx -mno-xl-compat
-@opindex mxl-compat
-@opindex mno-xl-compat
-Produce code that conforms more closely to IBM XL compiler semantics
-when using AIX-compatible ABI@. Pass floating-point arguments to
-prototyped functions beyond the register save area (RSA) on the stack
-in addition to argument FPRs. Do not assume that most significant
-double in 128-bit long double value is properly rounded when comparing
-values and converting to double. Use XL symbol names for long double
-support routines.
-
-The AIX calling convention was extended but not initially documented to
-handle an obscure K&R C case of calling a function that takes the
-address of its arguments with fewer arguments than declared. IBM XL
-compilers access floating-point arguments that do not fit in the
-RSA from the stack when a subroutine is compiled without
-optimization. Because always storing floating-point arguments on the
-stack is inefficient and rarely needed, this option is not enabled by
-default and only is necessary when calling subroutines compiled by IBM
-XL compilers without optimization.
-
-@item -mpe
-@opindex mpe
-Support @dfn{IBM RS/6000 SP} @dfn{Parallel Environment} (PE)@. Link an
-application written to use message passing with special startup code to
-enable the application to run. The system must have PE installed in the
-standard location (@file{/usr/lpp/ppe.poe/}), or the @file{specs} file
-must be overridden with the @option{-specs=} option to specify the
-appropriate directory location. The Parallel Environment does not
-support threads, so the @option{-mpe} option and the @option{-pthread}
-option are incompatible.
-
-@item -malign-natural
-@itemx -malign-power
-@opindex malign-natural
-@opindex malign-power
-On AIX, 32-bit Darwin, and 64-bit PowerPC GNU/Linux, the option
-@option{-malign-natural} overrides the ABI-defined alignment of larger
-types, such as floating-point doubles, on their natural size-based boundary.
-The option @option{-malign-power} instructs GCC to follow the ABI-specified
-alignment rules. GCC defaults to the standard alignment defined in the ABI@.
-
-On 64-bit Darwin, natural alignment is the default, and @option{-malign-power}
-is not supported.
-
-@item -msoft-float
-@itemx -mhard-float
-@opindex msoft-float
-@opindex mhard-float
-Generate code that does not use (uses) the floating-point register set.
-Software floating-point emulation is provided if you use the
-@option{-msoft-float} option, and pass the option to GCC when linking.
-
-@item -msingle-float
-@itemx -mdouble-float
-@opindex msingle-float
-@opindex mdouble-float
-Generate code for single- or double-precision floating-point operations.
-@option{-mdouble-float} implies @option{-msingle-float}.
-
-@item -msimple-fpu
-@opindex msimple-fpu
-Do not generate @code{sqrt} and @code{div} instructions for hardware
-floating-point unit.
-
-@item -mfpu=@var{name}
-@opindex mfpu
-Specify type of floating-point unit. Valid values for @var{name} are
-@samp{sp_lite} (equivalent to @option{-msingle-float -msimple-fpu}),
-@samp{dp_lite} (equivalent to @option{-mdouble-float -msimple-fpu}),
-@samp{sp_full} (equivalent to @option{-msingle-float}),
-and @samp{dp_full} (equivalent to @option{-mdouble-float}).
-
-@item -mxilinx-fpu
-@opindex mxilinx-fpu
-Perform optimizations for the floating-point unit on Xilinx PPC 405/440.
-
-@item -mmultiple
-@itemx -mno-multiple
-@opindex mmultiple
-@opindex mno-multiple
-Generate code that uses (does not use) the load multiple word
-instructions and the store multiple word instructions. These
-instructions are generated by default on POWER systems, and not
-generated on PowerPC systems. Do not use @option{-mmultiple} on little-endian
-PowerPC systems, since those instructions do not work when the
-processor is in little-endian mode. The exceptions are PPC740 and
-PPC750 which permit these instructions in little-endian mode.
-
-@item -mstring
-@itemx -mno-string
-@opindex mstring
-@opindex mno-string
-Generate code that uses (does not use) the load string instructions
-and the store string word instructions to save multiple registers and
-do small block moves. These instructions are generated by default on
-POWER systems, and not generated on PowerPC systems. Do not use
-@option{-mstring} on little-endian PowerPC systems, since those
-instructions do not work when the processor is in little-endian mode.
-The exceptions are PPC740 and PPC750 which permit these instructions
-in little-endian mode.
-
-@item -mupdate
-@itemx -mno-update
-@opindex mupdate
-@opindex mno-update
-Generate code that uses (does not use) the load or store instructions
-that update the base register to the address of the calculated memory
-location. These instructions are generated by default. If you use
-@option{-mno-update}, there is a small window between the time that the
-stack pointer is updated and the address of the previous frame is
-stored, which means code that walks the stack frame across interrupts or
-signals may get corrupted data.
-
-@item -mavoid-indexed-addresses
-@itemx -mno-avoid-indexed-addresses
-@opindex mavoid-indexed-addresses
-@opindex mno-avoid-indexed-addresses
-Generate code that tries to avoid (not avoid) the use of indexed load
-or store instructions. These instructions can incur a performance
-penalty on Power6 processors in certain situations, such as when
-stepping through large arrays that cross a 16M boundary. This option
-is enabled by default when targeting Power6 and disabled otherwise.
-
-@item -mfused-madd
-@itemx -mno-fused-madd
-@opindex mfused-madd
-@opindex mno-fused-madd
-Generate code that uses (does not use) the floating-point multiply and
-accumulate instructions. These instructions are generated by default
-if hardware floating point is used. The machine-dependent
-@option{-mfused-madd} option is now mapped to the machine-independent
-@option{-ffp-contract=fast} option, and @option{-mno-fused-madd} is
-mapped to @option{-ffp-contract=off}.
-
-@item -mmulhw
-@itemx -mno-mulhw
-@opindex mmulhw
-@opindex mno-mulhw
-Generate code that uses (does not use) the half-word multiply and
-multiply-accumulate instructions on the IBM 405, 440, 464 and 476 processors.
-These instructions are generated by default when targeting those
-processors.
-
-@item -mdlmzb
-@itemx -mno-dlmzb
-@opindex mdlmzb
-@opindex mno-dlmzb
-Generate code that uses (does not use) the string-search @samp{dlmzb}
-instruction on the IBM 405, 440, 464 and 476 processors. This instruction is
-generated by default when targeting those processors.
-
-@item -mno-bit-align
-@itemx -mbit-align
-@opindex mno-bit-align
-@opindex mbit-align
-On System V.4 and embedded PowerPC systems do not (do) force structures
-and unions that contain bit-fields to be aligned to the base type of the
-bit-field.
-
-For example, by default a structure containing nothing but 8
-@code{unsigned} bit-fields of length 1 is aligned to a 4-byte
-boundary and has a size of 4 bytes. By using @option{-mno-bit-align},
-the structure is aligned to a 1-byte boundary and is 1 byte in
-size.
-
-@item -mno-strict-align
-@itemx -mstrict-align
-@opindex mno-strict-align
-@opindex mstrict-align
-On System V.4 and embedded PowerPC systems do not (do) assume that
-unaligned memory references are handled by the system.
-
-@item -mrelocatable
-@itemx -mno-relocatable
-@opindex mrelocatable
-@opindex mno-relocatable
-Generate code that allows (does not allow) a static executable to be
-relocated to a different address at run time. A simple embedded
-PowerPC system loader should relocate the entire contents of
-@code{.got2} and 4-byte locations listed in the @code{.fixup} section,
-a table of 32-bit addresses generated by this option. For this to
-work, all objects linked together must be compiled with
-@option{-mrelocatable} or @option{-mrelocatable-lib}.
-@option{-mrelocatable} code aligns the stack to an 8-byte boundary.
-
-@item -mrelocatable-lib
-@itemx -mno-relocatable-lib
-@opindex mrelocatable-lib
-@opindex mno-relocatable-lib
-Like @option{-mrelocatable}, @option{-mrelocatable-lib} generates a
-@code{.fixup} section to allow static executables to be relocated at
-run time, but @option{-mrelocatable-lib} does not use the smaller stack
-alignment of @option{-mrelocatable}. Objects compiled with
-@option{-mrelocatable-lib} may be linked with objects compiled with
-any combination of the @option{-mrelocatable} options.
-
-@item -mno-toc
-@itemx -mtoc
-@opindex mno-toc
-@opindex mtoc
-On System V.4 and embedded PowerPC systems do not (do) assume that
-register 2 contains a pointer to a global area pointing to the addresses
-used in the program.
-
-@item -mlittle
-@itemx -mlittle-endian
-@opindex mlittle
-@opindex mlittle-endian
-On System V.4 and embedded PowerPC systems compile code for the
-processor in little-endian mode. The @option{-mlittle-endian} option is
-the same as @option{-mlittle}.
-
-@item -mbig
-@itemx -mbig-endian
-@opindex mbig
-@opindex mbig-endian
-On System V.4 and embedded PowerPC systems compile code for the
-processor in big-endian mode. The @option{-mbig-endian} option is
-the same as @option{-mbig}.
-
-@item -mdynamic-no-pic
-@opindex mdynamic-no-pic
-On Darwin and Mac OS X systems, compile code so that it is not
-relocatable, but that its external references are relocatable. The
-resulting code is suitable for applications, but not shared
-libraries.
-
-@item -msingle-pic-base
-@opindex msingle-pic-base
-Treat the register used for PIC addressing as read-only, rather than
-loading it in the prologue for each function. The runtime system is
-responsible for initializing this register with an appropriate value
-before execution begins.
-
-@item -mprioritize-restricted-insns=@var{priority}
-@opindex mprioritize-restricted-insns
-This option controls the priority that is assigned to
-dispatch-slot restricted instructions during the second scheduling
-pass. The argument @var{priority} takes the value @samp{0}, @samp{1},
-or @samp{2} to assign no, highest, or second-highest (respectively)
-priority to dispatch-slot restricted
-instructions.
-
-@item -msched-costly-dep=@var{dependence_type}
-@opindex msched-costly-dep
-This option controls which dependences are considered costly
-by the target during instruction scheduling. The argument
-@var{dependence_type} takes one of the following values:
-
-@table @asis
-@item @samp{no}
-No dependence is costly.
-
-@item @samp{all}
-All dependences are costly.
-
-@item @samp{true_store_to_load}
-A true dependence from store to load is costly.
-
-@item @samp{store_to_load}
-Any dependence from store to load is costly.
-
-@item @var{number}
-Any dependence for which the latency is greater than or equal to
-@var{number} is costly.
-@end table
-
-@item -minsert-sched-nops=@var{scheme}
-@opindex minsert-sched-nops
-This option controls which NOP insertion scheme is used during
-the second scheduling pass. The argument @var{scheme} takes one of the
-following values:
-
-@table @asis
-@item @samp{no}
-Don't insert NOPs.
-
-@item @samp{pad}
-Pad with NOPs any dispatch group that has vacant issue slots,
-according to the scheduler's grouping.
-
-@item @samp{regroup_exact}
-Insert NOPs to force costly dependent insns into
-separate groups. Insert exactly as many NOPs as needed to force an insn
-to a new group, according to the estimated processor grouping.
-
-@item @var{number}
-Insert NOPs to force costly dependent insns into
-separate groups. Insert @var{number} NOPs to force an insn to a new group.
-@end table
-
-@item -mcall-sysv
-@opindex mcall-sysv
-On System V.4 and embedded PowerPC systems compile code using calling
-conventions that adhere to the March 1995 draft of the System V
-Application Binary Interface, PowerPC processor supplement. This is the
-default unless you configured GCC using @samp{powerpc-*-eabiaix}.
-
-@item -mcall-sysv-eabi
-@itemx -mcall-eabi
-@opindex mcall-sysv-eabi
-@opindex mcall-eabi
-Specify both @option{-mcall-sysv} and @option{-meabi} options.
-
-@item -mcall-sysv-noeabi
-@opindex mcall-sysv-noeabi
-Specify both @option{-mcall-sysv} and @option{-mno-eabi} options.
-
-@item -mcall-aixdesc
-@opindex m
-On System V.4 and embedded PowerPC systems compile code for the AIX
-operating system.
-
-@item -mcall-linux
-@opindex mcall-linux
-On System V.4 and embedded PowerPC systems compile code for the
-Linux-based GNU system.
-
-@item -mcall-freebsd
-@opindex mcall-freebsd
-On System V.4 and embedded PowerPC systems compile code for the
-FreeBSD operating system.
-
-@item -mcall-netbsd
-@opindex mcall-netbsd
-On System V.4 and embedded PowerPC systems compile code for the
-NetBSD operating system.
-
-@item -mcall-openbsd
-@opindex mcall-netbsd
-On System V.4 and embedded PowerPC systems compile code for the
-OpenBSD operating system.
-
-@item -maix-struct-return
-@opindex maix-struct-return
-Return all structures in memory (as specified by the AIX ABI)@.
-
-@item -msvr4-struct-return
-@opindex msvr4-struct-return
-Return structures smaller than 8 bytes in registers (as specified by the
-SVR4 ABI)@.
-
-@item -mabi=@var{abi-type}
-@opindex mabi
-Extend the current ABI with a particular extension, or remove such extension.
-Valid values are @var{altivec}, @var{no-altivec}, @var{spe},
-@var{no-spe}, @var{ibmlongdouble}, @var{ieeelongdouble}@.
-
-@item -mabi=spe
-@opindex mabi=spe
-Extend the current ABI with SPE ABI extensions. This does not change
-the default ABI, instead it adds the SPE ABI extensions to the current
-ABI@.
-
-@item -mabi=no-spe
-@opindex mabi=no-spe
-Disable Book-E SPE ABI extensions for the current ABI@.
-
-@item -mabi=ibmlongdouble
-@opindex mabi=ibmlongdouble
-Change the current ABI to use IBM extended-precision long double.
-This is a PowerPC 32-bit SYSV ABI option.
-
-@item -mabi=ieeelongdouble
-@opindex mabi=ieeelongdouble
-Change the current ABI to use IEEE extended-precision long double.
-This is a PowerPC 32-bit Linux ABI option.
-
-@item -mprototype
-@itemx -mno-prototype
-@opindex mprototype
-@opindex mno-prototype
-On System V.4 and embedded PowerPC systems assume that all calls to
-variable argument functions are properly prototyped. Otherwise, the
-compiler must insert an instruction before every non-prototyped call to
-set or clear bit 6 of the condition code register (@var{CR}) to
-indicate whether floating-point values are passed in the floating-point
-registers in case the function takes variable arguments. With
-@option{-mprototype}, only calls to prototyped variable argument functions
-set or clear the bit.
-
-@item -msim
-@opindex msim
-On embedded PowerPC systems, assume that the startup module is called
-@file{sim-crt0.o} and that the standard C libraries are @file{libsim.a} and
-@file{libc.a}. This is the default for @samp{powerpc-*-eabisim}
-configurations.
-
-@item -mmvme
-@opindex mmvme
-On embedded PowerPC systems, assume that the startup module is called
-@file{crt0.o} and the standard C libraries are @file{libmvme.a} and
-@file{libc.a}.
-
-@item -mads
-@opindex mads
-On embedded PowerPC systems, assume that the startup module is called
-@file{crt0.o} and the standard C libraries are @file{libads.a} and
-@file{libc.a}.
-
-@item -myellowknife
-@opindex myellowknife
-On embedded PowerPC systems, assume that the startup module is called
-@file{crt0.o} and the standard C libraries are @file{libyk.a} and
-@file{libc.a}.
-
-@item -mvxworks
-@opindex mvxworks
-On System V.4 and embedded PowerPC systems, specify that you are
-compiling for a VxWorks system.
-
-@item -memb
-@opindex memb
-On embedded PowerPC systems, set the @var{PPC_EMB} bit in the ELF flags
-header to indicate that @samp{eabi} extended relocations are used.
-
-@item -meabi
-@itemx -mno-eabi
-@opindex meabi
-@opindex mno-eabi
-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 from @code{main} to set up the EABI
-environment, 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,
-no EABI initialization function is called from @code{main}, and the
-@option{-msdata} option only uses @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.
-
-@item -msdata=eabi
-@opindex msdata=eabi
-On System V.4 and embedded PowerPC systems, put small initialized
-@code{const} global and static data in the @samp{.sdata2} section, which
-is pointed to by register @code{r2}. Put small initialized
-non-@code{const} global and static data in the @samp{.sdata} section,
-which is pointed to by register @code{r13}. Put small uninitialized
-global and static data in the @samp{.sbss} section, which is adjacent to
-the @samp{.sdata} section. The @option{-msdata=eabi} option is
-incompatible with the @option{-mrelocatable} option. The
-@option{-msdata=eabi} option also sets the @option{-memb} option.
-
-@item -msdata=sysv
-@opindex msdata=sysv
-On System V.4 and embedded PowerPC systems, put small global and static
-data in the @samp{.sdata} section, which is pointed to by register
-@code{r13}. Put small uninitialized global and static data in the
-@samp{.sbss} section, which is adjacent to the @samp{.sdata} section.
-The @option{-msdata=sysv} option is incompatible with the
-@option{-mrelocatable} option.
-
-@item -msdata=default
-@itemx -msdata
-@opindex msdata=default
-@opindex msdata
-On System V.4 and embedded PowerPC systems, if @option{-meabi} is used,
-compile code the same as @option{-msdata=eabi}, otherwise compile code the
-same as @option{-msdata=sysv}.
-
-@item -msdata=data
-@opindex msdata=data
-On System V.4 and embedded PowerPC systems, put small global
-data in the @samp{.sdata} section. Put small uninitialized global
-data in the @samp{.sbss} section. Do not use register @code{r13}
-to address small data however. This is the default behavior unless
-other @option{-msdata} options are used.
-
-@item -msdata=none
-@itemx -mno-sdata
-@opindex msdata=none
-@opindex mno-sdata
-On embedded PowerPC systems, put all initialized global and static data
-in the @samp{.data} section, and all uninitialized data in the
-@samp{.bss} section.
-
-@item -mblock-move-inline-limit=@var{num}
-@opindex mblock-move-inline-limit
-Inline all block moves (such as calls to @code{memcpy} or structure
-copies) less than or equal to @var{num} bytes. The minimum value for
-@var{num} is 32 bytes on 32-bit targets and 64 bytes on 64-bit
-targets. The default value is target-specific.
-
-@item -G @var{num}
-@opindex G
-@cindex smaller data references (PowerPC)
-@cindex .sdata/.sdata2 references (PowerPC)
-On embedded PowerPC systems, put global and static items less than or
-equal to @var{num} bytes into the small data or BSS sections instead of
-the normal data or BSS section. By default, @var{num} is 8. The
-@option{-G @var{num}} switch is also passed to the linker.
-All modules should be compiled with the same @option{-G @var{num}} value.
-
-@item -mregnames
-@itemx -mno-regnames
-@opindex mregnames
-@opindex mno-regnames
-On System V.4 and embedded PowerPC systems do (do not) emit register
-names in the assembly language output using symbolic forms.
-
-@item -mlongcall
-@itemx -mno-longcall
-@opindex mlongcall
-@opindex mno-longcall
-By default assume that all calls are far away so that a longer and more
-expensive calling sequence is required. This is required for calls
-farther than 32 megabytes (33,554,432 bytes) from the current location.
-A short call is generated if the compiler knows
-the call cannot be that far away. This setting can be overridden by
-the @code{shortcall} function attribute, or by @code{#pragma
-longcall(0)}.
-
-Some linkers are capable of detecting out-of-range calls and generating
-glue code on the fly. On these systems, long calls are unnecessary and
-generate slower code. As of this writing, the AIX linker can do this,
-as can the GNU linker for PowerPC/64. It is planned to add this feature
-to the GNU linker for 32-bit PowerPC systems as well.
-
-On Darwin/PPC systems, @code{#pragma longcall} generates @code{jbsr
-callee, L42}, plus a @dfn{branch island} (glue code). The two target
-addresses represent the callee and the branch island. The
-Darwin/PPC linker prefers the first address and generates a @code{bl
-callee} if the PPC @code{bl} instruction reaches the callee directly;
-otherwise, the linker generates @code{bl L42} to call the branch
-island. The branch island is appended to the body of the
-calling function; it computes the full 32-bit address of the callee
-and jumps to it.
-
-On Mach-O (Darwin) systems, this option directs the compiler emit to
-the glue for every direct call, and the Darwin linker decides whether
-to use or discard it.
-
-In the future, GCC may ignore all longcall specifications
-when the linker is known to generate glue.
-
-@item -mtls-markers
-@itemx -mno-tls-markers
-@opindex mtls-markers
-@opindex mno-tls-markers
-Mark (do not mark) calls to @code{__tls_get_addr} with a relocation
-specifying the function argument. The relocation allows the linker to
-reliably associate function call with argument setup instructions for
-TLS optimization, which in turn allows GCC to better schedule the
-sequence.
-
-@item -pthread
-@opindex pthread
-Adds support for multithreading with the @dfn{pthreads} library.
-This option sets flags for both the preprocessor and linker.
-
-@item -mrecip
-@itemx -mno-recip
-@opindex mrecip
-This option enables use of the reciprocal estimate and
-reciprocal square root estimate instructions with additional
-Newton-Raphson steps to increase precision instead of doing a divide or
-square root and divide for floating-point arguments. You should use
-the @option{-ffast-math} option when using @option{-mrecip} (or at
-least @option{-funsafe-math-optimizations},
-@option{-finite-math-only}, @option{-freciprocal-math} and
-@option{-fno-trapping-math}). Note that while the throughput of the
-sequence is generally higher than the throughput of the non-reciprocal
-instruction, the precision of the sequence can be decreased by up to 2
-ulp (i.e.@: the inverse of 1.0 equals 0.99999994) for reciprocal square
-roots.
-
-@item -mrecip=@var{opt}
-@opindex mrecip=opt
-This option controls which reciprocal estimate instructions
-may be used. @var{opt} is a comma-separated list of options, which may
-be preceded by a @code{!} to invert the option:
-@code{all}: enable all estimate instructions,
-@code{default}: enable the default instructions, equivalent to @option{-mrecip},
-@code{none}: disable all estimate instructions, equivalent to @option{-mno-recip};
-@code{div}: enable the reciprocal approximation instructions for both single and double precision;
-@code{divf}: enable the single-precision reciprocal approximation instructions;
-@code{divd}: enable the double-precision reciprocal approximation instructions;
-@code{rsqrt}: enable the reciprocal square root approximation instructions for both single and double precision;
-@code{rsqrtf}: enable the single-precision reciprocal square root approximation instructions;
-@code{rsqrtd}: enable the double-precision reciprocal square root approximation instructions;
-
-So, for example, @option{-mrecip=all,!rsqrtd} enables
-all of the reciprocal estimate instructions, except for the
-@code{FRSQRTE}, @code{XSRSQRTEDP}, and @code{XVRSQRTEDP} instructions
-which handle the double-precision reciprocal square root calculations.
-
-@item -mrecip-precision
-@itemx -mno-recip-precision
-@opindex mrecip-precision
-Assume (do not assume) that the reciprocal estimate instructions
-provide higher-precision estimates than is mandated by the PowerPC
-ABI. Selecting @option{-mcpu=power6}, @option{-mcpu=power7} or
-@option{-mcpu=power8} automatically selects @option{-mrecip-precision}.
-The double-precision square root estimate instructions are not generated by
-default on low-precision machines, since they do not provide an
-estimate that converges after three steps.
-
-@item -mveclibabi=@var{type}
-@opindex mveclibabi
-Specifies the ABI type to use for vectorizing intrinsics using an
-external library. The only type supported at present is @code{mass},
-which specifies to use IBM's Mathematical Acceleration Subsystem
-(MASS) libraries for vectorizing intrinsics using external libraries.
-GCC currently emits calls to @code{acosd2}, @code{acosf4},
-@code{acoshd2}, @code{acoshf4}, @code{asind2}, @code{asinf4},
-@code{asinhd2}, @code{asinhf4}, @code{atan2d2}, @code{atan2f4},
-@code{atand2}, @code{atanf4}, @code{atanhd2}, @code{atanhf4},
-@code{cbrtd2}, @code{cbrtf4}, @code{cosd2}, @code{cosf4},
-@code{coshd2}, @code{coshf4}, @code{erfcd2}, @code{erfcf4},
-@code{erfd2}, @code{erff4}, @code{exp2d2}, @code{exp2f4},
-@code{expd2}, @code{expf4}, @code{expm1d2}, @code{expm1f4},
-@code{hypotd2}, @code{hypotf4}, @code{lgammad2}, @code{lgammaf4},
-@code{log10d2}, @code{log10f4}, @code{log1pd2}, @code{log1pf4},
-@code{log2d2}, @code{log2f4}, @code{logd2}, @code{logf4},
-@code{powd2}, @code{powf4}, @code{sind2}, @code{sinf4}, @code{sinhd2},
-@code{sinhf4}, @code{sqrtd2}, @code{sqrtf4}, @code{tand2},
-@code{tanf4}, @code{tanhd2}, and @code{tanhf4} when generating code
-for power7. Both @option{-ftree-vectorize} and
-@option{-funsafe-math-optimizations} must also be enabled. The MASS
-libraries must be specified at link time.
-
-@item -mfriz
-@itemx -mno-friz
-@opindex mfriz
-Generate (do not generate) the @code{friz} instruction when the
-@option{-funsafe-math-optimizations} option is used to optimize
-rounding of floating-point values to 64-bit integer and back to floating
-point. The @code{friz} instruction does not return the same value if
-the floating-point number is too large to fit in an integer.
-
-@item -mpointers-to-nested-functions
-@itemx -mno-pointers-to-nested-functions
-@opindex mpointers-to-nested-functions
-Generate (do not generate) code to load up the static chain register
-(@var{r11}) when calling through a pointer on AIX and 64-bit Linux
-systems where a function pointer points to a 3-word descriptor giving
-the function address, TOC value to be loaded in register @var{r2}, and
-static chain value to be loaded in register @var{r11}. The
-@option{-mpointers-to-nested-functions} is on by default. You cannot
-call through pointers to nested functions or pointers
-to functions compiled in other languages that use the static chain if
-you use the @option{-mno-pointers-to-nested-functions}.
-
-@item -msave-toc-indirect
-@itemx -mno-save-toc-indirect
-@opindex msave-toc-indirect
-Generate (do not generate) code to save the TOC value in the reserved
-stack location in the function prologue if the function calls through
-a pointer on AIX and 64-bit Linux systems. If the TOC value is not
-saved in the prologue, it is saved just before the call through the
-pointer. The @option{-mno-save-toc-indirect} option is the default.
-@end table
-
-@node RX Options
-@subsection RX Options
-@cindex RX Options
-
-These command-line options are defined for RX targets:
-
-@table @gcctabopt
-@item -m64bit-doubles
-@itemx -m32bit-doubles
-@opindex m64bit-doubles
-@opindex m32bit-doubles
-Make the @code{double} data type be 64 bits (@option{-m64bit-doubles})
-or 32 bits (@option{-m32bit-doubles}) in size. The default is
-@option{-m32bit-doubles}. @emph{Note} RX floating-point hardware only
-works on 32-bit values, which is why the default is
-@option{-m32bit-doubles}.
-
-@item -fpu
-@itemx -nofpu
-@opindex fpu
-@opindex nofpu
-Enables (@option{-fpu}) or disables (@option{-nofpu}) the use of RX
-floating-point hardware. The default is enabled for the @var{RX600}
-series and disabled for the @var{RX200} series.
-
-Floating-point instructions are only generated for 32-bit floating-point
-values, however, so the FPU hardware is not used for doubles if the
-@option{-m64bit-doubles} option is used.
-
-@emph{Note} If the @option{-fpu} option is enabled then
-@option{-funsafe-math-optimizations} is also enabled automatically.
-This is because the RX FPU instructions are themselves unsafe.
-
-@item -mcpu=@var{name}
-@opindex -mcpu
-Selects the type of RX CPU to be targeted. Currently three types are
-supported, the generic @var{RX600} and @var{RX200} series hardware and
-the specific @var{RX610} CPU. The default is @var{RX600}.
-
-The only difference between @var{RX600} and @var{RX610} is that the
-@var{RX610} does not support the @code{MVTIPL} instruction.
-
-The @var{RX200} series does not have a hardware floating-point unit
-and so @option{-nofpu} is enabled by default when this type is
-selected.
-
-@item -mbig-endian-data
-@itemx -mlittle-endian-data
-@opindex mbig-endian-data
-@opindex mlittle-endian-data
-Store data (but not code) in the big-endian format. The default is
-@option{-mlittle-endian-data}, i.e.@: to store data in the little-endian
-format.
-
-@item -msmall-data-limit=@var{N}
-@opindex msmall-data-limit
-Specifies the maximum size in bytes of global and static variables
-which can be placed into the small data area. Using the small data
-area can lead to smaller and faster code, but the size of area is
-limited and it is up to the programmer to ensure that the area does
-not overflow. Also when the small data area is used one of the RX's
-registers (usually @code{r13}) is reserved for use pointing to this
-area, so it is no longer available for use by the compiler. This
-could result in slower and/or larger code if variables are pushed onto
-the stack instead of being held in this register.
-
-Note, common variables (variables that have not been initialized) and
-constants are not placed into the small data area as they are assigned
-to other sections in the output executable.
-
-The default value is zero, which disables this feature. Note, this
-feature is not enabled by default with higher optimization levels
-(@option{-O2} etc) because of the potentially detrimental effects of
-reserving a register. It is up to the programmer to experiment and
-discover whether this feature is of benefit to their program. See the
-description of the @option{-mpid} option for a description of how the
-actual register to hold the small data area pointer is chosen.
-
-@item -msim
-@itemx -mno-sim
-@opindex msim
-@opindex mno-sim
-Use the simulator runtime. The default is to use the libgloss
-board-specific runtime.
-
-@item -mas100-syntax
-@itemx -mno-as100-syntax
-@opindex mas100-syntax
-@opindex mno-as100-syntax
-When generating assembler output use a syntax that is compatible with
-Renesas's AS100 assembler. This syntax can also be handled by the GAS
-assembler, but it has some restrictions so it is not generated by default.
-
-@item -mmax-constant-size=@var{N}
-@opindex mmax-constant-size
-Specifies the maximum size, in bytes, of a constant that can be used as
-an operand in a RX instruction. Although the RX instruction set does
-allow constants of up to 4 bytes in length to be used in instructions,
-a longer value equates to a longer instruction. Thus in some
-circumstances it can be beneficial to restrict the size of constants
-that are used in instructions. Constants that are too big are instead
-placed into a constant pool and referenced via register indirection.
-
-The value @var{N} can be between 0 and 4. A value of 0 (the default)
-or 4 means that constants of any size are allowed.
-
-@item -mrelax
-@opindex mrelax
-Enable linker relaxation. Linker relaxation is a process whereby the
-linker attempts to reduce the size of a program by finding shorter
-versions of various instructions. Disabled by default.
-
-@item -mint-register=@var{N}
-@opindex mint-register
-Specify the number of registers to reserve for fast interrupt handler
-functions. The value @var{N} can be between 0 and 4. A value of 1
-means that register @code{r13} is reserved for the exclusive use
-of fast interrupt handlers. A value of 2 reserves @code{r13} and
-@code{r12}. A value of 3 reserves @code{r13}, @code{r12} and
-@code{r11}, and a value of 4 reserves @code{r13} through @code{r10}.
-A value of 0, the default, does not reserve any registers.
-
-@item -msave-acc-in-interrupts
-@opindex msave-acc-in-interrupts
-Specifies that interrupt handler functions should preserve the
-accumulator register. This is only necessary if normal code might use
-the accumulator register, for example because it performs 64-bit
-multiplications. The default is to ignore the accumulator as this
-makes the interrupt handlers faster.
-
-@item -mpid
-@itemx -mno-pid
-@opindex mpid
-@opindex mno-pid
-Enables the generation of position independent data. When enabled any
-access to constant data is done via an offset from a base address
-held in a register. This allows the location of constant data to be
-determined at run time without requiring the executable to be
-relocated, which is a benefit to embedded applications with tight
-memory constraints. Data that can be modified is not affected by this
-option.
-
-Note, using this feature reserves a register, usually @code{r13}, for
-the constant data base address. This can result in slower and/or
-larger code, especially in complicated functions.
-
-The actual register chosen to hold the constant data base address
-depends upon whether the @option{-msmall-data-limit} and/or the
-@option{-mint-register} command-line options are enabled. Starting
-with register @code{r13} and proceeding downwards, registers are
-allocated first to satisfy the requirements of @option{-mint-register},
-then @option{-mpid} and finally @option{-msmall-data-limit}. Thus it
-is possible for the small data area register to be @code{r8} if both
-@option{-mint-register=4} and @option{-mpid} are specified on the
-command line.
-
-By default this feature is not enabled. The default can be restored
-via the @option{-mno-pid} command-line option.
-
-@item -mno-warn-multiple-fast-interrupts
-@itemx -mwarn-multiple-fast-interrupts
-@opindex mno-warn-multiple-fast-interrupts
-@opindex mwarn-multiple-fast-interrupts
-Prevents GCC from issuing a warning message if it finds more than one
-fast interrupt handler when it is compiling a file. The default is to
-issue a warning for each extra fast interrupt handler found, as the RX
-only supports one such interrupt.
-
-@end table
-
-@emph{Note:} The generic GCC command-line option @option{-ffixed-@var{reg}}
-has special significance to the RX port when used with the
-@code{interrupt} function attribute. This attribute indicates a
-function intended to process fast interrupts. GCC ensures
-that it only uses the registers @code{r10}, @code{r11}, @code{r12}
-and/or @code{r13} and only provided that the normal use of the
-corresponding registers have been restricted via the
-@option{-ffixed-@var{reg}} or @option{-mint-register} command-line
-options.
-
-@node S/390 and zSeries Options
-@subsection S/390 and zSeries Options
-@cindex S/390 and zSeries Options
-
-These are the @samp{-m} options defined for the S/390 and zSeries architecture.
-
-@table @gcctabopt
-@item -mhard-float
-@itemx -msoft-float
-@opindex mhard-float
-@opindex msoft-float
-Use (do not use) the hardware floating-point instructions and registers
-for floating-point operations. When @option{-msoft-float} is specified,
-functions in @file{libgcc.a} are used to perform floating-point
-operations. When @option{-mhard-float} is specified, the compiler
-generates IEEE floating-point instructions. This is the default.
-
-@item -mhard-dfp
-@itemx -mno-hard-dfp
-@opindex mhard-dfp
-@opindex mno-hard-dfp
-Use (do not use) the hardware decimal-floating-point instructions for
-decimal-floating-point operations. When @option{-mno-hard-dfp} is
-specified, functions in @file{libgcc.a} are used to perform
-decimal-floating-point operations. When @option{-mhard-dfp} is
-specified, the compiler generates decimal-floating-point hardware
-instructions. This is the default for @option{-march=z9-ec} or higher.
-
-@item -mlong-double-64
-@itemx -mlong-double-128
-@opindex mlong-double-64
-@opindex mlong-double-128
-These switches control the size of @code{long double} type. A size
-of 64 bits makes the @code{long double} type equivalent to the @code{double}
-type. This is the default.
-
-@item -mbackchain
-@itemx -mno-backchain
-@opindex mbackchain
-@opindex mno-backchain
-Store (do not store) the address of the caller's frame as backchain pointer
-into the callee's stack frame.
-A backchain may be needed to allow debugging using tools that do not understand
-DWARF 2 call frame information.
-When @option{-mno-packed-stack} is in effect, the backchain pointer is stored
-at the bottom of the stack frame; when @option{-mpacked-stack} is in effect,
-the backchain is placed into the topmost word of the 96/160 byte register
-save area.
-
-In general, code compiled with @option{-mbackchain} is call-compatible with
-code compiled with @option{-mmo-backchain}; however, use of the backchain
-for debugging purposes usually requires that the whole binary is built with
-@option{-mbackchain}. Note that the combination of @option{-mbackchain},
-@option{-mpacked-stack} and @option{-mhard-float} is not supported. In order
-to build a linux kernel use @option{-msoft-float}.
-
-The default is to not maintain the backchain.
-
-@item -mpacked-stack
-@itemx -mno-packed-stack
-@opindex mpacked-stack
-@opindex mno-packed-stack
-Use (do not use) the packed stack layout. When @option{-mno-packed-stack} is
-specified, the compiler uses the all fields of the 96/160 byte register save
-area only for their default purpose; unused fields still take up stack space.
-When @option{-mpacked-stack} is specified, register save slots are densely
-packed at the top of the register save area; unused space is reused for other
-purposes, allowing for more efficient use of the available stack space.
-However, when @option{-mbackchain} is also in effect, the topmost word of
-the save area is always used to store the backchain, and the return address
-register is always saved two words below the backchain.
-
-As long as the stack frame backchain is not used, code generated with
-@option{-mpacked-stack} is call-compatible with code generated with
-@option{-mno-packed-stack}. Note that some non-FSF releases of GCC 2.95 for
-S/390 or zSeries generated code that uses the stack frame backchain at run
-time, not just for debugging purposes. Such code is not call-compatible
-with code compiled with @option{-mpacked-stack}. Also, note that the
-combination of @option{-mbackchain},
-@option{-mpacked-stack} and @option{-mhard-float} is not supported. In order
-to build a linux kernel use @option{-msoft-float}.
-
-The default is to not use the packed stack layout.
-
-@item -msmall-exec
-@itemx -mno-small-exec
-@opindex msmall-exec
-@opindex mno-small-exec
-Generate (or do not generate) code using the @code{bras} instruction
-to do subroutine calls.
-This only works reliably if the total executable size does not
-exceed 64k. The default is to use the @code{basr} instruction instead,
-which does not have this limitation.
-
-@item -m64
-@itemx -m31
-@opindex m64
-@opindex m31
-When @option{-m31} is specified, generate code compliant to the
-GNU/Linux for S/390 ABI@. When @option{-m64} is specified, generate
-code compliant to the GNU/Linux for zSeries ABI@. This allows GCC in
-particular to generate 64-bit instructions. For the @samp{s390}
-targets, the default is @option{-m31}, while the @samp{s390x}
-targets default to @option{-m64}.
-
-@item -mzarch
-@itemx -mesa
-@opindex mzarch
-@opindex mesa
-When @option{-mzarch} is specified, generate code using the
-instructions available on z/Architecture.
-When @option{-mesa} is specified, generate code using the
-instructions available on ESA/390. Note that @option{-mesa} is
-not possible with @option{-m64}.
-When generating code compliant to the GNU/Linux for S/390 ABI,
-the default is @option{-mesa}. When generating code compliant
-to the GNU/Linux for zSeries ABI, the default is @option{-mzarch}.
-
-@item -mmvcle
-@itemx -mno-mvcle
-@opindex mmvcle
-@opindex mno-mvcle
-Generate (or do not generate) code using the @code{mvcle} instruction
-to perform block moves. When @option{-mno-mvcle} is specified,
-use a @code{mvc} loop instead. This is the default unless optimizing for
-size.
-
-@item -mdebug
-@itemx -mno-debug
-@opindex mdebug
-@opindex mno-debug
-Print (or do not print) additional debug information when compiling.
-The default is to not print debug information.
-
-@item -march=@var{cpu-type}
-@opindex march
-Generate code that runs on @var{cpu-type}, which is the name of a system
-representing a certain processor type. Possible values for
-@var{cpu-type} are @samp{g5}, @samp{g6}, @samp{z900}, @samp{z990},
-@samp{z9-109}, @samp{z9-ec} and @samp{z10}.
-When generating code using the instructions available on z/Architecture,
-the default is @option{-march=z900}. Otherwise, the default is
-@option{-march=g5}.
-
-@item -mtune=@var{cpu-type}
-@opindex mtune
-Tune to @var{cpu-type} everything applicable about the generated code,
-except for the ABI and the set of available instructions.
-The list of @var{cpu-type} values is the same as for @option{-march}.
-The default is the value used for @option{-march}.
-
-@item -mtpf-trace
-@itemx -mno-tpf-trace
-@opindex mtpf-trace
-@opindex mno-tpf-trace
-Generate code that adds (does not add) in TPF OS specific branches to trace
-routines in the operating system. This option is off by default, even
-when compiling for the TPF OS@.
-
-@item -mfused-madd
-@itemx -mno-fused-madd
-@opindex mfused-madd
-@opindex mno-fused-madd
-Generate code that uses (does not use) the floating-point multiply and
-accumulate instructions. These instructions are generated by default if
-hardware floating point is used.
-
-@item -mwarn-framesize=@var{framesize}
-@opindex mwarn-framesize
-Emit a warning if the current function exceeds the given frame size. Because
-this is a compile-time check it doesn't need to be a real problem when the program
-runs. It is intended to identify functions that most probably cause
-a stack overflow. It is useful to be used in an environment with limited stack
-size e.g.@: the linux kernel.
-
-@item -mwarn-dynamicstack
-@opindex mwarn-dynamicstack
-Emit a warning if the function calls @code{alloca} or uses dynamically-sized
-arrays. This is generally a bad idea with a limited stack size.
-
-@item -mstack-guard=@var{stack-guard}
-@itemx -mstack-size=@var{stack-size}
-@opindex mstack-guard
-@opindex mstack-size
-If these options are provided the S/390 back end emits additional instructions in
-the function prologue that trigger a trap if the stack size is @var{stack-guard}
-bytes above the @var{stack-size} (remember that the stack on S/390 grows downward).
-If the @var{stack-guard} option is omitted the smallest power of 2 larger than
-the frame size of the compiled function is chosen.
-These options are intended to be used to help debugging stack overflow problems.
-The additionally emitted code causes only little overhead and hence can also be
-used in production-like systems without greater performance degradation. The given
-values have to be exact powers of 2 and @var{stack-size} has to be greater than
-@var{stack-guard} without exceeding 64k.
-In order to be efficient the extra code makes the assumption that the stack starts
-at an address aligned to the value given by @var{stack-size}.
-The @var{stack-guard} option can only be used in conjunction with @var{stack-size}.
-@end table
-
-@node Score Options
-@subsection Score Options
-@cindex Score Options
-
-These options are defined for Score implementations:
-
-@table @gcctabopt
-@item -meb
-@opindex meb
-Compile code for big-endian mode. This is the default.
-
-@item -mel
-@opindex mel
-Compile code for little-endian mode.
-
-@item -mnhwloop
-@opindex mnhwloop
-Disable generation of @code{bcnz} instructions.
-
-@item -muls
-@opindex muls
-Enable generation of unaligned load and store instructions.
-
-@item -mmac
-@opindex mmac
-Enable the use of multiply-accumulate instructions. Disabled by default.
-
-@item -mscore5
-@opindex mscore5
-Specify the SCORE5 as the target architecture.
-
-@item -mscore5u
-@opindex mscore5u
-Specify the SCORE5U of the target architecture.
-
-@item -mscore7
-@opindex mscore7
-Specify the SCORE7 as the target architecture. This is the default.
-
-@item -mscore7d
-@opindex mscore7d
-Specify the SCORE7D as the target architecture.
-@end table
-
-@node SH Options
-@subsection SH Options
-
-These @samp{-m} options are defined for the SH implementations:
-
-@table @gcctabopt
-@item -m1
-@opindex m1
-Generate code for the SH1.
-
-@item -m2
-@opindex m2
-Generate code for the SH2.
-
-@item -m2e
-Generate code for the SH2e.
-
-@item -m2a-nofpu
-@opindex m2a-nofpu
-Generate code for the SH2a without FPU, or for a SH2a-FPU in such a way
-that the floating-point unit is not used.
-
-@item -m2a-single-only
-@opindex m2a-single-only
-Generate code for the SH2a-FPU, in such a way that no double-precision
-floating-point operations are used.
-
-@item -m2a-single
-@opindex m2a-single
-Generate code for the SH2a-FPU assuming the floating-point unit is in
-single-precision mode by default.
-
-@item -m2a
-@opindex m2a
-Generate code for the SH2a-FPU assuming the floating-point unit is in
-double-precision mode by default.
-
-@item -m3
-@opindex m3
-Generate code for the SH3.
-
-@item -m3e
-@opindex m3e
-Generate code for the SH3e.
-
-@item -m4-nofpu
-@opindex m4-nofpu
-Generate code for the SH4 without a floating-point unit.
-
-@item -m4-single-only
-@opindex m4-single-only
-Generate code for the SH4 with a floating-point unit that only
-supports single-precision arithmetic.
-
-@item -m4-single
-@opindex m4-single
-Generate code for the SH4 assuming the floating-point unit is in
-single-precision mode by default.
-
-@item -m4
-@opindex m4
-Generate code for the SH4.
-
-@item -m4a-nofpu
-@opindex m4a-nofpu
-Generate code for the SH4al-dsp, or for a SH4a in such a way that the
-floating-point unit is not used.
-
-@item -m4a-single-only
-@opindex m4a-single-only
-Generate code for the SH4a, in such a way that no double-precision
-floating-point operations are used.
-
-@item -m4a-single
-@opindex m4a-single
-Generate code for the SH4a assuming the floating-point unit is in
-single-precision mode by default.
-
-@item -m4a
-@opindex m4a
-Generate code for the SH4a.
-
-@item -m4al
-@opindex m4al
-Same as @option{-m4a-nofpu}, except that it implicitly passes
-@option{-dsp} to the assembler. GCC doesn't generate any DSP
-instructions at the moment.
-
-@item -mb
-@opindex mb
-Compile code for the processor in big-endian mode.
-
-@item -ml
-@opindex ml
-Compile code for the processor in little-endian mode.
-
-@item -mdalign
-@opindex mdalign
-Align doubles at 64-bit boundaries. Note that this changes the calling
-conventions, and thus some functions from the standard C library do
-not work unless you recompile it first with @option{-mdalign}.
-
-@item -mrelax
-@opindex mrelax
-Shorten some address references at link time, when possible; uses the
-linker option @option{-relax}.
-
-@item -mbigtable
-@opindex mbigtable
-Use 32-bit offsets in @code{switch} tables. The default is to use
-16-bit offsets.
-
-@item -mbitops
-@opindex mbitops
-Enable the use of bit manipulation instructions on SH2A.
-
-@item -mfmovd
-@opindex mfmovd
-Enable the use of the instruction @code{fmovd}. Check @option{-mdalign} for
-alignment constraints.
-
-@item -mhitachi
-@opindex mhitachi
-Comply with the calling conventions defined by Renesas.
-
-@item -mrenesas
-@opindex mhitachi
-Comply with the calling conventions defined by Renesas.
-
-@item -mno-renesas
-@opindex mhitachi
-Comply with the calling conventions defined for GCC before the Renesas
-conventions were available. This option is the default for all
-targets of the SH toolchain.
-
-@item -mnomacsave
-@opindex mnomacsave
-Mark the @code{MAC} register as call-clobbered, even if
-@option{-mhitachi} is given.
-
-@item -mieee
-@itemx -mno-ieee
-@opindex mieee
-@opindex mnoieee
-Control the IEEE compliance of floating-point comparisons, which affects the
-handling of cases where the result of a comparison is unordered. By default
-@option{-mieee} is implicitly enabled. If @option{-ffinite-math-only} is
-enabled @option{-mno-ieee} is implicitly set, which results in faster
-floating-point greater-equal and less-equal comparisons. The implcit settings
-can be overridden by specifying either @option{-mieee} or @option{-mno-ieee}.
-
-@item -minline-ic_invalidate
-@opindex minline-ic_invalidate
-Inline code to invalidate instruction cache entries after setting up
-nested function trampolines.
-This option has no effect if @option{-musermode} is in effect and the selected
-code generation option (e.g. @option{-m4}) does not allow the use of the @code{icbi}
-instruction.
-If the selected code generation option does not allow the use of the @code{icbi}
-instruction, and @option{-musermode} is not in effect, the inlined code
-manipulates the instruction cache address array directly with an associative
-write. This not only requires privileged mode at run time, but it also
-fails if the cache line had been mapped via the TLB and has become unmapped.
-
-@item -misize
-@opindex misize
-Dump instruction size and location in the assembly code.
-
-@item -mpadstruct
-@opindex mpadstruct
-This option is deprecated. It pads structures to multiple of 4 bytes,
-which is incompatible with the SH ABI@.
-
-@item -matomic-model=@var{model}
-@opindex matomic-model=@var{model}
-Sets the model of atomic operations and additional parameters as a comma
-separated list. For details on the atomic built-in functions see
-@ref{__atomic Builtins}. The following models and parameters are supported:
-
-@table @samp
-
-@item none
-Disable compiler generated atomic sequences and emit library calls for atomic
-operations. This is the default if the target is not @code{sh-*-linux*}.
-
-@item soft-gusa
-Generate GNU/Linux compatible gUSA software atomic sequences for the atomic
-built-in functions. The generated atomic sequences require additional support
-from the interrupt/exception handling code of the system and are only suitable
-for SH3* and SH4* single-core systems. This option is enabled by default when
-the target is @code{sh-*-linux*} and SH3* or SH4*. When the target is SH4A,
-this option will also partially utilize the hardware atomic instructions
-@code{movli.l} and @code{movco.l} to create more efficient code, unless
-@samp{strict} is specified.
-
-@item soft-tcb
-Generate software atomic sequences that use a variable in the thread control
-block. This is a variation of the gUSA sequences which can also be used on
-SH1* and SH2* targets. The generated atomic sequences require additional
-support from the interrupt/exception handling code of the system and are only
-suitable for single-core systems. When using this model, the @samp{gbr-offset=}
-parameter has to be specified as well.
-
-@item soft-imask
-Generate software atomic sequences that temporarily disable interrupts by
-setting @code{SR.IMASK = 1111}. This model works only when the program runs
-in privileged mode and is only suitable for single-core systems. Additional
-support from the interrupt/exception handling code of the system is not
-required. This model is enabled by default when the target is
-@code{sh-*-linux*} and SH1* or SH2*.
-
-@item hard-llcs
-Generate hardware atomic sequences using the @code{movli.l} and @code{movco.l}
-instructions only. This is only available on SH4A and is suitable for
-multi-core systems. Since the hardware instructions support only 32 bit atomic
-variables access to 8 or 16 bit variables is emulated with 32 bit accesses.
-Code compiled with this option will also be compatible with other software
-atomic model interrupt/exception handling systems if executed on an SH4A
-system. Additional support from the interrupt/exception handling code of the
-system is not required for this model.
-
-@item gbr-offset=
-This parameter specifies the offset in bytes of the variable in the thread
-control block structure that should be used by the generated atomic sequences
-when the @samp{soft-tcb} model has been selected. For other models this
-parameter is ignored. The specified value must be an integer multiple of four
-and in the range 0-1020.
-
-@item strict
-This parameter prevents mixed usage of multiple atomic models, even though they
-would be compatible, and will make the compiler generate atomic sequences of the
-specified model only.
-
-@end table
-
-@item -mtas
-@opindex mtas
-Generate the @code{tas.b} opcode for @code{__atomic_test_and_set}.
-Notice that depending on the particular hardware and software configuration
-this can degrade overall performance due to the operand cache line flushes
-that are implied by the @code{tas.b} instruction. On multi-core SH4A
-processors the @code{tas.b} instruction must be used with caution since it
-can result in data corruption for certain cache configurations.
-
-@item -mspace
-@opindex mspace
-Optimize for space instead of speed. Implied by @option{-Os}.
-
-@item -mprefergot
-@opindex mprefergot
-When generating position-independent code, emit function calls using
-the Global Offset Table instead of the Procedure Linkage Table.
-
-@item -musermode
-@opindex musermode
-Don't generate privileged mode only code. This option
-implies @option{-mno-inline-ic_invalidate}
-if the inlined code would not work in user mode.
-This is the default when the target is @code{sh-*-linux*}.
-
-@item -multcost=@var{number}
-@opindex multcost=@var{number}
-Set the cost to assume for a multiply insn.
-
-@item -mdiv=@var{strategy}
-@opindex mdiv=@var{strategy}
-Set the division strategy to be used for integer division operations.
-For SHmedia @var{strategy} can be one of:
-
-@table @samp
-
-@item fp
-Performs the operation in floating point. This has a very high latency,
-but needs only a few instructions, so it might be a good choice if
-your code has enough easily-exploitable ILP to allow the compiler to
-schedule the floating-point instructions together with other instructions.
-Division by zero causes a floating-point exception.
-
-@item inv
-Uses integer operations to calculate the inverse of the divisor,
-and then multiplies the dividend with the inverse. This strategy allows
-CSE and hoisting of the inverse calculation. Division by zero calculates
-an unspecified result, but does not trap.
-
-@item inv:minlat
-A variant of @samp{inv} where, if no CSE or hoisting opportunities
-have been found, or if the entire operation has been hoisted to the same
-place, the last stages of the inverse calculation are intertwined with the
-final multiply to reduce the overall latency, at the expense of using a few
-more instructions, and thus offering fewer scheduling opportunities with
-other code.
-
-@item call
-Calls a library function that usually implements the @samp{inv:minlat}
-strategy.
-This gives high code density for @code{m5-*media-nofpu} compilations.
-
-@item call2
-Uses a different entry point of the same library function, where it
-assumes that a pointer to a lookup table has already been set up, which
-exposes the pointer load to CSE and code hoisting optimizations.
-
-@item inv:call
-@itemx inv:call2
-@itemx inv:fp
-Use the @samp{inv} algorithm for initial
-code generation, but if the code stays unoptimized, revert to the @samp{call},
-@samp{call2}, or @samp{fp} strategies, respectively. Note that the
-potentially-trapping side effect of division by zero is carried by a
-separate instruction, so it is possible that all the integer instructions
-are hoisted out, but the marker for the side effect stays where it is.
-A recombination to floating-point operations or a call is not possible
-in that case.
-
-@item inv20u
-@itemx inv20l
-Variants of the @samp{inv:minlat} strategy. In the case
-that the inverse calculation is not separated from the multiply, they speed
-up division where the dividend fits into 20 bits (plus sign where applicable)
-by inserting a test to skip a number of operations in this case; this test
-slows down the case of larger dividends. @samp{inv20u} assumes the case of a such
-a small dividend to be unlikely, and @samp{inv20l} assumes it to be likely.
-
-@end table
-
-For targets other than SHmedia @var{strategy} can be one of:
-
-@table @samp
-
-@item call-div1
-Calls a library function that uses the single-step division instruction
-@code{div1} to perform the operation. Division by zero calculates an
-unspecified result and does not trap. This is the default except for SH4,
-SH2A and SHcompact.
-
-@item call-fp
-Calls a library function that performs the operation in double precision
-floating point. Division by zero causes a floating-point exception. This is
-the default for SHcompact with FPU. Specifying this for targets that do not
-have a double precision FPU will default to @code{call-div1}.
-
-@item call-table
-Calls a library function that uses a lookup table for small divisors and
-the @code{div1} instruction with case distinction for larger divisors. Division
-by zero calculates an unspecified result and does not trap. This is the default
-for SH4. Specifying this for targets that do not have dynamic shift
-instructions will default to @code{call-div1}.
-
-@end table
-
-When a division strategy has not been specified the default strategy will be
-selected based on the current target. For SH2A the default strategy is to
-use the @code{divs} and @code{divu} instructions instead of library function
-calls.
-
-@item -maccumulate-outgoing-args
-@opindex maccumulate-outgoing-args
-Reserve space once for outgoing arguments in the function prologue rather
-than around each call. Generally beneficial for performance and size. Also
-needed for unwinding to avoid changing the stack frame around conditional code.
-
-@item -mdivsi3_libfunc=@var{name}
-@opindex mdivsi3_libfunc=@var{name}
-Set the name of the library function used for 32-bit signed division to
-@var{name}.
-This only affects the name used in the @samp{call} and @samp{inv:call}
-division strategies, and the compiler still expects the same
-sets of input/output/clobbered registers as if this option were not present.
-
-@item -mfixed-range=@var{register-range}
-@opindex mfixed-range
-Generate code treating the given register range as fixed registers.
-A fixed register is one that the register allocator can not use. This is
-useful when compiling kernel code. A register range is specified as
-two registers separated by a dash. Multiple register ranges can be
-specified separated by a comma.
-
-@item -mindexed-addressing
-@opindex mindexed-addressing
-Enable the use of the indexed addressing mode for SHmedia32/SHcompact.
-This is only safe if the hardware and/or OS implement 32-bit wrap-around
-semantics for the indexed addressing mode. The architecture allows the
-implementation of processors with 64-bit MMU, which the OS could use to
-get 32-bit addressing, but since no current hardware implementation supports
-this or any other way to make the indexed addressing mode safe to use in
-the 32-bit ABI, the default is @option{-mno-indexed-addressing}.
-
-@item -mgettrcost=@var{number}
-@opindex mgettrcost=@var{number}
-Set the cost assumed for the @code{gettr} instruction to @var{number}.
-The default is 2 if @option{-mpt-fixed} is in effect, 100 otherwise.
-
-@item -mpt-fixed
-@opindex mpt-fixed
-Assume @code{pt*} instructions won't trap. This generally generates
-better-scheduled code, but is unsafe on current hardware.
-The current architecture
-definition says that @code{ptabs} and @code{ptrel} trap when the target
-anded with 3 is 3.
-This has the unintentional effect of making it unsafe to schedule these
-instructions before a branch, or hoist them out of a loop. For example,
-@code{__do_global_ctors}, a part of @file{libgcc}
-that runs constructors at program
-startup, calls functions in a list which is delimited by @minus{}1. With the
-@option{-mpt-fixed} option, the @code{ptabs} is done before testing against @minus{}1.
-That means that all the constructors run a bit more quickly, but when
-the loop comes to the end of the list, the program crashes because @code{ptabs}
-loads @minus{}1 into a target register.
-
-Since this option is unsafe for any
-hardware implementing the current architecture specification, the default
-is @option{-mno-pt-fixed}. Unless specified explicitly with
-@option{-mgettrcost}, @option{-mno-pt-fixed} also implies @option{-mgettrcost=100};
-this deters register allocation from using target registers for storing
-ordinary integers.
-
-@item -minvalid-symbols
-@opindex minvalid-symbols
-Assume symbols might be invalid. Ordinary function symbols generated by
-the compiler are always valid to load with
-@code{movi}/@code{shori}/@code{ptabs} or
-@code{movi}/@code{shori}/@code{ptrel},
-but with assembler and/or linker tricks it is possible
-to generate symbols that cause @code{ptabs} or @code{ptrel} to trap.
-This option is only meaningful when @option{-mno-pt-fixed} is in effect.
-It prevents cross-basic-block CSE, hoisting and most scheduling
-of symbol loads. The default is @option{-mno-invalid-symbols}.
-
-@item -mbranch-cost=@var{num}
-@opindex mbranch-cost=@var{num}
-Assume @var{num} to be the cost for a branch instruction. Higher numbers
-make the compiler try to generate more branch-free code if possible.
-If not specified the value is selected depending on the processor type that
-is being compiled for.
-
-@item -mzdcbranch
-@itemx -mno-zdcbranch
-@opindex mzdcbranch
-@opindex mno-zdcbranch
-Assume (do not assume) that zero displacement conditional branch instructions
-@code{bt} and @code{bf} are fast. If @option{-mzdcbranch} is specified, the
-compiler will try to prefer zero displacement branch code sequences. This is
-enabled by default when generating code for SH4 and SH4A. It can be explicitly
-disabled by specifying @option{-mno-zdcbranch}.
-
-@item -mcbranchdi
-@opindex mcbranchdi
-Enable the @code{cbranchdi4} instruction pattern.
-
-@item -mcmpeqdi
-@opindex mcmpeqdi
-Emit the @code{cmpeqdi_t} instruction pattern even when @option{-mcbranchdi}
-is in effect.
-
-@item -mfused-madd
-@itemx -mno-fused-madd
-@opindex mfused-madd
-@opindex mno-fused-madd
-Generate code that uses (does not use) the floating-point multiply and
-accumulate instructions. These instructions are generated by default
-if hardware floating point is used. The machine-dependent
-@option{-mfused-madd} option is now mapped to the machine-independent
-@option{-ffp-contract=fast} option, and @option{-mno-fused-madd} is
-mapped to @option{-ffp-contract=off}.
-
-@item -mfsca
-@itemx -mno-fsca
-@opindex mfsca
-@opindex mno-fsca
-Allow or disallow the compiler to emit the @code{fsca} instruction for sine
-and cosine approximations. The option @code{-mfsca} must be used in
-combination with @code{-funsafe-math-optimizations}. It is enabled by default
-when generating code for SH4A. Using @code{-mno-fsca} disables sine and cosine
-approximations even if @code{-funsafe-math-optimizations} is in effect.
-
-@item -mfsrra
-@itemx -mno-fsrra
-@opindex mfsrra
-@opindex mno-fsrra
-Allow or disallow the compiler to emit the @code{fsrra} instruction for
-reciprocal square root approximations. The option @code{-mfsrra} must be used
-in combination with @code{-funsafe-math-optimizations} and
-@code{-ffinite-math-only}. It is enabled by default when generating code for
-SH4A. Using @code{-mno-fsrra} disables reciprocal square root approximations
-even if @code{-funsafe-math-optimizations} and @code{-ffinite-math-only} are
-in effect.
-
-@item -mpretend-cmove
-@opindex mpretend-cmove
-Prefer zero-displacement conditional branches for conditional move instruction
-patterns. This can result in faster code on the SH4 processor.
-
-@end table
-
-@node Solaris 2 Options
-@subsection Solaris 2 Options
-@cindex Solaris 2 options
-
-These @samp{-m} options are supported on Solaris 2:
-
-@table @gcctabopt
-@item -mimpure-text
-@opindex mimpure-text
-@option{-mimpure-text}, used in addition to @option{-shared}, tells
-the compiler to not pass @option{-z text} to the linker when linking a
-shared object. Using this option, you can link position-dependent
-code into a shared object.
-
-@option{-mimpure-text} suppresses the ``relocations remain against
-allocatable but non-writable sections'' linker error message.
-However, the necessary relocations trigger copy-on-write, and the
-shared object is not actually shared across processes. Instead of
-using @option{-mimpure-text}, you should compile all source code with
-@option{-fpic} or @option{-fPIC}.
-
-@end table
-
-These switches are supported in addition to the above on Solaris 2:
-
-@table @gcctabopt
-@item -pthreads
-@opindex pthreads
-Add support for multithreading using the POSIX threads library. This
-option sets flags for both the preprocessor and linker. This option does
-not affect the thread safety of object code produced by the compiler or
-that of libraries supplied with it.
-
-@item -pthread
-@opindex pthread
-This is a synonym for @option{-pthreads}.
-@end table
-
-@node SPARC Options
-@subsection SPARC Options
-@cindex SPARC options
-
-These @samp{-m} options are supported on the SPARC:
-
-@table @gcctabopt
-@item -mno-app-regs
-@itemx -mapp-regs
-@opindex mno-app-regs
-@opindex mapp-regs
-Specify @option{-mapp-regs} to generate output using the global registers
-2 through 4, which the SPARC SVR4 ABI reserves for applications. This
-is the default.
-
-To be fully SVR4 ABI-compliant at the cost of some performance loss,
-specify @option{-mno-app-regs}. You should compile libraries and system
-software with this option.
-
-@item -mflat
-@itemx -mno-flat
-@opindex mflat
-@opindex mno-flat
-With @option{-mflat}, the compiler does not generate save/restore instructions
-and uses a ``flat'' or single register window model. This model is compatible
-with the regular register window model. The local registers and the input
-registers (0--5) are still treated as ``call-saved'' registers and are
-saved on the stack as needed.
-
-With @option{-mno-flat} (the default), the compiler generates save/restore
-instructions (except for leaf functions). This is the normal operating mode.
-
-@item -mfpu
-@itemx -mhard-float
-@opindex mfpu
-@opindex mhard-float
-Generate output containing floating-point instructions. This is the
-default.
-
-@item -mno-fpu
-@itemx -msoft-float
-@opindex mno-fpu
-@opindex msoft-float
-Generate output containing library calls for floating point.
-@strong{Warning:} the requisite libraries are not available for all SPARC
-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. The embedded targets @samp{sparc-*-aout} and
-@samp{sparclite-*-*} do provide software floating-point support.
-
-@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 -mhard-quad-float
-@opindex mhard-quad-float
-Generate output containing quad-word (long double) floating-point
-instructions.
-
-@item -msoft-quad-float
-@opindex msoft-quad-float
-Generate output containing library calls for quad-word (long double)
-floating-point instructions. The functions called are those specified
-in the SPARC ABI@. This is the default.
-
-As of this writing, there are no SPARC implementations that have hardware
-support for the quad-word floating-point instructions. They all invoke
-a trap handler for one of these instructions, and then the trap handler
-emulates the effect of the instruction. Because of the trap handler overhead,
-this is much slower than calling the ABI library routines. Thus the
-@option{-msoft-quad-float} option is the default.
-
-@item -mno-unaligned-doubles
-@itemx -munaligned-doubles
-@opindex mno-unaligned-doubles
-@opindex munaligned-doubles
-Assume that doubles have 8-byte alignment. This is the default.
-
-With @option{-munaligned-doubles}, GCC assumes that doubles have 8-byte
-alignment only if they are contained in another type, or if they have an
-absolute address. Otherwise, it assumes they have 4-byte alignment.
-Specifying this option avoids some rare compatibility problems with code
-generated by other compilers. It is not the default because it results
-in a performance loss, especially for floating-point code.
-
-@item -mno-faster-structs
-@itemx -mfaster-structs
-@opindex mno-faster-structs
-@opindex mfaster-structs
-With @option{-mfaster-structs}, the compiler assumes that structures
-should have 8-byte alignment. This enables the use of pairs of
-@code{ldd} and @code{std} instructions for copies in structure
-assignment, in place of twice as many @code{ld} and @code{st} pairs.
-However, the use of this changed alignment directly violates the SPARC
-ABI@. Thus, it's intended only for use on targets where the developer
-acknowledges that their resulting code is not directly in line with
-the rules of the ABI@.
-
-@item -mcpu=@var{cpu_type}
-@opindex mcpu
-Set the instruction set, register set, and instruction scheduling parameters
-for machine type @var{cpu_type}. Supported values for @var{cpu_type} are
-@samp{v7}, @samp{cypress}, @samp{v8}, @samp{supersparc}, @samp{hypersparc},
-@samp{leon}, @samp{sparclite}, @samp{f930}, @samp{f934}, @samp{sparclite86x},
-@samp{sparclet}, @samp{tsc701}, @samp{v9}, @samp{ultrasparc},
-@samp{ultrasparc3}, @samp{niagara}, @samp{niagara2}, @samp{niagara3},
-and @samp{niagara4}.
-
-Native Solaris and GNU/Linux toolchains also support the value @samp{native},
-which selects the best architecture option for the host processor.
-@option{-mcpu=native} has no effect if GCC does not recognize
-the processor.
-
-Default instruction scheduling parameters are used for values that select
-an architecture and not an implementation. These are @samp{v7}, @samp{v8},
-@samp{sparclite}, @samp{sparclet}, @samp{v9}.
-
-Here is a list of each supported architecture and their supported
-implementations.
-
-@table @asis
-@item v7
-cypress
-
-@item v8
-supersparc, hypersparc, leon
-
-@item sparclite
-f930, f934, sparclite86x
-
-@item sparclet
-tsc701
-
-@item v9
-ultrasparc, ultrasparc3, niagara, niagara2, niagara3, niagara4
-@end table
-
-By default (unless configured otherwise), GCC generates code for the V7
-variant of the SPARC architecture. With @option{-mcpu=cypress}, the compiler
-additionally optimizes it for the Cypress CY7C602 chip, as used in the
-SPARCStation/SPARCServer 3xx series. This is also appropriate for the older
-SPARCStation 1, 2, IPX etc.
-
-With @option{-mcpu=v8}, GCC generates code for the V8 variant of the SPARC
-architecture. The only difference from V7 code is that the compiler emits
-the integer multiply and integer divide instructions which exist in SPARC-V8
-but not in SPARC-V7. With @option{-mcpu=supersparc}, the compiler additionally
-optimizes it for the SuperSPARC chip, as used in the SPARCStation 10, 1000 and
-2000 series.
-
-With @option{-mcpu=sparclite}, GCC generates code for the SPARClite variant of
-the SPARC architecture. This adds the integer multiply, integer divide step
-and scan (@code{ffs}) instructions which exist in SPARClite but not in SPARC-V7.
-With @option{-mcpu=f930}, the compiler additionally optimizes it for the
-Fujitsu MB86930 chip, which is the original SPARClite, with no FPU@. With
-@option{-mcpu=f934}, the compiler additionally optimizes it for the Fujitsu
-MB86934 chip, which is the more recent SPARClite with FPU@.
-
-With @option{-mcpu=sparclet}, GCC generates code for the SPARClet variant of
-the SPARC architecture. This adds the integer multiply, multiply/accumulate,
-integer divide step and scan (@code{ffs}) instructions which exist in SPARClet
-but not in SPARC-V7. With @option{-mcpu=tsc701}, the compiler additionally
-optimizes it for the TEMIC SPARClet chip.
-
-With @option{-mcpu=v9}, GCC generates code for the V9 variant of the SPARC
-architecture. This adds 64-bit integer and floating-point move instructions,
-3 additional floating-point condition code registers and conditional move
-instructions. With @option{-mcpu=ultrasparc}, the compiler additionally
-optimizes it for the Sun UltraSPARC I/II/IIi chips. With
-@option{-mcpu=ultrasparc3}, the compiler additionally optimizes it for the
-Sun UltraSPARC III/III+/IIIi/IIIi+/IV/IV+ chips. With
-@option{-mcpu=niagara}, the compiler additionally optimizes it for
-Sun UltraSPARC T1 chips. With @option{-mcpu=niagara2}, the compiler
-additionally optimizes it for Sun UltraSPARC T2 chips. With
-@option{-mcpu=niagara3}, the compiler additionally optimizes it for Sun
-UltraSPARC T3 chips. With @option{-mcpu=niagara4}, the compiler
-additionally optimizes it for Sun UltraSPARC T4 chips.
-
-@item -mtune=@var{cpu_type}
-@opindex mtune
-Set the instruction scheduling parameters for machine type
-@var{cpu_type}, but do not set the instruction set or register set that the
-option @option{-mcpu=@var{cpu_type}} does.
-
-The same values for @option{-mcpu=@var{cpu_type}} can be used for
-@option{-mtune=@var{cpu_type}}, but the only useful values are those
-that select a particular CPU implementation. Those are @samp{cypress},
-@samp{supersparc}, @samp{hypersparc}, @samp{leon}, @samp{f930}, @samp{f934},
-@samp{sparclite86x}, @samp{tsc701}, @samp{ultrasparc}, @samp{ultrasparc3},
-@samp{niagara}, @samp{niagara2}, @samp{niagara3} and @samp{niagara4}. With
-native Solaris and GNU/Linux toolchains, @samp{native} can also be used.
-
-@item -mv8plus
-@itemx -mno-v8plus
-@opindex mv8plus
-@opindex mno-v8plus
-With @option{-mv8plus}, GCC generates code for the SPARC-V8+ ABI@. The
-difference from the V8 ABI is that the global and out registers are
-considered 64 bits wide. This is enabled by default on Solaris in 32-bit
-mode for all SPARC-V9 processors.
-
-@item -mvis
-@itemx -mno-vis
-@opindex mvis
-@opindex mno-vis
-With @option{-mvis}, GCC generates code that takes advantage of the UltraSPARC
-Visual Instruction Set extensions. The default is @option{-mno-vis}.
-
-@item -mvis2
-@itemx -mno-vis2
-@opindex mvis2
-@opindex mno-vis2
-With @option{-mvis2}, GCC generates code that takes advantage of
-version 2.0 of the UltraSPARC Visual Instruction Set extensions. The
-default is @option{-mvis2} when targeting a cpu that supports such
-instructions, such as UltraSPARC-III and later. Setting @option{-mvis2}
-also sets @option{-mvis}.
-
-@item -mvis3
-@itemx -mno-vis3
-@opindex mvis3
-@opindex mno-vis3
-With @option{-mvis3}, GCC generates code that takes advantage of
-version 3.0 of the UltraSPARC Visual Instruction Set extensions. The
-default is @option{-mvis3} when targeting a cpu that supports such
-instructions, such as niagara-3 and later. Setting @option{-mvis3}
-also sets @option{-mvis2} and @option{-mvis}.
-
-@item -mcbcond
-@itemx -mno-cbcond
-@opindex mcbcond
-@opindex mno-cbcond
-With @option{-mcbcond}, GCC generates code that takes advantage of
-compare-and-branch instructions, as defined in the Sparc Architecture 2011.
-The default is @option{-mcbcond} when targeting a cpu that supports such
-instructions, such as niagara-4 and later.
-
-@item -mpopc
-@itemx -mno-popc
-@opindex mpopc
-@opindex mno-popc
-With @option{-mpopc}, GCC generates code that takes advantage of the UltraSPARC
-population count instruction. The default is @option{-mpopc}
-when targeting a cpu that supports such instructions, such as Niagara-2 and
-later.
-
-@item -mfmaf
-@itemx -mno-fmaf
-@opindex mfmaf
-@opindex mno-fmaf
-With @option{-mfmaf}, GCC generates code that takes advantage of the UltraSPARC
-Fused Multiply-Add Floating-point extensions. The default is @option{-mfmaf}
-when targeting a cpu that supports such instructions, such as Niagara-3 and
-later.
-
-@item -mfix-at697f
-@opindex mfix-at697f
-Enable the documented workaround for the single erratum of the Atmel AT697F
-processor (which corresponds to erratum #13 of the AT697E processor).
-@end table
-
-These @samp{-m} options are supported in addition to the above
-on SPARC-V9 processors in 64-bit environments:
-
-@table @gcctabopt
-@item -m32
-@itemx -m64
-@opindex m32
-@opindex m64
-Generate code for a 32-bit or 64-bit environment.
-The 32-bit environment sets int, long and pointer to 32 bits.
-The 64-bit environment sets int to 32 bits and long and pointer
-to 64 bits.
-
-@item -mcmodel=@var{which}
-@opindex mcmodel
-Set the code model to one of
-
-@table @samp
-@item medlow
-The Medium/Low code model: 64-bit addresses, programs
-must be linked in the low 32 bits of memory. Programs can be statically
-or dynamically linked.
-
-@item medmid
-The Medium/Middle code model: 64-bit addresses, programs
-must be linked in the low 44 bits of memory, the text and data segments must
-be less than 2GB in size and the data segment must be located within 2GB of
-the text segment.
-
-@item medany
-The Medium/Anywhere code model: 64-bit addresses, programs
-may be linked anywhere in memory, the text and data segments must be less
-than 2GB in size and the data segment must be located within 2GB of the
-text segment.
-
-@item embmedany
-The Medium/Anywhere code model for embedded systems:
-64-bit addresses, the text and data segments must be less than 2GB in
-size, both starting anywhere in memory (determined at link time). The
-global register %g4 points to the base of the data segment. Programs
-are statically linked and PIC is not supported.
-@end table
-
-@item -mmemory-model=@var{mem-model}
-@opindex mmemory-model
-Set the memory model in force on the processor to one of
-
-@table @samp
-@item default
-The default memory model for the processor and operating system.
-
-@item rmo
-Relaxed Memory Order
-
-@item pso
-Partial Store Order
-
-@item tso
-Total Store Order
-
-@item sc
-Sequential Consistency
-@end table
-
-These memory models are formally defined in Appendix D of the Sparc V9
-architecture manual, as set in the processor's @code{PSTATE.MM} field.
-
-@item -mstack-bias
-@itemx -mno-stack-bias
-@opindex mstack-bias
-@opindex mno-stack-bias
-With @option{-mstack-bias}, GCC assumes that the stack pointer, and
-frame pointer if present, are offset by @minus{}2047 which must be added back
-when making stack frame references. This is the default in 64-bit mode.
-Otherwise, assume no such offset is present.
-@end table
-
-@node SPU Options
-@subsection SPU Options
-@cindex SPU options
-
-These @samp{-m} options are supported on the SPU:
-
-@table @gcctabopt
-@item -mwarn-reloc
-@itemx -merror-reloc
-@opindex mwarn-reloc
-@opindex merror-reloc
-
-The loader for SPU does not handle dynamic relocations. By default, GCC
-gives an error when it generates code that requires a dynamic
-relocation. @option{-mno-error-reloc} disables the error,
-@option{-mwarn-reloc} generates a warning instead.
-
-@item -msafe-dma
-@itemx -munsafe-dma
-@opindex msafe-dma
-@opindex munsafe-dma
-
-Instructions that initiate or test completion of DMA must not be
-reordered with respect to loads and stores of the memory that is being
-accessed.
-With @option{-munsafe-dma} you must use the @code{volatile} keyword to protect
-memory accesses, but that can lead to inefficient code in places where the
-memory is known to not change. Rather than mark the memory as volatile,
-you can use @option{-msafe-dma} to tell the compiler to treat
-the DMA instructions as potentially affecting all memory.
-
-@item -mbranch-hints
-@opindex mbranch-hints
-
-By default, GCC generates a branch hint instruction to avoid
-pipeline stalls for always-taken or probably-taken branches. A hint
-is not generated closer than 8 instructions away from its branch.
-There is little reason to disable them, except for debugging purposes,
-or to make an object a little bit smaller.
-
-@item -msmall-mem
-@itemx -mlarge-mem
-@opindex msmall-mem
-@opindex mlarge-mem
-
-By default, GCC generates code assuming that addresses are never larger
-than 18 bits. With @option{-mlarge-mem} code is generated that assumes
-a full 32-bit address.
-
-@item -mstdmain
-@opindex mstdmain
-
-By default, GCC links against startup code that assumes the SPU-style
-main function interface (which has an unconventional parameter list).
-With @option{-mstdmain}, GCC links your program against startup
-code that assumes a C99-style interface to @code{main}, including a
-local copy of @code{argv} strings.
-
-@item -mfixed-range=@var{register-range}
-@opindex mfixed-range
-Generate code treating the given register range as fixed registers.
-A fixed register is one that the register allocator cannot use. This is
-useful when compiling kernel code. A register range is specified as
-two registers separated by a dash. Multiple register ranges can be
-specified separated by a comma.
-
-@item -mea32
-@itemx -mea64
-@opindex mea32
-@opindex mea64
-Compile code assuming that pointers to the PPU address space accessed
-via the @code{__ea} named address space qualifier are either 32 or 64
-bits wide. The default is 32 bits. As this is an ABI-changing option,
-all object code in an executable must be compiled with the same setting.
-
-@item -maddress-space-conversion
-@itemx -mno-address-space-conversion
-@opindex maddress-space-conversion
-@opindex mno-address-space-conversion
-Allow/disallow treating the @code{__ea} address space as superset
-of the generic address space. This enables explicit type casts
-between @code{__ea} and generic pointer as well as implicit
-conversions of generic pointers to @code{__ea} pointers. The
-default is to allow address space pointer conversions.
-
-@item -mcache-size=@var{cache-size}
-@opindex mcache-size
-This option controls the version of libgcc that the compiler links to an
-executable and selects a software-managed cache for accessing variables
-in the @code{__ea} address space with a particular cache size. Possible
-options for @var{cache-size} are @samp{8}, @samp{16}, @samp{32}, @samp{64}
-and @samp{128}. The default cache size is 64KB.
-
-@item -matomic-updates
-@itemx -mno-atomic-updates
-@opindex matomic-updates
-@opindex mno-atomic-updates
-This option controls the version of libgcc that the compiler links to an
-executable and selects whether atomic updates to the software-managed
-cache of PPU-side variables are used. If you use atomic updates, changes
-to a PPU variable from SPU code using the @code{__ea} named address space
-qualifier do not interfere with changes to other PPU variables residing
-in the same cache line from PPU code. If you do not use atomic updates,
-such interference may occur; however, writing back cache lines is
-more efficient. The default behavior is to use atomic updates.
-
-@item -mdual-nops
-@itemx -mdual-nops=@var{n}
-@opindex mdual-nops
-By default, GCC inserts nops to increase dual issue when it expects
-it to increase performance. @var{n} can be a value from 0 to 10. A
-smaller @var{n} inserts fewer nops. 10 is the default, 0 is the
-same as @option{-mno-dual-nops}. Disabled with @option{-Os}.
-
-@item -mhint-max-nops=@var{n}
-@opindex mhint-max-nops
-Maximum number of nops to insert for a branch hint. A branch hint must
-be at least 8 instructions away from the branch it is affecting. GCC
-inserts up to @var{n} nops to enforce this, otherwise it does not
-generate the branch hint.
-
-@item -mhint-max-distance=@var{n}
-@opindex mhint-max-distance
-The encoding of the branch hint instruction limits the hint to be within
-256 instructions of the branch it is affecting. By default, GCC makes
-sure it is within 125.
-
-@item -msafe-hints
-@opindex msafe-hints
-Work around a hardware bug that causes the SPU to stall indefinitely.
-By default, GCC inserts the @code{hbrp} instruction to make sure
-this stall won't happen.
-
-@end table
-
-@node System V Options
-@subsection Options for System V
-
-These additional options are available on System V Release 4 for
-compatibility with other compilers on those systems:
-
-@table @gcctabopt
-@item -G
-@opindex G
-Create a shared object.
-It is recommended that @option{-symbolic} or @option{-shared} be used instead.
-
-@item -Qy
-@opindex Qy
-Identify the versions of each tool used by the compiler, in a
-@code{.ident} assembler directive in the output.
-
-@item -Qn
-@opindex Qn
-Refrain from adding @code{.ident} directives to the output file (this is
-the default).
-
-@item -YP,@var{dirs}
-@opindex YP
-Search the directories @var{dirs}, and no others, for libraries
-specified with @option{-l}.
-
-@item -Ym,@var{dir}
-@opindex Ym
-Look in the directory @var{dir} to find the M4 preprocessor.
-The assembler uses this option.
-@c This is supposed to go with a -Yd for predefined M4 macro files, but
-@c the generic assembler that comes with Solaris takes just -Ym.
-@end table
-
-@node TILE-Gx Options
-@subsection TILE-Gx Options
-@cindex TILE-Gx options
-
-These @samp{-m} options are supported on the TILE-Gx:
-
-@table @gcctabopt
-@item -mcmodel=small
-@opindex mcmodel=small
-Generate code for the small model. The distance for direct calls is
-limited to 500M in either direction. PC-relative addresses are 32
-bits. Absolute addresses support the full address range.
-
-@item -mcmodel=large
-@opindex mcmodel=large
-Generate code for the large model. There is no limitation on call
-distance, pc-relative addresses, or absolute addresses.
-
-@item -mcpu=@var{name}
-@opindex mcpu
-Selects the type of CPU to be targeted. Currently the only supported
-type is @samp{tilegx}.
-
-@item -m32
-@itemx -m64
-@opindex m32
-@opindex m64
-Generate code for a 32-bit or 64-bit environment. The 32-bit
-environment sets int, long, and pointer to 32 bits. The 64-bit
-environment sets int to 32 bits and long and pointer to 64 bits.
-@end table
-
-@node TILEPro Options
-@subsection TILEPro Options
-@cindex TILEPro options
-
-These @samp{-m} options are supported on the TILEPro:
-
-@table @gcctabopt
-@item -mcpu=@var{name}
-@opindex mcpu
-Selects the type of CPU to be targeted. Currently the only supported
-type is @samp{tilepro}.
-
-@item -m32
-@opindex m32
-Generate code for a 32-bit environment, which sets int, long, and
-pointer to 32 bits. This is the only supported behavior so the flag
-is essentially ignored.
-@end table
-
-@node V850 Options
-@subsection V850 Options
-@cindex V850 Options
-
-These @samp{-m} options are defined for V850 implementations:
-
-@table @gcctabopt
-@item -mlong-calls
-@itemx -mno-long-calls
-@opindex mlong-calls
-@opindex mno-long-calls
-Treat all calls as being far away (near). If calls are assumed to be
-far away, the compiler always loads the function's address into a
-register, and calls indirect through the pointer.
-
-@item -mno-ep
-@itemx -mep
-@opindex mno-ep
-@opindex mep
-Do not optimize (do optimize) basic blocks that use the same index
-pointer 4 or more times to copy pointer into the @code{ep} register, and
-use the shorter @code{sld} and @code{sst} instructions. The @option{-mep}
-option is on by default if you optimize.
-
-@item -mno-prolog-function
-@itemx -mprolog-function
-@opindex mno-prolog-function
-@opindex mprolog-function
-Do not use (do use) external functions to save and restore registers
-at the prologue and epilogue of a function. The external functions
-are slower, but use less code space if more than one function saves
-the same number of registers. The @option{-mprolog-function} option
-is on by default if you optimize.
-
-@item -mspace
-@opindex mspace
-Try to make the code as small as possible. At present, this just turns
-on the @option{-mep} and @option{-mprolog-function} options.
-
-@item -mtda=@var{n}
-@opindex mtda
-Put static or global variables whose size is @var{n} bytes or less into
-the tiny data area that register @code{ep} points to. The tiny data
-area can hold up to 256 bytes in total (128 bytes for byte references).
-
-@item -msda=@var{n}
-@opindex msda
-Put static or global variables whose size is @var{n} bytes or less into
-the small data area that register @code{gp} points to. The small data
-area can hold up to 64 kilobytes.
-
-@item -mzda=@var{n}
-@opindex mzda
-Put static or global variables whose size is @var{n} bytes or less into
-the first 32 kilobytes of memory.
-
-@item -mv850
-@opindex mv850
-Specify that the target processor is the V850.
-
-@item -mv850e3v5
-@opindex mv850e3v5
-Specify that the target processor is the V850E3V5. The preprocessor
-constant @samp{__v850e3v5__} is defined if this option is used.
-
-@item -mv850e2v4
-@opindex mv850e2v4
-Specify that the target processor is the V850E3V5. This is an alias for
-the @option{-mv850e3v5} option.
-
-@item -mv850e2v3
-@opindex mv850e2v3
-Specify that the target processor is the V850E2V3. The preprocessor
-constant @samp{__v850e2v3__} is defined if this option is used.
-
-@item -mv850e2
-@opindex mv850e2
-Specify that the target processor is the V850E2. The preprocessor
-constant @samp{__v850e2__} is defined if this option is used.
-
-@item -mv850e1
-@opindex mv850e1
-Specify that the target processor is the V850E1. The preprocessor
-constants @samp{__v850e1__} and @samp{__v850e__} are defined if
-this option is used.
-
-@item -mv850es
-@opindex mv850es
-Specify that the target processor is the V850ES. This is an alias for
-the @option{-mv850e1} option.
-
-@item -mv850e
-@opindex mv850e
-Specify that the target processor is the V850E@. The preprocessor
-constant @samp{__v850e__} is defined if this option is used.
-
-If neither @option{-mv850} nor @option{-mv850e} nor @option{-mv850e1}
-nor @option{-mv850e2} nor @option{-mv850e2v3} nor @option{-mv850e3v5}
-are defined then a default target processor is chosen and the
-relevant @samp{__v850*__} preprocessor constant is defined.
-
-The preprocessor constants @samp{__v850} and @samp{__v851__} are always
-defined, regardless of which processor variant is the target.
-
-@item -mdisable-callt
-@itemx -mno-disable-callt
-@opindex mdisable-callt
-@opindex mno-disable-callt
-This option suppresses generation of the @code{CALLT} instruction for the
-v850e, v850e1, v850e2, v850e2v3 and v850e3v5 flavors of the v850
-architecture.
-
-This option is enabled by default when the RH850 ABI is
-in use (see @option{-mrh850-abi}), and disabled by default when the
-GCC ABI is in use. If @code{CALLT} instructions are being generated
-then the C preprocessor symbol @code{__V850_CALLT__} will be defined.
-
-@item -mrelax
-@itemx -mno-relax
-@opindex mrelax
-@opindex mno-relax
-Pass on (or do not pass on) the @option{-mrelax} command line option
-to the assembler.
-
-@item -mlong-jumps
-@itemx -mno-long-jumps
-@opindex mlong-jumps
-@opindex mno-long-jumps
-Disable (or re-enable) the generation of PC-relative jump instructions.
-
-@item -msoft-float
-@itemx -mhard-float
-@opindex msoft-float
-@opindex mhard-float
-Disable (or re-enable) the generation of hardware floating point
-instructions. This option is only significant when the target
-architecture is @samp{V850E2V3} or higher. If hardware floating point
-instructions are being generated then the C preprocessor symbol
-@code{__FPU_OK__} will be defined, otherwise the symbol
-@code{__NO_FPU__} will be defined.
-
-@item -mloop
-@opindex mloop
-Enables the use of the e3v5 LOOP instruction. The use of this
-instruction is not enabled by default when the e3v5 architecture is
-selected because its use is still experimental.
-
-@item -mrh850-abi
-@itemx -mghs
-@opindex mrh850-abi
-@opindex mghs
-Enables support for the RH850 version of the V850 ABI. This is the
-default. With this version of the ABI the following rules apply:
-
-@itemize
-@item
-Integer sized structures and unions are returned via a memory pointer
-rather than a register.
-
-@item
-Large structures and unions (more than 8 bytes in size) are passed by
-value.
-
-@item
-Functions are aligned to 16-bit boundaries.
-
-@item
-The @option{-m8byte-align} command line option is supported.
-
-@item
-The @option{-mdisable-callt} command line option is enabled by
-default. The @option{-mno-disable-callt} command line option is not
-supported.
-@end itemize
-
-When this version of the ABI is enabled the C preprocessor symbol
-@code{__V850_RH850_ABI__} is defined.
-
-@item -mgcc-abi
-@opindex mgcc-abi
-Enables support for the old GCC version of the V850 ABI. With this
-version of the ABI the following rules apply:
-
-@itemize
-@item
-Integer sized structures and unions are returned in register @code{r10}.
-
-@item
-Large structures and unions (more than 8 bytes in size) are passed by
-reference.
-
-@item
-Functions are aligned to 32-bit boundaries, unless optimizing for
-size.
-
-@item
-The @option{-m8byte-align} command line option is not supported.
-
-@item
-The @option{-mdisable-callt} command line option is supported but not
-enabled by default.
-@end itemize
-
-When this version of the ABI is enabled the C preprocessor symbol
-@code{__V850_GCC_ABI__} is defined.
-
-@item -m8byte-align
-@itemx -mno-8byte-align
-@opindex m8byte-align
-@opindex mno-8byte-align
-Enables support for @code{doubles} and @code{long long} types to be
-aligned on 8-byte boundaries. The default is to restrict the
-alignment of all objects to at most 4-bytes. When
-@option{-m8byte-align} is in effect the C preprocessor symbol
-@code{__V850_8BYTE_ALIGN__} will be defined.
-
-@item -mbig-switch
-@opindex mbig-switch
-Generate code suitable for big switch tables. Use this option only if
-the assembler/linker complain about out of range branches within a switch
-table.
-
-@item -mapp-regs
-@opindex mapp-regs
-This option causes r2 and r5 to be used in the code generated by
-the compiler. This setting is the default.
-
-@item -mno-app-regs
-@opindex mno-app-regs
-This option causes r2 and r5 to be treated as fixed registers.
-
-@end table
-
-@node VAX Options
-@subsection VAX Options
-@cindex VAX options
-
-These @samp{-m} options are defined for the VAX:
-
-@table @gcctabopt
-@item -munix
-@opindex munix
-Do not output certain jump instructions (@code{aobleq} and so on)
-that the Unix assembler for the VAX cannot handle across long
-ranges.
-
-@item -mgnu
-@opindex mgnu
-Do output those jump instructions, on the assumption that the
-GNU assembler is being used.
-
-@item -mg
-@opindex mg
-Output code for G-format floating-point numbers instead of D-format.
-@end table
-
-@node VMS Options
-@subsection VMS Options
-
-These @samp{-m} options are defined for the VMS implementations:
-
-@table @gcctabopt
-@item -mvms-return-codes
-@opindex mvms-return-codes
-Return VMS condition codes from @code{main}. The default is to return POSIX-style
-condition (e.g.@ error) codes.
-
-@item -mdebug-main=@var{prefix}
-@opindex mdebug-main=@var{prefix}
-Flag the first routine whose name starts with @var{prefix} as the main
-routine for the debugger.
-
-@item -mmalloc64
-@opindex mmalloc64
-Default to 64-bit memory allocation routines.
-
-@item -mpointer-size=@var{size}
-@opindex -mpointer-size=@var{size}
-Set the default size of pointers. Possible options for @var{size} are
-@samp{32} or @samp{short} for 32 bit pointers, @samp{64} or @samp{long}
-for 64 bit pointers, and @samp{no} for supporting only 32 bit pointers.
-The later option disables @code{pragma pointer_size}.
-@end table
-
-@node VxWorks Options
-@subsection VxWorks Options
-@cindex VxWorks Options
-
-The options in this section are defined for all VxWorks targets.
-Options specific to the target hardware are listed with the other
-options for that target.
-
-@table @gcctabopt
-@item -mrtp
-@opindex mrtp
-GCC can generate code for both VxWorks kernels and real time processes
-(RTPs). This option switches from the former to the latter. It also
-defines the preprocessor macro @code{__RTP__}.
-
-@item -non-static
-@opindex non-static
-Link an RTP executable against shared libraries rather than static
-libraries. The options @option{-static} and @option{-shared} can
-also be used for RTPs (@pxref{Link Options}); @option{-static}
-is the default.
-
-@item -Bstatic
-@itemx -Bdynamic
-@opindex Bstatic
-@opindex Bdynamic
-These options are passed down to the linker. They are defined for
-compatibility with Diab.
-
-@item -Xbind-lazy
-@opindex Xbind-lazy
-Enable lazy binding of function calls. This option is equivalent to
-@option{-Wl,-z,now} and is defined for compatibility with Diab.
-
-@item -Xbind-now
-@opindex Xbind-now
-Disable lazy binding of function calls. This option is the default and
-is defined for compatibility with Diab.
-@end table
-
-@node x86-64 Options
-@subsection x86-64 Options
-@cindex x86-64 options
-
-These are listed under @xref{i386 and x86-64 Options}.
-
-@node Xstormy16 Options
-@subsection Xstormy16 Options
-@cindex Xstormy16 Options
-
-These options are defined for Xstormy16:
-
-@table @gcctabopt
-@item -msim
-@opindex msim
-Choose startup files and linker script suitable for the simulator.
-@end table
-
-@node Xtensa Options
-@subsection Xtensa Options
-@cindex Xtensa Options
-
-These options are supported for Xtensa targets:
-
-@table @gcctabopt
-@item -mconst16
-@itemx -mno-const16
-@opindex mconst16
-@opindex mno-const16
-Enable or disable use of @code{CONST16} instructions for loading
-constant values. The @code{CONST16} instruction is currently not a
-standard option from Tensilica. When enabled, @code{CONST16}
-instructions are always used in place of the standard @code{L32R}
-instructions. The use of @code{CONST16} is enabled by default only if
-the @code{L32R} instruction is not available.
-
-@item -mfused-madd
-@itemx -mno-fused-madd
-@opindex mfused-madd
-@opindex mno-fused-madd
-Enable or disable use of fused multiply/add and multiply/subtract
-instructions in the floating-point option. This has no effect if the
-floating-point option is not also enabled. Disabling fused multiply/add
-and multiply/subtract instructions forces the compiler to use separate
-instructions for the multiply and add/subtract operations. This may be
-desirable in some cases where strict IEEE 754-compliant results are
-required: the fused multiply add/subtract instructions do not round the
-intermediate result, thereby producing results with @emph{more} bits of
-precision than specified by the IEEE standard. Disabling fused multiply
-add/subtract instructions also ensures that the program output is not
-sensitive to the compiler's ability to combine multiply and add/subtract
-operations.
-
-@item -mserialize-volatile
-@itemx -mno-serialize-volatile
-@opindex mserialize-volatile
-@opindex mno-serialize-volatile
-When this option is enabled, GCC inserts @code{MEMW} instructions before
-@code{volatile} memory references to guarantee sequential consistency.
-The default is @option{-mserialize-volatile}. Use
-@option{-mno-serialize-volatile} to omit the @code{MEMW} instructions.
-
-@item -mforce-no-pic
-@opindex mforce-no-pic
-For targets, like GNU/Linux, where all user-mode Xtensa code must be
-position-independent code (PIC), this option disables PIC for compiling
-kernel code.
-
-@item -mtext-section-literals
-@itemx -mno-text-section-literals
-@opindex mtext-section-literals
-@opindex mno-text-section-literals
-Control the treatment of literal pools. The default is
-@option{-mno-text-section-literals}, which places literals in a separate
-section in the output file. This allows the literal pool to be placed
-in a data RAM/ROM, and it also allows the linker to combine literal
-pools from separate object files to remove redundant literals and
-improve code size. With @option{-mtext-section-literals}, the literals
-are interspersed in the text section in order to keep them as close as
-possible to their references. This may be necessary for large assembly
-files.
-
-@item -mtarget-align
-@itemx -mno-target-align
-@opindex mtarget-align
-@opindex mno-target-align
-When this option is enabled, GCC instructs the assembler to
-automatically align instructions to reduce branch penalties at the
-expense of some code density. The assembler attempts to widen density
-instructions to align branch targets and the instructions following call
-instructions. If there are not enough preceding safe density
-instructions to align a target, no widening is performed. The
-default is @option{-mtarget-align}. These options do not affect the
-treatment of auto-aligned instructions like @code{LOOP}, which the
-assembler always aligns, either by widening density instructions or
-by inserting NOP instructions.
-
-@item -mlongcalls
-@itemx -mno-longcalls
-@opindex mlongcalls
-@opindex mno-longcalls
-When this option is enabled, GCC instructs the assembler to translate
-direct calls to indirect calls unless it can determine that the target
-of a direct call is in the range allowed by the call instruction. This
-translation typically occurs for calls to functions in other source
-files. Specifically, the assembler translates a direct @code{CALL}
-instruction into an @code{L32R} followed by a @code{CALLX} instruction.
-The default is @option{-mno-longcalls}. This option should be used in
-programs where the call target can potentially be out of range. This
-option is implemented in the assembler, not the compiler, so the
-assembly code generated by GCC still shows direct call
-instructions---look at the disassembled object code to see the actual
-instructions. Note that the assembler uses an indirect call for
-every cross-file call, not just those that really are out of range.
-@end table
-
-@node zSeries Options
-@subsection zSeries Options
-@cindex zSeries options
-
-These are listed under @xref{S/390 and zSeries Options}.
-
-@node Code Gen Options
-@section Options for Code Generation Conventions
-@cindex code generation conventions
-@cindex options, code generation
-@cindex run-time options
-
-These machine-independent options control the interface conventions
-used in code generation.
-
-Most of them have both positive and negative forms; the negative form
-of @option{-ffoo} is @option{-fno-foo}. In the table below, only
-one of the forms is listed---the one that is not the default. You
-can figure out the other form by either removing @samp{no-} or adding
-it.
-
-@table @gcctabopt
-@item -fbounds-check
-@opindex fbounds-check
-For front ends that support it, generate additional code to check that
-indices used to access arrays are within the declared range. This is
-currently only supported by the Java and Fortran front ends, where
-this option defaults to true and false respectively.
-
-@item -fstack-reuse=@var{reuse-level}
-@opindex fstack_reuse
-This option controls stack space reuse for user declared local/auto variables
-and compiler generated temporaries. @var{reuse_level} can be @samp{all},
-@samp{named_vars}, or @samp{none}. @samp{all} enables stack reuse for all
-local variables and temporaries, @samp{named_vars} enables the reuse only for
-user defined local variables with names, and @samp{none} disables stack reuse
-completely. The default value is @samp{all}. The option is needed when the
-program extends the lifetime of a scoped local variable or a compiler generated
-temporary beyond the end point defined by the language. When a lifetime of
-a variable ends, and if the variable lives in memory, the optimizing compiler
-has the freedom to reuse its stack space with other temporaries or scoped
-local variables whose live range does not overlap with it. Legacy code extending
-local lifetime will likely to break with the stack reuse optimization.
-
-For example,
-
-@smallexample
- int *p;
- @{
- int local1;
-
- p = &local1;
- local1 = 10;
- ....
- @}
- @{
- int local2;
- local2 = 20;
- ...
- @}
-
- if (*p == 10) // out of scope use of local1
- @{
-
- @}
-@end smallexample
-
-Another example:
-@smallexample
-
- struct A
- @{
- A(int k) : i(k), j(k) @{ @}
- int i;
- int j;
- @};
-
- A *ap;
-
- void foo(const A& ar)
- @{
- ap = &ar;
- @}
-
- void bar()
- @{
- foo(A(10)); // temp object's lifetime ends when foo returns
-
- @{
- A a(20);
- ....
- @}
- ap->i+= 10; // ap references out of scope temp whose space
- // is reused with a. What is the value of ap->i?
- @}
-
-@end smallexample
-
-The lifetime of a compiler generated temporary is well defined by the C++
-standard. When a lifetime of a temporary ends, and if the temporary lives
-in memory, the optimizing compiler has the freedom to reuse its stack
-space with other temporaries or scoped local variables whose live range
-does not overlap with it. However some of the legacy code relies on
-the behavior of older compilers in which temporaries' stack space is
-not reused, the aggressive stack reuse can lead to runtime errors. This
-option is used to control the temporary stack reuse optimization.
-
-@item -ftrapv
-@opindex ftrapv
-This option generates traps for signed overflow on addition, subtraction,
-multiplication operations.
-
-@item -fwrapv
-@opindex fwrapv
-This option instructs the compiler to assume that signed arithmetic
-overflow of addition, subtraction and multiplication wraps around
-using twos-complement representation. This flag enables some optimizations
-and disables others. This option is enabled by default for the Java
-front end, as required by the Java language specification.
-
-@item -fexceptions
-@opindex fexceptions
-Enable exception handling. Generates extra code needed to propagate
-exceptions. For some targets, this implies GCC generates frame
-unwind information for all functions, which can produce significant data
-size overhead, although it does not affect execution. If you do not
-specify this option, GCC enables it by default for languages like
-C++ that normally require exception handling, and disables it for
-languages like C that do not normally require it. However, you may need
-to enable this option when compiling C code that needs to interoperate
-properly with exception handlers written in C++. You may also wish to
-disable this option if you are compiling older C++ programs that don't
-use exception handling.
-
-@item -fnon-call-exceptions
-@opindex fnon-call-exceptions
-Generate code that allows trapping instructions to throw exceptions.
-Note that this requires platform-specific runtime support that does
-not exist everywhere. Moreover, it only allows @emph{trapping}
-instructions to throw exceptions, i.e.@: memory references or floating-point
-instructions. It does not allow exceptions to be thrown from
-arbitrary signal handlers such as @code{SIGALRM}.
-
-@item -fdelete-dead-exceptions
-@opindex fdelete-dead-exceptions
-Consider that instructions that may throw exceptions but don't otherwise
-contribute to the execution of the program can be optimized away.
-This option is enabled by default for the Ada front end, as permitted by
-the Ada language specification.
-Optimization passes that cause dead exceptions to be removed are enabled independently at different optimization levels.
-
-@item -funwind-tables
-@opindex funwind-tables
-Similar to @option{-fexceptions}, except that it just generates any needed
-static data, but does not affect the generated code in any other way.
-You normally do not need to enable this option; instead, a language processor
-that needs this handling enables it on your behalf.
-
-@item -fasynchronous-unwind-tables
-@opindex fasynchronous-unwind-tables
-Generate unwind table in DWARF 2 format, if supported by target machine. The
-table is exact at each instruction boundary, so it can be used for stack
-unwinding from asynchronous events (such as debugger or garbage collector).
-
-@item -fpcc-struct-return
-@opindex fpcc-struct-return
-Return ``short'' @code{struct} and @code{union} values in memory like
-longer ones, rather than in registers. This convention is less
-efficient, but it has the advantage of allowing intercallability between
-GCC-compiled files and files compiled with other compilers, particularly
-the Portable C Compiler (pcc).
-
-The precise convention for returning structures in memory depends
-on the target configuration macros.
-
-Short structures and unions are those whose size and alignment match
-that of some integer type.
-
-@strong{Warning:} code compiled with the @option{-fpcc-struct-return}
-switch is not binary compatible with code compiled with the
-@option{-freg-struct-return} switch.
-Use it to conform to a non-default application binary interface.
-
-@item -freg-struct-return
-@opindex freg-struct-return
-Return @code{struct} and @code{union} values in registers when possible.
-This is more efficient for small structures than
-@option{-fpcc-struct-return}.
-
-If you specify neither @option{-fpcc-struct-return} nor
-@option{-freg-struct-return}, GCC defaults to whichever convention is
-standard for the target. If there is no standard convention, GCC
-defaults to @option{-fpcc-struct-return}, except on targets where GCC is
-the principal compiler. In those cases, we can choose the standard, and
-we chose the more efficient register return alternative.
-
-@strong{Warning:} code compiled with the @option{-freg-struct-return}
-switch is not binary compatible with code compiled with the
-@option{-fpcc-struct-return} switch.
-Use it to conform to a non-default application binary interface.
-
-@item -fshort-enums
-@opindex fshort-enums
-Allocate to an @code{enum} type only as many bytes as it needs for the
-declared range of possible values. Specifically, the @code{enum} type
-is equivalent to the smallest integer type that has enough room.
-
-@strong{Warning:} the @option{-fshort-enums} switch causes GCC to generate
-code that is not binary compatible with code generated without that switch.
-Use it to conform to a non-default application binary interface.
-
-@item -fshort-double
-@opindex fshort-double
-Use the same size for @code{double} as for @code{float}.
-
-@strong{Warning:} the @option{-fshort-double} switch causes GCC to generate
-code that is not binary compatible with code generated without that switch.
-Use it to conform to a non-default application binary interface.
-
-@item -fshort-wchar
-@opindex fshort-wchar
-Override the underlying type for @samp{wchar_t} to be @samp{short
-unsigned int} instead of the default for the target. This option is
-useful for building programs to run under WINE@.
-
-@strong{Warning:} the @option{-fshort-wchar} switch causes GCC to generate
-code that is not binary compatible with code generated without that switch.
-Use it to conform to a non-default application binary interface.
-
-@item -fno-common
-@opindex fno-common
-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 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 that always treat uninitialized
-variable declarations this way.
-
-@item -fno-ident
-@opindex fno-ident
-Ignore the @samp{#ident} directive.
-
-@item -finhibit-size-directive
-@opindex finhibit-size-directive
-Don't output a @code{.size} assembler directive, or anything else that
-would cause trouble if the function is split in the middle, and the
-two halves are placed at locations far apart in memory. This option is
-used when compiling @file{crtstuff.c}; you should not need to use it
-for anything else.
-
-@item -fverbose-asm
-@opindex fverbose-asm
-Put extra commentary information in the generated assembly code to
-make it more readable. This option is generally only of use to those
-who actually need to read the generated assembly code (perhaps while
-debugging the compiler itself).
-
-@option{-fno-verbose-asm}, the default, causes the
-extra information to be omitted and is useful when comparing two assembler
-files.
-
-@item -frecord-gcc-switches
-@opindex frecord-gcc-switches
-This switch causes the command line used to invoke the
-compiler to be recorded into the object file that is being created.
-This switch is only implemented on some targets and the exact format
-of the recording is target and binary file format dependent, but it
-usually takes the form of a section containing ASCII text. This
-switch is related to the @option{-fverbose-asm} switch, but that
-switch only records information in the assembler output file as
-comments, so it never reaches the object file.
-See also @option{-grecord-gcc-switches} for another
-way of storing compiler options into the object file.
-
-@item -fpic
-@opindex fpic
-@cindex global offset table
-@cindex PIC
-Generate position-independent code (PIC) suitable for use in a shared
-library, if supported for the target machine. Such code accesses all
-constant addresses through a global offset table (GOT)@. The dynamic
-loader resolves the GOT entries when the program starts (the dynamic
-loader is not part of GCC; it is part of the operating system). If
-the GOT size for the linked executable exceeds a machine-specific
-maximum size, you get an error message from the linker indicating that
-@option{-fpic} does not work; in that case, recompile with @option{-fPIC}
-instead. (These maximums are 8k on the SPARC and 32k
-on the m68k and RS/6000. The 386 has no such limit.)
-
-Position-independent code requires special support, and therefore works
-only on certain machines. For the 386, GCC supports PIC for System V
-but not for the Sun 386i. Code generated for the IBM RS/6000 is always
-position-independent.
-
-When this flag is set, the macros @code{__pic__} and @code{__PIC__}
-are defined to 1.
-
-@item -fPIC
-@opindex fPIC
-If supported for the target machine, emit position-independent code,
-suitable for dynamic linking and avoiding any limit on the size of the
-global offset table. This option makes a difference on the m68k,
-PowerPC and SPARC@.
-
-Position-independent code requires special support, and therefore works
-only on certain machines.
-
-When this flag is set, the macros @code{__pic__} and @code{__PIC__}
-are defined to 2.
-
-@item -fpie
-@itemx -fPIE
-@opindex fpie
-@opindex fPIE
-These options are similar to @option{-fpic} and @option{-fPIC}, but
-generated position independent code can be only linked into executables.
-Usually these options are used when @option{-pie} GCC option is
-used during linking.
-
-@option{-fpie} and @option{-fPIE} both define the macros
-@code{__pie__} and @code{__PIE__}. The macros have the value 1
-for @option{-fpie} and 2 for @option{-fPIE}.
-
-@item -fno-jump-tables
-@opindex fno-jump-tables
-Do not use jump tables for switch statements even where it would be
-more efficient than other code generation strategies. This option is
-of use in conjunction with @option{-fpic} or @option{-fPIC} for
-building code that forms part of a dynamic linker and cannot
-reference the address of a jump table. On some targets, jump tables
-do not require a GOT and this option is not needed.
-
-@item -ffixed-@var{reg}
-@opindex ffixed
-Treat the register named @var{reg} as a fixed register; generated code
-should never refer to it (except perhaps as a stack pointer, frame
-pointer or in some other fixed role).
-
-@var{reg} must be the name of a register. The register names accepted
-are machine-specific and are defined in the @code{REGISTER_NAMES}
-macro in the machine description macro file.
-
-This flag does not have a negative form, because it specifies a
-three-way choice.
-
-@item -fcall-used-@var{reg}
-@opindex fcall-used
-Treat the register named @var{reg} as an allocable register that is
-clobbered by function calls. It may be allocated for temporaries or
-variables that do not live across a call. Functions compiled this way
-do not save and restore the register @var{reg}.
-
-It is an error to use this flag with the frame pointer or stack pointer.
-Use of this flag for other registers that have fixed pervasive roles in
-the machine's execution model produces disastrous results.
-
-This flag does not have a negative form, because it specifies a
-three-way choice.
-
-@item -fcall-saved-@var{reg}
-@opindex fcall-saved
-Treat the register named @var{reg} as an allocable register saved by
-functions. It may be allocated even for temporaries or variables that
-live across a call. Functions compiled this way save and restore
-the register @var{reg} if they use it.
-
-It is an error to use this flag with the frame pointer or stack pointer.
-Use of this flag for other registers that have fixed pervasive roles in
-the machine's execution model produces disastrous results.
-
-A different sort of disaster results from the use of this flag for
-a register in which function values may be returned.
-
-This flag does not have a negative form, because it specifies a
-three-way choice.
-
-@item -fpack-struct[=@var{n}]
-@opindex fpack-struct
-Without a value specified, pack all structure members together without
-holes. When a value is specified (which must be a small power of two), pack
-structure members according to this value, representing the maximum
-alignment (that is, objects with default alignment requirements larger than
-this are output potentially unaligned at the next fitting location.
-
-@strong{Warning:} the @option{-fpack-struct} switch causes GCC to generate
-code that is not binary compatible with code generated without that switch.
-Additionally, it makes the code suboptimal.
-Use it to conform to a non-default application binary interface.
-
-@item -finstrument-functions
-@opindex finstrument-functions
-Generate instrumentation calls for entry and exit to functions. Just
-after function entry and just before function exit, the following
-profiling functions are called with the address of the current
-function and its call site. (On some platforms,
-@code{__builtin_return_address} does not work beyond the current
-function, so the call site information may not be available to the
-profiling functions otherwise.)
-
-@smallexample
-void __cyg_profile_func_enter (void *this_fn,
- void *call_site);
-void __cyg_profile_func_exit (void *this_fn,
- void *call_site);
-@end smallexample
-
-The first argument is the address of the start of the current function,
-which may be looked up exactly in the symbol table.
-
-This instrumentation is also done for functions expanded inline in other
-functions. The profiling calls indicate where, conceptually, the
-inline function is entered and exited. This means that addressable
-versions of such functions must be available. If all your uses of a
-function are expanded inline, this may mean an additional expansion of
-code size. If you use @samp{extern inline} in your C code, an
-addressable version of such functions must be provided. (This is
-normally the case anyway, but if you get lucky and the optimizer always
-expands the functions inline, you might have gotten away without
-providing static copies.)
-
-A function may be given the attribute @code{no_instrument_function}, in
-which case this instrumentation is not done. This can be used, for
-example, for the profiling functions listed above, high-priority
-interrupt routines, and any functions from which the profiling functions
-cannot safely be called (perhaps signal handlers, if the profiling
-routines generate output or allocate memory).
-
-@item -finstrument-functions-exclude-file-list=@var{file},@var{file},@dots{}
-@opindex finstrument-functions-exclude-file-list
-
-Set the list of functions that are excluded from instrumentation (see
-the description of @code{-finstrument-functions}). If the file that
-contains a function definition matches with one of @var{file}, then
-that function is not instrumented. The match is done on substrings:
-if the @var{file} parameter is a substring of the file name, it is
-considered to be a match.
-
-For example:
-
-@smallexample
--finstrument-functions-exclude-file-list=/bits/stl,include/sys
-@end smallexample
-
-@noindent
-excludes any inline function defined in files whose pathnames
-contain @code{/bits/stl} or @code{include/sys}.
-
-If, for some reason, you want to include letter @code{','} in one of
-@var{sym}, write @code{'\,'}. For example,
-@code{-finstrument-functions-exclude-file-list='\,\,tmp'}
-(note the single quote surrounding the option).
-
-@item -finstrument-functions-exclude-function-list=@var{sym},@var{sym},@dots{}
-@opindex finstrument-functions-exclude-function-list
-
-This is similar to @code{-finstrument-functions-exclude-file-list},
-but this option sets the list of function names to be excluded from
-instrumentation. The function name to be matched is its user-visible
-name, such as @code{vector<int> blah(const vector<int> &)}, not the
-internal mangled name (e.g., @code{_Z4blahRSt6vectorIiSaIiEE}). The
-match is done on substrings: if the @var{sym} parameter is a substring
-of the function name, it is considered to be a match. For C99 and C++
-extended identifiers, the function name must be given in UTF-8, not
-using universal character names.
-
-@item -fstack-check
-@opindex fstack-check
-Generate code to verify that you do not go beyond the boundary of the
-stack. You should specify this flag if you are running in an
-environment with multiple threads, but you only rarely need to specify it in
-a single-threaded environment since stack overflow is automatically
-detected on nearly all systems if there is only one stack.
-
-Note that this switch does not actually cause checking to be done; the
-operating system or the language runtime must do that. The switch causes
-generation of code to ensure that they see the stack being extended.
-
-You can additionally specify a string parameter: @code{no} means no
-checking, @code{generic} means force the use of old-style checking,
-@code{specific} means use the best checking method and is equivalent
-to bare @option{-fstack-check}.
-
-Old-style checking is a generic mechanism that requires no specific
-target support in the compiler but comes with the following drawbacks:
-
-@enumerate
-@item
-Modified allocation strategy for large objects: they are always
-allocated dynamically if their size exceeds a fixed threshold.
-
-@item
-Fixed limit on the size of the static frame of functions: when it is
-topped by a particular function, stack checking is not reliable and
-a warning is issued by the compiler.
-
-@item
-Inefficiency: because of both the modified allocation strategy and the
-generic implementation, code performance is hampered.
-@end enumerate
-
-Note that old-style stack checking is also the fallback method for
-@code{specific} if no target support has been added in the compiler.
-
-@item -fstack-limit-register=@var{reg}
-@itemx -fstack-limit-symbol=@var{sym}
-@itemx -fno-stack-limit
-@opindex fstack-limit-register
-@opindex fstack-limit-symbol
-@opindex fno-stack-limit
-Generate code to ensure that the stack does not grow beyond a certain value,
-either the value of a register or the address of a symbol. If a larger
-stack is required, a signal is raised at run time. For most targets,
-the signal is raised before the stack overruns the boundary, so
-it is possible to catch the signal without taking special precautions.
-
-For instance, if the stack starts at absolute address @samp{0x80000000}
-and grows downwards, you can use the flags
-@option{-fstack-limit-symbol=__stack_limit} and
-@option{-Wl,--defsym,__stack_limit=0x7ffe0000} to enforce a stack limit
-of 128KB@. Note that this may only work with the GNU linker.
-
-@item -fsplit-stack
-@opindex fsplit-stack
-Generate code to automatically split the stack before it overflows.
-The resulting program has a discontiguous stack which can only
-overflow if the program is unable to allocate any more memory. This
-is most useful when running threaded programs, as it is no longer
-necessary to calculate a good stack size to use for each thread. This
-is currently only implemented for the i386 and x86_64 back ends running
-GNU/Linux.
-
-When code compiled with @option{-fsplit-stack} calls code compiled
-without @option{-fsplit-stack}, there may not be much stack space
-available for the latter code to run. If compiling all code,
-including library code, with @option{-fsplit-stack} is not an option,
-then the linker can fix up these calls so that the code compiled
-without @option{-fsplit-stack} always has a large stack. Support for
-this is implemented in the gold linker in GNU binutils release 2.21
-and later.
-
-@item -fleading-underscore
-@opindex fleading-underscore
-This option and its counterpart, @option{-fno-leading-underscore}, forcibly
-change the way C symbols are represented in the object file. One use
-is to help link with legacy assembly code.
-
-@strong{Warning:} the @option{-fleading-underscore} switch causes GCC to
-generate code that is not binary compatible with code generated without that
-switch. Use it to conform to a non-default application binary interface.
-Not all targets provide complete support for this switch.
-
-@item -ftls-model=@var{model}
-@opindex ftls-model
-Alter the thread-local storage model to be used (@pxref{Thread-Local}).
-The @var{model} argument should be one of @code{global-dynamic},
-@code{local-dynamic}, @code{initial-exec} or @code{local-exec}.
-
-The default without @option{-fpic} is @code{initial-exec}; with
-@option{-fpic} the default is @code{global-dynamic}.
-
-@item -fvisibility=@var{default|internal|hidden|protected}
-@opindex fvisibility
-Set the default ELF image symbol visibility to the specified option---all
-symbols are marked with this unless overridden within the code.
-Using this feature can very substantially improve linking and
-load times of shared object libraries, produce more optimized
-code, provide near-perfect API export and prevent symbol clashes.
-It is @strong{strongly} recommended that you use this in any shared objects
-you distribute.
-
-Despite the nomenclature, @code{default} always means public; i.e.,
-available to be linked against from outside the shared object.
-@code{protected} and @code{internal} are pretty useless in real-world
-usage so the only other commonly used option is @code{hidden}.
-The default if @option{-fvisibility} isn't specified is
-@code{default}, i.e., make every
-symbol public---this causes the same behavior as previous versions of
-GCC@.
-
-A good explanation of the benefits offered by ensuring ELF
-symbols have the correct visibility is given by ``How To Write
-Shared Libraries'' by Ulrich Drepper (which can be found at
-@w{@uref{http://people.redhat.com/~drepper/}})---however a superior
-solution made possible by this option to marking things hidden when
-the default is public is to make the default hidden and mark things
-public. This is the norm with DLLs on Windows and with @option{-fvisibility=hidden}
-and @code{__attribute__ ((visibility("default")))} instead of
-@code{__declspec(dllexport)} you get almost identical semantics with
-identical syntax. This is a great boon to those working with
-cross-platform projects.
-
-For those adding visibility support to existing code, you may find
-@samp{#pragma GCC visibility} of use. This works by you enclosing
-the declarations you wish to set visibility for with (for example)
-@samp{#pragma GCC visibility push(hidden)} and
-@samp{#pragma GCC visibility pop}.
-Bear in mind that symbol visibility should be viewed @strong{as
-part of the API interface contract} and thus all new code should
-always specify visibility when it is not the default; i.e., declarations
-only for use within the local DSO should @strong{always} be marked explicitly
-as hidden as so to avoid PLT indirection overheads---making this
-abundantly clear also aids readability and self-documentation of the code.
-Note that due to ISO C++ specification requirements, @code{operator new} and
-@code{operator delete} must always be of default visibility.
-
-Be aware that headers from outside your project, in particular system
-headers and headers from any other library you use, may not be
-expecting to be compiled with visibility other than the default. You
-may need to explicitly say @samp{#pragma GCC visibility push(default)}
-before including any such headers.
-
-@samp{extern} declarations are not affected by @option{-fvisibility}, so
-a lot of code can be recompiled with @option{-fvisibility=hidden} with
-no modifications. However, this means that calls to @code{extern}
-functions with no explicit visibility use the PLT, so it is more
-effective to use @code{__attribute ((visibility))} and/or
-@code{#pragma GCC visibility} to tell the compiler which @code{extern}
-declarations should be treated as hidden.
-
-Note that @option{-fvisibility} does affect C++ vague linkage
-entities. This means that, for instance, an exception class that is
-be thrown between DSOs must be explicitly marked with default
-visibility so that the @samp{type_info} nodes are unified between
-the DSOs.
-
-An overview of these techniques, their benefits and how to use them
-is at @uref{http://gcc.gnu.org/@/wiki/@/Visibility}.
-
-@item -fstrict-volatile-bitfields
-@opindex fstrict-volatile-bitfields
-This option should be used if accesses to volatile bit-fields (or other
-structure fields, although the compiler usually honors those types
-anyway) should use a single access of the width of the
-field's type, aligned to a natural alignment if possible. For
-example, targets with memory-mapped peripheral registers might require
-all such accesses to be 16 bits wide; with this flag you can
-declare all peripheral bit-fields as @code{unsigned short} (assuming short
-is 16 bits on these targets) to force GCC to use 16-bit accesses
-instead of, perhaps, a more efficient 32-bit access.
-
-If this option is disabled, the compiler uses the most efficient
-instruction. In the previous example, that might be a 32-bit load
-instruction, even though that accesses bytes that do not contain
-any portion of the bit-field, or memory-mapped registers unrelated to
-the one being updated.
-
-If the target requires strict alignment, and honoring the field
-type would require violating this alignment, a warning is issued.
-If the field has @code{packed} attribute, the access is done without
-honoring the field type. If the field doesn't have @code{packed}
-attribute, the access is done honoring the field type. In both cases,
-GCC assumes that the user knows something about the target hardware
-that it is unaware of.
-
-The default value of this option is determined by the application binary
-interface for the target processor.
-
-@item -fsync-libcalls
-@opindex fsync-libcalls
-This option controls whether any out-of-line instance of the @code{__sync}
-family of functions may be used to implement the C++11 @code{__atomic}
-family of functions.
-
-The default value of this option is enabled, thus the only useful form
-of the option is @option{-fno-sync-libcalls}. This option is used in
-the implementation of the @file{libatomic} runtime library.
-
-@end table
-
-@c man end
-
-@node Environment Variables
-@section Environment Variables Affecting GCC
-@cindex environment variables
-
-@c man begin ENVIRONMENT
-This section describes several environment variables that affect how GCC
-operates. Some of them work by specifying directories or prefixes to use
-when searching for various kinds of files. Some are used to specify other
-aspects of the compilation environment.
-
-Note that you can also specify places to search using options such as
-@option{-B}, @option{-I} and @option{-L} (@pxref{Directory Options}). These
-take precedence over places specified using environment variables, which
-in turn take precedence over those specified by the configuration of GCC@.
-@xref{Driver,, Controlling the Compilation Driver @file{gcc}, gccint,
-GNU Compiler Collection (GCC) Internals}.
-
-@table @env
-@item LANG
-@itemx LC_CTYPE
-@c @itemx LC_COLLATE
-@itemx LC_MESSAGES
-@c @itemx LC_MONETARY
-@c @itemx LC_NUMERIC
-@c @itemx LC_TIME
-@itemx LC_ALL
-@findex LANG
-@findex LC_CTYPE
-@c @findex LC_COLLATE
-@findex LC_MESSAGES
-@c @findex LC_MONETARY
-@c @findex LC_NUMERIC
-@c @findex LC_TIME
-@findex LC_ALL
-@cindex locale
-These environment variables control the way that GCC uses
-localization information which allows GCC to work with different
-national conventions. GCC inspects the locale categories
-@env{LC_CTYPE} and @env{LC_MESSAGES} if it has been configured to do
-so. These locale categories can be set to any value supported by your
-installation. A typical value is @samp{en_GB.UTF-8} for English in the United
-Kingdom encoded in UTF-8.
-
-The @env{LC_CTYPE} environment variable specifies character
-classification. GCC uses it to determine the character boundaries in
-a string; this is needed for some multibyte encodings that contain quote
-and escape characters that are otherwise interpreted as a string
-end or escape.
-
-The @env{LC_MESSAGES} environment variable specifies the language to
-use in diagnostic messages.
-
-If the @env{LC_ALL} environment variable is set, it overrides the value
-of @env{LC_CTYPE} and @env{LC_MESSAGES}; otherwise, @env{LC_CTYPE}
-and @env{LC_MESSAGES} default to the value of the @env{LANG}
-environment variable. If none of these variables are set, GCC
-defaults to traditional C English behavior.
-
-@item TMPDIR
-@findex TMPDIR
-If @env{TMPDIR} is set, it specifies the directory to use for temporary
-files. GCC uses temporary files to hold the output of one stage of
-compilation which is to be used as input to the next stage: for example,
-the output of the preprocessor, which is the input to the compiler
-proper.
-
-@item GCC_COMPARE_DEBUG
-@findex GCC_COMPARE_DEBUG
-Setting @env{GCC_COMPARE_DEBUG} is nearly equivalent to passing
-@option{-fcompare-debug} to the compiler driver. See the documentation
-of this option for more details.
-
-@item GCC_EXEC_PREFIX
-@findex GCC_EXEC_PREFIX
-If @env{GCC_EXEC_PREFIX} is set, it specifies a prefix to use in the
-names of the subprograms executed by the compiler. No slash is added
-when this prefix is combined with the name of a subprogram, but you can
-specify a prefix that ends with a slash if you wish.
-
-If @env{GCC_EXEC_PREFIX} is not set, GCC attempts to figure out
-an appropriate prefix to use based on the pathname it is invoked with.
-
-If GCC cannot find the subprogram using the specified prefix, it
-tries looking in the usual places for the subprogram.
-
-The default value of @env{GCC_EXEC_PREFIX} is
-@file{@var{prefix}/lib/gcc/} where @var{prefix} is the prefix to
-the installed compiler. In many cases @var{prefix} is the value
-of @code{prefix} when you ran the @file{configure} script.
-
-Other prefixes specified with @option{-B} take precedence over this prefix.
-
-This prefix is also used for finding files such as @file{crt0.o} that are
-used for linking.
-
-In addition, the prefix is used in an unusual way in finding the
-directories to search for header files. For each of the standard
-directories whose name normally begins with @samp{/usr/local/lib/gcc}
-(more precisely, with the value of @env{GCC_INCLUDE_DIR}), GCC tries
-replacing that beginning with the specified prefix to produce an
-alternate directory name. Thus, with @option{-Bfoo/}, GCC searches
-@file{foo/bar} just before it searches the standard directory
-@file{/usr/local/lib/bar}.
-If a standard directory begins with the configured
-@var{prefix} then the value of @var{prefix} is replaced by
-@env{GCC_EXEC_PREFIX} when looking for header files.
-
-@item COMPILER_PATH
-@findex COMPILER_PATH
-The value of @env{COMPILER_PATH} is a colon-separated list of
-directories, much like @env{PATH}. GCC tries the directories thus
-specified when searching for subprograms, if it can't find the
-subprograms using @env{GCC_EXEC_PREFIX}.
-
-@item LIBRARY_PATH
-@findex LIBRARY_PATH
-The value of @env{LIBRARY_PATH} is a colon-separated list of
-directories, much like @env{PATH}. When configured as a native compiler,
-GCC tries the directories thus specified when searching for special
-linker files, if it can't find them using @env{GCC_EXEC_PREFIX}. Linking
-using GCC also uses these directories when searching for ordinary
-libraries for the @option{-l} option (but directories specified with
-@option{-L} come first).
-
-@item LANG
-@findex LANG
-@cindex locale definition
-This variable is used to pass locale information to the compiler. One way in
-which this information is used is to determine the character set to be used
-when character literals, string literals and comments are parsed in C and C++.
-When the compiler is configured to allow multibyte characters,
-the following values for @env{LANG} are recognized:
-
-@table @samp
-@item C-JIS
-Recognize JIS characters.
-@item C-SJIS
-Recognize SJIS characters.
-@item C-EUCJP
-Recognize EUCJP characters.
-@end table
-
-If @env{LANG} is not defined, or if it has some other value, then the
-compiler uses @code{mblen} and @code{mbtowc} as defined by the default locale to
-recognize and translate multibyte characters.
-@end table
-
-@noindent
-Some additional environment variables affect the behavior of the
-preprocessor.
-
-@include cppenv.texi
-
-@c man end
-
-@node Precompiled Headers
-@section Using Precompiled Headers
-@cindex precompiled headers
-@cindex speed of compilation
-
-Often large projects have many header files that are included in every
-source file. The time the compiler takes to process these header files
-over and over again can account for nearly all of the time required to
-build the project. To make builds faster, GCC allows you to
-@dfn{precompile} a header file.
-
-To create a precompiled header file, simply compile it as you would any
-other file, if necessary using the @option{-x} option to make the driver
-treat it as a C or C++ header file. You may want to use a
-tool like @command{make} to keep the precompiled header up-to-date when
-the headers it contains change.
-
-A precompiled header file is searched for when @code{#include} is
-seen in the compilation. As it searches for the included file
-(@pxref{Search Path,,Search Path,cpp,The C Preprocessor}) the
-compiler looks for a precompiled header in each directory just before it
-looks for the include file in that directory. The name searched for is
-the name specified in the @code{#include} with @samp{.gch} appended. If
-the precompiled header file can't be used, it is ignored.
-
-For instance, if you have @code{#include "all.h"}, and you have
-@file{all.h.gch} in the same directory as @file{all.h}, then the
-precompiled header file is used if possible, and the original
-header is used otherwise.
-
-Alternatively, you might decide to put the precompiled header file in a
-directory and use @option{-I} to ensure that directory is searched
-before (or instead of) the directory containing the original header.
-Then, if you want to check that the precompiled header file is always
-used, you can put a file of the same name as the original header in this
-directory containing an @code{#error} command.
-
-This also works with @option{-include}. So yet another way to use
-precompiled headers, good for projects not designed with precompiled
-header files in mind, is to simply take most of the header files used by
-a project, include them from another header file, precompile that header
-file, and @option{-include} the precompiled header. If the header files
-have guards against multiple inclusion, they are skipped because
-they've already been included (in the precompiled header).
-
-If you need to precompile the same header file for different
-languages, targets, or compiler options, you can instead make a
-@emph{directory} named like @file{all.h.gch}, and put each precompiled
-header in the directory, perhaps using @option{-o}. It doesn't matter
-what you call the files in the directory; every precompiled header in
-the directory is considered. The first precompiled header
-encountered in the directory that is valid for this compilation is
-used; they're searched in no particular order.
-
-There are many other possibilities, limited only by your imagination,
-good sense, and the constraints of your build system.
-
-A precompiled header file can be used only when these conditions apply:
-
-@itemize
-@item
-Only one precompiled header can be used in a particular compilation.
-
-@item
-A precompiled header can't be used once the first C token is seen. You
-can have preprocessor directives before a precompiled header; you cannot
-include a precompiled header from inside another header.
-
-@item
-The precompiled header file must be produced for the same language as
-the current compilation. You can't use a C precompiled header for a C++
-compilation.
-
-@item
-The precompiled header file must have been produced by the same compiler
-binary as the current compilation is using.
-
-@item
-Any macros defined before the precompiled header is included must
-either be defined in the same way as when the precompiled header was
-generated, or must not affect the precompiled header, which usually
-means that they don't appear in the precompiled header at all.
-
-The @option{-D} option is one way to define a macro before a
-precompiled header is included; using a @code{#define} can also do it.
-There are also some options that define macros implicitly, like
-@option{-O} and @option{-Wdeprecated}; the same rule applies to macros
-defined this way.
-
-@item If debugging information is output when using the precompiled
-header, using @option{-g} or similar, the same kind of debugging information
-must have been output when building the precompiled header. However,
-a precompiled header built using @option{-g} can be used in a compilation
-when no debugging information is being output.
-
-@item The same @option{-m} options must generally be used when building
-and using the precompiled header. @xref{Submodel Options},
-for any cases where this rule is relaxed.
-
-@item Each of the following options must be the same when building and using
-the precompiled header:
-
-@gccoptlist{-fexceptions}
-
-@item
-Some other command-line options starting with @option{-f},
-@option{-p}, or @option{-O} must be defined in the same way as when
-the precompiled header was generated. At present, it's not clear
-which options are safe to change and which are not; the safest choice
-is to use exactly the same options when generating and using the
-precompiled header. The following are known to be safe:
-
-@gccoptlist{-fmessage-length= -fpreprocessed -fsched-interblock @gol
--fsched-spec -fsched-spec-load -fsched-spec-load-dangerous @gol
--fsched-verbose=@var{number} -fschedule-insns -fvisibility= @gol
--pedantic-errors}
-
-@end itemize
-
-For all of these except the last, the compiler automatically
-ignores the precompiled header if the conditions aren't met. If you
-find an option combination that doesn't work and doesn't cause the
-precompiled header to be ignored, please consider filing a bug report,
-see @ref{Bugs}.
-
-If you do use differing options when generating and using the
-precompiled header, the actual behavior is a mixture of the
-behavior for the options. For instance, if you use @option{-g} to
-generate the precompiled header but not when using it, you may or may
-not get debugging information for routines in the precompiled header.
diff --git a/gcc-4.8/libgcc/config.host.orig b/gcc-4.8/libgcc/config.host.orig
deleted file mode 100644
index 6bd4b3936..000000000
--- a/gcc-4.8/libgcc/config.host.orig
+++ /dev/null
@@ -1,1170 +0,0 @@
-# libgcc host-specific configuration file.
-# Copyright (C) 1997-2013 Free Software Foundation, Inc.
-
-#This file is part of GCC.
-
-#GCC is free software; you can redistribute it and/or modify it under
-#the terms of the GNU General Public License as published by the Free
-#Software Foundation; either version 3, or (at your option) any later
-#version.
-
-#GCC is distributed in the hope that it will be useful, but WITHOUT
-#ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-#FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-#for more details.
-
-#You should have received a copy of the GNU General Public License
-#along with GCC; see the file COPYING3. If not see
-#<http://www.gnu.org/licenses/>.
-
-# This is the libgcc host-specific configuration file
-# where a configuration type is mapped to different system-specific
-# definitions and files. This is invoked by the autoconf-generated
-# configure script. Putting it in a separate shell file lets us skip
-# running autoconf when modifying host-specific information.
-
-# This file bears an obvious resemblance to gcc/config.gcc. The cases
-# should be kept similar, to ease moving library-specific settings
-# from config.gcc to this file. That is also why tmake_file is
-# left as tmake_file, rather than hmake_file, even though this library
-# switches on ${host}.
-
-# This file switches on the shell variable ${host}, and also uses the
-# following shell variables:
-#
-# with_* Various variables as set by configure.
-
-# This file sets the following shell variables for use by the
-# autoconf-generated configure script:
-#
-# asm_hidden_op The assembler pseudo-op to use for hide
-# lists for object files implemented in
-# assembly (with -fvisibility=hidden for C).
-# The default is ".hidden".
-# cpu_type The name of the cpu, if different from the first
-# chunk of the canonical host name.
-# enable_execute_stack The name of a source file implementing
-# __enable_execute_stack.
-# extra_parts List of extra object files that should be compiled
-# for this target machine. This may be overridden
-# by setting EXTRA_PARTS in a tmake_file fragment.
-# If either is set, EXTRA_PARTS and
-# EXTRA_MULTILIB_PARTS inherited from the GCC
-# subdirectory will be ignored.
-# md_unwind_header The name of a header file defining
-# MD_FALLBACK_FRAME_STATE_FOR.
-# sfp_machine_header The name of a sfp-machine.h header file for soft-fp.
-# Defaults to "$cpu_type/sfp-machine.h" if it exists,
-# no-sfp-machine.h otherwise.
-# tmake_file A list of machine-description-specific
-# makefile fragments.
-# tm_defines List of target macros to define for all compilations.
-# tm_file A list of target macro files used only for code
-# built for the target, not the host. These files
-# are relative to $srcdir/config and must not have
-# the same names as files in $srcdir/../gcc/config.
-# unwind_header The name of the header file declaring the unwind
-# runtime interface routines.
-
-asm_hidden_op=.hidden
-enable_execute_stack=
-extra_parts=
-tmake_file=
-tm_file=
-tm_define=
-md_unwind_header=no-unwind.h
-unwind_header=unwind-generic.h
-
-# Set default cpu_type so it can be updated in each machine entry.
-cpu_type=`echo ${host} | sed 's/-.*$//'`
-case ${host} in
-m32c*-*-*)
- cpu_type=m32c
- tmake_file=t-fdpbit
- ;;
-aarch64*-*-*)
- cpu_type=aarch64
- ;;
-alpha*-*-*)
- cpu_type=alpha
- ;;
-am33_2.0-*-linux*)
- cpu_type=mn10300
- ;;
-arm*-*-*)
- cpu_type=arm
- ;;
-avr-*-*)
- cpu_type=avr
- ;;
-bfin*-*)
- cpu_type=bfin
- ;;
-cr16-*-*)
- ;;
-fido-*-*)
- cpu_type=m68k
- ;;
-frv*) cpu_type=frv
- ;;
-moxie*) cpu_type=moxie
- ;;
-i[34567]86-*-*)
- cpu_type=i386
- ;;
-x86_64-*-*)
- cpu_type=i386
- ;;
-ia64-*-*)
- ;;
-hppa*-*-*)
- cpu_type=pa
- ;;
-lm32*-*-*)
- cpu_type=lm32
- ;;
-m32r*-*-*)
- cpu_type=m32r
- ;;
-m68k-*-*)
- ;;
-mep*-*-*)
- ;;
-microblaze*-*-*)
- cpu_type=microblaze
- ;;
-mips*-*-*)
- cpu_type=mips
- tmake_file=mips/t-mips
- ;;
-powerpc*-*-*)
- cpu_type=rs6000
- ;;
-rs6000*-*-*)
- ;;
-score*-*-*)
- cpu_type=score
- ;;
-sparc64*-*-*)
- cpu_type=sparc
- ;;
-sparc*-*-*)
- cpu_type=sparc
- ;;
-spu*-*-*)
- cpu_type=spu
- ;;
-s390*-*-*)
- cpu_type=s390
- ;;
-# Note the 'l'; we need to be able to match e.g. "shle" or "shl".
-sh[123456789lbe]*-*-*)
- cpu_type=sh
- ;;
-v850*-*-*)
- cpu_type=v850
- ;;
-tic6x-*-*)
- cpu_type=c6x
- ;;
-esac
-
-# Common parts for widely ported systems.
-case ${host} in
-*-*-darwin*)
- asm_hidden_op=.private_extern
- tmake_file="$tmake_file t-darwin ${cpu_type}/t-darwin t-libgcc-pic t-slibgcc-darwin"
- extra_parts="crt3.o crttms.o crttme.o"
- ;;
-*-*-freebsd*)
- # This is the generic ELF configuration of FreeBSD. Later
- # machine-specific sections may refine and add to this
- # configuration.
- tmake_file="$tmake_file t-freebsd t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver"
- extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o"
- case ${target_thread_file} in
- posix)
- tmake_file="${tmake_file} t-freebsd-thread"
- # Before 5.0, FreeBSD can't bind shared libraries to -lc
- # when "optionally" threaded via weak pthread_* checks.
- case ${host} in
- *-*-freebsd[34] | *-*-freebsd[34].*)
- tmake_file="${tmake_file} t-slibgcc-nolc-override"
- ;;
- esac
- ;;
- esac
- ;;
-*-*-linux* | frv-*-*linux* | *-*-kfreebsd*-gnu | *-*-knetbsd*-gnu | *-*-gnu* | *-*-kopensolaris*-gnu)
- tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver t-linux"
- extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
- ;;
-*-*-lynxos*)
- tmake_file="$tmake_file t-lynx $cpu_type/t-crtstuff t-crtstuff-pic t-libgcc-pic"
- extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
- ;;
-*-*-netbsd*)
- tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver"
- # NetBSD 1.7 and later are set up to use GCC's crtstuff for
- # ELF configurations. We will clear extra_parts in the
- # a.out configurations.
- case ${host} in
- *-*-netbsd*1.[7-9]* | *-*-netbsd[2-9]* | *-*-netbsdelf[2-9]*)
- extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
- ;;
- esac
- ;;
-*-*-openbsd*)
- tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip"
- case ${target_thread_file} in
- posix)
- tmake_file="$tmake_file t-openbsd-thread"
- ;;
- esac
- ;;
-*-*-rtems*)
- tmake_file="$tmake_file t-rtems"
- extra_parts="crtbegin.o crtend.o"
- ;;
-*-*-solaris2*)
- # Unless linker support and dl_iterate_phdr are present,
- # unwind-dw2-fde-dip.c automatically falls back to unwind-dw2-fde.c.
- tmake_file="$tmake_file t-sol2 t-eh-dw2-dip t-libgcc-pic t-slibgcc t-slibgcc-elf-ver"
- if test $with_gnu_ld = yes; then
- tmake_file="$tmake_file t-slibgcc-gld"
- else
- tmake_file="$tmake_file t-slibgcc-sld"
- fi
- # Add cpu-specific t-sol2 after t-slibgcc-* so it can augment SHLIB_MAPFILES.
- tmake_file="$tmake_file $cpu_type/t-sol2"
- extra_parts="gmon.o crtbegin.o crtend.o"
- case ${host} in
- i?86-*-solaris2.1[0-9]* | x86_64-*-solaris2.1[0-9]*)
- # Solaris 10+/x86 provides crt1.o, crti.o, crtn.o, and gcrt1.o as
- # part of the base system.
- ;;
- sparc*-*-solaris2.1[0-9]*)
- # Solaris 10+/SPARC lacks crt1.o and gcrt1.o.
- extra_parts="$extra_parts crt1.o gcrt1.o"
- ;;
- *)
- extra_parts="$extra_parts crt1.o crti.o crtn.o gcrt1.o"
- ;;
- esac
- ;;
-*-*-uclinux*)
- extra_parts="crtbegin.o crtend.o"
- ;;
-*-*-*vms*)
- tmake_file="vms/t-vms"
- extra_parts="crt0.o crtbegin.o crtbeginS.o crtend.o crtendS.o"
- ;;
-*-*-vxworks*)
- tmake_file=t-vxworks
- ;;
-*-*-elf)
- extra_parts="crtbegin.o crtend.o"
- ;;
-esac
-
-case ${host} in
-*-*-darwin* | *-*-freebsd* | *-*-netbsd* | *-*-openbsd* | *-*-solaris2*)
- enable_execute_stack=enable-execute-stack-mprotect.c
- ;;
-i[34567]86-*-mingw* | x86_64-*-mingw*)
- enable_execute_stack=config/i386/enable-execute-stack-mingw32.c
- ;;
-*)
- enable_execute_stack=enable-execute-stack-empty.c;
- ;;
-esac
-
-case ${host} in
-aarch64*-*-elf)
- extra_parts="$extra_parts crtbegin.o crtend.o crti.o crtn.o"
- tmake_file="${tmake_file} ${cpu_type}/t-aarch64"
- tmake_file="${tmake_file} ${cpu_type}/t-softfp t-softfp"
- ;;
-aarch64*-*-linux*-android*)
- #md_unwind_header=aarch64/linux-unwind.h # disable this for now since bionic isn't 64-bit ready yet
- tmake_file="${tmake_file} ${cpu_type}/t-aarch64"
- tmake_file="${tmake_file} ${cpu_type}/t-softfp t-softfp"
- ;;
-aarch64*-*-linux*)
- md_unwind_header=aarch64/linux-unwind.h
- tmake_file="${tmake_file} ${cpu_type}/t-aarch64"
- tmake_file="${tmake_file} ${cpu_type}/t-softfp t-softfp"
- ;;
-alpha*-*-linux*)
- tmake_file="${tmake_file} alpha/t-alpha alpha/t-ieee t-crtfm alpha/t-linux"
- extra_parts="$extra_parts crtfastmath.o"
- md_unwind_header=alpha/linux-unwind.h
- ;;
-alpha*-*-freebsd*)
- tmake_file="${tmake_file} alpha/t-alpha alpha/t-ieee t-crtfm"
- extra_parts="$extra_parts crtbeginT.o crtfastmath.o"
- ;;
-alpha*-*-netbsd*)
- tmake_file="${tmake_file} alpha/t-alpha alpha/t-ieee"
- ;;
-alpha*-*-openbsd*)
- tmake_file="${tmake_file} alpha/t-alpha alpha/t-ieee"
- ;;
-alpha64-dec-*vms*)
- tmake_file="$tmake_file alpha/t-alpha alpha/t-ieee alpha/t-vms t-slibgcc-vms"
- extra_parts="$extra_parts vms-dwarf2.o vms-dwarf2eh.o"
- md_unwind_header=alpha/vms-unwind.h
- ;;
-alpha*-dec-*vms*)
- tmake_file="$tmake_file alpha/t-alpha alpha/t-ieee alpha/t-vms t-slibgcc-vms"
- extra_parts="$extra_parts vms-dwarf2.o vms-dwarf2eh.o"
- md_unwind_header=alpha/vms-unwind.h
- ;;
-arm-wrs-vxworks)
- tmake_file="$tmake_file arm/t-arm arm/t-vxworks t-fdpbit"
- extra_parts="$extra_parts crti.o crtn.o"
- ;;
-arm*-*-netbsdelf*)
- tmake_file="$tmake_file arm/t-arm arm/t-netbsd t-slibgcc-gld-nover"
- ;;
-arm*-*-linux*) # ARM GNU/Linux with ELF
- tmake_file="${tmake_file} arm/t-arm t-fixedpoint-gnu-prefix"
- tmake_file="${tmake_file} arm/t-elf arm/t-bpabi arm/t-linux-eabi t-slibgcc-libgcc"
- tm_file="$tm_file arm/bpabi-lib.h"
- unwind_header=config/arm/unwind-arm.h
- tmake_file="$tmake_file t-softfp-sfdf t-softfp-excl arm/t-softfp t-softfp"
- ;;
-arm*-*-uclinux*) # ARM ucLinux
- tmake_file="${tmake_file} t-fixedpoint-gnu-prefix"
- tmake_file="${tmake_file} arm/t-bpabi"
- tm_file="$tm_file arm/bpabi-lib.h"
- unwind_header=config/arm/unwind-arm.h
- tmake_file="$tmake_file arm/t-arm arm/t-elf t-softfp-sfdf t-softfp-excl arm/t-softfp t-softfp"
- extra_parts="$extra_parts crti.o crtn.o"
- ;;
-arm*-*-eabi* | arm*-*-symbianelf* | arm*-*-rtems*)
- tmake_file="${tmake_file} arm/t-arm arm/t-elf t-fixedpoint-gnu-prefix"
- tm_file="$tm_file arm/bpabi-lib.h"
- case ${host} in
- arm*-*-eabi* | arm*-*-rtems*)
- tmake_file="${tmake_file} arm/t-bpabi"
- extra_parts="crtbegin.o crtend.o crti.o crtn.o"
- ;;
- arm*-*-symbianelf*)
- tmake_file="${tmake_file} arm/t-symbian t-slibgcc-nolc-override"
- tm_file="$tm_file arm/symbian-lib.h"
- # Symbian OS provides its own startup code.
- ;;
- esac
- tmake_file="$tmake_file t-softfp-sfdf t-softfp-excl arm/t-softfp t-softfp"
- unwind_header=config/arm/unwind-arm.h
- ;;
-avr-*-rtems*)
- tmake_file="$tmake_file avr/t-avr avr/t-rtems t-fpbit"
- tm_file="$tm_file avr/avr-lib.h"
- # Don't use default.
- extra_parts=
- ;;
-avr-*-*)
- # Make HImode functions for AVR
- tmake_file="${cpu_type}/t-avr t-fpbit"
- if test x${with_avrlibc} != xno; then
- tmake_file="$tmake_file ${cpu_type}/t-avrlibc"
- fi
- tm_file="$tm_file avr/avr-lib.h"
- ;;
-bfin*-elf*)
- tmake_file="bfin/t-bfin bfin/t-crtlibid bfin/t-crtstuff t-libgcc-pic t-fdpbit"
- extra_parts="$extra_parts crtbeginS.o crtendS.o crti.o crtn.o crtlibid.o"
- ;;
-bfin*-uclinux*)
- tmake_file="bfin/t-bfin bfin/t-crtlibid bfin/t-crtstuff t-libgcc-pic t-fdpbit"
- extra_parts="$extra_parts crtbeginS.o crtendS.o crtlibid.o"
- md_unwind_header=bfin/linux-unwind.h
- ;;
-bfin*-linux-uclibc*)
- tmake_file="$tmake_file bfin/t-bfin bfin/t-crtstuff t-libgcc-pic t-fdpbit bfin/t-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"
- md_unwind_header=bfin/linux-unwind.h
- ;;
-bfin*-rtems*)
- tmake_file="$tmake_file bfin/t-bfin t-fdpbit"
- extra_parts="$extra_parts crti.o crtn.o"
- ;;
-bfin*-*)
- tmake_file="$tmake_file bfin/t-bfin t-fdpbit"
- extra_parts="crtbegin.o crtend.o crti.o crtn.o"
- ;;
-cr16-*-elf)
- tmake_file="${tmake_file} cr16/t-cr16 cr16/t-crtlibid t-fdpbit"
- extra_parts="$extra_parts crti.o crtn.o crtlibid.o"
- ;;
-crisv32-*-elf)
- tmake_file="$tmake_file cris/t-cris t-fdpbit"
- ;;
-cris-*-elf)
- tmake_file="$tmake_file cris/t-cris t-fdpbit cris/t-elfmulti"
- ;;
-cris-*-linux* | crisv32-*-linux*)
- tmake_file="$tmake_file cris/t-cris t-fdpbit cris/t-linux"
- ;;
-epiphany-*-elf*)
- tmake_file="epiphany/t-epiphany t-fdpbit epiphany/t-custom-eqsf"
- extra_parts="$extra_parts crti.o crtint.o crtrunc.o crtm1reg-r43.o crtm1reg-r63.o crtn.o"
- ;;
-fr30-*-elf)
- tmake_file="$tmake_file fr30/t-fr30 t-fdpbit"
- extra_parts="$extra_parts crti.o crtn.o"
- ;;
-frv-*-elf)
- tmake_file="$tmake_file frv/t-frv t-fdpbit"
- tm_file="$tm_file frv/frv-abi.h"
- # Don't use crtbegin.o, crtend.o.
- extra_parts="frvbegin.o frvend.o"
- ;;
-frv-*-*linux*)
- tmake_file="$tmake_file frv/t-frv frv/t-linux t-fdpbit"
- tm_file="$tm_file frv/frv-abi.h"
- ;;
-h8300-*-rtems*)
- tmake_file="$tmake_file h8300/t-h8300 t-fpbit"
- tm_file="$tm_file h8300/h8300-lib.h"
- extra_parts="$extra_parts crti.o crtn.o"
- ;;
-h8300-*-elf*)
- tmake_file="$tmake_file h8300/t-h8300 t-fpbit"
- tm_file="$tm_file h8300/h8300-lib.h"
- extra_parts="$extra_parts crti.o crtn.o"
- ;;
-hppa*64*-*-linux*)
- tmake_file="$tmake_file pa/t-linux pa/t-linux64"
- ;;
-hppa*-*-linux*)
- tmake_file="$tmake_file pa/t-linux t-slibgcc-libgcc"
- # Set the libgcc version number
- if test x$enable_sjlj_exceptions = xyes; then
- tmake_file="$tmake_file pa/t-slibgcc-sjlj-ver"
- else
- tmake_file="$tmake_file pa/t-slibgcc-dwarf-ver"
- fi
- md_unwind_header=pa/linux-unwind.h
- ;;
-hppa[12]*-*-hpux10*)
- tmake_file="$tmake_file pa/t-hpux pa/t-hpux10 t-libgcc-pic t-slibgcc"
- # Set the libgcc version number
- if test x$enable_sjlj_exceptions = xyes; then
- tmake_file="$tmake_file pa/t-slibgcc-sjlj-ver"
- else
- tmake_file="$tmake_file pa/t-slibgcc-dwarf-ver"
- fi
- tmake_file="$tmake_file pa/t-slibgcc-hpux t-slibgcc-hpux"
- md_unwind_header=pa/hpux-unwind.h
- ;;
-hppa*64*-*-hpux11*)
- tmake_file="$tmake_file pa/t-hpux pa/t-pa64 pa/t-stublib t-libgcc-pic t-slibgcc"
- # Set the libgcc version number
- if test x$enable_sjlj_exceptions = xyes; then
- tmake_file="$tmake_file pa/t-slibgcc-sjlj-ver"
- else
- tmake_file="$tmake_file pa/t-slibgcc-dwarf-ver"
- fi
- tmake_file="$tmake_file pa/t-slibgcc-hpux t-slibgcc-hpux"
- extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o \
- libgcc_stub.a"
- md_unwind_header=pa/hpux-unwind.h
- ;;
-hppa[12]*-*-hpux11*)
- tmake_file="$tmake_file pa/t-hpux pa/t-stublib t-libgcc-pic t-slibgcc"
- # Set the libgcc version number
- if test x$enable_sjlj_exceptions = xyes; then
- tmake_file="$tmake_file pa/t-slibgcc-sjlj-ver"
- else
- tmake_file="$tmake_file pa/t-slibgcc-dwarf-ver"
- fi
- tmake_file="$tmake_file pa/t-slibgcc-hpux t-slibgcc-hpux"
- extra_parts="libgcc_stub.a"
- md_unwind_header=pa/hpux-unwind.h
- ;;
-hppa*-*-openbsd*)
- tmake_file="$tmake_file pa/t-openbsd"
- ;;
-i[34567]86-*-darwin*)
- tmake_file="$tmake_file i386/t-crtpc i386/t-crtfm"
- tm_file="$tm_file i386/darwin-lib.h"
- extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o"
- ;;
-x86_64-*-darwin*)
- tmake_file="$tmake_file i386/t-crtpc i386/t-crtfm"
- tm_file="$tm_file i386/darwin-lib.h"
- extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o"
- ;;
-i[34567]86-*-elf*)
- tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic"
- ;;
-x86_64-*-elf*)
- tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic"
- ;;
-i[34567]86-*-freebsd*)
- tmake_file="${tmake_file} i386/t-freebsd i386/t-crtstuff"
- ;;
-x86_64-*-freebsd*)
- tmake_file="${tmake_file} i386/t-freebsd i386/t-crtstuff"
- ;;
-i[34567]86-*-netbsdelf*)
- ;;
-x86_64-*-netbsd*)
- tmake_file="${tmake_file} i386/t-crtstuff"
- ;;
-i[34567]86-*-openbsd2.*|i[34567]86-*openbsd3.[0123])
- ;;
-i[34567]86-*-openbsd*)
- ;;
-x86_64-*-openbsd*)
- ;;
-i[34567]86-*-linux*)
- extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o"
- tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm i386/t-crtstuff t-dfprules"
- md_unwind_header=i386/linux-unwind.h
- ;;
-i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-knetbsd*-gnu | i[34567]86-*-gnu* | i[34567]86-*-kopensolaris*-gnu)
- extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o"
- tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm i386/t-crtstuff t-dfprules"
- ;;
-x86_64-*-linux*)
- extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o"
- tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm i386/t-crtstuff t-dfprules"
- md_unwind_header=i386/linux-unwind.h
- ;;
-x86_64-*-kfreebsd*-gnu | x86_64-*-knetbsd*-gnu)
- extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o"
- tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm i386/t-crtstuff t-dfprules"
- ;;
-i[34567]86-pc-msdosdjgpp*)
- ;;
-i[34567]86-*-lynxos*)
- ;;
-i[34567]86-*-nto-qnx*)
- tmake_file="$tmake_file i386/t-nto t-libgcc-pic"
- extra_parts=crtbegin.o
- ;;
-i[34567]86-*-rtems*)
- tmake_file="$tmake_file i386/t-softfp i386/t-crtstuff"
- extra_parts="$extra_parts crti.o crtn.o"
- ;;
-i[34567]86-*-solaris2* | x86_64-*-solaris2.1[0-9]*)
- tmake_file="$tmake_file i386/t-crtpc i386/t-crtfm"
- extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o"
- md_unwind_header=i386/sol2-unwind.h
- ;;
-i[4567]86-wrs-vxworks|i[4567]86-wrs-vxworksae)
- ;;
-i[34567]86-*-cygwin*)
- extra_parts="crtbegin.o crtend.o crtfastmath.o"
- # This has to match the logic for DWARF2_UNWIND_INFO in gcc/config/i386/cygming.h
- if test x$enable_sjlj_exceptions = xyes; then
- tmake_eh_file="i386/t-sjlj-eh"
- else
- tmake_eh_file="i386/t-dw2-eh"
- fi
- # Shared libgcc DLL install dir depends on cross/native build.
- if test x${build} = x${host} ; then
- tmake_dlldir_file="i386/t-dlldir"
- else
- tmake_dlldir_file="i386/t-dlldir-x"
- fi
- tmake_file="${tmake_file} ${tmake_eh_file} ${tmake_dlldir_file} i386/t-slibgcc-cygming i386/t-cygming i386/t-cygwin i386/t-crtfm i386/t-chkstk t-dfprules"
- ;;
-i[34567]86-*-mingw*)
- extra_parts="crtbegin.o crtend.o crtfastmath.o"
- case ${target_thread_file} in
- win32)
- tmake_file="$tmake_file i386/t-gthr-win32"
- ;;
- posix)
- tmake_file="i386/t-mingw-pthread $tmake_file"
- ;;
- esac
- # This has to match the logic for DWARF2_UNWIND_INFO in gcc/config/i386/cygming.h
- if test x$enable_sjlj_exceptions = xyes; then
- tmake_eh_file="i386/t-sjlj-eh"
- else
- tmake_eh_file="i386/t-dw2-eh"
- md_unwind_header=i386/w32-unwind.h
- fi
- # Shared libgcc DLL install dir depends on cross/native build.
- if test x${build} = x${host} ; then
- tmake_dlldir_file="i386/t-dlldir"
- else
- tmake_dlldir_file="i386/t-dlldir-x"
- fi
- tmake_file="${tmake_file} ${tmake_eh_file} ${tmake_dlldir_file} i386/t-slibgcc-cygming i386/t-cygming i386/t-mingw32 i386/t-crtfm i386/t-chkstk t-dfprules"
- ;;
-x86_64-*-mingw*)
- case ${target_thread_file} in
- win32)
- tmake_file="$tmake_file i386/t-gthr-win32"
- ;;
- posix)
- tmake_file="i386/t-mingw-pthread $tmake_file"
- ;;
- esac
- # This has to match the logic for DWARF2_UNWIND_INFO in gcc/config/i386/cygming.h
- if test x$enable_sjlj_exceptions = xyes; then
- tmake_eh_file="i386/t-sjlj-eh"
- else
- tmake_eh_file="i386/t-seh-eh"
- fi
- # Shared libgcc DLL install dir depends on cross/native build.
- if test x${build} = x${host} ; then
- tmake_dlldir_file="i386/t-dlldir"
- else
- tmake_dlldir_file="i386/t-dlldir-x"
- fi
- tmake_file="${tmake_file} ${tmake_eh_file} ${tmake_dlldir_file} i386/t-slibgcc-cygming i386/t-mingw32 t-dfprules i386/t-crtfm i386/t-chkstk"
- extra_parts="$extra_parts crtfastmath.o"
- ;;
-i[34567]86-*-interix[3-9]*)
- tmake_file="$tmake_file i386/t-interix i386/t-chkstk"
- ;;
-ia64*-*-elf*)
- extra_parts="$extra_parts crtbeginS.o crtendS.o crtfastmath.o"
- tmake_file="ia64/t-ia64 ia64/t-ia64-elf ia64/t-eh-ia64 t-crtfm"
- ;;
-ia64*-*-freebsd*)
- extra_parts="$extra_parts crtfastmath.o"
- tmake_file="$tmake_file ia64/t-ia64 ia64/t-ia64-elf ia64/t-eh-ia64 t-crtfm"
- ;;
-ia64*-*-linux*)
- # Don't use crtbeginT.o from *-*-linux* default.
- extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtfastmath.o"
- tmake_file="$tmake_file ia64/t-ia64 ia64/t-ia64-elf t-crtfm t-softfp-tf ia64/t-softfp t-softfp ia64/t-softfp-compat ia64/t-eh-ia64 t-libunwind ia64/t-linux"
- if test x$with_system_libunwind != xyes ; then
- tmake_file="${tmake_file} t-libunwind-elf ia64/t-linux-libunwind"
- fi
- md_unwind_header=ia64/linux-unwind.h
- ;;
-ia64*-*-hpux*)
- tmake_file="ia64/t-ia64 ia64/t-ia64-elf ia64/t-hpux t-slibgcc ia64/t-slibgcc-hpux t-slibgcc-hpux"
- ;;
-ia64-hp-*vms*)
- tmake_file="$tmake_file ia64/t-ia64 ia64/t-eh-ia64 ia64/t-vms t-slibgcc-vms"
- extra_parts="$extra_parts crtinitS.o"
- md_unwind_header=ia64/vms-unwind.h
- ;;
-iq2000*-*-elf*)
- tmake_file="iq2000/t-iq2000 t-fdpbit"
- # Don't use default.
- extra_parts=
- ;;
-lm32-*-elf*)
- extra_parts="$extra_parts crti.o crtn.o"
- tmake_file="lm32/t-lm32 lm32/t-elf t-softfp-sfdf t-softfp"
- ;;
-lm32-*-rtems*)
- tmake_file="$tmake_file lm32/t-lm32 lm32/t-elf t-softfp-sfdf t-softfp"
- extra_parts="$extra_parts crti.o crtn.o"
- ;;
-lm32-*-uclinux*)
- extra_parts="$extra_parts crtbegin.o crtendS.o crtbeginT.o"
- tmake_file="lm32/t-lm32 lm32/t-uclinux t-libgcc-pic t-softfp-sfdf t-softfp"
- ;;
-m32r-*-elf*)
- tmake_file=t-fdpbit
- ;;
-m32r-*-rtems*)
- tmake_file="$tmake_file m32r/t-m32r t-fdpbit"
- extra_parts="$extra_parts crtinit.o crtfini.o"
- ;;
-m32rle-*-elf*)
- tmake_file=t-fdpbit
- ;;
-m32r-*-linux*)
- tmake_file="$tmake_file m32r/t-linux t-fdpbit"
- ;;
-m32rle-*-linux*)
- tmake_file="$tmake_file m32r/t-linux t-fdpbit"
- ;;
-m68k-*-elf* | fido-*-elf)
- tmake_file="$tmake_file m68k/t-floatlib"
- ;;
-m68k*-*-netbsdelf*)
- ;;
-m68k*-*-openbsd*)
- ;;
-m68k-*-uclinux*) # Motorola m68k/ColdFire running uClinux with uClibc
- tmake_file="$tmake_file m68k/t-floatlib m68k/t-linux"
- md_unwind_header=m68k/linux-unwind.h
- ;;
-m68k-*-linux*) # Motorola m68k's running GNU/Linux
- # with ELF format using glibc 2
- # aka the GNU/Linux C library 6.
- tmake_file="$tmake_file m68k/t-floatlib m68k/t-linux"
- # If not configured with --enable-sjlj-exceptions, bump the
- # libgcc version number.
- if test x$enable_sjlj_exceptions != xyes; then
- tmake_file="$tmake_file m68k/t-slibgcc-elf-ver"
- fi
- md_unwind_header=m68k/linux-unwind.h
- ;;
-m68k-*-rtems*)
- tmake_file="$tmake_file m68k/t-floatlib"
- extra_parts="$extra_parts crti.o crtn.o"
- ;;
-mcore-*-elf)
- tmake_file="mcore/t-mcore t-fdpbit"
- extra_parts="$extra_parts crti.o crtn.o"
- ;;
-microblaze*-linux*)
- tmake_file="${tmake_file} microblaze/t-microblaze t-fdpbit t-slibgcc-libgcc"
- ;;
-microblaze*-*-elf)
- tmake_file="${tmake_file} microblaze/t-microblaze t-fdpbit"
- extra_parts="$extra_parts crtbeginS.o crtendS.o crtbeginT.o crti.o crtn.o"
- ;;
-mips*-*-netbsd*) # NetBSD/mips, either endian.
- ;;
-mips*-*-linux*) # Linux MIPS, either endian.
- extra_parts="$extra_parts crtfastmath.o"
- tmake_file="${tmake_file} t-crtfm mips/t-mips16"
- md_unwind_header=mips/linux-unwind.h
- if test "${ac_cv_sizeof_long_double}" = 16; then
- tmake_file="${tmake_file} mips/t-tpbit"
- fi
- ;;
-mips*-sde-elf*)
- tmake_file="$tmake_file mips/t-crtstuff mips/t-mips16"
- case "${with_newlib}" in
- yes)
- # newlib / libgloss.
- ;;
- *)
- # MIPS toolkit libraries.
- tmake_file="$tmake_file mips/t-sdemtk"
- ;;
- esac
- extra_parts="$extra_parts crti.o crtn.o"
- ;;
-mipsisa32-*-elf* | mipsisa32el-*-elf* | \
-mipsisa32r2-*-elf* | mipsisa32r2el-*-elf* | \
-mipsisa64-*-elf* | mipsisa64el-*-elf* | \
-mipsisa64r2-*-elf* | mipsisa64r2el-*-elf*)
- tmake_file="$tmake_file mips/t-elf mips/t-crtstuff mips/t-mips16"
- extra_parts="$extra_parts crti.o crtn.o"
- ;;
-mipsisa64sr71k-*-elf*)
- tmake_file="$tmake_file mips/t-elf mips/t-crtstuff t-fdpbit"
- extra_parts="$extra_parts crti.o crtn.o"
- ;;
-mipsisa64sb1-*-elf* | mipsisa64sb1el-*-elf*)
- tmake_file="$tmake_file mips/t-elf mips/t-crtstuff mips/t-mips16"
- extra_parts="$extra_parts crti.o crtn.o"
- ;;
-mips-*-elf* | mipsel-*-elf*)
- tmake_file="$tmake_file mips/t-elf mips/t-crtstuff mips/t-mips16"
- extra_parts="$extra_parts crti.o crtn.o"
- ;;
-mips64-*-elf* | mips64el-*-elf*)
- tmake_file="$tmake_file mips/t-elf mips/t-crtstuff mips/t-mips16"
- extra_parts="$extra_parts crti.o crtn.o"
- ;;
-mips64vr-*-elf* | mips64vrel-*-elf*)
- tmake_file="$tmake_file mips/t-elf mips/t-vr mips/t-crtstuff"
- extra_parts="$extra_parts crti.o crtn.o"
- ;;
-mips64orion-*-elf* | mips64orionel-*-elf*)
- tmake_file="$tmake_file mips/t-elf mips/t-crtstuff mips/t-mips16"
- extra_parts="$extra_parts crti.o crtn.o"
- ;;
-mips*-*-rtems*)
- tmake_file="$tmake_file mips/t-elf mips/t-crtstuff mips/t-mips16"
- extra_parts="$extra_parts crti.o crtn.o"
- ;;
-mips-wrs-vxworks)
- ;;
-mipstx39-*-elf* | mipstx39el-*-elf*)
- tmake_file="$tmake_file mips/t-crtstuff mips/t-mips16"
- ;;
-mmix-knuth-mmixware)
- extra_parts="crti.o crtn.o crtbegin.o crtend.o"
- tmake_file="${tmake_file} ${cpu_type}/t-${cpu_type}"
- ;;
-mn10300-*-*)
- tmake_file=t-fdpbit
- ;;
-moxie-*-elf | moxie-*-uclinux*)
- tmake_file="moxie/t-moxie t-softfp-sfdf t-softfp-excl t-softfp"
- extra_parts="$extra_parts crti.o crtn.o"
- ;;
-moxie-*-rtems*)
- tmake_file="$tmake_file moxie/t-moxie t-softfp-sfdf t-softfp-excl t-softfp"
- # Don't use default.
- extra_parts=
- ;;
-pdp11-*-*)
- tmake_file="pdp11/t-pdp11 t-fdpbit"
- ;;
-picochip-*-*)
- tmake_file="picochip/t-picochip t-fpbit"
- ;;
-powerpc-*-darwin*)
- case ${host} in
- *-*-darwin9* | *-*-darwin[12][0-9]*)
- # libSystem contains unwind information for signal frames since
- # Darwin 9.
- ;;
- *)
- md_unwind_header=rs6000/darwin-unwind.h
- ;;
- esac
- tmake_file="$tmake_file rs6000/t-ibm-ldouble"
- extra_parts="$extra_parts crt2.o"
- ;;
-powerpc64-*-darwin*)
- tmake_file="$tmake_file rs6000/t-darwin64 rs6000/t-ibm-ldouble"
- extra_parts="$extra_parts crt2.o"
- ;;
-powerpc*-*-freebsd*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-savresfgpr rs6000/t-crtstuff rs6000/t-freebsd t-softfp-sfdf t-softfp-excl t-softfp"
- extra_parts="$extra_parts crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
- case ${host} in
- powerpc64*)
- tmake_file="${tmake_file} rs6000/t-freebsd64"
- md_unwind_header=rs6000/freebsd-unwind.h
- ;;
- esac
- ;;
-powerpc-*-netbsd*)
- tmake_file="$tmake_file rs6000/t-netbsd rs6000/t-crtstuff"
- ;;
-powerpc-*-eabispe*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-savresfgpr rs6000/t-crtstuff t-crtstuff-pic"
- extra_parts="$extra_parts crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
- ;;
-powerpc-*-eabisimaltivec*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
- extra_parts="$extra_parts crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
- ;;
-powerpc-*-eabisim*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
- extra_parts="$extra_parts crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
- ;;
-powerpc-*-elf*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
- extra_parts="$extra_parts crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
- ;;
-powerpc-*-eabialtivec*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
- extra_parts="$extra_parts crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
- ;;
-powerpc-xilinx-eabi*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
- extra_parts="$extra_parts crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
- ;;
-powerpc-*-eabi*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-savresfgpr rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
- extra_parts="$extra_parts crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
- ;;
-powerpc-*-rtems*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-savresfgpr rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
- extra_parts="$extra_parts crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
- ;;
-powerpc-*-linux* | powerpc64-*-linux*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-savresfgpr rs6000/t-crtstuff rs6000/t-linux t-softfp-sfdf t-softfp-excl t-dfprules rs6000/t-ppc64-fp t-softfp t-slibgcc-libgcc"
- extra_parts="$extra_parts ecrti.o ecrtn.o ncrti.o ncrtn.o"
- md_unwind_header=rs6000/linux-unwind.h
- ;;
-powerpc-wrs-vxworks|powerpc-wrs-vxworksae)
- tmake_file="$tmake_file rs6000/t-ppccomm t-fdpbit"
- ;;
-powerpc-*-lynxos*)
- tmake_file="$tmake_file rs6000/t-lynx t-fdpbit"
- ;;
-powerpcle-*-elf*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
- extra_parts="$extra_parts crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
- ;;
-powerpcle-*-eabisim*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
- extra_parts="$extra_parts crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
- ;;
-powerpcle-*-eabi*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
- extra_parts="$extra_parts crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
- ;;
-rs6000-ibm-aix4.[3456789]* | powerpc-ibm-aix4.[3456789]*)
- md_unwind_header=rs6000/aix-unwind.h
- tmake_file="t-fdpbit rs6000/t-ppc64-fp rs6000/t-slibgcc-aix rs6000/t-ibm-ldouble"
- ;;
-rs6000-ibm-aix5.1.* | powerpc-ibm-aix5.1.*)
- md_unwind_header=rs6000/aix-unwind.h
- tmake_file="t-fdpbit rs6000/t-ppc64-fp rs6000/t-slibgcc-aix rs6000/t-ibm-ldouble"
- ;;
-rs6000-ibm-aix[56789].* | powerpc-ibm-aix[56789].*)
- md_unwind_header=rs6000/aix-unwind.h
- tmake_file="t-fdpbit rs6000/t-ppc64-fp rs6000/t-slibgcc-aix rs6000/t-ibm-ldouble rs6000/t-aix-cxa"
- extra_parts="crtcxa.o crtcxa_s.o"
- ;;
-rl78-*-elf)
- tmake_file="$tm_file t-fdpbit rl78/t-rl78"
- ;;
-rx-*-elf)
- tmake_file="rx/t-rx t-fdpbit"
- tm_file="$tm_file rx/rx-abi.h rx/rx-lib.h"
- ;;
-s390-*-linux*)
- tmake_file="${tmake_file} s390/t-crtstuff s390/t-linux s390/32/t-floattodi"
- md_unwind_header=s390/linux-unwind.h
- ;;
-s390x-*-linux*)
- tmake_file="${tmake_file} s390/t-crtstuff s390/t-linux"
- md_unwind_header=s390/linux-unwind.h
- ;;
-s390x-ibm-tpf*)
- tmake_file="${tmake_file} s390/t-crtstuff t-libgcc-pic t-eh-dw2-dip"
- extra_parts="crtbeginS.o crtendS.o"
- md_unwind_header=s390/tpf-unwind.h
- ;;
-score-*-elf)
- tmake_file="${tmake_file} t-softfp-sfdf t-softfp-excl t-softfp"
- extra_parts="$extra_parts crti.o crtn.o"
- ;;
-sh-*-elf* | sh[12346l]*-*-elf*)
- tmake_file="$tmake_file sh/t-sh t-crtstuff-pic t-fdpbit"
- extra_parts="$extra_parts crt1.o crti.o crtn.o crtbeginS.o crtendS.o \
- libic_invalidate_array_4-100.a \
- libic_invalidate_array_4-200.a \
- libic_invalidate_array_4a.a \
- libgcc-Os-4-200.a libgcc-4-300.a"
- case ${host} in sh64*-*-*)
- tmake_file="$tmake_file sh/t-sh64"
- ;;
- esac
- case ${host} in
- sh*-superh-elf)
- tmake_file="$tmake_file sh/t-superh"
- extra_parts="$extra_parts crt1-mmu.o gcrt1-mmu.o gcrt1.o"
- ;;
- esac
- ;;
-sh-*-linux* | sh[2346lbe]*-*-linux*)
- tmake_file="${tmake_file} sh/t-sh t-slibgcc-libgcc sh/t-linux t-fdpbit"
- case ${host} in sh64*-*-linux*)
- tmake_file="$tmake_file sh/t-sh64"
- ;;
- esac
- md_unwind_header=sh/linux-unwind.h
- ;;
-sh-*-netbsdelf* | shl*-*-netbsdelf* | sh5-*-netbsd* | sh5l*-*-netbsd* | \
- sh64-*-netbsd* | sh64l*-*-netbsd*)
- tmake_file="$tmake_file sh/t-sh sh/t-netbsd"
- case ${host} in
- sh5*-*-netbsd* | sh64*-netbsd*)
- tmake_file="$tmake_file sh/t-sh64"
- ;;
- esac
- # NetBSD's C library includes a fast software FP library that
- # has support for setting/setting the rounding mode, exception
- # mask, etc. Therefore, we don't want to include software FP
- # in libgcc.
- ;;
-sh-*-rtems*)
- tmake_file="$tmake_file sh/t-sh t-crtstuff-pic t-fdpbit"
- extra_parts="$extra_parts crt1.o crti.o crtn.o crtbeginS.o crtendS.o \
- libic_invalidate_array_4-100.a \
- libic_invalidate_array_4-200.a \
- libic_invalidate_array_4a.a \
- libgcc-Os-4-200.a libgcc-4-300.a"
- ;;
-sh-wrs-vxworks)
- tmake_file="$tmake_file sh/t-sh t-crtstuff-pic t-fdpbit"
- ;;
-sparc-*-netbsdelf*)
- ;;
-sparc64-*-openbsd*)
- ;;
-sparc-*-elf*)
- case ${host} in
- *-leon[3-9]*)
- ;;
- *)
- tmake_file="sparc/t-softmul"
- ;;
- esac
- tmake_file="${tmake_file} t-fdpbit t-crtfm"
- extra_parts="$extra_parts crti.o crtn.o crtfastmath.o"
- ;;
-sparc-*-linux*) # SPARC's running GNU/Linux, libc6
- tmake_file="${tmake_file} t-crtfm"
- if test "${host_address}" = 64; then
- tmake_file="$tmake_file sparc/t-linux64"
- fi
- case ${host} in
- *-leon*)
- tmake_file="${tmake_file} t-fdpbit"
- ;;
- *)
- tmake_file="${tmake_file} sparc/t-linux"
- ;;
- esac
- case ${host} in
- *-leon[3-9]*)
- ;;
- *)
- if test "${host_address}" = 32; then
- tmake_file="$tmake_file sparc/t-softmul"
- fi
- ;;
- esac
- extra_parts="$extra_parts crtfastmath.o"
- md_unwind_header=sparc/linux-unwind.h
- ;;
-sparc-*-rtems*)
- tmake_file="$tmake_file sparc/t-elf sparc/t-softmul t-crtfm t-fdpbit"
- extra_parts="$extra_parts crti.o crtn.o crtfastmath.o"
- ;;
-sparc*-*-solaris2*)
- tmake_file="$tmake_file t-crtfm"
- extra_parts="$extra_parts crtfastmath.o"
- md_unwind_header=sparc/sol2-unwind.h
- ;;
-sparc64-*-elf*)
- tmake_file="${tmake_file} t-crtfm"
- extra_parts="$extra_parts crti.o crtn.o crtfastmath.o"
- ;;
-sparc64-*-rtems*)
- tmake_file="$tmake_file t-crtfm"
- extra_parts="$extra_parts crti.o crtn.o crtfastmath.o"
- ;;
-sparc-wrs-vxworks)
- ;;
-sparc64-*-freebsd*|ultrasparc-*-freebsd*)
- tmake_file="$tmake_file t-crtfm"
- extra_parts="$extra_parts crtfastmath.o"
- ;;
-sparc64-*-linux*) # 64-bit SPARC's running GNU/Linux
- extra_parts="$extra_parts crtfastmath.o"
- tmake_file="${tmake_file} t-crtfm sparc/t-linux"
- if test "${host_address}" = 64; then
- tmake_file="${tmake_file} sparc/t-linux64"
- fi
- if test "${host_address}" = 32; then
- tmake_file="${tmake_file} sparc/t-softmul"
- fi
- md_unwind_header=sparc/linux-unwind.h
- ;;
-sparc64-*-netbsd*)
- ;;
-spu-*-elf*)
- tmake_file="$tmake_file spu/t-elf t-libgcc-pic t-fdpbit"
- extra_parts="$extra_parts \
- libgcc_cachemgr.a libgcc_cachemgr_nonatomic.a \
- libgcc_cache8k.a libgcc_cache16k.a libgcc_cache32k.a \
- libgcc_cache64k.a libgcc_cache128k.a"
- ;;
-tic6x-*-uclinux)
- tmake_file="${tmake_file} t-softfp-sfdf t-softfp-excl t-softfp \
- c6x/t-elf c6x/t-uclinux t-crtstuff-pic t-libgcc-pic \
- t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver t-gnu-prefix"
- tm_file="$tm_file c6x/c6x-abi.h"
- extra_parts="$extra_parts crtbeginS.o crtendS.o crti.o crtn.o"
- unwind_header=config/c6x/unwind-c6x.h
- ;;
-tic6x-*-elf)
- tmake_file="${tmake_file} t-softfp-sfdf t-softfp-excl t-softfp t-gnu-prefix c6x/t-elf"
- tm_file="$tm_file c6x/c6x-abi.h"
- extra_parts="$extra_parts crtbeginS.o crtendS.o crti.o crtn.o"
- unwind_header=config/c6x/unwind-c6x.h
- ;;
-tilegx-*-linux*)
- tmake_file="${tmake_file} tilegx/t-crtstuff t-softfp-sfdf tilegx/t-softfp t-softfp tilegx/t-tilegx"
- md_unwind_header=tilepro/linux-unwind.h
- ;;
-tilepro-*-linux*)
- tmake_file="${tmake_file} tilepro/t-crtstuff t-softfp-sfdf t-softfp tilepro/t-tilepro"
- md_unwind_header=tilepro/linux-unwind.h
- ;;
-v850*-*-*)
- tmake_file="v850/t-v850 t-fdpbit"
- ;;
-vax-*-linux*)
- tmake_file="$tmake_file vax/t-linux"
- ;;
-vax-*-netbsdelf*)
- ;;
-vax-*-openbsd*)
- ;;
-xstormy16-*-elf)
- tmake_file="stormy16/t-stormy16 t-fdpbit"
- ;;
-xtensa*-*-elf*)
- tmake_file="$tmake_file xtensa/t-xtensa xtensa/t-elf"
- extra_parts="$extra_parts crti.o crtn.o"
- ;;
-xtensa*-*-linux*)
- tmake_file="$tmake_file xtensa/t-xtensa xtensa/t-linux"
- md_unwind_header=xtensa/linux-unwind.h
- ;;
-am33_2.0-*-linux*)
- # Don't need crtbeginT.o from *-*-linux* default.
- extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o"
- tmake_file="$tmake_file t-fdpbit"
- ;;
-m32c-*-elf*|m32c-*-rtems*)
- tmake_file="$tmake_file m32c/t-m32c"
- ;;
-mep*-*-*)
- tmake_file="mep/t-mep t-fdpbit"
- extra_parts="crtbegin.o crtend.o"
- ;;
-*)
- echo "*** Configuration ${host} not supported" 1>&2
- exit 1
- ;;
-esac
-
-case ${host} in
-i[34567]86-*-* | x86_64-*-*)
- tmake_file="${tmake_file} i386/t-cpuinfo"
- ;;
-esac
-
-case ${host} in
-i[34567]86-*-linux* | x86_64-*-linux* | \
- i[34567]86-*-kfreebsd*-gnu | x86_64-*-kfreebsd*-gnu | \
- i[34567]86-*-knetbsd*-gnu | \
- i[34567]86-*-gnu*)
- tmake_file="${tmake_file} t-tls i386/t-linux"
- if test "$libgcc_cv_cfi" = "yes"; then
- tmake_file="${tmake_file} t-stack i386/t-stack-i386"
- fi
- ;;
-esac
-
-case ${host} in
-i[34567]86-*-darwin* | x86_64-*-darwin* | \
- i[34567]86-*-kfreebsd*-gnu | x86_64-*-kfreebsd*-gnu | \
- i[34567]86-*-linux* | x86_64-*-linux* | \
- i[34567]86-*-gnu* | \
- i[34567]86-*-solaris2* | x86_64-*-solaris2.1[0-9]* | \
- i[34567]86-*-cygwin* | i[34567]86-*-mingw* | x86_64-*-mingw* | \
- i[34567]86-*-freebsd* | x86_64-*-freebsd* | \
- i[34567]86-*-openbsd* | x86_64-*-openbsd*)
- tmake_file="${tmake_file} t-softfp-tf"
- if test "${host_address}" = 32; then
- tmake_file="${tmake_file} i386/${host_address}/t-softfp"
- fi
- tmake_file="${tmake_file} i386/t-softfp t-softfp"
- ;;
-esac
-
-case ${host} in
-i[34567]86-*-linux* | x86_64-*-linux*)
- # Provide backward binary compatibility for 64bit Linux/x86.
- if test "${host_address}" = 64; then
- tmake_file="${tmake_file} i386/${host_address}/t-softfp-compat"
- fi
- tm_file="${tm_file} i386/value-unwind.h"
- ;;
-esac
diff --git a/gcc-4.8/libgo/go/archive/tar/testdata/pax.tar b/gcc-4.8/libgo/go/archive/tar/testdata/pax.tar
index e69de29bb..9bc24b658 100644
--- a/gcc-4.8/libgo/go/archive/tar/testdata/pax.tar
+++ b/gcc-4.8/libgo/go/archive/tar/testdata/pax.tar
Binary files differ
diff --git a/gcc-4.8/libgo/go/archive/tar/testdata/ustar.tar b/gcc-4.8/libgo/go/archive/tar/testdata/ustar.tar
index e69de29bb..29679d9a3 100644
--- a/gcc-4.8/libgo/go/archive/tar/testdata/ustar.tar
+++ b/gcc-4.8/libgo/go/archive/tar/testdata/ustar.tar
Binary files differ
diff --git a/gcc-4.8/libgo/go/archive/zip/testdata/test-trailing-junk.zip b/gcc-4.8/libgo/go/archive/zip/testdata/test-trailing-junk.zip
index e69de29bb..42281b4e3 100644
--- a/gcc-4.8/libgo/go/archive/zip/testdata/test-trailing-junk.zip
+++ b/gcc-4.8/libgo/go/archive/zip/testdata/test-trailing-junk.zip
Binary files differ