mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-20 18:50:21 +02:00
initial import
(automatically generated log message) git-archimport-id: bonzini@gnu.org--2004b/lightning--stable--1.2--base-0
This commit is contained in:
commit
3b4c061913
79 changed files with 26993 additions and 0 deletions
2
AUTHORS
Normal file
2
AUTHORS
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Paolo Bonzini <bonzini@gnu.org>
|
||||||
|
i386 and PPC assemblers by Ian Piumarta <piumarta@inria.fr>
|
340
COPYING
Normal file
340
COPYING
Normal file
|
@ -0,0 +1,340 @@
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
355
COPYING.DOC
Normal file
355
COPYING.DOC
Normal file
|
@ -0,0 +1,355 @@
|
||||||
|
GNU Free Documentation License
|
||||||
|
Version 1.1, March 2000
|
||||||
|
|
||||||
|
Copyright (C) 2000 Free Software Foundation, Inc.
|
||||||
|
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
|
||||||
|
0. PREAMBLE
|
||||||
|
|
||||||
|
The purpose of this License is to make a manual, textbook, or other
|
||||||
|
written document "free" in the sense of freedom: to assure everyone
|
||||||
|
the effective freedom to copy and redistribute it, with or without
|
||||||
|
modifying it, either commercially or noncommercially. Secondarily,
|
||||||
|
this License preserves for the author and publisher a way to get
|
||||||
|
credit for their work, while not being considered responsible for
|
||||||
|
modifications made by others.
|
||||||
|
|
||||||
|
This License is a kind of "copyleft", which means that derivative
|
||||||
|
works of the document must themselves be free in the same sense. It
|
||||||
|
complements the GNU General Public License, which is a copyleft
|
||||||
|
license designed for free software.
|
||||||
|
|
||||||
|
We have designed this License in order to use it for manuals for free
|
||||||
|
software, because free software needs free documentation: a free
|
||||||
|
program should come with manuals providing the same freedoms that the
|
||||||
|
software does. But this License is not limited to software manuals;
|
||||||
|
it can be used for any textual work, regardless of subject matter or
|
||||||
|
whether it is published as a printed book. We recommend this License
|
||||||
|
principally for works whose purpose is instruction or reference.
|
||||||
|
|
||||||
|
|
||||||
|
1. APPLICABILITY AND DEFINITIONS
|
||||||
|
|
||||||
|
This License applies to any manual or other work that contains a
|
||||||
|
notice placed by the copyright holder saying it can be distributed
|
||||||
|
under the terms of this License. The "Document", below, refers to any
|
||||||
|
such manual or work. Any member of the public is a licensee, and is
|
||||||
|
addressed as "you".
|
||||||
|
|
||||||
|
A "Modified Version" of the Document means any work containing the
|
||||||
|
Document or a portion of it, either copied verbatim, or with
|
||||||
|
modifications and/or translated into another language.
|
||||||
|
|
||||||
|
A "Secondary Section" is a named appendix or a front-matter section of
|
||||||
|
the Document that deals exclusively with the relationship of the
|
||||||
|
publishers or authors of the Document to the Document's overall subject
|
||||||
|
(or to related matters) and contains nothing that could fall directly
|
||||||
|
within that overall subject. (For example, if the Document is in part a
|
||||||
|
textbook of mathematics, a Secondary Section may not explain any
|
||||||
|
mathematics.) The relationship could be a matter of historical
|
||||||
|
connection with the subject or with related matters, or of legal,
|
||||||
|
commercial, philosophical, ethical or political position regarding
|
||||||
|
them.
|
||||||
|
|
||||||
|
The "Invariant Sections" are certain Secondary Sections whose titles
|
||||||
|
are designated, as being those of Invariant Sections, in the notice
|
||||||
|
that says that the Document is released under this License.
|
||||||
|
|
||||||
|
The "Cover Texts" are certain short passages of text that are listed,
|
||||||
|
as Front-Cover Texts or Back-Cover Texts, in the notice that says that
|
||||||
|
the Document is released under this License.
|
||||||
|
|
||||||
|
A "Transparent" copy of the Document means a machine-readable copy,
|
||||||
|
represented in a format whose specification is available to the
|
||||||
|
general public, whose contents can be viewed and edited directly and
|
||||||
|
straightforwardly with generic text editors or (for images composed of
|
||||||
|
pixels) generic paint programs or (for drawings) some widely available
|
||||||
|
drawing editor, and that is suitable for input to text formatters or
|
||||||
|
for automatic translation to a variety of formats suitable for input
|
||||||
|
to text formatters. A copy made in an otherwise Transparent file
|
||||||
|
format whose markup has been designed to thwart or discourage
|
||||||
|
subsequent modification by readers is not Transparent. A copy that is
|
||||||
|
not "Transparent" is called "Opaque".
|
||||||
|
|
||||||
|
Examples of suitable formats for Transparent copies include plain
|
||||||
|
ASCII without markup, Texinfo input format, LaTeX input format, SGML
|
||||||
|
or XML using a publicly available DTD, and standard-conforming simple
|
||||||
|
HTML designed for human modification. Opaque formats include
|
||||||
|
PostScript, PDF, proprietary formats that can be read and edited only
|
||||||
|
by proprietary word processors, SGML or XML for which the DTD and/or
|
||||||
|
processing tools are not generally available, and the
|
||||||
|
machine-generated HTML produced by some word processors for output
|
||||||
|
purposes only.
|
||||||
|
|
||||||
|
The "Title Page" means, for a printed book, the title page itself,
|
||||||
|
plus such following pages as are needed to hold, legibly, the material
|
||||||
|
this License requires to appear in the title page. For works in
|
||||||
|
formats which do not have any title page as such, "Title Page" means
|
||||||
|
the text near the most prominent appearance of the work's title,
|
||||||
|
preceding the beginning of the body of the text.
|
||||||
|
|
||||||
|
|
||||||
|
2. VERBATIM COPYING
|
||||||
|
|
||||||
|
You may copy and distribute the Document in any medium, either
|
||||||
|
commercially or noncommercially, provided that this License, the
|
||||||
|
copyright notices, and the license notice saying this License applies
|
||||||
|
to the Document are reproduced in all copies, and that you add no other
|
||||||
|
conditions whatsoever to those of this License. You may not use
|
||||||
|
technical measures to obstruct or control the reading or further
|
||||||
|
copying of the copies you make or distribute. However, you may accept
|
||||||
|
compensation in exchange for copies. If you distribute a large enough
|
||||||
|
number of copies you must also follow the conditions in section 3.
|
||||||
|
|
||||||
|
You may also lend copies, under the same conditions stated above, and
|
||||||
|
you may publicly display copies.
|
||||||
|
|
||||||
|
|
||||||
|
3. COPYING IN QUANTITY
|
||||||
|
|
||||||
|
If you publish printed copies of the Document numbering more than 100,
|
||||||
|
and the Document's license notice requires Cover Texts, you must enclose
|
||||||
|
the copies in covers that carry, clearly and legibly, all these Cover
|
||||||
|
Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
|
||||||
|
the back cover. Both covers must also clearly and legibly identify
|
||||||
|
you as the publisher of these copies. The front cover must present
|
||||||
|
the full title with all words of the title equally prominent and
|
||||||
|
visible. You may add other material on the covers in addition.
|
||||||
|
Copying with changes limited to the covers, as long as they preserve
|
||||||
|
the title of the Document and satisfy these conditions, can be treated
|
||||||
|
as verbatim copying in other respects.
|
||||||
|
|
||||||
|
If the required texts for either cover are too voluminous to fit
|
||||||
|
legibly, you should put the first ones listed (as many as fit
|
||||||
|
reasonably) on the actual cover, and continue the rest onto adjacent
|
||||||
|
pages.
|
||||||
|
|
||||||
|
If you publish or distribute Opaque copies of the Document numbering
|
||||||
|
more than 100, you must either include a machine-readable Transparent
|
||||||
|
copy along with each Opaque copy, or state in or with each Opaque copy
|
||||||
|
a publicly-accessible computer-network location containing a complete
|
||||||
|
Transparent copy of the Document, free of added material, which the
|
||||||
|
general network-using public has access to download anonymously at no
|
||||||
|
charge using public-standard network protocols. If you use the latter
|
||||||
|
option, you must take reasonably prudent steps, when you begin
|
||||||
|
distribution of Opaque copies in quantity, to ensure that this
|
||||||
|
Transparent copy will remain thus accessible at the stated location
|
||||||
|
until at least one year after the last time you distribute an Opaque
|
||||||
|
copy (directly or through your agents or retailers) of that edition to
|
||||||
|
the public.
|
||||||
|
|
||||||
|
It is requested, but not required, that you contact the authors of the
|
||||||
|
Document well before redistributing any large number of copies, to give
|
||||||
|
them a chance to provide you with an updated version of the Document.
|
||||||
|
|
||||||
|
|
||||||
|
4. MODIFICATIONS
|
||||||
|
|
||||||
|
You may copy and distribute a Modified Version of the Document under
|
||||||
|
the conditions of sections 2 and 3 above, provided that you release
|
||||||
|
the Modified Version under precisely this License, with the Modified
|
||||||
|
Version filling the role of the Document, thus licensing distribution
|
||||||
|
and modification of the Modified Version to whoever possesses a copy
|
||||||
|
of it. In addition, you must do these things in the Modified Version:
|
||||||
|
|
||||||
|
A. Use in the Title Page (and on the covers, if any) a title distinct
|
||||||
|
from that of the Document, and from those of previous versions
|
||||||
|
(which should, if there were any, be listed in the History section
|
||||||
|
of the Document). You may use the same title as a previous version
|
||||||
|
if the original publisher of that version gives permission.
|
||||||
|
B. List on the Title Page, as authors, one or more persons or entities
|
||||||
|
responsible for authorship of the modifications in the Modified
|
||||||
|
Version, together with at least five of the principal authors of the
|
||||||
|
Document (all of its principal authors, if it has less than five).
|
||||||
|
C. State on the Title page the name of the publisher of the
|
||||||
|
Modified Version, as the publisher.
|
||||||
|
D. Preserve all the copyright notices of the Document.
|
||||||
|
E. Add an appropriate copyright notice for your modifications
|
||||||
|
adjacent to the other copyright notices.
|
||||||
|
F. Include, immediately after the copyright notices, a license notice
|
||||||
|
giving the public permission to use the Modified Version under the
|
||||||
|
terms of this License, in the form shown in the Addendum below.
|
||||||
|
G. Preserve in that license notice the full lists of Invariant Sections
|
||||||
|
and required Cover Texts given in the Document's license notice.
|
||||||
|
H. Include an unaltered copy of this License.
|
||||||
|
I. Preserve the section entitled "History", and its title, and add to
|
||||||
|
it an item stating at least the title, year, new authors, and
|
||||||
|
publisher of the Modified Version as given on the Title Page. If
|
||||||
|
there is no section entitled "History" in the Document, create one
|
||||||
|
stating the title, year, authors, and publisher of the Document as
|
||||||
|
given on its Title Page, then add an item describing the Modified
|
||||||
|
Version as stated in the previous sentence.
|
||||||
|
J. Preserve the network location, if any, given in the Document for
|
||||||
|
public access to a Transparent copy of the Document, and likewise
|
||||||
|
the network locations given in the Document for previous versions
|
||||||
|
it was based on. These may be placed in the "History" section.
|
||||||
|
You may omit a network location for a work that was published at
|
||||||
|
least four years before the Document itself, or if the original
|
||||||
|
publisher of the version it refers to gives permission.
|
||||||
|
K. In any section entitled "Acknowledgements" or "Dedications",
|
||||||
|
preserve the section's title, and preserve in the section all the
|
||||||
|
substance and tone of each of the contributor acknowledgements
|
||||||
|
and/or dedications given therein.
|
||||||
|
L. Preserve all the Invariant Sections of the Document,
|
||||||
|
unaltered in their text and in their titles. Section numbers
|
||||||
|
or the equivalent are not considered part of the section titles.
|
||||||
|
M. Delete any section entitled "Endorsements". Such a section
|
||||||
|
may not be included in the Modified Version.
|
||||||
|
N. Do not retitle any existing section as "Endorsements"
|
||||||
|
or to conflict in title with any Invariant Section.
|
||||||
|
|
||||||
|
If the Modified Version includes new front-matter sections or
|
||||||
|
appendices that qualify as Secondary Sections and contain no material
|
||||||
|
copied from the Document, you may at your option designate some or all
|
||||||
|
of these sections as invariant. To do this, add their titles to the
|
||||||
|
list of Invariant Sections in the Modified Version's license notice.
|
||||||
|
These titles must be distinct from any other section titles.
|
||||||
|
|
||||||
|
You may add a section entitled "Endorsements", provided it contains
|
||||||
|
nothing but endorsements of your Modified Version by various
|
||||||
|
parties--for example, statements of peer review or that the text has
|
||||||
|
been approved by an organization as the authoritative definition of a
|
||||||
|
standard.
|
||||||
|
|
||||||
|
You may add a passage of up to five words as a Front-Cover Text, and a
|
||||||
|
passage of up to 25 words as a Back-Cover Text, to the end of the list
|
||||||
|
of Cover Texts in the Modified Version. Only one passage of
|
||||||
|
Front-Cover Text and one of Back-Cover Text may be added by (or
|
||||||
|
through arrangements made by) any one entity. If the Document already
|
||||||
|
includes a cover text for the same cover, previously added by you or
|
||||||
|
by arrangement made by the same entity you are acting on behalf of,
|
||||||
|
you may not add another; but you may replace the old one, on explicit
|
||||||
|
permission from the previous publisher that added the old one.
|
||||||
|
|
||||||
|
The author(s) and publisher(s) of the Document do not by this License
|
||||||
|
give permission to use their names for publicity for or to assert or
|
||||||
|
imply endorsement of any Modified Version.
|
||||||
|
|
||||||
|
|
||||||
|
5. COMBINING DOCUMENTS
|
||||||
|
|
||||||
|
You may combine the Document with other documents released under this
|
||||||
|
License, under the terms defined in section 4 above for modified
|
||||||
|
versions, provided that you include in the combination all of the
|
||||||
|
Invariant Sections of all of the original documents, unmodified, and
|
||||||
|
list them all as Invariant Sections of your combined work in its
|
||||||
|
license notice.
|
||||||
|
|
||||||
|
The combined work need only contain one copy of this License, and
|
||||||
|
multiple identical Invariant Sections may be replaced with a single
|
||||||
|
copy. If there are multiple Invariant Sections with the same name but
|
||||||
|
different contents, make the title of each such section unique by
|
||||||
|
adding at the end of it, in parentheses, the name of the original
|
||||||
|
author or publisher of that section if known, or else a unique number.
|
||||||
|
Make the same adjustment to the section titles in the list of
|
||||||
|
Invariant Sections in the license notice of the combined work.
|
||||||
|
|
||||||
|
In the combination, you must combine any sections entitled "History"
|
||||||
|
in the various original documents, forming one section entitled
|
||||||
|
"History"; likewise combine any sections entitled "Acknowledgements",
|
||||||
|
and any sections entitled "Dedications". You must delete all sections
|
||||||
|
entitled "Endorsements."
|
||||||
|
|
||||||
|
|
||||||
|
6. COLLECTIONS OF DOCUMENTS
|
||||||
|
|
||||||
|
You may make a collection consisting of the Document and other documents
|
||||||
|
released under this License, and replace the individual copies of this
|
||||||
|
License in the various documents with a single copy that is included in
|
||||||
|
the collection, provided that you follow the rules of this License for
|
||||||
|
verbatim copying of each of the documents in all other respects.
|
||||||
|
|
||||||
|
You may extract a single document from such a collection, and distribute
|
||||||
|
it individually under this License, provided you insert a copy of this
|
||||||
|
License into the extracted document, and follow this License in all
|
||||||
|
other respects regarding verbatim copying of that document.
|
||||||
|
|
||||||
|
|
||||||
|
7. AGGREGATION WITH INDEPENDENT WORKS
|
||||||
|
|
||||||
|
A compilation of the Document or its derivatives with other separate
|
||||||
|
and independent documents or works, in or on a volume of a storage or
|
||||||
|
distribution medium, does not as a whole count as a Modified Version
|
||||||
|
of the Document, provided no compilation copyright is claimed for the
|
||||||
|
compilation. Such a compilation is called an "aggregate", and this
|
||||||
|
License does not apply to the other self-contained works thus compiled
|
||||||
|
with the Document, on account of their being thus compiled, if they
|
||||||
|
are not themselves derivative works of the Document.
|
||||||
|
|
||||||
|
If the Cover Text requirement of section 3 is applicable to these
|
||||||
|
copies of the Document, then if the Document is less than one quarter
|
||||||
|
of the entire aggregate, the Document's Cover Texts may be placed on
|
||||||
|
covers that surround only the Document within the aggregate.
|
||||||
|
Otherwise they must appear on covers around the whole aggregate.
|
||||||
|
|
||||||
|
|
||||||
|
8. TRANSLATION
|
||||||
|
|
||||||
|
Translation is considered a kind of modification, so you may
|
||||||
|
distribute translations of the Document under the terms of section 4.
|
||||||
|
Replacing Invariant Sections with translations requires special
|
||||||
|
permission from their copyright holders, but you may include
|
||||||
|
translations of some or all Invariant Sections in addition to the
|
||||||
|
original versions of these Invariant Sections. You may include a
|
||||||
|
translation of this License provided that you also include the
|
||||||
|
original English version of this License. In case of a disagreement
|
||||||
|
between the translation and the original English version of this
|
||||||
|
License, the original English version will prevail.
|
||||||
|
|
||||||
|
|
||||||
|
9. TERMINATION
|
||||||
|
|
||||||
|
You may not copy, modify, sublicense, or distribute the Document except
|
||||||
|
as expressly provided for under this License. Any other attempt to
|
||||||
|
copy, modify, sublicense or distribute the Document is void, and will
|
||||||
|
automatically terminate your rights under this License. However,
|
||||||
|
parties who have received copies, or rights, from you under this
|
||||||
|
License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
|
||||||
|
10. FUTURE REVISIONS OF THIS LICENSE
|
||||||
|
|
||||||
|
The Free Software Foundation may publish new, revised versions
|
||||||
|
of the GNU Free Documentation 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. See
|
||||||
|
http://www.gnu.org/copyleft/.
|
||||||
|
|
||||||
|
Each version of the License is given a distinguishing version number.
|
||||||
|
If the Document specifies that a particular numbered version of this
|
||||||
|
License "or any later version" applies to it, you have the option of
|
||||||
|
following the terms and conditions either of that specified version or
|
||||||
|
of any later version that has been published (not as a draft) by the
|
||||||
|
Free Software Foundation. If the Document does not specify a version
|
||||||
|
number of this License, you may choose any version ever published (not
|
||||||
|
as a draft) by the Free Software Foundation.
|
||||||
|
|
||||||
|
|
||||||
|
ADDENDUM: How to use this License for your documents
|
||||||
|
|
||||||
|
To use this License in a document you have written, include a copy of
|
||||||
|
the License in the document and put the following copyright and
|
||||||
|
license notices just after the title page:
|
||||||
|
|
||||||
|
Copyright (c) YEAR YOUR NAME.
|
||||||
|
Permission is granted to copy, distribute and/or modify this document
|
||||||
|
under the terms of the GNU Free Documentation License, Version 1.1
|
||||||
|
or any later version published by the Free Software Foundation;
|
||||||
|
with the Invariant Sections being LIST THEIR TITLES, with the
|
||||||
|
Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
|
||||||
|
A copy of the license is included in the section entitled "GNU
|
||||||
|
Free Documentation License".
|
||||||
|
|
||||||
|
If you have no Invariant Sections, write "with no Invariant Sections"
|
||||||
|
instead of saying which ones are invariant. If you have no
|
||||||
|
Front-Cover Texts, write "no Front-Cover Texts" instead of
|
||||||
|
"Front-Cover Texts being LIST"; likewise for Back-Cover Texts.
|
||||||
|
|
||||||
|
If your document contains nontrivial examples of program code, we
|
||||||
|
recommend releasing these examples in parallel under your choice of
|
||||||
|
free software license, such as the GNU General Public License,
|
||||||
|
to permit their use in free software.
|
503
COPYING.LESSER
Normal file
503
COPYING.LESSER
Normal file
|
@ -0,0 +1,503 @@
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 2.1, February 1999
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||||
|
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the Lesser GPL. It also counts
|
||||||
|
as the successor of the GNU Library Public License, version 2, hence
|
||||||
|
the version number 2.1.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
Licenses are intended to guarantee your freedom to share and change
|
||||||
|
free software--to make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Lesser General Public License, applies to some
|
||||||
|
specially designated software packages--typically libraries--of the
|
||||||
|
Free Software Foundation and other authors who decide to use it. You
|
||||||
|
can use it too, but we suggest you first think carefully about whether
|
||||||
|
this license or the ordinary General Public License is the better
|
||||||
|
strategy to use in any particular case, based on the explanations below.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom of use,
|
||||||
|
not price. Our General Public Licenses are designed to make sure that
|
||||||
|
you have the freedom to distribute copies of free software (and charge
|
||||||
|
for this service if you wish); that you receive source code or can get
|
||||||
|
it if you want it; that you can change the software and use pieces of
|
||||||
|
it in new free programs; and that you are informed that you can do
|
||||||
|
these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
distributors to deny you these rights or to ask you to surrender these
|
||||||
|
rights. These restrictions translate to certain responsibilities for
|
||||||
|
you if you distribute copies of the library or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis
|
||||||
|
or for a fee, you must give the recipients all the rights that we gave
|
||||||
|
you. You must make sure that they, too, receive or can get the source
|
||||||
|
code. If you link other code with the library, you must provide
|
||||||
|
complete object files to the recipients, so that they can relink them
|
||||||
|
with the library after making changes to the library and recompiling
|
||||||
|
it. And you must show them these terms so they know their rights.
|
||||||
|
|
||||||
|
We protect your rights with a two-step method: (1) we copyright the
|
||||||
|
library, and (2) we offer you this license, which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
To protect each distributor, we want to make it very clear that
|
||||||
|
there is no warranty for the free library. Also, if the library is
|
||||||
|
modified by someone else and passed on, the recipients should know
|
||||||
|
that what they have is not the original version, so that the original
|
||||||
|
author's reputation will not be affected by problems that might be
|
||||||
|
introduced by others.
|
||||||
|
|
||||||
|
Finally, software patents pose a constant threat to the existence of
|
||||||
|
any free program. We wish to make sure that a company cannot
|
||||||
|
effectively restrict the users of a free program by obtaining a
|
||||||
|
restrictive license from a patent holder. Therefore, we insist that
|
||||||
|
any patent license obtained for a version of the library must be
|
||||||
|
consistent with the full freedom of use specified in this license.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the
|
||||||
|
ordinary GNU General Public License. This license, the GNU Lesser
|
||||||
|
General Public License, applies to certain designated libraries, and
|
||||||
|
is quite different from the ordinary General Public License. We use
|
||||||
|
this license for certain libraries in order to permit linking those
|
||||||
|
libraries into non-free programs.
|
||||||
|
|
||||||
|
When a program is linked with a library, whether statically or using
|
||||||
|
a shared library, the combination of the two is legally speaking a
|
||||||
|
combined work, a derivative of the original library. The ordinary
|
||||||
|
General Public License therefore permits such linking only if the
|
||||||
|
entire combination fits its criteria of freedom. The Lesser General
|
||||||
|
Public License permits more lax criteria for linking other code with
|
||||||
|
the library.
|
||||||
|
|
||||||
|
We call this license the "Lesser" General Public License because it
|
||||||
|
does Less to protect the user's freedom than the ordinary General
|
||||||
|
Public License. It also provides other free software developers Less
|
||||||
|
of an advantage over competing non-free programs. These disadvantages
|
||||||
|
are the reason we use the ordinary General Public License for many
|
||||||
|
libraries. However, the Lesser license provides advantages in certain
|
||||||
|
special circumstances.
|
||||||
|
|
||||||
|
For example, on rare occasions, there may be a special need to
|
||||||
|
encourage the widest possible use of a certain library, so that it becomes
|
||||||
|
a de-facto standard. To achieve this, non-free programs must be
|
||||||
|
allowed to use the library. A more frequent case is that a free
|
||||||
|
library does the same job as widely used non-free libraries. In this
|
||||||
|
case, there is little to gain by limiting the free library to free
|
||||||
|
software only, so we use the Lesser General Public License.
|
||||||
|
|
||||||
|
In other cases, permission to use a particular library in non-free
|
||||||
|
programs enables a greater number of people to use a large body of
|
||||||
|
free software. For example, permission to use the GNU C Library in
|
||||||
|
non-free programs enables many more people to use the whole GNU
|
||||||
|
operating system, as well as its variant, the GNU/Linux operating
|
||||||
|
system.
|
||||||
|
|
||||||
|
Although the Lesser General Public License is Less protective of the
|
||||||
|
users' freedom, it does ensure that the user of a program that is
|
||||||
|
linked with the Library has the freedom and the wherewithal to run
|
||||||
|
that program using a modified version of the Library.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow. Pay close attention to the difference between a
|
||||||
|
"work based on the library" and a "work that uses the library". The
|
||||||
|
former contains code derived from the library, whereas the latter must
|
||||||
|
be combined with the library in order to run.
|
||||||
|
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library or other
|
||||||
|
program which contains a notice placed by the copyright holder or
|
||||||
|
other authorized party saying it may be distributed under the terms of
|
||||||
|
this Lesser General Public License (also called "this License").
|
||||||
|
Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work
|
||||||
|
which has been distributed under these terms. A "work based on the
|
||||||
|
Library" means either the Library or any derivative work under
|
||||||
|
copyright law: that is to say, a work containing the Library or a
|
||||||
|
portion of it, either verbatim or with modifications and/or translated
|
||||||
|
straightforwardly into another language. (Hereinafter, translation is
|
||||||
|
included without limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For a library, complete source code means
|
||||||
|
all the source code for all modules it contains, plus any associated
|
||||||
|
interface definition files, plus the scripts used to control compilation
|
||||||
|
and installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running a program using the Library is not restricted, and output from
|
||||||
|
such a program is covered only if its contents constitute a work based
|
||||||
|
on the Library (independent of the use of the Library in a tool for
|
||||||
|
writing it). Whether that is true depends on what the Library does
|
||||||
|
and what the program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's
|
||||||
|
complete source code as you receive it, in any medium, provided that
|
||||||
|
you conspicuously and appropriately publish on each copy an
|
||||||
|
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||||
|
all the notices that refer to this License and to the absence of any
|
||||||
|
warranty; and distribute a copy of this License along with the
|
||||||
|
Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy,
|
||||||
|
and you may at your option offer warranty protection in exchange for a
|
||||||
|
fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion
|
||||||
|
of it, thus forming a work based on the Library, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no
|
||||||
|
charge to all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a
|
||||||
|
table of data to be supplied by an application program that uses
|
||||||
|
the facility, other than as an argument passed when the facility
|
||||||
|
is invoked, then you must make a good faith effort to ensure that,
|
||||||
|
in the event an application does not supply such function or
|
||||||
|
table, the facility still operates, and performs whatever part of
|
||||||
|
its purpose remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has
|
||||||
|
a purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must
|
||||||
|
be optional: if the application does not supply it, the square
|
||||||
|
root function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Library, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote
|
||||||
|
it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so
|
||||||
|
that they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in
|
||||||
|
these notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for
|
||||||
|
that copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of
|
||||||
|
the Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or
|
||||||
|
derivative of it, under Section 2) in object code or executable form
|
||||||
|
under the terms of Sections 1 and 2 above provided that you accompany
|
||||||
|
it with the complete corresponding machine-readable source code, which
|
||||||
|
must be distributed under the terms of Sections 1 and 2 above on a
|
||||||
|
medium customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy
|
||||||
|
from a designated place, then offering equivalent access to copy the
|
||||||
|
source code from the same place satisfies the requirement to
|
||||||
|
distribute the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the
|
||||||
|
Library, but is designed to work with the Library by being compiled or
|
||||||
|
linked with it, is called a "work that uses the Library". Such a
|
||||||
|
work, in isolation, is not a derivative work of the Library, and
|
||||||
|
therefore falls outside the scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library
|
||||||
|
creates an executable that is a derivative of the Library (because it
|
||||||
|
contains portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License.
|
||||||
|
Section 6 states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is not.
|
||||||
|
Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data
|
||||||
|
structure layouts and accessors, and small macros and small inline
|
||||||
|
functions (ten lines or less in length), then the use of the object
|
||||||
|
file is unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section 6.
|
||||||
|
Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also combine or
|
||||||
|
link a "work that uses the Library" with the Library to produce a
|
||||||
|
work containing portions of the Library, and distribute that work
|
||||||
|
under terms of your choice, provided that the terms permit
|
||||||
|
modification of the work for the customer's own use and reverse
|
||||||
|
engineering for debugging such modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work
|
||||||
|
during execution displays copyright notices, you must include the
|
||||||
|
copyright notice for the Library among them, as well as a reference
|
||||||
|
directing the user to the copy of this License. Also, you must do one
|
||||||
|
of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding
|
||||||
|
machine-readable source code for the Library including whatever
|
||||||
|
changes were used in the work (which must be distributed under
|
||||||
|
Sections 1 and 2 above); and, if the work is an executable linked
|
||||||
|
with the Library, with the complete machine-readable "work that
|
||||||
|
uses the Library", as object code and/or source code, so that the
|
||||||
|
user can modify the Library and then relink to produce a modified
|
||||||
|
executable containing the modified Library. (It is understood
|
||||||
|
that the user who changes the contents of definitions files in the
|
||||||
|
Library will not necessarily be able to recompile the application
|
||||||
|
to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (1) uses at run time a
|
||||||
|
copy of the library already present on the user's computer system,
|
||||||
|
rather than copying library functions into the executable, and (2)
|
||||||
|
will operate properly with a modified version of the library, if
|
||||||
|
the user installs one, as long as the modified version is
|
||||||
|
interface-compatible with the version that the work was made with.
|
||||||
|
|
||||||
|
c) Accompany the work with a written offer, valid for at
|
||||||
|
least three years, to give the same user the materials
|
||||||
|
specified in Subsection 6a, above, for a charge no more
|
||||||
|
than the cost of performing this distribution.
|
||||||
|
|
||||||
|
d) If distribution of the work is made by offering access to copy
|
||||||
|
from a designated place, offer equivalent access to copy the above
|
||||||
|
specified materials from the same place.
|
||||||
|
|
||||||
|
e) Verify that the user has already received a copy of these
|
||||||
|
materials or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the
|
||||||
|
Library" must include any data and utility programs needed for
|
||||||
|
reproducing the executable from it. However, as a special exception,
|
||||||
|
the materials to be distributed need not include anything that is
|
||||||
|
normally distributed (in either source or binary form) with the major
|
||||||
|
components (compiler, kernel, and so on) of the operating system on
|
||||||
|
which the executable runs, unless that component itself accompanies
|
||||||
|
the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license
|
||||||
|
restrictions of other proprietary libraries that do not normally
|
||||||
|
accompany the operating system. Such a contradiction means you cannot
|
||||||
|
use both them and the Library together in an executable that you
|
||||||
|
distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the
|
||||||
|
Library side-by-side in a single library together with other library
|
||||||
|
facilities not covered by this License, and distribute such a combined
|
||||||
|
library, provided that the separate distribution of the work based on
|
||||||
|
the Library and of the other library facilities is otherwise
|
||||||
|
permitted, and provided that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work
|
||||||
|
based on the Library, uncombined with any other library
|
||||||
|
facilities. This must be distributed under the terms of the
|
||||||
|
Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact
|
||||||
|
that part of it is a work based on the Library, and explaining
|
||||||
|
where to find the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute
|
||||||
|
the Library except as expressly provided under this License. Any
|
||||||
|
attempt otherwise to copy, modify, sublicense, link with, or
|
||||||
|
distribute the Library is void, and will automatically terminate your
|
||||||
|
rights under this License. However, parties who have received copies,
|
||||||
|
or rights, from you under this License will not have their licenses
|
||||||
|
terminated so long as such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Library or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Library (or any work based on the
|
||||||
|
Library), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Library or works based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties with
|
||||||
|
this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Library by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under any
|
||||||
|
particular circumstance, the balance of the section is intended to apply,
|
||||||
|
and the section as a whole is intended to apply in other circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Library under this License may add
|
||||||
|
an explicit geographical distribution limitation excluding those countries,
|
||||||
|
so that distribution is permitted only in or among countries not thus
|
||||||
|
excluded. In such case, this License incorporates the limitation as if
|
||||||
|
written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new
|
||||||
|
versions of the Lesser General Public License from time to time.
|
||||||
|
Such new versions will be similar in spirit to the present version,
|
||||||
|
but may differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and
|
||||||
|
"any later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a
|
||||||
|
license version number, you may choose any version ever published by
|
||||||
|
the Free Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free
|
||||||
|
Software Foundation; we sometimes make exceptions for this. Our
|
||||||
|
decision will be guided by the two goals of preserving the free status
|
||||||
|
of all derivatives of our free software and of promoting the sharing
|
||||||
|
and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||||
|
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||||
|
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||||
|
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||||
|
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||||
|
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||||
|
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||||
|
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||||
|
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||||
|
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||||
|
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||||
|
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||||
|
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||||
|
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||||
|
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the library's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||||
|
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
That's all there is to it!
|
||||||
|
|
75
ChangeLog
Normal file
75
ChangeLog
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
2004-03-02 Paolo Bonzini <bonzini@gnu.org>
|
||||||
|
|
||||||
|
* lightning/i386/core.h: generate correct code when
|
||||||
|
doing lt/le/ge/etc. on ESI and EDI. Use MOVZX/MOVSX
|
||||||
|
where possible.
|
||||||
|
* lightning/i386/asm.h: Add macros for MOVZX/MOVSX.
|
||||||
|
Move macros for x87 here, and add many of them.
|
||||||
|
* lightning/i386/fp.h: Use new macros for x87.
|
||||||
|
|
||||||
|
2004-02-06 Paolo Bonzini <bonzini@gnu.org>
|
||||||
|
|
||||||
|
* lightning/i386/core.h: avoid generating MOV reg, reg.
|
||||||
|
* lightning/sparc/core.h: fix several bugs.
|
||||||
|
* lightning/ppc/core.h: fix several bugs.
|
||||||
|
* tests/rpn.c: rewritten.
|
||||||
|
|
||||||
|
2004-01-08 Paolo Bonzini <bonzini@gnu.org>
|
||||||
|
|
||||||
|
* tests/rpnfp.c: new example, suggested by Basile
|
||||||
|
Starynkevitch.
|
||||||
|
* tests/rpnfp.ok: new example.
|
||||||
|
|
||||||
|
2003-12-12 Paolo Bonzini <bonzini@gnu.org>
|
||||||
|
|
||||||
|
* tests/add.c: new test, suggested by Steve Dekorte.
|
||||||
|
* tests/add.c: new test.
|
||||||
|
|
||||||
|
2003-11-14 Paolo Bonzini <bonzini@gnu.org>
|
||||||
|
John Redford <eirenik@hotmail.com>
|
||||||
|
|
||||||
|
* lightning/asm-common.h: change the 'pc' field of _jit to
|
||||||
|
be a union of various data types, because ISO C99 doesn't
|
||||||
|
permit using ++ on a = cast. Change the incremented casts of
|
||||||
|
_jit.pc to be _jit.x.uc_pc, _jit.x.us_pc, etc.
|
||||||
|
* all files: change all non-cast instances of _jit.pc to be
|
||||||
|
_jit.x.pc.
|
||||||
|
* lightning/i386/core.h: remove casts from jit_might.
|
||||||
|
|
||||||
|
2003-05-25 Paolo Bonzini <bonzini@gnu.org>
|
||||||
|
|
||||||
|
* lightning/i386/core.h: use JITSORRY in jit_replace
|
||||||
|
* lightning/asm-common.h: define JITSORRY
|
||||||
|
|
||||||
|
2003-05-14 Paolo Bonzini <bonzini@gnu.org>
|
||||||
|
|
||||||
|
* lightning/i386/core.h: fix missing comma in several
|
||||||
|
load/store macros.
|
||||||
|
* lightning/core-common.h: fix long/unsigned long/pointer
|
||||||
|
jit_pushr/jit_popr.
|
||||||
|
* lightning/ppc/funcs.h: correctly align stack pointer
|
||||||
|
|
||||||
|
No changelogs for the assemblers (lightning directory) until 1.0
|
||||||
|
|
||||||
|
2003-03-27 Paolo Bonzini <bonzini@gnu.org>
|
||||||
|
|
||||||
|
* tests/printf2.c: new test
|
||||||
|
|
||||||
|
2001-05-03 Paolo Bonzini <bonzini@gnu.org>
|
||||||
|
|
||||||
|
* tests/printf.c: made the message platform independent
|
||||||
|
|
||||||
|
2001-01-19 Paolo Bonzini <bonzini@gnu.org>
|
||||||
|
|
||||||
|
* configure.in: support cross-assembling
|
||||||
|
|
||||||
|
* disass/bfd.h, disass/dis-asm.h, disass/dis-buf.c,
|
||||||
|
disass/i386-dis.c, disass/i386.h, disass/ppc-dis.c,
|
||||||
|
disass/ppc.h, disass/ppc-opc.c, disass/sparc-dis.c,
|
||||||
|
disass/sparc.h, disass/sparc-opc.c: new files, from GDB
|
||||||
|
|
||||||
|
* disass/disass.c, disass/Makefile.am: new files
|
||||||
|
|
||||||
|
* tests/fib.c, tests/fibit.c, tests/incr.c, tests/printf.c,
|
||||||
|
tests/rpn.c, tests/testfp.c, tests/Makefile.am: support
|
||||||
|
disassembling
|
229
INSTALL
Normal file
229
INSTALL
Normal file
|
@ -0,0 +1,229 @@
|
||||||
|
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
|
||||||
|
Foundation, Inc.
|
||||||
|
|
||||||
|
This file is free documentation; the Free Software Foundation gives
|
||||||
|
unlimited permission to copy, distribute and modify it.
|
||||||
|
|
||||||
|
Basic Installation
|
||||||
|
==================
|
||||||
|
|
||||||
|
These are generic installation instructions.
|
||||||
|
|
||||||
|
The `configure' shell script attempts to guess correct values for
|
||||||
|
various system-dependent variables used during compilation. It uses
|
||||||
|
those values to create a `Makefile' in each directory of the package.
|
||||||
|
It may also create one or more `.h' files containing system-dependent
|
||||||
|
definitions. Finally, it creates a shell script `config.status' that
|
||||||
|
you can run in the future to recreate the current configuration, and a
|
||||||
|
file `config.log' containing compiler output (useful mainly for
|
||||||
|
debugging `configure').
|
||||||
|
|
||||||
|
It can also use an optional file (typically called `config.cache'
|
||||||
|
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||||
|
the results of its tests to speed up reconfiguring. (Caching is
|
||||||
|
disabled by default to prevent problems with accidental use of stale
|
||||||
|
cache files.)
|
||||||
|
|
||||||
|
If you need to do unusual things to compile the package, please try
|
||||||
|
to figure out how `configure' could check whether to do them, and mail
|
||||||
|
diffs or instructions to the address given in the `README' so they can
|
||||||
|
be considered for the next release. If you are using the cache, and at
|
||||||
|
some point `config.cache' contains results you don't want to keep, you
|
||||||
|
may remove or edit it.
|
||||||
|
|
||||||
|
The file `configure.ac' (or `configure.in') is used to create
|
||||||
|
`configure' by a program called `autoconf'. You only need
|
||||||
|
`configure.ac' if you want to change it or regenerate `configure' using
|
||||||
|
a newer version of `autoconf'.
|
||||||
|
|
||||||
|
The simplest way to compile this package is:
|
||||||
|
|
||||||
|
1. `cd' to the directory containing the package's source code and type
|
||||||
|
`./configure' to configure the package for your system. If you're
|
||||||
|
using `csh' on an old version of System V, you might need to type
|
||||||
|
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||||
|
`configure' itself.
|
||||||
|
|
||||||
|
Running `configure' takes awhile. While running, it prints some
|
||||||
|
messages telling which features it is checking for.
|
||||||
|
|
||||||
|
2. Type `make' to compile the package.
|
||||||
|
|
||||||
|
3. Optionally, type `make check' to run any self-tests that come with
|
||||||
|
the package.
|
||||||
|
|
||||||
|
4. Type `make install' to install the programs and any data files and
|
||||||
|
documentation.
|
||||||
|
|
||||||
|
5. You can remove the program binaries and object files from the
|
||||||
|
source code directory by typing `make clean'. To also remove the
|
||||||
|
files that `configure' created (so you can compile the package for
|
||||||
|
a different kind of computer), type `make distclean'. There is
|
||||||
|
also a `make maintainer-clean' target, but that is intended mainly
|
||||||
|
for the package's developers. If you use it, you may have to get
|
||||||
|
all sorts of other programs in order to regenerate files that came
|
||||||
|
with the distribution.
|
||||||
|
|
||||||
|
Compilers and Options
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Some systems require unusual options for compilation or linking that
|
||||||
|
the `configure' script does not know about. Run `./configure --help'
|
||||||
|
for details on some of the pertinent environment variables.
|
||||||
|
|
||||||
|
You can give `configure' initial values for configuration parameters
|
||||||
|
by setting variables in the command line or in the environment. Here
|
||||||
|
is an example:
|
||||||
|
|
||||||
|
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
|
||||||
|
|
||||||
|
*Note Defining Variables::, for more details.
|
||||||
|
|
||||||
|
Compiling For Multiple Architectures
|
||||||
|
====================================
|
||||||
|
|
||||||
|
You can compile the package for more than one kind of computer at the
|
||||||
|
same time, by placing the object files for each architecture in their
|
||||||
|
own directory. To do this, you must use a version of `make' that
|
||||||
|
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||||
|
directory where you want the object files and executables to go and run
|
||||||
|
the `configure' script. `configure' automatically checks for the
|
||||||
|
source code in the directory that `configure' is in and in `..'.
|
||||||
|
|
||||||
|
If you have to use a `make' that does not support the `VPATH'
|
||||||
|
variable, you have to compile the package for one architecture at a
|
||||||
|
time in the source code directory. After you have installed the
|
||||||
|
package for one architecture, use `make distclean' before reconfiguring
|
||||||
|
for another architecture.
|
||||||
|
|
||||||
|
Installation Names
|
||||||
|
==================
|
||||||
|
|
||||||
|
By default, `make install' will install the package's files in
|
||||||
|
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||||
|
installation prefix other than `/usr/local' by giving `configure' the
|
||||||
|
option `--prefix=PATH'.
|
||||||
|
|
||||||
|
You can specify separate installation prefixes for
|
||||||
|
architecture-specific files and architecture-independent files. If you
|
||||||
|
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||||
|
PATH as the prefix for installing programs and libraries.
|
||||||
|
Documentation and other data files will still use the regular prefix.
|
||||||
|
|
||||||
|
In addition, if you use an unusual directory layout you can give
|
||||||
|
options like `--bindir=PATH' to specify different values for particular
|
||||||
|
kinds of files. Run `configure --help' for a list of the directories
|
||||||
|
you can set and what kinds of files go in them.
|
||||||
|
|
||||||
|
If the package supports it, you can cause programs to be installed
|
||||||
|
with an extra prefix or suffix on their names by giving `configure' the
|
||||||
|
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||||
|
|
||||||
|
Optional Features
|
||||||
|
=================
|
||||||
|
|
||||||
|
Some packages pay attention to `--enable-FEATURE' options to
|
||||||
|
`configure', where FEATURE indicates an optional part of the package.
|
||||||
|
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||||
|
is something like `gnu-as' or `x' (for the X Window System). The
|
||||||
|
`README' should mention any `--enable-' and `--with-' options that the
|
||||||
|
package recognizes.
|
||||||
|
|
||||||
|
For packages that use the X Window System, `configure' can usually
|
||||||
|
find the X include and library files automatically, but if it doesn't,
|
||||||
|
you can use the `configure' options `--x-includes=DIR' and
|
||||||
|
`--x-libraries=DIR' to specify their locations.
|
||||||
|
|
||||||
|
Specifying the System Type
|
||||||
|
==========================
|
||||||
|
|
||||||
|
There may be some features `configure' cannot figure out
|
||||||
|
automatically, but needs to determine by the type of machine the package
|
||||||
|
will run on. Usually, assuming the package is built to be run on the
|
||||||
|
_same_ architectures, `configure' can figure that out, but if it prints
|
||||||
|
a message saying it cannot guess the machine type, give it the
|
||||||
|
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||||
|
type, such as `sun4', or a canonical name which has the form:
|
||||||
|
|
||||||
|
CPU-COMPANY-SYSTEM
|
||||||
|
|
||||||
|
where SYSTEM can have one of these forms:
|
||||||
|
|
||||||
|
OS KERNEL-OS
|
||||||
|
|
||||||
|
See the file `config.sub' for the possible values of each field. If
|
||||||
|
`config.sub' isn't included in this package, then this package doesn't
|
||||||
|
need to know the machine type.
|
||||||
|
|
||||||
|
If you are _building_ compiler tools for cross-compiling, you should
|
||||||
|
use the `--target=TYPE' option to select the type of system they will
|
||||||
|
produce code for.
|
||||||
|
|
||||||
|
If you want to _use_ a cross compiler, that generates code for a
|
||||||
|
platform different from the build platform, you should specify the
|
||||||
|
"host" platform (i.e., that on which the generated programs will
|
||||||
|
eventually be run) with `--host=TYPE'.
|
||||||
|
|
||||||
|
Sharing Defaults
|
||||||
|
================
|
||||||
|
|
||||||
|
If you want to set default values for `configure' scripts to share,
|
||||||
|
you can create a site shell script called `config.site' that gives
|
||||||
|
default values for variables like `CC', `cache_file', and `prefix'.
|
||||||
|
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||||
|
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||||
|
`CONFIG_SITE' environment variable to the location of the site script.
|
||||||
|
A warning: not all `configure' scripts look for a site script.
|
||||||
|
|
||||||
|
Defining Variables
|
||||||
|
==================
|
||||||
|
|
||||||
|
Variables not defined in a site shell script can be set in the
|
||||||
|
environment passed to `configure'. However, some packages may run
|
||||||
|
configure again during the build, and the customized values of these
|
||||||
|
variables may be lost. In order to avoid this problem, you should set
|
||||||
|
them in the `configure' command line, using `VAR=value'. For example:
|
||||||
|
|
||||||
|
./configure CC=/usr/local2/bin/gcc
|
||||||
|
|
||||||
|
will cause the specified gcc to be used as the C compiler (unless it is
|
||||||
|
overridden in the site shell script).
|
||||||
|
|
||||||
|
`configure' Invocation
|
||||||
|
======================
|
||||||
|
|
||||||
|
`configure' recognizes the following options to control how it
|
||||||
|
operates.
|
||||||
|
|
||||||
|
`--help'
|
||||||
|
`-h'
|
||||||
|
Print a summary of the options to `configure', and exit.
|
||||||
|
|
||||||
|
`--version'
|
||||||
|
`-V'
|
||||||
|
Print the version of Autoconf used to generate the `configure'
|
||||||
|
script, and exit.
|
||||||
|
|
||||||
|
`--cache-file=FILE'
|
||||||
|
Enable the cache: use and save the results of the tests in FILE,
|
||||||
|
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||||
|
disable caching.
|
||||||
|
|
||||||
|
`--config-cache'
|
||||||
|
`-C'
|
||||||
|
Alias for `--cache-file=config.cache'.
|
||||||
|
|
||||||
|
`--quiet'
|
||||||
|
`--silent'
|
||||||
|
`-q'
|
||||||
|
Do not print messages saying which checks are being made. To
|
||||||
|
suppress all normal output, redirect it to `/dev/null' (any error
|
||||||
|
messages will still be shown).
|
||||||
|
|
||||||
|
`--srcdir=DIR'
|
||||||
|
Look for the package's source code in directory DIR. Usually
|
||||||
|
`configure' can determine that directory automatically.
|
||||||
|
|
||||||
|
`configure' also accepts some other, not widely useful, options. Run
|
||||||
|
`configure --help' for more details.
|
||||||
|
|
19
Makefile.am
Normal file
19
Makefile.am
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# Automake requirements:
|
||||||
|
AUTOMAKE_OPTIONS = 1.7 gnu
|
||||||
|
|
||||||
|
SUBDIRS = . doc lightning opcode tests
|
||||||
|
EXTRA_DIST = config/texi2dvi config/help2man
|
||||||
|
|
||||||
|
dist_noinst_HEADERS = lightning-inst.h
|
||||||
|
nodist_noinst_HEADERS = lightning.h
|
||||||
|
|
||||||
|
uninstall-local:
|
||||||
|
-rm -f $(DESTDIR)$(includedir)/lightning.h
|
||||||
|
|
||||||
|
install-data-local:
|
||||||
|
$(mkinstalldirs) $(DESTDIR)$(includedir)
|
||||||
|
$(INSTALL_DATA) $(srcdir)/lightning-inst.h $(DESTDIR)$(includedir)/lightning.h
|
||||||
|
|
||||||
|
aclocaldir = $(datadir)/aclocal
|
||||||
|
dist_aclocal_DATA = lightning.m4
|
||||||
|
bin_SCRIPTS = lightningize
|
124
NEWS
Normal file
124
NEWS
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
NEWS FROM VERSION 1.1.2 TO 1.2
|
||||||
|
|
||||||
|
o Floating-point interface rewritten, uses a common register
|
||||||
|
file architecture rather than a stack.
|
||||||
|
|
||||||
|
o Many bug fixes.
|
||||||
|
|
||||||
|
o More (and more complete) examples provided.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
NEWS FROM VERSION 1.1.1 TO 1.1.2
|
||||||
|
|
||||||
|
o This release fixes the bugs in PowerPC cache flushing and in
|
||||||
|
SPARC testing.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
NEWS FROM VERSION 1.1 TO 1.1.1
|
||||||
|
|
||||||
|
o Merge changes from Debian
|
||||||
|
|
||||||
|
This version was released to have a distributable version of lightning
|
||||||
|
after the recent crack of the GNU FTP machines. It does not fix
|
||||||
|
outstanding bugs; I apologize for the inconvenience.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
NEWS FROM VERSION 1.0 TO 1.1
|
||||||
|
|
||||||
|
o Several bug fixes
|
||||||
|
|
||||||
|
o improved infrastructure for embedding GNU lightning (lightningize
|
||||||
|
script)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
NEWS FROM VERSION 0.99 TO 1.0
|
||||||
|
|
||||||
|
o SPARC backend tested on GNU Smalltalk
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
NEWS FROM VERSION 0.98 TO 0.99
|
||||||
|
|
||||||
|
o Added floating point function support (thanks to Laurent Michel);
|
||||||
|
unfortunately this broke even more the PPC and SPARC floating point
|
||||||
|
stuff :-(
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
NEWS FROM VERSION 0.97 to 0.98
|
||||||
|
|
||||||
|
o PPC backend tested on GNU Smalltalk
|
||||||
|
|
||||||
|
o switched to autoconf 2.50
|
||||||
|
|
||||||
|
o new (much faster) PPC cache flushing code by John McIntosh
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
NEWS FROM VERSION 0.96 to 0.97
|
||||||
|
|
||||||
|
o support for cross-assembling and for disassembling the code that the tests
|
||||||
|
generate
|
||||||
|
|
||||||
|
o PPC microtests pass (tested directly by me), SPARC was said to work
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
NEWS FROM VERSION 0.95 to 0.96
|
||||||
|
|
||||||
|
o fixed implementation of delay slots to be coherent with the manual
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
NEWS FROM VERSION 0.94 to 0.95
|
||||||
|
|
||||||
|
o adc/sbc replaced with addc/addx/subc/subx to allow for more optimization
|
||||||
|
(inspired by the PPC instruction set).
|
||||||
|
|
||||||
|
o A few fixes and much less warnings from the compiler
|
||||||
|
|
||||||
|
o Automake-ized everything
|
||||||
|
|
||||||
|
o i386 backend generates smaller code for bms/bmc/or/xor by using byte
|
||||||
|
or word versions if possible
|
||||||
|
|
||||||
|
o Moved backends to separate directories
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
NEWS FROM VERSION 0.93 to 0.94
|
||||||
|
|
||||||
|
o Manual builds as DVI file.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
NEWS FROM VERSION 0.92 to 0.93
|
||||||
|
|
||||||
|
o Floating-point front-end (began supporting PPC & SPARC).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
NEWS FROM VERSION 0.91 to 0.92
|
||||||
|
|
||||||
|
o Floating-point front-end (only x86 supported).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
NEWS FROM VERSION 0.9 to 0.91
|
||||||
|
|
||||||
|
o Carrying supported in addition/subtraction.
|
||||||
|
|
||||||
|
o insn type changed to jit_insn.
|
||||||
|
|
||||||
|
o Misc bug fixes.
|
||||||
|
|
||||||
|
o Reentrancy supported.
|
||||||
|
|
||||||
|
o SPARC run-time assembler rewritten.
|
||||||
|
|
||||||
|
o The run-time assembler can be disabled for debugging purposes.
|
3
README
Normal file
3
README
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
GNU lightning is a library to aid in making portable programs
|
||||||
|
that compile assembly code at run time. For more information,
|
||||||
|
look at the info documentation.
|
559
config/help2man
Executable file
559
config/help2man
Executable file
|
@ -0,0 +1,559 @@
|
||||||
|
#!/usr/bin/env perl
|
||||||
|
|
||||||
|
# Generate a short man page from --help and --version output.
|
||||||
|
# Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Free Software
|
||||||
|
# Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
# Written by Brendan O'Dea <bod@debian.org>
|
||||||
|
# Available from ftp://ftp.gnu.org/gnu/help2man/
|
||||||
|
|
||||||
|
use 5.005;
|
||||||
|
use strict;
|
||||||
|
use Getopt::Long;
|
||||||
|
use Text::Tabs qw(expand);
|
||||||
|
use POSIX qw(strftime setlocale LC_TIME);
|
||||||
|
|
||||||
|
my $this_program = 'help2man';
|
||||||
|
my $this_version = '1.28';
|
||||||
|
my $version_info = <<EOT;
|
||||||
|
GNU $this_program $this_version
|
||||||
|
|
||||||
|
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||||
|
This is free software; see the source for copying conditions. There is NO
|
||||||
|
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
Written by Brendan O'Dea <bod\@debian.org>
|
||||||
|
EOT
|
||||||
|
|
||||||
|
my $help_info = <<EOT;
|
||||||
|
`$this_program' generates a man page out of `--help' and `--version' output.
|
||||||
|
|
||||||
|
Usage: $this_program [OPTION]... EXECUTABLE
|
||||||
|
|
||||||
|
-n, --name=STRING description for the NAME paragraph
|
||||||
|
-s, --section=SECTION section number for manual page (1, 6, 8)
|
||||||
|
-m, --manual=TEXT name of manual (User Commands, ...)
|
||||||
|
-S, --source=TEXT source of program (FSF, Debian, ...)
|
||||||
|
-i, --include=FILE include material from `FILE'
|
||||||
|
-I, --opt-include=FILE include material from `FILE' if it exists
|
||||||
|
-o, --output=FILE send output to `FILE'
|
||||||
|
-p, --info-page=TEXT name of Texinfo manual
|
||||||
|
-N, --no-info suppress pointer to Texinfo manual
|
||||||
|
--help print this help, then exit
|
||||||
|
--version print version number, then exit
|
||||||
|
|
||||||
|
EXECUTABLE should accept `--help' and `--version' options although
|
||||||
|
alternatives may be specified using:
|
||||||
|
|
||||||
|
-h, --help-option=STRING help option string
|
||||||
|
-v, --version-option=STRING version option string
|
||||||
|
|
||||||
|
Report bugs to <bug-help2man\@gnu.org>.
|
||||||
|
EOT
|
||||||
|
|
||||||
|
my $section = 1;
|
||||||
|
my $manual = '';
|
||||||
|
my $source = '';
|
||||||
|
my $help_option = '--help';
|
||||||
|
my $version_option = '--version';
|
||||||
|
my ($opt_name, @opt_include, $opt_output, $opt_info, $opt_no_info);
|
||||||
|
|
||||||
|
my %opt_def = (
|
||||||
|
'n|name=s' => \$opt_name,
|
||||||
|
's|section=s' => \$section,
|
||||||
|
'm|manual=s' => \$manual,
|
||||||
|
'S|source=s' => \$source,
|
||||||
|
'i|include=s' => sub { push @opt_include, [ pop, 1 ] },
|
||||||
|
'I|opt-include=s' => sub { push @opt_include, [ pop, 0 ] },
|
||||||
|
'o|output=s' => \$opt_output,
|
||||||
|
'p|info-page=s' => \$opt_info,
|
||||||
|
'N|no-info' => \$opt_no_info,
|
||||||
|
'h|help-option=s' => \$help_option,
|
||||||
|
'v|version-option=s' => \$version_option,
|
||||||
|
);
|
||||||
|
|
||||||
|
# Parse options.
|
||||||
|
Getopt::Long::config('bundling');
|
||||||
|
GetOptions (%opt_def,
|
||||||
|
help => sub { print $help_info; exit },
|
||||||
|
version => sub { print $version_info; exit },
|
||||||
|
) or die $help_info;
|
||||||
|
|
||||||
|
die $help_info unless @ARGV == 1;
|
||||||
|
|
||||||
|
my %include = ();
|
||||||
|
my %append = ();
|
||||||
|
my @include = (); # retain order given in include file
|
||||||
|
|
||||||
|
# Process include file (if given). Format is:
|
||||||
|
#
|
||||||
|
# [section name]
|
||||||
|
# verbatim text
|
||||||
|
#
|
||||||
|
# or
|
||||||
|
#
|
||||||
|
# /pattern/
|
||||||
|
# verbatim text
|
||||||
|
#
|
||||||
|
|
||||||
|
while (@opt_include)
|
||||||
|
{
|
||||||
|
my ($inc, $required) = @{shift @opt_include};
|
||||||
|
|
||||||
|
next unless -f $inc or $required;
|
||||||
|
die "$this_program: can't open `$inc' ($!)\n"
|
||||||
|
unless open INC, $inc;
|
||||||
|
|
||||||
|
my $key;
|
||||||
|
my $hash = \%include;
|
||||||
|
|
||||||
|
while (<INC>)
|
||||||
|
{
|
||||||
|
# [section]
|
||||||
|
if (/^\[([^]]+)\]/)
|
||||||
|
{
|
||||||
|
$key = uc $1;
|
||||||
|
$key =~ s/^\s+//;
|
||||||
|
$key =~ s/\s+$//;
|
||||||
|
$hash = \%include;
|
||||||
|
push @include, $key unless $include{$key};
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
# /pattern/
|
||||||
|
if (m!^/(.*)/([ims]*)!)
|
||||||
|
{
|
||||||
|
my $pat = $2 ? "(?$2)$1" : $1;
|
||||||
|
|
||||||
|
# Check pattern.
|
||||||
|
eval { $key = qr($pat) };
|
||||||
|
if ($@)
|
||||||
|
{
|
||||||
|
$@ =~ s/ at .*? line \d.*//;
|
||||||
|
die "$inc:$.:$@";
|
||||||
|
}
|
||||||
|
|
||||||
|
$hash = \%append;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check for options before the first section--anything else is
|
||||||
|
# silently ignored, allowing the first for comments and
|
||||||
|
# revision info.
|
||||||
|
unless ($key)
|
||||||
|
{
|
||||||
|
# handle options
|
||||||
|
if (/^-/)
|
||||||
|
{
|
||||||
|
local @ARGV = split;
|
||||||
|
GetOptions %opt_def;
|
||||||
|
}
|
||||||
|
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
$hash->{$key} ||= '';
|
||||||
|
$hash->{$key} .= $_;
|
||||||
|
}
|
||||||
|
|
||||||
|
close INC;
|
||||||
|
|
||||||
|
die "$this_program: no valid information found in `$inc'\n"
|
||||||
|
unless $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Compress trailing blank lines.
|
||||||
|
for my $hash (\(%include, %append))
|
||||||
|
{
|
||||||
|
for (keys %$hash) { $hash->{$_} =~ s/\n+$/\n/ }
|
||||||
|
}
|
||||||
|
|
||||||
|
# Turn off localisation of executable's ouput.
|
||||||
|
@ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
|
||||||
|
|
||||||
|
# Turn off localisation of date (for strftime).
|
||||||
|
setlocale LC_TIME, 'C';
|
||||||
|
|
||||||
|
# Grab help and version info from executable.
|
||||||
|
my ($help_text, $version_text) = map {
|
||||||
|
join '', map { s/ +$//; expand $_ } `$ARGV[0] $_ 2>/dev/null`
|
||||||
|
or die "$this_program: can't get `$_' info from $ARGV[0]\n"
|
||||||
|
} $help_option, $version_option;
|
||||||
|
|
||||||
|
my $date = strftime "%B %Y", localtime;
|
||||||
|
(my $program = $ARGV[0]) =~ s!.*/!!;
|
||||||
|
my $package = $program;
|
||||||
|
my $version;
|
||||||
|
|
||||||
|
if ($opt_output)
|
||||||
|
{
|
||||||
|
unlink $opt_output
|
||||||
|
or die "$this_program: can't unlink $opt_output ($!)\n"
|
||||||
|
if -e $opt_output;
|
||||||
|
|
||||||
|
open STDOUT, ">$opt_output"
|
||||||
|
or die "$this_program: can't create $opt_output ($!)\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
# The first line of the --version information is assumed to be in one
|
||||||
|
# of the following formats:
|
||||||
|
#
|
||||||
|
# <version>
|
||||||
|
# <program> <version>
|
||||||
|
# {GNU,Free} <program> <version>
|
||||||
|
# <program> ({GNU,Free} <package>) <version>
|
||||||
|
# <program> - {GNU,Free} <package> <version>
|
||||||
|
#
|
||||||
|
# and seperated from any copyright/author details by a blank line.
|
||||||
|
|
||||||
|
($_, $version_text) = split /\n+/, $version_text, 2;
|
||||||
|
|
||||||
|
if (/^(\S+) +\(((?:GNU|Free) +[^)]+)\) +(.*)/ or
|
||||||
|
/^(\S+) +- *((?:GNU|Free) +\S+) +(.*)/)
|
||||||
|
{
|
||||||
|
$program = $1;
|
||||||
|
$package = $2;
|
||||||
|
$version = $3;
|
||||||
|
}
|
||||||
|
elsif (/^((?:GNU|Free) +)?(\S+) +(.*)/)
|
||||||
|
{
|
||||||
|
$program = $2;
|
||||||
|
$package = $1 ? "$1$2" : $2;
|
||||||
|
$version = $3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$version = $_;
|
||||||
|
}
|
||||||
|
|
||||||
|
$program =~ s!.*/!!;
|
||||||
|
|
||||||
|
# No info for `info' itself.
|
||||||
|
$opt_no_info = 1 if $program eq 'info';
|
||||||
|
|
||||||
|
# --name overrides --include contents.
|
||||||
|
$include{NAME} = "$program \\- $opt_name\n" if $opt_name;
|
||||||
|
|
||||||
|
# Default (useless) NAME paragraph.
|
||||||
|
$include{NAME} ||= "$program \\- manual page for $program $version\n";
|
||||||
|
|
||||||
|
# Man pages traditionally have the page title in caps.
|
||||||
|
my $PROGRAM = uc $program;
|
||||||
|
|
||||||
|
# Set default page head/footers
|
||||||
|
$source ||= "$program $version";
|
||||||
|
unless ($manual)
|
||||||
|
{
|
||||||
|
for ($section)
|
||||||
|
{
|
||||||
|
if (/^(1[Mm]|8)/) { $manual = 'System Administration Utilities' }
|
||||||
|
elsif (/^6/) { $manual = 'Games' }
|
||||||
|
else { $manual = 'User Commands' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Extract usage clause(s) [if any] for SYNOPSIS.
|
||||||
|
if ($help_text =~ s/^Usage:( +(\S+))(.*)((?:\n(?: {6}\1| *or: +\S).*)*)//m)
|
||||||
|
{
|
||||||
|
my @syn = $2 . $3;
|
||||||
|
|
||||||
|
if ($_ = $4)
|
||||||
|
{
|
||||||
|
s/^\n//;
|
||||||
|
for (split /\n/) { s/^ *(or: +)?//; push @syn, $_ }
|
||||||
|
}
|
||||||
|
|
||||||
|
my $synopsis = '';
|
||||||
|
for (@syn)
|
||||||
|
{
|
||||||
|
$synopsis .= ".br\n" if $synopsis;
|
||||||
|
s!^\S*/!!;
|
||||||
|
s/^(\S+) *//;
|
||||||
|
$synopsis .= ".B $1\n";
|
||||||
|
s/\s+$//;
|
||||||
|
s/(([][]|\.\.+)+)/\\fR$1\\fI/g;
|
||||||
|
s/^/\\fI/ unless s/^\\fR//;
|
||||||
|
$_ .= '\fR';
|
||||||
|
s/(\\fI)( *)/$2$1/g;
|
||||||
|
s/\\fI\\fR//g;
|
||||||
|
s/^\\fR//;
|
||||||
|
s/\\fI$//;
|
||||||
|
s/^\./\\&./;
|
||||||
|
|
||||||
|
$synopsis .= "$_\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$include{SYNOPSIS} ||= $synopsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Process text, initial section is DESCRIPTION.
|
||||||
|
my $sect = 'DESCRIPTION';
|
||||||
|
$_ = "$help_text\n\n$version_text";
|
||||||
|
|
||||||
|
# Normalise paragraph breaks.
|
||||||
|
s/^\n+//;
|
||||||
|
s/\n*$/\n/;
|
||||||
|
s/\n\n+/\n\n/g;
|
||||||
|
|
||||||
|
# Temporarily exchange leading dots, apostrophes and backslashes for
|
||||||
|
# tokens.
|
||||||
|
s/^\./\x80/mg;
|
||||||
|
s/^'/\x81/mg;
|
||||||
|
s/\\/\x82/g;
|
||||||
|
|
||||||
|
# Start a new paragraph (if required) for these.
|
||||||
|
s/([^\n])\n(Report +bugs|Email +bug +reports +to|Written +by)/$1\n\n$2/g;
|
||||||
|
|
||||||
|
sub convert_option;
|
||||||
|
|
||||||
|
while (length)
|
||||||
|
{
|
||||||
|
# Convert some standard paragraph names.
|
||||||
|
if (s/^(Options|Examples): *\n//)
|
||||||
|
{
|
||||||
|
$sect = uc $1;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Copyright section
|
||||||
|
if (/^Copyright +[(\xa9]/)
|
||||||
|
{
|
||||||
|
$sect = 'COPYRIGHT';
|
||||||
|
$include{$sect} ||= '';
|
||||||
|
$include{$sect} .= ".PP\n" if $include{$sect};
|
||||||
|
|
||||||
|
my $copy;
|
||||||
|
($copy, $_) = split /\n\n/, $_, 2;
|
||||||
|
|
||||||
|
for ($copy)
|
||||||
|
{
|
||||||
|
# Add back newline
|
||||||
|
s/\n*$/\n/;
|
||||||
|
|
||||||
|
# Convert iso9959-1 copyright symbol or (c) to nroff
|
||||||
|
# character.
|
||||||
|
s/^Copyright +(?:\xa9|\([Cc]\))/Copyright \\(co/mg;
|
||||||
|
|
||||||
|
# Insert line breaks before additional copyright messages
|
||||||
|
# and the disclaimer.
|
||||||
|
s/(.)\n(Copyright |This +is +free +software)/$1\n.br\n$2/g;
|
||||||
|
|
||||||
|
# Join hyphenated lines.
|
||||||
|
s/([A-Za-z])-\n */$1/g;
|
||||||
|
}
|
||||||
|
|
||||||
|
$include{$sect} .= $copy;
|
||||||
|
$_ ||= '';
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Catch bug report text.
|
||||||
|
if (/^(Report +bugs|Email +bug +reports +to) /)
|
||||||
|
{
|
||||||
|
$sect = 'REPORTING BUGS';
|
||||||
|
}
|
||||||
|
|
||||||
|
# Author section.
|
||||||
|
elsif (/^Written +by/)
|
||||||
|
{
|
||||||
|
$sect = 'AUTHOR';
|
||||||
|
}
|
||||||
|
|
||||||
|
# Examples, indicated by an indented leading $, % or > are
|
||||||
|
# rendered in a constant width font.
|
||||||
|
if (/^( +)([\$\%>] )\S/)
|
||||||
|
{
|
||||||
|
my $indent = $1;
|
||||||
|
my $prefix = $2;
|
||||||
|
my $break = '.IP';
|
||||||
|
$include{$sect} ||= '';
|
||||||
|
while (s/^$indent\Q$prefix\E(\S.*)\n*//)
|
||||||
|
{
|
||||||
|
$include{$sect} .= "$break\n\\f(CW$prefix$1\\fR\n";
|
||||||
|
$break = '.br';
|
||||||
|
}
|
||||||
|
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $matched = '';
|
||||||
|
$include{$sect} ||= '';
|
||||||
|
|
||||||
|
# Sub-sections have a trailing colon and the second line indented.
|
||||||
|
if (s/^(\S.*:) *\n / /)
|
||||||
|
{
|
||||||
|
$matched .= $& if %append;
|
||||||
|
$include{$sect} .= qq(.SS "$1"\n);
|
||||||
|
}
|
||||||
|
|
||||||
|
my $indent = 0;
|
||||||
|
my $content = '';
|
||||||
|
|
||||||
|
# Option with description.
|
||||||
|
if (s/^( {1,10}([+-]\S.*?))(?:( +(?!-))|\n( {20,}))(\S.*)\n//)
|
||||||
|
{
|
||||||
|
$matched .= $& if %append;
|
||||||
|
$indent = length ($4 || "$1$3");
|
||||||
|
$content = ".TP\n\x83$2\n\x83$5\n";
|
||||||
|
unless ($4)
|
||||||
|
{
|
||||||
|
# Indent may be different on second line.
|
||||||
|
$indent = length $& if /^ {20,}/;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Option without description.
|
||||||
|
elsif (s/^ {1,10}([+-]\S.*)\n//)
|
||||||
|
{
|
||||||
|
$matched .= $& if %append;
|
||||||
|
$content = ".HP\n\x83$1\n";
|
||||||
|
$indent = 80; # not continued
|
||||||
|
}
|
||||||
|
|
||||||
|
# Indented paragraph with tag.
|
||||||
|
elsif (s/^( +(\S.*?) +)(\S.*)\n//)
|
||||||
|
{
|
||||||
|
$matched .= $& if %append;
|
||||||
|
$indent = length $1;
|
||||||
|
$content = ".TP\n\x83$2\n\x83$3\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Indented paragraph.
|
||||||
|
elsif (s/^( +)(\S.*)\n//)
|
||||||
|
{
|
||||||
|
$matched .= $& if %append;
|
||||||
|
$indent = length $1;
|
||||||
|
$content = ".IP\n\x83$2\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Left justified paragraph.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s/(.*)\n//;
|
||||||
|
$matched .= $& if %append;
|
||||||
|
$content = ".PP\n" if $include{$sect};
|
||||||
|
$content .= "$1\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Append continuations.
|
||||||
|
while (s/^ {$indent}(\S.*)\n//)
|
||||||
|
{
|
||||||
|
$matched .= $& if %append;
|
||||||
|
$content .= "\x83$1\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Move to next paragraph.
|
||||||
|
s/^\n+//;
|
||||||
|
|
||||||
|
for ($content)
|
||||||
|
{
|
||||||
|
# Leading dot and apostrophe protection.
|
||||||
|
s/\x83\./\x80/g;
|
||||||
|
s/\x83'/\x81/g;
|
||||||
|
s/\x83//g;
|
||||||
|
|
||||||
|
# Convert options.
|
||||||
|
s/(^| )(-[][\w=-]+)/$1 . convert_option $2/mge;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if matched paragraph contains /pat/.
|
||||||
|
if (%append)
|
||||||
|
{
|
||||||
|
for my $pat (keys %append)
|
||||||
|
{
|
||||||
|
if ($matched =~ $pat)
|
||||||
|
{
|
||||||
|
$content .= ".PP\n" unless $append{$pat} =~ /^\./;
|
||||||
|
$content .= $append{$pat};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$include{$sect} .= $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Refer to the real documentation.
|
||||||
|
unless ($opt_no_info)
|
||||||
|
{
|
||||||
|
my $info_page = $opt_info || $program;
|
||||||
|
|
||||||
|
$sect = 'SEE ALSO';
|
||||||
|
$include{$sect} ||= '';
|
||||||
|
$include{$sect} .= ".PP\n" if $include{$sect};
|
||||||
|
$include{$sect} .= <<EOT;
|
||||||
|
The full documentation for
|
||||||
|
.B $program
|
||||||
|
is maintained as a Texinfo manual. If the
|
||||||
|
.B info
|
||||||
|
and
|
||||||
|
.B $program
|
||||||
|
programs are properly installed at your site, the command
|
||||||
|
.IP
|
||||||
|
.B info $info_page
|
||||||
|
.PP
|
||||||
|
should give you access to the complete manual.
|
||||||
|
EOT
|
||||||
|
}
|
||||||
|
|
||||||
|
# Output header.
|
||||||
|
print <<EOT;
|
||||||
|
.\\" DO NOT MODIFY THIS FILE! It was generated by $this_program $this_version.
|
||||||
|
.TH $PROGRAM "$section" "$date" "$source" "$manual"
|
||||||
|
EOT
|
||||||
|
|
||||||
|
# Section ordering.
|
||||||
|
my @pre = qw(NAME SYNOPSIS DESCRIPTION OPTIONS EXAMPLES);
|
||||||
|
my @post = ('AUTHOR', 'REPORTING BUGS', 'COPYRIGHT', 'SEE ALSO');
|
||||||
|
my $filter = join '|', @pre, @post;
|
||||||
|
|
||||||
|
# Output content.
|
||||||
|
for (@pre, (grep ! /^($filter)$/o, @include), @post)
|
||||||
|
{
|
||||||
|
if ($include{$_})
|
||||||
|
{
|
||||||
|
my $quote = /\W/ ? '"' : '';
|
||||||
|
print ".SH $quote$_$quote\n";
|
||||||
|
|
||||||
|
for ($include{$_})
|
||||||
|
{
|
||||||
|
# Replace leading dot, apostrophe and backslash tokens.
|
||||||
|
s/\x80/\\&./g;
|
||||||
|
s/\x81/\\&'/g;
|
||||||
|
s/\x82/\\e/g;
|
||||||
|
print;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit;
|
||||||
|
|
||||||
|
# Convert option dashes to \- to stop nroff from hyphenating 'em, and
|
||||||
|
# embolden. Option arguments get italicised.
|
||||||
|
sub convert_option
|
||||||
|
{
|
||||||
|
local $_ = '\fB' . shift;
|
||||||
|
|
||||||
|
s/-/\\-/g;
|
||||||
|
unless (s/\[=(.*)\]$/\\fR[=\\fI$1\\fR]/)
|
||||||
|
{
|
||||||
|
s/=(.)/\\fR=\\fI$1/;
|
||||||
|
s/ (.)/ \\fI$1/;
|
||||||
|
$_ .= '\fR';
|
||||||
|
}
|
||||||
|
|
||||||
|
$_;
|
||||||
|
}
|
660
config/texi2dvi
Executable file
660
config/texi2dvi
Executable file
|
@ -0,0 +1,660 @@
|
||||||
|
#! /bin/sh
|
||||||
|
# texi2dvi --- produce DVI (or PDF) files from Texinfo (or LaTeX) sources.
|
||||||
|
# $Id: texi2dvi,v 1.14 2003/02/05 00:42:33 karl Exp $
|
||||||
|
#
|
||||||
|
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2001,
|
||||||
|
# 2002, 2003 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, you can either send email to this
|
||||||
|
# program's maintainer or write to: The Free Software Foundation,
|
||||||
|
# Inc.; 59 Temple Place, Suite 330; Boston, MA 02111-1307, USA.
|
||||||
|
#
|
||||||
|
# Original author: Noah Friedman <friedman@gnu.org>.
|
||||||
|
#
|
||||||
|
# Please send bug reports, etc. to bug-texinfo@gnu.org.
|
||||||
|
# If possible, please send a copy of the output of the script called with
|
||||||
|
# the `--debug' option when making a bug report.
|
||||||
|
|
||||||
|
# This string is expanded by rcs automatically when this file is checked out.
|
||||||
|
rcs_revision='$Revision: 1.14 $'
|
||||||
|
rcs_version=`set - $rcs_revision; echo $2`
|
||||||
|
program=`echo $0 | sed -e 's!.*/!!'`
|
||||||
|
version="texi2dvi (GNU Texinfo 4.5) $rcs_version
|
||||||
|
|
||||||
|
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||||
|
There is NO warranty. You may redistribute this software
|
||||||
|
under the terms of the GNU General Public License.
|
||||||
|
For more information about these matters, see the files named COPYING."
|
||||||
|
|
||||||
|
usage="Usage: $program [OPTION]... FILE...
|
||||||
|
|
||||||
|
Run each Texinfo or LaTeX FILE through TeX in turn until all
|
||||||
|
cross-references are resolved, building all indices. The directory
|
||||||
|
containing each FILE is searched for included files. The suffix of FILE
|
||||||
|
is used to determine its language (LaTeX or Texinfo).
|
||||||
|
|
||||||
|
Makeinfo is used to perform Texinfo macro expansion before running TeX
|
||||||
|
when needed.
|
||||||
|
|
||||||
|
Operation modes:
|
||||||
|
-b, --batch no interaction
|
||||||
|
-c, --clean remove all auxiliary files
|
||||||
|
-D, --debug turn on shell debugging (set -x)
|
||||||
|
-h, --help display this help and exit successfully
|
||||||
|
-o, --output=OFILE leave output in OFILE (implies --clean);
|
||||||
|
Only one input FILE may be specified in this case
|
||||||
|
-q, --quiet no output unless errors (implies --batch)
|
||||||
|
-s, --silent same as --quiet
|
||||||
|
-v, --version display version information and exit successfully
|
||||||
|
-V, --verbose report on what is done
|
||||||
|
|
||||||
|
TeX tuning:
|
||||||
|
-@ use @input instead of \input; for preloaded Texinfo
|
||||||
|
-e, -E, --expand force macro expansion using makeinfo
|
||||||
|
-I DIR search DIR for Texinfo files
|
||||||
|
-l, --language=LANG specify the LANG of FILE (LaTeX or Texinfo)
|
||||||
|
-p, --pdf use pdftex or pdflatex for processing
|
||||||
|
-t, --texinfo=CMD insert CMD after @setfilename in copy of input file
|
||||||
|
multiple values accumulate
|
||||||
|
|
||||||
|
The values of the BIBTEX, LATEX (or PDFLATEX), MAKEINDEX, MAKEINFO,
|
||||||
|
TEX (or PDFTEX), and TEXINDEX environment variables are used to run
|
||||||
|
those commands, if they are set.
|
||||||
|
|
||||||
|
Email bug reports to <bug-texinfo@gnu.org>,
|
||||||
|
general questions and discussion to <help-texinfo@gnu.org>.
|
||||||
|
Texinfo home page: http://www.gnu.org/software/texinfo/"
|
||||||
|
|
||||||
|
# Initialize variables for option overriding and otherwise.
|
||||||
|
# Don't use `unset' since old bourne shells don't have this command.
|
||||||
|
# Instead, assign them an empty value.
|
||||||
|
batch=false # eval for batch mode
|
||||||
|
clean=
|
||||||
|
debug=
|
||||||
|
escape='\'
|
||||||
|
expand= # t for expansion via makeinfo
|
||||||
|
miincludes= # makeinfo include path
|
||||||
|
oformat=dvi
|
||||||
|
oname= # --output
|
||||||
|
quiet= # by default let the tools' message be displayed
|
||||||
|
set_language=
|
||||||
|
textra=
|
||||||
|
tmpdir=${TMPDIR:-/tmp}/t2d$$ # avoid collisions on 8.3 filesystems.
|
||||||
|
txincludes= # TEXINPUTS extensions, with trailing colon
|
||||||
|
txiprereq=19990129 # minimum texinfo.tex version to have macro expansion
|
||||||
|
verbose=false # echo for verbose mode
|
||||||
|
|
||||||
|
orig_pwd=`pwd`
|
||||||
|
|
||||||
|
# Systems which define $COMSPEC or $ComSpec use semicolons to separate
|
||||||
|
# directories in TEXINPUTS.
|
||||||
|
if test -n "$COMSPEC$ComSpec"; then
|
||||||
|
path_sep=";"
|
||||||
|
else
|
||||||
|
path_sep=":"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Pacify verbose cds.
|
||||||
|
CDPATH=${ZSH_VERSION+.}$path_sep
|
||||||
|
|
||||||
|
# In case someone crazy insists on using grep -E.
|
||||||
|
: ${EGREP=egrep}
|
||||||
|
|
||||||
|
# Save this so we can construct a new TEXINPUTS path for each file.
|
||||||
|
TEXINPUTS_orig="$TEXINPUTS"
|
||||||
|
# Unfortunately makeindex does not read TEXINPUTS.
|
||||||
|
INDEXSTYLE_orig="$INDEXSTYLE"
|
||||||
|
export TEXINPUTS INDEXSTYLE
|
||||||
|
|
||||||
|
# Push a token among the arguments that will be used to notice when we
|
||||||
|
# ended options/arguments parsing.
|
||||||
|
# Use "set dummy ...; shift" rather than 'set - ..." because on
|
||||||
|
# Solaris set - turns off set -x (but keeps set -e).
|
||||||
|
# Use ${1+"$@"} rather than "$@" because Digital Unix and Ultrix 4.3
|
||||||
|
# still expand "$@" to a single argument (the empty string) rather
|
||||||
|
# than nothing at all.
|
||||||
|
arg_sep="$$--$$"
|
||||||
|
set dummy ${1+"$@"} "$arg_sep"; shift
|
||||||
|
|
||||||
|
#
|
||||||
|
# Parse command line arguments.
|
||||||
|
while test x"$1" != x"$arg_sep"; do
|
||||||
|
|
||||||
|
# Handle --option=value by splitting apart and putting back on argv.
|
||||||
|
case "$1" in
|
||||||
|
--*=*)
|
||||||
|
opt=`echo "$1" | sed -e 's/=.*//'`
|
||||||
|
val=`echo "$1" | sed -e 's/[^=]*=//'`
|
||||||
|
shift
|
||||||
|
set dummy "$opt" "$val" ${1+"$@"}; shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# This recognizes --quark as --quiet. So what.
|
||||||
|
case "$1" in
|
||||||
|
-@ ) escape=@;;
|
||||||
|
# Silently and without documentation accept -b and --b[atch] as synonyms.
|
||||||
|
-b | --b*) batch=eval;;
|
||||||
|
-q | -s | --q* | --s*) quiet=t; batch=eval;;
|
||||||
|
-c | --c*) clean=t;;
|
||||||
|
-D | --d*) debug=t;;
|
||||||
|
-e | -E | --e*) expand=t;;
|
||||||
|
-h | --h*) echo "$usage"; exit 0;;
|
||||||
|
-I | --I*)
|
||||||
|
shift
|
||||||
|
miincludes="$miincludes -I $1"
|
||||||
|
txincludes="$txincludes$1$path_sep"
|
||||||
|
;;
|
||||||
|
-l | --l*) shift; set_language=$1;;
|
||||||
|
-o | --o*)
|
||||||
|
shift
|
||||||
|
clean=t
|
||||||
|
case "$1" in
|
||||||
|
/* | ?:/*) oname=$1;;
|
||||||
|
*) oname="$orig_pwd/$1";;
|
||||||
|
esac;;
|
||||||
|
-p | --p*) oformat=pdf;;
|
||||||
|
-t | --t*) shift; textra="$textra\\
|
||||||
|
$1";;
|
||||||
|
-v | --vers*) echo "$version"; exit 0;;
|
||||||
|
-V | --verb*) verbose=echo;;
|
||||||
|
--) # What remains are not options.
|
||||||
|
shift
|
||||||
|
while test x"$1" != x"$arg_sep"; do
|
||||||
|
set dummy ${1+"$@"} "$1"; shift
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
break;;
|
||||||
|
-*)
|
||||||
|
echo "$0: Unknown or ambiguous option \`$1'." >&2
|
||||||
|
echo "$0: Try \`--help' for more information." >&2
|
||||||
|
exit 1;;
|
||||||
|
*) set dummy ${1+"$@"} "$1"; shift;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
# Pop the token
|
||||||
|
shift
|
||||||
|
|
||||||
|
# Interpret remaining command line args as filenames.
|
||||||
|
case $# in
|
||||||
|
0)
|
||||||
|
echo "$0: Missing file arguments." >&2
|
||||||
|
echo "$0: Try \`--help' for more information." >&2
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
1) ;;
|
||||||
|
*)
|
||||||
|
if test -n "$oname"; then
|
||||||
|
echo "$0: Can't use option \`--output' with more than one argument." >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Prepare the temporary directory. Remove it at exit, unless debugging.
|
||||||
|
if test -z "$debug"; then
|
||||||
|
trap "cd / && rm -rf $tmpdir" 0 1 2 15
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create the temporary directory with strict rights
|
||||||
|
(umask 077 && mkdir $tmpdir) || exit 1
|
||||||
|
|
||||||
|
# Prepare the tools we might need. This may be extra work in some
|
||||||
|
# cases, but improves the readibility of the script.
|
||||||
|
utildir=$tmpdir/utils
|
||||||
|
mkdir $utildir || exit 1
|
||||||
|
|
||||||
|
# A sed script that preprocesses Texinfo sources in order to keep the
|
||||||
|
# iftex sections only. We want to remove non TeX sections, and
|
||||||
|
# comment (with `@c texi2dvi') TeX sections so that makeinfo does not
|
||||||
|
# try to parse them. Nevertheless, while commenting TeX sections,
|
||||||
|
# don't comment @macro/@end macro so that makeinfo does propagate
|
||||||
|
# them. Unfortunately makeinfo --iftex --no-ifhtml --no-ifinfo
|
||||||
|
# doesn't work well enough (yet) to use that, so work around with sed.
|
||||||
|
comment_iftex_sed=$utildir/comment.sed
|
||||||
|
cat <<EOF >$comment_iftex_sed
|
||||||
|
/^@tex/,/^@end tex/{
|
||||||
|
s/^/@c texi2dvi/
|
||||||
|
}
|
||||||
|
/^@iftex/,/^@end iftex/{
|
||||||
|
s/^/@c texi2dvi/
|
||||||
|
/^@c texi2dvi@macro/,/^@c texi2dvi@end macro/{
|
||||||
|
s/^@c texi2dvi//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/^@html/,/^@end html/{
|
||||||
|
s/^/@c (texi2dvi)/
|
||||||
|
}
|
||||||
|
/^@ifhtml/,/^@end ifhtml/{
|
||||||
|
s/^/@c (texi2dvi)/
|
||||||
|
}
|
||||||
|
/^@ifnottex/,/^@end ifnottex/{
|
||||||
|
s/^/@c (texi2dvi)/
|
||||||
|
}
|
||||||
|
/^@ifinfo/,/^@end ifinfo/{
|
||||||
|
/^@node/p
|
||||||
|
/^@menu/,/^@end menu/p
|
||||||
|
t
|
||||||
|
s/^/@c (texi2dvi)/
|
||||||
|
}
|
||||||
|
s/^@ifnotinfo/@c texi2dvi@ifnotinfo/
|
||||||
|
s/^@end ifnotinfo/@c texi2dvi@end ifnotinfo/
|
||||||
|
EOF
|
||||||
|
# Uncommenting is simple: Remove any leading `@c texi2dvi'.
|
||||||
|
uncomment_iftex_sed=$utildir/uncomment.sed
|
||||||
|
cat <<EOF >$uncomment_iftex_sed
|
||||||
|
s/^@c texi2dvi//
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# A shell script that computes the list of xref files.
|
||||||
|
# Takes the filename (without extension) of which we look for xref
|
||||||
|
# files as argument. The index files must be reported last.
|
||||||
|
get_xref_files=$utildir/get_xref.sh
|
||||||
|
cat <<\EOF >$get_xref_files
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
# Get list of xref files (indexes, tables and lists).
|
||||||
|
# Find all files having root filename with a two-letter extension,
|
||||||
|
# saves the ones that are really Texinfo-related files. .?o? catches
|
||||||
|
# many files: .toc, .log, LaTeX tables and lists, FiXme's .lox, maybe more.
|
||||||
|
for this_file in "$1".?o? "$1".aux "$1".?? "$1".idx; do
|
||||||
|
# If file is empty, skip it.
|
||||||
|
test -s "$this_file" || continue
|
||||||
|
# If the file is not suitable to be an index or xref file, don't
|
||||||
|
# process it. The file can't be if its first character is not a
|
||||||
|
# backslash or single quote.
|
||||||
|
first_character=`sed -n '1s/^\(.\).*$/\1/p;q' $this_file`
|
||||||
|
if test "x$first_character" = "x\\" \
|
||||||
|
|| test "x$first_character" = "x'"; then
|
||||||
|
xref_files="$xref_files ./$this_file"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "$xref_files"
|
||||||
|
EOF
|
||||||
|
chmod 500 $get_xref_files
|
||||||
|
|
||||||
|
# File descriptor usage:
|
||||||
|
# 0 standard input
|
||||||
|
# 1 standard output (--verbose messages)
|
||||||
|
# 2 standard error
|
||||||
|
# 3 some systems may open it to /dev/tty
|
||||||
|
# 4 used on the Kubota Titan
|
||||||
|
# 5 tools output (turned off by --quiet)
|
||||||
|
|
||||||
|
# Tools' output. If quiet, discard, else redirect to the message flow.
|
||||||
|
if test "$quiet" = t; then
|
||||||
|
exec 5>/dev/null
|
||||||
|
else
|
||||||
|
exec 5>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Enable tracing
|
||||||
|
test "$debug" = t && set -x
|
||||||
|
|
||||||
|
#
|
||||||
|
# TeXify files.
|
||||||
|
|
||||||
|
for command_line_filename in ${1+"$@"}; do
|
||||||
|
$verbose "Processing $command_line_filename ..."
|
||||||
|
|
||||||
|
# If the COMMAND_LINE_FILENAME is not absolute (e.g., --debug.tex),
|
||||||
|
# prepend `./' in order to avoid that the tools take it as an option.
|
||||||
|
echo "$command_line_filename" | $EGREP '^(/|[A-z]:/)' >/dev/null \
|
||||||
|
|| command_line_filename="./$command_line_filename"
|
||||||
|
|
||||||
|
# See if the file exists. If it doesn't we're in trouble since, even
|
||||||
|
# though the user may be able to reenter a valid filename at the tex
|
||||||
|
# prompt (assuming they're attending the terminal), this script won't
|
||||||
|
# be able to find the right xref files and so forth.
|
||||||
|
if test ! -r "$command_line_filename"; then
|
||||||
|
echo "$0: Could not read $command_line_filename, skipping." >&2
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get the name of the current directory. We want the full path
|
||||||
|
# because in clean mode we are in tmp, in which case a relative
|
||||||
|
# path has no meaning.
|
||||||
|
filename_dir=`echo $command_line_filename | sed 's!/[^/]*$!!;s!^$!.!'`
|
||||||
|
filename_dir=`cd "$filename_dir" >/dev/null && pwd`
|
||||||
|
|
||||||
|
# Strip directory part but leave extension.
|
||||||
|
filename_ext=`basename "$command_line_filename"`
|
||||||
|
# Strip extension.
|
||||||
|
filename_noext=`echo "$filename_ext" | sed 's/\.[^.]*$//'`
|
||||||
|
ext=`echo "$filename_ext" | sed 's/^.*\.//'`
|
||||||
|
|
||||||
|
# _src. Use same basename since we want to generate aux files with
|
||||||
|
# the same basename as the manual. If --expand, then output the
|
||||||
|
# macro-expanded file to here, else copy the original file.
|
||||||
|
tmpdir_src=$tmpdir/src
|
||||||
|
filename_src=$tmpdir_src/$filename_noext.$ext
|
||||||
|
|
||||||
|
# _xtr. The file with the user's extra commands.
|
||||||
|
tmpdir_xtr=$tmpdir/xtr
|
||||||
|
filename_xtr=$tmpdir_xtr/$filename_noext.$ext
|
||||||
|
|
||||||
|
# _bak. Copies of the previous xref files (another round is run if
|
||||||
|
# they differ from the new one).
|
||||||
|
tmpdir_bak=$tmpdir/bak
|
||||||
|
|
||||||
|
# Make all those directories and give up if we can't succeed.
|
||||||
|
mkdir $tmpdir_src $tmpdir_xtr $tmpdir_bak || exit 1
|
||||||
|
|
||||||
|
# Source file might include additional sources.
|
||||||
|
# We want `.:$orig_pwd' before anything else. (We'll add `.:' later
|
||||||
|
# after all other directories have been turned into absolute paths.)
|
||||||
|
# `.' goes first to ensure that any old .aux, .cps,
|
||||||
|
# etc. files in ${directory} don't get used in preference to fresher
|
||||||
|
# files in `.'. Include orig_pwd in case we are in clean mode, where
|
||||||
|
# we've cd'd to a temp directory.
|
||||||
|
common="$orig_pwd$path_sep$filename_dir$path_sep$txincludes"
|
||||||
|
TEXINPUTS="$common$TEXINPUTS_orig"
|
||||||
|
INDEXSTYLE="$common$INDEXSTYLE_orig"
|
||||||
|
|
||||||
|
# Convert relative paths to absolute paths, so we can run in another
|
||||||
|
# directory (e.g., in --clean mode, or during the macro-support
|
||||||
|
# detection.)
|
||||||
|
#
|
||||||
|
# Empty path components are meaningful to tex. We rewrite them
|
||||||
|
# as `EMPTY' so they don't get lost when we split on $path_sep.
|
||||||
|
TEXINPUTS=`echo $TEXINPUTS |sed 's/^:/EMPTY:/;s/:$/:EMPTY/;s/::/:EMPTY:/g'`
|
||||||
|
INDEXSTYLE=`echo $INDEXSTYLE |sed 's/^:/EMPTY:/;s/:$/:EMPTY/;s/::/:EMPTY:/g'`
|
||||||
|
save_IFS=$IFS
|
||||||
|
IFS=$path_sep
|
||||||
|
set x $TEXINPUTS; shift
|
||||||
|
TEXINPUTS=.
|
||||||
|
for dir
|
||||||
|
do
|
||||||
|
case $dir in
|
||||||
|
EMPTY)
|
||||||
|
TEXINPUTS=$TEXINPUTS$path_sep
|
||||||
|
;;
|
||||||
|
[\\/]* | ?:[\\/]*) # Absolute paths don't need to be expansed.
|
||||||
|
TEXINPUTS=$TEXINPUTS$path_sep$dir
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
abs=`cd "$dir" && pwd` && TEXINPUTS=$TEXINPUTS$path_sep$abs
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
set x $INDEXSTYLE; shift
|
||||||
|
INDEXSTYLE=.
|
||||||
|
for dir
|
||||||
|
do
|
||||||
|
case $dir in
|
||||||
|
EMPTY)
|
||||||
|
INDEXSTYLE=$INDEXSTYLE$path_sep
|
||||||
|
;;
|
||||||
|
[\\/]* | ?:[\\/]*) # Absolute paths don't need to be expansed.
|
||||||
|
INDEXSTYLE=$INDEXSTYLE$path_sep$dir
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
abs=`cd "$dir" && pwd` && INDEXSTYLE=$INDEXSTYLE$path_sep$abs
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
IFS=$save_IFS
|
||||||
|
|
||||||
|
# If the user explicitly specified the language, use that.
|
||||||
|
# Otherwise, if the first line is \input texinfo, assume it's texinfo.
|
||||||
|
# Otherwise, guess from the file extension.
|
||||||
|
if test -n "$set_language"; then
|
||||||
|
language=$set_language
|
||||||
|
elif sed 1q "$command_line_filename" | grep 'input texinfo' >/dev/null; then
|
||||||
|
language=texinfo
|
||||||
|
else
|
||||||
|
language=
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get the type of the file (latex or texinfo) from the given language
|
||||||
|
# we just guessed, or from the file extension if not set yet.
|
||||||
|
case ${language:-$filename_ext} in
|
||||||
|
[lL]a[tT]e[xX] | *.ltx | *.tex)
|
||||||
|
# Assume a LaTeX file. LaTeX needs bibtex and uses latex for
|
||||||
|
# compilation. No makeinfo.
|
||||||
|
bibtex=${BIBTEX:-bibtex}
|
||||||
|
makeinfo= # no point in running makeinfo on latex source.
|
||||||
|
texindex=${MAKEINDEX:-makeindex}
|
||||||
|
if test $oformat = dvi; then
|
||||||
|
tex=${LATEX:-latex}
|
||||||
|
else
|
||||||
|
tex=${PDFLATEX:-pdflatex}
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
# Assume a Texinfo file. Texinfo files need makeinfo, texindex and tex.
|
||||||
|
bibtex=
|
||||||
|
texindex=${TEXINDEX:-texindex}
|
||||||
|
if test $oformat = dvi; then
|
||||||
|
tex=${TEX:-tex}
|
||||||
|
else
|
||||||
|
tex=${PDFTEX:-pdftex}
|
||||||
|
fi
|
||||||
|
# Unless required by the user, makeinfo expansion is wanted only
|
||||||
|
# if texinfo.tex is too old.
|
||||||
|
if test "$expand" = t; then
|
||||||
|
makeinfo=${MAKEINFO:-makeinfo}
|
||||||
|
else
|
||||||
|
# Check if texinfo.tex performs macro expansion by looking for
|
||||||
|
# its version. The version is a date of the form YEAR-MO-DA.
|
||||||
|
# We don't need to use [0-9] to match the digits since anyway
|
||||||
|
# the comparison with $txiprereq, a number, will fail with non
|
||||||
|
# digits.
|
||||||
|
txiversion_tex=txiversion.tex
|
||||||
|
echo '\input texinfo.tex @bye' >$tmpdir/$txiversion_tex
|
||||||
|
# Run in the tmpdir to avoid leaving files.
|
||||||
|
eval `cd $tmpdir >/dev/null &&
|
||||||
|
$tex $txiversion_tex 2>/dev/null |
|
||||||
|
sed -n 's/^.*\[\(.*\)version \(....\)-\(..\)-\(..\).*$/txiformat=\1 txiversion="\2\3\4"/p'`
|
||||||
|
$verbose "texinfo.tex preloaded as \`$txiformat', version is \`$txiversion' ..."
|
||||||
|
if test "$txiprereq" -le "$txiversion" >/dev/null 2>&1; then
|
||||||
|
makeinfo=
|
||||||
|
else
|
||||||
|
makeinfo=${MAKEINFO:-makeinfo}
|
||||||
|
fi
|
||||||
|
# As long as we had to run TeX, offer the user this convenience
|
||||||
|
if test "$txiformat" = Texinfo; then
|
||||||
|
escape=@
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Expand macro commands in the original source file using Makeinfo.
|
||||||
|
# Always use `end' footnote style, since the `separate' style
|
||||||
|
# generates different output (arguably this is a bug in -E).
|
||||||
|
# Discard main info output, the user asked to run TeX, not makeinfo.
|
||||||
|
if test -n "$makeinfo"; then
|
||||||
|
$verbose "Macro-expanding $command_line_filename to $filename_src ..."
|
||||||
|
sed -f $comment_iftex_sed "$command_line_filename" \
|
||||||
|
| $makeinfo --footnote-style=end -I "$filename_dir" $miincludes \
|
||||||
|
-o /dev/null --macro-expand=- \
|
||||||
|
| sed -f $uncomment_iftex_sed >"$filename_src"
|
||||||
|
filename_input=$filename_src
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If makeinfo failed (or was not even run), use the original file as input.
|
||||||
|
if test $? -ne 0 \
|
||||||
|
|| test ! -r "$filename_src"; then
|
||||||
|
$verbose "Reverting to $command_line_filename ..."
|
||||||
|
filename_input=$filename_dir/$filename_ext
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Used most commonly for @finalout, @smallbook, etc.
|
||||||
|
if test -n "$textra"; then
|
||||||
|
$verbose "Inserting extra commands: $textra"
|
||||||
|
sed '/^@setfilename/a\
|
||||||
|
'"$textra" "$filename_input" >$filename_xtr
|
||||||
|
filename_input=$filename_xtr
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If clean mode was specified, then move to the temporary directory.
|
||||||
|
if test "$clean" = t; then
|
||||||
|
$verbose "cd $tmpdir_src"
|
||||||
|
cd "$tmpdir_src" || exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while :; do # will break out of loop below
|
||||||
|
orig_xref_files=`$get_xref_files "$filename_noext"`
|
||||||
|
|
||||||
|
# Save copies of originals for later comparison.
|
||||||
|
if test -n "$orig_xref_files"; then
|
||||||
|
$verbose "Backing up xref files: `echo $orig_xref_files | sed 's|\./||g'`"
|
||||||
|
cp $orig_xref_files $tmpdir_bak
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run bibtex on current file.
|
||||||
|
# - If its input (AUX) exists.
|
||||||
|
# - If AUX contains both `\bibdata' and `\bibstyle'.
|
||||||
|
# - If some citations are missing (LOG contains `Citation').
|
||||||
|
# or the LOG complains of a missing .bbl
|
||||||
|
#
|
||||||
|
# We run bibtex first, because I can see reasons for the indexes
|
||||||
|
# to change after bibtex is run, but I see no reason for the
|
||||||
|
# converse.
|
||||||
|
#
|
||||||
|
# Don't try to be too smart. Running bibtex only if the bbl file
|
||||||
|
# exists and is older than the LaTeX file is wrong, since the
|
||||||
|
# document might include files that have changed. Because there
|
||||||
|
# can be several AUX (if there are \include's), but a single LOG,
|
||||||
|
# looking for missing citations in LOG is easier, though we take
|
||||||
|
# the risk to match false messages.
|
||||||
|
if test -n "$bibtex" \
|
||||||
|
&& test -r "$filename_noext.aux" \
|
||||||
|
&& test -r "$filename_noext.log" \
|
||||||
|
&& (grep '^\\bibdata[{]' "$filename_noext.aux" \
|
||||||
|
&& grep '^\\bibstyle[{]' "$filename_noext.aux" \
|
||||||
|
&& (grep 'Warning:.*Citation.*undefined' "$filename_noext.log" \
|
||||||
|
|| grep 'No file .*\.bbl\.' "$filename_noext.log")) \
|
||||||
|
>/dev/null 2>&1; \
|
||||||
|
then
|
||||||
|
$verbose "Running $bibtex $filename_noext ..."
|
||||||
|
if $bibtex "$filename_noext" >&5; then :; else
|
||||||
|
echo "$0: $bibtex exited with bad status, quitting." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# What we'll run texindex on -- exclude non-index files.
|
||||||
|
# Since we know index files are last, it is correct to remove everything
|
||||||
|
# before .aux and .?o?. But don't really do <anything>o<anything>
|
||||||
|
# -- don't match whitespace as <anything>.
|
||||||
|
# Otherwise, if orig_xref_files contains something like
|
||||||
|
# foo.xo foo.whatever
|
||||||
|
# the space after the o will get matched.
|
||||||
|
index_files=`echo "$orig_xref_files" \
|
||||||
|
| sed "s!.*\.aux!!g;
|
||||||
|
s!./$filename_noext\.[^ ]o[^ ]!!g;
|
||||||
|
s/^[ ]*//;s/[ ]*$//"`
|
||||||
|
# Run texindex (or makeindex) on current index files. If they
|
||||||
|
# already exist, and after running TeX a first time the index
|
||||||
|
# files don't change, then there's no reason to run TeX again.
|
||||||
|
# But we won't know that if the index files are out of date or
|
||||||
|
# nonexistent.
|
||||||
|
if test -n "$texindex" && test -n "$index_files"; then
|
||||||
|
$verbose "Running $texindex $index_files ..."
|
||||||
|
if $texindex $index_files 2>&5 1>&2; then :; else
|
||||||
|
echo "$0: $texindex exited with bad status, quitting." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Finally, run TeX.
|
||||||
|
# Prevent $ESCAPE from being interpreted by the shell if it happens
|
||||||
|
# to be `/'.
|
||||||
|
$batch tex_args="\\${escape}nonstopmode\ \\${escape}input"
|
||||||
|
cmd="$tex $tex_args $filename_input"
|
||||||
|
$verbose "Running $cmd ..."
|
||||||
|
if $cmd >&5; then :; else
|
||||||
|
echo "$0: $tex exited with bad status, quitting." >&2
|
||||||
|
echo "$0: see $filename_noext.log for errors." >&2
|
||||||
|
test "$clean" = t \
|
||||||
|
&& cp "$filename_noext.log" "$orig_pwd"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Decide if looping again is needed.
|
||||||
|
finished=t
|
||||||
|
|
||||||
|
# LaTeX (and the package changebar) report in the LOG file if it
|
||||||
|
# should be rerun. This is needed for files included from
|
||||||
|
# subdirs, since texi2dvi does not try to compare xref files in
|
||||||
|
# subdirs. Performing xref files test is still good since LaTeX
|
||||||
|
# does not report changes in xref files.
|
||||||
|
if grep "Rerun to get" "$filename_noext.log" >/dev/null 2>&1; then
|
||||||
|
finished=
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if xref files changed.
|
||||||
|
new_xref_files=`$get_xref_files "$filename_noext"`
|
||||||
|
$verbose "Original xref files = `echo $orig_xref_files | sed 's|\./||g'`"
|
||||||
|
$verbose "New xref files = `echo $new_xref_files | sed 's|\./||g'`"
|
||||||
|
|
||||||
|
# If old and new lists don't at least have the same file list,
|
||||||
|
# then one file or another has definitely changed.
|
||||||
|
test "x$orig_xref_files" != "x$new_xref_files" && finished=
|
||||||
|
|
||||||
|
# File list is the same. We must compare each file until we find
|
||||||
|
# a difference.
|
||||||
|
if test -n "$finished"; then
|
||||||
|
for this_file in $new_xref_files; do
|
||||||
|
$verbose "Comparing xref file `echo $this_file | sed 's|\./||g'` ..."
|
||||||
|
# cmp -s returns nonzero exit status if files differ.
|
||||||
|
if cmp -s "$this_file" "$tmpdir_bak/$this_file"; then :; else
|
||||||
|
# We only need to keep comparing until we find one that
|
||||||
|
# differs, because we'll have to run texindex & tex again no
|
||||||
|
# matter how many more there might be.
|
||||||
|
finished=
|
||||||
|
$verbose "xref file `echo $this_file | sed 's|\./||g'` differed ..."
|
||||||
|
test "$debug" = t && diff -c "$tmpdir_bak/$this_file" "$this_file"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If finished, exit the loop, else rerun the loop.
|
||||||
|
test -n "$finished" && break
|
||||||
|
done
|
||||||
|
|
||||||
|
# If we were in clean mode, compilation was in a tmp directory.
|
||||||
|
# Copy the DVI (or PDF) file into the directory where the compilation
|
||||||
|
# has been done. (The temp dir is about to get removed anyway.)
|
||||||
|
# We also return to the original directory so that
|
||||||
|
# - the next file is processed in correct conditions
|
||||||
|
# - the temporary file can be removed
|
||||||
|
if test -n "$clean"; then
|
||||||
|
if test -n "$oname"; then
|
||||||
|
dest=$oname
|
||||||
|
else
|
||||||
|
dest=$orig_pwd
|
||||||
|
fi
|
||||||
|
$verbose "Copying $oformat file from `pwd` to $dest"
|
||||||
|
cp -p "./$filename_noext.$oformat" "$dest"
|
||||||
|
cd / # in case $orig_pwd is on a different drive (for DOS)
|
||||||
|
cd $orig_pwd || exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove temporary files.
|
||||||
|
if test "x$debug" = "x"; then
|
||||||
|
$verbose "Removing $tmpdir_src $tmpdir_xtr $tmpdir_bak ..."
|
||||||
|
cd /
|
||||||
|
rm -rf $tmpdir_src $tmpdir_xtr $tmpdir_bak
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
$verbose "$0 done."
|
||||||
|
exit 0 # exit successfully, not however we ended the loop.
|
94
configure.ac
Normal file
94
configure.ac
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
dnl Hey Emacs, I want this in -*- autoconf -*- mode, please.
|
||||||
|
|
||||||
|
dnl Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||||
|
dnl Please see COPYING for a description your rights and responsibilities
|
||||||
|
dnl with this software.
|
||||||
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
|
dnl ----------------------------- HOST SYSTEM -----------------------------------
|
||||||
|
|
||||||
|
AC_PREREQ(2.54)
|
||||||
|
AC_INIT([GNU lightning], 1.2a, bonzini@gnu.org, lightning)
|
||||||
|
AC_CONFIG_AUX_DIR(config)
|
||||||
|
AC_CONFIG_SRCDIR([lightning.h.in])
|
||||||
|
|
||||||
|
AC_CANONICAL_TARGET
|
||||||
|
AM_CONFIG_HEADER(lightning.h)
|
||||||
|
AM_INIT_AUTOMAKE
|
||||||
|
|
||||||
|
# We don't use autoheader.
|
||||||
|
AUTOHEADER="touch lightning.h.in"
|
||||||
|
|
||||||
|
AC_PROG_CC
|
||||||
|
AC_PROG_CPP
|
||||||
|
AC_PROG_LN_S
|
||||||
|
AC_PROG_RANLIB
|
||||||
|
AC_PROG_INSTALL
|
||||||
|
AC_PROG_MAKE_SET
|
||||||
|
AC_PATH_PROG(INSTALL_INFO, install-info, :, $PATH:/sbin)
|
||||||
|
AC_EXEEXT
|
||||||
|
|
||||||
|
AC_CHECK_FUNCS(memcpy)
|
||||||
|
|
||||||
|
BACKENDS="i386 sparc ppc"
|
||||||
|
AC_SUBST(BACKENDS)
|
||||||
|
|
||||||
|
case "$target_cpu" in
|
||||||
|
i?86) cpu=i386; AC_DEFINE(LIGHTNING_I386, 1) ;;
|
||||||
|
sparc*) cpu=sparc; AC_DEFINE(LIGHTNING_SPARC, 1) ;;
|
||||||
|
powerpc) cpu=ppc; AC_DEFINE(LIGHTNING_PPC, 1) ;;
|
||||||
|
*) AC_MSG_ERROR([cpu $target_cpu not supported]) ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
dnl ---------------------------- COMMAND LINE ---------------------------------
|
||||||
|
|
||||||
|
AC_ARG_ENABLE( disassembling,
|
||||||
|
[ --enable-disassembling make the test programs disassemble the code
|
||||||
|
enabled by default if host != target],
|
||||||
|
, enable_disassembling=no)
|
||||||
|
|
||||||
|
AM_CONDITIONAL(REGRESSION_TESTING, test "$host_cpu" = "$target_cpu")
|
||||||
|
if test "$host_cpu" != "$target_cpu"; then
|
||||||
|
AC_DEFINE(LIGHTNING_CROSS, 1)
|
||||||
|
enable_disassembling=yes
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$enable_disassembling" != no; then
|
||||||
|
AC_DEFINE(LIGHTNING_DISASSEMBLE, 1)
|
||||||
|
fi
|
||||||
|
LIBDISASS=""
|
||||||
|
AM_CONDITIONAL(DISASS, test "$enable_disassembling" != no)
|
||||||
|
test "$enable_disassembling" != no && LIBDISASS="libdisass.a"
|
||||||
|
|
||||||
|
AC_ARG_ENABLE( assertions,
|
||||||
|
[ --enable-assertions perform internal consistency checks],
|
||||||
|
, enable_assertions=no)
|
||||||
|
|
||||||
|
if test "$enable_assertions" != no; then
|
||||||
|
AC_DEFINE(_ASM_SAFETY, 1)
|
||||||
|
fi
|
||||||
|
|
||||||
|
AM_CONDITIONAL(LIGHTNING_MAIN, :)
|
||||||
|
|
||||||
|
dnl --------------------------- PRODUCE OUTPUT --------------------------------
|
||||||
|
|
||||||
|
cpu_dir=lightning/$cpu
|
||||||
|
AC_CONFIG_LINKS(lightning/asm.h:$cpu_dir/asm.h dnl
|
||||||
|
lightning/fp.h:$cpu_dir/fp.h dnl
|
||||||
|
lightning/core.h:$cpu_dir/core.h dnl
|
||||||
|
lightning/funcs.h:$cpu_dir/funcs.h, [],
|
||||||
|
[cpu_dir=$cpu_dir])
|
||||||
|
|
||||||
|
AC_SUBST(LIBDISASS)
|
||||||
|
|
||||||
|
AC_CONFIG_FILES(Makefile doc/Makefile tests/Makefile opcode/Makefile
|
||||||
|
lightning/Makefile)
|
||||||
|
AC_CONFIG_FILES(lightningize, chmod +x lightningize)
|
||||||
|
|
||||||
|
AC_OUTPUT
|
||||||
|
|
||||||
|
# A small sanity check
|
||||||
|
echo "#include <stdio.h>" > confdefs.h # dummy input file
|
||||||
|
CPPFLAGS="$CPPFLAGS -I. -I$srcdir"
|
||||||
|
AC_TRY_COMPILE([#include "lightning.h"], , ,
|
||||||
|
AC_MSG_WARN(the compiler that was found could not compile GNU lightning))
|
18
doc/Makefile.am
Normal file
18
doc/Makefile.am
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
EXTRA_DIST=lightning.info lightning.info-1 lightning.info-2 lightning.info-3
|
||||||
|
|
||||||
|
TEXI2DVI=$(top_srcdir)/config/texi2dvi
|
||||||
|
HELP2MAN = $(top_srcdir)/config/help2man
|
||||||
|
|
||||||
|
dist_man1_MANS = lightningize.1
|
||||||
|
info_TEXINFOS = lightning.texi
|
||||||
|
EXTRA_TEXINFOS = u-lightning.texi p-lightning.texi
|
||||||
|
MOSTLYCLEANFILES = lightning.tmp
|
||||||
|
|
||||||
|
lightning_TEXINFOS = body.texi toc.texi using.texi porting.texi version.texi
|
||||||
|
u_lightning_TEXINFOS = body.texi toc.texi using.texi version.texi
|
||||||
|
p_lightning_TEXINFOS = body.texi toc.texi porting.texi version.texi
|
||||||
|
|
||||||
|
lightningize.1: $(top_srcdir)/lightningize.in $(top_srcdir)/configure.ac
|
||||||
|
cd $(top_srcdir) && $(MAKE) lightningize
|
||||||
|
$(HELP2MAN) -p lightning $(top_srcdir)/lightningize > $(srcdir)/lightningize.1
|
||||||
|
|
306
doc/body.texi
Normal file
306
doc/body.texi
Normal file
|
@ -0,0 +1,306 @@
|
||||||
|
@ifinfo
|
||||||
|
@dircategory @lightning{}, a library for dynamic code generation
|
||||||
|
@direntry
|
||||||
|
* @value{TITLE}: (lightning).
|
||||||
|
@end direntry
|
||||||
|
|
||||||
|
This file documents GNU lightning, Version @value{VERSION}.
|
||||||
|
It was last updated on @value{UPDATED}.
|
||||||
|
|
||||||
|
Copyright @copyright{} 2000 Free Software Foundation, Inc.
|
||||||
|
Authored by Paolo Bonzini.
|
||||||
|
|
||||||
|
This document is released under the terms of the GNU Free Documentation
|
||||||
|
License as published by the Free Software Foundation; either version 1.1, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Free Documentation License along
|
||||||
|
with GNU lightning; see the file @file{COPYING.DOC}. If not, write to the Free
|
||||||
|
Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
There are no Secondary Sections, no Cover Texts and no Invariant Sections
|
||||||
|
(as defined in the license); this text, along with its equivalent in the
|
||||||
|
printed manual, constitutes the Title Page.
|
||||||
|
@end ifinfo
|
||||||
|
|
||||||
|
@setchapternewpage odd
|
||||||
|
|
||||||
|
@titlepage
|
||||||
|
@title @value{TITLE}
|
||||||
|
@subtitle Version @value{VERSION}
|
||||||
|
@subtitle @value{UPDATE-MONTH}
|
||||||
|
|
||||||
|
@author by Paolo Bonzini
|
||||||
|
|
||||||
|
@c The following two commands start the copyright page.
|
||||||
|
@page
|
||||||
|
@vskip 0pt plus 1filll
|
||||||
|
Copyright 1988-92, 1994-95, 1999, 2000 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This document is released under the terms of the @sc{gnu} Free Documentation
|
||||||
|
License as published by the Free Software Foundation; either version 1.1, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
You should have received a copy of the @sc{gnu} Free Documentation License
|
||||||
|
along with @sc{gnu} @i{lightning}; see the file @file{COPYING.DOC}. If not,
|
||||||
|
write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
MA 02111-1307, USA.
|
||||||
|
|
||||||
|
There are no Secondary Sections, no Cover Texts and no Invariant Sections
|
||||||
|
(as defined in the license); this text, along with its equivalent in the
|
||||||
|
Info documentation, constitutes the Title Page.
|
||||||
|
@end titlepage
|
||||||
|
|
||||||
|
@ifclear ISTEX
|
||||||
|
@node Top
|
||||||
|
@top @lightning{}
|
||||||
|
|
||||||
|
This document describes @value{TOPIC} the @lightning{} library for
|
||||||
|
dynamic code generation. Unlike other dynamic code generation systems,
|
||||||
|
which are usually either inefficient or non-portable, @lightning{} is
|
||||||
|
both retargetable and very fast.
|
||||||
|
|
||||||
|
@include toc.texi
|
||||||
|
@end ifclear
|
||||||
|
|
||||||
|
@node Overview
|
||||||
|
@chapter Introduction to @lightning{}
|
||||||
|
|
||||||
|
@ifset ISTEX
|
||||||
|
This document describes @value{TOPIC} the @lightning{} library for
|
||||||
|
dynamic code generation. Unlike other dynamic code generation systems,
|
||||||
|
which are usually either inefficient or non-portable, @lightning{} is
|
||||||
|
both retargetable and very fast.
|
||||||
|
@end ifset
|
||||||
|
|
||||||
|
@ifclear USING
|
||||||
|
This manual assumes that you are pretty comfortable with the usage of
|
||||||
|
@lightning{} for dynamic code generation, as described in
|
||||||
|
@usingref{The instruction set, @lightning{}'s instruction set}, and
|
||||||
|
instead focuses on the retargeting process. What follows is nothing
|
||||||
|
more then a brief overview of the system.
|
||||||
|
@end ifclear
|
||||||
|
|
||||||
|
Dynamic code generation is the generation of machine code
|
||||||
|
at runtime. It is typically used to strip a layer of interpretation
|
||||||
|
by allowing compilation to occur at runtime. One of the most
|
||||||
|
well-known applications of dynamic code generation is perhaps that
|
||||||
|
of interpreters that compile source code to an intermediate bytecode
|
||||||
|
form, which is then recompiled to machine code at run-time: this
|
||||||
|
approach effectively combines the portability of bytecode
|
||||||
|
representations with the speed of machine code. Another common
|
||||||
|
application of dynamic code generation is in the field of hardware
|
||||||
|
simulators and binary emulators, which can use the same techniques
|
||||||
|
to translate simulated instructions to the instructions of the
|
||||||
|
underlying machine.
|
||||||
|
|
||||||
|
Yet other applications come to mind: for example, windowing
|
||||||
|
@dfn{bitblt} operations, matrix manipulations, and network packet
|
||||||
|
filters. Albeit very powerful and relatively well known within the
|
||||||
|
compiler community, dynamic code generation techniques are rarely
|
||||||
|
exploited to their full potential and, with the exception of the
|
||||||
|
two applications described above, have remained curiosities because
|
||||||
|
of their portability and functionality barriers: binary instructions
|
||||||
|
are generated, so programs using dynamic code generation must be
|
||||||
|
retargeted for each machine; in addition, coding a run-time code
|
||||||
|
generator is a tedious and error-prone task more than a difficult one.
|
||||||
|
|
||||||
|
@ifset USING
|
||||||
|
This manual describes the @lightning{} dynamic code generation library.
|
||||||
|
@lightning{} provides a portable, fast and easily retargetable dynamic
|
||||||
|
code generation system.
|
||||||
|
@end ifset
|
||||||
|
@ifclear USING
|
||||||
|
@lightning{} provides a portable, fast and easily retargetable dynamic
|
||||||
|
code generation system.
|
||||||
|
@end ifclear
|
||||||
|
|
||||||
|
To be fast, @lightning{} emits machine code without first creating
|
||||||
|
intermediate data structures such as RTL representations traditionally
|
||||||
|
used by optimizing compilers (@pxref{RTL representation, , , gcc, Using
|
||||||
|
and porting GNU CC}). @lightning{} translates code directly from a
|
||||||
|
machine independent interface to that of the underlying architecture.
|
||||||
|
This makes code generation more efficient, since no intermediate data
|
||||||
|
structures have to be constructed and consumed. A collateral benefit
|
||||||
|
it that @lightning{} consumes little space: other than the memory
|
||||||
|
needed to store generated instructions and data structures such as
|
||||||
|
parse trees, the only data structure that client will usually need
|
||||||
|
is an array of pointers to labels and unresolved jumps, which you
|
||||||
|
can often allocate directly on the system stack.
|
||||||
|
|
||||||
|
To be portable, @lightning{} abstracts over current architectures'
|
||||||
|
quirks and unorthogonalities. The interface that it exposes to is that
|
||||||
|
of a standardized RISC architecture loosely based on the SPARC and MIPS
|
||||||
|
chips. There are a few general-purpose registers (six, not including
|
||||||
|
those used to receive and pass parameters between subroutines), and
|
||||||
|
arithmetic operations involve three operands---either three registers
|
||||||
|
or two registers and an arbitrarily sized immediate value.
|
||||||
|
|
||||||
|
On one hand, this architecture is general enough that it is possible to
|
||||||
|
generate pretty efficient code even on CISC architectures such as the
|
||||||
|
Intel x86 or the Motorola 68k families. On the other hand, it matches
|
||||||
|
real architectures closely enough that, most of the time, the
|
||||||
|
compiler's constant folding pass ends up generating code which
|
||||||
|
assembles machine instructions without further tests.
|
||||||
|
|
||||||
|
@section Drawbacks
|
||||||
|
|
||||||
|
@lightning{} has been useful in practice; however, it does have
|
||||||
|
at least four drawbacks: it has limited registers, no peephole
|
||||||
|
optimizer, no instruction scheduler and no symbolic debugger. Of
|
||||||
|
these, the last is the most critical even though it does not
|
||||||
|
affect the quality of generated code: the only way to debug code
|
||||||
|
generated at run-time is to step through it at the level of
|
||||||
|
host specific machine code. A decent knowledge of the underlying
|
||||||
|
instruction set is thus needed to make sense of the debugger's
|
||||||
|
output.
|
||||||
|
|
||||||
|
The low number of available registers (six) is also an important
|
||||||
|
limitation. However, let's take the primary application of dynamic
|
||||||
|
code generation, that is, bytecode translators. The underlying
|
||||||
|
virtual machines tend to have very few general purpose registers
|
||||||
|
(usually 0 to 2) and the translators seldom rely on sophisticated
|
||||||
|
graph-coloring algorithms to allocate registers to temporary
|
||||||
|
variables. Rather, these translators usually obtain performance
|
||||||
|
increases because: a) they remove indirect jumps, which are usually
|
||||||
|
poorly predicted, and thus often form a bottleneck, b) they
|
||||||
|
parameterize the generated code and go through the process of decoding
|
||||||
|
the bytecodes just once. So, their usage of registers is rather
|
||||||
|
sparse---in fact, in practice, six registers were found to be
|
||||||
|
enough for most purposes.
|
||||||
|
|
||||||
|
The lack of a peephole optimizer is most important on machines where a
|
||||||
|
single instruction can map to multiple native instructions. For
|
||||||
|
instance, Intel chips' division instruction hard-codes the dividend
|
||||||
|
to be in EAX and the quotient and remainder to be output, respectively,
|
||||||
|
in EAX and EDX: on such chips, @lightning{} does lots of pushing and
|
||||||
|
popping of EAX and EDX to save those registers that are not used.
|
||||||
|
Unnecessary stack operations could be removed by looking at whether
|
||||||
|
preserved registers are destroyed soon. Unfortunately, the current
|
||||||
|
implementation of @lightning{} is so fast because it only knows about
|
||||||
|
the single instruction that is being generated; performing these
|
||||||
|
optimizations would require a flow analysis pass that would probably
|
||||||
|
hinder @lightning{}'s speed.
|
||||||
|
|
||||||
|
The lack of an instruction scheduler is not very important---pretty
|
||||||
|
good instruction scheduling can actually be obtained by separating
|
||||||
|
register writes from register reads. The only architectures on which
|
||||||
|
a scheduler would be useful are those on which arithmetic instructions
|
||||||
|
have two operands; an example is, again, the x86, on which the single
|
||||||
|
instruction
|
||||||
|
@example
|
||||||
|
subr_i R0, R1, R2 @rem{!Compute R0 = R1 - R2}
|
||||||
|
@end example
|
||||||
|
@noindent
|
||||||
|
is translated to two instruction, of which the second depends on the
|
||||||
|
result of the first:
|
||||||
|
@example
|
||||||
|
movl %ebx, %eax @rem{! Move R1 into R0}
|
||||||
|
subl %edx, %eax @rem{! Subtract R2 from R0}
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@ifset BOTH
|
||||||
|
@node Using GNU lightning
|
||||||
|
@chapter Using @lightning{}
|
||||||
|
|
||||||
|
This chapter describes installing and using @lightning{}.
|
||||||
|
|
||||||
|
@menu
|
||||||
|
@usingmenu{}
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
@lowersections
|
||||||
|
@end ifset
|
||||||
|
|
||||||
|
@ifset USING
|
||||||
|
@include using.texi
|
||||||
|
@end ifset
|
||||||
|
|
||||||
|
@ifset BOTH
|
||||||
|
@raisesections
|
||||||
|
|
||||||
|
@node Porting GNU lightning
|
||||||
|
@chapter Porting @lightning{}
|
||||||
|
|
||||||
|
This chapter describes the process of porting @lightning{}.
|
||||||
|
It assumes that you are pretty comfortable with the usage of
|
||||||
|
@lightning{} for dynamic code generation, as described in
|
||||||
|
@ref{Using GNU lightning}.
|
||||||
|
|
||||||
|
@menu
|
||||||
|
@portingmenu{}
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
@lowersections
|
||||||
|
@end ifset
|
||||||
|
|
||||||
|
@ifset PORTING
|
||||||
|
@include porting.texi
|
||||||
|
@end ifset
|
||||||
|
|
||||||
|
@ifset BOTH
|
||||||
|
@raisesections
|
||||||
|
@end ifset
|
||||||
|
|
||||||
|
@node Future
|
||||||
|
@chapter The future of @lightning{}
|
||||||
|
|
||||||
|
Presented below is the set of tasks that I feel need to be performed
|
||||||
|
to make @lightning{} a more fully functional, viable system. They are
|
||||||
|
presented in no particular order. I would @emph{very much} welcome any
|
||||||
|
volunteers who would like to help with the implementation of one or
|
||||||
|
more of these tasks. Please write to me, Paolo Bonzini, at
|
||||||
|
@email{bonzini@@gnu.org} if you are interested in adding your efforts
|
||||||
|
to the @lightning{} project.
|
||||||
|
|
||||||
|
Tasks:
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
The most important task to make @lightning{} more widely usable
|
||||||
|
is to retarget it. Although currently supported architectures
|
||||||
|
(x86, SPARC, PowerPC) are certainly some of the most widely used,
|
||||||
|
@lightning{} could be ported to others---namely, the Alpha and
|
||||||
|
MIPS architectures.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Another interesting task is to allow the instruction stream to grow
|
||||||
|
dynamically. This is a problem because not all architectures allow
|
||||||
|
to write position independent code.@footnote{The x86's absolute
|
||||||
|
jumps, for example, are actually slow indirect jumps, and need a
|
||||||
|
register.}
|
||||||
|
|
||||||
|
@item
|
||||||
|
Optimize leaf procedures on the SPARC. This involves using the
|
||||||
|
output registers (@code{%o@i{X}}) instead of the local registers
|
||||||
|
(@code{%l@i{X}}) when writing leaf procedures; the problem is,
|
||||||
|
leaf procedures also receive parameters in the output registers,
|
||||||
|
so they would be overwritten by write accesses to general-purpose
|
||||||
|
registers.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
|
||||||
|
@node Acknowledgements
|
||||||
|
@chapter Acknowledgements
|
||||||
|
|
||||||
|
As far as I know, the first general-purpose portable dynamic code
|
||||||
|
generator is @sc{dcg}, by Dawson R.@: Engler and T.@: A.@: Proebsting.
|
||||||
|
Further work by Dawson R. Engler resulted in the @sc{vcode} system;
|
||||||
|
unlike @sc{dcg}, @sc{vcode} used no intermediate representation and
|
||||||
|
directly inspired @lightning{}.
|
||||||
|
|
||||||
|
Thanks go to Ian Piumarta, who kindly accepted to release his own
|
||||||
|
program @sc{ccg} under the GNU General Public License, thereby allowing
|
||||||
|
@lightning{} to use the run-time assemblers he had wrote for @sc{ccg}.
|
||||||
|
@sc{ccg} provides a way of dynamically assemble programs written in the
|
||||||
|
underlying architecture's assembly language. So it is not portable,
|
||||||
|
yet very interesting.
|
||||||
|
|
||||||
|
I also thank Steve Byrne for writing GNU Smalltalk, since @lightning{}
|
||||||
|
was first developed as a tool to be used in GNU Smalltalk's dynamic
|
||||||
|
translator from bytecodes to native code.
|
||||||
|
|
||||||
|
@iftex
|
||||||
|
@contents
|
||||||
|
@end iftex
|
||||||
|
|
||||||
|
@bye
|
105
doc/lightning.texi
Normal file
105
doc/lightning.texi
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
\input texinfo.tex @c -*- texinfo -*-
|
||||||
|
@c %**start of header (This is for running Texinfo on a region.)
|
||||||
|
|
||||||
|
@setfilename lightning.info
|
||||||
|
|
||||||
|
@set TITLE Using and porting @sc{gnu} @i{lightning}
|
||||||
|
@set TOPIC installing, using and porting
|
||||||
|
@set BOTH
|
||||||
|
@set USING
|
||||||
|
@set PORTING
|
||||||
|
|
||||||
|
@settitle @value{TITLE}
|
||||||
|
|
||||||
|
@c ---------------------------------------------------------------------
|
||||||
|
@c Common macros
|
||||||
|
@c ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
@macro bulletize{a}
|
||||||
|
@item
|
||||||
|
\a\
|
||||||
|
@end macro
|
||||||
|
|
||||||
|
@macro rem{a}
|
||||||
|
@r{@i{\a\}}
|
||||||
|
@end macro
|
||||||
|
|
||||||
|
@macro gnu{}
|
||||||
|
@sc{gnu}
|
||||||
|
@end macro
|
||||||
|
|
||||||
|
@macro lightning{}
|
||||||
|
@gnu{} @i{lightning}
|
||||||
|
@end macro
|
||||||
|
|
||||||
|
@c ---------------------------------------------------------------------
|
||||||
|
@c Macros for Texinfo 3.1/4.0 compatibility
|
||||||
|
@c ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
@c Emulate the `@ifnottex' command which is found in Texinfo 4.0
|
||||||
|
@iftex
|
||||||
|
@set ISTEX
|
||||||
|
@end iftex
|
||||||
|
|
||||||
|
@c @hlink (macro), @url and @email are used instead of @uref for Texinfo 3.1
|
||||||
|
@c compatibility
|
||||||
|
@macro hlink{url, link}
|
||||||
|
\link\ (\url\)
|
||||||
|
@end macro
|
||||||
|
|
||||||
|
@c ifhtml can only be true in Texinfo 4.0, which has uref
|
||||||
|
@ifhtml
|
||||||
|
@unmacro hlink
|
||||||
|
|
||||||
|
@macro hlink{url, link}
|
||||||
|
@uref{\url\, \link\}
|
||||||
|
@end macro
|
||||||
|
|
||||||
|
@macro email{mail}
|
||||||
|
@uref{mailto:\mail\, , \mail\}
|
||||||
|
@end macro
|
||||||
|
|
||||||
|
@macro url{url}
|
||||||
|
@uref{\url\}
|
||||||
|
@end macro
|
||||||
|
@end ifhtml
|
||||||
|
|
||||||
|
@c ---------------------------------------------------------------------
|
||||||
|
@c References to the other half of the manual
|
||||||
|
@c ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ifset USING
|
||||||
|
@macro usingref{node, name}
|
||||||
|
@ref{\node\, , \name\}
|
||||||
|
@end macro
|
||||||
|
@end ifset
|
||||||
|
|
||||||
|
@ifclear USING
|
||||||
|
@macro usingref{node, name}
|
||||||
|
@ref{\node\, , \name\, u-lightning, Using @sc{gnu} @i{lightning}}
|
||||||
|
@end macro
|
||||||
|
@end ifclear
|
||||||
|
|
||||||
|
@ifset PORTING
|
||||||
|
@macro portingref{node, name}
|
||||||
|
@ref{\node\, , \name\}
|
||||||
|
@end macro
|
||||||
|
@end ifset
|
||||||
|
|
||||||
|
@ifclear PORTING
|
||||||
|
@macro portingref{node, name}
|
||||||
|
@ref{\node\, , \name\, p-lightning, Porting @sc{gnu} @i{lightning}}
|
||||||
|
@end macro
|
||||||
|
@end ifclear
|
||||||
|
|
||||||
|
@c ---------------------------------------------------------------------
|
||||||
|
@c End of macro section
|
||||||
|
@c ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
@include version.texi
|
||||||
|
@include body.texi
|
||||||
|
|
||||||
|
@c %**end of header (This is for running Texinfo on a region.)
|
||||||
|
|
||||||
|
@c ***********************************************************************
|
||||||
|
|
1415
doc/porting.texi
Normal file
1415
doc/porting.texi
Normal file
File diff suppressed because it is too large
Load diff
77
doc/toc.texi
Normal file
77
doc/toc.texi
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
@c These macros are used because these items could go both in the
|
||||||
|
@c short listing (for partial books) and in the detailed listing
|
||||||
|
@c (for full books - i.e. using & porting)
|
||||||
|
|
||||||
|
@macro usingmenu{}
|
||||||
|
@ifset USING
|
||||||
|
* Installation:: Configuring and installing GNU lightning
|
||||||
|
* The instruction set:: The RISC instruction set used i GNU lightning
|
||||||
|
* GNU lightning macros:: GNU lightning's macros
|
||||||
|
* Floating-point:: Doing floating point computations.
|
||||||
|
* Reentrancy:: Re-entrant usage of GNU lightning
|
||||||
|
* Autoconf support:: Using @code{autoconf} with GNU lightning
|
||||||
|
@end ifset
|
||||||
|
@end macro
|
||||||
|
|
||||||
|
@macro portingmenu{}
|
||||||
|
@ifset PORTING
|
||||||
|
* Structure of a port:: An overview of the porting process
|
||||||
|
* Adjusting configure:: Automatically recognizing the new platform
|
||||||
|
* Run-time assemblers:: An internal layer to simplify porting
|
||||||
|
* Standard macros:: The platform-independent layer used by clients.
|
||||||
|
* Standard functions:: Doing more complex tasks.
|
||||||
|
* Floating-point macros:: Implementing macros for floating point.
|
||||||
|
@end ifset
|
||||||
|
@end macro
|
||||||
|
|
||||||
|
@macro standardmacrosmenu{}
|
||||||
|
@c This comment is needed because of makeinfo's vagaries...
|
||||||
|
* Forward references:: Implementing forward references
|
||||||
|
* Common features:: Common features supported by @file{core-common.h}
|
||||||
|
* Delay slots:: Supporting scheduling of delay slots
|
||||||
|
* Immediate values:: Supporting arbitrarily sized immediate values
|
||||||
|
* Implementing the ABI:: Function prologs and epilogs, and argument passing
|
||||||
|
* Macro list:: Macros composing the platform-independent layer
|
||||||
|
@end macro
|
||||||
|
|
||||||
|
@menu
|
||||||
|
@ifclear BOTH
|
||||||
|
* Overview:: What GNU lightning is
|
||||||
|
@usingmenu{}
|
||||||
|
@portingmenu{}
|
||||||
|
* Future:: Tasks for GNU lightning's subsequent releases
|
||||||
|
* Acknowledgements:: Acknowledgements for GNU lightning
|
||||||
|
|
||||||
|
@ifset PORTING
|
||||||
|
@detailmenu
|
||||||
|
--- The detailed node listing ---
|
||||||
|
|
||||||
|
Standard macros:
|
||||||
|
@standardmacrosmenu{}
|
||||||
|
@end detailmenu
|
||||||
|
@end ifset
|
||||||
|
@end ifclear
|
||||||
|
|
||||||
|
@ifset BOTH
|
||||||
|
* Overview:: What GNU lightning is.
|
||||||
|
* Using GNU lightning:: Using GNU lightning in your programs
|
||||||
|
* Porting GNU lightning:: Retargeting GNU lightning to a new system
|
||||||
|
* Future:: Tasks for GNU lightning's subsequent releases
|
||||||
|
* Acknowledgements:: Acknowledgements for GNU lightning
|
||||||
|
|
||||||
|
@detailmenu
|
||||||
|
--- The detailed node listing ---
|
||||||
|
|
||||||
|
Using @lightning{}:
|
||||||
|
@usingmenu{}
|
||||||
|
|
||||||
|
Porting @lightning{}:
|
||||||
|
@portingmenu{}
|
||||||
|
|
||||||
|
Standard macros:
|
||||||
|
@standardmacrosmenu{}
|
||||||
|
@end detailmenu
|
||||||
|
|
||||||
|
@end ifset
|
||||||
|
|
||||||
|
@end menu
|
1086
doc/using.texi
Normal file
1086
doc/using.texi
Normal file
File diff suppressed because it is too large
Load diff
4
doc/version.texi
Normal file
4
doc/version.texi
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
@set UPDATED 2 November 2001
|
||||||
|
@set UPDATED-MONTH November 2001
|
||||||
|
@set EDITION 1.2a
|
||||||
|
@set VERSION 1.2a
|
65
lightning-inst.h
Normal file
65
lightning-inst.h
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* lightning main include file
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __lightning_h
|
||||||
|
#define __lightning_h
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <lightning/asm-common.h>
|
||||||
|
#include <lightning/funcs-common.h>
|
||||||
|
|
||||||
|
#ifndef LIGHTNING_DEBUG
|
||||||
|
#include <lightning/asm.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <lightning/core.h>
|
||||||
|
#include <lightning/core-common.h>
|
||||||
|
#include <lightning/funcs.h>
|
||||||
|
#include <lightning/fp.h>
|
||||||
|
|
||||||
|
#ifdef jit_cmp
|
||||||
|
#include <lightning/fp-common.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef JIT_R0
|
||||||
|
#error GNU lightning does not support the current target
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __lightning_h */
|
88
lightning.h.in
Normal file
88
lightning.h.in
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* lightning main include file
|
||||||
|
* Unlike lightning-dist.h, this contains a few definitions
|
||||||
|
* used by the test suite.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __lightning_h
|
||||||
|
#define __lightning_h
|
||||||
|
|
||||||
|
/* Define if you want assertions enabled. */
|
||||||
|
#undef _ASM_SAFETY
|
||||||
|
|
||||||
|
/* Define if lightning is compiling for i386 */
|
||||||
|
#undef LIGHTNING_I386
|
||||||
|
|
||||||
|
/* Define if lightning is compiling for Sparc */
|
||||||
|
#undef LIGHTNING_SPARC
|
||||||
|
|
||||||
|
/* Define if lightning is compiling for PowerPC */
|
||||||
|
#undef LIGHTNING_PPC
|
||||||
|
|
||||||
|
/* Define if you want the test programs to disassemble their output */
|
||||||
|
#undef LIGHTNING_DISASSEMBLE
|
||||||
|
|
||||||
|
/* Define if creating a cross-assembler */
|
||||||
|
#undef LIGHTNING_CROSS
|
||||||
|
|
||||||
|
/* Define if you have the memcpy function */
|
||||||
|
#undef HAVE_MEMCPY
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <lightning/asm-common.h>
|
||||||
|
#include <lightning/funcs-common.h>
|
||||||
|
|
||||||
|
#ifndef LIGHTNING_DEBUG
|
||||||
|
#include <lightning/asm.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <lightning/core.h>
|
||||||
|
#include <lightning/core-common.h>
|
||||||
|
#include <lightning/funcs.h>
|
||||||
|
#include <lightning/fp.h>
|
||||||
|
|
||||||
|
#ifdef jit_cmp
|
||||||
|
#include <lightning/fp-common.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LIGHTNING_DISASSEMBLE
|
||||||
|
extern void disassemble(FILE *stream, char *from, char *to);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __lightning_h */
|
57
lightning.m4
Normal file
57
lightning.m4
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
dnl I'd like this to be edited in -*- Autoconf -*- mode...
|
||||||
|
dnl
|
||||||
|
# serial 1 LIGHTNING_CONFIGURE_IF_NOT_FOUND
|
||||||
|
AC_DEFUN([LIGHTNING_CONFIGURE_IF_NOT_FOUND], [
|
||||||
|
AC_REQUIRE([AC_PROG_LN_S])dnl
|
||||||
|
AC_REQUIRE([AC_CANONICAL_HOST])dnl
|
||||||
|
AC_CHECK_HEADER(lightning.h)
|
||||||
|
AM_CONDITIONAL(LIGHTNING_MAIN, (exit 1))
|
||||||
|
AM_CONDITIONAL(HAVE_INSTALLED_LIGHTNING, test "$ac_cv_header_lightning_h" = yes)
|
||||||
|
|
||||||
|
lightning=
|
||||||
|
if test "$ac_cv_header_lightning_h" = yes; then
|
||||||
|
lightning=yes
|
||||||
|
else
|
||||||
|
case "$host_cpu" in
|
||||||
|
i?86) cpu_subdir=i386 ;;
|
||||||
|
sparc*) cpu_subdir=sparc ;;
|
||||||
|
powerpc) cpu_subdir=ppc ;;
|
||||||
|
*) ;;
|
||||||
|
esac
|
||||||
|
test -n "$cpu_subdir" && lightning=yes
|
||||||
|
fi
|
||||||
|
|
||||||
|
ifdef([AC_HELP_STRING], [
|
||||||
|
dnl autoconf 2.50 style
|
||||||
|
if test -n "$cpu_subdir"; then
|
||||||
|
AC_CONFIG_LINKS(lightning/asm.h:lightning/$cpu_subdir/asm.h
|
||||||
|
lightning/core.h:lightning/$cpu_subdir/core.h
|
||||||
|
lightning/fp.h:lightning/$cpu_subdir/fp.h
|
||||||
|
lightning/funcs.h:lightning/$cpu_subdir/funcs.h, , [
|
||||||
|
cpu_subdir=$cpu_subdir
|
||||||
|
])
|
||||||
|
fi
|
||||||
|
], [
|
||||||
|
dnl autoconf 2.13 style
|
||||||
|
AC_OUTPUT_COMMANDS([
|
||||||
|
if test -n "$cpu_subdir"; then
|
||||||
|
for i in asm fp core funcs; do
|
||||||
|
echo linking $srcdir/lightning/$cpu_subdir/$i.h to lightning/$i.h
|
||||||
|
(cd lightning && $LN_S -f $srcdir/$cpu_subdir/$i.h $i.h)
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
], [
|
||||||
|
LN_S='$LN_S'
|
||||||
|
cpu_subdir=$cpu_subdir
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
if test -n "$lightning"; then
|
||||||
|
AC_DEFINE(HAVE_LIGHTNING, 1, [Define if GNU lightning can be used])
|
||||||
|
lightning=
|
||||||
|
ifelse([$1], , :, [$1])
|
||||||
|
else
|
||||||
|
ifelse([$2], , :, [$2])
|
||||||
|
fi
|
||||||
|
|
||||||
|
])dnl
|
16
lightning/Makefile.am
Normal file
16
lightning/Makefile.am
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
DISTCLEANFILES = asm.h core.h funcs.h fp.h
|
||||||
|
|
||||||
|
LIGHTNING_FILES = funcs-common.h core-common.h fp-common.h \
|
||||||
|
asm-common.h \
|
||||||
|
i386/asm.h i386/core.h i386/funcs.h i386/fp.h \
|
||||||
|
sparc/asm.h sparc/core.h sparc/funcs.h sparc/fp.h \
|
||||||
|
ppc/asm.h ppc/core.h ppc/funcs.h ppc/fp.h
|
||||||
|
|
||||||
|
if LIGHTNING_MAIN
|
||||||
|
lightningdir = $(includedir)/lightning
|
||||||
|
dist_pkgdata_DATA = Makefile.am
|
||||||
|
nobase_dist_lightning_HEADERS = $(LIGHTNING_FILES)
|
||||||
|
nodist_lightning_HEADERS = asm.h core.h funcs.h fp.h
|
||||||
|
else
|
||||||
|
dist_noinst_HEADERS = $(LIGHTNING_FILES) lightning.h
|
||||||
|
endif
|
197
lightning/asm-common.h
Normal file
197
lightning/asm-common.h
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Dynamic assembler support
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __lightning_asm_common_h
|
||||||
|
#define __lightning_asm_common_h_
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _ASM_SAFETY
|
||||||
|
#define JITFAIL(MSG) 0
|
||||||
|
#else
|
||||||
|
#if defined __GNUC__ && (__GNUC__ == 3 ? __GNUC_MINOR__ >= 2 : __GNUC__ > 3)
|
||||||
|
#define JITFAIL(MSG) jit_fail(MSG, __FILE__, __LINE__, __func__)
|
||||||
|
#else
|
||||||
|
#define JITFAIL(MSG) jit_fail(MSG, __FILE__, __LINE__, __FUNCTION__)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined __GNUC__ && (__GNUC__ == 3 ? __GNUC_MINOR__ >= 2 : __GNUC__ > 3)
|
||||||
|
#define JITSORRY(MSG) jit_fail("sorry, unimplemented: " MSG, __FILE__, __LINE__, __func__)
|
||||||
|
#else
|
||||||
|
#define JITSORRY(MSG) jit_fail("sorry, unimplemented: " MSG, __FILE__, __LINE__, __FUNCTION__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define JIT_UNUSED __attribute__((unused))
|
||||||
|
#else
|
||||||
|
#define JIT_UNUSED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
|
||||||
|
does not implement __extension__. But that compiler doesn't define
|
||||||
|
__GNUC_MINOR__. */
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#if __GNUC__ < 2 || (defined(__NeXT__) && !__GNUC_MINOR__)
|
||||||
|
#define __extension__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _TEMPD(type, var)
|
||||||
|
|
||||||
|
#define _TEMP(type, var, val, body) __extension__ ({ \
|
||||||
|
register struct { type var } _jitl; _jitl.var = val; \
|
||||||
|
body; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* Between loading a global and calling a subroutine, we choose the lesser
|
||||||
|
* evil. */
|
||||||
|
#define _TEMPD(type, var) static type var;
|
||||||
|
#define _TEMP(type, var, val, body) ((var = val), body)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef char _sc;
|
||||||
|
typedef unsigned char _uc;
|
||||||
|
typedef unsigned short _us;
|
||||||
|
typedef unsigned int _ui;
|
||||||
|
typedef long _sl;
|
||||||
|
typedef unsigned long _ul;
|
||||||
|
|
||||||
|
#define _jit_UC(X) ((_uc )(X))
|
||||||
|
#define _jit_US(X) ((_us )(X))
|
||||||
|
#define _jit_UI(X) ((_ui )(X))
|
||||||
|
#define _jit_SL(X) ((_sl )(X))
|
||||||
|
#define _jit_UL(X) ((_ul )(X))
|
||||||
|
|
||||||
|
# define _PUC(X) ((_uc *)(X))
|
||||||
|
# define _PUS(X) ((_us *)(X))
|
||||||
|
# define _PUI(X) ((_ui *)(X))
|
||||||
|
# define _PSL(X) ((_sl *)(X))
|
||||||
|
# define _PUL(X) ((_ul *)(X))
|
||||||
|
|
||||||
|
#define _jit_B(B) _jit_UL(((*_jit.x.uc_pc++)= _jit_UC((B)& 0xff)))
|
||||||
|
#define _jit_W(W) _jit_UL(((*_jit.x.us_pc++)= _jit_US((W)&0xffff)))
|
||||||
|
#define _jit_I(I) _jit_UL(((*_jit.x.ui_pc++)= _jit_UI((I) )))
|
||||||
|
#define _jit_L(L) _jit_UL(((*_jit.x.ul_pc++)= _jit_UL((L) )))
|
||||||
|
|
||||||
|
#define _MASK(N) ((unsigned)((1<<(N)))-1)
|
||||||
|
#define _siP(N,I) (!((((unsigned)(I))^(((unsigned)(I))<<1))&~_MASK(N)))
|
||||||
|
#define _uiP(N,I) (!(((unsigned)(I))&~_MASK(N)))
|
||||||
|
#define _suiP(N,I) (_siP(N,I) | _uiP(N,I))
|
||||||
|
|
||||||
|
#ifndef _ASM_SAFETY
|
||||||
|
#define _ck_s(W,I) (_jit_UL(I) & _MASK(W))
|
||||||
|
#define _ck_u(W,I) (_jit_UL(I) & _MASK(W))
|
||||||
|
#define _ck_su(W,I) (_jit_UL(I) & _MASK(W))
|
||||||
|
#define _ck_d(W,I) (_jit_UL(I) & _MASK(W))
|
||||||
|
#else
|
||||||
|
#define _ck_s(W,I) (_siP(W,I) ? (_jit_UL(I) & _MASK(W)) : JITFAIL( "signed integer `"#I"' too large for "#W"-bit field"))
|
||||||
|
#define _ck_u(W,I) (_uiP(W,I) ? (_jit_UL(I) & _MASK(W)) : JITFAIL("unsigned integer `"#I"' too large for "#W"-bit field"))
|
||||||
|
#define _ck_su(W,I) (_suiP(W,I) ? (_jit_UL(I) & _MASK(W)) : JITFAIL( "integer `"#I"' too large for "#W"-bit field"))
|
||||||
|
#define _ck_d(W,I) (_siP(W,I) ? (_jit_UL(I) & _MASK(W)) : JITFAIL( "displacement `"#I"' too large for "#W"-bit field"))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _s0P(I) ((I)==0)
|
||||||
|
#define _s8P(I) _siP(8,I)
|
||||||
|
#define _s16P(I) _siP(16,I)
|
||||||
|
#define _u8P(I) _uiP(8,I)
|
||||||
|
#define _u16P(I) _uiP(16,I)
|
||||||
|
|
||||||
|
#define _su8(I) _ck_su(8,I)
|
||||||
|
#define _su16(I) _ck_su(16,I)
|
||||||
|
|
||||||
|
#define _s1(I) _ck_s( 1,I)
|
||||||
|
#define _s2(I) _ck_s( 2,I)
|
||||||
|
#define _s3(I) _ck_s( 3,I)
|
||||||
|
#define _s4(I) _ck_s( 4,I)
|
||||||
|
#define _s5(I) _ck_s( 5,I)
|
||||||
|
#define _s6(I) _ck_s( 6,I)
|
||||||
|
#define _s7(I) _ck_s( 7,I)
|
||||||
|
#define _s8(I) _ck_s( 8,I)
|
||||||
|
#define _s9(I) _ck_s( 9,I)
|
||||||
|
#define _s10(I) _ck_s(10,I)
|
||||||
|
#define _s11(I) _ck_s(11,I)
|
||||||
|
#define _s12(I) _ck_s(12,I)
|
||||||
|
#define _s13(I) _ck_s(13,I)
|
||||||
|
#define _s14(I) _ck_s(14,I)
|
||||||
|
#define _s15(I) _ck_s(15,I)
|
||||||
|
#define _s16(I) _ck_s(16,I)
|
||||||
|
#define _s17(I) _ck_s(17,I)
|
||||||
|
#define _s18(I) _ck_s(18,I)
|
||||||
|
#define _s19(I) _ck_s(19,I)
|
||||||
|
#define _s20(I) _ck_s(20,I)
|
||||||
|
#define _s21(I) _ck_s(21,I)
|
||||||
|
#define _s22(I) _ck_s(22,I)
|
||||||
|
#define _s23(I) _ck_s(23,I)
|
||||||
|
#define _s24(I) _ck_s(24,I)
|
||||||
|
#define _s25(I) _ck_s(25,I)
|
||||||
|
#define _s26(I) _ck_s(26,I)
|
||||||
|
#define _s27(I) _ck_s(27,I)
|
||||||
|
#define _s28(I) _ck_s(28,I)
|
||||||
|
#define _s29(I) _ck_s(29,I)
|
||||||
|
#define _s30(I) _ck_s(30,I)
|
||||||
|
#define _s31(I) _ck_s(31,I)
|
||||||
|
#define _u1(I) _ck_u( 1,I)
|
||||||
|
#define _u2(I) _ck_u( 2,I)
|
||||||
|
#define _u3(I) _ck_u( 3,I)
|
||||||
|
#define _u4(I) _ck_u( 4,I)
|
||||||
|
#define _u5(I) _ck_u( 5,I)
|
||||||
|
#define _u6(I) _ck_u( 6,I)
|
||||||
|
#define _u7(I) _ck_u( 7,I)
|
||||||
|
#define _u8(I) _ck_u( 8,I)
|
||||||
|
#define _u9(I) _ck_u( 9,I)
|
||||||
|
#define _u10(I) _ck_u(10,I)
|
||||||
|
#define _u11(I) _ck_u(11,I)
|
||||||
|
#define _u12(I) _ck_u(12,I)
|
||||||
|
#define _u13(I) _ck_u(13,I)
|
||||||
|
#define _u14(I) _ck_u(14,I)
|
||||||
|
#define _u15(I) _ck_u(15,I)
|
||||||
|
#define _u16(I) _ck_u(16,I)
|
||||||
|
#define _u17(I) _ck_u(17,I)
|
||||||
|
#define _u18(I) _ck_u(18,I)
|
||||||
|
#define _u19(I) _ck_u(19,I)
|
||||||
|
#define _u20(I) _ck_u(20,I)
|
||||||
|
#define _u21(I) _ck_u(21,I)
|
||||||
|
#define _u22(I) _ck_u(22,I)
|
||||||
|
#define _u23(I) _ck_u(23,I)
|
||||||
|
#define _u24(I) _ck_u(24,I)
|
||||||
|
#define _u25(I) _ck_u(25,I)
|
||||||
|
#define _u26(I) _ck_u(26,I)
|
||||||
|
#define _u27(I) _ck_u(27,I)
|
||||||
|
#define _u28(I) _ck_u(28,I)
|
||||||
|
#define _u29(I) _ck_u(29,I)
|
||||||
|
#define _u30(I) _ck_u(30,I)
|
||||||
|
#define _u31(I) _ck_u(31,I)
|
||||||
|
|
||||||
|
#endif /* __lightning_asm_common_h */
|
568
lightning/core-common.h
Normal file
568
lightning/core-common.h
Normal file
|
@ -0,0 +1,568 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Platform-independent layer support
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __lightning_core_common_h
|
||||||
|
#define __lightning_core_common_h_
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
union {
|
||||||
|
jit_insn *pc;
|
||||||
|
_uc *uc_pc;
|
||||||
|
_us *us_pc;
|
||||||
|
_ui *ui_pc;
|
||||||
|
_ul *ul_pc;
|
||||||
|
} x;
|
||||||
|
struct jit_fp *fp;
|
||||||
|
struct jit_local_state jitl;
|
||||||
|
} jit_state;
|
||||||
|
|
||||||
|
static jit_state _jit;
|
||||||
|
|
||||||
|
#define JIT_NOREG (-1)
|
||||||
|
|
||||||
|
#define _jitl _jit.jitl
|
||||||
|
|
||||||
|
#define jit_get_ip() (*(jit_code *) &_jit.x.pc)
|
||||||
|
#define jit_set_ip(ptr) (_jit.x.pc = (jit_insn *) ptr, jit_get_ip())
|
||||||
|
#define jit_get_label() (_jit.x.pc)
|
||||||
|
#define jit_forward() (_jit.x.pc)
|
||||||
|
|
||||||
|
#define jit_field(struc, f) ( ((long) (&((struc *) 8)->f) ) - 8)
|
||||||
|
#define jit_ptr_field(struc_p, f) ( ((long) (&((struc_p) 8)->f) ) - 8)
|
||||||
|
|
||||||
|
/* realignment via N-byte no-ops */
|
||||||
|
|
||||||
|
#ifndef jit_align
|
||||||
|
#define jit_align(n)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* jit_code: union of many possible function pointer types. Returned
|
||||||
|
* by jit_get_ip().
|
||||||
|
*/
|
||||||
|
typedef union jit_code {
|
||||||
|
char *ptr;
|
||||||
|
void (*vptr)(void);
|
||||||
|
char (*cptr)(void);
|
||||||
|
unsigned char (*ucptr)(void);
|
||||||
|
short (*sptr)(void);
|
||||||
|
unsigned short (*usptr)(void);
|
||||||
|
int (*iptr)(void);
|
||||||
|
unsigned int (*uiptr)(void);
|
||||||
|
long (*lptr)(void);
|
||||||
|
unsigned long (*ulptr)(void);
|
||||||
|
void * (*pptr)(void);
|
||||||
|
float (*fptr)(void);
|
||||||
|
double (*dptr)(void);
|
||||||
|
} jit_code;
|
||||||
|
|
||||||
|
#ifndef jit_fill_delay_after
|
||||||
|
#define jit_fill_delay_after(branch) (branch)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define jit_delay(insn, branch) ((insn), jit_fill_delay_after(branch))
|
||||||
|
|
||||||
|
|
||||||
|
/* ALU synonyms */
|
||||||
|
#define jit_addi_ui(d, rs, is) jit_addi_i((d), (rs), (is))
|
||||||
|
#define jit_addr_ui(d, s1, s2) jit_addr_i((d), (s1), (s2))
|
||||||
|
#define jit_addci_ui(d, rs, is) jit_addci_i((d), (rs), (is))
|
||||||
|
#define jit_addcr_ui(d, s1, s2) jit_addcr_i((d), (s1), (s2))
|
||||||
|
#define jit_addxi_ui(d, rs, is) jit_addxi_i((d), (rs), (is))
|
||||||
|
#define jit_addxr_ui(d, s1, s2) jit_addxr_i((d), (s1), (s2))
|
||||||
|
#define jit_andi_ui(d, rs, is) jit_andi_i((d), (rs), (is))
|
||||||
|
#define jit_andr_ui(d, s1, s2) jit_andr_i((d), (s1), (s2))
|
||||||
|
#define jit_lshi_ui(d, rs, is) jit_lshi_i((d), (rs), (is))
|
||||||
|
#define jit_lshr_ui(d, s1, s2) jit_lshr_i((d), (s1), (s2))
|
||||||
|
#define jit_movi_ui(d, rs) jit_movi_i((d), (rs))
|
||||||
|
#define jit_movr_ui(d, rs) jit_movr_i((d), (rs))
|
||||||
|
#define jit_ori_ui(d, rs, is) jit_ori_i((d), (rs), (is))
|
||||||
|
#define jit_orr_ui(d, s1, s2) jit_orr_i((d), (s1), (s2))
|
||||||
|
#define jit_rsbi_ui(d, rs, is) jit_rsbi_i((d), (rs), (is))
|
||||||
|
#define jit_rsbr_ui(d, s1, s2) jit_rsbr_i((d), (s1), (s2))
|
||||||
|
#define jit_subi_ui(d, rs, is) jit_subi_i((d), (rs), (is))
|
||||||
|
#define jit_subr_ui(d, s1, s2) jit_subr_i((d), (s1), (s2))
|
||||||
|
#define jit_subci_ui(d, rs, is) jit_subci_i((d), (rs), (is))
|
||||||
|
#define jit_subcr_ui(d, s1, s2) jit_subcr_i((d), (s1), (s2))
|
||||||
|
#define jit_subxi_ui(d, rs, is) jit_subxi_i((d), (rs), (is))
|
||||||
|
#define jit_subxr_ui(d, s1, s2) jit_subxr_i((d), (s1), (s2))
|
||||||
|
#define jit_xori_ui(d, rs, is) jit_xori_i((d), (rs), (is))
|
||||||
|
#define jit_xorr_ui(d, s1, s2) jit_xorr_i((d), (s1), (s2))
|
||||||
|
|
||||||
|
#define jit_addi_ul(d, rs, is) jit_addi_l((d), (rs), (is))
|
||||||
|
#define jit_addr_ul(d, s1, s2) jit_addr_l((d), (s1), (s2))
|
||||||
|
#define jit_addci_ul(d, rs, is) jit_addci_l((d), (rs), (is))
|
||||||
|
#define jit_addcr_ul(d, s1, s2) jit_addcr_l((d), (s1), (s2))
|
||||||
|
#define jit_addxi_ul(d, rs, is) jit_addxi_l((d), (rs), (is))
|
||||||
|
#define jit_addxr_ul(d, s1, s2) jit_addxr_l((d), (s1), (s2))
|
||||||
|
#define jit_andi_ul(d, rs, is) jit_andi_l((d), (rs), (is))
|
||||||
|
#define jit_andr_ul(d, s1, s2) jit_andr_l((d), (s1), (s2))
|
||||||
|
#define jit_lshi_ul(d, rs, is) jit_lshi_l((d), (rs), (is))
|
||||||
|
#define jit_lshr_ul(d, s1, s2) jit_lshr_l((d), (s1), (s2))
|
||||||
|
#define jit_movi_ul(d, rs) jit_movi_l((d), (rs))
|
||||||
|
#define jit_movr_ul(d, rs) jit_movr_l((d), (rs))
|
||||||
|
#define jit_ori_ul(d, rs, is) jit_ori_l((d), (rs), (is))
|
||||||
|
#define jit_orr_ul(d, s1, s2) jit_orr_l((d), (s1), (s2))
|
||||||
|
#define jit_rsbi_ul(d, rs, is) jit_rsbi_l((d), (rs), (is))
|
||||||
|
#define jit_rsbr_ul(d, s1, s2) jit_rsbr_l((d), (s1), (s2))
|
||||||
|
#define jit_subi_ul(d, rs, is) jit_subi_l((d), (rs), (is))
|
||||||
|
#define jit_subr_ul(d, s1, s2) jit_subr_l((d), (s1), (s2))
|
||||||
|
#define jit_subci_ul(d, rs, is) jit_subci_l((d), (rs), (is))
|
||||||
|
#define jit_subcr_ul(d, s1, s2) jit_subcr_l((d), (s1), (s2))
|
||||||
|
#define jit_subxi_ui(d, rs, is) jit_subxi_i((d), (rs), (is))
|
||||||
|
#define jit_subxr_ui(d, s1, s2) jit_subxr_i((d), (s1), (s2))
|
||||||
|
#define jit_xori_ul(d, rs, is) jit_xori_l((d), (rs), (is))
|
||||||
|
#define jit_xorr_ul(d, s1, s2) jit_xorr_l((d), (s1), (s2))
|
||||||
|
|
||||||
|
#define jit_addr_p(d, s1, s2) jit_addr_ul((d), (s1), (s2))
|
||||||
|
#define jit_addi_p(d, rs, is) jit_addi_ul((d), (rs), (long) (is))
|
||||||
|
#define jit_movr_p(d, rs) jit_movr_ul((d), (rs))
|
||||||
|
#define jit_movi_p(d, is) jit_movi_ul((d), (long) (is))
|
||||||
|
#define jit_subr_p(d, s1, s2) jit_subr_ul((d), (s1), (s2))
|
||||||
|
#define jit_subi_p(d, rs, is) jit_subi_ul((d), (rs), (long) (is))
|
||||||
|
|
||||||
|
#ifndef jit_addci_i
|
||||||
|
#define jit_addci_i(d, rs, is) jit_addi_i((d), (rs), (is))
|
||||||
|
#define jit_addcr_i(d, s1, s2) jit_addr_i((d), (s1), (s2))
|
||||||
|
#define jit_addci_l(d, rs, is) jit_addi_l((d), (rs), (is))
|
||||||
|
#define jit_addcr_l(d, s1, s2) jit_addr_l((d), (s1), (s2))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef jit_subcr_i
|
||||||
|
#define jit_subcr_i(d, s1, s2) jit_subr_i((d), (s1), (s2))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* NEG is not mandatory -- pick an appropriate implementation */
|
||||||
|
#ifndef jit_negr_i
|
||||||
|
# ifdef JIT_RZERO
|
||||||
|
# define jit_negr_i(d, rs) jit_subr_i((d), JIT_RZERO, (rs))
|
||||||
|
# define jit_negr_l(d, rs) jit_subr_l((d), JIT_RZERO, (rs))
|
||||||
|
# else /* !JIT_RZERO */
|
||||||
|
# ifndef jit_rsbi_i
|
||||||
|
# define jit_negr_i(d, rs) (jit_xori_i((d), (rs), -1), jit_addi_l((d), (d), 1))
|
||||||
|
# define jit_negr_l(d, rs) (jit_xori_l((d), (rs), -1), jit_addi_l((d), (d), 1))
|
||||||
|
# else /* jit_rsbi_i */
|
||||||
|
# define jit_negr_i(d, rs) jit_rsbi_i((d), (rs), 0)
|
||||||
|
# define jit_negr_l(d, rs) jit_rsbi_l((d), (rs), 0)
|
||||||
|
# endif /* jit_rsbi_i */
|
||||||
|
# endif /* !JIT_RZERO */
|
||||||
|
#endif /* !jit_negr_i */
|
||||||
|
|
||||||
|
/* RSB is not mandatory */
|
||||||
|
#ifndef jit_rsbi_i
|
||||||
|
# define jit_rsbi_i(d, rs, is) (jit_subi_i((d), (rs), (is)), jit_negr_i((d), (d)))
|
||||||
|
|
||||||
|
# ifndef jit_rsbi_l
|
||||||
|
# define jit_rsbi_l(d, rs, is) (jit_subi_l((d), (rs), (is)), jit_negr_l((d), (d)))
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Common 'shortcut' implementations */
|
||||||
|
#define jit_subi_i(d, rs, is) jit_addi_i((d), (rs), -(is))
|
||||||
|
#define jit_subi_l(d, rs, is) jit_addi_l((d), (rs), -(is))
|
||||||
|
#define jit_subci_i(d, rs, is) jit_addci_i((d), (rs), -(is))
|
||||||
|
#define jit_subci_l(d, rs, is) jit_addci_l((d), (rs), -(is))
|
||||||
|
#define jit_rsbr_i(d, s1, s2) jit_subr_i((d), (s2), (s1))
|
||||||
|
#define jit_rsbr_l(d, s1, s2) jit_subr_l((d), (s2), (s1))
|
||||||
|
|
||||||
|
/* Unary */
|
||||||
|
#define jit_notr_c(d, rs) jit_xori_c((d), (rs), 255)
|
||||||
|
#define jit_notr_uc(d, rs) jit_xori_c((d), (rs), 255)
|
||||||
|
#define jit_notr_s(d, rs) jit_xori_s((d), (rs), 65535)
|
||||||
|
#define jit_notr_us(d, rs) jit_xori_s((d), (rs), 65535)
|
||||||
|
#define jit_notr_i(d, rs) jit_xori_i((d), (rs), ~0)
|
||||||
|
#define jit_notr_ui(d, rs) jit_xori_i((d), (rs), ~0)
|
||||||
|
#define jit_notr_l(d, rs) jit_xori_l((d), (rs), ~0L)
|
||||||
|
#define jit_notr_ul(d, rs) jit_xori_l((d), (rs), ~0L)
|
||||||
|
|
||||||
|
#ifndef jit_extr_c_ui
|
||||||
|
#define jit_extr_c_ui(d, rs) jit_andi_ui((d), (rs), 0xFF)
|
||||||
|
#endif
|
||||||
|
#ifndef jit_extr_s_ui
|
||||||
|
#define jit_extr_s_ui(d, rs) jit_andi_ui((d), (rs), 0xFFFF)
|
||||||
|
#endif
|
||||||
|
#ifndef jit_extr_c_i
|
||||||
|
#define jit_extr_c_i(d, rs) (jit_lshi_i((d), (rs), 24), jit_rshi_i((d), (d), 24))
|
||||||
|
#endif
|
||||||
|
#ifndef jit_extr_s_i
|
||||||
|
#define jit_extr_s_i(d, rs) (jit_lshi_i((d), (rs), 16), jit_rshi_i((d), (d), 16))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define jit_extr_uc_i(d, rs) jit_extr_c_ui((d), (rs))
|
||||||
|
#define jit_extr_uc_ui(d, rs) jit_extr_c_ui((d), (rs))
|
||||||
|
#define jit_extr_us_i(d, rs) jit_extr_s_ui((d), (rs))
|
||||||
|
#define jit_extr_us_ui(d, rs) jit_extr_s_ui((d), (rs))
|
||||||
|
|
||||||
|
#ifndef jit_extr_i_ul
|
||||||
|
#ifdef jit_addi_l /* sizeof(long) != sizeof(int) */
|
||||||
|
#define jit_extr_i_ul(d, rs) jit_andi_ui((d), (rs), 0xFF)
|
||||||
|
#else /* sizeof(long) == sizeof(int) */
|
||||||
|
#define jit_extr_i_ul(d, rs) jit_movr_i(d, rs)
|
||||||
|
#endif /* sizeof(long) == sizeof(int) */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define jit_extr_ui_l(d, rs) jit_extr_i_ul((d), (rs))
|
||||||
|
#define jit_extr_ui_ul(d, rs) jit_extr_i_ul((d), (rs))
|
||||||
|
|
||||||
|
/* NTOH/HTON is not mandatory for big endian architectures */
|
||||||
|
#ifndef jit_ntoh_ui /* big endian */
|
||||||
|
#define jit_ntoh_ui(d, rs) ((d) == (rs) ? (void)0 : jit_movr_i((d), (rs)))
|
||||||
|
#define jit_ntoh_us(d, rs) ((d) == (rs) ? (void)0 : jit_movr_i((d), (rs)))
|
||||||
|
#endif /* big endian */
|
||||||
|
|
||||||
|
/* hton is a synonym for ntoh */
|
||||||
|
#define jit_hton_ui(d, rs) jit_ntoh_ui((d), (rs))
|
||||||
|
#define jit_hton_us(d, rs) jit_ntoh_us((d), (rs))
|
||||||
|
|
||||||
|
/* Stack synonyms */
|
||||||
|
#define jit_pushr_ui(rs) jit_pushr_i(rs)
|
||||||
|
#define jit_popr_ui(rs) jit_popr_i(rs)
|
||||||
|
#define jit_pushr_ul(rs) jit_pushr_l(rs)
|
||||||
|
#define jit_popr_ul(rs) jit_popr_l(rs)
|
||||||
|
#define jit_pushr_p(rs) jit_pushr_ul(rs)
|
||||||
|
#define jit_popr_p(rs) jit_popr_ul(rs)
|
||||||
|
|
||||||
|
#define jit_prepare(nint) jitfp_prepare((nint), 0, 0)
|
||||||
|
#define jit_pusharg_c(rs) jit_pusharg_i(rs)
|
||||||
|
#define jit_pusharg_s(rs) jit_pusharg_i(rs)
|
||||||
|
#define jit_pusharg_uc(rs) jit_pusharg_i(rs)
|
||||||
|
#define jit_pusharg_us(rs) jit_pusharg_i(rs)
|
||||||
|
#define jit_pusharg_ui(rs) jit_pusharg_i(rs)
|
||||||
|
#define jit_pusharg_ul(rs) jit_pusharg_l(rs)
|
||||||
|
#define jit_pusharg_p(rs) jit_pusharg_ul(rs)
|
||||||
|
|
||||||
|
/* Memory synonyms */
|
||||||
|
|
||||||
|
#ifdef JIT_RZERO
|
||||||
|
#ifndef jit_ldi_c
|
||||||
|
#define jit_ldi_c(rd, is) jit_ldxi_c((rd), JIT_RZERO, (is))
|
||||||
|
#define jit_sti_c(id, rs) jit_stxi_c((id), JIT_RZERO, (rs))
|
||||||
|
#define jit_ldi_s(rd, is) jit_ldxi_s((rd), JIT_RZERO, (is))
|
||||||
|
#define jit_sti_s(id, rs) jit_stxi_s((id), JIT_RZERO, (rs))
|
||||||
|
#define jit_ldi_i(rd, is) jit_ldxi_i((rd), JIT_RZERO, (is))
|
||||||
|
#define jit_sti_i(id, rs) jit_stxi_i((id), JIT_RZERO, (rs))
|
||||||
|
#define jit_ldi_l(rd, is) jit_ldxi_l((rd), JIT_RZERO, (is))
|
||||||
|
#define jit_sti_l(id, rs) jit_stxi_l((id), JIT_RZERO, (rs))
|
||||||
|
#define jit_ldi_uc(rd, is) jit_ldxi_uc((rd), JIT_RZERO, (is))
|
||||||
|
#define jit_ldi_us(rd, is) jit_ldxi_us((rd), JIT_RZERO, (is))
|
||||||
|
#define jit_ldi_ui(rd, is) jit_ldxi_ui((rd), JIT_RZERO, (is))
|
||||||
|
#define jit_ldi_ul(rd, is) jit_ldxi_ul((rd), JIT_RZERO, (is))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef jit_ldr_c
|
||||||
|
#define jit_ldr_c(rd, rs) jit_ldxr_c((rd), JIT_RZERO, (rs))
|
||||||
|
#define jit_str_c(rd, rs) jit_stxr_c(JIT_RZERO, (rd), (rs))
|
||||||
|
#define jit_ldr_s(rd, rs) jit_ldxr_s((rd), JIT_RZERO, (rs))
|
||||||
|
#define jit_str_s(rd, rs) jit_stxr_s(JIT_RZERO, (rd), (rs))
|
||||||
|
#define jit_ldr_i(rd, rs) jit_ldxr_i((rd), JIT_RZERO, (rs))
|
||||||
|
#define jit_str_i(rd, rs) jit_stxr_i(JIT_RZERO, (rd), (rs))
|
||||||
|
#define jit_ldr_l(rd, rs) jit_ldxr_l((rd), JIT_RZERO, (rs))
|
||||||
|
#define jit_str_l(rd, rs) jit_stxr_l(JIT_RZERO, (rd), (rs))
|
||||||
|
#define jit_ldr_uc(rd, rs) jit_ldxr_uc((rd), JIT_RZERO, (rs))
|
||||||
|
#define jit_ldr_us(rd, rs) jit_ldxr_us((rd), JIT_RZERO, (rs))
|
||||||
|
#define jit_ldr_ui(rd, rs) jit_ldxr_ui((rd), JIT_RZERO, (rs))
|
||||||
|
#define jit_ldr_ul(rd, rs) jit_ldxr_ul((rd), JIT_RZERO, (rs))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define jit_str_uc(rd, rs) jit_str_c((rd), (rs))
|
||||||
|
#define jit_sti_uc(id, rs) jit_sti_c((id), (rs))
|
||||||
|
#define jit_stxr_uc(d1, d2, rs) jit_stxr_c((d1), (d2), (rs))
|
||||||
|
#define jit_stxi_uc(id, rd, is) jit_stxi_c((id), (rd), (is))
|
||||||
|
|
||||||
|
#define jit_str_us(rd, rs) jit_str_s((rd), (rs))
|
||||||
|
#define jit_sti_us(id, rs) jit_sti_s((id), (rs))
|
||||||
|
#define jit_stxr_us(d1, d2, rs) jit_stxr_s((d1), (d2), (rs))
|
||||||
|
#define jit_stxi_us(id, rd, is) jit_stxi_s((id), (rd), (is))
|
||||||
|
|
||||||
|
#define jit_str_ui(rd, rs) jit_str_i((rd), (rs))
|
||||||
|
#define jit_sti_ui(id, rs) jit_sti_i((id), (rs))
|
||||||
|
#define jit_stxr_ui(d1, d2, rs) jit_stxr_i((d1), (d2), (rs))
|
||||||
|
#define jit_stxi_ui(id, rd, is) jit_stxi_i((id), (rd), (is))
|
||||||
|
|
||||||
|
#define jit_str_ul(rd, rs) jit_str_l((rd), (rs))
|
||||||
|
#define jit_sti_ul(id, rs) jit_sti_l((id), (rs))
|
||||||
|
#define jit_stxr_ul(d1, d2, rs) jit_stxr_l((d1), (d2), (rs))
|
||||||
|
#define jit_stxi_ul(id, rd, is) jit_stxi_l((id), (rd), (is))
|
||||||
|
|
||||||
|
#define jit_str_p(rd, rs) jit_str_l((rd), (rs))
|
||||||
|
#define jit_sti_p(id, rs) jit_sti_l((id), (rs))
|
||||||
|
#define jit_stxr_p(d1, d2, rs) jit_stxr_l((d1), (d2), (rs))
|
||||||
|
#define jit_stxi_p(id, rd, is) jit_stxi_l((id), (rd), (is))
|
||||||
|
|
||||||
|
#define jit_ldr_p(rd, rs) jit_ldr_l((rd), (rs))
|
||||||
|
#define jit_ldi_p(rd, is) jit_ldi_l((rd), (is))
|
||||||
|
#define jit_ldxr_p(rd, s1, s2) jit_ldxr_l((rd), (s1), (s2))
|
||||||
|
#define jit_ldxi_p(rd, rs, is) jit_ldxi_l((rd), (rs), (is))
|
||||||
|
|
||||||
|
|
||||||
|
/* Boolean & branch synonyms */
|
||||||
|
#define jit_eqr_ui(d, s1, s2) jit_eqr_i((d), (s1), (s2))
|
||||||
|
#define jit_eqi_ui(d, rs, is) jit_eqi_i((d), (rs), (is))
|
||||||
|
#define jit_ner_ui(d, s1, s2) jit_ner_i((d), (s1), (s2))
|
||||||
|
#define jit_nei_ui(d, rs, is) jit_nei_i((d), (rs), (is))
|
||||||
|
|
||||||
|
#define jit_eqr_ul(d, s1, s2) jit_eqr_l((d), (s1), (s2))
|
||||||
|
#define jit_eqi_ul(d, rs, is) jit_eqi_l((d), (rs), (is))
|
||||||
|
#define jit_ner_ul(d, s1, s2) jit_ner_l((d), (s1), (s2))
|
||||||
|
#define jit_nei_ul(d, rs, is) jit_nei_l((d), (rs), (is))
|
||||||
|
|
||||||
|
#define jit_beqr_ui(label, s1, s2) jit_beqr_i((label), (s1), (s2))
|
||||||
|
#define jit_beqi_ui(label, rs, is) jit_beqi_i((label), (rs), (is))
|
||||||
|
#define jit_bner_ui(label, s1, s2) jit_bner_i((label), (s1), (s2))
|
||||||
|
#define jit_bnei_ui(label, rs, is) jit_bnei_i((label), (rs), (is))
|
||||||
|
#define jit_bmcr_ui(label, s1, s2) jit_bmcr_i((label), (s1), (s2))
|
||||||
|
#define jit_bmci_ui(label, rs, is) jit_bmci_i((label), (rs), (is))
|
||||||
|
#define jit_bmsr_ui(label, s1, s2) jit_bmsr_i((label), (s1), (s2))
|
||||||
|
#define jit_bmsi_ui(label, rs, is) jit_bmsi_i((label), (rs), (is))
|
||||||
|
|
||||||
|
#define jit_beqr_ul(label, s1, s2) jit_beqr_l((label), (s1), (s2))
|
||||||
|
#define jit_beqi_ul(label, rs, is) jit_beqi_l((label), (rs), (is))
|
||||||
|
#define jit_bner_ul(label, s1, s2) jit_bner_l((label), (s1), (s2))
|
||||||
|
#define jit_bnei_ul(label, rs, is) jit_bnei_l((label), (rs), (is))
|
||||||
|
#define jit_bmcr_ul(label, s1, s2) jit_bmcr_l((label), (s1), (s2))
|
||||||
|
#define jit_bmci_ul(label, rs, is) jit_bmci_l((label), (rs), (is))
|
||||||
|
#define jit_bmsr_ul(label, s1, s2) jit_bmsr_l((label), (s1), (s2))
|
||||||
|
#define jit_bmsi_ul(label, rs, is) jit_bmsi_l((label), (rs), (is))
|
||||||
|
|
||||||
|
#define jit_ltr_p(d, s1, s2) jit_ltr_ul((d), (s1), (s2))
|
||||||
|
#define jit_lti_p(d, rs, is) jit_lti_ul((d), (rs), (is))
|
||||||
|
#define jit_ler_p(d, s1, s2) jit_ler_ul((d), (s1), (s2))
|
||||||
|
#define jit_lei_p(d, rs, is) jit_lei_ul((d), (rs), (is))
|
||||||
|
#define jit_gtr_p(d, s1, s2) jit_gtr_ul((d), (s1), (s2))
|
||||||
|
#define jit_gti_p(d, rs, is) jit_gti_ul((d), (rs), (is))
|
||||||
|
#define jit_ger_p(d, s1, s2) jit_ger_ul((d), (s1), (s2))
|
||||||
|
#define jit_gei_p(d, rs, is) jit_gei_ul((d), (rs), (is))
|
||||||
|
#define jit_eqr_p(d, s1, s2) jit_eqr_ul((d), (s1), (s2))
|
||||||
|
#define jit_eqi_p(d, rs, is) jit_eqi_ul((d), (rs), (is))
|
||||||
|
#define jit_ner_p(d, s1, s2) jit_ner_ul((d), (s1), (s2))
|
||||||
|
#define jit_nei_p(d, rs, is) jit_nei_ul((d), (rs), (is))
|
||||||
|
|
||||||
|
#define jit_bltr_p(label, s1, s2) jit_bltr_ul((label), (s1), (s2))
|
||||||
|
#define jit_blti_p(label, rs, is) jit_blti_ul((label), (rs), (is))
|
||||||
|
#define jit_bler_p(label, s1, s2) jit_bler_ul((label), (s1), (s2))
|
||||||
|
#define jit_blei_p(label, rs, is) jit_blei_ul((label), (rs), (is))
|
||||||
|
#define jit_bgtr_p(label, s1, s2) jit_bgtr_ul((label), (s1), (s2))
|
||||||
|
#define jit_bgti_p(label, rs, is) jit_bgti_ul((label), (rs), (is))
|
||||||
|
#define jit_bger_p(label, s1, s2) jit_bger_ul((label), (s1), (s2))
|
||||||
|
#define jit_bgei_p(label, rs, is) jit_bgei_ul((label), (rs), (is))
|
||||||
|
#define jit_beqr_p(label, s1, s2) jit_beqr_ul((label), (s1), (s2))
|
||||||
|
#define jit_beqi_p(label, rs, is) jit_beqi_ul((label), (rs), (is))
|
||||||
|
#define jit_bner_p(label, s1, s2) jit_bner_ul((label), (s1), (s2))
|
||||||
|
#define jit_bnei_p(label, rs, is) jit_bnei_ul((label), (rs), (is))
|
||||||
|
|
||||||
|
#define jit_retval_ui(rd) jit_retval_i((rd))
|
||||||
|
#define jit_retval_uc(rd) jit_retval_i((rd))
|
||||||
|
#define jit_retval_us(rd) jit_retval_i((rd))
|
||||||
|
#define jit_retval_ul(rd) jit_retval_l((rd))
|
||||||
|
#define jit_retval_p(rd) jit_retval_ul((rd))
|
||||||
|
#define jit_retval_c(rd) jit_retval_i((rd))
|
||||||
|
#define jit_retval_s(rd) jit_retval_i((rd))
|
||||||
|
|
||||||
|
#ifndef jit_finish
|
||||||
|
#define jit_finish(sub) jit_calli(sub)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef jit_prolog
|
||||||
|
#define jit_prolog(numargs)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef jit_leaf
|
||||||
|
#define jit_leaf(numargs) jit_prolog(numargs)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef jit_getarg_c
|
||||||
|
#ifndef JIT_FP
|
||||||
|
#define jit_getarg_c(reg, ofs) jit_extr_c_i ((reg), (ofs))
|
||||||
|
#define jit_getarg_i(reg, ofs) jit_movr_i ((reg), (ofs))
|
||||||
|
#define jit_getarg_l(reg, ofs) jit_movr_l ((reg), (ofs))
|
||||||
|
#define jit_getarg_p(reg, ofs) jit_movr_p ((reg), (ofs))
|
||||||
|
#define jit_getarg_s(reg, ofs) jit_extr_s_i ((reg), (ofs))
|
||||||
|
#define jit_getarg_uc(reg, ofs) jit_extr_uc_ui((reg), (ofs))
|
||||||
|
#define jit_getarg_ui(reg, ofs) jit_movr_ui ((reg), (ofs))
|
||||||
|
#define jit_getarg_ul(reg, ofs) jit_extr_uc_ul((reg), (ofs))
|
||||||
|
#define jit_getarg_us(reg, ofs) jit_extr_us_ul((reg), (ofs))
|
||||||
|
#else
|
||||||
|
#define jit_getarg_c(reg, ofs) jit_ldxi_c((reg), JIT_FP, (ofs));
|
||||||
|
#define jit_getarg_uc(reg, ofs) jit_ldxi_uc((reg), JIT_FP, (ofs));
|
||||||
|
#define jit_getarg_s(reg, ofs) jit_ldxi_s((reg), JIT_FP, (ofs));
|
||||||
|
#define jit_getarg_us(reg, ofs) jit_ldxi_us((reg), JIT_FP, (ofs));
|
||||||
|
#define jit_getarg_i(reg, ofs) jit_ldxi_i((reg), JIT_FP, (ofs));
|
||||||
|
#define jit_getarg_ui(reg, ofs) jit_ldxi_ui((reg), JIT_FP, (ofs));
|
||||||
|
#define jit_getarg_l(reg, ofs) jit_ldxi_l((reg), JIT_FP, (ofs));
|
||||||
|
#define jit_getarg_ul(reg, ofs) jit_ldxi_ul((reg), JIT_FP, (ofs));
|
||||||
|
#define jit_getarg_p(reg, ofs) jit_ldxi_p((reg), JIT_FP, (ofs));
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Common definitions when sizeof(long) = sizeof(int) */
|
||||||
|
#ifndef jit_addi_l
|
||||||
|
#define JIT_LONG_IS_INT
|
||||||
|
|
||||||
|
/* ALU */
|
||||||
|
#define jit_addi_l(d, rs, is) jit_addi_i((d), (rs), (is))
|
||||||
|
#define jit_addr_l(d, s1, s2) jit_addr_i((d), (s1), (s2))
|
||||||
|
#define jit_addci_l(d, rs, is) jit_addci_i((d), (rs), (is))
|
||||||
|
#define jit_addcr_l(d, s1, s2) jit_addcr_i((d), (s1), (s2))
|
||||||
|
#define jit_addxi_l(d, rs, is) jit_addxi_i((d), (rs), (is))
|
||||||
|
#define jit_addxr_l(d, s1, s2) jit_addxr_i((d), (s1), (s2))
|
||||||
|
#define jit_andi_l(d, rs, is) jit_andi_i((d), (rs), (is))
|
||||||
|
#define jit_andr_l(d, s1, s2) jit_andr_i((d), (s1), (s2))
|
||||||
|
#define jit_divi_l(d, rs, is) jit_divi_i((d), (rs), (is))
|
||||||
|
#define jit_divr_l(d, s1, s2) jit_divr_i((d), (s1), (s2))
|
||||||
|
#define jit_hmuli_l(d, rs, is) jit_hmuli_i((d), (rs), (is))
|
||||||
|
#define jit_hmulr_l(d, s1, s2) jit_hmulr_i((d), (s1), (s2))
|
||||||
|
#define jit_lshi_l(d, rs, is) jit_lshi_i((d), (rs), (is))
|
||||||
|
#define jit_lshr_l(d, s1, s2) jit_lshr_i((d), (s1), (s2))
|
||||||
|
#define jit_modi_l(d, rs, is) jit_modi_i((d), (rs), (is))
|
||||||
|
#define jit_modr_l(d, s1, s2) jit_modr_i((d), (s1), (s2))
|
||||||
|
#define jit_muli_l(d, rs, is) jit_muli_i((d), (rs), (is))
|
||||||
|
#define jit_mulr_l(d, s1, s2) jit_mulr_i((d), (s1), (s2))
|
||||||
|
#define jit_ori_l(d, rs, is) jit_ori_i((d), (rs), (is))
|
||||||
|
#define jit_orr_l(d, s1, s2) jit_orr_i((d), (s1), (s2))
|
||||||
|
#define jit_rshi_l(d, rs, is) jit_rshi_i((d), (rs), (is))
|
||||||
|
#define jit_rshr_l(d, s1, s2) jit_rshr_i((d), (s1), (s2))
|
||||||
|
#define jit_subr_l(d, s1, s2) jit_subr_i((d), (s1), (s2))
|
||||||
|
#define jit_subcr_l(d, s1, s2) jit_subcr_i((d), (s1), (s2))
|
||||||
|
#define jit_subxi_l(d, rs, is) jit_subxi_i((d), (rs), (is))
|
||||||
|
#define jit_subxr_l(d, s1, s2) jit_subxr_i((d), (s1), (s2))
|
||||||
|
#define jit_xori_l(d, rs, is) jit_xori_i((d), (rs), (is))
|
||||||
|
#define jit_xorr_l(d, s1, s2) jit_xorr_i((d), (s1), (s2))
|
||||||
|
|
||||||
|
#ifndef jit_rsbi_l
|
||||||
|
#define jit_rsbi_l(d, rs, is) jit_rsbi_i((d), (rs), (is))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define jit_divi_ul(d, rs, is) jit_divi_ui((d), (rs), (is))
|
||||||
|
#define jit_divr_ul(d, s1, s2) jit_divr_ui((d), (s1), (s2))
|
||||||
|
#define jit_hmuli_ul(d, rs, is) jit_hmuli_ui((d), (rs), (is))
|
||||||
|
#define jit_hmulr_ul(d, s1, s2) jit_hmulr_ui((d), (s1), (s2))
|
||||||
|
#define jit_modi_ul(d, rs, is) jit_modi_ui((d), (rs), (is))
|
||||||
|
#define jit_modr_ul(d, s1, s2) jit_modr_ui((d), (s1), (s2))
|
||||||
|
#define jit_muli_ul(d, rs, is) jit_muli_ui((d), (rs), (is))
|
||||||
|
#define jit_mulr_ul(d, s1, s2) jit_mulr_ui((d), (s1), (s2))
|
||||||
|
#define jit_rshi_ul(d, rs, is) jit_rshi_ui((d), (rs), (is))
|
||||||
|
#define jit_rshr_ul(d, s1, s2) jit_rshr_ui((d), (s1), (s2))
|
||||||
|
|
||||||
|
/* Unary */
|
||||||
|
#define jit_movi_l(d, rs) jit_movi_i((d), (rs))
|
||||||
|
#define jit_movr_l(d, rs) jit_movr_i((d), (rs))
|
||||||
|
|
||||||
|
/* Stack */
|
||||||
|
#define jit_pushr_l(rs) jit_pushr_i(rs)
|
||||||
|
#define jit_popr_l(rs) jit_popr_i(rs)
|
||||||
|
#define jit_pusharg_l(rs) jit_pusharg_i(rs)
|
||||||
|
|
||||||
|
/* Memory */
|
||||||
|
#ifndef JIT_RZERO
|
||||||
|
#define jit_ldr_l(d, rs) jit_ldr_i((d), (rs))
|
||||||
|
#define jit_ldi_l(d, is) jit_ldi_i((d), (is))
|
||||||
|
#define jit_str_l(d, rs) jit_str_i((d), (rs))
|
||||||
|
#define jit_sti_l(d, is) jit_sti_i((d), (is))
|
||||||
|
#define jit_ldr_ui(d, rs) jit_ldr_i((d), (rs))
|
||||||
|
#define jit_ldi_ui(d, is) jit_ldi_i((d), (is))
|
||||||
|
#define jit_ldr_ul(d, rs) jit_ldr_ui((d), (rs))
|
||||||
|
#define jit_ldi_ul(d, is) jit_ldi_ui((d), (is))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define jit_ldxr_l(d, s1, s2) jit_ldxr_i((d), (s1), (s2))
|
||||||
|
#define jit_ldxi_l(d, rs, is) jit_ldxi_i((d), (rs), (is))
|
||||||
|
#define jit_stxr_l(d, s1, s2) jit_stxr_i((d), (s1), (s2))
|
||||||
|
#define jit_stxi_l(d, rs, is) jit_stxi_i((d), (rs), (is))
|
||||||
|
#define jit_ldxr_ui(d, s1, s2) jit_ldxr_i((d), (s1), (s2))
|
||||||
|
#define jit_ldxi_ui(d, rs, is) jit_ldxi_i((d), (rs), (is))
|
||||||
|
#define jit_ldxr_ul(d, s1, s2) jit_ldxr_ui((d), (s1), (s2))
|
||||||
|
#define jit_ldxi_ul(d, rs, is) jit_ldxi_ui((d), (rs), (is))
|
||||||
|
|
||||||
|
|
||||||
|
/* Boolean */
|
||||||
|
#define jit_ltr_l(d, s1, s2) jit_ltr_i((d), (s1), (s2))
|
||||||
|
#define jit_lti_l(d, rs, is) jit_lti_i((d), (rs), (is))
|
||||||
|
#define jit_ler_l(d, s1, s2) jit_ler_i((d), (s1), (s2))
|
||||||
|
#define jit_lei_l(d, rs, is) jit_lei_i((d), (rs), (is))
|
||||||
|
#define jit_gtr_l(d, s1, s2) jit_gtr_i((d), (s1), (s2))
|
||||||
|
#define jit_gti_l(d, rs, is) jit_gti_i((d), (rs), (is))
|
||||||
|
#define jit_ger_l(d, s1, s2) jit_ger_i((d), (s1), (s2))
|
||||||
|
#define jit_gei_l(d, rs, is) jit_gei_i((d), (rs), (is))
|
||||||
|
#define jit_eqr_l(d, s1, s2) jit_eqr_i((d), (s1), (s2))
|
||||||
|
#define jit_eqi_l(d, rs, is) jit_eqi_i((d), (rs), (is))
|
||||||
|
#define jit_ner_l(d, s1, s2) jit_ner_i((d), (s1), (s2))
|
||||||
|
#define jit_nei_l(d, rs, is) jit_nei_i((d), (rs), (is))
|
||||||
|
#define jit_ltr_ul(d, s1, s2) jit_ltr_ui((d), (s1), (s2))
|
||||||
|
#define jit_lti_ul(d, rs, is) jit_lti_ui((d), (rs), (is))
|
||||||
|
#define jit_ler_ul(d, s1, s2) jit_ler_ui((d), (s1), (s2))
|
||||||
|
#define jit_lei_ul(d, rs, is) jit_lei_ui((d), (rs), (is))
|
||||||
|
#define jit_gtr_ul(d, s1, s2) jit_gtr_ui((d), (s1), (s2))
|
||||||
|
#define jit_gti_ul(d, rs, is) jit_gti_ui((d), (rs), (is))
|
||||||
|
#define jit_ger_ul(d, s1, s2) jit_ger_ui((d), (s1), (s2))
|
||||||
|
#define jit_gei_ul(d, rs, is) jit_gei_ui((d), (rs), (is))
|
||||||
|
|
||||||
|
/* Branches */
|
||||||
|
#define jit_bltr_l(label, s1, s2) jit_bltr_i((label), (s1), (s2))
|
||||||
|
#define jit_blti_l(label, rs, is) jit_blti_i((label), (rs), (is))
|
||||||
|
#define jit_bler_l(label, s1, s2) jit_bler_i((label), (s1), (s2))
|
||||||
|
#define jit_blei_l(label, rs, is) jit_blei_i((label), (rs), (is))
|
||||||
|
#define jit_bgtr_l(label, s1, s2) jit_bgtr_i((label), (s1), (s2))
|
||||||
|
#define jit_bgti_l(label, rs, is) jit_bgti_i((label), (rs), (is))
|
||||||
|
#define jit_bger_l(label, s1, s2) jit_bger_i((label), (s1), (s2))
|
||||||
|
#define jit_bgei_l(label, rs, is) jit_bgei_i((label), (rs), (is))
|
||||||
|
#define jit_beqr_l(label, s1, s2) jit_beqr_i((label), (s1), (s2))
|
||||||
|
#define jit_beqi_l(label, rs, is) jit_beqi_i((label), (rs), (is))
|
||||||
|
#define jit_bner_l(label, s1, s2) jit_bner_i((label), (s1), (s2))
|
||||||
|
#define jit_bnei_l(label, rs, is) jit_bnei_i((label), (rs), (is))
|
||||||
|
#define jit_bmcr_l(label, s1, s2) jit_bmcr_i((label), (s1), (s2))
|
||||||
|
#define jit_bmci_l(label, rs, is) jit_bmci_i((label), (rs), (is))
|
||||||
|
#define jit_bmsr_l(label, s1, s2) jit_bmsr_i((label), (s1), (s2))
|
||||||
|
#define jit_bmsi_l(label, rs, is) jit_bmsi_i((label), (rs), (is))
|
||||||
|
#define jit_boaddr_l(label, s1, s2) jit_boaddr_i((label), (s1), (s2))
|
||||||
|
#define jit_boaddi_l(label, rs, is) jit_boaddi_i((label), (rs), (is))
|
||||||
|
#define jit_bosubr_l(label, s1, s2) jit_bosubr_i((label), (s1), (s2))
|
||||||
|
#define jit_bosubi_l(label, rs, is) jit_bosubi_i((label), (rs), (is))
|
||||||
|
#define jit_bltr_ul(label, s1, s2) jit_bltr_ui((label), (s1), (s2))
|
||||||
|
#define jit_blti_ul(label, rs, is) jit_blti_ui((label), (rs), (is))
|
||||||
|
#define jit_bler_ul(label, s1, s2) jit_bler_ui((label), (s1), (s2))
|
||||||
|
#define jit_blei_ul(label, rs, is) jit_blei_ui((label), (rs), (is))
|
||||||
|
#define jit_bgtr_ul(label, s1, s2) jit_bgtr_ui((label), (s1), (s2))
|
||||||
|
#define jit_bgti_ul(label, rs, is) jit_bgti_ui((label), (rs), (is))
|
||||||
|
#define jit_bger_ul(label, s1, s2) jit_bger_ui((label), (s1), (s2))
|
||||||
|
#define jit_bgei_ul(label, rs, is) jit_bgei_ui((label), (rs), (is))
|
||||||
|
#define jit_boaddr_ul(label, s1, s2) jit_boaddr_ui((label), (s1), (s2))
|
||||||
|
#define jit_boaddi_ul(label, rs, is) jit_boaddi_ui((label), (rs), (is))
|
||||||
|
#define jit_bosubr_ul(label, s1, s2) jit_bosubr_ui((label), (s1), (s2))
|
||||||
|
#define jit_bosubi_ul(label, rs, is) jit_bosubi_ui((label), (rs), (is))
|
||||||
|
|
||||||
|
#define jit_retval_l(rd) jit_retval_i((rd))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __lightning_core_common_h_ */
|
260
lightning/fp-common.h
Normal file
260
lightning/fp-common.h
Normal file
|
@ -0,0 +1,260 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Platform-independent layer floating-point interface
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
struct jit_fp {
|
||||||
|
char kind;
|
||||||
|
char subkind;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
int displ;
|
||||||
|
char reg1;
|
||||||
|
char reg2;
|
||||||
|
} addr;
|
||||||
|
union {
|
||||||
|
double number;
|
||||||
|
long split[sizeof(double) / sizeof(long)];
|
||||||
|
} imm;
|
||||||
|
struct {
|
||||||
|
struct jit_fp *lhs, *rhs;
|
||||||
|
} ops;
|
||||||
|
} d;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef jit_trunc
|
||||||
|
|
||||||
|
enum { JIT_NULL, /* unused */
|
||||||
|
|
||||||
|
JIT_CMP, JIT_FLOOR, JIT_CEIL, JIT_ROUND, JIT_TRUNC, /* integer */
|
||||||
|
|
||||||
|
JIT_XI, JIT_ADD, JIT_XR, JIT_SUB, /* subkinds */
|
||||||
|
JIT_I, JIT_MUL, JIT_R, JIT_DIV,
|
||||||
|
JIT_INT,
|
||||||
|
|
||||||
|
JIT_ABS, JIT_SIN, JIT_COS, JIT_TAN, JIT_ATN, /* functions */
|
||||||
|
JIT_EXP, JIT_LOG, JIT_NEG, JIT_SQRT,
|
||||||
|
|
||||||
|
JIT_OP, JIT_FN, JIT_LD, JIT_IMM }; /* kinds */
|
||||||
|
|
||||||
|
/* Declarations */
|
||||||
|
|
||||||
|
static void _jit_emit(jit_state *, struct jit_fp *,
|
||||||
|
int, int, int, int) JIT_UNUSED;
|
||||||
|
static struct jit_fp *_jit_op(struct jit_fp *, int,
|
||||||
|
struct jit_fp *, struct jit_fp *) JIT_UNUSED;
|
||||||
|
static struct jit_fp *_jit_ld(struct jit_fp *, int,
|
||||||
|
int, int) JIT_UNUSED;
|
||||||
|
static struct jit_fp *_jit_fn(struct jit_fp *, int,
|
||||||
|
struct jit_fp *) JIT_UNUSED;
|
||||||
|
static struct jit_fp *_jit_imm(struct jit_fp *, double) JIT_UNUSED;
|
||||||
|
|
||||||
|
/* Internal function to walk the tree */
|
||||||
|
|
||||||
|
void
|
||||||
|
_jit_emit(jit_state *jit, struct jit_fp *head,
|
||||||
|
int store_kind, int store1, int store2, int reg0)
|
||||||
|
{
|
||||||
|
#define _jit (*jit)
|
||||||
|
switch (head->kind) {
|
||||||
|
case JIT_OP:
|
||||||
|
_jit_emit(jit, head->d.ops.lhs, JIT_NULL, 0, 0, reg0);
|
||||||
|
_jit_emit(jit, head->d.ops.rhs, JIT_NULL, 0, 0, reg0 + 1);
|
||||||
|
switch (head->subkind) {
|
||||||
|
case JIT_ADD: jit_add_two(reg0); break;
|
||||||
|
case JIT_SUB: jit_sub_two(reg0); break;
|
||||||
|
case JIT_MUL: jit_mul_two(reg0); break;
|
||||||
|
case JIT_DIV: jit_div_two(reg0); break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JIT_IMM:
|
||||||
|
#ifdef JIT_LONG_IS_INT
|
||||||
|
jit_fpimm(reg0, head->d.imm.split[0], head->d.imm.split[1]);
|
||||||
|
#else
|
||||||
|
jit_fpimm(reg0, head->d.imm.split[0]);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JIT_FN:
|
||||||
|
_jit_emit(jit, head->d.ops.lhs, JIT_NULL, 0, 0, reg0);
|
||||||
|
switch (head->subkind) {
|
||||||
|
case JIT_ABS: jit_abs(reg0); break;
|
||||||
|
case JIT_NEG: jit_neg(reg0); break;
|
||||||
|
#ifdef JIT_TRANSCENDENTAL
|
||||||
|
case JIT_SIN: jit_sin(reg0); break;
|
||||||
|
case JIT_SQRT: jit_sqrt(reg0); break;
|
||||||
|
case JIT_COS: jit_cos(reg0); break;
|
||||||
|
case JIT_TAN: jit_tan(reg0); break;
|
||||||
|
case JIT_ATN: jit_atn(reg0); break;
|
||||||
|
case JIT_EXP: jit_exp(reg0); break;
|
||||||
|
case JIT_LOG: jit_log(reg0); break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JIT_LD:
|
||||||
|
switch (head->subkind) {
|
||||||
|
case JIT_INT: jit_exti_d(reg0, head->d.addr.reg1); break;
|
||||||
|
case JIT_XI: jit_ldxi_f(reg0, head->d.addr.reg1, head->d.addr.displ); break;
|
||||||
|
case JIT_XR: jit_ldxr_f(reg0, head->d.addr.reg1, head->d.addr.reg2); break;
|
||||||
|
case JIT_XI | 1: jit_ldxi_d(reg0, head->d.addr.reg1, head->d.addr.displ); break;
|
||||||
|
case JIT_XR | 1: jit_ldxr_d(reg0, head->d.addr.reg1, head->d.addr.reg2); break;
|
||||||
|
#ifndef JIT_RZERO
|
||||||
|
case JIT_I: jit_ldi_f(reg0, head->d.addr.displ); break;
|
||||||
|
case JIT_R: jit_ldr_f(reg0, head->d.addr.reg1); break;
|
||||||
|
case JIT_I | 1: jit_ldi_d(reg0, head->d.addr.displ); break;
|
||||||
|
case JIT_R | 1: jit_ldr_d(reg0, head->d.addr.reg1); break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (store_kind) {
|
||||||
|
case JIT_FLOOR: jit_floor(store1, reg0); break;
|
||||||
|
case JIT_CEIL: jit_ceil(store1, reg0); break;
|
||||||
|
case JIT_TRUNC: jit_trunc(store1, reg0); break;
|
||||||
|
case JIT_ROUND: jit_round(store1, reg0); break;
|
||||||
|
case JIT_CMP: jit_cmp(store1, store2, reg0); break;
|
||||||
|
case JIT_XI: jit_stxi_f(store2, store1, reg0); break;
|
||||||
|
case JIT_XR: jit_stxr_f(store2, store1, reg0); break;
|
||||||
|
case JIT_XI | 1: jit_stxi_d(store2, store1, reg0); break;
|
||||||
|
case JIT_XR | 1: jit_stxr_d(store2, store1, reg0); break;
|
||||||
|
#ifndef JIT_RZERO
|
||||||
|
case JIT_I: jit_sti_f(store2, reg0); break;
|
||||||
|
case JIT_R: jit_str_f(store2, reg0); break;
|
||||||
|
case JIT_I | 1: jit_sti_d(store2, reg0); break;
|
||||||
|
case JIT_R | 1: jit_str_d(store2, reg0); break;
|
||||||
|
#endif
|
||||||
|
case JIT_NULL: break;
|
||||||
|
}
|
||||||
|
#undef _jit
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Internal functions to build the tree */
|
||||||
|
|
||||||
|
struct jit_fp *
|
||||||
|
_jit_op(struct jit_fp *where, int which,
|
||||||
|
struct jit_fp *op1, struct jit_fp *op2)
|
||||||
|
{
|
||||||
|
where->kind = JIT_OP;
|
||||||
|
where->subkind = which;
|
||||||
|
where->d.ops.lhs = op1;
|
||||||
|
where->d.ops.rhs = op2;
|
||||||
|
return (where);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct jit_fp *
|
||||||
|
_jit_ld(struct jit_fp *where, int which, int op1, int op2)
|
||||||
|
{
|
||||||
|
where->kind = JIT_LD;
|
||||||
|
where->subkind = which;
|
||||||
|
switch (which & ~1) {
|
||||||
|
case JIT_XI: where->d.addr.reg1 = op1;
|
||||||
|
case JIT_I: where->d.addr.displ = op2; break;
|
||||||
|
case JIT_XR: where->d.addr.reg2 = op2;
|
||||||
|
case JIT_INT:
|
||||||
|
case JIT_R: where->d.addr.reg1 = op1; break;
|
||||||
|
}
|
||||||
|
return (where);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct jit_fp *
|
||||||
|
_jit_fn(struct jit_fp *where, int which, struct jit_fp *op1)
|
||||||
|
{
|
||||||
|
where->kind = JIT_FN;
|
||||||
|
where->subkind = which;
|
||||||
|
where->d.ops.lhs = op1;
|
||||||
|
return (where);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct jit_fp *
|
||||||
|
_jit_imm(struct jit_fp *where, double number)
|
||||||
|
{
|
||||||
|
where->kind = JIT_IMM;
|
||||||
|
where->d.imm.number = number;
|
||||||
|
return (where);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define jitfp_begin(buf) (_jit.fp = (buf), --_jit.fp)
|
||||||
|
#define jitfp_add(op1, op2) _jit_op(++_jit.fp, JIT_ADD, (op1), (op2))
|
||||||
|
#define jitfp_sub(op1, op2) _jit_op(++_jit.fp, JIT_SUB, (op1), (op2))
|
||||||
|
#define jitfp_mul(op1, op2) _jit_op(++_jit.fp, JIT_MUL, (op1), (op2))
|
||||||
|
#define jitfp_div(op1, op2) _jit_op(++_jit.fp, JIT_DIV, (op1), (op2))
|
||||||
|
#define jitfp_imm(imm) _jit_imm(++_jit.fp, (imm))
|
||||||
|
#define jitfp_exti_d(reg1) _jit_ld(++_jit.fp, JIT_INT, (reg1), 0)
|
||||||
|
#define jitfp_ldxi_f(reg1, imm) _jit_ld(++_jit.fp, JIT_XI, (reg1), (long)(imm))
|
||||||
|
#define jitfp_ldxr_f(reg1, reg2) _jit_ld(++_jit.fp, JIT_XR, (reg1), (reg2))
|
||||||
|
#define jitfp_ldxi_d(reg1, imm) _jit_ld(++_jit.fp, JIT_XI | 1, (reg1), (long)(imm))
|
||||||
|
#define jitfp_ldxr_d(reg1, reg2) _jit_ld(++_jit.fp, JIT_XR | 1, (reg1), (reg2))
|
||||||
|
#define jitfp_abs(op1) _jit_fn(++_jit.fp, JIT_ABS, (op1))
|
||||||
|
#define jitfp_sqrt(op1) _jit_fn(++_jit.fp, JIT_SQRT, (op1))
|
||||||
|
#define jitfp_neg(op1) _jit_fn(++_jit.fp, JIT_NEG, (op1))
|
||||||
|
#define jitfp_stxi_f(imm, reg1, op1) _jit_emit(&_jit, (op1), JIT_XI, (reg1), (long)(imm), 0)
|
||||||
|
#define jitfp_stxr_f(reg1, reg2, op1) _jit_emit(&_jit, (op1), JIT_XR, (reg1), (reg2), 0)
|
||||||
|
#define jitfp_stxi_d(imm, reg1, op1) _jit_emit(&_jit, (op1), JIT_XI | 1, (reg1), (long)(imm), 0)
|
||||||
|
#define jitfp_stxr_d(reg1, reg2, op1) _jit_emit(&_jit, (op1), JIT_XR | 1, (reg1), (reg2), 0)
|
||||||
|
#define jitfp_cmp(regle, regge, op1) _jit_emit(&_jit, (op1), JIT_CMP, regle, regge, 0)
|
||||||
|
#define jitfp_floor(reg1, op1) _jit_emit(&_jit, (op1), JIT_FLOOR, reg1, 0, 0)
|
||||||
|
#define jitfp_ceil(reg1, op1) _jit_emit(&_jit, (op1), JIT_CEIL, reg1, 0, 0)
|
||||||
|
#define jitfp_trunc(reg1, op1) _jit_emit(&_jit, (op1), JIT_TRUNC, reg1, 0, 0)
|
||||||
|
#define jitfp_round(reg1, op1) _jit_emit(&_jit, (op1), JIT_ROUND, reg1, 0, 0)
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef JIT_TRANSCENDENTAL
|
||||||
|
#define jitfp_sin(op1) _jit_fn(++_jit.fp, JIT_SIN, (op1))
|
||||||
|
#define jitfp_cos(op1) _jit_fn(++_jit.fp, JIT_COS, (op1))
|
||||||
|
#define jitfp_tan(op1) _jit_fn(++_jit.fp, JIT_TAN, (op1))
|
||||||
|
#define jitfp_atn(op1) _jit_fn(++_jit.fp, JIT_ATN, (op1))
|
||||||
|
#define jitfp_exp(op1) _jit_fn(++_jit.fp, JIT_EXP, (op1))
|
||||||
|
#define jitfp_log(op1) _jit_fn(++_jit.fp, JIT_LOG, (op1))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef JIT_RZERO
|
||||||
|
#define jitfp_ldi_f(imm) _jit_ld(++_jit.fp, JIT_XI, JIT_RZERO, (long)(imm))
|
||||||
|
#define jitfp_ldr_f(reg1) _jit_ld(++_jit.fp, JIT_XR, JIT_RZERO, (reg1))
|
||||||
|
#define jitfp_ldi_d(imm) _jit_ld(++_jit.fp, JIT_XI | 1, JIT_RZERO, (long)(imm))
|
||||||
|
#define jitfp_ldr_d(reg1) _jit_ld(++_jit.fp, JIT_XR | 1, JIT_RZERO, (reg1))
|
||||||
|
#define jitfp_sti_f(imm, op1) _jit_emit(&_jit, (op1), JIT_XI, JIT_RZERO, (long)(imm), 0)
|
||||||
|
#define jitfp_str_f(reg1, op1) _jit_emit(&_jit, (op1), JIT_XR, JIT_RZERO, (reg1), 0)
|
||||||
|
#define jitfp_sti_d(imm, op1) _jit_emit(&_jit, (op1), JIT_XI | 1, JIT_RZERO, (long)(imm), 0)
|
||||||
|
#define jitfp_str_d(reg1, op1) _jit_emit(&_jit, (op1), JIT_XR | 1, JIT_RZERO, (reg1), 0)
|
||||||
|
#else
|
||||||
|
#define jitfp_ldi_f(imm) _jit_ld(++_jit.fp, JIT_I, 0, (long)(imm))
|
||||||
|
#define jitfp_ldr_f(reg1) _jit_ld(++_jit.fp, JIT_R, (reg1), 0)
|
||||||
|
#define jitfp_ldi_d(imm) _jit_ld(++_jit.fp, JIT_I | 1, 0, (long)(imm))
|
||||||
|
#define jitfp_ldr_d(reg1) _jit_ld(++_jit.fp, JIT_R | 1, (reg1), 0)
|
||||||
|
#define jitfp_sti_f(imm, op1) _jit_emit(&_jit, (op1), JIT_I, 0, (long)(imm), 0)
|
||||||
|
#define jitfp_str_f(reg1, op1) _jit_emit(&_jit, (op1), JIT_R, 0, (reg1), 0)
|
||||||
|
#define jitfp_sti_d(imm, op1) _jit_emit(&_jit, (op1), JIT_I | 1, 0, (long)(imm), 0)
|
||||||
|
#define jitfp_str_d(reg1, op1) _jit_emit(&_jit, (op1), JIT_R | 1, 0, (reg1), 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
48
lightning/funcs-common.h
Normal file
48
lightning/funcs-common.h
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Platform-independent layer inline functions (common part)
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#ifndef __lightning_funcs_common_h
|
||||||
|
#define __lightning_funcs_common_h
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static int jit_fail(const char *, const char*, int, const char *) JIT_UNUSED;
|
||||||
|
|
||||||
|
int
|
||||||
|
jit_fail(const char *msg, const char *file, int line, const char *function)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: In function `%s':\n", file, function);
|
||||||
|
fprintf(stderr, "%s:%d: %s\n", file, line, msg);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __lightning_funcs_common_h */
|
1060
lightning/i386/asm.h
Normal file
1060
lightning/i386/asm.h
Normal file
File diff suppressed because it is too large
Load diff
408
lightning/i386/core.h
Normal file
408
lightning/i386/core.h
Normal file
|
@ -0,0 +1,408 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Platform-independent layer (i386 version)
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __lightning_core_h
|
||||||
|
#define __lightning_core_h
|
||||||
|
|
||||||
|
#define JIT_R0 _EAX
|
||||||
|
#define JIT_R1 _ECX
|
||||||
|
#define JIT_R2 _EDX
|
||||||
|
#define JIT_V0 _EBX
|
||||||
|
#define JIT_V1 _ESI
|
||||||
|
#define JIT_V2 _EDI
|
||||||
|
#define JIT_FP _EBP
|
||||||
|
#define JIT_SP _ESP
|
||||||
|
#define JIT_RET _EAX
|
||||||
|
|
||||||
|
struct jit_local_state {
|
||||||
|
int framesize;
|
||||||
|
int argssize;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 3-parameter operation */
|
||||||
|
#define jit_opr_(d, s1, s2, op1d, op2d) \
|
||||||
|
( (s2 == d) ? op1d : \
|
||||||
|
( ((s1 == d) ? (void)0 : (void)MOVLrr(s1, d)), op2d ) \
|
||||||
|
)
|
||||||
|
|
||||||
|
/* 3-parameter operation, with immediate */
|
||||||
|
#define jit_op_(d, s1, op2d) \
|
||||||
|
((s1 == d) ? op2d : (MOVLrr(s1, d), op2d)) \
|
||||||
|
|
||||||
|
/* 3-parameter operation, optimizable */
|
||||||
|
#define jit_opo_(d, s1, s2, op1d, op2d, op12d) \
|
||||||
|
((s2 == d) ? op2d : \
|
||||||
|
((s1 == d) ? op1d : op12d))
|
||||||
|
|
||||||
|
/* 3-parameter operation, optimizable, with immediate */
|
||||||
|
#define jit_opi_(d, rs, opdi, opdri) \
|
||||||
|
((rs == d) ? opdi : opdri)
|
||||||
|
|
||||||
|
/* An operand is forced into a register */
|
||||||
|
#define jit_replace(rd, rs, forced, op) \
|
||||||
|
((rd == forced) ? JITSORRY("Register conflict for " # op) : \
|
||||||
|
(rs == forced) ? op : (PUSHLr(forced), MOVLrr(rs, forced), op, POPLr(forced)))
|
||||||
|
|
||||||
|
/* For LT, LE, ... */
|
||||||
|
#define jit_replace8(d, op) \
|
||||||
|
(jit_check8(d) \
|
||||||
|
? (MOVLir(0, d), op(d)) \
|
||||||
|
: (PUSHLr(_EAX), MOVLir(0, _EAX), op(_EAX), MOVLrr(_EAX, (d)), POPLr(_EAX)))
|
||||||
|
|
||||||
|
#define jit_bool_r(d, s1, s2, op) \
|
||||||
|
(CMPLrr(s2, s1), jit_replace8(d, op))
|
||||||
|
|
||||||
|
#define jit_bool_i(d, rs, is, op) \
|
||||||
|
(CMPLir(is, rs), jit_replace8(d, op))
|
||||||
|
|
||||||
|
/* When CMP with 0 can be replaced with TEST */
|
||||||
|
#define jit_bool_i0(d, rs, is, op, op0) \
|
||||||
|
((is) != 0 \
|
||||||
|
? (CMPLir(is, rs), jit_replace8(d, op)) \
|
||||||
|
: (TESTLrr(rs, rs), jit_replace8(d, op0)))
|
||||||
|
|
||||||
|
/* For BLT, BLE, ... */
|
||||||
|
#define jit_bra_r(s1, s2, op) (CMPLrr(s2, s1), op, _jit.x.pc)
|
||||||
|
#define jit_bra_i(rs, is, op) (CMPLir(is, rs), op, _jit.x.pc)
|
||||||
|
|
||||||
|
/* When CMP with 0 can be replaced with TEST */
|
||||||
|
#define jit_bra_i0(rs, is, op, op0) \
|
||||||
|
( (is) == 0 ? (TESTLrr(rs, rs), op0, _jit.x.pc) : (CMPLir(is, rs), op, _jit.x.pc))
|
||||||
|
|
||||||
|
/* Used to implement ldc, stc, ... */
|
||||||
|
#define jit_check8(rs) ( (rs) <= _EBX )
|
||||||
|
#define jit_reg8(rs) ( ((rs) == _SI || (rs) == _DI) ? _AL : ((rs) & _BH) | _AL )
|
||||||
|
#define jit_reg16(rs) ( ((rs) & _BH) | _AX )
|
||||||
|
|
||||||
|
/* In jit_replace below, _EBX is dummy */
|
||||||
|
#define jit_movbrm(rs, dd, db, di, ds) \
|
||||||
|
(jit_check8(rs) \
|
||||||
|
? MOVBrm(jit_reg8(rs), dd, db, di, ds) \
|
||||||
|
: jit_replace(_EBX, rs, _EAX, MOVBrm(_AL, dd, db, di, ds)))
|
||||||
|
|
||||||
|
/* Reduce arguments of XOR/OR/TEST */
|
||||||
|
#define jit_reduce_(op) op
|
||||||
|
#define jit_reduce(op, is, rs) \
|
||||||
|
(_u8P(is) && jit_check8(rs) ? jit_reduce_(op##Bir(is, jit_reg8(rs))) : \
|
||||||
|
(_u16P(is) ? jit_reduce_(op##Wir(is, jit_reg16(rs))) : \
|
||||||
|
jit_reduce_(op##Lir(is, rs)) ))
|
||||||
|
|
||||||
|
/* Helper macros for MUL/DIV/IDIV */
|
||||||
|
#define jit_might(d, s1, op) \
|
||||||
|
((s1 == d) ? 0 : op)
|
||||||
|
|
||||||
|
#define jit_mulr_ui_(s1, s2) jit_opr_(_EAX, s1, s2, MULLr(s1), MULLr(s2))
|
||||||
|
#define jit_mulr_i_(s1, s2) jit_opr_(_EAX, s1, s2, IMULLr(s1), IMULLr(s2))
|
||||||
|
|
||||||
|
|
||||||
|
#define jit_muli_i_(is, rs) \
|
||||||
|
(MOVLir(is, rs == _EAX ? _EDX : _EAX), \
|
||||||
|
IMULLr(rs == _EAX ? _EDX : rs))
|
||||||
|
|
||||||
|
#define jit_muli_ui_(is, rs) \
|
||||||
|
(MOVLir(is, rs == _EAX ? _EDX : _EAX), \
|
||||||
|
IMULLr(rs == _EAX ? _EDX : rs))
|
||||||
|
|
||||||
|
#define jit_divi_i_(result, d, rs, is) \
|
||||||
|
(jit_might (d, _EAX, PUSHLr(_EAX)), \
|
||||||
|
jit_might (d, _ECX, PUSHLr(_ECX)), \
|
||||||
|
jit_might (d, _EDX, PUSHLr(_EDX)), \
|
||||||
|
jit_might (rs, _EAX, MOVLrr(rs, _EAX)), \
|
||||||
|
jit_might (rs, _EDX, MOVLrr(rs, _EDX)), \
|
||||||
|
MOVLir(is, _ECX), \
|
||||||
|
SARLir(31, _EDX), \
|
||||||
|
IDIVLr(_ECX), \
|
||||||
|
jit_might(d, result, MOVLrr(result, d)), \
|
||||||
|
jit_might(d, _EDX, POPLr(_EDX)), \
|
||||||
|
jit_might(d, _ECX, POPLr(_ECX)), \
|
||||||
|
jit_might(d, _EAX, POPLr(_EAX)))
|
||||||
|
|
||||||
|
#define jit_divr_i_(result, d, s1, s2) \
|
||||||
|
(jit_might (d, _EAX, PUSHLr(_EAX)), \
|
||||||
|
jit_might (d, _ECX, PUSHLr(_ECX)), \
|
||||||
|
jit_might (d, _EDX, PUSHLr(_EDX)), \
|
||||||
|
((s1 == _ECX) ? PUSHLr(_ECX) : 0), \
|
||||||
|
jit_might (s2, _ECX, MOVLrr(s2, _ECX)), \
|
||||||
|
((s1 == _ECX) ? POPLr(_EDX) : \
|
||||||
|
jit_might (s1, _EDX, MOVLrr(s1, _EDX))), \
|
||||||
|
MOVLrr(_EDX, _EAX), \
|
||||||
|
SARLir(31, _EDX), \
|
||||||
|
IDIVLr(_ECX), \
|
||||||
|
jit_might(d, result, MOVLrr(result, d)), \
|
||||||
|
jit_might(d, _EDX, POPLr(_EDX)), \
|
||||||
|
jit_might(d, _ECX, POPLr(_ECX)), \
|
||||||
|
jit_might(d, _EAX, POPLr(_EAX)))
|
||||||
|
|
||||||
|
#define jit_divi_ui_(result, d, rs, is) \
|
||||||
|
(jit_might (d, _EAX, PUSHLr(_EAX)), \
|
||||||
|
jit_might (d, _ECX, PUSHLr(_ECX)), \
|
||||||
|
jit_might (d, _EDX, PUSHLr(_EDX)), \
|
||||||
|
jit_might (rs, _EAX, MOVLrr(rs, _EAX)), \
|
||||||
|
MOVLir(is, _ECX), \
|
||||||
|
XORLrr(_EDX, _EDX), \
|
||||||
|
DIVLr(_ECX), \
|
||||||
|
jit_might(d, result, MOVLrr(result, d)), \
|
||||||
|
jit_might(d, _EDX, POPLr(_EDX)), \
|
||||||
|
jit_might(d, _ECX, POPLr(_ECX)), \
|
||||||
|
jit_might(d, _EAX, POPLr(_EAX)))
|
||||||
|
|
||||||
|
#define jit_divr_ui_(result, d, s1, s2) \
|
||||||
|
(jit_might (d, _EAX, PUSHLr(_EAX)), \
|
||||||
|
jit_might (d, _ECX, PUSHLr(_ECX)), \
|
||||||
|
jit_might (d, _EDX, PUSHLr(_EDX)), \
|
||||||
|
((s1 == _ECX) ? PUSHLr(_ECX) : 0), \
|
||||||
|
jit_might (s2, _ECX, MOVLrr(s2, _ECX)), \
|
||||||
|
((s1 == _ECX) ? POPLr(_EAX) : \
|
||||||
|
jit_might (s1, _EAX, MOVLrr(s1, _EAX))), \
|
||||||
|
XORLrr(_EDX, _EDX), \
|
||||||
|
DIVLr(_ECX), \
|
||||||
|
jit_might(d, result, MOVLrr(result, d)), \
|
||||||
|
jit_might(d, _EDX, POPLr(_EDX)), \
|
||||||
|
jit_might(d, _ECX, POPLr(_ECX)), \
|
||||||
|
jit_might(d, _EAX, POPLr(_EAX)))
|
||||||
|
|
||||||
|
|
||||||
|
/* ALU */
|
||||||
|
#define jit_addi_i(d, rs, is) jit_opi_((d), (rs), ADDLir((is), (d)), LEALmr((is), (rs), 0, 0, (d)) )
|
||||||
|
#define jit_addr_i(d, s1, s2) jit_opo_((d), (s1), (s2), ADDLrr((s2), (d)), ADDLrr((s1), (d)), LEALmr(0, (s1), (s2), 1, (d)) )
|
||||||
|
#define jit_addci_i(d, rs, is) jit_op_ ((d), (rs), ADDLir((is), (d)) )
|
||||||
|
#define jit_addcr_i(d, s1, s2) jit_opr_((d), (s1), (s2), ADDLrr((s1), (d)), ADDLrr((s2), (d)) )
|
||||||
|
#define jit_addxi_i(d, rs, is) jit_op_ ((d), (rs), ADCLir((is), (d)) )
|
||||||
|
#define jit_addxr_i(d, s1, s2) jit_opr_((d), (s1), (s2), ADCLrr((s1), (d)), ADCLrr((s2), (d)) )
|
||||||
|
#define jit_andi_i(d, rs, is) jit_op_ ((d), (rs), ANDLir((is), (d)) )
|
||||||
|
#define jit_andr_i(d, s1, s2) jit_opr_((d), (s1), (s2), ANDLrr((s1), (d)), ANDLrr((s2), (d)) )
|
||||||
|
#define jit_orr_i(d, s1, s2) jit_opr_((d), (s1), (s2), ORLrr((s1), (d)), ORLrr((s2), (d)) )
|
||||||
|
#define jit_subr_i(d, s1, s2) jit_opr_((d), (s1), (s2), (SUBLrr((s1), (d)), NEGLr(d)), SUBLrr((s2), (d)) )
|
||||||
|
#define jit_subcr_i(d, s1, s2) jit_subr_i((d), (s1), (s2))
|
||||||
|
#define jit_subxr_i(d, s1, s2) jit_opr_((d), (s1), (s2), SBBLrr((s1), (d)), SBBLrr((s2), (d)) )
|
||||||
|
#define jit_subxi_i(d, rs, is) jit_op_ ((d), (rs), SBBLir((is), (d)) )
|
||||||
|
#define jit_xorr_i(d, s1, s2) jit_opr_((d), (s1), (s2), XORLrr((s1), (d)), XORLrr((s2), (d)) )
|
||||||
|
|
||||||
|
/* These can sometimes use byte or word versions! */
|
||||||
|
#define jit_ori_i(d, rs, is) jit_op_ ((d), (rs), jit_reduce(OR, (is), (d)) )
|
||||||
|
#define jit_xori_i(d, rs, is) jit_op_ ((d), (rs), jit_reduce(XOR, (is), (d)) )
|
||||||
|
|
||||||
|
#define jit_muli_i(d, rs, is) jit_op_ ((d), (rs), IMULLir((is), (d)) )
|
||||||
|
#define jit_mulr_i(d, s1, s2) jit_opr_((d), (s1), (s2), IMULLrr((s1), (d)), IMULLrr((s2), (d)) )
|
||||||
|
|
||||||
|
/* As far as low bits are concerned, signed and unsigned multiplies are
|
||||||
|
exactly the same. */
|
||||||
|
#define jit_muli_ui(d, rs, is) jit_op_ ((d), (rs), IMULLir((is), (d)) )
|
||||||
|
#define jit_mulr_ui(d, s1, s2) jit_opr_((d), (s1), (s2), IMULLrr((s1), (d)), IMULLrr((s2), (d)) )
|
||||||
|
|
||||||
|
#define jit_hmuli_i(d, rs, is) \
|
||||||
|
((d) == _EDX ? ( PUSHLr(_EAX), jit_muli_i_((is), (rs)), POPLr(_EAX) ) : \
|
||||||
|
((d) == _EAX ? (PUSHLr(_EDX), jit_muli_i_((is), (rs)), MOVLrr(_EDX, _EAX), POPLr(_EDX) ) : \
|
||||||
|
(PUSHLr(_EDX), PUSHLr(_EAX), jit_muli_i_((is), (rs)), MOVLrr(_EDX, (d)), POPLr(_EAX), POPLr(_EDX) )))
|
||||||
|
|
||||||
|
#define jit_hmulr_i(d, s1, s2) \
|
||||||
|
((d) == _EDX ? ( PUSHLr(_EAX), jit_mulr_i_((s1), (s2)), POPLr(_EAX) ) : \
|
||||||
|
((d) == _EAX ? (PUSHLr(_EDX), jit_mulr_i_((s1), (s2)), MOVLrr(_EDX, _EAX), POPLr(_EDX) ) : \
|
||||||
|
(PUSHLr(_EDX), PUSHLr(_EAX), jit_mulr_i_((s1), (s2)), MOVLrr(_EDX, (d)), POPLr(_EAX), POPLr(_EDX) )))
|
||||||
|
|
||||||
|
#define jit_hmuli_ui(d, rs, is) \
|
||||||
|
((d) == _EDX ? ( PUSHLr(_EAX), jit_muli_ui_((is), (rs)), POPLr(_EAX) ) : \
|
||||||
|
((d) == _EAX ? (PUSHLr(_EDX), jit_muli_ui_((is), (rs)), MOVLrr(_EDX, _EAX), POPLr(_EDX) ) : \
|
||||||
|
(PUSHLr(_EDX), PUSHLr(_EAX), jit_muli_ui_((is), (rs)), MOVLrr(_EDX, (d)), POPLr(_EAX), POPLr(_EDX) )))
|
||||||
|
|
||||||
|
#define jit_hmulr_ui(d, s1, s2) \
|
||||||
|
((d) == _EDX ? ( PUSHLr(_EAX), jit_mulr_ui_((s1), (s2)), POPLr(_EAX) ) : \
|
||||||
|
((d) == _EAX ? (PUSHLr(_EDX), jit_mulr_ui_((s1), (s2)), MOVLrr(_EDX, _EAX), POPLr(_EDX) ) : \
|
||||||
|
(PUSHLr(_EDX), PUSHLr(_EAX), jit_mulr_ui_((s1), (s2)), MOVLrr(_EDX, (d)), POPLr(_EAX), POPLr(_EDX) )))
|
||||||
|
|
||||||
|
#define jit_divi_i(d, rs, is) jit_divi_i_(_EAX, (d), (rs), (is))
|
||||||
|
#define jit_divi_ui(d, rs, is) jit_divi_ui_(_EAX, (d), (rs), (is))
|
||||||
|
#define jit_modi_i(d, rs, is) jit_divi_i_(_EDX, (d), (rs), (is))
|
||||||
|
#define jit_modi_ui(d, rs, is) jit_divi_ui_(_EDX, (d), (rs), (is))
|
||||||
|
#define jit_divr_i(d, s1, s2) jit_divr_i_(_EAX, (d), (s1), (s2))
|
||||||
|
#define jit_divr_ui(d, s1, s2) jit_divr_ui_(_EAX, (d), (s1), (s2))
|
||||||
|
#define jit_modr_i(d, s1, s2) jit_divr_i_(_EDX, (d), (s1), (s2))
|
||||||
|
#define jit_modr_ui(d, s1, s2) jit_divr_ui_(_EDX, (d), (s1), (s2))
|
||||||
|
|
||||||
|
|
||||||
|
/* Shifts */
|
||||||
|
#define jit_lshi_i(d, rs, is) ((is) <= 3 ? LEALmr(0, 0, (rs), 1 << (is), (d)) : jit_op_ ((d), (rs), SHLLir((is), (d)) ))
|
||||||
|
#define jit_rshi_i(d, rs, is) jit_op_ ((d), (rs), SARLir((is), (d)) )
|
||||||
|
#define jit_rshi_ui(d, rs, is) jit_op_ ((d), (rs), SHRLir((is), (d)) )
|
||||||
|
#define jit_lshr_i(d, r1, r2) jit_replace((r1), (r2), _ECX, jit_op_ ((d), (r1), SHLLrr(_CL, (d)) ))
|
||||||
|
#define jit_rshr_i(d, r1, r2) jit_replace((r1), (r2), _ECX, jit_op_ ((d), (r1), SARLrr(_CL, (d)) ))
|
||||||
|
#define jit_rshr_ui(d, r1, r2) jit_replace((r1), (r2), _ECX, jit_op_ ((d), (r1), SHRLrr(_CL, (d)) ))
|
||||||
|
|
||||||
|
/* Stack */
|
||||||
|
#define jit_pushr_i(rs) PUSHLr(rs)
|
||||||
|
#define jit_popr_i(rs) POPLr(rs)
|
||||||
|
#define jit_prolog(n) (_jitl.framesize = 8, PUSHLr(_EBP), MOVLrr(_ESP, _EBP), PUSHLr(_EBX), PUSHLr(_ESI), PUSHLr(_EDI))
|
||||||
|
|
||||||
|
/* The += allows for stack pollution */
|
||||||
|
|
||||||
|
#define jitfp_prepare(ni,nf,nd) ((void) (_jitl.argssize += (ni) + (nf) + 2*(nd)))
|
||||||
|
#define jit_pusharg_i(rs) PUSHLr(rs)
|
||||||
|
#define jit_finish(sub) (jit_calli((sub)), ADDLir(4 * _jitl.argssize, JIT_SP), _jitl.argssize = 0)
|
||||||
|
#define jit_retval(rd) jit_movr_i ((rd), _EAX)
|
||||||
|
|
||||||
|
#define jit_arg_c() ((_jitl.framesize += sizeof(int)) - sizeof(int))
|
||||||
|
#define jit_arg_uc() ((_jitl.framesize += sizeof(int)) - sizeof(int))
|
||||||
|
#define jit_arg_s() ((_jitl.framesize += sizeof(int)) - sizeof(int))
|
||||||
|
#define jit_arg_us() ((_jitl.framesize += sizeof(int)) - sizeof(int))
|
||||||
|
#define jit_arg_i() ((_jitl.framesize += sizeof(int)) - sizeof(int))
|
||||||
|
#define jit_arg_ui() ((_jitl.framesize += sizeof(int)) - sizeof(int))
|
||||||
|
#define jit_arg_l() ((_jitl.framesize += sizeof(long)) - sizeof(long))
|
||||||
|
#define jit_arg_ul() ((_jitl.framesize += sizeof(long)) - sizeof(long))
|
||||||
|
#define jit_arg_p() ((_jitl.framesize += sizeof(long)) - sizeof(long))
|
||||||
|
|
||||||
|
#define jit_arg_f() ((_jitl.framesize += sizeof(float)) - sizeof(float))
|
||||||
|
#define jit_arg_d() ((_jitl.framesize += sizeof(double)) - sizeof(double))
|
||||||
|
|
||||||
|
/* Unary */
|
||||||
|
#define jit_negr_i(d, rs) jit_opi_((d), (rs), NEGLr(d), (XORLrr((d), (d)), SUBLrr((rs), (d))) )
|
||||||
|
#define jit_negr_l(d, rs) jit_opi_((d), (rs), NEGLr(d), (XORLrr((d), (d)), SUBLrr((rs), (d))) )
|
||||||
|
|
||||||
|
#define jit_movr_i(d, rs) ((rs) == (d) ? 0 : MOVLrr((rs), (d)))
|
||||||
|
#define jit_movi_i(d, is) ((is) ? MOVLir((is), (d)) : XORLrr ((d), (d)) )
|
||||||
|
|
||||||
|
#define jit_ntoh_ui(d, rs) jit_op_((d), (rs), BSWAPLr(d))
|
||||||
|
#define jit_ntoh_us(d, rs) jit_op_((d), (rs), RORWir(8, d))
|
||||||
|
|
||||||
|
/* Boolean */
|
||||||
|
#define jit_ltr_i(d, s1, s2) jit_bool_r((d), (s1), (s2), SETLr )
|
||||||
|
#define jit_ler_i(d, s1, s2) jit_bool_r((d), (s1), (s2), SETLEr )
|
||||||
|
#define jit_gtr_i(d, s1, s2) jit_bool_r((d), (s1), (s2), SETGr )
|
||||||
|
#define jit_ger_i(d, s1, s2) jit_bool_r((d), (s1), (s2), SETGEr )
|
||||||
|
#define jit_eqr_i(d, s1, s2) jit_bool_r((d), (s1), (s2), SETEr )
|
||||||
|
#define jit_ner_i(d, s1, s2) jit_bool_r((d), (s1), (s2), SETNEr )
|
||||||
|
#define jit_ltr_ui(d, s1, s2) jit_bool_r((d), (s1), (s2), SETBr )
|
||||||
|
#define jit_ler_ui(d, s1, s2) jit_bool_r((d), (s1), (s2), SETBEr )
|
||||||
|
#define jit_gtr_ui(d, s1, s2) jit_bool_r((d), (s1), (s2), SETAr )
|
||||||
|
#define jit_ger_ui(d, s1, s2) jit_bool_r((d), (s1), (s2), SETAEr )
|
||||||
|
|
||||||
|
#define jit_lti_i(d, rs, is) jit_bool_i0((d), (rs), (is), SETLr, SETSr )
|
||||||
|
#define jit_lei_i(d, rs, is) jit_bool_i ((d), (rs), (is), SETLEr )
|
||||||
|
#define jit_gti_i(d, rs, is) jit_bool_i ((d), (rs), (is), SETGr )
|
||||||
|
#define jit_gei_i(d, rs, is) jit_bool_i0((d), (rs), (is), SETGEr, SETNSr )
|
||||||
|
#define jit_eqi_i(d, rs, is) jit_bool_i0((d), (rs), (is), SETEr, SETEr )
|
||||||
|
#define jit_nei_i(d, rs, is) jit_bool_i0((d), (rs), (is), SETNEr, SETNEr )
|
||||||
|
#define jit_lti_ui(d, rs, is) jit_bool_i ((d), (rs), (is), SETB )
|
||||||
|
#define jit_lei_ui(d, rs, is) jit_bool_i0((d), (rs), (is), SETBEr, SETEr )
|
||||||
|
#define jit_gti_ui(d, rs, is) jit_bool_i0((d), (rs), (is), SETAr, SETNEr )
|
||||||
|
#define jit_gei_ui(d, rs, is) jit_bool_i0((d), (rs), (is), SETAEr, INCLr )
|
||||||
|
|
||||||
|
/* Jump */
|
||||||
|
#define jit_bltr_i(label, s1, s2) jit_bra_r((s1), (s2), JLm(label, 0,0,0) )
|
||||||
|
#define jit_bler_i(label, s1, s2) jit_bra_r((s1), (s2), JLEm(label,0,0,0) )
|
||||||
|
#define jit_bgtr_i(label, s1, s2) jit_bra_r((s1), (s2), JGm(label, 0,0,0) )
|
||||||
|
#define jit_bger_i(label, s1, s2) jit_bra_r((s1), (s2), JGEm(label,0,0,0) )
|
||||||
|
#define jit_beqr_i(label, s1, s2) jit_bra_r((s1), (s2), JEm(label, 0,0,0) )
|
||||||
|
#define jit_bner_i(label, s1, s2) jit_bra_r((s1), (s2), JNEm(label,0,0,0) )
|
||||||
|
#define jit_bltr_ui(label, s1, s2) jit_bra_r((s1), (s2), JBm(label, 0,0,0) )
|
||||||
|
#define jit_bler_ui(label, s1, s2) jit_bra_r((s1), (s2), JBEm(label,0,0,0) )
|
||||||
|
#define jit_bgtr_ui(label, s1, s2) jit_bra_r((s1), (s2), JAm(label, 0,0,0) )
|
||||||
|
#define jit_bger_ui(label, s1, s2) jit_bra_r((s1), (s2), JAEm(label,0,0,0) )
|
||||||
|
#define jit_bmsr_i(label, s1, s2) (TESTLrr((s1), (s2)), JNZm(label,0,0,0), _jit.x.pc)
|
||||||
|
#define jit_bmcr_i(label, s1, s2) (TESTLrr((s1), (s2)), JZm(label,0,0,0), _jit.x.pc)
|
||||||
|
#define jit_boaddr_i(label, s1, s2) (ADDLrr((s2), (s1)), JOm(label,0,0,0), _jit.x.pc)
|
||||||
|
#define jit_bosubr_i(label, s1, s2) (SUBLrr((s2), (s1)), JOm(label,0,0,0), _jit.x.pc)
|
||||||
|
#define jit_boaddr_ui(label, s1, s2) (ADDLrr((s2), (s1)), JCm(label,0,0,0), _jit.x.pc)
|
||||||
|
#define jit_bosubr_ui(label, s1, s2) (SUBLrr((s2), (s1)), JCm(label,0,0,0), _jit.x.pc)
|
||||||
|
|
||||||
|
#define jit_blti_i(label, rs, is) jit_bra_i0((rs), (is), JLm(label, 0,0,0), JSm(label, 0,0,0) )
|
||||||
|
#define jit_blei_i(label, rs, is) jit_bra_i ((rs), (is), JLEm(label,0,0,0) )
|
||||||
|
#define jit_bgti_i(label, rs, is) jit_bra_i ((rs), (is), JGm(label, 0,0,0) )
|
||||||
|
#define jit_bgei_i(label, rs, is) jit_bra_i0((rs), (is), JGEm(label,0,0,0), JNSm(label,0,0,0) )
|
||||||
|
#define jit_beqi_i(label, rs, is) jit_bra_i0((rs), (is), JEm(label, 0,0,0), JEm(label, 0,0,0) )
|
||||||
|
#define jit_bnei_i(label, rs, is) jit_bra_i0((rs), (is), JNEm(label,0,0,0), JNEm(label,0,0,0) )
|
||||||
|
#define jit_blti_ui(label, rs, is) jit_bra_i ((rs), (is), JLm(label, 0,0,0) )
|
||||||
|
#define jit_blei_ui(label, rs, is) jit_bra_i0((rs), (is), JLEm(label,0,0,0), JEm(label, 0,0,0) )
|
||||||
|
#define jit_bgti_ui(label, rs, is) jit_bra_i0((rs), (is), JGm(label, 0,0,0), JNEm(label,0,0,0) )
|
||||||
|
#define jit_bgei_ui(label, rs, is) jit_bra_i ((rs), (is), JGEm(label,0,0,0) )
|
||||||
|
#define jit_boaddi_i(label, rs, is) (ADDLir((is), (rs)), JOm(label,0,0,0), _jit.x.pc)
|
||||||
|
#define jit_bosubi_i(label, rs, is) (SUBLir((is), (rs)), JOm(label,0,0,0), _jit.x.pc)
|
||||||
|
#define jit_boaddi_ui(label, rs, is) (ADDLir((is), (rs)), JCm(label,0,0,0), _jit.x.pc)
|
||||||
|
#define jit_bosubi_ui(label, rs, is) (SUBLir((is), (rs)), JCm(label,0,0,0), _jit.x.pc)
|
||||||
|
|
||||||
|
#define jit_bmsi_i(label, rs, is) (jit_reduce(TEST, (is), (rs)), JNZm(label,0,0,0), _jit.x.pc)
|
||||||
|
#define jit_bmci_i(label, rs, is) (jit_reduce(TEST, (is), (rs)), JZm(label,0,0,0), _jit.x.pc)
|
||||||
|
|
||||||
|
#define jit_jmpi(label) (JMPm( ((unsigned long) (label)), 0, 0, 0), _jit.x.pc)
|
||||||
|
#define jit_calli(label) (CALLm( ((unsigned long) (label)), 0, 0, 0), _jit.x.pc)
|
||||||
|
#define jit_jmpr(reg) JMPsr(reg)
|
||||||
|
#define jit_patch(jump_pc) (*_PSL((jump_pc) - 4) = _jit_SL(_jit.x.pc - (jump_pc)))
|
||||||
|
#define jit_ret() (POPLr(_EDI), POPLr(_ESI), POPLr(_EBX), POPLr(_EBP), RET())
|
||||||
|
|
||||||
|
/* Memory */
|
||||||
|
#define jit_ldi_c(d, is) MOVSBLmr((is), 0, 0, 0, (d))
|
||||||
|
#define jit_ldr_c(d, rs) MOVSBLmr(0, (rs), 0, 0, (d))
|
||||||
|
#define jit_ldxr_c(d, s1, s2) MOVSBLmr(0, (s1), (s2), 1, (d))
|
||||||
|
#define jit_ldxi_c(d, rs, is) MOVSBLmr((is), (rs), 0, 0, (d))
|
||||||
|
|
||||||
|
#define jit_ldi_uc(d, is) MOVZBLmr((is), 0, 0, 0, (d))
|
||||||
|
#define jit_ldr_uc(d, rs) MOVZBLmr(0, (rs), 0, 0, (d))
|
||||||
|
#define jit_ldxr_uc(d, s1, s2) MOVZBLmr(0, (s1), (s2), 1, (d))
|
||||||
|
#define jit_ldxi_uc(d, rs, is) MOVZBLmr((is), (rs), 0, 0, (d))
|
||||||
|
|
||||||
|
#define jit_sti_c(id, rs) jit_movbrm((rs), (id), 0, 0, 0)
|
||||||
|
#define jit_str_c(rd, rs) jit_movbrm((rs), 0, (rd), 0, 0)
|
||||||
|
#define jit_stxr_c(d1, d2, rs) jit_movbrm((rs), 0, (d1), (d2), 1)
|
||||||
|
#define jit_stxi_c(id, rd, rs) jit_movbrm((rs), (id), (rd), 0, 0)
|
||||||
|
|
||||||
|
#define jit_ldi_s(d, is) MOVSWLmr((is), 0, 0, 0, (d))
|
||||||
|
#define jit_ldr_s(d, rs) MOVSWLmr(0, (rs), 0, 0, (d))
|
||||||
|
#define jit_ldxr_s(d, s1, s2) MOVSWLmr(0, (s1), (s2), 1, (d))
|
||||||
|
#define jit_ldxi_s(d, rs, is) MOVSWLmr((is), (rs), 0, 0, (d))
|
||||||
|
|
||||||
|
#define jit_ldi_us(d, is) MOVZWLmr((is), 0, 0, 0, (d))
|
||||||
|
#define jit_ldr_us(d, rs) MOVZWLmr(0, (rs), 0, 0, (d))
|
||||||
|
#define jit_ldxr_us(d, s1, s2) MOVZWLmr(0, (s1), (s2), 1, (d))
|
||||||
|
#define jit_ldxi_us(d, rs, is) MOVZWLmr((is), (rs), 0, 0, (d))
|
||||||
|
|
||||||
|
#define jit_sti_s(id, rs) MOVWrm(jit_reg16(rs), (id), 0, 0, 0)
|
||||||
|
#define jit_str_s(rd, rs) MOVWrm(jit_reg16(rs), 0, (rd), 0, 0)
|
||||||
|
#define jit_stxr_s(d1, d2, rs) MOVWrm(jit_reg16(rs), 0, (d1), (d2), 1)
|
||||||
|
#define jit_stxi_s(id, rd, rs) MOVWrm(jit_reg16(rs), (id), (rd), 0, 0)
|
||||||
|
|
||||||
|
#define jit_ldi_i(d, is) MOVLmr((is), 0, 0, 0, (d))
|
||||||
|
#define jit_ldr_i(d, rs) MOVLmr(0, (rs), 0, 0, (d))
|
||||||
|
#define jit_ldxr_i(d, s1, s2) MOVLmr(0, (s1), (s2), 1, (d))
|
||||||
|
#define jit_ldxi_i(d, rs, is) MOVLmr((is), (rs), 0, 0, (d))
|
||||||
|
|
||||||
|
#define jit_sti_i(id, rs) MOVLrm((rs), (id), 0, 0, 0)
|
||||||
|
#define jit_str_i(rd, rs) MOVLrm((rs), 0, (rd), 0, 0)
|
||||||
|
#define jit_stxr_i(d1, d2, rs) MOVLrm((rs), 0, (d1), (d2), 1)
|
||||||
|
#define jit_stxi_i(id, rd, rs) MOVLrm((rs), (id), (rd), 0, 0)
|
||||||
|
|
||||||
|
/* Extra */
|
||||||
|
#define jit_nop() NOP()
|
||||||
|
|
||||||
|
#define _jit_alignment(pc, n) (((pc ^ _MASK(4)) + 1) & _MASK(n))
|
||||||
|
#define jit_align(n) _NOPi(_jit_alignment(_jit_UL(_jit.x.pc), (n)))
|
||||||
|
|
||||||
|
#endif /* __lightning_core_h */
|
252
lightning/i386/fp.h
Normal file
252
lightning/i386/fp.h
Normal file
|
@ -0,0 +1,252 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Run-time assembler & support macros for the i386 math coprocessor
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __lightning_asm_fp_h
|
||||||
|
#define __lightning_asm_fp_h
|
||||||
|
|
||||||
|
/* Actually, we should redesign the jitfp interface. As a first step, I have
|
||||||
|
defined the macros for many x87 instructions, and I am using them here.
|
||||||
|
|
||||||
|
In practice, we can provide something sensible and make it work on the x86
|
||||||
|
using the stack like a file of eight registers. Then this awful stuff goes
|
||||||
|
away, and everything is "beautiful" as the rest of GNU lightning---and we'll
|
||||||
|
document it, promised.
|
||||||
|
|
||||||
|
Well, let's use six or seven registers so as to have some freedom
|
||||||
|
for floor, ceil, round, log, tan, atn and exp.
|
||||||
|
|
||||||
|
Not hard at all, basically play with FXCH. FXCH is mostly free,
|
||||||
|
so the generated code is not bad. Of course we special case when one
|
||||||
|
of the operands turns out to be ST0.
|
||||||
|
|
||||||
|
- binary ops:
|
||||||
|
|
||||||
|
add FRR3 to FPR0
|
||||||
|
FADD ST0,ST3
|
||||||
|
|
||||||
|
add FPR0 to FPR3
|
||||||
|
FADD ST3,ST0
|
||||||
|
|
||||||
|
add FPR3 to FPR7 (I'm using nasm syntax here)
|
||||||
|
FXCH ST3
|
||||||
|
FADD ST7,ST0
|
||||||
|
FXCH ST3
|
||||||
|
|
||||||
|
- stores:
|
||||||
|
|
||||||
|
store FPR3
|
||||||
|
|
||||||
|
FXCH ST3
|
||||||
|
FST [FUBAR]
|
||||||
|
FXCH ST3
|
||||||
|
|
||||||
|
store FPR0
|
||||||
|
|
||||||
|
FST [FUBAR]
|
||||||
|
|
||||||
|
(and similarly for other unary ops like FCHS or FABS)
|
||||||
|
|
||||||
|
- moves:
|
||||||
|
|
||||||
|
move FPR0 to FPR3
|
||||||
|
FST ST3
|
||||||
|
|
||||||
|
move FPR3 to FPR0
|
||||||
|
FXCH ST3
|
||||||
|
FST ST3
|
||||||
|
|
||||||
|
move FPR3 to FPR1
|
||||||
|
FSTP ST1 Save old st0 into destination register
|
||||||
|
FLD ST2 Stack is rotated, so FPRn becomes STn-1
|
||||||
|
FXCH ST1 Get back old st0
|
||||||
|
|
||||||
|
- loads:
|
||||||
|
|
||||||
|
load into FPR0
|
||||||
|
FSTP ST0
|
||||||
|
FLD [FUBAR]
|
||||||
|
|
||||||
|
load into FPR3
|
||||||
|
FSTP ST3 Save old st0 into destination register
|
||||||
|
FLD [FUBAR]
|
||||||
|
FXCH ST3 Get back old st0
|
||||||
|
|
||||||
|
(and similarly for immediates, using the stack) */
|
||||||
|
|
||||||
|
#define jit_add_two(reg0) FADDPr(1)
|
||||||
|
#define jit_sub_two(reg0) FSUBRPr(1)
|
||||||
|
#define jit_mul_two(reg0) FMULPr(1)
|
||||||
|
#define jit_div_two(reg0) FDIVRPr(1)
|
||||||
|
|
||||||
|
#define jit_abs(reg0) _OO(0xd9e1) /* fabs */
|
||||||
|
#define jit_sqr(reg0) FMULrr(0,0)
|
||||||
|
#define jit_sqrt(reg0) _OO(0xd9fa) /* fsqrt */
|
||||||
|
|
||||||
|
#define jit_exti_d(reg0, rs) (PUSHLr((rs)), FILDLm(0, _ESP, 0, 0), POPLr((rs)))
|
||||||
|
|
||||||
|
#define jit_neg(reg0) _OO(0xd9e0) /* fchs */
|
||||||
|
|
||||||
|
#define jit_ldxr_f(reg0, s1, s2) FLDSm(0, (s1), (s2), 1)
|
||||||
|
#define jit_ldxi_f(reg0, rs, is) FLDSm((is), (rs), 0, 0)
|
||||||
|
#define jit_ldxr_f(reg0, s1, s2) FLDSm(0, (s1), (s2), 1)
|
||||||
|
#define jit_ldxi_d(reg0, rs, is) FLDLm((is), (rs), 0, 0)
|
||||||
|
#define jit_ldxr_d(reg0, s1, s2) FLDLm(0, (s1), (s2), 1)
|
||||||
|
#define jit_ldi_f(reg0, is) FLDSm((is), 0, 0, 0)
|
||||||
|
#define jit_ldr_f(reg0, rs) FLDSm(0, (rs), 0, 0)
|
||||||
|
#define jit_ldi_d(reg0, is) FLDLm((is), 0, 0, 0)
|
||||||
|
#define jit_ldr_d(reg0, rs) FLDLm(0, (rs), 0, 0)
|
||||||
|
#define jit_stxi_f(id, rd, reg0) FSTPSm((id), (rd), 0, 0)
|
||||||
|
#define jit_stxr_f(d1, d2, reg0) FSTPSm(0, (d1), (d2), 1)
|
||||||
|
#define jit_stxi_d(id, rd, reg0) FSTPLm((id), (rd), 0, 0)
|
||||||
|
#define jit_stxr_d(d1, d2, reg0) FSTPLm(0, (d1), (d2), 1)
|
||||||
|
#define jit_sti_f(id, reg0) FSTPSm((id), 0, 0, 0)
|
||||||
|
#define jit_str_f(rd, reg0) FSTPSm(0, (rd), 0, 0)
|
||||||
|
#define jit_sti_d(id, reg0) FSTPLm((id), 0, 0, 0)
|
||||||
|
#define jit_str_d(rd, reg0) FSTPLm(0, (rd), 0, 0)
|
||||||
|
|
||||||
|
#define jit_fpimm(reg0, first, second) \
|
||||||
|
(PUSHLi(second), \
|
||||||
|
PUSHLi(first), \
|
||||||
|
FLDLm(0, _ESP, 0, 0), \
|
||||||
|
ADDLir(8, _ESP))
|
||||||
|
|
||||||
|
|
||||||
|
/* Assume round to near mode */
|
||||||
|
#define jit_floor(rd, reg0) \
|
||||||
|
jit_floor2((rd), ((rd) == _EDX ? _EAX : _EDX))
|
||||||
|
|
||||||
|
#define jit_ceil(rd, reg0) \
|
||||||
|
jit_ceil2((rd), ((rd) == _EDX ? _EAX : _EDX))
|
||||||
|
|
||||||
|
#define jit_trunc(rd, reg0) \
|
||||||
|
jit_trunc2((rd), ((rd) == _EDX ? _EAX : _EDX))
|
||||||
|
|
||||||
|
#define jit_calc_diff(ofs) \
|
||||||
|
FISTLm(ofs, _ESP, 0, 0), \
|
||||||
|
FILDLm(ofs, _ESP, 0, 0), \
|
||||||
|
FSUBRPr(1), \
|
||||||
|
FSTPSm(4+ofs, _ESP, 0, 0) \
|
||||||
|
|
||||||
|
/* The real meat */
|
||||||
|
#define jit_floor2(rd, aux) \
|
||||||
|
(PUSHLr(aux), \
|
||||||
|
SUBLir(8, _ESP), \
|
||||||
|
jit_calc_diff(0), \
|
||||||
|
POPLr(rd), /* floor in rd */ \
|
||||||
|
POPLr(aux), /* x-round(x) in aux */ \
|
||||||
|
ADDLir(0x7FFFFFFF, aux), /* carry if x-round(x) < -0 */ \
|
||||||
|
SBBLir(0, rd), /* subtract 1 if carry */ \
|
||||||
|
POPLr(aux))
|
||||||
|
|
||||||
|
#define jit_ceil2(rd, aux) \
|
||||||
|
(PUSHLr(aux), \
|
||||||
|
SUBLir(8, _ESP), \
|
||||||
|
jit_calc_diff(0), \
|
||||||
|
POPLr(rd), /* floor in rd */ \
|
||||||
|
POPLr(aux), /* x-round(x) in aux */ \
|
||||||
|
TESTLrr(aux, aux), \
|
||||||
|
SETGr(jit_reg8(aux)), \
|
||||||
|
SHRLir(1, aux), \
|
||||||
|
ADCLir(0, rd), \
|
||||||
|
POPLr(aux))
|
||||||
|
|
||||||
|
/* a mingling of the two above */
|
||||||
|
#define jit_trunc2(rd, aux) \
|
||||||
|
(PUSHLr(aux), \
|
||||||
|
SUBLir(12, _ESP), \
|
||||||
|
FSTSm(0, _ESP, 0, 0), \
|
||||||
|
jit_calc_diff(4), \
|
||||||
|
POPLr(aux), \
|
||||||
|
POPLr(rd), \
|
||||||
|
TESTLrr(aux, aux), \
|
||||||
|
POPLr(aux), \
|
||||||
|
JSSm(_jit.x.pc + 11, 0, 0, 0), \
|
||||||
|
ADDLir(0x7FFFFFFF, aux), /* 6 */ \
|
||||||
|
SBBLir(0, rd), /* 3 */ \
|
||||||
|
JMPSm(_jit.x.pc + 10, 0, 0, 0), /* 2 */ \
|
||||||
|
TESTLrr(aux, aux), /* 2 */ \
|
||||||
|
SETGr(jit_reg8(aux)), /* 3 */ \
|
||||||
|
SHRLir(1, aux), /* 2 */ \
|
||||||
|
ADCLir(0, rd), /* 3 */ \
|
||||||
|
POPLr(aux))
|
||||||
|
|
||||||
|
/* the easy one */
|
||||||
|
#define jit_round(rd, reg0) \
|
||||||
|
(PUSHLr(_EAX), \
|
||||||
|
FISTPLm(0, _ESP, 0, 0), \
|
||||||
|
POPLr((rd)))
|
||||||
|
|
||||||
|
#define jit_cmp(le, ge, reg0) ( \
|
||||||
|
((le) == _EAX || (ge) == _EAX ? 0 : PUSHLr(_EAX)), \
|
||||||
|
FCOMr(0), \
|
||||||
|
FNSTSWr(_AX), \
|
||||||
|
TESTBir(0x40, _AH), \
|
||||||
|
MOVLir(0, (le)), \
|
||||||
|
MOVLrr((le), (ge)), \
|
||||||
|
JZSm(_jit.x.pc + 11, 0, 0, 0), \
|
||||||
|
_OO(0xd9e4), /* ftst */ /* 2 */ \
|
||||||
|
FNSTSWr(_AX), /* 2 */ \
|
||||||
|
SAHF(), /* 1 */ \
|
||||||
|
SETLEr( ((le) & 15) | 0x10), /* 3 */ \
|
||||||
|
SETGEr( ((ge) & 15) | 0x10), /* 3 */ \
|
||||||
|
((le) == _EAX || (ge) == _EAX ? ANDLir (1, _EAX) : POPLr(_EAX)) )
|
||||||
|
|
||||||
|
#define jitfp_getarg_f(ofs) jitfp_ldxi_f(JIT_FP,(ofs))
|
||||||
|
#define jitfp_getarg_d(ofs) jitfp_ldxi_d(JIT_FP,(ofs))
|
||||||
|
#define jitfp_pusharg_d(op1) (jit_subi_i(JIT_SP,JIT_SP,sizeof(double)), jitfp_str_d(JIT_SP,(op1)))
|
||||||
|
#define jitfp_pusharg_f(op1) (jit_subi_i(JIT_SP,JIT_SP,sizeof(float)), jitfp_str_f(JIT_SP,(op1)))
|
||||||
|
#define jitfp_retval(op1) _jit_emit(&_jit, (op1), JIT_NULL, 0, 0, 0)
|
||||||
|
|
||||||
|
#define JIT_TRANSCENDENTAL
|
||||||
|
|
||||||
|
#define jit_sin(reg0) _OO(0xd9fe) /* fsin */
|
||||||
|
#define jit_cos(reg0) _OO(0xd9ff) /* fcos */
|
||||||
|
#define jit_tan(reg0) (_OO(0xd9f2), /* fptan */ \
|
||||||
|
FSTPr(0)) /* fstp st */
|
||||||
|
#define jit_atn(reg0) (_OO(0xd9e8), /* fld1 */ \
|
||||||
|
_OO(0xd9f3)) /* fpatan */
|
||||||
|
#define jit_exp(reg0) (_OO(0xd9ea), /* fldl2e */ \
|
||||||
|
FMULPr(1), /* fmulp */ \
|
||||||
|
_OO(0xd9c0), /* fld st */ \
|
||||||
|
_OO(0xd9fc), /* frndint */ \
|
||||||
|
_OO(0xdce9), /* fsubr */ \
|
||||||
|
FXCHr(1), /* fxch st(1) */ \
|
||||||
|
_OO(0xd9f0), /* f2xm1 */ \
|
||||||
|
_OO(0xd9e8), /* fld1 */ \
|
||||||
|
_OO(0xdec1), /* faddp */ \
|
||||||
|
_OO(0xd9fd), /* fscale */ \
|
||||||
|
FSTPr(1)) /* fstp st(1) */
|
||||||
|
#define jit_log(reg0) (_OO(0xd9ed), /* fldln2 */ \
|
||||||
|
FXCHr(1), /* fxch st(1) */ \
|
||||||
|
_OO(0xd9f1)) /* fyl2x */
|
||||||
|
|
||||||
|
#endif /* __lightning_asm_h */
|
39
lightning/i386/funcs.h
Normal file
39
lightning/i386/funcs.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Platform-independent layer inline functions (i386)
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __lightning_funcs_h
|
||||||
|
#define __lightning_funcs_h
|
||||||
|
|
||||||
|
#define jit_flush_code(dest, end)
|
||||||
|
|
||||||
|
#endif /* __lightning_funcs_h */
|
597
lightning/ppc/asm.h
Normal file
597
lightning/ppc/asm.h
Normal file
|
@ -0,0 +1,597 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Run-time assembler for the PowerPC
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 1999, 2000, 2001, 2002 Ian Piumarta
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#ifndef __lightning_asm_h
|
||||||
|
#define __lightning_asm_h
|
||||||
|
|
||||||
|
/* <imm> = [0-9]+ | (.+) -> add i, one parameter (imm)
|
||||||
|
* <reg> = r<imm> -> add r, one parameter (imm)
|
||||||
|
* <mem> = <imm>(<reg>) -> add m, two parameters (imm,reg)
|
||||||
|
* <idx> = <reg>(<reg>) -> add x, two parameters (reg,reg)
|
||||||
|
*
|
||||||
|
* `x' operands have two forms. For example `stwu source, rega(regb)'
|
||||||
|
* could be written as either
|
||||||
|
* STWUrx(source, rega, regb)
|
||||||
|
* or
|
||||||
|
* STWUXrrr(source, rega, regb)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*** a brief NOTE about halfwords and "shifted" operands
|
||||||
|
*
|
||||||
|
* LOGICAL insns require UNSIGNED args in 0..65535, whether or not shifted
|
||||||
|
*
|
||||||
|
* ARITHMETIC insns require SIGNED args in -32768..32767, even when shifted
|
||||||
|
*
|
||||||
|
* as a special case: "lis/addis" also accepts UNSIGNED arguments in
|
||||||
|
* 0..65535 since it is often used immediately before "ori" to load a 32-bit
|
||||||
|
* constant (this is consistent with the GNU rs/6000 and PowerPC assemblers)
|
||||||
|
*
|
||||||
|
* thus: lis rD, expression@hi
|
||||||
|
* ori rD, rD, expression@lo ; load 32-bit constant
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef unsigned int jit_insn;
|
||||||
|
|
||||||
|
#define _cr0 0
|
||||||
|
#define _cr1 1
|
||||||
|
#define _cr2 2
|
||||||
|
#define _cr3 3
|
||||||
|
#define _cr4 4
|
||||||
|
#define _cr5 5
|
||||||
|
#define _cr6 6
|
||||||
|
#define _cr7 7
|
||||||
|
|
||||||
|
#define _lt 0
|
||||||
|
#define _gt 1
|
||||||
|
#define _eq 2
|
||||||
|
#define _so 3
|
||||||
|
#define _un 3
|
||||||
|
|
||||||
|
#define _d16(D) (_ck_d(16,(_jit_UL(D)-_jit_UL(_jit.x.pc))) & ~3)
|
||||||
|
#define _d26(D) (_ck_d(26,(_jit_UL(D)-_jit_UL(_jit.x.pc))) & ~3)
|
||||||
|
|
||||||
|
/* primitive instruction forms [1, Section A.4] */
|
||||||
|
|
||||||
|
#define _FB( OP, BD,AA,LK ) _jit_I((_u6(OP)<<26)| _d26(BD)| (_u1(AA)<<1)|_u1(LK))
|
||||||
|
#define _FBA( OP, BD,AA,LK ) _jit_I((_u6(OP)<<26)| (_u26(BD)&~3)| (_u1(AA)<<1)|_u1(LK))
|
||||||
|
#define _BB( OP,BO,BI, BD,AA,LK ) _jit_I((_u6(OP)<<26)|(_u5(BO)<<21)|(_u5(BI)<<16)| _d16(BD)| (_u1(AA)<<1)|_u1(LK))
|
||||||
|
#define _D( OP,RD,RA, DD ) _jit_I((_u6(OP)<<26)|(_u5(RD)<<21)|(_u5(RA)<<16)| _s16(DD) )
|
||||||
|
#define _Du( OP,RD,RA, DD ) _jit_I((_u6(OP)<<26)|(_u5(RD)<<21)|(_u5(RA)<<16)| _u16(DD) )
|
||||||
|
#define _Ds( OP,RD,RA, DD ) _jit_I((_u6(OP)<<26)|(_u5(RD)<<21)|(_u5(RA)<<16)| _su16(DD) )
|
||||||
|
#define _X( OP,RD,RA,RB, XO,RC ) _jit_I((_u6(OP)<<26)|(_u5(RD)<<21)|(_u5(RA)<<16)|( _u5(RB)<<11)| (_u10(XO)<<1)|_u1(RC))
|
||||||
|
#define _XL( OP,BO,BI, XO,LK ) _jit_I((_u6(OP)<<26)|(_u5(BO)<<21)|(_u5(BI)<<16)|( _u5(00)<<11)| (_u10(XO)<<1)|_u1(LK))
|
||||||
|
#define _XFX( OP,RD, SR,XO ) _jit_I((_u6(OP)<<26)|(_u5(RD)<<21)| (_u10(SR)<<11)| (_u10(XO)<<1)|_u1(00))
|
||||||
|
#define _XO( OP,RD,RA,RB,OE,XO,RC ) _jit_I((_u6(OP)<<26)|(_u5(RD)<<21)|(_u5(RA)<<16)|( _u5(RB)<<11)|(_u1(OE)<<10)|( _u9(XO)<<1)|_u1(RC))
|
||||||
|
#define _M( OP,RS,RA,SH,MB,ME,RC ) _jit_I((_u6(OP)<<26)|(_u5(RS)<<21)|(_u5(RA)<<16)|( _u5(SH)<<11)|(_u5(MB)<< 6)|( _u5(ME)<<1)|_u1(RC))
|
||||||
|
|
||||||
|
/* special purpose registers (form XFX) [1, Section 8.2, page 8-138] */
|
||||||
|
|
||||||
|
#define SPR_LR ((8<<5)|(0))
|
||||||
|
|
||||||
|
/* +++ intrinsic instructions */
|
||||||
|
|
||||||
|
#define ADDrrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 266, 0)
|
||||||
|
#define ADD_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 266, 1)
|
||||||
|
#define ADDCrrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 10, 0)
|
||||||
|
#define ADDC_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 10, 1)
|
||||||
|
#define ADDErrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 138, 0)
|
||||||
|
#define ADDE_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 138, 1)
|
||||||
|
#define ADDOrrr(RD, RA, RB) _XO (31, RD, RA, RB, 1, 266, 0)
|
||||||
|
#define ADDO_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 1, 266, 1)
|
||||||
|
#define ADDIrri(RD, RA, IMM) _D (14, RD, RA, IMM)
|
||||||
|
#define ADDICrri(RD, RA, IMM) _D (12, RD, RA, IMM)
|
||||||
|
#define ADDIC_rri(RD, RA, IMM) _D (13, RD, RA, IMM)
|
||||||
|
#define ADDISrri(RD, RA, IMM) _Ds (15, RD, RA, IMM)
|
||||||
|
|
||||||
|
#define ANDrrr(RA, RS, RB) _X (31, RS, RA, RB, 28, 0)
|
||||||
|
#define AND_rrr(RA, RS, RB) _X (31, RS, RA, RB, 28, 1)
|
||||||
|
#define ANDCrrr(RA, RS, RB) _X (31, RS, RA, RB, 60, 0)
|
||||||
|
#define ANDC_rrr(RA, RS, RB) _X (31, RS, RA, RB, 60, 1)
|
||||||
|
#define ANDI_rri(RA, RS, IMM) _Du (28, RS, RA, IMM)
|
||||||
|
#define ANDIS_rri(RA, RS, IMM) _Du (29, RS, RA, IMM)
|
||||||
|
|
||||||
|
#define Bi(BD) _FB (18, BD, 0, 0)
|
||||||
|
#define BAi(BD) _FBA (18, BD, 1, 0)
|
||||||
|
#define BLi(BD) _FB (18, BD, 0, 1)
|
||||||
|
#define BLAi(BD) _FBA (18, BD, 1, 1)
|
||||||
|
|
||||||
|
#define BCiii(BO,BI,BD) _BB (16, BO, BI, BD, 0, 0)
|
||||||
|
#define BCAiii(BO,BI,BD) _BB (16, BO, BI, BD, 1, 0)
|
||||||
|
#define BCLiii(BO,BI,BD) _BB (16, BO, BI, BD, 0, 1)
|
||||||
|
#define BCLAiii(BO,BI,BD) _BB (16, BO, BI, BD, 1, 1)
|
||||||
|
|
||||||
|
#define BCCTRii(BO,BI) _XL (19, BO, BI, 528, 0)
|
||||||
|
#define BCCTRLii(BO,BI) _XL (19, BO, BI, 528, 1)
|
||||||
|
|
||||||
|
#define BCLRii(BO,BI) _XL (19, BO, BI, 16, 0)
|
||||||
|
#define BCLRLii(BO,BI) _XL (19, BO, BI, 16, 1)
|
||||||
|
|
||||||
|
#define CMPiirr(CR, LL, RA, RB) _X (31, ((CR)<<2)|(LL), RA, RB, 0, 0)
|
||||||
|
#define CMPIiiri(CR, LL, RA, IMM) _D (11, ((CR)<<2)|(LL), RA, IMM)
|
||||||
|
|
||||||
|
#define CMPLiirr(CR, LL, RA, RB) _X (31, ((CR)<<2)|(LL), RA, RB, 32, 0)
|
||||||
|
#define CMPLIiiri(CR, LL, RA, IMM) _D (10, ((CR)<<2)|(LL), RA, IMM)
|
||||||
|
|
||||||
|
#define CRANDiii(CRD,CRA,CRB) _X (19, CRD, CRA, CRB, 257, 0)
|
||||||
|
#define CRANDCiii(CRD,CRA,CRB) _X (19, CRD, CRA, CRB, 129, 0)
|
||||||
|
#define CREQViii(CRD,CRA,CRB) _X (19, CRD, CRA, CRB, 289, 0)
|
||||||
|
#define CRNANDiii(CRD,CRA,CRB) _X (19, CRD, CRA, CRB, 225, 0)
|
||||||
|
#define CRNORiii(CRD,CRA,CRB) _X (19, CRD, CRA, CRB, 33, 0)
|
||||||
|
#define CRORiii(CRD,CRA,CRB) _X (19, CRD, CRA, CRB, 449, 0)
|
||||||
|
#define CRORCiii(CRD,CRA,CRB) _X (19, CRD, CRA, CRB, 417, 0)
|
||||||
|
#define CRXORiii(CRD,CRA,CRB) _X (19, CRD, CRA, CRB, 193, 0)
|
||||||
|
|
||||||
|
#define DCBSTrr(RA,RB) _X (31, 00, RA, RB, 54, 0)
|
||||||
|
|
||||||
|
#define DIVWrrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 491, 0)
|
||||||
|
#define DIVW_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 491, 1)
|
||||||
|
#define DIVWOrrr(RD, RA, RB) _XO (31, RD, RA, RB, 1, 491, 0)
|
||||||
|
#define DIVWO_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 1, 491, 1)
|
||||||
|
|
||||||
|
#define DIVWUrrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 459, 0)
|
||||||
|
#define DIVWU_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 459, 1)
|
||||||
|
#define DIVWUOrrr(RD, RA, RB) _XO (31, RD, RA, RB, 1, 459, 0)
|
||||||
|
#define DIVWUO_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 1, 459, 1)
|
||||||
|
|
||||||
|
#define EQVrrr(Ra,RS,RB) _X (31, RS, RA, RB, 284, 0)
|
||||||
|
#define EQV_rrr(Ra,RS,RB) _X (31, RS, RA, RB, 284, 1)
|
||||||
|
|
||||||
|
#define EXTSBrr(RA,RS) _X (31, RS, RA, 0, 954, 0)
|
||||||
|
#define EXTSB_rr(RA,RS) _X (31, RS, RA, 0, 954, 1)
|
||||||
|
|
||||||
|
#define EXTSHrr(RA,RS) _X (31, RS, RA, 0, 922, 0)
|
||||||
|
#define EXTSH_rr(RA,RS) _X (31, RS, RA, 0, 922, 1)
|
||||||
|
|
||||||
|
#define ICBIrr(RA,RB) _X (31, 00, RA, RB, 982, 0)
|
||||||
|
|
||||||
|
#define ISYNC() _X (19, 00, 00, 00, 150, 0)
|
||||||
|
|
||||||
|
#define LBZrm(RD,ID,RA) _D (34, RD, RA, ID)
|
||||||
|
#define LBZUrm(RD,ID,RA) _D (35, RD, RA, ID)
|
||||||
|
#define LBZUXrrr(RD,RA,RB) _X (31, RD, RA, RB, 119, 0)
|
||||||
|
#define LBZXrrr(RD,RA,RB) _X (31, RD, RA, RB, 87, 0)
|
||||||
|
|
||||||
|
#define LHArm(RD,ID,RA) _D (42, RD, RA, ID)
|
||||||
|
#define LHAUrm(RD,ID,RA) _D (43, RD, RA, ID)
|
||||||
|
#define LHAUXrrr(RD,RA,RB) _X (31, RD, RA, RB, 375, 0)
|
||||||
|
#define LHAXrrr(RD,RA,RB) _X (31, RD, RA, RB, 343, 0)
|
||||||
|
#define LHBRXrrr(RD,RA,RB) _X (31, RD, RA, RB, 790, 0)
|
||||||
|
|
||||||
|
#define LHZrm(RD,ID,RA) _D (40, RD, RA, ID)
|
||||||
|
#define LHZUrm(RD,ID,RA) _D (41, RD, RA, ID)
|
||||||
|
#define LHZUXrrr(RD,RA,RB) _X (31, RD, RA, RB, 311, 0)
|
||||||
|
#define LHZXrrr(RD,RA,RB) _X (31, RD, RA, RB, 279, 0)
|
||||||
|
|
||||||
|
#define LMWrm(RD,ID,RA) _D (46, RD, RA, ID)
|
||||||
|
|
||||||
|
#define LWBRXrrr(RD,RA,RB) _X (31, RD, RA, RB, 534, 0)
|
||||||
|
|
||||||
|
#define LWZrm(RD, DISP, RA) _D (32, RD, RA, DISP)
|
||||||
|
#define LWZUrm(RD, DISP, RA) _D (33, RD, RA, DISP)
|
||||||
|
#define LWZUXrrr(RD, RA, RB) _X (31, RD, RA, RB, 56, 0)
|
||||||
|
#define LWZXrrr(RD, RA, RB) _X (31, RD, RA, RB, 23, 0)
|
||||||
|
|
||||||
|
#define MCRFii(CD,CS) _X (19, ((CD)<<2), ((CS)<<2), 0, 0, 0)
|
||||||
|
|
||||||
|
#define MFCRr(RD) _X (31, RD, 0, 0, 19, 0)
|
||||||
|
#define MCRXRi(RD) _XFX (31, (RD)<<2, 0, 512)
|
||||||
|
|
||||||
|
#define MFSPRri(RD, SPR) _XFX (31, RD, (SPR)<<5, 339)
|
||||||
|
#define MTSPRir(SPR, RS) _XFX (31, RS, (SPR)<<5, 467)
|
||||||
|
|
||||||
|
#define MULHWrrr(RD,RA,RB) _XO (31, RD, RA, RB, 0, 75, 0)
|
||||||
|
#define MULHW_rrr(RD,RA,RB) _XO (31, RD, RA, RB, 0, 75, 1)
|
||||||
|
#define MULHWUrrr(RD,RA,RB) _XO (31, RD, RA, RB, 0, 11, 0)
|
||||||
|
#define MULHWU_rrr(RD,RA,RB) _XO (31, RD, RA, RB, 0, 11, 1)
|
||||||
|
|
||||||
|
#define MULLIrri(RD,RA,IM) _D (07, RD, RA, IM)
|
||||||
|
|
||||||
|
#define MULLWrrr(RD,RA,RB) _XO (31, RD, RA, RB, 0, 235, 0)
|
||||||
|
#define MULLW_rrr(RD,RA,RB) _XO (31, RD, RA, RB, 0, 235, 1)
|
||||||
|
#define MULLWOrrr(RD,RA,RB) _XO (31, RD, RA, RB, 1, 235, 0)
|
||||||
|
#define MULLWO_rrr(RD,RA,RB) _XO (31, RD, RA, RB, 1, 235, 1)
|
||||||
|
|
||||||
|
#define NANDrrr(RA,RS,RB) _X (31, RS, RA, RB, 476, 0)
|
||||||
|
#define NAND_rrr(RA,RS,RB) _X (31, RS, RA, RB, 476, 1)
|
||||||
|
|
||||||
|
#define NEGrr(RD,RA) _XO (31, RD, RA, 0, 0, 104, 0)
|
||||||
|
#define NEG_rr(RD,RA) _XO (31, RD, RA, 0, 0, 104, 1)
|
||||||
|
#define NEGOrr(RD,RA) _XO (31, RD, RA, 0, 1, 104, 0)
|
||||||
|
#define NEGO_rr(RD,RA) _XO (31, RD, RA, 0, 1, 104, 1)
|
||||||
|
|
||||||
|
#define NORrrr(RA,RS,RB) _X (31, RS, RA, RB, 124, 0)
|
||||||
|
#define NOR_rrr(RA,RS,RB) _X (31, RS, RA, RB, 124, 1)
|
||||||
|
|
||||||
|
#define ORrrr(RA,RS,RB) _X (31, RS, RA, RB, 444, 0)
|
||||||
|
#define OR_rrr(RA,RS,RB) _X (31, RS, RA, RB, 444, 1)
|
||||||
|
#define ORCrrr(RA,RS,RB) _X (31, RS, RA, RB, 412, 0)
|
||||||
|
#define ORC_rrr(RA,RS,RB) _X (31, RS, RA, RB, 412, 1)
|
||||||
|
#define ORIrri(RA,RS,IM) _Du (24, RS, RA, IM)
|
||||||
|
#define ORISrri(RA,RS,IM) _Du (25, RS, RA, IM)
|
||||||
|
|
||||||
|
#define RLWIMIrriii(RA,RS,SH,MB,ME) _M (20, RS, RA, SH, MB, ME, 0)
|
||||||
|
#define RLWIMI_rriii(RA,RS,SH,MB,ME) _M (20, RS, RA, SH, MB, ME, 1)
|
||||||
|
|
||||||
|
#define RLWINMrriii(RA,RS,SH,MB,ME) _M (21, RS, RA, SH, MB, ME, 0)
|
||||||
|
#define RLWINM_rriii(RA,RS,SH,MB,ME) _M (21, RS, RA, SH, MB, ME, 1)
|
||||||
|
|
||||||
|
#define RLWNMrrrii(RA,RS,RB,MB,ME) _M (23, RS, RA, RB, MB, ME, 0)
|
||||||
|
#define RLWNM_rrrii(RA,RS,RB,MB,ME) _M (23, RS, RA, RB, MB, ME, 1)
|
||||||
|
|
||||||
|
#define SLWrrr(RA,RS,RB) _X (31, RS, RA, RB, 24, 0)
|
||||||
|
#define SLW_rrr(RA,RS,RB) _X (31, RS, RA, RB, 24, 1)
|
||||||
|
|
||||||
|
#define SRAWrrr(RA,RS,RB) _X (31, RS, RA, RB, 792, 0)
|
||||||
|
#define SRAW_rrr(RA,RS,RB) _X (31, RS, RA, RB, 792, 1)
|
||||||
|
|
||||||
|
#define SRAWIrri(RD, RS, SH) _X (31, RS, RD, SH, 824, 0)
|
||||||
|
#define SRAWI_rri(RD, RS, SH) _X (31, RS, RD, SH, 824, 1)
|
||||||
|
|
||||||
|
#define SRWrrr(RA,RS,RB) _X (31, RS, RA, RB, 536, 0)
|
||||||
|
#define SRW_rrr(RA,RS,RB) _X (31, RS, RA, RB, 536, 1)
|
||||||
|
|
||||||
|
#define STBrm(RS,ID,RA) _D (38, RS, RA, ID)
|
||||||
|
#define STBUrm(RS,ID,RA) _D (39, RS, RA, ID)
|
||||||
|
#define STBUXrrr(RS,RA,RB) _X (31, RS, RA, RB, 247, 0)
|
||||||
|
#define STBXrrr(RS,RA,RB) _X (31, RS, RA, RB, 215, 0)
|
||||||
|
|
||||||
|
#define STHrm(RS,ID,RA) _D (44, RS, RA, ID)
|
||||||
|
#define STHUrm(RS,ID,RA) _D (45, RS, RA, ID)
|
||||||
|
#define STHBRXrrr(RS,RA,RB) _X (31, RS, RA, RB, 918, 0)
|
||||||
|
#define STHUXrrr(RS,RA,RB) _X (31, RS, RA, RB, 439, 0)
|
||||||
|
#define STHXrrr(RS,RA,RB) _X (31, RS, RA, RB, 407, 0)
|
||||||
|
|
||||||
|
#define STMWrm(RS,ID,RA) _D (47, RS, RA, ID)
|
||||||
|
|
||||||
|
#define STWrm(RS,ID,RA) _D (36, RS, RA, ID)
|
||||||
|
#define STWBRXrrr(RS,RA,RB) _X (31, RS, RA, RB, 662, 0)
|
||||||
|
#define STWCXrrr(RS,RA,RB) _X (31, RS, RA, RB, 150, 0)
|
||||||
|
#define STWCX_rrr(RS,RA,RB) _X (31, RS, RA, RB, 150, 1)
|
||||||
|
#define STWUrm(RS,ID,RA) _D (37, RS, RA, ID)
|
||||||
|
#define STWUXrrr(RS,RA,RB) _X (31, RS, RA, RB, 183, 0)
|
||||||
|
#define STWXrrr(RS,RA,RB) _X (31, RS, RA, RB, 151, 0)
|
||||||
|
|
||||||
|
#define SUBFrrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 40, 0)
|
||||||
|
#define SUBF_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 40, 1)
|
||||||
|
#define SUBFrrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 40, 0)
|
||||||
|
#define SUBF_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 40, 1)
|
||||||
|
#define SUBFErrr(RD, RA, RB) _XO (31, RD, RA, RB, 1, 136, 0)
|
||||||
|
#define SUBFE_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 1, 136, 1)
|
||||||
|
#define SUBFCrrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 8, 0)
|
||||||
|
#define SUBFC_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 8, 1)
|
||||||
|
#define SUBFCOrrr(RD, RA, RB) _XO (31, RD, RA, RB, 1, 8, 0)
|
||||||
|
#define SUBFCO_rrr(RD, RA, RB) _XO (31, RD, RA, RB, 1, 8, 1)
|
||||||
|
#define SUBFICrri(RD, RA, IMM) _D (8, RD, RA, IMM)
|
||||||
|
|
||||||
|
#define ADDrrr(RD, RA, RB) _XO (31, RD, RA, RB, 0, 266, 0)
|
||||||
|
#define ADDOrrr(RD, RA, RB) _XO (31, RD, RA, RB, 1, 266, 0)
|
||||||
|
#define ADDIrri(RD, RA, IMM) _D (14, RD, RA, IMM)
|
||||||
|
#define ADDISrri(RD, RA, IMM) _Ds (15, RD, RA, IMM)
|
||||||
|
|
||||||
|
#define SYNC() _X (31, 00, 00, 00, 598, 0)
|
||||||
|
|
||||||
|
#define TWirr(TO,RA,RB) _X (31, TO, RA, RB, 4, 0)
|
||||||
|
#define TWIiri(TO,RA,IM) _D (03, TO, RA, IM)
|
||||||
|
|
||||||
|
#define XORrrr(RA,RS,RB) _X (31, RS, RA, RB, 316, 0)
|
||||||
|
#define XOR_rrr(RA,RS,RB) _X (31, RS, RA, RB, 316, 1)
|
||||||
|
#define XORIrri(RA,RS,IM) _Du (26, RS, RA, IM)
|
||||||
|
#define XORISrri(RA,RS,IM) _Du (27, RS, RA, IM)
|
||||||
|
|
||||||
|
/* simplified mnemonics [1, Appendix F] */
|
||||||
|
|
||||||
|
#define MOVEIri2(R,H,L) (LISri(R,H), (L ? ORIrri(R,R,L) : 0))
|
||||||
|
#define MOVEIri(R,I) (_siP(16,I) ? LIri(R,I) : \
|
||||||
|
MOVEIri2(R, _HI(I), _LO(I)) )
|
||||||
|
|
||||||
|
#define SUBIrri(RD,RA,IM) ADDIrri(RD,RA,-_jit_L((IM))) /* [1, Section F.2.1] */
|
||||||
|
#define SUBISrri(RD,RA,IM) ADDISrri(RD,RA,-_jit_L((IM)))
|
||||||
|
#define SUBICrri(RD,RA,IM) ADDICrri(RD,RA,-_jit_L((IM)))
|
||||||
|
#define SUBIC_rri(RD,RA,IM) ADDIC_rri(RD,RA,-_jit_L((IM)))
|
||||||
|
|
||||||
|
#define SUBrrr(RD,RA,RB) SUBFrrr(RD,RB,RA) /* [1, Section F.2.2] */
|
||||||
|
#define SUBOrrr(RD,RA,RB) SUBFOrrr(RD,RB,RA)
|
||||||
|
#define SUB_rrr(RD,RA,RB) SUBF_rrr(RD,RB,RA)
|
||||||
|
#define SUBCrrr(RD,RA,RB) SUBFCrrr(RD,RB,RA)
|
||||||
|
#define SUBCOrrr(RD,RA,RB) SUBFCOrrr(RD,RB,RA)
|
||||||
|
#define SUBC_rrr(RD,RA,RB) SUBFC_rrr(RD,RB,RA)
|
||||||
|
#define SUBErrr(RD,RA,RB) SUBFErrr(RD,RB,RA)
|
||||||
|
#define SUBE_rrr(RD,RA,RB) SUBFE_rrr(RD,RB,RA)
|
||||||
|
|
||||||
|
#define CMPWIiri(C,RA,IM) CMPIiiri(C,0,RA,IM) /* [1, Table F-2] */
|
||||||
|
#define CMPWirr(C,RA,RB) CMPiirr(C,0,RA,RB)
|
||||||
|
#define CMPLWIiri(C,RA,IM) CMPLIiiri(C,0,RA,IM)
|
||||||
|
#define CMPLWirr(C,RA,RB) CMPLiirr(C,0,RA,RB)
|
||||||
|
|
||||||
|
#define CMPWIri(RA,IM) CMPWIiri(0,RA,IM) /* with implicit _cr0 */
|
||||||
|
#define CMPWrr(RA,RB) CMPWirr(0,RA,RB)
|
||||||
|
#define CMPLWIri(RA,IM) CMPLWIiri(0,RA,IM)
|
||||||
|
#define CMPLWrr(RA,RB) CMPLWirr(0,RA,RB)
|
||||||
|
|
||||||
|
#define EXTLWIrrii(RA,RS,N,B) RLWINMrriii(RA, RS, B, 0, (N)-1) /* [1, Table F-3] */
|
||||||
|
#define EXTRWIrrii(RA,RS,N,B) RLWINMrriii(RA, RS, (B)+(N), 32-(N), 31)
|
||||||
|
#define INSLWIrrii(RA,RS,N,B) RLWIMIrriii(RA, RS, 32-(B), B, (B)+(N)-1)
|
||||||
|
#define INSRWIrrii(RA,RS,N,B) RLWIMIrriii(RA, RS, 32-((B)+(N)), B, (B)+(N)-1)
|
||||||
|
#define ROTLWIrri(RA,RS,N) RLWINMrriii(RA, RS, N, 0, 31)
|
||||||
|
#define ROTRWIrri(RA,RS,N) RLWINMrriii(RA, RS, 32-(N), 0, 31)
|
||||||
|
#define ROTLWrrr(RA,RS,RB) RLWNMrrrii( RA, RS, RB, 0, 31)
|
||||||
|
#define SLWIrri(RA,RS,N) RLWINMrriii(RA, RS, N, 0, 31-(N))
|
||||||
|
#define SRWIrri(RA,RS,N) RLWINMrriii(RA, RS, 32-(N), N, 31)
|
||||||
|
#define CLRLWIrri(RA,RS,N) RLWINMrriii(RA, RS, 0, N, 31)
|
||||||
|
#define CLRRWIrri(RA,RS,N) RLWINMrriii(RA, RS, 0, 0, 31-(N))
|
||||||
|
#define CLRLSLWIrrii(RA,RS,B,N) RLWINMrriii(RA, RS, N, (B)-(N), 31-(N))
|
||||||
|
|
||||||
|
/* 9 below inverts the branch condition and the branch prediction.
|
||||||
|
* This has an incestuous knowledge of the fact that register 26
|
||||||
|
* is used as auxiliary!!! */
|
||||||
|
#define BC_EXT(A, C, D) (_siP(16, _jit_UL(D)-_jit_UL(_jit.x.pc)) \
|
||||||
|
? BCiii((A), (C), (D)) \
|
||||||
|
: (BCiii((A)^9, (C), _jit.x.pc+5), LISri(26,_HI(D)), ORIrri(26,26,_LO(D)), \
|
||||||
|
MTLRr(26), BLR() ))
|
||||||
|
|
||||||
|
#define B_EXT(D) (_siP(16, _jit_UL(D)-_jit_UL(_jit.x.pc)) \
|
||||||
|
? Bi((D)) \
|
||||||
|
: (LISri(26,_HI(D)), ORIrri(26,26,_LO(D)), MTLRr(26), BLR()) )
|
||||||
|
|
||||||
|
#define BTii(C,D) BC_EXT(12, C, D) /* [1, Table F-5] */
|
||||||
|
#define BFii(C,D) BC_EXT( 4, C, D)
|
||||||
|
#define BDNZi(D) BCiii(16, 0, D)
|
||||||
|
#define BDNZTii(C,D) BC_EXT( 8, C, D)
|
||||||
|
#define BDNZFii(C,D) BC_EXT( 0, C, D)
|
||||||
|
#define BDZi(D) BCiii(18, 0, D)
|
||||||
|
#define BDZTii(C,D) BC_EXT(10, C, D)
|
||||||
|
#define BDZFii(C,D) BC_EXT( 2, C, D)
|
||||||
|
|
||||||
|
#define BCTR() BCCTRii(20, 0) /* [1, Table F-6] */
|
||||||
|
#define BCTRL() BCCTRLii(20, 0)
|
||||||
|
|
||||||
|
#define BLR() BCLRii(20, 0) /* [1, Table F-6] */
|
||||||
|
#define BLRL() BCLRLii(20, 0)
|
||||||
|
|
||||||
|
|
||||||
|
#define BLTLRi(CR) BCLRii(12, ((CR)<<2)+0) /* [1, Table F-10] */
|
||||||
|
#define BLELRi(CR) BCLRii( 4 ((CR)<<2)+1)
|
||||||
|
#define BEQLRi(CR) BCLRii(12, ((CR)<<2)+2)
|
||||||
|
#define BGELRi(CR) BCLRii( 4, ((CR)<<2)+0)
|
||||||
|
#define BGTLRi(CR) BCLRii(12, ((CR)<<2)+1)
|
||||||
|
#define BNLLRi(CR) BCLRii( 4, ((CR)<<2)+0)
|
||||||
|
#define BNELRi(CR) BCLRii( 4, ((CR)<<2)+2)
|
||||||
|
#define BNGLRi(CR) BCLRii( 4, ((CR)<<2)+1)
|
||||||
|
#define BSOLRi(CR) BCLRii(12, ((CR)<<2)+3)
|
||||||
|
#define BNSLRi(CR) BCLRii( 4, ((CR)<<2)+3)
|
||||||
|
#define BUNLRi(CR) BCLRii(12, ((CR)<<2)+3)
|
||||||
|
#define BNULRi(CR) BCLRii( 4, ((CR)<<2)+3)
|
||||||
|
|
||||||
|
#define BLTLRLi(CR) BCLRLii(12, ((CR)<<2)+0) /* [1, Table F-10] */
|
||||||
|
#define BLELRLi(CR) BCLRLii( 4, ((CR)<<2)+1)
|
||||||
|
#define BEQLRLi(CR) BCLRLii(12, ((CR)<<2)+2)
|
||||||
|
#define BGELRLi(CR) BCLRLii( 4, ((CR)<<2)+0)
|
||||||
|
#define BGTLRLi(CR) BCLRLii(12, ((CR)<<2)+1)
|
||||||
|
#define BNLLRLi(CR) BCLRLii( 4, ((CR)<<2)+0)
|
||||||
|
#define BNELRLi(CR) BCLRLii( 4, ((CR)<<2)+2)
|
||||||
|
#define BNGLRLi(CR) BCLRLii( 4, ((CR)<<2)+1)
|
||||||
|
#define BSOLRLi(CR) BCLRLii(12, ((CR)<<2)+3)
|
||||||
|
#define BNSLRLi(CR) BCLRLii( 4, ((CR)<<2)+3)
|
||||||
|
#define BUNLRLi(CR) BCLRLii(12, ((CR)<<2)+3)
|
||||||
|
#define BNULRLi(CR) BCLRLii( 4, ((CR)<<2)+3)
|
||||||
|
|
||||||
|
#define BLTCTRi(CR) BCCTRii(12, ((CR)<<2)+0) /* [1, Table F-10] */
|
||||||
|
#define BLECTRi(CR) BCCTRii( 4 ((CR)<<2)+1)
|
||||||
|
#define BEQCTRi(CR) BCCTRii(12, ((CR)<<2)+2)
|
||||||
|
#define BGECTRi(CR) BCCTRii( 4, ((CR)<<2)+0)
|
||||||
|
#define BGTCTRi(CR) BCCTRii(12, ((CR)<<2)+1)
|
||||||
|
#define BNLCTRi(CR) BCCTRii( 4, ((CR)<<2)+0)
|
||||||
|
#define BNECTRi(CR) BCCTRii( 4, ((CR)<<2)+2)
|
||||||
|
#define BNGCTRi(CR) BCCTRii( 4, ((CR)<<2)+1)
|
||||||
|
#define BSOCTRi(CR) BCCTRii(12, ((CR)<<2)+3)
|
||||||
|
#define BNSCTRi(CR) BCCTRii( 4, ((CR)<<2)+3)
|
||||||
|
#define BUNCTRi(CR) BCCTRii(12, ((CR)<<2)+3)
|
||||||
|
#define BNUCTRi(CR) BCCTRii( 4, ((CR)<<2)+3)
|
||||||
|
|
||||||
|
#define BLTCTRLi(CR) BCCTRLii(12, ((CR)<<2)+0) /* [1, Table F-10] */
|
||||||
|
#define BLECTRLi(CR) BCCTRLii( 4, ((CR)<<2)+1)
|
||||||
|
#define BEQCTRLi(CR) BCCTRLii(12, ((CR)<<2)+2)
|
||||||
|
#define BGECTRLi(CR) BCCTRLii( 4, ((CR)<<2)+0)
|
||||||
|
#define BGTCTRLi(CR) BCCTRLii(12, ((CR)<<2)+1)
|
||||||
|
#define BNLCTRLi(CR) BCCTRLii( 4, ((CR)<<2)+0)
|
||||||
|
#define BNECTRLi(CR) BCCTRLii( 4, ((CR)<<2)+2)
|
||||||
|
#define BNGCTRLi(CR) BCCTRLii( 4, ((CR)<<2)+1)
|
||||||
|
#define BSOCTRLi(CR) BCCTRLii(12, ((CR)<<2)+3)
|
||||||
|
#define BNSCTRLi(CR) BCCTRLii( 4, ((CR)<<2)+3)
|
||||||
|
#define BUNCTRLi(CR) BCCTRLii(12, ((CR)<<2)+3)
|
||||||
|
#define BNUCTRLi(CR) BCCTRLii( 4, ((CR)<<2)+3)
|
||||||
|
|
||||||
|
|
||||||
|
#define BLTLR() BLTLRi(0) /* with implicit _cr0 */
|
||||||
|
#define BLELR() BLELRi(0)
|
||||||
|
#define BEQLR() BEQLRi(0)
|
||||||
|
#define BGELR() BGELRi(0)
|
||||||
|
#define BGTLR() BGTLRi(0)
|
||||||
|
#define BNLLR() BNLLRi(0)
|
||||||
|
#define BNELR() BNELRi(0)
|
||||||
|
#define BNGLR() BNGLRi(0)
|
||||||
|
#define BSOLR() BSOLRi(0)
|
||||||
|
#define BNSLR() BNSLRi(0)
|
||||||
|
#define BUNLR() BUNLRi(0)
|
||||||
|
#define BNULR() BNULRi(0)
|
||||||
|
|
||||||
|
#define BLTLRL() BLTLRLi(0)
|
||||||
|
#define BLELRL() BLELRLi(0)
|
||||||
|
#define BEQLRL() BEQLRLi(0)
|
||||||
|
#define BGELRL() BGELRLi(0)
|
||||||
|
#define BGTLRL() BGTLRLi(0)
|
||||||
|
#define BNLLRL() BNLLRLi(0)
|
||||||
|
#define BNELRL() BNELRLi(0)
|
||||||
|
#define BNGLRL() BNGLRLi(0)
|
||||||
|
#define BSOLRL() BSOLRLi(0)
|
||||||
|
#define BNSLRL() BNSLRLi(0)
|
||||||
|
#define BUNLRL() BUNLRLi(0)
|
||||||
|
#define BNULRL() BNULRLi(0)
|
||||||
|
|
||||||
|
#define BLTCTR() BLTCTRi(0)
|
||||||
|
#define BLECTR() BLECTRi(0)
|
||||||
|
#define BEQCTR() BEQCTRi(0)
|
||||||
|
#define BGECTR() BGECTRi(0)
|
||||||
|
#define BGTCTR() BGTCTRi(0)
|
||||||
|
#define BNLCTR() BNLCTRi(0)
|
||||||
|
#define BNECTR() BNECTRi(0)
|
||||||
|
#define BNGCTR() BNGCTRi(0)
|
||||||
|
#define BSOCTR() BSOCTRi(0)
|
||||||
|
#define BNSCTR() BNSCTRi(0)
|
||||||
|
#define BUNCTR() BUNCTRi(0)
|
||||||
|
#define BNUCTR() BNUCTRi(0)
|
||||||
|
|
||||||
|
#define BLTCTRL() BLTCTRLi(0)
|
||||||
|
#define BLECTRL() BLECTRLi(0)
|
||||||
|
#define BEQCTRL() BEQCTRLi(0)
|
||||||
|
#define BGECTRL() BGECTRLi(0)
|
||||||
|
#define BGTCTRL() BGTCTRLi(0)
|
||||||
|
#define BNLCTRL() BNLCTRLi(0)
|
||||||
|
#define BNECTRL() BNECTRLi(0)
|
||||||
|
#define BNGCTRL() BNGCTRLi(0)
|
||||||
|
#define BSOCTRL() BSOCTRLi(0)
|
||||||
|
#define BNSCTRL() BNSCTRLi(0)
|
||||||
|
#define BUNCTRL() BUNCTRLi(0)
|
||||||
|
#define BNUCTRL() BNUCTRLi(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define BLTii(C,D) BC_EXT(12, ((C)<<2)+0, D) /* [1, Table F-11] */
|
||||||
|
#define BNLii(C,D) BC_EXT( 4, ((C)<<2)+0, D)
|
||||||
|
#define BGEii(C,D) BC_EXT( 4, ((C)<<2)+0, D)
|
||||||
|
#define BGTii(C,D) BC_EXT(12, ((C)<<2)+1, D)
|
||||||
|
#define BNGii(C,D) BC_EXT( 4, ((C)<<2)+1, D)
|
||||||
|
#define BLEii(C,D) BC_EXT( 4, ((C)<<2)+1, D)
|
||||||
|
#define BEQii(C,D) BC_EXT(12, ((C)<<2)+2, D)
|
||||||
|
#define BNEii(C,D) BC_EXT( 4, ((C)<<2)+2, D)
|
||||||
|
#define BSOii(C,D) BC_EXT(12, ((C)<<2)+3, D)
|
||||||
|
#define BNSii(C,D) BC_EXT( 4, ((C)<<2)+3, D)
|
||||||
|
#define BUNii(C,D) BC_EXT(12, ((C)<<2)+3, D)
|
||||||
|
#define BNUii(C,D) BC_EXT( 4, ((C)<<2)+3, D)
|
||||||
|
|
||||||
|
#define BLTi(D) BLTii(0,D) /* with implicit _cr0 */
|
||||||
|
#define BLEi(D) BLEii(0,D)
|
||||||
|
#define BEQi(D) BEQii(0,D)
|
||||||
|
#define BGEi(D) BGEii(0,D)
|
||||||
|
#define BGTi(D) BGTii(0,D)
|
||||||
|
#define BNLi(D) BNLii(0,D)
|
||||||
|
#define BNEi(D) BNEii(0,D)
|
||||||
|
#define BNGi(D) BNGii(0,D)
|
||||||
|
#define BSOi(D) BSOii(0,D)
|
||||||
|
#define BNSi(D) BNSii(0,D)
|
||||||
|
#define BUNi(D) BUNii(0,D)
|
||||||
|
#define BNUi(D) BNUii(0,D)
|
||||||
|
|
||||||
|
#define BLTLii(C,D) BCLiii(12, ((C)<<2)+0, D) /* [1, Table F-??] */
|
||||||
|
#define BLELii(C,D) BCLiii( 4 ((C)<<2)+1, D)
|
||||||
|
#define BEQLii(C,D) BCLiii(12, ((C)<<2)+2, D)
|
||||||
|
#define BGELii(C,D) BCLiii( 4, ((C)<<2)+0, D)
|
||||||
|
#define BGTLii(C,D) BCLiii(12, ((C)<<2)+1, D)
|
||||||
|
#define BNLLii(C,D) BCLiii( 4, ((C)<<2)+0, D)
|
||||||
|
#define BNELii(C,D) BCLiii( 4, ((C)<<2)+2, D)
|
||||||
|
#define BNGLii(C,D) BCLiii( 4, ((C)<<2)+1, D)
|
||||||
|
#define BSOLii(C,D) BCLiii(12, ((C)<<2)+3, D)
|
||||||
|
#define BNSLii(C,D) BCLiii( 4, ((C)<<2)+3, D)
|
||||||
|
#define BUNLii(C,D) BCLiii(12, ((C)<<2)+3, D)
|
||||||
|
#define BNULii(C,D) BCLiii( 4, ((C)<<2)+3, D)
|
||||||
|
|
||||||
|
#define BLTLi(D) BLTLii(0,D) /* with implicit _cr0 */
|
||||||
|
#define BLELi(D) BLELii(0,D)
|
||||||
|
#define BEQLi(D) BEQLii(0,D)
|
||||||
|
#define BGELi(D) BGELii(0,D)
|
||||||
|
#define BGTLi(D) BGTLii(0,D)
|
||||||
|
#define BNLLi(D) BNLLii(0,D)
|
||||||
|
#define BNELi(D) BNELii(0,D)
|
||||||
|
#define BNGLi(D) BNGLii(0,D)
|
||||||
|
#define BSOLi(D) BSOLii(0,D)
|
||||||
|
#define BNSLi(D) BNSLii(0,D)
|
||||||
|
#define BUNLi(D) BUNLii(0,D)
|
||||||
|
#define BNULi(D) BNULii(0,D)
|
||||||
|
|
||||||
|
/* Note: there are many tens of other simplified branches that are not (yet?) defined here */
|
||||||
|
|
||||||
|
#define CRSETi(BX) CREQViii(BX, BX, BX) /* [1, Table F-15] */
|
||||||
|
#define CRCLRi(BX) CRXORiii(BX, BX, BX)
|
||||||
|
#define CRMOVEii(BX,BY) CRORiii(BX, BY, BY)
|
||||||
|
#define CRNOTii(BX,BY) CRNORiii(BX, BY, BY)
|
||||||
|
|
||||||
|
#define MTLRr(RS) MTSPRir(8, RS) /* [1, Table F-20] */
|
||||||
|
#define MFLRr(RD) MFSPRri(RD, 8)
|
||||||
|
#define MTCTRr(RS) MTSPRir(9, RS)
|
||||||
|
#define MFCTRr(RD) MFSPRri(RD, 9)
|
||||||
|
#define MTXERr(RS) MTSPRir(1, RS)
|
||||||
|
#define MFXERr(RD) MFSPRri(RD, 1)
|
||||||
|
|
||||||
|
#define NOP() ORIrri(0, 0, 0) /* [1, Section F.9] */
|
||||||
|
#define LIri(RD,IM) ADDIrri(RD, 0, IM)
|
||||||
|
#define LISri(RD,IM) ADDISrri(RD, 0, IM)
|
||||||
|
#define LArm(RD,D,RA) ADDIrri(RD, RA, D)
|
||||||
|
#define LArrr(RD,RB,RA) ADDIrrr(RD, RA, RB)
|
||||||
|
#define MRrr(RA,RS) ORrrr(RA, RS, RS)
|
||||||
|
#define NOTrr(RA,RS) NORrrr(RA, RS, RS)
|
||||||
|
|
||||||
|
/* alternative parenthesised forms of extended indexed load/store insns */
|
||||||
|
|
||||||
|
#define LBZUrx(RD,RA,RB) LBZUXrrr(RD,RA,RB)
|
||||||
|
#define LBZrx(RD,RA,RB) LBZXrrr(RD,RA,RB)
|
||||||
|
#define LHAUrx(RD,RA,RB) LHAUXrrr(RD,RA,RB)
|
||||||
|
#define LHArx(RD,RA,RB) LHAXrrr(RD,RA,RB)
|
||||||
|
#define LHBRrx(RD,RA,RB) LHBRXrrr(RD,RA,RB)
|
||||||
|
#define LHZUrx(RD,RA,RB) LHZUXrrr(RD,RA,RB)
|
||||||
|
#define LHZrx(RD,RA,RB) LHZXrrr(RD,RA,RB)
|
||||||
|
#define LWBRrx(RD,RA,RB) LWBRXrrr(RD,RA,RB)
|
||||||
|
#define LWZUrx(RD, RA, RB) LWZUXrrr(RD, RA, RB)
|
||||||
|
#define LWZrx(RD, RA, RB) LWZXrrr(RD, RA, RB)
|
||||||
|
#define STBUrx(RD,RA,RB) STBUXrrr(RD,RA,RB)
|
||||||
|
#define STBrx(RD,RA,RB) STBXrrr(RD,RA,RB)
|
||||||
|
#define STHBRrx(RS,RA,RB) STHBRXrrr(RS,RA,RB)
|
||||||
|
#define STHUrx(RS,RA,RB) STHUXrrr(RS,RA,RB)
|
||||||
|
#define STHrx(RS,RA,RB) STHXrrr(RS,RA,RB)
|
||||||
|
#define STWBRrx(RS,RA,RB) STWBRXrrr(RS,RA,RB)
|
||||||
|
#define STWCrx(RS,RA,RB) STWCXrrr(RS,RA,RB)
|
||||||
|
#define STWCX_rx(RS,RA,RB) STWCX_rrr(RS,RA,RB)
|
||||||
|
#define STWUrx(RS,RA,RB) STWUXrrr(RS,RA,RB)
|
||||||
|
#define STWrx(RS,RA,RB) STWXrrr(RS,RA,RB)
|
||||||
|
#define LArx(RD,RB,RA) LArrr(RD,RB,RA)
|
||||||
|
|
||||||
|
|
||||||
|
#define _LO(I) (_jit_UL(I) & _MASK(16))
|
||||||
|
#define _HI(I) (_jit_UL(I) >> (16))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*** References:
|
||||||
|
*
|
||||||
|
* [1] "PowerPC Microprocessor Family: The Programming Environments For 32-Bit Microprocessors", Motorola, 1997.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __ccg_asm_ppc_h */
|
276
lightning/ppc/core.h
Normal file
276
lightning/ppc/core.h
Normal file
|
@ -0,0 +1,276 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Platform-independent layer (PowerPC version)
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __lightning_core_h
|
||||||
|
#define __lightning_core_h
|
||||||
|
|
||||||
|
struct jit_local_state {
|
||||||
|
int nextarg_put; /* Next r3-r8 reg. to be written */
|
||||||
|
int nextarg_putfp; /* Next r3-r8 reg. to be written */
|
||||||
|
int nextarg_get; /* Next r20-r25 reg. to be read */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define JIT_SP 1
|
||||||
|
#define JIT_RET 3
|
||||||
|
#define JIT_R0 9
|
||||||
|
#define JIT_R1 10
|
||||||
|
#define JIT_R2 30 /* using r8 would limit argument passing */
|
||||||
|
#define JIT_V0 29
|
||||||
|
#define JIT_V1 28
|
||||||
|
#define JIT_V2 27
|
||||||
|
#define JIT_AUX 26 /* for 32-bit operands & shift counts */
|
||||||
|
|
||||||
|
/* If possible, use the `small' instruction (rd, rs, imm)
|
||||||
|
* else load imm into r26 and use the `big' instruction (rd, rs, r26)
|
||||||
|
*/
|
||||||
|
#define jit_chk_ims(imm, small, big) (_siP(16,(imm)) ? (small) : (MOVEIri(JIT_AUX, imm), (big)) )
|
||||||
|
#define jit_chk_imu(imm, small, big) (_uiP(16,(imm)) ? (small) : (MOVEIri(JIT_AUX, imm), (big)) )
|
||||||
|
#define jit_chk_imu15(imm, small, big) (_uiP(15,(imm)) ? (small) : (MOVEIri(JIT_AUX, imm), (big)) )
|
||||||
|
|
||||||
|
/* Helper macros for branches */
|
||||||
|
#define jit_s_brai(rs, is, jmp) (jit_chk_ims (is, CMPWIri(rs, is), CMPWrr(rs, JIT_AUX)), jmp, _jit.x.pc)
|
||||||
|
#define jit_s_brar(s1, s2, jmp) ( CMPWrr(s1, s2), jmp, _jit.x.pc)
|
||||||
|
#define jit_u_brai(rs, is, jmp) (jit_chk_imu (is, CMPLWIri(rs, is), CMPLWrr(rs, JIT_AUX)), jmp, _jit.x.pc)
|
||||||
|
#define jit_u_brar(s1, s2, jmp) ( CMPLWrr(s1, s2), jmp, _jit.x.pc)
|
||||||
|
|
||||||
|
/* Helper macros for boolean tests. */
|
||||||
|
#define jit_sbooli(d, rs, is, jmp) (jit_chk_ims (is, CMPWIri (rs, is), CMPWrr(rs, JIT_AUX)), MFCRr((d)), EXTRWIrrii((d), (d), 1, (jmp)))
|
||||||
|
#define jit_sboolr(d, s1, s2, jmp) ( CMPWrr (s1, s2), MFCRr((d)), EXTRWIrrii((d), (d), 1, (jmp)))
|
||||||
|
#define jit_sbooli2(d, rs, is, jmp) (jit_chk_ims (is, CMPWIri (rs, is), CMPWrr(rs, JIT_AUX)), MFCRr((d)), EXTRWIrrii((d), (d), 1, (jmp)), XORIrri((d), (d), 1))
|
||||||
|
#define jit_sboolr2(d, s1, s2, jmp) ( CMPWrr (s1, s2), MFCRr((d)), EXTRWIrrii((d), (d), 1, (jmp)), XORIrri((d), (d), 1))
|
||||||
|
#define jit_ubooli(d, rs, is, jmp) (jit_chk_imu (is, CMPLWIri(rs, is), CMPLWrr(rs, JIT_AUX)), MFCRr((d)), EXTRWIrrii((d), (d), 1, (jmp)))
|
||||||
|
#define jit_uboolr(d, s1, s2, jmp) ( CMPLWrr (s1, s2), MFCRr((d)), EXTRWIrrii((d), (d), 1, (jmp)))
|
||||||
|
#define jit_ubooli2(d, rs, is, jmp) (jit_chk_imu (is, CMPLWIri(rs, is), CMPLWrr(rs, JIT_AUX)), MFCRr((d)), EXTRWIrrii((d), (d), 1, (jmp)), XORIrri((d), (d), 1))
|
||||||
|
#define jit_uboolr2(d, s1, s2, jmp) ( CMPLWrr (s1, s2), MFCRr((d)), EXTRWIrrii((d), (d), 1, (jmp)), XORIrri((d), (d), 1))
|
||||||
|
|
||||||
|
/* modulus with immediate
|
||||||
|
* movei r26, imm
|
||||||
|
* mtlr r31
|
||||||
|
* divw r31, rs, r26 (or divwu)
|
||||||
|
* mullw r31, r31, r26
|
||||||
|
* sub rs, rs, r26
|
||||||
|
* mflr r31
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _jit_mod(div, rs, imm) (MOVEIri(JIT_AUX, (imm)), MTLRr(31), (div), \
|
||||||
|
MULLWrrr(31, 31, JIT_AUX), SUBrrr((rs), (rs), JIT_AUX), \
|
||||||
|
MFLRr(31))
|
||||||
|
|
||||||
|
/* Emit a 2-instruction MOVEI, even if a 1-instruction one is possible
|
||||||
|
* (it is a rare case for branches, and a fixed sequence of instructions
|
||||||
|
* is easier to patch). */
|
||||||
|
#define jit_movei(reg, imm) (LISri(reg,_HI(imm)), ORIrri((reg),(reg),_LO(imm)))
|
||||||
|
|
||||||
|
/* Patch a movei instruction made of a LIS at lis_pc and an ORI at ori_pc. */
|
||||||
|
#define jit_patch_movei(lis_pc, ori_pc) \
|
||||||
|
(*(lis_pc) &= ~_MASK(16), *lis_pc |= _HI(_jit.x.pc), \
|
||||||
|
*(ori_pc) &= ~_MASK(16), *ori_pc |= _LO(_jit.x.pc)) \
|
||||||
|
|
||||||
|
/* Patch a branch instruction */
|
||||||
|
#define jit_patch_branch(jump_pc) \
|
||||||
|
(*(jump_pc) &= ~_MASK(16) | 3, \
|
||||||
|
*(jump_pc) |= (_jit_UL(_jit.x.pc) - _jit_UL(jump_pc)) & _MASK(16))
|
||||||
|
|
||||||
|
#define _jit_blr_encoding ((19 << 26) | (20 << 21) | (00 << 16) | (00 << 11) | (16 << 1))
|
||||||
|
|
||||||
|
#define jit_patch(jump_pc) ( \
|
||||||
|
((*(jump_pc - 1) & ~1) == _jit_blr_encoding) \
|
||||||
|
? jit_patch_movei(((jump_pc) - 4), ((jump_pc) - 3)) \
|
||||||
|
: jit_patch_branch((jump_pc) - 1))
|
||||||
|
|
||||||
|
|
||||||
|
#define jit_arg_c() (_jitl.nextarg_get--)
|
||||||
|
#define jit_arg_i() (_jitl.nextarg_get--)
|
||||||
|
#define jit_arg_l() (_jitl.nextarg_get--)
|
||||||
|
#define jit_arg_p() (_jitl.nextarg_get--)
|
||||||
|
#define jit_arg_s() (_jitl.nextarg_get--)
|
||||||
|
#define jit_arg_uc() (_jitl.nextarg_get--)
|
||||||
|
#define jit_arg_ui() (_jitl.nextarg_get--)
|
||||||
|
#define jit_arg_ul() (_jitl.nextarg_get--)
|
||||||
|
#define jit_arg_us() (_jitl.nextarg_get--)
|
||||||
|
#define jit_addi_i(d, rs, is) jit_chk_ims((is), ADDICrri((d), (rs), (is)), ADDrrr((d), (rs), JIT_AUX))
|
||||||
|
#define jit_addr_i(d, s1, s2) ADDrrr((d), (s1), (s2))
|
||||||
|
#define jit_addci_i(d, rs, is) jit_chk_ims((is), ADDICrri((d), (rs), (is)), ADDCrrr((d), (rs), JIT_AUX))
|
||||||
|
#define jit_addcr_i(d, s1, s2) ADDCrrr((d), (s1), (s2))
|
||||||
|
#define jit_addxi_i(d, rs, is) (MOVEIri(JIT_AUX, (is)), ADDErrr((d), (rs), JIT_AUX))
|
||||||
|
#define jit_addxr_i(d, s1, s2) ADDErrr((d), (s1), (s2))
|
||||||
|
#define jit_andi_i(d, rs, is) jit_chk_imu((is), ANDI_rri((d), (rs), (is)), ANDrrr((d), (rs), JIT_AUX))
|
||||||
|
#define jit_andr_i(d, s1, s2) ANDrrr((d), (s1), (s2))
|
||||||
|
#define jit_bmsi_i(label, rs, is) (jit_chk_imu((is), ANDI_rri(JIT_AUX, (rs), (is)), AND_rrr(JIT_AUX, (rs), JIT_AUX)), BGTi((label)), _jit.x.pc)
|
||||||
|
#define jit_bmci_i(label, rs, is) (jit_chk_imu((is), ANDI_rri(JIT_AUX, (rs), (is)), AND_rrr(JIT_AUX, (rs), JIT_AUX)), BEQi((label)), _jit.x.pc)
|
||||||
|
#define jit_bmsr_i(label, s1, s2) ( AND_rrr(JIT_AUX, (s1), (s2)), BGTi((label)), _jit.x.pc)
|
||||||
|
#define jit_bmcr_i(label, s1, s2) ( AND_rrr(JIT_AUX, (s1), (s2)), BEQi((label)), _jit.x.pc)
|
||||||
|
#define jit_beqi_i(label, rs, is) jit_s_brai((rs), (is), BEQi((label)) )
|
||||||
|
#define jit_beqr_i(label, s1, s2) jit_s_brar((s1), (s2), BEQi((label)) )
|
||||||
|
#define jit_bgei_i(label, rs, is) jit_s_brai((rs), (is), BGEi((label)) )
|
||||||
|
#define jit_bgei_ui(label, rs, is) jit_u_brai((rs), (is), BGEi((label)) )
|
||||||
|
#define jit_bger_i(label, s1, s2) jit_s_brar((s1), (s2), BGEi((label)) )
|
||||||
|
#define jit_bger_ui(label, s1, s2) jit_u_brar((s1), (s2), BGEi((label)) )
|
||||||
|
#define jit_bgti_i(label, rs, is) jit_s_brai((rs), (is), BGTi((label)) )
|
||||||
|
#define jit_bgti_ui(label, rs, is) jit_u_brai((rs), (is), BGTi((label)) )
|
||||||
|
#define jit_bgtr_i(label, s1, s2) jit_s_brar((s1), (s2), BGTi((label)) )
|
||||||
|
#define jit_bgtr_ui(label, s1, s2) jit_u_brar((s1), (s2), BGTi((label)) )
|
||||||
|
#define jit_blei_i(label, rs, is) jit_s_brai((rs), (is), BLEi((label)) )
|
||||||
|
#define jit_blei_ui(label, rs, is) jit_u_brai((rs), (is), BLEi((label)) )
|
||||||
|
#define jit_bler_i(label, s1, s2) jit_s_brar((s1), (s2), BLEi((label)) )
|
||||||
|
#define jit_bler_ui(label, s1, s2) jit_u_brar((s1), (s2), BLEi((label)) )
|
||||||
|
#define jit_blti_i(label, rs, is) jit_s_brai((rs), (is), BLTi((label)) )
|
||||||
|
#define jit_blti_ui(label, rs, is) jit_u_brai((rs), (is), BLTi((label)) )
|
||||||
|
#define jit_bltr_i(label, s1, s2) jit_s_brar((s1), (s2), BLTi((label)) )
|
||||||
|
#define jit_bltr_ui(label, s1, s2) jit_u_brar((s1), (s2), BLTi((label)) )
|
||||||
|
#define jit_bnei_i(label, rs, is) jit_s_brai((rs), (is), BNEi((label)) )
|
||||||
|
#define jit_bner_i(label, s1, s2) jit_s_brar((s1), (s2), BNEi((label)) )
|
||||||
|
#define jit_boaddi_i(label, rs, is) (MOVEIri(JIT_AUX, (is)), ADDOrrr((rs), (rs), JIT_AUX), MCRXRi(0), BGTi((label)), _jit.x.pc) /* GT = bit 1 of XER = OV */
|
||||||
|
#define jit_bosubi_i(label, rs, is) (MOVEIri(JIT_AUX, (is)), SUBCOrrr((rs), (rs), JIT_AUX), MCRXRi(0), BGTi((label)), _jit.x.pc)
|
||||||
|
#define jit_boaddr_i(label, s1, s2) ( ADDOrrr((s1), (s1), (s2)), MCRXRi(0), BGTi((label)), _jit.x.pc)
|
||||||
|
#define jit_bosubr_i(label, s1, s2) ( SUBCOrrr((s1), (s1), (s2)), MCRXRi(0), BGTi((label)), _jit.x.pc)
|
||||||
|
#define jit_boaddi_ui(label, rs, is) (jit_chk_ims ((is), ADDICri((rs), (rs), is), ADDCrr((rs), JIT_AUX)), MCRXRi(0), BEQi((label)), _jit.x.pc) /* EQ = bit 2 of XER = CA */
|
||||||
|
#define jit_bosubi_ui(label, rs, is) (jit_chk_ims ((is), SUBICri((rs), (rs), is), SUBCrr((rs), JIT_AUX)), MCRXRi(0), BEQi((label)), _jit.x.pc)
|
||||||
|
#define jit_boaddr_ui(label, s1, s2) ( ADDCrr((s1), (s1), (s2)), MCRXRi(0), BEQi((label)), _jit.x.pc)
|
||||||
|
#define jit_bosubr_ui(label, s1, s2) ( SUBCrr((s1), (s1), (s2)), MCRXRi(0), BEQi((label)), _jit.x.pc)
|
||||||
|
#define jit_calli(label) (jit_movei(JIT_AUX, (label)), MTLRr(JIT_AUX), BLRL(), _jit.x.pc)
|
||||||
|
#define jit_divi_i(d, rs, is) jit_chk_ims(1111111, 0, DIVWrrr ((d), (rs), JIT_AUX))
|
||||||
|
#define jit_divi_ui(d, rs, is) jit_chk_imu(1111111, 0, DIVWUrrr((d), (rs), JIT_AUX))
|
||||||
|
#define jit_divr_i(d, s1, s2) DIVWrrr ((d), (s1), (s2))
|
||||||
|
#define jit_divr_ui(d, s1, s2) DIVWUrrr((d), (s1), (s2))
|
||||||
|
#define jit_eqi_i(d, rs, is) (jit_chk_ims((is), SUBIrri(JIT_AUX, (rs), (is)), SUBrrr(JIT_AUX, (rs), JIT_AUX)), SUBFICrri((d), JIT_AUX, 0), ADDErrr((d), (d), JIT_AUX))
|
||||||
|
#define jit_eqr_i(d, s1, s2) (SUBrrr(JIT_AUX, (s1), (s2)), SUBFICrri((d), JIT_AUX, 0), ADDErrr((d), (d), JIT_AUX))
|
||||||
|
#define jit_extr_c_i(d, rs) EXTSBrr((d), (rs))
|
||||||
|
#define jit_extr_s_i(d, rs) EXTSHrr((d), (rs))
|
||||||
|
#define jit_gei_i(d, rs, is) jit_sbooli2((d), (rs), (is), _lt)
|
||||||
|
#define jit_gei_ui(d, rs, is) jit_ubooli2((d), (rs), (is), _lt)
|
||||||
|
#define jit_ger_i(d, s1, s2) jit_sboolr2((d), (s1), (s2), _lt)
|
||||||
|
#define jit_ger_ui(d, s1, s2) jit_uboolr2((d), (s1), (s2), _lt)
|
||||||
|
#define jit_gti_i(d, rs, is) jit_sbooli ((d), (rs), (is), _gt)
|
||||||
|
#define jit_gti_ui(d, rs, is) jit_ubooli ((d), (rs), (is), _gt)
|
||||||
|
#define jit_gtr_i(d, s1, s2) jit_sboolr ((d), (s1), (s2), _gt)
|
||||||
|
#define jit_gtr_ui(d, s1, s2) jit_uboolr ((d), (s1), (s2), _gt)
|
||||||
|
#define jit_hmuli_i(d, rs, is) jit_chk_ims(1111111, 0, MULHWrrr ((d), (rs), JIT_AUX))
|
||||||
|
#define jit_hmuli_ui(d, rs, is) jit_chk_imu(1111111, 0, MULHWUrrr((d), (rs), JIT_AUX))
|
||||||
|
#define jit_hmulr_i(d, s1, s2) MULHWrrr ((d), (s1), (s2))
|
||||||
|
#define jit_hmulr_ui(d, s1, s2) MULHWUrrr((d), (s1), (s2))
|
||||||
|
#define jit_jmpi(label) (B_EXT((label)), _jit.x.pc)
|
||||||
|
#define jit_jmpr(reg) (MTLRr(reg), BLR())
|
||||||
|
#define jit_ldxi_c(d, rs, is) (jit_ldxi_uc((d), (rs), (is)), jit_extr_c_i((d), (d)))
|
||||||
|
#define jit_ldxr_c(d, s1, s2) (jit_ldxr_uc((d), (s1), (s2)), jit_extr_c_i((d), (d)))
|
||||||
|
#define jit_ldxi_i(d, rs, is) jit_chk_ims((d), LWZrm((d), (is), (rs)), LWZrx((d), JIT_AUX, (rs)))
|
||||||
|
#define jit_ldxi_s(d, rs, is) jit_chk_ims((d), LHArm((d), (is), (rs)), LHArx((d), JIT_AUX, (rs)))
|
||||||
|
#define jit_ldxi_uc(d, rs, is) jit_chk_ims((d), LBZrm((d), (is), (rs)), LBZrx((d), JIT_AUX, (rs)))
|
||||||
|
#define jit_ldxi_us(d, rs, is) jit_chk_ims((d), LHZrm((d), (is), (rs)), LHZrx((d), JIT_AUX, (rs)))
|
||||||
|
#define jit_ldxr_i(d, s1, s2) LWZrx((d), (s1), (s2))
|
||||||
|
#define jit_ldxr_s(d, s1, s2) LHArx((d), (s1), (s2))
|
||||||
|
#define jit_ldxr_uc(d, s1, s2) LBZrx((d), (s1), (s2))
|
||||||
|
#define jit_ldxr_us(d, s1, s2) LHZrx((d), (s1), (s2))
|
||||||
|
#define jit_lei_i(d, rs, is) jit_sbooli2((d), (rs), (is), _gt )
|
||||||
|
#define jit_lei_ui(d, rs, is) jit_ubooli2((d), (rs), (is), _gt )
|
||||||
|
#define jit_ler_i(d, s1, s2) jit_sboolr2((d), (s1), (s2), _gt )
|
||||||
|
#define jit_ler_ui(d, s1, s2) jit_uboolr2((d), (s1), (s2), _gt )
|
||||||
|
#define jit_lshi_i(d, rs, is) SLWIrri((d), (rs), (is))
|
||||||
|
#define jit_lshr_i(d, s1, s2) (ANDIrri(JIT_AUX, (s2), 31), SLWrrr ((d), (s1), JIT_AUX))
|
||||||
|
#define jit_lti_i(d, rs, is) jit_sbooli ((d), (rs), (is), _lt )
|
||||||
|
#define jit_lti_ui(d, rs, is) jit_ubooli ((d), (rs), (is), _lt )
|
||||||
|
#define jit_ltr_i(d, s1, s2) jit_sboolr ((d), (s1), (s2), _lt )
|
||||||
|
#define jit_ltr_ui(d, s1, s2) jit_uboolr ((d), (s1), (s2), _lt )
|
||||||
|
#define jit_modi_i(d, rs, is) _jit_mod(jit_divi_i (31, (rs), JIT_AUX), (is))
|
||||||
|
#define jit_modi_ui(d, rs, is) _jit_mod(jit_divi_ui(31, (rs), JIT_AUX), (irs))
|
||||||
|
#define jit_modr_i(d, s1, s2) (DIVWrrr(JIT_AUX, (s1), (s2)), MULLWrrr(JIT_AUX, JIT_AUX, (s2)), SUBrrr((d), (s1), JIT_AUX))
|
||||||
|
#define jit_modr_ui(d, s1, s2) (DIVWUrrr(JIT_AUX, (s1), (s2)), MULLWrrr(JIT_AUX, JIT_AUX, (s2)), SUBrrr((d), (s1), JIT_AUX))
|
||||||
|
#define jit_movi_i(d, is) MOVEIri((d), (is))
|
||||||
|
#define jit_movr_i(d, rs) MRrr((d), (rs))
|
||||||
|
#define jit_muli_i(d, rs, is) jit_chk_ims ((is), MULLIrri((d), (rs), (is)), MULLWrrr((d), (rs), JIT_AUX))
|
||||||
|
#define jit_muli_ui(d, rs, is) jit_chk_imu15((is), MULLIrri((d), (rs), (is)), MULLWrrr((d), (rs), JIT_AUX))
|
||||||
|
#define jit_mulr_i(d, s1, s2) MULLWrrr((d), (s1), (s2))
|
||||||
|
#define jit_mulr_ui(d, s1, s2) MULLWrrr((d), (s1), (s2))
|
||||||
|
#define jit_nei_i(d, rs, is) (jit_chk_ims((is), SUBIrri(JIT_AUX, (rs), (is)), SUBrrr(JIT_AUX, (rs), JIT_AUX)), ADDICrri((d), JIT_AUX, -1), SUBFErrr((d), (d), JIT_AUX))
|
||||||
|
#define jit_ner_i(d, s1, s2) (SUBrrr(JIT_AUX, (s1), (s2)), ADDICrri((d), JIT_AUX, -1), SUBFErrr((d), (d), JIT_AUX))
|
||||||
|
#define jit_nop() NOP()
|
||||||
|
#define jit_ori_i(d, rs, is) jit_chk_imu((is), ORIrri((d), (rs), (is)), ORrrr((d), (rs), JIT_AUX))
|
||||||
|
#define jit_orr_i(d, s1, s2) ORrrr((d), (s1), (s2))
|
||||||
|
#define jit_popr_i(rs) (LWZrm((rs), 0, 1), ADDIrri(1, 1, 4))
|
||||||
|
#define jitfp_prepare(numi, numf, numd) (_jitl.nextarg_put = 3 + (numi) + (numf) + 2*(numd))
|
||||||
|
#define jit_prolog(n) _jit_prolog(&_jit, (n))
|
||||||
|
#define jit_pushr_i(rs) STWUrm((rs), -4, 1)
|
||||||
|
#define jit_pusharg_i(rs) (--_jitl.nextarg_put, MRrr(_jitl.nextarg_put, (rs)))
|
||||||
|
#define jit_ret() jit_jmpr(31)
|
||||||
|
#define jit_retval(rd) MRrr((rd), 3)
|
||||||
|
#define jit_rsbi_i(d, rs, is) jit_chk_ims((is), SUBFICrri((d), (rs), (is)), SUBFCrrr((d), (rs), JIT_AUX))
|
||||||
|
#define jit_rshi_i(d, rs, is) SRAWIrri((d), (rs), (is))
|
||||||
|
#define jit_rshi_ui(d, rs, is) SRWIrri ((d), (rs), (is))
|
||||||
|
#define jit_rshr_i(d, s1, s2) (ANDIrrr(JIT_AUX, (s2), 31), SRAWrrr ((d), (s1), JIT_AUX))
|
||||||
|
#define jit_rshr_ui(d, s1, s2) (ANDIrrr(JIT_AUX, (s2), 31), SRWrrr ((d), (s1), JIT_AUX))
|
||||||
|
#define jit_stxi_c(id, rd, rs) jit_chk_ims((id), STBrm((rs), (id), (rd)), STBrx((rs), (rd), JIT_AUX))
|
||||||
|
#define jit_stxi_i(id, rd, rs) jit_chk_ims((id), STWrm((rs), (id), (rd)), STWrx((rs), (rd), JIT_AUX))
|
||||||
|
#define jit_stxi_s(id, rd, rs) jit_chk_ims((id), STHrm((rs), (id), (rd)), STHrx((rs), (rd), JIT_AUX))
|
||||||
|
#define jit_stxr_c(d1, d2, rs) STBrx((rs), (d1), (d2))
|
||||||
|
#define jit_stxr_i(d1, d2, rs) STWrx((rs), (d1), (d2))
|
||||||
|
#define jit_stxr_s(d1, d2, rs) STHrx((rs), (d1), (d2))
|
||||||
|
#define jit_subr_i(d, s1, s2) SUBrrr((d), (s1), (s2))
|
||||||
|
#define jit_subcr_i(d, s1, s2) SUBCrrr((d), (s1), (s2))
|
||||||
|
#define jit_subxi_i(d, rs, is) jit_chk_ims(111111111, 0, SUBErrr((d), (rs), JIT_AUX))
|
||||||
|
#define jit_subxr_i(d, s1, s2) SUBErrr((d), (s1), (s2))
|
||||||
|
#define jit_xori_i(d, rs, is) jit_chk_imu((is), XORIrri((d), (rs), (is)), XORrrr((d), (rs), JIT_AUX))
|
||||||
|
#define jit_xorr_i(d, s1, s2) XORrrr((d), (s1), (s2))
|
||||||
|
|
||||||
|
/* Cannot use JIT_RZERO because having 0 in a register field on the PowerPC
|
||||||
|
* does not mean `a register whose value is 0', but rather `no register at
|
||||||
|
* all' */
|
||||||
|
|
||||||
|
#define jit_negr_i(d, rs) jit_rsbi_i((d), (rs), 0)
|
||||||
|
#define jit_negr_l(d, rs) jit_rsbi_l((d), (rs), 0)
|
||||||
|
#define jit_ldr_c(rd, rs) jit_ldxr_c((rd), 0, (rs))
|
||||||
|
#define jit_str_c(rd, rs) jit_stxr_c(0, (rd), (rs))
|
||||||
|
#define jit_ldr_s(rd, rs) jit_ldxr_s((rd), 0, (rs))
|
||||||
|
#define jit_str_s(rd, rs) jit_stxr_s(0, (rd), (rs))
|
||||||
|
#define jit_ldr_i(rd, rs) jit_ldxr_i((rd), 0, (rs))
|
||||||
|
#define jit_str_i(rd, rs) jit_stxr_i(0, (rd), (rs))
|
||||||
|
#define jit_ldr_uc(rd, rs) jit_ldxr_uc((rd), 0, (rs))
|
||||||
|
#define jit_ldr_us(rd, rs) jit_ldxr_us((rd), 0, (rs))
|
||||||
|
|
||||||
|
/* e.g.
|
||||||
|
* 0x01234567 _HA << 16 = 0x01230000 _LA = 0x00004567 _HA << 16 + LA = 0x01234567
|
||||||
|
* 0x89abcdef _HA << 16 = 0x89ac0000 _LA = 0xffffcdef _HA << 16 + LA = 0x89abcdef
|
||||||
|
*/
|
||||||
|
#define _HA(addr) ((_jit_UL(addr) >> 16) + (_jit_US(_jit_UL(addr)) >> 15))
|
||||||
|
#define _LA(addr) (_jit_UL(addr) - (_HA(addr) << 16))
|
||||||
|
|
||||||
|
#define jit_ldi_c(rd, is) (LISri(JIT_AUX, _HA(is)), jit_ldxi_c((rd), JIT_AUX, _LA(is)))
|
||||||
|
#define jit_sti_c(id, rs) (LISri(JIT_AUX, _HA(id)), jit_stxi_c(_LA(id), JIT_AUX, (rs)))
|
||||||
|
#define jit_ldi_s(rd, is) (LISri(JIT_AUX, _HA(is)), jit_ldxi_s((rd), JIT_AUX, _LA(is)))
|
||||||
|
#define jit_sti_s(id, rs) (LISri(JIT_AUX, _HA(id)), jit_stxi_s(_LA(id), JIT_AUX, (rs)))
|
||||||
|
#define jit_ldi_i(rd, is) (LISri(JIT_AUX, _HA(is)), jit_ldxi_i((rd), JIT_AUX, _LA(is)))
|
||||||
|
#define jit_sti_i(id, rs) (LISri(JIT_AUX, _HA(id)), jit_stxi_i(_LA(id), JIT_AUX, (rs)))
|
||||||
|
#define jit_ldi_uc(rd, is) (LISri(JIT_AUX, _HA(is)), jit_ldxi_uc((rd), JIT_AUX, _LA(is)))
|
||||||
|
#define jit_ldi_us(rd, is) (LISri(JIT_AUX, _HA(is)), jit_ldxi_us((rd), JIT_AUX, _LA(is)))
|
||||||
|
|
||||||
|
#endif /* __lightning_core_h */
|
104
lightning/ppc/fp.h
Normal file
104
lightning/ppc/fp.h
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Run-time assembler & support macros for the Sparc math unit
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __lightning_asm_fp_h
|
||||||
|
#define __lightning_asm_fp_h
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
/* dummy for now */
|
||||||
|
|
||||||
|
#define jit_add_two(reg0) FADDrrr(13 - (reg0), 13 - (reg0), 12 - (reg0))
|
||||||
|
#define jit_sub_two(reg0) FSUBrrr(13 - (reg0), 13 - (reg0), 12 - (reg0))
|
||||||
|
#define jit_mul_two(reg0) FMULrrr(13 - (reg0), 13 - (reg0), 12 - (reg0))
|
||||||
|
#define jit_div_two(reg0) FDIVrrr(13 - (reg0), 13 - (reg0), 12 - (reg0))
|
||||||
|
|
||||||
|
#define jit_abs(reg0) FABSr(13 - (reg0))
|
||||||
|
#define jit_sqrt(reg0) FSQRTr(13 - (reg0))
|
||||||
|
#define jit_neg(reg0) FNEGr(13 - (reg0))
|
||||||
|
|
||||||
|
#define jit_ldxi_f(reg0, rs, is) 0
|
||||||
|
#define jit_ldxr_f(reg0, s1, s2) 0
|
||||||
|
#define jit_ldxi_d(reg0, rs, is) 0
|
||||||
|
#define jit_ldxr_d(reg0, s1, s2) 0
|
||||||
|
#define jit_ldi_f(reg0, is) 0
|
||||||
|
#define jit_ldr_f(reg0, rs) 0
|
||||||
|
#define jit_ldi_d(reg0, is) 0
|
||||||
|
#define jit_ldr_d(reg0, rs) 0
|
||||||
|
#define jit_stxi_f(id, rd, reg0) 0
|
||||||
|
#define jit_stxr_f(d1, d2, reg0) 0
|
||||||
|
#define jit_stxi_d(id, rd, reg0) 0
|
||||||
|
#define jit_stxr_d(d1, d2, reg0) 0
|
||||||
|
#define jit_sti_f(id, reg0) 0
|
||||||
|
#define jit_str_f(rd, reg0) 0
|
||||||
|
#define jit_sti_d(id, reg0) 0
|
||||||
|
#define jit_str_d(rd, reg0) 0
|
||||||
|
|
||||||
|
/* Make space for 1 or 2 words, store address in REG */
|
||||||
|
#define jit_data(REG, D1) (_FBA (18, 8, 0, 1), _jit_L(D1), MFLRr(REG))
|
||||||
|
#define jit_data2(REG, D1, D2) (_FBA (18, 12, 0, 1), _jit_L(D1), _jit_L(D2), MFLRr(REG))
|
||||||
|
|
||||||
|
#define jit_fpimm(reg0, first, second) \
|
||||||
|
(jit_data2(JIT_AUX, (first), (second)), \
|
||||||
|
jit_ldxi_d((reg0), JIT_AUX, 0))
|
||||||
|
|
||||||
|
#define jit_floor(rd, reg0) jit_call_fp((rd), (reg0), floor)
|
||||||
|
#define jit_ceil(rd, reg0) jit_call_fp((rd), (reg0), ceil)
|
||||||
|
|
||||||
|
#define jit_call_fp(rd, reg0, fn) \
|
||||||
|
jit_fail(#fn " not supported", __FILE__, __LINE__, __FUNCTION__)
|
||||||
|
/* pass reg0 as first parameter of rd
|
||||||
|
bl fn
|
||||||
|
mr r3, rd */
|
||||||
|
|
||||||
|
#define jit_trunc(rd, reg0) (jit_data((rd), 0), \
|
||||||
|
FCTIWZrr(13 - (reg0), 13 - (reg0)), \
|
||||||
|
STFIWXrrr(13 - (reg0), 0, (rd)), \
|
||||||
|
LWZrm((rd), 0, (rd)))
|
||||||
|
|
||||||
|
#define jit_round(rd, reg0) (jit_data((rd), 0), \
|
||||||
|
FCTIWrr(13 - (reg0), 13 - (reg0)), \
|
||||||
|
STFIWXrrr(13 - (reg0), 0, (rd)), \
|
||||||
|
LWZrm((rd), 0, (rd)))
|
||||||
|
|
||||||
|
#define jit_cmp(le, ge, reg0) (FCMPOirr(7, 13 - (reg0), 0), \
|
||||||
|
CRORiii(28 + _gt, 28 + _gt, 28 + _eq), \
|
||||||
|
CRORiii(28 + _lt, 28 + _lt, 28 + _eq), \
|
||||||
|
MFCRr((ge)), \
|
||||||
|
EXTRWIrrii((le), (ge), 1, 28 + _lt), \
|
||||||
|
EXTRWIrrii((ge), (ge), 1, 28 + _gt))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __lightning_asm_h */
|
161
lightning/ppc/funcs.h
Normal file
161
lightning/ppc/funcs.h
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Platform-independent layer inline functions (PowerPC)
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __lightning_funcs_h
|
||||||
|
#define __lightning_funcs_h
|
||||||
|
|
||||||
|
#if !defined(__GNUC__) && !defined(__GNUG__)
|
||||||
|
#error Go get GNU C, I do not know how to flush the cache
|
||||||
|
#error with this compiler.
|
||||||
|
#else
|
||||||
|
static void
|
||||||
|
jit_flush_code(void *start, void *end)
|
||||||
|
{
|
||||||
|
#ifndef LIGHTNING_CROSS
|
||||||
|
register char *ddest, *idest;
|
||||||
|
|
||||||
|
static int cache_line_size;
|
||||||
|
if (cache_line_size == 0) {
|
||||||
|
char buffer[8192];
|
||||||
|
int i, probe;
|
||||||
|
|
||||||
|
/* Find out the size of a cache line by zeroing one */
|
||||||
|
memset(buffer, 0xFF, 8192);
|
||||||
|
__asm__ __volatile__ ("dcbz 0,%0" : : "r"(buffer + 4096));
|
||||||
|
|
||||||
|
/* Probe for the beginning of the cache line. */
|
||||||
|
for(i = 0, probe = 4096; probe; probe >>= 1)
|
||||||
|
if (buffer[i | probe] != 0x00)
|
||||||
|
i |= probe;
|
||||||
|
|
||||||
|
/* i is now just before the start of the cache line */
|
||||||
|
i++;
|
||||||
|
for(cache_line_size = 1; i + cache_line_size < 8192; cache_line_size <<= 1)
|
||||||
|
if (buffer[i + cache_line_size] != 0x00)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
start -= ((long) start) & (cache_line_size - 1);
|
||||||
|
end -= ((long) end) & (cache_line_size - 1);
|
||||||
|
|
||||||
|
/* Force data cache write-backs */
|
||||||
|
for (ddest = start; ddest <= (char *) end; ddest += cache_line_size) {
|
||||||
|
__asm__ __volatile__ ("dcbst 0,%0" : : "r"(ddest));
|
||||||
|
}
|
||||||
|
__asm__ __volatile__ ("sync" : : );
|
||||||
|
|
||||||
|
/* Now invalidate the instruction cache */
|
||||||
|
for (idest = start; idest <= (char *) end; idest += cache_line_size) {
|
||||||
|
__asm__ __volatile__ ("icbi 0,%0" : : "r"(idest));
|
||||||
|
}
|
||||||
|
__asm__ __volatile__ ("isync" : : );
|
||||||
|
#endif /* !LIGHTNING_CROSS */
|
||||||
|
}
|
||||||
|
#endif /* __GNUC__ || __GNUG__ */
|
||||||
|
|
||||||
|
#define _jit (*jit)
|
||||||
|
|
||||||
|
/* Emit a trampoline for a function.
|
||||||
|
* Upon entrance to the trampoline:
|
||||||
|
* - R0 = return address for the function
|
||||||
|
* - LR = address where the real code for the function lies
|
||||||
|
* - R3-R8 = parameters
|
||||||
|
* After jumping to the address pointed to by R10:
|
||||||
|
* - LR = address where the epilog lies (the function must return there)
|
||||||
|
* - R25-R20 = parameters (order is reversed, 1st argument is R25)
|
||||||
|
*/
|
||||||
|
static jit_insn *
|
||||||
|
_jit_trampoline(jit, n)
|
||||||
|
register jit_state *jit;
|
||||||
|
register int n;
|
||||||
|
{
|
||||||
|
static jit_insn trampolines[200];
|
||||||
|
static jit_insn *p_trampolines[6], *free = trampolines;
|
||||||
|
jit_insn *trampo;
|
||||||
|
int i, ofs, frame_size;
|
||||||
|
|
||||||
|
if (!p_trampolines[n]) {
|
||||||
|
_jit.x.pc = trampo = p_trampolines[n] = free;
|
||||||
|
|
||||||
|
frame_size = 24 + (6 + n) * 4; /* r26..r31 + args */
|
||||||
|
frame_size += 15; /* the stack must be quad-word */
|
||||||
|
frame_size &= ~15; /* aligned */
|
||||||
|
|
||||||
|
STWUrm(1, -frame_size, 1); /* stwu r1, -x(r1) */
|
||||||
|
|
||||||
|
for (ofs = frame_size - (6 + n) * 4, i = 26 - n; i <= 31; ofs += 4, i++) {
|
||||||
|
STWrm(i, ofs, 1); /* stw rI, ofs(r1) */
|
||||||
|
}
|
||||||
|
STWrm(0, ofs+4, 1); /* stw r0, x(r1) */
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
MRrr(25-i, 3+i); /* save parameters in r25..r20 */
|
||||||
|
}
|
||||||
|
BLRL(); /* blrl */
|
||||||
|
LWZrm(0, ofs+4, 1); /* lwz r0, x(r1) (ret.addr.) */
|
||||||
|
MTLRr(0); /* mtspr LR, r0 */
|
||||||
|
|
||||||
|
for (ofs = frame_size - (6 + n) * 4, i = 26 - n; i <= 31; ofs += 4, i++) {
|
||||||
|
LWZrm(i, ofs, 1); /* lwz rI, ofs(r1) */
|
||||||
|
}
|
||||||
|
ADDIrri(1, 1, frame_size); /* addi r1, r1, x */
|
||||||
|
BLR(); /* blr */
|
||||||
|
|
||||||
|
jit_flush_code(trampo, _jit.x.pc);
|
||||||
|
free = _jit.x.pc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return p_trampolines[n];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_jit_prolog(jit, n)
|
||||||
|
register jit_state *jit;
|
||||||
|
register int n;
|
||||||
|
{
|
||||||
|
register jit_insn *save_pc, *trampo;
|
||||||
|
|
||||||
|
save_pc = _jit.x.pc;
|
||||||
|
trampo = _jit_trampoline(jit, n);
|
||||||
|
_jit.x.pc = save_pc;
|
||||||
|
|
||||||
|
_jitl.nextarg_get = 25;
|
||||||
|
MFLRr(0);
|
||||||
|
MOVEIri(10, trampo);
|
||||||
|
MTLRr(10);
|
||||||
|
BLRL(); /* blrl */
|
||||||
|
MFLRr(31); /* mflr r31 */
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef _jit
|
||||||
|
|
||||||
|
#endif /* __lightning_funcs_h */
|
303
lightning/sparc/asm.h
Normal file
303
lightning/sparc/asm.h
Normal file
|
@ -0,0 +1,303 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Run-time assembler for the SPARC
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 1999, 2000, 2001, 2002 Ian Piumarta
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __lightning_asm_h
|
||||||
|
#define __lightning_asm_h
|
||||||
|
|
||||||
|
|
||||||
|
/* <imm> = [0-9]+ -> add i, one parameter (imm)
|
||||||
|
* <reg> = %<imm> -> add r, one parameter (imm or _Rr(imm) )
|
||||||
|
* %g<imm> -> add r, one parameter (imm or _Rg(imm) )
|
||||||
|
* %o<imm> -> add r, one parameter (imm+8 or _Ro(imm) )
|
||||||
|
* %l<imm> -> add r, one parameter (imm+16 or _Rl(imm) )
|
||||||
|
* %i<imm> -> add r, one parameter (imm+24 or _Ri(imm) )
|
||||||
|
* <mem> = <imm>(<reg>) -> add m, two parameters (reg,imm)
|
||||||
|
* <idx> = <reg>(<reg>) -> add x, two parameters (reg,reg)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
typedef unsigned int jit_insn;
|
||||||
|
|
||||||
|
#define _d30(BD) ((_jit_UL(BD) - _jit_UL(_jit.x.pc))>>2)
|
||||||
|
#define _d22(BD) _ck_d(22, _d30(BD))
|
||||||
|
|
||||||
|
#define _HI(I) (_jit_UL(I) >> (10))
|
||||||
|
#define _LO(I) (_jit_UL(I) & _MASK(10))
|
||||||
|
|
||||||
|
/* register names */
|
||||||
|
|
||||||
|
#define _y 0
|
||||||
|
#define _psr 1
|
||||||
|
|
||||||
|
#define _Rr(N) ( 0+(N))
|
||||||
|
#define _Rg(N) ( 0+(N))
|
||||||
|
#define _Ro(N) ( 8+(N))
|
||||||
|
#define _Rl(N) (16+(N))
|
||||||
|
#define _Ri(N) (24+(N))
|
||||||
|
|
||||||
|
/* instruction formats -- Figure 5-1, page 44 in */
|
||||||
|
/* SPARC International, "The SPARC Architecture Manual, Version 8", Prentice-Hall, 1992. */
|
||||||
|
|
||||||
|
#define _0i(RD, OP2, IMM) _jit_I((0<<30)| (_u5(RD)<<25)|(_u3(OP2)<<22)| _u22(IMM))
|
||||||
|
#define _0( A, CC, OP2, DSP) _jit_I((0<<30)|(_u1(A)<<29)|(_u4(CC)<<25)|(_u3(OP2)<<22)| _d22(DSP))
|
||||||
|
#define _0d( A, CC, OP2, DSP) _jit_I((0<<30)|(_u1(A)<<29)|(_u4(CC)<<25)|(_u3(OP2)<<22)| _u22(DSP))
|
||||||
|
|
||||||
|
#define _1( DSP) _jit_I((1<<30)| _d30(DSP))
|
||||||
|
|
||||||
|
#define _2( RD, OP3, RS1, I, ASI, RS2) _jit_I((2<<30)| (_u5(RD)<<25)|(_u6(OP3)<<19)|(_u5(RS1)<<14)|(_u1(I)<<13)|(_u8(ASI)<<5)|_u5 (RS2))
|
||||||
|
#define _2i(RD, OP3, RS1, I, IMM) _jit_I((2<<30)| (_u5(RD)<<25)|(_u6(OP3)<<19)|(_u5(RS1)<<14)|(_u1(I)<<13)| _s13(IMM))
|
||||||
|
#define _2f(RD, OP3, RS1, OPF, RS2) _jit_I((2<<30)| (_u5(RD)<<25)|(_u6(OP3)<<19)|(_u5(RS1)<<14)| (_u9(OPF)<<5)|_u5 (RS2))
|
||||||
|
|
||||||
|
#define _3( RD, OP3, RS1, I, ASI, RS2) _jit_I((3<<30)| (_u5(RD)<<25)|(_u6(OP3)<<19)|(_u5(RS1)<<14)|(_u1(I)<<13)|(_u8(ASI)<<5)|_u5 (RS2))
|
||||||
|
#define _3i(RD, OP3, RS1, I, IMM) _jit_I((3<<30)| (_u5(RD)<<25)|(_u6(OP3)<<19)|(_u5(RS1)<<14)|(_u1(I)<<13)| _s13(IMM))
|
||||||
|
|
||||||
|
/* basic instructions [Section B, page 87] */
|
||||||
|
|
||||||
|
#define ADDrrr(RS1, RS2, RD) _2 ((RD), 0, (RS1), 0, 0, (RS2))
|
||||||
|
#define ADDrir(RS1, IMM, RD) _2i ((RD), 0, (RS1), 1, (IMM))
|
||||||
|
#define ADDCCrrr(RS1, RS2, RD) _2 ((RD), 16, (RS1), 0, 0, (RS2))
|
||||||
|
#define ADDCCrir(RS1, IMM, RD) _2i ((RD), 16, (RS1), 1, (IMM))
|
||||||
|
#define ADDXrrr(RS1, RS2, RD) _2 ((RD), 8, (RS1), 0, 0, (RS2))
|
||||||
|
#define ADDXrir(RS1, IMM, RD) _2i ((RD), 8, (RS1), 1, (IMM))
|
||||||
|
#define ADDXCCrrr(RS1, RS2, RD) _2 ((RD), 24, (RS1), 0, 0, (RS2))
|
||||||
|
#define ADDXCCrir(RS1, IMM, RD) _2i ((RD), 24, (RS1), 1, (IMM))
|
||||||
|
#define ANDrrr(RS1, RS2, RD) _2 ((RD), 1, (RS1), 0, 0, (RS2))
|
||||||
|
#define ANDrir(RS1, IMM, RD) _2i ((RD), 1, (RS1), 1, (IMM))
|
||||||
|
#define ANDCCrrr(RS1, RS2, RD) _2 ((RD), 17, (RS1), 0, 0, (RS2))
|
||||||
|
#define ANDCCrir(RS1, IMM, RD) _2i ((RD), 17, (RS1), 1, (IMM))
|
||||||
|
|
||||||
|
#define BNi(DISP) _0 (0, 0, 2, (DISP))
|
||||||
|
#define BN_Ai(DISP) _0 (1, 0, 2, (DISP))
|
||||||
|
#define BEi(DISP) _0 (0, 1, 2, (DISP))
|
||||||
|
#define BE_Ai(DISP) _0 (1, 1, 2, (DISP))
|
||||||
|
#define BLEi(DISP) _0 (0, 2, 2, (DISP))
|
||||||
|
#define BLE_Ai(DISP) _0 (1, 2, 2, (DISP))
|
||||||
|
#define BLi(DISP) _0 (0, 3, 2, (DISP))
|
||||||
|
#define BL_Ai(DISP) _0 (1, 3, 2, (DISP))
|
||||||
|
#define BLEUi(DISP) _0 (0, 4, 2, (DISP))
|
||||||
|
#define BLEU_Ai(DISP) _0 (1, 4, 2, (DISP))
|
||||||
|
#define BCSi(DISP) _0 (0, 5, 2, (DISP))
|
||||||
|
#define BCS_Ai(DISP) _0 (1, 5, 2, (DISP))
|
||||||
|
#define BNEGi(DISP) _0 (0, 6, 2, (DISP))
|
||||||
|
#define BNEG_Ai(DISP) _0 (1, 6, 2, (DISP))
|
||||||
|
#define BVSi(DISP) _0 (0, 7, 2, (DISP))
|
||||||
|
#define BVS_Ai(DISP) _0 (1, 7, 2, (DISP))
|
||||||
|
#define BAi(DISP) _0 (0, 8, 2, (DISP))
|
||||||
|
#define BA_Ai(DISP) _0 (1, 8, 2, (DISP))
|
||||||
|
#define BNEi(DISP) _0 (0, 9, 2, (DISP))
|
||||||
|
#define BNE_Ai(DISP) _0 (1, 9, 2, (DISP))
|
||||||
|
#define BGi(DISP) _0 (0, 10, 2, (DISP))
|
||||||
|
#define BG_Ai(DISP) _0 (1, 10, 2, (DISP))
|
||||||
|
#define BGEi(DISP) _0 (0, 11, 2, (DISP))
|
||||||
|
#define BGE_Ai(DISP) _0 (1, 11, 2, (DISP))
|
||||||
|
#define BGUi(DISP) _0 (0, 12, 2, (DISP))
|
||||||
|
#define BGU_Ai(DISP) _0 (1, 12, 2, (DISP))
|
||||||
|
#define BCCi(DISP) _0 (0, 13, 2, (DISP))
|
||||||
|
#define BCC_Ai(DISP) _0 (1, 13, 2, (DISP))
|
||||||
|
#define BPOSi(DISP) _0 (0, 14, 2, (DISP))
|
||||||
|
#define BPOS_Ai(DISP) _0 (1, 14, 2, (DISP))
|
||||||
|
#define BVCi(DISP) _0 (0, 15, 2, (DISP))
|
||||||
|
#define BVC_Ai(DISP) _0 (1, 15, 2, (DISP))
|
||||||
|
|
||||||
|
#define CALLi(DISP) _1 ((DISP))
|
||||||
|
|
||||||
|
#define FLUSHrr(RS1, RS2) _2 (0, 0x3b, (RS1), 0, 0, (RS2))
|
||||||
|
#define FLUSHir(IMM, RS1) _2i (0, 0x3b, (RS1), 1, (IMM))
|
||||||
|
|
||||||
|
#define JMPLxr(RS1, RS2, RD) _2 ((RD), 56, (RS1), 0, 0, (RS2))
|
||||||
|
#define JMPLmr(RS1, IMM, RD) _2i ((RD), 56, (RS1), 1, (IMM))
|
||||||
|
|
||||||
|
#define LDxr(RS1, RS2, RD) _3 ((RD), 0, (RS1), 0, 0, (RS2))
|
||||||
|
#define LDmr(RS1, IMM, RD) _3i ((RD), 0, (RS1), 1, (IMM))
|
||||||
|
#define LDUBxr(RS1, RS2, RD) _3 ((RD), 1, (RS1), 0, 0, (RS2))
|
||||||
|
#define LDUBmr(RS1, IMM, RD) _3i ((RD), 1, (RS1), 1, (IMM))
|
||||||
|
#define LDUHxr(RS1, RS2, RD) _3 ((RD), 2, (RS1), 0, 0, (RS2))
|
||||||
|
#define LDUHmr(RS1, IMM, RD) _3i ((RD), 2, (RS1), 1, (IMM))
|
||||||
|
#define LDDxr(RS1, RS2, RD) _3 ((RD), 3, (RS1), 0, 0, (RS2))
|
||||||
|
#define LDDmr(RS1, IMM, RD) _3i ((RD), 3, (RS1), 1, (IMM))
|
||||||
|
#define LDSBxr(RS1, RS2, RD) _3 ((RD), 9, (RS1), 0, 0, (RS2))
|
||||||
|
#define LDSBmr(RS1, IMM, RD) _3i ((RD), 9, (RS1), 1, (IMM))
|
||||||
|
#define LDSHxr(RS1, RS2, RD) _3 ((RD), 10, (RS1), 0, 0, (RS2))
|
||||||
|
#define LDSHmr(RS1, IMM, RD) _3i ((RD), 10, (RS1), 1, (IMM))
|
||||||
|
|
||||||
|
#define ORrrr(RS1, RS2, RD) _2 ((RD), 2, (RS1), 0, 0, (RS2))
|
||||||
|
#define ORrir(RS1, IMM, RD) _2i ((RD), 2, (RS1), 1, (IMM))
|
||||||
|
#define ORCCrrr(RS1, RS2, RD) _2 ((RD), 18, (RS1), 0, 0, (RS2))
|
||||||
|
#define ORCCrir(RS1, IMM, RD) _2i ((RD), 18, (RS1), 1, (IMM))
|
||||||
|
|
||||||
|
#define RDir(RS, RD) _2 ((RD), (RS)|0x28, 0, 0, 0,0)
|
||||||
|
#define RESTORErrr(RS1, RS2, RD) _2 ((RD), 61, (RS1), 0, 0, (RS2))
|
||||||
|
#define RESTORErir(RS1, IMM, RD) _2i ((RD), 61, (RS1), 1, (IMM))
|
||||||
|
|
||||||
|
#define SAVErrr(RS1, RS2, RD) _2 ((RD), 60, (RS1), 0, 0, (RS2))
|
||||||
|
#define SAVErir(RS1, IMM, RD) _2i ((RD), 60, (RS1), 1, (IMM))
|
||||||
|
#define SDIVrrr(RS1, RS2, RD) _2 ((RD), 15, (RS1), 0, 0, (RS2))
|
||||||
|
#define SDIVrir(RS1, IMM, RD) _2i ((RD), 15, (RS1), 1, (IMM))
|
||||||
|
#define SDIVCCrrr(RS1, RS2, RD) _2 ((RD), 31, (RS1), 0, 0, (RS2))
|
||||||
|
#define SDIVCCrir(RS1, IMM, RD) _2i ((RD), 31, (RS1), 1, (IMM))
|
||||||
|
#define SETHIir(IMM, RD) _0i ((RD), 4, (IMM))
|
||||||
|
#define SLLrrr(RS1, RS2, RD) _2 ((RD), 37, (RS1), 0, 0, (RS2))
|
||||||
|
#define SLLrir(RS1, IMM, RD) _2i ((RD), 37, (RS1), 1, (IMM))
|
||||||
|
#define SMULrrr(RS1, RS2, RD) _2 ((RD), 11, (RS1), 0, 0, (RS2))
|
||||||
|
#define SMULrir(RS1, IMM, RD) _2i ((RD), 11, (RS1), 1, (IMM))
|
||||||
|
#define SMULCCrrr(RS1, RS2, RD) _2 ((RD), 27, (RS1), 0, 0, (RS2))
|
||||||
|
#define SMULCCrir(RS1, IMM, RD) _2i ((RD), 27, (RS1), 1, (IMM))
|
||||||
|
#define SRArrr(RS1, RS2, RD) _2 ((RD), 39, (RS1), 0, 0, (RS2))
|
||||||
|
#define SRArir(RS1, IMM, RD) _2i ((RD), 39, (RS1), 1, (IMM))
|
||||||
|
#define SRLrrr(RS1, RS2, RD) _2 ((RD), 38, (RS1), 0, 0, (RS2))
|
||||||
|
#define SRLrir(RS1, IMM, RD) _2i ((RD), 38, (RS1), 1, (IMM))
|
||||||
|
#define STrx(RS, RD1, RD2) _3 ((RS), 4, (RD1), 0, 0, (RD2))
|
||||||
|
#define STrm(RS, RD, IMM) _3i ((RS), 4, (RD), 1, (IMM))
|
||||||
|
#define STBrx(RS, RD1, RD2) _3 ((RS), 5, (RD1), 0, 0, (RD2))
|
||||||
|
#define STBrm(RS, RD, IMM) _3i ((RS), 5, (RD), 1, (IMM))
|
||||||
|
#define STBAR() _0i (0, 0x28, 15, 0, 0)
|
||||||
|
#define STHrx(RS, RD1, RD2) _3 ((RS), 6, (RD1), 0, 0, (RD2))
|
||||||
|
#define STHrm(RS, RD, IMM) _3i ((RS), 6, (RD), 1, (IMM))
|
||||||
|
#define STDrx(RS, RD1, RD2) _3 ((RS), 7, (RD1), 0, 0, (RD2))
|
||||||
|
#define STDrm(RS, RD, IMM) _3i ((RS), 7, (RD), 1, (IMM))
|
||||||
|
#define SUBrrr(RS1, RS2, RD) _2 ((RD), 4, (RS1), 0, 0, (RS2))
|
||||||
|
#define SUBrir(RS1, IMM, RD) _2i ((RD), 4, (RS1), 1, (IMM))
|
||||||
|
#define SUBCCrrr(RS1, RS2, RD) _2 ((RD), 20, (RS1), 0, 0, (RS2))
|
||||||
|
#define SUBCCrir(RS1, IMM, RD) _2i ((RD), 20, (RS1), 1, (IMM))
|
||||||
|
#define SUBXrrr(RS1, RS2, RD) _2 ((RD), 12, (RS1), 0, 0, (RS2))
|
||||||
|
#define SUBXrir(RS1, IMM, RD) _2i ((RD), 12, (RS1), 1, (IMM))
|
||||||
|
#define SUBXCCrrr(RS1, RS2, RD) _2 ((RD), 28, (RS1), 0, 0, (RS2))
|
||||||
|
#define SUBXCCrir(RS1, IMM, RD) _2i ((RD), 28, (RS1), 1, (IMM))
|
||||||
|
|
||||||
|
#define UDIVrrr(RS1, RS2, RD) _2 ((RD), 14, (RS1), 0, 0, (RS2))
|
||||||
|
#define UDIVrir(RS1, IMM, RD) _2i ((RD), 14, (RS1), 1, (IMM))
|
||||||
|
#define UDIVCCrrr(RS1, RS2, RD) _2 ((RD), 30, (RS1), 0, 0, (RS2))
|
||||||
|
#define UDIVCCrir(RS1, IMM, RD) _2i ((RD), 30, (RS1), 1, (IMM))
|
||||||
|
#define UMULrrr(RS1, RS2, RD) _2 ((RD), 10, (RS1), 0, 0, (RS2))
|
||||||
|
#define UMULrir(RS1, IMM, RD) _2i ((RD), 10, (RS1), 1, (IMM))
|
||||||
|
#define UMULCCrrr(RS1, RS2, RD) _2 ((RD), 26, (RS1), 0, 0, (RS2))
|
||||||
|
#define UMULCCrir(RS1, IMM, RD) _2i ((RD), 26, (RS1), 1, (IMM))
|
||||||
|
|
||||||
|
#define WRrri(RS1, RS2, RD) _2 (0, (RD)|0x30, RS1, 0, 0, (RS2))
|
||||||
|
#define WRrii(RS1, IMM, RD) _2i (0, (RD)|0x30, RS1, 1, (IMM))
|
||||||
|
|
||||||
|
#define XORrrr(RS1, RS2, RD) _2 ((RD), 3, (RS1), 0, 0, (RS2))
|
||||||
|
#define XORrir(RS1, IMM, RD) _2i ((RD), 3, (RS1), 1, (IMM))
|
||||||
|
#define XORCCrrr(RS1, RS2, RD) _2 ((RD), 19, (RS1), 0, 0, (RS2))
|
||||||
|
#define XORCCrir(RS1, IMM, RD) _2i ((RD), 19, (RS1), 1, (IMM))
|
||||||
|
|
||||||
|
/* synonyms */
|
||||||
|
|
||||||
|
#define Bi(DISP) BAi((DISP))
|
||||||
|
#define B_Ai(DISP) BA_Ai((DISP))
|
||||||
|
#define BNZi(DISP) BNEi((DISP))
|
||||||
|
#define BNZ_Ai(DISP) BNE_Ai((DISP))
|
||||||
|
#define BZi(DISP) BEi((DISP))
|
||||||
|
#define BZ_Ai(DISP) BE_Ai((DISP))
|
||||||
|
#define BGEUi(DISP) BCCi((DISP))
|
||||||
|
#define BGEU_Ai(DISP) BCC_Ai((DISP))
|
||||||
|
#define BLUi(DISP) BCSi((DISP))
|
||||||
|
#define BLU_Ai(DISP) BCS_Ai((DISP))
|
||||||
|
|
||||||
|
#define LDUWxr(RS1, RS2, RD) LDxr((RS1), (RS2), (RD))
|
||||||
|
#define LDUWmr(RS1, IMM, RD) LDmr((RS1), (IMM), (RD))
|
||||||
|
#define LDSWxr(RS1, RS2, RD) LDxr((RS1), (RS2), (RD))
|
||||||
|
#define LDSWmr(RS1, IMM, RD) LDmr((RS1), (IMM), (RD))
|
||||||
|
|
||||||
|
#define STWrx(RS, RD1, RD2) STrx((RS), (RD1), (RD2))
|
||||||
|
#define STWrm(RS, RD, IMM) STrm((RS), (RD), (IMM))
|
||||||
|
|
||||||
|
/* synthetic instructions [Table A-1, page 85] */
|
||||||
|
|
||||||
|
#define BCLRrr(R,S) ANDNrrr((R), (S), (S))
|
||||||
|
#define BCLRir(I,R) ANDNrir((R), (I), (R))
|
||||||
|
#define BSETrr(R,S) ORrrr((R), (S), (S))
|
||||||
|
#define BSETir(I,R) ORrir((R), (I), (R))
|
||||||
|
#define BTOGrr(R,S) XORrrr((R), (S), (S))
|
||||||
|
#define BTOGir(I,R) XORrir((R), (I), (R))
|
||||||
|
#define BTSTrr(R,S) ANDCCrrr((R), (S), 0)
|
||||||
|
#define BTSTir(I,R) ANDCCrir((R), (I), 0)
|
||||||
|
|
||||||
|
#define CALLm(R,I) JMPLmr((R), (I), _Ro(7))
|
||||||
|
#define CALLx(R,S) JMPLxr((R), (S), _Ro(7))
|
||||||
|
|
||||||
|
#define CLRr(R) ORrrr(0, 0, (R))
|
||||||
|
#define CLRBm(R,I) STBrm(0, (R), (I))
|
||||||
|
#define CLRBx(R,S) STBrm(0, (R), (S))
|
||||||
|
#define CLRHm(R,I) STHrm(0, (R), (I))
|
||||||
|
#define CLRHx(R,S) STHrm(0, (R), (S))
|
||||||
|
#define CLRm(R,I) STrm(0, (R), (I))
|
||||||
|
#define CLRx(R,S) STrm(0, (R), (S))
|
||||||
|
|
||||||
|
#define CMPrr(RS1, RS2) SUBCCrrr((RS1), (RS2), 0)
|
||||||
|
#define CMPri(RS1, IMM) SUBCCrir((RS1), (IMM), 0)
|
||||||
|
|
||||||
|
#define DECr(R) SUBrir((R), 1, (R))
|
||||||
|
#define DECir(I,R) SUBrir((R), (I), (R))
|
||||||
|
#define DECCCr(R) SUBCCrir((R), 1, (R))
|
||||||
|
#define DECCCir(I,R) SUBCCrir((R), (I), (R))
|
||||||
|
|
||||||
|
#define INCr(R) ADDrir((R), 1, (R))
|
||||||
|
#define INCir(I,R) ADDrir((R), (I), (R))
|
||||||
|
#define INCCCr(R) ADDCCrir((R), 1, (R))
|
||||||
|
#define INCCCir(I,R) ADDCCrir((R), (I), (R))
|
||||||
|
|
||||||
|
#define JMPm(R,I) JMPLmr((R), (I), 0)
|
||||||
|
#define JMPx(R,S) JMPLxr((R), (S), 0)
|
||||||
|
|
||||||
|
#define MOVrr(R,S) ORrrr(0, (R), (S))
|
||||||
|
#define MOVir(I, R) ORrir(0, (I), (R))
|
||||||
|
|
||||||
|
#define NEGrr(R,S) SUBrrr(0, (R), (S))
|
||||||
|
#define NEGr(R) SUBrrr(0, (R), (R))
|
||||||
|
#define NOP() SETHIir(0, 0)
|
||||||
|
|
||||||
|
#define NOTrr(R,S) XNORrrr((R), 0, (S))
|
||||||
|
#define NOTr(R) XNORrrr((R), 0, (R))
|
||||||
|
|
||||||
|
#define RESTORE() RESTORErrr(0, 0, 0)
|
||||||
|
#define RET() JMPLmr(_Ri(7),8 ,0)
|
||||||
|
#define RETL() JMPLmr(_Ro(7),8 ,0)
|
||||||
|
|
||||||
|
#define SAVE() SAVErrr(0, 0, 0)
|
||||||
|
#define SETir(I,R) (_siP(13,(I)) ? MOVir((I),(R)) : SETir2(_HI(I), _LO(I), (R)))
|
||||||
|
#define SETir2(H,L,R) (SETHIir(H,R), (L ? ORrir(R,L,R) : 0))
|
||||||
|
|
||||||
|
/* BNZ,a executes the delay instruction if NZ (so skips if Z)
|
||||||
|
* BZ,a executes the delay instruction if Z (so skips if NZ). */
|
||||||
|
#define SKIPZ() _0d (1, 9, 2, 2) /* BNZ,a .+8 */
|
||||||
|
#define SKIPNZ() _0d (1, 1, 2, 2) /* BZ,a .+8 */
|
||||||
|
#define SKIP() _0d (1, 0, 2, 0) /* BN,a . */
|
||||||
|
|
||||||
|
#define TSTr(R) ORCCrrr(0, (R), 0)
|
||||||
|
|
||||||
|
#define WRii(IMM, RD) WRrii(0, (IMM), (RD))
|
||||||
|
#define WRri(RS2, RD) WRrri(0, (RS2), (RD))
|
||||||
|
|
||||||
|
#endif /* __ccg_asm_sparc_h */
|
249
lightning/sparc/core.h
Normal file
249
lightning/sparc/core.h
Normal file
|
@ -0,0 +1,249 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Platform-independent layer (Sparc version)
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __lightning_core_h
|
||||||
|
#define __lightning_core_h
|
||||||
|
|
||||||
|
#define JIT_R0 _Rl(0)
|
||||||
|
#define JIT_R1 _Rl(1)
|
||||||
|
#define JIT_R2 _Rl(2)
|
||||||
|
#define JIT_V0 _Rl(3)
|
||||||
|
#define JIT_V1 _Rl(4)
|
||||||
|
#define JIT_V2 _Rl(5)
|
||||||
|
#define JIT_BIG _Rg(1) /* %g1 used to make 32-bit operands */
|
||||||
|
#define JIT_BIG2 _Rg(2) /* %g2 used to make 32-bit compare operands */
|
||||||
|
#define JIT_SP _Ro(6)
|
||||||
|
#define JIT_RZERO _Rg(0)
|
||||||
|
#define JIT_RET _Ri(0)
|
||||||
|
|
||||||
|
/* Delay slot scheduling: jmp generates branches with annulled delay
|
||||||
|
* slots; we toggle the annul bit if we can fill the slot. CALLs and
|
||||||
|
* cond. branches have a different meaning for the annul bit, so we
|
||||||
|
* automatically generate a NOP and eventually copy the delay insn onto
|
||||||
|
* it. Delay slots in RET are already used for RESTORE, so we don't
|
||||||
|
* schedule them.
|
||||||
|
*
|
||||||
|
* ,--- _jit.x.pc
|
||||||
|
* insn X X before
|
||||||
|
* cmp branch insn X X after (branch)
|
||||||
|
* `--- _jit.x.pc
|
||||||
|
* call insn insn X after (call)
|
||||||
|
* `--- _jit.x.pc
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct jit_local_state {
|
||||||
|
int nextarg_put; /* Next %o reg. to be written */
|
||||||
|
int nextarg_get; /* Next %i reg. to be read */
|
||||||
|
jit_insn delay;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define jit_fill_delay_after(branch) (_jitl.delay = *--_jit.x.pc, \
|
||||||
|
((branch) == _jit.x.pc /* check if NOP was inserted */ \
|
||||||
|
? (_jit.x.pc[-1] ^= 1<<29) /* no if branch, toggle annul bit */ \
|
||||||
|
: (_jit.x.pc[-1] = _jitl.delay)), /* yes if call, replace NOP with delay insn */ \
|
||||||
|
*_jit.x.pc = _jitl.delay, _jit.x.pc - 1) /* return addr of delay insn */
|
||||||
|
|
||||||
|
/* If possible, use the `small' instruction (rs, imm, rd)
|
||||||
|
* else load imm into %l6 and use the `big' instruction (rs, %l6, rd)
|
||||||
|
* jit_chk_imm2 uses %l7 instead of %l6 to avoid conflicts when using delay slots
|
||||||
|
*/
|
||||||
|
#define jit_chk_imm(imm, small, big) (_siP(13,(imm)) ? (small) : (SETir((imm), JIT_BIG), (big)) )
|
||||||
|
#define jit_chk_imm2(imm, small, big) (_siP(13,(imm)) ? (small) : (SETir((imm), JIT_BIG2), (big)) )
|
||||||
|
|
||||||
|
/* Helper macros for branches */
|
||||||
|
#define jit_branchi(rs, is, jmp, nop) (jit_chk_imm2(is, CMPri(rs, is), CMPrr(rs, JIT_BIG2)), jmp, nop, _jit.x.pc - 1)
|
||||||
|
#define jit_branchr(s1, s2, jmp, nop) ( CMPrr(s1, s2), jmp, nop, _jit.x.pc - 1)
|
||||||
|
|
||||||
|
/* Helper macros for boolean tests -- delay slot sets d to 1;
|
||||||
|
* taken branch leaves it to 1, not-taken branch resets it to 0 */
|
||||||
|
#define jit_booli(d, rs, is, jmp) (jit_chk_imm (is, CMPri(rs, is), CMPrr(rs, JIT_BIG)), jmp, MOVir(1, (d)), MOVir(0, (d)))
|
||||||
|
#define jit_boolr(d, s1, s2, jmp) ( CMPrr(s1, s2), jmp, MOVir(1, (d)), MOVir(0, (d)))
|
||||||
|
|
||||||
|
/* Helper macros for division
|
||||||
|
* The architecture specifies that there must be 3 instructions between *
|
||||||
|
* a y register write and a use of it for correct results. */
|
||||||
|
#define jit_prepare_y(rs, is) (SRArir(rs, 31, JIT_BIG), WRri(JIT_BIG, _y), NOP(), NOP(), NOP(), _jit.x.pc -= jit_immsize(is))
|
||||||
|
#define jit_clr_y(rs, is) ( WRri(0, _y), NOP(), NOP(), NOP(), _jit.x.pc -= jit_immsize(is))
|
||||||
|
|
||||||
|
#define jit_mod(div, mul, d, s1, s2) ( \
|
||||||
|
div (JIT_BIG2, s1, s2), \
|
||||||
|
mul (JIT_BIG2, JIT_BIG2, s2), \
|
||||||
|
jit_subr_i (d, s1, JIT_BIG2))
|
||||||
|
|
||||||
|
/* How many instruction are needed to put imm in a register. */
|
||||||
|
#define jit_immsize(imm) (!(imm) ? 0 : \
|
||||||
|
(!_siP((imm), 13) && ((imm) & 0x3ff) ? 2 : 1))
|
||||||
|
|
||||||
|
|
||||||
|
/* branch instructions return the address of the *delay* instruction -- this
|
||||||
|
* is just a helper macro that makes jit_patch more readable.
|
||||||
|
*/
|
||||||
|
#define jit_patch_(jump_pc) \
|
||||||
|
(*jump_pc &= ~_MASK(22), \
|
||||||
|
*jump_pc |= ((_jit_UL(_jit.x.pc) - _jit_UL(jump_pc)) >> 2) & _MASK(22))
|
||||||
|
|
||||||
|
|
||||||
|
#define jit_arg_c() (_jitl.nextarg_get++)
|
||||||
|
#define jit_arg_i() (_jitl.nextarg_get++)
|
||||||
|
#define jit_arg_l() (_jitl.nextarg_get++)
|
||||||
|
#define jit_arg_p() (_jitl.nextarg_get++)
|
||||||
|
#define jit_arg_s() (_jitl.nextarg_get++)
|
||||||
|
#define jit_arg_uc() (_jitl.nextarg_get++)
|
||||||
|
#define jit_arg_ui() (_jitl.nextarg_get++)
|
||||||
|
#define jit_arg_ul() (_jitl.nextarg_get++)
|
||||||
|
#define jit_arg_us() (_jitl.nextarg_get++)
|
||||||
|
#define jit_addi_i(d, rs, is) jit_chk_imm((is), ADDrir((rs), (is), (d)), ADDrrr((rs), JIT_BIG, (d)))
|
||||||
|
#define jit_addr_i(d, s1, s2) ADDrrr((s1), (s2), (d))
|
||||||
|
#define jit_addci_i(d, rs, is) jit_chk_imm((is), ADDCCrir((rs), (is), (d)), ADDCCrrr((rs), JIT_BIG, (d)))
|
||||||
|
#define jit_addcr_i(d, s1, s2) ADDCCrrr((s1), (s2), (d))
|
||||||
|
#define jit_addxi_i(d, rs, is) jit_chk_imm((is), ADDXCCrir((rs), (is), (d)), ADDXCCrrr((rs), JIT_BIG, (d)))
|
||||||
|
#define jit_addxr_i(d, s1, s2) ADDXCCrrr((s1), (s2), (d))
|
||||||
|
#define jit_andi_i(d, rs, is) jit_chk_imm((is), ANDrir((rs), (is), (d)), ANDrrr((rs), JIT_BIG, (d)))
|
||||||
|
#define jit_andr_i(d, s1, s2) ANDrrr((s1), (s2), (d))
|
||||||
|
#define jit_beqi_i(label, rs, is) jit_branchi((rs), (is), BEi((label)), NOP() )
|
||||||
|
#define jit_beqr_i(label, s1, s2) jit_branchr((s1), (s2), BEi((label)), NOP() )
|
||||||
|
#define jit_bgei_i(label, rs, is) jit_branchi((rs), (is), BGEi((label)), NOP() )
|
||||||
|
#define jit_bgei_ui(label, rs, is) jit_branchi((rs), (is), BGEUi((label)), NOP() )
|
||||||
|
#define jit_bger_i(label, s1, s2) jit_branchr((s1), (s2), BGEi((label)), NOP() )
|
||||||
|
#define jit_bger_ui(label, s1, s2) jit_branchr((s1), (s2), BGEUi((label)), NOP() )
|
||||||
|
#define jit_bgti_i(label, rs, is) jit_branchi((rs), (is), BGi((label)), NOP() )
|
||||||
|
#define jit_bgti_ui(label, rs, is) jit_branchi((rs), (is), BGUi((label)), NOP() )
|
||||||
|
#define jit_bgtr_i(label, s1, s2) jit_branchr((s1), (s2), BGi((label)), NOP() )
|
||||||
|
#define jit_bgtr_ui(label, s1, s2) jit_branchr((s1), (s2), BGUi((label)), NOP() )
|
||||||
|
#define jit_blei_i(label, rs, is) jit_branchi((rs), (is), BLEi((label)), NOP() )
|
||||||
|
#define jit_blei_ui(label, rs, is) jit_branchi((rs), (is), BLEUi((label)), NOP() )
|
||||||
|
#define jit_bler_i(label, s1, s2) jit_branchr((s1), (s2), BLEi((label)), NOP() )
|
||||||
|
#define jit_bler_ui(label, s1, s2) jit_branchr((s1), (s2), BLEUi((label)), NOP() )
|
||||||
|
#define jit_blti_i(label, rs, is) jit_branchi((rs), (is), BLi((label)), NOP() )
|
||||||
|
#define jit_blti_ui(label, rs, is) jit_branchi((rs), (is), BLUi((label)), NOP() )
|
||||||
|
#define jit_bltr_i(label, s1, s2) jit_branchr((s1), (s2), BLi((label)), NOP() )
|
||||||
|
#define jit_bltr_ui(label, s1, s2) jit_branchr((s1), (s2), BLUi((label)), NOP() )
|
||||||
|
#define jit_bnei_i(label, rs, is) jit_branchi((rs), (is), BNEi((label)), NOP() )
|
||||||
|
#define jit_bner_i(label, s1, s2) jit_branchr((s1), (s2), BNEi((label)), NOP() )
|
||||||
|
#define jit_bmsi_i(label, rs, is) (jit_chk_imm((is), BTSTir((is), (rs)), BTSTrr((rs), JIT_BIG)), BNEi((label)), NOP(), _jit.x.pc - 1)
|
||||||
|
#define jit_bmci_i(label, rs, is) (jit_chk_imm((is), BTSTir((is), (rs)), BTSTrr((rs), JIT_BIG)), BEi((label)), NOP(), _jit.x.pc - 1)
|
||||||
|
#define jit_bmsr_i(label, s1, s2) ( BTSTrr((s1), (s2)), BNEi((label)), NOP(), _jit.x.pc - 1)
|
||||||
|
#define jit_bmcr_i(label, s1, s2) ( BTSTrr((s1), (s2)), BEi((label)), NOP(), _jit.x.pc - 1)
|
||||||
|
#define jit_boaddi_i(label, rs, is) (jit_chk_imm((is), ADDCCrir((rs), (is), (rs)), ADDCCrrr((rs), JIT_BIG, (rs))), BVSi((label)), NOP(), _jit.x.pc - 1)
|
||||||
|
#define jit_bosubi_i(label, rs, is) (jit_chk_imm((is), SUBCCrir((rs), (is), (rs)), SUBCCrrr((rs), JIT_BIG, (rs))), BVSi((label)), NOP(), _jit.x.pc - 1)
|
||||||
|
#define jit_boaddr_i(label, s1, s2) ( ADDCCrrr((s1), (s2), (s1)), BVSi((label)), NOP(), _jit.x.pc - 1)
|
||||||
|
#define jit_bosubr_i(label, s1, s2) ( SUBCCrrr((s1), (s2), (s1)), BVSi((label)), NOP(), _jit.x.pc - 1)
|
||||||
|
#define jit_boaddi_ui(label, rs, is) (jit_chk_imm((is), ADDCCrir((rs), (is), (rs)), ADDCCrrr((rs), JIT_BIG, (rs))), BCSi((label)), NOP(), _jit.x.pc - 1)
|
||||||
|
#define jit_bosubi_ui(label, rs, is) (jit_chk_imm((is), SUBCCrir((rs), (is), (rs)), SUBCCrrr((rs), JIT_BIG, (rs))), BCSi((label)), NOP(), _jit.x.pc - 1)
|
||||||
|
#define jit_boaddr_ui(label, s1, s2) ( ADDCCrrr((s1), (s2), (s1)), BCSi((label)), NOP(), _jit.x.pc - 1)
|
||||||
|
#define jit_bosubr_ui(label, s1, s2) ( SUBCCrrr((s1), (s2), (s1)), BCSi((label)), NOP(), _jit.x.pc - 1)
|
||||||
|
#define jit_calli(label) (CALLi(label), NOP(), _jit.x.pc - 1)
|
||||||
|
#define jit_divi_i(d, rs, is) (jit_prepare_y((rs), 0x12345678), SETir((is), JIT_BIG), SDIVrrr((rs), JIT_BIG, (d)) )
|
||||||
|
#define jit_divi_ui(d, rs, is) (jit_clr_y((rs)), 0x12345678), SETir((is), JIT_BIG), UDIVrrr((rs), JIT_BIG, (d)) )
|
||||||
|
#define jit_divr_i(d, s1, s2) (jit_prepare_y((s1), 0), SDIVrrr((s1), (s2), (d)))
|
||||||
|
#define jit_divr_ui(d, s1, s2) (jit_clr_y((s1), 0), UDIVrrr((s1), (s2), (d)))
|
||||||
|
#define jit_eqi_i(d, rs, is) jit_chk_imm((is), \
|
||||||
|
(SUBCCrir((rs), (is), (d)), ADDXCCrir((d), -1, JIT_BIG), SUBXrir(0,-1,(d))),\
|
||||||
|
jit_eqr_i(d, rs, JIT_BIG))
|
||||||
|
#define jit_eqr_i(d, s1, s2) (SUBCCrrr((s1), (s2), (d)), ADDXCCrir((d), -1, JIT_BIG), SUBXrir(0,-1,(d)))
|
||||||
|
#define jit_nei_i(d, rs, is) jit_chk_imm((is), \
|
||||||
|
(SUBCCrir((rs), (is), (d)), ADDXCCrir((d), -1, JIT_BIG), ADDXrrr(0,0,(d))),\
|
||||||
|
jit_ner_i(d, rs, JIT_BIG))
|
||||||
|
#define jit_ner_i(d, s1, s2) (SUBCCrrr((s1), (s2), (d)), ADDXCCrir((d), -1, JIT_BIG), ADDXrrr(0,0,(d)))
|
||||||
|
#define jit_gei_i(d, rs, is) jit_booli ((d), (rs), (is), BGEi(_jit.x.pc + 3) )
|
||||||
|
#define jit_gei_ui(d, rs, is) jit_booli ((d), (rs), (is), BGEUi(_jit.x.pc + 3))
|
||||||
|
#define jit_ger_i(d, s1, s2) jit_boolr ((d), (s1), (s2), BGEi(_jit.x.pc + 3) )
|
||||||
|
#define jit_ger_ui(d, s1, s2) jit_boolr ((d), (s1), (s2), BGEUi(_jit.x.pc + 3))
|
||||||
|
#define jit_gti_i(d, rs, is) jit_booli ((d), (rs), (is), BGi(_jit.x.pc + 3) )
|
||||||
|
#define jit_gti_ui(d, rs, is) jit_booli ((d), (rs), (is), BGUi(_jit.x.pc + 3) )
|
||||||
|
#define jit_gtr_i(d, s1, s2) jit_boolr ((d), (s1), (s2), BGi(_jit.x.pc + 3) )
|
||||||
|
#define jit_gtr_ui(d, s1, s2) jit_boolr ((d), (s1), (s2), BGUi(_jit.x.pc + 3) )
|
||||||
|
#define jit_hmuli_i(d, rs, is) (jit_muli_i (JIT_BIG, (rs), (is)), RDir (_y, (d)))
|
||||||
|
#define jit_hmuli_ui(d, rs, is) (jit_muli_ui(JIT_BIG, (rs), (is)), RDir (_y, (d)))
|
||||||
|
#define jit_hmulr_i(d, s1, s2) (jit_mulr_i (JIT_BIG, (s1), (s2)), RDir (_y, (d)))
|
||||||
|
#define jit_hmulr_ui(d, s1, s2) (jit_mulr_ui(JIT_BIG, (s1), (s2)), RDir (_y, (d)))
|
||||||
|
#define jit_jmpi(label) (BA_Ai((label)), _jit.x.pc)
|
||||||
|
#define jit_jmpr(reg) (JMPx(JIT_RZERO, (reg)), NOP(), _jit.x.pc - 1)
|
||||||
|
#define jit_ldxi_c(d, rs, is) jit_chk_imm((is), LDSBmr((rs), (is), (d)), LDSBxr((rs), JIT_BIG, (d)))
|
||||||
|
#define jit_ldxi_i(d, rs, is) jit_chk_imm((is), LDSWmr((rs), (is), (d)), LDSWxr((rs), JIT_BIG, (d)))
|
||||||
|
#define jit_ldxi_s(d, rs, is) jit_chk_imm((is), LDSHmr((rs), (is), (d)), LDSHxr((rs), JIT_BIG, (d)))
|
||||||
|
#define jit_ldxi_uc(d, rs, is) jit_chk_imm((is), LDUBmr((rs), (is), (d)), LDUBxr((rs), JIT_BIG, (d)))
|
||||||
|
#define jit_ldxi_us(d, rs, is) jit_chk_imm((is), LDUHmr((rs), (is), (d)), LDUHxr((rs), JIT_BIG, (d)))
|
||||||
|
#define jit_ldxr_c(d, s1, s2) LDSBxr((s1), (s2), (d))
|
||||||
|
#define jit_ldxr_i(d, s1, s2) LDSWxr((s1), (s2), (d))
|
||||||
|
#define jit_ldxr_s(d, s1, s2) LDSHxr((s1), (s2), (d))
|
||||||
|
#define jit_ldxr_uc(d, s1, s2) LDUBxr((s1), (s2), (d))
|
||||||
|
#define jit_ldxr_us(d, s1, s2) LDUHxr((s1), (s2), (d))
|
||||||
|
#define jit_lei_i(d, rs, is) jit_booli ((d), (rs), (is), BLEi(_jit.x.pc + 3) )
|
||||||
|
#define jit_lei_ui(d, rs, is) jit_booli ((d), (rs), (is), BLEUi(_jit.x.pc + 3))
|
||||||
|
#define jit_ler_i(d, s1, s2) jit_boolr ((d), (s1), (s2), BLEi(_jit.x.pc + 3) )
|
||||||
|
#define jit_ler_ui(d, s1, s2) jit_boolr ((d), (s1), (s2), BLEUi(_jit.x.pc + 3))
|
||||||
|
#define jit_lshi_i(d, rs, is) SLLrir((rs), (is), (d))
|
||||||
|
#define jit_lshr_i(d, r1, r2) SLLrrr((r1), (r2), (d))
|
||||||
|
#define jit_lti_i(d, rs, is) jit_booli ((d), (rs), (is), BLi(_jit.x.pc + 3) )
|
||||||
|
#define jit_lti_ui(d, rs, is) jit_booli ((d), (rs), (is), BLUi(_jit.x.pc + 3) )
|
||||||
|
#define jit_ltr_i(d, s1, s2) jit_boolr ((d), (s1), (s2), BLi(_jit.x.pc + 3) )
|
||||||
|
#define jit_ltr_ui(d, s1, s2) jit_boolr ((d), (s1), (s2), BLUi(_jit.x.pc + 3) )
|
||||||
|
#define jit_modi_i(d, rs, is) jit_modi(jit_divi_i, jit_muli_i, (d), (rs), (is))
|
||||||
|
#define jit_modi_ui(d, rs, is) jit_modi(jit_divi_i, jit_muli_i, (d), (rs), (is))
|
||||||
|
#define jit_modr_i(d, s1, s2) jit_modr(jit_divr_i, jit_mulr_i, (d), (s1), (s2))
|
||||||
|
#define jit_modr_ui(d, s1, s2) jit_modr(jit_divr_i, jit_mulr_i, (d), (s1), (s2))
|
||||||
|
#define jit_movi_i(d, is) SETir((is), (d))
|
||||||
|
#define jit_movr_i(d, rs) MOVrr((rs), (d))
|
||||||
|
#define jit_muli_i(d, rs, is) jit_chk_imm((is), SMULrir((rs), (is), (d)), SMULrrr((rs), JIT_BIG, (d)))
|
||||||
|
#define jit_muli_ui(d, rs, is) jit_chk_imm((is), UMULrir((rs), (is), (d)), UMULrrr((rs), JIT_BIG, (d)))
|
||||||
|
#define jit_mulr_i(d, s1, s2) SMULrrr((s1), (s2), (d))
|
||||||
|
#define jit_mulr_ui(d, s1, s2) UMULrrr((s1), (s2), (d))
|
||||||
|
#define jit_nop() NOP()
|
||||||
|
#define jit_ori_i(d, rs, is) jit_chk_imm((is), ORrir((rs), (is), (d)), ORrrr((rs), JIT_BIG, (d)))
|
||||||
|
#define jit_orr_i(d, s1, s2) ORrrr((s1), (s2), (d))
|
||||||
|
#define jit_patch(delay_pc) jit_patch_ ( ((delay_pc) - 1) )
|
||||||
|
#define jit_popr_i(rs) (LDmr(JIT_SP, 0, (rs)), ADDrir(JIT_SP, 8, JIT_SP))
|
||||||
|
#define jitfp_prepare(numargs, nf, nd) (_jitl.nextarg_put = (numargs))
|
||||||
|
#define jit_prolog(numargs) (SAVErir(JIT_SP, -96, JIT_SP), _jitl.nextarg_get = _Ri(0))
|
||||||
|
#define jit_pushr_i(rs) (STrm((rs), JIT_SP, -8), SUBrir(JIT_SP, 8, JIT_SP))
|
||||||
|
#define jit_pusharg_i(rs) (--_jitl.nextarg_put, MOVrr((rs), _Ro(_jitl.nextarg_put)))
|
||||||
|
#define jit_ret() (RET(), RESTORE())
|
||||||
|
#define jit_retval(rd) MOVrr(_Ro(0), (rd))
|
||||||
|
#define jit_rshi_i(d, rs, is) SRArir((rs), (is), (d))
|
||||||
|
#define jit_rshi_ui(d, rs, is) SRLrir((rs), (is), (d))
|
||||||
|
#define jit_rshr_i(d, r1, r2) SRArrr((r1), (r2), (d))
|
||||||
|
#define jit_rshr_ui(d, r1, r2) SRLrrr((r1), (r2), (d))
|
||||||
|
#define jit_stxi_c(id, rd, rs) jit_chk_imm((id), STBrm((rs), (rd), (id)), STBrx((rs), (rd), JIT_BIG))
|
||||||
|
#define jit_stxi_i(id, rd, rs) jit_chk_imm((id), STWrm((rs), (rd), (id)), STWrx((rs), (rd), JIT_BIG))
|
||||||
|
#define jit_stxi_s(id, rd, rs) jit_chk_imm((id), STHrm((rs), (rd), (id)), STHrx((rs), (rd), JIT_BIG))
|
||||||
|
#define jit_stxr_c(d1, d2, rs) STBrx((rs), (d1), (d2))
|
||||||
|
#define jit_stxr_i(d1, d2, rs) STWrx((rs), (d1), (d2))
|
||||||
|
#define jit_stxr_s(d1, d2, rs) STHrx((rs), (d1), (d2))
|
||||||
|
#define jit_subr_i(d, s1, s2) SUBrrr((s1), (s2), (d))
|
||||||
|
#define jit_subcr_i(d, s1, s2) SUBCCrrr((s1), (s2), (d))
|
||||||
|
#define jit_subxi_i(d, rs, is) jit_chk_imm((is), SUBXCCrir((rs), (is), (d)), SUBXCCrrr((rs), JIT_BIG, (d)))
|
||||||
|
#define jit_subxr_i(d, s1, s2) SUBXCCrrr((s1), (s2), (d))
|
||||||
|
#define jit_xori_i(d, rs, is) jit_chk_imm((is), XORrir((rs), (is), (d)), XORrrr((rs), JIT_BIG, (d)))
|
||||||
|
#define jit_xorr_i(d, s1, s2) XORrrr((s1), (s2), (d))
|
||||||
|
|
||||||
|
#endif /* __lightning_core_h */
|
163
lightning/sparc/fp.h
Normal file
163
lightning/sparc/fp.h
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Run-time assembler & support macros for the PowerPC math unit
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __lightning_asm_fp_h
|
||||||
|
#define __lightning_asm_fp_h
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
/* dummy for now */
|
||||||
|
|
||||||
|
#define _FP1(RD, RS1, OPF, RS2) _2f((RD), 52, (RS1), (OPF), (RS2))
|
||||||
|
#define _FP2(RD, RS1, OPF, RS2) _2f((RD), 53, (RS1), (OPF), (RS2))
|
||||||
|
|
||||||
|
#define FITODrr(FRS, FRD) _FP1((FRD), 0, 200, (FRS))
|
||||||
|
#define FDTOIrr(FRS, FRD) _FP1((FRD), 0, 210, (FRS))
|
||||||
|
#define FSTODrr(FRS, FRD) _FP1((FRD), 0, 201, (FRS))
|
||||||
|
#define FDTOSrr(FRS, FRD) _FP1((FRD), 0, 198, (FRS))
|
||||||
|
#define FMOVSrr(FRS, FRD) _FP1((FRD), 0, 1, (FRS))
|
||||||
|
#define FNEGSrr(FRS, FRD) _FP1((FRD), 0, 5, (FRS))
|
||||||
|
#define FABSSrr(FRS, FRD) _FP1((FRD), 0, 9, (FRS))
|
||||||
|
#define FSQRTDrr(FRS, FRD) _FP1((FRD), 0, 74, (FRS))
|
||||||
|
|
||||||
|
#define FADDDrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 66, (FRS2))
|
||||||
|
#define FSUBDrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 70, (FRS2))
|
||||||
|
#define FMULDrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 82, (FRS2))
|
||||||
|
#define FDIVDrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 86, (FRS2))
|
||||||
|
|
||||||
|
#define FCMPDrr(FRS1, FRS2) _FP2(0, (FRS1), 82, (FRS2))
|
||||||
|
|
||||||
|
#define LDFxr(RS1, RS2, RD) _3 ((RD), 32, (RS1), 0, 0, (RS2))
|
||||||
|
#define LDFmr(RS1, IMM, RD) _3i ((RD), 32, (RS1), 1, (IMM))
|
||||||
|
#define LDDFxr(RS1, RS2, RD) _3 ((RD), 35, (RS1), 0, 0, (RS2))
|
||||||
|
#define LDDFmr(RS1, IMM, RD) _3i ((RD), 35, (RS1), 1, (IMM))
|
||||||
|
#define STFrx(RS, RD1, RD2) _3 ((RS), 36, (RD1), 0, 0, (RD2))
|
||||||
|
#define STFrm(RS, RD1, IMM) _3i ((RS), 36, (RD1), 1, (IMM))
|
||||||
|
#define STDFrx(RS, RD1, RD2) _3 ((RS), 39, (RD1), 0, 0, (RD2))
|
||||||
|
#define STDFrm(RS, RD1, IMM) _3i ((RS), 39, (RD1), 1, (IMM))
|
||||||
|
|
||||||
|
#define FBNi(DISP) _0 (0, 0, 6, (DISP))
|
||||||
|
#define FBN_Ai(DISP) _0 (1, 0, 6, (DISP))
|
||||||
|
#define FBNEi(DISP) _0 (0, 1, 6, (DISP))
|
||||||
|
#define FBNE_Ai(DISP) _0 (1, 1, 6, (DISP))
|
||||||
|
#define FBLGi(DISP) _0 (0, 2, 6, (DISP))
|
||||||
|
#define FBLG_Ai(DISP) _0 (1, 2, 6, (DISP))
|
||||||
|
#define FBULi(DISP) _0 (0, 3, 6, (DISP))
|
||||||
|
#define FBUL_Ai(DISP) _0 (1, 3, 6, (DISP))
|
||||||
|
#define FBLi(DISP) _0 (0, 4, 6, (DISP))
|
||||||
|
#define FBL_Ai(DISP) _0 (1, 4, 6, (DISP))
|
||||||
|
#define FBUGi(DISP) _0 (0, 5, 6, (DISP))
|
||||||
|
#define FBUG_Ai(DISP) _0 (1, 5, 6, (DISP))
|
||||||
|
#define FBGi(DISP) _0 (0, 6, 6, (DISP))
|
||||||
|
#define FBG_Ai(DISP) _0 (1, 6, 6, (DISP))
|
||||||
|
#define FBUi(DISP) _0 (0, 7, 6, (DISP))
|
||||||
|
#define FBU_Ai(DISP) _0 (1, 7, 6, (DISP))
|
||||||
|
#define FBAi(DISP) _0 (0, 8, 6, (DISP))
|
||||||
|
#define FBA_Ai(DISP) _0 (1, 8, 6, (DISP))
|
||||||
|
#define FBEi(DISP) _0 (0, 9, 6, (DISP))
|
||||||
|
#define FBE_Ai(DISP) _0 (1, 9, 6, (DISP))
|
||||||
|
#define FBUEi(DISP) _0 (0, 10, 6, (DISP))
|
||||||
|
#define FBUE_Ai(DISP) _0 (1, 10, 6, (DISP))
|
||||||
|
#define FBGEi(DISP) _0 (0, 11, 6, (DISP))
|
||||||
|
#define FBGE_Ai(DISP) _0 (1, 11, 6, (DISP))
|
||||||
|
#define FBUGEi(DISP) _0 (0, 12, 6, (DISP))
|
||||||
|
#define FBUGE_Ai(DISP) _0 (1, 12, 6, (DISP))
|
||||||
|
#define FBLEi(DISP) _0 (0, 13, 6, (DISP))
|
||||||
|
#define FBLE_Ai(DISP) _0 (1, 13, 6, (DISP))
|
||||||
|
#define FBULEi(DISP) _0 (0, 14, 6, (DISP))
|
||||||
|
#define FBULE_Ai(DISP) _0 (1, 14, 6, (DISP))
|
||||||
|
#define FBOi(DISP) _0 (0, 15, 6, (DISP))
|
||||||
|
#define FBO_Ai(DISP) _0 (1, 15, 6, (DISP))
|
||||||
|
|
||||||
|
#define FSKIPUG() _0d (1, 13, 6, 2) /* fble,a .+8 */
|
||||||
|
#define FSKIPUL() _0d (1, 11, 6, 2) /* fbge,a .+8 */
|
||||||
|
|
||||||
|
#define jit_add_two(reg0) FADDDrrr(30 - (reg0) * 2, 28 - (reg0) * 2, 30 - (reg0) * 2)
|
||||||
|
#define jit_sub_two(reg0) FSUBDrrr(30 - (reg0) * 2, 28 - (reg0) * 2, 30 - (reg0) * 2)
|
||||||
|
#define jit_mul_two(reg0) FMULDrrr(30 - (reg0) * 2, 28 - (reg0) * 2, 30 - (reg0) * 2)
|
||||||
|
#define jit_div_two(reg0) FDIVDrrr(30 - (reg0) * 2, 28 - (reg0) * 2, 30 - (reg0) * 2)
|
||||||
|
|
||||||
|
#define jit_abs(reg0) FABSSrr(30 - (reg0) * 2, 30 - (reg0) * 2)
|
||||||
|
#define jit_neg(reg0) FNEGSrr(30 - (reg0) * 2, 30 - (reg0) * 2)
|
||||||
|
#define jit_sqrt(reg0) FSQRTDrr(30 - (reg0) * 2, 30 - (reg0) * 2)
|
||||||
|
|
||||||
|
#define jit_fpimm(reg0, first, second) \
|
||||||
|
(_1(4), NOP(), _jit_L(first), _jit_L(second), \
|
||||||
|
jit_ldxi_d((reg0), _Ro(7), 8))
|
||||||
|
|
||||||
|
#define jit_ldxi_f(reg0, rs, is) (jit_chk_imm((is), LDFmr((rs), (is), 30 - (reg0) * 2), LDFxr((rs), JIT_BIG, 30 - (reg0) * 2)), FSTODrr(30 - (reg0) * 2, 30 - (reg0) * 2))
|
||||||
|
#define jit_ldxi_d(reg0, rs, is) jit_chk_imm((is), LDDFmr((rs), (is), 30 - (reg0) * 2), LDDFxr((rs), JIT_BIG, 30 - (reg0) * 2))
|
||||||
|
#define jit_ldxr_f(reg0, s1, s2) (LDFxr((s1), (s2), 30 - (reg0) * 2), FSTODrr(30 - (reg0) * 2, 30 - (reg0) * 2))
|
||||||
|
#define jit_ldxr_d(reg0, s1, s2) LDDFxr((s1), (s2), 30 - (reg0) * 2)
|
||||||
|
#define jit_stxi_f(id, rd, reg0) (FDTOSrr(30 - (reg0) * 2, 30 - (reg0) * 2), jit_chk_imm((id), STFrm(30 - (reg0) * 2, (rd), (id)), STFrx(30 - (reg0) * 2, (rd), JIT_BIG)))
|
||||||
|
#define jit_stxi_d(id, rd, reg0) jit_chk_imm((id), STDFrm(30 - (reg0) * 2, (rd), (id)), STDFrx(30 - (reg0) * 2, (rd), JIT_BIG))
|
||||||
|
#define jit_stxr_f(d1, d2, reg0) (FDTOSrr(30 - (reg0) * 2, 30 - (reg0) * 2), STFrx (30 - (reg0) * 2, (d1), (d2)))
|
||||||
|
#define jit_stxr_d(d1, d2, reg0) STDFrx(30 - (reg0) * 2, (d1), (d2))
|
||||||
|
|
||||||
|
|
||||||
|
#define jit_do_round(mode, rd, freg) ( \
|
||||||
|
_1(3), \
|
||||||
|
SETHIir(_HI(mode << 29), JIT_BIG), \
|
||||||
|
NOP(), \
|
||||||
|
STFSRm(_Ro(7), 8), /* store fsr */ \
|
||||||
|
LDmr(_Ro(7), 8, rd), \
|
||||||
|
XORrrr(rd, JIT_BIG, JIT_BIG), /* adjust mode */ \
|
||||||
|
STrm(JIT_BIG, _Ro(7), 8), \
|
||||||
|
LDFSRm(_Ro(7), 8), /* load fsr */ \
|
||||||
|
FDTOIrr(freg, freg), /* truncate */ \
|
||||||
|
STrm(rd, _Ro(7), 8), /* load old fsr */ \
|
||||||
|
LDFSRm(_Ro(7), 8), \
|
||||||
|
STFrm(freg, _Ro(7), 8), /* store truncated value */ \
|
||||||
|
LDmr(_Ro(7), 8, rd)) /* load it into rd */
|
||||||
|
|
||||||
|
|
||||||
|
/* call delay slot data ,--- call lands here */
|
||||||
|
#define jit_exti_d(reg0, rs) (_1(3), NOP(), NOP(), STrm((rs), _Ro(7), 8), LDFmr(_Ro(7), 8, 30 - (reg0) * 2), FITODrr(30 - (reg0) * 2, 30 - (reg0) * 2))
|
||||||
|
#define jit_round(rd, reg0) (_1(3), FDTOIrr(30 - (reg0) * 2, 30 - (reg0) * 2), NOP(), STFrm(30 - (reg0) * 2, _Ro(7), 8), LDmr(_Ro(7), 8, (rd)))
|
||||||
|
#define jit_floor(rd, reg0) jit_do_round(3, (rd), (30 - (reg0) * 2))
|
||||||
|
#define jit_ceil(rd, reg0) jit_do_round(2, (rd), (30 - (reg0) * 2))
|
||||||
|
#define jit_trunc(rd, reg0) jit_do_round(1, (rd), (30 - (reg0) * 2))
|
||||||
|
|
||||||
|
static double jit_zero = 0.0;
|
||||||
|
|
||||||
|
#define jit_cmp(le, ge, reg0) (SETHIir(_HI(_jit_UL(&jit_zero)), (le)), \
|
||||||
|
LDDFmr((le), _LO(_jit_UL(&jit_zero)), 28 - (reg0) * 2), \
|
||||||
|
FCMPDrr(30 - (reg0) * 2, 28 - (reg0) * 2), \
|
||||||
|
MOVir(0, (le)), MOVir(0, (ge)), \
|
||||||
|
FSKIPUL(), MOVir(1, (ge)), \
|
||||||
|
FSKIPUG(), MOVir(1, (le)))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __lightning_asm_fp_h */
|
65
lightning/sparc/funcs.h
Normal file
65
lightning/sparc/funcs.h
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Platform-independent layer inline functions (Sparc)
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __lightning_funcs_h
|
||||||
|
#define __lightning_funcs_h
|
||||||
|
|
||||||
|
#if !defined(__GNUC__) && !defined(__GNUG__)
|
||||||
|
#error Go get GNU C, I do not know how to flush the cache
|
||||||
|
#error with this compiler.
|
||||||
|
#else
|
||||||
|
/* Why doesn't this compile?!?
|
||||||
|
* static void
|
||||||
|
* jit_flush_code(start, end)
|
||||||
|
* void *start;
|
||||||
|
* void *end;
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
jit_flush_code(void* start, void* end)
|
||||||
|
{
|
||||||
|
#ifndef LIGHTNING_CROSS
|
||||||
|
register char *dest;
|
||||||
|
|
||||||
|
__asm__ __volatile__ ("stbar");
|
||||||
|
for (dest = (char *)start; dest <= (char *)end; dest += 4) {
|
||||||
|
__asm__ __volatile__ ("flush %0"::"r"(dest));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [SPARC Architecture Manual v8, page 139, implementation note #5] */
|
||||||
|
__asm__ __volatile__ ("nop; nop; nop; nop; nop");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __lightning_core_h */
|
226
lightningize.in
Normal file
226
lightningize.in
Normal file
|
@ -0,0 +1,226 @@
|
||||||
|
#! /bin/sh
|
||||||
|
# lightningize - Prepare a package to use lightning.
|
||||||
|
# Generated automatically from lightningize.in by configure.
|
||||||
|
# Copyright (C) 1996-2000 Free Software Foundation, Inc.
|
||||||
|
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
# General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
#
|
||||||
|
# As a special exception to the GNU General Public License, if you
|
||||||
|
# distribute this file as part of a program that contains a
|
||||||
|
# configuration script generated by Autoconf, you may include it under
|
||||||
|
# the same distribution terms that you use for the rest of that program.
|
||||||
|
|
||||||
|
# The name of this program.
|
||||||
|
progname=`echo "$0" | sed 's%^.*/%%'`
|
||||||
|
|
||||||
|
# Constants.
|
||||||
|
PROGRAM=lightningize
|
||||||
|
PACKAGE=@PACKAGE@
|
||||||
|
VERSION=@VERSION@
|
||||||
|
|
||||||
|
# Directory names.
|
||||||
|
prefix=@prefix@
|
||||||
|
datadir=@datadir@
|
||||||
|
includedir=@includedir@
|
||||||
|
pkgdatadir=${datadir}/lightning
|
||||||
|
pkgincludedir=${includedir}/lightning
|
||||||
|
aclocaldir=${datadir}/aclocal
|
||||||
|
|
||||||
|
BACKENDS="@BACKENDS@"
|
||||||
|
file_base_names="asm core funcs fp"
|
||||||
|
macro_name=LIGHTNING_CONFIGURE_IF_NOT_FOUND
|
||||||
|
lightning_m4="$aclocaldir/lightning.m4"
|
||||||
|
|
||||||
|
# Global variables.
|
||||||
|
automake=
|
||||||
|
copy=
|
||||||
|
force=
|
||||||
|
configure_ac=
|
||||||
|
status=0
|
||||||
|
dry_run=no
|
||||||
|
help="Try \`$progname --help' for more information."
|
||||||
|
rm="rm -f"
|
||||||
|
ln_s="@LN_S@"
|
||||||
|
cp="cp -f"
|
||||||
|
mkdir="mkdir"
|
||||||
|
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
case "$arg" in
|
||||||
|
--help)
|
||||||
|
cat <<EOF
|
||||||
|
Usage: $progname [OPTION]...
|
||||||
|
|
||||||
|
Prepare a package to use lightning.
|
||||||
|
|
||||||
|
--automake work silently, and assume that Automake is in use
|
||||||
|
-c, --copy copy files rather than symlinking them
|
||||||
|
--debug enable verbose shell tracing
|
||||||
|
-n, --dry-run print commands rather than running them
|
||||||
|
-f, --force replace existing files
|
||||||
|
--help display this message and exit
|
||||||
|
--version print version information and exit
|
||||||
|
|
||||||
|
You must \`cd' to the top directory of your package before you run
|
||||||
|
\`$progname'.
|
||||||
|
EOF
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
--version)
|
||||||
|
echo "$PROGRAM (GNU $PACKAGE) $VERSION"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
--automake)
|
||||||
|
automake=yes
|
||||||
|
;;
|
||||||
|
|
||||||
|
-c | --copy)
|
||||||
|
ln_s=
|
||||||
|
;;
|
||||||
|
|
||||||
|
--debug)
|
||||||
|
echo "$progname: enabling shell trace mode"
|
||||||
|
set -x
|
||||||
|
;;
|
||||||
|
|
||||||
|
-n | --dry-run)
|
||||||
|
if test "$dry_run" != yes; then
|
||||||
|
dry_run=yes
|
||||||
|
rm="echo $rm"
|
||||||
|
test -n "$ln_s" && ln_s="echo $ln_s"
|
||||||
|
cp="echo $cp"
|
||||||
|
mkdir="echo $mkdir"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
-f | --force)
|
||||||
|
force=yes
|
||||||
|
;;
|
||||||
|
|
||||||
|
-*)
|
||||||
|
echo "$progname: unrecognized option \`$arg'" 1>&2
|
||||||
|
echo "$help" 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "$progname: too many arguments" 1>&2
|
||||||
|
echo "$help" 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if test -f configure.ac; then
|
||||||
|
configure_ac=configure.ac
|
||||||
|
elif test -f configure.in; then
|
||||||
|
configure_ac=configure.in
|
||||||
|
else
|
||||||
|
echo "$progname: \`configure.ac' does not exist" 1>&2
|
||||||
|
echo "$help" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test -z "$automake"; then
|
||||||
|
if egrep "^$macro_name" $configure_ac >/dev/null 2>&1; then :
|
||||||
|
else
|
||||||
|
echo "Remember to add \`$macro_name' to \`$configure_ac'."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if grep 'generated automatically by aclocal' aclocal.m4 >/dev/null 2>&1; then
|
||||||
|
updatemsg="update your \`aclocal.m4' by running aclocal"
|
||||||
|
else
|
||||||
|
updatemsg="add the contents of \`$lightning_m4' to \`aclocal.m4'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if egrep '^AC_DEFUN\(\['$macro_name aclocal.m4 >/dev/null 2>&1; then
|
||||||
|
# Check the version number on lightning.m4 and the one used in aclocal.m4.
|
||||||
|
instserial=`grep '^# serial ' $lightning_m4 | grep $macro_name | sed -e 's/^# serial \([0-9][0-9]*\).*$/\1/; q'`
|
||||||
|
|
||||||
|
if test -z "$instserial"; then
|
||||||
|
echo "$progname: warning: no serial number on \`$lightning_m4'" 1>&2
|
||||||
|
else
|
||||||
|
# If the local macro has no serial number, we assume it's ancient.
|
||||||
|
localserial=`grep '^# serial ' aclocal.m4 | grep $macro_name | sed -e 's/^# serial \([0-9][0-9]*\).*$/\1/; q'`
|
||||||
|
|
||||||
|
test -z "$localserial" && localserial=0
|
||||||
|
|
||||||
|
if test "$localserial" -lt "$instserial"; then
|
||||||
|
echo "You should $updatemsg."
|
||||||
|
elif test "$localserial" -gt "$instserial"; then
|
||||||
|
echo "$progname: \`$lightning_m4' is serial $instserial, less than $localserial in \`aclocal.m4'" 1>&2
|
||||||
|
if test -z "$force"; then
|
||||||
|
echo "Use \`--force' to replace newer lightning files with this version." 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "To remain compatible, you should $updatemsg."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "You should $updatemsg."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create the list of directories and files to be updated
|
||||||
|
# Syntax is DESTINATION-DIRECTORY:ABSOLUTE-SRC-PATH
|
||||||
|
|
||||||
|
dirs="lightning"
|
||||||
|
files="lightning:$includedir/lightning.h lightning:$pkgdatadir/Makefile.am"
|
||||||
|
for i in $file_base_names; do
|
||||||
|
files="$files lightning:$pkgincludedir/$i-common.h"
|
||||||
|
done
|
||||||
|
for j in $BACKENDS; do
|
||||||
|
dirs="$dirs lightning/$j"
|
||||||
|
for i in $file_base_names; do
|
||||||
|
files="$files lightning/$j:$pkgincludedir/$j/$i.h"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
for dir in $dirs; do
|
||||||
|
if $mkdir $dir; then :
|
||||||
|
else
|
||||||
|
echo "$progname: cannot create \`$dir'" 1>&2
|
||||||
|
status=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
for file in $files; do
|
||||||
|
base=`echo $file | sed 's%^.*/%%' `
|
||||||
|
src=`echo $file | sed 's/^.*://' `
|
||||||
|
dest=`echo $file | sed 's/:.*//' `/$base
|
||||||
|
if test -f "$dest" && test -z "$force"; then
|
||||||
|
test -z "$automake" && echo "$progname: \`$dest' exists: use \`--force' to overwrite" 1>&2
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
$rm $dest
|
||||||
|
if test -n "$ln_s" && $ln_s $src $dest; then :
|
||||||
|
elif $cp $src $dest; then :
|
||||||
|
else
|
||||||
|
echo "$progname: cannot copy \`$src' to \`$dest'" 1>&2
|
||||||
|
status=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
exit $status
|
||||||
|
|
||||||
|
# Local Variables:
|
||||||
|
# mode:shell-script
|
||||||
|
# sh-indentation:2
|
||||||
|
# End:
|
7
opcode/Makefile.am
Normal file
7
opcode/Makefile.am
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
EXTRA_LIBRARIES = libdisass.a
|
||||||
|
noinst_LIBRARIES = @LIBDISASS@
|
||||||
|
|
||||||
|
libdisass_a_SOURCES = dis-buf.c i386-dis.c ppc-dis.c ppc-opc.c sparc-dis.c \
|
||||||
|
sparc-opc.c disass.c
|
||||||
|
|
||||||
|
noinst_HEADERS = ansidecl.h bfd.h dis-asm.h i386.h ppc.h sparc.h sysdep.h
|
13
opcode/ansidecl.h
Normal file
13
opcode/ansidecl.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#ifndef __ANSIDECL_H_SEEN
|
||||||
|
#define __ANSIDECL_H_SEEN
|
||||||
|
|
||||||
|
#ifdef __STDC__
|
||||||
|
#define PARAMS(x) x
|
||||||
|
typedef void *PTR;
|
||||||
|
#else
|
||||||
|
#define CONST const
|
||||||
|
#define PARAMS(x) ()
|
||||||
|
typedef char *PTR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
185
opcode/bfd.h
Normal file
185
opcode/bfd.h
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
/* Main header file for the bfd library -- portable access to object files.
|
||||||
|
Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
|
||||||
|
Contributed by Cygnus Support.
|
||||||
|
|
||||||
|
This file is part of BFD, the Binary File Descriptor library.
|
||||||
|
(Simplified and modified for GNU lightning)
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
/* bfd.h -- The only header file required by users of the bfd library
|
||||||
|
|
||||||
|
The bfd.h file is generated from bfd-in.h and various .c files; if you
|
||||||
|
change it, your changes will probably be lost.
|
||||||
|
|
||||||
|
All the prototypes and definitions following the comment "THE FOLLOWING
|
||||||
|
IS EXTRACTED FROM THE SOURCE" are extracted from the source files for
|
||||||
|
BFD. If you change it, someone oneday will extract it from the source
|
||||||
|
again, and your changes will be lost. To save yourself from this bind,
|
||||||
|
change the definitions in the source in the bfd directory. Type "make
|
||||||
|
docs" and then "make headers" in that directory, and magically this file
|
||||||
|
will change to reflect your changes.
|
||||||
|
|
||||||
|
If you don't have the tools to perform the extraction, then you are
|
||||||
|
safe from someone on your system trampling over your header files.
|
||||||
|
You should still maintain the equivalence between the source and this
|
||||||
|
file though; every change you make to the .c file should be reflected
|
||||||
|
here. */
|
||||||
|
|
||||||
|
#ifndef __BFD_H_SEEN__
|
||||||
|
#define __BFD_H_SEEN__
|
||||||
|
|
||||||
|
#include "ansidecl.h"
|
||||||
|
|
||||||
|
#ifndef INLINE
|
||||||
|
#if __GNUC__ >= 2
|
||||||
|
#define INLINE __inline__
|
||||||
|
#else
|
||||||
|
#define INLINE
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* To squelch erroneous compiler warnings ("illegal pointer
|
||||||
|
combination") from the SVR3 compiler, we would like to typedef
|
||||||
|
boolean to int (it doesn't like functions which return boolean.
|
||||||
|
Making sure they are never implicitly declared to return int
|
||||||
|
doesn't seem to help). But this file is not configured based on
|
||||||
|
the host. */
|
||||||
|
/* General rules: functions which are boolean return true on success
|
||||||
|
and false on failure (unless they're a predicate). -- bfd.doc */
|
||||||
|
/* I'm sure this is going to break something and someone is going to
|
||||||
|
force me to change it. */
|
||||||
|
/* typedef enum boolean {false, true} boolean; */
|
||||||
|
/* Yup, SVR4 has a "typedef enum boolean" in <sys/types.h> -fnf */
|
||||||
|
/* It gets worse if the host also defines a true/false enum... -sts */
|
||||||
|
/* And even worse if your compiler has built-in boolean types... -law */
|
||||||
|
#if defined (__GNUG__) && (__GNUC_MINOR__ > 5)
|
||||||
|
#define TRUE_FALSE_ALREADY_DEFINED
|
||||||
|
#endif
|
||||||
|
#ifdef MPW
|
||||||
|
/* Pre-emptive strike - get the file with the enum. */
|
||||||
|
#include <Types.h>
|
||||||
|
#define TRUE_FALSE_ALREADY_DEFINED
|
||||||
|
#endif /* MPW */
|
||||||
|
#ifndef TRUE_FALSE_ALREADY_DEFINED
|
||||||
|
typedef enum bfd_boolean {false, true} boolean;
|
||||||
|
#define BFD_TRUE_FALSE
|
||||||
|
#else
|
||||||
|
/* Use enum names that will appear nowhere else. */
|
||||||
|
typedef enum bfd_boolean {bfd_fffalse, bfd_tttrue} boolean;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* A pointer to a position in a file. */
|
||||||
|
/* FIXME: This should be using off_t from <sys/types.h>.
|
||||||
|
For now, try to avoid breaking stuff by not including <sys/types.h> here.
|
||||||
|
This will break on systems with 64-bit file offsets (e.g. 4.4BSD).
|
||||||
|
Probably the best long-term answer is to avoid using file_ptr AND off_t
|
||||||
|
in this header file, and to handle this in the BFD implementation
|
||||||
|
rather than in its interface. */
|
||||||
|
/* typedef off_t file_ptr; */
|
||||||
|
typedef long int file_ptr;
|
||||||
|
|
||||||
|
/* Represent a target address. Also used as a generic unsigned type
|
||||||
|
which is guaranteed to be big enough to hold any arithmetic types
|
||||||
|
we need to deal with. */
|
||||||
|
typedef unsigned long bfd_vma;
|
||||||
|
|
||||||
|
/* A generic signed type which is guaranteed to be big enough to hold any
|
||||||
|
arithmetic types we need to deal with. Can be assumed to be compatible
|
||||||
|
with bfd_vma in the same way that signed and unsigned ints are compatible
|
||||||
|
(as parameters, in assignment, etc). */
|
||||||
|
typedef long bfd_signed_vma;
|
||||||
|
|
||||||
|
typedef unsigned long symvalue;
|
||||||
|
typedef unsigned long bfd_size_type;
|
||||||
|
|
||||||
|
/* Print a bfd_vma x on stream s. */
|
||||||
|
#define fprintf_vma(s,x) fprintf(s, "%08lx", x)
|
||||||
|
#define sprintf_vma(s,x) sprintf(s, "%08lx", x)
|
||||||
|
#define printf_vma(x) fprintf_vma(stdout,x)
|
||||||
|
|
||||||
|
typedef unsigned int flagword; /* 32 bits of flags */
|
||||||
|
typedef unsigned char bfd_byte;
|
||||||
|
|
||||||
|
enum bfd_architecture
|
||||||
|
{
|
||||||
|
bfd_arch_unknown, /* File arch not known */
|
||||||
|
bfd_arch_obscure, /* Arch known, not one of these */
|
||||||
|
bfd_arch_m68k, /* Motorola 68xxx */
|
||||||
|
bfd_arch_vax, /* DEC Vax */
|
||||||
|
bfd_arch_i960, /* Intel 960 */
|
||||||
|
/* The order of the following is important.
|
||||||
|
lower number indicates a machine type that
|
||||||
|
only accepts a subset of the instructions
|
||||||
|
available to machines with higher numbers.
|
||||||
|
The exception is the "ca", which is
|
||||||
|
incompatible with all other machines except
|
||||||
|
"core". */
|
||||||
|
|
||||||
|
#define bfd_mach_i960_core 1
|
||||||
|
#define bfd_mach_i960_ka_sa 2
|
||||||
|
#define bfd_mach_i960_kb_sb 3
|
||||||
|
#define bfd_mach_i960_mc 4
|
||||||
|
#define bfd_mach_i960_xa 5
|
||||||
|
#define bfd_mach_i960_ca 6
|
||||||
|
#define bfd_mach_i960_jx 7
|
||||||
|
#define bfd_mach_i960_hx 8
|
||||||
|
|
||||||
|
bfd_arch_a29k, /* AMD 29000 */
|
||||||
|
bfd_arch_sparc, /* SPARC */
|
||||||
|
#define bfd_mach_sparc 1
|
||||||
|
/* The difference between v8plus and v9 is that v9 is a true 64 bit env. */
|
||||||
|
#define bfd_mach_sparc_v8plus 2
|
||||||
|
#define bfd_mach_sparc_v8plusa 3 /* with ultrasparc add'ns */
|
||||||
|
#define bfd_mach_sparc_v9 4
|
||||||
|
#define bfd_mach_sparc_v9a 5 /* with ultrasparc add'ns */
|
||||||
|
/* Nonzero if MACH has the v9 instruction set. */
|
||||||
|
#define bfd_mach_sparc_v9_p(mach) ((mach) != bfd_mach_sparc)
|
||||||
|
bfd_arch_mips, /* MIPS Rxxxx */
|
||||||
|
bfd_arch_i386, /* Intel 386 */
|
||||||
|
bfd_arch_we32k, /* AT&T WE32xxx */
|
||||||
|
bfd_arch_tahoe, /* CCI/Harris Tahoe */
|
||||||
|
bfd_arch_i860, /* Intel 860 */
|
||||||
|
bfd_arch_romp, /* IBM ROMP PC/RT */
|
||||||
|
bfd_arch_alliant, /* Alliant */
|
||||||
|
bfd_arch_convex, /* Convex */
|
||||||
|
bfd_arch_m88k, /* Motorola 88xxx */
|
||||||
|
bfd_arch_pyramid, /* Pyramid Technology */
|
||||||
|
bfd_arch_h8300, /* Hitachi H8/300 */
|
||||||
|
#define bfd_mach_h8300 1
|
||||||
|
#define bfd_mach_h8300h 2
|
||||||
|
bfd_arch_powerpc, /* PowerPC */
|
||||||
|
bfd_arch_rs6000, /* IBM RS/6000 */
|
||||||
|
bfd_arch_hppa, /* HP PA RISC */
|
||||||
|
bfd_arch_z8k, /* Zilog Z8000 */
|
||||||
|
#define bfd_mach_z8001 1
|
||||||
|
#define bfd_mach_z8002 2
|
||||||
|
bfd_arch_h8500, /* Hitachi H8/500 */
|
||||||
|
bfd_arch_sh, /* Hitachi SH */
|
||||||
|
bfd_arch_alpha, /* Dec Alpha */
|
||||||
|
bfd_arch_arm, /* Advanced Risc Machines ARM */
|
||||||
|
bfd_arch_ns32k, /* National Semiconductors ns32000 */
|
||||||
|
bfd_arch_w65, /* WDC 65816 */
|
||||||
|
bfd_arch_last
|
||||||
|
};
|
||||||
|
|
||||||
|
enum bfd_endian { BFD_ENDIAN_UNKNOWN };
|
||||||
|
|
||||||
|
typedef struct bfd bfd;
|
||||||
|
|
||||||
|
#define bfd_getb32(x) *((int *)(x))
|
||||||
|
#define bfd_getl32(x) *((int *)(x))
|
||||||
|
|
||||||
|
#endif
|
175
opcode/dis-asm.h
Normal file
175
opcode/dis-asm.h
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
/* Interface between the opcode library and its callers.
|
||||||
|
Written by Cygnus Support, 1993.
|
||||||
|
|
||||||
|
The opcode library (libopcodes.a) provides instruction decoders for
|
||||||
|
a large variety of instruction sets, callable with an identical
|
||||||
|
interface, for making instruction-processing programs more independent
|
||||||
|
of the instruction set being processed. */
|
||||||
|
|
||||||
|
#ifndef DIS_ASM_H
|
||||||
|
#define DIS_ASM_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "bfd.h"
|
||||||
|
|
||||||
|
typedef int (*fprintf_ftype) PARAMS((FILE*, const char*, ...));
|
||||||
|
|
||||||
|
enum dis_insn_type {
|
||||||
|
dis_noninsn, /* Not a valid instruction */
|
||||||
|
dis_nonbranch, /* Not a branch instruction */
|
||||||
|
dis_branch, /* Unconditional branch */
|
||||||
|
dis_condbranch, /* Conditional branch */
|
||||||
|
dis_jsr, /* Jump to subroutine */
|
||||||
|
dis_condjsr, /* Conditional jump to subroutine */
|
||||||
|
dis_dref, /* Data reference instruction */
|
||||||
|
dis_dref2 /* Two data references in instruction */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This struct is passed into the instruction decoding routine,
|
||||||
|
and is passed back out into each callback. The various fields are used
|
||||||
|
for conveying information from your main routine into your callbacks,
|
||||||
|
for passing information into the instruction decoders (such as the
|
||||||
|
addresses of the callback functions), or for passing information
|
||||||
|
back from the instruction decoders to their callers.
|
||||||
|
|
||||||
|
It must be initialized before it is first passed; this can be done
|
||||||
|
by hand, or using one of the initialization macros below. */
|
||||||
|
|
||||||
|
typedef struct disassemble_info {
|
||||||
|
fprintf_ftype fprintf_func;
|
||||||
|
FILE *stream;
|
||||||
|
PTR application_data;
|
||||||
|
|
||||||
|
/* Target description. We could replace this with a pointer to the bfd,
|
||||||
|
but that would require one. There currently isn't any such requirement
|
||||||
|
so to avoid introducing one we record these explicitly. */
|
||||||
|
/* The bfd_arch value. */
|
||||||
|
enum bfd_architecture arch;
|
||||||
|
/* The bfd_mach value. */
|
||||||
|
unsigned long mach;
|
||||||
|
/* Endianness (for bi-endian cpus). Mono-endian cpus can ignore this. */
|
||||||
|
enum bfd_endian endian;
|
||||||
|
|
||||||
|
/* For use by the disassembler.
|
||||||
|
The top 16 bits are reserved for public use (and are documented here).
|
||||||
|
The bottom 16 bits are for the internal use of the disassembler. */
|
||||||
|
unsigned long flags;
|
||||||
|
PTR private_data;
|
||||||
|
|
||||||
|
/* Function used to get bytes to disassemble. MEMADDR is the
|
||||||
|
address of the stuff to be disassembled, MYADDR is the address to
|
||||||
|
put the bytes in, and LENGTH is the number of bytes to read.
|
||||||
|
INFO is a pointer to this struct.
|
||||||
|
Returns an errno value or 0 for success. */
|
||||||
|
int (*read_memory_func)
|
||||||
|
PARAMS ((bfd_vma memaddr, bfd_byte *myaddr, int length,
|
||||||
|
struct disassemble_info *info));
|
||||||
|
|
||||||
|
/* Function which should be called if we get an error that we can't
|
||||||
|
recover from. STATUS is the errno value from read_memory_func and
|
||||||
|
MEMADDR is the address that we were trying to read. INFO is a
|
||||||
|
pointer to this struct. */
|
||||||
|
void (*memory_error_func)
|
||||||
|
PARAMS ((int status, bfd_vma memaddr, struct disassemble_info *info));
|
||||||
|
|
||||||
|
/* Function called to print ADDR. */
|
||||||
|
void (*print_address_func)
|
||||||
|
PARAMS ((bfd_vma addr, struct disassemble_info *info));
|
||||||
|
|
||||||
|
/* These are for buffer_read_memory. */
|
||||||
|
bfd_byte *buffer;
|
||||||
|
bfd_vma buffer_vma;
|
||||||
|
int buffer_length;
|
||||||
|
|
||||||
|
/* Results from instruction decoders. Not all decoders yet support
|
||||||
|
this information. This info is set each time an instruction is
|
||||||
|
decoded, and is only valid for the last such instruction.
|
||||||
|
|
||||||
|
To determine whether this decoder supports this information, set
|
||||||
|
insn_info_valid to 0, decode an instruction, then check it. */
|
||||||
|
|
||||||
|
char insn_info_valid; /* Branch info has been set. */
|
||||||
|
char branch_delay_insns; /* How many sequential insn's will run before
|
||||||
|
a branch takes effect. (0 = normal) */
|
||||||
|
char data_size; /* Size of data reference in insn, in bytes */
|
||||||
|
enum dis_insn_type insn_type; /* Type of instruction */
|
||||||
|
bfd_vma target; /* Target address of branch or dref, if known;
|
||||||
|
zero if unknown. */
|
||||||
|
bfd_vma target2; /* Second target address for dref2 */
|
||||||
|
|
||||||
|
} disassemble_info;
|
||||||
|
|
||||||
|
|
||||||
|
/* Standard disassemblers. Disassemble one instruction at the given
|
||||||
|
target address. Return number of bytes processed. */
|
||||||
|
typedef int (*disassembler_ftype)
|
||||||
|
PARAMS((bfd_vma, disassemble_info *));
|
||||||
|
|
||||||
|
extern int print_insn_big_mips PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_little_mips PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_i386 PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_m68k PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_z8001 PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_z8002 PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_h8300 PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_h8300h PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_h8500 PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_alpha PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_big_arm PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_little_arm PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_sparc PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_sparc64 PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_big_a29k PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_little_a29k PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_i960 PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_sh PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_shl PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_hppa PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_m88k PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_ns32k PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_big_powerpc PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_little_powerpc PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_rs6000 PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
extern int print_insn_w65 PARAMS ((bfd_vma, disassemble_info*));
|
||||||
|
|
||||||
|
/* Fetch the disassembler for a given BFD, if that support is available. */
|
||||||
|
extern disassembler_ftype disassembler PARAMS ((bfd *));
|
||||||
|
|
||||||
|
|
||||||
|
/* This block of definitions is for particular callers who read instructions
|
||||||
|
into a buffer before calling the instruction decoder. */
|
||||||
|
|
||||||
|
/* Here is a function which callers may wish to use for read_memory_func.
|
||||||
|
It gets bytes from a buffer. */
|
||||||
|
extern int buffer_read_memory
|
||||||
|
PARAMS ((bfd_vma, bfd_byte *, int, struct disassemble_info *));
|
||||||
|
|
||||||
|
/* This function goes with buffer_read_memory.
|
||||||
|
It prints a message using info->fprintf_func and info->stream. */
|
||||||
|
extern void perror_memory PARAMS ((int, bfd_vma, struct disassemble_info *));
|
||||||
|
|
||||||
|
|
||||||
|
/* Just print the address in hex. This is included for completeness even
|
||||||
|
though both GDB and objdump provide their own (to print symbolic
|
||||||
|
addresses). */
|
||||||
|
extern void generic_print_address
|
||||||
|
PARAMS ((bfd_vma, struct disassemble_info *));
|
||||||
|
|
||||||
|
/* Macro to initialize a disassemble_info struct. This should be called
|
||||||
|
by all applications creating such a struct. */
|
||||||
|
#define INIT_DISASSEMBLE_INFO(INFO, STREAM, FPRINTF_FUNC) \
|
||||||
|
(INFO).fprintf_func = (FPRINTF_FUNC), \
|
||||||
|
(INFO).stream = (STREAM), \
|
||||||
|
(INFO).buffer = NULL, \
|
||||||
|
(INFO).buffer_vma = 0, \
|
||||||
|
(INFO).buffer_length = 0, \
|
||||||
|
(INFO).read_memory_func = buffer_read_memory, \
|
||||||
|
(INFO).memory_error_func = perror_memory, \
|
||||||
|
(INFO).print_address_func = generic_print_address, \
|
||||||
|
(INFO).arch = bfd_arch_unknown, \
|
||||||
|
(INFO).mach = 0, \
|
||||||
|
(INFO).endian = BFD_ENDIAN_UNKNOWN, \
|
||||||
|
(INFO).flags = 0, \
|
||||||
|
(INFO).insn_info_valid = 0
|
||||||
|
|
||||||
|
#endif /* ! defined (DIS_ASM_H) */
|
70
opcode/dis-buf.c
Normal file
70
opcode/dis-buf.c
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
/* Disassemble from a buffer, for GNU.
|
||||||
|
Copyright (C) 1993, 1994 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "dis-asm.h"
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
/* Get LENGTH bytes from info's buffer, at target address memaddr.
|
||||||
|
Transfer them to myaddr. */
|
||||||
|
int
|
||||||
|
buffer_read_memory (memaddr, myaddr, length, info)
|
||||||
|
bfd_vma memaddr;
|
||||||
|
bfd_byte *myaddr;
|
||||||
|
int length;
|
||||||
|
struct disassemble_info *info;
|
||||||
|
{
|
||||||
|
if (memaddr < info->buffer_vma
|
||||||
|
|| memaddr + length > info->buffer_vma + info->buffer_length)
|
||||||
|
/* Out of bounds. Use EIO because GDB uses it. */
|
||||||
|
return EIO;
|
||||||
|
memcpy (myaddr, info->buffer + (memaddr - info->buffer_vma), length);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print an error message. We can assume that this is in response to
|
||||||
|
an error return from buffer_read_memory. */
|
||||||
|
void
|
||||||
|
perror_memory (status, memaddr, info)
|
||||||
|
int status;
|
||||||
|
bfd_vma memaddr;
|
||||||
|
struct disassemble_info *info;
|
||||||
|
{
|
||||||
|
if (status != EIO)
|
||||||
|
/* Can't happen. */
|
||||||
|
(*info->fprintf_func) (info->stream, "Unknown error %d\n", status);
|
||||||
|
else
|
||||||
|
/* Actually, address between memaddr and memaddr + len was
|
||||||
|
out of bounds. */
|
||||||
|
(*info->fprintf_func) (info->stream,
|
||||||
|
"Address 0x%x is out of bounds.\n", memaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This could be in a separate file, to save miniscule amounts of space
|
||||||
|
in statically linked executables. */
|
||||||
|
|
||||||
|
/* Just print the address is hex. This is included for completeness even
|
||||||
|
though both GDB and objdump provide their own (to print symbolic
|
||||||
|
addresses). */
|
||||||
|
|
||||||
|
void
|
||||||
|
generic_print_address (addr, info)
|
||||||
|
bfd_vma addr;
|
||||||
|
struct disassemble_info *info;
|
||||||
|
{
|
||||||
|
(*info->fprintf_func) (info->stream, "0x%x", addr);
|
||||||
|
}
|
78
opcode/disass.c
Normal file
78
opcode/disass.c
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* lightning disassembling support
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "lightning.h"
|
||||||
|
#include "dis-asm.h"
|
||||||
|
|
||||||
|
void disassemble(stream, from, to)
|
||||||
|
FILE *stream;
|
||||||
|
char *from, *to;
|
||||||
|
{
|
||||||
|
disassemble_info info;
|
||||||
|
bfd_vma pc = (bfd_vma) from;
|
||||||
|
bfd_vma end = (bfd_vma) to;
|
||||||
|
|
||||||
|
INIT_DISASSEMBLE_INFO(info, stream, fprintf);
|
||||||
|
info.buffer = NULL;
|
||||||
|
info.buffer_vma = 0;
|
||||||
|
info.buffer_length = end;
|
||||||
|
|
||||||
|
while (pc < end) {
|
||||||
|
fprintf_vma(stream, pc);
|
||||||
|
putc('\t', stream);
|
||||||
|
#ifdef LIGHTNING_I386
|
||||||
|
pc += print_insn_i386(pc, &info);
|
||||||
|
#endif
|
||||||
|
#ifdef LIGHTNING_PPC
|
||||||
|
pc += print_insn_big_powerpc(pc, &info);
|
||||||
|
#endif
|
||||||
|
#ifdef LIGHTNING_SPARC
|
||||||
|
pc += print_insn_sparc(pc, &info);
|
||||||
|
#endif
|
||||||
|
putc('\n', stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Panic on failing malloc */
|
||||||
|
PTR
|
||||||
|
xmalloc(size)
|
||||||
|
size_t size;
|
||||||
|
{
|
||||||
|
PTR ret = malloc(size ? size : 1);
|
||||||
|
if (!ret) {
|
||||||
|
fprintf(stderr, "Couldn't allocate memory\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
2031
opcode/i386-dis.c
Normal file
2031
opcode/i386-dis.c
Normal file
File diff suppressed because it is too large
Load diff
898
opcode/i386.h
Normal file
898
opcode/i386.h
Normal file
|
@ -0,0 +1,898 @@
|
||||||
|
/* i386-opcode.h -- Intel 80386 opcode table
|
||||||
|
Copyright 1989, 1991, 1992, 1995 Free Software Foundation.
|
||||||
|
|
||||||
|
This file is part of GAS, the GNU Assembler, and GDB, the GNU Debugger.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
static const template i386_optab[] = {
|
||||||
|
|
||||||
|
#define _ None
|
||||||
|
/* move instructions */
|
||||||
|
#define MOV_AX_DISP32 0xa0
|
||||||
|
{ "mov", 2, 0xa0, _, DW|NoModrm, { Disp32, Acc, 0 } },
|
||||||
|
{ "mov", 2, 0x88, _, DW|Modrm, { Reg, Reg|Mem, 0 } },
|
||||||
|
{ "mov", 2, 0xb0, _, ShortFormW, { Imm, Reg, 0 } },
|
||||||
|
{ "mov", 2, 0xc6, _, W|Modrm, { Imm, Reg|Mem, 0 } },
|
||||||
|
{ "mov", 2, 0x8c, _, D|Modrm, { SReg3|SReg2, Reg16|Mem, 0 } },
|
||||||
|
/* move to/from control debug registers */
|
||||||
|
{ "mov", 2, 0x0f20, _, D|Modrm, { Control, Reg32, 0} },
|
||||||
|
{ "mov", 2, 0x0f21, _, D|Modrm, { Debug, Reg32, 0} },
|
||||||
|
{ "mov", 2, 0x0f24, _, D|Modrm, { Test, Reg32, 0} },
|
||||||
|
|
||||||
|
/* move with sign extend */
|
||||||
|
/* "movsbl" & "movsbw" must not be unified into "movsb" to avoid
|
||||||
|
conflict with the "movs" string move instruction. Thus,
|
||||||
|
{"movsb", 2, 0x0fbe, _, ReverseRegRegmem|Modrm, { Reg8|Mem, Reg16|Reg32, 0} },
|
||||||
|
is not kosher; we must seperate the two instructions. */
|
||||||
|
{"movsbl", 2, 0x0fbe, _, ReverseRegRegmem|Modrm|Data32, { Reg8|Mem, Reg32, 0} },
|
||||||
|
{"movsbw", 2, 0x0fbe, _, ReverseRegRegmem|Modrm|Data16, { Reg8|Mem, Reg16, 0} },
|
||||||
|
{"movswl", 2, 0x0fbf, _, ReverseRegRegmem|Modrm, { Reg16|Mem, Reg32, 0} },
|
||||||
|
|
||||||
|
/* move with zero extend */
|
||||||
|
{"movzb", 2, 0x0fb6, _, ReverseRegRegmem|Modrm, { Reg8|Mem, Reg16|Reg32, 0} },
|
||||||
|
{"movzwl", 2, 0x0fb7, _, ReverseRegRegmem|Modrm, { Reg16|Mem, Reg32, 0} },
|
||||||
|
|
||||||
|
/* push instructions */
|
||||||
|
{"push", 1, 0x50, _, ShortForm, { WordReg,0,0 } },
|
||||||
|
{"push", 1, 0xff, 0x6, Modrm, { WordReg|WordMem, 0, 0 } },
|
||||||
|
{"push", 1, 0x6a, _, NoModrm, { Imm8S, 0, 0} },
|
||||||
|
{"push", 1, 0x68, _, NoModrm, { Imm16|Imm32, 0, 0} },
|
||||||
|
{"push", 1, 0x06, _, Seg2ShortForm, { SReg2,0,0 } },
|
||||||
|
{"push", 1, 0x0fa0, _, Seg3ShortForm, { SReg3,0,0 } },
|
||||||
|
/* push all */
|
||||||
|
{"pusha", 0, 0x60, _, NoModrm, { 0, 0, 0 } },
|
||||||
|
|
||||||
|
/* pop instructions */
|
||||||
|
{"pop", 1, 0x58, _, ShortForm, { WordReg,0,0 } },
|
||||||
|
{"pop", 1, 0x8f, 0x0, Modrm, { WordReg|WordMem, 0, 0 } },
|
||||||
|
#define POP_SEG_SHORT 0x7
|
||||||
|
{"pop", 1, 0x07, _, Seg2ShortForm, { SReg2,0,0 } },
|
||||||
|
{"pop", 1, 0x0fa1, _, Seg3ShortForm, { SReg3,0,0 } },
|
||||||
|
/* pop all */
|
||||||
|
{"popa", 0, 0x61, _, NoModrm, { 0, 0, 0 } },
|
||||||
|
|
||||||
|
/* xchg exchange instructions
|
||||||
|
xchg commutes: we allow both operand orders */
|
||||||
|
{"xchg", 2, 0x90, _, ShortForm, { WordReg, Acc, 0 } },
|
||||||
|
{"xchg", 2, 0x90, _, ShortForm, { Acc, WordReg, 0 } },
|
||||||
|
{"xchg", 2, 0x86, _, W|Modrm, { Reg, Reg|Mem, 0 } },
|
||||||
|
{"xchg", 2, 0x86, _, W|Modrm, { Reg|Mem, Reg, 0 } },
|
||||||
|
|
||||||
|
/* in/out from ports */
|
||||||
|
{"in", 2, 0xe4, _, W|NoModrm, { Imm8, Acc, 0 } },
|
||||||
|
{"in", 2, 0xec, _, W|NoModrm, { InOutPortReg, Acc, 0 } },
|
||||||
|
{"in", 1, 0xe4, _, W|NoModrm, { Imm8, 0, 0 } },
|
||||||
|
{"in", 1, 0xec, _, W|NoModrm, { InOutPortReg, 0, 0 } },
|
||||||
|
{"out", 2, 0xe6, _, W|NoModrm, { Acc, Imm8, 0 } },
|
||||||
|
{"out", 2, 0xee, _, W|NoModrm, { Acc, InOutPortReg, 0 } },
|
||||||
|
{"out", 1, 0xe6, _, W|NoModrm, { Imm8, 0, 0 } },
|
||||||
|
{"out", 1, 0xee, _, W|NoModrm, { InOutPortReg, 0, 0 } },
|
||||||
|
|
||||||
|
/* load effective address */
|
||||||
|
{"lea", 2, 0x8d, _, Modrm, { WordMem, WordReg, 0 } },
|
||||||
|
|
||||||
|
/* load segment registers from memory */
|
||||||
|
{"lds", 2, 0xc5, _, Modrm, { Mem, Reg32, 0} },
|
||||||
|
{"les", 2, 0xc4, _, Modrm, { Mem, Reg32, 0} },
|
||||||
|
{"lfs", 2, 0x0fb4, _, Modrm, { Mem, Reg32, 0} },
|
||||||
|
{"lgs", 2, 0x0fb5, _, Modrm, { Mem, Reg32, 0} },
|
||||||
|
{"lss", 2, 0x0fb2, _, Modrm, { Mem, Reg32, 0} },
|
||||||
|
|
||||||
|
/* flags register instructions */
|
||||||
|
{"clc", 0, 0xf8, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"cld", 0, 0xfc, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"cli", 0, 0xfa, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"clts", 0, 0x0f06, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"cmc", 0, 0xf5, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"lahf", 0, 0x9f, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"sahf", 0, 0x9e, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"pushfl", 0, 0x9c, _, NoModrm|Data32, { 0, 0, 0} },
|
||||||
|
{"popfl", 0, 0x9d, _, NoModrm|Data32, { 0, 0, 0} },
|
||||||
|
{"pushfw", 0, 0x9c, _, NoModrm|Data16, { 0, 0, 0} },
|
||||||
|
{"popfw", 0, 0x9d, _, NoModrm|Data16, { 0, 0, 0} },
|
||||||
|
{"pushf", 0, 0x9c, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"popf", 0, 0x9d, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"stc", 0, 0xf9, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"std", 0, 0xfd, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"sti", 0, 0xfb, _, NoModrm, { 0, 0, 0} },
|
||||||
|
|
||||||
|
{"add", 2, 0x0, _, DW|Modrm, { Reg, Reg|Mem, 0} },
|
||||||
|
{"add", 2, 0x83, 0, Modrm, { Imm8S, WordReg|WordMem, 0} },
|
||||||
|
{"add", 2, 0x4, _, W|NoModrm, { Imm, Acc, 0} },
|
||||||
|
{"add", 2, 0x80, 0, W|Modrm, { Imm, Reg|Mem, 0} },
|
||||||
|
|
||||||
|
{"inc", 1, 0x40, _, ShortForm, { WordReg, 0, 0} },
|
||||||
|
{"inc", 1, 0xfe, 0, W|Modrm, { Reg|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"sub", 2, 0x28, _, DW|Modrm, { Reg, Reg|Mem, 0} },
|
||||||
|
{"sub", 2, 0x83, 5, Modrm, { Imm8S, WordReg|WordMem, 0} },
|
||||||
|
{"sub", 2, 0x2c, _, W|NoModrm, { Imm, Acc, 0} },
|
||||||
|
{"sub", 2, 0x80, 5, W|Modrm, { Imm, Reg|Mem, 0} },
|
||||||
|
|
||||||
|
{"dec", 1, 0x48, _, ShortForm, { WordReg, 0, 0} },
|
||||||
|
{"dec", 1, 0xfe, 1, W|Modrm, { Reg|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"sbb", 2, 0x18, _, DW|Modrm, { Reg, Reg|Mem, 0} },
|
||||||
|
{"sbb", 2, 0x83, 3, Modrm, { Imm8S, WordReg|WordMem, 0} },
|
||||||
|
{"sbb", 2, 0x1c, _, W|NoModrm, { Imm, Acc, 0} },
|
||||||
|
{"sbb", 2, 0x80, 3, W|Modrm, { Imm, Reg|Mem, 0} },
|
||||||
|
|
||||||
|
{"cmp", 2, 0x38, _, DW|Modrm, { Reg, Reg|Mem, 0} },
|
||||||
|
{"cmp", 2, 0x83, 7, Modrm, { Imm8S, WordReg|WordMem, 0} },
|
||||||
|
{"cmp", 2, 0x3c, _, W|NoModrm, { Imm, Acc, 0} },
|
||||||
|
{"cmp", 2, 0x80, 7, W|Modrm, { Imm, Reg|Mem, 0} },
|
||||||
|
|
||||||
|
{"test", 2, 0x84, _, W|Modrm, { Reg|Mem, Reg, 0} },
|
||||||
|
{"test", 2, 0x84, _, W|Modrm, { Reg, Reg|Mem, 0} },
|
||||||
|
{"test", 2, 0xa8, _, W|NoModrm, { Imm, Acc, 0} },
|
||||||
|
{"test", 2, 0xf6, 0, W|Modrm, { Imm, Reg|Mem, 0} },
|
||||||
|
|
||||||
|
{"and", 2, 0x20, _, DW|Modrm, { Reg, Reg|Mem, 0} },
|
||||||
|
{"and", 2, 0x83, 4, Modrm, { Imm8S, WordReg|WordMem, 0} },
|
||||||
|
{"and", 2, 0x24, _, W|NoModrm, { Imm, Acc, 0} },
|
||||||
|
{"and", 2, 0x80, 4, W|Modrm, { Imm, Reg|Mem, 0} },
|
||||||
|
|
||||||
|
{"or", 2, 0x08, _, DW|Modrm, { Reg, Reg|Mem, 0} },
|
||||||
|
{"or", 2, 0x83, 1, Modrm, { Imm8S, WordReg|WordMem, 0} },
|
||||||
|
{"or", 2, 0x0c, _, W|NoModrm, { Imm, Acc, 0} },
|
||||||
|
{"or", 2, 0x80, 1, W|Modrm, { Imm, Reg|Mem, 0} },
|
||||||
|
|
||||||
|
{"xor", 2, 0x30, _, DW|Modrm, { Reg, Reg|Mem, 0} },
|
||||||
|
{"xor", 2, 0x83, 6, Modrm, { Imm8S, WordReg|WordMem, 0} },
|
||||||
|
{"xor", 2, 0x34, _, W|NoModrm, { Imm, Acc, 0} },
|
||||||
|
{"xor", 2, 0x80, 6, W|Modrm, { Imm, Reg|Mem, 0} },
|
||||||
|
|
||||||
|
{"adc", 2, 0x10, _, DW|Modrm, { Reg, Reg|Mem, 0} },
|
||||||
|
{"adc", 2, 0x83, 2, Modrm, { Imm8S, WordReg|WordMem, 0} },
|
||||||
|
{"adc", 2, 0x14, _, W|NoModrm, { Imm, Acc, 0} },
|
||||||
|
{"adc", 2, 0x80, 2, W|Modrm, { Imm, Reg|Mem, 0} },
|
||||||
|
|
||||||
|
{"neg", 1, 0xf6, 3, W|Modrm, { Reg|Mem, 0, 0} },
|
||||||
|
{"not", 1, 0xf6, 2, W|Modrm, { Reg|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"aaa", 0, 0x37, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"aas", 0, 0x3f, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"daa", 0, 0x27, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"das", 0, 0x2f, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"aad", 0, 0xd50a, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"aam", 0, 0xd40a, _, NoModrm, { 0, 0, 0} },
|
||||||
|
|
||||||
|
/* conversion insns */
|
||||||
|
/* conversion: intel naming */
|
||||||
|
{"cbw", 0, 0x98, _, NoModrm|Data16, { 0, 0, 0} },
|
||||||
|
{"cwd", 0, 0x99, _, NoModrm|Data16, { 0, 0, 0} },
|
||||||
|
{"cwde", 0, 0x98, _, NoModrm|Data32, { 0, 0, 0} },
|
||||||
|
{"cdq", 0, 0x99, _, NoModrm|Data32, { 0, 0, 0} },
|
||||||
|
/* att naming */
|
||||||
|
{"cbtw", 0, 0x98, _, NoModrm|Data16, { 0, 0, 0} },
|
||||||
|
{"cwtl", 0, 0x98, _, NoModrm|Data32, { 0, 0, 0} },
|
||||||
|
{"cwtd", 0, 0x99, _, NoModrm|Data16, { 0, 0, 0} },
|
||||||
|
{"cltd", 0, 0x99, _, NoModrm|Data32, { 0, 0, 0} },
|
||||||
|
|
||||||
|
/* Warning! the mul/imul (opcode 0xf6) must only have 1 operand! They are
|
||||||
|
expanding 64-bit multiplies, and *cannot* be selected to accomplish
|
||||||
|
'imul %ebx, %eax' (opcode 0x0faf must be used in this case)
|
||||||
|
These multiplies can only be selected with single operand forms. */
|
||||||
|
{"mul", 1, 0xf6, 4, W|Modrm, { Reg|Mem, 0, 0} },
|
||||||
|
{"imul", 1, 0xf6, 5, W|Modrm, { Reg|Mem, 0, 0} },
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* imulKludge here is needed to reverse the i.rm.reg & i.rm.regmem fields.
|
||||||
|
These instructions are exceptions: 'imul $2, %eax, %ecx' would put
|
||||||
|
'%eax' in the reg field and '%ecx' in the regmem field if we did not
|
||||||
|
switch them. */
|
||||||
|
{"imul", 2, 0x0faf, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} },
|
||||||
|
{"imul", 3, 0x6b, _, Modrm|ReverseRegRegmem, { Imm8S, WordReg|Mem, WordReg} },
|
||||||
|
{"imul", 3, 0x69, _, Modrm|ReverseRegRegmem, { Imm16|Imm32, WordReg|Mem, WordReg} },
|
||||||
|
/*
|
||||||
|
imul with 2 operands mimicks imul with 3 by puting register both
|
||||||
|
in i.rm.reg & i.rm.regmem fields
|
||||||
|
*/
|
||||||
|
{"imul", 2, 0x6b, _, Modrm|imulKludge, { Imm8S, WordReg, 0} },
|
||||||
|
{"imul", 2, 0x69, _, Modrm|imulKludge, { Imm16|Imm32, WordReg, 0} },
|
||||||
|
{"div", 1, 0xf6, 6, W|Modrm, { Reg|Mem, 0, 0} },
|
||||||
|
{"div", 2, 0xf6, 6, W|Modrm, { Reg|Mem, Acc, 0} },
|
||||||
|
{"idiv", 1, 0xf6, 7, W|Modrm, { Reg|Mem, 0, 0} },
|
||||||
|
{"idiv", 2, 0xf6, 7, W|Modrm, { Reg|Mem, Acc, 0} },
|
||||||
|
|
||||||
|
{"rol", 2, 0xd0, 0, W|Modrm, { Imm1, Reg|Mem, 0} },
|
||||||
|
{"rol", 2, 0xc0, 0, W|Modrm, { Imm8, Reg|Mem, 0} },
|
||||||
|
{"rol", 2, 0xd2, 0, W|Modrm, { ShiftCount, Reg|Mem, 0} },
|
||||||
|
{"rol", 1, 0xd0, 0, W|Modrm, { Reg|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"ror", 2, 0xd0, 1, W|Modrm, { Imm1, Reg|Mem, 0} },
|
||||||
|
{"ror", 2, 0xc0, 1, W|Modrm, { Imm8, Reg|Mem, 0} },
|
||||||
|
{"ror", 2, 0xd2, 1, W|Modrm, { ShiftCount, Reg|Mem, 0} },
|
||||||
|
{"ror", 1, 0xd0, 1, W|Modrm, { Reg|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"rcl", 2, 0xd0, 2, W|Modrm, { Imm1, Reg|Mem, 0} },
|
||||||
|
{"rcl", 2, 0xc0, 2, W|Modrm, { Imm8, Reg|Mem, 0} },
|
||||||
|
{"rcl", 2, 0xd2, 2, W|Modrm, { ShiftCount, Reg|Mem, 0} },
|
||||||
|
{"rcl", 1, 0xd0, 2, W|Modrm, { Reg|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"rcr", 2, 0xd0, 3, W|Modrm, { Imm1, Reg|Mem, 0} },
|
||||||
|
{"rcr", 2, 0xc0, 3, W|Modrm, { Imm8, Reg|Mem, 0} },
|
||||||
|
{"rcr", 2, 0xd2, 3, W|Modrm, { ShiftCount, Reg|Mem, 0} },
|
||||||
|
{"rcr", 1, 0xd0, 3, W|Modrm, { Reg|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"sal", 2, 0xd0, 4, W|Modrm, { Imm1, Reg|Mem, 0} },
|
||||||
|
{"sal", 2, 0xc0, 4, W|Modrm, { Imm8, Reg|Mem, 0} },
|
||||||
|
{"sal", 2, 0xd2, 4, W|Modrm, { ShiftCount, Reg|Mem, 0} },
|
||||||
|
{"sal", 1, 0xd0, 4, W|Modrm, { Reg|Mem, 0, 0} },
|
||||||
|
{"shl", 2, 0xd0, 4, W|Modrm, { Imm1, Reg|Mem, 0} },
|
||||||
|
{"shl", 2, 0xc0, 4, W|Modrm, { Imm8, Reg|Mem, 0} },
|
||||||
|
{"shl", 2, 0xd2, 4, W|Modrm, { ShiftCount, Reg|Mem, 0} },
|
||||||
|
{"shl", 1, 0xd0, 4, W|Modrm, { Reg|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"shld", 3, 0x0fa4, _, Modrm, { Imm8, WordReg, WordReg|Mem} },
|
||||||
|
{"shld", 3, 0x0fa5, _, Modrm, { ShiftCount, WordReg, WordReg|Mem} },
|
||||||
|
{"shld", 2, 0x0fa5, _, Modrm, { WordReg, WordReg|Mem, 0} },
|
||||||
|
|
||||||
|
{"shr", 2, 0xd0, 5, W|Modrm, { Imm1, Reg|Mem, 0} },
|
||||||
|
{"shr", 2, 0xc0, 5, W|Modrm, { Imm8, Reg|Mem, 0} },
|
||||||
|
{"shr", 2, 0xd2, 5, W|Modrm, { ShiftCount, Reg|Mem, 0} },
|
||||||
|
{"shr", 1, 0xd0, 5, W|Modrm, { Reg|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"shrd", 3, 0x0fac, _, Modrm, { Imm8, WordReg, WordReg|Mem} },
|
||||||
|
{"shrd", 3, 0x0fad, _, Modrm, { ShiftCount, WordReg, WordReg|Mem} },
|
||||||
|
{"shrd", 2, 0x0fad, _, Modrm, { WordReg, WordReg|Mem, 0} },
|
||||||
|
|
||||||
|
{"sar", 2, 0xd0, 7, W|Modrm, { Imm1, Reg|Mem, 0} },
|
||||||
|
{"sar", 2, 0xc0, 7, W|Modrm, { Imm8, Reg|Mem, 0} },
|
||||||
|
{"sar", 2, 0xd2, 7, W|Modrm, { ShiftCount, Reg|Mem, 0} },
|
||||||
|
{"sar", 1, 0xd0, 7, W|Modrm, { Reg|Mem, 0, 0} },
|
||||||
|
|
||||||
|
/* control transfer instructions */
|
||||||
|
#define CALL_PC_RELATIVE 0xe8
|
||||||
|
{"call", 1, 0xe8, _, JumpDword, { Disp32, 0, 0} },
|
||||||
|
{"call", 1, 0xff, 2, Modrm|Data32, { Reg|Mem|JumpAbsolute, 0, 0} },
|
||||||
|
{"callw", 1, 0xff, 2, Modrm|Data16, { Reg|Mem|JumpAbsolute, 0, 0} },
|
||||||
|
#define CALL_FAR_IMMEDIATE 0x9a
|
||||||
|
{"lcall", 2, 0x9a, _, JumpInterSegment, { Imm16, Abs32|Imm32, 0} },
|
||||||
|
{"lcall", 1, 0xff, 3, Modrm|Data32, { Mem, 0, 0} },
|
||||||
|
{"lcallw", 1, 0xff, 3, Modrm|Data16, { Mem, 0, 0} },
|
||||||
|
|
||||||
|
#define JUMP_PC_RELATIVE 0xeb
|
||||||
|
{"jmp", 1, 0xeb, _, Jump, { Disp, 0, 0} },
|
||||||
|
{"jmp", 1, 0xff, 4, Modrm, { Reg32|Mem|JumpAbsolute, 0, 0} },
|
||||||
|
#define JUMP_FAR_IMMEDIATE 0xea
|
||||||
|
{"ljmp", 2, 0xea, _, JumpInterSegment, { Imm16, Imm32, 0} },
|
||||||
|
{"ljmp", 1, 0xff, 5, Modrm|Data32, { Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"ret", 0, 0xc3, _, NoModrm|Data32, { 0, 0, 0} },
|
||||||
|
{"ret", 1, 0xc2, _, NoModrm|Data32, { Imm16, 0, 0} },
|
||||||
|
{"retw", 0, 0xc3, _, NoModrm|Data16, { 0, 0, 0} },
|
||||||
|
{"retw", 1, 0xc2, _, NoModrm|Data16, { Imm16, 0, 0} },
|
||||||
|
{"lret", 0, 0xcb, _, NoModrm|Data32, { 0, 0, 0} },
|
||||||
|
{"lret", 1, 0xca, _, NoModrm|Data32, { Imm16, 0, 0} },
|
||||||
|
{"lretw", 0, 0xcb, _, NoModrm|Data16, { 0, 0, 0} },
|
||||||
|
{"lretw", 1, 0xca, _, NoModrm|Data16, { Imm16, 0, 0} },
|
||||||
|
{"enter", 2, 0xc8, _, NoModrm|Data32, { Imm16, Imm8, 0} },
|
||||||
|
{"leave", 0, 0xc9, _, NoModrm|Data32, { 0, 0, 0} },
|
||||||
|
{"enterw", 2, 0xc8, _, NoModrm|Data16, { Imm16, Imm8, 0} },
|
||||||
|
{"leavew", 0, 0xc9, _, NoModrm|Data16, { 0, 0, 0} },
|
||||||
|
|
||||||
|
/* conditional jumps */
|
||||||
|
{"jo", 1, 0x70, _, Jump, { Disp, 0, 0} },
|
||||||
|
|
||||||
|
{"jno", 1, 0x71, _, Jump, { Disp, 0, 0} },
|
||||||
|
|
||||||
|
{"jb", 1, 0x72, _, Jump, { Disp, 0, 0} },
|
||||||
|
{"jc", 1, 0x72, _, Jump, { Disp, 0, 0} },
|
||||||
|
{"jnae", 1, 0x72, _, Jump, { Disp, 0, 0} },
|
||||||
|
|
||||||
|
{"jnb", 1, 0x73, _, Jump, { Disp, 0, 0} },
|
||||||
|
{"jnc", 1, 0x73, _, Jump, { Disp, 0, 0} },
|
||||||
|
{"jae", 1, 0x73, _, Jump, { Disp, 0, 0} },
|
||||||
|
|
||||||
|
{"je", 1, 0x74, _, Jump, { Disp, 0, 0} },
|
||||||
|
{"jz", 1, 0x74, _, Jump, { Disp, 0, 0} },
|
||||||
|
|
||||||
|
{"jne", 1, 0x75, _, Jump, { Disp, 0, 0} },
|
||||||
|
{"jnz", 1, 0x75, _, Jump, { Disp, 0, 0} },
|
||||||
|
|
||||||
|
{"jbe", 1, 0x76, _, Jump, { Disp, 0, 0} },
|
||||||
|
{"jna", 1, 0x76, _, Jump, { Disp, 0, 0} },
|
||||||
|
|
||||||
|
{"jnbe", 1, 0x77, _, Jump, { Disp, 0, 0} },
|
||||||
|
{"ja", 1, 0x77, _, Jump, { Disp, 0, 0} },
|
||||||
|
|
||||||
|
{"js", 1, 0x78, _, Jump, { Disp, 0, 0} },
|
||||||
|
|
||||||
|
{"jns", 1, 0x79, _, Jump, { Disp, 0, 0} },
|
||||||
|
|
||||||
|
{"jp", 1, 0x7a, _, Jump, { Disp, 0, 0} },
|
||||||
|
{"jpe", 1, 0x7a, _, Jump, { Disp, 0, 0} },
|
||||||
|
|
||||||
|
{"jnp", 1, 0x7b, _, Jump, { Disp, 0, 0} },
|
||||||
|
{"jpo", 1, 0x7b, _, Jump, { Disp, 0, 0} },
|
||||||
|
|
||||||
|
{"jl", 1, 0x7c, _, Jump, { Disp, 0, 0} },
|
||||||
|
{"jnge", 1, 0x7c, _, Jump, { Disp, 0, 0} },
|
||||||
|
|
||||||
|
{"jnl", 1, 0x7d, _, Jump, { Disp, 0, 0} },
|
||||||
|
{"jge", 1, 0x7d, _, Jump, { Disp, 0, 0} },
|
||||||
|
|
||||||
|
{"jle", 1, 0x7e, _, Jump, { Disp, 0, 0} },
|
||||||
|
{"jng", 1, 0x7e, _, Jump, { Disp, 0, 0} },
|
||||||
|
|
||||||
|
{"jnle", 1, 0x7f, _, Jump, { Disp, 0, 0} },
|
||||||
|
{"jg", 1, 0x7f, _, Jump, { Disp, 0, 0} },
|
||||||
|
|
||||||
|
#if 0 /* XXX where are these macros used?
|
||||||
|
To get them working again, they need to take
|
||||||
|
an entire template as the parameter,
|
||||||
|
and check for Data16/Data32 flags. */
|
||||||
|
/* these turn into pseudo operations when disp is larger than 8 bits */
|
||||||
|
#define IS_JUMP_ON_CX_ZERO(o) \
|
||||||
|
(o == 0x66e3)
|
||||||
|
#define IS_JUMP_ON_ECX_ZERO(o) \
|
||||||
|
(o == 0xe3)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{"jcxz", 1, 0xe3, _, JumpByte|Data16, { Disp, 0, 0} },
|
||||||
|
{"jecxz", 1, 0xe3, _, JumpByte|Data32, { Disp, 0, 0} },
|
||||||
|
|
||||||
|
#define IS_LOOP_ECX_TIMES(o) \
|
||||||
|
(o == 0xe2 || o == 0xe1 || o == 0xe0)
|
||||||
|
|
||||||
|
{"loop", 1, 0xe2, _, JumpByte, { Disp, 0, 0} },
|
||||||
|
|
||||||
|
{"loopz", 1, 0xe1, _, JumpByte, { Disp, 0, 0} },
|
||||||
|
{"loope", 1, 0xe1, _, JumpByte, { Disp, 0, 0} },
|
||||||
|
|
||||||
|
{"loopnz", 1, 0xe0, _, JumpByte, { Disp, 0, 0} },
|
||||||
|
{"loopne", 1, 0xe0, _, JumpByte, { Disp, 0, 0} },
|
||||||
|
|
||||||
|
/* set byte on flag instructions */
|
||||||
|
{"seto", 1, 0x0f90, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"setno", 1, 0x0f91, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"setb", 1, 0x0f92, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
{"setc", 1, 0x0f92, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
{"setnae", 1, 0x0f92, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"setnb", 1, 0x0f93, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
{"setnc", 1, 0x0f93, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
{"setae", 1, 0x0f93, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"sete", 1, 0x0f94, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
{"setz", 1, 0x0f94, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"setne", 1, 0x0f95, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
{"setnz", 1, 0x0f95, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"setbe", 1, 0x0f96, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
{"setna", 1, 0x0f96, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"setnbe", 1, 0x0f97, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
{"seta", 1, 0x0f97, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"sets", 1, 0x0f98, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"setns", 1, 0x0f99, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"setp", 1, 0x0f9a, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
{"setpe", 1, 0x0f9a, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"setnp", 1, 0x0f9b, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
{"setpo", 1, 0x0f9b, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"setl", 1, 0x0f9c, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
{"setnge", 1, 0x0f9c, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"setnl", 1, 0x0f9d, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
{"setge", 1, 0x0f9d, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"setle", 1, 0x0f9e, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
{"setng", 1, 0x0f9e, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"setnle", 1, 0x0f9f, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
{"setg", 1, 0x0f9f, 0, Modrm, { Reg8|Mem, 0, 0} },
|
||||||
|
|
||||||
|
#define IS_STRING_INSTRUCTION(o) \
|
||||||
|
((o) == 0xa6 || (o) == 0x6c || (o) == 0x6e || (o) == 0x6e || \
|
||||||
|
(o) == 0xac || (o) == 0xa4 || (o) == 0xae || (o) == 0xaa || \
|
||||||
|
(o) == 0xd7)
|
||||||
|
|
||||||
|
/* string manipulation */
|
||||||
|
{"cmps", 0, 0xa6, _, W|NoModrm, { 0, 0, 0} },
|
||||||
|
{"scmp", 0, 0xa6, _, W|NoModrm, { 0, 0, 0} },
|
||||||
|
{"ins", 0, 0x6c, _, W|NoModrm, { 0, 0, 0} },
|
||||||
|
{"outs", 0, 0x6e, _, W|NoModrm, { 0, 0, 0} },
|
||||||
|
{"lods", 0, 0xac, _, W|NoModrm, { 0, 0, 0} },
|
||||||
|
{"slod", 0, 0xac, _, W|NoModrm, { 0, 0, 0} },
|
||||||
|
{"movs", 0, 0xa4, _, W|NoModrm, { 0, 0, 0} },
|
||||||
|
{"smov", 0, 0xa4, _, W|NoModrm, { 0, 0, 0} },
|
||||||
|
{"scas", 0, 0xae, _, W|NoModrm, { 0, 0, 0} },
|
||||||
|
{"ssca", 0, 0xae, _, W|NoModrm, { 0, 0, 0} },
|
||||||
|
{"stos", 0, 0xaa, _, W|NoModrm, { 0, 0, 0} },
|
||||||
|
{"ssto", 0, 0xaa, _, W|NoModrm, { 0, 0, 0} },
|
||||||
|
{"xlat", 0, 0xd7, _, NoModrm, { 0, 0, 0} },
|
||||||
|
|
||||||
|
/* bit manipulation */
|
||||||
|
{"bsf", 2, 0x0fbc, _, Modrm|ReverseRegRegmem, { Reg|Mem, Reg, 0} },
|
||||||
|
{"bsr", 2, 0x0fbd, _, Modrm|ReverseRegRegmem, { Reg|Mem, Reg, 0} },
|
||||||
|
{"bt", 2, 0x0fa3, _, Modrm, { Reg, Reg|Mem, 0} },
|
||||||
|
{"bt", 2, 0x0fba, 4, Modrm, { Imm8, Reg|Mem, 0} },
|
||||||
|
{"btc", 2, 0x0fbb, _, Modrm, { Reg, Reg|Mem, 0} },
|
||||||
|
{"btc", 2, 0x0fba, 7, Modrm, { Imm8, Reg|Mem, 0} },
|
||||||
|
{"btr", 2, 0x0fb3, _, Modrm, { Reg, Reg|Mem, 0} },
|
||||||
|
{"btr", 2, 0x0fba, 6, Modrm, { Imm8, Reg|Mem, 0} },
|
||||||
|
{"bts", 2, 0x0fab, _, Modrm, { Reg, Reg|Mem, 0} },
|
||||||
|
{"bts", 2, 0x0fba, 5, Modrm, { Imm8, Reg|Mem, 0} },
|
||||||
|
|
||||||
|
/* interrupts & op. sys insns */
|
||||||
|
/* See gas/config/tc-i386.c for conversion of 'int $3' into the special
|
||||||
|
int 3 insn. */
|
||||||
|
#define INT_OPCODE 0xcd
|
||||||
|
#define INT3_OPCODE 0xcc
|
||||||
|
{"int", 1, 0xcd, _, NoModrm, { Imm8, 0, 0} },
|
||||||
|
{"int3", 0, 0xcc, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"into", 0, 0xce, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"iret", 0, 0xcf, _, NoModrm|Data32, { 0, 0, 0} },
|
||||||
|
{"iretw", 0, 0xcf, _, NoModrm|Data16, { 0, 0, 0} },
|
||||||
|
/* i386sl, i486sl, later 486, and Pentium */
|
||||||
|
{"rsm", 0, 0x0faa, _, NoModrm,{ 0, 0, 0} },
|
||||||
|
|
||||||
|
{"boundl", 2, 0x62, _, Modrm|Data32, { Reg32, Mem, 0} },
|
||||||
|
{"boundw", 2, 0x62, _, Modrm|Data16, { Reg16, Mem, 0} },
|
||||||
|
|
||||||
|
{"hlt", 0, 0xf4, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"wait", 0, 0x9b, _, NoModrm, { 0, 0, 0} },
|
||||||
|
/* nop is actually 'xchgl %eax, %eax' */
|
||||||
|
{"nop", 0, 0x90, _, NoModrm, { 0, 0, 0} },
|
||||||
|
|
||||||
|
/* protection control */
|
||||||
|
{"arpl", 2, 0x63, _, Modrm, { Reg16, Reg16|Mem, 0} },
|
||||||
|
{"lar", 2, 0x0f02, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} },
|
||||||
|
{"lgdt", 1, 0x0f01, 2, Modrm, { Mem, 0, 0} },
|
||||||
|
{"lidt", 1, 0x0f01, 3, Modrm, { Mem, 0, 0} },
|
||||||
|
{"lldt", 1, 0x0f00, 2, Modrm, { WordReg|Mem, 0, 0} },
|
||||||
|
{"lmsw", 1, 0x0f01, 6, Modrm, { WordReg|Mem, 0, 0} },
|
||||||
|
{"lsl", 2, 0x0f03, _, Modrm|ReverseRegRegmem, { WordReg|Mem, WordReg, 0} },
|
||||||
|
{"ltr", 1, 0x0f00, 3, Modrm, { WordReg|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"sgdt", 1, 0x0f01, 0, Modrm, { Mem, 0, 0} },
|
||||||
|
{"sidt", 1, 0x0f01, 1, Modrm, { Mem, 0, 0} },
|
||||||
|
{"sldt", 1, 0x0f00, 0, Modrm, { WordReg|Mem, 0, 0} },
|
||||||
|
{"smsw", 1, 0x0f01, 4, Modrm, { WordReg|Mem, 0, 0} },
|
||||||
|
{"str", 1, 0x0f00, 1, Modrm, { Reg16|Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"verr", 1, 0x0f00, 4, Modrm, { WordReg|Mem, 0, 0} },
|
||||||
|
{"verw", 1, 0x0f00, 5, Modrm, { WordReg|Mem, 0, 0} },
|
||||||
|
|
||||||
|
/* floating point instructions */
|
||||||
|
|
||||||
|
/* load */
|
||||||
|
{"fld", 1, 0xd9c0, _, ShortForm, { FloatReg, 0, 0} }, /* register */
|
||||||
|
{"flds", 1, 0xd9, 0, Modrm, { Mem, 0, 0} }, /* %st0 <-- mem float */
|
||||||
|
{"fldl", 1, 0xdd, 0, Modrm, { Mem, 0, 0} }, /* %st0 <-- mem double */
|
||||||
|
{"fldl", 1, 0xd9c0, _, ShortForm, { FloatReg, 0, 0} }, /* register */
|
||||||
|
{"fild", 1, 0xdf, 0, Modrm, { Mem, 0, 0} }, /* %st0 <-- mem word (16) */
|
||||||
|
{"fildl", 1, 0xdb, 0, Modrm, { Mem, 0, 0} }, /* %st0 <-- mem dword (32) */
|
||||||
|
{"fildq",1, 0xdf, 5, Modrm, { Mem, 0, 0} }, /* %st0 <-- mem qword (64) */
|
||||||
|
{"fildll",1, 0xdf, 5, Modrm, { Mem, 0, 0} }, /* %st0 <-- mem qword (64) */
|
||||||
|
{"fldt", 1, 0xdb, 5, Modrm, { Mem, 0, 0} }, /* %st0 <-- mem efloat */
|
||||||
|
{"fbld", 1, 0xdf, 4, Modrm, { Mem, 0, 0} }, /* %st0 <-- mem bcd */
|
||||||
|
|
||||||
|
/* store (no pop) */
|
||||||
|
{"fst", 1, 0xddd0, _, ShortForm, { FloatReg, 0, 0} }, /* register */
|
||||||
|
{"fsts", 1, 0xd9, 2, Modrm, { Mem, 0, 0} }, /* %st0 --> mem float */
|
||||||
|
{"fstl", 1, 0xdd, 2, Modrm, { Mem, 0, 0} }, /* %st0 --> mem double */
|
||||||
|
{"fstl", 1, 0xddd0, _, ShortForm, { FloatReg, 0, 0} }, /* register */
|
||||||
|
{"fist", 1, 0xdf, 2, Modrm, { Mem, 0, 0} }, /* %st0 --> mem word (16) */
|
||||||
|
{"fistl", 1, 0xdb, 2, Modrm, { Mem, 0, 0} }, /* %st0 --> mem dword (32) */
|
||||||
|
|
||||||
|
/* store (with pop) */
|
||||||
|
{"fstp", 1, 0xddd8, _, ShortForm, { FloatReg, 0, 0} }, /* register */
|
||||||
|
{"fstps", 1, 0xd9, 3, Modrm, { Mem, 0, 0} }, /* %st0 --> mem float */
|
||||||
|
{"fstpl", 1, 0xdd, 3, Modrm, { Mem, 0, 0} }, /* %st0 --> mem double */
|
||||||
|
{"fstpl", 1, 0xddd8, _, ShortForm, { FloatReg, 0, 0} }, /* register */
|
||||||
|
{"fistp", 1, 0xdf, 3, Modrm, { Mem, 0, 0} }, /* %st0 --> mem word (16) */
|
||||||
|
{"fistpl",1, 0xdb, 3, Modrm, { Mem, 0, 0} }, /* %st0 --> mem dword (32) */
|
||||||
|
{"fistpq",1, 0xdf, 7, Modrm, { Mem, 0, 0} }, /* %st0 --> mem qword (64) */
|
||||||
|
{"fistpll",1,0xdf, 7, Modrm, { Mem, 0, 0} }, /* %st0 --> mem qword (64) */
|
||||||
|
{"fstpt", 1, 0xdb, 7, Modrm, { Mem, 0, 0} }, /* %st0 --> mem efloat */
|
||||||
|
{"fbstp", 1, 0xdf, 6, Modrm, { Mem, 0, 0} }, /* %st0 --> mem bcd */
|
||||||
|
|
||||||
|
/* exchange %st<n> with %st0 */
|
||||||
|
{"fxch", 1, 0xd9c8, _, ShortForm, { FloatReg, 0, 0} },
|
||||||
|
{"fxch", 0, 0xd9c9, _, NoModrm, { 0, 0, 0} }, /* alias for fxch %st, %st(1) */
|
||||||
|
|
||||||
|
/* comparison (without pop) */
|
||||||
|
{"fcom", 1, 0xd8d0, _, ShortForm, { FloatReg, 0, 0} },
|
||||||
|
{"fcoms", 1, 0xd8, 2, Modrm, { Mem, 0, 0} }, /* compare %st0, mem float */
|
||||||
|
{"ficoml", 1, 0xda, 2, Modrm, { Mem, 0, 0} }, /* compare %st0, mem word */
|
||||||
|
{"fcoml", 1, 0xdc, 2, Modrm, { Mem, 0, 0} }, /* compare %st0, mem double */
|
||||||
|
{"fcoml", 1, 0xd8d0, _, ShortForm, { FloatReg, 0, 0} },
|
||||||
|
{"ficoms", 1, 0xde, 2, Modrm, { Mem, 0, 0} }, /* compare %st0, mem dword */
|
||||||
|
|
||||||
|
/* comparison (with pop) */
|
||||||
|
{"fcomp", 1, 0xd8d8, _, ShortForm, { FloatReg, 0, 0} },
|
||||||
|
{"fcomps", 1, 0xd8, 3, Modrm, { Mem, 0, 0} }, /* compare %st0, mem float */
|
||||||
|
{"ficompl", 1, 0xda, 3, Modrm, { Mem, 0, 0} }, /* compare %st0, mem word */
|
||||||
|
{"fcompl", 1, 0xdc, 3, Modrm, { Mem, 0, 0} }, /* compare %st0, mem double */
|
||||||
|
{"fcompl", 1, 0xd8d8, _, ShortForm, { FloatReg, 0, 0} },
|
||||||
|
{"ficomps", 1, 0xde, 3, Modrm, { Mem, 0, 0} }, /* compare %st0, mem dword */
|
||||||
|
{"fcompp", 0, 0xded9, _, NoModrm, { 0, 0, 0} }, /* compare %st0, %st1 & pop 2 */
|
||||||
|
|
||||||
|
/* unordered comparison (with pop) */
|
||||||
|
{"fucom", 1, 0xdde0, _, ShortForm, { FloatReg, 0, 0} },
|
||||||
|
{"fucomp", 1, 0xdde8, _, ShortForm, { FloatReg, 0, 0} },
|
||||||
|
{"fucompp", 0, 0xdae9, _, NoModrm, { 0, 0, 0} }, /* ucompare %st0, %st1 & pop twice */
|
||||||
|
|
||||||
|
{"ftst", 0, 0xd9e4, _, NoModrm, { 0, 0, 0} }, /* test %st0 */
|
||||||
|
{"fxam", 0, 0xd9e5, _, NoModrm, { 0, 0, 0} }, /* examine %st0 */
|
||||||
|
|
||||||
|
/* load constants into %st0 */
|
||||||
|
{"fld1", 0, 0xd9e8, _, NoModrm, { 0, 0, 0} }, /* %st0 <-- 1.0 */
|
||||||
|
{"fldl2t", 0, 0xd9e9, _, NoModrm, { 0, 0, 0} }, /* %st0 <-- log2(10) */
|
||||||
|
{"fldl2e", 0, 0xd9ea, _, NoModrm, { 0, 0, 0} }, /* %st0 <-- log2(e) */
|
||||||
|
{"fldpi", 0, 0xd9eb, _, NoModrm, { 0, 0, 0} }, /* %st0 <-- pi */
|
||||||
|
{"fldlg2", 0, 0xd9ec, _, NoModrm, { 0, 0, 0} }, /* %st0 <-- log10(2) */
|
||||||
|
{"fldln2", 0, 0xd9ed, _, NoModrm, { 0, 0, 0} }, /* %st0 <-- ln(2) */
|
||||||
|
{"fldz", 0, 0xd9ee, _, NoModrm, { 0, 0, 0} }, /* %st0 <-- 0.0 */
|
||||||
|
|
||||||
|
/* arithmetic */
|
||||||
|
|
||||||
|
/* add */
|
||||||
|
{"fadd", 1, 0xd8c0, _, ShortForm, { FloatReg, 0, 0} },
|
||||||
|
{"fadd", 2, 0xd8c0, _, ShortForm|FloatD, { FloatReg, FloatAcc, 0} },
|
||||||
|
{"fadd", 0, 0xdcc1, _, NoModrm, { 0, 0, 0} }, /* alias for fadd %st, %st(1) */
|
||||||
|
{"faddp", 1, 0xdac0, _, ShortForm, { FloatReg, 0, 0} },
|
||||||
|
{"faddp", 2, 0xdac0, _, ShortForm|FloatD, { FloatReg, FloatAcc, 0} },
|
||||||
|
{"faddp", 0, 0xdec1, _, NoModrm, { 0, 0, 0} }, /* alias for faddp %st, %st(1) */
|
||||||
|
{"fadds", 1, 0xd8, 0, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fiaddl", 1, 0xda, 0, Modrm, { Mem, 0, 0} },
|
||||||
|
{"faddl", 1, 0xdc, 0, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fiadds", 1, 0xde, 0, Modrm, { Mem, 0, 0} },
|
||||||
|
|
||||||
|
/* sub */
|
||||||
|
/* Note: intel has decided that certain of these operations are reversed
|
||||||
|
in assembler syntax. */
|
||||||
|
{"fsub", 1, 0xd8e0, _, ShortForm, { FloatReg, 0, 0} },
|
||||||
|
{"fsub", 2, 0xd8e0, _, ShortForm, { FloatReg, FloatAcc, 0} },
|
||||||
|
#ifdef NON_BROKEN_OPCODES
|
||||||
|
{"fsub", 2, 0xdce8, _, ShortForm, { FloatAcc, FloatReg, 0} },
|
||||||
|
#else
|
||||||
|
{"fsub", 2, 0xdce0, _, ShortForm, { FloatAcc, FloatReg, 0} },
|
||||||
|
#endif
|
||||||
|
{"fsub", 0, 0xdce1, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fsubp", 1, 0xdae0, _, ShortForm, { FloatReg, 0, 0} },
|
||||||
|
{"fsubp", 2, 0xdae0, _, ShortForm, { FloatReg, FloatAcc, 0} },
|
||||||
|
#ifdef NON_BROKEN_OPCODES
|
||||||
|
{"fsubp", 2, 0xdee8, _, ShortForm, { FloatAcc, FloatReg, 0} },
|
||||||
|
#else
|
||||||
|
{"fsubp", 2, 0xdee0, _, ShortForm, { FloatAcc, FloatReg, 0} },
|
||||||
|
#endif
|
||||||
|
{"fsubp", 0, 0xdee1, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fsubs", 1, 0xd8, 4, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fisubl", 1, 0xda, 4, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fsubl", 1, 0xdc, 4, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fisubs", 1, 0xde, 4, Modrm, { Mem, 0, 0} },
|
||||||
|
|
||||||
|
/* sub reverse */
|
||||||
|
{"fsubr", 1, 0xd8e8, _, ShortForm, { FloatReg, 0, 0} },
|
||||||
|
{"fsubr", 2, 0xd8e8, _, ShortForm, { FloatReg, FloatAcc, 0} },
|
||||||
|
#ifdef NON_BROKEN_OPCODES
|
||||||
|
{"fsubr", 2, 0xdce0, _, ShortForm, { FloatAcc, FloatReg, 0} },
|
||||||
|
#else
|
||||||
|
{"fsubr", 2, 0xdce8, _, ShortForm, { FloatAcc, FloatReg, 0} },
|
||||||
|
#endif
|
||||||
|
{"fsubr", 0, 0xdce9, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fsubrp", 1, 0xdae8, _, ShortForm, { FloatReg, 0, 0} },
|
||||||
|
{"fsubrp", 2, 0xdae8, _, ShortForm, { FloatReg, FloatAcc, 0} },
|
||||||
|
#ifdef NON_BROKEN_OPCODES
|
||||||
|
{"fsubrp", 2, 0xdee0, _, ShortForm, { FloatAcc, FloatReg, 0} },
|
||||||
|
#else
|
||||||
|
{"fsubrp", 2, 0xdee8, _, ShortForm, { FloatAcc, FloatReg, 0} },
|
||||||
|
#endif
|
||||||
|
{"fsubrp", 0, 0xdee9, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fsubrs", 1, 0xd8, 5, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fisubrl", 1, 0xda, 5, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fsubrl", 1, 0xdc, 5, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fisubrs", 1, 0xde, 5, Modrm, { Mem, 0, 0} },
|
||||||
|
|
||||||
|
/* mul */
|
||||||
|
{"fmul", 1, 0xd8c8, _, ShortForm, { FloatReg, 0, 0} },
|
||||||
|
{"fmul", 2, 0xd8c8, _, ShortForm|FloatD, { FloatReg, FloatAcc, 0} },
|
||||||
|
{"fmul", 0, 0xdcc9, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fmulp", 1, 0xdac8, _, ShortForm, { FloatReg, 0, 0} },
|
||||||
|
{"fmulp", 2, 0xdac8, _, ShortForm|FloatD, { FloatReg, FloatAcc, 0} },
|
||||||
|
{"fmulp", 0, 0xdec9, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fmuls", 1, 0xd8, 1, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fimull", 1, 0xda, 1, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fmull", 1, 0xdc, 1, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fimuls", 1, 0xde, 1, Modrm, { Mem, 0, 0} },
|
||||||
|
|
||||||
|
/* div */
|
||||||
|
/* Note: intel has decided that certain of these operations are reversed
|
||||||
|
in assembler syntax. */
|
||||||
|
{"fdiv", 1, 0xd8f0, _, ShortForm, { FloatReg, 0, 0} },
|
||||||
|
{"fdiv", 2, 0xd8f0, _, ShortForm, { FloatReg, FloatAcc, 0} },
|
||||||
|
#ifdef NON_BROKEN_OPCODES
|
||||||
|
{"fdiv", 2, 0xdcf8, _, ShortForm, { FloatAcc, FloatReg, 0} },
|
||||||
|
#else
|
||||||
|
{"fdiv", 2, 0xdcf0, _, ShortForm, { FloatAcc, FloatReg, 0} },
|
||||||
|
#endif
|
||||||
|
{"fdiv", 0, 0xdcf1, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fdivp", 1, 0xdaf0, _, ShortForm, { FloatReg, 0, 0} },
|
||||||
|
{"fdivp", 2, 0xdaf0, _, ShortForm, { FloatReg, FloatAcc, 0} },
|
||||||
|
#ifdef NON_BROKEN_OPCODES
|
||||||
|
{"fdivp", 2, 0xdef8, _, ShortForm, { FloatAcc, FloatReg, 0} },
|
||||||
|
#else
|
||||||
|
{"fdivp", 2, 0xdef0, _, ShortForm, { FloatAcc, FloatReg, 0} },
|
||||||
|
#endif
|
||||||
|
{"fdivp", 0, 0xdef1, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fdivs", 1, 0xd8, 6, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fidivl", 1, 0xda, 6, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fdivl", 1, 0xdc, 6, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fidivs", 1, 0xde, 6, Modrm, { Mem, 0, 0} },
|
||||||
|
|
||||||
|
/* div reverse */
|
||||||
|
{"fdivr", 1, 0xd8f8, _, ShortForm, { FloatReg, 0, 0} },
|
||||||
|
{"fdivr", 2, 0xd8f8, _, ShortForm, { FloatReg, FloatAcc, 0} },
|
||||||
|
#ifdef NON_BROKEN_OPCODES
|
||||||
|
{"fdivr", 2, 0xdcf0, _, ShortForm, { FloatAcc, FloatReg, 0} },
|
||||||
|
#else
|
||||||
|
{"fdivr", 2, 0xdcf8, _, ShortForm, { FloatAcc, FloatReg, 0} },
|
||||||
|
#endif
|
||||||
|
{"fdivr", 0, 0xdcf9, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fdivrp", 1, 0xdaf8, _, ShortForm, { FloatReg, 0, 0} },
|
||||||
|
{"fdivrp", 2, 0xdaf8, _, ShortForm, { FloatReg, FloatAcc, 0} },
|
||||||
|
#ifdef NON_BROKEN_OPCODES
|
||||||
|
{"fdivrp", 2, 0xdef0, _, ShortForm, { FloatAcc, FloatReg, 0} },
|
||||||
|
#else
|
||||||
|
{"fdivrp", 2, 0xdef8, _, ShortForm, { FloatAcc, FloatReg, 0} },
|
||||||
|
#endif
|
||||||
|
{"fdivrp", 0, 0xdef9, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fdivrs", 1, 0xd8, 7, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fidivrl", 1, 0xda, 7, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fdivrl", 1, 0xdc, 7, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fidivrs", 1, 0xde, 7, Modrm, { Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"f2xm1", 0, 0xd9f0, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fyl2x", 0, 0xd9f1, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fptan", 0, 0xd9f2, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fpatan", 0, 0xd9f3, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fxtract", 0, 0xd9f4, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fprem1", 0, 0xd9f5, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fdecstp", 0, 0xd9f6, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fincstp", 0, 0xd9f7, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fprem", 0, 0xd9f8, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fyl2xp1", 0, 0xd9f9, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fsqrt", 0, 0xd9fa, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fsincos", 0, 0xd9fb, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"frndint", 0, 0xd9fc, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fscale", 0, 0xd9fd, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fsin", 0, 0xd9fe, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fcos", 0, 0xd9ff, _, NoModrm, { 0, 0, 0} },
|
||||||
|
|
||||||
|
{"fchs", 0, 0xd9e0, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fabs", 0, 0xd9e1, _, NoModrm, { 0, 0, 0} },
|
||||||
|
|
||||||
|
/* processor control */
|
||||||
|
{"fninit", 0, 0xdbe3, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"finit", 0, 0x9bdbe3, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fldcw", 1, 0xd9, 5, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fnstcw", 1, 0xd9, 7, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fstcw", 1, 0x9bd9, 7, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fnstsw", 1, 0xdfe0, _, NoModrm, { Acc, 0, 0} },
|
||||||
|
{"fnstsw", 1, 0xdd, 7, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fnstsw", 0, 0xdfe0, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fstsw", 1, 0x9bdfe0, _, NoModrm, { Acc, 0, 0} },
|
||||||
|
{"fstsw", 1, 0x9bdd, 7, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fstsw", 0, 0x9bdfe0, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fnclex", 0, 0xdbe2, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fclex", 0, 0x9bdbe2, _, NoModrm, { 0, 0, 0} },
|
||||||
|
/*
|
||||||
|
We ignore the short format (287) versions of fstenv/fldenv & fsave/frstor
|
||||||
|
instructions; i'm not sure how to add them or how they are different.
|
||||||
|
My 386/387 book offers no details about this.
|
||||||
|
*/
|
||||||
|
{"fnstenv", 1, 0xd9, 6, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fstenv", 1, 0x9bd9, 6, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fldenv", 1, 0xd9, 4, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fnsave", 1, 0xdd, 6, Modrm, { Mem, 0, 0} },
|
||||||
|
{"fsave", 1, 0x9bdd, 6, Modrm, { Mem, 0, 0} },
|
||||||
|
{"frstor", 1, 0xdd, 4, Modrm, { Mem, 0, 0} },
|
||||||
|
|
||||||
|
{"ffree", 1, 0xddc0, _, ShortForm, { FloatReg, 0, 0} },
|
||||||
|
{"fnop", 0, 0xd9d0, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fwait", 0, 0x9b, _, NoModrm, { 0, 0, 0} },
|
||||||
|
|
||||||
|
/*
|
||||||
|
opcode prefixes; we allow them as seperate insns too
|
||||||
|
(see prefix table below)
|
||||||
|
*/
|
||||||
|
{"aword", 0, 0x67, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"addr16", 0, 0x67, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"word", 0, 0x66, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"data16", 0, 0x66, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"lock", 0, 0xf0, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"cs", 0, 0x2e, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"ds", 0, 0x3e, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"es", 0, 0x26, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"fs", 0, 0x64, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"gs", 0, 0x65, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"ss", 0, 0x36, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"rep", 0, 0xf3, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"repe", 0, 0xf3, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"repz", 0, 0xf3, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"repne", 0, 0xf2, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"repnz", 0, 0xf2, _, NoModrm, { 0, 0, 0} },
|
||||||
|
|
||||||
|
/* 486 extensions */
|
||||||
|
|
||||||
|
{"bswap", 1, 0x0fc8, _, ShortForm, { Reg32,0,0 } },
|
||||||
|
{"xadd", 2, 0x0fc0, _, DW|Modrm, { Reg, Reg|Mem, 0 } },
|
||||||
|
{"cmpxchg", 2, 0x0fb0, _, DW|Modrm, { Reg, Reg|Mem, 0 } },
|
||||||
|
{"invd", 0, 0x0f08, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"wbinvd", 0, 0x0f09, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"invlpg", 1, 0x0f01, 7, Modrm, { Mem, 0, 0} },
|
||||||
|
|
||||||
|
/* 586 and late 486 extensions */
|
||||||
|
{"cpuid", 0, 0x0fa2, _, NoModrm, { 0, 0, 0} },
|
||||||
|
|
||||||
|
/* Pentium extensions */
|
||||||
|
{"wrmsr", 0, 0x0f30, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"rdtsc", 0, 0x0f31, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"rdmsr", 0, 0x0f32, _, NoModrm, { 0, 0, 0} },
|
||||||
|
{"cmpxchg8b", 1, 0x0fc7, 1, Modrm, { Mem, 0, 0} },
|
||||||
|
|
||||||
|
/* Pentium Pro extensions */
|
||||||
|
{"rdpmc", 0, 0x0f33, _, NoModrm, { 0, 0, 0} },
|
||||||
|
|
||||||
|
{"cmovo", 2, 0x0f40, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} },
|
||||||
|
{"cmovno", 2, 0x0f41, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} },
|
||||||
|
{"cmovb", 2, 0x0f42, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} },
|
||||||
|
{"cmovae", 2, 0x0f43, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} },
|
||||||
|
{"cmove", 2, 0x0f44, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} },
|
||||||
|
{"cmovne", 2, 0x0f45, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} },
|
||||||
|
{"cmovbe", 2, 0x0f46, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} },
|
||||||
|
{"cmova", 2, 0x0f47, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} },
|
||||||
|
{"cmovs", 2, 0x0f48, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} },
|
||||||
|
{"cmovns", 2, 0x0f49, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} },
|
||||||
|
{"cmovp", 2, 0x0f4a, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} },
|
||||||
|
{"cmovnp", 2, 0x0f4b, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} },
|
||||||
|
{"cmovl", 2, 0x0f4c, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} },
|
||||||
|
{"cmovge", 2, 0x0f4d, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} },
|
||||||
|
{"cmovle", 2, 0x0f4e, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} },
|
||||||
|
{"cmovg", 2, 0x0f4f, _, W|Modrm|ReverseRegRegmem, { WordReg|WordMem, WordReg, 0} },
|
||||||
|
|
||||||
|
{"fcmovb", 2, 0xdac0, _, ShortForm, { FloatReg, FloatAcc, 0} },
|
||||||
|
{"fcmove", 2, 0xdac8, _, ShortForm, { FloatReg, FloatAcc, 0} },
|
||||||
|
{"fcmovbe",2, 0xdad0, _, ShortForm, { FloatReg, FloatAcc, 0} },
|
||||||
|
{"fcmovu", 2, 0xdad8, _, ShortForm, { FloatReg, FloatAcc, 0} },
|
||||||
|
{"fcmovnb", 2, 0xdbc0, _, ShortForm, { FloatReg, FloatAcc, 0} },
|
||||||
|
{"fcmovne", 2, 0xdbc8, _, ShortForm, { FloatReg, FloatAcc, 0} },
|
||||||
|
{"fcmovnbe",2, 0xdbd0, _, ShortForm, { FloatReg, FloatAcc, 0} },
|
||||||
|
{"fcmovnu", 2, 0xdbd8, _, ShortForm, { FloatReg, FloatAcc, 0} },
|
||||||
|
|
||||||
|
{"fcomi", 2, 0xdbf0, _, ShortForm, { FloatReg, FloatAcc, 0} },
|
||||||
|
{"fucomi", 2, 0xdbe8, _, ShortForm, { FloatReg, FloatAcc, 0} },
|
||||||
|
{"fcomip", 2, 0xdff0, _, ShortForm, { FloatReg, FloatAcc, 0} },
|
||||||
|
{"fucomip",2, 0xdfe8, _, ShortForm, { FloatReg, FloatAcc, 0} },
|
||||||
|
|
||||||
|
{"", 0, 0, 0, 0, { 0, 0, 0} } /* sentinel */
|
||||||
|
};
|
||||||
|
#undef _
|
||||||
|
|
||||||
|
static const template *const i386_optab_end
|
||||||
|
= i386_optab + sizeof (i386_optab)/sizeof(i386_optab[0]);
|
||||||
|
|
||||||
|
/* 386 register table */
|
||||||
|
|
||||||
|
static const reg_entry i386_regtab[] = {
|
||||||
|
/* 8 bit regs */
|
||||||
|
{"al", Reg8|Acc, 0}, {"cl", Reg8|ShiftCount, 1}, {"dl", Reg8, 2},
|
||||||
|
{"bl", Reg8, 3},
|
||||||
|
{"ah", Reg8, 4}, {"ch", Reg8, 5}, {"dh", Reg8, 6}, {"bh", Reg8, 7},
|
||||||
|
/* 16 bit regs */
|
||||||
|
{"ax", Reg16|Acc, 0}, {"cx", Reg16, 1}, {"dx", Reg16|InOutPortReg, 2}, {"bx", Reg16, 3},
|
||||||
|
{"sp", Reg16, 4}, {"bp", Reg16, 5}, {"si", Reg16, 6}, {"di", Reg16, 7},
|
||||||
|
/* 32 bit regs */
|
||||||
|
{"eax", Reg32|Acc, 0}, {"ecx", Reg32, 1}, {"edx", Reg32, 2}, {"ebx", Reg32, 3},
|
||||||
|
{"esp", Reg32, 4}, {"ebp", Reg32, 5}, {"esi", Reg32, 6}, {"edi", Reg32, 7},
|
||||||
|
/* segment registers */
|
||||||
|
{"es", SReg2, 0}, {"cs", SReg2, 1}, {"ss", SReg2, 2},
|
||||||
|
{"ds", SReg2, 3}, {"fs", SReg3, 4}, {"gs", SReg3, 5},
|
||||||
|
/* control registers */
|
||||||
|
{"cr0", Control, 0}, {"cr2", Control, 2}, {"cr3", Control, 3},
|
||||||
|
{"cr4", Control, 4},
|
||||||
|
/* debug registers */
|
||||||
|
{"db0", Debug, 0}, {"db1", Debug, 1}, {"db2", Debug, 2},
|
||||||
|
{"db3", Debug, 3}, {"db6", Debug, 6}, {"db7", Debug, 7},
|
||||||
|
{"dr0", Debug, 0}, {"dr1", Debug, 1}, {"dr2", Debug, 2},
|
||||||
|
{"dr3", Debug, 3}, {"dr6", Debug, 6}, {"dr7", Debug, 7},
|
||||||
|
/* test registers */
|
||||||
|
{"tr3", Test, 3}, {"tr4", Test, 4}, {"tr5", Test, 5},
|
||||||
|
{"tr6", Test, 6}, {"tr7", Test, 7},
|
||||||
|
/* float registers */
|
||||||
|
{"st(0)", FloatReg|FloatAcc, 0},
|
||||||
|
{"st", FloatReg|FloatAcc, 0},
|
||||||
|
{"st(1)", FloatReg, 1}, {"st(2)", FloatReg, 2},
|
||||||
|
{"st(3)", FloatReg, 3}, {"st(4)", FloatReg, 4}, {"st(5)", FloatReg, 5},
|
||||||
|
{"st(6)", FloatReg, 6}, {"st(7)", FloatReg, 7}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAX_REG_NAME_SIZE 8 /* for parsing register names from input */
|
||||||
|
|
||||||
|
static const reg_entry *const i386_regtab_end
|
||||||
|
= i386_regtab + sizeof(i386_regtab)/sizeof(i386_regtab[0]);
|
||||||
|
|
||||||
|
/* segment stuff */
|
||||||
|
static const seg_entry cs = { "cs", 0x2e };
|
||||||
|
static const seg_entry ds = { "ds", 0x3e };
|
||||||
|
static const seg_entry ss = { "ss", 0x36 };
|
||||||
|
static const seg_entry es = { "es", 0x26 };
|
||||||
|
static const seg_entry fs = { "fs", 0x64 };
|
||||||
|
static const seg_entry gs = { "gs", 0x65 };
|
||||||
|
static const seg_entry null = { "", 0x0 };
|
||||||
|
|
||||||
|
/*
|
||||||
|
This table is used to store the default segment register implied by all
|
||||||
|
possible memory addressing modes.
|
||||||
|
It is indexed by the mode & modrm entries of the modrm byte as follows:
|
||||||
|
index = (mode<<3) | modrm;
|
||||||
|
*/
|
||||||
|
static const seg_entry *const one_byte_segment_defaults[] = {
|
||||||
|
/* mode 0 */
|
||||||
|
&ds, &ds, &ds, &ds, &null, &ds, &ds, &ds,
|
||||||
|
/* mode 1 */
|
||||||
|
&ds, &ds, &ds, &ds, &null, &ss, &ds, &ds,
|
||||||
|
/* mode 2 */
|
||||||
|
&ds, &ds, &ds, &ds, &null, &ss, &ds, &ds,
|
||||||
|
/* mode 3 --- not a memory reference; never referenced */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const seg_entry *const two_byte_segment_defaults[] = {
|
||||||
|
/* mode 0 */
|
||||||
|
&ds, &ds, &ds, &ds, &ss, &ds, &ds, &ds,
|
||||||
|
/* mode 1 */
|
||||||
|
&ds, &ds, &ds, &ds, &ss, &ds, &ds, &ds,
|
||||||
|
/* mode 2 */
|
||||||
|
&ds, &ds, &ds, &ds, &ss, &ds, &ds, &ds,
|
||||||
|
/* mode 3 --- not a memory reference; never referenced */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const prefix_entry i386_prefixtab[] = {
|
||||||
|
#define ADDR_PREFIX_OPCODE 0x67
|
||||||
|
{ "addr16", 0x67 }, /* address size prefix ==> 16bit addressing
|
||||||
|
* (How is this useful?) */
|
||||||
|
#define WORD_PREFIX_OPCODE 0x66
|
||||||
|
{ "data16", 0x66 }, /* operand size prefix */
|
||||||
|
{ "lock", 0xf0 }, /* bus lock prefix */
|
||||||
|
{ "wait", 0x9b }, /* wait for coprocessor */
|
||||||
|
{ "cs", 0x2e }, { "ds", 0x3e }, /* segment overrides ... */
|
||||||
|
{ "es", 0x26 }, { "fs", 0x64 },
|
||||||
|
{ "gs", 0x65 }, { "ss", 0x36 },
|
||||||
|
/* REPE & REPNE used to detect rep/repne with a non-string instruction */
|
||||||
|
#define REPNE 0xf2
|
||||||
|
#define REPE 0xf3
|
||||||
|
{ "rep", 0xf3 }, /* repeat string instructions */
|
||||||
|
{ "repe", 0xf3 }, { "repz", 0xf3 },
|
||||||
|
{ "repne", 0xf2 }, { "repnz", 0xf2 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const prefix_entry *const i386_prefixtab_end
|
||||||
|
= i386_prefixtab + sizeof(i386_prefixtab)/sizeof(i386_prefixtab[0]);
|
||||||
|
|
||||||
|
/* end of i386-opcode.h */
|
238
opcode/ppc-dis.c
Normal file
238
opcode/ppc-dis.c
Normal file
|
@ -0,0 +1,238 @@
|
||||||
|
/* ppc-dis.c -- Disassemble PowerPC instructions
|
||||||
|
Copyright 1994 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Cygnus Support
|
||||||
|
|
||||||
|
This file is part of GDB, GAS, and the GNU binutils.
|
||||||
|
|
||||||
|
GDB, GAS, and the GNU binutils are free software; you can redistribute
|
||||||
|
them and/or modify them under the terms of the GNU General Public
|
||||||
|
License as published by the Free Software Foundation; either version
|
||||||
|
2, or (at your option) any later version.
|
||||||
|
|
||||||
|
GDB, GAS, and the GNU binutils are distributed in the hope that they
|
||||||
|
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 file; see the file COPYING. If not, write to the Free
|
||||||
|
Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "ansidecl.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "dis-asm.h"
|
||||||
|
#include "opcode/ppc.h"
|
||||||
|
|
||||||
|
/* This file provides several disassembler functions, all of which use
|
||||||
|
the disassembler interface defined in dis-asm.h. Several functions
|
||||||
|
are provided because this file handles disassembly for the PowerPC
|
||||||
|
in both big and little endian mode and also for the POWER (RS/6000)
|
||||||
|
chip. */
|
||||||
|
|
||||||
|
static int print_insn_powerpc PARAMS ((bfd_vma, struct disassemble_info *,
|
||||||
|
int bigendian, int dialect));
|
||||||
|
|
||||||
|
/* Print a big endian PowerPC instruction. For convenience, also
|
||||||
|
disassemble instructions supported by the Motorola PowerPC 601. */
|
||||||
|
|
||||||
|
int
|
||||||
|
print_insn_big_powerpc (memaddr, info)
|
||||||
|
bfd_vma memaddr;
|
||||||
|
struct disassemble_info *info;
|
||||||
|
{
|
||||||
|
return print_insn_powerpc (memaddr, info, 1,
|
||||||
|
PPC_OPCODE_PPC | PPC_OPCODE_601);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print a little endian PowerPC instruction. For convenience, also
|
||||||
|
disassemble instructions supported by the Motorola PowerPC 601. */
|
||||||
|
|
||||||
|
int
|
||||||
|
print_insn_little_powerpc (memaddr, info)
|
||||||
|
bfd_vma memaddr;
|
||||||
|
struct disassemble_info *info;
|
||||||
|
{
|
||||||
|
return print_insn_powerpc (memaddr, info, 0,
|
||||||
|
PPC_OPCODE_PPC | PPC_OPCODE_601);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print a POWER (RS/6000) instruction. */
|
||||||
|
|
||||||
|
int
|
||||||
|
print_insn_rs6000 (memaddr, info)
|
||||||
|
bfd_vma memaddr;
|
||||||
|
struct disassemble_info *info;
|
||||||
|
{
|
||||||
|
return print_insn_powerpc (memaddr, info, 1, PPC_OPCODE_POWER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print a PowerPC or POWER instruction. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
print_insn_powerpc (memaddr, info, bigendian, dialect)
|
||||||
|
bfd_vma memaddr;
|
||||||
|
struct disassemble_info *info;
|
||||||
|
int bigendian;
|
||||||
|
int dialect;
|
||||||
|
{
|
||||||
|
bfd_byte buffer[4];
|
||||||
|
int status;
|
||||||
|
unsigned long insn;
|
||||||
|
const struct powerpc_opcode *opcode;
|
||||||
|
const struct powerpc_opcode *opcode_end;
|
||||||
|
unsigned long op;
|
||||||
|
|
||||||
|
status = (*info->read_memory_func) (memaddr, buffer, 4, info);
|
||||||
|
if (status != 0)
|
||||||
|
{
|
||||||
|
(*info->memory_error_func) (status, memaddr, info);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bigendian)
|
||||||
|
insn = bfd_getb32 (buffer);
|
||||||
|
else
|
||||||
|
insn = bfd_getl32 (buffer);
|
||||||
|
|
||||||
|
/* Get the major opcode of the instruction. */
|
||||||
|
op = PPC_OP (insn);
|
||||||
|
|
||||||
|
/* Find the first match in the opcode table. We could speed this up
|
||||||
|
a bit by doing a binary search on the major opcode. */
|
||||||
|
opcode_end = powerpc_opcodes + powerpc_num_opcodes;
|
||||||
|
for (opcode = powerpc_opcodes; opcode < opcode_end; opcode++)
|
||||||
|
{
|
||||||
|
unsigned long table_op;
|
||||||
|
const unsigned char *opindex;
|
||||||
|
const struct powerpc_operand *operand;
|
||||||
|
int invalid;
|
||||||
|
int need_comma;
|
||||||
|
int need_paren;
|
||||||
|
|
||||||
|
table_op = PPC_OP (opcode->opcode);
|
||||||
|
if (op < table_op)
|
||||||
|
break;
|
||||||
|
if (op > table_op)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((insn & opcode->mask) != opcode->opcode
|
||||||
|
|| (opcode->flags & dialect) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Make two passes over the operands. First see if any of them
|
||||||
|
have extraction functions, and, if they do, make sure the
|
||||||
|
instruction is valid. */
|
||||||
|
invalid = 0;
|
||||||
|
for (opindex = opcode->operands; *opindex != 0; opindex++)
|
||||||
|
{
|
||||||
|
operand = powerpc_operands + *opindex;
|
||||||
|
if (operand->extract)
|
||||||
|
(*operand->extract) (insn, &invalid);
|
||||||
|
}
|
||||||
|
if (invalid)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* The instruction is valid. */
|
||||||
|
(*info->fprintf_func) (info->stream, "%s", opcode->name);
|
||||||
|
if (opcode->operands[0] != 0)
|
||||||
|
(*info->fprintf_func) (info->stream, "\t");
|
||||||
|
|
||||||
|
/* Now extract and print the operands. */
|
||||||
|
need_comma = 0;
|
||||||
|
need_paren = 0;
|
||||||
|
for (opindex = opcode->operands; *opindex != 0; opindex++)
|
||||||
|
{
|
||||||
|
long value;
|
||||||
|
|
||||||
|
operand = powerpc_operands + *opindex;
|
||||||
|
|
||||||
|
/* Operands that are marked FAKE are simply ignored. We
|
||||||
|
already made sure that the extract function considered
|
||||||
|
the instruction to be valid. */
|
||||||
|
if ((operand->flags & PPC_OPERAND_FAKE) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Extract the value from the instruction. */
|
||||||
|
if (operand->extract)
|
||||||
|
value = (*operand->extract) (insn, (int *) NULL);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
|
||||||
|
if ((operand->flags & PPC_OPERAND_SIGNED) != 0
|
||||||
|
&& (value & (1 << (operand->bits - 1))) != 0)
|
||||||
|
value -= 1 << operand->bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the operand is optional, and the value is zero, don't
|
||||||
|
print anything. */
|
||||||
|
if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
|
||||||
|
&& (operand->flags & PPC_OPERAND_NEXT) == 0
|
||||||
|
&& value == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (need_comma)
|
||||||
|
{
|
||||||
|
(*info->fprintf_func) (info->stream, ",");
|
||||||
|
need_comma = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print the operand as directed by the flags. */
|
||||||
|
if ((operand->flags & PPC_OPERAND_GPR) != 0)
|
||||||
|
(*info->fprintf_func) (info->stream, "r%ld", value);
|
||||||
|
else if ((operand->flags & PPC_OPERAND_FPR) != 0)
|
||||||
|
(*info->fprintf_func) (info->stream, "f%ld", value);
|
||||||
|
else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
|
||||||
|
(*info->print_address_func) (memaddr + value, info);
|
||||||
|
else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
|
||||||
|
(*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
|
||||||
|
else if ((operand->flags & PPC_OPERAND_CR) == 0
|
||||||
|
|| (dialect & PPC_OPCODE_PPC) == 0)
|
||||||
|
(*info->fprintf_func) (info->stream, "%ld", value);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (operand->bits == 3)
|
||||||
|
(*info->fprintf_func) (info->stream, "cr%d", value);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
|
||||||
|
int cr;
|
||||||
|
int cc;
|
||||||
|
|
||||||
|
cr = value >> 2;
|
||||||
|
if (cr != 0)
|
||||||
|
(*info->fprintf_func) (info->stream, "4*cr%d", cr);
|
||||||
|
cc = value & 3;
|
||||||
|
if (cc != 0)
|
||||||
|
{
|
||||||
|
if (cr != 0)
|
||||||
|
(*info->fprintf_func) (info->stream, "+");
|
||||||
|
(*info->fprintf_func) (info->stream, "%s", cbnames[cc]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (need_paren)
|
||||||
|
{
|
||||||
|
(*info->fprintf_func) (info->stream, ")");
|
||||||
|
need_paren = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((operand->flags & PPC_OPERAND_PARENS) == 0)
|
||||||
|
need_comma = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(*info->fprintf_func) (info->stream, "(");
|
||||||
|
need_paren = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We have found and printed an instruction; return. */
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We could not find a match. */
|
||||||
|
(*info->fprintf_func) (info->stream, ".long 0x%lx", insn);
|
||||||
|
|
||||||
|
return 4;
|
||||||
|
}
|
2830
opcode/ppc-opc.c
Normal file
2830
opcode/ppc-opc.c
Normal file
File diff suppressed because it is too large
Load diff
248
opcode/ppc.h
Normal file
248
opcode/ppc.h
Normal file
|
@ -0,0 +1,248 @@
|
||||||
|
/* ppc.h -- Header file for PowerPC opcode table
|
||||||
|
Copyright 1994, 1995 Free Software Foundation, Inc.
|
||||||
|
Written by Ian Lance Taylor, Cygnus Support
|
||||||
|
|
||||||
|
This file is part of GDB, GAS, and the GNU binutils.
|
||||||
|
|
||||||
|
GDB, GAS, and the GNU binutils are free software; you can redistribute
|
||||||
|
them and/or modify them 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.
|
||||||
|
|
||||||
|
GDB, GAS, and the GNU binutils are distributed in the hope that they
|
||||||
|
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 file; see the file COPYING. If not, write to the Free
|
||||||
|
Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#ifndef PPC_H
|
||||||
|
#define PPC_H
|
||||||
|
|
||||||
|
/* The opcode table is an array of struct powerpc_opcode. */
|
||||||
|
|
||||||
|
struct powerpc_opcode
|
||||||
|
{
|
||||||
|
/* The opcode name. */
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
/* The opcode itself. Those bits which will be filled in with
|
||||||
|
operands are zeroes. */
|
||||||
|
unsigned long opcode;
|
||||||
|
|
||||||
|
/* The opcode mask. This is used by the disassembler. This is a
|
||||||
|
mask containing ones indicating those bits which must match the
|
||||||
|
opcode field, and zeroes indicating those bits which need not
|
||||||
|
match (and are presumably filled in by operands). */
|
||||||
|
unsigned long mask;
|
||||||
|
|
||||||
|
/* One bit flags for the opcode. These are used to indicate which
|
||||||
|
specific processors support the instructions. The defined values
|
||||||
|
are listed below. */
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
/* An array of operand codes. Each code is an index into the
|
||||||
|
operand table. They appear in the order which the operands must
|
||||||
|
appear in assembly code, and are terminated by a zero. */
|
||||||
|
unsigned char operands[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The table itself is sorted by major opcode number, and is otherwise
|
||||||
|
in the order in which the disassembler should consider
|
||||||
|
instructions. */
|
||||||
|
extern const struct powerpc_opcode powerpc_opcodes[];
|
||||||
|
extern const int powerpc_num_opcodes;
|
||||||
|
|
||||||
|
/* Values defined for the flags field of a struct powerpc_opcode. */
|
||||||
|
|
||||||
|
/* Opcode is defined for the PowerPC architecture. */
|
||||||
|
#define PPC_OPCODE_PPC (01)
|
||||||
|
|
||||||
|
/* Opcode is defined for the POWER (RS/6000) architecture. */
|
||||||
|
#define PPC_OPCODE_POWER (02)
|
||||||
|
|
||||||
|
/* Opcode is defined for the POWER2 (Rios 2) architecture. */
|
||||||
|
#define PPC_OPCODE_POWER2 (04)
|
||||||
|
|
||||||
|
/* Opcode is only defined on 32 bit architectures. */
|
||||||
|
#define PPC_OPCODE_32 (010)
|
||||||
|
|
||||||
|
/* Opcode is only defined on 64 bit architectures. */
|
||||||
|
#define PPC_OPCODE_64 (020)
|
||||||
|
|
||||||
|
/* Opcode is supported by the Motorola PowerPC 601 processor. The 601
|
||||||
|
is assumed to support all PowerPC (PPC_OPCODE_PPC) instructions,
|
||||||
|
but it also supports many additional POWER instructions. */
|
||||||
|
#define PPC_OPCODE_601 (040)
|
||||||
|
|
||||||
|
/* Opcode is supported in both the Power and PowerPC architectures
|
||||||
|
(ie, compiler's -mcpu=common or assembler's -mcom). */
|
||||||
|
#define PPC_OPCODE_COMMON (0100)
|
||||||
|
|
||||||
|
/* Opcode is supported for any Power or PowerPC platform (this is
|
||||||
|
for the assembler's -many option, and it eliminates duplicates). */
|
||||||
|
#define PPC_OPCODE_ANY (0200)
|
||||||
|
|
||||||
|
/* A macro to extract the major opcode from an instruction. */
|
||||||
|
#define PPC_OP(i) (((i) >> 26) & 0x3f)
|
||||||
|
|
||||||
|
/* The operands table is an array of struct powerpc_operand. */
|
||||||
|
|
||||||
|
struct powerpc_operand
|
||||||
|
{
|
||||||
|
/* The number of bits in the operand. */
|
||||||
|
int bits;
|
||||||
|
|
||||||
|
/* How far the operand is left shifted in the instruction. */
|
||||||
|
int shift;
|
||||||
|
|
||||||
|
/* Insertion function. This is used by the assembler. To insert an
|
||||||
|
operand value into an instruction, check this field.
|
||||||
|
|
||||||
|
If it is NULL, execute
|
||||||
|
i |= (op & ((1 << o->bits) - 1)) << o->shift;
|
||||||
|
(i is the instruction which we are filling in, o is a pointer to
|
||||||
|
this structure, and op is the opcode value; this assumes twos
|
||||||
|
complement arithmetic).
|
||||||
|
|
||||||
|
If this field is not NULL, then simply call it with the
|
||||||
|
instruction and the operand value. It will return the new value
|
||||||
|
of the instruction. If the ERRMSG argument is not NULL, then if
|
||||||
|
the operand value is illegal, *ERRMSG will be set to a warning
|
||||||
|
string (the operand will be inserted in any case). If the
|
||||||
|
operand value is legal, *ERRMSG will be unchanged (most operands
|
||||||
|
can accept any value). */
|
||||||
|
unsigned long (*insert) PARAMS ((unsigned long instruction, long op,
|
||||||
|
const char **errmsg));
|
||||||
|
|
||||||
|
/* Extraction function. This is used by the disassembler. To
|
||||||
|
extract this operand type from an instruction, check this field.
|
||||||
|
|
||||||
|
If it is NULL, compute
|
||||||
|
op = ((i) >> o->shift) & ((1 << o->bits) - 1);
|
||||||
|
if ((o->flags & PPC_OPERAND_SIGNED) != 0
|
||||||
|
&& (op & (1 << (o->bits - 1))) != 0)
|
||||||
|
op -= 1 << o->bits;
|
||||||
|
(i is the instruction, o is a pointer to this structure, and op
|
||||||
|
is the result; this assumes twos complement arithmetic).
|
||||||
|
|
||||||
|
If this field is not NULL, then simply call it with the
|
||||||
|
instruction value. It will return the value of the operand. If
|
||||||
|
the INVALID argument is not NULL, *INVALID will be set to
|
||||||
|
non-zero if this operand type can not actually be extracted from
|
||||||
|
this operand (i.e., the instruction does not match). If the
|
||||||
|
operand is valid, *INVALID will not be changed. */
|
||||||
|
long (*extract) PARAMS ((unsigned long instruction, int *invalid));
|
||||||
|
|
||||||
|
/* One bit syntax flags. */
|
||||||
|
unsigned long flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Elements in the table are retrieved by indexing with values from
|
||||||
|
the operands field of the powerpc_opcodes table. */
|
||||||
|
|
||||||
|
extern const struct powerpc_operand powerpc_operands[];
|
||||||
|
|
||||||
|
/* Values defined for the flags field of a struct powerpc_operand. */
|
||||||
|
|
||||||
|
/* This operand takes signed values. */
|
||||||
|
#define PPC_OPERAND_SIGNED (01)
|
||||||
|
|
||||||
|
/* This operand takes signed values, but also accepts a full positive
|
||||||
|
range of values when running in 32 bit mode. That is, if bits is
|
||||||
|
16, it takes any value from -0x8000 to 0xffff. In 64 bit mode,
|
||||||
|
this flag is ignored. */
|
||||||
|
#define PPC_OPERAND_SIGNOPT (02)
|
||||||
|
|
||||||
|
/* This operand does not actually exist in the assembler input. This
|
||||||
|
is used to support extended mnemonics such as mr, for which two
|
||||||
|
operands fields are identical. The assembler should call the
|
||||||
|
insert function with any op value. The disassembler should call
|
||||||
|
the extract function, ignore the return value, and check the value
|
||||||
|
placed in the valid argument. */
|
||||||
|
#define PPC_OPERAND_FAKE (04)
|
||||||
|
|
||||||
|
/* The next operand should be wrapped in parentheses rather than
|
||||||
|
separated from this one by a comma. This is used for the load and
|
||||||
|
store instructions which want their operands to look like
|
||||||
|
reg,displacement(reg)
|
||||||
|
*/
|
||||||
|
#define PPC_OPERAND_PARENS (010)
|
||||||
|
|
||||||
|
/* This operand may use the symbolic names for the CR fields, which
|
||||||
|
are
|
||||||
|
lt 0 gt 1 eq 2 so 3 un 3
|
||||||
|
cr0 0 cr1 1 cr2 2 cr3 3
|
||||||
|
cr4 4 cr5 5 cr6 6 cr7 7
|
||||||
|
These may be combined arithmetically, as in cr2*4+gt. These are
|
||||||
|
only supported on the PowerPC, not the POWER. */
|
||||||
|
#define PPC_OPERAND_CR (020)
|
||||||
|
|
||||||
|
/* This operand names a register. The disassembler uses this to print
|
||||||
|
register names with a leading 'r'. */
|
||||||
|
#define PPC_OPERAND_GPR (040)
|
||||||
|
|
||||||
|
/* This operand names a floating point register. The disassembler
|
||||||
|
prints these with a leading 'f'. */
|
||||||
|
#define PPC_OPERAND_FPR (0100)
|
||||||
|
|
||||||
|
/* This operand is a relative branch displacement. The disassembler
|
||||||
|
prints these symbolically if possible. */
|
||||||
|
#define PPC_OPERAND_RELATIVE (0200)
|
||||||
|
|
||||||
|
/* This operand is an absolute branch address. The disassembler
|
||||||
|
prints these symbolically if possible. */
|
||||||
|
#define PPC_OPERAND_ABSOLUTE (0400)
|
||||||
|
|
||||||
|
/* This operand is optional, and is zero if omitted. This is used for
|
||||||
|
the optional BF and L fields in the comparison instructions. The
|
||||||
|
assembler must count the number of operands remaining on the line,
|
||||||
|
and the number of operands remaining for the opcode, and decide
|
||||||
|
whether this operand is present or not. The disassembler should
|
||||||
|
print this operand out only if it is not zero. */
|
||||||
|
#define PPC_OPERAND_OPTIONAL (01000)
|
||||||
|
|
||||||
|
/* This flag is only used with PPC_OPERAND_OPTIONAL. If this operand
|
||||||
|
is omitted, then for the next operand use this operand value plus
|
||||||
|
1, ignoring the next operand field for the opcode. This wretched
|
||||||
|
hack is needed because the Power rotate instructions can take
|
||||||
|
either 4 or 5 operands. The disassembler should print this operand
|
||||||
|
out regardless of the PPC_OPERAND_OPTIONAL field. */
|
||||||
|
#define PPC_OPERAND_NEXT (02000)
|
||||||
|
|
||||||
|
/* This operand should be regarded as a negative number for the
|
||||||
|
purposes of overflow checking (i.e., the normal most negative
|
||||||
|
number is disallowed and one more than the normal most positive
|
||||||
|
number is allowed). This flag will only be set for a signed
|
||||||
|
operand. */
|
||||||
|
#define PPC_OPERAND_NEGATIVE (04000)
|
||||||
|
|
||||||
|
/* The POWER and PowerPC assemblers use a few macros. We keep them
|
||||||
|
with the operands table for simplicity. The macro table is an
|
||||||
|
array of struct powerpc_macro. */
|
||||||
|
|
||||||
|
struct powerpc_macro
|
||||||
|
{
|
||||||
|
/* The macro name. */
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
/* The number of operands the macro takes. */
|
||||||
|
unsigned int operands;
|
||||||
|
|
||||||
|
/* One bit flags for the opcode. These are used to indicate which
|
||||||
|
specific processors support the instructions. The values are the
|
||||||
|
same as those for the struct powerpc_opcode flags field. */
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
/* A format string to turn the macro into a normal instruction.
|
||||||
|
Each %N in the string is replaced with operand number N (zero
|
||||||
|
based). */
|
||||||
|
const char *format;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const struct powerpc_macro powerpc_macros[];
|
||||||
|
extern const int powerpc_num_macros;
|
||||||
|
|
||||||
|
#endif /* PPC_H */
|
868
opcode/sparc-dis.c
Normal file
868
opcode/sparc-dis.c
Normal file
|
@ -0,0 +1,868 @@
|
||||||
|
/* Print SPARC instructions.
|
||||||
|
Copyright (C) 1989, 91-93, 1995, 1996 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#include "ansidecl.h"
|
||||||
|
#include "opcode/sparc.h"
|
||||||
|
#include "dis-asm.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* Bitmask of v9 architectures. */
|
||||||
|
#define MASK_V9 ((1 << SPARC_OPCODE_ARCH_V9) \
|
||||||
|
| (1 << SPARC_OPCODE_ARCH_V9A))
|
||||||
|
/* 1 if INSN is for v9 only. */
|
||||||
|
#define V9_ONLY_P(insn) (! ((insn)->architecture & ~MASK_V9))
|
||||||
|
/* 1 if INSN is for v9. */
|
||||||
|
#define V9_P(insn) (((insn)->architecture & MASK_V9) != 0)
|
||||||
|
|
||||||
|
/* For faster lookup, after insns are sorted they are hashed. */
|
||||||
|
/* ??? I think there is room for even more improvement. */
|
||||||
|
|
||||||
|
#define HASH_SIZE 256
|
||||||
|
/* It is important that we only look at insn code bits as that is how the
|
||||||
|
opcode table is hashed. OPCODE_BITS is a table of valid bits for each
|
||||||
|
of the main types (0,1,2,3). */
|
||||||
|
static int opcode_bits[4] = { 0x01c00000, 0x0, 0x01f80000, 0x01f80000 };
|
||||||
|
#define HASH_INSN(INSN) \
|
||||||
|
((((INSN) >> 24) & 0xc0) | (((INSN) & opcode_bits[((INSN) >> 30) & 3]) >> 19))
|
||||||
|
struct opcode_hash {
|
||||||
|
struct opcode_hash *next;
|
||||||
|
struct sparc_opcode *opcode;
|
||||||
|
};
|
||||||
|
static struct opcode_hash *opcode_hash_table[HASH_SIZE];
|
||||||
|
static void build_hash_table ();
|
||||||
|
|
||||||
|
/* Sign-extend a value which is N bits long. */
|
||||||
|
#define SEX(value, bits) \
|
||||||
|
((((int)(value)) << ((8 * sizeof (int)) - bits)) \
|
||||||
|
>> ((8 * sizeof (int)) - bits) )
|
||||||
|
|
||||||
|
static char *reg_names[] =
|
||||||
|
{ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
|
||||||
|
"o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
|
||||||
|
"l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
|
||||||
|
"i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
|
||||||
|
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
|
||||||
|
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
|
||||||
|
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
|
||||||
|
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
|
||||||
|
"f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
|
||||||
|
"f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
|
||||||
|
"f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
|
||||||
|
"f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
|
||||||
|
/* psr, wim, tbr, fpsr, cpsr are v8 only. */
|
||||||
|
"y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr"
|
||||||
|
};
|
||||||
|
|
||||||
|
#define freg_names (®_names[4 * 8])
|
||||||
|
|
||||||
|
/* These are ordered according to there register number in
|
||||||
|
rdpr and wrpr insns. */
|
||||||
|
static char *v9_priv_reg_names[] =
|
||||||
|
{
|
||||||
|
"tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl",
|
||||||
|
"pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
|
||||||
|
"wstate", "fq"
|
||||||
|
/* "ver" - special cased */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Macros used to extract instruction fields. Not all fields have
|
||||||
|
macros defined here, only those which are actually used. */
|
||||||
|
|
||||||
|
#define X_RD(i) (((i) >> 25) & 0x1f)
|
||||||
|
#define X_RS1(i) (((i) >> 14) & 0x1f)
|
||||||
|
#define X_LDST_I(i) (((i) >> 13) & 1)
|
||||||
|
#define X_ASI(i) (((i) >> 5) & 0xff)
|
||||||
|
#define X_RS2(i) (((i) >> 0) & 0x1f)
|
||||||
|
#define X_IMM13(i) (((i) >> 0) & 0x1fff)
|
||||||
|
#define X_DISP22(i) (((i) >> 0) & 0x3fffff)
|
||||||
|
#define X_IMM22(i) X_DISP22 (i)
|
||||||
|
#define X_DISP30(i) (((i) >> 0) & 0x3fffffff)
|
||||||
|
|
||||||
|
/* These are for v9. */
|
||||||
|
#define X_DISP16(i) (((((i) >> 20) & 3) << 14) | (((i) >> 0) & 0x3fff))
|
||||||
|
#define X_DISP19(i) (((i) >> 0) & 0x7ffff)
|
||||||
|
#define X_MEMBAR(i) ((i) & 0x7f)
|
||||||
|
|
||||||
|
/* Here is the union which was used to extract instruction fields
|
||||||
|
before the shift and mask macros were written.
|
||||||
|
|
||||||
|
union sparc_insn
|
||||||
|
{
|
||||||
|
unsigned long int code;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned int anop:2;
|
||||||
|
#define op ldst.anop
|
||||||
|
unsigned int anrd:5;
|
||||||
|
#define rd ldst.anrd
|
||||||
|
unsigned int op3:6;
|
||||||
|
unsigned int anrs1:5;
|
||||||
|
#define rs1 ldst.anrs1
|
||||||
|
unsigned int i:1;
|
||||||
|
unsigned int anasi:8;
|
||||||
|
#define asi ldst.anasi
|
||||||
|
unsigned int anrs2:5;
|
||||||
|
#define rs2 ldst.anrs2
|
||||||
|
#define shcnt rs2
|
||||||
|
} ldst;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1;
|
||||||
|
unsigned int IMM13:13;
|
||||||
|
#define imm13 IMM13.IMM13
|
||||||
|
} IMM13;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned int anop:2;
|
||||||
|
unsigned int a:1;
|
||||||
|
unsigned int cond:4;
|
||||||
|
unsigned int op2:3;
|
||||||
|
unsigned int DISP22:22;
|
||||||
|
#define disp22 branch.DISP22
|
||||||
|
#define imm22 disp22
|
||||||
|
} branch;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned int anop:2;
|
||||||
|
unsigned int a:1;
|
||||||
|
unsigned int z:1;
|
||||||
|
unsigned int rcond:3;
|
||||||
|
unsigned int op2:3;
|
||||||
|
unsigned int DISP16HI:2;
|
||||||
|
unsigned int p:1;
|
||||||
|
unsigned int _rs1:5;
|
||||||
|
unsigned int DISP16LO:14;
|
||||||
|
} branch16;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned int anop:2;
|
||||||
|
unsigned int adisp30:30;
|
||||||
|
#define disp30 call.adisp30
|
||||||
|
} call;
|
||||||
|
};
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Nonzero if INSN is the opcode for a delayed branch. */
|
||||||
|
static int
|
||||||
|
is_delayed_branch (insn)
|
||||||
|
unsigned long insn;
|
||||||
|
{
|
||||||
|
struct opcode_hash *op;
|
||||||
|
|
||||||
|
for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
|
||||||
|
{
|
||||||
|
const struct sparc_opcode *opcode = op->opcode;
|
||||||
|
if ((opcode->match & insn) == opcode->match
|
||||||
|
&& (opcode->lose & insn) == 0)
|
||||||
|
return (opcode->flags & F_DELAYED);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Nonzero of opcode table has been initialized. */
|
||||||
|
static int opcodes_initialized = 0;
|
||||||
|
|
||||||
|
/* extern void qsort (); */
|
||||||
|
static int compare_opcodes ();
|
||||||
|
|
||||||
|
/* Print one instruction from MEMADDR on INFO->STREAM.
|
||||||
|
|
||||||
|
We suffix the instruction with a comment that gives the absolute
|
||||||
|
address involved, as well as its symbolic form, if the instruction
|
||||||
|
is preceded by a findable `sethi' and it either adds an immediate
|
||||||
|
displacement to that register, or it is an `add' or `or' instruction
|
||||||
|
on that register. */
|
||||||
|
|
||||||
|
int
|
||||||
|
print_insn_sparc (memaddr, info)
|
||||||
|
bfd_vma memaddr;
|
||||||
|
disassemble_info *info;
|
||||||
|
{
|
||||||
|
FILE *stream = info->stream;
|
||||||
|
bfd_byte buffer[4];
|
||||||
|
unsigned long insn;
|
||||||
|
register unsigned int i;
|
||||||
|
register struct opcode_hash *op;
|
||||||
|
int sparc_v9_p = bfd_mach_sparc_v9_p (info->mach);
|
||||||
|
|
||||||
|
if (!opcodes_initialized)
|
||||||
|
{
|
||||||
|
qsort ((char *) sparc_opcodes, sparc_num_opcodes,
|
||||||
|
sizeof (sparc_opcodes[0]), compare_opcodes);
|
||||||
|
build_hash_table (sparc_opcodes, opcode_hash_table, sparc_num_opcodes);
|
||||||
|
opcodes_initialized = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int status =
|
||||||
|
(*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
|
||||||
|
if (status != 0)
|
||||||
|
{
|
||||||
|
(*info->memory_error_func) (status, memaddr, info);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
insn = bfd_getb32 (buffer);
|
||||||
|
|
||||||
|
info->insn_info_valid = 1; /* We do return this info */
|
||||||
|
info->insn_type = dis_nonbranch; /* Assume non branch insn */
|
||||||
|
info->branch_delay_insns = 0; /* Assume no delay */
|
||||||
|
info->target = 0; /* Assume no target known */
|
||||||
|
|
||||||
|
for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
|
||||||
|
{
|
||||||
|
const struct sparc_opcode *opcode = op->opcode;
|
||||||
|
|
||||||
|
/* ??? These architecture tests need to be more selective. */
|
||||||
|
|
||||||
|
/* If the current architecture isn't sparc64, skip sparc64 insns. */
|
||||||
|
if (!sparc_v9_p
|
||||||
|
&& V9_ONLY_P (opcode))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* If the current architecture is sparc64, skip sparc32 only insns. */
|
||||||
|
if (sparc_v9_p
|
||||||
|
&& ! V9_P (opcode))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((opcode->match & insn) == opcode->match
|
||||||
|
&& (opcode->lose & insn) == 0)
|
||||||
|
{
|
||||||
|
/* Nonzero means that we have found an instruction which has
|
||||||
|
the effect of adding or or'ing the imm13 field to rs1. */
|
||||||
|
int imm_added_to_rs1 = 0;
|
||||||
|
|
||||||
|
/* Nonzero means that we have found a plus sign in the args
|
||||||
|
field of the opcode table. */
|
||||||
|
int found_plus = 0;
|
||||||
|
|
||||||
|
/* Nonzero means we have an annulled branch. */
|
||||||
|
int is_annulled = 0;
|
||||||
|
|
||||||
|
/* Do we have an `add' or `or' instruction where rs1 is the same
|
||||||
|
as rsd, and which has the i bit set? */
|
||||||
|
if ((opcode->match == 0x80102000 || opcode->match == 0x80002000)
|
||||||
|
/* (or) (add) */
|
||||||
|
&& X_RS1 (insn) == X_RD (insn))
|
||||||
|
imm_added_to_rs1 = 1;
|
||||||
|
|
||||||
|
if (X_RS1 (insn) != X_RD (insn)
|
||||||
|
&& strchr (opcode->args, 'r') != 0)
|
||||||
|
/* Can't do simple format if source and dest are different. */
|
||||||
|
continue;
|
||||||
|
if (X_RS2 (insn) != X_RD (insn)
|
||||||
|
&& strchr (opcode->args, 'O') != 0)
|
||||||
|
/* Can't do simple format if source and dest are different. */
|
||||||
|
continue;
|
||||||
|
|
||||||
|
(*info->fprintf_func) (stream, opcode->name);
|
||||||
|
|
||||||
|
{
|
||||||
|
register const char *s;
|
||||||
|
|
||||||
|
if (opcode->args[0] != ',')
|
||||||
|
(*info->fprintf_func) (stream, " ");
|
||||||
|
for (s = opcode->args; *s != '\0'; ++s)
|
||||||
|
{
|
||||||
|
while (*s == ',')
|
||||||
|
{
|
||||||
|
(*info->fprintf_func) (stream, ",");
|
||||||
|
++s;
|
||||||
|
switch (*s) {
|
||||||
|
case 'a':
|
||||||
|
(*info->fprintf_func) (stream, "a");
|
||||||
|
is_annulled = 1;
|
||||||
|
++s;
|
||||||
|
continue;
|
||||||
|
case 'N':
|
||||||
|
(*info->fprintf_func) (stream, "pn");
|
||||||
|
++s;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 'T':
|
||||||
|
(*info->fprintf_func) (stream, "pt");
|
||||||
|
++s;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
} /* switch on arg */
|
||||||
|
} /* while there are comma started args */
|
||||||
|
|
||||||
|
(*info->fprintf_func) (stream, " ");
|
||||||
|
|
||||||
|
switch (*s)
|
||||||
|
{
|
||||||
|
case '+':
|
||||||
|
found_plus = 1;
|
||||||
|
|
||||||
|
/* note fall-through */
|
||||||
|
default:
|
||||||
|
(*info->fprintf_func) (stream, "%c", *s);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '#':
|
||||||
|
(*info->fprintf_func) (stream, "0");
|
||||||
|
break;
|
||||||
|
|
||||||
|
#define reg(n) (*info->fprintf_func) (stream, "%%%s", reg_names[n])
|
||||||
|
case '1':
|
||||||
|
case 'r':
|
||||||
|
reg (X_RS1 (insn));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '2':
|
||||||
|
case 'O':
|
||||||
|
reg (X_RS2 (insn));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
reg (X_RD (insn));
|
||||||
|
break;
|
||||||
|
#undef reg
|
||||||
|
|
||||||
|
#define freg(n) (*info->fprintf_func) (stream, "%%%s", freg_names[n])
|
||||||
|
#define fregx(n) (*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)])
|
||||||
|
case 'e':
|
||||||
|
freg (X_RS1 (insn));
|
||||||
|
break;
|
||||||
|
case 'v': /* double/even */
|
||||||
|
case 'V': /* quad/multiple of 4 */
|
||||||
|
fregx (X_RS1 (insn));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
freg (X_RS2 (insn));
|
||||||
|
break;
|
||||||
|
case 'B': /* double/even */
|
||||||
|
case 'R': /* quad/multiple of 4 */
|
||||||
|
fregx (X_RS2 (insn));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'g':
|
||||||
|
freg (X_RD (insn));
|
||||||
|
break;
|
||||||
|
case 'H': /* double/even */
|
||||||
|
case 'J': /* quad/multiple of 4 */
|
||||||
|
fregx (X_RD (insn));
|
||||||
|
break;
|
||||||
|
#undef freg
|
||||||
|
#undef fregx
|
||||||
|
|
||||||
|
#define creg(n) (*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n))
|
||||||
|
case 'b':
|
||||||
|
creg (X_RS1 (insn));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'c':
|
||||||
|
creg (X_RS2 (insn));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'D':
|
||||||
|
creg (X_RD (insn));
|
||||||
|
break;
|
||||||
|
#undef creg
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
(*info->fprintf_func) (stream, "%%hi(%#x)",
|
||||||
|
(0xFFFFFFFF
|
||||||
|
& ((int) X_IMM22 (insn) << 10)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'i':
|
||||||
|
{
|
||||||
|
int imm = SEX (X_IMM13 (insn), 13);
|
||||||
|
|
||||||
|
/* Check to see whether we have a 1+i, and take
|
||||||
|
note of that fact.
|
||||||
|
|
||||||
|
Note: because of the way we sort the table,
|
||||||
|
we will be matching 1+i rather than i+1,
|
||||||
|
so it is OK to assume that i is after +,
|
||||||
|
not before it. */
|
||||||
|
if (found_plus)
|
||||||
|
imm_added_to_rs1 = 1;
|
||||||
|
|
||||||
|
if (imm <= 9)
|
||||||
|
(*info->fprintf_func) (stream, "%d", imm);
|
||||||
|
else
|
||||||
|
(*info->fprintf_func) (stream, "%#x", imm);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'I': /* 11 bit immediate. */
|
||||||
|
case 'j': /* 10 bit immediate. */
|
||||||
|
{
|
||||||
|
int imm;
|
||||||
|
|
||||||
|
if (*s == 'I')
|
||||||
|
imm = SEX (X_IMM13 (insn), 11);
|
||||||
|
else
|
||||||
|
imm = SEX (X_IMM13 (insn), 10);
|
||||||
|
|
||||||
|
/* Check to see whether we have a 1+i, and take
|
||||||
|
note of that fact.
|
||||||
|
|
||||||
|
Note: because of the way we sort the table,
|
||||||
|
we will be matching 1+i rather than i+1,
|
||||||
|
so it is OK to assume that i is after +,
|
||||||
|
not before it. */
|
||||||
|
if (found_plus)
|
||||||
|
imm_added_to_rs1 = 1;
|
||||||
|
|
||||||
|
if (imm <= 9)
|
||||||
|
(info->fprintf_func) (stream, "%d", imm);
|
||||||
|
else
|
||||||
|
(info->fprintf_func) (stream, "%#x", (unsigned) imm);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'K':
|
||||||
|
{
|
||||||
|
int mask = X_MEMBAR (insn);
|
||||||
|
int bit = 0x40, printed_one = 0;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
if (mask == 0)
|
||||||
|
(info->fprintf_func) (stream, "0");
|
||||||
|
else
|
||||||
|
while (bit)
|
||||||
|
{
|
||||||
|
if (mask & bit)
|
||||||
|
{
|
||||||
|
if (printed_one)
|
||||||
|
(info->fprintf_func) (stream, "|");
|
||||||
|
name = sparc_decode_membar (bit);
|
||||||
|
(info->fprintf_func) (stream, "%s", name);
|
||||||
|
printed_one = 1;
|
||||||
|
}
|
||||||
|
bit >>= 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'k':
|
||||||
|
info->target = memaddr + SEX (X_DISP16 (insn), 16) * 4;
|
||||||
|
(*info->print_address_func) (info->target, info);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'G':
|
||||||
|
info->target = memaddr + SEX (X_DISP19 (insn), 19) * 4;
|
||||||
|
(*info->print_address_func) (info->target, info);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '6':
|
||||||
|
case '7':
|
||||||
|
case '8':
|
||||||
|
case '9':
|
||||||
|
(*info->fprintf_func) (stream, "%%fcc%c", *s - '6' + '0');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'z':
|
||||||
|
(*info->fprintf_func) (stream, "%%icc");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'Z':
|
||||||
|
(*info->fprintf_func) (stream, "%%xcc");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'E':
|
||||||
|
(*info->fprintf_func) (stream, "%%ccr");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
(*info->fprintf_func) (stream, "%%fprs");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'o':
|
||||||
|
(*info->fprintf_func) (stream, "%%asi");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'W':
|
||||||
|
(*info->fprintf_func) (stream, "%%tick");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'P':
|
||||||
|
(*info->fprintf_func) (stream, "%%pc");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '?':
|
||||||
|
if (X_RS1 (insn) == 31)
|
||||||
|
(*info->fprintf_func) (stream, "%%ver");
|
||||||
|
else if ((unsigned) X_RS1 (insn) < 16)
|
||||||
|
(*info->fprintf_func) (stream, "%%%s",
|
||||||
|
v9_priv_reg_names[X_RS1 (insn)]);
|
||||||
|
else
|
||||||
|
(*info->fprintf_func) (stream, "%%reserved");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '!':
|
||||||
|
if ((unsigned) X_RD (insn) < 15)
|
||||||
|
(*info->fprintf_func) (stream, "%%%s",
|
||||||
|
v9_priv_reg_names[X_RD (insn)]);
|
||||||
|
else
|
||||||
|
(*info->fprintf_func) (stream, "%%reserved");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '*':
|
||||||
|
{
|
||||||
|
char *name = sparc_decode_prefetch (X_RD (insn));
|
||||||
|
|
||||||
|
if (name)
|
||||||
|
(*info->fprintf_func) (stream, "%s", name);
|
||||||
|
else
|
||||||
|
(*info->fprintf_func) (stream, "%d", X_RD (insn));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'M':
|
||||||
|
(*info->fprintf_func) (stream, "%%asr%d", X_RS1 (insn));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'm':
|
||||||
|
(*info->fprintf_func) (stream, "%%asr%d", X_RD (insn));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'L':
|
||||||
|
info->target = memaddr + SEX (X_DISP30 (insn), 30) * 4;
|
||||||
|
(*info->print_address_func) (info->target, info);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'n':
|
||||||
|
(*info->fprintf_func)
|
||||||
|
(stream, "%#x", SEX (X_DISP22 (insn), 22));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'l':
|
||||||
|
info->target = memaddr + SEX (X_DISP22 (insn), 22) * 4;
|
||||||
|
(*info->print_address_func) (info->target, info);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'A':
|
||||||
|
{
|
||||||
|
char *name = sparc_decode_asi (X_ASI (insn));
|
||||||
|
|
||||||
|
if (name)
|
||||||
|
(*info->fprintf_func) (stream, "%s", name);
|
||||||
|
else
|
||||||
|
(*info->fprintf_func) (stream, "(%d)", X_ASI (insn));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'C':
|
||||||
|
(*info->fprintf_func) (stream, "%%csr");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'F':
|
||||||
|
(*info->fprintf_func) (stream, "%%fsr");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
(*info->fprintf_func) (stream, "%%psr");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'q':
|
||||||
|
(*info->fprintf_func) (stream, "%%fq");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'Q':
|
||||||
|
(*info->fprintf_func) (stream, "%%cq");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 't':
|
||||||
|
(*info->fprintf_func) (stream, "%%tbr");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'w':
|
||||||
|
(*info->fprintf_func) (stream, "%%wim");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'x':
|
||||||
|
(*info->fprintf_func) (stream, "%d",
|
||||||
|
((X_LDST_I (insn) << 8)
|
||||||
|
+ X_ASI (insn)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'y':
|
||||||
|
(*info->fprintf_func) (stream, "%%y");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'u':
|
||||||
|
case 'U':
|
||||||
|
{
|
||||||
|
int val = *s == 'U' ? X_RS1 (insn) : X_RD (insn);
|
||||||
|
char *name = sparc_decode_sparclet_cpreg (val);
|
||||||
|
|
||||||
|
if (name)
|
||||||
|
(*info->fprintf_func) (stream, "%s", name);
|
||||||
|
else
|
||||||
|
(*info->fprintf_func) (stream, "%%cpreg(%d)", val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we are adding or or'ing something to rs1, then
|
||||||
|
check to see whether the previous instruction was
|
||||||
|
a sethi to the same register as in the sethi.
|
||||||
|
If so, attempt to print the result of the add or
|
||||||
|
or (in this context add and or do the same thing)
|
||||||
|
and its symbolic value. */
|
||||||
|
if (imm_added_to_rs1)
|
||||||
|
{
|
||||||
|
unsigned long prev_insn;
|
||||||
|
int errcode;
|
||||||
|
|
||||||
|
errcode =
|
||||||
|
(*info->read_memory_func)
|
||||||
|
(memaddr - 4, buffer, sizeof (buffer), info);
|
||||||
|
prev_insn = bfd_getb32 (buffer);
|
||||||
|
|
||||||
|
if (errcode == 0)
|
||||||
|
{
|
||||||
|
/* If it is a delayed branch, we need to look at the
|
||||||
|
instruction before the delayed branch. This handles
|
||||||
|
sequences such as
|
||||||
|
|
||||||
|
sethi %o1, %hi(_foo), %o1
|
||||||
|
call _printf
|
||||||
|
or %o1, %lo(_foo), %o1
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (is_delayed_branch (prev_insn))
|
||||||
|
{
|
||||||
|
errcode = (*info->read_memory_func)
|
||||||
|
(memaddr - 8, buffer, sizeof (buffer), info);
|
||||||
|
prev_insn = bfd_getb32 (buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If there was a problem reading memory, then assume
|
||||||
|
the previous instruction was not sethi. */
|
||||||
|
if (errcode == 0)
|
||||||
|
{
|
||||||
|
/* Is it sethi to the same register? */
|
||||||
|
if ((prev_insn & 0xc1c00000) == 0x01000000
|
||||||
|
&& X_RD (prev_insn) == X_RS1 (insn))
|
||||||
|
{
|
||||||
|
(*info->fprintf_func) (stream, "\t! ");
|
||||||
|
info->target =
|
||||||
|
(0xFFFFFFFF & (int) X_IMM22 (prev_insn) << 10)
|
||||||
|
| SEX (X_IMM13 (insn), 13);
|
||||||
|
(*info->print_address_func) (info->target, info);
|
||||||
|
info->insn_type = dis_dref;
|
||||||
|
info->data_size = 4; /* FIXME!!! */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR))
|
||||||
|
{
|
||||||
|
/* FIXME -- check is_annulled flag */
|
||||||
|
if (opcode->flags & F_UNBR)
|
||||||
|
info->insn_type = dis_branch;
|
||||||
|
if (opcode->flags & F_CONDBR)
|
||||||
|
info->insn_type = dis_condbranch;
|
||||||
|
if (opcode->flags & F_JSR)
|
||||||
|
info->insn_type = dis_jsr;
|
||||||
|
if (opcode->flags & F_DELAYED)
|
||||||
|
info->branch_delay_insns = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sizeof (buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
info->insn_type = dis_noninsn; /* Mark as non-valid instruction */
|
||||||
|
(*info->fprintf_func) (stream, "unknown");
|
||||||
|
return sizeof (buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compare opcodes A and B. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
compare_opcodes (a, b)
|
||||||
|
char *a, *b;
|
||||||
|
{
|
||||||
|
struct sparc_opcode *op0 = (struct sparc_opcode *) a;
|
||||||
|
struct sparc_opcode *op1 = (struct sparc_opcode *) b;
|
||||||
|
unsigned long int match0 = op0->match, match1 = op1->match;
|
||||||
|
unsigned long int lose0 = op0->lose, lose1 = op1->lose;
|
||||||
|
register unsigned int i;
|
||||||
|
|
||||||
|
/* If a bit is set in both match and lose, there is something
|
||||||
|
wrong with the opcode table. */
|
||||||
|
if (match0 & lose0)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
|
||||||
|
op0->name, match0, lose0);
|
||||||
|
op0->lose &= ~op0->match;
|
||||||
|
lose0 = op0->lose;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match1 & lose1)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
|
||||||
|
op1->name, match1, lose1);
|
||||||
|
op1->lose &= ~op1->match;
|
||||||
|
lose1 = op1->lose;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Because the bits that are variable in one opcode are constant in
|
||||||
|
another, it is important to order the opcodes in the right order. */
|
||||||
|
for (i = 0; i < 32; ++i)
|
||||||
|
{
|
||||||
|
unsigned long int x = 1 << i;
|
||||||
|
int x0 = (match0 & x) != 0;
|
||||||
|
int x1 = (match1 & x) != 0;
|
||||||
|
|
||||||
|
if (x0 != x1)
|
||||||
|
return x1 - x0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 32; ++i)
|
||||||
|
{
|
||||||
|
unsigned long int x = 1 << i;
|
||||||
|
int x0 = (lose0 & x) != 0;
|
||||||
|
int x1 = (lose1 & x) != 0;
|
||||||
|
|
||||||
|
if (x0 != x1)
|
||||||
|
return x1 - x0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Put non-sparc64 insns ahead of sparc64 ones. */
|
||||||
|
if (V9_ONLY_P (op0) != V9_ONLY_P (op1))
|
||||||
|
return V9_ONLY_P (op0) - V9_ONLY_P (op1);
|
||||||
|
|
||||||
|
/* They are functionally equal. So as long as the opcode table is
|
||||||
|
valid, we can put whichever one first we want, on aesthetic grounds. */
|
||||||
|
|
||||||
|
/* Our first aesthetic ground is that aliases defer to real insns. */
|
||||||
|
{
|
||||||
|
int alias_diff = (op0->flags & F_ALIAS) - (op1->flags & F_ALIAS);
|
||||||
|
if (alias_diff != 0)
|
||||||
|
/* Put the one that isn't an alias first. */
|
||||||
|
return alias_diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Except for aliases, two "identical" instructions had
|
||||||
|
better have the same opcode. This is a sanity check on the table. */
|
||||||
|
i = strcmp (op0->name, op1->name);
|
||||||
|
if (i)
|
||||||
|
if (op0->flags & F_ALIAS) /* If they're both aliases, be arbitrary. */
|
||||||
|
return i;
|
||||||
|
else
|
||||||
|
fprintf (stderr,
|
||||||
|
"Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n",
|
||||||
|
op0->name, op1->name);
|
||||||
|
|
||||||
|
/* Fewer arguments are preferred. */
|
||||||
|
{
|
||||||
|
int length_diff = strlen (op0->args) - strlen (op1->args);
|
||||||
|
if (length_diff != 0)
|
||||||
|
/* Put the one with fewer arguments first. */
|
||||||
|
return length_diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Put 1+i before i+1. */
|
||||||
|
{
|
||||||
|
char *p0 = (char *) strchr(op0->args, '+');
|
||||||
|
char *p1 = (char *) strchr(op1->args, '+');
|
||||||
|
|
||||||
|
if (p0 && p1)
|
||||||
|
{
|
||||||
|
/* There is a plus in both operands. Note that a plus
|
||||||
|
sign cannot be the first character in args,
|
||||||
|
so the following [-1]'s are valid. */
|
||||||
|
if (p0[-1] == 'i' && p1[1] == 'i')
|
||||||
|
/* op0 is i+1 and op1 is 1+i, so op1 goes first. */
|
||||||
|
return 1;
|
||||||
|
if (p0[1] == 'i' && p1[-1] == 'i')
|
||||||
|
/* op0 is 1+i and op1 is i+1, so op0 goes first. */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Put 1,i before i,1. */
|
||||||
|
{
|
||||||
|
int i0 = strncmp (op0->args, "i,1", 3) == 0;
|
||||||
|
int i1 = strncmp (op1->args, "i,1", 3) == 0;
|
||||||
|
|
||||||
|
if (i0 ^ i1)
|
||||||
|
return i0 - i1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* They are, as far as we can tell, identical.
|
||||||
|
Since qsort may have rearranged the table partially, there is
|
||||||
|
no way to tell which one was first in the opcode table as
|
||||||
|
written, so just say there are equal. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build a hash table from the opcode table. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
build_hash_table (table, hash_table, num_opcodes)
|
||||||
|
struct sparc_opcode *table;
|
||||||
|
struct opcode_hash **hash_table;
|
||||||
|
int num_opcodes;
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
int hash_count[HASH_SIZE];
|
||||||
|
static struct opcode_hash *hash_buf = NULL;
|
||||||
|
|
||||||
|
/* Start at the end of the table and work backwards so that each
|
||||||
|
chain is sorted. */
|
||||||
|
|
||||||
|
memset (hash_table, 0, HASH_SIZE * sizeof (hash_table[0]));
|
||||||
|
memset (hash_count, 0, HASH_SIZE * sizeof (hash_count[0]));
|
||||||
|
if (hash_buf != NULL)
|
||||||
|
free (hash_buf);
|
||||||
|
hash_buf = (struct opcode_hash *) xmalloc (sizeof (struct opcode_hash) * num_opcodes);
|
||||||
|
for (i = num_opcodes - 1; i >= 0; --i)
|
||||||
|
{
|
||||||
|
register int hash = HASH_INSN (sparc_opcodes[i].match);
|
||||||
|
register struct opcode_hash *h = &hash_buf[i];
|
||||||
|
h->next = hash_table[hash];
|
||||||
|
h->opcode = &sparc_opcodes[i];
|
||||||
|
hash_table[hash] = h;
|
||||||
|
++hash_count[hash];
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0 /* for debugging */
|
||||||
|
{
|
||||||
|
int min_count = num_opcodes, max_count = 0;
|
||||||
|
int total;
|
||||||
|
|
||||||
|
for (i = 0; i < HASH_SIZE; ++i)
|
||||||
|
{
|
||||||
|
if (hash_count[i] < min_count)
|
||||||
|
min_count = hash_count[i];
|
||||||
|
if (hash_count[i] > max_count)
|
||||||
|
max_count = hash_count[i];
|
||||||
|
total += hash_count[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("Opcode hash table stats: min %d, max %d, ave %f\n",
|
||||||
|
min_count, max_count, (double) total / HASH_SIZE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
1757
opcode/sparc-opc.c
Normal file
1757
opcode/sparc-opc.c
Normal file
File diff suppressed because it is too large
Load diff
220
opcode/sparc.h
Normal file
220
opcode/sparc.h
Normal file
|
@ -0,0 +1,220 @@
|
||||||
|
/* Definitions for opcode table for the sparc.
|
||||||
|
Copyright (C) 1989, 1991, 1992, 1995, 1996 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GAS, the GNU Assembler, GDB, the GNU debugger, and
|
||||||
|
the GNU Binutils.
|
||||||
|
|
||||||
|
GAS/GDB is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GAS/GDB 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 GAS or GDB; see the file COPYING. If not, write to
|
||||||
|
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||||
|
Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
/* The SPARC opcode table (and other related data) is defined in
|
||||||
|
the opcodes library in sparc-opc.c. If you change anything here, make
|
||||||
|
sure you fix up that file, and vice versa. */
|
||||||
|
|
||||||
|
/* FIXME-someday: perhaps the ,a's and such should be embedded in the
|
||||||
|
instruction's name rather than the args. This would make gas faster, pinsn
|
||||||
|
slower, but would mess up some macros a bit. xoxorich. */
|
||||||
|
|
||||||
|
/* List of instruction sets variations.
|
||||||
|
These values are such that each element is either a superset of a
|
||||||
|
preceding each one or they conflict in which case SPARC_OPCODE_CONFLICT_P
|
||||||
|
returns non-zero.
|
||||||
|
The values are indices into `sparc_opcode_archs' defined in sparc-opc.c.
|
||||||
|
Don't change this without updating sparc-opc.c. */
|
||||||
|
|
||||||
|
enum sparc_opcode_arch_val {
|
||||||
|
SPARC_OPCODE_ARCH_V6 = 0,
|
||||||
|
SPARC_OPCODE_ARCH_V7,
|
||||||
|
SPARC_OPCODE_ARCH_V8,
|
||||||
|
SPARC_OPCODE_ARCH_SPARCLET,
|
||||||
|
SPARC_OPCODE_ARCH_SPARCLITE,
|
||||||
|
/* v9 variants must appear last */
|
||||||
|
SPARC_OPCODE_ARCH_V9,
|
||||||
|
SPARC_OPCODE_ARCH_V9A, /* v9 with ultrasparc additions */
|
||||||
|
SPARC_OPCODE_ARCH_BAD /* error return from sparc_opcode_lookup_arch */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The highest architecture in the table. */
|
||||||
|
#define SPARC_OPCODE_ARCH_MAX (SPARC_OPCODE_ARCH_BAD - 1)
|
||||||
|
|
||||||
|
/* Table of cpu variants. */
|
||||||
|
|
||||||
|
struct sparc_opcode_arch {
|
||||||
|
const char *name;
|
||||||
|
/* Mask of sparc_opcode_arch_val's supported.
|
||||||
|
EG: For v7 this would be ((1 << v6) | (1 << v7)). */
|
||||||
|
/* These are short's because sparc_opcode.architecture is. */
|
||||||
|
short supported;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const struct sparc_opcode_arch sparc_opcode_archs[];
|
||||||
|
|
||||||
|
/* Given architecture name, look up it's sparc_opcode_arch_val value. */
|
||||||
|
extern enum sparc_opcode_arch_val sparc_opcode_lookup_arch ();
|
||||||
|
|
||||||
|
/* Return the bitmask of supported architectures for ARCH. */
|
||||||
|
#define SPARC_OPCODE_SUPPORTED(ARCH) (sparc_opcode_archs[ARCH].supported)
|
||||||
|
|
||||||
|
/* Non-zero if ARCH1 conflicts with ARCH2.
|
||||||
|
IE: ARCH1 as a supported bit set that ARCH2 doesn't, and vice versa. */
|
||||||
|
#define SPARC_OPCODE_CONFLICT_P(ARCH1, ARCH2) \
|
||||||
|
(((SPARC_OPCODE_SUPPORTED (ARCH1) & SPARC_OPCODE_SUPPORTED (ARCH2)) \
|
||||||
|
!= SPARC_OPCODE_SUPPORTED (ARCH1)) \
|
||||||
|
&& ((SPARC_OPCODE_SUPPORTED (ARCH1) & SPARC_OPCODE_SUPPORTED (ARCH2)) \
|
||||||
|
!= SPARC_OPCODE_SUPPORTED (ARCH2)))
|
||||||
|
|
||||||
|
/* Structure of an opcode table entry. */
|
||||||
|
|
||||||
|
struct sparc_opcode {
|
||||||
|
const char *name;
|
||||||
|
unsigned long match; /* Bits that must be set. */
|
||||||
|
unsigned long lose; /* Bits that must not be set. */
|
||||||
|
const char *args;
|
||||||
|
/* This was called "delayed" in versions before the flags. */
|
||||||
|
char flags;
|
||||||
|
short architecture; /* Bitmask of sparc_opcode_arch_val's. */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define F_DELAYED 1 /* Delayed branch */
|
||||||
|
#define F_ALIAS 2 /* Alias for a "real" instruction */
|
||||||
|
#define F_UNBR 4 /* Unconditional branch */
|
||||||
|
#define F_CONDBR 8 /* Conditional branch */
|
||||||
|
#define F_JSR 16 /* Subroutine call */
|
||||||
|
/* FIXME: Add F_ANACHRONISTIC flag for v9. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
All sparc opcodes are 32 bits, except for the `set' instruction (really a
|
||||||
|
macro), which is 64 bits. It is handled as a special case.
|
||||||
|
|
||||||
|
The match component is a mask saying which bits must match a particular
|
||||||
|
opcode in order for an instruction to be an instance of that opcode.
|
||||||
|
|
||||||
|
The args component is a string containing one character for each operand of the
|
||||||
|
instruction.
|
||||||
|
|
||||||
|
Kinds of operands:
|
||||||
|
# Number used by optimizer. It is ignored.
|
||||||
|
1 rs1 register.
|
||||||
|
2 rs2 register.
|
||||||
|
d rd register.
|
||||||
|
e frs1 floating point register.
|
||||||
|
v frs1 floating point register (double/even).
|
||||||
|
V frs1 floating point register (quad/multiple of 4).
|
||||||
|
f frs2 floating point register.
|
||||||
|
B frs2 floating point register (double/even).
|
||||||
|
R frs2 floating point register (quad/multiple of 4).
|
||||||
|
g frsd floating point register.
|
||||||
|
H frsd floating point register (double/even).
|
||||||
|
J frsd floating point register (quad/multiple of 4).
|
||||||
|
b crs1 coprocessor register
|
||||||
|
c crs2 coprocessor register
|
||||||
|
D crsd coprocessor register
|
||||||
|
m alternate space register (asr) in rd
|
||||||
|
M alternate space register (asr) in rs1
|
||||||
|
h 22 high bits.
|
||||||
|
K MEMBAR mask (7 bits). (v9)
|
||||||
|
j 10 bit Immediate. (v9)
|
||||||
|
I 11 bit Immediate. (v9)
|
||||||
|
i 13 bit Immediate.
|
||||||
|
n 22 bit immediate.
|
||||||
|
k 2+14 bit PC relative immediate. (v9)
|
||||||
|
G 19 bit PC relative immediate. (v9)
|
||||||
|
l 22 bit PC relative immediate.
|
||||||
|
L 30 bit PC relative immediate.
|
||||||
|
a Annul. The annul bit is set.
|
||||||
|
A Alternate address space. Stored as 8 bits.
|
||||||
|
C Coprocessor state register.
|
||||||
|
F floating point state register.
|
||||||
|
p Processor state register.
|
||||||
|
N Branch predict clear ",pn" (v9)
|
||||||
|
T Branch predict set ",pt" (v9)
|
||||||
|
z %icc. (v9)
|
||||||
|
Z %xcc. (v9)
|
||||||
|
q Floating point queue.
|
||||||
|
r Single register that is both rs1 and rd.
|
||||||
|
O Single register that is both rs2 and rd.
|
||||||
|
Q Coprocessor queue.
|
||||||
|
S Special case.
|
||||||
|
t Trap base register.
|
||||||
|
w Window invalid mask register.
|
||||||
|
y Y register.
|
||||||
|
u sparclet coprocessor registers in rd position
|
||||||
|
U sparclet coprocessor registers in rs1 position
|
||||||
|
E %ccr. (v9)
|
||||||
|
s %fprs. (v9)
|
||||||
|
P %pc. (v9)
|
||||||
|
W %tick. (v9)
|
||||||
|
o %asi. (v9)
|
||||||
|
6 %fcc0. (v9)
|
||||||
|
7 %fcc1. (v9)
|
||||||
|
8 %fcc2. (v9)
|
||||||
|
9 %fcc3. (v9)
|
||||||
|
! Privileged Register in rd (v9)
|
||||||
|
? Privileged Register in rs1 (v9)
|
||||||
|
* Prefetch function constant. (v9)
|
||||||
|
x OPF field (v9 impdep).
|
||||||
|
|
||||||
|
The following chars are unused: (note: ,[] are used as punctuation)
|
||||||
|
[XY3450]
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define OP2(x) (((x)&0x7) << 22) /* op2 field of format2 insns */
|
||||||
|
#define OP3(x) (((x)&0x3f) << 19) /* op3 field of format3 insns */
|
||||||
|
#define OP(x) ((unsigned)((x)&0x3) << 30) /* op field of all insns */
|
||||||
|
#define OPF(x) (((x)&0x1ff) << 5) /* opf field of float insns */
|
||||||
|
#define OPF_LOW5(x) OPF((x)&0x1f) /* v9 */
|
||||||
|
#define F3F(x, y, z) (OP(x) | OP3(y) | OPF(z)) /* format3 float insns */
|
||||||
|
#define F3I(x) (((x)&0x1) << 13) /* immediate field of format 3 insns */
|
||||||
|
#define F2(x, y) (OP(x) | OP2(y)) /* format 2 insns */
|
||||||
|
#define F3(x, y, z) (OP(x) | OP3(y) | F3I(z)) /* format3 insns */
|
||||||
|
#define F1(x) (OP(x))
|
||||||
|
#define DISP30(x) ((x)&0x3fffffff)
|
||||||
|
#define ASI(x) (((x)&0xff) << 5) /* asi field of format3 insns */
|
||||||
|
#define RS2(x) ((x)&0x1f) /* rs2 field */
|
||||||
|
#define SIMM13(x) ((x)&0x1fff) /* simm13 field */
|
||||||
|
#define RD(x) (((x)&0x1f) << 25) /* destination register field */
|
||||||
|
#define RS1(x) (((x)&0x1f) << 14) /* rs1 field */
|
||||||
|
#define ASI_RS2(x) (SIMM13(x))
|
||||||
|
#define MEMBAR(x) ((x)&0x7f)
|
||||||
|
|
||||||
|
#define ANNUL (1<<29)
|
||||||
|
#define BPRED (1<<19) /* v9 */
|
||||||
|
#define IMMED F3I(1)
|
||||||
|
#define RD_G0 RD(~0)
|
||||||
|
#define RS1_G0 RS1(~0)
|
||||||
|
#define RS2_G0 RS2(~0)
|
||||||
|
|
||||||
|
extern struct sparc_opcode sparc_opcodes[];
|
||||||
|
extern const int sparc_num_opcodes;
|
||||||
|
|
||||||
|
int sparc_encode_asi ();
|
||||||
|
char *sparc_decode_asi ();
|
||||||
|
int sparc_encode_membar ();
|
||||||
|
char *sparc_decode_membar ();
|
||||||
|
int sparc_encode_prefetch ();
|
||||||
|
char *sparc_decode_prefetch ();
|
||||||
|
int sparc_encode_sparclet_cpreg ();
|
||||||
|
char *sparc_decode_sparclet_cpreg ();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local Variables:
|
||||||
|
* fill-column: 131
|
||||||
|
* comment-column: 0
|
||||||
|
* End:
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* end of sparc.h */
|
10
opcode/sysdep.h
Normal file
10
opcode/sysdep.h
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#ifndef __SYSDEP_H_SEEN
|
||||||
|
#define __SYSDEP_H_SEEN
|
||||||
|
|
||||||
|
#include "lightning.h"
|
||||||
|
|
||||||
|
#ifndef HAVE_MEMCPY
|
||||||
|
#define memcpy(d, s, n) bcopy((s),(d),(n))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
16
tests/Makefile.am
Normal file
16
tests/Makefile.am
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir)
|
||||||
|
|
||||||
|
EXTRA_PROGRAMS = testfp funcfp rpnfp
|
||||||
|
noinst_PROGRAMS = fibit incr printf printf2 rpn fib fibdelay add
|
||||||
|
noinst_DATA = fibit.ok incr.ok printf.ok printf2.ok rpn.ok fib.ok fibdelay.ok testfp.ok funcfp.ok rpnfp.ok add.ok
|
||||||
|
EXTRA_DIST = $(noinst_DATA) run-test
|
||||||
|
|
||||||
|
if DISASS
|
||||||
|
LDADD = $(top_builddir)/opcode/libdisass.a
|
||||||
|
endif
|
||||||
|
|
||||||
|
if REGRESSION_TESTING
|
||||||
|
TESTS = fib fibit fibdelay incr printf printf2 rpn add \
|
||||||
|
#testfp funcfp rpnfp
|
||||||
|
TESTS_ENVIRONMENT=$(srcdir)/run-test
|
||||||
|
endif
|
61
tests/add.c
Normal file
61
tests/add.c
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Sample call for using arguments in GNU lightning
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "lightning.h"
|
||||||
|
|
||||||
|
static char codeBuffer[1024];
|
||||||
|
|
||||||
|
typedef int (*pifii)(int, int); /* Pointer to Int Function of Int, Int */
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
pifii myFunction= (pifii) (jit_set_ip(codeBuffer).iptr);
|
||||||
|
int ofs; /* offset of the argument */
|
||||||
|
|
||||||
|
jit_leaf(2);
|
||||||
|
ofs = jit_arg_i();
|
||||||
|
jit_getarg_i(JIT_R0, ofs);
|
||||||
|
ofs = jit_arg_i();
|
||||||
|
jit_getarg_i(JIT_R1, ofs);
|
||||||
|
jit_addr_i(JIT_RET, JIT_R0, JIT_R1);
|
||||||
|
jit_ret();
|
||||||
|
jit_flush_code(codeBuffer, jit_get_ip().ptr);
|
||||||
|
|
||||||
|
/* call the generated code, passing its size as argument */
|
||||||
|
#ifdef LIGHTNING_DISASSEMBLE
|
||||||
|
disassemble(stderr, codeBuffer, jit_get_ip().ptr);
|
||||||
|
#endif
|
||||||
|
#ifndef LIGHTNING_CROSS
|
||||||
|
printf("%d + %d = %d\n", 5, 4, myFunction(5, 4));
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
1
tests/add.ok
Normal file
1
tests/add.ok
Normal file
|
@ -0,0 +1 @@
|
||||||
|
5 + 4 = 9
|
77
tests/fib.c
Normal file
77
tests/fib.c
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Sample example of recursion and forward references
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "lightning.h"
|
||||||
|
|
||||||
|
static jit_insn codeBuffer[1024];
|
||||||
|
|
||||||
|
typedef int (*pifi)(int); /* Pointer to Int Function of Int */
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
pifi nfibs = (pifi) (jit_set_ip(codeBuffer).iptr);
|
||||||
|
int in; /* offset of the argument */
|
||||||
|
jit_insn *ref; /* to patch the forward reference */
|
||||||
|
|
||||||
|
jit_prolog (1);
|
||||||
|
in = jit_arg_ui ();
|
||||||
|
jit_getarg_ui(JIT_V0, in); /* V0 = n */
|
||||||
|
ref = jit_blti_ui (jit_forward(), JIT_V0, 2);
|
||||||
|
jit_subi_ui (JIT_V1, JIT_V0, 1); /* V1 = n-1 */
|
||||||
|
jit_subi_ui (JIT_V2, JIT_V0, 2); /* V2 = n-2 */
|
||||||
|
jit_prepare (1);
|
||||||
|
jit_pusharg_ui(JIT_V1);
|
||||||
|
jit_finish(nfibs);
|
||||||
|
jit_retval(JIT_V1); /* V1 = nfibs(n-1) */
|
||||||
|
jit_prepare(1);
|
||||||
|
jit_pusharg_ui(JIT_V2);
|
||||||
|
jit_finish(nfibs);
|
||||||
|
jit_retval(JIT_V2); /* V2 = nfibs(n-2) */
|
||||||
|
jit_addi_ui(JIT_V1, JIT_V1, 1);
|
||||||
|
jit_addr_ui(JIT_RET, JIT_V1, JIT_V2); /* RET = V1 + V2 + 1 */
|
||||||
|
jit_ret();
|
||||||
|
|
||||||
|
jit_patch(ref); /* patch jump */
|
||||||
|
jit_movi_i(JIT_RET, 1); /* RET = 1 */
|
||||||
|
jit_ret();
|
||||||
|
|
||||||
|
/* call the generated code, passing 32 as an argument */
|
||||||
|
jit_flush_code(codeBuffer, jit_get_ip().ptr);
|
||||||
|
|
||||||
|
#ifdef LIGHTNING_DISASSEMBLE
|
||||||
|
disassemble(stderr, codeBuffer, jit_get_ip().ptr);
|
||||||
|
#endif
|
||||||
|
#ifndef LIGHTNING_CROSS
|
||||||
|
printf("nfibs(%d) = %d\n", 32, nfibs(32));
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
1
tests/fib.ok
Normal file
1
tests/fib.ok
Normal file
|
@ -0,0 +1 @@
|
||||||
|
nfibs(32) = 7049155
|
77
tests/fibdelay.c
Normal file
77
tests/fibdelay.c
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Sample example of branches
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "lightning.h"
|
||||||
|
|
||||||
|
static jit_insn codeBuffer[1024];
|
||||||
|
|
||||||
|
typedef int (*pifi)(int); /* Pointer to Int Function of Int */
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
pifi nfibs = (pifi) (jit_set_ip(codeBuffer).iptr);
|
||||||
|
int in; /* offset of the argument */
|
||||||
|
jit_insn *ref; /* to patch the forward reference */
|
||||||
|
jit_insn *loop; /* start of the loop */
|
||||||
|
|
||||||
|
jit_prolog (1);
|
||||||
|
in = jit_arg_ui ();
|
||||||
|
jit_getarg_ui(JIT_R2, in); /* V0 = n */
|
||||||
|
jit_delay(
|
||||||
|
jit_movi_ui (JIT_R1, 1),
|
||||||
|
ref = jit_blti_ui (jit_forward(), JIT_R2, 2));
|
||||||
|
jit_subi_ui (JIT_R2, JIT_R2, 1);
|
||||||
|
jit_movi_ui (JIT_R0, 1);
|
||||||
|
|
||||||
|
loop= jit_get_label();
|
||||||
|
jit_subi_ui (JIT_R2, JIT_R2, 1); /* decr. counter */
|
||||||
|
jit_addr_ui (JIT_V0, JIT_R0, JIT_R1); /* V0 = R0 + R1 */
|
||||||
|
jit_movr_ui (JIT_R0, JIT_R1); /* R0 = R1 */
|
||||||
|
jit_delay(
|
||||||
|
jit_addi_ui (JIT_R1, JIT_V0, 1), /* R1 = V0 + 1 */
|
||||||
|
jit_bnei_ui (loop, JIT_R2, 0)); /* if (R2) goto loop; */
|
||||||
|
|
||||||
|
jit_patch(ref); /* patch forward jump */
|
||||||
|
jit_movr_ui (JIT_RET, JIT_R1); /* RET = R1 */
|
||||||
|
jit_ret();
|
||||||
|
|
||||||
|
jit_flush_code(codeBuffer, jit_get_ip().ptr);
|
||||||
|
|
||||||
|
#ifdef LIGHTNING_DISASSEMBLE
|
||||||
|
disassemble(stderr, codeBuffer, jit_get_ip().ptr);
|
||||||
|
#endif
|
||||||
|
#ifndef LIGHTNING_CROSS
|
||||||
|
/* call the generated code, passing 36 as an argument */
|
||||||
|
printf("nfibs(%d) = %d\n", 36, nfibs(36));
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
1
tests/fibdelay.ok
Normal file
1
tests/fibdelay.ok
Normal file
|
@ -0,0 +1 @@
|
||||||
|
nfibs(36) = 48315633
|
75
tests/fibit.c
Normal file
75
tests/fibit.c
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Sample example of branches
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "lightning.h"
|
||||||
|
|
||||||
|
static jit_insn codeBuffer[1024];
|
||||||
|
|
||||||
|
typedef int (*pifi)(int); /* Pointer to Int Function of Int */
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
pifi nfibs = (pifi) (jit_set_ip(codeBuffer).iptr);
|
||||||
|
int in; /* offset of the argument */
|
||||||
|
jit_insn *ref; /* to patch the forward reference */
|
||||||
|
jit_insn *loop; /* start of the loop */
|
||||||
|
|
||||||
|
jit_prolog (1);
|
||||||
|
in = jit_arg_ui ();
|
||||||
|
jit_getarg_ui(JIT_R2, in); /* V0 = n */
|
||||||
|
jit_movi_ui (JIT_R1, 1);
|
||||||
|
ref = jit_blti_ui (jit_forward(), JIT_R2, 2);
|
||||||
|
jit_subi_ui (JIT_R2, JIT_R2, 1);
|
||||||
|
jit_movi_ui (JIT_R0, 1);
|
||||||
|
|
||||||
|
loop= jit_get_label();
|
||||||
|
jit_subi_ui (JIT_R2, JIT_R2, 1); /* we'll calculate one more */
|
||||||
|
jit_addr_ui (JIT_V0, JIT_R0, JIT_R1); /* V0 = R0 + R1 */
|
||||||
|
jit_movr_ui (JIT_R0, JIT_R1); /* R0 = R1 */
|
||||||
|
jit_addi_ui (JIT_R1, JIT_V0, 1); /* R1 = V0 + 1 */
|
||||||
|
jit_bnei_ui (loop, JIT_R2, 0); /* if (R2) goto loop; */
|
||||||
|
|
||||||
|
jit_patch(ref); /* patch forward jump */
|
||||||
|
jit_movr_ui (JIT_RET, JIT_R1); /* RET = R1 */
|
||||||
|
jit_ret();
|
||||||
|
|
||||||
|
jit_flush_code(codeBuffer, jit_get_ip().ptr);
|
||||||
|
|
||||||
|
#ifdef LIGHTNING_DISASSEMBLE
|
||||||
|
disassemble(stderr, codeBuffer, jit_get_ip().ptr);
|
||||||
|
#endif
|
||||||
|
#ifndef LIGHTNING_CROSS
|
||||||
|
/* call the generated code, passing 36 as an argument */
|
||||||
|
printf("nfibs(%d) = %d\n", 36, nfibs(36));
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
1
tests/fibit.ok
Normal file
1
tests/fibit.ok
Normal file
|
@ -0,0 +1 @@
|
||||||
|
nfibs(36) = 48315633
|
173
tests/funcfp.c
Normal file
173
tests/funcfp.c
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Floating-point function invocation using GNU lightning
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "lightning.h"
|
||||||
|
|
||||||
|
static jit_insn codeBuffer[300];
|
||||||
|
static struct jit_fp buffer[300];
|
||||||
|
|
||||||
|
|
||||||
|
typedef int (*intFunc)(int,int);
|
||||||
|
typedef double (*dblFunc)(double,double);
|
||||||
|
typedef float (*floatFunc)(float,float);
|
||||||
|
|
||||||
|
|
||||||
|
dblFunc makeDblFunc()
|
||||||
|
/* Generate a function that computes and returns the sum of
|
||||||
|
its two double arguments (return an int)
|
||||||
|
i.e., double foo(double x,double y) { return x + y;}
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
dblFunc retVal;
|
||||||
|
int dbl1,dbl2;
|
||||||
|
jit_set_ip(codeBuffer);
|
||||||
|
retVal = (dblFunc)jit_get_ip().iptr;
|
||||||
|
jit_prolog(2);
|
||||||
|
jitfp_begin(buffer);
|
||||||
|
dbl1 = jit_arg_d();
|
||||||
|
dbl2 = jit_arg_d();
|
||||||
|
|
||||||
|
|
||||||
|
jitfp_retval(jitfp_add(jitfp_getarg_d(dbl1),
|
||||||
|
jitfp_getarg_d(dbl2)));
|
||||||
|
|
||||||
|
jit_ret();
|
||||||
|
jit_flush_code((char*)retVal,jit_get_ip().ptr);
|
||||||
|
|
||||||
|
#ifdef LIGHTNING_DISASSEMBLE
|
||||||
|
disassemble(stderr, retVal, jit_get_ip().ptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
floatFunc makeFloatFunc()
|
||||||
|
/* Generate a function that computes and returns the sum of
|
||||||
|
its two double arguments (return an int)
|
||||||
|
i.e., double foo(double x,double y) { return x + y;}
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
floatFunc retVal;
|
||||||
|
int dbl1,dbl2;
|
||||||
|
//jit_set_ip(codeBuffer);
|
||||||
|
retVal = (floatFunc)jit_get_ip().iptr;
|
||||||
|
jit_prolog(2);
|
||||||
|
jitfp_begin(buffer);
|
||||||
|
dbl1 = jit_arg_f();
|
||||||
|
dbl2 = jit_arg_f();
|
||||||
|
|
||||||
|
|
||||||
|
jitfp_retval(jitfp_add(jitfp_getarg_f(dbl1),
|
||||||
|
jitfp_getarg_f(dbl2)));
|
||||||
|
|
||||||
|
jit_ret();
|
||||||
|
jit_flush_code((char*)retVal,jit_get_ip().ptr);
|
||||||
|
|
||||||
|
#ifdef LIGHTNING_DISASSEMBLE
|
||||||
|
disassemble(stderr, retVal, jit_get_ip().ptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
dblFunc makeCallFunc(dblFunc theFunc)
|
||||||
|
{
|
||||||
|
dblFunc retVal;
|
||||||
|
int dbl1,dbl2;
|
||||||
|
//jit_set_ip(codeBuffer);
|
||||||
|
retVal = (dblFunc)jit_get_ip().iptr;
|
||||||
|
jit_prolog(2);
|
||||||
|
jitfp_begin(buffer);
|
||||||
|
dbl1 = jit_arg_d();
|
||||||
|
dbl2 = jit_arg_d();
|
||||||
|
|
||||||
|
jitfp_prepare(0,0,2);
|
||||||
|
jitfp_pusharg_d(jitfp_mul(jitfp_getarg_d(dbl1),
|
||||||
|
jitfp_getarg_d(dbl2)));
|
||||||
|
jitfp_pusharg_d(jitfp_getarg_d(dbl1));
|
||||||
|
jit_finish((void*)theFunc);
|
||||||
|
jit_ret();
|
||||||
|
jit_flush_code((char*)retVal,jit_get_ip().ptr);
|
||||||
|
|
||||||
|
#ifdef LIGHTNING_DISASSEMBLE
|
||||||
|
disassemble(stderr, retVal, jit_get_ip().ptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
floatFunc makeCallFloatFunc(floatFunc theFunc)
|
||||||
|
{
|
||||||
|
floatFunc retVal;
|
||||||
|
int dbl1,dbl2;
|
||||||
|
//jit_set_ip(codeBuffer);
|
||||||
|
retVal = (floatFunc)jit_get_ip().iptr;
|
||||||
|
jit_prolog(2);
|
||||||
|
jitfp_begin(buffer);
|
||||||
|
dbl1 = jit_arg_f();
|
||||||
|
dbl2 = jit_arg_f();
|
||||||
|
|
||||||
|
jitfp_prepare(0,2,0);
|
||||||
|
jitfp_pusharg_f(jitfp_mul(jitfp_getarg_f(dbl1),
|
||||||
|
jitfp_getarg_f(dbl2)));
|
||||||
|
jitfp_pusharg_f(jitfp_getarg_f(dbl1));
|
||||||
|
jit_finish((void*)theFunc);
|
||||||
|
jit_ret();
|
||||||
|
jit_flush_code((char*)retVal,jit_get_ip().ptr);
|
||||||
|
|
||||||
|
#ifdef LIGHTNING_DISASSEMBLE
|
||||||
|
disassemble(stderr, retVal, jit_get_ip().ptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc,char* argv[])
|
||||||
|
{
|
||||||
|
dblFunc myFunc2 = makeDblFunc();
|
||||||
|
floatFunc myFunc3 = makeFloatFunc();
|
||||||
|
dblFunc callIt1 = makeCallFunc(myFunc2);
|
||||||
|
floatFunc callIt2 = makeCallFloatFunc(myFunc3);
|
||||||
|
|
||||||
|
#ifndef LIGHTNING_CROSS
|
||||||
|
double y = callIt1(10.5,15.3);
|
||||||
|
float a = 1.5;
|
||||||
|
float b = 10.5;
|
||||||
|
float z = callIt2(a,b);
|
||||||
|
printf("result is %f\t %f\n",y,z);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
1
tests/funcfp.ok
Normal file
1
tests/funcfp.ok
Normal file
|
@ -0,0 +1 @@
|
||||||
|
result is 171.150000 17.250000
|
59
tests/incr.c
Normal file
59
tests/incr.c
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Sample call for using arguments in GNU lightning
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "lightning.h"
|
||||||
|
|
||||||
|
static char codeBuffer[1024];
|
||||||
|
|
||||||
|
typedef int (*pifi)(int); /* Pointer to Int Function of Int */
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
pifi myFunction= (pifi) (jit_set_ip(codeBuffer).iptr);
|
||||||
|
int ofs; /* offset of the argument */
|
||||||
|
|
||||||
|
jit_leaf(1);
|
||||||
|
ofs = jit_arg_i();
|
||||||
|
jit_getarg_i(JIT_R0, ofs);
|
||||||
|
jit_addi_i(JIT_RET, JIT_R0, 1);
|
||||||
|
jit_ret();
|
||||||
|
jit_flush_code(codeBuffer, jit_get_ip().ptr);
|
||||||
|
|
||||||
|
/* call the generated code, passing its size as argument */
|
||||||
|
#ifdef LIGHTNING_DISASSEMBLE
|
||||||
|
disassemble(stderr, codeBuffer, jit_get_ip().ptr);
|
||||||
|
#endif
|
||||||
|
#ifndef LIGHTNING_CROSS
|
||||||
|
printf("%d + 1 = %d\n", 5, myFunction(5));
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
1
tests/incr.ok
Normal file
1
tests/incr.ok
Normal file
|
@ -0,0 +1 @@
|
||||||
|
5 + 1 = 6
|
68
tests/printf.c
Normal file
68
tests/printf.c
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Sample call to printf using GNU lightning
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "lightning.h"
|
||||||
|
|
||||||
|
static char codeBuffer[1024];
|
||||||
|
|
||||||
|
typedef void (*pvfi)(int); /* Pointer to Void Function of Int */
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
pvfi myFunction; /* ptr to generated code */
|
||||||
|
char *start, *end; /* a couple of labels */
|
||||||
|
int ofs; /* to get the argument */
|
||||||
|
|
||||||
|
myFunction = (pvfi) (jit_set_ip(codeBuffer).vptr);
|
||||||
|
start = jit_get_ip().ptr;
|
||||||
|
jit_prolog(1);
|
||||||
|
ofs = jit_arg_i();
|
||||||
|
jit_movi_p(JIT_R0, "looks like %d bytes sufficed\n");
|
||||||
|
jit_getarg_i(JIT_R1, ofs);
|
||||||
|
jit_prepare(2);
|
||||||
|
jit_pusharg_i(JIT_R1); /* push in reverse order */
|
||||||
|
jit_pusharg_p(JIT_R0);
|
||||||
|
jit_finish(printf);
|
||||||
|
jit_ret();
|
||||||
|
end = jit_get_ip().ptr;
|
||||||
|
|
||||||
|
jit_flush_code(codeBuffer, end);
|
||||||
|
|
||||||
|
#ifdef LIGHTNING_DISASSEMBLE
|
||||||
|
disassemble(stderr, codeBuffer, end);
|
||||||
|
#endif
|
||||||
|
#ifndef LIGHTNING_CROSS
|
||||||
|
/* call the generated code, passing its size as argument */
|
||||||
|
myFunction(sizeof(codeBuffer));
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
1
tests/printf.ok
Normal file
1
tests/printf.ok
Normal file
|
@ -0,0 +1 @@
|
||||||
|
looks like 1024 bytes sufficed
|
2409
tests/printf2.c
Normal file
2409
tests/printf2.c
Normal file
File diff suppressed because it is too large
Load diff
2376
tests/printf2.ok
Normal file
2376
tests/printf2.ok
Normal file
File diff suppressed because it is too large
Load diff
445
tests/rpn.c
Normal file
445
tests/rpn.c
Normal file
|
@ -0,0 +1,445 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Sample RPN calculator using GNU lightning
|
||||||
|
* Binary operators: + - * / % & | ^ < <= > >= = != << >> >>>
|
||||||
|
* Unary operators: _ (unary minus) and ~ (unary NOT)
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000, 2004 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "lightning.h"
|
||||||
|
|
||||||
|
static jit_insn codeBuffer[1024];
|
||||||
|
|
||||||
|
typedef int (*pifi) (int); /* Pointer to Int Function of Int */
|
||||||
|
|
||||||
|
|
||||||
|
enum stack_kind { IMM, EXPR, ARG };
|
||||||
|
enum operator { LE, GE, NE, LSH, RSHU, RSH };
|
||||||
|
|
||||||
|
struct stack_element
|
||||||
|
{
|
||||||
|
enum stack_kind kind;
|
||||||
|
int imm;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Return a new operator TOK2 such that A TOK B = B TOK2 A,
|
||||||
|
or 0 if there is none. */
|
||||||
|
int
|
||||||
|
swap_op (int tok)
|
||||||
|
{
|
||||||
|
switch (tok)
|
||||||
|
{
|
||||||
|
case '<':
|
||||||
|
case '>':
|
||||||
|
/* Swap < and >. */
|
||||||
|
return '<' ^ '>' ^ tok;
|
||||||
|
|
||||||
|
case LE:
|
||||||
|
case GE:
|
||||||
|
/* Swap <= and >=. */
|
||||||
|
return LE ^ GE ^ tok;
|
||||||
|
|
||||||
|
case '+':
|
||||||
|
case '*':
|
||||||
|
case '&':
|
||||||
|
case '|':
|
||||||
|
case '^':
|
||||||
|
case '=':
|
||||||
|
case NE:
|
||||||
|
/* These are commutative. */
|
||||||
|
return tok;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Perform constant folding on the two operands X and Y,
|
||||||
|
passing them through the operator TOK. */
|
||||||
|
int
|
||||||
|
fold (int x, int y, int tok)
|
||||||
|
{
|
||||||
|
switch (tok)
|
||||||
|
{
|
||||||
|
case '+': return x + y;
|
||||||
|
case '-': return x - y;
|
||||||
|
case '*': return x * y;
|
||||||
|
case '/': return x / y;
|
||||||
|
case '%': return x % y;
|
||||||
|
case '=': return x == y;
|
||||||
|
case '<': return x < y;
|
||||||
|
case '>': return x > y;
|
||||||
|
case '&': return x & y;
|
||||||
|
case '|': return x | y;
|
||||||
|
case '^': return x ^ y;
|
||||||
|
case LE: return x <= y;
|
||||||
|
case GE: return x >= y;
|
||||||
|
case NE: return x != y;
|
||||||
|
case LSH: return x << y;
|
||||||
|
case RSH: return x >> y;
|
||||||
|
case RSHU: return ((unsigned) x) >> y;
|
||||||
|
default: abort ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store in R0 the result of evaluating the operator TOK with
|
||||||
|
a register operand SRC and an immediate operand IMM. */
|
||||||
|
void
|
||||||
|
gen_reg_imm (int src, int imm, int tok)
|
||||||
|
{
|
||||||
|
switch (tok)
|
||||||
|
{
|
||||||
|
case '+': jit_addi_i (JIT_R0, src, imm); break;
|
||||||
|
case '-': jit_subi_i (JIT_R0, src, imm); break;
|
||||||
|
case '*': jit_muli_i (JIT_R0, src, imm); break;
|
||||||
|
case '/': jit_divi_i (JIT_R0, src, imm); break;
|
||||||
|
case '%': jit_modi_i (JIT_R0, src, imm); break;
|
||||||
|
case '&': jit_andi_i (JIT_R0, src, imm); break;
|
||||||
|
case '|': jit_ori_i (JIT_R0, src, imm); break;
|
||||||
|
case '^': jit_xori_i (JIT_R0, src, imm); break;
|
||||||
|
case '=': jit_eqi_i (JIT_R0, src, imm); break;
|
||||||
|
case '<': jit_lti_i (JIT_R0, src, imm); break;
|
||||||
|
case '>': jit_gti_i (JIT_R0, src, imm); break;
|
||||||
|
case LE: jit_lei_i (JIT_R0, src, imm); break;
|
||||||
|
case GE: jit_gei_i (JIT_R0, src, imm); break;
|
||||||
|
case NE: jit_nei_i (JIT_R0, src, imm); break;
|
||||||
|
case LSH: jit_lshi_i (JIT_R0, src, imm); break;
|
||||||
|
case RSH: jit_rshi_i (JIT_R0, src, imm); break;
|
||||||
|
case RSHU: jit_rshi_ui (JIT_R0, src, imm); break;
|
||||||
|
default: abort ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store in R0 the result of evaluating the operator TOK with
|
||||||
|
two register operands SRC1 and SRC2. */
|
||||||
|
void
|
||||||
|
gen_reg_reg (int src1, int src2, int tok)
|
||||||
|
{
|
||||||
|
switch (tok)
|
||||||
|
{
|
||||||
|
case '+': jit_addr_i (JIT_R0, src1, src2); break;
|
||||||
|
case '-': jit_subr_i (JIT_R0, src1, src2); break;
|
||||||
|
case '*': jit_mulr_i (JIT_R0, src1, src2); break;
|
||||||
|
case '/': jit_divr_i (JIT_R0, src1, src2); break;
|
||||||
|
case '%': jit_modr_i (JIT_R0, src1, src2); break;
|
||||||
|
case '&': jit_andr_i (JIT_R0, src1, src2); break;
|
||||||
|
case '|': jit_orr_i (JIT_R0, src1, src2); break;
|
||||||
|
case '^': jit_xorr_i (JIT_R0, src1, src2); break;
|
||||||
|
case '=': jit_eqr_i (JIT_R0, src1, src2); break;
|
||||||
|
case '<': jit_ltr_i (JIT_R0, src1, src2); break;
|
||||||
|
case '>': jit_gtr_i (JIT_R0, src1, src2); break;
|
||||||
|
case LE: jit_ler_i (JIT_R0, src1, src2); break;
|
||||||
|
case GE: jit_ger_i (JIT_R0, src1, src2); break;
|
||||||
|
case NE: jit_ner_i (JIT_R0, src1, src2); break;
|
||||||
|
case LSH: jit_lshr_i (JIT_R0, src1, src2); break;
|
||||||
|
case RSH: jit_rshr_i (JIT_R0, src1, src2); break;
|
||||||
|
case RSHU: jit_rshr_ui (JIT_R0, src1, src2); break;
|
||||||
|
default: abort ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function does all of lexing, parsing, and picking a good
|
||||||
|
order of evaluation... Needless to say, this is not the best
|
||||||
|
possible design, but it avoids cluttering everything with globals. */
|
||||||
|
pifi
|
||||||
|
compile_rpn (char *expr)
|
||||||
|
{
|
||||||
|
struct stack_element stack[32];
|
||||||
|
int sp = 0;
|
||||||
|
int curr_tos = -1; /* stack element currently in R0 */
|
||||||
|
|
||||||
|
pifi fn;
|
||||||
|
int ofs;
|
||||||
|
fn = (pifi) (jit_get_ip ().iptr);
|
||||||
|
jit_leaf (1);
|
||||||
|
ofs = jit_arg_i ();
|
||||||
|
|
||||||
|
while (*expr)
|
||||||
|
{
|
||||||
|
int with_imm;
|
||||||
|
int imm;
|
||||||
|
int tok;
|
||||||
|
int src1, src2;
|
||||||
|
|
||||||
|
/* This is the lexer. */
|
||||||
|
switch (*expr)
|
||||||
|
{
|
||||||
|
case ' ': case '\t':
|
||||||
|
expr++;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
|
stack[sp].kind = IMM;
|
||||||
|
stack[sp++].imm = strtol (expr, &expr, 0);
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 'x':
|
||||||
|
expr++;
|
||||||
|
stack[sp++].kind = ARG;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case '~':
|
||||||
|
/* NOT. Implemented as a XOR with -1. */
|
||||||
|
stack[sp].kind = IMM;
|
||||||
|
stack[sp++].imm = ~0;
|
||||||
|
tok = '^';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '_':
|
||||||
|
/* Unary minus. Transform to 0 - X and go on.
|
||||||
|
Also used to enter negative constants (32_ = -32). */
|
||||||
|
expr++;
|
||||||
|
stack[sp] = stack[sp - 1];
|
||||||
|
|
||||||
|
/* Ensure CURR_TOS is correct. */
|
||||||
|
if (curr_tos == sp - 1)
|
||||||
|
curr_tos = sp;
|
||||||
|
|
||||||
|
stack[sp - 1].kind = IMM;
|
||||||
|
stack[sp - 1].imm = 0;
|
||||||
|
sp++;
|
||||||
|
tok = '-';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '+':
|
||||||
|
case '-':
|
||||||
|
case '*':
|
||||||
|
case '/':
|
||||||
|
case '%':
|
||||||
|
case '&':
|
||||||
|
case '|':
|
||||||
|
case '^':
|
||||||
|
case '=':
|
||||||
|
tok = *expr++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '!':
|
||||||
|
/* Get != */
|
||||||
|
expr++;
|
||||||
|
assert (*expr == '=');
|
||||||
|
tok = NE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '<':
|
||||||
|
/* Get <, <<, <= */
|
||||||
|
if (expr[1] == '=')
|
||||||
|
expr += 2, tok = LE;
|
||||||
|
else if (expr[1] == '<')
|
||||||
|
expr += 2, tok = LSH;
|
||||||
|
else
|
||||||
|
expr++, tok = '<';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '>':
|
||||||
|
/* Get >, >>, >>>, >= */
|
||||||
|
if (expr[1] == '=')
|
||||||
|
expr += 2, tok = GE;
|
||||||
|
else if (expr[1] == '>' && expr[2] == '>')
|
||||||
|
expr += 3, tok = RSHU;
|
||||||
|
else if (expr[1] == '>')
|
||||||
|
expr += 2, tok = RSH;
|
||||||
|
else
|
||||||
|
expr++, tok = '>';
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
assert (sp >= 2);
|
||||||
|
|
||||||
|
/* Constant folding. */
|
||||||
|
if (stack[sp - 1].kind == IMM && stack[sp - 2].kind == IMM)
|
||||||
|
{
|
||||||
|
stack[sp - 2].imm =
|
||||||
|
fold (stack[sp - 2].imm, stack[sp - 1].imm, tok);
|
||||||
|
sp--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If possible, ensure that the constant is the RHS, possibly
|
||||||
|
by changing TOK (if it is a comparison). */
|
||||||
|
if (stack[sp - 2].kind == IMM)
|
||||||
|
{
|
||||||
|
int swapped_operation = swap_op (tok);
|
||||||
|
if (swapped_operation)
|
||||||
|
{
|
||||||
|
tok = swapped_operation;
|
||||||
|
stack[sp - 2].kind = stack[sp - 1].kind;
|
||||||
|
stack[sp - 1].kind = IMM;
|
||||||
|
stack[sp - 1].imm = stack[sp - 2].imm;
|
||||||
|
|
||||||
|
/* Ensure CURR_TOS is correct. */
|
||||||
|
if (curr_tos == sp - 1)
|
||||||
|
curr_tos = sp - 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the second argument into a register, if not an immediate.
|
||||||
|
Also decide which argument will be prepared into JIT_R0 and
|
||||||
|
which will be prepared into JIT_V0. */
|
||||||
|
with_imm = 0;
|
||||||
|
src1 = JIT_R0;
|
||||||
|
src2 = JIT_V0;
|
||||||
|
switch (stack[sp - 1].kind)
|
||||||
|
{
|
||||||
|
case IMM:
|
||||||
|
/* RHS is an immediate, use an immediate instruction. */
|
||||||
|
with_imm = 1;
|
||||||
|
imm = stack[sp - 1].imm;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EXPR:
|
||||||
|
/* RHS is an expression, check if it is already in JIT_R0. */
|
||||||
|
if (curr_tos == sp - 1)
|
||||||
|
{
|
||||||
|
/* Invert the two sources. */
|
||||||
|
src1 = JIT_V0;
|
||||||
|
src2 = JIT_R0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
jit_popr_i (JIT_V0);
|
||||||
|
|
||||||
|
curr_tos = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ARG:
|
||||||
|
jit_getarg_i (JIT_V0, ofs);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the first argument into a register indicated by SRC1. */
|
||||||
|
switch (stack[sp - 2].kind)
|
||||||
|
{
|
||||||
|
case IMM:
|
||||||
|
/* LHS is an immediate, check if we must spill the top of stack. */
|
||||||
|
if (curr_tos != -1)
|
||||||
|
{
|
||||||
|
jit_pushr_i (JIT_R0);
|
||||||
|
curr_tos = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
jit_movi_i (src1, stack[sp - 2].imm);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EXPR:
|
||||||
|
/* LHS is an expression, check if it is already in JIT_R0. */
|
||||||
|
if (curr_tos != sp - 2)
|
||||||
|
{
|
||||||
|
jit_popr_i (src1);
|
||||||
|
curr_tos = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
assert (src1 == JIT_R0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ARG:
|
||||||
|
if (curr_tos != -1)
|
||||||
|
{
|
||||||
|
jit_pushr_i (JIT_R0);
|
||||||
|
curr_tos = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
jit_getarg_i (src1, ofs);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set up the new stack entry, which is cached in R0. */
|
||||||
|
sp -= 2;
|
||||||
|
curr_tos = sp;
|
||||||
|
stack[sp++].kind = EXPR;
|
||||||
|
|
||||||
|
/* Perform the computation. */
|
||||||
|
if (with_imm)
|
||||||
|
gen_reg_imm (src1, imm, tok);
|
||||||
|
else
|
||||||
|
gen_reg_reg (src1, src2, tok);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert (sp == 1);
|
||||||
|
switch (stack[0].kind)
|
||||||
|
{
|
||||||
|
case IMM:
|
||||||
|
jit_movi_i (JIT_RET, stack[0].imm);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EXPR:
|
||||||
|
assert (curr_tos == 0);
|
||||||
|
jit_movr_i (JIT_RET, JIT_R0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ARG:
|
||||||
|
jit_getarg_i (JIT_V0, ofs);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
jit_ret ();
|
||||||
|
jit_flush_code ((char *) fn, jit_get_ip ().ptr);
|
||||||
|
|
||||||
|
#ifdef LIGHTNING_DISASSEMBLE
|
||||||
|
disassemble (stderr, (char *) fn, jit_get_ip ().ptr);
|
||||||
|
#endif
|
||||||
|
return fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
pifi c2f, f2c;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
jit_set_ip (codeBuffer);
|
||||||
|
c2f = compile_rpn ("32 x 9 * 5 / +");
|
||||||
|
f2c = compile_rpn ("5 x 32_ + * 9 /");
|
||||||
|
|
||||||
|
#ifndef LIGHTNING_CROSS
|
||||||
|
printf ("\nC:");
|
||||||
|
for (i = 0; i <= 100; i += 10)
|
||||||
|
printf ("%3d ", i);
|
||||||
|
printf ("\nF:");
|
||||||
|
for (i = 0; i <= 100; i += 10)
|
||||||
|
printf ("%3d ", c2f (i));
|
||||||
|
printf ("\n");
|
||||||
|
|
||||||
|
printf ("\nF:");
|
||||||
|
for (i = 32; i <= 212; i += 10)
|
||||||
|
printf ("%3d ", i);
|
||||||
|
printf ("\nC:");
|
||||||
|
for (i = 32; i <= 212; i += 10)
|
||||||
|
printf ("%3d ", f2c (i));
|
||||||
|
printf ("\n");
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
6
tests/rpn.ok
Normal file
6
tests/rpn.ok
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
C: 0 10 20 30 40 50 60 70 80 90 100
|
||||||
|
F: 32 50 68 86 104 122 140 158 176 194 212
|
||||||
|
|
||||||
|
F: 32 42 52 62 72 82 92 102 112 122 132 142 152 162 172 182 192 202 212
|
||||||
|
C: 0 5 11 16 22 27 33 38 44 50 55 61 66 72 77 83 88 94 100
|
134
tests/rpnfp.c
Normal file
134
tests/rpnfp.c
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Sample RPN calculator using GNU lightning and floating-point
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000, 2004 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "lightning.h"
|
||||||
|
|
||||||
|
static jit_insn codeBuffer[1024];
|
||||||
|
|
||||||
|
typedef double (*pdfd) (double); /* Pointer to Double Function of Double */
|
||||||
|
|
||||||
|
|
||||||
|
pdfd
|
||||||
|
compile_rpn (char *expr)
|
||||||
|
{
|
||||||
|
pdfd fn;
|
||||||
|
int ofs, sp = 1;
|
||||||
|
struct jit_fp buffer[300], *stack[10];
|
||||||
|
|
||||||
|
jitfp_begin (buffer);
|
||||||
|
fn = (pdfd) (jit_get_ip ().dptr);
|
||||||
|
jit_leaf (1);
|
||||||
|
ofs = jit_arg_d ();
|
||||||
|
stack[0] = jitfp_getarg_d (ofs);
|
||||||
|
|
||||||
|
while (*expr)
|
||||||
|
{
|
||||||
|
char buf[32];
|
||||||
|
int n;
|
||||||
|
|
||||||
|
/* This scanner is much less advanced than the one in rpn.c. */
|
||||||
|
if (sscanf (expr, "%[0-9]%n", buf, &n))
|
||||||
|
{
|
||||||
|
double d = strtod (buf, NULL);
|
||||||
|
expr += n - 1;
|
||||||
|
stack[sp++] = jitfp_imm (d);
|
||||||
|
}
|
||||||
|
else if (*expr == '+')
|
||||||
|
{
|
||||||
|
stack[sp - 2] = jitfp_add (stack[sp - 2], stack[sp - 1]);
|
||||||
|
sp--;
|
||||||
|
}
|
||||||
|
else if (*expr == '-')
|
||||||
|
{
|
||||||
|
stack[sp - 2] = jitfp_sub (stack[sp - 2], stack[sp - 1]);
|
||||||
|
sp--;
|
||||||
|
}
|
||||||
|
else if (*expr == '*')
|
||||||
|
{
|
||||||
|
stack[sp - 2] = jitfp_mul (stack[sp - 2], stack[sp - 1]);
|
||||||
|
sp--;
|
||||||
|
}
|
||||||
|
else if (*expr == '/')
|
||||||
|
{
|
||||||
|
stack[sp - 2] = jitfp_div (stack[sp - 2], stack[sp - 1]);
|
||||||
|
sp--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf (stderr, "cannot compile: %s\n", expr);
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
++expr;
|
||||||
|
}
|
||||||
|
jitfp_retval (stack[0]);
|
||||||
|
jit_ret ();
|
||||||
|
|
||||||
|
jit_flush_code ((char *) fn, jit_get_ip ().ptr);
|
||||||
|
|
||||||
|
#ifdef LIGHTNING_DISASSEMBLE
|
||||||
|
disassemble (stderr, (char *) fn, jit_get_ip ().ptr);
|
||||||
|
#endif
|
||||||
|
return fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
pdfd c2f, f2c;
|
||||||
|
double i;
|
||||||
|
|
||||||
|
jit_set_ip (codeBuffer);
|
||||||
|
c2f = compile_rpn ("9*5/32+");
|
||||||
|
f2c = compile_rpn ("32-5*9/");
|
||||||
|
|
||||||
|
#ifndef LIGHTNING_CROSS
|
||||||
|
printf ("\nC:");
|
||||||
|
for (i = 0; i <= 100; i += 10)
|
||||||
|
printf ("%6.1f", i);
|
||||||
|
printf ("\nF:");
|
||||||
|
for (i = 0; i <= 100; i += 10)
|
||||||
|
printf ("%6.1f", c2f (i));
|
||||||
|
printf ("\n");
|
||||||
|
|
||||||
|
printf ("\nF:");
|
||||||
|
for (i = 32; i <= 212; i += 10)
|
||||||
|
printf ("%6.1f", i);
|
||||||
|
printf ("\nC:");
|
||||||
|
for (i = 32; i <= 212; i += 10)
|
||||||
|
printf ("%6.1f", f2c (i));
|
||||||
|
printf ("\n");
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
6
tests/rpnfp.ok
Normal file
6
tests/rpnfp.ok
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
C: 0.0 10.0 20.0 30.0 40.0 50.0 60.0 70.0 80.0 90.0 100.0
|
||||||
|
F: 32.0 50.0 68.0 86.0 104.0 122.0 140.0 158.0 176.0 194.0 212.0
|
||||||
|
|
||||||
|
F: 32.0 42.0 52.0 62.0 72.0 82.0 92.0 102.0 112.0 122.0 132.0 142.0 152.0 162.0 172.0 182.0 192.0 202.0 212.0
|
||||||
|
C: 0.0 5.6 11.1 16.7 22.2 27.8 33.3 38.9 44.4 50.0 55.6 61.1 66.7 72.2 77.8 83.3 88.9 94.4 100.0
|
9
tests/run-test
Executable file
9
tests/run-test
Executable file
|
@ -0,0 +1,9 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
./$1 > $1.log
|
||||||
|
if cmp -s $srcdir/$1.ok $1.log; then
|
||||||
|
rm $1.log
|
||||||
|
else
|
||||||
|
diff $srcdir/$1.ok $1.log
|
||||||
|
exit 1
|
||||||
|
fi
|
186
tests/testfp.c
Normal file
186
tests/testfp.c
Normal file
|
@ -0,0 +1,186 @@
|
||||||
|
/******************************** -*- C -*- ****************************
|
||||||
|
*
|
||||||
|
* Floating-point miscellanea using GNU lightning
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2000, 2002 Free Software Foundation, Inc.
|
||||||
|
* Written by Paolo Bonzini.
|
||||||
|
*
|
||||||
|
* This file is part of GNU lightning.
|
||||||
|
*
|
||||||
|
* GNU lightning is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2.1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* GNU lightning 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 Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
|
||||||
|
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "lightning.h"
|
||||||
|
|
||||||
|
static jit_insn codeBuffer[300];
|
||||||
|
static struct jit_fp buffer[300];
|
||||||
|
static double a;
|
||||||
|
|
||||||
|
void
|
||||||
|
int_test(what, code)
|
||||||
|
char *what;
|
||||||
|
jit_code code;
|
||||||
|
{
|
||||||
|
a = -2.6; printf("%s\t\t%d ", what, code.iptr());
|
||||||
|
a = -2.4; printf("%d ", code.iptr());
|
||||||
|
a = 0.0; printf("%d ", code.iptr());
|
||||||
|
a = 2.4; printf("%d ", code.iptr());
|
||||||
|
a = 2.6; printf("%d\n", code.iptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
jit_code code;
|
||||||
|
code.ptr = (char *) codeBuffer;
|
||||||
|
|
||||||
|
jit_set_ip(codeBuffer);
|
||||||
|
jit_leaf(0);
|
||||||
|
jitfp_begin(buffer);
|
||||||
|
jitfp_cmp(JIT_R1, JIT_R0,
|
||||||
|
jitfp_ldi_d(&a)
|
||||||
|
);
|
||||||
|
jit_subr_i(JIT_RET, JIT_R0, JIT_R1); /* [greater] - [less] = -1/0/1 */
|
||||||
|
jit_ret();
|
||||||
|
|
||||||
|
jit_flush_code(codeBuffer, jit_get_ip().ptr);
|
||||||
|
#ifdef LIGHTNING_DISASSEMBLE
|
||||||
|
disassemble(stderr, codeBuffer, jit_get_ip().ptr);
|
||||||
|
#endif
|
||||||
|
#ifndef LIGHTNING_CROSS
|
||||||
|
int_test("compare", code);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
jit_set_ip(codeBuffer);
|
||||||
|
jit_leaf(0);
|
||||||
|
jitfp_begin(buffer);
|
||||||
|
jitfp_trunc(JIT_RET,
|
||||||
|
jitfp_ldi_d(&a)
|
||||||
|
);
|
||||||
|
jit_ret();
|
||||||
|
#ifdef LIGHTNING_DISASSEMBLE
|
||||||
|
disassemble(stderr, codeBuffer, jit_get_ip().ptr);
|
||||||
|
#endif
|
||||||
|
#ifndef LIGHTNING_CROSS
|
||||||
|
int_test("trunc", code);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
jit_set_ip(codeBuffer);
|
||||||
|
jit_leaf(0);
|
||||||
|
jitfp_begin(buffer);
|
||||||
|
jitfp_ceil(JIT_RET,
|
||||||
|
jitfp_ldi_d(&a)
|
||||||
|
);
|
||||||
|
jit_ret();
|
||||||
|
#ifdef LIGHTNING_DISASSEMBLE
|
||||||
|
disassemble(stderr, codeBuffer, jit_get_ip().ptr);
|
||||||
|
#endif
|
||||||
|
#ifndef LIGHTNING_CROSS
|
||||||
|
int_test("ceil", code);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
jit_set_ip(codeBuffer);
|
||||||
|
jit_leaf(0);
|
||||||
|
jitfp_begin(buffer);
|
||||||
|
jitfp_floor(JIT_RET,
|
||||||
|
jitfp_ldi_d(&a)
|
||||||
|
);
|
||||||
|
jit_ret();
|
||||||
|
#ifdef LIGHTNING_DISASSEMBLE
|
||||||
|
disassemble(stderr, codeBuffer, jit_get_ip().ptr);
|
||||||
|
#endif
|
||||||
|
#ifndef LIGHTNING_CROSS
|
||||||
|
int_test("floor", code);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
jit_set_ip(codeBuffer);
|
||||||
|
jit_leaf(0);
|
||||||
|
jitfp_begin(buffer);
|
||||||
|
jitfp_round(JIT_RET,
|
||||||
|
jitfp_ldi_d(&a)
|
||||||
|
);
|
||||||
|
jit_ret();
|
||||||
|
#ifdef LIGHTNING_DISASSEMBLE
|
||||||
|
disassemble(stderr, codeBuffer, jit_get_ip().ptr);
|
||||||
|
#endif
|
||||||
|
#ifndef LIGHTNING_CROSS
|
||||||
|
int_test("round", code);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0 && defined JIT_TRANSCENDENTAL
|
||||||
|
jit_set_ip(codeBuffer);
|
||||||
|
jit_leaf(0);
|
||||||
|
jitfp_begin(buffer);
|
||||||
|
jitfp_sti_d(&a,
|
||||||
|
jitfp_log(
|
||||||
|
jitfp_exp(jitfp_imm(1.0))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
jit_ret();
|
||||||
|
code.vptr();
|
||||||
|
#ifdef LIGHTNING_DISASSEMBLE
|
||||||
|
disassemble(stderr, codeBuffer, jit_get_ip().ptr);
|
||||||
|
#endif
|
||||||
|
#ifndef LIGHTNING_CROSS
|
||||||
|
printf("log e = \t%f\n", a);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
jit_set_ip(codeBuffer);
|
||||||
|
jit_leaf(0);
|
||||||
|
jitfp_begin(buffer);
|
||||||
|
jitfp_sti_d(&a,
|
||||||
|
jitfp_atn(
|
||||||
|
jitfp_imm(1.732050807657)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
jit_ret();
|
||||||
|
code.vptr();
|
||||||
|
#ifdef LIGHTNING_DISASSEMBLE
|
||||||
|
disassemble(stderr, codeBuffer, jit_get_ip().ptr);
|
||||||
|
#endif
|
||||||
|
#ifndef LIGHTNING_CROSS
|
||||||
|
printf("pi = \t%f\n", a*3);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
jit_set_ip(codeBuffer);
|
||||||
|
jit_leaf(0);
|
||||||
|
jitfp_begin(buffer);
|
||||||
|
jitfp_sti_d(&a,
|
||||||
|
jitfp_tan(
|
||||||
|
jitfp_ldi_d(&a)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
jit_ret();
|
||||||
|
code.vptr();
|
||||||
|
#ifdef LIGHTNING_DISASSEMBLE
|
||||||
|
disassemble(stderr, codeBuffer, jit_get_ip().ptr);
|
||||||
|
#endif
|
||||||
|
#ifndef LIGHTNING_CROSS
|
||||||
|
printf("tan^2 pi/3 = \t%f\n", a*a);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* JIT_TRANSCEDENTAL */
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
5
tests/testfp.ok
Normal file
5
tests/testfp.ok
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
compare 1 1 0 1 1
|
||||||
|
trunc -2 -2 0 2 2
|
||||||
|
ceil -2 -2 0 3 3
|
||||||
|
floor -3 -3 0 2 2
|
||||||
|
round -3 -2 0 2 3
|
Loading…
Add table
Add a link
Reference in a new issue