[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] 01/437: initial import
From: |
Andy Wingo |
Subject: |
[Guile-commits] 01/437: initial import |
Date: |
Mon, 2 Jul 2018 05:13:32 -0400 (EDT) |
wingo pushed a commit to branch lightning
in repository guile.
commit 3b4c0619133a7a6e829d2d2db267f5b0f4e8c93d
Author: Paolo Bonzini <address@hidden>
Date: Sun Oct 10 21:18:38 2004 +0000
initial import
(automatically generated log message)
git-archimport-id: address@hidden/lightning--stable--1.2--base-0
---
AUTHORS | 2 +
COPYING | 340 ++++++
COPYING.DOC | 355 ++++++
COPYING.LESSER | 503 ++++++++
ChangeLog | 75 ++
INSTALL | 229 ++++
Makefile.am | 19 +
NEWS | 124 ++
README | 3 +
config/help2man | 559 +++++++++
config/texi2dvi | 660 +++++++++++
configure.ac | 94 ++
doc/Makefile.am | 18 +
doc/body.texi | 306 +++++
doc/lightning.texi | 105 ++
doc/porting.texi | 1415 +++++++++++++++++++++++
doc/toc.texi | 77 ++
doc/using.texi | 1086 ++++++++++++++++++
doc/version.texi | 4 +
lightning-inst.h | 65 ++
lightning.h.in | 88 ++
lightning.m4 | 57 +
lightning/Makefile.am | 16 +
lightning/asm-common.h | 197 ++++
lightning/core-common.h | 568 ++++++++++
lightning/fp-common.h | 260 +++++
lightning/funcs-common.h | 48 +
lightning/i386/asm.h | 1060 +++++++++++++++++
lightning/i386/core.h | 408 +++++++
lightning/i386/fp.h | 252 +++++
lightning/i386/funcs.h | 39 +
lightning/ppc/asm.h | 597 ++++++++++
lightning/ppc/core.h | 276 +++++
lightning/ppc/fp.h | 104 ++
lightning/ppc/funcs.h | 161 +++
lightning/sparc/asm.h | 303 +++++
lightning/sparc/core.h | 249 ++++
lightning/sparc/fp.h | 163 +++
lightning/sparc/funcs.h | 65 ++
lightningize.in | 226 ++++
opcode/Makefile.am | 7 +
opcode/ansidecl.h | 13 +
opcode/bfd.h | 185 +++
opcode/dis-asm.h | 175 +++
opcode/dis-buf.c | 70 ++
opcode/disass.c | 78 ++
opcode/i386-dis.c | 2031 +++++++++++++++++++++++++++++++++
opcode/i386.h | 898 +++++++++++++++
opcode/ppc-dis.c | 238 ++++
opcode/ppc-opc.c | 2830 ++++++++++++++++++++++++++++++++++++++++++++++
opcode/ppc.h | 248 ++++
opcode/sparc-dis.c | 868 ++++++++++++++
opcode/sparc-opc.c | 1757 ++++++++++++++++++++++++++++
opcode/sparc.h | 220 ++++
opcode/sysdep.h | 10 +
tests/Makefile.am | 16 +
tests/add.c | 61 +
tests/add.ok | 1 +
tests/fib.c | 77 ++
tests/fib.ok | 1 +
tests/fibdelay.c | 77 ++
tests/fibdelay.ok | 1 +
tests/fibit.c | 75 ++
tests/fibit.ok | 1 +
tests/funcfp.c | 173 +++
tests/funcfp.ok | 1 +
tests/incr.c | 59 +
tests/incr.ok | 1 +
tests/printf.c | 68 ++
tests/printf.ok | 1 +
tests/printf2.c | 2409 +++++++++++++++++++++++++++++++++++++++
tests/printf2.ok | 2376 ++++++++++++++++++++++++++++++++++++++
tests/rpn.c | 445 ++++++++
tests/rpn.ok | 6 +
tests/rpnfp.c | 134 +++
tests/rpnfp.ok | 6 +
tests/run-test | 9 +
tests/testfp.c | 186 +++
tests/testfp.ok | 5 +
79 files changed, 26993 insertions(+)
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..d19bf6b
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,2 @@
+Paolo Bonzini <address@hidden>
+i386 and PPC assemblers by Ian Piumarta <address@hidden>
\ No newline at end of file
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..d60c31a
--- /dev/null
+++ b/COPYING
@@ -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.
diff --git a/COPYING.DOC b/COPYING.DOC
new file mode 100644
index 0000000..b42936b
--- /dev/null
+++ b/COPYING.DOC
@@ -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.
diff --git a/COPYING.LESSER b/COPYING.LESSER
new file mode 100644
index 0000000..18662c2
--- /dev/null
+++ b/COPYING.LESSER
@@ -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!
+
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..5fbd089
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,75 @@
+2004-03-02 Paolo Bonzini <address@hidden>
+
+ * 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 <address@hidden>
+
+ * 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 <address@hidden>
+
+ * tests/rpnfp.c: new example, suggested by Basile
+ Starynkevitch.
+ * tests/rpnfp.ok: new example.
+
+2003-12-12 Paolo Bonzini <address@hidden>
+
+ * tests/add.c: new test, suggested by Steve Dekorte.
+ * tests/add.c: new test.
+
+2003-11-14 Paolo Bonzini <address@hidden>
+ John Redford <address@hidden>
+
+ * 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 <address@hidden>
+
+ * lightning/i386/core.h: use JITSORRY in jit_replace
+ * lightning/asm-common.h: define JITSORRY
+
+2003-05-14 Paolo Bonzini <address@hidden>
+
+ * 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 <address@hidden>
+
+ * tests/printf2.c: new test
+
+2001-05-03 Paolo Bonzini <address@hidden>
+
+ * tests/printf.c: made the message platform independent
+
+2001-01-19 Paolo Bonzini <address@hidden>
+
+ * 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
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..54caf7c
--- /dev/null
+++ b/INSTALL
@@ -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.
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..5077ec1
--- /dev/null
+++ b/Makefile.am
@@ -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
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..bae18f3
--- /dev/null
+++ b/NEWS
@@ -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.
diff --git a/README b/README
new file mode 100644
index 0000000..ae36ea5
--- /dev/null
+++ b/README
@@ -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.
diff --git a/config/help2man b/config/help2man
new file mode 100755
index 0000000..5d4377b
--- /dev/null
+++ b/config/help2man
@@ -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 <address@hidden>
+# 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 <address@hidden>
+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 <address@hidden>.
+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.
address@hidden(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';
+ }
+
+ $_;
+}
diff --git a/config/texi2dvi b/config/texi2dvi
new file mode 100755
index 0000000..010b586
--- /dev/null
+++ b/config/texi2dvi
@@ -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 <address@hidden>.
+#
+# Please send bug reports, etc. to address@hidden
+# 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 <address@hidden>,
+general questions and discussion to <address@hidden>.
+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 address@hidden 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
+/address@hidden/,/address@hidden tex/{
+ s/^/@c texi2dvi/
+}
+/address@hidden/,/address@hidden iftex/{
+ s/^/@c texi2dvi/
+ /address@hidden address@hidden/,/address@hidden address@hidden macro/{
+ s/address@hidden texi2dvi//
+ }
+}
+/address@hidden/,/address@hidden html/{
+ s/^/@c (texi2dvi)/
+}
+/address@hidden/,/address@hidden ifhtml/{
+ s/^/@c (texi2dvi)/
+}
+/address@hidden/,/address@hidden ifnottex/{
+ s/^/@c (texi2dvi)/
+}
+/address@hidden/,/address@hidden ifinfo/{
+ /address@hidden/p
+ /address@hidden/,/address@hidden menu/p
+ t
+ s/^/@c (texi2dvi)/
+}
+s/address@hidden/@c address@hidden/
+s/address@hidden ifnotinfo/@c address@hidden ifnotinfo/
+EOF
+# Uncommenting is simple: Remove any leading address@hidden texi2dvi'.
+uncomment_iftex_sed=$utildir/uncomment.sed
+cat <<EOF >$uncomment_iftex_sed
+s/address@hidden 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 '/address@hidden/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.
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..e1a9154
--- /dev/null
+++ b/configure.ac
@@ -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, address@hidden, 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))
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..968812f
--- /dev/null
+++ b/doc/Makefile.am
@@ -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
+
diff --git a/doc/body.texi b/doc/body.texi
new file mode 100644
index 0000000..cccadd0
--- /dev/null
+++ b/doc/body.texi
@@ -0,0 +1,306 @@
address@hidden
address@hidden @lightning{}, a library for dynamic code generation
address@hidden
+ * @value{TITLE}: (lightning).
address@hidden 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.
address@hidden ifinfo
+
address@hidden odd
+
address@hidden
address@hidden @value{TITLE}
address@hidden Version @value{VERSION}
address@hidden @value{UPDATE-MONTH}
+
address@hidden by Paolo Bonzini
+
address@hidden The following two commands start the copyright page.
address@hidden
address@hidden 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.
address@hidden titlepage
+
address@hidden ISTEX
address@hidden Top
address@hidden @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.
+
address@hidden toc.texi
address@hidden ifclear
+
address@hidden Overview
address@hidden Introduction to @lightning{}
+
address@hidden 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.
address@hidden ifset
+
address@hidden USING
+This manual assumes that you are pretty comfortable with the usage of
address@hidden for dynamic code generation, as described in
address@hidden 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.
address@hidden 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
address@hidden 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.
+
address@hidden USING
+This manual describes the @lightning{} dynamic code generation library.
address@hidden provides a portable, fast and easily retargetable dynamic
+code generation system.
address@hidden ifset
address@hidden USING
address@hidden provides a portable, fast and easily retargetable dynamic
+code generation system.
address@hidden 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.
+
address@hidden Drawbacks
+
address@hidden 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
address@hidden
+ subr_i R0, R1, R2 @rem{!Compute R0 = R1 - R2}
address@hidden example
address@hidden
+is translated to two instruction, of which the second depends on the
+result of the first:
address@hidden
+ movl %ebx, %eax @rem{! Move R1 into R0}
+ subl %edx, %eax @rem{! Subtract R2 from R0}
address@hidden example
+
address@hidden BOTH
address@hidden Using GNU lightning
address@hidden Using @lightning{}
+
+This chapter describes installing and using @lightning{}.
+
address@hidden
address@hidden
address@hidden menu
+
address@hidden
address@hidden ifset
+
address@hidden USING
address@hidden using.texi
address@hidden ifset
+
address@hidden BOTH
address@hidden
+
address@hidden Porting GNU lightning
address@hidden Porting @lightning{}
+
+This chapter describes the process of porting @lightning{}.
+It assumes that you are pretty comfortable with the usage of
address@hidden for dynamic code generation, as described in
address@hidden GNU lightning}.
+
address@hidden
address@hidden
address@hidden menu
+
address@hidden
address@hidden ifset
+
address@hidden PORTING
address@hidden porting.texi
address@hidden ifset
+
address@hidden BOTH
address@hidden
address@hidden ifset
+
address@hidden Future
address@hidden 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
address@hidden@@gnu.org} if you are interested in adding your efforts
+to the @lightning{} project.
+
+Tasks:
address@hidden @bullet
address@hidden
+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,
address@hidden could be ported to others---namely, the Alpha and
+MIPS architectures.
+
address@hidden
+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 address@hidden x86's absolute
+jumps, for example, are actually slow indirect jumps, and need a
+register.}
+
address@hidden
+Optimize leaf procedures on the SPARC. This involves using the
+output registers (@address@hidden) instead of the local registers
+(@address@hidden) 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.
address@hidden itemize
+
+
address@hidden Acknowledgements
address@hidden 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
address@hidden to use the run-time assemblers he had wrote for @sc{ccg}.
address@hidden 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.
+
address@hidden
address@hidden
address@hidden iftex
+
address@hidden
diff --git a/doc/lightning.texi b/doc/lightning.texi
new file mode 100644
index 0000000..dee770e
--- /dev/null
+++ b/doc/lightning.texi
@@ -0,0 +1,105 @@
+\input texinfo.tex @c -*- texinfo -*-
address@hidden %**start of header (This is for running Texinfo on a region.)
+
address@hidden lightning.info
+
address@hidden TITLE Using and porting @sc{gnu} @i{lightning}
address@hidden TOPIC installing, using and porting
address@hidden BOTH
address@hidden USING
address@hidden PORTING
+
address@hidden @value{TITLE}
+
address@hidden
---------------------------------------------------------------------
address@hidden Common macros
address@hidden
---------------------------------------------------------------------
+
address@hidden bulletize{a}
address@hidden
+\a\
address@hidden macro
+
address@hidden rem{a}
address@hidden@i{\a\}}
address@hidden macro
+
address@hidden gnu{}
address@hidden
address@hidden macro
+
address@hidden lightning{}
address@hidden @i{lightning}
address@hidden macro
+
address@hidden
---------------------------------------------------------------------
address@hidden Macros for Texinfo 3.1/4.0 compatibility
address@hidden
---------------------------------------------------------------------
+
address@hidden Emulate the address@hidden' command which is found in Texinfo 4.0
address@hidden
address@hidden ISTEX
address@hidden iftex
+
address@hidden @hlink (macro), @url and @email are used instead of @uref for
Texinfo 3.1
address@hidden compatibility
address@hidden hlink{url, link}
+\link\ (\url\)
address@hidden macro
+
address@hidden ifhtml can only be true in Texinfo 4.0, which has uref
address@hidden
address@hidden hlink
+
address@hidden hlink{url, link}
address@hidden, \link\}
address@hidden macro
+
address@hidden email{mail}
address@hidden:\mail\, , \mail\}
address@hidden macro
+
address@hidden url{url}
address@hidden
address@hidden macro
address@hidden ifhtml
+
address@hidden
---------------------------------------------------------------------
address@hidden References to the other half of the manual
address@hidden
---------------------------------------------------------------------
+
address@hidden USING
address@hidden usingref{node, name}
address@hidden, , \name\}
address@hidden macro
address@hidden ifset
+
address@hidden USING
address@hidden usingref{node, name}
address@hidden, , \name\, u-lightning, Using @sc{gnu} @i{lightning}}
address@hidden macro
address@hidden ifclear
+
address@hidden PORTING
address@hidden portingref{node, name}
address@hidden, , \name\}
address@hidden macro
address@hidden ifset
+
address@hidden PORTING
address@hidden portingref{node, name}
address@hidden, , \name\, p-lightning, Porting @sc{gnu} @i{lightning}}
address@hidden macro
address@hidden ifclear
+
address@hidden
---------------------------------------------------------------------
address@hidden End of macro section
address@hidden
---------------------------------------------------------------------
+
address@hidden version.texi
address@hidden body.texi
+
address@hidden %**end of header (This is for running Texinfo on a region.)
+
address@hidden
***********************************************************************
+
diff --git a/doc/porting.texi b/doc/porting.texi
new file mode 100644
index 0000000..7423397
--- /dev/null
+++ b/doc/porting.texi
@@ -0,0 +1,1415 @@
address@hidden Structure of a port
address@hidden An overview of the porting process
+
+A particular port of @lightning{} is composed of four files. These
+have a common suffix which identifies the port (for example,
address@hidden or @code{ppc}), and a prefix that identifies their
+function; they are:
+
address@hidden @bullet
address@hidden
address@hidden@var{suffix}.h}, which contains the description of the
+target machine's instruction format. The creation of this file
+is discussed in @ref{Run-time assemblers, , Creating the run-time
+assembler}.
+
address@hidden
address@hidden@var{suffix}.h}, which contains the mappings from
address@hidden's instruction set to the target machine's assembly
+language format. The creation of this file is discussed in
address@hidden macros, , Creating the platform-independent layer}.
+
address@hidden
address@hidden@var{suffix}.h}, for now, only contains the definition
+of @code{jit_flush_code}. The creation of this file is briefly
+discussed in @ref{Standard functions, , More complex tasks in
+the platform-independent layer}.
+
address@hidden
address@hidden@var{suffix}.h}, which contains the description of the
+target machine's instruction format and the internal macros for doing
+floating point computation. The creation of this file is discussed
+in @ref{Floating-point macros, , Implementing macros for floating
+point}.
address@hidden itemize
+
+Before doing anything, you have to add the ability to recognize the
+new port during the configuration process. This is explained in
address@hidden configure, , Automatically recognizing the new platform}.
+
address@hidden Adjusting configure
address@hidden Automatically recognizing the new platform
+
+Before starting your port, you have to add the ability to recognize the
+new port during the configure process. You only have to run
address@hidden, which you'll find in the main distribution
+directory, and note down the first part of the output (up to the first
+dash).
+
+Then, in the two files @file{configure.in} and @file{lightning.m4},
+lookup the line
address@hidden
+ case "$host_cpu" in
address@hidden example
+
address@hidden
+and, right after it, add the line:
address@hidden
+ @var{cpu-name}) address@hidden ;;
address@hidden example
+
address@hidden
+where @var{cpu-name} is the cpu as output by @file{config.guess}, and
address@hidden is the suffix that you are going to use for your files
+(@pxref{Structure of a port, , An overview of the porting process}).
+
+Now create empty files for your new port:
address@hidden
+ touch lightning/asm-xxx.h
+ touch lightning/fp-xxx.h
+ touch lightning/core-xxx.h
+ touch lightning/funcs-xxx.h
address@hidden example
+
address@hidden
+and run @file{configure}, which should create the symlinks that are
+needed by @code{lightning.h}. This is important because it will allow
+you to use @lightning{} (albeit in a limited way) for testing even
+before the port is completed.
+
address@hidden Run-time assemblers
address@hidden Creating the run-time assembler
+
+The run-time assembler is a set of macros whose purpose is to assemble
+instructions for the target machine's assembly language, translating
+mnemonics to machine language together with their operands. While a
+run-time assembler is not, strictly speaking, part of @lightning{}
+(it is a private layer to be used while implementing the standard
+macros that are ultimately used by clients), designing a run-time
+assembler first allows you to think in terms of assembly language
+rather than binary code (address@hidden), making it considerably easier
+to write the standard macros.
+
+Creating a run-time assembler is a tedious process rather than a
+difficult one, because most of the time will be spent collecting and
+copying information from the architecture's manual.
+
+Macros defined by a run-time assembler are conventionally named after
+the mnemonic and the type of its operands. Examples took from the
+SPARC's run-time assembler are @code{ADDrrr}, a macro that assembles
+an @code{ADD} instruction with three register operands, and
address@hidden, which assembles a @code{SUBCC} instruction whose second
+operand is an immediate and the remaining two are registers.
+
+The first step in creating the assembler is to pick a convention for
+operand specifiers (@code{r} and @code{i} in the example above) and for
+register names. On the SPARC, this convention is as follows
+
address@hidden @code
address@hidden @b{r}
+A register name. For every @code{r} in the macro name, a numeric
+parameter @code{RR} is passed to the macro, and the operand is assembled
+as @address@hidden
+
address@hidden @b{i}
+An immediate, usually a 13-bit signed integer (with exception for
+instructions such as @code{SETHI} and branches). The macros check
+the size of the passed parameter if @lightning{} is configured with
address@hidden
+
address@hidden @b{x}
+A combination of two @code{r} parameters, which are summed to determine
+the effective address in a memory load/store operation.
+
address@hidden @b{m}
+A combination of an @code{r} and @code{i} parameter, which are summed to
+determine the effective address in a memory load/store operation.
address@hidden table
+
+Additional macros can be defined that provide easier access to register
+names. For example, on the SPARC, @code{_Ro(3)} and @code{_Rg(5)} map
+respectively to @code{%o3} and @code{%g5}; on the x86, instead, symbolic
+representations of the register names are provided (for example,
address@hidden and @code{_EBX}).
+
+CISC architectures sometimes have registers of different sizes--this is
+the case on the x86 where @code{%ax} is a 16-bit register while
address@hidden is a 32-bit one. In this case, it can be useful to embed
+information on the size in the definition of register names. The x86
+machine language, for example, represents all three of @code{%bh},
address@hidden and @code{%edi} as 7; but the x86 run-time assemblers defines
+them with different numbers, putting the register's size in the upper
+nybble (for example, @samp{17h} for @code{%bh} and @samp{27h} for
address@hidden) so that consistency checks can be made on the operands'
+sizes when @code{--enable-assertions} is used.
+
+The next important part defines the native architecture's instruction
+formats. These can be as few as ten on RISC architectures, and as many
+as fifty on CISC architectures. In the latter case it can be useful
+to define more macros for sub-formats (such as macros for different
+addressing modes) or even for sub-fields in an instruction. Let's see
+an example of these macros.
+
address@hidden
+#define _2i( OP, RD, OP2, IMM)
+ _I((_u2 (OP )<<30) | (_u5(RD)<<25) | (_u3(OP2)<<22) |
+ _u22(IMM) )
address@hidden example
+
+The name of the macro, @code{_2i}, indicates a two-operand instruction
+comprising an immediate operand. The instruction format is:
+
address@hidden
+ .------.---------.------.-------------------------------------------.
+ | OP | RD | OP2 | IMM |
+ |------+---------+------+-------------------------------------------|
+ |2 bits| 5 bits |3 bits| 22 bits |
+ |31-30 | 29-25 | 22-24| 0-21 |
+ '------'---------'------'-------------------------------------------'
address@hidden example
+
address@hidden provides macros named @code{_sXX(OP)} and @code{_uXX(OP)},
+where XX is a number between 1 and 31, which address@hidden when
address@hidden is used.} whether @code{OP} can be
+represented as (respectively) a signed or unsigned integer of the
+given size. What the macro above does, then, is to shift and @sc{or}
+together the different fields, ensuring that each of them fits the field.
+
+Here is another definition, this time for the PowerPC architecture.
+
address@hidden
+#define _X(OP,RD,RA,RB,XO,RC)
+ _I((_u6 (OP)<<26) | (_u5(RD)<<21) | (_u5(RA)<<16) |
+ ( _u5(RB)<<11) | (_u10(XO)<<1) | _u1(RC) )
address@hidden example
+
+Here is the bit layout corresponding to this instruction format:
+
address@hidden
+ .--------.--------.--------.--------.---------------------.-------.
+ | OP | RD | RA | RB | X0 | RC |
+ |--------+--------+--------+--------+-----------------------------|
+ | 6 bits | 5 bits | 5 bits | 5 bits | 10 bits | 1 bit |
+ | 31-26 | 25-21 | 16-20 | 11-15 | 1-10 | 0 |
+ '--------'---------'-------'--------'-----------------------------'
address@hidden example
+
+How do these macros actually generate code? The secret lies in the
address@hidden macro, which is one of four predefined macros which actually
+store machine language instructions in memory. They are @code{_B},
address@hidden, @code{_I} and @code{_L}, respectively for 8-bit, 16-bit,
+32-bit, and @code{long} (either 32-bit or 64-bit, depending on the
+architecture) values.
+
+Next comes another set of macros (usually the biggest) which represents
+the actual mnemonics---macros such as @code{ADDrrr} and @code{SUBCCrir},
+which were cited earlier in this chapter, belong to this set. Most of
+the times, all these macros will do is to use the ``instruction format''
+macros, specifying the values of the fields in the different instruction
+formats. Let's see a few of these definitions, again taken from the
+SPARC assembler:
+
address@hidden
+#define BAi(DISP) _2 (0, 0, 8, 2, DISP)
+#define BA_Ai(DISP) _2 (0, 1, 8, 2, DISP)
+
+#define SETHIir(IMM, RD) _2i (0, RD, 4, IMM)
+
+#define ADDrrr(RS1, RS2, RD) _3 (2, RD, 0, RS1, 0, 0, RS2)
+#define ADDrir(RS1, IMM, RD) _3i (2, RD, 0, RS1, 1, IMM)
+#define ADDCCrrr(RS1, RS2, RD) _3 (2, RD, 16, RS1, 0, 0, RS2)
+#define ADDCCrir(RS1, IMM, RD) _3i (2, RD, 16, RS1, 1, IMM)
+#define ANDrrr(RS1, RS2, RD) _3 (2, RD, 1, RS1, 0, 0, RS2)
+#define ANDrir(RS1, IMM, RD) _3i (2, RD, 1, RS1, 1, IMM)
+#define ANDCCrrr(RS1, RS2, RD) _3 (2, RD, 17, RS1, 0, 0, RS2)
+#define ANDCCrir(RS1, IMM, RD) _3i (2, RD, 17, RS1, 1, IMM)
address@hidden example
+
+A few things have to be noted. For example:
address@hidden @bullet
address@hidden
+The SPARC assembly language sometimes uses a comma inside a mnemonic
+(for example, @code{ba,a}). This symbol is not allowed inside a
address@hidden macro name, so it is replaced with an underscore; the same
+is done with the dots found in the PowerPC assembly language (for
+example, @code{andi.} is defined as @code{ANDI_rri}).
+
address@hidden
+It can be useful to group together instructions with the same
+instruction format, as doing this tends to make the source code
+more readable (numbers are put in the same columns).
+
address@hidden
+Using an editor without automatic wrap at end of line can be useful,
+since run-time assemblers tend to have very long lines.
address@hidden itemize
+
+A final touch is to define the synthetic instructions, which are
+usually found on RISC machines. For example, on the SPARC, the
address@hidden instruction has two synonyms (@code{LDUW} and @code{LDSW})
+which are defined thus:
+
address@hidden
+#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)
address@hidden example
+
+Other common case are instructions which take advantage of registers
+whose value is hard-wired to zero, and short-cut instructions which
+hard-code some or all of the operands:
+
address@hidden
address@hidden/* Destination is %g0\, which the processor never overwrites. */}
+#define CMPrr(R1, R2) SUBCCrrr(R1, R2, 0) @rem{/* subcc %r1\, %r2\, %g0 */}
+
address@hidden/* One of the source registers is hard-coded to be %g0. */}
+#define NEGrr(R,S) SUBrrr(0, R, S) @rem{/* sub %g0\, %rR\, %rS */}
+
address@hidden/* All of the operands are hard-coded. */}
+#define RET() JMPLmr(31,8 ,0) @rem{/* jmpl [%r31+8]\, %g0 */}
+
address@hidden/* One of the operands acts as both source and destination */}
+#define BSETrr(R,S) ORrrr(R, S, S) @rem{/* or %rR\, %rS\, %rS */}
address@hidden example
+
+Specific to RISC computers, finally, is the instruction to load an
+arbitrarily sized immediate into a register. This instruction is
+usually implemented as one or two basic instructions:
+
address@hidden
address@hidden
+If the number is small enough, an instruction is sufficient
+(@code{LI} or @code{ORI} on the PowerPC, @code{MOV} on the SPARC).
+
address@hidden
+If the lowest bits are all zeroed, an instruction is sufficient
+(@code{LIS} on the PowerPC, @code{SETHI} on the SPARC).
+
address@hidden
+Otherwise, the high bits are set first (with @code{LIS} or
address@hidden), and the result is then @sc{or}ed with the low
+bits
address@hidden enumerate
+
+Here is the definition of such an instruction for the PowerPC:
+
address@hidden
+#define MOVEIri(R,I) (_siP(16,I) ? LIri(R,I) : \ @rem{/* case 1 */}
+ (_uiP(16,I) ? ORIrri(R,0,I) : \ @rem{/* case 1 */}
+ _MOVEIri(R, _HI(I), _LO(I)) )) @rem{/* case 2/3 */}
+
+#define _MOVEIri(H,L,R) (LISri(R,H), (L ? ORIrri(R,R,L) : 0))
address@hidden example
+
address@hidden
+and for the SPARC:
+
address@hidden
+#define SETir(I,R) (_siP(13,I) ? MOVir(I,R) : \
+ _SETir(_HI(I), _LO(I), R))
+
+#define _SETir(H,L,R) (SETHIir(H,R), (L ? ORrir(R,L,R) : 0))
address@hidden example
+
+In both cases, @code{_HI} and @code{_LO} are macros for internal use
+that extract different parts of the immediate operand.
+
+You should take a look at the run-time assemblers distributed with
address@hidden before trying to craft your own. In particular, make
+sure you understand the RISC run-time assemblers (the SPARC's is
+the simplest) before trying to decypher the x86 run-time assembler,
+which is significantly more complex.
+
+
address@hidden Standard macros
address@hidden Creating the platform-independent layer
+
+The platform-independent layer is the one that is ultimately used
+by @lightning{} clients. Creating this layer is a matter of creating
+a hundred or so macros that comprise part of the interface used by
+the clients, as described in
address@hidden instruction set, @lightning{}'s instruction set}.
+
+Fortunately, a number of these definitions are common to the different
+platforms and are defined just once in one of the header files that
+make up @lightning{}, that is, @file{core-common.h}.
+
+Most of the macros are relatively straight-forward to implement (with
+a few caveats for architectures whose assembly language only offers
+two-operand arithmetic instructions). This section will cover the
+tricky points, before presenting the complete listing of the macros
+that make up the platform-independent interface provided by
address@hidden
+
address@hidden
address@hidden
address@hidden menu
+
address@hidden Forward references
address@hidden Implementing forward references
+
+Implementation of forward references takes place in:
+
address@hidden @bullet
address@hidden The branch macros
address@hidden The @code{jit_patch} macros
address@hidden itemize
+
+Roughly speaking, the branch macros, as seen in @usingref{GNU lightning
+macros, Generating code at run-time}, return a value that later calls
+to @code{jit_patch} use to complete the assembly of the forward
+reference. This value is usually the contents of the program counter
+after the branch instruction is compiled (which is accessible in the
address@hidden variable). Let's see an example from the x86 back-end:
+
address@hidden
+#define jit_bmsr_i(label, s1, s2) \
+ (TESTLrr((s1), (s2)), JNZm(label,0,0,0), _jit.pc)
address@hidden example
+
+The @code{bms} (@dfn{branch if mask set}) instruction is assembled as
+the combination of a @code{TEST} instruction (bit-wise @sc{and} between
+the two operands) and a @code{JNZ} instruction (jump if non-zero). The
+macro then returns the final value of the program counter.
+
address@hidden is one of the few macros that need to possess a
+knowledge of the machine's instruction formats. Its purpose is to
+patch a branch instruction (identified by the value returned at the
+moment the branch was compiled) to jump to the current position (that
+is, to the address identified by @code{_jit.pc}).
+
+On the x86, the displacement between the jump and the landing point is
+expressed as a 32-bit signed integer lying in the last four bytes of the
+jump instruction. The definition of @code{_jit_patch} is:
+
address@hidden
+#define jit_patch(jump_pc) (*_PSL((jump_pc) - 4) = \
+ _jit.pc - (jump_pc))
address@hidden example
+
+The @code{_PSL} macro is nothing more than a cast to @code{long *},
+and is used here to shorten the definition and avoid cluttering it with
+excessive parentheses. These type-cast macros are:
+
address@hidden @bullet
address@hidden @code{_PUC(X)} to cast to a @code{unsigned char *}.
address@hidden @code{_PUS(X)} to cast to a @code{unsigned short *}.
address@hidden @code{_PUI(X)} to cast to a @code{unsigned int *}.
address@hidden @code{_PSL(X)} to cast to a @code{long *}.
address@hidden @code{_PUL(X)} to cast to a @code{unsigned long *}.
address@hidden itemize
+
+On other platforms, notably RISC ones, the displacement is embedded into
+the instruction itself. In this case, @code{jit_patch} must first zero
+out the field, and then @sc{or} in the correct displacement. The SPARC,
+for example, encodes the displacement in the bottom 22 bits; in addition
+the right-most two bits are suppressed, which are always zero because
+instruction have to be word-aligned.
+
address@hidden
+#define jit_patch(delay_pc) jit_patch_ ( ((delay_pc) - 1) )
+
address@hidden/* branch instructions return the address of the @emph{delay}
+ * instruction---this is just a helper macro that makes the code more
+ * readable.
+ */}
+#define jit_patch_(jump_pc) (*jump_pc = \
+ (*jump_pc & ~_MASK(22)) | \
+ ((_UL(_jit.pc) - _UL(jump_pc)) >> 2) & _MASK(22))
address@hidden example
+
+This introduces more predefined shortcut macros:
address@hidden @bullet
address@hidden @code{_UC(X)} to cast to a @code{unsigned char}.
address@hidden @code{_US(X)} to cast to a @code{unsigned short}.
address@hidden @code{_UI(X)} to cast to a @code{unsigned int}.
address@hidden @code{_SL(X)} to cast to a @code{long}.
address@hidden @code{_UL(X)} to cast to a @code{unsigned long}.
address@hidden @code{_MASK(N)} gives a binary number made of N ones.
address@hidden itemize
+
+
address@hidden Common features
address@hidden Common features supported by @file{core-common.h}
+
+The @file{core-common.h} file contains hundreds of macro definitions
+which will spare you defining a lot of things in the files the are
+specific to your port. Here is a list of the features that
address@hidden provides.
+
address@hidden @b
address@hidden Support for common synthetic instructions
+These are instructions that can be represented as a simple operation,
+for example a bit-wise @sc{and} or a subtraction. @file{core-common.h}
+recognizes when the port-specific header file defines these macros and
+avoids compiler warnings about redefined macros, but there should be
+no need to define them. They are:
address@hidden
+#define jit_extr_c_ui(d, rs)
+#define jit_extr_i_ul(d, rs)
+#define jit_extr_s_ui(d, rs)
+#define jit_negr_i(d, rs)
+#define jit_negr_l(d, rs)
address@hidden example
+
address@hidden Support for the @sc{abi}
+Both @code{jit_prolog}, @code{jit_leaf} and @code{jit_finish} are not
+mandatory. If not defined, they will be defined respectively as an
+empty macro, as a synonym for @code{jit_prolog}, and as a synonym for
address@hidden Whether to define them or not in the port-specific
+header file, it depends on the underlying architecture's @sc{abi}---in
+general, however, you'll need to define at least @code{jit_prolog}.
+
address@hidden Support for uncommon instructions
+These are instructions that many widespread architectures lack.
address@hidden is able to provide default definitions, but they
+are usually inefficient if the hardware provides a way to do these
+operations with a single instruction. They are extension with sign
+and ``reverse subtraction'' (that is, address@hidden@math{-}REG1):
address@hidden
+#define jit_extr_c_i(d, rs)
+#define jit_extr_s_i(d, rs)
+#define jit_rsbi_i(d, rs, is)
+#define jit_rsbi_l(d, rs, is)
address@hidden example
+
address@hidden Conversion between network and host byte ordering
+These macros are no-ops on big endian systems. Don't define them on
+such systems; on the other hand, they are mandatory on little endian
+systems. They are:
address@hidden
+#define jit_ntoh_ui(d, rs)
+#define jit_ntoh_us(d, rs)
address@hidden example
+
address@hidden Support for a ``zero'' register
+Many RISC architectures provide a read-only register whose value is
+hard-coded to be zero; this register is then used implicitly when
+referring to a memory location using a single register. For example,
+on the SPARC, an operand like @code{[%l6]} is actually assembled as
address@hidden If this is the case, you should define
address@hidden to be the number of this register; @file{core-common.h}
+will use it to implement all variations of the @code{ld} and @code{st}
+instructions. For example:
address@hidden
+#define jit_ldi_c(d, is) jit_ldxi_c(d, JIT_RZERO, is)
+#define jit_ldr_i(d, rs) jit_ldxr_c(d, JIT_RZERO, rs)
address@hidden example
+
+If available, JIT_RZERO is also used to provide more efficient
+definitions of the @code{neg} instruction (see ``Support for common
+synthetic instructions'', above).
+
address@hidden Synonyms
address@hidden provides a lot of trivial definitions which make
+the instruction set as orthogonal as possible. For example, adding two
+unsigned integers is exactly the same as adding two signed integers
+(assuming a two's complement representation of negative numbers); yet,
address@hidden provides both @code{jit_addr_i} and @code{jit_addr_ui}
+macros. Similarly, pointers and unsigned long integers behave in the
+same way, but @lightning{} has separate instruction for the two data
+types---those that operate on pointers usually comprise a typecast
+that makes programs clearer.
+
address@hidden Shortcuts
+These define ``synthetic'' instructions whose definition is not as
+trivial as in the case of synonyms, but is anyway standard. This
+is the case for bitwise @sc{not} (which is implemented by XORing a
+string of ones), ``reverse subtraction'' between registers (which is
+converted to a normal subtraction with the two source operands
+inverted), and subtraction of an immediate from a register (which is
+converted to an addition). Unlike @code{neg} and @code{ext} (see
+``Support for common synthetic instructions'', above), which are
+simply non-mandatory, you must not define these functions.
+
address@hidden Support for @code{long}s
+On most systems, @code{long}s and @code{unsigned long}s are the same
+as, respectively, @code{int}s and @code{unsigned int}s. In this case,
address@hidden defines operations on these types to be synonyms.
+
address@hidden @code{jit_state}
+Last but not least, @file{core-common.h} defines the @code{jit_state}
+type. Part of this @code{struct} is machine-dependent and includes
+all kinds of state needed by the back-end; this part is always
+accessible in a re-entrant way as @code{_jitl}. @code{_jitl} will be
+of type @code{struct jit_local_state}; this struct must be defined
+even if no state is required.
+
address@hidden table
+
address@hidden Delay slots
address@hidden Supporting scheduling of delay slots
+
+Delay slot scheduling is obtained by clients through the
address@hidden macro. However this macro is not to be defined
+in the platform-independent layer, because @lightning{} provides
+a common definition in @file{core-common.h}.
+
+Instead, the platform-independent layer must define another macro,
+called @code{jit_fill_delay_after}, which has to exchange the
+instruction to be scheduled in the delay slot with the branch
+instruction. The only parameter accepted by the macro is a call
+to a branch macro, which must be expanded @strong{exactly once} by
address@hidden The client must be able to pass the
+return value of @code{jit_fill_delay_after} to @code{jit_patch}.
+
+There are two possible approaches that can be used in
address@hidden They are summarized in the following
+pictures:
+
address@hidden @bullet
address@hidden
+The branch instructions assemble a @sc{nop} instruction which is
+then removed by @code{jit_fill_delay_after}.
+
address@hidden
+ before | after
+ ---------------------------------+-----------------------------
+ ... |
+ <would-be delay instruction> | <branch instruction>
+ <branch instruction> | <delay instruction>
+ NOP | <--- _jit.pc
+ <--- _jit.pc |
address@hidden example
+
address@hidden
+The branch instruction assembles the branch so that the delay
+slot is annulled, @code{jit_fill_delay_after} toggles the bit:
+
address@hidden
+ before | after
+ ---------------------------------+-----------------------------
+ ... |
+ <would-be delay instruction> | <branch instruction>
+ <branch with annulled delay> | <delay instruction>
+ <--- _jit.pc | <--- _jit.pc
address@hidden example
address@hidden itemize
+
+Don't forget that you can take advantage of delay slots in the
+implementation of boolean instructions such as @code{le} or @code{gt}.
+
address@hidden Immediate values
address@hidden Supporting arbitrarily sized immediate values
+
+This is a problem that is endemic to RISC machines. The basic idea
+is to reserve one or two register to represent large immediate values.
+Let's see an example from the SPARC:
+
address@hidden
+ addi_i R0, V2, 45 | addi_i R0, V2, 10000
+ ---------------------------+---------------------------
+ add %l5, 45, %l0 | set 10000, %l6
+ | add %l5, %l6, %l0
address@hidden example
+
+In this case, @code{%l6} is reserved to be used for large immediates.
+An elegant solution is to use an internal macro which automatically
+decides which version is to be compiled.
+
+Beware of register conflicts on machines with delay slots. This is
+the case for the SPARC, where @code{%l7} is used instead for large
+immediates in compare-and-branch instructions. So the sequence
+
address@hidden
+ jit_delay(
+ jit_addi_i(JIT_R0, JIT_V2, 10000),
+ jit_blei_i(label, JIT_R1, 20000)
+ );
address@hidden example
+
address@hidden
+is assembled this way:
+
address@hidden
+ set 10000, %l6 @rem{! prepare immediate for add}
+ set 20000, %l7 @rem{! prepare immediate for cmp}
+ cmp %l1, %l7
+ ble label
+ add %l5, %l6, %l0 @rem{! delay slot}
+ @end example
+
+Note that using @code{%l6} in the branch instruction would have given
+an incorrect address@hidden would have been filled with the value of
address@hidden@i{20000}} rather than @address@hidden
+
address@hidden Implementing the ABI
address@hidden Implementing the ABI
+
+Implementing the underlying architecture's @sc{abi} is done in the
+macros that handle function prologs and epilogs and argument passing.
+
+Let's look at the prologs and epilogs first. These are usually pretty
+simple and, what's more important, with constant content---that is,
+they always generate exactly the same instruction sequence. Here is
+an example:
+
address@hidden
+ SPARC x86
+ save %sp, -96, %sp push %ebp
+ push %ebx
+ push %esi
+ push %edi
+ movl %esp, %ebp
+ ... ...
+ ret popl %edi
+ restore popl %esi
+ popl %ebx
+ popl %ebp
+ ret
address@hidden example
+
+The registers that are saved (@code{%ebx}, @code{%esi}, @code{%edi}) are
+mapped to the @code{V0} through @code{V2} registers in the @lightning{}
+instruction set.
+
+Argument passing is more tricky. There are basically three
address@hidden speed and ease of implementation, @lightning{} does not
+currently support passing some of the parameters on the stack and some
+in registers.}:
address@hidden @b
address@hidden Register windows
+Output registers are different from input registers---the prolog takes
+care of moving the caller's output registers to the callee's input
+registers. This is the case with the SPARC.
+
address@hidden Passing parameters via registers
+In this case, output registers are the same as input registers. The
+program must take care of saving input parameters somewhere (on the
+stack, or in non-argument registers). This is the case with the
+PowerPC.
+
address@hidden All the parameters are passed on the stack
+This case is by far the simplest and is the most common in CISC
+architectures, like the x86 and Motorola 68000.
address@hidden table
+
+In all cases, the port-specific header file will define two variable
+for private use---one to be used by the caller during the
address@hidden/@code{pusharg}/@code{finish} sequence, one to be used
+by the callee, specifically in the @code{jit_prolog} and @code{jit_arg}
+macros.
+
+Let's look again, this time with more detail, at each of the cases.
+
address@hidden @b
address@hidden Register windows
address@hidden is the same as @code{jit_calli}, and is defined
+in @file{core-common.h} (@pxref{Common features, , Common features
+supported by @file{core-common.h}}).
+
address@hidden
+#define jit_prepare(numargs) (_jitl.pusharg = _Ro(numargs))
+#define jit_pusharg_i(rs) (--_jitl.pusharg, \
+ MOVrr((rs), _jitl.pusharg))
address@hidden example
+
+Remember that arguments pushing takes place in reverse order, thus
+giving a pre-decrement (rather than post-increment) in
address@hidden
+
+Here is what happens on the callee's side:
+
address@hidden
+#define jit_arg_c() (_jitl.getarg++)
+#define jit_getarg_c(rd, ofs) jit_extr_c_i ((rd), (ofs))
+#define jit_prolog(numargs) (SAVErir(JIT_SP, -96, JIT_SP), \
+ _jitl.getarg = _Ri(0))
address@hidden example
+
+The @code{jit_arg} macros return nothing more than a register index,
+which is then used by the @code{jit_getarg} macros. @code{jit_prolog}
+resets the counter used by @code{jit_arg} to zero; the @code{numargs}
+parameter is not used. It is sufficient for @code{jit_leaf} to be a
+synonym for @code{jit_prolog}.
+
address@hidden Passing parameter via registers
+The code is almost the same as that for the register windows case, but
+with an additional address@hidden will transfer the
+argument from the input register to a non-argument register so that
+function calls will not clobber it. The prolog and epilog code can then
+become unbearably long, up to 20 instructions on the PPC; a common
+solution in this case is that of @dfn{trampolines}.
+
+The prolog does nothing more than put the function's actual address in a
+caller-preserved register and then call the trampoline:
address@hidden
+ mflr r0 @rem{! grab return address}
+ movei r10, trampo_2args @rem{! jump to trampoline}
+ mtlr r10
+ blrl
+here: mflr r31 @rem{! r31 = address of epilog}
+ @rem{...actual code...}
+ mtlr r31 @rem{! return to the trampoline}
+ blr
address@hidden example
+
+In this case, @code{jit_prolog} does use its argument containing the
+number of parameters to pick the appropriate trampoline. Here,
address@hidden is the address of a trampoline designed for
+2-argument functions.
+
+The trampoline executes the prolog code, jumps to the contents of
address@hidden, and upon return from the subroutine it executes the
+epilog code.
+
address@hidden All the parameters are passed on the stack
address@hidden uses a hardware push operation, which is commonly
+available on CISC machines (where this approach is most likely
+followed). Since the stack has to be cleaned up after the call,
address@hidden remembers how many parameters have been put there,
+and @code{jit_finish} adjusts the stack pointer after the call.
+
address@hidden
+#define jit_prepare(numargs) (_jitl.args += (numargs))
+#define jit_pusharg_i(rs) PUSHLr(rs)
+#define jit_finish(sub) (jit_calli((sub)), \
+ ADDLir(4 * _jitl.args, JIT_SP), \
+ _jitl.numargs = 0)
address@hidden example
+
+Note the usage of @code{+=} in @code{jit_prepare}. This is done
+so that one can defer the popping of the arguments that were saved
+on the stack (@dfn{stack pollution}). To do so, it is sufficient to
+use @code{jit_calli} instead of @code{jit_finish} in all but the
+last call.
+
+On the caller's side, @code{arg} returns an offset relative to the
+frame pointer, and @code{getarg} loads the argument from the stack:
+
address@hidden
+#define jit_getarg_c(rd, ofs) jit_ldxi_c((rd), _EBP, (ofs));
+#define jit_arg_c() ((_jitl.frame += sizeof(int) \
+ - sizeof(int))
address@hidden example
+
+The @code{_jitl.frame} variable is initialized by @code{jit_prolog}
+with the displacement between the value of the frame pointer
+(@code{%ebp}) and the address of the first parameter.
address@hidden table
+
+These schemes are the most used, so @file{core-common.h} provides a way
+to employ them automatically. If you do not define the
address@hidden macro and its companions, @file{core-common.h} will
+presume that you intend to pass parameters through either the registers
+or the stack.
+
+If you define @code{JIT_FP}, stack-based parameter passing will be
+employed and the @code{jit_getarg} macros will be defined like this:
+
address@hidden
+#define jit_getarg_c(reg, ofs) jit_ldxi_c((reg), JIT_FP, (ofs));
address@hidden example
+
+In other words, the @code{jit_arg} macros (which are still to be defined
+by the platform-specific back-end) shall return an offset into the stack
+frame. On the other hand, if you don't define @code{JIT_FP},
+register-based parameter passing will be employed and the @code{jit_arg}
+macros shall return a register number; in this case, @code{jit_getarg}
+will be implemented in terms of @code{jit_extr} and @code{jit_movr}
+operations:
+
address@hidden
+#define jit_getarg_c(reg, ofs) jit_extr_c_i ((reg), (ofs))
+#define jit_getarg_i(reg, ofs) jit_movr_i ((reg), (ofs))
address@hidden example
+
+
address@hidden Macro list
address@hidden Macros composing the platform-independent layer
+
address@hidden @b
address@hidden Register names (all mandatory but the last two)
address@hidden
+#define JIT_R0
+#define JIT_R1
+#define JIT_R2
+#define JIT_V0
+#define JIT_V1
+#define JIT_V2
+#define JIT_SP
+#define JIT_FP
+#define JIT_RZERO
address@hidden example
+
address@hidden Helper macros (non-mandatory):
address@hidden
+#define jit_fill_delay_after(branch)
address@hidden example
+
address@hidden Mandatory:
address@hidden
+#define jit_arg_c()
+#define jit_arg_i()
+#define jit_arg_l()
+#define jit_arg_p()
+#define jit_arg_s()
+#define jit_arg_uc()
+#define jit_arg_ui()
+#define jit_arg_ul()
+#define jit_arg_us()
+#define jit_addi_i(d, rs, is)
+#define jit_addr_i(d, s1, s2)
+#define jit_addxi_i(d, rs, is)
+#define jit_addxr_i(d, s1, s2)
+#define jit_andi_i(d, rs, is)
+#define jit_andr_i(d, s1, s2)
+#define jit_beqi_i(label, rs, is)
+#define jit_beqr_i(label, s1, s2)
+#define jit_bgei_i(label, rs, is)
+#define jit_bgei_ui(label, rs, is)
+#define jit_bger_i(label, s1, s2)
+#define jit_bger_ui(label, s1, s2)
+#define jit_bgti_i(label, rs, is)
+#define jit_bgti_ui(label, rs, is)
+#define jit_bgtr_i(label, s1, s2)
+#define jit_bgtr_ui(label, s1, s2)
+#define jit_blei_i(label, rs, is)
+#define jit_blei_ui(label, rs, is)
+#define jit_bler_i(label, s1, s2)
+#define jit_bler_ui(label, s1, s2)
+#define jit_blti_i(label, rs, is)
+#define jit_blti_ui(label, rs, is)
+#define jit_bltr_i(label, s1, s2)
+#define jit_bltr_ui(label, s1, s2)
+#define jit_boaddi_i(label, rs, is)
+#define jit_boaddi_ui(label, rs, is)
+#define jit_boaddr_i(label, s1, s2)
+#define jit_boaddr_ui(label, s1, s2)
+#define jit_bosubi_i(label, rs, is)
+#define jit_bosubi_ui(label, rs, is)
+#define jit_bosubr_i(label, s1, s2)
+#define jit_bosubr_ui(label, s1, s2)
+#define jit_bmci_i(label, rs, is)
+#define jit_bmcr_i(label, s1, s2)
+#define jit_bmsi_i(label, rs, is)
+#define jit_bmsr_i(label, s1, s2)
+#define jit_bnei_i(label, rs, is)
+#define jit_bner_i(label, s1, s2)
+#define jit_calli(label)
+#define jit_divi_i(d, rs, is)
+#define jit_divi_ui(d, rs, is)
+#define jit_divr_i(d, s1, s2)
+#define jit_divr_ui(d, s1, s2)
+#define jit_eqi_i(d, rs, is)
+#define jit_eqr_i(d, s1, s2)
+#define jit_gei_i(d, rs, is)
+#define jit_gei_ui(d, s1, s2)
+#define jit_ger_i(d, s1, s2)
+#define jit_ger_ui(d, s1, s2)
+#define jit_gti_i(d, rs, is)
+#define jit_gti_ui(d, s1, s2)
+#define jit_gtr_i(d, s1, s2)
+#define jit_gtr_ui(d, s1, s2)
+#define jit_hmuli_i(d, rs, is)
+#define jit_hmuli_ui(d, rs, is)
+#define jit_hmulr_i(d, s1, s2)
+#define jit_hmulr_ui(d, s1, s2)
+#define jit_jmpi(label)
+#define jit_jmpr(reg)
+#define jit_ldxi_c(d, rs, is)
+#define jit_ldxi_i(d, rs, is)
+#define jit_ldxi_s(d, rs, is)
+#define jit_ldxi_uc(d, rs, is)
+#define jit_ldxi_us(d, rs, is)
+#define jit_ldxr_c(d, s1, s2)
+#define jit_ldxr_i(d, s1, s2)
+#define jit_ldxr_s(d, s1, s2)
+#define jit_ldxr_uc(d, s1, s2)
+#define jit_ldxr_us(d, s1, s2)
+#define jit_lei_i(d, rs, is)
+#define jit_lei_ui(d, s1, s2)
+#define jit_ler_i(d, s1, s2)
+#define jit_ler_ui(d, s1, s2)
+#define jit_lshi_i(d, rs, is)
+#define jit_lshr_i(d, r1, r2)
+#define jit_lti_i(d, rs, is)
+#define jit_lti_ui(d, s1, s2)
+#define jit_ltr_i(d, s1, s2)
+#define jit_ltr_ui(d, s1, s2)
+#define jit_modi_i(d, rs, is)
+#define jit_modi_ui(d, rs, is)
+#define jit_modr_i(d, s1, s2)
+#define jit_modr_ui(d, s1, s2)
+#define jit_movi_i(d, is)
+#define jit_movr_i(d, rs)
+#define jit_muli_i(d, rs, is)
+#define jit_muli_ui(d, rs, is)
+#define jit_mulr_i(d, s1, s2)
+#define jit_mulr_ui(d, s1, s2)
+#define jit_nei_i(d, rs, is)
+#define jit_ner_i(d, s1, s2)
+#define jit_nop()
+#define jit_ori_i(d, rs, is)
+#define jit_orr_i(d, s1, s2)
+#define jit_patch(jump_pc)
+#define jit_pop_i(rs)
+#define jit_prepare(numargs)
+#define jit_push_i(rs)
+#define jit_pusharg_i(rs)
+#define jit_ret()
+#define jit_retval_i(rd)
+#define jit_rshi_i(d, rs, is)
+#define jit_rshi_ui(d, rs, is)
+#define jit_rshr_i(d, r1, r2)
+#define jit_rshr_ui(d, r1, r2)
+#define jit_stxi_c(rd, id, rs)
+#define jit_stxi_i(rd, id, rs)
+#define jit_stxi_s(rd, id, rs)
+#define jit_stxr_c(d1, d2, rs)
+#define jit_stxr_i(d1, d2, rs)
+#define jit_stxr_s(d1, d2, rs)
+#define jit_subr_i(d, s1, s2)
+#define jit_subxi_i(d, rs, is)
+#define jit_subxr_i(d, s1, s2)
+#define jit_xori_i(d, rs, is)
+#define jit_xorr_i(d, s1, s2)
address@hidden example
+
address@hidden Non mandatory---there should be no need to define them:
address@hidden
+#define jit_extr_c_ui(d, rs)
+#define jit_extr_i_ul(d, rs)
+#define jit_extr_s_ui(d, rs)
+#define jit_negr_i(d, rs)
+#define jit_negr_l(d, rs)
address@hidden example
+
address@hidden Non mandatory---whether to define them depends on the @sc{abi}:
address@hidden
+#define jit_prolog()
+#define jit_finish()
+#define jit_leaf()
+#define jit_getarg_c(reg, ofs)
+#define jit_getarg_i(reg, ofs)
+#define jit_getarg_l(reg, ofs)
+#define jit_getarg_p(reg, ofs)
+#define jit_getarg_s(reg, ofs)
+#define jit_getarg_uc(reg, ofs)
+#define jit_getarg_ui(reg, ofs)
+#define jit_getarg_ul(reg, ofs)
+#define jit_getarg_us(reg, ofs)
address@hidden example
+
address@hidden Non mandatory---define them if instructions that do this exist:
address@hidden
+#define jit_extr_c_i(d, rs)
+#define jit_extr_s_i(d, rs)
+#define jit_rsbi_i(d, rs, is)
+#define jit_rsbi_l(d, rs, is)
address@hidden example
+
address@hidden Non mandatory if condition code are always set by add/sub,
needed on other systems:
address@hidden
+#define jit_addci_i(d, rs, is)
+#define jit_addci_l(d, rs, is)
+#define jit_subci_i(d, rs, is)
+#define jit_subci_l(d, rs, is)
address@hidden example
+
address@hidden Mandatory on little endian systems---don't define them on other
systems:
address@hidden
+#define jit_ntoh_ui(d, rs)
+#define jit_ntoh_us(d, rs)
address@hidden example
+
address@hidden Mandatory if JIT_RZERO not defined---don't define them if it is
defined:
address@hidden
+#define jit_ldi_c(d, is)
+#define jit_ldi_i(d, is)
+#define jit_ldi_s(d, is)
+#define jit_ldr_c(d, rs)
+#define jit_ldr_i(d, rs)
+#define jit_ldr_s(d, rs)
+#define jit_ldi_uc(d, is)
+#define jit_ldi_ui(d, is)
+#define jit_ldi_ul(d, is)
+#define jit_ldi_us(d, is)
+#define jit_ldr_uc(d, rs)
+#define jit_ldr_ui(d, rs)
+#define jit_ldr_ul(d, rs)
+#define jit_ldr_us(d, rs)
+#define jit_sti_c(id, rs)
+#define jit_sti_i(id, rs)
+#define jit_sti_s(id, rs)
+#define jit_str_c(rd, rs)
+#define jit_str_i(rd, rs)
+#define jit_str_s(rd, rs)
address@hidden example
+
address@hidden Synonyms---don't define them:
address@hidden
+#define jit_addi_p(d, rs, is)
+#define jit_addi_ui(d, rs, is)
+#define jit_addi_ul(d, rs, is)
+#define jit_addr_p(d, s1, s2)
+#define jit_addr_ui(d, s1, s2)
+#define jit_addr_ul(d, s1, s2)
+#define jit_andi_ui(d, rs, is)
+#define jit_andi_ul(d, rs, is)
+#define jit_andr_ui(d, s1, s2)
+#define jit_andr_ul(d, s1, s2)
+#define jit_beqi_p(label, rs, is)
+#define jit_beqi_ui(label, rs, is)
+#define jit_beqi_ul(label, rs, is)
+#define jit_beqr_p(label, s1, s2)
+#define jit_beqr_ui(label, s1, s2)
+#define jit_beqr_ul(label, s1, s2)
+#define jit_bmci_ui(label, rs, is)
+#define jit_bmci_ul(label, rs, is)
+#define jit_bmcr_ui(label, s1, s2)
+#define jit_bmcr_ul(label, s1, s2)
+#define jit_bmsi_ui(label, rs, is)
+#define jit_bmsi_ul(label, rs, is)
+#define jit_bmsr_ui(label, s1, s2)
+#define jit_bmsr_ul(label, s1, s2)
+#define jit_bgei_p(label, rs, is)
+#define jit_bger_p(label, s1, s2)
+#define jit_bgti_p(label, rs, is)
+#define jit_bgtr_p(label, s1, s2)
+#define jit_blei_p(label, rs, is)
+#define jit_bler_p(label, s1, s2)
+#define jit_blti_p(label, rs, is)
+#define jit_bltr_p(label, s1, s2)
+#define jit_bnei_p(label, rs, is)
+#define jit_bnei_ui(label, rs, is)
+#define jit_bnei_ul(label, rs, is)
+#define jit_bner_p(label, s1, s2)
+#define jit_bner_ui(label, s1, s2)
+#define jit_bner_ul(label, s1, s2)
+#define jit_eqi_p(d, rs, is)
+#define jit_eqi_ui(d, rs, is)
+#define jit_eqi_ul(d, rs, is)
+#define jit_eqr_p(d, s1, s2)
+#define jit_eqr_ui(d, s1, s2)
+#define jit_eqr_ul(d, s1, s2)
+#define jit_extr_uc_i(d, rs)
+#define jit_extr_uc_ui(d, rs)
+#define jit_extr_ui_l(d, rs)
+#define jit_extr_ui_l(d, rs)
+#define jit_extr_ui_ul(d, rs)
+#define jit_extr_ui_ul(d, rs)
+#define jit_extr_us_i(d, rs)
+#define jit_extr_us_ui(d, rs)
+#define jit_gei_p(d, rs, is)
+#define jit_ger_p(d, s1, s2)
+#define jit_gti_p(d, rs, is)
+#define jit_gtr_p(d, s1, s2)
+#define jit_ldr_p(d, rs)
+#define jit_ldi_p(d, is)
+#define jit_ldxi_p(d, rs, is)
+#define jit_ldxr_p(d, s1, s2)
+#define jit_lei_p(d, rs, is)
+#define jit_ler_p(d, s1, s2)
+#define jit_lshi_ui(d, rs, is)
+#define jit_lshi_ul(d, rs, is)
+#define jit_lshr_ui(d, s1, s2)
+#define jit_lshr_ul(d, s1, s2)
+#define jit_lti_p(d, rs, is)
+#define jit_ltr_p(d, s1, s2)
+#define jit_movi_p(d, is)
+#define jit_movi_ui(d, rs)
+#define jit_movi_ul(d, rs)
+#define jit_movr_p(d, rs)
+#define jit_movr_ui(d, rs)
+#define jit_movr_ul(d, rs)
+#define jit_nei_p(d, rs, is)
+#define jit_nei_ui(d, rs, is)
+#define jit_nei_ul(d, rs, is)
+#define jit_ner_p(d, s1, s2)
+#define jit_ner_ui(d, s1, s2)
+#define jit_ner_ul(d, s1, s2)
+#define jit_hton_ui(d, rs)
+#define jit_hton_us(d, rs)
+#define jit_ori_ui(d, rs, is)
+#define jit_ori_ul(d, rs, is)
+#define jit_orr_ui(d, s1, s2)
+#define jit_orr_ul(d, s1, s2)
+#define jit_pop_ui(rs)
+#define jit_pop_ul(rs)
+#define jit_push_ui(rs)
+#define jit_push_ul(rs)
+#define jit_pusharg_c(rs)
+#define jit_pusharg_p(rs)
+#define jit_pusharg_s(rs)
+#define jit_pusharg_uc(rs)
+#define jit_pusharg_ui(rs)
+#define jit_pusharg_ul(rs)
+#define jit_pusharg_us(rs)
+#define jit_retval_c(rd)
+#define jit_retval_p(rd)
+#define jit_retval_s(rd)
+#define jit_retval_uc(rd)
+#define jit_retval_ui(rd)
+#define jit_retval_ul(rd)
+#define jit_retval_us(rd)
+#define jit_rsbi_ui(d, rs, is)
+#define jit_rsbi_ul(d, rs, is)
+#define jit_rsbr_ui(d, s1, s2)
+#define jit_rsbr_ul(d, s1, s2)
+#define jit_sti_p(d, is)
+#define jit_sti_uc(d, is)
+#define jit_sti_ui(d, is)
+#define jit_sti_ul(d, is)
+#define jit_sti_us(d, is)
+#define jit_str_p(d, rs)
+#define jit_str_uc(d, rs)
+#define jit_str_ui(d, rs)
+#define jit_str_ul(d, rs)
+#define jit_str_us(d, rs)
+#define jit_stxi_p(d, rs, is)
+#define jit_stxi_uc(d, rs, is)
+#define jit_stxi_ui(d, rs, is)
+#define jit_stxi_ul(d, rs, is)
+#define jit_stxi_us(d, rs, is)
+#define jit_stxr_p(d, s1, s2)
+#define jit_stxr_uc(d, s1, s2)
+#define jit_stxr_ui(d, s1, s2)
+#define jit_stxr_ul(d, s1, s2)
+#define jit_stxr_us(d, s1, s2)
+#define jit_subi_p(d, rs, is)
+#define jit_subi_ui(d, rs, is)
+#define jit_subi_ul(d, rs, is)
+#define jit_subr_p(d, s1, s2)
+#define jit_subr_ui(d, s1, s2)
+#define jit_subr_ul(d, s1, s2)
+#define jit_xori_ui(d, rs, is)
+#define jit_xori_ul(d, rs, is)
+#define jit_xorr_ui(d, s1, s2)
+#define jit_xorr_ul(d, s1, s2)
address@hidden example
+
address@hidden Shortcuts---don't define them:
address@hidden
+#define jit_notr_c(d, rs)
+#define jit_notr_i(d, rs)
+#define jit_notr_l(d, rs)
+#define jit_notr_s(d, rs)
+#define jit_notr_uc(d, rs)
+#define jit_notr_ui(d, rs)
+#define jit_notr_ul(d, rs)
+#define jit_notr_us(d, rs)
+#define jit_rsbr_i(d, s1, s2)
+#define jit_rsbr_l(d, s1, s2)
+#define jit_subi_i(d, rs, is)
+#define jit_subi_l(d, rs, is)
address@hidden example
+
address@hidden Mandatory if sizeof(long) != sizeof(int)---don't define them on
other systems:
address@hidden
+#define jit_addi_l(d, rs, is)
+#define jit_addr_l(d, s1, s2)
+#define jit_andi_l(d, rs, is)
+#define jit_andr_l(d, s1, s2)
+#define jit_beqi_l(label, rs, is)
+#define jit_beqr_l(label, s1, s2)
+#define jit_bgei_l(label, rs, is)
+#define jit_bgei_ul(label, rs, is)
+#define jit_bger_l(label, s1, s2)
+#define jit_bger_ul(label, s1, s2)
+#define jit_bgti_l(label, rs, is)
+#define jit_bgti_ul(label, rs, is)
+#define jit_bgtr_l(label, s1, s2)
+#define jit_bgtr_ul(label, s1, s2)
+#define jit_blei_l(label, rs, is)
+#define jit_blei_ul(label, rs, is)
+#define jit_bler_l(label, s1, s2)
+#define jit_bler_ul(label, s1, s2)
+#define jit_blti_l(label, rs, is)
+#define jit_blti_ul(label, rs, is)
+#define jit_bltr_l(label, s1, s2)
+#define jit_bltr_ul(label, s1, s2)
+#define jit_bosubi_l(label, rs, is)
+#define jit_bosubi_ul(label, rs, is)
+#define jit_bosubr_l(label, s1, s2)
+#define jit_bosubr_ul(label, s1, s2)
+#define jit_boaddi_l(label, rs, is)
+#define jit_boaddi_ul(label, rs, is)
+#define jit_boaddr_l(label, s1, s2)
+#define jit_boaddr_ul(label, s1, s2)
+#define jit_bmci_l(label, rs, is)
+#define jit_bmcr_l(label, s1, s2)
+#define jit_bmsi_l(label, rs, is)
+#define jit_bmsr_l(label, s1, s2)
+#define jit_bnei_l(label, rs, is)
+#define jit_bner_l(label, s1, s2)
+#define jit_divi_l(d, rs, is)
+#define jit_divi_ul(d, rs, is)
+#define jit_divr_l(d, s1, s2)
+#define jit_divr_ul(d, s1, s2)
+#define jit_eqi_l(d, rs, is)
+#define jit_eqr_l(d, s1, s2)
+#define jit_gei_l(d, rs, is)
+#define jit_gei_ul(d, rs, is)
+#define jit_ger_l(d, s1, s2)
+#define jit_ger_ul(d, s1, s2)
+#define jit_gti_l(d, rs, is)
+#define jit_gti_ul(d, rs, is)
+#define jit_gtr_l(d, s1, s2)
+#define jit_gtr_ul(d, s1, s2)
+#define jit_hmuli_l(d, rs, is)
+#define jit_hmuli_ul(d, rs, is)
+#define jit_hmulr_l(d, s1, s2)
+#define jit_hmulr_ul(d, s1, s2)
+#define jit_ldi_l(d, is)
+#define jit_ldi_ui(d, is)
+#define jit_ldr_l(d, rs)
+#define jit_ldr_ui(d, rs)
+#define jit_ldxi_l(d, rs, is)
+#define jit_ldxi_ui(d, rs, is)
+#define jit_ldxi_ul(d, rs, is)
+#define jit_ldxr_l(d, s1, s2)
+#define jit_ldxr_ui(d, s1, s2)
+#define jit_ldxr_ul(d, s1, s2)
+#define jit_lei_l(d, rs, is)
+#define jit_lei_ul(d, rs, is)
+#define jit_ler_l(d, s1, s2)
+#define jit_ler_ul(d, s1, s2)
+#define jit_lshi_l(d, rs, is)
+#define jit_lshr_l(d, s1, s2)
+#define jit_lti_l(d, rs, is)
+#define jit_lti_ul(d, rs, is)
+#define jit_ltr_l(d, s1, s2)
+#define jit_ltr_ul(d, s1, s2)
+#define jit_modi_l(d, rs, is)
+#define jit_modi_ul(d, rs, is)
+#define jit_modr_l(d, s1, s2)
+#define jit_modr_ul(d, s1, s2)
+#define jit_movi_l(d, rs)
+#define jit_movr_l(d, rs)
+#define jit_muli_l(d, rs, is)
+#define jit_muli_ul(d, rs, is)
+#define jit_mulr_l(d, s1, s2)
+#define jit_mulr_ul(d, s1, s2)
+#define jit_nei_l(d, rs, is)
+#define jit_ner_l(d, s1, s2)
+#define jit_ori_l(d, rs, is)
+#define jit_orr_l(d, s1, s2)
+#define jit_pop_l(rs)
+#define jit_push_l(rs)
+#define jit_pusharg_l(rs)
+#define jit_retval_l(rd)
+#define jit_rshi_l(d, rs, is)
+#define jit_rshi_ul(d, rs, is)
+#define jit_rshr_l(d, s1, s2)
+#define jit_rshr_ul(d, s1, s2)
+#define jit_sti_l(d, is)
+#define jit_str_l(d, rs)
+#define jit_stxi_l(d, rs, is)
+#define jit_stxr_l(d, s1, s2)
+#define jit_subr_l(d, s1, s2)
+#define jit_xori_l(d, rs, is)
+#define jit_xorr_l(d, s1, s2)
address@hidden example
address@hidden table
+
address@hidden Standard functions
address@hidden More complex tasks in the platform-independent layer
+
+There is actually a single function that you @strong{must} define
+in the @address@hidden file, that is, @code{jit_flush_code}.
+
+As explained in @usingref{GNU lightning macros, Generating code at
+run-time}, its purpose is to flush part of the processor's
+instruction cache (usually the part of memory that contains the
+generated code), avoiding the processor executing bogus data
+that it happens to find in the cache. The @code{jit_flush_code}
+function takes the first and the last address to flush.
+
+On many processors (for example, the x86 and the all the processors
+in the 68k family up to the 68030), it is not even necessary to flush
+the cache. In this case, the contents of the file will simply be
+
address@hidden
+#ifndef __lightning_funcs_h
+#define __lightning_funcs_h
+
+#define jit_flush_code(dest, end)
+
+#endif @rem{/* __lightning_core_h */}
address@hidden example
+
+On other processors, flushing the cache is necessary for
+proper behavior of the program; in this case, the file will contain
+a proper definition of the function. However, we must make yet
+another distinction.
+
+On some processors, flushing the cache is obtained through a call
+to the operating system or to the C run-time library. In this case,
+the definition of @code{jit_flush_code} will be very simple: two
+examples are the Alpha and the 68040. For the Alpha the code will
+be:
address@hidden
+#define jit_flush_code(dest, end) \
+ __asm__ __volatile__("call_pal 0x86");
address@hidden example
+
address@hidden
+and, for the Motorola
address@hidden
+#define jit_flush_code(start, end) \
+ __clear_cache((start), (end))
address@hidden example
+
+As you can see, the Alpha does not even need to pass the start and
+end address to the function. It is good practice to protect usage of
+the @acronym{GNU CC}-specific @code{__asm__} directive by relying
+on the preprocessor. For example:
+
address@hidden
+#if !defined(__GNUC__) && !defined(__GNUG__)
+#error Go get GNU C, I do not know how to flush the cache
+#error with this compiler.
+#else
+#define jit_flush_code(dest, end) \
+ __asm__ __volatile__("call_pal 0x86");
+#endif
address@hidden example
+
address@hidden's configuration process tries to compile a dummy file that
+includes @code{lightning.h}, and gives a warning if there are problem
+with the compiler that is installed on the system.
+
+In more complex cases, you'll need to write a full-fledged function.
+Don't forget to make it @code{static}, otherwise you'll have problems
+linking programs that include @code{lightning.h} multiple times. An
+example, taken from the @file{funcs-ppc.h} file, is:
+
address@hidden
+#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(start, end)
+ void *start;
+ void *end;
address@hidden
+ register char *dest = start;
+
+ for (; dest <= end; dest += SIZEOF_CHAR_P)
+ __asm__ __volatile__
+ ("dcbst 0,%0; sync; icbi 0,%0; isync"::"r"(dest));
address@hidden
+#endif
+
+#endif /* __lightning_funcs_h */
address@hidden example
+
+The @address@hidden file is also the right place to put
+helper functions that do complex tasks for the
address@hidden@var{suffix}.h} file. For example, the PowerPC assembler
+defines @code{jit_prolog} as a function and puts it in that file (for more
+information, @pxref{Implementing the ABI}). Take special care when
+defining such a function, as explained in @usingref{Reentrancy,
+Reentrant usage of @lightning{}}.
+
+
address@hidden Floating-point macros
address@hidden Implementing macros for floating point
+
diff --git a/doc/toc.texi b/doc/toc.texi
new file mode 100644
index 0000000..8a37022
--- /dev/null
+++ b/doc/toc.texi
@@ -0,0 +1,77 @@
address@hidden These macros are used because these items could go both in the
address@hidden short listing (for partial books) and in the detailed listing
address@hidden (for full books - i.e. using & porting)
+
address@hidden usingmenu{}
address@hidden 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
address@hidden ifset
address@hidden macro
+
address@hidden portingmenu{}
address@hidden 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.
address@hidden ifset
address@hidden macro
+
address@hidden standardmacrosmenu{}
address@hidden 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
address@hidden macro
+
address@hidden
address@hidden BOTH
+* Overview:: What GNU lightning is
address@hidden
address@hidden
+* Future:: Tasks for GNU lightning's subsequent releases
+* Acknowledgements:: Acknowledgements for GNU lightning
+
address@hidden PORTING
address@hidden
+--- The detailed node listing ---
+
+Standard macros:
address@hidden
address@hidden detailmenu
address@hidden ifset
address@hidden ifclear
+
address@hidden 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
+
address@hidden
+--- The detailed node listing ---
+
+Using @lightning{}:
address@hidden
+
+Porting @lightning{}:
address@hidden
+
+Standard macros:
address@hidden
address@hidden detailmenu
+
address@hidden ifset
+
address@hidden menu
diff --git a/doc/using.texi b/doc/using.texi
new file mode 100644
index 0000000..a65a048
--- /dev/null
+++ b/doc/using.texi
@@ -0,0 +1,1086 @@
address@hidden Installation
address@hidden Configuring and installing @lightning{}
+
+The first thing to do to use @lightning{} is to configure the
+program, picking the set of macros to be used on the host
+architecture; this configuration is automatically performed by
+the @file{configure} shell script; to run it, merely type:
address@hidden
+ ./configure
address@hidden example
+
address@hidden supports cross-compiling in that you can choose a
+different set of macros from the one needed on the computer that
+you are compiling @lightning{} on. For example,
address@hidden
+ ./configure --host=sparc-sun-linux
address@hidden example
+
address@hidden will select the SPARC set of runtime assemblers. You can use
+configure's ability to make reasonable assumptions about the vendor
+and operating system and simply type
address@hidden
+ ./configure --host=i386
+ ./configure --host=ppc
+ ./configure --host=sparc
address@hidden example
+
+Another option that @file{configure} accepts is
address@hidden, which enables several consistency checks in
+the run-time assemblers. These are not usually needed, so you can
+decide to simply forget about it; also remember that these consistency
+checks tend to slow down your code generator.
+
+After you've configured @lightning{}, you don't have to compile it
+because it is nothing more than a set of include files. If you want to
+compile the examples, run @file{make} as usual. The next important
+step is:
address@hidden
+ make install
address@hidden example
+
+This ends the process of installing @lightning{}.
+
address@hidden The instruction set
address@hidden @lightning{}'s instruction set
+
address@hidden's instruction set was designed by deriving instructions
+that closely match those of most existing RISC architectures, or
+that can be easily syntesized if absent. Each instruction is composed
+of:
address@hidden @bullet
address@hidden an operation (like @code{sub} or @code{mul})
address@hidden sometimes, an register/immediate flag (@code{r} or @code{i})
address@hidden a type identifier (occasionally, two)
address@hidden itemize
+
+The second and third field are separated by an underscore; thus,
+examples of legal mnemonics are @code{addr_i} (integer add, with three
+register operands) and @code{muli_l} (long integer multiply, with two
+register operands and an immediate operand). Each instruction takes
+two or three operands; in most cases, one of them can be an immediate
+value instead of a register.
+
address@hidden supports a full range of integer types: operands can be 1,
+2 or 4 bytes long (64-bit architectures might support 8 bytes long
+operands), either signed or unsigned. The types are listed in the
+following table together with the C types they represent:
+
address@hidden
+ c @r{signed char}
+ uc @r{unsigned char}
+ s @r{short}
+ us @r{unsigned short}
+ i @r{int}
+ ui @r{unsigned int}
+ l @r{long}
+ ul @r{unsigned long}
+ p @r{void *}
address@hidden example
+
+Some of these types may not be distinct: for example, (e.g., @code{l}
+is equivalent to @code{i} on 32-bit machines, and @code{p} is
+substantially equivalent to @code{ul}).
+
+There are seven registers, of which six are general-purpose, while
+the last is used to contain the stack pointer (@code{SP}). The
+stack pointer can be used to allocate and access local variables
+on the stack (which is supposed to grow downwards in memory on all
+architectures).
+
+Of the six general-purpose registers, three are guaranteed to be
+preserved across function calls (@code{V0}, @code{V1} and
address@hidden) and three are not (@code{R0}, @code{R1} and
address@hidden)address@hidden registers are not very much, but this
+restriction was forced by the need to target CISC architectures
+which, like the x86, are poor of registers. Anyway, consider
+that even on a RISC architecture you don't have many more registers
+which are not devoted to function calls: on the SPARC, you have nine
+(@code{%g1} and the eight registers @code{%l0} through @code{%l7}).}
+
+In addition, there is a special @code{RET} register which contains
+the return value. You should always remember, however, that writing
+this register could overwrite either a general-purpose register or
+an incoming parameter, depending on the architecture.
+
+The complete instruction set follows; as you can see, most non-memory
+operations only take integers, long integers (either signed or
+unsigned) and pointers as operands; this was done in order to reduce
+the instruction set, and because most architectures only provide word
+and long word operations on registers. There are instructions that
+allow operands to be extended to fit a larger data type, both in a
+signed and in an unsigned way.
+
address@hidden @b
address@hidden Binary ALU operations
+These accept three operands, of which the last can be an immediate
+value. @code{addx} operations must directly follow @code{addc}, and
address@hidden must follow @code{subc}; otherwise, results are undefined.
address@hidden
+addr/addi i ui l ul p O1 = O2 + O3
+addxr/addxi i ui l ul O1 = O2 + (O3 + carry)
+addcr/addci i ui l ul O1 = O2 + O3, set carry
+subr/subi i ui l ul p O1 = O2 - O3
+subxr/subxi i ui l ul O1 = O2 - (O3 + carry)
+subcr/subci i ui l ul O1 = O2 - O3, set carry
+rsbr/rsbi i ui l ul p O1 = O3 - O2
+mulr/muli i ui l ul O1 = O2 * O3
+hmulr/hmuli i ui l ul O1 = @r{high bits of} O2 * O3
+divr/divi i ui l ul O1 = O2 / O3
+modr/modi i ui l ul O1 = O2 % O3
+andr/andi i ui l ul O1 = O2 & O3
+orr/ori i ui l ul O1 = O2 | O3
+xorr/xori i ui l ul O1 = O2 ^ O3
+lshr/lshi i ui l ul O1 = O2 << O3
+rshr/rshi i ui l ul O1 = O2 >> address@hidden sign bit is propagated
for signed types.}
address@hidden example
+
address@hidden Unary ALU operations
+These accept two operands, both of which must be registers.
address@hidden
+negr i l O1 = -O2
+notr i ui l ul O1 = ~O2
address@hidden example
+
address@hidden Compare instructions
+These accept three operands, of which the last can be an immediate
+value. The last two operands are compared, and the first operand is
+set to either 0 or 1, according to whether the given condition was
+met or not.
+
address@hidden
+ltr/lti i ui l ul p O1 = (O2 < O3)
+ler/lei i ui l ul p O1 = (O2 <= O3)
+gtr/gti i ui l ul p O1 = (O2 > O3)
+ger/gei i ui l ul p O1 = (O2 >= O3)
+eqr/eqi i ui l ul p O1 = (O2 == O3)
+ner/nei i ui l ul p O1 = (O2 != O3)
address@hidden example
+
address@hidden Transfer operations
+These accept two operands; for @code{ext} both of them must be
+registers, while @code{mov} accepts an immediate value as the second
+operand. @code{ext} needs @strong{two} data type specifications, of
+which the first must be smaller in size than the second; for example
address@hidden is correct while @code{extr_ul_us} is not.
address@hidden
+movr/movi i ui l ul p O1 = O2
+extr c uc s us i ui l ul O1 = address@hidden @code{movr} and
@code{movi}, @code{extr} is applied between operands of different sizes.}
address@hidden example
+
address@hidden Network extensions
+These accept two operands, both of which must be registers; these
+two instructions actually perform the same task, yet they are
+assigned to two mnemonics for the sake of convenience and
+completeness. As usual, the first operand is the destination and
+the second is the source.
address@hidden
+hton us ui @r{Host-to-network (big endian) order}
+ntoh us ui @r{Network-to-host order }
address@hidden example
+
address@hidden Load operations
address@hidden accepts two operands while @code{ldx} accepts three;
+in both cases, the last can be either a register or an immediate
+value. Values are extended (with or without sign, according to
+the data type specification) to fit a whole register.
address@hidden
+ldr/ldi c uc s us i ui l ul p O1 = *O2
+ldxr/ldxi c uc s us i ui l ul p O1 = *(O2+O3)
address@hidden example
+
address@hidden Store operations
address@hidden accepts two operands while @code{stx} accepts three; in
+both cases, the first can be either a register or an immediate
+value. Values are sign-extended to fit a whole register.
address@hidden
+str/sti c uc s us i ui l ul p *O1 = O2
+stxr/stxi c uc s us i ui l ul p *(O1+O2) = O3
address@hidden example
+
address@hidden Stack management
+These accept a single register parameter. These operations are not
+guaranteed to be efficient on all architectures.
+
address@hidden
+pushr i ui l ul p @r{push address@hidden on the stack}
+popr i ui l ul p @r{pop address@hidden off the stack}
address@hidden example
+
address@hidden Argument management
+These are:
address@hidden
+prepare (not specified)
+pusharg c uc s us i ui l ul p
+getarg c uc s us i ui l ul p
+arg c uc s us i ui l ul p
address@hidden example
+
+Of these, the first two are used by the caller, while the last two
+are used by the callee. A code snippet that wants to call another
+procedure and has to pass registers must, in order: use the
address@hidden instruction, giving the number of arguments to
+be passed to the procedure; use @code{pusharg} to push the arguments
address@hidden reverse order}; and use @code{calli} or @code{finish}
+(explained below) to perform the actual call.
+
address@hidden and @code{getarg} are used by the callee.
address@hidden is different from other instruction in that it does not
+actually generate any code: instead, it is a function which returns
+a value to be passed to @address@hidden a
+value'' means that @lightning{} macros that compile these
+instructions return a value when expanded.} You should call
address@hidden as soon as possible, before any function call or, more
+easily, right after the @code{prolog} or @code{leaf} instructions
+(which are treated later).
+
address@hidden accepts a register argument and a value returned by
address@hidden, and will move that argument to the register, extending
+it (with or without sign, according to the data type specification)
+to fit a whole register. These instructions are more intimately
+related to the usage of the @lightning{} instruction set in code
+that generates other code, so they will be treated more
+specifically in @ref{GNU lightning macros, , Generating code at
+run-time}.
+
+You should observe a few rules when using these macros. First of
+all, it is not allowed to call functions with more than six arguments;
+this was done to simplify and speed up the implementation on
+architectures that use registers for parameter passing.
+
+You should not nest calls to @code{prepare}, nor call zero-argument
+functions (which do not need a call to @code{prepare}) inside a
address@hidden/calli} or @code{prepare/finish} block. Doing this
+might corrupt already pushed arguments.
+
+You @strong{cannot} pass parameters between subroutines using
+the six general-purpose registers. This might work only when
+targeting particular architectures.
+
+On the other hand, it is possible to assume that callee-saved registers
+(@code{R0} through @code{R2}) are not clobbered by another dynamically
+generated function which does not use them as operands in its code and
+which does not return a value.
+
address@hidden Branch instructions
+Like @code{arg}, these also return a value which, in this case,
+is to be used to compile forward branches as explained in
address@hidden, , Fibonacci numbers}. They accept a pointer to the
+destination of the branch and two operands to be compared; of these,
+the last can be either a register or an immediate. They are:
address@hidden
+bltr/blti i ui l ul p @r{if }O2 < address@hidden goto }O1
+bler/blei i ui l ul p @r{if }O2 <= address@hidden goto }O1
+bgtr/bgti i ui l ul p @r{if }O2 > address@hidden goto }O1
+bger/bgei i ui l ul p @r{if }O2 >= address@hidden goto }O1
+beqr/beqi i ui l ul p @r{if }O2 == address@hidden goto }O1
+bner/bnei i ui l ul p @r{if }O2 != address@hidden goto }O1
+
+bmsr/bmsi i ui l ul @r{if }O2 & address@hidden goto }O1
+bmcr/bmci i ui l ul @r{if }!(O2 & O3)@r{ goto address@hidden two
mnemonics mean, respectively, @dfn{branch if mask set} and @dfn{branch if mask
cleared}.}
+
+boaddr/boaddi i ui l ul O2 += address@hidden, goto address@hidden on
overflow}
+bosubr/bosubi i ui l ul O2 -= address@hidden, goto address@hidden on
overflow}
address@hidden example
+
address@hidden Jump and return operations
+These accept one argument except @code{ret} which has none; the
+difference between @code{finish} and @code{calli} is that the
+latter does not clean the stack from pushed parameters (if any)
+and the former must @strong{always} follow a @code{prepare}
+instruction. Results are undefined when using function calls
+in a leaf function.
address@hidden
+calli (not specified) @r{function call to O1}
+finish (not specified) @r{function call to O1}
+jmpi/jmpr (not specified) @r{unconditional jump to O1}
+prolog (not specified) @r{function prolog for O1 args}
+leaf (not specified) @r{the same for leaf functions}
+ret (not specified) @r{return from subroutine}
+retval c uc s us i ui l ul p @r{move return value}
+ @r{to register}
address@hidden example
+
+Like branch instruction, @code{jmpi} also returns a value which is to
+be used to compile forward branches. @xref{Fibonacci, , Fibonacci
+numbers}.
+
address@hidden table
+
+As a small appetizer, here is a small function that adds 1 to the input
+parameter (an @code{int}). I'm using an assembly-like syntax here which
+is a bit different from the one used when writing real subroutines with
address@hidden; the real syntax will be introduced in @xref{GNU lightning
+macros, , Generating code at run-time}.
+
address@hidden
+incr:
+ leaf 1
+in = arg_i @rem{! We have an integer argument}
+ getarg_i R0, in @rem{! Move it to R0}
+ addi_i RET, R0, 1 @rem{! Add 1\, put result in return value}
+ ret @rem{! And return the result}
address@hidden example
+
+And here is another function which uses the @code{printf} function from
+the standard C library to write a number in hexadecimal notation:
+
address@hidden
+printhex:
+ prolog 1
+in = arg_i @rem{! Same as above}
+ getarg_i R0, in
+ prepare 2 @rem{! Begin call sequence for printf}
+ pusharg_i R0 @rem{! Push second argument}
+ pusharg_p "%x" @rem{! Push format string}
+ finish printf @rem{! Call printf}
+ ret @rem{! Return to caller}
address@hidden example
+
address@hidden GNU lightning macros
address@hidden Generating code at run-time
+
+To use @lightning{}, you should include the @file{lightning.h} file that
+is put in your include directory by the @samp{make install} command.
+That include files defines about four hundred public macros (plus
+others that are private to @lightning{}), one for each opcode listed
+above.
+
+Each of the instructions above translates to a macro. All you have to
+do is prepend @code{jit_} (lowercase) to opcode names and @code{JIT_}
+(uppercase) to register names. Of course, parameters are to be put
+between parentheses, just like with every other @sc{cpp} macro.
+
+This small tutorial presents three examples:
+
address@hidden ISTEX
address@hidden @bullet
address@hidden
+The @code{incr} function found in @ref{The instruction set, ,
address@hidden's instruction set}:
+
address@hidden
+A simple function call to @code{printf}
+
address@hidden
+An RPN calculator.
+
address@hidden
+Fibonacci numbers
address@hidden itemize
address@hidden ifset
address@hidden ISTEX
address@hidden
+* incr:: A function which increments a number by one
+* printf:: A simple function call to printf
+* RPN calculator:: A more complex example, an RPN calculator
+* Fibonacci:: Calculating Fibonacci numbers
address@hidden menu
address@hidden ifclear
+
address@hidden incr
address@hidden A function which increments a number by one
+
+Let's see how to create and use the sample @code{incr} function created
+in @ref{The instruction set, , @lightning{}'s instruction set}:
+
address@hidden
+#include <stdio.h>
+#include "lightning.h"
+
+static jit_insn codeBuffer[1024];
+
+typedef int (*pifi)(int); @rem{/* Pointer to Int Function of Int */}
+
+int main()
address@hidden
+ pifi incr = (pifi) (jit_set_ip(codeBuffer).iptr);
+ int in;
+
+ jit_leaf(1); @rem{/* @t{ leaf 1 } */}
+ in = jit_arg_i(); @rem{/* @t{in = arg_i } */}
+ jit_getarg_i(JIT_R0, in); @rem{/* @t{ getarg_i R0 } */}
+ jit_addi_i(JIT_RET, JIT_R0, 1); @rem{/* @t{ addi_i RET\, R0\, 1} */}
+ jit_ret(); @rem{/* @t{ ret } */}
+
+ jit_flush_code(codeBuffer, jit_get_ip().ptr);
+
+ @rem{/* call the generated code\, passing 5 as an argument */}
+ printf("%d + 1 = %d\n", 5, incr(5));
+ return 0;
address@hidden
address@hidden example
+
+Let's examine the code line by line (well, address@hidden):
+
address@hidden @t
address@hidden #include "lightning.h"
+You already know about this. It defines all of @lightning{}'s macros.
+
address@hidden static jit_insn codeBuffer[1024];
+You might wonder about what is @code{jit_insn}. It is just a type that
+is defined by @lightning{}. Its exact definition depends on the
+architecture; in general, defining an array of 1024 @code{jit_insn}s
+allows one to write 100 to 400 @lightning{} instructions (depending on
+the architecture and exact instructions).
+
address@hidden typedef int (*pifi)(int);
+Just a handy typedef for a pointer to a function that takes an
address@hidden and returns another.
+
address@hidden pifi incr = (pifi) (jit_set_ip(codeBuffer).iptr);
+This is the first @lightning{} macro we encounter that does not map to
+an instruction. It is @code{jit_set_ip}, which takes a pointer to an
+area of memory where compiled code will be put and returns the same
+value, cast to a @code{union} type whose members are pointers to
+functions returning different C types. This union is called
address@hidden and is defined as follows:
+
address@hidden
+ typedef union jit_code @{
+ char *ptr;
+ void (*vptr)();
+ char (*cptr)();
+ unsigned char (*ucptr)();
+ short (*sptr)();
+ unsigned short (*usptr)();
+ int (*iptr)();
+ unsigned int (*uiptr)();
+ long (*lptr)();
+ unsigned long (*ulptr)();
+ void * (*pptr)();
+ float (*fptr)();
+ double (*dptr)();
+ @} jit_code;
address@hidden example
+
+Any of the members could have been used, since the result is soon casted
+to type @code{pifi} but, for the sake of clarity, the program uses
address@hidden, a pointer to a function with no prototype and returning an
address@hidden
+
+Analogous to @code{jit_set_ip} is @code{jit_get_ip}, which does not
+modify the instruction pointer---it is nothing more than a cast of the
+current @sc{ip} to @code{jit_code}.
+
address@hidden int in;
+A footnote in @ref{The instruction set, , @lightning{}'s instruction
+set}, under the description of @code{arg}, says that macros implementing
address@hidden return a value---we'll be using this variable to store the
+result of @code{arg}.
+
address@hidden jit_leaf(1);
+Ok, so we start generating code for our beloved address@hidden it will
+accept one argument and won't call any other function.
+
address@hidden in = jit_arg_i();
address@hidden jit_getarg_i(JIT_R0, in);
+We retrieve the first (and only) argument, an integer, and store it
+into the general-purpose register @code{R0}.
+
address@hidden jit_addi_i(JIT_RET, JIT_R0, 1);
+We add one to the content of the register and store the result in the
+return value.
+
address@hidden jit_ret();
+This instruction generates a standard function epilog that returns
+the contents of the @code{RET} register.
+
address@hidden jit_flush_code(codeBuffer, jit_get_ip().ptr);
+This instruction is very important. It flushes the generated code
+area out of the processor's instruction cache, avoiding the processor
+executes bogus data that it happens to find there. The
address@hidden function accepts the first and the last address
+to flush; we use @code{jit_get_ip} to find out the latter.
+
address@hidden printf("%d + 1 = %d", 5, incr(5));
+Calling our function is this simple---it is not distinguishable from
+a normal C function call, the only difference being that @code{incr}
+is a variable.
address@hidden table
+
address@hidden abstracts two phases of dynamic code generation: selecting
+instructions that map the standard representation, and emitting binary
+code for these instructions. The client program has the responsibility
+of describing the code to be generated using the standard @lightning{}
+instruction set.
+
+Let's examine the code generated for @code{incr} on the SPARC and x86
+architectures (on the right is the code that an assembly-language
+programmer would write):
+
address@hidden @b
address@hidden SPARC
address@hidden
+ save %sp, -96, %sp
+ mov %i0, %l0 retl
+ add %l0, 1, %i0 add %o0, 1, %o0
+ ret
+ restore
address@hidden example
+In this case, @lightning{} introduces overhead to create a register
+window (not knowing that the procedure is a leaf procedure) and to
+move the argument to the general purpose register @code{R0} (which
+maps to @code{%l0} on the SPARC). The former overhead could be
+avoided by teaching @lightning{} about leaf procedures (@pxref{Future});
+the latter could instead be avoided by rewriting the getarg instruction
+as @code{jit_getarg_i(JIT_RET, in)}, which was not done in this
+example.
+
address@hidden x86
address@hidden
+ pushl %ebp
+ movl %esp, %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ movl 8(%ebp), %eax movl 4(%esp), %eax
+ addl $1, %eax incl %eax
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret ret
address@hidden example
+In this case, the main overhead is due to the function's prolog and
+epilog, which is nine instructions long on the x86; a hand-written
+routine would not save unused callee-preserved registers on the stack.
+It is to be said, however, that this is not a problem in more
+complicated uses, because more complex procedure would probably use
+the @code{V0} through @code{V2} registers (@code{%ebx}, @code{%esi},
address@hidden); in this case, a hand-written routine would have included
+the prolog too. Also, a ten byte prolog would probably be a small
+overhead in a more complex function.
address@hidden table
+
+In such a simple case, the macros that make up the back-end compile
+reasonably efficient code, with the notable exception of prolog/epilog
+code.
+
address@hidden printf
address@hidden A simple function call to @code{printf}
+
+Again, here is the code for the example:
+
address@hidden
+#include <stdio.h>
+#include "lightning.h"
+
+static jit_insn codeBuffer[1024];
+
+typedef void (*pvfi)(int); @rem{/* Pointer to Void Function of Int */}
+
+int main()
address@hidden
+ pvfi myFunction; @rem{/* ptr to generated code */}
+ char *start, *end; @rem{/* a couple of labels */}
+ int in; @rem{/* to get the argument */}
+
+ myFunction = (pvfi) (jit_set_ip(codeBuffer).vptr);
+ start = jit_get_ip().ptr;
+ jit_prolog(1);
+ in = jit_arg_i();
+ jit_movi_p(JIT_R0, "generated %d bytes\n");
+ jit_getarg_i(JIT_R1, in);
+ jit_prepare(2);
+ jit_pusharg_i(JIT_R1); @rem{/* push in reverse order */}
+ jit_pusharg_p(JIT_R0);
+ jit_finish(printf);
+ jit_ret();
+ end = jit_get_ip().ptr;
+
+ @rem{/* call the generated code\, passing its size as argument */}
+ jit_flush_code(start, end);
+ myFunction(end - start);
address@hidden
address@hidden example
+
+The function shows how many bytes were generated. Most of the code
+is not very interesting, as it resembles very closely the program
+presented in @ref{incr, , A function which increments a number by one}.
+
+For this reason, we're going to concentrate on just a few statements.
+
address@hidden @t
address@hidden start = jit_get_ip().ptr;
address@hidden @address@hidden
address@hidden end = jit_get_ip().ptr;
+These two instruction call the @code{jit_get_ip} macro which was
+mentioned in @ref{incr, , A function which increments a number by one}
+too. In this case we use the only field of @code{jit_code} that is
+not a function pointer: @code{ptr}, which is a simple @code{char *}.
+
address@hidden jit_movi_p(JIT_R0, "generated %d bytes\n");
+Note the use of the @samp{p} type specifier, which automatically
+casts the second parameter to an @code{unsigned long} to make the
+code more clear and less cluttered by typecasts.
+
address@hidden jit_prepare(2);
address@hidden jit_pusharg_i(JIT_R1);
address@hidden jit_pusharg_p(JIT_R0);
address@hidden jit_finish(printf);
+Once the arguments to @code{printf} have been put in general-purpose
+registers, we can start a prepare/pusharg/finish sequence that
+moves the argument to either the stack or registers, then calls
address@hidden, then cleans up the stack. Note how @lightning{}
+abstracts the differences between different architectures and
+ABI's -- the client program does not know how parameter passing
+works on the host architecture.
address@hidden table
+
address@hidden RPN calculator
address@hidden A more complex example, an RPN calculator
+
+We create a small stack-based RPN calculator which applies a series
+of operators to a given parameter and to other numeric operands.
+Unlike previous examples, the code generator is fully parameterized
+and is able to compile different formulas to different functions.
+Here is the code for the expression compiler; a sample usage will
+follow.
+
address@hidden
+#include <stdio.h>
+#include "lightning.h"
+
+typedef int (*pifi)(int); @rem{/* Pointer to Int Function of Int */}
+
+pifi compile_rpn(char *expr)
address@hidden
+ pifi fn;
+ int in;
+ fn = (pifi) (jit_get_ip().iptr);
+ jit_leaf(1);
+ in = jit_arg_i();
+ jit_getarg_i(JIT_R0, in);
+
+ while (*expr) @{
+ char buf[32];
+ int n;
+ if (sscanf(expr, "%[0-9]%n", buf, &n)) @{
+ expr += n - 1;
+ jit_push_i(JIT_R0);
+ jit_movi_i(JIT_R0, atoi(buf));
+ @} else if (*expr == '+') @{
+ jit_pop_i(JIT_R1);
+ jit_addr_i(JIT_R0, JIT_R1, JIT_R0);
+ @} else if (*expr == '-') @{
+ jit_pop_i(JIT_R1);
+ jit_subr_i(JIT_R0, JIT_R1, JIT_R0);
+ @} else if (*expr == '*') @{
+ jit_pop_i(JIT_R1);
+ jit_mulr_i(JIT_R0, JIT_R1, JIT_R0);
+ @} else if (*expr == '/') @{
+ jit_pop_i(JIT_R1);
+ jit_divr_i(JIT_R0, JIT_R1, JIT_R0);
+ @} else @{
+ fprintf(stderr, "cannot compile: %s\n", expr);
+ abort();
+ @}
+ ++expr;
+ @}
+ jit_movr_i(JIT_RET, JIT_R0);
+ jit_ret();
+ return fn;
address@hidden
address@hidden example
+
+The principle on which the calculator is based is easy: the stack
+top is held in R0, while the remaining items of the stack are held
+on the hardware stack. Compiling an operand pushes the old stack
+top onto the stack and moves the operand into R0; compiling an
+operator pops the second operand off the stack into R1, and
+compiles the operation so that the result goes into R0, thus
+becoming the new stack top.
+
+Try to locate a call to @code{jit_set_ip} in the source code. You
+will not find one; this means that the client has to manually set
+the instruction pointer. This technique has one advantage and one
+drawback. The advantage is that the client can simply set the
+instruction pointer once and then generate code for multiple functions,
+one after another, without caring about passing a different instruction
+pointer each time; see @ref{Reentrancy, , Re-entrant usage of
address@hidden for the disadvantage.
+
+Source code for the client (which lies in the same source file) follows:
+
address@hidden
+static jit_insn codeBuffer[1024];
+
+int main()
address@hidden
+ pifi c2f, f2c;
+ int i;
+
+ jit_set_ip(codeBuffer);
+ c2f = compile_rpn("9*5/32+");
+ f2c = compile_rpn("32-5*9/");
+ jit_flush_code(codeBuffer, jit_get_ip().ptr);
+
+ 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");
+ return 0;
address@hidden
address@hidden example
+
+The client displays a conversion table between Celsius and Fahrenheit
+degrees (both Celsius-to-Fahrenheit and Fahrenheit-to-Celsius). The
+formulas are, @math{F(c) = c*9/5+32} and @math{C(f) = (f-32)*5/9},
+respectively.
+
+Providing the formula as an argument to @code{compile_rpn} effectively
+parameterizes code generation, making it possible to use the same code
+to compile different functions; this is what makes dynamic code
+generation so powerful.
+
+The @file{rpn.c} file in the @lightning{} distribution includes a more
+complete (and more complex) implementation of @code{compile_rpn},
+which does constant folding, allows the argument to the functions
+to be used more than once, and is able to assemble instructions with
+an immediate parameter.
+
address@hidden Fibonacci
address@hidden Fibonacci numbers
+
+The code in this section calculates a variant of the Fibonacci sequence.
+While the traditional Fibonacci sequence is modeled by the recurrence
+relation:
address@hidden
+ f(0) = f(1) = 1
+ f(n) = f(n-1) + f(n-2)
address@hidden display
+
address@hidden
+the functions in this section calculates the following sequence, which
+is more interesting as a address@hidden's because, as is
+easily seen, the sequence represents the number of activations of the
address@hidden procedure that are needed to compute its value through
+recursion.}:
address@hidden
+ nfibs(0) = nfibs(1) = 1
+ nfibs(n) = nfibs(n-1) + nfibs(n-2) + 1
address@hidden display
+
+The purpose of this example is to introduce branches. There are two
+kind of branches: backward branches and forward branches. We'll
+present the calculation in a recursive and iterative form; the
+former only uses forward branches, while the latter uses both.
+
address@hidden
+#include <stdio.h>
+#include "lightning.h"
+
+static jit_insn codeBuffer[1024];
+
+typedef int (*pifi)(int); @rem{/* Pointer to Int Function of Int */}
+
+int main()
address@hidden
+ pifi nfibs = (pifi) (jit_set_ip(codeBuffer).iptr);
+ int in; @rem{/* offset of the argument */}
+ jit_insn *ref; @rem{/* to patch the forward reference */}
+
+ jit_prolog (1);
+ in = jit_arg_ui ();
+ jit_getarg_ui(JIT_V0, in); @rem{/* V0 = n */}
+ ref = jit_blti_ui (jit_forward(), JIT_V0, 2);
+ jit_subi_ui (JIT_V1, JIT_V0, 1); @rem{/* V1 = n-1 */}
+ jit_subi_ui (JIT_V2, JIT_V0, 2); @rem{/* V2 = n-2 */}
+ jit_prepare(1);
+ jit_pusharg_ui(JIT_V1);
+ jit_finish(nfibs);
+ jit_retval(JIT_V1); @rem{/* V1 = nfibs(n-1) */}
+ jit_prepare(1);
+ jit_pusharg_ui(JIT_V2);
+ jit_finish(nfibs);
+ jit_retval(JIT_V2); @rem{/* V2 = nfibs(n-2) */}
+ jit_addi_ui(JIT_V1, JIT_V1, 1);
+ jit_addr_ui(JIT_RET, JIT_V1, JIT_V2); @rem{/* RET = V1 + V2 + 1 */}
+ jit_ret();
+
+ jit_patch(ref); @rem{/* patch jump */}
+ jit_movi_i(JIT_RET, 1); @rem{/* RET = 1 */}
+ jit_ret();
+
+ @rem{/* call the generated code\, passing 32 as an argument */}
+ jit_flush_code(codeBuffer, jit_get_ip().ptr);
+ printf("nfibs(%d) = %d", 32, nfibs(32));
+ return 0;
address@hidden
address@hidden example
+
+As said above, this is the first example of dynamically compiling
+branches. Branch instructions have three operands: two contains the
+values to be compared, while the first is a @dfn{label}; @lightning{}
+label's are represented as @code{jit_insn *} values. Unlike other
+instructions (apart from @code{arg}, which is actually a directive
+rather than an instruction), branch instructions also return a value
+which, as we see in the example above, can be used to compile
+forward references.
+
+Compiling a forward reference is a two-step operation. First, a
+branch is compiled with a dummy label, since the actual destination
+of the jump is not yet known; the dummy label is returned by the
address@hidden()} macro. The value returned by the branch
+instruction is saved to be used later.
+
+Then, when the destination of the jump is reached, another macro
+is used, @code{jit_patch()}. This macro must be called once for
address@hidden point in which the code had a forward branch to the
+instruction following @code{jit_patch} (in this case a @code{movi_i}
+instruction).
+
+Now, here is the iterative version:
+
address@hidden
+#include <stdio.h>
+#include "lightning.h"
+
+static jit_insn codeBuffer[1024];
+
+typedef int (*pifi)(int); @rem{/* Pointer to Int Function of Int */}
+
+int main()
address@hidden
+ pifi nfibs = (pifi) (jit_set_ip(codeBuffer).iptr);
+ int in; @rem{/* offset of the argument */}
+ jit_insn *ref; @rem{/* to patch the forward reference */}
+ jit_insn *loop; @rem{/* start of the loop */}
+
+ jit_leaf (1);
+ in = jit_arg_ui ();
+ jit_getarg_ui(JIT_R2, in); @rem{/* R2 = 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); @rem{/* decr. counter */}
+ jit_addr_ui (JIT_V0, JIT_R0, JIT_R1); @rem{/* V0 = R0 + R1 */}
+ jit_movr_ui (JIT_R0, JIT_R1); @rem{/* R0 = R1 */}
+ jit_addi_ui (JIT_R1, JIT_V0, 1); @rem{/* R1 = V0 + 1 */}
+ jit_bnei_ui (loop, JIT_R2, 0); @rem{/* if (R2) goto loop; */}
+
+ jit_patch(ref); @rem{/* patch forward jump */}
+ jit_movr_ui (JIT_RET, JIT_R1); @rem{/* RET = R1 */}
+ jit_ret ();
+
+ @rem{/* call the generated code\, passing 36 as an argument */}
+ jit_flush_code(codeBuffer, jit_get_ip().ptr);
+ printf("nfibs(%d) = %d", 36, nfibs(36));
+ return 0;
address@hidden
address@hidden example
+
+This code calculates the recurrence relation using iteration (a
address@hidden loop in high-level languages). There is still a forward
+reference (indicated by the @code{jit_forward}/@code{jit_patch} pair);
+there are no function calls anymore: instead, there is a backward
+jump (the @code{bnei} at the end of the loop).
+
+In this case, the destination address should be known, because the
+jumps lands on an instruction that has already been compiled.
+However the program must make a provision and remember the address
+where the jump will land. This is achieved with @code{jit_get_label},
+yet another macro that is much similar to @code{jit_get_ip} but,
+instead of a @code{jit_code} union, it answers an @code{jit_insn *}
+that the branch macros accept.
+
+Now, let's make one more change: let's rewrite the loop like this:
+
address@hidden
+ @address@hidden
+
+ 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);
+
+ loop= jit_get_label();
+ jit_subi_ui (JIT_R2, JIT_R2, 1); @rem{/* decr. counter */}
+ jit_addr_ui (JIT_V0, JIT_R0, JIT_R1); @rem{/* V0 = R0 + R1 */}
+ jit_movr_ui (JIT_R0, JIT_R1); @rem{/* R0 = R1 */}
+ jit_delay(
+ jit_addi_ui (JIT_R1, JIT_V0, 1), @rem{/* R1 = V0 + 1 */}
+ jit_bnei_ui (loop, JIT_R2, 0)); @rem{/* if (R2) goto loop; */}
+
+ @address@hidden
address@hidden example
+
+The @code{jit_delay} macro is used to schedule delay slots in jumps and
+branches. This is optional, but might lead to performance improvements
+in tight inner loops (of course not in a loop that is executed 35
+times, but this is just an example).
+
address@hidden takes two @lightning{} instructions, a @dfn{delay
+instruction} and a @dfn{branch instruction}. Note that the two
+instructions must be written in execution order (first the delay
+instruction, then the branch instruction), @strong{not} with the branch
+first. If the current machine has a delay slot, the delay instruction
+(or part of it) is placed in the delay slot after the branch
+instruction; otherwise, it emits the delay instruction before the branch
+instruction. The delay instruction must not depend on being executed
+before or after the branch.
+
address@hidden Floating-point
address@hidden Doing floating point computations
+
address@hidden Reentrancy
address@hidden Re-entrant usage of @lightning{}
+
+By default, @lightning{} is able to compile different functions at the
+same time as long as it happens in different object files, and on the
+other hand constrains code generation tasks to reside in a single
+object file.
+
+The reason for this is not apparent, but is easily explained:
+the @file{lightning.h} header file defines its state as a
address@hidden variable, so calls to @code{jit_set_ip} and
address@hidden residing in different files access different
+instruction pointers. This was not done without reason: it makes
+the usage of @lightning{} much simpler, as it limits the initialization
+tasks to the bare minimum and removes the need to link the program
+with a separate library.
+
+On the other hand, multi-threaded or otherwise concurrent programs
+require reentrancy in the code generator, so this approach cannot be
+the only one. In fact, it is possible to define your own copy of
address@hidden's instruction state by defining a variable of type
address@hidden and @code{#define}-ing @code{_jit} to it:
+
address@hidden
+ struct jit_state lightning;
+ #define _jit lightning
address@hidden example
+
+You are free to define the @code{jit_state} variable as you like:
address@hidden, @code{static} to a function, @code{auto}, or global.
+
+This feature takes advantage of an aspect of macros (@dfn{cascaded
+macros}), which is documented thus in @acronym{CPP}'s reference manual:
+
address@hidden
+A cascade of macros is when one macro's body contains a reference to
+another macro. This is very common practice. For example,
address@hidden
+#define BUFSIZE 1020
+#define TABLESIZE BUFSIZE
address@hidden example
+This is not at all the same as defining @code{TABLESIZE} to be
address@hidden The @code{#define} for @code{TABLESIZE} uses exactly the
+body you specify---in this case, @code{BUFSIZE}---and does not check to
+see whether it too is the name of a macro; it's only when you use
address@hidden that the result of its expansion is checked for more
+macro names.
+
+This makes a difference if you change the definition of @code{BUFSIZE}
+at some point in the source file. @code{TABLESIZE}, defined as shown,
+will always expand using the definition of @code{BUFSIZE} that is
+currently in effect:
+#define BUFSIZE 1020
+#define TABLESIZE BUFSIZE
+#undef BUFSIZE
+#define BUFSIZE 37
+
+Now @code{TABLESIZE} expands (in two stages) to `37'. (The @code{#undef}
+is to prevent any warning about the nontrivial redefinition of
address@hidden)
address@hidden quotation
+
address@hidden
+In the same way, @code{jit_get_label} will adopt whatever definition of
address@hidden is in effect:
address@hidden
+#define jit_get_label() (_jit.pc)
address@hidden example
+
+Special care must be taken when functions residing in separate files
+must access the same state. This could be the case, for example, if a
+special library contained function for strength reduction of
+multiplications to adds & shifts, or maybe of divisions to
+multiplications and shifts. The function would be compiled using a
+single definition of @code{_jit} and that definition would be used
+whenever the function would be called.
+
+Since @lightning{} uses a feature of the preprocessor to obtain
+re-entrancy, it makes sense to rely on the preprocessor in this case
+too.
+
+The idea is to pass the current @code{struct jit_state} to the
+function:
+
address@hidden
+static void
+_opt_muli_i(jit, dest, source, n)
+ register struct jit_state *jit;
+ register int dest, source, n;
address@hidden
+#define _jit jit
address@hidden
+#undef _jit
address@hidden
address@hidden example
+
address@hidden
+doing this unbeknownst to the client, using a macro in the header file:
+
address@hidden
+extern void _opt_muli_i(struct jit_state *, int, int, int);
+
+#define opt_muli_i(rd, rs, n) _opt_muli_i(&_jit, (rd), (rs), (n))
address@hidden example
+
+
address@hidden Autoconf support
address@hidden Using @code{autoconf} with @lightning{}
+
+It is very easy to include @lightning{}'s source code (without the
+documentation and examples) into your program's distribution
+so that people don't need to have it installed in order to use it.
+
+Here is a step by step explanation of what to do:
+
address@hidden
address@hidden Run @command{lightningize} from your package's main
+distribution directory.
address@hidden
+ lightningize
address@hidden example
+
address@hidden
+If you're using Automake, you might be pleased to know that
address@hidden files will be already there.
+
address@hidden If you're not using Automake and @code{aclocal}, instead,
+you should delete the @file{Makefile.am} files (they are of no use
+to you) and copy the contents of the @file{lightning.m4} file, found in
address@hidden's macro repository (usually @file{/usr/share/aclocal},
+to your @file{configure.in} or @file{acinclude.m4} or @file{aclocal.m4} file.
+
address@hidden Include a call to the @code{LIGHTNING_CONFIGURE_IF_NOT_FOUND}
+macro in your @file{configure.in} file.
address@hidden enumerate
+
address@hidden will first look for a
+pre-installed copy of @lightning{} and, if it can be found, it will
+use it; otherwise, it will do exactly the same things that
address@hidden's own configure script does. If @lightning{} is
+already installed, or if the configuration process succeeds, it
+will define the @code{HAVE_LIGHTNING} symbol.
+
+In addtion, an Automake conditional named @code{HAVE_INSTALLED_LIGHTNING}
+will be set if @lightning{} is already installed, which can be used to
+set up include paths appropriately.
+
+Finally, @code{LIGHTNING_CONFIGURE_IF_NOT_FOUND} accepts two
+optional parameters: respectively, an action to be taken if @lightning{}
+is available, and an action to be taken if it is not.
diff --git a/doc/version.texi b/doc/version.texi
new file mode 100644
index 0000000..b112f90
--- /dev/null
+++ b/doc/version.texi
@@ -0,0 +1,4 @@
address@hidden UPDATED 2 November 2001
address@hidden UPDATED-MONTH November 2001
address@hidden EDITION 1.2a
address@hidden VERSION 1.2a
diff --git a/lightning-inst.h b/lightning-inst.h
new file mode 100644
index 0000000..5cf1af2
--- /dev/null
+++ b/lightning-inst.h
@@ -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 */
diff --git a/lightning.h.in b/lightning.h.in
new file mode 100644
index 0000000..fd1a4d7
--- /dev/null
+++ b/lightning.h.in
@@ -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 */
diff --git a/lightning.m4 b/lightning.m4
new file mode 100644
index 0000000..280a63e
--- /dev/null
+++ b/lightning.m4
@@ -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
diff --git a/lightning/Makefile.am b/lightning/Makefile.am
new file mode 100644
index 0000000..d032e2a
--- /dev/null
+++ b/lightning/Makefile.am
@@ -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
diff --git a/lightning/asm-common.h b/lightning/asm-common.h
new file mode 100644
index 0000000..b0a1194
--- /dev/null
+++ b/lightning/asm-common.h
@@ -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 */
diff --git a/lightning/core-common.h b/lightning/core-common.h
new file mode 100644
index 0000000..23b4747
--- /dev/null
+++ b/lightning/core-common.h
@@ -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_ */
diff --git a/lightning/fp-common.h b/lightning/fp-common.h
new file mode 100644
index 0000000..de25fbb
--- /dev/null
+++ b/lightning/fp-common.h
@@ -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
diff --git a/lightning/funcs-common.h b/lightning/funcs-common.h
new file mode 100644
index 0000000..dafae1f
--- /dev/null
+++ b/lightning/funcs-common.h
@@ -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 */
diff --git a/lightning/i386/asm.h b/lightning/i386/asm.h
new file mode 100644
index 0000000..d805716
--- /dev/null
+++ b/lightning/i386/asm.h
@@ -0,0 +1,1060 @@
+/******************************** -*- C -*- ****************************
+ *
+ * Run-time assembler for the i386
+ *
+ ***********************************************************************/
+
+
+/***********************************************************************
+ *
+ * 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
+
+/* OPCODE + i = immediate operand
+ * + r = register operand
+ * + m = memory operand (disp,base,index,scale)
+ * + sr/sm = a star preceding a register or memory
+ */
+
+
+typedef _uc jit_insn;
+
+#define _b00 0
+#define _b01 1
+#define _b10 2
+#define _b11 3
+
+#define _b000 0
+#define _b001 1
+#define _b010 2
+#define _b011 3
+#define _b100 4
+#define _b101 5
+#define _b110 6
+#define _b111 7
+
+/*** REGISTERS ***/ /* [size,,number] */
+
+
+#define _AL 0x10
+#define _CL 0x11
+#define _DL 0x12
+#define _BL 0x13
+#define _AH 0x14
+#define _CH 0x15
+#define _DH 0x16
+#define _BH 0x17
+
+#define _AX 0x20
+#define _CX 0x21
+#define _DX 0x22
+#define _BX 0x23
+#define _SP 0x24
+#define _BP 0x25
+#define _SI 0x26
+#define _DI 0x27
+
+#define _EAX 0x40
+#define _ECX 0x41
+#define _EDX 0x42
+#define _EBX 0x43
+#define _ESP 0x44
+#define _EBP 0x45
+#define _ESI 0x46
+#define _EDI 0x47
+
+#define _ST0 0
+#define _ST1 1
+#define _ST2 2
+#define _ST3 3
+#define _ST4 4
+#define _ST5 5
+#define _ST6 6
+#define _ST7 7
+
+#define _rS(R) ((R)>>4)
+#define _rN(R) ((R)&0x7)
+#define _r0P(R) ((R)==0)
+
+#ifndef _ASM_SAFETY
+#define _r1(R) _rN(R)
+#define _r2(R) _rN(R)
+#define _r4(R) _rN(R)
+#else
+#define _r1(R) ((_rS(R)==1) ? _rN(R) : JITFAIL( "8-bit register
required"))
+#define _r2(R) ((_rS(R)==2) ? _rN(R) : JITFAIL("16-bit register
required"))
+#define _r4(R) ((_rS(R)==4) ? _rN(R) : JITFAIL("32-bit register
required"))
+#endif
+
+/*** ASSEMBLER ***/
+
+#define _OFF4(D) (_jit_UL(D) - _jit_UL(_jit.x.pc))
+#define _CKD8(D) _ck_d(8, ((_uc) _OFF4(D)) )
+
+#define _D8(D) (_jit_B(0), ((*(_PUC(_jit.x.pc)-1))= _CKD8(D)))
+#define _D32(D) (_jit_L(0), ((*(_PUL(_jit.x.pc)-1))= _OFF4(D)))
+
+#ifndef _ASM_SAFETY
+# define _M(M) (M)
+# define _r(R) (R)
+# define _m(M) (M)
+# define _s(S) (S)
+# define _i(I) (I)
+# define _b(B) (B)
+# define _noESP(I,OK) (OK)
+#else
+# define _M(M) (((M)>3) ? JITFAIL("internal error: mod = " #M) : (M))
+# define _r(R) (((R)>7) ? JITFAIL("internal error: reg = " #R) : (R))
+# define _m(M) (((M)>7) ? JITFAIL("internal error: r/m = " #M) : (M))
+# define _s(S) (((S)>3) ? JITFAIL("internal error: memory scale = "
#S) : (S))
+# define _i(I) (((I)>7) ? JITFAIL("internal error: memory index = "
#I) : (I))
+# define _b(B) (((B)>7) ? JITFAIL("internal error: memory base = "
#B) : (B))
+# define _noESP(I,OK) (((I)==_ESP) ? JITFAIL("illegal index register: %esp")
: (OK))
+#endif
+
+#define _Mrm(Md,R,M) _jit_B((_M(Md)<<6)|(_r(R)<<3)|_m(M))
+#define _SIB(Sc,I, B) _jit_B((_s(Sc)<<6)|(_i(I)<<3)|_b(B))
+
+#define _SCL(S) ((((S)==1) ? _b00 : \
+ (((S)==2) ? _b01 : \
+ (((S)==4) ? _b10 : \
+ (((S)==8) ? _b11 : JITFAIL("illegal scale: " #S))))))
+
+/* memory subformats - urgh! */
+
+#define _r_D( R, D ) (_Mrm(_b00,_rN(R),_b101 )
,_jit_L((long)(D)))
+#define _r_0B( R, B ) (_Mrm(_b00,_rN(R),_r4(B))
)
+#define _r_0BIS(R, B,I,S) (_Mrm(_b00,_rN(R),_b100
),_SIB(_SCL(S),_r4(I),_r4(B)) )
+#define _r_1B( R, D,B ) (_Mrm(_b01,_rN(R),_r4(B))
,_jit_B((long)(D)))
+#define _r_1BIS(R, D,B,I,S) (_Mrm(_b01,_rN(R),_b100
),_SIB(_SCL(S),_r4(I),_r4(B)),_jit_B((long)(D)))
+#define _r_4B( R, D,B ) (_Mrm(_b10,_rN(R),_r4(B))
,_jit_L((long)(D)))
+#define _r_4IS( R, D,I,S) (_Mrm(_b00,_rN(R),_b100
),_SIB(_SCL(S),_r4(I),_b101 ),_jit_L((long)(D)))
+#define _r_4BIS(R, D,B,I,S) (_Mrm(_b10,_rN(R),_b100
),_SIB(_SCL(S),_r4(I),_r4(B)),_jit_L((long)(D)))
+
+#define _r_DB( R, D,B ) ((_s0P(D) && (B != _EBP) ? _r_0B (R, B ) :
(_s8P(D) ? _r_1B( R,D,B ) : _r_4B( R,D,B ))))
+#define _r_DBIS(R, D,B,I,S) ((_s0P(D) ? _r_0BIS(R, B,I,S) :
(_s8P(D) ? _r_1BIS(R,D,B,I,S) : _r_4BIS(R,D,B,I,S))))
+
+#define _r_X( R, D,B,I,S) (_r0P(I) ? (_r0P(B) ? _r_D (R,D
) : \
+ (_ESP==(B) ?
_r_DBIS(R,D,_ESP,_ESP,1) : \
+ _r_DB (R,D, B
))) : \
+ (_r0P(B) ? _r_4IS (R,D,
I,S) : \
+ (((I)!=_ESP) ? _r_DBIS(R,D, B,
I,S) : \
+ JITFAIL("illegal index
register: %esp"))))
+
+
+/* instruction formats */
+
+/* _format Opcd
ModR/M dN(rB,rI,Sc) imm... */
+
+#define _d16() (
_jit_B(0x66 ) )
+#define _O( OP ) (
_jit_B( OP ) )
+#define _Or( OP,R ) (
_jit_B( (OP)|_r(R)) )
+#define _OO( OP ) ( _jit_B((OP)>>8),
_jit_B( (OP) ) )
+#define _OOr( OP,R ) ( _jit_B((OP)>>8),
_jit_B( (OP)|_r(R)) )
+#define _Os( OP,B ) ( _s8P(B) ?
_jit_B(((OP)|_b10)) : _jit_B(OP) )
+#define _sW( W ) (
_s8P(W) ? _jit_B(W):_jit_W(W) )
+#define _sL( L ) (
_s8P(L) ? _jit_B(L):_jit_L(L) )
+#define _O_W( OP ,W ) ( _O (
OP ) ,_jit_W(W) )
+#define _O_D8( OP ,D ) ( _O (
OP ) ,_D8(D) )
+#define _O_D32( OP ,D ) ( _O (
OP ) ,_D32(D) )
+#define _OO_D32( OP ,D ) ( _OO (
OP ) ,_D32(D) )
+#define _Os_sW( OP ,W ) ( _Os (
OP,W) ,_sW(W) )
+#define _Os_sL( OP ,L ) ( _Os (
OP,L) ,_sL(L) )
+#define _O_W_B( OP ,W,B) ( _O (
OP ) ,_jit_W(W),_jit_B(B))
+#define _Or_B( OP,R ,B ) ( _Or (
OP,R) ,_jit_B(B) )
+#define _Or_W( OP,R ,W ) ( _Or (
OP,R) ,_jit_W(W) )
+#define _Or_L( OP,R ,L ) ( _Or (
OP,R) ,_jit_L(L) )
+#define _O_Mrm( OP ,MO,R,M ) ( _O (
OP ),_Mrm(MO,R,M ) )
+#define _OO_Mrm( OP ,MO,R,M ) ( _OO (
OP ),_Mrm(MO,R,M ) )
+#define _O_Mrm_B( OP ,MO,R,M ,B ) ( _O (
OP ),_Mrm(MO,R,M ) ,_jit_B(B) )
+#define _O_Mrm_W( OP ,MO,R,M ,W ) ( _O (
OP ),_Mrm(MO,R,M ) ,_jit_W(W) )
+#define _O_Mrm_L( OP ,MO,R,M ,L ) ( _O (
OP ),_Mrm(MO,R,M ) ,_jit_L(L) )
+#define _OO_Mrm_B( OP ,MO,R,M ,B ) ( _OO (
OP ),_Mrm(MO,R,M ) ,_jit_B(B) )
+#define _Os_Mrm_sW(OP ,MO,R,M ,W ) ( _Os (
OP,W),_Mrm(MO,R,M ),_sW(W) )
+#define _Os_Mrm_sL(OP ,MO,R,M ,L ) ( _Os (
OP,L),_Mrm(MO,R,M ),_sL(L) )
+#define _O_r_X( OP ,R ,MD,MB,MI,MS ) ( _O (
OP ),_r_X( R ,MD,MB,MI,MS) )
+#define _OO_r_X( OP ,R ,MD,MB,MI,MS ) ( _OO (
OP ),_r_X( R ,MD,MB,MI,MS) )
+#define _O_r_X_B( OP ,R ,MD,MB,MI,MS,B ) ( _O (
OP ),_r_X( R ,MD,MB,MI,MS) ,_jit_B(B) )
+#define _O_r_X_W( OP ,R ,MD,MB,MI,MS,W ) ( _O (
OP ),_r_X( R ,MD,MB,MI,MS) ,_jit_W(W) )
+#define _O_r_X_L( OP ,R ,MD,MB,MI,MS,L ) ( _O (
OP ),_r_X( R ,MD,MB,MI,MS) ,_jit_L(L) )
+#define _OO_r_X_B( OP ,R ,MD,MB,MI,MS,B ) ( _OO (
OP ),_r_X( R ,MD,MB,MI,MS) ,_jit_B(B) )
+#define _Os_r_X_sW(OP ,R ,MD,MB,MI,MS,W ) ( _Os (
OP,W),_r_X( R ,MD,MB,MI,MS),_sW(W) )
+#define _Os_r_X_sL(OP ,R ,MD,MB,MI,MS,L ) ( _Os (
OP,L),_r_X( R ,MD,MB,MI,MS),_sL(L) )
+#define _O_X_B( OP ,MD,MB,MI,MS,B ) ( _O_r_X_B(
OP ,0 ,MD,MB,MI,MS ,B) )
+#define _O_X_W( OP ,MD,MB,MI,MS,W ) ( _O_r_X_W(
OP ,0 ,MD,MB,MI,MS ,W) )
+#define _O_X_L( OP ,MD,MB,MI,MS,L ) ( _O_r_X_L(
OP ,0 ,MD,MB,MI,MS ,L) )
+#define _wO( OP ) (_d16(), _O(
OP ) )
+#define _wOr( OP,R ) (_d16(), _Or(
OP,R ) )
+#define _wOr_W( OP,R ,W ) (_d16(), _Or_W(
OP,R ,W) )
+#define _wOs_sW( OP ,W ) (_d16(), _Os_sW(
OP ,W) )
+#define _wO_Mrm( OP ,MO,R,M ) (_d16(), _O_Mrm(
OP ,MO,R,M ) )
+#define _wOO_Mrm( OP ,MO,R,M ) (_d16(),_OO_Mrm(
OP ,MO,R,M ) )
+#define _wO_Mrm_B( OP ,MO,R,M ,B ) (_d16(), _O_Mrm_B(
OP ,MO,R,M ,B) )
+#define _wOO_Mrm_B( OP ,MO,R,M ,B ) (_d16(),_OO_Mrm_B(
OP ,MO,R,M ,B) )
+#define _wO_Mrm_W( OP ,MO,R,M ,W ) (_d16(), _O_Mrm_W(
OP ,MO,R,M ,W) )
+#define _wOs_Mrm_sW(OP ,MO,R,M ,W ) (_d16(),
_Os_Mrm_sW(OP ,MO,R,M ,W) )
+#define _wO_X_W( OP ,MD,MB,MI,MS,W ) (_d16(), _O_X_W(
OP ,MD,MB,MI,MS ,W) )
+#define _wO_r_X( OP ,R ,MD,MB,MI,MS ) (_d16(), _O_r_X(
OP ,R ,MD,MB,MI,MS ) )
+#define _wOO_r_X( OP ,R ,MD,MB,MI,MS ) (_d16(),_OO_r_X(
OP ,R ,MD,MB,MI,MS ) )
+#define _wO_r_X_B( OP ,R ,MD,MB,MI,MS,B ) (_d16(), _O_r_X_B(
OP ,R ,MD,MB,MI,MS ,B) )
+#define _wOO_r_X_B( OP ,R ,MD,MB,MI,MS,B ) (_d16(),_OO_r_X_B(
OP ,R ,MD,MB,MI,MS ,B) )
+#define _wO_r_X_W( OP ,R ,MD,MB,MI,MS,W ) (_d16(), _O_r_X_W(
OP ,R ,MD,MB,MI,MS ,W) )
+#define _wOs_r_X_sW(OP ,R ,MD,MB,MI,MS,W ) (_d16(),
_Os_r_X_sW(OP ,R ,MD,MB,MI,MS ,W) )
+
+/* +++ fully-qualified intrinsic instructions */
+
+/* _format Opcd ,Mod ,r
,m ,mem=dsp+sib ,imm... */
+
+#define ADCBrr(RS, RD) _O_Mrm (0x10
,_b11,_r1(RS),_r1(RD) )
+#define ADCBmr(MD, MB, MI, MS, RD) _O_r_X (0x12
,_r1(RD) ,MD,MB,MI,MS )
+#define ADCBrm(RS, MD, MB, MI, MS) _O_r_X (0x10
,_r1(RS) ,MD,MB,MI,MS )
+#define ADCBir(IM, RD) _O_Mrm_B (0x80
,_b11,_b010 ,_r1(RD) ,_su8(IM))
+#define ADCBim(IM, MD, MB, MI, MS) _O_r_X_B (0x80
,_b010 ,MD,MB,MI,MS ,_su8(IM))
+
+#define ADCWrr(RS, RD) _wO_Mrm (0x11
,_b11,_r2(RS),_r2(RD) )
+#define ADCWmr(MD, MB, MI, MS, RD) _wO_r_X (0x13
,_r2(RD) ,MD,MB,MI,MS )
+#define ADCWrm(RS, MD, MB, MI, MS) _wO_r_X (0x11
,_r2(RS) ,MD,MB,MI,MS )
+#define ADCWir(IM, RD) _wOs_Mrm_sW (0x81
,_b11,_b010 ,_r2(RD) ,_su16(IM))
+#define ADCWim(IM, MD, MB, MI, MS) _wOs_r_X_sW (0x81
,_b010 ,MD,MB,MI,MS ,_su16(IM))
+
+#define ADCLrr(RS, RD) _O_Mrm (0x11
,_b11,_r4(RS),_r4(RD) )
+#define ADCLmr(MD, MB, MI, MS, RD) _O_r_X (0x13
,_r4(RD) ,MD,MB,MI,MS )
+#define ADCLrm(RS, MD, MB, MI, MS) _O_r_X (0x11
,_r4(RS) ,MD,MB,MI,MS )
+#define ADCLir(IM, RD) _Os_Mrm_sL (0x81
,_b11,_b010 ,_r4(RD) ,IM )
+#define ADCLim(IM, MD, MB, MI, MS) _Os_r_X_sL (0x81
,_b010 ,MD,MB,MI,MS ,IM )
+
+
+#define ADDBrr(RS, RD) _O_Mrm (0x00
,_b11,_r1(RS),_r1(RD) )
+#define ADDBmr(MD, MB, MI, MS, RD) _O_r_X (0x02
,_r1(RD) ,MD,MB,MI,MS )
+#define ADDBrm(RS, MD, MB, MI, MS) _O_r_X (0x00
,_r1(RS) ,MD,MB,MI,MS )
+#define ADDBir(IM, RD) _O_Mrm_B (0x80
,_b11,_b000 ,_r1(RD) ,_su8(IM))
+#define ADDBim(IM, MD, MB, MI, MS) _O_r_X_B (0x80
,_b000 ,MD,MB,MI,MS ,_su8(IM))
+
+#define ADDWrr(RS, RD) _wO_Mrm (0x01
,_b11,_r2(RS),_r2(RD) )
+#define ADDWmr(MD, MB, MI, MS, RD) _wO_r_X (0x03
,_r2(RD) ,MD,MB,MI,MS )
+#define ADDWrm(RS, MD, MB, MI, MS) _wO_r_X (0x01
,_r2(RS) ,MD,MB,MI,MS )
+#define ADDWir(IM, RD) _wOs_Mrm_sW (0x81
,_b11,_b000 ,_r2(RD) ,_su16(IM))
+#define ADDWim(IM, MD, MB, MI, MS) _wOs_r_X_sW (0x81
,_b000 ,MD,MB,MI,MS ,_su16(IM))
+
+#define ADDLrr(RS, RD) _O_Mrm (0x01
,_b11,_r4(RS),_r4(RD) )
+#define ADDLmr(MD, MB, MI, MS, RD) _O_r_X (0x03
,_r4(RD) ,MD,MB,MI,MS )
+#define ADDLrm(RS, MD, MB, MI, MS) _O_r_X (0x01
,_r4(RS) ,MD,MB,MI,MS )
+#define ADDLir(IM, RD) _Os_Mrm_sL (0x81
,_b11,_b000 ,_r4(RD) ,IM )
+#define ADDLim(IM, MD, MB, MI, MS) _Os_r_X_sL (0x81
,_b000 ,MD,MB,MI,MS ,IM )
+
+
+#define ANDBrr(RS, RD) _O_Mrm (0x20
,_b11,_r1(RS),_r1(RD) )
+#define ANDBmr(MD, MB, MI, MS, RD) _O_r_X (0x22
,_r1(RD) ,MD,MB,MI,MS )
+#define ANDBrm(RS, MD, MB, MI, MS) _O_r_X (0x20
,_r1(RS) ,MD,MB,MI,MS )
+#define ANDBir(IM, RD) _O_Mrm_B (0x80
,_b11,_b100 ,_r1(RD) ,_su8(IM))
+#define ANDBim(IM, MD, MB, MI, MS) _O_r_X_B (0x80
,_b100 ,MD,MB,MI,MS ,_su8(IM))
+
+#define ANDWrr(RS, RD) _wO_Mrm (0x21
,_b11,_r2(RS),_r2(RD) )
+#define ANDWmr(MD, MB, MI, MS, RD) _wO_r_X (0x23
,_r2(RD) ,MD,MB,MI,MS )
+#define ANDWrm(RS, MD, MB, MI, MS) _wO_r_X (0x21
,_r2(RS) ,MD,MB,MI,MS )
+#define ANDWir(IM, RD) _wOs_Mrm_sW (0x81
,_b11,_b100 ,_r2(RD) ,_su16(IM))
+#define ANDWim(IM, MD, MB, MI, MS) _wOs_r_X_sW (0x81
,_b100 ,MD,MB,MI,MS ,_su16(IM))
+
+#define ANDLrr(RS, RD) _O_Mrm (0x21
,_b11,_r4(RS),_r4(RD) )
+#define ANDLmr(MD, MB, MI, MS, RD) _O_r_X (0x23
,_r4(RD) ,MD,MB,MI,MS )
+#define ANDLrm(RS, MD, MB, MI, MS) _O_r_X (0x21
,_r4(RS) ,MD,MB,MI,MS )
+#define ANDLir(IM, RD) _Os_Mrm_sL (0x81
,_b11,_b100 ,_r4(RD) ,IM )
+#define ANDLim(IM, MD, MB, MI, MS) _Os_r_X_sL (0x81
,_b100 ,MD,MB,MI,MS ,IM )
+
+
+#define BSWAPLr(R) _OOr (0x0fc8,_r4(R)
)
+
+
+#define BTWir(IM,RD) _wOO_Mrm_B (0x0fba
,_b11,_b100 ,_r2(RD) ,_u8(IM))
+#define BTWim(IM,MD,MB,MI,MS) _wOO_r_X_B (0x0fba
,_b100 ,MD,MB,MI,MS ,_u8(IM))
+#define BTWrr(RS,RD) _wOO_Mrm (0x0fa3
,_b11,_r2(RS),_r2(RD) )
+#define BTWrm(RS,MD,MB,MI,MS) _wOO_r_X (0x0fa3
,_r2(RS) ,MD,MB,MI,MS )
+
+#define BTLir(IM,RD) _OO_Mrm_B (0x0fba
,_b11,_b100 ,_r4(RD) ,_u8(IM))
+#define BTLim(IM,MD,MB,MI,MS) _OO_r_X_B (0x0fba
,_b100 ,MD,MB,MI,MS ,_u8(IM))
+#define BTLrr(RS,RD) _OO_Mrm (0x0fa3
,_b11,_r4(RS),_r4(RD) )
+#define BTLrm(RS,MD,MB,MI,MS) _OO_r_X (0x0fa3
,_r4(RS) ,MD,MB,MI,MS )
+
+
+#define BTCWir(IM,RD) _wOO_Mrm_B (0x0fba
,_b11,_b111 ,_r2(RD) ,_u8(IM))
+#define BTCWim(IM,MD,MB,MI,MS) _wOO_r_X_B (0x0fba
,_b111 ,MD,MB,MI,MS ,_u8(IM))
+#define BTCWrr(RS,RD) _wOO_Mrm (0x0fbb
,_b11,_r2(RS),_r2(RD) )
+#define BTCWrm(RS,MD,MB,MI,MS) _wOO_r_X (0x0fbb
,_r2(RS) ,MD,MB,MI,MS )
+
+#define BTCLir(IM,RD) _OO_Mrm_B (0x0fba
,_b11,_b111 ,_r4(RD) ,_u8(IM))
+#define BTCLim(IM,MD,MB,MI,MS) _OO_r_X_B (0x0fba
,_b111 ,MD,MB,MI,MS ,_u8(IM))
+#define BTCLrr(RS,RD) _OO_Mrm (0x0fbb
,_b11,_r4(RS),_r4(RD) )
+#define BTCLrm(RS,MD,MB,MI,MS) _OO_r_X (0x0fbb
,_r4(RS) ,MD,MB,MI,MS )
+
+
+#define BTRWir(IM,RD) _wOO_Mrm_B (0x0fba
,_b11,_b110 ,_r2(RD) ,_u8(IM))
+#define BTRWim(IM,MD,MB,MI,MS) _wOO_r_X_B (0x0fba
,_b110 ,MD,MB,MI,MS ,_u8(IM))
+#define BTRWrr(RS,RD) _wOO_Mrm (0x0fb3
,_b11,_r2(RS),_r2(RD) )
+#define BTRWrm(RS,MD,MB,MI,MS) _wOO_r_X (0x0fb3
,_r2(RS) ,MD,MB,MI,MS )
+
+#define BTRLir(IM,RD) _OO_Mrm_B (0x0fba
,_b11,_b110 ,_r4(RD) ,_u8(IM))
+#define BTRLim(IM,MD,MB,MI,MS) _OO_r_X_B (0x0fba
,_b110 ,MD,MB,MI,MS ,_u8(IM))
+#define BTRLrr(RS,RD) _OO_Mrm (0x0fb3
,_b11,_r4(RS),_r4(RD) )
+#define BTRLrm(RS,MD,MB,MI,MS) _OO_r_X (0x0fb3
,_r4(RS) ,MD,MB,MI,MS )
+
+
+#define BTSWir(IM,RD) _wOO_Mrm_B (0x0fba
,_b11,_b101 ,_r2(RD) ,_u8(IM))
+#define BTSWim(IM,MD,MB,MI,MS) _wOO_r_X_B (0x0fba
,_b101 ,MD,MB,MI,MS ,_u8(IM))
+#define BTSWrr(RS,RD) _wOO_Mrm (0x0fab
,_b11,_r2(RS),_r2(RD) )
+#define BTSWrm(RS,MD,MB,MI,MS) _wOO_r_X (0x0fab
,_r2(RS) ,MD,MB,MI,MS )
+
+#define BTSLir(IM,RD) _OO_Mrm_B (0x0fba
,_b11,_b101 ,_r4(RD) ,_u8(IM))
+#define BTSLim(IM,MD,MB,MI,MS) _OO_r_X_B (0x0fba
,_b101 ,MD,MB,MI,MS ,_u8(IM))
+#define BTSLrr(RS,RD) _OO_Mrm (0x0fab
,_b11,_r4(RS),_r4(RD) )
+#define BTSLrm(RS,MD,MB,MI,MS) _OO_r_X (0x0fab
,_r4(RS) ,MD,MB,MI,MS )
+
+
+#define CALLm(D,B,I,S) ((_r0P(B) && _r0P(I)) ? _O_D32 (0xe8
,(int)(D) ) : \
+
JITFAIL("illegal mode in direct jump"))
+
+#define CALLsr(R) _O_Mrm (0xff ,_b11,_b010,_r4(R)
)
+
+#define CALLsm(D,B,I,S) _O_r_X (0xff ,_b010
,(int)(D),B,I,S )
+
+#define CBW() _O (0x98
)
+#define CLC() _O (0xf8
)
+#define CLTD() _O (0x99
)
+#define CMC() _O (0xf5
)
+
+
+#define CMPBrr(RS, RD) _O_Mrm (0x38
,_b11,_r1(RS),_r1(RD) )
+#define CMPBmr(MD, MB, MI, MS, RD) _O_r_X (0x3a
,_r1(RD) ,MD,MB,MI,MS )
+#define CMPBrm(RS, MD, MB, MI, MS) _O_r_X (0x38
,_r1(RS) ,MD,MB,MI,MS )
+#define CMPBir(IM, RD) _O_Mrm_B (0x80
,_b11,_b111 ,_r1(RD) ,_su8(IM))
+#define CMPBim(IM, MD, MB, MI, MS) _O_r_X_B (0x80
,_b111 ,MD,MB,MI,MS ,_su8(IM))
+
+#define CMPWrr(RS, RD) _wO_Mrm (0x39
,_b11,_r2(RS),_r2(RD) )
+#define CMPWmr(MD, MB, MI, MS, RD) _wO_r_X (0x3b
,_r2(RD) ,MD,MB,MI,MS )
+#define CMPWrm(RS, MD, MB, MI, MS) _wO_r_X (0x39
,_r2(RS) ,MD,MB,MI,MS )
+#define CMPWir(IM, RD) _wOs_Mrm_sW (0x81
,_b11,_b111 ,_r2(RD) ,_su16(IM))
+#define CMPWim(IM, MD, MB, MI, MS) _wOs_r_X_sW (0x81
,_b111 ,MD,MB,MI,MS ,_su16(IM))
+
+#define CMPLrr(RS, RD) _O_Mrm (0x39
,_b11,_r4(RS),_r4(RD) )
+#define CMPLmr(MD, MB, MI, MS, RD) _O_r_X (0x3b
,_r4(RD) ,MD,MB,MI,MS )
+#define CMPLrm(RS, MD, MB, MI, MS) _O_r_X (0x39
,_r4(RS) ,MD,MB,MI,MS )
+#define CMPLir(IM, RD) _O_Mrm_L (0x81
,_b11,_b111 ,_r4(RD) ,IM )
+#define CMPLim(IM, MD, MB, MI, MS) _O_r_X_L (0x81
,_b111 ,MD,MB,MI,MS ,IM )
+
+
+#define CWD() _O (0x99
)
+
+
+#define CMPXCHGBrr(RS,RD) _OO_Mrm (0x0fb0
,_b11,_r1(RS),_r1(RD) )
+#define CMPXCHGBrm(RS,MD,MB,MI,MS) _OO_r_X (0x0fb0
,_r1(RS) ,MD,MB,MI,MS )
+
+#define CMPXCHGWrr(RS,RD) _wOO_Mrm (0x0fb1
,_b11,_r2(RS),_r2(RD) )
+#define CMPXCHGWrm(RS,MD,MB,MI,MS) _wOO_r_X (0x0fb1
,_r2(RS) ,MD,MB,MI,MS )
+
+#define CMPXCHGLrr(RS,RD) _OO_Mrm (0x0fb1
,_b11,_r4(RS),_r4(RD) )
+#define CMPXCHGLrm(RS,MD,MB,MI,MS) _OO_r_X (0x0fb1
,_r4(RS) ,MD,MB,MI,MS )
+
+
+#define DECBr(RD) _O_Mrm (0xfe
,_b11,_b001 ,_r1(RD) )
+#define DECBm(MD,MB,MI,MS) _O_r_X (0xfe
,_b001 ,MD,MB,MI,MS )
+
+#define DECWr(RD) _wOr (0x48,_r2(RD)
)
+#define DECWm(MD,MB,MI,MS) _wO_r_X (0xff
,_b001 ,MD,MB,MI,MS )
+
+#define DECLr(RD) _Or (0x48,_r4(RD)
)
+#define DECLm(MD,MB,MI,MS) _O_r_X (0xff
,_b001 ,MD,MB,MI,MS )
+
+
+#define DIVBr(RS) _O_Mrm (0xf6
,_b11,_b110 ,_r1(RS) )
+#define DIVBm(MD,MB,MI,MS) _O_r_X (0xf6
,_b110 ,MD,MB,MI,MS )
+
+#define DIVWr(RS) _wO_Mrm (0xf7
,_b11,_b110 ,_r2(RS) )
+#define DIVWm(MD,MB,MI,MS) _wO_r_X (0xf7
,_b110 ,MD,MB,MI,MS )
+
+#define DIVLr(RS) _O_Mrm (0xf7
,_b11,_b110 ,_r4(RS) )
+#define DIVLm(MD,MB,MI,MS) _O_r_X (0xf7
,_b110 ,MD,MB,MI,MS )
+
+
+#define ENTERii(W, B) _O_W_B (0xc8
,_su16(W),_su8(B))
+#define HLT() _O (0xf4
)
+
+
+#define IDIVBr(RS) _O_Mrm (0xf6
,_b11,_b111 ,_r1(RS) )
+#define IDIVBm(MD,MB,MI,MS) _O_r_X (0xf6
,_b111 ,MD,MB,MI,MS )
+
+#define IDIVWr(RS) _wO_Mrm (0xf7
,_b11,_b111 ,_r2(RS) )
+#define IDIVWm(MD,MB,MI,MS) _wO_r_X (0xf7
,_b111 ,MD,MB,MI,MS )
+
+#define IDIVLr(RS) _O_Mrm (0xf7
,_b11,_b111 ,_r4(RS) )
+#define IDIVLm(MD,MB,MI,MS) _O_r_X (0xf7
,_b111 ,MD,MB,MI,MS )
+
+#define IMULBr(RS) _O_Mrm (0xf6
,_b11,_b101 ,_r1(RS) )
+#define IMULBm(MD,MB,MI,MS) _O_r_X (0xf6
,_b101 ,MD,MB,MI,MS )
+
+#define IMULWr(RS) _wO_Mrm (0xf7
,_b11,_b101 ,_r2(RS) )
+#define IMULWm(MD,MB,MI,MS) _wO_r_X (0xf7
,_b101 ,MD,MB,MI,MS )
+
+#define IMULLr(RS) _O_Mrm (0xf7
,_b11,_b101 ,_r4(RS) )
+#define IMULLm(MD,MB,MI,MS) _O_r_X (0xf7
,_b101 ,MD,MB,MI,MS )
+
+
+#define IMULWrr(RS,RD) _wOO_Mrm (0x0faf
,_b11,_r2(RS),_r2(RD) )
+#define IMULWmr(MD,MB,MI,MS,RD) _wOO_r_X (0x0faf
,_r2(RD) ,MD,MB,MI,MS )
+#define IMULWirr(IM,RS,RD) _wOs_Mrm_sW (0x69
,_b11,_r2(RS),_r2(RD) ,_su16(IM) )
+#define IMULWimr(IM,MD,MB,MI,MS,RD) _wOs_r_X_sW (0x69
,_r2(RD) ,MD,MB,MI,MS ,_su16(IM) )
+
+#define IMULLir(IM,RD) _Os_Mrm_sL (0x69
,_b11,_r4(RD),_r4(RD) ,IM )
+#define IMULLrr(RS,RD) _OO_Mrm (0x0faf
,_b11,_r4(RD),_r4(RS) )
+#define IMULLmr(MD,MB,MI,MS,RD) _OO_r_X (0x0faf
,_r4(RD) ,MD,MB,MI,MS )
+#define IMULLirr(IM,RS,RD) _Os_Mrm_sL (0x69
,_b11,_r4(RS),_r4(RD) ,IM )
+#define IMULLimr(IM,MD,MB,MI,MS,RD) _Os_r_X_sL (0x69
,_r4(RD) ,MD,MB,MI,MS ,IM )
+
+
+#define INCBr(RD) _O_Mrm (0xfe
,_b11,_b000 ,_r1(RD) )
+#define INCBm(MD,MB,MI,MS) _O_r_X (0xfe
,_b000 ,MD,MB,MI,MS )
+
+#define INCWr(RD) _wOr (0x40,_r2(RD)
)
+#define INCWm(MD,MB,MI,MS) _wO_r_X (0xff
,_b000 ,MD,MB,MI,MS )
+
+#define INCLr(RD) _Or (0x40,_r4(RD)
)
+#define INCLm(MD,MB,MI,MS) _O_r_X (0xff
,_b000 ,MD,MB,MI,MS )
+
+
+#define INVD() _OO (0x0f08
)
+#define INVLPGm(MD, MB, MI, MS) _OO_r_X (0x0f01
,_b111 ,MD,MB,MI,MS )
+
+
+#define JCCSim(CC,D,B,I,S) ((_r0P(B) && _r0P(I)) ? _O_D8
(0x70|(CC) ,(int)(D) ) : \
+
JITFAIL("illegal mode in conditional jump"))
+
+#define JOSm(D,B,I,S) JCCSim(0x0,D,B,I,S)
+#define JNOSm(D,B,I,S) JCCSim(0x1,D,B,I,S)
+#define JBSm(D,B,I,S) JCCSim(0x2,D,B,I,S)
+#define JNAESm(D,B,I,S) JCCSim(0x2,D,B,I,S)
+#define JNBSm(D,B,I,S) JCCSim(0x3,D,B,I,S)
+#define JAESm(D,B,I,S) JCCSim(0x3,D,B,I,S)
+#define JESm(D,B,I,S) JCCSim(0x4,D,B,I,S)
+#define JZSm(D,B,I,S) JCCSim(0x4,D,B,I,S)
+#define JNESm(D,B,I,S) JCCSim(0x5,D,B,I,S)
+#define JNZSm(D,B,I,S) JCCSim(0x5,D,B,I,S)
+#define JBESm(D,B,I,S) JCCSim(0x6,D,B,I,S)
+#define JNASm(D,B,I,S) JCCSim(0x6,D,B,I,S)
+#define JNBESm(D,B,I,S) JCCSim(0x7,D,B,I,S)
+#define JASm(D,B,I,S) JCCSim(0x7,D,B,I,S)
+#define JSSm(D,B,I,S) JCCSim(0x8,D,B,I,S)
+#define JNSSm(D,B,I,S) JCCSim(0x9,D,B,I,S)
+#define JPSm(D,B,I,S) JCCSim(0xa,D,B,I,S)
+#define JPESm(D,B,I,S) JCCSim(0xa,D,B,I,S)
+#define JNPSm(D,B,I,S) JCCSim(0xb,D,B,I,S)
+#define JPOSm(D,B,I,S) JCCSim(0xb,D,B,I,S)
+#define JLSm(D,B,I,S) JCCSim(0xc,D,B,I,S)
+#define JNGESm(D,B,I,S) JCCSim(0xc,D,B,I,S)
+#define JNLSm(D,B,I,S) JCCSim(0xd,D,B,I,S)
+#define JGESm(D,B,I,S) JCCSim(0xd,D,B,I,S)
+#define JLESm(D,B,I,S) JCCSim(0xe,D,B,I,S)
+#define JNGSm(D,B,I,S) JCCSim(0xe,D,B,I,S)
+#define JNLESm(D,B,I,S) JCCSim(0xf,D,B,I,S)
+#define JGSm(D,B,I,S) JCCSim(0xf,D,B,I,S)
+
+#define JCCim(CC,D,B,I,S) ((_r0P(B) && _r0P(I)) ? _OO_D32
(0x0f80|(CC) ,(int)(D) ) : \
+
JITFAIL("illegal mode in conditional jump"))
+
+#define JOm(D,B,I,S) JCCim(0x0,D,B,I,S)
+#define JNOm(D,B,I,S) JCCim(0x1,D,B,I,S)
+#define JBm(D,B,I,S) JCCim(0x2,D,B,I,S)
+#define JNAEm(D,B,I,S) JCCim(0x2,D,B,I,S)
+#define JNBm(D,B,I,S) JCCim(0x3,D,B,I,S)
+#define JAEm(D,B,I,S) JCCim(0x3,D,B,I,S)
+#define JEm(D,B,I,S) JCCim(0x4,D,B,I,S)
+#define JZm(D,B,I,S) JCCim(0x4,D,B,I,S)
+#define JNEm(D,B,I,S) JCCim(0x5,D,B,I,S)
+#define JNZm(D,B,I,S) JCCim(0x5,D,B,I,S)
+#define JBEm(D,B,I,S) JCCim(0x6,D,B,I,S)
+#define JNAm(D,B,I,S) JCCim(0x6,D,B,I,S)
+#define JNBEm(D,B,I,S) JCCim(0x7,D,B,I,S)
+#define JAm(D,B,I,S) JCCim(0x7,D,B,I,S)
+#define JSm(D,B,I,S) JCCim(0x8,D,B,I,S)
+#define JNSm(D,B,I,S) JCCim(0x9,D,B,I,S)
+#define JPm(D,B,I,S) JCCim(0xa,D,B,I,S)
+#define JPEm(D,B,I,S) JCCim(0xa,D,B,I,S)
+#define JNPm(D,B,I,S) JCCim(0xb,D,B,I,S)
+#define JPOm(D,B,I,S) JCCim(0xb,D,B,I,S)
+#define JLm(D,B,I,S) JCCim(0xc,D,B,I,S)
+#define JNGEm(D,B,I,S) JCCim(0xc,D,B,I,S)
+#define JNLm(D,B,I,S) JCCim(0xd,D,B,I,S)
+#define JGEm(D,B,I,S) JCCim(0xd,D,B,I,S)
+#define JLEm(D,B,I,S) JCCim(0xe,D,B,I,S)
+#define JNGm(D,B,I,S) JCCim(0xe,D,B,I,S)
+#define JNLEm(D,B,I,S) JCCim(0xf,D,B,I,S)
+#define JGm(D,B,I,S) JCCim(0xf,D,B,I,S)
+
+
+#define JMPSm(D,B,I,S) ((_r0P(B) && _r0P(I)) ? _O_D8 (0xeb
,(int)(D) ) : \
+
JITFAIL("illegal mode in short jump"))
+
+#define JMPm(D,B,I,S) ((_r0P(B) && _r0P(I)) ? _O_D32 (0xe9
,(int)(D) ) : \
+
JITFAIL("illegal mode in direct jump"))
+
+#define JMPsr(R) _O_Mrm (0xff ,_b11,_b100,_r4(R)
)
+
+#define JMPsm(D,B,I,S) _O_r_X (0xff ,_b100
,(int)(D),B,I,S )
+
+
+#define LAHF() _O (0x9f
)
+#define LEALmr(MD, MB, MI, MS, RD) _O_r_X (0x8d
,_r4(RD) ,MD,MB,MI,MS )
+#define LEAVE() _O (0xc9
)
+
+
+#define LMSWr(RS) _OO_Mrm (0x0f01
,_b11,_b110,_r4(RS) )
+#define LMSWm(MD,MB,MI,MS) _OO_r_X (0x0f01
,_b110 ,MD,MB,MI,MS )
+
+#define LOOPm(MD,MB,MI,MS) ((_r0P(MB) && _r0P(MI)) ? _O_D8 (0xe2
,MD ) : \
+
JITFAIL("illegal mode in loop"))
+
+#define LOOPEm(MD,MB,MI,MS) ((_r0P(MB) && _r0P(MI)) ? _O_D8 (0xe1
,MD ) : \
+
JITFAIL("illegal mode in loope"))
+
+#define LOOPZm(MD,MB,MI,MS) ((_r0P(MB) && _r0P(MI)) ? _O_D8 (0xe1
,MD ) : \
+
JITFAIL("illegal mode in loopz"))
+
+#define LOOPNEm(MD,MB,MI,MS) ((_r0P(MB) && _r0P(MI)) ? _O_D8 (0xe0
,MD ) : \
+
JITFAIL("illegal mode in loopne"))
+
+#define LOOPNZm(MD,MB,MI,MS) ((_r0P(MB) && _r0P(MI)) ? _O_D8 (0xe0
,MD ) : \
+
JITFAIL("illegal mode in loopnz"))
+
+
+#define MOVBrr(RS, RD) _O_Mrm (0x80
,_b11,_r1(RS),_r1(RD) )
+#define MOVBmr(MD, MB, MI, MS, RD) _O_r_X (0x8a
,_r1(RD) ,MD,MB,MI,MS )
+#define MOVBrm(RS, MD, MB, MI, MS) _O_r_X (0x88
,_r1(RS) ,MD,MB,MI,MS )
+#define MOVBir(IM, R) _Or_B (0xb0,_r1(R)
,_su8(IM))
+#define MOVBim(IM, MD, MB, MI, MS) _O_X_B (0xc6
,MD,MB,MI,MS ,_su8(IM))
+
+#define MOVWrr(RS, RD) _wO_Mrm (0x89
,_b11,_r2(RS),_r2(RD) )
+#define MOVWmr(MD, MB, MI, MS, RD) _wO_r_X (0x8b
,_r2(RD) ,MD,MB,MI,MS )
+#define MOVWrm(RS, MD, MB, MI, MS) _wO_r_X (0x89
,_r2(RS) ,MD,MB,MI,MS )
+#define MOVWir(IM, R) _wOr_W (0xb8,_r2(R)
,_su16(IM))
+#define MOVWim(IM, MD, MB, MI, MS) _wO_X_W (0xc7
,MD,MB,MI,MS ,_su16(IM))
+
+#define MOVLrr(RS, RD) _O_Mrm (0x89
,_b11,_r4(RS),_r4(RD) )
+#define MOVLmr(MD, MB, MI, MS, RD) _O_r_X (0x8b
,_r4(RD) ,MD,MB,MI,MS )
+#define MOVLrm(RS, MD, MB, MI, MS) _O_r_X (0x89
,_r4(RS) ,MD,MB,MI,MS )
+#define MOVLir(IM, R) _Or_L (0xb8,_r4(R)
,IM )
+#define MOVLim(IM, MD, MB, MI, MS) _O_X_L (0xc7
,MD,MB,MI,MS ,IM )
+
+#define MOVZBLrr(RS, RD) _OO_Mrm (0x0fb6
,_b11,_r1(RD),_r1(RS) )
+#define MOVZBLmr(MD, MB, MI, MS, RD) _OO_r_X (0x0fb6
,_r1(RD) ,MD,MB,MI,MS )
+#define MOVZBWrr(RS, RD) _wOO_Mrm (0x0fb6
,_b11,_r2(RD),_r2(RS) )
+#define MOVZBWmr(MD, MB, MI, MS, RD) _wOO_r_X (0x0fb6
,_r2(RD) ,MD,MB,MI,MS )
+#define MOVZWLrr(RS, RD) _OO_Mrm (0x0fb7
,_b11,_r1(RD),_r1(RS) )
+#define MOVZWLmr(MD, MB, MI, MS, RD) _OO_r_X (0x0fb7
,_r1(RD) ,MD,MB,MI,MS )
+
+#define MOVSBLrr(RS, RD) _OO_Mrm (0x0fbe
,_b11,_r1(RD),_r1(RS) )
+#define MOVSBLmr(MD, MB, MI, MS, RD) _OO_r_X (0x0fbe
,_r1(RD) ,MD,MB,MI,MS )
+#define MOVSBWrr(RS, RD) _wOO_Mrm (0x0fbe
,_b11,_r2(RD),_r2(RS) )
+#define MOVSBWmr(MD, MB, MI, MS, RD) _wOO_r_X (0x0fbe
,_r2(RD) ,MD,MB,MI,MS )
+#define MOVSWLrr(RS, RD) _OO_Mrm (0x0fbf
,_b11,_r1(RD),_r1(RS) )
+#define MOVSWLmr(MD, MB, MI, MS, RD) _OO_r_X (0x0fbf
,_r1(RD) ,MD,MB,MI,MS )
+
+
+#define MULBr(RS) _O_Mrm (0xf6
,_b11,_b100 ,_r1(RS) )
+#define MULBm(MD,MB,MI,MS) _O_r_X (0xf6
,_b100 ,MD,MB,MI,MS )
+
+#define MULWr(RS) _wO_Mrm (0xf7
,_b11,_b100 ,_r2(RS) )
+#define MULWm(MD,MB,MI,MS) _wO_r_X (0xf7
,_b100 ,MD,MB,MI,MS )
+
+#define MULLr(RS) _O_Mrm (0xf7
,_b11,_b100 ,_r4(RS) )
+#define MULLm(MD,MB,MI,MS) _O_r_X (0xf7
,_b100 ,MD,MB,MI,MS )
+
+
+#define NEGBr(RD) _O_Mrm (0xf6
,_b11,_b011 ,_r1(RD) )
+#define NEGBm(MD,MB,MI,MS) _O_r_X (0xf6
,_b011 ,MD,MB,MI,MS )
+
+#define NEGWr(RD) _wO_Mrm (0xf7
,_b11,_b011 ,_r2(RD) )
+#define NEGWm(MD,MB,MI,MS) _wO_r_X (0xf7
,_b011 ,MD,MB,MI,MS )
+
+#define NEGLr(RD) _O_Mrm (0xf7
,_b11,_b011 ,_r4(RD) )
+#define NEGLm(MD,MB,MI,MS) _O_r_X (0xf7
,_b011 ,MD,MB,MI,MS )
+
+
+#define NOP() _O (0x90
)
+
+
+#define NOTBr(RD) _O_Mrm (0xf6
,_b11,_b010 ,_r1(RD) )
+#define NOTBm(MD,MB,MI,MS) _O_r_X (0xf6
,_b010 ,MD,MB,MI,MS )
+
+#define NOTWr(RD) _wO_Mrm (0xf7
,_b11,_b010 ,_r2(RD) )
+#define NOTWm(MD,MB,MI,MS) _wO_r_X (0xf7
,_b010 ,MD,MB,MI,MS )
+
+#define NOTLr(RD) _O_Mrm (0xf7
,_b11,_b010 ,_r4(RD) )
+#define NOTLm(MD,MB,MI,MS) _O_r_X (0xf7
,_b010 ,MD,MB,MI,MS )
+
+
+#define ORBrr(RS, RD) _O_Mrm (0x08
,_b11,_r1(RS),_r1(RD) )
+#define ORBmr(MD, MB, MI, MS, RD) _O_r_X (0x0a
,_r1(RD) ,MD,MB,MI,MS )
+#define ORBrm(RS, MD, MB, MI, MS) _O_r_X (0x08
,_r1(RS) ,MD,MB,MI,MS )
+#define ORBir(IM, RD) _O_Mrm_B (0x80
,_b11,_b001 ,_r1(RD) ,_su8(IM))
+#define ORBim(IM, MD, MB, MI, MS) _O_r_X_B (0x80
,_b001 ,MD,MB,MI,MS ,_su8(IM))
+
+#define ORWrr(RS, RD) _wO_Mrm (0x09
,_b11,_r2(RS),_r2(RD) )
+#define ORWmr(MD, MB, MI, MS, RD) _wO_r_X (0x0b
,_r2(RD) ,MD,MB,MI,MS )
+#define ORWrm(RS, MD, MB, MI, MS) _wO_r_X (0x09
,_r2(RS) ,MD,MB,MI,MS )
+#define ORWir(IM, RD) _wOs_Mrm_sW (0x81
,_b11,_b001 ,_r2(RD) ,_su16(IM))
+#define ORWim(IM, MD, MB, MI, MS) _wOs_r_X_sW (0x81
,_b001 ,MD,MB,MI,MS ,_su16(IM))
+
+#define ORLrr(RS, RD) _O_Mrm (0x09
,_b11,_r4(RS),_r4(RD) )
+#define ORLmr(MD, MB, MI, MS, RD) _O_r_X (0x0b
,_r4(RD) ,MD,MB,MI,MS )
+#define ORLrm(RS, MD, MB, MI, MS) _O_r_X (0x09
,_r4(RS) ,MD,MB,MI,MS )
+#define ORLir(IM, RD) _Os_Mrm_sL (0x81
,_b11,_b001 ,_r4(RD) ,IM )
+#define ORLim(IM, MD, MB, MI, MS) _Os_r_X_sL (0x81
,_b001 ,MD,MB,MI,MS ,IM )
+
+
+#define POPWr(RD) _wOr (0x58,_r2(RD)
)
+#define POPWm(MD,MB,MI,MS) _wO_r_X (0x8f
,_b000 ,MD,MB,MI,MS )
+
+#define POPLr(RD) _Or (0x58,_r4(RD)
)
+#define POPLm(MD,MB,MI,MS) _O_r_X (0x8f
,_b000 ,MD,MB,MI,MS )
+
+
+#define POPA() _wO (0x61
)
+#define POPAD() _O (0x61
)
+
+#define POPF() _wO (0x9d
)
+#define POPFD() _O (0x9d
)
+
+
+#define PUSHWr(R) _wOr (0x50,_r2(R)
)
+#define PUSHWm(MD,MB,MI,MS) _wO_r_X (0xff,
,_b110 ,MD,MB,MI,MS )
+#define PUSHWi(IM) _wOs_sW (0x68
,IM )
+
+#define PUSHLr(R) _Or (0x50,_r4(R)
)
+#define PUSHLm(MD,MB,MI,MS) _O_r_X (0xff
,_b110 ,MD,MB,MI,MS )
+#define PUSHLi(IM) _Os_sL (0x68
,IM )
+
+
+#define PUSHA() _wO (0x60
)
+#define PUSHAD() _O (0x60
)
+
+#define PUSHF() _O (0x9c
)
+#define PUSHFD() _wO (0x9c
)
+
+#define RET() _O (0xc3
)
+#define RETi(IM) _O_W (0xc2
,_su16(IM))
+
+
+#define ROLBir(IM,RD) (((IM)==1) ? _O_Mrm (0xd0
,_b11,_b000,_r1(RD) ) : \
+ _O_Mrm_B (0xc0
,_b11,_b000,_r1(RD) ,_u8(IM) ) )
+#define ROLBim(IM,MD,MB,MS,MI) (((IM)==1) ? _O_r_X (0xd0
,_b000 ,MD,MB,MI,MS ) : \
+ _O_r_X_B (0xc0
,_b000 ,MD,MB,MI,MS ,_u8(IM) ) )
+#define ROLBrr(RS,RD) (((RS)==_CL) ? _O_Mrm (0xd2
,_b11,_b000,_r1(RD) ) : \
+ JITFAIL ("source
register must be CL" ) )
+#define ROLBrm(RS,MD,MB,MS,MI) (((RS)==_CL) ? _O_r_X (0xd2
,_b000 ,MD,MB,MI,MS ) : \
+ JITFAIL ("source
register must be CL" ) )
+
+#define ROLWir(IM,RD) (((IM)==1) ? _wO_Mrm (0xd1
,_b11,_b000,_r2(RD) ) : \
+ _wO_Mrm_B (0xc1
,_b11,_b000,_r2(RD) ,_u8(IM) ) )
+#define ROLWim(IM,MD,MB,MS,MI) (((IM)==1) ? _wO_r_X (0xd1 ,_b000
,MD,MB,MI,MS ) : \
+ _wO_r_X_B (0xc1
,_b000 ,MD,MB,MI,MS ,_u8(IM) ) )
+#define ROLWrr(RS,RD) (((RS)==_CL) ? _wO_Mrm (0xd3
,_b11,_b000,_r2(RD) ) : \
+ JITFAIL ("source register must
be CL" ) )
+#define ROLWrm(RS,MD,MB,MS,MI) (((RS)==_CL) ? _wO_r_X (0xd3 ,_b000
,MD,MB,MI,MS ) : \
+ JITFAIL ("source register must
be CL" ) )
+
+#define ROLLir(IM,RD) (((IM)==1) ? _O_Mrm (0xd1
,_b11,_b000,_r4(RD) ) : \
+ _O_Mrm_B (0xc1
,_b11,_b000,_r4(RD) ,_u8(IM) ) )
+#define ROLLim(IM,MD,MB,MS,MI) (((IM)==1) ? _O_r_X (0xd1
,_b000 ,MD,MB,MI,MS ) : \
+ _O_r_X_B (0xc1
,_b000 ,MD,MB,MI,MS ,_u8(IM) ) )
+#define ROLLrr(RS,RD) (((RS)==_CL) ? _O_Mrm (0xd3
,_b11,_b000,_r4(RD) ) : \
+ JITFAIL ("source
register must be CL" ) )
+#define ROLLrm(RS,MD,MB,MS,MI) (((RS)==_CL) ? _O_r_X (0xd3
,_b000 ,MD,MB,MI,MS ) : \
+ JITFAIL ("source
register must be CL" ) )
+
+
+#define RORBir(IM,RD) (((IM)==1) ? _O_Mrm (0xd0
,_b11,_b001,_r1(RD) ) : \
+ _O_Mrm_B (0xc0
,_b11,_b001,_r1(RD) ,_u8(IM) ) )
+#define RORBim(IM,MD,MB,MS,MI) (((IM)==1) ? _O_r_X (0xd0
,_b001 ,MD,MB,MI,MS ) : \
+ _O_r_X_B (0xc0
,_b001 ,MD,MB,MI,MS ,_u8(IM) ) )
+#define RORBrr(RS,RD) (((RS)==_CL) ? _O_Mrm (0xd2
,_b11,_b001,_r1(RD) ) : \
+ JITFAIL ("source
register must be CL" ) )
+#define RORBrm(RS,MD,MB,MS,MI) (((RS)==_CL) ? _O_r_X (0xd2
,_b001 ,MD,MB,MI,MS ) : \
+ JITFAIL ("source
register must be CL" ) )
+
+#define RORWir(IM,RD) (((IM)==1) ? _wO_Mrm (0xd1
,_b11,_b001,_r2(RD) ) : \
+ _wO_Mrm_B (0xc1
,_b11,_b001,_r2(RD) ,_u8(IM) ) )
+#define RORWim(IM,MD,MB,MS,MI) (((IM)==1) ? _wO_r_X (0xd1 ,_b001
,MD,MB,MI,MS ) : \
+ _wO_r_X_B (0xc1
,_b001 ,MD,MB,MI,MS ,_u8(IM) ) )
+#define RORWrr(RS,RD) (((RS)==_CL) ? _wO_Mrm (0xd3
,_b11,_b001,_r2(RD) ) : \
+ JITFAIL ("source register must
be CL" ) )
+#define RORWrm(RS,MD,MB,MS,MI) (((RS)==_CL) ? _wO_r_X (0xd3 ,_b001
,MD,MB,MI,MS ) : \
+ JITFAIL ("source register must
be CL" ) )
+
+#define RORLir(IM,RD) (((IM)==1) ? _O_Mrm (0xd1
,_b11,_b001,_r4(RD) ) : \
+ _O_Mrm_B (0xc1
,_b11,_b001,_r4(RD) ,_u8(IM) ) )
+#define RORLim(IM,MD,MB,MS,MI) (((IM)==1) ? _O_r_X (0xd1
,_b001 ,MD,MB,MI,MS ) : \
+ _O_r_X_B (0xc1
,_b001 ,MD,MB,MI,MS ,_u8(IM) ) )
+#define RORLrr(RS,RD) (((RS)==_CL) ? _O_Mrm (0xd3
,_b11,_b001,_r4(RD) ) : \
+ JITFAIL ("source
register must be CL" ) )
+#define RORLrm(RS,MD,MB,MS,MI) (((RS)==_CL) ? _O_r_X (0xd3
,_b001 ,MD,MB,MI,MS ) : \
+ JITFAIL ("source
register must be CL" ) )
+
+
+#define SAHF() _O (0x9e
)
+
+
+#define SALBir SHLBir
+#define SALBim SHLBim
+#define SALBrr SHLBrr
+#define SALBrm SHLBrm
+#define SALWir SHLWir
+#define SALWim SHLWim
+#define SALWrr SHLWrr
+#define SALWrm SHLWrm
+#define SALLir SHLLir
+#define SALLim SHLLim
+#define SALLrr SHLLrr
+#define SALLrm SHLLrm
+
+
+#define SARBir(IM,RD) (((IM)==1) ? _O_Mrm (0xd0
,_b11,_b111,_r1(RD) ) : \
+ _O_Mrm_B (0xc0
,_b11,_b111,_r1(RD) ,_u8(IM) ) )
+#define SARBim(IM,MD,MB,MS,MI) (((IM)==1) ? _O_r_X (0xd0
,_b111 ,MD,MB,MI,MS ) : \
+ _O_r_X_B (0xc0
,_b111 ,MD,MB,MI,MS ,_u8(IM) ) )
+#define SARBrr(RS,RD) (((RS)==_CL) ? _O_Mrm (0xd2
,_b11,_b111,_r1(RD) ) : \
+ JITFAIL ("source
register must be CL" ) )
+#define SARBrm(RS,MD,MB,MS,MI) (((RS)==_CL) ? _O_r_X (0xd2
,_b111 ,MD,MB,MI,MS ) : \
+ JITFAIL ("source
register must be CL" ) )
+
+#define SARWir(IM,RD) (((IM)==1) ? _wO_Mrm (0xd1
,_b11,_b111,_r2(RD) ) : \
+ _wO_Mrm_B (0xc1
,_b11,_b111,_r2(RD) ,_u8(IM) ) )
+#define SARWim(IM,MD,MB,MS,MI) (((IM)==1) ? _wO_r_X (0xd1 ,_b111
,MD,MB,MI,MS ) : \
+ _wO_r_X_B (0xc1
,_b111 ,MD,MB,MI,MS ,_u8(IM) ) )
+#define SARWrr(RS,RD) (((RS)==_CL) ? _wO_Mrm (0xd3
,_b11,_b111,_r2(RD) ) : \
+ JITFAIL ("source register must
be CL" ) )
+#define SARWrm(RS,MD,MB,MS,MI) (((RS)==_CL) ? _wO_r_X (0xd3 ,_b111
,MD,MB,MI,MS ) : \
+ JITFAIL ("source register must
be CL" ) )
+
+#define SARLir(IM,RD) (((IM)==1) ? _O_Mrm (0xd1
,_b11,_b111,_r4(RD) ) : \
+ _O_Mrm_B (0xc1
,_b11,_b111,_r4(RD) ,_u8(IM) ) )
+#define SARLim(IM,MD,MB,MS,MI) (((IM)==1) ? _O_r_X (0xd1
,_b111 ,MD,MB,MI,MS ) : \
+ _O_r_X_B (0xc1
,_b111 ,MD,MB,MI,MS ,_u8(IM) ) )
+#define SARLrr(RS,RD) (((RS)==_CL) ? _O_Mrm (0xd3
,_b11,_b111,_r4(RD) ) : \
+ JITFAIL ("source
register must be CL" ) )
+#define SARLrm(RS,MD,MB,MS,MI) (((RS)==_CL) ? _O_r_X (0xd3
,_b111 ,MD,MB,MI,MS ) : \
+ JITFAIL ("source
register must be CL" ) )
+
+
+#define SBBBrr(RS, RD) _O_Mrm (0x18
,_b11,_r1(RS),_r1(RD) )
+#define SBBBmr(MD, MB, MI, MS, RD) _O_r_X (0x1a
,_r1(RD) ,MD,MB,MI,MS )
+#define SBBBrm(RS, MD, MB, MI, MS) _O_r_X (0x18
,_r1(RS) ,MD,MB,MI,MS )
+#define SBBBir(IM, RD) _O_Mrm_B (0x80
,_b11,_b011 ,_r1(RD) ,_su8(IM))
+#define SBBBim(IM, MD, MB, MI, MS) _O_r_X_B (0x80
,_b011 ,MD,MB,MI,MS ,_su8(IM))
+
+#define SBBWrr(RS, RD) _wO_Mrm (0x19
,_b11,_r2(RS),_r2(RD) )
+#define SBBWmr(MD, MB, MI, MS, RD) _wO_r_X (0x1b
,_r2(RD) ,MD,MB,MI,MS )
+#define SBBWrm(RS, MD, MB, MI, MS) _wO_r_X (0x19
,_r2(RS) ,MD,MB,MI,MS )
+#define SBBWir(IM, RD) _wOs_Mrm_sW (0x81
,_b11,_b011 ,_r2(RD) ,_su16(IM))
+#define SBBWim(IM, MD, MB, MI, MS) _wOs_r_X_sW (0x81
,_b011 ,MD,MB,MI,MS ,_su16(IM))
+
+#define SBBLrr(RS, RD) _O_Mrm (0x19
,_b11,_r4(RS),_r4(RD) )
+#define SBBLmr(MD, MB, MI, MS, RD) _O_r_X (0x1b
,_r4(RD) ,MD,MB,MI,MS )
+#define SBBLrm(RS, MD, MB, MI, MS) _O_r_X (0x19
,_r4(RS) ,MD,MB,MI,MS )
+#define SBBLir(IM, RD) _Os_Mrm_sL (0x81
,_b11,_b011 ,_r4(RD) ,IM )
+#define SBBLim(IM, MD, MB, MI, MS) _Os_r_X_sL (0x81
,_b011 ,MD,MB,MI,MS ,IM )
+
+
+#define SETCCir(CC,RD) _OO_Mrm (0x0f90|(CC)
,_b11,_b000,_r1(RD) )
+
+#define SETOr(RD) SETCCir(0x0,RD)
+#define SETNOr(RD) SETCCir(0x1,RD)
+#define SETBr(RD) SETCCir(0x2,RD)
+#define SETNAEr(RD) SETCCir(0x2,RD)
+#define SETNBr(RD) SETCCir(0x3,RD)
+#define SETAEr(RD) SETCCir(0x3,RD)
+#define SETEr(RD) SETCCir(0x4,RD)
+#define SETZr(RD) SETCCir(0x4,RD)
+#define SETNEr(RD) SETCCir(0x5,RD)
+#define SETNZr(RD) SETCCir(0x5,RD)
+#define SETBEr(RD) SETCCir(0x6,RD)
+#define SETNAr(RD) SETCCir(0x6,RD)
+#define SETNBEr(RD) SETCCir(0x7,RD)
+#define SETAr(RD) SETCCir(0x7,RD)
+#define SETSr(RD) SETCCir(0x8,RD)
+#define SETNSr(RD) SETCCir(0x9,RD)
+#define SETPr(RD) SETCCir(0xa,RD)
+#define SETPEr(RD) SETCCir(0xa,RD)
+#define SETNPr(RD) SETCCir(0xb,RD)
+#define SETPOr(RD) SETCCir(0xb,RD)
+#define SETLr(RD) SETCCir(0xc,RD)
+#define SETNGEr(RD) SETCCir(0xc,RD)
+#define SETNLr(RD) SETCCir(0xd,RD)
+#define SETGEr(RD) SETCCir(0xd,RD)
+#define SETLEr(RD) SETCCir(0xe,RD)
+#define SETNGr(RD) SETCCir(0xe,RD)
+#define SETNLEr(RD) SETCCir(0xf,RD)
+#define SETGr(RD) SETCCir(0xf,RD)
+
+#define SETCCim(CC,MD,MB,MI,MS) _OO_r_X (0x0f90|(CC)
,_b000 ,MD,MB,MI,MS )
+
+#define SETOm(D,B,I,S) SETCCim(0x0,D,B,I,S)
+#define SETNOm(D,B,I,S) SETCCim(0x1,D,B,I,S)
+#define SETBm(D,B,I,S) SETCCim(0x2,D,B,I,S)
+#define SETNAEm(D,B,I,S) SETCCim(0x2,D,B,I,S)
+#define SETNBm(D,B,I,S) SETCCim(0x3,D,B,I,S)
+#define SETAEm(D,B,I,S) SETCCim(0x3,D,B,I,S)
+#define SETEm(D,B,I,S) SETCCim(0x4,D,B,I,S)
+#define SETZm(D,B,I,S) SETCCim(0x4,D,B,I,S)
+#define SETNEm(D,B,I,S) SETCCim(0x5,D,B,I,S)
+#define SETNZm(D,B,I,S) SETCCim(0x5,D,B,I,S)
+#define SETBEm(D,B,I,S) SETCCim(0x6,D,B,I,S)
+#define SETNAm(D,B,I,S) SETCCim(0x6,D,B,I,S)
+#define SETNBEm(D,B,I,S) SETCCim(0x7,D,B,I,S)
+#define SETAm(D,B,I,S) SETCCim(0x7,D,B,I,S)
+#define SETSm(D,B,I,S) SETCCim(0x8,D,B,I,S)
+#define SETNSm(D,B,I,S) SETCCim(0x9,D,B,I,S)
+#define SETPm(D,B,I,S) SETCCim(0xa,D,B,I,S)
+#define SETPEm(D,B,I,S) SETCCim(0xa,D,B,I,S)
+#define SETNPm(D,B,I,S) SETCCim(0xb,D,B,I,S)
+#define SETPOm(D,B,I,S) SETCCim(0xb,D,B,I,S)
+#define SETLm(D,B,I,S) SETCCim(0xc,D,B,I,S)
+#define SETNGEm(D,B,I,S) SETCCim(0xc,D,B,I,S)
+#define SETNLm(D,B,I,S) SETCCim(0xd,D,B,I,S)
+#define SETGEm(D,B,I,S) SETCCim(0xd,D,B,I,S)
+#define SETLEm(D,B,I,S) SETCCim(0xe,D,B,I,S)
+#define SETNGm(D,B,I,S) SETCCim(0xe,D,B,I,S)
+#define SETNLEm(D,B,I,S) SETCCim(0xf,D,B,I,S)
+#define SETGm(D,B,I,S) SETCCim(0xf,D,B,I,S)
+
+
+#define SHLBir(IM,RD) (((IM)==1) ? _O_Mrm (0xd0
,_b11,_b100,_r1(RD) ) : \
+ _O_Mrm_B (0xc0
,_b11,_b100,_r1(RD) ,_u8(IM) ) )
+#define SHLBim(IM,MD,MB,MS,MI) (((IM)==1) ? _O_r_X (0xd0
,_b100 ,MD,MB,MI,MS ) : \
+ _O_r_X_B (0xc0
,_b100 ,MD,MB,MI,MS ,_u8(IM) ) )
+#define SHLBrr(RS,RD) (((RS)==_CL) ? _O_Mrm (0xd2
,_b11,_b100,_r1(RD) ) : \
+ JITFAIL ("source
register must be CL" ) )
+#define SHLBrm(RS,MD,MB,MS,MI) (((RS)==_CL) ? _O_r_X (0xd2
,_b100 ,MD,MB,MI,MS ) : \
+ JITFAIL ("source
register must be CL" ) )
+
+#define SHLWir(IM,RD) (((IM)==1) ? _wO_Mrm (0xd1
,_b11,_b100,_r2(RD) ) : \
+ _wO_Mrm_B (0xc1
,_b11,_b100,_r2(RD) ,_u8(IM) ) )
+#define SHLWim(IM,MD,MB,MS,MI) (((IM)==1) ? _wO_r_X (0xd1
,_b100 ,MD,MB,MI,MS ) : \
+ _wO_r_X_B (0xc1
,_b100 ,MD,MB,MI,MS ,_u8(IM) ) )
+#define SHLWrr(RS,RD) (((RS)==_CL) ? _wO_Mrm (0xd3
,_b11,_b100,_r2(RD) ) : \
+ JITFAIL ("source
register must be CL" ) )
+#define SHLWrm(RS,MD,MB,MS,MI) (((RS)==_CL) ? _wO_r_X (0xd3
,_b100 ,MD,MB,MI,MS ) : \
+ JITFAIL ("source
register must be CL" ) )
+
+#define SHLLir(IM,RD) (((IM)==1) ? _O_Mrm (0xd1
,_b11,_b100,_r4(RD) ) : \
+ _O_Mrm_B (0xc1
,_b11,_b100,_r4(RD) ,_u8(IM) ) )
+#define SHLLim(IM,MD,MB,MS,MI) (((IM)==1) ? _O_r_X (0xd1
,_b100 ,MD,MB,MI,MS ) : \
+ _O_r_X_B (0xc1
,_b100 ,MD,MB,MI,MS ,_u8(IM) ) )
+#define SHLLrr(RS,RD) (((RS)==_CL) ? _O_Mrm (0xd3
,_b11,_b100,_r4(RD) ) : \
+ JITFAIL ("source
register must be CL" ) )
+#define SHLLrm(RS,MD,MB,MS,MI) (((RS)==_CL) ? _O_r_X (0xd3
,_b100 ,MD,MB,MI,MS ) : \
+ JITFAIL ("source
register must be CL" ) )
+
+
+#define SHRBir(IM,RD) (((IM)==1) ? _O_Mrm (0xd0
,_b11,_b101,_r1(RD) ) : \
+ _O_Mrm_B (0xc0
,_b11,_b101,_r1(RD) ,_u8(IM) ) )
+#define SHRBim(IM,MD,MB,MS,MI) (((IM)==1) ? _O_r_X (0xd0
,_b101 ,MD,MB,MI,MS ) : \
+ _O_r_X_B (0xc0
,_b101 ,MD,MB,MI,MS ,_u8(IM) ) )
+#define SHRBrr(RS,RD) (((RS)==_CL) ? _O_Mrm (0xd2
,_b11,_b101,_r1(RD) ) : \
+ JITFAIL ("source
register must be CL" ) )
+#define SHRBrm(RS,MD,MB,MS,MI) (((RS)==_CL) ? _O_r_X (0xd2
,_b101 ,MD,MB,MI,MS ) : \
+ JITFAIL ("source
register must be CL" ) )
+
+#define SHRWir(IM,RD) (((IM)==1) ? _wO_Mrm (0xd1
,_b11,_b101,_r2(RD) ) : \
+ _wO_Mrm_B (0xc1
,_b11,_b101,_r2(RD) ,_u8(IM) ) )
+#define SHRWim(IM,MD,MB,MS,MI) (((IM)==1) ? _wO_r_X (0xd1
,_b101 ,MD,MB,MI,MS ) : \
+ _wO_r_X_B (0xc1
,_b101 ,MD,MB,MI,MS ,_u8(IM) ) )
+#define SHRWrr(RS,RD) (((RS)==_CL) ? _wO_Mrm (0xd3
,_b11,_b101,_r2(RD) ) : \
+ JITFAIL ("source
register must be CL" ) )
+#define SHRWrm(RS,MD,MB,MS,MI) (((RS)==_CL) ? _wO_r_X (0xd3
,_b101 ,MD,MB,MI,MS ) : \
+ JITFAIL ("source
register must be CL" ) )
+
+#define SHRLir(IM,RD) (((IM)==1) ? _O_Mrm (0xd1
,_b11,_b101,_r4(RD) ) : \
+ _O_Mrm_B (0xc1
,_b11,_b101,_r4(RD) ,_u8(IM) ) )
+#define SHRLim(IM,MD,MB,MS,MI) (((IM)==1) ? _O_r_X (0xd1
,_b101 ,MD,MB,MI,MS ) : \
+ _O_r_X_B (0xc1
,_b101 ,MD,MB,MI,MS ,_u8(IM) ) )
+#define SHRLrr(RS,RD) (((RS)==_CL) ? _O_Mrm (0xd3
,_b11,_b101,_r4(RD) ) : \
+ JITFAIL ("source
register must be CL" ) )
+#define SHRLrm(RS,MD,MB,MS,MI) (((RS)==_CL) ? _O_r_X (0xd3
,_b101 ,MD,MB,MI,MS ) : \
+ JITFAIL ("source
register must be CL" ) )
+
+
+#define STC() _O (0xf9
)
+
+
+#define SUBBrr(RS, RD) _O_Mrm (0x28
,_b11,_r1(RS),_r1(RD) )
+#define SUBBmr(MD, MB, MI, MS, RD) _O_r_X (0x2a
,_r1(RD) ,MD,MB,MI,MS )
+#define SUBBrm(RS, MD, MB, MI, MS) _O_r_X (0x28
,_r1(RS) ,MD,MB,MI,MS )
+#define SUBBir(IM, RD) _O_Mrm_B (0x80
,_b11,_b101 ,_r1(RD) ,_su8(IM))
+#define SUBBim(IM, MD, MB, MI, MS) _O_r_X_B (0x80
,_b101 ,MD,MB,MI,MS ,_su8(IM))
+
+#define SUBWrr(RS, RD) _wO_Mrm (0x29
,_b11,_r2(RS),_r2(RD) )
+#define SUBWmr(MD, MB, MI, MS, RD) _wO_r_X (0x2b
,_r2(RD) ,MD,MB,MI,MS )
+#define SUBWrm(RS, MD, MB, MI, MS) _wO_r_X (0x29
,_r2(RS) ,MD,MB,MI,MS )
+#define SUBWir(IM, RD) _wOs_Mrm_sW (0x81
,_b11,_b101 ,_r2(RD) ,_su16(IM))
+#define SUBWim(IM, MD, MB, MI, MS) _wOs_r_X_sW (0x81
,_b101 ,MD,MB,MI,MS ,_su16(IM))
+
+#define SUBLrr(RS, RD) _O_Mrm (0x29
,_b11,_r4(RS),_r4(RD) )
+#define SUBLmr(MD, MB, MI, MS, RD) _O_r_X (0x2b
,_r4(RD) ,MD,MB,MI,MS )
+#define SUBLrm(RS, MD, MB, MI, MS) _O_r_X (0x29
,_r4(RS) ,MD,MB,MI,MS )
+#define SUBLir(IM, RD) _Os_Mrm_sL (0x81
,_b11,_b101 ,_r4(RD) ,IM )
+#define SUBLim(IM, MD, MB, MI, MS) _Os_r_X_sL (0x81
,_b101 ,MD,MB,MI,MS ,IM )
+
+
+#define TESTBrr(RS, RD) _O_Mrm (0x84
,_b11,_r1(RS),_r1(RD) )
+#define TESTBrm(RS, MD, MB, MI, MS) _O_r_X (0x84
,_r1(RS) ,MD,MB,MI,MS )
+#define TESTBir(IM, RD) _O_Mrm_B (0xf6
,_b11,_b000 ,_r1(RD) ,_u8(IM))
+#define TESTBim(IM, MD, MB, MI, MS) _O_r_X_B (0xf6
,_b000 ,MD,MB,MI,MS ,_u8(IM))
+
+#define TESTWrr(RS, RD) _wO_Mrm (0x85
,_b11,_r2(RS),_r2(RD) )
+#define TESTWrm(RS, MD, MB, MI, MS) _wO_r_X (0x85
,_r2(RS) ,MD,MB,MI,MS )
+#define TESTWir(IM, RD) _wO_Mrm_W (0xf7
,_b11,_b000 ,_r2(RD) ,_u16(IM))
+#define TESTWim(IM, MD, MB, MI, MS) _wO_r_X_W (0xf7
,_b000 ,MD,MB,MI,MS ,_u16(IM))
+
+#define TESTLrr(RS, RD) _O_Mrm (0x85
,_b11,_r4(RS),_r4(RD) )
+#define TESTLrm(RS, MD, MB, MI, MS) _O_r_X (0x85
,_r4(RS) ,MD,MB,MI,MS )
+#define TESTLir(IM, RD) _O_Mrm_L (0xf7
,_b11,_b000 ,_r4(RD) ,IM )
+#define TESTLim(IM, MD, MB, MI, MS) _O_r_X_L (0xf7
,_b000 ,MD,MB,MI,MS ,IM )
+
+
+#define XADDBrr(RS,RD) _OO_Mrm (0x0fc0
,_b11,_r1(RS),_r1(RD) )
+#define XADDBrm(RS,MD,MB,MI,MS) _OO_r_X (0x0fc0
,_r1(RS) ,MD,MB,MI,MS )
+
+#define XADDWrr(RS,RD) _wOO_Mrm (0x0fc1
,_b11,_r2(RS),_r2(RD) )
+#define XADDWrm(RS,MD,MB,MI,MS) _wOO_r_X (0x0fc1
,_r2(RS) ,MD,MB,MI,MS )
+
+#define XADDLrr(RS,RD) _OO_Mrm (0x0fc1
,_b11,_r4(RS),_r4(RD) )
+#define XADDLrm(RS,MD,MB,MI,MS) _OO_r_X (0x0fc1
,_r4(RS) ,MD,MB,MI,MS )
+
+
+#define XCHGBrr(RS,RD) _O_Mrm (0x86
,_b11,_r1(RS),_r1(RD) )
+#define XCHGBrm(RS,MD,MB,MI,MS) _O_r_X (0x86
,_r1(RS) ,MD,MB,MI,MS )
+
+#define XCHGWrr(RS,RD) _wO_Mrm (0x87
,_b11,_r2(RS),_r2(RD) )
+#define XCHGWrm(RS,MD,MB,MI,MS) _wO_r_X (0x87
,_r2(RS) ,MD,MB,MI,MS )
+
+#define XCHGLrr(RS,RD) _O_Mrm (0x87
,_b11,_r4(RS),_r4(RD) )
+#define XCHGLrm(RS,MD,MB,MI,MS) _O_r_X (0x87
,_r4(RS) ,MD,MB,MI,MS )
+
+
+#define XORBrr(RS, RD) _O_Mrm (0x30
,_b11,_r1(RS),_r1(RD) )
+#define XORBmr(MD, MB, MI, MS, RD) _O_r_X (0x32
,_r1(RD) ,MD,MB,MI,MS )
+#define XORBrm(RS, MD, MB, MI, MS) _O_r_X (0x30
,_r1(RS) ,MD,MB,MI,MS )
+#define XORBir(IM, RD) _O_Mrm_B (0x80
,_b11,_b110 ,_r1(RD) ,_su8(IM))
+#define XORBim(IM, MD, MB, MI, MS) _O_r_X_B (0x80
,_b110 ,MD,MB,MI,MS ,_su8(IM))
+
+#define XORWrr(RS, RD) _wO_Mrm (0x31
,_b11,_r2(RS),_r2(RD) )
+#define XORWmr(MD, MB, MI, MS, RD) _wO_r_X (0x33
,_r2(RD) ,MD,MB,MI,MS )
+#define XORWrm(RS, MD, MB, MI, MS) _wO_r_X (0x31
,_r2(RS) ,MD,MB,MI,MS )
+#define XORWir(IM, RD) _wOs_Mrm_sW (0x81
,_b11,_b110 ,_r2(RD) ,_su16(IM))
+#define XORWim(IM, MD, MB, MI, MS) _wOs_r_X_sW (0x81
,_b110 ,MD,MB,MI,MS ,_su16(IM))
+
+#define XORLrr(RS, RD) _O_Mrm (0x31
,_b11,_r4(RS),_r4(RD) )
+#define XORLmr(MD, MB, MI, MS, RD) _O_r_X (0x33
,_r4(RD) ,MD,MB,MI,MS )
+#define XORLrm(RS, MD, MB, MI, MS) _O_r_X (0x31
,_r4(RS) ,MD,MB,MI,MS )
+#define XORLir(IM, RD) _Os_Mrm_sL (0x81
,_b11,_b110 ,_r4(RD) ,IM )
+#define XORLim(IM, MD, MB, MI, MS) _Os_r_X_sL (0x81
,_b110 ,MD,MB,MI,MS ,IM )
+
+/* x87 instructions -- yay, we found a use for octal constants :-) */
+
+#define ESCmi(D,B,I,S,OP) _O_r_X(0xd8|(OP >> 3), (OP & 7), D,B,I,S)
+#define ESCri(RD,OP) _O_Mrm(0xd8|(OP >> 3), _b11, (OP & 7), RD)
+
+#define ESCrri(RS,RD,OP) ((RS) = _ST0 ? ESCri(RD,(OP|040))
\
+ : (RD) = _ST0 ? ESCri(RS,OP)
\
+ : JITFAIL ("coprocessor instruction without
st0"))
+
+#define FLDSm(D,B,I,S) ESCmi(D,B,I,S,010) /* fld m32real */
+#define FILDLm(D,B,I,S) ESCmi(D,B,I,S,030) /* fild m32int
*/
+#define FLDLm(D,B,I,S) ESCmi(D,B,I,S,050) /* fld m64real */
+#define FILDWm(D,B,I,S) ESCmi(D,B,I,S,070) /* fild m16int
*/
+#define FSTSm(D,B,I,S) ESCmi(D,B,I,S,012) /* fst m32real */
+#define FISTLm(D,B,I,S) ESCmi(D,B,I,S,032) /* fist m32int
*/
+#define FSTLm(D,B,I,S) ESCmi(D,B,I,S,052) /* fst m64real */
+#define FISTWm(D,B,I,S) ESCmi(D,B,I,S,072) /* fist m16int
*/
+#define FSTPSm(D,B,I,S) ESCmi(D,B,I,S,013) /* fstp m32real
*/
+#define FISTPLm(D,B,I,S) ESCmi(D,B,I,S,033) /* fistp m32int */
+#define FSTPLm(D,B,I,S) ESCmi(D,B,I,S,053) /* fstp m64real
*/
+#define FISTPWm(D,B,I,S) ESCmi(D,B,I,S,073) /* fistp m16int */
+#define FLDTm(D,B,I,S) ESCmi(D,B,I,S,035) /* fld m80real */
+#define FILDQm(D,B,I,S) ESCmi(D,B,I,S,075) /* fild m64int
*/
+#define FSTPTm(D,B,I,S) ESCmi(D,B,I,S,037) /* fstp m80real
*/
+#define FISTPQm(D,B,I,S) ESCmi(D,B,I,S,077) /* fistp m64int */
+
+#define FADDrr(RS,RD) ESCrri(RS,RD,000)
+#define FMULrr(RS,RD) ESCrri(RS,RD,001)
+#define FSUBrr(RS,RD) ESCrri(RS,RD,004)
+#define FSUBRrr(RS,RD) ESCrri(RS,RD,005)
+#define FDIVrr(RS,RD) ESCrri(RS,RD,006)
+#define FDIVRrr(RS,RD) ESCrri(RS,RD,007)
+
+#define FLDr(RD) ESCri(RD,010)
+#define FXCHr(RD) ESCri(RD,011)
+#define FFREEr(RD) ESCri(RD,050)
+#define FSTr(RD) ESCri(RD,052)
+#define FSTPr(RD) ESCri(RD,053)
+#define FCOMr(RD) ESCri(RD,002)
+#define FCOMPr(RD) ESCri(RD,003)
+#define FCOMIr(RD) ESCri(RD,036)
+#define FCOMIPr(RD) ESCri(RD,076)
+#define FUCOMr(RD) ESCri(RD,054)
+#define FUCOMPr(RD) ESCri(RD,055)
+#define FUCOMIr(RD) ESCri(RD,035)
+#define FUCOMIPr(RD) ESCri(RD,075)
+#define FADDPr(RD) ESCri(RD,060)
+#define FMULPr(RD) ESCri(RD,061)
+#define FSUBPr(RD) ESCri(RD,064)
+#define FSUBRPr(RD) ESCri(RD,065)
+#define FDIVPr(RD) ESCri(RD,066)
+#define FDIVRPr(RD) ESCri(RD,067)
+
+#define FNSTSWr(RD) ((RD == _AX || RD == _EAX) ? _OO (0xdfe0)
\
+ : JITFAIL ("AX or EAX expected"))
+/* N byte NOPs */
+#define _NOPi(N) ((( (N) >= 8) ?
(_jit_B(0x8d),_jit_B(0xb4),_jit_B(0x26),_jit_L(0x00),_jit_B(0x90)) : (void) 0),
\
+ (( ((N)&7) == 7) ?
(_jit_B(0x8d),_jit_B(0xb4),_jit_B(0x26),_jit_L(0x00)) : \
+ ( ((N)&7) == 6) ?
(_jit_B(0x8d),_jit_B(0xb6),_jit_L(0x00)) : \
+ ( ((N)&7) == 5) ?
(_jit_B(0x90),_jit_B(0x8d),_jit_B(0x74),_jit_B(0x26),_jit_B(0x00)) : \
+/* leal 0(,%esi), %esi */ ( ((N)&7) == 4) ?
(_jit_B(0x8d),_jit_B(0x74),_jit_B(0x26),_jit_B(0x00)) : \
+/* leal (,%esi), %esi */ ( ((N)&7) == 3) ?
(_jit_B(0x8d),_jit_B(0x76),_jit_B(0x00)) : \
+/* movl %esi, %esi */ ( ((N)&7) == 2) ? (_jit_B(0x89),_jit_B(0xf6)) : \
+ ( ((N)&7) == 1) ? (_jit_B(0x90)) : \
+ ( ((N)&7) == 0) ? 0 : \
+ JITFAIL(".align argument too large")))
+
+
+/*** References:
*/
+/*
*/
+/* [1] "Intel Architecture Software Developer's Manual Volume 1: Basic
Architecture", */
+/* Intel Corporation 1997.
*/
+/*
*/
+/* [2] "Intel Architecture Software Developer's Manual Volume 2: Instruction
Set Reference", */
+/* Intel Corporation 1997.
*/
+
+#endif /* __lightning_asm_h */
+
diff --git a/lightning/i386/core.h b/lightning/i386/core.h
new file mode 100644
index 0000000..79f4d64
--- /dev/null
+++ b/lightning/i386/core.h
@@ -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 */
diff --git a/lightning/i386/fp.h b/lightning/i386/fp.h
new file mode 100644
index 0000000..c347e3d
--- /dev/null
+++ b/lightning/i386/fp.h
@@ -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 */
diff --git a/lightning/i386/funcs.h b/lightning/i386/funcs.h
new file mode 100644
index 0000000..a618a85
--- /dev/null
+++ b/lightning/i386/funcs.h
@@ -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 */
diff --git a/lightning/ppc/asm.h b/lightning/ppc/asm.h
new file mode 100644
index 0000000..d102283
--- /dev/null
+++ b/lightning/ppc/asm.h
@@ -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, address@hidden
+ * ori rD, rD, address@hidden ; 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 */
diff --git a/lightning/ppc/core.h b/lightning/ppc/core.h
new file mode 100644
index 0000000..1377e51
--- /dev/null
+++ b/lightning/ppc/core.h
@@ -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 */
diff --git a/lightning/ppc/fp.h b/lightning/ppc/fp.h
new file mode 100644
index 0000000..1767195
--- /dev/null
+++ b/lightning/ppc/fp.h
@@ -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 */
diff --git a/lightning/ppc/funcs.h b/lightning/ppc/funcs.h
new file mode 100644
index 0000000..38b6a65
--- /dev/null
+++ b/lightning/ppc/funcs.h
@@ -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 */
diff --git a/lightning/sparc/asm.h b/lightning/sparc/asm.h
new file mode 100644
index 0000000..808bb4a
--- /dev/null
+++ b/lightning/sparc/asm.h
@@ -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 */
diff --git a/lightning/sparc/core.h b/lightning/sparc/core.h
new file mode 100644
index 0000000..b70259e
--- /dev/null
+++ b/lightning/sparc/core.h
@@ -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 */
diff --git a/lightning/sparc/fp.h b/lightning/sparc/fp.h
new file mode 100644
index 0000000..660af3d
--- /dev/null
+++ b/lightning/sparc/fp.h
@@ -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 */
diff --git a/lightning/sparc/funcs.h b/lightning/sparc/funcs.h
new file mode 100644
index 0000000..8fd9e10
--- /dev/null
+++ b/lightning/sparc/funcs.h
@@ -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 */
diff --git a/lightningize.in b/lightningize.in
new file mode 100644
index 0000000..71d4ba3
--- /dev/null
+++ b/lightningize.in
@@ -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 <address@hidden>, 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
address@hidden@
address@hidden@
+
+# Directory names.
address@hidden@
address@hidden@
address@hidden@
+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:
diff --git a/opcode/Makefile.am b/opcode/Makefile.am
new file mode 100644
index 0000000..198480d
--- /dev/null
+++ b/opcode/Makefile.am
@@ -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
diff --git a/opcode/ansidecl.h b/opcode/ansidecl.h
new file mode 100644
index 0000000..4944cb2
--- /dev/null
+++ b/opcode/ansidecl.h
@@ -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
diff --git a/opcode/bfd.h b/opcode/bfd.h
new file mode 100644
index 0000000..431021e
--- /dev/null
+++ b/opcode/bfd.h
@@ -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
diff --git a/opcode/dis-asm.h b/opcode/dis-asm.h
new file mode 100644
index 0000000..d70bd51
--- /dev/null
+++ b/opcode/dis-asm.h
@@ -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) */
diff --git a/opcode/dis-buf.c b/opcode/dis-buf.c
new file mode 100644
index 0000000..47a2e33
--- /dev/null
+++ b/opcode/dis-buf.c
@@ -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);
+}
diff --git a/opcode/disass.c b/opcode/disass.c
new file mode 100644
index 0000000..71b1d1b
--- /dev/null
+++ b/opcode/disass.c
@@ -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;
+}
+
diff --git a/opcode/i386-dis.c b/opcode/i386-dis.c
new file mode 100644
index 0000000..b781edc
--- /dev/null
+++ b/opcode/i386-dis.c
@@ -0,0 +1,2031 @@
+/* Print i386 instructions for GDB, the GNU debugger.
+ Copyright (C) 1988, 89, 91, 93, 94, 95, 1996 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+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. */
+
+/*
+ * 80386 instruction printer by Pace Willisson (address@hidden)
+ * July 1988
+ * modified by John Hassey (address@hidden)
+ */
+
+/*
+ * The main tables describing the instructions is essentially a copy
+ * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
+ * Programmers Manual. Usually, there is a capital letter, followed
+ * by a small letter. The capital letter tell the addressing mode,
+ * and the small letter tells about the operand size. Refer to
+ * the Intel manual for details.
+ */
+
+#include "dis-asm.h"
+#include "sysdep.h"
+
+#define MAXLEN 20
+
+#include <setjmp.h>
+
+struct dis_private
+{
+ /* Points to first byte not fetched. */
+ bfd_byte *max_fetched;
+ bfd_byte the_buffer[MAXLEN];
+ bfd_vma insn_start;
+ jmp_buf bailout;
+};
+
+/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
+ to ADDR (exclusive) are valid. Returns 1 for success, longjmps
+ on error. */
+#define FETCH_DATA(info, addr) \
+ ((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \
+ ? 1 : fetch_data ((info), (addr)))
+
+static int
+fetch_data (info, addr)
+ struct disassemble_info *info;
+ bfd_byte *addr;
+{
+ int status;
+ struct dis_private *priv = (struct dis_private *)info->private_data;
+ bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
+
+ status = (*info->read_memory_func) (start,
+ priv->max_fetched,
+ addr - priv->max_fetched,
+ info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, start, info);
+ longjmp (priv->bailout, 1);
+ }
+ else
+ priv->max_fetched = addr;
+ return 1;
+}
+
+#define Eb OP_E, b_mode
+#define indirEb OP_indirE, b_mode
+#define Gb OP_G, b_mode
+#define Ev OP_E, v_mode
+#define indirEv OP_indirE, v_mode
+#define Ew OP_E, w_mode
+#define Ma OP_E, v_mode
+#define M OP_E, 0
+#define Mp OP_E, 0 /* ? */
+#define Gv OP_G, v_mode
+#define Gw OP_G, w_mode
+#define Rw OP_rm, w_mode
+#define Rd OP_rm, d_mode
+#define Ib OP_I, b_mode
+#define sIb OP_sI, b_mode /* sign extened byte */
+#define Iv OP_I, v_mode
+#define Iw OP_I, w_mode
+#define Jb OP_J, b_mode
+#define Jv OP_J, v_mode
+#define ONE OP_ONE, 0
+#define Cd OP_C, d_mode
+#define Dd OP_D, d_mode
+#define Td OP_T, d_mode
+
+#define eAX OP_REG, eAX_reg
+#define eBX OP_REG, eBX_reg
+#define eCX OP_REG, eCX_reg
+#define eDX OP_REG, eDX_reg
+#define eSP OP_REG, eSP_reg
+#define eBP OP_REG, eBP_reg
+#define eSI OP_REG, eSI_reg
+#define eDI OP_REG, eDI_reg
+#define AL OP_REG, al_reg
+#define CL OP_REG, cl_reg
+#define DL OP_REG, dl_reg
+#define BL OP_REG, bl_reg
+#define AH OP_REG, ah_reg
+#define CH OP_REG, ch_reg
+#define DH OP_REG, dh_reg
+#define BH OP_REG, bh_reg
+#define AX OP_REG, ax_reg
+#define DX OP_REG, dx_reg
+#define indirDX OP_REG, indir_dx_reg
+
+#define Sw OP_SEG, w_mode
+#define Ap OP_DIR, lptr
+#define Av OP_DIR, v_mode
+#define Ob OP_OFF, b_mode
+#define Ov OP_OFF, v_mode
+#define Xb OP_DSSI, b_mode
+#define Xv OP_DSSI, v_mode
+#define Yb OP_ESDI, b_mode
+#define Yv OP_ESDI, v_mode
+
+#define es OP_REG, es_reg
+#define ss OP_REG, ss_reg
+#define cs OP_REG, cs_reg
+#define ds OP_REG, ds_reg
+#define fs OP_REG, fs_reg
+#define gs OP_REG, gs_reg
+
+int OP_E(), OP_indirE(), OP_G(), OP_I(), OP_sI(), OP_REG();
+int OP_J(), OP_SEG();
+int OP_DIR(), OP_OFF(), OP_DSSI(), OP_ESDI(), OP_ONE(), OP_C();
+int OP_D(), OP_T(), OP_rm();
+
+static void dofloat (), putop (), append_prefix (), set_op ();
+static int get16 (), get32 ();
+
+#define b_mode 1
+#define v_mode 2
+#define w_mode 3
+#define d_mode 4
+
+#define es_reg 100
+#define cs_reg 101
+#define ss_reg 102
+#define ds_reg 103
+#define fs_reg 104
+#define gs_reg 105
+#define eAX_reg 107
+#define eCX_reg 108
+#define eDX_reg 109
+#define eBX_reg 110
+#define eSP_reg 111
+#define eBP_reg 112
+#define eSI_reg 113
+#define eDI_reg 114
+
+#define lptr 115
+
+#define al_reg 116
+#define cl_reg 117
+#define dl_reg 118
+#define bl_reg 119
+#define ah_reg 120
+#define ch_reg 121
+#define dh_reg 122
+#define bh_reg 123
+
+#define ax_reg 124
+#define cx_reg 125
+#define dx_reg 126
+#define bx_reg 127
+#define sp_reg 128
+#define bp_reg 129
+#define si_reg 130
+#define di_reg 131
+
+#define indir_dx_reg 150
+
+#define GRP1b NULL, NULL, 0
+#define GRP1S NULL, NULL, 1
+#define GRP1Ss NULL, NULL, 2
+#define GRP2b NULL, NULL, 3
+#define GRP2S NULL, NULL, 4
+#define GRP2b_one NULL, NULL, 5
+#define GRP2S_one NULL, NULL, 6
+#define GRP2b_cl NULL, NULL, 7
+#define GRP2S_cl NULL, NULL, 8
+#define GRP3b NULL, NULL, 9
+#define GRP3S NULL, NULL, 10
+#define GRP4 NULL, NULL, 11
+#define GRP5 NULL, NULL, 12
+#define GRP6 NULL, NULL, 13
+#define GRP7 NULL, NULL, 14
+#define GRP8 NULL, NULL, 15
+#define GRP9 NULL, NULL, 16
+
+#define FLOATCODE 50
+#define FLOAT NULL, NULL, FLOATCODE
+
+struct dis386 {
+ char *name;
+ int (*op1)();
+ int bytemode1;
+ int (*op2)();
+ int bytemode2;
+ int (*op3)();
+ int bytemode3;
+};
+
+struct dis386 dis386[] = {
+ /* 00 */
+ { "addb", Eb, Gb },
+ { "addS", Ev, Gv },
+ { "addb", Gb, Eb },
+ { "addS", Gv, Ev },
+ { "addb", AL, Ib },
+ { "addS", eAX, Iv },
+ { "pushl", es },
+ { "popl", es },
+ /* 08 */
+ { "orb", Eb, Gb },
+ { "orS", Ev, Gv },
+ { "orb", Gb, Eb },
+ { "orS", Gv, Ev },
+ { "orb", AL, Ib },
+ { "orS", eAX, Iv },
+ { "pushl", cs },
+ { "(bad)" }, /* 0x0f extended opcode escape */
+ /* 10 */
+ { "adcb", Eb, Gb },
+ { "adcS", Ev, Gv },
+ { "adcb", Gb, Eb },
+ { "adcS", Gv, Ev },
+ { "adcb", AL, Ib },
+ { "adcS", eAX, Iv },
+ { "pushl", ss },
+ { "popl", ss },
+ /* 18 */
+ { "sbbb", Eb, Gb },
+ { "sbbS", Ev, Gv },
+ { "sbbb", Gb, Eb },
+ { "sbbS", Gv, Ev },
+ { "sbbb", AL, Ib },
+ { "sbbS", eAX, Iv },
+ { "pushl", ds },
+ { "popl", ds },
+ /* 20 */
+ { "andb", Eb, Gb },
+ { "andS", Ev, Gv },
+ { "andb", Gb, Eb },
+ { "andS", Gv, Ev },
+ { "andb", AL, Ib },
+ { "andS", eAX, Iv },
+ { "(bad)" }, /* SEG ES prefix */
+ { "daa" },
+ /* 28 */
+ { "subb", Eb, Gb },
+ { "subS", Ev, Gv },
+ { "subb", Gb, Eb },
+ { "subS", Gv, Ev },
+ { "subb", AL, Ib },
+ { "subS", eAX, Iv },
+ { "(bad)" }, /* SEG CS prefix */
+ { "das" },
+ /* 30 */
+ { "xorb", Eb, Gb },
+ { "xorS", Ev, Gv },
+ { "xorb", Gb, Eb },
+ { "xorS", Gv, Ev },
+ { "xorb", AL, Ib },
+ { "xorS", eAX, Iv },
+ { "(bad)" }, /* SEG SS prefix */
+ { "aaa" },
+ /* 38 */
+ { "cmpb", Eb, Gb },
+ { "cmpS", Ev, Gv },
+ { "cmpb", Gb, Eb },
+ { "cmpS", Gv, Ev },
+ { "cmpb", AL, Ib },
+ { "cmpS", eAX, Iv },
+ { "(bad)" }, /* SEG DS prefix */
+ { "aas" },
+ /* 40 */
+ { "incS", eAX },
+ { "incS", eCX },
+ { "incS", eDX },
+ { "incS", eBX },
+ { "incS", eSP },
+ { "incS", eBP },
+ { "incS", eSI },
+ { "incS", eDI },
+ /* 48 */
+ { "decS", eAX },
+ { "decS", eCX },
+ { "decS", eDX },
+ { "decS", eBX },
+ { "decS", eSP },
+ { "decS", eBP },
+ { "decS", eSI },
+ { "decS", eDI },
+ /* 50 */
+ { "pushS", eAX },
+ { "pushS", eCX },
+ { "pushS", eDX },
+ { "pushS", eBX },
+ { "pushS", eSP },
+ { "pushS", eBP },
+ { "pushS", eSI },
+ { "pushS", eDI },
+ /* 58 */
+ { "popS", eAX },
+ { "popS", eCX },
+ { "popS", eDX },
+ { "popS", eBX },
+ { "popS", eSP },
+ { "popS", eBP },
+ { "popS", eSI },
+ { "popS", eDI },
+ /* 60 */
+ { "pusha" },
+ { "popa" },
+ { "boundS", Gv, Ma },
+ { "arpl", Ew, Gw },
+ { "(bad)" }, /* seg fs */
+ { "(bad)" }, /* seg gs */
+ { "(bad)" }, /* op size prefix */
+ { "(bad)" }, /* adr size prefix */
+ /* 68 */
+ { "pushS", Iv }, /* 386 book wrong */
+ { "imulS", Gv, Ev, Iv },
+ { "pushl", sIb }, /* push of byte really pushes 4 bytes */
+ { "imulS", Gv, Ev, Ib },
+ { "insb", Yb, indirDX },
+ { "insS", Yv, indirDX },
+ { "outsb", indirDX, Xb },
+ { "outsS", indirDX, Xv },
+ /* 70 */
+ { "jo", Jb },
+ { "jno", Jb },
+ { "jb", Jb },
+ { "jae", Jb },
+ { "je", Jb },
+ { "jne", Jb },
+ { "jbe", Jb },
+ { "ja", Jb },
+ /* 78 */
+ { "js", Jb },
+ { "jns", Jb },
+ { "jp", Jb },
+ { "jnp", Jb },
+ { "jl", Jb },
+ { "jnl", Jb },
+ { "jle", Jb },
+ { "jg", Jb },
+ /* 80 */
+ { GRP1b },
+ { GRP1S },
+ { "(bad)" },
+ { GRP1Ss },
+ { "testb", Eb, Gb },
+ { "testS", Ev, Gv },
+ { "xchgb", Eb, Gb },
+ { "xchgS", Ev, Gv },
+ /* 88 */
+ { "movb", Eb, Gb },
+ { "movS", Ev, Gv },
+ { "movb", Gb, Eb },
+ { "movS", Gv, Ev },
+ { "movw", Ew, Sw },
+ { "leaS", Gv, M },
+ { "movw", Sw, Ew },
+ { "popS", Ev },
+ /* 90 */
+ { "nop" },
+ { "xchgS", eCX, eAX },
+ { "xchgS", eDX, eAX },
+ { "xchgS", eBX, eAX },
+ { "xchgS", eSP, eAX },
+ { "xchgS", eBP, eAX },
+ { "xchgS", eSI, eAX },
+ { "xchgS", eDI, eAX },
+ /* 98 */
+ { "cwtl" },
+ { "cltd" },
+ { "lcall", Ap },
+ { "(bad)" }, /* fwait */
+ { "pushf" },
+ { "popf" },
+ { "sahf" },
+ { "lahf" },
+ /* a0 */
+ { "movb", AL, Ob },
+ { "movS", eAX, Ov },
+ { "movb", Ob, AL },
+ { "movS", Ov, eAX },
+ { "movsb", Yb, Xb },
+ { "movsS", Yv, Xv },
+ { "cmpsb", Yb, Xb },
+ { "cmpsS", Yv, Xv },
+ /* a8 */
+ { "testb", AL, Ib },
+ { "testS", eAX, Iv },
+ { "stosb", Yb, AL },
+ { "stosS", Yv, eAX },
+ { "lodsb", AL, Xb },
+ { "lodsS", eAX, Xv },
+ { "scasb", AL, Yb },
+ { "scasS", eAX, Yv },
+ /* b0 */
+ { "movb", AL, Ib },
+ { "movb", CL, Ib },
+ { "movb", DL, Ib },
+ { "movb", BL, Ib },
+ { "movb", AH, Ib },
+ { "movb", CH, Ib },
+ { "movb", DH, Ib },
+ { "movb", BH, Ib },
+ /* b8 */
+ { "movS", eAX, Iv },
+ { "movS", eCX, Iv },
+ { "movS", eDX, Iv },
+ { "movS", eBX, Iv },
+ { "movS", eSP, Iv },
+ { "movS", eBP, Iv },
+ { "movS", eSI, Iv },
+ { "movS", eDI, Iv },
+ /* c0 */
+ { GRP2b },
+ { GRP2S },
+ { "ret", Iw },
+ { "ret" },
+ { "lesS", Gv, Mp },
+ { "ldsS", Gv, Mp },
+ { "movb", Eb, Ib },
+ { "movS", Ev, Iv },
+ /* c8 */
+ { "enter", Iw, Ib },
+ { "leave" },
+ { "lret", Iw },
+ { "lret" },
+ { "int3" },
+ { "int", Ib },
+ { "into" },
+ { "iret" },
+ /* d0 */
+ { GRP2b_one },
+ { GRP2S_one },
+ { GRP2b_cl },
+ { GRP2S_cl },
+ { "aam", Ib },
+ { "aad", Ib },
+ { "(bad)" },
+ { "xlat" },
+ /* d8 */
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ /* e0 */
+ { "loopne", Jb },
+ { "loope", Jb },
+ { "loop", Jb },
+ { "jCcxz", Jb },
+ { "inb", AL, Ib },
+ { "inS", eAX, Ib },
+ { "outb", Ib, AL },
+ { "outS", Ib, eAX },
+ /* e8 */
+ { "call", Av },
+ { "jmp", Jv },
+ { "ljmp", Ap },
+ { "jmp", Jb },
+ { "inb", AL, indirDX },
+ { "inS", eAX, indirDX },
+ { "outb", indirDX, AL },
+ { "outS", indirDX, eAX },
+ /* f0 */
+ { "(bad)" }, /* lock prefix */
+ { "(bad)" },
+ { "(bad)" }, /* repne */
+ { "(bad)" }, /* repz */
+ { "hlt" },
+ { "cmc" },
+ { GRP3b },
+ { GRP3S },
+ /* f8 */
+ { "clc" },
+ { "stc" },
+ { "cli" },
+ { "sti" },
+ { "cld" },
+ { "std" },
+ { GRP4 },
+ { GRP5 },
+};
+
+struct dis386 dis386_twobyte[] = {
+ /* 00 */
+ { GRP6 },
+ { GRP7 },
+ { "larS", Gv, Ew },
+ { "lslS", Gv, Ew },
+ { "(bad)" },
+ { "(bad)" },
+ { "clts" },
+ { "(bad)" },
+ /* 08 */
+ { "invd" },
+ { "wbinvd" },
+ { "(bad)" }, { "ud2a" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 10 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 18 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 20 */
+ /* these are all backward in appendix A of the intel book */
+ { "movl", Rd, Cd },
+ { "movl", Rd, Dd },
+ { "movl", Cd, Rd },
+ { "movl", Dd, Rd },
+ { "movl", Rd, Td },
+ { "(bad)" },
+ { "movl", Td, Rd },
+ { "(bad)" },
+ /* 28 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 30 */
+ { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 38 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 40 */
+ { "cmovo", Gv,Ev }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae",
Gv,Ev },
+ { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova",
Gv,Ev },
+ /* 48 */
+ { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp",
Gv,Ev },
+ { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg",
Gv,Ev },
+ /* 50 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 58 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 60 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 68 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 70 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 78 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* 80 */
+ { "jo", Jv },
+ { "jno", Jv },
+ { "jb", Jv },
+ { "jae", Jv },
+ { "je", Jv },
+ { "jne", Jv },
+ { "jbe", Jv },
+ { "ja", Jv },
+ /* 88 */
+ { "js", Jv },
+ { "jns", Jv },
+ { "jp", Jv },
+ { "jnp", Jv },
+ { "jl", Jv },
+ { "jge", Jv },
+ { "jle", Jv },
+ { "jg", Jv },
+ /* 90 */
+ { "seto", Eb },
+ { "setno", Eb },
+ { "setb", Eb },
+ { "setae", Eb },
+ { "sete", Eb },
+ { "setne", Eb },
+ { "setbe", Eb },
+ { "seta", Eb },
+ /* 98 */
+ { "sets", Eb },
+ { "setns", Eb },
+ { "setp", Eb },
+ { "setnp", Eb },
+ { "setl", Eb },
+ { "setge", Eb },
+ { "setle", Eb },
+ { "setg", Eb },
+ /* a0 */
+ { "pushl", fs },
+ { "popl", fs },
+ { "cpuid" },
+ { "btS", Ev, Gv },
+ { "shldS", Ev, Gv, Ib },
+ { "shldS", Ev, Gv, CL },
+ { "(bad)" },
+ { "(bad)" },
+ /* a8 */
+ { "pushl", gs },
+ { "popl", gs },
+ { "rsm" },
+ { "btsS", Ev, Gv },
+ { "shrdS", Ev, Gv, Ib },
+ { "shrdS", Ev, Gv, CL },
+ { "(bad)" },
+ { "imulS", Gv, Ev },
+ /* b0 */
+ { "cmpxchgb", Eb, Gb },
+ { "cmpxchgS", Ev, Gv },
+ { "lssS", Gv, Mp }, /* 386 lists only Mp */
+ { "btrS", Ev, Gv },
+ { "lfsS", Gv, Mp }, /* 386 lists only Mp */
+ { "lgsS", Gv, Mp }, /* 386 lists only Mp */
+ { "movzbS", Gv, Eb },
+ { "movzwS", Gv, Ew },
+ /* b8 */
+ { "ud2b" },
+ { "(bad)" },
+ { GRP8 },
+ { "btcS", Ev, Gv },
+ { "bsfS", Gv, Ev },
+ { "bsrS", Gv, Ev },
+ { "movsbS", Gv, Eb },
+ { "movswS", Gv, Ew },
+ /* c0 */
+ { "xaddb", Eb, Gb },
+ { "xaddS", Ev, Gv },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { GRP9 },
+ /* c8 */
+ { "bswap", eAX },
+ { "bswap", eCX },
+ { "bswap", eDX },
+ { "bswap", eBX },
+ { "bswap", eSP },
+ { "bswap", eBP },
+ { "bswap", eSI },
+ { "bswap", eDI },
+ /* d0 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* d8 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* e0 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* e8 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* f0 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ /* f8 */
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+};
+
+static const unsigned char onebyte_has_modrm[256] = {
+ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
+ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
+ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
+ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
+ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1
+};
+
+static const unsigned char twobyte_has_modrm[256] = {
+ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+};
+
+static char obuf[100];
+static char *obufp;
+static char scratchbuf[100];
+static unsigned char *start_codep;
+static unsigned char *codep;
+static disassemble_info *the_info;
+static int mod;
+static int rm;
+static int reg;
+static void oappend ();
+
+static char *names32[]={
+ "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
+};
+static char *names16[] = {
+ "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
+};
+static char *names8[] = {
+ "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
+};
+static char *names_seg[] = {
+ "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
+};
+static char *index16[] = {
+ "bx+si","bx+di","bp+si","bp+di","si","di","bp","bx"
+};
+
+struct dis386 grps[][8] = {
+ /* GRP1b */
+ {
+ { "addb", Eb, Ib },
+ { "orb", Eb, Ib },
+ { "adcb", Eb, Ib },
+ { "sbbb", Eb, Ib },
+ { "andb", Eb, Ib },
+ { "subb", Eb, Ib },
+ { "xorb", Eb, Ib },
+ { "cmpb", Eb, Ib }
+ },
+ /* GRP1S */
+ {
+ { "addS", Ev, Iv },
+ { "orS", Ev, Iv },
+ { "adcS", Ev, Iv },
+ { "sbbS", Ev, Iv },
+ { "andS", Ev, Iv },
+ { "subS", Ev, Iv },
+ { "xorS", Ev, Iv },
+ { "cmpS", Ev, Iv }
+ },
+ /* GRP1Ss */
+ {
+ { "addS", Ev, sIb },
+ { "orS", Ev, sIb },
+ { "adcS", Ev, sIb },
+ { "sbbS", Ev, sIb },
+ { "andS", Ev, sIb },
+ { "subS", Ev, sIb },
+ { "xorS", Ev, sIb },
+ { "cmpS", Ev, sIb }
+ },
+ /* GRP2b */
+ {
+ { "rolb", Eb, Ib },
+ { "rorb", Eb, Ib },
+ { "rclb", Eb, Ib },
+ { "rcrb", Eb, Ib },
+ { "shlb", Eb, Ib },
+ { "shrb", Eb, Ib },
+ { "(bad)" },
+ { "sarb", Eb, Ib },
+ },
+ /* GRP2S */
+ {
+ { "rolS", Ev, Ib },
+ { "rorS", Ev, Ib },
+ { "rclS", Ev, Ib },
+ { "rcrS", Ev, Ib },
+ { "shlS", Ev, Ib },
+ { "shrS", Ev, Ib },
+ { "(bad)" },
+ { "sarS", Ev, Ib },
+ },
+ /* GRP2b_one */
+ {
+ { "rolb", Eb },
+ { "rorb", Eb },
+ { "rclb", Eb },
+ { "rcrb", Eb },
+ { "shlb", Eb },
+ { "shrb", Eb },
+ { "(bad)" },
+ { "sarb", Eb },
+ },
+ /* GRP2S_one */
+ {
+ { "rolS", Ev },
+ { "rorS", Ev },
+ { "rclS", Ev },
+ { "rcrS", Ev },
+ { "shlS", Ev },
+ { "shrS", Ev },
+ { "(bad)" },
+ { "sarS", Ev },
+ },
+ /* GRP2b_cl */
+ {
+ { "rolb", Eb, CL },
+ { "rorb", Eb, CL },
+ { "rclb", Eb, CL },
+ { "rcrb", Eb, CL },
+ { "shlb", Eb, CL },
+ { "shrb", Eb, CL },
+ { "(bad)" },
+ { "sarb", Eb, CL },
+ },
+ /* GRP2S_cl */
+ {
+ { "rolS", Ev, CL },
+ { "rorS", Ev, CL },
+ { "rclS", Ev, CL },
+ { "rcrS", Ev, CL },
+ { "shlS", Ev, CL },
+ { "shrS", Ev, CL },
+ { "(bad)" },
+ { "sarS", Ev, CL }
+ },
+ /* GRP3b */
+ {
+ { "testb", Eb, Ib },
+ { "(bad)", Eb },
+ { "notb", Eb },
+ { "negb", Eb },
+ { "mulb", AL, Eb },
+ { "imulb", AL, Eb },
+ { "divb", AL, Eb },
+ { "idivb", AL, Eb }
+ },
+ /* GRP3S */
+ {
+ { "testS", Ev, Iv },
+ { "(bad)" },
+ { "notS", Ev },
+ { "negS", Ev },
+ { "mulS", eAX, Ev },
+ { "imulS", eAX, Ev },
+ { "divS", eAX, Ev },
+ { "idivS", eAX, Ev },
+ },
+ /* GRP4 */
+ {
+ { "incb", Eb },
+ { "decb", Eb },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ },
+ /* GRP5 */
+ {
+ { "incS", Ev },
+ { "decS", Ev },
+ { "call", indirEv },
+ { "lcall", indirEv },
+ { "jmp", indirEv },
+ { "ljmp", indirEv },
+ { "pushS", Ev },
+ { "(bad)" },
+ },
+ /* GRP6 */
+ {
+ { "sldt", Ew },
+ { "str", Ew },
+ { "lldt", Ew },
+ { "ltr", Ew },
+ { "verr", Ew },
+ { "verw", Ew },
+ { "(bad)" },
+ { "(bad)" }
+ },
+ /* GRP7 */
+ {
+ { "sgdt", Ew },
+ { "sidt", Ew },
+ { "lgdt", Ew },
+ { "lidt", Ew },
+ { "smsw", Ew },
+ { "(bad)" },
+ { "lmsw", Ew },
+ { "invlpg", Ew },
+ },
+ /* GRP8 */
+ {
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "btS", Ev, Ib },
+ { "btsS", Ev, Ib },
+ { "btrS", Ev, Ib },
+ { "btcS", Ev, Ib },
+ },
+ /* GRP9 */
+ {
+ { "(bad)" },
+ { "cmpxchg8b", Ev },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ }
+};
+
+#define PREFIX_REPZ 1
+#define PREFIX_REPNZ 2
+#define PREFIX_LOCK 4
+#define PREFIX_CS 8
+#define PREFIX_SS 0x10
+#define PREFIX_DS 0x20
+#define PREFIX_ES 0x40
+#define PREFIX_FS 0x80
+#define PREFIX_GS 0x100
+#define PREFIX_DATA 0x200
+#define PREFIX_ADR 0x400
+#define PREFIX_FWAIT 0x800
+
+static int prefixes;
+
+static void
+ckprefix ()
+{
+ prefixes = 0;
+ while (1)
+ {
+ FETCH_DATA (the_info, codep + 1);
+ switch (*codep)
+ {
+ case 0xf3:
+ prefixes |= PREFIX_REPZ;
+ break;
+ case 0xf2:
+ prefixes |= PREFIX_REPNZ;
+ break;
+ case 0xf0:
+ prefixes |= PREFIX_LOCK;
+ break;
+ case 0x2e:
+ prefixes |= PREFIX_CS;
+ break;
+ case 0x36:
+ prefixes |= PREFIX_SS;
+ break;
+ case 0x3e:
+ prefixes |= PREFIX_DS;
+ break;
+ case 0x26:
+ prefixes |= PREFIX_ES;
+ break;
+ case 0x64:
+ prefixes |= PREFIX_FS;
+ break;
+ case 0x65:
+ prefixes |= PREFIX_GS;
+ break;
+ case 0x66:
+ prefixes |= PREFIX_DATA;
+ break;
+ case 0x67:
+ prefixes |= PREFIX_ADR;
+ break;
+ case 0x9b:
+ prefixes |= PREFIX_FWAIT;
+ break;
+ default:
+ return;
+ }
+ codep++;
+ }
+}
+
+static int dflag;
+static int aflag;
+
+static char op1out[100], op2out[100], op3out[100];
+static int op_address[3], op_ad, op_index[3];
+static int start_pc;
+
+
+/*
+ * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
+ * (see topic "Redundant prefixes" in the "Differences from 8086"
+ * section of the "Virtual 8086 Mode" chapter.)
+ * 'pc' should be the address of this instruction, it will
+ * be used to print the target address if this is a relative jump or call
+ * The function returns the length of this instruction in bytes.
+ */
+
+int
+print_insn_i386 (pc, info)
+ bfd_vma pc;
+ disassemble_info *info;
+{
+ struct dis386 *dp;
+ int i;
+ int enter_instruction;
+ char *first, *second, *third;
+ int needcomma;
+ unsigned char need_modrm;
+
+ struct dis_private priv;
+ bfd_byte *inbuf = priv.the_buffer;
+
+ info->private_data = (PTR) &priv;
+ priv.max_fetched = priv.the_buffer;
+ priv.insn_start = pc;
+ if (setjmp (priv.bailout) != 0)
+ /* Error return. */
+ return -1;
+
+ obuf[0] = 0;
+ op1out[0] = 0;
+ op2out[0] = 0;
+ op3out[0] = 0;
+
+ op_index[0] = op_index[1] = op_index[2] = -1;
+
+ the_info = info;
+ start_pc = pc;
+ start_codep = inbuf;
+ codep = inbuf;
+
+ ckprefix ();
+
+ FETCH_DATA (info, codep + 1);
+ if (*codep == 0xc8)
+ enter_instruction = 1;
+ else
+ enter_instruction = 0;
+
+ obufp = obuf;
+
+ if (prefixes & PREFIX_REPZ)
+ oappend ("repz ");
+ if (prefixes & PREFIX_REPNZ)
+ oappend ("repnz ");
+ if (prefixes & PREFIX_LOCK)
+ oappend ("lock ");
+
+ if ((prefixes & PREFIX_FWAIT)
+ && ((*codep < 0xd8) || (*codep > 0xdf)))
+ {
+ /* fwait not followed by floating point instruction */
+ (*info->fprintf_func) (info->stream, "fwait");
+ return (1);
+ }
+
+ /* these would be initialized to 0 if disassembling for 8086 or 286 */
+ dflag = 1;
+ aflag = 1;
+
+ if (prefixes & PREFIX_DATA)
+ dflag ^= 1;
+
+ if (prefixes & PREFIX_ADR)
+ {
+ aflag ^= 1;
+ oappend ("addr16 ");
+ }
+
+ if (*codep == 0x0f)
+ {
+ FETCH_DATA (info, codep + 2);
+ dp = &dis386_twobyte[*++codep];
+ need_modrm = twobyte_has_modrm[*codep];
+ }
+ else
+ {
+ dp = &dis386[*codep];
+ need_modrm = onebyte_has_modrm[*codep];
+ }
+ codep++;
+
+ if (need_modrm)
+ {
+ FETCH_DATA (info, codep + 1);
+ mod = (*codep >> 6) & 3;
+ reg = (*codep >> 3) & 7;
+ rm = *codep & 7;
+ }
+
+ if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
+ {
+ dofloat ();
+ }
+ else
+ {
+ if (dp->name == NULL)
+ dp = &grps[dp->bytemode1][reg];
+
+ putop (dp->name);
+
+ obufp = op1out;
+ op_ad = 2;
+ if (dp->op1)
+ (*dp->op1)(dp->bytemode1);
+
+ obufp = op2out;
+ op_ad = 1;
+ if (dp->op2)
+ (*dp->op2)(dp->bytemode2);
+
+ obufp = op3out;
+ op_ad = 0;
+ if (dp->op3)
+ (*dp->op3)(dp->bytemode3);
+ }
+
+ obufp = obuf + strlen (obuf);
+ for (i = strlen (obuf); i < 6; i++)
+ oappend (" ");
+ oappend (" ");
+ (*info->fprintf_func) (info->stream, "%s", obuf);
+
+ /* enter instruction is printed with operands in the
+ * same order as the intel book; everything else
+ * is printed in reverse order
+ */
+ if (enter_instruction)
+ {
+ first = op1out;
+ second = op2out;
+ third = op3out;
+ op_ad = op_index[0];
+ op_index[0] = op_index[2];
+ op_index[2] = op_ad;
+ }
+ else
+ {
+ first = op3out;
+ second = op2out;
+ third = op1out;
+ }
+ needcomma = 0;
+ if (*first)
+ {
+ if (op_index[0] != -1)
+ (*info->print_address_func) (op_address[op_index[0]], info);
+ else
+ (*info->fprintf_func) (info->stream, "%s", first);
+ needcomma = 1;
+ }
+ if (*second)
+ {
+ if (needcomma)
+ (*info->fprintf_func) (info->stream, ",");
+ if (op_index[1] != -1)
+ (*info->print_address_func) (op_address[op_index[1]], info);
+ else
+ (*info->fprintf_func) (info->stream, "%s", second);
+ needcomma = 1;
+ }
+ if (*third)
+ {
+ if (needcomma)
+ (*info->fprintf_func) (info->stream, ",");
+ if (op_index[2] != -1)
+ (*info->print_address_func) (op_address[op_index[2]], info);
+ else
+ (*info->fprintf_func) (info->stream, "%s", third);
+ }
+ return (codep - inbuf);
+}
+
+char *float_mem[] = {
+ /* d8 */
+ "fadds",
+ "fmuls",
+ "fcoms",
+ "fcomps",
+ "fsubs",
+ "fsubrs",
+ "fdivs",
+ "fdivrs",
+ /* d9 */
+ "flds",
+ "(bad)",
+ "fsts",
+ "fstps",
+ "fldenv",
+ "fldcw",
+ "fNstenv",
+ "fNstcw",
+ /* da */
+ "fiaddl",
+ "fimull",
+ "ficoml",
+ "ficompl",
+ "fisubl",
+ "fisubrl",
+ "fidivl",
+ "fidivrl",
+ /* db */
+ "fildl",
+ "(bad)",
+ "fistl",
+ "fistpl",
+ "(bad)",
+ "fldt",
+ "(bad)",
+ "fstpt",
+ /* dc */
+ "faddl",
+ "fmull",
+ "fcoml",
+ "fcompl",
+ "fsubl",
+ "fsubrl",
+ "fdivl",
+ "fdivrl",
+ /* dd */
+ "fldl",
+ "(bad)",
+ "fstl",
+ "fstpl",
+ "frstor",
+ "(bad)",
+ "fNsave",
+ "fNstsw",
+ /* de */
+ "fiadd",
+ "fimul",
+ "ficom",
+ "ficomp",
+ "fisub",
+ "fisubr",
+ "fidiv",
+ "fidivr",
+ /* df */
+ "fild",
+ "(bad)",
+ "fist",
+ "fistp",
+ "fbld",
+ "fildll",
+ "fbstp",
+ "fistpll",
+};
+
+#define ST OP_ST, 0
+#define STi OP_STi, 0
+int OP_ST(), OP_STi();
+
+#define FGRPd9_2 NULL, NULL, 0
+#define FGRPd9_4 NULL, NULL, 1
+#define FGRPd9_5 NULL, NULL, 2
+#define FGRPd9_6 NULL, NULL, 3
+#define FGRPd9_7 NULL, NULL, 4
+#define FGRPda_5 NULL, NULL, 5
+#define FGRPdb_4 NULL, NULL, 6
+#define FGRPde_3 NULL, NULL, 7
+#define FGRPdf_4 NULL, NULL, 8
+
+struct dis386 float_reg[][8] = {
+ /* d8 */
+ {
+ { "fadd", ST, STi },
+ { "fmul", ST, STi },
+ { "fcom", STi },
+ { "fcomp", STi },
+ { "fsub", ST, STi },
+ { "fsubr", ST, STi },
+ { "fdiv", ST, STi },
+ { "fdivr", ST, STi },
+ },
+ /* d9 */
+ {
+ { "fld", STi },
+ { "fxch", STi },
+ { FGRPd9_2 },
+ { "(bad)" },
+ { FGRPd9_4 },
+ { FGRPd9_5 },
+ { FGRPd9_6 },
+ { FGRPd9_7 },
+ },
+ /* da */
+ {
+ { "fcmovb", ST, STi },
+ { "fcmove", ST, STi },
+ { "fcmovbe",ST, STi },
+ { "fcmovu", ST, STi },
+ { "(bad)" },
+ { FGRPda_5 },
+ { "(bad)" },
+ { "(bad)" },
+ },
+ /* db */
+ {
+ { "fcmovnb",ST, STi },
+ { "fcmovne",ST, STi },
+ { "fcmovnbe",ST, STi },
+ { "fcmovnu",ST, STi },
+ { FGRPdb_4 },
+ { "fucomi", ST, STi },
+ { "fcomi", ST, STi },
+ { "(bad)" },
+ },
+ /* dc */
+ {
+ { "fadd", STi, ST },
+ { "fmul", STi, ST },
+ { "(bad)" },
+ { "(bad)" },
+ { "fsub", STi, ST },
+ { "fsubr", STi, ST },
+ { "fdiv", STi, ST },
+ { "fdivr", STi, ST },
+ },
+ /* dd */
+ {
+ { "ffree", STi },
+ { "(bad)" },
+ { "fst", STi },
+ { "fstp", STi },
+ { "fucom", STi },
+ { "fucomp", STi },
+ { "(bad)" },
+ { "(bad)" },
+ },
+ /* de */
+ {
+ { "faddp", STi, ST },
+ { "fmulp", STi, ST },
+ { "(bad)" },
+ { FGRPde_3 },
+ { "fsubp", STi, ST },
+ { "fsubrp", STi, ST },
+ { "fdivp", STi, ST },
+ { "fdivrp", STi, ST },
+ },
+ /* df */
+ {
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { "(bad)" },
+ { FGRPdf_4 },
+ { "fucomip",ST, STi },
+ { "fcomip", ST, STi },
+ { "(bad)" },
+ },
+};
+
+
+char *fgrps[][8] = {
+ /* d9_2 0 */
+ {
+ "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+ },
+
+ /* d9_4 1 */
+ {
+ "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
+ },
+
+ /* d9_5 2 */
+ {
+ "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
+ },
+
+ /* d9_6 3 */
+ {
+ "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
+ },
+
+ /* d9_7 4 */
+ {
+ "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
+ },
+
+ /* da_5 5 */
+ {
+ "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+ },
+
+ /* db_4 6 */
+ {
+ "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
+ "fNsetpm(287 only)","(bad)","(bad)","(bad)",
+ },
+
+ /* de_3 7 */
+ {
+ "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+ },
+
+ /* df_4 8 */
+ {
+ "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+ },
+};
+
+static void
+dofloat ()
+{
+ struct dis386 *dp;
+ unsigned char floatop;
+
+ floatop = codep[-1];
+
+ if (mod != 3)
+ {
+ putop (float_mem[(floatop - 0xd8) * 8 + reg]);
+ obufp = op1out;
+ OP_E (v_mode);
+ return;
+ }
+ codep++;
+
+ dp = &float_reg[floatop - 0xd8][reg];
+ if (dp->name == NULL)
+ {
+ putop (fgrps[dp->bytemode1][rm]);
+ /* instruction fnstsw is only one with strange arg */
+ if (floatop == 0xdf
+ && FETCH_DATA (the_info, codep + 1)
+ && *codep == 0xe0)
+ strcpy (op1out, "%eax");
+ }
+ else
+ {
+ putop (dp->name);
+ obufp = op1out;
+ if (dp->op1)
+ (*dp->op1)(dp->bytemode1);
+ obufp = op2out;
+ if (dp->op2)
+ (*dp->op2)(dp->bytemode2);
+ }
+}
+
+/* ARGSUSED */
+int
+OP_ST (ignore)
+ int ignore;
+{
+ oappend ("%st");
+ return (0);
+}
+
+/* ARGSUSED */
+int
+OP_STi (ignore)
+ int ignore;
+{
+ sprintf (scratchbuf, "%%st(%d)", rm);
+ oappend (scratchbuf);
+ return (0);
+}
+
+
+/* capital letters in template are macros */
+static void
+putop (template)
+ char *template;
+{
+ char *p;
+
+ for (p = template; *p; p++)
+ {
+ switch (*p)
+ {
+ default:
+ *obufp++ = *p;
+ break;
+ case 'C': /* For jcxz/jecxz */
+ if (aflag)
+ *obufp++ = 'e';
+ break;
+ case 'N':
+ if ((prefixes & PREFIX_FWAIT) == 0)
+ *obufp++ = 'n';
+ break;
+ case 'S':
+ /* operand size flag */
+ if (dflag)
+ *obufp++ = 'l';
+ else
+ *obufp++ = 'w';
+ break;
+ }
+ }
+ *obufp = 0;
+}
+
+static void
+oappend (s)
+ char *s;
+{
+ strcpy (obufp, s);
+ obufp += strlen (s);
+ *obufp = 0;
+}
+
+static void
+append_prefix ()
+{
+ if (prefixes & PREFIX_CS)
+ oappend ("%cs:");
+ if (prefixes & PREFIX_DS)
+ oappend ("%ds:");
+ if (prefixes & PREFIX_SS)
+ oappend ("%ss:");
+ if (prefixes & PREFIX_ES)
+ oappend ("%es:");
+ if (prefixes & PREFIX_FS)
+ oappend ("%fs:");
+ if (prefixes & PREFIX_GS)
+ oappend ("%gs:");
+}
+
+int
+OP_indirE (bytemode)
+ int bytemode;
+{
+ oappend ("*");
+ return OP_E (bytemode);
+}
+
+int
+OP_E (bytemode)
+ int bytemode;
+{
+ int disp;
+
+ /* skip mod/rm byte */
+ codep++;
+
+ if (mod == 3)
+ {
+ switch (bytemode)
+ {
+ case b_mode:
+ oappend (names8[rm]);
+ break;
+ case w_mode:
+ oappend (names16[rm]);
+ break;
+ case v_mode:
+ if (dflag)
+ oappend (names32[rm]);
+ else
+ oappend (names16[rm]);
+ break;
+ default:
+ oappend ("<bad dis table>");
+ break;
+ }
+ return 0;
+ }
+
+ disp = 0;
+ append_prefix ();
+
+ if (aflag) /* 32 bit address mode */
+ {
+ int havesib;
+ int havebase;
+ int base;
+ int index;
+ int scale;
+
+ havesib = 0;
+ havebase = 1;
+ base = rm;
+
+ if (base == 4)
+ {
+ havesib = 1;
+ FETCH_DATA (the_info, codep + 1);
+ scale = (*codep >> 6) & 3;
+ index = (*codep >> 3) & 7;
+ base = *codep & 7;
+ codep++;
+ }
+
+ switch (mod)
+ {
+ case 0:
+ if (base == 5)
+ {
+ havebase = 0;
+ disp = get32 ();
+ }
+ break;
+ case 1:
+ FETCH_DATA (the_info, codep + 1);
+ disp = *(char *)codep++;
+ break;
+ case 2:
+ disp = get32 ();
+ break;
+ }
+
+ if (mod != 0 || base == 5)
+ {
+ sprintf (scratchbuf, "0x%x", disp);
+ oappend (scratchbuf);
+ }
+
+ if (havebase || (havesib && (index != 4 || scale != 0)))
+ {
+ oappend ("(");
+ if (havebase)
+ oappend (names32[base]);
+ if (havesib)
+ {
+ if (index != 4)
+ {
+ sprintf (scratchbuf, ",%s", names32[index]);
+ oappend (scratchbuf);
+ }
+ sprintf (scratchbuf, ",%d", 1 << scale);
+ oappend (scratchbuf);
+ }
+ oappend (")");
+ }
+ }
+ else
+ { /* 16 bit address mode */
+ switch (mod)
+ {
+ case 0:
+ if (rm == 6)
+ disp = (short) get16 ();
+ break;
+ case 1:
+ FETCH_DATA (the_info, codep + 1);
+ disp = *(char *)codep++;
+ break;
+ case 2:
+ disp = (short) get16 ();
+ break;
+ }
+
+ if (mod != 0 || rm == 6)
+ {
+ sprintf (scratchbuf, "0x%x", disp);
+ oappend (scratchbuf);
+ }
+
+ if (mod != 0 || rm != 6)
+ {
+ oappend ("(");
+ oappend (index16[rm]);
+ oappend (")");
+ }
+ }
+ return 0;
+}
+
+int
+OP_G (bytemode)
+ int bytemode;
+{
+ switch (bytemode)
+ {
+ case b_mode:
+ oappend (names8[reg]);
+ break;
+ case w_mode:
+ oappend (names16[reg]);
+ break;
+ case d_mode:
+ oappend (names32[reg]);
+ break;
+ case v_mode:
+ if (dflag)
+ oappend (names32[reg]);
+ else
+ oappend (names16[reg]);
+ break;
+ default:
+ oappend ("<internal disassembler error>");
+ break;
+ }
+ return (0);
+}
+
+static int
+get32 ()
+{
+ int x = 0;
+
+ FETCH_DATA (the_info, codep + 4);
+ x = *codep++ & 0xff;
+ x |= (*codep++ & 0xff) << 8;
+ x |= (*codep++ & 0xff) << 16;
+ x |= (*codep++ & 0xff) << 24;
+ return (x);
+}
+
+static int
+get16 ()
+{
+ int x = 0;
+
+ FETCH_DATA (the_info, codep + 2);
+ x = *codep++ & 0xff;
+ x |= (*codep++ & 0xff) << 8;
+ return (x);
+}
+
+static void
+set_op (op)
+ int op;
+{
+ op_index[op_ad] = op_ad;
+ op_address[op_ad] = op;
+}
+
+int
+OP_REG (code)
+ int code;
+{
+ char *s;
+
+ switch (code)
+ {
+ case indir_dx_reg: s = "(%dx)"; break;
+ case ax_reg: case cx_reg: case dx_reg: case bx_reg:
+ case sp_reg: case bp_reg: case si_reg: case di_reg:
+ s = names16[code - ax_reg];
+ break;
+ case es_reg: case ss_reg: case cs_reg:
+ case ds_reg: case fs_reg: case gs_reg:
+ s = names_seg[code - es_reg];
+ break;
+ case al_reg: case ah_reg: case cl_reg: case ch_reg:
+ case dl_reg: case dh_reg: case bl_reg: case bh_reg:
+ s = names8[code - al_reg];
+ break;
+ case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
+ case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
+ if (dflag)
+ s = names32[code - eAX_reg];
+ else
+ s = names16[code - eAX_reg];
+ break;
+ default:
+ s = "<internal disassembler error>";
+ break;
+ }
+ oappend (s);
+ return (0);
+}
+
+int
+OP_I (bytemode)
+ int bytemode;
+{
+ int op;
+
+ switch (bytemode)
+ {
+ case b_mode:
+ FETCH_DATA (the_info, codep + 1);
+ op = *codep++ & 0xff;
+ break;
+ case v_mode:
+ if (dflag)
+ op = get32 ();
+ else
+ op = get16 ();
+ break;
+ case w_mode:
+ op = get16 ();
+ break;
+ default:
+ oappend ("<internal disassembler error>");
+ return (0);
+ }
+ sprintf (scratchbuf, "$0x%x", op);
+ oappend (scratchbuf);
+ return (0);
+}
+
+int
+OP_sI (bytemode)
+ int bytemode;
+{
+ int op;
+
+ switch (bytemode)
+ {
+ case b_mode:
+ FETCH_DATA (the_info, codep + 1);
+ op = *(char *)codep++;
+ break;
+ case v_mode:
+ if (dflag)
+ op = get32 ();
+ else
+ op = (short)get16();
+ break;
+ case w_mode:
+ op = (short)get16 ();
+ break;
+ default:
+ oappend ("<internal disassembler error>");
+ return (0);
+ }
+ sprintf (scratchbuf, "$0x%x", op);
+ oappend (scratchbuf);
+ return (0);
+}
+
+int
+OP_J (bytemode)
+ int bytemode;
+{
+ int disp;
+ int mask = -1;
+
+ switch (bytemode)
+ {
+ case b_mode:
+ FETCH_DATA (the_info, codep + 1);
+ disp = *(char *)codep++;
+ break;
+ case v_mode:
+ if (dflag)
+ disp = get32 ();
+ else
+ {
+ disp = (short)get16 ();
+ /* for some reason, a data16 prefix on a jump instruction
+ means that the pc is masked to 16 bits after the
+ displacement is added! */
+ mask = 0xffff;
+ }
+ break;
+ default:
+ oappend ("<internal disassembler error>");
+ return (0);
+ }
+ disp = (start_pc + codep - start_codep + disp) & mask;
+ set_op (disp);
+ sprintf (scratchbuf, "0x%x", disp);
+ oappend (scratchbuf);
+ return (0);
+}
+
+/* ARGSUSED */
+int
+OP_SEG (dummy)
+ int dummy;
+{
+ static char *sreg[] = {
+ "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
+ };
+
+ oappend (sreg[reg]);
+ return (0);
+}
+
+int
+OP_DIR (size)
+ int size;
+{
+ int seg, offset;
+
+ switch (size)
+ {
+ case lptr:
+ if (aflag)
+ {
+ offset = get32 ();
+ seg = get16 ();
+ }
+ else
+ {
+ offset = get16 ();
+ seg = get16 ();
+ }
+ sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
+ oappend (scratchbuf);
+ break;
+ case v_mode:
+ if (aflag)
+ offset = get32 ();
+ else
+ offset = (short)get16 ();
+
+ offset = start_pc + codep - start_codep + offset;
+ set_op (offset);
+ sprintf (scratchbuf, "0x%x", offset);
+ oappend (scratchbuf);
+ break;
+ default:
+ oappend ("<internal disassembler error>");
+ break;
+ }
+ return (0);
+}
+
+/* ARGSUSED */
+int
+OP_OFF (bytemode)
+ int bytemode;
+{
+ int off;
+
+ if (aflag)
+ off = get32 ();
+ else
+ off = get16 ();
+
+ sprintf (scratchbuf, "0x%x", off);
+ oappend (scratchbuf);
+ return (0);
+}
+
+/* ARGSUSED */
+int
+OP_ESDI (dummy)
+ int dummy;
+{
+ oappend ("%es:(");
+ oappend (aflag ? "%edi" : "%di");
+ oappend (")");
+ return (0);
+}
+
+/* ARGSUSED */
+int
+OP_DSSI (dummy)
+ int dummy;
+{
+ oappend ("%ds:(");
+ oappend (aflag ? "%esi" : "%si");
+ oappend (")");
+ return (0);
+}
+
+/* ARGSUSED */
+int
+OP_ONE (dummy)
+ int dummy;
+{
+ oappend ("1");
+ return (0);
+}
+
+/* ARGSUSED */
+int
+OP_C (dummy)
+ int dummy;
+{
+ codep++; /* skip mod/rm */
+ sprintf (scratchbuf, "%%cr%d", reg);
+ oappend (scratchbuf);
+ return (0);
+}
+
+/* ARGSUSED */
+int
+OP_D (dummy)
+ int dummy;
+{
+ codep++; /* skip mod/rm */
+ sprintf (scratchbuf, "%%db%d", reg);
+ oappend (scratchbuf);
+ return (0);
+}
+
+/* ARGSUSED */
+int
+OP_T (dummy)
+ int dummy;
+{
+ codep++; /* skip mod/rm */
+ sprintf (scratchbuf, "%%tr%d", reg);
+ oappend (scratchbuf);
+ return (0);
+}
+
+int
+OP_rm (bytemode)
+ int bytemode;
+{
+ switch (bytemode)
+ {
+ case d_mode:
+ oappend (names32[rm]);
+ break;
+ case w_mode:
+ oappend (names16[rm]);
+ break;
+ }
+ return (0);
+}
diff --git a/opcode/i386.h b/opcode/i386.h
new file mode 100644
index 0000000..849a86f
--- /dev/null
+++ b/opcode/i386.h
@@ -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 */
diff --git a/opcode/ppc-dis.c b/opcode/ppc-dis.c
new file mode 100644
index 0000000..70716ea
--- /dev/null
+++ b/opcode/ppc-dis.c
@@ -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;
+}
diff --git a/opcode/ppc-opc.c b/opcode/ppc-opc.c
new file mode 100644
index 0000000..3e11db9
--- /dev/null
+++ b/opcode/ppc-opc.c
@@ -0,0 +1,2830 @@
+/* ppc-opc.c -- PowerPC opcode list
+ 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 "opcode/ppc.h"
+
+/* This file holds the PowerPC opcode table. The opcode table
+ includes almost all of the extended instruction mnemonics. This
+ permits the disassembler to use them, and simplifies the assembler
+ logic, at the cost of increasing the table size. The table is
+ strictly constant data, so the compiler should be able to put it in
+ the .text section.
+
+ This file also holds the operand table. All knowledge about
+ inserting operands into instructions and vice-versa is kept in this
+ file. */
+
+/* Local insertion and extraction functions. */
+
+static unsigned long insert_bat PARAMS ((unsigned long, long, const char **));
+static long extract_bat PARAMS ((unsigned long, int *));
+static unsigned long insert_bba PARAMS ((unsigned long, long, const char **));
+static long extract_bba PARAMS ((unsigned long, int *));
+static unsigned long insert_bd PARAMS ((unsigned long, long, const char **));
+static long extract_bd PARAMS ((unsigned long, int *));
+static unsigned long insert_bdm PARAMS ((unsigned long, long, const char **));
+static long extract_bdm PARAMS ((unsigned long, int *));
+static unsigned long insert_bdp PARAMS ((unsigned long, long, const char **));
+static long extract_bdp PARAMS ((unsigned long, int *));
+static unsigned long insert_bo PARAMS ((unsigned long, long, const char **));
+static long extract_bo PARAMS ((unsigned long, int *));
+static unsigned long insert_boe PARAMS ((unsigned long, long, const char **));
+static long extract_boe PARAMS ((unsigned long, int *));
+static unsigned long insert_ds PARAMS ((unsigned long, long, const char **));
+static long extract_ds PARAMS ((unsigned long, int *));
+static unsigned long insert_li PARAMS ((unsigned long, long, const char **));
+static long extract_li PARAMS ((unsigned long, int *));
+static unsigned long insert_mbe PARAMS ((unsigned long, long, const char **));
+static long extract_mbe PARAMS ((unsigned long, int *));
+static unsigned long insert_mb6 PARAMS ((unsigned long, long, const char **));
+static long extract_mb6 PARAMS ((unsigned long, int *));
+static unsigned long insert_nb PARAMS ((unsigned long, long, const char **));
+static long extract_nb PARAMS ((unsigned long, int *));
+static unsigned long insert_nsi PARAMS ((unsigned long, long, const char **));
+static long extract_nsi PARAMS ((unsigned long, int *));
+static unsigned long insert_ral PARAMS ((unsigned long, long, const char **));
+static unsigned long insert_ram PARAMS ((unsigned long, long, const char **));
+static unsigned long insert_ras PARAMS ((unsigned long, long, const char **));
+static unsigned long insert_rbs PARAMS ((unsigned long, long, const char **));
+static long extract_rbs PARAMS ((unsigned long, int *));
+static unsigned long insert_sh6 PARAMS ((unsigned long, long, const char **));
+static long extract_sh6 PARAMS ((unsigned long, int *));
+static unsigned long insert_spr PARAMS ((unsigned long, long, const char **));
+static long extract_spr PARAMS ((unsigned long, int *));
+static unsigned long insert_tbr PARAMS ((unsigned long, long, const char **));
+static long extract_tbr PARAMS ((unsigned long, int *));
+
+/* The operands table.
+
+ The fields are bits, shift, signed, insert, extract, flags. */
+
+const struct powerpc_operand powerpc_operands[] =
+{
+ /* The zero index is used to indicate the end of the list of
+ operands. */
+#define UNUSED (0)
+ { 0, 0, 0, 0, 0 },
+
+ /* The BA field in an XL form instruction. */
+#define BA (UNUSED + 1)
+#define BA_MASK (0x1f << 16)
+ { 5, 16, 0, 0, PPC_OPERAND_CR },
+
+ /* The BA field in an XL form instruction when it must be the same
+ as the BT field in the same instruction. */
+#define BAT (BA + 1)
+ { 5, 16, insert_bat, extract_bat, PPC_OPERAND_FAKE },
+
+ /* The BB field in an XL form instruction. */
+#define BB (BAT + 1)
+#define BB_MASK (0x1f << 11)
+ { 5, 11, 0, 0, PPC_OPERAND_CR },
+
+ /* The BB field in an XL form instruction when it must be the same
+ as the BA field in the same instruction. */
+#define BBA (BB + 1)
+ { 5, 11, insert_bba, extract_bba, PPC_OPERAND_FAKE },
+
+ /* The BD field in a B form instruction. The lower two bits are
+ forced to zero. */
+#define BD (BBA + 1)
+ { 16, 0, insert_bd, extract_bd, PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
+
+ /* The BD field in a B form instruction when absolute addressing is
+ used. */
+#define BDA (BD + 1)
+ { 16, 0, insert_bd, extract_bd, PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
+
+ /* The BD field in a B form instruction when the - modifier is used.
+ This sets the y bit of the BO field appropriately. */
+#define BDM (BDA + 1)
+ { 16, 0, insert_bdm, extract_bdm,
+ PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
+
+ /* The BD field in a B form instruction when the - modifier is used
+ and absolute address is used. */
+#define BDMA (BDM + 1)
+ { 16, 0, insert_bdm, extract_bdm,
+ PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
+
+ /* The BD field in a B form instruction when the + modifier is used.
+ This sets the y bit of the BO field appropriately. */
+#define BDP (BDMA + 1)
+ { 16, 0, insert_bdp, extract_bdp,
+ PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
+
+ /* The BD field in a B form instruction when the + modifier is used
+ and absolute addressing is used. */
+#define BDPA (BDP + 1)
+ { 16, 0, insert_bdp, extract_bdp,
+ PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
+
+ /* The BF field in an X or XL form instruction. */
+#define BF (BDPA + 1)
+ { 3, 23, 0, 0, PPC_OPERAND_CR },
+
+ /* An optional BF field. This is used for comparison instructions,
+ in which an omitted BF field is taken as zero. */
+#define OBF (BF + 1)
+ { 3, 23, 0, 0, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL },
+
+ /* The BFA field in an X or XL form instruction. */
+#define BFA (OBF + 1)
+ { 3, 18, 0, 0, PPC_OPERAND_CR },
+
+ /* The BI field in a B form or XL form instruction. */
+#define BI (BFA + 1)
+#define BI_MASK (0x1f << 16)
+ { 5, 16, 0, 0, PPC_OPERAND_CR },
+
+ /* The BO field in a B form instruction. Certain values are
+ illegal. */
+#define BO (BI + 1)
+#define BO_MASK (0x1f << 21)
+ { 5, 21, insert_bo, extract_bo, 0 },
+
+ /* The BO field in a B form instruction when the + or - modifier is
+ used. This is like the BO field, but it must be even. */
+#define BOE (BO + 1)
+ { 5, 21, insert_boe, extract_boe, 0 },
+
+ /* The BT field in an X or XL form instruction. */
+#define BT (BOE + 1)
+ { 5, 21, 0, 0, PPC_OPERAND_CR },
+
+ /* The condition register number portion of the BI field in a B form
+ or XL form instruction. This is used for the extended
+ conditional branch mnemonics, which set the lower two bits of the
+ BI field. This field is optional. */
+#define CR (BT + 1)
+ { 3, 18, 0, 0, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL },
+
+ /* The D field in a D form instruction. This is a displacement off
+ a register, and implies that the next operand is a register in
+ parentheses. */
+#define D (CR + 1)
+ { 16, 0, 0, 0, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED },
+
+ /* The DS field in a DS form instruction. This is like D, but the
+ lower two bits are forced to zero. */
+#define DS (D + 1)
+ { 16, 0, insert_ds, extract_ds, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED },
+
+ /* The FL1 field in a POWER SC form instruction. */
+#define FL1 (DS + 1)
+ { 4, 12, 0, 0, 0 },
+
+ /* The FL2 field in a POWER SC form instruction. */
+#define FL2 (FL1 + 1)
+ { 3, 2, 0, 0, 0 },
+
+ /* The FLM field in an XFL form instruction. */
+#define FLM (FL2 + 1)
+ { 8, 17, 0, 0, 0 },
+
+ /* The FRA field in an X or A form instruction. */
+#define FRA (FLM + 1)
+#define FRA_MASK (0x1f << 16)
+ { 5, 16, 0, 0, PPC_OPERAND_FPR },
+
+ /* The FRB field in an X or A form instruction. */
+#define FRB (FRA + 1)
+#define FRB_MASK (0x1f << 11)
+ { 5, 11, 0, 0, PPC_OPERAND_FPR },
+
+ /* The FRC field in an A form instruction. */
+#define FRC (FRB + 1)
+#define FRC_MASK (0x1f << 6)
+ { 5, 6, 0, 0, PPC_OPERAND_FPR },
+
+ /* The FRS field in an X form instruction or the FRT field in a D, X
+ or A form instruction. */
+#define FRS (FRC + 1)
+#define FRT (FRS)
+ { 5, 21, 0, 0, PPC_OPERAND_FPR },
+
+ /* The FXM field in an XFX instruction. */
+#define FXM (FRS + 1)
+#define FXM_MASK (0xff << 12)
+ { 8, 12, 0, 0, 0 },
+
+ /* The L field in a D or X form instruction. */
+#define L (FXM + 1)
+ { 1, 21, 0, 0, PPC_OPERAND_OPTIONAL },
+
+ /* The LEV field in a POWER SC form instruction. */
+#define LEV (L + 1)
+ { 7, 5, 0, 0, 0 },
+
+ /* The LI field in an I form instruction. The lower two bits are
+ forced to zero. */
+#define LI (LEV + 1)
+ { 26, 0, insert_li, extract_li, PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
+
+ /* The LI field in an I form instruction when used as an absolute
+ address. */
+#define LIA (LI + 1)
+ { 26, 0, insert_li, extract_li, PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
+
+ /* The MB field in an M form instruction. */
+#define MB (LIA + 1)
+#define MB_MASK (0x1f << 6)
+ { 5, 6, 0, 0, 0 },
+
+ /* The ME field in an M form instruction. */
+#define ME (MB + 1)
+#define ME_MASK (0x1f << 1)
+ { 5, 1, 0, 0, 0 },
+
+ /* The MB and ME fields in an M form instruction expressed a single
+ operand which is a bitmask indicating which bits to select. This
+ is a two operand form using PPC_OPERAND_NEXT. See the
+ description in opcode/ppc.h for what this means. */
+#define MBE (ME + 1)
+ { 5, 6, 0, 0, PPC_OPERAND_OPTIONAL | PPC_OPERAND_NEXT },
+ { 32, 0, insert_mbe, extract_mbe, 0 },
+
+ /* The MB or ME field in an MD or MDS form instruction. The high
+ bit is wrapped to the low end. */
+#define MB6 (MBE + 2)
+#define ME6 (MB6)
+#define MB6_MASK (0x3f << 5)
+ { 6, 5, insert_mb6, extract_mb6, 0 },
+
+ /* The NB field in an X form instruction. The value 32 is stored as
+ 0. */
+#define NB (MB6 + 1)
+ { 6, 11, insert_nb, extract_nb, 0 },
+
+ /* The NSI field in a D form instruction. This is the same as the
+ SI field, only negated. */
+#define NSI (NB + 1)
+ { 16, 0, insert_nsi, extract_nsi,
+ PPC_OPERAND_NEGATIVE | PPC_OPERAND_SIGNED },
+
+ /* The RA field in an D, DS, X, XO, M, or MDS form instruction. */
+#define RA (NSI + 1)
+#define RA_MASK (0x1f << 16)
+ { 5, 16, 0, 0, PPC_OPERAND_GPR },
+
+ /* The RA field in a D or X form instruction which is an updating
+ load, which means that the RA field may not be zero and may not
+ equal the RT field. */
+#define RAL (RA + 1)
+ { 5, 16, insert_ral, 0, PPC_OPERAND_GPR },
+
+ /* The RA field in an lmw instruction, which has special value
+ restrictions. */
+#define RAM (RAL + 1)
+ { 5, 16, insert_ram, 0, PPC_OPERAND_GPR },
+
+ /* The RA field in a D or X form instruction which is an updating
+ store or an updating floating point load, which means that the RA
+ field may not be zero. */
+#define RAS (RAM + 1)
+ { 5, 16, insert_ras, 0, PPC_OPERAND_GPR },
+
+ /* The RB field in an X, XO, M, or MDS form instruction. */
+#define RB (RAS + 1)
+#define RB_MASK (0x1f << 11)
+ { 5, 11, 0, 0, PPC_OPERAND_GPR },
+
+ /* The RB field in an X form instruction when it must be the same as
+ the RS field in the instruction. This is used for extended
+ mnemonics like mr. */
+#define RBS (RB + 1)
+ { 5, 1, insert_rbs, extract_rbs, PPC_OPERAND_FAKE },
+
+ /* The RS field in a D, DS, X, XFX, XS, M, MD or MDS form
+ instruction or the RT field in a D, DS, X, XFX or XO form
+ instruction. */
+#define RS (RBS + 1)
+#define RT (RS)
+#define RT_MASK (0x1f << 21)
+ { 5, 21, 0, 0, PPC_OPERAND_GPR },
+
+ /* The SH field in an X or M form instruction. */
+#define SH (RS + 1)
+#define SH_MASK (0x1f << 11)
+ { 5, 11, 0, 0, 0 },
+
+ /* The SH field in an MD form instruction. This is split. */
+#define SH6 (SH + 1)
+#define SH6_MASK ((0x1f << 11) | (1 << 1))
+ { 6, 1, insert_sh6, extract_sh6, 0 },
+
+ /* The SI field in a D form instruction. */
+#define SI (SH6 + 1)
+ { 16, 0, 0, 0, PPC_OPERAND_SIGNED },
+
+ /* The SI field in a D form instruction when we accept a wide range
+ of positive values. */
+#define SISIGNOPT (SI + 1)
+ { 16, 0, 0, 0, PPC_OPERAND_SIGNED | PPC_OPERAND_SIGNOPT },
+
+ /* The SPR field in an XFX form instruction. This is flipped--the
+ lower 5 bits are stored in the upper 5 and vice- versa. */
+#define SPR (SISIGNOPT + 1)
+#define SPR_MASK (0x3ff << 11)
+ { 10, 11, insert_spr, extract_spr, 0 },
+
+ /* The BAT index number in an XFX form m[ft]ibat[lu] instruction. */
+#define SPRBAT (SPR + 1)
+#define SPRBAT_MASK (0x3 << 17)
+ { 2, 17, 0, 0, 0 },
+
+ /* The SPRG register number in an XFX form m[ft]sprg instruction. */
+#define SPRG (SPRBAT + 1)
+#define SPRG_MASK (0x3 << 16)
+ { 2, 16, 0, 0, 0 },
+
+ /* The SR field in an X form instruction. */
+#define SR (SPRG + 1)
+ { 4, 16, 0, 0, 0 },
+
+ /* The SV field in a POWER SC form instruction. */
+#define SV (SR + 1)
+ { 14, 2, 0, 0, 0 },
+
+ /* The TBR field in an XFX form instruction. This is like the SPR
+ field, but it is optional. */
+#define TBR (SV + 1)
+ { 10, 11, insert_tbr, extract_tbr, PPC_OPERAND_OPTIONAL },
+
+ /* The TO field in a D or X form instruction. */
+#define TO (TBR + 1)
+#define TO_MASK (0x1f << 21)
+ { 5, 21, 0, 0, 0 },
+
+ /* The U field in an X form instruction. */
+#define U (TO + 1)
+ { 4, 12, 0, 0, 0 },
+
+ /* The UI field in a D form instruction. */
+#define UI (U + 1)
+ { 16, 0, 0, 0, 0 },
+};
+
+/* The functions used to insert and extract complicated operands. */
+
+/* The BA field in an XL form instruction when it must be the same as
+ the BT field in the same instruction. This operand is marked FAKE.
+ The insertion function just copies the BT field into the BA field,
+ and the extraction function just checks that the fields are the
+ same. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_bat (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ return insn | (((insn >> 21) & 0x1f) << 16);
+}
+
+static long
+extract_bat (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ if (invalid != (int *) NULL
+ && ((insn >> 21) & 0x1f) != ((insn >> 16) & 0x1f))
+ *invalid = 1;
+ return 0;
+}
+
+/* The BB field in an XL form instruction when it must be the same as
+ the BA field in the same instruction. This operand is marked FAKE.
+ The insertion function just copies the BA field into the BB field,
+ and the extraction function just checks that the fields are the
+ same. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_bba (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ return insn | (((insn >> 16) & 0x1f) << 11);
+}
+
+static long
+extract_bba (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ if (invalid != (int *) NULL
+ && ((insn >> 16) & 0x1f) != ((insn >> 11) & 0x1f))
+ *invalid = 1;
+ return 0;
+}
+
+/* The BD field in a B form instruction. The lower two bits are
+ forced to zero. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_bd (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ return insn | (value & 0xfffc);
+}
+
+/*ARGSUSED*/
+static long
+extract_bd (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ if ((insn & 0x8000) != 0)
+ return (insn & 0xfffc) - 0x10000;
+ else
+ return insn & 0xfffc;
+}
+
+/* The BD field in a B form instruction when the - modifier is used.
+ This modifier means that the branch is not expected to be taken.
+ We must set the y bit of the BO field to 1 if the offset is
+ negative. When extracting, we require that the y bit be 1 and that
+ the offset be positive, since if the y bit is 0 we just want to
+ print the normal form of the instruction. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_bdm (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ if ((value & 0x8000) != 0)
+ insn |= 1 << 21;
+ return insn | (value & 0xfffc);
+}
+
+static long
+extract_bdm (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ if (invalid != (int *) NULL
+ && ((insn & (1 << 21)) == 0
+ || (insn & (1 << 15)) == 0))
+ *invalid = 1;
+ if ((insn & 0x8000) != 0)
+ return (insn & 0xfffc) - 0x10000;
+ else
+ return insn & 0xfffc;
+}
+
+/* The BD field in a B form instruction when the + modifier is used.
+ This is like BDM, above, except that the branch is expected to be
+ taken. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_bdp (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ if ((value & 0x8000) == 0)
+ insn |= 1 << 21;
+ return insn | (value & 0xfffc);
+}
+
+static long
+extract_bdp (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ if (invalid != (int *) NULL
+ && ((insn & (1 << 21)) == 0
+ || (insn & (1 << 15)) != 0))
+ *invalid = 1;
+ if ((insn & 0x8000) != 0)
+ return (insn & 0xfffc) - 0x10000;
+ else
+ return insn & 0xfffc;
+}
+
+/* Check for legal values of a BO field. */
+
+static int
+valid_bo (value)
+ long value;
+{
+ /* Certain encodings have bits that are required to be zero. These
+ are (z must be zero, y may be anything):
+ 001zy
+ 011zy
+ 1z00y
+ 1z01y
+ 1z1zz
+ */
+ switch (value & 0x14)
+ {
+ default:
+ case 0:
+ return 1;
+ case 0x4:
+ return (value & 0x2) == 0;
+ case 0x10:
+ return (value & 0x8) == 0;
+ case 0x14:
+ return value == 0x14;
+ }
+}
+
+/* The BO field in a B form instruction. Warn about attempts to set
+ the field to an illegal value. */
+
+static unsigned long
+insert_bo (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ if (errmsg != (const char **) NULL
+ && ! valid_bo (value))
+ *errmsg = "invalid conditional option";
+ return insn | ((value & 0x1f) << 21);
+}
+
+static long
+extract_bo (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ long value;
+
+ value = (insn >> 21) & 0x1f;
+ if (invalid != (int *) NULL
+ && ! valid_bo (value))
+ *invalid = 1;
+ return value;
+}
+
+/* The BO field in a B form instruction when the + or - modifier is
+ used. This is like the BO field, but it must be even. When
+ extracting it, we force it to be even. */
+
+static unsigned long
+insert_boe (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ if (errmsg != (const char **) NULL)
+ {
+ if (! valid_bo (value))
+ *errmsg = "invalid conditional option";
+ else if ((value & 1) != 0)
+ *errmsg = "attempt to set y bit when using + or - modifier";
+ }
+ return insn | ((value & 0x1f) << 21);
+}
+
+static long
+extract_boe (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ long value;
+
+ value = (insn >> 21) & 0x1f;
+ if (invalid != (int *) NULL
+ && ! valid_bo (value))
+ *invalid = 1;
+ return value & 0x1e;
+}
+
+/* The DS field in a DS form instruction. This is like D, but the
+ lower two bits are forced to zero. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_ds (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ return insn | (value & 0xfffc);
+}
+
+/*ARGSUSED*/
+static long
+extract_ds (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ if ((insn & 0x8000) != 0)
+ return (insn & 0xfffc) - 0x10000;
+ else
+ return insn & 0xfffc;
+}
+
+/* The LI field in an I form instruction. The lower two bits are
+ forced to zero. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_li (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ return insn | (value & 0x3fffffc);
+}
+
+/*ARGSUSED*/
+static long
+extract_li (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ if ((insn & 0x2000000) != 0)
+ return (insn & 0x3fffffc) - 0x4000000;
+ else
+ return insn & 0x3fffffc;
+}
+
+/* The MB and ME fields in an M form instruction expressed as a single
+ operand which is itself a bitmask. The extraction function always
+ marks it as invalid, since we never want to recognize an
+ instruction which uses a field of this type. */
+
+static unsigned long
+insert_mbe (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ unsigned long uval;
+ int mb, me;
+
+ uval = value;
+
+ if (uval == 0)
+ {
+ if (errmsg != (const char **) NULL)
+ *errmsg = "illegal bitmask";
+ return insn;
+ }
+
+ me = 31;
+ while ((uval & 1) == 0)
+ {
+ uval >>= 1;
+ --me;
+ }
+
+ mb = me;
+ uval >>= 1;
+ while ((uval & 1) != 0)
+ {
+ uval >>= 1;
+ --mb;
+ }
+
+ if (uval != 0)
+ {
+ if (errmsg != (const char **) NULL)
+ *errmsg = "illegal bitmask";
+ }
+
+ return insn | (mb << 6) | (me << 1);
+}
+
+static long
+extract_mbe (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ long ret;
+ int mb, me;
+ int i;
+
+ if (invalid != (int *) NULL)
+ *invalid = 1;
+
+ ret = 0;
+ mb = (insn >> 6) & 0x1f;
+ me = (insn >> 1) & 0x1f;
+ for (i = mb; i < me; i++)
+ ret |= 1 << (31 - i);
+ return ret;
+}
+
+/* The MB or ME field in an MD or MDS form instruction. The high bit
+ is wrapped to the low end. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_mb6 (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ return insn | ((value & 0x1f) << 6) | (value & 0x20);
+}
+
+/*ARGSUSED*/
+static long
+extract_mb6 (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ return ((insn >> 6) & 0x1f) | (insn & 0x20);
+}
+
+/* The NB field in an X form instruction. The value 32 is stored as
+ 0. */
+
+static unsigned long
+insert_nb (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ if (value < 0 || value > 32)
+ *errmsg = "value out of range";
+ if (value == 32)
+ value = 0;
+ return insn | ((value & 0x1f) << 11);
+}
+
+/*ARGSUSED*/
+static long
+extract_nb (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ long ret;
+
+ ret = (insn >> 11) & 0x1f;
+ if (ret == 0)
+ ret = 32;
+ return ret;
+}
+
+/* The NSI field in a D form instruction. This is the same as the SI
+ field, only negated. The extraction function always marks it as
+ invalid, since we never want to recognize an instruction which uses
+ a field of this type. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_nsi (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ return insn | ((- value) & 0xffff);
+}
+
+static long
+extract_nsi (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ if (invalid != (int *) NULL)
+ *invalid = 1;
+ if ((insn & 0x8000) != 0)
+ return - ((insn & 0xffff) - 0x10000);
+ else
+ return - (insn & 0xffff);
+}
+
+/* The RA field in a D or X form instruction which is an updating
+ load, which means that the RA field may not be zero and may not
+ equal the RT field. */
+
+static unsigned long
+insert_ral (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ if (value == 0
+ || value == ((insn >> 21) & 0x1f))
+ *errmsg = "invalid register operand when updating";
+ return insn | ((value & 0x1f) << 16);
+}
+
+/* The RA field in an lmw instruction, which has special value
+ restrictions. */
+
+static unsigned long
+insert_ram (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ if (value >= ((insn >> 21) & 0x1f))
+ *errmsg = "index register in load range";
+ return insn | ((value & 0x1f) << 16);
+}
+
+/* The RA field in a D or X form instruction which is an updating
+ store or an updating floating point load, which means that the RA
+ field may not be zero. */
+
+static unsigned long
+insert_ras (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ if (value == 0)
+ *errmsg = "invalid register operand when updating";
+ return insn | ((value & 0x1f) << 16);
+}
+
+/* The RB field in an X form instruction when it must be the same as
+ the RS field in the instruction. This is used for extended
+ mnemonics like mr. This operand is marked FAKE. The insertion
+ function just copies the BT field into the BA field, and the
+ extraction function just checks that the fields are the same. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_rbs (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ return insn | (((insn >> 21) & 0x1f) << 11);
+}
+
+static long
+extract_rbs (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ if (invalid != (int *) NULL
+ && ((insn >> 21) & 0x1f) != ((insn >> 11) & 0x1f))
+ *invalid = 1;
+ return 0;
+}
+
+/* The SH field in an MD form instruction. This is split. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_sh6 (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ return insn | ((value & 0x1f) << 11) | ((value & 0x20) >> 4);
+}
+
+/*ARGSUSED*/
+static long
+extract_sh6 (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ return ((insn >> 11) & 0x1f) | ((insn << 4) & 0x20);
+}
+
+/* The SPR field in an XFX form instruction. This is flipped--the
+ lower 5 bits are stored in the upper 5 and vice- versa. */
+
+static unsigned long
+insert_spr (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ return insn | ((value & 0x1f) << 16) | ((value & 0x3e0) << 6);
+}
+
+static long
+extract_spr (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
+}
+
+/* The TBR field in an XFX instruction. This is just like SPR, but it
+ is optional. When TBR is omitted, it must be inserted as 268 (the
+ magic number of the TB register). These functions treat 0
+ (indicating an omitted optional operand) as 268. This means that
+ ``mftb 4,0'' is not handled correctly. This does not matter very
+ much, since the architecture manual does not define mftb as
+ accepting any values other than 268 or 269. */
+
+#define TB (268)
+
+static unsigned long
+insert_tbr (insn, value, errmsg)
+ unsigned long insn;
+ long value;
+ const char **errmsg;
+{
+ if (value == 0)
+ value = TB;
+ return insn | ((value & 0x1f) << 16) | ((value & 0x3e0) << 6);
+}
+
+static long
+extract_tbr (insn, invalid)
+ unsigned long insn;
+ int *invalid;
+{
+ long ret;
+
+ ret = ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
+ if (ret == TB)
+ ret = 0;
+ return ret;
+}
+
+/* Macros used to form opcodes. */
+
+/* The main opcode. */
+#define OP(x) (((x) & 0x3f) << 26)
+#define OP_MASK OP (0x3f)
+
+/* The main opcode combined with a trap code in the TO field of a D
+ form instruction. Used for extended mnemonics for the trap
+ instructions. */
+#define OPTO(x,to) (OP (x) | (((to) & 0x1f) << 21))
+#define OPTO_MASK (OP_MASK | TO_MASK)
+
+/* The main opcode combined with a comparison size bit in the L field
+ of a D form or X form instruction. Used for extended mnemonics for
+ the comparison instructions. */
+#define OPL(x,l) (OP (x) | (((l) & 1) << 21))
+#define OPL_MASK OPL (0x3f,1)
+
+/* An A form instruction. */
+#define A(op, xop, rc) (OP (op) | (((xop) & 0x1f) << 1) | ((rc) & 1))
+#define A_MASK A (0x3f, 0x1f, 1)
+
+/* An A_MASK with the FRB field fixed. */
+#define AFRB_MASK (A_MASK | FRB_MASK)
+
+/* An A_MASK with the FRC field fixed. */
+#define AFRC_MASK (A_MASK | FRC_MASK)
+
+/* An A_MASK with the FRA and FRC fields fixed. */
+#define AFRAFRC_MASK (A_MASK | FRA_MASK | FRC_MASK)
+
+/* A B form instruction. */
+#define B(op, aa, lk) (OP (op) | (((aa) & 1) << 1) | ((lk) & 1))
+#define B_MASK B (0x3f, 1, 1)
+
+/* A B form instruction setting the BO field. */
+#define BBO(op, bo, aa, lk) (B ((op), (aa), (lk)) | (((bo) & 0x1f) << 21))
+#define BBO_MASK BBO (0x3f, 0x1f, 1, 1)
+
+/* A BBO_MASK with the y bit of the BO field removed. This permits
+ matching a conditional branch regardless of the setting of the y
+ bit. */
+#define Y_MASK (1 << 21)
+#define BBOY_MASK (BBO_MASK &~ Y_MASK)
+
+/* A B form instruction setting the BO field and the condition bits of
+ the BI field. */
+#define BBOCB(op, bo, cb, aa, lk) \
+ (BBO ((op), (bo), (aa), (lk)) | (((cb) & 0x3) << 16))
+#define BBOCB_MASK BBOCB (0x3f, 0x1f, 0x3, 1, 1)
+
+/* A BBOCB_MASK with the y bit of the BO field removed. */
+#define BBOYCB_MASK (BBOCB_MASK &~ Y_MASK)
+
+/* A BBOYCB_MASK in which the BI field is fixed. */
+#define BBOYBI_MASK (BBOYCB_MASK | BI_MASK)
+
+/* The main opcode mask with the RA field clear. */
+#define DRA_MASK (OP_MASK | RA_MASK)
+
+/* A DS form instruction. */
+#define DSO(op, xop) (OP (op) | ((xop) & 0x3))
+#define DS_MASK DSO (0x3f, 3)
+
+/* An M form instruction. */
+#define M(op, rc) (OP (op) | ((rc) & 1))
+#define M_MASK M (0x3f, 1)
+
+/* An M form instruction with the ME field specified. */
+#define MME(op, me, rc) (M ((op), (rc)) | (((me) & 0x1f) << 1))
+
+/* An M_MASK with the MB and ME fields fixed. */
+#define MMBME_MASK (M_MASK | MB_MASK | ME_MASK)
+
+/* An M_MASK with the SH and ME fields fixed. */
+#define MSHME_MASK (M_MASK | SH_MASK | ME_MASK)
+
+/* An MD form instruction. */
+#define MD(op, xop, rc) (OP (op) | (((xop) & 0x7) << 2) | ((rc) & 1))
+#define MD_MASK MD (0x3f, 0x7, 1)
+
+/* An MD_MASK with the MB field fixed. */
+#define MDMB_MASK (MD_MASK | MB6_MASK)
+
+/* An MD_MASK with the SH field fixed. */
+#define MDSH_MASK (MD_MASK | SH6_MASK)
+
+/* An MDS form instruction. */
+#define MDS(op, xop, rc) (OP (op) | (((xop) & 0xf) << 1) | ((rc) & 1))
+#define MDS_MASK MDS (0x3f, 0xf, 1)
+
+/* An MDS_MASK with the MB field fixed. */
+#define MDSMB_MASK (MDS_MASK | MB6_MASK)
+
+/* An SC form instruction. */
+#define SC(op, sa, lk) (OP (op) | (((sa) & 1) << 1) | ((lk) & 1))
+#define SC_MASK (OP_MASK | (0x3ff << 16) | (1 << 1) | 1)
+
+/* An X form instruction. */
+#define X(op, xop) (OP (op) | (((xop) & 0x3ff) << 1))
+
+/* An X form instruction with the RC bit specified. */
+#define XRC(op, xop, rc) (X ((op), (xop)) | ((rc) & 1))
+
+/* The mask for an X form instruction. */
+#define X_MASK XRC (0x3f, 0x3ff, 1)
+
+/* An X_MASK with the RA field fixed. */
+#define XRA_MASK (X_MASK | RA_MASK)
+
+/* An X_MASK with the RB field fixed. */
+#define XRB_MASK (X_MASK | RB_MASK)
+
+/* An X_MASK with the RT field fixed. */
+#define XRT_MASK (X_MASK | RT_MASK)
+
+/* An X_MASK with the RA and RB fields fixed. */
+#define XRARB_MASK (X_MASK | RA_MASK | RB_MASK)
+
+/* An X_MASK with the RT and RA fields fixed. */
+#define XRTRA_MASK (X_MASK | RT_MASK | RA_MASK)
+
+/* An X form comparison instruction. */
+#define XCMPL(op, xop, l) (X ((op), (xop)) | (((l) & 1) << 21))
+
+/* The mask for an X form comparison instruction. */
+#define XCMP_MASK (X_MASK | (1 << 22))
+
+/* The mask for an X form comparison instruction with the L field
+ fixed. */
+#define XCMPL_MASK (XCMP_MASK | (1 << 21))
+
+/* An X form trap instruction with the TO field specified. */
+#define XTO(op, xop, to) (X ((op), (xop)) | (((to) & 0x1f) << 21))
+#define XTO_MASK (X_MASK | TO_MASK)
+
+/* An XFL form instruction. */
+#define XFL(op, xop, rc) (OP (op) | (((xop) & 0x3ff) << 1) | ((rc) & 1))
+#define XFL_MASK (XFL (0x3f, 0x3ff, 1) | (1 << 25) | (1 << 16))
+
+/* An XL form instruction with the LK field set to 0. */
+#define XL(op, xop) (OP (op) | (((xop) & 0x3ff) << 1))
+
+/* An XL form instruction which uses the LK field. */
+#define XLLK(op, xop, lk) (XL ((op), (xop)) | ((lk) & 1))
+
+/* The mask for an XL form instruction. */
+#define XL_MASK XLLK (0x3f, 0x3ff, 1)
+
+/* An XL form instruction which explicitly sets the BO field. */
+#define XLO(op, bo, xop, lk) \
+ (XLLK ((op), (xop), (lk)) | (((bo) & 0x1f) << 21))
+#define XLO_MASK (XL_MASK | BO_MASK)
+
+/* An XL form instruction which explicitly sets the y bit of the BO
+ field. */
+#define XLYLK(op, xop, y, lk) (XLLK ((op), (xop), (lk)) | (((y) & 1) << 21))
+#define XLYLK_MASK (XL_MASK | Y_MASK)
+
+/* An XL form instruction which sets the BO field and the condition
+ bits of the BI field. */
+#define XLOCB(op, bo, cb, xop, lk) \
+ (XLO ((op), (bo), (xop), (lk)) | (((cb) & 3) << 16))
+#define XLOCB_MASK XLOCB (0x3f, 0x1f, 0x3, 0x3ff, 1)
+
+/* An XL_MASK or XLYLK_MASK or XLOCB_MASK with the BB field fixed. */
+#define XLBB_MASK (XL_MASK | BB_MASK)
+#define XLYBB_MASK (XLYLK_MASK | BB_MASK)
+#define XLBOCBBB_MASK (XLOCB_MASK | BB_MASK)
+
+/* An XL_MASK with the BO and BB fields fixed. */
+#define XLBOBB_MASK (XL_MASK | BO_MASK | BB_MASK)
+
+/* An XL_MASK with the BO, BI and BB fields fixed. */
+#define XLBOBIBB_MASK (XL_MASK | BO_MASK | BI_MASK | BB_MASK)
+
+/* An XO form instruction. */
+#define XO(op, xop, oe, rc) \
+ (OP (op) | (((xop) & 0x1ff) << 1) | (((oe) & 1) << 10) | ((rc) & 1))
+#define XO_MASK XO (0x3f, 0x1ff, 1, 1)
+
+/* An XO_MASK with the RB field fixed. */
+#define XORB_MASK (XO_MASK | RB_MASK)
+
+/* An XS form instruction. */
+#define XS(op, xop, rc) (OP (op) | (((xop) & 0x1ff) << 2) | ((rc) & 1))
+#define XS_MASK XS (0x3f, 0x1ff, 1)
+
+/* A mask for the FXM version of an XFX form instruction. */
+#define XFXFXM_MASK (X_MASK | (1 << 20) | (1 << 11))
+
+/* An XFX form instruction with the FXM field filled in. */
+#define XFXM(op, xop, fxm) \
+ (X ((op), (xop)) | (((fxm) & 0xff) << 12))
+
+/* An XFX form instruction with the SPR field filled in. */
+#define XSPR(op, xop, spr) \
+ (X ((op), (xop)) | (((spr) & 0x1f) << 16) | (((spr) & 0x3e0) << 6))
+#define XSPR_MASK (X_MASK | SPR_MASK)
+
+/* An XFX form instruction with the SPR field filled in except for the
+ SPRBAT field. */
+#define XSPRBAT_MASK (XSPR_MASK &~ SPRBAT_MASK)
+
+/* An XFX form instruction with the SPR field filled in except for the
+ SPRG field. */
+#define XSPRG_MASK (XSPR_MASK &~ SPRG_MASK)
+
+/* The BO encodings used in extended conditional branch mnemonics. */
+#define BODNZF (0x0)
+#define BODNZFP (0x1)
+#define BODZF (0x2)
+#define BODZFP (0x3)
+#define BOF (0x4)
+#define BOFP (0x5)
+#define BODNZT (0x8)
+#define BODNZTP (0x9)
+#define BODZT (0xa)
+#define BODZTP (0xb)
+#define BOT (0xc)
+#define BOTP (0xd)
+#define BODNZ (0x10)
+#define BODNZP (0x11)
+#define BODZ (0x12)
+#define BODZP (0x13)
+#define BOU (0x14)
+
+/* The BI condition bit encodings used in extended conditional branch
+ mnemonics. */
+#define CBLT (0)
+#define CBGT (1)
+#define CBEQ (2)
+#define CBSO (3)
+
+/* The TO encodings used in extended trap mnemonics. */
+#define TOLGT (0x1)
+#define TOLLT (0x2)
+#define TOEQ (0x4)
+#define TOLGE (0x5)
+#define TOLNL (0x5)
+#define TOLLE (0x6)
+#define TOLNG (0x6)
+#define TOGT (0x8)
+#define TOGE (0xc)
+#define TONL (0xc)
+#define TOLT (0x10)
+#define TOLE (0x14)
+#define TONG (0x14)
+#define TONE (0x18)
+#define TOU (0x1f)
+
+/* Smaller names for the flags so each entry in the opcodes table will
+ fit on a single line. */
+#undef PPC
+#define PPC PPC_OPCODE_PPC | PPC_OPCODE_ANY
+#define PPCCOM PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_ANY
+#define PPC32 PPC_OPCODE_PPC | PPC_OPCODE_32 | PPC_OPCODE_ANY
+#define PPC64 PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_ANY
+#define PPCONLY PPC_OPCODE_PPC
+#define POWER PPC_OPCODE_POWER | PPC_OPCODE_ANY
+#define POWER2 PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_ANY
+#define POWER32 PPC_OPCODE_POWER | PPC_OPCODE_ANY | PPC_OPCODE_32
+#define COM PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON |
PPC_OPCODE_ANY
+#define COM32 PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON |
PPC_OPCODE_ANY | PPC_OPCODE_32
+#define M601 PPC_OPCODE_POWER | PPC_OPCODE_601 | PPC_OPCODE_ANY
+#define PWRCOM PPC_OPCODE_POWER | PPC_OPCODE_601 | PPC_OPCODE_COMMON |
PPC_OPCODE_ANY
+#define MFDEC1 PPC_OPCODE_POWER
+#define MFDEC2 PPC_OPCODE_PPC | PPC_OPCODE_601
+
+/* The opcode table.
+
+ The format of the opcode table is:
+
+ NAME OPCODE MASK FLAGS { OPERANDS }
+
+ NAME is the name of the instruction.
+ OPCODE is the instruction opcode.
+ MASK is the opcode mask; this is used to tell the disassembler
+ which bits in the actual opcode must match OPCODE.
+ FLAGS are flags indicated what processors support the instruction.
+ OPERANDS is the list of operands.
+
+ The disassembler reads the table in order and prints the first
+ instruction which matches, so this table is sorted to put more
+ specific instructions before more general instructions. It is also
+ sorted by major opcode. */
+
+const struct powerpc_opcode powerpc_opcodes[] = {
+{ "tdlgti", OPTO(2,TOLGT), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdllti", OPTO(2,TOLLT), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdeqi", OPTO(2,TOEQ), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdlgei", OPTO(2,TOLGE), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdlnli", OPTO(2,TOLNL), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdllei", OPTO(2,TOLLE), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdlngi", OPTO(2,TOLNG), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdgti", OPTO(2,TOGT), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdgei", OPTO(2,TOGE), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdnli", OPTO(2,TONL), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdlti", OPTO(2,TOLT), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdlei", OPTO(2,TOLE), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdngi", OPTO(2,TONG), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdnei", OPTO(2,TONE), OPTO_MASK, PPC64, { RA, SI } },
+{ "tdi", OP(2), OP_MASK, PPC64, { TO, RA, SI } },
+
+{ "twlgti", OPTO(3,TOLGT), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tlgti", OPTO(3,TOLGT), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twllti", OPTO(3,TOLLT), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tllti", OPTO(3,TOLLT), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "tweqi", OPTO(3,TOEQ), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "teqi", OPTO(3,TOEQ), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twlgei", OPTO(3,TOLGE), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tlgei", OPTO(3,TOLGE), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twlnli", OPTO(3,TOLNL), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tlnli", OPTO(3,TOLNL), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twllei", OPTO(3,TOLLE), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tllei", OPTO(3,TOLLE), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twlngi", OPTO(3,TOLNG), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tlngi", OPTO(3,TOLNG), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twgti", OPTO(3,TOGT), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tgti", OPTO(3,TOGT), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twgei", OPTO(3,TOGE), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tgei", OPTO(3,TOGE), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twnli", OPTO(3,TONL), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tnli", OPTO(3,TONL), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twlti", OPTO(3,TOLT), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tlti", OPTO(3,TOLT), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twlei", OPTO(3,TOLE), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tlei", OPTO(3,TOLE), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twngi", OPTO(3,TONG), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tngi", OPTO(3,TONG), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twnei", OPTO(3,TONE), OPTO_MASK, PPCCOM, { RA, SI } },
+{ "tnei", OPTO(3,TONE), OPTO_MASK, PWRCOM, { RA, SI } },
+{ "twi", OP(3), OP_MASK, PPCCOM, { TO, RA, SI } },
+{ "ti", OP(3), OP_MASK, PWRCOM, { TO, RA, SI } },
+
+{ "mulli", OP(7), OP_MASK, PPCCOM, { RT, RA, SI } },
+{ "muli", OP(7), OP_MASK, PWRCOM, { RT, RA, SI } },
+
+{ "subfic", OP(8), OP_MASK, PPCCOM, { RT, RA, SI } },
+{ "sfi", OP(8), OP_MASK, PWRCOM, { RT, RA, SI } },
+
+{ "dozi", OP(9), OP_MASK, M601, { RT, RA, SI } },
+
+{ "cmplwi", OPL(10,0), OPL_MASK, PPCCOM, { OBF, RA, UI }
},
+{ "cmpldi", OPL(10,1), OPL_MASK, PPC64, { OBF, RA, UI } },
+{ "cmpli", OP(10), OP_MASK, PPCONLY, { BF, L, RA, UI } },
+{ "cmpli", OP(10), OP_MASK, PWRCOM, { BF, RA, UI } },
+
+{ "cmpwi", OPL(11,0), OPL_MASK, PPCCOM, { OBF, RA, SI }
},
+{ "cmpdi", OPL(11,1), OPL_MASK, PPC64, { OBF, RA, SI }
},
+{ "cmpi", OP(11), OP_MASK, PPCONLY, { BF, L, RA, SI } },
+{ "cmpi", OP(11), OP_MASK, PWRCOM, { BF, RA, SI } },
+
+{ "addic", OP(12), OP_MASK, PPCCOM, { RT, RA, SI } },
+{ "ai", OP(12), OP_MASK, PWRCOM, { RT, RA, SI }
},
+{ "subic", OP(12), OP_MASK, PPCCOM, { RT, RA, NSI } },
+
+{ "addic.", OP(13), OP_MASK, PPCCOM, { RT, RA, SI } },
+{ "ai.", OP(13), OP_MASK, PWRCOM, { RT, RA, SI } },
+{ "subic.", OP(13), OP_MASK, PPCCOM, { RT, RA, NSI } },
+
+{ "li", OP(14), DRA_MASK, PPCCOM, { RT, SI } },
+{ "lil", OP(14), DRA_MASK, PWRCOM, { RT, SI } },
+{ "addi", OP(14), OP_MASK, PPCCOM, { RT, RA, SI } },
+{ "cal", OP(14), OP_MASK, PWRCOM, { RT, D, RA } },
+{ "subi", OP(14), OP_MASK, PPCCOM, { RT, RA, NSI } },
+{ "la", OP(14), OP_MASK, PPCCOM, { RT, D, RA } },
+
+{ "lis", OP(15), DRA_MASK, PPCCOM, { RT, SISIGNOPT } },
+{ "liu", OP(15), DRA_MASK, PWRCOM, { RT, SISIGNOPT } },
+{ "addis", OP(15), OP_MASK, PPCCOM, { RT,RA,SISIGNOPT } },
+{ "cau", OP(15), OP_MASK, PWRCOM, { RT,RA,SISIGNOPT } },
+{ "subis", OP(15), OP_MASK, PPCCOM, { RT, RA, NSI } },
+
+{ "bdnz-", BBO(16,BODNZ,0,0), BBOYBI_MASK, PPC, { BDM } },
+{ "bdnz+", BBO(16,BODNZ,0,0), BBOYBI_MASK, PPC, { BDP } },
+{ "bdnz", BBO(16,BODNZ,0,0), BBOYBI_MASK, PPCCOM, { BD } },
+{ "bdn", BBO(16,BODNZ,0,0), BBOYBI_MASK, PWRCOM, { BD } },
+{ "bdnzl-", BBO(16,BODNZ,0,1), BBOYBI_MASK, PPC, { BDM } },
+{ "bdnzl+", BBO(16,BODNZ,0,1), BBOYBI_MASK, PPC, { BDP } },
+{ "bdnzl", BBO(16,BODNZ,0,1), BBOYBI_MASK, PPCCOM, { BD } },
+{ "bdnl", BBO(16,BODNZ,0,1), BBOYBI_MASK, PWRCOM, { BD } },
+{ "bdnza-", BBO(16,BODNZ,1,0), BBOYBI_MASK, PPC, { BDMA } },
+{ "bdnza+", BBO(16,BODNZ,1,0), BBOYBI_MASK, PPC, { BDPA } },
+{ "bdnza", BBO(16,BODNZ,1,0), BBOYBI_MASK, PPCCOM, { BDA } },
+{ "bdna", BBO(16,BODNZ,1,0), BBOYBI_MASK, PWRCOM, { BDA } },
+{ "bdnzla-", BBO(16,BODNZ,1,1), BBOYBI_MASK, PPC, { BDMA } },
+{ "bdnzla+", BBO(16,BODNZ,1,1), BBOYBI_MASK, PPC, { BDPA } },
+{ "bdnzla", BBO(16,BODNZ,1,1), BBOYBI_MASK, PPCCOM, { BDA } },
+{ "bdnla", BBO(16,BODNZ,1,1), BBOYBI_MASK, PWRCOM, { BDA } },
+{ "bdz-", BBO(16,BODZ,0,0), BBOYBI_MASK, PPC, { BDM } },
+{ "bdz+", BBO(16,BODZ,0,0), BBOYBI_MASK, PPC, { BDP } },
+{ "bdz", BBO(16,BODZ,0,0), BBOYBI_MASK, COM, { BD } },
+{ "bdzl-", BBO(16,BODZ,0,1), BBOYBI_MASK, PPC, { BDM } },
+{ "bdzl+", BBO(16,BODZ,0,1), BBOYBI_MASK, PPC, { BDP } },
+{ "bdzl", BBO(16,BODZ,0,1), BBOYBI_MASK, COM, { BD } },
+{ "bdza-", BBO(16,BODZ,1,0), BBOYBI_MASK, PPC, { BDMA } },
+{ "bdza+", BBO(16,BODZ,1,0), BBOYBI_MASK, PPC, { BDPA } },
+{ "bdza", BBO(16,BODZ,1,0), BBOYBI_MASK, COM, { BDA } },
+{ "bdzla-", BBO(16,BODZ,1,1), BBOYBI_MASK, PPC, { BDMA } },
+{ "bdzla+", BBO(16,BODZ,1,1), BBOYBI_MASK, PPC, { BDPA } },
+{ "bdzla", BBO(16,BODZ,1,1), BBOYBI_MASK, COM, { BDA } },
+{ "blt-", BBOCB(16,BOT,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "blt+", BBOCB(16,BOT,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "blt", BBOCB(16,BOT,CBLT,0,0), BBOYCB_MASK, COM, { CR, BD } },
+{ "bltl-", BBOCB(16,BOT,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bltl+", BBOCB(16,BOT,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bltl", BBOCB(16,BOT,CBLT,0,1), BBOYCB_MASK, COM, { CR, BD } },
+{ "blta-", BBOCB(16,BOT,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "blta+", BBOCB(16,BOT,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "blta", BBOCB(16,BOT,CBLT,1,0), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bltla-", BBOCB(16,BOT,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bltla+", BBOCB(16,BOT,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bltla", BBOCB(16,BOT,CBLT,1,1), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bgt-", BBOCB(16,BOT,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bgt+", BBOCB(16,BOT,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bgt", BBOCB(16,BOT,CBGT,0,0), BBOYCB_MASK, COM, { CR, BD } },
+{ "bgtl-", BBOCB(16,BOT,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bgtl+", BBOCB(16,BOT,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bgtl", BBOCB(16,BOT,CBGT,0,1), BBOYCB_MASK, COM, { CR, BD } },
+{ "bgta-", BBOCB(16,BOT,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bgta+", BBOCB(16,BOT,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bgta", BBOCB(16,BOT,CBGT,1,0), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bgtla-", BBOCB(16,BOT,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bgtla+", BBOCB(16,BOT,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bgtla", BBOCB(16,BOT,CBGT,1,1), BBOYCB_MASK, COM, { CR, BDA } },
+{ "beq-", BBOCB(16,BOT,CBEQ,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "beq+", BBOCB(16,BOT,CBEQ,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "beq", BBOCB(16,BOT,CBEQ,0,0), BBOYCB_MASK, COM, { CR, BD } },
+{ "beql-", BBOCB(16,BOT,CBEQ,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "beql+", BBOCB(16,BOT,CBEQ,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "beql", BBOCB(16,BOT,CBEQ,0,1), BBOYCB_MASK, COM, { CR, BD } },
+{ "beqa-", BBOCB(16,BOT,CBEQ,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "beqa+", BBOCB(16,BOT,CBEQ,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "beqa", BBOCB(16,BOT,CBEQ,1,0), BBOYCB_MASK, COM, { CR, BDA } },
+{ "beqla-", BBOCB(16,BOT,CBEQ,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "beqla+", BBOCB(16,BOT,CBEQ,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "beqla", BBOCB(16,BOT,CBEQ,1,1), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bso-", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bso+", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bso", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, COM, { CR, BD } },
+{ "bsol-", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bsol+", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bsol", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, COM, { CR, BD } },
+{ "bsoa-", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bsoa+", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bsoa", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bsola-", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bsola+", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bsola", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bun-", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bun+", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bun", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPCCOM, { CR, BD } },
+{ "bunl-", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bunl+", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bunl", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPCCOM, { CR, BD } },
+{ "buna-", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "buna+", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "buna", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPCCOM, { CR, BDA } },
+{ "bunla-", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bunla+", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bunla", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPCCOM, { CR, BDA } },
+{ "bge-", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bge+", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bge", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, COM, { CR, BD } },
+{ "bgel-", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bgel+", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bgel", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, COM, { CR, BD } },
+{ "bgea-", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bgea+", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bgea", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bgela-", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bgela+", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bgela", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bnl-", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bnl+", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bnl", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, COM, { CR, BD } },
+{ "bnll-", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bnll+", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bnll", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, COM, { CR, BD } },
+{ "bnla-", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bnla+", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bnla", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bnlla-", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bnlla+", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bnlla", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, COM, { CR, BDA } },
+{ "ble-", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "ble+", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "ble", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, COM, { CR, BD } },
+{ "blel-", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "blel+", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "blel", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, COM, { CR, BD } },
+{ "blea-", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "blea+", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "blea", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, COM, { CR, BDA } },
+{ "blela-", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "blela+", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "blela", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bng-", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bng+", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bng", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, COM, { CR, BD } },
+{ "bngl-", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bngl+", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bngl", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, COM, { CR, BD } },
+{ "bnga-", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bnga+", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bnga", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bngla-", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bngla+", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bngla", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bne-", BBOCB(16,BOF,CBEQ,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bne+", BBOCB(16,BOF,CBEQ,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bne", BBOCB(16,BOF,CBEQ,0,0), BBOYCB_MASK, COM, { CR, BD } },
+{ "bnel-", BBOCB(16,BOF,CBEQ,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bnel+", BBOCB(16,BOF,CBEQ,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bnel", BBOCB(16,BOF,CBEQ,0,1), BBOYCB_MASK, COM, { CR, BD } },
+{ "bnea-", BBOCB(16,BOF,CBEQ,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bnea+", BBOCB(16,BOF,CBEQ,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bnea", BBOCB(16,BOF,CBEQ,1,0), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bnela-", BBOCB(16,BOF,CBEQ,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bnela+", BBOCB(16,BOF,CBEQ,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bnela", BBOCB(16,BOF,CBEQ,1,1), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bns-", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bns+", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bns", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, COM, { CR, BD } },
+{ "bnsl-", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bnsl+", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bnsl", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, COM, { CR, BD } },
+{ "bnsa-", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bnsa+", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bnsa", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bnsla-", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bnsla+", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bnsla", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, COM, { CR, BDA } },
+{ "bnu-", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bnu+", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bnu", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPCCOM, { CR, BD } },
+{ "bnul-", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
+{ "bnul+", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
+{ "bnul", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPCCOM, { CR, BD } },
+{ "bnua-", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bnua+", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bnua", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPCCOM, { CR, BDA } },
+{ "bnula-", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
+{ "bnula+", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
+{ "bnula", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPCCOM, { CR, BDA } },
+{ "bdnzt-", BBO(16,BODNZT,0,0), BBOY_MASK, PPC, { BI, BDM } },
+{ "bdnzt+", BBO(16,BODNZT,0,0), BBOY_MASK, PPC, { BI, BDP } },
+{ "bdnzt", BBO(16,BODNZT,0,0), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bdnztl-", BBO(16,BODNZT,0,1), BBOY_MASK, PPC, { BI, BDM } },
+{ "bdnztl+", BBO(16,BODNZT,0,1), BBOY_MASK, PPC, { BI, BDP } },
+{ "bdnztl", BBO(16,BODNZT,0,1), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bdnzta-", BBO(16,BODNZT,1,0), BBOY_MASK, PPC, { BI, BDMA } },
+{ "bdnzta+", BBO(16,BODNZT,1,0), BBOY_MASK, PPC, { BI, BDPA } },
+{ "bdnzta", BBO(16,BODNZT,1,0), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bdnztla-",BBO(16,BODNZT,1,1), BBOY_MASK, PPC, { BI, BDMA } },
+{ "bdnztla+",BBO(16,BODNZT,1,1), BBOY_MASK, PPC, { BI, BDPA } },
+{ "bdnztla", BBO(16,BODNZT,1,1), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bdnzf-", BBO(16,BODNZF,0,0), BBOY_MASK, PPC, { BI, BDM } },
+{ "bdnzf+", BBO(16,BODNZF,0,0), BBOY_MASK, PPC, { BI, BDP } },
+{ "bdnzf", BBO(16,BODNZF,0,0), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bdnzfl-", BBO(16,BODNZF,0,1), BBOY_MASK, PPC, { BI, BDM } },
+{ "bdnzfl+", BBO(16,BODNZF,0,1), BBOY_MASK, PPC, { BI, BDP } },
+{ "bdnzfl", BBO(16,BODNZF,0,1), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bdnzfa-", BBO(16,BODNZF,1,0), BBOY_MASK, PPC, { BI, BDMA } },
+{ "bdnzfa+", BBO(16,BODNZF,1,0), BBOY_MASK, PPC, { BI, BDPA } },
+{ "bdnzfa", BBO(16,BODNZF,1,0), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bdnzfla-",BBO(16,BODNZF,1,1), BBOY_MASK, PPC, { BI, BDMA } },
+{ "bdnzfla+",BBO(16,BODNZF,1,1), BBOY_MASK, PPC, { BI, BDPA } },
+{ "bdnzfla", BBO(16,BODNZF,1,1), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bt-", BBO(16,BOT,0,0), BBOY_MASK, PPC, { BI, BDM } },
+{ "bt+", BBO(16,BOT,0,0), BBOY_MASK, PPC, { BI, BDP } },
+{ "bt", BBO(16,BOT,0,0), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bbt", BBO(16,BOT,0,0), BBOY_MASK, PWRCOM, { BI, BD } },
+{ "btl-", BBO(16,BOT,0,1), BBOY_MASK, PPC, { BI, BDM } },
+{ "btl+", BBO(16,BOT,0,1), BBOY_MASK, PPC, { BI, BDP } },
+{ "btl", BBO(16,BOT,0,1), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bbtl", BBO(16,BOT,0,1), BBOY_MASK, PWRCOM, { BI, BD } },
+{ "bta-", BBO(16,BOT,1,0), BBOY_MASK, PPC, { BI, BDMA } },
+{ "bta+", BBO(16,BOT,1,0), BBOY_MASK, PPC, { BI, BDPA } },
+{ "bta", BBO(16,BOT,1,0), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bbta", BBO(16,BOT,1,0), BBOY_MASK, PWRCOM, { BI, BDA } },
+{ "btla-", BBO(16,BOT,1,1), BBOY_MASK, PPC, { BI, BDMA } },
+{ "btla+", BBO(16,BOT,1,1), BBOY_MASK, PPC, { BI, BDPA } },
+{ "btla", BBO(16,BOT,1,1), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bbtla", BBO(16,BOT,1,1), BBOY_MASK, PWRCOM, { BI, BDA } },
+{ "bf-", BBO(16,BOF,0,0), BBOY_MASK, PPC, { BI, BDM } },
+{ "bf+", BBO(16,BOF,0,0), BBOY_MASK, PPC, { BI, BDP } },
+{ "bf", BBO(16,BOF,0,0), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bbf", BBO(16,BOF,0,0), BBOY_MASK, PWRCOM, { BI, BD } },
+{ "bfl-", BBO(16,BOF,0,1), BBOY_MASK, PPC, { BI, BDM } },
+{ "bfl+", BBO(16,BOF,0,1), BBOY_MASK, PPC, { BI, BDP } },
+{ "bfl", BBO(16,BOF,0,1), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bbfl", BBO(16,BOF,0,1), BBOY_MASK, PWRCOM, { BI, BD } },
+{ "bfa-", BBO(16,BOF,1,0), BBOY_MASK, PPC, { BI, BDMA } },
+{ "bfa+", BBO(16,BOF,1,0), BBOY_MASK, PPC, { BI, BDPA } },
+{ "bfa", BBO(16,BOF,1,0), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bbfa", BBO(16,BOF,1,0), BBOY_MASK, PWRCOM, { BI, BDA } },
+{ "bfla-", BBO(16,BOF,1,1), BBOY_MASK, PPC, { BI, BDMA } },
+{ "bfla+", BBO(16,BOF,1,1), BBOY_MASK, PPC, { BI, BDPA } },
+{ "bfla", BBO(16,BOF,1,1), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bbfla", BBO(16,BOF,1,1), BBOY_MASK, PWRCOM, { BI, BDA } },
+{ "bdzt-", BBO(16,BODZT,0,0), BBOY_MASK, PPC, { BI, BDM } },
+{ "bdzt+", BBO(16,BODZT,0,0), BBOY_MASK, PPC, { BI, BDP } },
+{ "bdzt", BBO(16,BODZT,0,0), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bdztl-", BBO(16,BODZT,0,1), BBOY_MASK, PPC, { BI, BDM } },
+{ "bdztl+", BBO(16,BODZT,0,1), BBOY_MASK, PPC, { BI, BDP } },
+{ "bdztl", BBO(16,BODZT,0,1), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bdzta-", BBO(16,BODZT,1,0), BBOY_MASK, PPC, { BI, BDMA } },
+{ "bdzta+", BBO(16,BODZT,1,0), BBOY_MASK, PPC, { BI, BDPA } },
+{ "bdzta", BBO(16,BODZT,1,0), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bdztla-", BBO(16,BODZT,1,1), BBOY_MASK, PPC, { BI, BDMA } },
+{ "bdztla+", BBO(16,BODZT,1,1), BBOY_MASK, PPC, { BI, BDPA } },
+{ "bdztla", BBO(16,BODZT,1,1), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bdzf-", BBO(16,BODZF,0,0), BBOY_MASK, PPC, { BI, BDM } },
+{ "bdzf+", BBO(16,BODZF,0,0), BBOY_MASK, PPC, { BI, BDP } },
+{ "bdzf", BBO(16,BODZF,0,0), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bdzfl-", BBO(16,BODZF,0,1), BBOY_MASK, PPC, { BI, BDM } },
+{ "bdzfl+", BBO(16,BODZF,0,1), BBOY_MASK, PPC, { BI, BDP } },
+{ "bdzfl", BBO(16,BODZF,0,1), BBOY_MASK, PPCCOM, { BI, BD } },
+{ "bdzfa-", BBO(16,BODZF,1,0), BBOY_MASK, PPC, { BI, BDMA } },
+{ "bdzfa+", BBO(16,BODZF,1,0), BBOY_MASK, PPC, { BI, BDPA } },
+{ "bdzfa", BBO(16,BODZF,1,0), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bdzfla-", BBO(16,BODZF,1,1), BBOY_MASK, PPC, { BI, BDMA } },
+{ "bdzfla+", BBO(16,BODZF,1,1), BBOY_MASK, PPC, { BI, BDPA } },
+{ "bdzfla", BBO(16,BODZF,1,1), BBOY_MASK, PPCCOM, { BI, BDA } },
+{ "bc-", B(16,0,0), B_MASK, PPC, { BOE, BI, BDM
} },
+{ "bc+", B(16,0,0), B_MASK, PPC, { BOE, BI, BDP
} },
+{ "bc", B(16,0,0), B_MASK, COM, { BO, BI, BD }
},
+{ "bcl-", B(16,0,1), B_MASK, PPC, { BOE, BI, BDM
} },
+{ "bcl+", B(16,0,1), B_MASK, PPC, { BOE, BI, BDP
} },
+{ "bcl", B(16,0,1), B_MASK, COM, { BO, BI, BD }
},
+{ "bca-", B(16,1,0), B_MASK, PPC, { BOE, BI, BDMA
} },
+{ "bca+", B(16,1,0), B_MASK, PPC, { BOE, BI, BDPA
} },
+{ "bca", B(16,1,0), B_MASK, COM, { BO, BI, BDA }
},
+{ "bcla-", B(16,1,1), B_MASK, PPC, { BOE, BI, BDMA
} },
+{ "bcla+", B(16,1,1), B_MASK, PPC, { BOE, BI, BDPA
} },
+{ "bcla", B(16,1,1), B_MASK, COM, { BO, BI, BDA }
},
+
+{ "sc", SC(17,1,0), 0xffffffff, PPC, { 0 } },
+{ "svc", SC(17,0,0), SC_MASK, POWER, { LEV, FL1, FL2 } },
+{ "svcl", SC(17,0,1), SC_MASK, POWER, { LEV, FL1, FL2 } },
+{ "svca", SC(17,1,0), SC_MASK, PWRCOM, { SV } },
+{ "svcla", SC(17,1,1), SC_MASK, POWER, { SV } },
+
+{ "b", B(18,0,0), B_MASK, COM, { LI } },
+{ "bl", B(18,0,1), B_MASK, COM, { LI } },
+{ "ba", B(18,1,0), B_MASK, COM, { LIA } },
+{ "bla", B(18,1,1), B_MASK, COM, { LIA } },
+
+{ "mcrf", XL(19,0), XLBB_MASK|(3<<21)|(3<<16), COM, { BF, BFA } },
+
+{ "blr", XLO(19,BOU,16,0), XLBOBIBB_MASK, PPCCOM, { 0 } },
+{ "br", XLO(19,BOU,16,0), XLBOBIBB_MASK, PWRCOM, { 0 } },
+{ "blrl", XLO(19,BOU,16,1), XLBOBIBB_MASK, PPCCOM, { 0 } },
+{ "brl", XLO(19,BOU,16,1), XLBOBIBB_MASK, PWRCOM, { 0 } },
+{ "bdnzlr", XLO(19,BODNZ,16,0), XLBOBIBB_MASK, PPCCOM, { 0 } },
+{ "bdnzlr-", XLO(19,BODNZ,16,0), XLBOBIBB_MASK, PPC, { 0 } },
+{ "bdnzlr+", XLO(19,BODNZP,16,0), XLBOBIBB_MASK, PPC, { 0 } },
+{ "bdnzlrl", XLO(19,BODNZ,16,1), XLBOBIBB_MASK, PPCCOM, { 0 } },
+{ "bdnzlrl-",XLO(19,BODNZ,16,1), XLBOBIBB_MASK, PPC, { 0 } },
+{ "bdnzlrl+",XLO(19,BODNZP,16,1), XLBOBIBB_MASK, PPC, { 0 } },
+{ "bdzlr", XLO(19,BODZ,16,0), XLBOBIBB_MASK, PPCCOM, { 0 } },
+{ "bdzlr-", XLO(19,BODZ,16,0), XLBOBIBB_MASK, PPC, { 0 } },
+{ "bdzlr+", XLO(19,BODZP,16,0), XLBOBIBB_MASK, PPC, { 0 } },
+{ "bdzlrl", XLO(19,BODZ,16,1), XLBOBIBB_MASK, PPCCOM, { 0 } },
+{ "bdzlrl-", XLO(19,BODZ,16,1), XLBOBIBB_MASK, PPC, { 0 } },
+{ "bdzlrl+", XLO(19,BODZP,16,1), XLBOBIBB_MASK, PPC, { 0 } },
+{ "bltlr", XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bltlr-", XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltlr+", XLOCB(19,BOTP,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltr", XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bltlrl", XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bltlrl-", XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltlrl+", XLOCB(19,BOTP,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltrl", XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bgtlr", XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bgtlr-", XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtlr+", XLOCB(19,BOTP,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtr", XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bgtlrl", XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bgtlrl-", XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtlrl+", XLOCB(19,BOTP,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtrl", XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "beqlr", XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "beqlr-", XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqlr+", XLOCB(19,BOTP,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqr", XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "beqlrl", XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "beqlrl-", XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqlrl+", XLOCB(19,BOTP,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqrl", XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bsolr", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bsolr-", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsolr+", XLOCB(19,BOTP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsor", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bsolrl", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bsolrl-", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsolrl+", XLOCB(19,BOTP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsorl", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bunlr", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bunlr-", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunlr+", XLOCB(19,BOTP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunlrl", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bunlrl-", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunlrl+", XLOCB(19,BOTP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgelr", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bgelr-", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgelr+", XLOCB(19,BOFP,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bger", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bgelrl", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bgelrl-", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgelrl+", XLOCB(19,BOFP,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgerl", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bnllr", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnllr-", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnllr+", XLOCB(19,BOFP,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlr", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bnllrl", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnllrl-", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnllrl+", XLOCB(19,BOFP,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlrl", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "blelr", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "blelr-", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "blelr+", XLOCB(19,BOFP,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bler", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "blelrl", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "blelrl-", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "blelrl+", XLOCB(19,BOFP,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "blerl", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bnglr", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnglr-", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnglr+", XLOCB(19,BOFP,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngr", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bnglrl", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnglrl-", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnglrl+", XLOCB(19,BOFP,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngrl", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bnelr", XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnelr-", XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnelr+", XLOCB(19,BOFP,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bner", XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bnelrl", XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnelrl-", XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnelrl+", XLOCB(19,BOFP,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnerl", XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bnslr", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnslr-", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnslr+", XLOCB(19,BOFP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsr", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bnslrl", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnslrl-", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnslrl+", XLOCB(19,BOFP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsrl", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PWRCOM, { CR } },
+{ "bnulr", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnulr-", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnulr+", XLOCB(19,BOFP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnulrl", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnulrl-", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnulrl+", XLOCB(19,BOFP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "btlr", XLO(19,BOT,16,0), XLBOBB_MASK, PPCCOM, { BI } },
+{ "btlr-", XLO(19,BOT,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "btlr+", XLO(19,BOTP,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "bbtr", XLO(19,BOT,16,0), XLBOBB_MASK, PWRCOM, { BI } },
+{ "btlrl", XLO(19,BOT,16,1), XLBOBB_MASK, PPCCOM, { BI } },
+{ "btlrl-", XLO(19,BOT,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "btlrl+", XLO(19,BOTP,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "bbtrl", XLO(19,BOT,16,1), XLBOBB_MASK, PWRCOM, { BI } },
+{ "bflr", XLO(19,BOF,16,0), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bflr-", XLO(19,BOF,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "bflr+", XLO(19,BOFP,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "bbfr", XLO(19,BOF,16,0), XLBOBB_MASK, PWRCOM, { BI } },
+{ "bflrl", XLO(19,BOF,16,1), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bflrl-", XLO(19,BOF,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "bflrl+", XLO(19,BOFP,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "bbfrl", XLO(19,BOF,16,1), XLBOBB_MASK, PWRCOM, { BI } },
+{ "bdnztlr", XLO(19,BODNZT,16,0), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bdnztlr-",XLO(19,BODNZT,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "bdnztlr+",XLO(19,BODNZTP,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "bdnztlrl",XLO(19,BODNZT,16,1), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bdnztlrl-",XLO(19,BODNZT,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "bdnztlrl+",XLO(19,BODNZTP,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "bdnzflr", XLO(19,BODNZF,16,0), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bdnzflr-",XLO(19,BODNZF,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "bdnzflr+",XLO(19,BODNZFP,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "bdnzflrl",XLO(19,BODNZF,16,1), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bdnzflrl-",XLO(19,BODNZF,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "bdnzflrl+",XLO(19,BODNZFP,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "bdztlr", XLO(19,BODZT,16,0), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bdztlr-", XLO(19,BODZT,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "bdztlr+", XLO(19,BODZTP,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "bdztlrl", XLO(19,BODZT,16,1), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bdztlrl-",XLO(19,BODZT,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "bdztlrl+",XLO(19,BODZTP,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "bdzflr", XLO(19,BODZF,16,0), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bdzflr-", XLO(19,BODZF,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "bdzflr+", XLO(19,BODZFP,16,0), XLBOBB_MASK, PPC, { BI } },
+{ "bdzflrl", XLO(19,BODZF,16,1), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bdzflrl-",XLO(19,BODZF,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "bdzflrl+",XLO(19,BODZFP,16,1), XLBOBB_MASK, PPC, { BI } },
+{ "bclr", XLLK(19,16,0), XLYBB_MASK, PPCCOM, { BO, BI } },
+{ "bclrl", XLLK(19,16,1), XLYBB_MASK, PPCCOM, { BO, BI } },
+{ "bclr+", XLYLK(19,16,1,0), XLYBB_MASK, PPC, { BOE, BI } },
+{ "bclrl+", XLYLK(19,16,1,1), XLYBB_MASK, PPC, { BOE, BI } },
+{ "bclr-", XLYLK(19,16,0,0), XLYBB_MASK, PPC, { BOE, BI } },
+{ "bclrl-", XLYLK(19,16,0,1), XLYBB_MASK, PPC, { BOE, BI } },
+{ "bcr", XLLK(19,16,0), XLBB_MASK, PWRCOM, { BO, BI } },
+{ "bcrl", XLLK(19,16,1), XLBB_MASK, PWRCOM, { BO, BI } },
+
+{ "crnot", XL(19,33), XL_MASK, PPCCOM, { BT, BA, BBA } },
+{ "crnor", XL(19,33), XL_MASK, COM, { BT, BA, BB }
},
+
+{ "rfi", XL(19,50), 0xffffffff, COM, { 0 } },
+{ "rfci", XL(19,51), 0xffffffff, PPC, { 0 } },
+
+{ "rfsvc", XL(19,82), 0xffffffff, POWER, { 0 } },
+
+{ "crandc", XL(19,129), XL_MASK, COM, { BT, BA, BB } },
+
+{ "isync", XL(19,150), 0xffffffff, PPCCOM, { 0 } },
+{ "ics", XL(19,150), 0xffffffff, PWRCOM, { 0 } },
+
+{ "crclr", XL(19,193), XL_MASK, PPCCOM, { BT, BAT, BBA } },
+{ "crxor", XL(19,193), XL_MASK, COM, { BT, BA, BB } },
+
+{ "crnand", XL(19,225), XL_MASK, COM, { BT, BA, BB } },
+
+{ "crand", XL(19,257), XL_MASK, COM, { BT, BA, BB } },
+
+{ "crset", XL(19,289), XL_MASK, PPCCOM, { BT, BAT, BBA } },
+{ "creqv", XL(19,289), XL_MASK, COM, { BT, BA, BB } },
+
+{ "crorc", XL(19,417), XL_MASK, COM, { BT, BA, BB } },
+
+{ "crmove", XL(19,449), XL_MASK, PPCCOM, { BT, BA, BBA } },
+{ "cror", XL(19,449), XL_MASK, COM, { BT, BA, BB } },
+
+{ "bctr", XLO(19,BOU,528,0), XLBOBIBB_MASK, COM, { 0 } },
+{ "bctrl", XLO(19,BOU,528,1), XLBOBIBB_MASK, COM, { 0 } },
+{ "bltctr", XLOCB(19,BOT,CBLT,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bltctr-", XLOCB(19,BOT,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltctr+", XLOCB(19,BOTP,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltctrl", XLOCB(19,BOT,CBLT,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bltctrl-",XLOCB(19,BOT,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bltctrl+",XLOCB(19,BOTP,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtctr", XLOCB(19,BOT,CBGT,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bgtctr-", XLOCB(19,BOT,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtctr+", XLOCB(19,BOTP,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtctrl", XLOCB(19,BOT,CBGT,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bgtctrl-",XLOCB(19,BOT,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgtctrl+",XLOCB(19,BOTP,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqctr", XLOCB(19,BOT,CBEQ,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "beqctr-", XLOCB(19,BOT,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqctr+", XLOCB(19,BOTP,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqctrl", XLOCB(19,BOT,CBEQ,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "beqctrl-",XLOCB(19,BOT,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "beqctrl+",XLOCB(19,BOTP,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsoctr", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bsoctr-", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsoctr+", XLOCB(19,BOTP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsoctrl", XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bsoctrl-",XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bsoctrl+",XLOCB(19,BOTP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunctr", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bunctr-", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunctr+", XLOCB(19,BOTP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunctrl", XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bunctrl-",XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bunctrl+",XLOCB(19,BOTP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgectr", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bgectr-", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgectr+", XLOCB(19,BOFP,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgectrl", XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bgectrl-",XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bgectrl+",XLOCB(19,BOFP,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlctr", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnlctr-", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlctr+", XLOCB(19,BOFP,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlctrl", XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnlctrl-",XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnlctrl+",XLOCB(19,BOFP,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "blectr", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "blectr-", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "blectr+", XLOCB(19,BOFP,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "blectrl", XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "blectrl-",XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "blectrl+",XLOCB(19,BOFP,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngctr", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bngctr-", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngctr+", XLOCB(19,BOFP,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngctrl", XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bngctrl-",XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bngctrl+",XLOCB(19,BOFP,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnectr", XLOCB(19,BOF,CBEQ,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnectr-", XLOCB(19,BOF,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnectr+", XLOCB(19,BOFP,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnectrl", XLOCB(19,BOF,CBEQ,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnectrl-",XLOCB(19,BOF,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnectrl+",XLOCB(19,BOFP,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsctr", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnsctr-", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsctr+", XLOCB(19,BOFP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsctrl", XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnsctrl-",XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnsctrl+",XLOCB(19,BOFP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnuctr", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnuctr-", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnuctr+", XLOCB(19,BOFP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnuctrl", XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPCCOM, { CR } },
+{ "bnuctrl-",XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "bnuctrl+",XLOCB(19,BOFP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
+{ "btctr", XLO(19,BOT,528,0), XLBOBB_MASK, PPCCOM, { BI } },
+{ "btctr-", XLO(19,BOT,528,0), XLBOBB_MASK, PPC, { BI } },
+{ "btctr+", XLO(19,BOTP,528,0), XLBOBB_MASK, PPC, { BI } },
+{ "btctrl", XLO(19,BOT,528,1), XLBOBB_MASK, PPCCOM, { BI } },
+{ "btctrl-", XLO(19,BOT,528,1), XLBOBB_MASK, PPC, { BI } },
+{ "btctrl+", XLO(19,BOTP,528,1), XLBOBB_MASK, PPC, { BI } },
+{ "bfctr", XLO(19,BOF,528,0), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bfctr-", XLO(19,BOF,528,0), XLBOBB_MASK, PPC, { BI } },
+{ "bfctr+", XLO(19,BOFP,528,0), XLBOBB_MASK, PPC, { BI } },
+{ "bfctrl", XLO(19,BOF,528,1), XLBOBB_MASK, PPCCOM, { BI } },
+{ "bfctrl-", XLO(19,BOF,528,1), XLBOBB_MASK, PPC, { BI } },
+{ "bfctrl+", XLO(19,BOFP,528,1), XLBOBB_MASK, PPC, { BI } },
+{ "bcctr", XLLK(19,528,0), XLYBB_MASK, PPCCOM, { BO, BI } },
+{ "bcctr-", XLYLK(19,528,0,0), XLYBB_MASK, PPC, { BOE, BI } },
+{ "bcctr+", XLYLK(19,528,1,0), XLYBB_MASK, PPC, { BOE, BI } },
+{ "bcctrl", XLLK(19,528,1), XLYBB_MASK, PPCCOM, { BO, BI } },
+{ "bcctrl-", XLYLK(19,528,0,1), XLYBB_MASK, PPC, { BOE, BI } },
+{ "bcctrl+", XLYLK(19,528,1,1), XLYBB_MASK, PPC, { BOE, BI } },
+{ "bcc", XLLK(19,528,0), XLBB_MASK, PWRCOM, { BO, BI } },
+{ "bccl", XLLK(19,528,1), XLBB_MASK, PWRCOM, { BO, BI } },
+
+{ "rlwimi", M(20,0), M_MASK, PPCCOM, { RA,RS,SH,MBE,ME } },
+{ "rlimi", M(20,0), M_MASK, PWRCOM, { RA,RS,SH,MBE,ME } },
+
+{ "rlwimi.", M(20,1), M_MASK, PPCCOM, { RA,RS,SH,MBE,ME } },
+{ "rlimi.", M(20,1), M_MASK, PWRCOM, { RA,RS,SH,MBE,ME } },
+
+{ "rotlwi", MME(21,31,0), MMBME_MASK, PPCCOM, { RA, RS, SH } },
+{ "clrlwi", MME(21,31,0), MSHME_MASK, PPCCOM, { RA, RS, MB } },
+{ "rlwinm", M(21,0), M_MASK, PPCCOM, { RA,RS,SH,MBE,ME } },
+{ "rlinm", M(21,0), M_MASK, PWRCOM, { RA,RS,SH,MBE,ME } },
+{ "rotlwi.", MME(21,31,1), MMBME_MASK, PPCCOM, { RA,RS,SH } },
+{ "clrlwi.", MME(21,31,1), MSHME_MASK, PPCCOM, { RA, RS, MB } },
+{ "rlwinm.", M(21,1), M_MASK, PPCCOM, { RA,RS,SH,MBE,ME } },
+{ "rlinm.", M(21,1), M_MASK, PWRCOM, { RA,RS,SH,MBE,ME } },
+
+{ "rlmi", M(22,0), M_MASK, M601, { RA,RS,RB,MBE,ME } },
+{ "rlmi.", M(22,1), M_MASK, M601, { RA,RS,RB,MBE,ME } },
+
+{ "rotlw", MME(23,31,0), MMBME_MASK, PPCCOM, { RA, RS, RB } },
+{ "rlwnm", M(23,0), M_MASK, PPCCOM, { RA,RS,RB,MBE,ME } },
+{ "rlnm", M(23,0), M_MASK, PWRCOM, { RA,RS,RB,MBE,ME } },
+{ "rotlw.", MME(23,31,1), MMBME_MASK, PPCCOM, { RA, RS, RB } },
+{ "rlwnm.", M(23,1), M_MASK, PPCCOM, { RA,RS,RB,MBE,ME } },
+{ "rlnm.", M(23,1), M_MASK, PWRCOM, { RA,RS,RB,MBE,ME } },
+
+{ "nop", OP(24), 0xffffffff, PPCCOM, { 0 } },
+{ "ori", OP(24), OP_MASK, PPCCOM, { RA, RS, UI } },
+{ "oril", OP(24), OP_MASK, PWRCOM, { RA, RS, UI } },
+
+{ "oris", OP(25), OP_MASK, PPCCOM, { RA, RS, UI } },
+{ "oriu", OP(25), OP_MASK, PWRCOM, { RA, RS, UI } },
+
+{ "xori", OP(26), OP_MASK, PPCCOM, { RA, RS, UI } },
+{ "xoril", OP(26), OP_MASK, PWRCOM, { RA, RS, UI } },
+
+{ "xoris", OP(27), OP_MASK, PPCCOM, { RA, RS, UI } },
+{ "xoriu", OP(27), OP_MASK, PWRCOM, { RA, RS, UI } },
+
+{ "andi.", OP(28), OP_MASK, PPCCOM, { RA, RS, UI } },
+{ "andil.", OP(28), OP_MASK, PWRCOM, { RA, RS, UI } },
+
+{ "andis.", OP(29), OP_MASK, PPCCOM, { RA, RS, UI } },
+{ "andiu.", OP(29), OP_MASK, PWRCOM, { RA, RS, UI } },
+
+{ "rotldi", MD(30,0,0), MDMB_MASK, PPC64, { RA, RS, SH6 } },
+{ "clrldi", MD(30,0,0), MDSH_MASK, PPC64, { RA, RS, MB6 } },
+{ "rldicl", MD(30,0,0), MD_MASK, PPC64, { RA, RS, SH6, MB6 } },
+{ "rotldi.", MD(30,0,1), MDMB_MASK, PPC64, { RA, RS, SH6 } },
+{ "clrldi.", MD(30,0,1), MDSH_MASK, PPC64, { RA, RS, MB6 } },
+{ "rldicl.", MD(30,0,1), MD_MASK, PPC64, { RA, RS, SH6, MB6 } },
+
+{ "rldicr", MD(30,1,0), MD_MASK, PPC64, { RA, RS, SH6, ME6 } },
+{ "rldicr.", MD(30,1,1), MD_MASK, PPC64, { RA, RS, SH6, ME6 } },
+
+{ "rldic", MD(30,2,0), MD_MASK, PPC64, { RA, RS, SH6, MB6 } },
+{ "rldic.", MD(30,2,1), MD_MASK, PPC64, { RA, RS, SH6, MB6 } },
+
+{ "rldimi", MD(30,3,0), MD_MASK, PPC64, { RA, RS, SH6, MB6 } },
+{ "rldimi.", MD(30,3,1), MD_MASK, PPC64, { RA, RS, SH6, MB6 } },
+
+{ "rotld", MDS(30,8,0), MDSMB_MASK, PPC64, { RA, RS, RB } },
+{ "rldcl", MDS(30,8,0), MDS_MASK, PPC64, { RA, RS, RB, MB6 } },
+{ "rotld.", MDS(30,8,1), MDSMB_MASK, PPC64, { RA, RS, RB } },
+{ "rldcl.", MDS(30,8,1), MDS_MASK, PPC64, { RA, RS, RB, MB6 } },
+
+{ "rldcr", MDS(30,9,0), MDS_MASK, PPC64, { RA, RS, RB, ME6 } },
+{ "rldcr.", MDS(30,9,1), MDS_MASK, PPC64, { RA, RS, RB, ME6 } },
+
+{ "cmpw", XCMPL(31,0,0), XCMPL_MASK, PPCCOM, { OBF, RA, RB }
},
+{ "cmpd", XCMPL(31,0,1), XCMPL_MASK, PPC64, { OBF, RA, RB } },
+{ "cmp", X(31,0), XCMP_MASK, PPCONLY, { BF, L, RA, RB } },
+{ "cmp", X(31,0), XCMPL_MASK, PWRCOM, { BF, RA, RB } },
+
+{ "twlgt", XTO(31,4,TOLGT), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tlgt", XTO(31,4,TOLGT), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twllt", XTO(31,4,TOLLT), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tllt", XTO(31,4,TOLLT), XTO_MASK, PWRCOM, { RA, RB } },
+{ "tweq", XTO(31,4,TOEQ), XTO_MASK, PPCCOM, { RA, RB } },
+{ "teq", XTO(31,4,TOEQ), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twlge", XTO(31,4,TOLGE), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tlge", XTO(31,4,TOLGE), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twlnl", XTO(31,4,TOLNL), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tlnl", XTO(31,4,TOLNL), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twlle", XTO(31,4,TOLLE), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tlle", XTO(31,4,TOLLE), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twlng", XTO(31,4,TOLNG), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tlng", XTO(31,4,TOLNG), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twgt", XTO(31,4,TOGT), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tgt", XTO(31,4,TOGT), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twge", XTO(31,4,TOGE), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tge", XTO(31,4,TOGE), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twnl", XTO(31,4,TONL), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tnl", XTO(31,4,TONL), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twlt", XTO(31,4,TOLT), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tlt", XTO(31,4,TOLT), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twle", XTO(31,4,TOLE), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tle", XTO(31,4,TOLE), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twng", XTO(31,4,TONG), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tng", XTO(31,4,TONG), XTO_MASK, PWRCOM, { RA, RB } },
+{ "twne", XTO(31,4,TONE), XTO_MASK, PPCCOM, { RA, RB } },
+{ "tne", XTO(31,4,TONE), XTO_MASK, PWRCOM, { RA, RB } },
+{ "trap", XTO(31,4,TOU), 0xffffffff, PPCCOM, { 0 } },
+{ "tw", X(31,4), X_MASK, PPCCOM, { TO, RA, RB } },
+{ "t", X(31,4), X_MASK, PWRCOM, { TO, RA, RB } },
+
+{ "subfc", XO(31,8,0,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "sf", XO(31,8,0,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "subc", XO(31,8,0,0), XO_MASK, PPC, { RT, RB, RA } },
+{ "subfc.", XO(31,8,0,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "sf.", XO(31,8,0,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "subc.", XO(31,8,0,1), XO_MASK, PPCCOM, { RT, RB, RA } },
+{ "subfco", XO(31,8,1,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "sfo", XO(31,8,1,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "subco", XO(31,8,1,0), XO_MASK, PPC, { RT, RB, RA } },
+{ "subfco.", XO(31,8,1,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "sfo.", XO(31,8,1,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "subco.", XO(31,8,1,1), XO_MASK, PPC, { RT, RB, RA } },
+
+{ "mulhdu", XO(31,9,0,0), XO_MASK, PPC64, { RT, RA, RB } },
+{ "mulhdu.", XO(31,9,0,1), XO_MASK, PPC64, { RT, RA, RB } },
+
+{ "addc", XO(31,10,0,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "a", XO(31,10,0,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "addc.", XO(31,10,0,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "a.", XO(31,10,0,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "addco", XO(31,10,1,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "ao", XO(31,10,1,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "addco.", XO(31,10,1,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "ao.", XO(31,10,1,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+
+{ "mulhwu", XO(31,11,0,0), XO_MASK, PPC, { RT, RA, RB } },
+{ "mulhwu.", XO(31,11,0,1), XO_MASK, PPC, { RT, RA, RB } },
+
+{ "mfcr", X(31,19), XRARB_MASK, COM, { RT } },
+
+{ "lwarx", X(31,20), X_MASK, PPC, { RT, RA, RB } },
+
+{ "ldx", X(31,21), X_MASK, PPC64, { RT, RA, RB } },
+
+{ "lwzx", X(31,23), X_MASK, PPCCOM, { RT, RA, RB } },
+{ "lx", X(31,23), X_MASK, PWRCOM, { RT, RA, RB } },
+
+{ "slw", XRC(31,24,0), X_MASK, PPCCOM, { RA, RS, RB } },
+{ "sl", XRC(31,24,0), X_MASK, PWRCOM, { RA, RS, RB } },
+{ "slw.", XRC(31,24,1), X_MASK, PPCCOM, { RA, RS, RB } },
+{ "sl.", XRC(31,24,1), X_MASK, PWRCOM, { RA, RS, RB } },
+
+{ "cntlzw", XRC(31,26,0), XRB_MASK, PPCCOM, { RA, RS } },
+{ "cntlz", XRC(31,26,0), XRB_MASK, PWRCOM, { RA, RS } },
+{ "cntlzw.", XRC(31,26,1), XRB_MASK, PPCCOM, { RA, RS } },
+{ "cntlz.", XRC(31,26,1), XRB_MASK, PWRCOM, { RA, RS } },
+
+{ "sld", XRC(31,27,0), X_MASK, PPC64, { RA, RS, RB } },
+{ "sld.", XRC(31,27,1), X_MASK, PPC64, { RA, RS, RB } },
+
+{ "and", XRC(31,28,0), X_MASK, COM, { RA, RS, RB } },
+{ "and.", XRC(31,28,1), X_MASK, COM, { RA, RS, RB } },
+
+{ "maskg", XRC(31,29,0), X_MASK, M601, { RA, RS, RB } },
+{ "maskg.", XRC(31,29,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "cmplw", XCMPL(31,32,0), XCMPL_MASK, PPCCOM, { OBF, RA, RB } },
+{ "cmpld", XCMPL(31,32,1), XCMPL_MASK, PPC64, { OBF, RA, RB }
},
+{ "cmpl", X(31,32), XCMP_MASK, PPCONLY, { BF, L, RA, RB } },
+{ "cmpl", X(31,32), XCMPL_MASK, PWRCOM, { BF, RA, RB } },
+
+{ "subf", XO(31,40,0,0), XO_MASK, PPC, { RT, RA, RB } },
+{ "sub", XO(31,40,0,0), XO_MASK, PPC, { RT, RB, RA } },
+{ "subf.", XO(31,40,0,1), XO_MASK, PPC, { RT, RA, RB } },
+{ "sub.", XO(31,40,0,1), XO_MASK, PPC, { RT, RB, RA } },
+{ "subfo", XO(31,40,1,0), XO_MASK, PPC, { RT, RA, RB } },
+{ "subo", XO(31,40,1,0), XO_MASK, PPC, { RT, RB, RA } },
+{ "subfo.", XO(31,40,1,1), XO_MASK, PPC, { RT, RA, RB } },
+{ "subo.", XO(31,40,1,1), XO_MASK, PPC, { RT, RB, RA } },
+
+{ "ldux", X(31,53), X_MASK, PPC64, { RT, RAL, RB } },
+
+{ "dcbst", X(31,54), XRT_MASK, PPC, { RA, RB } },
+
+{ "lwzux", X(31,55), X_MASK, PPCCOM, { RT, RAL, RB } },
+{ "lux", X(31,55), X_MASK, PWRCOM, { RT, RA, RB } },
+
+{ "cntlzd", XRC(31,58,0), XRB_MASK, PPC64, { RA, RS } },
+{ "cntlzd.", XRC(31,58,1), XRB_MASK, PPC64, { RA, RS } },
+
+{ "andc", XRC(31,60,0), X_MASK, COM, { RA, RS, RB } },
+{ "andc.", XRC(31,60,1), X_MASK, COM, { RA, RS, RB } },
+
+{ "tdlgt", XTO(31,68,TOLGT), XTO_MASK, PPC64, { RA, RB } },
+{ "tdllt", XTO(31,68,TOLLT), XTO_MASK, PPC64, { RA, RB } },
+{ "tdeq", XTO(31,68,TOEQ), XTO_MASK, PPC64, { RA, RB } },
+{ "tdlge", XTO(31,68,TOLGE), XTO_MASK, PPC64, { RA, RB } },
+{ "tdlnl", XTO(31,68,TOLNL), XTO_MASK, PPC64, { RA, RB } },
+{ "tdlle", XTO(31,68,TOLLE), XTO_MASK, PPC64, { RA, RB } },
+{ "tdlng", XTO(31,68,TOLNG), XTO_MASK, PPC64, { RA, RB } },
+{ "tdgt", XTO(31,68,TOGT), XTO_MASK, PPC64, { RA, RB } },
+{ "tdge", XTO(31,68,TOGE), XTO_MASK, PPC64, { RA, RB } },
+{ "tdnl", XTO(31,68,TONL), XTO_MASK, PPC64, { RA, RB } },
+{ "tdlt", XTO(31,68,TOLT), XTO_MASK, PPC64, { RA, RB } },
+{ "tdle", XTO(31,68,TOLE), XTO_MASK, PPC64, { RA, RB } },
+{ "tdng", XTO(31,68,TONG), XTO_MASK, PPC64, { RA, RB } },
+{ "tdne", XTO(31,68,TONE), XTO_MASK, PPC64, { RA, RB } },
+{ "td", X(31,68), X_MASK, PPC64, { TO, RA, RB }
},
+
+{ "mulhd", XO(31,73,0,0), XO_MASK, PPC64, { RT, RA, RB } },
+{ "mulhd.", XO(31,73,0,1), XO_MASK, PPC64, { RT, RA, RB } },
+
+{ "mulhw", XO(31,75,0,0), XO_MASK, PPC, { RT, RA, RB } },
+{ "mulhw.", XO(31,75,0,1), XO_MASK, PPC, { RT, RA, RB } },
+
+{ "mfmsr", X(31,83), XRARB_MASK, COM, { RT } },
+
+{ "ldarx", X(31,84), X_MASK, PPC64, { RT, RA, RB } },
+
+{ "dcbf", X(31,86), XRT_MASK, PPC, { RA, RB } },
+
+{ "lbzx", X(31,87), X_MASK, COM, { RT, RA, RB } },
+
+{ "neg", XO(31,104,0,0), XORB_MASK, COM, { RT, RA } },
+{ "neg.", XO(31,104,0,1), XORB_MASK, COM, { RT, RA } },
+{ "nego", XO(31,104,1,0), XORB_MASK, COM, { RT, RA } },
+{ "nego.", XO(31,104,1,1), XORB_MASK, COM, { RT, RA } },
+
+{ "mul", XO(31,107,0,0), XO_MASK, M601, { RT, RA, RB } },
+{ "mul.", XO(31,107,0,1), XO_MASK, M601, { RT, RA, RB } },
+{ "mulo", XO(31,107,1,0), XO_MASK, M601, { RT, RA, RB } },
+{ "mulo.", XO(31,107,1,1), XO_MASK, M601, { RT, RA, RB } },
+
+{ "clf", X(31,118), XRB_MASK, POWER, { RT, RA } },
+
+{ "lbzux", X(31,119), X_MASK, COM, { RT, RAL, RB }
},
+
+{ "not", XRC(31,124,0), X_MASK, COM, { RA, RS, RBS } },
+{ "nor", XRC(31,124,0), X_MASK, COM, { RA, RS, RB } },
+{ "not.", XRC(31,124,1), X_MASK, COM, { RA, RS, RBS } },
+{ "nor.", XRC(31,124,1), X_MASK, COM, { RA, RS, RB } },
+
+{ "subfe", XO(31,136,0,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "sfe", XO(31,136,0,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "subfe.", XO(31,136,0,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "sfe.", XO(31,136,0,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "subfeo", XO(31,136,1,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "sfeo", XO(31,136,1,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "subfeo.", XO(31,136,1,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "sfeo.", XO(31,136,1,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+
+{ "adde", XO(31,138,0,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "ae", XO(31,138,0,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "adde.", XO(31,138,0,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "ae.", XO(31,138,0,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "addeo", XO(31,138,1,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "aeo", XO(31,138,1,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "addeo.", XO(31,138,1,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "aeo.", XO(31,138,1,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+
+{ "mtcr", XFXM(31,144,0xff), XFXFXM_MASK|FXM_MASK, COM, { RS }},
+{ "mtcrf", X(31,144), XFXFXM_MASK, COM, { FXM, RS } },
+
+{ "mtmsr", X(31,146), XRARB_MASK, COM, { RS } },
+
+{ "stdx", X(31,149), X_MASK, PPC64, { RS, RA, RB }
},
+
+{ "stwcx.", XRC(31,150,1), X_MASK, PPC, { RS, RA, RB } },
+
+{ "stwx", X(31,151), X_MASK, PPCCOM, { RS, RA, RB }
},
+{ "stx", X(31,151), X_MASK, PWRCOM, { RS, RA, RB }
},
+
+{ "slq", XRC(31,152,0), X_MASK, M601, { RA, RS, RB } },
+{ "slq.", XRC(31,152,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "sle", XRC(31,153,0), X_MASK, M601, { RA, RS, RB } },
+{ "sle.", XRC(31,153,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "stdux", X(31,181), X_MASK, PPC64, { RS, RAS, RB }
},
+
+{ "stwux", X(31,183), X_MASK, PPCCOM, { RS, RAS, RB }
},
+{ "stux", X(31,183), X_MASK, PWRCOM, { RS, RA, RB }
},
+
+{ "sliq", XRC(31,184,0), X_MASK, M601, { RA, RS, SH } },
+{ "sliq.", XRC(31,184,1), X_MASK, M601, { RA, RS, SH } },
+
+{ "subfze", XO(31,200,0,0), XORB_MASK, PPCCOM, { RT, RA } },
+{ "sfze", XO(31,200,0,0), XORB_MASK, PWRCOM, { RT, RA } },
+{ "subfze.", XO(31,200,0,1), XORB_MASK, PPCCOM, { RT, RA } },
+{ "sfze.", XO(31,200,0,1), XORB_MASK, PWRCOM, { RT, RA } },
+{ "subfzeo", XO(31,200,1,0), XORB_MASK, PPCCOM, { RT, RA } },
+{ "sfzeo", XO(31,200,1,0), XORB_MASK, PWRCOM, { RT, RA } },
+{ "subfzeo.",XO(31,200,1,1), XORB_MASK, PPCCOM, { RT, RA } },
+{ "sfzeo.", XO(31,200,1,1), XORB_MASK, PWRCOM, { RT, RA } },
+
+{ "addze", XO(31,202,0,0), XORB_MASK, PPCCOM, { RT, RA } },
+{ "aze", XO(31,202,0,0), XORB_MASK, PWRCOM, { RT, RA } },
+{ "addze.", XO(31,202,0,1), XORB_MASK, PPCCOM, { RT, RA } },
+{ "aze.", XO(31,202,0,1), XORB_MASK, PWRCOM, { RT, RA } },
+{ "addzeo", XO(31,202,1,0), XORB_MASK, PPCCOM, { RT, RA } },
+{ "azeo", XO(31,202,1,0), XORB_MASK, PWRCOM, { RT, RA } },
+{ "addzeo.", XO(31,202,1,1), XORB_MASK, PPCCOM, { RT, RA } },
+{ "azeo.", XO(31,202,1,1), XORB_MASK, PWRCOM, { RT, RA } },
+
+{ "mtsr", X(31,210), XRB_MASK|(1<<20), COM32, { SR, RS } },
+
+{ "stdcx.", XRC(31,214,1), X_MASK, PPC64, { RS, RA, RB } },
+
+{ "stbx", X(31,215), X_MASK, COM, { RS, RA, RB } },
+
+{ "sllq", XRC(31,216,0), X_MASK, M601, { RA, RS, RB } },
+{ "sllq.", XRC(31,216,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "sleq", XRC(31,217,0), X_MASK, M601, { RA, RS, RB } },
+{ "sleq.", XRC(31,217,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "subfme", XO(31,232,0,0), XORB_MASK, PPCCOM, { RT, RA } },
+{ "sfme", XO(31,232,0,0), XORB_MASK, PWRCOM, { RT, RA } },
+{ "subfme.", XO(31,232,0,1), XORB_MASK, PPCCOM, { RT, RA } },
+{ "sfme.", XO(31,232,0,1), XORB_MASK, PWRCOM, { RT, RA } },
+{ "subfmeo", XO(31,232,1,0), XORB_MASK, PPCCOM, { RT, RA } },
+{ "sfmeo", XO(31,232,1,0), XORB_MASK, PWRCOM, { RT, RA } },
+{ "subfmeo.",XO(31,232,1,1), XORB_MASK, PPCCOM, { RT, RA } },
+{ "sfmeo.", XO(31,232,1,1), XORB_MASK, PWRCOM, { RT, RA } },
+
+{ "mulld", XO(31,233,0,0), XO_MASK, PPC64, { RT, RA, RB } },
+{ "mulld.", XO(31,233,0,1), XO_MASK, PPC64, { RT, RA, RB } },
+{ "mulldo", XO(31,233,1,0), XO_MASK, PPC64, { RT, RA, RB } },
+{ "mulldo.", XO(31,233,1,1), XO_MASK, PPC64, { RT, RA, RB } },
+
+{ "addme", XO(31,234,0,0), XORB_MASK, PPCCOM, { RT, RA } },
+{ "ame", XO(31,234,0,0), XORB_MASK, PWRCOM, { RT, RA } },
+{ "addme.", XO(31,234,0,1), XORB_MASK, PPCCOM, { RT, RA } },
+{ "ame.", XO(31,234,0,1), XORB_MASK, PWRCOM, { RT, RA } },
+{ "addmeo", XO(31,234,1,0), XORB_MASK, PPCCOM, { RT, RA } },
+{ "ameo", XO(31,234,1,0), XORB_MASK, PWRCOM, { RT, RA } },
+{ "addmeo.", XO(31,234,1,1), XORB_MASK, PPCCOM, { RT, RA } },
+{ "ameo.", XO(31,234,1,1), XORB_MASK, PWRCOM, { RT, RA } },
+
+{ "mullw", XO(31,235,0,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "muls", XO(31,235,0,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "mullw.", XO(31,235,0,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "muls.", XO(31,235,0,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "mullwo", XO(31,235,1,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "mulso", XO(31,235,1,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "mullwo.", XO(31,235,1,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "mulso.", XO(31,235,1,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+
+{ "mtsrin", X(31,242), XRA_MASK, PPC32, { RS, RB } },
+{ "mtsri", X(31,242), XRA_MASK, POWER32, { RS, RB } },
+
+{ "dcbtst", X(31,246), XRT_MASK, PPC, { RA, RB } },
+
+{ "stbux", X(31,247), X_MASK, COM, { RS, RAS, RB }
},
+
+{ "slliq", XRC(31,248,0), X_MASK, M601, { RA, RS, SH } },
+{ "slliq.", XRC(31,248,1), X_MASK, M601, { RA, RS, SH } },
+
+{ "doz", XO(31,264,0,0), XO_MASK, M601, { RT, RA, RB } },
+{ "doz.", XO(31,264,0,1), XO_MASK, M601, { RT, RA, RB } },
+{ "dozo", XO(31,264,1,0), XO_MASK, M601, { RT, RA, RB } },
+{ "dozo.", XO(31,264,1,1), XO_MASK, M601, { RT, RA, RB } },
+
+{ "add", XO(31,266,0,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "cax", XO(31,266,0,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "add.", XO(31,266,0,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "cax.", XO(31,266,0,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "addo", XO(31,266,1,0), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "caxo", XO(31,266,1,0), XO_MASK, PWRCOM, { RT, RA, RB } },
+{ "addo.", XO(31,266,1,1), XO_MASK, PPCCOM, { RT, RA, RB } },
+{ "caxo.", XO(31,266,1,1), XO_MASK, PWRCOM, { RT, RA, RB } },
+
+{ "lscbx", XRC(31,277,0), X_MASK, M601, { RT, RA, RB } },
+{ "lscbx.", XRC(31,277,1), X_MASK, M601, { RT, RA, RB } },
+
+{ "dcbt", X(31,278), XRT_MASK, PPC, { RA, RB } },
+
+{ "lhzx", X(31,279), X_MASK, COM, { RT, RA, RB }
},
+
+{ "icbt", X(31,262), XRT_MASK, PPC, { RA, RB } },
+
+{ "eqv", XRC(31,284,0), X_MASK, COM, { RA, RS, RB } },
+{ "eqv.", XRC(31,284,1), X_MASK, COM, { RA, RS, RB } },
+
+{ "tlbie", X(31,306), XRTRA_MASK, PPC, { RB } },
+{ "tlbi", X(31,306), XRT_MASK, POWER, { RA, RB } },
+
+{ "eciwx", X(31,310), X_MASK, PPC, { RT, RA, RB }
},
+
+{ "lhzux", X(31,311), X_MASK, COM, { RT, RAL, RB }
},
+
+{ "xor", XRC(31,316,0), X_MASK, COM, { RA, RS, RB } },
+{ "xor.", XRC(31,316,1), X_MASK, COM, { RA, RS, RB } },
+
+{ "mfdcr", X(31,323), X_MASK, PPC, { RT, SPR } },
+
+{ "div", XO(31,331,0,0), XO_MASK, M601, { RT, RA, RB } },
+{ "div.", XO(31,331,0,1), XO_MASK, M601, { RT, RA, RB } },
+{ "divo", XO(31,331,1,0), XO_MASK, M601, { RT, RA, RB } },
+{ "divo.", XO(31,331,1,1), XO_MASK, M601, { RT, RA, RB } },
+
+{ "mfmq", XSPR(31,339,0), XSPR_MASK, M601, { RT } },
+{ "mfxer", XSPR(31,339,1), XSPR_MASK, COM, { RT } },
+{ "mfrtcu", XSPR(31,339,4), XSPR_MASK, COM, { RT } },
+{ "mfrtcl", XSPR(31,339,5), XSPR_MASK, COM, { RT } },
+{ "mfdec", XSPR(31,339,6), XSPR_MASK, MFDEC1, { RT } },
+{ "mflr", XSPR(31,339,8), XSPR_MASK, COM, { RT } },
+{ "mfctr", XSPR(31,339,9), XSPR_MASK, COM, { RT } },
+{ "mftid", XSPR(31,339,17), XSPR_MASK, POWER, { RT } },
+{ "mfdsisr", XSPR(31,339,18), XSPR_MASK, COM, { RT } },
+{ "mfdar", XSPR(31,339,19), XSPR_MASK, COM, { RT } },
+{ "mfdec", XSPR(31,339,22), XSPR_MASK, MFDEC2, { RT } },
+{ "mfsdr0", XSPR(31,339,24), XSPR_MASK, POWER, { RT } },
+{ "mfsdr1", XSPR(31,339,25), XSPR_MASK, COM, { RT } },
+{ "mfsrr0", XSPR(31,339,26), XSPR_MASK, COM, { RT } },
+{ "mfsrr1", XSPR(31,339,27), XSPR_MASK, COM, { RT } },
+{ "mfsprg", XSPR(31,339,272), XSPRG_MASK, PPC, { RT, SPRG } },
+{ "mfasr", XSPR(31,339,280), XSPR_MASK, PPC64, { RT } },
+{ "mfear", XSPR(31,339,282), XSPR_MASK, PPC, { RT } },
+{ "mfpvr", XSPR(31,339,287), XSPR_MASK, PPC, { RT } },
+{ "mfibatu", XSPR(31,339,528), XSPRBAT_MASK, PPC, { RT, SPRBAT } },
+{ "mfibatl", XSPR(31,339,529), XSPRBAT_MASK, PPC, { RT, SPRBAT } },
+{ "mfdbatu", XSPR(31,339,536), XSPRBAT_MASK, PPC, { RT, SPRBAT } },
+{ "mfdbatl", XSPR(31,339,537), XSPRBAT_MASK, PPC, { RT, SPRBAT } },
+{ "mfspr", X(31,339), X_MASK, COM, { RT, SPR } },
+
+{ "lwax", X(31,341), X_MASK, PPC64, { RT, RA, RB }
},
+
+{ "lhax", X(31,343), X_MASK, COM, { RT, RA, RB }
},
+
+{ "dccci", X(31,454), XRT_MASK, PPC, { RA, RB } },
+
+{ "abs", XO(31,360,0,0), XORB_MASK, M601, { RT, RA } },
+{ "abs.", XO(31,360,0,1), XORB_MASK, M601, { RT, RA } },
+{ "abso", XO(31,360,1,0), XORB_MASK, M601, { RT, RA } },
+{ "abso.", XO(31,360,1,1), XORB_MASK, M601, { RT, RA } },
+
+{ "divs", XO(31,363,0,0), XO_MASK, M601, { RT, RA, RB } },
+{ "divs.", XO(31,363,0,1), XO_MASK, M601, { RT, RA, RB } },
+{ "divso", XO(31,363,1,0), XO_MASK, M601, { RT, RA, RB } },
+{ "divso.", XO(31,363,1,1), XO_MASK, M601, { RT, RA, RB } },
+
+{ "tlbia", X(31,370), 0xffffffff, PPC, { 0 } },
+
+{ "mftbu", XSPR(31,371,269), XSPR_MASK, PPC, { RT } },
+{ "mftb", X(31,371), X_MASK, PPC, { RT, TBR } },
+
+{ "lwaux", X(31,373), X_MASK, PPC64, { RT, RAL, RB }
},
+
+{ "lhaux", X(31,375), X_MASK, COM, { RT, RAL, RB }
},
+
+{ "sthx", X(31,407), X_MASK, COM, { RS, RA, RB }
},
+
+{ "lfqx", X(31,791), X_MASK, POWER2, { FRT, RA, RB }
},
+
+{ "lfqux", X(31,823), X_MASK, POWER2, { FRT, RA, RB }
},
+
+{ "stfqx", X(31,919), X_MASK, POWER2, { FRS, RA, RB }
},
+
+{ "stfqux", X(31,951), X_MASK, POWER2, { FRS, RA, RB }
},
+
+{ "orc", XRC(31,412,0), X_MASK, COM, { RA, RS, RB } },
+{ "orc.", XRC(31,412,1), X_MASK, COM, { RA, RS, RB } },
+
+{ "sradi", XS(31,413,0), XS_MASK, PPC64, { RA, RS, SH6 } },
+{ "sradi.", XS(31,413,1), XS_MASK, PPC64, { RA, RS, SH6 } },
+
+{ "slbie", X(31,434), XRTRA_MASK, PPC64, { RB } },
+
+{ "ecowx", X(31,438), X_MASK, PPC, { RT, RA, RB }
},
+
+{ "sthux", X(31,439), X_MASK, COM, { RS, RAS, RB }
},
+
+{ "mr", XRC(31,444,0), X_MASK, COM, { RA, RS, RBS }
},
+{ "or", XRC(31,444,0), X_MASK, COM, { RA, RS, RB } },
+{ "mr.", XRC(31,444,1), X_MASK, COM, { RA, RS, RBS } },
+{ "or.", XRC(31,444,1), X_MASK, COM, { RA, RS, RB } },
+
+{ "mtdcr", X(31,451), X_MASK, PPC, { SPR, RS } },
+
+{ "divdu", XO(31,457,0,0), XO_MASK, PPC64, { RT, RA, RB } },
+{ "divdu.", XO(31,457,0,1), XO_MASK, PPC64, { RT, RA, RB } },
+{ "divduo", XO(31,457,1,0), XO_MASK, PPC64, { RT, RA, RB } },
+{ "divduo.", XO(31,457,1,1), XO_MASK, PPC64, { RT, RA, RB } },
+
+{ "divwu", XO(31,459,0,0), XO_MASK, PPC, { RT, RA, RB } },
+{ "divwu.", XO(31,459,0,1), XO_MASK, PPC, { RT, RA, RB } },
+{ "divwuo", XO(31,459,1,0), XO_MASK, PPC, { RT, RA, RB } },
+{ "divwuo.", XO(31,459,1,1), XO_MASK, PPC, { RT, RA, RB } },
+
+{ "mtmq", XSPR(31,467,0), XSPR_MASK, M601, { RS } },
+{ "mtxer", XSPR(31,467,1), XSPR_MASK, COM, { RS } },
+{ "mtlr", XSPR(31,467,8), XSPR_MASK, COM, { RS } },
+{ "mtctr", XSPR(31,467,9), XSPR_MASK, COM, { RS } },
+{ "mttid", XSPR(31,467,17), XSPR_MASK, POWER, { RS } },
+{ "mtdsisr", XSPR(31,467,18), XSPR_MASK, COM, { RS } },
+{ "mtdar", XSPR(31,467,19), XSPR_MASK, COM, { RS } },
+{ "mtrtcu", XSPR(31,467,20), XSPR_MASK, COM, { RS } },
+{ "mtrtcl", XSPR(31,467,21), XSPR_MASK, COM, { RS } },
+{ "mtdec", XSPR(31,467,22), XSPR_MASK, COM, { RS } },
+{ "mtsdr0", XSPR(31,467,24), XSPR_MASK, POWER, { RS } },
+{ "mtsdr1", XSPR(31,467,25), XSPR_MASK, COM, { RS } },
+{ "mtsrr0", XSPR(31,467,26), XSPR_MASK, COM, { RS } },
+{ "mtsrr1", XSPR(31,467,27), XSPR_MASK, COM, { RS } },
+{ "mtsprg", XSPR(31,467,272), XSPRG_MASK, PPC, { SPRG, RS } },
+{ "mtasr", XSPR(31,467,280), XSPR_MASK, PPC64, { RS } },
+{ "mtear", XSPR(31,467,282), XSPR_MASK, PPC, { RS } },
+{ "mttbl", XSPR(31,467,284), XSPR_MASK, PPC, { RS } },
+{ "mttbu", XSPR(31,467,285), XSPR_MASK, PPC, { RS } },
+{ "mtibatu", XSPR(31,467,528), XSPRBAT_MASK, PPC, { SPRBAT, RS } },
+{ "mtibatl", XSPR(31,467,529), XSPRBAT_MASK, PPC, { SPRBAT, RS } },
+{ "mtdbatu", XSPR(31,467,536), XSPRBAT_MASK, PPC, { SPRBAT, RS } },
+{ "mtdbatl", XSPR(31,467,537), XSPRBAT_MASK, PPC, { SPRBAT, RS } },
+{ "mtspr", X(31,467), X_MASK, COM, { SPR, RS } },
+
+{ "dcbi", X(31,470), XRT_MASK, PPC, { RA, RB } },
+
+{ "nand", XRC(31,476,0), X_MASK, COM, { RA, RS, RB } },
+{ "nand.", XRC(31,476,1), X_MASK, COM, { RA, RS, RB } },
+
+{ "nabs", XO(31,488,0,0), XORB_MASK, M601, { RT, RA } },
+{ "nabs.", XO(31,488,0,1), XORB_MASK, M601, { RT, RA } },
+{ "nabso", XO(31,488,1,0), XORB_MASK, M601, { RT, RA } },
+{ "nabso.", XO(31,488,1,1), XORB_MASK, M601, { RT, RA } },
+
+{ "divd", XO(31,489,0,0), XO_MASK, PPC64, { RT, RA, RB } },
+{ "divd.", XO(31,489,0,1), XO_MASK, PPC64, { RT, RA, RB } },
+{ "divdo", XO(31,489,1,0), XO_MASK, PPC64, { RT, RA, RB } },
+{ "divdo.", XO(31,489,1,1), XO_MASK, PPC64, { RT, RA, RB } },
+
+{ "divw", XO(31,491,0,0), XO_MASK, PPC, { RT, RA, RB } },
+{ "divw.", XO(31,491,0,1), XO_MASK, PPC, { RT, RA, RB } },
+{ "divwo", XO(31,491,1,0), XO_MASK, PPC, { RT, RA, RB } },
+{ "divwo.", XO(31,491,1,1), XO_MASK, PPC, { RT, RA, RB } },
+
+{ "slbia", X(31,498), 0xffffffff, PPC64, { 0 } },
+
+{ "cli", X(31,502), XRB_MASK, POWER, { RT, RA } },
+
+{ "mcrxr", X(31,512), XRARB_MASK|(3<<21), COM, { BF } },
+
+{ "clcs", X(31,531), XRB_MASK, M601, { RT, RA } },
+
+{ "lswx", X(31,533), X_MASK, PPCCOM, { RT, RA, RB }
},
+{ "lsx", X(31,533), X_MASK, PWRCOM, { RT, RA, RB }
},
+
+{ "lwbrx", X(31,534), X_MASK, PPCCOM, { RT, RA, RB }
},
+{ "lbrx", X(31,534), X_MASK, PWRCOM, { RT, RA, RB }
},
+
+{ "lfsx", X(31,535), X_MASK, COM, { FRT, RA, RB }
},
+
+{ "srw", XRC(31,536,0), X_MASK, PPCCOM, { RA, RS, RB } },
+{ "sr", XRC(31,536,0), X_MASK, PWRCOM, { RA, RS, RB } },
+{ "srw.", XRC(31,536,1), X_MASK, PPCCOM, { RA, RS, RB } },
+{ "sr.", XRC(31,536,1), X_MASK, PWRCOM, { RA, RS, RB } },
+
+{ "rrib", XRC(31,537,0), X_MASK, M601, { RA, RS, RB } },
+{ "rrib.", XRC(31,537,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "srd", XRC(31,539,0), X_MASK, PPC64, { RA, RS, RB } },
+{ "srd.", XRC(31,539,1), X_MASK, PPC64, { RA, RS, RB } },
+
+{ "maskir", XRC(31,541,0), X_MASK, M601, { RA, RS, RB } },
+{ "maskir.", XRC(31,541,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "tlbsync", X(31,566), 0xffffffff, PPC, { 0 } },
+
+{ "lfsux", X(31,567), X_MASK, COM, { FRT, RAS, RB
} },
+
+{ "mfsr", X(31,595), XRB_MASK|(1<<20), COM32, { RT, SR } },
+
+{ "lswi", X(31,597), X_MASK, PPCCOM, { RT, RA, NB }
},
+{ "lsi", X(31,597), X_MASK, PWRCOM, { RT, RA, NB }
},
+
+{ "sync", X(31,598), 0xffffffff, PPCCOM, { 0 } },
+{ "dcs", X(31,598), 0xffffffff, PWRCOM, { 0 } },
+
+{ "lfdx", X(31,599), X_MASK, COM, { FRT, RA, RB }
},
+
+{ "mfsri", X(31,627), X_MASK, PWRCOM, { RT, RA, RB }
},
+
+{ "dclst", X(31,630), XRB_MASK, PWRCOM, { RS, RA } },
+
+{ "lfdux", X(31,631), X_MASK, COM, { FRT, RAS, RB
} },
+
+{ "mfsrin", X(31,659), XRA_MASK, PPC32, { RT, RB } },
+
+{ "stswx", X(31,661), X_MASK, PPCCOM, { RS, RA, RB }
},
+{ "stsx", X(31,661), X_MASK, PWRCOM, { RS, RA, RB }
},
+
+{ "stwbrx", X(31,662), X_MASK, PPCCOM, { RS, RA, RB }
},
+{ "stbrx", X(31,662), X_MASK, PWRCOM, { RS, RA, RB }
},
+
+{ "stfsx", X(31,663), X_MASK, COM, { FRS, RA, RB }
},
+
+{ "srq", XRC(31,664,0), X_MASK, M601, { RA, RS, RB } },
+{ "srq.", XRC(31,664,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "sre", XRC(31,665,0), X_MASK, M601, { RA, RS, RB } },
+{ "sre.", XRC(31,665,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "stfsux", X(31,695), X_MASK, COM, { FRS, RAS, RB
} },
+
+{ "sriq", XRC(31,696,0), X_MASK, M601, { RA, RS, SH } },
+{ "sriq.", XRC(31,696,1), X_MASK, M601, { RA, RS, SH } },
+
+{ "stswi", X(31,725), X_MASK, PPCCOM, { RS, RA, NB }
},
+{ "stsi", X(31,725), X_MASK, PWRCOM, { RS, RA, NB }
},
+
+{ "stfdx", X(31,727), X_MASK, COM, { FRS, RA, RB }
},
+
+{ "srlq", XRC(31,728,0), X_MASK, M601, { RA, RS, RB } },
+{ "srlq.", XRC(31,728,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "sreq", XRC(31,729,0), X_MASK, M601, { RA, RS, RB } },
+{ "sreq.", XRC(31,729,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "stfdux", X(31,759), X_MASK, COM, { FRS, RAS, RB
} },
+
+{ "srliq", XRC(31,760,0), X_MASK, M601, { RA, RS, SH } },
+{ "srliq.", XRC(31,760,1), X_MASK, M601, { RA, RS, SH } },
+
+{ "lhbrx", X(31,790), X_MASK, COM, { RT, RA, RB }
},
+
+{ "sraw", XRC(31,792,0), X_MASK, PPCCOM, { RA, RS, RB } },
+{ "sra", XRC(31,792,0), X_MASK, PWRCOM, { RA, RS, RB } },
+{ "sraw.", XRC(31,792,1), X_MASK, PPCCOM, { RA, RS, RB } },
+{ "sra.", XRC(31,792,1), X_MASK, PWRCOM, { RA, RS, RB } },
+
+{ "srad", XRC(31,794,0), X_MASK, PPC64, { RA, RS, RB } },
+{ "srad.", XRC(31,794,1), X_MASK, PPC64, { RA, RS, RB } },
+
+{ "rac", X(31,818), X_MASK, PWRCOM, { RT, RA, RB }
},
+
+{ "srawi", XRC(31,824,0), X_MASK, PPCCOM, { RA, RS, SH } },
+{ "srai", XRC(31,824,0), X_MASK, PWRCOM, { RA, RS, SH } },
+{ "srawi.", XRC(31,824,1), X_MASK, PPCCOM, { RA, RS, SH } },
+{ "srai.", XRC(31,824,1), X_MASK, PWRCOM, { RA, RS, SH } },
+
+{ "eieio", X(31,854), 0xffffffff, PPC, { 0 } },
+
+{ "sthbrx", X(31,918), X_MASK, COM, { RS, RA, RB }
},
+
+{ "sraq", XRC(31,920,0), X_MASK, M601, { RA, RS, RB } },
+{ "sraq.", XRC(31,920,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "srea", XRC(31,921,0), X_MASK, M601, { RA, RS, RB } },
+{ "srea.", XRC(31,921,1), X_MASK, M601, { RA, RS, RB } },
+
+{ "extsh", XRC(31,922,0), XRB_MASK, PPCCOM, { RA, RS } },
+{ "exts", XRC(31,922,0), XRB_MASK, PWRCOM, { RA, RS } },
+{ "extsh.", XRC(31,922,1), XRB_MASK, PPCCOM, { RA, RS } },
+{ "exts.", XRC(31,922,1), XRB_MASK, PWRCOM, { RA, RS } },
+
+{ "sraiq", XRC(31,952,0), X_MASK, M601, { RA, RS, SH } },
+{ "sraiq.", XRC(31,952,1), X_MASK, M601, { RA, RS, SH } },
+
+{ "extsb", XRC(31,954,0), XRB_MASK, PPC, { RA, RS} },
+{ "extsb.", XRC(31,954,1), XRB_MASK, PPC, { RA, RS} },
+
+{ "iccci", X(31,966), XRT_MASK, PPC, { RA, RB } },
+
+{ "tlbld", X(31,978), XRTRA_MASK, PPC, { RB } },
+
+{ "icbi", X(31,982), XRT_MASK, PPC, { RA, RB } },
+
+{ "stfiwx", X(31,983), X_MASK, PPC, { FRS, RA, RB }
},
+
+{ "extsw", XRC(31,986,0), XRB_MASK, PPC, { RA, RS } },
+{ "extsw.", XRC(31,986,1), XRB_MASK, PPC, { RA, RS } },
+
+{ "tlbli", X(31,1010), XRTRA_MASK, PPC, { RB } },
+
+{ "dcbz", X(31,1014), XRT_MASK, PPC, { RA, RB } },
+{ "dclz", X(31,1014), XRT_MASK, PPC, { RA, RB } },
+
+{ "lwz", OP(32), OP_MASK, PPCCOM, { RT, D, RA } },
+{ "l", OP(32), OP_MASK, PWRCOM, { RT, D, RA } },
+
+{ "lwzu", OP(33), OP_MASK, PPCCOM, { RT, D, RAL } },
+{ "lu", OP(33), OP_MASK, PWRCOM, { RT, D, RA } },
+
+{ "lbz", OP(34), OP_MASK, COM, { RT, D, RA } },
+
+{ "lbzu", OP(35), OP_MASK, COM, { RT, D, RAL } },
+
+{ "stw", OP(36), OP_MASK, PPCCOM, { RS, D, RA } },
+{ "st", OP(36), OP_MASK, PWRCOM, { RS, D, RA } },
+
+{ "stwu", OP(37), OP_MASK, PPCCOM, { RS, D, RAS } },
+{ "stu", OP(37), OP_MASK, PWRCOM, { RS, D, RA } },
+
+{ "stb", OP(38), OP_MASK, COM, { RS, D, RA } },
+
+{ "stbu", OP(39), OP_MASK, COM, { RS, D, RAS } },
+
+{ "lhz", OP(40), OP_MASK, COM, { RT, D, RA } },
+
+{ "lhzu", OP(41), OP_MASK, COM, { RT, D, RAL } },
+
+{ "lha", OP(42), OP_MASK, COM, { RT, D, RA } },
+
+{ "lhau", OP(43), OP_MASK, COM, { RT, D, RAL } },
+
+{ "sth", OP(44), OP_MASK, COM, { RS, D, RA } },
+
+{ "sthu", OP(45), OP_MASK, COM, { RS, D, RAS } },
+
+{ "lmw", OP(46), OP_MASK, PPCCOM, { RT, D, RAM } },
+{ "lm", OP(46), OP_MASK, PWRCOM, { RT, D, RA } },
+
+{ "stmw", OP(47), OP_MASK, PPCCOM, { RS, D, RA } },
+{ "stm", OP(47), OP_MASK, PWRCOM, { RS, D, RA } },
+
+{ "lfs", OP(48), OP_MASK, COM, { FRT, D, RA } },
+
+{ "lfsu", OP(49), OP_MASK, COM, { FRT, D, RAS } },
+
+{ "lfd", OP(50), OP_MASK, COM, { FRT, D, RA } },
+
+{ "lfdu", OP(51), OP_MASK, COM, { FRT, D, RAS } },
+
+{ "stfs", OP(52), OP_MASK, COM, { FRS, D, RA } },
+
+{ "stfsu", OP(53), OP_MASK, COM, { FRS, D, RAS } },
+
+{ "stfd", OP(54), OP_MASK, COM, { FRS, D, RA } },
+
+{ "stfdu", OP(55), OP_MASK, COM, { FRS, D, RAS } },
+
+{ "lfq", OP(56), OP_MASK, POWER2, { FRT, D, RA } },
+
+{ "lfqu", OP(57), OP_MASK, POWER2, { FRT, D, RA } },
+
+{ "ld", DSO(58,0), DS_MASK, PPC64, { RT, DS, RA }
},
+
+{ "ldu", DSO(58,1), DS_MASK, PPC64, { RT, DS, RAL } },
+
+{ "lwa", DSO(58,2), DS_MASK, PPC64, { RT, DS, RA } },
+
+{ "fdivs", A(59,18,0), AFRC_MASK, PPC, { FRT, FRA, FRB } },
+{ "fdivs.", A(59,18,1), AFRC_MASK, PPC, { FRT, FRA, FRB } },
+
+{ "fsubs", A(59,20,0), AFRC_MASK, PPC, { FRT, FRA, FRB } },
+{ "fsubs.", A(59,20,1), AFRC_MASK, PPC, { FRT, FRA, FRB } },
+
+{ "fadds", A(59,21,0), AFRC_MASK, PPC, { FRT, FRA, FRB } },
+{ "fadds.", A(59,21,1), AFRC_MASK, PPC, { FRT, FRA, FRB } },
+
+{ "fsqrts", A(59,22,0), AFRAFRC_MASK, PPC, { FRT, FRB } },
+{ "fsqrts.", A(59,22,1), AFRAFRC_MASK, PPC, { FRT, FRB } },
+
+{ "fres", A(59,24,0), AFRAFRC_MASK, PPC, { FRT, FRB } },
+{ "fres.", A(59,24,1), AFRAFRC_MASK, PPC, { FRT, FRB } },
+
+{ "fmuls", A(59,25,0), AFRB_MASK, PPC, { FRT, FRA, FRC } },
+{ "fmuls.", A(59,25,1), AFRB_MASK, PPC, { FRT, FRA, FRC } },
+
+{ "fmsubs", A(59,28,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
+{ "fmsubs.", A(59,28,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
+
+{ "fmadds", A(59,29,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
+{ "fmadds.", A(59,29,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
+
+{ "fnmsubs", A(59,30,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
+{ "fnmsubs.",A(59,30,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
+
+{ "fnmadds", A(59,31,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
+{ "fnmadds.",A(59,31,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
+
+{ "stfq", OP(60), OP_MASK, POWER2, { FRS, D, RA } },
+
+{ "stfqu", OP(61), OP_MASK, POWER2, { FRS, D, RA } },
+
+{ "std", DSO(62,0), DS_MASK, PPC64, { RS, DS, RA }
},
+
+{ "stdu", DSO(62,1), DS_MASK, PPC64, { RS, DS, RAS }
},
+
+{ "fcmpu", X(63,0), X_MASK|(3<<21), COM, { BF, FRA, FRB } },
+
+{ "frsp", XRC(63,12,0), XRA_MASK, COM, { FRT, FRB } },
+{ "frsp.", XRC(63,12,1), XRA_MASK, COM, { FRT, FRB } },
+
+{ "fctiw", XRC(63,14,0), XRA_MASK, PPCCOM, { FRT, FRB } },
+{ "fcir", XRC(63,14,0), XRA_MASK, POWER2, { FRT, FRB } },
+{ "fctiw.", XRC(63,14,1), XRA_MASK, PPCCOM, { FRT, FRB } },
+{ "fcir.", XRC(63,14,1), XRA_MASK, POWER2, { FRT, FRB } },
+
+{ "fctiwz", XRC(63,15,0), XRA_MASK, PPCCOM, { FRT, FRB } },
+{ "fcirz", XRC(63,15,0), XRA_MASK, POWER2, { FRT, FRB } },
+{ "fctiwz.", XRC(63,15,1), XRA_MASK, PPCCOM, { FRT, FRB } },
+{ "fcirz.", XRC(63,15,1), XRA_MASK, POWER2, { FRT, FRB } },
+
+{ "fdiv", A(63,18,0), AFRC_MASK, PPCCOM, { FRT, FRA, FRB } },
+{ "fd", A(63,18,0), AFRC_MASK, PWRCOM, { FRT, FRA, FRB } },
+{ "fdiv.", A(63,18,1), AFRC_MASK, PPCCOM, { FRT, FRA, FRB } },
+{ "fd.", A(63,18,1), AFRC_MASK, PWRCOM, { FRT, FRA, FRB } },
+
+{ "fsub", A(63,20,0), AFRC_MASK, PPCCOM, { FRT, FRA, FRB } },
+{ "fs", A(63,20,0), AFRC_MASK, PWRCOM, { FRT, FRA, FRB } },
+{ "fsub.", A(63,20,1), AFRC_MASK, PPCCOM, { FRT, FRA, FRB } },
+{ "fs.", A(63,20,1), AFRC_MASK, PWRCOM, { FRT, FRA, FRB } },
+
+{ "fadd", A(63,21,0), AFRC_MASK, PPCCOM, { FRT, FRA, FRB } },
+{ "fa", A(63,21,0), AFRC_MASK, PWRCOM, { FRT, FRA, FRB } },
+{ "fadd.", A(63,21,1), AFRC_MASK, PPCCOM, { FRT, FRA, FRB } },
+{ "fa.", A(63,21,1), AFRC_MASK, PWRCOM, { FRT, FRA, FRB } },
+
+{ "fsqrt", A(63,22,0), AFRAFRC_MASK, POWER2, { FRT, FRB } },
+{ "fsqrt.", A(63,22,1), AFRAFRC_MASK, POWER2, { FRT, FRB } },
+{ "fsqrt", A(63,22,0), AFRAFRC_MASK, PPC, { FRT, FRB } },
+{ "fsqrt.", A(63,22,1), AFRAFRC_MASK, PPC, { FRT, FRB } },
+
+{ "fsel", A(63,23,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
+{ "fsel.", A(63,23,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
+
+{ "fmul", A(63,25,0), AFRB_MASK, PPCCOM, { FRT, FRA, FRC } },
+{ "fm", A(63,25,0), AFRB_MASK, PWRCOM, { FRT, FRA, FRC } },
+{ "fmul.", A(63,25,1), AFRB_MASK, PPCCOM, { FRT, FRA, FRC } },
+{ "fm.", A(63,25,1), AFRB_MASK, PWRCOM, { FRT, FRA, FRC } },
+
+{ "frsqrte", A(63,26,0), AFRAFRC_MASK, PPC, { FRT, FRB } },
+{ "frsqrte.",A(63,26,1), AFRAFRC_MASK, PPC, { FRT, FRB } },
+
+{ "fmsub", A(63,28,0), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB } },
+{ "fms", A(63,28,0), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB } },
+{ "fmsub.", A(63,28,1), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB } },
+{ "fms.", A(63,28,1), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB } },
+
+{ "fmadd", A(63,29,0), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB } },
+{ "fma", A(63,29,0), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB } },
+{ "fmadd.", A(63,29,1), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB } },
+{ "fma.", A(63,29,1), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB } },
+
+{ "fnmsub", A(63,30,0), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB } },
+{ "fnms", A(63,30,0), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB } },
+{ "fnmsub.", A(63,30,1), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB } },
+{ "fnms.", A(63,30,1), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB } },
+
+{ "fnmadd", A(63,31,0), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB } },
+{ "fnma", A(63,31,0), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB } },
+{ "fnmadd.", A(63,31,1), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB } },
+{ "fnma.", A(63,31,1), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB } },
+
+{ "fcmpo", X(63,30), X_MASK|(3<<21), COM, { BF, FRA, FRB } },
+
+{ "mtfsb1", XRC(63,38,0), XRARB_MASK, COM, { BT } },
+{ "mtfsb1.", XRC(63,38,1), XRARB_MASK, COM, { BT } },
+
+{ "fneg", XRC(63,40,0), XRA_MASK, COM, { FRT, FRB } },
+{ "fneg.", XRC(63,40,1), XRA_MASK, COM, { FRT, FRB } },
+
+{ "mcrfs", X(63,64), XRB_MASK|(3<<21)|(3<<16), COM, { BF, BFA } },
+
+{ "mtfsb0", XRC(63,70,0), XRARB_MASK, COM, { BT } },
+{ "mtfsb0.", XRC(63,70,1), XRARB_MASK, COM, { BT } },
+
+{ "fmr", XRC(63,72,0), XRA_MASK, COM, { FRT, FRB } },
+{ "fmr.", XRC(63,72,1), XRA_MASK, COM, { FRT, FRB } },
+
+{ "mtfsfi", XRC(63,134,0), XRA_MASK|(3<<21)|(1<<11), COM, { BF, U } },
+{ "mtfsfi.", XRC(63,134,1), XRA_MASK|(3<<21)|(1<<11), COM, { BF, U } },
+
+{ "fnabs", XRC(63,136,0), XRA_MASK, COM, { FRT, FRB } },
+{ "fnabs.", XRC(63,136,1), XRA_MASK, COM, { FRT, FRB } },
+
+{ "fabs", XRC(63,264,0), XRA_MASK, COM, { FRT, FRB } },
+{ "fabs.", XRC(63,264,1), XRA_MASK, COM, { FRT, FRB } },
+
+{ "mffs", XRC(63,583,0), XRARB_MASK, COM, { FRT } },
+{ "mffs.", XRC(63,583,1), XRARB_MASK, COM, { FRT } },
+
+{ "mtfsf", XFL(63,711,0), XFL_MASK, COM, { FLM, FRB } },
+{ "mtfsf.", XFL(63,711,1), XFL_MASK, COM, { FLM, FRB } },
+
+{ "fctid", XRC(63,814,0), XRA_MASK, PPC64, { FRT, FRB } },
+{ "fctid.", XRC(63,814,1), XRA_MASK, PPC64, { FRT, FRB } },
+
+{ "fctidz", XRC(63,815,0), XRA_MASK, PPC64, { FRT, FRB } },
+{ "fctidz.", XRC(63,815,1), XRA_MASK, PPC64, { FRT, FRB } },
+
+{ "fcfid", XRC(63,846,0), XRA_MASK, PPC64, { FRT, FRB } },
+{ "fcfid.", XRC(63,846,1), XRA_MASK, PPC64, { FRT, FRB } },
+
+};
+
+const int powerpc_num_opcodes =
+ sizeof (powerpc_opcodes) / sizeof (powerpc_opcodes[0]);
+
+/* The macro table. This is only used by the assembler. */
+
+const struct powerpc_macro powerpc_macros[] = {
+{ "extldi", 4, PPC64, "rldicr %0,%1,%3,(%2)-1" },
+{ "extldi.", 4, PPC64, "rldicr. %0,%1,%3,(%2)-1" },
+{ "extrdi", 4, PPC64, "rldicl %0,%1,(%2)+(%3),64-(%2)" },
+{ "extrdi.", 4, PPC64, "rldicl. %0,%1,(%2)+(%3),64-(%2)" },
+{ "insrdi", 4, PPC64, "rldimi %0,%1,64-((%2)+(%3)),%3" },
+{ "insrdi.", 4, PPC64, "rldimi. %0,%1,64-((%2)+(%3)),%3" },
+{ "rotrdi", 3, PPC64, "rldicl %0,%1,64-(%2),0" },
+{ "rotrdi.", 3, PPC64, "rldicl. %0,%1,64-(%2),0" },
+{ "sldi", 3, PPC64, "rldicr %0,%1,%2,63-(%2)" },
+{ "sldi.", 3, PPC64, "rldicr. %0,%1,%2,63-(%2)" },
+{ "srdi", 3, PPC64, "rldicl %0,%1,64-(%2),%2" },
+{ "srdi.", 3, PPC64, "rldicl. %0,%1,64-(%2),%2" },
+{ "clrrdi", 3, PPC64, "rldicr %0,%1,0,63-(%2)" },
+{ "clrrdi.", 3, PPC64, "rldicr. %0,%1,0,63-(%2)" },
+{ "clrlsldi",4, PPC64, "rldic %0,%1,%3,(%2)-(%3)" },
+{ "clrlsldi.",4, PPC64, "rldic. %0,%1,%3,(%2)-(%3)" },
+
+{ "extlwi", 4, PPCCOM, "rlwinm %0,%1,%3,0,(%2)-1" },
+{ "extlwi.", 4, PPCCOM, "rlwinm. %0,%1,%3,0,(%2)-1" },
+{ "extrwi", 4, PPCCOM, "rlwinm %0,%1,(%2)+(%3),32-(%2),31" },
+{ "extrwi.", 4, PPCCOM, "rlwinm. %0,%1,(%2)+(%3),32-(%2),31" },
+{ "inslwi", 4, PPCCOM, "rlwimi %0,%1,32-(%3),%3,(%2)+(%3)-1" },
+{ "inslwi.", 4, PPCCOM, "rlwimi. %0,%1,32-(%3),%3,(%2)+(%3)-1" },
+{ "insrwi", 4, PPCCOM, "rlwimi %0,%1,32-((%2)+(%3)),%3,(%2)+(%3)-1" },
+{ "insrwi.", 4, PPCCOM, "rlwimi. %0,%1,32-((%2)+(%3)),%3,(%2)+(%3)-1"},
+{ "rotrwi", 3, PPCCOM, "rlwinm %0,%1,32-(%2),0,31" },
+{ "rotrwi.", 3, PPCCOM, "rlwinm. %0,%1,32-(%2),0,31" },
+{ "slwi", 3, PPCCOM, "rlwinm %0,%1,%2,0,31-(%2)" },
+{ "sli", 3, PWRCOM, "rlinm %0,%1,%2,0,31-(%2)" },
+{ "slwi.", 3, PPCCOM, "rlwinm. %0,%1,%2,0,31-(%2)" },
+{ "sli.", 3, PWRCOM, "rlinm. %0,%1,%2,0,31-(%2)" },
+{ "srwi", 3, PPCCOM, "rlwinm %0,%1,32-(%2),%2,31" },
+{ "sri", 3, PWRCOM, "rlinm %0,%1,32-(%2),%2,31" },
+{ "srwi.", 3, PPCCOM, "rlwinm. %0,%1,32-(%2),%2,31" },
+{ "sri.", 3, PWRCOM, "rlinm. %0,%1,32-(%2),%2,31" },
+{ "clrrwi", 3, PPCCOM, "rlwinm %0,%1,0,0,31-(%2)" },
+{ "clrrwi.", 3, PPCCOM, "rlwinm. %0,%1,0,0,31-(%2)" },
+{ "clrlslwi",4, PPCCOM, "rlwinm %0,%1,%3,(%2)-(%3),31-(%3)" },
+{ "clrlslwi.",4, PPCCOM, "rlwinm. %0,%1,%3,(%2)-(%3),31-(%3)" },
+
+};
+
+const int powerpc_num_macros =
+ sizeof (powerpc_macros) / sizeof (powerpc_macros[0]);
diff --git a/opcode/ppc.h b/opcode/ppc.h
new file mode 100644
index 0000000..a9e3b24
--- /dev/null
+++ b/opcode/ppc.h
@@ -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 */
diff --git a/opcode/sparc-dis.c b/opcode/sparc-dis.c
new file mode 100644
index 0000000..42388ae
--- /dev/null
+++ b/opcode/sparc-dis.c
@@ -0,0 +1,868 @@
+/* Print SPARC instructions.
+ Copyright (C) 1989, 91-93, 1995, 1996 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "ansidecl.h"
+#include "opcode/sparc.h"
+#include "dis-asm.h"
+
+#include <string.h>
+
+/* Bitmask of v9 architectures. */
+#define MASK_V9 ((1 << SPARC_OPCODE_ARCH_V9) \
+ | (1 << SPARC_OPCODE_ARCH_V9A))
+/* 1 if INSN is for v9 only. */
+#define V9_ONLY_P(insn) (! ((insn)->architecture & ~MASK_V9))
+/* 1 if INSN is for v9. */
+#define V9_P(insn) (((insn)->architecture & MASK_V9) != 0)
+
+/* For faster lookup, after insns are sorted they are hashed. */
+/* ??? I think there is room for even more improvement. */
+
+#define HASH_SIZE 256
+/* It is important that we only look at insn code bits as that is how the
+ opcode table is hashed. OPCODE_BITS is a table of valid bits for each
+ of the main types (0,1,2,3). */
+static int opcode_bits[4] = { 0x01c00000, 0x0, 0x01f80000, 0x01f80000 };
+#define HASH_INSN(INSN) \
+ ((((INSN) >> 24) & 0xc0) | (((INSN) & opcode_bits[((INSN) >> 30) & 3]) >>
19))
+struct opcode_hash {
+ struct opcode_hash *next;
+ struct sparc_opcode *opcode;
+};
+static struct opcode_hash *opcode_hash_table[HASH_SIZE];
+static void build_hash_table ();
+
+/* Sign-extend a value which is N bits long. */
+#define SEX(value, bits) \
+ ((((int)(value)) << ((8 * sizeof (int)) - bits)) \
+ >> ((8 * sizeof (int)) - bits) )
+
+static char *reg_names[] =
+{ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
+ "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
+ "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
+ "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+ "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
+ "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
+ "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
+ "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
+/* psr, wim, tbr, fpsr, cpsr are v8 only. */
+ "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr"
+};
+
+#define freg_names (®_names[4 * 8])
+
+/* These are ordered according to there register number in
+ rdpr and wrpr insns. */
+static char *v9_priv_reg_names[] =
+{
+ "tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl",
+ "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
+ "wstate", "fq"
+ /* "ver" - special cased */
+};
+
+/* Macros used to extract instruction fields. Not all fields have
+ macros defined here, only those which are actually used. */
+
+#define X_RD(i) (((i) >> 25) & 0x1f)
+#define X_RS1(i) (((i) >> 14) & 0x1f)
+#define X_LDST_I(i) (((i) >> 13) & 1)
+#define X_ASI(i) (((i) >> 5) & 0xff)
+#define X_RS2(i) (((i) >> 0) & 0x1f)
+#define X_IMM13(i) (((i) >> 0) & 0x1fff)
+#define X_DISP22(i) (((i) >> 0) & 0x3fffff)
+#define X_IMM22(i) X_DISP22 (i)
+#define X_DISP30(i) (((i) >> 0) & 0x3fffffff)
+
+/* These are for v9. */
+#define X_DISP16(i) (((((i) >> 20) & 3) << 14) | (((i) >> 0) & 0x3fff))
+#define X_DISP19(i) (((i) >> 0) & 0x7ffff)
+#define X_MEMBAR(i) ((i) & 0x7f)
+
+/* Here is the union which was used to extract instruction fields
+ before the shift and mask macros were written.
+
+ union sparc_insn
+ {
+ unsigned long int code;
+ struct
+ {
+ unsigned int anop:2;
+ #define op ldst.anop
+ unsigned int anrd:5;
+ #define rd ldst.anrd
+ unsigned int op3:6;
+ unsigned int anrs1:5;
+ #define rs1 ldst.anrs1
+ unsigned int i:1;
+ unsigned int anasi:8;
+ #define asi ldst.anasi
+ unsigned int anrs2:5;
+ #define rs2 ldst.anrs2
+ #define shcnt rs2
+ } ldst;
+ struct
+ {
+ unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1;
+ unsigned int IMM13:13;
+ #define imm13 IMM13.IMM13
+ } IMM13;
+ struct
+ {
+ unsigned int anop:2;
+ unsigned int a:1;
+ unsigned int cond:4;
+ unsigned int op2:3;
+ unsigned int DISP22:22;
+ #define disp22 branch.DISP22
+ #define imm22 disp22
+ } branch;
+ struct
+ {
+ unsigned int anop:2;
+ unsigned int a:1;
+ unsigned int z:1;
+ unsigned int rcond:3;
+ unsigned int op2:3;
+ unsigned int DISP16HI:2;
+ unsigned int p:1;
+ unsigned int _rs1:5;
+ unsigned int DISP16LO:14;
+ } branch16;
+ struct
+ {
+ unsigned int anop:2;
+ unsigned int adisp30:30;
+ #define disp30 call.adisp30
+ } call;
+ };
+
+ */
+
+/* Nonzero if INSN is the opcode for a delayed branch. */
+static int
+is_delayed_branch (insn)
+ unsigned long insn;
+{
+ struct opcode_hash *op;
+
+ for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
+ {
+ const struct sparc_opcode *opcode = op->opcode;
+ if ((opcode->match & insn) == opcode->match
+ && (opcode->lose & insn) == 0)
+ return (opcode->flags & F_DELAYED);
+ }
+ return 0;
+}
+
+/* Nonzero of opcode table has been initialized. */
+static int opcodes_initialized = 0;
+
+/* extern void qsort (); */
+static int compare_opcodes ();
+
+/* Print one instruction from MEMADDR on INFO->STREAM.
+
+ We suffix the instruction with a comment that gives the absolute
+ address involved, as well as its symbolic form, if the instruction
+ is preceded by a findable `sethi' and it either adds an immediate
+ displacement to that register, or it is an `add' or `or' instruction
+ on that register. */
+
+int
+print_insn_sparc (memaddr, info)
+ bfd_vma memaddr;
+ disassemble_info *info;
+{
+ FILE *stream = info->stream;
+ bfd_byte buffer[4];
+ unsigned long insn;
+ register unsigned int i;
+ register struct opcode_hash *op;
+ int sparc_v9_p = bfd_mach_sparc_v9_p (info->mach);
+
+ if (!opcodes_initialized)
+ {
+ qsort ((char *) sparc_opcodes, sparc_num_opcodes,
+ sizeof (sparc_opcodes[0]), compare_opcodes);
+ build_hash_table (sparc_opcodes, opcode_hash_table, sparc_num_opcodes);
+ opcodes_initialized = 1;
+ }
+
+ {
+ int status =
+ (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ }
+
+ insn = bfd_getb32 (buffer);
+
+ info->insn_info_valid = 1; /* We do return this info */
+ info->insn_type = dis_nonbranch; /* Assume non branch insn */
+ info->branch_delay_insns = 0; /* Assume no delay */
+ info->target = 0; /* Assume no target known */
+
+ for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
+ {
+ const struct sparc_opcode *opcode = op->opcode;
+
+ /* ??? These architecture tests need to be more selective. */
+
+ /* If the current architecture isn't sparc64, skip sparc64 insns. */
+ if (!sparc_v9_p
+ && V9_ONLY_P (opcode))
+ continue;
+
+ /* If the current architecture is sparc64, skip sparc32 only insns. */
+ if (sparc_v9_p
+ && ! V9_P (opcode))
+ continue;
+
+ if ((opcode->match & insn) == opcode->match
+ && (opcode->lose & insn) == 0)
+ {
+ /* Nonzero means that we have found an instruction which has
+ the effect of adding or or'ing the imm13 field to rs1. */
+ int imm_added_to_rs1 = 0;
+
+ /* Nonzero means that we have found a plus sign in the args
+ field of the opcode table. */
+ int found_plus = 0;
+
+ /* Nonzero means we have an annulled branch. */
+ int is_annulled = 0;
+
+ /* Do we have an `add' or `or' instruction where rs1 is the same
+ as rsd, and which has the i bit set? */
+ if ((opcode->match == 0x80102000 || opcode->match == 0x80002000)
+ /* (or) (add) */
+ && X_RS1 (insn) == X_RD (insn))
+ imm_added_to_rs1 = 1;
+
+ if (X_RS1 (insn) != X_RD (insn)
+ && strchr (opcode->args, 'r') != 0)
+ /* Can't do simple format if source and dest are different. */
+ continue;
+ if (X_RS2 (insn) != X_RD (insn)
+ && strchr (opcode->args, 'O') != 0)
+ /* Can't do simple format if source and dest are different. */
+ continue;
+
+ (*info->fprintf_func) (stream, opcode->name);
+
+ {
+ register const char *s;
+
+ if (opcode->args[0] != ',')
+ (*info->fprintf_func) (stream, " ");
+ for (s = opcode->args; *s != '\0'; ++s)
+ {
+ while (*s == ',')
+ {
+ (*info->fprintf_func) (stream, ",");
+ ++s;
+ switch (*s) {
+ case 'a':
+ (*info->fprintf_func) (stream, "a");
+ is_annulled = 1;
+ ++s;
+ continue;
+ case 'N':
+ (*info->fprintf_func) (stream, "pn");
+ ++s;
+ continue;
+
+ case 'T':
+ (*info->fprintf_func) (stream, "pt");
+ ++s;
+ continue;
+
+ default:
+ break;
+ } /* switch on arg */
+ } /* while there are comma started args */
+
+ (*info->fprintf_func) (stream, " ");
+
+ switch (*s)
+ {
+ case '+':
+ found_plus = 1;
+
+ /* note fall-through */
+ default:
+ (*info->fprintf_func) (stream, "%c", *s);
+ break;
+
+ case '#':
+ (*info->fprintf_func) (stream, "0");
+ break;
+
+#define reg(n) (*info->fprintf_func) (stream, "%%%s", reg_names[n])
+ case '1':
+ case 'r':
+ reg (X_RS1 (insn));
+ break;
+
+ case '2':
+ case 'O':
+ reg (X_RS2 (insn));
+ break;
+
+ case 'd':
+ reg (X_RD (insn));
+ break;
+#undef reg
+
+#define freg(n) (*info->fprintf_func) (stream, "%%%s",
freg_names[n])
+#define fregx(n) (*info->fprintf_func) (stream, "%%%s",
freg_names[((n) & ~1) | (((n) & 1) << 5)])
+ case 'e':
+ freg (X_RS1 (insn));
+ break;
+ case 'v': /* double/even */
+ case 'V': /* quad/multiple of 4 */
+ fregx (X_RS1 (insn));
+ break;
+
+ case 'f':
+ freg (X_RS2 (insn));
+ break;
+ case 'B': /* double/even */
+ case 'R': /* quad/multiple of 4 */
+ fregx (X_RS2 (insn));
+ break;
+
+ case 'g':
+ freg (X_RD (insn));
+ break;
+ case 'H': /* double/even */
+ case 'J': /* quad/multiple of 4 */
+ fregx (X_RD (insn));
+ break;
+#undef freg
+#undef fregx
+
+#define creg(n) (*info->fprintf_func) (stream, "%%c%u", (unsigned int)
(n))
+ case 'b':
+ creg (X_RS1 (insn));
+ break;
+
+ case 'c':
+ creg (X_RS2 (insn));
+ break;
+
+ case 'D':
+ creg (X_RD (insn));
+ break;
+#undef creg
+
+ case 'h':
+ (*info->fprintf_func) (stream, "%%hi(%#x)",
+ (0xFFFFFFFF
+ & ((int) X_IMM22 (insn) << 10)));
+ break;
+
+ case 'i':
+ {
+ int imm = SEX (X_IMM13 (insn), 13);
+
+ /* Check to see whether we have a 1+i, and take
+ note of that fact.
+
+ Note: because of the way we sort the table,
+ we will be matching 1+i rather than i+1,
+ so it is OK to assume that i is after +,
+ not before it. */
+ if (found_plus)
+ imm_added_to_rs1 = 1;
+
+ if (imm <= 9)
+ (*info->fprintf_func) (stream, "%d", imm);
+ else
+ (*info->fprintf_func) (stream, "%#x", imm);
+ }
+ break;
+
+ case 'I': /* 11 bit immediate. */
+ case 'j': /* 10 bit immediate. */
+ {
+ int imm;
+
+ if (*s == 'I')
+ imm = SEX (X_IMM13 (insn), 11);
+ else
+ imm = SEX (X_IMM13 (insn), 10);
+
+ /* Check to see whether we have a 1+i, and take
+ note of that fact.
+
+ Note: because of the way we sort the table,
+ we will be matching 1+i rather than i+1,
+ so it is OK to assume that i is after +,
+ not before it. */
+ if (found_plus)
+ imm_added_to_rs1 = 1;
+
+ if (imm <= 9)
+ (info->fprintf_func) (stream, "%d", imm);
+ else
+ (info->fprintf_func) (stream, "%#x", (unsigned) imm);
+ }
+ break;
+
+ case 'K':
+ {
+ int mask = X_MEMBAR (insn);
+ int bit = 0x40, printed_one = 0;
+ char *name;
+
+ if (mask == 0)
+ (info->fprintf_func) (stream, "0");
+ else
+ while (bit)
+ {
+ if (mask & bit)
+ {
+ if (printed_one)
+ (info->fprintf_func) (stream, "|");
+ name = sparc_decode_membar (bit);
+ (info->fprintf_func) (stream, "%s", name);
+ printed_one = 1;
+ }
+ bit >>= 1;
+ }
+ break;
+ }
+
+ case 'k':
+ info->target = memaddr + SEX (X_DISP16 (insn), 16) * 4;
+ (*info->print_address_func) (info->target, info);
+ break;
+
+ case 'G':
+ info->target = memaddr + SEX (X_DISP19 (insn), 19) * 4;
+ (*info->print_address_func) (info->target, info);
+ break;
+
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ (*info->fprintf_func) (stream, "%%fcc%c", *s - '6' + '0');
+ break;
+
+ case 'z':
+ (*info->fprintf_func) (stream, "%%icc");
+ break;
+
+ case 'Z':
+ (*info->fprintf_func) (stream, "%%xcc");
+ break;
+
+ case 'E':
+ (*info->fprintf_func) (stream, "%%ccr");
+ break;
+
+ case 's':
+ (*info->fprintf_func) (stream, "%%fprs");
+ break;
+
+ case 'o':
+ (*info->fprintf_func) (stream, "%%asi");
+ break;
+
+ case 'W':
+ (*info->fprintf_func) (stream, "%%tick");
+ break;
+
+ case 'P':
+ (*info->fprintf_func) (stream, "%%pc");
+ break;
+
+ case '?':
+ if (X_RS1 (insn) == 31)
+ (*info->fprintf_func) (stream, "%%ver");
+ else if ((unsigned) X_RS1 (insn) < 16)
+ (*info->fprintf_func) (stream, "%%%s",
+ v9_priv_reg_names[X_RS1 (insn)]);
+ else
+ (*info->fprintf_func) (stream, "%%reserved");
+ break;
+
+ case '!':
+ if ((unsigned) X_RD (insn) < 15)
+ (*info->fprintf_func) (stream, "%%%s",
+ v9_priv_reg_names[X_RD (insn)]);
+ else
+ (*info->fprintf_func) (stream, "%%reserved");
+ break;
+
+ case '*':
+ {
+ char *name = sparc_decode_prefetch (X_RD (insn));
+
+ if (name)
+ (*info->fprintf_func) (stream, "%s", name);
+ else
+ (*info->fprintf_func) (stream, "%d", X_RD (insn));
+ break;
+ }
+
+ case 'M':
+ (*info->fprintf_func) (stream, "%%asr%d", X_RS1 (insn));
+ break;
+
+ case 'm':
+ (*info->fprintf_func) (stream, "%%asr%d", X_RD (insn));
+ break;
+
+ case 'L':
+ info->target = memaddr + SEX (X_DISP30 (insn), 30) * 4;
+ (*info->print_address_func) (info->target, info);
+ break;
+
+ case 'n':
+ (*info->fprintf_func)
+ (stream, "%#x", SEX (X_DISP22 (insn), 22));
+ break;
+
+ case 'l':
+ info->target = memaddr + SEX (X_DISP22 (insn), 22) * 4;
+ (*info->print_address_func) (info->target, info);
+ break;
+
+ case 'A':
+ {
+ char *name = sparc_decode_asi (X_ASI (insn));
+
+ if (name)
+ (*info->fprintf_func) (stream, "%s", name);
+ else
+ (*info->fprintf_func) (stream, "(%d)", X_ASI (insn));
+ break;
+ }
+
+ case 'C':
+ (*info->fprintf_func) (stream, "%%csr");
+ break;
+
+ case 'F':
+ (*info->fprintf_func) (stream, "%%fsr");
+ break;
+
+ case 'p':
+ (*info->fprintf_func) (stream, "%%psr");
+ break;
+
+ case 'q':
+ (*info->fprintf_func) (stream, "%%fq");
+ break;
+
+ case 'Q':
+ (*info->fprintf_func) (stream, "%%cq");
+ break;
+
+ case 't':
+ (*info->fprintf_func) (stream, "%%tbr");
+ break;
+
+ case 'w':
+ (*info->fprintf_func) (stream, "%%wim");
+ break;
+
+ case 'x':
+ (*info->fprintf_func) (stream, "%d",
+ ((X_LDST_I (insn) << 8)
+ + X_ASI (insn)));
+ break;
+
+ case 'y':
+ (*info->fprintf_func) (stream, "%%y");
+ break;
+
+ case 'u':
+ case 'U':
+ {
+ int val = *s == 'U' ? X_RS1 (insn) : X_RD (insn);
+ char *name = sparc_decode_sparclet_cpreg (val);
+
+ if (name)
+ (*info->fprintf_func) (stream, "%s", name);
+ else
+ (*info->fprintf_func) (stream, "%%cpreg(%d)", val);
+ break;
+ }
+ }
+ }
+ }
+
+ /* If we are adding or or'ing something to rs1, then
+ check to see whether the previous instruction was
+ a sethi to the same register as in the sethi.
+ If so, attempt to print the result of the add or
+ or (in this context add and or do the same thing)
+ and its symbolic value. */
+ if (imm_added_to_rs1)
+ {
+ unsigned long prev_insn;
+ int errcode;
+
+ errcode =
+ (*info->read_memory_func)
+ (memaddr - 4, buffer, sizeof (buffer), info);
+ prev_insn = bfd_getb32 (buffer);
+
+ if (errcode == 0)
+ {
+ /* If it is a delayed branch, we need to look at the
+ instruction before the delayed branch. This handles
+ sequences such as
+
+ sethi %o1, %hi(_foo), %o1
+ call _printf
+ or %o1, %lo(_foo), %o1
+ */
+
+ if (is_delayed_branch (prev_insn))
+ {
+ errcode = (*info->read_memory_func)
+ (memaddr - 8, buffer, sizeof (buffer), info);
+ prev_insn = bfd_getb32 (buffer);
+ }
+ }
+
+ /* If there was a problem reading memory, then assume
+ the previous instruction was not sethi. */
+ if (errcode == 0)
+ {
+ /* Is it sethi to the same register? */
+ if ((prev_insn & 0xc1c00000) == 0x01000000
+ && X_RD (prev_insn) == X_RS1 (insn))
+ {
+ (*info->fprintf_func) (stream, "\t! ");
+ info->target =
+ (0xFFFFFFFF & (int) X_IMM22 (prev_insn) << 10)
+ | SEX (X_IMM13 (insn), 13);
+ (*info->print_address_func) (info->target, info);
+ info->insn_type = dis_dref;
+ info->data_size = 4; /* FIXME!!! */
+ }
+ }
+ }
+
+ if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR))
+ {
+ /* FIXME -- check is_annulled flag */
+ if (opcode->flags & F_UNBR)
+ info->insn_type = dis_branch;
+ if (opcode->flags & F_CONDBR)
+ info->insn_type = dis_condbranch;
+ if (opcode->flags & F_JSR)
+ info->insn_type = dis_jsr;
+ if (opcode->flags & F_DELAYED)
+ info->branch_delay_insns = 1;
+ }
+
+ return sizeof (buffer);
+ }
+ }
+
+ info->insn_type = dis_noninsn; /* Mark as non-valid instruction */
+ (*info->fprintf_func) (stream, "unknown");
+ return sizeof (buffer);
+}
+
+/* Compare opcodes A and B. */
+
+static int
+compare_opcodes (a, b)
+ char *a, *b;
+{
+ struct sparc_opcode *op0 = (struct sparc_opcode *) a;
+ struct sparc_opcode *op1 = (struct sparc_opcode *) b;
+ unsigned long int match0 = op0->match, match1 = op1->match;
+ unsigned long int lose0 = op0->lose, lose1 = op1->lose;
+ register unsigned int i;
+
+ /* If a bit is set in both match and lose, there is something
+ wrong with the opcode table. */
+ if (match0 & lose0)
+ {
+ fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx,
%#.8lx\n",
+ op0->name, match0, lose0);
+ op0->lose &= ~op0->match;
+ lose0 = op0->lose;
+ }
+
+ if (match1 & lose1)
+ {
+ fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx,
%#.8lx\n",
+ op1->name, match1, lose1);
+ op1->lose &= ~op1->match;
+ lose1 = op1->lose;
+ }
+
+ /* Because the bits that are variable in one opcode are constant in
+ another, it is important to order the opcodes in the right order. */
+ for (i = 0; i < 32; ++i)
+ {
+ unsigned long int x = 1 << i;
+ int x0 = (match0 & x) != 0;
+ int x1 = (match1 & x) != 0;
+
+ if (x0 != x1)
+ return x1 - x0;
+ }
+
+ for (i = 0; i < 32; ++i)
+ {
+ unsigned long int x = 1 << i;
+ int x0 = (lose0 & x) != 0;
+ int x1 = (lose1 & x) != 0;
+
+ if (x0 != x1)
+ return x1 - x0;
+ }
+
+ /* Put non-sparc64 insns ahead of sparc64 ones. */
+ if (V9_ONLY_P (op0) != V9_ONLY_P (op1))
+ return V9_ONLY_P (op0) - V9_ONLY_P (op1);
+
+ /* They are functionally equal. So as long as the opcode table is
+ valid, we can put whichever one first we want, on aesthetic grounds. */
+
+ /* Our first aesthetic ground is that aliases defer to real insns. */
+ {
+ int alias_diff = (op0->flags & F_ALIAS) - (op1->flags & F_ALIAS);
+ if (alias_diff != 0)
+ /* Put the one that isn't an alias first. */
+ return alias_diff;
+ }
+
+ /* Except for aliases, two "identical" instructions had
+ better have the same opcode. This is a sanity check on the table. */
+ i = strcmp (op0->name, op1->name);
+ if (i)
+ if (op0->flags & F_ALIAS) /* If they're both aliases, be arbitrary. */
+ return i;
+ else
+ fprintf (stderr,
+ "Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n",
+ op0->name, op1->name);
+
+ /* Fewer arguments are preferred. */
+ {
+ int length_diff = strlen (op0->args) - strlen (op1->args);
+ if (length_diff != 0)
+ /* Put the one with fewer arguments first. */
+ return length_diff;
+ }
+
+ /* Put 1+i before i+1. */
+ {
+ char *p0 = (char *) strchr(op0->args, '+');
+ char *p1 = (char *) strchr(op1->args, '+');
+
+ if (p0 && p1)
+ {
+ /* There is a plus in both operands. Note that a plus
+ sign cannot be the first character in args,
+ so the following [-1]'s are valid. */
+ if (p0[-1] == 'i' && p1[1] == 'i')
+ /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
+ return 1;
+ if (p0[1] == 'i' && p1[-1] == 'i')
+ /* op0 is 1+i and op1 is i+1, so op0 goes first. */
+ return -1;
+ }
+ }
+
+ /* Put 1,i before i,1. */
+ {
+ int i0 = strncmp (op0->args, "i,1", 3) == 0;
+ int i1 = strncmp (op1->args, "i,1", 3) == 0;
+
+ if (i0 ^ i1)
+ return i0 - i1;
+ }
+
+ /* They are, as far as we can tell, identical.
+ Since qsort may have rearranged the table partially, there is
+ no way to tell which one was first in the opcode table as
+ written, so just say there are equal. */
+ return 0;
+}
+
+/* Build a hash table from the opcode table. */
+
+static void
+build_hash_table (table, hash_table, num_opcodes)
+ struct sparc_opcode *table;
+ struct opcode_hash **hash_table;
+ int num_opcodes;
+{
+ register int i;
+ int hash_count[HASH_SIZE];
+ static struct opcode_hash *hash_buf = NULL;
+
+ /* Start at the end of the table and work backwards so that each
+ chain is sorted. */
+
+ memset (hash_table, 0, HASH_SIZE * sizeof (hash_table[0]));
+ memset (hash_count, 0, HASH_SIZE * sizeof (hash_count[0]));
+ if (hash_buf != NULL)
+ free (hash_buf);
+ hash_buf = (struct opcode_hash *) xmalloc (sizeof (struct opcode_hash) *
num_opcodes);
+ for (i = num_opcodes - 1; i >= 0; --i)
+ {
+ register int hash = HASH_INSN (sparc_opcodes[i].match);
+ register struct opcode_hash *h = &hash_buf[i];
+ h->next = hash_table[hash];
+ h->opcode = &sparc_opcodes[i];
+ hash_table[hash] = h;
+ ++hash_count[hash];
+ }
+
+#if 0 /* for debugging */
+ {
+ int min_count = num_opcodes, max_count = 0;
+ int total;
+
+ for (i = 0; i < HASH_SIZE; ++i)
+ {
+ if (hash_count[i] < min_count)
+ min_count = hash_count[i];
+ if (hash_count[i] > max_count)
+ max_count = hash_count[i];
+ total += hash_count[i];
+ }
+
+ printf ("Opcode hash table stats: min %d, max %d, ave %f\n",
+ min_count, max_count, (double) total / HASH_SIZE);
+ }
+#endif
+}
diff --git a/opcode/sparc-opc.c b/opcode/sparc-opc.c
new file mode 100644
index 0000000..4e91227
--- /dev/null
+++ b/opcode/sparc-opc.c
@@ -0,0 +1,1757 @@
+/* Table of opcodes for the sparc.
+ Copyright (C) 1989, 1991, 1992, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the BFD library.
+
+BFD 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.
+
+BFD 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 software; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* 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. */
+
+/* v9 FIXME: Doesn't accept `setsw', `setx' synthetic instructions for v9. */
+
+#include <stdio.h>
+#include "ansidecl.h"
+#include "opcode/sparc.h"
+
+/* Some defines to make life easy. */
+#define MASK_V6 (1 << SPARC_OPCODE_ARCH_V6)
+#define MASK_V7 (1 << SPARC_OPCODE_ARCH_V7)
+#define MASK_V8 (1 << SPARC_OPCODE_ARCH_V8)
+#define MASK_SPARCLET (1 << SPARC_OPCODE_ARCH_SPARCLET)
+#define MASK_SPARCLITE (1 << SPARC_OPCODE_ARCH_SPARCLITE)
+#define MASK_V9 (1 << SPARC_OPCODE_ARCH_V9)
+#define MASK_V9A (1 << SPARC_OPCODE_ARCH_V9A)
+
+/* Bit masks of architectures supporting the insn. */
+
+#define v6 (MASK_V6 | MASK_V7 | MASK_V8 | MASK_SPARCLET \
+ | MASK_SPARCLITE | MASK_V9 | MASK_V9A)
+#define v7 (MASK_V7 | MASK_V8 | MASK_SPARCLET \
+ | MASK_SPARCLITE | MASK_V9 | MASK_V9A)
+/* Although not all insns are implemented in hardware, sparclite is defined
+ to be a superset of v8. Unimplemented insns trap and are then theoretically
+ implemented in software.
+ It's not clear that the same is true for sparclet, although the docs
+ suggest it is. Rather than complicating things, the sparclet assembler
+ recognizes all v8 insns. */
+#define v8 (MASK_V8 | MASK_SPARCLET | MASK_SPARCLITE | MASK_V9 |
MASK_V9A)
+#define sparclet (MASK_SPARCLET)
+#define sparclite (MASK_SPARCLITE)
+#define v9 (MASK_V9 | MASK_V9A)
+#define v9a (MASK_V9A)
+/* v6 insns not supported by v9 */
+#define v6notv9 (MASK_V6 | MASK_V7 | MASK_V8 \
+ | MASK_SPARCLET | MASK_SPARCLITE)
+
+/* Table of opcode architectures.
+ The order is defined in opcode/sparc.h. */
+const struct sparc_opcode_arch sparc_opcode_archs[] = {
+ { "v6", MASK_V6 },
+ { "v7", MASK_V6 | MASK_V7 },
+ { "v8", MASK_V6 | MASK_V7 | MASK_V8 },
+ { "sparclet", MASK_V6 | MASK_V7 | MASK_V8 | MASK_SPARCLET },
+ { "sparclite", MASK_V6 | MASK_V7 | MASK_V8 | MASK_SPARCLITE },
+ /* ??? Don't some v8 priviledged insns conflict with v9? */
+ { "v9", MASK_V6 | MASK_V7 | MASK_V8 | MASK_V9 },
+ /* v9 with ultrasparc additions */
+ { "v9a", MASK_V6 | MASK_V7 | MASK_V8 | MASK_V9 | MASK_V9A },
+ { NULL, 0 }
+};
+
+/* Given NAME, return it's architecture entry. */
+
+enum sparc_opcode_arch_val
+sparc_opcode_lookup_arch (name)
+ const char *name;
+{
+ const struct sparc_opcode_arch *p;
+
+ for (p = &sparc_opcode_archs[0]; p->name; ++p)
+ {
+ if (strcmp (name, p->name) == 0)
+ return (enum sparc_opcode_arch_val) (p - &sparc_opcode_archs[0]);
+ }
+
+ return SPARC_OPCODE_ARCH_BAD;
+}
+
+/* Branch condition field. */
+#define COND(x) (((x)&0xf)<<25)
+
+/* v9: Move (MOVcc and FMOVcc) condition field. */
+#define MCOND(x,i_or_f) ((((i_or_f)&1)<<18)|(((x)>>11)&(0xf<<14))) /*
v9 */
+
+/* v9: Move register (MOVRcc and FMOVRcc) condition field. */
+#define RCOND(x) (((x)&0x7)<<10) /* v9 */
+
+#define CONDA (COND(0x8))
+#define CONDCC (COND(0xd))
+#define CONDCS (COND(0x5))
+#define CONDE (COND(0x1))
+#define CONDG (COND(0xa))
+#define CONDGE (COND(0xb))
+#define CONDGU (COND(0xc))
+#define CONDL (COND(0x3))
+#define CONDLE (COND(0x2))
+#define CONDLEU (COND(0x4))
+#define CONDN (COND(0x0))
+#define CONDNE (COND(0x9))
+#define CONDNEG (COND(0x6))
+#define CONDPOS (COND(0xe))
+#define CONDVC (COND(0xf))
+#define CONDVS (COND(0x7))
+
+#define CONDNZ CONDNE
+#define CONDZ CONDE
+#define CONDGEU CONDCC
+#define CONDLU CONDCS
+
+#define FCONDA (COND(0x8))
+#define FCONDE (COND(0x9))
+#define FCONDG (COND(0x6))
+#define FCONDGE (COND(0xb))
+#define FCONDL (COND(0x4))
+#define FCONDLE (COND(0xd))
+#define FCONDLG (COND(0x2))
+#define FCONDN (COND(0x0))
+#define FCONDNE (COND(0x1))
+#define FCONDO (COND(0xf))
+#define FCONDU (COND(0x7))
+#define FCONDUE (COND(0xa))
+#define FCONDUG (COND(0x5))
+#define FCONDUGE (COND(0xc))
+#define FCONDUL (COND(0x3))
+#define FCONDULE (COND(0xe))
+
+#define FCONDNZ FCONDNE
+#define FCONDZ FCONDE
+
+#define ICC (0) /* v9 */
+#define XCC (1<<12) /* v9 */
+#define FCC(x) (((x)&0x3)<<11) /* v9 */
+#define FBFCC(x) (((x)&0x3)<<20) /* v9 */
+
+/* The order of the opcodes in the table is significant:
+
+ * The assembler requires that all instances of the same mnemonic must
+ be consecutive. If they aren't, the assembler will bomb at runtime.
+
+ * The disassembler should not care about the order of the opcodes.
+
+*/
+
+/* Entries for commutative arithmetic operations. */
+/* ??? More entries can make use of this. */
+#define commuteop(opcode, op3, arch_mask) \
+{ opcode, F3(2, op3, 0), F3(~2, ~op3, ~0)|ASI(~0), "1,2,d", 0,
arch_mask }, \
+{ opcode, F3(2, op3, 1), F3(~2, ~op3, ~1), "1,i,d", 0,
arch_mask }, \
+{ opcode, F3(2, op3, 1), F3(~2, ~op3, ~1), "i,1,d", 0,
arch_mask }
+
+struct sparc_opcode sparc_opcodes[] = {
+
+{ "ld", F3(3, 0x00, 0), F3(~3, ~0x00, ~0), "[1+2],d", 0,
v6 },
+{ "ld", F3(3, 0x00, 0), F3(~3, ~0x00, ~0)|RS2_G0, "[1],d", 0, v6
}, /* ld [rs1+%g0],d */
+{ "ld", F3(3, 0x00, 1), F3(~3, ~0x00, ~1), "[1+i],d", 0,
v6 },
+{ "ld", F3(3, 0x00, 1), F3(~3, ~0x00, ~1), "[i+1],d", 0,
v6 },
+{ "ld", F3(3, 0x00, 1), F3(~3, ~0x00, ~1)|RS1_G0, "[i],d", 0, v6
},
+{ "ld", F3(3, 0x00, 1), F3(~3, ~0x00, ~1)|SIMM13(~0), "[1],d", 0, v6
}, /* ld [rs1+0],d */
+{ "ld", F3(3, 0x20, 0), F3(~3, ~0x20, ~0), "[1+2],g", 0,
v6 },
+{ "ld", F3(3, 0x20, 0), F3(~3, ~0x20, ~0)|RS2_G0, "[1],g", 0, v6
}, /* ld [rs1+%g0],d */
+{ "ld", F3(3, 0x20, 1), F3(~3, ~0x20, ~1), "[1+i],g", 0,
v6 },
+{ "ld", F3(3, 0x20, 1), F3(~3, ~0x20, ~1), "[i+1],g", 0,
v6 },
+{ "ld", F3(3, 0x20, 1), F3(~3, ~0x20, ~1)|RS1_G0, "[i],g", 0, v6
},
+{ "ld", F3(3, 0x20, 1), F3(~3, ~0x20, ~1)|SIMM13(~0), "[1],g", 0, v6
}, /* ld [rs1+0],d */
+
+{ "ld", F3(3, 0x21, 0), F3(~3, ~0x21, ~0)|RD(~0), "[1+2],F", 0,
v6 },
+{ "ld", F3(3, 0x21, 0), F3(~3, ~0x21, ~0)|RS2_G0|RD(~0),"[1],F", 0, v6
}, /* ld [rs1+%g0],d */
+{ "ld", F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|RD(~0), "[1+i],F", 0,
v6 },
+{ "ld", F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|RD(~0), "[i+1],F", 0,
v6 },
+{ "ld", F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|RS1_G0|RD(~0),"[i],F", 0, v6
},
+{ "ld", F3(3, 0x21, 1), F3(~3, ~0x21, ~1)|SIMM13(~0)|RD(~0),"[1],F", 0,
v6 }, /* ld [rs1+0],d */
+
+{ "ld", F3(3, 0x30, 0), F3(~3, ~0x30, ~0), "[1+2],D", 0,
v6notv9 },
+{ "ld", F3(3, 0x30, 0), F3(~3, ~0x30, ~0)|RS2_G0, "[1],D", 0,
v6notv9 }, /* ld [rs1+%g0],d */
+{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1), "[1+i],D", 0,
v6notv9 },
+{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1), "[i+1],D", 0,
v6notv9 },
+{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|RS1_G0, "[i],D", 0,
v6notv9 },
+{ "ld", F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|SIMM13(~0), "[1],D", 0,
v6notv9 }, /* ld [rs1+0],d */
+{ "ld", F3(3, 0x31, 0), F3(~3, ~0x31, ~0), "[1+2],C", 0,
v6notv9 },
+{ "ld", F3(3, 0x31, 0), F3(~3, ~0x31, ~0)|RS2_G0, "[1],C", 0,
v6notv9 }, /* ld [rs1+%g0],d */
+{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1), "[1+i],C", 0,
v6notv9 },
+{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1), "[i+1],C", 0,
v6notv9 },
+{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1)|RS1_G0, "[i],C", 0,
v6notv9 },
+{ "ld", F3(3, 0x31, 1), F3(~3, ~0x31, ~1)|SIMM13(~0), "[1],C", 0,
v6notv9 }, /* ld [rs1+0],d */
+
+/* The v9 LDUW is the same as the old 'ld' opcode, it is not the same as the
+ 'ld' pseudo-op in v9. */
+{ "lduw", F3(3, 0x00, 0), F3(~3, ~0x00, ~0), "[1+2],d",
F_ALIAS, v9 },
+{ "lduw", F3(3, 0x00, 0), F3(~3, ~0x00, ~0)|RS2_G0, "[1],d",
F_ALIAS, v9 }, /* ld [rs1+%g0],d */
+{ "lduw", F3(3, 0x00, 1), F3(~3, ~0x00, ~1), "[1+i],d",
F_ALIAS, v9 },
+{ "lduw", F3(3, 0x00, 1), F3(~3, ~0x00, ~1), "[i+1],d",
F_ALIAS, v9 },
+{ "lduw", F3(3, 0x00, 1), F3(~3, ~0x00, ~1)|RS1_G0, "[i],d",
F_ALIAS, v9 },
+{ "lduw", F3(3, 0x00, 1), F3(~3, ~0x00, ~1)|SIMM13(~0), "[1],d",
F_ALIAS, v9 }, /* ld [rs1+0],d */
+
+{ "ldd", F3(3, 0x03, 0), F3(~3, ~0x03, ~0)|ASI(~0), "[1+2],d", 0,
v6 },
+{ "ldd", F3(3, 0x03, 0), F3(~3, ~0x03, ~0)|ASI_RS2(~0), "[1],d", 0, v6
}, /* ldd [rs1+%g0],d */
+{ "ldd", F3(3, 0x03, 1), F3(~3, ~0x03, ~1), "[1+i],d", 0,
v6 },
+{ "ldd", F3(3, 0x03, 1), F3(~3, ~0x03, ~1), "[i+1],d", 0,
v6 },
+{ "ldd", F3(3, 0x03, 1), F3(~3, ~0x03, ~1)|RS1_G0, "[i],d", 0, v6
},
+{ "ldd", F3(3, 0x03, 1), F3(~3, ~0x03, ~1)|SIMM13(~0), "[1],d", 0, v6
}, /* ldd [rs1+0],d */
+{ "ldd", F3(3, 0x23, 0), F3(~3, ~0x23, ~0)|ASI(~0), "[1+2],H", 0,
v6 },
+{ "ldd", F3(3, 0x23, 0), F3(~3, ~0x23, ~0)|ASI_RS2(~0), "[1],H", 0, v6
}, /* ldd [rs1+%g0],d */
+{ "ldd", F3(3, 0x23, 1), F3(~3, ~0x23, ~1), "[1+i],H", 0,
v6 },
+{ "ldd", F3(3, 0x23, 1), F3(~3, ~0x23, ~1), "[i+1],H", 0,
v6 },
+{ "ldd", F3(3, 0x23, 1), F3(~3, ~0x23, ~1)|RS1_G0, "[i],H", 0, v6
},
+{ "ldd", F3(3, 0x23, 1), F3(~3, ~0x23, ~1)|SIMM13(~0), "[1],H", 0, v6
}, /* ldd [rs1+0],d */
+
+{ "ldd", F3(3, 0x33, 0), F3(~3, ~0x33, ~0)|ASI(~0), "[1+2],D", 0,
v6notv9 },
+{ "ldd", F3(3, 0x33, 0), F3(~3, ~0x33, ~0)|ASI_RS2(~0), "[1],D", 0,
v6notv9 }, /* ldd [rs1+%g0],d */
+{ "ldd", F3(3, 0x33, 1), F3(~3, ~0x33, ~1), "[1+i],D", 0,
v6notv9 },
+{ "ldd", F3(3, 0x33, 1), F3(~3, ~0x33, ~1), "[i+1],D", 0,
v6notv9 },
+{ "ldd", F3(3, 0x33, 1), F3(~3, ~0x33, ~1)|RS1_G0, "[i],D", 0,
v6notv9 },
+{ "ldd", F3(3, 0x33, 1), F3(~3, ~0x33, ~1)|SIMM13(~0), "[1],D", 0,
v6notv9 }, /* ldd [rs1+0],d */
+
+{ "ldq", F3(3, 0x22, 0), F3(~3, ~0x22, ~0)|ASI(~0), "[1+2],J", 0,
v9 },
+{ "ldq", F3(3, 0x22, 0), F3(~3, ~0x22, ~0)|ASI_RS2(~0), "[1],J", 0, v9
}, /* ldd [rs1+%g0],d */
+{ "ldq", F3(3, 0x22, 1), F3(~3, ~0x22, ~1), "[1+i],J", 0,
v9 },
+{ "ldq", F3(3, 0x22, 1), F3(~3, ~0x22, ~1), "[i+1],J", 0,
v9 },
+{ "ldq", F3(3, 0x22, 1), F3(~3, ~0x22, ~1)|RS1_G0, "[i],J", 0, v9
},
+{ "ldq", F3(3, 0x22, 1), F3(~3, ~0x22, ~1)|SIMM13(~0), "[1],J", 0, v9
}, /* ldd [rs1+0],d */
+
+{ "ldsb", F3(3, 0x09, 0), F3(~3, ~0x09, ~0)|ASI(~0), "[1+2],d", 0,
v6 },
+{ "ldsb", F3(3, 0x09, 0), F3(~3, ~0x09, ~0)|ASI_RS2(~0), "[1],d", 0, v6
}, /* ldsb [rs1+%g0],d */
+{ "ldsb", F3(3, 0x09, 1), F3(~3, ~0x09, ~1), "[1+i],d", 0,
v6 },
+{ "ldsb", F3(3, 0x09, 1), F3(~3, ~0x09, ~1), "[i+1],d", 0,
v6 },
+{ "ldsb", F3(3, 0x09, 1), F3(~3, ~0x09, ~1)|RS1_G0, "[i],d", 0, v6
},
+{ "ldsb", F3(3, 0x09, 1), F3(~3, ~0x09, ~1)|SIMM13(~0), "[1],d", 0, v6
}, /* ldsb [rs1+0],d */
+
+{ "ldsh", F3(3, 0x0a, 0), F3(~3, ~0x0a, ~0)|ASI_RS2(~0), "[1],d", 0, v6
}, /* ldsh [rs1+%g0],d */
+{ "ldsh", F3(3, 0x0a, 0), F3(~3, ~0x0a, ~0)|ASI(~0), "[1+2],d", 0,
v6 },
+{ "ldsh", F3(3, 0x0a, 1), F3(~3, ~0x0a, ~1), "[1+i],d", 0,
v6 },
+{ "ldsh", F3(3, 0x0a, 1), F3(~3, ~0x0a, ~1), "[i+1],d", 0,
v6 },
+{ "ldsh", F3(3, 0x0a, 1), F3(~3, ~0x0a, ~1)|RS1_G0, "[i],d", 0, v6
},
+{ "ldsh", F3(3, 0x0a, 1), F3(~3, ~0x0a, ~1)|SIMM13(~0), "[1],d", 0, v6
}, /* ldsh [rs1+0],d */
+
+{ "ldstub", F3(3, 0x0d, 0), F3(~3, ~0x0d, ~0)|ASI(~0), "[1+2],d", 0,
v6 },
+{ "ldstub", F3(3, 0x0d, 0), F3(~3, ~0x0d, ~0)|ASI_RS2(~0), "[1],d", 0, v6
}, /* ldstub [rs1+%g0],d */
+{ "ldstub", F3(3, 0x0d, 1), F3(~3, ~0x0d, ~1), "[1+i],d", 0,
v6 },
+{ "ldstub", F3(3, 0x0d, 1), F3(~3, ~0x0d, ~1), "[i+1],d", 0,
v6 },
+{ "ldstub", F3(3, 0x0d, 1), F3(~3, ~0x0d, ~1)|RS1_G0, "[i],d", 0, v6
},
+{ "ldstub", F3(3, 0x0d, 1), F3(~3, ~0x0d, ~1)|SIMM13(~0), "[1],d", 0, v6
}, /* ldstub [rs1+0],d */
+
+{ "ldsw", F3(3, 0x08, 0), F3(~3, ~0x08, ~0)|ASI(~0), "[1+2],d", 0,
v9 },
+{ "ldsw", F3(3, 0x08, 0), F3(~3, ~0x08, ~0)|ASI_RS2(~0), "[1],d", 0, v9
}, /* ldsw [rs1+%g0],d */
+{ "ldsw", F3(3, 0x08, 1), F3(~3, ~0x08, ~1), "[1+i],d", 0,
v9 },
+{ "ldsw", F3(3, 0x08, 1), F3(~3, ~0x08, ~1), "[i+1],d", 0,
v9 },
+{ "ldsw", F3(3, 0x08, 1), F3(~3, ~0x08, ~1)|RS1_G0, "[i],d", 0, v9
},
+{ "ldsw", F3(3, 0x08, 1), F3(~3, ~0x08, ~1)|SIMM13(~0), "[1],d", 0, v9
}, /* ldsw [rs1+0],d */
+
+{ "ldub", F3(3, 0x01, 0), F3(~3, ~0x01, ~0)|ASI(~0), "[1+2],d", 0,
v6 },
+{ "ldub", F3(3, 0x01, 0), F3(~3, ~0x01, ~0)|ASI_RS2(~0), "[1],d", 0, v6
}, /* ldub [rs1+%g0],d */
+{ "ldub", F3(3, 0x01, 1), F3(~3, ~0x01, ~1), "[1+i],d", 0,
v6 },
+{ "ldub", F3(3, 0x01, 1), F3(~3, ~0x01, ~1), "[i+1],d", 0,
v6 },
+{ "ldub", F3(3, 0x01, 1), F3(~3, ~0x01, ~1)|RS1_G0, "[i],d", 0, v6
},
+{ "ldub", F3(3, 0x01, 1), F3(~3, ~0x01, ~1)|SIMM13(~0), "[1],d", 0, v6
}, /* ldub [rs1+0],d */
+
+{ "lduh", F3(3, 0x02, 0), F3(~3, ~0x02, ~0)|ASI(~0), "[1+2],d", 0,
v6 },
+{ "lduh", F3(3, 0x02, 0), F3(~3, ~0x02, ~0)|ASI_RS2(~0), "[1],d", 0, v6
}, /* lduh [rs1+%g0],d */
+{ "lduh", F3(3, 0x02, 1), F3(~3, ~0x02, ~1), "[1+i],d", 0,
v6 },
+{ "lduh", F3(3, 0x02, 1), F3(~3, ~0x02, ~1), "[i+1],d", 0,
v6 },
+{ "lduh", F3(3, 0x02, 1), F3(~3, ~0x02, ~1)|RS1_G0, "[i],d", 0, v6
},
+{ "lduh", F3(3, 0x02, 1), F3(~3, ~0x02, ~1)|SIMM13(~0), "[1],d", 0, v6
}, /* lduh [rs1+0],d */
+
+{ "ldx", F3(3, 0x0b, 0), F3(~3, ~0x0b, ~0)|ASI(~0), "[1+2],d", 0,
v9 },
+{ "ldx", F3(3, 0x0b, 0), F3(~3, ~0x0b, ~0)|ASI_RS2(~0), "[1],d", 0, v9
}, /* ldx [rs1+%g0],d */
+{ "ldx", F3(3, 0x0b, 1), F3(~3, ~0x0b, ~1), "[1+i],d", 0,
v9 },
+{ "ldx", F3(3, 0x0b, 1), F3(~3, ~0x0b, ~1), "[i+1],d", 0,
v9 },
+{ "ldx", F3(3, 0x0b, 1), F3(~3, ~0x0b, ~1)|RS1_G0, "[i],d", 0, v9
},
+{ "ldx", F3(3, 0x0b, 1), F3(~3, ~0x0b, ~1)|SIMM13(~0), "[1],d", 0, v9
}, /* ldx [rs1+0],d */
+
+{ "ldx", F3(3, 0x21, 0)|RD(1), F3(~3, ~0x21, ~0)|RD(~1), "[1+2],F", 0,
v9 },
+{ "ldx", F3(3, 0x21, 0)|RD(1), F3(~3, ~0x21, ~0)|RS2_G0|RD(~1),
"[1],F", 0, v9 }, /* ld [rs1+%g0],d */
+{ "ldx", F3(3, 0x21, 1)|RD(1), F3(~3, ~0x21, ~1)|RD(~1), "[1+i],F", 0,
v9 },
+{ "ldx", F3(3, 0x21, 1)|RD(1), F3(~3, ~0x21, ~1)|RD(~1), "[i+1],F", 0,
v9 },
+{ "ldx", F3(3, 0x21, 1)|RD(1), F3(~3, ~0x21, ~1)|RS1_G0|RD(~1),
"[i],F", 0, v9 },
+{ "ldx", F3(3, 0x21, 1)|RD(1), F3(~3, ~0x21,
~1)|SIMM13(~0)|RD(~1),"[1],F", 0, v9 }, /* ld [rs1+0],d */
+
+{ "lda", F3(3, 0x10, 0), F3(~3, ~0x10, ~0), "[1+2]A,d", 0,
v6 },
+{ "lda", F3(3, 0x10, 0), F3(~3, ~0x10, ~0)|RS2_G0, "[1]A,d", 0, v6
}, /* lda [rs1+%g0],d */
+{ "lda", F3(3, 0x10, 1), F3(~3, ~0x10, ~1), "[1+i]o,d", 0,
v9 },
+{ "lda", F3(3, 0x10, 1), F3(~3, ~0x10, ~1), "[i+1]o,d", 0,
v9 },
+{ "lda", F3(3, 0x10, 1), F3(~3, ~0x10, ~1)|RS1_G0, "[i]o,d", 0, v9
},
+{ "lda", F3(3, 0x10, 1), F3(~3, ~0x10, ~1)|SIMM13(~0), "[1]o,d", 0, v9
}, /* ld [rs1+0],d */
+{ "lda", F3(3, 0x30, 0), F3(~3, ~0x30, ~0), "[1+2]A,g", 0,
v9 },
+{ "lda", F3(3, 0x30, 0), F3(~3, ~0x30, ~0)|RS2_G0, "[1]A,g", 0, v9
}, /* lda [rs1+%g0],d */
+{ "lda", F3(3, 0x30, 1), F3(~3, ~0x30, ~1), "[1+i]o,g", 0,
v9 },
+{ "lda", F3(3, 0x30, 1), F3(~3, ~0x30, ~1), "[i+1]o,g", 0,
v9 },
+{ "lda", F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|RS1_G0, "[i]o,g", 0, v9
},
+{ "lda", F3(3, 0x30, 1), F3(~3, ~0x30, ~1)|SIMM13(~0), "[1]o,g", 0, v9
}, /* ld [rs1+0],d */
+
+{ "ldda", F3(3, 0x13, 0), F3(~3, ~0x13, ~0), "[1+2]A,d", 0,
v6 },
+{ "ldda", F3(3, 0x13, 0), F3(~3, ~0x13, ~0)|RS2_G0, "[1]A,d", 0, v6
}, /* ldda [rs1+%g0],d */
+{ "ldda", F3(3, 0x13, 1), F3(~3, ~0x13, ~1), "[1+i]o,d", 0,
v9 },
+{ "ldda", F3(3, 0x13, 1), F3(~3, ~0x13, ~1), "[i+1]o,d", 0,
v9 },
+{ "ldda", F3(3, 0x13, 1), F3(~3, ~0x13, ~1)|RS1_G0, "[i]o,d", 0, v9
},
+{ "ldda", F3(3, 0x13, 1), F3(~3, ~0x13, ~1)|SIMM13(~0), "[1]o,d", 0, v9
}, /* ld [rs1+0],d */
+
+{ "ldda", F3(3, 0x33, 0), F3(~3, ~0x33, ~0), "[1+2]A,H", 0,
v9 },
+{ "ldda", F3(3, 0x33, 0), F3(~3, ~0x33, ~0)|RS2_G0, "[1]A,H", 0, v9
}, /* ldda [rs1+%g0],d */
+{ "ldda", F3(3, 0x33, 1), F3(~3, ~0x33, ~1), "[1+i]o,H", 0,
v9 },
+{ "ldda", F3(3, 0x33, 1), F3(~3, ~0x33, ~1), "[i+1]o,H", 0,
v9 },
+{ "ldda", F3(3, 0x33, 1), F3(~3, ~0x33, ~1)|RS1_G0, "[i]o,H", 0, v9
},
+{ "ldda", F3(3, 0x33, 1), F3(~3, ~0x33, ~1)|SIMM13(~0), "[1]o,H", 0, v9
}, /* ld [rs1+0],d */
+
+{ "ldqa", F3(3, 0x32, 0), F3(~3, ~0x32, ~0), "[1+2]A,J", 0,
v9 },
+{ "ldqa", F3(3, 0x32, 0), F3(~3, ~0x32, ~0)|RS2_G0, "[1]A,J", 0, v9
}, /* ldd [rs1+%g0],d */
+{ "ldqa", F3(3, 0x32, 1), F3(~3, ~0x32, ~1), "[1+i]o,J", 0,
v9 },
+{ "ldqa", F3(3, 0x32, 1), F3(~3, ~0x32, ~1), "[i+1]o,J", 0,
v9 },
+{ "ldqa", F3(3, 0x32, 1), F3(~3, ~0x32, ~1)|RS1_G0, "[i]o,J", 0, v9
},
+{ "ldqa", F3(3, 0x32, 1), F3(~3, ~0x32, ~1)|SIMM13(~0), "[1]o,J", 0, v9
}, /* ldd [rs1+0],d */
+
+{ "ldsba", F3(3, 0x19, 0), F3(~3, ~0x19, ~0), "[1+2]A,d", 0,
v6 },
+{ "ldsba", F3(3, 0x19, 0), F3(~3, ~0x19, ~0)|RS2_G0, "[1]A,d", 0, v6
}, /* ldsba [rs1+%g0],d */
+{ "ldsba", F3(3, 0x19, 1), F3(~3, ~0x19, ~1), "[1+i]o,d", 0,
v9 },
+{ "ldsba", F3(3, 0x19, 1), F3(~3, ~0x19, ~1), "[i+1]o,d", 0,
v9 },
+{ "ldsba", F3(3, 0x19, 1), F3(~3, ~0x19, ~1)|RS1_G0, "[i]o,d", 0, v9
},
+{ "ldsba", F3(3, 0x19, 1), F3(~3, ~0x19, ~1)|SIMM13(~0), "[1]o,d", 0, v9
}, /* ld [rs1+0],d */
+
+{ "ldsha", F3(3, 0x1a, 0), F3(~3, ~0x1a, ~0), "[1+2]A,d", 0,
v6 },
+{ "ldsha", F3(3, 0x1a, 0), F3(~3, ~0x1a, ~0)|RS2_G0, "[1]A,d", 0, v6
}, /* ldsha [rs1+%g0],d */
+{ "ldsha", F3(3, 0x1a, 1), F3(~3, ~0x1a, ~1), "[1+i]o,d", 0,
v9 },
+{ "ldsha", F3(3, 0x1a, 1), F3(~3, ~0x1a, ~1), "[i+1]o,d", 0,
v9 },
+{ "ldsha", F3(3, 0x1a, 1), F3(~3, ~0x1a, ~1)|RS1_G0, "[i]o,d", 0, v9
},
+{ "ldsha", F3(3, 0x1a, 1), F3(~3, ~0x1a, ~1)|SIMM13(~0), "[1]o,d", 0, v9
}, /* ld [rs1+0],d */
+
+{ "ldstuba", F3(3, 0x1d, 0), F3(~3, ~0x1d, ~0), "[1+2]A,d", 0,
v6 },
+{ "ldstuba", F3(3, 0x1d, 0), F3(~3, ~0x1d, ~0)|RS2_G0, "[1]A,d", 0, v6
}, /* ldstuba [rs1+%g0],d */
+{ "ldstuba", F3(3, 0x1d, 1), F3(~3, ~0x1d, ~1), "[1+i]o,d", 0,
v9 },
+{ "ldstuba", F3(3, 0x1d, 1), F3(~3, ~0x1d, ~1), "[i+1]o,d", 0,
v9 },
+{ "ldstuba", F3(3, 0x1d, 1), F3(~3, ~0x1d, ~1)|RS1_G0, "[i]o,d", 0, v9
},
+{ "ldstuba", F3(3, 0x1d, 1), F3(~3, ~0x1d, ~1)|SIMM13(~0), "[1]o,d", 0, v9
}, /* ld [rs1+0],d */
+
+{ "ldswa", F3(3, 0x18, 0), F3(~3, ~0x18, ~0), "[1+2]A,d", 0,
v9 },
+{ "ldswa", F3(3, 0x18, 0), F3(~3, ~0x18, ~0)|RS2_G0, "[1]A,d", 0, v9
}, /* lda [rs1+%g0],d */
+{ "ldswa", F3(3, 0x18, 1), F3(~3, ~0x18, ~1), "[1+i]o,d", 0,
v9 },
+{ "ldswa", F3(3, 0x18, 1), F3(~3, ~0x18, ~1), "[i+1]o,d", 0,
v9 },
+{ "ldswa", F3(3, 0x18, 1), F3(~3, ~0x18, ~1)|RS1_G0, "[i]o,d", 0, v9
},
+{ "ldswa", F3(3, 0x18, 1), F3(~3, ~0x18, ~1)|SIMM13(~0), "[1]o,d", 0, v9
}, /* ld [rs1+0],d */
+
+{ "lduba", F3(3, 0x11, 0), F3(~3, ~0x11, ~0), "[1+2]A,d", 0,
v6 },
+{ "lduba", F3(3, 0x11, 0), F3(~3, ~0x11, ~0)|RS2_G0, "[1]A,d", 0, v6
}, /* lduba [rs1+%g0],d */
+{ "lduba", F3(3, 0x11, 1), F3(~3, ~0x11, ~1), "[1+i]o,d", 0,
v9 },
+{ "lduba", F3(3, 0x11, 1), F3(~3, ~0x11, ~1), "[i+1]o,d", 0,
v9 },
+{ "lduba", F3(3, 0x11, 1), F3(~3, ~0x11, ~1)|RS1_G0, "[i]o,d", 0, v9
},
+{ "lduba", F3(3, 0x11, 1), F3(~3, ~0x11, ~1)|SIMM13(~0), "[1]o,d", 0, v9
}, /* ld [rs1+0],d */
+
+{ "lduha", F3(3, 0x12, 0), F3(~3, ~0x12, ~0), "[1+2]A,d", 0,
v6 },
+{ "lduha", F3(3, 0x12, 0), F3(~3, ~0x12, ~0)|RS2_G0, "[1]A,d", 0, v6
}, /* lduha [rs1+%g0],d */
+{ "lduha", F3(3, 0x12, 1), F3(~3, ~0x12, ~1), "[1+i]o,d", 0,
v9 },
+{ "lduha", F3(3, 0x12, 1), F3(~3, ~0x12, ~1), "[i+1]o,d", 0,
v9 },
+{ "lduha", F3(3, 0x12, 1), F3(~3, ~0x12, ~1)|RS1_G0, "[i]o,d", 0, v9
},
+{ "lduha", F3(3, 0x12, 1), F3(~3, ~0x12, ~1)|SIMM13(~0), "[1]o,d", 0, v9
}, /* ld [rs1+0],d */
+
+{ "lduwa", F3(3, 0x10, 0), F3(~3, ~0x10, ~0), "[1+2]A,d",
F_ALIAS, v9 }, /* lduwa === lda */
+{ "lduwa", F3(3, 0x10, 0), F3(~3, ~0x10, ~0)|RS2_G0, "[1]A,d",
F_ALIAS, v9 }, /* lda [rs1+%g0],d */
+{ "lduwa", F3(3, 0x10, 1), F3(~3, ~0x10, ~1), "[1+i]o,d",
F_ALIAS, v9 },
+{ "lduwa", F3(3, 0x10, 1), F3(~3, ~0x10, ~1), "[i+1]o,d",
F_ALIAS, v9 },
+{ "lduwa", F3(3, 0x10, 1), F3(~3, ~0x10, ~1)|RS1_G0, "[i]o,d",
F_ALIAS, v9 },
+{ "lduwa", F3(3, 0x10, 1), F3(~3, ~0x10, ~1)|SIMM13(~0), "[1]o,d",
F_ALIAS, v9 }, /* ld [rs1+0],d */
+
+{ "ldxa", F3(3, 0x1b, 0), F3(~3, ~0x1b, ~0), "[1+2]A,d", 0,
v9 }, /* lduwa === lda */
+{ "ldxa", F3(3, 0x1b, 0), F3(~3, ~0x1b, ~0)|RS2_G0, "[1]A,d", 0, v9
}, /* lda [rs1+%g0],d */
+{ "ldxa", F3(3, 0x1b, 1), F3(~3, ~0x1b, ~1), "[1+i]o,d", 0,
v9 },
+{ "ldxa", F3(3, 0x1b, 1), F3(~3, ~0x1b, ~1), "[i+1]o,d", 0,
v9 },
+{ "ldxa", F3(3, 0x1b, 1), F3(~3, ~0x1b, ~1)|RS1_G0, "[i]o,d", 0, v9
},
+{ "ldxa", F3(3, 0x1b, 1), F3(~3, ~0x1b, ~1)|SIMM13(~0), "[1]o,d", 0, v9
}, /* ld [rs1+0],d */
+
+{ "st", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI(~0),
"d,[1+2]", 0, v6 },
+{ "st", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI_RS2(~0),
"d,[1]", 0, v6 }, /* st d,[rs1+%g0] */
+{ "st", F3(3, 0x04, 1), F3(~3, ~0x04, ~1),
"d,[1+i]", 0, v6 },
+{ "st", F3(3, 0x04, 1), F3(~3, ~0x04, ~1),
"d,[i+1]", 0, v6 },
+{ "st", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RS1_G0,
"d,[i]", 0, v6 },
+{ "st", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|SIMM13(~0),
"d,[1]", 0, v6 }, /* st d,[rs1+0] */
+{ "st", F3(3, 0x24, 0), F3(~3, ~0x24, ~0)|ASI(~0),
"g,[1+2]", 0, v6 },
+{ "st", F3(3, 0x24, 0), F3(~3, ~0x24, ~0)|ASI_RS2(~0),
"g,[1]", 0, v6 }, /* st d[rs1+%g0] */
+{ "st", F3(3, 0x24, 1), F3(~3, ~0x24, ~1),
"g,[1+i]", 0, v6 },
+{ "st", F3(3, 0x24, 1), F3(~3, ~0x24, ~1),
"g,[i+1]", 0, v6 },
+{ "st", F3(3, 0x24, 1), F3(~3, ~0x24, ~1)|RS1_G0,
"g,[i]", 0, v6 },
+{ "st", F3(3, 0x24, 1), F3(~3, ~0x24, ~1)|SIMM13(~0),
"g,[1]", 0, v6 }, /* st d,[rs1+0] */
+
+{ "st", F3(3, 0x34, 0), F3(~3, ~0x34, ~0)|ASI(~0),
"D,[1+2]", 0, v6notv9 },
+{ "st", F3(3, 0x34, 0), F3(~3, ~0x34, ~0)|ASI_RS2(~0),
"D,[1]", 0, v6notv9 }, /* st d,[rs1+%g0] */
+{ "st", F3(3, 0x34, 1), F3(~3, ~0x34, ~1),
"D,[1+i]", 0, v6notv9 },
+{ "st", F3(3, 0x34, 1), F3(~3, ~0x34, ~1),
"D,[i+1]", 0, v6notv9 },
+{ "st", F3(3, 0x34, 1), F3(~3, ~0x34, ~1)|RS1_G0,
"D,[i]", 0, v6notv9 },
+{ "st", F3(3, 0x34, 1), F3(~3, ~0x34, ~1)|SIMM13(~0),
"D,[1]", 0, v6notv9 }, /* st d,[rs1+0] */
+{ "st", F3(3, 0x35, 0), F3(~3, ~0x35, ~0)|ASI(~0),
"C,[1+2]", 0, v6notv9 },
+{ "st", F3(3, 0x35, 0), F3(~3, ~0x35, ~0)|ASI_RS2(~0),
"C,[1]", 0, v6notv9 }, /* st d,[rs1+%g0] */
+{ "st", F3(3, 0x35, 1), F3(~3, ~0x35, ~1),
"C,[1+i]", 0, v6notv9 },
+{ "st", F3(3, 0x35, 1), F3(~3, ~0x35, ~1),
"C,[i+1]", 0, v6notv9 },
+{ "st", F3(3, 0x35, 1), F3(~3, ~0x35, ~1)|RS1_G0,
"C,[i]", 0, v6notv9 },
+{ "st", F3(3, 0x35, 1), F3(~3, ~0x35, ~1)|SIMM13(~0),
"C,[1]", 0, v6notv9 }, /* st d,[rs1+0] */
+
+{ "st", F3(3, 0x25, 0), F3(~3, ~0x25, ~0)|RD_G0|ASI(~0),
"F,[1+2]", 0, v6 },
+{ "st", F3(3, 0x25, 0), F3(~3, ~0x25, ~0)|RD_G0|ASI_RS2(~0),
"F,[1]", 0, v6 }, /* st d,[rs1+%g0] */
+{ "st", F3(3, 0x25, 1), F3(~3, ~0x25, ~1)|RD_G0,
"F,[1+i]", 0, v6 },
+{ "st", F3(3, 0x25, 1), F3(~3, ~0x25, ~1)|RD_G0,
"F,[i+1]", 0, v6 },
+{ "st", F3(3, 0x25, 1), F3(~3, ~0x25, ~1)|RD_G0|RS1_G0,
"F,[i]", 0, v6 },
+{ "st", F3(3, 0x25, 1), F3(~3, ~0x25, ~1)|RD_G0|SIMM13(~0),
"F,[1]", 0, v6 }, /* st d,[rs1+0] */
+
+{ "stw", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI(~0), "d,[1+2]",
F_ALIAS, v9 },
+{ "stw", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|ASI_RS2(~0), "d,[1]",
F_ALIAS, v9 }, /* st d,[rs1+%g0] */
+{ "stw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1), "d,[1+i]",
F_ALIAS, v9 },
+{ "stw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1), "d,[i+1]",
F_ALIAS, v9 },
+{ "stw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RS1_G0, "d,[i]",
F_ALIAS, v9 },
+{ "stw", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|SIMM13(~0), "d,[1]",
F_ALIAS, v9 }, /* st d,[rs1+0] */
+
+{ "sta", F3(3, 0x14, 0), F3(~3, ~0x14, ~0), "d,[1+2]A", 0,
v6 },
+{ "sta", F3(3, 0x14, 0), F3(~3, ~0x14, ~0)|RS2(~0), "d,[1]A", 0, v6
}, /* sta d,[rs1+%g0] */
+{ "sta", F3(3, 0x14, 1), F3(~3, ~0x14, ~1), "d,[1+i]o", 0,
v9 },
+{ "sta", F3(3, 0x14, 1), F3(~3, ~0x14, ~1), "d,[i+1]o", 0,
v9 },
+{ "sta", F3(3, 0x14, 1), F3(~3, ~0x14, ~1)|RS1_G0, "d,[i]o", 0, v9
},
+{ "sta", F3(3, 0x14, 1), F3(~3, ~0x14, ~1)|SIMM13(~0), "d,[1]o", 0, v9
}, /* st d,[rs1+0] */
+
+{ "sta", F3(3, 0x34, 0), F3(~3, ~0x34, ~0), "g,[1+2]A", 0,
v9 },
+{ "sta", F3(3, 0x34, 0), F3(~3, ~0x34, ~0)|RS2(~0), "g,[1]A", 0, v9
}, /* sta d,[rs1+%g0] */
+{ "sta", F3(3, 0x34, 1), F3(~3, ~0x34, ~1), "g,[1+i]o", 0,
v9 },
+{ "sta", F3(3, 0x34, 1), F3(~3, ~0x34, ~1), "g,[i+1]o", 0,
v9 },
+{ "sta", F3(3, 0x34, 1), F3(~3, ~0x34, ~1)|RS1_G0, "g,[i]o", 0, v9
},
+{ "sta", F3(3, 0x34, 1), F3(~3, ~0x34, ~1)|SIMM13(~0), "g,[1]o", 0, v9
}, /* st d,[rs1+0] */
+
+{ "stwa", F3(3, 0x14, 0), F3(~3, ~0x14, ~0), "d,[1+2]A",
F_ALIAS, v9 },
+{ "stwa", F3(3, 0x14, 0), F3(~3, ~0x14, ~0)|RS2(~0), "d,[1]A",
F_ALIAS, v9 }, /* sta d,[rs1+%g0] */
+{ "stwa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1), "d,[1+i]o",
F_ALIAS, v9 },
+{ "stwa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1), "d,[i+1]o",
F_ALIAS, v9 },
+{ "stwa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1)|RS1_G0, "d,[i]o",
F_ALIAS, v9 },
+{ "stwa", F3(3, 0x14, 1), F3(~3, ~0x14, ~1)|SIMM13(~0), "d,[1]o",
F_ALIAS, v9 }, /* st d,[rs1+0] */
+
+{ "stb", F3(3, 0x05, 0), F3(~3, ~0x05, ~0)|ASI(~0), "d,[1+2]", 0,
v6 },
+{ "stb", F3(3, 0x05, 0), F3(~3, ~0x05, ~0)|ASI_RS2(~0), "d,[1]", 0, v6
}, /* stb d,[rs1+%g0] */
+{ "stb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1), "d,[1+i]", 0,
v6 },
+{ "stb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1), "d,[i+1]", 0,
v6 },
+{ "stb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|RS1_G0, "d,[i]", 0, v6
},
+{ "stb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|SIMM13(~0), "d,[1]", 0, v6
}, /* stb d,[rs1+0] */
+
+{ "stba", F3(3, 0x15, 0), F3(~3, ~0x15, ~0), "d,[1+2]A", 0,
v6 },
+{ "stba", F3(3, 0x15, 0), F3(~3, ~0x15, ~0)|RS2(~0), "d,[1]A", 0, v6
}, /* stba d,[rs1+%g0] */
+{ "stba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1), "d,[1+i]o", 0,
v9 },
+{ "stba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1), "d,[i+1]o", 0,
v9 },
+{ "stba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1)|RS1_G0, "d,[i]o", 0, v9
},
+{ "stba", F3(3, 0x15, 1), F3(~3, ~0x15, ~1)|SIMM13(~0), "d,[1]o", 0, v9
}, /* stb d,[rs1+0] */
+
+{ "std", F3(3, 0x07, 0), F3(~3, ~0x07, ~0)|ASI(~0), "d,[1+2]", 0,
v6 },
+{ "std", F3(3, 0x07, 0), F3(~3, ~0x07, ~0)|ASI_RS2(~0), "d,[1]", 0, v6
}, /* std d,[rs1+%g0] */
+{ "std", F3(3, 0x07, 1), F3(~3, ~0x07, ~1), "d,[1+i]", 0,
v6 },
+{ "std", F3(3, 0x07, 1), F3(~3, ~0x07, ~1), "d,[i+1]", 0,
v6 },
+{ "std", F3(3, 0x07, 1), F3(~3, ~0x07, ~1)|RS1_G0, "d,[i]", 0, v6
},
+{ "std", F3(3, 0x07, 1), F3(~3, ~0x07, ~1)|SIMM13(~0), "d,[1]", 0, v6
}, /* std d,[rs1+0] */
+
+{ "std", F3(3, 0x26, 0), F3(~3, ~0x26, ~0)|ASI(~0), "q,[1+2]", 0,
v6notv9 },
+{ "std", F3(3, 0x26, 0), F3(~3, ~0x26, ~0)|ASI_RS2(~0), "q,[1]", 0,
v6notv9 }, /* std d,[rs1+%g0] */
+{ "std", F3(3, 0x26, 1), F3(~3, ~0x26, ~1), "q,[1+i]", 0,
v6notv9 },
+{ "std", F3(3, 0x26, 1), F3(~3, ~0x26, ~1), "q,[i+1]", 0,
v6notv9 },
+{ "std", F3(3, 0x26, 1), F3(~3, ~0x26, ~1)|RS1_G0, "q,[i]", 0,
v6notv9 },
+{ "std", F3(3, 0x26, 1), F3(~3, ~0x26, ~1)|SIMM13(~0), "q,[1]", 0,
v6notv9 }, /* std d,[rs1+0] */
+{ "std", F3(3, 0x27, 0), F3(~3, ~0x27, ~0)|ASI(~0), "H,[1+2]", 0,
v6 },
+{ "std", F3(3, 0x27, 0), F3(~3, ~0x27, ~0)|ASI_RS2(~0), "H,[1]", 0, v6
}, /* std d,[rs1+%g0] */
+{ "std", F3(3, 0x27, 1), F3(~3, ~0x27, ~1), "H,[1+i]", 0,
v6 },
+{ "std", F3(3, 0x27, 1), F3(~3, ~0x27, ~1), "H,[i+1]", 0,
v6 },
+{ "std", F3(3, 0x27, 1), F3(~3, ~0x27, ~1)|RS1_G0, "H,[i]", 0, v6
},
+{ "std", F3(3, 0x27, 1), F3(~3, ~0x27, ~1)|SIMM13(~0), "H,[1]", 0, v6
}, /* std d,[rs1+0] */
+
+{ "std", F3(3, 0x36, 0), F3(~3, ~0x36, ~0)|ASI(~0), "Q,[1+2]", 0,
v6notv9 },
+{ "std", F3(3, 0x36, 0), F3(~3, ~0x36, ~0)|ASI_RS2(~0), "Q,[1]", 0,
v6notv9 }, /* std d,[rs1+%g0] */
+{ "std", F3(3, 0x36, 1), F3(~3, ~0x36, ~1), "Q,[1+i]", 0,
v6notv9 },
+{ "std", F3(3, 0x36, 1), F3(~3, ~0x36, ~1), "Q,[i+1]", 0,
v6notv9 },
+{ "std", F3(3, 0x36, 1), F3(~3, ~0x36, ~1)|RS1_G0, "Q,[i]", 0,
v6notv9 },
+{ "std", F3(3, 0x36, 1), F3(~3, ~0x36, ~1)|SIMM13(~0), "Q,[1]", 0,
v6notv9 }, /* std d,[rs1+0] */
+{ "std", F3(3, 0x37, 0), F3(~3, ~0x37, ~0)|ASI(~0), "D,[1+2]", 0,
v6notv9 },
+{ "std", F3(3, 0x37, 0), F3(~3, ~0x37, ~0)|ASI_RS2(~0), "D,[1]", 0,
v6notv9 }, /* std d,[rs1+%g0] */
+{ "std", F3(3, 0x37, 1), F3(~3, ~0x37, ~1), "D,[1+i]", 0,
v6notv9 },
+{ "std", F3(3, 0x37, 1), F3(~3, ~0x37, ~1), "D,[i+1]", 0,
v6notv9 },
+{ "std", F3(3, 0x37, 1), F3(~3, ~0x37, ~1)|RS1_G0, "D,[i]", 0,
v6notv9 },
+{ "std", F3(3, 0x37, 1), F3(~3, ~0x37, ~1)|SIMM13(~0), "D,[1]", 0,
v6notv9 }, /* std d,[rs1+0] */
+
+{ "stda", F3(3, 0x17, 0), F3(~3, ~0x17, ~0), "d,[1+2]A", 0,
v6 },
+{ "stda", F3(3, 0x17, 0), F3(~3, ~0x17, ~0)|RS2(~0), "d,[1]A", 0, v6
}, /* stda d,[rs1+%g0] */
+{ "stda", F3(3, 0x17, 1), F3(~3, ~0x17, ~1), "d,[1+i]o", 0,
v9 },
+{ "stda", F3(3, 0x17, 1), F3(~3, ~0x17, ~1), "d,[i+1]o", 0,
v9 },
+{ "stda", F3(3, 0x17, 1), F3(~3, ~0x17, ~1)|RS1_G0, "d,[i]o", 0, v9
},
+{ "stda", F3(3, 0x17, 1), F3(~3, ~0x17, ~1)|SIMM13(~0), "d,[1]o", 0, v9
}, /* std d,[rs1+0] */
+{ "stda", F3(3, 0x37, 0), F3(~3, ~0x37, ~0), "H,[1+2]A", 0,
v9 },
+{ "stda", F3(3, 0x37, 0), F3(~3, ~0x37, ~0)|RS2(~0), "H,[1]A", 0, v9
}, /* stda d,[rs1+%g0] */
+{ "stda", F3(3, 0x37, 1), F3(~3, ~0x37, ~1), "H,[1+i]o", 0,
v9 },
+{ "stda", F3(3, 0x37, 1), F3(~3, ~0x37, ~1), "H,[i+1]o", 0,
v9 },
+{ "stda", F3(3, 0x37, 1), F3(~3, ~0x37, ~1)|RS1_G0, "H,[i]o", 0, v9
},
+{ "stda", F3(3, 0x37, 1), F3(~3, ~0x37, ~1)|SIMM13(~0), "H,[1]o", 0, v9
}, /* std d,[rs1+0] */
+
+{ "sth", F3(3, 0x06, 0), F3(~3, ~0x06, ~0)|ASI(~0), "d,[1+2]", 0,
v6 },
+{ "sth", F3(3, 0x06, 0), F3(~3, ~0x06, ~0)|ASI_RS2(~0), "d,[1]", 0, v6
}, /* sth d,[rs1+%g0] */
+{ "sth", F3(3, 0x06, 1), F3(~3, ~0x06, ~1), "d,[1+i]", 0,
v6 },
+{ "sth", F3(3, 0x06, 1), F3(~3, ~0x06, ~1), "d,[i+1]", 0,
v6 },
+{ "sth", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|RS1_G0, "d,[i]", 0, v6
},
+{ "sth", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|SIMM13(~0), "d,[1]", 0, v6
}, /* sth d,[rs1+0] */
+
+{ "stha", F3(3, 0x16, 0), F3(~3, ~0x16, ~0), "d,[1+2]A", 0,
v6 },
+{ "stha", F3(3, 0x16, 0), F3(~3, ~0x16, ~0)|RS2(~0), "d,[1]A", 0, v6
}, /* stha ,[rs1+%g0] */
+{ "stha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1), "d,[1+i]o", 0,
v9 },
+{ "stha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1), "d,[i+1]o", 0,
v9 },
+{ "stha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1)|RS1_G0, "d,[i]o", 0, v9
},
+{ "stha", F3(3, 0x16, 1), F3(~3, ~0x16, ~1)|SIMM13(~0), "d,[1]o", 0, v9
}, /* sth d,[rs1+0] */
+
+{ "stx", F3(3, 0x0e, 0), F3(~3, ~0x0e, ~0)|ASI(~0), "d,[1+2]", 0,
v9 },
+{ "stx", F3(3, 0x0e, 0), F3(~3, ~0x0e, ~0)|ASI_RS2(~0), "d,[1]", 0, v9
}, /* stx d,[rs1+%g0] */
+{ "stx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1), "d,[1+i]", 0,
v9 },
+{ "stx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1), "d,[i+1]", 0,
v9 },
+{ "stx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1)|RS1_G0, "d,[i]", 0, v9
},
+{ "stx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1)|SIMM13(~0), "d,[1]", 0, v9
}, /* stx d,[rs1+0] */
+
+{ "stx", F3(3, 0x25, 0)|RD(1), F3(~3, ~0x25, ~0)|ASI(~0)|RD(~1),
"F,[1+2]", 0, v9 },
+{ "stx", F3(3, 0x25, 0)|RD(1), F3(~3, ~0x25,
~0)|ASI_RS2(~0)|RD(~1),"F,[1]", 0, v9 }, /* stx d,[rs1+%g0] */
+{ "stx", F3(3, 0x25, 1)|RD(1), F3(~3, ~0x25, ~1)|RD(~1),
"F,[1+i]", 0, v9 },
+{ "stx", F3(3, 0x25, 1)|RD(1), F3(~3, ~0x25, ~1)|RD(~1),
"F,[i+1]", 0, v9 },
+{ "stx", F3(3, 0x25, 1)|RD(1), F3(~3, ~0x25, ~1)|RS1_G0|RD(~1),
"F,[i]", 0, v9 },
+{ "stx", F3(3, 0x25, 1)|RD(1), F3(~3, ~0x25,
~1)|SIMM13(~0)|RD(~1),"F,[1]", 0, v9 }, /* stx d,[rs1+0] */
+
+{ "stxa", F3(3, 0x1e, 0), F3(~3, ~0x1e, ~0), "d,[1+2]A", 0,
v9 },
+{ "stxa", F3(3, 0x1e, 0), F3(~3, ~0x1e, ~0)|RS2(~0), "d,[1]A", 0, v9
}, /* stxa d,[rs1+%g0] */
+{ "stxa", F3(3, 0x1e, 1), F3(~3, ~0x1e, ~1), "d,[1+i]o", 0,
v9 },
+{ "stxa", F3(3, 0x1e, 1), F3(~3, ~0x1e, ~1), "d,[i+1]o", 0,
v9 },
+{ "stxa", F3(3, 0x1e, 1), F3(~3, ~0x1e, ~1)|RS1_G0, "d,[i]o", 0, v9
},
+{ "stxa", F3(3, 0x1e, 1), F3(~3, ~0x1e, ~1)|SIMM13(~0), "d,[1]o", 0, v9
}, /* stx d,[rs1+0] */
+
+{ "stq", F3(3, 0x26, 0), F3(~3, ~0x26, ~0)|ASI(~0), "J,[1+2]", 0,
v9 },
+{ "stq", F3(3, 0x26, 0), F3(~3, ~0x26, ~0)|ASI_RS2(~0), "J,[1]", 0, v9
}, /* stq [rs1+%g0] */
+{ "stq", F3(3, 0x26, 1), F3(~3, ~0x26, ~1), "J,[1+i]", 0,
v9 },
+{ "stq", F3(3, 0x26, 1), F3(~3, ~0x26, ~1), "J,[i+1]", 0,
v9 },
+{ "stq", F3(3, 0x26, 1), F3(~3, ~0x26, ~1)|RS1_G0, "J,[i]", 0, v9
},
+{ "stq", F3(3, 0x26, 1), F3(~3, ~0x26, ~1)|SIMM13(~0), "J,[1]", 0, v9
}, /* stq [rs1+0] */
+
+{ "stqa", F3(3, 0x36, 0), F3(~3, ~0x36, ~0)|ASI(~0), "J,[1+2]A", 0,
v9 },
+{ "stqa", F3(3, 0x36, 0), F3(~3, ~0x36, ~0)|ASI_RS2(~0), "J,[1]A", 0, v9
}, /* stqa [rs1+%g0] */
+{ "stqa", F3(3, 0x36, 1), F3(~3, ~0x36, ~1), "J,[1+i]o", 0,
v9 },
+{ "stqa", F3(3, 0x36, 1), F3(~3, ~0x36, ~1), "J,[i+1]o", 0,
v9 },
+{ "stqa", F3(3, 0x36, 1), F3(~3, ~0x36, ~1)|RS1_G0, "J,[i]o", 0, v9
},
+{ "stqa", F3(3, 0x36, 1), F3(~3, ~0x36, ~1)|SIMM13(~0), "J,[1]o", 0, v9
}, /* stqa [rs1+0] */
+
+{ "swap", F3(3, 0x0f, 0), F3(~3, ~0x0f, ~0)|ASI(~0), "[1+2],d", 0,
v7 },
+{ "swap", F3(3, 0x0f, 0), F3(~3, ~0x0f, ~0)|ASI_RS2(~0), "[1],d", 0, v7
}, /* swap [rs1+%g0],d */
+{ "swap", F3(3, 0x0f, 1), F3(~3, ~0x0f, ~1), "[1+i],d", 0,
v7 },
+{ "swap", F3(3, 0x0f, 1), F3(~3, ~0x0f, ~1), "[i+1],d", 0,
v7 },
+{ "swap", F3(3, 0x0f, 1), F3(~3, ~0x0f, ~1)|RS1_G0, "[i],d", 0, v7
},
+{ "swap", F3(3, 0x0f, 1), F3(~3, ~0x0f, ~1)|SIMM13(~0), "[1],d", 0, v7
}, /* swap [rs1+0],d */
+
+{ "swapa", F3(3, 0x1f, 0), F3(~3, ~0x1f, ~0), "[1+2]A,d", 0,
v7 },
+{ "swapa", F3(3, 0x1f, 0), F3(~3, ~0x1f, ~0)|RS2(~0), "[1]A,d", 0, v7
}, /* swapa [rs1+%g0],d */
+{ "swapa", F3(3, 0x1f, 1), F3(~3, ~0x1f, ~1), "[1+i]o,d", 0,
v9 },
+{ "swapa", F3(3, 0x1f, 1), F3(~3, ~0x1f, ~1), "[i+1]o,d", 0,
v9 },
+{ "swapa", F3(3, 0x1f, 1), F3(~3, ~0x1f, ~1)|RS1_G0, "[i]o,d", 0, v9
},
+{ "swapa", F3(3, 0x1f, 1), F3(~3, ~0x1f, ~1)|SIMM13(~0), "[1]o,d", 0, v9
}, /* swap [rs1+0],d */
+
+{ "restore", F3(2, 0x3d, 0), F3(~2, ~0x3d, ~0)|ASI(~0),
"1,2,d", 0, v6 },
+{ "restore", F3(2, 0x3d, 0), F3(~2, ~0x3d, ~0)|RD_G0|RS1_G0|ASI_RS2(~0),
"", 0, v6 }, /* restore %g0,%g0,%g0 */
+{ "restore", F3(2, 0x3d, 1), F3(~2, ~0x3d, ~1),
"1,i,d", 0, v6 },
+{ "restore", F3(2, 0x3d, 1), F3(~2, ~0x3d, ~1)|RD_G0|RS1_G0|SIMM13(~0),
"", 0, v6 }, /* restore %g0,0,%g0 */
+
+{ "rett", F3(2, 0x39, 0), F3(~2, ~0x39, ~0)|RD_G0|ASI(~0), "1+2",
F_UNBR|F_DELAYED, v6 }, /* rett rs1+rs2 */
+{ "rett", F3(2, 0x39, 0), F3(~2, ~0x39, ~0)|RD_G0|ASI_RS2(~0), "1",
F_UNBR|F_DELAYED, v6 }, /* rett rs1,%g0 */
+{ "rett", F3(2, 0x39, 1), F3(~2, ~0x39, ~1)|RD_G0, "1+i",
F_UNBR|F_DELAYED, v6 }, /* rett rs1+X */
+{ "rett", F3(2, 0x39, 1), F3(~2, ~0x39, ~1)|RD_G0, "i+1",
F_UNBR|F_DELAYED, v6 }, /* rett X+rs1 */
+{ "rett", F3(2, 0x39, 1), F3(~2, ~0x39, ~1)|RD_G0|RS1_G0, "i",
F_UNBR|F_DELAYED, v6 }, /* rett X+rs1 */
+{ "rett", F3(2, 0x39, 1), F3(~2, ~0x39, ~1)|RD_G0|RS1_G0, "i",
F_UNBR|F_DELAYED, v6 }, /* rett X */
+{ "rett", F3(2, 0x39, 1), F3(~2, ~0x39, ~1)|RD_G0|SIMM13(~0), "1",
F_UNBR|F_DELAYED, v6 }, /* rett rs1+0 */
+
+{ "save", F3(2, 0x3c, 0), F3(~2, ~0x3c, ~0)|ASI(~0), "1,2,d", 0, v6
},
+{ "save", F3(2, 0x3c, 1), F3(~2, ~0x3c, ~1), "1,i,d", 0, v6
},
+{ "save", 0x81e00000, ~0x81e00000, "", F_ALIAS, v6
},
+
+{ "ret", F3(2, 0x38, 1)|RS1(0x1f)|SIMM13(8), F3(~2, ~0x38, ~1)|SIMM13(~8),
"", F_UNBR|F_DELAYED, v6 }, /* jmpl %i7+8,%g0 */
+{ "retl", F3(2, 0x38, 1)|RS1(0x0f)|SIMM13(8), F3(~2, ~0x38,
~1)|RS1(~0x0f)|SIMM13(~8), "", F_UNBR|F_DELAYED, v6 }, /* jmpl %o7+8,%g0 */
+
+{ "jmpl", F3(2, 0x38, 0), F3(~2, ~0x38, ~0)|ASI(~0), "1+2,d",
F_JSR|F_DELAYED, v6 },
+{ "jmpl", F3(2, 0x38, 0), F3(~2, ~0x38, ~0)|ASI_RS2(~0), "1,d",
F_JSR|F_DELAYED, v6 }, /* jmpl rs1+%g0,d */
+{ "jmpl", F3(2, 0x38, 1), F3(~2, ~0x38, ~1)|SIMM13(~0), "1,d",
F_JSR|F_DELAYED, v6 }, /* jmpl rs1+0,d */
+{ "jmpl", F3(2, 0x38, 1), F3(~2, ~0x38, ~1)|RS1_G0, "i,d",
F_JSR|F_DELAYED, v6 }, /* jmpl %g0+i,d */
+{ "jmpl", F3(2, 0x38, 1), F3(~2, ~0x38, ~1), "1+i,d",
F_JSR|F_DELAYED, v6 },
+{ "jmpl", F3(2, 0x38, 1), F3(~2, ~0x38, ~1), "i+1,d",
F_JSR|F_DELAYED, v6 },
+
+{ "done", F3(2, 0x3e, 0)|RD(0), F3(~2, ~0x3e,
~0)|RD(~0)|RS1_G0|SIMM13(~0), "", 0, v9 },
+{ "retry", F3(2, 0x3e, 0)|RD(1), F3(~2, ~0x3e,
~0)|RD(~1)|RS1_G0|SIMM13(~0), "", 0, v9 },
+{ "saved", F3(2, 0x31, 0)|RD(0), F3(~2, ~0x31,
~0)|RD(~0)|RS1_G0|SIMM13(~0), "", 0, v9 },
+{ "restored", F3(2, 0x31, 0)|RD(1), F3(~2, ~0x31,
~0)|RD(~1)|RS1_G0|SIMM13(~0), "", 0, v9 },
+{ "sir", F3(2, 0x30, 1)|RD(0xf), F3(~2, ~0x30, ~1)|RD(~0xf)|RS1_G0,
"i", 0, v9 },
+
+{ "flush", F3(2, 0x3b, 0), F3(~2, ~0x3b, ~0)|ASI(~0), "1+2", 0, v8 },
+{ "flush", F3(2, 0x3b, 0), F3(~2, ~0x3b, ~0)|ASI_RS2(~0), "1", 0, v8 },
/* flush rs1+%g0 */
+{ "flush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1)|SIMM13(~0), "1", 0, v8 },
/* flush rs1+0 */
+{ "flush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1)|RS1_G0, "i", 0, v8 },
/* flush %g0+i */
+{ "flush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1), "1+i", 0, v8 },
+{ "flush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1), "i+1", 0, v8 },
+
+/* IFLUSH was renamed to FLUSH in v8. */
+{ "iflush", F3(2, 0x3b, 0), F3(~2, ~0x3b, ~0)|ASI(~0), "1+2", F_ALIAS,
v6 },
+{ "iflush", F3(2, 0x3b, 0), F3(~2, ~0x3b, ~0)|ASI_RS2(~0), "1", F_ALIAS,
v6 }, /* flush rs1+%g0 */
+{ "iflush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1)|SIMM13(~0), "1", F_ALIAS,
v6 }, /* flush rs1+0 */
+{ "iflush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1)|RS1_G0, "i", F_ALIAS,
v6 },
+{ "iflush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1), "1+i", F_ALIAS,
v6 },
+{ "iflush", F3(2, 0x3b, 1), F3(~2, ~0x3b, ~1), "i+1", F_ALIAS,
v6 },
+
+{ "return", F3(2, 0x39, 0), F3(~2, ~0x39, ~0)|ASI(~0), "1+2", 0, v9 },
+{ "return", F3(2, 0x39, 0), F3(~2, ~0x39, ~0)|ASI_RS2(~0), "1", 0, v9 },
/* return rs1+%g0 */
+{ "return", F3(2, 0x39, 1), F3(~2, ~0x39, ~1)|SIMM13(~0), "1", 0, v9 },
/* return rs1+0 */
+{ "return", F3(2, 0x39, 1), F3(~2, ~0x39, ~1)|RS1_G0, "i", 0, v9 },
/* return %g0+i */
+{ "return", F3(2, 0x39, 1), F3(~2, ~0x39, ~1), "1+i", 0, v9 },
+{ "return", F3(2, 0x39, 1), F3(~2, ~0x39, ~1), "i+1", 0, v9 },
+
+{ "flushw", F3(2, 0x2b, 0), F3(~2, ~0x2b, ~0)|RD_G0|RS1_G0|ASI_RS2(~0),
"", 0, v9 },
+
+{ "membar", F3(2, 0x28, 1)|RS1(0xf), F3(~2, ~0x28,
~1)|RD_G0|RS1(~0xf)|SIMM13(~127), "K", 0, v9 },
+{ "stbar", F3(2, 0x28, 0)|RS1(0xf), F3(~2, ~0x28,
~0)|RD_G0|RS1(~0xf)|SIMM13(~0), "", 0, v8 },
+
+{ "prefetch", F3(3, 0x2d, 0), F3(~3, ~0x2d, ~0), "[1+2],*", 0,
v9 },
+{ "prefetch", F3(3, 0x2d, 0), F3(~3, ~0x2d, ~0)|RS2_G0, "[1],*", 0, v9
}, /* prefetch [rs1+%g0],prefetch_fcn */
+{ "prefetch", F3(3, 0x2d, 1), F3(~3, ~0x2d, ~1), "[1+i],*", 0,
v9 },
+{ "prefetch", F3(3, 0x2d, 1), F3(~3, ~0x2d, ~1), "[i+1],*", 0,
v9 },
+{ "prefetch", F3(3, 0x2d, 1), F3(~3, ~0x2d, ~1)|RS1_G0, "[i],*", 0, v9
},
+{ "prefetch", F3(3, 0x2d, 1), F3(~3, ~0x2d, ~1)|SIMM13(~0), "[1],*", 0, v9
}, /* prefetch [rs1+0],prefetch_fcn */
+{ "prefetcha", F3(3, 0x3d, 0), F3(~3, ~0x3d, ~0), "[1+2]A,*", 0,
v9 },
+{ "prefetcha", F3(3, 0x3d, 0), F3(~3, ~0x3d, ~0)|RS2_G0, "[1]A,*", 0, v9
}, /* prefetcha [rs1+%g0],prefetch_fcn */
+{ "prefetcha", F3(3, 0x3d, 1), F3(~3, ~0x3d, ~1), "[1+i]o,*", 0,
v9 },
+{ "prefetcha", F3(3, 0x3d, 1), F3(~3, ~0x3d, ~1), "[i+1]o,*", 0,
v9 },
+{ "prefetcha", F3(3, 0x3d, 1), F3(~3, ~0x3d, ~1)|RS1_G0, "[i]o,*", 0, v9
},
+{ "prefetcha", F3(3, 0x3d, 1), F3(~3, ~0x3d, ~1)|SIMM13(~0), "[1]o,*", 0, v9
}, /* prefetcha [rs1+0],d */
+
+ /* The 1<<12 is a long story. It is necessary. For more info, please
contact address@hidden */
+ /* FIXME: 'i' is wrong, need new letter for 5 bit unsigned constants. */
+{ "sll", F3(2, 0x25, 0), F3(~2, ~0x25, ~0)|(1<<12)|ASI(~0),
"1,2,d", 0, v6 },
+{ "sll", F3(2, 0x25, 1), F3(~2, ~0x25, ~1)|(1<<12),
"1,i,d", 0, v6 },
+{ "sra", F3(2, 0x27, 0), F3(~2, ~0x27, ~0)|(1<<12)|ASI(~0),
"1,2,d", 0, v6 },
+{ "sra", F3(2, 0x27, 1), F3(~2, ~0x27, ~1)|(1<<12),
"1,i,d", 0, v6 },
+{ "srl", F3(2, 0x26, 0), F3(~2, ~0x26, ~0)|(1<<12)|ASI(~0),
"1,2,d", 0, v6 },
+{ "srl", F3(2, 0x26, 1), F3(~2, ~0x26, ~1)|(1<<12),
"1,i,d", 0, v6 },
+
+ /* FIXME: 'j' is wrong, need new letter for 6 bit unsigned constants. */
+{ "sllx", F3(2, 0x25, 0)|(1<<12), F3(~2, ~0x25, ~0)|(ASI(~0)^(1<<12)),
"1,2,d", 0, v9 },
+{ "sllx", F3(2, 0x25, 1)|(1<<12), F3(~2, ~0x25, ~1)|(0x3f<<6),
"1,j,d", 0, v9 },
+{ "srax", F3(2, 0x27, 0)|(1<<12), F3(~2, ~0x27, ~0)|(ASI(~0)^(1<<12)),
"1,2,d", 0, v9 },
+{ "srax", F3(2, 0x27, 1)|(1<<12), F3(~2, ~0x27, ~1)|(0x3f<<6),
"1,j,d", 0, v9 },
+{ "srlx", F3(2, 0x26, 0)|(1<<12), F3(~2, ~0x26, ~0)|(ASI(~0)^(1<<12)),
"1,2,d", 0, v9 },
+{ "srlx", F3(2, 0x26, 1)|(1<<12), F3(~2, ~0x26, ~1)|(0x3f<<6),
"1,j,d", 0, v9 },
+
+{ "mulscc", F3(2, 0x24, 0), F3(~2, ~0x24, ~0)|ASI(~0), "1,2,d", 0, v6
},
+{ "mulscc", F3(2, 0x24, 1), F3(~2, ~0x24, ~1), "1,i,d", 0, v6
},
+
+{ "divscc", F3(2, 0x1d, 0), F3(~2, ~0x1d, ~0)|ASI(~0), "1,2,d", 0,
sparclite },
+{ "divscc", F3(2, 0x1d, 1), F3(~2, ~0x1d, ~1), "1,i,d", 0,
sparclite },
+
+{ "scan", F3(2, 0x2c, 0), F3(~2, ~0x2c, ~0)|ASI(~0), "1,2,d", 0,
sparclet|sparclite },
+{ "scan", F3(2, 0x2c, 1), F3(~2, ~0x2c, ~1), "1,i,d", 0,
sparclet|sparclite },
+
+{ "popc", F3(2, 0x2e, 0), F3(~2, ~0x2e, ~0)|RS2_G0|ASI(~0),"2,d", 0, v9 },
+{ "popc", F3(2, 0x2e, 1), F3(~2, ~0x2e, ~1)|RS2_G0, "i,d", 0, v9 },
+
+{ "clr", F3(2, 0x02, 0), F3(~2, ~0x02, ~0)|RD_G0|RS1_G0|ASI_RS2(~0),
"d", F_ALIAS, v6 }, /* or %g0,%g0,d */
+{ "clr", F3(2, 0x02, 1), F3(~2, ~0x02, ~1)|RS1_G0|SIMM13(~0),
"d", F_ALIAS, v6 }, /* or %g0,0,d */
+{ "clr", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|RD_G0|ASI(~0),
"[1+2]", F_ALIAS, v6 },
+{ "clr", F3(3, 0x04, 0), F3(~3, ~0x04, ~0)|RD_G0|ASI_RS2(~0),
"[1]", F_ALIAS, v6 }, /* st %g0,[rs1+%g0] */
+{ "clr", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RD_G0,
"[1+i]", F_ALIAS, v6 },
+{ "clr", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RD_G0,
"[i+1]", F_ALIAS, v6 },
+{ "clr", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RD_G0|RS1_G0,
"[i]", F_ALIAS, v6 },
+{ "clr", F3(3, 0x04, 1), F3(~3, ~0x04, ~1)|RD_G0|SIMM13(~0),
"[1]", F_ALIAS, v6 }, /* st %g0,[rs1+0] */
+
+{ "clrb", F3(3, 0x05, 0), F3(~3, ~0x05, ~0)|RD_G0|ASI(~0),
"[1+2]", F_ALIAS, v6 },
+{ "clrb", F3(3, 0x05, 0), F3(~3, ~0x05, ~0)|RD_G0|ASI_RS2(~0), "[1]",
F_ALIAS, v6 }, /* stb %g0,[rs1+%g0] */
+{ "clrb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|RD_G0,
"[1+i]", F_ALIAS, v6 },
+{ "clrb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|RD_G0,
"[i+1]", F_ALIAS, v6 },
+{ "clrb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|RD_G0|RS1_G0, "[i]",
F_ALIAS, v6 },
+{ "clrb", F3(3, 0x05, 1), F3(~3, ~0x05, ~1)|RD_G0|SIMM13(~0), "[1]",
F_ALIAS, v6 }, /* stb %g0,[rs1+0] */
+
+{ "clrh", F3(3, 0x06, 0), F3(~3, ~0x06, ~0)|RD_G0|ASI(~0),
"[1+2]", F_ALIAS, v6 },
+{ "clrh", F3(3, 0x06, 0), F3(~3, ~0x06, ~0)|RD_G0|ASI_RS2(~0), "[1]",
F_ALIAS, v6 }, /* sth %g0,[rs1+%g0] */
+{ "clrh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|RD_G0,
"[1+i]", F_ALIAS, v6 },
+{ "clrh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|RD_G0,
"[i+1]", F_ALIAS, v6 },
+{ "clrh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|RD_G0|RS1_G0, "[i]",
F_ALIAS, v6 },
+{ "clrh", F3(3, 0x06, 1), F3(~3, ~0x06, ~1)|RD_G0|SIMM13(~0), "[1]",
F_ALIAS, v6 }, /* sth %g0,[rs1+0] */
+
+{ "clrx", F3(3, 0x0e, 0), F3(~3, ~0x0e, ~0)|RD_G0|ASI(~0),
"[1+2]", F_ALIAS, v9 },
+{ "clrx", F3(3, 0x0e, 0), F3(~3, ~0x0e, ~0)|RD_G0|ASI_RS2(~0), "[1]",
F_ALIAS, v9 }, /* stx %g0,[rs1+%g0] */
+{ "clrx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1)|RD_G0,
"[1+i]", F_ALIAS, v9 },
+{ "clrx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1)|RD_G0,
"[i+1]", F_ALIAS, v9 },
+{ "clrx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1)|RD_G0|RS1_G0, "[i]",
F_ALIAS, v9 },
+{ "clrx", F3(3, 0x0e, 1), F3(~3, ~0x0e, ~1)|RD_G0|SIMM13(~0), "[1]",
F_ALIAS, v9 }, /* stx %g0,[rs1+0] */
+
+{ "orcc", F3(2, 0x12, 0), F3(~2, ~0x12, ~0)|ASI(~0), "1,2,d", 0, v6
},
+{ "orcc", F3(2, 0x12, 1), F3(~2, ~0x12, ~1), "1,i,d", 0, v6
},
+{ "orcc", F3(2, 0x12, 1), F3(~2, ~0x12, ~1), "i,1,d", 0, v6
},
+
+/* This is not a commutative instruction. */
+{ "orncc", F3(2, 0x16, 0), F3(~2, ~0x16, ~0)|ASI(~0), "1,2,d", 0, v6
},
+{ "orncc", F3(2, 0x16, 1), F3(~2, ~0x16, ~1), "1,i,d", 0, v6
},
+
+/* This is not a commutative instruction. */
+{ "orn", F3(2, 0x06, 0), F3(~2, ~0x06, ~0)|ASI(~0), "1,2,d", 0, v6
},
+{ "orn", F3(2, 0x06, 1), F3(~2, ~0x06, ~1), "1,i,d", 0, v6
},
+
+{ "tst", F3(2, 0x12, 0), F3(~2, ~0x12, ~0)|RD_G0|ASI_RS2(~0), "1", 0,
v6 }, /* orcc rs1, %g0, %g0 */
+{ "tst", F3(2, 0x12, 0), F3(~2, ~0x12, ~0)|RD_G0|RS1_G0|ASI(~0), "2", 0,
v6 }, /* orcc %g0, rs2, %g0 */
+{ "tst", F3(2, 0x12, 1), F3(~2, ~0x12, ~1)|RD_G0|SIMM13(~0), "1", 0,
v6 }, /* orcc rs1, 0, %g0 */
+
+{ "wr", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|ASI(~0),
"1,2,m", 0, v8 }, /* wr r,r,%asrX */
+{ "wr", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|RD_G0|ASI(~0),
"1,2,y", 0, v6 }, /* wr r,r,%y */
+{ "wr", F3(2, 0x30, 1), F3(~2, ~0x30, ~1),
"1,i,m", 0, v8 }, /* wr r,i,%asrX */
+{ "wr", F3(2, 0x30, 1), F3(~2, ~0x30, ~1)|RD_G0,
"1,i,y", 0, v6 }, /* wr r,i,%y */
+{ "wr", F3(2, 0x31, 0), F3(~2, ~0x31, ~0)|RD_G0|ASI(~0),
"1,2,p", 0, v6notv9 }, /* wr r,r,%psr */
+{ "wr", F3(2, 0x31, 1), F3(~2, ~0x31, ~1)|RD_G0,
"1,i,p", 0, v6notv9 }, /* wr r,i,%psr */
+{ "wr", F3(2, 0x32, 0), F3(~2, ~0x32, ~0)|RD_G0|ASI(~0),
"1,2,w", 0, v6notv9 }, /* wr r,r,%wim */
+{ "wr", F3(2, 0x32, 1), F3(~2, ~0x32, ~1)|RD_G0,
"1,i,w", 0, v6notv9 }, /* wr r,i,%wim */
+{ "wr", F3(2, 0x33, 0), F3(~2, ~0x33, ~0)|RD_G0|ASI(~0),
"1,2,t", 0, v6notv9 }, /* wr r,r,%tbr */
+{ "wr", F3(2, 0x33, 1), F3(~2, ~0x33, ~1)|RD_G0,
"1,i,t", 0, v6notv9 }, /* wr r,i,%tbr */
+
+{ "wr", F3(2, 0x30, 0)|RD(2), F3(~2, ~0x30, ~0)|RD(~2)|ASI(~0),
"1,2,E", 0, v9 }, /* wr r,r,%ccr */
+{ "wr", F3(2, 0x30, 1)|RD(2), F3(~2, ~0x30, ~1)|RD(~2),
"1,i,E", 0, v9 }, /* wr r,i,%ccr */
+{ "wr", F3(2, 0x30, 0)|RD(3), F3(~2, ~0x30, ~0)|RD(~3)|ASI(~0),
"1,2,o", 0, v9 }, /* wr r,r,%asi */
+{ "wr", F3(2, 0x30, 1)|RD(3), F3(~2, ~0x30, ~1)|RD(~3),
"1,i,o", 0, v9 }, /* wr r,i,%asi */
+{ "wr", F3(2, 0x30, 0)|RD(6), F3(~2, ~0x30, ~0)|RD(~6)|ASI(~0),
"1,2,s", 0, v9 }, /* wr r,i,%fprs */
+{ "wr", F3(2, 0x30, 1)|RD(6), F3(~2, ~0x30, ~1)|RD(~6),
"1,i,s", 0, v9 }, /* wr r,i,%fprs */
+
+{ "rd", F3(2, 0x28, 0), F3(~2, ~0x28, ~0)|SIMM13(~0),
"M,d", 0, v8 }, /* rd %asrX,r */
+{ "rd", F3(2, 0x28, 0), F3(~2, ~0x28,
~0)|RS1_G0|SIMM13(~0), "y,d", 0, v6 }, /* rd %y,r */
+{ "rd", F3(2, 0x29, 0), F3(~2, ~0x29,
~0)|RS1_G0|SIMM13(~0), "p,d", 0, v6notv9 }, /* rd %psr,r */
+{ "rd", F3(2, 0x2a, 0), F3(~2, ~0x2a,
~0)|RS1_G0|SIMM13(~0), "w,d", 0, v6notv9 }, /* rd %wim,r */
+{ "rd", F3(2, 0x2b, 0), F3(~2, ~0x2b,
~0)|RS1_G0|SIMM13(~0), "t,d", 0, v6notv9 }, /* rd %tbr,r */
+
+{ "rd", F3(2, 0x28, 0)|RS1(2), F3(~2, ~0x28,
~0)|RS1(~2)|SIMM13(~0), "E,d", 0, v9 }, /* rd %ccr,r */
+{ "rd", F3(2, 0x28, 0)|RS1(3), F3(~2, ~0x28,
~0)|RS1(~3)|SIMM13(~0), "o,d", 0, v9 }, /* rd %asi,r */
+{ "rd", F3(2, 0x28, 0)|RS1(4), F3(~2, ~0x28,
~0)|RS1(~4)|SIMM13(~0), "W,d", 0, v9 }, /* rd %tick,r */
+{ "rd", F3(2, 0x28, 0)|RS1(5), F3(~2, ~0x28,
~0)|RS1(~5)|SIMM13(~0), "P,d", 0, v9 }, /* rd %pc,r */
+{ "rd", F3(2, 0x28, 0)|RS1(6), F3(~2, ~0x28,
~0)|RS1(~6)|SIMM13(~0), "s,d", 0, v9 }, /* rd %fprs,r */
+
+{ "rdpr", F3(2, 0x2a, 0), F3(~2, ~0x2a, ~0)|SIMM13(~0), "?,d",
0, v9 }, /* rdpr %priv,r */
+{ "wrpr", F3(2, 0x32, 0), F3(~2, ~0x32, ~0),
"1,2,!", 0, v9 }, /* wrpr r1,r2,%priv */
+{ "wrpr", F3(2, 0x32, 0), F3(~2, ~0x32, ~0)|SIMM13(~0), "1,!",
0, v9 }, /* wrpr r1,%priv */
+{ "wrpr", F3(2, 0x32, 1), F3(~2, ~0x32, ~1),
"1,i,!", 0, v9 }, /* wrpr r1,i,%priv */
+{ "wrpr", F3(2, 0x32, 1), F3(~2, ~0x32, ~1),
"i,1,!", F_ALIAS, v9 }, /* wrpr i,r1,%priv */
+{ "wrpr", F3(2, 0x32, 1), F3(~2, ~0x32, ~1)|RS1(~0), "i,!",
0, v9 }, /* wrpr i,%priv */
+
+{ "mov", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|ASI(~0),
"1,2,m", F_ALIAS, v8 }, /* wr r,r,%asrX */
+{ "mov", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|RD_G0|ASI(~0),
"1,2,y", F_ALIAS, v6 }, /* wr r,r,%y */
+{ "mov", F3(2, 0x30, 1), F3(~2, ~0x30, ~1),
"1,i,m", F_ALIAS, v8 }, /* wr r,i,%asrX */
+{ "mov", F3(2, 0x30, 1), F3(~2, ~0x30, ~1)|RD_G0,
"1,i,y", F_ALIAS, v6 }, /* wr r,i,%y */
+{ "mov", F3(2, 0x31, 0), F3(~2, ~0x31, ~0)|RD_G0|ASI(~0),
"1,2,p", F_ALIAS, v6notv9 }, /* wr r,r,%psr */
+{ "mov", F3(2, 0x31, 1), F3(~2, ~0x31, ~1)|RD_G0,
"1,i,p", F_ALIAS, v6notv9 }, /* wr r,i,%psr */
+{ "mov", F3(2, 0x32, 0), F3(~2, ~0x32, ~0)|RD_G0|ASI(~0),
"1,2,w", F_ALIAS, v6notv9 }, /* wr r,r,%wim */
+{ "mov", F3(2, 0x32, 1), F3(~2, ~0x32, ~1)|RD_G0,
"1,i,w", F_ALIAS, v6notv9 }, /* wr r,i,%wim */
+{ "mov", F3(2, 0x33, 0), F3(~2, ~0x33, ~0)|RD_G0|ASI(~0),
"1,2,t", F_ALIAS, v6notv9 }, /* wr r,r,%tbr */
+{ "mov", F3(2, 0x33, 1), F3(~2, ~0x33, ~1)|RD_G0,
"1,i,t", F_ALIAS, v6notv9 }, /* wr r,i,%tbr */
+
+{ "mov", F3(2, 0x28, 0), F3(~2, ~0x28, ~0)|SIMM13(~0),
"M,d", F_ALIAS, v8 }, /* rd %asr1,r */
+{ "mov", F3(2, 0x28, 0), F3(~2, ~0x28, ~0)|RS1_G0|SIMM13(~0),
"y,d", F_ALIAS, v6 }, /* rd %y,r */
+{ "mov", F3(2, 0x29, 0), F3(~2, ~0x29, ~0)|RS1_G0|SIMM13(~0),
"p,d", F_ALIAS, v6notv9 }, /* rd %psr,r */
+{ "mov", F3(2, 0x2a, 0), F3(~2, ~0x2a, ~0)|RS1_G0|SIMM13(~0),
"w,d", F_ALIAS, v6notv9 }, /* rd %wim,r */
+{ "mov", F3(2, 0x2b, 0), F3(~2, ~0x2b, ~0)|RS1_G0|SIMM13(~0),
"t,d", F_ALIAS, v6notv9 }, /* rd %tbr,r */
+
+{ "mov", F3(2, 0x30, 0), F3(~2, ~0x30, ~0)|ASI_RS2(~0), "1,y", F_ALIAS,
v6 }, /* wr rs1,%g0,%y */
+{ "mov", F3(2, 0x30, 1), F3(~2, ~0x30, ~1), "i,y", F_ALIAS,
v6 }, /* wr %g0,i,%y */
+{ "mov", F3(2, 0x30, 1), F3(~2, ~0x30, ~1)|SIMM13(~0), "1,y", F_ALIAS,
v6 }, /* wr rs1,0,%y */
+{ "mov", F3(2, 0x31, 0), F3(~2, ~0x31, ~0)|ASI_RS2(~0), "1,p", F_ALIAS,
v6notv9 }, /* wr rs1,%g0,%psr */
+{ "mov", F3(2, 0x31, 1), F3(~2, ~0x31, ~1), "i,p", F_ALIAS,
v6notv9 }, /* wr %g0,i,%psr */
+{ "mov", F3(2, 0x31, 1), F3(~2, ~0x31, ~1)|SIMM13(~0), "1,p", F_ALIAS,
v6notv9 }, /* wr rs1,0,%psr */
+{ "mov", F3(2, 0x32, 0), F3(~2, ~0x32, ~0)|ASI_RS2(~0), "1,w", F_ALIAS,
v6notv9 }, /* wr rs1,%g0,%wim */
+{ "mov", F3(2, 0x32, 1), F3(~2, ~0x32, ~1), "i,w", F_ALIAS,
v6notv9 }, /* wr %g0,i,%wim */
+{ "mov", F3(2, 0x32, 1), F3(~2, ~0x32, ~1)|SIMM13(~0), "1,w", F_ALIAS,
v6notv9 }, /* wr rs1,0,%wim */
+{ "mov", F3(2, 0x33, 0), F3(~2, ~0x33, ~0)|ASI_RS2(~0), "1,t", F_ALIAS,
v6notv9 }, /* wr rs1,%g0,%tbr */
+{ "mov", F3(2, 0x33, 1), F3(~2, ~0x33, ~1), "i,t", F_ALIAS,
v6notv9 }, /* wr %g0,i,%tbr */
+{ "mov", F3(2, 0x33, 1), F3(~2, ~0x33, ~1)|SIMM13(~0), "1,t", F_ALIAS,
v6notv9 }, /* wr rs1,0,%tbr */
+
+{ "mov", F3(2, 0x02, 0), F3(~2, ~0x02, ~0)|RS1_G0|ASI(~0), "2,d",
0, v6 }, /* or %g0,rs2,d */
+{ "mov", F3(2, 0x02, 1), F3(~2, ~0x02, ~1)|RS1_G0, "i,d",
0, v6 }, /* or %g0,i,d */
+{ "mov", F3(2, 0x02, 0), F3(~2, ~0x02, ~0)|ASI_RS2(~0), "1,d",
0, v6 }, /* or rs1,%g0,d */
+{ "mov", F3(2, 0x02, 1), F3(~2, ~0x02, ~1)|SIMM13(~0), "1,d",
0, v6 }, /* or rs1,0,d */
+
+{ "or", F3(2, 0x02, 0), F3(~2, ~0x02, ~0)|ASI(~0), "1,2,d", 0, v6
},
+{ "or", F3(2, 0x02, 1), F3(~2, ~0x02, ~1), "1,i,d", 0, v6
},
+{ "or", F3(2, 0x02, 1), F3(~2, ~0x02, ~1), "i,1,d", 0, v6
},
+
+{ "bset", F3(2, 0x02, 0), F3(~2, ~0x02, ~0)|ASI(~0), "2,r", F_ALIAS,
v6 }, /* or rd,rs2,rd */
+{ "bset", F3(2, 0x02, 1), F3(~2, ~0x02, ~1), "i,r", F_ALIAS,
v6 }, /* or rd,i,rd */
+
+/* This is not a commutative instruction. */
+{ "andn", F3(2, 0x05, 0), F3(~2, ~0x05, ~0)|ASI(~0), "1,2,d", 0, v6
},
+{ "andn", F3(2, 0x05, 1), F3(~2, ~0x05, ~1), "1,i,d", 0, v6
},
+
+/* This is not a commutative instruction. */
+{ "andncc", F3(2, 0x15, 0), F3(~2, ~0x15, ~0)|ASI(~0), "1,2,d", 0, v6
},
+{ "andncc", F3(2, 0x15, 1), F3(~2, ~0x15, ~1), "1,i,d", 0, v6
},
+
+{ "bclr", F3(2, 0x05, 0), F3(~2, ~0x05, ~0)|ASI(~0), "2,r", F_ALIAS,
v6 }, /* andn rd,rs2,rd */
+{ "bclr", F3(2, 0x05, 1), F3(~2, ~0x05, ~1), "i,r", F_ALIAS,
v6 }, /* andn rd,i,rd */
+
+{ "cmp", F3(2, 0x14, 0), F3(~2, ~0x14, ~0)|RD_G0|ASI(~0), "1,2",
0, v6 }, /* subcc rs1,rs2,%g0 */
+{ "cmp", F3(2, 0x14, 1), F3(~2, ~0x14, ~1)|RD_G0, "1,i",
0, v6 }, /* subcc rs1,i,%g0 */
+
+{ "sub", F3(2, 0x04, 0), F3(~2, ~0x04, ~0)|ASI(~0), "1,2,d", 0, v6
},
+{ "sub", F3(2, 0x04, 1), F3(~2, ~0x04, ~1), "1,i,d", 0, v6
},
+
+{ "subcc", F3(2, 0x14, 0), F3(~2, ~0x14, ~0)|ASI(~0), "1,2,d", 0, v6
},
+{ "subcc", F3(2, 0x14, 1), F3(~2, ~0x14, ~1), "1,i,d", 0, v6
},
+
+{ "subx", F3(2, 0x0c, 0), F3(~2, ~0x0c, ~0)|ASI(~0), "1,2,d", 0,
v6notv9 },
+{ "subx", F3(2, 0x0c, 1), F3(~2, ~0x0c, ~1), "1,i,d", 0,
v6notv9 },
+{ "subc", F3(2, 0x0c, 0), F3(~2, ~0x0c, ~0)|ASI(~0), "1,2,d", 0, v9
},
+{ "subc", F3(2, 0x0c, 1), F3(~2, ~0x0c, ~1), "1,i,d", 0, v9
},
+
+{ "subxcc", F3(2, 0x1c, 0), F3(~2, ~0x1c, ~0)|ASI(~0), "1,2,d", 0,
v6notv9 },
+{ "subxcc", F3(2, 0x1c, 1), F3(~2, ~0x1c, ~1), "1,i,d", 0,
v6notv9 },
+{ "subccc", F3(2, 0x1c, 0), F3(~2, ~0x1c, ~0)|ASI(~0), "1,2,d", 0, v9
},
+{ "subccc", F3(2, 0x1c, 1), F3(~2, ~0x1c, ~1), "1,i,d", 0, v9
},
+
+{ "and", F3(2, 0x01, 0), F3(~2, ~0x01, ~0)|ASI(~0), "1,2,d", 0, v6
},
+{ "and", F3(2, 0x01, 1), F3(~2, ~0x01, ~1), "1,i,d", 0, v6
},
+{ "and", F3(2, 0x01, 1), F3(~2, ~0x01, ~1), "i,1,d", 0, v6
},
+
+{ "andcc", F3(2, 0x11, 0), F3(~2, ~0x11, ~0)|ASI(~0), "1,2,d", 0, v6
},
+{ "andcc", F3(2, 0x11, 1), F3(~2, ~0x11, ~1), "1,i,d", 0, v6
},
+{ "andcc", F3(2, 0x11, 1), F3(~2, ~0x11, ~1), "i,1,d", 0, v6
},
+
+{ "dec", F3(2, 0x04, 1)|SIMM13(0x1), F3(~2, ~0x04, ~1)|SIMM13(~0x0001),
"r", F_ALIAS, v6 }, /* sub rd,1,rd */
+{ "dec", F3(2, 0x04, 1), F3(~2, ~0x04, ~1),
"i,r", F_ALIAS, v8 }, /* sub rd,imm,rd */
+{ "deccc", F3(2, 0x14, 1)|SIMM13(0x1), F3(~2, ~0x14, ~1)|SIMM13(~0x0001),
"r", F_ALIAS, v6 }, /* subcc rd,1,rd */
+{ "deccc", F3(2, 0x14, 1), F3(~2, ~0x14, ~1),
"i,r", F_ALIAS, v8 }, /* subcc rd,imm,rd */
+{ "inc", F3(2, 0x00, 1)|SIMM13(0x1), F3(~2, ~0x00, ~1)|SIMM13(~0x0001),
"r", F_ALIAS, v6 }, /* add rd,1,rd */
+{ "inc", F3(2, 0x00, 1), F3(~2, ~0x00, ~1),
"i,r", F_ALIAS, v8 }, /* add rd,imm,rd */
+{ "inccc", F3(2, 0x10, 1)|SIMM13(0x1), F3(~2, ~0x10, ~1)|SIMM13(~0x0001),
"r", F_ALIAS, v6 }, /* addcc rd,1,rd */
+{ "inccc", F3(2, 0x10, 1), F3(~2, ~0x10, ~1),
"i,r", F_ALIAS, v8 }, /* addcc rd,imm,rd */
+
+{ "btst", F3(2, 0x11, 0), F3(~2, ~0x11, ~0)|RD_G0|ASI(~0), "1,2",
F_ALIAS, v6 }, /* andcc rs1,rs2,%g0 */
+{ "btst", F3(2, 0x11, 1), F3(~2, ~0x11, ~1)|RD_G0, "i,1", F_ALIAS, v6 },
/* andcc rs1,i,%g0 */
+
+{ "neg", F3(2, 0x04, 0), F3(~2, ~0x04, ~0)|RS1_G0|ASI(~0), "2,d",
F_ALIAS, v6 }, /* sub %g0,rs2,rd */
+{ "neg", F3(2, 0x04, 0), F3(~2, ~0x04, ~0)|RS1_G0|ASI(~0), "O", F_ALIAS,
v6 }, /* sub %g0,rd,rd */
+
+{ "add", F3(2, 0x00, 0), F3(~2, ~0x00, ~0)|ASI(~0), "1,2,d", 0, v6
},
+{ "add", F3(2, 0x00, 1), F3(~2, ~0x00, ~1), "1,i,d", 0, v6
},
+{ "add", F3(2, 0x00, 1), F3(~2, ~0x00, ~1), "i,1,d", 0, v6
},
+{ "addcc", F3(2, 0x10, 0), F3(~2, ~0x10, ~0)|ASI(~0), "1,2,d", 0, v6
},
+{ "addcc", F3(2, 0x10, 1), F3(~2, ~0x10, ~1), "1,i,d", 0, v6
},
+{ "addcc", F3(2, 0x10, 1), F3(~2, ~0x10, ~1), "i,1,d", 0, v6
},
+
+{ "addx", F3(2, 0x08, 0), F3(~2, ~0x08, ~0)|ASI(~0), "1,2,d", 0,
v6notv9 },
+{ "addx", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "1,i,d", 0,
v6notv9 },
+{ "addx", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "i,1,d", 0,
v6notv9 },
+{ "addc", F3(2, 0x08, 0), F3(~2, ~0x08, ~0)|ASI(~0), "1,2,d", 0, v9
},
+{ "addc", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "1,i,d", 0, v9
},
+{ "addc", F3(2, 0x08, 1), F3(~2, ~0x08, ~1), "i,1,d", 0, v9
},
+
+{ "addxcc", F3(2, 0x18, 0), F3(~2, ~0x18, ~0)|ASI(~0), "1,2,d", 0,
v6notv9 },
+{ "addxcc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "1,i,d", 0,
v6notv9 },
+{ "addxcc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "i,1,d", 0,
v6notv9 },
+{ "addccc", F3(2, 0x18, 0), F3(~2, ~0x18, ~0)|ASI(~0), "1,2,d", 0, v9
},
+{ "addccc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "1,i,d", 0, v9
},
+{ "addccc", F3(2, 0x18, 1), F3(~2, ~0x18, ~1), "i,1,d", 0, v9
},
+
+{ "smul", F3(2, 0x0b, 0), F3(~2, ~0x0b, ~0)|ASI(~0), "1,2,d", 0, v8
},
+{ "smul", F3(2, 0x0b, 1), F3(~2, ~0x0b, ~1), "1,i,d", 0, v8
},
+{ "smul", F3(2, 0x0b, 1), F3(~2, ~0x0b, ~1), "i,1,d", 0, v8
},
+{ "smulcc", F3(2, 0x1b, 0), F3(~2, ~0x1b, ~0)|ASI(~0), "1,2,d", 0, v8
},
+{ "smulcc", F3(2, 0x1b, 1), F3(~2, ~0x1b, ~1), "1,i,d", 0, v8
},
+{ "smulcc", F3(2, 0x1b, 1), F3(~2, ~0x1b, ~1), "i,1,d", 0, v8
},
+{ "umul", F3(2, 0x0a, 0), F3(~2, ~0x0a, ~0)|ASI(~0), "1,2,d", 0, v8
},
+{ "umul", F3(2, 0x0a, 1), F3(~2, ~0x0a, ~1), "1,i,d", 0, v8
},
+{ "umul", F3(2, 0x0a, 1), F3(~2, ~0x0a, ~1), "i,1,d", 0, v8
},
+{ "umulcc", F3(2, 0x1a, 0), F3(~2, ~0x1a, ~0)|ASI(~0), "1,2,d", 0, v8
},
+{ "umulcc", F3(2, 0x1a, 1), F3(~2, ~0x1a, ~1), "1,i,d", 0, v8
},
+{ "umulcc", F3(2, 0x1a, 1), F3(~2, ~0x1a, ~1), "i,1,d", 0, v8
},
+{ "sdiv", F3(2, 0x0f, 0), F3(~2, ~0x0f, ~0)|ASI(~0), "1,2,d", 0, v8
},
+{ "sdiv", F3(2, 0x0f, 1), F3(~2, ~0x0f, ~1), "1,i,d", 0, v8
},
+{ "sdiv", F3(2, 0x0f, 1), F3(~2, ~0x0f, ~1), "i,1,d", 0, v8
},
+{ "sdivcc", F3(2, 0x1f, 0), F3(~2, ~0x1f, ~0)|ASI(~0), "1,2,d", 0, v8
},
+{ "sdivcc", F3(2, 0x1f, 1), F3(~2, ~0x1f, ~1), "1,i,d", 0, v8
},
+{ "sdivcc", F3(2, 0x1f, 1), F3(~2, ~0x1f, ~1), "i,1,d", 0, v8
},
+{ "udiv", F3(2, 0x0e, 0), F3(~2, ~0x0e, ~0)|ASI(~0), "1,2,d", 0, v8
},
+{ "udiv", F3(2, 0x0e, 1), F3(~2, ~0x0e, ~1), "1,i,d", 0, v8
},
+{ "udiv", F3(2, 0x0e, 1), F3(~2, ~0x0e, ~1), "i,1,d", 0, v8
},
+{ "udivcc", F3(2, 0x1e, 0), F3(~2, ~0x1e, ~0)|ASI(~0), "1,2,d", 0, v8
},
+{ "udivcc", F3(2, 0x1e, 1), F3(~2, ~0x1e, ~1), "1,i,d", 0, v8
},
+{ "udivcc", F3(2, 0x1e, 1), F3(~2, ~0x1e, ~1), "i,1,d", 0, v8
},
+
+{ "mulx", F3(2, 0x09, 0), F3(~2, ~0x09, ~0)|ASI(~0), "1,2,d", 0, v9
},
+{ "mulx", F3(2, 0x09, 1), F3(~2, ~0x09, ~1), "1,i,d", 0, v9
},
+{ "sdivx", F3(2, 0x2d, 0), F3(~2, ~0x2d, ~0)|ASI(~0), "1,2,d", 0, v9
},
+{ "sdivx", F3(2, 0x2d, 1), F3(~2, ~0x2d, ~1), "1,i,d", 0, v9
},
+{ "udivx", F3(2, 0x0d, 0), F3(~2, ~0x0d, ~0)|ASI(~0), "1,2,d", 0, v9
},
+{ "udivx", F3(2, 0x0d, 1), F3(~2, ~0x0d, ~1), "1,i,d", 0, v9
},
+
+{ "call", F1(0x1), F1(~0x1), "L", F_JSR|F_DELAYED, v6 },
+{ "call", F1(0x1), F1(~0x1), "L,#", F_JSR|F_DELAYED, v6 },
+
+{ "call", F3(2, 0x38, 0)|RD(0xf), F3(~2, ~0x38, ~0)|RD(~0xf)|ASI(~0),
"1+2", F_JSR|F_DELAYED, v6 }, /* jmpl rs1+rs2,%o7 */
+{ "call", F3(2, 0x38, 0)|RD(0xf), F3(~2, ~0x38, ~0)|RD(~0xf)|ASI(~0),
"1+2,#", F_JSR|F_DELAYED, v6 },
+{ "call", F3(2, 0x38, 0)|RD(0xf), F3(~2, ~0x38, ~0)|RD(~0xf)|ASI_RS2(~0),
"1", F_JSR|F_DELAYED, v6 }, /* jmpl rs1+%g0,%o7 */
+{ "call", F3(2, 0x38, 0)|RD(0xf), F3(~2, ~0x38, ~0)|RD(~0xf)|ASI_RS2(~0),
"1,#", F_JSR|F_DELAYED, v6 },
+{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf),
"1+i", F_JSR|F_DELAYED, v6 }, /* jmpl rs1+i,%o7 */
+{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf),
"1+i,#", F_JSR|F_DELAYED, v6 },
+{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf),
"i+1", F_JSR|F_DELAYED, v6 }, /* jmpl i+rs1,%o7 */
+{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf),
"i+1,#", F_JSR|F_DELAYED, v6 },
+{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf)|RS1_G0,
"i", F_JSR|F_DELAYED, v6 }, /* jmpl %g0+i,%o7 */
+{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf)|RS1_G0,
"i,#", F_JSR|F_DELAYED, v6 },
+{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf)|SIMM13(~0),
"1", F_JSR|F_DELAYED, v6 }, /* jmpl rs1+0,%o7 */
+{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf)|SIMM13(~0),
"1,#", F_JSR|F_DELAYED, v6 },
+
+
+/* Conditional instructions.
+
+ Because this part of the table was such a mess earlier, I have
+ macrofied it so that all the branches and traps are generated from
+ a single-line description of each condition value. John Gilmore. */
+
+/* Define branches -- one annulled, one without, etc. */
+#define br(opcode, mask, lose, flags) \
+ { opcode, (mask)|ANNUL, (lose), ",a l", (flags), v6 }, \
+ { opcode, (mask) , (lose)|ANNUL, "l", (flags), v6 }
+
+#define brx(opcode, mask, lose, flags) /* v9 */ \
+ { opcode, (mask)|(2<<20)|BPRED, ANNUL|(lose), "Z,G", (flags), v9 }, \
+ { opcode, (mask)|(2<<20)|BPRED, ANNUL|(lose), ",T Z,G", (flags), v9 }, \
+ { opcode, (mask)|(2<<20)|BPRED|ANNUL, (lose), ",a Z,G", (flags), v9 }, \
+ { opcode, (mask)|(2<<20)|BPRED|ANNUL, (lose), ",a,T Z,G", (flags), v9 }, \
+ { opcode, (mask)|(2<<20), ANNUL|BPRED|(lose), ",N Z,G", (flags), v9 }, \
+ { opcode, (mask)|(2<<20)|ANNUL, BPRED|(lose), ",a,N Z,G", (flags), v9 }, \
+ { opcode, (mask)|BPRED, ANNUL|(lose)|(2<<20), "z,G", (flags), v9 }, \
+ { opcode, (mask)|BPRED, ANNUL|(lose)|(2<<20), ",T z,G", (flags), v9 }, \
+ { opcode, (mask)|BPRED|ANNUL, (lose)|(2<<20), ",a z,G", (flags), v9 }, \
+ { opcode, (mask)|BPRED|ANNUL, (lose)|(2<<20), ",a,T z,G", (flags), v9 }, \
+ { opcode, (mask), ANNUL|BPRED|(lose)|(2<<20), ",N z,G", (flags), v9 }, \
+ { opcode, (mask)|ANNUL, BPRED|(lose)|(2<<20), ",a,N z,G", (flags), v9 }
+
+/* Define four traps: reg+reg, reg + immediate, immediate alone, reg alone. */
+#define tr(opcode, mask, lose, flags) \
+ { opcode, (mask)|(2<<11)|IMMED, (lose)|RS1_G0, "Z,i", (flags), v9 },
/* %g0 + imm */ \
+ { opcode, (mask)|(2<<11)|IMMED, (lose), "Z,1+i", (flags), v9 }, /* rs1
+ imm */ \
+ { opcode, (mask)|(2<<11), IMMED|(lose), "Z,1+2", (flags), v9 }, /* rs1
+ rs2 */ \
+ { opcode, (mask)|(2<<11), IMMED|(lose)|RS2_G0, "Z,1", (flags), v9 },
/* rs1 + %g0 */ \
+ { opcode, (mask)|IMMED, (lose)|RS1_G0, "z,i", (flags)|F_ALIAS, v9 },
/* %g0 + imm */ \
+ { opcode, (mask)|IMMED, (lose), "z,1+i", (flags)|F_ALIAS, v9 }, /* rs1
+ imm */ \
+ { opcode, (mask), IMMED|(lose), "z,1+2", (flags)|F_ALIAS, v9 }, /* rs1
+ rs2 */ \
+ { opcode, (mask), IMMED|(lose)|RS2_G0, "z,1", (flags)|F_ALIAS, v9 },
/* rs1 + %g0 */ \
+ { opcode, (mask)|IMMED, (lose)|RS1_G0, "i", (flags), v6 },
/* %g0 + imm */ \
+ { opcode, (mask)|IMMED, (lose), "1+i", (flags), v6 }, /* rs1
+ imm */ \
+ { opcode, (mask), IMMED|(lose), "1+2", (flags), v6 }, /* rs1
+ rs2 */ \
+ { opcode, (mask), IMMED|(lose)|RS2_G0, "1", (flags), v6 }
/* rs1 + %g0 */
+
+/* v9: We must put `brx' before `br', to ensure that we never match something
+ v9: against an expression unless it is an expression. Otherwise, we end
+ v9: up with undefined symbol tables entries, because they get added, but
+ v9: are not deleted if the pattern fails to match. */
+
+/* Define both branches and traps based on condition mask */
+#define cond(bop, top, mask, flags) \
+ brx(bop, F2(0, 1)|(mask), F2(~0, ~1)|((~mask)&COND(~0)), F_DELAYED|(flags)),
/* v9 */ \
+ br(bop, F2(0, 2)|(mask), F2(~0, ~2)|((~mask)&COND(~0)), F_DELAYED|(flags)),
\
+ tr(top, F3(2, 0x3a, 0)|(mask), F3(~2, ~0x3a, 0)|((~mask)&COND(~0)),
((flags) & ~(F_UNBR|F_CONDBR)))
+
+/* Define all the conditions, all the branches, all the traps. */
+
+/* Standard branch, trap mnemonics */
+cond ("b", "ta", CONDA, F_UNBR),
+/* Alternative form (just for assembly, not for disassembly) */
+cond ("ba", "t", CONDA, F_UNBR|F_ALIAS),
+
+cond ("bcc", "tcc", CONDCC, F_CONDBR),
+cond ("bcs", "tcs", CONDCS, F_CONDBR),
+cond ("be", "te", CONDE, F_CONDBR),
+cond ("bg", "tg", CONDG, F_CONDBR),
+cond ("bgt", "tgt", CONDG, F_CONDBR|F_ALIAS),
+cond ("bge", "tge", CONDGE, F_CONDBR),
+cond ("bgeu", "tgeu", CONDGEU, F_CONDBR|F_ALIAS), /* for cc */
+cond ("bgu", "tgu", CONDGU, F_CONDBR),
+cond ("bl", "tl", CONDL, F_CONDBR),
+cond ("blt", "tlt", CONDL, F_CONDBR|F_ALIAS),
+cond ("ble", "tle", CONDLE, F_CONDBR),
+cond ("bleu", "tleu", CONDLEU, F_CONDBR),
+cond ("blu", "tlu", CONDLU, F_CONDBR|F_ALIAS), /* for cs */
+cond ("bn", "tn", CONDN, F_CONDBR),
+cond ("bne", "tne", CONDNE, F_CONDBR),
+cond ("bneg", "tneg", CONDNEG, F_CONDBR),
+cond ("bnz", "tnz", CONDNZ, F_CONDBR|F_ALIAS), /* for ne */
+cond ("bpos", "tpos", CONDPOS, F_CONDBR),
+cond ("bvc", "tvc", CONDVC, F_CONDBR),
+cond ("bvs", "tvs", CONDVS, F_CONDBR),
+cond ("bz", "tz", CONDZ, F_CONDBR|F_ALIAS), /* for e */
+
+#undef cond
+#undef br
+#undef brr /* v9 */
+#undef tr
+
+#define brr(opcode, mask, lose, flags) /* v9 */ \
+ { opcode, (mask)|BPRED, ANNUL|(lose), "1,k", F_DELAYED|(flags), v9 }, \
+ { opcode, (mask)|BPRED, ANNUL|(lose), ",T 1,k", F_DELAYED|(flags), v9 }, \
+ { opcode, (mask)|BPRED|ANNUL, (lose), ",a 1,k", F_DELAYED|(flags), v9 }, \
+ { opcode, (mask)|BPRED|ANNUL, (lose), ",a,T 1,k", F_DELAYED|(flags), v9 }, \
+ { opcode, (mask), ANNUL|BPRED|(lose), ",N 1,k", F_DELAYED|(flags), v9 }, \
+ { opcode, (mask)|ANNUL, BPRED|(lose), ",a,N 1,k", F_DELAYED|(flags), v9 }
+
+#define condr(bop, mask, flags) /* v9 */ \
+ brr(bop, F2(0, 3)|COND(mask), F2(~0, ~3)|COND(~(mask)), (flags)) /* v9 */
+
+/* v9 */ condr("brnz", 0x5, F_CONDBR),
+/* v9 */ condr("brz", 0x1, F_CONDBR),
+/* v9 */ condr("brgez", 0x7, F_CONDBR),
+/* v9 */ condr("brlz", 0x3, F_CONDBR),
+/* v9 */ condr("brlez", 0x2, F_CONDBR),
+/* v9 */ condr("brgz", 0x6, F_CONDBR),
+
+#undef condr /* v9 */
+#undef brr /* v9 */
+
+#define movr(opcode, mask, flags) /* v9 */ \
+ { opcode, F3(2, 0x2f, 0)|RCOND(mask), F3(~2, ~0x2f, ~0)|RCOND(~(mask)),
"1,2,d", (flags), v9 }, \
+ { opcode, F3(2, 0x2f, 1)|RCOND(mask), F3(~2, ~0x2f, ~1)|RCOND(~(mask)),
"1,j,d", (flags), v9 }
+
+#define fmrrs(opcode, mask, lose, flags) /* v9 */ \
+ { opcode, (mask), (lose), "1,f,g", (flags), v9 }
+#define fmrrd(opcode, mask, lose, flags) /* v9 */ \
+ { opcode, (mask), (lose), "1,B,H", (flags), v9 }
+#define fmrrq(opcode, mask, lose, flags) /* v9 */ \
+ { opcode, (mask), (lose), "1,R,J", (flags), v9 }
+
+#define fmovrs(mop, mask, flags) /* v9 */ \
+ fmrrs(mop, F3(2, 0x35, 0)|OPF_LOW5(5)|RCOND(mask), F3(~2, ~0x35,
0)|OPF_LOW5(~5)|RCOND(~(mask)), (flags)) /* v9 */
+#define fmovrd(mop, mask, flags) /* v9 */ \
+ fmrrd(mop, F3(2, 0x35, 0)|OPF_LOW5(6)|RCOND(mask), F3(~2, ~0x35,
0)|OPF_LOW5(~6)|RCOND(~(mask)), (flags)) /* v9 */
+#define fmovrq(mop, mask, flags) /* v9 */ \
+ fmrrq(mop, F3(2, 0x35, 0)|OPF_LOW5(7)|RCOND(mask), F3(~2, ~0x35,
0)|OPF_LOW5(~7)|RCOND(~(mask)), (flags)) /* v9 */
+
+/* v9 */ movr("movrne", 0x5, 0),
+/* v9 */ movr("movre", 0x1, 0),
+/* v9 */ movr("movrgez", 0x7, 0),
+/* v9 */ movr("movrlz", 0x3, 0),
+/* v9 */ movr("movrlez", 0x2, 0),
+/* v9 */ movr("movrgz", 0x6, 0),
+/* v9 */ movr("movrnz", 0x5, F_ALIAS),
+/* v9 */ movr("movrz", 0x1, F_ALIAS),
+
+/* v9 */ fmovrs("fmovrsne", 0x5, 0),
+/* v9 */ fmovrs("fmovrse", 0x1, 0),
+/* v9 */ fmovrs("fmovrsgez", 0x7, 0),
+/* v9 */ fmovrs("fmovrslz", 0x3, 0),
+/* v9 */ fmovrs("fmovrslez", 0x2, 0),
+/* v9 */ fmovrs("fmovrsgz", 0x6, 0),
+/* v9 */ fmovrs("fmovrsnz", 0x5, F_ALIAS),
+/* v9 */ fmovrs("fmovrsz", 0x1, F_ALIAS),
+
+/* v9 */ fmovrd("fmovrdne", 0x5, 0),
+/* v9 */ fmovrd("fmovrde", 0x1, 0),
+/* v9 */ fmovrd("fmovrdgez", 0x7, 0),
+/* v9 */ fmovrd("fmovrdlz", 0x3, 0),
+/* v9 */ fmovrd("fmovrdlez", 0x2, 0),
+/* v9 */ fmovrd("fmovrdgz", 0x6, 0),
+/* v9 */ fmovrd("fmovrdnz", 0x5, F_ALIAS),
+/* v9 */ fmovrd("fmovrdz", 0x1, F_ALIAS),
+
+/* v9 */ fmovrq("fmovrqne", 0x5, 0),
+/* v9 */ fmovrq("fmovrqe", 0x1, 0),
+/* v9 */ fmovrq("fmovrqgez", 0x7, 0),
+/* v9 */ fmovrq("fmovrqlz", 0x3, 0),
+/* v9 */ fmovrq("fmovrqlez", 0x2, 0),
+/* v9 */ fmovrq("fmovrqgz", 0x6, 0),
+/* v9 */ fmovrq("fmovrqnz", 0x5, F_ALIAS),
+/* v9 */ fmovrq("fmovrqz", 0x1, F_ALIAS),
+
+#undef movr /* v9 */
+#undef fmovr /* v9 */
+#undef fmrr /* v9 */
+
+#define movicc(opcode, cond, flags) /* v9 */ \
+ { opcode, F3(2, 0x2c, 0)|MCOND(cond,1)|ICC, F3(~2, ~0x2c,
~0)|MCOND(~cond,~1)|XCC|(1<<11), "z,2,d", flags, v9 }, \
+ { opcode, F3(2, 0x2c, 1)|MCOND(cond,1)|ICC, F3(~2, ~0x2c,
~1)|MCOND(~cond,~1)|XCC|(1<<11), "z,I,d", flags, v9 }, \
+ { opcode, F3(2, 0x2c, 0)|MCOND(cond,1)|XCC, F3(~2, ~0x2c,
~0)|MCOND(~cond,~1)|(1<<11), "Z,2,d", flags, v9 }, \
+ { opcode, F3(2, 0x2c, 1)|MCOND(cond,1)|XCC, F3(~2, ~0x2c,
~1)|MCOND(~cond,~1)|(1<<11), "Z,I,d", flags, v9 }
+
+#define movfcc(opcode, fcond, flags) /* v9 */ \
+ { opcode, F3(2, 0x2c, 0)|FCC(0)|MCOND(fcond,0),
MCOND(~fcond,~0)|FCC(~0)|F3(~2, ~0x2c, ~0), "6,2,d", flags, v9 }, \
+ { opcode, F3(2, 0x2c, 1)|FCC(0)|MCOND(fcond,0),
MCOND(~fcond,~0)|FCC(~0)|F3(~2, ~0x2c, ~1), "6,I,d", flags, v9 }, \
+ { opcode, F3(2, 0x2c, 0)|FCC(1)|MCOND(fcond,0),
MCOND(~fcond,~0)|FCC(~1)|F3(~2, ~0x2c, ~0), "7,2,d", flags, v9 }, \
+ { opcode, F3(2, 0x2c, 1)|FCC(1)|MCOND(fcond,0),
MCOND(~fcond,~0)|FCC(~1)|F3(~2, ~0x2c, ~1), "7,I,d", flags, v9 }, \
+ { opcode, F3(2, 0x2c, 0)|FCC(2)|MCOND(fcond,0),
MCOND(~fcond,~0)|FCC(~2)|F3(~2, ~0x2c, ~0), "8,2,d", flags, v9 }, \
+ { opcode, F3(2, 0x2c, 1)|FCC(2)|MCOND(fcond,0),
MCOND(~fcond,~0)|FCC(~2)|F3(~2, ~0x2c, ~1), "8,I,d", flags, v9 }, \
+ { opcode, F3(2, 0x2c, 0)|FCC(3)|MCOND(fcond,0),
MCOND(~fcond,~0)|FCC(~3)|F3(~2, ~0x2c, ~0), "9,2,d", flags, v9 }, \
+ { opcode, F3(2, 0x2c, 1)|FCC(3)|MCOND(fcond,0),
MCOND(~fcond,~0)|FCC(~3)|F3(~2, ~0x2c, ~1), "9,I,d", flags, v9 }
+
+#define movcc(opcode, cond, fcond, flags) /* v9 */ \
+ movfcc (opcode, fcond, flags), /* v9 */ \
+ movicc (opcode, cond, flags) /* v9 */
+
+/* v9 */ movcc ("mova", CONDA, FCONDA, 0),
+/* v9 */ movicc ("movcc", CONDCC, 0),
+/* v9 */ movicc ("movgeu", CONDGEU, F_ALIAS),
+/* v9 */ movicc ("movcs", CONDCS, 0),
+/* v9 */ movicc ("movlu", CONDLU, F_ALIAS),
+/* v9 */ movcc ("move", CONDE, FCONDE, 0),
+/* v9 */ movcc ("movg", CONDG, FCONDG, 0),
+/* v9 */ movcc ("movge", CONDGE, FCONDGE, 0),
+/* v9 */ movicc ("movgu", CONDGU, 0),
+/* v9 */ movcc ("movl", CONDL, FCONDL, 0),
+/* v9 */ movcc ("movle", CONDLE, FCONDLE, 0),
+/* v9 */ movicc ("movleu", CONDLEU, 0),
+/* v9 */ movfcc ("movlg", FCONDLG, 0),
+/* v9 */ movcc ("movn", CONDN, FCONDN, 0),
+/* v9 */ movcc ("movne", CONDNE, FCONDNE, 0),
+/* v9 */ movicc ("movneg", CONDNEG, 0),
+/* v9 */ movcc ("movnz", CONDNZ, FCONDNZ, F_ALIAS),
+/* v9 */ movfcc ("movo", FCONDO, 0),
+/* v9 */ movicc ("movpos", CONDPOS, 0),
+/* v9 */ movfcc ("movu", FCONDU, 0),
+/* v9 */ movfcc ("movue", FCONDUE, 0),
+/* v9 */ movfcc ("movug", FCONDUG, 0),
+/* v9 */ movfcc ("movuge", FCONDUGE, 0),
+/* v9 */ movfcc ("movul", FCONDUL, 0),
+/* v9 */ movfcc ("movule", FCONDULE, 0),
+/* v9 */ movicc ("movvc", CONDVC, 0),
+/* v9 */ movicc ("movvs", CONDVS, 0),
+/* v9 */ movcc ("movz", CONDZ, FCONDZ, F_ALIAS),
+
+#undef movicc /* v9 */
+#undef movfcc /* v9 */
+#undef movcc /* v9 */
+
+#define FM_SF 1 /* v9 - values for fpsize */
+#define FM_DF 2 /* v9 */
+#define FM_QF 3 /* v9 */
+
+#define fmovicc(opcode, fpsize, cond, flags) /* v9 */ \
+{ opcode, F3F(2, 0x35, 0x100+fpsize)|MCOND(cond,0), F3F(~2, ~0x35,
~(0x100+fpsize))|MCOND(~cond,~0), "z,f,g", flags, v9 }, \
+{ opcode, F3F(2, 0x35, 0x180+fpsize)|MCOND(cond,0), F3F(~2, ~0x35,
~(0x180+fpsize))|MCOND(~cond,~0), "Z,f,g", flags, v9 }
+
+#define fmovfcc(opcode, fpsize, fcond, flags) /* v9 */ \
+{ opcode, F3F(2, 0x35, 0x000+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35,
~(0x000+fpsize))|MCOND(~fcond,~0), "6,f,g", flags, v9 }, \
+{ opcode, F3F(2, 0x35, 0x040+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35,
~(0x040+fpsize))|MCOND(~fcond,~0), "7,f,g", flags, v9 }, \
+{ opcode, F3F(2, 0x35, 0x080+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35,
~(0x080+fpsize))|MCOND(~fcond,~0), "8,f,g", flags, v9 }, \
+{ opcode, F3F(2, 0x35, 0x0c0+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35,
~(0x0c0+fpsize))|MCOND(~fcond,~0), "9,f,g", flags, v9 }
+
+/* FIXME: use fmovicc/fmovfcc? */ /* v9 */
+#define fmovcc(opcode, fpsize, cond, fcond, flags) /* v9 */ \
+{ opcode, F3F(2, 0x35, 0x100+fpsize)|MCOND(cond,0), F3F(~2, ~0x35,
~(0x100+fpsize))|MCOND(~cond,~0), "z,f,g", flags, v9 }, \
+{ opcode, F3F(2, 0x35, 0x000+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35,
~(0x000+fpsize))|MCOND(~fcond,~0), "6,f,g", flags, v9 }, \
+{ opcode, F3F(2, 0x35, 0x180+fpsize)|MCOND(cond,0), F3F(~2, ~0x35,
~(0x180+fpsize))|MCOND(~cond,~0), "Z,f,g", flags, v9 }, \
+{ opcode, F3F(2, 0x35, 0x040+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35,
~(0x040+fpsize))|MCOND(~fcond,~0), "7,f,g", flags, v9 }, \
+{ opcode, F3F(2, 0x35, 0x080+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35,
~(0x080+fpsize))|MCOND(~fcond,~0), "8,f,g", flags, v9 }, \
+{ opcode, F3F(2, 0x35, 0x0c0+fpsize)|MCOND(fcond,0), F3F(~2, ~0x35,
~(0x0c0+fpsize))|MCOND(~fcond,~0), "9,f,g", flags, v9 }
+
+/* v9 */ fmovcc ("fmovda", FM_DF, CONDA, FCONDA, 0),
+/* v9 */ fmovcc ("fmovqa", FM_QF, CONDA, FCONDA, 0),
+/* v9 */ fmovcc ("fmovsa", FM_SF, CONDA, FCONDA, 0),
+/* v9 */ fmovicc ("fmovdcc", FM_DF, CONDCC, 0),
+/* v9 */ fmovicc ("fmovqcc", FM_QF, CONDCC, 0),
+/* v9 */ fmovicc ("fmovscc", FM_SF, CONDCC, 0),
+/* v9 */ fmovicc ("fmovdcs", FM_DF, CONDCS, 0),
+/* v9 */ fmovicc ("fmovqcs", FM_QF, CONDCS, 0),
+/* v9 */ fmovicc ("fmovscs", FM_SF, CONDCS, 0),
+/* v9 */ fmovcc ("fmovde", FM_DF, CONDE, FCONDE, 0),
+/* v9 */ fmovcc ("fmovqe", FM_QF, CONDE, FCONDE, 0),
+/* v9 */ fmovcc ("fmovse", FM_SF, CONDE, FCONDE, 0),
+/* v9 */ fmovcc ("fmovdg", FM_DF, CONDG, FCONDG, 0),
+/* v9 */ fmovcc ("fmovqg", FM_QF, CONDG, FCONDG, 0),
+/* v9 */ fmovcc ("fmovsg", FM_SF, CONDG, FCONDG, 0),
+/* v9 */ fmovcc ("fmovdge", FM_DF, CONDGE, FCONDGE, 0),
+/* v9 */ fmovcc ("fmovqge", FM_QF, CONDGE, FCONDGE, 0),
+/* v9 */ fmovcc ("fmovsge", FM_SF, CONDGE, FCONDGE, 0),
+/* v9 */ fmovicc ("fmovdgeu", FM_DF, CONDGEU, F_ALIAS),
+/* v9 */ fmovicc ("fmovqgeu", FM_QF, CONDGEU, F_ALIAS),
+/* v9 */ fmovicc ("fmovsgeu", FM_SF, CONDGEU, F_ALIAS),
+/* v9 */ fmovicc ("fmovdgu", FM_DF, CONDGU, 0),
+/* v9 */ fmovicc ("fmovqgu", FM_QF, CONDGU, 0),
+/* v9 */ fmovicc ("fmovsgu", FM_SF, CONDGU, 0),
+/* v9 */ fmovcc ("fmovdl", FM_DF, CONDL, FCONDL, 0),
+/* v9 */ fmovcc ("fmovql", FM_QF, CONDL, FCONDL, 0),
+/* v9 */ fmovcc ("fmovsl", FM_SF, CONDL, FCONDL, 0),
+/* v9 */ fmovcc ("fmovdle", FM_DF, CONDLE, FCONDLE, 0),
+/* v9 */ fmovcc ("fmovqle", FM_QF, CONDLE, FCONDLE, 0),
+/* v9 */ fmovcc ("fmovsle", FM_SF, CONDLE, FCONDLE, 0),
+/* v9 */ fmovicc ("fmovdleu", FM_DF, CONDLEU, 0),
+/* v9 */ fmovicc ("fmovqleu", FM_QF, CONDLEU, 0),
+/* v9 */ fmovicc ("fmovsleu", FM_SF, CONDLEU, 0),
+/* v9 */ fmovfcc ("fmovdlg", FM_DF, FCONDLG, 0),
+/* v9 */ fmovfcc ("fmovqlg", FM_QF, FCONDLG, 0),
+/* v9 */ fmovfcc ("fmovslg", FM_SF, FCONDLG, 0),
+/* v9 */ fmovicc ("fmovdlu", FM_DF, CONDLU, F_ALIAS),
+/* v9 */ fmovicc ("fmovqlu", FM_QF, CONDLU, F_ALIAS),
+/* v9 */ fmovicc ("fmovslu", FM_SF, CONDLU, F_ALIAS),
+/* v9 */ fmovcc ("fmovdn", FM_DF, CONDN, FCONDN, 0),
+/* v9 */ fmovcc ("fmovqn", FM_QF, CONDN, FCONDN, 0),
+/* v9 */ fmovcc ("fmovsn", FM_SF, CONDN, FCONDN, 0),
+/* v9 */ fmovcc ("fmovdne", FM_DF, CONDNE, FCONDNE, 0),
+/* v9 */ fmovcc ("fmovqne", FM_QF, CONDNE, FCONDNE, 0),
+/* v9 */ fmovcc ("fmovsne", FM_SF, CONDNE, FCONDNE, 0),
+/* v9 */ fmovicc ("fmovdneg", FM_DF, CONDNEG, 0),
+/* v9 */ fmovicc ("fmovqneg", FM_QF, CONDNEG, 0),
+/* v9 */ fmovicc ("fmovsneg", FM_SF, CONDNEG, 0),
+/* v9 */ fmovcc ("fmovdnz", FM_DF, CONDNZ, FCONDNZ, F_ALIAS),
+/* v9 */ fmovcc ("fmovqnz", FM_QF, CONDNZ, FCONDNZ, F_ALIAS),
+/* v9 */ fmovcc ("fmovsnz", FM_SF, CONDNZ, FCONDNZ, F_ALIAS),
+/* v9 */ fmovfcc ("fmovdo", FM_DF, FCONDO, 0),
+/* v9 */ fmovfcc ("fmovqo", FM_QF, FCONDO, 0),
+/* v9 */ fmovfcc ("fmovso", FM_SF, FCONDO, 0),
+/* v9 */ fmovicc ("fmovdpos", FM_DF, CONDPOS, 0),
+/* v9 */ fmovicc ("fmovqpos", FM_QF, CONDPOS, 0),
+/* v9 */ fmovicc ("fmovspos", FM_SF, CONDPOS, 0),
+/* v9 */ fmovfcc ("fmovdu", FM_DF, FCONDU, 0),
+/* v9 */ fmovfcc ("fmovqu", FM_QF, FCONDU, 0),
+/* v9 */ fmovfcc ("fmovsu", FM_SF, FCONDU, 0),
+/* v9 */ fmovfcc ("fmovdue", FM_DF, FCONDUE, 0),
+/* v9 */ fmovfcc ("fmovque", FM_QF, FCONDUE, 0),
+/* v9 */ fmovfcc ("fmovsue", FM_SF, FCONDUE, 0),
+/* v9 */ fmovfcc ("fmovdug", FM_DF, FCONDUG, 0),
+/* v9 */ fmovfcc ("fmovqug", FM_QF, FCONDUG, 0),
+/* v9 */ fmovfcc ("fmovsug", FM_SF, FCONDUG, 0),
+/* v9 */ fmovfcc ("fmovduge", FM_DF, FCONDUGE, 0),
+/* v9 */ fmovfcc ("fmovquge", FM_QF, FCONDUGE, 0),
+/* v9 */ fmovfcc ("fmovsuge", FM_SF, FCONDUGE, 0),
+/* v9 */ fmovfcc ("fmovdul", FM_DF, FCONDUL, 0),
+/* v9 */ fmovfcc ("fmovqul", FM_QF, FCONDUL, 0),
+/* v9 */ fmovfcc ("fmovsul", FM_SF, FCONDUL, 0),
+/* v9 */ fmovfcc ("fmovdule", FM_DF, FCONDULE, 0),
+/* v9 */ fmovfcc ("fmovqule", FM_QF, FCONDULE, 0),
+/* v9 */ fmovfcc ("fmovsule", FM_SF, FCONDULE, 0),
+/* v9 */ fmovicc ("fmovdvc", FM_DF, CONDVC, 0),
+/* v9 */ fmovicc ("fmovqvc", FM_QF, CONDVC, 0),
+/* v9 */ fmovicc ("fmovsvc", FM_SF, CONDVC, 0),
+/* v9 */ fmovicc ("fmovdvs", FM_DF, CONDVS, 0),
+/* v9 */ fmovicc ("fmovqvs", FM_QF, CONDVS, 0),
+/* v9 */ fmovicc ("fmovsvs", FM_SF, CONDVS, 0),
+/* v9 */ fmovcc ("fmovdz", FM_DF, CONDZ, FCONDZ, F_ALIAS),
+/* v9 */ fmovcc ("fmovqz", FM_QF, CONDZ, FCONDZ, F_ALIAS),
+/* v9 */ fmovcc ("fmovsz", FM_SF, CONDZ, FCONDZ, F_ALIAS),
+
+#undef fmovicc /* v9 */
+#undef fmovfcc /* v9 */
+#undef fmovcc /* v9 */
+#undef FM_DF /* v9 */
+#undef FM_QF /* v9 */
+#undef FM_SF /* v9 */
+
+#define brfc(opcode, mask, lose, flags) \
+ { opcode, (mask), ANNUL|(lose), "l", flags|F_DELAYED, v6 }, \
+ { opcode, (mask)|ANNUL, (lose), ",a l", flags|F_DELAYED, v6 }
+
+#define brfcx(opcode, mask, lose, flags) /* v9 */ \
+ { opcode, FBFCC(0)|(mask)|BPRED, ANNUL|FBFCC(~0)|(lose), "6,G",
flags|F_DELAYED, v9 }, \
+ { opcode, FBFCC(0)|(mask)|BPRED, ANNUL|FBFCC(~0)|(lose), ",T 6,G",
flags|F_DELAYED, v9 }, \
+ { opcode, FBFCC(0)|(mask)|BPRED|ANNUL, FBFCC(~0)|(lose), ",a 6,G",
flags|F_DELAYED, v9 }, \
+ { opcode, FBFCC(0)|(mask)|BPRED|ANNUL, FBFCC(~0)|(lose), ",a,T 6,G",
flags|F_DELAYED, v9 }, \
+ { opcode, FBFCC(0)|(mask), ANNUL|BPRED|FBFCC(~0)|(lose), ",N 6,G",
flags|F_DELAYED, v9 }, \
+ { opcode, FBFCC(0)|(mask)|ANNUL, BPRED|FBFCC(~0)|(lose), ",a,N 6,G",
flags|F_DELAYED, v9 }, \
+ { opcode, FBFCC(1)|(mask)|BPRED, ANNUL|FBFCC(~1)|(lose), "7,G",
flags|F_DELAYED, v9 }, \
+ { opcode, FBFCC(1)|(mask)|BPRED, ANNUL|FBFCC(~1)|(lose), ",T 7,G",
flags|F_DELAYED, v9 }, \
+ { opcode, FBFCC(1)|(mask)|BPRED|ANNUL, FBFCC(~1)|(lose), ",a 7,G",
flags|F_DELAYED, v9 }, \
+ { opcode, FBFCC(1)|(mask)|BPRED|ANNUL, FBFCC(~1)|(lose), ",a,T 7,G",
flags|F_DELAYED, v9 }, \
+ { opcode, FBFCC(1)|(mask), ANNUL|BPRED|FBFCC(~1)|(lose), ",N 7,G",
flags|F_DELAYED, v9 }, \
+ { opcode, FBFCC(1)|(mask)|ANNUL, BPRED|FBFCC(~1)|(lose), ",a,N 7,G",
flags|F_DELAYED, v9 }, \
+ { opcode, FBFCC(2)|(mask)|BPRED, ANNUL|FBFCC(~2)|(lose), "8,G",
flags|F_DELAYED, v9 }, \
+ { opcode, FBFCC(2)|(mask)|BPRED, ANNUL|FBFCC(~2)|(lose), ",T 8,G",
flags|F_DELAYED, v9 }, \
+ { opcode, FBFCC(2)|(mask)|BPRED|ANNUL, FBFCC(~2)|(lose), ",a 8,G",
flags|F_DELAYED, v9 }, \
+ { opcode, FBFCC(2)|(mask)|BPRED|ANNUL, FBFCC(~2)|(lose), ",a,T 8,G",
flags|F_DELAYED, v9 }, \
+ { opcode, FBFCC(2)|(mask), ANNUL|BPRED|FBFCC(~2)|(lose), ",N 8,G",
flags|F_DELAYED, v9 }, \
+ { opcode, FBFCC(2)|(mask)|ANNUL, BPRED|FBFCC(~2)|(lose), ",a,N 8,G",
flags|F_DELAYED, v9 }, \
+ { opcode, FBFCC(3)|(mask)|BPRED, ANNUL|FBFCC(~3)|(lose), "9,G",
flags|F_DELAYED, v9 }, \
+ { opcode, FBFCC(3)|(mask)|BPRED, ANNUL|FBFCC(~3)|(lose), ",T 9,G",
flags|F_DELAYED, v9 }, \
+ { opcode, FBFCC(3)|(mask)|BPRED|ANNUL, FBFCC(~3)|(lose), ",a 9,G",
flags|F_DELAYED, v9 }, \
+ { opcode, FBFCC(3)|(mask)|BPRED|ANNUL, FBFCC(~3)|(lose), ",a,T 9,G",
flags|F_DELAYED, v9 }, \
+ { opcode, FBFCC(3)|(mask), ANNUL|BPRED|FBFCC(~3)|(lose), ",N 9,G",
flags|F_DELAYED, v9 }, \
+ { opcode, FBFCC(3)|(mask)|ANNUL, BPRED|FBFCC(~3)|(lose), ",a,N 9,G",
flags|F_DELAYED, v9 }
+
+/* v9: We must put `brfcx' before `brfc', to ensure that we never match
+ v9: something against an expression unless it is an expression. Otherwise,
+ v9: we end up with undefined symbol tables entries, because they get added,
+ v9: but are not deleted if the pattern fails to match. */
+
+#define condfc(fop, cop, mask, flags) \
+ brfcx(fop, F2(0, 5)|COND(mask), F2(~0, ~5)|COND(~(mask)), flags), /* v9 */ \
+ brfc(fop, F2(0, 6)|COND(mask), F2(~0, ~6)|COND(~(mask)), flags), \
+ brfc(cop, F2(0, 7)|COND(mask), F2(~0, ~7)|COND(~(mask)), flags)
+
+#define condf(fop, mask, flags) \
+ brfcx(fop, F2(0, 5)|COND(mask), F2(~0, ~5)|COND(~(mask)), flags), /* v9 */ \
+ brfc(fop, F2(0, 6)|COND(mask), F2(~0, ~6)|COND(~(mask)), flags)
+
+condfc("fb", "cb", 0x8, 0),
+condfc("fba", "cba", 0x8, F_ALIAS),
+condfc("fbe", "cb0", 0x9, 0),
+condf("fbz", 0x9, F_ALIAS),
+condfc("fbg", "cb2", 0x6, 0),
+condfc("fbge", "cb02", 0xb, 0),
+condfc("fbl", "cb1", 0x4, 0),
+condfc("fble", "cb01", 0xd, 0),
+condfc("fblg", "cb12", 0x2, 0),
+condfc("fbn", "cbn", 0x0, 0),
+condfc("fbne", "cb123", 0x1, 0),
+condf("fbnz", 0x1, F_ALIAS),
+condfc("fbo", "cb012", 0xf, 0),
+condfc("fbu", "cb3", 0x7, 0),
+condfc("fbue", "cb03", 0xa, 0),
+condfc("fbug", "cb23", 0x5, 0),
+condfc("fbuge", "cb023", 0xc, 0),
+condfc("fbul", "cb13", 0x3, 0),
+condfc("fbule", "cb013", 0xe, 0),
+
+#undef condfc
+#undef brfc
+#undef brfcx /* v9 */
+
+{ "jmp", F3(2, 0x38, 0), F3(~2, ~0x38, ~0)|RD_G0|ASI(~0), "1+2",
F_UNBR|F_DELAYED, v6 }, /* jmpl rs1+rs2,%g0 */
+{ "jmp", F3(2, 0x38, 0), F3(~2, ~0x38, ~0)|RD_G0|ASI_RS2(~0), "1",
F_UNBR|F_DELAYED, v6 }, /* jmpl rs1+%g0,%g0 */
+{ "jmp", F3(2, 0x38, 1), F3(~2, ~0x38, ~1)|RD_G0, "1+i",
F_UNBR|F_DELAYED, v6 }, /* jmpl rs1+i,%g0 */
+{ "jmp", F3(2, 0x38, 1), F3(~2, ~0x38, ~1)|RD_G0, "i+1",
F_UNBR|F_DELAYED, v6 }, /* jmpl i+rs1,%g0 */
+{ "jmp", F3(2, 0x38, 1), F3(~2, ~0x38, ~1)|RD_G0|RS1_G0, "i",
F_UNBR|F_DELAYED, v6 }, /* jmpl %g0+i,%g0 */
+{ "jmp", F3(2, 0x38, 1), F3(~2, ~0x38, ~1)|RD_G0|SIMM13(~0), "1",
F_UNBR|F_DELAYED, v6 }, /* jmpl rs1+0,%g0 */
+
+{ "nop", F2(0, 4), 0xfeffffff, "", 0, v6 }, /* sethi 0, %g0 */
+
+{ "set", F2(0x0, 0x4), F2(~0x0, ~0x4), "Sh,d", F_ALIAS, v6 },
+
+{ "sethi", F2(0x0, 0x4), F2(~0x0, ~0x4), "h,d", 0, v6 },
+
+{ "taddcc", F3(2, 0x20, 0), F3(~2, ~0x20, ~0)|ASI(~0), "1,2,d", 0, v6
},
+{ "taddcc", F3(2, 0x20, 1), F3(~2, ~0x20, ~1), "1,i,d", 0, v6
},
+{ "taddcc", F3(2, 0x20, 1), F3(~2, ~0x20, ~1), "i,1,d", 0, v6
},
+{ "taddcctv", F3(2, 0x22, 0), F3(~2, ~0x22, ~0)|ASI(~0), "1,2,d", 0, v6
},
+{ "taddcctv", F3(2, 0x22, 1), F3(~2, ~0x22, ~1), "1,i,d", 0, v6
},
+{ "taddcctv", F3(2, 0x22, 1), F3(~2, ~0x22, ~1), "i,1,d", 0, v6
},
+
+{ "tsubcc", F3(2, 0x21, 0), F3(~2, ~0x21, ~0)|ASI(~0), "1,2,d", 0, v6
},
+{ "tsubcc", F3(2, 0x21, 1), F3(~2, ~0x21, ~1), "1,i,d", 0, v6
},
+{ "tsubcctv", F3(2, 0x23, 0), F3(~2, ~0x23, ~0)|ASI(~0), "1,2,d", 0, v6
},
+{ "tsubcctv", F3(2, 0x23, 1), F3(~2, ~0x23, ~1), "1,i,d", 0, v6
},
+
+{ "unimp", F2(0x0, 0x0), 0xffc00000, "n", 0, v6notv9 },
+{ "illtrap", F2(0, 0), F2(~0, ~0)|RD_G0, "n", 0, v9 },
+
+/* This *is* a commutative instruction. */
+{ "xnor", F3(2, 0x07, 0), F3(~2, ~0x07, ~0)|ASI(~0), "1,2,d", 0, v6
},
+{ "xnor", F3(2, 0x07, 1), F3(~2, ~0x07, ~1), "1,i,d", 0, v6
},
+{ "xnor", F3(2, 0x07, 1), F3(~2, ~0x07, ~1), "i,1,d", 0, v6
},
+/* This *is* a commutative instruction. */
+{ "xnorcc", F3(2, 0x17, 0), F3(~2, ~0x17, ~0)|ASI(~0), "1,2,d", 0, v6
},
+{ "xnorcc", F3(2, 0x17, 1), F3(~2, ~0x17, ~1), "1,i,d", 0, v6
},
+{ "xnorcc", F3(2, 0x17, 1), F3(~2, ~0x17, ~1), "i,1,d", 0, v6
},
+{ "xor", F3(2, 0x03, 0), F3(~2, ~0x03, ~0)|ASI(~0), "1,2,d", 0, v6
},
+{ "xor", F3(2, 0x03, 1), F3(~2, ~0x03, ~1), "1,i,d", 0, v6
},
+{ "xor", F3(2, 0x03, 1), F3(~2, ~0x03, ~1), "i,1,d", 0, v6
},
+{ "xorcc", F3(2, 0x13, 0), F3(~2, ~0x13, ~0)|ASI(~0), "1,2,d", 0, v6
},
+{ "xorcc", F3(2, 0x13, 1), F3(~2, ~0x13, ~1), "1,i,d", 0, v6
},
+{ "xorcc", F3(2, 0x13, 1), F3(~2, ~0x13, ~1), "i,1,d", 0, v6
},
+
+{ "not", F3(2, 0x07, 0), F3(~2, ~0x07, ~0)|ASI(~0), "1,d", F_ALIAS, v6
}, /* xnor rs1,%0,rd */
+{ "not", F3(2, 0x07, 0), F3(~2, ~0x07, ~0)|ASI(~0), "r", F_ALIAS, v6 },
/* xnor rd,%0,rd */
+
+{ "btog", F3(2, 0x03, 0), F3(~2, ~0x03, ~0)|ASI(~0), "2,r", F_ALIAS,
v6 }, /* xor rd,rs2,rd */
+{ "btog", F3(2, 0x03, 1), F3(~2, ~0x03, ~1), "i,r", F_ALIAS,
v6 }, /* xor rd,i,rd */
+
+/* FPop1 and FPop2 are not instructions. Don't accept them. */
+
+{ "fdtoi", F3F(2, 0x34, 0x0d2), F3F(~2, ~0x34, ~0x0d2)|RS1_G0, "B,g", 0,
v6 },
+{ "fstoi", F3F(2, 0x34, 0x0d1), F3F(~2, ~0x34, ~0x0d1)|RS1_G0, "f,g", 0,
v6 },
+{ "fqtoi", F3F(2, 0x34, 0x0d3), F3F(~2, ~0x34, ~0x0d3)|RS1_G0, "R,g", 0,
v8 },
+
+{ "fdtox", F3F(2, 0x34, 0x082), F3F(~2, ~0x34, ~0x082)|RS1_G0, "B,g", 0,
v9 },
+{ "fstox", F3F(2, 0x34, 0x081), F3F(~2, ~0x34, ~0x081)|RS1_G0, "f,g", 0,
v9 },
+{ "fqtox", F3F(2, 0x34, 0x083), F3F(~2, ~0x34, ~0x083)|RS1_G0, "R,g", 0,
v9 },
+
+{ "fitod", F3F(2, 0x34, 0x0c8), F3F(~2, ~0x34, ~0x0c8)|RS1_G0, "f,H", 0,
v6 },
+{ "fitos", F3F(2, 0x34, 0x0c4), F3F(~2, ~0x34, ~0x0c4)|RS1_G0, "f,g", 0,
v6 },
+{ "fitoq", F3F(2, 0x34, 0x0cc), F3F(~2, ~0x34, ~0x0cc)|RS1_G0, "f,J", 0,
v8 },
+
+{ "fxtod", F3F(2, 0x34, 0x088), F3F(~2, ~0x34, ~0x088)|RS1_G0, "f,H", 0,
v9 },
+{ "fxtos", F3F(2, 0x34, 0x084), F3F(~2, ~0x34, ~0x084)|RS1_G0, "f,g", 0,
v9 },
+{ "fxtoq", F3F(2, 0x34, 0x08c), F3F(~2, ~0x34, ~0x08c)|RS1_G0, "f,J", 0,
v9 },
+
+{ "fdtoq", F3F(2, 0x34, 0x0ce), F3F(~2, ~0x34, ~0x0ce)|RS1_G0, "B,J", 0,
v8 },
+{ "fdtos", F3F(2, 0x34, 0x0c6), F3F(~2, ~0x34, ~0x0c6)|RS1_G0, "B,g", 0,
v6 },
+{ "fqtod", F3F(2, 0x34, 0x0cb), F3F(~2, ~0x34, ~0x0cb)|RS1_G0, "R,H", 0,
v8 },
+{ "fqtos", F3F(2, 0x34, 0x0c7), F3F(~2, ~0x34, ~0x0c7)|RS1_G0, "R,g", 0,
v8 },
+{ "fstod", F3F(2, 0x34, 0x0c9), F3F(~2, ~0x34, ~0x0c9)|RS1_G0, "f,H", 0,
v6 },
+{ "fstoq", F3F(2, 0x34, 0x0cd), F3F(~2, ~0x34, ~0x0cd)|RS1_G0, "f,J", 0,
v8 },
+
+{ "fdivd", F3F(2, 0x34, 0x04e), F3F(~2, ~0x34, ~0x04e), "v,B,H", 0, v6 },
+{ "fdivq", F3F(2, 0x34, 0x04f), F3F(~2, ~0x34, ~0x04f), "V,R,J", 0, v8 },
+{ "fdivs", F3F(2, 0x34, 0x04d), F3F(~2, ~0x34, ~0x04d), "e,f,g", 0, v6 },
+{ "fmuld", F3F(2, 0x34, 0x04a), F3F(~2, ~0x34, ~0x04a), "v,B,H", 0, v6 },
+{ "fmulq", F3F(2, 0x34, 0x04b), F3F(~2, ~0x34, ~0x04b), "V,R,J", 0, v8 },
+{ "fmuls", F3F(2, 0x34, 0x049), F3F(~2, ~0x34, ~0x049), "e,f,g", 0, v6 },
+
+{ "fdmulq", F3F(2, 0x34, 0x06e), F3F(~2, ~0x34, ~0x06e), "v,B,J", 0, v8 },
+{ "fsmuld", F3F(2, 0x34, 0x069), F3F(~2, ~0x34, ~0x069), "e,f,H", 0, v8 },
+
+{ "fsqrtd", F3F(2, 0x34, 0x02a), F3F(~2, ~0x34, ~0x02a)|RS1_G0, "B,H", 0,
v7 },
+{ "fsqrtq", F3F(2, 0x34, 0x02b), F3F(~2, ~0x34, ~0x02b)|RS1_G0, "R,J", 0,
v8 },
+{ "fsqrts", F3F(2, 0x34, 0x029), F3F(~2, ~0x34, ~0x029)|RS1_G0, "f,g", 0,
v7 },
+
+{ "fabsd", F3F(2, 0x34, 0x00a), F3F(~2, ~0x34, ~0x00a)|RS1_G0, "B,H", 0,
v9 },
+{ "fabsq", F3F(2, 0x34, 0x00b), F3F(~2, ~0x34, ~0x00b)|RS1_G0, "R,J", 0,
v9 },
+{ "fabss", F3F(2, 0x34, 0x009), F3F(~2, ~0x34, ~0x009)|RS1_G0, "f,g", 0,
v6 },
+{ "fmovd", F3F(2, 0x34, 0x002), F3F(~2, ~0x34, ~0x002)|RS1_G0, "B,H", 0,
v9 },
+{ "fmovq", F3F(2, 0x34, 0x003), F3F(~2, ~0x34, ~0x003)|RS1_G0, "R,J", 0,
v9 },
+{ "fmovs", F3F(2, 0x34, 0x001), F3F(~2, ~0x34, ~0x001)|RS1_G0, "f,g", 0,
v6 },
+{ "fnegd", F3F(2, 0x34, 0x006), F3F(~2, ~0x34, ~0x006)|RS1_G0, "B,H", 0,
v9 },
+{ "fnegq", F3F(2, 0x34, 0x007), F3F(~2, ~0x34, ~0x007)|RS1_G0, "R,J", 0,
v9 },
+{ "fnegs", F3F(2, 0x34, 0x005), F3F(~2, ~0x34, ~0x005)|RS1_G0, "f,g", 0,
v6 },
+
+{ "faddd", F3F(2, 0x34, 0x042), F3F(~2, ~0x34, ~0x042), "v,B,H", 0, v6 },
+{ "faddq", F3F(2, 0x34, 0x043), F3F(~2, ~0x34, ~0x043), "V,R,J", 0, v8 },
+{ "fadds", F3F(2, 0x34, 0x041), F3F(~2, ~0x34, ~0x041), "e,f,g", 0, v6 },
+{ "fsubd", F3F(2, 0x34, 0x046), F3F(~2, ~0x34, ~0x046), "v,B,H", 0, v6 },
+{ "fsubq", F3F(2, 0x34, 0x047), F3F(~2, ~0x34, ~0x047), "V,R,J", 0, v8 },
+{ "fsubs", F3F(2, 0x34, 0x045), F3F(~2, ~0x34, ~0x045), "e,f,g", 0, v6 },
+
+#define CMPFCC(x) (((x)&0x3)<<25)
+
+{ "fcmpd", F3F(2, 0x35, 0x052), F3F(~2, ~0x35,
~0x052)|RD_G0, "v,B", 0, v6 },
+{ "fcmpd", CMPFCC(0)|F3F(2, 0x35, 0x052), CMPFCC(~0)|F3F(~2, ~0x35,
~0x052), "6,v,B", 0, v9 },
+{ "fcmpd", CMPFCC(1)|F3F(2, 0x35, 0x052), CMPFCC(~1)|F3F(~2, ~0x35,
~0x052), "7,v,B", 0, v9 },
+{ "fcmpd", CMPFCC(2)|F3F(2, 0x35, 0x052), CMPFCC(~2)|F3F(~2, ~0x35,
~0x052), "8,v,B", 0, v9 },
+{ "fcmpd", CMPFCC(3)|F3F(2, 0x35, 0x052), CMPFCC(~3)|F3F(~2, ~0x35,
~0x052), "9,v,B", 0, v9 },
+{ "fcmped", F3F(2, 0x35, 0x056), F3F(~2, ~0x35,
~0x056)|RD_G0, "v,B", 0, v6 },
+{ "fcmped", CMPFCC(0)|F3F(2, 0x35, 0x056), CMPFCC(~0)|F3F(~2, ~0x35,
~0x056), "6,v,B", 0, v9 },
+{ "fcmped", CMPFCC(1)|F3F(2, 0x35, 0x056), CMPFCC(~1)|F3F(~2, ~0x35,
~0x056), "7,v,B", 0, v9 },
+{ "fcmped", CMPFCC(2)|F3F(2, 0x35, 0x056), CMPFCC(~2)|F3F(~2, ~0x35,
~0x056), "8,v,B", 0, v9 },
+{ "fcmped", CMPFCC(3)|F3F(2, 0x35, 0x056), CMPFCC(~3)|F3F(~2, ~0x35,
~0x056), "9,v,B", 0, v9 },
+{ "fcmpq", F3F(2, 0x34, 0x053), F3F(~2, ~0x34,
~0x053)|RD_G0, "V,R", 0, v8 },
+{ "fcmpq", CMPFCC(0)|F3F(2, 0x35, 0x053), CMPFCC(~0)|F3F(~2, ~0x35,
~0x053), "6,V,R", 0, v9 },
+{ "fcmpq", CMPFCC(1)|F3F(2, 0x35, 0x053), CMPFCC(~1)|F3F(~2, ~0x35,
~0x053), "7,V,R", 0, v9 },
+{ "fcmpq", CMPFCC(2)|F3F(2, 0x35, 0x053), CMPFCC(~2)|F3F(~2, ~0x35,
~0x053), "8,V,R", 0, v9 },
+{ "fcmpq", CMPFCC(3)|F3F(2, 0x35, 0x053), CMPFCC(~3)|F3F(~2, ~0x35,
~0x053), "9,V,R", 0, v9 },
+{ "fcmpeq", F3F(2, 0x34, 0x057), F3F(~2, ~0x34,
~0x057)|RD_G0, "V,R", 0, v8 },
+{ "fcmpeq", CMPFCC(0)|F3F(2, 0x35, 0x057), CMPFCC(~0)|F3F(~2, ~0x35,
~0x057), "6,V,R", 0, v9 },
+{ "fcmpeq", CMPFCC(1)|F3F(2, 0x35, 0x057), CMPFCC(~1)|F3F(~2, ~0x35,
~0x057), "7,V,R", 0, v9 },
+{ "fcmpeq", CMPFCC(2)|F3F(2, 0x35, 0x057), CMPFCC(~2)|F3F(~2, ~0x35,
~0x057), "8,V,R", 0, v9 },
+{ "fcmpeq", CMPFCC(3)|F3F(2, 0x35, 0x057), CMPFCC(~3)|F3F(~2, ~0x35,
~0x057), "9,V,R", 0, v9 },
+{ "fcmps", F3F(2, 0x35, 0x051), F3F(~2, ~0x35,
~0x051)|RD_G0, "e,f", 0, v6 },
+{ "fcmps", CMPFCC(0)|F3F(2, 0x35, 0x051), CMPFCC(~0)|F3F(~2, ~0x35,
~0x051), "6,e,f", 0, v9 },
+{ "fcmps", CMPFCC(1)|F3F(2, 0x35, 0x051), CMPFCC(~1)|F3F(~2, ~0x35,
~0x051), "7,e,f", 0, v9 },
+{ "fcmps", CMPFCC(2)|F3F(2, 0x35, 0x051), CMPFCC(~2)|F3F(~2, ~0x35,
~0x051), "8,e,f", 0, v9 },
+{ "fcmps", CMPFCC(3)|F3F(2, 0x35, 0x051), CMPFCC(~3)|F3F(~2, ~0x35,
~0x051), "9,e,f", 0, v9 },
+{ "fcmpes", F3F(2, 0x35, 0x055), F3F(~2, ~0x35,
~0x055)|RD_G0, "e,f", 0, v6 },
+{ "fcmpes", CMPFCC(0)|F3F(2, 0x35, 0x055), CMPFCC(~0)|F3F(~2, ~0x35,
~0x055), "6,e,f", 0, v9 },
+{ "fcmpes", CMPFCC(1)|F3F(2, 0x35, 0x055), CMPFCC(~1)|F3F(~2, ~0x35,
~0x055), "7,e,f", 0, v9 },
+{ "fcmpes", CMPFCC(2)|F3F(2, 0x35, 0x055), CMPFCC(~2)|F3F(~2, ~0x35,
~0x055), "8,e,f", 0, v9 },
+{ "fcmpes", CMPFCC(3)|F3F(2, 0x35, 0x055), CMPFCC(~3)|F3F(~2, ~0x35,
~0x055), "9,e,f", 0, v9 },
+
+/* These Extended FPop (FIFO) instructions are new in the Fujitsu
+ MB86934, replacing the CPop instructions from v6 and later
+ processors. */
+
+#define EFPOP1_2(name, op, args) { name, F3F(2, 0x36, op), F3F(~2, ~0x36,
~op)|RS1_G0, args, 0, sparclite }
+#define EFPOP1_3(name, op, args) { name, F3F(2, 0x36, op), F3F(~2, ~0x36,
~op), args, 0, sparclite }
+#define EFPOP2_2(name, op, args) { name, F3F(2, 0x37, op), F3F(~2, ~0x37,
~op)|RD_G0, args, 0, sparclite }
+
+EFPOP1_2 ("efitod", 0x0c8, "f,H"),
+EFPOP1_2 ("efitos", 0x0c4, "f,g"),
+EFPOP1_2 ("efdtoi", 0x0d2, "B,g"),
+EFPOP1_2 ("efstoi", 0x0d1, "f,g"),
+EFPOP1_2 ("efstod", 0x0c9, "f,H"),
+EFPOP1_2 ("efdtos", 0x0c6, "B,g"),
+EFPOP1_2 ("efmovs", 0x001, "f,g"),
+EFPOP1_2 ("efnegs", 0x005, "f,g"),
+EFPOP1_2 ("efabss", 0x009, "f,g"),
+EFPOP1_2 ("efsqrtd", 0x02a, "B,H"),
+EFPOP1_2 ("efsqrts", 0x029, "f,g"),
+EFPOP1_3 ("efaddd", 0x042, "v,B,H"),
+EFPOP1_3 ("efadds", 0x041, "e,f,g"),
+EFPOP1_3 ("efsubd", 0x046, "v,B,H"),
+EFPOP1_3 ("efsubs", 0x045, "e,f,g"),
+EFPOP1_3 ("efdivd", 0x04e, "v,B,H"),
+EFPOP1_3 ("efdivs", 0x04d, "e,f,g"),
+EFPOP1_3 ("efmuld", 0x04a, "v,B,H"),
+EFPOP1_3 ("efmuls", 0x049, "e,f,g"),
+EFPOP1_3 ("efsmuld", 0x069, "e,f,H"),
+EFPOP2_2 ("efcmpd", 0x052, "v,B"),
+EFPOP2_2 ("efcmped", 0x056, "v,B"),
+EFPOP2_2 ("efcmps", 0x051, "e,f"),
+EFPOP2_2 ("efcmpes", 0x055, "e,f"),
+
+#undef EFPOP1_2
+#undef EFPOP1_3
+#undef EFPOP2_2
+
+/* These are marked F_ALIAS, so that they won't conflict with sparclite insns
+ present. Otherwise, the F_ALIAS flag is ignored. */
+{ "cpop1", F3(2, 0x36, 0), F3(~2, ~0x36, ~1), "[1+2],d", F_ALIAS, v6notv9
},
+{ "cpop2", F3(2, 0x37, 0), F3(~2, ~0x37, ~1), "[1+2],d", F_ALIAS, v6notv9
},
+
+/* sparclet specific insns */
+
+commuteop ("umac", 0x3e, sparclet),
+commuteop ("smac", 0x3f, sparclet),
+commuteop ("umacd", 0x2e, sparclet),
+commuteop ("smacd", 0x2f, sparclet),
+commuteop ("umuld", 0x09, sparclet),
+commuteop ("smuld", 0x0d, sparclet),
+
+{ "shuffle", F3(2, 0x2d, 0), F3(~2, ~0x2d, ~0)|ASI(~0), "1,2,d", 0,
sparclet },
+{ "shuffle", F3(2, 0x2d, 1), F3(~2, ~0x2d, ~1), "1,i,d", 0,
sparclet },
+
+{ "crdcxt", F3(2, 0x36, 0)|ASI(4), F3(~2, ~0x36, ~0)|ASI(~4)|RS2(~0),
"U,d", 0, sparclet },
+{ "cwrcxt", F3(2, 0x36, 0)|ASI(3), F3(~2, ~0x36, ~0)|ASI(~3)|RS2(~0),
"1,u", 0, sparclet },
+{ "cpush", F3(2, 0x36, 0)|ASI(0), F3(~2, ~0x36, ~0)|ASI(~0)|RD(~0),
"1,2", 0, sparclet },
+{ "cpusha", F3(2, 0x36, 0)|ASI(1), F3(~2, ~0x36, ~0)|ASI(~1)|RD(~0),
"1,2", 0, sparclet },
+{ "cpull", F3(2, 0x36, 0)|ASI(2), F3(~2, ~0x36,
~0)|ASI(~2)|RS1(~0)|RS2(~0), "d", 0, sparclet },
+
+/* sparclet coprocessor branch insns */
+/* FIXME: We have to mark these as aliases until we can sort opcodes based
+ on selected cpu. */
+#define slcbcc2(opcode, mask, lose) \
+ { opcode, (mask), ANNUL|(lose), "l", F_DELAYED|F_CONDBR|F_ALIAS, sparclet
}, \
+ { opcode, (mask)|ANNUL, (lose), ",a l", F_DELAYED|F_CONDBR|F_ALIAS, sparclet }
+#define slcbcc(opcode, mask) \
+ slcbcc2(opcode, F2(0, 7)|COND(mask), F2(~0, ~7)|COND(~(mask)))
+
+/*slcbcc("cbn", 0), - already defined */
+slcbcc("cbe", 1),
+slcbcc("cbf", 2),
+slcbcc("cbef", 3),
+slcbcc("cbr", 4),
+slcbcc("cber", 5),
+slcbcc("cbfr", 6),
+slcbcc("cbefr", 7),
+/*slcbcc("cba", 8), - already defined */
+slcbcc("cbne", 9),
+slcbcc("cbnf", 10),
+slcbcc("cbnef", 11),
+slcbcc("cbnr", 12),
+slcbcc("cbner", 13),
+slcbcc("cbnfr", 14),
+slcbcc("cbnefr", 15),
+
+#undef slcbcc2
+#undef slcbcc
+
+/* More v9 specific insns */
+
+#define IMPDEP(name, code) \
+{ name, F3(2, code, 0), F3(~2, ~code, ~0)|ASI(~0), "1,2,d", 0, v9 }, \
+{ name, F3(2, code, 1), F3(~2, ~code, ~1), "1,i,d", 0, v9 }, \
+{ name, F3(2, code, 0), F3(~2, ~code, ~0), "x,1,2,d", 0, v9 }, \
+{ name, F3(2, code, 0), F3(~2, ~code, ~0), "x,e,f,g", 0, v9 }
+
+IMPDEP ("impdep1", 0x36),
+IMPDEP ("impdep2", 0x37),
+
+#undef IMPDEP
+
+{ "casa", F3(3, 0x3c, 0), F3(~3, ~0x3c, ~0), "[1]A,2,d", 0, v9 },
+{ "casa", F3(3, 0x3c, 1), F3(~3, ~0x3c, ~1), "[1]o,2,d", 0, v9 },
+{ "casxa", F3(3, 0x3e, 0), F3(~3, ~0x3e, ~0), "[1]A,2,d", 0, v9 },
+{ "casxa", F3(3, 0x3e, 1), F3(~3, ~0x3e, ~1), "[1]o,2,d", 0, v9 },
+
+/* v9 synthetic insns */
+/* FIXME: still missing "signx d", and "clruw d". Can't be done here. */
+{ "iprefetch", F2(0, 1)|(2<<20)|BPRED, F2(~0, ~1)|(1<<20)|ANNUL|COND(~0), "G",
0, v9 }, /* bn,a,pt %xcc,label */
+{ "signx", F3(2, 0x27, 0), F3(~2, ~0x27, ~0)|(1<<12)|ASI(~0)|RS2_G0,
"1,d", F_ALIAS, v9 }, /* sra rs1,%g0,rd */
+{ "clruw", F3(2, 0x26, 0), F3(~2, ~0x26, ~0)|(1<<12)|ASI(~0)|RS2_G0,
"1,d", F_ALIAS, v9 }, /* srl rs1,%g0,rd */
+{ "cas", F3(3, 0x3c, 0)|ASI(0x80), F3(~3, ~0x3c, ~0)|ASI(~0x80),
"[1],2,d", F_ALIAS, v9 }, /* casa [rs1]ASI_P,rs2,rd */
+{ "casl", F3(3, 0x3c, 0)|ASI(0x88), F3(~3, ~0x3c, ~0)|ASI(~0x88),
"[1],2,d", F_ALIAS, v9 }, /* casa [rs1]ASI_P_L,rs2,rd */
+{ "casx", F3(3, 0x3e, 0)|ASI(0x80), F3(~3, ~0x3e, ~0)|ASI(~0x80),
"[1],2,d", F_ALIAS, v9 }, /* casxa [rs1]ASI_P,rs2,rd */
+{ "casxl", F3(3, 0x3e, 0)|ASI(0x88), F3(~3, ~0x3e, ~0)|ASI(~0x88),
"[1],2,d", F_ALIAS, v9 }, /* casxa [rs1]ASI_P_L,rs2,rd */
+
+/* Ultrasparc extensions */
+/* FIXME: lots more to go */
+{ "shutdown", F3F(2, 0x36, 0x80), F3(~2, ~0x36, ~0x80)|RD_G0|RS1_G0|RS2_G0,
"", 0, v9a },
+
+};
+
+const int sparc_num_opcodes = ((sizeof sparc_opcodes)/(sizeof
sparc_opcodes[0]));
+
+/* Utilities for argument parsing. */
+
+typedef struct
+{
+ int value;
+ char *name;
+} arg;
+
+/* Look up NAME in TABLE. */
+
+static int
+lookup_name (table, name)
+ arg *table;
+ char *name;
+{
+ arg *p;
+
+ for (p = table; p->name; ++p)
+ if (strcmp (name, p->name) == 0)
+ return p->value;
+
+ return -1;
+}
+
+/* Look up VALUE in TABLE. */
+
+static char *
+lookup_value (table, value)
+ arg *table;
+ int value;
+{
+ arg *p;
+
+ for (p = table; p->name; ++p)
+ if (value == p->value)
+ return p->name;
+
+ return (char *) 0;
+}
+
+/* Handle ASI's. */
+
+static arg asi_table[] =
+{
+ { 0x10, "#ASI_AIUP" },
+ { 0x11, "#ASI_AIUS" },
+ { 0x18, "#ASI_AIUP_L" },
+ { 0x19, "#ASI_AIUS_L" },
+ { 0x80, "#ASI_P" },
+ { 0x81, "#ASI_S" },
+ { 0x82, "#ASI_PNF" },
+ { 0x83, "#ASI_SNF" },
+ { 0x88, "#ASI_P_L" },
+ { 0x89, "#ASI_S_L" },
+ { 0x8a, "#ASI_PNF_L" },
+ { 0x8b, "#ASI_SNF_L" },
+ { 0x10, "#ASI_AS_IF_USER_PRIMARY" },
+ { 0x11, "#ASI_AS_IF_USER_SECONDARY" },
+ { 0x18, "#ASI_AS_IF_USER_PRIMARY_L" },
+ { 0x19, "#ASI_AS_IF_USER_SECONDARY_L" },
+ { 0x80, "#ASI_PRIMARY" },
+ { 0x81, "#ASI_SECONDARY" },
+ { 0x82, "#ASI_PRIMARY_NOFAULT" },
+ { 0x83, "#ASI_SECONDARY_NOFAULT" },
+ { 0x88, "#ASI_PRIMARY_LITTLE" },
+ { 0x89, "#ASI_SECONDARY_LITTLE" },
+ { 0x8a, "#ASI_PRIMARY_NOFAULT_LITTLE" },
+ { 0x8b, "#ASI_SECONDARY_NOFAULT_LITTLE" },
+ { 0, 0 }
+};
+
+/* Return the value for ASI NAME, or -1 if not found. */
+
+int
+sparc_encode_asi (name)
+ char *name;
+{
+ return lookup_name (asi_table, name);
+}
+
+/* Return the name for ASI value VALUE or NULL if not found. */
+
+char *
+sparc_decode_asi (value)
+ int value;
+{
+ return lookup_value (asi_table, value);
+}
+
+/* Handle membar masks. */
+
+static arg membar_table[] =
+{
+ { 0x40, "#Sync" },
+ { 0x20, "#MemIssue" },
+ { 0x10, "#Lookaside" },
+ { 0x08, "#StoreStore" },
+ { 0x04, "#LoadStore" },
+ { 0x02, "#StoreLoad" },
+ { 0x01, "#LoadLoad" },
+ { 0, 0 }
+};
+
+/* Return the value for membar arg NAME, or -1 if not found. */
+
+int
+sparc_encode_membar (name)
+ char *name;
+{
+ return lookup_name (membar_table, name);
+}
+
+/* Return the name for membar value VALUE or NULL if not found. */
+
+char *
+sparc_decode_membar (value)
+ int value;
+{
+ return lookup_value (membar_table, value);
+}
+
+/* Handle prefetch args. */
+
+static arg prefetch_table[] =
+{
+ { 0, "#n_reads" },
+ { 1, "#one_read" },
+ { 2, "#n_writes" },
+ { 3, "#one_write" },
+ { 4, "#page" },
+ { 0, 0 }
+};
+
+/* Return the value for prefetch arg NAME, or -1 if not found. */
+
+int
+sparc_encode_prefetch (name)
+ char *name;
+{
+ return lookup_name (prefetch_table, name);
+}
+
+/* Return the name for prefetch value VALUE or NULL if not found. */
+
+char *
+sparc_decode_prefetch (value)
+ int value;
+{
+ return lookup_value (prefetch_table, value);
+}
+
+/* Handle sparclet coprocessor registers. */
+
+static arg sparclet_cpreg_table[] =
+{
+ { 0, "%ccsr" },
+ { 1, "%ccfr" },
+ { 2, "%cccrcr" },
+ { 3, "%ccpr" },
+ { 0, 0 }
+};
+
+/* Return the value for sparclet cpreg arg NAME, or -1 if not found. */
+
+int
+sparc_encode_sparclet_cpreg (name)
+ char *name;
+{
+ return lookup_name (sparclet_cpreg_table, name);
+}
+
+/* Return the name for sparclet cpreg value VALUE or NULL if not found. */
+
+char *
+sparc_decode_sparclet_cpreg (value)
+ int value;
+{
+ return lookup_value (sparclet_cpreg_table, value);
+}
diff --git a/opcode/sparc.h b/opcode/sparc.h
new file mode 100644
index 0000000..b9281e6
--- /dev/null
+++ b/opcode/sparc.h
@@ -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 */
diff --git a/opcode/sysdep.h b/opcode/sysdep.h
new file mode 100644
index 0000000..db31dc6
--- /dev/null
+++ b/opcode/sysdep.h
@@ -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
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 0000000..04abed3
--- /dev/null
+++ b/tests/Makefile.am
@@ -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
diff --git a/tests/add.c b/tests/add.c
new file mode 100644
index 0000000..0d36618
--- /dev/null
+++ b/tests/add.c
@@ -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;
+}
diff --git a/tests/add.ok b/tests/add.ok
new file mode 100644
index 0000000..f5f322c
--- /dev/null
+++ b/tests/add.ok
@@ -0,0 +1 @@
+5 + 4 = 9
diff --git a/tests/fib.c b/tests/fib.c
new file mode 100644
index 0000000..647ec8d
--- /dev/null
+++ b/tests/fib.c
@@ -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;
+}
diff --git a/tests/fib.ok b/tests/fib.ok
new file mode 100644
index 0000000..ce73f6e
--- /dev/null
+++ b/tests/fib.ok
@@ -0,0 +1 @@
+nfibs(32) = 7049155
diff --git a/tests/fibdelay.c b/tests/fibdelay.c
new file mode 100644
index 0000000..313208c
--- /dev/null
+++ b/tests/fibdelay.c
@@ -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;
+}
diff --git a/tests/fibdelay.ok b/tests/fibdelay.ok
new file mode 100644
index 0000000..334ce3f
--- /dev/null
+++ b/tests/fibdelay.ok
@@ -0,0 +1 @@
+nfibs(36) = 48315633
diff --git a/tests/fibit.c b/tests/fibit.c
new file mode 100644
index 0000000..4281b19
--- /dev/null
+++ b/tests/fibit.c
@@ -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;
+}
diff --git a/tests/fibit.ok b/tests/fibit.ok
new file mode 100644
index 0000000..334ce3f
--- /dev/null
+++ b/tests/fibit.ok
@@ -0,0 +1 @@
+nfibs(36) = 48315633
diff --git a/tests/funcfp.c b/tests/funcfp.c
new file mode 100644
index 0000000..a95f3f5
--- /dev/null
+++ b/tests/funcfp.c
@@ -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;
+}
diff --git a/tests/funcfp.ok b/tests/funcfp.ok
new file mode 100644
index 0000000..5077368
--- /dev/null
+++ b/tests/funcfp.ok
@@ -0,0 +1 @@
+result is 171.150000 17.250000
diff --git a/tests/incr.c b/tests/incr.c
new file mode 100644
index 0000000..7a0a516
--- /dev/null
+++ b/tests/incr.c
@@ -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;
+}
diff --git a/tests/incr.ok b/tests/incr.ok
new file mode 100644
index 0000000..0c3e5c8
--- /dev/null
+++ b/tests/incr.ok
@@ -0,0 +1 @@
+5 + 1 = 6
diff --git a/tests/printf.c b/tests/printf.c
new file mode 100644
index 0000000..ec27a2f
--- /dev/null
+++ b/tests/printf.c
@@ -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;
+}
diff --git a/tests/printf.ok b/tests/printf.ok
new file mode 100644
index 0000000..efa2663
--- /dev/null
+++ b/tests/printf.ok
@@ -0,0 +1 @@
+looks like 1024 bytes sufficed
diff --git a/tests/printf2.c b/tests/printf2.c
new file mode 100644
index 0000000..d4a297d
--- /dev/null
+++ b/tests/printf2.c
@@ -0,0 +1,2409 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "lightning.h"
+
+typedef int (*pifi)(int);
+ /* Pointer to Int Function of Int */
+
+void test(void);
+
+int main(void)
+{
+ jit_insn *codeBuffer = calloc(1, 1024);
+ pifi incr = (pifi) (jit_set_ip(codeBuffer).iptr);
+ int in;
+
+ jit_leaf(1);
+ in = jit_arg_i();
+ jit_getarg_i(JIT_R0, in);
+ jit_addi_i(JIT_R0, JIT_R0, 1);
+ jit_movr_i(JIT_RET, JIT_R0);
+ jit_ret();
+
+ jit_flush_code(codeBuffer, jit_get_ip().ptr);
+
+ /* call the generated code, passing 5 as an argument */
+ printf("%d + 1 = %d\n", 5, incr(5));
+ test();
+ return 0;
+}
+
+void test(void)
+{
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+ printf("this is a test\n");
+}
diff --git a/tests/printf2.ok b/tests/printf2.ok
new file mode 100644
index 0000000..1c2f0b7
--- /dev/null
+++ b/tests/printf2.ok
@@ -0,0 +1,2376 @@
+5 + 1 = 6
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
+this is a test
diff --git a/tests/rpn.c b/tests/rpn.c
new file mode 100644
index 0000000..a7549eb
--- /dev/null
+++ b/tests/rpn.c
@@ -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;
+}
diff --git a/tests/rpn.ok b/tests/rpn.ok
new file mode 100644
index 0000000..a1a2c4f
--- /dev/null
+++ b/tests/rpn.ok
@@ -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
diff --git a/tests/rpnfp.c b/tests/rpnfp.c
new file mode 100644
index 0000000..85b10af
--- /dev/null
+++ b/tests/rpnfp.c
@@ -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;
+}
diff --git a/tests/rpnfp.ok b/tests/rpnfp.ok
new file mode 100644
index 0000000..b803f59
--- /dev/null
+++ b/tests/rpnfp.ok
@@ -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
diff --git a/tests/run-test b/tests/run-test
new file mode 100755
index 0000000..ae3dfc7
--- /dev/null
+++ b/tests/run-test
@@ -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
diff --git a/tests/testfp.c b/tests/testfp.c
new file mode 100644
index 0000000..83d3edf
--- /dev/null
+++ b/tests/testfp.c
@@ -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);
+}
diff --git a/tests/testfp.ok b/tests/testfp.ok
new file mode 100644
index 0000000..8822dee
--- /dev/null
+++ b/tests/testfp.ok
@@ -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
- [Guile-commits] 393/437: Intermediate, fully functional, rework for variadic functions, (continued)
- [Guile-commits] 393/437: Intermediate, fully functional, rework for variadic functions, Andy Wingo, 2018/07/02
- [Guile-commits] 361/437: Correct the reason the simplify_stxi bug was not noticed before, Andy Wingo, 2018/07/02
- [Guile-commits] 356/437: ARM: Do not limit to 24 bit displacement jump to unknown address, Andy Wingo, 2018/07/02
- [Guile-commits] 422/437: Remove lightning unit tests, Andy Wingo, 2018/07/02
- [Guile-commits] 226/437: New aarch64 port built on the Foundation v8 emulator., Andy Wingo, 2018/07/02
- [Guile-commits] 128/437: Big merge with new lightning semantics aiming for lightning 2.0., Andy Wingo, 2018/07/02
- [Guile-commits] 132/437: Add extra files implementing different jit backends., Andy Wingo, 2018/07/02
- [Guile-commits] 433/437: Remove unused configure-time checks for x87, thumb, and sof float, Andy Wingo, 2018/07/02
- [Guile-commits] 283/437: Correct crash on arm in the doc/printf example., Andy Wingo, 2018/07/02
- [Guile-commits] 432/437: Remove lightning configure snippet related to libdl, Andy Wingo, 2018/07/02
- [Guile-commits] 01/437: initial import,
Andy Wingo <=
- [Guile-commits] 412/437: Add extra argument to jit_update to prevent recursion on branches, Andy Wingo, 2018/07/02
- [Guile-commits] 404/437: Correct wrong live information for some code patterns, Andy Wingo, 2018/07/02