1
Fork 0
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:
Paolo Bonzini 2004-10-10 21:18:38 +00:00
commit 3b4c061913
79 changed files with 26993 additions and 0 deletions

2
AUTHORS Normal file
View file

@ -0,0 +1,2 @@
Paolo Bonzini <bonzini@gnu.org>
i386 and PPC assemblers by Ian Piumarta <piumarta@inria.fr>

340
COPYING Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

77
doc/toc.texi Normal file
View 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

File diff suppressed because it is too large Load diff

4
doc/version.texi Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

408
lightning/i386/core.h Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

898
opcode/i386.h Normal file
View 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
View 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

File diff suppressed because it is too large Load diff

248
opcode/ppc.h Normal file
View 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
View 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 (&reg_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

File diff suppressed because it is too large Load diff

220
opcode/sparc.h Normal file
View 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
View 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
View 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
View 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
View file

@ -0,0 +1 @@
5 + 4 = 9

77
tests/fib.c Normal file
View 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
View file

@ -0,0 +1 @@
nfibs(32) = 7049155

77
tests/fibdelay.c Normal file
View 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
View file

@ -0,0 +1 @@
nfibs(36) = 48315633

75
tests/fibit.c Normal file
View 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
View file

@ -0,0 +1 @@
nfibs(36) = 48315633

173
tests/funcfp.c Normal file
View 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
View file

@ -0,0 +1 @@
result is 171.150000 17.250000

59
tests/incr.c Normal file
View 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
View file

@ -0,0 +1 @@
5 + 1 = 6

68
tests/printf.c Normal file
View 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
View file

@ -0,0 +1 @@
looks like 1024 bytes sufficed

2409
tests/printf2.c Normal file

File diff suppressed because it is too large Load diff

2376
tests/printf2.ok Normal file

File diff suppressed because it is too large Load diff

445
tests/rpn.c Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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