Import gcc 3.3.6.
144 gcc bugs were fixed between 3.3.3 and 3.3.6.
This commit is contained in:
parent
b38b3d39ad
commit
549c70ea2b
6
gnu/dist/gcc/FAQ
vendored
6
gnu/dist/gcc/FAQ
vendored
@ -415,7 +415,7 @@ dynamic_cast, throw, typeid don't work with shared libraries
|
||||
The new C++ ABI in the GCC 3.0 series uses address comparisons, rather
|
||||
than string compares, to determine type equality. This leads to better
|
||||
performance. Like other objects that have to be present in the final
|
||||
executable, these std::typeinfo_t objects have what is called vague
|
||||
executable, these std::type_info objects have what is called vague
|
||||
linkage because they are not tightly bound to any one particular
|
||||
translation unit (object file). The compiler has to emit them in any
|
||||
translation unit that requires their presence, and then rely on the
|
||||
@ -426,7 +426,7 @@ dynamic_cast, throw, typeid don't work with shared libraries
|
||||
a shared library are resolved against objects in the executable and
|
||||
other shared libraries.
|
||||
* For a program which is linked against a shared library, no
|
||||
additional precautions need taking.
|
||||
additional precautions are needed.
|
||||
* You cannot create a shared library with the "-Bsymbolic" option,
|
||||
as that prevents the resolution described above.
|
||||
* If you use dlopen to explicitly load code from a shared library,
|
||||
@ -455,7 +455,7 @@ dynamic_cast, throw, typeid don't work with shared libraries
|
||||
|
||||
For more details about the way that GCC implements these and other C++
|
||||
features, please read the [40]ABI specification. Note the
|
||||
std::typeinfo_t objects which must be resolved all begin with "_ZTS".
|
||||
std::type_info objects which must be resolved all begin with "_ZTS".
|
||||
Refer to ld's documentation for a description of the "-E" &
|
||||
"-Bsymbolic" flags.
|
||||
_________________________________________________________________
|
||||
|
2
gnu/dist/gcc/MAINTAINERS
vendored
2
gnu/dist/gcc/MAINTAINERS
vendored
@ -258,7 +258,7 @@ Krister Walfridsson cato@df.lth.se
|
||||
John Wehle john@feith.com
|
||||
Florian Weimer fw@deneb.enyo.de
|
||||
Mark Wielaard mark@gcc.gnu.org
|
||||
Josef Zlomek zlomekj@suse.cz
|
||||
Josef Zlomek josef.zlomek@email.cz
|
||||
|
||||
GNATS only accounts
|
||||
|
||||
|
125
gnu/dist/gcc/bugs.html
vendored
125
gnu/dist/gcc/bugs.html
vendored
@ -29,7 +29,7 @@
|
||||
<li><a href="#cxx">C++</a>
|
||||
<ul>
|
||||
<li><a href="#missing">Missing features</a></li>
|
||||
<li><a href="#fixed34">Bugs fixed in the upcoming 3.4 series</a></li>
|
||||
<li><a href="#fixed34">Bugs fixed in the 3.4 series</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#fortran">Fortran</a></li>
|
||||
@ -315,7 +315,7 @@ definitions may be included from the header.</p></dd>
|
||||
|
||||
</dl>
|
||||
|
||||
<h3><a name="fixed34">Bugs fixed in the upcoming 3.4 series</a></h3>
|
||||
<h3><a name="fixed34">Bugs fixed in the 3.4 series</a></h3>
|
||||
|
||||
<p>The following bugs are present up to (and including) GCC 3.3.x.
|
||||
They have been fixed in 3.4.0.</p>
|
||||
@ -390,7 +390,7 @@ The work-around was to omit the parentheses:</p>
|
||||
return A();
|
||||
</pre></blockquote>
|
||||
|
||||
<p>This problem occured in a number of variants; in <code>throw</code>
|
||||
<p>This problem occurred in a number of variants; in <code>throw</code>
|
||||
statements, people also frequently put the object in parentheses.</p></dd>
|
||||
|
||||
</dl>
|
||||
@ -442,7 +442,7 @@ int main()
|
||||
<p>might print 50 on some systems and optimization levels, and 49 on
|
||||
others.</p>
|
||||
|
||||
<p>The is the result of <em>rounding</em>: The computer cannot
|
||||
<p>This is the result of <em>rounding</em>: The computer cannot
|
||||
represent all real numbers exactly, so it has to use
|
||||
approximations. When computing with approximation, the computer needs
|
||||
to round to the nearest representable number.</p>
|
||||
@ -458,6 +458,38 @@ for more information.</p></dd>
|
||||
<h2><a name="nonbugs_c">C</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt>Increment/decrement operator (<code>++</code>/<code>--</code>) not
|
||||
working as expected - a <a href="http://gcc.gnu.org/PR11751">problem with
|
||||
many variations</a>.</dt>
|
||||
|
||||
<dd><p>The following expressions have unpredictable results:</p>
|
||||
<blockquote><pre>
|
||||
x[i]=++i
|
||||
foo(i,++i)
|
||||
i*(++i) /* special case with foo=="operator*" */
|
||||
std::cout << i << ++i /* foo(foo(std::cout,i),++i) */
|
||||
</pre></blockquote>
|
||||
<p>since the <code>i</code> without increment can be evaluated before or
|
||||
after <code>++i</code>.</p>
|
||||
|
||||
<p>The C and C++ standards have the notion of "sequence points". Everything
|
||||
that happens between two sequence points happens in an unspecified order,
|
||||
but it has to happen after the first and before the second sequence point.
|
||||
The end of a statement and a function call are examples for sequence points,
|
||||
whereas assignments and the comma between function arguments are not.</p>
|
||||
|
||||
<p>Modifying a value twice between two sequence points as shown in the
|
||||
following examples is even worse:</p>
|
||||
<blockquote><pre>
|
||||
i=++i
|
||||
foo(++i,++i)
|
||||
(++i)*(++i) /* special case with foo=="operator*" */
|
||||
std::cout << ++i << ++i /* foo(foo(std::cout,++i),++i) */
|
||||
</pre></blockquote>
|
||||
<p>This leads to undefined behavior (i.e. the compiler can do
|
||||
anything).</p></dd>
|
||||
|
||||
|
||||
<dt>Casting does not work as expected when optimization is turned on.</dt>
|
||||
|
||||
<dd><p>This is often caused by a violation of aliasing rules, which are part
|
||||
@ -685,20 +717,77 @@ a parse error before the character <code>:</code> (the colon before
|
||||
<p>The simplest way to avoid this is to write <code>std::vector<
|
||||
::X></code>, i.e. place a space between the opening angle bracket
|
||||
and the scope operator.</p></dd>
|
||||
|
||||
|
||||
<dt><a name="cxx_rvalbind">Copy constructor access check while
|
||||
initializing a reference.</a></dt>
|
||||
|
||||
<dd><p>Consider this code:</p>
|
||||
|
||||
<blockquote><pre>
|
||||
class A
|
||||
{
|
||||
public:
|
||||
A();
|
||||
|
||||
private:
|
||||
A(const A&); // private copy ctor
|
||||
};
|
||||
|
||||
A makeA(void);
|
||||
void foo(const A&);
|
||||
|
||||
void bar(void)
|
||||
{
|
||||
foo(A()); // error, copy ctor is not accessible
|
||||
foo(makeA()); // error, copy ctor is not accessible
|
||||
|
||||
A a1;
|
||||
foo(a1); // OK, a1 is a lvalue
|
||||
}</pre></blockquote>
|
||||
|
||||
<p>Starting with GCC 3.4.0, binding an rvalue to a const reference requires
|
||||
an accessible copy constructor. This might be surprising at first sight,
|
||||
especially since most popular compilers do not correctly implement this
|
||||
rule.</p>
|
||||
|
||||
<p>The C++ Standard says that a temporary object should be created in
|
||||
this context and its contents filled with a copy of the object we are
|
||||
trying to bind to the reference; it also says that the temporary copy
|
||||
can be elided, but the semantic constraints (eg. accessibility) of the
|
||||
copy constructor still have to be checked.</p>
|
||||
|
||||
<p>For further information, you can consult the following paragraphs of
|
||||
the C++ standard: [dcl.init.ref]/5, bullet 2, sub-bullet 1, and
|
||||
[class.temporary]/2.</p></dd>
|
||||
</dl>
|
||||
|
||||
<h3><a name="upgrading">Common problems when upgrading the compiler</a></h3>
|
||||
|
||||
<h4>ABI changes</h4>
|
||||
|
||||
<p>The application binary interface (ABI) defines how the elements of
|
||||
classes are laid out, how functions are called, how function names are
|
||||
mangled etc. It usually changes with each major release (i.e. when the
|
||||
first or second part of the version number changes). You <em>must</em>
|
||||
recompile all C++ libraries, or you risk linker errors or malfunctioning
|
||||
programs. However, the ABI is not changed with bug-fix releases (i.e.
|
||||
when the third part of the version number changes). The code should be
|
||||
binary compatible among these versions.</p>
|
||||
<p>The C++ application binary interface (ABI) consists of two
|
||||
components: the first defines how the elements of classes are laid
|
||||
out, how functions are called, how function names are mangled, etc;
|
||||
the second part deals with the internals of the objects in libstdc++.
|
||||
Although we strive for a non-changing ABI, so far we have had to
|
||||
modify it with each major release. If you change your compiler to a
|
||||
different major release <em>you must recompile all libraries that
|
||||
contain C++ code</em>. If you fail to do so you risk getting linker
|
||||
errors or malfunctioning programs. Some of our Java support libraries
|
||||
also contain C++ code, so you might want to recompile all libraries to
|
||||
be safe. It should not be necessary to recompile if you have changed
|
||||
to a bug-fix release of the same version of the compiler; bug-fix
|
||||
releases are careful to avoid ABI changes. See also the
|
||||
<a href="http://gcc.gnu.org/onlinedocs/gcc/Compatibility.html">compatibility
|
||||
section</a> of the GCC manual.</p>
|
||||
|
||||
<p>Remark: A major release is designated by a change to the first or second
|
||||
component of the two- or three-part version number. A minor (bug-fix)
|
||||
release is designated by a change to the third component only. Thus GCC
|
||||
3.2 and 3.3 are major releases, while 3.3.1 and 3.3.2 are bug-fix releases
|
||||
for GCC 3.3. With the 3.4 series we are introducing a new naming scheme;
|
||||
the first release of this series is 3.4.0 instead of just 3.4.</p>
|
||||
|
||||
<h4>Standard conformance</h4>
|
||||
|
||||
@ -707,9 +796,9 @@ binary compatible among these versions.</p>
|
||||
<a href="http://www.ncits.org/cplusplus.htm">http://www.ncits.org/cplusplus.htm</a>).
|
||||
We have also implemented some of the core and library defect reports
|
||||
(available at
|
||||
<a href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_defects.html">http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_defects.html</a>
|
||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html">http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html</a>
|
||||
&
|
||||
<a href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html">http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html</a>
|
||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html">http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html</a>
|
||||
respectively).</p>
|
||||
|
||||
<p>Non-conforming legacy code that worked with older versions of GCC may be
|
||||
@ -720,8 +809,8 @@ However, some non-conforming constructs are allowed when the command-line
|
||||
option <code>-fpermissive</code> is used.</p>
|
||||
|
||||
<p>Two milestones in standard conformance are GCC 3.0 (including a major
|
||||
overhaul of the standard library) and the upcoming 3.4.0 version (with its
|
||||
new C++ parser).</p>
|
||||
overhaul of the standard library) and the 3.4.0 version (with its new C++
|
||||
parser).</p>
|
||||
|
||||
<h4>New in GCC 3.0</h4>
|
||||
|
||||
@ -843,8 +932,8 @@ template <typename T> struct B : A<T>
|
||||
</ul>
|
||||
|
||||
<p>In addition to the problems listed above, the manual contains a section on
|
||||
<a href="http://gcc.gnu.org/onlinedocs/gcc/C---Misunderstandings.html">Common
|
||||
Misunderstandings with GNU C++</a>.</p>
|
||||
<a href="http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Misunderstandings.html">
|
||||
Common Misunderstandings with GNU C++</a>.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
12
gnu/dist/gcc/config/ChangeLog
vendored
12
gnu/dist/gcc/config/ChangeLog
vendored
@ -1,3 +1,15 @@
|
||||
2005-05-03 Release Manager
|
||||
|
||||
* GCC 3.3.6 Released.
|
||||
|
||||
2004-09-30 Release Manager
|
||||
|
||||
* GCC 3.3.5 Released.
|
||||
|
||||
2004-05-31 Release Manager
|
||||
|
||||
* GCC 3.3.4 Released.
|
||||
|
||||
2004-02-14 Release Manager
|
||||
|
||||
* GCC 3.3.3 Released.
|
||||
|
21
gnu/dist/gcc/contrib/ChangeLog
vendored
21
gnu/dist/gcc/contrib/ChangeLog
vendored
@ -1,3 +1,24 @@
|
||||
2005-05-03 Release Manager
|
||||
|
||||
* GCC 3.3.6 Released.
|
||||
|
||||
2004-09-30 Release Manager
|
||||
|
||||
* GCC 3.3.5 Released.
|
||||
|
||||
2004-08-26 Matthias Klose <doko@debian.org>
|
||||
|
||||
* texi2pod.pl: keep references of the form @ref{...}, print them bold.
|
||||
|
||||
2003-08-26 Matthias Klose <doko@debian.org>
|
||||
|
||||
* test_summary: Include baseline used for libstdc++-v3 abi check
|
||||
in test summary.
|
||||
|
||||
2004-05-31 Release Manager
|
||||
|
||||
* GCC 3.3.4 Released.
|
||||
|
||||
2004-02-14 Release Manager
|
||||
|
||||
* GCC 3.3.3 Released.
|
||||
|
12
gnu/dist/gcc/contrib/regression/ChangeLog
vendored
12
gnu/dist/gcc/contrib/regression/ChangeLog
vendored
@ -1,3 +1,15 @@
|
||||
2005-05-03 Release Manager
|
||||
|
||||
* GCC 3.3.6 Released.
|
||||
|
||||
2004-09-30 Release Manager
|
||||
|
||||
* GCC 3.3.5 Released.
|
||||
|
||||
2004-05-31 Release Manager
|
||||
|
||||
* GCC 3.3.4 Released.
|
||||
|
||||
2004-02-14 Release Manager
|
||||
|
||||
* GCC 3.3.3 Released.
|
||||
|
1
gnu/dist/gcc/contrib/test_summary
vendored
1
gnu/dist/gcc/contrib/test_summary
vendored
@ -116,6 +116,7 @@ $2 == "version" { save = $0; $1 = ""; $2 = ""; version = $0; gsub(/^ */, "", ver
|
||||
/\===.*Summary/ { print ""; print; blanks=1; }
|
||||
/tests ===/ || /^(Target|Host|Native)/ || $2 == "version" { print; blanks=1; }
|
||||
/^(XPASS|FAIL|UNRESOLVED|WARNING|ERROR|# of )/ { print; }
|
||||
/^using:/ { print ""; print; print ""; }
|
||||
# dumpall != 0 && /^X?(PASS|FAIL|UNTESTED)|^testcase/ { dumpall=0; }
|
||||
# dumpall != 0 { print; }
|
||||
# /^FAIL/ { dumpall=1; }
|
||||
|
3
gnu/dist/gcc/contrib/texi2pod.pl
vendored
3
gnu/dist/gcc/contrib/texi2pod.pl
vendored
@ -345,6 +345,9 @@ sub postprocess
|
||||
s/\@w\{([^\}]*)\}/S<$1>/g;
|
||||
s/\@(?:dmn|math)\{([^\}]*)\}/$1/g;
|
||||
|
||||
# keep references of the form @ref{...}, print them bold
|
||||
s/\@(?:ref)\{([^\}]*)\}/B<$1>/g;
|
||||
|
||||
# Cross references are thrown away, as are @noindent and @refill.
|
||||
# (@noindent is impossible in .pod, and @refill is unnecessary.)
|
||||
# @* is also impossible in .pod; we discard it and any newline that
|
||||
|
6
gnu/dist/gcc/faq.html
vendored
6
gnu/dist/gcc/faq.html
vendored
@ -491,7 +491,7 @@ final version of the Standard, it is.</p>
|
||||
<p>The new C++ ABI in the GCC 3.0 series uses address comparisons,
|
||||
rather than string compares, to determine type equality. This leads
|
||||
to better performance. Like other objects that have to be present in the
|
||||
final executable, these <code>std::typeinfo_t</code> objects have what
|
||||
final executable, these <code>std::type_info</code> objects have what
|
||||
is called vague linkage because they are not tightly bound to any one
|
||||
particular translation unit (object file). The compiler has to emit
|
||||
them in any translation unit that requires their presence, and then
|
||||
@ -504,7 +504,7 @@ executable and other shared libraries.</p>
|
||||
|
||||
<ul>
|
||||
<li>For a program which is linked against a shared library, no additional
|
||||
precautions need taking.</li>
|
||||
precautions are needed.</li>
|
||||
|
||||
<li>You cannot create a shared library with the "<code>-Bsymbolic</code>"
|
||||
option, as that prevents the resolution described above.</li>
|
||||
@ -539,7 +539,7 @@ linkage the same name is a violation of the One Definition Rule (ODR)
|
||||
<p>For more details about the way that GCC implements these and other
|
||||
C++ features, please read the <a
|
||||
href="http://www.codesourcery.com/cxx-abi/">ABI specification</a>.
|
||||
Note the <code>std::typeinfo_t</code> objects which <i>must</i> be
|
||||
Note the <code>std::type_info</code> objects which <i>must</i> be
|
||||
resolved all begin with "_ZTS". Refer to <code>ld</code>'s
|
||||
documentation for a description of the "<code>-E</code>" &
|
||||
"<code>-Bsymbolic</code>" flags.</p>
|
||||
|
2
gnu/dist/gcc/gcc/aclocal.m4
vendored
2
gnu/dist/gcc/gcc/aclocal.m4
vendored
@ -413,7 +413,7 @@ else
|
||||
# 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*)
|
||||
vms* | ultrix*)
|
||||
gcc_cv_func_mmap_file=no ;;
|
||||
*)
|
||||
gcc_cv_func_mmap_file=yes;;
|
||||
|
171
gnu/dist/gcc/gcc/alias.c
vendored
171
gnu/dist/gcc/gcc/alias.c
vendored
@ -110,6 +110,8 @@ static tree decl_for_component_ref PARAMS ((tree));
|
||||
static rtx adjust_offset_for_component_ref PARAMS ((tree, rtx));
|
||||
static int nonoverlapping_memrefs_p PARAMS ((rtx, rtx));
|
||||
static int write_dependence_p PARAMS ((rtx, rtx, int));
|
||||
static void set_reg_known_value PARAMS ((unsigned int, rtx));
|
||||
static void set_reg_known_equiv_p PARAMS ((unsigned int, int));
|
||||
|
||||
static int nonlocal_mentioned_p_1 PARAMS ((rtx *, void *));
|
||||
static int nonlocal_mentioned_p PARAMS ((rtx));
|
||||
@ -173,16 +175,16 @@ static GTY (()) rtx static_reg_base_value[FIRST_PSEUDO_REGISTER];
|
||||
|
||||
Because this array contains only pseudo registers it has no effect
|
||||
after reload. */
|
||||
static rtx *alias_invariant;
|
||||
static GTY((length("alias_invariant_size"))) rtx *alias_invariant;
|
||||
unsigned GTY(()) int alias_invariant_size;
|
||||
|
||||
/* Vector indexed by N giving the initial (unchanging) value known for
|
||||
pseudo-register N. This array is initialized in
|
||||
init_alias_analysis, and does not change until end_alias_analysis
|
||||
is called. */
|
||||
rtx *reg_known_value;
|
||||
pseudo-register N. This array is initialized in init_alias_analysis,
|
||||
and does not change until end_alias_analysis is called. */
|
||||
static GTY((length("reg_known_value_size"))) rtx *reg_known_value;
|
||||
|
||||
/* Indicates number of valid entries in reg_known_value. */
|
||||
static unsigned int reg_known_value_size;
|
||||
static GTY(()) unsigned int reg_known_value_size;
|
||||
|
||||
/* Vector recording for each reg_known_value whether it is due to a
|
||||
REG_EQUIV note. Future passes (viz., reload) may replace the
|
||||
@ -196,7 +198,7 @@ static unsigned int reg_known_value_size;
|
||||
REG_EQUIV notes. One could argue that the REG_EQUIV notes are
|
||||
wrong, but solving the problem in the scheduler will likely give
|
||||
better code, so we do it here. */
|
||||
char *reg_known_equiv_p;
|
||||
static bool *reg_known_equiv_p;
|
||||
|
||||
/* True when scanning insns from the start of the rtl to the
|
||||
NOTE_INSN_FUNCTION_BEG note. */
|
||||
@ -506,6 +508,8 @@ get_alias_set (t)
|
||||
/* If we haven't computed the actual alias set, do it now. */
|
||||
if (DECL_POINTER_ALIAS_SET (decl) == -2)
|
||||
{
|
||||
tree pointed_to_type = TREE_TYPE (TREE_TYPE (decl));
|
||||
|
||||
/* No two restricted pointers can point at the same thing.
|
||||
However, a restricted pointer can point at the same thing
|
||||
as an unrestricted pointer, if that unrestricted pointer
|
||||
@ -514,11 +518,22 @@ get_alias_set (t)
|
||||
alias set for the type pointed to by the type of the
|
||||
decl. */
|
||||
HOST_WIDE_INT pointed_to_alias_set
|
||||
= get_alias_set (TREE_TYPE (TREE_TYPE (decl)));
|
||||
= get_alias_set (pointed_to_type);
|
||||
|
||||
if (pointed_to_alias_set == 0)
|
||||
/* It's not legal to make a subset of alias set zero. */
|
||||
;
|
||||
DECL_POINTER_ALIAS_SET (decl) = 0;
|
||||
else if (AGGREGATE_TYPE_P (pointed_to_type))
|
||||
/* For an aggregate, we must treat the restricted
|
||||
pointer the same as an ordinary pointer. If we
|
||||
were to make the type pointed to by the
|
||||
restricted pointer a subset of the pointed-to
|
||||
type, then we would believe that other subsets
|
||||
of the pointed-to type (such as fields of that
|
||||
type) do not conflict with the type pointed to
|
||||
by the restricted pointer. */
|
||||
DECL_POINTER_ALIAS_SET (decl)
|
||||
= pointed_to_alias_set;
|
||||
else
|
||||
{
|
||||
DECL_POINTER_ALIAS_SET (decl) = new_alias_set ();
|
||||
@ -1029,7 +1044,7 @@ record_base_value (regno, val, invariant)
|
||||
if (regno >= reg_base_value_size)
|
||||
return;
|
||||
|
||||
if (invariant && alias_invariant)
|
||||
if (invariant && alias_invariant && regno < alias_invariant_size)
|
||||
alias_invariant[regno] = val;
|
||||
|
||||
if (GET_CODE (val) == REG)
|
||||
@ -1054,10 +1069,76 @@ clear_reg_alias_info (reg)
|
||||
{
|
||||
unsigned int regno = REGNO (reg);
|
||||
|
||||
if (regno < reg_known_value_size && regno >= FIRST_PSEUDO_REGISTER)
|
||||
reg_known_value[regno] = reg;
|
||||
if (regno >= FIRST_PSEUDO_REGISTER)
|
||||
{
|
||||
regno -= FIRST_PSEUDO_REGISTER;
|
||||
if (regno < reg_known_value_size)
|
||||
{
|
||||
reg_known_value[regno] = reg;
|
||||
reg_known_equiv_p[regno] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If a value is known for REGNO, return it. */
|
||||
|
||||
rtx
|
||||
get_reg_known_value (regno)
|
||||
unsigned int regno;
|
||||
{
|
||||
if (regno >= FIRST_PSEUDO_REGISTER)
|
||||
{
|
||||
regno -= FIRST_PSEUDO_REGISTER;
|
||||
if (regno < reg_known_value_size)
|
||||
return reg_known_value[regno];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set it. */
|
||||
|
||||
static void
|
||||
set_reg_known_value (regno, val)
|
||||
unsigned int regno;
|
||||
rtx val;
|
||||
{
|
||||
if (regno >= FIRST_PSEUDO_REGISTER)
|
||||
{
|
||||
regno -= FIRST_PSEUDO_REGISTER;
|
||||
if (regno < reg_known_value_size)
|
||||
reg_known_value[regno] = val;
|
||||
}
|
||||
}
|
||||
|
||||
/* Similarly for reg_known_equiv_p. */
|
||||
|
||||
bool
|
||||
get_reg_known_equiv_p (regno)
|
||||
unsigned int regno;
|
||||
{
|
||||
if (regno >= FIRST_PSEUDO_REGISTER)
|
||||
{
|
||||
regno -= FIRST_PSEUDO_REGISTER;
|
||||
if (regno < reg_known_value_size)
|
||||
return reg_known_equiv_p[regno];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
set_reg_known_equiv_p (regno, val)
|
||||
unsigned int regno;
|
||||
int val;
|
||||
{
|
||||
if (regno >= FIRST_PSEUDO_REGISTER)
|
||||
{
|
||||
regno -= FIRST_PSEUDO_REGISTER;
|
||||
if (regno < reg_known_value_size)
|
||||
reg_known_equiv_p[regno] = val;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Returns a canonical version of X, from the point of view alias
|
||||
analysis. (For example, if X is a MEM whose address is a register,
|
||||
and the register has a known value (say a SYMBOL_REF), then a MEM
|
||||
@ -1068,11 +1149,16 @@ canon_rtx (x)
|
||||
rtx x;
|
||||
{
|
||||
/* Recursively look for equivalences. */
|
||||
if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER
|
||||
&& REGNO (x) < reg_known_value_size)
|
||||
return reg_known_value[REGNO (x)] == x
|
||||
? x : canon_rtx (reg_known_value[REGNO (x)]);
|
||||
else if (GET_CODE (x) == PLUS)
|
||||
if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
|
||||
{
|
||||
rtx t = get_reg_known_value (REGNO (x));
|
||||
if (t == x)
|
||||
return x;
|
||||
if (t)
|
||||
return canon_rtx (t);
|
||||
}
|
||||
|
||||
if (GET_CODE (x) == PLUS)
|
||||
{
|
||||
rtx x0 = canon_rtx (XEXP (x, 0));
|
||||
rtx x1 = canon_rtx (XEXP (x, 1));
|
||||
@ -2698,14 +2784,9 @@ init_alias_analysis ()
|
||||
unsigned int ui;
|
||||
rtx insn;
|
||||
|
||||
reg_known_value_size = maxreg;
|
||||
|
||||
reg_known_value
|
||||
= (rtx *) xcalloc ((maxreg - FIRST_PSEUDO_REGISTER), sizeof (rtx))
|
||||
- FIRST_PSEUDO_REGISTER;
|
||||
reg_known_equiv_p
|
||||
= (char*) xcalloc ((maxreg - FIRST_PSEUDO_REGISTER), sizeof (char))
|
||||
- FIRST_PSEUDO_REGISTER;
|
||||
reg_known_value_size = maxreg - FIRST_PSEUDO_REGISTER;
|
||||
reg_known_value = ggc_calloc (reg_known_value_size, sizeof (rtx));
|
||||
reg_known_equiv_p = xcalloc (reg_known_value_size, sizeof (bool));
|
||||
|
||||
/* Overallocate reg_base_value to allow some growth during loop
|
||||
optimization. Loop unrolling can create a large number of
|
||||
@ -2718,10 +2799,9 @@ init_alias_analysis ()
|
||||
reg_seen = (char *) xmalloc (reg_base_value_size);
|
||||
if (! reload_completed && flag_unroll_loops)
|
||||
{
|
||||
/* ??? Why are we realloc'ing if we're just going to zero it? */
|
||||
alias_invariant = (rtx *)xrealloc (alias_invariant,
|
||||
reg_base_value_size * sizeof (rtx));
|
||||
memset ((char *)alias_invariant, 0, reg_base_value_size * sizeof (rtx));
|
||||
alias_invariant = (rtx *) ggc_alloc_cleared (reg_base_value_size
|
||||
* sizeof (rtx));
|
||||
alias_invariant_size = reg_base_value_size;
|
||||
}
|
||||
|
||||
/* The basic idea is that each pass through this loop will use the
|
||||
@ -2810,6 +2890,7 @@ init_alias_analysis ()
|
||||
{
|
||||
unsigned int regno = REGNO (SET_DEST (set));
|
||||
rtx src = SET_SRC (set);
|
||||
rtx t;
|
||||
|
||||
if (REG_NOTES (insn) != 0
|
||||
&& (((note = find_reg_note (insn, REG_EQUAL, 0)) != 0
|
||||
@ -2817,29 +2898,28 @@ init_alias_analysis ()
|
||||
|| (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0)
|
||||
&& GET_CODE (XEXP (note, 0)) != EXPR_LIST
|
||||
&& ! rtx_varies_p (XEXP (note, 0), 1)
|
||||
&& ! reg_overlap_mentioned_p (SET_DEST (set), XEXP (note, 0)))
|
||||
&& ! reg_overlap_mentioned_p (SET_DEST (set),
|
||||
XEXP (note, 0)))
|
||||
{
|
||||
reg_known_value[regno] = XEXP (note, 0);
|
||||
reg_known_equiv_p[regno] = REG_NOTE_KIND (note) == REG_EQUIV;
|
||||
set_reg_known_value (regno, XEXP (note, 0));
|
||||
set_reg_known_equiv_p (regno,
|
||||
REG_NOTE_KIND (note) == REG_EQUIV);
|
||||
}
|
||||
else if (REG_N_SETS (regno) == 1
|
||||
&& GET_CODE (src) == PLUS
|
||||
&& GET_CODE (XEXP (src, 0)) == REG
|
||||
&& REGNO (XEXP (src, 0)) >= FIRST_PSEUDO_REGISTER
|
||||
&& (reg_known_value[REGNO (XEXP (src, 0))])
|
||||
&& (t = get_reg_known_value (REGNO (XEXP (src, 0))))
|
||||
&& GET_CODE (XEXP (src, 1)) == CONST_INT)
|
||||
{
|
||||
rtx op0 = XEXP (src, 0);
|
||||
op0 = reg_known_value[REGNO (op0)];
|
||||
reg_known_value[regno]
|
||||
= plus_constant (op0, INTVAL (XEXP (src, 1)));
|
||||
reg_known_equiv_p[regno] = 0;
|
||||
t = plus_constant (t, INTVAL (XEXP (src, 1)));
|
||||
set_reg_known_value (regno, t);
|
||||
set_reg_known_equiv_p (regno, 0);
|
||||
}
|
||||
else if (REG_N_SETS (regno) == 1
|
||||
&& ! rtx_varies_p (src, 1))
|
||||
{
|
||||
reg_known_value[regno] = src;
|
||||
reg_known_equiv_p[regno] = 0;
|
||||
set_reg_known_value (regno, src);
|
||||
set_reg_known_equiv_p (regno, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2863,9 +2943,9 @@ init_alias_analysis ()
|
||||
while (changed && ++pass < MAX_ALIAS_LOOP_PASSES);
|
||||
|
||||
/* Fill in the remaining entries. */
|
||||
for (i = FIRST_PSEUDO_REGISTER; i < maxreg; i++)
|
||||
for (i = 0; i < (int)reg_known_value_size; i++)
|
||||
if (reg_known_value[i] == 0)
|
||||
reg_known_value[i] = regno_reg_rtx[i];
|
||||
reg_known_value[i] = regno_reg_rtx[i + FIRST_PSEUDO_REGISTER];
|
||||
|
||||
/* Simplify the reg_base_value array so that no register refers to
|
||||
another register, except to special registers indirectly through
|
||||
@ -2908,17 +2988,16 @@ init_alias_analysis ()
|
||||
void
|
||||
end_alias_analysis ()
|
||||
{
|
||||
free (reg_known_value + FIRST_PSEUDO_REGISTER);
|
||||
reg_known_value = 0;
|
||||
reg_known_value_size = 0;
|
||||
free (reg_known_equiv_p + FIRST_PSEUDO_REGISTER);
|
||||
free (reg_known_equiv_p);
|
||||
reg_known_equiv_p = 0;
|
||||
reg_base_value = 0;
|
||||
reg_base_value_size = 0;
|
||||
if (alias_invariant)
|
||||
{
|
||||
free (alias_invariant);
|
||||
alias_invariant = 0;
|
||||
alias_invariant_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
29
gnu/dist/gcc/gcc/builtins.c
vendored
29
gnu/dist/gcc/gcc/builtins.c
vendored
@ -2418,7 +2418,7 @@ expand_builtin_memcmp (exp, arglist, target, mode)
|
||||
return expand_expr (result, target, mode, EXPAND_NORMAL);
|
||||
}
|
||||
|
||||
#ifdef HAVE_cmpstrsi
|
||||
#if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
|
||||
{
|
||||
rtx arg1_rtx, arg2_rtx, arg3_rtx;
|
||||
rtx result;
|
||||
@ -2428,8 +2428,19 @@ expand_builtin_memcmp (exp, arglist, target, mode)
|
||||
= get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
|
||||
int arg2_align
|
||||
= get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
|
||||
enum machine_mode insn_mode
|
||||
= insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
|
||||
enum machine_mode insn_mode;
|
||||
|
||||
#ifdef HAVE_cmpmemsi
|
||||
if (HAVE_cmpmemsi)
|
||||
insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
|
||||
else
|
||||
#endif
|
||||
#ifdef HAVE_cmpstrsi
|
||||
if (HAVE_cmpstrsi)
|
||||
insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
|
||||
else
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
/* If we don't have POINTER_TYPE, call the function. */
|
||||
if (arg1_align == 0 || arg2_align == 0)
|
||||
@ -2445,11 +2456,19 @@ expand_builtin_memcmp (exp, arglist, target, mode)
|
||||
arg1_rtx = get_memory_rtx (arg1);
|
||||
arg2_rtx = get_memory_rtx (arg2);
|
||||
arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
|
||||
if (!HAVE_cmpstrsi)
|
||||
insn = NULL_RTX;
|
||||
#ifdef HAVE_cmpmemsi
|
||||
if (HAVE_cmpmemsi)
|
||||
insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
|
||||
GEN_INT (MIN (arg1_align, arg2_align)));
|
||||
else
|
||||
#endif
|
||||
#ifdef HAVE_cmpstrsi
|
||||
if (HAVE_cmpstrsi)
|
||||
insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
|
||||
GEN_INT (MIN (arg1_align, arg2_align)));
|
||||
else
|
||||
#endif
|
||||
abort ();
|
||||
|
||||
if (insn)
|
||||
emit_insn (insn);
|
||||
|
17
gnu/dist/gcc/gcc/c-decl.c
vendored
17
gnu/dist/gcc/gcc/c-decl.c
vendored
@ -5320,12 +5320,21 @@ finish_struct (t, fieldlist, attributes)
|
||||
&& TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (x))) == NULL_TREE)
|
||||
{
|
||||
if (TREE_CODE (t) == UNION_TYPE)
|
||||
error_with_decl (x, "flexible array member in union");
|
||||
{
|
||||
error_with_decl (x, "flexible array member in union");
|
||||
TREE_TYPE (x) = error_mark_node;
|
||||
}
|
||||
else if (TREE_CHAIN (x) != NULL_TREE)
|
||||
error_with_decl (x, "flexible array member not at end of struct");
|
||||
{
|
||||
error_with_decl (x, "flexible array member not at end of struct");
|
||||
TREE_TYPE (x) = error_mark_node;
|
||||
}
|
||||
else if (! saw_named_field)
|
||||
error_with_decl (x, "flexible array member in otherwise empty struct");
|
||||
}
|
||||
{
|
||||
error_with_decl (x, "flexible array member in otherwise empty struct");
|
||||
TREE_TYPE (x) = error_mark_node;
|
||||
}
|
||||
}
|
||||
|
||||
if (pedantic && TREE_CODE (t) == RECORD_TYPE
|
||||
&& flexible_array_type_p (TREE_TYPE (x)))
|
||||
|
1
gnu/dist/gcc/gcc/c-parse.in
vendored
1
gnu/dist/gcc/gcc/c-parse.in
vendored
@ -2177,6 +2177,7 @@ compstmt_primary_start:
|
||||
push_label_level ();
|
||||
compstmt_count++;
|
||||
$$ = add_stmt (build_stmt (COMPOUND_STMT, last_tree));
|
||||
last_expr_type = NULL_TREE;
|
||||
}
|
||||
;
|
||||
|
||||
|
2
gnu/dist/gcc/gcc/c-tree.h
vendored
2
gnu/dist/gcc/gcc/c-tree.h
vendored
@ -270,7 +270,7 @@ extern tree build_external_ref PARAMS ((tree, int));
|
||||
extern tree parser_build_binary_op PARAMS ((enum tree_code,
|
||||
tree, tree));
|
||||
extern int c_tree_expr_nonnegative_p PARAMS ((tree));
|
||||
extern void readonly_warning PARAMS ((tree, const char *));
|
||||
extern void readonly_error PARAMS ((tree, const char *));
|
||||
extern tree build_conditional_expr PARAMS ((tree, tree, tree));
|
||||
extern tree build_compound_expr PARAMS ((tree));
|
||||
extern tree c_cast_expr PARAMS ((tree, tree));
|
||||
|
74
gnu/dist/gcc/gcc/c-typeck.c
vendored
74
gnu/dist/gcc/gcc/c-typeck.c
vendored
@ -2154,11 +2154,9 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
|
||||
but don't convert the args to int! */
|
||||
build_type = integer_type_node;
|
||||
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
|
||||
|| code0 == COMPLEX_TYPE
|
||||
|| code0 == VECTOR_TYPE)
|
||||
|| code0 == COMPLEX_TYPE)
|
||||
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
|
||||
|| code1 == COMPLEX_TYPE
|
||||
|| code1 == VECTOR_TYPE))
|
||||
|| code1 == COMPLEX_TYPE))
|
||||
short_compare = 1;
|
||||
else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
|
||||
{
|
||||
@ -2968,10 +2966,10 @@ build_unary_op (code, xarg, flag)
|
||||
|
||||
/* Report a read-only lvalue. */
|
||||
if (TREE_READONLY (arg))
|
||||
readonly_warning (arg,
|
||||
((code == PREINCREMENT_EXPR
|
||||
|| code == POSTINCREMENT_EXPR)
|
||||
? "increment" : "decrement"));
|
||||
readonly_error (arg,
|
||||
((code == PREINCREMENT_EXPR
|
||||
|| code == POSTINCREMENT_EXPR)
|
||||
? "increment" : "decrement"));
|
||||
|
||||
if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
|
||||
val = boolean_increment (code, arg);
|
||||
@ -3234,41 +3232,40 @@ static void
|
||||
pedantic_lvalue_warning (code)
|
||||
enum tree_code code;
|
||||
{
|
||||
if (pedantic)
|
||||
switch (code)
|
||||
{
|
||||
case COND_EXPR:
|
||||
pedwarn ("ISO C forbids use of conditional expressions as lvalues");
|
||||
break;
|
||||
case COMPOUND_EXPR:
|
||||
pedwarn ("ISO C forbids use of compound expressions as lvalues");
|
||||
break;
|
||||
default:
|
||||
pedwarn ("ISO C forbids use of cast expressions as lvalues");
|
||||
break;
|
||||
}
|
||||
switch (code)
|
||||
{
|
||||
case COND_EXPR:
|
||||
pedwarn ("use of conditional expressions as lvalues is deprecated");
|
||||
break;
|
||||
case COMPOUND_EXPR:
|
||||
pedwarn ("use of compound expressions as lvalues is deprecated");
|
||||
break;
|
||||
default:
|
||||
pedwarn ("use of cast expressions as lvalues is deprecated");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Warn about storing in something that is `const'. */
|
||||
|
||||
void
|
||||
readonly_warning (arg, msgid)
|
||||
readonly_error (arg, msgid)
|
||||
tree arg;
|
||||
const char *msgid;
|
||||
{
|
||||
if (TREE_CODE (arg) == COMPONENT_REF)
|
||||
{
|
||||
if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
|
||||
readonly_warning (TREE_OPERAND (arg, 0), msgid);
|
||||
readonly_error (TREE_OPERAND (arg, 0), msgid);
|
||||
else
|
||||
pedwarn ("%s of read-only member `%s'", _(msgid),
|
||||
IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (arg, 1))));
|
||||
error ("%s of read-only member `%s'", _(msgid),
|
||||
IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (arg, 1))));
|
||||
}
|
||||
else if (TREE_CODE (arg) == VAR_DECL)
|
||||
pedwarn ("%s of read-only variable `%s'", _(msgid),
|
||||
IDENTIFIER_POINTER (DECL_NAME (arg)));
|
||||
error ("%s of read-only variable `%s'", _(msgid),
|
||||
IDENTIFIER_POINTER (DECL_NAME (arg)));
|
||||
else
|
||||
pedwarn ("%s of read-only location", _(msgid));
|
||||
error ("%s of read-only location", _(msgid));
|
||||
}
|
||||
|
||||
/* Mark EXP saying that we need to be able to take the
|
||||
@ -3313,7 +3310,7 @@ c_mark_addressable (exp)
|
||||
if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
|
||||
&& DECL_NONLOCAL (x))
|
||||
{
|
||||
if (TREE_PUBLIC (x))
|
||||
if (TREE_PUBLIC (x) || TREE_STATIC (x) || DECL_EXTERNAL (x))
|
||||
{
|
||||
error ("global register variable `%s' used in nested function",
|
||||
IDENTIFIER_POINTER (DECL_NAME (x)));
|
||||
@ -3324,7 +3321,7 @@ c_mark_addressable (exp)
|
||||
}
|
||||
else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
|
||||
{
|
||||
if (TREE_PUBLIC (x))
|
||||
if (TREE_PUBLIC (x) || TREE_STATIC (x) || DECL_EXTERNAL (x))
|
||||
{
|
||||
error ("address of global register variable `%s' requested",
|
||||
IDENTIFIER_POINTER (DECL_NAME (x)));
|
||||
@ -3955,7 +3952,7 @@ build_modify_expr (lhs, modifycode, rhs)
|
||||
|| ((TREE_CODE (lhstype) == RECORD_TYPE
|
||||
|| TREE_CODE (lhstype) == UNION_TYPE)
|
||||
&& C_TYPE_FIELDS_READONLY (lhstype)))
|
||||
readonly_warning (lhs, "assignment");
|
||||
readonly_error (lhs, "assignment");
|
||||
|
||||
/* If storing into a structure or union member,
|
||||
it has probably been given type `int'.
|
||||
@ -5500,6 +5497,10 @@ pop_init_level (implicit)
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Now output all pending elements. */
|
||||
constructor_incremental = 1;
|
||||
output_pending_init_elements (1);
|
||||
|
||||
p = constructor_stack;
|
||||
|
||||
/* Error for initializing a flexible array member, or a zero-length
|
||||
@ -5554,10 +5555,6 @@ pop_init_level (implicit)
|
||||
}
|
||||
}
|
||||
|
||||
/* Now output all pending elements. */
|
||||
constructor_incremental = 1;
|
||||
output_pending_init_elements (1);
|
||||
|
||||
/* Pad out the end of the structure. */
|
||||
if (p->replacement_value)
|
||||
/* If this closes a superfluous brace pair,
|
||||
@ -6244,6 +6241,11 @@ output_init_element (value, type, field, pending)
|
||||
tree value, type, field;
|
||||
int pending;
|
||||
{
|
||||
if (type == error_mark_node)
|
||||
{
|
||||
constructor_erroneous = 1;
|
||||
return;
|
||||
}
|
||||
if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE
|
||||
|| (TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
|
||||
&& !(TREE_CODE (value) == STRING_CST
|
||||
@ -7037,7 +7039,7 @@ c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
|
||||
|| ((TREE_CODE (type) == RECORD_TYPE
|
||||
|| TREE_CODE (type) == UNION_TYPE)
|
||||
&& C_TYPE_FIELDS_READONLY (type)))
|
||||
readonly_warning (o[i], "modification by `asm'");
|
||||
readonly_error (o[i], "modification by `asm'");
|
||||
}
|
||||
}
|
||||
|
||||
|
89
gnu/dist/gcc/gcc/combine.c
vendored
89
gnu/dist/gcc/gcc/combine.c
vendored
@ -10138,13 +10138,8 @@ gen_lowpart_for_combine (mode, x)
|
||||
|
||||
result = gen_lowpart_common (mode, x);
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
if (result != 0
|
||||
&& GET_CODE (result) == SUBREG
|
||||
&& GET_CODE (SUBREG_REG (result)) == REG
|
||||
&& REGNO (SUBREG_REG (result)) >= FIRST_PSEUDO_REGISTER)
|
||||
bitmap_set_bit (&subregs_of_mode, REGNO (SUBREG_REG (result))
|
||||
* MAX_MACHINE_MODE
|
||||
+ GET_MODE (result));
|
||||
if (result != 0 && GET_CODE (result) == SUBREG)
|
||||
record_subregs_of_mode (result);
|
||||
#endif
|
||||
|
||||
if (result)
|
||||
@ -10818,34 +10813,61 @@ simplify_comparison (code, pop0, pop1)
|
||||
break;
|
||||
|
||||
case SUBREG:
|
||||
/* Check for the case where we are comparing A - C1 with C2,
|
||||
both constants are smaller than 1/2 the maximum positive
|
||||
value in MODE, and the comparison is equality or unsigned.
|
||||
In that case, if A is either zero-extended to MODE or has
|
||||
sufficient sign bits so that the high-order bit in MODE
|
||||
is a copy of the sign in the inner mode, we can prove that it is
|
||||
safe to do the operation in the wider mode. This simplifies
|
||||
many range checks. */
|
||||
/* Check for the case where we are comparing A - C1 with C2, that is
|
||||
|
||||
(subreg:MODE (plus (A) (-C1))) op (C2)
|
||||
|
||||
with C1 a constant, and try to lift the SUBREG, i.e. to do the
|
||||
comparison in the wider mode. One of the following two conditions
|
||||
must be true in order for this to be valid:
|
||||
|
||||
1. The mode extension results in the same bit pattern being added
|
||||
on both sides and the comparison is equality or unsigned. As
|
||||
C2 has been truncated to fit in MODE, the pattern can only be
|
||||
all 0s or all 1s.
|
||||
|
||||
2. The mode extension results in the sign bit being copied on
|
||||
each side.
|
||||
|
||||
The difficulty here is that we have predicates for A but not for
|
||||
(A - C1) so we need to check that C1 is within proper bounds so
|
||||
as to perturbate A as little as possible. */
|
||||
|
||||
if (mode_width <= HOST_BITS_PER_WIDE_INT
|
||||
&& subreg_lowpart_p (op0)
|
||||
&& GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0))) > mode_width
|
||||
&& GET_CODE (SUBREG_REG (op0)) == PLUS
|
||||
&& GET_CODE (XEXP (SUBREG_REG (op0), 1)) == CONST_INT
|
||||
&& INTVAL (XEXP (SUBREG_REG (op0), 1)) < 0
|
||||
&& (-INTVAL (XEXP (SUBREG_REG (op0), 1))
|
||||
< (HOST_WIDE_INT) (GET_MODE_MASK (mode) / 2))
|
||||
&& (unsigned HOST_WIDE_INT) const_op < GET_MODE_MASK (mode) / 2
|
||||
&& (0 == (nonzero_bits (XEXP (SUBREG_REG (op0), 0),
|
||||
GET_MODE (SUBREG_REG (op0)))
|
||||
& ~GET_MODE_MASK (mode))
|
||||
|| (num_sign_bit_copies (XEXP (SUBREG_REG (op0), 0),
|
||||
GET_MODE (SUBREG_REG (op0)))
|
||||
> (unsigned int)
|
||||
(GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
|
||||
- GET_MODE_BITSIZE (mode)))))
|
||||
&& GET_CODE (XEXP (SUBREG_REG (op0), 1)) == CONST_INT)
|
||||
{
|
||||
op0 = SUBREG_REG (op0);
|
||||
continue;
|
||||
enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op0));
|
||||
rtx a = XEXP (SUBREG_REG (op0), 0);
|
||||
HOST_WIDE_INT c1 = -INTVAL (XEXP (SUBREG_REG (op0), 1));
|
||||
|
||||
if ((c1 > 0
|
||||
&& (unsigned HOST_WIDE_INT) c1
|
||||
< (unsigned HOST_WIDE_INT) 1 << (mode_width - 1)
|
||||
&& (equality_comparison_p || unsigned_comparison_p)
|
||||
/* (A - C1) zero-extends if it is positive and sign-extends
|
||||
if it is negative, C2 both zero- and sign-extends. */
|
||||
&& ((0 == (nonzero_bits (a, inner_mode)
|
||||
& ~GET_MODE_MASK (mode))
|
||||
&& const_op >= 0)
|
||||
/* (A - C1) sign-extends if it is positive and 1-extends
|
||||
if it is negative, C2 both sign- and 1-extends. */
|
||||
|| (num_sign_bit_copies (a, inner_mode)
|
||||
> (unsigned int) (GET_MODE_BITSIZE (inner_mode)
|
||||
- mode_width)
|
||||
&& const_op < 0)))
|
||||
|| ((unsigned HOST_WIDE_INT) c1
|
||||
< (unsigned HOST_WIDE_INT) 1 << (mode_width - 2)
|
||||
/* (A - C1) always sign-extends, like C2. */
|
||||
&& num_sign_bit_copies (a, inner_mode)
|
||||
> (unsigned int) (GET_MODE_BITSIZE (inner_mode)
|
||||
- mode_width - 1)))
|
||||
{
|
||||
op0 = SUBREG_REG (op0);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the inner mode is narrower and we are extracting the low part,
|
||||
@ -12798,8 +12820,11 @@ distribute_notes (notes, from_insn, i3, i2)
|
||||
|
||||
/* If the register is being set at TEM, see if that is all
|
||||
TEM is doing. If so, delete TEM. Otherwise, make this
|
||||
into a REG_UNUSED note instead. */
|
||||
if (reg_set_p (XEXP (note, 0), PATTERN (tem)))
|
||||
into a REG_UNUSED note instead. Don't delete sets to
|
||||
global register vars. */
|
||||
if ((REGNO (XEXP (note, 0)) >= FIRST_PSEUDO_REGISTER
|
||||
|| !global_regs[REGNO (XEXP (note, 0))])
|
||||
&& reg_set_p (XEXP (note, 0), PATTERN (tem)))
|
||||
{
|
||||
rtx set = single_set (tem);
|
||||
rtx inner_dest = 0;
|
||||
|
3
gnu/dist/gcc/gcc/config.in
vendored
3
gnu/dist/gcc/gcc/config.in
vendored
@ -617,6 +617,9 @@
|
||||
/* Define if your linker supports --eh-frame-hdr option. */
|
||||
#undef HAVE_LD_EH_FRAME_HDR
|
||||
|
||||
/* Define if your linker supports --as-needed and --no-as-needed options. */
|
||||
#undef HAVE_LD_AS_NEEDED
|
||||
|
||||
/* Define if your MIPS libgloss linker scripts consistently include STARTUP directives. */
|
||||
#undef HAVE_MIPS_LIBGLOSS_STARTUP_DIRECTIVES
|
||||
|
||||
|
33
gnu/dist/gcc/gcc/config/alpha/alpha.c
vendored
33
gnu/dist/gcc/gcc/config/alpha/alpha.c
vendored
@ -501,6 +501,9 @@ override_options ()
|
||||
warning ("trap mode not supported for VAX floats");
|
||||
alpha_fptm = ALPHA_FPTM_SU;
|
||||
}
|
||||
if (target_flags_explicit & MASK_LONG_DOUBLE_128)
|
||||
warning ("128-bit long double not supported for VAX floats");
|
||||
target_flags &= ~MASK_LONG_DOUBLE_128;
|
||||
}
|
||||
|
||||
{
|
||||
@ -1822,6 +1825,10 @@ alpha_in_small_data_p (exp)
|
||||
if (TREE_CODE (exp) == STRING_CST)
|
||||
return false;
|
||||
|
||||
/* Functions are never in the small data area. Duh. */
|
||||
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));
|
||||
@ -6759,11 +6766,6 @@ alpha_sa_mask (imaskP, fmaskP)
|
||||
break;
|
||||
imask |= 1L << regno;
|
||||
}
|
||||
|
||||
/* Glibc likes to use $31 as an unwind stopper for crt0. To
|
||||
avoid hackery in unwind-dw2.c, we need to actively store a
|
||||
zero in the prologue of _Unwind_RaiseException et al. */
|
||||
imask |= 1UL << 31;
|
||||
}
|
||||
|
||||
/* If any register spilled, then spill the return address also. */
|
||||
@ -7229,24 +7231,6 @@ alpha_expand_prologue ()
|
||||
reg_offset += 8;
|
||||
}
|
||||
|
||||
/* Store a zero if requested for unwinding. */
|
||||
if (imask & (1UL << 31))
|
||||
{
|
||||
rtx insn, t;
|
||||
|
||||
mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
|
||||
set_mem_alias_set (mem, alpha_sr_alias_set);
|
||||
insn = emit_move_insn (mem, const0_rtx);
|
||||
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
t = gen_rtx_REG (Pmode, 31);
|
||||
t = gen_rtx_SET (VOIDmode, mem, t);
|
||||
t = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, t, REG_NOTES (insn));
|
||||
REG_NOTES (insn) = t;
|
||||
|
||||
reg_offset += 8;
|
||||
}
|
||||
|
||||
for (i = 0; i < 31; i++)
|
||||
if (fmask & (1L << i))
|
||||
{
|
||||
@ -7667,9 +7651,6 @@ alpha_expand_epilogue ()
|
||||
reg_offset += 8;
|
||||
}
|
||||
|
||||
if (imask & (1UL << 31))
|
||||
reg_offset += 8;
|
||||
|
||||
for (i = 0; i < 31; ++i)
|
||||
if (fmask & (1L << i))
|
||||
{
|
||||
|
35
gnu/dist/gcc/gcc/config/alpha/alpha.h
vendored
35
gnu/dist/gcc/gcc/config/alpha/alpha.h
vendored
@ -67,6 +67,8 @@ Boston, MA 02111-1307, USA. */
|
||||
builtin_define ("_IEEE_FP"); \
|
||||
if (TARGET_IEEE_WITH_INEXACT) \
|
||||
builtin_define ("_IEEE_FP_INEXACT"); \
|
||||
if (TARGET_LONG_DOUBLE_128) \
|
||||
builtin_define ("__LONG_DOUBLE_128__"); \
|
||||
\
|
||||
/* Macros dependent on the C dialect. */ \
|
||||
SUBTARGET_LANGUAGE_CPP_BUILTINS(); \
|
||||
@ -222,6 +224,11 @@ extern int alpha_tls_size;
|
||||
#define MASK_TLS_KERNEL (1 << 14)
|
||||
#define TARGET_TLS_KERNEL (target_flags & MASK_TLS_KERNEL)
|
||||
|
||||
/* This means use IEEE quad-format for long double. Assumes the
|
||||
presence of the GEM support library routines. */
|
||||
#define MASK_LONG_DOUBLE_128 (1 << 16)
|
||||
#define TARGET_LONG_DOUBLE_128 (target_flags & MASK_LONG_DOUBLE_128)
|
||||
|
||||
/* This means that the processor is an EV5, EV56, or PCA56.
|
||||
Unlike alpha_cpu this is not affected by -mtune= setting. */
|
||||
#define MASK_CPU_EV5 (1 << 28)
|
||||
@ -254,7 +261,7 @@ extern int alpha_tls_size;
|
||||
#define TARGET_CAN_FAULT_IN_PROLOGUE 0
|
||||
#endif
|
||||
#ifndef TARGET_HAS_XFLOATING_LIBS
|
||||
#define TARGET_HAS_XFLOATING_LIBS 0
|
||||
#define TARGET_HAS_XFLOATING_LIBS TARGET_LONG_DOUBLE_128
|
||||
#endif
|
||||
#ifndef TARGET_PROFILING_NEEDS_GP
|
||||
#define TARGET_PROFILING_NEEDS_GP 0
|
||||
@ -312,6 +319,10 @@ extern int alpha_tls_size;
|
||||
N_("Emit 32-bit relocations to the small data areas")}, \
|
||||
{"tls-kernel", MASK_TLS_KERNEL, \
|
||||
N_("Emit rdval instead of rduniq for thread pointer")}, \
|
||||
{"long-double-128", MASK_LONG_DOUBLE_128, \
|
||||
N_("Use 128-bit long double")}, \
|
||||
{"long-double-64", -MASK_LONG_DOUBLE_128, \
|
||||
N_("Use 64-bit long double")}, \
|
||||
{"", TARGET_DEFAULT | TARGET_CPU_DEFAULT \
|
||||
| TARGET_DEFAULT_EXPLICIT_RELOCS, ""} }
|
||||
|
||||
@ -421,7 +432,18 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
|
||||
|
||||
#define FLOAT_TYPE_SIZE 32
|
||||
#define DOUBLE_TYPE_SIZE 64
|
||||
#define LONG_DOUBLE_TYPE_SIZE 64
|
||||
#define LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_128 ? 128 : 64)
|
||||
|
||||
/* Define this to set long double type size to use in libgcc2.c, which can
|
||||
not depend on target_flags. */
|
||||
#ifdef __LONG_DOUBLE_128__
|
||||
#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 128
|
||||
#else
|
||||
#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
|
||||
#endif
|
||||
|
||||
/* Work around target_flags dependency in ada/targtyps.c. */
|
||||
#define WIDEST_HARDWARE_FP_SIZE 64
|
||||
|
||||
#define WCHAR_TYPE "unsigned int"
|
||||
#define WCHAR_TYPE_SIZE 32
|
||||
@ -482,7 +504,7 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
|
||||
#define PARM_BOUNDARY 64
|
||||
|
||||
/* Boundary (in *bits*) on which stack pointer should be aligned. */
|
||||
#define STACK_BOUNDARY 64
|
||||
#define STACK_BOUNDARY 128
|
||||
|
||||
/* Allocation boundary (in *bits*) for the code of a function. */
|
||||
#define FUNCTION_BOUNDARY 32
|
||||
@ -620,12 +642,12 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
|
||||
|
||||
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
|
||||
On Alpha, the integer registers can hold any mode. The floating-point
|
||||
registers can hold 32-bit and 64-bit integers as well, but not 16-bit
|
||||
or 8-bit values. */
|
||||
registers can hold 64-bit integers as well, but not smaller values. */
|
||||
|
||||
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
|
||||
((REGNO) >= 32 && (REGNO) <= 62 \
|
||||
? GET_MODE_UNIT_SIZE (MODE) == 8 || GET_MODE_UNIT_SIZE (MODE) == 4 \
|
||||
? (MODE) == SFmode || (MODE) == DFmode || (MODE) == DImode \
|
||||
|| (MODE) == SCmode || (MODE) == DCmode \
|
||||
: 1)
|
||||
|
||||
/* Value is 1 if MODE is a supported vector mode. */
|
||||
@ -1277,6 +1299,7 @@ do { \
|
||||
#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, 26)
|
||||
#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (26)
|
||||
#define DWARF_ALT_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (64)
|
||||
#define DWARF_ZERO_REG 31
|
||||
|
||||
/* Describe how we implement __builtin_eh_return. */
|
||||
#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 16 : INVALID_REGNUM)
|
||||
|
355
gnu/dist/gcc/gcc/config/alpha/alpha.md
vendored
355
gnu/dist/gcc/gcc/config/alpha/alpha.md
vendored
@ -30,7 +30,7 @@
|
||||
(UNSPEC_INSXH 2)
|
||||
(UNSPEC_MSKXH 3)
|
||||
(UNSPEC_CVTQL 4)
|
||||
(UNSPEC_NT_LDA 5)
|
||||
(UNSPEC_CVTLQ 5)
|
||||
(UNSPEC_UMK_LAUM 6)
|
||||
(UNSPEC_UMK_LALM 7)
|
||||
(UNSPEC_UMK_LAL 8)
|
||||
@ -58,6 +58,9 @@
|
||||
(UNSPEC_PERR 26)
|
||||
(UNSPEC_CTLZ 27)
|
||||
(UNSPEC_CTPOP 28)
|
||||
|
||||
;; Legacy
|
||||
(UNSPEC_NT_LDA 29)
|
||||
])
|
||||
|
||||
;; UNSPEC_VOLATILE:
|
||||
@ -77,6 +80,7 @@
|
||||
(UNSPECV_PLDGP2 11) ; prologue ldgp
|
||||
(UNSPECV_SET_TP 12)
|
||||
(UNSPECV_RPCC 13)
|
||||
(UNSPECV_SETJMPR_ER 14) ; builtin_setjmp_receiver fragment
|
||||
])
|
||||
|
||||
;; Where necessary, the suffixes _le and _be are used to distinguish between
|
||||
@ -177,41 +181,36 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
|
||||
""
|
||||
"")
|
||||
|
||||
(define_insn "*extendsidi2_nofix"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r,r,*f,?*f")
|
||||
(define_insn "*cvtlq"
|
||||
[(set (match_operand:DI 0 "register_operand" "=f")
|
||||
(unspec:DI [(match_operand:SF 1 "reg_or_0_operand" "fG")]
|
||||
UNSPEC_CVTLQ))]
|
||||
""
|
||||
"cvtlq %1,%0"
|
||||
[(set_attr "type" "fadd")])
|
||||
|
||||
(define_insn "*extendsidi2_1"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r,r,!*f")
|
||||
(sign_extend:DI
|
||||
(match_operand:SI 1 "nonimmediate_operand" "r,m,*f,m")))]
|
||||
"! TARGET_FIX"
|
||||
(match_operand:SI 1 "nonimmediate_operand" "r,m,m")))]
|
||||
""
|
||||
"@
|
||||
addl $31,%1,%0
|
||||
ldl %0,%1
|
||||
cvtlq %1,%0
|
||||
lds %0,%1\;cvtlq %0,%0"
|
||||
[(set_attr "type" "iadd,ild,fadd,fld")
|
||||
(set_attr "length" "*,*,*,8")])
|
||||
[(set_attr "type" "iadd,ild,fld")
|
||||
(set_attr "length" "*,*,8")])
|
||||
|
||||
(define_insn "*extendsidi2_fix"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r,r,r,?*f,?*f")
|
||||
(sign_extend:DI
|
||||
(match_operand:SI 1 "nonimmediate_operand" "r,m,*f,*f,m")))]
|
||||
"TARGET_FIX"
|
||||
"@
|
||||
addl $31,%1,%0
|
||||
ldl %0,%1
|
||||
ftois %1,%0
|
||||
cvtlq %1,%0
|
||||
lds %0,%1\;cvtlq %0,%0"
|
||||
[(set_attr "type" "iadd,ild,ftoi,fadd,fld")
|
||||
(set_attr "length" "*,*,*,*,8")])
|
||||
|
||||
;; Due to issues with CLASS_CANNOT_CHANGE_SIZE, we cannot use a subreg here.
|
||||
(define_split
|
||||
[(set (match_operand:DI 0 "hard_fp_register_operand" "")
|
||||
(sign_extend:DI (match_operand:SI 1 "memory_operand" "")))]
|
||||
"reload_completed"
|
||||
[(set (match_dup 2) (match_dup 1))
|
||||
(set (match_dup 0) (sign_extend:DI (match_dup 2)))]
|
||||
"operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));")
|
||||
(set (match_dup 0) (unspec:DI [(match_dup 2)] UNSPEC_CVTLQ))]
|
||||
{
|
||||
operands[1] = adjust_address (operands[1], SFmode, 0);
|
||||
operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));
|
||||
})
|
||||
|
||||
;; Optimize sign-extension of SImode loads. This shows up in the wake of
|
||||
;; reload when converting fp->int.
|
||||
@ -227,28 +226,6 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
|
||||
(sign_extend:DI (match_dup 1)))]
|
||||
"")
|
||||
|
||||
(define_peephole2
|
||||
[(set (match_operand:SI 0 "hard_int_register_operand" "")
|
||||
(match_operand:SI 1 "hard_fp_register_operand" ""))
|
||||
(set (match_operand:DI 2 "hard_int_register_operand" "")
|
||||
(sign_extend:DI (match_dup 0)))]
|
||||
"TARGET_FIX
|
||||
&& (true_regnum (operands[0]) == true_regnum (operands[2])
|
||||
|| peep2_reg_dead_p (2, operands[0]))"
|
||||
[(set (match_dup 2)
|
||||
(sign_extend:DI (match_dup 1)))]
|
||||
"")
|
||||
|
||||
(define_peephole2
|
||||
[(set (match_operand:DI 0 "hard_fp_register_operand" "")
|
||||
(sign_extend:DI (match_operand:SI 1 "hard_fp_register_operand" "")))
|
||||
(set (match_operand:DI 2 "hard_int_register_operand" "")
|
||||
(match_dup 0))]
|
||||
"TARGET_FIX && peep2_reg_dead_p (2, operands[0])"
|
||||
[(set (match_dup 2)
|
||||
(sign_extend:DI (match_dup 1)))]
|
||||
"")
|
||||
|
||||
;; Don't say we have addsi3 if optimizing. This generates better code. We
|
||||
;; have the anonymous addsi3 pattern below in case combine wants to make it.
|
||||
(define_expand "addsi3"
|
||||
@ -2305,8 +2282,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
|
||||
;; processing, it is cheaper to do the truncation in the int regs.
|
||||
|
||||
(define_insn "*cvtql"
|
||||
[(set (match_operand:SI 0 "register_operand" "=f")
|
||||
(unspec:SI [(match_operand:DI 1 "reg_or_0_operand" "fG")]
|
||||
[(set (match_operand:SF 0 "register_operand" "=f")
|
||||
(unspec:SF [(match_operand:DI 1 "reg_or_0_operand" "fG")]
|
||||
UNSPEC_CVTQL))]
|
||||
"TARGET_FP"
|
||||
"cvtql%/ %R1,%0"
|
||||
@ -2318,14 +2295,16 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
|
||||
[(set (match_operand:SI 0 "memory_operand" "=m")
|
||||
(subreg:SI (fix:DI (match_operand:DF 1 "reg_or_0_operand" "fG")) 0))
|
||||
(clobber (match_scratch:DI 2 "=&f"))
|
||||
(clobber (match_scratch:SI 3 "=&f"))]
|
||||
(clobber (match_scratch:SF 3 "=&f"))]
|
||||
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(set (match_dup 2) (fix:DI (match_dup 1)))
|
||||
(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
|
||||
(set (match_dup 0) (match_dup 3))]
|
||||
""
|
||||
(set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
|
||||
(set (match_dup 5) (match_dup 3))]
|
||||
{
|
||||
operands[5] = adjust_address (operands[0], SFmode, 0);
|
||||
}
|
||||
[(set_attr "type" "fadd")
|
||||
(set_attr "trap" "yes")])
|
||||
|
||||
@ -2337,10 +2316,12 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(set (match_dup 2) (fix:DI (match_dup 1)))
|
||||
(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
|
||||
(set (match_dup 0) (match_dup 3))]
|
||||
;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
|
||||
"operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));"
|
||||
(set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
|
||||
(set (match_dup 4) (match_dup 3))]
|
||||
{
|
||||
operands[3] = gen_rtx_REG (SFmode, REGNO (operands[2]));
|
||||
operands[4] = adjust_address (operands[0], SFmode, 0);
|
||||
}
|
||||
[(set_attr "type" "fadd")
|
||||
(set_attr "trap" "yes")])
|
||||
|
||||
@ -2371,14 +2352,16 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
|
||||
(subreg:SI (fix:DI (float_extend:DF
|
||||
(match_operand:SF 1 "reg_or_0_operand" "fG"))) 0))
|
||||
(clobber (match_scratch:DI 2 "=&f"))
|
||||
(clobber (match_scratch:SI 3 "=&f"))]
|
||||
(clobber (match_scratch:SF 3 "=&f"))]
|
||||
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
|
||||
(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
|
||||
(set (match_dup 0) (match_dup 3))]
|
||||
""
|
||||
(set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
|
||||
(set (match_dup 4) (match_dup 3))]
|
||||
{
|
||||
operands[4] = adjust_address (operands[0], SFmode, 0);
|
||||
}
|
||||
[(set_attr "type" "fadd")
|
||||
(set_attr "trap" "yes")])
|
||||
|
||||
@ -2391,10 +2374,12 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
|
||||
(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
|
||||
(set (match_dup 0) (match_dup 3))]
|
||||
;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
|
||||
"operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));"
|
||||
(set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
|
||||
(set (match_dup 4) (match_dup 3))]
|
||||
{
|
||||
operands[3] = gen_rtx_REG (SFmode, REGNO (operands[2]));
|
||||
operands[4] = adjust_address (operands[0], SFmode, 0);
|
||||
}
|
||||
[(set_attr "type" "fadd")
|
||||
(set_attr "trap" "yes")])
|
||||
|
||||
@ -2446,6 +2431,35 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
|
||||
(set_attr "round_suffix" "normal")
|
||||
(set_attr "trap_suffix" "sui")])
|
||||
|
||||
(define_insn_and_split "*floatsisf2_ieee"
|
||||
[(set (match_operand:SF 0 "register_operand" "=&f")
|
||||
(float:SF (match_operand:SI 1 "memory_operand" "m")))
|
||||
(clobber (match_scratch:DI 2 "=&f"))
|
||||
(clobber (match_scratch:SF 3 "=&f"))]
|
||||
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(set (match_dup 3) (match_dup 1))
|
||||
(set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
|
||||
(set (match_dup 0) (float:SF (match_dup 2)))]
|
||||
{
|
||||
operands[1] = adjust_address (operands[1], SFmode, 0);
|
||||
})
|
||||
|
||||
(define_insn_and_split "*floatsisf2"
|
||||
[(set (match_operand:SF 0 "register_operand" "=f")
|
||||
(float:SF (match_operand:SI 1 "memory_operand" "m")))]
|
||||
"TARGET_FP"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(set (match_dup 0) (match_dup 1))
|
||||
(set (match_dup 2) (unspec:DI [(match_dup 0)] UNSPEC_CVTLQ))
|
||||
(set (match_dup 0) (float:SF (match_dup 2)))]
|
||||
{
|
||||
operands[1] = adjust_address (operands[1], SFmode, 0);
|
||||
operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
|
||||
})
|
||||
|
||||
(define_insn "*floatdidf_ieee"
|
||||
[(set (match_operand:DF 0 "register_operand" "=&f")
|
||||
(float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
|
||||
@ -2466,6 +2480,36 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
|
||||
(set_attr "round_suffix" "normal")
|
||||
(set_attr "trap_suffix" "sui")])
|
||||
|
||||
(define_insn_and_split "*floatsidf2_ieee"
|
||||
[(set (match_operand:DF 0 "register_operand" "=&f")
|
||||
(float:DF (match_operand:SI 1 "memory_operand" "m")))
|
||||
(clobber (match_scratch:DI 2 "=&f"))
|
||||
(clobber (match_scratch:SF 3 "=&f"))]
|
||||
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(set (match_dup 3) (match_dup 1))
|
||||
(set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
|
||||
(set (match_dup 0) (float:DF (match_dup 2)))]
|
||||
{
|
||||
operands[1] = adjust_address (operands[1], SFmode, 0);
|
||||
})
|
||||
|
||||
(define_insn_and_split "*floatsidf2"
|
||||
[(set (match_operand:DF 0 "register_operand" "=f")
|
||||
(float:DF (match_operand:SI 1 "memory_operand" "m")))]
|
||||
"TARGET_FP"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(set (match_dup 3) (match_dup 1))
|
||||
(set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
|
||||
(set (match_dup 0) (float:DF (match_dup 2)))]
|
||||
{
|
||||
operands[1] = adjust_address (operands[1], SFmode, 0);
|
||||
operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
|
||||
operands[3] = gen_rtx_REG (SFmode, REGNO (operands[0]));
|
||||
})
|
||||
|
||||
(define_expand "floatditf2"
|
||||
[(use (match_operand:TF 0 "register_operand" ""))
|
||||
(use (match_operand:DI 1 "general_operand" ""))]
|
||||
@ -5086,10 +5130,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
|
||||
operands[1] = force_reg (TFmode, operands[1]);
|
||||
})
|
||||
|
||||
(define_insn "*movsi_nofix"
|
||||
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m")
|
||||
(match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f"))]
|
||||
"(TARGET_ABI_OSF || TARGET_ABI_UNICOSMK) && ! TARGET_FIX
|
||||
(define_insn "*movsi"
|
||||
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m")
|
||||
(match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ"))]
|
||||
"(TARGET_ABI_OSF || TARGET_ABI_UNICOSMK)
|
||||
&& (register_operand (operands[0], SImode)
|
||||
|| reg_or_0_operand (operands[1], SImode))"
|
||||
"@
|
||||
@ -5097,36 +5141,13 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
|
||||
lda %0,%1($31)
|
||||
ldah %0,%h1($31)
|
||||
ldl %0,%1
|
||||
stl %r1,%0
|
||||
cpys %R1,%R1,%0
|
||||
ld%, %0,%1
|
||||
st%, %R1,%0"
|
||||
[(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst")])
|
||||
stl %r1,%0"
|
||||
[(set_attr "type" "ilog,iadd,iadd,ild,ist")])
|
||||
|
||||
(define_insn "*movsi_fix"
|
||||
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m,r,*f")
|
||||
(match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f,*f,r"))]
|
||||
"TARGET_ABI_OSF && TARGET_FIX
|
||||
&& (register_operand (operands[0], SImode)
|
||||
|| reg_or_0_operand (operands[1], SImode))"
|
||||
"@
|
||||
bis $31,%r1,%0
|
||||
lda %0,%1($31)
|
||||
ldah %0,%h1($31)
|
||||
ldl %0,%1
|
||||
stl %r1,%0
|
||||
cpys %R1,%R1,%0
|
||||
ld%, %0,%1
|
||||
st%, %R1,%0
|
||||
ftois %1,%0
|
||||
itofs %1,%0"
|
||||
[(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")])
|
||||
|
||||
(define_insn "*movsi_nt_vms_nofix"
|
||||
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m")
|
||||
(match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f"))]
|
||||
(define_insn "*movsi_nt_vms"
|
||||
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m")
|
||||
(match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ"))]
|
||||
"(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS)
|
||||
&& !TARGET_FIX
|
||||
&& (register_operand (operands[0], SImode)
|
||||
|| reg_or_0_operand (operands[1], SImode))"
|
||||
"@
|
||||
@ -5135,32 +5156,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
|
||||
ldah %0,%h1
|
||||
lda %0,%1
|
||||
ldl %0,%1
|
||||
stl %r1,%0
|
||||
cpys %R1,%R1,%0
|
||||
ld%, %0,%1
|
||||
st%, %R1,%0"
|
||||
[(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
|
||||
|
||||
(define_insn "*movsi_nt_vms_fix"
|
||||
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m,r,*f")
|
||||
(match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f,*f,r"))]
|
||||
"(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS)
|
||||
&& TARGET_FIX
|
||||
&& (register_operand (operands[0], SImode)
|
||||
|| reg_or_0_operand (operands[1], SImode))"
|
||||
"@
|
||||
bis $31,%1,%0
|
||||
lda %0,%1
|
||||
ldah %0,%h1
|
||||
lda %0,%1
|
||||
ldl %0,%1
|
||||
stl %r1,%0
|
||||
cpys %R1,%R1,%0
|
||||
ld%, %0,%1
|
||||
st%, %R1,%0
|
||||
ftois %1,%0
|
||||
itofs %1,%0"
|
||||
[(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
|
||||
stl %r1,%0"
|
||||
[(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist")])
|
||||
|
||||
(define_insn "*movhi_nobwx"
|
||||
[(set (match_operand:HI 0 "register_operand" "=r,r")
|
||||
@ -6768,70 +6765,44 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
|
||||
"jmp $31,(%0),0"
|
||||
[(set_attr "type" "ibr")])
|
||||
|
||||
(define_insn "*builtin_setjmp_receiver_er_sl_1"
|
||||
[(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
|
||||
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && TARGET_AS_CAN_SUBTRACT_LABELS"
|
||||
"lda $27,$LSJ%=-%l0($27)\n$LSJ%=:")
|
||||
|
||||
(define_insn "*builtin_setjmp_receiver_er_1"
|
||||
[(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
|
||||
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
||||
"br $27,$LSJ%=\n$LSJ%=:"
|
||||
[(set_attr "type" "ibr")])
|
||||
|
||||
(define_split
|
||||
[(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
|
||||
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
|
||||
&& prev_nonnote_insn (insn) == operands[0]"
|
||||
[(const_int 0)]
|
||||
"
|
||||
{
|
||||
emit_note (NULL, NOTE_INSN_DELETED);
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_insn "*builtin_setjmp_receiver_1"
|
||||
(define_expand "builtin_setjmp_receiver"
|
||||
[(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
|
||||
"TARGET_ABI_OSF"
|
||||
"br $27,$LSJ%=\n$LSJ%=:\;ldgp $29,0($27)"
|
||||
[(set_attr "length" "12")
|
||||
(set_attr "type" "multi")])
|
||||
"")
|
||||
|
||||
(define_expand "builtin_setjmp_receiver_er"
|
||||
[(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)
|
||||
(define_insn_and_split "*builtin_setjmp_receiver_1"
|
||||
[(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR)]
|
||||
"TARGET_ABI_OSF"
|
||||
{
|
||||
if (TARGET_EXPLICIT_RELOCS)
|
||||
return "#";
|
||||
else
|
||||
return "br $27,$LSJ%=\n$LSJ%=:\;ldgp $29,0($27)";
|
||||
}
|
||||
"&& TARGET_EXPLICIT_RELOCS && reload_completed"
|
||||
[(unspec_volatile [(match_dup 0)] UNSPECV_SETJMPR_ER)
|
||||
(set (match_dup 1)
|
||||
(unspec_volatile:DI [(match_dup 2) (match_dup 3)] UNSPECV_LDGP1))
|
||||
(set (match_dup 1)
|
||||
(unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LDGP2))]
|
||||
""
|
||||
{
|
||||
operands[1] = pic_offset_table_rtx;
|
||||
operands[2] = gen_rtx_REG (Pmode, 27);
|
||||
operands[3] = GEN_INT (alpha_next_sequence_number++);
|
||||
})
|
||||
}
|
||||
[(set_attr "length" "12")
|
||||
(set_attr "type" "multi")])
|
||||
|
||||
(define_expand "builtin_setjmp_receiver"
|
||||
[(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
|
||||
"TARGET_ABI_OSF"
|
||||
{
|
||||
if (TARGET_EXPLICIT_RELOCS)
|
||||
{
|
||||
emit_insn (gen_builtin_setjmp_receiver_er (operands[0]));
|
||||
DONE;
|
||||
}
|
||||
})
|
||||
(define_insn "*builtin_setjmp_receiver_er_sl_1"
|
||||
[(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR_ER)]
|
||||
"TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS && TARGET_AS_CAN_SUBTRACT_LABELS"
|
||||
"lda $27,$LSJ%=-%l0($27)\n$LSJ%=:")
|
||||
|
||||
(define_expand "exception_receiver_er"
|
||||
[(set (match_dup 0)
|
||||
(unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
|
||||
(set (match_dup 0)
|
||||
(unspec:DI [(match_dup 0) (match_dup 2)] UNSPEC_LDGP2))]
|
||||
""
|
||||
{
|
||||
operands[0] = pic_offset_table_rtx;
|
||||
operands[1] = gen_rtx_REG (Pmode, 26);
|
||||
operands[2] = GEN_INT (alpha_next_sequence_number++);
|
||||
})
|
||||
(define_insn "*builtin_setjmp_receiver_er_1"
|
||||
[(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR_ER)]
|
||||
"TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS"
|
||||
"br $27,$LSJ%=\n$LSJ%=:"
|
||||
[(set_attr "type" "ibr")])
|
||||
|
||||
(define_expand "exception_receiver"
|
||||
[(unspec_volatile [(match_dup 0)] UNSPECV_EHR)]
|
||||
@ -6839,28 +6810,38 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
|
||||
{
|
||||
if (TARGET_LD_BUGGY_LDGP)
|
||||
operands[0] = alpha_gp_save_rtx ();
|
||||
else if (TARGET_EXPLICIT_RELOCS)
|
||||
{
|
||||
emit_insn (gen_exception_receiver_er ());
|
||||
DONE;
|
||||
}
|
||||
else
|
||||
operands[0] = const0_rtx;
|
||||
})
|
||||
|
||||
(define_insn "*exception_receiver_1"
|
||||
[(unspec_volatile [(const_int 0)] UNSPECV_EHR)]
|
||||
"! TARGET_LD_BUGGY_LDGP"
|
||||
"ldgp $29,0($26)"
|
||||
[(set_attr "length" "8")
|
||||
(set_attr "type" "multi")])
|
||||
|
||||
(define_insn "*exception_receiver_2"
|
||||
[(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_EHR)]
|
||||
"TARGET_LD_BUGGY_LDGP"
|
||||
"TARGET_ABI_OSF && TARGET_LD_BUGGY_LDGP"
|
||||
"ldq $29,%0"
|
||||
[(set_attr "type" "ild")])
|
||||
|
||||
(define_insn_and_split "*exception_receiver_1"
|
||||
[(unspec_volatile [(const_int 0)] UNSPECV_EHR)]
|
||||
"TARGET_ABI_OSF"
|
||||
{
|
||||
if (TARGET_EXPLICIT_RELOCS)
|
||||
return "ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*";
|
||||
else
|
||||
return "ldgp $29,0($26)";
|
||||
}
|
||||
"&& TARGET_EXPLICIT_RELOCS && reload_completed"
|
||||
[(set (match_dup 0)
|
||||
(unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
|
||||
(set (match_dup 0)
|
||||
(unspec:DI [(match_dup 0) (match_dup 2)] UNSPEC_LDGP2))]
|
||||
{
|
||||
operands[0] = pic_offset_table_rtx;
|
||||
operands[1] = gen_rtx_REG (Pmode, 26);
|
||||
operands[2] = GEN_INT (alpha_next_sequence_number++);
|
||||
}
|
||||
[(set_attr "length" "8")
|
||||
(set_attr "type" "multi")])
|
||||
|
||||
(define_expand "nonlocal_goto_receiver"
|
||||
[(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
|
||||
(set (reg:DI 27) (mem:DI (reg:DI 29)))
|
||||
|
9
gnu/dist/gcc/gcc/config/alpha/osf5.h
vendored
9
gnu/dist/gcc/gcc/config/alpha/osf5.h
vendored
@ -1,5 +1,5 @@
|
||||
/* Definitions of target machine for GNU compiler, for DEC Alpha on Tru64 5.
|
||||
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
@ -19,11 +19,8 @@
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Tru64 5.1 uses IEEE QUAD format. */
|
||||
/* ??? However, since there is no support for VAX H_floating, we must
|
||||
drop back to a 64-bit long double to avoid a crash looking for the
|
||||
format associated with TFmode. */
|
||||
#undef LONG_DOUBLE_TYPE_SIZE
|
||||
#define LONG_DOUBLE_TYPE_SIZE (TARGET_FLOAT_VAX ? 64 : 128)
|
||||
#undef TARGET_DEFAULT
|
||||
#define TARGET_DEFAULT MASK_FP | MASK_FPREGS | MASK_LONG_DOUBLE_128
|
||||
|
||||
/* In Tru64 UNIX V5.1, Compaq introduced a new assembler
|
||||
(/usr/lib/cmplrs/cc/adu) which currently (versions between 3.04.29 and
|
||||
|
4
gnu/dist/gcc/gcc/config/alpha/qrnnd.asm
vendored
4
gnu/dist/gcc/gcc/config/alpha/qrnnd.asm
vendored
@ -26,6 +26,10 @@
|
||||
# Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
# MA 02111-1307, USA.
|
||||
|
||||
#ifdef __ELF__
|
||||
.section .note.GNU-stack,""
|
||||
#endif
|
||||
|
||||
.set noreorder
|
||||
.set noat
|
||||
|
||||
|
2
gnu/dist/gcc/gcc/config/arm/linux-elf.h
vendored
2
gnu/dist/gcc/gcc/config/arm/linux-elf.h
vendored
@ -34,6 +34,8 @@ Boston, MA 02111-1307, USA. */
|
||||
#undef TARGET_DEFAULT
|
||||
#define TARGET_DEFAULT (ARM_FLAG_APCS_32 | ARM_FLAG_MMU_TRAPS)
|
||||
|
||||
#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm6
|
||||
|
||||
#define SUBTARGET_EXTRA_LINK_SPEC " -m armelf_linux -p"
|
||||
|
||||
#undef MULTILIB_DEFAULTS
|
||||
|
48
gnu/dist/gcc/gcc/config/cris/cris.c
vendored
48
gnu/dist/gcc/gcc/config/cris/cris.c
vendored
@ -1,5 +1,5 @@
|
||||
/* Definitions for GCC. Part of the machine description for CRIS.
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
Contributed by Axis Communications. Written by Hans-Peter Nilsson.
|
||||
|
||||
This file is part of GCC.
|
||||
@ -312,7 +312,10 @@ cris_commutative_orth_op (x, mode)
|
||||
|| code == IOR || code == AND || code == UMIN));
|
||||
}
|
||||
|
||||
/* Check if MODE is same as mode for X, and X is PLUS or MINUS or UMIN. */
|
||||
/* Check if MODE is same as mode for X, and X is PLUS or MINUS or UMIN.
|
||||
By the name, you might think we should include MULT. We don't because
|
||||
it doesn't accept the same addressing modes as the others (ony
|
||||
registers) and there's also the problem of handling TARGET_MUL_BUG. */
|
||||
|
||||
int
|
||||
cris_operand_extend_operator (x, mode)
|
||||
@ -496,7 +499,11 @@ cris_op_str (x)
|
||||
break;
|
||||
|
||||
case MULT:
|
||||
return "mul";
|
||||
/* This function is for retrieving a part of an instruction name for
|
||||
an operator, for immediate output. If that ever happens for
|
||||
MULT, we need to apply TARGET_MUL_BUG in the caller. Make sure
|
||||
we notice. */
|
||||
abort ();
|
||||
break;
|
||||
|
||||
case DIV:
|
||||
@ -1401,6 +1408,23 @@ cris_print_operand (file, x, code)
|
||||
fputs ("\n\tnop", file);
|
||||
return;
|
||||
|
||||
case '!':
|
||||
/* Output directive for alignment padded with "nop" insns.
|
||||
Optimizing for size, it's plain 4-byte alignment, otherwise we
|
||||
align the section to a cache-line (32 bytes) and skip at max 2
|
||||
bytes, i.e. we skip if it's the last insn on a cache-line. The
|
||||
latter is faster by a small amount (for two test-programs 99.6%
|
||||
and 99.9%) and larger by a small amount (ditto 100.1% and
|
||||
100.2%). This is supposed to be the simplest yet performance-
|
||||
wise least intrusive way to make sure the immediately following
|
||||
(supposed) muls/mulu insn isn't located at the end of a
|
||||
cache-line. */
|
||||
if (TARGET_MUL_BUG)
|
||||
fputs (optimize_size
|
||||
? ".p2alignw 2,0x050f\n\t"
|
||||
: ".p2alignw 5,0x050f,2\n\t", file);
|
||||
return;
|
||||
|
||||
case 'H':
|
||||
/* Print high (most significant) part of something. */
|
||||
switch (GET_CODE (operand))
|
||||
@ -2635,10 +2659,24 @@ cris_asm_output_mi_thunk (stream, thunkdecl, delta, vcall_offset, funcdecl)
|
||||
{
|
||||
const char *name = XSTR (XEXP (DECL_RTL (funcdecl), 0), 0);
|
||||
|
||||
/* We have no other relative (to either PC or GOT) reloc than one
|
||||
that requests a PLT entry. Since we don't set up the GOT
|
||||
register, the jump absolutely must not be redirected through a
|
||||
PLT entry. We manage anyway by going through a local symbol.
|
||||
This depends on the assembler to not short-circuit equalities
|
||||
set by the ".set" directive (at least not for PIC relocs) and
|
||||
on the linker to direct R_CRIS_32_PLT_PCREL relocs *directly*
|
||||
to the symbol for local symbols, instead of through a PLT
|
||||
entry. */
|
||||
name = (* targetm.strip_name_encoding) (name);
|
||||
fprintf (stream, "add.d ");
|
||||
fprintf (stream, "\tadd.d ");
|
||||
assemble_name (stream, name);
|
||||
fprintf (stream, "%s,$pc\n", CRIS_PLT_PCOFFSET_SUFFIX);
|
||||
fprintf (stream, "..xth%s,$pc\n", CRIS_PLT_PCOFFSET_SUFFIX);
|
||||
fprintf (stream, "\t.set ");
|
||||
assemble_name (stream, name);
|
||||
fprintf (stream, "..xth,");
|
||||
assemble_name (stream, name);
|
||||
fprintf (stream, "\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
39
gnu/dist/gcc/gcc/config/cris/cris.h
vendored
39
gnu/dist/gcc/gcc/config/cris/cris.h
vendored
@ -170,9 +170,17 @@ extern const char *cris_elinux_stacksize_str;
|
||||
%{!melinux:%{!maout|melf:%{!fno-vtable-gc:-fvtable-gc}}}}}". */
|
||||
#define CC1PLUS_SPEC ""
|
||||
|
||||
#ifdef HAVE_AS_MUL_BUG_ABORT_OPTION
|
||||
#define MAYBE_AS_NO_MUL_BUG_ABORT \
|
||||
"%{mno-mul-bug-workaround:-no-mul-bug-abort} "
|
||||
#else
|
||||
#define MAYBE_AS_NO_MUL_BUG_ABORT
|
||||
#endif
|
||||
|
||||
/* Override previous definitions (linux.h). */
|
||||
#undef ASM_SPEC
|
||||
#define ASM_SPEC \
|
||||
MAYBE_AS_NO_MUL_BUG_ABORT \
|
||||
"%{v:-v}\
|
||||
%(asm_subtarget)"
|
||||
|
||||
@ -331,8 +339,34 @@ extern int target_flags;
|
||||
#define TARGET_MASK_AVOID_GOTPLT 8192
|
||||
#define TARGET_AVOID_GOTPLT (target_flags & TARGET_MASK_AVOID_GOTPLT)
|
||||
|
||||
/* Whether or not to work around multiplication instruction hardware bug
|
||||
when generating code for models where it may be present. From the
|
||||
trouble report for Etrax 100 LX: "A multiply operation may cause
|
||||
incorrect cache behaviour under some specific circumstances. The
|
||||
problem can occur if the instruction following the multiply instruction
|
||||
causes a cache miss, and multiply operand 1 (source operand) bits
|
||||
[31:27] matches the logical mapping of the mode register address
|
||||
(0xb0....), and bits [9:2] of operand 1 matches the TLB register
|
||||
address (0x258-0x25f). There is such a mapping in kernel mode or when
|
||||
the MMU is off. Normally there is no such mapping in user mode, and
|
||||
the problem will therefore probably not occur in Linux user mode
|
||||
programs."
|
||||
|
||||
We have no sure-fire way to know from within GCC that we're compiling a
|
||||
user program. For example, -fpic/PIC is used in libgcc which is linked
|
||||
into the kernel. However, the workaround option -mno-mul-bug can be
|
||||
safely used per-package when compiling programs. The same goes for
|
||||
general user-only libraries such as glibc, since there's no user-space
|
||||
driver-like program that gets a mapping of I/O registers (all on the
|
||||
same page, including the TLB registers). */
|
||||
#define TARGET_MASK_MUL_BUG 16384
|
||||
#define TARGET_MUL_BUG (target_flags & TARGET_MASK_MUL_BUG)
|
||||
|
||||
#define TARGET_SWITCHES \
|
||||
{ \
|
||||
{"mul-bug-workaround", TARGET_MASK_MUL_BUG, \
|
||||
N_("Work around bug in multiplication instruction")}, \
|
||||
{"no-mul-bug-workaround", -TARGET_MASK_MUL_BUG, ""}, \
|
||||
/* No "no-etrax" as it does not really imply any model. \
|
||||
On the other hand, "etrax" implies the common (and large) \
|
||||
subset matching all models. */ \
|
||||
@ -410,7 +444,7 @@ extern int target_flags;
|
||||
# define TARGET_DEFAULT \
|
||||
(TARGET_MASK_SIDE_EFFECT_PREFIXES + TARGET_MASK_STACK_ALIGN \
|
||||
+ TARGET_MASK_CONST_ALIGN + TARGET_MASK_DATA_ALIGN \
|
||||
+ TARGET_MASK_PROLOGUE_EPILOGUE)
|
||||
+ TARGET_MASK_PROLOGUE_EPILOGUE + TARGET_MASK_MUL_BUG)
|
||||
#endif
|
||||
|
||||
/* For the cris-*-elf subtarget. */
|
||||
@ -1622,7 +1656,8 @@ call_ ## FUNC (void) \
|
||||
cris_print_operand (FILE, X, CODE)
|
||||
|
||||
/* For delay-slot handling. */
|
||||
#define PRINT_OPERAND_PUNCT_VALID_P(CODE) (CODE == '#')
|
||||
#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
|
||||
((CODE) == '#' || (CODE) == '!')
|
||||
|
||||
#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
|
||||
cris_print_operand_address (FILE, ADDR)
|
||||
|
73
gnu/dist/gcc/gcc/config/cris/cris.md
vendored
73
gnu/dist/gcc/gcc/config/cris/cris.md
vendored
@ -2468,8 +2468,11 @@
|
||||
(zero_extend:SI (match_operand:HI 1 "register_operand" "0"))
|
||||
(zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
|
||||
"TARGET_HAS_MUL_INSNS"
|
||||
"mulu.w %2,%0"
|
||||
[(set_attr "slottable" "yes")
|
||||
"%!mulu.w %2,%0"
|
||||
[(set (attr "slottable")
|
||||
(if_then_else (ne (symbol_ref "TARGET_MUL_BUG") (const_int 0))
|
||||
(const_string "no")
|
||||
(const_string "yes")))
|
||||
;; Just N unusable here, but let's be safe.
|
||||
(set_attr "cc" "clobber")])
|
||||
|
||||
@ -2479,8 +2482,11 @@
|
||||
(zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
|
||||
(zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
|
||||
"TARGET_HAS_MUL_INSNS"
|
||||
"mulu.b %2,%0"
|
||||
[(set_attr "slottable" "yes")
|
||||
"%!mulu.b %2,%0"
|
||||
[(set (attr "slottable")
|
||||
(if_then_else (ne (symbol_ref "TARGET_MUL_BUG") (const_int 0))
|
||||
(const_string "no")
|
||||
(const_string "yes")))
|
||||
;; Not exactly sure, but let's be safe.
|
||||
(set_attr "cc" "clobber")])
|
||||
|
||||
@ -2495,8 +2501,11 @@
|
||||
(mult:SI (match_operand:SI 1 "register_operand" "0")
|
||||
(match_operand:SI 2 "register_operand" "r")))]
|
||||
"TARGET_HAS_MUL_INSNS"
|
||||
"muls.d %2,%0"
|
||||
[(set_attr "slottable" "yes")
|
||||
"%!muls.d %2,%0"
|
||||
[(set (attr "slottable")
|
||||
(if_then_else (ne (symbol_ref "TARGET_MUL_BUG") (const_int 0))
|
||||
(const_string "no")
|
||||
(const_string "yes")))
|
||||
;; Just N unusable here, but let's be safe.
|
||||
(set_attr "cc" "clobber")])
|
||||
|
||||
@ -2510,8 +2519,11 @@
|
||||
(sign_extend:HI (match_operand:QI 1 "register_operand" "0"))
|
||||
(sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
|
||||
"TARGET_HAS_MUL_INSNS"
|
||||
"muls.b %2,%0"
|
||||
[(set_attr "slottable" "yes")
|
||||
"%!muls.b %2,%0"
|
||||
[(set (attr "slottable")
|
||||
(if_then_else (ne (symbol_ref "TARGET_MUL_BUG") (const_int 0))
|
||||
(const_string "no")
|
||||
(const_string "yes")))
|
||||
(set_attr "cc" "clobber")])
|
||||
|
||||
(define_insn "mulhisi3"
|
||||
@ -2520,8 +2532,11 @@
|
||||
(sign_extend:SI (match_operand:HI 1 "register_operand" "0"))
|
||||
(sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
|
||||
"TARGET_HAS_MUL_INSNS"
|
||||
"muls.w %2,%0"
|
||||
[(set_attr "slottable" "yes")
|
||||
"%!muls.w %2,%0"
|
||||
[(set (attr "slottable")
|
||||
(if_then_else (ne (symbol_ref "TARGET_MUL_BUG") (const_int 0))
|
||||
(const_string "no")
|
||||
(const_string "yes")))
|
||||
;; Just N unusable here, but let's be safe.
|
||||
(set_attr "cc" "clobber")])
|
||||
|
||||
@ -2537,7 +2552,7 @@
|
||||
(sign_extend:DI (match_operand:SI 1 "register_operand" "0"))
|
||||
(sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
|
||||
"TARGET_HAS_MUL_INSNS"
|
||||
"muls.d %2,%M0\;move $mof,%H0")
|
||||
"%!muls.d %2,%M0\;move $mof,%H0")
|
||||
|
||||
(define_insn "umulsidi3"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
@ -2545,7 +2560,7 @@
|
||||
(zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
|
||||
(zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
|
||||
"TARGET_HAS_MUL_INSNS"
|
||||
"mulu.d %2,%M0\;move $mof,%H0")
|
||||
"%!mulu.d %2,%M0\;move $mof,%H0")
|
||||
|
||||
;; This pattern would probably not be needed if we add "mof" in its own
|
||||
;; register class (and open a can of worms about /not/ pairing it with a
|
||||
@ -2564,7 +2579,7 @@
|
||||
(const_int 32))))
|
||||
(clobber (match_scratch:SI 3 "=X,1,1"))]
|
||||
"TARGET_HAS_MUL_INSNS"
|
||||
"muls.d %2,%1\;move $mof,%0"
|
||||
"%!muls.d %2,%1\;move $mof,%0"
|
||||
[(set_attr "cc" "clobber")])
|
||||
|
||||
(define_insn "umulsi3_highpart"
|
||||
@ -2577,7 +2592,7 @@
|
||||
(const_int 32))))
|
||||
(clobber (match_scratch:SI 3 "=X,1,1"))]
|
||||
"TARGET_HAS_MUL_INSNS"
|
||||
"mulu.d %2,%1\;move $mof,%0"
|
||||
"%!mulu.d %2,%1\;move $mof,%0"
|
||||
[(set_attr "cc" "clobber")])
|
||||
|
||||
;; Divide and modulus instructions. CRIS only has a step instruction.
|
||||
@ -2682,17 +2697,19 @@
|
||||
|
||||
(define_insn "*andsi_movu"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
|
||||
(and:SI (match_operand:SI 1 "nonimmediate_operand" "%r,Q>,m")
|
||||
(and:SI (match_operand:SI 1 "nonimmediate_operand" "%r,Q,To")
|
||||
(match_operand:SI 2 "const_int_operand" "n,n,n")))]
|
||||
"INTVAL (operands[2]) == 255 || INTVAL (operands[2]) == 65535"
|
||||
"(INTVAL (operands[2]) == 255 || INTVAL (operands[2]) == 65535)
|
||||
&& (GET_CODE (operands[1]) != MEM || ! MEM_VOLATILE_P (operands[1]))"
|
||||
"movu.%z2 %1,%0"
|
||||
[(set_attr "slottable" "yes,yes,no")])
|
||||
|
||||
(define_insn "*andsi_clear"
|
||||
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,Q>,Q>,m,m")
|
||||
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,Q,Q,To,To")
|
||||
(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0,0")
|
||||
(match_operand:SI 2 "const_int_operand" "P,n,P,n,P,n")))]
|
||||
"INTVAL (operands[2]) == -65536 || INTVAL (operands[2]) == -256"
|
||||
"(INTVAL (operands[2]) == -65536 || INTVAL (operands[2]) == -256)
|
||||
&& (GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0]))"
|
||||
"@
|
||||
cLear.b %0
|
||||
cLear.w %0
|
||||
@ -2770,27 +2787,17 @@
|
||||
|
||||
(define_insn "*andhi_movu"
|
||||
[(set (match_operand:HI 0 "register_operand" "=r,r,r")
|
||||
(and:HI (match_operand:HI 1 "nonimmediate_operand" "r,Q>,m")
|
||||
(and:HI (match_operand:HI 1 "nonimmediate_operand" "r,Q,To")
|
||||
(const_int 255)))]
|
||||
""
|
||||
"GET_CODE (operands[1]) != MEM || ! MEM_VOLATILE_P (operands[1])"
|
||||
"mOvu.b %1,%0"
|
||||
[(set_attr "slottable" "yes,yes,no")])
|
||||
|
||||
(define_insn "*andhi_clear_signed"
|
||||
[(set (match_operand:HI 0 "nonimmediate_operand" "=r,Q>,m")
|
||||
(define_insn "*andhi_clear"
|
||||
[(set (match_operand:HI 0 "nonimmediate_operand" "=r,Q,To")
|
||||
(and:HI (match_operand:HI 1 "nonimmediate_operand" "0,0,0")
|
||||
(const_int -256)))]
|
||||
""
|
||||
"cLear.b %0"
|
||||
[(set_attr "slottable" "yes,yes,no")
|
||||
(set_attr "cc" "none")])
|
||||
|
||||
;; FIXME: Either this or the pattern above should be redundant.
|
||||
(define_insn "*andhi_clear_unsigned"
|
||||
[(set (match_operand:HI 0 "nonimmediate_operand" "=r,Q>,m")
|
||||
(and:HI (match_operand:HI 1 "nonimmediate_operand" "0,0,0")
|
||||
(const_int 65280)))]
|
||||
""
|
||||
"GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0])"
|
||||
"cLear.b %0"
|
||||
[(set_attr "slottable" "yes,yes,no")
|
||||
(set_attr "cc" "none")])
|
||||
|
7
gnu/dist/gcc/gcc/config/cris/mulsi3.asm
vendored
7
gnu/dist/gcc/gcc/config/cris/mulsi3.asm
vendored
@ -82,8 +82,13 @@
|
||||
.type ___Mul,@function
|
||||
___Mul:
|
||||
#if defined (__CRIS_arch_version) && __CRIS_arch_version >= 10
|
||||
ret
|
||||
;; Can't have the mulu.d last on a cache-line (in the delay-slot of the
|
||||
;; "ret"), due to hardware bug. See documentation for -mmul-bug-workaround.
|
||||
;; Not worthwhile to conditionalize here.
|
||||
.p2alignw 2,0x050f
|
||||
mulu.d $r11,$r10
|
||||
ret
|
||||
nop
|
||||
#else
|
||||
move.d $r10,$r12
|
||||
move.d $r11,$r9
|
||||
|
2
gnu/dist/gcc/gcc/config/darwin.h
vendored
2
gnu/dist/gcc/gcc/config/darwin.h
vendored
@ -192,7 +192,7 @@ Boston, MA 02111-1307, USA. */
|
||||
%{!Zdynamiclib:%{!A:%{!nostdlib:%{!nostartfiles:%S}}}} \
|
||||
%{L*} %(link_libgcc) %o %{!nostdlib:%{!nodefaultlibs:%G %L}} \
|
||||
%{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} %{F*} \
|
||||
%{!--help:%{!no-c++filt|c++filt:| c++filt3 }} }}}}}}}}"
|
||||
%{!--help:%{!no-c++filt|c++filt:| c++filt }} }}}}}}}}"
|
||||
|
||||
/* Please keep the random linker options in alphabetical order (modulo
|
||||
'Z' and 'no' prefixes). Options that can only go to one of libtool
|
||||
|
14
gnu/dist/gcc/gcc/config/freebsd-spec.h
vendored
14
gnu/dist/gcc/gcc/config/freebsd-spec.h
vendored
@ -130,13 +130,7 @@ is built with the --enable-threads configure-time option.} \
|
||||
%{pg: -lc_p} \
|
||||
}"
|
||||
#else
|
||||
#if FBSD_MAJOR >= 5
|
||||
#define FBSD_LIB_SPEC " \
|
||||
%{!shared: \
|
||||
%{!pg: %{pthread:-lc_r} -lc} \
|
||||
%{pg: %{pthread:-lc_r_p} -lc_p} \
|
||||
}"
|
||||
#else
|
||||
#if FBSD_MAJOR < 5
|
||||
#define FBSD_LIB_SPEC " \
|
||||
%{!shared: \
|
||||
%{!pg: \
|
||||
@ -146,5 +140,11 @@ is built with the --enable-threads configure-time option.} \
|
||||
%{!pthread:-lc_p} \
|
||||
%{pthread:-lc_r_p}} \
|
||||
}"
|
||||
#else
|
||||
#define FBSD_LIB_SPEC " \
|
||||
%{!shared: \
|
||||
%{!pg: %{pthread:-lpthread} -lc} \
|
||||
%{pg: %{pthread:-lpthread_p} -lc_p} \
|
||||
}"
|
||||
#endif
|
||||
#endif
|
||||
|
8
gnu/dist/gcc/gcc/config/i370/i370.md
vendored
8
gnu/dist/gcc/gcc/config/i370/i370.md
vendored
@ -474,10 +474,10 @@ check_label_emit ();
|
||||
)
|
||||
|
||||
;
|
||||
; cmpstrsi instruction pattern(s).
|
||||
; cmpmemsi instruction pattern(s).
|
||||
;
|
||||
|
||||
(define_expand "cmpstrsi"
|
||||
(define_expand "cmpmemsi"
|
||||
[(set (match_operand:SI 0 "general_operand" "")
|
||||
(compare (match_operand:BLK 1 "general_operand" "")
|
||||
(match_operand:BLK 2 "general_operand" "")))
|
||||
@ -545,7 +545,7 @@ check_label_emit ();
|
||||
emit_move_insn (gen_rtx_SUBREG (SImode, reg2, GET_MODE_SIZE (SImode)), len);
|
||||
|
||||
/* Compare! */
|
||||
emit_insn (gen_cmpstrsi_1 (result, reg1, reg2));
|
||||
emit_insn (gen_cmpmemsi_1 (result, reg1, reg2));
|
||||
}
|
||||
DONE;
|
||||
}")
|
||||
@ -569,7 +569,7 @@ check_label_emit ();
|
||||
|
||||
; Compare a block that is larger than 255 bytes in length.
|
||||
|
||||
(define_insn "cmpstrsi_1"
|
||||
(define_insn "cmpmemsi_1"
|
||||
[(set (match_operand:SI 0 "register_operand" "+d")
|
||||
(compare
|
||||
(mem:BLK (subreg:SI (match_operand:DI 1 "register_operand" "+d") 0))
|
||||
|
2
gnu/dist/gcc/gcc/config/i386/i386-protos.h
vendored
2
gnu/dist/gcc/gcc/config/i386/i386-protos.h
vendored
@ -88,6 +88,8 @@ extern int memory_displacement_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int cmpsi_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int long_memory_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int aligned_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int compare_operator PARAMS ((rtx, enum machine_mode));
|
||||
extern int flags_reg_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern enum machine_mode ix86_cc_mode PARAMS ((enum rtx_code, rtx, rtx));
|
||||
|
||||
extern int ix86_expand_movstr PARAMS ((rtx, rtx, rtx, rtx));
|
||||
|
2
gnu/dist/gcc/gcc/config/i386/i386.h
vendored
2
gnu/dist/gcc/gcc/config/i386/i386.h
vendored
@ -3319,6 +3319,7 @@ do { \
|
||||
SYMBOL_REF, LABEL_REF, SUBREG, REG, MEM}}, \
|
||||
{"nonmemory_no_elim_operand", {CONST_INT, REG, SUBREG}}, \
|
||||
{"index_register_operand", {SUBREG, REG}}, \
|
||||
{"flags_reg_operand", {REG}}, \
|
||||
{"q_regs_operand", {SUBREG, REG}}, \
|
||||
{"non_q_regs_operand", {SUBREG, REG}}, \
|
||||
{"fcmov_comparison_operator", {EQ, NE, LTU, GTU, LEU, GEU, UNORDERED, \
|
||||
@ -3354,6 +3355,7 @@ do { \
|
||||
{"fp_register_operand", {REG}}, \
|
||||
{"register_and_not_fp_reg_operand", {REG}}, \
|
||||
{"vector_move_operand", {CONST_VECTOR, SUBREG, REG, MEM}}, \
|
||||
{"compare_operator", {COMPARE}},
|
||||
|
||||
/* A list of predicates that do special things with modes, and so
|
||||
should not elicit warnings for VOIDmode match_operand. */
|
||||
|
589
gnu/dist/gcc/gcc/config/i386/i386.md
vendored
589
gnu/dist/gcc/gcc/config/i386/i386.md
vendored
@ -1188,10 +1188,9 @@
|
||||
""
|
||||
"xchg{l}\t%1, %0"
|
||||
[(set_attr "type" "imov")
|
||||
(set_attr "mode" "SI")
|
||||
(set_attr "pent_pair" "np")
|
||||
(set_attr "athlon_decode" "vector")
|
||||
(set_attr "mode" "SI")
|
||||
(set_attr "modrm" "0")
|
||||
(set_attr "ppro_uops" "few")])
|
||||
|
||||
(define_expand "movhi"
|
||||
@ -1304,12 +1303,12 @@
|
||||
(match_operand:HI 1 "register_operand" "+r"))
|
||||
(set (match_dup 1)
|
||||
(match_dup 0))]
|
||||
"TARGET_PARTIAL_REG_STALL"
|
||||
"xchg{w}\t%1, %0"
|
||||
"!TARGET_PARTIAL_REG_STALL || optimize_size"
|
||||
"xchg{l}\t%k1, %k0"
|
||||
[(set_attr "type" "imov")
|
||||
(set_attr "mode" "SI")
|
||||
(set_attr "pent_pair" "np")
|
||||
(set_attr "mode" "HI")
|
||||
(set_attr "modrm" "0")
|
||||
(set_attr "athlon_decode" "vector")
|
||||
(set_attr "ppro_uops" "few")])
|
||||
|
||||
(define_insn "*swaphi_2"
|
||||
@ -1317,12 +1316,12 @@
|
||||
(match_operand:HI 1 "register_operand" "+r"))
|
||||
(set (match_dup 1)
|
||||
(match_dup 0))]
|
||||
"! TARGET_PARTIAL_REG_STALL"
|
||||
"xchg{l}\t%k1, %k0"
|
||||
"TARGET_PARTIAL_REG_STALL"
|
||||
"xchg{w}\t%1, %0"
|
||||
[(set_attr "type" "imov")
|
||||
(set_attr "mode" "HI")
|
||||
(set_attr "pent_pair" "np")
|
||||
(set_attr "mode" "SI")
|
||||
(set_attr "modrm" "0")
|
||||
(set_attr "athlon_decode" "vector")
|
||||
(set_attr "ppro_uops" "few")])
|
||||
|
||||
(define_expand "movstricthi"
|
||||
@ -1470,17 +1469,30 @@
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn "*swapqi"
|
||||
(define_insn "*swapqi_1"
|
||||
[(set (match_operand:QI 0 "register_operand" "+r")
|
||||
(match_operand:QI 1 "register_operand" "+r"))
|
||||
(set (match_dup 1)
|
||||
(match_dup 0))]
|
||||
""
|
||||
"!TARGET_PARTIAL_REG_STALL || optimize_size"
|
||||
"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 "ppro_uops" "few")])
|
||||
|
||||
(define_insn "*swapqi_2"
|
||||
[(set (match_operand:QI 0 "register_operand" "+q")
|
||||
(match_operand:QI 1 "register_operand" "+q"))
|
||||
(set (match_dup 1)
|
||||
(match_dup 0))]
|
||||
"TARGET_PARTIAL_REG_STALL"
|
||||
"xchg{b}\t%1, %0"
|
||||
[(set_attr "type" "imov")
|
||||
(set_attr "pent_pair" "np")
|
||||
(set_attr "mode" "QI")
|
||||
(set_attr "modrm" "0")
|
||||
(set_attr "pent_pair" "np")
|
||||
(set_attr "athlon_decode" "vector")
|
||||
(set_attr "ppro_uops" "few")])
|
||||
|
||||
(define_expand "movstrictqi"
|
||||
@ -1690,11 +1702,11 @@
|
||||
[(set_attr "type" "imov")
|
||||
(set_attr "mode" "QI")])
|
||||
|
||||
(define_insn "*movsi_insv_1_rex64"
|
||||
[(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
|
||||
(define_insn "movdi_insv_1_rex64"
|
||||
[(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
|
||||
(const_int 8)
|
||||
(const_int 8))
|
||||
(match_operand:SI 1 "nonmemory_operand" "Qn"))]
|
||||
(match_operand:DI 1 "nonmemory_operand" "Qn"))]
|
||||
"TARGET_64BIT"
|
||||
"mov{b}\t{%b1, %h0|%h0, %b1}"
|
||||
[(set_attr "type" "imov")
|
||||
@ -1987,13 +1999,11 @@
|
||||
"TARGET_64BIT"
|
||||
"xchg{q}\t%1, %0"
|
||||
[(set_attr "type" "imov")
|
||||
(set_attr "mode" "DI")
|
||||
(set_attr "pent_pair" "np")
|
||||
(set_attr "athlon_decode" "vector")
|
||||
(set_attr "mode" "DI")
|
||||
(set_attr "modrm" "0")
|
||||
(set_attr "ppro_uops" "few")])
|
||||
|
||||
|
||||
(define_expand "movsf"
|
||||
[(set (match_operand:SF 0 "nonimmediate_operand" "")
|
||||
(match_operand:SF 1 "general_operand" ""))]
|
||||
@ -7559,17 +7569,21 @@
|
||||
""
|
||||
"")
|
||||
|
||||
(define_insn "*testqi_1"
|
||||
(define_insn "*testqi_1_maybe_si"
|
||||
[(set (reg 17)
|
||||
(compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
|
||||
(match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
|
||||
(const_int 0)))]
|
||||
"ix86_match_ccmode (insn, CCNOmode)"
|
||||
(compare
|
||||
(and:QI
|
||||
(match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
|
||||
(match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
|
||||
(const_int 0)))]
|
||||
"(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
|
||||
&& ix86_match_ccmode (insn,
|
||||
GET_CODE (operands[1]) == CONST_INT
|
||||
&& INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
|
||||
{
|
||||
if (which_alternative == 3)
|
||||
{
|
||||
if (GET_CODE (operands[1]) == CONST_INT
|
||||
&& (INTVAL (operands[1]) & 0xffffff00))
|
||||
if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
|
||||
operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
|
||||
return "test{l}\t{%1, %k0|%k0, %1}";
|
||||
}
|
||||
@ -7580,6 +7594,18 @@
|
||||
(set_attr "mode" "QI,QI,QI,SI")
|
||||
(set_attr "pent_pair" "uv,np,uv,np")])
|
||||
|
||||
(define_insn "*testqi_1"
|
||||
[(set (reg 17)
|
||||
(compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm")
|
||||
(match_operand:QI 1 "nonmemory_operand" "n,n,qn"))
|
||||
(const_int 0)))]
|
||||
"ix86_match_ccmode (insn, CCNOmode)"
|
||||
"test{b}\t{%1, %0|%0, %1}"
|
||||
[(set_attr "type" "test")
|
||||
(set_attr "modrm" "0,1,1")
|
||||
(set_attr "mode" "QI")
|
||||
(set_attr "pent_pair" "uv,np,uv")])
|
||||
|
||||
(define_expand "testqi_ext_ccno_0"
|
||||
[(set (reg:CCNO 17)
|
||||
(compare:CCNO
|
||||
@ -7697,51 +7723,53 @@
|
||||
"#")
|
||||
|
||||
(define_split
|
||||
[(set (reg 17)
|
||||
(compare (zero_extract
|
||||
(match_operand 0 "nonimmediate_operand" "")
|
||||
(match_operand 1 "const_int_operand" "")
|
||||
(match_operand 2 "const_int_operand" ""))
|
||||
(const_int 0)))]
|
||||
[(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 (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
|
||||
[(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
|
||||
{
|
||||
HOST_WIDE_INT len = INTVAL (operands[1]);
|
||||
HOST_WIDE_INT pos = INTVAL (operands[2]);
|
||||
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 (operands[0]);
|
||||
if (GET_CODE (operands[0]) == MEM)
|
||||
mode = GET_MODE (val);
|
||||
if (GET_CODE (val) == MEM)
|
||||
{
|
||||
/* ??? 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 (operands[0]))
|
||||
if (! MEM_VOLATILE_P (val))
|
||||
{
|
||||
mode = smallest_mode_for_size (pos + len, MODE_INT);
|
||||
operands[0] = adjust_address (operands[0], mode, 0);
|
||||
val = adjust_address (val, mode, 0);
|
||||
}
|
||||
}
|
||||
else if (GET_CODE (operands[0]) == SUBREG
|
||||
&& (submode = GET_MODE (SUBREG_REG (operands[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))
|
||||
{
|
||||
/* Narrow a paradoxical subreg to prevent partial register stalls. */
|
||||
mode = submode;
|
||||
operands[0] = SUBREG_REG (operands[0]);
|
||||
val = SUBREG_REG (val);
|
||||
}
|
||||
else if (mode == HImode && pos + len <= 8)
|
||||
{
|
||||
/* Small HImode tests can be converted to QImode. */
|
||||
mode = QImode;
|
||||
operands[0] = gen_lowpart (QImode, operands[0]);
|
||||
val = gen_lowpart (QImode, val);
|
||||
}
|
||||
|
||||
mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
|
||||
mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
|
||||
|
||||
operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
|
||||
operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
|
||||
})
|
||||
|
||||
;; Convert HImode/SImode test instructions with immediate to QImode ones.
|
||||
@ -7750,46 +7778,44 @@
|
||||
;; Do the converison only post-reload to avoid limiting of the register class
|
||||
;; to QI regs.
|
||||
(define_split
|
||||
[(set (reg 17)
|
||||
(compare
|
||||
(and (match_operand 0 "register_operand" "")
|
||||
(match_operand 1 "const_int_operand" ""))
|
||||
(const_int 0)))]
|
||||
[(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[0])
|
||||
&& QI_REG_P (operands[2])
|
||||
&& GET_MODE (operands[2]) != QImode
|
||||
&& ((ix86_match_ccmode (insn, CCZmode)
|
||||
&& !(INTVAL (operands[1]) & ~(255 << 8)))
|
||||
&& !(INTVAL (operands[3]) & ~(255 << 8)))
|
||||
|| (ix86_match_ccmode (insn, CCNOmode)
|
||||
&& !(INTVAL (operands[1]) & ~(127 << 8))))
|
||||
&& GET_MODE (operands[0]) != QImode"
|
||||
[(set (reg:CCNO 17)
|
||||
(compare:CCNO
|
||||
(and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
|
||||
(match_dup 1))
|
||||
(const_int 0)))]
|
||||
"operands[0] = gen_lowpart (SImode, operands[0]);
|
||||
operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
|
||||
&& !(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 (reg 17)
|
||||
(compare
|
||||
(and (match_operand 0 "nonimmediate_operand" "")
|
||||
(match_operand 1 "const_int_operand" ""))
|
||||
(const_int 0)))]
|
||||
[(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
|
||||
&& (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
|
||||
&& GET_MODE (operands[2]) != QImode
|
||||
&& (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
|
||||
&& ((ix86_match_ccmode (insn, CCZmode)
|
||||
&& !(INTVAL (operands[1]) & ~255))
|
||||
&& !(INTVAL (operands[3]) & ~255))
|
||||
|| (ix86_match_ccmode (insn, CCNOmode)
|
||||
&& !(INTVAL (operands[1]) & ~127)))
|
||||
&& GET_MODE (operands[0]) != QImode"
|
||||
[(set (reg:CCNO 17)
|
||||
(compare:CCNO
|
||||
(and:QI (match_dup 0)
|
||||
(match_dup 1))
|
||||
(const_int 0)))]
|
||||
"operands[0] = gen_lowpart (QImode, operands[0]);
|
||||
operands[1] = gen_lowpart (QImode, operands[1]);")
|
||||
&& !(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,
|
||||
@ -8066,7 +8092,7 @@
|
||||
[(set_attr "type" "alu1")
|
||||
(set_attr "mode" "QI")])
|
||||
|
||||
(define_insn "*andqi_2"
|
||||
(define_insn "*andqi_2_maybe_si"
|
||||
[(set (reg 17)
|
||||
(compare (and:QI
|
||||
(match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
|
||||
@ -8074,13 +8100,14 @@
|
||||
(const_int 0)))
|
||||
(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
|
||||
(and:QI (match_dup 1) (match_dup 2)))]
|
||||
"ix86_match_ccmode (insn, CCNOmode)
|
||||
&& ix86_binary_operator_ok (AND, QImode, operands)"
|
||||
"ix86_binary_operator_ok (AND, QImode, operands)
|
||||
&& ix86_match_ccmode (insn,
|
||||
GET_CODE (operands[2]) == CONST_INT
|
||||
&& INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
|
||||
{
|
||||
if (which_alternative == 2)
|
||||
{
|
||||
if (GET_CODE (operands[2]) == CONST_INT
|
||||
&& (INTVAL (operands[2]) & 0xffffff00))
|
||||
if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
|
||||
operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
|
||||
return "and{l}\t{%2, %k0|%k0, %2}";
|
||||
}
|
||||
@ -8089,6 +8116,20 @@
|
||||
[(set_attr "type" "alu")
|
||||
(set_attr "mode" "QI,QI,SI")])
|
||||
|
||||
(define_insn "*andqi_2"
|
||||
[(set (reg 17)
|
||||
(compare (and:QI
|
||||
(match_operand:QI 1 "nonimmediate_operand" "%0,0")
|
||||
(match_operand:QI 2 "general_operand" "qim,qi"))
|
||||
(const_int 0)))
|
||||
(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
|
||||
(and:QI (match_dup 1) (match_dup 2)))]
|
||||
"ix86_match_ccmode (insn, CCNOmode)
|
||||
&& ix86_binary_operator_ok (AND, QImode, operands)"
|
||||
"and{b}\t{%2, %0|%0, %2}"
|
||||
[(set_attr "type" "alu")
|
||||
(set_attr "mode" "QI")])
|
||||
|
||||
(define_insn "*andqi_2_slp"
|
||||
[(set (reg 17)
|
||||
(compare (and:QI
|
||||
@ -10147,17 +10188,19 @@
|
||||
(set_attr "mode" "DI")])
|
||||
|
||||
(define_split
|
||||
[(set (reg 17)
|
||||
(compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
|
||||
(const_int 0)))
|
||||
(set (match_operand:DI 0 "nonimmediate_operand" "")
|
||||
(not:DI (match_dup 1)))]
|
||||
[(set (match_operand 0 "flags_reg_operand" "")
|
||||
(match_operator 2 "compare_operator"
|
||||
[(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
|
||||
(const_int 0)]))
|
||||
(set (match_operand:DI 1 "nonimmediate_operand" "")
|
||||
(not:DI (match_dup 3)))]
|
||||
"TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
|
||||
[(parallel [(set (reg:CCNO 17)
|
||||
(compare:CCNO (xor:DI (match_dup 1) (const_int -1))
|
||||
(const_int 0)))
|
||||
(set (match_dup 0)
|
||||
(xor:DI (match_dup 1) (const_int -1)))])]
|
||||
[(parallel [(set (match_dup 0)
|
||||
(match_op_dup 2
|
||||
[(xor:DI (match_dup 3) (const_int -1))
|
||||
(const_int 0)]))
|
||||
(set (match_dup 1)
|
||||
(xor:DI (match_dup 3) (const_int -1)))])]
|
||||
"")
|
||||
|
||||
(define_expand "one_cmplsi2"
|
||||
@ -10196,17 +10239,18 @@
|
||||
(set_attr "mode" "SI")])
|
||||
|
||||
(define_split
|
||||
[(set (reg 17)
|
||||
(compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
|
||||
(const_int 0)))
|
||||
(set (match_operand:SI 0 "nonimmediate_operand" "")
|
||||
(not:SI (match_dup 1)))]
|
||||
[(set (match_operand 0 "flags_reg_operand" "")
|
||||
(match_operator 2 "compare_operator"
|
||||
[(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
|
||||
(const_int 0)]))
|
||||
(set (match_operand:SI 1 "nonimmediate_operand" "")
|
||||
(not:SI (match_dup 3)))]
|
||||
"ix86_match_ccmode (insn, CCNOmode)"
|
||||
[(parallel [(set (reg:CCNO 17)
|
||||
(compare:CCNO (xor:SI (match_dup 1) (const_int -1))
|
||||
(const_int 0)))
|
||||
(set (match_dup 0)
|
||||
(xor:SI (match_dup 1) (const_int -1)))])]
|
||||
[(parallel [(set (match_dup 0)
|
||||
(match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
|
||||
(const_int 0)]))
|
||||
(set (match_dup 1)
|
||||
(xor:SI (match_dup 3) (const_int -1)))])]
|
||||
"")
|
||||
|
||||
;; ??? Currently never generated - xor is used instead.
|
||||
@ -10223,17 +10267,18 @@
|
||||
(set_attr "mode" "SI")])
|
||||
|
||||
(define_split
|
||||
[(set (reg 17)
|
||||
(compare (not:SI (match_operand:SI 1 "register_operand" ""))
|
||||
(const_int 0)))
|
||||
(set (match_operand:DI 0 "register_operand" "")
|
||||
(zero_extend:DI (not:SI (match_dup 1))))]
|
||||
[(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 (reg:CCNO 17)
|
||||
(compare:CCNO (xor:SI (match_dup 1) (const_int -1))
|
||||
(const_int 0)))
|
||||
(set (match_dup 0)
|
||||
(zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
|
||||
[(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))))])]
|
||||
"")
|
||||
|
||||
(define_expand "one_cmplhi2"
|
||||
@ -10263,17 +10308,18 @@
|
||||
(set_attr "mode" "HI")])
|
||||
|
||||
(define_split
|
||||
[(set (reg 17)
|
||||
(compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
|
||||
(const_int 0)))
|
||||
(set (match_operand:HI 0 "nonimmediate_operand" "")
|
||||
(not:HI (match_dup 1)))]
|
||||
[(set (match_operand 0 "flags_reg_operand" "")
|
||||
(match_operator 2 "compare_operator"
|
||||
[(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
|
||||
(const_int 0)]))
|
||||
(set (match_operand:HI 1 "nonimmediate_operand" "")
|
||||
(not:HI (match_dup 3)))]
|
||||
"ix86_match_ccmode (insn, CCNOmode)"
|
||||
[(parallel [(set (reg:CCNO 17)
|
||||
(compare:CCNO (xor:HI (match_dup 1) (const_int -1))
|
||||
(const_int 0)))
|
||||
(set (match_dup 0)
|
||||
(xor:HI (match_dup 1) (const_int -1)))])]
|
||||
[(parallel [(set (match_dup 0)
|
||||
(match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
|
||||
(const_int 0)]))
|
||||
(set (match_dup 1)
|
||||
(xor:HI (match_dup 3) (const_int -1)))])]
|
||||
"")
|
||||
|
||||
;; %%% Potential partial reg stall on alternative 1. What to do?
|
||||
@ -10306,17 +10352,18 @@
|
||||
(set_attr "mode" "QI")])
|
||||
|
||||
(define_split
|
||||
[(set (reg 17)
|
||||
(compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
|
||||
(const_int 0)))
|
||||
(set (match_operand:QI 0 "nonimmediate_operand" "")
|
||||
(not:QI (match_dup 1)))]
|
||||
[(set (match_operand 0 "flags_reg_operand" "")
|
||||
(match_operator 2 "compare_operator"
|
||||
[(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
|
||||
(const_int 0)]))
|
||||
(set (match_operand:QI 1 "nonimmediate_operand" "")
|
||||
(not:QI (match_dup 3)))]
|
||||
"ix86_match_ccmode (insn, CCNOmode)"
|
||||
[(parallel [(set (reg:CCNO 17)
|
||||
(compare:CCNO (xor:QI (match_dup 1) (const_int -1))
|
||||
(const_int 0)))
|
||||
(set (match_dup 0)
|
||||
(xor:QI (match_dup 1) (const_int -1)))])]
|
||||
[(parallel [(set (match_dup 0)
|
||||
(match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
|
||||
(const_int 0)]))
|
||||
(set (match_dup 1)
|
||||
(xor:QI (match_dup 3) (const_int -1)))])]
|
||||
"")
|
||||
|
||||
;; Arithmetic shift instructions
|
||||
@ -12422,10 +12469,10 @@
|
||||
})
|
||||
|
||||
(define_expand "insv"
|
||||
[(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
|
||||
(match_operand:SI 1 "immediate_operand" "")
|
||||
(match_operand:SI 2 "immediate_operand" ""))
|
||||
(match_operand:SI 3 "register_operand" ""))]
|
||||
[(set (zero_extract (match_operand 0 "ext_register_operand" "")
|
||||
(match_operand 1 "immediate_operand" "")
|
||||
(match_operand 2 "immediate_operand" ""))
|
||||
(match_operand 3 "register_operand" ""))]
|
||||
""
|
||||
{
|
||||
/* Handle extractions from %ah et al. */
|
||||
@ -12436,6 +12483,13 @@
|
||||
matches the predicate, so check it again here. */
|
||||
if (! register_operand (operands[0], VOIDmode))
|
||||
FAIL;
|
||||
|
||||
if (TARGET_64BIT)
|
||||
emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
|
||||
else
|
||||
emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
|
||||
|
||||
DONE;
|
||||
})
|
||||
|
||||
;; %%% bts, btr, btc, bt.
|
||||
@ -16632,10 +16686,12 @@
|
||||
(set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
|
||||
(subreg:TI (match_dup 7) 0)))]
|
||||
{
|
||||
/* If op2 == op3, op3 will be clobbered before it is used.
|
||||
This should be optimized out though. */
|
||||
/* If op2 == op3, op3 would be clobbered before it is used. */
|
||||
if (operands_match_p (operands[2], operands[3]))
|
||||
abort ();
|
||||
{
|
||||
emit_move_insn (operands[0], operands[2]);
|
||||
DONE;
|
||||
}
|
||||
PUT_MODE (operands[1], GET_MODE (operands[0]));
|
||||
if (operands_match_p (operands[0], operands[4]))
|
||||
operands[6] = operands[4], operands[7] = operands[2];
|
||||
@ -16856,52 +16912,56 @@
|
||||
; instruction size is unchanged, except in the %eax case for
|
||||
; which it is increased by one byte, hence the ! optimize_size.
|
||||
(define_split
|
||||
[(set (reg 17)
|
||||
(compare (and (match_operand 1 "aligned_operand" "")
|
||||
(match_operand 2 "const_int_operand" ""))
|
||||
(const_int 0)))
|
||||
(set (match_operand 0 "register_operand" "")
|
||||
(and (match_dup 1) (match_dup 2)))]
|
||||
[(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
|
||||
/* Ensure that the operand will remain sign-extended immediate. */
|
||||
&& ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
|
||||
&& ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
|
||||
&& ! optimize_size
|
||||
&& ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
|
||||
|| (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
|
||||
[(parallel [(set (reg:CCNO 17)
|
||||
(compare:CCNO (and:SI (match_dup 1) (match_dup 2))
|
||||
(const_int 0)))
|
||||
(set (match_dup 0)
|
||||
(and:SI (match_dup 1) (match_dup 2)))])]
|
||||
"operands[2]
|
||||
= gen_int_mode (INTVAL (operands[2])
|
||||
& GET_MODE_MASK (GET_MODE (operands[0])),
|
||||
SImode);
|
||||
operands[0] = gen_lowpart (SImode, operands[0]);
|
||||
operands[1] = gen_lowpart (SImode, operands[1]);")
|
||||
&& ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
|
||||
|| (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
|
||||
[(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 (reg 17)
|
||||
(compare (and (match_operand:HI 0 "aligned_operand" "")
|
||||
(match_operand:HI 1 "const_int_operand" ""))
|
||||
(const_int 0)))]
|
||||
[(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
|
||||
/* Ensure that the operand will remain sign-extended immediate. */
|
||||
&& ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
|
||||
&& ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
|
||||
&& ! TARGET_FAST_PREFIX
|
||||
&& ! optimize_size"
|
||||
[(set (reg:CCNO 17)
|
||||
(compare:CCNO (and:SI (match_dup 0) (match_dup 1))
|
||||
(const_int 0)))]
|
||||
"operands[1]
|
||||
= gen_int_mode (INTVAL (operands[1])
|
||||
& GET_MODE_MASK (GET_MODE (operands[0])),
|
||||
SImode);
|
||||
operands[0] = gen_lowpart (SImode, operands[0]);")
|
||||
[(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" "")
|
||||
@ -17074,13 +17134,14 @@
|
||||
|
||||
;; Don't compare memory with zero, load and use a test instead.
|
||||
(define_peephole2
|
||||
[(set (reg 17)
|
||||
(compare (match_operand:SI 0 "memory_operand" "")
|
||||
(const_int 0)))
|
||||
[(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")]
|
||||
"ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
|
||||
[(set (match_dup 3) (match_dup 0))
|
||||
(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
|
||||
[(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.
|
||||
@ -17144,77 +17205,77 @@
|
||||
;; versions if we're concerned about partial register stalls.
|
||||
|
||||
(define_peephole2
|
||||
[(set (reg 17)
|
||||
(compare (and:SI (match_operand:SI 0 "register_operand" "")
|
||||
(match_operand:SI 1 "immediate_operand" ""))
|
||||
(const_int 0)))]
|
||||
[(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[0]) != 0
|
||||
|| (GET_CODE (operands[1]) == CONST_INT
|
||||
&& CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
|
||||
&& find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
|
||||
&& (true_regnum (operands[2]) != 0
|
||||
|| (GET_CODE (operands[3]) == CONST_INT
|
||||
&& CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
|
||||
&& peep2_reg_dead_p (1, operands[2])"
|
||||
[(parallel
|
||||
[(set (reg:CCNO 17)
|
||||
(compare:CCNO (and:SI (match_dup 0)
|
||||
(match_dup 1))
|
||||
(const_int 0)))
|
||||
(set (match_dup 0)
|
||||
(and:SI (match_dup 0) (match_dup 1)))])]
|
||||
[(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 (reg 17)
|
||||
(compare (and:QI (match_operand:QI 0 "register_operand" "")
|
||||
(match_operand:QI 1 "immediate_operand" ""))
|
||||
(const_int 0)))]
|
||||
[(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[0]) != 0
|
||||
&& find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
|
||||
&& true_regnum (operands[2]) != 0
|
||||
&& peep2_reg_dead_p (1, operands[2])"
|
||||
[(parallel
|
||||
[(set (reg:CCNO 17)
|
||||
(compare:CCNO (and:QI (match_dup 0)
|
||||
(match_dup 1))
|
||||
(const_int 0)))
|
||||
(set (match_dup 0)
|
||||
(and:QI (match_dup 0) (match_dup 1)))])]
|
||||
[(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 (reg 17)
|
||||
(compare
|
||||
(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)))]
|
||||
[(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[0]) != 0
|
||||
&& find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
|
||||
[(parallel [(set (reg:CCNO 17)
|
||||
(compare:CCNO
|
||||
(and:SI
|
||||
(zero_extract:SI
|
||||
(match_dup 0)
|
||||
(const_int 8)
|
||||
(const_int 8))
|
||||
(match_dup 1))
|
||||
(const_int 0)))
|
||||
(set (zero_extract:SI (match_dup 0)
|
||||
&& true_regnum (operands[2]) != 0
|
||||
&& 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 0)
|
||||
(match_dup 2)
|
||||
(const_int 8)
|
||||
(const_int 8))
|
||||
(match_dup 1)))])]
|
||||
(match_dup 3)))])]
|
||||
"")
|
||||
|
||||
;; Don't do logical operations with memory inputs.
|
||||
@ -17516,66 +17577,20 @@
|
||||
"")
|
||||
|
||||
;; Convert compares with 1 to shorter inc/dec operations when CF is not
|
||||
;; required and register dies.
|
||||
;; required and register dies. Similarly for 128 to plus -128.
|
||||
(define_peephole2
|
||||
[(set (reg 17)
|
||||
(compare (match_operand:SI 0 "register_operand" "")
|
||||
(match_operand:SI 1 "incdec_operand" "")))]
|
||||
"ix86_match_ccmode (insn, CCGCmode)
|
||||
&& find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
|
||||
[(parallel [(set (reg:CCGC 17)
|
||||
(compare:CCGC (match_dup 0)
|
||||
(match_dup 1)))
|
||||
(clobber (match_dup 0))])]
|
||||
"")
|
||||
|
||||
(define_peephole2
|
||||
[(set (reg 17)
|
||||
(compare (match_operand:HI 0 "register_operand" "")
|
||||
(match_operand:HI 1 "incdec_operand" "")))]
|
||||
"ix86_match_ccmode (insn, CCGCmode)
|
||||
&& find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
|
||||
[(parallel [(set (reg:CCGC 17)
|
||||
(compare:CCGC (match_dup 0)
|
||||
(match_dup 1)))
|
||||
(clobber (match_dup 0))])]
|
||||
"")
|
||||
|
||||
(define_peephole2
|
||||
[(set (reg 17)
|
||||
(compare (match_operand:QI 0 "register_operand" "")
|
||||
(match_operand:QI 1 "incdec_operand" "")))]
|
||||
"ix86_match_ccmode (insn, CCGCmode)
|
||||
&& find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
|
||||
[(parallel [(set (reg:CCGC 17)
|
||||
(compare:CCGC (match_dup 0)
|
||||
(match_dup 1)))
|
||||
(clobber (match_dup 0))])]
|
||||
"")
|
||||
|
||||
;; Convert compares with 128 to shorter add -128
|
||||
(define_peephole2
|
||||
[(set (reg 17)
|
||||
(compare (match_operand:SI 0 "register_operand" "")
|
||||
(const_int 128)))]
|
||||
"ix86_match_ccmode (insn, CCGCmode)
|
||||
&& find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
|
||||
[(parallel [(set (reg:CCGC 17)
|
||||
(compare:CCGC (match_dup 0)
|
||||
(const_int 128)))
|
||||
(clobber (match_dup 0))])]
|
||||
"")
|
||||
|
||||
(define_peephole2
|
||||
[(set (reg 17)
|
||||
(compare (match_operand:HI 0 "register_operand" "")
|
||||
(const_int 128)))]
|
||||
"ix86_match_ccmode (insn, CCGCmode)
|
||||
&& find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
|
||||
[(parallel [(set (reg:CCGC 17)
|
||||
(compare:CCGC (match_dup 0)
|
||||
(const_int 128)))
|
||||
(clobber (match_dup 0))])]
|
||||
[(set (match_operand 0 "flags_reg_operand" "")
|
||||
(match_operator 1 "compare_operator"
|
||||
[(match_operand 2 "register_operand" "")
|
||||
(match_operand 3 "const_int_operand" "")]))]
|
||||
"(INTVAL (operands[3]) == -1
|
||||
|| INTVAL (operands[3]) == 1
|
||||
|| 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))])]
|
||||
"")
|
||||
|
||||
(define_peephole2
|
||||
@ -17773,9 +17788,9 @@
|
||||
return "call\t%P1";
|
||||
}
|
||||
if (SIBLING_CALL_P (insn))
|
||||
return "jmp\t%*%1";
|
||||
return "jmp\t%A1";
|
||||
else
|
||||
return "call\t%*%1";
|
||||
return "call\t%A1";
|
||||
}
|
||||
[(set_attr "type" "callv")])
|
||||
|
||||
|
70
gnu/dist/gcc/gcc/config/ia64/ia64.c
vendored
70
gnu/dist/gcc/gcc/config/ia64/ia64.c
vendored
@ -1086,8 +1086,7 @@ ia64_expand_load_address (dest, src, scratch)
|
||||
if (! scratch)
|
||||
scratch = no_new_pseudos ? subtarget : gen_reg_rtx (DImode);
|
||||
|
||||
emit_insn (gen_load_symptr (subtarget, plus_constant (sym, hi),
|
||||
scratch));
|
||||
ia64_expand_load_address (subtarget, plus_constant (sym, hi), scratch);
|
||||
emit_insn (gen_adddi3 (temp, subtarget, GEN_INT (lo)));
|
||||
}
|
||||
else
|
||||
@ -2885,10 +2884,13 @@ ia64_expand_epilogue (sibcall_p)
|
||||
preserve those input registers used as arguments to the sibling call.
|
||||
It is unclear how to compute that number here. */
|
||||
if (current_frame_info.n_input_regs != 0)
|
||||
emit_insn (gen_alloc (gen_rtx_REG (DImode, fp),
|
||||
GEN_INT (0), GEN_INT (0),
|
||||
GEN_INT (current_frame_info.n_input_regs),
|
||||
GEN_INT (0)));
|
||||
{
|
||||
rtx n_inputs = GEN_INT (current_frame_info.n_input_regs);
|
||||
insn = emit_insn (gen_alloc (gen_rtx_REG (DImode, fp),
|
||||
const0_rtx, const0_rtx,
|
||||
n_inputs, const0_rtx));
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3022,15 +3024,16 @@ ia64_assemble_integer (x, size, aligned_p)
|
||||
int aligned_p;
|
||||
{
|
||||
if (size == (TARGET_ILP32 ? 4 : 8)
|
||||
&& aligned_p
|
||||
&& !(TARGET_NO_PIC || TARGET_AUTO_PIC)
|
||||
&& GET_CODE (x) == SYMBOL_REF
|
||||
&& SYMBOL_REF_FLAG (x))
|
||||
{
|
||||
if (TARGET_ILP32)
|
||||
fputs ("\tdata4\t@fptr(", asm_out_file);
|
||||
else
|
||||
fputs ("\tdata8\t@fptr(", asm_out_file);
|
||||
static const char * const directive[2][2] = {
|
||||
/* 64-bit pointer */ /* 32-bit pointer */
|
||||
{ "\tdata8.ua\t@fptr(", "\tdata4.ua\t@fptr("}, /* unaligned */
|
||||
{ "\tdata8\t@fptr(", "\tdata4\t@fptr("} /* aligned */
|
||||
};
|
||||
fputs (directive[aligned_p != 0][TARGET_ILP32 != 0], asm_out_file);
|
||||
output_addr_const (asm_out_file, x);
|
||||
fputs (")\n", asm_out_file);
|
||||
return true;
|
||||
@ -7175,11 +7178,12 @@ ia64_reorg (insns)
|
||||
insn = get_last_insn ();
|
||||
if (! INSN_P (insn))
|
||||
insn = prev_active_insn (insn);
|
||||
if (GET_CODE (insn) == INSN
|
||||
&& GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
|
||||
&& XINT (PATTERN (insn), 1) == UNSPECV_INSN_GROUP_BARRIER)
|
||||
{
|
||||
saw_stop = 1;
|
||||
/* Skip over insns that expand to nothing. */
|
||||
while (GET_CODE (insn) == INSN && get_attr_empty (insn) == EMPTY_YES)
|
||||
{
|
||||
if (GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
|
||||
&& XINT (PATTERN (insn), 1) == UNSPECV_INSN_GROUP_BARRIER)
|
||||
saw_stop = 1;
|
||||
insn = prev_active_insn (insn);
|
||||
}
|
||||
if (GET_CODE (insn) == CALL_INSN)
|
||||
@ -7356,7 +7360,8 @@ ia64_encode_section_info (decl, first)
|
||||
if (encoding == symbol_str[1])
|
||||
return;
|
||||
/* ??? Sdata became thread or thread becaome not thread. Lose. */
|
||||
abort ();
|
||||
if (encoding == 's' || symbol_str[1] == 's')
|
||||
abort ();
|
||||
}
|
||||
|
||||
len = strlen (symbol_str);
|
||||
@ -7394,6 +7399,12 @@ bool
|
||||
ia64_function_ok_for_sibcall (decl)
|
||||
tree decl;
|
||||
{
|
||||
/* We can't perform a sibcall if the current function has the syscall_linkage
|
||||
attribute. */
|
||||
if (lookup_attribute ("syscall_linkage",
|
||||
TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
|
||||
return false;
|
||||
|
||||
/* We must always return with our current GP. This means we can
|
||||
only sibcall to functions defined in the current module. */
|
||||
return decl && (*targetm.binds_local_p) (decl);
|
||||
@ -7445,13 +7456,24 @@ process_set (asm_out_file, pat)
|
||||
{
|
||||
dest_regno = REGNO (dest);
|
||||
|
||||
/* If this isn't the final destination for ar.pfs, the alloc
|
||||
shouldn't have been marked frame related. */
|
||||
if (dest_regno != current_frame_info.reg_save_ar_pfs)
|
||||
abort ();
|
||||
|
||||
fprintf (asm_out_file, "\t.save ar.pfs, r%d\n",
|
||||
ia64_dbx_register_number (dest_regno));
|
||||
/* If this is the final destination for ar.pfs, then this must
|
||||
be the alloc in the prologue. */
|
||||
if (dest_regno == current_frame_info.reg_save_ar_pfs)
|
||||
fprintf (asm_out_file, "\t.save ar.pfs, r%d\n",
|
||||
ia64_dbx_register_number (dest_regno));
|
||||
else
|
||||
{
|
||||
/* This must be an alloc before a sibcall. We must drop the
|
||||
old frame info. The easiest way to drop the old frame
|
||||
info is to ensure we had a ".restore sp" directive
|
||||
followed by a new prologue. If the procedure doesn't
|
||||
have a memory-stack frame, we'll issue a dummy ".restore
|
||||
sp" now. */
|
||||
if (current_frame_info.total_size == 0 && !frame_pointer_needed)
|
||||
/* if haven't done process_epilogue() yet, do it now */
|
||||
process_epilogue ();
|
||||
fprintf (asm_out_file, "\t.prologue\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
13
gnu/dist/gcc/gcc/config/ia64/ia64.md
vendored
13
gnu/dist/gcc/gcc/config/ia64/ia64.md
vendored
@ -147,6 +147,10 @@
|
||||
|
||||
(define_attr "predicable" "no,yes" (const_string "yes"))
|
||||
|
||||
;; Empty. True iff this insn does not generate any code.
|
||||
|
||||
(define_attr "empty" "no,yes" (const_string "no"))
|
||||
|
||||
|
||||
;; ::::::::::::::::::::
|
||||
;; ::
|
||||
@ -5062,7 +5066,8 @@
|
||||
""
|
||||
""
|
||||
[(set_attr "itanium_class" "ignore")
|
||||
(set_attr "predicable" "no")])
|
||||
(set_attr "predicable" "no")
|
||||
(set_attr "empty" "yes")])
|
||||
|
||||
;; Allocate a new register frame.
|
||||
|
||||
@ -5229,7 +5234,8 @@
|
||||
[(const_int 5)]
|
||||
""
|
||||
""
|
||||
[(set_attr "itanium_class" "nop_x")])
|
||||
[(set_attr "itanium_class" "nop_x")
|
||||
(set_attr "empty" "yes")])
|
||||
|
||||
(define_insn "bundle_selector"
|
||||
[(unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BUNDLE_SELECTOR)]
|
||||
@ -5253,7 +5259,8 @@
|
||||
""
|
||||
";;"
|
||||
[(set_attr "itanium_class" "stop_bit")
|
||||
(set_attr "predicable" "no")])
|
||||
(set_attr "predicable" "no")
|
||||
(set_attr "empty" "yes")])
|
||||
|
||||
(define_expand "trap"
|
||||
[(trap_if (const_int 1) (const_int 0))]
|
||||
|
2
gnu/dist/gcc/gcc/config/ia64/unwind-ia64.c
vendored
2
gnu/dist/gcc/gcc/config/ia64/unwind-ia64.c
vendored
@ -2176,6 +2176,8 @@ uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
|
||||
"(p6) ldf.fill f22 = [r28] \n\t"
|
||||
"cmp.ne p7, p0 = r0, r29 \n\t"
|
||||
";; \n\t"
|
||||
"ld8 r27 = [r20], 8 \n\t"
|
||||
";; \n\t"
|
||||
"ld8 r28 = [r20], 8 \n\t"
|
||||
"(p7) ldf.fill f23 = [r29] \n\t"
|
||||
"cmp.ne p6, p0 = r0, r22 \n\t"
|
||||
|
@ -53,7 +53,7 @@ DPBIT = dp-bit.c
|
||||
dp-bit.c: $(srcdir)/config/fp-bit.c
|
||||
echo '#define SMALL_MACHINE' >> dp-bit.c
|
||||
echo '#define CMPtype HItype' >> dp-bit.c
|
||||
echo '#ifdef __LITTLE_ENDIAN__' > dp-bit.c
|
||||
echo '#ifdef __LITTLE_ENDIAN__' >> dp-bit.c
|
||||
echo '#define FLOAT_BIT_ORDER_MISMATCH' >>dp-bit.c
|
||||
echo '#endif' >> dp-bit.c
|
||||
cat $(srcdir)/config/fp-bit.c >> dp-bit.c
|
||||
|
12
gnu/dist/gcc/gcc/config/mips/mips-protos.h
vendored
12
gnu/dist/gcc/gcc/config/mips/mips-protos.h
vendored
@ -1,6 +1,6 @@
|
||||
/* Prototypes of target machine for GNU compiler. MIPS version.
|
||||
Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2001, 2002 Free Software Foundation, Inc.
|
||||
1999, 2001, 2002, 2005 Free Software Foundation, Inc.
|
||||
Contributed by A. Lichnewsky (lich@inria.inria.fr).
|
||||
Changed by Michael Meissner (meissner@osf.org).
|
||||
64 bit r4000 support by Ian Lance Taylor (ian@cygnus.com) and
|
||||
@ -36,9 +36,13 @@ extern void iris6_asm_output_align PARAMS ((FILE *, unsigned));
|
||||
extern const char * current_section_name PARAMS ((void));
|
||||
extern unsigned int current_section_flags PARAMS ((void));
|
||||
extern int mips_can_use_return_insn PARAMS ((void));
|
||||
extern void mips_declare_object PARAMS ((FILE *, const char *,
|
||||
const char *,
|
||||
const char *, int));
|
||||
extern void mips_output_aligned_decl_common
|
||||
PARAMS ((FILE *, tree, const char *,
|
||||
unsigned HOST_WIDE_INT,
|
||||
unsigned int));
|
||||
extern void mips_declare_object
|
||||
PARAMS ((FILE *, const char *, const char *,
|
||||
const char *, ...));
|
||||
extern void mips_expand_epilogue PARAMS ((void));
|
||||
extern void mips_expand_prologue PARAMS ((void));
|
||||
extern void mips_output_filename PARAMS ((FILE *, const char *));
|
||||
|
25
gnu/dist/gcc/gcc/config/mips/mips.h
vendored
25
gnu/dist/gcc/gcc/config/mips/mips.h
vendored
@ -1,6 +1,6 @@
|
||||
/* Definitions of target machine for GNU compiler. MIPS version.
|
||||
Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
|
||||
1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
Contributed by A. Lichnewsky (lich@inria.inria.fr).
|
||||
Changed by Michael Meissner (meissner@osf.org).
|
||||
64 bit r4000 support by Ian Lance Taylor (ian@cygnus.com) and
|
||||
@ -4326,28 +4326,7 @@ while (0)
|
||||
|
||||
/* This says how to define a global common symbol. */
|
||||
|
||||
#define ASM_OUTPUT_ALIGNED_DECL_COMMON(STREAM, DECL, NAME, SIZE, ALIGN) \
|
||||
do { \
|
||||
/* If the target wants uninitialized const declarations in \
|
||||
.rdata then don't put them in .comm */ \
|
||||
if (TARGET_EMBEDDED_DATA && TARGET_UNINIT_CONST_IN_RODATA \
|
||||
&& TREE_CODE (DECL) == VAR_DECL && TREE_READONLY (DECL) \
|
||||
&& (DECL_INITIAL (DECL) == 0 \
|
||||
|| DECL_INITIAL (DECL) == error_mark_node)) \
|
||||
{ \
|
||||
if (TREE_PUBLIC (DECL) && DECL_NAME (DECL)) \
|
||||
(*targetm.asm_out.globalize_label) (STREAM, NAME); \
|
||||
\
|
||||
readonly_data_section (); \
|
||||
ASM_OUTPUT_ALIGN (STREAM, floor_log2 (ALIGN / BITS_PER_UNIT)); \
|
||||
mips_declare_object (STREAM, NAME, "", ":\n\t.space\t%u\n", \
|
||||
(SIZE)); \
|
||||
} \
|
||||
else \
|
||||
mips_declare_object (STREAM, NAME, "\n\t.comm\t", ",%u\n", \
|
||||
(SIZE)); \
|
||||
} while (0)
|
||||
|
||||
#define ASM_OUTPUT_ALIGNED_DECL_COMMON mips_output_aligned_decl_common
|
||||
|
||||
/* This says how to define a local common symbol (ie, not visible to
|
||||
linker). */
|
||||
|
9
gnu/dist/gcc/gcc/config/mips/mips.md
vendored
9
gnu/dist/gcc/gcc/config/mips/mips.md
vendored
@ -1,6 +1,6 @@
|
||||
;; Mips.md Machine Description for MIPS based processors
|
||||
;; Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
;; 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
;; 1999, 2000, 2001, 2002, 2005 Free Software Foundation, Inc.
|
||||
;; Contributed by A. Lichnewsky, lich@inria.inria.fr
|
||||
;; Changes by Michael Meissner, meissner@osf.org
|
||||
;; 64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
|
||||
@ -104,7 +104,7 @@
|
||||
(define_attr "length" ""
|
||||
(cond [(eq_attr "type" "branch")
|
||||
(cond [(lt (abs (minus (match_dup 1) (plus (pc) (const_int 4))))
|
||||
(const_int 131072))
|
||||
(const_int 65536))
|
||||
(const_int 4)
|
||||
(ne (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC")
|
||||
(const_int 0))
|
||||
@ -163,7 +163,8 @@
|
||||
|
||||
;; Describe a user's asm statement.
|
||||
(define_asm_attributes
|
||||
[(set_attr "type" "multi")])
|
||||
[(set_attr "type" "multi")
|
||||
(set_attr "can_delay" "no")])
|
||||
|
||||
;; whether or not generating calls to position independent functions
|
||||
(define_attr "abicalls" "no,yes"
|
||||
@ -9625,7 +9626,7 @@ move\\t%0,%z4\\n\\
|
||||
(const_int 0))
|
||||
(lt (abs (minus (match_dup 0)
|
||||
(plus (pc) (const_int 4))))
|
||||
(const_int 131072)))
|
||||
(const_int 65536)))
|
||||
(const_int 4) (const_int 16)))])
|
||||
|
||||
;; We need a different insn for the mips16, because a mips16 branch
|
||||
|
28
gnu/dist/gcc/gcc/config/pa/pa.c
vendored
28
gnu/dist/gcc/gcc/config/pa/pa.c
vendored
@ -1401,14 +1401,17 @@ emit_move_sequence (operands, mode, scratch_reg)
|
||||
operand1 = gen_rtx_MEM (GET_MODE (operand1), tem);
|
||||
|
||||
/* Handle secondary reloads for loads/stores of FP registers from
|
||||
REG+D addresses where D does not fit in 5 bits, including
|
||||
REG+D addresses where D does not fit in 5 or 14 bits, including
|
||||
(subreg (mem (addr))) cases. */
|
||||
if (fp_reg_operand (operand0, mode)
|
||||
&& ((GET_CODE (operand1) == MEM
|
||||
&& ! memory_address_p (DFmode, XEXP (operand1, 0)))
|
||||
&& !memory_address_p ((GET_MODE_SIZE (mode) == 4 ? SFmode : DFmode),
|
||||
XEXP (operand1, 0)))
|
||||
|| ((GET_CODE (operand1) == SUBREG
|
||||
&& GET_CODE (XEXP (operand1, 0)) == MEM
|
||||
&& !memory_address_p (DFmode, XEXP (XEXP (operand1, 0), 0)))))
|
||||
&& !memory_address_p ((GET_MODE_SIZE (mode) == 4
|
||||
? SFmode : DFmode),
|
||||
XEXP (XEXP (operand1, 0), 0)))))
|
||||
&& scratch_reg)
|
||||
{
|
||||
if (GET_CODE (operand1) == SUBREG)
|
||||
@ -1437,10 +1440,14 @@ emit_move_sequence (operands, mode, scratch_reg)
|
||||
}
|
||||
else if (fp_reg_operand (operand1, mode)
|
||||
&& ((GET_CODE (operand0) == MEM
|
||||
&& ! memory_address_p (DFmode, XEXP (operand0, 0)))
|
||||
&& !memory_address_p ((GET_MODE_SIZE (mode) == 4
|
||||
? SFmode : DFmode),
|
||||
XEXP (operand0, 0)))
|
||||
|| ((GET_CODE (operand0) == SUBREG)
|
||||
&& GET_CODE (XEXP (operand0, 0)) == MEM
|
||||
&& !memory_address_p (DFmode, XEXP (XEXP (operand0, 0), 0))))
|
||||
&& !memory_address_p ((GET_MODE_SIZE (mode) == 4
|
||||
? SFmode : DFmode),
|
||||
XEXP (XEXP (operand0, 0), 0))))
|
||||
&& scratch_reg)
|
||||
{
|
||||
if (GET_CODE (operand0) == SUBREG)
|
||||
@ -1706,6 +1713,7 @@ emit_move_sequence (operands, mode, scratch_reg)
|
||||
operands[1] = force_const_mem (mode, operand1);
|
||||
operands[1] = legitimize_pic_address (XEXP (operands[1], 0),
|
||||
mode, temp);
|
||||
operands[1] = gen_rtx_MEM (mode, operands[1]);
|
||||
emit_move_sequence (operands, mode, temp);
|
||||
}
|
||||
else
|
||||
@ -6931,7 +6939,15 @@ output_indirect_call (insn, call_dest)
|
||||
No need to check target flags as the length uniquely identifies
|
||||
the remaining cases. */
|
||||
if (attr_length_indirect_call (insn) == 8)
|
||||
return ".CALL\tARGW0=GR\n\t{bl|b,l} $$dyncall,%%r31\n\tcopy %%r31,%%r2";
|
||||
{
|
||||
/* The HP linker substitutes a BLE for millicode calls using
|
||||
the short PIC PCREL form. Thus, we must use %r31 as the
|
||||
link register when generating PA 1.x code. */
|
||||
if (TARGET_PA_20)
|
||||
return ".CALL\tARGW0=GR\n\tb,l $$dyncall,%%r2\n\tcopy %%r2,%%r31";
|
||||
else
|
||||
return ".CALL\tARGW0=GR\n\tbl $$dyncall,%%r31\n\tcopy %%r31,%%r2";
|
||||
}
|
||||
|
||||
/* Long millicode call, but we are not generating PIC or portable runtime
|
||||
code. */
|
||||
|
227
gnu/dist/gcc/gcc/config/pa/pa.h
vendored
227
gnu/dist/gcc/gcc/config/pa/pa.h
vendored
@ -991,7 +991,7 @@ extern int may_call_alloca;
|
||||
|
||||
#define TRAMPOLINE_TEMPLATE(FILE) \
|
||||
{ \
|
||||
if (! TARGET_64BIT) \
|
||||
if (!TARGET_64BIT) \
|
||||
{ \
|
||||
fputs ("\tldw 36(%r22),%r21\n", FILE); \
|
||||
fputs ("\tbb,>=,n %r21,30,.+16\n", FILE); \
|
||||
@ -1001,10 +1001,20 @@ extern int may_call_alloca;
|
||||
fputs ("\tdepwi 0,31,2,%r21\n", FILE); \
|
||||
fputs ("\tldw 4(%r21),%r19\n", FILE); \
|
||||
fputs ("\tldw 0(%r21),%r21\n", FILE); \
|
||||
fputs ("\tldsid (%r21),%r1\n", FILE); \
|
||||
fputs ("\tmtsp %r1,%sr0\n", FILE); \
|
||||
fputs ("\tbe 0(%sr0,%r21)\n", FILE); \
|
||||
fputs ("\tldw 40(%r22),%r29\n", FILE); \
|
||||
if (TARGET_PA_20) \
|
||||
{ \
|
||||
fputs ("\tbve (%r21)\n", FILE); \
|
||||
fputs ("\tldw 40(%r22),%r29\n", FILE); \
|
||||
fputs ("\t.word 0\n", FILE); \
|
||||
fputs ("\t.word 0\n", FILE); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
fputs ("\tldsid (%r21),%r1\n", FILE); \
|
||||
fputs ("\tmtsp %r1,%sr0\n", FILE); \
|
||||
fputs ("\tbe 0(%sr0,%r21)\n", FILE); \
|
||||
fputs ("\tldw 40(%r22),%r29\n", FILE); \
|
||||
} \
|
||||
fputs ("\t.word 0\n", FILE); \
|
||||
fputs ("\t.word 0\n", FILE); \
|
||||
fputs ("\t.word 0\n", FILE); \
|
||||
@ -1027,17 +1037,22 @@ extern int may_call_alloca;
|
||||
} \
|
||||
}
|
||||
|
||||
/* Length in units of the trampoline for entering a nested function.
|
||||
|
||||
Flush the cache entries corresponding to the first and last addresses
|
||||
of the trampoline. This is necessary as the trampoline may cross two
|
||||
cache lines.
|
||||
|
||||
If the code part of the trampoline ever grows to > 32 bytes, then it
|
||||
will become necessary to hack on the cacheflush pattern in pa.md. */
|
||||
/* Length in units of the trampoline for entering a nested function. */
|
||||
|
||||
#define TRAMPOLINE_SIZE (TARGET_64BIT ? 72 : 52)
|
||||
|
||||
/* Length in units of the trampoline instruction code. */
|
||||
|
||||
#define TRAMPOLINE_CODE_SIZE (TARGET_64BIT ? 24 : (TARGET_PA_20 ? 32 : 40))
|
||||
|
||||
/* Minimum length of a cache line. A length of 16 will work on all
|
||||
PA-RISC processors. All PA 1.1 processors have a cache line of
|
||||
32 bytes. Most but not all PA 2.0 processors have a cache line
|
||||
of 64 bytes. As cache flushes are expensive and we don't support
|
||||
PA 1.0, we use a minimum length of 32. */
|
||||
|
||||
#define MIN_CACHELINE_SIZE 32
|
||||
|
||||
/* Emit RTL insns to initialize the variable parts of a trampoline.
|
||||
FNADDR is an RTX for the address of the function's pure code.
|
||||
CXT is an RTX for the static chain value for the function.
|
||||
@ -1046,55 +1061,85 @@ extern int may_call_alloca;
|
||||
Move the static chain value to trampoline template at offset 40.
|
||||
Move the trampoline address to trampoline template at offset 44.
|
||||
Move r19 to trampoline template at offset 48. The latter two
|
||||
words create a plabel for the indirect call to the trampoline. */
|
||||
words create a plabel for the indirect call to the trampoline.
|
||||
|
||||
A similar sequence is used for the 64-bit port but the plabel is
|
||||
at the beginning of the trampoline.
|
||||
|
||||
Finally, the cache entries for the trampoline code are flushed.
|
||||
This is necessary to ensure that the trampoline instruction sequence
|
||||
is written to memory prior to any attempts at prefetching the code
|
||||
sequence. */
|
||||
|
||||
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
|
||||
{ \
|
||||
if (! TARGET_64BIT) \
|
||||
{ \
|
||||
rtx start_addr, end_addr; \
|
||||
rtx start_addr = gen_reg_rtx (Pmode); \
|
||||
rtx end_addr = gen_reg_rtx (Pmode); \
|
||||
rtx line_length = gen_reg_rtx (Pmode); \
|
||||
rtx tmp; \
|
||||
\
|
||||
start_addr = memory_address (Pmode, plus_constant ((TRAMP), 36)); \
|
||||
emit_move_insn (gen_rtx_MEM (Pmode, start_addr), (FNADDR)); \
|
||||
start_addr = memory_address (Pmode, plus_constant ((TRAMP), 40)); \
|
||||
emit_move_insn (gen_rtx_MEM (Pmode, start_addr), (CXT)); \
|
||||
start_addr = memory_address (Pmode, plus_constant ((TRAMP), 44)); \
|
||||
emit_move_insn (gen_rtx_MEM (Pmode, start_addr), (TRAMP)); \
|
||||
start_addr = memory_address (Pmode, plus_constant ((TRAMP), 48)); \
|
||||
emit_move_insn (gen_rtx_MEM (Pmode, start_addr), \
|
||||
if (!TARGET_64BIT) \
|
||||
{ \
|
||||
tmp = memory_address (Pmode, plus_constant ((TRAMP), 36)); \
|
||||
emit_move_insn (gen_rtx_MEM (Pmode, tmp), (FNADDR)); \
|
||||
tmp = memory_address (Pmode, plus_constant ((TRAMP), 40)); \
|
||||
emit_move_insn (gen_rtx_MEM (Pmode, tmp), (CXT)); \
|
||||
\
|
||||
/* Create a fat pointer for the trampoline. */ \
|
||||
tmp = memory_address (Pmode, plus_constant ((TRAMP), 44)); \
|
||||
emit_move_insn (gen_rtx_MEM (Pmode, tmp), (TRAMP)); \
|
||||
tmp = memory_address (Pmode, plus_constant ((TRAMP), 48)); \
|
||||
emit_move_insn (gen_rtx_MEM (Pmode, tmp), \
|
||||
gen_rtx_REG (Pmode, 19)); \
|
||||
\
|
||||
/* fdc and fic only use registers for the address to flush, \
|
||||
they do not accept integer displacements. */ \
|
||||
start_addr = force_reg (Pmode, (TRAMP)); \
|
||||
end_addr = force_reg (Pmode, plus_constant ((TRAMP), 32)); \
|
||||
emit_insn (gen_dcacheflush (start_addr, end_addr)); \
|
||||
end_addr = force_reg (Pmode, plus_constant (start_addr, 32)); \
|
||||
emit_insn (gen_icacheflush (start_addr, end_addr, start_addr, \
|
||||
gen_reg_rtx (Pmode), gen_reg_rtx (Pmode)));\
|
||||
they do not accept integer displacements. We align the \
|
||||
start and end addresses to the beginning of their respective \
|
||||
cache lines to minimize the number of lines flushed. */ \
|
||||
tmp = force_reg (Pmode, (TRAMP)); \
|
||||
emit_insn (gen_andsi3 (start_addr, tmp, \
|
||||
GEN_INT (-MIN_CACHELINE_SIZE))); \
|
||||
tmp = force_reg (Pmode, \
|
||||
plus_constant (tmp, TRAMPOLINE_CODE_SIZE - 1)); \
|
||||
emit_insn (gen_andsi3 (end_addr, tmp, \
|
||||
GEN_INT (-MIN_CACHELINE_SIZE))); \
|
||||
emit_move_insn (line_length, GEN_INT (MIN_CACHELINE_SIZE)); \
|
||||
emit_insn (gen_dcacheflush (start_addr, end_addr, line_length)); \
|
||||
emit_insn (gen_icacheflush (start_addr, end_addr, line_length, \
|
||||
gen_reg_rtx (Pmode), \
|
||||
gen_reg_rtx (Pmode))); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
rtx start_addr, end_addr; \
|
||||
tmp = memory_address (Pmode, plus_constant ((TRAMP), 56)); \
|
||||
emit_move_insn (gen_rtx_MEM (Pmode, tmp), (FNADDR)); \
|
||||
tmp = memory_address (Pmode, plus_constant ((TRAMP), 64)); \
|
||||
emit_move_insn (gen_rtx_MEM (Pmode, tmp), (CXT)); \
|
||||
\
|
||||
start_addr = memory_address (Pmode, plus_constant ((TRAMP), 56)); \
|
||||
emit_move_insn (gen_rtx_MEM (Pmode, start_addr), (FNADDR)); \
|
||||
start_addr = memory_address (Pmode, plus_constant ((TRAMP), 64)); \
|
||||
emit_move_insn (gen_rtx_MEM (Pmode, start_addr), (CXT)); \
|
||||
/* Create a fat pointer for the trampoline. */ \
|
||||
end_addr = force_reg (Pmode, plus_constant ((TRAMP), 32)); \
|
||||
start_addr = memory_address (Pmode, plus_constant ((TRAMP), 16)); \
|
||||
emit_move_insn (gen_rtx_MEM (Pmode, start_addr), end_addr); \
|
||||
end_addr = gen_rtx_REG (Pmode, 27); \
|
||||
start_addr = memory_address (Pmode, plus_constant ((TRAMP), 24)); \
|
||||
emit_move_insn (gen_rtx_MEM (Pmode, start_addr), end_addr); \
|
||||
tmp = memory_address (Pmode, plus_constant ((TRAMP), 16)); \
|
||||
emit_move_insn (gen_rtx_MEM (Pmode, tmp), \
|
||||
force_reg (Pmode, plus_constant ((TRAMP), 32))); \
|
||||
tmp = memory_address (Pmode, plus_constant ((TRAMP), 24)); \
|
||||
emit_move_insn (gen_rtx_MEM (Pmode, tmp), \
|
||||
gen_rtx_REG (Pmode, 27)); \
|
||||
\
|
||||
/* fdc and fic only use registers for the address to flush, \
|
||||
they do not accept integer displacements. */ \
|
||||
start_addr = force_reg (Pmode, (TRAMP)); \
|
||||
end_addr = force_reg (Pmode, plus_constant ((TRAMP), 32)); \
|
||||
emit_insn (gen_dcacheflush (start_addr, end_addr)); \
|
||||
end_addr = force_reg (Pmode, plus_constant (start_addr, 32)); \
|
||||
emit_insn (gen_icacheflush (start_addr, end_addr, start_addr, \
|
||||
gen_reg_rtx (Pmode), gen_reg_rtx (Pmode)));\
|
||||
they do not accept integer displacements. We align the \
|
||||
start and end addresses to the beginning of their respective \
|
||||
cache lines to minimize the number of lines flushed. */ \
|
||||
tmp = force_reg (Pmode, plus_constant ((TRAMP), 32)); \
|
||||
emit_insn (gen_anddi3 (start_addr, tmp, \
|
||||
GEN_INT (-MIN_CACHELINE_SIZE))); \
|
||||
tmp = force_reg (Pmode, \
|
||||
plus_constant (tmp, TRAMPOLINE_CODE_SIZE - 1)); \
|
||||
emit_insn (gen_anddi3 (end_addr, tmp, \
|
||||
GEN_INT (-MIN_CACHELINE_SIZE))); \
|
||||
emit_move_insn (line_length, GEN_INT (MIN_CACHELINE_SIZE)); \
|
||||
emit_insn (gen_dcacheflush (start_addr, end_addr, line_length)); \
|
||||
emit_insn (gen_icacheflush (start_addr, end_addr, line_length, \
|
||||
gen_reg_rtx (Pmode), \
|
||||
gen_reg_rtx (Pmode))); \
|
||||
} \
|
||||
}
|
||||
|
||||
@ -1219,7 +1264,7 @@ extern int may_call_alloca;
|
||||
|
||||
`S' is the constant 31.
|
||||
|
||||
`T' is for fp loads and stores. */
|
||||
`T' is for floating-point loads and stores. */
|
||||
#define EXTRA_CONSTRAINT(OP, C) \
|
||||
((C) == 'Q' ? \
|
||||
(IS_RELOADING_PSEUDO_P (OP) \
|
||||
@ -1238,22 +1283,24 @@ extern int may_call_alloca;
|
||||
&& (move_operand (OP, GET_MODE (OP)) \
|
||||
|| memory_address_p (GET_MODE (OP), XEXP (OP, 0))\
|
||||
|| reload_in_progress)) \
|
||||
: ((C) == 'T' ? \
|
||||
(GET_CODE (OP) == MEM \
|
||||
/* Using DFmode forces only short displacements \
|
||||
to be recognized as valid in reg+d addresses. \
|
||||
However, this is not necessary for PA2.0 since\
|
||||
it has long FP loads/stores. \
|
||||
\
|
||||
FIXME: the ELF32 linker clobbers the LSB of \
|
||||
the FP register number in {fldw,fstw} insns. \
|
||||
Thus, we only allow long FP loads/stores on \
|
||||
TARGET_64BIT. */ \
|
||||
&& memory_address_p ((TARGET_PA_20 \
|
||||
&& !TARGET_ELF32 \
|
||||
? GET_MODE (OP) \
|
||||
: DFmode), \
|
||||
XEXP (OP, 0)) \
|
||||
: ((C) == 'T' ? \
|
||||
(GET_CODE (OP) == MEM \
|
||||
/* Floating-point loads and stores are used to load \
|
||||
integer values as well as floating-point values. \
|
||||
They don't have the same set of REG+D address modes \
|
||||
as integer loads and stores. PA 1.x supports only \
|
||||
short displacements. PA 2.0 supports long displacements \
|
||||
but the base register needs to be aligned. \
|
||||
\
|
||||
The checks in GO_IF_LEGITIMATE_ADDRESS for SFmode and \
|
||||
DFmode test the validity of an address for use in a \
|
||||
floating point load or store. So, we use SFmode/DFmode \
|
||||
to see if the address is valid for a floating-point \
|
||||
load/store operation. */ \
|
||||
&& memory_address_p ((GET_MODE_SIZE (GET_MODE (OP)) == 4 \
|
||||
? SFmode \
|
||||
: DFmode), \
|
||||
XEXP (OP, 0)) \
|
||||
&& !(GET_CODE (XEXP (OP, 0)) == LO_SUM \
|
||||
&& GET_CODE (XEXP (XEXP (OP, 0), 0)) == REG \
|
||||
&& REG_OK_FOR_BASE_P (XEXP (XEXP (OP, 0), 0))\
|
||||
@ -1353,17 +1400,36 @@ extern int may_call_alloca;
|
||||
&& REG_OK_FOR_BASE_P (XEXP (X, 1))) \
|
||||
base = XEXP (X, 1), index = XEXP (X, 0); \
|
||||
if (base != 0) \
|
||||
if (GET_CODE (index) == CONST_INT \
|
||||
&& ((INT_14_BITS (index) \
|
||||
&& (TARGET_SOFT_FLOAT \
|
||||
|| (TARGET_PA_20 \
|
||||
&& ((MODE == SFmode \
|
||||
&& (INTVAL (index) % 4) == 0)\
|
||||
|| (MODE == DFmode \
|
||||
&& (INTVAL (index) % 8) == 0)))\
|
||||
|| ((MODE) != SFmode && (MODE) != DFmode))) \
|
||||
|| INT_5_BITS (index))) \
|
||||
goto ADDR; \
|
||||
if (GET_CODE (index) == CONST_INT \
|
||||
&& ((INT_14_BITS (index) \
|
||||
&& (((MODE) != DImode \
|
||||
&& (MODE) != SFmode \
|
||||
&& (MODE) != DFmode) \
|
||||
/* The base register for DImode loads and stores \
|
||||
with long displacements must be aligned because \
|
||||
the lower three bits in the displacement are \
|
||||
assumed to be zero. */ \
|
||||
|| ((MODE) == DImode \
|
||||
&& (!TARGET_64BIT \
|
||||
|| (INTVAL (index) % 8) == 0)) \
|
||||
/* Similarly, the base register for SFmode/DFmode \
|
||||
loads and stores with long displacements must \
|
||||
be aligned. \
|
||||
\
|
||||
FIXME: the ELF32 linker clobbers the LSB of \
|
||||
the FP register number in PA 2.0 floating-point \
|
||||
insns with long displacements. This is because \
|
||||
R_PARISC_DPREL14WR and other relocations like \
|
||||
it are not supported. For now, we reject long \
|
||||
displacements on this target. */ \
|
||||
|| (((MODE) == SFmode || (MODE) == DFmode) \
|
||||
&& (TARGET_SOFT_FLOAT \
|
||||
|| (TARGET_PA_20 \
|
||||
&& !TARGET_ELF32 \
|
||||
&& (INTVAL (index) \
|
||||
% GET_MODE_SIZE (MODE)) == 0))))) \
|
||||
|| INT_5_BITS (index))) \
|
||||
goto ADDR; \
|
||||
if (! TARGET_SOFT_FLOAT \
|
||||
&& ! TARGET_DISABLE_INDEXING \
|
||||
&& base \
|
||||
@ -1466,6 +1532,11 @@ do { \
|
||||
else \
|
||||
newoffset = offset & ~mask; \
|
||||
\
|
||||
/* Ensure that long displacements are aligned. */ \
|
||||
if (!VAL_5_BITS_P (newoffset) \
|
||||
&& GET_MODE_CLASS (MODE) == MODE_FLOAT) \
|
||||
newoffset &= ~(GET_MODE_SIZE (MODE) -1); \
|
||||
\
|
||||
if (newoffset != 0 \
|
||||
&& VAL_14_BITS_P (newoffset)) \
|
||||
{ \
|
||||
|
129
gnu/dist/gcc/gcc/config/pa/pa.md
vendored
129
gnu/dist/gcc/gcc/config/pa/pa.md
vendored
@ -2264,9 +2264,9 @@
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
|
||||
"=r,r,r,r,r,r,Q,!*q,!f,f,*TR")
|
||||
"=r,r,r,r,r,r,Q,!*q,!r,!f,f,*TR")
|
||||
(match_operand:SI 1 "move_operand"
|
||||
"A,r,J,N,K,RQ,rM,!rM,!fM,*RT,f"))]
|
||||
"A,r,J,N,K,RQ,rM,!rM,!*q,!fM,*RT,f"))]
|
||||
"(register_operand (operands[0], SImode)
|
||||
|| reg_or_0_operand (operands[1], SImode))
|
||||
&& ! TARGET_SOFT_FLOAT"
|
||||
@ -2279,18 +2279,19 @@
|
||||
ldw%M1 %1,%0
|
||||
stw%M0 %r1,%0
|
||||
mtsar %r1
|
||||
{mfctl|mfctl,w} %%sar,%0
|
||||
fcpy,sgl %f1,%0
|
||||
fldw%F1 %1,%0
|
||||
fstw%F0 %1,%0"
|
||||
[(set_attr "type" "load,move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
|
||||
[(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
|
||||
(set_attr "pa_combine_type" "addmove")
|
||||
(set_attr "length" "4,4,4,4,4,4,4,4,4,4,4")])
|
||||
(set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
|
||||
"=r,r,r,r,r,r,Q,!*q")
|
||||
"=r,r,r,r,r,r,Q,!*q,!r")
|
||||
(match_operand:SI 1 "move_operand"
|
||||
"A,r,J,N,K,RQ,rM,!rM"))]
|
||||
"A,r,J,N,K,RQ,rM,!rM,!*q"))]
|
||||
"(register_operand (operands[0], SImode)
|
||||
|| reg_or_0_operand (operands[1], SImode))
|
||||
&& TARGET_SOFT_FLOAT"
|
||||
@ -2302,10 +2303,11 @@
|
||||
{zdepi|depwi,z} %Z1,%0
|
||||
ldw%M1 %1,%0
|
||||
stw%M0 %r1,%0
|
||||
mtsar %r1"
|
||||
[(set_attr "type" "load,move,move,move,move,load,store,move")
|
||||
mtsar %r1
|
||||
{mfctl|mfctl,w} %%sar,%0"
|
||||
[(set_attr "type" "load,move,move,move,move,load,store,move,move")
|
||||
(set_attr "pa_combine_type" "addmove")
|
||||
(set_attr "length" "4,4,4,4,4,4,4,4")])
|
||||
(set_attr "length" "4,4,4,4,4,4,4,4,4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
@ -2699,8 +2701,10 @@
|
||||
}")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,!*q,!*f")
|
||||
(match_operand:HI 1 "move_operand" "r,J,N,K,RQ,rM,!rM,!*fM"))]
|
||||
[(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand"
|
||||
"=r,r,r,r,r,Q,!*q,!r,!*f")
|
||||
(match_operand:HI 1 "move_operand"
|
||||
"r,J,N,K,RQ,rM,!rM,!*q,!*fM"))]
|
||||
"register_operand (operands[0], HImode)
|
||||
|| reg_or_0_operand (operands[1], HImode)"
|
||||
"@
|
||||
@ -2711,10 +2715,11 @@
|
||||
ldh%M1 %1,%0
|
||||
sth%M0 %r1,%0
|
||||
mtsar %r1
|
||||
{mfctl|mfctl,w} %sar,%0
|
||||
fcpy,sgl %f1,%0"
|
||||
[(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
|
||||
[(set_attr "type" "move,move,move,shift,load,store,move,move,fpalu")
|
||||
(set_attr "pa_combine_type" "addmove")
|
||||
(set_attr "length" "4,4,4,4,4,4,4,4")])
|
||||
(set_attr "length" "4,4,4,4,4,4,4,4,4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:HI 0 "register_operand" "=r")
|
||||
@ -2814,8 +2819,10 @@
|
||||
}")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,!*q,!*f")
|
||||
(match_operand:QI 1 "move_operand" "r,J,N,K,RQ,rM,!rM,!*fM"))]
|
||||
[(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand"
|
||||
"=r,r,r,r,r,Q,!*q,!r,!*f")
|
||||
(match_operand:QI 1 "move_operand"
|
||||
"r,J,N,K,RQ,rM,!rM,!*q,!*fM"))]
|
||||
"register_operand (operands[0], QImode)
|
||||
|| reg_or_0_operand (operands[1], QImode)"
|
||||
"@
|
||||
@ -2826,10 +2833,11 @@
|
||||
ldb%M1 %1,%0
|
||||
stb%M0 %r1,%0
|
||||
mtsar %r1
|
||||
{mfctl|mfctl,w} %%sar,%0
|
||||
fcpy,sgl %f1,%0"
|
||||
[(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
|
||||
[(set_attr "type" "move,move,move,shift,load,store,move,move,fpalu")
|
||||
(set_attr "pa_combine_type" "addmove")
|
||||
(set_attr "length" "4,4,4,4,4,4,4,4")])
|
||||
(set_attr "length" "4,4,4,4,4,4,4,4,4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:QI 0 "register_operand" "=r")
|
||||
@ -3137,9 +3145,9 @@
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
|
||||
"=r,r,r,r,r,Q,!*q,!f,f,*TR")
|
||||
"=r,r,r,r,r,Q,!f,f,*TR")
|
||||
(match_operand:DF 1 "move_operand"
|
||||
"r,J,N,K,RQ,rM,!rM,!fM,*RT,f"))]
|
||||
"r,J,N,K,RQ,rM,!fM,*RT,f"))]
|
||||
"(register_operand (operands[0], DFmode)
|
||||
|| reg_or_0_operand (operands[1], DFmode))
|
||||
&& ! TARGET_SOFT_FLOAT && TARGET_64BIT"
|
||||
@ -3150,13 +3158,12 @@
|
||||
depdi,z %z1,%0
|
||||
ldd%M1 %1,%0
|
||||
std%M0 %r1,%0
|
||||
mtsar %r1
|
||||
fcpy,dbl %f1,%0
|
||||
fldd%F1 %1,%0
|
||||
fstd%F0 %1,%0"
|
||||
[(set_attr "type" "move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
|
||||
[(set_attr "type" "move,move,move,shift,load,store,fpalu,fpload,fpstore")
|
||||
(set_attr "pa_combine_type" "addmove")
|
||||
(set_attr "length" "4,4,4,4,4,4,4,4,4,4")])
|
||||
(set_attr "length" "4,4,4,4,4,4,4,4,4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:DF 0 "register_operand" "=fx")
|
||||
@ -3296,9 +3303,9 @@
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
|
||||
"=r,r,r,r,r,r,Q,!*q,!f,f,*TR")
|
||||
"=r,r,r,r,r,r,Q,!*q,!r,!f,f,*TR")
|
||||
(match_operand:DI 1 "move_operand"
|
||||
"A,r,J,N,K,RQ,rM,!rM,!fM,*RT,f"))]
|
||||
"A,r,J,N,K,RQ,rM,!rM,!*q,!fM,*RT,f"))]
|
||||
"(register_operand (operands[0], DImode)
|
||||
|| reg_or_0_operand (operands[1], DImode))
|
||||
&& ! TARGET_SOFT_FLOAT && TARGET_64BIT"
|
||||
@ -3311,12 +3318,13 @@
|
||||
ldd%M1 %1,%0
|
||||
std%M0 %r1,%0
|
||||
mtsar %r1
|
||||
{mfctl|mfctl,w} %%sar,%0
|
||||
fcpy,dbl %f1,%0
|
||||
fldd%F1 %1,%0
|
||||
fstd%F0 %1,%0"
|
||||
[(set_attr "type" "load,move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
|
||||
[(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
|
||||
(set_attr "pa_combine_type" "addmove")
|
||||
(set_attr "length" "4,4,4,4,4,4,4,4,4,4,4")])
|
||||
(set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
|
||||
@ -4385,14 +4393,13 @@
|
||||
|
||||
(define_expand "anddi3"
|
||||
[(set (match_operand:DI 0 "register_operand" "")
|
||||
(and:DI (match_operand:DI 1 "arith_double_operand" "")
|
||||
(and:DI (match_operand:DI 1 "register_operand" "")
|
||||
(match_operand:DI 2 "arith_double_operand" "")))]
|
||||
""
|
||||
"
|
||||
{
|
||||
if (! register_operand (operands[1], DImode)
|
||||
|| ! register_operand (operands[2], DImode))
|
||||
/* Let GCC break this into word-at-a-time operations. */
|
||||
/* Both operands must be register operands. */
|
||||
if (!TARGET_64BIT && !register_operand (operands[2], DImode))
|
||||
FAIL;
|
||||
}")
|
||||
|
||||
@ -4454,14 +4461,13 @@
|
||||
|
||||
(define_expand "iordi3"
|
||||
[(set (match_operand:DI 0 "register_operand" "")
|
||||
(ior:DI (match_operand:DI 1 "arith_double_operand" "")
|
||||
(ior:DI (match_operand:DI 1 "register_operand" "")
|
||||
(match_operand:DI 2 "arith_double_operand" "")))]
|
||||
""
|
||||
"
|
||||
{
|
||||
if (! register_operand (operands[1], DImode)
|
||||
|| ! register_operand (operands[2], DImode))
|
||||
/* Let GCC break this into word-at-a-time operations. */
|
||||
/* Both operands must be register operands. */
|
||||
if (!TARGET_64BIT && !register_operand (operands[2], DImode))
|
||||
FAIL;
|
||||
}")
|
||||
|
||||
@ -7769,29 +7775,58 @@
|
||||
return \"\";
|
||||
}")
|
||||
|
||||
;; Flush the I and D cache line found at the address in operand 0.
|
||||
;; Flush the I and D cache lines from the start address (operand0)
|
||||
;; to the end address (operand1). No lines are flushed if the end
|
||||
;; address is less than the start address (unsigned).
|
||||
;;
|
||||
;; Because the range of memory flushed is variable and the size of
|
||||
;; a MEM can only be a CONST_INT, the patterns specify that they
|
||||
;; perform an unspecified volatile operation on all memory.
|
||||
;;
|
||||
;; The address range for an icache flush must lie within a single
|
||||
;; space on targets with non-equivalent space registers.
|
||||
;;
|
||||
;; This is used by the trampoline code for nested functions.
|
||||
;; So long as the trampoline itself is less than 32 bytes this
|
||||
;; is sufficient.
|
||||
|
||||
;;
|
||||
;; Operand 0 contains the start address.
|
||||
;; Operand 1 contains the end address.
|
||||
;; Operand 2 contains the line length to use.
|
||||
;; Operands 3 and 4 (icacheflush) are clobbered scratch registers.
|
||||
(define_insn "dcacheflush"
|
||||
[(unspec_volatile [(const_int 1)] 0)
|
||||
(use (mem:SI (match_operand 0 "pmode_register_operand" "r")))
|
||||
(use (mem:SI (match_operand 1 "pmode_register_operand" "r")))]
|
||||
[(const_int 1)
|
||||
(unspec_volatile [(mem:BLK (scratch))] 0)
|
||||
(use (match_operand 0 "pmode_register_operand" "r"))
|
||||
(use (match_operand 1 "pmode_register_operand" "r"))
|
||||
(use (match_operand 2 "pmode_register_operand" "r"))
|
||||
(clobber (match_scratch 3 "=&0"))]
|
||||
""
|
||||
"fdc 0(%0)\;fdc 0(%1)\;sync"
|
||||
"*
|
||||
{
|
||||
if (TARGET_64BIT)
|
||||
return \"cmpb,*<<=,n %3,%1,.\;fdc,m %2(%3)\;sync\";
|
||||
else
|
||||
return \"cmpb,<<=,n %3,%1,.\;fdc,m %2(%3)\;sync\";
|
||||
}"
|
||||
[(set_attr "type" "multi")
|
||||
(set_attr "length" "12")])
|
||||
|
||||
(define_insn "icacheflush"
|
||||
[(unspec_volatile [(const_int 2)] 0)
|
||||
(use (mem:SI (match_operand 0 "pmode_register_operand" "r")))
|
||||
(use (mem:SI (match_operand 1 "pmode_register_operand" "r")))
|
||||
[(const_int 2)
|
||||
(unspec_volatile [(mem:BLK (scratch))] 0)
|
||||
(use (match_operand 0 "pmode_register_operand" "r"))
|
||||
(use (match_operand 1 "pmode_register_operand" "r"))
|
||||
(use (match_operand 2 "pmode_register_operand" "r"))
|
||||
(clobber (match_operand 3 "pmode_register_operand" "=&r"))
|
||||
(clobber (match_operand 4 "pmode_register_operand" "=&r"))]
|
||||
(clobber (match_operand 4 "pmode_register_operand" "=&r"))
|
||||
(clobber (match_scratch 5 "=&0"))]
|
||||
""
|
||||
"mfsp %%sr0,%4\;ldsid (%2),%3\;mtsp %3,%%sr0\;fic 0(%%sr0,%0)\;fic 0(%%sr0,%1)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop"
|
||||
"*
|
||||
{
|
||||
if (TARGET_64BIT)
|
||||
return \"mfsp %%sr0,%4\;ldsid (%5),%3\;mtsp %3,%%sr0\;cmpb,*<<=,n %5,%1,.\;fic,m %2(%%sr0,%5)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop\";
|
||||
else
|
||||
return \"mfsp %%sr0,%4\;ldsid (%5),%3\;mtsp %3,%%sr0\;cmpb,<<=,n %5,%1,.\;fic,m %2(%%sr0,%5)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop\";
|
||||
}"
|
||||
[(set_attr "type" "multi")
|
||||
(set_attr "length" "52")])
|
||||
|
||||
|
2
gnu/dist/gcc/gcc/config/pa/pa32-linux.h
vendored
2
gnu/dist/gcc/gcc/config/pa/pa32-linux.h
vendored
@ -28,7 +28,7 @@ Boston, MA 02111-1307, USA. */
|
||||
pointer into the frame. This target does not need multiple
|
||||
subspace stubs, so we allow sibcalls to all functions. */
|
||||
#undef FUNCTION_OK_FOR_SIBCALL
|
||||
#define FUNCTION_OK_FOR_SIBCALL(DECL) 1
|
||||
#define FUNCTION_OK_FOR_SIBCALL(DECL) (!TARGET_PORTABLE_RUNTIME)
|
||||
|
||||
/* The libcall __canonicalize_funcptr_for_compare is referenced in
|
||||
crtend.o and the reference isn't resolved in objects that don't
|
||||
|
27
gnu/dist/gcc/gcc/config/pa/pa64-hpux.h
vendored
27
gnu/dist/gcc/gcc/config/pa/pa64-hpux.h
vendored
@ -43,16 +43,35 @@ Boston, MA 02111-1307, USA. */
|
||||
"%{!mgnu-ld:+Accept TypeMismatch} -E %{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{shared:%{mgnu-ld:-shared}%{!mgnu-ld:-b}}"
|
||||
#endif
|
||||
|
||||
/* Like the default, except no -lg. */
|
||||
/* Profiling support is only provided in libc.a. However, libprof and
|
||||
libgprof are only available in shared form on HP-UX 11.00. We use
|
||||
the shared form if we are using the GNU linker or an archive form
|
||||
isn't available. We also usually need to link with libdld and it's
|
||||
only available in shared form. */
|
||||
#undef LIB_SPEC
|
||||
#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_GNU_LD)
|
||||
#define LIB_SPEC \
|
||||
"%{!shared:\
|
||||
%{!p:%{!pg: -lc %{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}}\
|
||||
%{pg: -L/usr/lib/pa20_64/libp/ -lgprof -lc\
|
||||
%{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}\
|
||||
%{p: -L/usr/lib/pa20_64/libp/ -lprof -lc\
|
||||
%{p:%{!pg:%{static:%{!mhp-ld:-a shared}%{mhp-ld:-a archive_shared}}\
|
||||
-lprof %{static:-a archive} -lc\
|
||||
%{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}}\
|
||||
%{pg:%{static:%{!mhp-ld:-a shared}%{mhp-ld:-a archive_shared}}\
|
||||
-lgprof %{static:-a archive} -lc\
|
||||
%{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}}\
|
||||
/usr/lib/pa20_64/milli.a"
|
||||
#else
|
||||
#define LIB_SPEC \
|
||||
"%{!shared:\
|
||||
%{!p:%{!pg: -lc %{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}}\
|
||||
%{p:%{!pg:%{static:%{mgnu-ld:-a shared}%{!mgnu-ld:-a archive_shared}}\
|
||||
-lprof %{static:-a archive} -lc\
|
||||
%{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}}\
|
||||
%{pg:%{static:%{mgnu-ld:-a shared}%{!mgnu-ld:-a archive_shared}}\
|
||||
-lgprof %{static:-a archive} -lc\
|
||||
%{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}}\
|
||||
/usr/lib/pa20_64/milli.a"
|
||||
#endif
|
||||
|
||||
/* Under hpux11, the normal location of the `ld' and `as' programs is the
|
||||
/usr/ccs/bin directory. */
|
||||
|
10
gnu/dist/gcc/gcc/config/pa/pa64-regs.h
vendored
10
gnu/dist/gcc/gcc/config/pa/pa64-regs.h
vendored
@ -169,13 +169,11 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
Registers 0 - 31 remain unchanged.
|
||||
|
||||
Registers 32 - 60 are mapped to 72, 74, 76 ...
|
||||
|
||||
Register 88 is mapped to 32. */
|
||||
Registers 32 - 59 are mapped to 72, 74, 76 ...
|
||||
|
||||
Register 60 is mapped to 32. */
|
||||
#define DBX_REGISTER_NUMBER(REGNO) \
|
||||
((REGNO) <= 31 ? (REGNO) : \
|
||||
((REGNO) > 31 && (REGNO) <= 60 ? (REGNO - 32) * 2 + 72 : 32))
|
||||
((REGNO) <= 31 ? (REGNO) : ((REGNO) < 60 ? (REGNO - 32) * 2 + 72 : 32))
|
||||
|
||||
/* We must not use the DBX register numbers for the DWARF 2 CFA column
|
||||
numbers because that maps to numbers beyond FIRST_PSEUDO_REGISTER.
|
||||
@ -292,7 +290,7 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS,
|
||||
"%fr28", "%fr29", "%fr30", "%fr31", "SAR"}
|
||||
|
||||
#define ADDITIONAL_REGISTER_NAMES \
|
||||
{{"%cr11",88}}
|
||||
{{"%cr11",60}}
|
||||
|
||||
#define FP_SAVED_REG_LAST 49
|
||||
#define FP_SAVED_REG_FIRST 40
|
||||
|
62
gnu/dist/gcc/gcc/config/rs6000/rs6000.md
vendored
62
gnu/dist/gcc/gcc/config/rs6000/rs6000.md
vendored
@ -3124,61 +3124,6 @@
|
||||
}"
|
||||
[(set_attr "length" "8")])
|
||||
|
||||
(define_insn_and_split "*andsi3_internal7"
|
||||
[(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
|
||||
(compare:CC (and:SI (match_operand:SI 0 "gpc_reg_operand" "r,r")
|
||||
(match_operand:SI 1 "mask_operand_wrap" "i,i"))
|
||||
(const_int 0)))
|
||||
(clobber (match_scratch:SI 3 "=r,r"))]
|
||||
"TARGET_POWERPC64"
|
||||
"#"
|
||||
"TARGET_POWERPC64"
|
||||
[(parallel [(set (match_dup 2)
|
||||
(compare:CC (and:SI (rotate:SI (match_dup 0) (match_dup 4))
|
||||
(match_dup 5))
|
||||
(const_int 0)))
|
||||
(clobber (match_dup 3))])]
|
||||
"
|
||||
{
|
||||
int mb = extract_MB (operands[1]);
|
||||
int me = extract_ME (operands[1]);
|
||||
operands[4] = GEN_INT (me + 1);
|
||||
operands[5] = GEN_INT (~((HOST_WIDE_INT) -1 << (33 + me - mb)));
|
||||
}"
|
||||
[(set_attr "type" "delayed_compare,compare")
|
||||
(set_attr "length" "4,8")])
|
||||
|
||||
(define_insn_and_split "*andsi3_internal8"
|
||||
[(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
|
||||
(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
|
||||
(match_operand:SI 2 "mask_operand_wrap" "i,i"))
|
||||
(const_int 0)))
|
||||
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
|
||||
(and:SI (match_dup 1)
|
||||
(match_dup 2)))]
|
||||
"TARGET_POWERPC64"
|
||||
"#"
|
||||
"TARGET_POWERPC64"
|
||||
[(parallel [(set (match_dup 3)
|
||||
(compare:CC (and:SI (rotate:SI (match_dup 1) (match_dup 4))
|
||||
(match_dup 5))
|
||||
(const_int 0)))
|
||||
(set (match_dup 0)
|
||||
(and:SI (rotate:SI (match_dup 1) (match_dup 4))
|
||||
(match_dup 5)))])
|
||||
(set (match_dup 0)
|
||||
(rotate:SI (match_dup 0) (match_dup 6)))]
|
||||
"
|
||||
{
|
||||
int mb = extract_MB (operands[2]);
|
||||
int me = extract_ME (operands[2]);
|
||||
operands[4] = GEN_INT (me + 1);
|
||||
operands[6] = GEN_INT (32 - (me + 1));
|
||||
operands[5] = GEN_INT (~((HOST_WIDE_INT) -1 << (33 + me - mb)));
|
||||
}"
|
||||
[(set_attr "type" "delayed_compare,compare")
|
||||
(set_attr "length" "8,12")])
|
||||
|
||||
(define_expand "iorsi3"
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "")
|
||||
(ior:SI (match_operand:SI 1 "gpc_reg_operand" "")
|
||||
@ -6350,7 +6295,7 @@
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r")
|
||||
(ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
|
||||
(match_operand:SI 2 "const_int_operand" "M,i")))]
|
||||
"TARGET_32BIT && !TARGET_POWER"
|
||||
"TARGET_32BIT && !TARGET_POWER && WORDS_BIG_ENDIAN"
|
||||
"@
|
||||
{srai|srawi} %0,%1,31\;{srai|srawi} %L0,%1,%h2
|
||||
{sri|srwi} %L0,%L1,%h2\;insrwi %L0,%1,%h2,0\;{srai|srawi} %0,%1,%h2"
|
||||
@ -7564,7 +7509,7 @@
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand" "")
|
||||
(ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
|
||||
(match_operand:SI 2 "reg_or_cint_operand" "")))]
|
||||
""
|
||||
"WORDS_BIG_ENDIAN"
|
||||
"
|
||||
{
|
||||
if (TARGET_POWERPC64)
|
||||
@ -7574,7 +7519,8 @@
|
||||
emit_insn (gen_ashrdi3_power (operands[0], operands[1], operands[2]));
|
||||
DONE;
|
||||
}
|
||||
else if (TARGET_32BIT && GET_CODE (operands[2]) == CONST_INT)
|
||||
else if (TARGET_32BIT && GET_CODE (operands[2]) == CONST_INT
|
||||
&& WORDS_BIG_ENDIAN)
|
||||
{
|
||||
emit_insn (gen_ashrdi3_no_power (operands[0], operands[1], operands[2]));
|
||||
DONE;
|
||||
|
2
gnu/dist/gcc/gcc/config/rs6000/sysv4.h
vendored
2
gnu/dist/gcc/gcc/config/rs6000/sysv4.h
vendored
@ -1137,7 +1137,7 @@ do { \
|
||||
%{!mnewlib: -lc }"
|
||||
#else
|
||||
#define LIB_LINUX_SPEC "%{mnewlib: --start-group -llinux -lc --end-group } \
|
||||
%{!mnewlib: %{shared:-lc} %{!shared: %{pthread:-lpthread } \
|
||||
%{!mnewlib: %{pthread:-lpthread} %{shared:-lc} %{!shared: \
|
||||
%{profile:-lc_p} %{!profile:-lc}}}"
|
||||
#endif
|
||||
|
||||
|
18
gnu/dist/gcc/gcc/config/rtems.h
vendored
18
gnu/dist/gcc/gcc/config/rtems.h
vendored
@ -1,7 +1,7 @@
|
||||
/* Configuration common to all targets running RTEMS.
|
||||
Copyright (C) 2000, 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000, 2002, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
This file is part of GCC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -35,3 +35,17 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
#undef ENDFILE_SPEC
|
||||
#define ENDFILE_SPEC ""
|
||||
|
||||
/*
|
||||
* Some targets do not set up LIB_SPECS, override it, here.
|
||||
*/
|
||||
#define STD_LIB_SPEC \
|
||||
"%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
|
||||
|
||||
#undef LIB_SPEC
|
||||
#define LIB_SPEC "%{!qrtems: " STD_LIB_SPEC "} " \
|
||||
"%{!nostdlib: %{qrtems: --start-group \
|
||||
%{!qrtems_debug: -lrtemsbsp -lrtemscpu} \
|
||||
%{qrtems_debug: -lrtemsbsp_g -lrtemscpu_g} \
|
||||
-lc -lgcc --end-group %{!qnolinkcmds: -T linkcmds%s}}}"
|
||||
|
||||
|
2
gnu/dist/gcc/gcc/config/s390/s390-protos.h
vendored
2
gnu/dist/gcc/gcc/config/s390/s390-protos.h
vendored
@ -69,7 +69,7 @@ extern void emit_symbolic_move PARAMS ((rtx *));
|
||||
extern void s390_load_address PARAMS ((rtx, rtx));
|
||||
extern void s390_expand_movstr PARAMS ((rtx, rtx, rtx));
|
||||
extern void s390_expand_clrstr PARAMS ((rtx, rtx));
|
||||
extern void s390_expand_cmpstr PARAMS ((rtx, rtx, rtx, rtx));
|
||||
extern void s390_expand_cmpmem PARAMS ((rtx, rtx, rtx, rtx));
|
||||
extern rtx s390_return_addr_rtx PARAMS ((int, rtx));
|
||||
|
||||
extern void s390_output_symbolic_const PARAMS ((FILE *, rtx));
|
||||
|
20
gnu/dist/gcc/gcc/config/s390/s390.c
vendored
20
gnu/dist/gcc/gcc/config/s390/s390.c
vendored
@ -2268,12 +2268,11 @@ legitimize_pic_address (orig, reg)
|
||||
that was pulled out of the literal pool. Force it back in. */
|
||||
|
||||
else if (GET_CODE (op0) == UNSPEC
|
||||
&& GET_CODE (op1) == CONST_INT)
|
||||
&& GET_CODE (op1) == CONST_INT
|
||||
&& XINT (op0, 1) == 100)
|
||||
{
|
||||
if (XVECLEN (op0, 0) != 1)
|
||||
abort ();
|
||||
if (XINT (op0, 1) != 100)
|
||||
abort ();
|
||||
|
||||
new = force_const_mem (Pmode, orig);
|
||||
}
|
||||
@ -2660,6 +2659,9 @@ s390_expand_movstr (dst, src, len)
|
||||
rtx reg0 = gen_reg_rtx (double_mode);
|
||||
rtx reg1 = gen_reg_rtx (double_mode);
|
||||
|
||||
emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
|
||||
emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
|
||||
|
||||
emit_move_insn (gen_highpart (single_mode, reg0),
|
||||
force_operand (XEXP (dst, 0), NULL_RTX));
|
||||
emit_move_insn (gen_highpart (single_mode, reg1),
|
||||
@ -2756,6 +2758,9 @@ s390_expand_clrstr (dst, len)
|
||||
rtx reg0 = gen_reg_rtx (double_mode);
|
||||
rtx reg1 = gen_reg_rtx (double_mode);
|
||||
|
||||
emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
|
||||
emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
|
||||
|
||||
emit_move_insn (gen_highpart (single_mode, reg0),
|
||||
force_operand (XEXP (dst, 0), NULL_RTX));
|
||||
convert_move (gen_lowpart (single_mode, reg0), len, 1);
|
||||
@ -2825,16 +2830,16 @@ s390_expand_clrstr (dst, len)
|
||||
and return the result in TARGET. */
|
||||
|
||||
void
|
||||
s390_expand_cmpstr (target, op0, op1, len)
|
||||
s390_expand_cmpmem (target, op0, op1, len)
|
||||
rtx target;
|
||||
rtx op0;
|
||||
rtx op1;
|
||||
rtx len;
|
||||
{
|
||||
rtx (*gen_short) PARAMS ((rtx, rtx, rtx)) =
|
||||
TARGET_64BIT ? gen_cmpstr_short_64 : gen_cmpstr_short_31;
|
||||
TARGET_64BIT ? gen_cmpmem_short_64 : gen_cmpmem_short_31;
|
||||
rtx (*gen_long) PARAMS ((rtx, rtx, rtx, rtx)) =
|
||||
TARGET_64BIT ? gen_cmpstr_long_64 : gen_cmpstr_long_31;
|
||||
TARGET_64BIT ? gen_cmpmem_long_64 : gen_cmpmem_long_31;
|
||||
rtx (*gen_result) PARAMS ((rtx)) =
|
||||
GET_MODE (target) == DImode ? gen_cmpint_di : gen_cmpint_si;
|
||||
|
||||
@ -2860,6 +2865,9 @@ s390_expand_cmpstr (target, op0, op1, len)
|
||||
rtx reg0 = gen_reg_rtx (double_mode);
|
||||
rtx reg1 = gen_reg_rtx (double_mode);
|
||||
|
||||
emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
|
||||
emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
|
||||
|
||||
emit_move_insn (gen_highpart (single_mode, reg0),
|
||||
force_operand (XEXP (op0, 0), NULL_RTX));
|
||||
emit_move_insn (gen_highpart (single_mode, reg1),
|
||||
|
46
gnu/dist/gcc/gcc/config/s390/s390.md
vendored
46
gnu/dist/gcc/gcc/config/s390/s390.md
vendored
@ -910,11 +910,13 @@
|
||||
})
|
||||
|
||||
(define_expand "reload_outti"
|
||||
[(parallel [(match_operand:TI 0 "memory_operand" "")
|
||||
[(parallel [(match_operand:TI 0 "" "")
|
||||
(match_operand:TI 1 "register_operand" "d")
|
||||
(match_operand:DI 2 "register_operand" "=&a")])]
|
||||
"TARGET_64BIT"
|
||||
{
|
||||
if (GET_CODE (operands[0]) != MEM)
|
||||
abort ();
|
||||
s390_load_address (operands[2], XEXP (operands[0], 0));
|
||||
operands[0] = replace_equiv_address (operands[0], operands[2]);
|
||||
emit_move_insn (operands[0], operands[1]);
|
||||
@ -1060,11 +1062,13 @@
|
||||
})
|
||||
|
||||
(define_expand "reload_outdi"
|
||||
[(parallel [(match_operand:DI 0 "memory_operand" "")
|
||||
[(parallel [(match_operand:DI 0 "" "")
|
||||
(match_operand:DI 1 "register_operand" "d")
|
||||
(match_operand:SI 2 "register_operand" "=&a")])]
|
||||
"!TARGET_64BIT"
|
||||
{
|
||||
if (GET_CODE (operands[0]) != MEM)
|
||||
abort ();
|
||||
s390_load_address (operands[2], XEXP (operands[0], 0));
|
||||
operands[0] = replace_equiv_address (operands[0], operands[2]);
|
||||
emit_move_insn (operands[0], operands[1]);
|
||||
@ -1374,11 +1378,13 @@
|
||||
})
|
||||
|
||||
(define_expand "reload_outdf"
|
||||
[(parallel [(match_operand:DF 0 "memory_operand" "")
|
||||
[(parallel [(match_operand:DF 0 "" "")
|
||||
(match_operand:DF 1 "register_operand" "d")
|
||||
(match_operand:SI 2 "register_operand" "=&a")])]
|
||||
"!TARGET_64BIT"
|
||||
{
|
||||
if (GET_CODE (operands[0]) != MEM)
|
||||
abort ();
|
||||
s390_load_address (operands[2], XEXP (operands[0], 0));
|
||||
operands[0] = replace_equiv_address (operands[0], operands[2]);
|
||||
emit_move_insn (operands[0], operands[1]);
|
||||
@ -1420,12 +1426,16 @@
|
||||
;
|
||||
; load_multiple pattern(s).
|
||||
;
|
||||
; ??? Due to reload problems with replacing registers inside match_parallel
|
||||
; we currently support load_multiple/store_multiple only after reload.
|
||||
;
|
||||
|
||||
|
||||
(define_expand "load_multiple"
|
||||
[(match_par_dup 3 [(set (match_operand 0 "" "")
|
||||
(match_operand 1 "" ""))
|
||||
(use (match_operand 2 "" ""))])]
|
||||
""
|
||||
"reload_completed"
|
||||
"
|
||||
{
|
||||
int regno;
|
||||
@ -1485,7 +1495,7 @@
|
||||
[(match_parallel 0 "load_multiple_operation"
|
||||
[(set (match_operand:DI 1 "register_operand" "=r")
|
||||
(match_operand:DI 2 "s_operand" "Q"))])]
|
||||
""
|
||||
"reload_completed"
|
||||
"*
|
||||
{
|
||||
int words = XVECLEN (operands[0], 0);
|
||||
@ -1504,7 +1514,7 @@
|
||||
[(match_parallel 0 "load_multiple_operation"
|
||||
[(set (match_operand:SI 1 "register_operand" "=r")
|
||||
(match_operand:SI 2 "s_operand" "Q"))])]
|
||||
""
|
||||
"reload_completed"
|
||||
"*
|
||||
{
|
||||
int words = XVECLEN (operands[0], 0);
|
||||
@ -1527,7 +1537,7 @@
|
||||
[(match_par_dup 3 [(set (match_operand 0 "" "")
|
||||
(match_operand 1 "" ""))
|
||||
(use (match_operand 2 "" ""))])]
|
||||
""
|
||||
"reload_completed"
|
||||
"
|
||||
{
|
||||
int regno;
|
||||
@ -1589,7 +1599,7 @@
|
||||
[(match_parallel 0 "store_multiple_operation"
|
||||
[(set (match_operand:DI 1 "s_operand" "=Q")
|
||||
(match_operand:DI 2 "register_operand" "r"))])]
|
||||
""
|
||||
"reload_completed"
|
||||
"*
|
||||
{
|
||||
int words = XVECLEN (operands[0], 0);
|
||||
@ -1609,7 +1619,7 @@
|
||||
[(match_parallel 0 "store_multiple_operation"
|
||||
[(set (match_operand:SI 1 "s_operand" "=Q")
|
||||
(match_operand:SI 2 "register_operand" "r"))])]
|
||||
""
|
||||
"reload_completed"
|
||||
"*
|
||||
{
|
||||
int words = XVECLEN (operands[0], 0);
|
||||
@ -1859,33 +1869,33 @@
|
||||
(set_attr "length" "8")])
|
||||
|
||||
;
|
||||
; cmpstrM instruction pattern(s).
|
||||
; cmpmemM instruction pattern(s).
|
||||
;
|
||||
|
||||
(define_expand "cmpstrdi"
|
||||
(define_expand "cmpmemdi"
|
||||
[(set (match_operand:DI 0 "register_operand" "")
|
||||
(compare:DI (match_operand:BLK 1 "memory_operand" "")
|
||||
(match_operand:BLK 2 "memory_operand" "") ) )
|
||||
(use (match_operand:DI 3 "general_operand" ""))
|
||||
(use (match_operand:DI 4 "" ""))]
|
||||
"TARGET_64BIT"
|
||||
"s390_expand_cmpstr (operands[0], operands[1],
|
||||
"s390_expand_cmpmem (operands[0], operands[1],
|
||||
operands[2], operands[3]); DONE;")
|
||||
|
||||
(define_expand "cmpstrsi"
|
||||
(define_expand "cmpmemsi"
|
||||
[(set (match_operand:SI 0 "register_operand" "")
|
||||
(compare:SI (match_operand:BLK 1 "memory_operand" "")
|
||||
(match_operand:BLK 2 "memory_operand" "") ) )
|
||||
(use (match_operand:SI 3 "general_operand" ""))
|
||||
(use (match_operand:SI 4 "" ""))]
|
||||
""
|
||||
"s390_expand_cmpstr (operands[0], operands[1],
|
||||
"s390_expand_cmpmem (operands[0], operands[1],
|
||||
operands[2], operands[3]); DONE;")
|
||||
|
||||
; Compare a block that is up to 256 bytes in length.
|
||||
; The block length is taken as (operands[2] % 256) + 1.
|
||||
|
||||
(define_insn "cmpstr_short_64"
|
||||
(define_insn "cmpmem_short_64"
|
||||
[(set (reg:CCS 33)
|
||||
(compare:CCS (match_operand:BLK 0 "memory_operand" "=Q,Q")
|
||||
(match_operand:BLK 1 "memory_operand" "Q,Q")))
|
||||
@ -1913,7 +1923,7 @@
|
||||
(set_attr "atype" "mem,mem")
|
||||
(set_attr "length" "*,14")])
|
||||
|
||||
(define_insn "cmpstr_short_31"
|
||||
(define_insn "cmpmem_short_31"
|
||||
[(set (reg:CCS 33)
|
||||
(compare:CCS (match_operand:BLK 0 "memory_operand" "=Q,Q")
|
||||
(match_operand:BLK 1 "memory_operand" "Q,Q")))
|
||||
@ -1943,7 +1953,7 @@
|
||||
|
||||
; Compare a block of arbitrary length.
|
||||
|
||||
(define_insn "cmpstr_long_64"
|
||||
(define_insn "cmpmem_long_64"
|
||||
[(clobber (match_operand:TI 0 "register_operand" "=d"))
|
||||
(clobber (match_operand:TI 1 "register_operand" "=d"))
|
||||
(set (reg:CCS 33)
|
||||
@ -1958,7 +1968,7 @@
|
||||
(set_attr "type" "vs")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
(define_insn "cmpstr_long_31"
|
||||
(define_insn "cmpmem_long_31"
|
||||
[(clobber (match_operand:DI 0 "register_operand" "=d"))
|
||||
(clobber (match_operand:DI 1 "register_operand" "=d"))
|
||||
(set (reg:CCS 33)
|
||||
|
8
gnu/dist/gcc/gcc/config/sh/libgcc-std.ver
vendored
8
gnu/dist/gcc/gcc/config/sh/libgcc-std.ver
vendored
@ -2,16 +2,16 @@ GCC_3.0 {
|
||||
# libgcc1 integer symbols
|
||||
__absvsi2
|
||||
__addvsi3
|
||||
#__ashlsi3
|
||||
#__ashrsi3
|
||||
# __ashlsi3
|
||||
# __ashrsi3
|
||||
__divsi3
|
||||
#__lshrsi3
|
||||
# __lshrsi3
|
||||
__modsi3
|
||||
__mulsi3
|
||||
__mulvsi3
|
||||
__negvsi2
|
||||
__subvsi3
|
||||
#__udivsi3
|
||||
# __udivsi3
|
||||
__umodsi3
|
||||
|
||||
# libgcc1 floating point symbols
|
||||
|
7
gnu/dist/gcc/gcc/config/sh/t-linux
vendored
7
gnu/dist/gcc/gcc/config/sh/t-linux
vendored
@ -14,8 +14,11 @@ MULTILIB_EXCEPTIONS=
|
||||
EXTRA_MULTILIB_PARTS= crtbegin.o crtend.o crtbeginS.o crtendS.o
|
||||
|
||||
# Override t-slibgcc-elf-ver to export some libgcc symbols with
|
||||
# the symbol versions that glibc used.
|
||||
SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver $(srcdir)/config/sh/libgcc-glibc.ver
|
||||
# the symbol versions that glibc used. Also use sh specific
|
||||
# libgcc-std.ver to avoid to export some lib1func routines which
|
||||
# shoud not be called via PLT.
|
||||
SHLIB_MAPFILES = $(srcdir)/config/sh/libgcc-std.ver \
|
||||
$(srcdir)/config/sh/libgcc-glibc.ver
|
||||
|
||||
# Override SHLIB_LINK and SHLIB_INSTALL to use linker script
|
||||
# libgcc_s.so.
|
||||
|
3
gnu/dist/gcc/gcc/config/sparc/linux.h
vendored
3
gnu/dist/gcc/gcc/config/sparc/linux.h
vendored
@ -245,6 +245,9 @@ do { \
|
||||
#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
|
||||
#endif
|
||||
|
||||
#undef DITF_CONVERSION_LIBFUNCS
|
||||
#define DITF_CONVERSION_LIBFUNCS 1
|
||||
|
||||
#if !defined(USE_GNULIBC_1) && defined(HAVE_LD_EH_FRAME_HDR)
|
||||
#define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
|
||||
#endif
|
||||
|
3
gnu/dist/gcc/gcc/config/sparc/linux64.h
vendored
3
gnu/dist/gcc/gcc/config/sparc/linux64.h
vendored
@ -308,6 +308,9 @@ do { \
|
||||
|
||||
/* #define DWARF_OFFSET_SIZE PTR_SIZE */
|
||||
|
||||
#undef DITF_CONVERSION_LIBFUNCS
|
||||
#define DITF_CONVERSION_LIBFUNCS 1
|
||||
|
||||
#if defined(HAVE_LD_EH_FRAME_HDR)
|
||||
#define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
|
||||
#endif
|
||||
|
19
gnu/dist/gcc/gcc/config/sparc/sol2-bi.h
vendored
19
gnu/dist/gcc/gcc/config/sparc/sol2-bi.h
vendored
@ -18,6 +18,7 @@
|
||||
#undef ASM_CPU32_DEFAULT_SPEC
|
||||
#define ASM_CPU32_DEFAULT_SPEC "-xarch=v8plus"
|
||||
#endif
|
||||
|
||||
#if TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc
|
||||
#undef CPP_CPU64_DEFAULT_SPEC
|
||||
#define CPP_CPU64_DEFAULT_SPEC ""
|
||||
@ -27,6 +28,15 @@
|
||||
#define ASM_CPU64_DEFAULT_SPEC AS_SPARC64_FLAG "a"
|
||||
#endif
|
||||
|
||||
#if TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc3
|
||||
#undef CPP_CPU64_DEFAULT_SPEC
|
||||
#define CPP_CPU64_DEFAULT_SPEC ""
|
||||
#undef ASM_CPU32_DEFAULT_SPEC
|
||||
#define ASM_CPU32_DEFAULT_SPEC "-xarch=v8plusb"
|
||||
#undef ASM_CPU64_DEFAULT_SPEC
|
||||
#define ASM_CPU64_DEFAULT_SPEC AS_SPARC64_FLAG "b"
|
||||
#endif
|
||||
|
||||
#if DEFAULT_ARCH32_P
|
||||
#define DEF_ARCH32_SPEC(__str) "%{!m64:" __str "}"
|
||||
#define DEF_ARCH64_SPEC(__str) "%{m64:" __str "}"
|
||||
@ -45,15 +55,16 @@
|
||||
%{mcpu=sparclite|mcpu-f930|mcpu=f934:-D__sparclite__} \
|
||||
%{mcpu=v8:" DEF_ARCH32_SPEC("-D__sparcv8") "} \
|
||||
%{mcpu=supersparc:-D__supersparc__ " DEF_ARCH32_SPEC("-D__sparcv8") "} \
|
||||
%{mcpu=v9|mcpu=ultrasparc:" DEF_ARCH32_SPEC("-D__sparcv8") "} \
|
||||
%{mcpu=v9|mcpu=ultrasparc|mcpu=ultrasparc3:" DEF_ARCH32_SPEC("-D__sparcv8") "} \
|
||||
%{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(cpp_cpu_default)}}}}}}} \
|
||||
"
|
||||
|
||||
#undef ASM_CPU_SPEC
|
||||
#define ASM_CPU_SPEC "\
|
||||
%{mcpu=ultrasparc:" DEF_ARCH32_SPEC("-xarch=v8plusa") DEF_ARCH64_SPEC(AS_SPARC64_FLAG "a") "} \
|
||||
%{mcpu=v9:" DEF_ARCH32_SPEC("-xarch=v8plus") DEF_ARCH64_SPEC(AS_SPARC64_FLAG) "} \
|
||||
%{!mcpu=ultrasparc:%{!mcpu=v9:%{mcpu*:" DEF_ARCH32_SPEC("-xarch=v8") DEF_ARCH64_SPEC(AS_SPARC64_FLAG) "}}} \
|
||||
%{mcpu=ultrasparc:" DEF_ARCH32_SPEC("-xarch=v8plusa") DEF_ARCH64_SPEC(AS_SPARC64_FLAG "a") "} \
|
||||
%{mcpu=ultrasparc3:" DEF_ARCH32_SPEC("-xarch=v8plusb") DEF_ARCH64_SPEC(AS_SPARC64_FLAG "b") "} \
|
||||
%{!mcpu=ultrasparc3:%{!mcpu=ultrasparc:%{!mcpu=v9:%{mcpu*:" DEF_ARCH32_SPEC("-xarch=v8") DEF_ARCH64_SPEC(AS_SPARC64_FLAG) "}}}} \
|
||||
%{!mcpu*:%(asm_cpu_default)} \
|
||||
"
|
||||
|
||||
@ -143,7 +154,7 @@
|
||||
%{compat-bsd: \
|
||||
%{!YP,*:%{p|pg:-Y P,/usr/ucblib/sparcv9:/usr/lib/libp/sparcv9:/usr/lib/sparcv9} \
|
||||
%{!p:%{!pg:-Y P,/usr/ucblib/sparcv9:/usr/lib/sparcv9}}} \
|
||||
-R /usr/ucblib} \
|
||||
-R /usr/ucblib/sparcv9} \
|
||||
%{!compat-bsd: \
|
||||
%{!YP,*:%{p|pg:-Y P,/usr/lib/libp/sparcv9:/usr/lib/sparcv9} \
|
||||
%{!p:%{!pg:-Y P,/usr/lib/sparcv9}}}}"
|
||||
|
6
gnu/dist/gcc/gcc/config/sparc/sol2.h
vendored
6
gnu/dist/gcc/gcc/config/sparc/sol2.h
vendored
@ -39,11 +39,17 @@ Boston, MA 02111-1307, USA. */
|
||||
#define ASM_CPU_DEFAULT_SPEC "-xarch=v8plusa"
|
||||
#endif
|
||||
|
||||
#if TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc3
|
||||
#undef ASM_CPU_DEFAULT_SPEC
|
||||
#define ASM_CPU_DEFAULT_SPEC "-xarch=v8plusb"
|
||||
#endif
|
||||
|
||||
#undef ASM_CPU_SPEC
|
||||
#define ASM_CPU_SPEC "\
|
||||
%{mcpu=v8plus:-xarch=v8plus} \
|
||||
%{mcpu=v9:-xarch=v8plus} \
|
||||
%{mcpu=ultrasparc:-xarch=v8plusa} \
|
||||
%{mcpu=ultrasparc3:-xarch=v8plusb} \
|
||||
%{!mcpu*:%(asm_cpu_default)} \
|
||||
"
|
||||
|
||||
|
4
gnu/dist/gcc/gcc/config/sparc/t-elf
vendored
4
gnu/dist/gcc/gcc/config/sparc/t-elf
vendored
@ -24,6 +24,6 @@ INSTALL_LIBGCC = install-multilib
|
||||
|
||||
# Assemble startup files.
|
||||
crti.o: $(srcdir)/config/sparc/sol2-ci.asm $(GCC_PASSES)
|
||||
$(GCC_FOR_TARGET) -c -o crti.o -x assembler $(srcdir)/config/sparc/sol2-ci.asm
|
||||
$(GCC_FOR_TARGET) -c -o crti.o -x assembler-with-cpp $(srcdir)/config/sparc/sol2-ci.asm
|
||||
crtn.o: $(srcdir)/config/sparc/sol2-cn.asm $(GCC_PASSES)
|
||||
$(GCC_FOR_TARGET) -c -o crtn.o -x assembler $(srcdir)/config/sparc/sol2-cn.asm
|
||||
$(GCC_FOR_TARGET) -c -o crtn.o -x assembler-with-cpp $(srcdir)/config/sparc/sol2-cn.asm
|
||||
|
0
gnu/dist/gcc/gcc/config/sparc/t-linux
vendored
Normal file
0
gnu/dist/gcc/gcc/config/sparc/t-linux
vendored
Normal file
17
gnu/dist/gcc/gcc/config/vax/vax.c
vendored
17
gnu/dist/gcc/gcc/config/vax/vax.c
vendored
@ -462,7 +462,7 @@ vax_address_cost (addr)
|
||||
case CONST_INT:
|
||||
/* byte offsets cost nothing (on a VAX 2, they cost 1 cycle) */
|
||||
if (offset == 0)
|
||||
offset = (unsigned)(INTVAL(addr)+128) > 256;
|
||||
offset = (unsigned HOST_WIDE_INT)(INTVAL(addr)+128) > 256;
|
||||
break;
|
||||
case CONST:
|
||||
case SYMBOL_REF:
|
||||
@ -595,13 +595,13 @@ vax_rtx_cost (x)
|
||||
fmt = "e"; /* all constant rotate counts are short */
|
||||
break;
|
||||
case PLUS:
|
||||
/* Check for small negative integer operand: subl2 can be used with
|
||||
a short positive constant instead. */
|
||||
if (GET_CODE (XEXP (x, 1)) == CONST_INT)
|
||||
if ((unsigned)(INTVAL (XEXP (x, 1)) + 63) < 127)
|
||||
fmt = "e";
|
||||
case MINUS:
|
||||
c = (mode == DFmode) ? 13 : 8; /* 6/8 on VAX 9000, 16/15 on VAX 2 */
|
||||
/* Small integer operands can use subl2 and addl2. */
|
||||
if ((GET_CODE (XEXP (x, 1)) == CONST_INT)
|
||||
&& (unsigned HOST_WIDE_INT)(INTVAL (XEXP (x, 1)) + 63) < 127)
|
||||
fmt = "e";
|
||||
break;
|
||||
case IOR:
|
||||
case XOR:
|
||||
c = 3;
|
||||
@ -611,7 +611,7 @@ vax_rtx_cost (x)
|
||||
c = 3;
|
||||
if (GET_CODE (XEXP (x, 0)) == CONST_INT)
|
||||
{
|
||||
if ((unsigned)~INTVAL (XEXP (x, 0)) > 63)
|
||||
if ((unsigned HOST_WIDE_INT)~INTVAL (XEXP (x, 0)) > 63)
|
||||
c = 4;
|
||||
fmt = "e";
|
||||
i = 1;
|
||||
@ -665,7 +665,8 @@ vax_rtx_cost (x)
|
||||
switch (code)
|
||||
{
|
||||
case CONST_INT:
|
||||
if ((unsigned)INTVAL (op) > 63 && GET_MODE (x) != QImode)
|
||||
if ((unsigned HOST_WIDE_INT)INTVAL (op) > 63
|
||||
&& GET_MODE (x) != QImode)
|
||||
c += 1; /* 2 on VAX 2 */
|
||||
break;
|
||||
case CONST:
|
||||
|
5
gnu/dist/gcc/gcc/config/vax/vax.h
vendored
5
gnu/dist/gcc/gcc/config/vax/vax.h
vendored
@ -800,11 +800,6 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
|
||||
Do not define this if the table should contain absolute addresses. */
|
||||
#define CASE_VECTOR_PC_RELATIVE 1
|
||||
|
||||
/* Define this if the case instruction drops through after the table
|
||||
when the index is out of range. Don't define it if the case insn
|
||||
jumps to the default label instead. */
|
||||
#define CASE_DROPS_THROUGH
|
||||
|
||||
/* Indicate that jump tables go in the text section. This is
|
||||
necessary when compiling PIC code. */
|
||||
#define JUMP_TABLES_IN_TEXT_SECTION 1
|
||||
|
105
gnu/dist/gcc/gcc/config/vax/vax.md
vendored
105
gnu/dist/gcc/gcc/config/vax/vax.md
vendored
@ -1969,68 +1969,63 @@
|
||||
"jmp (%0)")
|
||||
|
||||
;; This is here to accept 5 arguments (as passed by expand_end_case)
|
||||
;; and pass the first 4 along to the casesi1 pattern that really does the work.
|
||||
;; and pass the first 4 along to the casesi1 pattern that really does
|
||||
;; the actual casesi work. We emit a jump here to the default label
|
||||
;; _before_ the casesi so that we can be sure that the casesi never
|
||||
;; drops through.
|
||||
;; This is suboptimal perhaps, but so is much of the rest of this
|
||||
;; machine description. For what it's worth, HPPA uses the same trick.
|
||||
;;
|
||||
;; operand 0 is index
|
||||
;; operand 1 is the minimum bound (a const_int)
|
||||
;; operand 2 is the maximum bound - minimum bound + 1 (also a const_int)
|
||||
;; operand 3 is CODE_LABEL for the table;
|
||||
;; operand 4 is the CODE_LABEL to go to if index out of range (ie. default).
|
||||
;;
|
||||
;; We emit:
|
||||
;; i = index - minimum_bound
|
||||
;; if (i > (maximum_bound - minimum_bound + 1) goto default;
|
||||
;; casesi (i, 0, table);
|
||||
;;
|
||||
(define_expand "casesi"
|
||||
[(match_operand:SI 0 "general_operand" "") ; index
|
||||
(match_operand:SI 1 "general_operand" "") ; lower
|
||||
(match_operand:SI 2 "general_operand" "") ; upper-lower
|
||||
(match_operand 3 "" "") ; table label
|
||||
(match_operand 4 "" "")] ; default label
|
||||
[(match_operand:SI 0 "general_operand" "")
|
||||
(match_operand:SI 1 "general_operand" "")
|
||||
(match_operand:SI 2 "general_operand" "")
|
||||
(match_operand 3 "" "")
|
||||
(match_operand 4 "" "")]
|
||||
""
|
||||
{
|
||||
emit_jump_insn (gen_casesi1 (operands[0], operands[1],
|
||||
operands[2], operands[3]));
|
||||
/* i = index - minimum_bound;
|
||||
But only if the lower bound is not already zero. */
|
||||
if (operands[1] != const0_rtx)
|
||||
{
|
||||
rtx index = gen_reg_rtx (SImode);
|
||||
emit_insn (gen_addsi3 (index,
|
||||
operands[0],
|
||||
GEN_INT (-INTVAL (operands[1]))));
|
||||
operands[0] = index;
|
||||
}
|
||||
|
||||
/* if (i > (maximum_bound - minimum_bound + 1) goto default; */
|
||||
emit_insn (gen_cmpsi (operands[0], operands[2]));
|
||||
emit_jump_insn (gen_bgtu (operands[4]));
|
||||
|
||||
/* casesi (i, 0, table); */
|
||||
emit_jump_insn (gen_casesi1 (operands[0], operands[2], operands[3]));
|
||||
DONE;
|
||||
})
|
||||
|
||||
;; This insn is a bit of a lier. It actually falls through if no case
|
||||
;; matches. But, we prevent that from ever happening by emiting a jump
|
||||
;; before this, see the define_expand above.
|
||||
(define_insn "casesi1"
|
||||
[(set (pc)
|
||||
(if_then_else
|
||||
(leu (minus:SI (match_operand:SI 0 "general_operand" "g")
|
||||
(match_operand:SI 1 "general_operand" "g"))
|
||||
(match_operand:SI 2 "general_operand" "g"))
|
||||
(plus:SI (sign_extend:SI
|
||||
(mem:HI (plus:SI (mult:SI (minus:SI (match_dup 0)
|
||||
(match_dup 1))
|
||||
(const_int 2))
|
||||
(pc))))
|
||||
(label_ref:SI (match_operand 3 "" "")))
|
||||
(pc)))]
|
||||
""
|
||||
"casel %0,%1,%2")
|
||||
|
||||
;; This can arise by simplification when operand 1 is a constant int.
|
||||
(define_insn ""
|
||||
[(set (pc)
|
||||
(if_then_else
|
||||
(leu (plus:SI (match_operand:SI 0 "general_operand" "g")
|
||||
(match_operand:SI 1 "const_int_operand" "n"))
|
||||
(match_operand:SI 2 "general_operand" "g"))
|
||||
(plus:SI (sign_extend:SI
|
||||
(mem:HI (plus:SI (mult:SI (plus:SI (match_dup 0)
|
||||
(match_dup 1))
|
||||
(const_int 2))
|
||||
(pc))))
|
||||
(label_ref:SI (match_operand 3 "" "")))
|
||||
(pc)))]
|
||||
""
|
||||
"*
|
||||
{
|
||||
operands[1] = GEN_INT (-INTVAL (operands[1]));
|
||||
return \"casel %0,%1,%2\";
|
||||
}")
|
||||
|
||||
;; This can arise by simplification when the base for the case insn is zero.
|
||||
(define_insn ""
|
||||
[(set (pc)
|
||||
(if_then_else (leu (match_operand:SI 0 "general_operand" "g")
|
||||
(match_operand:SI 1 "general_operand" "g"))
|
||||
(plus:SI (sign_extend:SI
|
||||
(mem:HI (plus:SI (mult:SI (match_dup 0)
|
||||
(const_int 2))
|
||||
(pc))))
|
||||
(label_ref:SI (match_operand 2 "" "")))
|
||||
(pc)))]
|
||||
[(match_operand:SI 1 "const_int_operand" "n")
|
||||
(set (pc)
|
||||
(plus:SI (sign_extend:SI
|
||||
(mem:HI (plus:SI (mult:SI (match_operand:SI 0 "general_operand" "g")
|
||||
(const_int 2))
|
||||
(pc))))
|
||||
(label_ref:SI (match_operand 2 "" ""))))]
|
||||
""
|
||||
"casel %0,$0,%1")
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Prototypes of target machine for GNU compiler for Xtensa.
|
||||
Copyright 2001,2002,2003 Free Software Foundation, Inc.
|
||||
Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
|
||||
|
||||
This file is part of GCC.
|
||||
@ -70,14 +70,14 @@ extern int xtensa_expand_conditional_move PARAMS ((rtx *, int));
|
||||
extern int xtensa_expand_scc PARAMS ((rtx *));
|
||||
extern int xtensa_expand_block_move PARAMS ((rtx *));
|
||||
extern int xtensa_emit_move_sequence PARAMS ((rtx *, enum machine_mode));
|
||||
extern bool xtensa_copy_incoming_a7 PARAMS ((rtx *, enum machine_mode));
|
||||
extern rtx xtensa_copy_incoming_a7 PARAMS ((rtx));
|
||||
extern void xtensa_emit_block_move PARAMS ((rtx *, rtx *, int));
|
||||
extern void xtensa_expand_nonlocal_goto PARAMS ((rtx *));
|
||||
extern void xtensa_emit_loop_end PARAMS ((rtx, rtx *));
|
||||
extern char * xtensa_emit_call PARAMS ((int, rtx *));
|
||||
|
||||
#ifdef TREE_CODE
|
||||
extern void init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx));
|
||||
extern void init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, int));
|
||||
extern void xtensa_va_start PARAMS ((tree, rtx));
|
||||
extern rtx xtensa_va_arg PARAMS ((tree, tree));
|
||||
#endif /* TREE_CODE */
|
||||
@ -93,7 +93,6 @@ extern enum reg_class xtensa_preferred_reload_class
|
||||
PARAMS ((rtx, enum reg_class, int));
|
||||
extern enum reg_class xtensa_secondary_reload_class
|
||||
PARAMS ((enum reg_class, enum machine_mode, rtx, int));
|
||||
extern int a7_overlap_mentioned_p PARAMS ((rtx x));
|
||||
#endif /* RTX_CODE */
|
||||
|
||||
#ifdef TREE_CODE
|
||||
|
297
gnu/dist/gcc/gcc/config/xtensa/xtensa.c
vendored
297
gnu/dist/gcc/gcc/config/xtensa/xtensa.c
vendored
@ -1,5 +1,5 @@
|
||||
/* Subroutines for insn-output.c for Tensilica's Xtensa architecture.
|
||||
Copyright 2001,2002,2003 Free Software Foundation, Inc.
|
||||
Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
|
||||
|
||||
This file is part of GCC.
|
||||
@ -90,7 +90,9 @@ const char *xtensa_st_opcodes[(int) MAX_MACHINE_MODE];
|
||||
struct machine_function GTY(())
|
||||
{
|
||||
int accesses_prev_frame;
|
||||
bool incoming_a7_copied;
|
||||
bool need_a7_copy;
|
||||
bool vararg_a7;
|
||||
rtx set_frame_ptr_insn;
|
||||
};
|
||||
|
||||
/* Vector, indexed by hard register number, which contains 1 for a
|
||||
@ -1276,8 +1278,7 @@ xtensa_emit_move_sequence (operands, mode)
|
||||
if (!xtensa_valid_move (mode, operands))
|
||||
operands[1] = force_reg (mode, operands[1]);
|
||||
|
||||
if (xtensa_copy_incoming_a7 (operands, mode))
|
||||
return 1;
|
||||
operands[1] = xtensa_copy_incoming_a7 (operands[1]);
|
||||
}
|
||||
|
||||
/* During reload we don't want to emit (subreg:X (mem:Y)) since that
|
||||
@ -1309,71 +1310,115 @@ fixup_subreg_mem (x)
|
||||
}
|
||||
|
||||
|
||||
/* Check if this move is copying an incoming argument in a7. If so,
|
||||
emit the move, followed by the special "set_frame_ptr"
|
||||
unspec_volatile insn, at the very beginning of the function. This
|
||||
is necessary because the register allocator will ignore conflicts
|
||||
with a7 and may assign some other pseudo to a7. If that pseudo was
|
||||
assigned prior to this move, it would clobber the incoming argument
|
||||
in a7. By copying the argument out of a7 as the very first thing,
|
||||
and then immediately following that with an unspec_volatile to keep
|
||||
the scheduler away, we should avoid any problems. */
|
||||
/* Check if an incoming argument in a7 is expected to be used soon and
|
||||
if OPND is a register or register pair that includes a7. If so,
|
||||
create a new pseudo and copy a7 into that pseudo at the very
|
||||
beginning of the function, followed by the special "set_frame_ptr"
|
||||
unspec_volatile insn. The return value is either the original
|
||||
operand, if it is not a7, or the new pseudo containing a copy of
|
||||
the incoming argument. This is necessary because the register
|
||||
allocator will ignore conflicts with a7 and may either assign some
|
||||
other pseudo to a7 or use a7 as the hard_frame_pointer, clobbering
|
||||
the incoming argument in a7. By copying the argument out of a7 as
|
||||
the very first thing, and then immediately following that with an
|
||||
unspec_volatile to keep the scheduler away, we should avoid any
|
||||
problems. Putting the set_frame_ptr insn at the beginning, with
|
||||
only the a7 copy before it, also makes it easier for the prologue
|
||||
expander to initialize the frame pointer after the a7 copy and to
|
||||
fix up the a7 copy to use the stack pointer instead of the frame
|
||||
pointer. */
|
||||
|
||||
bool
|
||||
xtensa_copy_incoming_a7 (operands, mode)
|
||||
rtx *operands;
|
||||
enum machine_mode mode;
|
||||
rtx
|
||||
xtensa_copy_incoming_a7 (opnd)
|
||||
rtx opnd;
|
||||
{
|
||||
if (a7_overlap_mentioned_p (operands[1])
|
||||
&& !cfun->machine->incoming_a7_copied)
|
||||
rtx entry_insns = 0;
|
||||
rtx reg, tmp;
|
||||
enum machine_mode mode;
|
||||
|
||||
if (!cfun->machine->need_a7_copy)
|
||||
return opnd;
|
||||
|
||||
/* This function should never be called again once a7 has been copied. */
|
||||
if (cfun->machine->set_frame_ptr_insn)
|
||||
abort ();
|
||||
|
||||
mode = GET_MODE (opnd);
|
||||
|
||||
/* The operand using a7 may come in a later instruction, so just return
|
||||
the original operand if it doesn't use a7. */
|
||||
reg = opnd;
|
||||
if (GET_CODE (reg) == SUBREG)
|
||||
{
|
||||
rtx mov;
|
||||
switch (mode)
|
||||
{
|
||||
case DFmode:
|
||||
mov = gen_movdf_internal (operands[0], operands[1]);
|
||||
break;
|
||||
case SFmode:
|
||||
mov = gen_movsf_internal (operands[0], operands[1]);
|
||||
break;
|
||||
case DImode:
|
||||
mov = gen_movdi_internal (operands[0], operands[1]);
|
||||
break;
|
||||
case SImode:
|
||||
mov = gen_movsi_internal (operands[0], operands[1]);
|
||||
break;
|
||||
case HImode:
|
||||
mov = gen_movhi_internal (operands[0], operands[1]);
|
||||
break;
|
||||
case QImode:
|
||||
mov = gen_movqi_internal (operands[0], operands[1]);
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
if (SUBREG_BYTE (reg) != 0)
|
||||
abort ();
|
||||
reg = SUBREG_REG (reg);
|
||||
}
|
||||
if (GET_CODE (reg) != REG
|
||||
|| REGNO (reg) > A7_REG
|
||||
|| REGNO (reg) + HARD_REGNO_NREGS (A7_REG, mode) <= A7_REG)
|
||||
return opnd;
|
||||
|
||||
/* Insert the instructions before any other argument copies.
|
||||
(The set_frame_ptr insn comes _after_ the move, so push it
|
||||
out first.) */
|
||||
push_topmost_sequence ();
|
||||
emit_insn_after (gen_set_frame_ptr (), get_insns ());
|
||||
emit_insn_after (mov, get_insns ());
|
||||
pop_topmost_sequence ();
|
||||
/* 1-word args will always be in a7; 2-word args in a6/a7. */
|
||||
if (REGNO (reg) + HARD_REGNO_NREGS (A7_REG, mode) - 1 != A7_REG)
|
||||
abort ();
|
||||
|
||||
/* Ideally the incoming argument in a7 would only be copied
|
||||
once, since propagating a7 into the body of a function
|
||||
will almost certainly lead to errors. However, there is
|
||||
at least one harmless case (in GCSE) where the original
|
||||
copy from a7 is changed to copy into a new pseudo. Thus,
|
||||
we use a flag to only do this special treatment for the
|
||||
first copy of a7. */
|
||||
cfun->machine->need_a7_copy = false;
|
||||
|
||||
cfun->machine->incoming_a7_copied = true;
|
||||
/* Copy a7 to a new pseudo at the function entry. Use gen_raw_REG to
|
||||
create the REG for a7 so that hard_frame_pointer_rtx is not used. */
|
||||
|
||||
return 1;
|
||||
push_to_sequence (entry_insns);
|
||||
tmp = gen_reg_rtx (mode);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case DFmode:
|
||||
case DImode:
|
||||
emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode, tmp, 0),
|
||||
gen_rtx_REG (SImode, A7_REG - 1)));
|
||||
emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode, tmp, 4),
|
||||
gen_raw_REG (SImode, A7_REG)));
|
||||
break;
|
||||
case SFmode:
|
||||
emit_insn (gen_movsf_internal (tmp, gen_raw_REG (mode, A7_REG)));
|
||||
break;
|
||||
case SImode:
|
||||
emit_insn (gen_movsi_internal (tmp, gen_raw_REG (mode, A7_REG)));
|
||||
break;
|
||||
case HImode:
|
||||
emit_insn (gen_movhi_internal (tmp, gen_raw_REG (mode, A7_REG)));
|
||||
break;
|
||||
case QImode:
|
||||
emit_insn (gen_movqi_internal (tmp, gen_raw_REG (mode, A7_REG)));
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
return 0;
|
||||
cfun->machine->set_frame_ptr_insn = emit_insn (gen_set_frame_ptr ());
|
||||
entry_insns = get_insns ();
|
||||
end_sequence ();
|
||||
|
||||
if (cfun->machine->vararg_a7)
|
||||
{
|
||||
/* This is called from within builtin_savereg, so we're already
|
||||
inside a start_sequence that will be placed at the start of
|
||||
the function. */
|
||||
emit_insn (entry_insns);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Put entry_insns after the NOTE that starts the function. If
|
||||
this is inside a start_sequence, make the outer-level insn
|
||||
chain current, so the code is placed at the start of the
|
||||
function. */
|
||||
push_topmost_sequence ();
|
||||
emit_insn_after (entry_insns, get_insns ());
|
||||
pop_topmost_sequence ();
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
@ -1721,12 +1766,12 @@ xtensa_dbx_register_number (regno)
|
||||
/* Initialize CUMULATIVE_ARGS for a function. */
|
||||
|
||||
void
|
||||
init_cumulative_args (cum, fntype, libname)
|
||||
init_cumulative_args (cum, incoming)
|
||||
CUMULATIVE_ARGS *cum; /* argument info to initialize */
|
||||
tree fntype ATTRIBUTE_UNUSED; /* tree ptr for function decl */
|
||||
rtx libname ATTRIBUTE_UNUSED; /* SYMBOL_REF of library name or 0 */
|
||||
int incoming;
|
||||
{
|
||||
cum->arg_words = 0;
|
||||
cum->incoming = incoming;
|
||||
}
|
||||
|
||||
/* Advance the argument to the next argument position. */
|
||||
@ -1767,7 +1812,6 @@ function_arg (cum, mode, type, incoming_p)
|
||||
int regbase, words, max;
|
||||
int *arg_words;
|
||||
int regno;
|
||||
enum machine_mode result_mode;
|
||||
|
||||
arg_words = &cum->arg_words;
|
||||
regbase = (incoming_p ? GP_ARG_FIRST : GP_OUTGOING_ARG_FIRST);
|
||||
@ -1784,33 +1828,11 @@ function_arg (cum, mode, type, incoming_p)
|
||||
return (rtx)0;
|
||||
|
||||
regno = regbase + *arg_words;
|
||||
result_mode = (mode == BLKmode ? TYPE_MODE (type) : mode);
|
||||
|
||||
/* We need to make sure that references to a7 are represented with
|
||||
rtx that is not equal to hard_frame_pointer_rtx. For BLKmode and
|
||||
modes bigger than 2 words (because we only have patterns for
|
||||
modes of 2 words or smaller), we can't control the expansion
|
||||
unless we explicitly list the individual registers in a PARALLEL. */
|
||||
if (cum->incoming && regno <= A7_REG && regno + words > A7_REG)
|
||||
cfun->machine->need_a7_copy = true;
|
||||
|
||||
if ((mode == BLKmode || words > 2)
|
||||
&& regno < A7_REG
|
||||
&& regno + words > A7_REG)
|
||||
{
|
||||
rtx result;
|
||||
int n;
|
||||
|
||||
result = gen_rtx_PARALLEL (result_mode, rtvec_alloc (words));
|
||||
for (n = 0; n < words; n++)
|
||||
{
|
||||
XVECEXP (result, 0, n) =
|
||||
gen_rtx_EXPR_LIST (VOIDmode,
|
||||
gen_raw_REG (SImode, regno + n),
|
||||
GEN_INT (n * UNITS_PER_WORD));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
return gen_raw_REG (result_mode, regno);
|
||||
return gen_rtx_REG (mode, regno);
|
||||
}
|
||||
|
||||
|
||||
@ -2187,8 +2209,6 @@ void
|
||||
xtensa_reorg (first)
|
||||
rtx first;
|
||||
{
|
||||
rtx insn, set_frame_ptr_insn = 0;
|
||||
|
||||
unsigned long tsize = compute_frame_size (get_frame_size ());
|
||||
if (tsize < (1 << (12+3)))
|
||||
frame_size_const = 0;
|
||||
@ -2204,34 +2224,15 @@ xtensa_reorg (first)
|
||||
if (!frame_pointer_needed)
|
||||
return;
|
||||
|
||||
/* Search all instructions, looking for the insn that sets up the
|
||||
frame pointer. This search will fail if the function does not
|
||||
have an incoming argument in $a7, but in that case, we can just
|
||||
set up the frame pointer at the very beginning of the
|
||||
function. */
|
||||
|
||||
for (insn = first; insn; insn = NEXT_INSN (insn))
|
||||
if (cfun->machine->set_frame_ptr_insn)
|
||||
{
|
||||
rtx pat;
|
||||
rtx insn;
|
||||
|
||||
if (!INSN_P (insn))
|
||||
continue;
|
||||
|
||||
pat = PATTERN (insn);
|
||||
if (GET_CODE (pat) == SET
|
||||
&& GET_CODE (SET_SRC (pat)) == UNSPEC_VOLATILE
|
||||
&& (XINT (SET_SRC (pat), 1) == UNSPECV_SET_FP))
|
||||
{
|
||||
set_frame_ptr_insn = insn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (set_frame_ptr_insn)
|
||||
{
|
||||
/* for all instructions prior to set_frame_ptr_insn, replace
|
||||
hard_frame_pointer references with stack_pointer */
|
||||
for (insn = first; insn != set_frame_ptr_insn; insn = NEXT_INSN (insn))
|
||||
for (insn = first;
|
||||
insn != cfun->machine->set_frame_ptr_insn;
|
||||
insn = NEXT_INSN (insn))
|
||||
{
|
||||
if (INSN_P (insn))
|
||||
PATTERN (insn) = replace_rtx (copy_rtx (PATTERN (insn)),
|
||||
@ -2379,9 +2380,8 @@ xtensa_builtin_saveregs ()
|
||||
rtx gp_regs, dest;
|
||||
int arg_words = current_function_arg_words;
|
||||
int gp_left = MAX_ARGS_IN_REGISTERS - arg_words;
|
||||
int i;
|
||||
|
||||
if (gp_left == 0)
|
||||
if (gp_left <= 0)
|
||||
return const0_rtx;
|
||||
|
||||
/* allocate the general-purpose register space */
|
||||
@ -2394,15 +2394,10 @@ xtensa_builtin_saveregs ()
|
||||
plus_constant (XEXP (gp_regs, 0),
|
||||
arg_words * UNITS_PER_WORD));
|
||||
|
||||
/* Note: Don't use move_block_from_reg() here because the incoming
|
||||
argument in a7 cannot be represented by hard_frame_pointer_rtx.
|
||||
Instead, call gen_raw_REG() directly so that we get a distinct
|
||||
instance of (REG:SI 7). */
|
||||
for (i = 0; i < gp_left; i++)
|
||||
{
|
||||
emit_move_insn (operand_subword (dest, i, 1, BLKmode),
|
||||
gen_raw_REG (SImode, GP_ARG_FIRST + arg_words + i));
|
||||
}
|
||||
cfun->machine->need_a7_copy = true;
|
||||
cfun->machine->vararg_a7 = true;
|
||||
move_block_from_reg (GP_ARG_FIRST + arg_words, dest, gp_left,
|
||||
gp_left * UNITS_PER_WORD);
|
||||
|
||||
return XEXP (gp_regs, 0);
|
||||
}
|
||||
@ -2722,56 +2717,6 @@ order_regs_for_local_alloc ()
|
||||
}
|
||||
|
||||
|
||||
/* A customized version of reg_overlap_mentioned_p that only looks for
|
||||
references to a7 (as opposed to hard_frame_pointer_rtx). */
|
||||
|
||||
int
|
||||
a7_overlap_mentioned_p (x)
|
||||
rtx x;
|
||||
{
|
||||
int i, j;
|
||||
unsigned int x_regno;
|
||||
const char *fmt;
|
||||
|
||||
if (GET_CODE (x) == REG)
|
||||
{
|
||||
x_regno = REGNO (x);
|
||||
return (x != hard_frame_pointer_rtx
|
||||
&& x_regno < A7_REG + 1
|
||||
&& x_regno + HARD_REGNO_NREGS (A7_REG, GET_MODE (x)) > A7_REG);
|
||||
}
|
||||
|
||||
if (GET_CODE (x) == SUBREG
|
||||
&& GET_CODE (SUBREG_REG (x)) == REG
|
||||
&& REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
|
||||
{
|
||||
x_regno = subreg_regno (x);
|
||||
return (SUBREG_REG (x) != hard_frame_pointer_rtx
|
||||
&& x_regno < A7_REG + 1
|
||||
&& x_regno + HARD_REGNO_NREGS (A7_REG, GET_MODE (x)) > A7_REG);
|
||||
}
|
||||
|
||||
/* X does not match, so try its subexpressions. */
|
||||
fmt = GET_RTX_FORMAT (GET_CODE (x));
|
||||
for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
|
||||
{
|
||||
if (fmt[i] == 'e')
|
||||
{
|
||||
if (a7_overlap_mentioned_p (XEXP (x, i)))
|
||||
return 1;
|
||||
}
|
||||
else if (fmt[i] == 'E')
|
||||
{
|
||||
for (j = XVECLEN (x, i) - 1; j >=0; j--)
|
||||
if (a7_overlap_mentioned_p (XVECEXP (x, i, j)))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Some Xtensa targets support multiple bss sections. If the section
|
||||
name ends with ".bss", add SECTION_BSS to the flags. */
|
||||
|
||||
|
24
gnu/dist/gcc/gcc/config/xtensa/xtensa.h
vendored
24
gnu/dist/gcc/gcc/config/xtensa/xtensa.h
vendored
@ -1,5 +1,5 @@
|
||||
/* Definitions of Tensilica's Xtensa target machine for GNU compiler.
|
||||
Copyright 2001,2002,2003 Free Software Foundation, Inc.
|
||||
Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
|
||||
|
||||
This file is part of GCC.
|
||||
@ -853,23 +853,21 @@ extern enum reg_class xtensa_char_to_class[256];
|
||||
#define FUNCTION_ARG_REGNO_P(N) \
|
||||
((N) >= GP_OUTGOING_ARG_FIRST && (N) <= GP_OUTGOING_ARG_LAST)
|
||||
|
||||
/* Define a data type for recording info about an argument list
|
||||
during the scan of that argument list. This data type should
|
||||
hold all necessary information about the function itself
|
||||
and about the args processed so far, enough to enable macros
|
||||
such as FUNCTION_ARG to determine where the next arg should go. */
|
||||
typedef struct xtensa_args {
|
||||
int arg_words; /* # total words the arguments take */
|
||||
/* Record the number of argument words seen so far, along with a flag to
|
||||
indicate whether these are incoming arguments. (FUNCTION_INCOMING_ARG
|
||||
is used for both incoming and outgoing args, so a separate flag is
|
||||
needed. */
|
||||
typedef struct xtensa_args
|
||||
{
|
||||
int arg_words;
|
||||
int incoming;
|
||||
} CUMULATIVE_ARGS;
|
||||
|
||||
/* 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. */
|
||||
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
|
||||
init_cumulative_args (&CUM, FNTYPE, LIBNAME)
|
||||
init_cumulative_args (&CUM, 0)
|
||||
|
||||
#define INIT_CUMULATIVE_INCOMING_ARGS(CUM, FNTYPE, LIBNAME) \
|
||||
init_cumulative_args (&CUM, FNTYPE, LIBNAME)
|
||||
init_cumulative_args (&CUM, 1)
|
||||
|
||||
/* Update the data in CUM to advance over an argument
|
||||
of mode MODE and data type TYPE.
|
||||
|
22
gnu/dist/gcc/gcc/config/xtensa/xtensa.md
vendored
22
gnu/dist/gcc/gcc/config/xtensa/xtensa.md
vendored
@ -1,5 +1,5 @@
|
||||
;; GCC machine description for Tensilica's Xtensa architecture.
|
||||
;; Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
;; Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
|
||||
|
||||
;; This file is part of GCC.
|
||||
@ -942,8 +942,7 @@
|
||||
&& !register_operand (operands[1], DImode))
|
||||
operands[1] = force_reg (DImode, operands[1]);
|
||||
|
||||
if (xtensa_copy_incoming_a7 (operands, DImode))
|
||||
DONE;
|
||||
operands[1] = xtensa_copy_incoming_a7 (operands[1]);
|
||||
}
|
||||
}")
|
||||
|
||||
@ -1116,8 +1115,7 @@
|
||||
&& constantpool_mem_p (operands[1]))))
|
||||
operands[1] = force_reg (SFmode, operands[1]);
|
||||
|
||||
if (xtensa_copy_incoming_a7 (operands, SFmode))
|
||||
DONE;
|
||||
operands[1] = xtensa_copy_incoming_a7 (operands[1]);
|
||||
}
|
||||
}")
|
||||
|
||||
@ -1198,8 +1196,7 @@
|
||||
&& !register_operand (operands[1], DFmode))
|
||||
operands[1] = force_reg (DFmode, operands[1]);
|
||||
|
||||
if (xtensa_copy_incoming_a7 (operands, DFmode))
|
||||
DONE;
|
||||
operands[1] = xtensa_copy_incoming_a7 (operands[1]);
|
||||
}
|
||||
}")
|
||||
|
||||
@ -1302,7 +1299,16 @@
|
||||
;; ....................
|
||||
;;
|
||||
|
||||
(define_insn "ashlsi3"
|
||||
(define_expand "ashlsi3"
|
||||
[(set (match_operand:SI 0 "register_operand" "")
|
||||
(ashift:SI (match_operand:SI 1 "register_operand" "")
|
||||
(match_operand:SI 2 "arith_operand" "")))]
|
||||
""
|
||||
{
|
||||
operands[1] = xtensa_copy_incoming_a7 (operands[1]);
|
||||
})
|
||||
|
||||
(define_insn "ashlsi3_internal"
|
||||
[(set (match_operand:SI 0 "register_operand" "=a,a")
|
||||
(ashift:SI (match_operand:SI 1 "register_operand" "r,r")
|
||||
(match_operand:SI 2 "arith_operand" "J,r")))]
|
||||
|
22
gnu/dist/gcc/gcc/convert.c
vendored
22
gnu/dist/gcc/gcc/convert.c
vendored
@ -182,7 +182,27 @@ convert_to_integer (type, expr)
|
||||
we are truncating EXPR. */
|
||||
|
||||
else if (outprec >= inprec)
|
||||
return build1 (NOP_EXPR, type, expr);
|
||||
{
|
||||
enum tree_code code;
|
||||
|
||||
/* If the precision of the EXPR's type is K bits and the
|
||||
destination mode has more bits, and the sign is changing,
|
||||
it is not safe to use a NOP_EXPR. For example, suppose
|
||||
that EXPR's type is a 3-bit unsigned integer type, the
|
||||
TYPE is a 3-bit signed integer type, and the machine mode
|
||||
for the types is 8-bit QImode. In that case, the
|
||||
conversion necessitates an explicit sign-extension. In
|
||||
the signed-to-unsigned case the high-order bits have to
|
||||
be cleared. */
|
||||
if (TREE_UNSIGNED (type) != TREE_UNSIGNED (TREE_TYPE (expr))
|
||||
&& (TYPE_PRECISION (TREE_TYPE (expr))
|
||||
!= GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (expr)))))
|
||||
code = CONVERT_EXPR;
|
||||
else
|
||||
code = NOP_EXPR;
|
||||
|
||||
return build1 (code, type, expr);
|
||||
}
|
||||
|
||||
/* If TYPE is an enumeral type or a type with a precision less
|
||||
than the number of bits in its mode, do the conversion to the
|
||||
|
234
gnu/dist/gcc/gcc/cp/ChangeLog
vendored
234
gnu/dist/gcc/gcc/cp/ChangeLog
vendored
@ -1,3 +1,237 @@
|
||||
2005-05-03 Release Manager
|
||||
|
||||
* GCC 3.3.6 Released.
|
||||
|
||||
2005-04-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
PR c++/18644
|
||||
* call.c (build_new_op): Remove check for warn_synth.
|
||||
|
||||
2004-12-18 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
|
||||
|
||||
PR c++/17456
|
||||
* cvt.c (convert_to_void): Set expr to void_zero_node after
|
||||
overload failure.
|
||||
|
||||
2004-12-15 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
|
||||
|
||||
PR c++/16806
|
||||
* error.c (dump_expr) [BASELINK]: Use dump_expr.
|
||||
|
||||
2004-12-10 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
|
||||
|
||||
PR c++/17868
|
||||
* error.c (dump_expr): Add missing case for RDIV_EXPR.
|
||||
|
||||
2004-12-09 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
PR c++/16681
|
||||
* init.c (build_zero_init): Build a RANGE_EXPR for an array
|
||||
initializer.
|
||||
|
||||
2004-09-30 Release Manager
|
||||
|
||||
* GCC 3.3.5 Released.
|
||||
|
||||
2004-09-21 Giovanni Bajo <giovannibajo@gcc.gnu.org>
|
||||
|
||||
* decl.c (reshape_init): Remove unused variable.
|
||||
|
||||
2004-09-21 Giovanni Bajo <giovannibajo@gcc.gnu.org>
|
||||
|
||||
PR c++/14179
|
||||
* decl.c (reshape_init): Extract array handling into...
|
||||
(reshape_init_array): New function. Use integers instead of trees
|
||||
for indices.
|
||||
|
||||
2004-09-13 Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
PR c++/15857
|
||||
Backport from gcc-3_4-branch
|
||||
2004-08-24 Jason Merrill <jason@redhat.com>
|
||||
PR c++/15461
|
||||
* semantics.c (nullify_returns_r): Replace a DECL_STMT
|
||||
for the NRV with an INIT_EXPR.
|
||||
|
||||
2004-07-24 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
PR c++/16175
|
||||
* error.c (dump_type) <BOUND_TEMPLATE_TEMPLATE_PARM case>: Output
|
||||
cv qualifier.
|
||||
|
||||
2004-05-31 Release Manager
|
||||
|
||||
* GCC 3.3.4 Released.
|
||||
|
||||
2004-05-16 Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
Backport from mainline:
|
||||
2004-03-18 Mark Mitchell <mark@codesourcery.com>
|
||||
* call.c (build_conditional_expr): Do not call force_rvalue for
|
||||
operands of void_type when the conditional expression itself has
|
||||
void type.
|
||||
|
||||
2004-05-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* Make-lang.in (cp/init.o): Depend on diagnostic.h.
|
||||
* except.c (do_free_exception): Prototype.
|
||||
* init.c: Include "diagnostic.h".
|
||||
|
||||
2004-05-04 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
|
||||
|
||||
Backport:
|
||||
2004-04-01 Mark Mitchell <mark@codesourcery.com>
|
||||
PR c++/14810
|
||||
* decl.c (maybe_push_cleanup_level): Robustify.
|
||||
|
||||
2004-05-01 Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
Backport from gcc-3_4-branch
|
||||
2004-03-30 Mark Mitchell <mark@codesourcery.com>
|
||||
Jakub Jelinek <jakub@redhat.com>
|
||||
PR c++/14763
|
||||
* pt.c (tsubst_default_argument): Clear current_function_decl.
|
||||
* decl2.c (mark_used): Don't segfault if cfun != NULL but
|
||||
current_function_decl == NULL.
|
||||
|
||||
2004-05-01 Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
Backport from gcc-3_4-branch:
|
||||
2004-03-30 Mark Mitchell <mark@codesourcery.com>
|
||||
PR c++/14724
|
||||
* decl.c (start_decl_1): Do not decide whether or not to create a
|
||||
new cleanup level until after the type has been completed.
|
||||
|
||||
2004-04-01 Richard Henderson <rth@redhat.com>
|
||||
|
||||
PR c++/14804
|
||||
* decl.c (cp_finish_decl): Preserve TREE_READONLY more often.
|
||||
* typeck2.c (split_nonconstant_init): Clear TREE_READONLY.
|
||||
|
||||
2003-03-17 Matt Austern <austern@apple.com>
|
||||
|
||||
Backport:
|
||||
PR debug/14079
|
||||
* decl.c (add_decl_to_level): Add extern variables, as well
|
||||
as static, to static_decls array.
|
||||
|
||||
2004-03-12 Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
Backport:
|
||||
2004-03-11 Mark Mitchell <mark@codesourcery.com>
|
||||
PR c++/14476
|
||||
* decl.c (xref_tag): Do not create dummy ENUMERAL_TYPEs.
|
||||
|
||||
2004-03-12 Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
Backport:
|
||||
2004-03-08 Mark Mitchell <mark@codesourcery.com>
|
||||
PR c++/14401
|
||||
* class.c (check_field_decls): Complain about non-static data
|
||||
members of reference type in unions. Propagate
|
||||
CLASSTYPE_REF_FIELDS_NEED_INIT and
|
||||
CLASSTYPE_READONLY_FIELDS_NEED_INIT from the types of non-static
|
||||
data members.
|
||||
* init.c (perform_member_init): Complain about members with const
|
||||
type that are not explicitly initialized.
|
||||
|
||||
2004-03-12 Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
Backport:
|
||||
2004-03-09 Mark Mitchell <mark@codesourcery.com>
|
||||
PR c++/14230
|
||||
* call.c (initialize_reference): Handle initializers that are
|
||||
class-member access expressions applies to rvalues.
|
||||
|
||||
2004-03-12 Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
Backport:
|
||||
2004-01-12 Richard Henderson <rth@redhat.com>
|
||||
PR opt/10776
|
||||
* typeck2.c (split_nonconstant_init_1, split_nonconstant_init): New.
|
||||
(store_init_value): Use it.
|
||||
* decl.c (check_initializer): Expect full initialization code
|
||||
from store_init_value.
|
||||
* init.c (expand_aggr_init_1): Likewise.
|
||||
* decl2.c (maybe_emit_vtables): Abort if runtime init needed.
|
||||
|
||||
2004-03-09 Giovanni Bajo <giovannibajo@gcc.gnu.org>
|
||||
|
||||
PR c++/14409
|
||||
* pt.c (determine_specialization): For member templates, match also
|
||||
constness.
|
||||
|
||||
2004-03-05 Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
Backport:
|
||||
2004-02-04 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/9941
|
||||
* rtti.c (tinfo_base_init): Use import_export_tinfo to decide the
|
||||
linkage for the typeinfo name string.
|
||||
|
||||
2004-02-24 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/13944
|
||||
* except.c (do_free_exception): Remove #if 0 wrapper.
|
||||
(build_throw): Use it if we elide a copy into the exception object.
|
||||
|
||||
2004-03-01 Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
* decl.c (current_binding_level): Define as an lvalue.
|
||||
|
||||
2004-02-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
PR c++/13635
|
||||
* pt.c (push_template_decl_real): Make sure DECL_TI_ARGS of DECL
|
||||
has full set of arguments.
|
||||
|
||||
2004-02-23 Giovanni Bajo <giovannibajo@gcc.gnu.org>
|
||||
|
||||
PR c++/14250
|
||||
* cvt.c (build_expr_type_conversion): Type must be complete before
|
||||
looking up for conversions.
|
||||
|
||||
2004-02-22 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* decl.c (reshape_init): Convert array designator to sizetype.
|
||||
|
||||
2004-02-22 Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
Backport from mainline
|
||||
2004-02-13 Mark Mitchell <mark@codesourcery.com>
|
||||
PR c++/14083
|
||||
* call.c (build_conditional_expr): Call force_rvalue on the
|
||||
non-void operand in the case that one result is a throw-expression
|
||||
and the other is not.
|
||||
|
||||
2004-02-22 Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
Backport from mainline
|
||||
2003-02-06 Giovanni Bajo <giovannibajo@gcc.gnu.org>
|
||||
PR c++/14033
|
||||
* decl.c (require_complete_types_for_parms): Do not insert
|
||||
error_mark_node in the parameter list.
|
||||
|
||||
2004-02-22 Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
Backport from mainline
|
||||
2004-02-04 Mark Mitchell <mark@codesourcery.com>
|
||||
PR c++/13932
|
||||
* call.c (convert_like_real): Use "converting" rather than
|
||||
"argument" as the descriptive keyword to
|
||||
dubious_conversion_warnings.
|
||||
* typeck.c (convert_for_assignment): Do not call
|
||||
dubious_conversion_warnings.
|
||||
|
||||
2004-02-22 Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
Backport from mainline
|
||||
2004-02-02 Mark Mitchell <mark@codesourcery.com>
|
||||
PR c++/13907
|
||||
* call.c (convert_class_to_reference): Keep better track of
|
||||
pedantically invalid user-defined conversions.
|
||||
|
||||
2004-02-14 Release Manager
|
||||
|
||||
* GCC 3.3.3 Released.
|
||||
|
2
gnu/dist/gcc/gcc/cp/Make-lang.in
vendored
2
gnu/dist/gcc/gcc/cp/Make-lang.in
vendored
@ -250,7 +250,7 @@ cp/call.o: cp/call.c $(CXX_TREE_H) flags.h toplev.h $(RTL_H) $(EXPR_H) \
|
||||
$(GGC_H) diagnostic.h gt-cp-call.h
|
||||
cp/friend.o: cp/friend.c $(CXX_TREE_H) flags.h $(RTL_H) toplev.h $(EXPR_H)
|
||||
cp/init.o: cp/init.c $(CXX_TREE_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \
|
||||
$(GGC_H) except.h
|
||||
diagnostic.h $(GGC_H) except.h
|
||||
cp/method.o: cp/method.c $(CXX_TREE_H) toplev.h $(GGC_H) $(RTL_H) $(EXPR_H) \
|
||||
$(TM_P_H) $(TARGET_H)
|
||||
cp/cvt.o: cp/cvt.c $(CXX_TREE_H) cp/decl.h flags.h toplev.h convert.h
|
||||
|
115
gnu/dist/gcc/gcc/cp/call.c
vendored
115
gnu/dist/gcc/gcc/cp/call.c
vendored
@ -1091,15 +1091,19 @@ convert_class_to_reference (t, s, expr)
|
||||
LOOKUP_NORMAL);
|
||||
|
||||
if (cand)
|
||||
/* Build a standard conversion sequence indicating the
|
||||
binding from the reference type returned by the
|
||||
function to the desired REFERENCE_TYPE. */
|
||||
cand->second_conv
|
||||
= (direct_reference_binding
|
||||
(reference_type,
|
||||
build1 (IDENTITY_CONV,
|
||||
TREE_TYPE (TREE_TYPE (TREE_TYPE (cand->fn))),
|
||||
NULL_TREE)));
|
||||
{
|
||||
/* Build a standard conversion sequence indicating the
|
||||
binding from the reference type returned by the
|
||||
function to the desired REFERENCE_TYPE. */
|
||||
cand->second_conv
|
||||
= (direct_reference_binding
|
||||
(reference_type,
|
||||
build1 (IDENTITY_CONV,
|
||||
TREE_TYPE (TREE_TYPE (TREE_TYPE (cand->fn))),
|
||||
NULL_TREE)));
|
||||
ICS_BAD_FLAG (cand->second_conv)
|
||||
|= ICS_BAD_FLAG (TREE_VEC_ELT (cand->convs, 0));
|
||||
}
|
||||
}
|
||||
conversions = TREE_CHAIN (conversions);
|
||||
}
|
||||
@ -3238,11 +3242,27 @@ build_conditional_expr (arg1, arg2, arg3)
|
||||
type of the other and is an rvalue.
|
||||
|
||||
--Both the second and the third operands have type void; the
|
||||
result is of type void and is an rvalue. */
|
||||
if ((TREE_CODE (arg2) == THROW_EXPR)
|
||||
^ (TREE_CODE (arg3) == THROW_EXPR))
|
||||
result_type = ((TREE_CODE (arg2) == THROW_EXPR)
|
||||
? arg3_type : arg2_type);
|
||||
result is of type void and is an rvalue.
|
||||
|
||||
We must avoid calling force_rvalue for expressions of type
|
||||
"void" because it will complain that their value is being
|
||||
used. */
|
||||
if (TREE_CODE (arg2) == THROW_EXPR
|
||||
&& TREE_CODE (arg3) != THROW_EXPR)
|
||||
{
|
||||
if (!VOID_TYPE_P (arg3_type))
|
||||
arg3 = force_rvalue (arg3);
|
||||
arg3_type = TREE_TYPE (arg3);
|
||||
result_type = arg3_type;
|
||||
}
|
||||
else if (TREE_CODE (arg2) != THROW_EXPR
|
||||
&& TREE_CODE (arg3) == THROW_EXPR)
|
||||
{
|
||||
if (!VOID_TYPE_P (arg2_type))
|
||||
arg2 = force_rvalue (arg2);
|
||||
arg2_type = TREE_TYPE (arg2);
|
||||
result_type = arg2_type;
|
||||
}
|
||||
else if (VOID_TYPE_P (arg2_type) && VOID_TYPE_P (arg3_type))
|
||||
result_type = void_type_node;
|
||||
else
|
||||
@ -3742,28 +3762,11 @@ build_new_op (code, flags, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
if (TREE_CODE (cand->fn) == FUNCTION_DECL)
|
||||
{
|
||||
extern int warn_synth;
|
||||
if (warn_synth
|
||||
&& fnname == ansi_assopname (NOP_EXPR)
|
||||
&& DECL_ARTIFICIAL (cand->fn)
|
||||
&& candidates->next
|
||||
&& ! candidates->next->next)
|
||||
{
|
||||
warning ("using synthesized `%#D' for copy assignment",
|
||||
cand->fn);
|
||||
cp_warning_at (" where cfront would use `%#D'",
|
||||
cand == candidates
|
||||
? candidates->next->fn
|
||||
: candidates->fn);
|
||||
}
|
||||
|
||||
return build_over_call
|
||||
(cand,
|
||||
TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE
|
||||
? mem_arglist : arglist,
|
||||
LOOKUP_NORMAL);
|
||||
}
|
||||
return build_over_call
|
||||
(cand,
|
||||
TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE
|
||||
? mem_arglist : arglist,
|
||||
LOOKUP_NORMAL);
|
||||
|
||||
/* Check for comparison of different enum types. */
|
||||
switch (code)
|
||||
@ -4093,7 +4096,7 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner,
|
||||
|
||||
if (issue_conversion_warnings)
|
||||
expr = dubious_conversion_warnings
|
||||
(totype, expr, "argument", fn, argnum);
|
||||
(totype, expr, "converting", fn, argnum);
|
||||
switch (TREE_CODE (convs))
|
||||
{
|
||||
case USER_CONV:
|
||||
@ -4308,20 +4311,20 @@ convert_arg_to_ellipsis (arg)
|
||||
|
||||
arg = require_complete_type (arg);
|
||||
|
||||
if (arg != error_mark_node
|
||||
&& !pod_type_p (TREE_TYPE (arg)))
|
||||
{
|
||||
/* Undefined behavior [expr.call] 5.2.2/7. We used to just warn
|
||||
here and do a bitwise copy, but now cp_expr_size will abort if we
|
||||
try to do that.
|
||||
If the call appears in the context of a sizeof expression,
|
||||
there is no need to emit a warning, since the expression won't be
|
||||
evaluated. We keep the builtin_trap just as a safety check. */
|
||||
if (!skip_evaluation)
|
||||
warning ("cannot pass objects of non-POD type `%#T' through `...'; "
|
||||
"call will abort at runtime", TREE_TYPE (arg));
|
||||
arg = call_builtin_trap ();
|
||||
}
|
||||
if (arg != error_mark_node
|
||||
&& !pod_type_p (TREE_TYPE (arg)))
|
||||
{
|
||||
/* Undefined behavior [expr.call] 5.2.2/7. We used to just warn
|
||||
here and do a bitwise copy, but now cp_expr_size will abort if we
|
||||
try to do that.
|
||||
If the call appears in the context of a sizeof expression,
|
||||
there is no need to emit a warning, since the expression won't be
|
||||
evaluated. We keep the builtin_trap just as a safety check. */
|
||||
if (!skip_evaluation)
|
||||
warning ("cannot pass objects of non-POD type `%#T' through `...'; "
|
||||
"call will abort at runtime", TREE_TYPE (arg));
|
||||
arg = call_builtin_trap ();
|
||||
}
|
||||
|
||||
return arg;
|
||||
}
|
||||
@ -6190,6 +6193,16 @@ initialize_reference (type, expr, decl, cleanup)
|
||||
type = TREE_TYPE (expr);
|
||||
var = make_temporary_var_for_ref_to_temp (decl, type);
|
||||
layout_decl (var, 0);
|
||||
/* If the rvalue is the result of a function call it will be
|
||||
a TARGET_EXPR. If it is some other construct (such as a
|
||||
member access expression where the underlying object is
|
||||
itself the result of a function call), turn it into a
|
||||
TARGET_EXPR here. It is important that EXPR be a
|
||||
TARGET_EXPR below since otherwise the INIT_EXPR will
|
||||
attempt to make a bitwise copy of EXPR to intialize
|
||||
VAR. */
|
||||
if (TREE_CODE (expr) != TARGET_EXPR)
|
||||
expr = get_target_expr (expr);
|
||||
/* Create the INIT_EXPR that will initialize the temporary
|
||||
variable. */
|
||||
init = build (INIT_EXPR, type, var, expr);
|
||||
|
45
gnu/dist/gcc/gcc/cp/class.c
vendored
45
gnu/dist/gcc/gcc/cp/class.c
vendored
@ -3231,9 +3231,30 @@ check_field_decls (tree t, tree *access_decls,
|
||||
|
||||
/* If we've gotten this far, it's a data member, possibly static,
|
||||
or an enumerator. */
|
||||
|
||||
DECL_CONTEXT (x) = t;
|
||||
|
||||
/* When this goes into scope, it will be a non-local reference. */
|
||||
DECL_NONLOCAL (x) = 1;
|
||||
|
||||
if (TREE_CODE (t) == UNION_TYPE)
|
||||
{
|
||||
/* [class.union]
|
||||
|
||||
If a union contains a static data member, or a member of
|
||||
reference type, the program is ill-formed. */
|
||||
if (TREE_CODE (x) == VAR_DECL)
|
||||
{
|
||||
cp_error_at ("`%D' may not be static because it is a member of a union", x);
|
||||
continue;
|
||||
}
|
||||
if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
{
|
||||
cp_error_at ("`%D' may not have reference type `%T' because it is a member of a union",
|
||||
x, type);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* ``A local class cannot have static data members.'' ARM 9.4 */
|
||||
if (current_function_decl && TREE_STATIC (x))
|
||||
cp_error_at ("field `%D' in local class cannot be static", x);
|
||||
@ -3263,21 +3284,9 @@ check_field_decls (tree t, tree *access_decls,
|
||||
if (type == error_mark_node)
|
||||
continue;
|
||||
|
||||
/* When this goes into scope, it will be a non-local reference. */
|
||||
DECL_NONLOCAL (x) = 1;
|
||||
|
||||
if (TREE_CODE (x) == CONST_DECL)
|
||||
if (TREE_CODE (x) == CONST_DECL || TREE_CODE (x) == VAR_DECL)
|
||||
continue;
|
||||
|
||||
if (TREE_CODE (x) == VAR_DECL)
|
||||
{
|
||||
if (TREE_CODE (t) == UNION_TYPE)
|
||||
/* Unions cannot have static members. */
|
||||
cp_error_at ("field `%D' declared static in union", x);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Now it can only be a FIELD_DECL. */
|
||||
|
||||
if (TREE_PRIVATE (x) || TREE_PROTECTED (x))
|
||||
@ -3308,6 +3317,14 @@ check_field_decls (tree t, tree *access_decls,
|
||||
if (TREE_CODE (type) == POINTER_TYPE)
|
||||
has_pointers = 1;
|
||||
|
||||
if (CLASS_TYPE_P (type))
|
||||
{
|
||||
if (CLASSTYPE_REF_FIELDS_NEED_INIT (type))
|
||||
SET_CLASSTYPE_REF_FIELDS_NEED_INIT (t, 1);
|
||||
if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (type))
|
||||
SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t, 1);
|
||||
}
|
||||
|
||||
if (DECL_MUTABLE_P (x) || TYPE_HAS_MUTABLE_P (type))
|
||||
CLASSTYPE_HAS_MUTABLE (t) = 1;
|
||||
|
||||
|
6
gnu/dist/gcc/gcc/cp/cvt.c
vendored
6
gnu/dist/gcc/gcc/cp/cvt.c
vendored
@ -903,6 +903,7 @@ convert_to_void (expr, implicit)
|
||||
of an overloaded function, and this is not one of them. */
|
||||
pedwarn ("%s cannot resolve address of overloaded function",
|
||||
implicit ? implicit : "void cast");
|
||||
expr = void_zero_node;
|
||||
}
|
||||
else if (implicit && probe == expr && is_overloaded_fn (probe))
|
||||
/* Only warn when there is no &. */
|
||||
@ -1073,8 +1074,9 @@ build_expr_type_conversion (desires, expr, complain)
|
||||
|
||||
/* The code for conversions from class type is currently only used for
|
||||
delete expressions. Other expressions are handled by build_new_op. */
|
||||
|
||||
if (! TYPE_HAS_CONVERSION (basetype))
|
||||
if (!complete_type_or_else (basetype, expr))
|
||||
return error_mark_node;
|
||||
if (!TYPE_HAS_CONVERSION (basetype))
|
||||
return NULL_TREE;
|
||||
|
||||
for (conv = lookup_conversions (basetype); conv; conv = TREE_CHAIN (conv))
|
||||
|
158
gnu/dist/gcc/gcc/cp/decl.c
vendored
158
gnu/dist/gcc/gcc/cp/decl.c
vendored
@ -147,6 +147,7 @@ static int cp_missing_noreturn_ok_p PARAMS ((tree));
|
||||
static void initialize_local_var (tree, tree);
|
||||
static void expand_static_init (tree, tree);
|
||||
static tree next_initializable_field (tree);
|
||||
static bool reshape_init_array (tree, tree, tree *, tree);
|
||||
static tree reshape_init (tree, tree *);
|
||||
|
||||
/* Erroneous argument lists can use this *IFF* they do not modify it. */
|
||||
@ -673,9 +674,9 @@ struct cp_binding_level GTY(())
|
||||
/* The binding level currently in effect. */
|
||||
|
||||
#define current_binding_level \
|
||||
(cfun && cp_function_chain->bindings \
|
||||
? cp_function_chain->bindings \
|
||||
: scope_chain->bindings)
|
||||
(*(cfun && cp_function_chain->bindings \
|
||||
? &cp_function_chain->bindings \
|
||||
: &scope_chain->bindings))
|
||||
|
||||
/* The binding level of the current class, if any. */
|
||||
|
||||
@ -1075,7 +1076,8 @@ void
|
||||
maybe_push_cleanup_level (type)
|
||||
tree type;
|
||||
{
|
||||
if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
|
||||
if (type != error_mark_node
|
||||
&& TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
|
||||
&& current_binding_level->more_cleanups_ok == 0)
|
||||
{
|
||||
keep_next_level (2);
|
||||
@ -1286,9 +1288,13 @@ add_decl_to_level (decl, b)
|
||||
b->names = decl;
|
||||
b->names_size++;
|
||||
|
||||
/* If appropriate, add decl to separate list of statics */
|
||||
/* If appropriate, add decl to separate list of statics. We
|
||||
include extern variables because they might turn out to be
|
||||
static later. It's OK for this list to contain a few false
|
||||
positives. */
|
||||
if (b->namespace_p)
|
||||
if ((TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
|
||||
if ((TREE_CODE (decl) == VAR_DECL
|
||||
&& (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
|
||||
|| (TREE_CODE (decl) == FUNCTION_DECL
|
||||
&& (!TREE_PUBLIC (decl) || DECL_DECLARED_INLINE_P (decl))))
|
||||
VARRAY_PUSH_TREE (b->static_decls, decl);
|
||||
@ -4935,10 +4941,10 @@ push_overloaded_decl (decl, flags)
|
||||
}
|
||||
|
||||
if (old || TREE_CODE (decl) == TEMPLATE_DECL
|
||||
/* If it's a using declaration, we always need to build an OVERLOAD,
|
||||
because it's the only way to remember that the declaration comes
|
||||
from 'using', and have the lookup behave correctly. */
|
||||
|| (flags & PUSH_USING))
|
||||
/* If it's a using declaration, we always need to build an OVERLOAD,
|
||||
because it's the only way to remember that the declaration comes
|
||||
from 'using', and have the lookup behave correctly. */
|
||||
|| (flags & PUSH_USING))
|
||||
{
|
||||
if (old && TREE_CODE (old) != OVERLOAD)
|
||||
new_binding = ovl_cons (decl, ovl_cons (old, NULL_TREE));
|
||||
@ -7868,8 +7874,6 @@ start_decl_1 (decl)
|
||||
if (type == error_mark_node)
|
||||
return;
|
||||
|
||||
maybe_push_cleanup_level (type);
|
||||
|
||||
if (initialized)
|
||||
/* Is it valid for this decl to have an initializer at all?
|
||||
If not, set INITIALIZED to zero, which will indirectly
|
||||
@ -7925,6 +7929,14 @@ start_decl_1 (decl)
|
||||
|
||||
if (! initialized)
|
||||
DECL_INITIAL (decl) = NULL_TREE;
|
||||
|
||||
/* Create a new scope to hold this declaration if necessary.
|
||||
Whether or not a new scope is necessary cannot be determined
|
||||
until after the type has been completed; if the type is a
|
||||
specialization of a class template it is not until after
|
||||
instantiation has occurred that TYPE_HAS_NONTRIVIAL_DESTRUCTOR
|
||||
will be set correctly. */
|
||||
maybe_push_cleanup_level (type);
|
||||
}
|
||||
|
||||
/* Handle initialization of references. DECL, TYPE, and INIT have the
|
||||
@ -8200,6 +8212,60 @@ next_initializable_field (tree field)
|
||||
return field;
|
||||
}
|
||||
|
||||
/* Subroutine of reshape_init. Reshape the constructor for an array. INITP
|
||||
is the pointer to the old constructor list (to the CONSTRUCTOR_ELTS of
|
||||
the CONSTRUCTOR we are processing), while NEW_INIT is the CONSTRUCTOR we
|
||||
are building.
|
||||
ELT_TYPE is the element type of the array. MAX_INDEX is an INTEGER_CST
|
||||
representing the size of the array minus one (the maximum index), or
|
||||
NULL_TREE if the array was declared without specifying the size. */
|
||||
|
||||
static bool
|
||||
reshape_init_array (tree elt_type, tree max_index,
|
||||
tree *initp, tree new_init)
|
||||
{
|
||||
bool sized_array_p = (max_index != NULL_TREE);
|
||||
HOST_WIDE_INT max_index_cst = 0;
|
||||
HOST_WIDE_INT index;
|
||||
|
||||
if (sized_array_p)
|
||||
/* HWI is either 32bit or 64bit, so it must be enough to represent the
|
||||
array size. */
|
||||
max_index_cst = tree_low_cst (max_index, 1);
|
||||
|
||||
/* Loop until there are no more initializers. */
|
||||
for (index = 0;
|
||||
*initp && (!sized_array_p || index <= max_index_cst);
|
||||
++index)
|
||||
{
|
||||
tree element_init;
|
||||
tree designated_index;
|
||||
|
||||
element_init = reshape_init (elt_type, initp);
|
||||
if (element_init == error_mark_node)
|
||||
return false;
|
||||
TREE_CHAIN (element_init) = CONSTRUCTOR_ELTS (new_init);
|
||||
CONSTRUCTOR_ELTS (new_init) = element_init;
|
||||
designated_index = TREE_PURPOSE (element_init);
|
||||
if (designated_index)
|
||||
{
|
||||
if (TREE_CODE (designated_index) != INTEGER_CST)
|
||||
abort ();
|
||||
if (sized_array_p
|
||||
&& tree_int_cst_lt (max_index, designated_index))
|
||||
{
|
||||
error ("Designated initializer `%E' larger than array "
|
||||
"size", designated_index);
|
||||
TREE_PURPOSE (element_init) = NULL_TREE;
|
||||
}
|
||||
else
|
||||
index = tree_low_cst (designated_index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Undo the brace-elision allowed by [dcl.init.aggr] in a
|
||||
brace-enclosed aggregate initializer.
|
||||
|
||||
@ -8375,28 +8441,15 @@ reshape_init (tree type, tree *initp)
|
||||
}
|
||||
else if ((TREE_CODE (type) == ARRAY_TYPE)|| (TREE_CODE (type) == VECTOR_TYPE))
|
||||
{
|
||||
tree index;
|
||||
tree max_index;
|
||||
|
||||
/* If the bound of the array is known, take no more initializers
|
||||
than are allowed. */
|
||||
max_index = ((TYPE_DOMAIN (type) && (TREE_CODE (type) == ARRAY_TYPE))
|
||||
? array_type_nelts (type) : NULL_TREE);
|
||||
/* Loop through the array elements, gathering initializers. */
|
||||
for (index = size_zero_node;
|
||||
*initp && (!max_index || !tree_int_cst_lt (max_index, index));
|
||||
index = size_binop (PLUS_EXPR, index, size_one_node))
|
||||
{
|
||||
tree element_init;
|
||||
|
||||
element_init = reshape_init (TREE_TYPE (type), initp);
|
||||
if (element_init == error_mark_node)
|
||||
return error_mark_node;
|
||||
TREE_CHAIN (element_init) = CONSTRUCTOR_ELTS (new_init);
|
||||
CONSTRUCTOR_ELTS (new_init) = element_init;
|
||||
if (TREE_PURPOSE (element_init))
|
||||
index = TREE_PURPOSE (element_init);
|
||||
}
|
||||
if (!reshape_init_array (TREE_TYPE (type), max_index,
|
||||
initp, new_init))
|
||||
return error_mark_node;
|
||||
}
|
||||
else
|
||||
abort ();
|
||||
@ -8428,6 +8481,7 @@ static tree
|
||||
check_initializer (tree decl, tree init, int flags, tree *cleanup)
|
||||
{
|
||||
tree type = TREE_TYPE (decl);
|
||||
tree init_code = NULL;
|
||||
|
||||
/* If `start_decl' didn't like having an initialization, ignore it now. */
|
||||
if (init != NULL_TREE && DECL_INITIAL (decl) == NULL_TREE)
|
||||
@ -8538,7 +8592,10 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
|
||||
{
|
||||
dont_use_constructor:
|
||||
if (TREE_CODE (init) != TREE_VEC)
|
||||
init = store_init_value (decl, init);
|
||||
{
|
||||
init_code = store_init_value (decl, init);
|
||||
init = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (DECL_EXTERNAL (decl))
|
||||
@ -8561,9 +8618,9 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
|
||||
check_for_uninitialized_const_var (decl);
|
||||
|
||||
if (init && init != error_mark_node)
|
||||
init = build (INIT_EXPR, type, decl, init);
|
||||
init_code = build (INIT_EXPR, type, decl, init);
|
||||
|
||||
return init;
|
||||
return init_code;
|
||||
}
|
||||
|
||||
/* If DECL is not a local variable, give it RTL. */
|
||||
@ -8879,16 +8936,17 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
|
||||
if (TREE_CODE (decl) != FUNCTION_DECL)
|
||||
ttype = target_type (type);
|
||||
|
||||
if (! DECL_EXTERNAL (decl) && TREE_READONLY (decl)
|
||||
&& (TYPE_NEEDS_CONSTRUCTING (type)
|
||||
|| TREE_CODE (type) == REFERENCE_TYPE))
|
||||
|
||||
/* Currently, GNU C++ puts constants in text space, making them
|
||||
impossible to initialize. In the future, one would hope for
|
||||
an operating system which understood the difference between
|
||||
initialization and the running of a program. */
|
||||
if (! DECL_EXTERNAL (decl) && TREE_READONLY (decl))
|
||||
{
|
||||
/* Currently, GNU C++ puts constants in text space, making them
|
||||
impossible to initialize. In the future, one would hope for
|
||||
an operating system which understood the difference between
|
||||
initialization and the running of a program. */
|
||||
was_readonly = 1;
|
||||
TREE_READONLY (decl) = 0;
|
||||
if (TYPE_NEEDS_CONSTRUCTING (type)
|
||||
|| TREE_CODE (type) == REFERENCE_TYPE)
|
||||
TREE_READONLY (decl) = 0;
|
||||
}
|
||||
|
||||
if (TREE_CODE (decl) == FIELD_DECL && asmspec)
|
||||
@ -12697,8 +12755,6 @@ require_complete_types_for_parms (parms)
|
||||
layout_decl (parms, 0);
|
||||
DECL_ARG_TYPE (parms) = type_passed_as (TREE_TYPE (parms));
|
||||
}
|
||||
else
|
||||
TREE_TYPE (parms) = error_mark_node;
|
||||
}
|
||||
}
|
||||
|
||||
@ -13686,25 +13742,7 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes,
|
||||
if (code == ENUMERAL_TYPE)
|
||||
{
|
||||
error ("use of enum `%#D' without previous declaration", name);
|
||||
|
||||
ref = make_node (ENUMERAL_TYPE);
|
||||
|
||||
/* Give the type a default layout like unsigned int
|
||||
to avoid crashing if it does not get defined. */
|
||||
TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node);
|
||||
TYPE_ALIGN (ref) = TYPE_ALIGN (unsigned_type_node);
|
||||
TYPE_USER_ALIGN (ref) = 0;
|
||||
TREE_UNSIGNED (ref) = 1;
|
||||
TYPE_PRECISION (ref) = TYPE_PRECISION (unsigned_type_node);
|
||||
TYPE_MIN_VALUE (ref) = TYPE_MIN_VALUE (unsigned_type_node);
|
||||
TYPE_MAX_VALUE (ref) = TYPE_MAX_VALUE (unsigned_type_node);
|
||||
|
||||
/* Enable us to recognize when a type is created in class context.
|
||||
To do nested classes correctly, this should probably be cleared
|
||||
out when we leave this classes scope. Currently this in only
|
||||
done in `start_enum'. */
|
||||
|
||||
pushtag (name, ref, globalize);
|
||||
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
7
gnu/dist/gcc/gcc/cp/decl2.c
vendored
7
gnu/dist/gcc/gcc/cp/decl2.c
vendored
@ -1851,7 +1851,11 @@ maybe_emit_vtables (tree ctype)
|
||||
import_export_vtable (vtbl, ctype, 1);
|
||||
mark_vtable_entries (vtbl);
|
||||
if (TREE_TYPE (DECL_INITIAL (vtbl)) == 0)
|
||||
store_init_value (vtbl, DECL_INITIAL (vtbl));
|
||||
{
|
||||
/* It had better be all done at compile-time. */
|
||||
if (store_init_value (vtbl, DECL_INITIAL (vtbl)))
|
||||
abort ();
|
||||
}
|
||||
|
||||
if (write_symbols == DWARF_DEBUG || write_symbols == DWARF2_DEBUG)
|
||||
{
|
||||
@ -4875,6 +4879,7 @@ mark_used (decl)
|
||||
generate its body to find that out. */
|
||||
|| TREE_NOTHROW (decl)
|
||||
|| !cfun
|
||||
|| !current_function_decl
|
||||
/* If we already know the current function can't throw,
|
||||
then we don't need to work hard to prove it. */
|
||||
|| TREE_NOTHROW (current_function_decl)
|
||||
|
4
gnu/dist/gcc/gcc/cp/error.c
vendored
4
gnu/dist/gcc/gcc/cp/error.c
vendored
@ -421,6 +421,7 @@ dump_type (t, flags)
|
||||
case BOUND_TEMPLATE_TEMPLATE_PARM:
|
||||
{
|
||||
tree args = TYPE_TI_ARGS (t);
|
||||
dump_qualifiers (t, after);
|
||||
print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (t));
|
||||
print_template_argument_list_start (scratch_buffer);
|
||||
dump_template_argument_list (args, flags);
|
||||
@ -1723,6 +1724,7 @@ dump_expr (t, flags)
|
||||
case CEIL_DIV_EXPR:
|
||||
case FLOOR_DIV_EXPR:
|
||||
case ROUND_DIV_EXPR:
|
||||
case RDIV_EXPR:
|
||||
dump_binary_op ("/", t, flags);
|
||||
break;
|
||||
|
||||
@ -2069,7 +2071,7 @@ dump_expr (t, flags)
|
||||
break;
|
||||
|
||||
case BASELINK:
|
||||
print_tree_identifier (scratch_buffer, DECL_NAME (get_first_fn (t)));
|
||||
dump_expr (get_first_fn (t), flags & ~TFF_EXPR_IN_PARENS);
|
||||
break;
|
||||
|
||||
case TREE_LIST:
|
||||
|
15
gnu/dist/gcc/gcc/cp/except.c
vendored
15
gnu/dist/gcc/gcc/cp/except.c
vendored
@ -53,6 +53,7 @@ static bool is_admissible_throw_operand PARAMS ((tree));
|
||||
static int can_convert_eh PARAMS ((tree, tree));
|
||||
static void check_handlers_1 PARAMS ((tree, tree));
|
||||
static tree cp_protect_cleanup_actions PARAMS ((void));
|
||||
static tree do_free_exception PARAMS ((tree));
|
||||
|
||||
/* Sets up all the global eh stuff that needs to be initialized at the
|
||||
start of compilation. */
|
||||
@ -511,9 +512,7 @@ do_allocate_exception (type)
|
||||
NULL_TREE));
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Call __cxa_free_exception from a cleanup. This is never invoked
|
||||
directly, but see the comment for stabilize_throw_expr. */
|
||||
/* Call __cxa_free_exception from a cleanup. */
|
||||
|
||||
static tree
|
||||
do_free_exception (ptr)
|
||||
@ -533,7 +532,6 @@ do_free_exception (ptr)
|
||||
|
||||
return build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR.
|
||||
Called from build_throw via walk_tree_without_duplicates. */
|
||||
@ -669,6 +667,7 @@ build_throw (exp)
|
||||
tree object, ptr;
|
||||
tree tmp;
|
||||
tree temp_expr, allocate_expr;
|
||||
bool elided;
|
||||
|
||||
fn = get_identifier ("__cxa_throw");
|
||||
if (IDENTIFIER_GLOBAL_VALUE (fn))
|
||||
@ -723,6 +722,8 @@ build_throw (exp)
|
||||
object = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (exp)), ptr);
|
||||
object = build_indirect_ref (object, NULL);
|
||||
|
||||
elided = (TREE_CODE (exp) == TARGET_EXPR);
|
||||
|
||||
/* And initialize the exception object. */
|
||||
exp = build_init (object, exp, LOOKUP_ONLYCONVERTING);
|
||||
if (exp == error_mark_node)
|
||||
@ -731,7 +732,11 @@ build_throw (exp)
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
exp = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (exp), exp);
|
||||
if (elided)
|
||||
exp = build (TRY_CATCH_EXPR, void_type_node, exp,
|
||||
do_free_exception (ptr));
|
||||
else
|
||||
exp = build1 (MUST_NOT_THROW_EXPR, void_type_node, exp);
|
||||
/* Prepend the allocation. */
|
||||
exp = build (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp);
|
||||
if (temp_expr != void_zero_node)
|
||||
|
34
gnu/dist/gcc/gcc/cp/init.c
vendored
34
gnu/dist/gcc/gcc/cp/init.c
vendored
@ -32,6 +32,7 @@ Boston, MA 02111-1307, USA. */
|
||||
#include "output.h"
|
||||
#include "except.h"
|
||||
#include "toplev.h"
|
||||
#include "diagnostic.h"
|
||||
#include "ggc.h"
|
||||
|
||||
static void construct_virtual_base (tree, tree);
|
||||
@ -234,7 +235,6 @@ build_zero_init (tree type, tree nelts, bool static_storage_p)
|
||||
}
|
||||
else if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
{
|
||||
tree index;
|
||||
tree max_index;
|
||||
tree inits;
|
||||
|
||||
@ -248,15 +248,17 @@ build_zero_init (tree type, tree nelts, bool static_storage_p)
|
||||
/* A zero-sized array, which is accepted as an extension, will
|
||||
have an upper bound of -1. */
|
||||
if (!tree_int_cst_equal (max_index, integer_minus_one_node))
|
||||
for (index = size_zero_node;
|
||||
!tree_int_cst_lt (max_index, index);
|
||||
index = size_binop (PLUS_EXPR, index, size_one_node))
|
||||
inits = tree_cons (index,
|
||||
build_zero_init (TREE_TYPE (type),
|
||||
/*nelts=*/NULL_TREE,
|
||||
static_storage_p),
|
||||
inits);
|
||||
CONSTRUCTOR_ELTS (init) = nreverse (inits);
|
||||
{
|
||||
tree elt_init = build_zero_init (TREE_TYPE (type),
|
||||
/*nelts=*/NULL_TREE,
|
||||
static_storage_p);
|
||||
tree range = build (RANGE_EXPR,
|
||||
sizetype, size_zero_node, max_index);
|
||||
|
||||
inits = tree_cons (range, elt_init, inits);
|
||||
}
|
||||
|
||||
CONSTRUCTOR_ELTS (init) = nreverse (inits);
|
||||
}
|
||||
else if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
;
|
||||
@ -390,6 +392,9 @@ perform_member_init (tree member, tree init)
|
||||
/* member traversal: note it leaves init NULL */
|
||||
else if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
pedwarn ("uninitialized reference member `%D'", member);
|
||||
else if (CP_TYPE_CONST_P (type))
|
||||
pedwarn ("uninitialized member '%D' with 'const' type '%T'",
|
||||
member, type);
|
||||
}
|
||||
else if (TREE_CODE (init) == TREE_LIST)
|
||||
{
|
||||
@ -1286,8 +1291,9 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, flags)
|
||||
/* If store_init_value returns NULL_TREE, the INIT has been
|
||||
record in the DECL_INITIAL for EXP. That means there's
|
||||
nothing more we have to do. */
|
||||
if (store_init_value (exp, init))
|
||||
finish_expr_stmt (build (INIT_EXPR, type, exp, init));
|
||||
init = store_init_value (exp, init);
|
||||
if (init)
|
||||
finish_expr_stmt (init);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3118,8 +3124,8 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
|
||||
warning ("possible problem detected in invocation of "
|
||||
"delete operator:");
|
||||
cxx_incomplete_type_diagnostic (addr, type, 1);
|
||||
inform ("neither the destructor nor the class-specific "
|
||||
"operator delete will be called, even if they are "
|
||||
inform ("neither the destructor nor the class-specific "
|
||||
"operator delete will be called, even if they are "
|
||||
"declared when the class is defined.");
|
||||
complete_p = false;
|
||||
}
|
||||
|
26
gnu/dist/gcc/gcc/cp/pt.c
vendored
26
gnu/dist/gcc/gcc/cp/pt.c
vendored
@ -960,7 +960,7 @@ register_specialization (spec, tmpl, args)
|
||||
the default argument expression is not substituted for in an
|
||||
instantiation unless and until it is actually needed. */
|
||||
return spec;
|
||||
|
||||
|
||||
/* There should be as many levels of arguments as there are
|
||||
levels of parameters. */
|
||||
my_friendly_assert (TMPL_ARGS_DEPTH (args)
|
||||
@ -1155,6 +1155,7 @@ determine_specialization (template_id, decl, targs_out,
|
||||
if (TREE_CODE (fn) == TEMPLATE_DECL)
|
||||
{
|
||||
tree decl_arg_types;
|
||||
tree fn_arg_types;
|
||||
|
||||
/* DECL might be a specialization of FN. */
|
||||
|
||||
@ -1171,8 +1172,16 @@ determine_specialization (template_id, decl, targs_out,
|
||||
The specialization f<int> is invalid but is not caught
|
||||
by get_bindings below. */
|
||||
|
||||
if (list_length (TYPE_ARG_TYPES (TREE_TYPE (fn)))
|
||||
!= list_length (decl_arg_types))
|
||||
fn_arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
|
||||
if (list_length (fn_arg_types) != list_length (decl_arg_types))
|
||||
continue;
|
||||
|
||||
/* For a non-static member function, we need to make sure that
|
||||
the const qualification is the same. This can be done by
|
||||
checking the 'this' in the argument list. */
|
||||
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
|
||||
&& !same_type_p (TREE_VALUE (fn_arg_types),
|
||||
TREE_VALUE (decl_arg_types)))
|
||||
continue;
|
||||
|
||||
/* See whether this function might be a specialization of this
|
||||
@ -2918,6 +2927,13 @@ push_template_decl_real (decl, is_friend)
|
||||
}
|
||||
}
|
||||
|
||||
/* The DECL_TI_ARGS of DECL contains full set of arguments refering
|
||||
back to its most general template. If TMPL is a specialization,
|
||||
ARGS may only have the innermost set of arguments. Add the missing
|
||||
argument levels if necessary. */
|
||||
if (DECL_TEMPLATE_INFO (tmpl))
|
||||
args = add_outermost_template_args (DECL_TI_ARGS (tmpl), args);
|
||||
|
||||
info = tree_cons (tmpl, args, NULL_TREE);
|
||||
|
||||
if (DECL_IMPLICIT_TYPEDEF_P (decl))
|
||||
@ -5889,6 +5905,10 @@ tsubst_default_argument (fn, type, arg)
|
||||
|
||||
/* FN is already the desired FUNCTION_DECL. */
|
||||
push_access_scope (fn);
|
||||
/* The default argument expression should not be considered to be
|
||||
within the scope of FN. Since push_access_scope sets
|
||||
current_function_decl, we must explicitly clear it here. */
|
||||
current_function_decl = NULL_TREE;
|
||||
|
||||
arg = tsubst_expr (arg, DECL_TI_ARGS (fn),
|
||||
tf_error | tf_warning, NULL_TREE);
|
||||
|
2
gnu/dist/gcc/gcc/cp/rtti.c
vendored
2
gnu/dist/gcc/gcc/cp/rtti.c
vendored
@ -761,7 +761,7 @@ tinfo_base_init (desc, target)
|
||||
TREE_STATIC (name_decl) = 1;
|
||||
DECL_EXTERNAL (name_decl) = 0;
|
||||
TREE_PUBLIC (name_decl) = 1;
|
||||
comdat_linkage (name_decl);
|
||||
import_export_tinfo (name_decl, target, typeinfo_in_lib_p (target));
|
||||
/* External name of the string containing the type's name has a
|
||||
special name. */
|
||||
SET_DECL_ASSEMBLER_NAME (name_decl,
|
||||
|
23
gnu/dist/gcc/gcc/cp/semantics.c
vendored
23
gnu/dist/gcc/gcc/cp/semantics.c
vendored
@ -2457,7 +2457,28 @@ nullify_returns_r (tp, walk_subtrees, data)
|
||||
else if (TREE_CODE (*tp) == CLEANUP_STMT
|
||||
&& CLEANUP_DECL (*tp) == nrv)
|
||||
CLEANUP_EH_ONLY (*tp) = 1;
|
||||
|
||||
/* Replace the DECL_STMT for the NRV with an initialization of the
|
||||
RESULT_DECL, if needed. */
|
||||
else if (TREE_CODE (*tp) == DECL_STMT
|
||||
&& DECL_STMT_DECL (*tp) == nrv)
|
||||
{
|
||||
tree init;
|
||||
if (DECL_INITIAL (nrv)
|
||||
&& DECL_INITIAL (nrv) != error_mark_node)
|
||||
{
|
||||
init = build (INIT_EXPR, void_type_node,
|
||||
DECL_RESULT (current_function_decl),
|
||||
DECL_INITIAL (nrv));
|
||||
DECL_INITIAL (nrv) = error_mark_node;
|
||||
}
|
||||
else
|
||||
init = NULL_TREE;
|
||||
init = build_stmt (EXPR_STMT, init);
|
||||
TREE_CHAIN (init) = TREE_CHAIN (*tp);
|
||||
STMT_LINENO (init) = STMT_LINENO (*tp);
|
||||
*tp = init;
|
||||
}
|
||||
|
||||
/* Keep iterating. */
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
2
gnu/dist/gcc/gcc/cp/typeck.c
vendored
2
gnu/dist/gcc/gcc/cp/typeck.c
vendored
@ -5937,8 +5937,6 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
|
||||
if (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
rhs = dubious_conversion_warnings (type, rhs, errtype, fndecl, parmnum);
|
||||
|
||||
/* The RHS of an assignment cannot have void type. */
|
||||
if (coder == VOID_TYPE)
|
||||
{
|
||||
|
112
gnu/dist/gcc/gcc/cp/typeck2.c
vendored
112
gnu/dist/gcc/gcc/cp/typeck2.c
vendored
@ -296,6 +296,109 @@ cxx_incomplete_type_error (value, type)
|
||||
}
|
||||
|
||||
|
||||
/* The recursive part of split_nonconstant_init. DEST is an lvalue
|
||||
expression to which INIT should be assigned. INIT is a CONSTRUCTOR.
|
||||
PCODE is a pointer to the tail of a chain of statements being emitted.
|
||||
The return value is the new tail of that chain after new statements
|
||||
are generated. */
|
||||
|
||||
static tree *
|
||||
split_nonconstant_init_1 (tree dest, tree init, tree *pcode)
|
||||
{
|
||||
tree *pelt, elt, type = TREE_TYPE (dest);
|
||||
tree sub, code, inner_type = NULL;
|
||||
bool array_type_p = false;
|
||||
|
||||
pelt = &CONSTRUCTOR_ELTS (init);
|
||||
switch (TREE_CODE (type))
|
||||
{
|
||||
case ARRAY_TYPE:
|
||||
inner_type = TREE_TYPE (type);
|
||||
array_type_p = true;
|
||||
/* FALLTHRU */
|
||||
|
||||
case RECORD_TYPE:
|
||||
case UNION_TYPE:
|
||||
case QUAL_UNION_TYPE:
|
||||
while ((elt = *pelt))
|
||||
{
|
||||
tree field_index = TREE_PURPOSE (elt);
|
||||
tree value = TREE_VALUE (elt);
|
||||
|
||||
if (!array_type_p)
|
||||
inner_type = TREE_TYPE (field_index);
|
||||
|
||||
if (TREE_CODE (value) == CONSTRUCTOR)
|
||||
{
|
||||
if (array_type_p)
|
||||
sub = build (ARRAY_REF, inner_type, dest, field_index);
|
||||
else
|
||||
sub = build (COMPONENT_REF, inner_type, dest, field_index);
|
||||
|
||||
pcode = split_nonconstant_init_1 (sub, value, pcode);
|
||||
}
|
||||
else if (!initializer_constant_valid_p (value, inner_type))
|
||||
{
|
||||
*pelt = TREE_CHAIN (elt);
|
||||
|
||||
if (array_type_p)
|
||||
sub = build (ARRAY_REF, inner_type, dest, field_index);
|
||||
else
|
||||
sub = build (COMPONENT_REF, inner_type, dest, field_index);
|
||||
|
||||
code = build (MODIFY_EXPR, inner_type, sub, value);
|
||||
code = build_stmt (EXPR_STMT, code);
|
||||
|
||||
*pcode = code;
|
||||
pcode = &TREE_CHAIN (code);
|
||||
continue;
|
||||
}
|
||||
pelt = &TREE_CHAIN (elt);
|
||||
}
|
||||
break;
|
||||
|
||||
case VECTOR_TYPE:
|
||||
if (!initializer_constant_valid_p (init, type))
|
||||
{
|
||||
CONSTRUCTOR_ELTS (init) = NULL;
|
||||
code = build (MODIFY_EXPR, type, dest, init);
|
||||
code = build_stmt (EXPR_STMT, code);
|
||||
pcode = &TREE_CHAIN (code);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
return pcode;
|
||||
}
|
||||
|
||||
/* A subroutine of store_init_value. Splits non-constant static
|
||||
initializer INIT into a constant part and generates code to
|
||||
perform the non-constant part of the initialization to DEST.
|
||||
Returns the code for the runtime init. */
|
||||
|
||||
static tree
|
||||
split_nonconstant_init (tree dest, tree init)
|
||||
{
|
||||
tree code;
|
||||
|
||||
if (TREE_CODE (init) == CONSTRUCTOR)
|
||||
{
|
||||
code = build_stmt (COMPOUND_STMT, NULL_TREE);
|
||||
split_nonconstant_init_1 (dest, init, &COMPOUND_BODY (code));
|
||||
code = build1 (STMT_EXPR, void_type_node, code);
|
||||
TREE_SIDE_EFFECTS (code) = 1;
|
||||
DECL_INITIAL (dest) = init;
|
||||
TREE_READONLY (dest) = 0;
|
||||
}
|
||||
else
|
||||
code = build (INIT_EXPR, TREE_TYPE (dest), dest, init);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
/* Perform appropriate conversions on the initial value of a variable,
|
||||
store it in the declaration DECL,
|
||||
and print any error messages that are appropriate.
|
||||
@ -311,9 +414,8 @@ cxx_incomplete_type_error (value, type)
|
||||
into a CONSTRUCTOR and use standard initialization techniques.
|
||||
Perhaps a warning should be generated?
|
||||
|
||||
Returns value of initializer if initialization could not be
|
||||
performed for static variable. In that case, caller must do
|
||||
the storing. */
|
||||
Returns code to be executed if initialization could not be performed
|
||||
for static variable. In that case, caller must emit the code. */
|
||||
|
||||
tree
|
||||
store_init_value (decl, init)
|
||||
@ -385,11 +487,11 @@ store_init_value (decl, init)
|
||||
constructing never make it into DECL_INITIAL, and passes 'init' to
|
||||
build_aggr_init without checking DECL_INITIAL. So just return. */
|
||||
else if (TYPE_NEEDS_CONSTRUCTING (type))
|
||||
return value;
|
||||
return build (INIT_EXPR, type, decl, value);
|
||||
else if (TREE_STATIC (decl)
|
||||
&& (! TREE_CONSTANT (value)
|
||||
|| ! initializer_constant_valid_p (value, TREE_TYPE (value))))
|
||||
return value;
|
||||
return split_nonconstant_init (decl, value);
|
||||
|
||||
/* Store the VALUE in DECL_INITIAL. If we're building a
|
||||
statement-tree we will actually expand the initialization later
|
||||
|
3
gnu/dist/gcc/gcc/cpplib.c
vendored
3
gnu/dist/gcc/gcc/cpplib.c
vendored
@ -1122,9 +1122,6 @@ do_pragma (pfile)
|
||||
if (pfile->cb.line_change)
|
||||
(*pfile->cb.line_change) (pfile, pragma_token, false);
|
||||
(*p->u.handler) (pfile);
|
||||
if (pfile->cb.line_change)
|
||||
(*pfile->cb.line_change) (pfile, pfile->cur_token, false);
|
||||
|
||||
}
|
||||
else if (pfile->cb.def_pragma)
|
||||
{
|
||||
|
389
gnu/dist/gcc/gcc/cse.c
vendored
389
gnu/dist/gcc/gcc/cse.c
vendored
@ -1,6 +1,6 @@
|
||||
/* Common subexpression elimination for GNU compiler.
|
||||
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998
|
||||
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
@ -38,6 +38,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "output.h"
|
||||
#include "ggc.h"
|
||||
#include "timevar.h"
|
||||
#include "target.h"
|
||||
|
||||
/* The basic idea of common subexpression elimination is to go
|
||||
through the code, keeping a record of expressions that would
|
||||
@ -701,6 +702,9 @@ static void flush_hash_table PARAMS ((void));
|
||||
static bool insn_live_p PARAMS ((rtx, int *));
|
||||
static bool set_live_p PARAMS ((rtx, rtx, int *));
|
||||
static bool dead_libcall_p PARAMS ((rtx, int *));
|
||||
static int cse_change_cc_mode PARAMS ((rtx *, void *));
|
||||
static void cse_change_cc_mode_insns PARAMS ((rtx, rtx, rtx));
|
||||
static enum machine_mode cse_cc_succs PARAMS ((basic_block, rtx, rtx, int));
|
||||
|
||||
/* Dump the expressions in the equivalence class indicated by CLASSP.
|
||||
This function is used only for debugging. */
|
||||
@ -3850,6 +3854,23 @@ fold_rtx (x, insn)
|
||||
|| (new_cost == old_cost && CONSTANT_P (XEXP (x, i))))
|
||||
break;
|
||||
|
||||
/* It's not safe to substitute the operand of a conversion
|
||||
operator with a constant, as the conversion's identity
|
||||
depends upon the mode of it's operand. This optimization
|
||||
is handled by the call to simplify_unary_operation. */
|
||||
if (GET_RTX_CLASS (code) == '1'
|
||||
&& GET_MODE (replacements[j]) != mode_arg0
|
||||
&& (code == ZERO_EXTEND
|
||||
|| code == SIGN_EXTEND
|
||||
|| code == TRUNCATE
|
||||
|| code == FLOAT_TRUNCATE
|
||||
|| code == FLOAT_EXTEND
|
||||
|| code == FLOAT
|
||||
|| code == FIX
|
||||
|| code == UNSIGNED_FLOAT
|
||||
|| code == UNSIGNED_FIX))
|
||||
continue;
|
||||
|
||||
if (validate_change (insn, &XEXP (x, i), replacements[j], 0))
|
||||
break;
|
||||
|
||||
@ -7774,3 +7795,369 @@ delete_trivially_dead_insns (insns, nreg)
|
||||
timevar_pop (TV_DELETE_TRIVIALLY_DEAD);
|
||||
return ndead;
|
||||
}
|
||||
|
||||
/* This function is called via for_each_rtx. The argument, NEWREG, is
|
||||
a condition code register with the desired mode. If we are looking
|
||||
at the same register in a different mode, replace it with
|
||||
NEWREG. */
|
||||
|
||||
static int
|
||||
cse_change_cc_mode (loc, data)
|
||||
rtx *loc;
|
||||
void *data;
|
||||
{
|
||||
rtx newreg = (rtx) data;
|
||||
|
||||
if (*loc
|
||||
&& GET_CODE (*loc) == REG
|
||||
&& REGNO (*loc) == REGNO (newreg)
|
||||
&& GET_MODE (*loc) != GET_MODE (newreg))
|
||||
{
|
||||
*loc = newreg;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Change the mode of any reference to the register REGNO (NEWREG) to
|
||||
GET_MODE (NEWREG), starting at START. Stop before END. Stop at
|
||||
any instruction which modifies NEWREG. */
|
||||
|
||||
static void
|
||||
cse_change_cc_mode_insns (start, end, newreg)
|
||||
rtx start;
|
||||
rtx end;
|
||||
rtx newreg;
|
||||
{
|
||||
rtx insn;
|
||||
|
||||
for (insn = start; insn != end; insn = NEXT_INSN (insn))
|
||||
{
|
||||
if (! INSN_P (insn))
|
||||
continue;
|
||||
|
||||
if (reg_set_p (newreg, insn))
|
||||
return;
|
||||
|
||||
for_each_rtx (&PATTERN (insn), cse_change_cc_mode, newreg);
|
||||
for_each_rtx (®_NOTES (insn), cse_change_cc_mode, newreg);
|
||||
}
|
||||
}
|
||||
|
||||
/* BB is a basic block which finishes with CC_REG as a condition code
|
||||
register which is set to CC_SRC. Look through the successors of BB
|
||||
to find blocks which have a single predecessor (i.e., this one),
|
||||
and look through those blocks for an assignment to CC_REG which is
|
||||
equivalent to CC_SRC. CAN_CHANGE_MODE indicates whether we are
|
||||
permitted to change the mode of CC_SRC to a compatible mode. This
|
||||
returns VOIDmode if no equivalent assignments were found.
|
||||
Otherwise it returns the mode which CC_SRC should wind up with.
|
||||
|
||||
The main complexity in this function is handling the mode issues.
|
||||
We may have more than one duplicate which we can eliminate, and we
|
||||
try to find a mode which will work for multiple duplicates. */
|
||||
|
||||
static enum machine_mode
|
||||
cse_cc_succs (bb, cc_reg, cc_src, can_change_mode)
|
||||
basic_block bb;
|
||||
rtx cc_reg;
|
||||
rtx cc_src;
|
||||
int can_change_mode;
|
||||
{
|
||||
bool found_equiv;
|
||||
enum machine_mode mode;
|
||||
unsigned int insn_count;
|
||||
edge e;
|
||||
rtx insns[2];
|
||||
enum machine_mode modes[2];
|
||||
rtx last_insns[2];
|
||||
unsigned int i;
|
||||
rtx newreg;
|
||||
|
||||
/* We expect to have two successors. Look at both before picking
|
||||
the final mode for the comparison. If we have more successors
|
||||
(i.e., some sort of table jump, although that seems unlikely),
|
||||
then we require all beyond the first two to use the same
|
||||
mode. */
|
||||
|
||||
found_equiv = false;
|
||||
mode = GET_MODE (cc_src);
|
||||
insn_count = 0;
|
||||
for (e = bb->succ; e; e = e->succ_next)
|
||||
{
|
||||
rtx insn;
|
||||
rtx end;
|
||||
|
||||
if (e->flags & EDGE_COMPLEX)
|
||||
continue;
|
||||
|
||||
if (! e->dest->pred
|
||||
|| e->dest->pred->pred_next
|
||||
|| e->dest == EXIT_BLOCK_PTR)
|
||||
continue;
|
||||
|
||||
end = NEXT_INSN (e->dest->end);
|
||||
for (insn = e->dest->head; insn != end; insn = NEXT_INSN (insn))
|
||||
{
|
||||
rtx set;
|
||||
|
||||
if (! INSN_P (insn))
|
||||
continue;
|
||||
|
||||
/* If CC_SRC is modified, we have to stop looking for
|
||||
something which uses it. */
|
||||
if (modified_in_p (cc_src, insn))
|
||||
break;
|
||||
|
||||
/* Check whether INSN sets CC_REG to CC_SRC. */
|
||||
set = single_set (insn);
|
||||
if (set
|
||||
&& GET_CODE (SET_DEST (set)) == REG
|
||||
&& REGNO (SET_DEST (set)) == REGNO (cc_reg))
|
||||
{
|
||||
bool found;
|
||||
enum machine_mode set_mode;
|
||||
enum machine_mode comp_mode;
|
||||
|
||||
found = false;
|
||||
set_mode = GET_MODE (SET_SRC (set));
|
||||
comp_mode = set_mode;
|
||||
if (rtx_equal_p (cc_src, SET_SRC (set)))
|
||||
found = true;
|
||||
else if (GET_CODE (cc_src) == COMPARE
|
||||
&& GET_CODE (SET_SRC (set)) == COMPARE
|
||||
&& mode != set_mode
|
||||
&& rtx_equal_p (XEXP (cc_src, 0),
|
||||
XEXP (SET_SRC (set), 0))
|
||||
&& rtx_equal_p (XEXP (cc_src, 1),
|
||||
XEXP (SET_SRC (set), 1)))
|
||||
|
||||
{
|
||||
comp_mode = (*targetm.cc_modes_compatible) (mode, set_mode);
|
||||
if (comp_mode != VOIDmode
|
||||
&& (can_change_mode || comp_mode == mode))
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
found_equiv = true;
|
||||
if (insn_count < ARRAY_SIZE (insns))
|
||||
{
|
||||
insns[insn_count] = insn;
|
||||
modes[insn_count] = set_mode;
|
||||
last_insns[insn_count] = end;
|
||||
++insn_count;
|
||||
|
||||
if (mode != comp_mode)
|
||||
{
|
||||
if (! can_change_mode)
|
||||
abort ();
|
||||
mode = comp_mode;
|
||||
PUT_MODE (cc_src, mode);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (set_mode != mode)
|
||||
{
|
||||
/* We found a matching expression in the
|
||||
wrong mode, but we don't have room to
|
||||
store it in the array. Punt. This case
|
||||
should be rare. */
|
||||
break;
|
||||
}
|
||||
/* INSN sets CC_REG to a value equal to CC_SRC
|
||||
with the right mode. We can simply delete
|
||||
it. */
|
||||
delete_insn (insn);
|
||||
}
|
||||
|
||||
/* We found an instruction to delete. Keep looking,
|
||||
in the hopes of finding a three-way jump. */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We found an instruction which sets the condition
|
||||
code, so don't look any farther. */
|
||||
break;
|
||||
}
|
||||
|
||||
/* If INSN sets CC_REG in some other way, don't look any
|
||||
farther. */
|
||||
if (reg_set_p (cc_reg, insn))
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we fell off the bottom of the block, we can keep looking
|
||||
through successors. We pass CAN_CHANGE_MODE as false because
|
||||
we aren't prepared to handle compatibility between the
|
||||
further blocks and this block. */
|
||||
if (insn == end)
|
||||
{
|
||||
enum machine_mode submode;
|
||||
|
||||
submode = cse_cc_succs (e->dest, cc_reg, cc_src, false);
|
||||
if (submode != VOIDmode)
|
||||
{
|
||||
if (submode != mode)
|
||||
abort ();
|
||||
found_equiv = true;
|
||||
can_change_mode = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! found_equiv)
|
||||
return VOIDmode;
|
||||
|
||||
/* Now INSN_COUNT is the number of instructions we found which set
|
||||
CC_REG to a value equivalent to CC_SRC. The instructions are in
|
||||
INSNS. The modes used by those instructions are in MODES. */
|
||||
|
||||
newreg = NULL_RTX;
|
||||
for (i = 0; i < insn_count; ++i)
|
||||
{
|
||||
if (modes[i] != mode)
|
||||
{
|
||||
/* We need to change the mode of CC_REG in INSNS[i] and
|
||||
subsequent instructions. */
|
||||
if (! newreg)
|
||||
{
|
||||
if (GET_MODE (cc_reg) == mode)
|
||||
newreg = cc_reg;
|
||||
else
|
||||
newreg = gen_rtx_REG (mode, REGNO (cc_reg));
|
||||
}
|
||||
cse_change_cc_mode_insns (NEXT_INSN (insns[i]), last_insns[i],
|
||||
newreg);
|
||||
}
|
||||
|
||||
delete_insn (insns[i]);
|
||||
}
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
/* If we have a fixed condition code register (or two), walk through
|
||||
the instructions and try to eliminate duplicate assignments. */
|
||||
|
||||
void
|
||||
cse_condition_code_reg ()
|
||||
{
|
||||
unsigned int cc_regno_1;
|
||||
unsigned int cc_regno_2;
|
||||
rtx cc_reg_1;
|
||||
rtx cc_reg_2;
|
||||
basic_block bb;
|
||||
|
||||
if (! (*targetm.fixed_condition_code_regs) (&cc_regno_1, &cc_regno_2))
|
||||
return;
|
||||
|
||||
cc_reg_1 = gen_rtx_REG (CCmode, cc_regno_1);
|
||||
if (cc_regno_2 != INVALID_REGNUM)
|
||||
cc_reg_2 = gen_rtx_REG (CCmode, cc_regno_2);
|
||||
else
|
||||
cc_reg_2 = NULL_RTX;
|
||||
|
||||
FOR_EACH_BB (bb)
|
||||
{
|
||||
rtx last_insn;
|
||||
rtx cc_reg;
|
||||
rtx insn;
|
||||
rtx cc_src_insn;
|
||||
rtx cc_src;
|
||||
enum machine_mode mode;
|
||||
enum machine_mode orig_mode;
|
||||
|
||||
/* Look for blocks which end with a conditional jump based on a
|
||||
condition code register. Then look for the instruction which
|
||||
sets the condition code register. Then look through the
|
||||
successor blocks for instructions which set the condition
|
||||
code register to the same value. There are other possible
|
||||
uses of the condition code register, but these are by far the
|
||||
most common and the ones which we are most likely to be able
|
||||
to optimize. */
|
||||
|
||||
last_insn = bb->end;
|
||||
if (GET_CODE (last_insn) != JUMP_INSN)
|
||||
continue;
|
||||
|
||||
if (reg_referenced_p (cc_reg_1, PATTERN (last_insn)))
|
||||
cc_reg = cc_reg_1;
|
||||
else if (cc_reg_2 && reg_referenced_p (cc_reg_2, PATTERN (last_insn)))
|
||||
cc_reg = cc_reg_2;
|
||||
else
|
||||
continue;
|
||||
|
||||
cc_src_insn = NULL_RTX;
|
||||
cc_src = NULL_RTX;
|
||||
for (insn = PREV_INSN (last_insn);
|
||||
insn && insn != PREV_INSN (bb->head);
|
||||
insn = PREV_INSN (insn))
|
||||
{
|
||||
rtx set;
|
||||
|
||||
if (! INSN_P (insn))
|
||||
continue;
|
||||
set = single_set (insn);
|
||||
if (set
|
||||
&& GET_CODE (SET_DEST (set)) == REG
|
||||
&& REGNO (SET_DEST (set)) == REGNO (cc_reg))
|
||||
{
|
||||
cc_src_insn = insn;
|
||||
cc_src = SET_SRC (set);
|
||||
break;
|
||||
}
|
||||
else if (reg_set_p (cc_reg, insn))
|
||||
break;
|
||||
}
|
||||
|
||||
if (! cc_src_insn)
|
||||
continue;
|
||||
|
||||
if (modified_between_p (cc_src, cc_src_insn, NEXT_INSN (last_insn)))
|
||||
continue;
|
||||
|
||||
/* Now CC_REG is a condition code register used for a
|
||||
conditional jump at the end of the block, and CC_SRC, in
|
||||
CC_SRC_INSN, is the value to which that condition code
|
||||
register is set, and CC_SRC is still meaningful at the end of
|
||||
the basic block. */
|
||||
|
||||
orig_mode = GET_MODE (cc_src);
|
||||
mode = cse_cc_succs (bb, cc_reg, cc_src, true);
|
||||
if (mode != VOIDmode)
|
||||
{
|
||||
if (mode != GET_MODE (cc_src))
|
||||
abort ();
|
||||
if (mode != orig_mode)
|
||||
{
|
||||
rtx newreg = gen_rtx_REG (mode, REGNO (cc_reg));
|
||||
|
||||
/* Change the mode of CC_REG in CC_SRC_INSN to
|
||||
GET_MODE (NEWREG). */
|
||||
for_each_rtx (&PATTERN (cc_src_insn), cse_change_cc_mode,
|
||||
newreg);
|
||||
for_each_rtx (®_NOTES (cc_src_insn), cse_change_cc_mode,
|
||||
newreg);
|
||||
|
||||
/* Do the same in the following insns that use the
|
||||
current value of CC_REG within BB. */
|
||||
cse_change_cc_mode_insns (NEXT_INSN (cc_src_insn),
|
||||
NEXT_INSN (last_insn),
|
||||
newreg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum machine_mode
|
||||
default_cc_modes_compatible (m1, m2)
|
||||
enum machine_mode m1;
|
||||
enum machine_mode m2;
|
||||
{
|
||||
if (m1 == m2)
|
||||
return m1;
|
||||
return VOIDmode;
|
||||
}
|
||||
|
31
gnu/dist/gcc/gcc/cselib.c
vendored
31
gnu/dist/gcc/gcc/cselib.c
vendored
@ -63,7 +63,7 @@ static void cselib_invalidate_regno PARAMS ((unsigned int,
|
||||
static int cselib_mem_conflict_p PARAMS ((rtx, rtx));
|
||||
static int cselib_invalidate_mem_1 PARAMS ((void **, void *));
|
||||
static void cselib_invalidate_mem PARAMS ((rtx));
|
||||
static void cselib_invalidate_rtx PARAMS ((rtx, rtx, void *));
|
||||
static void cselib_invalidate_rtx_note_stores PARAMS ((rtx, rtx, void *));
|
||||
static void cselib_record_set PARAMS ((rtx, cselib_val *,
|
||||
cselib_val *));
|
||||
static void cselib_record_sets PARAMS ((rtx));
|
||||
@ -1143,15 +1143,11 @@ cselib_invalidate_mem (mem_rtx)
|
||||
htab_traverse (hash_table, cselib_invalidate_mem_1, mem_rtx);
|
||||
}
|
||||
|
||||
/* Invalidate DEST, which is being assigned to or clobbered. The second and
|
||||
the third parameter exist so that this function can be passed to
|
||||
note_stores; they are ignored. */
|
||||
/* Invalidate DEST, which is being assigned to or clobbered. */
|
||||
|
||||
static void
|
||||
cselib_invalidate_rtx (dest, ignore, data)
|
||||
void
|
||||
cselib_invalidate_rtx (dest)
|
||||
rtx dest;
|
||||
rtx ignore ATTRIBUTE_UNUSED;
|
||||
void *data ATTRIBUTE_UNUSED;
|
||||
{
|
||||
while (GET_CODE (dest) == STRICT_LOW_PART || GET_CODE (dest) == SIGN_EXTRACT
|
||||
|| GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SUBREG)
|
||||
@ -1167,7 +1163,18 @@ cselib_invalidate_rtx (dest, ignore, data)
|
||||
invalidate the stack pointer correctly. Note that invalidating
|
||||
the stack pointer is different from invalidating DEST. */
|
||||
if (push_operand (dest, GET_MODE (dest)))
|
||||
cselib_invalidate_rtx (stack_pointer_rtx, NULL_RTX, NULL);
|
||||
cselib_invalidate_rtx (stack_pointer_rtx);
|
||||
}
|
||||
|
||||
/* A wrapper for cselib_invalidate_rtx to be called via note_stores. */
|
||||
|
||||
static void
|
||||
cselib_invalidate_rtx_note_stores (dest, ignore, data)
|
||||
rtx dest;
|
||||
rtx ignore ATTRIBUTE_UNUSED;
|
||||
void *data ATTRIBUTE_UNUSED;
|
||||
{
|
||||
cselib_invalidate_rtx (dest);
|
||||
}
|
||||
|
||||
/* Record the result of a SET instruction. DEST is being set; the source
|
||||
@ -1293,7 +1300,7 @@ cselib_record_sets (insn)
|
||||
/* Invalidate all locations written by this insn. Note that the elts we
|
||||
looked up in the previous loop aren't affected, just some of their
|
||||
locations may go away. */
|
||||
note_stores (body, cselib_invalidate_rtx, NULL);
|
||||
note_stores (body, cselib_invalidate_rtx_note_stores, NULL);
|
||||
|
||||
/* Now enter the equivalences in our tables. */
|
||||
for (i = 0; i < n_sets; i++)
|
||||
@ -1358,7 +1365,7 @@ cselib_process_insn (insn)
|
||||
unlikely to help. */
|
||||
for (x = REG_NOTES (insn); x; x = XEXP (x, 1))
|
||||
if (REG_NOTE_KIND (x) == REG_INC)
|
||||
cselib_invalidate_rtx (XEXP (x, 0), NULL_RTX, NULL);
|
||||
cselib_invalidate_rtx (XEXP (x, 0));
|
||||
#endif
|
||||
|
||||
/* Look for any CLOBBERs in CALL_INSN_FUNCTION_USAGE, but only
|
||||
@ -1366,7 +1373,7 @@ cselib_process_insn (insn)
|
||||
if (GET_CODE (insn) == CALL_INSN)
|
||||
for (x = CALL_INSN_FUNCTION_USAGE (insn); x; x = XEXP (x, 1))
|
||||
if (GET_CODE (XEXP (x, 0)) == CLOBBER)
|
||||
cselib_invalidate_rtx (XEXP (XEXP (x, 0), 0), NULL_RTX, NULL);
|
||||
cselib_invalidate_rtx (XEXP (XEXP (x, 0), 0));
|
||||
|
||||
cselib_current_insn = 0;
|
||||
|
||||
|
1
gnu/dist/gcc/gcc/cselib.h
vendored
1
gnu/dist/gcc/gcc/cselib.h
vendored
@ -68,3 +68,4 @@ extern void cselib_process_insn PARAMS ((rtx));
|
||||
extern int rtx_equal_for_cselib_p PARAMS ((rtx, rtx));
|
||||
extern int references_value_p PARAMS ((rtx, int));
|
||||
extern rtx cselib_subst_to_values PARAMS ((rtx));
|
||||
extern void cselib_invalidate_rtx PARAMS ((rtx));
|
||||
|
5
gnu/dist/gcc/gcc/dbxout.c
vendored
5
gnu/dist/gcc/gcc/dbxout.c
vendored
@ -796,6 +796,11 @@ dbxout_type_fields (type)
|
||||
field that we can support. */
|
||||
for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
|
||||
{
|
||||
|
||||
/* If on of the nodes is an error_mark or its type is then return early. */
|
||||
if (tem == error_mark_node || TREE_TYPE (tem) == error_mark_node)
|
||||
return;
|
||||
|
||||
/* Omit here local type decls until we know how to support them. */
|
||||
if (TREE_CODE (tem) == TYPE_DECL
|
||||
/* Omit fields whose position or size are variable or too large to
|
||||
|
2
gnu/dist/gcc/gcc/doc/contrib.texi
vendored
2
gnu/dist/gcc/gcc/doc/contrib.texi
vendored
@ -143,7 +143,7 @@ Eric Christopher for his Java porting help and clean-ups.
|
||||
Branko Cibej for more warning contributions.
|
||||
|
||||
@item
|
||||
The @uref{http://www.classpath.org,,GNU Classpath project}
|
||||
The @uref{http://www.gnu.org/software/classpath/,,GNU Classpath project}
|
||||
for all of their merged runtime code.
|
||||
|
||||
@item
|
||||
|
78
gnu/dist/gcc/gcc/doc/cppinternals.info
vendored
78
gnu/dist/gcc/gcc/doc/cppinternals.info
vendored
@ -1,5 +1,5 @@
|
||||
Ceci est le fichier Info doc/cppinternals.info, produit par Makeinfo
|
||||
version 4.6 à partir doc/cppinternals.texi.
|
||||
This is doc/cppinternals.info, produced by makeinfo version 4.7 from
|
||||
doc/cppinternals.texi.
|
||||
|
||||
INFO-DIR-SECTION Programming
|
||||
START-INFO-DIR-ENTRY
|
||||
@ -26,10 +26,11 @@ versions.
|
||||
|
||||
File: cppinternals.info, Node: Top, Next: Conventions, Up: (dir)
|
||||
|
||||
The GNU C Preprocessor Internals
|
||||
********************************
|
||||
|
||||
|
||||
Cpplib--the GNU C Preprocessor
|
||||
******************************
|
||||
1 Cpplib--the GNU C Preprocessor
|
||||
********************************
|
||||
|
||||
The GNU C preprocessor in GCC 3.x has been completely rewritten. It is
|
||||
now implemented as a library, "cpplib", so it can be easily shared
|
||||
@ -990,44 +991,45 @@ File: cppinternals.info, Node: Index, Prev: Files, Up: Top
|
||||
Index
|
||||
*****
|
||||
|
||||
|