mirror of
https://github.com/pmret/gcc-papermario.git
synced 2024-11-08 11:53:01 +01:00
Initial commit of GCC 2.8.1
This commit is contained in:
commit
57261bd1c1
95
.gdbinit
Normal file
95
.gdbinit
Normal file
@ -0,0 +1,95 @@
|
||||
define pr
|
||||
set debug_rtx ($)
|
||||
end
|
||||
|
||||
document pr
|
||||
Print the full structure of the rtx that is $.
|
||||
Works only when an inferior is executing.
|
||||
end
|
||||
|
||||
define prl
|
||||
set debug_rtx_list ($, debug_rtx_count)
|
||||
end
|
||||
|
||||
document prl
|
||||
Print the full structure of all rtx insns beginning at $.
|
||||
Works only when an inferior is executing.
|
||||
Uses variable debug_rtx_count to control number of insns printed:
|
||||
debug_rtx_count > 0: print from $ on.
|
||||
debug_rtx_count < 0: print a window around $.
|
||||
|
||||
There is also debug_rtx_find (rtx, uid) that will scan a list for UID and print
|
||||
it using debug_rtx_list. Usage example: set $foo=debug_rtx_find(first, 42)
|
||||
end
|
||||
|
||||
define pt
|
||||
set debug_tree ($)
|
||||
end
|
||||
|
||||
document pt
|
||||
Print the full structure of the tree that is $.
|
||||
Works only when an inferior is executing.
|
||||
end
|
||||
|
||||
define ptc
|
||||
output (enum tree_code) $.common.code
|
||||
echo \n
|
||||
end
|
||||
|
||||
document ptc
|
||||
Print the tree-code of the tree node that is $.
|
||||
end
|
||||
|
||||
define pdn
|
||||
output $.decl.name->identifier.pointer
|
||||
echo \n
|
||||
end
|
||||
|
||||
document pdn
|
||||
Print the name of the decl-node that is $.
|
||||
end
|
||||
|
||||
define ptn
|
||||
output $.type.name->decl.name->identifier.pointer
|
||||
echo \n
|
||||
end
|
||||
|
||||
document ptn
|
||||
Print the name of the type-node that is $.
|
||||
end
|
||||
|
||||
define prc
|
||||
output (enum rtx_code) $.code
|
||||
echo \ (
|
||||
output $.mode
|
||||
echo )\n
|
||||
end
|
||||
|
||||
document prc
|
||||
Print the rtx-code and machine mode of the rtx that is $.
|
||||
end
|
||||
|
||||
define pi
|
||||
print $.fld[0].rtx@7
|
||||
end
|
||||
|
||||
document pi
|
||||
Print the fields of an instruction that is $.
|
||||
end
|
||||
|
||||
define pbs
|
||||
set print_binding_stack ()
|
||||
end
|
||||
|
||||
document pbs
|
||||
In cc1plus, print the current binding stack, frame by frame, up to and
|
||||
including the global binding level.
|
||||
end
|
||||
|
||||
# Don't let abort actually run, as it will make
|
||||
# stdio stop working and therefore the `pr' command below as well.
|
||||
b abort
|
||||
|
||||
# Make gdb complain about symbol reading errors. This is so that gcc
|
||||
# developers can see and fix bugs in gcc debug output.
|
||||
set complaints 20
|
23
BUGS
Normal file
23
BUGS
Normal file
@ -0,0 +1,23 @@
|
||||
If you think you may have found a bug in GNU CC, please
|
||||
read the Bugs section of the GCC manual for advice on
|
||||
|
||||
(1) how to tell when to report a bug,
|
||||
(2) where to send your bug report, and
|
||||
(2) how to write a useful bug report and what information
|
||||
it needs to have.
|
||||
|
||||
There are three ways to read the Bugs section.
|
||||
|
||||
(1) In a printed copy of the GCC manual. You can order one from the
|
||||
Free Software Foundation; see the file ORDERS. But if you don't have
|
||||
a copy on hand and you think you have found a bug, you shouldn't wait
|
||||
to get a printed manual; you should read the section right away as
|
||||
described below.
|
||||
|
||||
(2) With Info. Start Emacs, do C-h i to enter Info,
|
||||
then m gcc RET to get to the GCC manual, then m Bugs RET
|
||||
to get to the section on bugs. Or use standalone Info in
|
||||
a like manner. (Standalone Info is part of the Texinfo distribution.)
|
||||
|
||||
(3) By hand. Search for the chapter "Reporting Bugs" in gcc.texi, or
|
||||
cat /usr/local/info/gcc* | more "+/^File: emacs, Node: Bugs,"
|
340
COPYING
Normal file
340
COPYING
Normal file
@ -0,0 +1,340 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
482
COPYING.LIB
Normal file
482
COPYING.LIB
Normal file
@ -0,0 +1,482 @@
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the library GPL. It is
|
||||
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Library General Public License, applies to some
|
||||
specially designated Free Software Foundation software, and to any
|
||||
other libraries whose authors decide to use it. You can use it for
|
||||
your libraries, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if
|
||||
you distribute copies of the library, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link a program with the library, you must provide
|
||||
complete object files to the recipients so that they can relink them
|
||||
with the library, after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
Our method of protecting your rights has two steps: (1) copyright
|
||||
the library, and (2) offer you this license which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
Also, for each distributor's protection, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
library. If the library is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original
|
||||
version, so that any problems introduced by others will not reflect on
|
||||
the original authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that companies distributing free
|
||||
software will individually obtain patent licenses, thus in effect
|
||||
transforming the program into proprietary software. To prevent this,
|
||||
we have made it clear that any patent must be licensed for everyone's
|
||||
free use or not licensed at all.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the ordinary
|
||||
GNU General Public License, which was designed for utility programs. This
|
||||
license, the GNU Library General Public License, applies to certain
|
||||
designated libraries. This license is quite different from the ordinary
|
||||
one; be sure to read it in full, and don't assume that anything in it is
|
||||
the same as in the ordinary license.
|
||||
|
||||
The reason we have a separate public license for some libraries is that
|
||||
they blur the distinction we usually make between modifying or adding to a
|
||||
program and simply using it. Linking a program with a library, without
|
||||
changing the library, is in some sense simply using the library, and is
|
||||
analogous to running a utility program or application program. However, in
|
||||
a textual and legal sense, the linked executable is a combined work, a
|
||||
derivative of the original library, and the ordinary General Public License
|
||||
treats it as such.
|
||||
|
||||
Because of this blurred distinction, using the ordinary General
|
||||
Public License for libraries did not effectively promote software
|
||||
sharing, because most developers did not use the libraries. We
|
||||
concluded that weaker conditions might promote sharing better.
|
||||
|
||||
However, unrestricted linking of non-free programs would deprive the
|
||||
users of those programs of all benefit from the free status of the
|
||||
libraries themselves. This Library General Public License is intended to
|
||||
permit developers of non-free programs to use free libraries, while
|
||||
preserving your freedom as a user of such programs to change the free
|
||||
libraries that are incorporated in them. (We have not seen how to achieve
|
||||
this as regards changes in header files, but we have achieved it as regards
|
||||
changes in the actual functions of the Library.) The hope is that this
|
||||
will lead to faster development of free libraries.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, while the latter only
|
||||
works together with the library.
|
||||
|
||||
Note that it is possible for a library to be covered by the ordinary
|
||||
General Public License rather than by this special one.
|
||||
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library which
|
||||
contains a notice placed by the copyright holder or other authorized
|
||||
party saying it may be distributed under the terms of this Library
|
||||
General Public License (also called "this License"). Each licensee is
|
||||
addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also compile or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
c) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
d) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the source code distributed need not include anything that is normally
|
||||
distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Library General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
6670
ChangeLog.0
Normal file
6670
ChangeLog.0
Normal file
File diff suppressed because it is too large
Load Diff
9207
ChangeLog.1
Normal file
9207
ChangeLog.1
Normal file
File diff suppressed because it is too large
Load Diff
10110
ChangeLog.10
Normal file
10110
ChangeLog.10
Normal file
File diff suppressed because it is too large
Load Diff
7229
ChangeLog.2
Normal file
7229
ChangeLog.2
Normal file
File diff suppressed because it is too large
Load Diff
8063
ChangeLog.3
Normal file
8063
ChangeLog.3
Normal file
File diff suppressed because it is too large
Load Diff
10783
ChangeLog.4
Normal file
10783
ChangeLog.4
Normal file
File diff suppressed because it is too large
Load Diff
8954
ChangeLog.5
Normal file
8954
ChangeLog.5
Normal file
File diff suppressed because it is too large
Load Diff
8173
ChangeLog.6
Normal file
8173
ChangeLog.6
Normal file
File diff suppressed because it is too large
Load Diff
10376
ChangeLog.7
Normal file
10376
ChangeLog.7
Normal file
File diff suppressed because it is too large
Load Diff
11080
ChangeLog.8
Normal file
11080
ChangeLog.8
Normal file
File diff suppressed because it is too large
Load Diff
9968
ChangeLog.9
Normal file
9968
ChangeLog.9
Normal file
File diff suppressed because it is too large
Load Diff
3799
ChangeLog.lib
Normal file
3799
ChangeLog.lib
Normal file
File diff suppressed because it is too large
Load Diff
2681
Makefile.in
Normal file
2681
Makefile.in
Normal file
File diff suppressed because it is too large
Load Diff
983
NEWS
Normal file
983
NEWS
Normal file
@ -0,0 +1,983 @@
|
||||
Noteworthy changes in GCC version 2.8.1
|
||||
---------------------------------------
|
||||
|
||||
Numerous bugs have been fixed and some minor performance
|
||||
improvements (compilation speed) have been made.
|
||||
|
||||
Noteworthy changes in GCC version 2.8.0
|
||||
---------------------------------------
|
||||
|
||||
A major change in this release is the addition of a framework for
|
||||
exception handling, currently used by C++. Many internal changes and
|
||||
optimization improvements have been made. These increase the
|
||||
maintainability and portability of GCC. GCC now uses autoconf to
|
||||
compute many host parameters.
|
||||
|
||||
A new project, egcs (pronounced ``eggs''), is maintaining an
|
||||
experimental version of the GNU C compiler. The egcs compiler
|
||||
contains features that are candidates for inclusion in future versions
|
||||
of GCC. The standard GCC distribution is intended to contain a mature
|
||||
compiler that is stable and reliable; egcs aims at making experimental
|
||||
changes available to interested users at an earlier stage in their
|
||||
development process than would be appropriate for a production
|
||||
compiler. Please see <http://www.cygnus.com/egcs/> for more
|
||||
information about egcs. A major motivation for the egcs project was
|
||||
the long release cycle for GCC 2.8.0. This was due to changes for
|
||||
exception handling that took a long time to complete. In the future,
|
||||
changes of this nature can be developed in the egcs framework and not
|
||||
interfere with the frequent releases of the standard GCC distribution.
|
||||
|
||||
Due to a bug fix related to exception handling, if you have previously
|
||||
built a sharable library with some recent unofficial versions of GCC
|
||||
on some systems and then rebuild the library with GCC 2.8.0, programs
|
||||
previously linked with that library may fail during initialization
|
||||
with a message about an undefined symbols __register_frame. If that
|
||||
happens, you must either relink the application or rebuild the
|
||||
sharable library with "-Wl,-u,__register_frame" on the command line.
|
||||
|
||||
The following lists changes that add new features or targets.
|
||||
|
||||
See cp/NEWS for new features of C++ in this release.
|
||||
|
||||
New tools and features:
|
||||
|
||||
The Dwarf 2 debugging information format is supported on ELF systems, and
|
||||
is the default for -ggdb where available. It can also be used for C++.
|
||||
The Dwarf version 1 debugging format is also permitted for C++, but
|
||||
does not work well.
|
||||
|
||||
gcov.c is provided for test coverage analysis and branch profiling
|
||||
analysis is also supported; see -fprofile-arcs, -ftest-coverage,
|
||||
and -fbranch-probabilities.
|
||||
|
||||
Support for the Checker memory checking tool.
|
||||
|
||||
New switch, -fstack-check, to check for stack overflow on systems that
|
||||
don't have such built into their ABI.
|
||||
|
||||
New switches, -Wundef and -Wno-undef to warn if an undefined identifier
|
||||
is evaluated in an #if directive.
|
||||
|
||||
Options -Wall and -Wimplicit now cause GCC to warn about implicit int
|
||||
in declarations (e.g. `register i;'), since the C Standard committee
|
||||
has decided to disallow this in the next revision of the standard;
|
||||
-Wimplicit-function-declarations and -Wimplicit-int are subsets of
|
||||
this.
|
||||
|
||||
Option -Wsign-compare causes GCC to warn about comparison of signed and
|
||||
unsigned values.
|
||||
|
||||
Add -dI option of cccp for cxref.
|
||||
|
||||
New features in configuration, installation and specs file handling:
|
||||
|
||||
New option --enable-c-cpplib to configure script.
|
||||
|
||||
You can use --with-cpu on the configure command to specify the default
|
||||
CPU that GCC should generate code for.
|
||||
|
||||
The -specs=file switch allows you to override default specs used in
|
||||
invoking programs like cc1, as, etc.
|
||||
|
||||
Allow including one specs file from another and renaming a specs
|
||||
variable.
|
||||
|
||||
You can now relocate all GCC files with a single environment variable
|
||||
or a registry entry under Windows 95 and Windows NT.
|
||||
|
||||
Changes in Objective-C:
|
||||
|
||||
The Objective-C Runtime Library has been made thread-safe.
|
||||
|
||||
The Objective-C Runtime Library contains an interface for creating
|
||||
mutexes, condition mutexes, and threads; it requires a back-end
|
||||
implementation for the specific platform and/or thread package.
|
||||
Currently supported are DEC/OSF1, IRIX, Mach, OS/2, POSIX, PCThreads,
|
||||
Solaris, and Windows32. The --enable-threads parameter can be used
|
||||
when configuring GCC to enable and select a thread back-end.
|
||||
|
||||
Objective-C is now configured as separate front-end language to GCC,
|
||||
making it more convenient to conditionally build it.
|
||||
|
||||
The internal structures of the Objective-C Runtime Library have
|
||||
changed sufficiently to warrant a new version number; now version 8.
|
||||
Programs compiled with an older version must be recompiled.
|
||||
|
||||
The Objective-C Runtime Library can be built as a DLL on Windows 95
|
||||
and Windows NT systems.
|
||||
|
||||
The Objective-C Runtime Library implements +load.
|
||||
|
||||
The following new targets are supported (see also list under each
|
||||
individual CPU below):
|
||||
|
||||
Embedded target m32r-elf.
|
||||
Embedded Hitachi Super-H using ELF.
|
||||
RTEMS real-time system on various CPU targets.
|
||||
ARC processor.
|
||||
NEC V850 processor.
|
||||
Matsushita MN10200 processor.
|
||||
Matsushita MN10300 processor.
|
||||
Sparc and PowerPC running on VxWorks.
|
||||
Support both glibc versions 1 and 2 on Linux-based GNU systems.
|
||||
|
||||
New features for DEC Alpha systems:
|
||||
|
||||
Allow detailed specification of IEEE fp support:
|
||||
-mieee, -mieee-with-inexact, and -mieee-conformant
|
||||
-mfp-trap-mode=xxx, -mfp-round-mode=xxx, -mtrap-precision=xxx
|
||||
-mcpu=xxx for CPU selection
|
||||
Support scheduling parameters for EV5.
|
||||
Add support for BWX, CIX, and MAX instruction set extensions.
|
||||
Support Linux-based GNU systems.
|
||||
Support VMS.
|
||||
|
||||
Additional supported processors and systems for MIPS targets:
|
||||
|
||||
MIPS4 instruction set.
|
||||
R4100, R4300 and R5000 processors.
|
||||
N32 and N64 ABI.
|
||||
IRIX 6.2.
|
||||
SNI SINIX.
|
||||
|
||||
New features for Intel x86 family:
|
||||
|
||||
Add scheduling parameters for Pentium and Pentium Pro.
|
||||
Support stabs on Solaris-x86.
|
||||
Intel x86 processors running the SCO OpenServer 5 family.
|
||||
Intel x86 processors running DG/UX.
|
||||
Intel x86 using Cygwin32 or Mingw32 on Windows 95 and Windows NT.
|
||||
|
||||
New features for Motorola 68k family:
|
||||
|
||||
Support for 68060 processor.
|
||||
More consistent switches to specify processor.
|
||||
Motorola 68k family running AUX.
|
||||
68040 running pSOS, ELF object files, DBX debugging.
|
||||
Coldfire variant of Motorola m68k family.
|
||||
|
||||
New features for the HP PA RISC:
|
||||
|
||||
-mspace and m-no-space
|
||||
-mlong-load-store and -mno-long-load-store
|
||||
-mbig-switch -mno-big-switch
|
||||
|
||||
GCC on the PA requires either gas-2.7 or the HP assembler; for best
|
||||
results using GAS is highly recommended. GAS is required for -g and
|
||||
exception handling support.
|
||||
|
||||
New features for SPARC-based systems:
|
||||
|
||||
The ultrasparc cpu.
|
||||
The sparclet cpu, supporting only a.out file format.
|
||||
Sparc running SunOS 4 with the GNU assembler.
|
||||
Sparc running the Linux-based GNU system.
|
||||
Embedded Sparc processors running the ELF object file format.
|
||||
-mcpu=xxx
|
||||
-mtune=xxx
|
||||
-malign-loops=xxx
|
||||
-malign-jumps=xxx
|
||||
-malign-functions=xxx
|
||||
-mimpure-text and -mno-impure-text
|
||||
|
||||
Options -mno-v8 and -mno-sparclite are no longer supported on SPARC
|
||||
targets. Options -mcypress, -mv8, -msupersparc, -msparclite, -mf930,
|
||||
and -mf934 are deprecated and will be deleted in GCC 2.9. Use
|
||||
-mcpu=xxx instead.
|
||||
|
||||
New features for rs6000 and PowerPC systems:
|
||||
|
||||
Solaris 2.51 running on PowerPC's.
|
||||
The Linux-based GNU system running on PowerPC's.
|
||||
-mcpu=604e,602,603e,620,801,823,mpc505,821,860,power2
|
||||
-mtune=xxx
|
||||
-mrelocatable-lib, m-no-relocatable-lib
|
||||
-msim, -mmve, -memb
|
||||
-mupdate, -mno-update
|
||||
-mfused-madd, -mno-fused-madd
|
||||
|
||||
-mregnames
|
||||
-meabi
|
||||
-mcall-linux, -mcall-solaris, -mcall-sysv-eabi, -mcall-sysv-noeabi
|
||||
-msdata, -msdata=none, -msdata=default, -msdata=sysv, -msdata=eabi
|
||||
-memb, -msim, -mmvme
|
||||
-myellowknife, -mads
|
||||
wchar_t is now of type long as per the ABI, not unsigned short.
|
||||
-p/-pg support
|
||||
-mcpu=403 now implies -mstrict-align.
|
||||
Implement System V profiling.
|
||||
|
||||
Aix 4.1 GCC targets now default to -mcpu=common so that programs
|
||||
compiled can be moved between rs6000 and powerpc based systems. A
|
||||
consequence of this is that -static won't work, and that some programs
|
||||
may be slightly slower.
|
||||
|
||||
You can select the default value to use for -mcpu=xxx on rs6000 and
|
||||
powerpc targets by using the --with-cpu=xxx option when configuring the
|
||||
compiler. In addition, a new options, -mtune=xxx was added that
|
||||
selects the machine to schedule for but does not select the
|
||||
architecture level.
|
||||
|
||||
Directory names used for storing the multilib libraries on System V
|
||||
and embedded PowerPC systems have been shortened to work with commands
|
||||
like tar that have fixed limits on pathname size.
|
||||
|
||||
New features for the Hitachi H8/300(H):
|
||||
|
||||
-malign-300
|
||||
-ms (for the Hitachi H8/S processor)
|
||||
-mint32
|
||||
|
||||
New features for the ARM:
|
||||
|
||||
-march=xxx, -mtune=xxx, -mcpu=xxx
|
||||
Support interworking with Thumb code.
|
||||
ARM processor with a.out object format, COFF, or AOF assembler.
|
||||
ARM on "semi-hosted" platform.
|
||||
ARM running NetBSD.
|
||||
ARM running the Linux-based GNU system.
|
||||
|
||||
New feature for Solaris systems:
|
||||
|
||||
GCC installation no longer makes a copy of system include files,
|
||||
thus insulating GCC better from updates to the operating system.
|
||||
|
||||
|
||||
Noteworthy changes in GCC version 2.7.2
|
||||
---------------------------------------
|
||||
|
||||
A few bugs have been fixed (most notably the generation of an
|
||||
invalid assembler opcode on some RS/6000 systems).
|
||||
|
||||
Noteworthy changes in GCC version 2.7.1
|
||||
---------------------------------------
|
||||
|
||||
This release fixes numerous bugs (mostly minor) in GCC 2.7.0, but
|
||||
also contains a few new features, mostly related to specific targets.
|
||||
|
||||
Major changes have been made in code to support Windows NT.
|
||||
|
||||
The following new targets are supported:
|
||||
|
||||
2.9 BSD on PDP-11
|
||||
Linux on m68k
|
||||
HP/UX version 10 on HP PA RISC (treated like version 9)
|
||||
DEC Alpha running Windows NT
|
||||
|
||||
When parsing C, GCC now recognizes C++ style `//' comments unless you
|
||||
specify `-ansi' or `-traditional'.
|
||||
|
||||
The PowerPC System V targets (powerpc-*-sysv, powerpc-*-eabi) now use the
|
||||
calling sequence specified in the System V Application Binary Interface
|
||||
Processor Supplement (PowerPC Processor ABI Supplement) rather than the calling
|
||||
sequence used in GCC version 2.7.0. That calling sequence was based on the AIX
|
||||
calling sequence without function descriptors. To compile code for that older
|
||||
calling sequence, either configure the compiler for powerpc-*-eabiaix or use
|
||||
the -mcall-aix switch when compiling and linking.
|
||||
|
||||
Noteworthy changes in GCC version 2.7.0
|
||||
---------------------------------------
|
||||
|
||||
GCC now works better on systems that use ".obj" and ".exe" instead of
|
||||
".o" and no extension. This involved changes to the driver program,
|
||||
gcc.c, to convert ".o" names to ".obj" and to GCC's Makefile to use
|
||||
".obj" and ".exe" in filenames that are not targets. In order to
|
||||
build GCC on such systems, you may need versions of GNU make and/or
|
||||
compatible shells. At this point, this support is preliminary.
|
||||
|
||||
Object file extensions of ".obj" and executable file extensions of
|
||||
".exe" are allowed when using appropriate version of GNU Make.
|
||||
|
||||
Numerous enhancements were made to the __attribute__ facility including
|
||||
more attributes and more places that support it. We now support the
|
||||
"packed", "nocommon", "noreturn", "volatile", "const", "unused",
|
||||
"transparent_union", "constructor", "destructor", "mode", "section",
|
||||
"align", "format", "weak", and "alias" attributes. Each of these
|
||||
names may also be specified with added underscores, e.g., "__packed__".
|
||||
__attribute__ may now be applied to parameter definitions, function
|
||||
definitions, and structure, enum, and union definitions.
|
||||
|
||||
GCC now supports returning more structures in registers, as specified by
|
||||
many calling sequences (ABIs), such as on the HP PA RISC.
|
||||
|
||||
A new option '-fpack-struct' was added to automatically pack all structure
|
||||
members together without holes.
|
||||
|
||||
There is a new library (cpplib) and program (cppmain) that at some
|
||||
point will replace cpp (aka cccp). To use cppmain as cpp now, pass
|
||||
the option CCCP=cppmain to make. The library is already used by the
|
||||
fix-header program, which should speed up the fixproto script.
|
||||
|
||||
New options for supported targets:
|
||||
|
||||
GNU on many targets.
|
||||
NetBSD on MIPS, m68k, VAX, and x86.
|
||||
LynxOS on x86, m68k, Sparc, and RS/6000.
|
||||
VxWorks on many targets.
|
||||
|
||||
Windows/NT on x86 architecture. Initial support for Windows/NT on Alpha
|
||||
(not fully working).
|
||||
|
||||
Many embedded targets, specifically UDI on a29k, aout, coff, elf,
|
||||
and vsta "operating systems" on m68k, m88k, mips, sparc, and x86.
|
||||
|
||||
Additional support for x86 (i386, i486, and Pentium):
|
||||
|
||||
Work with old and new linkers for Linux-based GNU systems,
|
||||
supporting both a.out and ELF.
|
||||
FreeBSD on x86.
|
||||
Stdcall convention.
|
||||
-malign-double, -mregparm=, -malign-loops= and -malign-jumps= switches.
|
||||
On ISC systems, support -Xp like -posix.
|
||||
|
||||
Additions for RS/6000:
|
||||
|
||||
Instruction scheduling information for PowerPC 403.
|
||||
AIX 4.1 on PowerPC.
|
||||
-mstring and -mno-string.
|
||||
-msoft-float and floating-point emulation included.
|
||||
Preliminary support for PowerPC System V.4 with or without the GNU as.
|
||||
Preliminary support for EABI.
|
||||
Preliminary support for 64-bit systems.
|
||||
Both big and little endian systems.
|
||||
|
||||
New features for MIPS-based systems:
|
||||
|
||||
r4650.
|
||||
mips4 and R8000.
|
||||
Irix 6.0.
|
||||
64-bit ABI.
|
||||
Allow dollar signs in labels on SGI/Irix 5.x.
|
||||
|
||||
New support for HP PA RISC:
|
||||
|
||||
Generation of PIC (requires binutils-2.5.2.u6 or later).
|
||||
HP-UX version 9 on HP PA RISC (dynamically links even with -g).
|
||||
Processor variants for HP PA RISC: 700, 7100, and 7100LC.
|
||||
Automatic generation of long calls when needed.
|
||||
-mfast-indirect-calls for kernels and static binaries.
|
||||
|
||||
The called routine now copies arguments passed by invisible reference,
|
||||
as required by the calling standard.
|
||||
|
||||
Other new miscellaneous target-specific support:
|
||||
|
||||
-mno-multm on a29k.
|
||||
-mold-align for i960.
|
||||
Configuration for "semi-hosted" ARM.
|
||||
-momit-leaf-frame-pointer for M88k.
|
||||
SH3 variant of Hitachi Super-H and support both big and little endian.
|
||||
|
||||
Changes to Objective-C:
|
||||
|
||||
Bare-bones implementation of NXConstantString has been added,
|
||||
which is invoked by the @"string" directive.
|
||||
|
||||
Class * has been changed to Class to conform to the NextSTEP and
|
||||
OpenStep runtime.
|
||||
|
||||
Enhancements to make dynamic loading easier.
|
||||
|
||||
The module version number has been updated to Version 7, thus existing
|
||||
code will need to be recompiled to use the current run-time library.
|
||||
|
||||
GCC now supports the ISO Normative Addendum 1 to the C Standard.
|
||||
As a result:
|
||||
|
||||
The header <iso646.h> defines macros for C programs written
|
||||
in national variants of ISO 646.
|
||||
|
||||
The following digraph tokens are supported:
|
||||
<: :> <% %> %: %:%:
|
||||
These behave like the following, respectively:
|
||||
[ ] { } # ##
|
||||
|
||||
Digraph tokens are supported unless you specify the `-traditional'
|
||||
option; you do not need to specify `-ansi' or `-trigraphs'. Except
|
||||
for contrived and unlikely examples involving preprocessor
|
||||
stringizing, digraph interpretation doesn't change the meaning of
|
||||
programs; this is unlike trigraph interpretation, which changes the
|
||||
meanings of relatively common strings.
|
||||
|
||||
The macro __STDC_VERSION__ has the value 199409L.
|
||||
|
||||
As usual, for full conformance to the standard, you also need a
|
||||
C library that conforms.
|
||||
|
||||
The following lists changes that have been made to g++. If some
|
||||
features mentioned below sound unfamiliar, you will probably want to
|
||||
look at the recently-released public review copy of the C++ Working
|
||||
Paper. For PostScript and PDF (Adobe Acrobat) versions, see the
|
||||
archive at ftp://research.att.com/dist/stdc++/WP. For HTML and ASCII
|
||||
versions, see ftp://ftp.cygnus.com/pub/g++. On the web, see
|
||||
http://www.cygnus.com/~mrs/wp-draft.
|
||||
|
||||
The scope of variables declared in the for-init-statement has been changed
|
||||
to conform to http://www.cygnus.com/~mrs/wp-draft/stmt.html#stmt.for; as a
|
||||
result, packages such as groff 1.09 will not compile unless you specify the
|
||||
-fno-for-scope flag. PLEASE DO NOT REPORT THIS AS A BUG; this is a change
|
||||
mandated by the C++ standardization committee.
|
||||
|
||||
Binary incompatibilities:
|
||||
|
||||
The builtin 'bool' type is now the size of a machine word on RISC targets,
|
||||
for code efficiency; it remains one byte long on CISC targets.
|
||||
|
||||
Code that does not use #pragma interface/implementation will most
|
||||
likely shrink dramatically, as g++ now only emits the vtable for a
|
||||
class in the translation unit where its first non-inline, non-abstract
|
||||
virtual function is defined.
|
||||
|
||||
Classes that do not define the copy constructor will sometimes be
|
||||
passed and returned in registers. This may illuminate latent bugs in
|
||||
your code.
|
||||
|
||||
Support for automatic template instantiation has *NOT* been added, due
|
||||
to a disagreement over design philosophies.
|
||||
|
||||
Support for exception handling has been improved; more targets are now
|
||||
supported, and throws will use the RTTI mechanism to match against the
|
||||
catch parameter type. Optimization is NOT SUPPORTED with
|
||||
-fhandle-exceptions; no need to report this as a bug.
|
||||
|
||||
Support for Run-Time Type Identification has been added with -frtti.
|
||||
This support is still in alpha; one major restriction is that any file
|
||||
compiled with -frtti must include <typeinfo.h>.
|
||||
|
||||
Preliminary support for namespaces has been added. This support is far
|
||||
from complete, and probably not useful.
|
||||
|
||||
Synthesis of compiler-generated constructors, destructors and
|
||||
assignment operators is now deferred until the functions are used.
|
||||
|
||||
The parsing of expressions such as `a ? b : c = 1' has changed from
|
||||
`(a ? b : c) = 1' to `a : b ? (c = 1)'.
|
||||
|
||||
The code generated for testing conditions, especially those using ||
|
||||
and &&, is now more efficient.
|
||||
|
||||
The operator keywords and, and_eq, bitand, bitor, compl, not, not_eq,
|
||||
or, or_eq, xor and xor_eq are now supported. Use -ansi or
|
||||
-foperator-names to enable them.
|
||||
|
||||
The 'explicit' keyword is now supported. 'explicit' is used to mark
|
||||
constructors and type conversion operators that should not be used
|
||||
implicitly.
|
||||
|
||||
g++ now accepts the typename keyword, though it currently has no
|
||||
semantics; it can be a no-op in the current template implementation.
|
||||
You may want to start using it in your code, however, since the
|
||||
pending rewrite of the template implementation to compile STL properly
|
||||
(perhaps for 2.8.0, perhaps not) will require you to use it as
|
||||
indicated by the current draft.
|
||||
|
||||
Handling of user-defined type conversion has been overhauled so that
|
||||
type conversion operators are now found and used properly in
|
||||
expressions and function calls.
|
||||
|
||||
-fno-strict-prototype now only applies to function declarations with
|
||||
"C" linkage.
|
||||
|
||||
g++ now warns about 'if (x=0)' with -Wparentheses or -Wall.
|
||||
|
||||
#pragma weak and #pragma pack are supported on System V R4 targets, as
|
||||
are various other target-specific #pragmas supported by gcc.
|
||||
|
||||
new and delete of const types is now allowed (with no additional
|
||||
semantics).
|
||||
|
||||
Explicit instantiation of template methods is now supported. Also,
|
||||
'inline template class foo<int>;' can be used to emit only the vtable
|
||||
for a template class.
|
||||
|
||||
With -fcheck-new, g++ will check the return value of all calls to
|
||||
operator new, and not attempt to modify a returned null pointer.
|
||||
|
||||
The template instantiation code now handles more conversions when
|
||||
passing to a parameter that does not depend on template arguments.
|
||||
This means that code like 'string s; cout << s;' now works.
|
||||
|
||||
Invalid jumps in a switch statement past declarations that require
|
||||
initializations are now caught.
|
||||
|
||||
Functions declared 'extern inline' now have the same linkage semantics
|
||||
as inline member functions. On supported targets, where previously
|
||||
these functions (and vtables, and template instantiations) would have
|
||||
been defined statically, they will now be defined as weak symbols so
|
||||
that only one out-of-line definition is used.
|
||||
|
||||
collect2 now demangles linker output, and c++filt has become part of
|
||||
the gcc distribution.
|
||||
|
||||
Noteworthy changes in GCC version 2.6.3:
|
||||
|
||||
A few more bugs have been fixed.
|
||||
|
||||
Noteworthy changes in GCC version 2.6.2:
|
||||
|
||||
A few bugs have been fixed.
|
||||
|
||||
Names of attributes can now be preceded and followed by double underscores.
|
||||
|
||||
Noteworthy changes in GCC version 2.6.1:
|
||||
|
||||
Numerous (mostly minor) bugs have been fixed.
|
||||
|
||||
The following new configurations are supported:
|
||||
|
||||
GNU on x86 (instead of treating it like MACH)
|
||||
NetBSD on Sparc and Motorola 68k
|
||||
AIX 4.1 on RS/6000 and PowerPC systems
|
||||
Sequent DYNIX/ptx 1.x and 2.x.
|
||||
Both COFF and ELF configurations on AViiON without using /bin/gcc
|
||||
Windows/NT on x86 architecture; preliminary
|
||||
AT&T DSP1610 digital signal processor chips
|
||||
i960 systems on bare boards using COFF
|
||||
PDP11; target only and not extensively tested
|
||||
|
||||
The -pg option is now supported for Alpha under OSF/1 V3.0 or later.
|
||||
|
||||
Files with an extension of ".c++" are treated as C++ code.
|
||||
|
||||
The -Xlinker and -Wl arguments are now passed to the linker in the
|
||||
position they were specified on the command line. This makes it
|
||||
possible, for example, to pass flags to the linker about specific
|
||||
object files.
|
||||
|
||||
The use of positional arguments to the configure script is no longer
|
||||
recommended. Use --target= to specify the target; see the GCC manual.
|
||||
|
||||
The 386 now supports two new switches: -mreg-alloc=<string> changes
|
||||
the default register allocation order used by the compiler, and
|
||||
-mno-wide-multiply disables the use of the mul/imul instructions that
|
||||
produce 64 bit results in EAX:EDX from 32 bit operands to do long long
|
||||
multiplies and 32-bit division by constants.
|
||||
|
||||
Noteworthy changes in GCC version 2.6.0:
|
||||
|
||||
Numerous bugs have been fixed, in the C and C++ front-ends, as
|
||||
well as in the common compiler code.
|
||||
|
||||
This release includes the C, Objective-C, and C++ compilers. However,
|
||||
we have moved the files for the C++ compiler (G++) files to a
|
||||
subdirectory, cp. Subsequent releases of GCC will split these files
|
||||
to a separate TAR file.
|
||||
|
||||
The G++ team has been tracking the development of the ANSI standard for C++.
|
||||
Here are some new features added from the latest working paper:
|
||||
|
||||
* built-in boolean type 'bool', with constants 'true' and 'false'.
|
||||
* array new and delete (operator new [] and delete []).
|
||||
* WP-conforming lifetime of temporaries.
|
||||
* explicit instantiation of templates (template class A<int>;),
|
||||
along with an option (-fno-implicit-templates) to disable emission
|
||||
of implicitly instantiated templates, obsoletes -fexternal-templates.
|
||||
* static member constants (static const int foo = 4; within the
|
||||
class declaration).
|
||||
|
||||
Many error messages have been improved to tell the user more about the
|
||||
problem. Conformance checking with -pedantic-errors has been
|
||||
improved. G++ now compiles Fresco.
|
||||
|
||||
There is now an experimental implementation of virtual functions using
|
||||
thunks instead of Cfront-style vtables, enabled with -fvtable-thunks.
|
||||
This option also enables a heuristic which causes the compiler to only
|
||||
emit the vtable in the translation unit where its first non-inline
|
||||
virtual function is defined; using this option and
|
||||
-fno-implicit-templates, users should be able to avoid #pragma
|
||||
interface/implementation altogether.
|
||||
|
||||
Signatures have been added as a GNU C++ extension. Using the option
|
||||
-fhandle-signatures, users are able to turn on recognition of
|
||||
signatures. A short introduction on signatures is in the section
|
||||
`Extension to the C++ Language' in the manual.
|
||||
|
||||
The `g++' program is now a C program, rather than a shell script.
|
||||
|
||||
Lots and lots and lots of bugs fixes, in nested types, access control,
|
||||
pointers to member functions, the parser, templates, overload
|
||||
resolution, etc, etc.
|
||||
|
||||
There have been two major enhancements to the Objective-C compiler:
|
||||
|
||||
1) Added portability. It now runs on Alpha, and some problems with
|
||||
message forwarding have been addressed on other platforms.
|
||||
|
||||
2) Selectors have been redefined to be pointers to structs like:
|
||||
{ void *sel_id, char *sel_types }, where the sel_id is the unique
|
||||
identifier, the selector itself is no longer unique.
|
||||
|
||||
Programmers should use the new function sel_eq to test selector
|
||||
equivalence.
|
||||
|
||||
The following major changes have been made to the base compiler and
|
||||
machine-specific files.
|
||||
|
||||
- The MIL-STD-1750A is a new port, but still preliminary.
|
||||
|
||||
- The h8/300h is now supported; both the h8/300 and h8/300h ports come
|
||||
with 32 bit IEEE 754 software floating point support.
|
||||
|
||||
- The 64-bit Sparc (v9) and 64-bit MIPS chips are supported.
|
||||
|
||||
- NetBSD is supported on m68k, Intel x86, and pc523 systems and FreeBSD
|
||||
on x86.
|
||||
|
||||
- COFF is supported on x86, m68k, and Sparc systems running LynxOS.
|
||||
|
||||
- 68K systems from Bull and Concurrent are supported and System V
|
||||
Release 4 is supported on the Atari.
|
||||
|
||||
- GCC supports GAS on the Motorola 3300 (sysV68) and debugging
|
||||
(assuming GAS) on the Plexus 68K system. (However, GAS does not yet
|
||||
work on those systems).
|
||||
|
||||
- System V Release 4 is supported on MIPS (Tandem).
|
||||
|
||||
- For DG/UX, an ELF configuration is now supported, and both the ELF
|
||||
and BCS configurations support ELF and COFF object file formats.
|
||||
|
||||
- OSF/1 V2.0 is supported on Alpha.
|
||||
|
||||
- Function profiling is also supported on Alpha.
|
||||
|
||||
- GAS and GDB is supported for Irix 5 (MIPS).
|
||||
|
||||
- "common mode" (code that will run on both POWER and PowerPC
|
||||
architectures) is now supported for the RS/6000 family; the
|
||||
compiler knows about more PPC chips.
|
||||
|
||||
- Both NeXTStep 2.1 and 3 are supported on 68k-based architectures.
|
||||
|
||||
- On the AMD 29k, the -msoft-float is now supported, as well as
|
||||
-mno-sum-in-toc for RS/6000, -mapp-regs and -mflat for Sparc, and
|
||||
-membedded-pic for MIPS.
|
||||
|
||||
- GCC can now convert division by integer constants into the equivalent
|
||||
multiplication and shift operations when that is faster than the
|
||||
division.
|
||||
|
||||
- Two new warning options, -Wbad-function-cast and
|
||||
-Wmissing-declarations have been added.
|
||||
|
||||
- Configurations may now add machine-specific __attribute__ options on
|
||||
type; many machines support the `section' attribute.
|
||||
|
||||
- The -ffast-math flag permits some optimization that violate strict
|
||||
IEEE rules, such as converting X * 0.0 to 0.0.
|
||||
|
||||
Noteworthy changes in GCC version 2.5.8:
|
||||
|
||||
This release only fixes a few serious bugs. These include fixes for a
|
||||
bug that prevented most programs from working on the RS/6000, a bug
|
||||
that caused invalid assembler code for programs with a `switch'
|
||||
statement on the NS32K, a G++ problem that caused undefined names in
|
||||
some configurations, and several less serious problems, some of which
|
||||
can affect most configuration.
|
||||
|
||||
Noteworthy change in GCC version 2.5.7:
|
||||
|
||||
This release only fixes a few bugs, one of which was causing bootstrap
|
||||
compare errors on some systems.
|
||||
|
||||
Noteworthy change in GCC version 2.5.6:
|
||||
|
||||
A few backend bugs have been fixed, some of which only occur on one
|
||||
machine.
|
||||
|
||||
The C++ compiler in 2.5.6 includes:
|
||||
|
||||
* fixes for some common crashes
|
||||
* correct handling of nested types that are referenced as `foo::bar'
|
||||
* spurious warnings about friends being declared static and never
|
||||
defined should no longer appear
|
||||
* enums that are local to a method in a class, or a class that's
|
||||
local to a function, are now handled correctly. For example:
|
||||
class foo { void bar () { enum { x, y } E; x; } };
|
||||
void bar () { class foo { enum { x, y } E; E baz; }; }
|
||||
|
||||
Noteworthy change in GCC version 2.5.5:
|
||||
|
||||
A large number of C++ bugs have been fixed.
|
||||
|
||||
The fixproto script adds prototypes conditionally on __cplusplus.
|
||||
|
||||
Noteworthy change in GCC version 2.5.4:
|
||||
|
||||
A bug fix in passing of structure arguments for the HP-PA architecture
|
||||
makes code compiled with GCC 2.5.4 incompatible with code compiled
|
||||
with earlier versions (if it passes struct arguments of 33 to 64 bits,
|
||||
interspersed with other types of arguments).
|
||||
|
||||
Noteworthy change in gcc version 2.5.3:
|
||||
|
||||
The method of "mangling" C++ function names has been changed. So you
|
||||
must recompile all C++ programs completely when you start using GCC
|
||||
2.5. Also, GCC 2.5 requires libg++ version 2.5. Earlier libg++
|
||||
versions won't work with GCC 2.5. (This is generally true--GCC
|
||||
version M.N requires libg++ version M.N.)
|
||||
|
||||
Noteworthy GCC changes in version 2.5:
|
||||
|
||||
* There is now support for the IBM 370 architecture as a target.
|
||||
Currently the only operating system supported is MVS; GCC does not run
|
||||
on MVS, so you must produce .s files using GCC as a cross compiler,
|
||||
then transfer them to MVS to assemble them. This port is not reliable
|
||||
yet.
|
||||
|
||||
* The Power PC is now supported.
|
||||
|
||||
* The i860-based Paragon machine is now supported.
|
||||
|
||||
* The Hitachi 3050 (an HP-PA machine) is now supported.
|
||||
|
||||
* The variable __GNUC_MINOR__ holds the minor version number of GCC, as
|
||||
an integer. For version 2.5.X, the value is 5.
|
||||
|
||||
* In C, initializers for static and global variables are now processed
|
||||
an element at a time, so that they don't need a lot of storage.
|
||||
|
||||
* The C syntax for specifying which structure field comes next in an
|
||||
initializer is now `.FIELDNAME='. The corresponding syntax for
|
||||
array initializers is now `[INDEX]='. For example,
|
||||
|
||||
char whitespace[256]
|
||||
= { [' '] = 1, ['\t'] = 1, ['\n'] = 1 };
|
||||
|
||||
This was changed to accord with the syntax proposed by the Numerical
|
||||
C Extensions Group (NCEG).
|
||||
|
||||
* Complex numbers are now supported in C. Use the keyword __complex__
|
||||
to declare complex data types. See the manual for details.
|
||||
|
||||
* GCC now supports `long double' meaningfully on the Sparc (128-bit
|
||||
floating point) and on the 386 (96-bit floating point). The Sparc
|
||||
support is enabled on on Solaris 2.x because earlier system versions
|
||||
(SunOS 4) have bugs in the emulation.
|
||||
|
||||
* All targets now have assertions for cpu, machine and system. So you
|
||||
can now use assertions to distinguish among all supported targets.
|
||||
|
||||
* Nested functions in C may now be inline. Just declare them inline
|
||||
in the usual way.
|
||||
|
||||
* Packed structure members are now supported fully; it should be possible
|
||||
to access them on any supported target, no matter how little alignment
|
||||
they have.
|
||||
|
||||
* To declare that a function does not return, you must now write
|
||||
something like this (works only in 2.5):
|
||||
|
||||
void fatal () __attribute__ ((noreturn));
|
||||
|
||||
or like this (works in older versions too):
|
||||
|
||||
typedef void voidfn ();
|
||||
|
||||
volatile voidfn fatal;
|
||||
|
||||
It used to be possible to do so by writing this:
|
||||
|
||||
volatile void fatal ();
|
||||
|
||||
but it turns out that ANSI C requires that to mean something
|
||||
else (which is useless).
|
||||
|
||||
Likewise, to declare that a function is side-effect-free
|
||||
so that calls may be deleted or combined, write
|
||||
something like this (works only in 2.5):
|
||||
|
||||
int computation () __attribute__ ((const));
|
||||
|
||||
or like this (works in older versions too):
|
||||
|
||||
typedef int intfn ();
|
||||
|
||||
const intfn computation;
|
||||
|
||||
* The new option -iwithprefixbefore specifies a directory to add to
|
||||
the search path for include files in the same position where -I would
|
||||
put it, but uses the specified prefix just like -iwithprefix.
|
||||
|
||||
* Basic block profiling has been enhanced to record the function the
|
||||
basic block comes from, and if the module was compiled for debugging,
|
||||
the line number and filename. A default version of the basic block
|
||||
support module has been added to libgcc2 that appends the basic block
|
||||
information to a text file 'bb.out'. Machine descriptions can now
|
||||
override the basic block support module in the target macro file.
|
||||
|
||||
New features in g++:
|
||||
|
||||
* The new flag `-fansi-overloading' for C++. Use a newly implemented
|
||||
scheme of argument matching for C++. It makes g++ more accurately
|
||||
obey the rules set down in Chapter 13 of the Annotated C++ Reference
|
||||
Manual (the ARM). This option will be turned on by default in a
|
||||
future release.
|
||||
|
||||
* The -finline-debug flag is now gone (it was never really used by the
|
||||
compiler).
|
||||
|
||||
* Recognizing the syntax for pointers to members, e.g., "foo::*bar", has been
|
||||
dramatically improved. You should not get any syntax errors or incorrect
|
||||
runtime results while using pointers to members correctly; if you do, it's
|
||||
a definite bug.
|
||||
|
||||
* Forward declaration of an enum is now flagged as an error.
|
||||
|
||||
* Class-local typedefs are now working properly.
|
||||
|
||||
* Nested class support has been significantly improved. The compiler
|
||||
will now (in theory) support up to 240 nested classes before hitting
|
||||
other system limits (like memory size).
|
||||
|
||||
* There is a new C version of the `g++' driver, to replace the old
|
||||
shell script. This should significantly improve the performance of
|
||||
executing g++ on a system where a user's PATH environment variable
|
||||
references many NFS-mounted filesystems. This driver also works
|
||||
under MS-DOS and OS/2.
|
||||
|
||||
* The ANSI committee working on the C++ standard has adopted a new
|
||||
keyword `mutable'. This will allow you to make a specific member be
|
||||
modifiable in an otherwise const class.
|
||||
|
||||
Noteworthy GCC changes in version 2.4.4:
|
||||
|
||||
A crash building g++ on various hosts (including m68k) has been
|
||||
fixed. Also the g++ compiler no longer reports incorrect
|
||||
ambiguities in some situations where they do not exist, and
|
||||
const template member functions are now being found properly.
|
||||
|
||||
Noteworthy GCC changes in version 2.4:
|
||||
|
||||
* On each target, the default is now to return short structures
|
||||
compatibly with the "usual" compiler on that target.
|
||||
|
||||
For most targets, this means the default is to return all structures
|
||||
in memory, like long structures, in whatever way is used on that
|
||||
target. Use -freg-struct-return to enable returning short structures
|
||||
(and unions) in registers.
|
||||
|
||||
This change means that newly compiled binaries are incompatible with
|
||||
binaries compiled with previous versions of GCC.
|
||||
|
||||
On some targets, GCC is itself the usual compiler. On these targets,
|
||||
the default way to return short structures is still in registers.
|
||||
Use -fpcc-struct-return to tell GCC to return them in memory.
|
||||
|
||||
* There is now a floating point emulator which can imitate the way all
|
||||
supported target machines do floating point arithmetic.
|
||||
|
||||
This makes it possible to have cross compilation to and from the VAX,
|
||||
and between machines of different endianness. However, this works
|
||||
only when the target machine description is updated to use the new
|
||||
facilities, and not all have been updated.
|
||||
|
||||
This also makes possible support for longer floating point types.
|
||||
GCC 2.4 supports extended format on the 68K if you use `long double',
|
||||
for targets that have a 68881. (When we have run time library
|
||||
routines for extended floating point, then `long double' will use
|
||||
extended format on all 68K targets.)
|
||||
|
||||
We expect to support extended floating point on the i386 and Sparc in
|
||||
future versions.
|
||||
|
||||
* Building GCC now automatically fixes the system's header files.
|
||||
This should require no attention.
|
||||
|
||||
* GCC now installs an unsigned data type as size_t when it fixes the
|
||||
header files (on all but a handful of old target machines).
|
||||
Therefore, the bug that size_t failed to be unsigned is fixed.
|
||||
|
||||
* Building and installation are now completely separate.
|
||||
All new files are constructed during the build process;
|
||||
installation just copies them.
|
||||
|
||||
* New targets supported: Clipper, Hitachi SH, Hitachi 8300, and Sparc
|
||||
Lite.
|
||||
|
||||
* A totally new and much better Objective C run time system is included.
|
||||
|
||||
* Objective C supports many new features. Alas, I can't describe them
|
||||
since I don't use that language; however, they are the same ones
|
||||
supported in recent versions of the NeXT operating system.
|
||||
|
||||
* The builtin functions __builtin_apply_args, __builtin_apply and
|
||||
__builtin_return let you record the arguments and returned
|
||||
value of a function without knowing their number or type.
|
||||
|
||||
* The builtin string variables __FUNCTION__ and __PRETTY_FUNCTION__
|
||||
give the name of the function in the source, and a pretty-printed
|
||||
version of the name. The two are the same in C, but differ in C++.
|
||||
|
||||
* Casts to union types do not yield lvalues.
|
||||
|
||||
* ## before an empty rest argument discards the preceding sequence
|
||||
of non-whitespace characters from the macro definition.
|
||||
(This feature is subject to change.)
|
||||
|
||||
|
||||
New features specific to C++:
|
||||
|
||||
* The manual contains a new section ``Common Misunderstandings with
|
||||
GNU C++'' that C++ users should read.
|
||||
|
||||
* #pragma interface and #pragma implementation let you use the same
|
||||
C++ source file for both interface and implementation.
|
||||
However, this mechanism is still in transition.
|
||||
|
||||
* Named returned values let you avoid an extra constructor call
|
||||
when a function result has a class type.
|
||||
|
||||
* The C++ operators <? and >? yield min and max, respectively.
|
||||
|
||||
* C++ gotos can exit a block safely even if the block has
|
||||
aggregates that require destructors.
|
||||
|
||||
* gcc defines the macro __GNUG__ when compiling C++ programs.
|
||||
|
||||
* GNU C++ now correctly distinguishes between the prefix and postfix
|
||||
forms of overloaded operator ++ and --. To avoid breaking old
|
||||
code, if a class defines only the prefix form, the compiler
|
||||
accepts either ++obj or obj++, unless -pedantic is used.
|
||||
|
||||
* If you are using version 2.3 of libg++, you need to rebuild it with
|
||||
`make CC=gcc' to avoid mismatches in the definition of `size_t'.
|
||||
|
||||
Newly documented compiler options:
|
||||
|
||||
-fnostartfiles
|
||||
Omit the standard system startup files when linking.
|
||||
|
||||
-fvolatile-global
|
||||
Consider memory references to extern and global data items to
|
||||
be volatile.
|
||||
|
||||
-idirafter DIR
|
||||
Add DIR to the second include path.
|
||||
|
||||
-iprefix PREFIX
|
||||
Specify PREFIX for later -iwithprefix options.
|
||||
|
||||
-iwithprefix DIR
|
||||
Add PREFIX/DIR to the second include path.
|
||||
|
||||
-mv8
|
||||
Emit Sparc v8 code (with integer multiply and divide).
|
||||
-msparclite
|
||||
Emit Sparclite code (roughly v7.5).
|
||||
|
||||
-print-libgcc-file-name
|
||||
Search for the libgcc.a file, print its absolute file name, and exit.
|
||||
|
||||
-Woverloaded-virtual
|
||||
Warn when a derived class function declaration may be an error
|
||||
in defining a C++ virtual function.
|
||||
|
||||
-Wtemplate-debugging
|
||||
When using templates in a C++ program, warn if debugging is
|
||||
not yet fully available.
|
||||
|
||||
+eN
|
||||
Control how C++ virtual function definitions are used
|
||||
(like cfront 1.x).
|
||||
|
117
PROBLEMS
Normal file
117
PROBLEMS
Normal file
@ -0,0 +1,117 @@
|
||||
3. When find_reloads is used to count number of spills needed
|
||||
it does not take into account the fact that a reload may
|
||||
turn out to be a dummy.
|
||||
|
||||
I'm not sure this really happens any more. Doesn't it find
|
||||
all the dummies on both passes?
|
||||
|
||||
10. movl a3@,a0
|
||||
movl a3@(16),a1
|
||||
clrb a0@(a1:l)
|
||||
is generated and may be worse than
|
||||
movl a3@,a0
|
||||
addl a3@(16),a0
|
||||
clrb a0@
|
||||
If ordering of operands is improved, many more
|
||||
such cases will be generated from typical array accesses.
|
||||
|
||||
38. Hack expand_mult so that if there is no same-modes multiply
|
||||
it will use a widening multiply and then truncate rather than
|
||||
calling the library.
|
||||
|
||||
39. Hack expanding of division to notice cases for
|
||||
long -> short division.
|
||||
|
||||
40. Represent divide insns as (DIV:SI ...) followed by
|
||||
a separate lowpart extract. Represent remainder insns as DIV:SI
|
||||
followed by a separate highpart extract. Then cse can work on
|
||||
the DIV:SI part. Problem is, this may not be desirable on machines
|
||||
where computing the quotient alone does not necessarily give
|
||||
a remainder--such as the 68020 for long operands.
|
||||
|
||||
52. Reloading can look at how reload_contents got set up.
|
||||
If it was copied from a register, just reload from that register.
|
||||
Otherwise, perhaps can change the previous insn to move the
|
||||
data via the reload reg, thus avoiding one memory ref.
|
||||
|
||||
63. Potential problem in cc_status.value2, if it ever activates itself
|
||||
after a two-address subtraction (which currently cannot happen).
|
||||
It is supposed to compare the current value of the destination
|
||||
but eliminating it would use the results of the subtraction, equivalent
|
||||
to comparing the previous value of the destination.
|
||||
|
||||
65. Should loops that neither start nor end with a break
|
||||
be rearranged to end with the last break?
|
||||
|
||||
69. Define the floating point converting arithmetic instructions
|
||||
for the 68881.
|
||||
|
||||
74. Combine loop opt with cse opt in one pass. Do cse on each loop,
|
||||
then loop opt on that loop, and go from innermost loops outward.
|
||||
Make loop invariants available for cse at end of loop.
|
||||
|
||||
85. pea can force a value to be reloaded into an areg
|
||||
which can make it worse than separate adding and pushing.
|
||||
This can only happen for adding something within addql range
|
||||
and it only loses if the qty becomes dead at that point
|
||||
so it can be added to with no copying.
|
||||
|
||||
93. If a pseudo doesn't get a hard reg everywhere,
|
||||
can it get one during a loop?
|
||||
|
||||
96. Can do SImode bitfield insns without reloading, but must
|
||||
alter the operands in special ways.
|
||||
|
||||
99. final could check loop-entry branches to see if they
|
||||
screw up deletion of a test instruction. If they do,
|
||||
can put another test instruction before the branch and
|
||||
make it conditional and redirect it.
|
||||
|
||||
106. Aliasing may be impossible if data types of refs differ
|
||||
and data type of containing objects also differ.
|
||||
(But check this wrt unions.)
|
||||
|
||||
108. Can speed up flow analysis by making a table saying which
|
||||
register is set and which registers are used by each instruction that
|
||||
only sets one register and only uses two. This way avoid the tree
|
||||
walk for such instructions (most instructions).
|
||||
|
||||
109. It is desirable to avoid converting INDEX to SImode if a
|
||||
narrower mode suffices, as HImode does on the 68000.
|
||||
How can this be done?
|
||||
|
||||
110. Possible special combination pattern:
|
||||
If the two operands to a comparison die there and both come from insns
|
||||
that are identical except for replacing one operand with the other,
|
||||
throw away those insns. Ok if insns being discarded are known 1 to 1.
|
||||
An andl #1 after a seq is 1 to 1, but how should compiler know that?
|
||||
|
||||
112. Can convert float to unsigned int by subtracting a constant,
|
||||
converting to signed int, and changing the sign bit.
|
||||
|
||||
117. Any number of slow zero-extensions in one loop, that have
|
||||
their clr insns moved out of the loop, can share one register
|
||||
if their original life spans are disjoint.
|
||||
But it may be hard to be sure of this since
|
||||
the life span data that regscan produces may be hard to interpret
|
||||
validly or may be incorrect after cse.
|
||||
|
||||
118. In cse, when a bfext insn refers to a register, if the field
|
||||
corresponds to a halfword or a byte and the register is equivalent
|
||||
to a memory location, it would be possible to detect this and
|
||||
replace it with a simple memory reference.
|
||||
|
||||
121. Insns that store two values cannot be moved out of loops.
|
||||
The code in scan_loop doesn't even try to deal with them.
|
||||
|
||||
122. When insn-output.c turns a bit-test into a sign-test,
|
||||
it should see whether the cc is already set up with that sign.
|
||||
|
||||
123. When a conditional expression is used as a function arg, it would
|
||||
be faster (and in some cases shorter) to push each alternative rather
|
||||
than compute in a register and push that. This would require
|
||||
being able to specify "push this" as a target for expand_expr.
|
||||
|
||||
124. On the 386, bad code results from foo (bar ()) when bar
|
||||
returns a double, because the pseudo used fails to get preferenced
|
||||
into an fp reg because of the distinction between regs 8 and 9.
|
448
PROJECTS
Normal file
448
PROJECTS
Normal file
@ -0,0 +1,448 @@
|
||||
0. Improved efficiency.
|
||||
|
||||
* Parse and output array initializers an element at a time, freeing
|
||||
storage after each, instead of parsing the whole initializer first and
|
||||
then outputting. This would reduce memory usage for large
|
||||
initializers.
|
||||
|
||||
* See if the techniques describe in Oct 1991 SIGPLAN Notices
|
||||
(Frazer and Hanson) are applicable to GCC.
|
||||
|
||||
1. Better optimization.
|
||||
|
||||
* Constants in unused inline functions
|
||||
|
||||
It would be nice to delay output of string constants so that string
|
||||
constants mentioned in unused inline functions are never generated.
|
||||
Perhaps this would also take care of string constants in dead code.
|
||||
|
||||
The difficulty is in finding a clean way for the RTL which refers
|
||||
to the constant (currently, only by an assembler symbol name)
|
||||
to point to the constant and cause it to be output.
|
||||
|
||||
* More cse
|
||||
|
||||
The techniques for doing full global cse are described in the red
|
||||
dragon book, or (a different version) in Frederick Chow's thesis from
|
||||
Stanford. It is likely to be slow and use a lot of memory, but it
|
||||
might be worth offering as an additional option.
|
||||
|
||||
It is probably possible to extend cse to a few very frequent cases
|
||||
without so much expense.
|
||||
|
||||
For example, it is not very hard to handle cse through if-then
|
||||
statements with no else clauses. Here's how to do it. On reaching a
|
||||
label, notice that the label's use-count is 1 and that the last
|
||||
preceding jump jumps conditionally to this label. Now you know it
|
||||
is a simple if-then statement. Remove from the hash table
|
||||
all the expressions that were entered since that jump insn
|
||||
and you can continue with cse.
|
||||
|
||||
It is probably not hard to handle cse from the end of a loop
|
||||
around to the beginning, and a few loops would be greatly sped
|
||||
up by this.
|
||||
|
||||
* Optimize a sequence of if statements whose conditions are exclusive.
|
||||
|
||||
It is possible to optimize
|
||||
|
||||
if (x == 1) ...;
|
||||
if (x == 2) ...;
|
||||
if (x == 3) ...;
|
||||
|
||||
into
|
||||
|
||||
if (x == 1) ...;
|
||||
else if (x == 2) ...;
|
||||
else if (x == 3) ...;
|
||||
|
||||
provided that x is not altered by the contents of the if statements.
|
||||
|
||||
It's not certain whether this is worth doing. Perhaps programmers
|
||||
nearly always write the else's themselves, leaving few opportunities
|
||||
to improve anything.
|
||||
|
||||
* Un-cse.
|
||||
|
||||
Perhaps we should have an un-cse step right after cse, which tries to
|
||||
replace a reg with its value if the value can be substituted for the
|
||||
reg everywhere, if that looks like an improvement. Which is if the
|
||||
reg is used only a few times. Use rtx_cost to determine if the
|
||||
change is really an improvement.
|
||||
|
||||
* Clean up how cse works.
|
||||
|
||||
The scheme is that each value has just one hash entry. The
|
||||
first_same_value and next_same_value chains are no longer needed.
|
||||
|
||||
For arithmetic, each hash table elt has the following slots:
|
||||
|
||||
* Operation. This is an rtx code.
|
||||
* Mode.
|
||||
* Operands 0, 1 and 2. These point to other hash table elements.
|
||||
|
||||
So, if we want to enter (PLUS:SI (REG:SI 30) (CONST_INT 104)), we
|
||||
first enter (CONST_INT 104) and find the entry that (REG:SI 30) now
|
||||
points to. Then we put these elts into operands 0 and 1 of a new elt.
|
||||
We put PLUS and SI into the new elt.
|
||||
|
||||
Registers and mem refs would never be entered into the table as such.
|
||||
However, the values they contain would be entered. There would be a
|
||||
table indexed by regno which points at the hash entry for the value in
|
||||
that reg.
|
||||
|
||||
The hash entry index now plays the role of a qty number.
|
||||
We still need qty_first_reg, reg_next_eqv, etc. to record which regs
|
||||
share a particular qty.
|
||||
|
||||
When a reg is used whose contents are unknown, we need to create a
|
||||
hash table entry whose contents say "unknown", as a place holder for
|
||||
whatever the reg contains. If that reg is added to something, then
|
||||
the hash entry for the sum will refer to the "unknown" entry. Use
|
||||
UNKNOWN for the rtx code in this entry. This replaces make_new_qty.
|
||||
|
||||
For a constant, a unique hash entry would be made based on the
|
||||
value of the constant.
|
||||
|
||||
What about MEM? Each time a memory address is referenced, we need a
|
||||
qty (a hash table elt) to represent what is in it. (Just as for a
|
||||
register.) If this isn't known, create one, just as for a reg whose
|
||||
contents are unknown.
|
||||
|
||||
We need a way to find all mem refs that still contain a certain value.
|
||||
Do this with a chain of hash elts (for memory addresses) that point to
|
||||
locations that hold the value. The hash elt for the value itself should
|
||||
point to the start of the chain. It would be good for the hash elt
|
||||
for an address to point to the hash elt for the contents of that address
|
||||
(but this ptr can be null if the contents have never been entered).
|
||||
|
||||
With this data structure, nothing need ever be invalidated except
|
||||
the lists of which regs or mems hold a particular value. It is easy
|
||||
to see if there is a reg or mem that is equiv to a particular value.
|
||||
If the value is constant, it is always explicitly constant.
|
||||
|
||||
* Support more general tail-recursion among different functions.
|
||||
|
||||
This might be possible under certain circumstances, such as when
|
||||
the argument lists of the functions have the same lengths.
|
||||
Perhaps it could be done with a special declaration.
|
||||
|
||||
You would need to verify in the calling function that it does not
|
||||
use the addresses of any local variables and does not use setjmp.
|
||||
|
||||
* Put short statics vars at low addresses and use short addressing mode?
|
||||
|
||||
Useful on the 68000/68020 and perhaps on the 32000 series,
|
||||
provided one has a linker that works with the feature.
|
||||
This is said to make a 15% speedup on the 68000.
|
||||
|
||||
* Keep global variables in registers.
|
||||
|
||||
Here is a scheme for doing this. A global variable, or a local variable
|
||||
whose address is taken, can be kept in a register for an entire function
|
||||
if it does not use non-constant memory addresses and (for globals only)
|
||||
does not call other functions. If the entire function does not meet
|
||||
this criterion, a loop may.
|
||||
|
||||
The VAR_DECL for such a variable would have to have two RTL expressions:
|
||||
the true home in memory, and the pseudo-register used temporarily.
|
||||
It is necessary to emit insns to copy the memory location into the
|
||||
pseudo-register at the beginning of the function or loop, and perhaps
|
||||
back out at the end. These insns should have REG_EQUIV notes so that,
|
||||
if the pseudo-register does not get a hard register, it is spilled into
|
||||
the memory location which exists in any case.
|
||||
|
||||
The easiest way to set up these insns is to modify the routine
|
||||
put_var_into_stack so that it does not apply to the entire function
|
||||
(sparing any loops which contain nothing dangerous) and to call it at
|
||||
the end of the function regardless of where in the function the
|
||||
address of a local variable is taken. It would be called
|
||||
unconditionally at the end of the function for all relevant global
|
||||
variables.
|
||||
|
||||
For debugger output, the thing to do is to invent a new binding level
|
||||
around the appropriate loop and define the variable name as a register
|
||||
variable with that scope.
|
||||
|
||||
* Live-range splitting.
|
||||
|
||||
Currently a variable is allocated a hard register either for the full
|
||||
extent of its use or not at all. Sometimes it would be good to
|
||||
allocate a variable a hard register for just part of a function; for
|
||||
example, through a particular loop where the variable is mostly used,
|
||||
or outside of a particular loop where the variable is not used. (The
|
||||
latter is nice because it might let the variable be in a register most
|
||||
of the time even though the loop needs all the registers.)
|
||||
|
||||
It might not be very hard to do this in global.c when a variable
|
||||
fails to get a hard register for its entire life span.
|
||||
|
||||
The first step is to find a loop in which the variable is live, but
|
||||
which is not the whole life span or nearly so. It's probably best to
|
||||
use a loop in which the variable is heavily used.
|
||||
|
||||
Then create a new pseudo-register to represent the variable in that loop.
|
||||
Substitute this for the old pseudo-register there, and insert move insns
|
||||
to copy between the two at the loop entry and all exits. (When several
|
||||
such moves are inserted at the same place, some new feature should be
|
||||
added to say that none of those registers conflict merely because of
|
||||
overlap between the new moves. And the reload pass should reorder them
|
||||
so that a store precedes a load, for any given hard register.)
|
||||
|
||||
After doing this for all the reasonable candidates, run global-alloc
|
||||
over again. With luck, one of the two pseudo-registers will be fit
|
||||
somewhere. It may even have a much higher priority due to its reduced
|
||||
life span.
|
||||
|
||||
There will be no room in general for the new pseudo-registers in
|
||||
basic_block_live_at_start, so there will need to be a second such
|
||||
matrix exclusively for the new ones. Various other vectors indexed by
|
||||
register number will have to be made bigger, or there will have to be
|
||||
secondary extender vectors just for global-alloc.
|
||||
|
||||
A simple new feature could arrange that both pseudo-registers get the
|
||||
same stack slot if they both fail to get hard registers.
|
||||
|
||||
Other compilers split live ranges when they are not connected, or
|
||||
try to split off pieces `at the edge'. I think splitting around loops
|
||||
will provide more speedup.
|
||||
|
||||
Creating a fake binding block and a new like-named variable with
|
||||
shorter life span and different address might succeed in describing
|
||||
this technique for the debugger.
|
||||
|
||||
* Detect dead stores into memory?
|
||||
|
||||
A store into memory is dead if it is followed by another store into
|
||||
the same location; and, in between, there is no reference to anything
|
||||
that might be that location (including no reference to a variable
|
||||
address).
|
||||
|
||||
* Loop optimization.
|
||||
|
||||
Strength reduction and iteration variable elimination could be
|
||||
smarter. They should know how to decide which iteration variables are
|
||||
not worth making explicit because they can be computed as part of an
|
||||
address calculation. Based on this information, they should decide
|
||||
when it is desirable to eliminate one iteration variable and create
|
||||
another in its place.
|
||||
|
||||
It should be possible to compute what the value of an iteration
|
||||
variable will be at the end of the loop, and eliminate the variable
|
||||
within the loop by computing that value at the loop end.
|
||||
|
||||
When a loop has a simple increment that adds 1,
|
||||
instead of jumping in after the increment,
|
||||
decrement the loop count and jump to the increment.
|
||||
This allows aob insns to be used.
|
||||
|
||||
* Using constraints on values.
|
||||
|
||||
Many operations could be simplified based on knowledge of the
|
||||
minimum and maximum possible values of a register at any particular time.
|
||||
These limits could come from the data types in the tree, via rtl generation,
|
||||
or they can be deduced from operations that are performed. For example,
|
||||
the result of an `and' operation one of whose operands is 7 must be in
|
||||
the range 0 to 7. Compare instructions also tell something about the
|
||||
possible values of the operand, in the code beyond the test.
|
||||
|
||||
Value constraints can be used to determine the results of a further
|
||||
comparison. They can also indicate that certain `and' operations are
|
||||
redundant. Constraints might permit a decrement and branch
|
||||
instruction that checks zeroness to be used when the user has
|
||||
specified to exit if negative.
|
||||
|
||||
* Smarter reload pass.
|
||||
|
||||
The reload pass as currently written can reload values only into registers
|
||||
that are reserved for reloading. This means that in order to use a
|
||||
register for reloading it must spill everything out of that register.
|
||||
|
||||
It would be straightforward, though complicated, for reload1.c to keep
|
||||
track, during its scan, of which hard registers were available at each
|
||||
point in the function, and use for reloading even registers that were
|
||||
free only at the point they were needed. This would avoid much spilling
|
||||
and make better code.
|
||||
|
||||
* Change the type of a variable.
|
||||
|
||||
Sometimes a variable is declared as `int', it is assigned only once
|
||||
from a value of type `char', and then it is used only by comparison
|
||||
against constants. On many machines, better code would result if
|
||||
the variable had type `char'. If the compiler could detect this
|
||||
case, it could change the declaration of the variable and change
|
||||
all the places that use it.
|
||||
|
||||
* Better handling for very sparse switches.
|
||||
|
||||
There may be cases where it would be better to compile a switch
|
||||
statement to use a fixed hash table rather than the current
|
||||
combination of jump tables and binary search.
|
||||
|
||||
* Order of subexpressions.
|
||||
|
||||
It might be possible to make better code by paying attention
|
||||
to the order in which to generate code for subexpressions of an expression.
|
||||
|
||||
* More code motion.
|
||||
|
||||
Consider hoisting common code up past conditional branches or
|
||||
tablejumps.
|
||||
|
||||
* Trace scheduling.
|
||||
|
||||
This technique is said to be able to figure out which way a jump
|
||||
will usually go, and rearrange the code to make that path the
|
||||
faster one.
|
||||
|
||||
* Distributive law.
|
||||
|
||||
The C expression *(X + 4 * (Y + C)) compiles better on certain
|
||||
machines if rewritten as *(X + 4*C + 4*Y) because of known addressing
|
||||
modes. It may be tricky to determine when, and for which machines, to
|
||||
use each alternative.
|
||||
|
||||
Some work has been done on this, in combine.c.
|
||||
|
||||
* Can optimize by changing if (x) y; else z; into z; if (x) y;
|
||||
if z and x do not interfere and z has no effects not undone by y.
|
||||
This is desirable if z is faster than jumping.
|
||||
|
||||
* For a two-insn loop on the 68020, such as
|
||||
foo: movb a2@+,a3@+
|
||||
jne foo
|
||||
it is better to insert dbeq d0,foo before the jne.
|
||||
d0 can be a junk register. The challenge is to fit this into
|
||||
a portable framework: when can you detect this situation and
|
||||
still be able to allocate a junk register?
|
||||
|
||||
2. Simpler porting.
|
||||
|
||||
Right now, describing the target machine's instructions is done
|
||||
cleanly, but describing its addressing mode is done with several
|
||||
ad-hoc macro definitions. Porting would be much easier if there were
|
||||
an RTL description for addressing modes like that for instructions.
|
||||
Tools analogous to genflags and genrecog would generate macros from
|
||||
this description.
|
||||
|
||||
There would be one pattern in the address-description file for each
|
||||
kind of addressing, and this pattern would have:
|
||||
|
||||
* the RTL expression for the address
|
||||
* C code to verify its validity (since that may depend on
|
||||
the exact data).
|
||||
* C code to print the address in assembler language.
|
||||
* C code to convert the address into a valid one, if it is not valid.
|
||||
(This would replace LEGITIMIZE_ADDRESS).
|
||||
* Register constraints for all indeterminates that appear
|
||||
in the RTL expression.
|
||||
|
||||
3. Other languages.
|
||||
|
||||
Front ends for Pascal, Fortran, Algol, Cobol, Modula-2 and Ada are
|
||||
desirable.
|
||||
|
||||
Pascal, Modula-2 and Ada require the implementation of functions
|
||||
within functions. Some of the mechanisms for this already exist.
|
||||
|
||||
4. More extensions.
|
||||
|
||||
* Generated unique labels. Have some way of generating distinct labels
|
||||
for use in extended asm statements. I don't know what a good syntax would
|
||||
be.
|
||||
|
||||
* A way of defining a structure containing a union, in which the choice of
|
||||
union alternative is controlled by a previous structure component.
|
||||
|
||||
Here is a possible syntax for this.
|
||||
|
||||
struct foo {
|
||||
enum { INT, DOUBLE } code;
|
||||
auto union { case INT: int i; case DOUBLE: double d;} value : code;
|
||||
};
|
||||
|
||||
* Allow constructor expressions as lvalues, like this:
|
||||
|
||||
(struct foo) {a, b, c} = foo();
|
||||
|
||||
This would call foo, which returns a structure, and then store the
|
||||
several components of the structure into the variables a, b, and c.
|
||||
|
||||
5. Generalize the machine model.
|
||||
|
||||
* Some new compiler features may be needed to do a good job on machines
|
||||
where static data needs to be addressed using base registers.
|
||||
|
||||
* Some machines have two stacks in different areas of memory, one used
|
||||
for scalars and another for large objects. The compiler does not
|
||||
now have a way to understand this.
|
||||
|
||||
6. Useful warnings.
|
||||
|
||||
* Warn about statements that are undefined because the order of
|
||||
evaluation of increment operators makes a big difference. Here is an
|
||||
example:
|
||||
|
||||
*foo++ = hack (*foo);
|
||||
|
||||
7. Better documentation of how GCC works and how to port it.
|
||||
|
||||
Here is an outline proposed by Allan Adler.
|
||||
|
||||
I. Overview of this document
|
||||
II. The machines on which GCC is implemented
|
||||
A. Prose description of those characteristics of target machines and
|
||||
their operating systems which are pertinent to the implementation
|
||||
of GCC.
|
||||
i. target machine characteristics
|
||||
ii. comparison of this system of machine characteristics with
|
||||
other systems of machine specification currently in use
|
||||
B. Tables of the characteristics of the target machines on which
|
||||
GCC is implemented.
|
||||
C. A priori restrictions on the values of characteristics of target
|
||||
machines, with special reference to those parts of the source code
|
||||
which entail those restrictions
|
||||
i. restrictions on individual characteristics
|
||||
ii. restrictions involving relations between various characteristics
|
||||
D. The use of GCC as a cross-compiler
|
||||
i. cross-compilation to existing machines
|
||||
ii. cross-compilation to non-existent machines
|
||||
E. Assumptions which are made regarding the target machine
|
||||
i. assumptions regarding the architecture of the target machine
|
||||
ii. assumptions regarding the operating system of the target machine
|
||||
iii. assumptions regarding software resident on the target machine
|
||||
iv. where in the source code these assumptions are in effect made
|
||||
III. A systematic approach to writing the files tm.h and xm.h
|
||||
A. Macros which require special care or skill
|
||||
B. Examples, with special reference to the underlying reasoning
|
||||
IV. A systematic approach to writing the machine description file md
|
||||
A. Minimal viable sets of insn descriptions
|
||||
B. Examples, with special reference to the underlying reasoning
|
||||
V. Uses of the file aux-output.c
|
||||
VI. Specification of what constitutes correct performance of an
|
||||
implementation of GCC
|
||||
A. The components of GCC
|
||||
B. The itinerary of a C program through GCC
|
||||
C. A system of benchmark programs
|
||||
D. What your RTL and assembler should look like with these benchmarks
|
||||
E. Fine tuning for speed and size of compiled code
|
||||
VII. A systematic procedure for debugging an implementation of GCC
|
||||
A. Use of GDB
|
||||
i. the macros in the file .gdbinit for GCC
|
||||
ii. obstacles to the use of GDB
|
||||
a. functions implemented as macros can't be called in GDB
|
||||
B. Debugging without GDB
|
||||
i. How to turn off the normal operation of GCC and access specific
|
||||
parts of GCC
|
||||
C. Debugging tools
|
||||
D. Debugging the parser
|
||||
i. how machine macros and insn definitions affect the parser
|
||||
E. Debugging the recognizer
|
||||
i. how machine macros and insn definitions affect the recognizer
|
||||
|
||||
ditto for other components
|
||||
|
||||
VIII. Data types used by GCC, with special reference to restrictions not
|
||||
specified in the formal definition of the data type
|
||||
IX. References to the literature for the algorithms used in GCC
|
||||
|
26
README
Normal file
26
README
Normal file
@ -0,0 +1,26 @@
|
||||
This directory contains the version 2.8.1 release of the GNU C
|
||||
compiler. It includes all of the support for compiling C++ and
|
||||
Objective C, including a run-time library for Objective C.
|
||||
|
||||
The GNU C compiler is free software. See the file COPYING for copying
|
||||
permission.
|
||||
|
||||
See the file gcc.texi (together with other files that it includes) for
|
||||
installation and porting information. The file INSTALL contains a
|
||||
copy of the installation information, as plain ASCII.
|
||||
|
||||
Installing this package will create various files in subdirectories of
|
||||
/usr/local/lib, which are passes used by the compiler and a library
|
||||
named libgcc.a. It will also create /usr/local/bin/gcc, which is
|
||||
the user-level command to do a compilation.
|
||||
|
||||
See the Bugs chapter of the GCC Manual for how to report bugs
|
||||
usefully. An online readable version of the manual is in the files
|
||||
gcc.info*.
|
||||
|
||||
The files pself.c and pself1.c are not part of GCC.
|
||||
They are programs that print themselves on standard output.
|
||||
They were written by Dario Dariol and Giovanni Cozzi, and are
|
||||
included for your hacking pleasure. Likewise pself2.c
|
||||
(Who is the author of that?) and pself3.c (by Vlad Taeerov and Rashit
|
||||
Fakhreyev).
|
9
README-fixinc
Normal file
9
README-fixinc
Normal file
@ -0,0 +1,9 @@
|
||||
This README file is copied into the directory for GCC-only header files
|
||||
when fixincludes is run by the makefile for GCC.
|
||||
|
||||
Many of the files in this directory were made from the standard system
|
||||
header files of this system by the shell script `fixincludes'.
|
||||
They are system-specific, and will not work on any other kind of system.
|
||||
They are also not part of GCC. The reason for making the files here
|
||||
is to fix the places in the header files which use constructs
|
||||
that are incompatible with ANSI C.
|
18
README.ACORN
Normal file
18
README.ACORN
Normal file
@ -0,0 +1,18 @@
|
||||
Specifying the -g flag to GCC on a RISC iX machine requires upgrading the
|
||||
standard assembler distributed with both RISC iX 1.1 and RISC iX 1.2 with a
|
||||
replacement that is available from Acorn. This version of the assembler is
|
||||
also an order of magnitude faster when assembling to an NFS mounted
|
||||
file-system.
|
||||
|
||||
Users of RISC iX 1.2 and above can obtain a copy of the assembler from the
|
||||
following places:
|
||||
|
||||
1) Via ftp from acorn.acorn.co.uk, directory pub/riscix.
|
||||
|
||||
2) From Acorn Customer Services.
|
||||
|
||||
3) From Granada Microcare.
|
||||
|
||||
Users of versions of RISC iX prior 1.2 should contact Acorn Customer Services;
|
||||
the assembler available on the net will not work with these versions due to
|
||||
changes in the shared libraries and system call numbers.
|
55
README.ALTOS
Normal file
55
README.ALTOS
Normal file
@ -0,0 +1,55 @@
|
||||
Since COFF-encapsulation is obsolete, this may not be needed anymore.
|
||||
|
||||
Return-Path: <jkp@sauna.hut.fi>
|
||||
Date: Mon, 10 Apr 89 10:13:45 +0300
|
||||
From: Jyrki Kuoppala <jkp@sauna.hut.fi>
|
||||
Sender: jkp@sauna.hut.fi
|
||||
To: info-gcc@prep.ai.mit.edu
|
||||
Subject: Kernel fix needed for Altos 3068 to get coff-encapsulation working right
|
||||
Organization: Helsinki University of Technology, Finland.
|
||||
|
||||
Here's a description how to fix a kernel bug in Altos 3068 and get
|
||||
gcc-compiled programs working.
|
||||
|
||||
Author: Jyrki Kuoppala (jkp@cs.hut.fi)
|
||||
Last modified: Mon Apr 10 09:28:40 1989
|
||||
|
||||
There's a bug in the Altos 3068 kernel that causes gcc-compiled
|
||||
programs to fail in certain situations when the machine has a heavy
|
||||
load and also in some other situations. The bug exists at least in
|
||||
SVR 2.2 1.0gT1 and SVR 2.2 1.0e.
|
||||
|
||||
If you have source code to your system, apply the following change to
|
||||
os/exec.c (function gethead):
|
||||
|
||||
Change the lines containing
|
||||
|
||||
u.u_exdata.ux_tstart = sizeof(struct naout) +
|
||||
sizeof(struct filhd) + (ep->ef.nscns * sizeof(struct scnhdr));
|
||||
|
||||
to
|
||||
|
||||
u.u_exdata.ux_tstart = u.u_exdata.ux_txtorg;
|
||||
|
||||
If you only have binary, use sdb to find out the address of the
|
||||
previous lines (on our system it's gethead+0x140) and use your
|
||||
favourite binary editor to change the bytes '3036 0162 fffc 0002 0280
|
||||
0000' to '23f9 01fb f4ca 01fb f4c2 6016'. This may or may not work in
|
||||
your case, depending on the version of the operating system and the
|
||||
phase of the moon.
|
||||
|
||||
Here's what is just before gethead+0x140 to ease finding out the right place:
|
||||
|
||||
0x9224 (gethead+0x122): 23f9 01fb f4ca 01fb f4ce mov.l &0x1fbf4ca.L,&0
|
||||
x1fbf4ce.L []
|
||||
0x922e (gethead+0x12c): 23f9 01fb f4c6 01fb f4ca mov.l &0x1fbf4c6.L,&0
|
||||
x1fbf4ca.L []
|
||||
0x9238 (gethead+0x136): 23f9 01fb f4c2 01fb f4c6 mov.l &0x1fbf4c2.L,&0
|
||||
x1fbf4c6.L []
|
||||
|
||||
Good luck !
|
||||
|
||||
//Jyrki
|
||||
|
||||
jkp@cs.hut.fi
|
||||
|
112
README.APOLLO
Normal file
112
README.APOLLO
Normal file
@ -0,0 +1,112 @@
|
||||
README.apollo
|
||||
|
||||
Building GCC 2.0 for 680x0 based Apollo systems requires the GNU
|
||||
assembler (GAS) version 1.38.1, with John Vasta's patches applied.
|
||||
|
||||
If you haven't done so yet, get `gas-1.38.1.tar.Z' from your favourite
|
||||
GNU distribution site. Furthermore, get `apollo-gas-1.38.1.diffs'
|
||||
from `labrea.stanford.edu:/pub/gnu', apply the patches, compile and
|
||||
install gas (under the name as). This should go through without any
|
||||
problems.
|
||||
|
||||
After switching into the BSD environment, you can configure GCC 2.0
|
||||
with the command
|
||||
|
||||
% ./configure m68k-apollo-bsd
|
||||
|
||||
The Apollo's `/usr/include/setjmp.h' uses a nonstandard `#options()'
|
||||
construct. You should create a local copy of this file and remove
|
||||
these constructs from the declarations of SIGSETJMP and SIGLONGJMP.
|
||||
|
||||
The Apollo's `/usr/include/sys/types.h' (BSD Version) doesn't allow
|
||||
to test for the definition of `size_t'. This should be fixed by
|
||||
|
||||
#ifndef _SIZE_T
|
||||
#define _SIZE_T
|
||||
typedef long size_t;
|
||||
#endif
|
||||
|
||||
The script `patch-apollo-includes' fixes these two problems, but does
|
||||
_not_ pretend to be a full fledged `fixincludes' for this system.
|
||||
|
||||
If you now follow the standard GCC installation instructions, building
|
||||
GCC 2.0 (including G++ 2.0) should proceed without any problems.
|
||||
|
||||
NB: Debugging is not yet supported for the Apollo. If someone wants
|
||||
to do a _big_ favour to the Apollo users, he/she should consider
|
||||
porting the Binary File Description library (BFD) to the Apollo.
|
||||
This library can be found in the gdb-4.x distributions or in the
|
||||
binutils-1.9x distributions.
|
||||
|
||||
|
||||
|
||||
|
||||
#!/bin/sh
|
||||
# patch-apollo-includes -- fix some (but not all!) Apollo brain damage.
|
||||
|
||||
FILES_TO_PATCH='sys/types.h setjmp.h'
|
||||
|
||||
mkdir sys
|
||||
|
||||
for i in $FILES_TO_PATCH;
|
||||
do
|
||||
cp /bsd4.3/usr/include/$i ./$i
|
||||
done
|
||||
|
||||
patch -b -apollo <<'EOP'
|
||||
*** /bsd4.3/usr/include/sys/types.h Fri Apr 8 20:29:06 1988
|
||||
--- sys/types.h Wed Feb 26 21:17:57 1992
|
||||
***************
|
||||
*** 38,44 ****
|
||||
--- 38,47 ----
|
||||
typedef char * caddr_t;
|
||||
typedef u_long ino_t;
|
||||
typedef long swblk_t;
|
||||
+ #ifndef _SIZE_T
|
||||
+ #define _SIZE_T
|
||||
typedef long size_t;
|
||||
+ #endif
|
||||
typedef long time_t;
|
||||
typedef long dev_t;
|
||||
typedef long off_t;
|
||||
*** /bsd4.3/usr/include/setjmp.h Fri Feb 3 21:40:21 1989
|
||||
--- setjmp.h Sun Feb 23 19:06:55 1992
|
||||
***************
|
||||
*** 24,30 ****
|
||||
--- 24,39 ----
|
||||
#endif
|
||||
|
||||
|
||||
+ #ifdef __GNUC__
|
||||
#ifdef _PROTOTYPES
|
||||
+ extern int sigsetjmp (sigjmp_buf env, int savemask);
|
||||
+ extern void siglongjmp (sigjmp_buf env, int val);
|
||||
+ #else
|
||||
+ extern int sigsetjmp();
|
||||
+ extern void siglongjmp();
|
||||
+ #endif /* _PROTOTYPES */
|
||||
+ #else /* not __GNUC__ */
|
||||
+ #ifdef _PROTOTYPES
|
||||
extern int sigsetjmp(
|
||||
sigjmp_buf env,
|
||||
int savemask
|
||||
***************
|
||||
*** 37,43 ****
|
||||
extern int sigsetjmp() #options(abnormal);
|
||||
extern void siglongjmp() #options(noreturn);
|
||||
#endif /* _PROTOTYPES */
|
||||
!
|
||||
#undef _PROTOTYPES
|
||||
|
||||
#ifdef __cplusplus
|
||||
--- 46,52 ----
|
||||
extern int sigsetjmp() #options(abnormal);
|
||||
extern void siglongjmp() #options(noreturn);
|
||||
#endif /* _PROTOTYPES */
|
||||
! #endif /* not __GNUC__ */
|
||||
#undef _PROTOTYPES
|
||||
|
||||
#ifdef __cplusplus
|
||||
EOP
|
||||
|
||||
exit 0
|
574
README.DWARF
Normal file
574
README.DWARF
Normal file
@ -0,0 +1,574 @@
|
||||
Notes on the GNU Implementation of DWARF Debugging Information
|
||||
--------------------------------------------------------------
|
||||
Last Updated: Sun Jul 17 08:17:42 PDT 1994 by rfg@segfault.us.com
|
||||
------------------------------------------------------------
|
||||
|
||||
This file describes special and unique aspects of the GNU implementation
|
||||
of the DWARF debugging information language, as provided in the GNU version
|
||||
2.x compiler(s).
|
||||
|
||||
For general information about the DWARF debugging information language,
|
||||
you should obtain the DWARF version 1 specification document (and perhaps
|
||||
also the DWARF version 2 draft specification document) developed by the
|
||||
UNIX International Programming Languages Special Interest Group. A copy
|
||||
of the the DWARF version 1 specification (in PostScript form) may be
|
||||
obtained either from me <rfg@netcom.com> or from the main Data General
|
||||
FTP server. (See below.) The file you are looking at now only describes
|
||||
known deviations from the DWARF version 1 specification, together with
|
||||
those things which are allowed by the DWARF version 1 specification but
|
||||
which are known to cause interoperability problems (e.g. with SVR4 SDB).
|
||||
|
||||
To obtain a copy of the DWARF Version 1 and/or DWARF Version 2 specification
|
||||
from Data General's FTP server, use the following procedure:
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
ftp to machine: "dg-rtp.dg.com" (128.222.1.2).
|
||||
|
||||
Log in as "ftp".
|
||||
cd to "plsig"
|
||||
get any of the following file you are interested in:
|
||||
|
||||
dwarf.1.0.3.ps
|
||||
dwarf.2.0.0.index.ps
|
||||
dwarf.2.0.0.ps
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
The generation of DWARF debugging information by the GNU version 2.x C
|
||||
compiler has now been tested rather extensively for m88k, i386, i860, and
|
||||
Sparc targets. The DWARF output of the GNU C compiler appears to inter-
|
||||
operate well with the standard SVR4 SDB debugger on these kinds of target
|
||||
systems (but of course, there are no guarantees).
|
||||
|
||||
DWARF generation for the GNU g++ compiler is still not operable. This is
|
||||
due primarily to the many remaining cases where the g++ front end does not
|
||||
conform to the conventions used in the GNU C front end for representing
|
||||
various kinds of declarations in the TREE data structure. It is not clear
|
||||
at this time how these problems will be addressed.
|
||||
|
||||
Future plans for the dwarfout.c module of the GNU compiler(s) includes the
|
||||
addition of full support for GNU FORTRAN. (This should, in theory, be a
|
||||
lot simpler to add than adding support for g++... but we'll see.)
|
||||
|
||||
Many features of the DWARF version 2 specification have been adapted to
|
||||
(and used in) the GNU implementation of DWARF (version 1). In most of
|
||||
these cases, a DWARF version 2 approach is used in place of (or in addition
|
||||
to) DWARF version 1 stuff simply because it is apparent that DWARF version
|
||||
1 is not sufficiently expressive to provide the kinds of information which
|
||||
may be necessary to support really robust debugging. In all of these cases
|
||||
however, the use of DWARF version 2 features should not interfere in any
|
||||
way with the interoperability (of GNU compilers) with generally available
|
||||
"classic" (pre version 1) DWARF consumer tools (e.g. SVR4 SDB).
|
||||
|
||||
The DWARF generation enhancement for the GNU compiler(s) was initially
|
||||
donated to the Free Software Foundation by Network Computing Devices.
|
||||
(Thanks NCD!) Additional development and maintenance of dwarfout.c has
|
||||
been largely supported (i.e. funded) by Intel Corporation. (Thanks Intel!)
|
||||
|
||||
If you have questions or comments about the DWARF generation feature, please
|
||||
send mail to me <rfg@netcom.com>. I will be happy to investigate any bugs
|
||||
reported and I may even provide fixes (but of course, I can make no promises).
|
||||
|
||||
The DWARF debugging information produced by GCC may deviate in a few minor
|
||||
(but perhaps significant) respects from the DWARF debugging information
|
||||
currently produced by other C compilers. A serious attempt has been made
|
||||
however to conform to the published specifications, to existing practice,
|
||||
and to generally accepted norms in the GNU implementation of DWARF.
|
||||
|
||||
** IMPORTANT NOTE ** ** IMPORTANT NOTE ** ** IMPORTANT NOTE **
|
||||
|
||||
Under normal circumstances, the DWARF information generated by the GNU
|
||||
compilers (in an assembly language file) is essentially impossible for
|
||||
a human being to read. This fact can make it very difficult to debug
|
||||
certain DWARF-related problems. In order to overcome this difficulty,
|
||||
a feature has been added to dwarfout.c (enabled by the -fverbose-asm
|
||||
option) which causes additional comments to be placed into the assembly
|
||||
language output file, out to the right-hand side of most bits of DWARF
|
||||
material. The comments indicate (far more clearly that the obscure
|
||||
DWARF hex codes do) what is actually being encoded in DWARF. Thus, the
|
||||
-fverbose-asm option can be highly useful for those who must study the
|
||||
DWARF output from the GNU compilers in detail.
|
||||
|
||||
---------
|
||||
|
||||
(Footnote: Within this file, the term `Debugging Information Entry' will
|
||||
be abbreviated as `DIE'.)
|
||||
|
||||
|
||||
Release Notes (aka known bugs)
|
||||
-------------------------------
|
||||
|
||||
In one very obscure case involving dynamically sized arrays, the DWARF
|
||||
"location information" for such an array may make it appear that the
|
||||
array has been totally optimized out of existence, when in fact it
|
||||
*must* actually exist. (This only happens when you are using *both* -g
|
||||
*and* -O.) This is due to aggressive dead store elimination in the
|
||||
compiler, and to the fact that the DECL_RTL expressions associated with
|
||||
variables are not always updated to correctly reflect the effects of
|
||||
GCC's aggressive dead store elimination.
|
||||
|
||||
-------------------------------
|
||||
|
||||
When attempting to set a breakpoint at the "start" of a function compiled
|
||||
with -g1, the debugger currently has no way of knowing exactly where the
|
||||
end of the prologue code for the function is. Thus, for most targets,
|
||||
all the debugger can do is to set the breakpoint at the AT_low_pc address
|
||||
for the function. But if you stop there and then try to look at one or
|
||||
more of the formal parameter values, they may not have been "homed" yet,
|
||||
so you may get inaccurate answers (or perhaps even addressing errors).
|
||||
|
||||
Some people may consider this simply a non-feature, but I consider it a
|
||||
bug, and I hope to provide some some GNU-specific attributes (on function
|
||||
DIEs) which will specify the address of the end of the prologue and the
|
||||
address of the beginning of the epilogue in a future release.
|
||||
|
||||
-------------------------------
|
||||
|
||||
It is believed at this time that old bugs relating to the AT_bit_offset
|
||||
values for bit-fields have been fixed.
|
||||
|
||||
There may still be some very obscure bugs relating to the DWARF description
|
||||
of type `long long' bit-fields for target machines (e.g. 80x86 machines)
|
||||
where the alignment of type `long long' data objects is different from
|
||||
(and less than) the size of a type `long long' data object.
|
||||
|
||||
Please report any problems with the DWARF description of bit-fields as you
|
||||
would any other GCC bug. (Procedures for bug reporting are given in the
|
||||
GNU C compiler manual.)
|
||||
|
||||
--------------------------------
|
||||
|
||||
At this time, GCC does not know how to handle the GNU C "nested functions"
|
||||
extension. (See the GCC manual for more info on this extension to ANSI C.)
|
||||
|
||||
--------------------------------
|
||||
|
||||
The GNU compilers now represent inline functions (and inlined instances
|
||||
thereof) in exactly the manner described by the current DWARF version 2
|
||||
(draft) specification. The version 1 specification for handling inline
|
||||
functions (and inlined instances) was known to be brain-damaged (by the
|
||||
PLSIG) when the version 1 spec was finalized, but it was simply too late
|
||||
in the cycle to get it removed before the version 1 spec was formally
|
||||
released to the public (by UI).
|
||||
|
||||
--------------------------------
|
||||
|
||||
At this time, GCC does not generate the kind of really precise information
|
||||
about the exact declared types of entities with signed integral types which
|
||||
is required by the current DWARF draft specification.
|
||||
|
||||
Specifically, the current DWARF draft specification seems to require that
|
||||
the type of an non-unsigned integral bit-field member of a struct or union
|
||||
type be represented as either a "signed" type or as a "plain" type,
|
||||
depending upon the the exact set of keywords that were used in the
|
||||
type specification for the given bit-field member. It was felt (by the
|
||||
UI/PLSIG) that this distinction between "plain" and "signed" integral types
|
||||
could have some significance (in the case of bit-fields) because ANSI C
|
||||
does not constrain the signedness of a plain bit-field, whereas it does
|
||||
constrain the signedness of an explicitly "signed" bit-field. For this
|
||||
reason, the current DWARF specification calls for compilers to produce
|
||||
type information (for *all* integral typed entities... not just bit-fields)
|
||||
which explicitly indicates the signedness of the relevant type to be
|
||||
"signed" or "plain" or "unsigned".
|
||||
|
||||
Unfortunately, the GNU DWARF implementation is currently incapable of making
|
||||
such distinctions.
|
||||
|
||||
--------------------------------
|
||||
|
||||
|
||||
Known Interoperability Problems
|
||||
-------------------------------
|
||||
|
||||
Although the GNU implementation of DWARF conforms (for the most part) with
|
||||
the current UI/PLSIG DWARF version 1 specification (with many compatible
|
||||
version 2 features added in as "vendor specific extensions" just for good
|
||||
measure) there are a few known cases where GCC's DWARF output can cause
|
||||
some confusion for "classic" (pre version 1) DWARF consumers such as the
|
||||
System V Release 4 SDB debugger. These cases are described in this section.
|
||||
|
||||
--------------------------------
|
||||
|
||||
The DWARF version 1 specification includes the fundamental type codes
|
||||
FT_ext_prec_float, FT_complex, FT_dbl_prec_complex, and FT_ext_prec_complex.
|
||||
Since GNU C is only a C compiler (and since C doesn't provide any "complex"
|
||||
data types) the only one of these fundamental type codes which GCC ever
|
||||
generates is FT_ext_prec_float. This fundamental type code is generated
|
||||
by GCC for the `long double' data type. Unfortunately, due to an apparent
|
||||
bug in the SVR4 SDB debugger, SDB can become very confused wherever any
|
||||
attempt is made to print a variable, parameter, or field whose type was
|
||||
given in terms of FT_ext_prec_float.
|
||||
|
||||
(Actually, SVR4 SDB fails to understand *any* of the four fundamental type
|
||||
codes mentioned here. This will fact will cause additional problems when
|
||||
there is a GNU FORTRAN front-end.)
|
||||
|
||||
--------------------------------
|
||||
|
||||
In general, it appears that SVR4 SDB is not able to effectively ignore
|
||||
fundamental type codes in the "implementation defined" range. This can
|
||||
cause problems when a program being debugged uses the `long long' data
|
||||
type (or the signed or unsigned varieties thereof) because these types
|
||||
are not defined by ANSI C, and thus, GCC must use its own private fundamental
|
||||
type codes (from the implementation-defined range) to represent these types.
|
||||
|
||||
--------------------------------
|
||||
|
||||
|
||||
General GNU DWARF extensions
|
||||
----------------------------
|
||||
|
||||
In the current DWARF version 1 specification, no mechanism is specified by
|
||||
which accurate information about executable code from include files can be
|
||||
properly (and fully) described. (The DWARF version 2 specification *does*
|
||||
specify such a mechanism, but it is about 10 times more complicated than
|
||||
it needs to be so I'm not terribly anxious to try to implement it right
|
||||
away.)
|
||||
|
||||
In the GNU implementation of DWARF version 1, a fully downward-compatible
|
||||
extension has been implemented which permits the GNU compilers to specify
|
||||
which executable lines come from which files. This extension places
|
||||
additional information (about source file names) in GNU-specific sections
|
||||
(which should be totally ignored by all non-GNU DWARF consumers) so that
|
||||
this extended information can be provided (to GNU DWARF consumers) in a way
|
||||
which is totally transparent (and invisible) to non-GNU DWARF consumers
|
||||
(e.g. the SVR4 SDB debugger). The additional information is placed *only*
|
||||
in specialized GNU-specific sections, where it should never even be seen
|
||||
by non-GNU DWARF consumers.
|
||||
|
||||
To understand this GNU DWARF extension, imagine that the sequence of entries
|
||||
in the .lines section is broken up into several subsections. Each contiguous
|
||||
sequence of .line entries which relates to a sequence of lines (or statements)
|
||||
from one particular file (either a `base' file or an `include' file) could
|
||||
be called a `line entries chunk' (LEC).
|
||||
|
||||
For each LEC there is one entry in the .debug_srcinfo section.
|
||||
|
||||
Each normal entry in the .debug_srcinfo section consists of two 4-byte
|
||||
words of data as follows:
|
||||
|
||||
(1) The starting address (relative to the entire .line section)
|
||||
of the first .line entry in the relevant LEC.
|
||||
|
||||
(2) The starting address (relative to the entire .debug_sfnames
|
||||
section) of a NUL terminated string representing the
|
||||
relevant filename. (This filename name be either a
|
||||
relative or an absolute filename, depending upon how the
|
||||
given source file was located during compilation.)
|
||||
|
||||
Obviously, each .debug_srcinfo entry allows you to find the relevant filename,
|
||||
and it also points you to the first .line entry that was generated as a result
|
||||
of having compiled a given source line from the given source file.
|
||||
|
||||
Each subsequent .line entry should also be assumed to have been produced
|
||||
as a result of compiling yet more lines from the same file. The end of
|
||||
any given LEC is easily found by looking at the first 4-byte pointer in
|
||||
the *next* .debug_srcinfo entry. That next .debug_srcinfo entry points
|
||||
to a new and different LEC, so the preceding LEC (implicitly) must have
|
||||
ended with the last .line section entry which occurs at the 2 1/2 words
|
||||
just before the address given in the first pointer of the new .debug_srcinfo
|
||||
entry.
|
||||
|
||||
The following picture may help to clarify this feature. Let's assume that
|
||||
`LE' stands for `.line entry'. Also, assume that `* 'stands for a pointer.
|
||||
|
||||
|
||||
.line section .debug_srcinfo section .debug_sfnames section
|
||||
----------------------------------------------------------------
|
||||
|
||||
LE <---------------------- *
|
||||
LE * -----------------> "foobar.c" <---
|
||||
LE |
|
||||
LE |
|
||||
LE <---------------------- * |
|
||||
LE * -----------------> "foobar.h" <| |
|
||||
LE | |
|
||||
LE | |
|
||||
LE <---------------------- * | |
|
||||
LE * -----------------> "inner.h" | |
|
||||
LE | |
|
||||
LE <---------------------- * | |
|
||||
LE * ------------------------------- |
|
||||
LE |
|
||||
LE |
|
||||
LE |
|
||||
LE |
|
||||
LE <---------------------- * |
|
||||
LE * -----------------------------------
|
||||
LE
|
||||
LE
|
||||
LE
|
||||
|
||||
In effect, each entry in the .debug_srcinfo section points to *both* a
|
||||
filename (in the .debug_sfnames section) and to the start of a block of
|
||||
consecutive LEs (in the .line section).
|
||||
|
||||
Note that just like in the .line section, there are specialized first and
|
||||
last entries in the .debug_srcinfo section for each object file. These
|
||||
special first and last entries for the .debug_srcinfo section are very
|
||||
different from the normal .debug_srcinfo section entries. They provide
|
||||
additional information which may be helpful to a debugger when it is
|
||||
interpreting the data in the .debug_srcinfo, .debug_sfnames, and .line
|
||||
sections.
|
||||
|
||||
The first entry in the .debug_srcinfo section for each compilation unit
|
||||
consists of five 4-byte words of data. The contents of these five words
|
||||
should be interpreted (by debuggers) as follows:
|
||||
|
||||
(1) The starting address (relative to the entire .line section)
|
||||
of the .line section for this compilation unit.
|
||||
|
||||
(2) The starting address (relative to the entire .debug_sfnames
|
||||
section) of the .debug_sfnames section for this compilation
|
||||
unit.
|
||||
|
||||
(3) The starting address (in the execution virtual address space)
|
||||
of the .text section for this compilation unit.
|
||||
|
||||
(4) The ending address plus one (in the execution virtual address
|
||||
space) of the .text section for this compilation unit.
|
||||
|
||||
(5) The date/time (in seconds since midnight 1/1/70) at which the
|
||||
compilation of this compilation unit occurred. This value
|
||||
should be interpreted as an unsigned quantity because gcc
|
||||
might be configured to generate a default value of 0xffffffff
|
||||
in this field (in cases where it is desired to have object
|
||||
files created at different times from identical source files
|
||||
be byte-for-byte identical). By default, these timestamps
|
||||
are *not* generated by dwarfout.c (so that object files
|
||||
compiled at different times will be byte-for-byte identical).
|
||||
If you wish to enable this "timestamp" feature however, you
|
||||
can simply place a #define for the symbol `DWARF_TIMESTAMPS'
|
||||
in your target configuration file and then rebuild the GNU
|
||||
compiler(s).
|
||||
|
||||
Note that the first string placed into the .debug_sfnames section for each
|
||||
compilation unit is the name of the directory in which compilation occurred.
|
||||
This string ends with a `/' (to help indicate that it is the pathname of a
|
||||
directory). Thus, the second word of each specialized initial .debug_srcinfo
|
||||
entry for each compilation unit may be used as a pointer to the (string)
|
||||
name of the compilation directory, and that string may in turn be used to
|
||||
"absolutize" any relative pathnames which may appear later on in the
|
||||
.debug_sfnames section entries for the same compilation unit.
|
||||
|
||||
The fifth and last word of each specialized starting entry for a compilation
|
||||
unit in the .debug_srcinfo section may (depending upon your configuration)
|
||||
indicate the date/time of compilation, and this may be used (by a debugger)
|
||||
to determine if any of the source files which contributed code to this
|
||||
compilation unit are newer than the object code for the compilation unit
|
||||
itself. If so, the debugger may wish to print an "out-of-date" warning
|
||||
about the compilation unit.
|
||||
|
||||
The .debug_srcinfo section associated with each compilation will also have
|
||||
a specialized terminating entry. This terminating .debug_srcinfo section
|
||||
entry will consist of the following two 4-byte words of data:
|
||||
|
||||
(1) The offset, measured from the start of the .line section to
|
||||
the beginning of the terminating entry for the .line section.
|
||||
|
||||
(2) A word containing the value 0xffffffff.
|
||||
|
||||
--------------------------------
|
||||
|
||||
In the current DWARF version 1 specification, no mechanism is specified by
|
||||
which information about macro definitions and un-definitions may be provided
|
||||
to the DWARF consumer.
|
||||
|
||||
The DWARF version 2 (draft) specification does specify such a mechanism.
|
||||
That specification was based on the GNU ("vendor specific extension")
|
||||
which provided some support for macro definitions and un-definitions,
|
||||
but the "official" DWARF version 2 (draft) specification mechanism for
|
||||
handling macros and the GNU implementation have diverged somewhat. I
|
||||
plan to update the GNU implementation to conform to the "official"
|
||||
DWARF version 2 (draft) specification as soon as I get time to do that.
|
||||
|
||||
Note that in the GNU implementation, additional information about macro
|
||||
definitions and un-definitions is *only* provided when the -g3 level of
|
||||
debug-info production is selected. (The default level is -g2 and the
|
||||
plain old -g option is considered to be identical to -g2.)
|
||||
|
||||
GCC records information about macro definitions and undefinitions primarily
|
||||
in a section called the .debug_macinfo section. Normal entries in the
|
||||
.debug_macinfo section consist of the following three parts:
|
||||
|
||||
(1) A special "type" byte.
|
||||
|
||||
(2) A 3-byte line-number/filename-offset field.
|
||||
|
||||
(3) A NUL terminated string.
|
||||
|
||||
The interpretation of the second and third parts is dependent upon the
|
||||
value of the leading (type) byte.
|
||||
|
||||
The type byte may have one of four values depending upon the type of the
|
||||
.debug_macinfo entry which follows. The 1-byte MACINFO type codes presently
|
||||
used, and their meanings are as follows:
|
||||
|
||||
MACINFO_start A base file or an include file starts here.
|
||||
MACINFO_resume The current base or include file ends here.
|
||||
MACINFO_define A #define directive occurs here.
|
||||
MACINFO_undef A #undef directive occur here.
|
||||
|
||||
(Note that the MACINFO_... codes mentioned here are simply symbolic names
|
||||
for constants which are defined in the GNU dwarf.h file.)
|
||||
|
||||
For MACINFO_define and MACINFO_undef entries, the second (3-byte) field
|
||||
contains the number of the source line (relative to the start of the current
|
||||
base source file or the current include files) when the #define or #undef
|
||||
directive appears. For a MACINFO_define entry, the following string field
|
||||
contains the name of the macro which is defined, followed by its definition.
|
||||
Note that the definition is always separated from the name of the macro
|
||||
by at least one whitespace character. For a MACINFO_undef entry, the
|
||||
string which follows the 3-byte line number field contains just the name
|
||||
of the macro which is being undef'ed.
|
||||
|
||||
For a MACINFO_start entry, the 3-byte field following the type byte contains
|
||||
the offset, relative to the start of the .debug_sfnames section for the
|
||||
current compilation unit, of a string which names the new source file which
|
||||
is beginning its inclusion at this point. Following that 3-byte field,
|
||||
each MACINFO_start entry always contains a zero length NUL terminated
|
||||
string.
|
||||
|
||||
For a MACINFO_resume entry, the 3-byte field following the type byte contains
|
||||
the line number WITHIN THE INCLUDING FILE at which the inclusion of the
|
||||
current file (whose inclusion ends here) was initiated. Following that
|
||||
3-byte field, each MACINFO_resume entry always contains a zero length NUL
|
||||
terminated string.
|
||||
|
||||
Each set of .debug_macinfo entries for each compilation unit is terminated
|
||||
by a special .debug_macinfo entry consisting of a 4-byte zero value followed
|
||||
by a single NUL byte.
|
||||
|
||||
--------------------------------
|
||||
|
||||
In the current DWARF draft specification, no provision is made for providing
|
||||
a separate level of (limited) debugging information necessary to support
|
||||
tracebacks (only) through fully-debugged code (e.g. code in system libraries).
|
||||
|
||||
A proposal to define such a level was submitted (by me) to the UI/PLSIG.
|
||||
This proposal was rejected by the UI/PLSIG for inclusion into the DWARF
|
||||
version 1 specification for two reasons. First, it was felt (by the PLSIG)
|
||||
that the issues involved in supporting a "traceback only" subset of DWARF
|
||||
were not well understood. Second, and perhaps more importantly, the PLSIG
|
||||
is already having enough trouble agreeing on what it means to be "conforming"
|
||||
to the DWARF specification, and it was felt that trying to specify multiple
|
||||
different *levels* of conformance would only complicate our discussions of
|
||||
this already divisive issue. Nonetheless, the GNU implementation of DWARF
|
||||
provides an abbreviated "traceback only" level of debug-info production for
|
||||
use with fully-debugged "system library" code. This level should only be
|
||||
used for fully debugged system library code, and even then, it should only
|
||||
be used where there is a very strong need to conserve disk space. This
|
||||
abbreviated level of debug-info production can be used by specifying the
|
||||
-g1 option on the compilation command line.
|
||||
|
||||
--------------------------------
|
||||
|
||||
As mentioned above, the GNU implementation of DWARF currently uses the DWARF
|
||||
version 2 (draft) approach for inline functions (and inlined instances
|
||||
thereof). This is used in preference to the version 1 approach because
|
||||
(quite simply) the version 1 approach is highly brain-damaged and probably
|
||||
unworkable.
|
||||
|
||||
--------------------------------
|
||||
|
||||
|
||||
GNU DWARF Representation of GNU C Extensions to ANSI C
|
||||
------------------------------------------------------
|
||||
|
||||
The file dwarfout.c has been designed and implemented so as to provide
|
||||
some reasonable DWARF representation for each and every declarative
|
||||
construct which is accepted by the GNU C compiler. Since the GNU C
|
||||
compiler accepts a superset of ANSI C, this means that there are some
|
||||
cases in which the DWARF information produced by GCC must take some
|
||||
liberties in improvising DWARF representations for declarations which
|
||||
are only valid in (extended) GNU C.
|
||||
|
||||
In particular, GNU C provides at least three significant extensions to
|
||||
ANSI C when it comes to declarations. These are (1) inline functions,
|
||||
and (2) dynamic arrays, and (3) incomplete enum types. (See the GCC
|
||||
manual for more information on these GNU extensions to ANSI C.) When
|
||||
used, these GNU C extensions are represented (in the generated DWARF
|
||||
output of GCC) in the most natural and intuitively obvious ways.
|
||||
|
||||
In the case of inline functions, the DWARF representation is exactly as
|
||||
called for in the DWARF version 2 (draft) specification for an identical
|
||||
function written in C++; i.e. we "reuse" the representation of inline
|
||||
functions which has been defined for C++ to support this GNU C extension.
|
||||
|
||||
In the case of dynamic arrays, we use the most obvious representational
|
||||
mechanism available; i.e. an array type in which the upper bound of
|
||||
some dimension (usually the first and only dimension) is a variable
|
||||
rather than a constant. (See the DWARF version 1 specification for more
|
||||
details.)
|
||||
|
||||
In the case of incomplete enum types, such types are represented simply
|
||||
as TAG_enumeration_type DIEs which DO NOT contain either AT_byte_size
|
||||
attributes or AT_element_list attributes.
|
||||
|
||||
--------------------------------
|
||||
|
||||
|
||||
Future Directions
|
||||
-----------------
|
||||
|
||||
The codes, formats, and other paraphernalia necessary to provide proper
|
||||
support for symbolic debugging for the C++ language are still being worked
|
||||
on by the UI/PLSIG. The vast majority of the additions to DWARF which will
|
||||
be needed to completely support C++ have already been hashed out and agreed
|
||||
upon, but a few small issues (e.g. anonymous unions, access declarations)
|
||||
are still being discussed. Also, we in the PLSIG are still discussing
|
||||
whether or not we need to do anything special for C++ templates. (At this
|
||||
time it is not yet clear whether we even need to do anything special for
|
||||
these.)
|
||||
|
||||
Unfortunately, as mentioned above, there are quite a few problems in the
|
||||
g++ front end itself, and these are currently responsible for severely
|
||||
restricting the progress which can be made on adding DWARF support
|
||||
specifically for the g++ front-end. Furthermore, Richard Stallman has
|
||||
expressed the view that C++ friendships might not be important enough to
|
||||
describe (in DWARF). This view directly conflicts with both the DWARF
|
||||
version 1 and version 2 (draft) specifications, so until this small
|
||||
misunderstanding is cleared up, DWARF support for g++ is unlikely.
|
||||
|
||||
With regard to FORTRAN, the UI/PLSIG has defined what is believed to be a
|
||||
complete and sufficient set of codes and rules for adequately representing
|
||||
all of FORTRAN 77, and most of Fortran 90 in DWARF. While some support for
|
||||
this has been implemented in dwarfout.c, further implementation and testing
|
||||
will have to await the arrival of the GNU Fortran front-end (which is
|
||||
currently in early alpha test as of this writing).
|
||||
|
||||
GNU DWARF support for other languages (i.e. Pascal and Modula) is a moot
|
||||
issue until there are GNU front-ends for these other languages.
|
||||
|
||||
GNU DWARF support for DWARF version 2 will probably not be attempted until
|
||||
such time as the version 2 specification is finalized. (More work needs
|
||||
to be done on the version 2 specification to make the new "abbreviations"
|
||||
feature of version 2 more easily implementable. Until then, it will be
|
||||
a royal pain the ass to implement version 2 "abbreviations".) For the
|
||||
time being, version 2 features will be added (in a version 1 compatible
|
||||
manner) when and where these features seem necessary or extremely desirable.
|
||||
|
||||
As currently defined, DWARF only describes a (binary) language which can
|
||||
be used to communicate symbolic debugging information from a compiler
|
||||
through an assembler and a linker, to a debugger. There is no clear
|
||||
specification of what processing should be (or must be) done by the
|
||||
assembler and/or the linker. Fortunately, the role of the assembler
|
||||
is easily inferred (by anyone knowledgeable about assemblers) just by
|
||||
looking at examples of assembly-level DWARF code. Sadly though, the
|
||||
allowable (or required) processing steps performed by a linker are
|
||||
harder to infer and (perhaps) even harder to agree upon. There are
|
||||
several forms of very useful `post-processing' steps which intelligent
|
||||
linkers *could* (in theory) perform on object files containing DWARF,
|
||||
but any and all such link-time transformations are currently both disallowed
|
||||
and unspecified.
|
||||
|
||||
In particular, possible link-time transformations of DWARF code which could
|
||||
provide significant benefits include (but are not limited to):
|
||||
|
||||
Commonization of duplicate DIEs obtained from multiple input
|
||||
(object) files.
|
||||
|
||||
Cross-compilation type checking based upon DWARF type information
|
||||
for objects and functions.
|
||||
|
||||
Other possible `compacting' transformations designed to save disk
|
||||
space and to reduce linker & debugger I/O activity.
|
17
README.FRESCO
Normal file
17
README.FRESCO
Normal file
@ -0,0 +1,17 @@
|
||||
Compiling Fresco with g++
|
||||
-----------------------------
|
||||
|
||||
Fresco is an evolving interface and toolkit for object-oriented
|
||||
graphics. A preliminary version (written in C++) was released
|
||||
with x11r6.
|
||||
|
||||
Previous versions of Fresco have not compiled using g++,
|
||||
partly because of the use of true and false as identifiers.
|
||||
(They are now reserved words in g++, as required by the
|
||||
ANSI/ISO draft standard for C++.)
|
||||
|
||||
If you get x11r6 with public patch #5 or a later version
|
||||
of Fresco, these problems should now be fixed.
|
||||
|
||||
See http://www.faslab.com/fresco/HomePage.html for information
|
||||
on Fresco, including how to get the latest version.
|
130
README.NS32K
Normal file
130
README.NS32K
Normal file
@ -0,0 +1,130 @@
|
||||
This file describes the implementation notes of the GNU C Compiler for
|
||||
the National Semiconductor 32032 chip (and 32000 family).
|
||||
|
||||
The 32032 machine description and configuration file for this compiler
|
||||
is, for NS32000 family machine, primarily machine independent.
|
||||
However, since this release still depends on vendor-supplied
|
||||
assemblers and linkers, the compiler must obey the existing
|
||||
conventions of the actual machine to which this compiler is targeted.
|
||||
In this case, the actual machine which this compiler was targeted to
|
||||
is a Sequent Balance 8000, running DYNIX 2.1.
|
||||
|
||||
The assembler for DYNIX 2.1 (and DYNIX 3.0, alas) does not cope with
|
||||
the full generality of the addressing mode REGISTER RELATIVE.
|
||||
Specifically, it generates incorrect code for operands of the
|
||||
following form:
|
||||
|
||||
sym(rn)
|
||||
|
||||
Where `rn' is one of the general registers. Correct code is generated
|
||||
for operands of the form
|
||||
|
||||
sym(pn)
|
||||
|
||||
where `pn' is one of the special processor registers (sb, fp, or sp).
|
||||
|
||||
An equivalent operand can be generated by the form
|
||||
|
||||
sym[rn:b]
|
||||
|
||||
although this addressing mode is about twice as slow on the 32032.
|
||||
|
||||
The more efficient addressing mode is controlled by defining the
|
||||
constant SEQUENT_ADDRESS_BUG to 0. It is currently defined to be 1.
|
||||
|
||||
Another bug in the assembler makes it impossible to compute with
|
||||
explicit addresses. In order to compute with a symbolic address, it
|
||||
is necessary to load that address into a register using the "addr"
|
||||
instruction. For example, it is not possible to say
|
||||
|
||||
cmpd _p,@_x
|
||||
|
||||
Rather one must say
|
||||
|
||||
addr _x,rn
|
||||
cmpd _p,rn
|
||||
|
||||
|
||||
The ns32032 chip has a number of known bugs. Any attempt to make the
|
||||
compiler unaware of these deficiencies will surely bring disaster.
|
||||
The current list of know bugs are as follows (list provided by Richard
|
||||
Stallman):
|
||||
|
||||
1) instructions with two overlapping operands in memory
|
||||
(unlikely in C code, perhaps impossible).
|
||||
|
||||
2) floating point conversion instructions with constant
|
||||
operands (these may never happen, but I'm not certain).
|
||||
|
||||
3) operands crossing a page boundary. These can be prevented
|
||||
by setting the flag in tm.h that requires strict alignment.
|
||||
|
||||
4) Scaled indexing in an insn following an insn that has a read-write
|
||||
operand in memory. This can be prevented by placing a no-op in
|
||||
between. I, Michael Tiemann, do not understand what exactly is meant
|
||||
by `read-write operand in memory'. If this is referring to the special
|
||||
TOS mode, for example "addd 5,tos" then one need not fear, since this
|
||||
will never be generated. However, is this includes "addd 5,-4(fp)"
|
||||
then there is room for disaster. The Sequent compiler does not insert
|
||||
a no-op for code involving the latter, and I have been informed that
|
||||
Sequent is aware of this list of bugs, so I must assume that it is not
|
||||
a problem.
|
||||
|
||||
5) The 32032 cannot shift by 32 bits. It shifts modulo the word size
|
||||
of the operand. Therefore, for 32-bit operations, 32-bit shifts are
|
||||
interpreted as zero bit shifts. 32-bit shifts have been removed from
|
||||
the compiler, but future hackers must be careful not to reintroduce
|
||||
them.
|
||||
|
||||
6) The ns32032 is a very slow chip; however, some instructions are
|
||||
still very much slower than one might expect. For example, it is
|
||||
almost always faster to double a quantity by adding it to itself than
|
||||
by shifting it by one, even if that quantity is deep in memory. The
|
||||
MOVM instruction has a 20-cycle setup time, after which it moves data
|
||||
at about the speed that normal moves would. It is also faster to use
|
||||
address generation instructions than shift instructions for left
|
||||
shifts less than 4. I do not claim that I generate optimal code for all
|
||||
given patterns, but where I did escape from National's "clean
|
||||
architecture", I did so because the timing specification from the data
|
||||
book says that I will win if I do. I suppose this is called the
|
||||
"performance gap".
|
||||
|
||||
|
||||
Signed bitfield extraction has not been implemented. It is not
|
||||
provided by the NS32032, and while it is most certainly possible to do
|
||||
better than the standard shift-left/shift-right sequence, it is also
|
||||
quite hairy. Also, since signed bitfields do not yet exist in C, this
|
||||
omission seems relatively harmless.
|
||||
|
||||
|
||||
Zero extractions could be better implemented if it were possible in
|
||||
GCC to provide sized zero extractions: i.e. a byte zero extraction
|
||||
would be allowed to yield a byte result. The current implementation
|
||||
of GCC manifests 68000-ist thinking, where bitfields are extracted
|
||||
into a register, and automatically sign/zero extended to fill the
|
||||
register. See comments in ns32k.md around the "extzv" insn for more
|
||||
details.
|
||||
|
||||
|
||||
It should be noted that while the NS32000 family was designed to
|
||||
provide odd-aligned addressing capability for multi-byte data (also
|
||||
provided by the 68020, but not by the 68000 or 68010), many machines
|
||||
do not opt to take advantage of this. For example, on the sequent,
|
||||
although there is no advantage to long-word aligning word data, shorts
|
||||
must be int-aligned in structs. This is an example of another
|
||||
machine-specific machine dependency.
|
||||
|
||||
|
||||
Because the ns32032 is has a coherent byte-order/bit-order
|
||||
architecture, many instructions which would be different for
|
||||
68000-style machines, fold into the same instruction for the 32032.
|
||||
The classic case is push effective address, where it does not matter
|
||||
whether one is pushing a long, word, or byte address. They all will
|
||||
push the same address.
|
||||
|
||||
|
||||
The macro FUNCTION_VALUE_REGNO_P is probably not sufficient, what is
|
||||
needed is FUNCTION_VALUE_P, which also takes a MODE parameter. In
|
||||
this way it will be possible to determine more exactly whether a
|
||||
register is really a function value register, or just one that happens
|
||||
to look right.
|
122
README.RS6000
Normal file
122
README.RS6000
Normal file
@ -0,0 +1,122 @@
|
||||
AIX 4.3 assembler
|
||||
|
||||
The AIX 4.3.0.0 assembler generates incorrect object files if the ".bs"
|
||||
pseudo-op references symbols in certain sections. If GCC is invoked with
|
||||
the -g debugging option (including during bootstrapping), incorrect object
|
||||
files will be produced and the AIX linker will fail with a severe error.
|
||||
A fix for APAR IX74254 (64BIT DISASSEMBLED OUPUT FROM COMPILER FAILS TO
|
||||
ASSEMBLE/BIND) is available from IBM Customer Support and IBM's
|
||||
service.boulder.ibm.com website.
|
||||
|
||||
|
||||
AIX 4.1 binder
|
||||
|
||||
Due to changes in the way that GCC invokes the binder (linker) for AIX 4.1,
|
||||
the link step now may produce warnings of duplicate symbols which were not
|
||||
reported before. The assembly files generated by GCC for AIX always have
|
||||
included multiple symbol definitions for certain global variable and
|
||||
function declarations in the original program. The warnings should not
|
||||
prevent the linker from producing a correct library or runnable executable.
|
||||
|
||||
|
||||
AIX NLS problems
|
||||
|
||||
AIX on the RS/6000 provides support (NLS) for environments outside of
|
||||
the United States. Compilers and assemblers use NLS to support
|
||||
locale-specific representations of various objects including
|
||||
floating-point numbers ("." vs "," for separating decimal fractions).
|
||||
There have been problems reported where the library linked with GCC does
|
||||
not produce the same floating-point formats that the assembler accepts.
|
||||
If you have this problem, set the LANG environment variable to "C" or
|
||||
"En_US".
|
||||
|
||||
|
||||
AIX 3.2.5 XLC-1.3 problems
|
||||
|
||||
XLC version 1.3.0.0 distributed with AIX 3.2.5 will miscompile jump.c when
|
||||
building the stage1 compiler during the bootstrap process. This will cause
|
||||
GCC to crash and the bootstrap to fail later while compiling libgcc2.c. XLC
|
||||
version 1.3.0.1 or later fixes this problem. XLC-1.3.0.19 also cannot
|
||||
bootstrap GCC so please avoid that release as well. You can obtain
|
||||
XLC-1.3.0.24 by requesting PTF 432238 from IBM, or just ask for the latest
|
||||
release of XLC-1.3.
|
||||
|
||||
There also have been reports of problems bootstrapping GCC with some older
|
||||
releases of xlc-1.2.1, including xlc-1.2.1.8. Newer releases of xlc-1.2.1
|
||||
do not exhibit this problem: xlc-1.2.1.28 is known to bootstrap properly.
|
||||
|
||||
|
||||
AIX 3.2 common-mode support
|
||||
|
||||
AIX common-mode providing transparent support of both the POWER and PowerPC
|
||||
architectures is usable in AIX 3.2.3 and above but an export file and
|
||||
support for hidden export via libc.a will not exist until AIX 4.1. libgcc.a
|
||||
also must be compiled in common-mode. Note that executables generated for
|
||||
the POWER (RIOS1 and RSC) architecture will run directly on systems using
|
||||
the MPC601 chip. Common-mode only improves the performance of a single
|
||||
executable run on both POWER and PowerPC architecture platforms by not using
|
||||
POWER- or PowerPC-specific instructions and eliminating the need to trap to
|
||||
emulation (for POWER instructions run on PowerPC).
|
||||
|
||||
To link a common-mode application prior to AIX 4.1 and run it on a system at
|
||||
AIX level 3.2.3 or above, use the text between the "<>" as an export file
|
||||
(e.g. milli.exp)
|
||||
|
||||
<><><><><><><><><><><>
|
||||
#!
|
||||
__mulh 0x3100
|
||||
__mull 0x3180
|
||||
__divss 0x3200
|
||||
__divus 0x3280
|
||||
__quoss 0x3300
|
||||
__quous 0x3380
|
||||
<><><><><><><><><><><>
|
||||
|
||||
and then link with -Wl,-bI:milli.exp.
|
||||
|
||||
|
||||
AIX 3.1 and 3.2 assembler problems
|
||||
|
||||
Specifying the -g flag to GCC on the RS/6000 requires upgrading the
|
||||
standard AIX assembler distributed with AIX 3.1 and versions of AIX
|
||||
3.2 earlier than 3.2.4 with a replacement that is available from IBM.
|
||||
Note that Makefile.in specifies the -g when compiling libgcc2.c.
|
||||
|
||||
You can test for the presence of a fixed assembler by entering the following:
|
||||
% as -u < /dev/null
|
||||
If the command exits normally, the assembler fix already is installed.
|
||||
If the assembler complains that "-u" is an unknown flag, you need to order
|
||||
the fix.
|
||||
|
||||
If you are running AIX 3.1 (lslpp -h bos.obj output reports
|
||||
03.01.0005.XXXX where the 0005 can be any higher number and the XXXX
|
||||
can be any value), call IBM Support at 800-237-5511 and ask for
|
||||
shipment of AIX/6000 fix PTF U403044 for APAR IX22829 (.extern foo
|
||||
conflicts with defining foo).
|
||||
|
||||
If you are running AIX 3.2 but not 3.2.4 or later (lslpp -h bos.obj
|
||||
output reports 03.02.0000.0000), a newer update to the assembler fix
|
||||
is available. Ask for shipment of AIX/6000 fix PTF U416277 for
|
||||
IX32992 (.global prevents detection of duplicate symbol).
|
||||
|
||||
If you are running AIX 3.2.4 or later, you already have the new
|
||||
assembler.
|
||||
|
||||
Any customer can order and get the replacement assembler, and install it on
|
||||
one or more machines. It is available on diskette from IBM Customer Support
|
||||
and from the IBM Internet fix anonymous ftp server (FixDist) at
|
||||
aix.boulder.ibm.com (198.17.57.66).
|
||||
|
||||
If you contact IBM Customer Support, they may also ask you for your customer
|
||||
number. If you do not know it, you will still be able to get the fix, but
|
||||
you will have to be persistent. IBM has corresponding support organizations
|
||||
outside of North America. Call your IBM branch office and ask them to put
|
||||
you in touch with the department that handles fixes for AIX/6000. If that
|
||||
doesn't work, ask for the department that handles software defect support
|
||||
for AIX/6000 and ask for the APAR fix.
|
||||
|
||||
If you use the GNU assembler instead of the system supplied assembler, you need
|
||||
an assembler modified after October 16th, 1995 in order to build the GNU C
|
||||
compiler. This is because the GNU C compiler wants to build a variant of its
|
||||
library, libgcc.a with the -mcpu=common switch to support building programs
|
||||
that can run on either the Power or PowerPC machines.
|
55
README.TRAD
Normal file
55
README.TRAD
Normal file
@ -0,0 +1,55 @@
|
||||
This is a partial list of how `gcc -traditional' disagrees with
|
||||
traditional C compilers (perhaps only some of them). Most of these
|
||||
differences are not bugs.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
K&R-1 (2.4.3) says:
|
||||
|
||||
"If the character following a backslash is not one of those
|
||||
specified {in the table above}, the backslash is ignored."
|
||||
|
||||
Up until recently, `gcc -traditional' complained about \x \a and \v
|
||||
appearing in a character or string literal. I believe however that
|
||||
this non-feature has been eliminated (recently).
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
When in -traditional mode, gcc allows the following erroneous pair of
|
||||
declarations to appear together in a given scope:
|
||||
|
||||
typedef int foo;
|
||||
typedef foo foo;
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
K&R-1 (8.5) says:
|
||||
|
||||
"No field may be wider than a word."
|
||||
|
||||
Gcc however allows:
|
||||
|
||||
struct S { int i:33; };
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
In K&R-1 there is no restriction against comments crossing include file
|
||||
boundaries. Gcc however doesn't allow this, even when in -traditional mode.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
Regarding the length of identifiers, K&R-1 (2.2) says:
|
||||
|
||||
"No more than the first eight characters are significant,
|
||||
although more may be used."
|
||||
|
||||
Gcc treats all characters of identifiers as significant, even when in
|
||||
-traditional mode.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
K&R-1 (2.2) says:
|
||||
|
||||
"An identifier is a sequence of letters and digits; the first
|
||||
character must be a letter. The underscore _ counts as a letter."
|
||||
|
||||
Gcc also allows dollar signs in identifiers. (This may also be an issue
|
||||
for the -pedantic option.)
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
|
447
README.X11
Normal file
447
README.X11
Normal file
@ -0,0 +1,447 @@
|
||||
[This file contains two alternative recipes for compiling X11 with GCC.
|
||||
The first alternative puts libgcc.a into the shared X library; the second
|
||||
does not. Neither alternative works on all kinds of systems.
|
||||
It may be that when using GCC 2.4, both alternatives work okay on
|
||||
relatively recent Sparc systems. The first alternative is likely
|
||||
not to work on a Sun 3 without hardware floating point.]
|
||||
|
||||
How to compile X11R5 (patch level 11) with GCC version 2:
|
||||
|
||||
The patches include support for building the shared libraries with GCC
|
||||
2 on the Sparc and 68k machines. This version includes the necessary
|
||||
parts of libgcc.a in the shared library for X, in case functions in
|
||||
that library need it. Thus the default behavior is now to build
|
||||
everything, including the libraries, with gcc.
|
||||
|
||||
If you build the shared library this way, it may not work with
|
||||
executables made with older versions of GCC (2.3.3 and earlier).
|
||||
If that happens, relink those executables with the latest GCC.
|
||||
IF YOU THINK YOU MIGHT COMPILE X FOR SOLARIS 2, then you really don't
|
||||
need this patch: get /contrib/R5.SunOS5.patch.tar.Z from
|
||||
export.lcs.mit.edu instead. It has everything you need to do the
|
||||
build for Solaris 2, sets you up to everything with GCC, and is
|
||||
backward compatible with SunOS 4.*. Get the the README
|
||||
(/contrib/R5.SunOS5.patch.README at export) for more info.
|
||||
|
||||
If you see undefined symbols _dlopen, _dlsym, or _dlclose when linking
|
||||
with -lX11, compile and link against the file mit/util/misc/dlsym.c in
|
||||
the MIT X11R5 distribution. Alternatively, do dynamic linking
|
||||
by using a non-GNU ld.
|
||||
|
||||
mit/config/Imake.tmpl -- Do not set -fstrength-reduce if we have GCC 2.
|
||||
If -fstrength-reduce (or any other -f option) is a major win, then it
|
||||
will most likely be turned on by -O2 optimization.
|
||||
|
||||
mit/config/sunLib.rules -- If HasGcc and GccVersion > 1 are true, then
|
||||
use gcc -fpic to generate PIC code. Make sure that gcc does not use
|
||||
gas (the GNU assembler) when compiling PIC code; gas does not assemble
|
||||
it correctly.
|
||||
|
||||
***If you have gas installed where gcc uses it by default, you might have
|
||||
to add -B/bin/ to the PositionIndependentCFlags.***
|
||||
|
||||
mit/config/site.def -- Define GccVersion to be 2.
|
||||
|
||||
mit/config/sun.cf -- When compiling with GCC 2, use -O2 optimization.
|
||||
|
||||
mit/config/sunLib.rules -- When compiling with GCC 2, use -fpic for
|
||||
position independent code generation.
|
||||
|
||||
mit/rgb/Imakefile -- No longer need to compile some modules with
|
||||
cc on the Sparc since GCC 2 produces proper -fpcc-struct-return code.
|
||||
|
||||
mit/server/os/Imakefile -- Likewise.
|
||||
|
||||
mit/server/ddx/sun/Imakefile -- When compiling with GCC 2, some modules
|
||||
should be compiled with -fvolatile.
|
||||
|
||||
mit/clients/twm/Imakefile -- Fix bad decls of malloc, realloc in gram.c.
|
||||
|
||||
mit/lib/X/Imakefile -- Make libgcc.a a required lib for libX11.so
|
||||
|
||||
*** mit/clients/twm/Imakefile Mon May 17 22:05:22 1993
|
||||
--- new/clients/twm/Imakefile Mon May 17 22:28:46 1993
|
||||
***************
|
||||
*** 32,41 ****
|
||||
--- 32,48 ----
|
||||
ComplexProgramTarget(twm)
|
||||
InstallNonExecFile(system.twmrc,$(TWMDIR))
|
||||
|
||||
+ #if HasGcc && GccVersion > 1 && defined (SunArchitecture)
|
||||
gram.h gram.c: gram.y
|
||||
yacc $(YFLAGS) gram.y
|
||||
+ sed -e 's/^extern char \*malloc(), \*realloc();//g' y.tab.c >gram.c
|
||||
+ $(MV) y.tab.h gram.h
|
||||
+ #else
|
||||
+ gram.h gram.c: gram.y
|
||||
+ yacc $(YFLAGS) gram.y
|
||||
$(MV) y.tab.c gram.c
|
||||
$(MV) y.tab.h gram.h
|
||||
+ #endif
|
||||
|
||||
clean::
|
||||
$(RM) y.tab.h y.tab.c lex.yy.c gram.h gram.c lex.c deftwmrc.c
|
||||
*** mit/config/Imake.tmpl Mon May 17 22:02:57 1993
|
||||
--- new/config/Imake.tmpl Mon May 17 22:15:06 1993
|
||||
***************
|
||||
*** 500,506 ****
|
||||
--- 500,510 ----
|
||||
#endif
|
||||
#ifndef CcCmd
|
||||
#if HasGcc
|
||||
+ #if GccVersion > 1
|
||||
+ #define CcCmd gcc -fpcc-struct-return
|
||||
+ #else
|
||||
#define CcCmd gcc -fstrength-reduce -fpcc-struct-return
|
||||
+ #endif
|
||||
#else
|
||||
#define CcCmd cc
|
||||
#endif
|
||||
*** mit/config/site.def Mon May 17 22:02:44 1993
|
||||
--- new/config/site.def Mon May 17 22:22:28 1993
|
||||
***************
|
||||
*** 25,31 ****
|
||||
|
||||
#ifdef BeforeVendorCF
|
||||
|
||||
! /* #define HasGcc YES */
|
||||
|
||||
#endif /* BeforeVendorCF */
|
||||
|
||||
--- 25,33 ----
|
||||
|
||||
#ifdef BeforeVendorCF
|
||||
|
||||
! #define HasGcc YES
|
||||
! /* GccVersion > 1 implies building shared libraries with gcc */
|
||||
! #define GccVersion 2
|
||||
|
||||
#endif /* BeforeVendorCF */
|
||||
|
||||
*** mit/config/sun.cf Mon May 17 22:03:02 1993
|
||||
--- new/config/sun.cf Mon May 17 22:24:55 1993
|
||||
***************
|
||||
*** 41,49 ****
|
||||
--- 41,55 ----
|
||||
|
||||
#if HasGcc
|
||||
|
||||
+ #if GccVersion > 1
|
||||
+ #define OptimizedCDebugFlags -O2
|
||||
+ #else
|
||||
+ #define OptimizedCDebugFlags -O
|
||||
#define SharedLibraryCcCmd cc
|
||||
#define ExtraLoadFlags -B/usr/bin/
|
||||
#define AllocateLocalDefines /**/
|
||||
+ #endif
|
||||
+
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(CFLAGS) $*.c
|
||||
*** mit/config/sunLib.rules Mon May 17 22:02:46 1993
|
||||
--- new/config/sunLib.rules Mon May 17 22:19:06 1993
|
||||
***************
|
||||
*** 23,29 ****
|
||||
--- 23,33 ----
|
||||
#define SharedLibraryLoadFlags -assert pure-text
|
||||
#endif
|
||||
#ifndef PositionIndependentCFlags
|
||||
+ #if defined(HasGcc) && GccVersion > 1
|
||||
+ #define PositionIndependentCFlags -fpic
|
||||
+ #else
|
||||
#define PositionIndependentCFlags -pic
|
||||
+ #endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
*** mit/lib/X/Imakefile Mon May 17 22:05:03 1993
|
||||
--- new/lib/X/Imakefile Mon May 17 22:32:26 1993
|
||||
***************
|
||||
*** 9,14 ****
|
||||
--- 9,31 ----
|
||||
#define MotifBC NO
|
||||
#endif
|
||||
|
||||
+ #if defined(SunArchitecture)
|
||||
+ #if SystemV4
|
||||
+ #if HasGcc
|
||||
+ REQUIREDLIBS= -lgcc -lc
|
||||
+ #else
|
||||
+ REQUIREDLIBS= -lc
|
||||
+ #endif
|
||||
+ #else
|
||||
+ #if HasGcc && GccVersion > 1
|
||||
+ XCOMM Hack to fix gcc 2 ``-nostdlib'' deficiency on SunOS 4.x
|
||||
+ REQUIREDLIBS= `gcc -v 2>&1 | awk '{print $$4}' | sed -e 's/specs$$/libgcc.a/'`
|
||||
+ #else
|
||||
+ REQUIREDLIBS=
|
||||
+ #endif
|
||||
+ #endif
|
||||
+ #endif
|
||||
+
|
||||
#ifndef BuildXimp
|
||||
#define BuildXimp NO
|
||||
#endif
|
||||
*** mit/rgb/Imakefile Mon May 17 22:05:31 1993
|
||||
--- new/rgb/Imakefile Mon May 17 22:25:30 1993
|
||||
***************
|
||||
*** 17,23 ****
|
||||
#if !(defined(SGIArchitecture) || SystemV4)
|
||||
DBMLIB = -ldbm
|
||||
#endif
|
||||
! #if defined(SparcArchitecture) && HasGcc
|
||||
CC = cc
|
||||
CCOPTIONS = /**/
|
||||
EXTRA_LOAD_FLAGS = /**/
|
||||
--- 17,23 ----
|
||||
#if !(defined(SGIArchitecture) || SystemV4)
|
||||
DBMLIB = -ldbm
|
||||
#endif
|
||||
! #if defined(SparcArchitecture) && HasGcc && GccVersion <= 1
|
||||
CC = cc
|
||||
CCOPTIONS = /**/
|
||||
EXTRA_LOAD_FLAGS = /**/
|
||||
*** mit/server/ddx/sun/Imakefile Mon May 17 22:05:57 1993
|
||||
--- new/server/ddx/sun/Imakefile Mon May 17 22:27:23 1993
|
||||
***************
|
||||
*** 43,48 ****
|
||||
--- 43,53 ----
|
||||
LinkFile(sunGX.o,sunGX.o.dist)
|
||||
#endif
|
||||
|
||||
+ #if HasGcc && GccVersion > 1
|
||||
+ SpecialObjectRule(sunCG2C.o,sunCG2C.c,-fvolatile)
|
||||
+ SpecialObjectRule(sunCG2M.o,sunCG2M.c,-fvolatile)
|
||||
+ #endif
|
||||
+
|
||||
sunInitExtMono.o: $(ICONFIGFILES)
|
||||
ObjectFromSpecialSource(sunInitExtMono,../mi/miinitext,-UPEXEXT)
|
||||
ObjectFromSpecialSource(sunInitMono,sunInit,-DMONO_ONLY)
|
||||
*** mit/server/os/Imakefile Mon May 17 22:05:46 1993
|
||||
--- new/server/os/Imakefile Mon May 17 22:26:02 1993
|
||||
***************
|
||||
*** 132,138 ****
|
||||
SpecialObjectRule(osinit.o,$(ICONFIGFILES),$(ADM_DEFINES))
|
||||
SpecialObjectRule(WaitFor.o,$(ICONFIGFILES),$(EXT_DEFINES))
|
||||
SpecialObjectRule(fonttype.o,$(ICONFIGFILES),$(FONT_DEFINES))
|
||||
! #if defined(SparcArchitecture) && HasGcc
|
||||
oscolor.o: $(ICONFIGFILES)
|
||||
$(RM) $@
|
||||
cc -c $(DBM_DEFINES) $(CDEBUGFLAGS) $(ALLDEFINES) $*.c
|
||||
--- 132,138 ----
|
||||
SpecialObjectRule(osinit.o,$(ICONFIGFILES),$(ADM_DEFINES))
|
||||
SpecialObjectRule(WaitFor.o,$(ICONFIGFILES),$(EXT_DEFINES))
|
||||
SpecialObjectRule(fonttype.o,$(ICONFIGFILES),$(FONT_DEFINES))
|
||||
! #if defined(SparcArchitecture) && HasGcc && GccVersion <= 1
|
||||
oscolor.o: $(ICONFIGFILES)
|
||||
$(RM) $@
|
||||
cc -c $(DBM_DEFINES) $(CDEBUGFLAGS) $(ALLDEFINES) $*.c
|
||||
|
||||
|
||||
[This is the older version]
|
||||
|
||||
How to compile X11R5 (patch level 11) with GCC version 2:
|
||||
|
||||
The patches include support for building the shared libraries with GCC 2 on
|
||||
the Sparc and 68k machines.
|
||||
|
||||
NOTE: Such shared libraries built with GCC version 2.3 DID NOT WORK
|
||||
with executables previously linked using Sun CC! This is because
|
||||
neither those executables nor the gcc-compiled shared libraries contain
|
||||
libgcc.a. The shared libraries did work with executables linked using
|
||||
GCC (running the Sun linker, of course) because GCC tells the linker to
|
||||
link in libgcc.a. Because of these limitations the default behavior is
|
||||
to NOT build the shared libraries with gcc.
|
||||
|
||||
Changes in GCC 2.4 seem to have eliminated the problem, and such a
|
||||
shared library now seems work with all executables. If you want the
|
||||
gcc-compiled shared libraries turn on "Gcc2BuildLibs" in site.def. If
|
||||
you try this, please tell bug-gcc@prep.ai.mit.edu whether it works.
|
||||
|
||||
Sun forgot to include a static version of libdl.a with some versions
|
||||
of SunOS (4.1 mainly). If you see undefined symbols _dlopen, _dlsym,
|
||||
or _dlclose when linking with -lX11, compile and link against the file
|
||||
mit/util/misc/dlsym.c in the MIT X11R5 distribution.
|
||||
|
||||
mit/config/Imake.tmpl -- Do not set -fstrength-reduce if we have GCC 2. If
|
||||
-fstrength-reduce (or any other -f option) is a major win, then it will
|
||||
most likely be turned on by -O2 optimization.
|
||||
|
||||
mit/config/sunLib.rules -- If HasGcc2 and Gcc2BuildLibs are defined, then
|
||||
use gcc -fpic to generate PIC code. Make sure that gcc does not use gas (the
|
||||
GNU assembler) when compiling PIC code; gas does not assemble it correctly.
|
||||
If you have gas installed where gcc uses it by default, you might have to add
|
||||
-B/bin/ to the PositionIndependentCFlags.
|
||||
|
||||
mit/config/site.def -- Define HasGcc2 to be YES.
|
||||
|
||||
mit/config/sun.cf -- When compiling with GCC 2, use -O2 optimization.
|
||||
|
||||
mit/rgb/Imakefile -- No longer need to compile some modules with
|
||||
cc on the Sparc since GCC 2 produces proper -fpcc-struct-return code.
|
||||
|
||||
mit/server/os/Imakefile -- Likewise.
|
||||
|
||||
mit/clients/twm/Imakefile -- fix bad decls of malloc, realloc in gram.c.
|
||||
|
||||
*** mit/config/Imake.tmpl.ORIG Tue Dec 31 11:07:56 1991
|
||||
--- mit/config/Imake.tmpl Tue Dec 31 12:30:47 1991
|
||||
***************
|
||||
*** 499,508 ****
|
||||
--- 499,512 ----
|
||||
#define HasGcc NO
|
||||
#endif
|
||||
#ifndef CcCmd
|
||||
+ #if HasGcc2
|
||||
+ #define CcCmd gcc -fpcc-struct-return
|
||||
+ #else
|
||||
#if HasGcc
|
||||
#define CcCmd gcc -fstrength-reduce -fpcc-struct-return
|
||||
#else
|
||||
#define CcCmd cc
|
||||
+ #endif
|
||||
#endif
|
||||
#endif
|
||||
#if HasFortran
|
||||
*** mit/config/sunLib.rules.ORIG Tue Dec 31 11:11:24 1991
|
||||
--- mit/config/sunLib.rules Tue May 5 12:26:12 1992
|
||||
***************
|
||||
*** 23,30 ****
|
||||
--- 23,34 ----
|
||||
#define SharedLibraryLoadFlags -assert pure-text
|
||||
#endif
|
||||
#ifndef PositionIndependentCFlags
|
||||
+ #if defined(HasGcc2) && defined (Gcc2BuildLibs)
|
||||
+ #define PositionIndependentCFlags -fpic
|
||||
+ #else
|
||||
#define PositionIndependentCFlags -pic
|
||||
#endif
|
||||
+ #endif
|
||||
|
||||
/*
|
||||
* InstallSharedLibrary - generate rules to install the shared library.
|
||||
*** mit/config/site.def.ORIG Tue Dec 31 11:13:49 1991
|
||||
--- mit/config/site.def Tue Dec 31 12:02:59 1991
|
||||
***************
|
||||
*** 25,31 ****
|
||||
|
||||
#ifdef BeforeVendorCF
|
||||
|
||||
! /* #define HasGcc YES */
|
||||
|
||||
#endif /* BeforeVendorCF */
|
||||
|
||||
--- 25,33 ----
|
||||
|
||||
#ifdef BeforeVendorCF
|
||||
|
||||
! #define HasGcc YES
|
||||
! #define HasGcc2 YES
|
||||
! /* #define Gcc2BuildLibs YES */
|
||||
|
||||
#endif /* BeforeVendorCF */
|
||||
|
||||
*** mit/config/sun.cf.ORIG Tue Dec 31 11:13:57 1991
|
||||
--- mit/config/sun.cf Tue May 5 12:29:50 1992
|
||||
***************
|
||||
*** 34,42 ****
|
||||
--- 41,61 ----
|
||||
|
||||
#if HasGcc
|
||||
|
||||
+ #if defined(HasGcc2)
|
||||
+ #define OptimizedCDebugFlags -O2
|
||||
+ /* Leave Alone XXX */
|
||||
+ #else
|
||||
+ #define OptimizedCDebugFlags -O
|
||||
#define SharedLibraryCcCmd cc
|
||||
#define ExtraLoadFlags -B/usr/bin/
|
||||
#define AllocateLocalDefines /**/
|
||||
+ #endif
|
||||
+
|
||||
+ #if !defined(Gcc2BuildLibs)
|
||||
+ #define SharedLibraryCcCmd cc
|
||||
+ #define ExtraLoadFlags -B/usr/bin/
|
||||
+ #define AllocateLocalDefines /**/
|
||||
+ #endif
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(CFLAGS) $*.c
|
||||
*** mit/rgb/Imakefile.ORIG Wed Jan 15 16:43:18 1992
|
||||
--- mit/rgb/Imakefile Thu Jan 2 13:34:09 1992
|
||||
***************
|
||||
*** 17,23 ****
|
||||
#if !(defined(SGIArchitecture) || SystemV4)
|
||||
DBMLIB = -ldbm
|
||||
#endif
|
||||
! #if defined(SparcArchitecture) && HasGcc
|
||||
CC = cc
|
||||
CCOPTIONS = /**/
|
||||
EXTRA_LOAD_FLAGS = /**/
|
||||
--- 17,23 ----
|
||||
#if !(defined(SGIArchitecture) || SystemV4)
|
||||
DBMLIB = -ldbm
|
||||
#endif
|
||||
! #if defined(SparcArchitecture) && HasGcc && !defined(HasGcc2)
|
||||
CC = cc
|
||||
CCOPTIONS = /**/
|
||||
EXTRA_LOAD_FLAGS = /**/
|
||||
*** mit/server/os/Imakefile.ORIG Wed Jan 15 16:46:23 1992
|
||||
--- mit/server/os/Imakefile Wed Jan 15 16:46:48 1992
|
||||
***************
|
||||
*** 132,138 ****
|
||||
SpecialObjectRule(osinit.o,$(ICONFIGFILES),$(ADM_DEFINES))
|
||||
SpecialObjectRule(WaitFor.o,$(ICONFIGFILES),$(EXT_DEFINES))
|
||||
SpecialObjectRule(fonttype.o,$(ICONFIGFILES),$(FONT_DEFINES))
|
||||
! #if defined(SparcArchitecture) && HasGcc
|
||||
oscolor.o: $(ICONFIGFILES)
|
||||
$(RM) $@
|
||||
cc -c $(DBM_DEFINES) $(CDEBUGFLAGS) $(ALLDEFINES) $*.c
|
||||
--- 132,138 ----
|
||||
SpecialObjectRule(osinit.o,$(ICONFIGFILES),$(ADM_DEFINES))
|
||||
SpecialObjectRule(WaitFor.o,$(ICONFIGFILES),$(EXT_DEFINES))
|
||||
SpecialObjectRule(fonttype.o,$(ICONFIGFILES),$(FONT_DEFINES))
|
||||
! #if defined(SparcArchitecture) && HasGcc && !defined(HasGcc2)
|
||||
oscolor.o: $(ICONFIGFILES)
|
||||
$(RM) $@
|
||||
cc -c $(DBM_DEFINES) $(CDEBUGFLAGS) $(ALLDEFINES) $*.c
|
||||
*** 1.1 1992/09/08 19:52:07
|
||||
--- mit/server/ddx/sun/Imakefile 1992/09/08 21:10:22
|
||||
***************
|
||||
*** 43,48 ****
|
||||
--- 43,53 ----
|
||||
LinkFile(sunGX.o,sunGX.o.dist)
|
||||
#endif
|
||||
|
||||
+ #if HasGcc2
|
||||
+ SpecialObjectRule(sunCG2C.o,sunCG2C.c,-fvolatile)
|
||||
+ SpecialObjectRule(sunCG2M.o,sunCG2M.c,-fvolatile)
|
||||
+ #endif
|
||||
+
|
||||
sunInitExtMono.o: $(ICONFIGFILES)
|
||||
ObjectFromSpecialSource(sunInitExtMono,../mi/miinitext,-UPEXEXT)
|
||||
ObjectFromSpecialSource(sunInitMono,sunInit,-DMONO_ONLY)
|
||||
|
||||
*** /tmp/RCSAa24446 Tue Sep 15 12:23:32 1992
|
||||
--- mit/clients/twm/Imakefile Thu Aug 13 18:18:07 1992
|
||||
***************
|
||||
*** 32,41 ****
|
||||
--- 32,48 ----
|
||||
ComplexProgramTarget(twm)
|
||||
InstallNonExecFile(system.twmrc,$(TWMDIR))
|
||||
|
||||
+ #if HasGcc2 && defined (SunArchitecture)
|
||||
gram.h gram.c: gram.y
|
||||
yacc $(YFLAGS) gram.y
|
||||
+ sed -e 's/^extern char \*malloc(), \*realloc();//g' y.tab.c >gram.c
|
||||
+ $(MV) y.tab.h gram.h
|
||||
+ #else
|
||||
+ gram.h gram.c: gram.y
|
||||
+ yacc $(YFLAGS) gram.y
|
||||
$(MV) y.tab.c gram.c
|
||||
$(MV) y.tab.h gram.h
|
||||
+ #endif
|
||||
|
||||
clean::
|
||||
$(RM) y.tab.h y.tab.c lex.yy.c gram.h gram.c lex.c deftwmrc.c
|
||||
|
39
TESTS.FLUNK
Normal file
39
TESTS.FLUNK
Normal file
@ -0,0 +1,39 @@
|
||||
This is a collection of things that test suites have
|
||||
said were "wrong" with GCC--but that I don't agree with.
|
||||
|
||||
First, test suites sometimes test for compatibility with
|
||||
traditional C. GCC with -traditional is not completely
|
||||
compatible with traditional C, and in some ways I think it
|
||||
should not be.
|
||||
|
||||
* K&R C allowed \x to appear in a string literal (or character
|
||||
literal?) even in cases where it is *not* followed by a sequence of
|
||||
hex digits. I'm not convinced this is desirable.
|
||||
|
||||
* K&R compilers allow comments to cross over an inclusion boundary (i.e.
|
||||
started in an include file and ended in the including file).
|
||||
I think this would be quite ugly and can't imagine it could
|
||||
be needed.
|
||||
|
||||
Sometimes tests disagree with GCC's interpretation of the ANSI standard.
|
||||
|
||||
* One test claims that this function should return 1.
|
||||
|
||||
enum {A, B} foo;
|
||||
|
||||
func (enum {B, A} arg)
|
||||
{
|
||||
return B;
|
||||
}
|
||||
|
||||
I think it should return 0, because the definition of B that
|
||||
applies is the one in func.
|
||||
|
||||
* Some tests report failure when the compiler does not produce
|
||||
an error message for a certain program.
|
||||
|
||||
ANSI C requires a "diagnostic" message for certain kinds of invalid
|
||||
programs, but a warning counts as a diagnostic. If GCC produces
|
||||
a warning but not an error, that is correct ANSI support.
|
||||
When test suites call this "failure", the tests are broken.
|
||||
|
27
acconfig.h
Normal file
27
acconfig.h
Normal file
@ -0,0 +1,27 @@
|
||||
/* Define if you have a working <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Whether malloc must be declared even if <stdlib.h> is included. */
|
||||
#undef NEED_DECLARATION_MALLOC
|
||||
|
||||
/* Whether realloc must be declared even if <stdlib.h> is included. */
|
||||
#undef NEED_DECLARATION_REALLOC
|
||||
|
||||
/* Whether calloc must be declared even if <stdlib.h> is included. */
|
||||
#undef NEED_DECLARATION_CALLOC
|
||||
|
||||
/* Whether free must be declared even if <stdlib.h> is included. */
|
||||
#undef NEED_DECLARATION_FREE
|
||||
|
||||
/* Whether index must be declared even if <stdlib.h> is included. */
|
||||
#undef NEED_DECLARATION_INDEX
|
||||
|
||||
/* Whether rindex must be declared even if <stdlib.h> is included. */
|
||||
#undef NEED_DECLARATION_RINDEX
|
||||
|
||||
/* Whether getenv must be declared even if <stdlib.h> is included. */
|
||||
#undef NEED_DECLARATION_GETENV
|
||||
|
||||
/* Whether sbrk must be declared even if <stdlib.h> is included. */
|
||||
#undef NEED_DECLARATION_SBRK
|
||||
@TOP@
|
33
aclocal.m4
vendored
Normal file
33
aclocal.m4
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
dnl See whether we need a declaration for a function.
|
||||
AC_DEFUN(GCC_NEED_DECLARATION,
|
||||
[AC_MSG_CHECKING([whether $1 must be declared])
|
||||
AC_CACHE_VAL(gcc_cv_decl_needed_$1,
|
||||
[AC_TRY_COMPILE([
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#else
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifndef HAVE_RINDEX
|
||||
#define rindex strrchr
|
||||
#endif
|
||||
#ifndef HAVE_INDEX
|
||||
#define index strchr
|
||||
#endif],
|
||||
[char *(*pfn) = (char *(*)) $1],
|
||||
gcc_cv_decl_needed_$1=no, gcc_cv_decl_needed_$1=yes)])
|
||||
AC_MSG_RESULT($gcc_cv_decl_needed_$1)
|
||||
if test $gcc_cv_decl_needed_$1 = yes; then
|
||||
gcc_tr_decl=NEED_DECLARATION_`echo $1 | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
|
||||
AC_DEFINE_UNQUOTED($gcc_tr_decl)
|
||||
fi
|
||||
])dnl
|
504
alloca.c
Normal file
504
alloca.c
Normal file
@ -0,0 +1,504 @@
|
||||
/* alloca.c -- allocate automatically reclaimed memory
|
||||
(Mostly) portable public-domain implementation -- D A Gwyn
|
||||
|
||||
This implementation of the PWB library alloca function,
|
||||
which is used to allocate space off the run-time stack so
|
||||
that it is automatically reclaimed upon procedure exit,
|
||||
was inspired by discussions with J. Q. Johnson of Cornell.
|
||||
J.Otto Tennant <jot@cray.com> contributed the Cray support.
|
||||
|
||||
There are some preprocessor constants that can
|
||||
be defined when compiling for your specific system, for
|
||||
improved efficiency; however, the defaults should be okay.
|
||||
|
||||
The general concept of this implementation is to keep
|
||||
track of all alloca-allocated blocks, and reclaim any
|
||||
that are found to be deeper in the stack than the current
|
||||
invocation. This heuristic does not reclaim storage as
|
||||
soon as it becomes invalid, but it will do so eventually.
|
||||
|
||||
As a special case, alloca(0) reclaims storage without
|
||||
allocating any. It is a good idea to use alloca(0) in
|
||||
your main control loop, etc. to force garbage collection. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef emacs
|
||||
#include "blockinput.h"
|
||||
#endif
|
||||
|
||||
/* If compiling with GCC 2, this file's not needed. */
|
||||
#if !defined (__GNUC__) || __GNUC__ < 2
|
||||
|
||||
/* If someone has defined alloca as a macro,
|
||||
there must be some other way alloca is supposed to work. */
|
||||
#ifndef alloca
|
||||
|
||||
#ifdef emacs
|
||||
#ifdef static
|
||||
/* actually, only want this if static is defined as ""
|
||||
-- this is for usg, in which emacs must undefine static
|
||||
in order to make unexec workable
|
||||
*/
|
||||
#ifndef STACK_DIRECTION
|
||||
you
|
||||
lose
|
||||
-- must know STACK_DIRECTION at compile-time
|
||||
#endif /* STACK_DIRECTION undefined */
|
||||
#endif /* static */
|
||||
#endif /* emacs */
|
||||
|
||||
/* If your stack is a linked list of frames, you have to
|
||||
provide an "address metric" ADDRESS_FUNCTION macro. */
|
||||
|
||||
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||
long i00afunc ();
|
||||
#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
|
||||
#else
|
||||
#define ADDRESS_FUNCTION(arg) &(arg)
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
typedef void *pointer;
|
||||
#else
|
||||
typedef char *pointer;
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
/* Different portions of Emacs need to call different versions of
|
||||
malloc. The Emacs executable needs alloca to call xmalloc, because
|
||||
ordinary malloc isn't protected from input signals. On the other
|
||||
hand, the utilities in lib-src need alloca to call malloc; some of
|
||||
them are very simple, and don't have an xmalloc routine.
|
||||
|
||||
Non-Emacs programs expect this to call use xmalloc.
|
||||
|
||||
Callers below should use malloc. */
|
||||
|
||||
#ifndef emacs
|
||||
#define malloc xmalloc
|
||||
#endif
|
||||
extern pointer malloc ();
|
||||
|
||||
/* Define STACK_DIRECTION if you know the direction of stack
|
||||
growth for your system; otherwise it will be automatically
|
||||
deduced at run-time.
|
||||
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||
|
||||
#ifndef STACK_DIRECTION
|
||||
#define STACK_DIRECTION 0 /* Direction unknown. */
|
||||
#endif
|
||||
|
||||
#if STACK_DIRECTION != 0
|
||||
|
||||
#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
|
||||
|
||||
#else /* STACK_DIRECTION == 0; need run-time code. */
|
||||
|
||||
static int stack_dir; /* 1 or -1 once known. */
|
||||
#define STACK_DIR stack_dir
|
||||
|
||||
static void
|
||||
find_stack_direction ()
|
||||
{
|
||||
static char *addr = NULL; /* Address of first `dummy', once known. */
|
||||
auto char dummy; /* To get stack address. */
|
||||
|
||||
if (addr == NULL)
|
||||
{ /* Initial entry. */
|
||||
addr = ADDRESS_FUNCTION (dummy);
|
||||
|
||||
find_stack_direction (); /* Recurse once. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Second entry. */
|
||||
if (ADDRESS_FUNCTION (dummy) > addr)
|
||||
stack_dir = 1; /* Stack grew upward. */
|
||||
else
|
||||
stack_dir = -1; /* Stack grew downward. */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* STACK_DIRECTION == 0 */
|
||||
|
||||
/* An "alloca header" is used to:
|
||||
(a) chain together all alloca'ed blocks;
|
||||
(b) keep track of stack depth.
|
||||
|
||||
It is very important that sizeof(header) agree with malloc
|
||||
alignment chunk size. The following default should work okay. */
|
||||
|
||||
#ifndef ALIGN_SIZE
|
||||
#define ALIGN_SIZE sizeof(double)
|
||||
#endif
|
||||
|
||||
typedef union hdr
|
||||
{
|
||||
char align[ALIGN_SIZE]; /* To force sizeof(header). */
|
||||
struct
|
||||
{
|
||||
union hdr *next; /* For chaining headers. */
|
||||
char *deep; /* For stack depth measure. */
|
||||
} h;
|
||||
} header;
|
||||
|
||||
static header *last_alloca_header = NULL; /* -> last alloca header. */
|
||||
|
||||
/* Return a pointer to at least SIZE bytes of storage,
|
||||
which will be automatically reclaimed upon exit from
|
||||
the procedure that called alloca. Originally, this space
|
||||
was supposed to be taken from the current stack frame of the
|
||||
caller, but that method cannot be made to work for some
|
||||
implementations of C, for example under Gould's UTX/32. */
|
||||
|
||||
pointer
|
||||
alloca (size)
|
||||
unsigned size;
|
||||
{
|
||||
auto char probe; /* Probes stack depth: */
|
||||
register char *depth = ADDRESS_FUNCTION (probe);
|
||||
|
||||
#if STACK_DIRECTION == 0
|
||||
if (STACK_DIR == 0) /* Unknown growth direction. */
|
||||
find_stack_direction ();
|
||||
#endif
|
||||
|
||||
/* Reclaim garbage, defined as all alloca'd storage that
|
||||
was allocated from deeper in the stack than currently. */
|
||||
|
||||
{
|
||||
register header *hp; /* Traverses linked list. */
|
||||
|
||||
#ifdef emacs
|
||||
BLOCK_INPUT;
|
||||
#endif
|
||||
|
||||
for (hp = last_alloca_header; hp != NULL;)
|
||||
if ((STACK_DIR > 0 && hp->h.deep > depth)
|
||||
|| (STACK_DIR < 0 && hp->h.deep < depth))
|
||||
{
|
||||
register header *np = hp->h.next;
|
||||
|
||||
free ((pointer) hp); /* Collect garbage. */
|
||||
|
||||
hp = np; /* -> next header. */
|
||||
}
|
||||
else
|
||||
break; /* Rest are not deeper. */
|
||||
|
||||
last_alloca_header = hp; /* -> last valid storage. */
|
||||
|
||||
#ifdef emacs
|
||||
UNBLOCK_INPUT;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
return NULL; /* No allocation required. */
|
||||
|
||||
/* Allocate combined header + user data storage. */
|
||||
|
||||
{
|
||||
register pointer new = malloc (sizeof (header) + size);
|
||||
/* Address of header. */
|
||||
|
||||
if (new == 0)
|
||||
abort();
|
||||
|
||||
((header *) new)->h.next = last_alloca_header;
|
||||
((header *) new)->h.deep = depth;
|
||||
|
||||
last_alloca_header = (header *) new;
|
||||
|
||||
/* User storage begins just after header. */
|
||||
|
||||
return (pointer) ((char *) new + sizeof (header));
|
||||
}
|
||||
}
|
||||
|
||||
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||
|
||||
#ifdef DEBUG_I00AFUNC
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifndef CRAY_STACK
|
||||
#define CRAY_STACK
|
||||
#ifndef CRAY2
|
||||
/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
|
||||
struct stack_control_header
|
||||
{
|
||||
long shgrow:32; /* Number of times stack has grown. */
|
||||
long shaseg:32; /* Size of increments to stack. */
|
||||
long shhwm:32; /* High water mark of stack. */
|
||||
long shsize:32; /* Current size of stack (all segments). */
|
||||
};
|
||||
|
||||
/* The stack segment linkage control information occurs at
|
||||
the high-address end of a stack segment. (The stack
|
||||
grows from low addresses to high addresses.) The initial
|
||||
part of the stack segment linkage control information is
|
||||
0200 (octal) words. This provides for register storage
|
||||
for the routine which overflows the stack. */
|
||||
|
||||
struct stack_segment_linkage
|
||||
{
|
||||
long ss[0200]; /* 0200 overflow words. */
|
||||
long sssize:32; /* Number of words in this segment. */
|
||||
long ssbase:32; /* Offset to stack base. */
|
||||
long:32;
|
||||
long sspseg:32; /* Offset to linkage control of previous
|
||||
segment of stack. */
|
||||
long:32;
|
||||
long sstcpt:32; /* Pointer to task common address block. */
|
||||
long sscsnm; /* Private control structure number for
|
||||
microtasking. */
|
||||
long ssusr1; /* Reserved for user. */
|
||||
long ssusr2; /* Reserved for user. */
|
||||
long sstpid; /* Process ID for pid based multi-tasking. */
|
||||
long ssgvup; /* Pointer to multitasking thread giveup. */
|
||||
long sscray[7]; /* Reserved for Cray Research. */
|
||||
long ssa0;
|
||||
long ssa1;
|
||||
long ssa2;
|
||||
long ssa3;
|
||||
long ssa4;
|
||||
long ssa5;
|
||||
long ssa6;
|
||||
long ssa7;
|
||||
long sss0;
|
||||
long sss1;
|
||||
long sss2;
|
||||
long sss3;
|
||||
long sss4;
|
||||
long sss5;
|
||||
long sss6;
|
||||
long sss7;
|
||||
};
|
||||
|
||||
#else /* CRAY2 */
|
||||
/* The following structure defines the vector of words
|
||||
returned by the STKSTAT library routine. */
|
||||
struct stk_stat
|
||||
{
|
||||
long now; /* Current total stack size. */
|
||||
long maxc; /* Amount of contiguous space which would
|
||||
be required to satisfy the maximum
|
||||
stack demand to date. */
|
||||
long high_water; /* Stack high-water mark. */
|
||||
long overflows; /* Number of stack overflow ($STKOFEN) calls. */
|
||||
long hits; /* Number of internal buffer hits. */
|
||||
long extends; /* Number of block extensions. */
|
||||
long stko_mallocs; /* Block allocations by $STKOFEN. */
|
||||
long underflows; /* Number of stack underflow calls ($STKRETN). */
|
||||
long stko_free; /* Number of deallocations by $STKRETN. */
|
||||
long stkm_free; /* Number of deallocations by $STKMRET. */
|
||||
long segments; /* Current number of stack segments. */
|
||||
long maxs; /* Maximum number of stack segments so far. */
|
||||
long pad_size; /* Stack pad size. */
|
||||
long current_address; /* Current stack segment address. */
|
||||
long current_size; /* Current stack segment size. This
|
||||
number is actually corrupted by STKSTAT to
|
||||
include the fifteen word trailer area. */
|
||||
long initial_address; /* Address of initial segment. */
|
||||
long initial_size; /* Size of initial segment. */
|
||||
};
|
||||
|
||||
/* The following structure describes the data structure which trails
|
||||
any stack segment. I think that the description in 'asdef' is
|
||||
out of date. I only describe the parts that I am sure about. */
|
||||
|
||||
struct stk_trailer
|
||||
{
|
||||
long this_address; /* Address of this block. */
|
||||
long this_size; /* Size of this block (does not include
|
||||
this trailer). */
|
||||
long unknown2;
|
||||
long unknown3;
|
||||
long link; /* Address of trailer block of previous
|
||||
segment. */
|
||||
long unknown5;
|
||||
long unknown6;
|
||||
long unknown7;
|
||||
long unknown8;
|
||||
long unknown9;
|
||||
long unknown10;
|
||||
long unknown11;
|
||||
long unknown12;
|
||||
long unknown13;
|
||||
long unknown14;
|
||||
};
|
||||
|
||||
#endif /* CRAY2 */
|
||||
#endif /* not CRAY_STACK */
|
||||
|
||||
#ifdef CRAY2
|
||||
/* Determine a "stack measure" for an arbitrary ADDRESS.
|
||||
I doubt that "lint" will like this much. */
|
||||
|
||||
static long
|
||||
i00afunc (long *address)
|
||||
{
|
||||
struct stk_stat status;
|
||||
struct stk_trailer *trailer;
|
||||
long *block, size;
|
||||
long result = 0;
|
||||
|
||||
/* We want to iterate through all of the segments. The first
|
||||
step is to get the stack status structure. We could do this
|
||||
more quickly and more directly, perhaps, by referencing the
|
||||
$LM00 common block, but I know that this works. */
|
||||
|
||||
STKSTAT (&status);
|
||||
|
||||
/* Set up the iteration. */
|
||||
|
||||
trailer = (struct stk_trailer *) (status.current_address
|
||||
+ status.current_size
|
||||
- 15);
|
||||
|
||||
/* There must be at least one stack segment. Therefore it is
|
||||
a fatal error if "trailer" is null. */
|
||||
|
||||
if (trailer == 0)
|
||||
abort ();
|
||||
|
||||
/* Discard segments that do not contain our argument address. */
|
||||
|
||||
while (trailer != 0)
|
||||
{
|
||||
block = (long *) trailer->this_address;
|
||||
size = trailer->this_size;
|
||||
if (block == 0 || size == 0)
|
||||
abort ();
|
||||
trailer = (struct stk_trailer *) trailer->link;
|
||||
if ((block <= address) && (address < (block + size)))
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the result to the offset in this segment and add the sizes
|
||||
of all predecessor segments. */
|
||||
|
||||
result = address - block;
|
||||
|
||||
if (trailer == 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (trailer->this_size <= 0)
|
||||
abort ();
|
||||
result += trailer->this_size;
|
||||
trailer = (struct stk_trailer *) trailer->link;
|
||||
}
|
||||
while (trailer != 0);
|
||||
|
||||
/* We are done. Note that if you present a bogus address (one
|
||||
not in any segment), you will get a different number back, formed
|
||||
from subtracting the address of the first block. This is probably
|
||||
not what you want. */
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
#else /* not CRAY2 */
|
||||
/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
|
||||
Determine the number of the cell within the stack,
|
||||
given the address of the cell. The purpose of this
|
||||
routine is to linearize, in some sense, stack addresses
|
||||
for alloca. */
|
||||
|
||||
static long
|
||||
i00afunc (long address)
|
||||
{
|
||||
long stkl = 0;
|
||||
|
||||
long size, pseg, this_segment, stack;
|
||||
long result = 0;
|
||||
|
||||
struct stack_segment_linkage *ssptr;
|
||||
|
||||
/* Register B67 contains the address of the end of the
|
||||
current stack segment. If you (as a subprogram) store
|
||||
your registers on the stack and find that you are past
|
||||
the contents of B67, you have overflowed the segment.
|
||||
|
||||
B67 also points to the stack segment linkage control
|
||||
area, which is what we are really interested in. */
|
||||
|
||||
stkl = CRAY_STACKSEG_END ();
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
|
||||
/* If one subtracts 'size' from the end of the segment,
|
||||
one has the address of the first word of the segment.
|
||||
|
||||
If this is not the first segment, 'pseg' will be
|
||||
nonzero. */
|
||||
|
||||
pseg = ssptr->sspseg;
|
||||
size = ssptr->sssize;
|
||||
|
||||
this_segment = stkl - size;
|
||||
|
||||
/* It is possible that calling this routine itself caused
|
||||
a stack overflow. Discard stack segments which do not
|
||||
contain the target address. */
|
||||
|
||||
while (!(this_segment <= address && address <= stkl))
|
||||
{
|
||||
#ifdef DEBUG_I00AFUNC
|
||||
fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
|
||||
#endif
|
||||
if (pseg == 0)
|
||||
break;
|
||||
stkl = stkl - pseg;
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
size = ssptr->sssize;
|
||||
pseg = ssptr->sspseg;
|
||||
this_segment = stkl - size;
|
||||
}
|
||||
|
||||
result = address - this_segment;
|
||||
|
||||
/* If you subtract pseg from the current end of the stack,
|
||||
you get the address of the previous stack segment's end.
|
||||
This seems a little convoluted to me, but I'll bet you save
|
||||
a cycle somewhere. */
|
||||
|
||||
while (pseg != 0)
|
||||
{
|
||||
#ifdef DEBUG_I00AFUNC
|
||||
fprintf (stderr, "%011o %011o\n", pseg, size);
|
||||
#endif
|
||||
stkl = stkl - pseg;
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
size = ssptr->sssize;
|
||||
pseg = ssptr->sspseg;
|
||||
result += size;
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
#endif /* not CRAY2 */
|
||||
#endif /* CRAY */
|
||||
|
||||
#endif /* no alloca */
|
||||
#endif /* not GCC version 2 */
|
54
assert.h
Normal file
54
assert.h
Normal file
@ -0,0 +1,54 @@
|
||||
/* Allow this file to be included multiple times
|
||||
with different settings of NDEBUG. */
|
||||
#undef assert
|
||||
#undef __assert
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define assert(ignore) ((void) 0)
|
||||
#else
|
||||
|
||||
#ifndef __GNUC__
|
||||
|
||||
#define assert(expression) \
|
||||
((void) ((expression) ? 0 : __assert (expression, __FILE__, __LINE__)))
|
||||
|
||||
#define __assert(expression, file, lineno) \
|
||||
(printf ("%s:%u: failed assertion\n", file, lineno), \
|
||||
abort (), 0)
|
||||
|
||||
#else
|
||||
|
||||
#if defined(__STDC__) || defined (__cplusplus)
|
||||
|
||||
/* Defined in libgcc.a */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern void __eprintf (const char *, const char *, unsigned, const char *)
|
||||
__attribute__ ((noreturn));
|
||||
}
|
||||
#else
|
||||
extern void __eprintf (const char *, const char *, unsigned, const char *)
|
||||
__attribute__ ((noreturn));
|
||||
#endif
|
||||
|
||||
#define assert(expression) \
|
||||
((void) ((expression) ? 0 : __assert (#expression, __FILE__, __LINE__)))
|
||||
|
||||
#define __assert(expression, file, line) \
|
||||
(__eprintf ("%s:%u: failed assertion `%s'\n", \
|
||||
file, line, expression), 0)
|
||||
|
||||
#else /* no __STDC__ and not C++; i.e. -traditional. */
|
||||
|
||||
extern void __eprintf () __attribute__ ((noreturn)); /* Defined in libgcc.a */
|
||||
|
||||
#define assert(expression) \
|
||||
((void) ((expression) ? 0 : __assert (expression, __FILE__, __LINE__)))
|
||||
|
||||
#define __assert(expression, file, lineno) \
|
||||
(__eprintf ("%s:%u: failed assertion `%s'\n", \
|
||||
file, lineno, "expression"), 0)
|
||||
|
||||
#endif /* no __STDC__ and not C++; i.e. -traditional. */
|
||||
#endif /* no __GNU__; i.e., /bin/cc. */
|
||||
#endif
|
130
basic-block.h
Normal file
130
basic-block.h
Normal file
@ -0,0 +1,130 @@
|
||||
/* Define control and data flow tables, and regsets.
|
||||
Copyright (C) 1987, 1997 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
#include "bitmap.h"
|
||||
|
||||
typedef bitmap regset; /* Head of register set linked list. */
|
||||
|
||||
/* Clear a register set by freeing up the linked list. */
|
||||
#define CLEAR_REG_SET(HEAD) bitmap_clear (HEAD)
|
||||
|
||||
/* Copy a register set to another register set. */
|
||||
#define COPY_REG_SET(TO, FROM) bitmap_copy (TO, FROM)
|
||||
|
||||
/* `and' a register set with a second register set. */
|
||||
#define AND_REG_SET(TO, FROM) bitmap_operation (TO, TO, FROM, BITMAP_AND)
|
||||
|
||||
/* `and' the complement of a register set with a register set. */
|
||||
#define AND_COMPL_REG_SET(TO, FROM) \
|
||||
bitmap_operation (TO, TO, FROM, BITMAP_AND_COMPL)
|
||||
|
||||
/* Inclusive or a register set with a second register set. */
|
||||
#define IOR_REG_SET(TO, FROM) bitmap_operation (TO, TO, FROM, BITMAP_IOR)
|
||||
|
||||
/* Or into TO the register set FROM1 `and'ed with the complement of FROM2. */
|
||||
#define IOR_AND_COMPL_REG_SET(TO, FROM1, FROM2) \
|
||||
bitmap_ior_and_compl (TO, FROM1, FROM2)
|
||||
|
||||
/* Clear a single register in a register set. */
|
||||
#define CLEAR_REGNO_REG_SET(HEAD, REG) bitmap_clear_bit (HEAD, REG)
|
||||
|
||||
/* Set a single register in a register set. */
|
||||
#define SET_REGNO_REG_SET(HEAD, REG) bitmap_set_bit (HEAD, REG)
|
||||
|
||||
/* Return true if a register is set in a register set. */
|
||||
#define REGNO_REG_SET_P(TO, REG) bitmap_bit_p (TO, REG)
|
||||
|
||||
/* Copy the hard registers in a register set to the hard register set. */
|
||||
#define REG_SET_TO_HARD_REG_SET(TO, FROM) \
|
||||
do { \
|
||||
int i_; \
|
||||
CLEAR_HARD_REG_SET (TO); \
|
||||
for (i_ = 0; i_ < FIRST_PSEUDO_REGISTER; i_++) \
|
||||
if (REGNO_REG_SET_P (FROM, i_)) \
|
||||
SET_HARD_REG_BIT (TO, i_); \
|
||||
} while (0)
|
||||
|
||||
/* Loop over all registers in REGSET, starting with MIN, setting REGNUM to the
|
||||
register number and executing CODE for all registers that are set. */
|
||||
#define EXECUTE_IF_SET_IN_REG_SET(REGSET, MIN, REGNUM, CODE) \
|
||||
EXECUTE_IF_SET_IN_BITMAP (REGSET, MIN, REGNUM, CODE)
|
||||
|
||||
/* Loop over all registers in REGSET1 and REGSET2, starting with MIN, setting
|
||||
REGNUM to the register number and executing CODE for all registers that are
|
||||
set in the first regset and not set in the second. */
|
||||
#define EXECUTE_IF_AND_COMPL_IN_REG_SET(REGSET1, REGSET2, MIN, REGNUM, CODE) \
|
||||
EXECUTE_IF_AND_COMPL_IN_BITMAP (REGSET1, REGSET2, MIN, REGNUM, CODE)
|
||||
|
||||
/* Loop over all registers in REGSET1 and REGSET2, starting with MIN, setting
|
||||
REGNUM to the register number and executing CODE for all registers that are
|
||||
set in both regsets. */
|
||||
#define EXECUTE_IF_AND_IN_REG_SET(REGSET1, REGSET2, MIN, REGNUM, CODE) \
|
||||
EXECUTE_IF_AND_IN_BITMAP (REGSET1, REGSET2, MIN, REGNUM, CODE)
|
||||
|
||||
/* Allocate a register set with oballoc. */
|
||||
#define OBSTACK_ALLOC_REG_SET(OBSTACK) BITMAP_OBSTACK_ALLOC (OBSTACK)
|
||||
|
||||
/* Allocate a register set with alloca. */
|
||||
#define ALLOCA_REG_SET() BITMAP_ALLOCA ()
|
||||
|
||||
/* Do any cleanup needed on a regset when it is no longer used. */
|
||||
#define FREE_REG_SET(REGSET) BITMAP_FREE(REGSET)
|
||||
|
||||
/* Do any one-time initializations needed for regsets. */
|
||||
#define INIT_ONCE_REG_SET() BITMAP_INIT_ONCE ()
|
||||
|
||||
/* Grow any tables needed when the number of registers is calculated
|
||||
or extended. For the linked list allocation, nothing needs to
|
||||
be done, other than zero the statistics on the first allocation. */
|
||||
#define MAX_REGNO_REG_SET(NUM_REGS, NEW_P, RENUMBER_P)
|
||||
|
||||
/* Number of basic blocks in the current function. */
|
||||
|
||||
extern int n_basic_blocks;
|
||||
|
||||
/* Index by basic block number, get first insn in the block. */
|
||||
|
||||
extern rtx *basic_block_head;
|
||||
|
||||
/* Index by basic block number, get last insn in the block. */
|
||||
|
||||
extern rtx *basic_block_end;
|
||||
|
||||
/* Index by basic block number, get address of regset
|
||||
describing the registers live at the start of that block. */
|
||||
|
||||
extern regset *basic_block_live_at_start;
|
||||
|
||||
/* What registers are live at the setjmp call. */
|
||||
|
||||
extern regset regs_live_at_setjmp;
|
||||
|
||||
/* Indexed by n, gives number of basic block that (REG n) is used in.
|
||||
If the value is REG_BLOCK_GLOBAL (-2),
|
||||
it means (REG n) is used in more than one basic block.
|
||||
REG_BLOCK_UNKNOWN (-1) means it hasn't been seen yet so we don't know.
|
||||
This information remains valid for the rest of the compilation
|
||||
of the current function; it is used to control register allocation. */
|
||||
|
||||
#define REG_BLOCK_UNKNOWN -1
|
||||
#define REG_BLOCK_GLOBAL -2
|
||||
|
||||
#define REG_BASIC_BLOCK(N) (reg_n_info[(N)].basic_block)
|
133
bc-emit.h
Normal file
133
bc-emit.h
Normal file
@ -0,0 +1,133 @@
|
||||
/* bc-emit.h - declare entry points for producing object files of bytecodes. */
|
||||
|
||||
/* Internal format of symbol table for the object file. */
|
||||
struct bc_sym
|
||||
{
|
||||
/* Private copy separately malloc'd. */
|
||||
char *name;
|
||||
|
||||
/* Symbol has a defined value. */
|
||||
unsigned int defined:1;
|
||||
|
||||
/* Symbol has been globalized. */
|
||||
unsigned int global:1;
|
||||
|
||||
/* Symbol is common. */
|
||||
unsigned int common:1;
|
||||
|
||||
/* Value if defined. */
|
||||
unsigned long int val;
|
||||
|
||||
/* Used in internal symbol table structure. */
|
||||
struct bc_sym *next;
|
||||
};
|
||||
|
||||
|
||||
/* List of symbols defined in a particular segment. */
|
||||
struct bc_segsym
|
||||
{
|
||||
struct bc_sym *sym;
|
||||
struct bc_segsym *next;
|
||||
};
|
||||
|
||||
|
||||
/* List of relocations needed in a particular segment. */
|
||||
struct bc_segreloc
|
||||
{
|
||||
/* Offset of datum to be relocated. */
|
||||
unsigned int offset;
|
||||
|
||||
/* Symbol to be relocated by. */
|
||||
struct bc_sym *sym;
|
||||
|
||||
struct bc_segreloc *next;
|
||||
};
|
||||
|
||||
|
||||
/* Segment of an object file. */
|
||||
struct bc_seg
|
||||
{
|
||||
/* Size allocated to contents. */
|
||||
unsigned int alloc;
|
||||
|
||||
/* Pointer to base of contents. */
|
||||
char *data;
|
||||
|
||||
/* Actual size of contents. */
|
||||
unsigned int size;
|
||||
|
||||
/* List of symbols defined in this segment. */
|
||||
struct bc_segsym *syms;
|
||||
|
||||
/* List of relocations for this segment. */
|
||||
struct bc_segreloc *relocs;
|
||||
};
|
||||
|
||||
|
||||
/* Anonymous bytecode label within a single function. */
|
||||
struct bc_label
|
||||
{
|
||||
/* Offset of label from start of segment. */
|
||||
unsigned int offset;
|
||||
|
||||
/* True when offset is valid. */
|
||||
unsigned int defined:1;
|
||||
|
||||
/* Unique bytecode ID, used to determine innermost
|
||||
block containment */
|
||||
int uid;
|
||||
|
||||
/* Next node in list */
|
||||
struct bc_label *next;
|
||||
};
|
||||
|
||||
|
||||
/* Reference to a bc_label; a list of all such references is kept for
|
||||
the function, then when it is finished they are backpatched to
|
||||
contain the correct values. */
|
||||
|
||||
struct bc_labelref
|
||||
{
|
||||
/* Label referenced. */
|
||||
struct bc_label *label;
|
||||
|
||||
/* Code offset of reference. */
|
||||
unsigned int offset;
|
||||
|
||||
/* Next labelref in list */
|
||||
struct bc_labelref *next;
|
||||
};
|
||||
|
||||
|
||||
|
||||
extern void bc_initialize();
|
||||
extern int bc_begin_function();
|
||||
extern char *bc_emit_trampoline();
|
||||
extern void bc_emit_bytecode();
|
||||
extern void bc_emit_bytecode_const();
|
||||
extern struct bc_label *bc_get_bytecode_label();
|
||||
extern int bc_emit_bytecode_labeldef();
|
||||
extern void bc_emit_bytecode_labelref();
|
||||
extern void bc_emit_code_labelref();
|
||||
extern char *bc_end_function();
|
||||
extern void bc_align_const();
|
||||
extern void bc_emit_const();
|
||||
extern void bc_emit_const_skip();
|
||||
extern int bc_emit_const_labeldef();
|
||||
extern void bc_emit_const_labelref();
|
||||
extern void bc_align_data();
|
||||
extern void bc_emit_data();
|
||||
extern void bc_emit_data_skip();
|
||||
extern int bc_emit_data_labeldef();
|
||||
extern void bc_emit_data_labelref();
|
||||
extern int bc_define_pointer ();
|
||||
extern int bc_emit_common();
|
||||
extern void bc_globalize_label();
|
||||
extern void bc_text();
|
||||
extern void bc_data();
|
||||
extern void bc_align();
|
||||
extern void bc_emit();
|
||||
extern void bc_emit_skip();
|
||||
extern int bc_emit_labeldef();
|
||||
extern void bc_emit_labelref();
|
||||
extern void bc_write_file();
|
802
bc-optab.c
Normal file
802
bc-optab.c
Normal file
@ -0,0 +1,802 @@
|
||||
/* Bytecode conversion definitions for GNU C-compiler.
|
||||
Copyright (C) 1993, 1994, 1997 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#include "tree.h"
|
||||
#include "rtl.h"
|
||||
#include "machmode.h"
|
||||
#include "obstack.h"
|
||||
#include "bytecode.h"
|
||||
#include "bc-typecd.h"
|
||||
#include "bc-opcode.h"
|
||||
#include "bc-optab.h"
|
||||
|
||||
#define obstack_chunk_alloc xmalloc
|
||||
#define obstack_chunk_free free
|
||||
|
||||
extern char *xmalloc ();
|
||||
|
||||
/* Table relating interpreter typecodes to machine modes. */
|
||||
#define GET_TYPECODE_MODE(CODE) (typecode_mode[((int) CODE)])
|
||||
enum machine_mode typecode_mode[] = {
|
||||
#define DEFTYPECODE(CODE, NAME, MODE, TYPE) MODE,
|
||||
#include "bc-typecd.def"
|
||||
#undef DEFTYPECODE
|
||||
};
|
||||
|
||||
/* Machine mode to type code map */
|
||||
static enum typecode signed_mode_to_code_map[MAX_MACHINE_MODE+1];
|
||||
static enum typecode unsigned_mode_to_code_map[MAX_MACHINE_MODE+1];
|
||||
|
||||
#define GET_TYPECODE_SIZE(CODE) GET_MODE_SIZE (GET_TYPECODE_MODE (CODE))
|
||||
|
||||
#define BIG_ARBITRARY_NUMBER 100000
|
||||
|
||||
/* Table of recipes for conversions among scalar types, to be filled
|
||||
in as needed at run time. */
|
||||
static struct conversion_recipe
|
||||
{
|
||||
unsigned char *opcodes; /* Bytecodes to emit in order. */
|
||||
int nopcodes; /* Count of bytecodes. */
|
||||
int cost; /* A rather arbitrary cost function. */
|
||||
} conversion_recipe[NUM_TYPECODES][NUM_TYPECODES];
|
||||
|
||||
/* Binary operator tables. */
|
||||
struct binary_operator optab_plus_expr[] = {
|
||||
{ addSI, SIcode, SIcode, SIcode },
|
||||
{ addDI, DIcode, DIcode, DIcode },
|
||||
{ addSF, SFcode, SFcode, SFcode },
|
||||
{ addDF, DFcode, DFcode, DFcode },
|
||||
{ addXF, XFcode, XFcode, XFcode },
|
||||
{ addPSI, Pcode, Pcode, SIcode },
|
||||
{ -1, -1, -1, -1 },
|
||||
};
|
||||
|
||||
struct binary_operator optab_minus_expr[] = {
|
||||
{ subSI, SIcode, SIcode, SIcode },
|
||||
{ subDI, DIcode, DIcode, DIcode },
|
||||
{ subSF, SFcode, SFcode, SFcode },
|
||||
{ subDF, DFcode, DFcode, DFcode },
|
||||
{ subXF, XFcode, XFcode, XFcode },
|
||||
{ subPP, SIcode, Pcode, Pcode },
|
||||
{ -1, -1, -1, -1 },
|
||||
};
|
||||
|
||||
/* The ordering of the tables for multiplicative operators
|
||||
is such that unsigned operations will be preferred to signed
|
||||
operations when one argument is unsigned. */
|
||||
|
||||
struct binary_operator optab_mult_expr[] = {
|
||||
{ mulSU, SUcode, SUcode, SUcode },
|
||||
{ mulDU, DUcode, DUcode, DUcode },
|
||||
{ mulSI, SIcode, SIcode, SIcode },
|
||||
{ mulDI, DIcode, DIcode, DIcode },
|
||||
{ mulSF, SFcode, SFcode, SFcode },
|
||||
{ mulDF, DFcode, DFcode, DFcode },
|
||||
{ mulXF, XFcode, XFcode, XFcode },
|
||||
{ -1, -1, -1, -1 },
|
||||
};
|
||||
|
||||
struct binary_operator optab_trunc_div_expr[] = {
|
||||
{ divSU, SUcode, SUcode, SUcode },
|
||||
{ divDU, DUcode, DUcode, DUcode },
|
||||
{ divSI, SIcode, SIcode, SIcode },
|
||||
{ divDI, DIcode, DIcode, DIcode },
|
||||
{ -1, -1, -1, -1 },
|
||||
};
|
||||
|
||||
struct binary_operator optab_trunc_mod_expr[] = {
|
||||
{ modSU, SUcode, SUcode, SUcode },
|
||||
{ modDU, DUcode, DUcode, DUcode },
|
||||
{ modSI, SIcode, SIcode, SIcode },
|
||||
{ modDI, DIcode, DIcode, DIcode },
|
||||
{ -1, -1, -1, -1 },
|
||||
};
|
||||
|
||||
struct binary_operator optab_rdiv_expr[] = {
|
||||
{ divSF, SFcode, SFcode, SFcode },
|
||||
{ divDF, DFcode, DFcode, DFcode },
|
||||
{ divXF, XFcode, XFcode, XFcode },
|
||||
{ -1, -1, -1, -1 },
|
||||
};
|
||||
|
||||
struct binary_operator optab_bit_and_expr[] = {
|
||||
{ andSI, SIcode, SIcode, SIcode },
|
||||
{ andDI, DIcode, DIcode, DIcode },
|
||||
{ -1, -1, -1, -1 },
|
||||
};
|
||||
|
||||
struct binary_operator optab_bit_ior_expr[] = {
|
||||
{ iorSI, SIcode, SIcode, SIcode },
|
||||
{ iorDI, DIcode, DIcode, DIcode },
|
||||
{ -1, -1, -1, -1 },
|
||||
};
|
||||
|
||||
struct binary_operator optab_bit_xor_expr[] = {
|
||||
{ xorSI, SIcode, SIcode, SIcode },
|
||||
{ xorDI, DIcode, DIcode, DIcode },
|
||||
{ -1, -1, -1, -1 },
|
||||
};
|
||||
|
||||
struct binary_operator optab_lshift_expr[] = {
|
||||
{ lshiftSI, SIcode, SIcode, SIcode },
|
||||
{ lshiftSU, SUcode, SUcode, SIcode },
|
||||
{ lshiftDI, DIcode, DIcode, SIcode },
|
||||
{ lshiftDU, DUcode, DUcode, SIcode },
|
||||
{ -1, -1, -1, -1 },
|
||||
};
|
||||
|
||||
struct binary_operator optab_rshift_expr[] = {
|
||||
{ rshiftSI, SIcode, SIcode, SIcode },
|
||||
{ rshiftSU, SUcode, SUcode, SIcode },
|
||||
{ rshiftDI, DIcode, DIcode, SIcode },
|
||||
{ rshiftDU, DUcode, DUcode, SIcode },
|
||||
{ -1, -1, -1, -1 },
|
||||
};
|
||||
|
||||
struct binary_operator optab_truth_and_expr[] = {
|
||||
{ andSI, SIcode, Tcode, Tcode },
|
||||
{ -1, -1, -1, -1 },
|
||||
};
|
||||
|
||||
struct binary_operator optab_truth_or_expr[] = {
|
||||
{ iorSI, SIcode, Tcode, Tcode },
|
||||
{ -1, -1, -1, -1 },
|
||||
};
|
||||
|
||||
struct binary_operator optab_lt_expr[] = {
|
||||
{ ltSI, Tcode, SIcode, SIcode },
|
||||
{ ltSU, Tcode, SUcode, SUcode },
|
||||
{ ltDI, Tcode, DIcode, DIcode },
|
||||
{ ltDU, Tcode, DUcode, DUcode },
|
||||
{ ltSF, Tcode, SFcode, SFcode },
|
||||
{ ltDF, Tcode, DFcode, DFcode },
|
||||
{ ltXF, Tcode, XFcode, XFcode },
|
||||
{ ltP, Tcode, Pcode, Pcode },
|
||||
{ -1, -1, -1, -1 },
|
||||
};
|
||||
|
||||
struct binary_operator optab_le_expr[] = {
|
||||
{ leSI, Tcode, SIcode, SIcode },
|
||||
{ leSU, Tcode, SUcode, SUcode },
|
||||
{ leDI, Tcode, DIcode, DIcode },
|
||||
{ leDU, Tcode, DUcode, DUcode },
|
||||
{ leSF, Tcode, SFcode, SFcode },
|
||||
{ leDF, Tcode, DFcode, DFcode },
|
||||
{ leXF, Tcode, XFcode, XFcode },
|
||||
{ leP, Tcode, Pcode, Pcode },
|
||||
{ -1, -1, -1, -1 },
|
||||
};
|
||||
|
||||
struct binary_operator optab_ge_expr[] = {
|
||||
{ geSI, Tcode, SIcode, SIcode },
|
||||
{ geSU, Tcode, SUcode, SUcode },
|
||||
{ geDI, Tcode, DIcode, DIcode },
|
||||
{ geDU, Tcode, DUcode, DUcode },
|
||||
{ geSF, Tcode, SFcode, SFcode },
|
||||
{ geDF, Tcode, DFcode, DFcode },
|
||||
{ geXF, Tcode, XFcode, XFcode },
|
||||
{ geP, Tcode, Pcode, Pcode },
|
||||
{ -1, -1, -1, -1 },
|
||||
};
|
||||
|
||||
struct binary_operator optab_gt_expr[] = {
|
||||
{ gtSI, Tcode, SIcode, SIcode },
|
||||
{ gtSU, Tcode, SUcode, SUcode },
|
||||
{ gtDI, Tcode, DIcode, DIcode },
|
||||
{ gtDU, Tcode, DUcode, DUcode },
|
||||
{ gtSF, Tcode, SFcode, SFcode },
|
||||
{ gtDF, Tcode, DFcode, DFcode },
|
||||
{ gtXF, Tcode, XFcode, XFcode },
|
||||
{ gtP, Tcode, Pcode, Pcode },
|
||||
{ -1, -1, -1, -1 },
|
||||
};
|
||||
|
||||
struct binary_operator optab_eq_expr[] = {
|
||||
{ eqSI, Tcode, SIcode, SIcode },
|
||||
{ eqDI, Tcode, DIcode, DIcode },
|
||||
{ eqSF, Tcode, SFcode, SFcode },
|
||||
{ eqDF, Tcode, DFcode, DFcode },
|
||||
{ eqXF, Tcode, XFcode, XFcode },
|
||||
{ eqP, Tcode, Pcode, Pcode },
|
||||
{ -1, -1, -1, -1 },
|
||||
};
|
||||
|
||||
struct binary_operator optab_ne_expr[] = {
|
||||
{ neSI, Tcode, SIcode, SIcode },
|
||||
{ neDI, Tcode, DIcode, DIcode },
|
||||
{ neSF, Tcode, SFcode, SFcode },
|
||||
{ neDF, Tcode, DFcode, DFcode },
|
||||
{ neXF, Tcode, XFcode, XFcode },
|
||||
{ neP, Tcode, Pcode, Pcode },
|
||||
{ -1, -1, -1, -1 },
|
||||
};
|
||||
|
||||
/* Unary operator tables. */
|
||||
struct unary_operator optab_negate_expr[] = {
|
||||
{ negSI, SIcode, SIcode },
|
||||
{ negDI, DIcode, DIcode },
|
||||
{ negSF, SFcode, SFcode },
|
||||
{ negDF, DFcode, DFcode },
|
||||
{ negXF, XFcode, XFcode },
|
||||
{ -1, -1, -1 },
|
||||
};
|
||||
|
||||
struct unary_operator optab_bit_not_expr[] = {
|
||||
{ notSI, SIcode, SIcode },
|
||||
{ notDI, DIcode, DIcode },
|
||||
{ -1, -1, -1 },
|
||||
};
|
||||
|
||||
struct unary_operator optab_truth_not_expr[] = {
|
||||
{ notT, SIcode, SIcode },
|
||||
{ -1, -1, -1 },
|
||||
};
|
||||
|
||||
/* Increment operator tables. */
|
||||
struct increment_operator optab_predecrement_expr[] = {
|
||||
{ predecQI, QIcode },
|
||||
{ predecQI, QUcode },
|
||||
{ predecHI, HIcode },
|
||||
{ predecHI, HUcode },
|
||||
{ predecSI, SIcode },
|
||||
{ predecSI, SUcode },
|
||||
{ predecDI, DIcode },
|
||||
{ predecDI, DUcode },
|
||||
{ predecP, Pcode },
|
||||
{ predecSF, SFcode },
|
||||
{ predecDF, DFcode },
|
||||
{ predecXF, XFcode },
|
||||
{ -1, -1 },
|
||||
};
|
||||
|
||||
struct increment_operator optab_preincrement_expr[] = {
|
||||
{ preincQI, QIcode },
|
||||
{ preincQI, QUcode },
|
||||
{ preincHI, HIcode },
|
||||
{ preincHI, HUcode },
|
||||
{ preincSI, SIcode },
|
||||
{ preincSI, SUcode },
|
||||
{ preincDI, DIcode },
|
||||
{ preincDI, DUcode },
|
||||
{ preincP, Pcode },
|
||||
{ preincSF, SFcode },
|
||||
{ preincDF, DFcode },
|
||||
{ preincXF, XFcode },
|
||||
{ -1, -1 },
|
||||
};
|
||||
|
||||
struct increment_operator optab_postdecrement_expr[] = {
|
||||
{ postdecQI, QIcode },
|
||||
{ postdecQI, QUcode },
|
||||
{ postdecHI, HIcode },
|
||||
{ postdecHI, HUcode },
|
||||
{ postdecSI, SIcode },
|
||||
{ postdecSI, SUcode },
|
||||
{ postdecDI, DIcode },
|
||||
{ postdecDI, DUcode },
|
||||
{ postdecP, Pcode },
|
||||
{ postdecSF, SFcode },
|
||||
{ postdecDF, DFcode },
|
||||
{ postdecXF, XFcode },
|
||||
{ -1, -1 },
|
||||
};
|
||||
|
||||
struct increment_operator optab_postincrement_expr[] = {
|
||||
{ postincQI, QIcode },
|
||||
{ postincQI, QUcode },
|
||||
{ postincHI, HIcode },
|
||||
{ postincHI, HUcode },
|
||||
{ postincSI, SIcode },
|
||||
{ postincSI, SUcode },
|
||||
{ postincDI, DIcode },
|
||||
{ postincDI, DUcode },
|
||||
{ postincP, Pcode },
|
||||
{ postincSF, SFcode },
|
||||
{ postincDF, DFcode },
|
||||
{ postincXF, XFcode },
|
||||
{ -1, -1 },
|
||||
};
|
||||
|
||||
/* Table of conversions supported by the interpreter. */
|
||||
static struct conversion_info
|
||||
{
|
||||
enum bytecode_opcode opcode; /* here indicates the conversion needs no opcode. */
|
||||
enum typecode from;
|
||||
enum typecode to;
|
||||
int cost; /* 1 for no-op conversions, 2 for widening conversions,
|
||||
4 for int/float conversions, 8 for narrowing conversions. */
|
||||
} conversion_info[] = {
|
||||
{ -1, QIcode, QUcode, 1 },
|
||||
{ -1, HIcode, HUcode, 1 },
|
||||
{ -1, SIcode, SUcode, 1 },
|
||||
{ -1, DIcode, DUcode, 1 },
|
||||
{ -1, QUcode, QIcode, 1 },
|
||||
{ -1, HUcode, HIcode, 1 },
|
||||
{ -1, SUcode, SIcode, 1 },
|
||||
{ -1, DUcode, DIcode, 1 },
|
||||
{ -1, Tcode, SIcode, 1 },
|
||||
{ convertQIHI, QIcode, HIcode, 2 },
|
||||
{ convertQUHU, QUcode, HUcode, 2 },
|
||||
{ convertQUSU, QUcode, SUcode, 2 },
|
||||
{ convertHISI, HIcode, SIcode, 2 },
|
||||
{ convertHUSU, HUcode, SUcode, 2 },
|
||||
{ convertSIDI, SIcode, DIcode, 2 },
|
||||
{ convertSUDU, SUcode, DUcode, 2 },
|
||||
{ convertSFDF, SFcode, DFcode, 2 },
|
||||
{ convertDFXF, DFcode, XFcode, 2 },
|
||||
{ convertHIQI, HIcode, QIcode, 8 },
|
||||
{ convertSIQI, SIcode, QIcode, 8 },
|
||||
{ convertSIHI, SIcode, HIcode, 8 },
|
||||
{ convertSUQU, SUcode, QUcode, 8 },
|
||||
{ convertDISI, DIcode, SIcode, 8 },
|
||||
{ convertDFSF, DFcode, SFcode, 8 },
|
||||
{ convertXFDF, XFcode, DFcode, 8 },
|
||||
{ convertPSI, Pcode, SIcode, 2 },
|
||||
{ convertSIP, SIcode, Pcode, 2 },
|
||||
{ convertSIT, SIcode, Tcode, 2 },
|
||||
{ convertDIT, DIcode, Tcode, 2 },
|
||||
{ convertSFT, SFcode, Tcode, 2 },
|
||||
{ convertDFT, DFcode, Tcode, 2 },
|
||||
{ convertXFT, XFcode, Tcode, 2 },
|
||||
{ convertQISI, QIcode, SIcode, 2 },
|
||||
{ convertPT, Pcode, Tcode, 2 },
|
||||
{ convertSISF, SIcode, SFcode, 4 },
|
||||
{ convertSIDF, SIcode, DFcode, 4 },
|
||||
{ convertSIXF, SIcode, XFcode, 4 },
|
||||
{ convertSUSF, SUcode, SFcode, 4 },
|
||||
{ convertSUDF, SUcode, DFcode, 4 },
|
||||
{ convertSUXF, SUcode, XFcode, 4 },
|
||||
{ convertDISF, DIcode, SFcode, 4 },
|
||||
{ convertDIDF, DIcode, DFcode, 4 },
|
||||
{ convertDIXF, DIcode, XFcode, 4 },
|
||||
{ convertDUSF, DUcode, SFcode, 4 },
|
||||
{ convertDUDF, DUcode, DFcode, 4 },
|
||||
{ convertDUXF, DUcode, XFcode, 4 },
|
||||
{ convertSFSI, SFcode, SIcode, 4 },
|
||||
{ convertDFSI, DFcode, SIcode, 4 },
|
||||
{ convertXFSI, XFcode, SIcode, 4 },
|
||||
{ convertSFSU, SFcode, SUcode, 4 },
|
||||
{ convertDFSU, DFcode, SUcode, 4 },
|
||||
{ convertXFSU, XFcode, SUcode, 4 },
|
||||
{ convertSFDI, SFcode, DIcode, 4 },
|
||||
{ convertDFDI, DFcode, DIcode, 4 },
|
||||
{ convertXFDI, XFcode, DIcode, 4 },
|
||||
{ convertSFDU, SFcode, DUcode, 4 },
|
||||
{ convertDFDU, DFcode, DUcode, 4 },
|
||||
{ convertXFDU, XFcode, DUcode, 4 },
|
||||
{ convertSIQI, SIcode, QIcode, 8 },
|
||||
};
|
||||
|
||||
#define NUM_CONVERSIONS (sizeof conversion_info / sizeof (struct conversion_info))
|
||||
|
||||
/* List form of a conversion recipe. */
|
||||
struct conversion_list
|
||||
{
|
||||
enum bytecode_opcode opcode;
|
||||
enum typecode to;
|
||||
int cost;
|
||||
struct conversion_list *prev;
|
||||
};
|
||||
|
||||
/* Determine if it is "reasonable" to add a given conversion to
|
||||
a given list of conversions. The following criteria define
|
||||
"reasonable" conversion lists:
|
||||
* No typecode appears more than once in the sequence (no loops).
|
||||
* At most one conversion from integer to float or vice versa is present.
|
||||
* Either sign extensions or zero extensions may be present, but not both.
|
||||
* No widening conversions occur after a signed/unsigned conversion.
|
||||
* The sequence of sizes must be strict nonincreasing or nondecreasing. */
|
||||
|
||||
static int
|
||||
conversion_reasonable_p (conversion, list)
|
||||
struct conversion_info *conversion;
|
||||
struct conversion_list *list;
|
||||
{
|
||||
struct conversion_list *curr;
|
||||
int curr_size, prev_size;
|
||||
int has_int_float, has_float_int;
|
||||
int has_sign_extend, has_zero_extend;
|
||||
int has_signed_unsigned, has_unsigned_signed;
|
||||
|
||||
has_int_float = 0;
|
||||
has_float_int = 0;
|
||||
has_sign_extend = 0;
|
||||
has_zero_extend = 0;
|
||||
has_signed_unsigned = 0;
|
||||
has_unsigned_signed = 0;
|
||||
|
||||
/* Make sure the destination typecode doesn't already appear in
|
||||
the list. */
|
||||
for (curr = list; curr; curr = curr->prev)
|
||||
if (conversion->to == curr->to)
|
||||
return 0;
|
||||
|
||||
/* Check for certain kinds of conversions. */
|
||||
if (TYPECODE_INTEGER_P (conversion->from)
|
||||
&& TYPECODE_FLOAT_P (conversion->to))
|
||||
has_int_float = 1;
|
||||
if (TYPECODE_FLOAT_P (conversion->from)
|
||||
&& TYPECODE_INTEGER_P (conversion->to))
|
||||
has_float_int = 1;
|
||||
if (TYPECODE_SIGNED_P (conversion->from)
|
||||
&& TYPECODE_SIGNED_P (conversion->to)
|
||||
&& GET_TYPECODE_SIZE (conversion->from)
|
||||
< GET_TYPECODE_SIZE (conversion->to))
|
||||
has_sign_extend = 1;
|
||||
if (TYPECODE_UNSIGNED_P (conversion->from)
|
||||
&& TYPECODE_UNSIGNED_P (conversion->to)
|
||||
&& GET_TYPECODE_SIZE (conversion->from)
|
||||
< GET_TYPECODE_SIZE (conversion->to))
|
||||
has_zero_extend = 1;
|
||||
|
||||
for (curr = list; curr && curr->prev; curr = curr->prev)
|
||||
{
|
||||
if (TYPECODE_INTEGER_P (curr->prev->to)
|
||||
&& TYPECODE_FLOAT_P (curr->to))
|
||||
has_int_float = 1;
|
||||
if (TYPECODE_FLOAT_P (curr->prev->to)
|
||||
&& TYPECODE_INTEGER_P (curr->to))
|
||||
has_float_int = 1;
|
||||
if (TYPECODE_SIGNED_P (curr->prev->to)
|
||||
&& TYPECODE_SIGNED_P (curr->to)
|
||||
&& GET_TYPECODE_SIZE (curr->prev->to)
|
||||
< GET_TYPECODE_SIZE (curr->to))
|
||||
has_sign_extend = 1;
|
||||
if (TYPECODE_UNSIGNED_P (curr->prev->to)
|
||||
&& TYPECODE_UNSIGNED_P (curr->to)
|
||||
&& GET_TYPECODE_SIZE (curr->prev->to)
|
||||
< GET_TYPECODE_SIZE (curr->to))
|
||||
has_zero_extend = 1;
|
||||
if (TYPECODE_SIGNED_P (curr->prev->to)
|
||||
&& TYPECODE_UNSIGNED_P (curr->to))
|
||||
has_signed_unsigned = 1;
|
||||
if (TYPECODE_UNSIGNED_P (curr->prev->to)
|
||||
&& TYPECODE_SIGNED_P (curr->to))
|
||||
has_unsigned_signed = 1;
|
||||
}
|
||||
|
||||
if (TYPECODE_INTEGER_P (conversion->from)
|
||||
&& TYPECODE_INTEGER_P (conversion->to)
|
||||
&& GET_TYPECODE_SIZE (conversion->to)
|
||||
> GET_TYPECODE_SIZE (conversion->from)
|
||||
&& (has_signed_unsigned || has_unsigned_signed))
|
||||
return 0;
|
||||
|
||||
if (has_float_int && has_int_float || has_sign_extend && has_zero_extend)
|
||||
return 0;
|
||||
|
||||
/* Make sure the sequence of destination typecode sizes is
|
||||
strictly nondecreasing or strictly nonincreasing. */
|
||||
prev_size = GET_TYPECODE_SIZE (conversion->to);
|
||||
for (curr = list; curr; curr = curr->prev)
|
||||
{
|
||||
curr_size = GET_TYPECODE_SIZE (curr->to);
|
||||
if (curr_size != prev_size)
|
||||
break;
|
||||
}
|
||||
if (!curr)
|
||||
return 1;
|
||||
|
||||
if (curr_size < prev_size)
|
||||
for (prev_size = curr_size; curr; curr = curr->prev)
|
||||
{
|
||||
curr_size = GET_TYPECODE_SIZE (curr->to);
|
||||
if (curr_size > prev_size)
|
||||
return 0;
|
||||
prev_size = curr_size;
|
||||
}
|
||||
else
|
||||
for (prev_size = curr_size; curr; curr = curr->prev)
|
||||
{
|
||||
curr_size = GET_TYPECODE_SIZE (curr->to);
|
||||
if (curr_size < prev_size)
|
||||
return 0;
|
||||
prev_size = curr_size;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Exhaustively search all reasonable conversions to find one to
|
||||
convert the given types. */
|
||||
|
||||
static struct conversion_recipe
|
||||
deduce_conversion (from, to)
|
||||
enum typecode from, to;
|
||||
{
|
||||
struct rl
|
||||
{
|
||||
struct conversion_list *list;
|
||||
struct rl *next;
|
||||
} *prev, curr, *good, *temp;
|
||||
struct conversion_list *conv, *best;
|
||||
int i, cost, bestcost;
|
||||
struct conversion_recipe result;
|
||||
struct obstack recipe_obstack;
|
||||
|
||||
|
||||
obstack_init (&recipe_obstack);
|
||||
curr.next = (struct rl *) obstack_alloc (&recipe_obstack, sizeof (struct rl));
|
||||
curr.next->list
|
||||
= (struct conversion_list *) obstack_alloc (&recipe_obstack,
|
||||
sizeof (struct conversion_list));
|
||||
curr.next->list->opcode = -1;
|
||||
curr.next->list->to = from;
|
||||
curr.next->list->cost = 0;
|
||||
curr.next->list->prev = 0;
|
||||
curr.next->next = 0;
|
||||
good = 0;
|
||||
|
||||
while (curr.next)
|
||||
{
|
||||
/* Remove successful conversions from further consideration. */
|
||||
for (prev = &curr; prev; prev = prev->next)
|
||||
if (prev->next && prev->next->list->to == to)
|
||||
{
|
||||
temp = prev->next->next;
|
||||
prev->next->next = good;
|
||||
good = prev->next;
|
||||
prev->next = temp;
|
||||
}
|
||||
|
||||
/* Go through each of the pending conversion chains, trying
|
||||
all possible candidate conversions on them. */
|
||||
for (prev = curr.next, curr.next = 0; prev; prev = prev->next)
|
||||
for (i = 0; i < NUM_CONVERSIONS; ++i)
|
||||
if (conversion_info[i].from == prev->list->to
|
||||
&& conversion_reasonable_p (&conversion_info[i], prev->list))
|
||||
{
|
||||
temp = (struct rl *) obstack_alloc (&recipe_obstack,
|
||||
sizeof (struct rl));
|
||||
temp->list = (struct conversion_list *)
|
||||
obstack_alloc (&recipe_obstack,
|
||||
sizeof (struct conversion_list));
|
||||
temp->list->opcode = conversion_info[i].opcode;
|
||||
temp->list->to = conversion_info[i].to;
|
||||
temp->list->cost = conversion_info[i].cost;
|
||||
temp->list->prev = prev->list;
|
||||
temp->next = curr.next;
|
||||
curr.next = temp;
|
||||
}
|
||||
}
|
||||
|
||||
bestcost = BIG_ARBITRARY_NUMBER;
|
||||
best = 0;
|
||||
for (temp = good; temp; temp = temp->next)
|
||||
{
|
||||
for (conv = temp->list, cost = 0; conv; conv = conv->prev)
|
||||
cost += conv->cost;
|
||||
if (cost < bestcost)
|
||||
{
|
||||
bestcost = cost;
|
||||
best = temp->list;
|
||||
}
|
||||
}
|
||||
|
||||
if (!best)
|
||||
abort ();
|
||||
|
||||
for (i = 0, conv = best; conv; conv = conv->prev)
|
||||
if (conv->opcode != -1)
|
||||
++i;
|
||||
|
||||
result.opcodes = (unsigned char *) xmalloc (i);
|
||||
result.nopcodes = i;
|
||||
for (conv = best; conv; conv = conv->prev)
|
||||
if (conv->opcode != -1)
|
||||
result.opcodes[--i] = conv->opcode;
|
||||
result.cost = bestcost;
|
||||
obstack_free (&recipe_obstack, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
#define DEDUCE_CONVERSION(FROM, TO) \
|
||||
(conversion_recipe[(int) FROM][(int) TO].opcodes ? 0 \
|
||||
: (conversion_recipe[(int) FROM][(int) TO] \
|
||||
= deduce_conversion (FROM, TO), 0))
|
||||
|
||||
|
||||
/* Emit a conversion between the given scalar types. */
|
||||
|
||||
void
|
||||
emit_typecode_conversion (from, to)
|
||||
enum typecode from, to;
|
||||
{
|
||||
int i;
|
||||
|
||||
DEDUCE_CONVERSION (from, to);
|
||||
for (i = 0; i < conversion_recipe[(int) from][(int) to].nopcodes; ++i)
|
||||
bc_emit_instruction (conversion_recipe[(int) from][(int) to].opcodes[i]);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize mode_to_code_map[] */
|
||||
|
||||
void
|
||||
bc_init_mode_to_code_map ()
|
||||
{
|
||||
int mode;
|
||||
|
||||
for (mode = 0; mode < MAX_MACHINE_MODE + 1; mode++)
|
||||
{
|
||||
signed_mode_to_code_map[mode]
|
||||
= unsigned_mode_to_code_map[mode]
|
||||
= LAST_AND_UNUSED_TYPECODE;
|
||||
}
|
||||
|
||||
#define DEF_MODEMAP(SYM, CODE, UCODE, CONST, LOAD, STORE) \
|
||||
{ signed_mode_to_code_map[(int) SYM] = CODE; \
|
||||
unsigned_mode_to_code_map[(int) SYM] = UCODE; }
|
||||
#include "modemap.def"
|
||||
#undef DEF_MODEMAP
|
||||
|
||||
/* Initialize opcode maps for const, load, and store */
|
||||
bc_init_mode_to_opcode_maps ();
|
||||
}
|
||||
|
||||
/* Given a machine mode return the preferred typecode. */
|
||||
|
||||
enum typecode
|
||||
preferred_typecode (mode, unsignedp)
|
||||
enum machine_mode mode;
|
||||
int unsignedp;
|
||||
{
|
||||
enum typecode code = (unsignedp
|
||||
? unsigned_mode_to_code_map
|
||||
: signed_mode_to_code_map) [MIN ((int) mode,
|
||||
(int) MAX_MACHINE_MODE)];
|
||||
|
||||
if (code == LAST_AND_UNUSED_TYPECODE)
|
||||
abort ();
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
/* Expand a conversion between the given types. */
|
||||
|
||||
void
|
||||
bc_expand_conversion (from, to)
|
||||
tree from, to;
|
||||
{
|
||||
enum typecode fcode, tcode;
|
||||
|
||||
fcode = preferred_typecode (TYPE_MODE (from), TREE_UNSIGNED (from));
|
||||
tcode = preferred_typecode (TYPE_MODE (to), TREE_UNSIGNED (to));
|
||||
|
||||
emit_typecode_conversion (fcode, tcode);
|
||||
}
|
||||
|
||||
/* Expand a conversion of the given type to a truth value. */
|
||||
|
||||
void
|
||||
bc_expand_truth_conversion (from)
|
||||
tree from;
|
||||
{
|
||||
enum typecode fcode;
|
||||
|
||||
fcode = preferred_typecode (TYPE_MODE (from), TREE_UNSIGNED (from));
|
||||
emit_typecode_conversion (fcode, Tcode);
|
||||
}
|
||||
|
||||
/* Emit an appropriate binary operation. */
|
||||
|
||||
void
|
||||
bc_expand_binary_operation (optab, resulttype, arg0, arg1)
|
||||
struct binary_operator optab[];
|
||||
tree resulttype, arg0, arg1;
|
||||
{
|
||||
int i, besti, cost, bestcost;
|
||||
enum typecode resultcode, arg0code, arg1code;
|
||||
|
||||
resultcode = preferred_typecode (TYPE_MODE (resulttype), TREE_UNSIGNED (resulttype));
|
||||
arg0code = preferred_typecode (TYPE_MODE (TREE_TYPE (arg0)), TREE_UNSIGNED (resulttype));
|
||||
arg1code = preferred_typecode (TYPE_MODE (TREE_TYPE (arg1)), TREE_UNSIGNED (resulttype));
|
||||
|
||||
besti = -1;
|
||||
bestcost = BIG_ARBITRARY_NUMBER;
|
||||
|
||||
for (i = 0; optab[i].opcode != -1; ++i)
|
||||
{
|
||||
cost = 0;
|
||||
DEDUCE_CONVERSION (arg0code, optab[i].arg0);
|
||||
cost += conversion_recipe[(int) arg0code][(int) optab[i].arg0].cost;
|
||||
DEDUCE_CONVERSION (arg1code, optab[i].arg1);
|
||||
cost += conversion_recipe[(int) arg1code][(int) optab[i].arg1].cost;
|
||||
if (cost < bestcost)
|
||||
{
|
||||
besti = i;
|
||||
bestcost = cost;
|
||||
}
|
||||
}
|
||||
|
||||
if (besti == -1)
|
||||
abort ();
|
||||
|
||||
expand_expr (arg1, 0, VOIDmode, 0);
|
||||
emit_typecode_conversion (arg1code, optab[besti].arg1);
|
||||
expand_expr (arg0, 0, VOIDmode, 0);
|
||||
emit_typecode_conversion (arg0code, optab[besti].arg0);
|
||||
bc_emit_instruction (optab[besti].opcode);
|
||||
emit_typecode_conversion (optab[besti].result, resultcode);
|
||||
}
|
||||
|
||||
/* Emit an appropriate unary operation. */
|
||||
|
||||
void
|
||||
bc_expand_unary_operation (optab, resulttype, arg0)
|
||||
struct unary_operator optab[];
|
||||
tree resulttype, arg0;
|
||||
{
|
||||
int i, besti, cost, bestcost;
|
||||
enum typecode resultcode, arg0code;
|
||||
|
||||
resultcode = preferred_typecode (TYPE_MODE (resulttype), TREE_UNSIGNED (resulttype));
|
||||
arg0code = preferred_typecode (TYPE_MODE (TREE_TYPE (arg0)), TREE_UNSIGNED (TREE_TYPE (arg0)));
|
||||
|
||||
besti = -1;
|
||||
bestcost = BIG_ARBITRARY_NUMBER;
|
||||
|
||||
for (i = 0; optab[i].opcode != -1; ++i)
|
||||
{
|
||||
DEDUCE_CONVERSION (arg0code, optab[i].arg0);
|
||||
cost = conversion_recipe[(int) arg0code][(int) optab[i].arg0].cost;
|
||||
if (cost < bestcost)
|
||||
{
|
||||
besti = i;
|
||||
bestcost = cost;
|
||||
}
|
||||
}
|
||||
|
||||
if (besti == -1)
|
||||
abort ();
|
||||
|
||||
expand_expr (arg0, 0, VOIDmode, 0);
|
||||
emit_typecode_conversion (arg0code, optab[besti].arg0);
|
||||
bc_emit_instruction (optab[besti].opcode);
|
||||
emit_typecode_conversion (optab[besti].result, resultcode);
|
||||
}
|
||||
|
||||
|
||||
/* Emit an appropriate increment. */
|
||||
|
||||
void
|
||||
bc_expand_increment (optab, type)
|
||||
struct increment_operator optab[];
|
||||
tree type;
|
||||
{
|
||||
enum typecode code;
|
||||
int i;
|
||||
|
||||
code = preferred_typecode (TYPE_MODE (type), TREE_UNSIGNED (type));
|
||||
for (i = 0; (int) optab[i].opcode >= 0; ++i)
|
||||
if (code == optab[i].arg)
|
||||
{
|
||||
bc_emit_instruction (optab[i].opcode);
|
||||
return;
|
||||
}
|
||||
abort ();
|
||||
}
|
75
bc-optab.h
Normal file
75
bc-optab.h
Normal file
@ -0,0 +1,75 @@
|
||||
/* Bytecode token definitions for GNU C-compiler.
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
extern void bc_expand_conversion ();
|
||||
extern void bc_expand_truth_conversion ();
|
||||
extern void bc_expand_binary_operation ();
|
||||
extern void bc_expand_unary_operation ();
|
||||
|
||||
struct binary_operator
|
||||
{
|
||||
enum bytecode_opcode opcode;
|
||||
enum typecode result;
|
||||
enum typecode arg0;
|
||||
enum typecode arg1;
|
||||
};
|
||||
|
||||
extern struct binary_operator optab_plus_expr[];
|
||||
extern struct binary_operator optab_minus_expr[];
|
||||
extern struct binary_operator optab_mult_expr[];
|
||||
extern struct binary_operator optab_trunc_div_expr[];
|
||||
extern struct binary_operator optab_trunc_mod_expr[];
|
||||
extern struct binary_operator optab_rdiv_expr[];
|
||||
extern struct binary_operator optab_bit_and_expr[];
|
||||
extern struct binary_operator optab_bit_ior_expr[];
|
||||
extern struct binary_operator optab_bit_xor_expr[];
|
||||
extern struct binary_operator optab_lshift_expr[];
|
||||
extern struct binary_operator optab_rshift_expr[];
|
||||
extern struct binary_operator optab_truth_and_expr[];
|
||||
extern struct binary_operator optab_truth_or_expr[];
|
||||
extern struct binary_operator optab_lt_expr[];
|
||||
extern struct binary_operator optab_le_expr[];
|
||||
extern struct binary_operator optab_ge_expr[];
|
||||
extern struct binary_operator optab_gt_expr[];
|
||||
extern struct binary_operator optab_eq_expr[];
|
||||
extern struct binary_operator optab_ne_expr[];
|
||||
|
||||
struct unary_operator
|
||||
{
|
||||
enum bytecode_opcode opcode;
|
||||
enum typecode result;
|
||||
enum typecode arg0;
|
||||
};
|
||||
|
||||
extern struct unary_operator optab_negate_expr[];
|
||||
extern struct unary_operator optab_bit_not_expr[];
|
||||
extern struct unary_operator optab_truth_not_expr[];
|
||||
|
||||
struct increment_operator
|
||||
{
|
||||
enum bytecode_opcode opcode;
|
||||
enum typecode arg;
|
||||
};
|
||||
|
||||
extern struct increment_operator optab_predecrement_expr[];
|
||||
extern struct increment_operator optab_preincrement_expr[];
|
||||
extern struct increment_operator optab_postdecrement_expr[];
|
||||
extern struct increment_operator optab_postincrement_expr[];
|
21
bc-typecd.def
Normal file
21
bc-typecd.def
Normal file
@ -0,0 +1,21 @@
|
||||
/* Typecodes used by the interpreter and their related
|
||||
machine modes and types.
|
||||
|
||||
The last argument is used for retrieving the given
|
||||
type from a varargs list. Due to a bug in varargs,
|
||||
the type has to be the generic machine type of
|
||||
larger. */
|
||||
|
||||
DEFTYPECODE (QIcode, "QI", QImode, SItype)
|
||||
DEFTYPECODE (QUcode, "QU", QImode, SUtype)
|
||||
DEFTYPECODE (HIcode, "HI", HImode, SItype)
|
||||
DEFTYPECODE (HUcode, "HU", HImode, SUtype)
|
||||
DEFTYPECODE (SIcode, "SI", SImode, SItype)
|
||||
DEFTYPECODE (SUcode, "SU", SImode, SUtype)
|
||||
DEFTYPECODE (DIcode, "DI", DImode, DItype)
|
||||
DEFTYPECODE (DUcode, "DU", DImode, DUtype)
|
||||
DEFTYPECODE (SFcode, "SF", SFmode, SFtype)
|
||||
DEFTYPECODE (DFcode, "DF", DFmode, DFtype)
|
||||
DEFTYPECODE (XFcode, "XF", XFmode, XFtype)
|
||||
DEFTYPECODE (Pcode, "P", PSImode, Ptype)
|
||||
DEFTYPECODE (Tcode, "T", SImode, SItype)
|
54
bc-typecd.h
Normal file
54
bc-typecd.h
Normal file
@ -0,0 +1,54 @@
|
||||
/* Typecode definitions for Bytecode Interpreter.
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef TYPECODE_H
|
||||
#define TYPECODE_H
|
||||
|
||||
enum typecode
|
||||
{
|
||||
#define DEFTYPECODE(CODE, NAME, MACHMODE, TYPE) CODE,
|
||||
#include "bc-typecd.def"
|
||||
#undef DEFTYPECODE
|
||||
|
||||
LAST_AND_UNUSED_TYPECODE
|
||||
};
|
||||
|
||||
/* Determine if a given type is integer. */
|
||||
#define TYPECODE_INTEGER_P(TYPECODE) ((int) (TYPECODE) < (int) SFcode)
|
||||
|
||||
/* Determine if a given type is unsigned. */
|
||||
#define TYPECODE_UNSIGNED_P(TYPECODE) \
|
||||
(TYPECODE_INTEGER_P(TYPECODE) && (int) (TYPECODE) & 1)
|
||||
|
||||
/* Determine if a given type is signed. */
|
||||
#define TYPECODE_SIGNED_P(TYPECODE) \
|
||||
(TYPECODE_INTEGER_P(TYPECODE) && !((int) (TYPECODE) & 1))
|
||||
|
||||
/* Determine if a given type is floating. */
|
||||
#define TYPECODE_FLOAT_P(TYPECODE) \
|
||||
((int) (TYPECODE) < (int) Pcode && !TYPECODE_INTEGER_P(TYPECODE))
|
||||
|
||||
/* Determine if the given type is arithmetic. */
|
||||
#define TYPECODE_ARITH_P(TYPECODE) \
|
||||
(TYPECODE_INTEGER_P(TYPECODE) || TYPECODE_FLOAT_P(TYPECODE))
|
||||
|
||||
#define NUM_TYPECODES ((int) LAST_AND_UNUSED_TYPECODE)
|
||||
|
||||
#endif
|
91
bi-arity.c
Normal file
91
bi-arity.c
Normal file
@ -0,0 +1,91 @@
|
||||
/* Bytecode Interpreter utility to generate arity table.
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "hconfig.h"
|
||||
#include "bi-defs.h"
|
||||
|
||||
int
|
||||
length (n)
|
||||
struct node *n;
|
||||
{
|
||||
int k;
|
||||
|
||||
for (k = 0; n; n = n->next)
|
||||
++k;
|
||||
return k;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
struct def *d;
|
||||
struct variation *v;
|
||||
struct node *n;
|
||||
|
||||
yyparse ();
|
||||
reverse ();
|
||||
|
||||
for (d = defs; d; d = d->next)
|
||||
for (v = d->variations; v; v = v->next)
|
||||
{
|
||||
printf ("{ %d, %d, %d, {", length (v->inputs),
|
||||
length (v->outputs), length (v->literals));
|
||||
for (n = v->literals; n; n = n->next)
|
||||
printf ("(char) %scode, ", n->text);
|
||||
if (v->literals == 0)
|
||||
printf ("0");
|
||||
printf ("}},\n");
|
||||
}
|
||||
|
||||
fflush (stdout);
|
||||
exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Safely allocate NBYTES bytes of memory. Returns pointer to block of
|
||||
memory. */
|
||||
|
||||
char *
|
||||
xmalloc (nbytes)
|
||||
int nbytes;
|
||||
{
|
||||
char *tmp = (char *) malloc (nbytes);
|
||||
|
||||
if (!tmp)
|
||||
{
|
||||
fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n", nbytes);
|
||||
exit (FATAL_EXIT_CODE);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* More 'friendly' abort that prints the line and file.
|
||||
config.h can #define abort fancy_abort if you like that sort of thing. */
|
||||
|
||||
void
|
||||
fancy_abort ()
|
||||
{
|
||||
fprintf (stderr, "Internal gcc abort.\n");
|
||||
exit (FATAL_EXIT_CODE);
|
||||
}
|
48
bi-defs.h
Normal file
48
bi-defs.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* Definitions for Bytecode Interpreter.
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
struct node
|
||||
{
|
||||
char *text;
|
||||
struct node *next;
|
||||
};
|
||||
|
||||
struct variation
|
||||
{
|
||||
char *name;
|
||||
int code;
|
||||
struct node *inputs;
|
||||
struct node *outputs;
|
||||
struct node *literals;
|
||||
struct variation *next;
|
||||
};
|
||||
|
||||
struct def
|
||||
{
|
||||
char *basename;
|
||||
char *template;
|
||||
struct variation *variations;
|
||||
struct def *next;
|
||||
};
|
||||
|
||||
extern struct def *defs;
|
||||
extern int ndefs;
|
||||
extern void reverse();
|
167
bi-lexer.c
Normal file
167
bi-lexer.c
Normal file
@ -0,0 +1,167 @@
|
||||
/* Lexer for scanner of bytecode definition file.
|
||||
Copyright (C) 1993, 1995 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "hconfig.h"
|
||||
#include "bi-parser.h"
|
||||
|
||||
|
||||
/* Safely allocate NBYTES bytes of memory. Returns pointer to block of
|
||||
memory. */
|
||||
|
||||
static char *
|
||||
xmalloc (nbytes)
|
||||
int nbytes;
|
||||
{
|
||||
char *tmp = (char *) malloc (nbytes);
|
||||
|
||||
if (!tmp)
|
||||
{
|
||||
fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n", nbytes);
|
||||
exit (FATAL_EXIT_CODE);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
/* Safely reallocate BLOCK so its size becomes NBYTES.
|
||||
The block returned may be different from the one supplied. */
|
||||
|
||||
static char *
|
||||
xrealloc (block, nbytes)
|
||||
char *block;
|
||||
int nbytes;
|
||||
{
|
||||
char *tmp = (block
|
||||
? (char *) realloc (block, nbytes)
|
||||
: (char *) malloc (nbytes));
|
||||
|
||||
if (!tmp)
|
||||
{
|
||||
fprintf (stderr, "can't reallocate %d bytes (out of virtual memory)\n", nbytes);
|
||||
exit (FATAL_EXIT_CODE);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
/* Scan for string token on standard input. A string is, for our
|
||||
purposes here, a sequence of characters that starts with the regexp
|
||||
``[^ #\t\n(),]'' and is then followed by the regexp ``[^#(),]*''. Any
|
||||
character is accepted if preceded by a backslash, "\\". It is assumed
|
||||
that the first character has already been checked by the main loop. */
|
||||
|
||||
static char *
|
||||
scan_string ()
|
||||
{
|
||||
char *buffer = NULL;
|
||||
char *point = NULL;
|
||||
int buffer_size = 0;
|
||||
int c;
|
||||
|
||||
while ((c = getc (stdin)) != EOF
|
||||
&& c != '#' && c != '(' && c != ')' && c != ',')
|
||||
{
|
||||
/* Extend buffer, if necessary (minus two so there's room for the NUL
|
||||
trailer as well as another character if this one is a backslash). */
|
||||
if (!buffer_size || (point - buffer >= buffer_size-2))
|
||||
{
|
||||
int previous_point_index = point - buffer;
|
||||
|
||||
buffer_size = (!buffer_size ? 32 : buffer_size * 2);
|
||||
if (!buffer)
|
||||
buffer = xmalloc (buffer_size);
|
||||
else
|
||||
buffer = xrealloc (buffer, buffer_size);
|
||||
|
||||
point = buffer + previous_point_index;
|
||||
}
|
||||
*point++ = c & 0xff;
|
||||
|
||||
if (c == '\\')
|
||||
{
|
||||
c = getc (stdin);
|
||||
|
||||
/* Catch special case: backslash at end of file */
|
||||
if (c == EOF)
|
||||
break;
|
||||
|
||||
*point++ = c;
|
||||
}
|
||||
}
|
||||
*point = 0;
|
||||
|
||||
if (c != EOF)
|
||||
ungetc (c, stdin);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
yylex ()
|
||||
{
|
||||
int c;
|
||||
char *token;
|
||||
|
||||
|
||||
/* First char determines what token we're looking at */
|
||||
for (;;)
|
||||
{
|
||||
c = getc (stdin);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case EOF:
|
||||
return 0;
|
||||
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
/* Ignore whitespace */
|
||||
continue;
|
||||
|
||||
case '#':
|
||||
/* Comments advance to next line */
|
||||
while ((c = getc (stdin)) != '\n' && c != EOF);
|
||||
continue;
|
||||
|
||||
default:
|
||||
if (c != '(' && c != ')' && c != '\\' && c != ',')
|
||||
{
|
||||
ungetc (c, stdin);
|
||||
yylval.string = scan_string ();
|
||||
|
||||
/* Check if string is "define_operator"; if so, return
|
||||
a DEFOP token instead. */
|
||||
if (!strcmp (yylval.string, "define_operator"))
|
||||
{
|
||||
free (yylval.string);
|
||||
yylval.string = 0;
|
||||
return DEFOP;
|
||||
}
|
||||
return STRING;
|
||||
}
|
||||
return c & 0xff;
|
||||
}
|
||||
}
|
||||
}
|
89
bi-opcode.c
Normal file
89
bi-opcode.c
Normal file
@ -0,0 +1,89 @@
|
||||
/* Utility to generate opcode list from bytecode definition.
|
||||
Copyright (C) 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "hconfig.h"
|
||||
#include "bi-defs.h"
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
struct def *d;
|
||||
struct variation *v;
|
||||
int i;
|
||||
|
||||
yyparse();
|
||||
reverse();
|
||||
|
||||
|
||||
printf ("/* This file is automatically generated from bytecode.def,\n");
|
||||
printf ("do not make any changes here. Instead edit bytecode.def. */\n\n");
|
||||
printf ("enum bytecode_opcode\n{");
|
||||
|
||||
i = 0;
|
||||
for (d = defs; d; d = d->next)
|
||||
for (v = d->variations; v; v = v->next)
|
||||
{
|
||||
printf (" %s%s,\n", d->basename, v->name);
|
||||
++i;
|
||||
}
|
||||
|
||||
puts (" LAST_AND_UNUSED_OPCODE\n};");
|
||||
|
||||
if (i > 256)
|
||||
fprintf (stderr, "%s: warning, number of opcodes is %d\n", *argv, i);
|
||||
else
|
||||
fprintf (stderr, "(Number of opcodes is %d)\n", i);
|
||||
|
||||
fflush (stdout);
|
||||
exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Safely allocate NBYTES bytes of memory. Returns pointer to block of
|
||||
memory. */
|
||||
|
||||
char *
|
||||
xmalloc (nbytes)
|
||||
int nbytes;
|
||||
{
|
||||
char *tmp = (char *) malloc (nbytes);
|
||||
|
||||
if (!tmp)
|
||||
{
|
||||
fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n", nbytes);
|
||||
exit (FATAL_EXIT_CODE);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* More 'friendly' abort that prints the line and file.
|
||||
config.h can #define abort fancy_abort if you like that sort of thing. */
|
||||
|
||||
void
|
||||
fancy_abort ()
|
||||
{
|
||||
fprintf (stderr, "Internal gcc abort.\n");
|
||||
exit (FATAL_EXIT_CODE);
|
||||
}
|
70
bi-opname.c
Normal file
70
bi-opname.c
Normal file
@ -0,0 +1,70 @@
|
||||
/* Utility to generate opcode name list from bytecode definition file.
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "hconfig.h"
|
||||
#include "bi-defs.h"
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
struct def *d;
|
||||
struct variation *v;
|
||||
|
||||
yyparse();
|
||||
reverse();
|
||||
|
||||
for (d = defs; d; d = d->next)
|
||||
for (v = d->variations; v; v = v->next)
|
||||
printf("\"%s%s\",\n", d->basename, v->name);
|
||||
|
||||
fflush (stdout);
|
||||
exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Safely allocate NBYTES bytes of memory. Returns pointer to block of
|
||||
memory. */
|
||||
|
||||
char *
|
||||
xmalloc (nbytes)
|
||||
int nbytes;
|
||||
{
|
||||
char *tmp = (char *) malloc (nbytes);
|
||||
|
||||
if (!tmp)
|
||||
{
|
||||
fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n", nbytes);
|
||||
exit (FATAL_EXIT_CODE);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* More 'friendly' abort that prints the line and file.
|
||||
config.h can #define abort fancy_abort if you like that sort of thing. */
|
||||
|
||||
void
|
||||
fancy_abort ()
|
||||
{
|
||||
fprintf (stderr, "Internal gcc abort.\n");
|
||||
exit (FATAL_EXIT_CODE);
|
||||
}
|
968
bi-parser.c
Normal file
968
bi-parser.c
Normal file
@ -0,0 +1,968 @@
|
||||
|
||||
/* A Bison parser, made from bi-parser.y
|
||||
by Bison version A2.5 (Andrew Consortium)
|
||||
*/
|
||||
|
||||
#define YYBISON 1 /* Identify Bison output. */
|
||||
|
||||
#define DEFOP 258
|
||||
#define STRING 259
|
||||
|
||||
#line 22 "bi-parser.y"
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "hconfig.h"
|
||||
#include "bi-defs.h"
|
||||
|
||||
extern char yytext[];
|
||||
extern int yyleng;
|
||||
|
||||
|
||||
/* Chain of all defs built by the parser. */
|
||||
struct def *defs;
|
||||
int ndefs;
|
||||
|
||||
static struct node *makenode ();
|
||||
static struct variation *makevar ();
|
||||
static struct def *makedef ();
|
||||
|
||||
void yyerror ();
|
||||
|
||||
|
||||
#line 44 "bi-parser.y"
|
||||
typedef union
|
||||
{
|
||||
char *string;
|
||||
struct def *def;
|
||||
struct variation *variation;
|
||||
struct node *node;
|
||||
} YYSTYPE;
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef __cplusplus
|
||||
#ifndef __STDC__
|
||||
#define const
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define YYFINAL 39
|
||||
#define YYFLAG -32768
|
||||
#define YYNTBASE 8
|
||||
|
||||
#define YYTRANSLATE(x) ((unsigned)(x) <= 259 ? yytranslate[x] : 17)
|
||||
|
||||
static const char yytranslate[] = { 0,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 5,
|
||||
7, 2, 2, 6, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 1, 2, 3, 4
|
||||
};
|
||||
|
||||
#if YYDEBUG != 0
|
||||
static const short yyprhs[] = { 0,
|
||||
0, 2, 4, 7, 18, 20, 24, 28, 34, 42,
|
||||
52, 53, 55, 59, 60, 62, 66
|
||||
};
|
||||
|
||||
static const short yyrhs[] = { 9,
|
||||
0, 10, 0, 9, 10, 0, 3, 5, 4, 6,
|
||||
13, 6, 5, 11, 7, 7, 0, 12, 0, 11,
|
||||
6, 12, 0, 5, 13, 7, 0, 5, 13, 6,
|
||||
14, 7, 0, 5, 13, 6, 14, 6, 14, 7,
|
||||
0, 5, 13, 6, 14, 6, 14, 6, 14, 7,
|
||||
0, 0, 4, 0, 5, 15, 7, 0, 0, 16,
|
||||
0, 16, 6, 15, 0, 4, 0
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if YYDEBUG != 0
|
||||
static const short yyrline[] = { 0,
|
||||
60, 65, 67, 71, 76, 78, 82, 85, 87, 89,
|
||||
93, 95, 98, 101, 105, 108, 112
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#if YYDEBUG != 0
|
||||
|
||||
static const char * const yytname[] = { "$","error","$undefined.","DEFOP",
|
||||
"STRING","'('","','","')'","top","defs","def","variations","variation","opt_string",
|
||||
"list","items","item", NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
static const short yyr1[] = { 0,
|
||||
8, 9, 9, 10, 11, 11, 12, 12, 12, 12,
|
||||
13, 13, 14, 14, 15, 15, 16
|
||||
};
|
||||
|
||||
static const short yyr2[] = { 0,
|
||||
1, 1, 2, 10, 1, 3, 3, 5, 7, 9,
|
||||
0, 1, 3, 0, 1, 3, 1
|
||||
};
|
||||
|
||||
static const short yydefact[] = { 0,
|
||||
0, 1, 2, 0, 3, 0, 11, 12, 0, 0,
|
||||
0, 11, 0, 5, 0, 0, 0, 14, 7, 6,
|
||||
4, 0, 0, 17, 0, 15, 14, 8, 13, 0,
|
||||
0, 16, 14, 9, 0, 10, 0, 0, 0
|
||||
};
|
||||
|
||||
static const short yydefgoto[] = { 37,
|
||||
2, 3, 13, 14, 9, 23, 25, 26
|
||||
};
|
||||
|
||||
static const short yypact[] = { 2,
|
||||
6, 2,-32768, 8,-32768, 7, 10,-32768, 9, 11,
|
||||
12, 10, -5,-32768, -3, 12, 13, 14,-32768,-32768,
|
||||
-32768, 17, 1,-32768, 15, 18, 14,-32768,-32768, 17,
|
||||
3,-32768, 14,-32768, 16,-32768, 25, 26,-32768
|
||||
};
|
||||
|
||||
static const short yypgoto[] = {-32768,
|
||||
-32768, 27,-32768, 19, 20, -27, -12,-32768
|
||||
};
|
||||
|
||||
|
||||
#define YYLAST 35
|
||||
|
||||
|
||||
static const short yytable[] = { 31,
|
||||
16, 17, 18, 19, 1, 35, 27, 28, 33, 34,
|
||||
4, 6, 7, 8, 10, 11, 12, 32, 22, 21,
|
||||
24, 29, 36, 30, 38, 39, 0, 0, 5, 0,
|
||||
0, 15, 0, 0, 20
|
||||
};
|
||||
|
||||
static const short yycheck[] = { 27,
|
||||
6, 7, 6, 7, 3, 33, 6, 7, 6, 7,
|
||||
5, 4, 6, 4, 6, 5, 5, 30, 5, 7,
|
||||
4, 7, 7, 6, 0, 0, -1, -1, 2, -1,
|
||||
-1, 12, -1, -1, 16
|
||||
};
|
||||
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
|
||||
#line 3 "/usr/share/bison.simple"
|
||||
|
||||
/* Skeleton output parser for bison,
|
||||
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* As a special exception, when this file is copied by Bison into a
|
||||
Bison output file, you may use that output file without restriction.
|
||||
This special exception was added by the Free Software Foundation
|
||||
in version 1.24 of Bison. */
|
||||
|
||||
#ifndef alloca
|
||||
#ifdef __GNUC__
|
||||
#define alloca __builtin_alloca
|
||||
#else /* not GNU C. */
|
||||
#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
|
||||
#include <alloca.h>
|
||||
#else /* not sparc */
|
||||
#if defined (MSDOS) && !defined (__TURBOC__)
|
||||
#include <malloc.h>
|
||||
#else /* not MSDOS, or __TURBOC__ */
|
||||
#if defined(_AIX)
|
||||
#include <malloc.h>
|
||||
#pragma alloca
|
||||
#else /* not MSDOS, __TURBOC__, or _AIX */
|
||||
#ifdef __hpux
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
void *alloca (unsigned int);
|
||||
};
|
||||
#else /* not __cplusplus */
|
||||
void *alloca ();
|
||||
#endif /* not __cplusplus */
|
||||
#endif /* __hpux */
|
||||
#endif /* not _AIX */
|
||||
#endif /* not MSDOS, or __TURBOC__ */
|
||||
#endif /* not sparc. */
|
||||
#endif /* not GNU C. */
|
||||
#endif /* alloca not defined. */
|
||||
|
||||
/* This is the parser code that is written into each bison parser
|
||||
when the %semantic_parser declaration is not specified in the grammar.
|
||||
It was written by Richard Stallman by simplifying the hairy parser
|
||||
used when %semantic_parser is specified. */
|
||||
|
||||
/* Note: there must be only one dollar sign in this file.
|
||||
It is replaced by the list of actions, each action
|
||||
as one case of the switch. */
|
||||
|
||||
#define yyerrok (yyerrstatus = 0)
|
||||
#define yyclearin (yychar = YYEMPTY)
|
||||
#define YYEMPTY -2
|
||||
#define YYEOF 0
|
||||
#define YYACCEPT return(0)
|
||||
#define YYABORT return(1)
|
||||
#define YYERROR goto yyerrlab1
|
||||
/* Like YYERROR except do call yyerror.
|
||||
This remains here temporarily to ease the
|
||||
transition to the new meaning of YYERROR, for GCC.
|
||||
Once GCC version 2 has supplanted version 1, this can go. */
|
||||
#define YYFAIL goto yyerrlab
|
||||
#define YYRECOVERING() (!!yyerrstatus)
|
||||
#define YYBACKUP(token, value) \
|
||||
do \
|
||||
if (yychar == YYEMPTY && yylen == 1) \
|
||||
{ yychar = (token), yylval = (value); \
|
||||
yychar1 = YYTRANSLATE (yychar); \
|
||||
YYPOPSTACK; \
|
||||
goto yybackup; \
|
||||
} \
|
||||
else \
|
||||
{ yyerror ("syntax error: cannot back up"); YYERROR; } \
|
||||
while (0)
|
||||
|
||||
#define YYTERROR 1
|
||||
#define YYERRCODE 256
|
||||
|
||||
#ifndef YYPURE
|
||||
#define YYLEX yylex()
|
||||
#endif
|
||||
|
||||
#ifdef YYPURE
|
||||
#ifdef YYLSP_NEEDED
|
||||
#ifdef YYLEX_PARAM
|
||||
#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
|
||||
#else
|
||||
#define YYLEX yylex(&yylval, &yylloc)
|
||||
#endif
|
||||
#else /* not YYLSP_NEEDED */
|
||||
#ifdef YYLEX_PARAM
|
||||
#define YYLEX yylex(&yylval, YYLEX_PARAM)
|
||||
#else
|
||||
#define YYLEX yylex(&yylval)
|
||||
#endif
|
||||
#endif /* not YYLSP_NEEDED */
|
||||
#endif
|
||||
|
||||
/* If nonreentrant, generate the variables here */
|
||||
|
||||
#ifndef YYPURE
|
||||
|
||||
int yychar; /* the lookahead symbol */
|
||||
YYSTYPE yylval; /* the semantic value of the */
|
||||
/* lookahead symbol */
|
||||
|
||||
#ifdef YYLSP_NEEDED
|
||||
YYLTYPE yylloc; /* location data for the lookahead */
|
||||
/* symbol */
|
||||
#endif
|
||||
|
||||
int yynerrs; /* number of parse errors so far */
|
||||
#endif /* not YYPURE */
|
||||
|
||||
#if YYDEBUG != 0
|
||||
int yydebug; /* nonzero means print parse trace */
|
||||
/* Since this is uninitialized, it does not stop multiple parsers
|
||||
from coexisting. */
|
||||
#endif
|
||||
|
||||
/* YYINITDEPTH indicates the initial size of the parser's stacks */
|
||||
|
||||
#ifndef YYINITDEPTH
|
||||
#define YYINITDEPTH 200
|
||||
#endif
|
||||
|
||||
/* YYMAXDEPTH is the maximum size the stacks can grow to
|
||||
(effective only if the built-in stack extension method is used). */
|
||||
|
||||
#if YYMAXDEPTH == 0
|
||||
#undef YYMAXDEPTH
|
||||
#endif
|
||||
|
||||
#ifndef YYMAXDEPTH
|
||||
#define YYMAXDEPTH 10000
|
||||
#endif
|
||||
|
||||
/* Prevent warning if -Wstrict-prototypes. */
|
||||
#ifdef __GNUC__
|
||||
int yyparse (void);
|
||||
#endif
|
||||
|
||||
#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
|
||||
#define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT)
|
||||
#else /* not GNU C or C++ */
|
||||
#ifndef __cplusplus
|
||||
|
||||
/* This is the most reliable way to avoid incompatibilities
|
||||
in available built-in functions on various systems. */
|
||||
static void
|
||||
__yy_memcpy (from, to, count)
|
||||
char *from;
|
||||
char *to;
|
||||
int count;
|
||||
{
|
||||
register char *f = from;
|
||||
register char *t = to;
|
||||
register int i = count;
|
||||
|
||||
while (i-- > 0)
|
||||
*t++ = *f++;
|
||||
}
|
||||
|
||||
#else /* __cplusplus */
|
||||
|
||||
/* This is the most reliable way to avoid incompatibilities
|
||||
in available built-in functions on various systems. */
|
||||
static void
|
||||
__yy_memcpy (char *from, char *to, int count)
|
||||
{
|
||||
register char *f = from;
|
||||
register char *t = to;
|
||||
register int i = count;
|
||||
|
||||
while (i-- > 0)
|
||||
*t++ = *f++;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#line 192 "/usr/share/bison.simple"
|
||||
|
||||
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
|
||||
into yyparse. The argument should have type void *.
|
||||
It should actually point to an object.
|
||||
Grammar actions can access the variable by casting it
|
||||
to the proper pointer type. */
|
||||
|
||||
#ifdef YYPARSE_PARAM
|
||||
#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
|
||||
#else
|
||||
#define YYPARSE_PARAM
|
||||
#define YYPARSE_PARAM_DECL
|
||||
#endif
|
||||
|
||||
int
|
||||
yyparse(YYPARSE_PARAM)
|
||||
YYPARSE_PARAM_DECL
|
||||
{
|
||||
register int yystate;
|
||||
register int yyn;
|
||||
register short *yyssp;
|
||||
register YYSTYPE *yyvsp;
|
||||
int yyerrstatus; /* number of tokens to shift before error messages enabled */
|
||||
int yychar1 = 0; /* lookahead token as an internal (translated) token number */
|
||||
|
||||
short yyssa[YYINITDEPTH]; /* the state stack */
|
||||
YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
|
||||
|
||||
short *yyss = yyssa; /* refer to the stacks thru separate pointers */
|
||||
YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
|
||||
|
||||
#ifdef YYLSP_NEEDED
|
||||
YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
|
||||
YYLTYPE *yyls = yylsa;
|
||||
YYLTYPE *yylsp;
|
||||
|
||||
#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
|
||||
#else
|
||||
#define YYPOPSTACK (yyvsp--, yyssp--)
|
||||
#endif
|
||||
|
||||
int yystacksize = YYINITDEPTH;
|
||||
|
||||
#ifdef YYPURE
|
||||
int yychar;
|
||||
YYSTYPE yylval;
|
||||
int yynerrs;
|
||||
#ifdef YYLSP_NEEDED
|
||||
YYLTYPE yylloc;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
YYSTYPE yyval; /* the variable used to return */
|
||||
/* semantic values from the action */
|
||||
/* routines */
|
||||
|
||||
int yylen;
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Starting parse\n");
|
||||
#endif
|
||||
|
||||
yystate = 0;
|
||||
yyerrstatus = 0;
|
||||
yynerrs = 0;
|
||||
yychar = YYEMPTY; /* Cause a token to be read. */
|
||||
|
||||
/* Initialize stack pointers.
|
||||
Waste one element of value and location stack
|
||||
so that they stay on the same level as the state stack.
|
||||
The wasted elements are never initialized. */
|
||||
|
||||
yyssp = yyss - 1;
|
||||
yyvsp = yyvs;
|
||||
#ifdef YYLSP_NEEDED
|
||||
yylsp = yyls;
|
||||
#endif
|
||||
|
||||
/* Push a new state, which is found in yystate . */
|
||||
/* In all cases, when you get here, the value and location stacks
|
||||
have just been pushed. so pushing a state here evens the stacks. */
|
||||
yynewstate:
|
||||
|
||||
*++yyssp = yystate;
|
||||
|
||||
if (yyssp >= yyss + yystacksize - 1)
|
||||
{
|
||||
/* Give user a chance to reallocate the stack */
|
||||
/* Use copies of these so that the &'s don't force the real ones into memory. */
|
||||
YYSTYPE *yyvs1 = yyvs;
|
||||
short *yyss1 = yyss;
|
||||
#ifdef YYLSP_NEEDED
|
||||
YYLTYPE *yyls1 = yyls;
|
||||
#endif
|
||||
|
||||
/* Get the current used size of the three stacks, in elements. */
|
||||
int size = yyssp - yyss + 1;
|
||||
|
||||
#ifdef yyoverflow
|
||||
/* Each stack pointer address is followed by the size of
|
||||
the data in use in that stack, in bytes. */
|
||||
#ifdef YYLSP_NEEDED
|
||||
/* This used to be a conditional around just the two extra args,
|
||||
but that might be undefined if yyoverflow is a macro. */
|
||||
yyoverflow("parser stack overflow",
|
||||
&yyss1, size * sizeof (*yyssp),
|
||||
&yyvs1, size * sizeof (*yyvsp),
|
||||
&yyls1, size * sizeof (*yylsp),
|
||||
&yystacksize);
|
||||
#else
|
||||
yyoverflow("parser stack overflow",
|
||||
&yyss1, size * sizeof (*yyssp),
|
||||
&yyvs1, size * sizeof (*yyvsp),
|
||||
&yystacksize);
|
||||
#endif
|
||||
|
||||
yyss = yyss1; yyvs = yyvs1;
|
||||
#ifdef YYLSP_NEEDED
|
||||
yyls = yyls1;
|
||||
#endif
|
||||
#else /* no yyoverflow */
|
||||
/* Extend the stack our own way. */
|
||||
if (yystacksize >= YYMAXDEPTH)
|
||||
{
|
||||
yyerror("parser stack overflow");
|
||||
return 2;
|
||||
}
|
||||
yystacksize *= 2;
|
||||
if (yystacksize > YYMAXDEPTH)
|
||||
yystacksize = YYMAXDEPTH;
|
||||
yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
|
||||
__yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
|
||||
yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
|
||||
__yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
|
||||
#ifdef YYLSP_NEEDED
|
||||
yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
|
||||
__yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
|
||||
#endif
|
||||
#endif /* no yyoverflow */
|
||||
|
||||
yyssp = yyss + size - 1;
|
||||
yyvsp = yyvs + size - 1;
|
||||
#ifdef YYLSP_NEEDED
|
||||
yylsp = yyls + size - 1;
|
||||
#endif
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Stack size increased to %d\n", yystacksize);
|
||||
#endif
|
||||
|
||||
if (yyssp >= yyss + yystacksize - 1)
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Entering state %d\n", yystate);
|
||||
#endif
|
||||
|
||||
goto yybackup;
|
||||
yybackup:
|
||||
|
||||
/* Do appropriate processing given the current state. */
|
||||
/* Read a lookahead token if we need one and don't already have one. */
|
||||
/* yyresume: */
|
||||
|
||||
/* First try to decide what to do without reference to lookahead token. */
|
||||
|
||||
yyn = yypact[yystate];
|
||||
if (yyn == YYFLAG)
|
||||
goto yydefault;
|
||||
|
||||
/* Not known => get a lookahead token if don't already have one. */
|
||||
|
||||
/* yychar is either YYEMPTY or YYEOF
|
||||
or a valid token in external form. */
|
||||
|
||||
if (yychar == YYEMPTY)
|
||||
{
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Reading a token: ");
|
||||
#endif
|
||||
yychar = YYLEX;
|
||||
}
|
||||
|
||||
/* Convert token to internal form (in yychar1) for indexing tables with */
|
||||
|
||||
if (yychar <= 0) /* This means end of input. */
|
||||
{
|
||||
yychar1 = 0;
|
||||
yychar = YYEOF; /* Don't call YYLEX any more */
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Now at end of input.\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
yychar1 = YYTRANSLATE(yychar);
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
{
|
||||
fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
|
||||
/* Give the individual parser a way to print the precise meaning
|
||||
of a token, for further debugging info. */
|
||||
#ifdef YYPRINT
|
||||
YYPRINT (stderr, yychar, yylval);
|
||||
#endif
|
||||
fprintf (stderr, ")\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
yyn += yychar1;
|
||||
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
|
||||
goto yydefault;
|
||||
|
||||
yyn = yytable[yyn];
|
||||
|
||||
/* yyn is what to do for this token type in this state.
|
||||
Negative => reduce, -yyn is rule number.
|
||||
Positive => shift, yyn is new state.
|
||||
New state is final state => don't bother to shift,
|
||||
just return success.
|
||||
0, or most negative number => error. */
|
||||
|
||||
if (yyn < 0)
|
||||
{
|
||||
if (yyn == YYFLAG)
|
||||
goto yyerrlab;
|
||||
yyn = -yyn;
|
||||
goto yyreduce;
|
||||
}
|
||||
else if (yyn == 0)
|
||||
goto yyerrlab;
|
||||
|
||||
if (yyn == YYFINAL)
|
||||
YYACCEPT;
|
||||
|
||||
/* Shift the lookahead token. */
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
|
||||
#endif
|
||||
|
||||
/* Discard the token being shifted unless it is eof. */
|
||||
if (yychar != YYEOF)
|
||||
yychar = YYEMPTY;
|
||||
|
||||
*++yyvsp = yylval;
|
||||
#ifdef YYLSP_NEEDED
|
||||
*++yylsp = yylloc;
|
||||
#endif
|
||||
|
||||
/* count tokens shifted since error; after three, turn off error status. */
|
||||
if (yyerrstatus) yyerrstatus--;
|
||||
|
||||
yystate = yyn;
|
||||
goto yynewstate;
|
||||
|
||||
/* Do the default action for the current state. */
|
||||
yydefault:
|
||||
|
||||
yyn = yydefact[yystate];
|
||||
if (yyn == 0)
|
||||
goto yyerrlab;
|
||||
|
||||
/* Do a reduction. yyn is the number of a rule to reduce with. */
|
||||
yyreduce:
|
||||
yylen = yyr2[yyn];
|
||||
if (yylen > 0)
|
||||
yyval = yyvsp[1-yylen]; /* implement default value of the action */
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf (stderr, "Reducing via rule %d (line %d), ",
|
||||
yyn, yyrline[yyn]);
|
||||
|
||||
/* Print the symbols being reduced, and their result. */
|
||||
for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
|
||||
fprintf (stderr, "%s ", yytname[yyrhs[i]]);
|
||||
fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
switch (yyn) {
|
||||
|
||||
case 1:
|
||||
#line 62 "bi-parser.y"
|
||||
{ defs = yyvsp[0].def; ;
|
||||
break;}
|
||||
case 3:
|
||||
#line 68 "bi-parser.y"
|
||||
{ yyvsp[0].def->next = yyvsp[-1].def; yyval.def = yyvsp[0].def; ;
|
||||
break;}
|
||||
case 4:
|
||||
#line 73 "bi-parser.y"
|
||||
{ yyval.def = makedef (yyvsp[-7].string, yyvsp[-5].string, yyvsp[-2].variation); ;
|
||||
break;}
|
||||
case 6:
|
||||
#line 79 "bi-parser.y"
|
||||
{ yyvsp[0].variation->next = yyvsp[-2].variation; yyval.variation = yyvsp[0].variation; ;
|
||||
break;}
|
||||
case 7:
|
||||
#line 84 "bi-parser.y"
|
||||
{ yyval.variation = makevar (yyvsp[-1].string, (struct node *) NULL, (struct node *) NULL, (struct node *) NULL); ;
|
||||
break;}
|
||||
case 8:
|
||||
#line 86 "bi-parser.y"
|
||||
{ yyval.variation = makevar (yyvsp[-3].string, yyvsp[-1].node, (struct node *) NULL, (struct node *) NULL); ;
|
||||
break;}
|
||||
case 9:
|
||||
#line 88 "bi-parser.y"
|
||||
{ yyval.variation = makevar (yyvsp[-5].string, yyvsp[-3].node, yyvsp[-1].node, (struct node *) NULL); ;
|
||||
break;}
|
||||
case 10:
|
||||
#line 90 "bi-parser.y"
|
||||
{ yyval.variation = makevar (yyvsp[-7].string, yyvsp[-5].node, yyvsp[-3].node, yyvsp[-1].node); ;
|
||||
break;}
|
||||
case 11:
|
||||
#line 94 "bi-parser.y"
|
||||
{ yyval.string = ""; ;
|
||||
break;}
|
||||
case 12:
|
||||
#line 95 "bi-parser.y"
|
||||
{ yyval.string = yyvsp[0].string; ;
|
||||
break;}
|
||||
case 13:
|
||||
#line 100 "bi-parser.y"
|
||||
{ yyval.node = yyvsp[-1].node; ;
|
||||
break;}
|
||||
case 14:
|
||||
#line 102 "bi-parser.y"
|
||||
{ yyval.node = NULL; ;
|
||||
break;}
|
||||
case 16:
|
||||
#line 109 "bi-parser.y"
|
||||
{ yyvsp[-2].node->next = yyvsp[0].node; yyval.node = yyvsp[-2].node; ;
|
||||
break;}
|
||||
case 17:
|
||||
#line 114 "bi-parser.y"
|
||||
{ yyval.node = makenode (yyvsp[0].string); ;
|
||||
break;}
|
||||
}
|
||||
/* the action file gets copied in in place of this dollarsign */
|
||||
#line 487 "/usr/share/bison.simple"
|
||||
|
||||
yyvsp -= yylen;
|
||||
yyssp -= yylen;
|
||||
#ifdef YYLSP_NEEDED
|
||||
yylsp -= yylen;
|
||||
#endif
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
{
|
||||
short *ssp1 = yyss - 1;
|
||||
fprintf (stderr, "state stack now");
|
||||
while (ssp1 != yyssp)
|
||||
fprintf (stderr, " %d", *++ssp1);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
*++yyvsp = yyval;
|
||||
|
||||
#ifdef YYLSP_NEEDED
|
||||
yylsp++;
|
||||
if (yylen == 0)
|
||||
{
|
||||
yylsp->first_line = yylloc.first_line;
|
||||
yylsp->first_column = yylloc.first_column;
|
||||
yylsp->last_line = (yylsp-1)->last_line;
|
||||
yylsp->last_column = (yylsp-1)->last_column;
|
||||
yylsp->text = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
yylsp->last_line = (yylsp+yylen-1)->last_line;
|
||||
yylsp->last_column = (yylsp+yylen-1)->last_column;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Now "shift" the result of the reduction.
|
||||
Determine what state that goes to,
|
||||
based on the state we popped back to
|
||||
and the rule number reduced by. */
|
||||
|
||||
yyn = yyr1[yyn];
|
||||
|
||||
yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
|
||||
if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
|
||||
yystate = yytable[yystate];
|
||||
else
|
||||
yystate = yydefgoto[yyn - YYNTBASE];
|
||||
|
||||
goto yynewstate;
|
||||
|
||||
yyerrlab: /* here on detecting error */
|
||||
|
||||
if (! yyerrstatus)
|
||||
/* If not already recovering from an error, report this error. */
|
||||
{
|
||||
++yynerrs;
|
||||
|
||||
#ifdef YYERROR_VERBOSE
|
||||
yyn = yypact[yystate];
|
||||
|
||||
if (yyn > YYFLAG && yyn < YYLAST)
|
||||
{
|
||||
int size = 0;
|
||||
char *msg;
|
||||
int x, count;
|
||||
|
||||
count = 0;
|
||||
/* Start X at -yyn if nec to avoid negative indexes in yycheck. */
|
||||
for (x = (yyn < 0 ? -yyn : 0);
|
||||
x < (sizeof(yytname) / sizeof(char *)); x++)
|
||||
if (yycheck[x + yyn] == x)
|
||||
size += strlen(yytname[x]) + 15, count++;
|
||||
msg = (char *) malloc(size + 15);
|
||||
if (msg != 0)
|
||||
{
|
||||
strcpy(msg, "parse error");
|
||||
|
||||
if (count < 5)
|
||||
{
|
||||
count = 0;
|
||||
for (x = (yyn < 0 ? -yyn : 0);
|
||||
x < (sizeof(yytname) / sizeof(char *)); x++)
|
||||
if (yycheck[x + yyn] == x)
|
||||
{
|
||||
strcat(msg, count == 0 ? ", expecting `" : " or `");
|
||||
strcat(msg, yytname[x]);
|
||||
strcat(msg, "'");
|
||||
count++;
|
||||
}
|
||||
}
|
||||
yyerror(msg);
|
||||
free(msg);
|
||||
}
|
||||
else
|
||||
yyerror ("parse error; also virtual memory exceeded");
|
||||
}
|
||||
else
|
||||
#endif /* YYERROR_VERBOSE */
|
||||
yyerror("parse error");
|
||||
}
|
||||
|
||||
goto yyerrlab1;
|
||||
yyerrlab1: /* here on error raised explicitly by an action */
|
||||
|
||||
if (yyerrstatus == 3)
|
||||
{
|
||||
/* if just tried and failed to reuse lookahead token after an error, discard it. */
|
||||
|
||||
/* return failure if at end of input */
|
||||
if (yychar == YYEOF)
|
||||
YYABORT;
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
|
||||
#endif
|
||||
|
||||
yychar = YYEMPTY;
|
||||
}
|
||||
|
||||
/* Else will try to reuse lookahead token
|
||||
after shifting the error token. */
|
||||
|
||||
yyerrstatus = 3; /* Each real token shifted decrements this */
|
||||
|
||||
goto yyerrhandle;
|
||||
|
||||
yyerrdefault: /* current state does not do anything special for the error token. */
|
||||
|
||||
#if 0
|
||||
/* This is wrong; only states that explicitly want error tokens
|
||||
should shift them. */
|
||||
yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
|
||||
if (yyn) goto yydefault;
|
||||
#endif
|
||||
|
||||
yyerrpop: /* pop the current state because it cannot handle the error token */
|
||||
|
||||
if (yyssp == yyss) YYABORT;
|
||||
yyvsp--;
|
||||
yystate = *--yyssp;
|
||||
#ifdef YYLSP_NEEDED
|
||||
yylsp--;
|
||||
#endif
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
{
|
||||
short *ssp1 = yyss - 1;
|
||||
fprintf (stderr, "Error: state stack now");
|
||||
while (ssp1 != yyssp)
|
||||
fprintf (stderr, " %d", *++ssp1);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
yyerrhandle:
|
||||
|
||||
yyn = yypact[yystate];
|
||||
if (yyn == YYFLAG)
|
||||
goto yyerrdefault;
|
||||
|
||||
yyn += YYTERROR;
|
||||
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
|
||||
goto yyerrdefault;
|
||||
|
||||
yyn = yytable[yyn];
|
||||
if (yyn < 0)
|
||||
{
|
||||
if (yyn == YYFLAG)
|
||||
goto yyerrpop;
|
||||
yyn = -yyn;
|
||||
goto yyreduce;
|
||||
}
|
||||
else if (yyn == 0)
|
||||
goto yyerrpop;
|
||||
|
||||
if (yyn == YYFINAL)
|
||||
YYACCEPT;
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
fprintf(stderr, "Shifting error token, ");
|
||||
#endif
|
||||
|
||||
*++yyvsp = yylval;
|
||||
#ifdef YYLSP_NEEDED
|
||||
*++yylsp = yylloc;
|
||||
#endif
|
||||
|
||||
yystate = yyn;
|
||||
goto yynewstate;
|
||||
}
|
||||
#line 117 "bi-parser.y"
|
||||
|
||||
|
||||
static struct node *
|
||||
makenode (s)
|
||||
char *s;
|
||||
{
|
||||
struct node *n;
|
||||
|
||||
n = (struct node *) malloc (sizeof (struct node));
|
||||
n->text = s;
|
||||
n->next = NULL;
|
||||
return n;
|
||||
}
|
||||
|
||||
static struct variation *
|
||||
makevar (name, inputs, outputs, literals)
|
||||
char *name;
|
||||
struct node *inputs, *outputs, *literals;
|
||||
{
|
||||
struct variation *v;
|
||||
|
||||
v = (struct variation *) malloc (sizeof (struct variation));
|
||||
v->name = name;
|
||||
v->code = ndefs++;
|
||||
v->inputs = inputs;
|
||||
v->outputs = outputs;
|
||||
v->literals = literals;
|
||||
v->next = NULL;
|
||||
return v;
|
||||
}
|
||||
|
||||
static struct def *
|
||||
makedef (name, template, vars)
|
||||
char *name, *template;
|
||||
struct variation *vars;
|
||||
{
|
||||
struct def *d;
|
||||
|
||||
d = (struct def *) malloc (sizeof (struct def));
|
||||
d->basename = name;
|
||||
d->template = template;
|
||||
d->variations = vars;
|
||||
d->next = NULL;
|
||||
return d;
|
||||
}
|
||||
|
||||
void
|
||||
yyerror (s)
|
||||
char *s;
|
||||
{
|
||||
fprintf (stderr, "syntax error in input\n");
|
||||
exit (FATAL_EXIT_CODE);
|
||||
}
|
12
bi-parser.h
Normal file
12
bi-parser.h
Normal file
@ -0,0 +1,12 @@
|
||||
typedef union
|
||||
{
|
||||
char *string;
|
||||
struct def *def;
|
||||
struct variation *variation;
|
||||
struct node *node;
|
||||
} YYSTYPE;
|
||||
#define DEFOP 258
|
||||
#define STRING 259
|
||||
|
||||
|
||||
extern YYSTYPE yylval;
|
169
bi-parser.y
Normal file
169
bi-parser.y
Normal file
@ -0,0 +1,169 @@
|
||||
/* Bytecode definition file parser.
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
%{
|
||||
|
||||
#include <stdio.h>
|
||||
#include "hconfig.h"
|
||||
#include "bi-defs.h"
|
||||
|
||||
extern char yytext[];
|
||||
extern int yyleng;
|
||||
|
||||
|
||||
/* Chain of all defs built by the parser. */
|
||||
struct def *defs;
|
||||
int ndefs;
|
||||
|
||||
static struct node *makenode ();
|
||||
static struct variation *makevar ();
|
||||
static struct def *makedef ();
|
||||
|
||||
void yyerror ();
|
||||
|
||||
%}
|
||||
|
||||
%union
|
||||
{
|
||||
char *string;
|
||||
struct def *def;
|
||||
struct variation *variation;
|
||||
struct node *node;
|
||||
}
|
||||
|
||||
%token <string> DEFOP STRING
|
||||
%type <string> opt_string
|
||||
%type <def> defs def
|
||||
%type <variation> variations variation
|
||||
%type <node> list items item
|
||||
|
||||
%%
|
||||
|
||||
top:
|
||||
defs
|
||||
{ defs = $1; }
|
||||
;
|
||||
|
||||
defs:
|
||||
def
|
||||
| defs def
|
||||
{ $2->next = $1; $$ = $2; }
|
||||
;
|
||||
|
||||
def:
|
||||
DEFOP '(' STRING ',' opt_string ',' '(' variations ')' ')'
|
||||
{ $$ = makedef ($3, $5, $8); }
|
||||
;
|
||||
|
||||
variations:
|
||||
variation
|
||||
| variations ',' variation
|
||||
{ $3->next = $1; $$ = $3; }
|
||||
;
|
||||
|
||||
variation:
|
||||
'(' opt_string ')'
|
||||
{ $$ = makevar ($2, (struct node *) NULL, (struct node *) NULL, (struct node *) NULL); }
|
||||
| '(' opt_string ',' list ')'
|
||||
{ $$ = makevar ($2, $4, (struct node *) NULL, (struct node *) NULL); }
|
||||
| '(' opt_string ',' list ',' list ')'
|
||||
{ $$ = makevar ($2, $4, $6, (struct node *) NULL); }
|
||||
| '(' opt_string ',' list ',' list ',' list ')'
|
||||
{ $$ = makevar ($2, $4, $6, $8); }
|
||||
;
|
||||
|
||||
opt_string:
|
||||
/* empty */ { $$ = ""; }
|
||||
| STRING { $$ = $1; }
|
||||
;
|
||||
|
||||
list:
|
||||
'(' items ')'
|
||||
{ $$ = $2; }
|
||||
| /* empty */
|
||||
{ $$ = NULL; }
|
||||
;
|
||||
|
||||
items:
|
||||
item
|
||||
/* Note right recursion. */
|
||||
| item ',' items
|
||||
{ $1->next = $3; $$ = $1; }
|
||||
;
|
||||
|
||||
item:
|
||||
STRING
|
||||
{ $$ = makenode ($1); }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
static struct node *
|
||||
makenode (s)
|
||||
char *s;
|
||||
{
|
||||
struct node *n;
|
||||
|
||||
n = (struct node *) malloc (sizeof (struct node));
|
||||
n->text = s;
|
||||
n->next = NULL;
|
||||
return n;
|
||||
}
|
||||
|
||||
static struct variation *
|
||||
makevar (name, inputs, outputs, literals)
|
||||
char *name;
|
||||
struct node *inputs, *outputs, *literals;
|
||||
{
|
||||
struct variation *v;
|
||||
|
||||
v = (struct variation *) malloc (sizeof (struct variation));
|
||||
v->name = name;
|
||||
v->code = ndefs++;
|
||||
v->inputs = inputs;
|
||||
v->outputs = outputs;
|
||||
v->literals = literals;
|
||||
v->next = NULL;
|
||||
return v;
|
||||
}
|
||||
|
||||
static struct def *
|
||||
makedef (name, template, vars)
|
||||
char *name, *template;
|
||||
struct variation *vars;
|
||||
{
|
||||
struct def *d;
|
||||
|
||||
d = (struct def *) malloc (sizeof (struct def));
|
||||
d->basename = name;
|
||||
d->template = template;
|
||||
d->variations = vars;
|
||||
d->next = NULL;
|
||||
return d;
|
||||
}
|
||||
|
||||
void
|
||||
yyerror (s)
|
||||
char *s;
|
||||
{
|
||||
fprintf (stderr, "syntax error in input\n");
|
||||
exit (FATAL_EXIT_CODE);
|
||||
}
|
61
bi-reverse.c
Normal file
61
bi-reverse.c
Normal file
@ -0,0 +1,61 @@
|
||||
/* Reverse order of definitions obtained from bytecode definition file.
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
#include "hconfig.h"
|
||||
#include "bi-defs.h"
|
||||
|
||||
void
|
||||
reverse()
|
||||
{
|
||||
struct def *dp, *d, *dn;
|
||||
struct variation *vp, *v, *vn;
|
||||
|
||||
dp = defs;
|
||||
if (dp)
|
||||
{
|
||||
vp = dp->variations;
|
||||
if (vp)
|
||||
{
|
||||
for (v = vp->next, vp->next = 0; v; vp = v, v = vn)
|
||||
{
|
||||
vn = v->next;
|
||||
v->next = vp;
|
||||
}
|
||||
dp->variations = vp;
|
||||
}
|
||||
for (d = dp->next, dp->next = 0; d; dp = d, d = dn)
|
||||
{
|
||||
vp = d->variations;
|
||||
if (vp)
|
||||
{
|
||||
for (v = vp->next, vp->next = 0; v; vp = v, v = vn)
|
||||
{
|
||||
vn = v->next;
|
||||
v->next = vp;
|
||||
}
|
||||
d->variations = vp;
|
||||
}
|
||||
dn = d->next;
|
||||
d->next = dp;
|
||||
}
|
||||
defs = dp;
|
||||
}
|
||||
}
|
159
bi-run.h
Normal file
159
bi-run.h
Normal file
@ -0,0 +1,159 @@
|
||||
/* Definitions for Bytecode Interpreter.
|
||||
Copyright (C) 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#define MAXLITERALS 5
|
||||
|
||||
struct arityvec
|
||||
{
|
||||
char ninputs;
|
||||
char noutputs;
|
||||
char nliterals;
|
||||
char literals[MAXLITERALS];
|
||||
};
|
||||
|
||||
struct argtype
|
||||
{
|
||||
int modealign; /* Argument mode:alignment */
|
||||
int size; /* Argument size, in bytes */
|
||||
};
|
||||
|
||||
struct callinfo
|
||||
{
|
||||
int nargs; /* Number of arguments in call */
|
||||
struct argtype retvaltype; /* Type of return value */
|
||||
struct argtype argtypes[1]; /* Argument types */
|
||||
};
|
||||
|
||||
/* Structure describing a bytecode function. If this changes, we also
|
||||
need to change expand_function_end () in bc-trans.c */
|
||||
struct bytecode
|
||||
{
|
||||
int stacksize; /* Depth required of evaluation stack. */
|
||||
int localsize; /* Size in bytes of local variables. */
|
||||
unsigned char *pc0; /* Initial program counter. */
|
||||
void **ptrlit; /* Vector of (relocatable) pointer literals. */
|
||||
struct callinfo *callinfo; /* Vector of procedure call type info. */
|
||||
};
|
||||
|
||||
|
||||
#define INTERP_BPC 8 /* Bits per char */
|
||||
#define INTERP_BPI \
|
||||
(sizeof (int) * INTERP_BPC) /* Bits per int */
|
||||
|
||||
|
||||
#ifndef min
|
||||
#define min(L, R) ((L) < (R) ? (L) : (R))
|
||||
#endif
|
||||
|
||||
|
||||
/* bit field operations. */
|
||||
|
||||
/* Low (high) mask: int with low (high) N bits set */
|
||||
|
||||
#define LM(N) ((1 << (N)) - 1)
|
||||
#define HM(N) ((~LM (INTERP_BPI - (N))))
|
||||
|
||||
|
||||
/* Sign-extend SIZE low bits of VALUE to integer (typeof VALUE)
|
||||
Signed bitfields are loaded from memory by the sxloadBI instruction,
|
||||
which first retrieves the bitfield with XFIELD and then sign extends
|
||||
it to an SItype. */
|
||||
|
||||
#define EXTEND(SIZE, VALUE) \
|
||||
({ SUtype value = (SUtype) (VALUE); \
|
||||
(value & (1 << ((SIZE) - 1)) ? value | ~LM (SIZE) : value); })
|
||||
|
||||
|
||||
/* Given OFFSET:SIZE for a bitfield, calculate:
|
||||
|
||||
[1] BYTE_OFFSET = the byte offset of the bit field.
|
||||
[2] BIT_OFFSET = the bit offset of the bit field (less than INTERP_BPC).
|
||||
[3] NBYTES = the number of integral bytes in the bit field.
|
||||
[4] TRAILING_BITS= the number of trailing bits (less than INTERP_BPC).
|
||||
|
||||
|
||||
, , , , , (memory bytes)
|
||||
---------------- (bitfield)
|
||||
| | || | | (divisions)
|
||||
^ ^ ^ ^
|
||||
| | | |__ [4] (bits)
|
||||
| | |_________ [3] (bytes)
|
||||
| |_________________ [2] (bits)
|
||||
|___________________________ [1] (bytes)
|
||||
|
||||
|
||||
The above applies to BYTE_LOW_ENDIAN machines. In BYTE_BIG_ENDIAN machines, the
|
||||
bit numbering is reversed (i.e. bit 0 is the sign bit).
|
||||
|
||||
(All right, so I drew this to keep my tongue in cheek while writing the code below,
|
||||
not because I'm into ASCII art.) */
|
||||
|
||||
|
||||
#define BI_PARAMS(OFFSET, SIZE, BYTE_OFFSET, BIT_OFFSET, NBYTES, TRAILING_BITS) \
|
||||
{ BYTE_OFFSET = (OFFSET) / (INTERP_BPC); \
|
||||
BIT_OFFSET = (OFFSET) % (INTERP_BPC); \
|
||||
NBYTES = ((SIZE) - (INTERP_BPC - (BIT_OFFSET))) / INTERP_BPC; \
|
||||
if ((NBYTES) < 0 || ((NBYTES) > 64)) \
|
||||
NBYTES = 0; \
|
||||
if ((SIZE) + (BIT_OFFSET) <= INTERP_BPC) \
|
||||
TRAILING_BITS = 0; \
|
||||
else \
|
||||
TRAILING_BITS = ((SIZE) - (INTERP_BPC - (BIT_OFFSET))) % INTERP_BPC; }
|
||||
|
||||
|
||||
/* SHIFT_IN_BITS retrieves NBITS bits from SOURCE and shifts into
|
||||
DEST. The bit field starts OFFSET bits into SOURCE.
|
||||
|
||||
OR_IN_BITS copies the NBITS low bits from VALUE into a the bitfield in
|
||||
DEST offset by OFFSET bits. */
|
||||
|
||||
|
||||
#define SHIFT_IN_BITS(DEST, SOURCE, OFFSET, NBITS) \
|
||||
(DEST = ((DEST) << (NBITS)) \
|
||||
| (LM ((NBITS)) \
|
||||
& ((SOURCE) \
|
||||
>> (BYTES_BIG_ENDIAN \
|
||||
? (INTERP_BPC - (OFFSET) - (NBITS)) \
|
||||
: (OFFSET)))))
|
||||
|
||||
#define OR_IN_BITS(DEST, VALUE, OFFSET, NBITS) \
|
||||
(DEST = ((DEST) & ~(LM ((NBITS)) \
|
||||
<< (BIG_ENDIAN \
|
||||
? (INTERP_BPC - (OFFSET) - (NBITS)) \
|
||||
: (OFFSET))) \
|
||||
| (((VALUE) & LM ((NBITS))) \
|
||||
<< (BIG_ENDIAN \
|
||||
? (INTERP_BPC - (OFFSET) - (NBITS)) \
|
||||
: (OFFSET)))))
|
||||
|
||||
/* Procedure call; arguments are a pointer to the function to be called,
|
||||
a pointer to a place to store the return value, a pointer to a vector
|
||||
describing the type of procedure call, and the interpreter's stack pointer,
|
||||
which will point to the first of the arguments at this point. */
|
||||
|
||||
#define CALL(FUNC, CALLDESC, RETVAL, SP) __call(FUNC, CALLDESC, RETVAL, SP)
|
||||
|
||||
|
||||
/* Procedure return; arguments are a pointer to the calldesc for this
|
||||
function, and a pointer to the place where the value to be returned
|
||||
may be found. Generally the MACHARGS above contain a machine dependent
|
||||
cookie that is used to determine where to jump to. */
|
||||
|
||||
#define PROCRET(CALLDESC, RETVAL) return
|
645
bitmap.c
Normal file
645
bitmap.c
Normal file
@ -0,0 +1,645 @@
|
||||
/* Functions to support general ended bitmaps.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include "rtl.h"
|
||||
#include "flags.h"
|
||||
#include "obstack.h"
|
||||
#include "regs.h"
|
||||
#include "basic-block.h"
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef NEED_DECLARATION_FREE
|
||||
extern void free PROTO((void *));
|
||||
#endif
|
||||
|
||||
/* Obstack to allocate bitmap elements from. */
|
||||
static struct obstack bitmap_obstack;
|
||||
static int bitmap_obstack_init = FALSE;
|
||||
|
||||
|
||||
#ifndef INLINE
|
||||
#ifndef __GNUC__
|
||||
#define INLINE
|
||||
#else
|
||||
#define INLINE __inline__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Global data */
|
||||
bitmap_element bitmap_zero; /* An element of all zero bits. */
|
||||
bitmap_element *bitmap_free; /* Freelist of bitmap elements. */
|
||||
|
||||
static void bitmap_element_free PROTO((bitmap, bitmap_element *));
|
||||
static bitmap_element *bitmap_element_allocate PROTO((bitmap));
|
||||
static int bitmap_element_zerop PROTO((bitmap_element *));
|
||||
static void bitmap_element_link PROTO((bitmap, bitmap_element *));
|
||||
static bitmap_element *bitmap_find_bit PROTO((bitmap, unsigned int));
|
||||
|
||||
/* Free a bitmap element */
|
||||
|
||||
static INLINE void
|
||||
bitmap_element_free (head, elt)
|
||||
bitmap head;
|
||||
bitmap_element *elt;
|
||||
{
|
||||
bitmap_element *next = elt->next;
|
||||
bitmap_element *prev = elt->prev;
|
||||
|
||||
if (prev)
|
||||
prev->next = next;
|
||||
|
||||
if (next)
|
||||
next->prev = prev;
|
||||
|
||||
if (head->first == elt)
|
||||
head->first = next;
|
||||
|
||||
/* Since the first thing we try is to insert before current,
|
||||
make current the next entry in preference to the previous. */
|
||||
if (head->current == elt)
|
||||
head->current = next != 0 ? next : prev;
|
||||
|
||||
elt->next = bitmap_free;
|
||||
bitmap_free = elt;
|
||||
}
|
||||
|
||||
/* Allocate a bitmap element. The bits are cleared, but nothing else is. */
|
||||
|
||||
static INLINE bitmap_element *
|
||||
bitmap_element_allocate (head)
|
||||
bitmap head;
|
||||
{
|
||||
bitmap_element *element;
|
||||
int i;
|
||||
|
||||
if (bitmap_free != 0)
|
||||
{
|
||||
element = bitmap_free;
|
||||
bitmap_free = element->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We can't use gcc_obstack_init to initialize the obstack since
|
||||
print-rtl.c now calls bitmap functions, and bitmap is linked
|
||||
into the gen* functions. */
|
||||
if (!bitmap_obstack_init)
|
||||
{
|
||||
bitmap_obstack_init = TRUE;
|
||||
|
||||
/* Let particular systems override the size of a chunk. */
|
||||
#ifndef OBSTACK_CHUNK_SIZE
|
||||
#define OBSTACK_CHUNK_SIZE 0
|
||||
#endif
|
||||
/* Let them override the alloc and free routines too. */
|
||||
#ifndef OBSTACK_CHUNK_ALLOC
|
||||
#define OBSTACK_CHUNK_ALLOC xmalloc
|
||||
#endif
|
||||
#ifndef OBSTACK_CHUNK_FREE
|
||||
#define OBSTACK_CHUNK_FREE free
|
||||
#endif
|
||||
|
||||
#if !defined(__GNUC__) || (__GNUC__ < 2)
|
||||
#define __alignof__(type) 0
|
||||
#endif
|
||||
|
||||
obstack_specify_allocation (&bitmap_obstack, OBSTACK_CHUNK_SIZE,
|
||||
__alignof__ (bitmap_element),
|
||||
(void *(*) ()) OBSTACK_CHUNK_ALLOC,
|
||||
(void (*) ()) OBSTACK_CHUNK_FREE);
|
||||
}
|
||||
|
||||
element = (bitmap_element *) obstack_alloc (&bitmap_obstack,
|
||||
sizeof (bitmap_element));
|
||||
}
|
||||
|
||||
#if BITMAP_ELEMENT_WORDS == 2
|
||||
element->bits[0] = element->bits[1] = 0;
|
||||
#else
|
||||
for (i = 0; i < BITMAP_ELEMENT_WORDS; i++)
|
||||
element->bits[i] = 0;
|
||||
#endif
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
/* Return nonzero if all bits in an element are zero. */
|
||||
|
||||
static INLINE int
|
||||
bitmap_element_zerop (element)
|
||||
bitmap_element *element;
|
||||
{
|
||||
#if BITMAP_ELEMENT_WORDS == 2
|
||||
return (element->bits[0] | element->bits[1]) == 0;
|
||||
#else
|
||||
int i;
|
||||
|
||||
for (i = 0; i < BITMAP_ELEMENT_WORDS; i++)
|
||||
if (element->bits[i] != 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Link the bitmap element into the current bitmap linked list. */
|
||||
|
||||
static INLINE void
|
||||
bitmap_element_link (head, element)
|
||||
bitmap head;
|
||||
bitmap_element *element;
|
||||
{
|
||||
unsigned int indx = element->indx;
|
||||
bitmap_element *ptr;
|
||||
|
||||
/* If this is the first and only element, set it in. */
|
||||
if (head->first == 0)
|
||||
{
|
||||
element->next = element->prev = 0;
|
||||
head->first = element;
|
||||
}
|
||||
|
||||
/* If this index is less than that of the current element, it goes someplace
|
||||
before the current element. */
|
||||
else if (indx < head->indx)
|
||||
{
|
||||
for (ptr = head->current;
|
||||
ptr->prev != 0 && ptr->prev->indx > indx;
|
||||
ptr = ptr->prev)
|
||||
;
|
||||
|
||||
if (ptr->prev)
|
||||
ptr->prev->next = element;
|
||||
else
|
||||
head->first = element;
|
||||
|
||||
element->prev = ptr->prev;
|
||||
element->next = ptr;
|
||||
ptr->prev = element;
|
||||
}
|
||||
|
||||
/* Otherwise, it must go someplace after the current element. */
|
||||
else
|
||||
{
|
||||
for (ptr = head->current;
|
||||
ptr->next != 0 && ptr->next->indx < indx;
|
||||
ptr = ptr->next)
|
||||
;
|
||||
|
||||
if (ptr->next)
|
||||
ptr->next->prev = element;
|
||||
|
||||
element->next = ptr->next;
|
||||
element->prev = ptr;
|
||||
ptr->next = element;
|
||||
}
|
||||
|
||||
/* Set up so this is the first element searched. */
|
||||
head->current = element;
|
||||
head->indx = indx;
|
||||
}
|
||||
|
||||
/* Clear a bitmap by freeing the linked list. */
|
||||
|
||||
void INLINE
|
||||
bitmap_clear (head)
|
||||
bitmap head;
|
||||
{
|
||||
bitmap_element *element, *next;
|
||||
|
||||
for (element = head->first; element != 0; element = next)
|
||||
{
|
||||
next = element->next;
|
||||
element->next = bitmap_free;
|
||||
bitmap_free = element;
|
||||
}
|
||||
|
||||
head->first = head->current = 0;
|
||||
}
|
||||
|
||||
/* Copy a bitmap to another bitmap */
|
||||
|
||||
void
|
||||
bitmap_copy (to, from)
|
||||
bitmap to;
|
||||
bitmap from;
|
||||
{
|
||||
bitmap_element *from_ptr, *to_ptr = 0;
|
||||
int i;
|
||||
|
||||
bitmap_clear (to);
|
||||
|
||||
/* Copy elements in forward direction one at a time */
|
||||
for (from_ptr = from->first; from_ptr; from_ptr = from_ptr->next)
|
||||
{
|
||||
bitmap_element *to_elt = bitmap_element_allocate (to);
|
||||
|
||||
to_elt->indx = from_ptr->indx;
|
||||
|
||||
#if BITMAP_ELEMENT_WORDS == 2
|
||||
to_elt->bits[0] = from_ptr->bits[0];
|
||||
to_elt->bits[1] = from_ptr->bits[1];
|
||||
#else
|
||||
for (i = 0; i < BITMAP_ELEMENT_WORDS; i++)
|
||||
to_elt->bits[i] = from_ptr->bits[i];
|
||||
#endif
|
||||
|
||||
/* Here we have a special case of bitmap_element_link, for the case
|
||||
where we know the links are being entered in sequence. */
|
||||
if (to_ptr == 0)
|
||||
{
|
||||
to->first = to->current = to_elt;
|
||||
to->indx = from_ptr->indx;
|
||||
to_elt->next = to_elt->prev = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
to_elt->prev = to_ptr;
|
||||
to_elt->next = 0;
|
||||
to_ptr->next = to_elt;
|
||||
}
|
||||
|
||||
to_ptr = to_elt;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find a bitmap element that would hold a bitmap's bit.
|
||||
Update the `current' field even if we can't find an element that
|
||||
would hold the bitmap's bit to make eventual allocation
|
||||
faster. */
|
||||
|
||||
static INLINE bitmap_element *
|
||||
bitmap_find_bit (head, bit)
|
||||
bitmap head;
|
||||
unsigned int bit;
|
||||
{
|
||||
bitmap_element *element;
|
||||
unsigned HOST_WIDE_INT indx = bit / BITMAP_ELEMENT_ALL_BITS;
|
||||
|
||||
if (head->current == 0)
|
||||
return 0;
|
||||
|
||||
if (head->indx > indx)
|
||||
for (element = head->current;
|
||||
element->prev != 0 && element->indx > indx;
|
||||
element = element->prev)
|
||||
;
|
||||
|
||||
else
|
||||
for (element = head->current;
|
||||
element->next != 0 && element->indx < indx;
|
||||
element = element->next)
|
||||
;
|
||||
|
||||
/* `element' is the nearest to the one we want. If it's not the one we
|
||||
want, the one we want doesn't exist. */
|
||||
head->current = element;
|
||||
head->indx = element->indx;
|
||||
if (element != 0 && element->indx != indx)
|
||||
element = 0;
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
/* Clear a single bit in a bitmap. */
|
||||
|
||||
void
|
||||
bitmap_clear_bit (head, bit)
|
||||
bitmap head;
|
||||
int bit;
|
||||
{
|
||||
bitmap_element *ptr = bitmap_find_bit (head, bit);
|
||||
|
||||
if (ptr != 0)
|
||||
{
|
||||
unsigned bit_num = bit % (unsigned) HOST_BITS_PER_WIDE_INT;
|
||||
unsigned word_num = ((bit / (unsigned) HOST_BITS_PER_WIDE_INT)
|
||||
% BITMAP_ELEMENT_WORDS);
|
||||
ptr->bits[word_num] &= ~ (((unsigned HOST_WIDE_INT) 1) << bit_num);
|
||||
|
||||
/* If we cleared the entire word, free up the element */
|
||||
if (bitmap_element_zerop (ptr))
|
||||
bitmap_element_free (head, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Set a single bit in a bitmap. */
|
||||
|
||||
void
|
||||
bitmap_set_bit (head, bit)
|
||||
bitmap head;
|
||||
int bit;
|
||||
{
|
||||
bitmap_element *ptr = bitmap_find_bit (head, bit);
|
||||
unsigned word_num
|
||||
= ((bit / (unsigned) HOST_BITS_PER_WIDE_INT) % BITMAP_ELEMENT_WORDS);
|
||||
unsigned bit_num = bit % (unsigned) HOST_BITS_PER_WIDE_INT;
|
||||
unsigned HOST_WIDE_INT bit_val = ((unsigned HOST_WIDE_INT) 1) << bit_num;
|
||||
|
||||
if (ptr == 0)
|
||||
{
|
||||
ptr = bitmap_element_allocate (head);
|
||||
ptr->indx = bit / BITMAP_ELEMENT_ALL_BITS;
|
||||
ptr->bits[word_num] = bit_val;
|
||||
bitmap_element_link (head, ptr);
|
||||
}
|
||||
else
|
||||
ptr->bits[word_num] |= bit_val;
|
||||
}
|
||||
|
||||
/* Return whether a bit is set within a bitmap. */
|
||||
|
||||
int
|
||||
bitmap_bit_p (head, bit)
|
||||
bitmap head;
|
||||
int bit;
|
||||
{
|
||||
bitmap_element *ptr;
|
||||
unsigned bit_num;
|
||||
unsigned word_num;
|
||||
|
||||
ptr = bitmap_find_bit (head, bit);
|
||||
if (ptr == 0)
|
||||
return 0;
|
||||
|
||||
bit_num = bit % (unsigned) HOST_BITS_PER_WIDE_INT;
|
||||
word_num
|
||||
= ((bit / (unsigned) HOST_BITS_PER_WIDE_INT) % BITMAP_ELEMENT_WORDS);
|
||||
|
||||
return
|
||||
(ptr->bits[word_num] & (((unsigned HOST_WIDE_INT) 1) << bit_num)) != 0;
|
||||
}
|
||||
|
||||
/* Store in bitmap TO the result of combining bitmap FROM1 and
|
||||
FROM2 using a specific bit manipulation. */
|
||||
|
||||
void
|
||||
bitmap_operation (to, from1, from2, operation)
|
||||
bitmap to;
|
||||
bitmap from1;
|
||||
bitmap from2;
|
||||
enum bitmap_bits operation;
|
||||
{
|
||||
bitmap_element *delete_list = 0;
|
||||
bitmap_element *from1_ptr = from1->first;
|
||||
bitmap_element *from2_ptr = from2->first;
|
||||
unsigned int indx1
|
||||
= (from1_ptr) ? from1_ptr->indx : ~ (unsigned HOST_WIDE_INT) 0;
|
||||
unsigned int indx2
|
||||
= (from2_ptr) ? from2_ptr->indx : ~ (unsigned HOST_WIDE_INT) 0;
|
||||
bitmap_element *to_ptr = 0;
|
||||
bitmap_element *from1_tmp;
|
||||
bitmap_element *from2_tmp;
|
||||
unsigned int indx;
|
||||
int i;
|
||||
|
||||
/* To simplify things, always create a new list. If the old list was one
|
||||
of the inputs, free it later. Otherwise, free it now. */
|
||||
if (to == from1 || to == from2)
|
||||
{
|
||||
delete_list = to->first;
|
||||
to->first = to->current = 0;
|
||||
}
|
||||
else
|
||||
bitmap_clear (to);
|
||||
|
||||
while (from1_ptr != 0 || from2_ptr != 0)
|
||||
{
|
||||
/* Figure out whether we need to substitute zero elements for
|
||||
missing links. */
|
||||
if (indx1 == indx2)
|
||||
{
|
||||
indx = indx1;
|
||||
from1_tmp = from1_ptr;
|
||||
from2_tmp = from2_ptr;
|
||||
from1_ptr = from1_ptr->next;
|
||||
indx1 = (from1_ptr) ? from1_ptr->indx : ~ (unsigned HOST_WIDE_INT) 0;
|
||||
from2_ptr = from2_ptr->next;
|
||||
indx2 = (from2_ptr) ? from2_ptr->indx : ~ (unsigned HOST_WIDE_INT) 0;
|
||||
}
|
||||
else if (indx1 < indx2)
|
||||
{
|
||||
indx = indx1;
|
||||
from1_tmp = from1_ptr;
|
||||
from2_tmp = &bitmap_zero;
|
||||
from1_ptr = from1_ptr->next;
|
||||
indx1 = (from1_ptr) ? from1_ptr->indx : ~ (unsigned HOST_WIDE_INT) 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
indx = indx2;
|
||||
from1_tmp = &bitmap_zero;
|
||||
from2_tmp = from2_ptr;
|
||||
from2_ptr = from2_ptr->next;
|
||||
indx2 = (from2_ptr) ? from2_ptr->indx : ~ (unsigned HOST_WIDE_INT) 0;
|
||||
}
|
||||
|
||||
if (to_ptr == 0)
|
||||
to_ptr = bitmap_element_allocate (to);
|
||||
|
||||
/* Do the operation, and if any bits are set, link it into the
|
||||
linked list. */
|
||||
switch (operation)
|
||||
{
|
||||
default:
|
||||
abort ();
|
||||
|
||||
case BITMAP_AND:
|
||||
#if BITMAP_ELEMENT_WORDS == 2
|
||||
to_ptr->bits[0] = from1_tmp->bits[0] & from2_tmp->bits[0];
|
||||
to_ptr->bits[1] = from1_tmp->bits[1] & from2_tmp->bits[1];
|
||||
#else
|
||||
for (i = BITMAP_ELEMENT_WORDS - 1; i >= 0; i--)
|
||||
to_ptr->bits[i] = from1_tmp->bits[i] & from2_tmp->bits[i];
|
||||
#endif
|
||||
break;
|
||||
|
||||
case BITMAP_AND_COMPL:
|
||||
#if BITMAP_ELEMENT_WORDS == 2
|
||||
to_ptr->bits[0] = from1_tmp->bits[0] & ~ from2_tmp->bits[0];
|
||||
to_ptr->bits[1] = from1_tmp->bits[1] & ~ from2_tmp->bits[1];
|
||||
#else
|
||||
for (i = BITMAP_ELEMENT_WORDS - 1; i >= 0; i--)
|
||||
to_ptr->bits[i] = from1_tmp->bits[i] & ~ from2_tmp->bits[i];
|
||||
#endif
|
||||
break;
|
||||
|
||||
case BITMAP_IOR:
|
||||
#if BITMAP_ELEMENT_WORDS == 2
|
||||
to_ptr->bits[0] = from1_tmp->bits[0] | from2_tmp->bits[0];
|
||||
to_ptr->bits[1] = from1_tmp->bits[1] | from2_tmp->bits[1];
|
||||
#else
|
||||
for (i = BITMAP_ELEMENT_WORDS - 1; i >= 0; i--)
|
||||
to_ptr->bits[i] = from1_tmp->bits[i] | from2_tmp->bits[i];
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
if (! bitmap_element_zerop (to_ptr))
|
||||
{
|
||||
to_ptr->indx = indx;
|
||||
bitmap_element_link (to, to_ptr);
|
||||
to_ptr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we have an unallocated element due to the last element being 0,
|
||||
release it back to the free pool. Don't bother calling
|
||||
bitmap_element_free since it was never linked into a bitmap. */
|
||||
if (to_ptr != 0)
|
||||
{
|
||||
to_ptr->next = bitmap_free;
|
||||
bitmap_free = to_ptr;
|
||||
}
|
||||
|
||||
/* If the output bitmap was one of the inputs, free up its
|
||||
elements now that we're done. */
|
||||
for (; delete_list != 0; delete_list = to_ptr)
|
||||
{
|
||||
to_ptr = delete_list->next;
|
||||
delete_list->next = bitmap_free;
|
||||
bitmap_free = delete_list;
|
||||
}
|
||||
}
|
||||
|
||||
/* Or into bitmap TO bitmap FROM1 and'ed with the complement of
|
||||
bitmap FROM2. */
|
||||
|
||||
void
|
||||
bitmap_ior_and_compl (to, from1, from2)
|
||||
bitmap to;
|
||||
bitmap from1;
|
||||
bitmap from2;
|
||||
{
|
||||
bitmap_head tmp;
|
||||
|
||||
tmp.first = tmp.current = 0;
|
||||
|
||||
bitmap_operation (&tmp, from1, from2, BITMAP_AND_COMPL);
|
||||
bitmap_operation (to, to, &tmp, BITMAP_IOR);
|
||||
bitmap_clear (&tmp);
|
||||
}
|
||||
|
||||
/* Initialize a bitmap header. */
|
||||
|
||||
bitmap
|
||||
bitmap_initialize (head)
|
||||
bitmap head;
|
||||
{
|
||||
head->first = head->current = 0;
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
/* Debugging function to print out the contents of a bitmap. */
|
||||
|
||||
void
|
||||
bitmap_debug_file (file, head)
|
||||
FILE *file;
|
||||
bitmap head;
|
||||
{
|
||||
bitmap_element *ptr;
|
||||
|
||||
fprintf (file, "\nfirst = ");
|
||||
fprintf (file, HOST_PTR_PRINTF, (HOST_WIDE_INT) head->first);
|
||||
fprintf (file, " current = ");
|
||||
fprintf (file, HOST_PTR_PRINTF, (HOST_WIDE_INT) head->current);
|
||||
fprintf (file, " indx = %u\n", head->indx);
|
||||
|
||||
for (ptr = head->first; ptr; ptr = ptr->next)
|
||||
{
|
||||
int i, j, col = 26;
|
||||
|
||||
fprintf (file, "\t");
|
||||
fprintf (file, HOST_PTR_PRINTF, (HOST_WIDE_INT) ptr);
|
||||
fprintf (file, " next = ");
|
||||
fprintf (file, HOST_PTR_PRINTF, (HOST_WIDE_INT) ptr->next);
|
||||
fprintf (file, " prev = ");
|
||||
fprintf (file, HOST_PTR_PRINTF, (HOST_WIDE_INT) ptr->prev);
|
||||
fprintf (file, " indx = %u\n\t\tbits = {", ptr->indx);
|
||||
|
||||
for (i = 0; i < BITMAP_ELEMENT_WORDS; i++)
|
||||
for (j = 0; j < HOST_BITS_PER_WIDE_INT; j++)
|
||||
if ((ptr->bits[i] & (((unsigned HOST_WIDE_INT) 1) << j)) != 0)
|
||||
{
|
||||
if (col > 70)
|
||||
{
|
||||
fprintf (file, "\n\t\t\t");
|
||||
col = 24;
|
||||
}
|
||||
|
||||
fprintf (file, " %u", (ptr->indx * BITMAP_ELEMENT_ALL_BITS
|
||||
+ i * HOST_BITS_PER_WIDE_INT + j));
|
||||
col += 4;
|
||||
}
|
||||
|
||||
fprintf (file, " }\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Function to be called from the debugger to print the contents
|
||||
of a bitmap. */
|
||||
|
||||
void
|
||||
debug_bitmap (head)
|
||||
bitmap head;
|
||||
{
|
||||
bitmap_debug_file (stdout, head);
|
||||
}
|
||||
|
||||
/* Function to print out the contents of a bitmap. Unlike bitmap_debug_file,
|
||||
it does not print anything but the bits. */
|
||||
|
||||
void
|
||||
bitmap_print (file, head, prefix, suffix)
|
||||
FILE *file;
|
||||
bitmap head;
|
||||
char *prefix;
|
||||
char *suffix;
|
||||
{
|
||||
char *comma = "";
|
||||
int i;
|
||||
|
||||
fputs (prefix, file);
|
||||
EXECUTE_IF_SET_IN_BITMAP (head, 0, i,
|
||||
{
|
||||
fprintf (file, "%s%d", comma, i);
|
||||
comma = ", ";
|
||||
});
|
||||
fputs (suffix, file);
|
||||
}
|
||||
|
||||
/* Release any memory allocated by bitmaps. */
|
||||
|
||||
void
|
||||
bitmap_release_memory ()
|
||||
{
|
||||
bitmap_free = 0;
|
||||
if (bitmap_obstack_init)
|
||||
{
|
||||
bitmap_obstack_init = FALSE;
|
||||
obstack_free (&bitmap_obstack, NULL_PTR);
|
||||
}
|
||||
}
|
315
bitmap.h
Normal file
315
bitmap.h
Normal file
@ -0,0 +1,315 @@
|
||||
/* Functions to support general ended bitmaps.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Number of words to use for each element in the linked list. */
|
||||
|
||||
#ifndef BITMAP_ELEMENT_WORDS
|
||||
#define BITMAP_ELEMENT_WORDS 2
|
||||
#endif
|
||||
|
||||
/* Number of bits in each actual element of a bitmap. We get slightly better
|
||||
code for bit % BITMAP_ELEMENT_ALL_BITS and bit / BITMAP_ELEMENT_ALL_BITS if
|
||||
bits is unsigned, assuming it is a power of 2. */
|
||||
|
||||
#define BITMAP_ELEMENT_ALL_BITS \
|
||||
((unsigned) (BITMAP_ELEMENT_WORDS * HOST_BITS_PER_WIDE_INT))
|
||||
|
||||
/* Bitmap set element. We use a linked list to hold only the bits that
|
||||
are set. This allows for use to grow the bitset dynamically without
|
||||
having to realloc and copy a giant bit array. The `prev' field is
|
||||
undefined for an element on the free list. */
|
||||
|
||||
typedef struct bitmap_element_def
|
||||
{
|
||||
struct bitmap_element_def *next; /* Next element. */
|
||||
struct bitmap_element_def *prev; /* Previous element. */
|
||||
unsigned int indx; /* regno/BITMAP_ELEMENT_ALL_BITS. */
|
||||
unsigned HOST_WIDE_INT bits[BITMAP_ELEMENT_WORDS]; /* Bits that are set. */
|
||||
} bitmap_element;
|
||||
|
||||
/* Head of bitmap linked list. */
|
||||
typedef struct bitmap_head_def {
|
||||
bitmap_element *first; /* First element in linked list. */
|
||||
bitmap_element *current; /* Last element looked at. */
|
||||
int indx; /* Index of last element looked at. */
|
||||
} bitmap_head, *bitmap;
|
||||
|
||||
/* Enumeration giving the various operations we support. */
|
||||
enum bitmap_bits {
|
||||
BITMAP_AND, /* TO = FROM1 & FROM2 */
|
||||
BITMAP_AND_COMPL, /* TO = FROM1 & ~ FROM2 */
|
||||
BITMAP_IOR /* TO = FROM1 | FROM2 */
|
||||
};
|
||||
|
||||
/* Global data */
|
||||
extern bitmap_element *bitmap_free; /* Freelist of bitmap elements */
|
||||
extern bitmap_element bitmap_zero; /* Zero bitmap element */
|
||||
|
||||
/* Clear a bitmap by freeing up the linked list. */
|
||||
extern void bitmap_clear PROTO((bitmap));
|
||||
|
||||
/* Copy a bitmap to another bitmap. */
|
||||
extern void bitmap_copy PROTO((bitmap, bitmap));
|
||||
|
||||
/* Perform an operation on two bitmaps, yielding a third. */
|
||||
extern void bitmap_operation PROTO((bitmap, bitmap, bitmap, enum bitmap_bits));
|
||||
|
||||
/* `or' into one bitmap the `and' of a second bitmap witih the complement
|
||||
of a third. */
|
||||
extern void bitmap_ior_and_compl PROTO((bitmap, bitmap, bitmap));
|
||||
|
||||
/* Clear a single register in a register set. */
|
||||
extern void bitmap_clear_bit PROTO((bitmap, int));
|
||||
|
||||
/* Set a single register in a register set. */
|
||||
extern void bitmap_set_bit PROTO((bitmap, int));
|
||||
|
||||
/* Return true if a register is set in a register set. */
|
||||
extern int bitmap_bit_p PROTO((bitmap, int));
|
||||
|
||||
/* Debug functions to print a bitmap linked list. */
|
||||
extern void bitmap_debug PROTO((bitmap));
|
||||
extern void bitmap_debug_file PROTO((FILE *, bitmap));
|
||||
|
||||
/* Print a bitmap */
|
||||
extern void bitmap_print PROTO((FILE *, bitmap, char *, char *));
|
||||
|
||||
/* Initialize a bitmap header. */
|
||||
extern bitmap bitmap_initialize PROTO((bitmap));
|
||||
|
||||
/* Release all memory held by bitmaps. */
|
||||
extern void bitmap_release_memory PROTO((void));
|
||||
|
||||
/* Allocate a bitmap with oballoc. */
|
||||
#define BITMAP_OBSTACK_ALLOC(OBSTACK) \
|
||||
bitmap_initialize ((bitmap) obstack_alloc (OBSTACK, sizeof (bitmap_head)))
|
||||
|
||||
/* Allocate a bitmap with alloca. */
|
||||
#define BITMAP_ALLOCA() \
|
||||
bitmap_initialize ((bitmap) alloca (sizeof (bitmap_head)))
|
||||
|
||||
/* Do any cleanup needed on a bitmap when it is no longer used. */
|
||||
#define BITMAP_FREE(BITMAP) \
|
||||
do { \
|
||||
if (BITMAP) \
|
||||
{ \
|
||||
bitmap_clear (BITMAP); \
|
||||
(BITMAP) = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Do any one-time initializations needed for bitmaps. */
|
||||
#define BITMAP_INIT_ONCE()
|
||||
|
||||
/* Loop over all bits in BITMAP, starting with MIN, setting BITNUM to the
|
||||
bit number and executing CODE for all bits that are set. */
|
||||
|
||||
#define EXECUTE_IF_SET_IN_BITMAP(BITMAP, MIN, BITNUM, CODE) \
|
||||
do { \
|
||||
bitmap_element *ptr_ = (BITMAP)->first; \
|
||||
unsigned int indx_ = (MIN) / BITMAP_ELEMENT_ALL_BITS; \
|
||||
unsigned bit_num_ = (MIN) % ((unsigned) HOST_BITS_PER_WIDE_INT); \
|
||||
unsigned word_num_ = (((MIN) / ((unsigned) HOST_BITS_PER_WIDE_INT)) \
|
||||
% BITMAP_ELEMENT_WORDS); \
|
||||
\
|
||||
\
|
||||
/* Find the block the minimum bit is in. */ \
|
||||
while (ptr_ != 0 && ptr_->indx < indx_) \
|
||||
ptr_ = ptr_->next; \
|
||||
\
|
||||
if (ptr_ != 0 && ptr_->indx != indx_) \
|
||||
{ \
|
||||
bit_num_ = 0; \
|
||||
word_num_ = 0; \
|
||||
} \
|
||||
\
|
||||
for (; ptr_ != 0; ptr_ = ptr_->next) \
|
||||
{ \
|
||||
for (; word_num_ < BITMAP_ELEMENT_WORDS; word_num_++) \
|
||||
{ \
|
||||
unsigned HOST_WIDE_INT word_ = ptr_->bits[word_num_]; \
|
||||
\
|
||||
if (word_ != 0) \
|
||||
{ \
|
||||
for (; bit_num_ < HOST_BITS_PER_WIDE_INT; bit_num_++) \
|
||||
{ \
|
||||
unsigned HOST_WIDE_INT mask_ \
|
||||
= ((unsigned HOST_WIDE_INT) 1) << bit_num_; \
|
||||
\
|
||||
if ((word_ & mask_) != 0) \
|
||||
{ \
|
||||
word_ &= ~ mask_; \
|
||||
(BITNUM) = (ptr_->indx * BITMAP_ELEMENT_ALL_BITS \
|
||||
+ word_num_ * HOST_BITS_PER_WIDE_INT \
|
||||
+ bit_num_); \
|
||||
CODE; \
|
||||
\
|
||||
if (word_ == 0) \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
bit_num_ = 0; \
|
||||
} \
|
||||
\
|
||||
word_num_ = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Loop over all bits in BITMAP1 and BITMAP2, starting with MIN, setting
|
||||
BITNUM to the bit number and executing CODE for all bits that are set in
|
||||
the first bitmap and not set in the second. */
|
||||
|
||||
#define EXECUTE_IF_AND_COMPL_IN_BITMAP(BITMAP1, BITMAP2, MIN, BITNUM, CODE) \
|
||||
do { \
|
||||
bitmap_element *ptr1_ = (BITMAP1)->first; \
|
||||
bitmap_element *ptr2_ = (BITMAP2)->first; \
|
||||
unsigned int indx_ = (MIN) / BITMAP_ELEMENT_ALL_BITS; \
|
||||
unsigned bit_num_ = (MIN) % ((unsigned) HOST_BITS_PER_WIDE_INT); \
|
||||
unsigned word_num_ = (((MIN) / ((unsigned) HOST_BITS_PER_WIDE_INT)) \
|
||||
% BITMAP_ELEMENT_WORDS); \
|
||||
\
|
||||
/* Find the block the minimum bit is in in the first bitmap. */ \
|
||||
while (ptr1_ != 0 && ptr1_->indx < indx_) \
|
||||
ptr1_ = ptr1_->next; \
|
||||
\
|
||||
if (ptr1_ != 0 && ptr1_->indx != indx_) \
|
||||
{ \
|
||||
bit_num_ = 0; \
|
||||
word_num_ = 0; \
|
||||
} \
|
||||
\
|
||||
for (; ptr1_ != 0 ; ptr1_ = ptr1_->next) \
|
||||
{ \
|
||||
/* Advance BITMAP2 to the equivalent link, using an all \
|
||||
zero element if an equivalent link doesn't exist. */ \
|
||||
bitmap_element *tmp2_; \
|
||||
\
|
||||
while (ptr2_ != 0 && ptr2_->indx < ptr1_->indx) \
|
||||
ptr2_ = ptr2_->next; \
|
||||
\
|
||||
tmp2_ = ((ptr2_ != 0 && ptr2_->indx == ptr1_->indx) \
|
||||
? ptr2_ : &bitmap_zero); \
|
||||
\
|
||||
for (; word_num_ < BITMAP_ELEMENT_WORDS; word_num_++) \
|
||||
{ \
|
||||
unsigned HOST_WIDE_INT word_ = (ptr1_->bits[word_num_] \
|
||||
& ~ tmp2_->bits[word_num_]); \
|
||||
if (word_ != 0) \
|
||||
{ \
|
||||
for (; bit_num_ < HOST_BITS_PER_WIDE_INT; bit_num_++) \
|
||||
{ \
|
||||
unsigned HOST_WIDE_INT mask_ \
|
||||
= ((unsigned HOST_WIDE_INT)1) << bit_num_; \
|
||||
\
|
||||
if ((word_ & mask_) != 0) \
|
||||
{ \
|
||||
word_ &= ~ mask_; \
|
||||
(BITNUM) = (ptr1_->indx * BITMAP_ELEMENT_ALL_BITS \
|
||||
+ word_num_ * HOST_BITS_PER_WIDE_INT \
|
||||
+ bit_num_); \
|
||||
\
|
||||
CODE; \
|
||||
if (word_ == 0) \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
bit_num_ = 0; \
|
||||
} \
|
||||
\
|
||||
word_num_ = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Loop over all bits in BITMAP1 and BITMAP2, starting with MIN, setting
|
||||
BITNUM to the bit number and executing CODE for all bits that are set in
|
||||
the both bitmaps. */
|
||||
|
||||
#define EXECUTE_IF_AND_IN_BITMAP(BITMAP1, BITMAP2, MIN, BITNUM, CODE) \
|
||||
do { \
|
||||
bitmap_element *ptr1_ = (BITMAP1)->first; \
|
||||
bitmap_element *ptr2_ = (BITMAP2)->first; \
|
||||
unsigned int indx_ = (MIN) / BITMAP_ELEMENT_ALL_BITS; \
|
||||
unsigned bit_num_ = (MIN) % ((unsigned) HOST_BITS_PER_WIDE_INT); \
|
||||
unsigned word_num_ = (((MIN) / ((unsigned) HOST_BITS_PER_WIDE_INT)) \
|
||||
% BITMAP_ELEMENT_WORDS); \
|
||||
\
|
||||
/* Find the block the minimum bit is in in the first bitmap. */ \
|
||||
while (ptr1_ != 0 && ptr1_->indx < indx_) \
|
||||
ptr1_ = ptr1_->next; \
|
||||
\
|
||||
if (ptr1_ != 0 && ptr1_->indx != indx_) \
|
||||
{ \
|
||||
bit_num_ = 0; \
|
||||
word_num_ = 0; \
|
||||
} \
|
||||
\
|
||||
for (; ptr1_ != 0 ; ptr1_ = ptr1_->next) \
|
||||
{ \
|
||||
/* Advance BITMAP2 to the equivalent link */ \
|
||||
while (ptr2_ != 0 && ptr2_->indx < ptr1_->indx) \
|
||||
ptr2_ = ptr2_->next; \
|
||||
\
|
||||
if (ptr2_ == 0) \
|
||||
{ \
|
||||
/* If there are no more elements in BITMAP2, exit loop now.*/ \
|
||||
ptr1_ = (bitmap_element *)0; \
|
||||
break; \
|
||||
} \
|
||||
else if (ptr2_->indx > ptr1_->indx) \
|
||||
{ \
|
||||
bit_num_ = word_num_ = 0; \
|
||||
continue; \
|
||||
} \
|
||||
\
|
||||
for (; word_num_ < BITMAP_ELEMENT_WORDS; word_num_++) \
|
||||
{ \
|
||||
unsigned HOST_WIDE_INT word_ = (ptr1_->bits[word_num_] \
|
||||
& ptr2_->bits[word_num_]); \
|
||||
if (word_ != 0) \
|
||||
{ \
|
||||
for (; bit_num_ < HOST_BITS_PER_WIDE_INT; bit_num_++) \
|
||||
{ \
|
||||
unsigned HOST_WIDE_INT mask_ \
|
||||
= ((unsigned HOST_WIDE_INT)1) << bit_num_; \
|
||||
\
|
||||
if ((word_ & mask_) != 0) \
|
||||
{ \
|
||||
word_ &= ~ mask_; \
|
||||
(BITNUM) = (ptr1_->indx * BITMAP_ELEMENT_ALL_BITS \
|
||||
+ word_num_ * HOST_BITS_PER_WIDE_INT \
|
||||
+ bit_num_); \
|
||||
\
|
||||
CODE; \
|
||||
if (word_ == 0) \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
bit_num_ = 0; \
|
||||
} \
|
||||
\
|
||||
word_num_ = 0; \
|
||||
} \
|
||||
} while (0)
|
35
build-make
Normal file
35
build-make
Normal file
@ -0,0 +1,35 @@
|
||||
# We have to use the cross-compiler we just built to compile it.
|
||||
CC = gcc -b $(host)
|
||||
|
||||
# Need those to compile binaries running on host machine.
|
||||
# It is configured by
|
||||
#
|
||||
# configure --host=target_cpu-target_os \
|
||||
# --target=host=target_cpu-target_os --build=host_cpu-host_os
|
||||
#
|
||||
# That HOST stuff has to be taken care of very carefully.
|
||||
HOST_PREFIX=l-
|
||||
HOST_PREFIX_1=$(HOST_PREFIX)
|
||||
HOST_CC=$(CC) -b $(build)
|
||||
HOST_CFLAGS=$(INTERNAL_CFLAGS) $(T_CFLAGS) $(CFLAGS) $(XCFLAGS)
|
||||
HOST_CLIB=
|
||||
HOST_LDFLAGS=$(LDFLAGS)
|
||||
HOST_CPPFLAGS=$(ALL_CPPFLAGS)
|
||||
HOST_ALLOCA=$(ALLOCA)
|
||||
HOST_MALLOC=$(MALLOC)
|
||||
HOST_OBSTACK=$(OBSTACK)
|
||||
|
||||
# To build the native compiler with the cross compiler, the headers
|
||||
# for the target are already fixed. And /usr/include is for host, not
|
||||
# target.
|
||||
FIXINCLUDES=Makefile.in
|
||||
|
||||
# Don't run fixproto either
|
||||
STMP_FIXPROTO =
|
||||
|
||||
# Cause installation using install-build. We do nothing here.
|
||||
INSTALL_TARGET = install-build
|
||||
|
||||
# Don't try to compile the things we can't compile or we have made
|
||||
# while making gcc with the cross-compiler.
|
||||
ALL = all.build
|
322
bytecode.def
Normal file
322
bytecode.def
Normal file
@ -0,0 +1,322 @@
|
||||
# -*- C -*-
|
||||
# bytecode.def - definitions of bytecodes for the stack machine.
|
||||
|
||||
# The production of the bytecode interpreter and compiler is
|
||||
# heavily automated by using this file creatively.
|
||||
|
||||
# Various elementary data types are understood by the bytecode interpreter.
|
||||
# Q[IU] - quarter word (byte) signed and unsigned integers (char).
|
||||
# H[IU] - half word signed and unsigned integers (short int, maybe int).
|
||||
# S[IU] - single word signed and unsigned integers (maybe int, long int).
|
||||
# D[IU] - double word signed and unsigned integers (long long int).
|
||||
# SF - single precision floating point (float).
|
||||
# DF - double precision floating point (double).
|
||||
# XF - extended precision floating point (long double).
|
||||
# P - pointer type for address arithmetic and other purposes.
|
||||
|
||||
# The bytecode specification consists of a series of define_operator
|
||||
# forms, that are parsed by preprocessors to automatically build
|
||||
# various switch statements.
|
||||
# define_operator(name,
|
||||
# <C prototype code for implementing the operator>,
|
||||
# <list of variations>)
|
||||
# The <C prototype> is self explanatory.
|
||||
# The <list of variations> consists of a (parenthesized list) of
|
||||
# variation items, each of which is in itself a list. A variation
|
||||
# item consists of a name suffix, the types of the input arguments
|
||||
# expected on the stack (shallowest item first) and (optionally) the
|
||||
# types of the output arguments (similarly ordered). Finally, the
|
||||
# types of the literal arguments (if any) may appear.
|
||||
|
||||
# Substitution in the C prototype code is as follows:
|
||||
# Substitution happens only after a dollar sign. To get a literal
|
||||
# dollar sign (why would you ever want one anyway?) use $$.
|
||||
# $R1 means "result 1" $TR1 means "type name of result one"
|
||||
# $S1 means "source 1" and similarly with $TS1.
|
||||
# $L1 means "literal (inline) argument 1" and $TL1 means type thereof.
|
||||
#
|
||||
|
||||
# Notice that the number following $R doesn't affect the push order;
|
||||
# it's used only for clarity and orthogonality, although it's checked
|
||||
# to make sure it doesn't exceed the number of outputs. A $R reference
|
||||
# results in a push, and represents the result lvalue. E.g.
|
||||
|
||||
# $R1 = 2\, $R2 = 17
|
||||
# will expand to:
|
||||
# INTERP_PUSH($TR1) = 2, INTERP_PUSH($TR2) = 17
|
||||
#
|
||||
|
||||
# Opcode 0 should never happen.
|
||||
define_operator(neverneverland, abort\(\), (()))
|
||||
|
||||
# Stack manipulations.
|
||||
define_operator(drop, 0, ((, (SI))))
|
||||
define_operator(duplicate, 0, ((, (SI), (SI, SI))))
|
||||
define_operator(over, 0, ((, (SI), (SI, SI))))
|
||||
|
||||
# Adjust stack pointer
|
||||
|
||||
define_operator(setstack, 0, ((SI,,,(SI))))
|
||||
define_operator(adjstack, 0, ((SI,,,(SI))))
|
||||
|
||||
# Constants, loads, and stores.
|
||||
define_operator(const,
|
||||
$R1 = $L1,
|
||||
((QI,, (QI), (QI)), (HI,, (HI), (HI)),
|
||||
(SI,, (SI), (SI)), (DI,, (DI), (DI)),
|
||||
(SF,, (SF), (SF)), (DF,, (DF), (DF)),
|
||||
(XF,, (XF), (XF)), (P,, (P), (P))))
|
||||
define_operator(load,
|
||||
$R1 = *\($TR1 *\) $S1,
|
||||
((QI, (P), (QI)), (HI, (P), (HI)),
|
||||
(SI, (P), (SI)), (DI, (P), (DI)),
|
||||
(SF, (P), (SF)), (DF, (P), (DF)),
|
||||
(XF, (P), (XF)), (P, (P), (P))))
|
||||
define_operator(store,
|
||||
*\($TS2 *\) $S1 = $S2,
|
||||
((QI, (P, QI)), (HI, (P, HI)),
|
||||
(SI, (P, SI)), (DI, (P, DI)),
|
||||
(SF, (P, SF)), (DF, (P, DF)),
|
||||
(XF, (P, XF)), (P, (P, P)),
|
||||
(BLK, (SI, BLK, BLK))))
|
||||
|
||||
# Clear memory block
|
||||
|
||||
define_operator(clear, $S1 + $S2, ((BLK, (SI, BLK))))
|
||||
|
||||
|
||||
# Advance pointer by SI constant
|
||||
|
||||
define_operator(addconst, $R1 = $S1, ((PSI, (P), (P), (SI))))
|
||||
|
||||
|
||||
# newlocalSI is used for creating variable-sized storage during function
|
||||
# initialization.
|
||||
|
||||
# Create local space, return pointer to block
|
||||
|
||||
define_operator(newlocal, $R1 = $S1, ((SI, (SI), (P))))
|
||||
|
||||
|
||||
# Push the address of a local variable.
|
||||
define_operator(local, $R1 = locals + $L1, ((P,, (P), (SI))))
|
||||
|
||||
# Push the address of an argument variable.
|
||||
define_operator(arg, $R1 = args + $L1, ((P,, (P), (SI))))
|
||||
|
||||
# Arithmetic conversions.
|
||||
define_operator(convert,
|
||||
$R1 = \($TR1\) $S1,
|
||||
(# Signed integral promotions (sign extensions).
|
||||
(QIHI, (QI), (HI)), (HISI, (HI), (SI)), (SIDI, (SI), (DI)),
|
||||
(QISI, (QI), (SI)),
|
||||
# Unsigned integral promotions (zero extensions).
|
||||
(QUHU, (QU), (HU)), (HUSU, (HU), (SU)), (SUDU, (SU), (DU)),
|
||||
(QUSU, (QU), (SU)),
|
||||
# Floating promotions.
|
||||
(SFDF, (SF), (DF)), (DFXF, (DF), (XF)),
|
||||
# Integral truncation.
|
||||
(HIQI, (HI), (QI)), (SIHI, (SI), (HI)), (DISI, (DI), (SI)),
|
||||
(SIQI, (SI), (QI)),
|
||||
# Unsigned truncation.
|
||||
(SUQU, (SU), (QU)),
|
||||
# Floating truncation.
|
||||
(DFSF, (DF), (SF)), (XFDF, (XF), (DF)),
|
||||
# Integral conversions to floating types.
|
||||
(SISF, (SI), (SF)), (SIDF, (SI), (DF)), (SIXF, (SI), (XF)),
|
||||
(SUSF, (SU), (SF)), (SUDF, (SU), (DF)), (SUXF, (SU), (XF)),
|
||||
(DISF, (DI), (SF)), (DIDF, (DI), (DF)), (DIXF, (DI), (XF)),
|
||||
(DUSF, (DU), (SF)), (DUDF, (DU), (DF)), (DUXF, (DU), (XF)),
|
||||
# Floating conversions to integral types.
|
||||
(SFSI, (SF), (SI)), (DFSI, (DF), (SI)), (XFSI, (XF), (SI)),
|
||||
(SFSU, (SF), (SU)), (DFSU, (DF), (SU)), (XFSU, (XF), (SU)),
|
||||
(SFDI, (SF), (DI)), (DFDI, (DF), (DI)), (XFDI, (XF), (DI)),
|
||||
(SFDU, (SF), (DU)), (DFDU, (DF), (DU)), (XFDU, (XF), (DU)),
|
||||
# Pointer/integer conversions.
|
||||
(PSI, (P), (SI)), (SIP, (SI), (P))))
|
||||
|
||||
# Truth value conversion. These are necessary because conversions of, e.g.,
|
||||
# floating types to integers may not function correctly for large values.
|
||||
define_operator(convert,
|
||||
$R1 = !!$S1,
|
||||
((SIT, (SI), (T)), (DIT, (DI), (T)),
|
||||
(SFT, (SF), (T)), (DFT, (DF), (T)),
|
||||
(XFT, (XF), (T)), (PT, (P), (T))))
|
||||
|
||||
# Bit field load/store.
|
||||
|
||||
# Load and zero-extend bitfield
|
||||
|
||||
define_operator(zxload, $R1 = $S1, ((BI, (SU, SU, P), (SU))))
|
||||
|
||||
# Load and sign-extend bitfield
|
||||
|
||||
define_operator(sxload, $R1 = $S1, ((BI, (SU, SU, P), (SI))))
|
||||
|
||||
# Store integer in bitfield
|
||||
|
||||
define_operator(sstore, $R1 = $S1, ((BI, (SU, SU, P, SI))))
|
||||
|
||||
|
||||
# Binary operations.
|
||||
define_operator(add,
|
||||
$R1 = $S1 + $S2,
|
||||
((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)),
|
||||
(SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)),
|
||||
(XF, (XF, XF), (XF)),
|
||||
(PSI, (P, SI), (P))))
|
||||
define_operator(sub,
|
||||
$R1 = $S1 - $S2,
|
||||
((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)),
|
||||
(SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)),
|
||||
(XF, (XF, XF), (XF)),
|
||||
(PP, (P, P), (SI))))
|
||||
define_operator(mul,
|
||||
$R1 = $S1 * $S2,
|
||||
((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)),
|
||||
(SU, (SU, SU), (SU)), (DU, (DU, DU), (DU)),
|
||||
(SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)),
|
||||
(XF, (XF, XF), (XF))))
|
||||
define_operator(div,
|
||||
$R1 = $S1 / $S2,
|
||||
((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)),
|
||||
(SU, (SU, SU), (SU)), (DU, (DU, DU), (DU)),
|
||||
(SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)),
|
||||
(XF, (XF, XF), (XF))))
|
||||
define_operator(mod,
|
||||
$R1 = $S1 % $S2,
|
||||
((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)),
|
||||
(SU, (SU, SU), (SU)), (DU, (DU, DU), (DU))))
|
||||
define_operator(and,
|
||||
$R1 = $S1 & $S2,
|
||||
((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI))))
|
||||
define_operator(ior,
|
||||
$R1 = $S1 | $S2,
|
||||
((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI))))
|
||||
define_operator(xor,
|
||||
$R1 = $S1 ^ $S2,
|
||||
((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI))))
|
||||
define_operator(lshift,
|
||||
$R1 = $S1 << $S2,
|
||||
((SI, (SI, SI), (SI)), (SU, (SU, SI), (SU)),
|
||||
(DI, (DI, SI), (DI)), (DU, (DU, SI), (DU))))
|
||||
define_operator(rshift,
|
||||
$R1 = $S1 >> $S2,
|
||||
((SI, (SI, SI), (SI)), (SU, (SU, SI), (SU)),
|
||||
(DI, (DI, SI), (DI)), (DU, (DU, SI), (DU))))
|
||||
define_operator(lt,
|
||||
$R1 = $S1 < $S2,
|
||||
((SI, (SI, SI), (T)), (SU, (SU, SU), (T)),
|
||||
(DI, (DI, DI), (T)), (DU, (DU, DU), (T)),
|
||||
(SF, (SF, SF), (T)), (DF, (DF, DF), (T)),
|
||||
(XF, (XF, XF), (T)), (P, (P, P), (T))))
|
||||
define_operator(le,
|
||||
$R1 = $S1 <= $S2,
|
||||
((SI, (SI, SI), (T)), (SU, (SU, SU), (T)),
|
||||
(DI, (DI, DI), (T)), (DU, (DU, DU), (T)),
|
||||
(SF, (SF, SF), (T)), (DF, (DF, DF), (T)),
|
||||
(XF, (XF, XF), (T)), (P, (P, P), (T))))
|
||||
define_operator(ge,
|
||||
$R1 = $S1 >= $S2,
|
||||
((SI, (SI, SI), (T)), (SU, (SU, SU), (T)),
|
||||
(DI, (DI, DI), (T)), (DU, (DU, DU), (T)),
|
||||
(SF, (SF, SF), (T)), (DF, (DF, DF), (T)),
|
||||
(XF, (XF, XF), (T)), (P, (P, P), (T))))
|
||||
define_operator(gt,
|
||||
$R1 = $S1 > $S2,
|
||||
((SI, (SI, SI), (T)), (SU, (SU, SU), (T)),
|
||||
(DI, (DI, DI), (T)), (DU, (DU, DU), (T)),
|
||||
(SF, (SF, SF), (T)), (DF, (DF, DF), (T)),
|
||||
(XF, (XF, XF), (T)), (P, (P, P), (T))))
|
||||
define_operator(eq,
|
||||
$R1 = $S1 == $S2,
|
||||
((SI, (SI, SI), (T)), (DI, (DI, DI), (T)),
|
||||
(SF, (SF, SF), (T)), (DF, (DF, DF), (T)),
|
||||
(XF, (XF, XF), (T)), (P, (P, P), (T))))
|
||||
define_operator(ne,
|
||||
$R1 = $S1 != $S2,
|
||||
((SI, (SI, SI), (T)), (DI, (DI, DI), (T)),
|
||||
(SF, (SF, SF), (T)), (DF, (DF, DF), (T)),
|
||||
(XF, (XF, XF), (T)), (P, (P, P), (T))))
|
||||
|
||||
# Unary operations.
|
||||
define_operator(neg,
|
||||
$R1 = -$S1,
|
||||
((SI, (SI), (SI)), (DI, (DI), (DI)),
|
||||
(SF, (SF), (SF)), (DF, (DF), (DF)),
|
||||
(XF, (XF), (XF))))
|
||||
define_operator(not,
|
||||
$R1 = ~$S1,
|
||||
((SI, (SI), (SI)), (DI, (DI), (DI))))
|
||||
define_operator(not,
|
||||
$R1 = !$S1,
|
||||
((T, (SI), (SI))))
|
||||
|
||||
# Increment operations.
|
||||
define_operator(predec,
|
||||
$R1 = *\($TR1 *\) $S1 -= $S2,
|
||||
((QI, (P, QI), (QI)), (HI, (P, HI), (HI)),
|
||||
(SI, (P, SI), (SI)), (DI, (P, DI), (DI)),
|
||||
(P, (P, SI), (P)), (SF, (P, SF), (SF)),
|
||||
(DF, (P, DF), (DF)), (XF, (P, XF), (XF)),
|
||||
(BI, (SU, SU, P, SI), (SI))))
|
||||
|
||||
define_operator(preinc,
|
||||
$R1 = *\($TR1 *\) $S1 += $S2,
|
||||
((QI, (P, QI), (QI)), (HI, (P, HI), (HI)),
|
||||
(SI, (P, SI), (SI)), (DI, (P, DI), (DI)),
|
||||
(P, (P, SI), (P)), (SF, (P, SF), (SF)),
|
||||
(DF, (P, DF), (DF)), (XF, (P, XF), (XF)),
|
||||
(BI, (SU, SU, P, SI), (SI))))
|
||||
|
||||
define_operator(postdec,
|
||||
$R1 = *\($TR1 *\) $S1\, *\($TR1 *\) $S1 -= $S2,
|
||||
((QI, (P, QI), (QI)), (HI, (P, HI), (HI)),
|
||||
(SI, (P, SI), (SI)), (DI, (P, DI), (DI)),
|
||||
(P, (P, SI), (P)), (SF, (P, SF), (SF)),
|
||||
(DF, (P, DF), (DF)), (XF, (P, XF), (XF)),
|
||||
(BI, (SU, SU, P, SI), (SI))))
|
||||
|
||||
define_operator(postinc,
|
||||
$R1 = *\($TR1 *\) $S1\, *\($TR1 *\) $S1 += $S2,
|
||||
((QI, (P, QI), (QI)), (HI, (P, HI), (HI)),
|
||||
(SI, (P, SI), (SI)), (DI, (P, DI), (DI)),
|
||||
(P, (P, SI), (P)), (SF, (P, SF), (SF)),
|
||||
(DF, (P, DF), (DF)), (XF, (P, XF), (XF)),
|
||||
(BI, (SU, SU, P, SI), (SI))))
|
||||
|
||||
# Jumps.
|
||||
define_operator(xjumpif, if \($S1\) pc = code->pc0 + $L1, ((, (T),, (SI))))
|
||||
define_operator(xjumpifnot, if \(! $S1\) pc = code->pc0 + $L1, ((, (T),, (SI))))
|
||||
define_operator(jump, pc = code->pc0 + $L1, ((,,,(SI))))
|
||||
|
||||
# This is for GCC2. It jumps to the address on the stack.
|
||||
define_operator(jump, pc = \(void *\) $S1, ((P,,)))
|
||||
|
||||
# Switches. In order to (eventually) support ranges we provide four different
|
||||
# varieties of switches. Arguments are the switch index from the stack, the
|
||||
# bytecode offset of the switch table, the size of the switch table, and
|
||||
# the default label.
|
||||
define_operator(caseSI, CASESI\($S1\, $L1\, $L2\, $L3\), ((, (SI),, (SI, SI, SI))))
|
||||
define_operator(caseSU, CASESU\($S1\, $L1\, $L2\, $L3\), ((, (SU),, (SI, SI, SI))))
|
||||
define_operator(caseDI, CASEDI\($S1\, $L1\, $L2\, $L3\), ((, (DI),, (SI, SI, SI))))
|
||||
define_operator(caseDU, CASEDU\($S1\, $L1\, $L2\, $L3\), ((, (DU),, (SI, SI, SI))))
|
||||
|
||||
# Procedure call.
|
||||
# Stack arguments are (deepest first):
|
||||
# procedure arguments in reverse order.
|
||||
# pointer to the place to hold the return value.
|
||||
# address of the call description vector.
|
||||
# pointer to the procedure to be called.
|
||||
define_operator(call, CALL\($S1\, $S2\, $S3\, sp\), ((, (P, P, P))))
|
||||
|
||||
# Procedure return.
|
||||
# Pushes on interpreter stack:
|
||||
# value of retptr (pointer to return value storage slot)
|
||||
define_operator(return, $R1 = retptr, ((P,,(P))))
|
||||
|
||||
# Really return.
|
||||
define_operator(ret, return, (()))
|
||||
|
||||
# Print an obnoxious line number.
|
||||
define_operator(linenote, fprintf\(stderr\, "%d\\n"\, $L1\), ((,,,(SI))))
|
82
bytecode.h
Normal file
82
bytecode.h
Normal file
@ -0,0 +1,82 @@
|
||||
/* Bytecode definitions for GNU C-compiler.
|
||||
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
extern int output_bytecode;
|
||||
extern int stack_depth;
|
||||
extern int max_stack_depth;
|
||||
|
||||
/* Emit DI constant according to target machine word ordering */
|
||||
|
||||
#define bc_emit_bytecode_DI_const(CST) \
|
||||
{ int opcode; \
|
||||
opcode = (WORDS_BIG_ENDIAN \
|
||||
? TREE_INT_CST_HIGH (CST) \
|
||||
: TREE_INT_CST_LOW (CST)); \
|
||||
bc_emit_bytecode_const ((char *) &opcode, sizeof opcode); \
|
||||
opcode = (WORDS_BIG_ENDIAN \
|
||||
? TREE_INT_CST_LOW (CST) \
|
||||
: TREE_INT_CST_HIGH (CST)); \
|
||||
bc_emit_bytecode_const ((char *) &opcode, sizeof opcode); \
|
||||
}
|
||||
|
||||
extern void bc_expand_expr ();
|
||||
extern void bc_output_data_constructor ();
|
||||
extern void bc_store_field ();
|
||||
extern void bc_load_bit_field ();
|
||||
extern void bc_store_bit_field ();
|
||||
extern void bc_push_offset_and_size ();
|
||||
extern void bc_init_mode_to_code_map ();
|
||||
|
||||
/* These are just stubs, so the compiler will compile for targets
|
||||
that aren't yet supported by the bytecode generator. */
|
||||
|
||||
#ifndef TARGET_SUPPORTS_BYTECODE
|
||||
|
||||
#define MACHINE_SEG_ALIGN 1
|
||||
#define INT_ALIGN 1
|
||||
#define PTR_ALIGN 1
|
||||
#define NAMES_HAVE_UNDERSCORES
|
||||
#define BC_NOP (0)
|
||||
#define BC_GLOBALIZE_LABEL(FP, NAME) BC_NOP
|
||||
#define BC_OUTPUT_COMMON(FP, NAME, SIZE, ROUNDED) BC_NOP
|
||||
#define BC_OUTPUT_BSS(FP, NAME, SIZE, ROUNDED) BC_NOP
|
||||
#define BC_OUTPUT_LOCAL(FP, NAME, SIZE, ROUNDED) BC_NOP
|
||||
#define BC_OUTPUT_ALIGN(FP, ALIGN) BC_NOP
|
||||
#define BC_OUTPUT_LABEL(FP, NAME) BC_NOP
|
||||
#define BC_OUTPUT_SKIP(FP, SIZE) BC_NOP
|
||||
#define BC_OUTPUT_LABELREF(FP, NAME) BC_NOP
|
||||
#define BC_OUTPUT_FLOAT(FP, VAL) BC_NOP
|
||||
#define BC_OUTPUT_DOUBLE(FP, VAL) BC_NOP
|
||||
#define BC_OUTPUT_BYTE(FP, VAL) BC_NOP
|
||||
#define BC_OUTPUT_FILE ASM_OUTPUT_FILE
|
||||
#define BC_OUTPUT_ASCII ASM_OUTPUT_ASCII
|
||||
#define BC_OUTPUT_IDENT ASM_OUTPUT_IDENT
|
||||
#define BCXSTR(RTX) ((RTX)->bc_label)
|
||||
#define BC_WRITE_FILE(FP) BC_NOP
|
||||
#define BC_WRITE_SEGSYM(SEGSYM, FP) BC_NOP
|
||||
#define BC_WRITE_RELOC_ENTRY(SEGRELOC, FP, OFFSET) BC_NOP
|
||||
#define BC_START_BYTECODE_LINE(FP) BC_NOP
|
||||
#define BC_WRITE_BYTECODE(SEP, VAL, FP) BC_NOP
|
||||
#define BC_WRITE_RTL(R, FP) BC_NOP
|
||||
#define BC_EMIT_TRAMPOLINE(TRAMPSEG, CALLINFO) BC_NOP
|
||||
#define VALIDATE_STACK BC_NOP
|
||||
|
||||
#endif /* !TARGET_SUPPORTS_BYTECODE */
|
35
bytetypes.h
Normal file
35
bytetypes.h
Normal file
@ -0,0 +1,35 @@
|
||||
/* These should come from genemit */
|
||||
|
||||
/* Use __signed__ in case compiling with -traditional. */
|
||||
|
||||
typedef __signed__ char QItype;
|
||||
typedef unsigned char QUtype;
|
||||
typedef __signed__ short int HItype;
|
||||
typedef unsigned short int HUtype;
|
||||
typedef __signed__ long int SItype;
|
||||
typedef unsigned long int SUtype;
|
||||
typedef __signed__ long long int DItype;
|
||||
typedef unsigned long long int DUtype;
|
||||
typedef float SFtype;
|
||||
typedef double DFtype;
|
||||
typedef long double XFtype;
|
||||
typedef char *Ptype;
|
||||
typedef int Ttype;
|
||||
|
||||
|
||||
typedef union stacktype
|
||||
{
|
||||
QItype QIval;
|
||||
QUtype QUval;
|
||||
HItype HIval;
|
||||
HUtype HUval;
|
||||
SItype SIval;
|
||||
SUtype SUval;
|
||||
DItype DIval;
|
||||
DUtype DUval;
|
||||
SFtype SFval;
|
||||
DFtype DFval;
|
||||
XFtype XFval;
|
||||
Ptype Pval;
|
||||
Ttype Tval;
|
||||
} stacktype;
|
644
c-aux-info.c
Normal file
644
c-aux-info.c
Normal file
@ -0,0 +1,644 @@
|
||||
/* Generate information regarding function declarations and definitions based
|
||||
on information stored in GCC's tree structure. This code implements the
|
||||
-aux-info option.
|
||||
Copyright (C) 1989, 1991, 1994, 1995, 1997 Free Software Foundation, Inc.
|
||||
Contributed by Ron Guilmette (rfg@segfault.us.com).
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include "flags.h"
|
||||
#include "tree.h"
|
||||
#include "c-tree.h"
|
||||
|
||||
extern char *xmalloc ();
|
||||
|
||||
enum formals_style_enum {
|
||||
ansi,
|
||||
k_and_r_names,
|
||||
k_and_r_decls
|
||||
};
|
||||
typedef enum formals_style_enum formals_style;
|
||||
|
||||
|
||||
static char *data_type;
|
||||
|
||||
static char *concat PROTO((char *, char *));
|
||||
static char *concat3 PROTO((char *, char *, char *));
|
||||
static char *affix_data_type PROTO((char *));
|
||||
static char *gen_formal_list_for_type PROTO((tree, formals_style));
|
||||
static int deserves_ellipsis PROTO((tree));
|
||||
static char *gen_formal_list_for_func_def PROTO((tree, formals_style));
|
||||
static char *gen_type PROTO((char *, tree, formals_style));
|
||||
static char *gen_decl PROTO((tree, int, formals_style));
|
||||
|
||||
/* Take two strings and mash them together into a newly allocated area. */
|
||||
|
||||
static char *
|
||||
concat (s1, s2)
|
||||
char *s1;
|
||||
char *s2;
|
||||
{
|
||||
int size1, size2;
|
||||
char *ret_val;
|
||||
|
||||
if (!s1)
|
||||
s1 = "";
|
||||
if (!s2)
|
||||
s2 = "";
|
||||
|
||||
size1 = strlen (s1);
|
||||
size2 = strlen (s2);
|
||||
ret_val = xmalloc (size1 + size2 + 1);
|
||||
strcpy (ret_val, s1);
|
||||
strcpy (&ret_val[size1], s2);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/* Take three strings and mash them together into a newly allocated area. */
|
||||
|
||||
static char *
|
||||
concat3 (s1, s2, s3)
|
||||
char *s1;
|
||||
char *s2;
|
||||
char *s3;
|
||||
{
|
||||
int size1, size2, size3;
|
||||
char *ret_val;
|
||||
|
||||
if (!s1)
|
||||
s1 = "";
|
||||
if (!s2)
|
||||
s2 = "";
|
||||
if (!s3)
|
||||
s3 = "";
|
||||
|
||||
size1 = strlen (s1);
|
||||
size2 = strlen (s2);
|
||||
size3 = strlen (s3);
|
||||
ret_val = xmalloc (size1 + size2 + size3 + 1);
|
||||
strcpy (ret_val, s1);
|
||||
strcpy (&ret_val[size1], s2);
|
||||
strcpy (&ret_val[size1+size2], s3);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/* Given a string representing an entire type or an entire declaration
|
||||
which only lacks the actual "data-type" specifier (at its left end),
|
||||
affix the data-type specifier to the left end of the given type
|
||||
specification or object declaration.
|
||||
|
||||
Because of C language weirdness, the data-type specifier (which normally
|
||||
goes in at the very left end) may have to be slipped in just to the
|
||||
right of any leading "const" or "volatile" qualifiers (there may be more
|
||||
than one). Actually this may not be strictly necessary because it seems
|
||||
that GCC (at least) accepts `<data-type> const foo;' and treats it the
|
||||
same as `const <data-type> foo;' but people are accustomed to seeing
|
||||
`const char *foo;' and *not* `char const *foo;' so we try to create types
|
||||
that look as expected. */
|
||||
|
||||
static char *
|
||||
affix_data_type (type_or_decl)
|
||||
char *type_or_decl;
|
||||
{
|
||||
char *p = type_or_decl;
|
||||
char *qualifiers_then_data_type;
|
||||
char saved;
|
||||
|
||||
/* Skip as many leading const's or volatile's as there are. */
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (!strncmp (p, "volatile ", 9))
|
||||
{
|
||||
p += 9;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp (p, "const ", 6))
|
||||
{
|
||||
p += 6;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* p now points to the place where we can insert the data type. We have to
|
||||
add a blank after the data-type of course. */
|
||||
|
||||
if (p == type_or_decl)
|
||||
return concat3 (data_type, " ", type_or_decl);
|
||||
|
||||
saved = *p;
|
||||
*p = '\0';
|
||||
qualifiers_then_data_type = concat (type_or_decl, data_type);
|
||||
*p = saved;
|
||||
return concat3 (qualifiers_then_data_type, " ", p);
|
||||
}
|
||||
|
||||
/* Given a tree node which represents some "function type", generate the
|
||||
source code version of a formal parameter list (of some given style) for
|
||||
this function type. Return the whole formal parameter list (including
|
||||
a pair of surrounding parens) as a string. Note that if the style
|
||||
we are currently aiming for is non-ansi, then we just return a pair
|
||||
of empty parens here. */
|
||||
|
||||
static char *
|
||||
gen_formal_list_for_type (fntype, style)
|
||||
tree fntype;
|
||||
formals_style style;
|
||||
{
|
||||
char *formal_list = "";
|
||||
tree formal_type;
|
||||
|
||||
if (style != ansi)
|
||||
return "()";
|
||||
|
||||
formal_type = TYPE_ARG_TYPES (fntype);
|
||||
while (formal_type && TREE_VALUE (formal_type) != void_type_node)
|
||||
{
|
||||
char *this_type;
|
||||
|
||||
if (*formal_list)
|
||||
formal_list = concat (formal_list, ", ");
|
||||
|
||||
this_type = gen_type ("", TREE_VALUE (formal_type), ansi);
|
||||
formal_list
|
||||
= ((strlen (this_type))
|
||||
? concat (formal_list, affix_data_type (this_type))
|
||||
: concat (formal_list, data_type));
|
||||
|
||||
formal_type = TREE_CHAIN (formal_type);
|
||||
}
|
||||
|
||||
/* If we got to here, then we are trying to generate an ANSI style formal
|
||||
parameters list.
|
||||
|
||||
New style prototyped ANSI formal parameter lists should in theory always
|
||||
contain some stuff between the opening and closing parens, even if it is
|
||||
only "void".
|
||||
|
||||
The brutal truth though is that there is lots of old K&R code out there
|
||||
which contains declarations of "pointer-to-function" parameters and
|
||||
these almost never have fully specified formal parameter lists associated
|
||||
with them. That is, the pointer-to-function parameters are declared
|
||||
with just empty parameter lists.
|
||||
|
||||
In cases such as these, protoize should really insert *something* into
|
||||
the vacant parameter lists, but what? It has no basis on which to insert
|
||||
anything in particular.
|
||||
|
||||
Here, we make life easy for protoize by trying to distinguish between
|
||||
K&R empty parameter lists and new-style prototyped parameter lists
|
||||
that actually contain "void". In the latter case we (obviously) want
|
||||
to output the "void" verbatim, and that what we do. In the former case,
|
||||
we do our best to give protoize something nice to insert.
|
||||
|
||||
This "something nice" should be something that is still valid (when
|
||||
re-compiled) but something that can clearly indicate to the user that
|
||||
more typing information (for the parameter list) should be added (by
|
||||
hand) at some convenient moment.
|
||||
|
||||
The string chosen here is a comment with question marks in it. */
|
||||
|
||||
if (!*formal_list)
|
||||
{
|
||||
if (TYPE_ARG_TYPES (fntype))
|
||||
/* assert (TREE_VALUE (TYPE_ARG_TYPES (fntype)) == void_type_node); */
|
||||
formal_list = "void";
|
||||
else
|
||||
formal_list = "/* ??? */";
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If there were at least some parameters, and if the formals-types-list
|
||||
petered out to a NULL (i.e. without being terminated by a
|
||||
void_type_node) then we need to tack on an ellipsis. */
|
||||
if (!formal_type)
|
||||
formal_list = concat (formal_list, ", ...");
|
||||
}
|
||||
|
||||
return concat3 (" (", formal_list, ")");
|
||||
}
|
||||
|
||||
/* For the generation of an ANSI prototype for a function definition, we have
|
||||
to look at the formal parameter list of the function's own "type" to
|
||||
determine if the function's formal parameter list should end with an
|
||||
ellipsis. Given a tree node, the following function will return non-zero
|
||||
if the "function type" parameter list should end with an ellipsis. */
|
||||
|
||||
static int
|
||||
deserves_ellipsis (fntype)
|
||||
tree fntype;
|
||||
{
|
||||
tree formal_type;
|
||||
|
||||
formal_type = TYPE_ARG_TYPES (fntype);
|
||||
while (formal_type && TREE_VALUE (formal_type) != void_type_node)
|
||||
formal_type = TREE_CHAIN (formal_type);
|
||||
|
||||
/* If there were at least some parameters, and if the formals-types-list
|
||||
petered out to a NULL (i.e. without being terminated by a void_type_node)
|
||||
then we need to tack on an ellipsis. */
|
||||
|
||||
return (!formal_type && TYPE_ARG_TYPES (fntype));
|
||||
}
|
||||
|
||||
/* Generate a parameter list for a function definition (in some given style).
|
||||
|
||||
Note that this routine has to be separate (and different) from the code that
|
||||
generates the prototype parameter lists for function declarations, because
|
||||
in the case of a function declaration, all we have to go on is a tree node
|
||||
representing the function's own "function type". This can tell us the types
|
||||
of all of the formal parameters for the function, but it cannot tell us the
|
||||
actual *names* of each of the formal parameters. We need to output those
|
||||
parameter names for each function definition.
|
||||
|
||||
This routine gets a pointer to a tree node which represents the actual
|
||||
declaration of the given function, and this DECL node has a list of formal
|
||||
parameter (variable) declarations attached to it. These formal parameter
|
||||
(variable) declaration nodes give us the actual names of the formal
|
||||
parameters for the given function definition.
|
||||
|
||||
This routine returns a string which is the source form for the entire
|
||||
function formal parameter list. */
|
||||
|
||||
static char *
|
||||
gen_formal_list_for_func_def (fndecl, style)
|
||||
tree fndecl;
|
||||
formals_style style;
|
||||
{
|
||||
char *formal_list = "";
|
||||
tree formal_decl;
|
||||
|
||||
formal_decl = DECL_ARGUMENTS (fndecl);
|
||||
while (formal_decl)
|
||||
{
|
||||
char *this_formal;
|
||||
|
||||
if (*formal_list && ((style == ansi) || (style == k_and_r_names)))
|
||||
formal_list = concat (formal_list, ", ");
|
||||
this_formal = gen_decl (formal_decl, 0, style);
|
||||
if (style == k_and_r_decls)
|
||||
formal_list = concat3 (formal_list, this_formal, "; ");
|
||||
else
|
||||
formal_list = concat (formal_list, this_formal);
|
||||
formal_decl = TREE_CHAIN (formal_decl);
|
||||
}
|
||||
if (style == ansi)
|
||||
{
|
||||
if (!DECL_ARGUMENTS (fndecl))
|
||||
formal_list = concat (formal_list, "void");
|
||||
if (deserves_ellipsis (TREE_TYPE (fndecl)))
|
||||
formal_list = concat (formal_list, ", ...");
|
||||
}
|
||||
if ((style == ansi) || (style == k_and_r_names))
|
||||
formal_list = concat3 (" (", formal_list, ")");
|
||||
return formal_list;
|
||||
}
|
||||
|
||||
/* Generate a string which is the source code form for a given type (t). This
|
||||
routine is ugly and complex because the C syntax for declarations is ugly
|
||||
and complex. This routine is straightforward so long as *no* pointer types,
|
||||
array types, or function types are involved.
|
||||
|
||||
In the simple cases, this routine will return the (string) value which was
|
||||
passed in as the "ret_val" argument. Usually, this starts out either as an
|
||||
empty string, or as the name of the declared item (i.e. the formal function
|
||||
parameter variable).
|
||||
|
||||
This routine will also return with the global variable "data_type" set to
|
||||
some string value which is the "basic" data-type of the given complete type.
|
||||
This "data_type" string can be concatenated onto the front of the returned
|
||||
string after this routine returns to its caller.
|
||||
|
||||
In complicated cases involving pointer types, array types, or function
|
||||
types, the C declaration syntax requires an "inside out" approach, i.e. if
|
||||
you have a type which is a "pointer-to-function" type, you need to handle
|
||||
the "pointer" part first, but it also has to be "innermost" (relative to
|
||||
the declaration stuff for the "function" type). Thus, is this case, you
|
||||
must prepend a "(*" and append a ")" to the name of the item (i.e. formal
|
||||
variable). Then you must append and prepend the other info for the
|
||||
"function type" part of the overall type.
|
||||
|
||||
To handle the "innermost precedence" rules of complicated C declarators, we
|
||||
do the following (in this routine). The input parameter called "ret_val"
|
||||
is treated as a "seed". Each time gen_type is called (perhaps recursively)
|
||||
some additional strings may be appended or prepended (or both) to the "seed"
|
||||
string. If yet another (lower) level of the GCC tree exists for the given
|
||||
type (as in the case of a pointer type, an array type, or a function type)
|
||||
then the (wrapped) seed is passed to a (recursive) invocation of gen_type()
|
||||
this recursive invocation may again "wrap" the (new) seed with yet more
|
||||
declarator stuff, by appending, prepending (or both). By the time the
|
||||
recursion bottoms out, the "seed value" at that point will have a value
|
||||
which is (almost) the complete source version of the declarator (except
|
||||
for the data_type info). Thus, this deepest "seed" value is simply passed
|
||||
back up through all of the recursive calls until it is given (as the return
|
||||
value) to the initial caller of the gen_type() routine. All that remains
|
||||
to do at this point is for the initial caller to prepend the "data_type"
|
||||
string onto the returned "seed". */
|
||||
|
||||
static char *
|
||||
gen_type (ret_val, t, style)
|
||||
char *ret_val;
|
||||
tree t;
|
||||
formals_style style;
|
||||
{
|
||||
tree chain_p;
|
||||
|
||||
if (TYPE_NAME (t) && DECL_NAME (TYPE_NAME (t)))
|
||||
data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)));
|
||||
else
|
||||
{
|
||||
switch (TREE_CODE (t))
|
||||
{
|
||||
case POINTER_TYPE:
|
||||
if (TYPE_READONLY (t))
|
||||
ret_val = concat ("const ", ret_val);
|
||||
if (TYPE_VOLATILE (t))
|
||||
ret_val = concat ("volatile ", ret_val);
|
||||
|
||||
ret_val = concat ("*", ret_val);
|
||||
|
||||
if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
|
||||
ret_val = concat3 ("(", ret_val, ")");
|
||||
|
||||
ret_val = gen_type (ret_val, TREE_TYPE (t), style);
|
||||
|
||||
return ret_val;
|
||||
|
||||
case ARRAY_TYPE:
|
||||
if (TYPE_SIZE (t) == 0 || TREE_CODE (TYPE_SIZE (t)) != INTEGER_CST)
|
||||
ret_val = gen_type (concat (ret_val, "[]"), TREE_TYPE (t), style);
|
||||
else if (int_size_in_bytes (t) == 0)
|
||||
ret_val = gen_type (concat (ret_val, "[0]"), TREE_TYPE (t), style);
|
||||
else
|
||||
{
|
||||
int size = (int_size_in_bytes (t) / int_size_in_bytes (TREE_TYPE (t)));
|
||||
char buff[10];
|
||||
sprintf (buff, "[%d]", size);
|
||||
ret_val = gen_type (concat (ret_val, buff),
|
||||
TREE_TYPE (t), style);
|
||||
}
|
||||
break;
|
||||
|
||||
case FUNCTION_TYPE:
|
||||
ret_val = gen_type (concat (ret_val, gen_formal_list_for_type (t, style)), TREE_TYPE (t), style);
|
||||
break;
|
||||
|
||||
case IDENTIFIER_NODE:
|
||||
data_type = IDENTIFIER_POINTER (t);
|
||||
break;
|
||||
|
||||
/* The following three cases are complicated by the fact that a
|
||||
user may do something really stupid, like creating a brand new
|
||||
"anonymous" type specification in a formal argument list (or as
|
||||
part of a function return type specification). For example:
|
||||
|
||||
int f (enum { red, green, blue } color);
|
||||
|
||||
In such cases, we have no name that we can put into the prototype
|
||||
to represent the (anonymous) type. Thus, we have to generate the
|
||||
whole darn type specification. Yuck! */
|
||||
|
||||
case RECORD_TYPE:
|
||||
if (TYPE_NAME (t))
|
||||
data_type = IDENTIFIER_POINTER (TYPE_NAME (t));
|
||||
else
|
||||
{
|
||||
data_type = "";
|
||||
chain_p = TYPE_FIELDS (t);
|
||||
while (chain_p)
|
||||
{
|
||||
data_type = concat (data_type, gen_decl (chain_p, 0, ansi));
|
||||
chain_p = TREE_CHAIN (chain_p);
|
||||
data_type = concat (data_type, "; ");
|
||||
}
|
||||
data_type = concat3 ("{ ", data_type, "}");
|
||||
}
|
||||
data_type = concat ("struct ", data_type);
|
||||
break;
|
||||
|
||||
case UNION_TYPE:
|
||||
if (TYPE_NAME (t))
|
||||
data_type = IDENTIFIER_POINTER (TYPE_NAME (t));
|
||||
else
|
||||
{
|
||||
data_type = "";
|
||||
chain_p = TYPE_FIELDS (t);
|
||||
while (chain_p)
|
||||
{
|
||||
data_type = concat (data_type, gen_decl (chain_p, 0, ansi));
|
||||
chain_p = TREE_CHAIN (chain_p);
|
||||
data_type = concat (data_type, "; ");
|
||||
}
|
||||
data_type = concat3 ("{ ", data_type, "}");
|
||||
}
|
||||
data_type = concat ("union ", data_type);
|
||||
break;
|
||||
|
||||
case ENUMERAL_TYPE:
|
||||
if (TYPE_NAME (t))
|
||||
data_type = IDENTIFIER_POINTER (TYPE_NAME (t));
|
||||
else
|
||||
{
|
||||
data_type = "";
|
||||
chain_p = TYPE_VALUES (t);
|
||||
while (chain_p)
|
||||
{
|
||||
data_type = concat (data_type,
|
||||
IDENTIFIER_POINTER (TREE_PURPOSE (chain_p)));
|
||||
chain_p = TREE_CHAIN (chain_p);
|
||||
if (chain_p)
|
||||
data_type = concat (data_type, ", ");
|
||||
}
|
||||
data_type = concat3 ("{ ", data_type, " }");
|
||||
}
|
||||
data_type = concat ("enum ", data_type);
|
||||
break;
|
||||
|
||||
case TYPE_DECL:
|
||||
data_type = IDENTIFIER_POINTER (DECL_NAME (t));
|
||||
break;
|
||||
|
||||
case INTEGER_TYPE:
|
||||
data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)));
|
||||
/* Normally, `unsigned' is part of the deal. Not so if it comes
|
||||
with `const' or `volatile'. */
|
||||
if (TREE_UNSIGNED (t) && (TYPE_READONLY (t) || TYPE_VOLATILE (t)))
|
||||
data_type = concat ("unsigned ", data_type);
|
||||
break;
|
||||
|
||||
case REAL_TYPE:
|
||||
data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)));
|
||||
break;
|
||||
|
||||
case VOID_TYPE:
|
||||
data_type = "void";
|
||||
break;
|
||||
|
||||
case ERROR_MARK:
|
||||
data_type = "[ERROR]";
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
if (TYPE_READONLY (t))
|
||||
ret_val = concat ("const ", ret_val);
|
||||
if (TYPE_VOLATILE (t))
|
||||
ret_val = concat ("volatile ", ret_val);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/* Generate a string (source) representation of an entire entity declaration
|
||||
(using some particular style for function types).
|
||||
|
||||
The given entity may be either a variable or a function.
|
||||
|
||||
If the "is_func_definition" parameter is non-zero, assume that the thing
|
||||
we are generating a declaration for is a FUNCTION_DECL node which is
|
||||
associated with a function definition. In this case, we can assume that
|
||||
an attached list of DECL nodes for function formal arguments is present. */
|
||||
|
||||
static char *
|
||||
gen_decl (decl, is_func_definition, style)
|
||||
tree decl;
|
||||
int is_func_definition;
|
||||
formals_style style;
|
||||
{
|
||||
char *ret_val;
|
||||
|
||||
if (DECL_NAME (decl))
|
||||
ret_val = IDENTIFIER_POINTER (DECL_NAME (decl));
|
||||
else
|
||||
ret_val = "";
|
||||
|
||||
/* If we are just generating a list of names of formal parameters, we can
|
||||
simply return the formal parameter name (with no typing information
|
||||
attached to it) now. */
|
||||
|
||||
if (style == k_and_r_names)
|
||||
return ret_val;
|
||||
|
||||
/* Note that for the declaration of some entity (either a function or a
|
||||
data object, like for instance a parameter) if the entity itself was
|
||||
declared as either const or volatile, then const and volatile properties
|
||||
are associated with just the declaration of the entity, and *not* with
|
||||
the `type' of the entity. Thus, for such declared entities, we have to
|
||||
generate the qualifiers here. */
|
||||
|
||||
if (TREE_THIS_VOLATILE (decl))
|
||||
ret_val = concat ("volatile ", ret_val);
|
||||
if (TREE_READONLY (decl))
|
||||
ret_val = concat ("const ", ret_val);
|
||||
|
||||
data_type = "";
|
||||
|
||||
/* For FUNCTION_DECL nodes, there are two possible cases here. First, if
|
||||
this FUNCTION_DECL node was generated from a function "definition", then
|
||||
we will have a list of DECL_NODE's, one for each of the function's formal
|
||||
parameters. In this case, we can print out not only the types of each
|
||||
formal, but also each formal's name. In the second case, this
|
||||
FUNCTION_DECL node came from an actual function declaration (and *not*
|
||||
a definition). In this case, we do nothing here because the formal
|
||||
argument type-list will be output later, when the "type" of the function
|
||||
is added to the string we are building. Note that the ANSI-style formal
|
||||
parameter list is considered to be a (suffix) part of the "type" of the
|
||||
function. */
|
||||
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL && is_func_definition)
|
||||
{
|
||||
ret_val = concat (ret_val, gen_formal_list_for_func_def (decl, ansi));
|
||||
|
||||
/* Since we have already added in the formals list stuff, here we don't
|
||||
add the whole "type" of the function we are considering (which
|
||||
would include its parameter-list info), rather, we only add in
|
||||
the "type" of the "type" of the function, which is really just
|
||||
the return-type of the function (and does not include the parameter
|
||||
list info). */
|
||||
|
||||
ret_val = gen_type (ret_val, TREE_TYPE (TREE_TYPE (decl)), style);
|
||||
}
|
||||
else
|
||||
ret_val = gen_type (ret_val, TREE_TYPE (decl), style);
|
||||
|
||||
ret_val = affix_data_type (ret_val);
|
||||
|
||||
if (TREE_CODE (decl) != FUNCTION_DECL && DECL_REGISTER (decl))
|
||||
ret_val = concat ("register ", ret_val);
|
||||
if (TREE_PUBLIC (decl))
|
||||
ret_val = concat ("extern ", ret_val);
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL && !TREE_PUBLIC (decl))
|
||||
ret_val = concat ("static ", ret_val);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
extern FILE *aux_info_file;
|
||||
|
||||
/* Generate and write a new line of info to the aux-info (.X) file. This
|
||||
routine is called once for each function declaration, and once for each
|
||||
function definition (even the implicit ones). */
|
||||
|
||||
void
|
||||
gen_aux_info_record (fndecl, is_definition, is_implicit, is_prototyped)
|
||||
tree fndecl;
|
||||
int is_definition;
|
||||
int is_implicit;
|
||||
int is_prototyped;
|
||||
{
|
||||
if (flag_gen_aux_info)
|
||||
{
|
||||
static int compiled_from_record = 0;
|
||||
|
||||
/* Each output .X file must have a header line. Write one now if we
|
||||
have not yet done so. */
|
||||
|
||||
if (! compiled_from_record++)
|
||||
{
|
||||
/* The first line tells which directory file names are relative to.
|
||||
Currently, -aux-info works only for files in the working
|
||||
directory, so just use a `.' as a placeholder for now. */
|
||||
fprintf (aux_info_file, "/* compiled from: . */\n");
|
||||
}
|
||||
|
||||
/* Write the actual line of auxiliary info. */
|
||||
|
||||
fprintf (aux_info_file, "/* %s:%d:%c%c */ %s;",
|
||||
DECL_SOURCE_FILE (fndecl),
|
||||
DECL_SOURCE_LINE (fndecl),
|
||||
(is_implicit) ? 'I' : (is_prototyped) ? 'N' : 'O',
|
||||
(is_definition) ? 'F' : 'C',
|
||||
gen_decl (fndecl, is_definition, ansi));
|
||||
|
||||
/* If this is an explicit function declaration, we need to also write
|
||||
out an old-style (i.e. K&R) function header, just in case the user
|
||||
wants to run unprotoize. */
|
||||
|
||||
if (is_definition)
|
||||
{
|
||||
fprintf (aux_info_file, " /*%s %s*/",
|
||||
gen_formal_list_for_func_def (fndecl, k_and_r_names),
|
||||
gen_formal_list_for_func_def (fndecl, k_and_r_decls));
|
||||
}
|
||||
|
||||
fprintf (aux_info_file, "\n");
|
||||
}
|
||||
}
|
2633
c-common.c
Normal file
2633
c-common.c
Normal file
File diff suppressed because it is too large
Load Diff
96
c-convert.c
Normal file
96
c-convert.c
Normal file
@ -0,0 +1,96 @@
|
||||
/* Language-level data type conversion for GNU C.
|
||||
Copyright (C) 1987, 1988, 1991 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
/* This file contains the functions for converting C expressions
|
||||
to different data types. The only entry point is `convert'.
|
||||
Every language front end must have a `convert' function
|
||||
but what kind of conversions it does will depend on the language. */
|
||||
|
||||
#include "config.h"
|
||||
#include "tree.h"
|
||||
#include "flags.h"
|
||||
#include "convert.h"
|
||||
|
||||
/* Change of width--truncation and extension of integers or reals--
|
||||
is represented with NOP_EXPR. Proper functioning of many things
|
||||
assumes that no other conversions can be NOP_EXPRs.
|
||||
|
||||
Conversion between integer and pointer is represented with CONVERT_EXPR.
|
||||
Converting integer to real uses FLOAT_EXPR
|
||||
and real to integer uses FIX_TRUNC_EXPR.
|
||||
|
||||
Here is a list of all the functions that assume that widening and
|
||||
narrowing is always done with a NOP_EXPR:
|
||||
In convert.c, convert_to_integer.
|
||||
In c-typeck.c, build_binary_op (boolean ops), and truthvalue_conversion.
|
||||
In expr.c: expand_expr, for operands of a MULT_EXPR.
|
||||
In fold-const.c: fold.
|
||||
In tree.c: get_narrower and get_unwidened. */
|
||||
|
||||
/* Subroutines of `convert'. */
|
||||
|
||||
|
||||
|
||||
/* Create an expression whose value is that of EXPR,
|
||||
converted to type TYPE. The TREE_TYPE of the value
|
||||
is always TYPE. This function implements all reasonable
|
||||
conversions; callers should filter out those that are
|
||||
not permitted by the language being compiled. */
|
||||
|
||||
tree
|
||||
convert (type, expr)
|
||||
tree type, expr;
|
||||
{
|
||||
register tree e = expr;
|
||||
register enum tree_code code = TREE_CODE (type);
|
||||
|
||||
if (type == TREE_TYPE (expr)
|
||||
|| TREE_CODE (expr) == ERROR_MARK)
|
||||
return expr;
|
||||
if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
|
||||
return fold (build1 (NOP_EXPR, type, expr));
|
||||
if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
|
||||
return error_mark_node;
|
||||
if (TREE_CODE (TREE_TYPE (expr)) == VOID_TYPE)
|
||||
{
|
||||
error ("void value not ignored as it ought to be");
|
||||
return error_mark_node;
|
||||
}
|
||||
if (code == VOID_TYPE)
|
||||
return build1 (CONVERT_EXPR, type, e);
|
||||
#if 0
|
||||
/* This is incorrect. A truncation can't be stripped this way.
|
||||
Extensions will be stripped by the use of get_unwidened. */
|
||||
if (TREE_CODE (expr) == NOP_EXPR)
|
||||
return convert (type, TREE_OPERAND (expr, 0));
|
||||
#endif
|
||||
if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
|
||||
return fold (convert_to_integer (type, e));
|
||||
if (code == POINTER_TYPE)
|
||||
return fold (convert_to_pointer (type, e));
|
||||
if (code == REAL_TYPE)
|
||||
return fold (convert_to_real (type, e));
|
||||
if (code == COMPLEX_TYPE)
|
||||
return fold (convert_to_complex (type, e));
|
||||
|
||||
error ("conversion to non-scalar type requested");
|
||||
return error_mark_node;
|
||||
}
|
186
c-gperf.h
Normal file
186
c-gperf.h
Normal file
@ -0,0 +1,186 @@
|
||||
/* C code produced by gperf version 2.5 (GNU C++ version) */
|
||||
/* Command-line: gperf -p -j1 -i 1 -g -o -t -G -N is_reserved_word -k1,3,$ ./c-parse.gperf */
|
||||
/* Command-line: gperf -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ c-parse.gperf */
|
||||
struct resword { char *name; short token; enum rid rid; };
|
||||
|
||||
#define TOTAL_KEYWORDS 79
|
||||
#define MIN_WORD_LENGTH 2
|
||||
#define MAX_WORD_LENGTH 20
|
||||
#define MIN_HASH_VALUE 10
|
||||
#define MAX_HASH_VALUE 144
|
||||
/* maximum key range = 135, duplicates = 0 */
|
||||
|
||||
#ifdef __GNUC__
|
||||
inline
|
||||
#endif
|
||||
static unsigned int
|
||||
hash (str, len)
|
||||
register char *str;
|
||||
register int unsigned len;
|
||||
{
|
||||
static unsigned char asso_values[] =
|
||||
{
|
||||
145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
|
||||
145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
|
||||
145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
|
||||
145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
|
||||
145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
|
||||
145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
|
||||
145, 145, 145, 145, 25, 145, 145, 145, 145, 145,
|
||||
145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
|
||||
145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
|
||||
145, 145, 145, 145, 145, 1, 145, 46, 8, 15,
|
||||
61, 6, 36, 48, 3, 5, 145, 18, 63, 25,
|
||||
29, 76, 1, 145, 13, 2, 1, 51, 37, 9,
|
||||
9, 1, 3, 145, 145, 145, 145, 145,
|
||||
};
|
||||
register int hval = len;
|
||||
|
||||
switch (hval)
|
||||
{
|
||||
default:
|
||||
case 3:
|
||||
hval += asso_values[str[2]];
|
||||
case 2:
|
||||
case 1:
|
||||
hval += asso_values[str[0]];
|
||||
break;
|
||||
}
|
||||
return hval + asso_values[str[len - 1]];
|
||||
}
|
||||
|
||||
static struct resword wordlist[] =
|
||||
{
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"",},
|
||||
{"int", TYPESPEC, RID_INT},
|
||||
{"",}, {"",},
|
||||
{"__typeof__", TYPEOF, NORID},
|
||||
{"__signed__", TYPESPEC, RID_SIGNED},
|
||||
{"__imag__", IMAGPART, NORID},
|
||||
{"switch", SWITCH, NORID},
|
||||
{"__inline__", SCSPEC, RID_INLINE},
|
||||
{"else", ELSE, NORID},
|
||||
{"__iterator__", SCSPEC, RID_ITERATOR},
|
||||
{"__inline", SCSPEC, RID_INLINE},
|
||||
{"__extension__", EXTENSION, NORID},
|
||||
{"struct", STRUCT, NORID},
|
||||
{"__real__", REALPART, NORID},
|
||||
{"__const", TYPE_QUAL, RID_CONST},
|
||||
{"while", WHILE, NORID},
|
||||
{"__const__", TYPE_QUAL, RID_CONST},
|
||||
{"case", CASE, NORID},
|
||||
{"__complex__", TYPESPEC, RID_COMPLEX},
|
||||
{"__iterator", SCSPEC, RID_ITERATOR},
|
||||
{"bycopy", TYPE_QUAL, RID_BYCOPY},
|
||||
{"",}, {"",}, {"",},
|
||||
{"__complex", TYPESPEC, RID_COMPLEX},
|
||||
{"",},
|
||||
{"in", TYPE_QUAL, RID_IN},
|
||||
{"break", BREAK, NORID},
|
||||
{"@defs", DEFS, NORID},
|
||||
{"",}, {"",}, {"",},
|
||||
{"extern", SCSPEC, RID_EXTERN},
|
||||
{"if", IF, NORID},
|
||||
{"typeof", TYPEOF, NORID},
|
||||
{"typedef", SCSPEC, RID_TYPEDEF},
|
||||
{"__typeof", TYPEOF, NORID},
|
||||
{"sizeof", SIZEOF, NORID},
|
||||
{"",},
|
||||
{"return", RETURN, NORID},
|
||||
{"const", TYPE_QUAL, RID_CONST},
|
||||
{"__volatile__", TYPE_QUAL, RID_VOLATILE},
|
||||
{"@private", PRIVATE, NORID},
|
||||
{"@selector", SELECTOR, NORID},
|
||||
{"__volatile", TYPE_QUAL, RID_VOLATILE},
|
||||
{"__asm__", ASM_KEYWORD, NORID},
|
||||
{"",}, {"",},
|
||||
{"continue", CONTINUE, NORID},
|
||||
{"__alignof__", ALIGNOF, NORID},
|
||||
{"__imag", IMAGPART, NORID},
|
||||
{"__attribute__", ATTRIBUTE, NORID},
|
||||
{"",}, {"",},
|
||||
{"__attribute", ATTRIBUTE, NORID},
|
||||
{"for", FOR, NORID},
|
||||
{"",},
|
||||
{"@encode", ENCODE, NORID},
|
||||
{"id", OBJECTNAME, RID_ID},
|
||||
{"static", SCSPEC, RID_STATIC},
|
||||
{"@interface", INTERFACE, NORID},
|
||||
{"",},
|
||||
{"__signed", TYPESPEC, RID_SIGNED},
|
||||
{"",},
|
||||
{"__label__", LABEL, NORID},
|
||||
{"",}, {"",},
|
||||
{"__asm", ASM_KEYWORD, NORID},
|
||||
{"char", TYPESPEC, RID_CHAR},
|
||||
{"",},
|
||||
{"inline", SCSPEC, RID_INLINE},
|
||||
{"out", TYPE_QUAL, RID_OUT},
|
||||
{"register", SCSPEC, RID_REGISTER},
|
||||
{"__real", REALPART, NORID},
|
||||
{"short", TYPESPEC, RID_SHORT},
|
||||
{"",},
|
||||
{"enum", ENUM, NORID},
|
||||
{"inout", TYPE_QUAL, RID_INOUT},
|
||||
{"",},
|
||||
{"oneway", TYPE_QUAL, RID_ONEWAY},
|
||||
{"union", UNION, NORID},
|
||||
{"",},
|
||||
{"__alignof", ALIGNOF, NORID},
|
||||
{"",},
|
||||
{"@implementation", IMPLEMENTATION, NORID},
|
||||
{"",},
|
||||
{"@class", CLASS, NORID},
|
||||
{"",},
|
||||
{"@public", PUBLIC, NORID},
|
||||
{"asm", ASM_KEYWORD, NORID},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"default", DEFAULT, NORID},
|
||||
{"",},
|
||||
{"void", TYPESPEC, RID_VOID},
|
||||
{"",},
|
||||
{"@protected", PROTECTED, NORID},
|
||||
{"@protocol", PROTOCOL, NORID},
|
||||
{"",}, {"",}, {"",},
|
||||
{"volatile", TYPE_QUAL, RID_VOLATILE},
|
||||
{"",}, {"",},
|
||||
{"signed", TYPESPEC, RID_SIGNED},
|
||||
{"float", TYPESPEC, RID_FLOAT},
|
||||
{"@end", END, NORID},
|
||||
{"",}, {"",},
|
||||
{"unsigned", TYPESPEC, RID_UNSIGNED},
|
||||
{"@compatibility_alias", ALIAS, NORID},
|
||||
{"double", TYPESPEC, RID_DOUBLE},
|
||||
{"",}, {"",},
|
||||
{"auto", SCSPEC, RID_AUTO},
|
||||
{"",},
|
||||
{"goto", GOTO, NORID},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"do", DO, NORID},
|
||||
{"",}, {"",}, {"",}, {"",},
|
||||
{"long", TYPESPEC, RID_LONG},
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
inline
|
||||
#endif
|
||||
struct resword *
|
||||
is_reserved_word (str, len)
|
||||
register char *str;
|
||||
register unsigned int len;
|
||||
{
|
||||
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
|
||||
{
|
||||
register int key = hash (str, len);
|
||||
|
||||
if (key <= MAX_HASH_VALUE && key >= 0)
|
||||
{
|
||||
register char *s = wordlist[key].name;
|
||||
|
||||
if (*s == *str && !strcmp (str + 1, s + 1))
|
||||
return &wordlist[key];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
601
c-iterate.c
Normal file
601
c-iterate.c
Normal file
@ -0,0 +1,601 @@
|
||||
/* Build expressions with type checking for C compiler.
|
||||
Copyright (C) 1987, 88, 89, 92, 93, 96, 1997 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
/* This file is part of the C front end.
|
||||
It is responsible for implementing iterators,
|
||||
both their declarations and the expansion of statements using them. */
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include "tree.h"
|
||||
#include "c-tree.h"
|
||||
#include "flags.h"
|
||||
#include "obstack.h"
|
||||
#include "rtl.h"
|
||||
|
||||
/*
|
||||
KEEPING TRACK OF EXPANSIONS
|
||||
|
||||
In order to clean out expansions corresponding to statements inside
|
||||
"{(...)}" constructs we have to keep track of all expansions. The
|
||||
cleanup is needed when an automatic, or implicit, expansion on
|
||||
iterator, say X, happens to a statement which contains a {(...)}
|
||||
form with a statement already expanded on X. In this case we have
|
||||
to go back and cleanup the inner expansion. This can be further
|
||||
complicated by the fact that {(...)} can be nested.
|
||||
|
||||
To make this cleanup possible, we keep lists of all expansions, and
|
||||
to make it work for nested constructs, we keep a stack. The list at
|
||||
the top of the stack (ITER_STACK.CURRENT_LEVEL) corresponds to the
|
||||
currently parsed level. All expansions of the levels below the
|
||||
current one are kept in one list whose head is pointed to by
|
||||
ITER_STACK.SUBLEVEL_FIRST (SUBLEVEL_LAST is there for making merges
|
||||
easy). The process works as follows:
|
||||
|
||||
-- On "({" a new node is added to the stack by PUSH_ITERATOR_STACK.
|
||||
The sublevel list is not changed at this point.
|
||||
|
||||
-- On "})" the list for the current level is appended to the sublevel
|
||||
list.
|
||||
|
||||
-- On ";" sublevel lists are appended to the current level lists.
|
||||
The reason is this: if they have not been superseded by the
|
||||
expansion at the current level, they still might be
|
||||
superseded later by the expansion on the higher level.
|
||||
The levels do not have to distinguish levels below, so we
|
||||
can merge the lists together. */
|
||||
|
||||
struct ixpansion
|
||||
{
|
||||
tree ixdecl; /* Iterator decl */
|
||||
rtx ixprologue_start; /* First insn of epilogue. NULL means */
|
||||
/* explicit (FOR) expansion*/
|
||||
rtx ixprologue_end;
|
||||
rtx ixepilogue_start;
|
||||
rtx ixepilogue_end;
|
||||
struct ixpansion *next; /* Next in the list */
|
||||
};
|
||||
|
||||
struct iter_stack_node
|
||||
{
|
||||
struct ixpansion *first; /* Head of list of ixpansions */
|
||||
struct ixpansion *last; /* Last node in list of ixpansions */
|
||||
struct iter_stack_node *next; /* Next level iterator stack node */
|
||||
};
|
||||
|
||||
struct iter_stack_node *iter_stack;
|
||||
struct iter_stack_node sublevel_ixpansions;
|
||||
|
||||
/* A special obstack, and a pointer to the start of
|
||||
all the data in it (so we can free everything easily). */
|
||||
static struct obstack ixp_obstack;
|
||||
static char *ixp_firstobj;
|
||||
|
||||
/* During collect_iterators, a list of SAVE_EXPRs already scanned. */
|
||||
static tree save_exprs;
|
||||
|
||||
static void expand_stmt_with_iterators_1 PROTO((tree, tree));
|
||||
static tree collect_iterators PROTO((tree, tree));
|
||||
static void iterator_loop_prologue PROTO((tree, rtx *, rtx *));
|
||||
static void iterator_loop_epilogue PROTO((tree, rtx *, rtx *));
|
||||
static int top_level_ixpansion_p PROTO((void));
|
||||
static void isn_append PROTO((struct iter_stack_node *,
|
||||
struct iter_stack_node *));
|
||||
static void istack_sublevel_to_current PROTO((void));
|
||||
static void add_ixpansion PROTO((tree, rtx, rtx, rtx, rtx));
|
||||
static void delete_ixpansion PROTO((tree));
|
||||
|
||||
/* Initialize our obstack once per compilation. */
|
||||
|
||||
void
|
||||
init_iterators ()
|
||||
{
|
||||
gcc_obstack_init (&ixp_obstack);
|
||||
ixp_firstobj = (char *) obstack_alloc (&ixp_obstack, 0);
|
||||
}
|
||||
|
||||
/* Handle the start of an explicit `for' loop for iterator IDECL. */
|
||||
|
||||
void
|
||||
iterator_for_loop_start (idecl)
|
||||
tree idecl;
|
||||
{
|
||||
ITERATOR_BOUND_P (idecl) = 1;
|
||||
add_ixpansion (idecl, 0, 0, 0, 0);
|
||||
iterator_loop_prologue (idecl, 0, 0);
|
||||
}
|
||||
|
||||
/* Handle the end of an explicit `for' loop for iterator IDECL. */
|
||||
|
||||
void
|
||||
iterator_for_loop_end (idecl)
|
||||
tree idecl;
|
||||
{
|
||||
iterator_loop_epilogue (idecl, 0, 0);
|
||||
ITERATOR_BOUND_P (idecl) = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
ITERATOR RTL EXPANSIONS
|
||||
|
||||
Expanding simple statements with iterators is straightforward:
|
||||
collect the list of all free iterators in the statement, and
|
||||
generate a loop for each of them.
|
||||
|
||||
An iterator is "free" if it has not been "bound" by a FOR
|
||||
operator. The DECL_RTL of the iterator is the loop counter. */
|
||||
|
||||
/* Expand a statement STMT, possibly containing iterator usage, into RTL. */
|
||||
|
||||
void
|
||||
iterator_expand (stmt)
|
||||
tree stmt;
|
||||
{
|
||||
tree iter_list;
|
||||
save_exprs = NULL_TREE;
|
||||
iter_list = collect_iterators (stmt, NULL_TREE);
|
||||
expand_stmt_with_iterators_1 (stmt, iter_list);
|
||||
istack_sublevel_to_current ();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
expand_stmt_with_iterators_1 (stmt, iter_list)
|
||||
tree stmt, iter_list;
|
||||
{
|
||||
if (iter_list == 0)
|
||||
expand_expr_stmt (stmt);
|
||||
else
|
||||
{
|
||||
tree current_iterator = TREE_VALUE (iter_list);
|
||||
tree iter_list_tail = TREE_CHAIN (iter_list);
|
||||
rtx p_start, p_end, e_start, e_end;
|
||||
|
||||
iterator_loop_prologue (current_iterator, &p_start, &p_end);
|
||||
expand_stmt_with_iterators_1 (stmt, iter_list_tail);
|
||||
iterator_loop_epilogue (current_iterator, &e_start, &e_end);
|
||||
|
||||
/** Delete all inner expansions based on current_iterator **/
|
||||
/** before adding the outer one. **/
|
||||
|
||||
delete_ixpansion (current_iterator);
|
||||
add_ixpansion (current_iterator, p_start, p_end, e_start, e_end);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Return a list containing all the free (i.e. not bound by a
|
||||
containing `for' statement) iterators mentioned in EXP, plus those
|
||||
in LIST. Do not add duplicate entries to the list. */
|
||||
|
||||
static tree
|
||||
collect_iterators (exp, list)
|
||||
tree exp, list;
|
||||
{
|
||||
if (exp == 0) return list;
|
||||
|
||||
switch (TREE_CODE (exp))
|
||||
{
|
||||
case VAR_DECL:
|
||||
if (! ITERATOR_P (exp) || ITERATOR_BOUND_P (exp))
|
||||
return list;
|
||||
if (value_member (exp, list))
|
||||
return list;
|
||||
return tree_cons (NULL_TREE, exp, list);
|
||||
|
||||
case TREE_LIST:
|
||||
{
|
||||
tree tail;
|
||||
for (tail = exp; tail; tail = TREE_CHAIN (tail))
|
||||
list = collect_iterators (TREE_VALUE (tail), list);
|
||||
return list;
|
||||
}
|
||||
|
||||
case SAVE_EXPR:
|
||||
/* In each scan, scan a given save_expr only once. */
|
||||
if (value_member (exp, save_exprs))
|
||||
return list;
|
||||
|
||||
save_exprs = tree_cons (NULL_TREE, exp, save_exprs);
|
||||
return collect_iterators (TREE_OPERAND (exp, 0), list);
|
||||
|
||||
/* we do not automatically iterate blocks -- one must */
|
||||
/* use the FOR construct to do that */
|
||||
|
||||
case BLOCK:
|
||||
return list;
|
||||
|
||||
default:
|
||||
switch (TREE_CODE_CLASS (TREE_CODE (exp)))
|
||||
{
|
||||
case '1':
|
||||
return collect_iterators (TREE_OPERAND (exp, 0), list);
|
||||
|
||||
case '2':
|
||||
case '<':
|
||||
return collect_iterators (TREE_OPERAND (exp, 0),
|
||||
collect_iterators (TREE_OPERAND (exp, 1),
|
||||
list));
|
||||
|
||||
case 'e':
|
||||
case 'r':
|
||||
{
|
||||
int num_args = tree_code_length[(int) TREE_CODE (exp)];
|
||||
int i;
|
||||
|
||||
/* Some tree codes have RTL, not trees, as operands. */
|
||||
switch (TREE_CODE (exp))
|
||||
{
|
||||
case CALL_EXPR:
|
||||
num_args = 2;
|
||||
break;
|
||||
case METHOD_CALL_EXPR:
|
||||
num_args = 3;
|
||||
break;
|
||||
case WITH_CLEANUP_EXPR:
|
||||
num_args = 1;
|
||||
break;
|
||||
case RTL_EXPR:
|
||||
return list;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_args; i++)
|
||||
list = collect_iterators (TREE_OPERAND (exp, i), list);
|
||||
return list;
|
||||
}
|
||||
default:
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Emit rtl for the start of a loop for iterator IDECL.
|
||||
|
||||
If necessary, create loop counter rtx and store it as DECL_RTL of IDECL.
|
||||
|
||||
The prologue normally starts and ends with notes, which are returned
|
||||
by this function in *START_NOTE and *END_NODE.
|
||||
If START_NOTE and END_NODE are 0, we don't make those notes. */
|
||||
|
||||
static void
|
||||
iterator_loop_prologue (idecl, start_note, end_note)
|
||||
tree idecl;
|
||||
rtx *start_note, *end_note;
|
||||
{
|
||||
tree expr;
|
||||
|
||||
/* Force the save_expr in DECL_INITIAL to be calculated
|
||||
if it hasn't been calculated yet. */
|
||||
expand_expr (DECL_INITIAL (idecl), const0_rtx, VOIDmode, 0);
|
||||
|
||||
if (DECL_RTL (idecl) == 0)
|
||||
expand_decl (idecl);
|
||||
|
||||
if (start_note)
|
||||
*start_note = emit_note (0, NOTE_INSN_DELETED);
|
||||
|
||||
/* Initialize counter. */
|
||||
expr = build (MODIFY_EXPR, TREE_TYPE (idecl), idecl, integer_zero_node);
|
||||
TREE_SIDE_EFFECTS (expr) = 1;
|
||||
expand_expr (expr, const0_rtx, VOIDmode, 0);
|
||||
|
||||
expand_start_loop_continue_elsewhere (1);
|
||||
|
||||
ITERATOR_BOUND_P (idecl) = 1;
|
||||
|
||||
if (end_note)
|
||||
*end_note = emit_note (0, NOTE_INSN_DELETED);
|
||||
}
|
||||
|
||||
/* Similar to the previous function, but for the end of the loop.
|
||||
|
||||
DECL_RTL is zeroed unless we are inside "({...})". The reason for that is
|
||||
described below.
|
||||
|
||||
When we create two (or more) loops based on the same IDECL, and
|
||||
both inside the same "({...})" construct, we must be prepared to
|
||||
delete both of the loops and create a single one on the level
|
||||
above, i.e. enclosing the "({...})". The new loop has to use the
|
||||
same counter rtl because the references to the iterator decl
|
||||
(IDECL) have already been expanded as references to the counter
|
||||
rtl.
|
||||
|
||||
It is incorrect to use the same counter reg in different functions,
|
||||
and it is desirable to use different counters in disjoint loops
|
||||
when we know there's no need to combine them (because then they can
|
||||
get allocated separately). */
|
||||
|
||||
static void
|
||||
iterator_loop_epilogue (idecl, start_note, end_note)
|
||||
tree idecl;
|
||||
rtx *start_note, *end_note;
|
||||
{
|
||||
tree test, incr;
|
||||
|
||||
if (start_note)
|
||||
*start_note = emit_note (0, NOTE_INSN_DELETED);
|
||||
expand_loop_continue_here ();
|
||||
incr = build_binary_op (PLUS_EXPR, idecl, integer_one_node, 0);
|
||||
incr = build (MODIFY_EXPR, TREE_TYPE (idecl), idecl, incr);
|
||||
TREE_SIDE_EFFECTS (incr) = 1;
|
||||
expand_expr (incr, const0_rtx, VOIDmode, 0);
|
||||
test = build_binary_op (LT_EXPR, idecl, DECL_INITIAL (idecl), 0);
|
||||
expand_exit_loop_if_false (0, test);
|
||||
expand_end_loop ();
|
||||
|
||||
ITERATOR_BOUND_P (idecl) = 0;
|
||||
/* we can reset rtl since there is not chance that this expansion */
|
||||
/* would be superseded by a higher level one */
|
||||
/* but don't do this if the decl is static, since we need to share */
|
||||
/* the same decl in that case. */
|
||||
if (top_level_ixpansion_p () && ! TREE_STATIC (idecl))
|
||||
DECL_RTL (idecl) = 0;
|
||||
if (end_note)
|
||||
*end_note = emit_note (0, NOTE_INSN_DELETED);
|
||||
}
|
||||
|
||||
/* Return true if we are not currently inside a "({...})" construct. */
|
||||
|
||||
static int
|
||||
top_level_ixpansion_p ()
|
||||
{
|
||||
return iter_stack == 0;
|
||||
}
|
||||
|
||||
/* Given two chains of iter_stack_nodes,
|
||||
append the nodes in X into Y. */
|
||||
|
||||
static void
|
||||
isn_append (x, y)
|
||||
struct iter_stack_node *x, *y;
|
||||
{
|
||||
if (x->first == 0)
|
||||
return;
|
||||
|
||||
if (y->first == 0)
|
||||
{
|
||||
y->first = x->first;
|
||||
y->last = x->last;
|
||||
}
|
||||
else
|
||||
{
|
||||
y->last->next = x->first;
|
||||
y->last = x->last;
|
||||
}
|
||||
}
|
||||
|
||||
/** Make X empty **/
|
||||
|
||||
#define ISN_ZERO(X) (X).first=(X).last=0
|
||||
|
||||
/* Move the ixpansions in sublevel_ixpansions into the current
|
||||
node on the iter_stack, or discard them if the iter_stack is empty.
|
||||
We do this at the end of a statement. */
|
||||
|
||||
static void
|
||||
istack_sublevel_to_current ()
|
||||
{
|
||||
/* At the top level we can throw away sublevel's expansions **/
|
||||
/* because there is nobody above us to ask for a cleanup **/
|
||||
if (iter_stack != 0)
|
||||
/** Merging with empty sublevel list is a no-op **/
|
||||
if (sublevel_ixpansions.last)
|
||||
isn_append (&sublevel_ixpansions, iter_stack);
|
||||
|
||||
if (iter_stack == 0)
|
||||
obstack_free (&ixp_obstack, ixp_firstobj);
|
||||
|
||||
ISN_ZERO (sublevel_ixpansions);
|
||||
}
|
||||
|
||||
/* Push a new node on the iter_stack, when we enter a ({...}). */
|
||||
|
||||
void
|
||||
push_iterator_stack ()
|
||||
{
|
||||
struct iter_stack_node *new_top
|
||||
= (struct iter_stack_node *)
|
||||
obstack_alloc (&ixp_obstack, sizeof (struct iter_stack_node));
|
||||
|
||||
new_top->first = 0;
|
||||
new_top->last = 0;
|
||||
new_top->next = iter_stack;
|
||||
iter_stack = new_top;
|
||||
}
|
||||
|
||||
/* Pop iter_stack, moving the ixpansions in the node being popped
|
||||
into sublevel_ixpansions. */
|
||||
|
||||
void
|
||||
pop_iterator_stack ()
|
||||
{
|
||||
if (iter_stack == 0)
|
||||
abort ();
|
||||
|
||||
isn_append (iter_stack, &sublevel_ixpansions);
|
||||
/** Pop current level node: */
|
||||
iter_stack = iter_stack->next;
|
||||
}
|
||||
|
||||
|
||||
/* Record an iterator expansion ("ixpansion") for IDECL.
|
||||
The remaining parameters are the notes in the loop entry
|
||||
and exit rtl. */
|
||||
|
||||
static void
|
||||
add_ixpansion (idecl, pro_start, pro_end, epi_start, epi_end)
|
||||
tree idecl;
|
||||
rtx pro_start, pro_end, epi_start, epi_end;
|
||||
{
|
||||
struct ixpansion *newix;
|
||||
|
||||
/* Do nothing if we are not inside "({...})",
|
||||
as in that case this expansion can't need subsequent RTL modification. */
|
||||
if (iter_stack == 0)
|
||||
return;
|
||||
|
||||
newix = (struct ixpansion *) obstack_alloc (&ixp_obstack,
|
||||
sizeof (struct ixpansion));
|
||||
newix->ixdecl = idecl;
|
||||
newix->ixprologue_start = pro_start;
|
||||
newix->ixprologue_end = pro_end;
|
||||
newix->ixepilogue_start = epi_start;
|
||||
newix->ixepilogue_end = epi_end;
|
||||
|
||||
newix->next = iter_stack->first;
|
||||
iter_stack->first = newix;
|
||||
if (iter_stack->last == 0)
|
||||
iter_stack->last = newix;
|
||||
}
|
||||
|
||||
/* Delete the RTL for all ixpansions for iterator IDECL
|
||||
in our sublevels. We do this when we make a larger
|
||||
containing expansion for IDECL. */
|
||||
|
||||
static void
|
||||
delete_ixpansion (idecl)
|
||||
tree idecl;
|
||||
{
|
||||
struct ixpansion *previx = 0, *ix;
|
||||
|
||||
for (ix = sublevel_ixpansions.first; ix; ix = ix->next)
|
||||
if (ix->ixdecl == idecl)
|
||||
{
|
||||
/** zero means that this is a mark for FOR -- **/
|
||||
/** we do not delete anything, just issue an error. **/
|
||||
|
||||
if (ix->ixprologue_start == 0)
|
||||
error_with_decl (idecl,
|
||||
"`for (%s)' appears within implicit iteration");
|
||||
else
|
||||
{
|
||||
rtx insn;
|
||||
/* We delete all insns, including notes because leaving loop */
|
||||
/* notes and barriers produced by iterator expansion would */
|
||||
/* be misleading to other phases */
|
||||
|
||||
for (insn = NEXT_INSN (ix->ixprologue_start);
|
||||
insn != ix->ixprologue_end;
|
||||
insn = NEXT_INSN (insn))
|
||||
delete_insn (insn);
|
||||
for (insn = NEXT_INSN (ix->ixepilogue_start);
|
||||
insn != ix->ixepilogue_end;
|
||||
insn = NEXT_INSN (insn))
|
||||
delete_insn (insn);
|
||||
}
|
||||
|
||||
/* Delete this ixpansion from sublevel_ixpansions. */
|
||||
if (previx)
|
||||
previx->next = ix->next;
|
||||
else
|
||||
sublevel_ixpansions.first = ix->next;
|
||||
if (sublevel_ixpansions.last == ix)
|
||||
sublevel_ixpansions.last = previx;
|
||||
}
|
||||
else
|
||||
previx = ix;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ITERATORS
|
||||
|
||||
/* The functions below are for use from source level debugger.
|
||||
They print short forms of iterator lists and the iterator stack. */
|
||||
|
||||
/* Print the name of the iterator D. */
|
||||
|
||||
void
|
||||
prdecl (d)
|
||||
tree d;
|
||||
{
|
||||
if (d)
|
||||
{
|
||||
if (TREE_CODE (d) == VAR_DECL)
|
||||
{
|
||||
tree tname = DECL_NAME (d);
|
||||
char *dname = IDENTIFIER_POINTER (tname);
|
||||
fprintf (stderr, dname);
|
||||
}
|
||||
else
|
||||
fprintf (stderr, "<<Not a Decl!!!>>");
|
||||
}
|
||||
else
|
||||
fprintf (stderr, "<<NULL!!>>");
|
||||
}
|
||||
|
||||
/* Print Iterator List -- names only */
|
||||
|
||||
tree
|
||||
pil (head)
|
||||
tree head;
|
||||
{
|
||||
tree current, next;
|
||||
for (current = head; current; current = next)
|
||||
{
|
||||
tree node = TREE_VALUE (current);
|
||||
prdecl (node);
|
||||
next = TREE_CHAIN (current);
|
||||
if (next) fprintf (stderr, ",");
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
/* Print IXpansion List */
|
||||
|
||||
struct ixpansion *
|
||||
pixl (head)
|
||||
struct ixpansion *head;
|
||||
{
|
||||
struct ixpansion *current, *next;
|
||||
fprintf (stderr, "> ");
|
||||
if (head == 0)
|
||||
fprintf (stderr, "(empty)");
|
||||
|
||||
for (current=head; current; current = next)
|
||||
{
|
||||
tree node = current->ixdecl;
|
||||
prdecl (node);
|
||||
next = current->next;
|
||||
if (next)
|
||||
fprintf (stderr, ",");
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
return head;
|
||||
}
|
||||
|
||||
/* Print Iterator Stack. */
|
||||
|
||||
void
|
||||
pis ()
|
||||
{
|
||||
struct iter_stack_node *stack_node;
|
||||
|
||||
fprintf (stderr, "--SubLevel: ");
|
||||
pixl (sublevel_ixpansions.first);
|
||||
fprintf (stderr, "--Stack:--\n");
|
||||
for (stack_node = iter_stack;
|
||||
stack_node;
|
||||
stack_node = stack_node->next)
|
||||
pixl (stack_node->first);
|
||||
}
|
||||
|
||||
#endif /* DEBUG_ITERATORS */
|
182
c-lang.c
Normal file
182
c-lang.c
Normal file
@ -0,0 +1,182 @@
|
||||
/* Language-specific hook definitions for C front end.
|
||||
Copyright (C) 1991, 1995, 1997 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include "tree.h"
|
||||
#include <stdio.h>
|
||||
#include "input.h"
|
||||
|
||||
/* Each of the functions defined here
|
||||
is an alternative to a function in objc-actions.c. */
|
||||
|
||||
int
|
||||
lang_decode_option (p)
|
||||
char *p;
|
||||
{
|
||||
return c_decode_option (p);
|
||||
}
|
||||
|
||||
void
|
||||
lang_init ()
|
||||
{
|
||||
#if !USE_CPPLIB
|
||||
/* the beginning of the file is a new line; check for # */
|
||||
/* With luck, we discover the real source file's name from that
|
||||
and put it in input_filename. */
|
||||
ungetc (check_newline (), finput);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
lang_finish ()
|
||||
{
|
||||
}
|
||||
|
||||
char *
|
||||
lang_identify ()
|
||||
{
|
||||
return "c";
|
||||
}
|
||||
|
||||
void
|
||||
print_lang_statistics ()
|
||||
{
|
||||
}
|
||||
|
||||
/* Used by c-lex.c, but only for objc. */
|
||||
|
||||
tree
|
||||
lookup_interface (arg)
|
||||
tree arg;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
tree
|
||||
is_class_name (arg)
|
||||
tree arg;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
maybe_objc_check_decl (decl)
|
||||
tree decl;
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
maybe_objc_comptypes (lhs, rhs, reflexive)
|
||||
tree lhs, rhs;
|
||||
int reflexive;
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
tree
|
||||
maybe_objc_method_name (decl)
|
||||
tree decl;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
tree
|
||||
maybe_building_objc_message_expr ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
recognize_objc_keyword ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
tree
|
||||
build_objc_string (len, str)
|
||||
int len;
|
||||
char *str;
|
||||
{
|
||||
abort ();
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
void
|
||||
GNU_xref_begin ()
|
||||
{
|
||||
fatal ("GCC does not yet support XREF");
|
||||
}
|
||||
|
||||
void
|
||||
GNU_xref_end ()
|
||||
{
|
||||
fatal ("GCC does not yet support XREF");
|
||||
}
|
||||
|
||||
/* Called at end of parsing, but before end-of-file processing. */
|
||||
|
||||
void
|
||||
finish_file ()
|
||||
{
|
||||
extern tree static_ctors, static_dtors;
|
||||
extern tree build_function_call PROTO((tree, tree));
|
||||
tree void_list_node = build_tree_list (NULL_TREE, void_type_node);
|
||||
#ifndef ASM_OUTPUT_CONSTRUCTOR
|
||||
if (static_ctors)
|
||||
{
|
||||
tree fnname = get_file_function_name ('I');
|
||||
start_function (void_list_node,
|
||||
build_parse_node (CALL_EXPR, fnname, void_list_node,
|
||||
NULL_TREE),
|
||||
NULL_TREE, NULL_TREE, 0);
|
||||
fnname = DECL_ASSEMBLER_NAME (current_function_decl);
|
||||
store_parm_decls ();
|
||||
|
||||
for (; static_ctors; static_ctors = TREE_CHAIN (static_ctors))
|
||||
expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors),
|
||||
NULL_TREE));
|
||||
|
||||
finish_function (0);
|
||||
|
||||
assemble_constructor (IDENTIFIER_POINTER (fnname));
|
||||
}
|
||||
#endif
|
||||
#ifndef ASM_OUTPUT_DESTRUCTOR
|
||||
if (static_dtors)
|
||||
{
|
||||
tree fnname = get_file_function_name ('D');
|
||||
start_function (void_list_node,
|
||||
build_parse_node (CALL_EXPR, fnname, void_list_node,
|
||||
NULL_TREE),
|
||||
NULL_TREE, NULL_TREE, 0);
|
||||
fnname = DECL_ASSEMBLER_NAME (current_function_decl);
|
||||
store_parm_decls ();
|
||||
|
||||
for (; static_dtors; static_dtors = TREE_CHAIN (static_dtors))
|
||||
expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors),
|
||||
NULL_TREE));
|
||||
|
||||
finish_function (0);
|
||||
|
||||
assemble_destructor (IDENTIFIER_POINTER (fnname));
|
||||
}
|
||||
#endif
|
||||
}
|
80
c-lex.h
Normal file
80
c-lex.h
Normal file
@ -0,0 +1,80 @@
|
||||
/* Define constants for communication with c-parse.y.
|
||||
Copyright (C) 1987, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
|
||||
enum rid
|
||||
{
|
||||
RID_UNUSED,
|
||||
RID_INT,
|
||||
RID_CHAR,
|
||||
RID_FLOAT,
|
||||
RID_DOUBLE,
|
||||
RID_VOID,
|
||||
RID_UNUSED1,
|
||||
|
||||
RID_UNSIGNED,
|
||||
RID_SHORT,
|
||||
RID_LONG,
|
||||
RID_AUTO,
|
||||
RID_STATIC,
|
||||
RID_EXTERN,
|
||||
RID_REGISTER,
|
||||
RID_TYPEDEF,
|
||||
RID_SIGNED,
|
||||
RID_CONST,
|
||||
RID_VOLATILE,
|
||||
RID_INLINE,
|
||||
RID_NOALIAS,
|
||||
RID_ITERATOR,
|
||||
RID_COMPLEX,
|
||||
|
||||
RID_IN,
|
||||
RID_OUT,
|
||||
RID_INOUT,
|
||||
RID_BYCOPY,
|
||||
RID_ONEWAY,
|
||||
RID_ID,
|
||||
|
||||
RID_MAX
|
||||
};
|
||||
|
||||
#define NORID RID_UNUSED
|
||||
|
||||
#define RID_FIRST_MODIFIER RID_UNSIGNED
|
||||
|
||||
/* The elements of `ridpointers' are identifier nodes
|
||||
for the reserved type names and storage classes.
|
||||
It is indexed by a RID_... value. */
|
||||
extern tree ridpointers[(int) RID_MAX];
|
||||
|
||||
/* the declaration found for the last IDENTIFIER token read in.
|
||||
yylex must look this up to detect typedefs, which get token type TYPENAME,
|
||||
so it is left around in case the identifier is not a typedef but is
|
||||
used in a context which makes it a reference to a variable. */
|
||||
extern tree lastiddecl;
|
||||
|
||||
extern char *token_buffer; /* Pointer to token buffer. */
|
||||
|
||||
extern tree make_pointer_declarator ();
|
||||
extern void reinit_parse_for_function ();
|
||||
extern int yylex ();
|
||||
|
||||
extern char *get_directive_line ();
|
84
c-parse.gperf
Normal file
84
c-parse.gperf
Normal file
@ -0,0 +1,84 @@
|
||||
%{
|
||||
/* Command-line: gperf -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ c-parse.gperf */
|
||||
%}
|
||||
struct resword { char *name; short token; enum rid rid; };
|
||||
%%
|
||||
@class, CLASS, NORID
|
||||
@compatibility_alias, ALIAS, NORID
|
||||
@defs, DEFS, NORID
|
||||
@encode, ENCODE, NORID
|
||||
@end, END, NORID
|
||||
@implementation, IMPLEMENTATION, NORID
|
||||
@interface, INTERFACE, NORID
|
||||
@private, PRIVATE, NORID
|
||||
@protected, PROTECTED, NORID
|
||||
@protocol, PROTOCOL, NORID
|
||||
@public, PUBLIC, NORID
|
||||
@selector, SELECTOR, NORID
|
||||
__alignof, ALIGNOF, NORID
|
||||
__alignof__, ALIGNOF, NORID
|
||||
__asm, ASM_KEYWORD, NORID
|
||||
__asm__, ASM_KEYWORD, NORID
|
||||
__attribute, ATTRIBUTE, NORID
|
||||
__attribute__, ATTRIBUTE, NORID
|
||||
__complex, TYPESPEC, RID_COMPLEX
|
||||
__complex__, TYPESPEC, RID_COMPLEX
|
||||
__const, TYPE_QUAL, RID_CONST
|
||||
__const__, TYPE_QUAL, RID_CONST
|
||||
__extension__, EXTENSION, NORID
|
||||
__imag, IMAGPART, NORID
|
||||
__imag__, IMAGPART, NORID
|
||||
__inline, SCSPEC, RID_INLINE
|
||||
__inline__, SCSPEC, RID_INLINE
|
||||
__iterator, SCSPEC, RID_ITERATOR
|
||||
__iterator__, SCSPEC, RID_ITERATOR
|
||||
__label__, LABEL, NORID
|
||||
__real, REALPART, NORID
|
||||
__real__, REALPART, NORID
|
||||
__signed, TYPESPEC, RID_SIGNED
|
||||
__signed__, TYPESPEC, RID_SIGNED
|
||||
__typeof, TYPEOF, NORID
|
||||
__typeof__, TYPEOF, NORID
|
||||
__volatile, TYPE_QUAL, RID_VOLATILE
|
||||
__volatile__, TYPE_QUAL, RID_VOLATILE
|
||||
asm, ASM_KEYWORD, NORID
|
||||
auto, SCSPEC, RID_AUTO
|
||||
break, BREAK, NORID
|
||||
bycopy, TYPE_QUAL, RID_BYCOPY
|
||||
case, CASE, NORID
|
||||
char, TYPESPEC, RID_CHAR
|
||||
const, TYPE_QUAL, RID_CONST
|
||||
continue, CONTINUE, NORID
|
||||
default, DEFAULT, NORID
|
||||
do, DO, NORID
|
||||
double, TYPESPEC, RID_DOUBLE
|
||||
else, ELSE, NORID
|
||||
enum, ENUM, NORID
|
||||
extern, SCSPEC, RID_EXTERN
|
||||
float, TYPESPEC, RID_FLOAT
|
||||
for, FOR, NORID
|
||||
goto, GOTO, NORID
|
||||
id, OBJECTNAME, RID_ID
|
||||
if, IF, NORID
|
||||
in, TYPE_QUAL, RID_IN
|
||||
inout, TYPE_QUAL, RID_INOUT
|
||||
inline, SCSPEC, RID_INLINE
|
||||
int, TYPESPEC, RID_INT
|
||||
long, TYPESPEC, RID_LONG
|
||||
oneway, TYPE_QUAL, RID_ONEWAY
|
||||
out, TYPE_QUAL, RID_OUT
|
||||
register, SCSPEC, RID_REGISTER
|
||||
return, RETURN, NORID
|
||||
short, TYPESPEC, RID_SHORT
|
||||
signed, TYPESPEC, RID_SIGNED
|
||||
sizeof, SIZEOF, NORID
|
||||
static, SCSPEC, RID_STATIC
|
||||
struct, STRUCT, NORID
|
||||
switch, SWITCH, NORID
|
||||
typedef, SCSPEC, RID_TYPEDEF
|
||||
typeof, TYPEOF, NORID
|
||||
union, UNION, NORID
|
||||
unsigned, TYPESPEC, RID_UNSIGNED
|
||||
void, TYPESPEC, RID_VOID
|
||||
volatile, TYPE_QUAL, RID_VOLATILE
|
||||
while, WHILE, NORID
|
64
c-parse.h
Normal file
64
c-parse.h
Normal file
@ -0,0 +1,64 @@
|
||||
typedef union {long itype; tree ttype; enum tree_code code;
|
||||
char *filename; int lineno; int ends_in_label; } YYSTYPE;
|
||||
#define IDENTIFIER 258
|
||||
#define TYPENAME 259
|
||||
#define SCSPEC 260
|
||||
#define TYPESPEC 261
|
||||
#define TYPE_QUAL 262
|
||||
#define CONSTANT 263
|
||||
#define STRING 264
|
||||
#define ELLIPSIS 265
|
||||
#define SIZEOF 266
|
||||
#define ENUM 267
|
||||
#define STRUCT 268
|
||||
#define UNION 269
|
||||
#define IF 270
|
||||
#define ELSE 271
|
||||
#define WHILE 272
|
||||
#define DO 273
|
||||
#define FOR 274
|
||||
#define SWITCH 275
|
||||
#define CASE 276
|
||||
#define DEFAULT 277
|
||||
#define BREAK 278
|
||||
#define CONTINUE 279
|
||||
#define RETURN 280
|
||||
#define GOTO 281
|
||||
#define ASM_KEYWORD 282
|
||||
#define TYPEOF 283
|
||||
#define ALIGNOF 284
|
||||
#define ATTRIBUTE 285
|
||||
#define EXTENSION 286
|
||||
#define LABEL 287
|
||||
#define REALPART 288
|
||||
#define IMAGPART 289
|
||||
#define ASSIGN 290
|
||||
#define OROR 291
|
||||
#define ANDAND 292
|
||||
#define EQCOMPARE 293
|
||||
#define ARITHCOMPARE 294
|
||||
#define LSHIFT 295
|
||||
#define RSHIFT 296
|
||||
#define UNARY 297
|
||||
#define PLUSPLUS 298
|
||||
#define MINUSMINUS 299
|
||||
#define HYPERUNARY 300
|
||||
#define POINTSAT 301
|
||||
#define INTERFACE 302
|
||||
#define IMPLEMENTATION 303
|
||||
#define END 304
|
||||
#define SELECTOR 305
|
||||
#define DEFS 306
|
||||
#define ENCODE 307
|
||||
#define CLASSNAME 308
|
||||
#define PUBLIC 309
|
||||
#define PRIVATE 310
|
||||
#define PROTECTED 311
|
||||
#define PROTOCOL 312
|
||||
#define OBJECTNAME 313
|
||||
#define CLASS 314
|
||||
#define ALIAS 315
|
||||
#define OBJC_STRING 316
|
||||
|
||||
|
||||
extern YYSTYPE yylval;
|
3024
c-parse.in
Normal file
3024
c-parse.in
Normal file
File diff suppressed because it is too large
Load Diff
169
c-pragma.c
Normal file
169
c-pragma.c
Normal file
@ -0,0 +1,169 @@
|
||||
/* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack.
|
||||
Copyright (C) 1992, 1997 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include "tree.h"
|
||||
#include "except.h"
|
||||
#include "function.h"
|
||||
#include "defaults.h"
|
||||
#include "c-pragma.h"
|
||||
|
||||
#ifdef HANDLE_SYSV_PRAGMA
|
||||
|
||||
/* When structure field packing is in effect, this variable is the
|
||||
number of bits to use as the maximum alignment. When packing is not
|
||||
in effect, this is zero. */
|
||||
|
||||
extern int maximum_field_alignment;
|
||||
|
||||
/* File used for outputting assembler code. */
|
||||
extern FILE *asm_out_file;
|
||||
|
||||
/* Handle one token of a pragma directive. TOKEN is the
|
||||
current token, and STRING is its printable form. */
|
||||
|
||||
void
|
||||
handle_pragma_token (string, token)
|
||||
char *string;
|
||||
tree token;
|
||||
{
|
||||
static enum pragma_state state = ps_start, type;
|
||||
static char *name;
|
||||
static char *value;
|
||||
static int align;
|
||||
|
||||
if (string == 0)
|
||||
{
|
||||
if (type == ps_pack)
|
||||
{
|
||||
if (state == ps_right)
|
||||
maximum_field_alignment = align * 8;
|
||||
else
|
||||
warning ("malformed `#pragma pack'");
|
||||
}
|
||||
else if (type == ps_weak)
|
||||
{
|
||||
#ifdef HANDLE_PRAGMA_WEAK
|
||||
if (HANDLE_PRAGMA_WEAK)
|
||||
handle_pragma_weak (state, name, value);
|
||||
|
||||
#endif /* HANDLE_PRAGMA_WEAK */
|
||||
}
|
||||
|
||||
type = state = ps_start;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case ps_start:
|
||||
if (token && TREE_CODE (token) == IDENTIFIER_NODE)
|
||||
{
|
||||
if (strcmp (IDENTIFIER_POINTER (token), "pack") == 0)
|
||||
type = state = ps_pack;
|
||||
else if (strcmp (IDENTIFIER_POINTER (token), "weak") == 0)
|
||||
type = state = ps_weak;
|
||||
else
|
||||
type = state = ps_done;
|
||||
}
|
||||
else
|
||||
type = state = ps_done;
|
||||
break;
|
||||
|
||||
case ps_weak:
|
||||
if (token && TREE_CODE (token) == IDENTIFIER_NODE)
|
||||
{
|
||||
name = IDENTIFIER_POINTER (token);
|
||||
state = ps_name;
|
||||
}
|
||||
else
|
||||
state = ps_bad;
|
||||
break;
|
||||
|
||||
case ps_name:
|
||||
state = (strcmp (string, "=") ? ps_bad : ps_equals);
|
||||
break;
|
||||
|
||||
case ps_equals:
|
||||
if (token && TREE_CODE (token) == IDENTIFIER_NODE)
|
||||
{
|
||||
value = IDENTIFIER_POINTER (token);
|
||||
state = ps_value;
|
||||
}
|
||||
else
|
||||
state = ps_bad;
|
||||
break;
|
||||
|
||||
case ps_value:
|
||||
state = ps_bad;
|
||||
break;
|
||||
|
||||
case ps_pack:
|
||||
if (strcmp (string, "(") == 0)
|
||||
state = ps_left;
|
||||
else
|
||||
state = ps_bad;
|
||||
break;
|
||||
|
||||
case ps_left:
|
||||
if (token && TREE_CODE (token) == INTEGER_CST
|
||||
&& TREE_INT_CST_HIGH (token) == 0)
|
||||
switch (TREE_INT_CST_LOW (token))
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
align = TREE_INT_CST_LOW (token);
|
||||
state = ps_align;
|
||||
break;
|
||||
|
||||
default:
|
||||
state = ps_bad;
|
||||
}
|
||||
else if (! token && strcmp (string, ")") == 0)
|
||||
{
|
||||
align = 0;
|
||||
state = ps_right;
|
||||
}
|
||||
else
|
||||
state = ps_bad;
|
||||
break;
|
||||
|
||||
case ps_align:
|
||||
if (strcmp (string, ")") == 0)
|
||||
state = ps_right;
|
||||
else
|
||||
state = ps_bad;
|
||||
break;
|
||||
|
||||
case ps_right:
|
||||
state = ps_bad;
|
||||
break;
|
||||
|
||||
case ps_bad:
|
||||
case ps_done:
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
#endif /* HANDLE_SYSV_PRAGMA */
|
46
c-pragma.h
Normal file
46
c-pragma.h
Normal file
@ -0,0 +1,46 @@
|
||||
/* Pragma related interfaces.
|
||||
Copyright (C) 1995 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Support #pragma weak iff ASM_WEAKEN_LABEL and ASM_OUTPUT_DEF are
|
||||
defined. */
|
||||
#if defined (ASM_WEAKEN_LABEL) && defined (ASM_OUTPUT_DEF)
|
||||
#define HANDLE_PRAGMA_WEAK SUPPORTS_WEAK
|
||||
#endif
|
||||
|
||||
enum pragma_state
|
||||
{
|
||||
ps_start,
|
||||
ps_done,
|
||||
ps_bad,
|
||||
ps_weak,
|
||||
ps_name,
|
||||
ps_equals,
|
||||
ps_value,
|
||||
ps_pack,
|
||||
ps_left,
|
||||
ps_align,
|
||||
ps_right
|
||||
};
|
||||
|
||||
/* Output asm to handle ``#pragma weak'' */
|
||||
extern void handle_pragma_weak PROTO((enum pragma_state, char *, char *));
|
||||
|
||||
/* Handle a C style pragma */
|
||||
extern void handle_pragma_token PROTO((char *, tree));
|
507
c-tree.h
Normal file
507
c-tree.h
Normal file
@ -0,0 +1,507 @@
|
||||
/* Definitions for C parsing and type checking.
|
||||
Copyright (C) 1987, 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _C_TREE_H
|
||||
#define _C_TREE_H
|
||||
|
||||
/* Language-dependent contents of an identifier. */
|
||||
|
||||
/* The limbo_value is used for block level extern declarations, which need
|
||||
to be type checked against subsequent extern declarations. They can't
|
||||
be referenced after they fall out of scope, so they can't be global. */
|
||||
|
||||
struct lang_identifier
|
||||
{
|
||||
struct tree_identifier ignore;
|
||||
tree global_value, local_value, label_value, implicit_decl;
|
||||
tree error_locus, limbo_value;
|
||||
};
|
||||
|
||||
/* Macros for access to language-specific slots in an identifier. */
|
||||
/* Each of these slots contains a DECL node or null. */
|
||||
|
||||
/* This represents the value which the identifier has in the
|
||||
file-scope namespace. */
|
||||
#define IDENTIFIER_GLOBAL_VALUE(NODE) \
|
||||
(((struct lang_identifier *) (NODE))->global_value)
|
||||
/* This represents the value which the identifier has in the current
|
||||
scope. */
|
||||
#define IDENTIFIER_LOCAL_VALUE(NODE) \
|
||||
(((struct lang_identifier *) (NODE))->local_value)
|
||||
/* This represents the value which the identifier has as a label in
|
||||
the current label scope. */
|
||||
#define IDENTIFIER_LABEL_VALUE(NODE) \
|
||||
(((struct lang_identifier *) (NODE))->label_value)
|
||||
/* This records the extern decl of this identifier, if it has had one
|
||||
at any point in this compilation. */
|
||||
#define IDENTIFIER_LIMBO_VALUE(NODE) \
|
||||
(((struct lang_identifier *) (NODE))->limbo_value)
|
||||
/* This records the implicit function decl of this identifier, if it
|
||||
has had one at any point in this compilation. */
|
||||
#define IDENTIFIER_IMPLICIT_DECL(NODE) \
|
||||
(((struct lang_identifier *) (NODE))->implicit_decl)
|
||||
/* This is the last function in which we printed an "undefined variable"
|
||||
message for this identifier. Value is a FUNCTION_DECL or null. */
|
||||
#define IDENTIFIER_ERROR_LOCUS(NODE) \
|
||||
(((struct lang_identifier *) (NODE))->error_locus)
|
||||
|
||||
/* In identifiers, C uses the following fields in a special way:
|
||||
TREE_PUBLIC to record that there was a previous local extern decl.
|
||||
TREE_USED to record that such a decl was used.
|
||||
TREE_ADDRESSABLE to record that the address of such a decl was used. */
|
||||
|
||||
/* Nonzero means reject anything that ANSI standard C forbids. */
|
||||
extern int pedantic;
|
||||
|
||||
/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is read-only. */
|
||||
#define C_TYPE_FIELDS_READONLY(type) TREE_LANG_FLAG_1 (type)
|
||||
|
||||
/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is volatile. */
|
||||
#define C_TYPE_FIELDS_VOLATILE(type) TREE_LANG_FLAG_2 (type)
|
||||
|
||||
/* In a RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE
|
||||
nonzero if the definition of the type has already started. */
|
||||
#define C_TYPE_BEING_DEFINED(type) TYPE_LANG_FLAG_0 (type)
|
||||
|
||||
/* In a RECORD_TYPE, a sorted array of the fields of the type. */
|
||||
struct lang_type
|
||||
{
|
||||
int len;
|
||||
tree elts[1];
|
||||
};
|
||||
|
||||
/* Mark which labels are explicitly declared.
|
||||
These may be shadowed, and may be referenced from nested functions. */
|
||||
#define C_DECLARED_LABEL_FLAG(label) TREE_LANG_FLAG_1 (label)
|
||||
|
||||
/* Record whether a type or decl was written with nonconstant size.
|
||||
Note that TYPE_SIZE may have simplified to a constant. */
|
||||
#define C_TYPE_VARIABLE_SIZE(type) TYPE_LANG_FLAG_1 (type)
|
||||
#define C_DECL_VARIABLE_SIZE(type) DECL_LANG_FLAG_0 (type)
|
||||
|
||||
/* Record in each node resulting from a binary operator
|
||||
what operator was specified for it. */
|
||||
#define C_EXP_ORIGINAL_CODE(exp) ((enum tree_code) TREE_COMPLEXITY (exp))
|
||||
|
||||
#if 0 /* Not used. */
|
||||
/* Record whether a decl for a function or function pointer has
|
||||
already been mentioned (in a warning) because it was called
|
||||
but didn't have a prototype. */
|
||||
#define C_MISSING_PROTOTYPE_WARNED(decl) DECL_LANG_FLAG_2(decl)
|
||||
#endif
|
||||
|
||||
/* Store a value in that field. */
|
||||
#define C_SET_EXP_ORIGINAL_CODE(exp, code) \
|
||||
(TREE_COMPLEXITY (exp) = (int) (code))
|
||||
|
||||
/* Record whether a typedef for type `int' was actually `signed int'. */
|
||||
#define C_TYPEDEF_EXPLICITLY_SIGNED(exp) DECL_LANG_FLAG_1 ((exp))
|
||||
|
||||
/* Nonzero for a declaration of a built in function if there has been no
|
||||
occasion that would declare the function in ordinary C.
|
||||
Using the function draws a pedantic warning in this case. */
|
||||
#define C_DECL_ANTICIPATED(exp) DECL_LANG_FLAG_3 ((exp))
|
||||
|
||||
/* For FUNCTION_TYPE, a hidden list of types of arguments. The same as
|
||||
TYPE_ARG_TYPES for functions with prototypes, but created for functions
|
||||
without prototypes. */
|
||||
#define TYPE_ACTUAL_ARG_TYPES(NODE) TYPE_NONCOPIED_PARTS (NODE)
|
||||
|
||||
/* In a FIELD_DECL, nonzero if the decl was originally a bitfield. */
|
||||
#define DECL_C_BIT_FIELD(NODE) DECL_LANG_FLAG_4 (NODE)
|
||||
|
||||
/* Nonzero if the type T promotes to itself.
|
||||
ANSI C states explicitly the list of types that promote;
|
||||
in particular, short promotes to int even if they have the same width. */
|
||||
#define C_PROMOTING_INTEGER_TYPE_P(t) \
|
||||
(TREE_CODE ((t)) == INTEGER_TYPE \
|
||||
&& (TYPE_MAIN_VARIANT (t) == char_type_node \
|
||||
|| TYPE_MAIN_VARIANT (t) == signed_char_type_node \
|
||||
|| TYPE_MAIN_VARIANT (t) == unsigned_char_type_node \
|
||||
|| TYPE_MAIN_VARIANT (t) == short_integer_type_node \
|
||||
|| TYPE_MAIN_VARIANT (t) == short_unsigned_type_node))
|
||||
|
||||
/* In a VAR_DECL, means the variable is really an iterator. */
|
||||
#define ITERATOR_P(D) (DECL_LANG_FLAG_4(D))
|
||||
|
||||
/* In a VAR_DECL for an iterator, means we are within
|
||||
an explicit loop over that iterator. */
|
||||
#define ITERATOR_BOUND_P(NODE) ((NODE)->common.readonly_flag)
|
||||
|
||||
/* in c-lang.c and objc-act.c */
|
||||
extern tree lookup_interface PROTO((tree));
|
||||
extern tree is_class_name PROTO((tree));
|
||||
extern void maybe_objc_check_decl PROTO((tree));
|
||||
extern int maybe_objc_comptypes PROTO((tree, tree, int));
|
||||
extern tree maybe_building_objc_message_expr PROTO((void));
|
||||
extern tree maybe_objc_method_name PROTO((tree));
|
||||
extern int recognize_objc_keyword PROTO((void));
|
||||
extern tree build_objc_string PROTO((int, char *));
|
||||
|
||||
/* in c-aux-info.c */
|
||||
extern void gen_aux_info_record PROTO((tree, int, int, int));
|
||||
|
||||
/* in c-common.c */
|
||||
extern void declare_function_name PROTO((void));
|
||||
extern void decl_attributes PROTO((tree, tree, tree));
|
||||
extern void init_function_format_info PROTO((void));
|
||||
extern void record_function_format PROTO((tree, tree, int, int, int));
|
||||
extern void check_function_format PROTO((tree, tree, tree));
|
||||
/* Print an error message for invalid operands to arith operation CODE.
|
||||
NOP_EXPR is used as a special case (see truthvalue_conversion). */
|
||||
extern void binary_op_error PROTO((enum tree_code));
|
||||
extern void c_expand_expr_stmt PROTO((tree));
|
||||
/* Validate the expression after `case' and apply default promotions. */
|
||||
extern tree check_case_value PROTO((tree));
|
||||
/* Concatenate a list of STRING_CST nodes into one STRING_CST. */
|
||||
extern tree combine_strings PROTO((tree));
|
||||
extern void constant_expression_warning PROTO((tree));
|
||||
extern tree convert_and_check PROTO((tree, tree));
|
||||
extern void overflow_warning PROTO((tree));
|
||||
extern void unsigned_conversion_warning PROTO((tree, tree));
|
||||
/* Read the rest of the current #-directive line. */
|
||||
extern char *get_directive_line PROTO((FILE *));
|
||||
/* Subroutine of build_binary_op, used for comparison operations.
|
||||
See if the operands have both been converted from subword integer types
|
||||
and, if so, perhaps change them both back to their original type. */
|
||||
extern tree shorten_compare PROTO((tree *, tree *, tree *, enum tree_code *));
|
||||
/* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
|
||||
or validate its data type for an `if' or `while' statement or ?..: exp. */
|
||||
extern tree truthvalue_conversion PROTO((tree));
|
||||
extern tree type_for_mode PROTO((enum machine_mode, int));
|
||||
extern tree type_for_size PROTO((unsigned, int));
|
||||
|
||||
/* in c-convert.c */
|
||||
extern tree convert PROTO((tree, tree));
|
||||
|
||||
/* in c-decl.c */
|
||||
/* Standard named or nameless data types of the C compiler. */
|
||||
extern tree char_array_type_node;
|
||||
extern tree char_type_node;
|
||||
extern tree const_ptr_type_node;
|
||||
extern tree const_string_type_node;
|
||||
extern tree default_function_type;
|
||||
extern tree double_ftype_double;
|
||||
extern tree double_ftype_double_double;
|
||||
extern tree double_type_node;
|
||||
extern tree float_type_node;
|
||||
extern tree intDI_type_node;
|
||||
extern tree intHI_type_node;
|
||||
extern tree intQI_type_node;
|
||||
extern tree intSI_type_node;
|
||||
extern tree int_array_type_node;
|
||||
extern tree int_ftype_cptr_cptr_sizet;
|
||||
extern tree int_ftype_int;
|
||||
extern tree int_ftype_ptr_ptr_int;
|
||||
extern tree int_ftype_string_string;
|
||||
extern tree integer_type_node;
|
||||
extern tree long_double_type_node;
|
||||
extern tree long_ftype_long;
|
||||
extern tree long_integer_type_node;
|
||||
extern tree long_long_integer_type_node;
|
||||
extern tree long_long_unsigned_type_node;
|
||||
extern tree long_unsigned_type_node;
|
||||
extern tree complex_integer_type_node;
|
||||
extern tree complex_float_type_node;
|
||||
extern tree complex_double_type_node;
|
||||
extern tree complex_long_double_type_node;
|
||||
extern tree ptr_type_node;
|
||||
extern tree ptrdiff_type_node;
|
||||
extern tree short_integer_type_node;
|
||||
extern tree short_unsigned_type_node;
|
||||
extern tree signed_char_type_node;
|
||||
extern tree signed_wchar_type_node;
|
||||
extern tree string_ftype_ptr_ptr;
|
||||
extern tree string_type_node;
|
||||
extern tree unsigned_char_type_node;
|
||||
extern tree unsigned_intDI_type_node;
|
||||
extern tree unsigned_intHI_type_node;
|
||||
extern tree unsigned_intQI_type_node;
|
||||
extern tree unsigned_intSI_type_node;
|
||||
extern tree unsigned_type_node;
|
||||
extern tree unsigned_wchar_type_node;
|
||||
extern tree void_ftype_ptr_int_int;
|
||||
extern tree void_ftype_ptr_ptr_int;
|
||||
extern tree void_type_node;
|
||||
extern tree wchar_array_type_node;
|
||||
extern tree wchar_type_node;
|
||||
extern tree boolean_type_node;
|
||||
extern tree boolean_true_node;
|
||||
extern tree boolean_false_node;
|
||||
|
||||
extern tree build_enumerator PROTO((tree, tree));
|
||||
/* Declare a predefined function. Return the declaration. */
|
||||
extern tree builtin_function PROTO((char *, tree, enum built_in_function function_, char *));
|
||||
/* Add qualifiers to a type, in the fashion for C. */
|
||||
extern tree c_build_type_variant PROTO((tree, int, int));
|
||||
extern int c_decode_option PROTO((char *));
|
||||
extern void c_mark_varargs PROTO((void));
|
||||
extern tree check_identifier PROTO((tree, tree));
|
||||
extern void clear_parm_order PROTO((void));
|
||||
extern tree combine_parm_decls PROTO((tree, tree, int));
|
||||
extern int complete_array_type PROTO((tree, tree, int));
|
||||
extern void declare_parm_level PROTO((int));
|
||||
extern tree define_label PROTO((char *, int, tree));
|
||||
extern void delete_block PROTO((tree));
|
||||
extern void finish_decl PROTO((tree, tree, tree));
|
||||
extern void finish_decl_top_level PROTO((tree, tree, tree));
|
||||
extern tree finish_enum PROTO((tree, tree, tree));
|
||||
extern void finish_function PROTO((int));
|
||||
extern tree finish_struct PROTO((tree, tree, tree));
|
||||
extern tree get_parm_info PROTO((int));
|
||||
extern tree getdecls PROTO((void));
|
||||
extern tree gettags PROTO((void));
|
||||
extern int global_bindings_p PROTO((void));
|
||||
extern tree grokfield PROTO((char *, int, tree, tree, tree));
|
||||
extern tree groktypename PROTO((tree));
|
||||
extern tree groktypename_in_parm_context PROTO((tree));
|
||||
extern tree implicitly_declare PROTO((tree));
|
||||
extern int in_parm_level_p PROTO((void));
|
||||
extern void init_decl_processing PROTO((void));
|
||||
extern void insert_block PROTO((tree));
|
||||
extern void keep_next_level PROTO((void));
|
||||
extern int kept_level_p PROTO((void));
|
||||
extern tree lookup_label PROTO((tree));
|
||||
extern tree lookup_name PROTO((tree));
|
||||
extern tree lookup_name_current_level PROTO((tree));
|
||||
extern tree lookup_name_current_level_global PROTO((tree));
|
||||
extern tree maybe_build_cleanup PROTO((tree));
|
||||
extern void parmlist_tags_warning PROTO((void));
|
||||
extern void pending_xref_error PROTO((void));
|
||||
extern void pop_c_function_context PROTO((void));
|
||||
extern void pop_label_level PROTO((void));
|
||||
extern tree poplevel PROTO((int, int, int));
|
||||
extern void print_lang_decl PROTO((FILE *, tree, int));
|
||||
extern void print_lang_identifier PROTO((FILE *, tree, int));
|
||||
extern void print_lang_type PROTO((FILE *, tree, int));
|
||||
extern void push_c_function_context PROTO((void));
|
||||
extern void push_label_level PROTO((void));
|
||||
extern void push_parm_decl PROTO((tree));
|
||||
extern tree pushdecl PROTO((tree));
|
||||
extern tree pushdecl_top_level PROTO((tree));
|
||||
extern void pushlevel PROTO((int));
|
||||
extern void pushtag PROTO((tree, tree));
|
||||
extern void set_block PROTO((tree));
|
||||
extern tree shadow_label PROTO((tree));
|
||||
extern void shadow_record_fields PROTO((tree));
|
||||
extern void shadow_tag PROTO((tree));
|
||||
extern void shadow_tag_warned PROTO((tree, int));
|
||||
extern tree start_enum PROTO((tree));
|
||||
extern int start_function PROTO((tree, tree, tree,
|
||||
tree, int));
|
||||
extern tree start_decl PROTO((tree, tree, int,
|
||||
tree, tree));
|
||||
extern tree start_struct PROTO((enum tree_code, tree));
|
||||
extern void store_parm_decls PROTO((void));
|
||||
extern tree xref_tag PROTO((enum tree_code, tree));
|
||||
|
||||
/* in c-typeck.c */
|
||||
extern tree require_complete_type PROTO((tree));
|
||||
extern void incomplete_type_error PROTO((tree, tree));
|
||||
/* Given two integer or real types, return the type for their sum.
|
||||
Given two compatible ANSI C types, returns the merged type. */
|
||||
extern tree common_type PROTO((tree, tree));
|
||||
extern int comptypes PROTO((tree, tree));
|
||||
extern int self_promoting_args_p PROTO((tree));
|
||||
extern tree c_sizeof PROTO((tree));
|
||||
extern tree c_sizeof_nowarn PROTO((tree));
|
||||
extern tree c_size_in_bytes PROTO((tree));
|
||||
extern tree c_alignof PROTO((tree));
|
||||
extern tree c_alignof_expr PROTO((tree));
|
||||
extern tree default_conversion PROTO((tree));
|
||||
extern tree build_component_ref PROTO((tree, tree));
|
||||
extern tree build_indirect_ref PROTO((tree, char *));
|
||||
extern tree build_array_ref PROTO((tree, tree));
|
||||
extern tree build_function_call PROTO((tree, tree));
|
||||
extern tree parser_build_binary_op PROTO((enum tree_code,
|
||||
tree, tree));
|
||||
extern tree build_binary_op PROTO((enum tree_code,
|
||||
tree, tree, int));
|
||||
extern tree build_unary_op PROTO((enum tree_code,
|
||||
tree, int));
|
||||
extern int lvalue_p PROTO((tree));
|
||||
extern int lvalue_or_else PROTO((tree, char *));
|
||||
extern void readonly_warning PROTO((tree, char *));
|
||||
extern int mark_addressable PROTO((tree));
|
||||
extern tree build_conditional_expr PROTO((tree, tree, tree));
|
||||
extern tree build_compound_expr PROTO((tree));
|
||||
extern tree build_c_cast PROTO((tree, tree));
|
||||
extern tree build_modify_expr PROTO((tree, enum tree_code,
|
||||
tree));
|
||||
extern tree initializer_constant_valid_p PROTO((tree, tree));
|
||||
extern void store_init_value PROTO((tree, tree));
|
||||
extern void error_init PROTO((char *, char *,
|
||||
char *));
|
||||
extern void pedwarn_init PROTO((char *, char *,
|
||||
char *));
|
||||
extern void start_init PROTO((tree, tree, int));
|
||||
extern void finish_init PROTO((void));
|
||||
extern void really_start_incremental_init PROTO((tree));
|
||||
extern void push_init_level PROTO((int));
|
||||
extern tree pop_init_level PROTO((int));
|
||||
extern void set_init_index PROTO((tree, tree));
|
||||
extern void set_init_label PROTO((tree));
|
||||
extern void process_init_element PROTO((tree));
|
||||
extern void c_expand_asm_operands PROTO((tree, tree, tree, tree,
|
||||
int, char *, int));
|
||||
extern void c_expand_return PROTO((tree));
|
||||
extern tree c_expand_start_case PROTO((tree));
|
||||
|
||||
/* in c-iterate.c */
|
||||
extern void iterator_expand PROTO((tree));
|
||||
extern void iterator_for_loop_start PROTO((tree));
|
||||
extern void iterator_for_loop_end PROTO((tree));
|
||||
extern void iterator_for_loop_record PROTO((tree));
|
||||
extern void push_iterator_stack PROTO((void));
|
||||
extern void pop_iterator_stack PROTO((void));
|
||||
|
||||
/* Set to 0 at beginning of a function definition, set to 1 if
|
||||
a return statement that specifies a return value is seen. */
|
||||
|
||||
extern int current_function_returns_value;
|
||||
|
||||
/* Set to 0 at beginning of a function definition, set to 1 if
|
||||
a return statement with no argument is seen. */
|
||||
|
||||
extern int current_function_returns_null;
|
||||
|
||||
/* Nonzero means the expression being parsed will never be evaluated.
|
||||
This is a count, since unevaluated expressions can nest. */
|
||||
|
||||
extern int skip_evaluation;
|
||||
|
||||
/* Nonzero means `$' can be in an identifier. */
|
||||
|
||||
extern int dollars_in_ident;
|
||||
|
||||
/* Nonzero means allow type mismatches in conditional expressions;
|
||||
just make their values `void'. */
|
||||
|
||||
extern int flag_cond_mismatch;
|
||||
|
||||
/* Nonzero means don't recognize the keyword `asm'. */
|
||||
|
||||
extern int flag_no_asm;
|
||||
|
||||
/* Nonzero means environment is hosted (i.e., not freestanding) */
|
||||
|
||||
extern int flag_hosted;
|
||||
|
||||
/* Nonzero means ignore `#ident' directives. */
|
||||
|
||||
extern int flag_no_ident;
|
||||
|
||||
/* Nonzero means warn about implicit declarations. */
|
||||
|
||||
extern int warn_implicit;
|
||||
|
||||
/* Nonzero means give string constants the type `const char *'
|
||||
to get extra warnings from them. These warnings will be too numerous
|
||||
to be useful, except in thoroughly ANSIfied programs. */
|
||||
|
||||
extern int warn_write_strings;
|
||||
|
||||
/* Nonzero means warn about sizeof (function) or addition/subtraction
|
||||
of function pointers. */
|
||||
|
||||
extern int warn_pointer_arith;
|
||||
|
||||
/* Nonzero means warn for all old-style non-prototype function decls. */
|
||||
|
||||
extern int warn_strict_prototypes;
|
||||
|
||||
/* Nonzero means warn about multiple (redundant) decls for the same single
|
||||
variable or function. */
|
||||
|
||||
extern int warn_redundant_decls;
|
||||
|
||||
/* Nonzero means warn about extern declarations of objects not at
|
||||
file-scope level and about *all* declarations of functions (whether
|
||||
extern or static) not at file-scope level. Note that we exclude
|
||||
implicit function declarations. To get warnings about those, use
|
||||
-Wimplicit. */
|
||||
|
||||
extern int warn_nested_externs;
|
||||
|
||||
/* Nonzero means warn about pointer casts that can drop a type qualifier
|
||||
from the pointer target type. */
|
||||
|
||||
extern int warn_cast_qual;
|
||||
|
||||
/* Nonzero means warn when casting a function call to a type that does
|
||||
not match the return type (e.g. (float)sqrt() or (anything*)malloc()
|
||||
when there is no previous declaration of sqrt or malloc. */
|
||||
|
||||
extern int warn_bad_function_cast;
|
||||
|
||||
/* Warn about traditional constructs whose meanings changed in ANSI C. */
|
||||
|
||||
extern int warn_traditional;
|
||||
|
||||
/* Warn about *printf or *scanf format/argument anomalies. */
|
||||
|
||||
extern int warn_format;
|
||||
|
||||
/* Warn about a subscript that has type char. */
|
||||
|
||||
extern int warn_char_subscripts;
|
||||
|
||||
/* Warn if a type conversion is done that might have confusing results. */
|
||||
|
||||
extern int warn_conversion;
|
||||
|
||||
/* Warn if main is suspicious. */
|
||||
|
||||
extern int warn_main;
|
||||
|
||||
/* Nonzero means do some things the same way PCC does. */
|
||||
|
||||
extern int flag_traditional;
|
||||
|
||||
/* Nonzero means to allow single precision math even if we're generally
|
||||
being traditional. */
|
||||
extern int flag_allow_single_precision;
|
||||
|
||||
/* Nonzero means warn about suggesting putting in ()'s. */
|
||||
|
||||
extern int warn_parentheses;
|
||||
|
||||
/* Warn if initializer is not completely bracketed. */
|
||||
|
||||
extern int warn_missing_braces;
|
||||
|
||||
/* Warn about comparison of signed and unsigned values. */
|
||||
|
||||
extern int warn_sign_compare;
|
||||
|
||||
/* Nonzero means this is a function to call to perform comptypes
|
||||
on two record types. */
|
||||
|
||||
extern int (*comptypes_record_hook) ();
|
||||
|
||||
/* Nonzero means we are reading code that came from a system header file. */
|
||||
|
||||
extern int system_header_p;
|
||||
|
||||
/* Nonzero enables objc features. */
|
||||
|
||||
extern int doing_objc_thang;
|
||||
|
||||
#endif /* not _C_TREE_H */
|
6726
c-typeck.c
Normal file
6726
c-typeck.c
Normal file
File diff suppressed because it is too large
Load Diff
760
caller-save.c
Normal file
760
caller-save.c
Normal file
@ -0,0 +1,760 @@
|
||||
/* Save and restore call-clobbered registers which are live across a call.
|
||||
Copyright (C) 1989, 1992, 1994, 1995, 1997 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include "rtl.h"
|
||||
#include "insn-config.h"
|
||||
#include "flags.h"
|
||||
#include "regs.h"
|
||||
#include "hard-reg-set.h"
|
||||
#include "recog.h"
|
||||
#include "basic-block.h"
|
||||
#include "reload.h"
|
||||
#include "expr.h"
|
||||
|
||||
#ifndef MAX_MOVE_MAX
|
||||
#define MAX_MOVE_MAX MOVE_MAX
|
||||
#endif
|
||||
|
||||
#ifndef MIN_UNITS_PER_WORD
|
||||
#define MIN_UNITS_PER_WORD UNITS_PER_WORD
|
||||
#endif
|
||||
|
||||
/* Modes for each hard register that we can save. The smallest mode is wide
|
||||
enough to save the entire contents of the register. When saving the
|
||||
register because it is live we first try to save in multi-register modes.
|
||||
If that is not possible the save is done one register at a time. */
|
||||
|
||||
static enum machine_mode
|
||||
regno_save_mode[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1];
|
||||
|
||||
/* For each hard register, a place on the stack where it can be saved,
|
||||
if needed. */
|
||||
|
||||
static rtx
|
||||
regno_save_mem[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1];
|
||||
|
||||
/* We will only make a register eligible for caller-save if it can be
|
||||
saved in its widest mode with a simple SET insn as long as the memory
|
||||
address is valid. We record the INSN_CODE is those insns here since
|
||||
when we emit them, the addresses might not be valid, so they might not
|
||||
be recognized. */
|
||||
|
||||
static enum insn_code
|
||||
reg_save_code[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1];
|
||||
static enum insn_code
|
||||
reg_restore_code[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1];
|
||||
|
||||
/* Set of hard regs currently live (during scan of all insns). */
|
||||
|
||||
static HARD_REG_SET hard_regs_live;
|
||||
|
||||
/* Set of hard regs currently residing in save area (during insn scan). */
|
||||
|
||||
static HARD_REG_SET hard_regs_saved;
|
||||
|
||||
/* Set of hard regs which need to be restored before referenced. */
|
||||
|
||||
static HARD_REG_SET hard_regs_need_restore;
|
||||
|
||||
/* Number of registers currently in hard_regs_saved. */
|
||||
|
||||
int n_regs_saved;
|
||||
|
||||
static void set_reg_live PROTO((rtx, rtx));
|
||||
static void clear_reg_live PROTO((rtx));
|
||||
static void restore_referenced_regs PROTO((rtx, rtx, enum machine_mode));
|
||||
static int insert_save_restore PROTO((rtx, int, int,
|
||||
enum machine_mode, int));
|
||||
|
||||
/* Initialize for caller-save.
|
||||
|
||||
Look at all the hard registers that are used by a call and for which
|
||||
regclass.c has not already excluded from being used across a call.
|
||||
|
||||
Ensure that we can find a mode to save the register and that there is a
|
||||
simple insn to save and restore the register. This latter check avoids
|
||||
problems that would occur if we tried to save the MQ register of some
|
||||
machines directly into memory. */
|
||||
|
||||
void
|
||||
init_caller_save ()
|
||||
{
|
||||
char *first_obj = (char *) oballoc (0);
|
||||
rtx addr_reg;
|
||||
int offset;
|
||||
rtx address;
|
||||
int i, j;
|
||||
|
||||
/* First find all the registers that we need to deal with and all
|
||||
the modes that they can have. If we can't find a mode to use,
|
||||
we can't have the register live over calls. */
|
||||
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
{
|
||||
if (call_used_regs[i] && ! call_fixed_regs[i])
|
||||
{
|
||||
for (j = 1; j <= MOVE_MAX / UNITS_PER_WORD; j++)
|
||||
{
|
||||
regno_save_mode[i][j] = choose_hard_reg_mode (i, j);
|
||||
if (regno_save_mode[i][j] == VOIDmode && j == 1)
|
||||
{
|
||||
call_fixed_regs[i] = 1;
|
||||
SET_HARD_REG_BIT (call_fixed_reg_set, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
regno_save_mode[i][1] = VOIDmode;
|
||||
}
|
||||
|
||||
/* The following code tries to approximate the conditions under which
|
||||
we can easily save and restore a register without scratch registers or
|
||||
other complexities. It will usually work, except under conditions where
|
||||
the validity of an insn operand is dependent on the address offset.
|
||||
No such cases are currently known.
|
||||
|
||||
We first find a typical offset from some BASE_REG_CLASS register.
|
||||
This address is chosen by finding the first register in the class
|
||||
and by finding the smallest power of two that is a valid offset from
|
||||
that register in every mode we will use to save registers. */
|
||||
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
if (TEST_HARD_REG_BIT (reg_class_contents[(int) BASE_REG_CLASS], i))
|
||||
break;
|
||||
|
||||
if (i == FIRST_PSEUDO_REGISTER)
|
||||
abort ();
|
||||
|
||||
addr_reg = gen_rtx (REG, Pmode, i);
|
||||
|
||||
for (offset = 1 << (HOST_BITS_PER_INT / 2); offset; offset >>= 1)
|
||||
{
|
||||
address = gen_rtx (PLUS, Pmode, addr_reg, GEN_INT (offset));
|
||||
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
if (regno_save_mode[i][1] != VOIDmode
|
||||
&& ! strict_memory_address_p (regno_save_mode[i][1], address))
|
||||
break;
|
||||
|
||||
if (i == FIRST_PSEUDO_REGISTER)
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we didn't find a valid address, we must use register indirect. */
|
||||
if (offset == 0)
|
||||
address = addr_reg;
|
||||
|
||||
/* Next we try to form an insn to save and restore the register. We
|
||||
see if such an insn is recognized and meets its constraints. */
|
||||
|
||||
start_sequence ();
|
||||
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
for (j = 1; j <= MOVE_MAX / UNITS_PER_WORD; j++)
|
||||
if (regno_save_mode[i][j] != VOIDmode)
|
||||
{
|
||||
rtx mem = gen_rtx (MEM, regno_save_mode[i][j], address);
|
||||
rtx reg = gen_rtx (REG, regno_save_mode[i][j], i);
|
||||
rtx savepat = gen_rtx (SET, VOIDmode, mem, reg);
|
||||
rtx restpat = gen_rtx (SET, VOIDmode, reg, mem);
|
||||
rtx saveinsn = emit_insn (savepat);
|
||||
rtx restinsn = emit_insn (restpat);
|
||||
int ok;
|
||||
|
||||
reg_save_code[i][j] = recog_memoized (saveinsn);
|
||||
reg_restore_code[i][j] = recog_memoized (restinsn);
|
||||
|
||||
/* Now extract both insns and see if we can meet their
|
||||
constraints. */
|
||||
ok = (reg_save_code[i][j] != -1 && reg_restore_code[i][j] != -1);
|
||||
if (ok)
|
||||
{
|
||||
insn_extract (saveinsn);
|
||||
ok = constrain_operands (reg_save_code[i][j], 1);
|
||||
insn_extract (restinsn);
|
||||
ok &= constrain_operands (reg_restore_code[i][j], 1);
|
||||
}
|
||||
|
||||
if (! ok)
|
||||
{
|
||||
regno_save_mode[i][j] = VOIDmode;
|
||||
if (j == 1)
|
||||
{
|
||||
call_fixed_regs[i] = 1;
|
||||
SET_HARD_REG_BIT (call_fixed_reg_set, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end_sequence ();
|
||||
|
||||
obfree (first_obj);
|
||||
}
|
||||
|
||||
/* Initialize save areas by showing that we haven't allocated any yet. */
|
||||
|
||||
void
|
||||
init_save_areas ()
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
for (j = 1; j <= MOVE_MAX / UNITS_PER_WORD; j++)
|
||||
regno_save_mem[i][j] = 0;
|
||||
}
|
||||
|
||||
/* Allocate save areas for any hard registers that might need saving.
|
||||
We take a conservative approach here and look for call-clobbered hard
|
||||
registers that are assigned to pseudos that cross calls. This may
|
||||
overestimate slightly (especially if some of these registers are later
|
||||
used as spill registers), but it should not be significant.
|
||||
|
||||
Then perform register elimination in the addresses of the save area
|
||||
locations; return 1 if all eliminated addresses are strictly valid.
|
||||
We assume that our caller has set up the elimination table to the
|
||||
worst (largest) possible offsets.
|
||||
|
||||
Set *PCHANGED to 1 if we had to allocate some memory for the save area.
|
||||
|
||||
Future work:
|
||||
|
||||
In the fallback case we should iterate backwards across all possible
|
||||
modes for the save, choosing the largest available one instead of
|
||||
falling back to the smallest mode immediately. (eg TF -> DF -> SF).
|
||||
|
||||
We do not try to use "move multiple" instructions that exist
|
||||
on some machines (such as the 68k moveml). It could be a win to try
|
||||
and use them when possible. The hard part is doing it in a way that is
|
||||
machine independent since they might be saving non-consecutive
|
||||
registers. (imagine caller-saving d0,d1,a0,a1 on the 68k) */
|
||||
|
||||
int
|
||||
setup_save_areas (pchanged)
|
||||
int *pchanged;
|
||||
{
|
||||
int i, j, k;
|
||||
HARD_REG_SET hard_regs_used;
|
||||
int ok = 1;
|
||||
|
||||
|
||||
/* Allocate space in the save area for the largest multi-register
|
||||
pseudos first, then work backwards to single register
|
||||
pseudos. */
|
||||
|
||||
/* Find and record all call-used hard-registers in this function. */
|
||||
CLEAR_HARD_REG_SET (hard_regs_used);
|
||||
for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
|
||||
if (reg_renumber[i] >= 0 && REG_N_CALLS_CROSSED (i) > 0)
|
||||
{
|
||||
int regno = reg_renumber[i];
|
||||
int endregno
|
||||
= regno + HARD_REGNO_NREGS (regno, GET_MODE (regno_reg_rtx[i]));
|
||||
int nregs = endregno - regno;
|
||||
|
||||
for (j = 0; j < nregs; j++)
|
||||
{
|
||||
if (call_used_regs[regno+j])
|
||||
SET_HARD_REG_BIT (hard_regs_used, regno+j);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now run through all the call-used hard-registers and allocate
|
||||
space for them in the caller-save area. Try to allocate space
|
||||
in a manner which allows multi-register saves/restores to be done. */
|
||||
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
for (j = MOVE_MAX / UNITS_PER_WORD; j > 0; j--)
|
||||
{
|
||||
int ok = 1;
|
||||
int do_save;
|
||||
|
||||
/* If no mode exists for this size, try another. Also break out
|
||||
if we have already saved this hard register. */
|
||||
if (regno_save_mode[i][j] == VOIDmode || regno_save_mem[i][1] != 0)
|
||||
continue;
|
||||
|
||||
/* See if any register in this group has been saved. */
|
||||
do_save = 1;
|
||||
for (k = 0; k < j; k++)
|
||||
if (regno_save_mem[i + k][1])
|
||||
{
|
||||
do_save = 0;
|
||||
break;
|
||||
}
|
||||
if (! do_save)
|
||||
continue;
|
||||
|
||||
for (k = 0; k < j; k++)
|
||||
{
|
||||
int regno = i + k;
|
||||
ok &= (TEST_HARD_REG_BIT (hard_regs_used, regno) != 0);
|
||||
}
|
||||
|
||||
/* We have found an acceptable mode to store in. */
|
||||
if (ok)
|
||||
{
|
||||
|
||||
regno_save_mem[i][j]
|
||||
= assign_stack_local (regno_save_mode[i][j],
|
||||
GET_MODE_SIZE (regno_save_mode[i][j]), 0);
|
||||
|
||||
/* Setup single word save area just in case... */
|
||||
for (k = 0; k < j; k++)
|
||||
{
|
||||
/* This should not depend on WORDS_BIG_ENDIAN.
|
||||
The order of words in regs is the same as in memory. */
|
||||
rtx temp = gen_rtx (MEM, regno_save_mode[i+k][1],
|
||||
XEXP (regno_save_mem[i][j], 0));
|
||||
|
||||
regno_save_mem[i+k][1]
|
||||
= adj_offsettable_operand (temp, k * UNITS_PER_WORD);
|
||||
}
|
||||
*pchanged = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
for (j = 1; j <= MOVE_MAX / UNITS_PER_WORD; j++)
|
||||
if (regno_save_mem[i][j] != 0)
|
||||
ok &= strict_memory_address_p (GET_MODE (regno_save_mem[i][j]),
|
||||
XEXP (eliminate_regs (regno_save_mem[i][j], 0, NULL_RTX, 1), 0));
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
/* Find the places where hard regs are live across calls and save them.
|
||||
|
||||
INSN_MODE is the mode to assign to any insns that we add. This is used
|
||||
by reload to determine whether or not reloads or register eliminations
|
||||
need be done on these insns. */
|
||||
|
||||
void
|
||||
save_call_clobbered_regs (insn_mode)
|
||||
enum machine_mode insn_mode;
|
||||
{
|
||||
rtx insn;
|
||||
int b;
|
||||
|
||||
for (b = 0; b < n_basic_blocks; b++)
|
||||
{
|
||||
regset regs_live = basic_block_live_at_start[b];
|
||||
rtx prev_block_last = PREV_INSN (basic_block_head[b]);
|
||||
int i, j;
|
||||
int regno;
|
||||
|
||||
/* Compute hard regs live at start of block -- this is the
|
||||
real hard regs marked live, plus live pseudo regs that
|
||||
have been renumbered to hard regs. No registers have yet been
|
||||
saved because we restore all of them before the end of the basic
|
||||
block. */
|
||||
|
||||
REG_SET_TO_HARD_REG_SET (hard_regs_live, regs_live);
|
||||
CLEAR_HARD_REG_SET (hard_regs_saved);
|
||||
CLEAR_HARD_REG_SET (hard_regs_need_restore);
|
||||
n_regs_saved = 0;
|
||||
|
||||
EXECUTE_IF_SET_IN_REG_SET (regs_live, 0, i,
|
||||
{
|
||||
if ((regno = reg_renumber[i]) >= 0)
|
||||
for (j = regno;
|
||||
j < regno + HARD_REGNO_NREGS (regno,
|
||||
PSEUDO_REGNO_MODE (i));
|
||||
j++)
|
||||
SET_HARD_REG_BIT (hard_regs_live, j);
|
||||
});
|
||||
|
||||
/* Now scan the insns in the block, keeping track of what hard
|
||||
regs are live as we go. When we see a call, save the live
|
||||
call-clobbered hard regs. */
|
||||
|
||||
for (insn = basic_block_head[b]; ; insn = NEXT_INSN (insn))
|
||||
{
|
||||
RTX_CODE code = GET_CODE (insn);
|
||||
|
||||
if (GET_RTX_CLASS (code) == 'i')
|
||||
{
|
||||
rtx link;
|
||||
|
||||
/* If some registers have been saved, see if INSN references
|
||||
any of them. We must restore them before the insn if so. */
|
||||
|
||||
if (n_regs_saved)
|
||||
restore_referenced_regs (PATTERN (insn), insn, insn_mode);
|
||||
|
||||
/* NB: the normal procedure is to first enliven any
|
||||
registers set by insn, then deaden any registers that
|
||||
had their last use at insn. This is incorrect now,
|
||||
since multiple pseudos may have been mapped to the
|
||||
same hard reg, and the death notes are ambiguous. So
|
||||
it must be done in the other, safe, order. */
|
||||
|
||||
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
|
||||
if (REG_NOTE_KIND (link) == REG_DEAD)
|
||||
clear_reg_live (XEXP (link, 0));
|
||||
|
||||
/* When we reach a call, we need to save all registers that are
|
||||
live, call-used, not fixed, and not already saved. We must
|
||||
test at this point because registers that die in a CALL_INSN
|
||||
are not live across the call and likewise for registers that
|
||||
are born in the CALL_INSN.
|
||||
|
||||
If registers are filled with parameters for this function,
|
||||
and some of these are also being set by this function, then
|
||||
they will not appear to die (no REG_DEAD note for them),
|
||||
to check if in fact they do, collect the set registers in
|
||||
hard_regs_live first. */
|
||||
|
||||
if (code == CALL_INSN)
|
||||
{
|
||||
HARD_REG_SET this_call_sets;
|
||||
{
|
||||
HARD_REG_SET old_hard_regs_live;
|
||||
|
||||
/* Save the hard_regs_live information. */
|
||||
COPY_HARD_REG_SET (old_hard_regs_live, hard_regs_live);
|
||||
|
||||
/* Now calculate hard_regs_live for this CALL_INSN
|
||||
only. */
|
||||
CLEAR_HARD_REG_SET (hard_regs_live);
|
||||
note_stores (PATTERN (insn), set_reg_live);
|
||||
COPY_HARD_REG_SET (this_call_sets, hard_regs_live);
|
||||
|
||||
/* Restore the hard_regs_live information. */
|
||||
COPY_HARD_REG_SET (hard_regs_live, old_hard_regs_live);
|
||||
}
|
||||
|
||||
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
|
||||
if (call_used_regs[regno] && ! call_fixed_regs[regno]
|
||||
&& TEST_HARD_REG_BIT (hard_regs_live, regno)
|
||||
/* It must not be set by this instruction. */
|
||||
&& ! TEST_HARD_REG_BIT (this_call_sets, regno)
|
||||
&& ! TEST_HARD_REG_BIT (hard_regs_saved, regno))
|
||||
regno += insert_save_restore (insn, 1, regno,
|
||||
insn_mode, 0);
|
||||
|
||||
/* Put the information for this CALL_INSN on top of what
|
||||
we already had. */
|
||||
IOR_HARD_REG_SET (hard_regs_live, this_call_sets);
|
||||
COPY_HARD_REG_SET (hard_regs_need_restore, hard_regs_saved);
|
||||
|
||||
/* Must recompute n_regs_saved. */
|
||||
n_regs_saved = 0;
|
||||
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
|
||||
if (TEST_HARD_REG_BIT (hard_regs_saved, regno))
|
||||
n_regs_saved++;
|
||||
}
|
||||
else
|
||||
{
|
||||
note_stores (PATTERN (insn), set_reg_live);
|
||||
#ifdef AUTO_INC_DEC
|
||||
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
|
||||
if (REG_NOTE_KIND (link) == REG_INC)
|
||||
set_reg_live (XEXP (link, 0), NULL_RTX);
|
||||
#endif
|
||||
}
|
||||
|
||||
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
|
||||
if (REG_NOTE_KIND (link) == REG_UNUSED)
|
||||
clear_reg_live (XEXP (link, 0));
|
||||
}
|
||||
|
||||
if (insn == basic_block_end[b])
|
||||
break;
|
||||
}
|
||||
|
||||
/* At the end of the basic block, we must restore any registers that
|
||||
remain saved. If the last insn in the block is a JUMP_INSN, put
|
||||
the restore before the insn, otherwise, put it after the insn. */
|
||||
|
||||
if (n_regs_saved)
|
||||
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
|
||||
if (TEST_HARD_REG_BIT (hard_regs_need_restore, regno))
|
||||
regno += insert_save_restore ((GET_CODE (insn) == JUMP_INSN
|
||||
? insn : NEXT_INSN (insn)), 0,
|
||||
regno, insn_mode, MOVE_MAX / UNITS_PER_WORD);
|
||||
|
||||
/* If we added any insns at the start of the block, update the start
|
||||
of the block to point at those insns. */
|
||||
basic_block_head[b] = NEXT_INSN (prev_block_last);
|
||||
}
|
||||
}
|
||||
|
||||
/* Here from note_stores when an insn stores a value in a register.
|
||||
Set the proper bit or bits in hard_regs_live. All pseudos that have
|
||||
been assigned hard regs have had their register number changed already,
|
||||
so we can ignore pseudos. */
|
||||
|
||||
static void
|
||||
set_reg_live (reg, setter)
|
||||
rtx reg, setter;
|
||||
{
|
||||
register int regno, endregno, i;
|
||||
enum machine_mode mode = GET_MODE (reg);
|
||||
int word = 0;
|
||||
|
||||
if (GET_CODE (reg) == SUBREG)
|
||||
{
|
||||
word = SUBREG_WORD (reg);
|
||||
reg = SUBREG_REG (reg);
|
||||
}
|
||||
|
||||
if (GET_CODE (reg) != REG || REGNO (reg) >= FIRST_PSEUDO_REGISTER)
|
||||
return;
|
||||
|
||||
regno = REGNO (reg) + word;
|
||||
endregno = regno + HARD_REGNO_NREGS (regno, mode);
|
||||
|
||||
for (i = regno; i < endregno; i++)
|
||||
{
|
||||
SET_HARD_REG_BIT (hard_regs_live, i);
|
||||
CLEAR_HARD_REG_BIT (hard_regs_saved, i);
|
||||
CLEAR_HARD_REG_BIT (hard_regs_need_restore, i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Here when a REG_DEAD note records the last use of a reg. Clear
|
||||
the appropriate bit or bits in hard_regs_live. Again we can ignore
|
||||
pseudos. */
|
||||
|
||||
static void
|
||||
clear_reg_live (reg)
|
||||
rtx reg;
|
||||
{
|
||||
register int regno, endregno, i;
|
||||
|
||||
if (GET_CODE (reg) != REG || REGNO (reg) >= FIRST_PSEUDO_REGISTER)
|
||||
return;
|
||||
|
||||
regno = REGNO (reg);
|
||||
endregno= regno + HARD_REGNO_NREGS (regno, GET_MODE (reg));
|
||||
|
||||
for (i = regno; i < endregno; i++)
|
||||
{
|
||||
CLEAR_HARD_REG_BIT (hard_regs_live, i);
|
||||
CLEAR_HARD_REG_BIT (hard_regs_need_restore, i);
|
||||
CLEAR_HARD_REG_BIT (hard_regs_saved, i);
|
||||
}
|
||||
}
|
||||
|
||||
/* If any register currently residing in the save area is referenced in X,
|
||||
which is part of INSN, emit code to restore the register in front of INSN.
|
||||
INSN_MODE is the mode to assign to any insns that we add. */
|
||||
|
||||
static void
|
||||
restore_referenced_regs (x, insn, insn_mode)
|
||||
rtx x;
|
||||
rtx insn;
|
||||
enum machine_mode insn_mode;
|
||||
{
|
||||
enum rtx_code code = GET_CODE (x);
|
||||
char *fmt;
|
||||
int i, j;
|
||||
|
||||
if (code == CLOBBER)
|
||||
return;
|
||||
|
||||
if (code == REG)
|
||||
{
|
||||
int regno = REGNO (x);
|
||||
|
||||
/* If this is a pseudo, scan its memory location, since it might
|
||||
involve the use of another register, which might be saved. */
|
||||
|
||||
if (regno >= FIRST_PSEUDO_REGISTER
|
||||
&& reg_equiv_mem[regno] != 0)
|
||||
restore_referenced_regs (XEXP (reg_equiv_mem[regno], 0),
|
||||
insn, insn_mode);
|
||||
else if (regno >= FIRST_PSEUDO_REGISTER
|
||||
&& reg_equiv_address[regno] != 0)
|
||||
restore_referenced_regs (reg_equiv_address[regno],
|
||||
insn, insn_mode);
|
||||
|
||||
/* Otherwise if this is a hard register, restore any piece of it that
|
||||
is currently saved. */
|
||||
|
||||
else if (regno < FIRST_PSEUDO_REGISTER)
|
||||
{
|
||||
int numregs = HARD_REGNO_NREGS (regno, GET_MODE (x));
|
||||
/* Save at most SAVEREGS at a time. This can not be larger than
|
||||
MOVE_MAX, because that causes insert_save_restore to fail. */
|
||||
int saveregs = MIN (numregs, MOVE_MAX / UNITS_PER_WORD);
|
||||
int endregno = regno + numregs;
|
||||
|
||||
for (i = regno; i < endregno; i++)
|
||||
if (TEST_HARD_REG_BIT (hard_regs_need_restore, i))
|
||||
i += insert_save_restore (insn, 0, i, insn_mode, saveregs);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
fmt = GET_RTX_FORMAT (code);
|
||||
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
|
||||
{
|
||||
if (fmt[i] == 'e')
|
||||
restore_referenced_regs (XEXP (x, i), insn, insn_mode);
|
||||
else if (fmt[i] == 'E')
|
||||
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
|
||||
restore_referenced_regs (XVECEXP (x, i, j), insn, insn_mode);
|
||||
}
|
||||
}
|
||||
|
||||
/* Insert a sequence of insns to save or restore, SAVE_P says which,
|
||||
REGNO. Place these insns in front of INSN. INSN_MODE is the mode
|
||||
to assign to these insns. MAXRESTORE is the maximum number of registers
|
||||
which should be restored during this call (when SAVE_P == 0). It should
|
||||
never be less than 1 since we only work with entire registers.
|
||||
|
||||
Note that we have verified in init_caller_save that we can do this
|
||||
with a simple SET, so use it. Set INSN_CODE to what we save there
|
||||
since the address might not be valid so the insn might not be recognized.
|
||||
These insns will be reloaded and have register elimination done by
|
||||
find_reload, so we need not worry about that here.
|
||||
|
||||
Return the extra number of registers saved. */
|
||||
|
||||
static int
|
||||
insert_save_restore (insn, save_p, regno, insn_mode, maxrestore)
|
||||
rtx insn;
|
||||
int save_p;
|
||||
int regno;
|
||||
enum machine_mode insn_mode;
|
||||
int maxrestore;
|
||||
{
|
||||
rtx pat;
|
||||
enum insn_code code;
|
||||
int i, numregs;
|
||||
|
||||
/* A common failure mode if register status is not correct in the RTL
|
||||
is for this routine to be called with a REGNO we didn't expect to
|
||||
save. That will cause us to write an insn with a (nil) SET_DEST
|
||||
or SET_SRC. Instead of doing so and causing a crash later, check
|
||||
for this common case and abort here instead. This will remove one
|
||||
step in debugging such problems. */
|
||||
|
||||
if (regno_save_mem[regno][1] == 0)
|
||||
abort ();
|
||||
|
||||
#ifdef HAVE_cc0
|
||||
/* If INSN references CC0, put our insns in front of the insn that sets
|
||||
CC0. This is always safe, since the only way we could be passed an
|
||||
insn that references CC0 is for a restore, and doing a restore earlier
|
||||
isn't a problem. We do, however, assume here that CALL_INSNs don't
|
||||
reference CC0. Guard against non-INSN's like CODE_LABEL. */
|
||||
|
||||
if ((GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN)
|
||||
&& reg_referenced_p (cc0_rtx, PATTERN (insn)))
|
||||
insn = prev_nonnote_insn (insn);
|
||||
#endif
|
||||
|
||||
/* Get the pattern to emit and update our status. */
|
||||
if (save_p)
|
||||
{
|
||||
int i, j, k;
|
||||
int ok;
|
||||
|
||||
/* See if we can save several registers with a single instruction.
|
||||
Work backwards to the single register case. */
|
||||
for (i = MOVE_MAX / UNITS_PER_WORD; i > 0; i--)
|
||||
{
|
||||
ok = 1;
|
||||
if (regno_save_mem[regno][i] != 0)
|
||||
for (j = 0; j < i; j++)
|
||||
{
|
||||
if (! call_used_regs[regno + j] || call_fixed_regs[regno + j]
|
||||
|| ! TEST_HARD_REG_BIT (hard_regs_live, regno + j)
|
||||
|| TEST_HARD_REG_BIT (hard_regs_saved, regno + j))
|
||||
ok = 0;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
/* Must do this one save at a time */
|
||||
if (! ok)
|
||||
continue;
|
||||
|
||||
pat = gen_rtx (SET, VOIDmode, regno_save_mem[regno][i],
|
||||
gen_rtx (REG, GET_MODE (regno_save_mem[regno][i]), regno));
|
||||
code = reg_save_code[regno][i];
|
||||
|
||||
/* Set hard_regs_saved for all the registers we saved. */
|
||||
for (k = 0; k < i; k++)
|
||||
{
|
||||
SET_HARD_REG_BIT (hard_regs_saved, regno + k);
|
||||
SET_HARD_REG_BIT (hard_regs_need_restore, regno + k);
|
||||
n_regs_saved++;
|
||||
}
|
||||
|
||||
numregs = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int i, j, k;
|
||||
int ok;
|
||||
|
||||
/* See if we can restore `maxrestore' registers at once. Work
|
||||
backwards to the single register case. */
|
||||
for (i = maxrestore; i > 0; i--)
|
||||
{
|
||||
ok = 1;
|
||||
if (regno_save_mem[regno][i])
|
||||
for (j = 0; j < i; j++)
|
||||
{
|
||||
if (! TEST_HARD_REG_BIT (hard_regs_need_restore, regno + j))
|
||||
ok = 0;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
/* Must do this one restore at a time */
|
||||
if (! ok)
|
||||
continue;
|
||||
|
||||
pat = gen_rtx (SET, VOIDmode,
|
||||
gen_rtx (REG, GET_MODE (regno_save_mem[regno][i]),
|
||||
regno),
|
||||
regno_save_mem[regno][i]);
|
||||
code = reg_restore_code[regno][i];
|
||||
|
||||
|
||||
/* Clear status for all registers we restored. */
|
||||
for (k = 0; k < i; k++)
|
||||
{
|
||||
CLEAR_HARD_REG_BIT (hard_regs_need_restore, regno + k);
|
||||
n_regs_saved--;
|
||||
}
|
||||
|
||||
numregs = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Emit the insn and set the code and mode. */
|
||||
|
||||
insn = emit_insn_before (pat, insn);
|
||||
PUT_MODE (insn, insn_mode);
|
||||
INSN_CODE (insn) = code;
|
||||
|
||||
/* Tell our callers how many extra registers we saved/restored */
|
||||
return numregs - 1;
|
||||
}
|
674
cccp.1
Normal file
674
cccp.1
Normal file
@ -0,0 +1,674 @@
|
||||
.\" Copyright (c) 1991, 1992, 1993 Free Software Foundation \-*-Text-*-
|
||||
.\" See section COPYING for conditions for redistribution
|
||||
.TH cpp 1 "30apr1993" "GNU Tools" "GNU Tools"
|
||||
.SH NAME
|
||||
cccp, cpp \- The GNU C-Compatible Compiler Preprocessor.
|
||||
.SH SYNOPSIS
|
||||
.hy 0
|
||||
.na
|
||||
.TP
|
||||
.B cccp
|
||||
.RB "[\|" \-$ "\|]"
|
||||
.RB "[\|" \-A \c
|
||||
.I predicate\c
|
||||
.RB [ (\c
|
||||
.I value\c
|
||||
.BR ) ]\|]
|
||||
.RB "[\|" \-C "\|]"
|
||||
.RB "[\|" \-D \c
|
||||
.I name\c
|
||||
.RB [ =\c
|
||||
.I definition\c
|
||||
\&]\|]
|
||||
.RB "[\|" \-dD "\|]"
|
||||
.RB "[\|" \-dM "\|]"
|
||||
.RB "[\|" "\-I\ "\c
|
||||
.I directory\c
|
||||
\&\|]
|
||||
.RB "[\|" \-H "\|]"
|
||||
.RB "[\|" \-I\- "\|]"
|
||||
.RB "[\|" "\-imacros\ "\c
|
||||
.I file\c
|
||||
\&\|]
|
||||
.RB "[\|" "\-include\ "\c
|
||||
.I file\c
|
||||
\&\|]
|
||||
.RB "[\|" "\-idirafter\ "\c
|
||||
.I dir\c
|
||||
\&\|]
|
||||
.RB "[\|" "\-iprefix\ "\c
|
||||
.I prefix\c
|
||||
\&\|]
|
||||
.RB "[\|" "\-iwithprefix\ "\c
|
||||
.I dir\c
|
||||
\&\|]
|
||||
.RB "[\|" \-lang\-c "\|]"
|
||||
.RB "[\|" \-lang\-c++ "\|]"
|
||||
.RB "[\|" \-lang\-objc "\|]"
|
||||
.RB "[\|" \-lang\-objc++ "\|]"
|
||||
.RB "[\|" \-lint "\|]"
|
||||
.RB "[\|" \-M\ [ \-MG "\|]]"
|
||||
.RB "[\|" \-MM\ [ \-MG "\|]]"
|
||||
.RB "[\|" \-MD\ \c
|
||||
.I file\ \c
|
||||
\&\|]
|
||||
.RB "[\|" \-MMD\ \c
|
||||
.I file\ \c
|
||||
\&\|]
|
||||
.RB "[\|" \-nostdinc "\|]"
|
||||
.RB "[\|" \-nostdinc++ "\|]"
|
||||
.RB "[\|" \-P "\|]"
|
||||
.RB "[\|" \-pedantic "\|]"
|
||||
.RB "[\|" \-pedantic\-errors "\|]"
|
||||
.RB "[\|" \-traditional "\|]"
|
||||
.RB "[\|" \-trigraphs "\|]"
|
||||
.RB "[\|" \-U \c
|
||||
.I name\c
|
||||
\&\|]
|
||||
.RB "[\|" \-undef "\|]"
|
||||
.RB "[\|" \-Wtrigraphs "\|]"
|
||||
.RB "[\|" \-Wcomment "\|]"
|
||||
.RB "[\|" \-Wall "\|]"
|
||||
.RB "[\|" \-Wtraditional "\|]"
|
||||
.br
|
||||
.RB "[\|" \c
|
||||
.I infile\c
|
||||
.RB | \- "\|]"
|
||||
.RB "[\|" \c
|
||||
.I outfile\c
|
||||
.RB | \- "\|]"
|
||||
.ad b
|
||||
.hy 1
|
||||
.SH DESCRIPTION
|
||||
The C preprocessor is a \c
|
||||
.I macro processor\c
|
||||
\& that is used automatically by
|
||||
the C compiler to transform your program before actual compilation. It is
|
||||
called a macro processor because it allows you to define \c
|
||||
.I macros\c
|
||||
\&,
|
||||
which are brief abbreviations for longer constructs.
|
||||
|
||||
The C preprocessor provides four separate facilities that you can use as
|
||||
you see fit:
|
||||
.TP
|
||||
\(bu
|
||||
Inclusion of header files. These are files of declarations that can be
|
||||
substituted into your program.
|
||||
.TP
|
||||
\(bu
|
||||
Macro expansion. You can define \c
|
||||
.I macros\c
|
||||
\&, which are abbreviations
|
||||
for arbitrary fragments of C code, and then the C preprocessor will
|
||||
replace the macros with their definitions throughout the program.
|
||||
.TP
|
||||
\(bu
|
||||
Conditional compilation. Using special preprocessing directives, you
|
||||
can include or exclude parts of the program according to various
|
||||
conditions.
|
||||
.TP
|
||||
\(bu
|
||||
Line control. If you use a program to combine or rearrange source files into
|
||||
an intermediate file which is then compiled, you can use line control
|
||||
to inform the compiler of where each source line originally came from.
|
||||
.PP
|
||||
C preprocessors vary in some details. For a full explanation of the
|
||||
GNU C preprocessor, see the
|
||||
.B info
|
||||
file `\|\c
|
||||
.B cpp.info\c
|
||||
\&\|', or the manual
|
||||
.I The C Preprocessor\c
|
||||
\&. Both of these are built from the same documentation source file, `\|\c
|
||||
.B cpp.texinfo\c
|
||||
\&\|'. The GNU C
|
||||
preprocessor provides a superset of the features of ANSI Standard C.
|
||||
|
||||
ANSI Standard C requires the rejection of many harmless constructs commonly
|
||||
used by today's C programs. Such incompatibility would be inconvenient for
|
||||
users, so the GNU C preprocessor is configured to accept these constructs
|
||||
by default. Strictly speaking, to get ANSI Standard C, you must use the
|
||||
options `\|\c
|
||||
.B \-trigraphs\c
|
||||
\&\|', `\|\c
|
||||
.B \-undef\c
|
||||
\&\|' and `\|\c
|
||||
.B \-pedantic\c
|
||||
\&\|', but in
|
||||
practice the consequences of having strict ANSI Standard C make it
|
||||
undesirable to do this.
|
||||
|
||||
Most often when you use the C preprocessor you will not have to invoke it
|
||||
explicitly: the C compiler will do so automatically. However, the
|
||||
preprocessor is sometimes useful individually.
|
||||
|
||||
When you call the preprocessor individually, either name
|
||||
(\c
|
||||
.B cpp\c
|
||||
\& or \c
|
||||
.B cccp\c
|
||||
\&) will do\(em\&they are completely synonymous.
|
||||
|
||||
The C preprocessor expects two file names as arguments, \c
|
||||
.I infile\c
|
||||
\& and
|
||||
\c
|
||||
.I outfile\c
|
||||
\&. The preprocessor reads \c
|
||||
.I infile\c
|
||||
\& together with any other
|
||||
files it specifies with `\|\c
|
||||
.B #include\c
|
||||
\&\|'. All the output generated by the
|
||||
combined input files is written in \c
|
||||
.I outfile\c
|
||||
\&.
|
||||
|
||||
Either \c
|
||||
.I infile\c
|
||||
\& or \c
|
||||
.I outfile\c
|
||||
\& may be `\|\c
|
||||
.B \-\c
|
||||
\&\|', which as \c
|
||||
.I infile\c
|
||||
\&
|
||||
means to read from standard input and as \c
|
||||
.I outfile\c
|
||||
\& means to write to
|
||||
standard output. Also, if \c
|
||||
.I outfile\c
|
||||
\& or both file names are omitted,
|
||||
the standard output and standard input are used for the omitted file names.
|
||||
.SH OPTIONS
|
||||
Here is a table of command options accepted by the C preprocessor.
|
||||
These options can also be given when compiling a C program; they are
|
||||
passed along automatically to the preprocessor when it is invoked by
|
||||
the compiler.
|
||||
.TP
|
||||
.B \-P
|
||||
Inhibit generation of `\|\c
|
||||
.B #\c
|
||||
\&\|'-lines with line-number information in
|
||||
the output from the preprocessor. This might be
|
||||
useful when running the preprocessor on something that is not C code
|
||||
and will be sent to a program which might be confused by the
|
||||
`\|\c
|
||||
.B #\c
|
||||
\&\|'-lines.
|
||||
.TP
|
||||
.B \-C
|
||||
Do not discard comments: pass them through to the output file.
|
||||
Comments appearing in arguments of a macro call will be copied to the
|
||||
output before the expansion of the macro call.
|
||||
.TP
|
||||
.B \-traditional
|
||||
Try to imitate the behavior of old-fashioned C, as opposed to ANSI C.
|
||||
.TP
|
||||
.B \-trigraphs
|
||||
Process ANSI standard trigraph sequences. These are three-character
|
||||
sequences, all starting with `\|\c
|
||||
.B ??\c
|
||||
\&\|', that are defined by ANSI C to
|
||||
stand for single characters. For example, `\|\c
|
||||
.B ??/\c
|
||||
\&\|' stands for
|
||||
`\|\c
|
||||
.BR "\e" "\|',"
|
||||
so `\|\c
|
||||
.B '??/n'\c
|
||||
\&\|' is a character constant for a newline.
|
||||
Strictly speaking, the GNU C preprocessor does not support all
|
||||
programs in ANSI Standard C unless `\|\c
|
||||
.B \-trigraphs\c
|
||||
\&\|' is used, but if
|
||||
you ever notice the difference it will be with relief.
|
||||
|
||||
You don't want to know any more about trigraphs.
|
||||
.TP
|
||||
.B \-pedantic
|
||||
Issue warnings required by the ANSI C standard in certain cases such
|
||||
as when text other than a comment follows `\|\c
|
||||
.B #else\c
|
||||
\&\|' or `\|\c
|
||||
.B #endif\c
|
||||
\&\|'.
|
||||
.TP
|
||||
.B \-pedantic\-errors
|
||||
Like `\|\c
|
||||
.B \-pedantic\c
|
||||
\&\|', except that errors are produced rather than
|
||||
warnings.
|
||||
.TP
|
||||
.B \-Wtrigraphs
|
||||
Warn if any trigraphs are encountered (assuming they are enabled).
|
||||
.TP
|
||||
.B \-Wcomment
|
||||
.TP
|
||||
.B \-Wcomments
|
||||
Warn whenever a comment-start sequence `\|\c
|
||||
.B /*\c
|
||||
\&\|' appears in a comment.
|
||||
(Both forms have the same effect).
|
||||
.TP
|
||||
.B \-Wall
|
||||
Requests both `\|\c
|
||||
.B \-Wtrigraphs\c
|
||||
\&\|' and `\|\c
|
||||
.B \-Wcomment\c
|
||||
\&\|' (but not
|
||||
`\|\c
|
||||
.B \-Wtraditional\c
|
||||
\&\|').
|
||||
.TP
|
||||
.B \-Wtraditional
|
||||
Warn about certain constructs that behave differently in traditional and
|
||||
ANSI C.
|
||||
.TP
|
||||
.BI "\-I " directory\c
|
||||
\&
|
||||
Add the directory \c
|
||||
.I directory\c
|
||||
\& to the end of the list of
|
||||
directories to be searched for header files.
|
||||
This can be used to override a system header file, substituting your
|
||||
own version, since these directories are searched before the system
|
||||
header file directories. If you use more than one `\|\c
|
||||
.B \-I\c
|
||||
\&\|' option,
|
||||
the directories are scanned in left-to-right order; the standard
|
||||
system directories come after.
|
||||
.TP
|
||||
.B \-I\-
|
||||
Any directories specified with `\|\c
|
||||
.B \-I\c
|
||||
\&\|' options before the `\|\c
|
||||
.B \-I\-\c
|
||||
\&\|'
|
||||
option are searched only for the case of `\|\c
|
||||
.B #include "\c
|
||||
.I file\c
|
||||
\&"\c
|
||||
\&\|';
|
||||
they are not searched for `\|\c
|
||||
.B #include <\c
|
||||
.I file\c
|
||||
\&>\c
|
||||
\&\|'.
|
||||
|
||||
If additional directories are specified with `\|\c
|
||||
.B \-I\c
|
||||
\&\|' options after
|
||||
the `\|\c
|
||||
.B \-I\-\c
|
||||
\&\|', these directories are searched for all `\|\c
|
||||
.B #include\c
|
||||
\&\|'
|
||||
directives.
|
||||
|
||||
In addition, the `\|\c
|
||||
.B \-I\-\c
|
||||
\&\|' option inhibits the use of the current
|
||||
directory as the first search directory for `\|\c
|
||||
.B #include "\c
|
||||
.I file\c
|
||||
\&"\c
|
||||
\&\|'.
|
||||
Therefore, the current directory is searched only if it is requested
|
||||
explicitly with `\|\c
|
||||
.B \-I.\c
|
||||
\&\|'. Specifying both `\|\c
|
||||
.B \-I\-\c
|
||||
\&\|' and `\|\c
|
||||
.B \-I.\c
|
||||
\&\|'
|
||||
allows you to control precisely which directories are searched before
|
||||
the current one and which are searched after.
|
||||
.TP
|
||||
.B \-nostdinc
|
||||
Do not search the standard system directories for header files.
|
||||
Only the directories you have specified with `\|\c
|
||||
.B \-I\c
|
||||
\&\|' options
|
||||
(and the current directory, if appropriate) are searched.
|
||||
.TP
|
||||
.B \-nostdinc++
|
||||
Do not search for header files in the C++ specific standard
|
||||
directories, but do still search the other standard directories.
|
||||
(This option is used when building libg++.)
|
||||
.TP
|
||||
.BI "\-D " "name"\c
|
||||
\&
|
||||
Predefine \c
|
||||
.I name\c
|
||||
\& as a macro, with definition `\|\c
|
||||
.B 1\c
|
||||
\&\|'.
|
||||
.TP
|
||||
.BI "\-D " "name" = definition
|
||||
\&
|
||||
Predefine \c
|
||||
.I name\c
|
||||
\& as a macro, with definition \c
|
||||
.I definition\c
|
||||
\&.
|
||||
There are no restrictions on the contents of \c
|
||||
.I definition\c
|
||||
\&, but if
|
||||
you are invoking the preprocessor from a shell or shell-like program
|
||||
you may need to use the shell's quoting syntax to protect characters
|
||||
such as spaces that have a meaning in the shell syntax. If you use more than
|
||||
one `\|\c
|
||||
.B \-D\c
|
||||
\&\|' for the same
|
||||
.I name\c
|
||||
\&, the rightmost definition takes effect.
|
||||
.TP
|
||||
.BI "\-U " "name"\c
|
||||
\&
|
||||
Do not predefine \c
|
||||
.I name\c
|
||||
\&. If both `\|\c
|
||||
.B \-U\c
|
||||
\&\|' and `\|\c
|
||||
.B \-D\c
|
||||
\&\|' are
|
||||
specified for one name, the `\|\c
|
||||
.B \-U\c
|
||||
\&\|' beats the `\|\c
|
||||
.B \-D\c
|
||||
\&\|' and the name
|
||||
is not predefined.
|
||||
.TP
|
||||
.B \-undef
|
||||
Do not predefine any nonstandard macros.
|
||||
.TP
|
||||
.BI "\-A " "name(" value )
|
||||
Assert (in the same way as the \c
|
||||
.B #assert\c
|
||||
\& directive)
|
||||
the predicate \c
|
||||
.I name\c
|
||||
\& with tokenlist \c
|
||||
.I value\c
|
||||
\&. Remember to escape or quote the parentheses on
|
||||
shell command lines.
|
||||
|
||||
You can use `\|\c
|
||||
.B \-A-\c
|
||||
\&\|' to disable all predefined assertions; it also
|
||||
undefines all predefined macros.
|
||||
.TP
|
||||
.B \-dM
|
||||
Instead of outputting the result of preprocessing, output a list of
|
||||
`\|\c
|
||||
.B #define\c
|
||||
\&\|' directives for all the macros defined during the
|
||||
execution of the preprocessor, including predefined macros. This gives
|
||||
you a way of finding out what is predefined in your version of the
|
||||
preprocessor; assuming you have no file `\|\c
|
||||
.B foo.h\c
|
||||
\&\|', the command
|
||||
.sp
|
||||
.br
|
||||
touch\ foo.h;\ cpp\ \-dM\ foo.h
|
||||
.br
|
||||
.sp
|
||||
will show the values of any predefined macros.
|
||||
.TP
|
||||
.B \-dD
|
||||
Like `\|\c
|
||||
.B \-dM\c
|
||||
\&\|' except in two respects: it does \c
|
||||
.I not\c
|
||||
\& include the
|
||||
predefined macros, and it outputs \c
|
||||
.I both\c
|
||||
\& the `\|\c
|
||||
.B #define\c
|
||||
\&\|'
|
||||
directives and the result of preprocessing. Both kinds of output go to
|
||||
the standard output file.
|
||||
.PP
|
||||
.TP
|
||||
.BR \-M\ [ \-MG ]
|
||||
Instead of outputting the result of preprocessing, output a rule
|
||||
suitable for \c
|
||||
.B make\c
|
||||
\& describing the dependencies of the main
|
||||
source file. The preprocessor outputs one \c
|
||||
.B make\c
|
||||
\& rule containing
|
||||
the object file name for that source file, a colon, and the names of
|
||||
all the included files. If there are many included files then the
|
||||
rule is split into several lines using `\|\c
|
||||
.B \\\\\c
|
||||
\&\|'-newline.
|
||||
|
||||
`\|\c
|
||||
.B \-MG\c
|
||||
\&\|' says to treat missing header files as generated files and assume \c
|
||||
they live in the same directory as the source file. It must be specified \c
|
||||
in addition to `\|\c
|
||||
.B \-M\c
|
||||
\&\|'.
|
||||
|
||||
This feature is used in automatic updating of makefiles.
|
||||
.TP
|
||||
.BR \-MM\ [ \-MG ]
|
||||
Like `\|\c
|
||||
.B \-M\c
|
||||
\&\|' but mention only the files included with `\|\c
|
||||
.B #include
|
||||
"\c
|
||||
.I file\c
|
||||
\&"\c
|
||||
\&\|'. System header files included with `\|\c
|
||||
.B #include
|
||||
<\c
|
||||
.I file\c
|
||||
\&>\c
|
||||
\&\|' are omitted.
|
||||
.TP
|
||||
.BI \-MD\ file
|
||||
Like `\|\c
|
||||
.B \-M\c
|
||||
\&\|' but the dependency information is written to `\|\c
|
||||
.I file\c
|
||||
\&\|'. This is in addition to compiling the file as
|
||||
specified\(em\&`\|\c
|
||||
.B \-MD\c
|
||||
\&\|' does not inhibit ordinary compilation the way
|
||||
`\|\c
|
||||
.B \-M\c
|
||||
\&\|' does.
|
||||
|
||||
When invoking gcc, do not specify the `\|\c
|
||||
.I file\c
|
||||
\&\|' argument. Gcc will create file names made by replacing `\|\c
|
||||
.B .c\c
|
||||
\&\|' with `\|\c
|
||||
.B .d\c
|
||||
\&\|' at the end of the input file names.
|
||||
|
||||
In Mach, you can use the utility \c
|
||||
.B md\c
|
||||
\& to merge multiple files
|
||||
into a single dependency file suitable for using with the `\|\c
|
||||
.B make\c
|
||||
\&\|'
|
||||
command.
|
||||
.TP
|
||||
.BI \-MMD\ file
|
||||
Like `\|\c
|
||||
.B \-MD\c
|
||||
\&\|' except mention only user header files, not system
|
||||
header files.
|
||||
.TP
|
||||
.B \-H
|
||||
Print the name of each header file used, in addition to other normal
|
||||
activities.
|
||||
.TP
|
||||
.BI "\-imacros " "file"\c
|
||||
\&
|
||||
Process \c
|
||||
.I file\c
|
||||
\& as input, discarding the resulting output, before
|
||||
processing the regular input file. Because the output generated from
|
||||
\c
|
||||
.I file\c
|
||||
\& is discarded, the only effect of `\|\c
|
||||
.B \-imacros \c
|
||||
.I file\c
|
||||
\&\c
|
||||
\&\|' is to
|
||||
make the macros defined in \c
|
||||
.I file\c
|
||||
\& available for use in the main
|
||||
input. The preprocessor evaluates any `\|\c
|
||||
.B \-D\c
|
||||
\&\|' and `\|\c
|
||||
.B \-U\c
|
||||
\&\|' options
|
||||
on the command line before processing `\|\c
|
||||
.B \-imacros \c
|
||||
.I file\c
|
||||
\&\|' \c
|
||||
\&.
|
||||
.TP
|
||||
.BI "\-include " "file"
|
||||
Process
|
||||
.I file
|
||||
as input, and include all the resulting output,
|
||||
before processing the regular input file.
|
||||
.TP
|
||||
.BI "-idirafter " "dir"\c
|
||||
\&
|
||||
Add the directory \c
|
||||
.I dir\c
|
||||
\& to the second include path. The directories
|
||||
on the second include path are searched when a header file is not found
|
||||
in any of the directories in the main include path (the one that
|
||||
`\|\c
|
||||
.B \-I\c
|
||||
\&\|' adds to).
|
||||
.TP
|
||||
.BI "-iprefix " "prefix"\c
|
||||
\&
|
||||
Specify \c
|
||||
.I prefix\c
|
||||
\& as the prefix for subsequent `\|\c
|
||||
.B \-iwithprefix\c
|
||||
\&\|'
|
||||
options.
|
||||
.TP
|
||||
.BI "-iwithprefix " "dir"\c
|
||||
\&
|
||||
Add a directory to the second include path. The directory's name is
|
||||
made by concatenating \c
|
||||
.I prefix\c
|
||||
\& and \c
|
||||
.I dir\c
|
||||
\&, where \c
|
||||
.I prefix\c
|
||||
\&
|
||||
was specified previously with `\|\c
|
||||
.B \-iprefix\c
|
||||
\&\|'.
|
||||
.TP
|
||||
.B \-lang-c
|
||||
.TP
|
||||
.B \-lang-c++
|
||||
.TP
|
||||
.B \-lang-objc
|
||||
.TP
|
||||
.B \-lang-objc++
|
||||
Specify the source language. `\|\c
|
||||
.B \-lang-c++\c
|
||||
\&\|' makes the preprocessor
|
||||
handle C++ comment syntax, and includes extra default include
|
||||
directories for C++, and `\|\c
|
||||
.B \-lang-objc\c
|
||||
\&\|' enables the Objective C
|
||||
`\|\c
|
||||
.B #import\c
|
||||
\&\|' directive. `\|\c
|
||||
.B \-lang-c\c
|
||||
\&\|' explicitly turns off both of
|
||||
these extensions, and `\|\c
|
||||
.B \-lang-objc++\c
|
||||
\&\|' enables both.
|
||||
|
||||
These options are generated by the compiler driver \c
|
||||
.B gcc\c
|
||||
\&, but not
|
||||
passed from the `\|\c
|
||||
.B gcc\c
|
||||
\&\|' command line.
|
||||
.TP
|
||||
.B \-lint
|
||||
Look for commands to the program checker \c
|
||||
.B lint\c
|
||||
\& embedded in
|
||||
comments, and emit them preceded by `\|\c
|
||||
.B #pragma lint\c
|
||||
\&\|'. For example,
|
||||
the comment `\|\c
|
||||
.B /* NOTREACHED */\c
|
||||
\&\|' becomes `\|\c
|
||||
.B #pragma lint
|
||||
NOTREACHED\c
|
||||
\&\|'.
|
||||
|
||||
This option is available only when you call \c
|
||||
.B cpp\c
|
||||
\& directly;
|
||||
\c
|
||||
.B gcc\c
|
||||
\& will not pass it from its command line.
|
||||
.TP
|
||||
.B \-$
|
||||
Forbid the use of `\|\c
|
||||
.B $\c
|
||||
\&\|' in identifiers. This was formerly required for strict conformance
|
||||
to the C Standard before the standard was corrected. \c
|
||||
|
||||
This option is available only when you call \c
|
||||
.B cpp\c
|
||||
\& directly;
|
||||
.B gcc\c
|
||||
\& will not pass it from its command line.
|
||||
.SH "SEE ALSO"
|
||||
.RB "`\|" Cpp "\|'"
|
||||
entry in
|
||||
.B info\c
|
||||
\&;
|
||||
.I The C Preprocessor\c
|
||||
, Richard M. Stallman.
|
||||
.br
|
||||
.BR gcc "(" 1 ");"
|
||||
.RB "`\|" Gcc "\|'"
|
||||
entry in
|
||||
.B info\c
|
||||
\&;
|
||||
.I
|
||||
Using and Porting GNU CC (for version 2.0)\c
|
||||
, Richard M. Stallman.
|
||||
.SH COPYING
|
||||
Copyright (c) 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
.PP
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
are preserved on all copies.
|
||||
.PP
|
||||
Permission is granted to copy and distribute modified versions of this
|
||||
manual under the conditions for verbatim copying, provided that the
|
||||
entire resulting derived work is distributed under the terms of a
|
||||
permission notice identical to this one.
|
||||
.PP
|
||||
Permission is granted to copy and distribute translations of this
|
||||
manual into another language, under the above conditions for modified
|
||||
versions, except that this permission notice may be included in
|
||||
translations approved by the Free Software Foundation instead of in
|
||||
the original English.
|
146
choose-temp.c
Normal file
146
choose-temp.c
Normal file
@ -0,0 +1,146 @@
|
||||
/* Utility to pick a temporary filename prefix.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the libiberty library.
|
||||
Libiberty is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
Libiberty is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with libiberty; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* This file exports one function: choose_temp_base. */
|
||||
|
||||
/* This file lives in at least two places: libiberty and gcc.
|
||||
Don't change one without the other. */
|
||||
|
||||
#ifdef IN_GCC
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_FILE_H
|
||||
#include <sys/types.h>
|
||||
#include <sys/file.h> /* May get R_OK, etc. on some systems. */
|
||||
#endif
|
||||
|
||||
#ifndef R_OK
|
||||
#define R_OK 4
|
||||
#define W_OK 2
|
||||
#define X_OK 1
|
||||
#endif
|
||||
|
||||
#include <stdio.h> /* May get P_tmpdir. */
|
||||
|
||||
#ifdef IN_GCC
|
||||
#include "gansidecl.h"
|
||||
extern char *xmalloc ();
|
||||
#else
|
||||
#include "ansidecl.h"
|
||||
#include "libiberty.h"
|
||||
#if defined (__MSDOS__) || defined (_WIN32)
|
||||
#define DIR_SEPARATOR '\\'
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef DIR_SEPARATOR
|
||||
#define DIR_SEPARATOR '/'
|
||||
#endif
|
||||
|
||||
/* On MSDOS, write temp files in current dir
|
||||
because there's no place else we can expect to use. */
|
||||
/* ??? Although the current directory is tried as a last resort,
|
||||
this is left in so that on MSDOS it is preferred to /tmp on the
|
||||
off chance that someone requires this, since that was the previous
|
||||
behaviour. */
|
||||
#ifdef __MSDOS__
|
||||
#ifndef P_tmpdir
|
||||
#define P_tmpdir "."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Name of temporary file.
|
||||
mktemp requires 6 trailing X's. */
|
||||
#define TEMP_FILE "ccXXXXXX"
|
||||
|
||||
/* Subroutine of choose_temp_base.
|
||||
If BASE is non-NULL, return it.
|
||||
Otherwise it checks if DIR is a usable directory.
|
||||
If success, DIR is returned.
|
||||
Otherwise NULL is returned. */
|
||||
|
||||
static char *
|
||||
try (dir, base)
|
||||
char *dir, *base;
|
||||
{
|
||||
if (base != 0)
|
||||
return base;
|
||||
if (dir != 0
|
||||
&& access (dir, R_OK | W_OK | X_OK) == 0)
|
||||
return dir;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return a prefix for temporary file names or NULL if unable to find one.
|
||||
The current directory is chosen if all else fails so the program is
|
||||
exited if a temporary directory can't be found (mktemp fails).
|
||||
The buffer for the result is obtained with xmalloc. */
|
||||
|
||||
char *
|
||||
choose_temp_base ()
|
||||
{
|
||||
char *base = 0;
|
||||
char *temp_filename;
|
||||
int len;
|
||||
static char tmp[] = { DIR_SEPARATOR, 't', 'm', 'p', 0 };
|
||||
static char usrtmp[] = { DIR_SEPARATOR, 'u', 's', 'r', DIR_SEPARATOR, 't', 'm', 'p', 0 };
|
||||
|
||||
#ifndef MPW
|
||||
base = try (getenv ("TMPDIR"), base);
|
||||
base = try (getenv ("TMP"), base);
|
||||
base = try (getenv ("TEMP"), base);
|
||||
|
||||
#ifdef P_tmpdir
|
||||
base = try (P_tmpdir, base);
|
||||
#endif
|
||||
|
||||
/* Try /usr/tmp, then /tmp. */
|
||||
base = try (usrtmp, base);
|
||||
base = try (tmp, base);
|
||||
|
||||
/* If all else fails, use the current directory! */
|
||||
if (base == 0)
|
||||
base = ".";
|
||||
|
||||
#else /* MPW */
|
||||
base = ":";
|
||||
#endif
|
||||
|
||||
len = strlen (base);
|
||||
temp_filename = xmalloc (len + 1 /*DIR_SEPARATOR*/
|
||||
+ strlen (TEMP_FILE) + 1);
|
||||
strcpy (temp_filename, base);
|
||||
|
||||
#ifndef MPW
|
||||
if (len != 0
|
||||
&& temp_filename[len-1] != '/'
|
||||
&& temp_filename[len-1] != DIR_SEPARATOR)
|
||||
temp_filename[len++] = DIR_SEPARATOR;
|
||||
#else /* MPW */
|
||||
if (temp_filename[len-1] != ':')
|
||||
temp_filename[len++] = ':';
|
||||
#endif /* MPW */
|
||||
strcpy (temp_filename + len, TEMP_FILE);
|
||||
|
||||
mktemp (temp_filename);
|
||||
if (strlen (temp_filename) == 0)
|
||||
abort ();
|
||||
return temp_filename;
|
||||
}
|
3484
collect2.c
Normal file
3484
collect2.c
Normal file
File diff suppressed because it is too large
Load Diff
118
conditions.h
Normal file
118
conditions.h
Normal file
@ -0,0 +1,118 @@
|
||||
/* Definitions for condition code handling in final.c and output routines.
|
||||
Copyright (C) 1987 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* None of the things in the files exist if we don't use CC0. */
|
||||
|
||||
#ifdef HAVE_cc0
|
||||
|
||||
/* The variable cc_status says how to interpret the condition code.
|
||||
It is set by output routines for an instruction that sets the cc's
|
||||
and examined by output routines for jump instructions.
|
||||
|
||||
cc_status contains two components named `value1' and `value2'
|
||||
that record two equivalent expressions for the values that the
|
||||
condition codes were set from. (Either or both may be null if
|
||||
there is no useful expression to record.) These fields are
|
||||
used for eliminating redundant test and compare instructions
|
||||
in the cases where the condition codes were already set by the
|
||||
previous instruction.
|
||||
|
||||
cc_status.flags contains flags which say that the condition codes
|
||||
were set in a nonstandard manner. The output of jump instructions
|
||||
uses these flags to compensate and produce the standard result
|
||||
with the nonstandard condition codes. Standard flags are defined here.
|
||||
The tm.h file can also define other machine-dependent flags.
|
||||
|
||||
cc_status also contains a machine-dependent component `mdep'
|
||||
whose type, `CC_STATUS_MDEP', may be defined as a macro in the
|
||||
tm.h file. */
|
||||
|
||||
#ifndef CC_STATUS_MDEP
|
||||
#define CC_STATUS_MDEP int
|
||||
#endif
|
||||
|
||||
#ifndef CC_STATUS_MDEP_INIT
|
||||
#define CC_STATUS_MDEP_INIT 0
|
||||
#endif
|
||||
|
||||
typedef struct {int flags; rtx value1, value2; CC_STATUS_MDEP mdep;} CC_STATUS;
|
||||
|
||||
/* While outputting an insn as assembler code,
|
||||
this is the status BEFORE that insn. */
|
||||
extern CC_STATUS cc_prev_status;
|
||||
|
||||
/* While outputting an insn as assembler code,
|
||||
this is being altered to the status AFTER that insn. */
|
||||
extern CC_STATUS cc_status;
|
||||
|
||||
/* These are the machine-independent flags: */
|
||||
|
||||
/* Set if the sign of the cc value is inverted:
|
||||
output a following jump-if-less as a jump-if-greater, etc. */
|
||||
#define CC_REVERSED 1
|
||||
|
||||
/* This bit means that the current setting of the N bit is bogus
|
||||
and conditional jumps should use the Z bit in its place.
|
||||
This state obtains when an extraction of a signed single-bit field
|
||||
or an arithmetic shift right of a byte by 7 bits
|
||||
is turned into a btst, because btst does not set the N bit. */
|
||||
#define CC_NOT_POSITIVE 2
|
||||
|
||||
/* This bit means that the current setting of the N bit is bogus
|
||||
and conditional jumps should pretend that the N bit is clear.
|
||||
Used after extraction of an unsigned bit
|
||||
or logical shift right of a byte by 7 bits is turned into a btst.
|
||||
The btst does not alter the N bit, but the result of that shift
|
||||
or extract is never negative. */
|
||||
#define CC_NOT_NEGATIVE 4
|
||||
|
||||
/* This bit means that the current setting of the overflow flag
|
||||
is bogus and conditional jumps should pretend there is no overflow. */
|
||||
/* ??? Note that for most targets this macro is misnamed as it applies
|
||||
to the carry flag, not the overflow flag. */
|
||||
#define CC_NO_OVERFLOW 010
|
||||
|
||||
/* This bit means that what ought to be in the Z bit
|
||||
should be tested as the complement of the N bit. */
|
||||
#define CC_Z_IN_NOT_N 020
|
||||
|
||||
/* This bit means that what ought to be in the Z bit
|
||||
should be tested as the N bit. */
|
||||
#define CC_Z_IN_N 040
|
||||
|
||||
/* Nonzero if we must invert the sense of the following branch, i.e.
|
||||
change EQ to NE. This is not safe for IEEE floating point operations!
|
||||
It is intended for use only when a combination of arithmetic
|
||||
or logical insns can leave the condition codes set in a fortuitous
|
||||
(though inverted) state. */
|
||||
#define CC_INVERTED 0100
|
||||
|
||||
/* Nonzero if we must convert signed condition operators to unsigned.
|
||||
This is only used by machine description files. */
|
||||
#define CC_NOT_SIGNED 0200
|
||||
|
||||
/* This is how to initialize the variable cc_status.
|
||||
final does this at appropriate moments. */
|
||||
|
||||
#define CC_STATUS_INIT \
|
||||
(cc_status.flags = 0, cc_status.value1 = 0, cc_status.value2 = 0, \
|
||||
CC_STATUS_MDEP_INIT)
|
||||
|
||||
#endif
|
890
config.guess
vendored
Normal file
890
config.guess
vendored
Normal file
@ -0,0 +1,890 @@
|
||||
#! /bin/sh
|
||||
# Attempt to guess a canonical system name.
|
||||
# Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# Written by Per Bothner <bothner@cygnus.com>.
|
||||
# The master version of this file is at the FSF in /home/gd/gnu/lib.
|
||||
#
|
||||
# This script attempts to guess a canonical system name similar to
|
||||
# config.sub. If it succeeds, it prints the system name on stdout, and
|
||||
# exits with 0. Otherwise, it exits with 1.
|
||||
#
|
||||
# The plan is that this can be called by configure scripts if you
|
||||
# don't specify an explicit system type (host/target name).
|
||||
#
|
||||
# Only a few systems have been added to this list; please add others
|
||||
# (but try to keep the structure clean).
|
||||
#
|
||||
|
||||
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
|
||||
# (ghazi@noc.rutgers.edu 8/24/94.)
|
||||
if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
|
||||
PATH=$PATH:/.attbin ; export PATH
|
||||
fi
|
||||
|
||||
UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
|
||||
UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
|
||||
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
|
||||
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
|
||||
|
||||
trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
|
||||
|
||||
# Note: order is significant - the case branches are not exclusive.
|
||||
|
||||
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
alpha:OSF1:*:*)
|
||||
if test $UNAME_RELEASE = "V4.0"; then
|
||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
|
||||
fi
|
||||
# A Vn.n version is a released version.
|
||||
# A Tn.n version is a released field test version.
|
||||
# A Xn.n version is an unreleased experimental baselevel.
|
||||
# 1.2 uses "1.2" for uname -r.
|
||||
cat <<EOF >dummy.s
|
||||
.globl main
|
||||
.ent main
|
||||
main:
|
||||
.frame \$30,0,\$26,0
|
||||
.prologue 0
|
||||
.long 0x47e03d80 # implver $0
|
||||
lda \$2,259
|
||||
.long 0x47e20c21 # amask $2,$1
|
||||
srl \$1,8,\$2
|
||||
sll \$2,2,\$2
|
||||
sll \$0,3,\$0
|
||||
addl \$1,\$0,\$0
|
||||
addl \$2,\$0,\$0
|
||||
ret \$31,(\$26),1
|
||||
.end main
|
||||
EOF
|
||||
${CC-cc} dummy.s -o dummy 2>/dev/null
|
||||
if test "$?" = 0 ; then
|
||||
./dummy
|
||||
case "$?" in
|
||||
7)
|
||||
UNAME_MACHINE="alpha"
|
||||
;;
|
||||
15)
|
||||
UNAME_MACHINE="alphaev5"
|
||||
;;
|
||||
14)
|
||||
UNAME_MACHINE="alphaev56"
|
||||
;;
|
||||
10)
|
||||
UNAME_MACHINE="alphapca56"
|
||||
;;
|
||||
16)
|
||||
UNAME_MACHINE="alphaev6"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
rm -f dummy.s dummy
|
||||
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]`
|
||||
exit 0 ;;
|
||||
21064:Windows_NT:50:3)
|
||||
echo alpha-dec-winnt3.5
|
||||
exit 0 ;;
|
||||
Amiga*:UNIX_System_V:4.0:*)
|
||||
echo m68k-cbm-sysv4
|
||||
exit 0;;
|
||||
amiga:NetBSD:*:*)
|
||||
echo m68k-cbm-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
amiga:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
arc64:OpenBSD:*:*)
|
||||
echo mips64el-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
arc:OpenBSD:*:*)
|
||||
echo mipsel-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
hkmips:OpenBSD:*:*)
|
||||
echo mips-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
pmax:OpenBSD:*:*)
|
||||
echo mipsel-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sgi:OpenBSD:*:*)
|
||||
echo mips-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
wgrisc:OpenBSD:*:*)
|
||||
echo mipsel-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
|
||||
echo arm-acorn-riscix${UNAME_RELEASE}
|
||||
exit 0;;
|
||||
arm32:NetBSD:*:*)
|
||||
echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
|
||||
exit 0 ;;
|
||||
SR2?01:HI-UX/MPP:*:*)
|
||||
echo hppa1.1-hitachi-hiuxmpp
|
||||
exit 0;;
|
||||
Pyramid*:OSx*:*:*|MIS*:OSx*:*:*)
|
||||
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
|
||||
if test "`(/bin/universe) 2>/dev/null`" = att ; then
|
||||
echo pyramid-pyramid-sysv3
|
||||
else
|
||||
echo pyramid-pyramid-bsd
|
||||
fi
|
||||
exit 0 ;;
|
||||
NILE:*:*:dcosx)
|
||||
echo pyramid-pyramid-svr4
|
||||
exit 0 ;;
|
||||
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
|
||||
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit 0 ;;
|
||||
i86pc:SunOS:5.*:*)
|
||||
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit 0 ;;
|
||||
sun4*:SunOS:6*:*)
|
||||
# According to config.sub, this is the proper way to canonicalize
|
||||
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
|
||||
# it's likely to be more like Solaris than SunOS4.
|
||||
echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit 0 ;;
|
||||
sun4*:SunOS:*:*)
|
||||
case "`/usr/bin/arch -k`" in
|
||||
Series*|S4*)
|
||||
UNAME_RELEASE=`uname -v`
|
||||
;;
|
||||
esac
|
||||
# Japanese Language versions have a version number like `4.1.3-JL'.
|
||||
echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
|
||||
exit 0 ;;
|
||||
sun3*:SunOS:*:*)
|
||||
echo m68k-sun-sunos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sun*:*:4.2BSD:*)
|
||||
UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
|
||||
test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
|
||||
case "`/bin/arch`" in
|
||||
sun3)
|
||||
echo m68k-sun-sunos${UNAME_RELEASE}
|
||||
;;
|
||||
sun4)
|
||||
echo sparc-sun-sunos${UNAME_RELEASE}
|
||||
;;
|
||||
esac
|
||||
exit 0 ;;
|
||||
aushp:SunOS:*:*)
|
||||
echo sparc-auspex-sunos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
atari*:NetBSD:*:*)
|
||||
echo m68k-atari-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
atari*:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sun3*:NetBSD:*:*)
|
||||
echo m68k-sun-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sun3*:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mac68k:NetBSD:*:*)
|
||||
echo m68k-apple-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mac68k:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mvme68k:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mvme88k:OpenBSD:*:*)
|
||||
echo m88k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
powerpc:machten:*:*)
|
||||
echo powerpc-apple-machten${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
RISC*:Mach:*:*)
|
||||
echo mips-dec-mach_bsd4.3
|
||||
exit 0 ;;
|
||||
RISC*:ULTRIX:*:*)
|
||||
echo mips-dec-ultrix${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
VAX*:ULTRIX*:*:*)
|
||||
echo vax-dec-ultrix${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
2020:CLIX:*:*)
|
||||
echo clipper-intergraph-clix${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mips:*:*:UMIPS | mips:*:*:RISCos)
|
||||
sed 's/^ //' << EOF >dummy.c
|
||||
int main (argc, argv) int argc; char **argv; {
|
||||
#if defined (host_mips) && defined (MIPSEB)
|
||||
#if defined (SYSTYPE_SYSV)
|
||||
printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
|
||||
#endif
|
||||
#if defined (SYSTYPE_SVR4)
|
||||
printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
|
||||
#endif
|
||||
#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
|
||||
printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
|
||||
#endif
|
||||
#endif
|
||||
exit (-1);
|
||||
}
|
||||
EOF
|
||||
${CC-cc} dummy.c -o dummy \
|
||||
&& ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
|
||||
&& rm dummy.c dummy && exit 0
|
||||
rm -f dummy.c dummy
|
||||
echo mips-mips-riscos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
Night_Hawk:Power_UNIX:*:*)
|
||||
echo powerpc-harris-powerunix
|
||||
exit 0 ;;
|
||||
m88k:CX/UX:7*:*)
|
||||
echo m88k-harris-cxux7
|
||||
exit 0 ;;
|
||||
m88k:*:4*:R4*)
|
||||
echo m88k-motorola-sysv4
|
||||
exit 0 ;;
|
||||
m88k:*:3*:R3*)
|
||||
echo m88k-motorola-sysv3
|
||||
exit 0 ;;
|
||||
AViiON:dgux:*:*)
|
||||
# DG/UX returns AViiON for all architectures
|
||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
||||
if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
|
||||
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
|
||||
-o ${TARGET_BINARY_INTERFACE}x = x ] ; then
|
||||
echo m88k-dg-dgux${UNAME_RELEASE}
|
||||
else
|
||||
echo m88k-dg-dguxbcs${UNAME_RELEASE}
|
||||
fi
|
||||
else echo i586-dg-dgux${UNAME_RELEASE}
|
||||
fi
|
||||
exit 0 ;;
|
||||
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
|
||||
echo m88k-dolphin-sysv3
|
||||
exit 0 ;;
|
||||
M88*:*:R3*:*)
|
||||
# Delta 88k system running SVR3
|
||||
echo m88k-motorola-sysv3
|
||||
exit 0 ;;
|
||||
XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
|
||||
echo m88k-tektronix-sysv3
|
||||
exit 0 ;;
|
||||
Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
|
||||
echo m68k-tektronix-bsd
|
||||
exit 0 ;;
|
||||
*:IRIX*:*:*)
|
||||
echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
|
||||
exit 0 ;;
|
||||
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
|
||||
echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
|
||||
exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
|
||||
i?86:AIX:*:*)
|
||||
echo i386-ibm-aix
|
||||
exit 0 ;;
|
||||
*:AIX:2:3)
|
||||
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
|
||||
sed 's/^ //' << EOF >dummy.c
|
||||
#include <sys/systemcfg.h>
|
||||
|
||||
main()
|
||||
{
|
||||
if (!__power_pc())
|
||||
exit(1);
|
||||
puts("powerpc-ibm-aix3.2.5");
|
||||
exit(0);
|
||||
}
|
||||
EOF
|
||||
${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
|
||||
rm -f dummy.c dummy
|
||||
echo rs6000-ibm-aix3.2.5
|
||||
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
|
||||
echo rs6000-ibm-aix3.2.4
|
||||
else
|
||||
echo rs6000-ibm-aix3.2
|
||||
fi
|
||||
exit 0 ;;
|
||||
*:AIX:*:4)
|
||||
if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
|
||||
IBM_ARCH=rs6000
|
||||
else
|
||||
IBM_ARCH=powerpc
|
||||
fi
|
||||
if [ -x /usr/bin/oslevel ] ; then
|
||||
IBM_REV=`/usr/bin/oslevel`
|
||||
else
|
||||
IBM_REV=4.${UNAME_RELEASE}
|
||||
fi
|
||||
echo ${IBM_ARCH}-ibm-aix${IBM_REV}
|
||||
exit 0 ;;
|
||||
*:AIX:*:*)
|
||||
echo rs6000-ibm-aix
|
||||
exit 0 ;;
|
||||
ibmrt:4.4BSD:*|romp-ibm:BSD:*)
|
||||
echo romp-ibm-bsd4.4
|
||||
exit 0 ;;
|
||||
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and
|
||||
echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
|
||||
exit 0 ;; # report: romp-ibm BSD 4.3
|
||||
*:BOSX:*:*)
|
||||
echo rs6000-bull-bosx
|
||||
exit 0 ;;
|
||||
DPX/2?00:B.O.S.:*:*)
|
||||
echo m68k-bull-sysv3
|
||||
exit 0 ;;
|
||||
9000/[34]??:4.3bsd:1.*:*)
|
||||
echo m68k-hp-bsd
|
||||
exit 0 ;;
|
||||
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
|
||||
echo m68k-hp-bsd4.4
|
||||
exit 0 ;;
|
||||
9000/[3478]??:HP-UX:*:*)
|
||||
case "${UNAME_MACHINE}" in
|
||||
9000/31? ) HP_ARCH=m68000 ;;
|
||||
9000/[34]?? ) HP_ARCH=m68k ;;
|
||||
9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;;
|
||||
9000/8?? ) HP_ARCH=hppa1.0 ;;
|
||||
esac
|
||||
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
|
||||
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
|
||||
exit 0 ;;
|
||||
3050*:HI-UX:*:*)
|
||||
sed 's/^ //' << EOF >dummy.c
|
||||
#include <unistd.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
long cpu = sysconf (_SC_CPU_VERSION);
|
||||
/* The order matters, because CPU_IS_HP_MC68K erroneously returns
|
||||
true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
|
||||
results, however. */
|
||||
if (CPU_IS_PA_RISC (cpu))
|
||||
{
|
||||
switch (cpu)
|
||||
{
|
||||
case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
|
||||
case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
|
||||
case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
|
||||
default: puts ("hppa-hitachi-hiuxwe2"); break;
|
||||
}
|
||||
}
|
||||
else if (CPU_IS_HP_MC68K (cpu))
|
||||
puts ("m68k-hitachi-hiuxwe2");
|
||||
else puts ("unknown-hitachi-hiuxwe2");
|
||||
exit (0);
|
||||
}
|
||||
EOF
|
||||
${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
|
||||
rm -f dummy.c dummy
|
||||
echo unknown-hitachi-hiuxwe2
|
||||
exit 0 ;;
|
||||
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
|
||||
echo hppa1.1-hp-bsd
|
||||
exit 0 ;;
|
||||
9000/8??:4.3bsd:*:*)
|
||||
echo hppa1.0-hp-bsd
|
||||
exit 0 ;;
|
||||
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
|
||||
echo hppa1.1-hp-osf
|
||||
exit 0 ;;
|
||||
hp8??:OSF1:*:*)
|
||||
echo hppa1.0-hp-osf
|
||||
exit 0 ;;
|
||||
i?86:OSF1:*:*)
|
||||
if [ -x /usr/sbin/sysversion ] ; then
|
||||
echo ${UNAME_MACHINE}-unknown-osf1mk
|
||||
else
|
||||
echo ${UNAME_MACHINE}-unknown-osf1
|
||||
fi
|
||||
exit 0 ;;
|
||||
parisc*:Lites*:*:*)
|
||||
echo hppa1.1-hp-lites
|
||||
exit 0 ;;
|
||||
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
|
||||
echo c1-convex-bsd
|
||||
exit 0 ;;
|
||||
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
|
||||
if getsysinfo -f scalar_acc
|
||||
then echo c32-convex-bsd
|
||||
else echo c2-convex-bsd
|
||||
fi
|
||||
exit 0 ;;
|
||||
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
|
||||
echo c34-convex-bsd
|
||||
exit 0 ;;
|
||||
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
|
||||
echo c38-convex-bsd
|
||||
exit 0 ;;
|
||||
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
|
||||
echo c4-convex-bsd
|
||||
exit 0 ;;
|
||||
CRAY*X-MP:*:*:*)
|
||||
echo xmp-cray-unicos
|
||||
exit 0 ;;
|
||||
CRAY*Y-MP:*:*:*)
|
||||
echo ymp-cray-unicos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
CRAY*[A-Z]90:*:*:*)
|
||||
echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
|
||||
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
|
||||
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
|
||||
exit 0 ;;
|
||||
CRAY*TS:*:*:*)
|
||||
echo t90-cray-unicos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
CRAY-2:*:*:*)
|
||||
echo cray2-cray-unicos
|
||||
exit 0 ;;
|
||||
F300:UNIX_System_V:*:*)
|
||||
FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
|
||||
echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit 0 ;;
|
||||
F301:UNIX_System_V:*:*)
|
||||
echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
|
||||
exit 0 ;;
|
||||
hp3[0-9][05]:NetBSD:*:*)
|
||||
echo m68k-hp-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
hp300:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
i?86:BSD/386:*:* | *:BSD/OS:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:FreeBSD:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
|
||||
exit 0 ;;
|
||||
*:NetBSD:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
|
||||
exit 0 ;;
|
||||
*:OpenBSD:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
|
||||
exit 0 ;;
|
||||
i*:CYGWIN*:*)
|
||||
echo ${UNAME_MACHINE}-pc-cygwin32
|
||||
exit 0 ;;
|
||||
i*:MINGW*:*)
|
||||
echo ${UNAME_MACHINE}-pc-mingw32
|
||||
exit 0 ;;
|
||||
p*:CYGWIN*:*)
|
||||
echo powerpcle-unknown-cygwin32
|
||||
exit 0 ;;
|
||||
prep*:SunOS:5.*:*)
|
||||
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit 0 ;;
|
||||
*:GNU:*:*)
|
||||
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
|
||||
exit 0 ;;
|
||||
*:Linux:*:*)
|
||||
# uname on the ARM produces all sorts of strangeness, and we need to
|
||||
# filter it out.
|
||||
case "$UNAME_MACHINE" in
|
||||
arm* | sa110*) UNAME_MACHINE="arm" ;;
|
||||
esac
|
||||
|
||||
# The BFD linker knows what the default object file format is, so
|
||||
# first see if it will tell us.
|
||||
ld_help_string=`ld --help 2>&1`
|
||||
ld_supported_emulations=`echo $ld_help_string \
|
||||
| sed -ne '/supported emulations:/!d
|
||||
s/[ ][ ]*/ /g
|
||||
s/.*supported emulations: *//
|
||||
s/ .*//
|
||||
p'`
|
||||
case "$ld_supported_emulations" in
|
||||
i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;;
|
||||
i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;;
|
||||
sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
|
||||
armlinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
|
||||
m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
|
||||
elf32ppc) echo "powerpc-unknown-linux-gnu" ; exit 0 ;;
|
||||
esac
|
||||
|
||||
if test "${UNAME_MACHINE}" = "alpha" ; then
|
||||
sed 's/^ //' <<EOF >dummy.s
|
||||
.globl main
|
||||
.ent main
|
||||
main:
|
||||
.frame \$30,0,\$26,0
|
||||
.prologue 0
|
||||
.long 0x47e03d80 # implver $0
|
||||
lda \$2,259
|
||||
.long 0x47e20c21 # amask $2,$1
|
||||
srl \$1,8,\$2
|
||||
sll \$2,2,\$2
|
||||
sll \$0,3,\$0
|
||||
addl \$1,\$0,\$0
|
||||
addl \$2,\$0,\$0
|
||||
ret \$31,(\$26),1
|
||||
.end main
|
||||
EOF
|
||||
LIBC=""
|
||||
${CC-cc} dummy.s -o dummy 2>/dev/null
|
||||
if test "$?" = 0 ; then
|
||||
./dummy
|
||||
case "$?" in
|
||||
7)
|
||||
UNAME_MACHINE="alpha"
|
||||
;;
|
||||
15)
|
||||
UNAME_MACHINE="alphaev5"
|
||||
;;
|
||||
14)
|
||||
UNAME_MACHINE="alphaev56"
|
||||
;;
|
||||
10)
|
||||
UNAME_MACHINE="alphapca56"
|
||||
;;
|
||||
16)
|
||||
UNAME_MACHINE="alphaev6"
|
||||
;;
|
||||
esac
|
||||
|
||||
objdump --private-headers dummy | \
|
||||
grep ld.so.1 > /dev/null
|
||||
if test "$?" = 0 ; then
|
||||
LIBC="libc1"
|
||||
fi
|
||||
fi
|
||||
rm -f dummy.s dummy
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
|
||||
elif test "${UNAME_MACHINE}" = "mips" ; then
|
||||
cat >dummy.c <<EOF
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
#ifdef __MIPSEB__
|
||||
printf ("%s-unknown-linux-gnu\n", argv[1]);
|
||||
#endif
|
||||
#ifdef __MIPSEL__
|
||||
printf ("%sel-unknown-linux-gnu\n", argv[1]);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
|
||||
rm -f dummy.c dummy
|
||||
else
|
||||
# Either a pre-BFD a.out linker (linux-gnuoldld)
|
||||
# or one that does not give us useful --help.
|
||||
# GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
|
||||
# If ld does not provide *any* "supported emulations:"
|
||||
# that means it is gnuoldld.
|
||||
echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
|
||||
test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
|
||||
|
||||
case "${UNAME_MACHINE}" in
|
||||
i?86)
|
||||
VENDOR=pc;
|
||||
;;
|
||||
*)
|
||||
VENDOR=unknown;
|
||||
;;
|
||||
esac
|
||||
# Determine whether the default compiler is a.out or elf
|
||||
cat >dummy.c <<EOF
|
||||
#include <features.h>
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
#ifdef __ELF__
|
||||
# ifdef __GLIBC__
|
||||
# if __GLIBC__ >= 2
|
||||
printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
|
||||
# else
|
||||
printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
|
||||
# endif
|
||||
# else
|
||||
printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
|
||||
# endif
|
||||
#else
|
||||
printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
|
||||
rm -f dummy.c dummy
|
||||
fi ;;
|
||||
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
|
||||
# are messed up and put the nodename in both sysname and nodename.
|
||||
i?86:DYNIX/ptx:4*:*)
|
||||
echo i386-sequent-sysv4
|
||||
exit 0 ;;
|
||||
i?86:UNIX_SV:4.2MP:2.*)
|
||||
# Unixware is an offshoot of SVR4, but it has its own version
|
||||
# number series starting with 2...
|
||||
# I am not positive that other SVR4 systems won't match this,
|
||||
# I just have to hope. -- rms.
|
||||
# Use sysv4.2uw... so that sysv4* matches it.
|
||||
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
|
||||
exit 0 ;;
|
||||
i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
|
||||
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
|
||||
echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
|
||||
else
|
||||
echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
|
||||
fi
|
||||
exit 0 ;;
|
||||
i?86:*:3.2:*)
|
||||
if test -f /usr/options/cb.name; then
|
||||
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
|
||||
echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
|
||||
elif /bin/uname -X 2>/dev/null >/dev/null ; then
|
||||
UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
|
||||
(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
|
||||
(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
|
||||
&& UNAME_MACHINE=i586
|
||||
echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
|
||||
else
|
||||
echo ${UNAME_MACHINE}-pc-sysv32
|
||||
fi
|
||||
exit 0 ;;
|
||||
pc:*:*:*)
|
||||
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
||||
# the processor, so we play safe by assuming i386.
|
||||
echo i386-pc-msdosdjgpp
|
||||
exit 0 ;;
|
||||
Intel:Mach:3*:*)
|
||||
echo i386-pc-mach3
|
||||
exit 0 ;;
|
||||
paragon:*:*:*)
|
||||
echo i860-intel-osf1
|
||||
exit 0 ;;
|
||||
i860:*:4.*:*) # i860-SVR4
|
||||
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
|
||||
echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
|
||||
else # Add other i860-SVR4 vendors below as they are discovered.
|
||||
echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
|
||||
fi
|
||||
exit 0 ;;
|
||||
mini*:CTIX:SYS*5:*)
|
||||
# "miniframe"
|
||||
echo m68010-convergent-sysv
|
||||
exit 0 ;;
|
||||
M68*:*:R3V[567]*:*)
|
||||
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
|
||||
3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
|
||||
OS_REL=''
|
||||
test -r /etc/.relid \
|
||||
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
|
||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& echo i486-ncr-sysv4.3${OS_REL} && exit 0
|
||||
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
|
||||
&& echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
|
||||
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
|
||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& echo i486-ncr-sysv4 && exit 0 ;;
|
||||
m68*:LynxOS:2.*:*)
|
||||
echo m68k-unknown-lynxos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mc68030:UNIX_System_V:4.*:*)
|
||||
echo m68k-atari-sysv4
|
||||
exit 0 ;;
|
||||
i?86:LynxOS:2.*:*)
|
||||
echo i386-unknown-lynxos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
TSUNAMI:LynxOS:2.*:*)
|
||||
echo sparc-unknown-lynxos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
|
||||
echo rs6000-unknown-lynxos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
SM[BE]S:UNIX_SV:*:*)
|
||||
echo mips-dde-sysv${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
RM*:SINIX-*:*:*)
|
||||
echo mips-sni-sysv4
|
||||
exit 0 ;;
|
||||
*:SINIX-*:*:*)
|
||||
if uname -p 2>/dev/null >/dev/null ; then
|
||||
UNAME_MACHINE=`(uname -p) 2>/dev/null`
|
||||
echo ${UNAME_MACHINE}-sni-sysv4
|
||||
else
|
||||
echo ns32k-sni-sysv
|
||||
fi
|
||||
exit 0 ;;
|
||||
PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
|
||||
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
||||
echo i586-unisys-sysv4
|
||||
exit 0 ;;
|
||||
*:UNIX_System_V:4*:FTX*)
|
||||
# From Gerald Hewes <hewes@openmarket.com>.
|
||||
# How about differentiating between stratus architectures? -djm
|
||||
echo hppa1.1-stratus-sysv4
|
||||
exit 0 ;;
|
||||
*:*:*:FTX*)
|
||||
# From seanf@swdc.stratus.com.
|
||||
echo i860-stratus-sysv4
|
||||
exit 0 ;;
|
||||
mc68*:A/UX:*:*)
|
||||
echo m68k-apple-aux${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
news*:NEWS-OS:*:6*)
|
||||
echo mips-sony-newsos6
|
||||
exit 0 ;;
|
||||
R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*)
|
||||
if [ -d /usr/nec ]; then
|
||||
echo mips-nec-sysv${UNAME_RELEASE}
|
||||
else
|
||||
echo mips-unknown-sysv${UNAME_RELEASE}
|
||||
fi
|
||||
exit 0 ;;
|
||||
esac
|
||||
|
||||
#echo '(No uname command or uname output not recognized.)' 1>&2
|
||||
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
|
||||
|
||||
cat >dummy.c <<EOF
|
||||
#ifdef _SEQUENT_
|
||||
# include <sys/types.h>
|
||||
# include <sys/utsname.h>
|
||||
#endif
|
||||
main ()
|
||||
{
|
||||
#if defined (sony)
|
||||
#if defined (MIPSEB)
|
||||
/* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
|
||||
I don't know.... */
|
||||
printf ("mips-sony-bsd\n"); exit (0);
|
||||
#else
|
||||
#include <sys/param.h>
|
||||
printf ("m68k-sony-newsos%s\n",
|
||||
#ifdef NEWSOS4
|
||||
"4"
|
||||
#else
|
||||
""
|
||||
#endif
|
||||
); exit (0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined (__arm) && defined (__acorn) && defined (__unix)
|
||||
printf ("arm-acorn-riscix"); exit (0);
|
||||
#endif
|
||||
|
||||
#if defined (hp300) && !defined (hpux)
|
||||
printf ("m68k-hp-bsd\n"); exit (0);
|
||||
#endif
|
||||
|
||||
#if defined (NeXT)
|
||||
#if !defined (__ARCHITECTURE__)
|
||||
#define __ARCHITECTURE__ "m68k"
|
||||
#endif
|
||||
int version;
|
||||
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
|
||||
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
|
||||
exit (0);
|
||||
#endif
|
||||
|
||||
#if defined (MULTIMAX) || defined (n16)
|
||||
#if defined (UMAXV)
|
||||
printf ("ns32k-encore-sysv\n"); exit (0);
|
||||
#else
|
||||
#if defined (CMU)
|
||||
printf ("ns32k-encore-mach\n"); exit (0);
|
||||
#else
|
||||
printf ("ns32k-encore-bsd\n"); exit (0);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined (__386BSD__)
|
||||
printf ("i386-pc-bsd\n"); exit (0);
|
||||
#endif
|
||||
|
||||
#if defined (sequent)
|
||||
#if defined (i386)
|
||||
printf ("i386-sequent-dynix\n"); exit (0);
|
||||
#endif
|
||||
#if defined (ns32000)
|
||||
printf ("ns32k-sequent-dynix\n"); exit (0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined (_SEQUENT_)
|
||||
struct utsname un;
|
||||
|
||||
uname(&un);
|
||||
|
||||
if (strncmp(un.version, "V2", 2) == 0) {
|
||||
printf ("i386-sequent-ptx2\n"); exit (0);
|
||||
}
|
||||
if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
|
||||
printf ("i386-sequent-ptx1\n"); exit (0);
|
||||
}
|
||||
printf ("i386-sequent-ptx\n"); exit (0);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined (vax)
|
||||
#if !defined (ultrix)
|
||||
printf ("vax-dec-bsd\n"); exit (0);
|
||||
#else
|
||||
printf ("vax-dec-ultrix\n"); exit (0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined (alliant) && defined (i860)
|
||||
printf ("i860-alliant-bsd\n"); exit (0);
|
||||
#endif
|
||||
|
||||
exit (1);
|
||||
}
|
||||
EOF
|
||||
|
||||
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
|
||||
rm -f dummy.c dummy
|
||||
|
||||
# Apollos put the system type in the environment.
|
||||
|
||||
test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
|
||||
|
||||
# Convex versions that predate uname can use getsysinfo(1)
|
||||
|
||||
if [ -x /usr/convex/getsysinfo ]
|
||||
then
|
||||
case `getsysinfo -f cpu_type` in
|
||||
c1*)
|
||||
echo c1-convex-bsd
|
||||
exit 0 ;;
|
||||
c2*)
|
||||
if getsysinfo -f scalar_acc
|
||||
then echo c32-convex-bsd
|
||||
else echo c2-convex-bsd
|
||||
fi
|
||||
exit 0 ;;
|
||||
c34*)
|
||||
echo c34-convex-bsd
|
||||
exit 0 ;;
|
||||
c38*)
|
||||
echo c38-convex-bsd
|
||||
exit 0 ;;
|
||||
c4*)
|
||||
echo c4-convex-bsd
|
||||
exit 0 ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
#echo '(Unable to guess system type)' 1>&2
|
||||
|
||||
exit 1
|
114
config.in
Normal file
114
config.in
Normal file
@ -0,0 +1,114 @@
|
||||
/* config.in. Generated automatically from configure.in by autoheader. */
|
||||
/* Define if you have a working <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Whether malloc must be declared even if <stdlib.h> is included. */
|
||||
#undef NEED_DECLARATION_MALLOC
|
||||
|
||||
/* Whether realloc must be declared even if <stdlib.h> is included. */
|
||||
#undef NEED_DECLARATION_REALLOC
|
||||
|
||||
/* Whether calloc must be declared even if <stdlib.h> is included. */
|
||||
#undef NEED_DECLARATION_CALLOC
|
||||
|
||||
/* Whether free must be declared even if <stdlib.h> is included. */
|
||||
#undef NEED_DECLARATION_FREE
|
||||
|
||||
/* Whether index must be declared even if <stdlib.h> is included. */
|
||||
#undef NEED_DECLARATION_INDEX
|
||||
|
||||
/* Whether rindex must be declared even if <stdlib.h> is included. */
|
||||
#undef NEED_DECLARATION_RINDEX
|
||||
|
||||
/* Whether getenv must be declared even if <stdlib.h> is included. */
|
||||
#undef NEED_DECLARATION_GETENV
|
||||
|
||||
/* Whether sbrk must be declared even if <stdlib.h> is included. */
|
||||
#undef NEED_DECLARATION_SBRK
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Define if `sys_siglist' is declared by <signal.h>. */
|
||||
#undef SYS_SIGLIST_DECLARED
|
||||
|
||||
/* Define if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#undef TIME_WITH_SYS_TIME
|
||||
|
||||
/* Define if you have the bcmp function. */
|
||||
#undef HAVE_BCMP
|
||||
|
||||
/* Define if you have the bcopy function. */
|
||||
#undef HAVE_BCOPY
|
||||
|
||||
/* Define if you have the bzero function. */
|
||||
#undef HAVE_BZERO
|
||||
|
||||
/* Define if you have the getrlimit function. */
|
||||
#undef HAVE_GETRLIMIT
|
||||
|
||||
/* Define if you have the index function. */
|
||||
#undef HAVE_INDEX
|
||||
|
||||
/* Define if you have the kill function. */
|
||||
#undef HAVE_KILL
|
||||
|
||||
/* Define if you have the popen function. */
|
||||
#undef HAVE_POPEN
|
||||
|
||||
/* Define if you have the putenv function. */
|
||||
#undef HAVE_PUTENV
|
||||
|
||||
/* Define if you have the rindex function. */
|
||||
#undef HAVE_RINDEX
|
||||
|
||||
/* Define if you have the setrlimit function. */
|
||||
#undef HAVE_SETRLIMIT
|
||||
|
||||
/* Define if you have the strerror function. */
|
||||
#undef HAVE_STRERROR
|
||||
|
||||
/* Define if you have the sysconf function. */
|
||||
#undef HAVE_SYSCONF
|
||||
|
||||
/* Define if you have the vprintf function. */
|
||||
#undef HAVE_VPRINTF
|
||||
|
||||
/* Define if you have the <fcntl.h> header file. */
|
||||
#undef HAVE_FCNTL_H
|
||||
|
||||
/* Define if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Define if you have the <stddef.h> header file. */
|
||||
#undef HAVE_STDDEF_H
|
||||
|
||||
/* Define if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define if you have the <sys/file.h> header file. */
|
||||
#undef HAVE_SYS_FILE_H
|
||||
|
||||
/* Define if you have the <sys/param.h> header file. */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
/* Define if you have the <sys/resource.h> header file. */
|
||||
#undef HAVE_SYS_RESOURCE_H
|
||||
|
||||
/* Define if you have the <sys/time.h> header file. */
|
||||
#undef HAVE_SYS_TIME_H
|
||||
|
||||
/* Define if you have the <sys/times.h> header file. */
|
||||
#undef HAVE_SYS_TIMES_H
|
||||
|
||||
/* Define if you have the <time.h> header file. */
|
||||
#undef HAVE_TIME_H
|
||||
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
952
config.sub
vendored
Normal file
952
config.sub
vendored
Normal file
@ -0,0 +1,952 @@
|
||||
#! /bin/sh
|
||||
# Configuration validation subroutine script, version 1.1.
|
||||
# Copyright (C) 1991, 92-97, 1998 Free Software Foundation, Inc.
|
||||
# This file is (in principle) common to ALL GNU software.
|
||||
# The presence of a machine in this file suggests that SOME GNU software
|
||||
# can handle that machine. It does not imply ALL GNU software can.
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# Configuration subroutine to validate and canonicalize a configuration type.
|
||||
# Supply the specified configuration type as an argument.
|
||||
# If it is invalid, we print an error message on stderr and exit with code 1.
|
||||
# Otherwise, we print the canonical config type on stdout and succeed.
|
||||
|
||||
# This file is supposed to be the same for all GNU packages
|
||||
# and recognize all the CPU types, system types and aliases
|
||||
# that are meaningful with *any* GNU software.
|
||||
# Each package is responsible for reporting which valid configurations
|
||||
# it does not support. The user should be able to distinguish
|
||||
# a failure to support a valid configuration from a meaningless
|
||||
# configuration.
|
||||
|
||||
# The goal of this file is to map all the various variations of a given
|
||||
# machine specification into a single specification in the form:
|
||||
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
|
||||
# or in some cases, the newer four-part form:
|
||||
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
|
||||
# It is wrong to echo any other type of specification.
|
||||
|
||||
if [ x$1 = x ]
|
||||
then
|
||||
echo Configuration name missing. 1>&2
|
||||
echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
|
||||
echo "or $0 ALIAS" 1>&2
|
||||
echo where ALIAS is a recognized configuration type. 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# First pass through any local machine types.
|
||||
case $1 in
|
||||
*local*)
|
||||
echo $1
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
|
||||
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
|
||||
# Here we must recognize all the valid KERNEL-OS combinations.
|
||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||
case $maybe_os in
|
||||
linux-gnu*)
|
||||
os=-$maybe_os
|
||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
||||
;;
|
||||
*)
|
||||
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
|
||||
if [ $basic_machine != $1 ]
|
||||
then os=`echo $1 | sed 's/.*-/-/'`
|
||||
else os=; fi
|
||||
;;
|
||||
esac
|
||||
|
||||
### Let's recognize common machines as not being operating systems so
|
||||
### that things like config.sub decstation-3100 work. We also
|
||||
### recognize some manufacturers as not being operating systems, so we
|
||||
### can provide default operating systems below.
|
||||
case $os in
|
||||
-sun*os*)
|
||||
# Prevent following clause from handling this invalid input.
|
||||
;;
|
||||
-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
|
||||
-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
|
||||
-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
|
||||
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
|
||||
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
|
||||
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
|
||||
-apple)
|
||||
os=
|
||||
basic_machine=$1
|
||||
;;
|
||||
-hiux*)
|
||||
os=-hiuxwe2
|
||||
;;
|
||||
-sco5)
|
||||
os=sco3.2v5
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-sco4)
|
||||
os=-sco3.2v4
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-sco3.2.[4-9]*)
|
||||
os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-sco3.2v[4-9]*)
|
||||
# Don't forget version if it is 3.2v4 or newer.
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-sco*)
|
||||
os=-sco3.2v2
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-isc)
|
||||
os=-isc2.2
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-clix*)
|
||||
basic_machine=clipper-intergraph
|
||||
;;
|
||||
-isc*)
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-lynx*)
|
||||
os=-lynxos
|
||||
;;
|
||||
-ptx*)
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
|
||||
;;
|
||||
-windowsnt*)
|
||||
os=`echo $os | sed -e 's/windowsnt/winnt/'`
|
||||
;;
|
||||
-psos*)
|
||||
os=-psos
|
||||
;;
|
||||
esac
|
||||
|
||||
# Decode aliases for certain CPU-COMPANY combinations.
|
||||
case $basic_machine in
|
||||
# Recognize the basic CPU types without company name.
|
||||
# Some are omitted here because they have special meanings below.
|
||||
tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
|
||||
| arme[lb] | pyramid | mn10200 | mn10300 \
|
||||
| tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \
|
||||
| alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \
|
||||
| i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
|
||||
| mips64 | mipsel | mips64el | mips64orion | mips64orionel \
|
||||
| mipstx39 | mipstx39el \
|
||||
| sparc | sparclet | sparclite | sparc64 | v850)
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
# We use `pc' rather than `unknown'
|
||||
# because (1) that's what they normally are, and
|
||||
# (2) the word "unknown" tends to confuse beginning users.
|
||||
i[34567]86)
|
||||
basic_machine=$basic_machine-pc
|
||||
;;
|
||||
# Object if more than one company name word.
|
||||
*-*-*)
|
||||
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
|
||||
exit 1
|
||||
;;
|
||||
# Recognize the basic CPU types with company name.
|
||||
vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \
|
||||
| m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
|
||||
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
|
||||
| power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \
|
||||
| xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* \
|
||||
| alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \
|
||||
| ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \
|
||||
| sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
|
||||
| sparc64-* | mips64-* | mipsel-* \
|
||||
| mips64el-* | mips64orion-* | mips64orionel-* \
|
||||
| mipstx39-* | mipstx39el-* \
|
||||
| f301-*)
|
||||
;;
|
||||
# Recognize the various machine names and aliases which stand
|
||||
# for a CPU type and a company and sometimes even an OS.
|
||||
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
|
||||
basic_machine=m68000-att
|
||||
;;
|
||||
3b*)
|
||||
basic_machine=we32k-att
|
||||
;;
|
||||
alliant | fx80)
|
||||
basic_machine=fx80-alliant
|
||||
;;
|
||||
altos | altos3068)
|
||||
basic_machine=m68k-altos
|
||||
;;
|
||||
am29k)
|
||||
basic_machine=a29k-none
|
||||
os=-bsd
|
||||
;;
|
||||
amdahl)
|
||||
basic_machine=580-amdahl
|
||||
os=-sysv
|
||||
;;
|
||||
amiga | amiga-*)
|
||||
basic_machine=m68k-cbm
|
||||
;;
|
||||
amigaos | amigados)
|
||||
basic_machine=m68k-cbm
|
||||
os=-amigaos
|
||||
;;
|
||||
amigaunix | amix)
|
||||
basic_machine=m68k-cbm
|
||||
os=-sysv4
|
||||
;;
|
||||
apollo68)
|
||||
basic_machine=m68k-apollo
|
||||
os=-sysv
|
||||
;;
|
||||
aux)
|
||||
basic_machine=m68k-apple
|
||||
os=-aux
|
||||
;;
|
||||
balance)
|
||||
basic_machine=ns32k-sequent
|
||||
os=-dynix
|
||||
;;
|
||||
convex-c1)
|
||||
basic_machine=c1-convex
|
||||
os=-bsd
|
||||
;;
|
||||
convex-c2)
|
||||
basic_machine=c2-convex
|
||||
os=-bsd
|
||||
;;
|
||||
convex-c32)
|
||||
basic_machine=c32-convex
|
||||
os=-bsd
|
||||
;;
|
||||
convex-c34)
|
||||
basic_machine=c34-convex
|
||||
os=-bsd
|
||||
;;
|
||||
convex-c38)
|
||||
basic_machine=c38-convex
|
||||
os=-bsd
|
||||
;;
|
||||
cray | ymp)
|
||||
basic_machine=ymp-cray
|
||||
os=-unicos
|
||||
;;
|
||||
cray2)
|
||||
basic_machine=cray2-cray
|
||||
os=-unicos
|
||||
;;
|
||||
[ctj]90-cray)
|
||||
basic_machine=c90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
crds | unos)
|
||||
basic_machine=m68k-crds
|
||||
;;
|
||||
da30 | da30-*)
|
||||
basic_machine=m68k-da30
|
||||
;;
|
||||
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
|
||||
basic_machine=mips-dec
|
||||
;;
|
||||
delta | 3300 | motorola-3300 | motorola-delta \
|
||||
| 3300-motorola | delta-motorola)
|
||||
basic_machine=m68k-motorola
|
||||
;;
|
||||
delta88)
|
||||
basic_machine=m88k-motorola
|
||||
os=-sysv3
|
||||
;;
|
||||
dpx20 | dpx20-*)
|
||||
basic_machine=rs6000-bull
|
||||
os=-bosx
|
||||
;;
|
||||
dpx2* | dpx2*-bull)
|
||||
basic_machine=m68k-bull
|
||||
os=-sysv3
|
||||
;;
|
||||
ebmon29k)
|
||||
basic_machine=a29k-amd
|
||||
os=-ebmon
|
||||
;;
|
||||
elxsi)
|
||||
basic_machine=elxsi-elxsi
|
||||
os=-bsd
|
||||
;;
|
||||
encore | umax | mmax)
|
||||
basic_machine=ns32k-encore
|
||||
;;
|
||||
fx2800)
|
||||
basic_machine=i860-alliant
|
||||
;;
|
||||
genix)
|
||||
basic_machine=ns32k-ns
|
||||
;;
|
||||
gmicro)
|
||||
basic_machine=tron-gmicro
|
||||
os=-sysv
|
||||
;;
|
||||
h3050r* | hiux*)
|
||||
basic_machine=hppa1.1-hitachi
|
||||
os=-hiuxwe2
|
||||
;;
|
||||
h8300hms)
|
||||
basic_machine=h8300-hitachi
|
||||
os=-hms
|
||||
;;
|
||||
harris)
|
||||
basic_machine=m88k-harris
|
||||
os=-sysv3
|
||||
;;
|
||||
hp300-*)
|
||||
basic_machine=m68k-hp
|
||||
;;
|
||||
hp300bsd)
|
||||
basic_machine=m68k-hp
|
||||
os=-bsd
|
||||
;;
|
||||
hp300hpux)
|
||||
basic_machine=m68k-hp
|
||||
os=-hpux
|
||||
;;
|
||||
hp9k2[0-9][0-9] | hp9k31[0-9])
|
||||
basic_machine=m68000-hp
|
||||
;;
|
||||
hp9k3[2-9][0-9])
|
||||
basic_machine=m68k-hp
|
||||
;;
|
||||
hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
|
||||
basic_machine=hppa1.1-hp
|
||||
;;
|
||||
hp9k8[0-9][0-9] | hp8[0-9][0-9])
|
||||
basic_machine=hppa1.0-hp
|
||||
;;
|
||||
hppa-next)
|
||||
os=-nextstep3
|
||||
;;
|
||||
i370-ibm* | ibm*)
|
||||
basic_machine=i370-ibm
|
||||
os=-mvs
|
||||
;;
|
||||
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
|
||||
i[34567]86v32)
|
||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||
os=-sysv32
|
||||
;;
|
||||
i[34567]86v4*)
|
||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||
os=-sysv4
|
||||
;;
|
||||
i[34567]86v)
|
||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||
os=-sysv
|
||||
;;
|
||||
i[34567]86sol2)
|
||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||
os=-solaris2
|
||||
;;
|
||||
iris | iris4d)
|
||||
basic_machine=mips-sgi
|
||||
case $os in
|
||||
-irix*)
|
||||
;;
|
||||
*)
|
||||
os=-irix4
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
isi68 | isi)
|
||||
basic_machine=m68k-isi
|
||||
os=-sysv
|
||||
;;
|
||||
m88k-omron*)
|
||||
basic_machine=m88k-omron
|
||||
;;
|
||||
magnum | m3230)
|
||||
basic_machine=mips-mips
|
||||
os=-sysv
|
||||
;;
|
||||
merlin)
|
||||
basic_machine=ns32k-utek
|
||||
os=-sysv
|
||||
;;
|
||||
miniframe)
|
||||
basic_machine=m68000-convergent
|
||||
;;
|
||||
mipsel*-linux*)
|
||||
basic_machine=mipsel-unknown
|
||||
os=-linux-gnu
|
||||
;;
|
||||
mips*-linux*)
|
||||
basic_machine=mips-unknown
|
||||
os=-linux-gnu
|
||||
;;
|
||||
mips3*-*)
|
||||
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
|
||||
;;
|
||||
mips3*)
|
||||
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
|
||||
;;
|
||||
ncr3000)
|
||||
basic_machine=i486-ncr
|
||||
os=-sysv4
|
||||
;;
|
||||
news | news700 | news800 | news900)
|
||||
basic_machine=m68k-sony
|
||||
os=-newsos
|
||||
;;
|
||||
news1000)
|
||||
basic_machine=m68030-sony
|
||||
os=-newsos
|
||||
;;
|
||||
news-3600 | risc-news)
|
||||
basic_machine=mips-sony
|
||||
os=-newsos
|
||||
;;
|
||||
next | m*-next )
|
||||
basic_machine=m68k-next
|
||||
case $os in
|
||||
-nextstep* )
|
||||
;;
|
||||
-ns2*)
|
||||
os=-nextstep2
|
||||
;;
|
||||
*)
|
||||
os=-nextstep3
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
nh3000)
|
||||
basic_machine=m68k-harris
|
||||
os=-cxux
|
||||
;;
|
||||
nh[45]000)
|
||||
basic_machine=m88k-harris
|
||||
os=-cxux
|
||||
;;
|
||||
nindy960)
|
||||
basic_machine=i960-intel
|
||||
os=-nindy
|
||||
;;
|
||||
np1)
|
||||
basic_machine=np1-gould
|
||||
;;
|
||||
pa-hitachi)
|
||||
basic_machine=hppa1.1-hitachi
|
||||
os=-hiuxwe2
|
||||
;;
|
||||
paragon)
|
||||
basic_machine=i860-intel
|
||||
os=-osf
|
||||
;;
|
||||
pbd)
|
||||
basic_machine=sparc-tti
|
||||
;;
|
||||
pbb)
|
||||
basic_machine=m68k-tti
|
||||
;;
|
||||
pc532 | pc532-*)
|
||||
basic_machine=ns32k-pc532
|
||||
;;
|
||||
pentium | p5 | k5 | nexen)
|
||||
basic_machine=i586-pc
|
||||
;;
|
||||
pentiumpro | p6 | k6 | 6x86)
|
||||
basic_machine=i686-pc
|
||||
;;
|
||||
pentiumii | pentium2)
|
||||
basic_machine=i786-pc
|
||||
;;
|
||||
pentium-* | p5-* | k5-* | nexen-*)
|
||||
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
pentiumpro-* | p6-* | k6-* | 6x86-*)
|
||||
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
pentiumii-* | pentium2-*)
|
||||
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
pn)
|
||||
basic_machine=pn-gould
|
||||
;;
|
||||
power) basic_machine=rs6000-ibm
|
||||
;;
|
||||
ppc) basic_machine=powerpc-unknown
|
||||
;;
|
||||
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppcle | powerpclittle | ppc-le | powerpc-little)
|
||||
basic_machine=powerpcle-unknown
|
||||
;;
|
||||
ppcle-* | powerpclittle-*)
|
||||
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ps2)
|
||||
basic_machine=i386-ibm
|
||||
;;
|
||||
rm[46]00)
|
||||
basic_machine=mips-siemens
|
||||
;;
|
||||
rtpc | rtpc-*)
|
||||
basic_machine=romp-ibm
|
||||
;;
|
||||
sequent)
|
||||
basic_machine=i386-sequent
|
||||
;;
|
||||
sh)
|
||||
basic_machine=sh-hitachi
|
||||
os=-hms
|
||||
;;
|
||||
sps7)
|
||||
basic_machine=m68k-bull
|
||||
os=-sysv2
|
||||
;;
|
||||
spur)
|
||||
basic_machine=spur-unknown
|
||||
;;
|
||||
sun2)
|
||||
basic_machine=m68000-sun
|
||||
;;
|
||||
sun2os3)
|
||||
basic_machine=m68000-sun
|
||||
os=-sunos3
|
||||
;;
|
||||
sun2os4)
|
||||
basic_machine=m68000-sun
|
||||
os=-sunos4
|
||||
;;
|
||||
sun3os3)
|
||||
basic_machine=m68k-sun
|
||||
os=-sunos3
|
||||
;;
|
||||
sun3os4)
|
||||
basic_machine=m68k-sun
|
||||
os=-sunos4
|
||||
;;
|
||||
sun4os3)
|
||||
basic_machine=sparc-sun
|
||||
os=-sunos3
|
||||
;;
|
||||
sun4os4)
|
||||
basic_machine=sparc-sun
|
||||
os=-sunos4
|
||||
;;
|
||||
sun4sol2)
|
||||
basic_machine=sparc-sun
|
||||
os=-solaris2
|
||||
;;
|
||||
sun3 | sun3-*)
|
||||
basic_machine=m68k-sun
|
||||
;;
|
||||
sun4)
|
||||
basic_machine=sparc-sun
|
||||
;;
|
||||
sun386 | sun386i | roadrunner)
|
||||
basic_machine=i386-sun
|
||||
;;
|
||||
symmetry)
|
||||
basic_machine=i386-sequent
|
||||
os=-dynix
|
||||
;;
|
||||
tx39)
|
||||
basic_machine=mipstx39-unknown
|
||||
;;
|
||||
tx39el)
|
||||
basic_machine=mipstx39el-unknown
|
||||
;;
|
||||
tower | tower-32)
|
||||
basic_machine=m68k-ncr
|
||||
;;
|
||||
udi29k)
|
||||
basic_machine=a29k-amd
|
||||
os=-udi
|
||||
;;
|
||||
ultra3)
|
||||
basic_machine=a29k-nyu
|
||||
os=-sym1
|
||||
;;
|
||||
vaxv)
|
||||
basic_machine=vax-dec
|
||||
os=-sysv
|
||||
;;
|
||||
vms)
|
||||
basic_machine=vax-dec
|
||||
os=-vms
|
||||
;;
|
||||
vpp*|vx|vx-*)
|
||||
basic_machine=f301-fujitsu
|
||||
;;
|
||||
vxworks960)
|
||||
basic_machine=i960-wrs
|
||||
os=-vxworks
|
||||
;;
|
||||
vxworks68)
|
||||
basic_machine=m68k-wrs
|
||||
os=-vxworks
|
||||
;;
|
||||
vxworks29k)
|
||||
basic_machine=a29k-wrs
|
||||
os=-vxworks
|
||||
;;
|
||||
xmp)
|
||||
basic_machine=xmp-cray
|
||||
os=-unicos
|
||||
;;
|
||||
xps | xps100)
|
||||
basic_machine=xps100-honeywell
|
||||
;;
|
||||
none)
|
||||
basic_machine=none-none
|
||||
os=-none
|
||||
;;
|
||||
|
||||
# Here we handle the default manufacturer of certain CPU types. It is in
|
||||
# some cases the only manufacturer, in others, it is the most popular.
|
||||
mips)
|
||||
if [ x$os = x-linux-gnu ]; then
|
||||
basic_machine=mips-unknown
|
||||
else
|
||||
basic_machine=mips-mips
|
||||
fi
|
||||
;;
|
||||
romp)
|
||||
basic_machine=romp-ibm
|
||||
;;
|
||||
rs6000)
|
||||
basic_machine=rs6000-ibm
|
||||
;;
|
||||
vax)
|
||||
basic_machine=vax-dec
|
||||
;;
|
||||
pdp11)
|
||||
basic_machine=pdp11-dec
|
||||
;;
|
||||
we32k)
|
||||
basic_machine=we32k-att
|
||||
;;
|
||||
sparc)
|
||||
basic_machine=sparc-sun
|
||||
;;
|
||||
cydra)
|
||||
basic_machine=cydra-cydrome
|
||||
;;
|
||||
orion)
|
||||
basic_machine=orion-highlevel
|
||||
;;
|
||||
orion105)
|
||||
basic_machine=clipper-highlevel
|
||||
;;
|
||||
*)
|
||||
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Here we canonicalize certain aliases for manufacturers.
|
||||
case $basic_machine in
|
||||
*-digital*)
|
||||
basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
|
||||
;;
|
||||
*-commodore*)
|
||||
basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
|
||||
# Decode manufacturer-specific aliases for certain operating systems.
|
||||
|
||||
if [ x"$os" != x"" ]
|
||||
then
|
||||
case $os in
|
||||
# First match some system type aliases
|
||||
# that might get confused with valid system types.
|
||||
# -solaris* is a basic system type, with this one exception.
|
||||
-solaris1 | -solaris1.*)
|
||||
os=`echo $os | sed -e 's|solaris1|sunos4|'`
|
||||
;;
|
||||
-solaris)
|
||||
os=-solaris2
|
||||
;;
|
||||
-svr4*)
|
||||
os=-sysv4
|
||||
;;
|
||||
-unixware*)
|
||||
os=-sysv4.2uw
|
||||
;;
|
||||
-gnu/linux*)
|
||||
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
|
||||
;;
|
||||
# First accept the basic system types.
|
||||
# The portable systems comes first.
|
||||
# Each alternative MUST END IN A *, to match a version number.
|
||||
# -sysv* is not here because it comes later, after sysvr4.
|
||||
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
|
||||
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
|
||||
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
|
||||
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
|
||||
| -aos* \
|
||||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
|
||||
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
|
||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
||||
| -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -linux-gnu* | -uxpv*)
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
-linux*)
|
||||
os=`echo $os | sed -e 's|linux|linux-gnu|'`
|
||||
;;
|
||||
-sunos5*)
|
||||
os=`echo $os | sed -e 's|sunos5|solaris2|'`
|
||||
;;
|
||||
-sunos6*)
|
||||
os=`echo $os | sed -e 's|sunos6|solaris3|'`
|
||||
;;
|
||||
-osfrose*)
|
||||
os=-osfrose
|
||||
;;
|
||||
-osf*)
|
||||
os=-osf
|
||||
;;
|
||||
-utek*)
|
||||
os=-bsd
|
||||
;;
|
||||
-dynix*)
|
||||
os=-bsd
|
||||
;;
|
||||
-acis*)
|
||||
os=-aos
|
||||
;;
|
||||
-ctix* | -uts*)
|
||||
os=-sysv
|
||||
;;
|
||||
-ns2 )
|
||||
os=-nextstep2
|
||||
;;
|
||||
# Preserve the version number of sinix5.
|
||||
-sinix5.*)
|
||||
os=`echo $os | sed -e 's|sinix|sysv|'`
|
||||
;;
|
||||
-sinix*)
|
||||
os=-sysv4
|
||||
;;
|
||||
-triton*)
|
||||
os=-sysv3
|
||||
;;
|
||||
-oss*)
|
||||
os=-sysv3
|
||||
;;
|
||||
-svr4)
|
||||
os=-sysv4
|
||||
;;
|
||||
-svr3)
|
||||
os=-sysv3
|
||||
;;
|
||||
-sysvr4)
|
||||
os=-sysv4
|
||||
;;
|
||||
# This must come after -sysvr4.
|
||||
-sysv*)
|
||||
;;
|
||||
-xenix)
|
||||
os=-xenix
|
||||
;;
|
||||
-none)
|
||||
;;
|
||||
*)
|
||||
# Get rid of the `-' at the beginning of $os.
|
||||
os=`echo $os | sed 's/[^-]*-//'`
|
||||
echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
else
|
||||
|
||||
# Here we handle the default operating systems that come with various machines.
|
||||
# The value should be what the vendor currently ships out the door with their
|
||||
# machine or put another way, the most popular os provided with the machine.
|
||||
|
||||
# Note that if you're going to try to match "-MANUFACTURER" here (say,
|
||||
# "-sun"), then you have to tell the case statement up towards the top
|
||||
# that MANUFACTURER isn't an operating system. Otherwise, code above
|
||||
# will signal an error saying that MANUFACTURER isn't an operating
|
||||
# system, and we'll never get to this point.
|
||||
|
||||
case $basic_machine in
|
||||
*-acorn)
|
||||
os=-riscix1.2
|
||||
;;
|
||||
arm*-semi)
|
||||
os=-aout
|
||||
;;
|
||||
pdp11-*)
|
||||
os=-none
|
||||
;;
|
||||
*-dec | vax-*)
|
||||
os=-ultrix4.2
|
||||
;;
|
||||
m68*-apollo)
|
||||
os=-domain
|
||||
;;
|
||||
i386-sun)
|
||||
os=-sunos4.0.2
|
||||
;;
|
||||
m68000-sun)
|
||||
os=-sunos3
|
||||
# This also exists in the configure program, but was not the
|
||||
# default.
|
||||
# os=-sunos4
|
||||
;;
|
||||
*-tti) # must be before sparc entry or we get the wrong os.
|
||||
os=-sysv3
|
||||
;;
|
||||
sparc-* | *-sun)
|
||||
os=-sunos4.1.1
|
||||
;;
|
||||
*-ibm)
|
||||
os=-aix
|
||||
;;
|
||||
*-hp)
|
||||
os=-hpux
|
||||
;;
|
||||
*-hitachi)
|
||||
os=-hiux
|
||||
;;
|
||||
i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
|
||||
os=-sysv
|
||||
;;
|
||||
*-cbm)
|
||||
os=-amigaos
|
||||
;;
|
||||
*-dg)
|
||||
os=-dgux
|
||||
;;
|
||||
*-dolphin)
|
||||
os=-sysv3
|
||||
;;
|
||||
m68k-ccur)
|
||||
os=-rtu
|
||||
;;
|
||||
m88k-omron*)
|
||||
os=-luna
|
||||
;;
|
||||
*-next )
|
||||
os=-nextstep
|
||||
;;
|
||||
*-sequent)
|
||||
os=-ptx
|
||||
;;
|
||||
*-crds)
|
||||
os=-unos
|
||||
;;
|
||||
*-ns)
|
||||
os=-genix
|
||||
;;
|
||||
i370-*)
|
||||
os=-mvs
|
||||
;;
|
||||
*-next)
|
||||
os=-nextstep3
|
||||
;;
|
||||
*-gould)
|
||||
os=-sysv
|
||||
;;
|
||||
*-highlevel)
|
||||
os=-bsd
|
||||
;;
|
||||
*-encore)
|
||||
os=-bsd
|
||||
;;
|
||||
*-sgi)
|
||||
os=-irix
|
||||
;;
|
||||
*-siemens)
|
||||
os=-sysv4
|
||||
;;
|
||||
*-masscomp)
|
||||
os=-rtu
|
||||
;;
|
||||
f301-fujitsu)
|
||||
os=-uxpv
|
||||
;;
|
||||
*)
|
||||
os=-none
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Here we handle the case where we know the os, and the CPU type, but not the
|
||||
# manufacturer. We pick the logical manufacturer.
|
||||
vendor=unknown
|
||||
case $basic_machine in
|
||||
*-unknown)
|
||||
case $os in
|
||||
-riscix*)
|
||||
vendor=acorn
|
||||
;;
|
||||
-sunos*)
|
||||
vendor=sun
|
||||
;;
|
||||
-aix*)
|
||||
vendor=ibm
|
||||
;;
|
||||
-hpux*)
|
||||
vendor=hp
|
||||
;;
|
||||
-hiux*)
|
||||
vendor=hitachi
|
||||
;;
|
||||
-unos*)
|
||||
vendor=crds
|
||||
;;
|
||||
-dgux*)
|
||||
vendor=dg
|
||||
;;
|
||||
-luna*)
|
||||
vendor=omron
|
||||
;;
|
||||
-genix*)
|
||||
vendor=ns
|
||||
;;
|
||||
-mvs*)
|
||||
vendor=ibm
|
||||
;;
|
||||
-ptx*)
|
||||
vendor=sequent
|
||||
;;
|
||||
-vxsim* | -vxworks*)
|
||||
vendor=wrs
|
||||
;;
|
||||
-aux*)
|
||||
vendor=apple
|
||||
;;
|
||||
esac
|
||||
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
|
||||
;;
|
||||
esac
|
||||
|
||||
echo $basic_machine$os
|
734
config/1750a/1750a.c
Normal file
734
config/1750a/1750a.c
Normal file
@ -0,0 +1,734 @@
|
||||
/* Subroutines for insn-output.c for MIL-STD-1750.
|
||||
Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||
Contributed by O.M.Kellogg, DASA (kellogg@space.otn.dasa.de)
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#define __datalbl
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rtl.h"
|
||||
#include "tree.h"
|
||||
#include "expr.h"
|
||||
#define HAVE_cc0
|
||||
#include "conditions.h"
|
||||
#include "real.h"
|
||||
#include "regs.h"
|
||||
|
||||
struct datalabel_array datalbl[DATALBL_ARRSIZ];
|
||||
int datalbl_ndx = -1;
|
||||
struct jumplabel_array jmplbl[JMPLBL_ARRSIZ];
|
||||
int jmplbl_ndx = -1;
|
||||
int label_pending = 0, program_counter = 0;
|
||||
enum section current_section = Normal;
|
||||
char *sectname[4] =
|
||||
{"Init", "Normal", "Konst", "Static"};
|
||||
|
||||
int
|
||||
notice_update_cc (exp)
|
||||
rtx exp;
|
||||
{
|
||||
if (GET_CODE (exp) == SET)
|
||||
{
|
||||
enum rtx_code src_code = GET_CODE (SET_SRC (exp));
|
||||
/* Jumps do not alter the cc's. */
|
||||
if (SET_DEST (exp) == pc_rtx)
|
||||
return;
|
||||
/* Moving a register or constant into memory doesn't alter the cc's. */
|
||||
if (GET_CODE (SET_DEST (exp)) == MEM
|
||||
&& (src_code == REG || src_code == CONST_INT))
|
||||
return;
|
||||
/* Function calls clobber the cc's. */
|
||||
if (src_code == CALL)
|
||||
{
|
||||
CC_STATUS_INIT;
|
||||
return;
|
||||
}
|
||||
/* Emulated longword bit-ops leave cc's incorrect */
|
||||
if (GET_MODE (SET_DEST (exp)) == HImode ?
|
||||
src_code == AND || src_code == IOR ||
|
||||
src_code == XOR || src_code == NOT : 0)
|
||||
{
|
||||
CC_STATUS_INIT;
|
||||
return;
|
||||
}
|
||||
/* Tests and compares set the cc's in predictable ways. */
|
||||
if (SET_DEST (exp) == cc0_rtx)
|
||||
{
|
||||
CC_STATUS_INIT;
|
||||
cc_status.value1 = SET_SRC (exp);
|
||||
return;
|
||||
}
|
||||
/* Anything else will set cc_status. */
|
||||
cc_status.flags = CC_NO_OVERFLOW;
|
||||
cc_status.value1 = SET_SRC (exp);
|
||||
cc_status.value2 = SET_DEST (exp);
|
||||
return;
|
||||
}
|
||||
else if (GET_CODE (exp) == PARALLEL
|
||||
&& GET_CODE (XVECEXP (exp, 0, 0)) == SET)
|
||||
{
|
||||
if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
|
||||
return;
|
||||
if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
|
||||
{
|
||||
CC_STATUS_INIT;
|
||||
cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
|
||||
return;
|
||||
}
|
||||
CC_STATUS_INIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
CC_STATUS_INIT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
rtx
|
||||
function_arg (cum, mode, type, named)
|
||||
int cum;
|
||||
enum machine_mode mode;
|
||||
tree type;
|
||||
int named;
|
||||
{
|
||||
int size;
|
||||
|
||||
if (MUST_PASS_IN_STACK (mode, type))
|
||||
return (rtx) 0;
|
||||
if (mode == BLKmode)
|
||||
size = int_size_in_bytes (type);
|
||||
else
|
||||
size = GET_MODE_SIZE (mode);
|
||||
if (cum + size < 12)
|
||||
return gen_rtx (REG, mode, cum);
|
||||
else
|
||||
return (rtx) 0;
|
||||
}
|
||||
|
||||
|
||||
double
|
||||
get_double (x)
|
||||
rtx x;
|
||||
{
|
||||
union
|
||||
{
|
||||
double d;
|
||||
long i[2];
|
||||
}
|
||||
du;
|
||||
|
||||
du.i[0] = CONST_DOUBLE_LOW (x);
|
||||
du.i[1] = CONST_DOUBLE_HIGH (x);
|
||||
return du.d;
|
||||
}
|
||||
|
||||
char *
|
||||
float_label (code, value)
|
||||
char code;
|
||||
double value;
|
||||
{
|
||||
int i = 1;
|
||||
static char label[32];
|
||||
char *p;
|
||||
|
||||
label[0] = code;
|
||||
p = label + 1;
|
||||
sprintf (p, "%lf", value);
|
||||
while (*p)
|
||||
{
|
||||
*p = (*p == '+') ? 'p' :
|
||||
(*p == '-') ? 'm' : *p;
|
||||
p++;
|
||||
}
|
||||
return xstrdup (label);
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
movcnt_regno_adjust (op)
|
||||
rtx *op;
|
||||
{
|
||||
static char outstr[80];
|
||||
int op0r = REGNO (op[0]), op1r = REGNO (op[1]), op2r = REGNO (op[2]);
|
||||
#define dstreg op0r
|
||||
#define srcreg op1r
|
||||
#define cntreg op2r
|
||||
#define cntreg_1750 (op0r + 1)
|
||||
|
||||
if (cntreg == cntreg_1750)
|
||||
sprintf (outstr, "mov r%d,r%d", op0r, op1r);
|
||||
else if (dstreg + 1 == srcreg && cntreg > srcreg)
|
||||
sprintf (outstr, "xwr r%d,r%d\n\tmov r%d,r%d", op2r, op1r, op0r, op2r);
|
||||
else if (dstreg == cntreg + 1)
|
||||
sprintf (outstr, "xwr r%d,r%d\n\tmov r%d,r%d", op0r, op2r, op2r, op1r);
|
||||
else if (dstreg == srcreg + 1)
|
||||
sprintf (outstr, "xwr r%d,r%d\n\txwr r%d,r%d\n\tmov r%d,r%d",
|
||||
op0r, op1r, op0r, op2r, op1r, op2r);
|
||||
else if (cntreg + 1 == srcreg)
|
||||
sprintf (outstr, "xwr r%d,r%d\n\txwr r%d,r%d\n\tmov r%d,r%d",
|
||||
op2r, op1r, op0r, op2r, op2r, op0r);
|
||||
else if (cntreg == srcreg + 1)
|
||||
sprintf (outstr, "xwr r%d,r%d\n\tmov r%d,r%d", op0r, op1r, op1r, op0r);
|
||||
else
|
||||
sprintf (outstr, "xwr r%d,r%d\n\tmov r%d,r%d\n\txwr r%d,r%d",
|
||||
op2r, cntreg_1750, op0r, op1r, op2r, cntreg_1750);
|
||||
return outstr;
|
||||
}
|
||||
|
||||
char *
|
||||
mod_regno_adjust (instr, op)
|
||||
char *instr;
|
||||
rtx *op;
|
||||
{
|
||||
static char outstr[40];
|
||||
char *r = (!strncmp (instr, "dvr", 3) ? "r" : "");
|
||||
int modregno_gcc = REGNO (op[3]), modregno_1750 = REGNO (op[0]) + 1;
|
||||
|
||||
if (modregno_gcc == modregno_1750
|
||||
|| (reg_renumber != NULL
|
||||
&& reg_renumber[modregno_gcc] >= 0
|
||||
&& reg_renumber[modregno_gcc] == reg_renumber[modregno_1750]))
|
||||
sprintf (outstr, "%s r%%0,%s%%2", instr, r);
|
||||
else
|
||||
sprintf (outstr, "lr r%d,r%d\n\t%s r%%0,%s%%2\n\txwr r%d,r%d",
|
||||
modregno_gcc, modregno_1750, instr, r, modregno_1750,
|
||||
modregno_gcc);
|
||||
return outstr;
|
||||
}
|
||||
|
||||
|
||||
/* Check if op is a valid memory operand for 1750A Load/Store instructions
|
||||
(memory indirection permitted.) */
|
||||
|
||||
int
|
||||
memop_valid (op)
|
||||
rtx op;
|
||||
{
|
||||
static int recurred = 0;
|
||||
int valid;
|
||||
|
||||
if (GET_MODE (op) != Pmode && GET_MODE (op) != VOIDmode
|
||||
&& GET_MODE (op) != QImode)
|
||||
return 0;
|
||||
switch (GET_CODE (op))
|
||||
{
|
||||
case MEM:
|
||||
if (!recurred && GET_CODE (XEXP (op, 0)) == REG)
|
||||
return 1;
|
||||
case MINUS:
|
||||
case MULT:
|
||||
case DIV:
|
||||
return 0;
|
||||
case PLUS:
|
||||
recurred = 1;
|
||||
valid = memop_valid (XEXP (op, 0));
|
||||
if (valid)
|
||||
valid = memop_valid (XEXP (op, 1));
|
||||
recurred = 0;
|
||||
return valid;
|
||||
case REG:
|
||||
if (REGNO (op) > 0)
|
||||
return 1;
|
||||
return 0;
|
||||
case CONST:
|
||||
case CONST_INT:
|
||||
case SYMBOL_REF:
|
||||
case SUBREG:
|
||||
return 1;
|
||||
default:
|
||||
printf ("memop_valid: code=%d\n", (int) GET_CODE (op));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* predicate for the MOV instruction: */
|
||||
int
|
||||
mov_memory_operand (op, mode)
|
||||
rtx op;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
return (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == REG);
|
||||
}
|
||||
|
||||
/* predicate for the STC instruction: */
|
||||
int
|
||||
small_nonneg_const (op, mode)
|
||||
rtx op;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
if (GET_CODE (op) == CONST_INT && INTVAL (op) >= 0 && INTVAL (op) <= 15)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* predicate for constant zero: */
|
||||
int
|
||||
zero_operand (op, mode)
|
||||
rtx op;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
return op == CONST0_RTX (mode);
|
||||
}
|
||||
|
||||
|
||||
/* predicate for 1750 `B' addressing mode (Base Register with Offset)
|
||||
memory operand */
|
||||
int
|
||||
b_mode_operand (op)
|
||||
rtx op;
|
||||
{
|
||||
if (GET_CODE (op) == MEM)
|
||||
{
|
||||
rtx inner = XEXP (op, 0);
|
||||
if (GET_CODE (inner) == REG && REG_OK_FOR_INDEX_P (inner))
|
||||
return 1;
|
||||
if (GET_CODE (inner) == PLUS)
|
||||
{
|
||||
rtx plus_op0 = XEXP (inner, 0);
|
||||
if (GET_CODE (plus_op0) == REG && REG_OK_FOR_INDEX_P (plus_op0))
|
||||
{
|
||||
rtx plus_op1 = XEXP (inner, 1);
|
||||
if (GET_CODE (plus_op1) == CONST_INT
|
||||
&& INTVAL (plus_op1) >= 0
|
||||
&& INTVAL (plus_op1) <= 255)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Decide whether to output a conditional jump as a "Jump Conditional"
|
||||
or as a "Branch Conditional": */
|
||||
|
||||
int
|
||||
find_jmplbl (labelnum)
|
||||
int labelnum;
|
||||
{
|
||||
int i, found = 0;
|
||||
|
||||
for (i = 0; i <= jmplbl_ndx; i++)
|
||||
if (labelnum == jmplbl[i].num)
|
||||
{
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
if (found)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *
|
||||
branch_or_jump (condition, targetlabel_number)
|
||||
char *condition;
|
||||
int targetlabel_number;
|
||||
{
|
||||
static char buf[30];
|
||||
int index;
|
||||
|
||||
if ((index = find_jmplbl (targetlabel_number)) >= 0)
|
||||
if (program_counter - jmplbl[index].pc < 128)
|
||||
{
|
||||
sprintf (buf, "b%s %%l0", condition);
|
||||
return buf;
|
||||
}
|
||||
sprintf (buf, "jc %s,%%l0", condition);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
unsigned_comparison_operator (insn)
|
||||
rtx insn;
|
||||
{
|
||||
switch (GET_CODE (insn))
|
||||
{
|
||||
case GEU:
|
||||
case GTU:
|
||||
case LEU:
|
||||
case LTU:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
next_cc_user_is_unsigned (insn)
|
||||
rtx insn;
|
||||
{
|
||||
if ( !(insn = next_cc0_user (insn)))
|
||||
abort ();
|
||||
else if (GET_CODE (insn) == JUMP_INSN
|
||||
&& GET_CODE (PATTERN (insn)) == SET
|
||||
&& GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE)
|
||||
return unsigned_comparison_operator (XEXP (SET_SRC (PATTERN (insn)), 0));
|
||||
else if (GET_CODE (insn) == INSN
|
||||
&& GET_CODE (PATTERN (insn)) == SET)
|
||||
return unsigned_comparison_operator (SET_SRC (PATTERN (insn)));
|
||||
else
|
||||
abort ();
|
||||
}
|
||||
|
||||
|
||||
static int addr_inc;
|
||||
|
||||
/* A C compound statement to output to stdio stream STREAM the
|
||||
assembler syntax for an instruction operand X. X is an RTL
|
||||
expression.
|
||||
|
||||
CODE is a value that can be used to specify one of several ways
|
||||
of printing the operand. It is used when identical operands
|
||||
must be printed differently depending on the context. CODE
|
||||
comes from the `%' specification that was used to request
|
||||
printing of the operand. If the specification was just `%DIGIT'
|
||||
then CODE is 0; if the specification was `%LTR DIGIT' then CODE
|
||||
is the ASCII code for LTR.
|
||||
|
||||
If X is a register, this macro should print the register's name.
|
||||
The names can be found in an array `reg_names' whose type is
|
||||
`char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
|
||||
|
||||
When the machine description has a specification `%PUNCT' (a `%'
|
||||
followed by a punctuation character), this macro is called with
|
||||
a null pointer for X and the punctuation character for CODE.
|
||||
|
||||
The 1750 specific codes are:
|
||||
'J' for the negative of a constant
|
||||
'Q' for printing addresses in B mode syntax
|
||||
'd' for the second register in a pair
|
||||
't' for the third register in a triple
|
||||
'b' for the bit number (using 1750 test bit convention)
|
||||
'B' for the bit number of the 1's complement (for bit clear)
|
||||
'w' for int - 16
|
||||
*/
|
||||
|
||||
print_operand (file, x, letter)
|
||||
FILE *file;
|
||||
rtx x;
|
||||
int letter;
|
||||
{
|
||||
switch (GET_CODE (x))
|
||||
{
|
||||
case REG:
|
||||
if (letter == 'd')
|
||||
fprintf (file, "%d", REGNO (x) + 1);
|
||||
else if (letter == 't')
|
||||
fprintf (file, "%d", REGNO (x) + 2);
|
||||
else
|
||||
fprintf (file, "%d", REGNO (x));
|
||||
break;
|
||||
|
||||
case SYMBOL_REF:
|
||||
fprintf (file, "%s", XSTR (x, 0));
|
||||
if (letter == 'A')
|
||||
fprintf (file, "+1");
|
||||
break;
|
||||
|
||||
case LABEL_REF:
|
||||
case CONST:
|
||||
case MEM:
|
||||
if (letter == 'Q')
|
||||
{
|
||||
rtx inner = XEXP (x, 0);
|
||||
switch (GET_CODE (inner))
|
||||
{
|
||||
case REG:
|
||||
fprintf (file, "r%d,0", REGNO (inner));
|
||||
break;
|
||||
case PLUS:
|
||||
fprintf (file, "r%d,%d", REGNO (XEXP (inner, 0)),
|
||||
INTVAL (XEXP (inner, 1)));
|
||||
break;
|
||||
default:
|
||||
fprintf (file, "[ill Q code=%d]", GET_CODE (inner));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
addr_inc = (letter == 'A' ? 1 : 0);
|
||||
output_address (XEXP (x, 0));
|
||||
}
|
||||
break;
|
||||
|
||||
case CONST_DOUBLE:
|
||||
/* {
|
||||
double value = get_double (x);
|
||||
char fltstr[32];
|
||||
sprintf (fltstr, "%lf", value);
|
||||
|
||||
if (letter == 'D' || letter == 'E')
|
||||
{
|
||||
int i, found = 0;
|
||||
for (i = 0; i <= datalbl_ndx; i++)
|
||||
if (strcmp (fltstr, datalbl[i].value) == 0)
|
||||
{
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
strcpy (datalbl[i = ++datalbl_ndx].value, fltstr);
|
||||
datalbl[i].name = float_label (letter, value);
|
||||
datalbl[i].size = (letter == 'E') ? 3 : 2;
|
||||
check_section (Konst);
|
||||
fprintf (file, "K%s \tdata%s %s ;p_o\n", datalbl[i].name,
|
||||
(letter == 'E' ? "ef" : "f"), fltstr);
|
||||
check_section (Normal);
|
||||
}
|
||||
}
|
||||
else if (letter == 'F' || letter == 'G')
|
||||
{
|
||||
int i, found = 0;
|
||||
for (i = 0; i <= datalbl_ndx; i++)
|
||||
if (strcmp (fltstr, datalbl[i].value) == 0)
|
||||
{
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"float value %lfnot found upon label reference\n", value);
|
||||
strcpy (datalbl[i = ++datalbl_ndx].value, fltstr);
|
||||
datalbl[i].name = float_label (letter, value);
|
||||
datalbl[i].size = (letter == 'G') ? 3 : 2;
|
||||
check_section (Konst);
|
||||
fprintf (file, "K%s \tdata%s %s ;p_o\n", datalbl[i].name,
|
||||
(letter == 'G' ? "ef" : "f"), fltstr);
|
||||
check_section (Normal);
|
||||
}
|
||||
fprintf (file, "%s ;P_O 'F'", datalbl[i].name);
|
||||
}
|
||||
else
|
||||
fprintf (file, " %s ;P_O cst_dbl ", fltstr);
|
||||
}
|
||||
*/
|
||||
fprintf (file, "%lf", get_double (x));
|
||||
break;
|
||||
|
||||
case CONST_INT:
|
||||
if (letter == 'J')
|
||||
fprintf (file, "%d", -INTVAL (x));
|
||||
else if (letter == 'b')
|
||||
fprintf (file, "%d", which_bit (INTVAL (x)));
|
||||
else if (letter == 'B')
|
||||
fprintf (file, "%d", which_bit (~INTVAL (x)));
|
||||
else if (letter == 'w')
|
||||
fprintf (file, "%d", INTVAL (x) - 16);
|
||||
else
|
||||
fprintf (file, "%d", INTVAL (x));
|
||||
break;
|
||||
|
||||
case CODE_LABEL:
|
||||
fprintf (file, "L%d", XINT (x, 3));
|
||||
break;
|
||||
|
||||
case CALL:
|
||||
fprintf (file, "CALL nargs=%d, func is either '%s' or '%s'",
|
||||
XEXP (x, 1), XSTR (XEXP (XEXP (x, 0), 1), 0), XSTR (XEXP (x, 0), 1));
|
||||
break;
|
||||
|
||||
case PLUS:
|
||||
{
|
||||
rtx op0 = XEXP (x, 0), op1 = XEXP (x, 1);
|
||||
int op0code = GET_CODE (op0), op1code = GET_CODE (op1);
|
||||
if (op1code == CONST_INT)
|
||||
switch (op0code)
|
||||
{
|
||||
case REG:
|
||||
fprintf (file, "%d,r%d ; p_o_PLUS for REG and CONST_INT",
|
||||
INTVAL (op1), REGNO (op0));
|
||||
break;
|
||||
case SYMBOL_REF:
|
||||
fprintf (file, "%d+%s", INTVAL (op1), XSTR (op0, 0));
|
||||
break;
|
||||
case MEM:
|
||||
fprintf (file, "%d,[mem:", INTVAL (op1));
|
||||
output_address (XEXP (op0, 0));
|
||||
fprintf (file, "] ;P_O plus");
|
||||
break;
|
||||
default:
|
||||
fprintf (file, "p_o_PLUS UFO, code=%d, with CONST=%d",
|
||||
(int) op0code, INTVAL (op1));
|
||||
}
|
||||
else if (op1code == SYMBOL_REF && op0code == REG)
|
||||
fprintf (file, "%s,r%d ; P_O: (plus reg sym)",
|
||||
XSTR (op1, 0), REGNO (op0));
|
||||
else
|
||||
fprintf (file, "p_o_+: op0code=%d, op1code=%d", op0code, op1code);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf (file, "p_o_UFO code=%d", GET_CODE (x));
|
||||
}
|
||||
|
||||
addr_inc = 0;
|
||||
}
|
||||
|
||||
print_operand_address (file, addr)
|
||||
FILE *file;
|
||||
rtx addr;
|
||||
{
|
||||
switch (GET_CODE (addr))
|
||||
{
|
||||
case REG:
|
||||
fprintf (file, "%d,r%d ; P_O_A", addr_inc, REGNO (addr));
|
||||
break;
|
||||
case PLUS:
|
||||
{
|
||||
register rtx x = XEXP (addr, 0), y = XEXP (addr, 1);
|
||||
switch (GET_CODE (x))
|
||||
{
|
||||
case REG:
|
||||
switch (GET_CODE (y))
|
||||
{
|
||||
case CONST:
|
||||
output_address (XEXP (y, 0));
|
||||
fprintf (file, ",r%d ;P_O_A reg + const expr", REGNO (x));
|
||||
break;
|
||||
case CONST_INT:
|
||||
fprintf (file, "%d,r%d", INTVAL (y) + addr_inc, REGNO (x));
|
||||
break;
|
||||
case SYMBOL_REF:
|
||||
fprintf (file, "%s", XSTR (y, 0));
|
||||
if (addr_inc)
|
||||
fprintf (file, "+%d", addr_inc);
|
||||
fprintf (file, ",r%d ; P_O_A reg + sym", REGNO (x));
|
||||
break;
|
||||
case LABEL_REF:
|
||||
output_address (XEXP (y, 0));
|
||||
fprintf (file, ",r%d ; P_O_A reg + label", REGNO (x));
|
||||
break;
|
||||
default:
|
||||
fprintf (file, "[P_O_A reg%d+UFO code=%d]",
|
||||
REGNO (x), GET_CODE (y));
|
||||
}
|
||||
break;
|
||||
case LABEL_REF:
|
||||
output_address (XEXP (x, 0));
|
||||
break;
|
||||
case SYMBOL_REF:
|
||||
switch (GET_CODE (y))
|
||||
{
|
||||
case CONST_INT:
|
||||
fprintf (file, "%d+%s", INTVAL (y) + addr_inc, XSTR (x, 0));
|
||||
break;
|
||||
case REG:
|
||||
fprintf (file, "%s,r%d ;P_O_A sym + reg",
|
||||
XSTR (x, 0), REGNO (y));
|
||||
break;
|
||||
default:
|
||||
fprintf (file, "P_O_A sym/lab+UFO[sym=%s,code(y)=%d]",
|
||||
XSTR (x, 0), GET_CODE (y));
|
||||
}
|
||||
break;
|
||||
case CONST:
|
||||
output_address (XEXP (x, 0));
|
||||
if (GET_CODE (y) == REG)
|
||||
fprintf (file, ",r%d ;P_O_A const + reg", REGNO (x));
|
||||
else
|
||||
fprintf (file, "P_O_A const+UFO code(y)=%d]", GET_CODE (y));
|
||||
break;
|
||||
case MEM:
|
||||
output_address (y);
|
||||
fprintf (file, ",[mem:");
|
||||
output_address (XEXP (x, 0));
|
||||
fprintf (file, "] ;P_O_A plus");
|
||||
break;
|
||||
default:
|
||||
fprintf (file, "P_O_A plus op1_UFO[code1=%d,code2=%d]",
|
||||
GET_CODE (x), GET_CODE (y));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CONST_INT:
|
||||
if (INTVAL (addr) < 0x10000 && INTVAL (addr) >= -0x10000)
|
||||
fprintf (file, "%d ; p_o_a const addr?!", INTVAL (addr));
|
||||
else
|
||||
{
|
||||
fprintf (file, "[p_o_a=ILLEGAL_CONST]");
|
||||
output_addr_const (file, addr);
|
||||
}
|
||||
break;
|
||||
case LABEL_REF:
|
||||
case SYMBOL_REF:
|
||||
fprintf (file, "%s", XSTR (addr, 0));
|
||||
if (addr_inc)
|
||||
fprintf (file, "+%d", addr_inc);
|
||||
break;
|
||||
case MEM:
|
||||
fprintf (file, "[memUFO:");
|
||||
output_address (XEXP (addr, 0));
|
||||
fprintf (file, "]");
|
||||
break;
|
||||
case CONST:
|
||||
output_address (XEXP (addr, 0));
|
||||
fprintf (file, " ;P_O_A const");
|
||||
break;
|
||||
case CODE_LABEL:
|
||||
fprintf (file, "L%d", XINT (addr, 3));
|
||||
break;
|
||||
default:
|
||||
fprintf (file, " p_o_a UFO, code=%d val=0x%x",
|
||||
(int) GET_CODE (addr), INTVAL (addr));
|
||||
break;
|
||||
}
|
||||
addr_inc = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return non zero if the LS 16 bits of the given value has just one bit set,
|
||||
* otherwise return zero. Note this function may be used to detect one
|
||||
* bit clear by inverting the param.
|
||||
*/
|
||||
int
|
||||
one_bit_set_p (x)
|
||||
int x;
|
||||
{
|
||||
x &= 0xffff;
|
||||
return x && (x & (x - 1)) == 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the number of the least significant bit set, using the same
|
||||
* convention for bit numbering as in the MIL-STD-1750 sb instruction.
|
||||
*/
|
||||
int
|
||||
which_bit (x)
|
||||
int x;
|
||||
{
|
||||
int b = 15;
|
||||
|
||||
while (b > 0 && (x & 1) == 0)
|
||||
{
|
||||
b--;
|
||||
x >>= 1;
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
|
1347
config/1750a/1750a.h
Normal file
1347
config/1750a/1750a.h
Normal file
File diff suppressed because it is too large
Load Diff
1436
config/1750a/1750a.md
Normal file
1436
config/1750a/1750a.md
Normal file
File diff suppressed because it is too large
Load Diff
158
config/1750a/ms1750.inc
Normal file
158
config/1750a/ms1750.inc
Normal file
@ -0,0 +1,158 @@
|
||||
;; GCC assembler includefile for AS1750
|
||||
;;
|
||||
;; Macros defined:
|
||||
;; EFLR.M #d,#s Load the three regs starting at R#s to R#d following.
|
||||
;; RET.M #fs Return from function (uses the framesize #fs)
|
||||
|
||||
|
||||
UC SET 15
|
||||
|
||||
; Return from function ; parameter: framesize
|
||||
MACRO RET.M
|
||||
IF `1` > 0
|
||||
IF `1` <= 16
|
||||
AISP R14,`1`
|
||||
ELSE
|
||||
AIM R14,`1`
|
||||
ENDIF
|
||||
ENDIF
|
||||
LR R15,R14
|
||||
URS R15
|
||||
ENDMACRO
|
||||
|
||||
; Useful instructions missing from the 1750A standard:
|
||||
|
||||
; Extended Float Load from Registers
|
||||
MACRO EFLR.M ; args : #1=dest-regno, #2=source-regno
|
||||
ONE SET `1` + 2
|
||||
TWO SET `2` + 2
|
||||
IF `1` >= `2` || `1`+2 < `2`
|
||||
LR R`ONE`,R`TWO`
|
||||
DLR R`1`,R`2`
|
||||
ELSE
|
||||
DLR R`1`,R`2`
|
||||
LR R`ONE`,R`TWO`
|
||||
DLR R`1`,R`1` ; Just to update condition codes
|
||||
ENDIF
|
||||
ENDMACRO
|
||||
|
||||
; The following leave the condition codes haywire. But that is
|
||||
; accounted for (see notice_update_cc in config/1750a.c.)
|
||||
|
||||
; Double ANd Register with Register
|
||||
MACRO DANR.M
|
||||
ONE SET `1` + 1
|
||||
TWO SET `2` + 1
|
||||
ANDR R`1`,R`2`
|
||||
ANDR R`ONE`,R`TWO`
|
||||
ENDMACRO
|
||||
|
||||
; Double OR Register with Register
|
||||
MACRO DORR.M
|
||||
ONE SET `1` + 1
|
||||
TWO SET `2` + 1
|
||||
ORR R`1`,R`2`
|
||||
ORR R`ONE`,R`TWO`
|
||||
ENDMACRO
|
||||
|
||||
; Double eXoR Register with Register
|
||||
MACRO DXRR.M
|
||||
ONE SET `1` + 1
|
||||
TWO SET `2` + 1
|
||||
XORR R`1`,R`2`
|
||||
XORR R`ONE`,R`TWO`
|
||||
ENDMACRO
|
||||
|
||||
; Double Nand Register with register
|
||||
MACRO DNR.M
|
||||
ONE SET `1` + 1
|
||||
TWO SET `2` + 1
|
||||
NR R`1`,R`2`
|
||||
NR R`ONE`,R`TWO`
|
||||
ENDMACRO
|
||||
|
||||
; Unsigned Compare Immediate
|
||||
|
||||
MACRO UCIM.M
|
||||
LAST SET `1` + 3
|
||||
PSHM R`1`,R`LAST`
|
||||
LO SET `1` + 1
|
||||
LR R`LO`,R`1`
|
||||
XORR R`1`,R`1`
|
||||
HI SET `1` + 2
|
||||
XORR R`HI`,R`HI`
|
||||
LIM R`LAST`,`2`
|
||||
DCR R`1`,R`HI`
|
||||
POPM R`1`,R`LAST`
|
||||
ENDMACRO
|
||||
|
||||
|
||||
; Unsigned Compare Register with register
|
||||
|
||||
MACRO UCR.M
|
||||
PSHM R10,R13 ; R12 and R13 are assumed not to be input parameters
|
||||
LR R13,R`2`
|
||||
LR R11,R`1`
|
||||
XORR R12,R12
|
||||
XORR R10,R10
|
||||
DCR R10,R12
|
||||
POPM R10,R13
|
||||
ENDMACRO
|
||||
|
||||
|
||||
; Unsigned Compare register with memory
|
||||
|
||||
MACRO UC.M
|
||||
PSHM R10,R13
|
||||
L R13,`2`
|
||||
LR R11,R`1`
|
||||
XORR R12,R12
|
||||
XORR R10,R10
|
||||
DCR R10,R12
|
||||
POPM R10,R13
|
||||
ENDMACRO
|
||||
|
||||
|
||||
; Double Unsigned Compare Register with register
|
||||
|
||||
MACRO DUCR.M
|
||||
PSHM R13,R14 ; R13 and R14 are assumed not to be input parameters
|
||||
LOW1 SET `1` + 1
|
||||
LOW2 SET `2` + 1
|
||||
PSHM R`1`,R`LOW1`
|
||||
PSHM R`2`,R`LOW2`
|
||||
LR R13,R`LOW1`
|
||||
LR R14,R`LOW2`
|
||||
DSRL R`1`,1
|
||||
DSRL R`2`,1
|
||||
DCR R`1`,R`2`
|
||||
BNE +6
|
||||
ANDM R13,1
|
||||
ANDM R14,1
|
||||
CR R13,R14
|
||||
POPM R`2`,R`LOW2`
|
||||
POPM R`1`,R`LOW1`
|
||||
POPM R13,R14
|
||||
ENDMACRO
|
||||
|
||||
|
||||
; Double Unsigned Compare register with memory
|
||||
|
||||
MACRO DUC.M
|
||||
PSHM R13,R14 ; R13 and R14 are assumed not to be input parameters
|
||||
LOW1 SET `1` + 1
|
||||
PSHM R`1`,R`LOW1`
|
||||
DL R13,`2`
|
||||
DSRL R`1`,1
|
||||
DSRL R13,1
|
||||
DCR R`1`,R13
|
||||
BNE +10 ; done, go pop the saved regs
|
||||
DL R13,`2` ; interested in the *low* word (R14)
|
||||
L R13,1,R15
|
||||
ANDM R13,1
|
||||
ANDM R14,1
|
||||
CR R13,R14
|
||||
POPM R`1`,R`LOW1`
|
||||
POPM R13,R14
|
||||
ENDMACRO
|
||||
|
23
config/1750a/xm-1750a.h
Normal file
23
config/1750a/xm-1750a.h
Normal file
@ -0,0 +1,23 @@
|
||||
/* Configuration for GNU C-compiler for MIL-STD-1750a.
|
||||
Copyright (C) 1995 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#error Gcc cannot run on a 1750a due to size problems!
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user