Import of unmodified (but trimmed) gcc-2.7.2. The bigger parts of the
non-i386, non-unix, and generatable files have been trimmed, but can easily be added in later if needed. gcc-2.7.2.1 will follow shortly, it's a very small delta to this and it's handy to have both available for reference for such little cost. The freebsd-specific changes will then be committed, and once the dust has settled, the bmakefiles will be committed to use this code.
This commit is contained in:
commit
a4cd5630b0
|
@ -0,0 +1,23 @@
|
|||
If you think you may have found a bug in GNU CC, please
|
||||
read the Bugs section of the Emacs 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,"
|
|
@ -0,0 +1,339 @@
|
|||
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
|
||||
|
||||
Appendix: 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.
|
|
@ -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!
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,735 @@
|
|||
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 DYNUX/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).
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -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.
|
|
@ -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
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
This directory contains the version 2.7.2 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).
|
|
@ -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.
|
|
@ -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.
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -0,0 +1,111 @@
|
|||
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.
|
||||
|
||||
|
||||
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 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.
|
|
@ -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.)
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,852 @@
|
|||
-*- text -*-
|
||||
GNU Service Directory
|
||||
---------------------
|
||||
|
||||
This is a list of people who have asked to be listed as offering
|
||||
support services for GNU software, including GNU Emacs, for a fee
|
||||
or in some cases at no charge.
|
||||
|
||||
The information comes from the people who asked to be listed;
|
||||
we do not include any information we know to be false, but we
|
||||
cannot check out any of the information; we are transmitting it to
|
||||
you as it was given to us and do not promise it is correct.
|
||||
Also, this is not an endorsement of the people listed here.
|
||||
We have no opinions and usually no information about the abilities of
|
||||
any specific person. We provide this list to enable you to contact
|
||||
service providers and decide for yourself whether to hire one.
|
||||
|
||||
Before FSF will list your name in the GNU Service Directory, we ask
|
||||
that you agree informally to the following terms:
|
||||
|
||||
1. You will not restrict (except by copyleft) the use or distribution
|
||||
of any software, documentation, or other information you supply anyone
|
||||
in the course of modifying, extending, or supporting GNU software.
|
||||
This includes any information specifically designed to ameliorate the
|
||||
use of GNU software.
|
||||
|
||||
2. You will not take advantage of contact made through the Service
|
||||
Directory to advertise an unrelated business (e.g., sales of
|
||||
non-GNU-related proprietary information). You may spontaneously
|
||||
mention your availability for general consulting, but you should not
|
||||
promote a specific unrelated business unless the client asks.
|
||||
|
||||
Please include some indication of your rates, because otherwise users
|
||||
have nothing to go by. Please put each e-mail address inside "<>".
|
||||
Please put nothing else inside "<>". Thanks!
|
||||
|
||||
For a current copy of this directory, or to have yourself listed, ask:
|
||||
gnu@prep.ai.mit.edu
|
||||
|
||||
** Please keep the entries in this file alphabetical **
|
||||
|
||||
|
||||
Joseph Arceneaux <jla@ai.mit.edu>
|
||||
PO Box 460633 http://www.samsara.com/~jla
|
||||
San Francisco, CA 94146-0633
|
||||
+1 415 648 9988
|
||||
+1 415 285 9088
|
||||
|
||||
Recently led the project making Wells Fargo Bank the first to provide
|
||||
secure customer account access over the Internet.
|
||||
|
||||
Former FSF staffmember. Performed X11 implementation of Emacs version
|
||||
19, designed and implemented WYSIWYG Emacs. Installed and
|
||||
administered FSF network. Maintainer of GNU indent. Over 15 years
|
||||
experience with Unix and other systems, from writing ROM monitors to
|
||||
UI design and system administration.
|
||||
|
||||
I provide installation, porting, debugging and customization or
|
||||
development of GNU and other Unix software. I also design and
|
||||
implement free software projects and consult on software engineering
|
||||
and systems design. Handholding and teaching services are also
|
||||
available as well as things like LAN and compute--infrastructure design.
|
||||
|
||||
Time and material rates around $150 USD per hour, depending upon the
|
||||
particular job. I am also very interested in fixed-bid jobs. For
|
||||
selected non-profit organizations with worthy goals, I work for free.
|
||||
|
||||
Updated: 17Oct95
|
||||
|
||||
Gerd Aschemann <aschemann@Informatik.TH-Darmstadt.de>
|
||||
Osannstr. 49
|
||||
D-64285 Darmstadt
|
||||
Tel.: +49 6151 16 2259
|
||||
http://www.informatik.th-darmstadt.de/~ascheman/
|
||||
|
||||
- System Administrator (UNIX) at CS Department, TU Darmstadt, Germany
|
||||
- 15 years expirience with CS, Systemadministration on different platforms
|
||||
- 8 years with UNIX/Networking/FreeWare/GNU/X11
|
||||
- 6 years organizer of Operating Systems and Distributed Systems courses
|
||||
- Lectures on System and Network Administration
|
||||
- Platforms: Solaris, SunOS, Ultrix, OSF1, HP-UX, Linux, FreeBSD, AIX
|
||||
- Experience with parallel environments (Connection Machine, Meiko, Parsytec)
|
||||
- Consultant for other UNIX users at TU Darmstadt
|
||||
|
||||
Rates are at 100,-- DM (~60 US$) per hour minimum, depending on the job.
|
||||
I am willing to travel for sufficiently large jobs.
|
||||
|
||||
Updated: 17Oct95
|
||||
|
||||
Giuseppe Attardi <attardi@di.unipi.it>
|
||||
Dipartimento di Informatica
|
||||
Corso Italia 40
|
||||
I-56125 Pisa, Italy
|
||||
+39 50 887-244
|
||||
|
||||
GNU: help on obtaininig GNU, for italian sites.
|
||||
|
||||
Updated: 5Apr94
|
||||
|
||||
James Craig Burley
|
||||
97 Arrowhead Circle
|
||||
Ashland, MA 01721-1987
|
||||
508 881-6087, -4745
|
||||
(Please call only between 0900-1700 Eastern time, and only if you
|
||||
are prepared to hire me -- ask me to help you for free only
|
||||
via email, to which I might or might not respond.)
|
||||
Email: <burley@gnu.ai.mit.edu> --preferred--
|
||||
<burley@cygnus.com>
|
||||
<burley@world.std.com>
|
||||
|
||||
Expertise:
|
||||
Compiler Internals (author of GNU Fortran, for example)
|
||||
Operating Systems Internals
|
||||
Tools/Utilities Development and Maintenance
|
||||
Microcode Development and Maintenance (primarily VLIW machines)
|
||||
System Design (computers, operating systems, toolsets, &c)
|
||||
Debugging (often asked to help debug Other People's Code)
|
||||
Documentation (authored many books and ran a few doc projects)
|
||||
Extensive experience with a variety of operating systems, hardware,
|
||||
languages, and so on
|
||||
|
||||
Rate: $70/hour -- willing to consider flat-fee arrangements
|
||||
|
||||
Updated: 14Aug95
|
||||
|
||||
Michael I. Bushnell <mib@gnu.ai.mit.edu>
|
||||
545 Technology Square, NE43-426
|
||||
Cambridge, MA 02139
|
||||
(617) 253-8568
|
||||
|
||||
All GNU software: Installation, customization, answering simple or
|
||||
complex questions, bug fixing, extension.
|
||||
|
||||
Experience: I have done Unix and GNU programming for several years,
|
||||
I am the primary author of the Hurd (which provides most
|
||||
kernel related facilities for the GNU OS).
|
||||
|
||||
I am easily available in the Cambridge/Boston area; work via email.
|
||||
I am willing to travel for sufficiently large jobs.
|
||||
|
||||
Rates: $100/hr, negotiable, less for non-profit organizaions.
|
||||
|
||||
Updated: 5Apr94
|
||||
|
||||
C2V Renaud Dumeur <renaud@ccv.fr>
|
||||
82 bd Haussmann Michel Delval <mfd@ccv.fr>
|
||||
75009 Paris Jean-Alain Le Borgne <jalb@ccv.fr>
|
||||
France
|
||||
Tel (1) 40.08.07.07
|
||||
Fax (1) 43.87.35.99
|
||||
|
||||
We offer source or source+binary distribution, installation, training,
|
||||
maintenance, technical support, consulting, specific development and
|
||||
followup on the GNU software development environment: Emacs, gcc/g++,
|
||||
binutils, gas, gdb.
|
||||
|
||||
Experience: adapted gcc, gas and binutils to work as cross-development
|
||||
tools for the Thomson st18950 DSP chip: GCC parser and typing system
|
||||
have been augmented to allow the manipulation of variables located in
|
||||
separated memory spaces. Porting on new platforms, and professionally
|
||||
developing software with the GNU tools in the Unix/X11 environment
|
||||
since they were first available.
|
||||
|
||||
Rates: from 2000 FF/day to 150 000 FF/year, 40% discount for
|
||||
educational institutions, add taxes and expenses. Ask for list.
|
||||
|
||||
Entered: 5May94
|
||||
|
||||
Contributed Software
|
||||
Graefestr. 76
|
||||
10967 Berlin, Germany
|
||||
phone: (+49 30) 694 69 07
|
||||
FAX: (+49 30) 694 68 09
|
||||
modems: (+49 30) 694 60 55 (5xZyXEL )
|
||||
modems: (+49 30) 693 40 51 (8xUSR DS)
|
||||
email: <info@contrib.de>
|
||||
internet: uropax.contrib.de [192.109.39.2], login as 'guest'.
|
||||
|
||||
We distribute, install, port, teach and support free software
|
||||
in general, i.e. X11, GNU, khoros etc. Rates are ECU 80,-- plus
|
||||
tax per hour. We offer maintenance and support contracts for full
|
||||
customer satisfaction.
|
||||
Highlights are transparent development environments for multi-platform
|
||||
sites and configuration management. Traveling is no problem.
|
||||
|
||||
Free Archive login for downloading on above modem numbers.
|
||||
|
||||
Updated: 5Apr94
|
||||
|
||||
Stuart Cracraft <cracraft@ai.mit.edu>
|
||||
25682 Cresta Loma
|
||||
Laguna Niguel, Ca.
|
||||
92677
|
||||
GNUline: 714-347-8106
|
||||
Rate: $75/hour
|
||||
Consultation topics:
|
||||
Entire GNU suite - porting, compilation, installation,
|
||||
user-training, administrator-training
|
||||
Method: telephone line support, call-in via modem to your site,
|
||||
or direct visit.
|
||||
|
||||
Experience: supporting GNU since the mid-1980's, coordinator
|
||||
of GNU Chess (original author), GNU Shogi, GNU Go. Ported GNU Emacs
|
||||
to Solaris (System V Release 4). Expertise in C, Emacs Lisp, and Perl.
|
||||
Customized programming also available.
|
||||
|
||||
Entered: 5Apr94
|
||||
|
||||
Cygnus Support <info@cygnus.com>
|
||||
1937 Landings Drive ...uunet!cygint!info
|
||||
Mountain View, CA 94043 USA
|
||||
+1 415 903 1400 voice
|
||||
+1 415 903 0122 fax
|
||||
|
||||
Cygnus Support
|
||||
48 Grove Street
|
||||
Somerville, MA 02144
|
||||
+1 617 629 3000 voice
|
||||
+1 617 629 3010 fax
|
||||
|
||||
Cygnus Support continues to provide supported, maintained versions of
|
||||
the GNU toolset including GCC, G++, the GNU debugger with graphical
|
||||
user interface, GNU linker, GNU macro-assembler and Emacs 19. In
|
||||
keeping with the rapidly advancing needs of software developers,
|
||||
Cygnus maintains a 90 day release cycle of the GNU toolset. Each
|
||||
release is regression tested and includes substantial improvements and
|
||||
additions to the existing matrix of over 65 supported platform
|
||||
configurations.
|
||||
|
||||
Updated: 2Feb95
|
||||
|
||||
Free Software Association of Germany
|
||||
Michaela Merz
|
||||
Heimatring 19
|
||||
6000 Frankfurt/Main 70
|
||||
phone: (+49 69) 6312083)
|
||||
ert : (+49-172-6987246)
|
||||
email: (info@elara.fsag.de)
|
||||
|
||||
Supporting all kinds of freeware (i.e. GNU), freeware development, consulting,
|
||||
training, installation. Special LINUX support group.
|
||||
|
||||
RATES:
|
||||
|
||||
Companies and for profit
|
||||
organizations : 100 US$ / hour
|
||||
Private and not-for-profit
|
||||
organizations : 40 US$ / hour
|
||||
ert (24h Emergency
|
||||
response team) : 300 US$ / hour
|
||||
|
||||
Entered: 14Apr94
|
||||
|
||||
Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
Building 600, Suite 214 2002-A Guadalupe St. #214
|
||||
One Kendall Square Austin, TX 78705
|
||||
Cambridge, MA 02139 (Local, faster to reach me)
|
||||
(Permanent)
|
||||
|
||||
|
||||
Author of several Emacs Lisp packages and parts of Emacs 19, as well as
|
||||
numerous utilities written in shell script and perl. Co-maintained GNU
|
||||
Texinfo and Autoconf for a couple of years. System administrator for a
|
||||
network of heterogenous machines. FSF employee Feb 1991--Sep 1994.
|
||||
|
||||
I can perform installation, porting, and enhancement of all GNU software
|
||||
and any other free software; system administration for unix-type systems
|
||||
and ethernet networks; and I am willing to teach shell programming and
|
||||
Emacs Lisp.
|
||||
|
||||
Fees negotiable, averaging $60-$75/hour. I can work in the Austin, TX area
|
||||
or anywhere accessible on the Internet. For larger jobs I may be willing
|
||||
to travel.
|
||||
|
||||
Updated: 16Aug95
|
||||
|
||||
Ronald F. Guilmette <rfg@monkeys.com>
|
||||
Infinite Monkeys & Co.
|
||||
1751 East Roseville Pkwy. #1828
|
||||
Roseville, CA 95661
|
||||
Tel: +1 916 786 7945
|
||||
FAX: +1 916 786 5311
|
||||
|
||||
Services: Development & porting of GNU software development tools.
|
||||
|
||||
GNU Contributions:
|
||||
Invented, designed, and implemented the protoize and
|
||||
unprotoize tools supplied with GCC2.
|
||||
|
||||
Designed and developed all code to support the generation
|
||||
of Dwarf symbolic debugging information for System V Release
|
||||
4 in GCC2.
|
||||
|
||||
Performed original port of GNU compilers to SVr4 system.
|
||||
|
||||
Finished port of GNU compilers to Intel i860 RISC
|
||||
processor.
|
||||
|
||||
Experience: 13+ years UNIX systems experience, all working on compilers
|
||||
and related tools.
|
||||
|
||||
7+ years working professionally on GCC, G++, and GDB under
|
||||
contract to various firms including the Microelectronics
|
||||
and Computer Technology Corporation (MCC), Data General (DG),
|
||||
Network Computing Devices (NCD), and Intel Corp.
|
||||
|
||||
Other qualifications:
|
||||
Developer of the RoadTest (tm) C and C++ commercial
|
||||
compiler test suites.
|
||||
|
||||
Former vice-chairman of UNIX International Programming
|
||||
Languages Special Interest Group (UI/PLSIG).
|
||||
|
||||
Bachelor's and a Master's degrees, both in Computer Science.
|
||||
|
||||
Rates: Variable depending upon contract duration. Call for quote.
|
||||
|
||||
Updated: 23Sep95
|
||||
|
||||
Hundred Acre Consulting <info@pooh.com>
|
||||
1155 W Fourth St Ste 225
|
||||
PO Box 6209
|
||||
Reno NV 89513-6209
|
||||
(702)-348-7299
|
||||
Hundred Acre is a consulting group providing support and development
|
||||
services to organizations of all sizes. We support GNU C++ and C in
|
||||
particular, but also provide support for all other GNU software and
|
||||
certain non-GNU public domain software as well. We work on a "service
|
||||
contract" basis for support -- for a yearly fee, we provide multiple
|
||||
levels of email and toll free telephone support, and free updates and
|
||||
bug fixes. The highersupport levels have on-site support. Development
|
||||
is charged on either an hourly or fixed bid basis.
|
||||
|
||||
Consulting rates: $70 to $90 per hour, or fixed bid.
|
||||
Support contracts: Several levels, from $495 to $90000 per year.
|
||||
|
||||
Updated: 27Dec94
|
||||
|
||||
Interactive Information Limited
|
||||
|
||||
Interactive Information Limited is an Edinburgh-based company that
|
||||
specialises in WWW services and support for using the Internet for
|
||||
marketing.
|
||||
|
||||
Our staff have many years experience in using, and developing lisp packages
|
||||
within, Emacs, and in using other GNU/Unix tools, particularly under public
|
||||
domain UNIXes.
|
||||
|
||||
We can provide services throughout the UK, at any level from general
|
||||
consultancy through fetching, installing and customising software to
|
||||
bespoke programming. Fees would be in the range #300 - #600 per day,
|
||||
depending primarily on the size of the job.
|
||||
|
||||
You can contact us
|
||||
by email: <enquire@interactive.co.uk>
|
||||
by phone: 0370 30 40 52 (UK)
|
||||
(+44) 370 30 40 52 (International)
|
||||
by post: 3, Lauriston Gardens,
|
||||
Edinburgh EH3 9HH
|
||||
Scotland
|
||||
|
||||
Entered: 13Nov95
|
||||
|
||||
Scott D. Kalter <sdk@mithril.com)
|
||||
2032 Corral Canyon
|
||||
Malibu, CA 90265-9503
|
||||
Home: (310) 456-0254
|
||||
|
||||
Emacs: Eoops, Elisp, and C level customization/extension training for
|
||||
general use and customization user support, installation, and
|
||||
troubleshooting.
|
||||
|
||||
Rates: $50/hr
|
||||
May answer brief and interesting questions for free.
|
||||
Prefer e-mail communication to telephone.
|
||||
|
||||
Qualifications: BS Math/CS 1985: Carnegie Mellon University
|
||||
MS CS 1988: UCLA
|
||||
|
||||
Very familiar with all levels of elisp programming. Taught
|
||||
Emacs use and customization in universities and industry. Extensive
|
||||
troubleshooting and user support experience. Co-developed an
|
||||
object-oriented extension to Elisp that can be used for
|
||||
projects. Extensive Elisp level modification for rapid
|
||||
prototyping of designs used in groupware research. This
|
||||
includes the development of an infrastructure to support
|
||||
multiple, communicating Emacs processes.
|
||||
|
||||
Updated: 6Apr94
|
||||
|
||||
KAMAN SCIENCES CORPORATION
|
||||
258 GENESEE STREET
|
||||
UTICA NY 13502
|
||||
(315) 734-3600
|
||||
|
||||
CONTACTS: Alan Piszcz (peesh) <apiszcz@utica1.kaman.com>
|
||||
: Dennis Fitzgerald <dennis@utica.kaman.com>
|
||||
|
||||
Kaman Sciences has performed a GNU port for a custom RISC processor.
|
||||
We have experience in the definition and description of the machine
|
||||
register transfer language to the GNU tool-set. This includes rewriting
|
||||
and modification of the necessary description and source files of gcc, gas,
|
||||
and gld and other binutils. Kaman also has services for installation and
|
||||
setup of GNU tools, (GAWK, GCC, EMACS, etc.) on Sun workstations.
|
||||
|
||||
Work is on a "service contract" basis and development is charged either
|
||||
hourly or as a fixed price contract.
|
||||
|
||||
Consulting rates: $70 to $200 per hour.
|
||||
|
||||
Entered: 13Jan95
|
||||
|
||||
Scott J. Kramer <sjk@aura.nbn.com>
|
||||
P.O. Box 620207
|
||||
Woodside, CA 94062
|
||||
+1 415-941-0755
|
||||
|
||||
GNU Software: Tutoring, installations/upgrades, Emacs Lisp customizations,
|
||||
general troubleshooting/support. Prefer that work I do
|
||||
becomes part integrated into official Free Software Foundation
|
||||
distributions.
|
||||
|
||||
Systems Administration: Sun (SunOS & Solaris) and SGI (IRIX)
|
||||
UNIX hardware/software platforms.
|
||||
|
||||
Rate: Task- and time-dependent; non-monetary offers accepted.
|
||||
|
||||
Updated: 12Apr94
|
||||
|
||||
Fen Labalme <fen@comedia.com)
|
||||
Broadcatch Technologies
|
||||
40 Carl St. #4 WE ARE EVERYWHERE
|
||||
San Francisco CA 94117 JUST SAY "KNOW"
|
||||
(415) 731-1174 ARE YOU KIND?
|
||||
|
||||
Rates: $80 hour (negotiable); quick email or phone questions free.
|
||||
Lower rates -- free of barter -- for schools and non-profits.
|
||||
|
||||
Consulting, installation, customization and training for GNU Emacs,
|
||||
and selected other GNU & network software (but not G++). I have been
|
||||
hacking Emacs since '76 when it was TECO and ^R macros (don't ask).
|
||||
|
||||
Updated: 6Apr94
|
||||
|
||||
Greg Lehey
|
||||
LEMIS
|
||||
Schellnhausen 2
|
||||
36325 Feldatal
|
||||
Germany
|
||||
|
||||
Phone: +49-6637-919123
|
||||
Fax: +49-6637-919122
|
||||
Mail <grog@lemis.de>
|
||||
|
||||
Services: Supply, porting, installation, consultation on all GNU
|
||||
products.
|
||||
|
||||
Experience: 20 years OS and compiler experience, portations of most
|
||||
GNU products. Author of ported software CD-ROM for Unix 4.2.
|
||||
|
||||
Rates: Choice of DM 150 per hour or hotline rates 3 DM per minute + 10
|
||||
DM per phone call. Quick questions may be free. Limited free support
|
||||
available for purchasers of LEMIS CD-ROMs.
|
||||
|
||||
Updated: 21Feb95
|
||||
|
||||
Marty Leisner <leisner@sdsp.mc.xerox.com>
|
||||
332 Shaftsbury Road
|
||||
Rochester, New York 14610
|
||||
Home:(716) 654-7931
|
||||
|
||||
Experience: 12 years C/Unix, 7 years DOS.
|
||||
Extensive experience with GNU binary tools, cross-compilers,
|
||||
embedded/hosted systems, realtime.
|
||||
Degree : BS CS, Cornell University
|
||||
Rates: $75/hr
|
||||
|
||||
|
||||
|
||||
marty
|
||||
<leisner@sdsp.mc.xerox.com> <leisner@eso.mc.xerox.com>
|
||||
|
||||
Updated: 15Apr94
|
||||
|
||||
Richard Levitte (in TeX: Richard Levitte
|
||||
Södra Långgatan 39, II S\"odra L{\aa}nggatan 39, II
|
||||
S-171 49 Solna S-171 49 Solna
|
||||
Sweden Sweden)
|
||||
Tel.nr.: +46 (8) 18 30 99 (there is an answering machine)
|
||||
e-mail: <levitte@e.kth.se> (preferred)
|
||||
<levitte@vms.stacken.kth.se>
|
||||
|
||||
What I do:
|
||||
Primarly I work on GNU software for VMS, both VAX and AXP. I
|
||||
also work on GNU stuff for Unix on occasion. I'm familiar with
|
||||
SunOS (version 4.x.x), BSD (version 4.2 and up),
|
||||
Ultrix (version 4.2 and up).
|
||||
I've been porting GNU Emacs to VMS since spring 1991. This
|
||||
includes versions 18.57 to 18.59 and version 19.22.
|
||||
I maintain GNU vmslib.
|
||||
|
||||
Programs supported:
|
||||
GNU vmslib: extending, installation, upgrading aid,
|
||||
simple and complex questions, you name it.
|
||||
GNU Emacs: porting, extending, installation, upgrading aid,
|
||||
customization, simple or complex questions,
|
||||
training, you name it.
|
||||
GNU autoconf: porting, extending, installation, upgrading aid.
|
||||
GNU zip, diffutils, m4, patch, texinfo:
|
||||
porting, installation, upgrading aid.
|
||||
GNU C/C++: installation, upgrading aid. I might start to
|
||||
hack at it some day.
|
||||
|
||||
The list of programs I currently support represents both my interests and
|
||||
current priorities. Your interest and funding can influence my priorities.
|
||||
|
||||
Experience:
|
||||
Fluent in C, C++, Emacs Lisp, Pascal as well as assembler
|
||||
on VAX, Motorola 680x0, Intel 8086 and 80x86. Modified key
|
||||
elements in Emacs (e.g., memory and process management) to work
|
||||
transparently on VMS. I have very good knowledge in the VMS
|
||||
operating system, as well as MS-DOS and IBM PC compatibles.
|
||||
I have worked for four and a half years as a VMS system manager.
|
||||
I've also provided consulting services on IBM PC compatibles,
|
||||
as well as held classes for IBM PC users.
|
||||
A reference list is available on request.
|
||||
|
||||
Your Rate:
|
||||
$50-$80/hour (400-700 SEK in sweden), plus expenses. My rates
|
||||
are negotiable, depending on how interesting the project is to me.
|
||||
|
||||
|
||||
Entered: 18Aug94
|
||||
|
||||
Roland McGrath <roland@frob.com>
|
||||
545 Tech Sq, Rm 426
|
||||
Cambridge, MA 02139
|
||||
Work: (617) 253-8568
|
||||
|
||||
Co-author of GNU Make (with Richard Stallman); maintainer of GNU Make.
|
||||
Author and maintainer of the GNU C Library and co-author of the GNU Hurd.
|
||||
Author of several GNU Emacs Lisp packages and parts of GNU Emacs 19.
|
||||
FSF employee summer 1989, fall 1990 to the present.
|
||||
|
||||
Installation, maintenance, porting, enhancement of all GNU software. I can
|
||||
install GNU software and maintain its installation on call via the Internet.
|
||||
|
||||
Fees negotiable; $75-$100/hour, higher for very short term projects. I can
|
||||
work anywhere in the Boston or SF Bay Area, or anywhere on the Internet. I
|
||||
am working full-time for the FSF on the GNU Hurd, so I am likely to take on
|
||||
only jobs that either can be done entirely via the Internet and are
|
||||
short-term, or that are very interesting.
|
||||
|
||||
Updated: 21Jan95
|
||||
|
||||
Wolfgang S. Rupprecht <wolfgang@wsrcc.com>
|
||||
47 Esparito Ave.
|
||||
Fremont, CA 94539-3827
|
||||
(510) 659-9757
|
||||
|
||||
Anything, (lisp, C, customization, porting, installing) I have
|
||||
written thousands of lines of GNU Emacs C and Lisp code. Original
|
||||
author of the floating point additions in Emacs 19.
|
||||
|
||||
Rates: $95/hr.
|
||||
|
||||
Updated: 14Apr94
|
||||
|
||||
Signum Support AB <info@signum.se>
|
||||
Box 2044 _ ...!seunet!signum!info
|
||||
S-580 02 Linkoping, Sweden
|
||||
+46 13 21 46 00 voice
|
||||
+46 13 21 47 00 fax
|
||||
|
||||
Signum Support AB is a company dedicated to supporting, developing
|
||||
and distributing free software for, including but not limited to,
|
||||
UNIX systems. The people behind Signum Support AB have many years
|
||||
of general UNIX experience, both as system administrators and as
|
||||
programmers, and also extensive experience in maintaining the GNU
|
||||
programs, both administrating it and finding and fixing bugs.
|
||||
|
||||
Services offered:
|
||||
|
||||
- Installation and customizing GNU and other free software. We will
|
||||
make free software as easy to install and use as shrink wrapped
|
||||
programs.
|
||||
- Warranty protection.
|
||||
- Customization and porting.
|
||||
- Subscriptions to new versions which we will send monthly or with
|
||||
any other interval.
|
||||
- Finding, Recommending and Investigation of free software in any
|
||||
area of the customers choise.
|
||||
- Regular consulting.
|
||||
|
||||
Rates: For software items, request our price list.
|
||||
For consulting, 400-800 SEK/hour.
|
||||
|
||||
Updated: 14Apr94
|
||||
|
||||
Small Business Systems, Inc. <postmaster@anomaly.sbs.com>
|
||||
Box 17220, Route 104
|
||||
Esmond, RI 02917
|
||||
401.273.4669
|
||||
|
||||
Rate: Varies depending on complexity of task.
|
||||
Hourly and fixed-rate contracts are available.
|
||||
Programs Supported: All
|
||||
|
||||
Updated: 14Apr94
|
||||
|
||||
Julian H. Stacey. <stacey@freefall.cdrom.com>
|
||||
Vector Systems Ltd, Holz Strasse 27d, D 80469 Munich (Muenchen), GERMANY.
|
||||
Tel. +49 89 268616 (089 268616 in Germany) 09:00-21:00 Timezone=GMT+01:00
|
||||
|
||||
Sources: All FSF/GNU, FreeBSD-current, X-Windows, XFree86, NetBSD, Mach, etc.
|
||||
(Plus various other things, such as, but not limited to:
|
||||
blas blt cflow CAD cnews crypt dvi2lj eispack elm encryption expect
|
||||
ezd f2c flexfax gic gopher info-zip ingres inn jpeg kermit ksh
|
||||
less lha linpack md5 mh mprof mtools mush nntp octave pbmplus
|
||||
popper sather sc schemetoc slurp sml spreadsheet sup tcl tcl-dp
|
||||
tcsh tcx term tex tiff tk top trn unarj ups urt wine xlock xv
|
||||
xview xxgdb zmodem zip zircon zoo zsh.)
|
||||
Media: QIC 1/4" Cartridge 525M, 150M, & 60M, TEAC CAS-60 60M Cassette,
|
||||
CD-ROM, Floppies 1.4M & 1.2 & 720K & 360K. DAT arrangeable.
|
||||
Postal Service C.O.D.(=`Nachnahme') or pre payment available.
|
||||
Commercial Consultancy:
|
||||
Custom Designs, Provision & support of FreeBSD or Unix, C, FSF tools,
|
||||
X Windows, own tools, systems engineering, hardware interfacing,
|
||||
multi lingual European, Cyrillic & Chinese tools & systems,
|
||||
Unix, MSDOS, real time etc, communications & scientific & industrial.
|
||||
DEUTSCH + FRANCAIS:
|
||||
Man kann mir in Deutsch schreiben, (oder mich anrufen).
|
||||
Je comprend Francais, mais je n'ecris pas des responses en Francais.
|
||||
(Contact me in English, German, or French).
|
||||
FREE for Symmetric Computer Systems Model 375 owners:
|
||||
Free Binaries & sources on SCS/375's TEAC 50/60M Cassette, for:
|
||||
GCC-1.40, UUCP-1.4, Ghostscript 2.3, Tar-1.08, Gzip-1.2.2 etc.
|
||||
(Native SCS compiler can't compile GCC on this NSC32016 based BSD4.2)
|
||||
On Request: Resume, Company Profile, Index of public & proprietary tools,
|
||||
Rate: ~120 DM/hour. ~100DM/Cartridge. (1.5DM = $1 USA = 0.6 UK Pounds @4/'94)
|
||||
Short enquiries free. (Kurze Anfragen Ohne Gebuhr).
|
||||
|
||||
Updated: 14Jun94
|
||||
|
||||
Richard M. Stallman <rms@prep.ai.mit.edu>
|
||||
UUCP: {mit-eddie,ucbvax,uunet,harvard,uw-beaver}!ai.mit.edu!rms
|
||||
545 Tech Sq, Rm 430
|
||||
Cambridge, MA 02139
|
||||
|
||||
Emacs: anything whatever
|
||||
Is anyone interested in courses in using or extending GNU Emacs?
|
||||
|
||||
Original inventor of Emacs and main author of GNU Emacs and GCC.
|
||||
|
||||
Rates: $6/min or $250/hr.
|
||||
|
||||
Updated: 14Apr94
|
||||
|
||||
JoS-Ware Comp Tech Johan Svensson <support@spird.jos.ec.lu.se>
|
||||
Box 739
|
||||
220 07 LUND
|
||||
SWEDEN
|
||||
Tel +46-46-104505 (Dept. of Economics, University of LUND)
|
||||
Fax +46-46-188445 (JoS-Ware Comp Tech)
|
||||
|
||||
What: We offer consulting services regarding installation,
|
||||
customization, troubleshooting, porting and integration
|
||||
of all free software, including GNU software.
|
||||
|
||||
Spec.: Network integration, integration of public domain software
|
||||
into commercial systems, WorldWideWeb, C, X-Windows, Linux,
|
||||
networked information systems
|
||||
|
||||
How: Remote login over internet, email, modem, phone, personal
|
||||
visits (in southern Sweden mainly)
|
||||
|
||||
Rates: 550SEK (+ tax) per hour within Sweden
|
||||
370SEK (+ tax) per hour within Sweden for educational org.
|
||||
US $90 per hour outside Sweden
|
||||
US $70 per hour outside Sweden for educational org.
|
||||
Note: fees may vary and special arrangements may be considered
|
||||
|
||||
Entered: 7Apr94
|
||||
|
||||
Kayvan Sylvan <kayvan@satyr.Sylvan.COM>
|
||||
Sylvan Associates
|
||||
879 Lewiston Drive
|
||||
San Jose, CA 95136
|
||||
Phone: 408-978-1407
|
||||
|
||||
I will help you port, install and customize GNU Emacs, GCC, G++,
|
||||
bison, and other GNU tools on almost any architechture and operating
|
||||
system. Questions answered. GNU C and lisp hacking available. I will
|
||||
also do ongoing support and periodic upgrades if you get on my GNU
|
||||
software subscription list.
|
||||
|
||||
Rates: $60-$100/hour, depending on type of work. Substantial discounts
|
||||
for long-term contracts and also for educational or non-profit
|
||||
institutions.
|
||||
|
||||
Experience: Many different Unix systems (2.9BSD to 4.4BSD, SVR3 and
|
||||
SVR4, Linux, Xenix). Systems programming and system administration on all
|
||||
brands of Unix. Kernel hacking experience. Lots of porting experience.
|
||||
I can port anything to anything (within reason).
|
||||
|
||||
Updated: 14Apr94
|
||||
|
||||
Leonard H. Tower Jr. <tower@prep.ai.mit.edu>
|
||||
36 Porter Street
|
||||
Somerville, MA 02143, USA
|
||||
+1 (617) 623-7739
|
||||
|
||||
Will work on most GNU software.
|
||||
Installation, handholding, trouble shooting, extensions, teaching.
|
||||
|
||||
Rates: 100.00/hour + travel expenses. Negotiable for non-profits.
|
||||
|
||||
Experience: Have hacked on over a dozen architectures in many languages. Have
|
||||
system mothered several varieties of Unixes. Assisted rms with the front end
|
||||
of gcc and it's back-end support. Resume available on request.
|
||||
|
||||
Entered: 14Apr94
|
||||
|
||||
UrbanSoft AO <info@usoft.spb.su>
|
||||
68 Malooktinskii Prospect
|
||||
St. Petersburg, Russia 195272
|
||||
|
||||
Custom GhostScript and TeX programming by e-mail.
|
||||
Database documents, directories, standard forms.
|
||||
|
||||
UrbanSoft uses a portion of its revenues to contribute
|
||||
diskette distributions of GNU software to Russian
|
||||
universities (most of which lack FTP access).
|
||||
|
||||
Rates: 30,000 rubles (currently USD 16.80) per hour.
|
||||
Fixed rate contracts also possible.
|
||||
Payable by bank transfer.
|
||||
|
||||
Updated: 20Apr94
|
||||
|
||||
noris network
|
||||
Matthias Urlichs
|
||||
Schleiermacherstrasse 12
|
||||
90491 Nuernberg
|
||||
Germany
|
||||
Phone: +49 911 9959621
|
||||
Fax: +49 911 5980150
|
||||
<info@noris.de>
|
||||
http://info.noris.de/ (German)
|
||||
|
||||
Expertise:
|
||||
OS internals, esp. Linux and BSD, esp. device drivers
|
||||
Network protocol / program design and coding
|
||||
Utilities coding and maintainance
|
||||
Program debugging, testing
|
||||
User interface design and testing
|
||||
Several programming and tool languages
|
||||
|
||||
Services:
|
||||
Installation, debugging, enhancement, distribution,
|
||||
for all kinds of free software.
|
||||
System administration for most Unix-like systems.
|
||||
Email, Fax, phone, and in-person consulting (and/or "question answering").
|
||||
Remote support and system monitoring (over the Internet),
|
||||
Update service (new tools tested and installed automagically)
|
||||
Internet access
|
||||
|
||||
Rates:
|
||||
DM 110 (~$70) per hour
|
||||
Support contracts start at DM 170/month + DM 30/supported system.
|
||||
Willing to travel for sufficiently large jobs.
|
||||
Rates don't include taxes.
|
||||
|
||||
Entered: 16Aug94
|
||||
|
||||
Joe Wells <jbw@cs.bu.edu>
|
||||
Postal Address:
|
||||
care of: Boston University Computer Science Department
|
||||
111 Cummington Street, Room 138
|
||||
Boston, Massachusetts 02215
|
||||
Work Telephone: (617) 353-3381 (sorry, but no answering machine or voice mail)
|
||||
Home Telephone: (617) 739-7456 (until August 1995)
|
||||
Finger "jbw@cs.bu.edu" for up-to-date contact information.
|
||||
|
||||
Experience:
|
||||
I have B.A. and M.A. degrees in Computer Science and have completed
|
||||
all but the dissertation for a Ph.D. in C.S. My research for my
|
||||
Ph.D. is in the areas of logic, type systems, and programming
|
||||
language theory. My primary programming languages are Emacs Lisp,
|
||||
Perl, and Bourne shell, but of course I can program in any language.
|
||||
I have written numerous Emacs Lisp packages. I started the USENET
|
||||
"List of Frequently Asked Questions about GNU Emacs with Answers" and
|
||||
maintained it for more than two years. Most of my work has been
|
||||
related to the telephone system (modems, voice mail, etc.), but I am
|
||||
not limited to that. Send e-mail for my complete resume or curriculum
|
||||
vita.
|
||||
|
||||
Programs supported:
|
||||
GNU Emacs and Taylor UUCP:
|
||||
Installation, training, customization, bug fixing, troubleshooting,
|
||||
extension, development, porting, or answering any kind of question.
|
||||
Any other GNU program:
|
||||
The same things, but I don't necessarily have huge amounts of
|
||||
experience with the particular program.
|
||||
|
||||
Working conditions:
|
||||
I am usually available for part-time work (less than 20 hours per week
|
||||
including any travel time). I can sometimes make time for full-time
|
||||
work for a month or two; please inquire. I can either work in or near
|
||||
Boston or via the Internet or via telephone; travel outside the Boston
|
||||
metropolitan area can be negotiated. My schedule is very flexible.
|
||||
Any programs I write will normally have the copying conditions of the
|
||||
GNU General Public License; this is negotiable.
|
||||
|
||||
Rates: $65/hour as an independent contractor.
|
||||
travel and telephone expenses.
|
||||
higher rates if extensive travel is required.
|
||||
|
||||
Updated: 27Sep94.
|
||||
|
||||
Herb Wood
|
||||
phone: 1-415-789-7173
|
||||
email: <ru@ccnext.ucsf.edu>
|
||||
|
||||
I'm a better "planner" than I am a hacker. A really good hacker will be able
|
||||
to keep many pieces of information in their short-term memory and to memorize
|
||||
new pieces of information at a fast rate. This is not my strong point.
|
||||
Rather, I excel in domains that require knowledge of the slightly more
|
||||
theoretical parts of computer science --for example, logic, formal methods of
|
||||
program development, and functional programming. I can write, and I have
|
||||
"tutoring" (teaching one-on-one) experience, an, unlike some programmers,
|
||||
I enjoy doing these things.
|
||||
|
||||
I have spend a lot of time looking at the Emacs Lisp sources and customizing
|
||||
Emacs and VM. I think I can customize Emacs and its packages quickly and
|
||||
effectively.
|
||||
|
||||
Entered: 30Jul95
|
||||
|
||||
Yggdrasil Computing, Inc./ Freesoft, Inc. <info@yggdrasil.com>
|
||||
4880 Stevens Creek Blvd. Ste. 205
|
||||
San Jose, CA 95129
|
||||
(408) 261-6630
|
||||
(800) 261 6630
|
||||
|
||||
Updated: 14Apr94
|
||||
|
||||
|
||||
For a current copy of this directory, or to have yourself listed, ask:
|
||||
gnu@prep.ai.mit.edu
|
||||
|
||||
** Please keep the entries in this file alphabetical **
|
|
@ -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.
|
||||
|
|
@ -0,0 +1,492 @@
|
|||
/* 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 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
|
||||
|
||||
#define NULL 0
|
||||
|
||||
/* 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. */
|
||||
|
||||
((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 */
|
|
@ -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
|
|
@ -0,0 +1,69 @@
|
|||
/* Define control and data flow tables, and regsets.
|
||||
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. */
|
||||
|
||||
|
||||
/* Number of bits in each actual element of a regset. */
|
||||
|
||||
#define REGSET_ELT_BITS HOST_BITS_PER_WIDE_INT
|
||||
|
||||
/* Type to use for a regset element. Note that lots of code assumes
|
||||
that the initial part of a regset that contains information on the
|
||||
hard registers is the same format as a HARD_REG_SET. */
|
||||
|
||||
#define REGSET_ELT_TYPE unsigned HOST_WIDE_INT
|
||||
|
||||
/* Define the type for a pointer to a set with a bit for each
|
||||
(hard or pseudo) register. */
|
||||
|
||||
typedef REGSET_ELT_TYPE *regset;
|
||||
|
||||
/* Size of a regset for the current function,
|
||||
in (1) bytes and (2) elements. */
|
||||
|
||||
extern int regset_bytes;
|
||||
extern int regset_size;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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
|
||||
extern int *reg_basic_block;
|
|
@ -0,0 +1,992 @@
|
|||
/* Output bytecodes for GNU C-compiler.
|
||||
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 "config.h"
|
||||
#ifdef __STDC__
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
#include "machmode.h"
|
||||
#include "rtl.h"
|
||||
#include "real.h"
|
||||
#include "obstack.h"
|
||||
#include "bytecode.h"
|
||||
#ifdef __GNUC__
|
||||
#include "bytetypes.h"
|
||||
#endif
|
||||
#include "bc-emit.h"
|
||||
#include "bc-opcode.h"
|
||||
#include "bc-typecd.h"
|
||||
#include "bi-run.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
extern char *xmalloc (), *xrealloc ();
|
||||
extern void free ();
|
||||
|
||||
extern struct obstack *rtl_obstack;
|
||||
|
||||
/* Indexed by mode class, gives the narrowest mode for each class. */
|
||||
|
||||
extern enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS];
|
||||
|
||||
/* Commonly used modes. */
|
||||
/* Mode whose width is BITS_PER_UNIT */
|
||||
extern enum machine_mode byte_mode;
|
||||
|
||||
/* Mode whose width is BITS_PER_WORD */
|
||||
extern enum machine_mode word_mode;
|
||||
|
||||
/* Vector indexed by opcode giving info about the args for each opcode. */
|
||||
static struct arityvec arityvec[] = {
|
||||
#include "bc-arity.h"
|
||||
};
|
||||
|
||||
/* How to print a symbol name for the assembler. */
|
||||
static void
|
||||
prsym (file, s)
|
||||
FILE *file;
|
||||
char *s;
|
||||
{
|
||||
if (*s == '*')
|
||||
fprintf (file, "%s", s + 1);
|
||||
else
|
||||
|
||||
#ifdef NAMES_HAVE_UNDERSCORES
|
||||
fprintf (file, "_%s", s);
|
||||
#else
|
||||
fprintf (file, "%s", s);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* Maintain a bucket hash table for symbol names. */
|
||||
|
||||
#define HASH_BITS 32
|
||||
#define HASH_SIZE 509
|
||||
|
||||
static struct bc_sym *hashtab[HASH_SIZE];
|
||||
|
||||
static unsigned int
|
||||
hash (name)
|
||||
char *name;
|
||||
{
|
||||
unsigned int hash = 0;
|
||||
|
||||
while (*name)
|
||||
{
|
||||
hash = hash << 3 | hash >> HASH_BITS - 3;
|
||||
hash += *name++;
|
||||
}
|
||||
|
||||
return hash % HASH_SIZE;
|
||||
}
|
||||
|
||||
|
||||
/* Look up the named symbol, creating it if it doesn't exist. */
|
||||
struct bc_sym *
|
||||
sym_lookup (name)
|
||||
char *name;
|
||||
{
|
||||
int i;
|
||||
struct bc_sym *s;
|
||||
|
||||
i = hash (name);
|
||||
for (s = hashtab[i]; s; s = s->next)
|
||||
if (!strcmp (s->name, name))
|
||||
return s;
|
||||
|
||||
s = (struct bc_sym *) xmalloc (sizeof (struct bc_sym));
|
||||
s->name = xmalloc (strlen (name) + 1);
|
||||
strcpy (s->name, name);
|
||||
s->defined = s->global = s->common = 0;
|
||||
s->val = 0;
|
||||
s->next = hashtab[i];
|
||||
hashtab[i] = s;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/* Write out .globl and common symbols to the named file. */
|
||||
static void
|
||||
bc_sym_write (file)
|
||||
FILE *file;
|
||||
{
|
||||
int i;
|
||||
struct bc_sym *s;
|
||||
|
||||
for (i = 0; i < HASH_SIZE; ++i)
|
||||
for (s = hashtab[i]; s; s = s->next)
|
||||
{
|
||||
if (s->global)
|
||||
{
|
||||
fprintf (file, "\n\t.globl ");
|
||||
prsym (file, s->name);
|
||||
putc ('\n', file);
|
||||
if (s->common)
|
||||
{
|
||||
fprintf (file, "\n\t.comm ");
|
||||
prsym (file, s->name);
|
||||
fprintf (file, ", %lu\n", s->val);
|
||||
}
|
||||
}
|
||||
else if (s->common)
|
||||
{
|
||||
fprintf (file, "\n\t.lcomm ");
|
||||
prsym (file, s->name);
|
||||
fprintf (file, ", %lu\n", s->val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Create and initialize a new segment. */
|
||||
static struct bc_seg *
|
||||
seg_create ()
|
||||
{
|
||||
struct bc_seg *result;
|
||||
|
||||
result = (struct bc_seg *) xmalloc (sizeof (struct bc_seg));
|
||||
result->alloc = 256;
|
||||
result->data = xmalloc (result->alloc);
|
||||
result->size = 0;
|
||||
result->syms = 0;
|
||||
result->relocs = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* Advance the segment index to the next alignment boundary. */
|
||||
static void
|
||||
seg_align (seg, log)
|
||||
struct bc_seg *seg;
|
||||
int log;
|
||||
{
|
||||
unsigned int oldsize = seg->size;
|
||||
|
||||
seg->size = seg->size + (1 << log) - 1 & ~((1 << log) - 1);
|
||||
if (seg->size > seg->alloc)
|
||||
{
|
||||
while (seg->size > seg->alloc)
|
||||
seg->alloc *= 2;
|
||||
seg->data = xrealloc (seg->data, seg->alloc);
|
||||
}
|
||||
bzero (seg->data + oldsize, seg->size - oldsize);
|
||||
}
|
||||
|
||||
|
||||
/* Append the given data to the given segment. */
|
||||
static void
|
||||
seg_data (seg, data, size)
|
||||
struct bc_seg *seg;
|
||||
char *data;
|
||||
unsigned int size;
|
||||
{
|
||||
if (seg->size + size > seg->alloc)
|
||||
{
|
||||
while (seg->size + size > seg->alloc)
|
||||
seg->alloc *= 2;
|
||||
seg->data = xrealloc (seg->data, seg->alloc);
|
||||
}
|
||||
|
||||
bcopy (data, seg->data + seg->size, size);
|
||||
seg->size += size;
|
||||
}
|
||||
|
||||
|
||||
/* Append a zero-filled skip to the given segment. */
|
||||
static void
|
||||
seg_skip (seg, size)
|
||||
struct bc_seg *seg;
|
||||
unsigned int size;
|
||||
{
|
||||
if (seg->size + size > seg->alloc)
|
||||
{
|
||||
while (seg->size + size > seg->alloc)
|
||||
seg->alloc *= 2;
|
||||
seg->data = xrealloc (seg->data, seg->alloc);
|
||||
}
|
||||
|
||||
memset (seg->data + seg->size, 0, size);
|
||||
seg->size += size;
|
||||
}
|
||||
|
||||
|
||||
/* Define the given name as the current offset in the given segment. It
|
||||
is an error if the name is already defined. Return 0 or 1 indicating
|
||||
failure or success respectively. */
|
||||
static int
|
||||
seg_defsym (seg, name)
|
||||
struct bc_seg *seg;
|
||||
char *name;
|
||||
{
|
||||
struct bc_sym *sym;
|
||||
struct bc_segsym *segsym;
|
||||
|
||||
sym = sym_lookup (name);
|
||||
if (sym->defined)
|
||||
return 0;
|
||||
|
||||
sym->defined = 1;
|
||||
sym->val = seg->size;
|
||||
segsym = (struct bc_segsym *) xmalloc (sizeof (struct bc_segsym));
|
||||
segsym->sym = sym;
|
||||
segsym->next = seg->syms;
|
||||
seg->syms = segsym;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Generate in seg's data a reference to the given sym, adjusted by
|
||||
the given offset. */
|
||||
static void
|
||||
seg_refsym (seg, name, offset)
|
||||
struct bc_seg *seg;
|
||||
char *name;
|
||||
int offset;
|
||||
{
|
||||
struct bc_sym *sym;
|
||||
struct bc_segreloc *segreloc;
|
||||
|
||||
sym = sym_lookup (name);
|
||||
segreloc = (struct bc_segreloc *) xmalloc (sizeof (struct bc_segreloc));
|
||||
segreloc->offset = seg->size;
|
||||
segreloc->sym = sym;
|
||||
segreloc->next = seg->relocs;
|
||||
seg->relocs = segreloc;
|
||||
seg_data (seg, (char *) &offset, sizeof offset);
|
||||
}
|
||||
|
||||
|
||||
/* Concatenate the contents of given segments into the first argument. */
|
||||
static void
|
||||
seg_concat (result, seg)
|
||||
struct bc_seg *result, *seg;
|
||||
{
|
||||
unsigned int fix;
|
||||
struct bc_segsym *segsym;
|
||||
struct bc_segreloc *segreloc;
|
||||
|
||||
seg_align (result, MACHINE_SEG_ALIGN);
|
||||
fix = result->size;
|
||||
seg_data (result, seg->data, seg->size);
|
||||
free (seg->data);
|
||||
|
||||
/* Go through the symbols and relocs of SEG, adjusting their offsets
|
||||
for their new location in RESULT. */
|
||||
if (seg->syms)
|
||||
{
|
||||
segsym = seg->syms;
|
||||
do
|
||||
segsym->sym->val += fix;
|
||||
while (segsym->next && (segsym = segsym->next));
|
||||
segsym->next = result->syms;
|
||||
result->syms = seg->syms;
|
||||
}
|
||||
if (seg->relocs)
|
||||
{
|
||||
segreloc = seg->relocs;
|
||||
do
|
||||
segreloc->offset += fix;
|
||||
while (segreloc->next && (segreloc = segreloc->next));
|
||||
segreloc->next = result->relocs;
|
||||
result->relocs = seg->relocs;
|
||||
}
|
||||
|
||||
free ((char *) seg);
|
||||
}
|
||||
|
||||
/* Write a segment to a file. */
|
||||
static void
|
||||
bc_seg_write (seg, file)
|
||||
struct bc_seg *seg;
|
||||
FILE *file;
|
||||
{
|
||||
struct bc_segsym *segsym, *nsegsym, *psegsym;
|
||||
struct bc_segreloc *segreloc, *nsegreloc, *psegreloc;
|
||||
int i, offset, flag;
|
||||
|
||||
/* Reverse the list of symbols. */
|
||||
for (psegsym = 0, segsym = seg->syms; segsym; segsym = nsegsym)
|
||||
{
|
||||
nsegsym = segsym->next;
|
||||
segsym->next = psegsym;
|
||||
psegsym = segsym;
|
||||
}
|
||||
seg->syms = psegsym;
|
||||
|
||||
/* Reverse the list of relocs. */
|
||||
for (psegreloc = 0, segreloc = seg->relocs; segreloc; segreloc = nsegreloc)
|
||||
{
|
||||
nsegreloc = segreloc->next;
|
||||
segreloc->next = psegreloc;
|
||||
psegreloc = segreloc;
|
||||
}
|
||||
seg->relocs = psegreloc;
|
||||
|
||||
/* Output each byte of the segment. */
|
||||
for (i = 0, segsym = seg->syms, segreloc = seg->relocs; i < seg->size; ++i)
|
||||
{
|
||||
while (segsym && segsym->sym->val == i)
|
||||
{
|
||||
if (i % 8 != 0)
|
||||
putc ('\n', file);
|
||||
|
||||
BC_WRITE_SEGSYM (segsym, file);
|
||||
segsym = segsym->next;
|
||||
flag = 1;
|
||||
}
|
||||
if (segreloc && segreloc->offset == i)
|
||||
{
|
||||
if (i % 8 != 0)
|
||||
putc ('\n', file);
|
||||
|
||||
bcopy (seg->data + i, (char *) &offset, sizeof (int));
|
||||
i += sizeof (int) - 1;
|
||||
|
||||
BC_WRITE_RELOC_ENTRY (segreloc, file, offset);
|
||||
segreloc = segreloc->next;
|
||||
flag = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i % 8 == 0 || flag)
|
||||
BC_START_BYTECODE_LINE (file);
|
||||
|
||||
BC_WRITE_BYTECODE (i % 8 == 0 || flag ? ' ' : ',',
|
||||
seg->data[i] & 0xFF,
|
||||
file);
|
||||
flag = 0;
|
||||
if (i % 8 == 7)
|
||||
putc ('\n', file);
|
||||
}
|
||||
}
|
||||
|
||||
/* Paranoia check--we should have visited all syms and relocs during
|
||||
the output pass. */
|
||||
|
||||
if (segsym || segreloc)
|
||||
abort ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Text and data segments of the object file in making. */
|
||||
static struct bc_seg *bc_text_seg;
|
||||
static struct bc_seg *bc_data_seg;
|
||||
|
||||
/* Called before anything else in this module. */
|
||||
void
|
||||
bc_initialize ()
|
||||
{
|
||||
int min_class_size[(int) MAX_MODE_CLASS];
|
||||
enum machine_mode mode;
|
||||
int i;
|
||||
|
||||
bc_init_mode_to_code_map ();
|
||||
|
||||
bc_text_seg = seg_create ();
|
||||
bc_data_seg = seg_create ();
|
||||
|
||||
dconst0 = REAL_VALUE_ATOF ("0", DFmode);
|
||||
dconst1 = REAL_VALUE_ATOF ("1", DFmode);
|
||||
dconst2 = REAL_VALUE_ATOF ("2", DFmode);
|
||||
dconstm1 = REAL_VALUE_ATOF ("-1", DFmode);
|
||||
|
||||
/* Find the narrowest mode for each class and compute the word and byte
|
||||
modes. */
|
||||
|
||||
for (i = 0; i < (int) MAX_MODE_CLASS; i++)
|
||||
min_class_size[i] = 1000;
|
||||
|
||||
for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
|
||||
mode = (enum machine_mode) ((int) mode + 1))
|
||||
{
|
||||
if (GET_MODE_SIZE (mode) < min_class_size[(int) GET_MODE_CLASS (mode)])
|
||||
{
|
||||
class_narrowest_mode[(int) GET_MODE_CLASS (mode)] = mode;
|
||||
min_class_size[(int) GET_MODE_CLASS (mode)] = GET_MODE_SIZE (mode);
|
||||
}
|
||||
if (GET_MODE_CLASS (mode) == MODE_INT
|
||||
&& GET_MODE_BITSIZE (mode) == BITS_PER_UNIT)
|
||||
byte_mode = mode;
|
||||
|
||||
if (GET_MODE_CLASS (mode) == MODE_INT
|
||||
&& GET_MODE_BITSIZE (mode) == BITS_PER_WORD)
|
||||
word_mode = mode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* External addresses referenced in a function. Rather than trying to
|
||||
work relocatable address directly into bytecoded functions (which would
|
||||
require us to provide hairy location info and possibly obey alignment
|
||||
rules imposed by the architecture) we build an auxiliary table of
|
||||
pointer constants, and encode just offsets into this table into the
|
||||
actual bytecode. */
|
||||
static struct bc_seg *ptrconsts;
|
||||
|
||||
/* Trampoline code for the function entry. */
|
||||
struct bc_seg *trampoline;
|
||||
|
||||
/* Actual byte code of the function. */
|
||||
struct bc_seg *bytecode;
|
||||
|
||||
/* List of labels defined in the function. */
|
||||
struct bc_label *labels;
|
||||
|
||||
/* List of label references in the function. */
|
||||
struct bc_labelref *labelrefs;
|
||||
|
||||
|
||||
/* Add symbol to pointer table. Return offset into table where
|
||||
pointer was stored. The offset usually goes into the bytecode
|
||||
stream as a constP literal. */
|
||||
int
|
||||
bc_define_pointer (p)
|
||||
char *p;
|
||||
{
|
||||
int offset = ptrconsts->size;
|
||||
|
||||
seg_refsym (ptrconsts, p, 0);
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
/* Begin a bytecoded function. */
|
||||
int
|
||||
bc_begin_function (name)
|
||||
char *name;
|
||||
{
|
||||
ptrconsts = seg_create ();
|
||||
trampoline = seg_create ();
|
||||
bytecode = seg_create ();
|
||||
return seg_defsym (trampoline, name);
|
||||
}
|
||||
|
||||
|
||||
/* Force alignment in inline bytecode. */
|
||||
void
|
||||
bc_align_bytecode (align)
|
||||
int align;
|
||||
{
|
||||
seg_align (bytecode, align);
|
||||
}
|
||||
|
||||
|
||||
/* Emit data inline into bytecode. */
|
||||
void
|
||||
bc_emit_bytecode_const (data, size)
|
||||
char *data;
|
||||
unsigned int size;
|
||||
{
|
||||
if (bytecode)
|
||||
seg_data (bytecode, data, size);
|
||||
}
|
||||
|
||||
|
||||
/* Create a new "bytecode label", to have its value defined later.
|
||||
Bytecode labels have nothing to do with the object file symbol table,
|
||||
and are purely local to a given bytecoded function. */
|
||||
struct bc_label *
|
||||
bc_get_bytecode_label ()
|
||||
{
|
||||
struct bc_label *result;
|
||||
|
||||
result = (struct bc_label *) xmalloc (sizeof (struct bc_label));
|
||||
result->defined = 0;
|
||||
result->next = labels;
|
||||
result->uid = 0;
|
||||
labels = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* Define the given label with the current location counter. */
|
||||
int
|
||||
bc_emit_bytecode_labeldef (label)
|
||||
struct bc_label *label;
|
||||
{
|
||||
extern int bc_new_uid ();
|
||||
|
||||
if (!label || label->defined)
|
||||
return 0;
|
||||
|
||||
label->offset = bytecode->size;
|
||||
label->defined = 1;
|
||||
label->uid = bc_new_uid ();
|
||||
|
||||
#ifdef DEBUG_PRINT_CODE
|
||||
fprintf (stderr, "$%lx:\n", label);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Generate a location-relative reference to the given bytecode label.
|
||||
It need not be defined yet; label references will be backpatched later. */
|
||||
void
|
||||
bc_emit_bytecode_labelref (label)
|
||||
struct bc_label *label;
|
||||
{
|
||||
struct bc_labelref *labelref;
|
||||
static int zero;
|
||||
|
||||
labelref = (struct bc_labelref *) xmalloc (sizeof (struct bc_labelref));
|
||||
labelref->label = label;
|
||||
labelref->offset = bytecode->size;
|
||||
labelref->next = labelrefs;
|
||||
labelrefs = labelref;
|
||||
|
||||
#ifdef DEBUG_PRINT_CODE
|
||||
fprintf (stderr, " $%lx", label);
|
||||
#endif
|
||||
|
||||
seg_data (bytecode, (char *) &zero, sizeof zero);
|
||||
}
|
||||
|
||||
|
||||
/* Emit a reference to an external address; generate the reference in the
|
||||
ptrconst area, and emit an offset in the bytecode. */
|
||||
void
|
||||
bc_emit_code_labelref (name, offset)
|
||||
char *name;
|
||||
int offset;
|
||||
{
|
||||
int ptroff;
|
||||
|
||||
ptroff = ptrconsts->size / sizeof (char *);
|
||||
seg_data (bytecode, (char *) &ptroff, sizeof ptroff);
|
||||
seg_refsym (ptrconsts, name, offset);
|
||||
|
||||
#ifdef DEBUG_PRINT_CODE
|
||||
fprintf (stderr, " [external <%x> %s]", ptroff, name);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Backpatch label references in the byte code, and concatenate the bytecode
|
||||
and pointer constant segments to the cumulative text for the object file.
|
||||
Return a label name for the pointer constants region. */
|
||||
char *
|
||||
bc_end_function ()
|
||||
{
|
||||
int addr;
|
||||
struct bc_label *label, *next;
|
||||
struct bc_labelref *ref, *nextref;
|
||||
char ptrconsts_label[20];
|
||||
static int nlab;
|
||||
|
||||
/* Backpatch bytecode label references. */
|
||||
for (ref = labelrefs; ref; ref = ref->next)
|
||||
if (ref->label->defined)
|
||||
{
|
||||
addr = ref->label->offset;
|
||||
bcopy ((char *) &addr, bytecode->data + ref->offset, sizeof addr);
|
||||
}
|
||||
|
||||
/* Free the chains of labelrefs and labeldefs. */
|
||||
for (ref = labelrefs; ref; ref = nextref)
|
||||
{
|
||||
nextref = ref->next;
|
||||
free ((char *) ref);
|
||||
}
|
||||
|
||||
for (label = labels; label; label = next)
|
||||
{
|
||||
next = label->next;
|
||||
free ((char *) label);
|
||||
}
|
||||
|
||||
seg_concat (trampoline, bytecode);
|
||||
seg_align (trampoline, MACHINE_SEG_ALIGN);
|
||||
sprintf (ptrconsts_label, "*LP%d", nlab++);
|
||||
seg_defsym (trampoline, ptrconsts_label);
|
||||
seg_concat (trampoline, ptrconsts);
|
||||
seg_concat (bc_text_seg, trampoline);
|
||||
|
||||
labels = 0;
|
||||
labelrefs = 0;
|
||||
trampoline = 0;
|
||||
bytecode = 0;
|
||||
ptrconsts = 0;
|
||||
|
||||
return sym_lookup (ptrconsts_label)->name;
|
||||
}
|
||||
|
||||
/* Force alignment in const data. */
|
||||
void
|
||||
bc_align_const (align)
|
||||
int align;
|
||||
{
|
||||
seg_align (bc_text_seg, align);
|
||||
}
|
||||
|
||||
/* Emit const data. */
|
||||
void
|
||||
bc_emit_const (data, size)
|
||||
char *data;
|
||||
unsigned int size;
|
||||
{
|
||||
seg_data (bc_text_seg, data, size);
|
||||
}
|
||||
|
||||
/* Emit a zero-filled constant skip. */
|
||||
void
|
||||
bc_emit_const_skip (size)
|
||||
unsigned int size;
|
||||
{
|
||||
seg_skip (bc_text_seg, size);
|
||||
}
|
||||
|
||||
/* Emit a label definition in const data. */
|
||||
int
|
||||
bc_emit_const_labeldef (name)
|
||||
char *name;
|
||||
{
|
||||
return seg_defsym (bc_text_seg, name);
|
||||
}
|
||||
|
||||
/* Emit a label reference in const data. */
|
||||
void
|
||||
bc_emit_const_labelref (name, offset)
|
||||
char *name;
|
||||
int offset;
|
||||
{
|
||||
seg_refsym (bc_text_seg, name, offset);
|
||||
}
|
||||
|
||||
/* Force alignment in data. */
|
||||
void
|
||||
bc_align_data (align)
|
||||
int align;
|
||||
{
|
||||
seg_align (bc_data_seg, align);
|
||||
}
|
||||
|
||||
/* Emit data. */
|
||||
void
|
||||
bc_emit_data (data, size)
|
||||
char *data;
|
||||
unsigned int size;
|
||||
{
|
||||
seg_data (bc_data_seg, data, size);
|
||||
}
|
||||
|
||||
/* Emit a zero-filled data skip. */
|
||||
void
|
||||
bc_emit_data_skip (size)
|
||||
unsigned int size;
|
||||
{
|
||||
seg_skip (bc_data_seg, size);
|
||||
}
|
||||
|
||||
/* Emit label definition in data. */
|
||||
int
|
||||
bc_emit_data_labeldef (name)
|
||||
char *name;
|
||||
{
|
||||
return seg_defsym (bc_data_seg, name);
|
||||
}
|
||||
|
||||
/* Emit label reference in data. */
|
||||
void
|
||||
bc_emit_data_labelref (name, offset)
|
||||
char *name;
|
||||
int offset;
|
||||
{
|
||||
seg_refsym (bc_data_seg, name, offset);
|
||||
}
|
||||
|
||||
/* Emit a common block of the given name and size. Note that
|
||||
when the .o file is actually written non-global "common"
|
||||
blocks will have to be turned into space in the data section. */
|
||||
int
|
||||
bc_emit_common (name, size)
|
||||
char *name;
|
||||
unsigned int size;
|
||||
{
|
||||
struct bc_sym *sym;
|
||||
|
||||
sym = sym_lookup (name);
|
||||
if (sym->defined)
|
||||
return 0;
|
||||
|
||||
sym->defined = 1;
|
||||
sym->common = 1;
|
||||
sym->val = size;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Globalize the given label. */
|
||||
void
|
||||
bc_globalize_label (name)
|
||||
char *name;
|
||||
{
|
||||
struct bc_sym *sym;
|
||||
|
||||
sym = sym_lookup (name);
|
||||
sym->global = 1;
|
||||
}
|
||||
|
||||
static enum { in_text, in_data } section = in_text;
|
||||
|
||||
void
|
||||
bc_text ()
|
||||
{
|
||||
section = in_text;
|
||||
}
|
||||
|
||||
void
|
||||
bc_data ()
|
||||
{
|
||||
section = in_data;
|
||||
}
|
||||
|
||||
void
|
||||
bc_align (align)
|
||||
int align;
|
||||
{
|
||||
if (section == in_text)
|
||||
bc_align_const (align);
|
||||
else
|
||||
bc_align_data (align);
|
||||
}
|
||||
|
||||
void
|
||||
bc_emit (data, size)
|
||||
char *data;
|
||||
unsigned int size;
|
||||
{
|
||||
if (section == in_text)
|
||||
bc_emit_const (data, size);
|
||||
else
|
||||
bc_emit_data (data, size);
|
||||
}
|
||||
|
||||
void
|
||||
bc_emit_skip (size)
|
||||
unsigned int size;
|
||||
{
|
||||
if (section == in_text)
|
||||
bc_emit_const_skip (size);
|
||||
else
|
||||
bc_emit_data_skip (size);
|
||||
}
|
||||
|
||||
int
|
||||
bc_emit_labeldef (name)
|
||||
char *name;
|
||||
{
|
||||
if (section == in_text)
|
||||
return bc_emit_const_labeldef (name);
|
||||
else
|
||||
return bc_emit_data_labeldef (name);
|
||||
}
|
||||
|
||||
void
|
||||
bc_emit_labelref (name, offset)
|
||||
char *name;
|
||||
int offset;
|
||||
{
|
||||
if (section == in_text)
|
||||
bc_emit_const_labelref (name, offset);
|
||||
else
|
||||
bc_emit_data_labelref (name, offset);
|
||||
}
|
||||
|
||||
void
|
||||
bc_write_file (file)
|
||||
FILE *file;
|
||||
{
|
||||
BC_WRITE_FILE (file);
|
||||
}
|
||||
|
||||
|
||||
/* Allocate a new bytecode rtx.
|
||||
If you supply a null BC_LABEL, we generate one. */
|
||||
|
||||
rtx
|
||||
bc_gen_rtx (label, offset, bc_label)
|
||||
char *label;
|
||||
int offset;
|
||||
struct bc_label *bc_label;
|
||||
{
|
||||
rtx r;
|
||||
|
||||
if (bc_label == 0)
|
||||
bc_label = (struct bc_label *) xmalloc (sizeof (struct bc_label));
|
||||
|
||||
r = gen_rtx (CODE_LABEL, VOIDmode, label, bc_label);
|
||||
bc_label->offset = offset;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/* Print bytecode rtx */
|
||||
void
|
||||
bc_print_rtl (fp, r)
|
||||
FILE *fp;
|
||||
rtx r;
|
||||
{
|
||||
#if 0 /* This needs to get fixed to really work again. */
|
||||
/* BC_WRITE_RTL has a definition
|
||||
that doesn't even make sense for this use. */
|
||||
BC_WRITE_RTL (r, fp);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Emit a bytecode, keeping a running tally of the stack depth. */
|
||||
void
|
||||
bc_emit_bytecode (bytecode)
|
||||
enum bytecode_opcode bytecode;
|
||||
{
|
||||
char byte;
|
||||
static int prev_lineno = -1;
|
||||
|
||||
byte = (char) bytecode;
|
||||
|
||||
#ifdef BCDEBUG_PRINT_CODE
|
||||
if (lineno != prev_lineno)
|
||||
{
|
||||
fprintf (stderr, "<line %d>\n", lineno);
|
||||
prev_lineno = lineno;
|
||||
}
|
||||
|
||||
fputs (opcode_name[(unsigned int) bytecode], stderr);
|
||||
#endif
|
||||
|
||||
/* Due to errors we are often requested to output bytecodes that
|
||||
will cause an interpreter stack undeflow when executed. Instead of
|
||||
dumping core on such occasions, we omit the bytecode. Erroneous code
|
||||
should not be executed, regardless. This makes life much easier, since
|
||||
we don't have to deceive ourselves about the known stack depth. */
|
||||
|
||||
bc_emit_bytecode_const (&byte, 1);
|
||||
|
||||
if ((stack_depth -= arityvec[(int) bytecode].ninputs) >= 0)
|
||||
{
|
||||
if ((stack_depth += arityvec[(int) bytecode].noutputs) > max_stack_depth)
|
||||
max_stack_depth = stack_depth;
|
||||
}
|
||||
|
||||
#ifdef VALIDATE_STACK_FOR_BC
|
||||
VALIDATE_STACK_FOR_BC ();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef BCDEBUG_PRINT_CODE
|
||||
#define PRLIT(TYPE, PTR) fprintf (stderr, " [%x]", *(TYPE *) PTR)
|
||||
#else
|
||||
#define PRLIT(X,Y)
|
||||
#endif
|
||||
|
||||
/* Emit a complete bytecode instruction, expecting the correct number
|
||||
of literal values in the call. First argument is the instruction, the
|
||||
remaining arguments are literals of size HOST_WIDE_INT or smaller. */
|
||||
void
|
||||
bc_emit_instruction VPROTO((enum bytecode_opcode opcode, ...))
|
||||
{
|
||||
#ifndef __STDC__
|
||||
enum bytecode_opcode opcode;
|
||||
#endif
|
||||
va_list arguments;
|
||||
int nliteral, instruction;
|
||||
|
||||
VA_START (arguments, opcode);
|
||||
|
||||
#ifndef __STDC__
|
||||
opcode = va_arg (arguments, enum bytecode_opcode);
|
||||
#endif
|
||||
|
||||
/* Emit instruction bytecode */
|
||||
bc_emit_bytecode (opcode);
|
||||
instruction = (int) opcode;
|
||||
|
||||
/* Loop literals and emit as bytecode constants */
|
||||
for (nliteral = 0; nliteral < arityvec[instruction].nliterals; nliteral++)
|
||||
{
|
||||
switch (arityvec[instruction].literals[nliteral])
|
||||
{
|
||||
/* This conditional is a kludge, but it's necessary
|
||||
because TYPE might be long long. */
|
||||
#ifdef __GNUC__
|
||||
/* Expand definitions into case statements */
|
||||
#define DEFTYPECODE(CODE, NAME, MODE, TYPE) \
|
||||
case CODE: \
|
||||
{ \
|
||||
TYPE temp = va_arg (arguments, TYPE); \
|
||||
bc_emit_bytecode_const ((void *) &temp, sizeof temp); \
|
||||
PRLIT (TYPE, &temp); } \
|
||||
break;
|
||||
|
||||
#include "bc-typecd.def"
|
||||
|
||||
#undef DEFTYPECODE
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BCDEBUG_PRINT_CODE
|
||||
fputc ('\n', stderr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Emit the machine-code interface trampoline at the beginning of a byte
|
||||
coded function. The argument is a label name of the interpreter
|
||||
bytecode callinfo structure; the return value is a label name for
|
||||
the beginning of the actual bytecode. */
|
||||
char *
|
||||
bc_emit_trampoline (callinfo)
|
||||
char *callinfo;
|
||||
{
|
||||
char mylab[20];
|
||||
static int n;
|
||||
|
||||
sprintf (mylab, "*LB%d", n++);
|
||||
|
||||
BC_EMIT_TRAMPOLINE (trampoline, callinfo);
|
||||
|
||||
seg_defsym (bytecode, mylab);
|
||||
return sym_lookup (mylab)->name;
|
||||
}
|
||||
|
||||
|
||||
/* Simple strdup */
|
||||
char *
|
||||
bc_xstrdup (str)
|
||||
char *str;
|
||||
{
|
||||
char *tmp = xmalloc (strlen (str) + 1);
|
||||
|
||||
strcpy (tmp, str);
|
||||
return tmp;
|
||||
}
|
|
@ -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();
|
|
@ -0,0 +1,789 @@
|
|||
/* Bytecode conversion definitions for GNU C-compiler.
|
||||
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 "config.h"
|
||||
#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 ();
|
||||
extern void free ();
|
||||
|
||||
/* 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 ();
|
||||
}
|
|
@ -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[];
|
|
@ -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)
|
|
@ -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
|
|
@ -0,0 +1,80 @@
|
|||
/* 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;
|
||||
}
|
|
@ -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();
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/* 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;
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/* 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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1,32 @@
|
|||
# We have to use the cross-compiler we just built to compile it.
|
||||
CC = gcc -b $(target)
|
||||
|
||||
# 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
|
||||
|
||||
# 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
|
|
@ -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))))
|
|
@ -0,0 +1,81 @@
|
|||
/* Bytecode definitions for GNU C-compiler.
|
||||
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. */
|
||||
|
||||
|
||||
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_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 */
|
|
@ -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;
|
|
@ -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 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 <stdio.h>
|
||||
#include "config.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 ();
|
||||
static char * concat3 ();
|
||||
static char * gen_formal_list_for_type ();
|
||||
static int deserves_ellipsis ();
|
||||
static char * gen_formal_list_for_func_def ();
|
||||
static char * gen_type ();
|
||||
static char * gen_decl ();
|
||||
void gen_aux_info_record ();
|
||||
|
||||
/* 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 (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");
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,596 @@
|
|||
/* Build expressions with type checking for C compiler.
|
||||
Copyright (C) 1987, 1988, 1989, 1992, 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. */
|
||||
|
||||
|
||||
/* 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"
|
||||
|
||||
static void expand_stmt_with_iterators_1 ();
|
||||
static tree collect_iterators ();
|
||||
static void iterator_loop_prologue ();
|
||||
static void iterator_loop_epilogue ();
|
||||
static void add_ixpansion ();
|
||||
static void delete_ixpansion();
|
||||
static int top_level_ixpansion_p ();
|
||||
static void istack_sublevel_to_current ();
|
||||
|
||||
/* 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;
|
||||
|
||||
/*
|
||||
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;
|
||||
|
||||
/* During collect_iterators, a list of SAVE_EXPRs already scanned. */
|
||||
static tree save_exprs;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
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 */
|
||||
if (top_level_ixpansion_p ())
|
||||
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 */
|
|
@ -0,0 +1,180 @@
|
|||
/* Language-specific hook definitions for C front end.
|
||||
Copyright (C) 1991, 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 "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 ()
|
||||
{
|
||||
/* 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);
|
||||
}
|
||||
|
||||
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 get_file_function_name ();
|
||||
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
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -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 ();
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,168 @@
|
|||
/* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack.
|
||||
Copyright (C) 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. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "config.h"
|
||||
#include "tree.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_PRAMA_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 */
|
|
@ -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));
|
|
@ -0,0 +1,490 @@
|
|||
/* Definitions for C parsing and type checking.
|
||||
Copyright (C) 1987, 1993, 1994, 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. */
|
||||
|
||||
#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)
|
||||
|
||||
/* 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 STDIO_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 STDIO_PROTO((FILE *, tree,
|
||||
int));
|
||||
extern void print_lang_identifier STDIO_PROTO((FILE *, tree,
|
||||
int));
|
||||
extern void print_lang_type STDIO_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 `$' 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 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;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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 */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,770 @@
|
|||
/* Save and restore call-clobbered registers which are live across a call.
|
||||
Copyright (C) 1989, 1992, 1994, 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 "config.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), 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]);
|
||||
REGSET_ELT_TYPE bit;
|
||||
int offset, 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. */
|
||||
|
||||
#ifdef HARD_REG_SET
|
||||
hard_regs_live = *regs_live;
|
||||
#else
|
||||
COPY_HARD_REG_SET (hard_regs_live, regs_live);
|
||||
#endif
|
||||
|
||||
CLEAR_HARD_REG_SET (hard_regs_saved);
|
||||
CLEAR_HARD_REG_SET (hard_regs_need_restore);
|
||||
n_regs_saved = 0;
|
||||
|
||||
for (offset = 0, i = 0; offset < regset_size; offset++)
|
||||
{
|
||||
if (regs_live[offset] == 0)
|
||||
i += REGSET_ELT_BITS;
|
||||
else
|
||||
for (bit = 1; bit && i < max_regno; bit <<= 1, i++)
|
||||
if ((regs_live[offset] & bit)
|
||||
&& (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;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,681 @@
|
|||
.\" 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 is required for ANSI
|
||||
conformance. \c
|
||||
.B gcc\c
|
||||
\& automatically supplies this option to the
|
||||
preprocessor if you specify `\|\c
|
||||
.B \-ansi\c
|
||||
\&\|', but \c
|
||||
.B gcc\c
|
||||
\& doesn't
|
||||
recognize the `\|\c
|
||||
.B \-$\c
|
||||
\&\|' option itself\(em\&to use it without the other
|
||||
effects of `\|\c
|
||||
.B \-ansi\c
|
||||
\&\|', you must call the preprocessor directly.
|
||||
.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.
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,116 @@
|
|||
/* 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. */
|
||||
#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
|
|
@ -0,0 +1,565 @@
|
|||
#! /bin/sh
|
||||
# Attempt to guess a canonical system name.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995 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:V*:*)
|
||||
# After 1.2, OSF1 uses "V1.3" for uname -r.
|
||||
echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^V//'`
|
||||
exit 0 ;;
|
||||
alpha:OSF1:*:*)
|
||||
# 1.2 uses "1.2" for uname -r.
|
||||
echo alpha-dec-osf${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
21064:Windows_NT:50:3)
|
||||
echo alpha-dec-winnt3.5
|
||||
exit 0 ;;
|
||||
amiga:NetBSD:*:*)
|
||||
echo m68k-cbm-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
|
||||
echo arm-acorn-riscix${UNAME_RELEASE}
|
||||
exit 0;;
|
||||
Pyramid*:OSx*:*:*)
|
||||
if test "`(/bin/universe) 2>/dev/null`" = att ; then
|
||||
echo pyramid-pyramid-sysv3
|
||||
else
|
||||
echo pyramid-pyramid-bsd
|
||||
fi
|
||||
exit 0 ;;
|
||||
sun4*:SunOS:5.*:*)
|
||||
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit 0 ;;
|
||||
i86pc:SunOS:5.*:*)
|
||||
echo i386-unknown-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 ;;
|
||||
atari*:NetBSD:*:*)
|
||||
echo m68k-atari-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sun3*:NetBSD:*:*)
|
||||
echo m68k-sun-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mac68k:NetBSD:*:*)
|
||||
echo m68k-apple-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
RISC*:ULTRIX:*:*)
|
||||
echo mips-dec-ultrix${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
VAX*:ULTRIX*:*:*)
|
||||
echo vax-dec-ultrix${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mips:*:4*:UMIPS)
|
||||
echo mips-mips-riscos4sysv
|
||||
exit 0 ;;
|
||||
mips:*:5*:RISCos)
|
||||
echo mips-mips-riscos${UNAME_RELEASE}
|
||||
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:*:*)
|
||||
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
|
||||
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[34]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?[79] ) 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 ;;
|
||||
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*C90:*:*:*)
|
||||
echo c90-cray-unicos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
CRAY-2:*:*:*)
|
||||
echo cray2-cray-unicos
|
||||
exit 0 ;;
|
||||
hp3[0-9][05]:NetBSD:*:*)
|
||||
echo m68k-hp-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
i[34]86:BSD/386:*:* | *:BSD/OS:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-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 ;;
|
||||
*:GNU:*:*)
|
||||
echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
|
||||
exit 0 ;;
|
||||
*:Linux:*:*)
|
||||
# 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`
|
||||
if echo $ld_help_string | grep >/dev/null 2>&1 "supported emulations: elf_i[345]86"; then
|
||||
echo "${UNAME_MACHINE}-unknown-linux" ; exit 0
|
||||
elif echo $ld_help_string | grep >/dev/null 2>&1 "supported emulations: i[345]86linux"; then
|
||||
echo "${UNAME_MACHINE}-unknown-linuxaout" ; exit 0
|
||||
elif echo $ld_help_string | grep >/dev/null 2>&1 "supported emulations: i[345]86coff"; then
|
||||
echo "${UNAME_MACHINE}-unknown-linuxcoff" ; exit 0
|
||||
elif test "${UNAME_MACHINE}" = "alpha" ; then
|
||||
echo alpha-unknown-linux ; exit 0
|
||||
else
|
||||
# Either a pre-BFD a.out linker (linuxoldld) or one that does not give us
|
||||
# useful --help. Gcc wants to distinguish between linuxoldld and linuxaout.
|
||||
test ! -d /usr/lib/ldscripts/. \
|
||||
&& echo "${UNAME_MACHINE}-unknown-linuxoldld" && exit 0
|
||||
# Determine whether the default compiler is a.out or elf
|
||||
cat >dummy.c <<EOF
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
#ifdef __ELF__
|
||||
printf ("%s-unknown-linux\n", argv[1]);
|
||||
#else
|
||||
printf ("%s-unknown-linuxaout\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[34]86:DYNIX/ptx:4*:*)
|
||||
echo i386-sequent-sysv4
|
||||
exit 0 ;;
|
||||
i[34]86:*:4.*:* | i[34]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}-unknown-sysv${UNAME_RELEASE}
|
||||
fi
|
||||
exit 0 ;;
|
||||
i[34]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}-unknown-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
|
||||
echo ${UNAME_MACHINE}-unknown-sco$UNAME_REL
|
||||
else
|
||||
echo ${UNAME_MACHINE}-unknown-sysv32
|
||||
fi
|
||||
exit 0 ;;
|
||||
Intel:Mach:3*:*)
|
||||
echo i386-unknown-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 ;;
|
||||
M680[234]0:*:R3V[567]*:*)
|
||||
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
|
||||
3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0)
|
||||
uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& echo i486-ncr-sysv4.3 && exit 0 ;;
|
||||
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
|
||||
uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& echo i486-ncr-sysv4 && exit 0 ;;
|
||||
m680[234]0:LynxOS:2.[23]*:*)
|
||||
echo m68k-lynx-lynxos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mc68030:UNIX_System_V:4.*:*)
|
||||
echo m68k-atari-sysv4
|
||||
exit 0 ;;
|
||||
i[34]86:LynxOS:2.[23]*:*)
|
||||
echo i386-lynx-lynxos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
TSUNAMI:LynxOS:2.[23]*:*)
|
||||
echo sparc-lynx-lynxos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
rs6000:LynxOS:2.[23]*:*)
|
||||
echo rs6000-lynx-lynxos${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 ;;
|
||||
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%s\n", __ARCHITECTURE__, version==2 ? "2" : "3");
|
||||
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-unknown-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
|
|
@ -0,0 +1,867 @@
|
|||
#! /bin/sh
|
||||
# Configuration validation subroutine script, version 1.1.
|
||||
# Copyright (C) 1991, 1992, 1993, 1994, 1995 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
|
||||
# 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 (if any).
|
||||
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
|
||||
if [ $basic_machine != $1 ]
|
||||
then os=`echo $1 | sed 's/.*-/-/'`
|
||||
else os=; fi
|
||||
|
||||
### 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 )
|
||||
os=
|
||||
basic_machine=$1
|
||||
;;
|
||||
-hiux*)
|
||||
os=-hiuxwe2
|
||||
;;
|
||||
-sco4)
|
||||
os=-sco3.2v4
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
|
||||
;;
|
||||
-sco3.2.[4-9]*)
|
||||
os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
|
||||
;;
|
||||
-sco3.2v[4-9]*)
|
||||
# Don't forget version if it is 3.2v4 or newer.
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
|
||||
;;
|
||||
-sco*)
|
||||
os=-sco3.2v2
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
|
||||
;;
|
||||
-isc)
|
||||
os=-isc2.2
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
|
||||
;;
|
||||
-clix*)
|
||||
basic_machine=clipper-intergraph
|
||||
;;
|
||||
-isc*)
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
|
||||
;;
|
||||
-lynx*)
|
||||
os=-lynxos
|
||||
;;
|
||||
-ptx*)
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
|
||||
;;
|
||||
-windowsnt*)
|
||||
os=`echo $os | sed -e 's/windowsnt/winnt/'`
|
||||
;;
|
||||
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 | i[345]86 | i860 | m68k | m68000 | m88k | ns32k | arm \
|
||||
| arme[lb] | pyramid \
|
||||
| tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \
|
||||
| alpha | we32k | ns16k | clipper | sparclite | i370 | sh \
|
||||
| powerpc | powerpcle | sparc64 | 1750a | dsp16xx | mips64 | mipsel \
|
||||
| pdp11 | mips64el | mips64orion | mips64orionel \
|
||||
| sparc)
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
# 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[345]86-* | i860-* | m68k-* | m68000-* | m88k-* \
|
||||
| sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \
|
||||
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \
|
||||
| none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \
|
||||
| hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \
|
||||
| pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \
|
||||
| pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* | mips64-* | mipsel-* \
|
||||
| mips64el-* | mips64orion-* | mips64orionel-*)
|
||||
;;
|
||||
# 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
|
||||
;;
|
||||
amigados)
|
||||
basic_machine=m68k-cbm
|
||||
os=-amigados
|
||||
;;
|
||||
amigaunix | amix)
|
||||
basic_machine=m68k-cbm
|
||||
os=-sysv4
|
||||
;;
|
||||
apollo68)
|
||||
basic_machine=m68k-apollo
|
||||
os=-sysv
|
||||
;;
|
||||
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
|
||||
;;
|
||||
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
|
||||
;;
|
||||
i370-ibm* | ibm*)
|
||||
basic_machine=i370-ibm
|
||||
os=-mvs
|
||||
;;
|
||||
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
|
||||
i[345]86v32)
|
||||
basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
|
||||
os=-sysv32
|
||||
;;
|
||||
i[345]86v4*)
|
||||
basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
|
||||
os=-sysv4
|
||||
;;
|
||||
i[345]86v)
|
||||
basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
|
||||
os=-sysv
|
||||
;;
|
||||
i[345]86sol2)
|
||||
basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
|
||||
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
|
||||
;;
|
||||
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 | p6)
|
||||
# We don't have specific support for the Intel Pentium (p6) followon yet, so just call it a Pentium
|
||||
basic_machine=i586-intel
|
||||
;;
|
||||
pentium-* | p5-* | p6-*)
|
||||
# We don't have specific support for the Intel Pentium (p6) followon yet, so just call it a Pentium
|
||||
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
k5)
|
||||
# We don't have specific support for AMD's K5 yet, so just call it a Pentium
|
||||
basic_machine=i586-amd
|
||||
;;
|
||||
nexen)
|
||||
# We don't have specific support for Nexgen yet, so just call it a Pentium
|
||||
basic_machine=i586-nexgen
|
||||
;;
|
||||
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
|
||||
;;
|
||||
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
|
||||
;;
|
||||
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)
|
||||
basic_machine=mips-mips
|
||||
;;
|
||||
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
|
||||
# -solaris* is a basic system type, with this one exception.
|
||||
-solaris1 | -solaris1.*)
|
||||
os=`echo $os | sed -e 's|solaris1|sunos4|'`
|
||||
;;
|
||||
-solaris)
|
||||
os=-solaris2
|
||||
;;
|
||||
-unixware* | svr4*)
|
||||
os=-sysv4
|
||||
;;
|
||||
-gnu/linux*)
|
||||
os=`echo $os | sed -e 's|gnu/linux|linux|'`
|
||||
;;
|
||||
# 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[345]* \
|
||||
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
|
||||
| -amigados* | -msdos* | -newsos* | -unicos* | -aos* \
|
||||
| -nindy* | -vxworks* | -ebmon* | -hms* | -mvs* | -clix* \
|
||||
| -riscos* | -linux* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||
| -hiux* | -386bsd* | -netbsd* | -freebsd* | -riscix* \
|
||||
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
|
||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||
| -udi* | -eabi* | -lites* )
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
-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
|
||||
;;
|
||||
# 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=-amigados
|
||||
;;
|
||||
*-dg)
|
||||
os=-dgux
|
||||
;;
|
||||
*-dolphin)
|
||||
os=-sysv3
|
||||
;;
|
||||
m68k-ccur)
|
||||
os=-rtu
|
||||
;;
|
||||
m88k-omron*)
|
||||
os=-luna
|
||||
;;
|
||||
*-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
|
||||
;;
|
||||
*)
|
||||
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
|
||||
;;
|
||||
-lynxos*)
|
||||
vendor=lynx
|
||||
;;
|
||||
-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
|
||||
;;
|
||||
-vxworks*)
|
||||
vendor=wrs
|
||||
;;
|
||||
esac
|
||||
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
|
||||
;;
|
||||
esac
|
||||
|
||||
echo $basic_machine$os
|
|
@ -0,0 +1,5 @@
|
|||
This directory contains machine-specific files for the GNU C compiler.
|
||||
It has a subdirectory for each basic CPU type.
|
||||
The only files in this directory itself
|
||||
are some .h files that pertain to particular operating systems
|
||||
and are used for more than one CPU type.
|
|
@ -0,0 +1,88 @@
|
|||
/* aoutos.h -- operating system specific defines to be used when
|
||||
targeting GCC for some system that uses a.out file format.
|
||||
Copyright (C) 1992 Free Software Foundation, Inc.
|
||||
|
||||
Written by Ron Guilmette (rfg@netcom.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. */
|
||||
|
||||
/* To use this file, make up a file with a name like:
|
||||
|
||||
?????aout.h
|
||||
|
||||
where ????? is replaced by the name of the basic hardware that you
|
||||
are targeting for. Then, in the file ?????aout.h, put something
|
||||
like:
|
||||
|
||||
#include "?????.h"
|
||||
#include "aoutos.h"
|
||||
|
||||
followed by any really system-specific defines (or overrides of
|
||||
defines) which you find that you need. Now, modify the configure
|
||||
or configure.in script to properly use the new ?????aout.h file
|
||||
when configuring for the system. */
|
||||
|
||||
/* Define a symbol indicating that we are using aoutos.h. */
|
||||
#define USING_AOUTOS_H
|
||||
|
||||
/* A C statement (sans semicolon) to output an element in the table of
|
||||
global constructors.
|
||||
If using GNU LD, tell it that this is part of the static destructor set.
|
||||
This code works for any machine provided you use GNU as/ld.
|
||||
If not using GNU LD, rely on a "collect" program to look for names defined
|
||||
in the particular form we choose as global constructor function names. */
|
||||
|
||||
#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
|
||||
do { \
|
||||
if (flag_gnu_linker) \
|
||||
{ \
|
||||
/* Output an N_SETT (0x16, 22.) for the name. */ \
|
||||
fprintf (FILE, "%s \"___CTOR_LIST__\",22,0,0,", ASM_STABS_OP); \
|
||||
assemble_name (FILE, NAME); \
|
||||
fputc ('\n', FILE); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* A C statement (sans semicolon) to output an element in the table of
|
||||
global destructors. */
|
||||
|
||||
#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \
|
||||
do { \
|
||||
if (flag_gnu_linker) \
|
||||
{ \
|
||||
/* Output an N_SETT (0x16, 22.) for the name. */ \
|
||||
fprintf (FILE, "%s \"___DTOR_LIST__\",22,0,0,", ASM_STABS_OP); \
|
||||
assemble_name (FILE, NAME); \
|
||||
fputc ('\n', FILE); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Likewise for entries we want to record for garbage collection.
|
||||
Garbage collection is still under development. */
|
||||
|
||||
#define ASM_OUTPUT_GC_ENTRY(FILE,NAME) \
|
||||
do { \
|
||||
if (flag_gnu_linker) \
|
||||
{ \
|
||||
/* Output an N_SETT (0x16, 22.) for the name. */ \
|
||||
fprintf (FILE, "%s \"___PTR_LIST__\",22,0,0,", ASM_STABS_OP); \
|
||||
assemble_name (FILE, NAME); \
|
||||
fputc ('\n', FILE); \
|
||||
} \
|
||||
} while (0)
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,30 @@
|
|||
/* Configuration common to all targets running the GNU system. */
|
||||
|
||||
/* Macro to produce CPP_PREDEFINES for GNU on a given machine. */
|
||||
#define GNU_CPP_PREDEFINES(machine) \
|
||||
"-D" machine " -Acpu(" machine ") -Amachine(" machine ")" \
|
||||
"-Dunix -Asystem(unix) \
|
||||
-DMACH -Asystem(mach) \
|
||||
-D__GNU__ -Asystem(gnu)"
|
||||
|
||||
/* Provide GCC options for standard feature-test macros. */
|
||||
#undef CPP_SPEC
|
||||
#define CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{bsd:-D_BSD_SOURCE}"
|
||||
|
||||
/* Default C library spec. Use -lbsd-compat for gcc -bsd. */
|
||||
#undef LIB_SPEC
|
||||
#define LIB_SPEC "%{bsd:-lbsd-compat} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}"
|
||||
|
||||
/* Standard include directory. In GNU, "/usr" is a four-letter word. */
|
||||
#undef STANDARD_INCLUDE_DIR
|
||||
#define STANDARD_INCLUDE_DIR "/include"
|
||||
|
||||
|
||||
/* We have atexit. */
|
||||
#define HAVE_ATEXIT
|
||||
|
||||
/* Implicit library calls should use memcpy, not bcopy, etc. */
|
||||
#define TARGET_MEM_FUNCTIONS
|
||||
|
||||
/* The system headers under GNU are C++-aware. */
|
||||
#define NO_IMPLICIT_EXTERN_C
|
|
@ -0,0 +1,96 @@
|
|||
/* US Software GOFAST floating point library support.
|
||||
Copyright (C) 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. */
|
||||
|
||||
/* This is used by fp-bit.c. */
|
||||
#define US_SOFTWARE_GOFAST
|
||||
|
||||
/* The US Software GOFAST library requires special optabs support.
|
||||
There is no negation libcall, and several others have names different
|
||||
from gcc. This file consolidates the support in one place.
|
||||
|
||||
The basic plan is to leave gcc proper alone and via some hook fix things
|
||||
after the optabs have been set up. Our main entry point is
|
||||
INIT_GOFAST_OPTABS. */
|
||||
|
||||
#define INIT_GOFAST_OPTABS \
|
||||
do { \
|
||||
GOFAST_CLEAR_NEG_FLOAT_OPTAB; \
|
||||
GOFAST_RENAME_LIBCALLS; \
|
||||
} while (0)
|
||||
|
||||
#define GOFAST_CLEAR_NEG_FLOAT_OPTAB \
|
||||
do { \
|
||||
int mode; \
|
||||
for (mode = SFmode; (int) mode <= (int) TFmode; \
|
||||
mode = (enum machine_mode) ((int) mode + 1)) \
|
||||
neg_optab->handlers[(int) mode].libfunc = NULL_RTX; \
|
||||
} while (0)
|
||||
|
||||
#define GOFAST_RENAME_LIBCALLS \
|
||||
add_optab->handlers[(int) SFmode].libfunc = gen_rtx (SYMBOL_REF, Pmode, "fpadd"); \
|
||||
add_optab->handlers[(int) DFmode].libfunc = gen_rtx (SYMBOL_REF, Pmode, "dpadd"); \
|
||||
sub_optab->handlers[(int) SFmode].libfunc = gen_rtx (SYMBOL_REF, Pmode, "fpsub"); \
|
||||
sub_optab->handlers[(int) DFmode].libfunc = gen_rtx (SYMBOL_REF, Pmode, "dpsub"); \
|
||||
smul_optab->handlers[(int) SFmode].libfunc = gen_rtx (SYMBOL_REF, Pmode, "fpmul"); \
|
||||
smul_optab->handlers[(int) DFmode].libfunc = gen_rtx (SYMBOL_REF, Pmode, "dpmul"); \
|
||||
flodiv_optab->handlers[(int) SFmode].libfunc = gen_rtx (SYMBOL_REF, Pmode, "fpdiv"); \
|
||||
flodiv_optab->handlers[(int) DFmode].libfunc = gen_rtx (SYMBOL_REF, Pmode, "dpdiv"); \
|
||||
cmp_optab->handlers[(int) SFmode].libfunc = gen_rtx (SYMBOL_REF, Pmode, "fpcmp"); \
|
||||
cmp_optab->handlers[(int) DFmode].libfunc = gen_rtx (SYMBOL_REF, Pmode, "dpcmp"); \
|
||||
\
|
||||
extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "fptodp"); \
|
||||
truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "dptofp"); \
|
||||
\
|
||||
eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "fpcmp"); \
|
||||
nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "fpcmp"); \
|
||||
gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "fpcmp"); \
|
||||
gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "fpcmp"); \
|
||||
ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "fpcmp"); \
|
||||
lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "fpcmp"); \
|
||||
\
|
||||
eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "dpcmp"); \
|
||||
nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "dpcmp"); \
|
||||
gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "dpcmp"); \
|
||||
gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "dpcmp"); \
|
||||
ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "dpcmp"); \
|
||||
ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "dpcmp"); \
|
||||
\
|
||||
eqxf2_libfunc = NULL_RTX; \
|
||||
nexf2_libfunc = NULL_RTX; \
|
||||
gtxf2_libfunc = NULL_RTX; \
|
||||
gexf2_libfunc = NULL_RTX; \
|
||||
ltxf2_libfunc = NULL_RTX; \
|
||||
lexf2_libfunc = NULL_RTX; \
|
||||
\
|
||||
eqtf2_libfunc = NULL_RTX; \
|
||||
netf2_libfunc = NULL_RTX; \
|
||||
gttf2_libfunc = NULL_RTX; \
|
||||
getf2_libfunc = NULL_RTX; \
|
||||
lttf2_libfunc = NULL_RTX; \
|
||||
letf2_libfunc = NULL_RTX; \
|
||||
\
|
||||
floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "sitofp"); \
|
||||
floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "litodp"); \
|
||||
fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "fptosi"); \
|
||||
fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "dptoli"); \
|
||||
fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "fptoui"); \
|
||||
fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "dptoul"); \
|
||||
|
||||
/* End of GOFAST_RENAME_LIBCALLS */
|
|
@ -0,0 +1,81 @@
|
|||
/* Configuration for an i386 running 386BSD as the target machine. */
|
||||
|
||||
/* This is tested by i386gas.h. */
|
||||
#define YES_UNDERSCORES
|
||||
|
||||
#include "i386/gstabs.h"
|
||||
|
||||
/* Get perform_* macros to build libgcc.a. */
|
||||
#include "i386/perform.h"
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-Dunix -Di386 -D____386BSD____ -D__386BSD__ -DBSD_NET2 -Asystem(unix) -Asystem(bsd) -Acpu(i386) -Amachine(i386)"
|
||||
|
||||
/* Like the default, except no -lg. */
|
||||
#define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}"
|
||||
|
||||
#undef SIZE_TYPE
|
||||
#define SIZE_TYPE "unsigned int"
|
||||
|
||||
#undef PTRDIFF_TYPE
|
||||
#define PTRDIFF_TYPE "int"
|
||||
|
||||
#undef WCHAR_TYPE
|
||||
#define WCHAR_TYPE "short unsigned int"
|
||||
|
||||
#define WCHAR_UNSIGNED 1
|
||||
|
||||
#undef WCHAR_TYPE_SIZE
|
||||
#define WCHAR_TYPE_SIZE 16
|
||||
|
||||
/* 386BSD does have atexit. */
|
||||
|
||||
#define HAVE_ATEXIT
|
||||
|
||||
/* Redefine this to use %eax instead of %edx. */
|
||||
#undef FUNCTION_PROFILER
|
||||
#define FUNCTION_PROFILER(FILE, LABELNO) \
|
||||
{ \
|
||||
if (flag_pic) \
|
||||
{ \
|
||||
fprintf (FILE, "\tleal %sP%d@GOTOFF(%%ebx),%%eax\n", \
|
||||
LPREFIX, (LABELNO)); \
|
||||
fprintf (FILE, "\tcall *mcount@GOT(%%ebx)\n"); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
fprintf (FILE, "\tmovl $%sP%d,%%eax\n", LPREFIX, (LABELNO)); \
|
||||
fprintf (FILE, "\tcall mcount\n"); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* There are conflicting reports about whether this system uses
|
||||
a different assembler syntax. wilson@cygnus.com says # is right. */
|
||||
#undef COMMENT_BEGIN
|
||||
#define COMMENT_BEGIN "#"
|
||||
|
||||
#undef ASM_APP_ON
|
||||
#define ASM_APP_ON "#APP\n"
|
||||
|
||||
#undef ASM_APP_OFF
|
||||
#define ASM_APP_OFF "#NO_APP\n"
|
||||
|
||||
/* The following macros are stolen from i386v4.h */
|
||||
/* These have to be defined to get PIC code correct */
|
||||
|
||||
/* This is how to output an element of a case-vector that is relative.
|
||||
This is only used for PIC code. See comments by the `casesi' insn in
|
||||
i386.md for an explanation of the expression this outputs. */
|
||||
|
||||
#undef ASM_OUTPUT_ADDR_DIFF_ELT
|
||||
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \
|
||||
fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, VALUE)
|
||||
|
||||
/* Indicate that jump tables go in the text section. This is
|
||||
necessary when compiling PIC code. */
|
||||
|
||||
#define JUMP_TABLES_IN_TEXT_SECTION
|
||||
|
||||
/* Don't default to pcc-struct-return, because gcc is the only compiler, and
|
||||
we want to retain compatibility with older gcc versions. */
|
||||
#define DEFAULT_PCC_STRUCT_RETURN 0
|
|
@ -0,0 +1,69 @@
|
|||
/* Definitions for IBM PS2 running AIX/386 with gas.
|
||||
From: Minh Tran-Le <TRANLE@intellicorp.com>
|
||||
Copyright (C) 1988 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 configuration file is for gcc with gas-2.x and gnu ld 2.x
|
||||
* with aix ps/2 1.3.x.
|
||||
*/
|
||||
|
||||
/* Define USE_GAS if you have the new version of gas that can handle
|
||||
* multiple segments and .section pseudo op. This will allow gcc to
|
||||
* use the .init section for g++ ctor/dtor.
|
||||
*
|
||||
* If you don't have gas then undefined USE_GAS. You will also have
|
||||
* to use collect if you want to use g++
|
||||
*/
|
||||
#define USE_GAS
|
||||
|
||||
#include "i386/aix386ng.h"
|
||||
|
||||
/* Use crt1.o as a startup file and crtn.o as a closing file.
|
||||
And add crtbegin.o and crtend.o for ctors and dtors */
|
||||
|
||||
#undef STARTFILE_SPEC
|
||||
#define STARTFILE_SPEC \
|
||||
"%{pg:gcrt0.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}} crtbegin.o%s"
|
||||
#undef ENDFILE_SPEC
|
||||
#define ENDFILE_SPEC \
|
||||
"crtend.o%s crtn.o%s"
|
||||
|
||||
/* Removed the -K flags because the gnu ld does not handle it */
|
||||
#undef LINK_SPEC
|
||||
#define LINK_SPEC "%{T*} %{z:-lm}"
|
||||
|
||||
/* Define a few machine-specific details of the implementation of
|
||||
constructors. */
|
||||
|
||||
#undef INIT_SECTION_ASM_OP
|
||||
#define INIT_SECTION_ASM_OP ".section .init,\"x\""
|
||||
|
||||
#define CTOR_LIST_BEGIN \
|
||||
asm (INIT_SECTION_ASM_OP); \
|
||||
asm ("pushl $0")
|
||||
#define CTOR_LIST_END CTOR_LIST_BEGIN
|
||||
|
||||
#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
|
||||
do { \
|
||||
init_section (); \
|
||||
fprintf (FILE, "\tpushl $"); \
|
||||
assemble_name (FILE, NAME); \
|
||||
fprintf (FILE, "\n"); \
|
||||
} while (0)
|
|
@ -0,0 +1,143 @@
|
|||
/* Definitions for IBM PS2 running AIX/386.
|
||||
From: Minh Tran-Le <TRANLE@intellicorp.com>
|
||||
Copyright (C) 1988 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 "i386/i386.h"
|
||||
|
||||
/* Get the generic definitions for system V.3. */
|
||||
|
||||
#include "svr3.h"
|
||||
|
||||
/* Use the ATT assembler syntax.
|
||||
This overrides at least one macro (ASM_OUTPUT_LABELREF) from svr3.h. */
|
||||
|
||||
#include "i386/att.h"
|
||||
|
||||
/* Use crt1.o as a startup file and crtn.o as a closing file. */
|
||||
|
||||
#define STARTFILE_SPEC "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}"
|
||||
#define ENDFILE_SPEC "crtn.o%s"
|
||||
|
||||
#define LIB_SPEC "%{shlib:-lc_s} -lc"
|
||||
|
||||
/* Special flags for the linker. I don't know what they do. */
|
||||
|
||||
#define LINK_SPEC "%{K} %{!K:-K} %{T*} %{z:-lm}"
|
||||
|
||||
/* Specify predefined symbols in preprocessor. */
|
||||
|
||||
#define CPP_PREDEFINES "-Dps2 -Dunix -Di386 -Asystem(unix) -Asystem(aix) -Acpu(i386) -Amachine(i386)"
|
||||
|
||||
#define CPP_SPEC \
|
||||
"%{posix:-D_POSIX_SOURCE}%{!posix:-DAIX} -D_I386 -D_AIX -D_MBCS"
|
||||
|
||||
/* special flags for the aix assembler to generate the short form for all
|
||||
qualifying forward reference */
|
||||
/* The buggy /bin/as of aix ps/2 1.2.x cannot always handle it. */
|
||||
#if 0
|
||||
#define ASM_SPEC "-s2"
|
||||
#endif /* 0 */
|
||||
|
||||
#undef ASM_FILE_START
|
||||
#define ASM_FILE_START(FILE) \
|
||||
do { fprintf (FILE, "\t.file\t"); \
|
||||
output_quoted_string (FILE, dump_base_name); \
|
||||
fprintf (FILE, "\n"); \
|
||||
if (optimize) \
|
||||
ASM_FILE_START_1 (FILE); \
|
||||
else \
|
||||
fprintf (FILE, "\t.noopt\n"); \
|
||||
} while (0)
|
||||
|
||||
/* This was suggested, but it shouldn't be right for DBX output. -- RMS
|
||||
#define ASM_OUTPUT_SOURCE_FILENAME(FILE, NAME) */
|
||||
|
||||
/* Writing `int' for a bitfield forces int alignment for the structure. */
|
||||
|
||||
#define PCC_BITFIELD_TYPE_MATTERS 1
|
||||
|
||||
#ifndef USE_GAS
|
||||
/* Don't write a `.optim' pseudo; this assembler
|
||||
is said to have a bug when .optim is used. */
|
||||
|
||||
#undef ASM_FILE_START_1
|
||||
#define ASM_FILE_START_1(FILE) fprintf (FILE, "\t.noopt\n")
|
||||
#endif
|
||||
|
||||
/* Output assembler code to FILE to increment profiler label # LABELNO
|
||||
for profiling a function entry. */
|
||||
|
||||
#undef FUNCTION_PROFILER
|
||||
#define FUNCTION_PROFILER(FILE, LABELNO) \
|
||||
fprintf (FILE, "\tleal %sP%d,%%eax\n\tcall mcount\n", LPREFIX, (LABELNO));
|
||||
|
||||
/* Note that using bss_section here caused errors
|
||||
in building shared libraries on system V.3.
|
||||
but AIX 1.2 does not have yet shareable libraries on PS2 */
|
||||
#undef ASM_OUTPUT_LOCAL
|
||||
#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
|
||||
(bss_section (), \
|
||||
ASM_OUTPUT_LABEL ((FILE), (NAME)), \
|
||||
fprintf ((FILE), "\t.set .,.+%u\n", (ROUNDED)))
|
||||
|
||||
|
||||
/* Undef all the .init and .fini section stuff if we are not using gas and
|
||||
* gnu ld so that we can use collect because the standard /bin/as and /bin/ld
|
||||
* cannot handle those.
|
||||
*/
|
||||
#ifndef USE_GAS
|
||||
# undef INIT_SECTION_ASM_OP
|
||||
# undef FINI_SECTION_ASM_OP
|
||||
# undef CTORS_SECTION_ASM_OP
|
||||
# undef DTORS_SECTION_ASM_OP
|
||||
# undef ASM_OUTPUT_CONSTRUCTOR
|
||||
# undef ASM_OUTPUT_DESTRUCTOR
|
||||
# undef DO_GLOBAL_CTORS_BODY
|
||||
|
||||
# undef CTOR_LIST_BEGIN
|
||||
# define CTOR_LIST_BEGIN
|
||||
# undef CTOR_LIST_END
|
||||
# define CTOR_LIST_END
|
||||
# undef DTOR_LIST_BEGIN
|
||||
# define DTOR_LIST_BEGIN
|
||||
# undef DTOR_LIST_END
|
||||
# define DTOR_LIST_END
|
||||
|
||||
# undef CONST_SECTION_FUNCTION
|
||||
# define CONST_SECTION_FUNCTION \
|
||||
void \
|
||||
const_section () \
|
||||
{ \
|
||||
extern void text_section(); \
|
||||
text_section(); \
|
||||
}
|
||||
|
||||
# undef EXTRA_SECTION_FUNCTIONS
|
||||
# define EXTRA_SECTION_FUNCTIONS \
|
||||
CONST_SECTION_FUNCTION \
|
||||
BSS_SECTION_FUNCTION
|
||||
|
||||
/* for collect2 */
|
||||
# define OBJECT_FORMAT_COFF
|
||||
# define MY_ISCOFF(magic) \
|
||||
((magic) == I386MAGIC || (magic) == I386SVMAGIC)
|
||||
|
||||
#endif /* !USE_GAS */
|
|
@ -0,0 +1,106 @@
|
|||
/* Definitions for AT&T assembler syntax for the Intel 80386.
|
||||
Copyright (C) 1988 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 common aspects of all 386 Unix assemblers. */
|
||||
#include "i386/unix.h"
|
||||
|
||||
#define TARGET_VERSION fprintf (stderr, " (80386, ATT syntax)");
|
||||
|
||||
/* Define the syntax of instructions and addresses. */
|
||||
|
||||
/* Prefix for internally generated assembler labels. */
|
||||
#define LPREFIX ".L"
|
||||
|
||||
/* Assembler pseudos to introduce constants of various size. */
|
||||
|
||||
/* #define ASM_BYTE_OP "\t.byte" Now in svr3.h or svr4.h. */
|
||||
#define ASM_SHORT "\t.value"
|
||||
#define ASM_LONG "\t.long"
|
||||
#define ASM_DOUBLE "\t.double"
|
||||
|
||||
/* How to output an ASCII string constant. */
|
||||
|
||||
#define ASM_OUTPUT_ASCII(FILE, p, size) \
|
||||
do \
|
||||
{ int i = 0; \
|
||||
while (i < (size)) \
|
||||
{ if (i%10 == 0) { if (i!=0) fprintf ((FILE), "\n"); \
|
||||
fprintf ((FILE), "%s ", ASM_BYTE_OP); } \
|
||||
else fprintf ((FILE), ","); \
|
||||
fprintf ((FILE), "0x%x", ((p)[i++] & 0377)) ;} \
|
||||
fprintf ((FILE), "\n"); \
|
||||
} while (0)
|
||||
|
||||
/* Do use .optim by default on this machine. */
|
||||
#undef ASM_FILE_START_1
|
||||
#define ASM_FILE_START_1(FILE) fprintf (FILE, "\t.optim\n")
|
||||
|
||||
/* This is how to output an assembler line
|
||||
that says to advance the location counter
|
||||
to a multiple of 2**LOG bytes. */
|
||||
|
||||
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
|
||||
if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG))
|
||||
|
||||
/* This is how to output an assembler line
|
||||
that says to advance the location counter by SIZE bytes. */
|
||||
|
||||
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
|
||||
fprintf ((FILE), "\t.set .,.+%u\n", (SIZE))
|
||||
|
||||
/* Can't use ASM_OUTPUT_SKIP in text section; it doesn't leave 0s. */
|
||||
|
||||
#define ASM_NO_SKIP_IN_TEXT 1
|
||||
|
||||
#undef BSS_SECTION_FUNCTION /* Override the definition from svr3.h. */
|
||||
#define BSS_SECTION_FUNCTION \
|
||||
void \
|
||||
bss_section () \
|
||||
{ \
|
||||
if (in_section != in_bss) \
|
||||
{ \
|
||||
fprintf (asm_out_file, "%s\n", BSS_SECTION_ASM_OP); \
|
||||
in_section = in_bss; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Define the syntax of labels and symbol definitions/declarations. */
|
||||
|
||||
/* This is how to store into the string BUF
|
||||
the symbol_ref name of an internal numbered label where
|
||||
PREFIX is the class of label and NUM is the number within the class.
|
||||
This is suitable for output with `assemble_name'. */
|
||||
|
||||
#undef ASM_GENERATE_INTERNAL_LABEL
|
||||
#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \
|
||||
sprintf ((BUF), ".%s%d", (PREFIX), (NUMBER))
|
||||
|
||||
/* This is how to output an internal numbered label where
|
||||
PREFIX is the class of label and NUM is the number within the class. */
|
||||
|
||||
#undef ASM_OUTPUT_INTERNAL_LABEL
|
||||
#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
|
||||
fprintf (FILE, ".%s%d:\n", PREFIX, NUM)
|
||||
|
||||
/* This is how to output a reference to a user-level label named NAME. */
|
||||
|
||||
#undef ASM_OUTPUT_LABELREF
|
||||
#define ASM_OUTPUT_LABELREF(FILE,NAME) \
|
||||
fprintf (FILE, "%s", NAME)
|
|
@ -0,0 +1,130 @@
|
|||
/* Definitions for BSD assembler syntax for Intel 386
|
||||
(actually AT&T syntax for insns and operands,
|
||||
adapted to BSD conventions for symbol names and debugging.)
|
||||
Copyright (C) 1988 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 common aspects of all 386 Unix assemblers. */
|
||||
#include "i386/unix.h"
|
||||
|
||||
/* Use the Sequent Symmetry assembler syntax. */
|
||||
|
||||
#define TARGET_VERSION fprintf (stderr, " (80386, BSD syntax)");
|
||||
|
||||
/* Define the syntax of pseudo-ops, labels and comments. */
|
||||
|
||||
/* Prefix for internally generated assembler labels. If we aren't using
|
||||
underscores, we are using prefix `.'s to identify labels that should
|
||||
be ignored, as in `i386/gas.h' --karl@cs.umb.edu */
|
||||
#ifdef NO_UNDERSCORES
|
||||
#define LPREFIX ".L"
|
||||
#else
|
||||
#define LPREFIX "L"
|
||||
#endif /* not NO_UNDERSCORES */
|
||||
|
||||
/* Assembler pseudos to introduce constants of various size. */
|
||||
|
||||
#define ASM_BYTE_OP "\t.byte"
|
||||
#define ASM_SHORT "\t.word"
|
||||
#define ASM_LONG "\t.long"
|
||||
#define ASM_DOUBLE "\t.double"
|
||||
|
||||
/* Output at beginning of assembler file.
|
||||
??? I am skeptical of this -- RMS. */
|
||||
|
||||
#define ASM_FILE_START(FILE) \
|
||||
do { fprintf (FILE, "\t.file\t"); \
|
||||
output_quoted_string (FILE, dump_base_name); \
|
||||
fprintf (FILE, "\n"); \
|
||||
} while (0)
|
||||
|
||||
/* This was suggested, but it shouldn't be right for DBX output. -- RMS
|
||||
#define ASM_OUTPUT_SOURCE_FILENAME(FILE, NAME) */
|
||||
|
||||
|
||||
/* Define the syntax of labels and symbol definitions/declarations. */
|
||||
|
||||
/* This is how to output an assembler line
|
||||
that says to advance the location counter by SIZE bytes. */
|
||||
|
||||
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
|
||||
fprintf (FILE, "\t.space %u\n", (SIZE))
|
||||
|
||||
/* Define the syntax of labels and symbol definitions/declarations. */
|
||||
|
||||
/* This says how to output an assembler line
|
||||
to define a global common symbol. */
|
||||
|
||||
#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
|
||||
( fputs (".comm ", (FILE)), \
|
||||
assemble_name ((FILE), (NAME)), \
|
||||
fprintf ((FILE), ",%u\n", (ROUNDED)))
|
||||
|
||||
/* This says how to output an assembler line
|
||||
to define a local common symbol. */
|
||||
|
||||
#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
|
||||
( fputs (".lcomm ", (FILE)), \
|
||||
assemble_name ((FILE), (NAME)), \
|
||||
fprintf ((FILE), ",%u\n", (ROUNDED)))
|
||||
|
||||
/* This is how to output an assembler line
|
||||
that says to advance the location counter
|
||||
to a multiple of 2**LOG bytes. */
|
||||
|
||||
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
|
||||
if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", (LOG))
|
||||
|
||||
/* This is how to store into the string BUF
|
||||
the symbol_ref name of an internal numbered label where
|
||||
PREFIX is the class of label and NUM is the number within the class.
|
||||
This is suitable for output with `assemble_name'. */
|
||||
|
||||
#ifdef NO_UNDERSCORES
|
||||
#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \
|
||||
sprintf ((BUF), "*.%s%d", (PREFIX), (NUMBER))
|
||||
#else
|
||||
#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \
|
||||
sprintf ((BUF), "*%s%d", (PREFIX), (NUMBER))
|
||||
#endif
|
||||
|
||||
/* This is how to output an internal numbered label where
|
||||
PREFIX is the class of label and NUM is the number within the class. */
|
||||
|
||||
#ifdef NO_UNDERSCORES
|
||||
#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
|
||||
fprintf (FILE, ".%s%d:\n", PREFIX, NUM)
|
||||
#else
|
||||
#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
|
||||
fprintf (FILE, "%s%d:\n", PREFIX, NUM)
|
||||
#endif
|
||||
|
||||
/* This is how to output a reference to a user-level label named NAME. */
|
||||
|
||||
#ifdef NO_UNDERSCORES
|
||||
#define ASM_OUTPUT_LABELREF(FILE,NAME) fprintf (FILE, "%s", NAME)
|
||||
#else
|
||||
#define ASM_OUTPUT_LABELREF(FILE,NAME) fprintf (FILE, "_%s", NAME)
|
||||
#endif /* not NO_UNDERSCORES */
|
||||
|
||||
/* Sequent has some changes in the format of DBX symbols. */
|
||||
#define DBX_NO_XREFS 1
|
||||
|
||||
/* Don't split DBX symbols into continuations. */
|
||||
#define DBX_CONTIN_LENGTH 0
|
|
@ -0,0 +1,18 @@
|
|||
/* Configuration for an i386 running BSDI's BSD/386 1.1 as the target
|
||||
machine. */
|
||||
|
||||
#include "i386/386bsd.h"
|
||||
|
||||
/* We exist mostly to add -Dbsdi and such to the predefines. */
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-Dunix -Di386 -Dbsdi -D__i386__ -D__bsdi__ -D____386BSD____ -D__386BSD__ -DBSD_NET2 -Asystem(unix) -Asystem(bsd) -Acpu(i386) -Amachine(i386)"
|
||||
|
||||
#undef WCHAR_TYPE
|
||||
#define WCHAR_TYPE "int"
|
||||
|
||||
#undef WCHAR_UNSIGNED
|
||||
#define WCHAR_UNSIGNED 0
|
||||
|
||||
#undef WCHAR_TYPE_SIZE
|
||||
#define WCHAR_TYPE_SIZE 32
|
|
@ -0,0 +1,38 @@
|
|||
/^Makefile/,/^ rm -f config.run/d
|
||||
s/rm -f/del/
|
||||
s/|| cp/|| copy/
|
||||
/^config.status/,/ fi/d
|
||||
s/config.status//g
|
||||
s/\/dev\/null/NUL/g
|
||||
s/$(srcdir)\/c-parse/c-parse/g
|
||||
s/$(srcdir)\/c-gperf/c-gperf/g
|
||||
/^multilib.h/ s/multilib/not-multilib/
|
||||
/^target=/ c\
|
||||
target=winnt3.5
|
||||
/^xmake_file=/ d
|
||||
/^tmake_file=/ d
|
||||
/^out_file/ c\
|
||||
out_file=config/i386/i386.c
|
||||
/^out_object_file/ c\
|
||||
out_object_file=i386.obj
|
||||
/^md_file/ c\
|
||||
md_file=config/i386/i386.md
|
||||
/^tm_file/ c\
|
||||
tm_file=config/i386/win-nt.h
|
||||
/^build_xm_file/ c\
|
||||
build_xm_file=config/i386/xm-winnt.h
|
||||
/^host_xm_file/ c\
|
||||
host_xm_file=config/i386/xm-winnt.h
|
||||
/^####target/ i\
|
||||
CC = cl \
|
||||
CLIB = libc.lib kernel32.lib \
|
||||
CFLAGS = -Di386 -DWIN32 -D_WIN32 -D_M_IX86=300 -D_X86_=1 \\\
|
||||
-DALMOST_STDC -D_MSC_VER=800 \
|
||||
LDFLAGS = -align:0x1000 -subsystem:console -entry:mainCRTStartup \\\
|
||||
-stack:1000000,1000 \
|
||||
\
|
||||
EXTRA_OBJS=winnt.obj \
|
||||
winnt.obj: $(srcdir)/config/i386/winnt.c \
|
||||
\ $(CC) $(CFLAGS) \\\
|
||||
\ -I. -I$(srcdir) -I$(srcdir)/config -c $(srcdir)/config/i386/winnt.c \
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
/* Definitions of target machine for GNU compiler for Intel 80386
|
||||
running FreeBSD.
|
||||
Copyright (C) 1988, 1992, 1994 Free Software Foundation, Inc.
|
||||
Contributed by Poul-Henning Kamp <phk@login.dkuug.dk>
|
||||
|
||||
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 goes away when the math-emulator is fixed */
|
||||
#define TARGET_CPU_DEFAULT 0400 /* TARGET_NO_FANCY_MATH_387 */
|
||||
|
||||
/* This is tested by i386gas.h. */
|
||||
#define YES_UNDERSCORES
|
||||
|
||||
/* Don't assume anything about the header files. */
|
||||
#define NO_IMPLICIT_EXTERN_C
|
||||
|
||||
#include "i386/gstabs.h"
|
||||
|
||||
/* Get perform_* macros to build libgcc.a. */
|
||||
#include "i386/perform.h"
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-Dunix -Di386 -D__FreeBSD__ -D__386BSD__ -Asystem(unix) -Asystem(FreeBSD) -Acpu(i386) -Amachine(i386)"
|
||||
|
||||
/* Like the default, except no -lg. */
|
||||
#define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}"
|
||||
|
||||
#undef SIZE_TYPE
|
||||
#define SIZE_TYPE "unsigned int"
|
||||
|
||||
#undef PTRDIFF_TYPE
|
||||
#define PTRDIFF_TYPE "int"
|
||||
|
||||
#undef WCHAR_TYPE
|
||||
#define WCHAR_TYPE "short unsigned int"
|
||||
|
||||
#define WCHAR_UNSIGNED 1
|
||||
|
||||
#undef WCHAR_TYPE_SIZE
|
||||
#define WCHAR_TYPE_SIZE 16
|
||||
|
||||
#define HAVE_ATEXIT
|
||||
|
||||
/* There are conflicting reports about whether this system uses
|
||||
a different assembler syntax. wilson@cygnus.com says # is right. */
|
||||
#undef COMMENT_BEGIN
|
||||
#define COMMENT_BEGIN "#"
|
||||
|
||||
#undef ASM_APP_ON
|
||||
#define ASM_APP_ON "#APP\n"
|
||||
|
||||
#undef ASM_APP_OFF
|
||||
#define ASM_APP_OFF "#NO_APP\n"
|
||||
|
||||
/* The following macros are stolen from i386v4.h */
|
||||
/* These have to be defined to get PIC code correct */
|
||||
|
||||
/* This is how to output an element of a case-vector that is relative.
|
||||
This is only used for PIC code. See comments by the `casesi' insn in
|
||||
i386.md for an explanation of the expression this outputs. */
|
||||
|
||||
#undef ASM_OUTPUT_ADDR_DIFF_ELT
|
||||
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \
|
||||
fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, VALUE)
|
||||
|
||||
/* Indicate that jump tables go in the text section. This is
|
||||
necessary when compiling PIC code. */
|
||||
|
||||
#define JUMP_TABLES_IN_TEXT_SECTION
|
||||
|
||||
/* Don't default to pcc-struct-return, because gcc is the only compiler, and
|
||||
we want to retain compatibility with older gcc versions. */
|
||||
#define DEFAULT_PCC_STRUCT_RETURN 0
|
||||
|
||||
/* Profiling routines, partially copied from i386/osfrose.h. */
|
||||
|
||||
/* Redefine this to use %eax instead of %edx. */
|
||||
#undef FUNCTION_PROFILER
|
||||
#define FUNCTION_PROFILER(FILE, LABELNO) \
|
||||
{ \
|
||||
if (flag_pic) \
|
||||
{ \
|
||||
fprintf (FILE, "\tleal %sP%d@GOTOFF(%%ebx),%%eax\n", \
|
||||
LPREFIX, (LABELNO)); \
|
||||
fprintf (FILE, "\tcall *mcount@GOT(%%ebx)\n"); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
fprintf (FILE, "\tmovl $%sP%d,%%eax\n", LPREFIX, (LABELNO)); \
|
||||
fprintf (FILE, "\tcall mcount\n"); \
|
||||
} \
|
||||
}
|
||||
|
||||
/*
|
||||
* Some imports from svr4.h in support of shared libraries.
|
||||
* Currently, we need the DECLARE_OBJECT_SIZE stuff.
|
||||
*/
|
||||
|
||||
/* Define the strings used for the special svr4 .type and .size directives.
|
||||
These strings generally do not vary from one system running svr4 to
|
||||
another, but if a given system (e.g. m88k running svr) needs to use
|
||||
different pseudo-op names for these, they may be overridden in the
|
||||
file which includes this one. */
|
||||
|
||||
#define TYPE_ASM_OP ".type"
|
||||
#define SIZE_ASM_OP ".size"
|
||||
|
||||
/* This is how we tell the assembler that a symbol is weak. */
|
||||
|
||||
#define ASM_WEAKEN_LABEL(FILE,NAME) \
|
||||
do { fputs ("\t.weak\t", FILE); assemble_name (FILE, NAME); \
|
||||
fputc ('\n', FILE); } while (0)
|
||||
|
||||
/* The following macro defines the format used to output the second
|
||||
operand of the .type assembler directive. Different svr4 assemblers
|
||||
expect various different forms for this operand. The one given here
|
||||
is just a default. You may need to override it in your machine-
|
||||
specific tm.h file (depending upon the particulars of your assembler). */
|
||||
|
||||
#define TYPE_OPERAND_FMT "@%s"
|
||||
|
||||
/* Write the extra assembler code needed to declare a function's result.
|
||||
Most svr4 assemblers don't require any special declaration of the
|
||||
result value, but there are exceptions. */
|
||||
|
||||
#ifndef ASM_DECLARE_RESULT
|
||||
#define ASM_DECLARE_RESULT(FILE, RESULT)
|
||||
#endif
|
||||
|
||||
/* These macros generate the special .type and .size directives which
|
||||
are used to set the corresponding fields of the linker symbol table
|
||||
entries in an ELF object file under SVR4. These macros also output
|
||||
the starting labels for the relevant functions/objects. */
|
||||
|
||||
/* Write the extra assembler code needed to declare a function properly.
|
||||
Some svr4 assemblers need to also have something extra said about the
|
||||
function's return value. We allow for that here. */
|
||||
|
||||
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
|
||||
do { \
|
||||
fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \
|
||||
assemble_name (FILE, NAME); \
|
||||
putc (',', FILE); \
|
||||
fprintf (FILE, TYPE_OPERAND_FMT, "function"); \
|
||||
putc ('\n', FILE); \
|
||||
ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
|
||||
ASM_OUTPUT_LABEL(FILE, NAME); \
|
||||
} while (0)
|
||||
|
||||
/* Write the extra assembler code needed to declare an object properly. */
|
||||
|
||||
#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \
|
||||
do { \
|
||||
fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \
|
||||
assemble_name (FILE, NAME); \
|
||||
putc (',', FILE); \
|
||||
fprintf (FILE, TYPE_OPERAND_FMT, "object"); \
|
||||
putc ('\n', FILE); \
|
||||
size_directive_output = 0; \
|
||||
if (!flag_inhibit_size_directive && DECL_SIZE (DECL)) \
|
||||
{ \
|
||||
size_directive_output = 1; \
|
||||
fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \
|
||||
assemble_name (FILE, NAME); \
|
||||
fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \
|
||||
} \
|
||||
ASM_OUTPUT_LABEL(FILE, NAME); \
|
||||
} while (0)
|
||||
|
||||
/* Output the size directive for a decl in rest_of_decl_compilation
|
||||
in the case where we did not do so before the initializer.
|
||||
Once we find the error_mark_node, we know that the value of
|
||||
size_directive_output was set
|
||||
by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */
|
||||
|
||||
#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \
|
||||
do { \
|
||||
char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
|
||||
if (!flag_inhibit_size_directive && DECL_SIZE (DECL) \
|
||||
&& ! AT_END && TOP_LEVEL \
|
||||
&& DECL_INITIAL (DECL) == error_mark_node \
|
||||
&& !size_directive_output) \
|
||||
{ \
|
||||
fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \
|
||||
assemble_name (FILE, name); \
|
||||
fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL)));\
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* This is how to declare the size of a function. */
|
||||
|
||||
#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
|
||||
do { \
|
||||
if (!flag_inhibit_size_directive) \
|
||||
{ \
|
||||
char label[256]; \
|
||||
static int labelno; \
|
||||
labelno++; \
|
||||
ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno); \
|
||||
ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno); \
|
||||
fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \
|
||||
assemble_name (FILE, (FNAME)); \
|
||||
fprintf (FILE, ","); \
|
||||
assemble_name (FILE, label); \
|
||||
fprintf (FILE, "-"); \
|
||||
assemble_name (FILE, (FNAME)); \
|
||||
putc ('\n', FILE); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ASM_SPEC " %| %{fpic:-k} %{fPIC:-k}"
|
||||
#define LINK_SPEC \
|
||||
"%{!nostdlib:%{!r*:%{!e*:-e start}}} -dc -dp %{static:-Bstatic} %{assert*}"
|
||||
|
||||
/* This is defined when gcc is compiled in the BSD-directory-tree, and must
|
||||
* make up for the gap to all the stuff done in the GNU-makefiles.
|
||||
*/
|
||||
|
||||
#ifdef FREEBSD_NATIVE
|
||||
|
||||
#define INCLUDE_DEFAULTS { \
|
||||
{ "/usr/include", 0 }, \
|
||||
{ "/usr/include/g++", 1 }, \
|
||||
{ 0, 0} \
|
||||
}
|
||||
|
||||
#undef MD_EXEC_PREFIX
|
||||
#define MD_EXEC_PREFIX "/usr/libexec/"
|
||||
|
||||
#undef STANDARD_STARTFILE_PREFIX
|
||||
#define STANDARD_STARTFILE_PREFIX "/usr/lib"
|
||||
|
||||
#if 0 /* This is very wrong!!! */
|
||||
#define DEFAULT_TARGET_MACHINE "i386-unknown-freebsd_1.0"
|
||||
#define GPLUSPLUS_INCLUDE_DIR "/usr/local/lib/gcc-lib/i386-unknown-freebsd_1.0/2.5.8/include"
|
||||
#define TOOL_INCLUDE_DIR "/usr/local/i386-unknown-freebsd_1.0/include"
|
||||
#define GCC_INCLUDE_DIR "/usr/local/lib/gcc-lib/i386-unknown-freebsd_1.0/2.5.8/include"
|
||||
#endif
|
||||
|
||||
#endif /* FREEBSD_NATIVE */
|
|
@ -0,0 +1,256 @@
|
|||
/* Definitions of target machine for GNU compiler for Intel 80386
|
||||
running FreeBSD.
|
||||
Copyright (C) 1988, 1992, 1994 Free Software Foundation, Inc.
|
||||
Contributed by Poul-Henning Kamp <phk@login.dkuug.dk>
|
||||
|
||||
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 goes away when the math-emulator is fixed */
|
||||
#define TARGET_CPU_DEFAULT 0400 /* TARGET_NO_FANCY_MATH_387 */
|
||||
|
||||
/* This is tested by i386gas.h. */
|
||||
#define YES_UNDERSCORES
|
||||
|
||||
/* Don't assume anything about the header files. */
|
||||
#define NO_IMPLICIT_EXTERN_C
|
||||
|
||||
#include "i386/gstabs.h"
|
||||
|
||||
/* Get perform_* macros to build libgcc.a. */
|
||||
#include "i386/perform.h"
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-Dunix -Di386 -D__FreeBSD__ -D__386BSD__ -Asystem(unix) -Asystem(FreeBSD) -Acpu(i386) -Amachine(i386)"
|
||||
|
||||
/* Like the default, except no -lg. */
|
||||
#define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}"
|
||||
|
||||
#undef SIZE_TYPE
|
||||
#define SIZE_TYPE "unsigned int"
|
||||
|
||||
#undef PTRDIFF_TYPE
|
||||
#define PTRDIFF_TYPE "int"
|
||||
|
||||
#undef WCHAR_TYPE
|
||||
#define WCHAR_TYPE "short unsigned int"
|
||||
|
||||
#define WCHAR_UNSIGNED 1
|
||||
|
||||
#undef WCHAR_TYPE_SIZE
|
||||
#define WCHAR_TYPE_SIZE 16
|
||||
|
||||
#define HAVE_ATEXIT
|
||||
|
||||
/* There are conflicting reports about whether this system uses
|
||||
a different assembler syntax. wilson@cygnus.com says # is right. */
|
||||
#undef COMMENT_BEGIN
|
||||
#define COMMENT_BEGIN "#"
|
||||
|
||||
#undef ASM_APP_ON
|
||||
#define ASM_APP_ON "#APP\n"
|
||||
|
||||
#undef ASM_APP_OFF
|
||||
#define ASM_APP_OFF "#NO_APP\n"
|
||||
|
||||
/* The following macros are stolen from i386v4.h */
|
||||
/* These have to be defined to get PIC code correct */
|
||||
|
||||
/* This is how to output an element of a case-vector that is relative.
|
||||
This is only used for PIC code. See comments by the `casesi' insn in
|
||||
i386.md for an explanation of the expression this outputs. */
|
||||
|
||||
#undef ASM_OUTPUT_ADDR_DIFF_ELT
|
||||
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \
|
||||
fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, VALUE)
|
||||
|
||||
/* Indicate that jump tables go in the text section. This is
|
||||
necessary when compiling PIC code. */
|
||||
|
||||
#define JUMP_TABLES_IN_TEXT_SECTION
|
||||
|
||||
/* Don't default to pcc-struct-return, because gcc is the only compiler, and
|
||||
we want to retain compatibility with older gcc versions. */
|
||||
#define DEFAULT_PCC_STRUCT_RETURN 0
|
||||
|
||||
/* Profiling routines, partially copied from i386/osfrose.h. */
|
||||
|
||||
/* Redefine this to use %eax instead of %edx. */
|
||||
#undef FUNCTION_PROFILER
|
||||
#define FUNCTION_PROFILER(FILE, LABELNO) \
|
||||
{ \
|
||||
if (flag_pic) \
|
||||
{ \
|
||||
fprintf (FILE, "\tleal %sP%d@GOTOFF(%%ebx),%%eax\n", \
|
||||
LPREFIX, (LABELNO)); \
|
||||
fprintf (FILE, "\tcall *mcount@GOT(%%ebx)\n"); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
fprintf (FILE, "\tmovl $%sP%d,%%eax\n", LPREFIX, (LABELNO)); \
|
||||
fprintf (FILE, "\tcall mcount\n"); \
|
||||
} \
|
||||
}
|
||||
|
||||
/*
|
||||
* Some imports from svr4.h in support of shared libraries.
|
||||
* Currently, we need the DECLARE_OBJECT_SIZE stuff.
|
||||
*/
|
||||
|
||||
/* Define the strings used for the special svr4 .type and .size directives.
|
||||
These strings generally do not vary from one system running svr4 to
|
||||
another, but if a given system (e.g. m88k running svr) needs to use
|
||||
different pseudo-op names for these, they may be overridden in the
|
||||
file which includes this one. */
|
||||
|
||||
#define TYPE_ASM_OP ".type"
|
||||
#define SIZE_ASM_OP ".size"
|
||||
|
||||
/* This is how we tell the assembler that a symbol is weak. */
|
||||
|
||||
#define ASM_WEAKEN_LABEL(FILE,NAME) \
|
||||
do { fputs ("\t.weak\t", FILE); assemble_name (FILE, NAME); \
|
||||
fputc ('\n', FILE); } while (0)
|
||||
|
||||
/* The following macro defines the format used to output the second
|
||||
operand of the .type assembler directive. Different svr4 assemblers
|
||||
expect various different forms for this operand. The one given here
|
||||
is just a default. You may need to override it in your machine-
|
||||
specific tm.h file (depending upon the particulars of your assembler). */
|
||||
|
||||
#define TYPE_OPERAND_FMT "@%s"
|
||||
|
||||
/* Write the extra assembler code needed to declare a function's result.
|
||||
Most svr4 assemblers don't require any special declaration of the
|
||||
result value, but there are exceptions. */
|
||||
|
||||
#ifndef ASM_DECLARE_RESULT
|
||||
#define ASM_DECLARE_RESULT(FILE, RESULT)
|
||||
#endif
|
||||
|
||||
/* These macros generate the special .type and .size directives which
|
||||
are used to set the corresponding fields of the linker symbol table
|
||||
entries in an ELF object file under SVR4. These macros also output
|
||||
the starting labels for the relevant functions/objects. */
|
||||
|
||||
/* Write the extra assembler code needed to declare a function properly.
|
||||
Some svr4 assemblers need to also have something extra said about the
|
||||
function's return value. We allow for that here. */
|
||||
|
||||
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
|
||||
do { \
|
||||
fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \
|
||||
assemble_name (FILE, NAME); \
|
||||
putc (',', FILE); \
|
||||
fprintf (FILE, TYPE_OPERAND_FMT, "function"); \
|
||||
putc ('\n', FILE); \
|
||||
ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
|
||||
ASM_OUTPUT_LABEL(FILE, NAME); \
|
||||
} while (0)
|
||||
|
||||
/* Write the extra assembler code needed to declare an object properly. */
|
||||
|
||||
#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \
|
||||
do { \
|
||||
fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \
|
||||
assemble_name (FILE, NAME); \
|
||||
putc (',', FILE); \
|
||||
fprintf (FILE, TYPE_OPERAND_FMT, "object"); \
|
||||
putc ('\n', FILE); \
|
||||
size_directive_output = 0; \
|
||||
if (!flag_inhibit_size_directive && DECL_SIZE (DECL)) \
|
||||
{ \
|
||||
size_directive_output = 1; \
|
||||
fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \
|
||||
assemble_name (FILE, NAME); \
|
||||
fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \
|
||||
} \
|
||||
ASM_OUTPUT_LABEL(FILE, NAME); \
|
||||
} while (0)
|
||||
|
||||
/* Output the size directive for a decl in rest_of_decl_compilation
|
||||
in the case where we did not do so before the initializer.
|
||||
Once we find the error_mark_node, we know that the value of
|
||||
size_directive_output was set
|
||||
by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */
|
||||
|
||||
#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \
|
||||
do { \
|
||||
char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
|
||||
if (!flag_inhibit_size_directive && DECL_SIZE (DECL) \
|
||||
&& ! AT_END && TOP_LEVEL \
|
||||
&& DECL_INITIAL (DECL) == error_mark_node \
|
||||
&& !size_directive_output) \
|
||||
{ \
|
||||
fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \
|
||||
assemble_name (FILE, name); \
|
||||
fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL)));\
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* This is how to declare the size of a function. */
|
||||
|
||||
#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
|
||||
do { \
|
||||
if (!flag_inhibit_size_directive) \
|
||||
{ \
|
||||
char label[256]; \
|
||||
static int labelno; \
|
||||
labelno++; \
|
||||
ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno); \
|
||||
ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno); \
|
||||
fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \
|
||||
assemble_name (FILE, (FNAME)); \
|
||||
fprintf (FILE, ","); \
|
||||
assemble_name (FILE, label); \
|
||||
fprintf (FILE, "-"); \
|
||||
assemble_name (FILE, (FNAME)); \
|
||||
putc ('\n', FILE); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ASM_SPEC " %| %{fpic:-k} %{fPIC:-k}"
|
||||
#define LINK_SPEC \
|
||||
"%{!nostdlib:%{!r*:%{!e*:-e start}}} -dc -dp %{static:-Bstatic} %{assert*}"
|
||||
|
||||
/* This is defined when gcc is compiled in the BSD-directory-tree, and must
|
||||
* make up for the gap to all the stuff done in the GNU-makefiles.
|
||||
*/
|
||||
|
||||
#ifdef FREEBSD_NATIVE
|
||||
|
||||
#define INCLUDE_DEFAULTS { \
|
||||
{ "/usr/include", 0 }, \
|
||||
{ "/usr/include/g++", 1 }, \
|
||||
{ 0, 0} \
|
||||
}
|
||||
|
||||
#undef MD_EXEC_PREFIX
|
||||
#define MD_EXEC_PREFIX "/usr/libexec/"
|
||||
|
||||
#undef STANDARD_STARTFILE_PREFIX
|
||||
#define STANDARD_STARTFILE_PREFIX "/usr/lib"
|
||||
|
||||
#if 0 /* This is very wrong!!! */
|
||||
#define DEFAULT_TARGET_MACHINE "i386-unknown-freebsd_1.0"
|
||||
#define GPLUSPLUS_INCLUDE_DIR "/usr/local/lib/gcc-lib/i386-unknown-freebsd_1.0/2.5.8/include"
|
||||
#define TOOL_INCLUDE_DIR "/usr/local/i386-unknown-freebsd_1.0/include"
|
||||
#define GCC_INCLUDE_DIR "/usr/local/lib/gcc-lib/i386-unknown-freebsd_1.0/2.5.8/include"
|
||||
#endif
|
||||
|
||||
#endif /* FREEBSD_NATIVE */
|
|
@ -0,0 +1,155 @@
|
|||
/* Definitions for Intel 386 running system V with gnu tools
|
||||
Copyright (C) 1988, 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. */
|
||||
|
||||
/* Note that i386/seq-gas.h is a GAS configuration that does not use this
|
||||
file. */
|
||||
|
||||
#include "i386/i386.h"
|
||||
|
||||
#ifndef YES_UNDERSCORES
|
||||
/* Define this now, because i386/bsd.h tests it. */
|
||||
#define NO_UNDERSCORES
|
||||
#endif
|
||||
|
||||
/* Use the bsd assembler syntax. */
|
||||
/* we need to do this because gas is really a bsd style assembler,
|
||||
* and so doesn't work well this these att-isms:
|
||||
*
|
||||
* ASM_OUTPUT_SKIP is .set .,.+N, which isn't implemented in gas
|
||||
* ASM_OUTPUT_LOCAL is done with .set .,.+N, but that can't be
|
||||
* used to define bss static space
|
||||
*
|
||||
* Next is the question of whether to uses underscores. RMS didn't
|
||||
* like this idea at first, but since it is now obvious that we
|
||||
* need this separate tm file for use with gas, at least to get
|
||||
* dbx debugging info, I think we should also switch to underscores.
|
||||
* We can keep i386v for real att style output, and the few
|
||||
* people who want both form will have to compile twice.
|
||||
*/
|
||||
|
||||
#include "i386/bsd.h"
|
||||
|
||||
/* these come from i386/bsd.h, but are specific to sequent */
|
||||
#undef DBX_NO_XREFS
|
||||
#undef DBX_CONTIN_LENGTH
|
||||
|
||||
/* Ask for COFF symbols. */
|
||||
|
||||
#define SDB_DEBUGGING_INFO
|
||||
|
||||
/* Specify predefined symbols in preprocessor. */
|
||||
|
||||
#define CPP_PREDEFINES "-Dunix -Di386 -Asystem(unix) -Acpu(i386) -Amachine(i386)"
|
||||
#define CPP_SPEC "%{posix:-D_POSIX_SOURCE}"
|
||||
|
||||
/* Allow #sccs in preprocessor. */
|
||||
|
||||
#define SCCS_DIRECTIVE
|
||||
|
||||
/* Output #ident as a .ident. */
|
||||
|
||||
#define ASM_OUTPUT_IDENT(FILE, NAME) fprintf (FILE, "\t.ident \"%s\"\n", NAME);
|
||||
|
||||
/* Implicit library calls should use memcpy, not bcopy, etc. */
|
||||
|
||||
#define TARGET_MEM_FUNCTIONS
|
||||
|
||||
#if 0 /* People say gas uses the log as the arg to .align. */
|
||||
/* When using gas, .align N aligns to an N-byte boundary. */
|
||||
|
||||
#undef ASM_OUTPUT_ALIGN
|
||||
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
|
||||
if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG))
|
||||
#endif
|
||||
|
||||
/* Align labels, etc. at 4-byte boundaries.
|
||||
For the 486, align to 16-byte boundary for sake of cache. */
|
||||
|
||||
#undef ASM_OUTPUT_ALIGN_CODE
|
||||
#define ASM_OUTPUT_ALIGN_CODE(FILE) \
|
||||
fprintf ((FILE), "\t.align %d,0x90\n", i386_align_jumps)
|
||||
|
||||
/* Align start of loop at 4-byte boundary. */
|
||||
|
||||
#undef ASM_OUTPUT_LOOP_ALIGN
|
||||
#define ASM_OUTPUT_LOOP_ALIGN(FILE) \
|
||||
fprintf ((FILE), "\t.align %d,0x90\n", i386_align_loops)
|
||||
|
||||
|
||||
/* A C statement or statements which output an assembler instruction
|
||||
opcode to the stdio stream STREAM. The macro-operand PTR is a
|
||||
variable of type `char *' which points to the opcode name in its
|
||||
"internal" form--the form that is written in the machine description.
|
||||
|
||||
GAS version 1.38.1 doesn't understand the `repz' opcode mnemonic.
|
||||
So use `repe' instead. */
|
||||
|
||||
#define ASM_OUTPUT_OPCODE(STREAM, PTR) \
|
||||
{ \
|
||||
if ((PTR)[0] == 'r' \
|
||||
&& (PTR)[1] == 'e' \
|
||||
&& (PTR)[2] == 'p') \
|
||||
{ \
|
||||
if ((PTR)[3] == 'z') \
|
||||
{ \
|
||||
fprintf (STREAM, "repe"); \
|
||||
(PTR) += 4; \
|
||||
} \
|
||||
else if ((PTR)[3] == 'n' && (PTR)[4] == 'z') \
|
||||
{ \
|
||||
fprintf (STREAM, "repne"); \
|
||||
(PTR) += 5; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Define macro used to output shift-double opcodes when the shift
|
||||
count is in %cl. Some assemblers require %cl as an argument;
|
||||
some don't.
|
||||
|
||||
GAS requires the %cl argument, so override i386/unix.h. */
|
||||
|
||||
#undef AS3_SHIFT_DOUBLE
|
||||
#define AS3_SHIFT_DOUBLE(a,b,c,d) AS3 (a,b,c,d)
|
||||
|
||||
/* Print opcodes the way that GAS expects them. */
|
||||
#define GAS_MNEMONICS 1
|
||||
|
||||
#ifdef NO_UNDERSCORES /* If user-symbols don't have underscores,
|
||||
then it must take more than `L' to identify
|
||||
a label that should be ignored. */
|
||||
|
||||
/* This is how to store into the string BUF
|
||||
the symbol_ref name of an internal numbered label where
|
||||
PREFIX is the class of label and NUM is the number within the class.
|
||||
This is suitable for output with `assemble_name'. */
|
||||
|
||||
#undef ASM_GENERATE_INTERNAL_LABEL
|
||||
#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \
|
||||
sprintf ((BUF), ".%s%d", (PREFIX), (NUMBER))
|
||||
|
||||
/* This is how to output an internal numbered label where
|
||||
PREFIX is the class of label and NUM is the number within the class. */
|
||||
|
||||
#undef ASM_OUTPUT_INTERNAL_LABEL
|
||||
#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
|
||||
fprintf (FILE, ".%s%d:\n", PREFIX, NUM)
|
||||
|
||||
#endif /* NO_UNDERSCORES */
|
|
@ -0,0 +1,20 @@
|
|||
/* Configuration for an i386 running GNU with ELF as the target machine. */
|
||||
|
||||
/* This does it mostly for us. */
|
||||
#include <i386/linux.h>
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES GNU_CPP_PREDEFINES("i386")
|
||||
|
||||
#undef LINK_SPEC
|
||||
#define LINK_SPEC "-m elf_i386 %{shared:-shared} \
|
||||
%{!shared: \
|
||||
%{!ibcs: \
|
||||
%{!static: \
|
||||
%{rdynamic:-export-dynamic} \
|
||||
%{!dynamic-linker:-dynamic-linker /lib/ld.so} \
|
||||
%{!rpath:-rpath /lib/}} %{static:-static}}}"
|
||||
|
||||
|
||||
/* Get machine-independent configuration parameters for the GNU system. */
|
||||
#include <gnu.h>
|
|
@ -0,0 +1,64 @@
|
|||
/* Configuration for an i386 running MS-DOS with djgpp/go32. */
|
||||
|
||||
/* Don't assume anything about the header files. */
|
||||
#define NO_IMPLICIT_EXTERN_C
|
||||
|
||||
#define HANDLE_SYSV_PRAGMA
|
||||
|
||||
#define YES_UNDERSCORES
|
||||
|
||||
#include "i386/gas.h"
|
||||
|
||||
#ifdef CPP_PREDEFINES
|
||||
#undef CPP_PREDEFINES
|
||||
#endif
|
||||
#define CPP_PREDEFINES "-Dunix -Di386 -DGO32 -DMSDOS \
|
||||
-Asystem(unix) -Asystem(msdos) -Acpu(i386) -Amachine(i386)"
|
||||
|
||||
#undef EXTRA_SECTIONS
|
||||
#define EXTRA_SECTIONS in_ctor, in_dtor
|
||||
|
||||
#undef EXTRA_SECTION_FUNCTIONS
|
||||
#define EXTRA_SECTION_FUNCTIONS \
|
||||
CTOR_SECTION_FUNCTION \
|
||||
DTOR_SECTION_FUNCTION
|
||||
|
||||
#define CTOR_SECTION_FUNCTION \
|
||||
void \
|
||||
ctor_section () \
|
||||
{ \
|
||||
if (in_section != in_ctor) \
|
||||
{ \
|
||||
fprintf (asm_out_file, "\t.section .ctor\n"); \
|
||||
in_section = in_ctor; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define DTOR_SECTION_FUNCTION \
|
||||
void \
|
||||
dtor_section () \
|
||||
{ \
|
||||
if (in_section != in_dtor) \
|
||||
{ \
|
||||
fprintf (asm_out_file, "\t.section .dtor\n"); \
|
||||
in_section = in_dtor; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
|
||||
do { \
|
||||
ctor_section (); \
|
||||
fprintf (FILE, "%s\t", ASM_LONG); \
|
||||
assemble_name (FILE, NAME); \
|
||||
fprintf (FILE, "\n"); \
|
||||
} while (0)
|
||||
|
||||
#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \
|
||||
do { \
|
||||
dtor_section (); \
|
||||
fprintf (FILE, "%s\t", ASM_LONG); \
|
||||
assemble_name (FILE, NAME); \
|
||||
fprintf (FILE, "\n"); \
|
||||
} while (0)
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
#include "i386/gas.h"
|
||||
|
||||
/* We do not want to output SDB debugging information. */
|
||||
|
||||
#undef SDB_DEBUGGING_INFO
|
||||
|
||||
/* We want to output DBX debugging information. */
|
||||
|
||||
#define DBX_DEBUGGING_INFO
|
|
@ -0,0 +1,34 @@
|
|||
/* Definitions for "naked" Intel 386 using a.out (or coff encap'd
|
||||
a.out) object format and stabs debugging info.
|
||||
|
||||
Copyright (C) 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. */
|
||||
|
||||
|
||||
/* This is tested by gas.h. */
|
||||
#define YES_UNDERSCORES
|
||||
|
||||
#include "i386/gstabs.h"
|
||||
|
||||
/* Specify predefined symbols in preprocessor. */
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-Di386"
|
||||
|
||||
/* end of i386-aout.h */
|
|
@ -0,0 +1,97 @@
|
|||
/* Definitions for "naked" Intel 386 using coff object format files
|
||||
and coff debugging info.
|
||||
|
||||
Copyright (C) 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 "i386/gas.h"
|
||||
|
||||
/* Specify predefined symbols in preprocessor. */
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-Di386"
|
||||
|
||||
#undef DBX_DEBUGGING_INFO
|
||||
#define SDB_DEBUGGING_INFO
|
||||
|
||||
/* Support the ctors and dtors sections for g++. */
|
||||
|
||||
#define CTORS_SECTION_ASM_OP ".section\t.ctors,\"x\""
|
||||
#define DTORS_SECTION_ASM_OP ".section\t.dtors,\"x\""
|
||||
|
||||
/* A list of other sections which the compiler might be "in" at any
|
||||
given time. */
|
||||
|
||||
#undef EXTRA_SECTIONS
|
||||
#define EXTRA_SECTIONS in_ctors, in_dtors
|
||||
|
||||
/* A list of extra section function definitions. */
|
||||
|
||||
#undef EXTRA_SECTION_FUNCTIONS
|
||||
#define EXTRA_SECTION_FUNCTIONS \
|
||||
CTORS_SECTION_FUNCTION \
|
||||
DTORS_SECTION_FUNCTION
|
||||
|
||||
#define CTORS_SECTION_FUNCTION \
|
||||
void \
|
||||
ctors_section () \
|
||||
{ \
|
||||
if (in_section != in_ctors) \
|
||||
{ \
|
||||
fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP); \
|
||||
in_section = in_ctors; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define DTORS_SECTION_FUNCTION \
|
||||
void \
|
||||
dtors_section () \
|
||||
{ \
|
||||
if (in_section != in_dtors) \
|
||||
{ \
|
||||
fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP); \
|
||||
in_section = in_dtors; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define INT_ASM_OP ".long"
|
||||
|
||||
/* A C statement (sans semicolon) to output an element in the table of
|
||||
global constructors. */
|
||||
#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
|
||||
do { \
|
||||
ctors_section (); \
|
||||
fprintf (FILE, "\t%s\t ", INT_ASM_OP); \
|
||||
assemble_name (FILE, NAME); \
|
||||
fprintf (FILE, "\n"); \
|
||||
} while (0)
|
||||
|
||||
/* A C statement (sans semicolon) to output an element in the table of
|
||||
global destructors. */
|
||||
#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \
|
||||
do { \
|
||||
dtors_section (); \
|
||||
fprintf (FILE, "\t%s\t ", INT_ASM_OP); \
|
||||
assemble_name (FILE, NAME); \
|
||||
fprintf (FILE, "\n"); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* end of i386-coff.h */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,67 @@
|
|||
/* Definitions for Intel 386 running Interactive Unix System V,
|
||||
producing stabs-in-coff output (using a slightly modified gas).
|
||||
Specifically, this is for recent versions that support POSIX;
|
||||
for version 2.0.2, use configuration option i386-sysv instead. */
|
||||
|
||||
/* Underscores are not used on ISC systems (probably not on any COFF
|
||||
system), despite the comments in i386/gas.h. If this is not defined,
|
||||
enquire (for example) will fail to link. --karl@cs.umb.edu */
|
||||
#define NO_UNDERSCORES
|
||||
|
||||
/* Mostly like other gas-using systems. */
|
||||
#include "i386/gas.h"
|
||||
|
||||
/* But with ISC-specific additions. */
|
||||
#include "i386/isc.h"
|
||||
|
||||
/* We do not want to output SDB debugging information. */
|
||||
|
||||
#undef SDB_DEBUGGING_INFO
|
||||
|
||||
/* We want to output DBX debugging information. */
|
||||
|
||||
#define DBX_DEBUGGING_INFO
|
||||
|
||||
|
||||
/* The function `dbxout_init' in dbxout.c omits the first character of
|
||||
`ltext_label_name' when outputting the main source directory and main
|
||||
source filename. I don't understand why, but rather than making a
|
||||
system-independent change there, I override dbxout.c's defaults.
|
||||
Perhaps it would be better to use ".Ltext0" instead of
|
||||
`ltext_label_name', but we've already generated the label, so we just
|
||||
use it here. --karl@cs.umb.edu */
|
||||
#define DBX_OUTPUT_MAIN_SOURCE_DIRECTORY(asmfile, cwd) \
|
||||
do { fprintf (asmfile, "%s ", ASM_STABS_OP); \
|
||||
output_quoted_string (asmfile, cwd); \
|
||||
fprintf (asmfile, ",%d,0,0,%s\n", N_SO, ltext_label_name); \
|
||||
} while (0)
|
||||
#define DBX_OUTPUT_MAIN_SOURCE_FILENAME(asmfile, input_file_name) \
|
||||
fprintf (asmfile, "%s ", ASM_STABS_OP); \
|
||||
output_quoted_string (input_file_name); \
|
||||
fprintf (asmfile, ",%d,0,0,%s\n", N_SO, ltext_label_name); \
|
||||
text_section (); \
|
||||
ASM_OUTPUT_INTERNAL_LABEL (asmfile, "Ltext", 0)
|
||||
|
||||
|
||||
/* Because we don't include `svr3.h', we haven't yet defined SIZE_TYPE
|
||||
and PTRDIFF_TYPE. ISC's definitions don't match GCC's defaults, so: */
|
||||
|
||||
#undef SIZE_TYPE
|
||||
#define SIZE_TYPE "unsigned int"
|
||||
|
||||
#undef PTRDIFF_TYPE
|
||||
#define PTRDIFF_TYPE "int"
|
||||
|
||||
|
||||
/* But we can't use crtbegin.o and crtend.o, because gas 1.38.1 doesn't
|
||||
grok .section. The definitions here are otherwise identical to those
|
||||
in i386/isc.h. */
|
||||
#undef STARTFILE_SPEC
|
||||
#define STARTFILE_SPEC \
|
||||
"%{!shlib:%{posix:%{pg:mcrtp1.o%s}%{!pg:%{p:mcrtp1.o%s}%{!p:crtp1.o%s}}}\
|
||||
%{!posix:%{pg:mcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}\
|
||||
%{p:-L/lib/libp} %{pg:-L/lib/libp}}}\
|
||||
%{shlib:%{posix:crtp1.o%s}%{!posix:crt1.o%s}}"
|
||||
|
||||
#undef ENDFILE_SPEC
|
||||
#define ENDFILE_SPEC "crtn.o%s"
|
|
@ -0,0 +1,89 @@
|
|||
/* Assembler-independent definitions for an Intel 386 running
|
||||
Interactive Unix System V. Specifically, this is for recent versions
|
||||
that support POSIX. */
|
||||
|
||||
/* Use crt1.o, not crt0.o, as a startup file, and crtn.o as a closing file. */
|
||||
#undef STARTFILE_SPEC
|
||||
#define STARTFILE_SPEC \
|
||||
"%{!shlib:%{posix:%{pg:mcrtp1.o%s}%{!pg:%{p:mcrtp1.o%s}%{!p:crtp1.o%s}}}\
|
||||
%{Xp:%{pg:mcrtp1.o%s}%{!pg:%{p:mcrtp1.o%s}%{!p:crtp1.o%s}}}\
|
||||
%{!posix:%{!Xp:%{pg:mcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}\
|
||||
%{p:-L/lib/libp} %{pg:-L/lib/libp}}}}\
|
||||
%{shlib:%{Xp:crtp1.o%s}%{posix:crtp1.o%s}%{!posix:%{!Xp:crt1.o%s}}}\
|
||||
crtbegin.o%s"
|
||||
|
||||
#define ENDFILE_SPEC "crtend.o%s crtn.o%s"
|
||||
|
||||
/* Library spec */
|
||||
#undef LIB_SPEC
|
||||
#define LIB_SPEC "%{shlib:-lc_s} %{posix:-lcposix} %{Xp:-lcposix} -lc -lg"
|
||||
|
||||
#undef CPP_SPEC
|
||||
#define CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{Xp:-D_POSIX_SOURCE}"
|
||||
|
||||
/* ISC 2.2 uses `char' for `wchar_t'. */
|
||||
#undef WCHAR_TYPE
|
||||
#define WCHAR_TYPE "char"
|
||||
|
||||
#undef WCHAR_TYPE_SIZE
|
||||
#define WCHAR_TYPE_SIZE BITS_PER_UNIT
|
||||
|
||||
#if 0
|
||||
/* This is apparently not true: ISC versions up to 3.0, at least, use
|
||||
the standard calling sequence in which the called function pops the
|
||||
extra arg. */
|
||||
/* caller has to pop the extra argument passed to functions that return
|
||||
structures. */
|
||||
|
||||
#undef RETURN_POPS_ARGS
|
||||
#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) \
|
||||
(TREE_CODE (FUNTYPE) == IDENTIFIER_NODE ? 0 \
|
||||
: (TARGET_RTD \
|
||||
&& (TYPE_ARG_TYPES (FUNTYPE) == 0 \
|
||||
|| (TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) \
|
||||
== void_type_node))) ? (SIZE) \
|
||||
: 0)
|
||||
/* On other 386 systems, the last line looks like this:
|
||||
: (aggregate_value_p (TREE_TYPE (FUNTYPE))) ? GET_MODE_SIZE (Pmode) : 0) */
|
||||
#endif
|
||||
|
||||
/* Handle #pragma pack and #pragma weak. */
|
||||
#define HANDLE_SYSV_PRAGMA
|
||||
|
||||
/* By default, target has a 80387, uses IEEE compatible arithmetic,
|
||||
and returns float values in the 387, ie,
|
||||
(TARGET_80387 | TARGET_FLOAT_RETURNS_IN_80387)
|
||||
|
||||
ISC's software emulation of a 387 fails to handle the `fucomp'
|
||||
opcode. fucomp is only used when generating IEEE compliant code.
|
||||
So don't make TARGET_IEEE_FP default for ISC. */
|
||||
|
||||
#undef TARGET_DEFAULT
|
||||
#define TARGET_DEFAULT 0201
|
||||
|
||||
/* The ISC 2.0.2 software FPU emulator apparently can't handle
|
||||
80-bit XFmode insns, so don't generate them. */
|
||||
#undef LONG_DOUBLE_TYPE_SIZE
|
||||
#define LONG_DOUBLE_TYPE_SIZE 64
|
||||
|
||||
/* The ISC assembler does not like a .file directive with a name
|
||||
longer than 14 characters. Truncating it will not permit
|
||||
debugging to work properly, but at least we won't get an error
|
||||
message. */
|
||||
|
||||
#undef ASM_FILE_START
|
||||
#define ASM_FILE_START(FILE) \
|
||||
do { \
|
||||
char c; \
|
||||
int max = 0; \
|
||||
char *string = dump_base_name; \
|
||||
\
|
||||
fputs ("\t.file\t\"", FILE); \
|
||||
\
|
||||
while ((c = *string++) != 0 && max++ < 14) { \
|
||||
if (c == '\"' || c == '\\') \
|
||||
putc ('\\', FILE); \
|
||||
putc (c, FILE); \
|
||||
} \
|
||||
fputs ("\"\n", FILE); \
|
||||
} while (0)
|
|
@ -0,0 +1,12 @@
|
|||
/* Definitions for Intel 386 running Interactive Unix System V.
|
||||
Specifically, this is for recent versions that support POSIX;
|
||||
for version 2.0.2, use configuration option i386-sysv instead.
|
||||
(But set TARGET_DEFAULT to 0201 if you do that,
|
||||
if you don't have a real 80387.) */
|
||||
|
||||
/* Mostly it's like AT&T Unix System V. */
|
||||
|
||||
#include "i386/sysv3.h"
|
||||
|
||||
/* But with a few changes. */
|
||||
#include "i386/isc.h"
|
|
@ -0,0 +1,43 @@
|
|||
/* Definitions for Intel 386 running Interactive Unix System V,
|
||||
using dbx-in-coff encapsulation.
|
||||
Specifically, this is for recent versions that support POSIX.
|
||||
Copyright (C) 1992, 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. */
|
||||
|
||||
/* Mostly it's like AT&T Unix System V with dbx-in-coff. */
|
||||
|
||||
#include "i386/svr3dbx.h"
|
||||
|
||||
/* But with a few changes. */
|
||||
#undef ENDFILE_SPEC
|
||||
#include "i386/isc.h"
|
||||
|
||||
/* Overridden defines for ifile usage. */
|
||||
|
||||
#undef STARTFILE_SPEC
|
||||
#define STARTFILE_SPEC \
|
||||
"%{!r:%{!z:svr3.ifile%s}%{z:svr3z.ifile%s}}\
|
||||
%{!shlib:%{posix:%{pg:mcrtp1.o%s}%{!pg:%{p:mcrtp1.o%s}%{!p:crtp1.o%s}}}\
|
||||
%{Xp:%{pg:mcrtp1.o%s}%{!pg:%{p:mcrtp1.o%s}%{!p:crtp1.o%s}}}\
|
||||
%{!posix:%{!Xp:%{pg:mcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}}}\
|
||||
%{p:-L/usr/lib/libp} %{pg:-L/usr/lib/libp}}\
|
||||
%{shlib:%{posix:crtp1.o%s}%{Xp:crtp1.o%s}%{!posix:%{!Xp:crt1.o%s}}}"
|
||||
|
||||
#undef ENDFILE_SPEC
|
||||
#define ENDFILE_SPEC "crtn.o%s"
|
|
@ -0,0 +1,76 @@
|
|||
/* Definitions for Intel 386 running Linux
|
||||
Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
|
||||
Contributed by H.J. Lu (hjl@nynexst.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. */
|
||||
|
||||
/* This is tested by i386/gas.h. */
|
||||
#define YES_UNDERSCORES
|
||||
|
||||
#include <i386/gstabs.h>
|
||||
#include <linux-aout.h> /* some common stuff */
|
||||
|
||||
/* Specify predefined symbols in preprocessor. */
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-Dunix -Di386 -Dlinux -Asystem(unix) -Asystem(posix) -Acpu(i386) -Amachine(i386)"
|
||||
|
||||
#undef CPP_SPEC
|
||||
#if TARGET_CPU_DEFAULT == 2
|
||||
#define CPP_SPEC "%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{!m386:-D__i486__} %{posix:-D_POSIX_SOURCE}"
|
||||
#else
|
||||
#define CPP_SPEC "%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{m486:-D__i486__} %{posix:-D_POSIX_SOURCE}"
|
||||
#endif
|
||||
|
||||
#undef SIZE_TYPE
|
||||
#define SIZE_TYPE "unsigned int"
|
||||
|
||||
#undef PTRDIFF_TYPE
|
||||
#define PTRDIFF_TYPE "int"
|
||||
|
||||
#undef WCHAR_TYPE
|
||||
#define WCHAR_TYPE "long int"
|
||||
|
||||
#undef WCHAR_TYPE_SIZE
|
||||
#define WCHAR_TYPE_SIZE BITS_PER_WORD
|
||||
|
||||
/* Don't default to pcc-struct-return, because gcc is the only compiler,
|
||||
and we want to retain compatibility with older gcc versions. */
|
||||
#define DEFAULT_PCC_STRUCT_RETURN 0
|
||||
|
||||
#undef LIB_SPEC
|
||||
|
||||
#if 1
|
||||
/* We no longer link with libc_p.a or libg.a by default. If you
|
||||
* want to profile or debug the Linux C library, please add
|
||||
* -lc_p or -ggdb to LDFLAGS at the link time, respectively.
|
||||
*/
|
||||
#define LIB_SPEC \
|
||||
"%{mieee-fp:-lieee} %{p:-lgmon} %{pg:-lgmon} %{!ggdb:-lc} %{ggdb:-lg}"
|
||||
#else
|
||||
#define LIB_SPEC \
|
||||
"%{mieee-fp:-lieee} %{p:-lgmon -lc_p} %{pg:-lgmon -lc_p} \
|
||||
%{!p:%{!pg:%{!g*:-lc} %{g*:-lg -static}}}"
|
||||
#endif
|
||||
|
||||
|
||||
#undef LINK_SPEC
|
||||
#define LINK_SPEC "-m i386linux"
|
||||
|
||||
/* Get perform_* macros to build libgcc.a. */
|
||||
#include "i386/perform.h"
|
|
@ -0,0 +1,76 @@
|
|||
/* Definitions for Intel 386 running Linux with pre-BFD a.out linkers
|
||||
Copyright (C) 1995 Free Software Foundation, Inc.
|
||||
Contributed by Michael Meissner (meissner@cygnus.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. */
|
||||
|
||||
/* This is tested by i386/gas.h. */
|
||||
#define YES_UNDERSCORES
|
||||
|
||||
#include <i386/gstabs.h>
|
||||
#include <linux-aout.h> /* some common stuff */
|
||||
|
||||
/* Specify predefined symbols in preprocessor. */
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-Dunix -Di386 -Dlinux -Asystem(unix) -Asystem(posix) -Acpu(i386) -Amachine(i386)"
|
||||
|
||||
#undef CPP_SPEC
|
||||
#if TARGET_CPU_DEFAULT == 2
|
||||
#define CPP_SPEC "%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{!m386:-D__i486__} %{posix:-D_POSIX_SOURCE}"
|
||||
#else
|
||||
#define CPP_SPEC "%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{m486:-D__i486__} %{posix:-D_POSIX_SOURCE}"
|
||||
#endif
|
||||
|
||||
#undef SIZE_TYPE
|
||||
#define SIZE_TYPE "unsigned int"
|
||||
|
||||
#undef PTRDIFF_TYPE
|
||||
#define PTRDIFF_TYPE "int"
|
||||
|
||||
#undef WCHAR_TYPE
|
||||
#define WCHAR_TYPE "long int"
|
||||
|
||||
#undef WCHAR_TYPE_SIZE
|
||||
#define WCHAR_TYPE_SIZE BITS_PER_WORD
|
||||
|
||||
/* Don't default to pcc-struct-return, because gcc is the only compiler,
|
||||
and we want to retain compatibility with older gcc versions. */
|
||||
#define DEFAULT_PCC_STRUCT_RETURN 0
|
||||
|
||||
#undef LIB_SPEC
|
||||
|
||||
#if 1
|
||||
/* We no longer link with libc_p.a or libg.a by default. If you
|
||||
* want to profile or debug the Linux C library, please add
|
||||
* -lc_p or -ggdb to LDFLAGS at the link time, respectively.
|
||||
*/
|
||||
#define LIB_SPEC \
|
||||
"%{mieee-fp:-lieee} %{p:-lgmon} %{pg:-lgmon} %{!ggdb:-lc} %{ggdb:-lg}"
|
||||
#else
|
||||
#define LIB_SPEC \
|
||||
"%{mieee-fp:-lieee} %{p:-lgmon -lc_p} %{pg:-lgmon -lc_p} \
|
||||
%{!p:%{!pg:%{!g*:-lc} %{g*:-lg -static}}}"
|
||||
#endif
|
||||
|
||||
|
||||
#undef LINK_SPEC
|
||||
#define LINK_SPEC ""
|
||||
|
||||
/* Get perform_* macros to build libgcc.a. */
|
||||
#include <i386/perform.h>
|
|
@ -0,0 +1,212 @@
|
|||
/* Definitions for Intel 386 running Linux with ELF format
|
||||
Copyright (C) 1994, 1995 Free Software Foundation, Inc.
|
||||
Contributed by Eric Youngdale.
|
||||
Modified for stabs-in-ELF by H.J. Lu.
|
||||
|
||||
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 LINUX_DEFAULT_ELF
|
||||
|
||||
/* A lie, I guess, but the general idea behind linux/ELF is that we are
|
||||
supposed to be outputting something that will assemble under SVr4.
|
||||
This gets us pretty close. */
|
||||
#include <i386/i386.h> /* Base i386 target machine definitions */
|
||||
#include <i386/att.h> /* Use the i386 AT&T assembler syntax */
|
||||
#include <linux.h> /* some common stuff */
|
||||
|
||||
#undef TARGET_VERSION
|
||||
#define TARGET_VERSION fprintf (stderr, " (i386 Linux/ELF)");
|
||||
|
||||
/* The svr4 ABI for the i386 says that records and unions are returned
|
||||
in memory. */
|
||||
#undef DEFAULT_PCC_STRUCT_RETURN
|
||||
#define DEFAULT_PCC_STRUCT_RETURN 1
|
||||
|
||||
/* This is how to output an element of a case-vector that is relative.
|
||||
This is only used for PIC code. See comments by the `casesi' insn in
|
||||
i386.md for an explanation of the expression this outputs. */
|
||||
#undef ASM_OUTPUT_ADDR_DIFF_ELT
|
||||
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \
|
||||
fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, VALUE)
|
||||
|
||||
/* Indicate that jump tables go in the text section. This is
|
||||
necessary when compiling PIC code. */
|
||||
#define JUMP_TABLES_IN_TEXT_SECTION
|
||||
|
||||
/* Copy this from the svr4 specifications... */
|
||||
/* Define the register numbers to be used in Dwarf debugging information.
|
||||
The SVR4 reference port C compiler uses the following register numbers
|
||||
in its Dwarf output code:
|
||||
0 for %eax (gnu regno = 0)
|
||||
1 for %ecx (gnu regno = 2)
|
||||
2 for %edx (gnu regno = 1)
|
||||
3 for %ebx (gnu regno = 3)
|
||||
4 for %esp (gnu regno = 7)
|
||||
5 for %ebp (gnu regno = 6)
|
||||
6 for %esi (gnu regno = 4)
|
||||
7 for %edi (gnu regno = 5)
|
||||
The following three DWARF register numbers are never generated by
|
||||
the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4
|
||||
believes these numbers have these meanings.
|
||||
8 for %eip (no gnu equivalent)
|
||||
9 for %eflags (no gnu equivalent)
|
||||
10 for %trapno (no gnu equivalent)
|
||||
It is not at all clear how we should number the FP stack registers
|
||||
for the x86 architecture. If the version of SDB on x86/svr4 were
|
||||
a bit less brain dead with respect to floating-point then we would
|
||||
have a precedent to follow with respect to DWARF register numbers
|
||||
for x86 FP registers, but the SDB on x86/svr4 is so completely
|
||||
broken with respect to FP registers that it is hardly worth thinking
|
||||
of it as something to strive for compatibility with.
|
||||
The version of x86/svr4 SDB I have at the moment does (partially)
|
||||
seem to believe that DWARF register number 11 is associated with
|
||||
the x86 register %st(0), but that's about all. Higher DWARF
|
||||
register numbers don't seem to be associated with anything in
|
||||
particular, and even for DWARF regno 11, SDB only seems to under-
|
||||
stand that it should say that a variable lives in %st(0) (when
|
||||
asked via an `=' command) if we said it was in DWARF regno 11,
|
||||
but SDB still prints garbage when asked for the value of the
|
||||
variable in question (via a `/' command).
|
||||
(Also note that the labels SDB prints for various FP stack regs
|
||||
when doing an `x' command are all wrong.)
|
||||
Note that these problems generally don't affect the native SVR4
|
||||
C compiler because it doesn't allow the use of -O with -g and
|
||||
because when it is *not* optimizing, it allocates a memory
|
||||
location for each floating-point variable, and the memory
|
||||
location is what gets described in the DWARF AT_location
|
||||
attribute for the variable in question.
|
||||
Regardless of the severe mental illness of the x86/svr4 SDB, we
|
||||
do something sensible here and we use the following DWARF
|
||||
register numbers. Note that these are all stack-top-relative
|
||||
numbers.
|
||||
11 for %st(0) (gnu regno = 8)
|
||||
12 for %st(1) (gnu regno = 9)
|
||||
13 for %st(2) (gnu regno = 10)
|
||||
14 for %st(3) (gnu regno = 11)
|
||||
15 for %st(4) (gnu regno = 12)
|
||||
16 for %st(5) (gnu regno = 13)
|
||||
17 for %st(6) (gnu regno = 14)
|
||||
18 for %st(7) (gnu regno = 15)
|
||||
*/
|
||||
#undef DBX_REGISTER_NUMBER
|
||||
#define DBX_REGISTER_NUMBER(n) \
|
||||
((n) == 0 ? 0 \
|
||||
: (n) == 1 ? 2 \
|
||||
: (n) == 2 ? 1 \
|
||||
: (n) == 3 ? 3 \
|
||||
: (n) == 4 ? 6 \
|
||||
: (n) == 5 ? 7 \
|
||||
: (n) == 6 ? 5 \
|
||||
: (n) == 7 ? 4 \
|
||||
: ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) ? (n)+3 \
|
||||
: (-1))
|
||||
|
||||
/* Output assembler code to FILE to increment profiler label # LABELNO
|
||||
for profiling a function entry. */
|
||||
|
||||
#undef FUNCTION_PROFILER
|
||||
#define FUNCTION_PROFILER(FILE, LABELNO) \
|
||||
{ \
|
||||
if (flag_pic) \
|
||||
{ \
|
||||
fprintf (FILE, "\tleal %sP%d@GOTOFF(%%ebx),%%edx\n", \
|
||||
LPREFIX, (LABELNO)); \
|
||||
fprintf (FILE, "\tcall *mcount@GOT(%%ebx)\n"); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
fprintf (FILE, "\tmovl $%sP%d,%%edx\n", LPREFIX, (LABELNO)); \
|
||||
fprintf (FILE, "\tcall mcount\n"); \
|
||||
} \
|
||||
}
|
||||
|
||||
#undef SIZE_TYPE
|
||||
#define SIZE_TYPE "unsigned int"
|
||||
|
||||
#undef PTRDIFF_TYPE
|
||||
#define PTRDIFF_TYPE "int"
|
||||
|
||||
#undef WCHAR_TYPE
|
||||
#define WCHAR_TYPE "long int"
|
||||
|
||||
#undef WCHAR_TYPE_SIZE
|
||||
#define WCHAR_TYPE_SIZE BITS_PER_WORD
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-D__ELF__ -Dunix -Di386 -Dlinux -Asystem(unix) -Asystem(posix) -Acpu(i386) -Amachine(i386)"
|
||||
|
||||
#undef CPP_SPEC
|
||||
#if TARGET_CPU_DEFAULT == 2
|
||||
#define CPP_SPEC "%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{!m386:-D__i486__} %{posix:-D_POSIX_SOURCE}"
|
||||
#else
|
||||
#define CPP_SPEC "%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{m486:-D__i486__} %{posix:-D_POSIX_SOURCE}"
|
||||
#endif
|
||||
|
||||
#undef LIB_SPEC
|
||||
#if 1
|
||||
/* We no longer link with libc_p.a or libg.a by default. If you
|
||||
* want to profile or debug the Linux C library, please add
|
||||
* -lc_p or -ggdb to LDFLAGS at the link time, respectively.
|
||||
*/
|
||||
#define LIB_SPEC \
|
||||
"%{!shared: %{mieee-fp:-lieee} %{p:-lgmon} %{pg:-lgmon} \
|
||||
%{!ggdb:-lc} %{ggdb:-lg}}"
|
||||
#else
|
||||
#define LIB_SPEC \
|
||||
"%{!shared: \
|
||||
%{mieee-fp:-lieee} %{p:-lgmon -lc_p} %{pg:-lgmon -lc_p} \
|
||||
%{!p:%{!pg:%{!g*:-lc} %{g*:-lg}}}}"
|
||||
#endif
|
||||
|
||||
/* Provide a LINK_SPEC appropriate for Linux. Here we provide support
|
||||
for the special GCC options -static and -shared, which allow us to
|
||||
link things in one of these three modes by applying the appropriate
|
||||
combinations of options at link-time. We like to support here for
|
||||
as many of the other GNU linker options as possible. But I don't
|
||||
have the time to search for those flags. I am sure how to add
|
||||
support for -soname shared_object_name. H.J.
|
||||
|
||||
I took out %{v:%{!V:-V}}. It is too much :-(. They can use
|
||||
-Wl,-V.
|
||||
|
||||
When the -shared link option is used a final link is not being
|
||||
done. */
|
||||
|
||||
/* If ELF is the default format, we should not use /lib/elf. */
|
||||
|
||||
#undef LINK_SPEC
|
||||
#ifndef LINUX_DEFAULT_ELF
|
||||
#define LINK_SPEC "-m elf_i386 %{shared:-shared} \
|
||||
%{!shared: \
|
||||
%{!ibcs: \
|
||||
%{!static: \
|
||||
%{rdynamic:-export-dynamic} \
|
||||
%{!dynamic-linker:-dynamic-linker /lib/elf/ld-linux.so.1} \
|
||||
%{!rpath:-rpath /lib/elf/}} %{static:-static}}}"
|
||||
#else
|
||||
#define LINK_SPEC "-m elf_i386 %{shared:-shared} \
|
||||
%{!shared: \
|
||||
%{!ibcs: \
|
||||
%{!static: \
|
||||
%{rdynamic:-export-dynamic} \
|
||||
%{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.1}} \
|
||||
%{static:-static}}}"
|
||||
#endif
|
||||
|
||||
/* Get perform_* macros to build libgcc.a. */
|
||||
#include "i386/perform.h"
|
|
@ -0,0 +1,37 @@
|
|||
/* Definitions for Intel 386 running LynxOS, using Lynx's old as and ld.
|
||||
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 <i386/gstabs.h>
|
||||
#include <lynx-ng.h>
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-Dunix -Di386 -DI386 -DLynx -DIBITS32 -Asystem(unix) -Asystem(lynx) -Acpu(i386) -Amachine(i386)"
|
||||
|
||||
/* Provide required defaults for linker switches. */
|
||||
|
||||
#undef LINK_SPEC
|
||||
#define LINK_SPEC "-P1000 %{msystem-v:-V} %{mcoff:-k}"
|
||||
|
||||
/* Apparently LynxOS clobbers ebx when you call into the OS. */
|
||||
|
||||
#undef CALL_USED_REGISTERS
|
||||
#define CALL_USED_REGISTERS \
|
||||
/*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg*/ \
|
||||
{ 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
|
|
@ -0,0 +1,39 @@
|
|||
/* Definitions for Intel 386 running LynxOS.
|
||||
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 <i386/gstabs.h>
|
||||
#include <lynx.h>
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-Dunix -Di386 -DI386 -DLynx -DIBITS32 -Asystem(unix) -Asystem(lynx) -Acpu(i386) -Amachine(i386)"
|
||||
|
||||
/* This is how to output a reference to a user-level label named NAME. */
|
||||
|
||||
/* Override the svr3 convention of adding a leading underscore. */
|
||||
|
||||
#undef ASM_OUTPUT_LABELREF
|
||||
#define ASM_OUTPUT_LABELREF(FILE,NAME) fprintf (FILE, "%s", NAME)
|
||||
|
||||
/* Apparently LynxOS clobbers ebx when you call into the OS. */
|
||||
|
||||
#undef CALL_USED_REGISTERS
|
||||
#define CALL_USED_REGISTERS \
|
||||
/*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg*/ \
|
||||
{ 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
|
|
@ -0,0 +1,20 @@
|
|||
/* Configuration for an i386 running Mach as the target machine. */
|
||||
|
||||
/* We do want to add an underscore to the front of each user symbol.
|
||||
i386/gas.h checks this. */
|
||||
#define YES_UNDERSCORES
|
||||
|
||||
#include "i386/gstabs.h"
|
||||
|
||||
/* Get perform_* macros to build libgcc.a. */
|
||||
#include "i386/perform.h"
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-Dunix -Di386 -DMACH -Asystem(unix) -Asystem(mach) -Acpu(i386) -Amachine(i386)"
|
||||
|
||||
/* Specify extra dir to search for include files. */
|
||||
#define SYSTEM_INCLUDE_DIR "/usr/mach/include"
|
||||
|
||||
/* Don't default to pcc-struct-return, because gcc is the only compiler, and
|
||||
we want to retain compatibility with older gcc versions. */
|
||||
#define DEFAULT_PCC_STRUCT_RETURN 0
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue