This commit was generated by cvs2svn to track changes on a CVS vendor
branch.
This commit is contained in:
commit
57b71b5058
|
@ -0,0 +1,249 @@
|
|||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 1, February 1989
|
||||
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The license agreements of most software companies try to keep users
|
||||
at the mercy of those companies. By contrast, our 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. The
|
||||
General Public License applies to the Free Software Foundation's
|
||||
software and to any other program whose authors commit to using it.
|
||||
You can use it for your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Specifically, the General Public License is designed to make
|
||||
sure that you have the freedom to give away or sell copies of free
|
||||
software, 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 a 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 tell them 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.
|
||||
|
||||
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 Agreement 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 work containing the
|
||||
Program or a portion of it, either verbatim or with modifications. Each
|
||||
licensee is addressed as "you".
|
||||
|
||||
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
|
||||
General Public License and to the absence of any warranty; and give any
|
||||
other recipients of the Program a copy of this General Public License
|
||||
along with the Program. You may charge a fee for the physical act of
|
||||
transferring a copy.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion of
|
||||
it, and copy and distribute such modifications under the terms of Paragraph
|
||||
1 above, provided that you also do the following:
|
||||
|
||||
a) cause the modified files to carry prominent notices stating that
|
||||
you changed the files and the date of any change; and
|
||||
|
||||
b) cause the whole of any work that you distribute or publish, that
|
||||
in whole or in part contains the Program or any part thereof, either
|
||||
with or without modifications, to be licensed at no charge to all
|
||||
third parties under the terms of this General Public License (except
|
||||
that you may choose to grant warranty protection to some or all
|
||||
third parties, at your option).
|
||||
|
||||
c) If the modified program normally reads commands interactively when
|
||||
run, you must cause it, when started running for such interactive use
|
||||
in the simplest and most usual 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 General
|
||||
Public License.
|
||||
|
||||
d) 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.
|
||||
|
||||
Mere aggregation of another independent work with the Program (or its
|
||||
derivative) on a volume of a storage or distribution medium does not bring
|
||||
the other work under the scope of these terms.
|
||||
|
||||
3. You may copy and distribute the Program (or a portion or derivative of
|
||||
it, under Paragraph 2) in object code or executable form under the terms of
|
||||
Paragraphs 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
|
||||
Paragraphs 1 and 2 above; or,
|
||||
|
||||
b) accompany it with a written offer, valid for at least three
|
||||
years, to give any third party free (except for a nominal charge
|
||||
for the cost of distribution) a complete machine-readable copy of the
|
||||
corresponding source code, to be distributed under the terms of
|
||||
Paragraphs 1 and 2 above; or,
|
||||
|
||||
c) accompany it with the information you received as to where the
|
||||
corresponding source code may be obtained. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form alone.)
|
||||
|
||||
Source code for a work means the preferred form of the work for making
|
||||
modifications to it. For an executable file, complete source code means
|
||||
all the source code for all modules it contains; but, as a special
|
||||
exception, it need not include source code for modules which are standard
|
||||
libraries that accompany the operating system on which the executable
|
||||
file runs, or for standard header files or definitions files that
|
||||
accompany that operating system.
|
||||
|
||||
4. You may not copy, modify, sublicense, distribute or transfer the
|
||||
Program except as expressly provided under this General Public License.
|
||||
Any attempt otherwise to copy, modify, sublicense, distribute or transfer
|
||||
the Program is void, and will automatically terminate your rights to use
|
||||
the Program under this License. However, parties who have received
|
||||
copies, or rights to use copies, from you under this General Public
|
||||
License will not have their licenses terminated so long as such parties
|
||||
remain in full compliance.
|
||||
|
||||
5. By copying, distributing or modifying 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.
|
||||
|
||||
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.
|
||||
|
||||
7. 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 the 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
|
||||
the license, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
8. 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
|
||||
|
||||
9. 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.
|
||||
|
||||
10. 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 humanity, 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 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
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) 19xx 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 a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
program `Gnomovision' (a program to direct compilers to make passes
|
||||
at assemblers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,888 @@
|
|||
This is a copy of one node from the Info file gcc.info-3.
|
||||
For full information on installing and porting GCC, refer to the
|
||||
GCC manual:
|
||||
|
||||
Info file gcc.info
|
||||
TeX output gcc.dvi
|
||||
TeX source gcc.texinfo
|
||||
|
||||
Installing GNU CC
|
||||
*****************
|
||||
|
||||
Here is the procedure for installing GNU CC on a Unix system.
|
||||
|
||||
* Menu:
|
||||
|
||||
* Other Dir:: Compiling in a separate directory (not where the source is).
|
||||
* Sun Install:: See below for installation on the Sun.
|
||||
* 3B1 Install:: See below for installation on the 3B1.
|
||||
* SCO Install:: See below for installation on SCO System V 3.2. (Or ESIX.)
|
||||
* VMS Install:: See below for installation on VMS.
|
||||
* HPUX Install:: See below for installation on HPUX.
|
||||
* Tower Install:: See below for installation on an NCR Tower.
|
||||
|
||||
1. Edit `Makefile'. If you are using HPUX, or any form of system V,
|
||||
you must make a few changes described in comments at the beginning
|
||||
of the file. Genix requires changes also, and so does the Pyramid.
|
||||
|
||||
2. On a Sequent system, go to the Berkeley universe.
|
||||
|
||||
3. Choose configuration files. The easy way to do this is to run the
|
||||
command file `config.gcc' with a single argument, which specifies
|
||||
the type of machine (and in some cases which operating system).
|
||||
|
||||
Here is a list of the possible arguments:
|
||||
|
||||
`vax'
|
||||
Vaxes running BSD.
|
||||
|
||||
`vms'
|
||||
Vaxes running VMS.
|
||||
|
||||
`vax-sysv'
|
||||
Vaxes running system V.
|
||||
|
||||
`i386-sysv'
|
||||
Intel 386 PCs running system V.
|
||||
|
||||
`i386-sysv-gas'
|
||||
Intel 386 PCs running system V, using the GNU assembler and
|
||||
GNU linker.
|
||||
|
||||
`i386-sysv4'
|
||||
Intel 386 PCs running system V.4. You must run the shell
|
||||
script `fixincludes-V4' in order for GNU CC to work properly.
|
||||
You must also uncomment some lines in `Makefile'.
|
||||
|
||||
`sequent-i386'
|
||||
Sequent with Intel 386 processors.
|
||||
|
||||
`i386-aix'
|
||||
Intel 386 PCs or PS/2s running AIX.
|
||||
|
||||
`sun2'
|
||||
Sun 2 running system version 2 or 3.
|
||||
|
||||
`sun3'
|
||||
Sun 3 running system version 4, with 68881. Note there we do
|
||||
not provide a configuration file to use an FPA by default,
|
||||
because programs that establish signal handlers for floating
|
||||
point traps inherently cannot work with the FPA.
|
||||
|
||||
`sun3-nfp'
|
||||
Sun 3 running system version 4, without 68881.
|
||||
|
||||
`sun4'
|
||||
Sun 4 running system version 4. *Note Incompatibilities::,
|
||||
for calling convention incompatibilities on the Sun 4 (sparc).
|
||||
|
||||
`sun2-os4'
|
||||
Sun 2 running system version 4.
|
||||
|
||||
`sun3-os3'
|
||||
Sun 3 running system version 2 or 3, with 68881.
|
||||
|
||||
`sun3-nfp-os3'
|
||||
Sun 3 running system version 2 or 3, without 68881.
|
||||
|
||||
`sun4-os3'
|
||||
Sun 4 running system version 2 or 3. *Note
|
||||
Incompatibilities::, for calling convention incompatibilities
|
||||
on the Sun 4 (sparc).
|
||||
|
||||
`sun386'
|
||||
Sun 386 ("roadrunner").
|
||||
|
||||
`alliant'
|
||||
Alliant FX/8 computer. Note that the standard installed C
|
||||
compiler in Concentrix 5.0 has a bug which prevent it from
|
||||
compiling GNU CC correctly. You can patch the compiler bug
|
||||
as follows:
|
||||
|
||||
cp /bin/pcc ./pcc
|
||||
adb -w ./pcc - << EOF
|
||||
15f6?w 6610
|
||||
EOF
|
||||
|
||||
Then you must use the `-ip12' option when compiling GNU CC
|
||||
with the patched compiler, as shown here:
|
||||
|
||||
make CC="./pcc -ip12" CFLAGS=-w
|
||||
|
||||
Note also that Alliant's version of DBX does not manage to
|
||||
work with the output from GNU CC.
|
||||
|
||||
`tahoe'
|
||||
The tahoe computer (running BSD, and using DBX).
|
||||
|
||||
`decstation'
|
||||
The DEC 3100 Mips machine ("pmax"). Note that GNU CC cannot
|
||||
generate debugging information in the unusual format used on
|
||||
the Mips.
|
||||
|
||||
`mips-sysv-os5'
|
||||
The Mips computer, RS series, with the System V environment
|
||||
running on revision 5.00 of RISC-OS as default. Note that GNU
|
||||
CC cannot generate debugging information in the unusual
|
||||
format used on the Mips, and also cannot be used to create
|
||||
programs that use shared libraries.
|
||||
|
||||
`mips-sysv'
|
||||
The Mips computer, RS series, with the System V environment
|
||||
as default. Note that GNU CC cannot generate debugging
|
||||
information in the unusual format used on the Mips.
|
||||
|
||||
`mips-bsd43-os5'
|
||||
The Mips computer, RS series, with the BSD 4.3 environment
|
||||
running revision 5.00 of RISC-OS as default. Note that GNU CC
|
||||
cannot generate debugging information in the unusual format
|
||||
used on the Mips, and also cannot be used to create programs
|
||||
that use shared libraries.
|
||||
|
||||
`mips-bsd43'
|
||||
The Mips computer, RS series, with the BSD 4.3 environment as
|
||||
default. Note that GNU CC cannot generate debugging
|
||||
information in the unusual format used on the Mips.
|
||||
|
||||
`mips-os5'
|
||||
The Mips computer, M series running revision 5.00 of RISC-OS.
|
||||
Note that GNU CC cannot generate debugging information in the
|
||||
unusual format used on the Mips, and also cannot be used to
|
||||
create programs that use shared libraries.
|
||||
|
||||
`mips'
|
||||
The Mips computer, M series. Note that GNU CC cannot
|
||||
generate debugging information in the unusual format used on
|
||||
the Mips.
|
||||
|
||||
`iris'
|
||||
Another variant of the Mips computer, the Silicon Graphics
|
||||
Iris 4D. Note that GNU CC cannot generate debugging
|
||||
information in the unusual format used on the Mips.
|
||||
|
||||
`convex-c1'
|
||||
Convex C1 computer. With operating system version 9, use `cc
|
||||
-pcc' as the compilation command when building stage 1 of GNU
|
||||
CC.
|
||||
|
||||
`convex-c2'
|
||||
Convex C2 computer. With operating system version 9, use `cc
|
||||
-pcc' as the compilation command when building stage 1 of GNU
|
||||
CC.
|
||||
|
||||
`pyramid'
|
||||
Pyramid computer.
|
||||
|
||||
`hp9k320'
|
||||
HP 9000 series 300 using HPUX assembler. Note there is no
|
||||
support in GNU CC for HP's debugger; thus, `-g' is not
|
||||
available in this configuration.
|
||||
|
||||
`hp9k320-gas'
|
||||
HP 9000 series 300 using GNU assembler, linker and debugger.
|
||||
This requires the HP-adapt package, which is available along
|
||||
with the GNU linker as part of the "binutils" distribution.
|
||||
This is on the GNU CC distribution tape.
|
||||
|
||||
`hp9k320-old'
|
||||
HP 9000 series 300 using HPUX assembler, in operating system
|
||||
versions older than 6.5. Note there is no support in GNU CC
|
||||
for HP's debugger; thus, `-g' is not available in this
|
||||
configuration.
|
||||
|
||||
`hp9k320-bsd'
|
||||
HP 9000 series 300 running BSD.
|
||||
|
||||
`hp9k200-bsd'
|
||||
HP 9000 series 200 running BSD. Note that the C compiler
|
||||
that comes with this system cannot compile GNU CC; contact
|
||||
`law@super.org' to get binaries of GNU CC for bootstrapping.
|
||||
Additionally, a minor patch is necessary if you wish to build
|
||||
kernels with GNU CC; contact `law@super.org' to get a copy of
|
||||
the patch.
|
||||
|
||||
`isi68'
|
||||
ISI 68000 or 68020 system with a 68881.
|
||||
|
||||
`isi68-nfp'
|
||||
ISI 68000 or 68020 system without a 68881.
|
||||
|
||||
`news800'
|
||||
Sony NEWS 68020 system.
|
||||
|
||||
`next'
|
||||
NeXT system.
|
||||
|
||||
`tower'
|
||||
NCR Tower 32 system.
|
||||
|
||||
`altos'
|
||||
Altos 3068. Note that you must use the GNU assembler, linker
|
||||
and debugger, with COFF-encapsulation. Also, you must fix a
|
||||
kernel bug. Details in the file `ALTOS-README'.
|
||||
|
||||
`3b1'
|
||||
AT&T 3b1, a.k.a. 7300 PC. Note that special procedures are
|
||||
needed to compile GNU CC with this machine's standard C
|
||||
compiler, due to bugs in that compiler. *Note 3b1 Install::.
|
||||
You can bootstrap it more easily with previous versions of
|
||||
GNU CC if you have them.
|
||||
|
||||
`3b1-gas'
|
||||
AT&T 3b1 using the GNU assembler.
|
||||
|
||||
`sequent-ns32k'
|
||||
Sequent containing ns32000 processors.
|
||||
|
||||
`encore'
|
||||
Encore ns32000 system.
|
||||
|
||||
`genix'
|
||||
National Semiconductor ns32000 system.
|
||||
|
||||
`88000'
|
||||
Motorola 88000 processor. This port is not finished.
|
||||
|
||||
Here we spell out what files need to be set up:
|
||||
|
||||
* Make a symbolic link named `config.h' to the top-level config
|
||||
file for the machine you are using (*note Config::.). This
|
||||
file is responsible for defining information about the host
|
||||
machine. It includes `tm.h'.
|
||||
|
||||
The file is located in the subdirectory `config'. Its name
|
||||
should be `xm-MACHINE.h', with these exceptions:
|
||||
|
||||
`xm-vms.h'
|
||||
for vaxen running VMS.
|
||||
|
||||
`xm-vaxv.h'
|
||||
for vaxen running system V.
|
||||
|
||||
`xm-i386v.h'
|
||||
for Intel 80386's running system V.
|
||||
|
||||
`xm-sun386i.h'
|
||||
for Sun roadrunner running any version of the operating
|
||||
system.
|
||||
|
||||
`xm-hp9k320.h'
|
||||
for the HP 9000 series 300.
|
||||
|
||||
`xm-genix.h'
|
||||
for the ns32000 running Genix
|
||||
|
||||
If your system does not support symbolic links, you might
|
||||
want to set up `config.h' to contain a `#include' command
|
||||
which refers to the appropriate file.
|
||||
|
||||
* Make a symbolic link named `tm.h' to the machine-description
|
||||
macro file for your machine. It should be in the subdirectory
|
||||
`config' and its name should be `tm-MACHINE.h'.
|
||||
|
||||
If your system is a 68000, don't use the file `tm-m68k.h'
|
||||
directly. Instead, use one of these files:
|
||||
|
||||
`tm-sun3.h'
|
||||
for Sun 3 machines with 68881.
|
||||
|
||||
`tm-sun3-nfp.h'
|
||||
for Sun 3 machines with no hardware floating point.
|
||||
|
||||
`tm-sun3os3.h'
|
||||
for Sun 3 machines with 68881, running Sunos version 3.
|
||||
|
||||
`tm-sun3os3nf.h'
|
||||
for Sun 3 machines with no hardware floating point,
|
||||
running Sunos version 3.
|
||||
|
||||
`tm-sun2.h'
|
||||
for Sun 2 machines.
|
||||
|
||||
`tm-3b1.h'
|
||||
for AT&T 3b1 (aka 7300 Unix PC).
|
||||
|
||||
`tm-isi68.h'
|
||||
for Integrated Solutions systems. This file assumes you
|
||||
use the GNU assembler.
|
||||
|
||||
`tm-isi68-nfp.h'
|
||||
for Integrated Solutions systems without a 68881. This
|
||||
file assumes you use the GNU assembler.
|
||||
|
||||
`tm-news800.h'
|
||||
for Sony NEWS systems.
|
||||
|
||||
`tm-hp9k320.h'
|
||||
for HPUX systems, if you are using GNU CC with the
|
||||
system's assembler and linker.
|
||||
|
||||
`tm-hp9k320g.h'
|
||||
for HPUX systems, if you are using the GNU assembler,
|
||||
linker and other utilities. Not all of the pieces of
|
||||
GNU software needed for this mode of operation are as
|
||||
yet in distribution; full instructions will appear here
|
||||
in the future.
|
||||
|
||||
`tm-tower-as.h'
|
||||
for NCR Tower 32 systems, using the standard system
|
||||
assembler.
|
||||
|
||||
For the vax, use `tm-vax.h' on BSD Unix, `tm-vaxv.h' on
|
||||
system V, or `tm-vms.h' on VMS.
|
||||
|
||||
For the Motorola 88000, use `tm-m88k.h'. The support for the
|
||||
88000 does not currently work; it requires extensive changes
|
||||
which we hope to reconcile in version 2.
|
||||
|
||||
For the 80386, don't use `tm-i386.h' directly. Use
|
||||
`tm-i386v.h' if the target machine is running system V,
|
||||
`tm-i386gas.h' if it is running system V but you are using the
|
||||
GNU assembler and linker, `tm-seq386.h' for a Sequent 386
|
||||
system, or `tm-compaq.h' for a Compaq, or `tm-sun386i.h' for
|
||||
a Sun 386 system.
|
||||
|
||||
For the Mips computer, there are five choices: `tm-mips.h'
|
||||
for the M series, `tm-mips-bsd.h' for the RS series with BSD,
|
||||
`tm-mips-sysv.h' for the RS series with System V, `tm-iris.h'
|
||||
for the Iris version of the machine, and `tm-decstatn.h' for
|
||||
the Decstation.
|
||||
|
||||
For the 32000, use `tm-sequent.h' if you are using a Sequent
|
||||
machine, or `tm-encore.h' for an Encore machine, or
|
||||
`tm-genix.h' if you are using Genix version 3; otherwise,
|
||||
perhaps `tm-ns32k.h' will work for you.
|
||||
|
||||
Note that Genix has bugs in `alloca' and `malloc'; you must
|
||||
get the compiled versions of these from GNU Emacs and edit
|
||||
GNU CC's `Makefile' to use them.
|
||||
|
||||
Note that Encore systems are supported only under BSD.
|
||||
|
||||
For Sparc (Sun 4) machines, use `tm-sparc.h' with operating
|
||||
system version 4, and `tm-sun4os3.h' with system version 3.
|
||||
|
||||
For Convex systems before version 8.1, use `tm-conv1os7.h' or
|
||||
`tm-conv2os7.h'. For versions 8.1 and greater, use
|
||||
`tm-convex1.h' or `tm-convex2.h'. You should also bootstrap
|
||||
GCC with `pcc' rather than `cc'; one way to do this is with
|
||||
the following commands.
|
||||
|
||||
ln -s /bin/pcc ./cc
|
||||
set path = (. $path)
|
||||
|
||||
* Make a symbolic link named `md' to the machine description
|
||||
pattern file. It should be in the `config' subdirectory and
|
||||
its name should be `MACHINE.md'; but MACHINE is often not the
|
||||
same as the name used in the `tm.h' file because the `md'
|
||||
files are more general.
|
||||
|
||||
* Make a symbolic link named `aux-output.c' to the output
|
||||
subroutine file for your machine. It should be in the
|
||||
`config' subdirectory and its name should be `out-MACHINE.c'.
|
||||
|
||||
4. Make sure the Bison parser generator is installed. (This is
|
||||
unnecessary if the Bison output files `c-parse.tab.c' and `cexp.c'
|
||||
are more recent than `c-parse.y' and `cexp.y' and you do not plan
|
||||
to change the `.y' files.)
|
||||
|
||||
Bison versions older than Sept 8, 1988 will produce incorrect
|
||||
output for `c-parse.tab.c'.
|
||||
|
||||
5. If you have a previous version of GCC installed, then chances are
|
||||
you can compile the new version with that. Do the following:
|
||||
|
||||
make CC="gcc -O"
|
||||
|
||||
Since this produces an optimized executable right away, there is
|
||||
no need to bootstrap the result with itself except to test it.
|
||||
Therefore, you can skip directly to the `make install' step below.
|
||||
|
||||
6. Build the compiler. Just type `make' in the compiler directory.
|
||||
|
||||
Ignore any warnings you may see about "statement not reached" in
|
||||
the `insn-emit.c'; they are normal. Any other compilation errors
|
||||
may represent bugs in the port to your machine or operating
|
||||
system, and should be investigated and reported (*note Bugs::.).
|
||||
|
||||
Some commercial compilers fail to compile GNU CC because they have
|
||||
bugs or limitations. For example, the Microsoft compiler is said
|
||||
to run out of macro space. Some Ultrix compilers run out of
|
||||
expression space; then you need to break up the statement where
|
||||
the problem happens.
|
||||
|
||||
7. If you are using COFF-encapsulation, you must convert `gnulib' to
|
||||
a GNU-format library at this point. See the file `README-ENCAP'
|
||||
in the directory containing the GNU binary file utilities, for
|
||||
directions.
|
||||
|
||||
8. Move the first-stage object files and executables into a
|
||||
subdirectory with this command:
|
||||
|
||||
make stage1
|
||||
|
||||
The files are moved into a subdirectory named `stage1'. Once
|
||||
installation is complete, you may wish to delete these files with
|
||||
`rm -r stage1'.
|
||||
|
||||
9. Recompile the compiler with itself, with this command:
|
||||
|
||||
make CC=stage1/gcc CFLAGS="-g -O -Bstage1/"
|
||||
|
||||
This is called making the stage 2 compiler.
|
||||
|
||||
On a 68000 or 68020 system lacking floating point hardware, unless
|
||||
you have selected a `tm.h' file that expects by default that there
|
||||
is no such hardware, do this instead:
|
||||
|
||||
make CC=stage1/gcc CFLAGS="-g -O -Bstage1/ -msoft-float"
|
||||
|
||||
10. If you wish to test the compiler by compiling it with itself one
|
||||
more time, do this (in C shell):
|
||||
|
||||
make stage2
|
||||
make CC=stage2/gcc CFLAGS="-g -O -Bstage2/"
|
||||
foreach file (*.o)
|
||||
cmp $file stage2/$file
|
||||
end
|
||||
|
||||
This is called making the stage 3 compiler. Aside from the `-B'
|
||||
option, the options should be the same as when you made the stage 2
|
||||
compiler.
|
||||
|
||||
The `foreach' command (written in C shell) will notify you if any
|
||||
of these stage 3 object files differs from those of stage 2. On
|
||||
BSD systems, any difference, no matter how innocuous, indicates
|
||||
that the stage 2 compiler has compiled GNU CC incorrectly, and is
|
||||
therefore a potentially serious bug which you should investigate
|
||||
and report (*note Bugs::.).
|
||||
|
||||
On systems that use COFF object files, bytes 5 to 8 will always be
|
||||
different, since it is a timestamp. On these systems, you can do
|
||||
the comparison as follows (in Bourne shell):
|
||||
|
||||
for file in *.o; do
|
||||
echo $file
|
||||
tail +10c $file > foo1
|
||||
tail +10c stage2/$file > foo2
|
||||
cmp foo1 foo2
|
||||
done
|
||||
|
||||
On MIPS machines, you should use the shell script `ecoff-cmp' to
|
||||
compare two object files.
|
||||
|
||||
11. Install the compiler driver, the compiler's passes and run-time
|
||||
support. You can use the following command:
|
||||
|
||||
make install
|
||||
|
||||
On some machines, you will find that starts to recompile the `.c'
|
||||
files, due to a bug in Make. If that happens, cancel it and try
|
||||
again specifying the same values for Make variables that you used
|
||||
in the last compilation; that may not prevent the spurious
|
||||
recompilation, but will at least do it properly. For example:
|
||||
|
||||
make CC=stage2/gcc CFLAGS="-g -O -Bstage2/" install
|
||||
|
||||
The `install' target copies the files `cc1', `cpp' and `gnulib' to
|
||||
files `gcc-cc1', `gcc-cpp' and `gcc-gnulib' in directory
|
||||
`/usr/local/lib', which is where the compiler driver program looks
|
||||
for them. It also copies the driver program `gcc' into the
|
||||
directory `/usr/local/bin', so that it appears in typical
|
||||
execution search paths.
|
||||
|
||||
*Warning: there is a bug in `alloca' in the Sun library. To avoid
|
||||
this bug, install the binaries of GNU CC that were compiled by GNU
|
||||
CC. They use `alloca' as a built-in function and never the one in
|
||||
the library.*
|
||||
|
||||
*Warning: the GNU CPP may not work for `ioctl.h', `ttychars.h' and
|
||||
other system header files unless the `-traditional' option is
|
||||
used.* The bug is in the header files: at least on some machines,
|
||||
they rely on behavior that is incompatible with ANSI C. This
|
||||
behavior consists of substituting for macro argument names when
|
||||
they appear inside of character constants. The `-traditional'
|
||||
option tells GNU CC to behave the way these headers expect.
|
||||
|
||||
Because of this problem, you might prefer to configure GNU CC to
|
||||
use the system's own C preprocessor. To do so, make the file
|
||||
`/usr/local/lib/gcc-cpp' a link to `/lib/cpp'.
|
||||
|
||||
Alternatively, on Sun systems and 4.3BSD at least, you can correct
|
||||
the include files by running the shell script `fixincludes'. This
|
||||
installs modified, corrected copies of the files `ioctl.h',
|
||||
`ttychars.h' and many others, in a special directory where only
|
||||
GNU CC will normally look for them. This script will work on
|
||||
various systems because it chooses the files by searching all the
|
||||
system headers for the problem cases that we know about.
|
||||
|
||||
Use the following command to do this:
|
||||
|
||||
make includes
|
||||
|
||||
If you selected a different directory for GNU CC installation when
|
||||
you installed it, by specifying the Make variable `prefix' or
|
||||
`libdir', specify it the same way in this command.
|
||||
|
||||
Note that some systems are starting to come with ANSI C system
|
||||
header files. On these systems, don't run `fixincludes'; it may
|
||||
not work, and is certainly not necessary.
|
||||
|
||||
*Warning:* `fixincludes' does not work on many MIPS systems,
|
||||
because those systems come with circular symbolic links which cause
|
||||
`ls -lR' to go into an infinite loop. The same problem may occur
|
||||
on some versions of SunOS. If you encounter this problem, try
|
||||
using `fixinc.new' instead opf `fixincludes'.
|
||||
|
||||
If you cannot install the compiler's passes and run-time support in
|
||||
`/usr/local/lib', you can alternatively use the `-B' option to specify
|
||||
a prefix by which they may be found. The compiler concatenates the
|
||||
prefix with the names `cpp', `cc1' and `gnulib'. Thus, you can put the
|
||||
files in a directory `/usr/foo/gcc' and specify `-B/usr/foo/gcc/' when
|
||||
you run GNU CC.
|
||||
|
||||
Also, you can specify an alternative default directory for these
|
||||
files by setting the Make variable `libdir' when you make GNU CC.
|
||||
|
||||
|
||||
File: gcc.info, Node: Other Dir, Next: Sun Install, Prev: Installation, Up: Installation
|
||||
|
||||
Compilation in a Separate Directory
|
||||
===================================
|
||||
|
||||
If you wish to build the object files and executables in a directory
|
||||
other than the one containing the source files, here is what you must
|
||||
do differently:
|
||||
|
||||
1. Go to that directory before running `config.gcc':
|
||||
|
||||
mkdir gcc-sun3
|
||||
cd gcc-sun3
|
||||
|
||||
On systems that do not support symbolic links, this directory must
|
||||
be on the same file system as the source code directory.
|
||||
|
||||
2. Specify where to find `config.gcc' when you run it:
|
||||
|
||||
../gcc-1.36/config.gcc ...
|
||||
|
||||
3. Specify where to find the sources, as an argument to `config.gcc':
|
||||
|
||||
../gcc-1.36/config.gcc -srcdir=../gcc-1.36 sun3
|
||||
|
||||
The `-srcdir=DIR' option is not needed when the source directory
|
||||
is the parent of the current directory, because `config.gcc'
|
||||
detects that case automatically.
|
||||
|
||||
Now, you can run `make' in that directory. You need not repeat the
|
||||
configuration steps shown above, when ordinary source files change. You
|
||||
must, however, run `config.gcc' again when the configuration files
|
||||
change, if your system does not support symbolic links.
|
||||
|
||||
|
||||
File: gcc.info, Node: Sun Install, Next: 3b1 Install, Prev: Other Dir, Up: Installation
|
||||
|
||||
Installing GNU CC on the Sun
|
||||
============================
|
||||
|
||||
Make sure the environment variable `FLOAT_OPTION' is not set when
|
||||
you compile `gnulib'. If this option were set to `f68881' when
|
||||
`gnulib' is compiled, the resulting code would demand to be linked with
|
||||
a special startup file and would not link properly without special
|
||||
pains.
|
||||
|
||||
There is a bug in `alloca' in certain versions of the Sun library.
|
||||
To avoid this bug, install the binaries of GNU CC that were compiled by
|
||||
GNU CC. They use `alloca' as a built-in function and never the one in
|
||||
the library.
|
||||
|
||||
Some versions of the Sun compiler crash when compiling GNU CC, with a
|
||||
segmentation fault in cpp. This can sometimes be due to the bulk of
|
||||
data in the environment variables. You may be able to avoid it by using
|
||||
the following command to compile GNU CC with Sun CC:
|
||||
|
||||
make CC="TERMCAP=x OBJS=x LIBFUNCS=x STAGESTUFF=x cc"
|
||||
|
||||
Another problem that often happens on Suns is that you get a crash
|
||||
when building stage 2, when `genflags' is run.
|
||||
|
||||
One reason for such as crash is if you configured GNU CC for the
|
||||
wrong version of SunOS. Starting with version 1.38, configurations
|
||||
`sun3' and `sun4' are for SunOS 4, so this problem should no longer
|
||||
happen.
|
||||
|
||||
Another cause of the same symptom is having installed the GNU linker
|
||||
with an earlier version of SunOS. The version that worked before
|
||||
stopped working due to a change in the format of executables in SunOS
|
||||
4.1. Many sites have installed the GNU linker as
|
||||
`/usr/local/lib/gcc-ld', often as part of installing GNU C++. So if
|
||||
you get such crashes and you have used the proper configuration, try
|
||||
deleting `/usr/local/lib/gcc-ld'.
|
||||
|
||||
The current version of the GNU linker, found in the current binutils
|
||||
release, does work with SunOS 4.1.
|
||||
|
||||
|
||||
File: gcc.info, Node: 3b1 Install, Next: SCO Install, Prev: Sun Install, Up: Installation
|
||||
|
||||
Installing GNU CC on the 3b1
|
||||
============================
|
||||
|
||||
Installing GNU CC on the 3b1 is difficult if you do not already have
|
||||
GNU CC running, due to bugs in the installed C compiler. However, the
|
||||
following procedure might work. We are unable to test it.
|
||||
|
||||
1. Comment out the `#include "config.h"' line on line 37 of `cccp.c'
|
||||
and do `make cpp'. This makes a preliminary version of GNU cpp.
|
||||
|
||||
2. Save the old `/lib/cpp' and copy the preliminary GNU cpp to that
|
||||
file name.
|
||||
|
||||
3. Undo your change in `cccp.c', or reinstall the original version,
|
||||
and do `make cpp' again.
|
||||
|
||||
4. Copy this final version of GNU cpp into `/lib/cpp'.
|
||||
|
||||
5. Replace every occurrence of `obstack_free' in `tree.c' with
|
||||
`_obstack_free'.
|
||||
|
||||
6. Run `make' to get the first-stage GNU CC.
|
||||
|
||||
7. Reinstall the original version of `/lib/cpp'.
|
||||
|
||||
8. Now you can compile GNU CC with itself and install it in the normal
|
||||
fashion.
|
||||
|
||||
If you have installed an earlier version of GCC, you can compile the
|
||||
newer version with that. However, you will run into trouble compiling
|
||||
`gnulib', since that is normally compiled with CC. To solve the
|
||||
problem, uncomment this line in `Makefile':
|
||||
|
||||
CCLIBFLAGS = -B/usr/local/lib/gcc- -tp -Wp,-traditional
|
||||
|
||||
|
||||
File: gcc.info, Node: SCO Install, Next: VMS Install, Prev: 3B1 Install, Up: Installation
|
||||
|
||||
Installing GNU CC on SCO System V 3.2
|
||||
=====================================
|
||||
|
||||
The compiler that comes with this system does not work properly with
|
||||
`-O'. Therefore, you should redefine the Make variable `CCLIBFLAGS'
|
||||
not to use `-O'.
|
||||
|
||||
You should also edit `Makefile' to enable the lines that set `CLIB'
|
||||
to `-lPW', and the ones specifically labeled as being for SCO, that set
|
||||
`RANLIB', and that set `CC' and `OLDCC' to `rcc -Di386 -DM_UNIX
|
||||
-DM_I386 -DM_SYSV -DM_COFF'.
|
||||
|
||||
Also, edit the definition of `USER_H' to remove the file `limits.h'.
|
||||
|
||||
Then you can run `config.gcc i386-sco' and finish building GNU CC
|
||||
normally.
|
||||
|
||||
Note that the function `memmove' is broken in 3.2v2; it clobbers
|
||||
register `%ebx'. See the file `sco-memmove.s'.
|
||||
|
||||
The same recipe should work on ESIX, but use `config.gcc i386-esix'
|
||||
instead.
|
||||
|
||||
|
||||
File: gcc.info, Node: VMS Install, Next: HPUX Install, Prev: SCO Install, Up: Installation
|
||||
|
||||
Installing GNU CC on VMS
|
||||
========================
|
||||
|
||||
The VMS version of GNU CC is distributed in a backup saveset
|
||||
containing both source code and precompiled binaries.
|
||||
|
||||
To install the `gcc' command so you can use the compiler easily, in
|
||||
the same manner as you use the VMS C compiler, you must install the VMS
|
||||
CLD file for GNU CC as follows:
|
||||
|
||||
1. Define the VMS logical names `GNU_CC' and `GNU_CC_INCLUDE' to
|
||||
point to the directories where the GNU CC executables (`gcc-cpp',
|
||||
`gcc-cc1', etc.) and the C include files are kept. This should be
|
||||
done with the commands:
|
||||
|
||||
$ assign /super /system disk:[gcc.] gnu_cc
|
||||
$ assign /super /system disk:[gcc.include.] gnu_cc_include
|
||||
|
||||
with the appropriate disk and directory names. These commands can
|
||||
be placed in your system startup file so they will be executed
|
||||
whenever the machine is rebooted. You may, if you choose, do this
|
||||
via the `GCC_INSTALL.COM' script in the `[GCC]' directory.
|
||||
|
||||
2. Install the `GCC' command with the command line:
|
||||
|
||||
$ set command /table=sys$library:dcltables gnu_cc:[000000]gcc
|
||||
|
||||
3. To install the help file, do the following:
|
||||
|
||||
$ lib/help sys$library:helplib.hlb gcc.hlp
|
||||
|
||||
Now you can invoke the compiler with a command like `gcc /verbose
|
||||
file.c', which is equivalent to the command `gcc -v -c file.c' in
|
||||
Unix.
|
||||
|
||||
We try to put corresponding binaries and sources on the VMS
|
||||
distribution tape. But sometimes the binaries will be from an older
|
||||
version that the sources, because we don't always have time to update
|
||||
them. (Use the `/verbose' option to determine the version number of
|
||||
the binaries and compare it with the source file `version.c' to tell
|
||||
whether this is so.) In this case, you should use the binaries you get
|
||||
to recompile the sources. If you must recompile, here is how:
|
||||
|
||||
1. Copy the file `tm-vms.h' to `tm.h', `xm-vms.h' to `config.h',
|
||||
`vax.md' to `md.' and `out-vax.c' to `aux-output.c'. The files to
|
||||
be copied are found in the subdirectory named `config'; they
|
||||
should be copied to the main directory of GNU CC.
|
||||
|
||||
2. Setup the logical names and command tables as defined above. In
|
||||
addition, define the vms logical name `GNU_BISON' to point at the
|
||||
to the directories where the Bison executable is kept. This
|
||||
should be done with the command:
|
||||
|
||||
$ assign /super /system disk:[bison.] gnu_bison
|
||||
|
||||
You may, if you choose, use the `INSTALL_BISON.COM' script in the
|
||||
`[BISON]' directory.
|
||||
|
||||
3. Install the `BISON' command with the command line:
|
||||
|
||||
$ set command /table=sys$library:dcltables gnu_bison:[000000]bison
|
||||
|
||||
4. Type `@make' to do recompile everything.
|
||||
|
||||
If you are compiling with a version of GNU CC older than 1.33,
|
||||
specify `/DEFINE=("inline=")' as an option in all the
|
||||
compilations. This requires editing all the `gcc' commands in
|
||||
`make-cc1.com'. (The older versions had problems supporting
|
||||
`inline'.) Once you have a working 1.33 or newer GNU CC, you can
|
||||
change this file back.
|
||||
|
||||
Due to the differences between the filesystems of Unix and VMS, the
|
||||
preprocessor attempts to translate the names of include files into
|
||||
something that VMS will understand. The basic strategy is to prepend a
|
||||
prefix to the specification of the include file, convert the whole
|
||||
filename to a VMS filename, and then try to open the file. The
|
||||
preprocessor tries various prefixes until one of them succeeds.
|
||||
|
||||
The first prefix is the `GNU_CC_INCLUDE:' logical name: this is
|
||||
where GNU_C header files are traditionally stored. If a header file is
|
||||
not found there, `SYS$SYSROOT:[SYSLIB.]' is tried next. If the
|
||||
preprocessor is still unable to locate the file, it then assumes that
|
||||
the include file specification is a valid VMS filename all by itself,
|
||||
and it uses this filename to attempt to open the include file. If none
|
||||
of these strategies succeeds, the preprocessor reports an error.
|
||||
|
||||
If you wish to store header files in non-standard locations, then you
|
||||
can assign the logical `GNU_CC_INCLUDE' to be a search list, where each
|
||||
element of the list is suitable for use with a rooted logical.
|
||||
|
||||
With this version of GNU CC, `const' global variables now work
|
||||
properly. Unless, however, the `const' modifier is also specified in
|
||||
every external declaration of the variable in all of the source files
|
||||
that use that variable, the linker will issue warnings about conflicting
|
||||
attributes for the variable, since the linker does not know if the
|
||||
variable should be read-only. The program will still work, but the
|
||||
variable will be placed in writable storage.
|
||||
|
||||
Due to an assembler bug, offsets to static constants are sometimes
|
||||
incorrectly evaluated. This bug is present in GAS 1.38.1, and should be
|
||||
fixed in the next version.
|
||||
|
||||
Under previous versions of GNU CC, the generated code would
|
||||
occasionally give strange results when linked to the sharable `VAXCRTL'
|
||||
library. Now this should work.
|
||||
|
||||
Even with this version, however, GNU CC itself should not be linked
|
||||
to the sharable `VAXCRTL'. The `qsort' routine supplied with `VAXCRTL'
|
||||
has a bug which can cause a compiler crash.
|
||||
|
||||
Similarly, the preprocessor should not be linked to the sharable
|
||||
`VAXCRTL'. The `strncat' routine supplied with `VAXCRTL' has a bug
|
||||
which can cause the preprocessor to go into an infinite loop.
|
||||
|
||||
It should be pointed out that if you attempt to link to the sharable
|
||||
`VAXCRTL', the VMS linker will strongly resist any effort to force it
|
||||
to use the `qsort' and `strncat' routines from `gcclib'. Until the
|
||||
bugs in `VAXCRTL' have been fixed, linking any of the compiler
|
||||
components to the sharable VAXCRTL is not recommended. (These routines
|
||||
can be bypassed by placing duplicate copies of `qsort' and `strncat' in
|
||||
`gcclib' under different names, and patching the compiler sources to
|
||||
use these routines). Both of the bugs in `VAXCRTL' are still present
|
||||
in VMS version 5.4-1, which is the most recent version as of this
|
||||
writing.
|
||||
|
||||
The executables that are generated by `make-cc1.com' and
|
||||
`make-cccp.com' use the non-shared version of `VAXCRTL' (and thus use
|
||||
the `qsort' and `strncat' routines from `gcclib.olb').
|
||||
|
||||
Note that GNU CC on VMS now generates debugging information to
|
||||
describe the programs symbols to the VMS debugger. However, you need
|
||||
version 1.37 or later of GAS in order to output them properly in the
|
||||
object file.
|
||||
|
||||
The VMS linker does not distinguish between upper and lower case
|
||||
letters in function and variable names. However, usual practice in C
|
||||
is to distinguish case. Normally GNU C (by means of the assembler GAS)
|
||||
implements usual C behavior by augmenting each name that is not all
|
||||
lower-case. A name is augmented by truncating it to at most 23
|
||||
characters and then adding more characters at the end which encode the
|
||||
case pattern the rest.
|
||||
|
||||
Name augmentation yields bad results for programs that use
|
||||
precompiled libraries (such as Xlib) which were generated by another
|
||||
compiler. Use the compiler option `/NOCASE_HACK' to inhibits
|
||||
augmentation; it makes external C functions and variables
|
||||
case-independent as is usual on VMS. Alternatively, you could write
|
||||
all references to the functions and variables in such libraries using
|
||||
lower case; this will work on VMS, but is not portable to other
|
||||
systems. In cases where you need to selectively inhibit augmentation,
|
||||
you can define a macro for each mixed case symbol for which you wish to
|
||||
inhibit augmentation, where the macro expands into the lower case
|
||||
equivalent of the name.
|
||||
|
||||
|
||||
File: gcc.info, Node: HPUX Install, Next: Tower Install, Prev: VMS Install, Up: Installation
|
||||
|
||||
Installing GNU CC on HPUX
|
||||
=========================
|
||||
|
||||
To install GNU CC on HPUX, you must start by editing the file
|
||||
`Makefile'. Search for the string `HPUX' to find comments saying what
|
||||
to change. You need to change some variable definitions and (if you
|
||||
are using GAS) some lines in the rule for the target `gnulib'.
|
||||
|
||||
To avoid errors when linking programs with `-g', create an empty
|
||||
library named `libg.a'. An easy way to do this is:
|
||||
|
||||
ar rc /usr/local/lib/libg.a
|
||||
|
||||
To compile with the HPUX C compiler, you must specify get the file
|
||||
`alloca.c' from GNU Emacs. Then, when you run `make', use this
|
||||
argument:
|
||||
|
||||
make ALLOCA=alloca.o
|
||||
|
||||
When recompiling GNU CC with itself, do not define `ALLOCA'.
|
||||
Instead, an `-I' option needs to be added to `CFLAGS' as follows:
|
||||
|
||||
make CC=stage1/gcc CFLAGS="-g -O -Bstage1/ -I../binutils/hp-include"
|
||||
|
||||
|
||||
File: gcc.info, Node: Tower Install, Prev: HPUX Install, Up: Installation
|
||||
|
||||
Installing GNU CC on an NCR Tower
|
||||
=================================
|
||||
|
||||
On an NCR Tower model 4x0 or 6x0, you may have trouble because the
|
||||
default maximum virtual address size of a process is just 1 Mb. Most
|
||||
often you will find this problem while compiling GNU CC with itself.
|
||||
|
||||
The only way to solve the problem is to reconfigure the kernel. Add
|
||||
a line such as this to the configuration file:
|
||||
|
||||
MAXUMEM = 4096
|
||||
|
||||
and then relink the kernel and reboot the machine.
|
|
@ -0,0 +1,475 @@
|
|||
#
|
||||
# This file is part of the Alliance CAD System
|
||||
# Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
# Universite Pierre et Marie Curie
|
||||
#
|
||||
# Home page : http://www-asim.lip6.fr/alliance/
|
||||
# E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
#
|
||||
# This progam 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.
|
||||
#
|
||||
# Alliance VLSI CAD System 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 the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
|
||||
# Makefile for GNU C compiler.
|
||||
# Copyright (C) 1987, 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 1, or (at your option)
|
||||
#any later version.
|
||||
|
||||
#GNU CC is distributed in the hope that it will be useful,
|
||||
#but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
#GNU General Public License for more details.
|
||||
|
||||
#You should have received a copy of the GNU General Public License
|
||||
#along with GNU CC; see the file COPYING. If not, write to
|
||||
#the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
#Notice :
|
||||
#for genview, this Makefile has been modified in order not to need bison or
|
||||
#whatever, as the actual state is what genview expects.
|
||||
#This is a minimized makefile for genview only, is this clear? :-(
|
||||
#Modified by Fr\'ed\'eric P\'etrot, 11 april 1993
|
||||
|
||||
include $(ALLIANCE_TOP)/etc/$(ALLIANCE_OS).mk
|
||||
CC = gcc
|
||||
# Variables that exist for you to override.
|
||||
# See below for how to change them for certain systems.
|
||||
|
||||
# Compiler to use for compiling gnulib.
|
||||
# OLDCC should not be the GNU C compiler.
|
||||
OLDCC = cc
|
||||
CFLAGS=-D$(ALLIANCE_OS)
|
||||
|
||||
# CFLAGS for use with OLDCC, for compiling gnulib.
|
||||
# NOTE: -O does not work on some Unix systems!
|
||||
# On them, you must take it out.
|
||||
CCLIBFLAGS=-O
|
||||
|
||||
# This should be the version of ar to use with output from $(OLDCC).
|
||||
OLDAR = ar
|
||||
|
||||
# CFLAGS for use with OLDCC, for compiling hard-params.
|
||||
HARD_PARAMS_FLAGS=
|
||||
|
||||
# Directory where sources are, from where we are.
|
||||
srcdir = .
|
||||
# Directory in which to put the executable for the command `gcc'
|
||||
libdir = $(prefix)/usr/local/lib
|
||||
|
||||
# Additional system libraries to link with.
|
||||
CLIB=
|
||||
|
||||
# Change this to a null string if obstacks are installed in the
|
||||
# system library.
|
||||
OBSTACK=obstack.o
|
||||
|
||||
# End of variables for you to override.
|
||||
|
||||
# If you are making gcc for the first time, and if you are compiling it with
|
||||
# a non-gcc compiler, and if your system doesn't have a working alloca() in any
|
||||
# of the standard libraries (as is true for HP/UX or Genix),
|
||||
# then un-comment the following line when compiling with the system's cc:
|
||||
# ALLOCA = alloca.o
|
||||
# But don't do that if compiling using GCC.
|
||||
|
||||
# Dependency on obstack, alloca, malloc or whatever library facilities
|
||||
# are not installed in the system libraries.
|
||||
LIBDEPS= $(OBSTACK) $(ALLOCA) $(MALLOC)
|
||||
|
||||
# How to link with both our special library facilities
|
||||
# and the system's installed libraries.
|
||||
LIBS = $(OBSTACK) $(ALLOCA) $(MALLOC) $(CLIB)
|
||||
|
||||
# Specify the directories to be searched for header files.
|
||||
# Both . and srcdir are used, in that order,
|
||||
# so that tm.h and config.h will be found in the compilation
|
||||
# subdirectory rather than in the source directory.
|
||||
INCLUDES = -I. -I$(srcdir) -I$(srcdir)/config
|
||||
SUBDIR_INCLUDES = -I.. -I../$(srcdir) -I../$(srcdir)/config
|
||||
|
||||
# Always use -I$(srcdir)/config when compiling.
|
||||
.c.o:
|
||||
$(CC) -c $(CFLAGS) $(CPPFLAGS) $(INCLUDES) $<
|
||||
|
||||
# Language-specific object files for C.
|
||||
C_OBJS = c-parse.tab.o c-decl.o c-typeck.o c-convert.o
|
||||
|
||||
# Language-specific object files for C++.
|
||||
# (These are not yet released.)
|
||||
CPLUS_OBJS = cplus-parse.o cplus-decl.o cplus-typeck.o \
|
||||
cplus-cvt.o cplus-search.o cplus-lex.o \
|
||||
cplus-class.o cplus-init.o cplus-method.o
|
||||
|
||||
# Language-independent object files.
|
||||
OBJS = toplev.o version.o tree.o print-tree.o stor-layout.o fold-const.o \
|
||||
rtl.o rtlanal.o expr.o stmt.o expmed.o explow.o optabs.o varasm.o \
|
||||
symout.o dbxout.o sdbout.o emit-rtl.o insn-emit.o \
|
||||
integrate.o jump.o cse.o loop.o flow.o stupid.o combine.o \
|
||||
regclass.o local-alloc.o global-alloc.o reload.o reload1.o caller-save.o \
|
||||
insn-peep.o final.o recog.o insn-recog.o insn-extract.o insn-output.o
|
||||
|
||||
# Files to be copied away after each stage in building.
|
||||
STAGE_GCC=genview_gcc
|
||||
STAGESTUFF = *.o insn-flags.h insn-config.h insn-codes.h \
|
||||
insn-output.c insn-recog.c insn-emit.c insn-extract.c insn-peep.c \
|
||||
stamp-flags stamp-config stamp-codes \
|
||||
stamp-output stamp-recog stamp-emit stamp-extract stamp-peep \
|
||||
genemit genoutput genrecog genextract genflags gencodes genconfig genpeep \
|
||||
genview_cc1
|
||||
|
||||
# Members of gnulib.
|
||||
LIBFUNCS = _eprintf _builtin_new _builtin_New _builtin_del _bb \
|
||||
_umulsi3 _mulsi3 _udivsi3 _divsi3 _umodsi3 _modsi3 \
|
||||
_lshrsi3 _lshlsi3 _ashrsi3 _ashlsi3 \
|
||||
_divdf3 _muldf3 _negdf2 _adddf3 _subdf3 _cmpdf2 \
|
||||
_fixunsdfsi _fixdfsi _floatsidf _truncdfsf2 _extendsfdf2 \
|
||||
_addsf3 _negsf2 _subsf3 _cmpsf2 _mulsf3 _divsf3
|
||||
|
||||
# Library members defined in gnulib2.c.
|
||||
LIB2FUNCS = _adddi3 _subdi3 _muldi3 _divdi3 _moddi3 _udivdi3 _umoddi3 _negdi2 \
|
||||
_anddi3 _iordi3 _xordi3 _lshrdi3 _lshldi3 _ashldi3 _ashrdi3 _one_cmpldi2 \
|
||||
_bdiv _cmpdi2 _ucmpdi2 _fixunsdfdi _fixdfdi _floatdidf _varargs
|
||||
|
||||
# Header files that are made available to programs compiled with gcc.
|
||||
USER_H = stddef.h assert.h va-i860.h va-mips.h va-pyr.h va-sparc.h \
|
||||
va-spur.h limits.h proto.h
|
||||
|
||||
# The files that "belong" in CONFIG_H are deliberately omitted
|
||||
# because having them there would not be useful in actual practice.
|
||||
# All they would do is cause complete recompilation every time
|
||||
# one of the machine description files is edited.
|
||||
# That may or may not be what one wants to do.
|
||||
# If it is, rm *.o is an easy way to do it.
|
||||
# CONFIG_H = config.h tm.h
|
||||
CONFIG_H =
|
||||
RTL_H = rtl.h rtl.def machmode.def
|
||||
TREE_H = tree.h real.h tree.def machmode.def
|
||||
CPLUS_TREE_H = $(TREE_H) cplus-tree.h c-tree.h
|
||||
|
||||
# Note that dependencies on obstack.h are not written
|
||||
# because that file is not part of GCC.
|
||||
# Dependencies on gvarargs.h are not written
|
||||
# because all that file does, when not compiling with GCC,
|
||||
# is include the system varargs.h.
|
||||
|
||||
#all: config.status gnulib genview_gcc genview_cc1
|
||||
all: config.status genview_gcc genview_cc1
|
||||
# Use this instead of `all' if you need to convert the libraries
|
||||
# before you can use the compiler.
|
||||
# Don't forget to do `make gnulib2' before installation.
|
||||
#all-libconvert: config.status gnulib genview_gcc genview_cc1 float.h
|
||||
all-libconvert: config.status genview_gcc genview_cc1
|
||||
|
||||
#lang-c: config.status gnulib genview_gcc genview_cc1
|
||||
lang-c: config.status genview_gcc genview_cc1
|
||||
config.status:
|
||||
@echo You must configure genview_gcc. Look at the INSTALL file for details.
|
||||
@false
|
||||
|
||||
compilations: ${OBJS}
|
||||
|
||||
genview_gcc: gcc.o version.o $(LIBDEPS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o gccnew gcc.o version.o $(LIBS)
|
||||
# Go via `gccnew' to avoid `file busy' if $(CC) is `gcc'.
|
||||
mv gccnew$(PROGRAM_SUFFIX) genview_gcc$(PROGRAM_SUFFIX)
|
||||
|
||||
genview_cc1: $(C_OBJS) $(OBJS) $(LIBDEPS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o genview_cc1 $(C_OBJS) $(OBJS) $(LIBS)
|
||||
|
||||
#Library of arithmetic subroutines
|
||||
# Don't compile this with gcc!
|
||||
# (That would cause most arithmetic functions to call themselves.)
|
||||
gnulib: gnulib.c $(CONFIG_H) config.status
|
||||
-rm -f stamp-gnulib2
|
||||
rm -f tmpgnulib gnulib; \
|
||||
for name in $(LIBFUNCS); \
|
||||
do \
|
||||
echo $${name}; \
|
||||
rm -f $${name}.c; \
|
||||
cp $(srcdir)/gnulib.c $${name}.c; \
|
||||
$(OLDCC) $(CCLIBFLAGS) $(INCLUDES) -c -DL$${name} $${name}.c; \
|
||||
$(OLDAR) qc tmpgnulib $${name}.o; \
|
||||
rm -f $${name}.[co]; \
|
||||
done
|
||||
-if [ -f /usr/bin/ranlib -o -f /bin/ranlib ] ;then $(RANLIB) tmpgnulib; else true; fi
|
||||
# Actually build it in tmpgnulib above, then rename now,
|
||||
# so that gnulib itself remains nonexistent if compilation is aborted.
|
||||
mv tmpgnulib gnulib
|
||||
# On HPUX, if you are working with the GNU assembler and linker,
|
||||
# the previous two command lines must be replaced with the following line.
|
||||
# No change is needed here if you are using the HPUX assembler and linker.
|
||||
# ../hp-bin/hpxt tmpgnulib gnulib
|
||||
|
||||
gnulib2: stamp-gnulib2;
|
||||
stamp-gnulib2: gnulib2.c gnulib genview_cc1 genview_gcc cpp $(CONFIG_H)
|
||||
for name in $(LIB2FUNCS); \
|
||||
do \
|
||||
echo $${name}; \
|
||||
./gcc -B./ -fstrength-reduce -O $(INCLUDES) $(GNULIB2_CFLAGS) -c -DL$${name} $(srcdir)/gnulib2.c -o $${name}.o; \
|
||||
$(AR) rc gnulib $${name}.o; \
|
||||
rm -f $${name}.o; \
|
||||
done
|
||||
-if [ -f /usr/bin/ranlib -o -f /bin/ranlib ] ; then $(RANLIB) gnulib; else true; fi
|
||||
# On HPUX, if you are working with the GNU assembler and linker,
|
||||
# the previous line must be commented out.
|
||||
# No change is needed here if you are using the HPUX assembler and linker.
|
||||
touch stamp-gnulib2
|
||||
|
||||
float.h:
|
||||
# Originally, we used `make' rather than $(MAKE), to avoid propagating
|
||||
# a CC=gcc command option. However, since hard-params is now made
|
||||
# with $(OLDCC) explicitly, this is no longer important.
|
||||
# However, $(MAKE) fails on some systems where it isn't defined.
|
||||
# `make' has the disadvantage of sometimes running the system's make,
|
||||
# instead of GNU make. And the system's make might not support VPATH.
|
||||
# However, the compilation of hard-params should not need to use VPATH,
|
||||
# due to the explicit use of `$(srcdir)'.
|
||||
make hard-params \
|
||||
HARD_PARAMS_FLAGS="$(HARD_PARAMS_FLAGS)" \
|
||||
CPPFLAGS="$(CPPFLAGS)" \
|
||||
LDFLAGS="$(LDFLAGS)"
|
||||
-./hard-params -f > float.h
|
||||
|
||||
# Compile hard-params with standard cc. It avoids some headaches.
|
||||
hard-params: hard-params.o
|
||||
$(OLDCC) $(HARD_PARAMS_FLAGS) $(LDFLAGS) hard-params.o -o $@
|
||||
hard-params.o: $(srcdir)/hard-params.c
|
||||
-cp $(srcdir)/hard-params.c . > /dev/null 2>&1
|
||||
$(OLDCC) $(HARD_PARAMS_FLAGS) $(CPPFLAGS) -DNO_SC -c hard-params.c
|
||||
|
||||
# C language specific files.
|
||||
|
||||
c-parse.tab.o : $(srcdir)/c-parse.tab.c $(CONFIG_H) $(TREE_H) c-parse.h c-tree.h input.h
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(INCLUDES) -D$(ALLIANCE_OS) -c $(srcdir)/c-parse.tab.c
|
||||
|
||||
c-parse.tab.c : c-parse.y
|
||||
bison c-parse.y
|
||||
|
||||
c-decl.o : c-decl.c $(CONFIG_H) $(TREE_H) c-tree.h c-parse.h flags.h
|
||||
c-typeck.o : c-typeck.c $(CONFIG_H) $(TREE_H) c-tree.h flags.h
|
||||
c-convert.o : c-convert.c $(CONFIG_H) $(TREE_H)
|
||||
|
||||
# Language-independent files.
|
||||
|
||||
gcc.o: gcc.c $(CONFIG_H) gvarargs.h obstack.h
|
||||
$(CC) $(CFLAGS) $(INCLUDES) \
|
||||
-DSTANDARD_STARTFILE_PREFIX=\"$(libdir)/\" \
|
||||
-DSTANDARD_EXEC_PREFIX=\"$(libdir)/gcc-\" -c \
|
||||
`echo $(srcdir)/gcc.c | sed 's,^\./,,'`
|
||||
|
||||
version.o: version.c
|
||||
obstack.o: obstack.c
|
||||
|
||||
tree.o : tree.c $(CONFIG_H) $(TREE_H) flags.h
|
||||
print-tree.o : print-tree.c $(CONFIG_H) $(TREE_H)
|
||||
stor-layout.o : stor-layout.c $(CONFIG_H) $(TREE_H) $(RTL_H)
|
||||
fold-const.o : fold-const.c $(CONFIG_H) $(TREE_H)
|
||||
toplev.o : toplev.c $(CONFIG_H) $(TREE_H) $(RTL_H) flags.h input.h
|
||||
|
||||
rtl.o : rtl.c $(CONFIG_H) $(RTL_H)
|
||||
|
||||
rtlanal.o : rtlanal.c $(CONFIG_H) $(RTL_H)
|
||||
|
||||
varasm.o : varasm.c $(CONFIG_H) $(TREE_H) $(RTL_H) flags.h expr.h \
|
||||
insn-codes.h hard-reg-set.h
|
||||
stmt.o : stmt.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h \
|
||||
insn-flags.h insn-config.h insn-codes.h expr.h regs.h hard-reg-set.h recog.h
|
||||
expr.o : expr.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h \
|
||||
insn-flags.h insn-codes.h expr.h insn-config.h recog.h typeclass.h
|
||||
expmed.o : expmed.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h \
|
||||
insn-flags.h insn-codes.h expr.h insn-config.h recog.h
|
||||
explow.o : explow.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h expr.h insn-codes.h
|
||||
optabs.o : optabs.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h \
|
||||
insn-flags.h insn-codes.h expr.h insn-config.h recog.h
|
||||
symout.o : symout.c $(CONFIG_H) $(TREE_H) $(RTL_H) symseg.h gdbfiles.h
|
||||
dbxout.o : dbxout.c $(CONFIG_H) $(TREE_H) $(RTL_H) flags.h
|
||||
sdbout.o : sdbout.c $(CONFIG_H) $(TREE_H) $(RTL_H)
|
||||
|
||||
emit-rtl.o : emit-rtl.c $(CONFIG_H) $(RTL_H) regs.h insn-config.h real.h
|
||||
|
||||
integrate.o : integrate.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h expr.h \
|
||||
insn-flags.h insn-codes.h
|
||||
|
||||
jump.o : jump.c $(CONFIG_H) $(RTL_H) flags.h regs.h
|
||||
stupid.o : stupid.c $(CONFIG_H) $(RTL_H) regs.h hard-reg-set.h
|
||||
|
||||
cse.o : cse.c $(CONFIG_H) $(RTL_H) regs.h hard-reg-set.h flags.h real.h
|
||||
loop.o : loop.c $(CONFIG_H) $(RTL_H) insn-config.h insn-codes.h \
|
||||
regs.h hard-reg-set.h recog.h flags.h expr.h
|
||||
flow.o : flow.c $(CONFIG_H) $(RTL_H) basic-block.h regs.h hard-reg-set.h
|
||||
combine.o : combine.c $(CONFIG_H) $(RTL_H) flags.h \
|
||||
insn-config.h regs.h basic-block.h recog.h
|
||||
regclass.o : regclass.c $(CONFIG_H) $(RTL_H) hard-reg-set.h flags.h \
|
||||
basic-block.h regs.h insn-config.h recog.h
|
||||
local-alloc.o : local-alloc.c $(CONFIG_H) $(RTL_H) flags.h basic-block.h regs.h \
|
||||
hard-reg-set.h insn-config.h recog.h
|
||||
global-alloc.o : global-alloc.c $(CONFIG_H) $(RTL_H) flags.h \
|
||||
basic-block.h regs.h hard-reg-set.h insn-config.h
|
||||
|
||||
reload.o : reload.c $(CONFIG_H) $(RTL_H) flags.h \
|
||||
reload.h recog.h hard-reg-set.h insn-config.h regs.h
|
||||
reload1.o : reload1.c $(CONFIG_H) $(RTL_H) flags.h \
|
||||
reload.h regs.h hard-reg-set.h insn-config.h basic-block.h recog.h
|
||||
caller-save.o : caller-save.c $(CONFIG_H) $(RTL_H) flags.h \
|
||||
reload.h regs.h hard-reg-set.h insn-config.h basic-block.h recog.h
|
||||
final.o : final.c $(CONFIG_H) $(RTL_H) flags.h regs.h recog.h conditions.h \
|
||||
gdbfiles.h insn-config.h real.h output.h
|
||||
recog.o : recog.c $(CONFIG_H) $(RTL_H) \
|
||||
regs.h recog.h hard-reg-set.h insn-config.h real.h
|
||||
|
||||
# Normally this target is not used; but it is used if you
|
||||
# define ALLOCA=alloca.o. In that case, you must get a suitable alloca.c
|
||||
# from the GNU Emacs distribution.
|
||||
# Note some machines won't allow $(CC) without -S on this source file.
|
||||
alloca.o: alloca.c
|
||||
$(CC) $(CFLAGS) -S `echo $(srcdir)/alloca.c | sed 's,^\./,,'`
|
||||
as alloca.s -o alloca.o
|
||||
|
||||
# Now the source files that are generated from the machine description.
|
||||
|
||||
.PRECIOUS: insn-config.h insn-flags.h insn-codes.h \
|
||||
insn-emit.c insn-recog.c insn-extract.c insn-output.c insn-peep.c
|
||||
|
||||
# The following pair of rules has this effect:
|
||||
# genconfig is run only if the md has changed since genconfig was last run;
|
||||
# but the file insn-config.h is touched only when its contents actually change.
|
||||
|
||||
# Each of the other insn-* files is handled by a similar pair of rules.
|
||||
|
||||
insn-config.h: stamp-config ;
|
||||
stamp-config : md genconfig $(srcdir)/move-if-change
|
||||
./genconfig md > tmp-config.h
|
||||
$(srcdir)/move-if-change tmp-config.h insn-config.h
|
||||
touch stamp-config
|
||||
|
||||
insn-flags.h: stamp-flags ;
|
||||
stamp-flags : md genflags $(srcdir)/move-if-change
|
||||
./genflags md > tmp-flags.h
|
||||
$(srcdir)/move-if-change tmp-flags.h insn-flags.h
|
||||
touch stamp-flags
|
||||
|
||||
insn-codes.h: stamp-codes ;
|
||||
stamp-codes : md gencodes $(srcdir)/move-if-change
|
||||
./gencodes md > tmp-codes.h
|
||||
$(srcdir)/move-if-change tmp-codes.h insn-codes.h
|
||||
touch stamp-codes
|
||||
|
||||
insn-emit.o : insn-emit.c $(CONFIG_H) $(RTL_H) expr.h real.h insn-codes.h \
|
||||
insn-config.h insn-flags.h
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -c insn-emit.c
|
||||
|
||||
insn-emit.c: stamp-emit ;
|
||||
stamp-emit : md genemit $(srcdir)/move-if-change
|
||||
./genemit md > tmp-emit.c
|
||||
$(srcdir)/move-if-change tmp-emit.c insn-emit.c
|
||||
touch stamp-emit
|
||||
|
||||
insn-recog.o : insn-recog.c $(CONFIG_H) $(RTL_H) insn-config.h real.h recog.h
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -c insn-recog.c
|
||||
|
||||
insn-recog.c: stamp-recog ;
|
||||
stamp-recog : md genrecog $(srcdir)/move-if-change
|
||||
./genrecog md > tmp-recog.c
|
||||
$(srcdir)/move-if-change tmp-recog.c insn-recog.c
|
||||
touch stamp-recog
|
||||
|
||||
insn-extract.o : insn-extract.c $(CONFIG_H) $(RTL_H)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -c insn-extract.c
|
||||
|
||||
insn-extract.c: stamp-extract ;
|
||||
stamp-extract : md genextract $(srcdir)/move-if-change
|
||||
./genextract md > tmp-extract.c
|
||||
$(srcdir)/move-if-change tmp-extract.c insn-extract.c
|
||||
touch stamp-extract
|
||||
|
||||
insn-peep.o : insn-peep.c $(CONFIG_H) $(RTL_H) regs.h real.h
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -c insn-peep.c
|
||||
|
||||
insn-peep.c: stamp-peep ;
|
||||
stamp-peep : md genpeep $(srcdir)/move-if-change
|
||||
./genpeep md > tmp-peep.c
|
||||
$(srcdir)/move-if-change tmp-peep.c insn-peep.c
|
||||
touch stamp-peep
|
||||
|
||||
insn-output.o : insn-output.c $(CONFIG_H) $(RTL_H) regs.h real.h conditions.h \
|
||||
hard-reg-set.h insn-config.h insn-flags.h output.h aux-output.c
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -c insn-output.c
|
||||
|
||||
insn-output.c: stamp-output ;
|
||||
stamp-output : md genoutput $(srcdir)/move-if-change
|
||||
./genoutput md > tmp-output.c
|
||||
$(srcdir)/move-if-change tmp-output.c insn-output.c
|
||||
touch stamp-output
|
||||
|
||||
# Now the programs that generate those files.
|
||||
# $(CONFIG_H) is omitted from the deps of the gen*.o
|
||||
# because these programs don't really depend on anything
|
||||
# about the target machine. They do depend on config.h itself,
|
||||
# since that describes the host machine.
|
||||
|
||||
genconfig : genconfig.o rtl.o $(LIBDEPS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o genconfig genconfig.o rtl.o $(LIBS)
|
||||
|
||||
genconfig.o : genconfig.c $(RTL_H) config.h
|
||||
|
||||
genflags : genflags.o rtl.o $(LIBDEPS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o genflags genflags.o rtl.o $(LIBS)
|
||||
|
||||
genflags.o : genflags.c $(RTL_H) config.h
|
||||
|
||||
gencodes : gencodes.o rtl.o $(LIBDEPS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o gencodes gencodes.o rtl.o $(LIBS)
|
||||
|
||||
gencodes.o : gencodes.c $(RTL_H) config.h
|
||||
|
||||
genemit : genemit.o rtl.o $(LIBDEPS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o genemit genemit.o rtl.o $(LIBS)
|
||||
|
||||
genemit.o : genemit.c $(RTL_H) config.h
|
||||
|
||||
genrecog : genrecog.o rtl.o $(LIBDEPS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o genrecog genrecog.o rtl.o $(LIBS)
|
||||
|
||||
genrecog.o : genrecog.c $(RTL_H) config.h
|
||||
|
||||
genextract : genextract.o rtl.o $(LIBDEPS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o genextract genextract.o rtl.o $(LIBS)
|
||||
|
||||
genextract.o : genextract.c $(RTL_H) config.h
|
||||
|
||||
genpeep : genpeep.o rtl.o $(LIBDEPS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o genpeep genpeep.o rtl.o $(LIBS)
|
||||
|
||||
genpeep.o : genpeep.c $(RTL_H) config.h
|
||||
|
||||
genoutput : genoutput.o rtl.o $(LIBDEPS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o genoutput genoutput.o rtl.o $(LIBS)
|
||||
|
||||
genoutput.o : genoutput.c $(RTL_H) config.h
|
||||
|
||||
# gnulib is not deleted because deleting it would be inconvenient
|
||||
# for most uses of this target.
|
||||
realclean clean:
|
||||
-rm -f $(STAGESTUFF) $(STAGE_GCC)
|
||||
# Delete the temp files made in the course of building gnulib.
|
||||
-rm -f tmpgnulib
|
||||
for name in $(LIBFUNCS); do rm -f $${name}.c; done
|
||||
-rm -f stamp-*.[ch] tmp-*
|
||||
-rm -f *.s *.s[0-9] *.co *.greg *.lreg *.combine *.flow *.cse *.jump *.rtl *.tree *.loop *.dbr *.jump2
|
||||
-rm -f core float.h hard-params
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,128 @@
|
|||
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.
|
||||
|
||||
23. (memory >> 24) and (memory >> 24) == CONST optimizations
|
||||
ought to be done machine independently.
|
||||
|
||||
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.
|
||||
|
||||
42. In subst in combine.c at line 704 or so, a reg that really
|
||||
wants an areg gets a dreg. It is i*4, for indexing. Why?
|
||||
|
||||
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.
|
||||
|
||||
53. Know that certain library routines do not clobber memory.
|
||||
|
||||
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?
|
||||
|
||||
95. Can simplify shift of result of a bfextu. See testunsfld.c.
|
||||
Likewise and of result of a bfextu. See hyph.c.
|
||||
|
||||
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,364 @@
|
|||
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.
|
||||
|
||||
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.
|
||||
|
||||
* 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-alloc.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.
|
||||
|
||||
* 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.
|
||||
|
||||
* Label-addresses as expressions.
|
||||
|
||||
It would be nice to have access to the addresses of labels; to be able to
|
||||
store them in variables, or initialize vectors of them.
|
||||
|
||||
Alas, `&label0' is the address of the variable named label0, which is
|
||||
unrelated to the label with that name. Some other syntax is needed.
|
||||
Perhaps colon as a unary operator? That is ambiguous with `?:' with
|
||||
the middle operand omitted. Perhaps ^ as a unary operator? Perhaps
|
||||
`__label__ label0' could mean the value of label0? Its type could be
|
||||
`void *'. `goto *EXP' could be used to go to a value of type `void
|
||||
*'--no ambiguity there.
|
||||
|
||||
Jump optimization and flow analysis must know about computed jumps,
|
||||
but that is not hard. Each basic block headed by a possible target of
|
||||
computed jumps must be considered a successor of each basic block
|
||||
ending in a computed jump. Aside from this, I believe no other
|
||||
optimizer changes are needed.
|
||||
|
||||
Next question: stack levels. In most functions, there is no problem,
|
||||
but it would be a shame to make a feature that doesn't work together
|
||||
with other features. Here is an idea:
|
||||
|
||||
For each label that might need stack level restoration, construct a
|
||||
shadow-label which will restore the stack and jump to the user-label.
|
||||
Then use the address of the shadow label for label0 when someone asks
|
||||
for that of label0. Jump optimization will delete all the shadow labels
|
||||
if the function has no computed gotos.
|
||||
|
||||
* 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.
|
||||
|
||||
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. 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,15 @@
|
|||
This directory contains the version 1.42 release of the GNU C compiler.
|
||||
All serious bugs (that would make ordinary C programs fail) reported for
|
||||
previous test releases have been fixed. We have often decided not to fix
|
||||
bugs that are Less important, to avoid risking creating new bugs.
|
||||
|
||||
See the file gcc.texinfo for installation and porting information.
|
||||
The file INSTALL contains a copy of the installation information.
|
||||
|
||||
The GNU C compiler is free software. See the file COPYING for copying
|
||||
permission.
|
||||
|
||||
The files print-self.c and print-self1.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.
|
|
@ -0,0 +1,53 @@
|
|||
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,69 @@
|
|||
1/3/89 Pace Willisson
|
||||
|
||||
Here is what to do to bring up GCC & tools on an 80386 running system 5.3
|
||||
(if you are adventurous and want to use the latest and greatest tools.
|
||||
If you want it to be easy, check back in a couple of months.)
|
||||
|
||||
All of these instructions assume you are using the usg compiler. After
|
||||
you get to the end, you could start over using the GNU compiler, but
|
||||
that may not work yet ...
|
||||
|
||||
First make gcc, cc1, cpp, and gnulib:
|
||||
|
||||
cd .../gcc
|
||||
config.gcc i386-sysv-gas
|
||||
make start.encap
|
||||
|
||||
Don't try to bootstrap the compiler with itself at this point,
|
||||
since it can't really be used until GAS and the converted libraries
|
||||
are installed.
|
||||
|
||||
Now you must copy `cc1' and `cpp' and `gnulib' into the directory
|
||||
`/usr/local/lib/gcc/i386-sysv-gas/VERSION', where VERSION stands for
|
||||
the GCC version number. Also install `gcc' in a directory in your
|
||||
path.
|
||||
|
||||
Now, make the GNU assembler:
|
||||
|
||||
cd .../gas
|
||||
make a386
|
||||
cp a386 /usr/local/lib/gcc/i386-sysv-gas/VERSION
|
||||
|
||||
Now, make the other utilities:
|
||||
|
||||
cd .../binutils
|
||||
|
||||
edit Makefile to turn on the CFLAGS for USG using COFF_ENCAPSULATE
|
||||
|
||||
make
|
||||
cp ld /usr/local/lib/gcc/i386-sysv-gas/VERSION
|
||||
|
||||
Put the other programs (size nm strip ar objdump and ranlib) somewhere
|
||||
handy, but don't clobber your usg programs. I put them all in
|
||||
/usr/gnu/gnucomp, and I have this shell script in my path under the name "gnu":
|
||||
|
||||
exec /usr/gnu/gnucomp/$*
|
||||
|
||||
That way, I can say "gnu nm a.out", etc.
|
||||
|
||||
Convert the libraries to the encapsulated format:
|
||||
|
||||
make libc.a
|
||||
cp libc.a /usr/local/lib/gnu/libc.a
|
||||
|
||||
cp .../gcc/gnulib usg-gnulib
|
||||
make gnulib
|
||||
cp gnulib /usr/local/lib/gcc/i386-sysv-gas/VERSION
|
||||
|
||||
robotussin /lib/crt0.o /usr/local/lib/gcc-crt0.o
|
||||
|
||||
Now add the parts of `gnulib' that are compiled with GCC,
|
||||
and install the complete `gnulib' in place of the partial one.
|
||||
|
||||
cp gnulib .../gcc
|
||||
cd .../gcc
|
||||
make rest.encap
|
||||
cp gnulib /usr/local/lib/gcc/i386-sysv-gas/VERSION
|
||||
|
||||
Now, you should be able to use 'gcc' to compile programs.
|
||||
If you want to bootstrap GCC with itself, this can now be done.
|
|
@ -0,0 +1,150 @@
|
|||
Copyright (C) 1987 Free Software Foundation, Inc.
|
||||
Contributed by Michael Tiemann (tiemann@mcc.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 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
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 refering 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,447 @@
|
|||
Return-Path: <info-gcc-request@prep.ai.mit.edu>
|
||||
Date: 11 Sep 90 14:07:21 GMT
|
||||
From: news@operations.dccs.upenn.edu (USENET News System)
|
||||
Organization: University of Pennsylvania
|
||||
Subject: Building gcc 1.37.1 with Vax C
|
||||
References: <9009102236.AA15872@wubios.wustl.edu>
|
||||
Sender: info-gcc-request@prep.ai.mit.edu
|
||||
To: info-gcc@prep.ai.mit.edu
|
||||
|
||||
during it; hopefully they'll come in handy.
|
||||
|
||||
To build the new gcc-cpp and gcc-cc1 that come with Gnu C
|
||||
version 1.37.1 with Vax C and NOT a previous version of gcc,
|
||||
do the following:
|
||||
|
||||
I - Building gcc-cpp
|
||||
|
||||
A - Modify cccp.c
|
||||
|
||||
1 - Replace
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
with
|
||||
|
||||
#ifndef VMS
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#else
|
||||
#include <types.h>
|
||||
#include <stat.h>
|
||||
#endif
|
||||
|
||||
[It is claimed that
|
||||
$ define sys sys$library
|
||||
will solve the same problem without source changes.]
|
||||
|
||||
2 - In the VMS-specific section (has perror.h etc in it),
|
||||
add the following:
|
||||
|
||||
#include <descrip.h> /* for dsc$descriptor_s */
|
||||
#include <string.h> /* for strchr & strrchr */
|
||||
#define index strchr
|
||||
#define rindex strrchr
|
||||
|
||||
3 - You have to replace all occurences of:
|
||||
|
||||
extern char *index(), *rindex();
|
||||
|
||||
as well as any where they're separated (e.g. extern char *index()
|
||||
by itself or extern char *rindex() by itself), with the following:
|
||||
|
||||
#ifndef VMS
|
||||
extern char *index(); /* or whatever was here */
|
||||
#endif
|
||||
|
||||
There's a total of three: one in main(), one in do_include(), and
|
||||
one in hack_vms_include_specification().
|
||||
|
||||
B - You have to have alloca.mar for cccp.c; it was distributed
|
||||
with vmsgcc1.34; it's also in the bison distribution. (both 1.03
|
||||
and 1.06)
|
||||
|
||||
C - After you've compiled alloca.mar (MACRO ALLOCA.MAR), follow
|
||||
the instructions at the top of MAKE-CC1.COM (namely, change the
|
||||
CC := line to say cc/noopt instead of gcc, take the
|
||||
cc1_options="-mpcc-alignment" part out of the CFLAGS line, and change
|
||||
the LIBS line to say:
|
||||
|
||||
$ LIBS := alloca,sys$share:vaxcrtl/libr
|
||||
|
||||
D - Since it doesn't come with the distribution, you have
|
||||
to generate cexp_tab.c yourself, either with bison on either
|
||||
a Vax or a Unix box, or yacc in Unix. (@make below will die if you
|
||||
don't have bison on your Vax or don't have this file)
|
||||
|
||||
E - Type:
|
||||
|
||||
@make
|
||||
|
||||
and watch it hum. It should go through okay; it'll die on the LINK
|
||||
line, but don't worry about it.
|
||||
|
||||
F - Now link the whole thing with:
|
||||
|
||||
link /nomap/exe=gcc-cpp cccp,cexp,version,alloca,-
|
||||
sys$share:vaxcrtl/libr
|
||||
|
||||
G - You should be screaming for joy right now; if you're not, then
|
||||
give up on life. <snicker>
|
||||
|
||||
|
||||
II - Building gcc-cc1
|
||||
|
||||
A - Change MAKE-CC1.COM to contain the line:
|
||||
|
||||
$ libs :== sys$share:vaxcrtl/libr,alloca
|
||||
|
||||
Yep, you have to have alloca.obj here too.
|
||||
|
||||
B - Modify toplev.c:
|
||||
|
||||
1 - Replace
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
with
|
||||
|
||||
#ifndef VMS
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#else
|
||||
#include <types.h>
|
||||
#include <stat.h>
|
||||
#endif
|
||||
|
||||
(You'll see this again.)
|
||||
|
||||
2 - Do:
|
||||
|
||||
Repl: rtx_equal_function_value_matters
|
||||
With: rtx_equ_func_value_matters
|
||||
Num: once
|
||||
|
||||
This is cuz you can't have a name over 31 chars with the
|
||||
Vax C compiler; and yep you guessed it this is over that
|
||||
limit. You're gonna be doing this a few more times.
|
||||
|
||||
C - Modify gcc.c:
|
||||
|
||||
1 - This is optional, since you never compile it (I'm
|
||||
working on that):
|
||||
|
||||
Replace
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <sys/file.h>
|
||||
|
||||
with
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#ifdef VMS
|
||||
#include <types.h>
|
||||
#include <file.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/file.h>
|
||||
#endif
|
||||
|
||||
D - Modify c-parse_tab.c (if this isn't there, you'll have
|
||||
to create it with bison or yacc):
|
||||
|
||||
Repl: expand_start_loop_continue_elsewhere
|
||||
With: expand_startloop_cont_elsewhere
|
||||
Num: twice
|
||||
|
||||
E - Modify tree.h:
|
||||
|
||||
Repl: expand_start_loop_continue_elsewhere
|
||||
With: expand_startloop_cont_elsewhere
|
||||
Num: once
|
||||
|
||||
F - Modify stmt.c:
|
||||
|
||||
Repl: expand_start_loop_continue_elsewhere
|
||||
With: expand_startloop_cont_elsewhere
|
||||
Num: twice
|
||||
|
||||
Repl: current_function_returns_pcc_struct
|
||||
With: cur_func_ret_pcc_struct
|
||||
Num: nine
|
||||
|
||||
Repl: current_function_returns_pointer
|
||||
With: cur_func_ret_ptr
|
||||
Num: 2
|
||||
|
||||
Repl: current_function_pretend_args_size
|
||||
With: cur_func_pretend_args_size
|
||||
Num: 3
|
||||
|
||||
G - Modify rtanal.c:
|
||||
|
||||
Repl: rtx_equal_function_value_matters
|
||||
With: rtx_equ_func_values_matters
|
||||
Num: twice
|
||||
|
||||
H - Modify output.h:
|
||||
|
||||
Repl: current_function_returns_pcc_struct
|
||||
With: cur_func_ret_pcc_struct
|
||||
Num: once
|
||||
|
||||
Repl: current_function_returns_pointer
|
||||
With: cur_func_ret_ptr
|
||||
Num: once
|
||||
|
||||
Repl: current_function_pretend_args_size
|
||||
With: cur_func_pretend_args_size
|
||||
Num: once
|
||||
|
||||
I - Modify tree.def:
|
||||
|
||||
Change the line that reads:
|
||||
|
||||
DEFTREECODE (FILE_TYPE, "file_type", "t", 0)
|
||||
|
||||
to:
|
||||
|
||||
#ifdef VMS
|
||||
DEFTREECODE (FILE_TYPE_GNU, "file_type", "t", 0)
|
||||
#else
|
||||
DEFTREECODE (FILE_TYPE, "file_type", "t", 0)
|
||||
#endif
|
||||
|
||||
This is cuz FILE_TYPE is defined in stdio.h as being
|
||||
struct _iobuf *, which totally screws everything up.
|
||||
|
||||
J - Modify expr.c:
|
||||
|
||||
Change the line that reads:
|
||||
|
||||
if (code == FILE_TYPE)
|
||||
|
||||
to:
|
||||
|
||||
#ifdef VMS
|
||||
if (code == FILE_TYPE_GNU)
|
||||
#else
|
||||
if (code == FILE_TYPE)
|
||||
#endif
|
||||
|
||||
K - Modify expmed.c:
|
||||
|
||||
Change the line that reads:
|
||||
|
||||
trymode && GET_MODE_SIZE (trymode) <= maxsize;
|
||||
|
||||
to:
|
||||
|
||||
(trymode != 0) && (GET_MODE_SIZE (trymode) <= maxsize);
|
||||
|
||||
Enclosing the second half of the and in parenthesis may be
|
||||
overkill. By the time I thought of it it was too late to
|
||||
change it (read: I didn't feel like going back), but you
|
||||
may want to give it a try.
|
||||
|
||||
L - Modify symout.c:
|
||||
|
||||
Change the line that has #include <stddef.h> on it to:
|
||||
|
||||
#ifndef VMS
|
||||
#include <stddef.h>
|
||||
#else
|
||||
#define NULL (void *) 0
|
||||
#endif
|
||||
|
||||
M - Modify insn-emit.c:
|
||||
|
||||
Line #1011 (in mine) is a 376-character long line that's
|
||||
one HUGE return (it calls a function a few zillion times
|
||||
embedded upon each other). This is a tad too big for Vax C
|
||||
to chew; try cutting it down to a few lines. I made it look
|
||||
like this:
|
||||
|
||||
rtx
|
||||
gen_casesi (operand0, operand1, operand2, operand3)
|
||||
rtx operand0;
|
||||
rtx operand1;
|
||||
rtx operand2;
|
||||
rtx operand3;
|
||||
{
|
||||
return gen_rtx (SET, VOIDmode, pc_rtx,
|
||||
gen_rtx (IF_THEN_ELSE, VOIDmode,
|
||||
gen_rtx (LE, VOIDmode,
|
||||
gen_rtx (MINUS, SImode, operand0, operand1),
|
||||
operand2),
|
||||
gen_rtx (PLUS, SImode,
|
||||
gen_rtx (SIGN_EXTEND, SImode,
|
||||
gen_rtx (MEM, HImode,
|
||||
gen_rtx (PLUS, SImode, pc_rtx,
|
||||
gen_rtx (MINUS, SImode, operand0, operand1)))),
|
||||
gen_rtx (LABEL_REF, SImode, operand3)),
|
||||
pc_rtx));
|
||||
}
|
||||
|
||||
Kinda smacks of lisp, no?
|
||||
|
||||
N - Modify final.c:
|
||||
|
||||
Change the line that reads:
|
||||
|
||||
rtx final_sequence;
|
||||
|
||||
to:
|
||||
|
||||
#ifndef VMS
|
||||
rtx final_sequence;
|
||||
#endif
|
||||
|
||||
This is cuz rtx final_sequence already appears in
|
||||
output.h, and Vax C screams when it sees this.
|
||||
|
||||
O - You have to have alloca(), bcopy(), bcmp(), and
|
||||
bzero(); all are in the VMS Gcc 1.34 distribution; only
|
||||
bcopy() is in the bison distribution. Since they're pretty
|
||||
short, I'm gonna include 'em here. These were sent under the
|
||||
Gnu public license.
|
||||
|
||||
alloca.mar:
|
||||
|
||||
.PSECT $CODE,LONG,PIC,REL,SHR,EXE,RD,NOWRT
|
||||
.ENTRY ALLOCA,^M<>
|
||||
SUBL2 4(AP),SP
|
||||
MOVL 16(FP),R1
|
||||
MOVQ 8(FP),AP
|
||||
BICL2 #3,SP
|
||||
ADDL2 #28,SP
|
||||
MOVL SP,R0
|
||||
JMP (R1)
|
||||
|
||||
.END
|
||||
|
||||
bcopy.mar:
|
||||
|
||||
.PSECT $CODE,LONG,PIC,REL,SHR,EXE,RD,NOWRT
|
||||
; bcopy(from, to, size)
|
||||
.ENTRY BCOPY,^M<R2,R3,R4,R5,R6>
|
||||
MOVL 4(AP),R1
|
||||
MOVL 8(AP),R3
|
||||
MOVL 12(AP),R6
|
||||
CMPL R1,R3
|
||||
BGTR 2$ ; NORMAL FORWARD CASE
|
||||
BLSS 3$ ; OVERLAPPING, MUST DO BACKWARDS
|
||||
RET ; EQUAL, NOTHING TO DO
|
||||
1$: SUBL2 R0,R6
|
||||
MOVC3 R0,(R1),(R3)
|
||||
2$: MOVZWL #65535,R0
|
||||
CMPL R6,R0
|
||||
BGTR 1$
|
||||
MOVC3 R6,(R1),(R3)
|
||||
RET
|
||||
3$: ADDL2 R6,R1
|
||||
ADDL2 R6,R3
|
||||
MOVZWL #65535,R0
|
||||
BRW 5$
|
||||
4$: SUBL2 R0,R6
|
||||
SUBL2 R0,R1
|
||||
SUBL2 R0,R3
|
||||
MOVC3 R0,(R1),(R3)
|
||||
MOVZWL #65535,R0
|
||||
SUBL2 R0,R1
|
||||
SUBL2 R0,R3
|
||||
5$: CMPL R6,R0
|
||||
BGTR 4$
|
||||
SUBL2 R6,R1
|
||||
SUBL2 R6,R3
|
||||
MOVC3 R6,(R1),(R3)
|
||||
|
||||
RET
|
||||
|
||||
.END
|
||||
|
||||
bcmp.mar:
|
||||
|
||||
.PSECT $CODE,LONG,PIC,REL,SHR,EXE,RD,NOWRT
|
||||
; bcmp(s1, s2, n)
|
||||
.ENTRY BCMP,^M<R2,R3,R4,R5>
|
||||
MOVL 4(AP),R1
|
||||
MOVL 8(AP),R3
|
||||
MOVL 12(AP),R4
|
||||
1$: MOVZWL #65535,R0
|
||||
CMPL R4,R0
|
||||
BLEQ 2$
|
||||
SUBL2 R0,R4
|
||||
CMPC3 R0,(R1),(R3)
|
||||
BEQL 1$
|
||||
ADDL2 R4,R0
|
||||
RET
|
||||
2$: CMPC3 R4,(R1),(R3)
|
||||
RET
|
||||
|
||||
.END
|
||||
|
||||
|
||||
bzero.mar:
|
||||
|
||||
.PSECT $CODE,LONG,PIC,REL,SHR,EXE,RD,NOWRT
|
||||
; bzero(ptr, size)
|
||||
.ENTRY BZERO,^M<R2,R3,R4,R5>
|
||||
MOVL 4(AP),R3
|
||||
BRB 2$
|
||||
1$: SUBL2 R0,8(AP)
|
||||
MOVC5 #0,(R3),#0,R0,(R3)
|
||||
2$: MOVZWL #65535,R0
|
||||
CMPL 8(AP),R0
|
||||
BGTR 1$
|
||||
MOVC5 #0,(R3),#0,8(AP),(R3)
|
||||
RET
|
||||
|
||||
.END
|
||||
|
||||
P - On the last lines (where it's got all of the link shit),
|
||||
change it so it reads:
|
||||
|
||||
...blahblahblah...
|
||||
...blahblah,insn-extract,insn-output,obstack,-
|
||||
integrate,caller-save,-
|
||||
bcopy,bcmp,bzero
|
||||
$!
|
||||
|
||||
So now it'll link the bcopy, bcmp, and bzero routines in.
|
||||
|
||||
Q - You should be screaming for joy right now; if you're
|
||||
not, then give up on life again. Hey, I don't get paid for my humor.
|
||||
|
||||
R - Finally, you have to use old versions of:
|
||||
|
||||
GCC.EXE GCC-AS.EXE
|
||||
GCC.COM GCC.CLD
|
||||
GCCLIB.OLB
|
||||
|
||||
to make the package work properly. I've only been able to make the
|
||||
new preprocessors make properly; since it wasn't even in the make
|
||||
files that came with it, I don't think gcc.exe 1.37.1 was intended
|
||||
to be built for the Vax .. we'll see.
|
||||
|
||||
In case you're wondering, I could never get vmsgcc134 to work properly;
|
||||
that's why I did this with Vax C.
|
||||
|
||||
Good luck! This only worked under 5.3-1 (and the latest version of
|
||||
Vax C...3.0? 3.1?), and isn't guaranteed in any way shape or form. If
|
||||
you have stumbling blocks and think I may have come upon it during all
|
||||
of this, feel free to mail me at kehoe@scotty.dccs.upenn.edu.
|
||||
|
||||
--
|
||||
Brendan Kehoe | Soon: brendan@cs.widener.edu
|
||||
For now: kehoe@scotty.dccs.upenn.edu | Or: bkehoe@widener.bitnet
|
||||
Last resort: brendan.kehoe@cyber.widener.edu
|
||||
Brendan Kehoe | Soon: brendan@cs.widener.edu
|
||||
For now: kehoe@scotty.dccs.upenn.edu | Or: bkehoe@widener.bitnet
|
||||
Last resort: brendan.kehoe@cyber.widener.edu
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
Our setup:
|
||||
|
||||
Sun 3/60 with cgfour
|
||||
SunOS 4.0 (plus what Sun calls their "general hygiene" patch tape)
|
||||
XV11R3 + MIT fixes 1 through 8 + "Purdue enhancements" + one local
|
||||
"ANSIfication" fix (previously reported to MIT,
|
||||
and attached below)
|
||||
|
||||
I installed gcc 1.34 (plus the expr.c fix) and also ran the "fixincludes"
|
||||
script.
|
||||
|
||||
I built the X stuff with with the "CC" line in the "Sun.macros" file set to:
|
||||
|
||||
CC = gcc -fcombine-regs -fstrength-reduce -finline-functions -fpcc-struct-return -DPURDUE -Dinline=INLINE -DNOSTDHDRS
|
||||
|
||||
where -fcombine-regs, -fstrength-reduce, and -finline-functions
|
||||
specify desired optimizations, -fpcc-struct-return makes things
|
||||
compatible with the dbm library, -DPURDUE buys the Purdue speedups,
|
||||
-Dinline=INLINE avoids a problem with a variable named "inline" in the
|
||||
X file "fonts/bdftosnf/fontutil.c", and -DNOSTDHDRS avoids a problem
|
||||
with multiple (and conflicting) typedef'ing of "size_t" in the
|
||||
gcc-provided STDDEF_H and Sun's "sys/types.h".
|
||||
|
||||
Some clients may need -fwritable-strings. twm is said to need it.
|
||||
|
||||
The ANSIfication fix:
|
||||
|
||||
> From ado Mon Dec 26 10:55:28 1988
|
||||
> To: xbugs@expo.lcs.mit.edu
|
||||
> Subject: Xlibint and __STDC__ don't mix
|
||||
>
|
||||
>
|
||||
> X Window System Bug Report
|
||||
> xbugs@expo.lcs.mit.edu
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
> VERSION:
|
||||
> R3
|
||||
>
|
||||
> CLIENT MACHINE and OPERATING SYSTEM:
|
||||
> Sun 3/60 running SunOS 4.0
|
||||
>
|
||||
> DISPLAY:
|
||||
> Sun CG4
|
||||
>
|
||||
> WINDOW MANAGER:
|
||||
> uwm
|
||||
>
|
||||
> AREA:
|
||||
> Xlib
|
||||
>
|
||||
> SYNOPSIS:
|
||||
> Xlibint.h and __STDC__ don't mix
|
||||
>
|
||||
> DESCRIPTION:
|
||||
> If __STDC__ is defined (and UNIXCPP is not defined),
|
||||
> code that uses the GetReqExtra macro defined in Xlibint.h
|
||||
> is uncompilable.
|
||||
>
|
||||
> REPEAT BY:
|
||||
> Script started on Mon Dec 26 10:52:58 1988
|
||||
> elsie$ cd lib/X
|
||||
> elsie$ rm Xbackgnd.o
|
||||
> rm: Xbackgnd.o: No such file or directory
|
||||
> elsie$ rm XBackgnd.o
|
||||
> elsie$ make XBackgnd.o CC=/usr/local/bin/gcc
|
||||
> rm -f XBackgnd.o
|
||||
> /usr/local/bin/gcc -c -O -I. -I../../. -I../.././X11 -DTCPCONN -DUNIXCONN XBackgnd.c
|
||||
> XBackgnd.c: In function XSetWindowBackground:
|
||||
> XBackgnd.c:16: undeclared variable `sz_' (first use here)
|
||||
> *** Error code 1
|
||||
> make: Fatal error: Command failed for target `XBackgnd.o'
|
||||
> elsie$ exit
|
||||
>
|
||||
> script done on Mon Dec 26 10:53:51 1988
|
||||
>
|
||||
> SAMPLE FIX:
|
||||
> *** 1.1/Xlibint.h Mon Dec 26 10:39:37 1988
|
||||
> --- 1.2/Xlibint.h Mon Dec 26 10:39:37 1988
|
||||
> ***************
|
||||
> *** 122,133 ****
|
||||
> #if defined(__STDC__) && !defined(UNIXCPP)
|
||||
> #define GetReqExtra(name, n, req) \
|
||||
> WORD64ALIGN\
|
||||
> ! if ((dpy->bufptr + SIZEOF(*req) + n) > dpy->bufmax)\
|
||||
> _XFlush(dpy);\
|
||||
> req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\
|
||||
> req->reqType = X_##name;\
|
||||
> ! req->length = (SIZEOF(*req) + n)>>2;\
|
||||
> ! dpy->bufptr += SIZEOF(*req) + n;\
|
||||
> dpy->request++
|
||||
> #else
|
||||
> #define GetReqExtra(name, n, req) \
|
||||
> --- 122,133 ----
|
||||
> #if defined(__STDC__) && !defined(UNIXCPP)
|
||||
> #define GetReqExtra(name, n, req) \
|
||||
> WORD64ALIGN\
|
||||
> ! if ((dpy->bufptr + SIZEOF(x##name##Req) + n) > dpy->bufmax)\
|
||||
> _XFlush(dpy);\
|
||||
> req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\
|
||||
> req->reqType = X_##name;\
|
||||
> ! req->length = (SIZEOF(x##name##Req) + n)>>2;\
|
||||
> ! dpy->bufptr += SIZEOF(x##name##Req) + n;\
|
||||
> dpy->request++
|
||||
> #else
|
||||
> #define GetReqExtra(name, n, req) \
|
||||
> --
|
||||
> Arthur David Olson ado@ncifcrf.gov ADO is a trademark of Ampex.
|
||||
|
|
@ -0,0 +1,968 @@
|
|||
GNU Service Directory -*- text -*-
|
||||
|
||||
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 this file alphabetical **
|
||||
|
||||
|
||||
Joseph Arceneaux <jla@ai.mit.edu>
|
||||
PO Box 460633
|
||||
San Francisco, CA 94146-0633
|
||||
+1 415 285 9088
|
||||
|
||||
FSF Staff Programmer. Performed X11 implementation of Emacs version 19.
|
||||
Currently working on hypertext emacs.
|
||||
|
||||
Service and development of GNU and X11 software. Handholding, teaching,
|
||||
and installations at lower rates.
|
||||
|
||||
Rates: $150/hour. Free to non-profits.
|
||||
|
||||
Updated: 11/7/91
|
||||
|
||||
Giuseppe Attardi <attardi@di.unipi.it>
|
||||
Dipartimento di Informatica
|
||||
Corso Italia 40
|
||||
I-56125 Pisa, Italy
|
||||
+39 (50) 510-111
|
||||
|
||||
GNU: help on obtaininig GNU, for italian sites.
|
||||
|
||||
Updated: 18/11/91
|
||||
|
||||
Randolph Back <rback@boulder.Colorado.edu>
|
||||
Back Software & Consulting, Inc.
|
||||
1705 14th St. #344
|
||||
Boulder, CO 80302
|
||||
(303) 443-7758
|
||||
|
||||
Consulting, installation, cutomization and training for GNU emacs, and
|
||||
other GNU software.
|
||||
|
||||
Entered: 3/13/91
|
||||
|
||||
Andrea Baldi
|
||||
European Space Agency (ESA)
|
||||
European Space Operations Center (ESOC)
|
||||
Robert-Bosch-Str 5
|
||||
D-6100 DARMSTADT
|
||||
West-Germany
|
||||
Phone 0049-6151-902762 (Work) Bitnet : <abaldi@esoc.bitnet>
|
||||
Fax 0049-6151-90-495 Uucp : <unido!esoc.bitnet!abaldi>
|
||||
|
||||
Your Rate: Free
|
||||
|
||||
Programs Supported: Emacs, bison, gcc, g++, gdb, bash, X11
|
||||
Emacs: installation and upgrading aid, answering, customization.
|
||||
Gcc, g++, gdb, bash: installation and upgrading aid.
|
||||
X11: quick questions
|
||||
|
||||
Experience (with gnu software)
|
||||
I have maintained Emacs for more than 4 years as well as bison, gcc,
|
||||
g++, gdb, bash, X11. I have written/modified several Emacs lisp programs.
|
||||
Currently I maintain many GNU programs for my department.
|
||||
|
||||
Updated: 11 Sept 91
|
||||
|
||||
Bard Bloom
|
||||
Department of Computer Science
|
||||
Cornell University
|
||||
Ithaca, NY 14850
|
||||
607-255-9211
|
||||
|
||||
Your Rate: $200/hour.
|
||||
I might do work for friends and worthy organizations for free.
|
||||
|
||||
Programs Supported: GNU Emacs
|
||||
|
||||
Experience: Lots. For example, in 1989 I wrote a safe multi-user
|
||||
database program of sorts in Gnu Emacs in about a week.
|
||||
I've written some 30,000 lines of Gnu Lisp code in total.
|
||||
|
||||
Degree: PhD in CS from MIT.
|
||||
Other: My real life as a professor takes precedence over consulting.
|
||||
|
||||
Updated: 11 Sept 91
|
||||
|
||||
James Craig Burley
|
||||
4 Mountain Gate Rd.
|
||||
Ashland, MA 01721-2326
|
||||
(508) 881-6087, -4745
|
||||
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 (lately Linux on the ix86)
|
||||
Tools/Utilities Development and Maintenance
|
||||
Microcode Development and Maintenance (primarily VLIW machines)
|
||||
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: $75/hour, though somewhat volatile due to commitments regarding
|
||||
GNU Fortran -- willing to consider flat-fee arrangements
|
||||
|
||||
Entered: 10 Jul 92
|
||||
|
||||
Michael I. Bushnell <mib@gnu.ai.mit.edu>
|
||||
NE43-426, 545 Technology Square
|
||||
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: $50/hr, negotiable, less for non-profit organizaions.
|
||||
|
||||
Updated: 10/29/91
|
||||
|
||||
C2V Renaud Dumeur <renaud@ccv.fr>
|
||||
82 bd Haussmann Jean-Alain Le Borgne <jalb@ccv.fr>
|
||||
75009 Paris
|
||||
France
|
||||
Tel (1) 40.08.07.07
|
||||
Fax (1) 43.87.35.99
|
||||
|
||||
Emacs: questions answered, installation, teaching (all levels), elisp
|
||||
and C extensions and customization, porting, troubleshooting
|
||||
gcc: installation, extensions, porting
|
||||
gdb: installation, debugging, porting
|
||||
X11: installation, debugging, internationalization
|
||||
|
||||
Experience: yes (ask for details)
|
||||
|
||||
Rates: 500ff/hr, negotiable.
|
||||
|
||||
Entered: 12/17/91
|
||||
|
||||
Mr. David J. Camp <david@wubios.wustl.edu>
|
||||
6103 Charlotte Avenue
|
||||
Saint Louis, MO 63120-1201
|
||||
|
||||
Background: Bachelor of Science in Computer Science, Washington University
|
||||
Master of Science in Computer Science, Washington University
|
||||
Over 12 years experience in the computer industry.
|
||||
Author of the future GNU uu/xxen/decoder program.
|
||||
Skilled in many languages, including C and Unix scripts.
|
||||
|
||||
Tasks: I can do on-site service in the St. Louis area.
|
||||
I prefer short-term projects.
|
||||
I can handle long projects given time.
|
||||
I reserve the right to refuse work.
|
||||
|
||||
Rates: $50 per hour, including travel time
|
||||
|
||||
Entered: 1/1/91
|
||||
|
||||
Computing Support Team (CSTeam)
|
||||
111 College Place, Rm 2-212
|
||||
Syracuse, NY, 13244-4100
|
||||
|
||||
phone: 1-315-443-3929, fax: 1-315-443-4745, email: <info@csteam.com>
|
||||
|
||||
The Computing Support Team offers a wide variety of support services
|
||||
including system design, installation, software support, contract
|
||||
programming, network design, integration and migration services,
|
||||
training, e-mail and telephone support. Experienced with GNU, X, TeX,
|
||||
and other public domain software.
|
||||
|
||||
Rates: $50-$80/hr, 33% non-profit discount.
|
||||
|
||||
Entered: 10 Jul 92
|
||||
|
||||
Contributed Software
|
||||
Graefestr. 76
|
||||
1000 Berlin 61, Germany
|
||||
phone: (+49 30) 694 69 07
|
||||
modems: (+49 30) 694 {61 82 | 67 49 | 68 09}
|
||||
email: <info@contrib.de>
|
||||
internet: scuzzy.contrib.de [192.109.39.1]
|
||||
|
||||
We distribute, install/port, teach and support free software
|
||||
in general, i.e. X11, GNU, khoros etc.
|
||||
Rates are DM 150,-- plus tax per hour, educational sites get rebates.
|
||||
|
||||
Entered: 10 Jul 92
|
||||
|
||||
Cygnus Support <info@cygnus.com>
|
||||
814 University Avenue ...uunet!cygint!info
|
||||
Palo Alto, CA 94301
|
||||
+1 415 322 3811 Voice
|
||||
+1 415 322 3270 FAX
|
||||
|
||||
Cygnus Support offers warranty protection (service contracts) for a
|
||||
number of free software tools. For a fixed annual fee our customers
|
||||
receive binary and source distributions, mail and phone support,
|
||||
documentation and customization assistance on a variety of popular
|
||||
platforms.
|
||||
|
||||
At the time of this writing we offer support for a development package
|
||||
including (among other things) gcc, g++, gdb, and of course, GNU
|
||||
Emacs. We also offer support for a network facilities package
|
||||
including many of the Athena tools like Kerberos and Hesiod. However
|
||||
the set of supported tools and platforms increases frequently so
|
||||
contact us for the latest information.
|
||||
|
||||
For those who need on-site assistance, support is also available from
|
||||
our Cambridge office.
|
||||
|
||||
Rates: $300/hour. Annual Support starts at $35,000.
|
||||
|
||||
Updated: 11 Sept 91
|
||||
|
||||
Bradley N. Davis <b-davis@jaguar.utah.edu>
|
||||
3242 South 540 West
|
||||
Bountiful, UT 84010
|
||||
(801) 298-6345
|
||||
|
||||
Will work on most GNU software. Especially GNU Emacs, GCC and a
|
||||
little X11 and G++. Experienced with PCs and 386s.
|
||||
|
||||
Services offered: Installation, porting, customizing, troubleshooting.
|
||||
|
||||
Fee: $20 to $50 / hour depending on job
|
||||
|
||||
Updated: 6/11/91
|
||||
|
||||
DePalma SoftCraft Contact: Mauro DePalma
|
||||
2923 Cohansey Drive Voice: (408) 259-4789
|
||||
San Jose, CA 95132-1619 Fax: (408) 259-6935
|
||||
Internet: <mauro@netcom.com> (or <apple!netcom!mauro>)
|
||||
|
||||
DePalma SoftCraft provides distribution, installation, setup, and
|
||||
support for the X Window System (X11R4).
|
||||
|
||||
This small business provides consulting in every area of a computer
|
||||
s/w project life cycle. We specialize in UNIX, GNU Development Tools
|
||||
(gcc, g++, ...), RCS, and XView.
|
||||
|
||||
Updated: 4/29/91
|
||||
|
||||
Equivalent Software HB <ingwa@isy.liu.se>
|
||||
Repslagaregatan 34 or <jonas-y@isy.liu.se>
|
||||
582 22 Linkoping
|
||||
SWEDEN
|
||||
+46 (0)13 13 54 21
|
||||
|
||||
Equivalent Software HB is the worlds second(?) company dedicated to
|
||||
supporting free UNIX software. The owners have more than 5 years of
|
||||
UNIX experience, both as system adminstrators and programmers. We
|
||||
also have extensive experience in maintaining the GNU programs, both
|
||||
administrating it and fixing bugs.
|
||||
|
||||
Services offered:
|
||||
|
||||
- Installation and custumizing GNU and other free software. We will
|
||||
make free software as easy to install and use as shrink wrapped
|
||||
programs.
|
||||
- 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. We prefer smaller jobs, but are willing to
|
||||
consider larger ones. We can work through the Internet, but prefer
|
||||
jobs in Sweden.
|
||||
|
||||
Rates: For software items, request our price list.
|
||||
For consulting, 450 SEK/hour.
|
||||
|
||||
Entered: 2/14/92
|
||||
|
||||
Andy Gaynor -- [Ag] <gaynor@paul.rutgers.edu>
|
||||
597 Hoes Lane, Piscataway, NJ 08854
|
||||
908-463-3376
|
||||
|
||||
GNU Emacs:
|
||||
Lisp development, customization, troubleshooting, support, etc
|
||||
User instruction and management for all levels of experience
|
||||
Umpteen-thousand lines of Lisp code, careful study of GNU Emacs organization,
|
||||
years of monitoring the UseNet Emacs and GNU groups, etc
|
||||
Version 19 is due soon -- I will be up-to-speed as quickly as possible
|
||||
$50/hour starting, negotiable on difficulty, organization, distribution, etc
|
||||
|
||||
Other Tasks:
|
||||
General programming/software engineering (language software preferred)
|
||||
Familiar with Unix, C, Lisp, networking, standard Unix utilities, various
|
||||
other languages, etc
|
||||
Contact me for more info
|
||||
|
||||
Entered: 10 Feb 92
|
||||
|
||||
Ron Guilmette <rfg@ncd.com>
|
||||
396 Ano Nuevo Ave. #216
|
||||
Sunnyvale, CA 94086
|
||||
408-732-7839
|
||||
|
||||
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.
|
||||
|
||||
Finished GCC2 port to the Intel i860 RISC processor.
|
||||
|
||||
Now developing GDB code for System V Release 4 support of
|
||||
ELF and Dwarf.
|
||||
|
||||
Experience: 9+ years UNIX systems experience, all working on compilers
|
||||
and related tools.
|
||||
|
||||
3+ 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:
|
||||
Holder of both a Bachelor's and a Master's degree, both in
|
||||
Computer Science.
|
||||
|
||||
Observer Member of ANSI X3J16 (C++ standardization) committee.
|
||||
|
||||
Former vice-chairman of UNIX International Programming
|
||||
Languages Special Interest Group (UI/PLSIG).
|
||||
|
||||
Rates: Variable depending upon contract duration. Call for quote.
|
||||
|
||||
Updated: 9 Feb 92
|
||||
|
||||
Johannes M. Heuft <ksh@pcs.com>
|
||||
Pfarrweg 2c
|
||||
D-8000 Munich 90
|
||||
Germany
|
||||
Telephone: Germany+89/681773
|
||||
|
||||
Rate: min. DM 180.- ($ 120.-) per hour
|
||||
interesting tasks for non-profit organisations may be free
|
||||
|
||||
Supported Programs: gcc, gas, g++, gdb, binutils, gnuplot, ...; (not emacs)
|
||||
|
||||
Experience: 10 years of operating system, network, and compiler
|
||||
construction; also includes engineering management.
|
||||
|
||||
Degrees: Dipl. Inform. (similar to MS CS)
|
||||
|
||||
Updated: 11/9/91
|
||||
|
||||
Sanjay Hiranandani <4393472@mcimail.com>
|
||||
16 Campus Plaza, Suite 180
|
||||
Vestal, NY 13850
|
||||
Work:607-729-7834 ext. 180
|
||||
Home:607-748-2709
|
||||
Fax:607-748-0243
|
||||
|
||||
Rate: $40/hr. Phone questions for free are ok as far as my schedule will permit
|
||||
Lower rates for students and certain non-profit organizations
|
||||
|
||||
Can help with installation/customization/modification of most GNU software.
|
||||
|
||||
Experience: Software Development, System Administration, and Consulting on
|
||||
a variety of computing platforms.
|
||||
|
||||
Updated: 11 Sept 91
|
||||
|
||||
Hundred Acre Software Consultants <info@pooh.com>
|
||||
1280 Terminal Way, Suite 26 <uunet!heather!info>
|
||||
Reno NV 89502-3243
|
||||
(702) 329-9333
|
||||
|
||||
Hundred Acre is a consulting group providing support and development
|
||||
services to organizations of all sizes. We support all kinds of publicly
|
||||
available software, not just GNU; write for the current list. We work on
|
||||
a "service contract" basis for support -- for a yearly fee, we provide email
|
||||
and toll free telephone support, and free updates and bug fixes. Certain
|
||||
support levels even have free on-site support. Development is charged on
|
||||
either an hourly or fixed bid basis.
|
||||
|
||||
Consulting rates: $50 to $70 per hour, or fixed bid.
|
||||
Support contracts: Several levels, from $500 to $30000 per year.
|
||||
|
||||
Updated: 2 Jul 91
|
||||
|
||||
Jose A. Fernandez <jaf@inference.com>
|
||||
|
||||
WORK: Inference Corporation HOME:
|
||||
550 N. Continental Blvd. 1025 Hillside Dr.
|
||||
El Segundo, CA 90245 Chino Hills, CA 91709
|
||||
(310) 322-0200 (714) 528-2523
|
||||
|
||||
RATES:
|
||||
$50-$200/hour plus expenses (or possibly free), depending on task.
|
||||
|
||||
SERVICES:
|
||||
GNU software: installation, troubleshooting, and customization.
|
||||
X11 software: installation and troubleshooting.
|
||||
SysAdmin: installation, configuration, and trouble-shooting.
|
||||
NetAdmin: installation, configuration, and trouble-shooting.
|
||||
Education: teaching how to fish opens the demand for fishing poles.
|
||||
Advice: free over email.
|
||||
|
||||
Entered: 10 Jul 92
|
||||
|
||||
Scott D. Kalter <sdk@twinsun.com>
|
||||
970 Palm Ave. #218
|
||||
West Hollywood, CA 90069
|
||||
Home: (213)657-9174
|
||||
Work: (213)524-1805
|
||||
|
||||
Emacs: e-lisp and C level customization/extension
|
||||
training for general use and customization
|
||||
user support, installation, troubleshooting
|
||||
Rates: approx. $50/hr, negotiable
|
||||
Very willing to answer quick questions for free.
|
||||
Prefer e-mail communication to telephone.
|
||||
|
||||
Qualifications: BS Math/CS 1985: Carnegie Mellon University
|
||||
MS CS 1988: UCLA
|
||||
Extensive e-lisp level modification for rapid prototyping of
|
||||
designs used in groupware research. Very familiar with all
|
||||
levels of elisp programming. Taught Emacs use and
|
||||
customization in universities and industry. Extensive
|
||||
troubleshooting and user support experience.
|
||||
|
||||
Updated:10/10/91
|
||||
|
||||
Scott J. Kramer <sjk@aura.nbn.com>
|
||||
P.O. Box 3392
|
||||
San Rafael, CA 94912
|
||||
+1 415-454-1295
|
||||
|
||||
Emacs: Tutoring, installations/upgrades, Lisp customizations,
|
||||
general troubleshooting/support. Prefer that work I do
|
||||
becomes part of the official Free Software Foundation
|
||||
distribution.
|
||||
|
||||
Rate: Task- and time-dependent; non-monetary offers considered.
|
||||
|
||||
Updated: 28Aug91
|
||||
|
||||
Fen Labalme <fen@well.sf.ca.us>
|
||||
Broadcatch Technologies
|
||||
40 Carl St. #4
|
||||
San Francisco CA 94117
|
||||
(415) 731-1174
|
||||
|
||||
Rates: Free phone consultation
|
||||
Extended project or consultation: $70/hour plus expenses
|
||||
Non-profits get lower rates or free; barter welcome!
|
||||
Emacs: Anything but specific termcap questions (general ones OK).
|
||||
Includes elisp extensions & teaching beginning or advanced users.
|
||||
Experience: I've been "hacking Emacs" for just about 15 years now.
|
||||
|
||||
Updated: 7/30/91
|
||||
|
||||
David C Lawrence <tale@cs.rpi.edu>
|
||||
P.O. Box 61
|
||||
North Chatham, NY 12132-0061
|
||||
Home:518 766-9098 Work:518 851-2813
|
||||
|
||||
Rates: $30 hour for projects less than 8 hours.
|
||||
$20 hour for longer projects.
|
||||
Course fees vary with level of subject being taught.
|
||||
Short queries answered free of charge.
|
||||
All rates negotiable.
|
||||
|
||||
Support: Emacs (both lisp and C aspects), GCC, GAWK, sed, fileutils,
|
||||
binutils, miscellaneous others. Definitely not G++.
|
||||
Consulting via email or telephone, or possibly on-site.
|
||||
|
||||
Updated: 11 Sept 91
|
||||
|
||||
Greg Lehey
|
||||
LEMIS
|
||||
Schellnhausen 2
|
||||
W-6324 Feldatal
|
||||
Germany
|
||||
|
||||
Phone: +49-6637-1488
|
||||
Fax: +49-6637-1489
|
||||
Mail <grog%lemis@Germany.EU.net>
|
||||
|
||||
Services: Supply, porting, installation, consultation on all GNU
|
||||
products.
|
||||
|
||||
Experience: 20 years OS and compiler experience, portations of most
|
||||
GNU products.
|
||||
|
||||
Entered: 10 Jul 92
|
||||
|
||||
Marty Leisner <leisner.henr801c@xerox.com>
|
||||
332 Shaftsbury Road
|
||||
Rochester, New York 14610
|
||||
Home:(716) 654-7931
|
||||
|
||||
Experience: 10 years C/Unix, 7 years DOS.
|
||||
Extensive experience with GNU binary tools, cross-compilers,
|
||||
embedded/hosted systems.
|
||||
Degree : BS CS, Cornell University
|
||||
Rates: $75/hr
|
||||
|
||||
Updated: 6 Jul 91
|
||||
|
||||
Roland McGrath <roland@ai.mit.edu>
|
||||
545 Tech Sq rm 426
|
||||
Cambridge, MA 02139
|
||||
Work:(617)253-8568
|
||||
|
||||
Co-author and maintainer of GNU Make (with Richard Stallman).
|
||||
Author and maintainer of the GNU C Library.
|
||||
FSF employee summer 1989, fall 1990 to the present.
|
||||
|
||||
Installation, maintenance, porting, enhancement of all GNU software.
|
||||
|
||||
Fees negotiable. I can work anywhere in the Boston or SF Bay Area, or
|
||||
anywhere on the Internet.
|
||||
|
||||
Updated: 12/15/90
|
||||
|
||||
Lee McLoughlin <lmjm@doc.ic.ac.uk>
|
||||
Department of Computing,
|
||||
Imperial College,
|
||||
180 Queens Gate,
|
||||
London
|
||||
SW7 2BZ,
|
||||
UK work: +44 71 589 5111 X 5085
|
||||
|
||||
gcc, emacs: can support and port to new machines
|
||||
other: some experience with most gnu packages
|
||||
|
||||
Ported emacs to two new platforms (WhiteChappel Worstations,
|
||||
HLH Orion). Worked on gcc port to Intergraph Clipper. Support
|
||||
various gnu packages as part of a teaching service.
|
||||
|
||||
Rates: Quick phone questions are free.
|
||||
|
||||
Degrees:.Sc(Hons) Computer Science
|
||||
|
||||
Other: I'm a general workaholic and well versed in compilers, communications
|
||||
and most things related to Unix.
|
||||
|
||||
Updated: 10.10.91
|
||||
|
||||
T.S.Mohan <mohan%vidya@shakti.ernet.in>
|
||||
KBCS Group <mohan@vigyan.ernet.in>
|
||||
Supercomputer Education and Research Centre
|
||||
Indian Institute of Science
|
||||
Bangalore 560 012
|
||||
INDIA
|
||||
Telephone (01-91-812)-341811, -341805
|
||||
|
||||
Rate: NIL. Availability for consultancy depends on
|
||||
work load. High preference for academic institutions.
|
||||
Support: emacs, gdb, gcc, g++ and other small public domain utilities
|
||||
Experience: Installed and supported these + other gnu programs in our
|
||||
centre for the past three years. General help to sister academic
|
||||
departments and other academic institutions.
|
||||
Degrees: Master of Engineering in CS. Currently working towards a PhD
|
||||
in Distributed computing and programming languages.
|
||||
|
||||
Updated: 1 Dec 1991
|
||||
|
||||
Mojave Systems <mojsys!support@uunet.uu.net>
|
||||
1254 Harvard Avenue
|
||||
Claremont, CA 91711
|
||||
714-621-7372
|
||||
|
||||
Mojave Systems offers porting services, warranty protection, and
|
||||
software support for several GNU products. Porting services are
|
||||
provided for a fixed fee. Software support is provided for fixed
|
||||
annual fee.
|
||||
|
||||
Mojave Systems is able to provide these services for a wide variety of
|
||||
hosts. We are currently porting GNU make and RCS to non-Unix hosts.
|
||||
|
||||
Entered: 12 Dec 90
|
||||
|
||||
Eric Raible <raible@nas.nasa.gov>
|
||||
Nasa Ames Research Center
|
||||
Mail Stop T045-1
|
||||
Moffett Field, CA, 94035
|
||||
(415) 604-4320 (W)
|
||||
|
||||
Rates: $40 hour; email questions free.
|
||||
|
||||
Gnu emacs C/lisp programming and porting. General
|
||||
unix/graphics/emacs hacking, especially on Silicon Graphics
|
||||
workstations.
|
||||
|
||||
Degree: MIT 83 BS CS.
|
||||
|
||||
Updated: 11 Sept 91
|
||||
|
||||
Paul Reilly <reilly@dg-rtp.dg.com>
|
||||
721 Bennington Drive
|
||||
Raleigh, NC 27615
|
||||
Work: 919 248 6210
|
||||
Home: 919 847 7294
|
||||
|
||||
Services: access, installation, porting, customizing and debugging
|
||||
Unix Free software: X11, GNU, TeX, etc.
|
||||
|
||||
Rates: $150/hour
|
||||
|
||||
Updated: Dec 1991
|
||||
|
||||
Adam J. Richter <adam@soda.berkeley.edu> ...!ucbvax!soda!adam
|
||||
409 Evelyn Avenue, Apartment 312 (510) 528-3209
|
||||
Albany, CA 94706 fax: (510) 528-8508
|
||||
|
||||
X windows server expert. Freeware (especially copylefted) projects
|
||||
preferred.
|
||||
|
||||
Updated: 18 Nov 91
|
||||
|
||||
Wolfgang S. Rupprecht <wolfgang@wsrcc.com>
|
||||
PO Box 6524 <uunet!wsrcc!wolfgang>
|
||||
Alexandria, VA 22306-0524 <wolfgang%wsrcc.com@uunet.uu.net>
|
||||
(703) 768-2640
|
||||
|
||||
Emacs: 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 to appear in Emacs 19.
|
||||
|
||||
Rates: $75/hr.
|
||||
|
||||
Updated: 7/20/91
|
||||
|
||||
John Sechrest
|
||||
Jasmic Systems Internet: <sechrest@jasmic.uucp>
|
||||
2140 SW 49th St. UUCP: <hp-pcd!orstcs!jasmic!sechrest>
|
||||
Corvallis, Oregon 97333
|
||||
|
||||
Gnu software: Questions about gnu emacs general use, training and classes,
|
||||
documentation, system set up and design.
|
||||
|
||||
Experience: 11 years of Unix work. Heavy on System administration.
|
||||
Teaching classes in Unix system administraion, Unix
|
||||
Kernal Programming, Networking and Consulting services.
|
||||
Currently working as the Support Coordinator for
|
||||
Oregon State University (for 8 years).
|
||||
|
||||
Familiar with BSD systems mostly. Some SysVR4.
|
||||
I have supported VAxes, HP's with HPUX, HP's with 4.3 BSD,
|
||||
Sequent's, Next's and a few other misc. machines.
|
||||
|
||||
Updated: 28 Oct 1991
|
||||
|
||||
Steve Simmons <scs@lokkur.dexter.mi.us>
|
||||
Inland Sea
|
||||
9353 Hidden Lake Circle
|
||||
Dexter, MI 48130
|
||||
313-769-4086 (office1)
|
||||
313-426-2086 (office2)
|
||||
|
||||
Rate: $75.00/hr for straight time until Jan 1, 1992. Rates will go up
|
||||
an undetermined amount at that time. Free advice for short questions
|
||||
by phone or email.
|
||||
|
||||
Programs Supported: Any. Quality of support I can offer depends on
|
||||
the nature of the software; in particular I am *not* a compiler person.
|
||||
|
||||
Experiance: 13 years in computing, 10 with UNIX and various derivatives.
|
||||
Specialist in systems administration. Lots of network admin.
|
||||
|
||||
Degree: Bachelors from University of Michigan, 1980.
|
||||
|
||||
Updated: 10 Oct 91
|
||||
|
||||
Lynn Slater <lrs@indetech.com>
|
||||
42075 Lawrence Place
|
||||
Fremont Ca 94538
|
||||
Office (415) 438-2048; Home (415) 793-1864; Fax (415) 438-2034
|
||||
|
||||
Programs: Gnu Emacs Ada Mode, Gnu Emacs Empire Tool, Emacs,
|
||||
g++ and gnumake (limited support only).
|
||||
|
||||
Experiance:
|
||||
Gnu Emacs Ada Mode -- Co-author, principle integrator
|
||||
Gnu Emacs Empire Tool -- Originator, co-author, principle distributor
|
||||
Emacs -- Almost all parts. Authored super-apropos, headers, first GDB
|
||||
interface, fancy-lisp, enhanced scribe mode,and lots of small stuff
|
||||
g++ -- Have maintained, modified, and used G++ on 300+ user commercial
|
||||
OLTP software.
|
||||
gnumake -- Have bug fixed and extended.
|
||||
|
||||
Have single makefile that can merge in local changes and build the
|
||||
following systems in a consistent manner in multiple releases on multiple
|
||||
machines:
|
||||
asm, bison, gcc, g++, emacs, rcs, gdb, libg++, att c++ libs, gnumake,
|
||||
diff, tex2iroff
|
||||
The makefile and related techniques are a bit hard to explain, but they
|
||||
enable use and local changes in a broad spectrum of FSF code on many
|
||||
platforms without having to remember all the individual make procedures.
|
||||
|
||||
Rate: Free for good cause or short stuff as there is time.
|
||||
Am most likely to help in areas in which I have had problems or expect to
|
||||
have problems.
|
||||
|
||||
Updated: 10 Oct 91
|
||||
|
||||
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: 11 Sept 91
|
||||
|
||||
Randall D. Smith <randy@ai.mit.edu>
|
||||
20 Watson Street
|
||||
Cambridge, MA 02139, USA
|
||||
+1 (617) 983-0276
|
||||
|
||||
Will work on most GNU software.
|
||||
Installation, handholding, trouble shooting, extensions, teaching,
|
||||
GCC, GDB, GNU-EMACS, and other ports.
|
||||
|
||||
Rates: Upward from $50.00/hour depending on my expertise in the area of the
|
||||
job. GDB consulting at $80.00/hour.
|
||||
|
||||
Experience: 4 years of intensive experience with Unix and C including
|
||||
system hacking and modification. Experience in porting GNU-EMACS (to
|
||||
SGI Iris 4D) and GCC (to use Sun FPA chip). Experience working
|
||||
full-time for the GNU project on other GNU programs (June 1988 -
|
||||
August 1989). Primary maintainer of GDB and the GNU loader for that
|
||||
period. Resume available on request.
|
||||
|
||||
Entered: 10 Feb 92
|
||||
|
||||
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.
|
||||
|
||||
Entered: 5/24/90
|
||||
|
||||
Jonathan Stone <jonathan@isor.vuw.ac.nz>
|
||||
c/o- Institute of Statistics and Operations Research
|
||||
Victoria University of Wellington
|
||||
P.O Box 600
|
||||
Wellington
|
||||
New Zealand
|
||||
Work: +64 4 715-315 Fax: +64 4 712-070
|
||||
|
||||
Rate: hourly rate: NZ $ 150/hr. Quick phone questions are free.
|
||||
Reduced rates available for for non-profit/educational insts
|
||||
and daily rate work. Fixed-price contracts also considered.
|
||||
|
||||
Programs: GNU Emacs, GCC, GDB, GNU binutils,
|
||||
Ghostscript, MIT X11
|
||||
I am the author of the Pyramid ports of gcc and gdb.
|
||||
|
||||
Experiance: Five years administration of Unix systems and GNU tools
|
||||
in University environments, and support of Unix administrators
|
||||
and GNU tools as an external contractor to New Zealand Government
|
||||
departments.
|
||||
|
||||
Degrees: M.Sc (Distinction) for a thesis involving work done on GCC.
|
||||
|
||||
Updated: 28 Aug 91
|
||||
|
||||
Bob Sutterfield <bob@morningstar.com>
|
||||
|
||||
work: home:
|
||||
Morning Star Technologies
|
||||
1760 Zollinger Road 3542 Norwood Street
|
||||
Columbus, Ohio 43221 USA Columbus, Ohio 43224-3424 USA
|
||||
(614)451-1883 (614)267-7611
|
||||
|
||||
Rates: $50/hr (negotiable) plus travel expenses
|
||||
Gratis to Christian missionaries and mission agencies
|
||||
|
||||
Services: Installation, troubleshooting, and mild customization of
|
||||
most GNU production and beta-test software; tutorials, training,
|
||||
and handholding; general UNIX system and network consulting.
|
||||
|
||||
Entered: 2/16/92
|
||||
|
||||
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.3BSD, SVR3 and
|
||||
SVR4, 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: 10 Jul 92
|
||||
|
||||
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: 12 Feb 92
|
||||
|
||||
Watchmaker Computing <support@watch.com>
|
||||
P.O.Box 163, Kendall Square
|
||||
Cambridge, MA 02142
|
||||
email: support@watch.com
|
||||
|
||||
Emacs: We'll do GNUEmacs support, porting, bug fixing, and customizing.
|
||||
We also have specific expertise in:
|
||||
packages: GCC, G++, X11, Xt, InterViews, PERL, TeX, Epoch
|
||||
languages: C, C++, Lisp, most others; we learn quickly!
|
||||
Extensive experience coding for portability under UNIX.
|
||||
Typical rates $35-$150/hour; will telecommute (Internet or phone)
|
||||
|
||||
Entered: 1/16/91
|
||||
|
||||
Chris Welty <weltyc@cs.rpi.edu>
|
||||
RPI Computer Science Dept
|
||||
Troy, NY 12180
|
||||
518-276-2816 (W)
|
||||
|
||||
EMail correspondance preferred.
|
||||
Rates vary depending on need, barter often accepted.
|
||||
|
||||
Programs: emacs, especially emacs lisp.
|
||||
Lots of experience in various areas.
|
||||
BS, MS from RPI. Currently working on PhD.
|
||||
|
||||
Updated: 10/10/91
|
||||
|
||||
Pace Willisson <pace@blitz.com>
|
||||
Blitz Product Development Corporation <uunet!blitz!pace>
|
||||
4 Spruce Road
|
||||
Medway, MA 02053, USA
|
||||
Work: (508) 533-6430
|
||||
|
||||
Rates: $80.00/hour
|
||||
|
||||
Will work on any GNU software.
|
||||
|
||||
Experience: 12 years working with C, Unix and Lisp Machines including
|
||||
compilation systems, networks, device drivers, demand paging systems,
|
||||
boot programs and window systems. Ported GDB to 80386. Designed COFF
|
||||
encapsulation scheme to run GNU linker output on System 5 kernels.
|
||||
Author of Unix "ispell".
|
||||
|
||||
Degree: BS in Computer Science from MIT
|
||||
|
||||
Updated: 7/31/91
|
||||
|
||||
Patrick Wood
|
||||
Pipeline Associates, Inc.
|
||||
2740 Route 10 West
|
||||
Morris Plains, NJ 07950
|
||||
|
||||
Rate: Free
|
||||
Support For: gcc, binutils, gnulib, using gcc for cross compiling
|
||||
Experiance: used gcc for cross compiling for over 2 years; used
|
||||
gcc for three years; installed and support gcc on several
|
||||
BSD and System V UNIX systems; wrote peephole optimizer for
|
||||
gcc on 68K, wrote portable replacement for FP routines in
|
||||
gnulib.c. Modified gcc and binutils to work in byte-swapped
|
||||
environments.
|
||||
Other: email consulting only <pipeline!phw@motown.com>,
|
||||
uunet!motown!pipeline!phw,sun!pipeline!phw, amdcad!pipeline!phw
|
||||
|
||||
Updated: 18 Sept 91
|
||||
|
||||
xprt Computer Consulting, Inc. <jody@shell.com>
|
||||
17200 El Camino Real Suite 110 T
|
||||
Houston, TX 77058
|
||||
(713) 480 UNIX
|
||||
(713) 486 8575 (Fax)
|
||||
|
||||
Programs Supported:
|
||||
X11, TeX, and all of GNU.
|
||||
|
||||
Experience:
|
||||
We have supported and maintained all of GNU, X11 and TeX for over four
|
||||
years for a major oil company's research division on several different
|
||||
Unix platforms.
|
||||
|
||||
Rates: $150/hour
|
||||
|
||||
Entered: 10 Jul 92
|
||||
|
||||
Name: david d [zoo] zuhn <zuhn@cs.umn.edu>
|
||||
Company: armadillo zoo software
|
||||
Fees: $50/hour, discounts for educational institutions and non-profits
|
||||
|
||||
GNU and X11 installation and maintainance on SGI Iris, Sun [68k &
|
||||
SPARC], and Sequent machines. Additional machines a possibility.
|
||||
Any GNU software installed. Most supported.
|
||||
|
||||
Updated: 7/11/92
|
||||
|
||||
** Please keep this file alphabetical **
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This progam 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.
|
||||
*
|
||||
* Alliance VLSI CAD System 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 the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
alloca -- (mostly) portable public-domain implementation -- D A Gwyn
|
||||
|
||||
last edit: 86/05/30 rms
|
||||
include config.h, since on VMS it renames some symbols.
|
||||
Use xmalloc instead of malloc.
|
||||
|
||||
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.
|
||||
|
||||
It should work under any C implementation that uses an
|
||||
actual procedure stack (as opposed to a linked list of
|
||||
frames). 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.
|
||||
*/
|
||||
#ifndef lint
|
||||
static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */
|
||||
#endif
|
||||
|
||||
#ifdef emacs
|
||||
#include "config.h"
|
||||
#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
|
||||
|
||||
#ifdef X3J11
|
||||
typedef void *pointer; /* generic pointer type */
|
||||
#else
|
||||
typedef char *pointer; /* generic pointer type */
|
||||
#endif
|
||||
|
||||
#define NULL 0 /* null pointer constant */
|
||||
|
||||
extern void free();
|
||||
extern pointer xmalloc();
|
||||
|
||||
/*
|
||||
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 (/* void */)
|
||||
{
|
||||
static char *addr = NULL; /* address of first
|
||||
`dummy', once known */
|
||||
auto char dummy; /* to get stack address */
|
||||
|
||||
if (addr == NULL)
|
||||
{ /* initial entry */
|
||||
addr = &dummy;
|
||||
|
||||
find_stack_direction (); /* recurse once */
|
||||
}
|
||||
else /* second entry */
|
||||
if (&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;
|
||||
|
||||
/*
|
||||
alloca( size ) returns 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.
|
||||
*/
|
||||
|
||||
static header *last_alloca_header = NULL; /* -> last alloca header */
|
||||
|
||||
pointer
|
||||
alloca (size) /* returns pointer to storage */
|
||||
unsigned size; /* # bytes to allocate */
|
||||
{
|
||||
auto char probe; /* probes stack depth: */
|
||||
register char *depth = &probe;
|
||||
|
||||
#if STACK_DIRECTION == 0
|
||||
if (STACK_DIR == 0) /* unknown growth direction */
|
||||
find_stack_direction ();
|
||||
#endif
|
||||
|
||||
/* Reclaim garbage, defined as all alloca()ed storage that
|
||||
was allocated from deeper in the stack than currently. */
|
||||
|
||||
{
|
||||
register header *hp; /* traverses linked list */
|
||||
|
||||
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 */
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
return NULL; /* no allocation required */
|
||||
|
||||
/* Allocate combined header + user data storage. */
|
||||
|
||||
{
|
||||
register pointer new = xmalloc (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));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This progam 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.
|
||||
*
|
||||
* Alliance VLSI CAD System 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 the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* 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
|
||||
|
||||
void __eprintf (); /* Defined in gnulib */
|
||||
|
||||
#ifdef __STDC__
|
||||
|
||||
#define assert(expression) \
|
||||
((void) ((expression) ? 0 : __assert (#expression, __FILE__, __LINE__)))
|
||||
|
||||
#define __assert(expression, file, lineno) \
|
||||
(__eprintf ("Failed assertion `%s' at line %d of `%s'.\n", \
|
||||
expression, lineno, file), 0)
|
||||
|
||||
#else /* no __STDC__; i.e. -traditional. */
|
||||
|
||||
#define assert(expression) \
|
||||
((void) ((expression) ? 0 : __assert (expression, __FILE__, __LINE__)))
|
||||
|
||||
#define __assert(expression, file, lineno) \
|
||||
(__eprintf ("Failed assertion `%s' at line %d of `%s'.\n", \
|
||||
"expression", lineno, file), 0)
|
||||
|
||||
#endif /* no __STDC__; i.e. -traditional. */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This progam 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.
|
||||
*
|
||||
* Alliance VLSI CAD System 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 the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Description de la machine virtuelle
|
||||
*
|
||||
* Ecrit par Arnaud COMPAN & Francois PECHEUX ** avril-juin 1990
|
||||
* Avec quelques modifications par Frederic Petrot.
|
||||
*/
|
||||
|
||||
#ifndef FILE
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#define AT_SP(mode) (gen_rtx (MEM, (mode), stack_pointer_rtx))
|
||||
#define AT_BP(mode) (gen_rtx (MEM, (mode), frame_pointer_rtx))
|
||||
|
||||
#define RET return ""
|
||||
|
||||
#define RETCOM(X) return ""
|
||||
|
||||
extern FILE *asm_out_file;
|
||||
static char *singlemove_string ();
|
||||
static void output_movf ();
|
||||
static void replace_float_constant ();
|
||||
static int mentions_fp_top ();
|
||||
static int call_top_dead_p ();
|
||||
static int fp_top_dead_p1 ();
|
||||
static rtx via_memory ();
|
||||
static void output_asm_insn_double_reg_op ();
|
||||
|
||||
#define PRINT_REG(X, CODE, FILE) fprintf (FILE, "%s", reg_name[REGNO (X)])
|
||||
|
||||
notice_update_cc(exp)
|
||||
rtx exp;
|
||||
{
|
||||
if (GET_CODE (exp) == SET) {
|
||||
if (SET_DEST (exp) == pc_rtx)
|
||||
return;
|
||||
if (REG_P (SET_DEST (exp))
|
||||
&& (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM)) {
|
||||
if (cc_status.value1
|
||||
&& reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
|
||||
cc_status.value1 = 0;
|
||||
if (cc_status.value2
|
||||
&& reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
|
||||
cc_status.value2 = 0;
|
||||
return;
|
||||
}
|
||||
if (GET_CODE (SET_DEST (exp)) == MEM && REG_P (SET_SRC (exp))) {
|
||||
if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
|
||||
cc_status.value1 = 0;
|
||||
if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
|
||||
cc_status.value2 = 0;
|
||||
return;
|
||||
} else if (GET_CODE (SET_SRC (exp)) == CALL) {
|
||||
CC_STATUS_INIT;
|
||||
return;
|
||||
} else if (SET_DEST (exp) == cc0_rtx) {
|
||||
CC_STATUS_INIT;
|
||||
cc_status.value1 = SET_SRC (exp);
|
||||
return;
|
||||
} else if (GET_MODE (SET_SRC (exp)) == SImode)
|
||||
switch (GET_CODE (SET_SRC (exp))) {
|
||||
case ASHIFTRT:
|
||||
case LSHIFTRT:
|
||||
case ASHIFT:
|
||||
case LSHIFT:
|
||||
if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT) {
|
||||
CC_STATUS_INIT;
|
||||
break;
|
||||
}
|
||||
case PLUS:
|
||||
case MINUS:
|
||||
case NEG:
|
||||
case AND:
|
||||
case IOR:
|
||||
case XOR:
|
||||
cc_status.flags = CC_NO_OVERFLOW;
|
||||
cc_status.value1 = SET_SRC (exp);
|
||||
cc_status.value2 = SET_DEST (exp);
|
||||
break;
|
||||
default:
|
||||
CC_STATUS_INIT;
|
||||
}
|
||||
else
|
||||
CC_STATUS_INIT;
|
||||
} else if (GET_CODE (exp) == PARALLEL
|
||||
&& GET_CODE (XVECEXP (exp, 0, 0)) == SET) {
|
||||
if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
|
||||
return;
|
||||
if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx) {
|
||||
CC_STATUS_INIT;
|
||||
cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
|
||||
return;
|
||||
}
|
||||
CC_STATUS_INIT;
|
||||
} else
|
||||
CC_STATUS_INIT;
|
||||
}
|
||||
|
||||
output_ascii(file, p, size)
|
||||
FILE *file;
|
||||
char *p;
|
||||
int size;
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf (file, "\t.string \"");
|
||||
for (i = 0; i < size; i++) {
|
||||
register int c = p[i];
|
||||
if (c == '\"' || c == '\\')
|
||||
putc ('\\', file);
|
||||
if (c >= ' ' && c < 0177)
|
||||
putc (c, file);
|
||||
else {
|
||||
fprintf (file, "\\%03o", c);
|
||||
if (i < size - 1 && p[i + 1] >= '0' && p[i + 1] <= '9')
|
||||
fprintf (file, "\"\n\tstring \"");
|
||||
}
|
||||
}
|
||||
fprintf (file, "\"\n");
|
||||
}
|
||||
|
||||
int ever_good(op, mode)
|
||||
register rtx op;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int no_good(op, mode)
|
||||
register rtx op;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This progam 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.
|
||||
*
|
||||
* Alliance VLSI CAD System 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 the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* 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 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
/* Define the type for a pointer to a set with a bit for each
|
||||
(hard or pseudo) register. */
|
||||
|
||||
typedef long *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 bits in each actual element of a regset. */
|
||||
|
||||
#define REGSET_ELT_BITS HOST_BITS_PER_INT
|
||||
|
||||
/* 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 short *reg_basic_block;
|
|
@ -0,0 +1,420 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This progam 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.
|
||||
*
|
||||
* Alliance VLSI CAD System 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 the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Language-level data type conversion for GNU C.
|
||||
Copyright (C) 1987, 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 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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"
|
||||
|
||||
/* 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 c-convert.c, convert_to_integer.
|
||||
In c-typeck.c, build_binary_op_nodefault (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'. */
|
||||
|
||||
static tree
|
||||
convert_to_pointer (type, expr)
|
||||
tree type, expr;
|
||||
{
|
||||
register tree intype = TREE_TYPE (expr);
|
||||
register enum tree_code form = TREE_CODE (intype);
|
||||
|
||||
if (integer_zerop (expr))
|
||||
{
|
||||
if (type == TREE_TYPE (null_pointer_node))
|
||||
return null_pointer_node;
|
||||
expr = build_int_2 (0, 0);
|
||||
TREE_TYPE (expr) = type;
|
||||
return expr;
|
||||
}
|
||||
|
||||
if (form == POINTER_TYPE)
|
||||
return build (NOP_EXPR, type, expr);
|
||||
|
||||
|
||||
if (form == INTEGER_TYPE || form == ENUMERAL_TYPE)
|
||||
{
|
||||
if (type_precision (intype) == POINTER_SIZE)
|
||||
return build (CONVERT_EXPR, type, expr);
|
||||
return convert_to_pointer (type,
|
||||
convert (type_for_size (POINTER_SIZE, 0),
|
||||
expr));
|
||||
}
|
||||
|
||||
error ("cannot convert to a pointer type");
|
||||
|
||||
return null_pointer_node;
|
||||
}
|
||||
|
||||
static tree
|
||||
convert_to_real (type, expr)
|
||||
tree type, expr;
|
||||
{
|
||||
register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
|
||||
extern int flag_float_store;
|
||||
|
||||
if (form == REAL_TYPE)
|
||||
return build (flag_float_store ? CONVERT_EXPR : NOP_EXPR,
|
||||
type, expr);
|
||||
|
||||
if (form == INTEGER_TYPE || form == ENUMERAL_TYPE)
|
||||
return build (FLOAT_EXPR, type, expr);
|
||||
|
||||
if (form == POINTER_TYPE)
|
||||
error ("pointer value used where a float was expected");
|
||||
else
|
||||
error ("aggregate value used where a float was expected");
|
||||
|
||||
{
|
||||
register tree tem = make_node (REAL_CST);
|
||||
TREE_TYPE (tem) = type;
|
||||
TREE_REAL_CST (tem) = REAL_VALUE_ATOF ("0.0");
|
||||
return tem;
|
||||
}
|
||||
}
|
||||
|
||||
/* The result of this is always supposed to be a newly created tree node
|
||||
not in use in any existing structure. */
|
||||
|
||||
static tree
|
||||
convert_to_integer (type, expr)
|
||||
tree type, expr;
|
||||
{
|
||||
register tree intype = TREE_TYPE (expr);
|
||||
register enum tree_code form = TREE_CODE (intype);
|
||||
extern tree build_binary_op_nodefault ();
|
||||
extern tree build_unary_op ();
|
||||
|
||||
if (form == POINTER_TYPE)
|
||||
{
|
||||
if (integer_zerop (expr))
|
||||
expr = integer_zero_node;
|
||||
else
|
||||
expr = fold (build (CONVERT_EXPR,
|
||||
type_for_size (POINTER_SIZE, 0), expr));
|
||||
intype = TREE_TYPE (expr);
|
||||
form = TREE_CODE (intype);
|
||||
if (intype == type)
|
||||
return expr;
|
||||
}
|
||||
|
||||
if (form == INTEGER_TYPE || form == ENUMERAL_TYPE)
|
||||
{
|
||||
register int outprec = TYPE_PRECISION (type);
|
||||
register int inprec = TYPE_PRECISION (intype);
|
||||
register enum tree_code ex_form = TREE_CODE (expr);
|
||||
|
||||
if (outprec >= inprec)
|
||||
return build (NOP_EXPR, type, expr);
|
||||
|
||||
/* Here detect when we can distribute the truncation down past some arithmetic.
|
||||
For example, if adding two longs and converting to an int,
|
||||
we can equally well convert both to ints and then add.
|
||||
For the operations handled here, such truncation distribution
|
||||
is always safe.
|
||||
It is desirable in these cases:
|
||||
1) when truncating down to full-word from a larger size
|
||||
2) when truncating takes no work.
|
||||
3) when at least one operand of the arithmetic has been extended
|
||||
(as by C's default conversions). In this case we need two conversions
|
||||
if we do the arithmetic as already requested, so we might as well
|
||||
truncate both and then combine. Perhaps that way we need only one.
|
||||
|
||||
Note that in general we cannot do the arithmetic in a type
|
||||
shorter than the desired result of conversion, even if the operands
|
||||
are both extended from a shorter type, because they might overflow
|
||||
if combined in that type. The exceptions to this--the times when
|
||||
two narrow values can be combined in their narrow type even to
|
||||
make a wider result--are handled by "shorten" in build_binary_op. */
|
||||
|
||||
switch (ex_form)
|
||||
{
|
||||
case RSHIFT_EXPR:
|
||||
/* We can pass truncation down through right shifting
|
||||
when the shift count is a negative constant. */
|
||||
if (TREE_CODE (TREE_OPERAND (expr, 1)) != INTEGER_CST
|
||||
|| TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)) > 0)
|
||||
break;
|
||||
goto trunc1;
|
||||
|
||||
case LSHIFT_EXPR:
|
||||
/* We can pass truncation down through left shifting
|
||||
when the shift count is a positive constant. */
|
||||
if (TREE_CODE (TREE_OPERAND (expr, 1)) != INTEGER_CST
|
||||
|| TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)) < 0)
|
||||
break;
|
||||
/* In this case, shifting is like multiplication. */
|
||||
goto trunc1;
|
||||
|
||||
case MAX_EXPR:
|
||||
case MIN_EXPR:
|
||||
case MULT_EXPR:
|
||||
{
|
||||
tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
|
||||
tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
|
||||
|
||||
/* Don't distribute unless the output precision is at least as big
|
||||
as the actual inputs. Otherwise, the comparison of the
|
||||
truncated values will be wrong. */
|
||||
if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
|
||||
&& outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
|
||||
/* If signedness of arg0 and arg1 don't match,
|
||||
we can't necessarily find a type to compare them in. */
|
||||
&& (TREE_UNSIGNED (TREE_TYPE (arg0))
|
||||
== TREE_UNSIGNED (TREE_TYPE (arg1))))
|
||||
goto trunc1;
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUS_EXPR:
|
||||
case MINUS_EXPR:
|
||||
case BIT_AND_EXPR:
|
||||
case BIT_IOR_EXPR:
|
||||
case BIT_XOR_EXPR:
|
||||
case BIT_ANDTC_EXPR:
|
||||
trunc1:
|
||||
{
|
||||
tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
|
||||
tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
|
||||
|
||||
if (outprec >= BITS_PER_WORD
|
||||
|| TRULY_NOOP_TRUNCATION (outprec, inprec)
|
||||
|| inprec > TYPE_PRECISION (TREE_TYPE (arg0))
|
||||
|| inprec > TYPE_PRECISION (TREE_TYPE (arg1)))
|
||||
{
|
||||
/* Do the arithmetic in type TYPEX,
|
||||
then convert result to TYPE. */
|
||||
register tree typex = type;
|
||||
|
||||
/* Can't do arithmetic in enumeral types
|
||||
so use an integer type that will hold the values. */
|
||||
if (TREE_CODE (typex) == ENUMERAL_TYPE)
|
||||
typex = type_for_size (TYPE_PRECISION (typex),
|
||||
TREE_UNSIGNED (typex));
|
||||
|
||||
/* But now perhaps TYPEX is as wide as INPREC.
|
||||
In that case, do nothing special here.
|
||||
(Otherwise would recurse infinitely in convert. */
|
||||
if (TYPE_PRECISION (typex) != inprec)
|
||||
{
|
||||
/* Don't do unsigned arithmetic where signed was wanted,
|
||||
or vice versa.
|
||||
Exception: if the original operands were unsigned
|
||||
then can safely do the work as unsigned.
|
||||
And we may need to do it as unsigned
|
||||
if we truncate to the original size. */
|
||||
typex = ((TREE_UNSIGNED (TREE_TYPE (expr))
|
||||
|| TREE_UNSIGNED (TREE_TYPE (arg0)))
|
||||
? unsigned_type (typex) : signed_type (typex));
|
||||
return convert (type,
|
||||
build_binary_op_nodefault (ex_form,
|
||||
convert (typex, arg0),
|
||||
convert (typex, arg1),
|
||||
ex_form));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EQ_EXPR:
|
||||
case NE_EXPR:
|
||||
case GT_EXPR:
|
||||
case GE_EXPR:
|
||||
case LT_EXPR:
|
||||
case LE_EXPR:
|
||||
case TRUTH_AND_EXPR:
|
||||
case TRUTH_ANDIF_EXPR:
|
||||
case TRUTH_OR_EXPR:
|
||||
case TRUTH_ORIF_EXPR:
|
||||
case TRUTH_NOT_EXPR:
|
||||
/* If we want result of comparison converted to a byte,
|
||||
we can just regard it as a byte, since it is 0 or 1. */
|
||||
TREE_TYPE (expr) = type;
|
||||
return expr;
|
||||
|
||||
case NEGATE_EXPR:
|
||||
case BIT_NOT_EXPR:
|
||||
case ABS_EXPR:
|
||||
{
|
||||
register tree typex = type;
|
||||
|
||||
/* Can't do arithmetic in enumeral types
|
||||
so use an integer type that will hold the values. */
|
||||
if (TREE_CODE (typex) == ENUMERAL_TYPE)
|
||||
typex = type_for_size (TYPE_PRECISION (typex),
|
||||
TREE_UNSIGNED (typex));
|
||||
|
||||
/* But now perhaps TYPEX is as wide as INPREC.
|
||||
In that case, do nothing special here.
|
||||
(Otherwise would recurse infinitely in convert. */
|
||||
if (TYPE_PRECISION (typex) != inprec)
|
||||
{
|
||||
/* Don't do unsigned arithmetic where signed was wanted,
|
||||
or vice versa. */
|
||||
typex = (TREE_UNSIGNED (TREE_TYPE (expr))
|
||||
? unsigned_type (typex) : signed_type (typex));
|
||||
return convert (type,
|
||||
build_unary_op (ex_form,
|
||||
convert (typex, TREE_OPERAND (expr, 0)),
|
||||
1));
|
||||
}
|
||||
}
|
||||
|
||||
case NOP_EXPR:
|
||||
/* If truncating after truncating, might as well do all at once.
|
||||
If truncating after extending, we may get rid of wasted work. */
|
||||
return convert (type, get_unwidened (TREE_OPERAND (expr, 0), type));
|
||||
|
||||
case COND_EXPR:
|
||||
/* Can treat the two alternative values like the operands
|
||||
of an arithmetic expression. */
|
||||
{
|
||||
tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
|
||||
tree arg2 = get_unwidened (TREE_OPERAND (expr, 2), type);
|
||||
|
||||
if (outprec >= BITS_PER_WORD
|
||||
|| TRULY_NOOP_TRUNCATION (outprec, inprec)
|
||||
|| inprec > TYPE_PRECISION (TREE_TYPE (arg1))
|
||||
|| inprec > TYPE_PRECISION (TREE_TYPE (arg2)))
|
||||
{
|
||||
/* Do the arithmetic in type TYPEX,
|
||||
then convert result to TYPE. */
|
||||
register tree typex = type;
|
||||
|
||||
/* Can't do arithmetic in enumeral types
|
||||
so use an integer type that will hold the values. */
|
||||
if (TREE_CODE (typex) == ENUMERAL_TYPE)
|
||||
typex = type_for_size (TYPE_PRECISION (typex),
|
||||
TREE_UNSIGNED (typex));
|
||||
|
||||
/* But now perhaps TYPEX is as wide as INPREC.
|
||||
In that case, do nothing special here.
|
||||
(Otherwise would recurse infinitely in convert. */
|
||||
if (TYPE_PRECISION (typex) != inprec)
|
||||
{
|
||||
/* Don't do unsigned arithmetic where signed was wanted,
|
||||
or vice versa. */
|
||||
typex = (TREE_UNSIGNED (TREE_TYPE (expr))
|
||||
? unsigned_type (typex) : signed_type (typex));
|
||||
return convert (type,
|
||||
build (COND_EXPR, typex,
|
||||
TREE_OPERAND (expr, 0),
|
||||
convert (typex, arg1),
|
||||
convert (typex, arg2)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return build (NOP_EXPR, type, expr);
|
||||
}
|
||||
|
||||
if (form == REAL_TYPE)
|
||||
return build (FIX_TRUNC_EXPR, type, expr);
|
||||
|
||||
error ("aggregate value used where an integer was expected");
|
||||
|
||||
{
|
||||
register tree tem = build_int_2 (0, 0);
|
||||
TREE_TYPE (tem) = type;
|
||||
return tem;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 (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 build (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));
|
||||
|
||||
error ("conversion to non-scalar type requested");
|
||||
return error_mark_node;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,56 @@
|
|||
%{
|
||||
/* 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; };
|
||||
%%
|
||||
__alignof, ALIGNOF, NORID
|
||||
__alignof__, ALIGNOF, NORID
|
||||
__asm, ASM, NORID
|
||||
__asm__, ASM, NORID
|
||||
__attribute, ATTRIBUTE, NORID
|
||||
__attribute__, ATTRIBUTE, NORID
|
||||
__const, TYPE_QUAL, RID_CONST
|
||||
__const__, TYPE_QUAL, RID_CONST
|
||||
__inline, SCSPEC, RID_INLINE
|
||||
__inline__, SCSPEC, RID_INLINE
|
||||
__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, NORID
|
||||
auto, SCSPEC, RID_AUTO
|
||||
break, BREAK, NORID
|
||||
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
|
||||
if, IF, NORID
|
||||
inline, SCSPEC, RID_INLINE
|
||||
int, TYPESPEC, RID_INT
|
||||
long, TYPESPEC, RID_LONG
|
||||
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
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This progam 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.
|
||||
*
|
||||
* Alliance VLSI CAD System 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 the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Define constants for communication with parse.y.
|
||||
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 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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_MAX
|
||||
};
|
||||
|
||||
#define RID_FIRST_MODIFIER RID_UNSIGNED
|
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,177 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This progam 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.
|
||||
*
|
||||
* Alliance VLSI CAD System 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 the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Definitions for C parsing and type checking.
|
||||
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 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Language-dependent contents of an identifier. */
|
||||
|
||||
struct lang_identifier
|
||||
{
|
||||
struct tree_identifier ignore;
|
||||
tree global_value, local_value, label_value, implicit_decl;
|
||||
tree error_locus;
|
||||
};
|
||||
|
||||
/* Macros for access to language-specific slots in an identifier. */
|
||||
|
||||
#define IDENTIFIER_GLOBAL_VALUE(NODE) \
|
||||
(((struct lang_identifier *)(NODE))->global_value)
|
||||
#define IDENTIFIER_LOCAL_VALUE(NODE) \
|
||||
(((struct lang_identifier *)(NODE))->local_value)
|
||||
#define IDENTIFIER_LABEL_VALUE(NODE) \
|
||||
(((struct lang_identifier *)(NODE))->label_value)
|
||||
#define IDENTIFIER_IMPLICIT_DECL(NODE) \
|
||||
(((struct lang_identifier *)(NODE))->implicit_decl)
|
||||
#define IDENTIFIER_ERROR_LOCUS(NODE) \
|
||||
(((struct lang_identifier *)(NODE))->error_locus)
|
||||
|
||||
/* 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) TYPE_SEP_UNIT (type)
|
||||
|
||||
/* in c-typecheck.c */
|
||||
extern tree build_component_ref(), build_conditional_expr(), build_compound_expr();
|
||||
extern tree build_unary_op(), build_binary_op(), build_function_call();
|
||||
extern tree build_binary_op_nodefault ();
|
||||
extern tree build_indirect_ref(), build_array_ref(), build_c_cast();
|
||||
extern tree build_modify_expr();
|
||||
extern tree c_sizeof (), c_alignof ();
|
||||
extern void store_init_value ();
|
||||
extern tree digest_init ();
|
||||
extern tree c_expand_start_case ();
|
||||
extern tree default_conversion ();
|
||||
|
||||
/* Given two integer or real types, return the type for their sum.
|
||||
Given two compatible ANSI C types, returns the merged type. */
|
||||
|
||||
extern tree commontype ();
|
||||
|
||||
/* in c-decl.c */
|
||||
extern tree build_label ();
|
||||
|
||||
extern int start_function ();
|
||||
extern void finish_function ();
|
||||
extern void store_parm_decls ();
|
||||
extern tree get_parm_info ();
|
||||
|
||||
extern void pushlevel ();
|
||||
extern tree poplevel ();
|
||||
|
||||
extern tree groktypename(), lookup_name();
|
||||
|
||||
extern tree lookup_label(), define_label();
|
||||
|
||||
extern tree implicitly_declare(), getdecls(), gettags ();
|
||||
|
||||
extern tree start_decl();
|
||||
extern void finish_decl();
|
||||
|
||||
extern tree start_struct(), finish_struct(), xref_tag();
|
||||
extern tree grokfield();
|
||||
|
||||
extern tree start_enum(), finish_enum();
|
||||
extern tree build_enumerator();
|
||||
|
||||
extern tree make_index_type ();
|
||||
|
||||
/* Add qualifiers to a type, in the fashion for C. */
|
||||
extern tree c_build_type_variant ();
|
||||
|
||||
extern tree double_type_node, long_double_type_node, float_type_node;
|
||||
extern tree char_type_node, unsigned_char_type_node, signed_char_type_node;
|
||||
|
||||
extern tree short_integer_type_node, short_unsigned_type_node;
|
||||
extern tree long_integer_type_node, long_unsigned_type_node;
|
||||
extern tree long_long_integer_type_node, long_long_unsigned_type_node;
|
||||
extern tree unsigned_type_node;
|
||||
extern tree string_type_node, char_array_type_node, int_array_type_node;
|
||||
|
||||
extern int current_function_returns_value;
|
||||
extern int current_function_returns_null;
|
||||
|
||||
extern tree ridpointers[];
|
||||
|
||||
/* 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 warn about implicit declarations. */
|
||||
|
||||
extern int warn_implicit;
|
||||
|
||||
/* Nonzero means warn about function definitions that default the return type
|
||||
or that use a null return and have a return-type other than void. */
|
||||
|
||||
extern int warn_return_type;
|
||||
|
||||
/* 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 pointer casts that can drop a type qualifier
|
||||
from the pointer target type. */
|
||||
|
||||
extern int warn_cast_qual;
|
||||
|
||||
/* Nonzero means do some things the same way PCC does. */
|
||||
|
||||
extern int flag_traditional;
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,689 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This progam 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.
|
||||
*
|
||||
* Alliance VLSI CAD System 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 the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Save and restore call-clobbered registers which are live across a call.
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "rtl.h"
|
||||
#include "insn-config.h"
|
||||
#include "flags.h"
|
||||
#include "regs.h"
|
||||
#include "hard-reg-set.h"
|
||||
#include "reload.h"
|
||||
#include "recog.h"
|
||||
#include "basic-block.h"
|
||||
|
||||
/* Set of hard regs currently live (during scan of all insns). */
|
||||
|
||||
static HARD_REG_SET hard_regs_live;
|
||||
|
||||
/* The block of storage on the stack where regs are saved */
|
||||
|
||||
static rtx save_block_addr;
|
||||
static int save_block_size;
|
||||
|
||||
/* A REG rtx for each hard register that has been saved. */
|
||||
|
||||
static rtx save_reg_rtx[FIRST_PSEUDO_REGISTER];
|
||||
|
||||
static void set_reg_live ();
|
||||
static void clear_reg_live ();
|
||||
static void insert_call_saves ();
|
||||
static void emit_mult_save ();
|
||||
static void emit_mult_restore ();
|
||||
static rtx grow_save_block ();
|
||||
static enum machine_mode choose_hard_reg_mode ();
|
||||
|
||||
/* Find the places where hard regs are live across calls and save them. */
|
||||
|
||||
save_call_clobbered_regs ()
|
||||
{
|
||||
rtx insn;
|
||||
int b;
|
||||
|
||||
if (obey_regdecls)
|
||||
return;
|
||||
|
||||
save_block_size = 0;
|
||||
save_block_addr = 0;
|
||||
bzero (save_reg_rtx, sizeof save_reg_rtx);
|
||||
|
||||
for (b = 0; b < n_basic_blocks; b++)
|
||||
{
|
||||
regset regs_live = basic_block_live_at_start[b];
|
||||
int offset, bit, i;
|
||||
|
||||
/* 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. */
|
||||
|
||||
#ifdef HARD_REG_SET
|
||||
hard_regs_live = *regs_live;
|
||||
#else
|
||||
COPY_HARD_REG_SET (hard_regs_live, regs_live);
|
||||
#endif
|
||||
|
||||
for (offset = 0, i = 0; offset < regset_size; offset++)
|
||||
{
|
||||
if (regs_live[offset] == 0)
|
||||
i += HOST_BITS_PER_INT;
|
||||
else
|
||||
for (bit = 1; bit && i < max_regno; bit <<= 1, i++)
|
||||
if ((regs_live[offset] & bit) && reg_renumber[i] >= 0)
|
||||
SET_HARD_REG_BIT (hard_regs_live, reg_renumber[i]);
|
||||
}
|
||||
|
||||
/* 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]; TRUE; insn = NEXT_INSN (insn))
|
||||
{
|
||||
RTX_CODE code = GET_CODE (insn);
|
||||
|
||||
if (code == CALL_INSN)
|
||||
insert_call_saves (insn);
|
||||
|
||||
if (code == INSN || code == CALL_INSN || code == JUMP_INSN)
|
||||
{
|
||||
rtx link;
|
||||
|
||||
/* 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));
|
||||
|
||||
note_stores (PATTERN (insn), set_reg_live);
|
||||
}
|
||||
|
||||
if (insn == basic_block_end[b])
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Here from note_stores when an insn stores a value in a register.
|
||||
Set the proper bit or bits in hard_regs_live. */
|
||||
|
||||
static void
|
||||
set_reg_live (reg, setter)
|
||||
rtx reg, setter;
|
||||
{
|
||||
register int regno;
|
||||
|
||||
/* WORD is which word of a multi-register group is being stored.
|
||||
For the case where the store is actually into a SUBREG of REG.
|
||||
Except we don't use it; I believe the entire REG needs to be
|
||||
live. */
|
||||
int word = 0;
|
||||
|
||||
if (GET_CODE (reg) == SUBREG)
|
||||
{
|
||||
word = SUBREG_WORD (reg);
|
||||
reg = SUBREG_REG (reg);
|
||||
}
|
||||
|
||||
if (GET_CODE (reg) != REG)
|
||||
return;
|
||||
|
||||
regno = REGNO (reg);
|
||||
|
||||
/* For pseudo reg, see if it has been assigned a hardware reg. */
|
||||
if (reg_renumber[regno] >= 0)
|
||||
regno = reg_renumber[regno] /* + word */;
|
||||
|
||||
/* Handle hardware regs (and pseudos allocated to hard regs). */
|
||||
if (regno < FIRST_PSEUDO_REGISTER && ! call_fixed_regs[regno])
|
||||
{
|
||||
register int last = regno + HARD_REGNO_NREGS (regno, GET_MODE (reg));
|
||||
while (regno < last)
|
||||
{
|
||||
SET_HARD_REG_BIT (hard_regs_live, regno);
|
||||
regno++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Here when a REG_DEAD note records the last use of a reg. Clear
|
||||
the appropriate bit or bits in hard_regs_live. */
|
||||
|
||||
static void
|
||||
clear_reg_live (reg)
|
||||
rtx reg;
|
||||
{
|
||||
register int regno = REGNO (reg);
|
||||
|
||||
/* For pseudo reg, see if it has been assigned a hardware reg. */
|
||||
if (reg_renumber[regno] >= 0)
|
||||
regno = reg_renumber[regno];
|
||||
|
||||
/* Handle hardware regs (and pseudos allocated to hard regs). */
|
||||
if (regno < FIRST_PSEUDO_REGISTER && ! call_fixed_regs[regno])
|
||||
{
|
||||
/* Pseudo regs already assigned hardware regs are treated
|
||||
almost the same as explicit hardware regs. */
|
||||
register int last = regno + HARD_REGNO_NREGS (regno, GET_MODE (reg));
|
||||
while (regno < last)
|
||||
{
|
||||
CLEAR_HARD_REG_BIT (hard_regs_live, regno);
|
||||
regno++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Insert insns to save and restore live call-clobbered regs around
|
||||
call insn INSN. */
|
||||
|
||||
static void
|
||||
insert_call_saves (insn)
|
||||
rtx insn;
|
||||
{
|
||||
int regno;
|
||||
int save_block_size_needed;
|
||||
int save_block_offset[FIRST_PSEUDO_REGISTER];
|
||||
|
||||
save_block_size_needed = 0;
|
||||
|
||||
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
|
||||
{
|
||||
save_block_offset[regno] = -1;
|
||||
if (call_used_regs[regno] && ! call_fixed_regs[regno]
|
||||
&& TEST_HARD_REG_BIT (hard_regs_live, regno))
|
||||
{
|
||||
enum machine_mode mode = choose_hard_reg_mode (regno);
|
||||
int align = GET_MODE_UNIT_SIZE (mode);
|
||||
if (align > BIGGEST_ALIGNMENT / BITS_PER_UNIT)
|
||||
align = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
|
||||
save_block_size_needed =
|
||||
((save_block_size_needed + align - 1) / align) * align;
|
||||
save_block_offset[regno] = save_block_size_needed;
|
||||
save_block_size_needed += GET_MODE_SIZE (mode);
|
||||
if (! save_reg_rtx[regno])
|
||||
save_reg_rtx[regno] = gen_rtx (REG, mode, regno);
|
||||
}
|
||||
}
|
||||
|
||||
if (save_block_size < save_block_size_needed)
|
||||
save_block_addr = grow_save_block (save_block_addr,
|
||||
save_block_size_needed);
|
||||
emit_mult_save (insn, save_block_addr, save_block_offset);
|
||||
emit_mult_restore (insn, save_block_addr, save_block_offset);
|
||||
}
|
||||
|
||||
/* Emit a string of stores to save the hard regs listed in
|
||||
OFFSET[] at address ADDR. Emit them before INSN.
|
||||
OFFSET[reg] is -1 if reg should not be saved, or a
|
||||
suitably-aligned offset from ADDR.
|
||||
The offsets actually used do not have to be those listed
|
||||
in OFFSET, but should fit in a block of the same size. */
|
||||
|
||||
static void
|
||||
emit_mult_save (insn, addr, offset)
|
||||
rtx insn, addr;
|
||||
int offset[];
|
||||
{
|
||||
int regno;
|
||||
/* A register to use as a temporary for address calculations. */
|
||||
rtx tempreg;
|
||||
/* A register that could be used as that temp if we save and restore it. */
|
||||
rtx can_push_reg;
|
||||
/* Nonzero means we need to save a register to use it as TEMPREG. */
|
||||
int needpush;
|
||||
/* The amount the stack is decremented to save that register (if we do). */
|
||||
int decrement;
|
||||
/* Record which regs we save, in case we branch to retry. */
|
||||
char already_saved[FIRST_PSEUDO_REGISTER];
|
||||
|
||||
bzero (already_saved, sizeof already_saved);
|
||||
|
||||
/* Hair is needed because sometimes the addresses to save in are
|
||||
not valid (offsets too big).
|
||||
So we need a reg, TEMPREG, to compute addresses in.
|
||||
|
||||
We look first for an empty reg to use.
|
||||
Sometimes no reg is empty. Then we push a reg, use it, and pop it.
|
||||
|
||||
Sometimes the only reg to push and pop this way is one we want to save.
|
||||
We can't save it while using it as a temporary.
|
||||
So we save all the other registers, pop it, and go back to `retry'.
|
||||
At that point, only this reg remains to be saved;
|
||||
all the others already saved are empty.
|
||||
So one of them can be the temporary for this one. */
|
||||
|
||||
/* Sometimes we can't save all the regs conveniently at once, just some.
|
||||
If that happens, we branch back here to save the rest. */
|
||||
retry:
|
||||
needpush = 0;
|
||||
tempreg = 0;
|
||||
can_push_reg = 0;
|
||||
|
||||
/* Set NEEDPUSH if any save-addresses are not valid memory addresses.
|
||||
If any register is available, record it in TEMPREG.
|
||||
If any register doesn't need saving here, record it in CAN_PUSH_REG. */
|
||||
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
|
||||
{
|
||||
if (offset[regno] >= 0 && ! already_saved[regno])
|
||||
{
|
||||
rtx reg = save_reg_rtx[regno];
|
||||
rtx addr1 = plus_constant (addr, offset[regno]);
|
||||
if (memory_address_p (GET_MODE (reg), addr1))
|
||||
needpush = 1;
|
||||
}
|
||||
|
||||
/* A call-clobbered reg that is dead, or already saved,
|
||||
can be used as a temporary for sure, at no extra cost. */
|
||||
if (tempreg == 0 && call_used_regs[regno] && ! fixed_regs[regno]
|
||||
&& !(offset[regno] >= 0 && ! already_saved[regno])
|
||||
&& HARD_REGNO_MODE_OK (regno, Pmode))
|
||||
{
|
||||
tempreg = gen_rtx (REG, Pmode, regno);
|
||||
/* Don't use it if not valid for addressing. */
|
||||
if (! strict_memory_address_p (QImode, tempreg))
|
||||
tempreg = 0;
|
||||
}
|
||||
|
||||
/* A call-saved reg can be a temporary if we push and pop it. */
|
||||
if (can_push_reg == 0 && ! call_used_regs[regno]
|
||||
&& HARD_REGNO_MODE_OK (regno, Pmode))
|
||||
{
|
||||
can_push_reg = gen_rtx (REG, Pmode, regno);
|
||||
/* Don't use it if not valid for addressing. */
|
||||
if (! strict_memory_address_p (QImode, can_push_reg))
|
||||
can_push_reg = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear NEEDPUSH if we already found an empty reg. */
|
||||
if (tempreg != 0)
|
||||
needpush = 0;
|
||||
|
||||
/* If we need a temp reg and none is free, make one free. */
|
||||
if (needpush)
|
||||
{
|
||||
/* Choose a reg, preferably not among those it is our job to save. */
|
||||
if (can_push_reg != 0)
|
||||
tempreg = can_push_reg;
|
||||
else
|
||||
{
|
||||
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
|
||||
if (offset[regno] >= 0 && !already_saved[regno]
|
||||
&& HARD_REGNO_MODE_OK (regno, Pmode))
|
||||
{
|
||||
tempreg = gen_rtx (REG, Pmode, regno);
|
||||
/* Don't use it if not valid for addressing. */
|
||||
if (! strict_memory_address_p (QImode, tempreg))
|
||||
tempreg = 0;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Push it on the stack. */
|
||||
#ifdef STACK_GROWS_DOWNWARD
|
||||
decrement = UNITS_PER_WORD;
|
||||
#else
|
||||
decrement = - UNITS_PER_WORD;
|
||||
#endif
|
||||
|
||||
emit_insn_before (gen_add2_insn (stack_pointer_rtx,
|
||||
gen_rtx (CONST_INT, VOIDmode, -decrement)),
|
||||
insn);
|
||||
emit_insn_before (gen_move_insn (gen_rtx (MEM, Pmode, stack_pointer_rtx),
|
||||
tempreg),
|
||||
insn);
|
||||
}
|
||||
|
||||
/* Save the regs we are supposed to save, aside from TEMPREG.
|
||||
Use TEMPREG for address calculations when needed. */
|
||||
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
|
||||
if (offset[regno] >= 0 && ! already_saved[regno]
|
||||
&& tempreg != 0 && REGNO (tempreg) != regno)
|
||||
{
|
||||
rtx reg = save_reg_rtx[regno];
|
||||
rtx addr1 = plus_constant (addr, offset[regno]);
|
||||
rtx temp;
|
||||
if (! memory_address_p (GET_MODE (reg), addr1))
|
||||
{
|
||||
if (GET_CODE (addr1) != PLUS)
|
||||
abort ();
|
||||
if (GET_CODE (XEXP (addr1, 1)) != CONST_INT
|
||||
|| GET_CODE (XEXP (addr1, 0)) != REG)
|
||||
abort ();
|
||||
emit_insn_before (gen_move_insn (tempreg, XEXP (addr1, 0)), insn);
|
||||
emit_insn_before (gen_add2_insn (tempreg, XEXP (addr1, 1)), insn);
|
||||
addr1 = tempreg;
|
||||
}
|
||||
temp = gen_rtx (MEM, GET_MODE (reg), addr1);
|
||||
emit_insn_before (gen_move_insn (temp, reg), insn);
|
||||
already_saved[regno] = 1;
|
||||
}
|
||||
|
||||
/* If we pushed TEMPREG to make it free, pop it. */
|
||||
if (needpush)
|
||||
{
|
||||
emit_insn_before (gen_move_insn (tempreg,
|
||||
gen_rtx (MEM, Pmode, stack_pointer_rtx)),
|
||||
insn);
|
||||
emit_insn_before (gen_add2_insn (stack_pointer_rtx,
|
||||
gen_rtx (CONST_INT, VOIDmode, decrement)),
|
||||
insn);
|
||||
}
|
||||
|
||||
/* If TEMPREG itself needs saving, go back and save it.
|
||||
There are plenty of free regs now, those already saved. */
|
||||
if (tempreg != 0
|
||||
&& offset[REGNO (tempreg)] >= 0 && ! already_saved[REGNO (tempreg)])
|
||||
goto retry;
|
||||
}
|
||||
|
||||
/* Emit a string of loads to restore the hard regs listed in
|
||||
OFFSET[] from address ADDR; insert the loads after INSN.
|
||||
OFFSET[reg] is -1 if reg should not be loaded, or a
|
||||
suitably-aligned offset from ADDR.
|
||||
The offsets actually used do not need to be those provided in
|
||||
OFFSET, but should agree with whatever emit_mult_save does. */
|
||||
|
||||
static void
|
||||
emit_mult_restore (insn, addr, offset)
|
||||
rtx insn, addr;
|
||||
int offset[];
|
||||
{
|
||||
int regno;
|
||||
|
||||
/* Number of regs now needing to be restored. */
|
||||
int restore_count;
|
||||
/* A register to use as a temporary for address calculations. */
|
||||
rtx tempreg;
|
||||
/* A register available for that purpose but less desirable. */
|
||||
rtx maybe_tempreg;
|
||||
/* A register that could be used as that temp if we push and pop it. */
|
||||
rtx can_push_reg;
|
||||
/* Nonzero means we need to push and pop a register to use it as TEMPREG. */
|
||||
int needpush;
|
||||
/* The amount the stack is decremented to save that register (if we do). */
|
||||
int decrement;
|
||||
/* Record which regs we restore, in case we branch to retry. */
|
||||
char already_restored[FIRST_PSEUDO_REGISTER];
|
||||
|
||||
bzero (already_restored, sizeof already_restored);
|
||||
|
||||
/* Note: INSN can't be the last insn, since if it were,
|
||||
no regs would live across it. */
|
||||
insn = NEXT_INSN (insn);
|
||||
if (insn == 0)
|
||||
abort ();
|
||||
/* Now we can insert before INSN.
|
||||
That is convenient because we can insert them in the order
|
||||
that they should ultimately appear. */
|
||||
|
||||
/* Hair is needed because sometimes the addresses to restore from are
|
||||
not valid (offsets too big).
|
||||
So we need a reg, TEMPREG, to compute addresses in.
|
||||
|
||||
We look first for an empty reg to use.
|
||||
Sometimes no reg is empty. Then we push a reg, use it, and pop it.
|
||||
|
||||
If all the suitable regs need to be restored,
|
||||
that strategy won't work. So we restore all but one, using that one
|
||||
as a temporary. Then we jump to `retry' to restore that one,
|
||||
pushing and popping another (already restored) as a temporary. */
|
||||
|
||||
retry:
|
||||
needpush = 0;
|
||||
tempreg = 0;
|
||||
can_push_reg = 0;
|
||||
restore_count = 0;
|
||||
|
||||
/* Set NEEDPUSH if any restore-addresses are not valid memory addresses.
|
||||
If any register is available, record it in TEMPREG.
|
||||
Otherwise, one register yet to be restored goes in MAYBE_TEMPREG,
|
||||
and can be used as TEMPREG for any other regs to be restored.
|
||||
If any register doesn't need restoring, record it in CAN_PUSH_REG. */
|
||||
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
|
||||
{
|
||||
if (offset[regno] >= 0 && ! already_restored[regno])
|
||||
{
|
||||
rtx reg = save_reg_rtx[regno];
|
||||
rtx addr1 = plus_constant (addr, offset[regno]);
|
||||
|
||||
restore_count++;
|
||||
|
||||
if (memory_address_p (GET_MODE (reg), addr1))
|
||||
needpush = 1;
|
||||
|
||||
/* Find a call-clobbered reg that needs restoring.
|
||||
We can use it as a temporary if we defer restoring it. */
|
||||
if (maybe_tempreg == 0)
|
||||
{
|
||||
maybe_tempreg = gen_rtx (REG, Pmode, regno);
|
||||
/* Don't use it if not valid for addressing. */
|
||||
if (! strict_memory_address_p (QImode, maybe_tempreg))
|
||||
maybe_tempreg = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If any call-clobbered reg is dead, put it in TEMPREG.
|
||||
It can be used as a temporary at no extra cost. */
|
||||
if (tempreg == 0 && call_used_regs[regno] && ! fixed_regs[regno]
|
||||
&& offset[regno] < 0
|
||||
&& HARD_REGNO_MODE_OK (regno, Pmode))
|
||||
{
|
||||
tempreg = gen_rtx (REG, Pmode, regno);
|
||||
/* Don't use it if not valid for addressing. */
|
||||
if (! strict_memory_address_p (QImode, tempreg))
|
||||
tempreg = 0;
|
||||
}
|
||||
|
||||
/* Any non-call-clobbered reg, put in CAN_PUSH_REG.
|
||||
It can be used as a temporary if we push and pop it. */
|
||||
if (can_push_reg == 0 && ! call_used_regs[regno]
|
||||
&& HARD_REGNO_MODE_OK (regno, Pmode))
|
||||
{
|
||||
can_push_reg = gen_rtx (REG, Pmode, regno);
|
||||
/* Don't use it if not valid for addressing. */
|
||||
if (! strict_memory_address_p (QImode, can_push_reg))
|
||||
can_push_reg = 0;
|
||||
}
|
||||
/* Any reg we already restored can be a temporary
|
||||
if we push and pop it. */
|
||||
if (can_push_reg == 0 && already_restored[regno]
|
||||
&& HARD_REGNO_MODE_OK (regno, Pmode))
|
||||
{
|
||||
can_push_reg = gen_rtx (REG, Pmode, regno);
|
||||
/* Don't use it if not valid for addressing. */
|
||||
if (! strict_memory_address_p (QImode, can_push_reg))
|
||||
can_push_reg = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If 2 or more regs need to be restored, use one as a temp reg
|
||||
for the rest (if we need a tempreg). */
|
||||
if (tempreg == 0 && maybe_tempreg != 0 && restore_count > 1)
|
||||
tempreg = maybe_tempreg;
|
||||
|
||||
/* Clear NEEDPUSH if we already found an empty reg. */
|
||||
if (tempreg != 0)
|
||||
needpush = 0;
|
||||
|
||||
/* If we need a temp reg and none is free, make one free. */
|
||||
if (needpush)
|
||||
{
|
||||
tempreg = can_push_reg;
|
||||
|
||||
/* Push it on the stack. */
|
||||
#ifdef STACK_GROWS_DOWNWARD
|
||||
decrement = UNITS_PER_WORD;
|
||||
#else
|
||||
decrement = - UNITS_PER_WORD;
|
||||
#endif
|
||||
|
||||
emit_insn_before (gen_add2_insn (stack_pointer_rtx,
|
||||
gen_rtx (CONST_INT, VOIDmode, -decrement)),
|
||||
insn);
|
||||
emit_insn_before (gen_move_insn (gen_rtx (MEM, Pmode, stack_pointer_rtx),
|
||||
tempreg),
|
||||
insn);
|
||||
}
|
||||
|
||||
/* Restore the regs we are supposed to restore, aside from TEMPREG.
|
||||
Use TEMPREG for address calculations when needed. */
|
||||
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
|
||||
if (offset[regno] >= 0 && ! already_restored[regno]
|
||||
&& tempreg != 0 && REGNO (tempreg) != regno)
|
||||
{
|
||||
rtx reg = save_reg_rtx[regno];
|
||||
rtx addr1 = plus_constant (addr, offset[regno]);
|
||||
rtx temp;
|
||||
if (! memory_address_p (GET_MODE (reg), addr1))
|
||||
{
|
||||
if (GET_CODE (addr1) != PLUS)
|
||||
abort ();
|
||||
if (GET_CODE (XEXP (addr1, 1)) != CONST_INT
|
||||
|| GET_CODE (XEXP (addr1, 0)) != REG)
|
||||
abort ();
|
||||
emit_insn_before (gen_move_insn (tempreg, XEXP (addr1, 0)), insn);
|
||||
emit_insn_before (gen_add2_insn (tempreg, XEXP (addr1, 1)), insn);
|
||||
addr1 = tempreg;
|
||||
}
|
||||
temp = gen_rtx (MEM, GET_MODE (reg), addr1);
|
||||
emit_insn_before (gen_move_insn (reg, temp), insn);
|
||||
already_restored[regno] = 1;
|
||||
}
|
||||
|
||||
/* If we pushed TEMPREG to make it free, pop it. */
|
||||
if (needpush)
|
||||
{
|
||||
emit_insn_before (gen_move_insn (tempreg,
|
||||
gen_rtx (MEM, Pmode, stack_pointer_rtx)),
|
||||
insn);
|
||||
emit_insn_before (gen_add2_insn (stack_pointer_rtx,
|
||||
gen_rtx (CONST_INT, VOIDmode, decrement)),
|
||||
insn);
|
||||
}
|
||||
|
||||
/* If TEMPREG itself needs restoring, go back and restore it.
|
||||
We can find a reg already restored to push and use as a temporary. */
|
||||
if (tempreg != 0
|
||||
&& offset[REGNO (tempreg)] >= 0 && ! already_restored[REGNO (tempreg)])
|
||||
goto retry;
|
||||
}
|
||||
|
||||
/* Return the address of a new block of size SIZE on the stack.
|
||||
The old save block is at ADDR; ADDR is 0 if no block exists yet. */
|
||||
|
||||
static rtx
|
||||
grow_save_block (addr, size)
|
||||
rtx addr;
|
||||
int size;
|
||||
{
|
||||
rtx newaddr;
|
||||
|
||||
/* Keep the size a multiple of the main allocation unit. */
|
||||
size = (((size + (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1)
|
||||
/ (BIGGEST_ALIGNMENT / BITS_PER_UNIT))
|
||||
* (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
|
||||
|
||||
/* If no save block exists yet, create one and return it. */
|
||||
if (! addr)
|
||||
{
|
||||
save_block_size = size;
|
||||
return XEXP (assign_stack_local (BLKmode, size), 0);
|
||||
}
|
||||
|
||||
/* Get a new block and coalesce it with the old one. */
|
||||
newaddr = XEXP (assign_stack_local (BLKmode, size - save_block_size), 0);
|
||||
if (GET_CODE (newaddr) == PLUS
|
||||
&& XEXP (newaddr, 0) == frame_pointer_rtx
|
||||
&& GET_CODE (XEXP (newaddr, 1)) == CONST_INT
|
||||
&& GET_CODE (addr) == PLUS
|
||||
&& XEXP (addr, 0) == frame_pointer_rtx
|
||||
&& GET_CODE (XEXP (addr, 1)) == CONST_INT
|
||||
&& ((INTVAL (XEXP (newaddr, 1)) - INTVAL (XEXP (addr, 1))
|
||||
== size - save_block_size)
|
||||
|| (INTVAL (XEXP (addr, 1)) - INTVAL (XEXP (newaddr, 1))
|
||||
== size - save_block_size)))
|
||||
{
|
||||
save_block_size = size;
|
||||
if (INTVAL (XEXP (newaddr, 1)) < INTVAL (XEXP (addr, 1)))
|
||||
return newaddr;
|
||||
else
|
||||
return addr;
|
||||
}
|
||||
|
||||
/* They didn't coalesce, find out why */
|
||||
abort ();
|
||||
|
||||
save_block_size = size;
|
||||
return XEXP (assign_stack_local (BLKmode, size), 0);
|
||||
}
|
||||
|
||||
/* Return a machine mode that is legitimate for hard reg REGNO
|
||||
and large enough to save the whole register. */
|
||||
|
||||
static enum machine_mode
|
||||
choose_hard_reg_mode (regno)
|
||||
int regno;
|
||||
{
|
||||
enum reg_class class = REGNO_REG_CLASS (regno);
|
||||
|
||||
if (CLASS_MAX_NREGS (class, DImode) == 1
|
||||
&& HARD_REGNO_MODE_OK (regno, DImode))
|
||||
return DImode;
|
||||
else if (CLASS_MAX_NREGS (class, DFmode) == 1
|
||||
&& HARD_REGNO_MODE_OK (regno, DFmode))
|
||||
return DFmode;
|
||||
else if (CLASS_MAX_NREGS (class, SImode) == 1
|
||||
&& HARD_REGNO_MODE_OK (regno, SImode))
|
||||
return SImode;
|
||||
else if (CLASS_MAX_NREGS (class, SFmode) == 1
|
||||
&& HARD_REGNO_MODE_OK (regno, SFmode))
|
||||
return SFmode;
|
||||
else if (CLASS_MAX_NREGS (class, HImode) == 1
|
||||
&& HARD_REGNO_MODE_OK (regno, HImode))
|
||||
return HImode;
|
||||
else
|
||||
abort ();
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,656 @@
|
|||
/* Parse C expressions for CCCP.
|
||||
Copyright (C) 1987 Free Software Foundation.
|
||||
|
||||
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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
In other words, you are welcome to use, share and improve this program.
|
||||
You are forbidden to forbid anyone else to use, share and improve
|
||||
what you give them. Help stamp out software-hoarding!
|
||||
|
||||
Adapted from expread.y of GDB by Paul Rubin, July 1986.
|
||||
|
||||
/* Parse a C expression from text in a string */
|
||||
|
||||
%{
|
||||
#include "config.h"
|
||||
#include <setjmp.h>
|
||||
/* #define YYDEBUG 1 */
|
||||
|
||||
int yylex ();
|
||||
void yyerror ();
|
||||
int expression_value;
|
||||
|
||||
static jmp_buf parse_return_error;
|
||||
|
||||
/* some external tables of character types */
|
||||
extern unsigned char is_idstart[], is_idchar[];
|
||||
|
||||
#ifndef CHAR_TYPE_SIZE
|
||||
#define CHAR_TYPE_SIZE BITS_PER_UNIT
|
||||
#endif
|
||||
%}
|
||||
|
||||
%union {
|
||||
struct constant {long value; int unsignedp;} integer;
|
||||
int voidval;
|
||||
char *sval;
|
||||
}
|
||||
|
||||
%type <integer> exp exp1 start
|
||||
%token <integer> INT CHAR
|
||||
%token <sval> NAME
|
||||
%token <integer> ERROR
|
||||
|
||||
%right '?' ':'
|
||||
%left ','
|
||||
%left OR
|
||||
%left AND
|
||||
%left '|'
|
||||
%left '^'
|
||||
%left '&'
|
||||
%left EQUAL NOTEQUAL
|
||||
%left '<' '>' LEQ GEQ
|
||||
%left LSH RSH
|
||||
%left '+' '-'
|
||||
%left '*' '/' '%'
|
||||
%right UNARY
|
||||
|
||||
/* %expect 40 */
|
||||
|
||||
%%
|
||||
|
||||
start : exp1
|
||||
{ expression_value = $1.value; }
|
||||
;
|
||||
|
||||
/* Expressions, including the comma operator. */
|
||||
exp1 : exp
|
||||
| exp1 ',' exp
|
||||
{ $$ = $3; }
|
||||
;
|
||||
|
||||
/* Expressions, not including the comma operator. */
|
||||
exp : '-' exp %prec UNARY
|
||||
{ $$.value = - $2.value;
|
||||
$$.unsignedp = $2.unsignedp; }
|
||||
| '!' exp %prec UNARY
|
||||
{ $$.value = ! $2.value;
|
||||
$$.unsignedp = 0; }
|
||||
| '+' exp %prec UNARY
|
||||
{ $$ = $2; }
|
||||
| '~' exp %prec UNARY
|
||||
{ $$.value = ~ $2.value;
|
||||
$$.unsignedp = $2.unsignedp; }
|
||||
| '(' exp1 ')'
|
||||
{ $$ = $2; }
|
||||
;
|
||||
|
||||
/* Binary operators in order of decreasing precedence. */
|
||||
exp : exp '*' exp
|
||||
{ $$.unsignedp = $1.unsignedp || $3.unsignedp;
|
||||
if ($$.unsignedp)
|
||||
$$.value = (unsigned) $1.value * $3.value;
|
||||
else
|
||||
$$.value = $1.value * $3.value; }
|
||||
| exp '/' exp
|
||||
{ if ($3.value == 0)
|
||||
{
|
||||
error ("division by zero in #if");
|
||||
$3.value = 1;
|
||||
}
|
||||
$$.unsignedp = $1.unsignedp || $3.unsignedp;
|
||||
if ($$.unsignedp)
|
||||
$$.value = (unsigned) $1.value / $3.value;
|
||||
else
|
||||
$$.value = $1.value / $3.value; }
|
||||
| exp '%' exp
|
||||
{ if ($3.value == 0)
|
||||
{
|
||||
error ("division by zero in #if");
|
||||
$3.value = 1;
|
||||
}
|
||||
$$.unsignedp = $1.unsignedp || $3.unsignedp;
|
||||
if ($$.unsignedp)
|
||||
$$.value = (unsigned) $1.value % $3.value;
|
||||
else
|
||||
$$.value = $1.value % $3.value; }
|
||||
| exp '+' exp
|
||||
{ $$.value = $1.value + $3.value;
|
||||
$$.unsignedp = $1.unsignedp || $3.unsignedp; }
|
||||
| exp '-' exp
|
||||
{ $$.value = $1.value - $3.value;
|
||||
$$.unsignedp = $1.unsignedp || $3.unsignedp; }
|
||||
| exp LSH exp
|
||||
{ $$.unsignedp = $1.unsignedp;
|
||||
if ($$.unsignedp)
|
||||
$$.value = (unsigned) $1.value << $3.value;
|
||||
else
|
||||
$$.value = $1.value << $3.value; }
|
||||
| exp RSH exp
|
||||
{ $$.unsignedp = $1.unsignedp;
|
||||
if ($$.unsignedp)
|
||||
$$.value = (unsigned) $1.value >> $3.value;
|
||||
else
|
||||
$$.value = $1.value >> $3.value; }
|
||||
| exp EQUAL exp
|
||||
{ $$.value = ($1.value == $3.value);
|
||||
$$.unsignedp = 0; }
|
||||
| exp NOTEQUAL exp
|
||||
{ $$.value = ($1.value != $3.value);
|
||||
$$.unsignedp = 0; }
|
||||
| exp LEQ exp
|
||||
{ $$.unsignedp = 0;
|
||||
if ($1.unsignedp || $3.unsignedp)
|
||||
$$.value = (unsigned) $1.value <= $3.value;
|
||||
else
|
||||
$$.value = $1.value <= $3.value; }
|
||||
| exp GEQ exp
|
||||
{ $$.unsignedp = 0;
|
||||
if ($1.unsignedp || $3.unsignedp)
|
||||
$$.value = (unsigned) $1.value >= $3.value;
|
||||
else
|
||||
$$.value = $1.value >= $3.value; }
|
||||
| exp '<' exp
|
||||
{ $$.unsignedp = 0;
|
||||
if ($1.unsignedp || $3.unsignedp)
|
||||
$$.value = (unsigned) $1.value < $3.value;
|
||||
else
|
||||
$$.value = $1.value < $3.value; }
|
||||
| exp '>' exp
|
||||
{ $$.unsignedp = 0;
|
||||
if ($1.unsignedp || $3.unsignedp)
|
||||
$$.value = (unsigned) $1.value > $3.value;
|
||||
else
|
||||
$$.value = $1.value > $3.value; }
|
||||
| exp '&' exp
|
||||
{ $$.value = $1.value & $3.value;
|
||||
$$.unsignedp = $1.unsignedp || $3.unsignedp; }
|
||||
| exp '^' exp
|
||||
{ $$.value = $1.value ^ $3.value;
|
||||
$$.unsignedp = $1.unsignedp || $3.unsignedp; }
|
||||
| exp '|' exp
|
||||
{ $$.value = $1.value | $3.value;
|
||||
$$.unsignedp = $1.unsignedp || $3.unsignedp; }
|
||||
| exp AND exp
|
||||
{ $$.value = ($1.value && $3.value);
|
||||
$$.unsignedp = 0; }
|
||||
| exp OR exp
|
||||
{ $$.value = ($1.value || $3.value);
|
||||
$$.unsignedp = 0; }
|
||||
| exp '?' exp ':' exp
|
||||
{ $$.value = $1.value ? $3.value : $5.value;
|
||||
$$.unsignedp = $3.unsignedp || $5.unsignedp; }
|
||||
| INT
|
||||
{ $$ = yylval.integer; }
|
||||
| CHAR
|
||||
{ $$ = yylval.integer; }
|
||||
| NAME
|
||||
{ $$.value = 0;
|
||||
$$.unsignedp = 0; }
|
||||
;
|
||||
%%
|
||||
|
||||
/* During parsing of a C expression, the pointer to the next character
|
||||
is in this variable. */
|
||||
|
||||
static char *lexptr;
|
||||
|
||||
/* Take care of parsing a number (anything that starts with a digit).
|
||||
Set yylval and return the token type; update lexptr.
|
||||
LEN is the number of characters in it. */
|
||||
|
||||
/* maybe needs to actually deal with floating point numbers */
|
||||
|
||||
int
|
||||
parse_number (olen)
|
||||
int olen;
|
||||
{
|
||||
register char *p = lexptr;
|
||||
register long n = 0;
|
||||
register int c;
|
||||
register int base = 10;
|
||||
register int len = olen;
|
||||
|
||||
for (c = 0; c < len; c++)
|
||||
if (p[c] == '.') {
|
||||
/* It's a float since it contains a point. */
|
||||
yyerror ("floating point numbers not allowed in #if expressions");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
yylval.integer.unsignedp = 0;
|
||||
|
||||
if (len >= 3 && (!strncmp (p, "0x", 2) || !strncmp (p, "0X", 2))) {
|
||||
p += 2;
|
||||
base = 16;
|
||||
len -= 2;
|
||||
}
|
||||
else if (*p == '0')
|
||||
base = 8;
|
||||
|
||||
while (len > 0) {
|
||||
c = *p++;
|
||||
len--;
|
||||
if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
|
||||
|
||||
if (c >= '0' && c <= '9') {
|
||||
n *= base;
|
||||
n += c - '0';
|
||||
} else if (base == 16 && c >= 'a' && c <= 'f') {
|
||||
n *= base;
|
||||
n += c - 'a' + 10;
|
||||
} else {
|
||||
/* `l' means long, and `u' means unsigned. */
|
||||
while (1) {
|
||||
if (c == 'l' || c == 'L')
|
||||
;
|
||||
else if (c == 'u' || c == 'U')
|
||||
yylval.integer.unsignedp = 1;
|
||||
else
|
||||
break;
|
||||
|
||||
if (len == 0)
|
||||
break;
|
||||
c = *p++;
|
||||
len--;
|
||||
}
|
||||
/* Don't look for any more digits after the suffixes. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (len != 0) {
|
||||
yyerror ("Invalid number in #if expression");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* If too big to be signed, consider it unsigned. */
|
||||
if (n < 0)
|
||||
yylval.integer.unsignedp = 1;
|
||||
|
||||
lexptr = p;
|
||||
yylval.integer.value = n;
|
||||
return INT;
|
||||
}
|
||||
|
||||
struct token {
|
||||
char *operator;
|
||||
int token;
|
||||
};
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
static struct token tokentab2[] = {
|
||||
{"&&", AND},
|
||||
{"||", OR},
|
||||
{"<<", LSH},
|
||||
{">>", RSH},
|
||||
{"==", EQUAL},
|
||||
{"!=", NOTEQUAL},
|
||||
{"<=", LEQ},
|
||||
{">=", GEQ},
|
||||
{NULL, ERROR}
|
||||
};
|
||||
|
||||
/* Read one token, getting characters through lexptr. */
|
||||
|
||||
int
|
||||
yylex ()
|
||||
{
|
||||
register int c;
|
||||
register int namelen;
|
||||
register char *tokstart;
|
||||
register struct token *toktab;
|
||||
|
||||
retry:
|
||||
|
||||
tokstart = lexptr;
|
||||
c = *tokstart;
|
||||
/* See if it is a special token of length 2. */
|
||||
for (toktab = tokentab2; toktab->operator != NULL; toktab++)
|
||||
if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) {
|
||||
lexptr += 2;
|
||||
return toktab->token;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case 0:
|
||||
return 0;
|
||||
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\r':
|
||||
case '\n':
|
||||
lexptr++;
|
||||
goto retry;
|
||||
|
||||
case '\'':
|
||||
lexptr++;
|
||||
c = *lexptr++;
|
||||
if (c == '\\')
|
||||
c = parse_escape (&lexptr);
|
||||
|
||||
/* Sign-extend the constant if chars are signed on target machine. */
|
||||
{
|
||||
if (lookup ("__CHAR_UNSIGNED__", sizeof ("__CHAR_UNSIGNED__")-1, -1)
|
||||
|| ((c >> (CHAR_TYPE_SIZE - 1)) & 1) == 0)
|
||||
yylval.integer.value = c & ((1 << CHAR_TYPE_SIZE) - 1);
|
||||
else
|
||||
yylval.integer.value = c | ~((1 << CHAR_TYPE_SIZE) - 1);
|
||||
}
|
||||
|
||||
yylval.integer.unsignedp = 0;
|
||||
c = *lexptr++;
|
||||
if (c != '\'') {
|
||||
yyerror ("Invalid character constant in #if");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return CHAR;
|
||||
|
||||
/* some of these chars are invalid in constant expressions;
|
||||
maybe do something about them later */
|
||||
case '/':
|
||||
case '+':
|
||||
case '-':
|
||||
case '*':
|
||||
case '%':
|
||||
case '|':
|
||||
case '&':
|
||||
case '^':
|
||||
case '~':
|
||||
case '!':
|
||||
case '@':
|
||||
case '<':
|
||||
case '>':
|
||||
case '(':
|
||||
case ')':
|
||||
case '[':
|
||||
case ']':
|
||||
case '.':
|
||||
case '?':
|
||||
case ':':
|
||||
case '=':
|
||||
case '{':
|
||||
case '}':
|
||||
case ',':
|
||||
lexptr++;
|
||||
return c;
|
||||
|
||||
case '"':
|
||||
yyerror ("double quoted strings not allowed in #if expressions");
|
||||
return ERROR;
|
||||
}
|
||||
if (c >= '0' && c <= '9') {
|
||||
/* It's a number */
|
||||
for (namelen = 0;
|
||||
c = tokstart[namelen], is_idchar[c] || c == '.';
|
||||
namelen++)
|
||||
;
|
||||
return parse_number (namelen);
|
||||
}
|
||||
|
||||
if (!is_idstart[c]) {
|
||||
yyerror ("Invalid token in expression");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* It is a name. See how long it is. */
|
||||
|
||||
for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++)
|
||||
;
|
||||
|
||||
lexptr += namelen;
|
||||
return NAME;
|
||||
}
|
||||
|
||||
|
||||
/* Parse a C escape sequence. STRING_PTR points to a variable
|
||||
containing a pointer to the string to parse. That pointer
|
||||
is updated past the characters we use. The value of the
|
||||
escape sequence is returned.
|
||||
|
||||
A negative value means the sequence \ newline was seen,
|
||||
which is supposed to be equivalent to nothing at all.
|
||||
|
||||
If \ is followed by a null character, we return a negative
|
||||
value and leave the string pointer pointing at the null character.
|
||||
|
||||
If \ is followed by 000, we return 0 and leave the string pointer
|
||||
after the zeros. A value of 0 does not mean end of string. */
|
||||
|
||||
int
|
||||
parse_escape (string_ptr)
|
||||
char **string_ptr;
|
||||
{
|
||||
register int c = *(*string_ptr)++;
|
||||
switch (c)
|
||||
{
|
||||
case 'a':
|
||||
return TARGET_BELL;
|
||||
case 'b':
|
||||
return TARGET_BS;
|
||||
case 'e':
|
||||
return 033;
|
||||
case 'f':
|
||||
return TARGET_FF;
|
||||
case 'n':
|
||||
return TARGET_NEWLINE;
|
||||
case 'r':
|
||||
return TARGET_CR;
|
||||
case 't':
|
||||
return TARGET_TAB;
|
||||
case 'v':
|
||||
return TARGET_VT;
|
||||
case '\n':
|
||||
return -2;
|
||||
case 0:
|
||||
(*string_ptr)--;
|
||||
return 0;
|
||||
case '^':
|
||||
c = *(*string_ptr)++;
|
||||
if (c == '\\')
|
||||
c = parse_escape (string_ptr);
|
||||
if (c == '?')
|
||||
return 0177;
|
||||
return (c & 0200) | (c & 037);
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
{
|
||||
register int i = c - '0';
|
||||
register int count = 0;
|
||||
while (++count < 3)
|
||||
{
|
||||
c = *(*string_ptr)++;
|
||||
if (c >= '0' && c <= '7')
|
||||
i = (i << 3) + c - '0';
|
||||
else
|
||||
{
|
||||
(*string_ptr)--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((i & ~((1 << CHAR_TYPE_SIZE) - 1)) != 0)
|
||||
{
|
||||
i &= (1 << CHAR_TYPE_SIZE) - 1;
|
||||
warning ("octal character constant does not fit in a byte");
|
||||
}
|
||||
return i;
|
||||
}
|
||||
case 'x':
|
||||
{
|
||||
register int i = 0;
|
||||
register int count = 0;
|
||||
for (;;)
|
||||
{
|
||||
c = *(*string_ptr)++;
|
||||
if (c >= '0' && c <= '9')
|
||||
i = (i << 4) + c - '0';
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
i = (i << 4) + c - 'a' + 10;
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
i = (i << 4) + c - 'A' + 10;
|
||||
else
|
||||
{
|
||||
(*string_ptr)--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((i & ~((1 << BITS_PER_UNIT) - 1)) != 0)
|
||||
{
|
||||
i &= (1 << BITS_PER_UNIT) - 1;
|
||||
warning ("hex character constant does not fit in a byte");
|
||||
}
|
||||
return i;
|
||||
}
|
||||
default:
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
yyerror (s)
|
||||
char *s;
|
||||
{
|
||||
error (s);
|
||||
longjmp (parse_return_error, 1);
|
||||
}
|
||||
|
||||
/* This page contains the entry point to this file. */
|
||||
|
||||
/* Parse STRING as an expression, and complain if this fails
|
||||
to use up all of the contents of STRING. */
|
||||
/* We do not support C comments. They should be removed before
|
||||
this function is called. */
|
||||
|
||||
int
|
||||
parse_c_expression (string)
|
||||
char *string;
|
||||
{
|
||||
lexptr = string;
|
||||
|
||||
if (lexptr == 0 || *lexptr == 0) {
|
||||
error ("empty #if expression");
|
||||
return 0; /* don't include the #if group */
|
||||
}
|
||||
|
||||
/* if there is some sort of scanning error, just return 0 and assume
|
||||
the parsing routine has printed an error message somewhere.
|
||||
there is surely a better thing to do than this. */
|
||||
if (setjmp (parse_return_error))
|
||||
return 0;
|
||||
|
||||
if (yyparse ())
|
||||
return 0; /* actually this is never reached
|
||||
the way things stand. */
|
||||
if (*lexptr)
|
||||
error ("Junk after end of expression.");
|
||||
|
||||
return expression_value; /* set by yyparse () */
|
||||
}
|
||||
|
||||
#ifdef TEST_EXP_READER
|
||||
/* main program, for testing purposes. */
|
||||
main ()
|
||||
{
|
||||
int n, c;
|
||||
char buf[1024];
|
||||
extern int yydebug;
|
||||
/*
|
||||
yydebug = 1;
|
||||
*/
|
||||
initialize_random_junk ();
|
||||
|
||||
for (;;) {
|
||||
printf ("enter expression: ");
|
||||
n = 0;
|
||||
while ((buf[n] = getchar ()) != '\n' && buf[n] != EOF)
|
||||
n++;
|
||||
if (buf[n] == EOF)
|
||||
break;
|
||||
buf[n] = '\0';
|
||||
printf ("parser returned %d\n", parse_c_expression (buf));
|
||||
}
|
||||
}
|
||||
|
||||
/* table to tell if char can be part of a C identifier. */
|
||||
unsigned char is_idchar[256];
|
||||
/* table to tell if char can be first char of a c identifier. */
|
||||
unsigned char is_idstart[256];
|
||||
/* table to tell if c is horizontal space. isspace () thinks that
|
||||
newline is space; this is not a good idea for this program. */
|
||||
char is_hor_space[256];
|
||||
|
||||
/*
|
||||
* initialize random junk in the hash table and maybe other places
|
||||
*/
|
||||
initialize_random_junk ()
|
||||
{
|
||||
register int i;
|
||||
|
||||
/*
|
||||
* Set up is_idchar and is_idstart tables. These should be
|
||||
* faster than saying (is_alpha (c) || c == '_'), etc.
|
||||
* Must do set up these things before calling any routines tthat
|
||||
* refer to them.
|
||||
*/
|
||||
for (i = 'a'; i <= 'z'; i++) {
|
||||
++is_idchar[i - 'a' + 'A'];
|
||||
++is_idchar[i];
|
||||
++is_idstart[i - 'a' + 'A'];
|
||||
++is_idstart[i];
|
||||
}
|
||||
for (i = '0'; i <= '9'; i++)
|
||||
++is_idchar[i];
|
||||
++is_idchar['_'];
|
||||
++is_idstart['_'];
|
||||
#if DOLLARS_IN_IDENTIFIERS
|
||||
++is_idchar['$'];
|
||||
++is_idstart['$'];
|
||||
#endif
|
||||
|
||||
/* horizontal space table */
|
||||
++is_hor_space[' '];
|
||||
++is_hor_space['\t'];
|
||||
}
|
||||
|
||||
error (msg)
|
||||
{
|
||||
printf ("error: %s\n", msg);
|
||||
}
|
||||
|
||||
warning (msg)
|
||||
{
|
||||
printf ("warning: %s\n", msg);
|
||||
}
|
||||
|
||||
struct hashnode *
|
||||
lookup (name, len, hash)
|
||||
char *name;
|
||||
int len;
|
||||
int hash;
|
||||
{
|
||||
return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This progam 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.
|
||||
*
|
||||
* Alliance VLSI CAD System 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 the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* 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 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
/* 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- 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- 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
|
||||
|
||||
/* 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)
|
|
@ -0,0 +1,26 @@
|
|||
$ !
|
||||
$ ! Set up to compile GCC on VMS
|
||||
$ !
|
||||
$ echo = "write sys$output"
|
||||
$ !
|
||||
$ if f$search("config.h") .nes. "" then delete config.h.*
|
||||
$ copy [.config]xm-vms.h []config.h
|
||||
$ echo "Linked `config.h' to `[.config]xm-vms.h'.
|
||||
$ !
|
||||
$ if f$search("tm.h") .nes. "" then delete tm.h.*
|
||||
$ copy [.config]tm-vms.h []tm.h
|
||||
$ echo "Linked `tm.h' to `[.config]tm-vms.h'.
|
||||
$ !
|
||||
$ if f$search("md.") .nes. "" then delete md..*
|
||||
$ copy [.config]vax.md []md.
|
||||
$ echo "Linked `md' to `[.config]vax.md'.
|
||||
$ !
|
||||
$ if f$search("aux-output.c") .nes. "" then delete aux-output.c.*
|
||||
$ copy [.config]out-vax.c []aux-output.c
|
||||
$ echo "Linked `aux-output.c' to `[.config]out-vax.c'.
|
||||
$ !
|
||||
$ if f$search("config.status") .nes. "" then delete config.status.*
|
||||
$ open/write file config.status
|
||||
$ write file "Links are now set up for use with a vax running VMS."
|
||||
$ close file
|
||||
$ type config.status
|
|
@ -0,0 +1,440 @@
|
|||
#!/bin/sh
|
||||
# Configuration script for GNU CC
|
||||
# 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 1, or (at your option)
|
||||
#any later version.
|
||||
|
||||
#GNU CC is distributed in the hope that it will be useful,
|
||||
#but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
#GNU General Public License for more details.
|
||||
|
||||
#You should have received a copy of the GNU General Public License
|
||||
#along with GNU CC; see the file COPYING. If not, write to
|
||||
#the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
#
|
||||
# Shell script to create proper links to machine-dependent files in
|
||||
# preparation for compiling gcc.
|
||||
#
|
||||
# Usage: config.gcc [vint] [-srcdir=DIR] machine
|
||||
#
|
||||
# If config.gcc succeeds, it leaves its status in config.status.
|
||||
# If config.gcc fails after disturbing the status quo,
|
||||
# config.status is removed.
|
||||
#
|
||||
|
||||
progname=$0
|
||||
|
||||
remove=rm
|
||||
hard_link=ln
|
||||
symbolic_link='ln -s'
|
||||
|
||||
#for Test
|
||||
#remove="echo rm"
|
||||
#hard_link="echo ln"
|
||||
#symbolic_link="echo ln -s"
|
||||
|
||||
for arg in $*;
|
||||
do
|
||||
case $arg in
|
||||
-srcdir=*)
|
||||
srcdir=`echo $arg | sed s/-srcdir=//`
|
||||
;;
|
||||
-vint)
|
||||
vint=on
|
||||
;;
|
||||
*)
|
||||
machine=$arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Find the source files, if location was not specified.
|
||||
if [ x$srcdir = x ]
|
||||
then
|
||||
srcdirdefaulted=1
|
||||
srcdir=.
|
||||
if [ ! -r tree.c ]
|
||||
then
|
||||
srcdir=..
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -r ${srcdir}/tree.c ]
|
||||
then
|
||||
if [ x$srcdirdefaulted = x ]
|
||||
then
|
||||
echo "$progname: Can't find compiler sources in \`${srcdir}'." 1>&2
|
||||
else
|
||||
echo "$progname: Can't find compiler sources in \`.' or \`..'." 1>&2
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ x$machine != x ];
|
||||
then
|
||||
case $machine in
|
||||
vax) # for vaxen running bsd
|
||||
;;
|
||||
ultrix) # for vaxen running ultrix
|
||||
cpu_type=vax
|
||||
;;
|
||||
tahoe) # for tahoe's running bsd
|
||||
;;
|
||||
harris) # for harris tahoe, using COFF.
|
||||
cpu_type=tahoe
|
||||
;;
|
||||
vms) # for vaxen running VMS
|
||||
cpu_type=vax
|
||||
configuration_file=xm-${machine}.h
|
||||
target_machine=tm-${machine}.h
|
||||
;;
|
||||
vax-sysv | vaxv) # for vaxen running system V
|
||||
cpu_type=vax
|
||||
configuration_file=xm-vaxv.h
|
||||
target_machine=tm-vaxv.h
|
||||
;;
|
||||
sequent-i386) # for Intel 80386's on Sequent Symmetry
|
||||
cpu_type=i386
|
||||
configuration_file=xm-i386.h
|
||||
target_machine=tm-seq386.h
|
||||
;;
|
||||
fmtowns)
|
||||
cpu_type=i386
|
||||
configuration_file=xm-i386.h
|
||||
target_machine=tm-fmtowns.h
|
||||
;;
|
||||
i386-mach)
|
||||
cpu_type=i386
|
||||
configuration_file=xm-i386.h
|
||||
target_machine=tm-i386gas.h
|
||||
;;
|
||||
i386-sysv | i386v) # for Intel 80386's running system V
|
||||
machine=i386v
|
||||
cpu_type=i386
|
||||
configuration_file=xm-${machine}.h
|
||||
;;
|
||||
i386-sysv4 | i386v4) # for Intel 80386's running system V.4
|
||||
machine=i386v4
|
||||
cpu_type=i386
|
||||
configuration_file=xm-i386v.h
|
||||
;;
|
||||
i386-sysv-gas | i386g)
|
||||
cpu_type=i386
|
||||
configuration_file=xm-i386v.h
|
||||
target_machine=tm-i386vgas.h
|
||||
;;
|
||||
i386-sco) # for Intel 80386's running SCO system
|
||||
machine=i386sco
|
||||
cpu_type=i386
|
||||
configuration_file=xm-i386v.h
|
||||
;;
|
||||
i386-esix) # for Intel 80386's running ESIX system
|
||||
machine=i386esix
|
||||
cpu_type=i386
|
||||
configuration_file=xm-i386v.h
|
||||
;;
|
||||
i386-isc) # for Intel 80386's running ISC
|
||||
machine=i386isc
|
||||
cpu_type=i386
|
||||
configuration_file=xm-i386v.h
|
||||
;;
|
||||
i386-aix | ps2-aix | aix386 | ps2aix ) # for IBM PS/2 running AIX
|
||||
machine=aix386
|
||||
cpu_type=i386
|
||||
configuration_file=xm-${machine}.h
|
||||
;;
|
||||
i860)
|
||||
;;
|
||||
i860-gas)
|
||||
machine=i860
|
||||
target_machine=tm-i860g.h
|
||||
;;
|
||||
next )
|
||||
cpu_type=m68k
|
||||
target_machine=tm-next.h
|
||||
;;
|
||||
sun4-os3 | sun-4-os3)
|
||||
cpu_type=sparc
|
||||
target_machine=tm-sun4os3.h
|
||||
;;
|
||||
sun3-os3 | sun-3-os3)
|
||||
cpu_type=m68k
|
||||
target_machine=tm-sun3os3.h
|
||||
;;
|
||||
sun3-nfp-os3 | sun-3-nfp-os3)
|
||||
cpu_type=m68k
|
||||
target_machine=tm-sun3os3nf.h
|
||||
;;
|
||||
sun3-mach)
|
||||
cpu_type=m68k
|
||||
target_machine=tm-sun3mach.h
|
||||
;;
|
||||
sun2 | sun-2 | sun2-os3 | sun-2-os3)
|
||||
cpu_type=m68k
|
||||
target_machine=tm-sun2.h
|
||||
;;
|
||||
sun2-os4 | sun-2-os4)
|
||||
cpu_type=m68k
|
||||
target_machine=tm-sun2os4.h
|
||||
;;
|
||||
sun386 | sun386i | roadrunner)
|
||||
cpu_type=i386
|
||||
configuration_file=xm-sun386i.h
|
||||
target_machine=tm-sun386i.h
|
||||
;;
|
||||
sun4 | sun-4 | sun4-os4 | sun-4-os4)
|
||||
cpu_type=sparc
|
||||
target_machine=tm-sparc.h
|
||||
;;
|
||||
sun3 | sun-3 | sun3-os4 | sun-3-os4)
|
||||
cpu_type=m68k
|
||||
target_machine=tm-sun3.h
|
||||
;;
|
||||
sun3-nfp | sun-3-nfp | sun3-nfp-os4 | sun-3-nfp-os4)
|
||||
cpu_type=m68k
|
||||
target_machine=tm-sun3-nfp.h
|
||||
;;
|
||||
sun2-os4 |sun-2-os4)
|
||||
cpu_type=m68k
|
||||
target_machine=tm-sun2.h
|
||||
;;
|
||||
hp9k320) # HP 9000 series 300 with gcc alone
|
||||
cpu_type=m68k
|
||||
configuration_file=xm-hp9k320.h
|
||||
;;
|
||||
hp9k320-old) # HP 9000 series 300 with gcc alone
|
||||
cpu_type=m68k
|
||||
target_machine=tm-hp9k32old.h
|
||||
configuration_file=xm-hp9k320.h
|
||||
;;
|
||||
hp9k320-gas | hp9k320g) # with gnu as, ld and gdb
|
||||
cpu_type=m68k
|
||||
configuration_file=xm-hp9k320.h
|
||||
target_machine=tm-hp9k320g.h
|
||||
;;
|
||||
hp9k320-bsd) # HP 9000/3xx running Berkeley Unix
|
||||
cpu_type=m68k
|
||||
target_machine=tm-hp9k3bsd.h
|
||||
;;
|
||||
hp9k200-bsd) # HP 9000/2xx running Berkeley Unix
|
||||
cpu_type=m68k
|
||||
target_machine=tm-hp9k2bsd.h
|
||||
;;
|
||||
isi68)
|
||||
cpu_type=m68k
|
||||
;;
|
||||
isi68-nfp)
|
||||
cpu_type=m68k
|
||||
;;
|
||||
news | news800)
|
||||
configuration_file=xm-m68k.h
|
||||
target_machine=tm-news.h
|
||||
cpu_type=m68k
|
||||
;;
|
||||
news-gas | news-g)
|
||||
configuration_file=xm-m68k.h
|
||||
target_machine=tm-newsgas.h
|
||||
cpu_type=m68k
|
||||
;;
|
||||
altos | altos3068) # Altos 3068 with gnu as, ld and gdb
|
||||
cpu_type=m68k
|
||||
configuration_file=xm-altos3068.h
|
||||
target_machine=tm-altos3068.h
|
||||
;;
|
||||
3b1)
|
||||
cpu_type=m68k
|
||||
configuration_file=xm-${machine}.h
|
||||
;;
|
||||
3b1g | 3b1-gas)
|
||||
machine=3b1g
|
||||
cpu_type=m68k
|
||||
configuration_file=xm-3b1.h
|
||||
;;
|
||||
delta68k | motorola-3300 | delta)
|
||||
cpu_type=m68k
|
||||
configuration_file=xm-delta68k.h
|
||||
target_machine=tm-delta68k.h
|
||||
;;
|
||||
sequent-ns32k | sequent)
|
||||
machine=sequent
|
||||
cpu_type=ns32k
|
||||
;;
|
||||
encore)
|
||||
cpu_type=ns32k
|
||||
;;
|
||||
genix)
|
||||
target_machine=tm-genix.h
|
||||
machine=ns32k
|
||||
cpu_type=ns32k
|
||||
configuration_file=xm-genix.h
|
||||
;;
|
||||
88000)
|
||||
cpu_type=m88k
|
||||
target_machine=tm-${cpu_type}.h
|
||||
;;
|
||||
alliant) # Alliant FX/8
|
||||
;;
|
||||
convex-c1) # Convex C1
|
||||
if [ -r /usr/include/stdlib.h ]
|
||||
then
|
||||
target_machine=tm-convex1.h
|
||||
else
|
||||
target_machine=tm-conv1os7.h
|
||||
fi
|
||||
cpu_type=convex
|
||||
;;
|
||||
convex-c2) # Convex C2
|
||||
if [ -r /usr/include/stdlib.h ]
|
||||
then
|
||||
target_machine=tm-convex2.h
|
||||
else
|
||||
target_machine=tm-conv2os7.h
|
||||
fi
|
||||
cpu_type=convex
|
||||
;;
|
||||
iris) # Mostly like a MIPS.
|
||||
cpu_type=mips
|
||||
target_machine=tm-iris.h
|
||||
configuration_file=xm-iris.h
|
||||
;;
|
||||
mips) # Default MIPS environment
|
||||
;;
|
||||
mips-os5) # SYSV variant of MIPS system.
|
||||
cpu_type=mips
|
||||
target_machine=tm-mips-5.h
|
||||
;;
|
||||
mips-os4) # Default MIPS environment on RISC-OS 4.00
|
||||
cpu_type=mips
|
||||
;;
|
||||
mips-sysv-os5) # SYSV variant of MIPS system, RISC-OS 5.00
|
||||
cpu_type=mips
|
||||
target_machine=tm-mips-5s.h
|
||||
configuration_file=xm-umips.h
|
||||
;;
|
||||
mips-bsd43-os5) # BSD 4.3 variant of MIPS system, RISC-OS 5.00
|
||||
cpu_type=mips
|
||||
target_machine=tm-mips-5b.h
|
||||
;;
|
||||
mips-sysv | mips-sysv-os4) # SYSV variant of MIPS system, RISC-OS 4.00
|
||||
cpu_type=mips
|
||||
target_machine=tm-mips-sysv.h
|
||||
configuration_file=xm-umips.h
|
||||
;;
|
||||
mips-bsd43 | mips-bsd43-os4) # BSD 4.3 variant of MIPS system, RISC-OS 4.00
|
||||
cpu_type=mips
|
||||
target_machine=tm-mips-bsd.h
|
||||
;;
|
||||
mips-news | news-3600 | risc-news) # Sony NEWS 3600 or risc/news.
|
||||
cpu_type=mips
|
||||
target_machine=tm-mips-news.h
|
||||
;;
|
||||
dec-3100 | decstation) # Decstation or pmax.
|
||||
cpu_type=mips
|
||||
target_machine=tm-decstatn.h
|
||||
;;
|
||||
apollo68)
|
||||
cpu_type=m68k
|
||||
;;
|
||||
tower) # NCR Tower 32 SVR3. as with sdb debugging.
|
||||
cpu_type=m68k
|
||||
target_machine=tm-tower-as.h
|
||||
configuration_file=xm-tower.h
|
||||
;;
|
||||
pyr | pyramid)
|
||||
machine=pyr
|
||||
;;
|
||||
# 370)
|
||||
# machine=370
|
||||
# ;;
|
||||
esac
|
||||
|
||||
# if cpu_type is not set, define cpu_type to machine.
|
||||
#
|
||||
cpu_type=${cpu_type-$machine}
|
||||
configuration_file=${configuration_file-xm-$cpu_type.h}
|
||||
target_machine=${target_machine-tm-$machine.h}
|
||||
machine_description=${cpu_type}.md
|
||||
aux_output=${aux_output-out-$cpu_type.c}
|
||||
|
||||
if [ xx${vint} = xx ]
|
||||
then
|
||||
files="$configuration_file $target_machine
|
||||
$machine_description $aux_output"
|
||||
links="config.h tm.h md aux-output.c"
|
||||
else
|
||||
files="$configuration_file tm-vmc.h $target_machine
|
||||
$machine_description $aux_output"
|
||||
links="config.h tm.h tm-pre.h md aux-output.c"
|
||||
fi
|
||||
|
||||
while [ -n "$files" ]
|
||||
do
|
||||
# set file to car of files, files to cdr of files
|
||||
set $files; file=$1; shift; files=$*
|
||||
set $links; link=$1; shift; links=$*
|
||||
|
||||
if [ ! -r ${srcdir}/config/$file ]
|
||||
then
|
||||
echo "$progname: cannot create a link \`$link'," 1>&2
|
||||
echo "since the file \`config/$file' does not exist." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
$remove -f $link
|
||||
rm -f config.status
|
||||
# Make a symlink if possible, otherwise try a hard link
|
||||
$symbolic_link ${srcdir}/config/$file $link 2>/dev/null || $hard_link ${srcdir}/config/$file $link
|
||||
|
||||
if [ ! -r $link ]
|
||||
then
|
||||
echo "$progname: unable to link \`$link' to \`${srcdir}/config/$file'." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Linked \`$link' to \`${srcdir}/config/$file'."
|
||||
done
|
||||
|
||||
if [ xx${vint} = xx ]
|
||||
then
|
||||
echo "Links are now set up for use with a $machine." \
|
||||
| tee config.status
|
||||
else
|
||||
echo "Links are now set up for use with a $machine (vint)." \
|
||||
| tee config.status
|
||||
fi
|
||||
|
||||
# Install a makefile, and make it set VPATH
|
||||
# if necessary so that the sources are found.
|
||||
# Also change its value of srcdir.
|
||||
# Also create a .gdbinit file which runs the one in srcdir
|
||||
# and tells GDB to look there for source files.
|
||||
case $srcdir in
|
||||
.)
|
||||
;;
|
||||
*)
|
||||
echo "VPATH = ${srcdir}" > x
|
||||
cat x ${srcdir}/Makefile | sed "s@^srcdir = \.@srcdir = ${srcdir}@" > Makefile
|
||||
rm x
|
||||
echo "dir ." > .gdbinit
|
||||
echo "dir ${srcdir}" >> .gdbinit
|
||||
echo "source ${srcdir}/.gdbinit" >> .gdbinit
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
else
|
||||
echo "Usage: $progname machine"
|
||||
echo -n "Where \`machine' is something like "
|
||||
echo "\`vax', \`sun3', \`encore', etc."
|
||||
if [ -r config.status ]
|
||||
then
|
||||
cat config.status
|
||||
fi
|
||||
exit 1
|
||||
fi
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This progam 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.
|
||||
*
|
||||
* Alliance VLSI CAD System 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 the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Description de la machine virtuelle
|
||||
*
|
||||
* Ecrit par Arnaud COMPAN & Francois PECHEUX ** avril-juin 1990
|
||||
*
|
||||
*/
|
||||
|
||||
#define MY_SUN
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define HOST_BITS_PER_CHAR 8
|
||||
#define HOST_BITS_PER_SHORT 16
|
||||
#define HOST_BITS_PER_INT 32
|
||||
#define HOST_BITS_PER_LONG 32
|
||||
|
||||
#define SUCCESS_EXIT_CODE 0
|
||||
#define FATAL_EXIT_CODE 33
|
||||
|
||||
#ifdef MY_SUN
|
||||
#define USG
|
||||
#endif
|
||||
|
||||
#include "tm.h"
|
||||
|
||||
#ifdef MY_SUN
|
||||
#define bcopy(a,b,c) memcpy (b,a,c)
|
||||
#define bzero(a,b) memset (a,0,b)
|
||||
#define bcmp(a,b,c) memcmp (a,b,c)
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define alloca(n) __builtin_alloca(n)
|
||||
#endif
|
||||
|
|
@ -0,0 +1 @@
|
|||
Links are now set up for use with a mu.
|
|
@ -0,0 +1,869 @@
|
|||
;; -------------------------------------------------------------
|
||||
|
||||
;;
|
||||
;; Description de la machine universelle
|
||||
;;
|
||||
|
||||
;;
|
||||
;; Ecrit par Arnaud COMPAN & Francois PECHEUX ** avril-juin 1990
|
||||
;; Quelques modifs par Frederic Petrot, 91/92
|
||||
|
||||
;; -------------------------------------------------------------
|
||||
|
||||
(define_insn "cmpqi"
|
||||
[(set (cc0)
|
||||
(compare (match_operand:QI 0 "general_operand" "g")
|
||||
(match_operand:QI 1 "general_operand" "g")))]
|
||||
""
|
||||
"cmp.qi %0,%1")
|
||||
|
||||
(define_insn "cmphi"
|
||||
[(set (cc0)
|
||||
(compare (match_operand:HI 0 "general_operand" "g")
|
||||
(match_operand:HI 1 "general_operand" "g")))]
|
||||
""
|
||||
"cmp.hi %0,%1")
|
||||
|
||||
(define_insn "cmpsi"
|
||||
[(set (cc0)
|
||||
(compare (match_operand:SI 0 "general_operand" "g")
|
||||
(match_operand:SI 1 "general_operand" "g")))]
|
||||
""
|
||||
"cmp.si %0,%1")
|
||||
|
||||
(define_insn "cmpsf"
|
||||
[(set (cc0)
|
||||
(compare (match_operand:SF 0 "general_operand" "g")
|
||||
(match_operand:SF 1 "general_operand" "g")))]
|
||||
""
|
||||
"cmp.sf %0,%1")
|
||||
|
||||
(define_insn "cmpdf"
|
||||
[(set (cc0)
|
||||
(compare (match_operand:DF 0 "general_operand" "g")
|
||||
(match_operand:DF 1 "general_operand" "g")))]
|
||||
""
|
||||
"cmp.df %0,%1")
|
||||
|
||||
(define_insn "tstqi"
|
||||
[(set (cc0)
|
||||
(match_operand:QI 0 "general_operand" "g"))]
|
||||
""
|
||||
"cmp.qi %0,#0")
|
||||
|
||||
(define_insn "tsthi"
|
||||
[(set (cc0)
|
||||
(match_operand:HI 0 "general_operand" "g"))]
|
||||
""
|
||||
"cmp.hi %0,#0")
|
||||
|
||||
(define_insn "tstsi"
|
||||
[(set (cc0)
|
||||
(match_operand:SI 0 "general_operand" "g"))]
|
||||
""
|
||||
"cmp.si %0,#0")
|
||||
|
||||
(define_insn "tstsf"
|
||||
[(set (cc0)
|
||||
(match_operand:SF 0 "general_operand" "g"))]
|
||||
""
|
||||
"cmp.sf %0,#0")
|
||||
|
||||
(define_insn "tstdf"
|
||||
[(set (cc0)
|
||||
(match_operand:DF 0 "general_operand" "g"))]
|
||||
""
|
||||
"cmp.df %0,#0")
|
||||
|
||||
(define_insn "movqi"
|
||||
[(set (match_operand:QI 0 "general_operand" "=g")
|
||||
(match_operand:QI 1 "general_operand" "g"))]
|
||||
""
|
||||
"mov.qi %0,%1")
|
||||
|
||||
(define_insn "movhi"
|
||||
[(set (match_operand:HI 0 "general_operand" "=g")
|
||||
(match_operand:HI 1 "general_operand" "g"))]
|
||||
""
|
||||
"mov.hi %0,%1")
|
||||
|
||||
(define_insn "movsi"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(match_operand:SI 1 "general_operand" "g"))]
|
||||
""
|
||||
"mov.si %0,%1")
|
||||
|
||||
(define_insn "movsf"
|
||||
[(set (match_operand:SF 0 "general_operand" "=g")
|
||||
(match_operand:SF 1 "general_operand" "g"))]
|
||||
""
|
||||
"mov.sf %0,%1")
|
||||
|
||||
(define_insn "movdf"
|
||||
[(set (match_operand:DF 0 "general_operand" "=g")
|
||||
(match_operand:DF 1 "general_operand" "g"))]
|
||||
""
|
||||
"mov.df %0,%1")
|
||||
|
||||
(define_insn "extendqihi2"
|
||||
[(set (match_operand:HI 0 "general_operand" "=g")
|
||||
(sign_extend:HI
|
||||
(match_operand:QI 1 "general_operand" "g")))]
|
||||
""
|
||||
"ext.qi.hi %1,%0")
|
||||
|
||||
(define_insn "extendqisi2"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(sign_extend:SI
|
||||
(match_operand:QI 1 "general_operand" "g")))]
|
||||
""
|
||||
"ext.qi.si %1,%0")
|
||||
|
||||
(define_insn "extendhisi2"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(sign_extend:SI
|
||||
(match_operand:HI 1 "general_operand" "g")))]
|
||||
""
|
||||
"ext.hi.si %1,%0")
|
||||
|
||||
(define_insn "zero_extendhisi2"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(zero_extend:SI
|
||||
(match_operand:HI 1 "general_operand" "g")))]
|
||||
""
|
||||
"ext0.hi.si %1,%0")
|
||||
|
||||
(define_insn "zero_extendqihi2"
|
||||
[(set (match_operand:HI 0 "general_operand" "=g")
|
||||
(zero_extend:HI
|
||||
(match_operand:QI 1 "general_operand" "g")))]
|
||||
""
|
||||
"ext0.qi.hi %1,%0")
|
||||
|
||||
(define_insn "zero_extendqisi2"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(zero_extend:SI
|
||||
(match_operand:QI 1 "general_operand" "g")))]
|
||||
""
|
||||
"ext0.qi.si %1,%0")
|
||||
|
||||
(define_insn "extendsfdf2"
|
||||
[(set (match_operand:DF 0 "general_operand" "=g")
|
||||
(float_extend:DF
|
||||
(match_operand:SF 1 "general_operand" "g")))]
|
||||
""
|
||||
"ext.sf.df %1,%0")
|
||||
|
||||
(define_insn "truncsiqi2"
|
||||
[(set (match_operand:QI 0 "general_operand" "=g")
|
||||
(truncate:QI
|
||||
(match_operand:SI 1 "general_operand" "g")))]
|
||||
""
|
||||
"trunc.si.qi %1,%0")
|
||||
|
||||
(define_insn "truncsihi2"
|
||||
[(set (match_operand:HI 0 "general_operand" "=g")
|
||||
(truncate:HI
|
||||
(match_operand:SI 1 "general_operand" "g")))]
|
||||
""
|
||||
"trunc.si.hi %1,%0")
|
||||
|
||||
(define_insn "trunchiqi2"
|
||||
[(set (match_operand:QI 0 "general_operand" "=g")
|
||||
(truncate:QI
|
||||
(match_operand:HI 1 "general_operand" "g")))]
|
||||
""
|
||||
"trunc.hi.qi %1,%0")
|
||||
|
||||
(define_insn "truncdfsf2"
|
||||
[(set (match_operand:SF 0 "general_operand" "=g")
|
||||
(float_truncate:SF
|
||||
(match_operand:DF 1 "general_operand" "g")))]
|
||||
""
|
||||
"trunc.df.sf %1,%0")
|
||||
|
||||
(define_insn "floatqisf2"
|
||||
[(set (match_operand:SF 0 "general_operand" "=g")
|
||||
(float:SF (match_operand:QI 1 "general_operand" "g")))]
|
||||
""
|
||||
"float.qi.sf %1,%0")
|
||||
|
||||
(define_insn "floathisf2"
|
||||
[(set (match_operand:SF 0 "general_operand" "=g")
|
||||
(float:SF (match_operand:HI 1 "general_operand" "g")))]
|
||||
""
|
||||
"float.hi.sf %1,%0")
|
||||
|
||||
(define_insn "floatsisf2"
|
||||
[(set (match_operand:SF 0 "general_operand" "=g")
|
||||
(float:SF (match_operand:SI 1 "general_operand" "g")))]
|
||||
""
|
||||
"float.si.sf %1,%0")
|
||||
|
||||
(define_insn "floatqidf2"
|
||||
[(set (match_operand:DF 0 "general_operand" "=g")
|
||||
(float:DF (match_operand:QI 1 "general_operand" "g")))]
|
||||
""
|
||||
"float.qi.df %1,%0")
|
||||
|
||||
(define_insn "floathidf2"
|
||||
[(set (match_operand:DF 0 "general_operand" "=g")
|
||||
(float:DF (match_operand:HI 1 "general_operand" "g")))]
|
||||
""
|
||||
"float.hi.df %1,%0")
|
||||
|
||||
(define_insn "floatsidf2"
|
||||
[(set (match_operand:DF 0 "general_operand" "=g")
|
||||
(float:DF (match_operand:SI 1 "general_operand" "g")))]
|
||||
""
|
||||
"float.si.df %1,%0")
|
||||
|
||||
(define_insn "fix_truncsfqi2"
|
||||
[(set (match_operand:QI 0 "general_operand" "=g")
|
||||
(fix:QI (fix:SF (match_operand:SF 1 "general_operand" "g"))))]
|
||||
""
|
||||
"fix_trunc.sf.qi %1,%0")
|
||||
|
||||
(define_insn "fix_truncsfhi2"
|
||||
[(set (match_operand:HI 0 "general_operand" "=g")
|
||||
(fix:HI (fix:SF (match_operand:SF 1 "general_operand" "g"))))]
|
||||
""
|
||||
"fix_trunc.sf.hi %1,%0")
|
||||
|
||||
(define_insn "fix_truncsfsi2"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(fix:SI (fix:SF (match_operand:SF 1 "general_operand" "g"))))]
|
||||
""
|
||||
"fix_trunc.sf.si %1,%0")
|
||||
|
||||
(define_insn "fix_truncdfqi2"
|
||||
[(set (match_operand:QI 0 "general_operand" "=g")
|
||||
(fix:QI (fix:DF (match_operand:DF 1 "general_operand" "g"))))]
|
||||
""
|
||||
"fix_trunc.df.qi %1,%0")
|
||||
|
||||
(define_insn "fix_truncdfhi2"
|
||||
[(set (match_operand:HI 0 "general_operand" "=g")
|
||||
(fix:HI (fix:DF (match_operand:DF 1 "general_operand" "g"))))]
|
||||
""
|
||||
"fix_trunc.df.hi %1,%0")
|
||||
|
||||
(define_insn "fix_truncdfsi2"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(fix:SI (fix:DF (match_operand:DF 1 "general_operand" "g"))))]
|
||||
""
|
||||
"fix_trunc.df.si %1,%0")
|
||||
|
||||
(define_insn "fixunssfqi2"
|
||||
[(set (match_operand:QI 0 "general_operand" "=g")
|
||||
(unsigned_fix:QI (fix:SF (match_operand:SF 1 "general_operand" "g"))))]
|
||||
""
|
||||
"fixuns.sf.qi %1,%0")
|
||||
|
||||
(define_insn "fixunssfhi2"
|
||||
[(set (match_operand:HI 0 "general_operand" "=g")
|
||||
(unsigned_fix:HI (fix:SF (match_operand:SF 1 "general_operand" "g"))))]
|
||||
""
|
||||
"fixuns.sf.hi %1,%0")
|
||||
|
||||
(define_insn "fixunssfsi2"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(unsigned_fix:SI (fix:SF (match_operand:SF 1 "general_operand" "g"))))]
|
||||
""
|
||||
"fixuns.sf.si %1,%0")
|
||||
|
||||
(define_insn "fixunsdfqi2"
|
||||
[(set (match_operand:QI 0 "general_operand" "=g")
|
||||
(unsigned_fix:QI (fix:DF (match_operand:DF 1 "general_operand" "g"))))]
|
||||
""
|
||||
"fixuns.df.qi %1,%0")
|
||||
|
||||
(define_insn "fixunsdfhi2"
|
||||
[(set (match_operand:HI 0 "general_operand" "=g")
|
||||
(unsigned_fix:HI (fix:DF (match_operand:DF 1 "general_operand" "g"))))]
|
||||
""
|
||||
"fixuns.df.hi %1,%0")
|
||||
|
||||
(define_insn "fixunsdfsi2"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(unsigned_fix:SI (fix:DF (match_operand:DF 1 "general_operand" "g"))))]
|
||||
""
|
||||
"fixuns.df.si %1,%0")
|
||||
|
||||
(define_insn "addqi3"
|
||||
[(set (match_operand:QI 0 "general_operand" "=g")
|
||||
(plus:QI (match_operand:QI 1 "general_operand" "%g")
|
||||
(match_operand:QI 2 "general_operand" "g")))]
|
||||
""
|
||||
"add.qi %0,%1,%2")
|
||||
|
||||
(define_insn "addhi3"
|
||||
[(set (match_operand:HI 0 "general_operand" "=g")
|
||||
(plus:HI (match_operand:HI 1 "general_operand" "%g")
|
||||
(match_operand:HI 2 "general_operand" "g")))]
|
||||
""
|
||||
"add.hi %0,%1,%2")
|
||||
|
||||
(define_insn "addsi3"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(plus:SI (match_operand:SI 1 "general_operand" "%g")
|
||||
(match_operand:SI 2 "general_operand" "g")))]
|
||||
""
|
||||
"add.si %0,%1,%2")
|
||||
|
||||
(define_insn "addsf3"
|
||||
[(set (match_operand:SF 0 "general_operand" "=g")
|
||||
(plus:SF (match_operand:SF 1 "general_operand" "%g")
|
||||
(match_operand:SF 2 "general_operand" "g")))]
|
||||
""
|
||||
"add.sf %0,%1,%2")
|
||||
|
||||
(define_insn "adddf3"
|
||||
[(set (match_operand:DF 0 "general_operand" "=g")
|
||||
(plus:DF (match_operand:DF 1 "general_operand" "%g")
|
||||
(match_operand:DF 2 "general_operand" "g")))]
|
||||
""
|
||||
"add.df %0,%1,%2")
|
||||
|
||||
(define_insn "mulqi3"
|
||||
[(set (match_operand:QI 0 "general_operand" "=g")
|
||||
(mult:QI (match_operand:QI 1 "general_operand" "%g")
|
||||
(match_operand:QI 2 "general_operand" "g")))]
|
||||
""
|
||||
"mul.qi %0,%1,%2")
|
||||
|
||||
(define_insn "mulhi3"
|
||||
[(set (match_operand:HI 0 "general_operand" "=g")
|
||||
(mult:HI (match_operand:HI 1 "general_operand" "%g")
|
||||
(match_operand:HI 2 "general_operand" "g")))]
|
||||
""
|
||||
"mul.hi %0,%1,%2")
|
||||
|
||||
(define_insn "mulsi3"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(mult:SI (match_operand:SI 1 "general_operand" "%g")
|
||||
(match_operand:SI 2 "general_operand" "g")))]
|
||||
""
|
||||
"mul.si %0,%1,%2")
|
||||
|
||||
(define_insn "mulsf3"
|
||||
[(set (match_operand:SF 0 "general_operand" "=g")
|
||||
(mult:SF (match_operand:SF 1 "general_operand" "%g")
|
||||
(match_operand:SF 2 "general_operand" "g")))]
|
||||
""
|
||||
"mul.sf %0,%1,%2")
|
||||
|
||||
(define_insn "muldf3"
|
||||
[(set (match_operand:DF 0 "general_operand" "=g")
|
||||
(mult:DF (match_operand:DF 1 "general_operand" "%g")
|
||||
(match_operand:DF 2 "general_operand" "g")))]
|
||||
""
|
||||
"mul.df %0,%1,%2")
|
||||
|
||||
(define_insn "divqi3"
|
||||
[(set (match_operand:QI 0 "general_operand" "=g")
|
||||
(div:QI (match_operand:QI 1 "general_operand" "g")
|
||||
(match_operand:QI 2 "general_operand" "g")))]
|
||||
""
|
||||
"div.qi %0,%1,%2")
|
||||
|
||||
(define_insn "divhi3"
|
||||
[(set (match_operand:HI 0 "general_operand" "=g")
|
||||
(div:HI (match_operand:HI 1 "general_operand" "g")
|
||||
(match_operand:HI 2 "general_operand" "g")))]
|
||||
""
|
||||
"div.hi %0,%1,%2")
|
||||
|
||||
(define_insn "divsi3"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(div:SI (match_operand:SI 1 "general_operand" "g")
|
||||
(match_operand:SI 2 "general_operand" "g")))]
|
||||
""
|
||||
"div.si %0,%1,%2")
|
||||
|
||||
(define_insn "divsf3"
|
||||
[(set (match_operand:SF 0 "general_operand" "=g")
|
||||
(div:SF (match_operand:SF 1 "general_operand" "g")
|
||||
(match_operand:SF 2 "general_operand" "g")))]
|
||||
""
|
||||
"div.sf %0,%1,%2")
|
||||
|
||||
(define_insn "divdf3"
|
||||
[(set (match_operand:DF 0 "general_operand" "=g")
|
||||
(div:DF (match_operand:DF 1 "general_operand" "g")
|
||||
(match_operand:DF 2 "general_operand" "g")))]
|
||||
""
|
||||
"div.df %0,%1,%2")
|
||||
|
||||
(define_insn "subqi3"
|
||||
[(set (match_operand:QI 0 "general_operand" "=g")
|
||||
(minus:QI (match_operand:QI 1 "general_operand" "g")
|
||||
(match_operand:QI 2 "general_operand" "g")))]
|
||||
""
|
||||
"sub.qi %0,%1,%2")
|
||||
|
||||
(define_insn "subhi3"
|
||||
[(set (match_operand:HI 0 "general_operand" "=g")
|
||||
(minus:HI (match_operand:HI 1 "general_operand" "g")
|
||||
(match_operand:HI 2 "general_operand" "g")))]
|
||||
""
|
||||
"sub.hi %0,%1,%2")
|
||||
|
||||
(define_insn "subsi3"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(minus:SI (match_operand:SI 1 "general_operand" "g")
|
||||
(match_operand:SI 2 "general_operand" "g")))]
|
||||
""
|
||||
"sub.si %0,%1,%2")
|
||||
|
||||
(define_insn "subsf3"
|
||||
[(set (match_operand:SF 0 "general_operand" "=g")
|
||||
(minus:SF (match_operand:SF 1 "general_operand" "g")
|
||||
(match_operand:SF 2 "general_operand" "g")))]
|
||||
""
|
||||
"sub.sf %0,%1,%2")
|
||||
|
||||
(define_insn "subdf3"
|
||||
[(set (match_operand:DF 0 "general_operand" "=g")
|
||||
(minus:DF (match_operand:DF 1 "general_operand" "g")
|
||||
(match_operand:DF 2 "general_operand" "g")))]
|
||||
""
|
||||
"sub.df %0,%1,%2")
|
||||
|
||||
(define_insn "andqi3"
|
||||
[(set (match_operand:QI 0 "general_operand" "=g")
|
||||
(and:QI (match_operand:QI 1 "general_operand" "%g")
|
||||
(match_operand:QI 2 "general_operand" "g")))]
|
||||
""
|
||||
"and.qi %0,%1,%2")
|
||||
|
||||
(define_insn "andhi3"
|
||||
[(set (match_operand:HI 0 "general_operand" "=g")
|
||||
(and:HI (match_operand:HI 1 "general_operand" "%g")
|
||||
(match_operand:HI 2 "general_operand" "g")))]
|
||||
""
|
||||
"and.hi %0,%1,%2")
|
||||
|
||||
(define_insn "andsi3"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(and:SI (match_operand:SI 1 "general_operand" "%g")
|
||||
(match_operand:SI 2 "general_operand" "g")))]
|
||||
""
|
||||
"and.si %0,%1,%2")
|
||||
|
||||
(define_insn "iorqi3"
|
||||
[(set (match_operand:QI 0 "general_operand" "=g")
|
||||
(ior:QI (match_operand:QI 1 "general_operand" "%g")
|
||||
(match_operand:QI 2 "general_operand" "g")))]
|
||||
""
|
||||
"or.qi %0,%1,%2")
|
||||
|
||||
(define_insn "iorhi3"
|
||||
[(set (match_operand:HI 0 "general_operand" "=g")
|
||||
(ior:HI (match_operand:HI 1 "general_operand" "%g")
|
||||
(match_operand:HI 2 "general_operand" "g")))]
|
||||
""
|
||||
"or.hi %0,%1,%2")
|
||||
|
||||
(define_insn "iorsi3"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(ior:SI (match_operand:SI 1 "general_operand" "%g")
|
||||
(match_operand:SI 2 "general_operand" "g")))]
|
||||
""
|
||||
"or.si %0,%1,%2")
|
||||
|
||||
(define_insn "xorqi3"
|
||||
[(set (match_operand:QI 0 "general_operand" "=g")
|
||||
(xor:QI (match_operand:QI 1 "general_operand" "%g")
|
||||
(match_operand:QI 2 "general_operand" "g")))]
|
||||
""
|
||||
"xor.qi %0,%1,%2")
|
||||
|
||||
(define_insn "xorhi3"
|
||||
[(set (match_operand:HI 0 "general_operand" "=g")
|
||||
(xor:HI (match_operand:HI 1 "general_operand" "%g")
|
||||
(match_operand:HI 2 "general_operand" "g")))]
|
||||
""
|
||||
"xor.hi %0,%1,%2")
|
||||
|
||||
(define_insn "xorsi3"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(xor:SI (match_operand:SI 1 "general_operand" "%g")
|
||||
(match_operand:SI 2 "general_operand" "g")))]
|
||||
""
|
||||
"xor.si %0,%1,%2")
|
||||
|
||||
(define_insn "negqi2"
|
||||
[(set (match_operand:QI 0 "general_operand" "=g")
|
||||
(neg:QI (match_operand:QI 1 "general_operand" "g")))]
|
||||
""
|
||||
"neg.qi %0,%1")
|
||||
|
||||
(define_insn "neghi2"
|
||||
[(set (match_operand:HI 0 "general_operand" "=g")
|
||||
(neg:HI (match_operand:HI 1 "general_operand" "g")))]
|
||||
""
|
||||
"neg.hi %0,%1")
|
||||
|
||||
(define_insn "negsi2"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(neg:SI (match_operand:SI 1 "general_operand" "g")))]
|
||||
""
|
||||
"neg.si %0,%1")
|
||||
|
||||
(define_insn "one_cmplqi2"
|
||||
[(set (match_operand:QI 0 "general_operand" "=g")
|
||||
(not:QI (match_operand:QI 1 "general_operand" "g")))]
|
||||
""
|
||||
"not.qi %0,%1")
|
||||
|
||||
(define_insn "one_cmplhi2"
|
||||
[(set (match_operand:HI 0 "general_operand" "=g")
|
||||
(not:HI (match_operand:HI 1 "general_operand" "g")))]
|
||||
""
|
||||
"not.hi %0,%1")
|
||||
|
||||
(define_insn "one_cmplsi2"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(not:SI (match_operand:SI 1 "general_operand" "g")))]
|
||||
""
|
||||
"not.si %0,%1")
|
||||
|
||||
(define_insn "ashlqi3"
|
||||
[(set (match_operand:QI 0 "general_operand" "=g")
|
||||
(ashift:QI (match_operand:QI 1 "general_operand" "g")
|
||||
(match_operand:QI 2 "general_operand" "g")))]
|
||||
""
|
||||
"asl.qi %0,%1,%2")
|
||||
|
||||
(define_insn "ashlhi3"
|
||||
[(set (match_operand:HI 0 "general_operand" "=g")
|
||||
(ashift:HI (match_operand:HI 1 "general_operand" "g")
|
||||
(match_operand:HI 2 "general_operand" "g")))]
|
||||
""
|
||||
"asl.hi %0,%1,%2")
|
||||
|
||||
(define_insn "ashlsi3"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(ashift:SI (match_operand:SI 1 "general_operand" "g")
|
||||
(match_operand:SI 2 "general_operand" "g")))]
|
||||
""
|
||||
"asl.si %0,%1,%2")
|
||||
|
||||
(define_insn "ashrqi3"
|
||||
[(set (match_operand:QI 0 "general_operand" "=g")
|
||||
(ashiftrt:QI (match_operand:QI 1 "general_operand" "g")
|
||||
(match_operand:QI 2 "general_operand" "g")))]
|
||||
""
|
||||
"asr.qi %0,%1,%2")
|
||||
|
||||
(define_insn "ashrhi3"
|
||||
[(set (match_operand:HI 0 "general_operand" "=g")
|
||||
(ashiftrt:HI (match_operand:HI 1 "general_operand" "g")
|
||||
(match_operand:HI 2 "general_operand" "g")))]
|
||||
""
|
||||
"asr.hi %0,%1,%2")
|
||||
|
||||
(define_insn "ashrsi3"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(ashiftrt:SI (match_operand:SI 1 "general_operand" "g")
|
||||
(match_operand:SI 2 "general_operand" "g")))]
|
||||
""
|
||||
"asr.si %0,%1,%2")
|
||||
|
||||
(define_insn "lshlqi3"
|
||||
[(set (match_operand:QI 0 "general_operand" "=g")
|
||||
(lshift:QI (match_operand:QI 1 "general_operand" "g")
|
||||
(match_operand:QI 2 "general_operand" "g")))]
|
||||
""
|
||||
"lsl.qi %0,%1,%2")
|
||||
|
||||
(define_insn "lshlhi3"
|
||||
[(set (match_operand:HI 0 "general_operand" "=g")
|
||||
(lshift:HI (match_operand:HI 1 "general_operand" "g")
|
||||
(match_operand:HI 2 "general_operand" "g")))]
|
||||
""
|
||||
"lsl.hi %0,%1,%2")
|
||||
|
||||
(define_insn "lshlsi3"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(lshift:SI (match_operand:SI 1 "general_operand" "g")
|
||||
(match_operand:SI 2 "general_operand" "g")))]
|
||||
""
|
||||
"lsl.si %0,%1,%2")
|
||||
|
||||
(define_insn "lshrqi3"
|
||||
[(set (match_operand:QI 0 "general_operand" "=g")
|
||||
(lshiftrt:QI (match_operand:QI 1 "general_operand" "g")
|
||||
(match_operand:QI 2 "general_operand" "g")))]
|
||||
""
|
||||
"lsr.qi %0,%1,%2")
|
||||
|
||||
(define_insn "lshrhi3"
|
||||
[(set (match_operand:HI 0 "general_operand" "=g")
|
||||
(lshiftrt:HI (match_operand:HI 1 "general_operand" "g")
|
||||
(match_operand:HI 2 "general_operand" "g")))]
|
||||
""
|
||||
"lsr.hi %0,%1,%2")
|
||||
|
||||
(define_insn "lshrsi3"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(lshiftrt:SI (match_operand:SI 1 "general_operand" "g")
|
||||
(match_operand:SI 2 "general_operand" "g")))]
|
||||
""
|
||||
"lsr.si %0,%1,%2")
|
||||
|
||||
/*
|
||||
(define_insn "rotlqi3"
|
||||
[(set (match_operand:QI 0 "general_operand" "=g")
|
||||
(rotate:QI (match_operand:QI 1 "general_operand" "g")
|
||||
(match_operand:QI 2 "general_operand" "g")))]
|
||||
""
|
||||
"rotl.qi %0,%1,%2")
|
||||
|
||||
(define_insn "rotlhi3"
|
||||
[(set (match_operand:HI 0 "general_operand" "=g")
|
||||
(rotate:HI (match_operand:HI 1 "general_operand" "g")
|
||||
(match_operand:HI 2 "general_operand" "g")))]
|
||||
""
|
||||
"rotl.hi %0,%1,%2")
|
||||
|
||||
(define_insn "rotlsi3"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(rotate:SI (match_operand:SI 1 "general_operand" "g")
|
||||
(match_operand:SI 2 "general_operand" "g")))]
|
||||
""
|
||||
"rotl.si %0,%1,%2")
|
||||
|
||||
(define_insn "rotrqi3"
|
||||
[(set (match_operand:QI 0 "general_operand" "=g")
|
||||
(rotatert:QI (match_operand:QI 1 "general_operand" "g")
|
||||
(match_operand:QI 2 "general_operand" "g")))]
|
||||
""
|
||||
"rotr.qi %0,%1,%2")
|
||||
|
||||
(define_insn "rotrhi3"
|
||||
[(set (match_operand:HI 0 "general_operand" "=g")
|
||||
(rotatert:HI (match_operand:HI 1 "general_operand" "g")
|
||||
(match_operand:HI 2 "general_operand" "g")))]
|
||||
""
|
||||
"rotr.hi %0,%1,%2")
|
||||
|
||||
(define_insn "rotrsi3"
|
||||
[(set (match_operand:SI 0 "general_operand" "=g")
|
||||
(rotatert:SI (match_operand:SI 1 "general_operand" "g")
|
||||
(match_operand:SI 2 "general_operand" "g")))]
|
||||
""
|
||||
"rotr.si %0,%1,%2")
|
||||
*/
|
||||
|
||||
(define_insn "beq"
|
||||
[(set (pc)
|
||||
(if_then_else (eq (cc0)
|
||||
(const_int 0))
|
||||
(label_ref (match_operand 0 "" ""))
|
||||
(pc)))]
|
||||
""
|
||||
"beq %l0")
|
||||
|
||||
(define_insn "bne"
|
||||
[(set (pc)
|
||||
(if_then_else (ne (cc0)
|
||||
(const_int 0))
|
||||
(label_ref (match_operand 0 "" ""))
|
||||
(pc)))]
|
||||
""
|
||||
"bne %l0")
|
||||
|
||||
(define_insn "bgt"
|
||||
[(set (pc)
|
||||
(if_then_else (gt (cc0)
|
||||
(const_int 0))
|
||||
(label_ref (match_operand 0 "" ""))
|
||||
(pc)))]
|
||||
""
|
||||
"bgt %l0")
|
||||
|
||||
(define_insn "bgtu"
|
||||
[(set (pc)
|
||||
(if_then_else (gtu (cc0)
|
||||
(const_int 0))
|
||||
(label_ref (match_operand 0 "" ""))
|
||||
(pc)))]
|
||||
""
|
||||
"bgtu %l0")
|
||||
|
||||
(define_insn "blt"
|
||||
[(set (pc)
|
||||
(if_then_else (lt (cc0)
|
||||
(const_int 0))
|
||||
(label_ref (match_operand 0 "" ""))
|
||||
(pc)))]
|
||||
""
|
||||
"blt %l0")
|
||||
|
||||
(define_insn "bltu"
|
||||
[(set (pc)
|
||||
(if_then_else (ltu (cc0)
|
||||
(const_int 0))
|
||||
(label_ref (match_operand 0 "" ""))
|
||||
(pc)))]
|
||||
""
|
||||
"bltu %l0")
|
||||
|
||||
(define_insn "bge"
|
||||
[(set (pc)
|
||||
(if_then_else (ge (cc0)
|
||||
(const_int 0))
|
||||
(label_ref (match_operand 0 "" ""))
|
||||
(pc)))]
|
||||
""
|
||||
"bge %l0")
|
||||
|
||||
(define_insn "bgeu"
|
||||
[(set (pc)
|
||||
(if_then_else (geu (cc0)
|
||||
(const_int 0))
|
||||
(label_ref (match_operand 0 "" ""))
|
||||
(pc)))]
|
||||
""
|
||||
"bgeu %l0")
|
||||
|
||||
(define_insn "ble"
|
||||
[(set (pc)
|
||||
(if_then_else (le (cc0)
|
||||
(const_int 0))
|
||||
(label_ref (match_operand 0 "" ""))
|
||||
(pc)))]
|
||||
""
|
||||
"ble %l0")
|
||||
|
||||
(define_insn "bleu"
|
||||
[(set (pc)
|
||||
(if_then_else (leu (cc0)
|
||||
(const_int 0))
|
||||
(label_ref (match_operand 0 "" ""))
|
||||
(pc)))]
|
||||
""
|
||||
"bleu %l0")
|
||||
|
||||
(define_insn ""
|
||||
[(set (pc)
|
||||
(if_then_else (eq (cc0)
|
||||
(const_int 0))
|
||||
(pc)
|
||||
(label_ref (match_operand 0 "" ""))))]
|
||||
""
|
||||
"bne %l0")
|
||||
|
||||
(define_insn ""
|
||||
[(set (pc)
|
||||
(if_then_else (ne (cc0)
|
||||
(const_int 0))
|
||||
(pc)
|
||||
(label_ref (match_operand 0 "" ""))))]
|
||||
""
|
||||
"beq %l0")
|
||||
|
||||
(define_insn ""
|
||||
[(set (pc)
|
||||
(if_then_else (gt (cc0)
|
||||
(const_int 0))
|
||||
(pc)
|
||||
(label_ref (match_operand 0 "" ""))))]
|
||||
""
|
||||
"ble %l0")
|
||||
|
||||
(define_insn ""
|
||||
[(set (pc)
|
||||
(if_then_else (gtu (cc0)
|
||||
(const_int 0))
|
||||
(pc)
|
||||
(label_ref (match_operand 0 "" ""))))]
|
||||
""
|
||||
"bleu %l0")
|
||||
|
||||
(define_insn ""
|
||||
[(set (pc)
|
||||
(if_then_else (lt (cc0)
|
||||
(const_int 0))
|
||||
(pc)
|
||||
(label_ref (match_operand 0 "" ""))))]
|
||||
""
|
||||
"bge %l0")
|
||||
|
||||
(define_insn ""
|
||||
[(set (pc)
|
||||
(if_then_else (ltu (cc0)
|
||||
(const_int 0))
|
||||
(pc)
|
||||
(label_ref (match_operand 0 "" ""))))]
|
||||
""
|
||||
"bgeu %l0")
|
||||
|
||||
(define_insn ""
|
||||
[(set (pc)
|
||||
(if_then_else (ge (cc0)
|
||||
(const_int 0))
|
||||
(pc)
|
||||
(label_ref (match_operand 0 "" ""))))]
|
||||
""
|
||||
"blt %l0")
|
||||
|
||||
(define_insn ""
|
||||
[(set (pc)
|
||||
(if_then_else (geu (cc0)
|
||||
(const_int 0))
|
||||
(pc)
|
||||
(label_ref (match_operand 0 "" ""))))]
|
||||
""
|
||||
"bltu %l0")
|
||||
|
||||
(define_insn ""
|
||||
[(set (pc)
|
||||
(if_then_else (le (cc0)
|
||||
(const_int 0))
|
||||
(pc)
|
||||
(label_ref (match_operand 0 "" ""))))]
|
||||
""
|
||||
"bgt %l0")
|
||||
|
||||
(define_insn ""
|
||||
[(set (pc)
|
||||
(if_then_else (leu (cc0)
|
||||
(const_int 0))
|
||||
(pc)
|
||||
(label_ref (match_operand 0 "" ""))))]
|
||||
""
|
||||
"bgtu %l0")
|
||||
|
||||
(define_insn "jump"
|
||||
[(set (pc)
|
||||
(label_ref (match_operand 0 "" "")))]
|
||||
""
|
||||
"bra %l0")
|
||||
|
||||
(define_insn "tablejump"
|
||||
[(set (pc) (match_operand:SI 0 "general_operand" "g"))
|
||||
(use (label_ref (match_operand 1 "" "")))]
|
||||
""
|
||||
"bra %0")
|
||||
|
||||
(define_insn "call"
|
||||
[(call (match_operand:SI 0 "ever_good" "g")
|
||||
(match_operand:SI 1 "ever_good" "g"))]
|
||||
""
|
||||
"call %0")
|
||||
|
||||
(define_insn "call_value"
|
||||
[(set (match_operand 0 "" "g")
|
||||
(call (match_operand:SI 1 "ever_good" "g")
|
||||
(match_operand:SI 2 "ever_good" "g")))]
|
||||
""
|
||||
"call %1")
|
||||
|
||||
(define_insn "nop"
|
||||
[(const_int 0)]
|
||||
""
|
||||
"nop")
|
||||
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This progam 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.
|
||||
*
|
||||
* Alliance VLSI CAD System 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 the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Description de la machine virtuelle
|
||||
*
|
||||
* Ecrit par Arnaud COMPAN & Francois PECHEUX ** avril-juin 1990
|
||||
* Avec quelques modifications par Frederic Petrot.
|
||||
*/
|
||||
|
||||
#ifndef FILE
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#define AT_SP(mode) (gen_rtx (MEM, (mode), stack_pointer_rtx))
|
||||
#define AT_BP(mode) (gen_rtx (MEM, (mode), frame_pointer_rtx))
|
||||
|
||||
#define RET return ""
|
||||
|
||||
#define RETCOM(X) return ""
|
||||
|
||||
extern FILE *asm_out_file;
|
||||
static char *singlemove_string ();
|
||||
static void output_movf ();
|
||||
static void replace_float_constant ();
|
||||
static int mentions_fp_top ();
|
||||
static int call_top_dead_p ();
|
||||
static int fp_top_dead_p1 ();
|
||||
static rtx via_memory ();
|
||||
static void output_asm_insn_double_reg_op ();
|
||||
|
||||
#define PRINT_REG(X, CODE, FILE) fprintf (FILE, "%s", reg_name[REGNO (X)])
|
||||
|
||||
notice_update_cc(exp)
|
||||
rtx exp;
|
||||
{
|
||||
if (GET_CODE (exp) == SET) {
|
||||
if (SET_DEST (exp) == pc_rtx)
|
||||
return;
|
||||
if (REG_P (SET_DEST (exp))
|
||||
&& (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM)) {
|
||||
if (cc_status.value1
|
||||
&& reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
|
||||
cc_status.value1 = 0;
|
||||
if (cc_status.value2
|
||||
&& reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
|
||||
cc_status.value2 = 0;
|
||||
return;
|
||||
}
|
||||
if (GET_CODE (SET_DEST (exp)) == MEM && REG_P (SET_SRC (exp))) {
|
||||
if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
|
||||
cc_status.value1 = 0;
|
||||
if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
|
||||
cc_status.value2 = 0;
|
||||
return;
|
||||
} else if (GET_CODE (SET_SRC (exp)) == CALL) {
|
||||
CC_STATUS_INIT;
|
||||
return;
|
||||
} else if (SET_DEST (exp) == cc0_rtx) {
|
||||
CC_STATUS_INIT;
|
||||
cc_status.value1 = SET_SRC (exp);
|
||||
return;
|
||||
} else if (GET_MODE (SET_SRC (exp)) == SImode)
|
||||
switch (GET_CODE (SET_SRC (exp))) {
|
||||
case ASHIFTRT:
|
||||
case LSHIFTRT:
|
||||
case ASHIFT:
|
||||
case LSHIFT:
|
||||
if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT) {
|
||||
CC_STATUS_INIT;
|
||||
break;
|
||||
}
|
||||
case PLUS:
|
||||
case MINUS:
|
||||
case NEG:
|
||||
case AND:
|
||||
case IOR:
|
||||
case XOR:
|
||||
cc_status.flags = CC_NO_OVERFLOW;
|
||||
cc_status.value1 = SET_SRC (exp);
|
||||
cc_status.value2 = SET_DEST (exp);
|
||||
break;
|
||||
default:
|
||||
CC_STATUS_INIT;
|
||||
}
|
||||
else
|
||||
CC_STATUS_INIT;
|
||||
} else if (GET_CODE (exp) == PARALLEL
|
||||
&& GET_CODE (XVECEXP (exp, 0, 0)) == SET) {
|
||||
if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
|
||||
return;
|
||||
if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx) {
|
||||
CC_STATUS_INIT;
|
||||
cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
|
||||
return;
|
||||
}
|
||||
CC_STATUS_INIT;
|
||||
} else
|
||||
CC_STATUS_INIT;
|
||||
}
|
||||
|
||||
output_ascii(file, p, size)
|
||||
FILE *file;
|
||||
char *p;
|
||||
int size;
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf (file, "\t.string \"");
|
||||
for (i = 0; i < size; i++) {
|
||||
register int c = p[i];
|
||||
if (c == '\"' || c == '\\')
|
||||
putc ('\\', file);
|
||||
if (c >= ' ' && c < 0177)
|
||||
putc (c, file);
|
||||
else {
|
||||
fprintf (file, "\\%03o", c);
|
||||
if (i < size - 1 && p[i + 1] >= '0' && p[i + 1] <= '9')
|
||||
fprintf (file, "\"\n\tstring \"");
|
||||
}
|
||||
}
|
||||
fprintf (file, "\"\n");
|
||||
}
|
||||
|
||||
int ever_good(op, mode)
|
||||
register rtx op;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int no_good(op, mode)
|
||||
register rtx op;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,494 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This progam 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.
|
||||
*
|
||||
* Alliance VLSI CAD System 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 the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Description de la machine virtuelle
|
||||
*
|
||||
* Ecrit par Arnaud COMPAN & Francois PECHEUX ** avril-juin 1990
|
||||
*
|
||||
*/
|
||||
|
||||
#define DBX_DEBUGGING_INFO
|
||||
|
||||
#ifdef MY_SUN
|
||||
#define CPP_PREDEFINES "-Dsun -Dunix"
|
||||
#endif
|
||||
|
||||
#ifdef MY_VAX
|
||||
#define CPP_PREDEFINES "-Dvax -Dunix"
|
||||
#endif
|
||||
|
||||
extern int target_flags;
|
||||
|
||||
#define TARGET_DEFAULT 1
|
||||
#define TARGET_SWITCHES {{ "", TARGET_DEFAULT}}
|
||||
|
||||
#define BITS_BIG_ENDIAN
|
||||
#define BYTES_BIG_ENDIAN
|
||||
#define BITS_PER_UNIT 8
|
||||
#define BITS_PER_WORD 32
|
||||
#define UNITS_PER_WORD 4
|
||||
#define POINTER_SIZE 32
|
||||
#define POINTER_BOUNDARY 32
|
||||
#define PARM_BOUNDARY 32
|
||||
#define STACK_BOUNDARY 32
|
||||
#define FUNCTION_BOUNDARY 32
|
||||
#define BIGGEST_ALIGNMENT 32
|
||||
#define EMPTY_FIELD_BOUNDARY 32
|
||||
#define STRUCTURE_SIZE_BOUNDARY 32
|
||||
#define STRICT_ALIGNMENT
|
||||
|
||||
#define MAX_FIXED_MODE_SIZE BITS_PER_WORD
|
||||
|
||||
#define FIRST_PSEUDO_REGISTER 32
|
||||
|
||||
#define FIXED_REGISTERS \
|
||||
{ \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 1 \
|
||||
}
|
||||
|
||||
#define CALL_USED_REGISTERS \
|
||||
{ \
|
||||
1, 1, 1, 1, 1, 1, 1, 1, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 1, 0, 0, 1, 1, 0, 1 \
|
||||
}
|
||||
|
||||
#define HARD_REGNO_NREGS(REGNO, MODE) \
|
||||
((GET_MODE_SIZE(MODE) + UNITS_PER_WORD -1) / UNITS_PER_WORD)
|
||||
|
||||
#define HARD_REGNO_MODE_OK(REGNO, MODE) 1
|
||||
|
||||
#define MODES_TIEABLE_P(MODE1, MODE2) ( (MODE1) == (MODE2) )
|
||||
|
||||
#define STACK_POINTER_REGNUM 31
|
||||
#define FRAME_POINTER_REGNUM 30
|
||||
#define FRAME_POINTER_REQUIRED 0
|
||||
#define ARG_POINTER_REGNUM 30
|
||||
#define STATIC_CHAIN_REGNUM 29
|
||||
#define STRUCT_VALUE_REGNUM 28
|
||||
|
||||
enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
|
||||
#define N_REG_CLASSES (int) LIM_REG_CLASSES
|
||||
#define GENERAL_REGS ALL_REGS
|
||||
#define REG_CLASS_NAMES {"NO_REGS", "ALL_REGS" }
|
||||
#define REG_CLASS_CONTENTS {0, -1}
|
||||
#define REGNO_REG_CLASS(REGNO) ALL_REGS
|
||||
#define INDEX_REG_CLASS ALL_REGS
|
||||
#define BASE_REG_CLASS ALL_REGS
|
||||
#define REG_CLASS_FROM_LETTER(C) NO_REGS
|
||||
#define REGNO_OK_FOR_INDEX_P(REGNO) \
|
||||
((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32)
|
||||
#define REGNO_OK_FOR_BASE_P(REGNO) \
|
||||
((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32)
|
||||
#define PREFERRED_RELOAD_CLASS(X,CLASS) (CLASS)
|
||||
#define CLASS_MAX_NREGS(CLASS, MODE) \
|
||||
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
|
||||
#define CONST_OK_FOR_LETTER_P(VALUE, C) (0)
|
||||
#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) (0)
|
||||
|
||||
#define STACK_GROWS_DOWNWARD 1
|
||||
#define FRAME_GROWS_DOWNWARD 1
|
||||
|
||||
#define FIRST_PARM_OFFSET(FNDECL) (8)
|
||||
#define RETURN_POPS_ARGS(FUNTYPE) (0)
|
||||
|
||||
#define FUNCTION_VALUE(VALTYPE, FUNC) \
|
||||
gen_rtx (REG, TYPE_MODE (VALTYPE), 25)
|
||||
#define LIBCALL_VALUE(MODE) gen_rtx (REG, MODE, 25)
|
||||
#define FUNCTION_VALUE_REGNO_P(N) ((N)==25)
|
||||
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) (0)
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
|
||||
#define CUMULATIVE_ARGS int
|
||||
#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE) ((CUM) = 0)
|
||||
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
|
||||
((CUM) += ((MODE) != BLKmode \
|
||||
? (GET_MODE_SIZE (MODE) + 3) / 4 \
|
||||
: (int_size_in_bytes (TYPE) + 3) / 4))
|
||||
#define FUNCTION_ARG_REGNO_P(N) (0)
|
||||
|
||||
#define FUNCTION_PROLOGUE(FILE, SIZE) \
|
||||
{ \
|
||||
extern char call_used_regs[]; \
|
||||
int i; \
|
||||
\
|
||||
fprintf(FILE, "\tsub.si d31,d31,#4\n"); \
|
||||
fprintf(FILE, "\tmov.si (d31),d30\n"); \
|
||||
fprintf(FILE, "\tmov.si d30,d31\n"); \
|
||||
if (SIZE != 0) \
|
||||
fprintf(FILE, "\tsub.si d31,d31,#%d\n",SIZE); \
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) \
|
||||
if (regs_ever_live[i] && !call_used_regs[i] && \
|
||||
i != FRAME_POINTER_REGNUM) { \
|
||||
fprintf(FILE, "\tsub.si d31,d31,#4\n"); \
|
||||
fprintf(FILE, "\tmov.si (d31),%s\n",reg_names[i]); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FUNCTION_PROFILER(FILE, LABELNO) \
|
||||
fprintf(FILE,"\t; ----- Profiler\n") ;
|
||||
|
||||
#define EXIT_IGNORE_STACK 0
|
||||
|
||||
#define FUNCTION_EPILOGUE(FILE, SIZE) \
|
||||
{ \
|
||||
extern char call_used_regs[]; \
|
||||
int i; \
|
||||
\
|
||||
for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--) \
|
||||
if (regs_ever_live[i] && !call_used_regs[i] && \
|
||||
i!=FRAME_POINTER_REGNUM) { \
|
||||
fprintf(FILE, "\tmov.si %s,(d31)\n",reg_names[i]); \
|
||||
fprintf(FILE, "\tadd.si d31,d31,#4\n"); \
|
||||
} \
|
||||
if (SIZE != 0) \
|
||||
fprintf(FILE, "\tadd.si d31,d31,#%d\n", SIZE); \
|
||||
fprintf(FILE, "\tmov.si d30,(d31)\n"); \
|
||||
fprintf(FILE, "\tadd.si d31,d31,#4\n"); \
|
||||
fprintf(FILE, "\tret\n"); \
|
||||
}
|
||||
|
||||
#define FIX_FRAME_POINTER_ADDRESS(ADDR,DEPTH) \
|
||||
{ \
|
||||
puts("Ah que schisme dans FIX_FRAME_POINTER_ADDRESS"); \
|
||||
abort(); \
|
||||
}
|
||||
|
||||
#define CONSTANT_ADDRESS_P(X) CONSTANT_P (X)
|
||||
|
||||
#define MAX_REGS_PER_ADDRESS 1
|
||||
|
||||
#ifndef REG_OK_STRICT
|
||||
#define REG_OK_FOR_INDEX_P(X) (1)
|
||||
#define REG_OK_FOR_BASE_P(X) (1)
|
||||
#else
|
||||
#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
|
||||
#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
|
||||
#endif
|
||||
|
||||
#define REG_OK_FOR_P(X) (REG_OK_FOR_INDEX_P(X) || REG_OK_FOR_BASE_P(X))
|
||||
|
||||
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
|
||||
{ \
|
||||
if (CONSTANT_ADDRESS_P(X)) \
|
||||
goto ADDR ; \
|
||||
else if (GET_CODE(X) == CONST_INT) \
|
||||
goto ADDR ; \
|
||||
else if (REG_P(X) && REG_OK_FOR_P(X)) \
|
||||
goto ADDR ; \
|
||||
else if (GET_CODE(X) == SYMBOL_REF) \
|
||||
goto ADDR ; \
|
||||
else if (GET_CODE(X) == PLUS) { \
|
||||
if (REG_P(XEXP(X,0)) && REG_OK_FOR_P(XEXP(X,0)) && \
|
||||
GET_CODE(XEXP(X,1))==CONST_INT) \
|
||||
goto ADDR ; \
|
||||
if (REG_P(XEXP(X,1)) && REG_OK_FOR_P(XEXP(X,1)) \
|
||||
&& GET_CODE(XEXP(X,0))==CONST_INT) \
|
||||
goto ADDR ; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) { }
|
||||
|
||||
#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)
|
||||
|
||||
#define LEGITIMATE_CONSTANT_P(X) (1)
|
||||
|
||||
#define CASE_VECTOR_MODE SImode
|
||||
#define CASE_TAKES_INDEX_RAW
|
||||
|
||||
/* #define CASE_VECTOR_PC_RELATIVE */
|
||||
|
||||
#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
|
||||
|
||||
#define EASY_DIV_EXPR TRUNC_DIV_EXPR
|
||||
|
||||
#define DEFAULT_SIGNED_CHAR 1
|
||||
|
||||
#define MOVE_MAX 4
|
||||
|
||||
#define SLOW_BYTE_ACCESS 0
|
||||
|
||||
#define SHIFT_COUNT_TRUNCATED
|
||||
|
||||
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
|
||||
|
||||
#define STORE_FLAG_VALUE 1
|
||||
|
||||
#define Pmode SImode
|
||||
|
||||
#define FUNCTION_MODE SImode
|
||||
|
||||
#define NO_FUNCTION_CSE
|
||||
|
||||
#define CONST_COSTS(RTX,CODE) \
|
||||
case CONST_INT: \
|
||||
case CONST: \
|
||||
case LABEL_REF: \
|
||||
case SYMBOL_REF: \
|
||||
case CONST_DOUBLE: \
|
||||
case PLUS: \
|
||||
return 1;
|
||||
|
||||
#define CC_IN_FCCR 04000
|
||||
|
||||
#define NOTICE_UPDATE_CC(EXP, INSN) notice_update_cc((EXP))
|
||||
|
||||
#define TEXT_SECTION_ASM_OP "\n\t.text"
|
||||
#define DATA_SECTION_ASM_OP "\n\t.data"
|
||||
#define ASM_APP_ON ""
|
||||
#define ASM_APP_OFF ""
|
||||
|
||||
#define ASM_FILE_START(FILE) \
|
||||
do { \
|
||||
extern char *version_string, *language_string; \
|
||||
{ \
|
||||
int len = strlen(dump_base_name); \
|
||||
char *na = dump_base_name + len; \
|
||||
char shorter[15]; \
|
||||
while (na > dump_base_name) { \
|
||||
if (na[-1] == '/') \
|
||||
break; \
|
||||
na--; \
|
||||
} \
|
||||
strncpy (shorter, na, 14); \
|
||||
shorter[14] = '\0'; \
|
||||
fprintf(FILE, "\t.file\t\"%s\"\n", shorter); \
|
||||
} \
|
||||
fprintf(FILE, "\t.version\t\"%s %s\"\n", \
|
||||
language_string, version_string); \
|
||||
} while (0)
|
||||
|
||||
#define REGISTER_NAMES \
|
||||
{ \
|
||||
"d0","d1","d2","d3","d4","d5","d6","d7","d8","d9", \
|
||||
"d10","d11","d12","d13","d14","d15","d16","d17","d18","d19", \
|
||||
"d20","d21","d22","d23","d24","d25","d26","d27","d28","d29", \
|
||||
"d30","d31" \
|
||||
}
|
||||
|
||||
#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
|
||||
|
||||
#define ASM_OUTPUT_LABEL(FILE,NAME) \
|
||||
(assemble_name(FILE, NAME), fputs (":\n", FILE))
|
||||
|
||||
#define ASM_GLOBALIZE_LABEL(FILE,NAME) \
|
||||
{ \
|
||||
fputs("\t.global\t", FILE); \
|
||||
assemble_name(FILE, NAME); \
|
||||
fputs("\n", FILE); \
|
||||
}
|
||||
|
||||
#define ASM_OUTPUT_LABELREF(FILE,NAME) \
|
||||
fprintf(FILE, "_%s", NAME)
|
||||
|
||||
#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
|
||||
fprintf(FILE, ".%s%d:\n", PREFIX, NUM)
|
||||
|
||||
#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
|
||||
sprintf(LABEL, "*#.%s%d", PREFIX, NUM)
|
||||
|
||||
#define ASM_OUTPUT_DOUBLE(FILE,VALUE) \
|
||||
fprintf(FILE, "\t.double %.20e\n", (VALUE))
|
||||
|
||||
#define ASM_OUTPUT_FLOAT(FILE,VALUE) \
|
||||
fprintf(FILE, "\t.float %.12e\n", (VALUE))
|
||||
|
||||
#define ASM_OUTPUT_INT(FILE,VALUE) \
|
||||
( fprintf(FILE, "\t.int "), \
|
||||
output_addr_const(FILE, (VALUE)), \
|
||||
fprintf(FILE, "\n") \
|
||||
)
|
||||
|
||||
#define ASM_OUTPUT_SHORT(FILE,VALUE) \
|
||||
( fprintf(FILE, "\t.short "), \
|
||||
output_addr_const(FILE, (VALUE)), \
|
||||
fprintf(FILE, "\n") \
|
||||
)
|
||||
|
||||
#define ASM_OUTPUT_CHAR(FILE,VALUE) \
|
||||
( fprintf(FILE, "\t.char "), \
|
||||
output_addr_const(FILE, (VALUE)), \
|
||||
fprintf(FILE, "\n") \
|
||||
)
|
||||
|
||||
#define ASM_OUTPUT_BYTE(FILE,VALUE) \
|
||||
fprintf(FILE, "\t.byte 0x%x\n", (VALUE))
|
||||
|
||||
#define ASM_OUTPUT_ASCII(FILE, P, SIZE) output_ascii(FILE, P, SIZE)
|
||||
|
||||
#define ASM_OUTPUT_ADDR_VEC_PROLOGUE(FILE, MODE, LEN) \
|
||||
fprintf(FILE, "\tjmp r1\n");
|
||||
|
||||
#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \
|
||||
fprintf(FILE, "push \n", \
|
||||
((REGNO) < 32 ? "" : "f"), reg_names[REGNO])
|
||||
|
||||
#define ASM_OUTPUT_REG_POP(FILE,REGNO) \
|
||||
fprintf(FILE, "pop \n", \
|
||||
((REGNO) < 32 ? "" : "f"), reg_names[REGNO])
|
||||
|
||||
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
|
||||
fprintf(FILE, "\t.L%d\n", VALUE)
|
||||
|
||||
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \
|
||||
fprintf(FILE, "\tword .L%d-.L%d\n", VALUE, REL)
|
||||
|
||||
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
|
||||
if ((LOG) != 0) \
|
||||
fprintf (FILE, "\t.align %d\n", 1<<(LOG))
|
||||
|
||||
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
|
||||
fprintf(FILE, "\t.skip %d\n", (SIZE))
|
||||
|
||||
#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
|
||||
( fputs ("\t.comm ", (FILE)), \
|
||||
assemble_name ((FILE), (NAME)), \
|
||||
fprintf ((FILE), ",%d\n", (ROUNDED)) \
|
||||
)
|
||||
|
||||
#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
|
||||
( fprintf ((FILE), "\t.data\n"), \
|
||||
fprintf ((FILE), "\t.align %d\n", (SIZE) <= 4 ? 4 : 8), \
|
||||
assemble_name ((FILE), (NAME)), \
|
||||
fprintf ((FILE), ":\n\t.skip %d\n", (ROUNDED)), \
|
||||
fprintf ((FILE), "\t.text\n") \
|
||||
)
|
||||
|
||||
#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
|
||||
( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
|
||||
sprintf ((OUTPUT), "%s_%d", (NAME), (LABELNO)) \
|
||||
)
|
||||
|
||||
#define ASM_OPEN_PAREN "("
|
||||
#define ASM_CLOSE_PAREN ")"
|
||||
|
||||
/* Define results of standard character escape sequences. */
|
||||
#define TARGET_BELL 007
|
||||
#define TARGET_BS 010
|
||||
#define TARGET_TAB 011
|
||||
#define TARGET_NEWLINE 012
|
||||
#define TARGET_VT 013
|
||||
#define TARGET_FF 014
|
||||
#define TARGET_CR 015
|
||||
|
||||
#define PRINT_OPERAND(FILE, X, CODE) \
|
||||
{ \
|
||||
/* fprintf(FILE,"'%d'",GET_CODE(X)) ; */ \
|
||||
if (GET_CODE (X) == REG) \
|
||||
fprintf (FILE, "%s", reg_names[REGNO (X)]); \
|
||||
else if (GET_CODE (X) == MEM) \
|
||||
output_address (XEXP (X, 0)); \
|
||||
else if (GET_CODE (X) == SYMBOL_REF) \
|
||||
output_addr_const (FILE, X); \
|
||||
else if (GET_CODE (X) == LABEL_REF) \
|
||||
output_addr_const (FILE, X); \
|
||||
else if (GET_CODE (X) == CONST) \
|
||||
{ \
|
||||
fprintf(FILE,"$") ; \
|
||||
output_addr_const (FILE, XEXP(X,0)); \
|
||||
} \
|
||||
else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode) \
|
||||
{ \
|
||||
union { double d; int i[2]; } u; \
|
||||
union { float f; int i; } u1; \
|
||||
u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X); \
|
||||
u1.f = u.d; \
|
||||
if (CODE == 'f') \
|
||||
fprintf (FILE, "#%f", u1.f); \
|
||||
else \
|
||||
fprintf (FILE, "#%x", u1.i); \
|
||||
} \
|
||||
else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != DImode) \
|
||||
{ \
|
||||
union { double d; int i[2]; } u; \
|
||||
u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X); \
|
||||
fprintf (FILE, "#%f", u.d); \
|
||||
} \
|
||||
else if (GET_CODE(X) == CONST_INT) \
|
||||
{ \
|
||||
fprintf(FILE,"#") ; \
|
||||
output_addr_const (FILE, X); \
|
||||
} \
|
||||
else if (GET_CODE(X) == PLUS) \
|
||||
{ \
|
||||
if (GET_CODE(XEXP(X,0)) == CONST_INT) \
|
||||
output_addr_const (FILE, XEXP(X,0)); \
|
||||
if (GET_CODE(XEXP(X,1)) == CONST_INT) \
|
||||
output_addr_const (FILE, XEXP(X,1)); \
|
||||
if (GET_CODE(XEXP(X,0)) == REG) \
|
||||
fprintf (FILE, "(%s)", reg_names[REGNO (XEXP(X,0))]); \
|
||||
if (GET_CODE(XEXP(X,1)) == REG) \
|
||||
fprintf (FILE, "(%s)", reg_names[REGNO (XEXP(X,1))]); \
|
||||
} \
|
||||
else \
|
||||
fprintf(FILE, "*print_operand %d*",GET_CODE(X)) ; \
|
||||
}
|
||||
|
||||
#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
|
||||
{ \
|
||||
switch (GET_CODE (ADDR)) \
|
||||
{ \
|
||||
case REG: \
|
||||
fprintf (FILE, "(%s)", reg_names[REGNO (ADDR)]); \
|
||||
break; \
|
||||
case MEM: \
|
||||
output_address (XEXP (ADDR, 0)); \
|
||||
break; \
|
||||
case CONST_INT: \
|
||||
fprintf(FILE,"#") ; \
|
||||
output_addr_const (FILE, ADDR); \
|
||||
break; \
|
||||
case SYMBOL_REF: \
|
||||
fprintf(FILE,"$") ; \
|
||||
output_addr_const (FILE, ADDR); \
|
||||
break; \
|
||||
case CONST: /* on suppose que c'est une addition */ \
|
||||
fprintf(FILE,"$") ; \
|
||||
output_addr_const (FILE, XEXP(ADDR,0)); \
|
||||
break ; \
|
||||
case PLUS: \
|
||||
if (GET_CODE(XEXP(ADDR,0)) == CONST_INT) \
|
||||
output_addr_const (FILE, XEXP(ADDR,0)); \
|
||||
if (GET_CODE(XEXP(ADDR,1)) == CONST_INT) \
|
||||
output_addr_const (FILE, XEXP(ADDR,1)); \
|
||||
if (GET_CODE(XEXP(ADDR,0)) == REG) \
|
||||
fprintf (FILE, "(%s)", reg_names[REGNO (XEXP(ADDR,0))]); \
|
||||
if (GET_CODE(XEXP(ADDR,1)) == REG) \
|
||||
fprintf (FILE, "(%s)", reg_names[REGNO (XEXP(ADDR,1))]); \
|
||||
break; \
|
||||
default: \
|
||||
fprintf (FILE, "*print_operand_address %d*",GET_CODE(ADDR)); \
|
||||
break; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SFVALUE float
|
||||
#define INTIFY(FLOATVAL) FLOATVAL
|
||||
|
||||
#define ASM_OPERAND_LETTER '#'
|
||||
#define STARTING_FRAME_OFFSET 0
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This progam 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.
|
||||
*
|
||||
* Alliance VLSI CAD System 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 the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Description de la machine virtuelle
|
||||
*
|
||||
* Ecrit par Arnaud COMPAN & Francois PECHEUX ** avril-juin 1990
|
||||
*
|
||||
*/
|
||||
|
||||
#define MY_SUN
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define HOST_BITS_PER_CHAR 8
|
||||
#define HOST_BITS_PER_SHORT 16
|
||||
#define HOST_BITS_PER_INT 32
|
||||
#define HOST_BITS_PER_LONG 32
|
||||
|
||||
#define SUCCESS_EXIT_CODE 0
|
||||
#define FATAL_EXIT_CODE 33
|
||||
|
||||
#ifdef MY_SUN
|
||||
#define USG
|
||||
#endif
|
||||
|
||||
#include "tm.h"
|
||||
|
||||
#ifdef MY_SUN
|
||||
#define bcopy(a,b,c) memcpy (b,a,c)
|
||||
#define bzero(a,b) memset (a,0,b)
|
||||
#define bcmp(a,b,c) memcmp (a,b,c)
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define alloca(n) __builtin_alloca(n)
|
||||
#endif
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
'xrdef {Top-pg}{1}
|
||||
'xrdef {Top-snt}{chapter'tie1}
|
||||
'xrdef {Global Actions-pg}{1}
|
||||
'xrdef {Global Actions-snt}{section'tie1.1}
|
||||
'xrdef {Commands-pg}{3}
|
||||
'xrdef {Commands-snt}{section'tie1.2}
|
||||
'xrdef {Header Files-pg}{3}
|
||||
'xrdef {Header Files-snt}{section'tie1.3}
|
||||
'xrdef {Header Uses-pg}{3}
|
||||
'xrdef {Header Uses-snt}{section'tie1.3.1}
|
||||
'xrdef {Include Syntax-pg}{4}
|
||||
'xrdef {Include Syntax-snt}{section'tie1.3.2}
|
||||
'xrdef {Include Operation-pg}{5}
|
||||
'xrdef {Include Operation-snt}{section'tie1.3.3}
|
||||
'xrdef {Once-Only-pg}{6}
|
||||
'xrdef {Once-Only-snt}{section'tie1.3.4}
|
||||
'xrdef {Macros-pg}{7}
|
||||
'xrdef {Macros-snt}{section'tie1.4}
|
||||
'xrdef {Simple Macros-pg}{7}
|
||||
'xrdef {Simple Macros-snt}{section'tie1.4.1}
|
||||
'xrdef {Argument Macros-pg}{9}
|
||||
'xrdef {Argument Macros-snt}{section'tie1.4.2}
|
||||
'xrdef {Predefined-pg}{11}
|
||||
'xrdef {Predefined-snt}{section'tie1.4.3}
|
||||
'xrdef {Standard Predefined-pg}{11}
|
||||
'xrdef {Standard Predefined-snt}{section'tie1.4.3.1}
|
||||
'xrdef {Nonstandard Predefined-pg}{13}
|
||||
'xrdef {Nonstandard Predefined-snt}{section'tie1.4.3.2}
|
||||
'xrdef {Stringification-pg}{15}
|
||||
'xrdef {Stringification-snt}{section'tie1.4.4}
|
||||
'xrdef {Concatenation-pg}{16}
|
||||
'xrdef {Concatenation-snt}{section'tie1.4.5}
|
||||
'xrdef {Undefining-pg}{17}
|
||||
'xrdef {Undefining-snt}{section'tie1.4.6}
|
||||
'xrdef {Redefining-pg}{18}
|
||||
'xrdef {Redefining-snt}{section'tie1.4.7}
|
||||
'xrdef {Macro Pitfalls-pg}{19}
|
||||
'xrdef {Macro Pitfalls-snt}{section'tie1.4.8}
|
||||
'xrdef {Misnesting-pg}{19}
|
||||
'xrdef {Misnesting-snt}{section'tie1.4.8.1}
|
||||
'xrdef {Macro Parentheses-pg}{19}
|
||||
'xrdef {Macro Parentheses-snt}{section'tie1.4.8.2}
|
||||
'xrdef {Swallow Semicolon-pg}{21}
|
||||
'xrdef {Swallow Semicolon-snt}{section'tie1.4.8.3}
|
||||
'xrdef {Side Effects-pg}{22}
|
||||
'xrdef {Side Effects-snt}{section'tie1.4.8.4}
|
||||
'xrdef {Self-Reference-pg}{23}
|
||||
'xrdef {Self-Reference-snt}{section'tie1.4.8.5}
|
||||
'xrdef {Argument Prescan-pg}{24}
|
||||
'xrdef {Argument Prescan-snt}{section'tie1.4.8.6}
|
||||
'xrdef {Cascaded Macros-pg}{27}
|
||||
'xrdef {Cascaded Macros-snt}{section'tie1.4.8.7}
|
||||
'xrdef {Conditionals-pg}{27}
|
||||
'xrdef {Conditionals-snt}{section'tie1.5}
|
||||
'xrdef {Conditional Uses-pg}{28}
|
||||
'xrdef {Conditional Uses-snt}{section'tie1.5.1}
|
||||
'xrdef {Conditional Syntax-pg}{28}
|
||||
'xrdef {Conditional Syntax-snt}{section'tie1.5.2}
|
||||
'xrdef {#if Command-pg}{28}
|
||||
'xrdef {#if Command-snt}{section'tie1.5.2.1}
|
||||
'xrdef {#else Command-pg}{29}
|
||||
'xrdef {#else Command-snt}{section'tie1.5.2.2}
|
||||
'xrdef {#elif Command-pg}{30}
|
||||
'xrdef {#elif Command-snt}{section'tie1.5.2.3}
|
||||
'xrdef {Deleted Code-pg}{31}
|
||||
'xrdef {Deleted Code-snt}{section'tie1.5.3}
|
||||
'xrdef {Conditionals-Macros-pg}{31}
|
||||
'xrdef {Conditionals-Macros-snt}{section'tie1.5.4}
|
||||
'xrdef {#error Command-pg}{32}
|
||||
'xrdef {#error Command-snt}{section'tie1.5.5}
|
||||
'xrdef {Combining Sources-pg}{33}
|
||||
'xrdef {Combining Sources-snt}{section'tie1.6}
|
||||
'xrdef {Other Commands-pg}{34}
|
||||
'xrdef {Other Commands-snt}{section'tie1.7}
|
||||
'xrdef {Output-pg}{35}
|
||||
'xrdef {Output-snt}{section'tie1.8}
|
||||
'xrdef {Invocation-pg}{35}
|
||||
'xrdef {Invocation-snt}{section'tie1.9}
|
||||
'xrdef {Concept Index-pg}{39}
|
||||
'xrdef {Concept Index-snt}{}
|
||||
'xrdef {Index-pg}{41}
|
||||
'xrdef {Index-snt}{}
|
|
@ -0,0 +1,30 @@
|
|||
\initial {C}
|
||||
\entry {cascaded macros}{27}
|
||||
\entry {commands}{3}
|
||||
\entry {concatenation}{16}
|
||||
\entry {conditionals}{27}
|
||||
\initial {H}
|
||||
\entry {header file}{3}
|
||||
\initial {L}
|
||||
\entry {line control}{33}
|
||||
\initial {M}
|
||||
\entry {macro body uses macro}{27}
|
||||
\initial {N}
|
||||
\entry {null command}{34}
|
||||
\initial {O}
|
||||
\entry {options}{35}
|
||||
\entry {output format}{35}
|
||||
\initial {P}
|
||||
\entry {predefined macros}{11}
|
||||
\entry {preprocessor commands}{3}
|
||||
\initial {R}
|
||||
\entry {redefining macros}{18}
|
||||
\entry {repeated inclusion}{6}
|
||||
\initial {S}
|
||||
\entry {self-reference}{23}
|
||||
\entry {semicolons (after macro calls)}{21}
|
||||
\entry {side effects (in macro arguments)}{22}
|
||||
\entry {stringification}{15}
|
||||
\initial {U}
|
||||
\entry {undefining macros}{17}
|
||||
\entry {unsafe macros}{22}
|
|
@ -0,0 +1,51 @@
|
|||
\initial {#}
|
||||
\entry {\code {#elif}}{30}
|
||||
\entry {\code {#else}}{29}
|
||||
\entry {\code {#error}}{32}
|
||||
\entry {\code {#ident}}{34}
|
||||
\entry {\code {#if}}{28}
|
||||
\entry {\code {#ifdef}}{32}
|
||||
\entry {\code {#ifndef}}{32}
|
||||
\entry {\code {#include}}{4}
|
||||
\entry {\code {#line}}{33}
|
||||
\entry {\code {#pragma}}{34}
|
||||
\initial {-}
|
||||
\entry {\code {-C}}{36}
|
||||
\entry {\code {-d}}{37}
|
||||
\entry {\code {-D}}{36}
|
||||
\entry {\code {-i}}{37}
|
||||
\entry {\code {-I}}{36}
|
||||
\entry {\code {-M}}{37}
|
||||
\entry {\code {-MM}}{37}
|
||||
\entry {\code {-P}}{35}
|
||||
\entry {\code {-pedantic}}{36}
|
||||
\entry {\code {-trigraphs}}{36}
|
||||
\entry {\code {-U}}{37}
|
||||
\entry {\code {-undef}}{37}
|
||||
\initial {{@fam @ttfam @tentt @char '137}}
|
||||
\entry {\code {{@fam @ttfam @tentt @char '137}{@fam @ttfam @tentt @char '137}BASE{@fam @ttfam @tentt @char '137}FILE{@fam @ttfam @tentt @char '137}{@fam @ttfam @tentt @char '137}}}{12}
|
||||
\entry {\code {{@fam @ttfam @tentt @char '137}{@fam @ttfam @tentt @char '137}DATE{@fam @ttfam @tentt @char '137}{@fam @ttfam @tentt @char '137}}}{12}
|
||||
\entry {\code {{@fam @ttfam @tentt @char '137}{@fam @ttfam @tentt @char '137}FILE{@fam @ttfam @tentt @char '137}{@fam @ttfam @tentt @char '137}}}{12}
|
||||
\entry {\code {{@fam @ttfam @tentt @char '137}{@fam @ttfam @tentt @char '137}LINE{@fam @ttfam @tentt @char '137}{@fam @ttfam @tentt @char '137}}}{12}
|
||||
\entry {\code {{@fam @ttfam @tentt @char '137}{@fam @ttfam @tentt @char '137}STDC{@fam @ttfam @tentt @char '137}{@fam @ttfam @tentt @char '137}}}{12}
|
||||
\entry {\code {{@fam @ttfam @tentt @char '137}{@fam @ttfam @tentt @char '137}TIME{@fam @ttfam @tentt @char '137}{@fam @ttfam @tentt @char '137}}}{12}
|
||||
\initial {B}
|
||||
\entry {\code {BSD}}{13}
|
||||
\initial {D}
|
||||
\entry {\code {defined}}{31}
|
||||
\initial {M}
|
||||
\entry {\code {M68020}}{14}
|
||||
\entry {\code {m68k}}{13}
|
||||
\entry {\code {mc68000}}{13}
|
||||
\initial {N}
|
||||
\entry {\code {ns32000}}{14}
|
||||
\initial {P}
|
||||
\entry {\code {pyr}}{14}
|
||||
\initial {S}
|
||||
\entry {\code {sequent}}{14}
|
||||
\entry {\code {sun}}{14}
|
||||
\entry {\code {system header files}}{4}
|
||||
\initial {U}
|
||||
\entry {\code {unix}}{13}
|
||||
\initial {V}
|
||||
\entry {\code {vax}}{13}
|
|
@ -0,0 +1,69 @@
|
|||
Info file cpp.info, produced by Makeinfo, -*- Text -*- from input
|
||||
file cpp.texinfo.
|
||||
|
||||
This file documents the GNU C Preprocessor.
|
||||
|
||||
Copyright (C) 1987, 1989 Free Software Foundation, Inc.
|
||||
|
||||
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.
|
||||
|
||||
Permission is granted to copy and distribute modified versions of
|
||||
this manual under the conditions for verbatim copying, provided also
|
||||
that the entire resulting derived work is distributed under the terms
|
||||
of a permission notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this
|
||||
manual into another language, under the above conditions for modified
|
||||
versions.
|
||||
|
||||
Indirect:
|
||||
cpp.info-1: 748
|
||||
cpp.info-2: 48706
|
||||
|
||||
Tag Table:
|
||||
(Indirect)
|
||||
Node: Top750
|
||||
Node: Global Actions3306
|
||||
Node: Commands5809
|
||||
Node: Header Files7414
|
||||
Node: Header Uses7990
|
||||
Node: Include Syntax9377
|
||||
Node: Include Operation12390
|
||||
Node: Once-Only14056
|
||||
Node: Macros15867
|
||||
Node: Simple Macros16779
|
||||
Node: Argument Macros19826
|
||||
Node: Predefined24914
|
||||
Node: Standard Predefined25342
|
||||
Node: Nonstandard Predefined29545
|
||||
Node: Stringification32827
|
||||
Node: Concatenation35666
|
||||
Node: Undefining38922
|
||||
Node: Redefining39944
|
||||
Node: Macro Pitfalls41230
|
||||
Node: Misnesting42273
|
||||
Node: Macro Parentheses43281
|
||||
Node: Swallow Semicolon45136
|
||||
Node: Side Effects47024
|
||||
Node: Self-Reference48708
|
||||
Node: Argument Prescan50953
|
||||
Node: Cascaded Macros55914
|
||||
Node: Conditionals56935
|
||||
Node: Conditional Uses58223
|
||||
Node: Conditional Syntax59610
|
||||
Node: #if Command60179
|
||||
Node: #else Command62430
|
||||
Node: #elif Command63077
|
||||
Node: Deleted Code64418
|
||||
Node: Conditionals-Macros64949
|
||||
Node: #error Command68171
|
||||
Node: Combining Sources69215
|
||||
Node: Other Commands71829
|
||||
Node: Output73062
|
||||
Node: Invocation73993
|
||||
Node: Concept Index79417
|
||||
Node: Index80219
|
||||
|
||||
End Tag Table
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,881 @@
|
|||
Info file cpp.info, produced by Makeinfo, -*- Text -*- from input
|
||||
file cpp.texinfo.
|
||||
|
||||
This file documents the GNU C Preprocessor.
|
||||
|
||||
Copyright (C) 1987, 1989 Free Software Foundation, Inc.
|
||||
|
||||
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.
|
||||
|
||||
Permission is granted to copy and distribute modified versions of
|
||||
this manual under the conditions for verbatim copying, provided also
|
||||
that the entire resulting derived work is distributed under the terms
|
||||
of a permission notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this
|
||||
manual into another language, under the above conditions for modified
|
||||
versions.
|
||||
|
||||
|
||||
|
||||
File: cpp.info, Node: Self-Reference, Next: Argument Prescan, Prev: Side Effects, Up: Macro Pitfalls
|
||||
|
||||
Self-Referential Macros
|
||||
.......................
|
||||
|
||||
A "self-referential" macro is one whose name appears in its definition.
|
||||
A special feature of ANSI Standard C is that the self-reference is
|
||||
not considered a macro call. It is passed into the preprocessor
|
||||
output unchanged.
|
||||
|
||||
Let's consider an example:
|
||||
|
||||
#define foo (4 + foo)
|
||||
|
||||
where `foo' is also a variable in your program.
|
||||
|
||||
Following the ordinary rules, each reference to `foo' will expand
|
||||
into `(4 + foo)'; then this will be rescanned and will expand into
|
||||
`(4 + (4 + foo))'; and so on until it causes a fatal error (memory
|
||||
full) in the preprocessor.
|
||||
|
||||
However, the special rule about self-reference cuts this process
|
||||
short after one step, at `(4 + foo)'. Therefore, this macro
|
||||
definition has the possibly useful effect of causing the program to
|
||||
add 4 to the value of `foo' wherever `foo' is referred to.
|
||||
|
||||
In most cases, it is a bad idea to take advantage of this feature. A
|
||||
person reading the program who sees that `foo' is a variable will not
|
||||
expect that it is a macro as well. The reader will come across the
|
||||
identifier `foo' in the program and think its value should be that of
|
||||
the variable `foo', whereas in fact the value is four greater.
|
||||
|
||||
The special rule for self-reference applies also to "indirect"
|
||||
self-reference. This is the case where a macro X expands to use a
|
||||
macro `y', and `y''s expansion refers to the macro `x'. The
|
||||
resulting reference to `x' comes indirectly from the expansion of
|
||||
`x', so it is a self-reference and is not further expanded. Thus,
|
||||
after
|
||||
|
||||
#define x (4 + y)
|
||||
#define y (2 * x)
|
||||
|
||||
`x' would expand into `(4 + (2 * x))'. Clear?
|
||||
|
||||
But suppose `y' is used elsewhere, not from the definition of `x'.
|
||||
Then the use of `x' in the expansion of `y' is not a self-reference
|
||||
because `x' is not "in progress". So it does expand. However, the
|
||||
expansion of `x' contains a reference to `y', and that is an indirect
|
||||
self-reference now because `y' is "in progress". The result is that
|
||||
`y' expands to `(2 * (4 + y))'.
|
||||
|
||||
It is not clear that this behavior would ever be useful, but it is
|
||||
specified by the ANSI C standard, so you need to understand it.
|
||||
|
||||
|
||||
|
||||
File: cpp.info, Node: Argument Prescan, Next: Cascaded Macros, Prev: Self-Reference, Up: Macro Pitfalls
|
||||
|
||||
Separate Expansion of Macro Arguments
|
||||
.....................................
|
||||
|
||||
We have explained that the expansion of a macro, including the
|
||||
substituted actual arguments, is scanned over again for macro calls
|
||||
to be expanded.
|
||||
|
||||
What really happens is more subtle: first each actual argument text
|
||||
is scanned separately for macro calls. Then the results of this are
|
||||
substituted into the macro body to produce the macro expansion, and
|
||||
the macro expansion is scanned again for macros to expand.
|
||||
|
||||
The result is that the actual arguments are scanned *twice* to expand
|
||||
macro calls in them.
|
||||
|
||||
Most of the time, this has no effect. If the actual argument
|
||||
contained any macro calls, they are expanded during the first scan.
|
||||
The result therefore contains no macro calls, so the second scan does
|
||||
not change it. If the actual argument were substituted as given,
|
||||
with no prescan, the single remaining scan would find the same macro
|
||||
calls and produce the same results.
|
||||
|
||||
You might expect the double scan to change the results when a
|
||||
self-referential macro is used in an actual argument of another macro
|
||||
(*note Self-Reference::.): the self-referential macro would be
|
||||
expanded once in the first scan, and a second time in the second
|
||||
scan. But this is not what happens. The self-references that do not
|
||||
expand in the first scan are marked so that they will not expand in
|
||||
the second scan either.
|
||||
|
||||
The prescan is not done when an argument is stringified or
|
||||
concatenated. Thus,
|
||||
|
||||
#define str(s) #s
|
||||
#define foo 4
|
||||
str (foo)
|
||||
|
||||
expands to `"foo"'. Once more, prescan has been prevented from
|
||||
having any noticeable effect.
|
||||
|
||||
More precisely, stringification and concatenation use the argument as
|
||||
written, in un-prescanned form. The same actual argument would be
|
||||
used in prescanned form if it is substituted elsewhere without
|
||||
stringification or concatenation.
|
||||
|
||||
#define str(s) #s lose(s)
|
||||
#define foo 4
|
||||
str (foo)
|
||||
|
||||
expands to `"foo" lose(4)'.
|
||||
|
||||
You might now ask, "Why mention the prescan, if it makes no difference?
|
||||
And why not skip it and make the preprocessor faster?" The answer is
|
||||
that the prescan does make a difference in three special cases:
|
||||
|
||||
* Nested calls to a macro.
|
||||
|
||||
* Macros that call other macros that stringify or concatenate.
|
||||
|
||||
* Macros whose expansions contain unshielded commas.
|
||||
|
||||
We say that "nested" calls to a macro occur when a macro's actual
|
||||
argument contains a call to that very macro. For example, if `f' is
|
||||
a macro that expects one argument, `f (f (1))' is a nested pair of
|
||||
calls to `f'. The desired expansion is made by expanding `f (1)' and
|
||||
substituting that into the definition of `f'. The prescan causes the
|
||||
expected result to happen. Without the prescan, `f (1)' itself would
|
||||
be substituted as an actual argument, and the inner use of `f' would
|
||||
appear during the main scan as an indirect self-reference and would
|
||||
not be expanded. Here, the prescan cancels an undesirable side
|
||||
effect (in the medical, not computational, sense of the term) of the
|
||||
special rule for self-referential macros.
|
||||
|
||||
But prescan causes trouble in certain other cases of nested macro
|
||||
calls. Here is an example:
|
||||
|
||||
#define foo a,b
|
||||
#define bar(x) lose(x)
|
||||
#define lose(x) (1 + (x))
|
||||
|
||||
bar(foo)
|
||||
|
||||
We would like `bar(foo)' to turn into `(1 + (foo))', which would then
|
||||
turn into `(1 + (a,b))'. But instead, `bar(foo)' expands into
|
||||
`lose(a,b)', and you get an error because `lose' requires a single
|
||||
argument. In this case, the problem is easily solved by the same
|
||||
parentheses that ought to be used to prevent misnesting of arithmetic
|
||||
operations:
|
||||
|
||||
#define foo (a,b)
|
||||
#define bar(x) lose((x))
|
||||
|
||||
The problem is more serious when the operands of the macro are not
|
||||
expressions; for example, when they are statements. Then parentheses
|
||||
are unacceptable because they would make for invalid C code:
|
||||
|
||||
#define foo { int a, b; ... }
|
||||
|
||||
In GNU C you can shield the commas using the `({...})' construct
|
||||
which turns a compound statement into an expression:
|
||||
|
||||
#define foo ({ int a, b; ... })
|
||||
|
||||
Or you can rewrite the macro definition to avoid such commas:
|
||||
|
||||
#define foo { int a; int b; ... }
|
||||
|
||||
There is also one case where prescan is useful. It is possible to
|
||||
use prescan to expand an argument and then stringify it--if you use
|
||||
two levels of macros. Let's add a new macro `xstr' to the example
|
||||
shown above:
|
||||
|
||||
#define xstr(s) str(s)
|
||||
#define str(s) #s
|
||||
#define foo 4
|
||||
xstr (foo)
|
||||
|
||||
This expands into `"4"', not `"foo"'. The reason for the difference
|
||||
is that the argument of `xstr' is expanded at prescan (because `xstr'
|
||||
does not specify stringification or concatenation of the argument).
|
||||
The result of prescan then forms the actual argument for `str'.
|
||||
`str' uses its argument without prescan because it performs
|
||||
stringification; but it cannot prevent or undo the prescanning
|
||||
already done by `xstr'.
|
||||
|
||||
|
||||
|
||||
File: cpp.info, Node: Cascaded Macros, Prev: Argument Prescan, Up: Macro Pitfalls
|
||||
|
||||
Cascaded Use of Macros
|
||||
......................
|
||||
|
||||
A "cascade" of macros is when one macro's body contains a reference
|
||||
to another macro. This is very common practice. For example,
|
||||
|
||||
#define BUFSIZE 1020
|
||||
#define TABLESIZE BUFSIZE
|
||||
|
||||
This is not at all the same as defining `TABLESIZE' to be `1020'.
|
||||
The `#define' for `TABLESIZE' uses exactly the body you specify--in
|
||||
this case, `BUFSIZE'--and does not check to see whether it too is the
|
||||
name of a macro.
|
||||
|
||||
It's only when you *use* `TABLESIZE' that the result of its expansion
|
||||
is checked for more macro names.
|
||||
|
||||
This makes a difference if you change the definition of `BUFSIZE' at
|
||||
some point in the source file. `TABLESIZE', defined as shown, will
|
||||
always expand using the definition of `BUFSIZE' that is currently in
|
||||
effect:
|
||||
|
||||
#define BUFSIZE 1020
|
||||
#define TABLESIZE BUFSIZE
|
||||
#undef BUFSIZE
|
||||
#define BUFSIZE 37
|
||||
|
||||
Now `TABLESIZE' expands (in two stages) to `37'.
|
||||
|
||||
|
||||
|
||||
File: cpp.info, Node: Conditionals, Next: Combining Sources, Prev: Macros, Up: Top
|
||||
|
||||
Conditionals
|
||||
============
|
||||
|
||||
In a macro processor, a "conditional" is a command that allows a part
|
||||
of the program to be ignored during compilation, on some conditions.
|
||||
In the C preprocessor, a conditional can test either an arithmetic
|
||||
expression or whether a name is defined as a macro.
|
||||
|
||||
A conditional in the C preprocessor resembles in some ways an `if'
|
||||
statement in C, but it is important to understand the difference
|
||||
between them. The condition in an `if' statement is tested during
|
||||
the execution of your program. Its purpose is to allow your program
|
||||
to behave differently from run to run, depending on the data it is
|
||||
operating on. The condition in a preprocessor conditional command is
|
||||
tested when your program is compiled. Its purpose is to allow
|
||||
different code to be included in the program depending on the
|
||||
situation at the time of compilation.
|
||||
|
||||
* Menu:
|
||||
|
||||
* Uses: Conditional Uses. What conditionals are for.
|
||||
* Syntax: Conditional Syntax. How conditionals are written.
|
||||
* Deletion: Deleted Code. Making code into a comment.
|
||||
* Macros: Conditionals-Macros. Why conditionals are used with macros.
|
||||
* Errors: #error Command. Detecting inconsistent compilation parameters.
|
||||
|
||||
|
||||
|
||||
File: cpp.info, Node: Conditional Uses, Next: Conditional Syntax, Prev: Conditionals, Up: Conditionals
|
||||
|
||||
Why Conditionals are Used
|
||||
-------------------------
|
||||
|
||||
Generally there are three kinds of reason to use a conditional.
|
||||
|
||||
* A program may need to use different code depending on the
|
||||
machine or operating system it is to run on. In some cases the
|
||||
code for one operating system may be erroneous on another
|
||||
operating system; for example, it might refer to library
|
||||
routines that do not exist on the other system. When this
|
||||
happens, it is not enough to avoid executing the invalid code:
|
||||
merely having it in the program makes it impossible to link the
|
||||
program and run it. With a preprocessor conditional, the
|
||||
offending code can be effectively excised from the program when
|
||||
it is not valid.
|
||||
|
||||
* You may want to be able to compile the same source file into two
|
||||
different programs. Sometimes the difference between the
|
||||
programs is that one makes frequent time-consuming consistency
|
||||
checks on its intermediate data while the other does not.
|
||||
|
||||
* A conditional whose condition is always false is a good way to
|
||||
exclude code from the program but keep it as a sort of comment
|
||||
for future reference.
|
||||
|
||||
Most simple programs that are intended to run on only one machine
|
||||
will not need to use preprocessor conditionals.
|
||||
|
||||
|
||||
|
||||
File: cpp.info, Node: Conditional Syntax, Next: Deleted Code, Prev: Conditional Uses, Up: Conditionals
|
||||
|
||||
Syntax of Conditionals
|
||||
----------------------
|
||||
|
||||
A conditional in the C preprocessor begins with a "conditional
|
||||
command": `#if', `#ifdef' or `#ifndef'. *Note Conditionals-Macros::,
|
||||
for info on `#ifdef' and `#ifndef'; only `#if' is explained here.
|
||||
|
||||
* Menu:
|
||||
|
||||
* If: #if Command. Basic conditionals using `#if' and `#endif'.
|
||||
* Else: #else Command. Including some text if the condition fails.
|
||||
* Elif: #elif Command. Testing several alternative possibilities.
|
||||
|
||||
|
||||
|
||||
File: cpp.info, Node: #if Command, Next: #else Command, Prev: Conditional Syntax, Up: Conditional Syntax
|
||||
|
||||
The `#if' Command
|
||||
.................
|
||||
|
||||
The `#if' command in its simplest form consists of
|
||||
|
||||
#if EXPRESSION
|
||||
CONTROLLED TEXT
|
||||
#endif /* EXPRESSION */
|
||||
|
||||
The comment following the `#endif' is not required, but it is a good
|
||||
practice because it helps people match the `#endif' to the
|
||||
corresponding `#if'. Such comments should always be used, except in
|
||||
short conditionals that are not nested. In fact, you can put
|
||||
anything at all after the `#endif' and it will be ignored by the GNU
|
||||
C preprocessor, but only comments are acceptable in ANSI Standard C.
|
||||
|
||||
EXPRESSION is a C expression of integer type, subject to stringent
|
||||
restrictions. It may contain
|
||||
|
||||
* Integer constants, which are all regarded as `long' or `unsigned
|
||||
long'.
|
||||
|
||||
* Character constants, which are interpreted according to the
|
||||
character set and conventions of the machine and operating
|
||||
system on which the preprocessor is running. The GNU C
|
||||
preprocessor uses the C data type `char' for these character
|
||||
constants; therefore, whether some character codes are negative
|
||||
is determined by the C compiler used to compile the
|
||||
preprocessor. If it treats `char' as signed, then character
|
||||
codes large enough to set the sign bit will be considered
|
||||
negative; otherwise, no character code is considered negative.
|
||||
|
||||
* Arithmetic operators for addition, subtraction, multiplication,
|
||||
division, bitwise operations, shifts, comparisons, and `&&' and
|
||||
`||'.
|
||||
|
||||
* Identifiers that are not macros, which are all treated as zero(!).
|
||||
|
||||
* Macro calls. All macro calls in the expression are expanded
|
||||
before actual computation of the expression's value begins.
|
||||
|
||||
Note that `sizeof' operators and `enum'-type values are not allowed.
|
||||
`enum'-type values, like all other identifiers that are not taken as
|
||||
macro calls and expanded, are treated as zero.
|
||||
|
||||
The text inside of a conditional can include preprocessor commands.
|
||||
Then the commands inside the conditional are obeyed only if that
|
||||
branch of the conditional succeeds. The text can also contain other
|
||||
conditional groups. However, the `#if''s and `#endif''s must balance.
|
||||
|
||||
|
||||
|
||||
File: cpp.info, Node: #else Command, Next: #elif Command, Prev: #if Command, Up: Conditional Syntax
|
||||
|
||||
The `#else' Command
|
||||
...................
|
||||
|
||||
The `#else' command can be added to a conditional to provide
|
||||
alternative text to be used if the condition is false. This looks like
|
||||
|
||||
#if EXPRESSION
|
||||
TEXT-IF-TRUE
|
||||
#else /* Not EXPRESSION */
|
||||
TEXT-IF-FALSE
|
||||
#endif /* Not EXPRESSION */
|
||||
|
||||
If EXPRESSION is nonzero, and the TEXT-IF-TRUE is considered
|
||||
included, then `#else' acts like a failing conditional and the
|
||||
TEXT-IF-FALSE is ignored. Contrariwise, if the `#if' conditional
|
||||
fails, the TEXT-IF-FALSE is considered included.
|
||||
|
||||
|
||||
|
||||
File: cpp.info, Node: #elif Command, Prev: #else Command, Up: Conditional Syntax
|
||||
|
||||
The `#elif' Command
|
||||
...................
|
||||
|
||||
One common case of nested conditionals is used to check for more than
|
||||
two possible alternatives. For example, you might have
|
||||
|
||||
#if X == 1
|
||||
...
|
||||
#else /* X != 1 */
|
||||
#if X == 2
|
||||
...
|
||||
#else /* X != 2 */
|
||||
...
|
||||
#endif /* X != 2 */
|
||||
#endif /* X != 1 */
|
||||
|
||||
Another conditional command, `#elif', allows this to be abbreviated
|
||||
as follows:
|
||||
|
||||
#if X == 1
|
||||
...
|
||||
#elif X == 2
|
||||
...
|
||||
#else /* X != 2 and X != 1*/
|
||||
...
|
||||
#endif /* X != 2 and X != 1*/
|
||||
|
||||
`#elif' stands for "else if". Like `#else', it goes in the middle of
|
||||
a `#if'-`#endif' pair and subdivides it; it does not require a
|
||||
matching `#endif' of its own. Like `#if', the `#elif' command
|
||||
includes an expression to be tested.
|
||||
|
||||
The text following the `#elif' is processed only if the original
|
||||
`#if'-condition failed and the `#elif' condition succeeeds. More
|
||||
than one `#elif' can go in the same `#if'-`#endif' group. Then the
|
||||
text after each `#elif' is processed only if the `#elif' condition
|
||||
succeeds after the original `#if' and any previous `#elif''s within
|
||||
it have failed. `#else' is equivalent to `#elif 1', and `#else' is
|
||||
allowed after any number of `#elif''s, but `#elif' may not follow a
|
||||
`#else'.
|
||||
|
||||
|
||||
|
||||
File: cpp.info, Node: Deleted Code, Next: Conditionals-Macros, Prev: Conditional Syntax, Up: Conditionals
|
||||
|
||||
Keeping Deleted Code for Future Reference
|
||||
-----------------------------------------
|
||||
|
||||
If you replace or delete a part of the program but want to keep the
|
||||
old code around as a comment for future reference, the easy way to do
|
||||
this is to put `#if 0' before it and `#endif' after it.
|
||||
|
||||
This works even if the code being turned off contains conditionals,
|
||||
but they must be entire conditionals (balanced `#if' and `#endif').
|
||||
|
||||
|
||||
|
||||
File: cpp.info, Node: Conditionals-Macros, Next: #error Command, Prev: Deleted Code, Up: Conditionals
|
||||
|
||||
Conditionals and Macros
|
||||
-----------------------
|
||||
|
||||
Conditionals are rarely useful except in connection with macros. A
|
||||
`#if' command whose expression uses no macros is equivalent to `#if
|
||||
1' or `#if 0'; you might as well determine which one, by computing
|
||||
the value of the expression yourself, and then simplify the program.
|
||||
But when the expression uses macros, its value can vary from
|
||||
compilation to compilation.
|
||||
|
||||
For example, here is a conditional that tests the expression `BUFSIZE
|
||||
== 1020', where `BUFSIZE' must be a macro.
|
||||
|
||||
#if BUFSIZE == 1020
|
||||
printf ("Large buffers!\n");
|
||||
#endif /* BUFSIZE is large */
|
||||
|
||||
The special operator `defined' may be used in `#if' expressions to
|
||||
test whether a certain name is defined as a macro. Either `defined
|
||||
NAME' or `defined (NAME)' is an expression whose value is 1 if NAME
|
||||
is defined as macro at the current point in the program, and 0
|
||||
otherwise. For the `defined' operator it makes no difference what
|
||||
the definition of the macro is; all that matters is whether there is
|
||||
a definition. Thus, for example,
|
||||
|
||||
#if defined (vax) || defined (ns16000)
|
||||
|
||||
would include the following code if either of the names `vax' and
|
||||
`ns16000' is defined as a macro.
|
||||
|
||||
If a macro is defined and later undefined with `#undef', subsequent
|
||||
use of the `defined' operator will return 0, because the name is no
|
||||
longer defined. If the macro is defined again with another
|
||||
`#define', `defined' will recommence returning 1.
|
||||
|
||||
Conditionals that test just the definedness of one name are very
|
||||
common, so there are two special short conditional commands for this
|
||||
case. They are
|
||||
|
||||
`#ifdef NAME'
|
||||
is equivalent to `#if defined (NAME)'.
|
||||
|
||||
`#ifndef NAME'
|
||||
is equivalent to `#if ! defined (NAME)'.
|
||||
|
||||
Macro definitions can vary between compilations for several reasons.
|
||||
|
||||
* Some macros are predefined on each kind of machine. For
|
||||
example, on a Vax, the name `vax' is a predefined macro. On
|
||||
other machines, it would not be defined.
|
||||
|
||||
* Many more macros are defined by system header files. Different
|
||||
systems and machines define different macros, or give them
|
||||
different values. It is useful to test these macros with
|
||||
conditionals to avoid using a system feature on a machine where
|
||||
it is not implemented.
|
||||
|
||||
* Macros are a common way of allowing users to customize a program
|
||||
for different machines or applications. For example, the macro
|
||||
`BUFSIZE' might be defined in a configuration file for your
|
||||
program that is included as a header file in each source file.
|
||||
You would use `BUFSIZE' in a preprocessor conditional in order
|
||||
to generate different code depending on the chosen configuration.
|
||||
|
||||
* Macros can be defined or undefined with `-D' and `-U' command
|
||||
options when you compile the program. You can arrange to
|
||||
compile the same source file into two different programs by
|
||||
choosing a macro name to specify which program you want, writing
|
||||
conditionals to test whether or how this macro is defined, and
|
||||
then controlling the state of the macro with compiler command
|
||||
options. *Note Invocation::.
|
||||
|
||||
|
||||
|
||||
File: cpp.info, Node: #error Command, Prev: Conditionals-Macros, Up: Conditionals
|
||||
|
||||
The `#error' Command
|
||||
--------------------
|
||||
|
||||
The command `#error' causes the preprocessor to report a fatal error.
|
||||
The rest of the line that follows `#error' is used as the error
|
||||
message.
|
||||
|
||||
You would use `#error' inside of a conditional that detects a
|
||||
combination of parameters which you know the program does not
|
||||
properly support. For example, if you know that the program will not
|
||||
run properly on a Vax, you might write
|
||||
|
||||
#ifdef vax
|
||||
#error Won't work on Vaxen. See comments at get_last_object.
|
||||
#endif
|
||||
|
||||
*Note Nonstandard Predefined::, for why this works.
|
||||
|
||||
If you have several configuration parameters that must be set up by
|
||||
the installation in a consistent way, you can use conditionals to
|
||||
detect an inconsistency and report it with `#error'. For example,
|
||||
|
||||
#if HASH_TABLE_SIZE % 2 == 0 || HASH_TABLE_SIZE % 3 == 0 \
|
||||
|| HASH_TABLE_SIZE % 5 == 0
|
||||
#error HASH_TABLE_SIZE should not be divisible by a small prime
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
File: cpp.info, Node: Combining Sources, Next: Other Commands, Prev: Conditionals, Up: Top
|
||||
|
||||
Combining Source Files
|
||||
======================
|
||||
|
||||
One of the jobs of the C preprocessor is to inform the C compiler of
|
||||
where each line of C code came from: which source file and which line
|
||||
number.
|
||||
|
||||
C code can come from multiple source files if you use `#include';
|
||||
both `#include' and the use of conditionals and macros can cause the
|
||||
line number of a line in the preprocessor output to be different from
|
||||
the line's number in the original source file. You will appreciate
|
||||
the value of making both the C compiler (in error messages) and
|
||||
symbolic debuggers such as GDB use the line numbers in your source
|
||||
file.
|
||||
|
||||
The C preprocessor builds on this feature by offering a command by
|
||||
which you can control the feature explicitly. This is useful when a
|
||||
file for input to the C preprocessor is the output from another
|
||||
program such as the `bison' parser generator, which operates on
|
||||
another file that is the true source file. Parts of the output from
|
||||
`bison' are generated from scratch, other parts come from a standard
|
||||
parser file. The rest are copied nearly verbatim from the source
|
||||
file, but their line numbers in the `bison' output are not the same
|
||||
as their original line numbers. Naturally you would like compiler
|
||||
error messages and symbolic debuggers to know the original source
|
||||
file and line number of each line in the `bison' output.
|
||||
|
||||
`bison' arranges this by writing `#line' commands into the output
|
||||
file. `#line' is a command that specifies the original line number
|
||||
and source file name for subsequent input in the current preprocessor
|
||||
input file. `#line' has three variants:
|
||||
|
||||
`#line LINENUM'
|
||||
Here LINENUM is a decimal integer constant. This specifies that
|
||||
the line number of the following line of input, in its original
|
||||
source file, was LINENUM.
|
||||
|
||||
`#line LINENUM FILENAME'
|
||||
Here LINENUM is a decimal integer constant and FILENAME is a
|
||||
string constant. This specifies that the following line of
|
||||
input came originally from source file FILENAME and its line
|
||||
number there was LINENUM. Keep in mind that FILENAME is not
|
||||
just a file name; it is surrounded by doublequote characters so
|
||||
that it looks like a string constant.
|
||||
|
||||
`#line ANYTHING ELSE'
|
||||
ANYTHING ELSE is checked for macro calls, which are expanded.
|
||||
The result should be a decimal integer constant followed
|
||||
optionally by a string constant, as described above.
|
||||
|
||||
`#line' commands alter the results of the `__FILE__' and `__LINE__'
|
||||
predefined macros from that point on. *Note Standard Predefined::.
|
||||
|
||||
|
||||
|
||||
File: cpp.info, Node: Other Commands, Next: Output, Prev: Combining Sources, Up: Top
|
||||
|
||||
Miscellaneous Preprocessor Commands
|
||||
===================================
|
||||
|
||||
This section describes three additional preprocessor commands. They
|
||||
are not very useful, but are mentioned for completeness.
|
||||
|
||||
The "null command" consists of a `#' followed by a Newline, with only
|
||||
whitespace (including comments) in between. A null command is
|
||||
understood as a preprocessor command but has no effect on the
|
||||
preprocessor output. The primary significance of the existence of
|
||||
the null command is that an input line consisting of just a `#' will
|
||||
produce no output, rather than a line of output containing just a
|
||||
`#'. Supposedly some old C programs contain such lines.
|
||||
|
||||
The `#pragma' command is specified in the ANSI standard to have an
|
||||
arbitrary implementation-defined effect. In the GNU C preprocessor,
|
||||
`#pragma' commands are ignored, except for `#pragma once' (*note
|
||||
Once-Only::.).
|
||||
|
||||
The `#ident' command is supported for compatibility with certain
|
||||
other systems. It is followed by a line of text. On certain
|
||||
systems, the text is copied into a special place in the object file;
|
||||
on most systems, the text is ignored and this directive has no effect.
|
||||
|
||||
|
||||
|
||||
File: cpp.info, Node: Output, Next: Invocation, Prev: Other Commands, Up: Top
|
||||
|
||||
C Preprocessor Output
|
||||
=====================
|
||||
|
||||
The output from the C preprocessor looks much like the input, except
|
||||
that all preprocessor command lines have been replaced with blank
|
||||
lines and all comments with spaces. Whitespace within a line is not
|
||||
altered; however, a space is inserted after the expansions of most
|
||||
macro calls.
|
||||
|
||||
Source file name and line number information is conveyed by lines of
|
||||
the form
|
||||
|
||||
# LINENUM FILENAME FLAG
|
||||
|
||||
which are inserted as needed into the middle of the input (but never
|
||||
within a string or character constant). Such a line means that the
|
||||
following line originated in file FILENAME at line LINENUM.
|
||||
|
||||
The third field, FLAG, may be a number, or may be absent. It is `1'
|
||||
for the beginning of a new source file, and `2' for return to an old
|
||||
source file at the end of an included file. It is absent otherwise.
|
||||
|
||||
|
||||
|
||||
File: cpp.info, Node: Invocation, Next: Concept Index, Prev: Output, Up: Top
|
||||
|
||||
Invoking the C Preprocessor
|
||||
===========================
|
||||
|
||||
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.
|
||||
|
||||
The C preprocessor expects two file names as arguments, INFILE and
|
||||
OUTFILE. The preprocessor reads INFILE together with any other files
|
||||
it specifies with `#include'. All the output generated by the
|
||||
combined input files is written in OUTFILE.
|
||||
|
||||
Either INFILE or OUTFILE may be `-', which as INFILE means to read
|
||||
from standard input and as OUTFILE means to write to standard output.
|
||||
Also, if OUTFILE or both file names are omitted, the standard output
|
||||
and standard input are used for the omitted file names.
|
||||
|
||||
Here is a table of command options accepted by the C preprocessor.
|
||||
Most of them can also be given when compiling a C program; they are
|
||||
passed along automatically to the preprocessor when it is invoked by
|
||||
the compiler.
|
||||
|
||||
`-P'
|
||||
Inhibit generation of `#'-lines with line-number information in
|
||||
the output from the preprocessor (*note Output::.). 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 `#'-lines
|
||||
|
||||
`-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.
|
||||
|
||||
`-trigraphs'
|
||||
Process ANSI standard trigraph sequences. These are
|
||||
three-character sequences, all starting with `??', that are
|
||||
defined by ANSI C to stand for single characters. For example,
|
||||
`??/' stands for `\', so `'??/n'' is a character constant for a
|
||||
newline. Strictly speaking, the GNU C preprocessor does not
|
||||
support all programs in ANSI Standard C unless `-trigraphs' is
|
||||
used, but if you ever notice the difference it will be with
|
||||
relief.
|
||||
|
||||
You don't want to know any more about trigraphs.
|
||||
|
||||
`-pedantic'
|
||||
Issue warnings required by the ANSI C standard in certain cases
|
||||
such as when text other than a comment follows `#else' or
|
||||
`#endif'.
|
||||
|
||||
`-I DIRECTORY'
|
||||
Add the directory DIRECTORY to the end of the list of
|
||||
directories to be searched for header files (*note Include
|
||||
Syntax::.). 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 `-I' option, the directories are scanned in
|
||||
left-to-right order; the standard system directories come after.
|
||||
|
||||
`-I-'
|
||||
Any directories specified with `-I' options before the `-I-'
|
||||
option are searched only for the case of `#include "FILE"'; they
|
||||
are not searched for `#include <FILE>'.
|
||||
|
||||
If additional directories are specified with `-I' options after
|
||||
the `-I-', these directories are searched for all `#include'
|
||||
directives.
|
||||
|
||||
In addition, the `-I-' option inhibits the use of the current
|
||||
directory as the first search directory for `#include "FILE"'.
|
||||
Therefore, the current directory is searched only if it is
|
||||
requested explicitly with `-I.'. Specifying both `-I-' and
|
||||
`-I.' allows you to control precisely which directories are
|
||||
searched before the current one and which are searched after.
|
||||
|
||||
`-nostdinc'
|
||||
Do not search the standard system directories for header files.
|
||||
Only the directories you have specified with `-I' options (and
|
||||
the current directory, if appropriate) are searched.
|
||||
|
||||
`-D NAME'
|
||||
Predefine NAME as a macro, with definition `1'.
|
||||
|
||||
`-D NAME=DEFINITION'
|
||||
Predefine NAME as a macro, with definition DEFINITION. There
|
||||
are no restrictions on the contents of DEFINITION, 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.
|
||||
|
||||
`-U NAME'
|
||||
Do not predefine NAME. If both `-U' and `-D' are specified for
|
||||
one name, the `-U' beats the `-D' and the name is not predefined.
|
||||
|
||||
`-undef'
|
||||
Do not predefine any nonstandard macros.
|
||||
|
||||
`-d'
|
||||
Instead of outputting the result of preprocessing, output a list
|
||||
of `#define' commands for all the macros defined during the
|
||||
execution of the preprocessor.
|
||||
|
||||
`-M'
|
||||
Instead of outputting the result of preprocessing, output a rule
|
||||
suitable for `make' describing the dependencies of the main
|
||||
source file. The preprocessor outputs one `make' 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
|
||||
`\'-newline.
|
||||
|
||||
This feature is used in automatic updating of makefiles.
|
||||
|
||||
`-MM'
|
||||
Like `-M' but mention only the files included with `#include
|
||||
"FILE"'. System header files included with `#include <FILE>'
|
||||
are omitted.
|
||||
|
||||
`-i FILE'
|
||||
Process FILE as input, discarding the resulting output, before
|
||||
processing the regular input file. Because the output generated
|
||||
from FILE is discarded, the only effect of `-i FILE' is to make
|
||||
the macros defined in FILE available for use in the main input.
|
||||
|
||||
|
||||
|
||||
File: cpp.info, Node: Concept Index, Next: Index, Prev: Invocation, Up: Top
|
||||
|
||||
Concept Index
|
||||
*************
|
||||
|
||||
* Menu:
|
||||
|
||||
* cascaded macros: Cascaded Macros.
|
||||
* commands: Commands.
|
||||
* concatenation: Concatenation.
|
||||
* conditionals: Conditionals.
|
||||
* header file: Header Files.
|
||||
* line control: Combining Sources.
|
||||
* macro body uses macro: Cascaded Macros.
|
||||
* null command: Other Commands.
|
||||
* options: Invocation.
|
||||
* output format: Output.
|
||||
* predefined macros: Predefined.
|
||||
* preprocessor commands: Commands.
|
||||
* redefining macros: Redefining.
|
||||
* repeated inclusion: Once-Only.
|
||||
* self-reference: Self-Reference.
|
||||
* semicolons (after macro calls): Swallow Semicolon.
|
||||
* side effects (in macro arguments): Side Effects.
|
||||
* stringification: Stringification.
|
||||
* undefining macros: Undefining.
|
||||
* unsafe macros: Side Effects.
|
||||
|
||||
|
||||
|
||||
|
||||
File: cpp.info, Node: Index, Prev: Concept Index, Up: Top
|
||||
|
||||
Index of Commands, Macros and Options
|
||||
*************************************
|
||||
|
||||
* Menu:
|
||||
|
||||
* #elif: #elif Command.
|
||||
* #else: #else Command.
|
||||
* #error: #error Command.
|
||||
* #ident: Other Commands.
|
||||
* #if: Conditional Syntax.
|
||||
* #ifdef: Conditionals-Macros.
|
||||
* #ifndef: Conditionals-Macros.
|
||||
* #include: Include Syntax.
|
||||
* #line: Combining Sources.
|
||||
* #pragma: Other Commands.
|
||||
* -C: Invocation.
|
||||
* -D: Invocation.
|
||||
* -I: Invocation.
|
||||
* -M: Invocation.
|
||||
* -MM: Invocation.
|
||||
* -P: Invocation.
|
||||
* -U: Invocation.
|
||||
* -d: Invocation.
|
||||
* -i: Invocation.
|
||||
* -pedantic: Invocation.
|
||||
* -trigraphs: Invocation.
|
||||
* -undef: Invocation.
|
||||
* BSD: Nonstandard Predefined.
|
||||
* M68020: Nonstandard Predefined.
|
||||
* __BASE_FILE__: Standard Predefined.
|
||||
* __DATE__: Standard Predefined.
|
||||
* __FILE__: Standard Predefined.
|
||||
* __LINE__: Standard Predefined.
|
||||
* __STDC__: Standard Predefined.
|
||||
* __TIME__: Standard Predefined.
|
||||
* defined: Conditionals-Macros.
|
||||
* m68k: Nonstandard Predefined.
|
||||
* mc68000: Nonstandard Predefined.
|
||||
* ns32000: Nonstandard Predefined.
|
||||
* pyr: Nonstandard Predefined.
|
||||
* sequent: Nonstandard Predefined.
|
||||
* sun: Nonstandard Predefined.
|
||||
* system header files: Header Uses.
|
||||
* unix: Nonstandard Predefined.
|
||||
* vax: Nonstandard Predefined.
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,472 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This progam 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.
|
||||
*
|
||||
* Alliance VLSI CAD System 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 the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Delayed branch scheduling pass.
|
||||
Copyright (C) 1987, 1988, 1989 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY. No author or distributor
|
||||
accepts responsibility to anyone for the consequences of using it
|
||||
or for whether it serves any particular purpose or works at all,
|
||||
unless he says so in writing. Refer to the GNU CC General Public
|
||||
License for full details.
|
||||
|
||||
Everyone is granted permission to copy, modify and redistribute
|
||||
GNU CC, but only under the conditions described in the
|
||||
GNU CC General Public License. A copy of this license is
|
||||
supposed to have been given to you along with GNU CC so you
|
||||
can know your rights and responsibilities. It should be in a
|
||||
file named COPYING. Among other things, the copyright notice
|
||||
and this notice must be preserved on all copies. */
|
||||
|
||||
/* Delayed Branch Scheduling Optimization
|
||||
|
||||
If the HAVE_DELAYED_BRANCH macro is defined in the machine
|
||||
description, this code is called by toplev.c during optimizing
|
||||
compilation immediately after the final jump optimization pass
|
||||
and just before assembler output generation, if delayed branch
|
||||
scheduling is requested with the -fdelayed-branch switch.
|
||||
|
||||
Machines with delayed branch allow one or more instructions
|
||||
placed *after* a branch instruction to be executed while the
|
||||
hardware is off fetching the next instruction. These instructions
|
||||
are executed after the branch is issued, but before the branch
|
||||
actually takes effect. The decision as to whether or not
|
||||
the branch is to be taken, and the address of the branch target
|
||||
are fixed at the time the branch is issued, so only instructions
|
||||
that do not appear in the dependency graphs for computing the
|
||||
branch decision and/or target address may be relocated "after"
|
||||
the branch. Some machines might have additional restrictions,
|
||||
such as not allowing memory instructions or condition code
|
||||
modification in the delay sequence.
|
||||
|
||||
Note that this scheduling pass occurs after register allocation, and
|
||||
(of course) final jump optimization. This mechanism is *not* intended
|
||||
to be hacked to deal with similar memory-latency pipeline scheduling
|
||||
(i.e. slots after loads/stores), as tempting as that might be. The
|
||||
right place to do load-store latency scheduling is prior to register
|
||||
allocation, since allocation may introduce artificial dependencies
|
||||
that could have been avoided; note that these artificial dependencies
|
||||
are *not* reflected in the flow information, which is one reason for
|
||||
the somewhat ad hoc analysis done in this pass.
|
||||
|
||||
The strategy and methods used are as follows. The function DBR_SCHEDULE
|
||||
is called from toplev.c if the scheduling pass is to be run. That function
|
||||
sets up the dump file, then scans the current function from top to bottom
|
||||
for "d-blocks", which are like basic blocks (single-entry, single-exit),
|
||||
with the additional condition that the last instruction in the block has
|
||||
delay slots. Note that if calls have slots, d-blocks can be smaller than
|
||||
basic blocks. If a basic block does not end with a delay-instruction,
|
||||
it is skipped.
|
||||
|
||||
To re-order instructions in a d-block (see DBR_DBLOCK_SCHED), the scheduler
|
||||
scans backward from the "d-instruction", trying to fill the slots. The
|
||||
scheduler is somewhat conservative. Volatile memory references are
|
||||
serialized (their order is never changed to avoid possible aliasing
|
||||
problems). Definitions of registers are serialized (so there is no
|
||||
possibility of deadlock). Since hard register dependencies are
|
||||
not noted by flow analysis, the scheduler does its own simplified
|
||||
tracking of the registers, memory, and condition code uses/defines
|
||||
by the d-instruction and the instructions it depends on). Information
|
||||
available from flow analysis is used to shortcut the analysis where
|
||||
possible.
|
||||
|
||||
Since only data dependencies are considered by the scheduler, any
|
||||
machine-specific restrictions, e.g. to keep memory instructions from
|
||||
being scheduled into slots, must be explicit in the definition of
|
||||
DBR_INSN_ELIGIBLE_P.
|
||||
|
||||
The scheduler scans backwards over the block, looking for eligible
|
||||
insns to fill the slot(s). If none are found, nothing is done, and no
|
||||
changes are made to the code. As eligible insns are found, they are
|
||||
removed from the chain, and recorded in an INSN_LIST rtx. When all
|
||||
slots are full (or the top of the d-block is reached), the *pattern*
|
||||
of the d-insn is replaced with a SEQUENCE rtx, which consists of
|
||||
a copy of the original d-insn followed by the slot fillers. Slot
|
||||
filling instructions remain in the original relative order in the
|
||||
sequence.
|
||||
|
||||
When the SEQUENCE pattern is encountered by final, the instructions
|
||||
are output "normally", though the output code for the instructions
|
||||
may test for this and alter their behavior appropriately.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "config.h"
|
||||
#include "rtl.h"
|
||||
#include "hard-reg-set.h"
|
||||
#include "flags.h"
|
||||
|
||||
FILE *dbr_dump_file;
|
||||
|
||||
/* The number of unfilled delay slots in the current sequence. */
|
||||
static int slots_avail;
|
||||
|
||||
/* A flag, nonzero indicating that some insn that could not
|
||||
go in a slot writes to memory. */
|
||||
|
||||
static int memw;
|
||||
|
||||
/* A flag, nonzero indicating that the condition code is written
|
||||
by some insn that couldn't go in a delay slot. */
|
||||
|
||||
static int ccw;
|
||||
|
||||
/* Each bit is nonzero if the corresponding hard register
|
||||
is written by an insn that couldn't go in a delay slot. */
|
||||
|
||||
static HARD_REG_SET regw;
|
||||
|
||||
/* A flag, set nonzero if ENOTE determines that
|
||||
the current insn can't go in a delay slot because of a
|
||||
data dependency detected by note_stores. */
|
||||
|
||||
static int eflag;
|
||||
|
||||
/* The insn having delay slots. Global because of the calls through
|
||||
note_stores that need it. */
|
||||
|
||||
static rtx dinsn;
|
||||
|
||||
/* The insn being currently considered for a delay slot. */
|
||||
|
||||
static rtx insn;
|
||||
|
||||
/* An INSN_LIST (just like the insn field) that we use to hold
|
||||
LOG_LINKS of ineligible insns. We use what flow analysis
|
||||
stuff we can - this prevents exhaustive searches for write-read
|
||||
dependencies in most cases. This tactic only loses on reloads
|
||||
and code generated with hard regs (instead of pseudos). */
|
||||
|
||||
static rtx dep_insn_list;
|
||||
|
||||
/* Called by note_stores on "ineligible" insns to keep track of
|
||||
pre-branch dependencies. */
|
||||
static void
|
||||
pnote (x, in)
|
||||
rtx x;
|
||||
rtx in;
|
||||
{
|
||||
switch (GET_CODE (x))
|
||||
{
|
||||
case REG:
|
||||
if (GET_CODE (in) != SET
|
||||
|| GET_CODE (SET_SRC (in)) != CALL)
|
||||
SET_HARD_REG_BIT (regw, REGNO (x));
|
||||
return;
|
||||
case MEM:
|
||||
memw = TRUE; /* this might be relaxed somewhat later */
|
||||
return;
|
||||
case CC0:
|
||||
ccw = TRUE;
|
||||
return;
|
||||
case PC:
|
||||
return;
|
||||
default:
|
||||
abort (); /* should never happen */
|
||||
}
|
||||
}
|
||||
|
||||
/* The d-block end insn is in DINSN. Initialize the flags to
|
||||
start building the delay sequence. Calls PNOTE from note_stores
|
||||
to track the written registers and memory. */
|
||||
|
||||
static void
|
||||
init_flags ()
|
||||
{
|
||||
CLEAR_HARD_REG_SET (regw);
|
||||
memw = ccw = 0;
|
||||
note_stores (PATTERN (dinsn), pnote);
|
||||
if (LOG_LINKS (dinsn))
|
||||
dep_insn_list = copy_rtx (LOG_LINKS (dinsn));
|
||||
else
|
||||
dep_insn_list = 0;
|
||||
slots_avail = DBR_SLOTS_AFTER (dinsn);
|
||||
}
|
||||
|
||||
|
||||
/* Called through note_stores on possibly eligible insn patterns.
|
||||
Checks to see if a register written by the pattern is needed by an already
|
||||
ineligible insn. Sets the global EFLAG nonzero if a dependency
|
||||
is found. */
|
||||
|
||||
static void
|
||||
enote (x, p)
|
||||
rtx x;
|
||||
rtx p;
|
||||
{
|
||||
if (eflag == 0)
|
||||
{
|
||||
if (GET_CODE (x) == REG)
|
||||
{
|
||||
if (reg_used_between_p (x, insn, dinsn))
|
||||
goto lose;
|
||||
if ((!FUNCTION_VALUE_REGNO_P (REGNO (x)) ||
|
||||
GET_CODE (dinsn) != CALL_INSN) &&
|
||||
reg_mentioned_p (x, (PATTERN (dinsn))))
|
||||
goto lose;
|
||||
}
|
||||
else if (x == cc0_rtx &&
|
||||
reg_used_between_p (x, insn, NEXT_INSN (dinsn)))
|
||||
goto lose;
|
||||
return;
|
||||
lose:
|
||||
eflag = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Search the current dependency list DEP_INSN_LIST for INSN,
|
||||
return nonzero if found. */
|
||||
|
||||
static int
|
||||
in_dep_list_p (insn)
|
||||
rtx insn;
|
||||
{
|
||||
rtx l;
|
||||
for (l = dep_insn_list; l ; l = XEXP (l, 1))
|
||||
if (insn == XEXP (l, 0)) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns zero if INSN is ineligible to be put in a delay slot
|
||||
of DINSN. INSN is ineligible if it:
|
||||
- is in the dependency list of an ineligible insn.
|
||||
- writes a hard register needed by an ineligible insn.
|
||||
- reads a register written by an ineligible insn.
|
||||
- refers to memory.
|
||||
- sets the condition code.
|
||||
- violates a machine-dependent constraint. */
|
||||
|
||||
static int
|
||||
insn_eligible_p ()
|
||||
{
|
||||
rtx dest;
|
||||
rtx pat = PATTERN (insn);
|
||||
int i,s;
|
||||
|
||||
/* See if there are any explicit dependencies on this insn. */
|
||||
if (in_dep_list_p (insn))
|
||||
return 0;
|
||||
|
||||
/* Check for implicit dependencies by calling enote on each
|
||||
store rtx. ENOTE makes sure that no ineligible instruction
|
||||
refers to a register in a way that flow analysis
|
||||
has missed or ignored. */
|
||||
eflag = 0;
|
||||
note_stores (PATTERN (insn), enote);
|
||||
if (eflag)
|
||||
return 0;
|
||||
|
||||
/* Check for volatile memory refs if any already ineligible. */
|
||||
|
||||
if (memw && volatile_refs_p (pat))
|
||||
{
|
||||
memw = TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* See if it refers to any regs that are clobbered by ineligibles. */
|
||||
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
if (TEST_HARD_REG_BIT (regw, i)
|
||||
&& refers_to_regno_p (i, i + 1, pat, 0))
|
||||
return 0;
|
||||
|
||||
#ifdef DBR_INSN_ELIGIBLE_P
|
||||
/* Check for arbitrary machine constraints if any. */
|
||||
if (! DBR_INSN_ELIGIBLE_P (insn, dinsn))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Add the links in LIST to the dependency list. We put them
|
||||
at the front since this should make searches faster in long
|
||||
d-blocks.
|
||||
*/
|
||||
static void
|
||||
prepend_to_dep_list (list)
|
||||
rtx list;
|
||||
{
|
||||
rtx l = copy_rtx (list);
|
||||
while (XEXP (l, 1) != 0)
|
||||
l = XEXP (l, 1);
|
||||
XEXP (l, 1) = dep_insn_list;
|
||||
dep_insn_list = l;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Update the flags for ineligible INSN - it can't be put in a delay
|
||||
slot. This involves setting bits to indicate the stores of INSN, and
|
||||
adding any flow-analysis dependencies of INSN's insn-list to
|
||||
the ineligible list. (Should ultimately catch reloads too.) */
|
||||
|
||||
static void
|
||||
update_flags (insn)
|
||||
rtx insn;
|
||||
{
|
||||
rtx l;
|
||||
note_stores (PATTERN (insn), pnote);
|
||||
if (l = LOG_LINKS (insn))
|
||||
prepend_to_dep_list (l);
|
||||
}
|
||||
|
||||
/* Put INSN and LIST together in a SEQUENCE rtx of LENGTH, and replace
|
||||
the pattern of INSN with the SEQUENCE. Include the available
|
||||
slots AVAIL in the SEQUENCE insn. */
|
||||
static void
|
||||
emit_delay_sequence (insn, list, length, avail)
|
||||
rtx insn;
|
||||
rtx list;
|
||||
int length;
|
||||
int avail;
|
||||
{
|
||||
register int i = 1;
|
||||
register rtx li, tem;
|
||||
/* Allocate the the rtvec to hold the insns and the SEQUENCE. */
|
||||
rtvec seqv = rtvec_alloc (length + 1);
|
||||
rtx seq = gen_rtx (SEQUENCE, VOIDmode, seqv);
|
||||
|
||||
/* Make a copy of the insn having delay slots. */
|
||||
tem = copy_rtx (insn);
|
||||
NEXT_INSN (tem) = 0;
|
||||
PREV_INSN (tem) = 0;
|
||||
/* Replace the original pattern with a sequence whose
|
||||
first insn is the copy. */
|
||||
PATTERN (insn) = seq;
|
||||
INSN_CODE (insn) = -1;
|
||||
XVECEXP (seq, 0, 0) = tem;
|
||||
/* Copy in the delay-slot filling insns. */
|
||||
for (li = list; li; li = XEXP (li, 1))
|
||||
{
|
||||
XVECEXP (seq, 0, i) = XEXP (li, 0);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to reorganize code in a d-block */
|
||||
|
||||
static void
|
||||
dbr_dblock_sched (first, last)
|
||||
rtx first, last;
|
||||
{
|
||||
rtx delay_insn_list = 0;
|
||||
int seq_len = 0;
|
||||
dinsn = last;
|
||||
if (first == last) return;
|
||||
init_flags ();
|
||||
insn = PREV_INSN (dinsn);
|
||||
while (1)
|
||||
{
|
||||
rtx prev = PREV_INSN (insn);
|
||||
rtx next = NEXT_INSN (insn);
|
||||
if (GET_CODE (insn) == INSN
|
||||
&& GET_CODE (PATTERN (insn)) != USE
|
||||
&& GET_CODE (PATTERN (insn)) != CLOBBER
|
||||
&& GET_CODE (PATTERN (insn)) != ADDR_VEC
|
||||
&& GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC)
|
||||
{
|
||||
if (slots_avail >= DBR_INSN_SLOTS (insn) && insn_eligible_p ())
|
||||
{
|
||||
/* Add this insn to the delay sequence and
|
||||
update the number of slots available. */
|
||||
register rtx t = delay_insn_list;
|
||||
delay_insn_list = gen_rtx (INSN_LIST, VOIDmode, insn, t);
|
||||
seq_len++;
|
||||
slots_avail -= DBR_INSN_SLOTS (insn);
|
||||
|
||||
/* Now remove it from the chain. */
|
||||
NEXT_INSN (prev) = next;
|
||||
PREV_INSN (next) = prev;
|
||||
NEXT_INSN (insn) = PREV_INSN (insn) = 0;
|
||||
}
|
||||
else
|
||||
update_flags (insn);
|
||||
}
|
||||
else
|
||||
if (GET_CODE (insn) != NOTE)
|
||||
abort ();
|
||||
if (slots_avail == 0 || insn == first)
|
||||
break;
|
||||
else
|
||||
insn = prev;
|
||||
}
|
||||
/* Done. If the delay list is non-empty, emit a sequence
|
||||
in place of the dinsn. */
|
||||
if (delay_insn_list != 0)
|
||||
emit_delay_sequence (dinsn, delay_insn_list, seq_len, slots_avail);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Identify d-blocks of a function, which are sort of like basic
|
||||
blocks, except that any instruction with delay slots defines the end
|
||||
of a dblock, and dblocks that do not end in delay-instructions are
|
||||
uninteresting degenerate cases.
|
||||
|
||||
This function finds d-blocks in the code for a function, and calls
|
||||
dbr_dblock_sched on non-degenerate blocks. Called from toplev.c
|
||||
if HAVE_DELAYED_BRANCH is defined and we are doing optimizing
|
||||
compilation. F is the first insn of the function, DUMP_FILE
|
||||
is the file to output debugging info on if requested. */
|
||||
|
||||
void
|
||||
dbr_schedule (f, dump_file)
|
||||
rtx f;
|
||||
FILE *dump_file;
|
||||
{
|
||||
rtx first = f;
|
||||
rtx insn;
|
||||
/* Dump output if requested */
|
||||
if (dbr_dump_file = dump_file)
|
||||
fprintf (dbr_dump_file, "Delayed-branch reordering dump.\n");
|
||||
|
||||
/* Search for d-blocks by scanning the insns from top to bottom. */
|
||||
for (insn = first; insn; insn = NEXT_INSN (insn))
|
||||
{
|
||||
if (DBR_SLOTS_AFTER (insn) > 0)
|
||||
{
|
||||
/* An insn with delay slots always terminates a d-block.
|
||||
Call the scheduler to fill in the slots if possible. */
|
||||
dbr_dblock_sched (first, insn);
|
||||
|
||||
/* Resume scanning after the end of the sequence. */
|
||||
first = NEXT_INSN (dinsn);
|
||||
}
|
||||
else
|
||||
/* Not an end of a real d-block, but need to check
|
||||
if it is the end of a degenerate one. Note that
|
||||
calls or jumps will only reach here if they aren't
|
||||
delayed instructions. */
|
||||
|
||||
if (GET_CODE (insn) == CODE_LABEL ||
|
||||
GET_CODE (insn) == JUMP_INSN ||
|
||||
GET_CODE (insn) == CALL_INSN)
|
||||
first = NEXT_INSN (insn);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,10 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# ecoff-cmp file1.o file2.o
|
||||
#
|
||||
ld -s -L -o /tmp/foo1.$$ $1 2>1 > /dev/null
|
||||
ld -s -L -o /tmp/foo2.$$ $2 2>1 > /dev/null
|
||||
tail +10c /tmp/foo1.$$ > /tmp/foo3.$$
|
||||
tail +10c /tmp/foo2.$$ > /tmp/foo4.$$
|
||||
cmp /tmp/foo3.$$ /tmp/foo4.$$
|
||||
rm -f /tmp/foo[1234].$$
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,598 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This progam 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.
|
||||
*
|
||||
* Alliance VLSI CAD System 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 the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Subroutines for manipulating rtx's in semantically interesting ways.
|
||||
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 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include "rtl.h"
|
||||
#include "tree.h"
|
||||
#include "flags.h"
|
||||
#include "expr.h"
|
||||
|
||||
/* Return an rtx for the sum of X and the integer C. */
|
||||
|
||||
rtx
|
||||
plus_constant (x, c)
|
||||
register rtx x;
|
||||
register int c;
|
||||
{
|
||||
register RTX_CODE code = GET_CODE (x);
|
||||
register enum machine_mode mode = GET_MODE (x);
|
||||
int all_constant = 0;
|
||||
|
||||
if (c == 0)
|
||||
return x;
|
||||
|
||||
if (code == CONST_INT)
|
||||
return gen_rtx (CONST_INT, VOIDmode, (INTVAL (x) + c));
|
||||
|
||||
/* If adding to something entirely constant, set a flag
|
||||
so that we can add a CONST around the result. */
|
||||
if (code == CONST)
|
||||
{
|
||||
x = XEXP (x, 0);
|
||||
all_constant = 1;
|
||||
}
|
||||
else if (code == SYMBOL_REF || code == LABEL_REF)
|
||||
all_constant = 1;
|
||||
|
||||
/* The interesting case is adding the integer to a sum.
|
||||
Look for constant term in the sum and combine
|
||||
with C. For an integer constant term, we make a combined
|
||||
integer. For a constant term that is not an explicit integer,
|
||||
we cannot really combine, but group them together anyway. */
|
||||
|
||||
if (GET_CODE (x) == PLUS)
|
||||
{
|
||||
if (GET_CODE (XEXP (x, 0)) == CONST_INT)
|
||||
{
|
||||
c += INTVAL (XEXP (x, 0));
|
||||
x = XEXP (x, 1);
|
||||
}
|
||||
else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
|
||||
{
|
||||
c += INTVAL (XEXP (x, 1));
|
||||
x = XEXP (x, 0);
|
||||
}
|
||||
else if (CONSTANT_P (XEXP (x, 0)))
|
||||
{
|
||||
return gen_rtx (PLUS, mode,
|
||||
plus_constant (XEXP (x, 0), c),
|
||||
XEXP (x, 1));
|
||||
}
|
||||
else if (CONSTANT_P (XEXP (x, 1)))
|
||||
{
|
||||
return gen_rtx (PLUS, mode,
|
||||
XEXP (x, 0),
|
||||
plus_constant (XEXP (x, 1), c));
|
||||
}
|
||||
#ifdef OLD_INDEXING
|
||||
/* Detect adding a constant to an indexed address
|
||||
of the form (PLUS (MULT (REG) (CONST)) regs-and-constants).
|
||||
Keep the (MULT ...) at the top level of addition so that
|
||||
the result is still suitable for indexing and constants
|
||||
are combined. */
|
||||
else if (GET_CODE (XEXP (x, 0)) == MULT)
|
||||
{
|
||||
return gen_rtx (PLUS, mode, XEXP (x, 0),
|
||||
plus_constant (XEXP (x, 1), c));
|
||||
}
|
||||
else if (GET_CODE (XEXP (x, 1)) == MULT)
|
||||
{
|
||||
return gen_rtx (PLUS, mode, plus_constant (XEXP (x, 0), c),
|
||||
XEXP (x, 1));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (c != 0)
|
||||
x = gen_rtx (PLUS, mode, x, gen_rtx (CONST_INT, VOIDmode, c));
|
||||
|
||||
if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
|
||||
return x;
|
||||
else if (all_constant)
|
||||
return gen_rtx (CONST, mode, x);
|
||||
else
|
||||
return x;
|
||||
}
|
||||
|
||||
/* If X is a sum, return a new sum like X but lacking any constant terms.
|
||||
Add all the removed constant terms into *CONSTPTR.
|
||||
X itself is not altered. The result != X if and only if
|
||||
it is not isomorphic to X. */
|
||||
|
||||
rtx
|
||||
eliminate_constant_term (x, constptr)
|
||||
rtx x;
|
||||
int *constptr;
|
||||
{
|
||||
int c;
|
||||
register rtx x0, x1;
|
||||
|
||||
if (GET_CODE (x) != PLUS)
|
||||
return x;
|
||||
|
||||
/* First handle constants appearing at this level explicitly. */
|
||||
if (GET_CODE (XEXP (x, 0)) == CONST_INT)
|
||||
{
|
||||
*constptr += INTVAL (XEXP (x, 0));
|
||||
return eliminate_constant_term (XEXP (x, 1), constptr);
|
||||
}
|
||||
|
||||
if (GET_CODE (XEXP (x, 1)) == CONST_INT)
|
||||
{
|
||||
*constptr += INTVAL (XEXP (x, 1));
|
||||
return eliminate_constant_term (XEXP (x, 0), constptr);
|
||||
}
|
||||
|
||||
c = 0;
|
||||
x0 = eliminate_constant_term (XEXP (x, 0), &c);
|
||||
x1 = eliminate_constant_term (XEXP (x, 1), &c);
|
||||
if (x1 != XEXP (x, 1) || x0 != XEXP (x, 0))
|
||||
{
|
||||
*constptr += c;
|
||||
return gen_rtx (PLUS, GET_MODE (x), x0, x1);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Return an rtx for the size in bytes of the value of EXP. */
|
||||
|
||||
rtx
|
||||
expr_size (exp)
|
||||
tree exp;
|
||||
{
|
||||
return expand_expr (size_in_bytes (TREE_TYPE (exp)), 0, SImode, 0);
|
||||
}
|
||||
|
||||
/* Not yet really written since C does not need it. */
|
||||
|
||||
rtx
|
||||
lookup_static_chain (context)
|
||||
rtx context;
|
||||
{
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Return a copy of X in which all memory references
|
||||
and all constants that involve symbol refs
|
||||
have been replaced with new temporary registers.
|
||||
Also emit code to load the memory locations and constants
|
||||
into those registers.
|
||||
|
||||
If X contains no such constants or memory references,
|
||||
X itself (not a copy) is returned.
|
||||
|
||||
X may contain no arithmetic except addition, subtraction and multiplication.
|
||||
Values returned by expand_expr with 1 for sum_ok fit this constraint. */
|
||||
|
||||
static rtx
|
||||
break_out_memory_refs (x)
|
||||
register rtx x;
|
||||
{
|
||||
if (GET_CODE (x) == MEM || GET_CODE (x) == CONST
|
||||
|| GET_CODE (x) == SYMBOL_REF)
|
||||
{
|
||||
register rtx temp = force_reg (Pmode, x);
|
||||
mark_reg_pointer (temp);
|
||||
x = temp;
|
||||
}
|
||||
else if (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS
|
||||
|| GET_CODE (x) == MULT)
|
||||
{
|
||||
register rtx op0 = break_out_memory_refs (XEXP (x, 0));
|
||||
register rtx op1 = break_out_memory_refs (XEXP (x, 1));
|
||||
if (op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
|
||||
x = gen_rtx (GET_CODE (x), Pmode, op0, op1);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Given a memory address or facsimile X, construct a new address,
|
||||
currently equivalent, that is stable: future stores won't change it.
|
||||
|
||||
X must be composed of constants, register and memory references
|
||||
combined with addition, subtraction and multiplication:
|
||||
in other words, just what you can get from expand_expr if sum_ok is 1.
|
||||
|
||||
Works by making copies of all regs and memory locations used
|
||||
by X and combining them the same way X does.
|
||||
You could also stabilize the reference to this address
|
||||
by copying the address to a register with copy_to_reg;
|
||||
but then you wouldn't get indexed addressing in the reference. */
|
||||
|
||||
rtx
|
||||
copy_all_regs (x)
|
||||
register rtx x;
|
||||
{
|
||||
if (GET_CODE (x) == REG)
|
||||
{
|
||||
if (REGNO (x) != FRAME_POINTER_REGNUM)
|
||||
x = copy_to_reg (x);
|
||||
}
|
||||
else if (GET_CODE (x) == MEM)
|
||||
x = copy_to_reg (x);
|
||||
else if (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS
|
||||
|| GET_CODE (x) == MULT)
|
||||
{
|
||||
register rtx op0 = copy_all_regs (XEXP (x, 0));
|
||||
register rtx op1 = copy_all_regs (XEXP (x, 1));
|
||||
if (op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
|
||||
x = gen_rtx (GET_CODE (x), Pmode, op0, op1);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Return something equivalent to X but valid as a memory address
|
||||
for something of mode MODE. When X is not itself valid, this
|
||||
works by copying X or subexpressions of it into registers. */
|
||||
|
||||
rtx
|
||||
memory_address (mode, x)
|
||||
enum machine_mode mode;
|
||||
register rtx x;
|
||||
{
|
||||
register rtx oldx;
|
||||
|
||||
/* By passing constant addresses thru registers
|
||||
we get a chance to cse them. */
|
||||
if (! cse_not_expected && CONSTANT_P (x))
|
||||
return force_reg (Pmode, x);
|
||||
|
||||
/* Accept a QUEUED that refers to a REG
|
||||
even though that isn't a valid address.
|
||||
On attempting to put this in an insn we will call protect_from_queue
|
||||
which will turn it into a REG, which is valid. */
|
||||
if (GET_CODE (x) == QUEUED
|
||||
&& GET_CODE (QUEUED_VAR (x)) == REG)
|
||||
return x;
|
||||
|
||||
/* We get better cse by rejecting indirect addressing at this stage.
|
||||
Let the combiner create indirect addresses where appropriate.
|
||||
For now, generate the code so that the subexpressions useful to share
|
||||
are visible. But not if cse won't be done! */
|
||||
oldx = x;
|
||||
if (! cse_not_expected && GET_CODE (x) != REG)
|
||||
x = break_out_memory_refs (x);
|
||||
|
||||
/* At this point, any valid address is accepted. */
|
||||
GO_IF_LEGITIMATE_ADDRESS (mode, x, win);
|
||||
|
||||
/* If it was valid before but breaking out memory refs invalidated it,
|
||||
use it the old way. */
|
||||
if (memory_address_p (mode, oldx))
|
||||
goto win2;
|
||||
|
||||
/* Perform machine-dependent transformations on X
|
||||
in certain cases. This is not necessary since the code
|
||||
below can handle all possible cases, but machine-dependent
|
||||
transformations can make better code. */
|
||||
LEGITIMIZE_ADDRESS (x, oldx, mode, win);
|
||||
|
||||
/* PLUS and MULT can appear in special ways
|
||||
as the result of attempts to make an address usable for indexing.
|
||||
Usually they are dealt with by calling force_operand, below.
|
||||
But a sum containing constant terms is special
|
||||
if removing them makes the sum a valid address:
|
||||
then we generate that address in a register
|
||||
and index off of it. We do this because it often makes
|
||||
shorter code, and because the addresses thus generated
|
||||
in registers often become common subexpressions. */
|
||||
if (GET_CODE (x) == PLUS)
|
||||
{
|
||||
int constant_term = 0;
|
||||
rtx y = eliminate_constant_term (x, &constant_term);
|
||||
if (constant_term == 0
|
||||
|| ! memory_address_p (mode, y))
|
||||
return force_operand (x, 0);
|
||||
|
||||
y = plus_constant (copy_to_reg (y), constant_term);
|
||||
if (! memory_address_p (mode, y))
|
||||
return force_operand (x, 0);
|
||||
return y;
|
||||
}
|
||||
if (GET_CODE (x) == MULT || GET_CODE (x) == MINUS)
|
||||
return force_operand (x, 0);
|
||||
|
||||
/* If we have a register that's an invalid address,
|
||||
it must be a hard reg of the wrong class. Copy it to a pseudo. */
|
||||
if (GET_CODE (x) == REG)
|
||||
return copy_to_reg (x);
|
||||
|
||||
/* Last resort: copy the value to a register, since
|
||||
the register is a valid address. */
|
||||
return force_reg (Pmode, x);
|
||||
|
||||
win2:
|
||||
x = oldx;
|
||||
win:
|
||||
if (flag_force_addr && optimize && GET_CODE (x) != REG
|
||||
/* Don't copy an addr via a reg if it is one of our stack slots.
|
||||
If we did, it would cause invalid REG_EQUIV notes for parms. */
|
||||
&& ! (GET_CODE (x) == PLUS
|
||||
&& (XEXP (x, 0) == frame_pointer_rtx
|
||||
|| XEXP (x, 0) == arg_pointer_rtx)))
|
||||
{
|
||||
if (general_operand (x, Pmode))
|
||||
return force_reg (Pmode, x);
|
||||
else
|
||||
return force_operand (x, 0);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Like `memory_address' but pretend `flag_force_addr' is 0. */
|
||||
|
||||
rtx
|
||||
memory_address_noforce (mode, x)
|
||||
enum machine_mode mode;
|
||||
rtx x;
|
||||
{
|
||||
int ambient_force_addr = flag_force_addr;
|
||||
rtx val;
|
||||
|
||||
flag_force_addr = 0;
|
||||
val = memory_address (mode, x);
|
||||
flag_force_addr = ambient_force_addr;
|
||||
return val;
|
||||
}
|
||||
|
||||
/* Return a modified copy of X with its memory address copied
|
||||
into a temporary register to protect it from side effects.
|
||||
If X is not a MEM, it is returned unchanged (and not copied).
|
||||
Perhaps even if it is a MEM, if there is no need to change it. */
|
||||
|
||||
rtx
|
||||
stabilize (x)
|
||||
rtx x;
|
||||
{
|
||||
register rtx addr;
|
||||
if (GET_CODE (x) != MEM)
|
||||
return x;
|
||||
addr = XEXP (x, 0);
|
||||
if (rtx_unstable_p (addr))
|
||||
{
|
||||
rtx temp = copy_all_regs (addr);
|
||||
rtx mem;
|
||||
if (GET_CODE (temp) != REG)
|
||||
temp = copy_to_reg (temp);
|
||||
mem = gen_rtx (MEM, GET_MODE (x), temp);
|
||||
/* Mark returned memref with in_struct
|
||||
if it's in an array or structure. */
|
||||
if (GET_CODE (addr) == PLUS || MEM_IN_STRUCT_P (x))
|
||||
MEM_IN_STRUCT_P (mem) = 1;
|
||||
return mem;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Copy the value or contents of X to a new temp reg and return that reg. */
|
||||
|
||||
rtx
|
||||
copy_to_reg (x)
|
||||
rtx x;
|
||||
{
|
||||
register rtx temp = gen_reg_rtx (GET_MODE (x));
|
||||
|
||||
/* If not an operand, must be an address with PLUS and MULT so
|
||||
do the computation. */
|
||||
if (! general_operand (x, VOIDmode))
|
||||
x = force_operand (x, temp);
|
||||
|
||||
if (x != temp)
|
||||
emit_move_insn (temp, x);
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
/* Like copy_to_reg but always give the new register mode Pmode
|
||||
in case X is a constant. */
|
||||
|
||||
rtx
|
||||
copy_addr_to_reg (x)
|
||||
rtx x;
|
||||
{
|
||||
return copy_to_mode_reg (Pmode, x);
|
||||
}
|
||||
|
||||
/* Like copy_to_reg but always give the new register mode MODE
|
||||
in case X is a constant. */
|
||||
|
||||
rtx
|
||||
copy_to_mode_reg (mode, x)
|
||||
enum machine_mode mode;
|
||||
rtx x;
|
||||
{
|
||||
register rtx temp = gen_reg_rtx (mode);
|
||||
|
||||
/* If not an operand, must be an address with PLUS and MULT so
|
||||
do the computation. */
|
||||
if (! general_operand (x, VOIDmode))
|
||||
x = force_operand (x, temp);
|
||||
|
||||
if (GET_MODE (x) != mode && GET_MODE (x) != VOIDmode)
|
||||
abort ();
|
||||
if (x != temp)
|
||||
emit_move_insn (temp, x);
|
||||
return temp;
|
||||
}
|
||||
|
||||
/* Load X into a register if it is not already one.
|
||||
Use mode MODE for the register.
|
||||
X should be valid for mode MODE, but it may be a constant which
|
||||
is valid for all integer modes; that's why caller must specify MODE.
|
||||
|
||||
The caller must not alter the value in the register we return,
|
||||
since we mark it as a "constant" register. */
|
||||
|
||||
rtx
|
||||
force_reg (mode, x)
|
||||
enum machine_mode mode;
|
||||
rtx x;
|
||||
{
|
||||
register rtx temp, insn;
|
||||
|
||||
if (GET_CODE (x) == REG)
|
||||
return x;
|
||||
temp = gen_reg_rtx (mode);
|
||||
insn = emit_move_insn (temp, x);
|
||||
/* Let optimizers know that TEMP's value never changes
|
||||
and that X can be substituted for it. */
|
||||
if (CONSTANT_P (x))
|
||||
REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUIV, x, REG_NOTES (insn));
|
||||
return temp;
|
||||
}
|
||||
|
||||
/* If X is a memory ref, copy its contents to a new temp reg and return
|
||||
that reg. Otherwise, return X. */
|
||||
|
||||
rtx
|
||||
force_not_mem (x)
|
||||
rtx x;
|
||||
{
|
||||
register rtx temp;
|
||||
if (GET_CODE (x) != MEM || GET_MODE (x) == BLKmode)
|
||||
return x;
|
||||
temp = gen_reg_rtx (GET_MODE (x));
|
||||
emit_move_insn (temp, x);
|
||||
return temp;
|
||||
}
|
||||
|
||||
/* Copy X to TARGET (if it's nonzero and a reg)
|
||||
or to a new temp reg and return that reg. */
|
||||
|
||||
rtx
|
||||
copy_to_suggested_reg (x, target)
|
||||
rtx x, target;
|
||||
{
|
||||
register rtx temp;
|
||||
if (target && GET_CODE (target) == REG)
|
||||
temp = target;
|
||||
else
|
||||
temp = gen_reg_rtx (GET_MODE (x));
|
||||
emit_move_insn (temp, x);
|
||||
return temp;
|
||||
}
|
||||
|
||||
/* Adjust the stack pointer by ADJUST (an rtx for a number of bytes).
|
||||
This pops when ADJUST is positive. ADJUST need not be constant. */
|
||||
|
||||
void
|
||||
adjust_stack (adjust)
|
||||
rtx adjust;
|
||||
{
|
||||
adjust = protect_from_queue (adjust, 0);
|
||||
|
||||
#ifdef STACK_GROWS_DOWNWARD
|
||||
emit_insn (gen_add2_insn (stack_pointer_rtx, adjust));
|
||||
#else
|
||||
emit_insn (gen_sub2_insn (stack_pointer_rtx, adjust));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Adjust the stack pointer by minus ADJUST (an rtx for a number of bytes).
|
||||
This pushes when ADJUST is positive. ADJUST need not be constant. */
|
||||
|
||||
void
|
||||
anti_adjust_stack (adjust)
|
||||
rtx adjust;
|
||||
{
|
||||
adjust = protect_from_queue (adjust, 0);
|
||||
|
||||
#ifdef STACK_GROWS_DOWNWARD
|
||||
emit_insn (gen_sub2_insn (stack_pointer_rtx, adjust));
|
||||
#else
|
||||
emit_insn (gen_add2_insn (stack_pointer_rtx, adjust));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Round the size of a block to be pushed up to the boundary required
|
||||
by this machine. SIZE is the desired size, which need not be constant. */
|
||||
|
||||
rtx
|
||||
round_push (size)
|
||||
rtx size;
|
||||
{
|
||||
#ifdef STACK_BOUNDARY
|
||||
int align = STACK_BOUNDARY / BITS_PER_UNIT;
|
||||
if (align == 1)
|
||||
return size;
|
||||
if (GET_CODE (size) == CONST_INT)
|
||||
{
|
||||
int new = (INTVAL (size) + align - 1) / align * align;
|
||||
if (INTVAL (size) != new)
|
||||
size = gen_rtx (CONST_INT, VOIDmode, new);
|
||||
}
|
||||
else
|
||||
{
|
||||
size = expand_divmod (0, CEIL_DIV_EXPR, Pmode, size,
|
||||
gen_rtx (CONST_INT, VOIDmode, align),
|
||||
0, 1);
|
||||
size = expand_mult (Pmode, size,
|
||||
gen_rtx (CONST_INT, VOIDmode, align),
|
||||
0, 1);
|
||||
}
|
||||
#endif /* STACK_BOUNDARY */
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Return an rtx representing the register or memory location
|
||||
in which a scalar value of data type VALTYPE
|
||||
was returned by a function call to function FUNC.
|
||||
FUNC is a FUNCTION_DECL node if the precise function is known,
|
||||
otherwise 0. */
|
||||
|
||||
rtx
|
||||
hard_function_value (valtype, func)
|
||||
tree valtype;
|
||||
tree func;
|
||||
{
|
||||
return FUNCTION_VALUE (valtype, func);
|
||||
}
|
||||
|
||||
/* Return an rtx representing the register or memory location
|
||||
in which a scalar value of mode MODE was returned by a library call. */
|
||||
|
||||
rtx
|
||||
hard_libcall_value (mode)
|
||||
enum machine_mode mode;
|
||||
{
|
||||
return LIBCALL_VALUE (mode);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,409 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This progam 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.
|
||||
*
|
||||
* Alliance VLSI CAD System 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 the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Definitions for code generation pass of GNU compiler.
|
||||
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 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
/* Macros to access the slots of a QUEUED rtx.
|
||||
Here rather than in rtl.h because only the expansion pass
|
||||
should ever encounter a QUEUED. */
|
||||
|
||||
/* The variable for which an increment is queued. */
|
||||
#define QUEUED_VAR(P) XEXP (P, 0)
|
||||
/* If the increment has been emitted, this is the insn
|
||||
that does the increment. It is zero before the increment is emitted. */
|
||||
#define QUEUED_INSN(P) XEXP (P, 1)
|
||||
/* If a pre-increment copy has been generated, this is the copy
|
||||
(it is a temporary reg). Zero if no copy made yet. */
|
||||
#define QUEUED_COPY(P) XEXP (P, 2)
|
||||
/* This is the body to use for the insn to do the increment.
|
||||
It is used to emit the increment. */
|
||||
#define QUEUED_BODY(P) XEXP (P, 3)
|
||||
/* Next QUEUED in the queue. */
|
||||
#define QUEUED_NEXT(P) XEXP (P, 4)
|
||||
|
||||
/* This is the 4th arg to `expand_expr'.
|
||||
EXPAND_SUM means it is ok to return a PLUS rtx or MULT rtx.
|
||||
EXPND_CONST_ADDRESS means it is ok to return a MEM whose address
|
||||
is a constant that is not a legitimate address. */
|
||||
enum expand_modifier {EXPAND_NORMAL, EXPAND_SUM, EXPAND_CONST_ADDRESS};
|
||||
|
||||
/* If this is nonzero, we do not bother generating VOLATILE
|
||||
around volatile memory references, and we are willing to
|
||||
output indirect addresses. If cse is to follow, we reject
|
||||
indirect addresses so a useful potential cse is generated;
|
||||
if it is used only once, instruction combination will produce
|
||||
the same indirect address eventually. */
|
||||
extern int cse_not_expected;
|
||||
|
||||
/* List (chain of EXPR_LISTs) of pseudo-regs of SAVE_EXPRs.
|
||||
So we can mark them all live at the end of the function, if stupid. */
|
||||
extern rtx save_expr_regs;
|
||||
|
||||
extern int current_function_calls_alloca;
|
||||
|
||||
/* This is the offset from the arg pointer to the place where the first
|
||||
anonymous arg can be found, if there is one. */
|
||||
extern rtx current_function_arg_offset_rtx;
|
||||
|
||||
/* Nonzero means stack pops must not be deferred, and deferred stack
|
||||
pops must not be output. It is nonzero inside a function call,
|
||||
inside a conditional expression, inside a statement expression,
|
||||
and in other cases as well. */
|
||||
extern int inhibit_defer_pop;
|
||||
|
||||
#define NO_DEFER_POP (inhibit_defer_pop += 1)
|
||||
#define OK_DEFER_POP (inhibit_defer_pop -= 1)
|
||||
|
||||
#ifdef TREE_CODE /* Don't lose if tree.h not included. */
|
||||
/* Structure to record the size of a sequence of arguments
|
||||
as the sum of a tree-expression and a constant. */
|
||||
|
||||
struct args_size
|
||||
{
|
||||
int constant;
|
||||
tree var;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Add the value of the tree INC to the `struct args_size' TO. */
|
||||
|
||||
#define ADD_PARM_SIZE(TO, INC) \
|
||||
{ tree inc = (INC); \
|
||||
if (TREE_CODE (inc) == INTEGER_CST) \
|
||||
(TO).constant += TREE_INT_CST_LOW (inc); \
|
||||
else if ((TO).var == 0) \
|
||||
(TO).var = inc; \
|
||||
else \
|
||||
(TO).var = genop (PLUS_EXPR, (TO).var, inc); }
|
||||
|
||||
#define SUB_PARM_SIZE(TO, DEC) \
|
||||
{ tree dec = (DEC); \
|
||||
if (TREE_CODE (dec) == INTEGER_CST) \
|
||||
(TO).constant -= TREE_INT_CST_LOW (dec); \
|
||||
else if ((TO).var == 0) \
|
||||
(TO).var = genop (MINUS_EXPR, integer_zero_node, dec); \
|
||||
else \
|
||||
(TO).var = genop (MINUS_EXPR, (TO).var, dec); }
|
||||
|
||||
/* Convert the implicit sum in a `struct args_size' into an rtx. */
|
||||
#define ARGS_SIZE_RTX(SIZE) \
|
||||
((SIZE).var == 0 ? gen_rtx (CONST_INT, VOIDmode, (SIZE).constant) \
|
||||
: plus_constant (expand_expr ((SIZE).var, 0, VOIDmode, 0), \
|
||||
(SIZE).constant))
|
||||
|
||||
/* Supply a default definition for FUNCTION_ARG_PADDING:
|
||||
usually pad upward, but pad short args downward on big-endian machines. */
|
||||
|
||||
enum direction {none, upward, downward}; /* Value has this type. */
|
||||
|
||||
#ifndef FUNCTION_ARG_PADDING
|
||||
#ifdef BYTES_BIG_ENDIAN
|
||||
#define FUNCTION_ARG_PADDING(mode, size) \
|
||||
(((mode) == BLKmode \
|
||||
? (GET_CODE (size) == CONST_INT \
|
||||
&& INTVAL (size) < PARM_BOUNDARY / BITS_PER_UNIT) \
|
||||
: GET_MODE_BITSIZE (mode) < PARM_BOUNDARY) \
|
||||
? downward : upward)
|
||||
#else
|
||||
#define FUNCTION_ARG_PADDING(mode, size) upward
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Nonzero if type TYPE should be returned in memory
|
||||
(even though its mode is not BLKmode).
|
||||
Most machines can use the following default definition. */
|
||||
|
||||
#ifndef RETURN_IN_MEMORY
|
||||
#define RETURN_IN_MEMORY(type) 0
|
||||
#endif
|
||||
|
||||
/* Optabs are tables saying how to generate insn bodies
|
||||
for various machine modes and numbers of operands.
|
||||
Each optab applies to one operation.
|
||||
For example, add_optab applies to addition.
|
||||
|
||||
The insn_code slot is the enum insn_code that says how to
|
||||
generate an insn for this operation on a particular machine mode.
|
||||
It is CODE_FOR_nothing if there is no such insn on the target machine.
|
||||
|
||||
The `lib_call' slot is the name of the library function that
|
||||
can be used to perform the operation.
|
||||
|
||||
A few optabs, such as move_optab and cmp_optab, are used
|
||||
by special code. */
|
||||
|
||||
/* Everything that uses expr.h needs to define enum insn_code
|
||||
but we don't list it in the Makefile dependencies just for that. */
|
||||
#include "insn-codes.h"
|
||||
|
||||
typedef struct optab
|
||||
{
|
||||
enum rtx_code code;
|
||||
struct {
|
||||
enum insn_code insn_code;
|
||||
char *lib_call;
|
||||
} handlers [NUM_MACHINE_MODES];
|
||||
} * optab;
|
||||
|
||||
/* Given an enum insn_code, access the function to construct
|
||||
the body of that kind of insn. */
|
||||
#define GEN_FCN(CODE) (*insn_gen_function[(int) (CODE)])
|
||||
extern rtx (*insn_gen_function[]) ();
|
||||
|
||||
extern optab add_optab;
|
||||
extern optab sub_optab;
|
||||
extern optab smul_optab; /* Signed multiply */
|
||||
extern optab umul_optab; /* Unsigned multiply */
|
||||
extern optab smul_widen_optab; /* Signed multiply with result
|
||||
one machine mode wider than args */
|
||||
extern optab umul_widen_optab;
|
||||
extern optab sdiv_optab; /* Signed divide */
|
||||
extern optab sdivmod_optab; /* Signed divide-and-remainder in one */
|
||||
extern optab udiv_optab;
|
||||
extern optab udivmod_optab;
|
||||
extern optab smod_optab; /* Signed remainder */
|
||||
extern optab umod_optab;
|
||||
extern optab flodiv_optab; /* Optab for floating divide. */
|
||||
extern optab ftrunc_optab; /* Convert float to integer in float fmt */
|
||||
extern optab and_optab; /* Logical and */
|
||||
extern optab andcb_optab; /* Logical and with complement of 2nd arg */
|
||||
extern optab ior_optab; /* Logical or */
|
||||
extern optab xor_optab; /* Logical xor */
|
||||
extern optab ashl_optab; /* Arithmetic shift left */
|
||||
extern optab ashr_optab; /* Arithmetic shift right */
|
||||
extern optab lshl_optab; /* Logical shift left */
|
||||
extern optab lshr_optab; /* Logical shift right */
|
||||
extern optab rotl_optab; /* Rotate left */
|
||||
extern optab rotr_optab; /* Rotate right */
|
||||
|
||||
extern optab mov_optab; /* Move instruction. */
|
||||
extern optab movstrict_optab; /* Move, preserving high part of register. */
|
||||
|
||||
extern optab cmp_optab; /* Compare insn; two operands. */
|
||||
extern optab tst_optab; /* tst insn; compare one operand against 0 */
|
||||
|
||||
/* Unary operations */
|
||||
extern optab neg_optab; /* Negation */
|
||||
extern optab abs_optab; /* Abs value */
|
||||
extern optab one_cmpl_optab; /* Bitwise not */
|
||||
extern optab ffs_optab; /* Find first bit set */
|
||||
|
||||
/* Passed to expand_binop and expand_unop to say which options to try to use
|
||||
if the requested operation can't be open-coded on the requisite mode.
|
||||
Either OPTAB_LIB or OPTAB_LIB_WIDEN says try using a library call.
|
||||
Either OPTAB_WIDEN or OPTAB_LIB_WIDEN says try using a wider mode.
|
||||
OPTAB_MUST_WIDEN says try widening and don't try anything else. */
|
||||
|
||||
enum optab_methods
|
||||
{
|
||||
OPTAB_DIRECT,
|
||||
OPTAB_LIB,
|
||||
OPTAB_WIDEN,
|
||||
OPTAB_LIB_WIDEN,
|
||||
OPTAB_MUST_WIDEN
|
||||
};
|
||||
|
||||
typedef rtx (*rtxfun) ();
|
||||
|
||||
/* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
|
||||
gives the gen_function to make a branch to test that condition. */
|
||||
|
||||
extern rtxfun bcc_gen_fctn[NUM_RTX_CODE];
|
||||
|
||||
/* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
|
||||
gives the gen_function to make a store-condition insn
|
||||
to test that condition. */
|
||||
|
||||
extern rtxfun setcc_gen_fctn[NUM_RTX_CODE];
|
||||
|
||||
/* Expand a binary operation given optab and rtx operands. */
|
||||
rtx expand_binop ();
|
||||
|
||||
/* Expand a binary operation with both signed and unsigned forms. */
|
||||
rtx sign_expand_binop ();
|
||||
|
||||
/* Expand a unary arithmetic operation given optab rtx operand. */
|
||||
rtx expand_unop ();
|
||||
|
||||
/* Arguments MODE, RTX: return an rtx for the negation of that value.
|
||||
May emit insns. */
|
||||
rtx negate_rtx ();
|
||||
|
||||
/* Initialize the tables that control conversion between fixed and
|
||||
floating values. */
|
||||
void init_fixtab ();
|
||||
void init_floattab ();
|
||||
|
||||
/* Generate code for a FIX_EXPR. */
|
||||
void expand_fix ();
|
||||
|
||||
/* Generate code for a FLOAT_EXPR. */
|
||||
void expand_float ();
|
||||
|
||||
/* Create but don't emit one rtl instruction to add one rtx into another.
|
||||
Modes must match.
|
||||
Likewise for subtraction and for just copying.
|
||||
These do not call protect_from_queue; caller must do so. */
|
||||
rtx gen_add2_insn ();
|
||||
rtx gen_sub2_insn ();
|
||||
rtx gen_move_insn ();
|
||||
|
||||
/* Emit one rtl instruction to store zero in specified rtx. */
|
||||
void emit_clr_insn ();
|
||||
|
||||
/* Emit one rtl insn to store 1 in specified rtx assuming it contains 0. */
|
||||
void emit_0_to_1_insn ();
|
||||
|
||||
/* Emit one rtl insn to compare two rtx's. */
|
||||
void emit_cmp_insn ();
|
||||
|
||||
/* Emit some rtl insns to move data between rtx's, converting machine modes.
|
||||
Both modes must be floating or both fixed. */
|
||||
void convert_move ();
|
||||
|
||||
/* Convert an rtx to specified machine mode and return the result. */
|
||||
rtx convert_to_mode ();
|
||||
|
||||
/* Emit code to push some arguments and call a library routine,
|
||||
storing the value in a specified place. Calling sequence is
|
||||
complicated. */
|
||||
void emit_library_call ();
|
||||
|
||||
/* Given an rtx that may include add and multiply operations,
|
||||
generate them as insns and return a pseudo-reg containing the value.
|
||||
Useful after calling expand_expr with 1 as sum_ok. */
|
||||
rtx force_operand ();
|
||||
|
||||
/* Return an rtx for the size in bytes of the value of an expr. */
|
||||
rtx expr_size ();
|
||||
|
||||
/* Return an rtx for the sum of an rtx and an integer. */
|
||||
rtx plus_constant ();
|
||||
|
||||
rtx lookup_static_chain ();
|
||||
|
||||
/* Return an rtx like arg but sans any constant terms.
|
||||
Returns the original rtx if it has no constant terms.
|
||||
The constant terms are added and stored via a second arg. */
|
||||
rtx eliminate_constant_term ();
|
||||
|
||||
/* Convert arg to a valid memory address for specified machine mode,
|
||||
by emitting insns to perform arithmetic if nec. */
|
||||
rtx memory_address ();
|
||||
|
||||
/* Like `memory_address' but pretent `flag_force_addr' is 0. */
|
||||
rtx memory_address_noforce ();
|
||||
|
||||
/* Return a memory reference like MEMREF, but with its mode changed
|
||||
to MODE and its address changed to ADDR.
|
||||
(VOIDmode means don't change the mode.
|
||||
NULL for ADDR means don't change the address.) */
|
||||
rtx change_address ();
|
||||
|
||||
/* Return 1 if two rtx's are equivalent in structure and elements. */
|
||||
int rtx_equal_p ();
|
||||
|
||||
/* Given rtx, return new rtx whose address won't be affected by
|
||||
any side effects. It has been copied to a new temporary reg. */
|
||||
rtx stabilize ();
|
||||
|
||||
/* Given an rtx, copy all regs it refers to into new temps
|
||||
and return a modified copy that refers to the new temps. */
|
||||
rtx copy_all_regs ();
|
||||
|
||||
/* Copy given rtx to a new temp reg and return that. */
|
||||
rtx copy_to_reg ();
|
||||
|
||||
/* Like copy_to_reg but always make the reg Pmode. */
|
||||
rtx copy_addr_to_reg ();
|
||||
|
||||
/* Like copy_to_reg but always make the reg the specified mode MODE. */
|
||||
rtx copy_to_mode_reg ();
|
||||
|
||||
/* Copy given rtx to given temp reg and return that. */
|
||||
rtx copy_to_suggested_reg ();
|
||||
|
||||
/* Copy a value to a register if it isn't already a register.
|
||||
Args are mode (in case value is a constant) and the value. */
|
||||
rtx force_reg ();
|
||||
|
||||
/* Return given rtx, copied into a new temp reg if it was in memory. */
|
||||
rtx force_not_mem ();
|
||||
|
||||
/* Remove some bytes from the stack. An rtx says how many. */
|
||||
void adjust_stack ();
|
||||
|
||||
/* Add some bytes to the stack. An rtx says how many. */
|
||||
void anti_adjust_stack ();
|
||||
|
||||
/* Emit code to copy function value to a new temp reg and return that reg. */
|
||||
rtx function_value ();
|
||||
|
||||
/* Return an rtx that refers to the value returned by a function
|
||||
in its original home. This becomes invalid if any more code is emitted. */
|
||||
rtx hard_function_value ();
|
||||
|
||||
/* Return an rtx that refers to the value returned by a library call
|
||||
in its original home. This becomes invalid if any more code is emitted. */
|
||||
rtx hard_libcall_value ();
|
||||
|
||||
/* Emit code to copy function value to a specified place. */
|
||||
void copy_function_value ();
|
||||
|
||||
/* Given an rtx, return an rtx for a value rounded up to a multiple
|
||||
of STACK_BOUNDARY / BITS_PER_UNIT. */
|
||||
rtx round_push ();
|
||||
|
||||
rtx store_bit_field ();
|
||||
rtx extract_bit_field ();
|
||||
rtx expand_shift ();
|
||||
rtx expand_bit_and ();
|
||||
rtx expand_mult ();
|
||||
rtx expand_divmod ();
|
||||
rtx expand_mult_add ();
|
||||
rtx get_structure_value_addr ();
|
||||
rtx expand_stmt_expr ();
|
||||
|
||||
void jumpifnot ();
|
||||
void jumpif ();
|
||||
void do_jump ();
|
||||
|
||||
rtx assemble_static_space ();
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,109 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# NAME:
|
||||
# fixcpp - fix CPP errors
|
||||
#
|
||||
# SYNOPSIS:
|
||||
# fixcpp [-c][-p patch_file][-b bak_dir][-n new_dir] files(s)
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# For each named file, use sed(1) to fixup any descriptive
|
||||
# text after #else or #endif or that is not properly
|
||||
# commented as this causes ANSI compilers to generate
|
||||
# unnecessary warnings.
|
||||
#
|
||||
# Naturally this script is not guaranteed to be bullit
|
||||
# proof, use of -n or -b is advisable!
|
||||
#
|
||||
# -c causes fixcpp to make sure that only files that
|
||||
# needed changing are affected by returning the original
|
||||
# file to its original location if no changes were needed.
|
||||
#
|
||||
# -p causes fixcpp to append to a patch file the context
|
||||
# diffs of the changes wraught.
|
||||
#
|
||||
# SEE ALSO:
|
||||
# sed(1)
|
||||
#
|
||||
# AMENDED:
|
||||
# 90/08/08 22:46:32 (sjg)
|
||||
#
|
||||
# RELEASED:
|
||||
# 90/08/08 22:46:34 v1.4
|
||||
#
|
||||
# SCCSID:
|
||||
# @(#)fixcpp.sh 1.4 90/08/08 22:46:32 (sjg)
|
||||
#
|
||||
# @(#)Copyright (c) 1990 Simon J. Gerraty
|
||||
#
|
||||
# This is free software. It comes with NO WARRANTY.
|
||||
# Everyone is granted permission to copy, modify and
|
||||
# redistribute this source code provided that all
|
||||
# recipients are given similar rights, and that the above
|
||||
# copyright notice and this notice are preserved in all
|
||||
# copies.
|
||||
|
||||
TMPF=/tmp/fixcpp.$$
|
||||
NEWDIR=
|
||||
BAKDIR=
|
||||
PATCHF=
|
||||
CHECK=
|
||||
|
||||
set -- `getopt "cp:b:n:" $*`
|
||||
if [ $? != 0 ]; then
|
||||
echo "$0 [-c][-p patch_file][-b bakup_dir][-n new_dir] file [file ...]" >&2
|
||||
exit 1
|
||||
fi
|
||||
for i in $*
|
||||
do
|
||||
case $i in
|
||||
-c) CHECK=yes; shift;;
|
||||
-p) PATCHF=$2; shift 2;;
|
||||
-b) BAKDIR=$2; shift 2;;
|
||||
-n) NEWDIR=$2; shift 2;;
|
||||
--) shift; break;;
|
||||
esac
|
||||
done
|
||||
NEWDIR=${NEWDIR:-.}
|
||||
if [ $BAKDIR ]; then
|
||||
if [ ! -d $BAKDIR ]; then
|
||||
echo "$0: no such directory -- $BAKDIR" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
|
||||
for i in $*
|
||||
do
|
||||
if [ $BAKDIR ]; then
|
||||
mv $i $BAKDIR
|
||||
infile=$BAKDIR/$i
|
||||
else
|
||||
if [ "$NEWDIR" = "." ]; then
|
||||
mv $i ${TMPF}
|
||||
infile=${TMPF}
|
||||
else
|
||||
infile=$i
|
||||
fi
|
||||
fi
|
||||
sed -e 's;^#\([ ]*e[nl][^ ]*[ ][ ]*\)\([^/ ][^\*].*\);#\1/* \2 */;' -e 's;^#\([ ]*e[nl][^ ]*[ ][ ]*\)\([^/ ]\)$;#\1/* \2 */;' $infile >${NEWDIR}/$i
|
||||
if [ "${CHECK}" = "yes" -o ${PATCHF} ]; then
|
||||
if cmp -s $infile ${NEWDIR}/$i ; then
|
||||
if [ "${CHECK}" = "yes" ]; then
|
||||
if [ $BAKDIR ]; then
|
||||
mv $infile ${NEWDIR}/$i
|
||||
else
|
||||
rm ${NEWDIR}/$i
|
||||
fi
|
||||
fi
|
||||
else
|
||||
if [ $PATCHF ]; then
|
||||
diff -c $infile ${NEWDIR}/$i >> ${PATCHF}
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
rm -f ${TMPF}
|
|
@ -0,0 +1,481 @@
|
|||
#! /bin/sh
|
||||
# Install modified versions of certain ANSI-incompatible system header files
|
||||
# which are fixed to work correctly with ANSI C
|
||||
# and placed in a directory that GNU C will search.
|
||||
# This works properly on a Sun in system version 3.4;
|
||||
# for other versions, you had better check.
|
||||
|
||||
# Directory containing the original header files.
|
||||
INCLUDES=${2-${INCLUDES-/usr/include}}
|
||||
|
||||
# Directory in which to store the results.
|
||||
LIB=${LIB-/usr/local/lib/gcc-include}
|
||||
|
||||
# Make sure it exists.
|
||||
if [ ! -d $LIB ]; then
|
||||
mkdir $LIB || exit 1
|
||||
fi
|
||||
|
||||
# Determine whether this system has symbolic links.
|
||||
if ln -s X $LIB/ShouldNotExist 2>/dev/null; then
|
||||
rm -f $LIB/ShouldNotExist
|
||||
LINKS=true
|
||||
else
|
||||
LINKS=false
|
||||
fi
|
||||
|
||||
echo Finding directories and links to directories
|
||||
cd ${INCLUDES}
|
||||
# Find all directories and all symlinks that point to directories.
|
||||
# Put the list in $files.
|
||||
# Each time we find a symlink, add it to newdirs
|
||||
# so that we do another find within the dir the link points to.
|
||||
# Note that $files may have duplicates in it;
|
||||
# later parts of this file are supposed to ignore them.
|
||||
dirs="."
|
||||
levels=2
|
||||
while [ -n "$dirs" ] && [ $levels -gt 0 ]
|
||||
do
|
||||
levels=`expr $levels - 1`
|
||||
newdirs=
|
||||
for d in $dirs
|
||||
do
|
||||
echo " Searching $INCLUDES/$d"
|
||||
if [ "$d" != . ]
|
||||
then
|
||||
d=$d/.
|
||||
fi
|
||||
|
||||
# Find all directories under $d, relative to $d, excluding $d itself.
|
||||
files="$files `find $d -type d -print | \
|
||||
sed -e '/\/\.$/d' -e '/^\.$/d'`"
|
||||
# Find all links to directories.
|
||||
# Using `-exec test -d' in find fails on some systems,
|
||||
# and trying to run test via sh fails on others,
|
||||
# so this is the simplest alternative left.
|
||||
# First find all the links, then test each one.
|
||||
theselinks=
|
||||
$LINKS && \
|
||||
theselinks=`find $d -type l -print`
|
||||
for d1 in $theselinks --dummy--
|
||||
do
|
||||
# If the link points to a directory,
|
||||
# add that dir to $newdirs
|
||||
if [ -d $d1 ]
|
||||
then
|
||||
newdirs="$newdirs $d1"
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
files="$files $newdirs"
|
||||
dirs="$newdirs"
|
||||
done
|
||||
|
||||
dirs=
|
||||
echo "All directories (including links to directories):"
|
||||
echo $files
|
||||
|
||||
for file in $files; do
|
||||
rm -rf $LIB/$file
|
||||
if [ ! -d $LIB/$file ]
|
||||
then mkdir $LIB/$file
|
||||
fi
|
||||
done
|
||||
mkdir $LIB/root
|
||||
|
||||
# treetops gets an alternating list
|
||||
# of old directories to copy
|
||||
# and the new directories to copy to.
|
||||
treetops="${INCLUDES} ${LIB}"
|
||||
|
||||
if $LINKS; then
|
||||
echo 'Making symbolic directory links'
|
||||
for file in $files; do
|
||||
dest=`ls -ld $file | sed -n 's/.*-> //p'`
|
||||
if [ "$dest" ]; then
|
||||
cwd=`pwd`
|
||||
# In case $dest is relative, get to $file's dir first.
|
||||
cd ${INCLUDES}
|
||||
cd `echo ./$file | sed -n 's&[^/]*$&&p'`
|
||||
# Check that the target directory exists.
|
||||
# Redirections changed to avoid bug in sh on Ultrix.
|
||||
(cd $dest) > /dev/null 2>&1
|
||||
if [ $? = 0 ]; then
|
||||
cd $dest
|
||||
# X gets the dir that the link actually leads to.
|
||||
x=`pwd`
|
||||
# If a link points to ., make a similar link to .
|
||||
if [ $x = $INCLUDES ]; then
|
||||
echo $file '->' . ': Making link'
|
||||
rm -fr ${LIB}/$file > /dev/null 2>&1
|
||||
ln -s . ${LIB}/$file > /dev/null 2>&1
|
||||
# If link leads back into ${INCLUDES},
|
||||
# make a similar link here.
|
||||
elif expr $x : "${INCLUDES}/.*" > /dev/null; then
|
||||
# Y gets the actual target dir name, relative to ${INCLUDES}.
|
||||
y=`echo $x | sed -n "s&${INCLUDES}/&&p"`
|
||||
echo $file '->' $y ': Making link'
|
||||
rm -fr ${LIB}/$file > /dev/null 2>&1
|
||||
ln -s ${LIB}/$y ${LIB}/$file > /dev/null 2>&1
|
||||
else
|
||||
# If the link is to a dir $target outside ${INCLUDES},
|
||||
# repoint the link at ${INCLUDES}/root$target
|
||||
# and process $target into ${INCLUDES}/root$target
|
||||
# treat this directory as if it actually contained the files.
|
||||
echo $file '->' root$x ': Making link'
|
||||
if [ -d $LIB/root$x ]
|
||||
then true
|
||||
else
|
||||
dirname=root$x/
|
||||
dirmade=.
|
||||
cd $LIB
|
||||
while [ x$dirname != x ]; do
|
||||
component=`echo $dirname | sed -e 's|/.*$||'`
|
||||
mkdir $component >/dev/null 2>&1
|
||||
cd $component
|
||||
dirmade=$dirmade/$component
|
||||
dirname=`echo $dirname | sed -e 's|[^/]*/||'`
|
||||
done
|
||||
fi
|
||||
rm -fr ${LIB}/$file > /dev/null 2>&1
|
||||
ln -s ${LIB}/root$x ${LIB}/$file > /dev/null 2>&1
|
||||
treetops="$treetops $x ${LIB}/root$x"
|
||||
fi
|
||||
fi
|
||||
cd $cwd
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
set - $treetops
|
||||
while [ $# != 0 ]; do
|
||||
# $1 is an old directory to copy, and $2 is the new directory to copy to.
|
||||
cd ${INCLUDES}
|
||||
cd $1
|
||||
# The same dir can appear more than once in treetops.
|
||||
# There's no need to scan it more than once.
|
||||
if [ -f $2/DONE ]
|
||||
then
|
||||
files=
|
||||
else
|
||||
touch $2/DONE
|
||||
echo Fixing directory $1 into $2
|
||||
# Check .h files which are symlinks as well as those which are files.
|
||||
# A link to a header file will not be processed by anything but this.
|
||||
if $LINKS; then
|
||||
files=`find . -name '*.h' \( -type f -o -type l \) -print`
|
||||
else
|
||||
files=`find . -name '*.h' -type f -print`
|
||||
fi
|
||||
echo Checking header files
|
||||
fi
|
||||
# Note that BSD43_* are used on recent MIPS systems.
|
||||
for file in $files; do
|
||||
# This call to egrep is essential, since checking a file with egrep
|
||||
# is much faster than actually trying to fix it.
|
||||
# It is also essential that most files *not* match!
|
||||
# Thus, matching every #endif is unacceptable.
|
||||
# But the argument to egrep must be kept small, or many versions of egrep
|
||||
# won't be able to handle it.
|
||||
# rms: I removed `|#[el].*if.*[^/ ]' because it made egrep fail.
|
||||
if egrep '[ _]_IO|CTRL|#define.NULL|#[el]*if.*([0-9]|sparc|vax|sun|pyr)' $file > /dev/null; then
|
||||
echo Fixing $file
|
||||
if [ -r $file ]; then
|
||||
cp $file $2/$file >/dev/null 2>&1 \
|
||||
|| echo "Can't copy $file"
|
||||
chmod +w $2/$file
|
||||
# Following two lines removed.
|
||||
# s%^\([ ]*#[ ]*endif[ ]*\)\([^/ ].*\)$%\1/* \2 */%
|
||||
# s%^\([ ]*#[ ]*else[ ]*\)\([^/ ].*\)$%\1/* \2 */%
|
||||
|
||||
sed -e '
|
||||
:loop
|
||||
/\\$/ N
|
||||
/\\$/ b loop
|
||||
/[ ]_IO[A-Z]*[ ]*(/ s/(\(.\),/('\''\1'\'',/
|
||||
/[ ]BSD43__IO[A-Z]*[ ]*(/ s/(\(.\),/('\''\1'\'',/
|
||||
/#define._IO/ s/'\''x'\''/x/g
|
||||
/#define.BSD43__IO/ s/'\''x'\''/x/g
|
||||
/[^A-Z]CTRL[ ]*(/ s/\([^'\'']\))/'\''\1'\'')/
|
||||
/#define.CTRL/ s/'\''c'\''/c/g
|
||||
/#define._CTRL/ s/'\''c'\''/c/g
|
||||
/#define.BSD43_CTRL/ s/'\''c'\''/c/g
|
||||
/#if.* m68k$/ s/m68k/__m68k__/g
|
||||
/#if.*defined *(m68k)/ s/m68k/__m68k__/g
|
||||
' $2/$file > $2/$file.sed
|
||||
mv $2/$file.sed $2/$file
|
||||
if cmp $file $2/$file >/dev/null 2>&1; then
|
||||
echo Deleting $2/$file\; no fixes were needed.
|
||||
rm $2/$file
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
shift; shift
|
||||
done
|
||||
|
||||
cd ${INCLUDES}
|
||||
|
||||
# Fix one other error in this file: a mismatched quote not inside a C comment.
|
||||
file=sundev/vuid_event.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
cp $file ${LIB}/$file >/dev/null 2>&1 \
|
||||
|| echo "Can't copy $file"
|
||||
chmod +w ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -r ${LIB}/$file ]; then
|
||||
echo Fixing $file comment
|
||||
ex ${LIB}/$file <<EOF
|
||||
g/doesn't/s/doesn't/does not/
|
||||
wq
|
||||
EOF
|
||||
if cmp $file ${LIB}/$file >/dev/null 2>&1; then
|
||||
echo Deleting ${LIB}/$file\; no fixes were needed.
|
||||
rm ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fix this Sun file to avoid intefering with stddef.h.
|
||||
|
||||
file=sys/stdtypes.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
cp $file ${LIB}/$file >/dev/null 2>&1 \
|
||||
|| echo "Can't copy $file"
|
||||
chmod +w ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -r ${LIB}/$file ]; then
|
||||
echo Fixing $file comment
|
||||
ex ${LIB}/$file <<EOF
|
||||
/size_t.*;/
|
||||
i
|
||||
#ifndef _SIZE_T
|
||||
#define _SIZE_T
|
||||
.
|
||||
/size_t/+1
|
||||
i
|
||||
#endif
|
||||
.
|
||||
/ptrdiff_t.*;/
|
||||
i
|
||||
#ifndef _PTRDIFF_T
|
||||
#define _PTRDIFF_T
|
||||
.
|
||||
/ptrdiff_t/+1
|
||||
i
|
||||
#endif
|
||||
.
|
||||
/wchar_t.*;/
|
||||
i
|
||||
#ifndef _WCHAR_T
|
||||
#define _WCHAR_T
|
||||
.
|
||||
/wchar_t/+1
|
||||
i
|
||||
#endif
|
||||
.
|
||||
wq
|
||||
EOF
|
||||
if cmp $file ${LIB}/$file >/dev/null 2>&1; then
|
||||
echo Deleting ${LIB}/$file\; no fixes were needed.
|
||||
rm ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fix an error in this file: a missing semi-colon at the end of the statsswtch
|
||||
# structure definition.
|
||||
file=rpcsvc/rstat.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
cp $file ${LIB}/$file >/dev/null 2>&1 \
|
||||
|| echo "Can't copy $file"
|
||||
chmod +w ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -r ${LIB}/$file ]; then
|
||||
echo Fixing $file, definition of statsswtch
|
||||
ex ${LIB}/$file <<EOF
|
||||
g/boottime$/s//&;/
|
||||
wq
|
||||
EOF
|
||||
if cmp $file ${LIB}/$file >/dev/null 2>&1; then
|
||||
echo Deleting ${LIB}/$file\; no fixes were needed.
|
||||
rm ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fix an error in this file: a missing semi-colon at the end of the nodeent
|
||||
# structure definition.
|
||||
file=netdnet/dnetdb.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
cp $file ${LIB}/$file >/dev/null 2>&1 \
|
||||
|| echo "Can't copy $file"
|
||||
chmod +w ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -r ${LIB}/$file ]; then
|
||||
echo Fixing $file, definition of nodeent
|
||||
ex ${LIB}/$file <<EOF
|
||||
g/na_addr/s//&;/
|
||||
wq
|
||||
EOF
|
||||
if cmp $file ${LIB}/$file >/dev/null 2>&1; then
|
||||
echo Deleting ${LIB}/$file\; no fixes were needed.
|
||||
rm ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for bad #ifdef line (in Ultrix 4.1)
|
||||
|
||||
file=sys/file.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
mkdir ${LIB}/rpcsvc 2>&-
|
||||
cp $file ${LIB}/$file >/dev/null 2>&1 \
|
||||
|| echo "Can't copy $file"
|
||||
chmod +w ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -r ${LIB}/$file ]; then
|
||||
echo Fixing $file, bad \#ifdef line
|
||||
ex ${LIB}/$file <<EOF
|
||||
g/^#ifdef KERNEL && !defined/
|
||||
s/#ifdef KERNEL && !defined/#if defined(KERNEL) \&\& !defined/
|
||||
wq
|
||||
EOF
|
||||
if cmp $file ${LIB}/$file >/dev/null 2>&1; then
|
||||
echo Deleting ${LIB}/$file\; no fixes were needed.
|
||||
rm ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for superfluous `static' (in Ultrix 4.2)
|
||||
|
||||
file=machine/cpu.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
mkdir ${LIB}/machine 2>&-
|
||||
cp $file ${LIB}/$file >/dev/null 2>&1 \
|
||||
|| echo "Can't copy $file"
|
||||
chmod +w ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -r ${LIB}/$file ]; then
|
||||
echo Fixing $file, superfluous static
|
||||
ex ${LIB}/$file <<EOF
|
||||
g/^static struct tlb_pid_state/
|
||||
s/static//
|
||||
wq
|
||||
EOF
|
||||
if cmp $file ${LIB}/$file >/dev/null 2>&1; then
|
||||
echo Deleting ${LIB}/$file\; no fixes were needed.
|
||||
rm ${LIB}/$file
|
||||
else
|
||||
# This file has an alternative name, mips/cpu.h. Fix that name, too.
|
||||
if cmp machine/cpu.h mips/cpu.h > /dev/null 2>& 1; then
|
||||
mkdir ${LIB}/mips 2>&-
|
||||
ln ${LIB}/$file ${LIB}/mips/cpu.h
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Deal with yet another challenge, this in X11/Xmu.h
|
||||
file=X11/Xmu.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
mkdir ${LIB}/X11 2>&-
|
||||
cp $file ${LIB}/$file >/dev/null 2>&1 \
|
||||
|| echo "Can't copy $file"
|
||||
chmod +w ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -r ${LIB}/$file ]; then
|
||||
echo Fixing $file sprintf declaration
|
||||
ex ${LIB}/$file <<EOF
|
||||
/^extern char \* sprintf();$/c
|
||||
#ifndef __STDC__
|
||||
extern char * sprintf();
|
||||
#endif /* !defined __STDC__ */
|
||||
.
|
||||
wq
|
||||
EOF
|
||||
if cmp $file ${LIB}/$file >/dev/null 2>&1; then
|
||||
echo Deleting ${LIB}/$file\; no fixes were needed.
|
||||
rm ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for missing ';' in struct
|
||||
|
||||
file=netinet/ip.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
mkdir ${LIB}/netinet 2>&-
|
||||
sed -e '/^struct/,/^};/s/}$/};/' $file > ${LIB}/$file
|
||||
cmp $file ${LIB}/$file >/dev/null 2>&1 && rm -f ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fix the CAT macro in memvar.h.
|
||||
|
||||
file=pixrect/memvar.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
mkdir ${LIB}/pixrect 2>&-
|
||||
sed -e '/^#define.CAT(a,b)/ i\
|
||||
#ifdef __STDC__ \
|
||||
#define CAT(a,b) a##b\
|
||||
#else
|
||||
/^#define.CAT(a,b)/ a\
|
||||
#endif
|
||||
' $file > ${LIB}/$file
|
||||
cmp $file ${LIB}/$file >/dev/null 2>&1 && rm -f ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for yet more missing ';' in struct (in SunOS 4.0.x)
|
||||
|
||||
file=rpcsvc/rusers.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
mkdir ${LIB}/rpcsvc 2>&-
|
||||
sed -e '/^struct/,/^};/s/_cnt$/_cnt;/' $file > ${LIB}/$file
|
||||
cmp $file ${LIB}/$file >/dev/null 2>&1 && rm -f ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
echo 'Removing unneeded directories:'
|
||||
cd $LIB
|
||||
files=`find . -type d -print | sort -r`
|
||||
for file in $files; do
|
||||
rmdir $LIB/$file > /dev/null 2>&1
|
||||
done
|
||||
|
||||
if $LINKS; then
|
||||
echo 'Making internal symbolic non-directory links'
|
||||
cd ${INCLUDES}
|
||||
files=`find . -type l -print`
|
||||
for file in $files; do
|
||||
dest=`ls -ld $file | sed -n 's/.*-> //p'`
|
||||
if expr "$dest" : '[^/].*' > /dev/null; then
|
||||
target=${LIB}/`echo file | sed "s|[^/]*\$|$dest|"`
|
||||
if [ -f $target ]; then
|
||||
ln -s $dest ${LIB}/$file >/dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,389 @@
|
|||
#! /bin/sh
|
||||
# Install modified versions of certain ANSI-incompatible system header files
|
||||
# which are fixed to work correctly with ANSI C
|
||||
# and placed in a directory that GNU C will search.
|
||||
# This works properly on a Sun in system version 3.4;
|
||||
# for other versions, you had better check.
|
||||
|
||||
# Directory containing the original header files.
|
||||
INCLUDES=${2-${INCLUDES-/usr/include}}
|
||||
|
||||
# Directory in which to store the results.
|
||||
LIB=${LIB-/usr/local/lib/gcc-include}
|
||||
|
||||
# Make sure it exists.
|
||||
if [ ! -d $LIB ]; then
|
||||
mkdir $LIB || exit 1
|
||||
fi
|
||||
|
||||
# Determine whether this system has symbolic links.
|
||||
if ln -s X $LIB/ShouldNotExist 2>/dev/null; then
|
||||
rm -f $LIB/ShouldNotExist
|
||||
LINKS=true
|
||||
else
|
||||
LINKS=false
|
||||
fi
|
||||
|
||||
echo 'Making directories:'
|
||||
cd ${INCLUDES}
|
||||
if $LINKS; then
|
||||
files=`ls -LR | sed -n s/:$//p`
|
||||
else
|
||||
files=`find . -type d -print | sed '/^.$/d'`
|
||||
fi
|
||||
for file in $files; do
|
||||
rm -rf $LIB/$file
|
||||
if [ ! -d $LIB/$file ]
|
||||
then mkdir $LIB/$file
|
||||
fi
|
||||
done
|
||||
|
||||
# treetops gets an alternating list
|
||||
# of old directories to copy
|
||||
# and the new directories to copy to.
|
||||
treetops="${INCLUDES} ${LIB}"
|
||||
|
||||
if $LINKS; then
|
||||
echo 'Making internal symbolic directory links'
|
||||
for file in $files; do
|
||||
dest=`ls -ld $file | sed -n 's/.*-> //p'`
|
||||
if [ "$dest" ]; then
|
||||
cwd=`pwd`
|
||||
# In case $dest is relative, get to $file's dir first.
|
||||
cd ${INCLUDES}
|
||||
cd `echo ./$file | sed -n 's&[^/]*$&&p'`
|
||||
# Check that the target directory exists.
|
||||
# Redirections changed to avoid bug in sh on Ultrix.
|
||||
(cd $dest) > /dev/null 2>&1
|
||||
if [ $? = 0 ]; then
|
||||
cd $dest
|
||||
# X gets the dir that the link actually leads to.
|
||||
x=`pwd`
|
||||
# If link leads back into ${INCLUDES},
|
||||
# make a similar link here.
|
||||
if expr $x : '${INCLUDES}/.*' > /dev/null; then
|
||||
# Y gets the actual target dir name, relative to ${INCLUDES}.
|
||||
y=`echo $x | sed -n 's&${INCLUDES}/&&p'`
|
||||
echo $file '->' $y ': Making link'
|
||||
rm -fr ${LIB}/$file > /dev/null 2>&1
|
||||
ln -s ${LIB}/$y ${LIB}/$file > /dev/null 2>&1
|
||||
else
|
||||
# If the link is to outside ${INCLUDES},
|
||||
# treat this directory as if it actually contained the files.
|
||||
# This line used to have $dest instead of $x.
|
||||
# $dest seemed to be wrong for links found in subdirectories
|
||||
# of ${INCLUDES}. Does this change break anything?
|
||||
treetops="$treetops $x ${LIB}/$file"
|
||||
fi
|
||||
fi
|
||||
cd $cwd
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
set - $treetops
|
||||
while [ $# != 0 ]; do
|
||||
# $1 is an old directory to copy, and $2 is the new directory to copy to.
|
||||
echo "Finding header files in $1:"
|
||||
cd ${INCLUDES}
|
||||
cd $1
|
||||
files=`find . -name '*.h' -type f -print`
|
||||
echo 'Checking header files:'
|
||||
# Note that BSD43_* are used on recent MIPS systems.
|
||||
for file in $files; do
|
||||
if egrep '[ ]_IO[A-Z]*\(|[ ]BSD43__IO[A-Z]*\(|#define._IO|#define.BSD43__IO|CTRL' $file > /dev/null; then
|
||||
echo Fixing $file
|
||||
if [ -r $file ]; then
|
||||
cp $file $2/$file >/dev/null 2>&1 \
|
||||
|| echo "Can't copy $file"
|
||||
chmod +w $2/$file
|
||||
sed -e '
|
||||
:loop
|
||||
/\\$/ N
|
||||
/\\$/ b loop
|
||||
/[ ]_IO[A-Z]*[ ]*(/ s/(\(.\),/('\''\1'\'',/
|
||||
/[ ]BSD43__IO[A-Z]*[ ]*(/ s/(\(.\),/('\''\1'\'',/
|
||||
/#define._IO/ s/'\''x'\''/x/g
|
||||
/#define.BSD43__IO/ s/'\''x'\''/x/g
|
||||
/[^A-Z]CTRL[ ]*(/ s/\([^'\'']\))/'\''\1'\'')/
|
||||
/#define.CTRL/ s/'\''c'\''/c/g
|
||||
/#define._CTRL/ s/'\''c'\''/c/g
|
||||
/#define.BSD43_CTRL/ s/'\''c'\''/c/g
|
||||
/#if.* m68k$/ s/m68k/__m68k__/g
|
||||
/#if.*defined *(m68k)/ s/m68k/__m68k__/g
|
||||
' $2/$file > $2/$file.sed
|
||||
mv $2/$file.sed $2/$file
|
||||
if cmp $file $2/$file >/dev/null 2>&1; then
|
||||
echo Deleting $2/$file\; no fixes were needed.
|
||||
rm $2/$file
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
shift; shift
|
||||
done
|
||||
|
||||
cd ${INCLUDES}
|
||||
|
||||
# Fix one other error in this file: a mismatched quote not inside a C comment.
|
||||
file=sundev/vuid_event.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
cp $file ${LIB}/$file >/dev/null 2>&1 \
|
||||
|| echo "Can't copy $file"
|
||||
chmod +w ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -r ${LIB}/$file ]; then
|
||||
echo Fixing $file comment
|
||||
ex ${LIB}/$file <<EOF
|
||||
g/doesn't/s/doesn't/does not/
|
||||
wq
|
||||
EOF
|
||||
if cmp $file ${LIB}/$file >/dev/null 2>&1; then
|
||||
echo Deleting ${LIB}/$file\; no fixes were needed.
|
||||
rm ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fix this Sun file to avoid intefering with stddef.h.
|
||||
|
||||
file=sys/stdtypes.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
cp $file ${LIB}/$file >/dev/null 2>&1 \
|
||||
|| echo "Can't copy $file"
|
||||
chmod +w ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -r ${LIB}/$file ]; then
|
||||
echo Fixing $file comment
|
||||
ex ${LIB}/$file <<EOF
|
||||
/size_t.*;/
|
||||
i
|
||||
#ifndef _SIZE_T
|
||||
#define _SIZE_T
|
||||
.
|
||||
/size_t/+1
|
||||
i
|
||||
#endif
|
||||
.
|
||||
/ptrdiff_t.*;/
|
||||
i
|
||||
#ifndef _PTRDIFF_T
|
||||
#define _PTRDIFF_T
|
||||
.
|
||||
/ptrdiff_t/+1
|
||||
i
|
||||
#endif
|
||||
.
|
||||
/wchar_t.*;/
|
||||
i
|
||||
#ifndef _WCHAR_T
|
||||
#define _WCHAR_T
|
||||
.
|
||||
/wchar_t/+1
|
||||
i
|
||||
#endif
|
||||
.
|
||||
wq
|
||||
EOF
|
||||
if cmp $file ${LIB}/$file >/dev/null 2>&1; then
|
||||
echo Deleting ${LIB}/$file\; no fixes were needed.
|
||||
rm ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fix an error in this file: a missing semi-colon at the end of the statsswtch
|
||||
# structure definition.
|
||||
file=rpcsvc/rstat.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
cp $file ${LIB}/$file >/dev/null 2>&1 \
|
||||
|| echo "Can't copy $file"
|
||||
chmod +w ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -r ${LIB}/$file ]; then
|
||||
echo Fixing $file, definition of statsswtch
|
||||
ex ${LIB}/$file <<EOF
|
||||
g/boottime$/s//&;/
|
||||
wq
|
||||
EOF
|
||||
if cmp $file ${LIB}/$file >/dev/null 2>&1; then
|
||||
echo Deleting ${LIB}/$file\; no fixes were needed.
|
||||
rm ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fix an error in this file: a missing semi-colon at the end of the nodeent
|
||||
# structure definition.
|
||||
file=netdnet/dnetdb.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
cp $file ${LIB}/$file >/dev/null 2>&1 \
|
||||
|| echo "Can't copy $file"
|
||||
chmod +w ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -r ${LIB}/$file ]; then
|
||||
echo Fixing $file, definition of nodeent
|
||||
ex ${LIB}/$file <<EOF
|
||||
g/na_addr/s//&;/
|
||||
wq
|
||||
EOF
|
||||
if cmp $file ${LIB}/$file >/dev/null 2>&1; then
|
||||
echo Deleting ${LIB}/$file\; no fixes were needed.
|
||||
rm ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for bad #ifdef line (in Ultrix 4.1)
|
||||
|
||||
file=sys/file.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
mkdir ${LIB}/rpcsvc 2>&-
|
||||
cp $file ${LIB}/$file >/dev/null 2>&1 \
|
||||
|| echo "Can't copy $file"
|
||||
chmod +w ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -r ${LIB}/$file ]; then
|
||||
echo Fixing $file, bad \#ifdef line
|
||||
ex ${LIB}/$file <<EOF
|
||||
g/^#ifdef KERNEL && !defined/
|
||||
s/#ifdef KERNEL && !defined/#if defined(KERNEL) \&\& !defined/
|
||||
wq
|
||||
EOF
|
||||
if cmp $file ${LIB}/$file >/dev/null 2>&1; then
|
||||
echo Deleting ${LIB}/$file\; no fixes were needed.
|
||||
rm ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for superfluous `static' (in Ultrix 4.2)
|
||||
|
||||
file=machine/cpu.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
mkdir ${LIB}/machine 2>&-
|
||||
cp $file ${LIB}/$file >/dev/null 2>&1 \
|
||||
|| echo "Can't copy $file"
|
||||
chmod +w ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -r ${LIB}/$file ]; then
|
||||
echo Fixing $file, superfluous static
|
||||
ex ${LIB}/$file <<EOF
|
||||
g/^static struct tlb_pid_state/
|
||||
s/static//
|
||||
wq
|
||||
EOF
|
||||
if cmp $file ${LIB}/$file >/dev/null 2>&1; then
|
||||
echo Deleting ${LIB}/$file\; no fixes were needed.
|
||||
rm ${LIB}/$file
|
||||
else
|
||||
# This file has an alternative name, mips/cpu.h. Fix that name, too.
|
||||
if cmp machine/cpu.h mips/cpu.h > /dev/null 2>& 1; then
|
||||
mkdir ${LIB}/mips 2>&-
|
||||
ln ${LIB}/$file ${LIB}/mips/cpu.h
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Deal with yet another challenge, this in X11/Xmu.h
|
||||
file=X11/Xmu.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
mkdir ${LIB}/X11 2>&-
|
||||
cp $file ${LIB}/$file >/dev/null 2>&1 \
|
||||
|| echo "Can't copy $file"
|
||||
chmod +w ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -r ${LIB}/$file ]; then
|
||||
echo Fixing $file sprintf declaration
|
||||
ex ${LIB}/$file <<EOF
|
||||
/^extern char \* sprintf();$/c
|
||||
#ifndef __STDC__
|
||||
extern char * sprintf();
|
||||
#endif /* !defined __STDC__ */
|
||||
.
|
||||
wq
|
||||
EOF
|
||||
if cmp $file ${LIB}/$file >/dev/null 2>&1; then
|
||||
echo Deleting ${LIB}/$file\; no fixes were needed.
|
||||
rm ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for missing ';' in struct
|
||||
|
||||
file=netinet/ip.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
mkdir ${LIB}/netinet 2>&-
|
||||
sed -e '/^struct/,/^};/s/}$/};/' $file > ${LIB}/$file
|
||||
cmp $file ${LIB}/$file >/dev/null 2>&1 && rm -f ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fix the CAT macro in memvar.h.
|
||||
|
||||
file=pixrect/memvar.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
mkdir ${LIB}/pixrect 2>&-
|
||||
sed -e '/^#define.CAT(a,b)/ i\
|
||||
#ifdef __STDC__ \
|
||||
#define CAT(a,b) a##b\
|
||||
#else
|
||||
/^#define.CAT(a,b)/ a\
|
||||
#endif
|
||||
' $file > ${LIB}/$file
|
||||
cmp $file ${LIB}/$file >/dev/null 2>&1 && rm -f ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for yet more missing ';' in struct (in SunOS 4.0.x)
|
||||
|
||||
file=rpcsvc/rusers.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
mkdir ${LIB}/rpcsvc 2>&-
|
||||
sed -e '/^struct/,/^};/s/_cnt$/_cnt;/' $file > ${LIB}/$file
|
||||
cmp $file ${LIB}/$file >/dev/null 2>&1 && rm -f ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
echo 'Removing unneeded directories:'
|
||||
cd $LIB
|
||||
files=`find . -type d -print | sort -r`
|
||||
for file in $files; do
|
||||
rmdir $LIB/$file > /dev/null 2>&1
|
||||
done
|
||||
|
||||
if $LINKS; then
|
||||
echo 'Making internal symbolic non-directory links'
|
||||
cd ${INCLUDES}
|
||||
files=`find . -type l -print`
|
||||
for file in $files; do
|
||||
dest=`ls -ld $file | sed -n 's/.*-> //p'`
|
||||
if expr "$dest" : '[^/].*' > /dev/null; then
|
||||
target=${LIB}/`echo file | sed "s|[^/]*\$|$dest|"`
|
||||
if [ -f $target ]; then
|
||||
ln -s $dest ${LIB}/$file >/dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,261 @@
|
|||
#! /bin/sh
|
||||
# Install modified versions of certain ANSI-incompatible system header files
|
||||
# which are fixed to work correctly with ANSI C
|
||||
# and placed in a directory that GNU C will search.
|
||||
# This works properly on a Sun in system version 3.4;
|
||||
# for other versions, you had better check.
|
||||
|
||||
# Directory in which to store the results.
|
||||
LIB=${LIB-/usr/local/lib/gcc-include}
|
||||
|
||||
# Make sure it exists.
|
||||
if [ ! -d $LIB ]; then
|
||||
mkdir $LIB || exit 1
|
||||
fi
|
||||
|
||||
# Determine whether this system has symbolic links.
|
||||
if ln -s X $LIB/ShouldNotExist 2>/dev/null; then
|
||||
rm -f $LIB/ShouldNotExist
|
||||
LINKS=true
|
||||
else
|
||||
LINKS=false
|
||||
fi
|
||||
|
||||
echo 'Making directories:'
|
||||
cd /usr/include
|
||||
if $LINKS; then
|
||||
files=`ls -LR | sed -n s/:$//p`
|
||||
else
|
||||
files=`find . -type d -print | sed '/^.$/d'`
|
||||
fi
|
||||
for file in $files; do
|
||||
rm -rf $LIB/$file
|
||||
if [ ! -d $LIB/$file ]
|
||||
then mkdir $LIB/$file
|
||||
fi
|
||||
done
|
||||
|
||||
# treetops gets an alternating list
|
||||
# of old directories to copy
|
||||
# and the new directories to copy to.
|
||||
treetops="/usr/include ${LIB}"
|
||||
|
||||
if $LINKS; then
|
||||
echo 'Making internal symbolic directory links'
|
||||
for file in $files; do
|
||||
dest=`ls -ld $file | sed -n 's/.*-> //p'`
|
||||
if [ "$dest" ]; then
|
||||
cwd=`pwd`
|
||||
# In case $dest is relative, get to $file's dir first.
|
||||
cd /usr/include
|
||||
cd `echo ./$file | sed -n 's&[^/]*$&&p'`
|
||||
# Check that the target directory exists.
|
||||
# Redirections changed to avoid bug in sh on Ultrix.
|
||||
(cd $dest) > /dev/null 2>&1
|
||||
if [ $? = 0 ]; then
|
||||
cd $dest
|
||||
# X gets the dir that the link actually leads to.
|
||||
x=`pwd`
|
||||
# If link leads back into /usr/include,
|
||||
# make a similar link here.
|
||||
if expr $x : '/usr/include/.*' > /dev/null; then
|
||||
# Y gets the actual target dir name, relative to /usr/include.
|
||||
y=`echo $x | sed -n 's&/usr/include/&&p'`
|
||||
echo $file '->' $y ': Making link'
|
||||
rm -fr ${LIB}/$file > /dev/null 2>&1
|
||||
ln -s ${LIB}/$y ${LIB}/$file > /dev/null 2>&1
|
||||
else
|
||||
# If the link is to outside /usr/include,
|
||||
# treat this directory as if it actually contained the files.
|
||||
# This line used to have $dest instead of $x.
|
||||
# $dest seemed to be wrong for links found in subdirectories
|
||||
# of /usr/include. Does this change break anything?
|
||||
treetops="$treetops $x ${LIB}/$file"
|
||||
fi
|
||||
fi
|
||||
cd $cwd
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
set - $treetops
|
||||
while [ $# != 0 ]; do
|
||||
# $1 is an old directory to copy, and $2 is the new directory to copy to.
|
||||
echo "Finding header files in $1:"
|
||||
cd /usr/include
|
||||
cd $1
|
||||
files=`find . -name '*.h' -type f -print`
|
||||
echo 'Checking header files:'
|
||||
for file in $files; do
|
||||
if egrep '[ ]_IO[A-Z]*\(|#define._IO|CTRL|#machine|#lint' $file > /dev/null; then
|
||||
echo Fixing $file
|
||||
if [ -r $file ]; then
|
||||
cp $file $2/$file >/dev/null 2>&1 \
|
||||
|| echo "Can't copy $file"
|
||||
chmod +w $2/$file
|
||||
sed -e '
|
||||
:loop
|
||||
/\\$/ N
|
||||
/\\$/ b loop
|
||||
/[ ]_IO[A-Z]*[ ]*(/ s/(\(.\),/('\''\1'\'',/
|
||||
/#define._IO/ s/'\''x'\''/x/g
|
||||
/[^A-Z]CTRL[ ]*(/ s/\([^'\'']\))/'\''\1'\'')/
|
||||
/#define.CTRL/ s/'\''c'\''/c/g
|
||||
/#define._CTRL/ s/'\''c'\''/c/g
|
||||
/^[ ]*#[ ]*if/ s/#machine/defined/g
|
||||
/^[ ]*#[ ]*elif/ s/#machine/defined/g
|
||||
/^[ ]*#[ ]*if/ s/#lint *(on)/defined(lint)/g
|
||||
/^[ ]*#[ ]*elif/ s/#lint *(on)/defined(lint)/g
|
||||
' $2/$file > $2/$file.sed
|
||||
mv $2/$file.sed $2/$file
|
||||
if cmp $file $2/$file >/dev/null 2>&1; then
|
||||
echo Deleting $2/$file\; no fixes were needed.
|
||||
rm $2/$file
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
shift; shift
|
||||
done
|
||||
|
||||
cd /usr/include
|
||||
|
||||
# Fix one other error in this file: a mismatched quote not inside a C comment.
|
||||
file=sundev/vuid_event.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
cp $file ${LIB}/$file >/dev/null 2>&1 \
|
||||
|| echo "Can't copy $file"
|
||||
chmod +w ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -r ${LIB}/$file ]; then
|
||||
echo Fixing $file comment
|
||||
ex ${LIB}/$file <<EOF
|
||||
g/doesn't/s/doesn't/does not/
|
||||
wq
|
||||
EOF
|
||||
if cmp $file ${LIB}/$file >/dev/null 2>&1; then
|
||||
echo Deleting ${LIB}/$file\; no fixes were needed.
|
||||
rm ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fix an error in this file: a missing semi-colon at the end of the statsswtch
|
||||
# structure definition.
|
||||
file=rpcsvc/rstat.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
cp $file ${LIB}/$file >/dev/null 2>&1 \
|
||||
|| echo "Can't copy $file"
|
||||
chmod +w ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -r ${LIB}/$file ]; then
|
||||
echo Fixing $file, definition of statsswtch
|
||||
ex ${LIB}/$file <<EOF
|
||||
g/boottime$/s//&;/
|
||||
wq
|
||||
EOF
|
||||
if cmp $file $2/$file >/dev/null 2>&1; then
|
||||
echo Deleting $2/$file\; no fixes were needed.
|
||||
rm $2/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
# Deal with yet another challenge, this in X11/Xmu.h
|
||||
file=X11/Xmu.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
mkdir ${LIB}/X11 2>&-
|
||||
cp $file ${LIB}/$file >/dev/null 2>&1 \
|
||||
|| echo "Can't copy $file"
|
||||
chmod +w ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -r ${LIB}/$file ]; then
|
||||
echo Fixing $file sprintf declaration
|
||||
ex ${LIB}/$file <<EOF
|
||||
/^extern char \* sprintf();$/c
|
||||
#ifndef __STDC__
|
||||
extern char * sprintf();
|
||||
#endif /* !defined __STDC__ */
|
||||
.
|
||||
wq
|
||||
EOF
|
||||
if cmp $file ${LIB}/$file >/dev/null 2>&1; then
|
||||
echo Deleting ${LIB}/$file\; no fixes were needed.
|
||||
rm ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for missing ';' in struct
|
||||
|
||||
file=netinet/ip.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
mkdir ${LIB}/netinet 2>&-
|
||||
sed -e '/^struct/,/^};/s/}$/};/' $file > ${LIB}/$file
|
||||
cmp $file ${LIB}/$file >&- && rm -f ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fix the CAT macro in memvar.h.
|
||||
|
||||
file=pixrect/memvar.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
mkdir ${LIB}/pixrect 2>&-
|
||||
sed -e '/^#define.CAT(a,b)/ s/IDENT(a)b/a##b/g' $file > ${LIB}/$file
|
||||
cmp $file ${LIB}/$file >&- && rm -f ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for yet more missing ';' in struct (in SunOS 4.0.x)
|
||||
|
||||
file=rpcsvc/rusers.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
mkdir ${LIB}/rpcsvc 2>&-
|
||||
sed -e '/^struct/,/^};/s/_cnt$/_cnt;/' $file > ${LIB}/$file
|
||||
cmp $file ${LIB}/$file >&- && rm -f ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for yet more missing ';' in struct (in SunOS 4.0.x)
|
||||
|
||||
file=rpcsvc/rusers.h
|
||||
if [ -r $file ]; then
|
||||
if [ ! -r ${LIB}/$file ]; then
|
||||
mkdir ${LIB}/rpcsvc 2>&-
|
||||
sed -e '/^struct/,/^};/s/_cnt$/_cnt;/' $file > ${LIB}/$file
|
||||
cmp $file ${LIB}/$file >&- && rm -f ${LIB}/$file
|
||||
fi
|
||||
fi
|
||||
|
||||
echo 'Removing unneeded directories:'
|
||||
cd $LIB
|
||||
files=`find . -type d -print | sort -r`
|
||||
for file in $files; do
|
||||
rmdir $LIB/$file > /dev/null 2>&1
|
||||
done
|
||||
|
||||
if $LINKS; then
|
||||
echo 'Making internal symbolic non-directory links'
|
||||
cd /usr/include
|
||||
files=`find . -type l -print`
|
||||
for file in $files; do
|
||||
dest=`ls -ld $file | sed -n 's/.*-> //p'`
|
||||
if expr "$dest" : '[^/].*' > /dev/null; then
|
||||
target=${LIB}/`echo file | sed "s|[^/]*\$|$dest|"`
|
||||
if [ -f $target ]; then
|
||||
ln -s $dest ${LIB}/$file >/dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This progam 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.
|
||||
*
|
||||
* Alliance VLSI CAD System 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 the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Compilation switch flag definitions for GNU CC.
|
||||
Copyright (C) 1987, 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 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Name of the input .c file being compiled. */
|
||||
extern char *main_input_filename;
|
||||
|
||||
/* 1 => write gdb debugging output (using symout.c).
|
||||
2 => write dbx debugging output (using dbxout.c).
|
||||
3 => write sdb debugging output (using sdbout.c). */
|
||||
enum debugger { NO_DEBUG = 0, GDB_DEBUG = 1, DBX_DEBUG = 2, SDB_DEBUG = 3,
|
||||
EXTENDED_DBX_DEBUG = 4 };
|
||||
|
||||
extern enum debugger write_symbols;
|
||||
|
||||
/* Nonzero means use GDB-only extensions of DBX format. */
|
||||
extern int use_gdb_dbx_extensions;
|
||||
|
||||
/* Nonzero means do optimizations. -opt. */
|
||||
|
||||
extern int optimize;
|
||||
|
||||
/* Nonzero means do stupid register allocation. -noreg.
|
||||
This and `optimize' are controlled by different switches in cc1,
|
||||
but normally cc controls them both with the -O switch. */
|
||||
|
||||
extern int obey_regdecls;
|
||||
|
||||
/* Don't print functions as they are compiled and don't print
|
||||
times taken by the various passes. -quiet. */
|
||||
|
||||
extern int quiet_flag;
|
||||
|
||||
/* Don't print warning messages. -w. */
|
||||
|
||||
extern int inhibit_warnings;
|
||||
|
||||
/* Do print extra warnings (such as for uninitialized variables). -W. */
|
||||
|
||||
extern int extra_warnings;
|
||||
|
||||
/* Nonzero to warn about unused local variables. */
|
||||
|
||||
extern int warn_unused;
|
||||
|
||||
/* Nonzero means warn about all declarations which shadow others. */
|
||||
|
||||
extern int warn_shadow;
|
||||
|
||||
/* Warn if a switch on an enum fails to have a case for every enum value. */
|
||||
|
||||
extern int warn_switch;
|
||||
|
||||
/* Nonzero means warn about any identifiers that match in the first N
|
||||
characters. The value N is in `id_clash_len'. */
|
||||
|
||||
extern int warn_id_clash;
|
||||
extern int id_clash_len;
|
||||
|
||||
/* Nonzero if generating code to do profiling. */
|
||||
|
||||
extern int profile_flag;
|
||||
|
||||
/* Nonzero if generating code to do profiling on the basis of basic blocks. */
|
||||
|
||||
extern int profile_block_flag;
|
||||
|
||||
/* Nonzero for -pedantic switch: warn about anything
|
||||
that standard C forbids. */
|
||||
|
||||
extern int pedantic;
|
||||
|
||||
/* Now the symbols that are set with `-f' switches. */
|
||||
|
||||
/* Nonzero means `char' should be signed. */
|
||||
|
||||
extern int flag_signed_char;
|
||||
|
||||
/* Nonzero means give an enum type only as many bytes as it needs. */
|
||||
|
||||
extern int flag_short_enums;
|
||||
|
||||
/* Nonzero for -fcaller-saves: allocate values in regs that need to
|
||||
be saved across function calls, if that produces overall better code.
|
||||
Optional now, so people can test it. */
|
||||
|
||||
extern int flag_caller_saves;
|
||||
|
||||
/* Nonzero for -fpcc-struct-return: return values the same way PCC does. */
|
||||
|
||||
extern int flag_pcc_struct_return;
|
||||
|
||||
/* Nonzero for -fforce-mem: load memory value into a register
|
||||
before arithmetic on it. This makes better cse but slower compilation. */
|
||||
|
||||
extern int flag_force_mem;
|
||||
|
||||
/* Nonzero for -fforce-addr: load memory address into a register before
|
||||
reference to memory. This makes better cse but slower compilation. */
|
||||
|
||||
extern int flag_force_addr;
|
||||
|
||||
/* Nonzero for -fdefer-pop: don't pop args after each function call;
|
||||
instead save them up to pop many calls' args with one insns. */
|
||||
|
||||
extern int flag_defer_pop;
|
||||
|
||||
/* Nonzero for -ffloat-store: don't allocate floats and doubles
|
||||
in extended-precision registers. */
|
||||
|
||||
extern int flag_float_store;
|
||||
|
||||
/* Nonzero for -fcombine-regs:
|
||||
allow instruction combiner to combine an insn
|
||||
that just copies one reg to another. */
|
||||
|
||||
extern int flag_combine_regs;
|
||||
|
||||
/* Nonzero enables strength-reduction in loop.c. */
|
||||
|
||||
extern int flag_strength_reduce;
|
||||
|
||||
/* Nonzero for -fwritable-strings:
|
||||
store string constants in data segment and don't uniquize them. */
|
||||
|
||||
extern int flag_writable_strings;
|
||||
|
||||
/* Nonzero means don't put addresses of constant functions in registers.
|
||||
Used for compiling the Unix kernel, where strange substitutions are
|
||||
done on the assembly output. */
|
||||
|
||||
extern int flag_no_function_cse;
|
||||
|
||||
/* Nonzero for -fomit-frame-pointer:
|
||||
don't make a frame pointer in simple functions that don't require one. */
|
||||
|
||||
extern int flag_omit_frame_pointer;
|
||||
|
||||
/* This isn't a flag, but everyone who needs flag_omit_frame_pointer
|
||||
also needs this.
|
||||
Nonzero means current function must be given a frame pointer.
|
||||
Set in stmt.c if anything is allocated on the stack there.
|
||||
Set in reload1.c if anything is allocated on the stack there. */
|
||||
|
||||
extern int frame_pointer_needed;
|
||||
|
||||
/* Nonzero to inhibit use of define_optimization peephole opts. */
|
||||
|
||||
extern int flag_no_peephole;
|
||||
|
||||
/* Nonzero means all references through pointers are volatile. */
|
||||
|
||||
extern int flag_volatile;
|
||||
|
||||
/* Nonzero means make functions that look like good inline candidates
|
||||
go inline. */
|
||||
|
||||
extern int flag_inline_functions;
|
||||
|
||||
/* Nonzero for -fkeep-inline-functions: even if we make a function
|
||||
go inline everywhere, keep its defintion around for debugging
|
||||
purposes. */
|
||||
|
||||
extern int flag_keep_inline_functions;
|
||||
|
||||
/* Nonzero if we are only using compiler to check syntax errors. */
|
||||
|
||||
extern int flag_syntax_only;
|
||||
|
||||
/* Nonzero means make the text shared if supported. */
|
||||
|
||||
extern int flag_shared_data;
|
||||
|
||||
/* Nonzero means put things in delayed-branch slots if supported. */
|
||||
|
||||
extern int flag_delayed_branch;
|
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,192 @@
|
|||
'xrdef {Copying-pg}{1}
|
||||
'xrdef {Copying-snt}{}
|
||||
'xrdef {Copying-pg}{1}
|
||||
'xrdef {Copying-snt}{}
|
||||
'xrdef {Copying-pg}{2}
|
||||
'xrdef {Copying-snt}{}
|
||||
'xrdef {Copying-pg}{5}
|
||||
'xrdef {Copying-snt}{}
|
||||
'xrdef {Contributors-pg}{7}
|
||||
'xrdef {Contributors-snt}{}
|
||||
'xrdef {Boycott-pg}{9}
|
||||
'xrdef {Boycott-snt}{chapter'tie1}
|
||||
'xrdef {Options-pg}{13}
|
||||
'xrdef {Options-snt}{chapter'tie2}
|
||||
'xrdef {Installation-pg}{27}
|
||||
'xrdef {Installation-snt}{chapter'tie3}
|
||||
'xrdef {Other Dir-pg}{35}
|
||||
'xrdef {Other Dir-snt}{section'tie3.1}
|
||||
'xrdef {Sun Install-pg}{35}
|
||||
'xrdef {Sun Install-snt}{section'tie3.2}
|
||||
'xrdef {3b1 Install-pg}{36}
|
||||
'xrdef {3b1 Install-snt}{section'tie3.3}
|
||||
'xrdef {SCO Install-pg}{37}
|
||||
'xrdef {SCO Install-snt}{section'tie3.4}
|
||||
'xrdef {VMS Install-pg}{37}
|
||||
'xrdef {VMS Install-snt}{section'tie3.5}
|
||||
'xrdef {HPUX Install-pg}{40}
|
||||
'xrdef {HPUX Install-snt}{section'tie3.6}
|
||||
'xrdef {Tower Install-pg}{41}
|
||||
'xrdef {Tower Install-snt}{section'tie3.7}
|
||||
'xrdef {Trouble-pg}{43}
|
||||
'xrdef {Trouble-snt}{chapter'tie4}
|
||||
'xrdef {Service-pg}{45}
|
||||
'xrdef {Service-snt}{chapter'tie5}
|
||||
'xrdef {Incompatibilities-pg}{47}
|
||||
'xrdef {Incompatibilities-snt}{chapter'tie6}
|
||||
'xrdef {Extensions-pg}{51}
|
||||
'xrdef {Extensions-snt}{chapter'tie7}
|
||||
'xrdef {Statement Exprs-pg}{51}
|
||||
'xrdef {Statement Exprs-snt}{section'tie7.1}
|
||||
'xrdef {Naming Types-pg}{52}
|
||||
'xrdef {Naming Types-snt}{section'tie7.2}
|
||||
'xrdef {Typeof-pg}{52}
|
||||
'xrdef {Typeof-snt}{section'tie7.3}
|
||||
'xrdef {Lvalues-pg}{53}
|
||||
'xrdef {Lvalues-snt}{section'tie7.4}
|
||||
'xrdef {Conditionals-pg}{55}
|
||||
'xrdef {Conditionals-snt}{section'tie7.5}
|
||||
'xrdef {Zero-Length-pg}{55}
|
||||
'xrdef {Zero-Length-snt}{section'tie7.6}
|
||||
'xrdef {Variable-Length-pg}{56}
|
||||
'xrdef {Variable-Length-snt}{section'tie7.7}
|
||||
'xrdef {Subscripting-pg}{57}
|
||||
'xrdef {Subscripting-snt}{section'tie7.8}
|
||||
'xrdef {Pointer Arith-pg}{57}
|
||||
'xrdef {Pointer Arith-snt}{section'tie7.9}
|
||||
'xrdef {Initializers-pg}{57}
|
||||
'xrdef {Initializers-snt}{section'tie7.10}
|
||||
'xrdef {Constructors-pg}{58}
|
||||
'xrdef {Constructors-snt}{section'tie7.11}
|
||||
'xrdef {Function Attributes-pg}{58}
|
||||
'xrdef {Function Attributes-snt}{section'tie7.12}
|
||||
'xrdef {Dollar Signs-pg}{59}
|
||||
'xrdef {Dollar Signs-snt}{section'tie7.13}
|
||||
'xrdef {Alignment-pg}{60}
|
||||
'xrdef {Alignment-snt}{section'tie7.14}
|
||||
'xrdef {Inline-pg}{60}
|
||||
'xrdef {Inline-snt}{section'tie7.15}
|
||||
'xrdef {Extended Asm-pg}{62}
|
||||
'xrdef {Extended Asm-snt}{section'tie7.16}
|
||||
'xrdef {Asm Labels-pg}{65}
|
||||
'xrdef {Asm Labels-snt}{section'tie7.17}
|
||||
'xrdef {Explicit Reg Vars-pg}{66}
|
||||
'xrdef {Explicit Reg Vars-snt}{section'tie7.18}
|
||||
'xrdef {Global Reg Vars-pg}{66}
|
||||
'xrdef {Global Reg Vars-snt}{section'tie7.18.1}
|
||||
'xrdef {Local Reg Vars-pg}{68}
|
||||
'xrdef {Local Reg Vars-snt}{section'tie7.18.2}
|
||||
'xrdef {Alternate Keywords-pg}{69}
|
||||
'xrdef {Alternate Keywords-snt}{section'tie7.19}
|
||||
'xrdef {Bugs-pg}{71}
|
||||
'xrdef {Bugs-snt}{chapter'tie8}
|
||||
'xrdef {Bug Criteria-pg}{71}
|
||||
'xrdef {Bug Criteria-snt}{section'tie8.1}
|
||||
'xrdef {Bug Reporting-pg}{72}
|
||||
'xrdef {Bug Reporting-snt}{section'tie8.2}
|
||||
'xrdef {Portability-pg}{77}
|
||||
'xrdef {Portability-snt}{chapter'tie9}
|
||||
'xrdef {Interface-pg}{79}
|
||||
'xrdef {Interface-snt}{chapter'tie10}
|
||||
'xrdef {Passes-pg}{81}
|
||||
'xrdef {Passes-snt}{chapter'tie11}
|
||||
'xrdef {RTL-pg}{87}
|
||||
'xrdef {RTL-snt}{chapter'tie12}
|
||||
'xrdef {RTL Objects-pg}{87}
|
||||
'xrdef {RTL Objects-snt}{section'tie12.1}
|
||||
'xrdef {Accessors-pg}{88}
|
||||
'xrdef {Accessors-snt}{section'tie12.2}
|
||||
'xrdef {Flags-pg}{90}
|
||||
'xrdef {Flags-snt}{section'tie12.3}
|
||||
'xrdef {Machine Modes-pg}{92}
|
||||
'xrdef {Machine Modes-snt}{section'tie12.4}
|
||||
'xrdef {Constants-pg}{94}
|
||||
'xrdef {Constants-snt}{section'tie12.5}
|
||||
'xrdef {Regs and Memory-pg}{96}
|
||||
'xrdef {Regs and Memory-snt}{section'tie12.6}
|
||||
'xrdef {Arithmetic-pg}{98}
|
||||
'xrdef {Arithmetic-snt}{section'tie12.7}
|
||||
'xrdef {Comparisons-pg}{100}
|
||||
'xrdef {Comparisons-snt}{section'tie12.8}
|
||||
'xrdef {Bit Fields-pg}{102}
|
||||
'xrdef {Bit Fields-snt}{section'tie12.9}
|
||||
'xrdef {Conversions-pg}{102}
|
||||
'xrdef {Conversions-snt}{section'tie12.10}
|
||||
'xrdef {RTL Declarations-pg}{103}
|
||||
'xrdef {RTL Declarations-snt}{section'tie12.11}
|
||||
'xrdef {Side Effects-pg}{104}
|
||||
'xrdef {Side Effects-snt}{section'tie12.12}
|
||||
'xrdef {Incdec-pg}{107}
|
||||
'xrdef {Incdec-snt}{section'tie12.13}
|
||||
'xrdef {Assembler-pg}{108}
|
||||
'xrdef {Assembler-snt}{section'tie12.14}
|
||||
'xrdef {Insns-pg}{109}
|
||||
'xrdef {Insns-snt}{section'tie12.15}
|
||||
'xrdef {Calls-pg}{113}
|
||||
'xrdef {Calls-snt}{section'tie12.16}
|
||||
'xrdef {Sharing-pg}{114}
|
||||
'xrdef {Sharing-snt}{section'tie12.17}
|
||||
'xrdef {Machine Desc-pg}{117}
|
||||
'xrdef {Machine Desc-snt}{chapter'tie13}
|
||||
'xrdef {Patterns-pg}{117}
|
||||
'xrdef {Patterns-snt}{section'tie13.1}
|
||||
'xrdef {Example-pg}{118}
|
||||
'xrdef {Example-snt}{section'tie13.2}
|
||||
'xrdef {RTL Template-pg}{119}
|
||||
'xrdef {RTL Template-snt}{section'tie13.3}
|
||||
'xrdef {Output Template-pg}{122}
|
||||
'xrdef {Output Template-snt}{section'tie13.4}
|
||||
'xrdef {Output Statement-pg}{123}
|
||||
'xrdef {Output Statement-snt}{section'tie13.5}
|
||||
'xrdef {Constraints-pg}{124}
|
||||
'xrdef {Constraints-snt}{section'tie13.6}
|
||||
'xrdef {Simple Constraints-pg}{124}
|
||||
'xrdef {Simple Constraints-snt}{section'tie13.6.1}
|
||||
'xrdef {Multi-Alternative-pg}{128}
|
||||
'xrdef {Multi-Alternative-snt}{section'tie13.6.2}
|
||||
'xrdef {Class Preferences-pg}{129}
|
||||
'xrdef {Class Preferences-snt}{section'tie13.6.3}
|
||||
'xrdef {Modifiers-pg}{130}
|
||||
'xrdef {Modifiers-snt}{section'tie13.6.4}
|
||||
'xrdef {No Constraints-pg}{131}
|
||||
'xrdef {No Constraints-snt}{section'tie13.6.5}
|
||||
'xrdef {Standard Names-pg}{131}
|
||||
'xrdef {Standard Names-snt}{section'tie13.7}
|
||||
'xrdef {Pattern Ordering-pg}{137}
|
||||
'xrdef {Pattern Ordering-snt}{section'tie13.8}
|
||||
'xrdef {Dependent Patterns-pg}{137}
|
||||
'xrdef {Dependent Patterns-snt}{section'tie13.9}
|
||||
'xrdef {Jump Patterns-pg}{140}
|
||||
'xrdef {Jump Patterns-snt}{section'tie13.10}
|
||||
'xrdef {Peephole Definitions-pg}{141}
|
||||
'xrdef {Peephole Definitions-snt}{section'tie13.11}
|
||||
'xrdef {Expander Definitions-pg}{144}
|
||||
'xrdef {Expander Definitions-snt}{section'tie13.12}
|
||||
'xrdef {Machine Macros-pg}{149}
|
||||
'xrdef {Machine Macros-snt}{chapter'tie14}
|
||||
'xrdef {Run-time Target-pg}{149}
|
||||
'xrdef {Run-time Target-snt}{section'tie14.1}
|
||||
'xrdef {Storage Layout-pg}{150}
|
||||
'xrdef {Storage Layout-snt}{section'tie14.2}
|
||||
'xrdef {Registers-pg}{152}
|
||||
'xrdef {Registers-snt}{section'tie14.3}
|
||||
'xrdef {Register Classes-pg}{157}
|
||||
'xrdef {Register Classes-snt}{section'tie14.4}
|
||||
'xrdef {Stack Layout-pg}{161}
|
||||
'xrdef {Stack Layout-snt}{section'tie14.5}
|
||||
'xrdef {Library Calls-pg}{169}
|
||||
'xrdef {Library Calls-snt}{section'tie14.6}
|
||||
'xrdef {Addressing Modes-pg}{170}
|
||||
'xrdef {Addressing Modes-snt}{section'tie14.7}
|
||||
'xrdef {Delayed Branch-pg}{172}
|
||||
'xrdef {Delayed Branch-snt}{section'tie14.8}
|
||||
'xrdef {Condition Code-pg}{173}
|
||||
'xrdef {Condition Code-snt}{section'tie14.9}
|
||||
'xrdef {Cross-compilation-pg}{174}
|
||||
'xrdef {Cross-compilation-snt}{section'tie14.10}
|
||||
'xrdef {Misc-pg}{176}
|
||||
'xrdef {Misc-snt}{section'tie14.11}
|
||||
'xrdef {Assembler Format-pg}{179}
|
||||
'xrdef {Assembler Format-snt}{section'tie14.12}
|
||||
'xrdef {Config-pg}{191}
|
||||
'xrdef {Config-snt}{chapter'tie15}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
|||
\entry {Installation on SCO systems}{37}{Installation on SCO systems}
|
|
@ -0,0 +1,2 @@
|
|||
\initial {I}
|
||||
\entry {Installation on SCO systems}{37}
|
|
@ -0,0 +1,153 @@
|
|||
1 GCC
|
||||
The GCC command invokes the GNU C compiler.
|
||||
|
||||
GCC file-spec
|
||||
|
||||
2 Parameters
|
||||
|
||||
file-spec
|
||||
|
||||
A C source file. If no input file extension is specified, GNU C
|
||||
assumes .C as the default extension.
|
||||
|
||||
2 Qualifiers
|
||||
|
||||
GNU C command qualifiers modify the way the compiler handles the
|
||||
compiliation.
|
||||
|
||||
The following is the list of available qualifiers for GNU C:
|
||||
|
||||
|
||||
/CC1_OPTIONS=(option [,option...]])
|
||||
|
||||
/DEBUG
|
||||
|
||||
/DEFINE=(identifier[=definition][,...])
|
||||
|
||||
/INCLUDE_DIRECTORY=(path [,path...]])
|
||||
|
||||
/MACHINE_CODE
|
||||
|
||||
/OPTIMIZE
|
||||
|
||||
/UNDEFINE=(identifier[,identifier,...])
|
||||
|
||||
/VERBOSE
|
||||
|
||||
|
||||
2 Linking
|
||||
|
||||
When linking programs compiled with GNU C, you should include the GNU
|
||||
C library before the VAX C library. For example,
|
||||
|
||||
LINK object-file,GNU_CC:[000000]GCCLIB/LIB,SYS$LIBRARY:VAXCRTL/LIB
|
||||
|
||||
You can also link your program with the shared VAX C library. This
|
||||
can reduce the size of the .EXE file, as well as make it smaller
|
||||
when it's running. For example,
|
||||
|
||||
$ LINK object-file, GNU_CC:[000000]GCCLIB/LIB,SYS$INPUT:/OPTIONS
|
||||
SYS$SHARE:VAXCRTL/SHARE
|
||||
|
||||
(If you use the second example and type it in by hand, be sure to type
|
||||
^Z after the last carriage return)
|
||||
|
||||
2 /DEBUG
|
||||
|
||||
/DEBUG includes additional information in the object file output so
|
||||
that the program can be debugged with the VAX Symbolic Debugger.
|
||||
This qualifier includes very little information, so using the
|
||||
debugger is somewhat difficult.
|
||||
|
||||
2 /DEFINE=(identifier[=definition][,...])
|
||||
|
||||
/DEFINE defines a string or macro ('definition') to be substituted
|
||||
for every occurrence of a given string ('identifier') in a program.
|
||||
It is equivalent to the #define preprocessor directive.
|
||||
|
||||
All definitions and identifiers are converted to uppercase unless they
|
||||
are in quotation marks.
|
||||
|
||||
The simple form of the /DEFINE qualifier,
|
||||
|
||||
/DEFINE=vms
|
||||
|
||||
results in a definition equivalent to the preprocessor directive
|
||||
|
||||
#define VMS 1
|
||||
|
||||
You must enclose macro definitions in quotation marks, as in this
|
||||
example:
|
||||
|
||||
/DEFINE="C(x)=((x) & 0xff)"
|
||||
|
||||
This definition is the same as the preprocessor definition
|
||||
|
||||
#define C(x) ((x) & 0xff)
|
||||
|
||||
If more than one /DEFINE is present on the GCC command line, only
|
||||
the last /DEFINE is used.
|
||||
|
||||
If both /DEFINE and /UNDEFINE are present on a command line, /DEFINE
|
||||
is evaluated before /UNDEFINE
|
||||
|
||||
2 /INCLUDE_DIRECTORY=(path [,path...])
|
||||
|
||||
The /INCLUDE_DIRECTORY qualifier provides additional directories to
|
||||
search for user-defined include files. 'path' can be either a
|
||||
logical name or a directory specification.
|
||||
|
||||
There are two forms for specifying include files - #include "file-spec"
|
||||
and #include <file-spec>. For the #include "file-spec" form, the search
|
||||
order is:
|
||||
|
||||
1. The directory containing the source file.
|
||||
|
||||
2. The directories in the /INCLUDE qualifier (if any).
|
||||
|
||||
3. The directory (or directories) specified in the logical name
|
||||
GNU_CC_INCLUDE.
|
||||
|
||||
4. The directory (or directories) specified in the logical name
|
||||
SYS$LIBRARY.
|
||||
|
||||
For the #include <file-spec> form, the search order is:
|
||||
|
||||
1. The directories specified in the /INCLUDE qualifier (if any).
|
||||
|
||||
2. The directory (or directories) specified in the logical name
|
||||
GNU_CC_INCLUDE.
|
||||
|
||||
3. The directory (or directories) specified in the logical name
|
||||
SYS$LIBRARY.
|
||||
|
||||
2 /MACHINE_CODE
|
||||
|
||||
Tells GNU C to output the machine code generated by the compiler. Note
|
||||
that no object file is produced when /MACHINE_CODE is specified. The
|
||||
machine code is output to a file with the same name as the input file,
|
||||
with the extension .S.
|
||||
|
||||
2 /OPTIMIZE
|
||||
/NOOPTIMIZE
|
||||
|
||||
Controls whether optimization is performed by the compiler. By default,
|
||||
optimization is on. /NOOPTIMIZE turns optimization off.
|
||||
|
||||
2 /UNDEFINE
|
||||
|
||||
/UNDEFINE cancels a macro definition. Thus, it is the same as the
|
||||
#undef preprocessor directive.
|
||||
|
||||
If more than one /UNDEFINE is present on the GCC command line, only
|
||||
the last /UNDEFINE is used.
|
||||
|
||||
If both /DEFINE and /UNDEFINE are present on a command line, /DEFINE
|
||||
is evaluated before /UNDEFINE
|
||||
|
||||
2 /VERBOSE
|
||||
|
||||
Controls whether the user sees the invocation command strings for the
|
||||
preprocessor, compiler, and assembler. The compiler also outputs
|
||||
some statistics on time spent in its various phases.
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
This is Info file gcc.info, produced by Makeinfo-1.47 from the input
|
||||
file gcc.texinfo.
|
||||
|
||||
This file documents the use and the internals of the GNU compiler.
|
||||
|
||||
Copyright (C) 1988, 1989, 1990 Free Software Foundation, Inc.
|
||||
|
||||
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.
|
||||
|
||||
Permission is granted to copy and distribute modified versions of
|
||||
this manual under the conditions for verbatim copying, provided also
|
||||
that the sections entitled "GNU General Public License" and "Protect
|
||||
Your Freedom--Fight `Look And Feel'" are included exactly as in the
|
||||
original, and provided that the entire resulting derived work is
|
||||
distributed under the terms of a permission notice identical to this
|
||||
one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this
|
||||
manual into another language, under the above conditions for modified
|
||||
versions, except that the sections entitled "GNU General Public
|
||||
License" and "Protect Your Freedom--Fight `Look And Feel'" and this
|
||||
permission notice may be included in translations approved by the Free
|
||||
Software Foundation instead of in the original English.
|
||||
|
||||
Indirect:
|
||||
gcc.info-1: 1204
|
||||
gcc.info-2: 23290
|
||||
gcc.info-3: 58923
|
||||
gcc.info-4: 106934
|
||||
gcc.info-5: 150408
|
||||
gcc.info-6: 199421
|
||||
gcc.info-7: 247429
|
||||
gcc.info-8: 289141
|
||||
gcc.info-9: 336430
|
||||
gcc.info-10: 385210
|
||||
gcc.info-11: 434739
|
||||
|
||||
Tag Table:
|
||||
(Indirect)
|
||||
Node: Top1206
|
||||
Node: Copying2582
|
||||
Node: Contributors15866
|
||||
Node: Boycott18065
|
||||
Node: Options23292
|
||||
Node: Installation58925
|
||||
Node: Other Dir79642
|
||||
Node: Sun Install80880
|
||||
Node: 3b1 Install82740
|
||||
Node: SCO Install84078
|
||||
Node: VMS Install84999
|
||||
Node: HPUX Install92592
|
||||
Node: Tower Install93547
|
||||
Node: Trouble94098
|
||||
Node: Service97090
|
||||
Node: Incompatibilities97667
|
||||
Node: Extensions106936
|
||||
Node: Statement Exprs108942
|
||||
Node: Naming Types110399
|
||||
Node: Typeof111488
|
||||
Node: Lvalues113350
|
||||
Node: Conditionals115614
|
||||
Node: Zero-Length116541
|
||||
Node: Variable-Length117218
|
||||
Node: Subscripting119001
|
||||
Node: Pointer Arith119484
|
||||
Node: Initializers120063
|
||||
Node: Constructors120507
|
||||
Node: Function Attributes122007
|
||||
Node: Dollar Signs123720
|
||||
Node: Alignment124221
|
||||
Node: Inline125558
|
||||
Node: Extended Asm128511
|
||||
Node: Asm Labels137286
|
||||
Node: Explicit Reg Vars138603
|
||||
Node: Global Reg Vars139617
|
||||
Node: Local Reg Vars143848
|
||||
Node: Alternate Keywords145441
|
||||
Node: Bugs146606
|
||||
Node: Bug Criteria147597
|
||||
Node: Bug Reporting150410
|
||||
Node: Portability161105
|
||||
Node: Interface162869
|
||||
Node: Passes167272
|
||||
Node: RTL180116
|
||||
Node: RTL Objects181951
|
||||
Node: Accessors184880
|
||||
Node: Flags188182
|
||||
Node: Machine Modes192771
|
||||
Node: Constants199423
|
||||
Node: Regs and Memory202169
|
||||
Node: Arithmetic209511
|
||||
Node: Comparisons214734
|
||||
Node: Bit Fields217545
|
||||
Node: Conversions218624
|
||||
Node: RTL Declarations221298
|
||||
Node: Side Effects222069
|
||||
Node: Incdec231332
|
||||
Node: Assembler233700
|
||||
Node: Insns235222
|
||||
Node: Calls245311
|
||||
Node: Sharing247431
|
||||
Node: Machine Desc250242
|
||||
Node: Patterns251884
|
||||
Node: Example255164
|
||||
Node: RTL Template256292
|
||||
Node: Output Template264294
|
||||
Node: Output Statement267312
|
||||
Node: Constraints269450
|
||||
Node: Simple Constraints270378
|
||||
Node: Multi-Alternative280768
|
||||
Node: Class Preferences283775
|
||||
Node: Modifiers284653
|
||||
Node: No Constraints288034
|
||||
Node: Standard Names289143
|
||||
Node: Pattern Ordering303968
|
||||
Node: Dependent Patterns305193
|
||||
Node: Jump Patterns309946
|
||||
Node: Peephole Definitions312323
|
||||
Node: Expander Definitions319276
|
||||
Node: Machine Macros326215
|
||||
Node: Run-time Target327452
|
||||
Node: Storage Layout331292
|
||||
Node: Registers336432
|
||||
Node: Register Classes350558
|
||||
Node: Stack Layout360578
|
||||
Node: Library Calls382803
|
||||
Node: Addressing Modes385212
|
||||
Node: Delayed Branch391626
|
||||
Node: Condition Code394697
|
||||
Node: Cross-compilation397402
|
||||
Node: Misc401854
|
||||
Node: Assembler Format409159
|
||||
Node: Config434741
|
||||
|
||||
End Tag Table
|
|
@ -0,0 +1,509 @@
|
|||
This is Info file gcc.info, produced by Makeinfo-1.47 from the input
|
||||
file gcc.texinfo.
|
||||
|
||||
This file documents the use and the internals of the GNU compiler.
|
||||
|
||||
Copyright (C) 1988, 1989, 1990 Free Software Foundation, Inc.
|
||||
|
||||
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.
|
||||
|
||||
Permission is granted to copy and distribute modified versions of
|
||||
this manual under the conditions for verbatim copying, provided also
|
||||
that the sections entitled "GNU General Public License" and "Protect
|
||||
Your Freedom--Fight `Look And Feel'" are included exactly as in the
|
||||
original, and provided that the entire resulting derived work is
|
||||
distributed under the terms of a permission notice identical to this
|
||||
one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this
|
||||
manual into another language, under the above conditions for modified
|
||||
versions, except that the sections entitled "GNU General Public
|
||||
License" and "Protect Your Freedom--Fight `Look And Feel'" and this
|
||||
permission notice may be included in translations approved by the Free
|
||||
Software Foundation instead of in the original English.
|
||||
|
||||
|
||||
File: gcc.info, Node: Top, Next: Copying, Up: (DIR)
|
||||
|
||||
Introduction
|
||||
************
|
||||
|
||||
This manual documents how to run, install and port the GNU C
|
||||
compiler, as well as its new features and incompatibilities, and how to
|
||||
report bugs.
|
||||
|
||||
* Menu:
|
||||
|
||||
* Copying:: GNU General Public License says
|
||||
how you can copy and share GNU CC.
|
||||
* Contributors:: People who have contributed to GNU CC.
|
||||
* Boycott:: Protect your freedom--fight "look and feel".
|
||||
* Options:: Command options supported by `gcc'.
|
||||
* Installation:: How to configure, compile and install GNU CC.
|
||||
* Trouble:: If you have trouble installing GNU CC.
|
||||
* Service:: How to find suppliers of services for GNU CC users.
|
||||
* Incompatibilities:: Incompatibilities of GNU CC.
|
||||
* Extensions:: GNU extensions to the C language.
|
||||
* Bugs:: How to report bugs (if you want to get them fixed).
|
||||
* Portability:: Goals of GNU CC's portability features.
|
||||
* Interface:: Function-call interface of GNU CC output.
|
||||
* Passes:: Order of passes, what they do, and what each file is for.
|
||||
* RTL:: The intermediate representation that most passes work on.
|
||||
* Machine Desc:: How to write machine description instruction patterns.
|
||||
* Machine Macros:: How to write the machine description C macros.
|
||||
* Config:: Writing the `xm-MACHINE.h' file.
|
||||
|
||||
|
||||
File: gcc.info, Node: Copying, Next: Contributors, Prev: Top, Up: Top
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
**************************
|
||||
|
||||
Version 1, February 1989
|
||||
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
========
|
||||
|
||||
The license agreements of most software companies try to keep users
|
||||
at the mercy of those companies. By contrast, our 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. The
|
||||
General Public License applies to the Free Software Foundation's
|
||||
software and to any other program whose authors commit to using it. You
|
||||
can use it for your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Specifically, the General Public License is designed to make
|
||||
sure that you have the freedom to give away or sell copies of free
|
||||
software, 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 a 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 tell them 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.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
1. This License Agreement 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 work
|
||||
containing the Program or a portion of it, either verbatim or with
|
||||
modifications. Each licensee is addressed as "you".
|
||||
|
||||
2. 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 General Public License
|
||||
and to the absence of any warranty; and give any other recipients
|
||||
of the Program a copy of this General Public License along with
|
||||
the Program. You may charge a fee for the physical act of
|
||||
transferring a copy.
|
||||
|
||||
3. You may modify your copy or copies of the Program or any portion of
|
||||
it, and copy and distribute such modifications under the terms of
|
||||
Paragraph 1 above, provided that you also do the following:
|
||||
|
||||
* cause the modified files to carry prominent notices stating
|
||||
that you changed the files and the date of any change; and
|
||||
|
||||
* cause the whole of any work that you distribute or publish,
|
||||
that in whole or in part contains the Program or any part
|
||||
thereof, either with or without modifications, to be licensed
|
||||
at no charge to all third parties under the terms of this
|
||||
General Public License (except that you may choose to grant
|
||||
warranty protection to some or all third parties, at your
|
||||
option).
|
||||
|
||||
* If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the simplest and most usual 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 General Public License.
|
||||
|
||||
* 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.
|
||||
|
||||
Mere aggregation of another independent work with the Program (or
|
||||
its derivative) on a volume of a storage or distribution medium
|
||||
does not bring the other work under the scope of these terms.
|
||||
|
||||
4. You may copy and distribute the Program (or a portion or
|
||||
derivative of it, under Paragraph 2) in object code or executable
|
||||
form under the terms of Paragraphs 1 and 2 above provided that you
|
||||
also do one of the following:
|
||||
|
||||
* accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of
|
||||
Paragraphs 1 and 2 above; or,
|
||||
|
||||
* accompany it with a written offer, valid for at least three
|
||||
years, to give any third party free (except for a nominal
|
||||
charge for the cost of distribution) a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Paragraphs 1 and 2 above; or,
|
||||
|
||||
* accompany it with the information you received as to where the
|
||||
corresponding source code may be obtained. (This alternative
|
||||
is allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form alone.)
|
||||
|
||||
Source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable file, complete
|
||||
source code means all the source code for all modules it contains;
|
||||
but, as a special exception, it need not include source code for
|
||||
modules which are standard libraries that accompany the operating
|
||||
system on which the executable file runs, or for standard header
|
||||
files or definitions files that accompany that operating system.
|
||||
|
||||
5. You may not copy, modify, sublicense, distribute or transfer the
|
||||
Program except as expressly provided under this General Public
|
||||
License. Any attempt otherwise to copy, modify, sublicense,
|
||||
distribute or transfer the Program is void, and will automatically
|
||||
terminate your rights to use the Program under this License.
|
||||
However, parties who have received copies, or rights to use
|
||||
copies, from you under this General Public License will not have
|
||||
their licenses terminated so long as such parties remain in full
|
||||
compliance.
|
||||
|
||||
6. By copying, distributing or modifying 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.
|
||||
|
||||
7. 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.
|
||||
|
||||
8. 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 the 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 the license, you may choose
|
||||
any version ever published by the Free Software Foundation.
|
||||
|
||||
9. 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
|
||||
|
||||
10. 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.
|
||||
|
||||
11. 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 humanity, 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 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
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 a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
program `Gnomovision' (a program to direct compilers to make passes
|
||||
at assemblers) written by James Hacker.
|
||||
|
||||
SIGNATURE OF TY COON, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
||||
File: gcc.info, Node: Contributors, Next: Boycott, Prev: Copying, Up: Top
|
||||
|
||||
Contributors to GNU CC
|
||||
**********************
|
||||
|
||||
In addition to Richard Stallman, several people have written parts
|
||||
of GNU CC.
|
||||
|
||||
* The idea of using RTL and some of the optimization ideas came from
|
||||
the U. of Arizona Portable Optimizer, written by Jack Davidson and
|
||||
Christopher Fraser. See "Register Allocation and Exhaustive
|
||||
Peephole Optimization", Software Practice and Experience 14 (9),
|
||||
Sept. 1984, 857-866.
|
||||
|
||||
* Paul Rubin wrote most of the preprocessor.
|
||||
|
||||
* Leonard Tower wrote parts of the parser, RTL generator, and RTL
|
||||
definitions, and of the Vax machine description.
|
||||
|
||||
* Ted Lemon wrote parts of the RTL reader and printer.
|
||||
|
||||
* Jim Wilson implemented loop strength reduction and some other loop
|
||||
optimizations.
|
||||
|
||||
* Nobuyuki Hikichi of Software Research Associates, Tokyo,
|
||||
contributed the support for the Sony NEWS machine.
|
||||
|
||||
* Charles LaBrec contributed the support for the Integrated Solutions
|
||||
68020 system.
|
||||
|
||||
* Michael Tiemann of MCC wrote most of the description of the
|
||||
National Semiconductor 32000 series cpu. He also wrote the code
|
||||
for inline function integration and for the SPARC cpu and Motorola
|
||||
88000 cpu and part of the Sun FPA support.
|
||||
|
||||
* Jan Stein of the Chalmers Computer Society provided support for
|
||||
Genix, as well as part of the 32000 machine description.
|
||||
|
||||
* Randy Smith finished the Sun FPA support.
|
||||
|
||||
* Robert Brown implemented the support for Encore 32000 systems.
|
||||
|
||||
* David Kashtan of SRI adapted GNU CC to the Vomit-Making System.
|
||||
|
||||
* Alex Crain provided changes for the 3b1.
|
||||
|
||||
* Greg Satz and Chris Hanson assisted in making GNU CC work on HP-UX
|
||||
for the 9000 series 300.
|
||||
|
||||
* William Schelter did most of the work on the Intel 80386 support.
|
||||
|
||||
* Christopher Smith did the port for Convex machines.
|
||||
|
||||
* Paul Petersen wrote the machine description for the Alliant FX/8.
|
||||
|
||||
* Alain Lichnewsky ported GNU CC to the Mips cpu.
|
||||
|
||||
* Devon Bowen, Dale Wiles and Kevin Zachmann ported GNU CC to the
|
||||
Tahoe.
|
||||
|
||||
* Jonathan Stone wrote the machine description for the Pyramid
|
||||
computer.
|
||||
|
||||
|
||||
File: gcc.info, Node: Boycott, Next: Options, Prev: Contributors, Up: Top
|
||||
|
||||
Protect Your Freedom--Fight "Look And Feel"
|
||||
*******************************************
|
||||
|
||||
This section is a political message from the League for Programming
|
||||
Freedom to the users of GNU CC. It is included here as an
|
||||
expression of support for the League on the part of the Free
|
||||
Software Foundation and Richard Stallman.
|
||||
|
||||
Ashton-Tate, Apple, Lotus and Xerox are trying to create a new form
|
||||
of legal monopoly: a copyright on a class of user interfaces. These
|
||||
monopolies would cause serious problems for users and developers of
|
||||
computer software and systems.
|
||||
|
||||
Until a few years ago, the law seemed clear: no one could restrict
|
||||
others from using a user interface; programmers were free to implement
|
||||
any interface they chose. Imitating interfaces, sometimes with changes,
|
||||
was standard practice in the computer field. The interfaces we know
|
||||
evolved gradually in this way; for example, the Macintosh user interface
|
||||
drew ideas from the Xerox interface, which in turn drew on work done at
|
||||
Stanford and SRI. 1-2-3 imitated VisiCalc, and dBase imitated a
|
||||
database program from JPL.
|
||||
|
||||
Most computer companies, and nearly all computer users, were happy
|
||||
with this state of affairs. The companies that are suing say it does
|
||||
not offer "enough incentive" to develop their products, but they must
|
||||
have considered it "enough" when they made their decision to do so. It
|
||||
seems they are not satisfied with the opportunity to continue to compete
|
||||
in the marketplace--not even with a head start.
|
||||
|
||||
If Xerox, Lotus, Apple and Ashton-Tate are permitted to make law
|
||||
through the courts, the precedent will hobble the software industry:
|
||||
|
||||
* Gratuitous incompatibilities will burden users. Imagine if each
|
||||
car manufacturer had to arrange the pedals in a different order.
|
||||
|
||||
* Software will become and remain more expensive. Users will be
|
||||
"locked in" to proprietary interfaces, for which there is no real
|
||||
competition.
|
||||
|
||||
* Large companies have an unfair advantage wherever lawsuits become
|
||||
commonplace. Since they can easily afford to sue, they can
|
||||
intimidate small companies with threats even when they don't
|
||||
really have a case.
|
||||
|
||||
* User interface improvements will come slower, since incremental
|
||||
evolution through creative imitation will no longer be permitted.
|
||||
|
||||
* Even Apple, etc., will find it harder to make improvements if they
|
||||
can no longer adapt the good ideas that others introduce, for fear
|
||||
of weakening their own legal positions. Some users suggest that
|
||||
this stagnation may already have started.
|
||||
|
||||
* If you use GNU software, you might find it of some concern that
|
||||
user interface copyright will make it hard for the Free Software
|
||||
Foundation to develop programs compatible with the interfaces that
|
||||
you already know.
|
||||
|
||||
To protect our freedom from lawsuits like these, a group of
|
||||
programmers and users have formed a new grass-roots political
|
||||
organization, the League for Programming Freedom.
|
||||
|
||||
The purpose of the League is to oppose new monopolistic practices
|
||||
such as user-interface copyright and software patents; it calls for a
|
||||
return to the legal policies of the recent past, in which these
|
||||
practices were not allowed. The League is not concerned with free
|
||||
software as an issue, and not affiliated with the Free Software
|
||||
Foundation.
|
||||
|
||||
The League's membership rolls include John McCarthy, inventor of
|
||||
Lisp, Marvin Minsky, founder of the Artificial Intelligence lab, Guy L.
|
||||
Steele, Jr., author of well-known books on Lisp and C, as well as
|
||||
Richard Stallman, the developer of GNU CC. Please join and add your
|
||||
name to the list. Membership dues in the League are $42 per year for
|
||||
programmers, managers and professionals; $10.50 for students; $21 for
|
||||
others.
|
||||
|
||||
The League needs both activist members and members who only pay their
|
||||
dues.
|
||||
|
||||
To join, or for more information, phone (617) 492-0023 or write to:
|
||||
|
||||
League for Programming Freedom
|
||||
1 Kendall Square #143
|
||||
P.O. Box 9171
|
||||
Cambridge, MA 02139 league@prep.ai.mit.edu
|
||||
|
||||
Here are some suggestions from the League for how you can protect
|
||||
your freedom to write programs:
|
||||
|
||||
* Don't buy from Xerox, Lotus, Apple or Ashton-Tate. Buy from their
|
||||
competitors or from the defendants they are suing.
|
||||
|
||||
* Don't develop software to work with the systems made by these
|
||||
companies.
|
||||
|
||||
* Port your existing software to competing systems, so that you
|
||||
encourage users to switch.
|
||||
|
||||
* Write letters to company presidents to let them know their conduct
|
||||
is unacceptable.
|
||||
|
||||
* Tell your friends and colleagues about this issue and how it
|
||||
threatens to ruin the computer industry.
|
||||
|
||||
* Above all, don't work for the look-and-feel plaintiffs, and don't
|
||||
accept contracts from them.
|
||||
|
||||
* Write to Congress to explain the importance of this issue.
|
||||
|
||||
House Subcommittee on Intellectual Property
|
||||
2137 Rayburn Bldg
|
||||
Washington, DC 20515
|
||||
|
||||
Senate Subcommittee on Patents, Trademarks and Copyrights
|
||||
United States Senate
|
||||
Washington, DC 20510
|
||||
|
||||
Express your opinion! You can make a difference.
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,74 @@
|
|||
This is Info file gcc.info, produced by Makeinfo-1.47 from the input
|
||||
file gcc.texinfo.
|
||||
|
||||
This file documents the use and the internals of the GNU compiler.
|
||||
|
||||
Copyright (C) 1988, 1989, 1990 Free Software Foundation, Inc.
|
||||
|
||||
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.
|
||||
|
||||
Permission is granted to copy and distribute modified versions of
|
||||
this manual under the conditions for verbatim copying, provided also
|
||||
that the sections entitled "GNU General Public License" and "Protect
|
||||
Your Freedom--Fight `Look And Feel'" are included exactly as in the
|
||||
original, and provided that the entire resulting derived work is
|
||||
distributed under the terms of a permission notice identical to this
|
||||
one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this
|
||||
manual into another language, under the above conditions for modified
|
||||
versions, except that the sections entitled "GNU General Public
|
||||
License" and "Protect Your Freedom--Fight `Look And Feel'" and this
|
||||
permission notice may be included in translations approved by the Free
|
||||
Software Foundation instead of in the original English.
|
||||
|
||||
|
||||
File: gcc.info, Node: Config, Prev: Machine Macros, Up: Top
|
||||
|
||||
The Configuration File
|
||||
**********************
|
||||
|
||||
The configuration file `xm-MACHINE.h' contains macro definitions
|
||||
that describe the machine and system on which the compiler is running.
|
||||
Most of the values in it are actually the same on all machines that GNU
|
||||
CC runs on, so large parts of all configuration files are identical.
|
||||
But there are some macros that vary:
|
||||
|
||||
`FAILURE_EXIT_CODE'
|
||||
A C expression for the status code to be returned when the compiler
|
||||
exits after serious errors.
|
||||
|
||||
`SUCCESS_EXIT_CODE'
|
||||
A C expression for the status code to be returned when the compiler
|
||||
exits without serious errors.
|
||||
|
||||
`USE_C_ALLOCA'
|
||||
Define this macro to indicate that the compiler is running with the
|
||||
`alloca' implemented in C. This version of `alloca' can be found
|
||||
in the file `alloca.c'; to use it, you must also alter the
|
||||
`Makefile' variable `ALLOCA'.
|
||||
|
||||
This macro, unlike most, describes the machine that the compiler is
|
||||
running on, rather than the one the compiler is compiling for.
|
||||
Therefore, it should be set in the `xm-MACHINE.h' file rather than
|
||||
in the `tm-MACHINE.h' file.
|
||||
|
||||
If you do define this macro, you should probably do it as follows:
|
||||
|
||||
#ifndef __GNUC__
|
||||
#define USE_C_ALLOCA
|
||||
#else
|
||||
#define alloca __builtin_alloca
|
||||
#endif
|
||||
|
||||
so that when the compiler is compiled with GNU CC it uses the more
|
||||
efficient built-in `alloca' function.
|
||||
|
||||
In addition, configuration files for system V define `bcopy',
|
||||
`bzero' and `bcmp' as aliases. Some files define `alloca' as a macro
|
||||
when compiled with GNU CC, in order to take advantage of the benefit of
|
||||
GNU CC's built-in `alloca'.
|
||||
|
||||
|
|
@ -0,0 +1,900 @@
|
|||
This is Info file gcc.info, produced by Makeinfo-1.47 from the input
|
||||
file gcc.texinfo.
|
||||
|
||||
This file documents the use and the internals of the GNU compiler.
|
||||
|
||||
Copyright (C) 1988, 1989, 1990 Free Software Foundation, Inc.
|
||||
|
||||
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.
|
||||
|
||||
Permission is granted to copy and distribute modified versions of
|
||||
this manual under the conditions for verbatim copying, provided also
|
||||
that the sections entitled "GNU General Public License" and "Protect
|
||||
Your Freedom--Fight `Look And Feel'" are included exactly as in the
|
||||
original, and provided that the entire resulting derived work is
|
||||
distributed under the terms of a permission notice identical to this
|
||||
one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this
|
||||
manual into another language, under the above conditions for modified
|
||||
versions, except that the sections entitled "GNU General Public
|
||||
License" and "Protect Your Freedom--Fight `Look And Feel'" and this
|
||||
permission notice may be included in translations approved by the Free
|
||||
Software Foundation instead of in the original English.
|
||||
|
||||
|
||||
File: gcc.info, Node: Options, Next: Installation, Prev: Boycott, Up: Top
|
||||
|
||||
GNU CC Command Options
|
||||
**********************
|
||||
|
||||
The GNU C compiler uses a command syntax much like the Unix C
|
||||
compiler. The `gcc' program accepts options and file names as operands.
|
||||
Multiple single-letter options may *not* be grouped: `-dr' is very
|
||||
different from `-d -r'.
|
||||
|
||||
When you invoke GNU CC, it normally does preprocessing, compilation,
|
||||
assembly and linking. File names which end in `.c' are taken as C
|
||||
source to be preprocessed and compiled; file names ending in `.i' are
|
||||
taken as preprocessor output to be compiled; compiler output files plus
|
||||
any input files with names ending in `.s' are assembled; then the
|
||||
resulting object files, plus any other input files, are linked together
|
||||
to produce an executable.
|
||||
|
||||
Command options allow you to stop this process at an intermediate
|
||||
stage. For example, the `-c' option says not to run the linker. Then
|
||||
the output consists of object files output by the assembler.
|
||||
|
||||
Other command options are passed on to one stage of processing. Some
|
||||
options control the preprocessor and others the compiler itself. Yet
|
||||
other options control the assembler and linker; these are not documented
|
||||
here, but you rarely need to use any of them.
|
||||
|
||||
Here are the options to control the overall compilation process,
|
||||
including those that say whether to link, whether to assemble, and so
|
||||
on.
|
||||
|
||||
`-o FILE'
|
||||
Place output in file FILE. This applies regardless to whatever
|
||||
sort of output is being produced, whether it be an executable file,
|
||||
an object file, an assembler file or preprocessed C code.
|
||||
|
||||
If `-o' is not specified, the default is to put an executable file
|
||||
in `a.out', the object file `SOURCE.c' in `SOURCE.o', an assembler
|
||||
file in `SOURCE.s', and preprocessed C on standard output.
|
||||
|
||||
`-c'
|
||||
Compile or assemble the source files, but do not link. Produce
|
||||
object files with names made by replacing `.c' or `.s' with `.o'
|
||||
at the end of the input file names. Do nothing at all for object
|
||||
files specified as input.
|
||||
|
||||
`-S'
|
||||
Compile into assembler code but do not assemble. The assembler
|
||||
output file name is made by replacing `.c' with `.s' at the end of
|
||||
the input file name. Do nothing at all for assembler source files
|
||||
or object files specified as input.
|
||||
|
||||
`-E'
|
||||
Run only the C preprocessor. Preprocess all the C source files
|
||||
specified and output the results to standard output.
|
||||
|
||||
`-v'
|
||||
Compiler driver program prints the commands it executes as it runs
|
||||
the preprocessor, compiler proper, assembler and linker. Some of
|
||||
these are directed to print their own version numbers.
|
||||
|
||||
`-pipe'
|
||||
Use pipes rather than temporary files for communication between the
|
||||
various stages of compilation. This fails to work on some systems
|
||||
where the assembler is unable to read from a pipe; but the GNU
|
||||
assembler has no trouble.
|
||||
|
||||
`-BPREFIX'
|
||||
Compiler driver program tries PREFIX as a prefix for each program
|
||||
it tries to run. These programs are `cpp', `cc1', `as' and `ld'.
|
||||
|
||||
For each subprogram to be run, the compiler driver first tries the
|
||||
`-B' prefix, if any. If that name is not found, or if `-B' was
|
||||
not specified, the driver tries two standard prefixes, which are
|
||||
`/usr/lib/gcc-' and `/usr/local/lib/gcc-'. If neither of those
|
||||
results in a file name that is found, the unmodified program name
|
||||
is searched for using the directories specified in your `PATH'
|
||||
environment variable.
|
||||
|
||||
The run-time support file `gnulib' is also searched for using the
|
||||
`-B' prefix, if needed. If it is not found there, the two
|
||||
standard prefixes above are tried, and that is all. The file is
|
||||
left out of the link if it is not found by those means. Most of
|
||||
the time, on most machines, you can do without it.
|
||||
|
||||
You can get a similar result from the environment variable;
|
||||
`GCC_EXEC_PREFIX' if it is defined, its value is used as a prefix
|
||||
in the same way. If both the `-B' option and the
|
||||
`GCC_EXEC_PREFIX' variable are present, the `-B' option is used
|
||||
first and the environment variable value second.
|
||||
|
||||
`-bPREFIX'
|
||||
The argument PREFIX is used as a second prefix for the compiler
|
||||
executables and libraries. This prefix is optional: the compiler
|
||||
tries each file first with it, then without it. This prefix
|
||||
follows the prefix specified with `-B' or the default prefixes.
|
||||
|
||||
Thus, `-bvax- -Bcc/' in the presence of environment variable
|
||||
`GCC_EXEC_PREFIX' with definition `/u/foo/' causes GNU CC to try
|
||||
the following file names for the preprocessor executable:
|
||||
|
||||
cc/vax-cpp
|
||||
cc/cpp
|
||||
/u/foo/vax-cpp
|
||||
/u/foo/cpp
|
||||
/usr/local/lib/gcc-vax-cpp
|
||||
/usr/local/lib/gcc-cpp
|
||||
/usr/lib/gcc-vax-cpp
|
||||
/usr/lib/gcc-cpp
|
||||
|
||||
These options control the details of C compilation itself.
|
||||
|
||||
`-ansi'
|
||||
Support all ANSI standard C programs.
|
||||
|
||||
This turns off certain features of GNU C that are incompatible with
|
||||
ANSI C, such as the `asm', `inline' and `typeof' keywords, and
|
||||
predefined macros such as `unix' and `vax' that identify the type
|
||||
of system you are using. It also enables the undesirable and
|
||||
rarely used ANSI trigraph feature.
|
||||
|
||||
The alternate keywords `__asm__', `__inline__' and `__typeof__'
|
||||
continue to work despite `-ansi'. You would not want to use them
|
||||
in an ANSI C program, of course, but it useful to put them in
|
||||
header files that might be included in compilations done with
|
||||
`-ansi'. Alternate predefined macros such as `__unix__' and
|
||||
`__vax__' are also available, with or without `-ansi'.
|
||||
|
||||
The `-ansi' option does not cause non-ANSI programs to be rejected
|
||||
gratuitously. For that, `-pedantic' is required in addition to
|
||||
`-ansi'.
|
||||
|
||||
The macro `__STRICT_ANSI__' is predefined when the `-ansi' option
|
||||
is used. Some header files may notice this macro and refrain from
|
||||
declaring certain functions or defining certain macros that the
|
||||
ANSI standard doesn't call for; this is to avoid interfering with
|
||||
any programs that might use these names for other things.
|
||||
|
||||
`-traditional'
|
||||
Attempt to support some aspects of traditional C compilers.
|
||||
Specifically:
|
||||
|
||||
* All `extern' declarations take effect globally even if they
|
||||
are written inside of a function definition. This includes
|
||||
implicit declarations of functions.
|
||||
|
||||
* The keywords `typeof', `inline', `signed', `const' and
|
||||
`volatile' are not recognized. (You can still use the
|
||||
alternative keywords such as `__typeof__', `__inline__', and
|
||||
so on.)
|
||||
|
||||
* Comparisons between pointers and integers are always allowed.
|
||||
|
||||
* Integer types `unsigned short' and `unsigned char' promote to
|
||||
`unsigned int'.
|
||||
|
||||
* Out-of-range floating point literals are not an error.
|
||||
|
||||
* String "constants" are not necessarily constant; they are
|
||||
stored in writable space, and identical looking constants are
|
||||
allocated separately.
|
||||
|
||||
* All automatic variables not declared `register' are preserved
|
||||
by `longjmp'. Ordinarily, GNU C follows ANSI C: automatic
|
||||
variables not declared `volatile' may be clobbered.
|
||||
|
||||
* In the preprocessor, comments convert to nothing at all,
|
||||
rather than to a space. This allows traditional token
|
||||
concatenation.
|
||||
|
||||
* In the preprocessor, macro arguments are recognized within
|
||||
string constants in a macro definition (and their values are
|
||||
stringified, though without additional quote marks, when they
|
||||
appear in such a context). The preprocessor always considers
|
||||
a string constant to end at a newline.
|
||||
|
||||
* The predefined macro `__STDC__' is not defined when you use
|
||||
`-traditional', but `__GNUC__' is (since the GNU extensions
|
||||
which `__GNUC__' indicates are not affected by
|
||||
`-traditional'). If you need to write header files that work
|
||||
differently depending on whether `-traditional' is in use, by
|
||||
testing both of these predefined macros you can distinguish
|
||||
four situations: GNU C, traditional GNU C, other ANSI C
|
||||
compilers, and other old C compilers.
|
||||
|
||||
`-O'
|
||||
Optimize. Optimizing compilation takes somewhat more time, and a
|
||||
lot more memory for a large function.
|
||||
|
||||
Without `-O', the compiler's goal is to reduce the cost of
|
||||
compilation and to make debugging produce the expected results.
|
||||
Statements are independent: if you stop the program with a
|
||||
breakpoint between statements, you can then assign a new value to
|
||||
any variable or change the program counter to any other statement
|
||||
in the function and get exactly the results you would expect from
|
||||
the source code.
|
||||
|
||||
Without `-O', only variables declared `register' are allocated in
|
||||
registers. The resulting compiled code is a little worse than
|
||||
produced by PCC without `-O'.
|
||||
|
||||
With `-O', the compiler tries to reduce code size and execution
|
||||
time.
|
||||
|
||||
Some of the `-f' options described below turn specific kinds of
|
||||
optimization on or off.
|
||||
|
||||
`-g'
|
||||
Produce debugging information in the operating system's native
|
||||
format (for DBX or SDB). GDB also can work with this debugging
|
||||
information.
|
||||
|
||||
Unlike most other C compilers, GNU CC allows you to use `-g' with
|
||||
`-O'. The shortcuts taken by optimized code may occasionally
|
||||
produce surprising results: some variables you declared may not
|
||||
exist at all; flow of control may briefly move where you did not
|
||||
expect it; some statements may not be executed because they
|
||||
compute constant results or their values were already at hand;
|
||||
some statements may execute in different places because they were
|
||||
moved out of loops. Nevertheless it proves possible to debug
|
||||
optimized output. This makes it reasonable to use the optimizer
|
||||
for programs that might have bugs.
|
||||
|
||||
`-gg'
|
||||
Produce debugging information in the old GDB format. This is
|
||||
obsolete.
|
||||
|
||||
`-w'
|
||||
Inhibit all warning messages.
|
||||
|
||||
`-W'
|
||||
Print extra warning messages for these events:
|
||||
|
||||
* An automatic variable is used without first being initialized.
|
||||
|
||||
These warnings are possible only in optimizing compilation,
|
||||
because they require data flow information that is computed
|
||||
only when optimizing. If you don't specify `-O', you simply
|
||||
won't get these warnings.
|
||||
|
||||
These warnings occur only for variables that are candidates
|
||||
for register allocation. Therefore, they do not occur for a
|
||||
variable that is declared `volatile', or whose address is
|
||||
taken, or whose size is other than 1, 2, 4 or 8 bytes. Also,
|
||||
they do not occur for structures, unions or arrays, even when
|
||||
they are in registers.
|
||||
|
||||
Note that there may be no warning about a variable that is
|
||||
used only to compute a value that itself is never used,
|
||||
because such computations may be deleted by data flow
|
||||
analysis before the warnings are printed.
|
||||
|
||||
These warnings are made optional because GNU CC is not smart
|
||||
enough to see all the reasons why the code might be correct
|
||||
despite appearing to have an error. Here is one example of
|
||||
how this can happen:
|
||||
|
||||
{
|
||||
int x;
|
||||
switch (y)
|
||||
{
|
||||
case 1: x = 1;
|
||||
break;
|
||||
case 2: x = 4;
|
||||
break;
|
||||
case 3: x = 5;
|
||||
}
|
||||
foo (x);
|
||||
}
|
||||
|
||||
If the value of `y' is always 1, 2 or 3, then `x' is always
|
||||
initialized, but GNU CC doesn't know this. Here is another
|
||||
common case:
|
||||
|
||||
{
|
||||
int save_y;
|
||||
if (change_y) save_y = y, y = new_y;
|
||||
...
|
||||
if (change_y) y = save_y;
|
||||
}
|
||||
|
||||
This has no bug because `save_y' is used only if it is set.
|
||||
|
||||
Some spurious warnings can be avoided if you declare as
|
||||
`volatile' all the functions you use that never return. *Note
|
||||
Function Attributes::.
|
||||
|
||||
* A nonvolatile automatic variable might be changed by a call to
|
||||
`longjmp'. These warnings as well are possible only in
|
||||
optimizing compilation.
|
||||
|
||||
The compiler sees only the calls to `setjmp'. It cannot know
|
||||
where `longjmp' will be called; in fact, a signal handler
|
||||
could call it at any point in the code. As a result, you may
|
||||
get a warning even when there is in fact no problem because
|
||||
`longjmp' cannot in fact be called at the place which would
|
||||
cause a problem.
|
||||
|
||||
* A function can return either with or without a value.
|
||||
(Falling off the end of the function body is considered
|
||||
returning without a value.) For example, this function would
|
||||
evoke such a warning:
|
||||
|
||||
foo (a)
|
||||
{
|
||||
if (a > 0)
|
||||
return a;
|
||||
}
|
||||
|
||||
Spurious warnings can occur because GNU CC does not realize
|
||||
that certain functions (including `abort' and `longjmp') will
|
||||
never return.
|
||||
|
||||
* An expression-statement contains no side effects.
|
||||
|
||||
In the future, other useful warnings may also be enabled by this
|
||||
option.
|
||||
|
||||
`-Wimplicit'
|
||||
Warn whenever a function is implicitly declared.
|
||||
|
||||
`-Wreturn-type'
|
||||
Warn whenever a function is defined with a return-type that
|
||||
defaults to `int'. Also warn about any `return' statement with no
|
||||
return-value in a function whose return-type is not `void'.
|
||||
|
||||
`-Wunused'
|
||||
Warn whenever a local variable is unused aside from its
|
||||
declaration, whenever a function is declared static but never
|
||||
defined, and whenever a statement computes a result that is
|
||||
explicitly not used.
|
||||
|
||||
`-Wswitch'
|
||||
Warn whenever a `switch' statement has an index of enumeral type
|
||||
and lacks a `case' for one or more of the named codes of that
|
||||
enumeration. (The presence of a `default' label prevents this
|
||||
warning.) `case' labels outside the enumeration range also
|
||||
provoke warnings when this option is used.
|
||||
|
||||
`-Wcomment'
|
||||
Warn whenever a comment-start sequence `/*' appears in a comment.
|
||||
|
||||
`-Wtrigraphs'
|
||||
Warn if any trigraphs are encountered (assuming they are enabled).
|
||||
|
||||
`-Wall'
|
||||
All of the above `-W' options combined. These are all the options
|
||||
which pertain to usage that we recommend avoiding and that we
|
||||
believe is easy to avoid, even in conjunction with macros.
|
||||
|
||||
The other `-W...' options below are not implied by `-Wall' because
|
||||
certain kinds of useful macros are almost impossible to write
|
||||
without causing those warnings.
|
||||
|
||||
`-Wshadow'
|
||||
Warn whenever a local variable shadows another local variable.
|
||||
|
||||
`-Wid-clash-LEN'
|
||||
Warn whenever two distinct identifiers match in the first LEN
|
||||
characters. This may help you prepare a program that will compile
|
||||
with certain obsolete, brain-damaged compilers.
|
||||
|
||||
`-Wpointer-arith'
|
||||
Warn about anything that depends on the "size of" a function type
|
||||
or of `void'. GNU C assigns these types a size of 1, for
|
||||
convenience in calculations with `void *' pointers and pointers to
|
||||
functions.
|
||||
|
||||
`-Wcast-qual'
|
||||
Warn whenever a pointer is cast so as to remove a type qualifier
|
||||
from the target type. For example, warn if a `const char *' is
|
||||
cast to an ordinary `char *'.
|
||||
|
||||
`-Wwrite-strings'
|
||||
Give string constants the type `const char[LENGTH]' so that
|
||||
copying the address of one into a non-`const' `char *' pointer
|
||||
will get a warning. These warnings will help you find at compile
|
||||
time code that can try to write into a string constant, but only
|
||||
if you have been very careful about using `const' in declarations
|
||||
and prototypes. Otherwise, it will just be a nuisance; this is
|
||||
why we did not make `-Wall' request these warnings.
|
||||
|
||||
`-p'
|
||||
Generate extra code to write profile information suitable for the
|
||||
analysis program `prof'.
|
||||
|
||||
`-pg'
|
||||
Generate extra code to write profile information suitable for the
|
||||
analysis program `gprof'.
|
||||
|
||||
`-a'
|
||||
Generate extra code to write profile information for basic blocks,
|
||||
which will record the number of times each basic block is
|
||||
executed. This data could be analyzed by a program like `tcov'.
|
||||
Note, however, that the format of the data is not what `tcov'
|
||||
expects. Eventually GNU `gprof' should be extended to process
|
||||
this data.
|
||||
|
||||
`-lLIBRARY'
|
||||
Search a standard list of directories for a library named LIBRARY,
|
||||
which is actually a file named `libLIBRARY.a'. The linker uses
|
||||
this file as if it had been specified precisely by name.
|
||||
|
||||
The directories searched include several standard system
|
||||
directories plus any that you specify with `-L'.
|
||||
|
||||
Normally the files found this way are library files--archive files
|
||||
whose members are object files. The linker handles an archive
|
||||
file by scanning through it for members which define symbols that
|
||||
have so far been referenced but not defined. But if the file that
|
||||
is found is an ordinary object file, it is linked in the usual
|
||||
fashion. The only difference between using an `-l' option and
|
||||
specifying a file name is that `-l' searches several directories.
|
||||
|
||||
`-LDIR'
|
||||
Add directory DIR to the list of directories to be searched for
|
||||
`-l'.
|
||||
|
||||
`-nostdlib'
|
||||
Don't use the standard system libraries and startup files when
|
||||
linking. Only the files you specify will be passed to the linker.
|
||||
|
||||
`-mMACHINESPEC'
|
||||
Machine-dependent option specifying something about the type of
|
||||
target machine. These options are defined by the macro
|
||||
`TARGET_SWITCHES' in the machine description. The default for the
|
||||
options is also defined by that macro, which enables you to change
|
||||
the defaults.
|
||||
|
||||
These are the `-m' options defined in the 68000 machine
|
||||
description:
|
||||
|
||||
`-m68020'
|
||||
`-mc68020'
|
||||
Generate output for a 68020 (rather than a 68000). This is
|
||||
the default if you use the unmodified sources.
|
||||
|
||||
`-m68000'
|
||||
`-mc68000'
|
||||
Generate output for a 68000 (rather than a 68020).
|
||||
|
||||
`-m68881'
|
||||
Generate output containing 68881 instructions for floating
|
||||
point. This is the default if you use the unmodified sources.
|
||||
|
||||
`-mfpa'
|
||||
Generate output containing Sun FPA instructions for floating
|
||||
point.
|
||||
|
||||
`-msoft-float'
|
||||
Generate output containing library calls for floating point.
|
||||
|
||||
`-mshort'
|
||||
Consider type `int' to be 16 bits wide, like `short int'.
|
||||
|
||||
`-mnobitfield'
|
||||
Do not use the bit-field instructions. `-m68000' implies
|
||||
`-mnobitfield'.
|
||||
|
||||
`-mbitfield'
|
||||
Do use the bit-field instructions. `-m68020' implies
|
||||
`-mbitfield'. This is the default if you use the unmodified
|
||||
sources.
|
||||
|
||||
`-mrtd'
|
||||
Use a different function-calling convention, in which
|
||||
functions that take a fixed number of arguments return with
|
||||
the `rtd' instruction, which pops their arguments while
|
||||
returning. This saves one instruction in the caller since
|
||||
there is no need to pop the arguments there.
|
||||
|
||||
This calling convention is incompatible with the one normally
|
||||
used on Unix, so you cannot use it if you need to call
|
||||
libraries compiled with the Unix compiler.
|
||||
|
||||
Also, you must provide function prototypes for all functions
|
||||
that take variable numbers of arguments (including `printf');
|
||||
otherwise incorrect code will be generated for calls to those
|
||||
functions.
|
||||
|
||||
In addition, seriously incorrect code will result if you call
|
||||
a function with too many arguments. (Normally, extra
|
||||
arguments are harmlessly ignored.)
|
||||
|
||||
The `rtd' instruction is supported by the 68010 and 68020
|
||||
processors, but not by the 68000.
|
||||
|
||||
These `-m' options are defined in the Vax machine description:
|
||||
|
||||
`-munix'
|
||||
Do not output certain jump instructions (`aobleq' and so on)
|
||||
that the Unix assembler for the Vax cannot handle across long
|
||||
ranges.
|
||||
|
||||
`-mgnu'
|
||||
Do output those jump instructions, on the assumption that you
|
||||
will assemble with the GNU assembler.
|
||||
|
||||
`-mg'
|
||||
Output code for g-format floating point numbers instead of
|
||||
d-format.
|
||||
|
||||
These `-m' switches are supported on the Sparc:
|
||||
|
||||
`-mfpu'
|
||||
Generate output containing floating point instructions. This
|
||||
is the default if you use the unmodified sources.
|
||||
|
||||
`-mno-epilogue'
|
||||
Generate separate return instructions for `return' statements.
|
||||
This has both advantages and disadvantages; I don't recall
|
||||
what they are.
|
||||
|
||||
These `-m' options are defined in the Convex machine description:
|
||||
|
||||
`-mc1'
|
||||
Generate output for a C1. This is the default when the
|
||||
compiler is configured for a C1.
|
||||
|
||||
`-mc2'
|
||||
Generate output for a C2. This is the default when the
|
||||
compiler is configured for a C2.
|
||||
|
||||
`-margcount'
|
||||
Generate code which puts an argument count in the word
|
||||
preceding each argument list. Some nonportable Convex and
|
||||
Vax programs need this word. (Debuggers don't; this info is
|
||||
in the symbol table.)
|
||||
|
||||
`-mnoargcount'
|
||||
Omit the argument count word. This is the default if you use
|
||||
the unmodified sources.
|
||||
|
||||
`-fFLAG'
|
||||
Specify machine-independent flags. Most flags have both positive
|
||||
and negative forms; the negative form of `-ffoo' would be
|
||||
`-fno-foo'. In the table below, only one of the forms is
|
||||
listed--the one which is not the default. You can figure out the
|
||||
other form by either removing `no-' or adding it.
|
||||
|
||||
`-fpcc-struct-return'
|
||||
Use the same convention for returning `struct' and `union'
|
||||
values that is used by the usual C compiler on your system.
|
||||
This convention is less efficient for small structures, and
|
||||
on many machines it fails to be reentrant; but it has the
|
||||
advantage of allowing intercallability between GCC-compiled
|
||||
code and PCC-compiled code.
|
||||
|
||||
`-ffloat-store'
|
||||
Do not store floating-point variables in registers. This
|
||||
prevents undesirable excess precision on machines such as the
|
||||
68000 where the floating registers (of the 68881) keep more
|
||||
precision than a `double' is supposed to have.
|
||||
|
||||
For most programs, the excess precision does only good, but a
|
||||
few programs rely on the precise definition of IEEE floating
|
||||
point. Use `-ffloat-store' for such programs.
|
||||
|
||||
`-fno-asm'
|
||||
Do not recognize `asm', `inline' or `typeof' as a keyword.
|
||||
These words may then be used as identifiers. You can use
|
||||
`__asm__', `__inline__' and `__typeof__' instead.
|
||||
|
||||
`-fno-defer-pop'
|
||||
Always pop the arguments to each function call as soon as that
|
||||
function returns. Normally the compiler (when optimizing)
|
||||
lets arguments accumulate on the stack for several function
|
||||
calls and pops them all at once.
|
||||
|
||||
`-fstrength-reduce'
|
||||
Perform the optimizations of loop strength reduction and
|
||||
elimination of iteration variables.
|
||||
|
||||
`-fcombine-regs'
|
||||
Allow the combine pass to combine an instruction that copies
|
||||
one register into another. This might or might not produce
|
||||
better code when used in addition to `-O'. I am interested in
|
||||
hearing about the difference this makes.
|
||||
|
||||
`-fforce-mem'
|
||||
Force memory operands to be copied into registers before doing
|
||||
arithmetic on them. This may produce better code by making
|
||||
all memory references potential common subexpressions. When
|
||||
they are not common subexpressions, instruction combination
|
||||
should eliminate the separate register-load. I am interested
|
||||
in hearing about the difference this makes.
|
||||
|
||||
`-fforce-addr'
|
||||
Force memory address constants to be copied into registers
|
||||
before doing arithmetic on them. This may produce better
|
||||
code just as `-fforce-mem' may. I am interested in hearing
|
||||
about the difference this makes.
|
||||
|
||||
`-fomit-frame-pointer'
|
||||
Don't keep the frame pointer in a register for functions that
|
||||
don't need one. This avoids the instructions to save, set up
|
||||
and restore frame pointers; it also makes an extra register
|
||||
available in many functions. *It also makes debugging
|
||||
impossible.*
|
||||
|
||||
On some machines, such as the Vax, this flag has no effect,
|
||||
because the standard calling sequence automatically handles
|
||||
the frame pointer and nothing is saved by pretending it
|
||||
doesn't exist. The machine-description macro
|
||||
`FRAME_POINTER_REQUIRED' controls whether a target machine
|
||||
supports this flag. *Note Registers::.
|
||||
|
||||
`-finline-functions'
|
||||
Integrate all simple functions into their callers. The
|
||||
compiler heuristically decides which functions are simple
|
||||
enough to be worth integrating in this way.
|
||||
|
||||
If all calls to a given function are integrated, and the
|
||||
function is declared `static', then the function is normally
|
||||
not output as assembler code in its own right.
|
||||
|
||||
`-fcaller-saves'
|
||||
Enable values to be allocated in registers that will be
|
||||
clobbered by function calls, by emitting extra instructions
|
||||
to save and restore the registers around such calls. Such
|
||||
allocation is done only when it seems to result in better
|
||||
code than would otherwise be produced.
|
||||
|
||||
This option is enabled by default on certain machines,
|
||||
usually those which have no call-preserved registers to use
|
||||
instead.
|
||||
|
||||
Don't use `-fcaller-saves' together with
|
||||
`-fomit-frame-pointer'. This combination does not work.
|
||||
|
||||
`-fkeep-inline-functions'
|
||||
Even if all calls to a given function are integrated, and the
|
||||
function is declared `static', nevertheless output a separate
|
||||
run-time callable version of the function.
|
||||
|
||||
`-fwritable-strings'
|
||||
Store string constants in the writable data segment and don't
|
||||
uniquize them. This is for compatibility with old programs
|
||||
which assume they can write into string constants.
|
||||
`-traditional' also has this effect.
|
||||
|
||||
Writing into string constants is a very bad idea; "constants"
|
||||
should be constant.
|
||||
|
||||
`-fcond-mismatch'
|
||||
Allow conditional expressions with mismatched types in the
|
||||
second and third arguments. The value of such an expression
|
||||
is void.
|
||||
|
||||
`-fno-function-cse'
|
||||
Do not put function addresses in registers; make each
|
||||
instruction that calls a constant function contain the
|
||||
function's address explicitly.
|
||||
|
||||
This option results in less efficient code, but some strange
|
||||
hacks that alter the assembler output may be confused by the
|
||||
optimizations performed when this option is not used.
|
||||
|
||||
`-fvolatile'
|
||||
Consider all memory references through pointers to be
|
||||
volatile.
|
||||
|
||||
`-fshared-data'
|
||||
Requests that the data and non-`const' variables of this
|
||||
compilation be shared data rather than private data. The
|
||||
distinction makes sense only on certain operating systems,
|
||||
where shared data is shared between processes running the
|
||||
same program, while private data exists in one copy per
|
||||
process.
|
||||
|
||||
`-funsigned-char'
|
||||
Let the type `char' be the unsigned, like `unsigned char'.
|
||||
|
||||
Each kind of machine has a default for what `char' should be.
|
||||
It is either like `unsigned char' by default or like `signed
|
||||
char' by default. (Actually, at present, the default is
|
||||
always signed.)
|
||||
|
||||
The type `char' is always a distinct type from either `signed
|
||||
char' or `unsigned char', even though its behavior is always
|
||||
just like one of those two.
|
||||
|
||||
Note that this is equivalent to `-fno-signed-char', which is
|
||||
the negative form of `-fsigned-char'.
|
||||
|
||||
`-fsigned-char'
|
||||
Let the type `char' be signed, like `signed char'.
|
||||
|
||||
Note that this is equivalent to `-fno-unsigned-char', which is
|
||||
the negative form of `-funsigned-char'.
|
||||
|
||||
`-fdelayed-branch'
|
||||
If supported for the target machine, attempt to reorder
|
||||
instructions to exploit instruction slots available after
|
||||
delayed branch instructions.
|
||||
|
||||
`-ffixed-REG'
|
||||
Treat the register named REG as a fixed register; generated
|
||||
code should never refer to it (except perhaps as a stack
|
||||
pointer, frame pointer or in some other fixed role).
|
||||
|
||||
REG must be the name of a register. The register names
|
||||
accepted are machine-specific and are defined in the
|
||||
`REGISTER_NAMES' macro in the machine description macro file.
|
||||
|
||||
This flag does not have a negative form, because it specifies
|
||||
a three-way choice.
|
||||
|
||||
`-fcall-used-REG'
|
||||
Treat the register named REG as an allocatable register that
|
||||
is clobbered by function calls. It may be allocated for
|
||||
temporaries or variables that do not live across a call.
|
||||
Functions compiled this way will not save and restore the
|
||||
register REG.
|
||||
|
||||
Use of this flag for a register that has a fixed pervasive
|
||||
role in the machine's execution model, such as the stack
|
||||
pointer or frame pointer, will produce disastrous results.
|
||||
|
||||
This flag does not have a negative form, because it specifies
|
||||
a three-way choice.
|
||||
|
||||
`-fcall-saved-REG'
|
||||
Treat the register named REG as an allocatable register saved
|
||||
by functions. It may be allocated even for temporaries or
|
||||
variables that live across a call. Functions compiled this
|
||||
way will save and restore the register REG if they use it.
|
||||
|
||||
Use of this flag for a register that has a fixed pervasive
|
||||
role in the machine's execution model, such as the stack
|
||||
pointer or frame pointer, will produce disastrous results.
|
||||
|
||||
A different sort of disaster will result from the use of this
|
||||
flag for a register in which function values may be returned.
|
||||
|
||||
This flag does not have a negative form, because it specifies
|
||||
a three-way choice.
|
||||
|
||||
`-dLETTERS'
|
||||
Says to make debugging dumps at times specified by LETTERS. Here
|
||||
are the possible letters:
|
||||
|
||||
`r'
|
||||
Dump after RTL generation.
|
||||
|
||||
`j'
|
||||
Dump after first jump optimization.
|
||||
|
||||
`s'
|
||||
Dump after CSE (including the jump optimization that sometimes
|
||||
follows CSE).
|
||||
|
||||
`L'
|
||||
Dump after loop optimization.
|
||||
|
||||
`f'
|
||||
Dump after flow analysis.
|
||||
|
||||
`c'
|
||||
Dump after instruction combination.
|
||||
|
||||
`l'
|
||||
Dump after local register allocation.
|
||||
|
||||
`g'
|
||||
Dump after global register allocation.
|
||||
|
||||
`d'
|
||||
Dump after delayed branch scheduling.
|
||||
|
||||
`J'
|
||||
Dump after last jump optimization.
|
||||
|
||||
`m'
|
||||
Print statistics on memory usage, at the end of the run.
|
||||
|
||||
`-pedantic'
|
||||
Issue all the warnings demanded by strict ANSI standard C; reject
|
||||
all programs that use forbidden extensions.
|
||||
|
||||
Valid ANSI standard C programs should compile properly with or
|
||||
without this option (though a rare few will require `-ansi').
|
||||
However, without this option, certain GNU extensions and
|
||||
traditional C features are supported as well. With this option,
|
||||
they are rejected. There is no reason to use this option; it
|
||||
exists only to satisfy pedants.
|
||||
|
||||
`-pedantic' does not cause warning messages for use of the
|
||||
alternate keywords whose names begin and end with `__'. *Note
|
||||
Alternate Keywords::.
|
||||
|
||||
`-static'
|
||||
On Suns running version 4, this prevents linking with the shared
|
||||
libraries. (`-g' has the same effect.)
|
||||
|
||||
These options control the C preprocessor, which is run on each C
|
||||
source file before actual compilation. If you use the `-E' option,
|
||||
nothing is done except C preprocessing. Some of these options make
|
||||
sense only together with `-E' because they request preprocessor output
|
||||
that is not suitable for actual compilation.
|
||||
|
||||
`-C'
|
||||
Tell the preprocessor not to discard comments. Used with the `-E'
|
||||
option.
|
||||
|
||||
`-IDIR'
|
||||
Search directory DIR for include files.
|
||||
|
||||
`-I-'
|
||||
Any directories specified with `-I' options before the `-I-'
|
||||
option are searched only for the case of `#include "FILE"'; they
|
||||
are not searched for `#include <FILE>'.
|
||||
|
||||
If additional directories are specified with `-I' options after
|
||||
the `-I-', these directories are searched for all `#include'
|
||||
directives. (Ordinarily *all* `-I' directories are used this way.)
|
||||
|
||||
In addition, the `-I-' option inhibits the use of the current
|
||||
directory (where the current input file came from) as the first
|
||||
search directory for `#include "FILE"'. There is no way to
|
||||
override this effect of `-I-'. With `-I.' you can specify
|
||||
searching the directory which was current when the compiler was
|
||||
invoked. That is not exactly the same as what the preprocessor
|
||||
does by default, but it is often satisfactory.
|
||||
|
||||
`-I-' does not inhibit the use of the standard system directories
|
||||
for header files. Thus, `-I-' and `-nostdinc' are independent.
|
||||
|
||||
`-i FILE'
|
||||
Process FILE as input, discarding the resulting output, before
|
||||
processing the regular input file. Because the output generated
|
||||
from FILE is discarded, the only effect of `-i FILE' is to make
|
||||
the macros defined in FILE available for use in the main input.
|
||||
|
||||
`-nostdinc'
|
||||
Do not search the standard system directories for header files.
|
||||
Only the directories you have specified with `-I' options (and the
|
||||
current directory, if appropriate) are searched.
|
||||
|
||||
Between `-nostdinc' and `-I-', you can eliminate all directories
|
||||
from the search path except those you specify.
|
||||
|
||||
`-M'
|
||||
Tell the preprocessor to output a rule suitable for `make'
|
||||
describing the dependencies of each object file. For each source
|
||||
file, the preprocessor outputs one `make'-rule whose target is the
|
||||
object file name for that source file and whose dependencies are
|
||||
all the files `#include'd in it. This rule may be a single line
|
||||
or may be continued with `\'-newline if it is long.
|
||||
|
||||
`-M' implies `-E'.
|
||||
|
||||
`-MM'
|
||||
Like `-M' but the output mentions only the user-header files
|
||||
included with `#include "FILE"'. System header files included
|
||||
with `#include <FILE>' are omitted.
|
||||
|
||||
`-MM' implies `-E'.
|
||||
|
||||
`-DMACRO'
|
||||
Define macro MACRO with the string `1' as its definition.
|
||||
|
||||
`-DMACRO=DEFN'
|
||||
Define macro MACRO as DEFN.
|
||||
|
||||
`-UMACRO'
|
||||
Undefine macro MACRO.
|
||||
|
||||
`-trigraphs'
|
||||
Support ANSI C trigraphs. You don't want to know about this
|
||||
brain-damage. The `-ansi' option also has this effect.
|
||||
|
||||
|
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,952 @@
|
|||
This is Info file gcc.info, produced by Makeinfo-1.47 from the input
|
||||
file gcc.texinfo.
|
||||
|
||||
This file documents the use and the internals of the GNU compiler.
|
||||
|
||||
Copyright (C) 1988, 1989, 1990 Free Software Foundation, Inc.
|
||||
|
||||
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.
|
||||
|
||||
Permission is granted to copy and distribute modified versions of
|
||||
this manual under the conditions for verbatim copying, provided also
|
||||
that the sections entitled "GNU General Public License" and "Protect
|
||||
Your Freedom--Fight `Look And Feel'" are included exactly as in the
|
||||
original, and provided that the entire resulting derived work is
|
||||
distributed under the terms of a permission notice identical to this
|
||||
one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this
|
||||
manual into another language, under the above conditions for modified
|
||||
versions, except that the sections entitled "GNU General Public
|
||||
License" and "Protect Your Freedom--Fight `Look And Feel'" and this
|
||||
permission notice may be included in translations approved by the Free
|
||||
Software Foundation instead of in the original English.
|
||||
|
||||
|
||||
File: gcc.info, Node: Sharing, Prev: Calls, Up: RTL
|
||||
|
||||
Structure Sharing Assumptions
|
||||
=============================
|
||||
|
||||
The compiler assumes that certain kinds of RTL expressions are
|
||||
unique; there do not exist two distinct objects representing the same
|
||||
value. In other cases, it makes an opposite assumption: that no RTL
|
||||
expression object of a certain kind appears in more than one place in
|
||||
the containing structure.
|
||||
|
||||
These assumptions refer to a single function; except for the RTL
|
||||
objects that describe global variables and external functions, no RTL
|
||||
objects are common to two functions.
|
||||
|
||||
* Each pseudo-register has only a single `reg' object to represent
|
||||
it, and therefore only a single machine mode.
|
||||
|
||||
* For any symbolic label, there is only one `symbol_ref' object
|
||||
referring to it.
|
||||
|
||||
* There is only one `const_int' expression with value zero, and only
|
||||
one with value one.
|
||||
|
||||
* There is only one `pc' expression.
|
||||
|
||||
* There is only one `cc0' expression.
|
||||
|
||||
* There is only one `const_double' expression with mode `SFmode' and
|
||||
value zero, and only one with mode `DFmode' and value zero.
|
||||
|
||||
* No `label_ref' appears in more than one place in the RTL
|
||||
structure; in other words, it is safe to do a tree-walk of all the
|
||||
insns in the function and assume that each time a `label_ref' is
|
||||
seen it is distinct from all others that are seen.
|
||||
|
||||
* Only one `mem' object is normally created for each static variable
|
||||
or stack slot, so these objects are frequently shared in all the
|
||||
places they appear. However, separate but equal objects for these
|
||||
variables are occasionally made.
|
||||
|
||||
* When a single `asm' statement has multiple output operands, a
|
||||
distinct `asm_operands' RTX is made for each output operand.
|
||||
However, these all share the vector which contains the sequence of
|
||||
input operands. Because this sharing is used later on to test
|
||||
whether two `asm_operands' RTX's come from the same statement, the
|
||||
sharing must be guaranteed to be preserved.
|
||||
|
||||
* No RTL object appears in more than one place in the RTL structure
|
||||
except as described above. Many passes of the compiler rely on
|
||||
this by assuming that they can modify RTL objects in place without
|
||||
unwanted side-effects on other insns.
|
||||
|
||||
* During initial RTL generation, shared structure is freely
|
||||
introduced. After all the RTL for a function has been generated,
|
||||
all shared structure is copied by `unshare_all_rtl' in
|
||||
`emit-rtl.c', after which the above rules are guaranteed to be
|
||||
followed.
|
||||
|
||||
* During the combiner pass, shared structure with an insn can exist
|
||||
temporarily. However, the shared structure is copied before the
|
||||
combiner is finished with the insn. This is done by
|
||||
`copy_substitutions' in `combine.c'.
|
||||
|
||||
|
||||
File: gcc.info, Node: Machine Desc, Next: Machine Macros, Prev: RTL, Up: Top
|
||||
|
||||
Machine Descriptions
|
||||
********************
|
||||
|
||||
A machine description has two parts: a file of instruction patterns
|
||||
(`.md' file) and a C header file of macro definitions.
|
||||
|
||||
The `.md' file for a target machine contains a pattern for each
|
||||
instruction that the target machine supports (or at least each
|
||||
instruction that is worth telling the compiler about). It may also
|
||||
contain comments. A semicolon causes the rest of the line to be a
|
||||
comment, unless the semicolon is inside a quoted string.
|
||||
|
||||
See the next chapter for information on the C header file.
|
||||
|
||||
* Menu:
|
||||
|
||||
* Patterns:: How to write instruction patterns.
|
||||
* Example:: An explained example of a `define_insn' pattern.
|
||||
* RTL Template:: The RTL template defines what insns match a pattern.
|
||||
* Output Template:: The output template says how to make assembler code
|
||||
from such an insn.
|
||||
* Output Statement:: For more generality, write C code to output
|
||||
the assembler code.
|
||||
* Constraints:: When not all operands are general operands.
|
||||
* Standard Names:: Names mark patterns to use for code generation.
|
||||
* Pattern Ordering:: When the order of patterns makes a difference.
|
||||
* Dependent Patterns:: Having one pattern may make you need another.
|
||||
* Jump Patterns:: Special considerations for patterns for jump insns.
|
||||
* Peephole Definitions::Defining machine-specific peephole optimizations.
|
||||
* Expander Definitions::Generating a sequence of several RTL insns
|
||||
for a standard operation.
|
||||
|
||||
|
||||
File: gcc.info, Node: Patterns, Next: Example, Prev: Machine Desc, Up: Machine Desc
|
||||
|
||||
Everything about Instruction Patterns
|
||||
=====================================
|
||||
|
||||
Each instruction pattern contains an incomplete RTL expression, with
|
||||
pieces to be filled in later, operand constraints that restrict how the
|
||||
pieces can be filled in, and an output pattern or C code to generate
|
||||
the assembler output, all wrapped up in a `define_insn' expression.
|
||||
|
||||
A `define_insn' is an RTL expression containing four or five
|
||||
operands:
|
||||
|
||||
1. An optional name. The presence of a name indicate that this
|
||||
instruction pattern can perform a certain standard job for the
|
||||
RTL-generation pass of the compiler. This pass knows certain
|
||||
names and will use the instruction patterns with those names, if
|
||||
the names are defined in the machine description.
|
||||
|
||||
The absence of a name is indicated by writing an empty string
|
||||
where the name should go. Nameless instruction patterns are never
|
||||
used for generating RTL code, but they may permit several simpler
|
||||
insns to be combined later on.
|
||||
|
||||
Names that are not thus known and used in RTL-generation have no
|
||||
effect; they are equivalent to no name at all.
|
||||
|
||||
2. The "RTL template" (*note RTL Template::.) is a vector of
|
||||
incomplete RTL expressions which show what the instruction should
|
||||
look like. It is incomplete because it may contain `match_operand'
|
||||
and `match_dup' expressions that stand for operands of the
|
||||
instruction.
|
||||
|
||||
If the vector has only one element, that element is the template
|
||||
for the instruction pattern. If the vector has multiple elements,
|
||||
then the instruction pattern is a `parallel' expression containing
|
||||
the elements described.
|
||||
|
||||
3. A condition. This is a string which contains a C expression that
|
||||
is the final test to decide whether an insn body matches this
|
||||
pattern.
|
||||
|
||||
For a named pattern, the condition (if present) may not depend on
|
||||
the data in the insn being matched, but only the
|
||||
target-machine-type flags. The compiler needs to test these
|
||||
conditions during initialization in order to learn exactly which
|
||||
named instructions are available in a particular run.
|
||||
|
||||
For nameless patterns, the condition is applied only when matching
|
||||
an individual insn, and only after the insn has matched the
|
||||
pattern's recognition template. The insn's operands may be found
|
||||
in the vector `operands'.
|
||||
|
||||
4. The "output template": a string that says how to output matching
|
||||
insns as assembler code. `%' in this string specifies where to
|
||||
substitute the value of an operand. *Note Output Template::.
|
||||
|
||||
When simple substitution isn't general enough, you can specify a
|
||||
piece of C code to compute the output. *Note Output Statement::.
|
||||
|
||||
5. Optionally, some "machine-specific information". The meaning of
|
||||
this information is defined only by an individual machine
|
||||
description; typically it might say whether this insn alters the
|
||||
condition codes, or how many bytes of output it generates.
|
||||
|
||||
This operand is written as a string containing a C initializer
|
||||
(complete with braces) for the structure type `INSN_MACHINE_INFO',
|
||||
whose definition is up to you (*note Misc::.).
|
||||
|
||||
|
||||
File: gcc.info, Node: Example, Next: RTL Template, Prev: Patterns, Up: Machine Desc
|
||||
|
||||
Example of `define_insn'
|
||||
========================
|
||||
|
||||
Here is an actual example of an instruction pattern, for the
|
||||
68000/68020.
|
||||
|
||||
(define_insn "tstsi"
|
||||
[(set (cc0)
|
||||
(match_operand:SI 0 "general_operand" "rm"))]
|
||||
""
|
||||
"*
|
||||
{ if (TARGET_68020 || ! ADDRESS_REG_P (operands[0]))
|
||||
return \"tstl %0\";
|
||||
return \"cmpl #0,%0\"; }")
|
||||
|
||||
This is an instruction that sets the condition codes based on the
|
||||
value of a general operand. It has no condition, so any insn whose RTL
|
||||
description has the form shown may be handled according to this
|
||||
pattern. The name `tstsi' means "test a `SImode' value" and tells the
|
||||
RTL generation pass that, when it is necessary to test such a value, an
|
||||
insn to do so can be constructed using this pattern.
|
||||
|
||||
The output control string is a piece of C code which chooses which
|
||||
output template to return based on the kind of operand and the specific
|
||||
type of CPU for which code is being generated.
|
||||
|
||||
`"rm"' is an operand constraint. Its meaning is explained below.
|
||||
|
||||
|
||||
File: gcc.info, Node: RTL Template, Next: Output Template, Prev: Example, Up: Machine Desc
|
||||
|
||||
RTL Template for Generating and Recognizing Insns
|
||||
=================================================
|
||||
|
||||
The RTL template is used to define which insns match the particular
|
||||
pattern and how to find their operands. For named patterns, the RTL
|
||||
template also says how to construct an insn from specified operands.
|
||||
|
||||
Construction involves substituting specified operands into a copy of
|
||||
the template. Matching involves determining the values that serve as
|
||||
the operands in the insn being matched. Both of these activities are
|
||||
controlled by special expression types that direct matching and
|
||||
substitution of the operands.
|
||||
|
||||
`(match_operand:M N PRED CONSTRAINT)'
|
||||
This expression is a placeholder for operand number N of the insn.
|
||||
When constructing an insn, operand number N will be substituted
|
||||
at this point. When matching an insn, whatever appears at this
|
||||
position in the insn will be taken as operand number N; but it
|
||||
must satisfy PRED or this instruction pattern will not match at
|
||||
all.
|
||||
|
||||
Operand numbers must be chosen consecutively counting from zero in
|
||||
each instruction pattern. There may be only one `match_operand'
|
||||
expression in the pattern for each operand number. Usually
|
||||
operands are numbered in the order of appearance in `match_operand'
|
||||
expressions.
|
||||
|
||||
PRED is a string that is the name of a C function that accepts two
|
||||
arguments, an expression and a machine mode. During matching, the
|
||||
function will be called with the putative operand as the expression
|
||||
and M as the mode argument. If it returns zero, this instruction
|
||||
pattern fails to match. PRED may be an empty string; then it
|
||||
means no test is to be done on the operand, so anything which
|
||||
occurs in this position is valid.
|
||||
|
||||
CONSTRAINT controls reloading and the choice of the best register
|
||||
class to use for a value, as explained later (*note
|
||||
Constraints::.).
|
||||
|
||||
People are often unclear on the difference between the constraint
|
||||
and the predicate. The predicate helps decide whether a given
|
||||
insn matches the pattern. The constraint plays no role in this
|
||||
decision; instead, it controls various decisions in the case of an
|
||||
insn which does match.
|
||||
|
||||
Most often, PRED is `"general_operand"'. This function checks
|
||||
that the putative operand is either a constant, a register or a
|
||||
memory reference, and that it is valid for mode M.
|
||||
|
||||
For an operand that must be a register, PRED should be
|
||||
`"register_operand"'. It would be valid to use
|
||||
`"general_operand"', since the reload pass would copy any
|
||||
non-register operands through registers, but this would make GNU
|
||||
CC do extra work, and it would prevent the register allocator from
|
||||
doing the best possible job.
|
||||
|
||||
For an operand that must be a constant, either PRED should be
|
||||
`"immediate_operand"', or the instruction pattern's extra
|
||||
condition should check for constants, or both. You cannot expect
|
||||
the constraints to do this work! If the constraints allow only
|
||||
constants, but the predicate allows something else, the compiler
|
||||
will crash when that case arises.
|
||||
|
||||
`(match_dup N)'
|
||||
This expression is also a placeholder for operand number N. It is
|
||||
used when the operand needs to appear more than once in the insn.
|
||||
|
||||
In construction, `match_dup' behaves exactly like `match_operand':
|
||||
the operand is substituted into the insn being constructed. But
|
||||
in matching, `match_dup' behaves differently. It assumes that
|
||||
operand number N has already been determined by a `match_operand'
|
||||
appearing earlier in the recognition template, and it matches only
|
||||
an identical-looking expression.
|
||||
|
||||
`(match_operator:M N "PREDICATE" [OPERANDS...])'
|
||||
This pattern is a kind of placeholder for a variable RTL expression
|
||||
code.
|
||||
|
||||
When constructing an insn, it stands for an RTL expression whose
|
||||
expression code is taken from that of operand N, and whose
|
||||
operands are constructed from the patterns OPERANDS.
|
||||
|
||||
When matching an expression, it matches an expression if the
|
||||
function PREDICATE returns nonzero on that expression *and* the
|
||||
patterns OPERANDS match the operands of the expression.
|
||||
|
||||
Suppose that the function `commutative_operator' is defined as
|
||||
follows, to match any expression whose operator is one of the six
|
||||
commutative arithmetic operators of RTL and whose mode is MODE:
|
||||
|
||||
int
|
||||
commutative_operator (x, mode)
|
||||
rtx x;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
enum rtx_code code = GET_CODE (x);
|
||||
if (GET_MODE (x) != mode)
|
||||
return 0;
|
||||
return (code == PLUS || code == MULT || code == UMULT
|
||||
|| code == AND || code == IOR || code == XOR);
|
||||
}
|
||||
|
||||
Then the following pattern will match any RTL expression consisting
|
||||
of a commutative operator applied to two general operands:
|
||||
|
||||
(match_operator:SI 2 "commutative_operator"
|
||||
[(match_operand:SI 3 "general_operand" "g")
|
||||
(match_operand:SI 4 "general_operand" "g")])
|
||||
|
||||
Here the vector `[OPERANDS...]' contains two patterns because the
|
||||
expressions to be matched all contain two operands.
|
||||
|
||||
When this pattern does match, the two operands of the commutative
|
||||
operator are recorded as operands 3 and 4 of the insn. (This is
|
||||
done by the two instances of `match_operand'.) Operand 2 of the
|
||||
insn will be the entire commutative expression: use `GET_CODE
|
||||
(operands[2])' to see which commutative operator was used.
|
||||
|
||||
The machine mode M of `match_operator' works like that of
|
||||
`match_operand': it is passed as the second argument to the
|
||||
predicate function, and that function is solely responsible for
|
||||
deciding whether the expression to be matched "has" that mode.
|
||||
|
||||
When constructing an insn, argument 2 of the gen-function will
|
||||
specify the operation (i.e. the expression code) for the
|
||||
expression to be made. It should be an RTL expression, whose
|
||||
expression code is copied into a new expression whose operands are
|
||||
arguments 3 and 4 of the gen-function. The subexpressions of
|
||||
argument 2 are not used; only its expression code matters.
|
||||
|
||||
There is no way to specify constraints in `match_operator'. The
|
||||
operand of the insn which corresponds to the `match_operator'
|
||||
never has any constraints because it is never reloaded as a whole.
|
||||
However, if parts of its OPERANDS are matched by `match_operand'
|
||||
patterns, those parts may have constraints of their own.
|
||||
|
||||
`(address (match_operand:M N "address_operand" ""))'
|
||||
This complex of expressions is a placeholder for an operand number
|
||||
N in a "load address" instruction: an operand which specifies a
|
||||
memory location in the usual way, but for which the actual operand
|
||||
value used is the address of the location, not the contents of the
|
||||
location.
|
||||
|
||||
`address' expressions never appear in RTL code, only in machine
|
||||
descriptions. And they are used only in machine descriptions that
|
||||
do not use the operand constraint feature. When operand
|
||||
constraints are in use, the letter `p' in the constraint serves
|
||||
this purpose.
|
||||
|
||||
M is the machine mode of the *memory location being addressed*,
|
||||
not the machine mode of the address itself. That mode is always
|
||||
the same on a given target machine (it is `Pmode', which normally
|
||||
is `SImode'), so there is no point in mentioning it; thus, no
|
||||
machine mode is written in the `address' expression. If some day
|
||||
support is added for machines in which addresses of different
|
||||
kinds of objects appear differently or are used differently (such
|
||||
as the PDP-10), different formats would perhaps need different
|
||||
machine modes and these modes might be written in the `address'
|
||||
expression.
|
||||
|
||||
|
||||
File: gcc.info, Node: Output Template, Next: Output Statement, Prev: RTL Template, Up: Machine Desc
|
||||
|
||||
Output Templates and Operand Substitution
|
||||
=========================================
|
||||
|
||||
The "output template" is a string which specifies how to output the
|
||||
assembler code for an instruction pattern. Most of the template is a
|
||||
fixed string which is output literally. The character `%' is used to
|
||||
specify where to substitute an operand; it can also be used to identify
|
||||
places where different variants of the assembler require different
|
||||
syntax.
|
||||
|
||||
In the simplest case, a `%' followed by a digit N says to output
|
||||
operand N at that point in the string.
|
||||
|
||||
`%' followed by a letter and a digit says to output an operand in an
|
||||
alternate fashion. Four letters have standard, built-in meanings
|
||||
described below. The machine description macro `PRINT_OPERAND' can
|
||||
define additional letters with nonstandard meanings.
|
||||
|
||||
`%cDIGIT' can be used to substitute an operand that is a constant
|
||||
value without the syntax that normally indicates an immediate operand.
|
||||
|
||||
`%nDIGIT' is like `%cDIGIT' except that the value of the constant is
|
||||
negated before printing.
|
||||
|
||||
`%aDIGIT' can be used to substitute an operand as if it were a
|
||||
memory reference, with the actual operand treated as the address. This
|
||||
may be useful when outputting a "load address" instruction, because
|
||||
often the assembler syntax for such an instruction requires you to
|
||||
write the operand as if it were a memory reference.
|
||||
|
||||
`%lDIGIT' is used to substitute a `label_ref' into a jump
|
||||
instruction.
|
||||
|
||||
`%' followed by a punctuation character specifies a substitution that
|
||||
does not use an operand. Only one case is standard: `%%' outputs a `%'
|
||||
into the assembler code. Other nonstandard cases can be defined in the
|
||||
`PRINT_OPERAND' macro. You must also define which punctuation
|
||||
characters are valid with the `PRINT_OPERAND_PUNCT_VALID_P' macro.
|
||||
|
||||
The template may generate multiple assembler instructions. Write
|
||||
the text for the instructions, with `\;' between them.
|
||||
|
||||
When the RTL contains two operands which are required by constraint
|
||||
to match each other, the output template must refer only to the
|
||||
lower-numbered operand. Matching operands are not always identical, and
|
||||
the rest of the compiler arranges to put the proper RTL expression for
|
||||
printing into the lower-numbered operand.
|
||||
|
||||
One use of nonstandard letters or punctuation following `%' is to
|
||||
distinguish between different assembler languages for the same machine;
|
||||
for example, Motorola syntax versus MIT syntax for the 68000. Motorola
|
||||
syntax requires periods in most opcode names, while MIT syntax does
|
||||
not. For example, the opcode `movel' in MIT syntax is `move.l' in
|
||||
Motorola syntax. The same file of patterns is used for both kinds of
|
||||
output syntax, but the character sequence `%.' is used in each place
|
||||
where Motorola syntax wants a period. The `PRINT_OPERAND' macro for
|
||||
Motorola syntax defines the sequence to output a period; the macro for
|
||||
MIT syntax defines it to do nothing.
|
||||
|
||||
|
||||
File: gcc.info, Node: Output Statement, Next: Constraints, Prev: Output Template, Up: Machine Desc
|
||||
|
||||
C Statements for Generating Assembler Output
|
||||
============================================
|
||||
|
||||
Often a single fixed template string cannot produce correct and
|
||||
efficient assembler code for all the cases that are recognized by a
|
||||
single instruction pattern. For example, the opcodes may depend on the
|
||||
kinds of operands; or some unfortunate combinations of operands may
|
||||
require extra machine instructions.
|
||||
|
||||
If the output control string starts with a `*', then it is not an
|
||||
output template but rather a piece of C program that should compute a
|
||||
template. It should execute a `return' statement to return the
|
||||
template-string you want. Most such templates use C string literals,
|
||||
which require doublequote characters to delimit them. To include these
|
||||
doublequote characters in the string, prefix each one with `\'.
|
||||
|
||||
The operands may be found in the array `operands', whose C data type
|
||||
is `rtx []'.
|
||||
|
||||
It is possible to output an assembler instruction and then go on to
|
||||
output or compute more of them, using the subroutine `output_asm_insn'.
|
||||
This receives two arguments: a template-string and a vector of
|
||||
operands. The vector may be `operands', or it may be another array of
|
||||
`rtx' that you declare locally and initialize yourself.
|
||||
|
||||
When an insn pattern has multiple alternatives in its constraints,
|
||||
often the appearance of the assembler code is determined mostly by
|
||||
which alternative was matched. When this is so, the C code can test
|
||||
the variable `which_alternative', which is the ordinal number of the
|
||||
alternative that was actually satisfied (0 for the first, 1 for the
|
||||
second alternative, etc.).
|
||||
|
||||
For example, suppose there are two opcodes for storing zero, `clrreg'
|
||||
for registers and `clrmem' for memory locations. Here is how a pattern
|
||||
could use `which_alternative' to choose between them:
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "general_operand" "=r,m")
|
||||
(const_int 0))]
|
||||
""
|
||||
"*
|
||||
return (which_alternative == 0
|
||||
? \"clrreg %0\" : \"clrmem %0\");
|
||||
")
|
||||
|
||||
|
||||
File: gcc.info, Node: Constraints, Next: Standard Names, Prev: Output Statement, Up: Machine Desc
|
||||
|
||||
Operand Constraints
|
||||
===================
|
||||
|
||||
Each `match_operand' in an instruction pattern can specify a
|
||||
constraint for the type of operands allowed. Constraints can say
|
||||
whether an operand may be in a register, and which kinds of register;
|
||||
whether the operand can be a memory reference, and which kinds of
|
||||
address; whether the operand may be an immediate constant, and which
|
||||
possible values it may have. Constraints can also require two operands
|
||||
to match.
|
||||
|
||||
* Menu:
|
||||
|
||||
* Simple Constraints:: Basic use of constraints.
|
||||
* Multi-Alternative:: When an insn has two alternative constraint-patterns.
|
||||
* Class Preferences:: Constraints guide which hard register to put things in.
|
||||
* Modifiers:: More precise control over effects of constraints.
|
||||
* No Constraints:: Describing a clean machine without constraints.
|
||||
|
||||
|
||||
File: gcc.info, Node: Simple Constraints, Next: Multi-Alternative, Prev: Constraints, Up: Constraints
|
||||
|
||||
Simple Constraints
|
||||
------------------
|
||||
|
||||
The simplest kind of constraint is a string full of letters, each of
|
||||
which describes one kind of operand that is permitted. Here are the
|
||||
letters that are allowed:
|
||||
|
||||
`m'
|
||||
A memory operand is allowed, with any kind of address that the
|
||||
machine supports in general.
|
||||
|
||||
`o'
|
||||
A memory operand is allowed, but only if the address is
|
||||
"offsettable". This means that adding a small integer (actually,
|
||||
the width in bytes of the operand, as determined by its machine
|
||||
mode) may be added to the address and the result is also a valid
|
||||
memory address.
|
||||
|
||||
For example, an address which is constant is offsettable; so is an
|
||||
address that is the sum of a register and a constant (as long as a
|
||||
slightly larger constant is also within the range of
|
||||
address-offsets supported by the machine); but an autoincrement or
|
||||
autodecrement address is not offsettable. More complicated
|
||||
indirect/indexed addresses may or may not be offsettable depending
|
||||
on the other addressing modes that the machine supports.
|
||||
|
||||
Note that in an output operand which can be matched by another
|
||||
operand, the constraint letter `o' is valid only when accompanied
|
||||
by both `<' (if the target machine has predecrement addressing)
|
||||
and `>' (if the target machine has preincrement addressing).
|
||||
|
||||
When the constraint letter `o' is used, the reload pass may
|
||||
generate instructions which copy a nonoffsettable address into an
|
||||
index register. The idea is that the register can be used as a
|
||||
replacement offsettable address. But this method requires that
|
||||
there be patterns to copy any kind of address into a register.
|
||||
Auto-increment and auto-decrement addresses are an exception;
|
||||
there need not be an instruction that can copy such an address
|
||||
into a register, because reload handles these cases specially.
|
||||
|
||||
Most older machine designs have "load address" instructions which
|
||||
do just what is needed here. Some RISC machines do not advertise
|
||||
such instructions, but the possible addresses on these machines
|
||||
are very limited, so it is easy to fake them.
|
||||
|
||||
`<'
|
||||
A memory operand with autodecrement addressing (either
|
||||
predecrement or postdecrement) is allowed.
|
||||
|
||||
`>'
|
||||
A memory operand with autoincrement addressing (either
|
||||
preincrement or postincrement) is allowed.
|
||||
|
||||
`r'
|
||||
A register operand is allowed provided that it is in a general
|
||||
register.
|
||||
|
||||
`d', `a', `f', ...
|
||||
Other letters can be defined in machine-dependent fashion to stand
|
||||
for particular classes of registers. `d', `a' and `f' are defined
|
||||
on the 68000/68020 to stand for data, address and floating point
|
||||
registers.
|
||||
|
||||
`i'
|
||||
An immediate integer operand (one with constant value) is allowed.
|
||||
This includes symbolic constants whose values will be known only at
|
||||
assembly time.
|
||||
|
||||
`n'
|
||||
An immediate integer operand with a known numeric value is allowed.
|
||||
Many systems cannot support assembly-time constants for operands
|
||||
less than a word wide. Constraints for these operands should use
|
||||
`n' rather than `i'.
|
||||
|
||||
`I', `J', `K', ...
|
||||
Other letters in the range `I' through `M' may be defined in a
|
||||
machine-dependent fashion to permit immediate integer operands with
|
||||
explicit integer values in specified ranges. For example, on the
|
||||
68000, `I' is defined to stand for the range of values 1 to 8.
|
||||
This is the range permitted as a shift count in the shift
|
||||
instructions.
|
||||
|
||||
`F'
|
||||
An immediate floating operand (expression code `const_double') is
|
||||
allowed.
|
||||
|
||||
`G', `H'
|
||||
`G' and `H' may be defined in a machine-dependent fashion to
|
||||
permit immediate floating operands in particular ranges of values.
|
||||
|
||||
`s'
|
||||
An immediate integer operand whose value is not an explicit
|
||||
integer is allowed.
|
||||
|
||||
This might appear strange; if an insn allows a constant operand
|
||||
with a value not known at compile time, it certainly must allow
|
||||
any known value. So why use `s' instead of `i'? Sometimes it
|
||||
allows better code to be generated.
|
||||
|
||||
For example, on the 68000 in a fullword instruction it is possible
|
||||
to use an immediate operand; but if the immediate value is between
|
||||
-128 and 127, better code results from loading the value into a
|
||||
register and using the register. This is because the load into
|
||||
the register can be done with a `moveq' instruction. We arrange
|
||||
for this to happen by defining the letter `K' to mean "any integer
|
||||
outside the range -128 to 127", and then specifying `Ks' in the
|
||||
operand constraints.
|
||||
|
||||
`g'
|
||||
Any register, memory or immediate integer operand is allowed,
|
||||
except for registers that are not general registers.
|
||||
|
||||
`N' (a digit)
|
||||
An operand that matches operand number N is allowed. If a digit is
|
||||
used together with letters, the digit should come last.
|
||||
|
||||
This is called a "matching constraint" and what it really means is
|
||||
that the assembler has only a single operand that fills two roles
|
||||
considered separate in the RTL insn. For example, an add insn has
|
||||
two input operands and one output operand in the RTL, but on most
|
||||
machines an add instruction really has only two operands, one of
|
||||
them an input-output operand.
|
||||
|
||||
Matching constraints work only in circumstances like that add insn.
|
||||
More precisely, the matching constraint must appear in an
|
||||
input-only operand and the operand that it matches must be an
|
||||
output-only operand with a lower number. Thus, operand N must
|
||||
have `=' in its constraint.
|
||||
|
||||
For operands to match in a particular case usually means that they
|
||||
are identical-looking RTL expressions. But in a few special cases
|
||||
specific kinds of dissimilarity are allowed. For example, `*x' as
|
||||
an input operand will match `*x++' as an output operand. For
|
||||
proper results in such cases, the output template should always
|
||||
use the output-operand's number when printing the operand.
|
||||
|
||||
`p'
|
||||
An operand that is a valid memory address is allowed. This is for
|
||||
"load address" and "push address" instructions.
|
||||
|
||||
`p' in the constraint must be accompanies by `address_operand' as
|
||||
the predicate in the `match_operand'.
|
||||
|
||||
In order to have valid assembler code, each operand must satisfy its
|
||||
constraint. But a failure to do so does not prevent the pattern from
|
||||
applying to an insn. Instead, it directs the compiler to modify the
|
||||
code so that the constraint will be satisfied. Usually this is done by
|
||||
copying an operand into a register.
|
||||
|
||||
Contrast, therefore, the two instruction patterns that follow:
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "general_operand" "=r")
|
||||
(plus:SI (match_dup 0)
|
||||
(match_operand:SI 1 "general_operand" "r")))]
|
||||
""
|
||||
"...")
|
||||
|
||||
which has two operands, one of which must appear in two places, and
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "general_operand" "=r")
|
||||
(plus:SI (match_operand:SI 1 "general_operand" "0")
|
||||
(match_operand:SI 2 "general_operand" "r")))]
|
||||
""
|
||||
"...")
|
||||
|
||||
which has three operands, two of which are required by a constraint to
|
||||
be identical. If we are considering an insn of the form
|
||||
|
||||
(insn N PREV NEXT
|
||||
(set (reg:SI 3)
|
||||
(plus:SI (reg:SI 6) (reg:SI 109)))
|
||||
...)
|
||||
|
||||
the first pattern would not apply at all, because this insn does not
|
||||
contain two identical subexpressions in the right place. The pattern
|
||||
would say, "That does not look like an add instruction; try other
|
||||
patterns." The second pattern would say, "Yes, that's an add
|
||||
instruction, but there is something wrong with it." It would direct
|
||||
the reload pass of the compiler to generate additional insns to make
|
||||
the constraint true. The results might look like this:
|
||||
|
||||
(insn N2 PREV N
|
||||
(set (reg:SI 3) (reg:SI 6))
|
||||
...)
|
||||
|
||||
(insn N N2 NEXT
|
||||
(set (reg:SI 3)
|
||||
(plus:SI (reg:SI 3) (reg:SI 109)))
|
||||
...)
|
||||
|
||||
It is up to you to make sure that each operand, in each pattern, has
|
||||
constraints that can handle any RTL expression that could be present for
|
||||
that operand. (When multiple alternatives are in use, each pattern
|
||||
must, for each possible combination of operand expressions, have at
|
||||
least one alternative which can handle that combination of operands.)
|
||||
The constraints don't need to *allow* any possible operand--when this is
|
||||
the case, they do not constrain--but they must at least point the way to
|
||||
reloading any possible operand so that it will fit.
|
||||
|
||||
* If the constraint accepts whatever operands the predicate permits,
|
||||
there is no problem: reloading is never necessary for this operand.
|
||||
|
||||
For example, an operand whose constraints permit everything except
|
||||
registers is safe provided its predicate rejects registers.
|
||||
|
||||
An operand whose predicate accepts only constant values is safe
|
||||
provided its constraints include the letter `i'. If any possible
|
||||
constant value is accepted, then nothing less than `i' will do; if
|
||||
the predicate is more selective, then the constraints may also be
|
||||
more selective.
|
||||
|
||||
* Any operand expression can be reloaded by copying it into a
|
||||
register. So if an operand's constraints allow some kind of
|
||||
register, it is certain to be safe. It need not permit all
|
||||
classes of registers; the compiler knows how to copy a register
|
||||
into another register of the proper class in order to make an
|
||||
instruction valid.
|
||||
|
||||
* A nonoffsettable memory reference can be reloaded by copying the
|
||||
address into a register. So if the constraint uses the letter
|
||||
`o', all memory references are taken care of.
|
||||
|
||||
* A constant operand can be reloaded by allocating space in memory to
|
||||
hold it as preinitialized data. Then the memory reference can be
|
||||
used in place of the constant. So if the constraint uses the
|
||||
letters `o' or `m', constant operands are not a problem.
|
||||
|
||||
If the operand's predicate can recognize registers, but the
|
||||
constraint does not permit them, it can make the compiler crash. When
|
||||
this operand happens to be a register, the reload pass will be stymied,
|
||||
because it does not know how to copy a register temporarily into memory.
|
||||
|
||||
|
||||
File: gcc.info, Node: Multi-Alternative, Next: Class Preferences, Prev: Simple Constraints, Up: Constraints
|
||||
|
||||
Multiple Alternative Constraints
|
||||
--------------------------------
|
||||
|
||||
Sometimes a single instruction has multiple alternative sets of
|
||||
possible operands. For example, on the 68000, a logical-or instruction
|
||||
can combine register or an immediate value into memory, or it can
|
||||
combine any kind of operand into a register; but it cannot combine one
|
||||
memory location into another.
|
||||
|
||||
These constraints are represented as multiple alternatives. An
|
||||
alternative can be described by a series of letters for each operand.
|
||||
The overall constraint for an operand is made from the letters for this
|
||||
operand from the first alternative, a comma, the letters for this
|
||||
operand from the second alternative, a comma, and so on until the last
|
||||
alternative. Here is how it is done for fullword logical-or on the
|
||||
68000:
|
||||
|
||||
(define_insn "iorsi3"
|
||||
[(set (match_operand:SI 0 "general_operand" "=m,d")
|
||||
(ior:SI (match_operand:SI 1 "general_operand" "%0,0")
|
||||
(match_operand:SI 2 "general_operand" "dKs,dmKs")))]
|
||||
...)
|
||||
|
||||
The first alternative has `m' (memory) for operand 0, `0' for
|
||||
operand 1 (meaning it must match operand 0), and `dKs' for operand 2.
|
||||
The second alternative has `d' (data register) for operand 0, `0' for
|
||||
operand 1, and `dmKs' for operand 2. The `=' and `%' in the
|
||||
constraints apply to all the alternatives; their meaning is explained
|
||||
in the next section.
|
||||
|
||||
If all the operands fit any one alternative, the instruction is
|
||||
valid. Otherwise, for each alternative, the compiler counts how many
|
||||
instructions must be added to copy the operands so that that
|
||||
alternative applies. The alternative requiring the least copying is
|
||||
chosen. If two alternatives need the same amount of copying, the one
|
||||
that comes first is chosen. These choices can be altered with the `?'
|
||||
and `!' characters:
|
||||
|
||||
`?'
|
||||
Disparage slightly the alternative that the `?' appears in, as a
|
||||
choice when no alternative applies exactly. The compiler regards
|
||||
this alternative as one unit more costly for each `?' that appears
|
||||
in it.
|
||||
|
||||
`!'
|
||||
Disparage severely the alternative that the `!' appears in. When
|
||||
operands must be copied into registers, the compiler will never
|
||||
choose this alternative as the one to strive for.
|
||||
|
||||
When an insn pattern has multiple alternatives in its constraints,
|
||||
often the appearance of the assembler code is determined mostly by which
|
||||
alternative was matched. When this is so, the C code for writing the
|
||||
assembler code can use the variable `which_alternative', which is the
|
||||
ordinal number of the alternative that was actually satisfied (0 for
|
||||
the first, 1 for the second alternative, etc.). For example:
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "general_operand" "=r,m")
|
||||
(const_int 0))]
|
||||
""
|
||||
"*
|
||||
return (which_alternative == 0
|
||||
? \"clrreg %0\" : \"clrmem %0\");
|
||||
")
|
||||
|
||||
|
||||
File: gcc.info, Node: Class Preferences, Next: Modifiers, Prev: Multi-Alternative, Up: Constraints
|
||||
|
||||
Register Class Preferences
|
||||
--------------------------
|
||||
|
||||
The operand constraints have another function: they enable the
|
||||
compiler to decide which kind of hardware register a pseudo register is
|
||||
best allocated to. The compiler examines the constraints that apply to
|
||||
the insns that use the pseudo register, looking for the
|
||||
machine-dependent letters such as `d' and `a' that specify classes of
|
||||
registers. The pseudo register is put in whichever class gets the most
|
||||
"votes". The constraint letters `g' and `r' also vote: they vote in
|
||||
favor of a general register. The machine description says which
|
||||
registers are considered general.
|
||||
|
||||
Of course, on some machines all registers are equivalent, and no
|
||||
register classes are defined. Then none of this complexity is relevant.
|
||||
|
||||
|
||||
File: gcc.info, Node: Modifiers, Next: No Constraints, Prev: Class Preferences, Up: Constraints
|
||||
|
||||
Constraint Modifier Characters
|
||||
------------------------------
|
||||
|
||||
`='
|
||||
Means that this operand is write-only for this instruction: the
|
||||
previous value is discarded and replaced by output data.
|
||||
|
||||
`+'
|
||||
Means that this operand is both read and written by the
|
||||
instruction.
|
||||
|
||||
When the compiler fixes up the operands to satisfy the constraints,
|
||||
it needs to know which operands are inputs to the instruction and
|
||||
which are outputs from it. `=' identifies an output; `+'
|
||||
identifies an operand that is both input and output; all other
|
||||
operands are assumed to be input only.
|
||||
|
||||
`&'
|
||||
Means (in a particular alternative) that this operand is written
|
||||
before the instruction is finished using the input operands.
|
||||
Therefore, this operand may not lie in a register that is used as
|
||||
an input operand or as part of any memory address.
|
||||
|
||||
`&' applies only to the alternative in which it is written. In
|
||||
constraints with multiple alternatives, sometimes one alternative
|
||||
requires `&' while others do not. See, for example, the `movdf'
|
||||
insn of the 68000.
|
||||
|
||||
`&' does not obviate the need to write `='.
|
||||
|
||||
`%'
|
||||
Declares the instruction to be commutative for this operand and the
|
||||
following operand. This means that the compiler may interchange
|
||||
the two operands if that is the cheapest way to make all operands
|
||||
fit the constraints. This is often used in patterns for addition
|
||||
instructions that really have only two operands: the result must
|
||||
go in one of the arguments. Here for example, is how the 68000
|
||||
halfword-add instruction is defined:
|
||||
|
||||
(define_insn "addhi3"
|
||||
[(set (match_operand:HI 0 "general_operand" "=m,r")
|
||||
(plus:HI (match_operand:HI 1 "general_operand" "%0,0")
|
||||
(match_operand:HI 2 "general_operand" "di,g")))]
|
||||
...)
|
||||
|
||||
Note that in previous versions of GNU CC the `%' constraint
|
||||
modifier always applied to operands 1 and 2 regardless of which
|
||||
operand it was written in. The usual custom was to write it in
|
||||
operand 0. Now it must be in operand 1 if the operands to be
|
||||
exchanged are 1 and 2.
|
||||
|
||||
`#'
|
||||
Says that all following characters, up to the next comma, are to be
|
||||
ignored as a constraint. They are significant only for choosing
|
||||
register preferences.
|
||||
|
||||
`*'
|
||||
Says that the following character should be ignored when choosing
|
||||
register preferences. `*' has no effect on the meaning of the
|
||||
constraint as a constraint.
|
||||
|
||||
Here is an example: the 68000 has an instruction to sign-extend a
|
||||
halfword in a data register, and can also sign-extend a value by
|
||||
copying it into an address register. While either kind of
|
||||
register is acceptable, the constraints on an address-register
|
||||
destination are less strict, so it is best if register allocation
|
||||
makes an address register its goal. Therefore, `*' is used so
|
||||
that the `d' constraint letter (for data register) is ignored when
|
||||
computing register preferences.
|
||||
|
||||
(define_insn "extendhisi2"
|
||||
[(set (match_operand:SI 0 "general_operand" "=*d,a")
|
||||
(sign_extend:SI
|
||||
(match_operand:HI 1 "general_operand" "0,g")))]
|
||||
...)
|
||||
|
||||
|
||||
File: gcc.info, Node: No Constraints, Prev: Modifiers, Up: Constraints
|
||||
|
||||
Not Using Constraints
|
||||
---------------------
|
||||
|
||||
Some machines are so clean that operand constraints are not
|
||||
required. For example, on the Vax, an operand valid in one context is
|
||||
valid in any other context. On such a machine, every operand
|
||||
constraint would be `g', excepting only operands of "load address"
|
||||
instructions which are written as if they referred to a memory
|
||||
location's contents but actual refer to its address. They would have
|
||||
constraint `p'.
|
||||
|
||||
For such machines, instead of writing `g' and `p' for all the
|
||||
constraints, you can choose to write a description with empty
|
||||
constraints. Then you write `""' for the constraint in every
|
||||
`match_operand'. Address operands are identified by writing an
|
||||
`address' expression around the `match_operand', not by their
|
||||
constraints.
|
||||
|
||||
When the machine description has just empty constraints, certain
|
||||
parts of compilation are skipped, making the compiler faster. However,
|
||||
few machines actually do not need constraints; all machine descriptions
|
||||
now in existence use constraints.
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,107 @@
|
|||
This is TeX, C Version 3.141 (format=plain 92.11.5) 29 DEC 1992 13:12
|
||||
**gcc.texinfo
|
||||
(gcc.texinfo (texinfo.tex Loading texinfo package [Version 2.1]: Basics,
|
||||
\bindingoffset=\dimen16
|
||||
\normaloffset=\dimen17
|
||||
\pagewidth=\dimen18
|
||||
\pageheight=\dimen19
|
||||
\cornerlong=\dimen20
|
||||
\cornerthick=\dimen21
|
||||
\topandbottommargin=\dimen22
|
||||
\outerhsize=\dimen23
|
||||
\outervsize=\dimen24
|
||||
\EMsimple=\toks12
|
||||
\singlespaceskip=\skip18
|
||||
|
||||
fonts,
|
||||
\fontdepth=\count26
|
||||
\tclosesave=\dimen25
|
||||
\tcloserm=\dimen26
|
||||
page headings,
|
||||
\titlepagetopglue=\skip19
|
||||
\titlepagebottomglue=\skip20
|
||||
\realeverypar=\toks13
|
||||
\evenheadline=\toks14
|
||||
\oddheadline=\toks15
|
||||
\evenfootline=\toks16
|
||||
\oddfootline=\toks17
|
||||
tables,
|
||||
\tableindent=\dimen27
|
||||
\itemindent=\dimen28
|
||||
\itemmargin=\dimen29
|
||||
\itemmax=\dimen30
|
||||
\itemno=\count27
|
||||
indexing,
|
||||
\initialskipamount=\skip21
|
||||
\secondaryindent=\skip22
|
||||
\partialpage=\box16
|
||||
\doublecolumnhsize=\dimen31
|
||||
\doublecolumnvsize=\dimen32
|
||||
\availdimen@=\dimen33
|
||||
sectioning,
|
||||
\chapno=\count28
|
||||
\secno=\count29
|
||||
\subsecno=\count30
|
||||
\subsubsecno=\count31
|
||||
\appendixno=\count32
|
||||
\contentsfile=\write0
|
||||
\chapheadingskip=\skip23
|
||||
\subsecheadingskip=\skip24
|
||||
\secheadingskip=\skip25
|
||||
toc printing,
|
||||
\tocindent=\dimen34
|
||||
|
||||
environments,
|
||||
\dblarrowbox=\box17
|
||||
\longdblarrowbox=\box18
|
||||
\pushcharbox=\box19
|
||||
\bullbox=\box20
|
||||
\equivbox=\box21
|
||||
\errorbox=\box22
|
||||
\lispnarrowing=\skip26
|
||||
\aboveenvskipamount=\skip27
|
||||
defuns,
|
||||
\defbodyindent=\skip28
|
||||
\defargsindent=\skip29
|
||||
\deftypemargin=\skip30
|
||||
\deflastargmargin=\skip31
|
||||
\parencount=\count33
|
||||
cross reference,
|
||||
\auxfile=\write1
|
||||
\footnoteno=\count34
|
||||
and turning on texinfo input format.)
|
||||
(gcc.aux)
|
||||
@cpindfile=@write2
|
||||
@fnindfile=@write3
|
||||
@vrindfile=@write4
|
||||
@tpindfile=@write5
|
||||
@kyindfile=@write6
|
||||
@pgindfile=@write7
|
||||
[1] [2] (GNU GENERAL PUBLIC LICENSE) [1] [2] [3] [4] [5]
|
||||
(Contributors to GNU CC) [6] Chapter 1 [7] [8] [9] [10] Chapter 2 [11] [12]
|
||||
[13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] Chapter 3
|
||||
[26] [27] [28] [29] [30] [31] [32] [33] [34] [35] [36] [37] [38] [39] [40]
|
||||
Chapter 4 [41] [42] [43] Chapter 5 [44] Chapter 6 [45] [46] [47] [48] [49]
|
||||
Chapter 7 [50] [51] [52] [53] [54] [55] [56] [57] [58] [59] [60] [61] [62]
|
||||
[63] [64] [65] [66] [67] [68] Chapter 8 [69] [70] [71] [72] [73] [74] [75]
|
||||
Chapter 9 [76] Chapter 10 [77] [78] [79] Chapter 11 [80] [81] [82] [83]
|
||||
[84] Chapter 12 [85] [86] [87] [88] [89] [90] [91] [92] [93] [94] [95] [96]
|
||||
[97] [98] [99] [100] [101] [102] [103] [104] [105] [106] [107] [108] [109]
|
||||
[110] [111] [112] [113] [114] Chapter 13 [115] [116] [117] [118] [119] [120]
|
||||
[121] [122] [123] [124] [125] [126] [127] [128] [129] [130] [131] [132]
|
||||
[133] [134] [135] [136] [137] [138] [139] [140] [141] [142] [143] [144]
|
||||
[145] [146] Chapter 14 [147] [148] [149] [150] [151] [152] [153] [154] [155]
|
||||
[156] [157] [158] [159] [160] [161] [162] [163] [164] [165] [166] [167]
|
||||
[168] [169] [170] [171] [172] [173] [174] [175] [176] [177] [178] [179]
|
||||
[180] [181] [182] [183] [184] [185] [186] [187] [188] Chapter 15 [189] [190]
|
||||
[191] [192] (gcc.toc [-1] [-2]) [-3] [-4] )
|
||||
Here is how much of TeX's memory you used:
|
||||
811 strings out of 13041
|
||||
8825 string characters out of 96249
|
||||
23980 words of memory out of 262141
|
||||
1694 multiletter control sequences out of 9500
|
||||
22679 words of font info for 76 fonts, out of 100000 for 255
|
||||
18 hyphenation exceptions out of 607
|
||||
12i,6n,10p,221b,120s stack positions out of 300i,40n,60p,3000b,4000s
|
||||
|
||||
Output written on gcc.dvi (198 pages, 551312 bytes).
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,96 @@
|
|||
\unnumbchapentry {GNU GENERAL PUBLIC LICENSE}{1}
|
||||
\unnumbsecentry{Preamble}{1}
|
||||
\unnumbsecentry{TERMS AND CONDITIONS}{2}
|
||||
\unnumbsecentry{Appendix: How to Apply These Terms to Your New Programs}{5}
|
||||
\unnumbchapentry {Contributors to GNU CC}{7}
|
||||
\chapentry {Protect Your Freedom---Fight ``Look And Feel''}{1}{9}
|
||||
\chapentry {GNU CC Command Options}{2}{13}
|
||||
\chapentry {Installing GNU CC}{3}{27}
|
||||
\secentry {Compilation in a Separate Directory}{3}{1}{35}
|
||||
\secentry {Installing GNU CC on the Sun}{3}{2}{35}
|
||||
\secentry {Installing GNU CC on the 3b1}{3}{3}{36}
|
||||
\secentry {Installing GNU CC on SCO System V 3.2}{3}{4}{37}
|
||||
\secentry {Installing GNU CC on VMS}{3}{5}{37}
|
||||
\secentry {Installing GNU CC on HPUX}{3}{6}{40}
|
||||
\secentry {Installing GNU CC on an NCR Tower}{3}{7}{41}
|
||||
\chapentry {Known Causes of Trouble with GNU CC}{4}{43}
|
||||
\chapentry {How To Get Help with GNU CC}{5}{45}
|
||||
\chapentry {Incompatibilities of GNU CC}{6}{47}
|
||||
\chapentry {GNU Extensions to the C Language}{7}{51}
|
||||
\secentry {Statements and Declarations inside of Expressions}{7}{1}{51}
|
||||
\secentry {Naming an Expression's Type}{7}{2}{52}
|
||||
\secentry {Referring to a Type with \code {typeof}}{7}{3}{52}
|
||||
\secentry {Generalized Lvalues}{7}{4}{53}
|
||||
\secentry {Conditional Expressions with Omitted Middle-Operands}{7}{5}{55}
|
||||
\secentry {Arrays of Length Zero}{7}{6}{55}
|
||||
\secentry {Arrays of Variable Length}{7}{7}{56}
|
||||
\secentry {Non-Lvalue Arrays May Have Subscripts}{7}{8}{57}
|
||||
\secentry {Arithmetic on \code {void}-Pointers and Function Pointers}{7}{9}{57}
|
||||
\secentry {Non-Constant Initializers}{7}{10}{57}
|
||||
\secentry {Constructor Expressions}{7}{11}{58}
|
||||
\secentry {Declaring Attributes of Functions}{7}{12}{58}
|
||||
\secentry {Dollar Signs in Identifier Names}{7}{13}{59}
|
||||
\secentry {Inquiring about the Alignment of a Type or Variable}{7}{14}{60}
|
||||
\secentry {An Inline Function is As Fast As a Macro}{7}{15}{60}
|
||||
\secentry {Assembler Instructions with C Expression Operands}{7}{16}{62}
|
||||
\secentry {Controlling Names Used in Assembler Code}{7}{17}{65}
|
||||
\secentry {Variables in Specified Registers}{7}{18}{66}
|
||||
\subsecentry {Defining Global Register Variables}{7}{18}{1}{66}
|
||||
\subsecentry {Specifying Registers for Local Variables}{7}{18}{2}{68}
|
||||
\secentry {Alternate Keywords}{7}{19}{69}
|
||||
\chapentry {Reporting Bugs}{8}{71}
|
||||
\secentry {Have You Found a Bug?}{8}{1}{71}
|
||||
\secentry {How to Report Bugs}{8}{2}{72}
|
||||
\chapentry {GNU CC and Portability}{9}{77}
|
||||
\chapentry {Interfacing to GNU CC Output}{10}{79}
|
||||
\chapentry {Passes and Files of the Compiler}{11}{81}
|
||||
\chapentry {RTL Representation}{12}{87}
|
||||
\secentry {RTL Object Types}{12}{1}{87}
|
||||
\secentry {Access to Operands}{12}{2}{88}
|
||||
\secentry {Flags in an RTL Expression}{12}{3}{90}
|
||||
\secentry {Machine Modes}{12}{4}{92}
|
||||
\secentry {Constant Expression Types}{12}{5}{94}
|
||||
\secentry {Registers and Memory}{12}{6}{96}
|
||||
\secentry {RTL Expressions for Arithmetic}{12}{7}{98}
|
||||
\secentry {Comparison Operations}{12}{8}{100}
|
||||
\secentry {Bit-fields}{12}{9}{102}
|
||||
\secentry {Conversions}{12}{10}{102}
|
||||
\secentry {Declarations}{12}{11}{103}
|
||||
\secentry {Side Effect Expressions}{12}{12}{104}
|
||||
\secentry {Embedded Side-Effects on Addresses}{12}{13}{107}
|
||||
\secentry {Assembler Instructions as Expressions}{12}{14}{108}
|
||||
\secentry {Insns}{12}{15}{109}
|
||||
\secentry {RTL Representation of Function-Call Insns}{12}{16}{113}
|
||||
\secentry {Structure Sharing Assumptions}{12}{17}{114}
|
||||
\chapentry {Machine Descriptions}{13}{117}
|
||||
\secentry {Everything about Instruction Patterns}{13}{1}{117}
|
||||
\secentry {Example of \code {define{@fam @ttfam @tentt \char'137}insn}}{13}{2}{118}
|
||||
\secentry {RTL Template for Generating and Recognizing Insns}{13}{3}{119}
|
||||
\secentry {Output Templates and Operand Substitution}{13}{4}{122}
|
||||
\secentry {C Statements for Generating Assembler Output}{13}{5}{123}
|
||||
\secentry {Operand Constraints}{13}{6}{124}
|
||||
\subsecentry {Simple Constraints}{13}{6}{1}{124}
|
||||
\subsecentry {Multiple Alternative Constraints}{13}{6}{2}{128}
|
||||
\subsecentry {Register Class Preferences}{13}{6}{3}{129}
|
||||
\subsecentry {Constraint Modifier Characters}{13}{6}{4}{130}
|
||||
\subsecentry {Not Using Constraints}{13}{6}{5}{131}
|
||||
\secentry {Standard Names for Patterns Used in Generation}{13}{7}{131}
|
||||
\secentry {When the Order of Patterns Matters}{13}{8}{137}
|
||||
\secentry {Interdependence of Patterns}{13}{9}{137}
|
||||
\secentry {Defining Jump Instruction Patterns}{13}{10}{140}
|
||||
\secentry {Defining Machine-Specific Peephole Optimizers}{13}{11}{141}
|
||||
\secentry {Defining RTL Sequences for Code Generation}{13}{12}{144}
|
||||
\chapentry {Machine Description Macros}{14}{149}
|
||||
\secentry {Run-time Target Specification}{14}{1}{149}
|
||||
\secentry {Storage Layout}{14}{2}{150}
|
||||
\secentry {Register Usage}{14}{3}{152}
|
||||
\secentry {Register Classes}{14}{4}{157}
|
||||
\secentry {Describing Stack Layout}{14}{5}{161}
|
||||
\secentry {Implicit Use of Library Routines}{14}{6}{169}
|
||||
\secentry {Addressing Modes}{14}{7}{170}
|
||||
\secentry {Parameters for Delayed Branch Optimization}{14}{8}{172}
|
||||
\secentry {Condition Code Information}{14}{9}{173}
|
||||
\secentry {Cross Compilation and Floating-Point Format}{14}{10}{174}
|
||||
\secentry {Miscellaneous Parameters}{14}{11}{176}
|
||||
\secentry {Output of Assembler Code}{14}{12}{179}
|
||||
\chapentry {The Configuration File}{15}{191}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This progam 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.
|
||||
*
|
||||
* Alliance VLSI CAD System 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 the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
/* Alist matching source file names to GDB filenumbers.
|
||||
Used in output_source_line. */
|
||||
|
||||
struct gdbfile
|
||||
{
|
||||
struct gdbfile *next;
|
||||
char *name; /* name of source file */
|
||||
int filenum; /* Assigned number */
|
||||
int nlines; /* # lines generated for this source file */
|
||||
};
|
||||
|
||||
/* Chain of all `struct gdbfile's. */
|
||||
|
||||
extern struct gdbfile *gdbfiles;
|
Binary file not shown.
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This progam 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.
|
||||
*
|
||||
* Alliance VLSI CAD System 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 the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Generate from machine description:
|
||||
|
||||
- some macros CODE_FOR_... giving the insn_code_number value
|
||||
for each of the defined standard insn names.
|
||||
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 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "config.h"
|
||||
#include "rtl.h"
|
||||
#include "obstack.h"
|
||||
|
||||
struct obstack obstack;
|
||||
struct obstack *rtl_obstack = &obstack;
|
||||
|
||||
#define obstack_chunk_alloc xmalloc
|
||||
#define obstack_chunk_free free
|
||||
extern int xmalloc ();
|
||||
extern void free ();
|
||||
|
||||
void fatal ();
|
||||
void fancy_abort ();
|
||||
|
||||
int insn_code_number;
|
||||
|
||||
void
|
||||
gen_insn (insn)
|
||||
rtx insn;
|
||||
{
|
||||
/* Don't mention instructions whose names are the null string.
|
||||
They are in the machine description just to be recognized. */
|
||||
if (strlen (XSTR (insn, 0)) != 0)
|
||||
printf (" CODE_FOR_%s = %d,\n", XSTR (insn, 0),
|
||||
insn_code_number);
|
||||
}
|
||||
|
||||
int
|
||||
xmalloc (size)
|
||||
{
|
||||
register int val = malloc (size);
|
||||
|
||||
if (val == 0)
|
||||
fatal ("virtual memory exhausted");
|
||||
return val;
|
||||
}
|
||||
|
||||
int
|
||||
xrealloc (ptr, size)
|
||||
char *ptr;
|
||||
int size;
|
||||
{
|
||||
int result = realloc (ptr, size);
|
||||
if (!result)
|
||||
fatal ("virtual memory exhausted");
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
fatal (s, a1, a2)
|
||||
char *s;
|
||||
{
|
||||
fprintf (stderr, "gencodes: ");
|
||||
fprintf (stderr, s, a1, a2);
|
||||
fprintf (stderr, "\n");
|
||||
exit (FATAL_EXIT_CODE);
|
||||
}
|
||||
|
||||
/* More 'friendly' abort that prints the line and file.
|
||||
config.h can #define abort fancy_abort if you like that sort of thing. */
|
||||
|
||||
void
|
||||
fancy_abort ()
|
||||
{
|
||||
fatal ("Internal gcc abort.");
|
||||
}
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
rtx desc;
|
||||
FILE *infile;
|
||||
extern rtx read_rtx ();
|
||||
register int c;
|
||||
|
||||
obstack_init (rtl_obstack);
|
||||
|
||||
if (argc <= 1)
|
||||
fatal ("No input file name.");
|
||||
|
||||
infile = fopen (argv[1], "r");
|
||||
if (infile == 0)
|
||||
{
|
||||
perror (argv[1]);
|
||||
exit (FATAL_EXIT_CODE);
|
||||
}
|
||||
|
||||
init_rtl ();
|
||||
|
||||
printf ("/* Generated automatically by the program `gencodes'\n\
|
||||
from the machine description file `md'. */\n\n");
|
||||
|
||||
printf ("#ifndef MAX_INSN_CODE\n\n");
|
||||
|
||||
/* Read the machine description. */
|
||||
|
||||
insn_code_number = 0;
|
||||
printf ("enum insn_code {\n");
|
||||
|
||||
while (1)
|
||||
{
|
||||
c = read_skip_spaces (infile);
|
||||
if (c == EOF)
|
||||
break;
|
||||
ungetc (c, infile);
|
||||
|
||||
desc = read_rtx (infile);
|
||||
if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
|
||||
{
|
||||
gen_insn (desc);
|
||||
insn_code_number++;
|
||||
}
|
||||
if (GET_CODE (desc) == DEFINE_PEEPHOLE)
|
||||
{
|
||||
insn_code_number++;
|
||||
}
|
||||
}
|
||||
|
||||
printf (" CODE_FOR_nothing };\n");
|
||||
|
||||
printf ("\n#define MAX_INSN_CODE ((int) CODE_FOR_nothing)\n");
|
||||
|
||||
printf ("#endif /* MAX_INSN_CODE */\n");
|
||||
|
||||
fflush (stdout);
|
||||
exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,290 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This progam 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.
|
||||
*
|
||||
* Alliance VLSI CAD System 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 the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Generate from machine description:
|
||||
|
||||
- some #define configuration flags.
|
||||
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 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "config.h"
|
||||
#include "rtl.h"
|
||||
#include "obstack.h"
|
||||
|
||||
struct obstack obstack;
|
||||
struct obstack *rtl_obstack = &obstack;
|
||||
|
||||
#define obstack_chunk_alloc xmalloc
|
||||
#define obstack_chunk_free free
|
||||
extern int xmalloc ();
|
||||
extern void free ();
|
||||
|
||||
/* flags to determine output of machine description dependent #define's. */
|
||||
int max_recog_operands_flag;
|
||||
int max_dup_operands_flag;
|
||||
int max_clobbers_per_insn_flag;
|
||||
int register_constraint_flag;
|
||||
|
||||
int clobbers_seen_this_insn;
|
||||
int dup_operands_seen_this_insn;
|
||||
|
||||
void fatal ();
|
||||
void fancy_abort ();
|
||||
|
||||
void
|
||||
walk_insn_part (part)
|
||||
rtx part;
|
||||
{
|
||||
register int i, j;
|
||||
register RTX_CODE code;
|
||||
register char *format_ptr;
|
||||
|
||||
if (part == 0)
|
||||
return;
|
||||
|
||||
code = GET_CODE (part);
|
||||
switch (code)
|
||||
{
|
||||
case CLOBBER:
|
||||
clobbers_seen_this_insn++;
|
||||
break;
|
||||
|
||||
case MATCH_OPERAND:
|
||||
if (XINT (part, 0) > max_recog_operands_flag)
|
||||
max_recog_operands_flag = XINT (part, 0);
|
||||
if (XSTR (part, 2) && *XSTR (part, 2))
|
||||
register_constraint_flag = 1;
|
||||
return;
|
||||
|
||||
case MATCH_OPERATOR:
|
||||
if (XINT (part, 0) > max_recog_operands_flag)
|
||||
max_recog_operands_flag = XINT (part, 0);
|
||||
/* Now scan the rtl'x in the vector inside the match_operator. */
|
||||
break;
|
||||
|
||||
case LABEL_REF:
|
||||
if (GET_CODE (XEXP (part, 0)) == MATCH_OPERAND)
|
||||
break;
|
||||
return;
|
||||
|
||||
case MATCH_DUP:
|
||||
++dup_operands_seen_this_insn;
|
||||
if (XINT (part, 0) > max_recog_operands_flag)
|
||||
max_recog_operands_flag = XINT (part, 0);
|
||||
|
||||
case REG: case CONST_INT: case SYMBOL_REF:
|
||||
case PC: case CC0:
|
||||
return;
|
||||
}
|
||||
|
||||
format_ptr = GET_RTX_FORMAT (GET_CODE (part));
|
||||
|
||||
for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
|
||||
switch (*format_ptr++)
|
||||
{
|
||||
case 'e':
|
||||
case 'u':
|
||||
walk_insn_part (XEXP (part, i));
|
||||
break;
|
||||
case 'E':
|
||||
if (XVEC (part, i) != NULL)
|
||||
for (j = 0; j < XVECLEN (part, i); j++)
|
||||
walk_insn_part (XVECEXP (part, i, j));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gen_insn (insn)
|
||||
rtx insn;
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Walk the insn pattern to gather the #define's status. */
|
||||
clobbers_seen_this_insn = 0;
|
||||
dup_operands_seen_this_insn = 0;
|
||||
if (XVEC (insn, 1) != 0)
|
||||
for (i = 0; i < XVECLEN (insn, 1); i++)
|
||||
walk_insn_part (XVECEXP (insn, 1, i));
|
||||
|
||||
if (clobbers_seen_this_insn > max_clobbers_per_insn_flag)
|
||||
max_clobbers_per_insn_flag = clobbers_seen_this_insn;
|
||||
if (dup_operands_seen_this_insn > max_dup_operands_flag)
|
||||
max_dup_operands_flag = dup_operands_seen_this_insn;
|
||||
}
|
||||
|
||||
/* Similar but scan a define_expand. */
|
||||
|
||||
void
|
||||
gen_expand (insn)
|
||||
rtx insn;
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Walk the insn pattern to gather the #define's status. */
|
||||
|
||||
/* Note that we don't bother recording the number of MATCH_DUPs
|
||||
that occur in a gen_expand, because only reload cares about that. */
|
||||
if (XVEC (insn, 1) != 0)
|
||||
for (i = 0; i < XVECLEN (insn, 1); i++)
|
||||
{
|
||||
/* Compute the maximum SETs and CLOBBERS
|
||||
in any one of the sub-insns;
|
||||
don't sum across all of them. */
|
||||
clobbers_seen_this_insn = 0;
|
||||
|
||||
walk_insn_part (XVECEXP (insn, 1, i));
|
||||
|
||||
if (clobbers_seen_this_insn > max_clobbers_per_insn_flag)
|
||||
max_clobbers_per_insn_flag = clobbers_seen_this_insn;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gen_peephole (peep)
|
||||
rtx peep;
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Look through the patterns that are matched
|
||||
to compute the maximum operand number. */
|
||||
for (i = 0; i < XVECLEN (peep, 0); i++)
|
||||
walk_insn_part (XVECEXP (peep, 0, i));
|
||||
}
|
||||
|
||||
int
|
||||
xmalloc (size)
|
||||
{
|
||||
register int val = malloc (size);
|
||||
|
||||
if (val == 0)
|
||||
fatal ("virtual memory exhausted");
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
int
|
||||
xrealloc (ptr, size)
|
||||
char *ptr;
|
||||
int size;
|
||||
{
|
||||
int result = realloc (ptr, size);
|
||||
if (!result)
|
||||
fatal ("virtual memory exhausted");
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
fatal (s, a1, a2)
|
||||
char *s;
|
||||
{
|
||||
fprintf (stderr, "genconfig: ");
|
||||
fprintf (stderr, s, a1, a2);
|
||||
fprintf (stderr, "\n");
|
||||
exit (FATAL_EXIT_CODE);
|
||||
}
|
||||
|
||||
/* More 'friendly' abort that prints the line and file.
|
||||
config.h can #define abort fancy_abort if you like that sort of thing. */
|
||||
|
||||
void
|
||||
fancy_abort ()
|
||||
{
|
||||
fatal ("Internal gcc abort.");
|
||||
}
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
rtx desc;
|
||||
FILE *infile;
|
||||
extern rtx read_rtx ();
|
||||
register int c;
|
||||
|
||||
obstack_init (rtl_obstack);
|
||||
|
||||
if (argc <= 1)
|
||||
fatal ("No input file name.");
|
||||
|
||||
infile = fopen (argv[1], "r");
|
||||
if (infile == 0)
|
||||
{
|
||||
perror (argv[1]);
|
||||
exit (FATAL_EXIT_CODE);
|
||||
}
|
||||
|
||||
init_rtl ();
|
||||
|
||||
printf ("/* Generated automatically by the program `genconfig'\n\
|
||||
from the machine description file `md'. */\n\n");
|
||||
|
||||
/* Read the machine description. */
|
||||
|
||||
while (1)
|
||||
{
|
||||
c = read_skip_spaces (infile);
|
||||
if (c == EOF)
|
||||
break;
|
||||
ungetc (c, infile);
|
||||
|
||||
desc = read_rtx (infile);
|
||||
if (GET_CODE (desc) == DEFINE_INSN)
|
||||
gen_insn (desc);
|
||||
if (GET_CODE (desc) == DEFINE_EXPAND)
|
||||
gen_expand (desc);
|
||||
if (GET_CODE (desc) == DEFINE_PEEPHOLE)
|
||||
gen_peephole (desc);
|
||||
}
|
||||
|
||||
/* 3 more than needed for this md file, for the sake of asm constructs. */
|
||||
printf ("\n#define MAX_RECOG_OPERANDS %d\n", max_recog_operands_flag + 4);
|
||||
|
||||
if (max_dup_operands_flag == 0)
|
||||
max_dup_operands_flag = 1;
|
||||
printf ("\n#define MAX_DUP_OPERANDS %d\n", max_dup_operands_flag);
|
||||
|
||||
if (register_constraint_flag)
|
||||
printf ("#define REGISTER_CONSTRAINTS\n");
|
||||
|
||||
fflush (stdout);
|
||||
exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,503 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This progam 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.
|
||||
*
|
||||
* Alliance VLSI CAD System 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 the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Generate code from machine description to emit insns as rtl.
|
||||
Copyright (C) 1987, 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 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "config.h"
|
||||
#include "rtl.h"
|
||||
#include "obstack.h"
|
||||
|
||||
struct obstack obstack;
|
||||
struct obstack *rtl_obstack = &obstack;
|
||||
|
||||
#define obstack_chunk_alloc xmalloc
|
||||
#define obstack_chunk_free free
|
||||
extern int xmalloc ();
|
||||
extern void free ();
|
||||
|
||||
void fatal ();
|
||||
void fancy_abort ();
|
||||
|
||||
int max_opno;
|
||||
int max_dup_opno;
|
||||
int register_constraints;
|
||||
int insn_code_number;
|
||||
|
||||
#define max(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
void
|
||||
max_operand_1 (x)
|
||||
rtx x;
|
||||
{
|
||||
register RTX_CODE code;
|
||||
register int i;
|
||||
register int len;
|
||||
register char *fmt;
|
||||
|
||||
if (x == 0)
|
||||
return;
|
||||
|
||||
code = GET_CODE (x);
|
||||
|
||||
if (code == MATCH_OPERAND && XSTR (x, 2) != 0)
|
||||
register_constraints = 1;
|
||||
if (code == MATCH_OPERAND || code == MATCH_OPERATOR)
|
||||
max_opno = max (max_opno, XINT (x, 0));
|
||||
if (code == MATCH_DUP)
|
||||
max_dup_opno = max (max_dup_opno, XINT (x, 0));
|
||||
|
||||
fmt = GET_RTX_FORMAT (code);
|
||||
len = GET_RTX_LENGTH (code);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (fmt[i] == 'e' || fmt[i] == 'u')
|
||||
max_operand_1 (XEXP (x, i));
|
||||
else if (fmt[i] == 'E')
|
||||
{
|
||||
int j;
|
||||
for (j = 0; j < XVECLEN (x, i); j++)
|
||||
max_operand_1 (XVECEXP (x, i, j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
max_operand_vec (insn, arg)
|
||||
rtx insn;
|
||||
int arg;
|
||||
{
|
||||
register int len = XVECLEN (insn, arg);
|
||||
register int i;
|
||||
|
||||
max_opno = -1;
|
||||
max_dup_opno = -1;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
max_operand_1 (XVECEXP (insn, arg, i));
|
||||
|
||||
return max_opno + 1;
|
||||
}
|
||||
|
||||
void
|
||||
print_code (code)
|
||||
RTX_CODE code;
|
||||
{
|
||||
register char *p1;
|
||||
for (p1 = GET_RTX_NAME (code); *p1; p1++)
|
||||
{
|
||||
if (*p1 >= 'a' && *p1 <= 'z')
|
||||
putchar (*p1 + 'A' - 'a');
|
||||
else
|
||||
putchar (*p1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Print a C expression to construct an RTX just like X,
|
||||
substituting any operand references appearing within. */
|
||||
|
||||
void
|
||||
gen_exp (x)
|
||||
rtx x;
|
||||
{
|
||||
register RTX_CODE code;
|
||||
register int i;
|
||||
register int len;
|
||||
register char *fmt;
|
||||
|
||||
if (x == 0)
|
||||
{
|
||||
printf ("0");
|
||||
return;
|
||||
}
|
||||
|
||||
code = GET_CODE (x);
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case MATCH_OPERAND:
|
||||
case MATCH_DUP:
|
||||
printf ("operand%d", XINT (x, 0));
|
||||
return;
|
||||
|
||||
case MATCH_OPERATOR:
|
||||
printf ("gen_rtx (GET_CODE (operand%d)", XINT (x, 0));
|
||||
printf (", %smode", GET_MODE_NAME (GET_MODE (x)));
|
||||
for (i = 0; i < XVECLEN (x, 2); i++)
|
||||
{
|
||||
printf (",\n\t\t");
|
||||
gen_exp (XVECEXP (x, 2, i));
|
||||
}
|
||||
printf (")");
|
||||
return;
|
||||
|
||||
case ADDRESS:
|
||||
fatal ("ADDRESS expression code used in named instruction pattern");
|
||||
|
||||
case PC:
|
||||
printf ("pc_rtx");
|
||||
return;
|
||||
|
||||
case CC0:
|
||||
printf ("cc0_rtx");
|
||||
return;
|
||||
|
||||
case CONST_INT:
|
||||
if (INTVAL (x) == 0)
|
||||
{
|
||||
printf ("const0_rtx");
|
||||
return;
|
||||
}
|
||||
if (INTVAL (x) == 1)
|
||||
{
|
||||
printf ("const1_rtx");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
printf ("gen_rtx (");
|
||||
print_code (code);
|
||||
printf (", %smode", GET_MODE_NAME (GET_MODE (x)));
|
||||
|
||||
fmt = GET_RTX_FORMAT (code);
|
||||
len = GET_RTX_LENGTH (code);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (fmt[i] == '0')
|
||||
break;
|
||||
printf (", ");
|
||||
if (fmt[i] == 'e' || fmt[i] == 'u')
|
||||
gen_exp (XEXP (x, i));
|
||||
else if (fmt[i] == 'i')
|
||||
printf ("%d", XINT (x, i));
|
||||
else if (fmt[i] == 's')
|
||||
printf ("\"%s\"", XSTR (x, i));
|
||||
else if (fmt[i] == 'E')
|
||||
{
|
||||
int j;
|
||||
printf ("gen_rtvec (%d", XVECLEN (x, i));
|
||||
for (j = 0; j < XVECLEN (x, i); j++)
|
||||
{
|
||||
printf (",\n\t\t");
|
||||
gen_exp (XVECEXP (x, i, j));
|
||||
}
|
||||
printf (")");
|
||||
}
|
||||
else
|
||||
abort ();
|
||||
}
|
||||
printf (")");
|
||||
}
|
||||
|
||||
/* Generate the `gen_...' function for a DEFINE_INSN. */
|
||||
|
||||
void
|
||||
gen_insn (insn)
|
||||
rtx insn;
|
||||
{
|
||||
int operands;
|
||||
register int i;
|
||||
|
||||
/* Don't mention instructions whose names are the null string.
|
||||
They are in the machine description just to be recognized. */
|
||||
if (strlen (XSTR (insn, 0)) == 0)
|
||||
return;
|
||||
|
||||
/* Find out how many operands this function has,
|
||||
and also whether any of them have register constraints. */
|
||||
register_constraints = 0;
|
||||
operands = max_operand_vec (insn, 1);
|
||||
if (max_dup_opno >= operands)
|
||||
fatal ("match_dup operand number has no match_operand");
|
||||
|
||||
/* Output the function name and argument declarations. */
|
||||
printf ("rtx\ngen_%s (", XSTR (insn, 0));
|
||||
for (i = 0; i < operands; i++)
|
||||
printf (i ? ", operand%d" : "operand%d", i);
|
||||
printf (")\n");
|
||||
for (i = 0; i < operands; i++)
|
||||
printf (" rtx operand%d;\n", i);
|
||||
printf ("{\n");
|
||||
|
||||
/* Output code to construct and return the rtl for the instruction body */
|
||||
|
||||
if (XVECLEN (insn, 1) == 1)
|
||||
{
|
||||
printf (" return ");
|
||||
gen_exp (XVECEXP (insn, 1, 0));
|
||||
printf (";\n}\n\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf (" return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (%d", XVECLEN (insn, 1));
|
||||
for (i = 0; i < XVECLEN (insn, 1); i++)
|
||||
{
|
||||
printf (",\n\t\t");
|
||||
gen_exp (XVECEXP (insn, 1, i));
|
||||
}
|
||||
printf ("));\n}\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate the `gen_...' function for a DEFINE_EXPAND. */
|
||||
|
||||
void
|
||||
gen_expand (expand)
|
||||
rtx expand;
|
||||
{
|
||||
int operands;
|
||||
register int i;
|
||||
|
||||
if (strlen (XSTR (expand, 0)) == 0)
|
||||
fatal ("define_expand lacks a name");
|
||||
if (XVEC (expand, 1) == 0)
|
||||
fatal ("define_expand for %s lacks a pattern", XSTR (expand, 0));
|
||||
|
||||
/* Find out how many operands this function has,
|
||||
and also whether any of them have register constraints. */
|
||||
register_constraints = 0;
|
||||
|
||||
operands = max_operand_vec (expand, 1);
|
||||
|
||||
/* Output the function name and argument declarations. */
|
||||
printf ("rtx\ngen_%s (", XSTR (expand, 0));
|
||||
for (i = 0; i < operands; i++)
|
||||
printf (i ? ", operand%d" : "operand%d", i);
|
||||
printf (")\n");
|
||||
for (i = 0; i < operands; i++)
|
||||
printf (" rtx operand%d;\n", i);
|
||||
printf ("{\n");
|
||||
|
||||
/* For each operand referred to only with MATCH_DUPs,
|
||||
make a local variable. */
|
||||
for (i = operands; i <= max_dup_opno; i++)
|
||||
printf (" rtx operand%d;\n", i);
|
||||
printf (" rtx operands[%d];\n", max (operands, max_dup_opno + 1));
|
||||
printf (" rtx _val;\n");
|
||||
printf (" start_sequence ();\n");
|
||||
|
||||
/* The fourth operand of DEFINE_EXPAND is some code to be executed
|
||||
before the actual construction.
|
||||
This code expects to refer to `operands'
|
||||
just as the output-code in a DEFINE_INSN does,
|
||||
but here `operands' is an automatic array.
|
||||
So copy the operand values there before executing it. */
|
||||
if (XSTR (expand, 3))
|
||||
{
|
||||
/* Output code to copy the arguments into `operands'. */
|
||||
for (i = 0; i < operands; i++)
|
||||
printf (" operands[%d] = operand%d;\n", i, i);
|
||||
|
||||
/* Output the special code to be executed before the sequence
|
||||
is generated. */
|
||||
printf ("%s\n", XSTR (expand, 3));
|
||||
|
||||
/* Output code to copy the arguments back out of `operands'
|
||||
(unless we aren't going to use them at all). */
|
||||
if (XVEC (expand, 1) != 0)
|
||||
{
|
||||
for (i = 0; i < operands; i++)
|
||||
printf (" operand%d = operands[%d];\n", i, i);
|
||||
for (; i <= max_dup_opno; i++)
|
||||
printf (" operand%d = operands[%d];\n", i, i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Output code to construct the rtl for the instruction bodies.
|
||||
Use emit_insn to add them to the sequence being accumulated.
|
||||
But don't do this if the user's code has set `no_more' nonzero. */
|
||||
|
||||
for (i = 0; i < XVECLEN (expand, 1); i++)
|
||||
{
|
||||
rtx next = XVECEXP (expand, 1, i);
|
||||
if ((GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC)
|
||||
|| (GET_CODE (next) == PARALLEL
|
||||
&& GET_CODE (XVECEXP (next, 0, 0)) == SET
|
||||
&& GET_CODE (SET_DEST (XVECEXP (next, 0, 0))) == PC)
|
||||
|| GET_CODE (next) == RETURN)
|
||||
printf (" emit_jump_insn (");
|
||||
else if ((GET_CODE (next) == SET && GET_CODE (SET_SRC (next)) == CALL)
|
||||
|| GET_CODE (next) == CALL
|
||||
|| (GET_CODE (next) == PARALLEL
|
||||
&& GET_CODE (XVECEXP (next, 0, 0)) == SET
|
||||
&& GET_CODE (SET_SRC (XVECEXP (next, 0, 0))) == CALL)
|
||||
|| (GET_CODE (next) == PARALLEL
|
||||
&& GET_CODE (XVECEXP (next, 0, 0)) == CALL))
|
||||
printf (" emit_call_insn (");
|
||||
else if (GET_CODE (next) == CODE_LABEL)
|
||||
printf (" emit_label (");
|
||||
else if (GET_CODE (next) == MATCH_OPERAND
|
||||
|| GET_CODE (next) == MATCH_OPERATOR
|
||||
|| GET_CODE (next) == MATCH_DUP
|
||||
|| GET_CODE (next) == PARALLEL)
|
||||
printf (" emit (");
|
||||
else
|
||||
printf (" emit_insn (");
|
||||
gen_exp (next);
|
||||
printf (");\n");
|
||||
if (GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC
|
||||
&& GET_CODE (SET_SRC (next)) == LABEL_REF)
|
||||
printf (" emit_barrier ();");
|
||||
}
|
||||
|
||||
/* Call `gen_sequence' to make a SEQUENCE out of all the
|
||||
insns emitted within this gen_... function. */
|
||||
|
||||
printf (" _done:\n");
|
||||
printf (" _val = gen_sequence ();\n");
|
||||
printf (" end_sequence ();\n");
|
||||
printf (" return _val;\n}\n\n");
|
||||
}
|
||||
|
||||
int
|
||||
xmalloc (size)
|
||||
{
|
||||
register int val = malloc (size);
|
||||
|
||||
if (val == 0)
|
||||
fatal ("virtual memory exhausted");
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
int
|
||||
xrealloc (ptr, size)
|
||||
char *ptr;
|
||||
int size;
|
||||
{
|
||||
int result = realloc (ptr, size);
|
||||
if (!result)
|
||||
fatal ("virtual memory exhausted");
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
fatal (s, a1, a2)
|
||||
char *s;
|
||||
{
|
||||
fprintf (stderr, "genemit: ");
|
||||
fprintf (stderr, s, a1, a2);
|
||||
fprintf (stderr, "\n");
|
||||
exit (FATAL_EXIT_CODE);
|
||||
}
|
||||
|
||||
/* More 'friendly' abort that prints the line and file.
|
||||
config.h can #define abort fancy_abort if you like that sort of thing. */
|
||||
|
||||
void
|
||||
fancy_abort ()
|
||||
{
|
||||
fatal ("Internal gcc abort.");
|
||||
}
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
rtx desc;
|
||||
FILE *infile;
|
||||
extern rtx read_rtx ();
|
||||
register int c;
|
||||
|
||||
obstack_init (rtl_obstack);
|
||||
|
||||
if (argc <= 1)
|
||||
fatal ("No input file name.");
|
||||
|
||||
infile = fopen (argv[1], "r");
|
||||
if (infile == 0)
|
||||
{
|
||||
perror (argv[1]);
|
||||
exit (FATAL_EXIT_CODE);
|
||||
}
|
||||
|
||||
init_rtl ();
|
||||
|
||||
/* Assign sequential codes to all entries in the machine description
|
||||
in parallel with the tables in insn-output.c. */
|
||||
|
||||
insn_code_number = 0;
|
||||
|
||||
printf ("/* Generated automatically by the program `genemit'\n\
|
||||
from the machine description file `md'. */\n\n");
|
||||
|
||||
printf ("#include \"config.h\"\n");
|
||||
printf ("#include \"rtl.h\"\n");
|
||||
printf ("#include \"expr.h\"\n");
|
||||
printf ("#include \"real.h\"\n");
|
||||
printf ("#include \"insn-config.h\"\n\n");
|
||||
printf ("#include \"insn-flags.h\"\n\n");
|
||||
printf ("extern char *insn_operand_constraint[][MAX_RECOG_OPERANDS];\n\n");
|
||||
printf ("extern rtx recog_operand[];\n");
|
||||
printf ("#define operands emit_operand\n\n");
|
||||
printf ("#define FAIL do { end_sequence (); return 0;} while (0)\n\n");
|
||||
printf ("#define DONE goto _done\n\n");
|
||||
|
||||
/* Read the machine description. */
|
||||
|
||||
while (1)
|
||||
{
|
||||
c = read_skip_spaces (infile);
|
||||
if (c == EOF)
|
||||
break;
|
||||
ungetc (c, infile);
|
||||
|
||||
desc = read_rtx (infile);
|
||||
if (GET_CODE (desc) == DEFINE_INSN)
|
||||
{
|
||||
gen_insn (desc);
|
||||
++insn_code_number;
|
||||
}
|
||||
if (GET_CODE (desc) == DEFINE_EXPAND)
|
||||
{
|
||||
gen_expand (desc);
|
||||
++insn_code_number;
|
||||
}
|
||||
if (GET_CODE (desc) == DEFINE_PEEPHOLE)
|
||||
{
|
||||
++insn_code_number;
|
||||
}
|
||||
}
|
||||
|
||||
fflush (stdout);
|
||||
exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,371 @@
|
|||
/*
|
||||
* This file is part of the Alliance CAD System
|
||||
* Copyright (C) Laboratoire LIP6 - Département ASIM
|
||||
* Universite Pierre et Marie Curie
|
||||
*
|
||||
* Home page : http://www-asim.lip6.fr/alliance/
|
||||
* E-mail support : mailto:alliance-support@asim.lip6.fr
|
||||
*
|
||||
* This progam 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.
|
||||
*
|
||||
* Alliance VLSI CAD System 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 the GNU C Library; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Generate code from machine description to extract operands from insn as rtl.
|
||||
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 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "config.h"
|
||||
#include "rtl.h"
|
||||
#include "obstack.h"
|
||||
|
||||
struct obstack obstack;
|
||||
struct obstack *rtl_obstack = &obstack;
|
||||
|
||||
#define obstack_chunk_alloc xmalloc
|
||||
#define obstack_chunk_free free
|
||||
extern int xmalloc ();
|
||||
extern void free ();
|
||||
|
||||
/* Number instruction patterns handled, starting at 0 for first one. */
|
||||
|
||||
int insn_code_number;
|
||||
|
||||
/* Number the occurrences of MATCH_DUP in each instruction,
|
||||
starting at 0 for the first occurrence. */
|
||||
|
||||
int dup_count;
|
||||
|
||||
/* While tree-walking an instruction pattern, we keep a chain
|
||||
of these `struct link's to record how to get down to the
|
||||
current position. In each one, POS is the operand number,
|
||||
and if the operand is a vector VEC is the element number.
|
||||
VEC is -1 if the operand is not a vector. */
|
||||
|
||||
struct link
|
||||
{
|
||||
struct link *next;
|
||||
int pos;
|
||||
int vecelt;
|
||||
};
|
||||
|
||||
void walk_rtx ();
|
||||
void print_path ();
|
||||
void fatal ();
|
||||
void fancy_abort ();
|
||||
|
||||
void
|
||||
gen_insn (insn)
|
||||
rtx insn;
|
||||
{
|
||||
register int i;
|
||||
|
||||
dup_count = 0;
|
||||
|
||||
/* Output the function name and argument declaration. */
|
||||
/* It would be cleaner to make `void' the return type
|
||||
but 4.2 vax compiler doesn't accept that in the array
|
||||
that these functions are supposed to go in. */
|
||||
printf ("VOID\nextract_%d (insn)\n rtx insn;\n", insn_code_number);
|
||||
printf ("{\n");
|
||||
|
||||
/* Walk the insn's pattern, remembering at all times the path
|
||||
down to the walking point. */
|
||||
|
||||
if (XVECLEN (insn, 1) == 1)
|
||||
walk_rtx (XVECEXP (insn, 1, 0), 0);
|
||||
else
|
||||
for (i = XVECLEN (insn, 1) - 1; i >= 0; i--)
|
||||
{
|
||||
struct link link;
|
||||
link.next = 0;
|
||||
link.pos = 0;
|
||||
link.vecelt = i;
|
||||
walk_rtx (XVECEXP (insn, 1, i), &link);
|
||||
}
|
||||
printf ("}\n\n");
|
||||
}
|
||||
|
||||
/* Like gen_insn but handles `define_peephole'. */
|
||||
|
||||
void
|
||||
gen_peephole (peep)
|
||||
rtx peep;
|
||||
{
|
||||
/* Output the function name and argument declaration. */
|
||||
printf ("VOID\nextract_%d (insn)\n rtx insn;\n", insn_code_number);
|
||||
printf ("{\n");
|
||||
/* The vector in the insn says how many operands it has.
|
||||
And all it contains are operands. In fact, the vector was
|
||||
created just for the sake of this function. */
|
||||
printf ("\
|
||||
bcopy (&XVECEXP (insn, 0, 0), recog_operand,\
|
||||
sizeof (rtx) * XVECLEN (insn, 0));\n");
|
||||
printf ("}\n\n");
|
||||
}
|
||||
|
||||
void
|
||||
walk_rtx (x, path)
|
||||
rtx x;
|
||||
struct link *path;
|
||||
{
|
||||
register RTX_CODE code;
|
||||
register int i;
|
||||
register int len;
|
||||
register char *fmt;
|
||||
struct link link;
|
||||
|
||||
if (x == 0)
|
||||
return;
|
||||
|
||||
code = GET_CODE (x);
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case PC:
|
||||
case CC0:
|
||||
case CONST_INT:
|
||||
case SYMBOL_REF:
|
||||
return;
|
||||
|
||||
case MATCH_OPERAND:
|
||||
printf (" recog_operand[%d] = *(recog_operand_loc[%d]\n = &",
|
||||
XINT (x, 0), XINT (x, 0));
|
||||
print_path (path);
|
||||
printf (");\n");
|
||||
break;
|
||||
|
||||
case MATCH_DUP:
|
||||
printf (" recog_dup_loc[%d] = &", dup_count);
|
||||
print_path (path);
|
||||
printf (";\n");
|
||||
printf (" recog_dup_num[%d] = %d;\n", dup_count, XINT (x, 0));
|
||||
dup_count++;
|
||||
break;
|
||||
|
||||
case MATCH_OPERATOR:
|
||||
printf (" recog_operand[%d] = *(recog_operand_loc[%d]\n = &",
|
||||
XINT (x, 0), XINT (x, 0));
|
||||
print_path (path);
|
||||
printf (");\n");
|
||||
link.next = path;
|
||||
link.vecelt = -1;
|
||||
for (i = XVECLEN (x, 2) - 1; i >= 0; i--)
|
||||
{
|
||||
link.pos = i;
|
||||
walk_rtx (XVECEXP (x, 2, i), &link);
|
||||
}
|
||||
return;
|
||||
|
||||
case ADDRESS:
|
||||
walk_rtx (XEXP (x, 0), path);
|
||||
return;
|
||||
}
|
||||
|
||||
link.next = path;
|
||||
link.vecelt = -1;
|
||||
fmt = GET_RTX_FORMAT (code);
|
||||
len = GET_RTX_LENGTH (code);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
link.pos = i;
|
||||
if (fmt[i] == 'e' || fmt[i] == 'u')
|
||||
{
|
||||
walk_rtx (XEXP (x, i), &link);
|
||||
}
|
||||
else if (fmt[i] == 'E')
|
||||
{
|
||||
int j;
|
||||
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
|
||||
{
|
||||
link.vecelt = j;
|
||||
walk_rtx (XVECEXP (x, i, j), &link);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Given a PATH, representing a path down the instruction's
|
||||
pattern from the root to a certain point, output code to
|
||||
evaluate to the rtx at that point. */
|
||||
|
||||
void
|
||||
print_path (path)
|
||||
struct link *path;
|
||||
{
|
||||
if (path == 0)
|
||||
printf ("insn");
|
||||
else if (path->vecelt >= 0)
|
||||
{
|
||||
printf ("XVECEXP (");
|
||||
print_path (path->next);
|
||||
printf (", %d, %d)", path->pos, path->vecelt);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("XEXP (");
|
||||
print_path (path->next);
|
||||
printf (", %d)", path->pos);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
xmalloc (size)
|
||||
{
|
||||
register int val = malloc (size);
|
||||
|
||||
if (val == 0)
|
||||
fatal ("virtual memory exhausted");
|
||||
return val;
|
||||
}
|
||||
|
||||
int
|
||||
xrealloc (ptr, size)
|
||||
char *ptr;
|
||||
int size;
|
||||
{
|
||||
int result = realloc (ptr, size);
|
||||
if (!result)
|
||||
fatal ("virtual memory exhausted");
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
fatal (s, a1, a2)
|
||||
char *s;
|
||||
{
|
||||
fprintf (stderr, "genextract: ");
|
||||
fprintf (stderr, s, a1, a2);
|
||||
fprintf (stderr, "\n");
|
||||
exit (FATAL_EXIT_CODE);
|
||||
}
|
||||
|
||||
/* More 'friendly' abort that prints the line and file.
|
||||
config.h can #define abort fancy_abort if you like that sort of thing. */
|
||||
|
||||
void
|
||||
fancy_abort ()
|
||||
{
|
||||
fatal ("Internal gcc abort.");
|
||||
}
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
rtx desc;
|
||||
FILE *infile;
|
||||
extern rtx read_rtx ();
|
||||
register int c, i;
|
||||
|
||||
obstack_init (rtl_obstack);
|
||||
|
||||
if (argc <= 1)
|
||||
fatal ("No input file name.");
|
||||
|
||||
infile = fopen (argv[1], "r");
|
||||
if (infile == 0)
|
||||
{
|
||||
perror (argv[1]);
|
||||
exit (FATAL_EXIT_CODE);
|
||||
}
|
||||
|
||||
init_rtl ();
|
||||
|
||||
/* Assign sequential codes to all entries in the machine description
|
||||
in parallel with the tables in insn-output.c. */
|
||||
|
||||
insn_code_number = 0;
|
||||
|
||||
printf ("/* Generated automatically by the program `genextract'\n\
|
||||
from the machine description file `md'. */\n\n");
|
||||
|
||||
printf ("#include \"config.h\"\n");
|
||||
printf ("#include \"rtl.h\"\n\n");
|
||||
|
||||
printf ("extern rtx recog_operand[];\n");
|
||||
printf ("extern rtx *recog_operand_loc[];\n");
|
||||
printf ("extern rtx *recog_dup_loc[];\n");
|
||||
printf ("extern char recog_dup_num[];\n\n");
|
||||
|
||||
/* The extractor functions really should return `void';
|
||||
but old C compilers don't seem to be able to handle the array
|
||||
definition if `void' is used. So use `int' in non-ANSI C compilers. */
|
||||
|
||||
printf ("#ifdef __STDC__\n#define VOID void\n#else\n#define VOID int\n#endif\n\n");
|
||||
|
||||
/* Read the machine description. */
|
||||
|
||||
while (1)
|
||||
{
|
||||
c = read_skip_spaces (infile);
|
||||
if (c == EOF)
|
||||
break;
|
||||
ungetc (c, infile);
|
||||
|
||||
desc = read_rtx (infile);
|
||||
if (GET_CODE (desc) == DEFINE_INSN)
|
||||
{
|
||||
gen_insn (desc);
|
||||
++insn_code_number;
|
||||
}
|
||||
if (GET_CODE (desc) == DEFINE_PEEPHOLE)
|
||||
{
|
||||
gen_peephole (desc);
|
||||
++insn_code_number;
|
||||
}
|
||||
if (GET_CODE (desc) == DEFINE_EXPAND)
|
||||
{
|
||||
printf ("VOID extract_%d () {}\n\n", insn_code_number);
|
||||
++insn_code_number;
|
||||
}
|
||||
}
|
||||
|
||||
printf ("VOID (*insn_extract_fn[]) () =\n{ ");
|
||||
for (i = 0; i < insn_code_number; i++)
|
||||
{
|
||||
if (i % 4 != 0)
|
||||
printf (", ");
|
||||
else if (i != 0)
|
||||
printf (",\n ");
|
||||
printf ("extract_%d", i);
|
||||
}
|
||||
printf ("\n};\n\n");
|
||||
|
||||
printf ("void fatal_insn_not_found ();\n\n");
|
||||
printf ("void\ninsn_extract (insn)\n");
|
||||
printf (" rtx insn;\n");
|
||||
printf ("{\n if (INSN_CODE (insn) == -1) fatal_insn_not_found (insn);\n");
|
||||
printf (" (*insn_extract_fn[INSN_CODE (insn)]) (PATTERN (insn));\n}\n");
|
||||
|
||||
fflush (stdout);
|
||||
exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
|
||||
}
|
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue