diff options
author | Stan Shebs <shebs@codesourcery.com> | 1999-04-16 01:35:26 +0000 |
---|---|---|
committer | Stan Shebs <shebs@codesourcery.com> | 1999-04-16 01:35:26 +0000 |
commit | c906108c21474dfb4ed285bcc0ac6fe02cd400cc (patch) | |
tree | a0015aa5cedc19ccbab307251353a41722a3ae13 /sim/arm | |
parent | cd946cff9ede3f30935803403f06f6ed30cad136 (diff) | |
download | gdb-c906108c21474dfb4ed285bcc0ac6fe02cd400cc.zip gdb-c906108c21474dfb4ed285bcc0ac6fe02cd400cc.tar.gz gdb-c906108c21474dfb4ed285bcc0ac6fe02cd400cc.tar.bz2 |
Initial creation of sourceware repositorygdb-4_18-branchpoint
Diffstat (limited to 'sim/arm')
36 files changed, 17817 insertions, 0 deletions
diff --git a/sim/arm/COPYING b/sim/arm/COPYING new file mode 100644 index 0000000..60549be --- /dev/null +++ b/sim/arm/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) 19yy <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/sim/arm/ChangeLog b/sim/arm/ChangeLog new file mode 100644 index 0000000..4149366 --- /dev/null +++ b/sim/arm/ChangeLog @@ -0,0 +1,426 @@ +Mon Sep 14 09:00:05 1998 Nick Clifton <nickc@cygnus.com> + + * wrapper.c (sim_open): Set endianness according to BFD or command + line switch. + + * tconfig.in: Define SIM_HAVE_BIENDIAN. + +Thu Aug 27 11:00:05 1998 Nick Clifton <nickc@cygnus.com> + + * armemu.c (Multiply64): Test for Rm (rather than Rs) not being + the same as either RdHi or RdLo. + +Thu Jul 2 10:24:35 1998 Nick Clifton <nickc@cygnus.com> + + * armos.c (ARMul_OSHandleSWI: AngelSWI_Reason_ReportException): + Set Reg[0] based on reason for for the exception. + +Thu Jun 4 15:22:03 1998 Jason Molenda (crash@bugshack.cygnus.com) + + * armos.c (SWIwrite0): New function. + (WriteCommandLineTo): New function. + (SWIopen): New function. + (SWIread): New function. + (SWIwrite): New function. + (SWIflen): New function. + (ARMul_OSHandleSWI): Call new functions instead of handling + these here. + (ARMul_OSHandleSWI): Handle Angel SWIs correctly. + (*): Reformat spacing to be a bit more GNUly. + Most code taken from a patch by Anthony Thompson + (athompso@cambridge.arm.com) + +Tue Jun 2 15:22:22 1998 Nick Clifton <nickc@cygnus.com> + + * armos.h: Add Angel SWI and its reason codes. + * armos.c (ARMul_OSHandleSWI): Ignore Angel SWIs (for now). + +Mon Jun 1 17:14:19 1998 Anthony Thompson (athompso@cambridge.arm.com) + + * armos.c (ARMul_OSHandleSWI::SWI_Open): Handle special case + of ":tt" to catch stdin in addition to stdout. + (ARMul_OSHandleSWI::SWI_Seek): Return 0 or 1 to indicate failure + or success of lseek(). + +Wed May 20 17:36:25 1998 Nick Clifton <nickc@cygnus.com> + + * armos.c (ARMul_OSHandleSWI): Special case code to catch attempts + to open stdout. + +Wed Apr 29 15:29:55 1998 Jeff Johnston <jjohnstn@cygnus.com> + + * armos.c (ARMul_OSHandleSWI): Added code for SWI_Clock, + SWI_Flen, and SWI_Time. Also fixed SWI_Seek code to only + seek from offset 0 and not to use R2 for whence since it is + not passed as part of the SWI call. + +Tue Apr 28 18:33:31 1998 Geoffrey Noer <noer@cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Sun Apr 26 15:31:55 1998 Tom Tromey <tromey@creche> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + * config.in: Ditto. + +Sun Apr 26 15:20:26 1998 Tom Tromey <tromey@cygnus.com> + + * acconfig.h: New file. + * configure.in: Reverted change of Apr 24; use sinclude again. + +Fri Apr 24 14:16:40 1998 Tom Tromey <tromey@creche> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + * config.in: Ditto. + +Fri Apr 24 11:20:19 1998 Tom Tromey <tromey@cygnus.com> + + * configure.in: Don't call sinclude. + +Sat Apr 4 20:36:25 1998 Andrew Cagney <cagney@b1.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Fri Mar 27 16:15:52 1998 Andrew Cagney <cagney@b1.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Wed Mar 25 12:35:29 1998 Andrew Cagney <cagney@b1.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Wed Mar 18 12:38:12 1998 Andrew Cagney <cagney@b1.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Tue Mar 10 09:26:38 1998 Nick Clifton <nickc@cygnus.com> + + * armopts.h: Remove definition of LITTLEND - it is not used. + +Tue Feb 17 12:35:54 1998 Andrew Cagney <cagney@b1.cygnus.com> + + * wrapper.c (sim_store_register, sim_fetch_register): Pass in + length parameter. Return -1. + +Sun Feb 1 16:47:51 1998 Andrew Cagney <cagney@b1.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Sat Jan 31 18:15:41 1998 Andrew Cagney <cagney@b1.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Mon Jan 19 22:26:29 1998 Doug Evans <devans@seba> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Mon Dec 15 23:17:11 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + * config.in: Ditto. + +Tue Dec 9 11:30:48 1997 Nick Clifton <nickc@cygnus.com> + + * Makefile.in: Updated with changes from branch. + * armdefs.h: ditto + * armemu.c: ditto these changes + * armemu.h: ditto add support for + * armos.c: ditto the Thumb instruction + * armsupp.c: ditto set and the new v4 + * armvirt.c: ditto architecture. + * wrapper.c: ditto + * thumbemu.c: New file from branch. + + +Thu Dec 4 09:21:05 1997 Doug Evans <devans@canuck.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Thu Oct 30 13:54:06 1997 Nick Clifton <nickc@cygnus.com> + + * armos.c (ARMul_OSHandleSWI): Add support for GetEnv SWI. Patch + from Tony Thompson at ARM: athompso@arm.com + + * wrapper.c (sim_create_inferior): Add code to create an execution + environment. Patch from Tony Thompson at ARM: athompso@arm.com + +Wed Oct 22 14:43:00 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * wrapper.c (sim_load): Pass lma_p and sim_write args to + sim_load_file. + +Fri Oct 3 09:28:00 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Wed Sep 24 17:38:57 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Tue Sep 23 11:04:38 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Mon Sep 22 11:46:20 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Fri Sep 19 17:45:25 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Mon Sep 15 17:36:15 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Thu Sep 4 17:21:23 1997 Doug Evans <dje@seba> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Wed Aug 27 18:13:22 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + * config.in: Ditto. + +Tue Aug 26 10:37:27 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * wrapper.c (sim_kill): Delete. + (sim_create_inferior): Add ABFD argument. + (sim_load): Move setting of PC from here. + (sim_create_inferior): To here. + +Mon Aug 25 17:50:22 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + * config.in: Ditto. + +Mon Aug 25 15:35:45 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * wrapper.c (sim_open): Add ABFD argument. + +Tue May 20 10:13:26 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * wrapper.c (sim_open): Add callback argument. + (sim_set_callbacks): Drop SIM_DESC argument. + +Thu Apr 24 00:39:51 1997 Doug Evans <dje@canuck.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Fri Apr 18 13:32:23 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * wrapper.c (sim_stop): Stub sim_stop function. + +Thu Apr 17 18:33:01 1997 Fred Fish <fnf@cygnus.com> + + * arminit.c (ARMul_NewState): Preinitialize the state to + all zero/NULL. + +Thu Apr 17 02:39:02 1997 Doug Evans <dje@canuck.cygnus.com> + + * Makefile.in (SIM_OBJS): Add sim-load.o. + * wrapper.c (sim_kind,myname): New static locals. + (sim_open): Set sim_kind, myname. + (sim_load): Call sim_load_file to do work. Set start address from bfd. + (sim_create_inferior): Return SIM_RC. Delete start_address arg. + +Thu Apr 17 11:48:25 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * wrapper.c (sim_trace): Update so that it matches prototype. + +Mon Apr 7 15:45:02 1997 Andrew Cagney <cagney@kremvax.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + * config.in: Ditto. + +Mon Apr 7 12:01:17 1997 Andrew Cagney <cagney@kremvax.cygnus.com> + + * Makefile.in (armemu32.o): Replace $< with autoconf recommended + $(srcdir)/.... + (armemu26.o): Ditto. + +Wed Apr 2 15:06:28 1997 Doug Evans <dje@canuck.cygnus.com> + + * wrapper.c (sim_open): New arg `kind'. + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Wed Apr 2 14:50:44 1997 Ian Lance Taylor <ian@cygnus.com> + + * COPYING: Update FSF address. + +Wed Apr 2 14:34:19 1997 Andrew Cagney <cagney@kremvax.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Wed Mar 19 01:14:00 1997 Andrew Cagney <cagney@kremvax.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Mon Mar 17 15:10:07 1997 Andrew Cagney <cagney@kremvax.cygnus.com> + + * configure: Re-generate. + +Fri Mar 14 10:34:11 1997 Michael Meissner <meissner@cygnus.com> + + * configure: Regenerate to track ../common/aclocal.m4 changes. + +Thu Mar 13 12:38:56 1997 Doug Evans <dje@canuck.cygnus.com> + + * wrapper.c (sim_open): Has result now. + (sim_*): New SIM_DESC argument. + +Tue Feb 4 13:22:21 1997 Doug Evans <dje@canuck.cygnus.com> + + * Makefile.in (@COMMON_MAKEFILE_FRAG@): Use + COMMON_{PRE,POST}_CONFIG_FRAG instead. + * configure.in: sinclude ../common/aclocal.m4. + * configure: Regenerated. + +Thu Jan 23 11:46:23 1997 Stu Grossman (grossman@critters.cygnus.com) + + * configure configure.in Makefile.in: Update to new configure + scheme which is more compatible with WinGDB builds. + * configure.in: Improve comment on how to run autoconf. + * configure: Re-run autoconf to get new ../common/aclocal.m4. + * Makefile.in: Use autoconf substitution to install common + makefile fragment. + +Wed Nov 20 01:05:10 1996 Doug Evans <dje@canuck.cygnus.com> + + * run.c: Deleted, use one in ../common now. + * Makefile.in: Delete everything that's been moved to + ../common/Make-common.in. + (SIM_OBJS): Define. + * configure.in: Simplify using macros in ../common/aclocal.m4. + * configure: Regenerated. + * config.in: New file. + * armos.c: #include config.h. + * wrapper.c (mem_size): Value is in bytes now. + (sim_callback): New global. + (arm_sim_set_profile{,_size}): Delete. + (arm_sim_set_mem_size): Rename to sim_size. + (sim_do_command): Call printf_filtered via callback. + (sim_set_callbacks): Record callback. + +Thu Oct 3 16:10:27 1996 Jason Molenda (crash@godzilla.cygnus.co.jp) + + * Makefile.in (mostlyclean): Remove config.log. + +Wed Jun 26 12:17:24 1996 Jason Molenda (crash@godzilla.cygnus.co.jp) + + * Makefile.in (bindir, libdir, datadir, mandir, infodir, includedir, + INSTALL_PROGRAM, INSTALL_DATA): Use autoconf-set values. + (docdir): Removed. + * configure.in (AC_PREREQ): autoconf 2.5 or higher. + (AC_PROG_INSTALL): Added. + * configure: Rebuilt. + +Wed Feb 21 12:14:31 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure: Regenerate with autoconf 2.7. + +Fri Dec 15 16:27:30 1995 Ian Lance Taylor <ian@cygnus.com> + + * run.c (main): Use new bfd_big_endian macro. + +Mon Nov 20 17:40:38 1995 Doug Evans <dje@canuck.cygnus.com> + + * run.c: Include "getopt.h". + (verbose): Delete. + (usage): Make static. + (main): Call arm_sim_set_verbosity. + Only load sections marked SEC_LOAD. + * wrapper.c (mem_size, verbosity): New static global. + (arm_sim_set_mem_size): Renamed from sim_size. Callers updated. + (arm_sim_set_profile{,_size}): Renamed from sim_foo. Callers updated. + +Fri Nov 17 19:35:11 1995 Doug Evans <dje@canuck.cygnus.com> + + * armdefs.h (ARMul_State): New member `verbose'. + * armrdi.c (ARMul_ConsolePrint): Add missing va_end. + * run.c (verbose): Make global. + * wrapper.c (init): Set state->verbose. + (ARMul_ConsolePrint): Don't print anything if !verbose. + +Fri Oct 13 15:30:30 1995 Doug Evans <dje@canuck.cygnus.com> + + * armos.c: #include dbg_rdi.h. + (ARMul_OSHandleSWI): Handle SWI_Breakpoint. + * armos.h (SWI_Breakpoint): Define. + * wrapper.c: #include armemu.h, dbg_rdi.h. + (rc): Delete. + (sim_resume): Use state->EndCondition to record stop state. + Call FLUSHPIPE before returning. + (sim_stop_reason): Determine reason from state->EndCondition. + +Fri Oct 13 15:04:05 1995 steve chamberlain <sac@slash.cygnus.com> + + * wrapper.c (sim_set_callbacks): New. + +Thu Sep 28 19:45:56 1995 Doug Evans <dje@deneb.cygnus.com> + + * armos.c (ARMul_OSHandleSWI): Result of read/write calls is + number of bytes not read/written (or -1). + +Wed Sep 20 13:35:54 1995 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (maintainer-clean): New synonym for realclean. + +Fri Sep 8 14:27:20 1995 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Remove AC_PROG_INSTALL. + * configure: Rebuild. + * Makefile.in (INSTALL): Revert to using install.sh. + (INSTALL_PROGRAM, INSTALL_DATA): Set to $(INSTALL). + (INSTALL_XFORM, INSTALL_XFORM1): Restore. + (mostlyclean): Make the same as clean, not distclean. + (clean): Remove config.log. + (install): Don't install in $(tooldir). + +Thu Sep 7 12:00:17 1995 Doug Evans <dje@canuck.cygnus.com> + + (Try to) Update to new bfd autoconf scheme. + * run.c: Don't include sysdep.h. + * Makefile.in (INSTALL{,_PROGRAM,_DATA}): Use autoconf computed value. + (CC, CFLAGS, AR, RANLIB): Likewise. + (HDEFINES, TDEFINES): Define. + (CC_FOR_BUILD): Delete. + (host_makefile_frag): Delete. + (Makefile): Don't depend on frags. + * configure.in (sysdep.h): Don't create symlink. + (host_makefile_frag, frags): Deleted. + (CC, CFLAGS, AR, RANLIB, INSTALL): Compute values. + * configure: Regenerated. + +Thu Aug 3 10:45:37 1995 Fred Fish <fnf@cygnus.com> + + * Update all FSF addresses except those in COPYING* files. + +Wed Jul 5 16:15:54 1995 J.T. Conklin <jtc@rtl.cygnus.com> + + * Makefile.in (clean): Remove run, libsim.a. + + * Makefile.in, configure.in: converted to autoconf. + * configure: New file, generated with autconf 2.4. + + * arm.mt: Removed. + +Fri Jun 30 16:49:47 1995 Stan Shebs <shebs@andros.cygnus.com> + + * wrapper.c (sim_do_command): New function. + +Tue Jun 13 10:57:32 1995 Steve Chamberlain <sac@slash.cygnus.com> + + * armos.c (ARMul_OSHandleSWI): New version to work with + newlib simply. + +Thu Jun 8 14:37:14 1995 Steve Chamberlain <sac@slash.cygnus.com> + + * run.c (main): Grab return value from right register. + +Wed May 24 14:37:31 1995 Steve Chamberlain <sac@slash.cygnus.com> + + * New. + + diff --git a/sim/arm/Makefile.in b/sim/arm/Makefile.in new file mode 100644 index 0000000..b6ae2af --- /dev/null +++ b/sim/arm/Makefile.in @@ -0,0 +1,48 @@ +# Makefile template for Configure for the arm sim library. +# Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. +# Written by Cygnus Support. +# +# 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. + +## COMMON_PRE_CONFIG_FRAG + +SIM_EXTRA_CFLAGS = -DMODET + +SIM_OBJS = armcopro.o armemu26.o armemu32.o arminit.o armos.o armsupp.o \ + armvirt.o bag.o thumbemu.o wrapper.o sim-load.o + +## COMMON_POST_CONFIG_FRAG + + +armos.o: armos.c armdefs.h armos.h armfpe.h + +armcopro.o: armcopro.c armdefs.h + +armemu26.o: armemu.c armdefs.h armemu.h + $(CC) -c $< -o armemu26.o $(ALL_CFLAGS) + +armemu32.o: armemu.c armdefs.h armemu.h + $(CC) -c $< -o armemu32.o -DMODE32 $(ALL_CFLAGS) + +arminit.o: arminit.c armdefs.h armemu.h + +armrdi.o: armrdi.c armdefs.h armemu.h armos.h dbg_cp.h dbg_conf.h dbg_rdi.h \ + dbg_hif.h communicate.h + +armsupp.o: armsupp.c armdefs.h armemu.h + +thumbemu.o: thumbemu.c armdefs.h armemu.h + +bag.o: bag.c bag.h diff --git a/sim/arm/README.Cygnus b/sim/arm/README.Cygnus new file mode 100644 index 0000000..adfb766 --- /dev/null +++ b/sim/arm/README.Cygnus @@ -0,0 +1,27 @@ + +This directory contains the standard release of the ARMulator from +Advanced RISC Machines, and was ftp'd from. + +ftp.cl.cam.ac.uk:/arm/gnu + +It likes to use TCP/IP between the simulator and the host, which is +nice, but is a pain to use under anything non-unix. + +I've added created a new Makefile.in (the original in Makefile.orig) +to build a version of the simulator without the TCP/IP stuff, and a +wrapper.c to link directly into gdb and the run command. + +It should be possible (barring major changes in the layout of +the armulator) to upgrade the simulator by copying all the files +out of a release into this directory and renaming the Makefile. + +(Except that I changed armos.c to work more simply with our +simulator rigs) + +Steve + +sac@cygnus.com + +Mon May 15 12:03:28 PDT 1995 + + diff --git a/sim/arm/acconfig.h b/sim/arm/acconfig.h new file mode 100644 index 0000000..f9b87a1 --- /dev/null +++ b/sim/arm/acconfig.h @@ -0,0 +1,15 @@ + +/* Define to 1 if NLS is requested. */ +#undef ENABLE_NLS + +/* Define as 1 if you have catgets and don't want to use GNU gettext. */ +#undef HAVE_CATGETS + +/* Define as 1 if you have gettext and don't want to use GNU gettext. */ +#undef HAVE_GETTEXT + +/* Define as 1 if you have the stpcpy function. */ +#undef HAVE_STPCPY + +/* Define if your locale.h file contains LC_MESSAGES. */ +#undef HAVE_LC_MESSAGES diff --git a/sim/arm/armcopro.c b/sim/arm/armcopro.c new file mode 100644 index 0000000..fc93a863 --- /dev/null +++ b/sim/arm/armcopro.c @@ -0,0 +1,357 @@ +/* armcopro.c -- co-processor interface: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 "armdefs.h" + +extern unsigned ARMul_CoProInit(ARMul_State *state) ; +extern void ARMul_CoProExit(ARMul_State *state) ; +extern void ARMul_CoProAttach(ARMul_State *state, unsigned number, + ARMul_CPInits *init, ARMul_CPExits *exit, + ARMul_LDCs *ldc, ARMul_STCs *stc, + ARMul_MRCs *mrc, ARMul_MCRs *mcr, + ARMul_CDPs *cdp, + ARMul_CPReads *read, ARMul_CPWrites *write) ; +extern void ARMul_CoProDetach(ARMul_State *state, unsigned number) ; + + +/***************************************************************************\ +* Dummy Co-processors * +\***************************************************************************/ + +static unsigned NoCoPro3R(ARMul_State *state,unsigned,ARMword) ; +static unsigned NoCoPro4R(ARMul_State *state,unsigned,ARMword,ARMword) ; +static unsigned NoCoPro4W(ARMul_State *state,unsigned,ARMword,ARMword *) ; + +/***************************************************************************\ +* Define Co-Processor instruction handlers here * +\***************************************************************************/ + +/* Here's ARMulator's MMU definition. A few things to note: +1) it has eight registers, but only two are defined. +2) you can only access its registers with MCR and MRC. +3) MMU Register 0 (ID) returns 0x41440110 +4) Register 1 only has 4 bits defined. Bits 0 to 3 are unused, bit 4 +controls 32/26 bit program space, bit 5 controls 32/26 bit data space, +bit 6 controls late abort timimg and bit 7 controls big/little endian. +*/ + +static ARMword MMUReg[8] ; + +static unsigned MMUInit(ARMul_State *state) +{MMUReg[1] = state->prog32Sig << 4 | + state->data32Sig << 5 | + state->lateabtSig << 6 | + state->bigendSig << 7 ; + ARMul_ConsolePrint (state, ", MMU present") ; + return(TRUE) ; +} + +static unsigned MMUMRC(ARMul_State *state, unsigned type, ARMword instr,ARMword *value) +{int reg = BITS(16,19) & 7 ; + + if (reg == 0) + *value = 0x41440110 ; + else + *value = MMUReg[reg] ; + return(ARMul_DONE) ; + } + +static unsigned MMUMCR(ARMul_State *state, unsigned type, ARMword instr, ARMword value) +{int reg = BITS(16,19) & 7 ; + + MMUReg[reg] = value ; + if (reg == 1) { + state->prog32Sig = value >> 4 & 1 ; + state->data32Sig = value >> 5 & 1 ; + state->lateabtSig = value >> 6 & 1 ; + state->bigendSig = value >> 7 & 1 ; + state->Emulate = TRUE ; /* force ARMulator to notice these now !*/ + } + return(ARMul_DONE) ; + } + + +static unsigned MMURead(ARMul_State *state, unsigned reg, ARMword *value) +{if (reg == 0) + *value = 0x41440110 ; + else if (reg < 8) + *value = MMUReg[reg] ; + return(TRUE) ; + } + +static unsigned MMUWrite(ARMul_State *state, unsigned reg, ARMword value) +{if (reg < 8) + MMUReg[reg] = value ; + if (reg == 1) { + state->prog32Sig = value >> 4 & 1 ; + state->data32Sig = value >> 5 & 1 ; + state->lateabtSig = value >> 6 & 1 ; + state->bigendSig = value >> 7 & 1 ; + state->Emulate = TRUE ; /* force ARMulator to notice these now !*/ + } + return(TRUE) ; + } + + +/* What follows is the Validation Suite Coprocessor. It uses two +co-processor numbers (4 and 5) and has the follwing functionality. +Sixteen registers. Both co-processor nuimbers can be used in an MCR and +MRC to access these registers. CP 4 can LDC and STC to and from the +registers. CP 4 and CP 5 CDP 0 will busy wait for the number of cycles +specified by a CP register. CP 5 CDP 1 issues a FIQ after a number of +cycles (specified in a CP register), CDP 2 issues an IRQW in the same +way, CDP 3 and 4 turn of the FIQ and IRQ source, and CDP 5 stores a 32 +bit time value in a CP register (actually it's the total number of N, S, +I, C and F cyles) */ + +static ARMword ValReg[16] ; + +static unsigned ValLDC(ARMul_State *state, unsigned type, + ARMword instr, ARMword data) +{static unsigned words ; + + if (type != ARMul_DATA) { + words = 0 ; + return(ARMul_DONE) ; + } + if (BIT(22)) { /* it's a long access, get two words */ + ValReg[BITS(12,15)] = data ; + if (words++ == 4) + return(ARMul_DONE) ; + else + return(ARMul_INC) ; + } + else { /* get just one word */ + ValReg[BITS(12,15)] = data ; + return(ARMul_DONE) ; + } + } + +static unsigned ValSTC(ARMul_State *state, unsigned type, + ARMword instr, ARMword *data) +{static unsigned words ; + + if (type != ARMul_DATA) { + words = 0 ; + return(ARMul_DONE) ; + } + if (BIT(22)) { /* it's a long access, get two words */ + *data = ValReg[BITS(12,15)] ; + if (words++ == 4) + return(ARMul_DONE) ; + else + return(ARMul_INC) ; + } + else { /* get just one word */ + *data = ValReg[BITS(12,15)] ; + return(ARMul_DONE) ; + } + } + +static unsigned ValMRC(ARMul_State *state, unsigned type, ARMword instr,ARMword *value) +{ + *value = ValReg[BITS(16,19)] ; + return(ARMul_DONE) ; + } + +static unsigned ValMCR(ARMul_State *state, unsigned type, ARMword instr, ARMword value) +{ + ValReg[BITS(16,19)] = value ; + return(ARMul_DONE) ; + } + +static unsigned ValCDP(ARMul_State *state, unsigned type, ARMword instr) +{ + static unsigned long finish = 0 ; + ARMword howlong ; + + howlong = ValReg[BITS(0,3)] ; + if (BITS(20,23)==0) { + if (type == ARMul_FIRST) { /* First cycle of a busy wait */ + finish = ARMul_Time(state) + howlong ; + if (howlong == 0) + return(ARMul_DONE) ; + else + return(ARMul_BUSY) ; + } + else if (type == ARMul_BUSY) { + if (ARMul_Time(state) >= finish) + return(ARMul_DONE) ; + else + return(ARMul_BUSY) ; + } + } + return(ARMul_CANT) ; + } + +static unsigned DoAFIQ(ARMul_State *state) +{state->NfiqSig = LOW ; + state->Exception++ ; + return(0) ; +} + +static unsigned DoAIRQ(ARMul_State *state) +{state->NirqSig = LOW ; + state->Exception++ ; + return(0) ; +} + +static unsigned IntCDP(ARMul_State *state, unsigned type, ARMword instr) +{static unsigned long finish ; + ARMword howlong ; + + howlong = ValReg[BITS(0,3)] ; + switch((int)BITS(20,23)) { + case 0 : if (type == ARMul_FIRST) { /* First cycle of a busy wait */ + finish = ARMul_Time(state) + howlong ; + if (howlong == 0) + return(ARMul_DONE) ; + else + return(ARMul_BUSY) ; + } + else if (type == ARMul_BUSY) { + if (ARMul_Time(state) >= finish) + return(ARMul_DONE) ; + else + return(ARMul_BUSY) ; + } + return(ARMul_DONE) ; + case 1 : if (howlong == 0) + ARMul_Abort(state,ARMul_FIQV) ; + else + ARMul_ScheduleEvent(state,howlong,DoAFIQ) ; + return(ARMul_DONE) ; + case 2 : if (howlong == 0) + ARMul_Abort(state,ARMul_IRQV) ; + else + ARMul_ScheduleEvent(state,howlong,DoAIRQ) ; + return(ARMul_DONE) ; + case 3 : state->NfiqSig = HIGH ; + state->Exception-- ; + return(ARMul_DONE) ; + case 4 : state->NirqSig = HIGH ; + state->Exception-- ; + return(ARMul_DONE) ; + case 5 : ValReg[BITS(0,3)] = ARMul_Time(state) ; + return(ARMul_DONE) ; + } + return(ARMul_CANT) ; + } + +/***************************************************************************\ +* Install co-processor instruction handlers in this routine * +\***************************************************************************/ + +unsigned ARMul_CoProInit(ARMul_State *state) +{register unsigned i ; + + for (i = 0 ; i < 16 ; i++) /* initialise tham all first */ + ARMul_CoProDetach(state, i) ; + + /* Install CoPro Instruction handlers here + The format is + ARMul_CoProAttach(state, CP Number, Init routine, Exit routine + LDC routine, STC routine, MRC routine, MCR routine, + CDP routine, Read Reg routine, Write Reg routine) ; + */ + + ARMul_CoProAttach(state, 4, NULL, NULL, + ValLDC, ValSTC, ValMRC, ValMCR, + ValCDP, NULL, NULL) ; + + ARMul_CoProAttach(state, 5, NULL, NULL, + NULL, NULL, ValMRC, ValMCR, + IntCDP, NULL, NULL) ; + + ARMul_CoProAttach(state, 15, MMUInit, NULL, + NULL, NULL, MMUMRC, MMUMCR, + NULL, MMURead, MMUWrite) ; + + + /* No handlers below here */ + + for (i = 0 ; i < 16 ; i++) /* Call all the initialisation routines */ + if (state->CPInit[i]) + (state->CPInit[i])(state) ; + return(TRUE) ; + } + +/***************************************************************************\ +* Install co-processor finalisation routines in this routine * +\***************************************************************************/ + +void ARMul_CoProExit(ARMul_State *state) +{register unsigned i ; + + for (i = 0 ; i < 16 ; i++) + if (state->CPExit[i]) + (state->CPExit[i])(state) ; + for (i = 0 ; i < 16 ; i++) /* Detach all handlers */ + ARMul_CoProDetach(state, i) ; + } + +/***************************************************************************\ +* Routines to hook Co-processors into ARMulator * +\***************************************************************************/ + +void ARMul_CoProAttach(ARMul_State *state, unsigned number, + ARMul_CPInits *init, ARMul_CPExits *exit, + ARMul_LDCs *ldc, ARMul_STCs *stc, + ARMul_MRCs *mrc, ARMul_MCRs *mcr, ARMul_CDPs *cdp, + ARMul_CPReads *read, ARMul_CPWrites *write) +{if (init != NULL) + state->CPInit[number] = init ; + if (exit != NULL) + state->CPExit[number] = exit ; + if (ldc != NULL) + state->LDC[number] = ldc ; + if (stc != NULL) + state->STC[number] = stc ; + if (mrc != NULL) + state->MRC[number] = mrc ; + if (mcr != NULL) + state->MCR[number] = mcr ; + if (cdp != NULL) + state->CDP[number] = cdp ; + if (read != NULL) + state->CPRead[number] = read ; + if (write != NULL) + state->CPWrite[number] = write ; +} + +void ARMul_CoProDetach(ARMul_State *state, unsigned number) +{ARMul_CoProAttach(state, number, NULL, NULL, + NoCoPro4R, NoCoPro4W, NoCoPro4W, NoCoPro4R, + NoCoPro3R, NULL, NULL) ; + state->CPInit[number] = NULL ; + state->CPExit[number] = NULL ; + state->CPRead[number] = NULL ; + state->CPWrite[number] = NULL ; +} + +/***************************************************************************\ +* There is no CoPro around, so Undefined Instruction trap * +\***************************************************************************/ + +static unsigned NoCoPro3R(ARMul_State *state,unsigned a,ARMword b) +{return(ARMul_CANT) ;} + +static unsigned NoCoPro4R(ARMul_State *state, unsigned a,ARMword b,ARMword c) +{return(ARMul_CANT) ;} + +static unsigned NoCoPro4W(ARMul_State *state, unsigned a,ARMword b,ARMword *c) +{return(ARMul_CANT) ;} diff --git a/sim/arm/armdefs.h b/sim/arm/armdefs.h new file mode 100644 index 0000000..1e1f352 --- /dev/null +++ b/sim/arm/armdefs.h @@ -0,0 +1,353 @@ +/* armdefs.h -- ARMulator common definitions: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 <stdio.h> +#include <stdlib.h> + +#define FALSE 0 +#define TRUE 1 +#define LOW 0 +#define HIGH 1 +#define LOWHIGH 1 +#define HIGHLOW 2 + +#ifndef __STDC__ +typedef char * VoidStar ; +#endif + +typedef unsigned long ARMword ; /* must be 32 bits wide */ + +typedef struct ARMul_State ARMul_State ; + +typedef unsigned ARMul_CPInits(ARMul_State *state) ; +typedef unsigned ARMul_CPExits(ARMul_State *state) ; +typedef unsigned ARMul_LDCs(ARMul_State *state,unsigned type,ARMword instr,ARMword value) ; +typedef unsigned ARMul_STCs(ARMul_State *state,unsigned type,ARMword instr,ARMword *value) ; +typedef unsigned ARMul_MRCs(ARMul_State *state,unsigned type,ARMword instr,ARMword *value) ; +typedef unsigned ARMul_MCRs(ARMul_State *state,unsigned type,ARMword instr,ARMword value) ; +typedef unsigned ARMul_CDPs(ARMul_State *state,unsigned type,ARMword instr) ; +typedef unsigned ARMul_CPReads(ARMul_State *state,unsigned reg,ARMword *value) ; +typedef unsigned ARMul_CPWrites(ARMul_State *state,unsigned reg,ARMword value) ; + +struct ARMul_State { + ARMword Emulate ; /* to start and stop emulation */ + unsigned EndCondition ; /* reason for stopping */ + unsigned ErrorCode ; /* type of illegal instruction */ + ARMword Reg[16] ; /* the current register file */ + ARMword RegBank[7][16] ; /* all the registers */ + ARMword Cpsr ; /* the current psr */ + ARMword Spsr[7] ; /* the exception psr's */ + ARMword NFlag, ZFlag, CFlag, VFlag, IFFlags ; /* dummy flags for speed */ +#ifdef MODET + ARMword TFlag ; /* Thumb state */ +#endif + ARMword Bank ; /* the current register bank */ + ARMword Mode ; /* the current mode */ + ARMword instr, pc, temp ; /* saved register state */ + ARMword loaded, decoded ; /* saved pipeline state */ + unsigned long NumScycles, + NumNcycles, + NumIcycles, + NumCcycles, + NumFcycles ; /* emulated cycles used */ + unsigned long NumInstrs ; /* the number of instructions executed */ + unsigned NextInstr ; + unsigned VectorCatch ; /* caught exception mask */ + unsigned CallDebug ; /* set to call the debugger */ + unsigned CanWatch ; /* set by memory interface if its willing to suffer the + overhead of checking for watchpoints on each memory + access */ + unsigned MemReadDebug, MemWriteDebug ; + unsigned long StopHandle ; + + unsigned char *MemDataPtr ; /* admin data */ + unsigned char *MemInPtr ; /* the Data In bus */ + unsigned char *MemOutPtr ; /* the Data Out bus (which you may not need */ + unsigned char *MemSparePtr ; /* extra space */ + ARMword MemSize ; + + unsigned char *OSptr ; /* OS Handle */ + char *CommandLine ; /* Command Line from ARMsd */ + + ARMul_CPInits *CPInit[16] ; /* coprocessor initialisers */ + ARMul_CPExits *CPExit[16] ; /* coprocessor finalisers */ + ARMul_LDCs *LDC[16] ; /* LDC instruction */ + ARMul_STCs *STC[16] ; /* STC instruction */ + ARMul_MRCs *MRC[16] ; /* MRC instruction */ + ARMul_MCRs *MCR[16] ; /* MCR instruction */ + ARMul_CDPs *CDP[16] ; /* CDP instruction */ + ARMul_CPReads *CPRead[16] ; /* Read CP register */ + ARMul_CPWrites *CPWrite[16] ; /* Write CP register */ + unsigned char *CPData[16] ; /* Coprocessor data */ + unsigned char const *CPRegWords[16] ; /* map of coprocessor register sizes */ + + unsigned EventSet ; /* the number of events in the queue */ + unsigned long Now ; /* time to the nearest cycle */ + struct EventNode **EventPtr ; /* the event list */ + + unsigned Exception ; /* enable the next four values */ + unsigned Debug ; /* show instructions as they are executed */ + unsigned NresetSig ; /* reset the processor */ + unsigned NfiqSig ; + unsigned NirqSig ; + + unsigned abortSig ; + unsigned NtransSig ; + unsigned bigendSig ; + unsigned prog32Sig ; + unsigned data32Sig ; + unsigned lateabtSig ; + ARMword Vector ; /* synthesize aborts in cycle modes */ + ARMword Aborted ; /* sticky flag for aborts */ + ARMword Reseted ; /* sticky flag for Reset */ + ARMword Inted, LastInted ; /* sticky flags for interrupts */ + ARMword Base ; /* extra hand for base writeback */ + ARMword AbortAddr ; /* to keep track of Prefetch aborts */ + + const struct Dbg_HostosInterface *hostif; + + int verbose; /* non-zero means print various messages like the banner */ + } ; + +#define ResetPin NresetSig +#define FIQPin NfiqSig +#define IRQPin NirqSig +#define AbortPin abortSig +#define TransPin NtransSig +#define BigEndPin bigendSig +#define Prog32Pin prog32Sig +#define Data32Pin data32Sig +#define LateAbortPin lateabtSig + +/***************************************************************************\ +* Types of ARM we know about * +\***************************************************************************/ + +/* The bitflags */ +#define ARM_Fix26_Prop 0x01 +#define ARM_Nexec_Prop 0x02 +#define ARM_Debug_Prop 0x10 +#define ARM_Isync_Prop ARM_Debug_Prop +#define ARM_Lock_Prop 0x20 + +/* ARM2 family */ +#define ARM2 (ARM_Fix26_Prop) +#define ARM2as ARM2 +#define ARM61 ARM2 +#define ARM3 ARM2 + +#ifdef ARM60 /* previous definition in armopts.h */ +#undef ARM60 +#endif + +/* ARM6 family */ +#define ARM6 (ARM_Lock_Prop) +#define ARM60 ARM6 +#define ARM600 ARM6 +#define ARM610 ARM6 +#define ARM620 ARM6 + + +/***************************************************************************\ +* Macros to extract instruction fields * +\***************************************************************************/ + +#define BIT(n) ( (ARMword)(instr>>(n))&1) /* bit n of instruction */ +#define BITS(m,n) ( (ARMword)(instr<<(31-(n))) >> ((31-(n))+(m)) ) /* bits m to n of instr */ +#define TOPBITS(n) (instr >> (n)) /* bits 31 to n of instr */ + +/***************************************************************************\ +* The hardware vector addresses * +\***************************************************************************/ + +#define ARMResetV 0L +#define ARMUndefinedInstrV 4L +#define ARMSWIV 8L +#define ARMPrefetchAbortV 12L +#define ARMDataAbortV 16L +#define ARMAddrExceptnV 20L +#define ARMIRQV 24L +#define ARMFIQV 28L +#define ARMErrorV 32L /* This is an offset, not an address ! */ + +#define ARMul_ResetV ARMResetV +#define ARMul_UndefinedInstrV ARMUndefinedInstrV +#define ARMul_SWIV ARMSWIV +#define ARMul_PrefetchAbortV ARMPrefetchAbortV +#define ARMul_DataAbortV ARMDataAbortV +#define ARMul_AddrExceptnV ARMAddrExceptnV +#define ARMul_IRQV ARMIRQV +#define ARMul_FIQV ARMFIQV + +/***************************************************************************\ +* Mode and Bank Constants * +\***************************************************************************/ + +#define USER26MODE 0L +#define FIQ26MODE 1L +#define IRQ26MODE 2L +#define SVC26MODE 3L +#define USER32MODE 16L +#define FIQ32MODE 17L +#define IRQ32MODE 18L +#define SVC32MODE 19L +#define ABORT32MODE 23L +#define UNDEF32MODE 27L + +#define ARM32BITMODE (state->Mode > 3) +#define ARM26BITMODE (state->Mode <= 3) +#define ARMMODE (state->Mode) +#define ARMul_MODEBITS 0x1fL +#define ARMul_MODE32BIT ARM32BITMODE +#define ARMul_MODE26BIT ARM26BITMODE + +#define USERBANK 0 +#define FIQBANK 1 +#define IRQBANK 2 +#define SVCBANK 3 +#define ABORTBANK 4 +#define UNDEFBANK 5 +#define DUMMYBANK 6 + +/***************************************************************************\ +* Definitons of things in the emulator * +\***************************************************************************/ + +extern void ARMul_EmulateInit(void) ; +extern ARMul_State *ARMul_NewState(void) ; +extern void ARMul_Reset(ARMul_State *state) ; +extern ARMword ARMul_DoProg(ARMul_State *state) ; +extern ARMword ARMul_DoInstr(ARMul_State *state) ; + +/***************************************************************************\ +* Definitons of things for event handling * +\***************************************************************************/ + +extern void ARMul_ScheduleEvent(ARMul_State *state, unsigned long delay, unsigned (*func)() ) ; +extern void ARMul_EnvokeEvent(ARMul_State *state) ; +extern unsigned long ARMul_Time(ARMul_State *state) ; + +/***************************************************************************\ +* Useful support routines * +\***************************************************************************/ + +extern ARMword ARMul_GetReg(ARMul_State *state, unsigned mode, unsigned reg) ; +extern void ARMul_SetReg(ARMul_State *state, unsigned mode, unsigned reg, ARMword value) ; +extern ARMword ARMul_GetPC(ARMul_State *state) ; +extern ARMword ARMul_GetNextPC(ARMul_State *state) ; +extern void ARMul_SetPC(ARMul_State *state, ARMword value) ; +extern ARMword ARMul_GetR15(ARMul_State *state) ; +extern void ARMul_SetR15(ARMul_State *state, ARMword value) ; + +extern ARMword ARMul_GetCPSR(ARMul_State *state) ; +extern void ARMul_SetCPSR(ARMul_State *state, ARMword value) ; +extern ARMword ARMul_GetSPSR(ARMul_State *state, ARMword mode) ; +extern void ARMul_SetSPSR(ARMul_State *state, ARMword mode, ARMword value) ; + +/***************************************************************************\ +* Definitons of things to handle aborts * +\***************************************************************************/ + +extern void ARMul_Abort(ARMul_State *state, ARMword address) ; +#define ARMul_ABORTWORD 0xefffffff /* SWI -1 */ +#define ARMul_PREFETCHABORT(address) if (state->AbortAddr == 1) \ + state->AbortAddr = (address & ~3L) +#define ARMul_DATAABORT(address) state->abortSig = HIGH ; \ + state->Aborted = ARMul_DataAbortV ; +#define ARMul_CLEARABORT state->abortSig = LOW + +/***************************************************************************\ +* Definitons of things in the memory interface * +\***************************************************************************/ + +extern unsigned ARMul_MemoryInit(ARMul_State *state,unsigned long initmemsize) ; +extern void ARMul_MemoryExit(ARMul_State *state) ; + +extern ARMword ARMul_LoadInstrS(ARMul_State *state,ARMword address,ARMword isize) ; +extern ARMword ARMul_LoadInstrN(ARMul_State *state,ARMword address,ARMword isize) ; +extern ARMword ARMul_ReLoadInstr(ARMul_State *state,ARMword address,ARMword isize) ; + +extern ARMword ARMul_LoadWordS(ARMul_State *state,ARMword address) ; +extern ARMword ARMul_LoadWordN(ARMul_State *state,ARMword address) ; +extern ARMword ARMul_LoadHalfWord(ARMul_State *state,ARMword address) ; +extern ARMword ARMul_LoadByte(ARMul_State *state,ARMword address) ; + +extern void ARMul_StoreWordS(ARMul_State *state,ARMword address, ARMword data) ; +extern void ARMul_StoreWordN(ARMul_State *state,ARMword address, ARMword data) ; +extern void ARMul_StoreHalfWord(ARMul_State *state,ARMword address, ARMword data) ; +extern void ARMul_StoreByte(ARMul_State *state,ARMword address, ARMword data) ; + +extern ARMword ARMul_SwapWord(ARMul_State *state,ARMword address, ARMword data) ; +extern ARMword ARMul_SwapByte(ARMul_State *state,ARMword address, ARMword data) ; + +extern void ARMul_Icycles(ARMul_State *state,unsigned number, ARMword address) ; +extern void ARMul_Ccycles(ARMul_State *state,unsigned number, ARMword address) ; + +extern ARMword ARMul_ReadWord(ARMul_State *state,ARMword address) ; +extern ARMword ARMul_ReadByte(ARMul_State *state,ARMword address) ; +extern void ARMul_WriteWord(ARMul_State *state,ARMword address, ARMword data) ; +extern void ARMul_WriteByte(ARMul_State *state,ARMword address, ARMword data) ; + +extern ARMword ARMul_MemAccess(ARMul_State *state,ARMword,ARMword,ARMword, + ARMword,ARMword,ARMword,ARMword,ARMword,ARMword,ARMword) ; + +/***************************************************************************\ +* Definitons of things in the co-processor interface * +\***************************************************************************/ + +#define ARMul_FIRST 0 +#define ARMul_TRANSFER 1 +#define ARMul_BUSY 2 +#define ARMul_DATA 3 +#define ARMul_INTERRUPT 4 +#define ARMul_DONE 0 +#define ARMul_CANT 1 +#define ARMul_INC 3 + +extern unsigned ARMul_CoProInit(ARMul_State *state) ; +extern void ARMul_CoProExit(ARMul_State *state) ; +extern void ARMul_CoProAttach(ARMul_State *state, unsigned number, + ARMul_CPInits *init, ARMul_CPExits *exit, + ARMul_LDCs *ldc, ARMul_STCs *stc, + ARMul_MRCs *mrc, ARMul_MCRs *mcr, + ARMul_CDPs *cdp, + ARMul_CPReads *read, ARMul_CPWrites *write) ; +extern void ARMul_CoProDetach(ARMul_State *state, unsigned number) ; + +/***************************************************************************\ +* Definitons of things in the host environment * +\***************************************************************************/ + +extern unsigned ARMul_OSInit(ARMul_State *state) ; +extern void ARMul_OSExit(ARMul_State *state) ; +extern unsigned ARMul_OSHandleSWI(ARMul_State *state,ARMword number) ; +extern ARMword ARMul_OSLastErrorP(ARMul_State *state) ; + +extern ARMword ARMul_Debug(ARMul_State *state, ARMword pc, ARMword instr) ; +extern unsigned ARMul_OSException(ARMul_State *state, ARMword vector, ARMword pc) ; +extern int rdi_log ; + +/***************************************************************************\ +* Host-dependent stuff * +\***************************************************************************/ + +#ifdef macintosh +pascal void SpinCursor(short increment); /* copied from CursorCtl.h */ +# define HOURGLASS SpinCursor( 1 ) +# define HOURGLASS_RATE 1023 /* 2^n - 1 */ +#endif + diff --git a/sim/arm/armemu.c b/sim/arm/armemu.c new file mode 100644 index 0000000..171f1c8 --- /dev/null +++ b/sim/arm/armemu.c @@ -0,0 +1,3454 @@ +/* armemu.c -- Main instruction emulation: ARM7 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + Modifications to add arch. v4 support by <jsmith@cygnus.com>. + + 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 "armdefs.h" +#include "armemu.h" + +static ARMword GetDPRegRHS(ARMul_State *state, ARMword instr) ; +static ARMword GetDPSRegRHS(ARMul_State *state, ARMword instr) ; +static void WriteR15(ARMul_State *state, ARMword src) ; +static void WriteSR15(ARMul_State *state, ARMword src) ; +static ARMword GetLSRegRHS(ARMul_State *state, ARMword instr) ; +static ARMword GetLS7RHS(ARMul_State *state, ARMword instr) ; +static unsigned LoadWord(ARMul_State *state, ARMword instr, ARMword address) ; +static unsigned LoadHalfWord(ARMul_State *state, ARMword instr, ARMword address,int signextend) ; +static unsigned LoadByte(ARMul_State *state, ARMword instr, ARMword address,int signextend) ; +static unsigned StoreWord(ARMul_State *state, ARMword instr, ARMword address) ; +static unsigned StoreHalfWord(ARMul_State *state, ARMword instr, ARMword address) ; +static unsigned StoreByte(ARMul_State *state, ARMword instr, ARMword address) ; +static void LoadMult(ARMul_State *state, ARMword address, ARMword instr, ARMword WBBase) ; +static void StoreMult(ARMul_State *state, ARMword address, ARMword instr, ARMword WBBase) ; +static void LoadSMult(ARMul_State *state, ARMword address, ARMword instr, ARMword WBBase) ; +static void StoreSMult(ARMul_State *state, ARMword address, ARMword instr, ARMword WBBase) ; +static unsigned Multiply64(ARMul_State *state, ARMword instr,int signextend,int scc) ; +static unsigned MultiplyAdd64(ARMul_State *state, ARMword instr,int signextend,int scc) ; + +#define LUNSIGNED (0) /* unsigned operation */ +#define LSIGNED (1) /* signed operation */ +#define LDEFAULT (0) /* default : do nothing */ +#define LSCC (1) /* set condition codes on result */ + +/***************************************************************************\ +* short-hand macros for LDR/STR * +\***************************************************************************/ + +/* store post decrement writeback */ +#define SHDOWNWB() \ + lhs = LHS ; \ + if (StoreHalfWord(state, instr, lhs)) \ + LSBase = lhs - GetLS7RHS(state, instr) ; + +/* store post increment writeback */ +#define SHUPWB() \ + lhs = LHS ; \ + if (StoreHalfWord(state, instr, lhs)) \ + LSBase = lhs + GetLS7RHS(state, instr) ; + +/* store pre decrement */ +#define SHPREDOWN() \ + (void)StoreHalfWord(state, instr, LHS - GetLS7RHS(state, instr)) ; + +/* store pre decrement writeback */ +#define SHPREDOWNWB() \ + temp = LHS - GetLS7RHS(state, instr) ; \ + if (StoreHalfWord(state, instr, temp)) \ + LSBase = temp ; + +/* store pre increment */ +#define SHPREUP() \ + (void)StoreHalfWord(state, instr, LHS + GetLS7RHS(state, instr)) ; + +/* store pre increment writeback */ +#define SHPREUPWB() \ + temp = LHS + GetLS7RHS(state, instr) ; \ + if (StoreHalfWord(state, instr, temp)) \ + LSBase = temp ; + +/* load post decrement writeback */ +#define LHPOSTDOWN() \ +{ \ + int done = 1 ; \ + lhs = LHS ; \ + switch (BITS(5,6)) { \ + case 1: /* H */ \ + if (LoadHalfWord(state,instr,lhs,LUNSIGNED)) \ + LSBase = lhs - GetLS7RHS(state,instr) ; \ + break ; \ + case 2: /* SB */ \ + if (LoadByte(state,instr,lhs,LSIGNED)) \ + LSBase = lhs - GetLS7RHS(state,instr) ; \ + break ; \ + case 3: /* SH */ \ + if (LoadHalfWord(state,instr,lhs,LSIGNED)) \ + LSBase = lhs - GetLS7RHS(state,instr) ; \ + break ; \ + case 0: /* SWP handled elsewhere */ \ + default: \ + done = 0 ; \ + break ; \ + } \ + if (done) \ + break ; \ +} + +/* load post increment writeback */ +#define LHPOSTUP() \ +{ \ + int done = 1 ; \ + lhs = LHS ; \ + switch (BITS(5,6)) { \ + case 1: /* H */ \ + if (LoadHalfWord(state,instr,lhs,LUNSIGNED)) \ + LSBase = lhs + GetLS7RHS(state,instr) ; \ + break ; \ + case 2: /* SB */ \ + if (LoadByte(state,instr,lhs,LSIGNED)) \ + LSBase = lhs + GetLS7RHS(state,instr) ; \ + break ; \ + case 3: /* SH */ \ + if (LoadHalfWord(state,instr,lhs,LSIGNED)) \ + LSBase = lhs + GetLS7RHS(state,instr) ; \ + break ; \ + case 0: /* SWP handled elsewhere */ \ + default: \ + done = 0 ; \ + break ; \ + } \ + if (done) \ + break ; \ +} + +/* load pre decrement */ +#define LHPREDOWN() \ +{ \ + int done = 1 ; \ + temp = LHS - GetLS7RHS(state,instr) ; \ + switch (BITS(5,6)) { \ + case 1: /* H */ \ + (void)LoadHalfWord(state,instr,temp,LUNSIGNED) ; \ + break ; \ + case 2: /* SB */ \ + (void)LoadByte(state,instr,temp,LSIGNED) ; \ + break ; \ + case 3: /* SH */ \ + (void)LoadHalfWord(state,instr,temp,LSIGNED) ; \ + break ; \ + case 0: /* SWP handled elsewhere */ \ + default: \ + done = 0 ; \ + break ; \ + } \ + if (done) \ + break ; \ +} + +/* load pre decrement writeback */ +#define LHPREDOWNWB() \ +{ \ + int done = 1 ; \ + temp = LHS - GetLS7RHS(state, instr) ; \ + switch (BITS(5,6)) { \ + case 1: /* H */ \ + if (LoadHalfWord(state,instr,temp,LUNSIGNED)) \ + LSBase = temp ; \ + break ; \ + case 2: /* SB */ \ + if (LoadByte(state,instr,temp,LSIGNED)) \ + LSBase = temp ; \ + break ; \ + case 3: /* SH */ \ + if (LoadHalfWord(state,instr,temp,LSIGNED)) \ + LSBase = temp ; \ + break ; \ + case 0: /* SWP handled elsewhere */ \ + default: \ + done = 0 ; \ + break ; \ + } \ + if (done) \ + break ; \ +} + +/* load pre increment */ +#define LHPREUP() \ +{ \ + int done = 1 ; \ + temp = LHS + GetLS7RHS(state,instr) ; \ + switch (BITS(5,6)) { \ + case 1: /* H */ \ + (void)LoadHalfWord(state,instr,temp,LUNSIGNED) ; \ + break ; \ + case 2: /* SB */ \ + (void)LoadByte(state,instr,temp,LSIGNED) ; \ + break ; \ + case 3: /* SH */ \ + (void)LoadHalfWord(state,instr,temp,LSIGNED) ; \ + break ; \ + case 0: /* SWP handled elsewhere */ \ + default: \ + done = 0 ; \ + break ; \ + } \ + if (done) \ + break ; \ +} + +/* load pre increment writeback */ +#define LHPREUPWB() \ +{ \ + int done = 1 ; \ + temp = LHS + GetLS7RHS(state, instr) ; \ + switch (BITS(5,6)) { \ + case 1: /* H */ \ + if (LoadHalfWord(state,instr,temp,LUNSIGNED)) \ + LSBase = temp ; \ + break ; \ + case 2: /* SB */ \ + if (LoadByte(state,instr,temp,LSIGNED)) \ + LSBase = temp ; \ + break ; \ + case 3: /* SH */ \ + if (LoadHalfWord(state,instr,temp,LSIGNED)) \ + LSBase = temp ; \ + break ; \ + case 0: /* SWP handled elsewhere */ \ + default: \ + done = 0 ; \ + break ; \ + } \ + if (done) \ + break ; \ +} + +/***************************************************************************\ +* EMULATION of ARM6 * +\***************************************************************************/ + +/* The PC pipeline value depends on whether ARM or Thumb instructions + are being executed: */ +ARMword isize; + +#ifdef MODE32 +ARMword ARMul_Emulate32(register ARMul_State *state) +{ +#else +ARMword ARMul_Emulate26(register ARMul_State *state) +{ +#endif + register ARMword instr, /* the current instruction */ + dest, /* almost the DestBus */ + temp, /* ubiquitous third hand */ + pc ; /* the address of the current instruction */ + ARMword lhs, rhs ; /* almost the ABus and BBus */ + ARMword decoded, loaded ; /* instruction pipeline */ + +/***************************************************************************\ +* Execute the next instruction * +\***************************************************************************/ + + if (state->NextInstr < PRIMEPIPE) { + decoded = state->decoded ; + loaded = state->loaded ; + pc = state->pc ; + } + + do { /* just keep going */ +#ifdef MODET + if (TFLAG) { + isize = 2; + } else +#endif + isize = 4; + switch (state->NextInstr) { + case SEQ : + state->Reg[15] += isize ; /* Advance the pipeline, and an S cycle */ + pc += isize ; + instr = decoded ; + decoded = loaded ; + loaded = ARMul_LoadInstrS(state,pc+(isize * 2),isize) ; + break ; + + case NONSEQ : + state->Reg[15] += isize ; /* Advance the pipeline, and an N cycle */ + pc += isize ; + instr = decoded ; + decoded = loaded ; + loaded = ARMul_LoadInstrN(state,pc+(isize * 2),isize) ; + NORMALCYCLE ; + break ; + + case PCINCEDSEQ : + pc += isize ; /* Program counter advanced, and an S cycle */ + instr = decoded ; + decoded = loaded ; + loaded = ARMul_LoadInstrS(state,pc+(isize * 2),isize) ; + NORMALCYCLE ; + break ; + + case PCINCEDNONSEQ : + pc += isize ; /* Program counter advanced, and an N cycle */ + instr = decoded ; + decoded = loaded ; + loaded = ARMul_LoadInstrN(state,pc+(isize * 2),isize) ; + NORMALCYCLE ; + break ; + + case RESUME : /* The program counter has been changed */ + pc = state->Reg[15] ; +#ifndef MODE32 + pc = pc & R15PCBITS ; +#endif + state->Reg[15] = pc + (isize * 2) ; + state->Aborted = 0 ; + instr = ARMul_ReLoadInstr(state,pc,isize) ; + decoded = ARMul_ReLoadInstr(state,pc + isize,isize) ; + loaded = ARMul_ReLoadInstr(state,pc + isize * 2,isize) ; + NORMALCYCLE ; + break ; + + default : /* The program counter has been changed */ + pc = state->Reg[15] ; +#ifndef MODE32 + pc = pc & R15PCBITS ; +#endif + state->Reg[15] = pc + (isize * 2) ; + state->Aborted = 0 ; + instr = ARMul_LoadInstrN(state,pc,isize) ; + decoded = ARMul_LoadInstrS(state,pc + (isize),isize) ; + loaded = ARMul_LoadInstrS(state,pc + (isize * 2),isize) ; + NORMALCYCLE ; + break ; + } + if (state->EventSet) + ARMul_EnvokeEvent(state) ; + +#if 0 + /* Enable this for a helpful bit of debugging when tracing is needed. */ + fprintf (stderr, "pc: %x, instr: %x\n", pc & ~1, instr); + if (instr == 0) abort (); +#endif + + if (state->Exception) { /* Any exceptions */ + if (state->NresetSig == LOW) { + ARMul_Abort(state,ARMul_ResetV) ; + break ; + } + else if (!state->NfiqSig && !FFLAG) { + ARMul_Abort(state,ARMul_FIQV) ; + break ; + } + else if (!state->NirqSig && !IFLAG) { + ARMul_Abort(state,ARMul_IRQV) ; + break ; + } + } + + if (state->CallDebug > 0) { + instr = ARMul_Debug(state,pc,instr) ; + if (state->Emulate < ONCE) { + state->NextInstr = RESUME ; + break ; + } + if (state->Debug) { + fprintf(stderr,"At %08lx Instr %08lx Mode %02lx\n",pc,instr,state->Mode) ; + (void)fgetc(stdin) ; + } + } + else + if (state->Emulate < ONCE) { + state->NextInstr = RESUME ; + break ; + } + + state->NumInstrs++ ; + +#ifdef MODET + /* Provide Thumb instruction decoding. If the processor is in Thumb + mode, then we can simply decode the Thumb instruction, and map it + to the corresponding ARM instruction (by directly loading the + instr variable, and letting the normal ARM simulator + execute). There are some caveats to ensure that the correct + pipelined PC value is used when executing Thumb code, and also for + dealing with the BL instruction. */ + if (TFLAG) { /* check if in Thumb mode */ + ARMword new; + switch (ARMul_ThumbDecode(state,pc,instr,&new)) { + case t_undefined: + ARMul_UndefInstr(state,instr); /* This is a Thumb instruction */ + break; + + case t_branch: /* already processed */ + goto donext; + + case t_decoded: /* ARM instruction available */ + instr = new; /* so continue instruction decoding */ + break; + } + } +#endif + +/***************************************************************************\ +* Check the condition codes * +\***************************************************************************/ + if ((temp = TOPBITS(28)) == AL) + goto mainswitch ; /* vile deed in the need for speed */ + + switch ((int)TOPBITS(28)) { /* check the condition code */ + case AL : temp=TRUE ; + break ; + case NV : temp=FALSE ; + break ; + case EQ : temp=ZFLAG ; + break ; + case NE : temp=!ZFLAG ; + break ; + case VS : temp=VFLAG ; + break ; + case VC : temp=!VFLAG ; + break ; + case MI : temp=NFLAG ; + break ; + case PL : temp=!NFLAG ; + break ; + case CS : temp=CFLAG ; + break ; + case CC : temp=!CFLAG ; + break ; + case HI : temp=(CFLAG && !ZFLAG) ; + break ; + case LS : temp=(!CFLAG || ZFLAG) ; + break ; + case GE : temp=((!NFLAG && !VFLAG) || (NFLAG && VFLAG)) ; + break ; + case LT : temp=((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) ; + break ; + case GT : temp=((!NFLAG && !VFLAG && !ZFLAG) || (NFLAG && VFLAG && !ZFLAG)) ; + break ; + case LE : temp=((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG ; + break ; + } /* cc check */ + +/***************************************************************************\ +* Actual execution of instructions begins here * +\***************************************************************************/ + + if (temp) { /* if the condition codes don't match, stop here */ +mainswitch: + + switch ((int)BITS(20,27)) { + +/***************************************************************************\ +* Data Processing Register RHS Instructions * +\***************************************************************************/ + + case 0x00 : /* AND reg and MUL */ +#ifdef MODET + if (BITS(4,11) == 0xB) { + /* STRH register offset, no write-back, down, post indexed */ + SHDOWNWB() ; + break ; + } + /* TODO: CHECK: should 0xD and 0xF generate undefined intruction aborts? */ +#endif + if (BITS(4,7) == 9) { /* MUL */ + rhs = state->Reg[MULRHSReg] ; + if (MULLHSReg == MULDESTReg) { + UNDEF_MULDestEQOp1 ; + state->Reg[MULDESTReg] = 0 ; + } + else if (MULDESTReg != 15) + state->Reg[MULDESTReg] = state->Reg[MULLHSReg] * rhs ; + else { + UNDEF_MULPCDest ; + } + for (dest = 0, temp = 0 ; dest < 32 ; dest++) + if (rhs & (1L << dest)) + temp = dest ; /* mult takes this many/2 I cycles */ + ARMul_Icycles(state,ARMul_MultTable[temp],0L) ; + } + else { /* AND reg */ + rhs = DPRegRHS ; + dest = LHS & rhs ; + WRITEDEST(dest) ; + } + break ; + + case 0x01 : /* ANDS reg and MULS */ +#ifdef MODET + if ((BITS(4,11) & 0xF9) == 0x9) { + /* LDR register offset, no write-back, down, post indexed */ + LHPOSTDOWN() ; + /* fall through to rest of decoding */ + } +#endif + if (BITS(4,7) == 9) { /* MULS */ + rhs = state->Reg[MULRHSReg] ; + if (MULLHSReg == MULDESTReg) { + UNDEF_MULDestEQOp1 ; + state->Reg[MULDESTReg] = 0 ; + CLEARN ; + SETZ ; + } + else if (MULDESTReg != 15) { + dest = state->Reg[MULLHSReg] * rhs ; + ARMul_NegZero(state,dest) ; + state->Reg[MULDESTReg] = dest ; + } + else { + UNDEF_MULPCDest ; + } + for (dest = 0, temp = 0 ; dest < 32 ; dest++) + if (rhs & (1L << dest)) + temp = dest ; /* mult takes this many/2 I cycles */ + ARMul_Icycles(state,ARMul_MultTable[temp],0L) ; + } + else { /* ANDS reg */ + rhs = DPSRegRHS ; + dest = LHS & rhs ; + WRITESDEST(dest) ; + } + break ; + + case 0x02 : /* EOR reg and MLA */ +#ifdef MODET + if (BITS(4,11) == 0xB) { + /* STRH register offset, write-back, down, post indexed */ + SHDOWNWB() ; + break ; + } +#endif + if (BITS(4,7) == 9) { /* MLA */ + rhs = state->Reg[MULRHSReg] ; + if (MULLHSReg == MULDESTReg) { + UNDEF_MULDestEQOp1 ; + state->Reg[MULDESTReg] = state->Reg[MULACCReg] ; + } + else if (MULDESTReg != 15) + state->Reg[MULDESTReg] = state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg] ; + else { + UNDEF_MULPCDest ; + } + for (dest = 0, temp = 0 ; dest < 32 ; dest++) + if (rhs & (1L << dest)) + temp = dest ; /* mult takes this many/2 I cycles */ + ARMul_Icycles(state,ARMul_MultTable[temp],0L) ; + } + else { + rhs = DPRegRHS ; + dest = LHS ^ rhs ; + WRITEDEST(dest) ; + } + break ; + + case 0x03 : /* EORS reg and MLAS */ +#ifdef MODET + if ((BITS(4,11) & 0xF9) == 0x9) { + /* LDR register offset, write-back, down, post-indexed */ + LHPOSTDOWN() ; + /* fall through to rest of the decoding */ + } +#endif + if (BITS(4,7) == 9) { /* MLAS */ + rhs = state->Reg[MULRHSReg] ; + if (MULLHSReg == MULDESTReg) { + UNDEF_MULDestEQOp1 ; + dest = state->Reg[MULACCReg] ; + ARMul_NegZero(state,dest) ; + state->Reg[MULDESTReg] = dest ; + } + else if (MULDESTReg != 15) { + dest = state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg] ; + ARMul_NegZero(state,dest) ; + state->Reg[MULDESTReg] = dest ; + } + else { + UNDEF_MULPCDest ; + } + for (dest = 0, temp = 0 ; dest < 32 ; dest++) + if (rhs & (1L << dest)) + temp = dest ; /* mult takes this many/2 I cycles */ + ARMul_Icycles(state,ARMul_MultTable[temp],0L) ; + } + else { /* EORS Reg */ + rhs = DPSRegRHS ; + dest = LHS ^ rhs ; + WRITESDEST(dest) ; + } + break ; + + case 0x04 : /* SUB reg */ +#ifdef MODET + if (BITS(4,7) == 0xB) { + /* STRH immediate offset, no write-back, down, post indexed */ + SHDOWNWB() ; + break ; + } +#endif + rhs = DPRegRHS; + dest = LHS - rhs ; + WRITEDEST(dest) ; + break ; + + case 0x05 : /* SUBS reg */ +#ifdef MODET + if ((BITS(4,7) & 0x9) == 0x9) { + /* LDR immediate offset, no write-back, down, post indexed */ + LHPOSTDOWN() ; + /* fall through to the rest of the instruction decoding */ + } +#endif + lhs = LHS ; + rhs = DPRegRHS ; + dest = lhs - rhs ; + if ((lhs >= rhs) || ((rhs | lhs) >> 31)) { + ARMul_SubCarry(state,lhs,rhs,dest) ; + ARMul_SubOverflow(state,lhs,rhs,dest) ; + } + else { + CLEARC ; + CLEARV ; + } + WRITESDEST(dest) ; + break ; + + case 0x06 : /* RSB reg */ +#ifdef MODET + if (BITS(4,7) == 0xB) { + /* STRH immediate offset, write-back, down, post indexed */ + SHDOWNWB() ; + break ; + } +#endif + rhs = DPRegRHS ; + dest = rhs - LHS ; + WRITEDEST(dest) ; + break ; + + case 0x07 : /* RSBS reg */ +#ifdef MODET + if ((BITS(4,7) & 0x9) == 0x9) { + /* LDR immediate offset, write-back, down, post indexed */ + LHPOSTDOWN() ; + /* fall through to remainder of instruction decoding */ + } +#endif + lhs = LHS ; + rhs = DPRegRHS ; + dest = rhs - lhs ; + if ((rhs >= lhs) || ((rhs | lhs) >> 31)) { + ARMul_SubCarry(state,rhs,lhs,dest) ; + ARMul_SubOverflow(state,rhs,lhs,dest) ; + } + else { + CLEARC ; + CLEARV ; + } + WRITESDEST(dest) ; + break ; + + case 0x08 : /* ADD reg */ +#ifdef MODET + if (BITS(4,11) == 0xB) { + /* STRH register offset, no write-back, up, post indexed */ + SHUPWB() ; + break ; + } +#endif +#ifdef MODET + if (BITS(4,7) == 0x9) { /* MULL */ + /* 32x32 = 64 */ + ARMul_Icycles(state,Multiply64(state,instr,LUNSIGNED,LDEFAULT),0L) ; + break ; + } +#endif + rhs = DPRegRHS ; + dest = LHS + rhs ; + WRITEDEST(dest) ; + break ; + + case 0x09 : /* ADDS reg */ +#ifdef MODET + if ((BITS(4,11) & 0xF9) == 0x9) { + /* LDR register offset, no write-back, up, post indexed */ + LHPOSTUP() ; + /* fall through to remaining instruction decoding */ + } +#endif +#ifdef MODET + if (BITS(4,7) == 0x9) { /* MULL */ + /* 32x32=64 */ + ARMul_Icycles(state,Multiply64(state,instr,LUNSIGNED,LSCC),0L) ; + break ; + } +#endif + lhs = LHS ; + rhs = DPRegRHS ; + dest = lhs + rhs ; + ASSIGNZ(dest==0) ; + if ((lhs | rhs) >> 30) { /* possible C,V,N to set */ + ASSIGNN(NEG(dest)) ; + ARMul_AddCarry(state,lhs,rhs,dest) ; + ARMul_AddOverflow(state,lhs,rhs,dest) ; + } + else { + CLEARN ; + CLEARC ; + CLEARV ; + } + WRITESDEST(dest) ; + break ; + + case 0x0a : /* ADC reg */ +#ifdef MODET + if (BITS(4,11) == 0xB) { + /* STRH register offset, write-back, up, post-indexed */ + SHUPWB() ; + break ; + } +#endif +#ifdef MODET + if (BITS(4,7) == 0x9) { /* MULL */ + /* 32x32=64 */ + ARMul_Icycles(state,MultiplyAdd64(state,instr,LUNSIGNED,LDEFAULT),0L) ; + break ; + } +#endif + rhs = DPRegRHS ; + dest = LHS + rhs + CFLAG ; + WRITEDEST(dest) ; + break ; + + case 0x0b : /* ADCS reg */ +#ifdef MODET + if ((BITS(4,11) & 0xF9) == 0x9) { + /* LDR register offset, write-back, up, post indexed */ + LHPOSTUP() ; + /* fall through to remaining instruction decoding */ + } +#endif +#ifdef MODET + if (BITS(4,7) == 0x9) { /* MULL */ + /* 32x32=64 */ + ARMul_Icycles(state,MultiplyAdd64(state,instr,LUNSIGNED,LSCC),0L) ; + break ; + } +#endif + lhs = LHS ; + rhs = DPRegRHS ; + dest = lhs + rhs + CFLAG ; + ASSIGNZ(dest==0) ; + if ((lhs | rhs) >> 30) { /* possible C,V,N to set */ + ASSIGNN(NEG(dest)) ; + ARMul_AddCarry(state,lhs,rhs,dest) ; + ARMul_AddOverflow(state,lhs,rhs,dest) ; + } + else { + CLEARN ; + CLEARC ; + CLEARV ; + } + WRITESDEST(dest) ; + break ; + + case 0x0c : /* SBC reg */ +#ifdef MODET + if (BITS(4,7) == 0xB) { + /* STRH immediate offset, no write-back, up post indexed */ + SHUPWB() ; + break ; + } +#endif +#ifdef MODET + if (BITS(4,7) == 0x9) { /* MULL */ + /* 32x32=64 */ + ARMul_Icycles(state,Multiply64(state,instr,LSIGNED,LDEFAULT),0L) ; + break ; + } +#endif + rhs = DPRegRHS ; + dest = LHS - rhs - !CFLAG ; + WRITEDEST(dest) ; + break ; + + case 0x0d : /* SBCS reg */ +#ifdef MODET + if ((BITS(4,7) & 0x9) == 0x9) { + /* LDR immediate offset, no write-back, up, post indexed */ + LHPOSTUP() ; + } +#endif +#ifdef MODET + if (BITS(4,7) == 0x9) { /* MULL */ + /* 32x32=64 */ + ARMul_Icycles(state,Multiply64(state,instr,LSIGNED,LSCC),0L) ; + break ; + } +#endif + lhs = LHS ; + rhs = DPRegRHS ; + dest = lhs - rhs - !CFLAG ; + if ((lhs >= rhs) || ((rhs | lhs) >> 31)) { + ARMul_SubCarry(state,lhs,rhs,dest) ; + ARMul_SubOverflow(state,lhs,rhs,dest) ; + } + else { + CLEARC ; + CLEARV ; + } + WRITESDEST(dest) ; + break ; + + case 0x0e : /* RSC reg */ +#ifdef MODET + if (BITS(4,7) == 0xB) { + /* STRH immediate offset, write-back, up, post indexed */ + SHUPWB() ; + break ; + } +#endif +#ifdef MODET + if (BITS(4,7) == 0x9) { /* MULL */ + /* 32x32=64 */ + ARMul_Icycles(state,MultiplyAdd64(state,instr,LSIGNED,LDEFAULT),0L) ; + break ; + } +#endif + rhs = DPRegRHS ; + dest = rhs - LHS - !CFLAG ; + WRITEDEST(dest) ; + break ; + + case 0x0f : /* RSCS reg */ +#ifdef MODET + if ((BITS(4,7) & 0x9) == 0x9) { + /* LDR immediate offset, write-back, up, post indexed */ + LHPOSTUP() ; + /* fall through to remaining instruction decoding */ + } +#endif +#ifdef MODET + if (BITS(4,7) == 0x9) { /* MULL */ + /* 32x32=64 */ + ARMul_Icycles(state,MultiplyAdd64(state,instr,LSIGNED,LSCC),0L) ; + break ; + } +#endif + lhs = LHS ; + rhs = DPRegRHS ; + dest = rhs - lhs - !CFLAG ; + if ((rhs >= lhs) || ((rhs | lhs) >> 31)) { + ARMul_SubCarry(state,rhs,lhs,dest) ; + ARMul_SubOverflow(state,rhs,lhs,dest) ; + } + else { + CLEARC ; + CLEARV ; + } + WRITESDEST(dest) ; + break ; + + case 0x10 : /* TST reg and MRS CPSR and SWP word */ +#ifdef MODET + if (BITS(4,11) == 0xB) { + /* STRH register offset, no write-back, down, pre indexed */ + SHPREDOWN() ; + break ; + } +#endif + if (BITS(4,11) == 9) { /* SWP */ + UNDEF_SWPPC ; + temp = LHS ; + BUSUSEDINCPCS ; +#ifndef MODE32 + if (VECTORACCESS(temp) || ADDREXCEPT(temp)) { + INTERNALABORT(temp) ; + (void)ARMul_LoadWordN(state,temp) ; + (void)ARMul_LoadWordN(state,temp) ; + } + else +#endif + dest = ARMul_SwapWord(state,temp,state->Reg[RHSReg]) ; + if (temp & 3) + DEST = ARMul_Align(state,temp,dest) ; + else + DEST = dest ; + if (state->abortSig || state->Aborted) { + TAKEABORT ; + } + } + else if ((BITS(0,11)==0) && (LHSReg==15)) { /* MRS CPSR */ + UNDEF_MRSPC ; + DEST = ECC | EINT | EMODE ; + } + else { + UNDEF_Test ; + } + break ; + + case 0x11 : /* TSTP reg */ +#ifdef MODET + if ((BITS(4,11) & 0xF9) == 0x9) { + /* LDR register offset, no write-back, down, pre indexed */ + LHPREDOWN() ; + /* continue with remaining instruction decode */ + } +#endif + if (DESTReg == 15) { /* TSTP reg */ +#ifdef MODE32 + state->Cpsr = GETSPSR(state->Bank) ; + ARMul_CPSRAltered(state) ; +#else + rhs = DPRegRHS ; + temp = LHS & rhs ; + SETR15PSR(temp) ; +#endif + } + else { /* TST reg */ + rhs = DPSRegRHS ; + dest = LHS & rhs ; + ARMul_NegZero(state,dest) ; + } + break ; + + case 0x12 : /* TEQ reg and MSR reg to CPSR (ARM6) */ +#ifdef MODET + if (BITS(4,11) == 0xB) { + /* STRH register offset, write-back, down, pre indexed */ + SHPREDOWNWB() ; + break ; + } +#endif +#ifdef MODET + if (BITS(4,27)==0x12FFF1) { /* BX */ + /* Branch to the address in RHSReg. If bit0 of + destination address is 1 then switch to Thumb mode: */ + ARMword addr = state->Reg[RHSReg]; + + /* If we read the PC then the bottom bit is clear */ + if (RHSReg == 15) addr &= ~1; + + /* Enable this for a helpful bit of debugging when + GDB is not yet fully working... + fprintf (stderr, "BX at %x to %x (go %s)\n", + state->Reg[15], addr, (addr & 1) ? "thumb": "arm" ); */ + + if (addr & (1 << 0)) { /* Thumb bit */ + SETT; + state->Reg[15] = addr & 0xfffffffe; + /* NOTE: The other CPSR flag setting blocks do not + seem to update the state->Cpsr state, but just do + the explicit flag. The copy from the seperate + flags to the register must happen later. */ + FLUSHPIPE; + } else { + CLEART; + state->Reg[15] = addr & 0xfffffffc; + FLUSHPIPE; + } + } +#endif + if (DESTReg==15 && BITS(17,18)==0) { /* MSR reg to CPSR */ + UNDEF_MSRPC ; + temp = DPRegRHS ; + ARMul_FixCPSR(state,instr,temp) ; + } + else { + UNDEF_Test ; + } + break ; + + case 0x13 : /* TEQP reg */ +#ifdef MODET + if ((BITS(4,11) & 0xF9) == 0x9) { + /* LDR register offset, write-back, down, pre indexed */ + LHPREDOWNWB() ; + /* continue with remaining instruction decode */ + } +#endif + if (DESTReg == 15) { /* TEQP reg */ +#ifdef MODE32 + state->Cpsr = GETSPSR(state->Bank) ; + ARMul_CPSRAltered(state) ; +#else + rhs = DPRegRHS ; + temp = LHS ^ rhs ; + SETR15PSR(temp) ; +#endif + } + else { /* TEQ Reg */ + rhs = DPSRegRHS ; + dest = LHS ^ rhs ; + ARMul_NegZero(state,dest) ; + } + break ; + + case 0x14 : /* CMP reg and MRS SPSR and SWP byte */ +#ifdef MODET + if (BITS(4,7) == 0xB) { + /* STRH immediate offset, no write-back, down, pre indexed */ + SHPREDOWN() ; + break ; + } +#endif + if (BITS(4,11) == 9) { /* SWP */ + UNDEF_SWPPC ; + temp = LHS ; + BUSUSEDINCPCS ; +#ifndef MODE32 + if (VECTORACCESS(temp) || ADDREXCEPT(temp)) { + INTERNALABORT(temp) ; + (void)ARMul_LoadByte(state,temp) ; + (void)ARMul_LoadByte(state,temp) ; + } + else +#endif + DEST = ARMul_SwapByte(state,temp,state->Reg[RHSReg]) ; + if (state->abortSig || state->Aborted) { + TAKEABORT ; + } + } + else if ((BITS(0,11)==0) && (LHSReg==15)) { /* MRS SPSR */ + UNDEF_MRSPC ; + DEST = GETSPSR(state->Bank) ; + } + else { + UNDEF_Test ; + } + break ; + + case 0x15 : /* CMPP reg */ +#ifdef MODET + if ((BITS(4,7) & 0x9) == 0x9) { + /* LDR immediate offset, no write-back, down, pre indexed */ + LHPREDOWN() ; + /* continue with remaining instruction decode */ + } +#endif + if (DESTReg == 15) { /* CMPP reg */ +#ifdef MODE32 + state->Cpsr = GETSPSR(state->Bank) ; + ARMul_CPSRAltered(state) ; +#else + rhs = DPRegRHS ; + temp = LHS - rhs ; + SETR15PSR(temp) ; +#endif + } + else { /* CMP reg */ + lhs = LHS ; + rhs = DPRegRHS ; + dest = lhs - rhs ; + ARMul_NegZero(state,dest) ; + if ((lhs >= rhs) || ((rhs | lhs) >> 31)) { + ARMul_SubCarry(state,lhs,rhs,dest) ; + ARMul_SubOverflow(state,lhs,rhs,dest) ; + } + else { + CLEARC ; + CLEARV ; + } + } + break ; + + case 0x16 : /* CMN reg and MSR reg to SPSR */ +#ifdef MODET + if (BITS(4,7) == 0xB) { + /* STRH immediate offset, write-back, down, pre indexed */ + SHPREDOWNWB() ; + break ; + } +#endif + if (DESTReg==15 && BITS(17,18)==0) { /* MSR */ + UNDEF_MSRPC ; + ARMul_FixSPSR(state,instr,DPRegRHS); + } + else { + UNDEF_Test ; + } + break ; + + case 0x17 : /* CMNP reg */ +#ifdef MODET + if ((BITS(4,7) & 0x9) == 0x9) { + /* LDR immediate offset, write-back, down, pre indexed */ + LHPREDOWNWB() ; + /* continue with remaining instruction decoding */ + } +#endif + if (DESTReg == 15) { +#ifdef MODE32 + state->Cpsr = GETSPSR(state->Bank) ; + ARMul_CPSRAltered(state) ; +#else + rhs = DPRegRHS ; + temp = LHS + rhs ; + SETR15PSR(temp) ; +#endif + break ; + } + else { /* CMN reg */ + lhs = LHS ; + rhs = DPRegRHS ; + dest = lhs + rhs ; + ASSIGNZ(dest==0) ; + if ((lhs | rhs) >> 30) { /* possible C,V,N to set */ + ASSIGNN(NEG(dest)) ; + ARMul_AddCarry(state,lhs,rhs,dest) ; + ARMul_AddOverflow(state,lhs,rhs,dest) ; + } + else { + CLEARN ; + CLEARC ; + CLEARV ; + } + } + break ; + + case 0x18 : /* ORR reg */ +#ifdef MODET + if (BITS(4,11) == 0xB) { + /* STRH register offset, no write-back, up, pre indexed */ + SHPREUP() ; + break ; + } +#endif + rhs = DPRegRHS ; + dest = LHS | rhs ; + WRITEDEST(dest) ; + break ; + + case 0x19 : /* ORRS reg */ +#ifdef MODET + if ((BITS(4,11) & 0xF9) == 0x9) { + /* LDR register offset, no write-back, up, pre indexed */ + LHPREUP() ; + /* continue with remaining instruction decoding */ + } +#endif + rhs = DPSRegRHS ; + dest = LHS | rhs ; + WRITESDEST(dest) ; + break ; + + case 0x1a : /* MOV reg */ +#ifdef MODET + if (BITS(4,11) == 0xB) { + /* STRH register offset, write-back, up, pre indexed */ + SHPREUPWB() ; + break ; + } +#endif + dest = DPRegRHS ; + WRITEDEST(dest) ; + break ; + + case 0x1b : /* MOVS reg */ +#ifdef MODET + if ((BITS(4,11) & 0xF9) == 0x9) { + /* LDR register offset, write-back, up, pre indexed */ + LHPREUPWB() ; + /* continue with remaining instruction decoding */ + } +#endif + dest = DPSRegRHS ; + WRITESDEST(dest) ; + break ; + + case 0x1c : /* BIC reg */ +#ifdef MODET + if (BITS(4,7) == 0xB) { + /* STRH immediate offset, no write-back, up, pre indexed */ + SHPREUP() ; + break ; + } +#endif + rhs = DPRegRHS ; + dest = LHS & ~rhs ; + WRITEDEST(dest) ; + break ; + + case 0x1d : /* BICS reg */ +#ifdef MODET + if ((BITS(4,7) & 0x9) == 0x9) { + /* LDR immediate offset, no write-back, up, pre indexed */ + LHPREUP() ; + /* continue with instruction decoding */ + } +#endif + rhs = DPSRegRHS ; + dest = LHS & ~rhs ; + WRITESDEST(dest) ; + break ; + + case 0x1e : /* MVN reg */ +#ifdef MODET + if (BITS(4,7) == 0xB) { + /* STRH immediate offset, write-back, up, pre indexed */ + SHPREUPWB() ; + break ; + } +#endif + dest = ~DPRegRHS ; + WRITEDEST(dest) ; + break ; + + case 0x1f : /* MVNS reg */ +#ifdef MODET + if ((BITS(4,7) & 0x9) == 0x9) { + /* LDR immediate offset, write-back, up, pre indexed */ + LHPREUPWB() ; + /* continue instruction decoding */ + } +#endif + dest = ~DPSRegRHS ; + WRITESDEST(dest) ; + break ; + +/***************************************************************************\ +* Data Processing Immediate RHS Instructions * +\***************************************************************************/ + + case 0x20 : /* AND immed */ + dest = LHS & DPImmRHS ; + WRITEDEST(dest) ; + break ; + + case 0x21 : /* ANDS immed */ + DPSImmRHS ; + dest = LHS & rhs ; + WRITESDEST(dest) ; + break ; + + case 0x22 : /* EOR immed */ + dest = LHS ^ DPImmRHS ; + WRITEDEST(dest) ; + break ; + + case 0x23 : /* EORS immed */ + DPSImmRHS ; + dest = LHS ^ rhs ; + WRITESDEST(dest) ; + break ; + + case 0x24 : /* SUB immed */ + dest = LHS - DPImmRHS ; + WRITEDEST(dest) ; + break ; + + case 0x25 : /* SUBS immed */ + lhs = LHS ; + rhs = DPImmRHS ; + dest = lhs - rhs ; + if ((lhs >= rhs) || ((rhs | lhs) >> 31)) { + ARMul_SubCarry(state,lhs,rhs,dest) ; + ARMul_SubOverflow(state,lhs,rhs,dest) ; + } + else { + CLEARC ; + CLEARV ; + } + WRITESDEST(dest) ; + break ; + + case 0x26 : /* RSB immed */ + dest = DPImmRHS - LHS ; + WRITEDEST(dest) ; + break ; + + case 0x27 : /* RSBS immed */ + lhs = LHS ; + rhs = DPImmRHS ; + dest = rhs - lhs ; + if ((rhs >= lhs) || ((rhs | lhs) >> 31)) { + ARMul_SubCarry(state,rhs,lhs,dest) ; + ARMul_SubOverflow(state,rhs,lhs,dest) ; + } + else { + CLEARC ; + CLEARV ; + } + WRITESDEST(dest) ; + break ; + + case 0x28 : /* ADD immed */ + dest = LHS + DPImmRHS ; + WRITEDEST(dest) ; + break ; + + case 0x29 : /* ADDS immed */ + lhs = LHS ; + rhs = DPImmRHS ; + dest = lhs + rhs ; + ASSIGNZ(dest==0) ; + if ((lhs | rhs) >> 30) { /* possible C,V,N to set */ + ASSIGNN(NEG(dest)) ; + ARMul_AddCarry(state,lhs,rhs,dest) ; + ARMul_AddOverflow(state,lhs,rhs,dest) ; + } + else { + CLEARN ; + CLEARC ; + CLEARV ; + } + WRITESDEST(dest) ; + break ; + + case 0x2a : /* ADC immed */ + dest = LHS + DPImmRHS + CFLAG ; + WRITEDEST(dest) ; + break ; + + case 0x2b : /* ADCS immed */ + lhs = LHS ; + rhs = DPImmRHS ; + dest = lhs + rhs + CFLAG ; + ASSIGNZ(dest==0) ; + if ((lhs | rhs) >> 30) { /* possible C,V,N to set */ + ASSIGNN(NEG(dest)) ; + ARMul_AddCarry(state,lhs,rhs,dest) ; + ARMul_AddOverflow(state,lhs,rhs,dest) ; + } + else { + CLEARN ; + CLEARC ; + CLEARV ; + } + WRITESDEST(dest) ; + break ; + + case 0x2c : /* SBC immed */ + dest = LHS - DPImmRHS - !CFLAG ; + WRITEDEST(dest) ; + break ; + + case 0x2d : /* SBCS immed */ + lhs = LHS ; + rhs = DPImmRHS ; + dest = lhs - rhs - !CFLAG ; + if ((lhs >= rhs) || ((rhs | lhs) >> 31)) { + ARMul_SubCarry(state,lhs,rhs,dest) ; + ARMul_SubOverflow(state,lhs,rhs,dest) ; + } + else { + CLEARC ; + CLEARV ; + } + WRITESDEST(dest) ; + break ; + + case 0x2e : /* RSC immed */ + dest = DPImmRHS - LHS - !CFLAG ; + WRITEDEST(dest) ; + break ; + + case 0x2f : /* RSCS immed */ + lhs = LHS ; + rhs = DPImmRHS ; + dest = rhs - lhs - !CFLAG ; + if ((rhs >= lhs) || ((rhs | lhs) >> 31)) { + ARMul_SubCarry(state,rhs,lhs,dest) ; + ARMul_SubOverflow(state,rhs,lhs,dest) ; + } + else { + CLEARC ; + CLEARV ; + } + WRITESDEST(dest) ; + break ; + + case 0x30 : /* TST immed */ + UNDEF_Test ; + break ; + + case 0x31 : /* TSTP immed */ + if (DESTReg == 15) { /* TSTP immed */ +#ifdef MODE32 + state->Cpsr = GETSPSR(state->Bank) ; + ARMul_CPSRAltered(state) ; +#else + temp = LHS & DPImmRHS ; + SETR15PSR(temp) ; +#endif + } + else { + DPSImmRHS ; /* TST immed */ + dest = LHS & rhs ; + ARMul_NegZero(state,dest) ; + } + break ; + + case 0x32 : /* TEQ immed and MSR immed to CPSR */ + if (DESTReg==15 && BITS(17,18)==0) { /* MSR immed to CPSR */ + ARMul_FixCPSR(state,instr,DPImmRHS) ; + } + else { + UNDEF_Test ; + } + break ; + + case 0x33 : /* TEQP immed */ + if (DESTReg == 15) { /* TEQP immed */ +#ifdef MODE32 + state->Cpsr = GETSPSR(state->Bank) ; + ARMul_CPSRAltered(state) ; +#else + temp = LHS ^ DPImmRHS ; + SETR15PSR(temp) ; +#endif + } + else { + DPSImmRHS ; /* TEQ immed */ + dest = LHS ^ rhs ; + ARMul_NegZero(state,dest) ; + } + break ; + + case 0x34 : /* CMP immed */ + UNDEF_Test ; + break ; + + case 0x35 : /* CMPP immed */ + if (DESTReg == 15) { /* CMPP immed */ +#ifdef MODE32 + state->Cpsr = GETSPSR(state->Bank) ; + ARMul_CPSRAltered(state) ; +#else + temp = LHS - DPImmRHS ; + SETR15PSR(temp) ; +#endif + break ; + } + else { + lhs = LHS ; /* CMP immed */ + rhs = DPImmRHS ; + dest = lhs - rhs ; + ARMul_NegZero(state,dest) ; + if ((lhs >= rhs) || ((rhs | lhs) >> 31)) { + ARMul_SubCarry(state,lhs,rhs,dest) ; + ARMul_SubOverflow(state,lhs,rhs,dest) ; + } + else { + CLEARC ; + CLEARV ; + } + } + break ; + + case 0x36 : /* CMN immed and MSR immed to SPSR */ + if (DESTReg==15 && BITS(17,18)==0) /* MSR */ + ARMul_FixSPSR(state, instr, DPImmRHS) ; + else { + UNDEF_Test ; + } + break ; + + case 0x37 : /* CMNP immed */ + if (DESTReg == 15) { /* CMNP immed */ +#ifdef MODE32 + state->Cpsr = GETSPSR(state->Bank) ; + ARMul_CPSRAltered(state) ; +#else + temp = LHS + DPImmRHS ; + SETR15PSR(temp) ; +#endif + break ; + } + else { + lhs = LHS ; /* CMN immed */ + rhs = DPImmRHS ; + dest = lhs + rhs ; + ASSIGNZ(dest==0) ; + if ((lhs | rhs) >> 30) { /* possible C,V,N to set */ + ASSIGNN(NEG(dest)) ; + ARMul_AddCarry(state,lhs,rhs,dest) ; + ARMul_AddOverflow(state,lhs,rhs,dest) ; + } + else { + CLEARN ; + CLEARC ; + CLEARV ; + } + } + break ; + + case 0x38 : /* ORR immed */ + dest = LHS | DPImmRHS ; + WRITEDEST(dest) ; + break ; + + case 0x39 : /* ORRS immed */ + DPSImmRHS ; + dest = LHS | rhs ; + WRITESDEST(dest) ; + break ; + + case 0x3a : /* MOV immed */ + dest = DPImmRHS ; + WRITEDEST(dest) ; + break ; + + case 0x3b : /* MOVS immed */ + DPSImmRHS ; + WRITESDEST(rhs) ; + break ; + + case 0x3c : /* BIC immed */ + dest = LHS & ~DPImmRHS ; + WRITEDEST(dest) ; + break ; + + case 0x3d : /* BICS immed */ + DPSImmRHS ; + dest = LHS & ~rhs ; + WRITESDEST(dest) ; + break ; + + case 0x3e : /* MVN immed */ + dest = ~DPImmRHS ; + WRITEDEST(dest) ; + break ; + + case 0x3f : /* MVNS immed */ + DPSImmRHS ; + WRITESDEST(~rhs) ; + break ; + +/***************************************************************************\ +* Single Data Transfer Immediate RHS Instructions * +\***************************************************************************/ + + case 0x40 : /* Store Word, No WriteBack, Post Dec, Immed */ + lhs = LHS ; + if (StoreWord(state,instr,lhs)) + LSBase = lhs - LSImmRHS ; + break ; + + case 0x41 : /* Load Word, No WriteBack, Post Dec, Immed */ + lhs = LHS ; + if (LoadWord(state,instr,lhs)) + LSBase = lhs - LSImmRHS ; + break ; + + case 0x42 : /* Store Word, WriteBack, Post Dec, Immed */ + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + lhs = LHS ; + temp = lhs - LSImmRHS ; + state->NtransSig = LOW ; + if (StoreWord(state,instr,lhs)) + LSBase = temp ; + state->NtransSig = (state->Mode & 3)?HIGH:LOW ; + break ; + + case 0x43 : /* Load Word, WriteBack, Post Dec, Immed */ + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + lhs = LHS ; + state->NtransSig = LOW ; + if (LoadWord(state,instr,lhs)) + LSBase = lhs - LSImmRHS ; + state->NtransSig = (state->Mode & 3)?HIGH:LOW ; + break ; + + case 0x44 : /* Store Byte, No WriteBack, Post Dec, Immed */ + lhs = LHS ; + if (StoreByte(state,instr,lhs)) + LSBase = lhs - LSImmRHS ; + break ; + + case 0x45 : /* Load Byte, No WriteBack, Post Dec, Immed */ + lhs = LHS ; + if (LoadByte(state,instr,lhs,LUNSIGNED)) + LSBase = lhs - LSImmRHS ; + break ; + + case 0x46 : /* Store Byte, WriteBack, Post Dec, Immed */ + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + lhs = LHS ; + state->NtransSig = LOW ; + if (StoreByte(state,instr,lhs)) + LSBase = lhs - LSImmRHS ; + state->NtransSig = (state->Mode & 3)?HIGH:LOW ; + break ; + + case 0x47 : /* Load Byte, WriteBack, Post Dec, Immed */ + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + lhs = LHS ; + state->NtransSig = LOW ; + if (LoadByte(state,instr,lhs,LUNSIGNED)) + LSBase = lhs - LSImmRHS ; + state->NtransSig = (state->Mode & 3)?HIGH:LOW ; + break ; + + case 0x48 : /* Store Word, No WriteBack, Post Inc, Immed */ + lhs = LHS ; + if (StoreWord(state,instr,lhs)) + LSBase = lhs + LSImmRHS ; + break ; + + case 0x49 : /* Load Word, No WriteBack, Post Inc, Immed */ + lhs = LHS ; + if (LoadWord(state,instr,lhs)) + LSBase = lhs + LSImmRHS ; + break ; + + case 0x4a : /* Store Word, WriteBack, Post Inc, Immed */ + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + lhs = LHS ; + state->NtransSig = LOW ; + if (StoreWord(state,instr,lhs)) + LSBase = lhs + LSImmRHS ; + state->NtransSig = (state->Mode & 3)?HIGH:LOW ; + break ; + + case 0x4b : /* Load Word, WriteBack, Post Inc, Immed */ + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + lhs = LHS ; + state->NtransSig = LOW ; + if (LoadWord(state,instr,lhs)) + LSBase = lhs + LSImmRHS ; + state->NtransSig = (state->Mode & 3)?HIGH:LOW ; + break ; + + case 0x4c : /* Store Byte, No WriteBack, Post Inc, Immed */ + lhs = LHS ; + if (StoreByte(state,instr,lhs)) + LSBase = lhs + LSImmRHS ; + break ; + + case 0x4d : /* Load Byte, No WriteBack, Post Inc, Immed */ + lhs = LHS ; + if (LoadByte(state,instr,lhs,LUNSIGNED)) + LSBase = lhs + LSImmRHS ; + break ; + + case 0x4e : /* Store Byte, WriteBack, Post Inc, Immed */ + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + lhs = LHS ; + state->NtransSig = LOW ; + if (StoreByte(state,instr,lhs)) + LSBase = lhs + LSImmRHS ; + state->NtransSig = (state->Mode & 3)?HIGH:LOW ; + break ; + + case 0x4f : /* Load Byte, WriteBack, Post Inc, Immed */ + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + lhs = LHS ; + state->NtransSig = LOW ; + if (LoadByte(state,instr,lhs,LUNSIGNED)) + LSBase = lhs + LSImmRHS ; + state->NtransSig = (state->Mode & 3)?HIGH:LOW ; + break ; + + + case 0x50 : /* Store Word, No WriteBack, Pre Dec, Immed */ + (void)StoreWord(state,instr,LHS - LSImmRHS) ; + break ; + + case 0x51 : /* Load Word, No WriteBack, Pre Dec, Immed */ + (void)LoadWord(state,instr,LHS - LSImmRHS) ; + break ; + + case 0x52 : /* Store Word, WriteBack, Pre Dec, Immed */ + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + temp = LHS - LSImmRHS ; + if (StoreWord(state,instr,temp)) + LSBase = temp ; + break ; + + case 0x53 : /* Load Word, WriteBack, Pre Dec, Immed */ + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + temp = LHS - LSImmRHS ; + if (LoadWord(state,instr,temp)) + LSBase = temp ; + break ; + + case 0x54 : /* Store Byte, No WriteBack, Pre Dec, Immed */ + (void)StoreByte(state,instr,LHS - LSImmRHS) ; + break ; + + case 0x55 : /* Load Byte, No WriteBack, Pre Dec, Immed */ + (void)LoadByte(state,instr,LHS - LSImmRHS,LUNSIGNED) ; + break ; + + case 0x56 : /* Store Byte, WriteBack, Pre Dec, Immed */ + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + temp = LHS - LSImmRHS ; + if (StoreByte(state,instr,temp)) + LSBase = temp ; + break ; + + case 0x57 : /* Load Byte, WriteBack, Pre Dec, Immed */ + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + temp = LHS - LSImmRHS ; + if (LoadByte(state,instr,temp,LUNSIGNED)) + LSBase = temp ; + break ; + + case 0x58 : /* Store Word, No WriteBack, Pre Inc, Immed */ + (void)StoreWord(state,instr,LHS + LSImmRHS) ; + break ; + + case 0x59 : /* Load Word, No WriteBack, Pre Inc, Immed */ + (void)LoadWord(state,instr,LHS + LSImmRHS) ; + break ; + + case 0x5a : /* Store Word, WriteBack, Pre Inc, Immed */ + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + temp = LHS + LSImmRHS ; + if (StoreWord(state,instr,temp)) + LSBase = temp ; + break ; + + case 0x5b : /* Load Word, WriteBack, Pre Inc, Immed */ + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + temp = LHS + LSImmRHS ; + if (LoadWord(state,instr,temp)) + LSBase = temp ; + break ; + + case 0x5c : /* Store Byte, No WriteBack, Pre Inc, Immed */ + (void)StoreByte(state,instr,LHS + LSImmRHS) ; + break ; + + case 0x5d : /* Load Byte, No WriteBack, Pre Inc, Immed */ + (void)LoadByte(state,instr,LHS + LSImmRHS,LUNSIGNED) ; + break ; + + case 0x5e : /* Store Byte, WriteBack, Pre Inc, Immed */ + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + temp = LHS + LSImmRHS ; + if (StoreByte(state,instr,temp)) + LSBase = temp ; + break ; + + case 0x5f : /* Load Byte, WriteBack, Pre Inc, Immed */ + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + temp = LHS + LSImmRHS ; + if (LoadByte(state,instr,temp,LUNSIGNED)) + LSBase = temp ; + break ; + +/***************************************************************************\ +* Single Data Transfer Register RHS Instructions * +\***************************************************************************/ + + case 0x60 : /* Store Word, No WriteBack, Post Dec, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + lhs = LHS ; + if (StoreWord(state,instr,lhs)) + LSBase = lhs - LSRegRHS ; + break ; + + case 0x61 : /* Load Word, No WriteBack, Post Dec, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + lhs = LHS ; + if (LoadWord(state,instr,lhs)) + LSBase = lhs - LSRegRHS ; + break ; + + case 0x62 : /* Store Word, WriteBack, Post Dec, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + lhs = LHS ; + state->NtransSig = LOW ; + if (StoreWord(state,instr,lhs)) + LSBase = lhs - LSRegRHS ; + state->NtransSig = (state->Mode & 3)?HIGH:LOW ; + break ; + + case 0x63 : /* Load Word, WriteBack, Post Dec, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + lhs = LHS ; + state->NtransSig = LOW ; + if (LoadWord(state,instr,lhs)) + LSBase = lhs - LSRegRHS ; + state->NtransSig = (state->Mode & 3)?HIGH:LOW ; + break ; + + case 0x64 : /* Store Byte, No WriteBack, Post Dec, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + lhs = LHS ; + if (StoreByte(state,instr,lhs)) + LSBase = lhs - LSRegRHS ; + break ; + + case 0x65 : /* Load Byte, No WriteBack, Post Dec, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + lhs = LHS ; + if (LoadByte(state,instr,lhs,LUNSIGNED)) + LSBase = lhs - LSRegRHS ; + break ; + + case 0x66 : /* Store Byte, WriteBack, Post Dec, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + lhs = LHS ; + state->NtransSig = LOW ; + if (StoreByte(state,instr,lhs)) + LSBase = lhs - LSRegRHS ; + state->NtransSig = (state->Mode & 3)?HIGH:LOW ; + break ; + + case 0x67 : /* Load Byte, WriteBack, Post Dec, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + lhs = LHS ; + state->NtransSig = LOW ; + if (LoadByte(state,instr,lhs,LUNSIGNED)) + LSBase = lhs - LSRegRHS ; + state->NtransSig = (state->Mode & 3)?HIGH:LOW ; + break ; + + case 0x68 : /* Store Word, No WriteBack, Post Inc, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + lhs = LHS ; + if (StoreWord(state,instr,lhs)) + LSBase = lhs + LSRegRHS ; + break ; + + case 0x69 : /* Load Word, No WriteBack, Post Inc, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + lhs = LHS ; + if (LoadWord(state,instr,lhs)) + LSBase = lhs + LSRegRHS ; + break ; + + case 0x6a : /* Store Word, WriteBack, Post Inc, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + lhs = LHS ; + state->NtransSig = LOW ; + if (StoreWord(state,instr,lhs)) + LSBase = lhs + LSRegRHS ; + state->NtransSig = (state->Mode & 3)?HIGH:LOW ; + break ; + + case 0x6b : /* Load Word, WriteBack, Post Inc, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + lhs = LHS ; + state->NtransSig = LOW ; + if (LoadWord(state,instr,lhs)) + LSBase = lhs + LSRegRHS ; + state->NtransSig = (state->Mode & 3)?HIGH:LOW ; + break ; + + case 0x6c : /* Store Byte, No WriteBack, Post Inc, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + lhs = LHS ; + if (StoreByte(state,instr,lhs)) + LSBase = lhs + LSRegRHS ; + break ; + + case 0x6d : /* Load Byte, No WriteBack, Post Inc, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + lhs = LHS ; + if (LoadByte(state,instr,lhs,LUNSIGNED)) + LSBase = lhs + LSRegRHS ; + break ; + + case 0x6e : /* Store Byte, WriteBack, Post Inc, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + lhs = LHS ; + state->NtransSig = LOW ; + if (StoreByte(state,instr,lhs)) + LSBase = lhs + LSRegRHS ; + state->NtransSig = (state->Mode & 3)?HIGH:LOW ; + break ; + + case 0x6f : /* Load Byte, WriteBack, Post Inc, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + lhs = LHS ; + state->NtransSig = LOW ; + if (LoadByte(state,instr,lhs,LUNSIGNED)) + LSBase = lhs + LSRegRHS ; + state->NtransSig = (state->Mode & 3)?HIGH:LOW ; + break ; + + + case 0x70 : /* Store Word, No WriteBack, Pre Dec, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + (void)StoreWord(state,instr,LHS - LSRegRHS) ; + break ; + + case 0x71 : /* Load Word, No WriteBack, Pre Dec, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + (void)LoadWord(state,instr,LHS - LSRegRHS) ; + break ; + + case 0x72 : /* Store Word, WriteBack, Pre Dec, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + temp = LHS - LSRegRHS ; + if (StoreWord(state,instr,temp)) + LSBase = temp ; + break ; + + case 0x73 : /* Load Word, WriteBack, Pre Dec, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + temp = LHS - LSRegRHS ; + if (LoadWord(state,instr,temp)) + LSBase = temp ; + break ; + + case 0x74 : /* Store Byte, No WriteBack, Pre Dec, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + (void)StoreByte(state,instr,LHS - LSRegRHS) ; + break ; + + case 0x75 : /* Load Byte, No WriteBack, Pre Dec, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + (void)LoadByte(state,instr,LHS - LSRegRHS,LUNSIGNED) ; + break ; + + case 0x76 : /* Store Byte, WriteBack, Pre Dec, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + temp = LHS - LSRegRHS ; + if (StoreByte(state,instr,temp)) + LSBase = temp ; + break ; + + case 0x77 : /* Load Byte, WriteBack, Pre Dec, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + temp = LHS - LSRegRHS ; + if (LoadByte(state,instr,temp,LUNSIGNED)) + LSBase = temp ; + break ; + + case 0x78 : /* Store Word, No WriteBack, Pre Inc, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + (void)StoreWord(state,instr,LHS + LSRegRHS) ; + break ; + + case 0x79 : /* Load Word, No WriteBack, Pre Inc, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + (void)LoadWord(state,instr,LHS + LSRegRHS) ; + break ; + + case 0x7a : /* Store Word, WriteBack, Pre Inc, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + temp = LHS + LSRegRHS ; + if (StoreWord(state,instr,temp)) + LSBase = temp ; + break ; + + case 0x7b : /* Load Word, WriteBack, Pre Inc, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + temp = LHS + LSRegRHS ; + if (LoadWord(state,instr,temp)) + LSBase = temp ; + break ; + + case 0x7c : /* Store Byte, No WriteBack, Pre Inc, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + (void)StoreByte(state,instr,LHS + LSRegRHS) ; + break ; + + case 0x7d : /* Load Byte, No WriteBack, Pre Inc, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + (void)LoadByte(state,instr,LHS + LSRegRHS,LUNSIGNED) ; + break ; + + case 0x7e : /* Store Byte, WriteBack, Pre Inc, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + temp = LHS + LSRegRHS ; + if (StoreByte(state,instr,temp)) + LSBase = temp ; + break ; + + case 0x7f : /* Load Byte, WriteBack, Pre Inc, Reg */ + if (BIT(4)) { + ARMul_UndefInstr(state,instr) ; + break ; + } + UNDEF_LSRBaseEQOffWb ; + UNDEF_LSRBaseEQDestWb ; + UNDEF_LSRPCBaseWb ; + UNDEF_LSRPCOffWb ; + temp = LHS + LSRegRHS ; + if (LoadByte(state,instr,temp,LUNSIGNED)) + LSBase = temp ; + break ; + +/***************************************************************************\ +* Multiple Data Transfer Instructions * +\***************************************************************************/ + + case 0x80 : /* Store, No WriteBack, Post Dec */ + STOREMULT(instr,LSBase - LSMNumRegs + 4L,0L) ; + break ; + + case 0x81 : /* Load, No WriteBack, Post Dec */ + LOADMULT(instr,LSBase - LSMNumRegs + 4L,0L) ; + break ; + + case 0x82 : /* Store, WriteBack, Post Dec */ + temp = LSBase - LSMNumRegs ; + STOREMULT(instr,temp + 4L,temp) ; + break ; + + case 0x83 : /* Load, WriteBack, Post Dec */ + temp = LSBase - LSMNumRegs ; + LOADMULT(instr,temp + 4L,temp) ; + break ; + + case 0x84 : /* Store, Flags, No WriteBack, Post Dec */ + STORESMULT(instr,LSBase - LSMNumRegs + 4L,0L) ; + break ; + + case 0x85 : /* Load, Flags, No WriteBack, Post Dec */ + LOADSMULT(instr,LSBase - LSMNumRegs + 4L,0L) ; + break ; + + case 0x86 : /* Store, Flags, WriteBack, Post Dec */ + temp = LSBase - LSMNumRegs ; + STORESMULT(instr,temp + 4L,temp) ; + break ; + + case 0x87 : /* Load, Flags, WriteBack, Post Dec */ + temp = LSBase - LSMNumRegs ; + LOADSMULT(instr,temp + 4L,temp) ; + break ; + + + case 0x88 : /* Store, No WriteBack, Post Inc */ + STOREMULT(instr,LSBase,0L) ; + break ; + + case 0x89 : /* Load, No WriteBack, Post Inc */ + LOADMULT(instr,LSBase,0L) ; + break ; + + case 0x8a : /* Store, WriteBack, Post Inc */ + temp = LSBase ; + STOREMULT(instr,temp,temp + LSMNumRegs) ; + break ; + + case 0x8b : /* Load, WriteBack, Post Inc */ + temp = LSBase ; + LOADMULT(instr,temp,temp + LSMNumRegs) ; + break ; + + case 0x8c : /* Store, Flags, No WriteBack, Post Inc */ + STORESMULT(instr,LSBase,0L) ; + break ; + + case 0x8d : /* Load, Flags, No WriteBack, Post Inc */ + LOADSMULT(instr,LSBase,0L) ; + break ; + + case 0x8e : /* Store, Flags, WriteBack, Post Inc */ + temp = LSBase ; + STORESMULT(instr,temp,temp + LSMNumRegs) ; + break ; + + case 0x8f : /* Load, Flags, WriteBack, Post Inc */ + temp = LSBase ; + LOADSMULT(instr,temp,temp + LSMNumRegs) ; + break ; + + + case 0x90 : /* Store, No WriteBack, Pre Dec */ + STOREMULT(instr,LSBase - LSMNumRegs,0L) ; + break ; + + case 0x91 : /* Load, No WriteBack, Pre Dec */ + LOADMULT(instr,LSBase - LSMNumRegs,0L) ; + break ; + + case 0x92 : /* Store, WriteBack, Pre Dec */ + temp = LSBase - LSMNumRegs ; + STOREMULT(instr,temp,temp) ; + break ; + + case 0x93 : /* Load, WriteBack, Pre Dec */ + temp = LSBase - LSMNumRegs ; + LOADMULT(instr,temp,temp) ; + break ; + + case 0x94 : /* Store, Flags, No WriteBack, Pre Dec */ + STORESMULT(instr,LSBase - LSMNumRegs,0L) ; + break ; + + case 0x95 : /* Load, Flags, No WriteBack, Pre Dec */ + LOADSMULT(instr,LSBase - LSMNumRegs,0L) ; + break ; + + case 0x96 : /* Store, Flags, WriteBack, Pre Dec */ + temp = LSBase - LSMNumRegs ; + STORESMULT(instr,temp,temp) ; + break ; + + case 0x97 : /* Load, Flags, WriteBack, Pre Dec */ + temp = LSBase - LSMNumRegs ; + LOADSMULT(instr,temp,temp) ; + break ; + + + case 0x98 : /* Store, No WriteBack, Pre Inc */ + STOREMULT(instr,LSBase + 4L,0L) ; + break ; + + case 0x99 : /* Load, No WriteBack, Pre Inc */ + LOADMULT(instr,LSBase + 4L,0L) ; + break ; + + case 0x9a : /* Store, WriteBack, Pre Inc */ + temp = LSBase ; + STOREMULT(instr,temp + 4L,temp + LSMNumRegs) ; + break ; + + case 0x9b : /* Load, WriteBack, Pre Inc */ + temp = LSBase ; + LOADMULT(instr,temp + 4L,temp + LSMNumRegs) ; + break ; + + case 0x9c : /* Store, Flags, No WriteBack, Pre Inc */ + STORESMULT(instr,LSBase + 4L,0L) ; + break ; + + case 0x9d : /* Load, Flags, No WriteBack, Pre Inc */ + LOADSMULT(instr,LSBase + 4L,0L) ; + break ; + + case 0x9e : /* Store, Flags, WriteBack, Pre Inc */ + temp = LSBase ; + STORESMULT(instr,temp + 4L,temp + LSMNumRegs) ; + break ; + + case 0x9f : /* Load, Flags, WriteBack, Pre Inc */ + temp = LSBase ; + LOADSMULT(instr,temp + 4L,temp + LSMNumRegs) ; + break ; + +/***************************************************************************\ +* Branch forward * +\***************************************************************************/ + + case 0xa0 : case 0xa1 : case 0xa2 : case 0xa3 : + case 0xa4 : case 0xa5 : case 0xa6 : case 0xa7 : + state->Reg[15] = pc + 8 + POSBRANCH ; + FLUSHPIPE ; + break ; + +/***************************************************************************\ +* Branch backward * +\***************************************************************************/ + + case 0xa8 : case 0xa9 : case 0xaa : case 0xab : + case 0xac : case 0xad : case 0xae : case 0xaf : + state->Reg[15] = pc + 8 + NEGBRANCH ; + FLUSHPIPE ; + break ; + +/***************************************************************************\ +* Branch and Link forward * +\***************************************************************************/ + + case 0xb0 : case 0xb1 : case 0xb2 : case 0xb3 : + case 0xb4 : case 0xb5 : case 0xb6 : case 0xb7 : +#ifdef MODE32 + state->Reg[14] = pc + 4 ; /* put PC into Link */ +#else + state->Reg[14] = pc + 4 | ECC | ER15INT | EMODE ; /* put PC into Link */ +#endif + state->Reg[15] = pc + 8 + POSBRANCH ; + FLUSHPIPE ; + break ; + +/***************************************************************************\ +* Branch and Link backward * +\***************************************************************************/ + + case 0xb8 : case 0xb9 : case 0xba : case 0xbb : + case 0xbc : case 0xbd : case 0xbe : case 0xbf : +#ifdef MODE32 + state->Reg[14] = pc + 4 ; /* put PC into Link */ +#else + state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE ; /* put PC into Link */ +#endif + state->Reg[15] = pc + 8 + NEGBRANCH ; + FLUSHPIPE ; + break ; + +/***************************************************************************\ +* Co-Processor Data Transfers * +\***************************************************************************/ + + case 0xc0 : + case 0xc4 : /* Store , No WriteBack , Post Dec */ + ARMul_STC(state,instr,LHS) ; + break ; + + case 0xc1 : + case 0xc5 : /* Load , No WriteBack , Post Dec */ + ARMul_LDC(state,instr,LHS) ; + break ; + + case 0xc2 : + case 0xc6 : /* Store , WriteBack , Post Dec */ + lhs = LHS ; + state->Base = lhs - LSCOff ; + ARMul_STC(state,instr,lhs) ; + break ; + + case 0xc3 : + case 0xc7 : /* Load , WriteBack , Post Dec */ + lhs = LHS ; + state->Base = lhs - LSCOff ; + ARMul_LDC(state,instr,lhs) ; + break ; + + case 0xc8 : + case 0xcc : /* Store , No WriteBack , Post Inc */ + ARMul_STC(state,instr,LHS) ; + break ; + + case 0xc9 : + case 0xcd : /* Load , No WriteBack , Post Inc */ + ARMul_LDC(state,instr,LHS) ; + break ; + + case 0xca : + case 0xce : /* Store , WriteBack , Post Inc */ + lhs = LHS ; + state->Base = lhs + LSCOff ; + ARMul_STC(state,instr,LHS) ; + break ; + + case 0xcb : + case 0xcf : /* Load , WriteBack , Post Inc */ + lhs = LHS ; + state->Base = lhs + LSCOff ; + ARMul_LDC(state,instr,LHS) ; + break ; + + + case 0xd0 : + case 0xd4 : /* Store , No WriteBack , Pre Dec */ + ARMul_STC(state,instr,LHS - LSCOff) ; + break ; + + case 0xd1 : + case 0xd5 : /* Load , No WriteBack , Pre Dec */ + ARMul_LDC(state,instr,LHS - LSCOff) ; + break ; + + case 0xd2 : + case 0xd6 : /* Store , WriteBack , Pre Dec */ + lhs = LHS - LSCOff ; + state->Base = lhs ; + ARMul_STC(state,instr,lhs) ; + break ; + + case 0xd3 : + case 0xd7 : /* Load , WriteBack , Pre Dec */ + lhs = LHS - LSCOff ; + state->Base = lhs ; + ARMul_LDC(state,instr,lhs) ; + break ; + + case 0xd8 : + case 0xdc : /* Store , No WriteBack , Pre Inc */ + ARMul_STC(state,instr,LHS + LSCOff) ; + break ; + + case 0xd9 : + case 0xdd : /* Load , No WriteBack , Pre Inc */ + ARMul_LDC(state,instr,LHS + LSCOff) ; + break ; + + case 0xda : + case 0xde : /* Store , WriteBack , Pre Inc */ + lhs = LHS + LSCOff ; + state->Base = lhs ; + ARMul_STC(state,instr,lhs) ; + break ; + + case 0xdb : + case 0xdf : /* Load , WriteBack , Pre Inc */ + lhs = LHS + LSCOff ; + state->Base = lhs ; + ARMul_LDC(state,instr,lhs) ; + break ; + +/***************************************************************************\ +* Co-Processor Register Transfers (MCR) and Data Ops * +\***************************************************************************/ + + case 0xe0 : case 0xe2 : case 0xe4 : case 0xe6 : + case 0xe8 : case 0xea : case 0xec : case 0xee : + if (BIT(4)) { /* MCR */ + if (DESTReg == 15) { + UNDEF_MCRPC ; +#ifdef MODE32 + ARMul_MCR(state,instr,state->Reg[15] + isize) ; +#else + ARMul_MCR(state,instr,ECC | ER15INT | EMODE | + ((state->Reg[15] + isize) & R15PCBITS) ) ; +#endif + } + else + ARMul_MCR(state,instr,DEST) ; + } + else /* CDP Part 1 */ + ARMul_CDP(state,instr) ; + break ; + +/***************************************************************************\ +* Co-Processor Register Transfers (MRC) and Data Ops * +\***************************************************************************/ + + case 0xe1 : case 0xe3 : case 0xe5 : case 0xe7 : + case 0xe9 : case 0xeb : case 0xed : case 0xef : + if (BIT(4)) { /* MRC */ + temp = ARMul_MRC(state,instr) ; + if (DESTReg == 15) { + ASSIGNN((temp & NBIT) != 0) ; + ASSIGNZ((temp & ZBIT) != 0) ; + ASSIGNC((temp & CBIT) != 0) ; + ASSIGNV((temp & VBIT) != 0) ; + } + else + DEST = temp ; + } + else /* CDP Part 2 */ + ARMul_CDP(state,instr) ; + break ; + +/***************************************************************************\ +* SWI instruction * +\***************************************************************************/ + + case 0xf0 : case 0xf1 : case 0xf2 : case 0xf3 : + case 0xf4 : case 0xf5 : case 0xf6 : case 0xf7 : + case 0xf8 : case 0xf9 : case 0xfa : case 0xfb : + case 0xfc : case 0xfd : case 0xfe : case 0xff : + if (instr == ARMul_ABORTWORD && state->AbortAddr == pc) { /* a prefetch abort */ + ARMul_Abort(state,ARMul_PrefetchAbortV) ; + break ; + } + + if (!ARMul_OSHandleSWI(state,BITS(0,23))) { + ARMul_Abort(state,ARMul_SWIV) ; + } + break ; + } /* 256 way main switch */ + } /* if temp */ + +#ifdef MODET +donext: +#endif + + if (state->Emulate == ONCE) + state->Emulate = STOP; + else if (state->Emulate != RUN) + break; + } while (1) ; /* do loop */ + + state->decoded = decoded ; + state->loaded = loaded ; + state->pc = pc ; + return(pc) ; + } /* Emulate 26/32 in instruction based mode */ + + +/***************************************************************************\ +* This routine evaluates most Data Processing register RHS's with the S * +* bit clear. It is intended to be called from the macro DPRegRHS, which * +* filters the common case of an unshifted register with in line code * +\***************************************************************************/ + +static ARMword GetDPRegRHS(ARMul_State *state, ARMword instr) +{ARMword shamt , base ; + + base = RHSReg ; + if (BIT(4)) { /* shift amount in a register */ + UNDEF_Shift ; + INCPC ; +#ifndef MODE32 + if (base == 15) + base = ECC | ER15INT | R15PC | EMODE ; + else +#endif + base = state->Reg[base] ; + ARMul_Icycles(state,1,0L) ; + shamt = state->Reg[BITS(8,11)] & 0xff ; + switch ((int)BITS(5,6)) { + case LSL : if (shamt == 0) + return(base) ; + else if (shamt >= 32) + return(0) ; + else + return(base << shamt) ; + case LSR : if (shamt == 0) + return(base) ; + else if (shamt >= 32) + return(0) ; + else + return(base >> shamt) ; + case ASR : if (shamt == 0) + return(base) ; + else if (shamt >= 32) + return((ARMword)((long int)base >> 31L)) ; + else + return((ARMword)((long int)base >> (int)shamt)) ; + case ROR : shamt &= 0x1f ; + if (shamt == 0) + return(base) ; + else + return((base << (32 - shamt)) | (base >> shamt)) ; + } + } + else { /* shift amount is a constant */ +#ifndef MODE32 + if (base == 15) + base = ECC | ER15INT | R15PC | EMODE ; + else +#endif + base = state->Reg[base] ; + shamt = BITS(7,11) ; + switch ((int)BITS(5,6)) { + case LSL : return(base<<shamt) ; + case LSR : if (shamt == 0) + return(0) ; + else + return(base >> shamt) ; + case ASR : if (shamt == 0) + return((ARMword)((long int)base >> 31L)) ; + else + return((ARMword)((long int)base >> (int)shamt)) ; + case ROR : if (shamt==0) /* its an RRX */ + return((base >> 1) | (CFLAG << 31)) ; + else + return((base << (32 - shamt)) | (base >> shamt)) ; + } + } + return(0) ; /* just to shut up lint */ + } +/***************************************************************************\ +* This routine evaluates most Logical Data Processing register RHS's * +* with the S bit set. It is intended to be called from the macro * +* DPSRegRHS, which filters the common case of an unshifted register * +* with in line code * +\***************************************************************************/ + +static ARMword GetDPSRegRHS(ARMul_State *state, ARMword instr) +{ARMword shamt , base ; + + base = RHSReg ; + if (BIT(4)) { /* shift amount in a register */ + UNDEF_Shift ; + INCPC ; +#ifndef MODE32 + if (base == 15) + base = ECC | ER15INT | R15PC | EMODE ; + else +#endif + base = state->Reg[base] ; + ARMul_Icycles(state,1,0L) ; + shamt = state->Reg[BITS(8,11)] & 0xff ; + switch ((int)BITS(5,6)) { + case LSL : if (shamt == 0) + return(base) ; + else if (shamt == 32) { + ASSIGNC(base & 1) ; + return(0) ; + } + else if (shamt > 32) { + CLEARC ; + return(0) ; + } + else { + ASSIGNC((base >> (32-shamt)) & 1) ; + return(base << shamt) ; + } + case LSR : if (shamt == 0) + return(base) ; + else if (shamt == 32) { + ASSIGNC(base >> 31) ; + return(0) ; + } + else if (shamt > 32) { + CLEARC ; + return(0) ; + } + else { + ASSIGNC((base >> (shamt - 1)) & 1) ; + return(base >> shamt) ; + } + case ASR : if (shamt == 0) + return(base) ; + else if (shamt >= 32) { + ASSIGNC(base >> 31L) ; + return((ARMword)((long int)base >> 31L)) ; + } + else { + ASSIGNC((ARMword)((long int)base >> (int)(shamt-1)) & 1) ; + return((ARMword)((long int)base >> (int)shamt)) ; + } + case ROR : if (shamt == 0) + return(base) ; + shamt &= 0x1f ; + if (shamt == 0) { + ASSIGNC(base >> 31) ; + return(base) ; + } + else { + ASSIGNC((base >> (shamt-1)) & 1) ; + return((base << (32-shamt)) | (base >> shamt)) ; + } + } + } + else { /* shift amount is a constant */ +#ifndef MODE32 + if (base == 15) + base = ECC | ER15INT | R15PC | EMODE ; + else +#endif + base = state->Reg[base] ; + shamt = BITS(7,11) ; + switch ((int)BITS(5,6)) { + case LSL : ASSIGNC((base >> (32-shamt)) & 1) ; + return(base << shamt) ; + case LSR : if (shamt == 0) { + ASSIGNC(base >> 31) ; + return(0) ; + } + else { + ASSIGNC((base >> (shamt - 1)) & 1) ; + return(base >> shamt) ; + } + case ASR : if (shamt == 0) { + ASSIGNC(base >> 31L) ; + return((ARMword)((long int)base >> 31L)) ; + } + else { + ASSIGNC((ARMword)((long int)base >> (int)(shamt-1)) & 1) ; + return((ARMword)((long int)base >> (int)shamt)) ; + } + case ROR : if (shamt == 0) { /* its an RRX */ + shamt = CFLAG ; + ASSIGNC(base & 1) ; + return((base >> 1) | (shamt << 31)) ; + } + else { + ASSIGNC((base >> (shamt - 1)) & 1) ; + return((base << (32-shamt)) | (base >> shamt)) ; + } + } + } + return(0) ; /* just to shut up lint */ + } + +/***************************************************************************\ +* This routine handles writes to register 15 when the S bit is not set. * +\***************************************************************************/ + +static void WriteR15(ARMul_State *state, ARMword src) +{ + /* The ARM documentation implies (but doe snot state) that the bottom bit of the PC is never set */ +#ifdef MODE32 + state->Reg[15] = src & PCBITS & ~ 0x1 ; +#else + state->Reg[15] = (src & R15PCBITS & ~ 0x1) | ECC | ER15INT | EMODE ; + ARMul_R15Altered(state) ; +#endif + FLUSHPIPE ; + } + +/***************************************************************************\ +* This routine handles writes to register 15 when the S bit is set. * +\***************************************************************************/ + +static void WriteSR15(ARMul_State *state, ARMword src) +{ +#ifdef MODE32 + state->Reg[15] = src & PCBITS ; + if (state->Bank > 0) { + state->Cpsr = state->Spsr[state->Bank] ; + ARMul_CPSRAltered(state) ; + } +#else + if (state->Bank == USERBANK) + state->Reg[15] = (src & (CCBITS | R15PCBITS)) | ER15INT | EMODE ; + else + state->Reg[15] = src ; + ARMul_R15Altered(state) ; +#endif + FLUSHPIPE ; + } + +/***************************************************************************\ +* This routine evaluates most Load and Store register RHS's. It is * +* intended to be called from the macro LSRegRHS, which filters the * +* common case of an unshifted register with in line code * +\***************************************************************************/ + +static ARMword GetLSRegRHS(ARMul_State *state, ARMword instr) +{ARMword shamt, base ; + + base = RHSReg ; +#ifndef MODE32 + if (base == 15) + base = ECC | ER15INT | R15PC | EMODE ; /* Now forbidden, but .... */ + else +#endif + base = state->Reg[base] ; + + shamt = BITS(7,11) ; + switch ((int)BITS(5,6)) { + case LSL : return(base << shamt) ; + case LSR : if (shamt == 0) + return(0) ; + else + return(base >> shamt) ; + case ASR : if (shamt == 0) + return((ARMword)((long int)base >> 31L)) ; + else + return((ARMword)((long int)base >> (int)shamt)) ; + case ROR : if (shamt==0) /* its an RRX */ + return((base >> 1) | (CFLAG << 31)) ; + else + return((base << (32-shamt)) | (base >> shamt)) ; + } + return(0) ; /* just to shut up lint */ + } + +/***************************************************************************\ +* This routine evaluates the ARM7T halfword and signed transfer RHS's. * +\***************************************************************************/ + +static ARMword GetLS7RHS(ARMul_State *state, ARMword instr) +{ + if (BIT(22) == 0) { /* register */ +#ifndef MODE32 + if (RHSReg == 15) + return ECC | ER15INT | R15PC | EMODE ; /* Now forbidden, but ... */ +#endif + return state->Reg[RHSReg] ; + } + + /* else immediate */ + return BITS(0,3) | (BITS(8,11) << 4) ; + } + +/***************************************************************************\ +* This function does the work of loading a word for a LDR instruction. * +\***************************************************************************/ + +static unsigned LoadWord(ARMul_State *state, ARMword instr, ARMword address) +{ + ARMword dest ; + + BUSUSEDINCPCS ; +#ifndef MODE32 + if (ADDREXCEPT(address)) { + INTERNALABORT(address) ; + } +#endif + dest = ARMul_LoadWordN(state,address) ; + if (state->Aborted) { + TAKEABORT ; + return(state->lateabtSig) ; + } + if (address & 3) + dest = ARMul_Align(state,address,dest) ; + WRITEDEST(dest) ; + ARMul_Icycles(state,1,0L) ; + + return(DESTReg != LHSReg) ; +} + +#ifdef MODET +/***************************************************************************\ +* This function does the work of loading a halfword. * +\***************************************************************************/ + +static unsigned LoadHalfWord(ARMul_State *state, ARMword instr, ARMword address,int signextend) +{ + ARMword dest ; + + BUSUSEDINCPCS ; +#ifndef MODE32 + if (ADDREXCEPT(address)) { + INTERNALABORT(address) ; + } +#endif + dest = ARMul_LoadHalfWord(state,address) ; + if (state->Aborted) { + TAKEABORT ; + return(state->lateabtSig) ; + } + UNDEF_LSRBPC ; + if (signextend) + { + if (dest & 1 << (16 - 1)) + dest = (dest & ((1 << 16) - 1)) - (1 << 16) ; + } + WRITEDEST(dest) ; + ARMul_Icycles(state,1,0L) ; + return(DESTReg != LHSReg) ; +} +#endif /* MODET */ + +/***************************************************************************\ +* This function does the work of loading a byte for a LDRB instruction. * +\***************************************************************************/ + +static unsigned LoadByte(ARMul_State *state, ARMword instr, ARMword address,int signextend) +{ + ARMword dest ; + + BUSUSEDINCPCS ; +#ifndef MODE32 + if (ADDREXCEPT(address)) { + INTERNALABORT(address) ; + } +#endif + dest = ARMul_LoadByte(state,address) ; + if (state->Aborted) { + TAKEABORT ; + return(state->lateabtSig) ; + } + UNDEF_LSRBPC ; + if (signextend) + { + if (dest & 1 << (8 - 1)) + dest = (dest & ((1 << 8) - 1)) - (1 << 8) ; + } + WRITEDEST(dest) ; + ARMul_Icycles(state,1,0L) ; + return(DESTReg != LHSReg) ; +} + +/***************************************************************************\ +* This function does the work of storing a word from a STR instruction. * +\***************************************************************************/ + +static unsigned StoreWord(ARMul_State *state, ARMword instr, ARMword address) +{BUSUSEDINCPCN ; +#ifndef MODE32 + if (DESTReg == 15) + state->Reg[15] = ECC | ER15INT | R15PC | EMODE ; +#endif +#ifdef MODE32 + ARMul_StoreWordN(state,address,DEST) ; +#else + if (VECTORACCESS(address) || ADDREXCEPT(address)) { + INTERNALABORT(address) ; + (void)ARMul_LoadWordN(state,address) ; + } + else + ARMul_StoreWordN(state,address,DEST) ; +#endif + if (state->Aborted) { + TAKEABORT ; + return(state->lateabtSig) ; + } + return(TRUE) ; +} + +#ifdef MODET +/***************************************************************************\ +* This function does the work of storing a byte for a STRH instruction. * +\***************************************************************************/ + +static unsigned StoreHalfWord(ARMul_State *state, ARMword instr, ARMword address) +{BUSUSEDINCPCN ; + +#ifndef MODE32 + if (DESTReg == 15) + state->Reg[15] = ECC | ER15INT | R15PC | EMODE ; +#endif + +#ifdef MODE32 + ARMul_StoreHalfWord(state,address,DEST); +#else + if (VECTORACCESS(address) || ADDREXCEPT(address)) { + INTERNALABORT(address) ; + (void)ARMul_LoadHalfWord(state,address) ; + } + else + ARMul_StoreHalfWord(state,address,DEST) ; +#endif + + if (state->Aborted) { + TAKEABORT ; + return(state->lateabtSig) ; + } + + return(TRUE) ; +} +#endif /* MODET */ + +/***************************************************************************\ +* This function does the work of storing a byte for a STRB instruction. * +\***************************************************************************/ + +static unsigned StoreByte(ARMul_State *state, ARMword instr, ARMword address) +{BUSUSEDINCPCN ; +#ifndef MODE32 + if (DESTReg == 15) + state->Reg[15] = ECC | ER15INT | R15PC | EMODE ; +#endif +#ifdef MODE32 + ARMul_StoreByte(state,address,DEST) ; +#else + if (VECTORACCESS(address) || ADDREXCEPT(address)) { + INTERNALABORT(address) ; + (void)ARMul_LoadByte(state,address) ; + } + else + ARMul_StoreByte(state,address,DEST) ; +#endif + if (state->Aborted) { + TAKEABORT ; + return(state->lateabtSig) ; + } + UNDEF_LSRBPC ; + return(TRUE) ; +} + +/***************************************************************************\ +* This function does the work of loading the registers listed in an LDM * +* instruction, when the S bit is clear. The code here is always increment * +* after, it's up to the caller to get the input address correct and to * +* handle base register modification. * +\***************************************************************************/ + +static void LoadMult(ARMul_State *state, ARMword instr, + ARMword address, ARMword WBBase) +{ARMword dest, temp ; + + UNDEF_LSMNoRegs ; + UNDEF_LSMPCBase ; + UNDEF_LSMBaseInListWb ; + BUSUSEDINCPCS ; +#ifndef MODE32 + if (ADDREXCEPT(address)) { + INTERNALABORT(address) ; + } +#endif + if (BIT(21) && LHSReg != 15) + LSBase = WBBase ; + + for (temp = 0 ; !BIT(temp) ; temp++) ; /* N cycle first */ + dest = ARMul_LoadWordN(state,address) ; + if (!state->abortSig && !state->Aborted) + state->Reg[temp++] = dest ; + else + if (!state->Aborted) + state->Aborted = ARMul_DataAbortV ; + + for (; temp < 16 ; temp++) /* S cycles from here on */ + if (BIT(temp)) { /* load this register */ + address += 4 ; + dest = ARMul_LoadWordS(state,address) ; + if (!state->abortSig && !state->Aborted) + state->Reg[temp] = dest ; + else + if (!state->Aborted) + state->Aborted = ARMul_DataAbortV ; + } + + if (BIT(15)) { /* PC is in the reg list */ +#ifdef MODE32 + state->Reg[15] = PC ; +#endif + FLUSHPIPE ; + } + + ARMul_Icycles(state,1,0L) ; /* to write back the final register */ + + if (state->Aborted) { + if (BIT(21) && LHSReg != 15) + LSBase = WBBase ; + TAKEABORT ; + } + } + +/***************************************************************************\ +* This function does the work of loading the registers listed in an LDM * +* instruction, when the S bit is set. The code here is always increment * +* after, it's up to the caller to get the input address correct and to * +* handle base register modification. * +\***************************************************************************/ + +static void LoadSMult(ARMul_State *state, ARMword instr, + ARMword address, ARMword WBBase) +{ARMword dest, temp ; + + UNDEF_LSMNoRegs ; + UNDEF_LSMPCBase ; + UNDEF_LSMBaseInListWb ; + BUSUSEDINCPCS ; +#ifndef MODE32 + if (ADDREXCEPT(address)) { + INTERNALABORT(address) ; + } +#endif + + if (!BIT(15) && state->Bank != USERBANK) { + (void)ARMul_SwitchMode(state,state->Mode,USER26MODE) ; /* temporary reg bank switch */ + UNDEF_LSMUserBankWb ; + } + + if (BIT(21) && LHSReg != 15) + LSBase = WBBase ; + + for (temp = 0 ; !BIT(temp) ; temp++) ; /* N cycle first */ + dest = ARMul_LoadWordN(state,address) ; + if (!state->abortSig) + state->Reg[temp++] = dest ; + else + if (!state->Aborted) + state->Aborted = ARMul_DataAbortV ; + + for (; temp < 16 ; temp++) /* S cycles from here on */ + if (BIT(temp)) { /* load this register */ + address += 4 ; + dest = ARMul_LoadWordS(state,address) ; + if (!state->abortSig || state->Aborted) + state->Reg[temp] = dest ; + else + if (!state->Aborted) + state->Aborted = ARMul_DataAbortV ; + } + + if (BIT(15)) { /* PC is in the reg list */ +#ifdef MODE32 + if (state->Mode != USER26MODE && state->Mode != USER32MODE) { + state->Cpsr = GETSPSR(state->Bank) ; + ARMul_CPSRAltered(state) ; + } + state->Reg[15] = PC ; +#else + if (state->Mode == USER26MODE || state->Mode == USER32MODE) { /* protect bits in user mode */ + ASSIGNN((state->Reg[15] & NBIT) != 0) ; + ASSIGNZ((state->Reg[15] & ZBIT) != 0) ; + ASSIGNC((state->Reg[15] & CBIT) != 0) ; + ASSIGNV((state->Reg[15] & VBIT) != 0) ; + } + else + ARMul_R15Altered(state) ; +#endif + FLUSHPIPE ; + } + + if (!BIT(15) && state->Mode != USER26MODE && state->Mode != USER32MODE) + (void)ARMul_SwitchMode(state,USER26MODE,state->Mode) ; /* restore the correct bank */ + + ARMul_Icycles(state,1,0L) ; /* to write back the final register */ + + if (state->Aborted) { + if (BIT(21) && LHSReg != 15) + LSBase = WBBase ; + TAKEABORT ; + } + +} + +/***************************************************************************\ +* This function does the work of storing the registers listed in an STM * +* instruction, when the S bit is clear. The code here is always increment * +* after, it's up to the caller to get the input address correct and to * +* handle base register modification. * +\***************************************************************************/ + +static void StoreMult(ARMul_State *state, ARMword instr, + ARMword address, ARMword WBBase) +{ARMword temp ; + + UNDEF_LSMNoRegs ; + UNDEF_LSMPCBase ; + UNDEF_LSMBaseInListWb ; + if (!TFLAG) { + BUSUSEDINCPCN ; /* N-cycle, increment the PC and update the NextInstr state */ + } + +#ifndef MODE32 + if (VECTORACCESS(address) || ADDREXCEPT(address)) { + INTERNALABORT(address) ; + } + if (BIT(15)) + PATCHR15 ; +#endif + + for (temp = 0 ; !BIT(temp) ; temp++) ; /* N cycle first */ +#ifdef MODE32 + ARMul_StoreWordN(state,address,state->Reg[temp++]) ; +#else + if (state->Aborted) { + (void)ARMul_LoadWordN(state,address) ; + for ( ; temp < 16 ; temp++) /* Fake the Stores as Loads */ + if (BIT(temp)) { /* save this register */ + address += 4 ; + (void)ARMul_LoadWordS(state,address) ; + } + if (BIT(21) && LHSReg != 15) + LSBase = WBBase ; + TAKEABORT ; + return ; + } + else + ARMul_StoreWordN(state,address,state->Reg[temp++]) ; +#endif + if (state->abortSig && !state->Aborted) + state->Aborted = ARMul_DataAbortV ; + + if (BIT(21) && LHSReg != 15) + LSBase = WBBase ; + + for ( ; temp < 16 ; temp++) /* S cycles from here on */ + if (BIT(temp)) { /* save this register */ + address += 4 ; + ARMul_StoreWordS(state,address,state->Reg[temp]) ; + if (state->abortSig && !state->Aborted) + state->Aborted = ARMul_DataAbortV ; + } + if (state->Aborted) { + TAKEABORT ; + } + } + +/***************************************************************************\ +* This function does the work of storing the registers listed in an STM * +* instruction when the S bit is set. The code here is always increment * +* after, it's up to the caller to get the input address correct and to * +* handle base register modification. * +\***************************************************************************/ + +static void StoreSMult(ARMul_State *state, ARMword instr, + ARMword address, ARMword WBBase) +{ARMword temp ; + + UNDEF_LSMNoRegs ; + UNDEF_LSMPCBase ; + UNDEF_LSMBaseInListWb ; + BUSUSEDINCPCN ; +#ifndef MODE32 + if (VECTORACCESS(address) || ADDREXCEPT(address)) { + INTERNALABORT(address) ; + } + if (BIT(15)) + PATCHR15 ; +#endif + + if (state->Bank != USERBANK) { + (void)ARMul_SwitchMode(state,state->Mode,USER26MODE) ; /* Force User Bank */ + UNDEF_LSMUserBankWb ; + } + + for (temp = 0 ; !BIT(temp) ; temp++) ; /* N cycle first */ +#ifdef MODE32 + ARMul_StoreWordN(state,address,state->Reg[temp++]) ; +#else + if (state->Aborted) { + (void)ARMul_LoadWordN(state,address) ; + for ( ; temp < 16 ; temp++) /* Fake the Stores as Loads */ + if (BIT(temp)) { /* save this register */ + address += 4 ; + (void)ARMul_LoadWordS(state,address) ; + } + if (BIT(21) && LHSReg != 15) + LSBase = WBBase ; + TAKEABORT ; + return ; + } + else + ARMul_StoreWordN(state,address,state->Reg[temp++]) ; +#endif + if (state->abortSig && !state->Aborted) + state->Aborted = ARMul_DataAbortV ; + + if (BIT(21) && LHSReg != 15) + LSBase = WBBase ; + + for (; temp < 16 ; temp++) /* S cycles from here on */ + if (BIT(temp)) { /* save this register */ + address += 4 ; + ARMul_StoreWordS(state,address,state->Reg[temp]) ; + if (state->abortSig && !state->Aborted) + state->Aborted = ARMul_DataAbortV ; + } + + if (state->Mode != USER26MODE && state->Mode != USER32MODE) + (void)ARMul_SwitchMode(state,USER26MODE,state->Mode) ; /* restore the correct bank */ + + if (state->Aborted) { + TAKEABORT ; + } +} + +/***************************************************************************\ +* This function does the work of adding two 32bit values together, and * +* calculating if a carry has occurred. * +\***************************************************************************/ + +static ARMword Add32(ARMword a1,ARMword a2,int *carry) +{ + ARMword result = (a1 + a2); + unsigned int uresult = (unsigned int)result; + unsigned int ua1 = (unsigned int)a1; + + /* If (result == RdLo) and (state->Reg[nRdLo] == 0), + or (result > RdLo) then we have no carry: */ + if ((uresult == ua1) ? (a2 != 0) : (uresult < ua1)) + *carry = 1; + else + *carry = 0; + + return(result); +} + +/***************************************************************************\ +* This function does the work of multiplying two 32bit values to give a * +* 64bit result. * +\***************************************************************************/ + +static unsigned Multiply64(ARMul_State *state,ARMword instr,int msigned,int scc) +{ + int nRdHi, nRdLo, nRs, nRm; /* operand register numbers */ + ARMword RdHi, RdLo, Rm; + int scount; /* cycle count */ + + nRdHi = BITS(16,19); + nRdLo = BITS(12,15); + nRs = BITS(8,11); + nRm = BITS(0,3); + + /* Needed to calculate the cycle count: */ + Rm = state->Reg[nRm]; + + /* Check for illegal operand combinations first: */ + if ( nRdHi != 15 + && nRdLo != 15 + && nRs != 15 + && nRm != 15 + && nRdHi != nRdLo + && nRdHi != nRm + && nRdLo != nRm) + { + ARMword lo, mid1, mid2, hi; /* intermediate results */ + int carry; + ARMword Rs = state->Reg[ nRs ]; + int sign = 0; + + if (msigned) + { + /* Compute sign of result and adjust operands if necessary. */ + + sign = (Rm ^ Rs) & 0x80000000; + + if (((signed long)Rm) < 0) + Rm = -Rm; + + if (((signed long)Rs) < 0) + Rs = -Rs; + } + + /* We can split the 32x32 into four 16x16 operations. This ensures + that we do not lose precision on 32bit only hosts: */ + lo = ((Rs & 0xFFFF) * (Rm & 0xFFFF)); + mid1 = ((Rs & 0xFFFF) * ((Rm >> 16) & 0xFFFF)); + mid2 = (((Rs >> 16) & 0xFFFF) * (Rm & 0xFFFF)); + hi = (((Rs >> 16) & 0xFFFF) * ((Rm >> 16) & 0xFFFF)); + + /* We now need to add all of these results together, taking care + to propogate the carries from the additions: */ + RdLo = Add32(lo,(mid1 << 16),&carry); + RdHi = carry; + RdLo = Add32(RdLo,(mid2 << 16),&carry); + RdHi += (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi); + + if (sign) + { + /* Negate result if necessary. */ + + RdLo = ~ RdLo; + RdHi = ~ RdHi; + if (RdLo == 0xFFFFFFFF) + { + RdLo = 0; + RdHi += 1; + } + else + RdLo += 1; + } + + state->Reg[nRdLo] = RdLo; + state->Reg[nRdHi] = RdHi; + + } /* else undefined result */ + else fprintf (stderr, "MULTIPLY64 - INVALID ARGUMENTS\n"); + + if (scc) + { + if ((RdHi == 0) && (RdLo == 0)) + ARMul_NegZero(state,RdHi); /* zero value */ + else + ARMul_NegZero(state,scc); /* non-zero value */ + } + + /* The cycle count depends on whether the instruction is a signed or + unsigned multiply, and what bits are clear in the multiplier: */ + if (msigned && (Rm & ((unsigned)1 << 31))) + Rm = ~Rm; /* invert the bits to make the check against zero */ + + if ((Rm & 0xFFFFFF00) == 0) + scount = 1 ; + else if ((Rm & 0xFFFF0000) == 0) + scount = 2 ; + else if ((Rm & 0xFF000000) == 0) + scount = 3 ; + else + scount = 4 ; + + return 2 + scount ; +} + +/***************************************************************************\ +* This function does the work of multiplying two 32bit values and adding * +* a 64bit value to give a 64bit result. * +\***************************************************************************/ + +static unsigned MultiplyAdd64(ARMul_State *state,ARMword instr,int msigned,int scc) +{ + unsigned scount; + ARMword RdLo, RdHi; + int nRdHi, nRdLo; + int carry = 0; + + nRdHi = BITS(16,19); + nRdLo = BITS(12,15); + + RdHi = state->Reg[nRdHi] ; + RdLo = state->Reg[nRdLo] ; + + scount = Multiply64(state,instr,msigned,LDEFAULT); + + RdLo = Add32(RdLo,state->Reg[nRdLo],&carry); + RdHi = (RdHi + state->Reg[nRdHi]) + carry; + + state->Reg[nRdLo] = RdLo; + state->Reg[nRdHi] = RdHi; + + if (scc) { + if ((RdHi == 0) && (RdLo == 0)) + ARMul_NegZero(state,RdHi); /* zero value */ + else + ARMul_NegZero(state,scc); /* non-zero value */ + } + + return scount + 1; /* extra cycle for addition */ +} diff --git a/sim/arm/armemu.h b/sim/arm/armemu.h new file mode 100644 index 0000000..9c40b8c --- /dev/null +++ b/sim/arm/armemu.h @@ -0,0 +1,425 @@ +/* armemu.h -- ARMulator emulation macros: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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. */ + +extern ARMword isize; + +/***************************************************************************\ +* Condition code values * +\***************************************************************************/ + +#define EQ 0 +#define NE 1 +#define CS 2 +#define CC 3 +#define MI 4 +#define PL 5 +#define VS 6 +#define VC 7 +#define HI 8 +#define LS 9 +#define GE 10 +#define LT 11 +#define GT 12 +#define LE 13 +#define AL 14 +#define NV 15 + +/***************************************************************************\ +* Shift Opcodes * +\***************************************************************************/ + +#define LSL 0 +#define LSR 1 +#define ASR 2 +#define ROR 3 + +/***************************************************************************\ +* Macros to twiddle the status flags and mode * +\***************************************************************************/ + +#define NBIT ((unsigned)1L << 31) +#define ZBIT (1L << 30) +#define CBIT (1L << 29) +#define VBIT (1L << 28) +#define IBIT (1L << 7) +#define FBIT (1L << 6) +#define IFBITS (3L << 6) +#define R15IBIT (1L << 27) +#define R15FBIT (1L << 26) +#define R15IFBITS (3L << 26) + +#define POS(i) ( (~(i)) >> 31 ) +#define NEG(i) ( (i) >> 31 ) + +#ifdef MODET /* Thumb support */ +/* ??? This bit is actually in the low order bit of the PC in the hardware. + It isn't clear if the simulator needs to model that or not. */ +#define TBIT (1L << 5) +#define TFLAG state->TFlag +#define SETT state->TFlag = 1 +#define CLEART state->TFlag = 0 +#define ASSIGNT(res) state->TFlag = res +#endif + +#define NFLAG state->NFlag +#define SETN state->NFlag = 1 +#define CLEARN state->NFlag = 0 +#define ASSIGNN(res) state->NFlag = res + +#define ZFLAG state->ZFlag +#define SETZ state->ZFlag = 1 +#define CLEARZ state->ZFlag = 0 +#define ASSIGNZ(res) state->ZFlag = res + +#define CFLAG state->CFlag +#define SETC state->CFlag = 1 +#define CLEARC state->CFlag = 0 +#define ASSIGNC(res) state->CFlag = res + +#define VFLAG state->VFlag +#define SETV state->VFlag = 1 +#define CLEARV state->VFlag = 0 +#define ASSIGNV(res) state->VFlag = res + +#define IFLAG (state->IFFlags >> 1) +#define FFLAG (state->IFFlags & 1) +#define IFFLAGS state->IFFlags +#define ASSIGNINT(res) state->IFFlags = (((res) >> 6) & 3) +#define ASSIGNR15INT(res) state->IFFlags = (((res) >> 26) & 3) ; + +#define CCBITS (0xf0000000L) +#define INTBITS (0xc0L) + +#if defined MODET && defined MODE32 +#define PCBITS (0xffffffffL) +#else +#define PCBITS (0xfffffffcL) +#endif + +#define MODEBITS (0x1fL) +#define R15INTBITS (3L << 26) + +#if defined MODET && defined MODE32 +#define R15PCBITS (0x03ffffffL) +#else +#define R15PCBITS (0x03fffffcL) +#endif + +#define R15PCMODEBITS (0x03ffffffL) +#define R15MODEBITS (0x3L) + +#ifdef MODE32 +#define PCMASK PCBITS +#define PCWRAP(pc) (pc) +#else +#define PCMASK R15PCBITS +#define PCWRAP(pc) ((pc) & R15PCBITS) +#endif + +#define PC (state->Reg[15] & PCMASK) +#define R15CCINTMODE (state->Reg[15] & (CCBITS | R15INTBITS | R15MODEBITS)) +#define R15INT (state->Reg[15] & R15INTBITS) +#define R15INTPC (state->Reg[15] & (R15INTBITS | R15PCBITS)) +#define R15INTPCMODE (state->Reg[15] & (R15INTBITS | R15PCBITS | R15MODEBITS)) +#define R15INTMODE (state->Reg[15] & (R15INTBITS | R15MODEBITS)) +#define R15PC (state->Reg[15] & R15PCBITS) +#define R15PCMODE (state->Reg[15] & (R15PCBITS | R15MODEBITS)) +#define R15MODE (state->Reg[15] & R15MODEBITS) + +#define ECC ((NFLAG << 31) | (ZFLAG << 30) | (CFLAG << 29) | (VFLAG << 28)) +#define EINT (IFFLAGS << 6) +#define ER15INT (IFFLAGS << 26) +#define EMODE (state->Mode) + +#ifdef MODET +#define CPSR (ECC | EINT | EMODE | (TFLAG << 5)) +#else +#define CPSR (ECC | EINT | EMODE) +#endif + +#ifdef MODE32 +#define PATCHR15 +#else +#define PATCHR15 state->Reg[15] = ECC | ER15INT | EMODE | R15PC +#endif + +#define GETSPSR(bank) bank>0?state->Spsr[bank]:ECC | EINT | EMODE ; +#define SETPSR(d,s) d = (s) & (ARMword)(CCBITS | INTBITS | MODEBITS) +#define SETINTMODE(d,s) d = ((d) & CCBITS) | ((s) & (INTBITS | MODEBITS)) +#define SETCC(d,s) d = ((d) & (INTBITS | MODEBITS)) | ((s) & CCBITS) +#define SETR15PSR(s) if (state->Mode == USER26MODE) { \ + state->Reg[15] = ((s) & CCBITS) | R15PC | ER15INT | EMODE ; \ + ASSIGNN((state->Reg[15] & NBIT) != 0) ; \ + ASSIGNZ((state->Reg[15] & ZBIT) != 0) ; \ + ASSIGNC((state->Reg[15] & CBIT) != 0) ; \ + ASSIGNV((state->Reg[15] & VBIT) != 0) ; \ + } \ + else { \ + state->Reg[15] = R15PC | (s) & (CCBITS | R15INTBITS | R15MODEBITS) ; \ + ARMul_R15Altered(state) ; \ + } +#define SETABORT(i,m) state->Cpsr = ECC | EINT | (i) | (m) + +#ifndef MODE32 +#define VECTORS 0x20 +#define LEGALADDR 0x03ffffff +#define VECTORACCESS(address) (address < VECTORS && ARMul_MODE26BIT && state->prog32Sig) +#define ADDREXCEPT(address) (address > LEGALADDR && !state->data32Sig) +#endif + +#define INTERNALABORT(address) if (address < VECTORS) \ + state->Aborted = ARMul_DataAbortV ; \ + else \ + state->Aborted = ARMul_AddrExceptnV ; + +#ifdef MODE32 +#define TAKEABORT ARMul_Abort(state,ARMul_DataAbortV) +#else +#define TAKEABORT if (state->Aborted == ARMul_AddrExceptnV) \ + ARMul_Abort(state,ARMul_AddrExceptnV) ; \ + else \ + ARMul_Abort(state,ARMul_DataAbortV) +#endif +#define CPTAKEABORT if (!state->Aborted) \ + ARMul_Abort(state,ARMul_UndefinedInstrV) ; \ + else if (state->Aborted == ARMul_AddrExceptnV) \ + ARMul_Abort(state,ARMul_AddrExceptnV) ; \ + else \ + ARMul_Abort(state,ARMul_DataAbortV) + + +/***************************************************************************\ +* Different ways to start the next instruction * +\***************************************************************************/ + +#define SEQ 0 +#define NONSEQ 1 +#define PCINCEDSEQ 2 +#define PCINCEDNONSEQ 3 +#define PRIMEPIPE 4 +#define RESUME 8 + +#define NORMALCYCLE state->NextInstr = 0 +#define BUSUSEDN state->NextInstr |= 1 /* the next fetch will be an N cycle */ +#define BUSUSEDINCPCS state->Reg[15] += isize ; /* a standard PC inc and an S cycle */ \ + state->NextInstr = (state->NextInstr & 0xff) | 2 +#define BUSUSEDINCPCN state->Reg[15] += isize ; /* a standard PC inc and an N cycle */ \ + state->NextInstr |= 3 +#define INCPC state->Reg[15] += isize ; /* a standard PC inc */ \ + state->NextInstr |= 2 +#define FLUSHPIPE state->NextInstr |= PRIMEPIPE + +/***************************************************************************\ +* Cycle based emulation * +\***************************************************************************/ + +#define OUTPUTCP(i,a,b) +#define NCYCLE +#define SCYCLE +#define ICYCLE +#define CCYCLE +#define NEXTCYCLE(c) + +/***************************************************************************\ +* States of the cycle based state machine * +\***************************************************************************/ + + +/***************************************************************************\ +* Macros to extract parts of instructions * +\***************************************************************************/ + +#define DESTReg (BITS(12,15)) +#define LHSReg (BITS(16,19)) +#define RHSReg (BITS(0,3)) + +#define DEST (state->Reg[DESTReg]) + +#ifdef MODE32 +#ifdef MODET +#define LHS ((LHSReg == 15) ? (state->Reg[15] & 0xFFFFFFFC): (state->Reg[LHSReg])) +#else +#define LHS (state->Reg[LHSReg]) +#endif +#else +#define LHS ((LHSReg == 15) ? R15PC : (state->Reg[LHSReg]) ) +#endif + +#define MULDESTReg (BITS(16,19)) +#define MULLHSReg (BITS(0,3)) +#define MULRHSReg (BITS(8,11)) +#define MULACCReg (BITS(12,15)) + +#define DPImmRHS (ARMul_ImmedTable[BITS(0,11)]) +#define DPSImmRHS temp = BITS(0,11) ; \ + rhs = ARMul_ImmedTable[temp] ; \ + if (temp > 255) /* there was a shift */ \ + ASSIGNC(rhs >> 31) ; + +#ifdef MODE32 +#define DPRegRHS ((BITS(4,11)==0) ? state->Reg[RHSReg] \ + : GetDPRegRHS(state, instr)) +#define DPSRegRHS ((BITS(4,11)==0) ? state->Reg[RHSReg] \ + : GetDPSRegRHS(state, instr)) +#else +#define DPRegRHS ((BITS(0,11)<15) ? state->Reg[RHSReg] \ + : GetDPRegRHS(state, instr)) +#define DPSRegRHS ((BITS(0,11)<15) ? state->Reg[RHSReg] \ + : GetDPSRegRHS(state, instr)) +#endif + +#define LSBase state->Reg[LHSReg] +#define LSImmRHS (BITS(0,11)) + +#ifdef MODE32 +#define LSRegRHS ((BITS(4,11)==0) ? state->Reg[RHSReg] \ + : GetLSRegRHS(state, instr)) +#else +#define LSRegRHS ((BITS(0,11)<15) ? state->Reg[RHSReg] \ + : GetLSRegRHS(state, instr)) +#endif + +#define LSMNumRegs ((ARMword)ARMul_BitList[BITS(0,7)] + \ + (ARMword)ARMul_BitList[BITS(8,15)] ) +#define LSMBaseFirst ((LHSReg == 0 && BIT(0)) || \ + (BIT(LHSReg) && BITS(0,LHSReg-1) == 0)) + +#define SWAPSRC (state->Reg[RHSReg]) + +#define LSCOff (BITS(0,7) << 2) +#define CPNum BITS(8,11) + +/***************************************************************************\ +* Macro to rotate n right by b bits * +\***************************************************************************/ + +#define ROTATER(n,b) (((n)>>(b))|((n)<<(32-(b)))) + +/***************************************************************************\ +* Macros to store results of instructions * +\***************************************************************************/ + +#define WRITEDEST(d) if (DESTReg==15) \ + WriteR15(state, d) ; \ + else \ + DEST = d + +#define WRITESDEST(d) if (DESTReg == 15) \ + WriteSR15(state, d) ; \ + else { \ + DEST = d ; \ + ARMul_NegZero(state, d) ; \ + } + +#define BYTETOBUS(data) ((data & 0xff) | \ + ((data & 0xff) << 8) | \ + ((data & 0xff) << 16) | \ + ((data & 0xff) << 24)) +#define BUSTOBYTE(address,data) \ + if (state->bigendSig) \ + temp = (data >> (((address ^ 3) & 3) << 3)) & 0xff ; \ + else \ + temp = (data >> ((address & 3) << 3)) & 0xff + +#define LOADMULT(instr,address,wb) LoadMult(state,instr,address,wb) +#define LOADSMULT(instr,address,wb) LoadSMult(state,instr,address,wb) +#define STOREMULT(instr,address,wb) StoreMult(state,instr,address,wb) +#define STORESMULT(instr,address,wb) StoreSMult(state,instr,address,wb) + +#define POSBRANCH ((instr & 0x7fffff) << 2) +#define NEGBRANCH (0xff000000 | ((instr & 0xffffff) << 2)) + +/***************************************************************************\ +* Values for Emulate * +\***************************************************************************/ + +#define STOP 0 /* stop */ +#define CHANGEMODE 1 /* change mode */ +#define ONCE 2 /* execute just one interation */ +#define RUN 3 /* continuous execution */ + +/***************************************************************************\ +* Stuff that is shared across modes * +\***************************************************************************/ + +extern ARMword ARMul_Emulate26(ARMul_State *state) ; +extern ARMword ARMul_Emulate32(ARMul_State *state) ; +extern unsigned ARMul_MultTable[] ; /* Number of I cycles for a mult */ +extern ARMword ARMul_ImmedTable[] ; /* immediate DP LHS values */ +extern char ARMul_BitList[] ; /* number of bits in a byte table */ +extern void ARMul_Abort26(ARMul_State *state, ARMword) ; +extern void ARMul_Abort32(ARMul_State *state, ARMword) ; +extern unsigned ARMul_NthReg(ARMword instr,unsigned number) ; +extern void ARMul_MSRCpsr(ARMul_State *state, ARMword instr, ARMword rhs) ; +extern void ARMul_NegZero(ARMul_State *state, ARMword result) ; +extern void ARMul_AddCarry(ARMul_State *state, ARMword a, ARMword b, ARMword result) ; +extern void ARMul_AddOverflow(ARMul_State *state, ARMword a, ARMword b, ARMword result) ; +extern void ARMul_SubCarry(ARMul_State *state, ARMword a, ARMword b, ARMword result) ; +extern void ARMul_SubOverflow(ARMul_State *state, ARMword a, ARMword b, ARMword result) ; +extern void ARMul_CPSRAltered(ARMul_State *state) ; +extern void ARMul_R15Altered(ARMul_State *state) ; +extern ARMword ARMul_SwitchMode(ARMul_State *state,ARMword oldmode, ARMword newmode) ; +extern unsigned ARMul_NthReg(ARMword instr, unsigned number) ; +extern void ARMul_LDC(ARMul_State *state,ARMword instr,ARMword address) ; +extern void ARMul_STC(ARMul_State *state,ARMword instr,ARMword address) ; +extern void ARMul_MCR(ARMul_State *state,ARMword instr, ARMword source) ; +extern ARMword ARMul_MRC(ARMul_State *state,ARMword instr) ; +extern void ARMul_CDP(ARMul_State *state,ARMword instr) ; +extern unsigned IntPending(ARMul_State *state) ; +extern ARMword ARMul_Align(ARMul_State *state, ARMword address, ARMword data) ; +#define EVENTLISTSIZE 1024L + +/* Thumb support: */ + +typedef enum { + t_undefined, /* undefined Thumb instruction */ + t_decoded, /* instruction decoded to ARM equivalent */ + t_branch /* Thumb branch (already processed) */ +} tdstate; + +extern tdstate ARMul_ThumbDecode(ARMul_State *state,ARMword pc,ARMword tinstr, ARMword *ainstr); + +/***************************************************************************\ +* Macros to scrutinize instructions * +\***************************************************************************/ + + +#define UNDEF_Test +#define UNDEF_Shift +#define UNDEF_MSRPC +#define UNDEF_MRSPC +#define UNDEF_MULPCDest +#define UNDEF_MULDestEQOp1 +#define UNDEF_LSRBPC +#define UNDEF_LSRBaseEQOffWb +#define UNDEF_LSRBaseEQDestWb +#define UNDEF_LSRPCBaseWb +#define UNDEF_LSRPCOffWb +#define UNDEF_LSMNoRegs +#define UNDEF_LSMPCBase +#define UNDEF_LSMUserBankWb +#define UNDEF_LSMBaseInListWb +#define UNDEF_SWPPC +#define UNDEF_CoProHS +#define UNDEF_MCRPC +#define UNDEF_LSCPCBaseWb +#define UNDEF_UndefNotBounced +#define UNDEF_ShortInt +#define UNDEF_IllegalMode +#define UNDEF_Prog32SigChange +#define UNDEF_Data32SigChange + diff --git a/sim/arm/armfpe.h b/sim/arm/armfpe.h new file mode 100644 index 0000000..b10af16 --- /dev/null +++ b/sim/arm/armfpe.h @@ -0,0 +1,1351 @@ +/* armfpe.h -- ARMulator pre-compiled FPE: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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. */ + +/* Array containing the Floating Point Emualtor (FPE). */ + + +unsigned long fpecode[] = { +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00070000,0x00000000,0xe92d400e,0xeb0013ef, +0xe28f00d4,0xe1a00120,0xe38004ea,0xe3a01004, +0xe5912000,0xe24f3028,0xe1500002,0x15832000, +0x15810000,0xe3a00001,0xe8bd800e,0xe28d9040, +0xe1a0a00e,0xe24f7048,0xe597b000,0xe20b74ee, +0xe14f8000,0xe2088040,0xe388809b,0xe121f008, +0xe35704ea,0x004bb007,0x01a0b10b,0x028bf00c, +0xe20b733b,0xe3570339,0x01a0ba0b,0x01a0ba2b, +0x059bb00c,0x0249800c,0x08880e00,0x0919ff80, +0xe24f7094,0xe1a0f007,0xe14f8000,0xe2088040, +0xe3888093,0xe121f008,0xe8dd7fff,0xe1a00000, +0xe28dd03c,0xe8fd8000,0xe14f8000,0xe2088040, +0xe3888093,0xe121f008,0xe8bd1fff,0xe28dd00c, +0xe1b0f00e,0xe14f8000,0xe2088040,0xe3888093, +0xe121f008,0xe28dd01c,0xe8bd1f80,0xe28dd00c, +0xe1b0f00e,0x00002100,0xe90d4007,0xe14f0000, +0xe24d1010,0xe10f2000,0xe20220c0,0xe3822003, +0xe121f002,0xe169f000,0xe8914007,0xe24dd040, +0xe8cd7fff,0xe24fcf6b,0xe58de03c,0xe24ea004, +0xe14f9000,0xe20990c0,0xe3899003,0xe121f009, +0xe4ba9008,0xe20987fe,0xe2197010,0xe0077aa9, +0xe0288a07,0x02097402,0x00077509,0x00888007, +0xe2097c0f,0xe3370c01,0x0209733e,0x0337033a, +0x008ff8a8,0xea00009f,0xea0003b7,0xea0003b6, +0xea000307,0xea000306,0xea0003b3,0xea0003b2, +0xea000303,0xea000302,0xea0003c3,0xea0003c2, +0xea00030d,0xea00030c,0xea0003bf,0xea0003be, +0xea000309,0xea000308,0xea0003cf,0xea0003ce, +0xea000314,0xea000313,0xea0003cb,0xea0003ca, +0xea000310,0xea00030f,0xea0003db,0xea0003da, +0xea00031a,0xea000319,0xea0003d7,0xea0003d6, +0xea000316,0xea000315,0xea0003e7,0xea0003e6, +0xea000321,0xea000320,0xea0003f7,0xea0003f6, +0xea00032b,0xea00032a,0xea000449,0xea000448, +0xea000335,0xea000334,0xea000459,0xea000458, +0xea000340,0xea00033f,0xea000469,0xea000468, +0xea00034b,0xea00034a,0xea000479,0xea000478, +0xea000355,0xea000354,0xea000489,0xea000488, +0xea00035f,0xea00035e,0xea000499,0xea000498, +0xea00036a,0xea000369,0xea000ac8,0xea000ac5, +0xea000c3d,0xea000c3a,0xea000b7b,0xea000b78, +0xea000b79,0xea000b76,0xea000d34,0xea000d31, +0xea000d08,0xea000d05,0xea000e34,0xea000e31, +0xea000e1c,0xea000e19,0xea000ecf,0xea000ecc, +0xea000c2d,0xea000c2a,0xea000d28,0xea000d25, +0xea000cfc,0xea000cf9,0xea00123d,0xea00123a, +0xeaffff55,0xeaffff54,0xeaffff53,0xeaffff52, +0xeaffff51,0xeaffff50,0xea0007b8,0xea0007ec, +0xea00073c,0xea00073b,0xea000806,0xea000805, +0xea00080f,0xea00080e,0xeaffff47,0xeaffff46, +0xeaffff45,0xeaffff44,0xeaffff43,0xeaffff42, +0xeaffff41,0xeaffff40,0xeaffff3f,0xeaffff3e, +0xea00086f,0xea00086e,0xeaffff3b,0xeaffff3a, +0xea00086b,0xea00086a,0xeaffff37,0xeaffff36, +0xea0007ff,0xea0007fe,0xeaffff33,0xeaffff32, +0xea0007fb,0xea0007fa,0xea000914,0xea0008f3, +0xea00091f,0xea0008fb,0xea00092b,0xea000904, +0xea0009dc,0xea0009d9,0xea0009fd,0xea0009fa, +0xea000ef8,0xea000ef5,0xea000ef6,0xea000ef3, +0xea000f9d,0xea000f9a,0xea00111e,0xea00111b, +0xea00111c,0xea001119,0xea00104e,0xea00104b, +0xea001147,0xea001144,0xea001145,0xea001142, +0xea00125a,0xea001257,0xeaffff13,0xeaffff12, +0xeaffff11,0xeaffff10,0xe3190c0e,0x1affff0e, +0xe3190c01,0x13190302,0x0affff0b,0xe28fb016, +0xe79b7d27,0xe14fb000,0xe1a0be2b,0xe28bb010, +0xe1170b37,0x0affff51,0xeaffff29,0x8000f0f0, +0x80000f0f,0x8000cccc,0x80003333,0x8000ff00, +0x800000ff,0x8000aaaa,0x80005555,0x8000cfcf, +0x80003030,0x800055aa,0x8000aa55,0x80005faf, +0x8000a050,0x80000000,0x8000ffff,0xe1300007, +0x5a000002,0xea00004a,0xe3100102,0x1a000048, +0xe053400b,0x4a00002d,0xe2745020,0xda00001b, +0xe092243a,0x20822518,0x30922518,0xe0b11438, +0xe1a0451a,0x2a000006,0xe0922fa4,0xe2b11000, +0x31b0f00e,0xe3a01102,0xe2833001,0xe1a040a4, +0xe1b0f00e,0xe2833001,0xe1a040a4,0xe1844f82, +0xe1a020a2,0xe1822f81,0xe1a01061,0xe0922fa4, +0xe2a11000,0xe1b0f00e,0xe1a04538,0xe0922fa4, +0xe2b11000,0x23a01102,0x22833001,0xe1b0f00e, +0xe2545040,0xaafffff7,0xe2444020,0xe2645020, +0xe0922438,0xe2b11000,0xe1a04518,0xe184443a, +0x2affffe7,0xe0922fa4,0xe2b11000,0x31b0f00e, +0xe3a01102,0xe2833001,0xe1a040a4,0xe1b0f00e, +0xe2644000,0xe1a0300b,0xe1a05001,0xe1a01008, +0xe1a08005,0xe1a05002,0xe1a0200a,0xe1a0a005, +0xe2745020,0xdaffffe5,0xe092243a,0x20822518, +0x30922518,0xe0b11438,0xe1a0451a,0x2affffd0, +0xe0922fa4,0xe2b11000,0x31b0f00e,0xe3a01102, +0xe2833001,0xe1a040a4,0xe1b0f00e,0xe3100102, +0x1affffb6,0xe053600b,0x4a00003d,0x01510008, +0x0152000a,0x0a00004f,0x3a000039,0xe3a04000, +0xe2765020,0xda00001a,0xe054451a,0xe0d2263a, +0x30422518,0x20522518,0xe0d11638,0x5a000002, +0xe0922fa4,0xe2a11000,0xe1b0f00e,0xe0944004, +0xe0b22002,0xe0b11001,0xe2433001,0x5afffffa, +0xe0922fa4,0xe2b11000,0x31b0f00e,0xe3a01102, +0xe2833001,0xe1a040a4,0xe1b0f00e,0xe0544538, +0x41b0f00e,0xe2d22000,0xe2d11000,0x41b0f00e, +0xeaffffed,0xe3a04000,0xe2565040,0xaafffff6, +0xe2466020,0xe2665020,0xe054751a,0xe0d4463a, +0x30444518,0x20544518,0xe0d22638,0xe2d11000, +0x5a000002,0xe0922fa4,0xe2a11000,0xe1b0f00e, +0xe0977007,0xe0b44004,0xe0b22002,0xe0b11001, +0xe2433001,0x5afffff9,0xe0922fa4,0xe2b11000, +0x31b0f00e,0xe3a01102,0xe2833001,0xe1a040a4, +0xe1b0f00e,0xe2666000,0xe2200102,0xe1a0300b, +0xe1a05001,0xe1a01008,0xe1a08005,0xe1a05002, +0xe1a0200a,0xe1a0a005,0xe3a04000,0xe2765020, +0xdaffffd7,0xe054451a,0xe0d2263a,0x30422518, +0x20522518,0xe0d11638,0x5affffbf,0xe0922fa4, +0xe2a11000,0xe1b0f00e,0xe3a03000,0xe3a02000, +0xe3a01000,0xe3a04000,0xe1b0f00e,0xe1a07000, +0xe1a08001,0xe1a0a002,0xe1a0b003,0xe0200007, +0xe1914002,0x1198400a,0x0afffff2,0xe3b054ff, +0xe0a3300b,0xe185b425,0xe043392b,0xe92c4209, +0xe1a04821,0xe1c1500b,0xe1a06822,0xe1c2700b, +0xe1c8900b,0xe1a08828,0xe1cab00b,0xe1a0a82a, +0xe0030b96,0xe0020b94,0xe0010994,0xe0000a97, +0xe0933000,0xe0000a95,0xe0b22000,0xe0000895, +0xe0b11000,0x33a0e000,0x23a0e001,0xe0000996, +0xe0922000,0xe2b11000,0xe2aee000,0xe0000897, +0xe0922000,0xe2b11000,0xe2aee000,0xe18ee803, +0xe1a03823,0xe1833802,0xe1a02822,0xe1822801, +0xe1a01821,0xe181180e,0xe3cee0ff,0xe0000b95, +0xe00b0b97,0xe09eb00b,0xe0b33000,0xe0000896, +0xe0b22000,0xe0000894,0xe0a11000,0xe0000a94, +0xe00a0a96,0xe09aa003,0xe0b22000,0xe2a11000, +0xe0000997,0xe09a4000,0xe0000995,0xe0b22000, +0xe2b11000,0xe8bc4209,0x4a000005,0xe09bb00b, +0xe0b44004,0xe0b22002,0xe0b11001,0xe2433001, +0x5afffff9,0xe0922fa4,0xe2b11000,0x31b0f00e, +0xe3a01102,0xe2833001,0xe1a040a4,0xe1b0f00e, +0xe1a07000,0xe1a08001,0xe1a0a002,0xe1a0b003, +0xe3a00000,0xe3a01102,0xe3b02100,0xe2e23901, +0xe0200007,0xe1914002,0x1198400a,0x0affff9d, +0xe043300b,0xe2833901,0xe2433001,0xe3a0b000, +0xe052500a,0xe0d14008,0x23a01003,0x2a00000c, +0xe1a05002,0xe1a04001,0xe3a01001,0xe2433001, +0xe0955005,0xe0b44004,0xe2abb000,0xe055700a, +0xe0d46008,0x31b0b0ab,0x21a05007,0x21a04006, +0xe0a11001,0xe0955005,0xe0b44004,0xe2abb000, +0xe055700a,0xe0d46008,0x31b0b0ab,0x21a05007, +0x21a04006,0xe0a11001,0xe0955005,0xe0b44004, +0xe2abb000,0xe055700a,0xe0d46008,0x31b0b0ab, +0x21a05007,0x21a04006,0xe0a11001,0xe0955005, +0xe0b44004,0xe2abb000,0xe055700a,0xe0d46008, +0x31b0b0ab,0x21a05007,0x21a04006,0xe0b11001, +0x3affffda,0xe1942005,0x01b0f00e,0xe3a02001, +0xe0955005,0xe0b44004,0xe2abb000,0xe055700a, +0xe0d46008,0x31b0b0ab,0x21a05007,0x21a04006, +0xe0a22002,0xe0955005,0xe0b44004,0xe2abb000, +0xe055700a,0xe0d46008,0x31b0b0ab,0x21a05007, +0x21a04006,0xe0a22002,0xe0955005,0xe0b44004, +0xe2abb000,0xe055700a,0xe0d46008,0x31b0b0ab, +0x21a05007,0x21a04006,0xe0a22002,0xe0955005, +0xe0b44004,0xe2abb000,0xe055700a,0xe0d46008, +0x31b0b0ab,0x21a05007,0x21a04006,0xe0b22002, +0x3affffda,0xe0955005,0xe0b44004,0x2a000001, +0xe1540008,0x0155000a,0xe2b22000,0xe2b11000, +0x31b0f00e,0xe2a33000,0xe3a01102,0xe1b0f00e, +0xe1b04883,0x0affff37,0xe2833901,0xe2433001, +0xe1b030a3,0xe1a05002,0x32414102,0x22414101, +0x33a07201,0x23a07202,0xe3a01102,0xe0955005, +0xe0b44004,0xe0216007,0x31540006,0x20444006, +0x20211087,0xe1b070e7,0x5afffff7,0xe1942005, +0x01b0f00e,0xe3a02000,0xe0955005,0xe0b44004, +0xe0a00000,0xe0226007,0xe055a006,0xe0d48001, +0x31b000a0,0x21a0500a,0x21a04008,0x20222087, +0x20211fa7,0xe1b070a7,0x1afffff2,0xe0955005, +0xe0b44004,0xe0b70007,0xe0d5a002,0xe0d48001, +0x31b000a0,0x21a0500a,0x21a04008,0x22222001, +0x23a07102,0xe3a00000,0xe0977007,0xe0b55005, +0xe0b44004,0x2a000002,0xe1540001,0x01550002, +0x03570101,0xe2b22000,0xe2b11000,0xe2a33000, +0x23a01102,0xe1b0f00e,0xe1b07004,0x42644000, +0xe3a0b901,0xe3a0a000,0xe1a08004,0xe1b04828, +0x01a08808,0x128bb010,0xe1b04c28,0x01a08408, +0x128bb008,0xe1b04e28,0x01a08208,0x128bb004, +0xe1b04f28,0x01a08108,0x128bb002,0xe1b04fa8, +0x01a08088,0x024bb001,0xe1b0f00e,0xe1a07000, +0xe1a0b003,0xe24b40fe,0xe2544c3f,0xda000011, +0xe2745020,0x4a000003,0xe3a0a000,0xe1a08531, +0xe1a08518,0xe1b0f00e,0xe1a08001,0xe1a0a002, +0xe2745040,0x41b0f00e,0xe1a0a53a,0xe1a0a51a, +0xe1b0f00e,0x03a04001,0x03a08102,0xe3a0a000, +0x028bb001,0x01b0f00e,0xe3a04000,0xe3a08000, +0xe3a0a000,0xe3a0b000,0xe1b0f00e,0xe1a07000, +0xe1a0b003,0xe24b40fe,0xe2544c3f,0xdafffff0, +0xe2745020,0x4a000007,0xe3a0a000,0xe1b04531, +0xe2a44000,0xe1b08514,0x31b0f00e,0xe1a08068, +0xe28bb001,0xe1b0f00e,0xe1a08001,0xe1a0a002, +0xe2745040,0xe3e04000,0x41b0f00e,0xe1b0a53a, +0xe2aaa000,0xe1b0a51a,0xe2b88000,0x31b0f00e, +0xe1a0a0aa,0xe18aaf88,0xe1a08068,0xe28bb001, +0xe1b0f00e,0xe38ee101,0xe24340fe,0xe2544c3f, +0xda000032,0xe2745020,0x4a000018,0xe1a08411, +0x01a08002,0x11a0a002,0x03a0a000,0xe3a02000, +0xe1a01531,0xe2194060,0x1a000007,0xe19aa088, +0x00088f81,0xe0911fa8,0x31b01511,0x31b0f00e, +0xe1a01061,0xe2833001,0xe1b0f00e,0xe3540060, +0x1198a00a,0x0a000003,0xe0304d04,0x5a000001, +0xe2911001,0xeafffff3,0xe1a01511,0xe1b0f00e, +0xe2745040,0xd1b0f00e,0xe2444020,0xe1a08412, +0xe1b02532,0xe2194060,0x1a00000a,0xe1b0a088, +0x00088f82,0xe0822fa8,0xe1b02512,0xe2b11000, +0x31b0f00e,0xe1a020a2,0xe1822f81,0xe1a01061, +0xe2833001,0xe1b0f00e,0xe3540060,0x13580000, +0x0afffff4,0xe0304d04,0x42822001,0xeafffff1, +0x0a000011,0xe2194060,0x1a000006,0xe1918002, +0x01b0f00e,0xe3a01000,0xe3a02000,0xe3a03000, +0xe3a04008,0xe1a0f00e,0xe1918002,0x13540060, +0x0afffff5,0xe0304d04,0x5afffff3,0xe3a01102, +0xe3b02100,0xe2e23901,0xe1b0f00e,0xe2194060, +0x1afffff4,0xe1924081,0x1afffff7,0xeaffffea, +0xe1a04000,0xe1a00007,0xe1a07004,0xe1a04001, +0xe1a01008,0xe1a08004,0xe1a04002,0xe1a0200a, +0xe1a0a004,0xe1a04003,0xe1a0300b,0xe1a0b004, +0xe1b0f00e,0xe209ba07,0xe08c542b,0xe209780f, +0xe79da727,0xe21980ff,0xe04a8108,0x178d8727, +0xe2199902,0xe3899901,0xe1a09789,0xe4ba6004, +0x14ba7004,0xe88503c0,0xeafffcae,0xe209ba07, +0xe08c542b,0xe209780f,0xe79da727,0xe21980ff, +0xe04a8108,0x178d8727,0xe2199902,0xe3899905, +0xe1a09789,0xe4ba6004,0xe4ba7004,0xe4ba8000, +0xe88503c0,0xeafffc9f,0xe209ba07,0xe08c542b, +0xe209780f,0xe79da727,0xe21980ff,0xe08a8108, +0x178d8727,0xe2199902,0xe3899901,0xe1a09789, +0xe4ba6004,0x14ba7004,0xe88503c0,0xeafffc91, +0xe209ba07,0xe08c542b,0xe209780f,0xe79da727, +0xe21980ff,0xe08a8108,0x178d8727,0xe2199902, +0xe3899905,0xe1a09789,0xe4ba6004,0xe4ba7004, +0xe4ba8000,0xe88503c0,0xeafffc82,0xe209ba07, +0xe08cc42b,0xe209780f,0xe337080f,0x179da727, +0xe21980ff,0xe04aa108,0xe2199902,0xe3899901, +0xe1a0b789,0xe4ba8004,0x14ba9004,0xe88c0f00, +0xeafffc83,0xe209ba07,0xe08c542b,0xe209780f, +0xe79da727,0xe21980ff,0xe04aa108,0x178da727, +0xe2199902,0xe3899901,0xe1a09789,0xe4ba6004, +0x14ba7004,0xe88503c0,0xeafffc66,0xe209ba07, +0xe08cc42b,0xe209780f,0xe337080f,0x179da727, +0xe21980ff,0xe04aa108,0xe2199902,0xe3899905, +0xe1a0b789,0xe4ba8004,0xe4ba9004,0xe4baa000, +0xe88c0f00,0xeafffc66,0xe209ba07,0xe08c542b, +0xe209780f,0xe79da727,0xe21980ff,0xe04aa108, +0x178da727,0xe2199902,0xe3899905,0xe1a09789, +0xe4ba6004,0xe4ba7004,0xe4ba8000,0xe88503c0, +0xeafffc48,0xe209ba07,0xe08cc42b,0xe209780f, +0xe337080f,0x179da727,0xe21980ff,0xe08aa108, +0xe2199902,0xe3899901,0xe1a0b789,0xe4ba8004, +0x14ba9004,0xe88c0f00,0xeafffc49,0xe209ba07, +0xe08c542b,0xe209780f,0xe79da727,0xe21980ff, +0xe08aa108,0x178da727,0xe2199902,0xe3899901, +0xe1a09789,0xe4ba6004,0x14ba7004,0xe88503c0, +0xeafffc2c,0xe209ba07,0xe08cc42b,0xe209780f, +0xe337080f,0x179da727,0xe21980ff,0xe08aa108, +0xe2199902,0xe3899905,0xe1a0b789,0xe4ba8004, +0xe4ba9004,0xe4baa000,0xe88c0f00,0xeafffc2c, +0xe209ba07,0xe08c542b,0xe209780f,0xe79da727, +0xe21980ff,0xe08aa108,0x178da727,0xe2199902, +0xe3899905,0xe1a09789,0xe4ba6004,0xe4ba7004, +0xe4ba8000,0xe88503c0,0xeafffc0e,0xe2095a07, +0xe08c5425,0xe895000f,0xe3a04002,0xe0044729, +0xe3844001,0xe1340ea3,0xe1844d23,0xe28f7004, +0xe28f5f6f,0x1085f104,0xe209780f,0xe79da727, +0xe21980ff,0xe04a8108,0x178d8727,0xe4aa0004, +0xe3130101,0x14aa1000,0xeafffbfa,0xe2095a07, +0xe08c5425,0xe895000f,0xe3a04002,0xe0044729, +0xe3844005,0xe1340ea3,0xe1844d23,0xe28f7004, +0xe28f5f5b,0x1085f104,0xe209780f,0xe79da727, +0xe21980ff,0xe04a8108,0x178d8727,0xe4aa0004, +0xe4aa1004,0xe4aa2000,0xeafffbe6,0xe2095a07, +0xe08c5425,0xe895000f,0xe3a04002,0xe0044729, +0xe3844001,0xe1340ea3,0xe1844d23,0xe28f7004, +0xe28f5f47,0x1085f104,0xe209780f,0xe79da727, +0xe21980ff,0xe08a8108,0x178d8727,0xe4aa0004, +0xe3130101,0x14aa1000,0xeafffbd2,0xe2095a07, +0xe08c5425,0xe895000f,0xe3a04002,0xe0044729, +0xe3844005,0xe1340ea3,0xe1844d23,0xe28f7004, +0xe28f50cc,0x1085f104,0xe209780f,0xe79da727, +0xe21980ff,0xe08a8108,0x178d8727,0xe4aa0004, +0xe4aa1004,0xe4aa2000,0xeafffbbe,0xe2095a07, +0xe08c5425,0xe895000f,0xe3a04002,0xe0044729, +0xe3844001,0xe1340ea3,0xe1844d23,0xe28f7004, +0xe28f507c,0x1085f104,0xe209780f,0xe337080f, +0x179da727,0xe21980ff,0xe04aa108,0xe4aa0004, +0xe3130101,0x14aa1000,0xeafffbb2,0xe2095a07, +0xe08c5425,0xe895000f,0xe3a04002,0xe0044729, +0xe3844001,0xe1340ea3,0xe1844d23,0xe28f7004, +0xe28f502c,0x1085f104,0xe209780f,0xe79da727, +0xe21980ff,0xe04aa108,0x178da727,0xe4aa0004, +0xe3130101,0x14aa1000,0xeafffb96,0xe08ff104, +0xeb00036b,0xe1a0f007,0xea0000b6,0xeb000368, +0xea0000ea,0xeb000366,0xea000123,0xeb000364, +0xea0001ca,0xea000124,0xe1a0f007,0xeb000360, +0xea000134,0xeb00035e,0xea00014b,0xeb00035c, +0xea0001bd,0xeb00035a,0xeb000359,0xeb000358, +0xeb000357,0xeb000356,0xeb000355,0xeb000354, +0xeb000353,0xea000156,0xea00016f,0xeb000350, +0xe1a0f007,0xeb00034e,0xea00018c,0xeb00034c, +0xea0001ad,0xeb00034a,0xeb000349,0xeb000348, +0xeb000347,0xeb000346,0xeb000345,0xeb000344, +0xeb000343,0xea00019f,0xea00008d,0xeb000340, +0xea0000c1,0xeb00033e,0xe1a0f007,0xeb00033c, +0xea00019d,0xeb00033a,0xeb000339,0xeb000338, +0xeb000337,0xeb000336,0xeb000335,0xeb000334, +0xeb000333,0xea00024f,0xea00024e,0xeb000330, +0xea00024c,0xeb00032e,0xea00024a,0xeb00032c, +0xe1a0f007,0xe2095a07,0xe08c5425,0xe895000f, +0xe3a04002,0xe0044729,0xe3844005,0xe1340ea3, +0xe1844d23,0xe28f7004,0xe24f5f4b,0x1085f104, +0xe209780f,0xe337080f,0x179da727,0xe21980ff, +0xe04aa108,0xe4aa0004,0xe4aa1004,0xe4aa2004, +0xeafffb48,0xe2095a07,0xe08c5425,0xe895000f, +0xe3a04002,0xe0044729,0xe3844005,0xe1340ea3, +0xe1844d23,0xe28f7004,0xe24f5f5f,0x1085f104, +0xe209780f,0xe79da727,0xe21980ff,0xe04aa108, +0x178da727,0xe4aa0004,0xe4aa1004,0xe4aa2000, +0xeafffb2c,0xe2095a07,0xe08c5425,0xe895000f, +0xe3a04002,0xe0044729,0xe3844001,0xe1340ea3, +0xe1844d23,0xe28f7004,0xe24f5f73,0x1085f104, +0xe209780f,0xe337080f,0x179da727,0xe21980ff, +0xe08aa108,0xe4aa0004,0xe3130101,0x14aa1000, +0xeafffb20,0xe2095a07,0xe08c5425,0xe895000f, +0xe3a04002,0xe0044729,0xe3844001,0xe1340ea3, +0xe1844d23,0xe28f7004,0xe24f5f87,0x1085f104, +0xe209780f,0xe79da727,0xe21980ff,0xe08aa108, +0x178da727,0xe4aa0004,0xe3130101,0x14aa1000, +0xeafffb04,0xe2095a07,0xe08c5425,0xe895000f, +0xe3a04002,0xe0044729,0xe3844005,0xe1340ea3, +0xe1844d23,0xe28f7004,0xe24f5f9b,0x1085f104, +0xe209780f,0xe337080f,0x179da727,0xe21980ff, +0xe08aa108,0xe4aa0004,0xe4aa1004,0xe4aa2004, +0xeafffaf8,0xe2095a07,0xe08c5425,0xe895000f, +0xe3a04002,0xe0044729,0xe3844005,0xe1340ea3, +0xe1844d23,0xe28f7004,0xe24f5faf,0x1085f104, +0xe209780f,0xe79da727,0xe21980ff,0xe08aa108, +0x178da727,0xe4aa0004,0xe4aa1004,0xe4aa2000, +0xeafffadc,0xe3c03102,0xe2000102,0xe1b05883, +0x12955802,0x0a00000e,0xe3320000,0x01922c81, +0xe2012080,0x000220a1,0xe0911002,0x31a01081, +0xe2a33000,0xe2533dfe,0x9a00001c,0xe35300ff, +0x31800b83,0x318004a1,0x33a03202,0x31a0f007, +0xea000008,0xe1b04c03,0xe18000a4,0xe3a03202, +0x13c11102,0x11800421,0x11a0f007,0xe1922001, +0x01a0f007,0xea000015,0xe380047f,0xe3800502, +0xe3a03202,0xe3a04004,0xe59c5080,0xe1855004, +0xe58c5080,0xe1140825,0x11a00004,0x1a000e8a, +0xe3540004,0x11a0f007,0xe3a04010,0xeafffff5, +0xe3730017,0xda000005,0xe1a01521,0xe3811501, +0xe2633000,0xe1800331,0xe3a03202,0xe1a0f007, +0xe3a03202,0xe3a04008,0xeaffffea,0xe3c03102, +0xe2000102,0xe1b05883,0x12955802,0x0a000012, +0xe1b04b02,0xe2024b01,0x000440a2,0xe0922004, +0xe2b11000,0xe2a33000,0xe0922002,0xe0a11001, +0xe2533b0f,0x9a000019,0xe2834001,0xe3540b02, +0x31800a03,0x31800621,0x31a01a01,0x31811622, +0x33a03206,0x31a0f007,0xea00000a,0xe1b04a83, +0xe18000a4,0xe3a03206,0x13c11102,0x118005a1, +0x11a01a81,0x118115a2,0x11a0f007,0xe1922001, +0x01a0f007,0xea000014,0xe380047f,0xe380060f, +0xe3a01000,0xe3a03206,0xe3a04004,0xeaffffc1, +0xe3730034,0xda00000c,0xe1a026a2,0xe1822981, +0xe1a016a1,0xe3811702,0xe2633000,0xe2534020, +0x21a01431,0x32634020,0x31800331,0x31a01411, +0x31811332,0xe3a03206,0xe1a0f007,0xe3a01000, +0xe3a03206,0xe3a04008,0xeaffffae,0xe2000102, +0xe1800003,0xe3a0320a,0xe1a0f007,0xe3a02000, +0xe1a03080,0xe1b03c23,0x133300ff,0x11a01400, +0x13811102,0x12833dfe,0x11a0f007,0xe1933383, +0x11a01400,0x13c11102,0x11a0f007,0xe1b01480, +0x01a0f007,0xe3a03dfe,0x52433001,0x51b01081, +0x5afffffc,0xe1a0f007,0xe1a01e80,0xe3c03102, +0xe2000102,0xe18001a3,0xe3a03206,0xe21026ff, +0x133206ff,0x1280030e,0x11a0f007,0xe1800182, +0xe3320000,0x11a0f007,0xe1912600,0x01a0f007, +0xe1a01a21,0xe1911600,0xe2000102,0xe380030e, +0x52400601,0x51b01081,0x5afffffc,0xe1a01081, +0xe1800621,0xe1a01a01,0xe1a0f007,0xe3a02000, +0xe1a03080,0xe1b03c23,0x133300ff,0xe1a01400, +0x13811102,0x12833dfe,0xe2000102,0xe1800003, +0xe3a0320a,0x11a0f007,0xe1800380,0xe31000ff, +0x13c11102,0x11a0f007,0xe1b01081,0x01a0f007, +0xe3800dfe,0x52400001,0x51b01081,0x5afffffc, +0xe1a0f007,0xe1a03080,0xe1b03aa3,0x12834001, +0x13340b02,0xe1a02581,0xe1a01aa1,0xe1811580, +0x13811102,0x12833b0f,0x11a0f007,0xe1933203, +0x11a0f007,0xe0922002,0xe0a11001,0xe1924001, +0x01a0f007,0xe3a03b0f,0xe1b01001,0x52433001, +0xe3a04000,0x51844fa2,0x51844081,0x51a02082, +0x51b01004,0x5afffff8,0xe1a0f007,0xe1a03080, +0xe1b03aa3,0x12834001,0x13340b02,0x0a00000f, +0xe1b04201,0xe1a01a21,0xe1811600,0xe2014c01, +0x000440a1,0xe0911004,0xe2a33000,0xe2000102, +0xe2533d0e,0x9affff49,0xe35300ff,0x31800b83, +0x318004a1,0x33a03202,0x31a0f007,0xeaffff35, +0xe1812600,0xe1a01a21,0xe1811600,0xe2000102, +0xe1b04c03,0xe18000a4,0xe3a03202,0x118004a1, +0x11a0f007,0xe3320000,0x01a0f007,0xeaffff3f, +0xe1a03080,0xe1b03aa3,0x12834001,0x13340b02, +0xe1a02581,0xe1a01aa1,0xe1811580,0x13811102, +0x12833b0f,0xe2000102,0xe1800003,0xe3a0320a, +0x11a0f007,0xe1800200,0xe31000ff,0x11a0f007, +0xe0922002,0xe0a11001,0xe1924001,0x01a0f007, +0xe3800b0f,0xe1b01001,0x52400001,0xe3a04000, +0x51844fa2,0x51844081,0x51a02082,0x51b01004, +0x5afffff8,0xe1a0f007,0xe3c03102,0xe1a0f007, +0x9a209a84,0xfbcff799,0x00003ffd,0xe92c0080, +0xe28f7004,0xe3c44007,0xeafffe2b,0xe8bc0080, +0xe1b05883,0x12955802,0x0a000099,0xe3a05901, +0xe2455001,0xe1530005,0x3a000006,0xe2855003, +0xe1530005,0x0351020a,0x33a04000,0x33a05000, +0x392c4ff0,0x3a000021,0xe92c4fcf,0xe3a00902, +0xe2404003,0xe0644083,0xebfffc46,0xe24bb001, +0xe24f4078,0xe894000e,0xebfffb4b,0xe3a04901, +0xe2444002,0xe0434004,0xe2644020,0xe1a09431, +0xe1510419,0x03520000,0x1210b102,0x12899001, +0xe200b102,0xe8bc000f,0xe92c0a00,0xeb0000bf, +0xe59c4004,0xe1b04004,0x5bfffb90,0x4bfffb3a, +0xe3a05901,0xe2455001,0xe1530005,0x3a000051, +0xe2855003,0xe1530005,0x0351020a,0x2a000040, +0xe3a04901,0xe2844002,0xe0544003,0xe2645020, +0xe1a03512,0x11a02432,0x11822511,0x11a01431, +0xe1a04e21,0xe3a07003,0xe3c1120f,0xe0933003, +0xe0b22002,0xe0a11001,0xe1a08101,0xe1888f22, +0xe1a0a102,0xe18aaf23,0xe092200a,0xe0a11008, +0xe2577001,0x11a04204,0x11844e21,0x1afffff1, +0xe1915002,0x03a06000,0x0a000019,0xe3a0700f, +0xe1a05205,0xe1855e26,0xe1a06206,0xe1866e21, +0xe3c1120f,0xe0922002,0xe0a11001,0xe1a08101, +0xe1888f22,0xe0922102,0xe0a11008,0xe2577001, +0x1afffff2,0xe1a05205,0xe1855e26,0xe1a06206, +0xe1866e21,0xe1b01281,0x3a000005,0xe2866001, +0xe1911002,0x03c66001,0xe206100f,0xe351000a, +0x02466001,0xe8bc0008,0xeb000023,0xe2000102, +0xe1800221,0xe8bc0080,0xe18000a7,0xe1800004, +0xe1a01005,0xe1a02006,0xe3a0320e,0xe8bc4fc0, +0xe1a0f007,0xe8bc0030,0xe3150102,0x12644000, +0xe2844001,0xe2145102,0x12644000,0xe92c0030, +0xe3a07901,0xe3a0820a,0xe3a0a000,0xe287b002, +0xebfffb3a,0xeaffffb1,0xe8bc0030,0xe3150102, +0x12644000,0xe2444001,0xe2145102,0x12644000, +0xe92c0030,0xe3a07901,0xe3a0820a,0xe3a0a000, +0xe287b002,0xebfffad8,0xeaffffa4,0xe1a02003, +0xe3a03010,0xe0922002,0x3352020a,0x2242220a, +0xe0b33003,0x3afffffa,0xe1a01622,0xe3530064, +0xa2433064,0xa2811201,0xaafffffb,0xe353000a, +0xa243300a,0xa2811401,0xaafffffb,0xe1811a03, +0xe1b0f00e,0xe3530000,0x1a00000a,0xe1915002, +0x03a0320e,0x03a00000,0x01a0f007,0xe3110102, +0x1affff5d,0xe0922002,0xe0b11001,0xe2433001, +0x5afffffb,0xeaffff58,0xe2000102,0xe1800603, +0xe3800302,0xe18009a1,0xe1a01681,0xe18119a2, +0xe1a02682,0xe3a0320e,0xe1a0f007,0x9392ee8e, +0x921d5d07,0x00003fc3,0xe1915002,0x01b05a00, +0x1200540f,0x1355040f,0x0a0000ac,0xe92c4fd0, +0xe3a07000,0xe3a06000,0xe1a04a00,0xe3a05003, +0xeb00009a,0xe1a04001,0xe3a05008,0xeb000097, +0xe1a04002,0xe3a05008,0xeb000094,0xe1a02007, +0xe1b01006,0xe3a0303e,0xe2833901,0x4a000003, +0xe0922002,0xe0b11001,0xe2433001,0x5afffffb, +0xe3a06000,0xe3a07000,0xe1a04200,0xe3a05004, +0xeb000086,0xe1a09007,0xeb00000c,0xe3100101, +0x1bfffade,0x0bfffa88,0xe24f70a4,0xe8970d00, +0xebfffa85,0xe8bc4fd0,0xe2935001,0xda000090, +0xe1b057a5,0x1a0000a7,0xe2044007,0xeafffd46, +0xe3590014,0xd28f8084,0xd0889209,0xd8990d80, +0xd1b0f00e,0xe92c400f,0xe3a01102,0xe3a02000, +0xe3a00901,0xe2403001,0xe3590000,0x0a000011, +0xe92c000f,0xe2833003,0xe3b0120a,0x3bfffa6a, +0xe1b090a9,0x3afffffc,0xe8bc0d80,0x192c000f, +0xebfffa69,0x0a000007,0xe8bc0d80,0xe92c000f, +0xe1a00007,0xe1a01008,0xe1a0200a,0xe1a0300b, +0xebfffa61,0xeafffff1,0xe1a07000,0xe1a08001, +0xe1a0a002,0xe1a0b003,0xe8bc400f,0xe1b0f00e, +0x00000000,0x80000000,0x00000000,0x00003fff, +0x00000000,0xa0000000,0x00000000,0x00004002, +0x00000000,0xc8000000,0x00000000,0x00004005, +0x00000000,0xfa000000,0x00000000,0x00004008, +0x00000000,0x9c400000,0x00000000,0x0000400c, +0x00000000,0xc3500000,0x00000000,0x0000400f, +0x00000000,0xf4240000,0x00000000,0x00004012, +0x00000000,0x98968000,0x00000000,0x00004016, +0x00000000,0xbebc2000,0x00000000,0x00004019, +0x00000000,0xee6b2800,0x00000000,0x0000401c, +0x00000000,0x9502f900,0x00000000,0x00004020, +0x00000000,0xba43b740,0x00000000,0x00004023, +0x00000000,0xe8d4a510,0x00000000,0x00004026, +0x00000000,0x9184e72a,0x00000000,0x0000402a, +0x00000000,0xb5e620f4,0x80000000,0x0000402d, +0x00000000,0xe35fa931,0xa0000000,0x00004030, +0x00000000,0x8e1bc9bf,0x04000000,0x00004034, +0x00000000,0xb1a2bc2e,0xc5000000,0x00004037, +0x00000000,0xde0b6b3a,0x76400000,0x0000403a, +0x00000000,0x8ac72304,0x89e80000,0x0000403e, +0x00000000,0xad78ebc5,0xac620000,0x00004041, +0xe0977007,0xe0a66006,0xe0978107,0xe0a6af27, +0xe08a6106,0xe1a07008,0xe0977e24,0xe2a66000, +0xe1a04204,0xe2555001,0x1afffff4,0xe1b0f00e, +0xe1a03280,0xe1a038a3,0xe1a026a2,0xe1822981, +0xe1a016a1,0xe1811980,0xe3c11102,0xe2044007, +0xeafffcb9,0xe2144007,0x13540005,0x0a000003, +0xe2000102,0xe3540001,0x0afffda0,0xeafffdda, +0xe2633000,0xe3530040,0xaa000008,0xe2735020, +0x42435020,0x41a02531,0x51a02332,0x51822511, +0xe1a01331,0xe3a03000,0xe2044007,0xeafffca6, +0xe2000102,0xe3a01000,0xe3a02000,0xe1a03e84, +0xe3a04008,0xeafffd7b,0xe2144007,0x0a000003, +0xe3a00000,0xe3540003,0x0afffdae,0xbafffd71, +0xe3a01000,0xe3b02100,0xe2e23902,0xe2000102, +0xe1800003,0xe3540000,0x13a0320a,0xe3a04004, +0xeafffd6c,0xeafffffe,0xe209aa0f,0xe3190008, +0x1a000069,0xe2095007,0xe08c5205,0xe895000f, +0xe1b04d23,0xe28f7000,0x1afffc87,0xe1b04883, +0x12944802,0x0a00002b,0x5a000039,0xe354083e, +0xe20448ff,0x4a000049,0xe1a048a4,0xe2199060, +0x1a00000e,0xe2846002,0xe1922611,0xe3a02101, +0xe0012432,0x000220a1,0xe264401f,0xe1a01431, +0xe3320000,0x12811001,0xe3100102,0x12611000, +0xe0312000,0x4a000049,0xe78d152a,0xeafff805, +0xe3590060,0x1a000005,0xe264401f,0xe1a01431, +0xe3100102,0x12611000,0xe78d152a,0xeafff7fd, +0xe0307d09,0x5afffff7,0xe2846001,0xe1922611, +0x0afffff4,0xe264401f,0xe1a01431,0xe2811001, +0xe3100102,0x12611000,0xe0312000,0x4a000033, +0xe78d152a,0xeafff7ef,0xe31300ff,0x1a000003, +0xe1921001,0x1a000006,0xe78d152a,0xeafff7e9, +0xe1921001,0x0a000029,0xe28f70bc,0xe3a04001, +0xeafffd28,0xe02970a9,0xe3170020,0x0a000010, +0xea000003,0xe2199060,0x0a000008,0xe3590060, +0x0a00000b,0xe0307d09,0x5a000009,0xe3a01001, +0xe3100102,0x12611000,0xe78d152a,0xeafff7d5, +0xe2947802,0x5a000002,0xe3510102,0x03520000, +0x8afffff5,0xe3a01000,0xe78d152a,0xea000016, +0xe354083e,0x03510102,0xe2000102,0x03500102, +0x1a00000a,0xe3520000,0x0affffae,0xe2199060, +0x0a000004,0xe3590060,0x0affffaa,0xe0307d09, +0x5affffa8,0xea000001,0xe3520102,0x9affffa5, +0xe28f7014,0xe3a04001,0xeafffcfe,0xe2091007, +0xe3510006,0xaa000001,0xe78d152a,0xeafff7b5, +0xe2811003,0xe351000a,0x13a01001,0xe2099060, +0x13590020,0x1affffde,0xe78d152a,0xeafff7ad, +0xe3190080,0x1a000034,0xe2097a0f,0xe79d8527, +0xe209b807,0xe08cb62b,0xe1b07008,0x42688000, +0xe3a0a09e,0xe28aadfe,0x03a0a01f,0xe1b0c828, +0x01a08808,0x024aa010,0xe1b0cc28,0x01a08408, +0x024aa008,0xe1b0ce28,0x01a08208,0x024aa004, +0xe1b0cf28,0x01a08108,0x024aa002,0xe1b0cfa8, +0x01a08088,0x024aa001,0xe1b0cc08,0x1a000002, +0xe3a09000,0xe88b0780,0xeafff79d,0xe2199060, +0x1a000008,0xe1b0c08c,0xe208c080,0x000cc0a8, +0xe098800c,0xe2aaa000,0x23a08102,0xe3c880ff, +0xe88b0780,0xeafff792,0xe2399060,0x0afffffa, +0xe027cc89,0xe20cc102,0xe0988bac,0xe2aaa000, +0x23a08102,0xe3a09000,0xe3c880ff,0xe88b0780, +0xeafff787,0xe3190080,0x1afff75f,0xe2097a0f, +0xe79d8527,0xe209b807,0xe08cb62b,0xe1b07008, +0x42688000,0xe3a0a09e,0xe28aadfe,0x03a0a01f, +0xe1b09828,0x01a08808,0x024aa010,0xe1b09c28, +0x01a08408,0x024aa008,0xe1b09e28,0x01a08208, +0x024aa004,0xe1b09f28,0x01a08108,0x024aa002, +0xe1b09fa8,0x01a08088,0x024aa001,0xe3a09000, +0xe88b0780,0xeafff76a,0xe2097a0f,0xe79da527, +0xe3ca801f,0xe3d8881f,0x1a000002,0xe38aa000, +0xe58ca080,0xeafff762,0xe24f700c,0xe3a04001, +0xeafffc94,0xe2097a0f,0xe59ca080,0xe78da527, +0xeafff74c,0xe1b08e09,0x4a000037,0xe08c8c28, +0xe898000f,0xe1b04d23,0xe28f7000,0x1afffbae, +0xe2097807,0xe1a0b003,0xe1a0a002,0xe0208509, +0xe1a09001,0xe08cc627,0xe89c000f,0xe1b04d23, +0xe28f7000,0x1afffba4,0x188c000f,0xe3a04803, +0xe0945883,0x3094588b,0x2a000015,0xe0305008, +0x4a000009,0xe153000b,0x01510009,0x0152000a, +0xe10f7000,0xe2077206,0x33877102,0x13100102, +0x1227720a,0xe168f007,0xeafff72a,0xe19b4003, +0x019a4002,0x01994001,0x0a000003,0xe3100102, +0x1368f102,0x0368f202,0xeafff722,0xe368f206, +0xeafff720,0xe0945883,0x3a000001,0xe1915002, +0x1a000003,0xe094588b,0x3affffe3,0xe199500a, +0x0affffe1,0xe368f201,0xe24fc0c0,0xe24ccc24, +0xe24f7038,0xe3a04001,0xeafffc56,0xe2097807, +0xe2095602,0xe24f6074,0xe0866c28,0xe8960f00, +0xe0288505,0xeaffffca,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x80000000, +0x00000000,0x00003fff,0x00000000,0x80000000, +0x00000000,0x00004000,0x00000000,0xc0000000, +0x00000000,0x00004000,0x00000000,0x80000000, +0x00000000,0x00004001,0x00000000,0xa0000000, +0x00000000,0x00004001,0x00000000,0x80000000, +0x00000000,0x00003ffe,0x00000000,0xa0000000, +0x00000000,0x00004002,0xe2097807,0xe2095602, +0xe24f6e11,0xe0866c28,0xe8960f00,0xe0288505, +0xea00000b,0xe1b08e09,0x4afffff6,0xe08c8c28, +0xe898000f,0xe1b04d23,0xe28f7000,0x1afffb46, +0xe2097807,0xe1a0b003,0xe1a0a002,0xe0208509, +0xe1a09001,0xe08cc627,0xe89c000f,0xe1b04d23, +0xe28f7000,0x1afffb3c,0x188c000f,0xe3a04803, +0xe0945883,0x3094588b,0x2a00000b,0xe0305008, +0x4affffa1,0xe153000b,0x01510009,0x0152000a, +0xe10f7000,0xe2077206,0x33877102,0x13100102, +0x1227720a,0xe168f007,0xeafff6c2,0xe0945883, +0x3a000001,0xe1915002,0x1a000003,0xe094588b, +0x3affffed,0xe199500a,0x0affffeb,0xe368f201, +0xeafff6b8,0xe2099060,0xe3590020,0x03a07209, +0x0a000006,0xe3a00000,0xe08cb42a,0xe28f708c, +0xe2877c05,0xea0000de,0xe357020e,0x0afffff4, +0xe24f8c02,0xe0887c27,0xe08cb42a,0xe8970780, +0xe88b0780,0xeafff6b6,0xe24f8f85,0xe0887c27, +0xe08cb42a,0xe8970700,0xe3a07102,0xe88b0780, +0xeafff6af,0xe24f7e23,0xe0878c28,0xe8980d00, +0xe3a04000,0xea0001f3,0xe24f7f91,0xe0878c28, +0xe8980d00,0xe3a04000,0xea0002a5,0xe3580102, +0x0a00040f,0xe24f7e26,0xe0878c28,0xe8980d00, +0xea00035f,0xe3580102,0x0a00050f,0xe24f7f9e, +0xe0878c28,0xe8980d00,0xea000456,0xe24f7fa3, +0xe0876c26,0xe896000f,0xea000463,0xe3580102, +0x0a0005b3,0xe24f7e2a,0xe0878c28,0xe8980d00, +0xea000546,0xe24f7fad,0xe0876c26,0xe896000f, +0xea000549,0xe24f8fb1,0xe0888c27,0xe08cb42a, +0xe898000f,0xe3570209,0x9a00018e,0xea000143, +0xe24f8e2e,0xe0888c27,0xe898000f,0xea00063a, +0xe24f8e2f,0xe0888c27,0xe898000f,0xea0006dd, +0xe24f8c03,0xe0888c27,0xe898000f,0xea000790, +0xe24f8e31,0xe0888c27,0xe898000f,0xea000858, +0xe3570102,0x13570209,0x1357020e,0x1a0008fe, +0xe24f8e33,0xe0888c27,0xe898000f,0xea000880, +0xe24f8d0d,0xe0888c27,0xe898000f,0xea000992, +0xe24f7e35,0xe0876c26,0xe896000f,0xea000937, +0xe24f7fd7,0xe0878c28,0xe8980d00,0xea0005b6, +0xe3190080,0x1afff638,0xe1b07e09,0xe209aa07, +0x4affff9e,0xe08c7c27,0xe08cb42a,0xe8970780, +0xe88b0780,0xeafff656,0xe3190080,0x1afff62e, +0xe1b07e09,0xe209aa07,0x4affff9a,0xe08c7c27, +0xe08cb42a,0xe8970780,0xe2277102,0xe88b0780, +0xeafff64b,0xe3190080,0x1afff623,0xe1b07e09, +0xe209aa07,0x4affff89,0xe08c7c27,0xe08cb42a, +0xe8970780,0xe3c77102,0xe88b0780,0xeafff640, +0xe1b07e09,0xe209aa07,0x4affff80,0xe08c7c27, +0xe08ca42a,0xe897000f,0xe2098080,0xe3888040, +0xe1580ba3,0x21b04183,0x3a00001d,0xe88a000f, +0xeafff62c,0xe1b07e09,0xe209aa07,0x4affff79, +0xe08c7c27,0xe08ca42a,0xe897000f,0xe2200102, +0xe2098080,0xe3888040,0xe1580ba3,0x21b04183, +0x3a00000f,0xe88a000f,0xeafff61e,0xe1b07e09, +0xe209aa07,0x4affff65,0xe08c7c27,0xe08ca42a, +0xe897000f,0xe3c00102,0xe2098080,0xe3888040, +0xe1580ba3,0x21b04183,0x3a000001,0xe88a000f, +0xeafff610,0xe1a04328,0xe1844d23,0xe24f7018, +0xe3540019,0x0a00006b,0xc3c03102,0xe3140002, +0x1a000034,0xe1b05883,0x12955802,0x0a00001c, +0xe2195060,0x1a00000c,0xe1925c81,0xe2012080, +0x000220a1,0xe0911002,0x23a01102,0xe2a33000, +0xe3a02000,0xe3c110ff,0xe2535dfe,0x9a00001a, +0xe35500ff,0x31a0f007,0xea000012,0xe3550060, +0x11922c01,0x10305d05,0x5afffff4,0xe2911c01, +0x23a01102,0xe2a33000,0xe3a02000,0xe3c110ff, +0xe2535dfe,0x9a00000c,0xe35500ff,0x31a0f007, +0xea000004,0xe31300ff,0x11a0f007,0xe1922001, +0x01a0f007,0xea00000a,0xe3a030ff,0xe3833c7f, +0xe3a01000,0xe3a04004,0xeafffb1a,0xe3750017, +0xda000003,0xe2655009,0xe1a01531,0xe1a01511, +0xe1a0f007,0xe3a03000,0xe3a02000,0xe3a01000, +0xe3a04008,0xeafffb0f,0xe1b05883,0x12955802, +0x0a000022,0xe2195060,0x1a00000f,0xe1b04b02, +0xe2024b01,0x000440a2,0xe0922004,0xe2b11000, +0xe2a33000,0x23a01102,0xe1a025a2,0xe1a02582, +0xe2535b0f,0x9a00001a,0xe2854001,0xe3540b02, +0x31a0f007,0xe3a02000,0xeaffffda,0xe3550060, +0x11b04a82,0x10305d05,0x5afffff2,0xe2922b02, +0xe2b11000,0x23a01102,0xe2a33000,0xe1a025a2, +0xe1a02582,0xe2535b0f,0x9a000009,0xe2854001, +0xe3540b02,0x31a0f007,0xe3a02000,0xeaffffc9, +0xe31300ff,0x11a0f007,0xe1922001,0x01a0f007, +0xeaffffcf,0xe3750034,0xdaffffcd,0xe265500c, +0xe2554020,0x21a02431,0x31a02532,0x21a01412, +0xe1a02512,0xe1a0f007,0xe1a03080,0xe1b03aa3, +0x12834001,0x13340b02,0x0a000023,0xe2833b0f, +0xe2195060,0x1a00000f,0xe1b04201,0xe1a01aa1, +0xe1811580,0xe3811102,0xe2014080,0x000440a1, +0xe0911004,0x23a01102,0xe2a33000,0xe3c110ff, +0xe3a02000,0xe2535dfe,0x9affffab,0xe35500ff, +0x31a0f007,0xeaffffa3,0xe1b04181,0xe1a01aa1, +0xe1811580,0xe3811102,0x13550060,0x10305d05, +0x5afffff1,0xe2911c01,0x23a01102,0xe2a33000, +0xe3a02000,0xe3c110ff,0xe2535dfe,0x9affff9a, +0xe35500ff,0x31a0f007,0xeaffff92,0xe1833203, +0xe1912600,0x01a0f007,0xe1a02581,0xe1a01aa1, +0xe1811580,0xe31300ff,0x11a0f007,0xeaffff94, +0xe3190080,0x1afff54c,0xe1b07e09,0xe209aa07, +0x4afffeb0,0xe08c7c27,0xe08cb42a,0xe897000f, +0xe1b04d23,0xe28f7000,0x1afff9c3,0xe1a04883, +0xe2944802,0x0a00000b,0xe92c4000,0xebfff83c, +0xe8bc4000,0xe28f7014,0x1afffa96,0xe1898629, +0xe3180080,0x0affff4e,0xe3190080,0x1affff81, +0xe88b000f,0xeafff553,0xe1928001,0x0a000003, +0xe3811101,0xe24f701c,0xe3a04001,0xeafffa89, +0xe3a02000,0xe24f702c,0xeaffff66,0xe3190080, +0x1afff529,0xe1b07e09,0xe209aa07,0x4afffec0, +0xe08c8c27,0xe08cb42a,0xe898000f,0xe1b04d23, +0xe28f7000,0x1afff9a0,0x1888000f,0xe1b04883, +0x12944802,0x0a000063,0xe3100102,0x1a000059, +0xe2833901,0xe2433001,0xe1b030a3,0xe1a05002, +0x32414102,0x22414101,0x33a07201,0x23a07202, +0xe3a01102,0xe0955005,0xe0b44004,0xe0216007, +0x31540006,0x20444006,0x20211087,0xe1b070e7, +0x5afffff7,0xe1942005,0x11892629,0x12122080, +0x03a07000,0x0a000018,0xe3a02000,0xe0955005, +0xe0b44004,0xe0a00000,0xe0226007,0xe055a006, +0xe0d48001,0x31b000a0,0x21a0500a,0x21a04008, +0x20222087,0x20211fa7,0xe1b070a7,0x1afffff2, +0xe0955005,0xe0b44004,0xe0b70007,0xe0d5a002, +0xe0d48001,0x31b000a0,0x21a0500a,0x21a04008, +0x22222001,0x23a07102,0xe3a00000,0xe3190702, +0x1a000008,0xe1954004,0x01944007,0x13822001, +0xe28f7044,0xe3530000,0xdaffff29,0xe3190080, +0x0afffef7,0xeaffff2b,0xe2196060,0x1a000015, +0xe0977007,0xe0b55005,0xe0b44004,0x2a000002, +0xe1540001,0x01550002,0x03570101,0xe2b22000, +0xe2b11000,0xe2a33000,0x23a01102,0xe59c5080, +0xe3150010,0x0a000001,0xe88b000f,0xeafff4ed, +0xe3855010,0xe58c5080,0xe3150601,0x0afffff9, +0xe3a00010,0xea0008b4,0xe1945005,0x01955007, +0x13560060,0x0afffff0,0xe1300c86,0x4affffee, +0xe2922001,0xeaffffe9,0xe3a014c5,0xe3a02000, +0xe3a030ff,0xe1833383,0xe3811101,0xe24f705c, +0xe3a04001,0xeafffa13,0xe3530000,0x1a000008, +0xe1914002,0x0affffe3,0xe1b01001,0x4affff95, +0xe0922002,0xe0b11001,0xe2433001,0x5afffffb, +0xeaffff90,0xe1914002,0x1affffee,0xe3100102, +0x0affffd5,0xeaffffe7,0xe3190080,0x1afff4a6, +0xe1b08e09,0x4afffe1a,0xe08c8c28,0xe898000f, +0xe1b04d23,0x0a00000b,0xe28f7024,0xe3540008, +0x1afff91d,0xe3a02000,0xe1a03080,0xe1b03c23, +0x133300ff,0x11a01400,0x13811102,0x12833dfe, +0x0afffa4d,0xe888000f,0xe1a0b003,0xe1a0a002, +0xe1a08001,0xe2004102,0xe2096807,0xe08c6626, +0xe896000f,0xe1340000,0x4a0000b6,0xe1b04d23, +0x0a00000b,0xe28f7024,0xe3540008,0x1afff906, +0xe3a02000,0xe1a03080,0xe1b03c23,0x133300ff, +0x11a01400,0x13811102,0x12833dfe,0x0afffa36, +0xe886000f,0xe3a06802,0xe0965883,0x3096588b, +0x2a000061,0xe053400b,0x4a000046,0xe2745020, +0xda00000e,0xe092243a,0x20822518,0x30922518, +0xe0b11438,0xe1a0851a,0xe1a0a088,0x2a000011, +0xe3190702,0x1a00001d,0xe19aa008,0x13822001, +0xe28f7090,0xe3190080,0x0afffe7d,0xeafffeb1, +0xe3540040,0xc18aa008,0xc3a08000,0xaa00000b, +0xe2444020,0xe2645020,0xe0922438,0xe2b11000, +0xe1a08518,0xe18aa088,0xe2a33000,0x218aa008, +0x21a08f82,0x21a020a2,0x21822f81,0x21a01061, +0xe3190702,0x1a000005,0xe19aa008,0x13822001, +0xe28f7030,0xe3190080,0x0afffe65,0xeafffe99, +0xe2197060,0x1a000014,0xe19aa088,0x00088f82, +0xe0922fa8,0xe2b11000,0xe2a33000,0x23a01102, +0xe0965883,0x0a00003b,0xe59c5080,0xe3150010, +0x0a000003,0xe2099a07,0xe08c9429,0xe889000f, +0xeafff45c,0xe3855010,0xe58c5080,0xe3150601, +0x0afffff7,0xe3a00010,0xea000823,0xe19aa008, +0x13570060,0x0affffef,0xe1300c87,0x4affffed, +0xe2922001,0xeaffffe6,0xe2644000,0xe1a0300b, +0xe1a05001,0xe1a01008,0xe1a08005,0xe1a05002, +0xe1a0200a,0xe1a0a005,0xe2745020,0xdaffffbf, +0xe092243a,0x20822518,0x30922518,0xe0b11438, +0xe1a0851a,0xe1a0a088,0x2affffc2,0xe3190702, +0x1affffce,0xe19aa008,0x13822001,0xe24f70ac, +0xe3190080,0x0afffe2e,0xeafffe62,0xe0965883, +0x1a000001,0xe1925001,0x1a000006,0xe096588b, +0x1affffcc,0xe1a0300b,0xe1a01008,0xe1a0200a, +0xe1915002,0x0affffc7,0xe3811101,0xe24f70ec, +0xe3a04001,0xeafff963,0xe3a030ff,0xe1833383, +0xe3a02000,0xe3a01000,0xe24f7f42,0xe3a04004, +0xeafff95c,0xe1b04d23,0x0a00000b,0xe28f7024, +0xe3540008,0x1afff87c,0xe3a02000,0xe1a03080, +0xe1b03c23,0x133300ff,0x11a01400,0x13811102, +0x12833dfe,0x0afff9ac,0xe886000f,0xe0200589, +0xeaffff73,0xe3190080,0x1afff3ef,0xe1b08e09, +0x4afffd68,0xe08c8c28,0xe898000f,0xe1b04d23, +0x0a00000b,0xe28f7024,0xe3540008,0x1afff866, +0xe3a02000,0xe1a03080,0xe1b03c23,0x133300ff, +0x11a01400,0x13811102,0x12833dfe,0x0afff996, +0xe888000f,0xe1a0b003,0xe1a0a002,0xe1a08001, +0xe2004102,0xe2096807,0xe08c6626,0xe896000f, +0xe1340000,0x4affffd2,0xe1b04d23,0x0a00000b, +0xe28f7024,0xe3540008,0x1afff84f,0xe3a02000, +0xe1a03080,0xe1b03c23,0x133300ff,0x11a01400, +0x13811102,0x12833dfe,0x0afff97f,0xe886000f, +0xe0200589,0xe3a06802,0xe0965883,0x3096588b, +0x2a00006b,0xe053400b,0x01510008,0x0152000a, +0x0a000078,0x3a00004c,0xe3a07000,0xe2745020, +0xda000015,0xe057651a,0xe0d2243a,0x30422518, +0x20522518,0xe0d11438,0x5a00001b,0xe3190702, +0x1a000029,0xe1977006,0x13822001,0xe28f70c0, +0xe3190080,0x0afffdc2,0xeafffdf6,0x13a06102, +0xe3a07001,0xe198500a,0x0a000029,0xe2522001, +0xe2d11000,0x5a00000c,0xea000011,0xe3a06000, +0xe3540040,0xaafffff4,0xe2444020,0xe2645020, +0xe057751a,0xe0d6643a,0x30466518,0x20566518, +0xe0d22438,0xe2d11000,0x4a000005,0xe0977007, +0xe0b66006,0xe0b22002,0xe0b11001,0xe2433001, +0x5afffff9,0xe3190702,0x1a000007,0xe3530000, +0xda00004c,0xe1977006,0x13822001,0xe28f7030, +0xe3190080,0x0afffd9e,0xeafffdd2,0xe2195060, +0x1a00000e,0xe1977086,0x00066f82,0xe0922fa6, +0xe2b11000,0xe2a33000,0x23a01102,0xe1b03003, +0x4a000042,0xe59c5080,0xe3150010,0x0affff3c, +0xe2099a07,0xe08c9429,0xe889000f,0xeafff395, +0xe1977006,0x13550060,0x0afffff3,0xe1300c85, +0x4afffff1,0xe2922001,0xeaffffec,0xe2644000, +0xe2200102,0xe1a0300b,0xe1a05001,0xe1a01008, +0xe1a08005,0xe1a05002,0xe1a0200a,0xe1a0a005, +0xe3a07000,0xe2745020,0xdaffffbf,0xe057651a, +0xe0d2243a,0x30422518,0x20522518,0xe0d11438, +0x5affffc5,0xe3190702,0x1affffd3,0xe1977006, +0x13822001,0xe24f7098,0xe3190080,0x0afffd6c, +0xeafffda0,0xe0965883,0x1a000005,0xe1925001, +0x1affff44,0xe153000b,0x0198500a,0x03a014c1, +0x0affff40,0xe096588b,0x1affffcd,0xe2200102, +0xe1a0300b,0xe1a01008,0xe1a0200a,0xe1915002, +0x0affffc7,0xeaffff37,0xe3a03000,0xe3a02000, +0xe3a01000,0xeaffffc2,0xe3a03000,0xe3a02000, +0xe3a01000,0xe24f7f42,0xe3a04008,0xeafff895, +0xe2633000,0xe2734020,0x42435020,0x41a02531, +0x51a02332,0x51822411,0xe1a01331,0xe3a03000, +0xeaffffb3,0xe3190080,0x1afff32f,0xe1b08e09, +0x4afffcad,0xe08c8c28,0xe898000f,0xe1b04d23, +0x0a00000b,0xe28f7024,0xe3540008,0x1afff7a6, +0xe3a02000,0xe1a03080,0xe1b03c23,0x133300ff, +0x11a01400,0x13811102,0x12833dfe,0x0afff8d6, +0xe888000f,0xe2000102,0xe183b000,0xe1a0a002, +0xe1a08001,0xe2096807,0xe08c6626,0xe896000f, +0xe1b04d23,0x0a00000b,0xe28f7024,0xe3540008, +0x1afff791,0xe3a02000,0xe1a03080,0xe1b03c23, +0x133300ff,0x11a01400,0x13811102,0x12833dfe, +0x0afff8c1,0xe886000f,0xe020000b,0xe3cbb102, +0xe3a06802,0xe3530000,0x135b0000,0x0a00008c, +0xe0965883,0x3096588b,0x2afffee7,0xe3b054ff, +0xe0a3300b,0xe185b425,0xe043392b,0xe19a4088, +0x11924081,0x0a000064,0xe92c4209,0xe1a04821, +0xe1c1500b,0xe1a06822,0xe1c2700b,0xe1c8900b, +0xe1a08828,0xe1cab00b,0xe1a0a82a,0xe0030b96, +0xe0020b94,0xe0010994,0xe0000a97,0xe0933000, +0xe0000a95,0xe0b22000,0xe0000895,0xe0b11000, +0x33a0e000,0x23a0e001,0xe0000996,0xe0922000, +0xe2b11000,0xe2aee000,0xe0000897,0xe0922000, +0xe2b11000,0xe2aee000,0xe18ee803,0xe1a03823, +0xe1833802,0xe1a02822,0xe1822801,0xe1a01821, +0xe181180e,0xe3cee0ff,0xe0000b95,0xe00b0b97, +0xe09eb00b,0xe0b33000,0xe0000896,0xe0b22000, +0xe0000894,0xe0a11000,0xe0000a94,0xe00a0a96, +0xe09aa003,0xe0b22000,0xe2a11000,0xe0000997, +0xe09aa000,0xe0000995,0xe0b22000,0xe2b11000, +0xe8bc4209,0x5a000009,0xe3190702,0x1a000017, +0xe19bb00a,0x13822001,0xe3530000,0xdaffff79, +0xe28f7078,0xe3190080,0x0afffccd,0xeafffd01, +0xe09bb00b,0xe0baa00a,0xe0b22002,0xe0b11001, +0xe2433001,0x5afffff9,0xe3190702,0x1a000007, +0xe3530000,0xdaffff6b,0xe19bb00a,0x13822001, +0xe28f7038,0xe3190080,0x0afffcbd,0xeafffcf1, +0xe2195060,0x1a00001c,0xe19bb08a,0x000aaf82, +0xe0922faa,0xe2b11000,0xe2a33000,0x23a01102, +0xe2934001,0xda00001b,0xe1b047a4,0x1afffe91, +0xe59c5080,0xe3150010,0x0afffe59,0xe2099a07, +0xe08c9429,0xe889000f,0xeafff2b2,0xe19a4088, +0x11a0200a,0x11a01008,0xe2433001,0xe3190702, +0x1affffee,0xe3530000,0xdaffff4a,0xe24f7044, +0xe3190080,0x0afffc9e,0xeafffcd2,0xe19bb00a, +0x13550060,0x0affffe5,0xe1300c85,0x4affffe3, +0xe2922001,0xeaffffde,0xe2633000,0xe3530040, +0xaaffff3c,0xe2734020,0x42435020,0x41a02531, +0x51a02332,0x51822411,0xe1a01331,0xe3a03000, +0xeaffffda,0xe3530000,0x1a000003,0xe1915002, +0x0a00000c,0xe35b0000,0x1affff6c,0xe198500a, +0x1affff6a,0xe0965883,0x33a03000,0x33a02000, +0x33a01000,0x3affffcd,0xe1915002,0x1afffe59, +0xe3a014c2,0xeafffe57,0xe096588b,0x3affffc7, +0xe198500a,0x1afffe48,0xe1a0300b,0xeafffff7, +0xe3190080,0x1afff25c,0xe2096807,0xe08c6626, +0xe896000f,0xe1b04d23,0x0a00000b,0xe28f7024, +0xe3540008,0x1afff6d4,0xe3a02000,0xe1a03080, +0xe1b03c23,0x133300ff,0x11a01400,0x13811102, +0x12833dfe,0x0afff804,0xe886000f,0xe2000102, +0xe183b000,0xe1a0a002,0xe1a08001,0xe1b06e09, +0x4afffbd1,0xe08c6c26,0xe896000f,0xe1b04d23, +0x0a000035,0xe28f7024,0xe3540008,0x1afff6be, +0xe3a02000,0xe1a03080,0xe1b03c23,0x133300ff, +0x11a01400,0x13811102,0x12833dfe,0x0afff7ee, +0xe886000f,0xea000028,0xe3190080,0x1afff232, +0xe1b08e09,0x4afffbb6,0xe08c8c28,0xe898000f, +0xe1b04d23,0x0a00000b,0xe28f7024,0xe3540008, +0x1afff6a9,0xe3a02000,0xe1a03080,0xe1b03c23, +0x133300ff,0x11a01400,0x13811102,0x12833dfe, +0x0afff7d9,0xe888000f,0xe2000102,0xe183b000, +0xe1a0a002,0xe1a08001,0xe2096807,0xe08c6626, +0xe896000f,0xe1b04d23,0x0a00000b,0xe28f7024, +0xe3540008,0x1afff694,0xe3a02000,0xe1a03080, +0xe1b03c23,0x133300ff,0x11a01400,0x13811102, +0x12833dfe,0x0afff7c4,0xe886000f,0xe020000b, +0xe3cbb102,0xe1b04883,0x11b0588b,0x12944802, +0x12955802,0x0a000082,0xe043300b,0xe2833901, +0xe2433001,0xe3a0b000,0xe052500a,0xe0d14008, +0x23a01003,0x2a00000c,0xe1a05002,0xe1a04001, +0xe3a01001,0xe2433001,0xe0955005,0xe0b44004, +0xe2abb000,0xe055700a,0xe0d46008,0x31b0b0ab, +0x21a05007,0x21a04006,0xe0a11001,0xe0955005, +0xe0b44004,0xe2abb000,0xe055700a,0xe0d46008, +0x31b0b0ab,0x21a05007,0x21a04006,0xe0a11001, +0xe0955005,0xe0b44004,0xe2abb000,0xe055700a, +0xe0d46008,0x31b0b0ab,0x21a05007,0x21a04006, +0xe0a11001,0xe0955005,0xe0b44004,0xe2abb000, +0xe055700a,0xe0d46008,0x31b0b0ab,0x21a05007, +0x21a04006,0xe0b11001,0x3affffda,0xe1942005, +0x11892629,0x12122080,0x0a000025,0xe3a02001, +0xe0955005,0xe0b44004,0xe2abb000,0xe055700a, +0xe0d46008,0x31b0b0ab,0x21a05007,0x21a04006, +0xe0a22002,0xe0955005,0xe0b44004,0xe2abb000, +0xe055700a,0xe0d46008,0x31b0b0ab,0x21a05007, +0x21a04006,0xe0a22002,0xe0955005,0xe0b44004, +0xe2abb000,0xe055700a,0xe0d46008,0x31b0b0ab, +0x21a05007,0x21a04006,0xe0a22002,0xe0955005, +0xe0b44004,0xe2abb000,0xe055700a,0xe0d46008, +0x31b0b0ab,0x21a05007,0x21a04006,0xe0b22002, +0x3affffda,0xe3190702,0x1a000007,0xe1954004, +0x13822001,0xe3530000,0xdafffe62,0xe28f7048, +0xe3190080,0x0afffbb6,0xeafffbea,0xe2197060, +0x1a000014,0xe0955005,0xe0b44004,0x2a000002, +0xe1540008,0x0155000a,0x011500a2,0xe2b22000, +0xe2b11000,0xe2a33000,0x23a01102,0xe2934001, +0xdaffff10,0xe1b047a4,0x1afffd86,0xe59c5080, +0xe3150010,0x0afffd4e,0xe2099a07,0xe08c9429, +0xe889000f,0xeafff1a7,0xe1945005,0x13570060, +0x0afffff1,0xe1300c87,0x4affffef,0xe2922001, +0xeaffffea,0xe1b04883,0x1a000013,0xe1915002, +0x1a00000d,0xe1b0588b,0x0198600a,0x03a014c3, +0x03a030ff,0x01833383,0x0afffd6a,0xe2955802, +0x1affffe8,0xe198600a,0x0affffe6,0xe1a01008, +0xe1a0200a,0xe1a0300b,0xeafffd62,0xe0922002, +0xe0b11001,0xe2433001,0x5afffffb,0xe1b0588b, +0x1a000010,0xe198600a,0x1a00000a,0xe2944802, +0x1a000001,0xe1916002,0x1afffd56,0xe3a01000, +0xe3a02000,0xe3a030ff,0xe1833383,0xe24f70bc, +0xe3a04002,0xeafff6b7,0xe09aa00a,0xe0b88008, +0xe24bb001,0x5afffffb,0xe2956802,0x12946802, +0x1affff50,0xe2946802,0x1a000006,0xe1916002, +0x1afffd44,0xe2956802,0x1affffbf,0xe198600a, +0x03a01331,0x0afffd3f,0xe198600a,0x0afffe09, +0xe1a01008,0xe1a0200a,0xe1a0300b,0xeafffd39, +0xe3190080,0x1afff144,0xe2096807,0xe08c6626, +0xe896000f,0xe1b04d23,0xe28f7000,0x1afff5be, +0x1886000f,0xe2000102,0xe183b000,0xe1a0a002, +0xe1a08001,0xe1b06e09,0x4afffacd,0xe08c6c26, +0xe896000f,0xe1b04d23,0xe28f7000,0x1afff5b2, +0x1886000f,0xea000014,0xe3190080,0x1afff12e, +0xe1b08e09,0x4afffabc,0xe08c8c28,0xe898000f, +0xe1b04d23,0xe28f7000,0x1afff5a7,0x1888000f, +0xe2000102,0xe183b000,0xe1a0a002,0xe1a08001, +0xe2096807,0xe08c6626,0xe896000f,0xe1b04d23, +0xe28f7000,0x1afff59c,0x1886000f,0xe1a0700b, +0xe3cbb102,0xe1b04883,0x12944802,0x11b0588b, +0x12955802,0x0a00004e,0xe92c4200,0x5a000035, +0xe24b4c3f,0xe24440fe,0xe3540010,0xca00002a, +0xe19a5418,0x1a00002f,0xe2649020,0xe1a09938, +0xe0000f89,0xe92c0080,0xe3a08102,0xe3a0a000, +0xe3a07901,0xe257b001,0xe92c0d80,0x3bfff2b6, +0xe1b090a9,0x3afffffc,0xe8bc0d80,0x192c000f, +0xebfff2b5,0xe2834001,0x0a000009,0xe3540902, +0xaa000010,0xe8bc0d80,0xe92c000f,0xe1a00007, +0xe1a01008,0xe1a0200a,0xe1a0300b,0xebfff2aa, +0xeaffffee,0xe8bc0080,0xe3170102,0x1bfff2f3, +0xe8bc4200,0xe2934001,0xdafffe6a,0xe1b047a4, +0x1afffce0,0xea0000cb,0xe28cc010,0xe8bc4280, +0xe3170102,0x1afffda3,0xeafffcda,0xe3540040, +0x2a000012,0xe2545020,0x21b0651a,0x0a000010, +0xe19a6418,0x0a00000e,0xe3100102,0x1a00000e, +0xe92c0001,0xe3a00000,0xe92c0d80,0xe3c99601, +0xeb0000e1,0xe8bc0d80,0xebfff28b,0xeb000166, +0xe8bc4201,0x0a0000b3,0xe28f7e2f,0xeafff629, +0x13b05100,0x33a00000,0xeafffff0,0xe8bc4200, +0xe3a014c7,0xe3a02000,0xe3a030ff,0xe1833383, +0xeafffcb8,0xe3540000,0x1a00001e,0xe3530000, +0x0a000002,0xe1916002,0x1afffcb2,0xea000001, +0xe1916002,0x1a000010,0xe1b0588b,0x1a000006, +0xe198600a,0x03a01102,0x03a02000,0x03a00000, +0x03a03901,0x02433001,0xea000096,0xe2955802, +0x1a000094,0xe198600a,0x0a000092,0xe1a01008, +0xe1a0200a,0xe1a0300b,0xeafffc9e,0xe0922002, +0xe0b11001,0xe2433001,0x5afffffb,0xe1b0588b, +0x12955802,0x1affff8f,0xe35b0000,0x0a000008, +0xe1a01008,0xe1a0200a,0xe1a00007,0xe1a0300b, +0xe198600a,0x1afffc8f,0xe3100102,0x13a03000, +0xea00007c,0xe198600a,0x0affffdd,0xe09aa00a, +0xe0b88008,0xe24bb001,0x5afffffb,0xe92c4200, +0xeaffffb4,0xe3190080,0x1afff08f,0xe1b08e09, +0x4afffa4e,0xe08c8c28,0xe898000f,0xe1b04d23, +0xe28f7000,0x1afff508,0x1888000f,0xe2000102, +0xe183b000,0xe1a0a002,0xe1a08001,0xe2096807, +0xe08c6626,0xe896000f,0xe1b04d23,0xe28f7000, +0x1afff4fd,0x1886000f,0xe1a0700b,0xe3cbb102, +0xe1b04883,0x12944802,0x11b0588b,0x12955802, +0x0a00000a,0xe92c400f,0xe92c0d80,0xebfff27f, +0xebfff36f,0xe8bc0d80,0xebfff227,0xe2200102, +0xe8bc0d80,0xebfff178,0xe8bc4000,0xea00004d, +0xe1b04883,0x1a000010,0xe1915002,0x1a00000a, +0xe1b0588b,0x0198600a,0x0a000013,0xe2955802, +0x1a000015,0xe198600a,0x0a000013,0xe1a01008, +0xe1a0200a,0xe1a0300b,0xeafffc4e,0xe0922002, +0xe0b11001,0xe2433001,0x5afffffb,0xe1b0588b, +0x1a000012,0xe198600a,0x1a00000c,0xe2944802, +0x1a000001,0xe1916002,0x1afffc42,0xe3a01333, +0xe3b02100,0xe2e23902,0xeafffc3e,0xe3a00000, +0xe3a01000,0xe3a02000,0xe3a03000,0xea000029, +0xe09aa00a,0xe0b88008,0xe24bb001,0x5afffffb, +0xe2956802,0x12946802,0x1affffc9,0xe2946802, +0x1a000008,0xe1916002,0x1afffc2e,0x03a01333, +0xe2956802,0x1afffc2b,0xe198600a,0x11a01008, +0x11a0200a,0xeafffc27,0xe198600a,0x0a000015, +0xe1a01008,0xe1a0200a,0xe1a0300b,0xeafffc21, +0xe3190080,0x1afff02c,0xe1b07e09,0x4afff9cb, +0xe08c8c27,0xe898000f,0xe1b04d23,0xe28f7000, +0x1afff4a5,0x1888000f,0xe1b04883,0x12944802, +0x0a00001d,0xe3100102,0x1a000016,0xe92c4000, +0xeb000029,0xe8bc4000,0xe3190702,0x1a000005, +0xe28f7018,0xe3530000,0xdafffa5d,0xe3190080, +0x0afffa2b,0xeafffa5f,0xe3530000,0xba000006, +0xe59c5080,0xe3150010,0x0afffbd1,0xe2099a07, +0xe08c9429,0xe889000f,0xeafff02a,0xe3730040, +0xcafffcce,0xeafffa4e,0xe3a014c6,0xe3a02000, +0xe3a030ff,0xe1833383,0xeafffbf6,0xe3530000, +0x1a000008,0xe1914002,0x0afffff6,0xe1b01001, +0x4affffdb,0xe0922002,0xe0b11001,0xe2433001, +0x5afffffb,0xeaffffd6,0xe1914002,0x1afffbe9, +0xe3100102,0x0affffe1,0xeaffffea,0xe28f4f52, +0xe8940500,0xe1510008,0x0152000a,0xe1a0a0a2, +0xe18aaf81,0xe1a080a1,0xe3888102,0xe3a0b0fe, +0xe18bb30b,0xe043400b,0x92444001,0xe92c4210, +0xe1a0300b,0x8a000005,0xe3c88101,0xe0922002, +0xe0b11001,0xe2433001,0x5a000003,0xea000008, +0xe3a00102,0xe2722000,0xe2f11000,0x03520000, +0x0a000035,0xe0922002,0xe0b11001,0xe2433001, +0x5afffff9,0xe3a07000,0xebfff1e0,0xe92c000f, +0xebfff185,0xe92c000f,0xe28f90c4,0xe8b90d00, +0xebfff125,0xe89c0d80,0xebfff183,0xe8b90d00, +0xebfff0d8,0xe89c0d80,0xebfff17f,0xe8b90d00, +0xebfff11d,0xe89c0d80,0xe92c000f,0xe3a00102, +0xe8b9000e,0xebfff178,0xe8b90d00,0xebfff0cd, +0xe28c4010,0xe8940d80,0xebfff173,0xe8b90d00, +0xebfff111,0xe8bc0d80,0xebfff1c4,0xe8bc0d80, +0xebfff16d,0xe89c0d80,0xebfff16b,0xe8bc0d80, +0xebfff0bd,0xe8bc0010,0xebfff25e,0xe92c000f, +0xe3a00000,0xe8b9000e,0xebfff163,0xe8bc0d80, +0xebfff0b5,0xe8bc0200,0xe3190601,0xe28f7074, +0x18970d00,0x1bfff15c,0xe8bc8000,0xe3a00000, +0xe3a03000,0xe28f9050,0xeaffffed,0xb504f333, +0xf9de6484,0x8eac025b,0x3e7076bb,0x00004004, +0x9c041fd0,0xa933ef60,0x00004007,0xc05ff4e0, +0x6c83bb96,0x00004008,0xca20ad9a,0xb5e946e9, +0x00003ffe,0x83125100,0xb57f6509,0x00004003, +0x803ff895,0x9dacd228,0x00004005,0xb17217f7, +0xd1cf79ac,0x00003ffe,0xde5bd8a9,0x37287195, +0x00003ffd,0xe3190080,0x1affef83,0xe1b07e09, +0x4afff926,0xe08c8c27,0xe898000f,0xe1b04d23, +0xe28f7000,0x1afff3fc,0x1888000f,0xe1a04883, +0xe2944802,0x0a000005,0xe92c4000,0xeb00000a, +0xe8bc4000,0x0affff57,0xe24f7d0a,0xeafff4cd, +0xe1914002,0x1afffb63,0xe3100102,0x0affff5b, +0xe3a00000,0xe3a03000,0xeaffff58,0xe28f4f6e, +0xe3100102,0x128f4f72,0xe8b40d00,0xe153000b, +0x01510008,0x0152000a,0x8a00005d,0xe8940d00, +0xe153000b,0x01510008,0x0152000a,0x3a000052, +0xe92c421f,0xe28f9e1b,0xe3a07000,0xe8b90d00, +0xebfff111,0xebfff238,0xe3170102,0x12644000, +0xe58c4010,0xe92c0d80,0xe3a00000,0xe8b9000e, +0xebfff109,0xe8bc0d80,0xe92c000f,0xe8b9000e, +0xe3a00102,0xebfff104,0xe92c000f,0xe28c4020, +0xe894000f,0xebfff20c,0xe3170102,0x0bfff09e, +0x1bfff054,0xe1a0400c,0xe92c000f,0xe894000f, +0xebfff04d,0xe8bc0d80,0xebfff04b,0xe28cc010, +0xe8bc0d80,0xebfff048,0xe88c000f,0xebfff0ee, +0xe92c000f,0xe3a07000,0xe8b90d00,0xebfff0ee, +0xe8b90d00,0xebfff043,0xe89c0d80,0xebfff0ea, +0xe8b90d00,0xebfff03f,0xe89c0d80,0xebfff0e6, +0xe8b90d00,0xebfff03b,0xe89c0d80,0xe92c000f, +0xe3a00000,0xe8b9000e,0xebfff0df,0xe8b90d00, +0xebfff034,0xe28c7010,0xe8970d80,0xebfff0da, +0xe8b90d00,0xebfff02f,0xe28c7020,0xe8970d80, +0xebfff0d5,0xe8bc0d80,0xe92c000f,0xe2200102, +0xebfff025,0xe1a07000,0xe1a08001,0xe1a0a002, +0xe1a0b003,0xe8bc000f,0xebfff120,0xe8b90d00, +0xebfff020,0xe28cc020,0xe8bc4210,0xe2844001, +0xe0833004,0xe3b04000,0xe1a0f00e,0xe3b00000, +0xe3a01102,0xe3a02000,0xe3a03901,0xe2433001, +0xe1a0f00e,0xe3100102,0xe3a00000,0xe3a01000, +0xe3a02000,0x13a03000,0x13a04008,0x03a030ff, +0x01833383,0x03b04004,0xe1a0f00e,0xb17217f7, +0xd1cf79ab,0x0000400c,0x80000000,0x00000000, +0x00003fbe,0xb21dfe7f,0x09e2baa9,0x0000400c, +0x80000000,0x00000000,0x00003fbe,0xb8aa3b29, +0x5c17f0bc,0x00003fff,0xde8082e3,0x08654362, +0x00003ff2,0xb1800000,0x00000000,0x00003ffe, +0xc99b1867,0x2822a93e,0x00003fea,0xa57862e1, +0x46a6fb39,0x00003ff4,0xe8b9428e,0xfecff592, +0x00003ffa,0x80000000,0x00000000,0x00003ffe, +0x845a2157,0x3490f106,0x00003ff0,0xf83a5f91, +0x50952c99,0x00003ff7,0x80000000,0x00000000, +0x00003ffd,0x80000000,0x00000000,0x00003ffe, +0xe3190080,0x1affeecc,0xe1b07e09,0x4afff873, +0xe08c8c27,0xe898000f,0xe1b04d23,0xe28f7000, +0x1afff345,0x1888000f,0xe1a04883,0xe2944802, +0x0a000006,0xe92c4000,0xeb000007,0xe8bc4000, +0x0afffea0,0xe24f705c,0xe2477c05,0xeafff415, +0xe1914002,0x03a01332,0xeafffaaa,0xe28f4f8f, +0xe8b40d00,0xe153000b,0x01510008,0x0152000a, +0x8a00006c,0xe1b01001,0x5a000063,0xe92c421f, +0xe3190601,0xe28f9e22,0xe3a07000,0xe8b90d00, +0xebfff061,0xebfff188,0x1b00006d,0xe58c4010, +0xe92c0d80,0xe3a00000,0xe8b9000e,0xebfff05a, +0xe8bc0d80,0xe92c000f,0xe8b9000e,0xe3a00102, +0xebfff055,0xe92c000f,0xe28c4020,0xe894000f, +0xebfff15d,0xe3170102,0x0bffefef,0x1bffefa5, +0xe1a0400c,0xe92c000f,0xe894000f,0xebffef9e, +0xe8bc0d80,0xebffef9c,0xe28cc010,0xe8bc0d80, +0xebffef99,0xe3a04c3f,0xe38440df,0xe1530004, +0xba000037,0xe88c000f,0xebfff03b,0xe92c000f, +0xe3a07000,0xe8b90d00,0xebfff03b,0xe8b90d00, +0xebffefd9,0xe89c0d80,0xebfff037,0xe8b90d00, +0xebffef8c,0xe89c0d80,0xebfff033,0xe8b90d00, +0xebffefd1,0xe89c0d80,0xebfff02f,0xe8b90d00, +0xebffef84,0xe89c0d80,0xe92c000f,0xe3a00102, +0xe8b9000e,0xebfff028,0xe8b90d00,0xebffef7d, +0xe28c7010,0xe8970d80,0xebfff023,0xe8b90d00, +0xebffefc1,0xe28c7010,0xe8970d80,0xebfff01e, +0xe28c7020,0xe8970d80,0xebfff01b,0xe28c7020, +0xe8970d80,0xebffef6c,0xe8bc0d80,0xe28cc020, +0xe8bc0010,0xe3140001,0x12200102,0x1bfff1a7, +0xe29b4902,0x4a000018,0xe35b0000,0x0198400a, +0x0a000015,0xebfff061,0xe8bc4200,0xe3b04000, +0xe1a0f00e,0xe24cc010,0xe3a07000,0xe3a08102, +0xe3b0a100,0xe2eab901,0xeaffffeb,0xe1914002, +0x0affff99,0xe2433001,0xe0922002,0xe0b11001, +0x5afffffb,0xeaffff94,0xe3a01332,0xe3b02100, +0xe2f23902,0xe3a04001,0xe1a0f00e,0xe3a01000, +0xe3b02100,0xe2f33902,0xe3a04004,0xe8bc4200, +0xe1a0f00e,0xe2844001,0xe35b0000,0x03a08102, +0xe3a06901,0x0246b002,0x01a0f00e,0xe2466002, +0xe04b6006,0xe3a05102,0xe153000b,0x01510008, +0x0152000a,0x20888635,0x21a0f00e,0xe0588635, +0x51a08088,0x524bb001,0xe2444001,0xe1a0f00e, +0xc90fdaa2,0x00000000,0x0000401d,0xa2f9836e, +0x4e44152a,0x00003ffe,0x95777a5c,0xf72cece6, +0x00003fed,0xc9100000,0x00000000,0x00003fff, +0x85bba783,0xb3c748a9,0x00003fea,0xa37b24c8, +0x4a42092e,0x00003ff3,0xd23cf50b,0xf10aca84, +0x00003ff9,0xeef5823f,0xdecea969,0x00003ffd, +0x80000000,0x00000000,0x00003fff,0x95d5b975, +0x16391da8,0x00003fef,0xe0741531,0xdd56f650, +0x00003ff6,0x8895af2a,0x6847fcd5,0x00003ffc, +0xe3190080,0x1affee00,0xe1b07e09,0x4afff7ab, +0xe08c8c27,0xe898000f,0xe1b04d23,0xe28f7000, +0x1afff279,0x1888000f,0xe1a04883,0xe2944802, +0x0a000015,0xe1c00589,0xe92c4000,0xe1914002, +0x12433001,0xebffff38,0x1a000012,0xe92c000f, +0xebffefa1,0xe3a08102,0xe3b0a100,0xe2eab901, +0xebffeef8,0xe1a07000,0xe1a08001,0xe1a0a002, +0xe1a0b003,0xe8bc000f,0xebffeff0,0xe1914002, +0x12833001,0xe8bc4000,0xeafffdc2,0xe1914002, +0x03a014c9,0xeafff9cf,0xe8bc4000,0xe3540004, +0x03a03000,0x03a00000,0x0afffdba,0xe3a014c9, +0xe3b02100,0xe2e23902,0xeafff9c6,0xe3190080, +0x1affedd1,0xe1b07e09,0x4afff780,0xe08c8c27, +0xe898000f,0xe1b04d23,0xe28f7000,0x1afff24a, +0x1888000f,0xe1b04883,0x0a00006b,0x52944802, +0x4a000072,0xe92c4201,0xe3a00000,0xe3a05901, +0xe2455002,0xe1530005,0xaa000009,0xe2094501, +0xe92c0010,0xe3a04901,0xe2444021,0xe1530004, +0xba000049,0xe92c000f,0xebffef6b,0xe92c000f, +0xea000012,0xe2094501,0xe2244501,0xe92c0010, +0xe3a00102,0xe3a08102,0xe3b0a100,0xe2eab901, +0xebffeebc,0xe1914002,0x0a00003b,0xe2433001, +0xe24cc010,0xe92c000f,0xebfff01c,0xe2200102, +0xe2833001,0xe28c4010,0xe884000f,0xe89c000f, +0xe28f9f59,0xe8b90d00,0xebffeef7,0xe89c0d80, +0xebffef55,0xe8b90d00,0xebffeeaa,0xe89c0d80, +0xebffef51,0xe8b90d00,0xebffeeef,0xe89c0d80, +0xebffef4d,0xe8b90d00,0xebffeea2,0xe89c0d80, +0xebffef49,0xe8b90d00,0xebffeee7,0xe89c0d80, +0xe92c000f,0xe3a00102,0xe8b9000e,0xebffef42, +0xe8b90d00,0xebffee97,0xe28c7010,0xe8970d80, +0xebffef3d,0xe8b90d00,0xebffeedb,0xe28c7010, +0xe8970d80,0xebffef38,0xe8b90d00,0xebffee8d, +0xe28c7010,0xe8970d80,0xebffef33,0xe8b90d00, +0xebffeed1,0xe28c7010,0xe8970d80,0xebffef2e, +0xe8bc0d80,0xe28cc010,0xebffef80,0xe89c0d80, +0xebffef29,0xe8bc0d80,0xebffee7b,0xe8bc0230, +0xe3190501,0x0a000008,0xe3150102,0x028f5c01, +0x128f5f46,0xe0855924,0x02200102,0xe8950d00, +0xebffee74,0xe8bc4000,0xeafffd46,0xe3150102, +0xe28f50dc,0xe0855924,0xe8950d00,0xebffee6d, +0x12200102,0xe8bc4000,0xeafffd3e,0xe1915002, +0x0affff93,0xe1b01001,0x4affff91,0xe2433001, +0xe0922002,0xe0b11001,0x5afffffb,0xeaffff8c, +0xe2f35901,0x01925081,0x0affff89,0xe2944802, +0x1a000001,0xe1914002,0x1afff93e,0xe3a014ca, +0xe3b02100,0xe2e23902,0xeafff93a,0xbe974377, +0xcc30f9e6,0x00004003,0x96f3e4b2,0xc8e37cbc, +0x00004006,0xbeee77e2,0xb5423cf3,0x00004007, +0xd0927880,0xf5c2170b,0x00004007,0xa43601f1, +0x5c3e6196,0x00004006,0xb25dedaf,0x30f3242c, +0x00003ffe,0xa270bb27,0x61c93957,0x00004002, +0x9ec1654d,0x36d4f820,0x00004004,0xe4d539b0, +0x56a451ad,0x00004004,0xdaf2ad41,0xd05311c4, +0x00004003,0x00000000,0x00000000,0x00000000, +0x00000000,0xc90fdaa2,0x2168c235,0x00003fff, +0xc90fdaa2,0x2168c235,0x00004000,0x00000000, +0xc90fdaa2,0x2168c235,0x00003fff,0xe3190080, +0x1affed19,0xe2096807,0xe08c6626,0xe896000f, +0xe1b04d23,0xe28f7000,0x1afff193,0x1886000f, +0xe2000102,0xe183b000,0xe1a0a002,0xe1a08001, +0xe1b06e09,0x4afff6c9,0xe08c6c26,0xe896000f, +0xe1b04d23,0xe28f7000,0x1afff187,0x1886000f, +0xe1a0700b,0xe3cbb102,0xe1b04883,0x12944802, +0x11b0588b,0x12955802,0x192c4281,0x1bffef0b, +0x1a00004e,0xe1b04883,0x1a000010,0xe1915002, +0x1a00000a,0xe1b0588b,0x0198600a,0x0a00001f, +0xe2955802,0x1a000016,0xe198600a,0x0a000014, +0xe1a01008,0xe1a0200a,0xe1a0300b,0xeafff8e1, +0xe0922002,0xe0b11001,0xe2433001,0x5afffffb, +0xe1b0588b,0x1a000019,0xe198600a,0x1a000013, +0xe2944802,0x1a000001,0xe1916002,0x1afff8d5, +0xe1a04000,0xe1a05007,0xe28f0fbd,0xe890000e, +0xea00008c,0xe1a04000,0xe1a05007,0xe3a00000, +0xe3a01000,0xe3a02000,0xe3a03000,0xea00007d, +0xe3a014cb,0xe3b02100,0xe2e23902,0xeafff8c5, +0xe09aa00a,0xe0b88008,0xe24bb001,0x5afffffb, +0xe2956802,0x12946802,0x1affffca,0xe2946802, +0x1a000006,0xe1916002,0x1afff8ba,0xe2956802, +0x1affffe2,0xe198600a,0x03a014cb,0x0afff8b5, +0xe198600a,0x0affffe2,0xe1a01008,0xe1a0200a, +0xe1a0300b,0xeafff8af,0xe3190080,0x1affecba, +0xe1b07e09,0x4afff671,0xe08c8c27,0xe898000f, +0xe1b04d23,0xe28f7000,0x1afff133,0x1888000f, +0xe1b04883,0x12944802,0x0a000060,0xe92c4281, +0xe3b00100,0xe2f34901,0xdbffeeb0,0xd3a04002, +0xc3a04000,0xe28f9d06,0xe8b90d00,0xe153000b, +0x01510008,0x0152000a,0xc2844001,0xe92c0010, +0xda00000d,0xe92c000f,0xe8990d00,0xebffedad, +0xe8bc0d80,0xe92c000f,0xe3a00000,0xe8b9000e, +0xebffee51,0xe3a08102,0xe3b0a100,0xe2eab901, +0xebffeded,0xe8bc0d80,0xebffeea0,0xe3a04901, +0xe2444021,0xe1530004,0xba00002c,0xe92c000f, +0xebffee41,0xe92c000f,0xe28f9f49,0xe8b90d00, +0xebffed98,0xe89c0d80,0xebffee3f,0xe8b90d00, +0xebffed94,0xe89c0d80,0xebffee3b,0xe8b90d00, +0xebffed90,0xe89c0d80,0xebffee37,0xe8b90d00, +0xebffed8c,0xe89c0d80,0xe92c000f,0xe3a00102, +0xe8b9000e,0xebffee30,0xe8b90d00,0xebffedce, +0xe28c7010,0xe8970d80,0xebffee2b,0xe8b90d00, +0xebffedc9,0xe28c7010,0xe8970d80,0xebffee26, +0xe8b90d00,0xebffedc4,0xe28c7010,0xe8970d80, +0xebffee21,0xe8bc0d80,0xe28cc010,0xebffee73, +0xe89c0d80,0xebffee1c,0xe8bc0d80,0xebffed6e, +0xe28f90dc,0xe8bc0010,0xe0200f04,0xe0899204, +0xe8990d00,0xebffed6b,0xe8bc4230,0xe3190601, +0x10200004,0x1afffc3b,0xe3150102,0x0a000005, +0xe92c4010,0xe2200102,0xe24f7d0d,0xe8970d00, +0xebffed60,0xe8bc4010,0xe0200004,0xeafffc31, +0xe3530000,0x0afffc2f,0xe1914002,0x1afff83d, +0xe28f009c,0xe890000e,0xeafffc2a,0x8930a2f4, +0xf66ab18a,0x00003ffd,0xddb3d742,0xc265539e, +0x00003fff,0xf0624f0a,0x56388310,0x00004002, +0xee505190,0x6d1eb4e8,0x00004004,0xac509020, +0x5b6d243b,0x00004005,0xa443e5e6,0x24ad4b90, +0x00004004,0xd66bd6cd,0x8c3de934,0x00003ffe, +0x87e9fae4,0x6b531a29,0x00004002,0xa40bfdcf, +0x15e65691,0x00004003,0xdb053288,0x30e70eb4, +0x00004002,0x00000000,0x00000000,0x00000000, +0x00000000,0x860a91c1,0x6b9b2c23,0x00003ffe, +0x00000000,0xc90fdaa2,0x2168c235,0x00003fff, +0x00000000,0x860a91c1,0x6b9b2c23,0x00003fff, +0xe92d5001,0xe24fc05c,0xe24ccc50,0xe3a00807, +0xe58c0080,0xe8bd9001,0xe1a00000,0xe3100001, +0x128f0e15,0x1a00000a,0xe3100004,0x128f0f47, +0x1a000007,0xe3100002,0x128f00e0,0x1a000004, +0xe3100008,0x128f00a8,0x1a000001,0xe28f0070, +0xeaffffff,0xe28f101c,0xe14fb000,0xe8bd07f8, +0xe8a107f8,0xe8bd07f8,0xe24aa004,0xe8a10ff8, +0xe28f1000,0xef000071,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00000000, +0x00000000,0x00000000,0x00000000,0x00002278, +0xffffffff,0x80000204,0x616f6c46,0x676e6974, +0x696f5020,0x4520746e,0x70656378,0x6e6f6974, +0x49203a20,0x6178656e,0x52207463,0x6c757365, +0x00000074,0x80000203,0x616f6c46,0x676e6974, +0x696f5020,0x4520746e,0x70656378,0x6e6f6974, +0x55203a20,0x7265646e,0x776f6c66,0x00000000, +0x80000202,0x616f6c46,0x676e6974,0x696f5020, +0x4520746e,0x70656378,0x6e6f6974,0x44203a20, +0x64697669,0x79422065,0x72655a20,0x0000006f, +0x80000201,0x616f6c46,0x676e6974,0x696f5020, +0x4520746e,0x70656378,0x6e6f6974,0x4f203a20, +0x66726576,0x00776f6c,0x80000200,0x616f6c46, +0x676e6974,0x696f5020,0x4520746e,0x70656378, +0x6e6f6974,0x49203a20,0x6c61766e,0x4f206469, +0x61726570,0x6e6f6974,0x00000000,0xfefefeff,0} ; + +unsigned long fpesize = 0x00005300 ; diff --git a/sim/arm/arminit.c b/sim/arm/arminit.c new file mode 100644 index 0000000..9ef7b1c --- /dev/null +++ b/sim/arm/arminit.c @@ -0,0 +1,294 @@ +/* arminit.c -- ARMulator initialization: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 "armdefs.h" +#include "armemu.h" + +/***************************************************************************\ +* Definitions for the emulator architecture * +\***************************************************************************/ + +void ARMul_EmulateInit(void) ; +ARMul_State *ARMul_NewState(void) ; +void ARMul_Reset(ARMul_State *state) ; +ARMword ARMul_DoCycle(ARMul_State *state) ; +unsigned ARMul_DoCoPro(ARMul_State *state) ; +ARMword ARMul_DoProg(ARMul_State *state) ; +ARMword ARMul_DoInstr(ARMul_State *state) ; +void ARMul_Abort(ARMul_State *state, ARMword address) ; + +unsigned ARMul_MultTable[32] = {1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9, + 10,10,11,11,12,12,13,13,14,14,15,15,16,16,16} ; +ARMword ARMul_ImmedTable[4096] ; /* immediate DP LHS values */ +char ARMul_BitList[256] ; /* number of bits in a byte table */ + +/***************************************************************************\ +* Call this routine once to set up the emulator's tables. * +\***************************************************************************/ + +void ARMul_EmulateInit(void) +{unsigned long i, j ; + + for (i = 0 ; i < 4096 ; i++) { /* the values of 12 bit dp rhs's */ + ARMul_ImmedTable[i] = ROTATER(i & 0xffL,(i >> 7L) & 0x1eL) ; + } + + for (i = 0 ; i < 256 ; ARMul_BitList[i++] = 0 ) ; /* how many bits in LSM */ + for (j = 1 ; j < 256 ; j <<= 1) + for (i = 0 ; i < 256 ; i++) + if ((i & j) > 0 ) + ARMul_BitList[i]++ ; + + for (i = 0 ; i < 256 ; i++) + ARMul_BitList[i] *= 4 ; /* you always need 4 times these values */ + +} + +/***************************************************************************\ +* Returns a new instantiation of the ARMulator's state * +\***************************************************************************/ + +ARMul_State *ARMul_NewState(void) +{ARMul_State *state ; + unsigned i, j ; + + state = (ARMul_State *)malloc(sizeof(ARMul_State)) ; + memset (state, 0, sizeof (ARMul_State)); + + state->Emulate = RUN ; + for (i = 0 ; i < 16 ; i++) { + state->Reg[i] = 0 ; + for (j = 0 ; j < 7 ; j++) + state->RegBank[j][i] = 0 ; + } + for (i = 0 ; i < 7 ; i++) + state->Spsr[i] = 0 ; + state->Mode = 0 ; + + state->CallDebug = FALSE ; + state->Debug = FALSE ; + state->VectorCatch = 0 ; + state->Aborted = FALSE ; + state->Reseted = FALSE ; + state->Inted = 3 ; + state->LastInted = 3 ; + + state->MemDataPtr = NULL ; + state->MemInPtr = NULL ; + state->MemOutPtr = NULL ; + state->MemSparePtr = NULL ; + state->MemSize = 0 ; + + state->OSptr = NULL ; + state->CommandLine = NULL ; + + state->EventSet = 0 ; + state->Now = 0 ; + state->EventPtr = (struct EventNode **)malloc((unsigned)EVENTLISTSIZE * + sizeof(struct EventNode *)) ; + for (i = 0 ; i < EVENTLISTSIZE ; i++) + *(state->EventPtr + i) = NULL ; + +#ifdef ARM61 + state->prog32Sig = LOW ; + state->data32Sig = LOW ; +#else + state->prog32Sig = HIGH ; + state->data32Sig = HIGH ; +#endif + + state->lateabtSig = LOW ; + state->bigendSig = LOW ; + + ARMul_Reset(state) ; + return(state) ; + } + +/***************************************************************************\ +* Call this routine to set ARMulator to model a certain processor * +\***************************************************************************/ + +void ARMul_SelectProcessor(ARMul_State *state, unsigned processor) { + if (processor & ARM_Fix26_Prop) { + state->prog32Sig = LOW; + state->data32Sig = LOW; + }else{ + state->prog32Sig = HIGH; + state->data32Sig = HIGH; + } + + state->lateabtSig = LOW; +} + +/***************************************************************************\ +* Call this routine to set up the initial machine state (or perform a RESET * +\***************************************************************************/ + +void ARMul_Reset(ARMul_State *state) +{state->NextInstr = 0 ; + if (state->prog32Sig) { + state->Reg[15] = 0 ; + state->Cpsr = INTBITS | SVC32MODE ; + } + else { + state->Reg[15] = R15INTBITS | SVC26MODE ; + state->Cpsr = INTBITS | SVC26MODE ; + } + ARMul_CPSRAltered(state) ; + state->Bank = SVCBANK ; + FLUSHPIPE ; + + state->EndCondition = 0 ; + state->ErrorCode = 0 ; + + state->Exception = FALSE ; + state->NresetSig = HIGH ; + state->NfiqSig = HIGH ; + state->NirqSig = HIGH ; + state->NtransSig = (state->Mode & 3)?HIGH:LOW ; + state->abortSig = LOW ; + state->AbortAddr = 1 ; + + state->NumInstrs = 0 ; + state->NumNcycles = 0 ; + state->NumScycles = 0 ; + state->NumIcycles = 0 ; + state->NumCcycles = 0 ; + state->NumFcycles = 0 ; +#ifdef ASIM + (void)ARMul_MemoryInit() ; + ARMul_OSInit(state) ; +#endif +} + + +/***************************************************************************\ +* Emulate the execution of an entire program. Start the correct emulator * +* (Emulate26 for a 26 bit ARM and Emulate32 for a 32 bit ARM), return the * +* address of the last instruction that is executed. * +\***************************************************************************/ + +ARMword ARMul_DoProg(ARMul_State *state) +{ARMword pc = 0 ; + + state->Emulate = RUN ; + while (state->Emulate != STOP) { + state->Emulate = RUN ; + if (state->prog32Sig && ARMul_MODE32BIT) + pc = ARMul_Emulate32(state) ; + else + pc = ARMul_Emulate26(state) ; + } + return(pc) ; + } + +/***************************************************************************\ +* Emulate the execution of one instruction. Start the correct emulator * +* (Emulate26 for a 26 bit ARM and Emulate32 for a 32 bit ARM), return the * +* address of the instruction that is executed. * +\***************************************************************************/ + +ARMword ARMul_DoInstr(ARMul_State *state) +{ARMword pc = 0 ; + + state->Emulate = ONCE ; + if (state->prog32Sig && ARMul_MODE32BIT) + pc = ARMul_Emulate32(state) ; + else + pc = ARMul_Emulate26(state) ; + + return(pc) ; + } + +/***************************************************************************\ +* This routine causes an Abort to occur, including selecting the correct * +* mode, register bank, and the saving of registers. Call with the * +* appropriate vector's memory address (0,4,8 ....) * +\***************************************************************************/ + +void ARMul_Abort(ARMul_State *state, ARMword vector) +{ARMword temp ; + + state->Aborted = FALSE ; + + if (ARMul_OSException(state,vector,ARMul_GetPC(state))) + return ; + + if (state->prog32Sig) + if (ARMul_MODE26BIT) + temp = R15PC ; + else + temp = state->Reg[15] ; + else + temp = R15PC | ECC | ER15INT | EMODE ; + + switch (vector) { + case ARMul_ResetV : /* RESET */ + state->Spsr[SVCBANK] = CPSR ; + SETABORT(INTBITS,state->prog32Sig?SVC32MODE:SVC26MODE) ; + ARMul_CPSRAltered(state) ; + state->Reg[14] = temp ; + break ; + case ARMul_UndefinedInstrV : /* Undefined Instruction */ + state->Spsr[state->prog32Sig?UNDEFBANK:SVCBANK] = CPSR ; + SETABORT(IBIT,state->prog32Sig?UNDEF32MODE:SVC26MODE) ; + ARMul_CPSRAltered(state) ; + state->Reg[14] = temp - 4 ; + break ; + case ARMul_SWIV : /* Software Interrupt */ + state->Spsr[SVCBANK] = CPSR ; + SETABORT(IBIT,state->prog32Sig?SVC32MODE:SVC26MODE) ; + ARMul_CPSRAltered(state) ; + state->Reg[14] = temp - 4 ; + break ; + case ARMul_PrefetchAbortV : /* Prefetch Abort */ + state->AbortAddr = 1 ; + state->Spsr[state->prog32Sig?ABORTBANK:SVCBANK] = CPSR ; + SETABORT(IBIT,state->prog32Sig?ABORT32MODE:SVC26MODE) ; + ARMul_CPSRAltered(state) ; + state->Reg[14] = temp - 4 ; + break ; + case ARMul_DataAbortV : /* Data Abort */ + state->Spsr[state->prog32Sig?ABORTBANK:SVCBANK] = CPSR ; + SETABORT(IBIT,state->prog32Sig?ABORT32MODE:SVC26MODE) ; + ARMul_CPSRAltered(state) ; + state->Reg[14] = temp - 4 ; /* the PC must have been incremented */ + break ; + case ARMul_AddrExceptnV : /* Address Exception */ + state->Spsr[SVCBANK] = CPSR ; + SETABORT(IBIT,SVC26MODE) ; + ARMul_CPSRAltered(state) ; + state->Reg[14] = temp - 4 ; + break ; + case ARMul_IRQV : /* IRQ */ + state->Spsr[IRQBANK] = CPSR ; + SETABORT(IBIT,state->prog32Sig?IRQ32MODE:IRQ26MODE) ; + ARMul_CPSRAltered(state) ; + state->Reg[14] = temp - 4 ; + break ; + case ARMul_FIQV : /* FIQ */ + state->Spsr[FIQBANK] = CPSR ; + SETABORT(INTBITS,state->prog32Sig?FIQ32MODE:FIQ26MODE) ; + ARMul_CPSRAltered(state) ; + state->Reg[14] = temp - 4 ; + break ; + } + if (ARMul_MODE32BIT) + ARMul_SetR15(state,vector) ; + else + ARMul_SetR15(state,R15CCINTMODE | vector) ; +} diff --git a/sim/arm/armopts.h b/sim/arm/armopts.h new file mode 100644 index 0000000..c3b5cb7 --- /dev/null +++ b/sim/arm/armopts.h @@ -0,0 +1,23 @@ +/* armopts.h -- ARMulator configuration options: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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. */ + +/* Define one of ARM60 or ARM61 */ +#ifndef ARM60 +#ifndef ARM61 +#define ARM60 +#endif +#endif diff --git a/sim/arm/armos.c b/sim/arm/armos.c new file mode 100644 index 0000000..2906d41 --- /dev/null +++ b/sim/arm/armos.c @@ -0,0 +1,1136 @@ +/* armos.c -- ARMulator OS interface: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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. */ + +/* This file contains a model of Demon, ARM Ltd's Debug Monitor, +including all the SWI's required to support the C library. The code in +it is not really for the faint-hearted (especially the abort handling +code), but it is a complete example. Defining NOOS will disable all the +fun, and definign VAILDATE will define SWI 1 to enter SVC mode, and SWI +0x11 to halt the emulator. */ + +#include "config.h" + +#include <time.h> +#include <errno.h> +#include <string.h> +#include <fcntl.h> + +#ifndef O_RDONLY +#define O_RDONLY 0 +#endif +#ifndef O_WRONLY +#define O_WRONLY 1 +#endif +#ifndef O_RDWR +#define O_RDWR 2 +#endif +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#ifdef __STDC__ +#define unlink(s) remove(s) +#endif + +#ifdef HAVE_UNISTD_H +#include <unistd.h> /* For SEEK_SET etc */ +#endif + +#ifdef __riscos +extern int _fisatty(FILE *); +#define isatty_(f) _fisatty(f) +#else +#ifdef __ZTC__ +#include <io.h> +#define isatty_(f) isatty((f)->_file) +#else +#ifdef macintosh +#include <ioctl.h> +#define isatty_(f) (~ioctl ((f)->_file, FIOINTERACTIVE, NULL)) +#else +#define isatty_(f) isatty (fileno (f)) +#endif +#endif +#endif + +#include "armdefs.h" +#include "armos.h" +#ifndef NOOS +#ifndef VALIDATE +/* #ifndef ASIM */ +#include "armfpe.h" +/* #endif */ +#endif +#endif + +/* For RDIError_BreakpointReached. */ +#include "dbg_rdi.h" + +extern unsigned ARMul_OSInit(ARMul_State *state) ; +extern void ARMul_OSExit(ARMul_State *state) ; +extern unsigned ARMul_OSHandleSWI(ARMul_State *state,ARMword number) ; +extern unsigned ARMul_OSException(ARMul_State *state, ARMword vector, ARMword pc) ; +extern ARMword ARMul_OSLastErrorP(ARMul_State *state) ; +extern ARMword ARMul_Debug(ARMul_State *state, ARMword pc, ARMword instr) ; + +#define BUFFERSIZE 4096 +#ifndef FOPEN_MAX +#define FOPEN_MAX 64 +#endif +#define UNIQUETEMPS 256 + +#ifndef NOOS +static void UnwindDataAbort(ARMul_State *state, ARMword addr); +static void getstring(ARMul_State *state, ARMword from, char *to) ; +#endif + +/***************************************************************************\ +* OS private Information * +\***************************************************************************/ + +struct OSblock { + ARMword Time0 ; + ARMword ErrorP ; + ARMword ErrorNo ; + FILE *FileTable[FOPEN_MAX] ; + char FileFlags[FOPEN_MAX] ; + char *tempnames[UNIQUETEMPS] ; + } ; + +#define NOOP 0 +#define BINARY 1 +#define READOP 2 +#define WRITEOP 4 + +#ifdef macintosh +#define FIXCRLF(t,c) ((t & BINARY) ? \ + c : \ + ((c == '\n' || c == '\r' ) ? (c ^ 7) : c) \ + ) +#else +#define FIXCRLF(t,c) c +#endif + +static ARMword softvectorcode[] = +{ /* basic: swi tidyexception + event; mov pc, lr; + ldmia r11,{r11,pc}; swi generateexception + event + */ + 0xef000090, 0xe1a0e00f, 0xe89b8800, 0xef000080, /*Reset*/ + 0xef000091, 0xe1a0e00f, 0xe89b8800, 0xef000081, /*Undef*/ + 0xef000092, 0xe1a0e00f, 0xe89b8800, 0xef000082, /*SWI */ + 0xef000093, 0xe1a0e00f, 0xe89b8800, 0xef000083, /*Prefetch abort*/ + 0xef000094, 0xe1a0e00f, 0xe89b8800, 0xef000084, /*Data abort*/ + 0xef000095, 0xe1a0e00f, 0xe89b8800, 0xef000085, /*Address exception*/ + 0xef000096, 0xe1a0e00f, 0xe89b8800, 0xef000086, /*IRQ*/ + 0xef000097, 0xe1a0e00f, 0xe89b8800, 0xef000087, /*FIQ*/ + 0xef000098, 0xe1a0e00f, 0xe89b8800, 0xef000088, /*Error*/ + 0xe1a0f00e /* default handler */ +}; + +/***************************************************************************\ +* Time for the Operating System to initialise itself. * +\***************************************************************************/ + +unsigned +ARMul_OSInit (ARMul_State *state) +{ +#ifndef NOOS +#ifndef VALIDATE + ARMword instr, i , j ; + struct OSblock* OSptr = (struct OSblock*)state->OSptr; + + if (state->OSptr == NULL) { + state->OSptr = (unsigned char *)malloc(sizeof(struct OSblock)); + if (state->OSptr == NULL) { + perror("OS Memory"); + exit(15); + } + } + OSptr = (struct OSblock*)state->OSptr; + OSptr->ErrorP = 0; + state->Reg[13] = ADDRSUPERSTACK; /* set up a stack for the current mode */ + ARMul_SetReg(state,SVC32MODE,13,ADDRSUPERSTACK); /* and for supervisor mode */ + ARMul_SetReg(state,ABORT32MODE,13,ADDRSUPERSTACK); /* and for abort 32 mode */ + ARMul_SetReg(state,UNDEF32MODE,13,ADDRSUPERSTACK); /* and for undef 32 mode */ + instr = 0xe59ff000 | (ADDRSOFTVECTORS - 8); /* load pc from soft vector */ + for (i = ARMul_ResetV ; i <= ARMFIQV ; i += 4) + ARMul_WriteWord(state, i, instr); /* write hardware vectors */ + for (i = ARMul_ResetV ; i <= ARMFIQV + 4 ; i += 4) { + ARMul_WriteWord(state, ADDRSOFTVECTORS + i, SOFTVECTORCODE + i * 4); + ARMul_WriteWord(state, ADDRSOFHANDLERS + 2*i + 4L, SOFTVECTORCODE + sizeof(softvectorcode) - 4L); + } + for (i = 0 ; i < sizeof(softvectorcode) ; i += 4) + ARMul_WriteWord(state, SOFTVECTORCODE + i, softvectorcode[i/4]); + for (i = 0 ; i < FOPEN_MAX ; i++) + OSptr->FileTable[i] = NULL ; + for (i = 0 ; i < UNIQUETEMPS ; i++) + OSptr->tempnames[i] = NULL ; + ARMul_ConsolePrint (state, ", Demon 1.01"); + +/* #ifndef ASIM */ + + /* install fpe */ + for (i = 0 ; i < fpesize ; i+=4) /* copy the code */ + ARMul_WriteWord(state,FPESTART + i,fpecode[i >> 2]) ; + for (i = FPESTART + fpesize ; ; i-=4) { /* reverse the error strings */ + if ((j = ARMul_ReadWord(state,i)) == 0xffffffff) + break ; + if (state->bigendSig && j < 0x80000000) { /* it's part of the string so swap it */ + j = ((j >> 0x18) & 0x000000ff) | + ((j >> 0x08) & 0x0000ff00) | + ((j << 0x08) & 0x00ff0000) | + ((j << 0x18) & 0xff000000) ; + ARMul_WriteWord(state,i,j) ; + } + } + ARMul_WriteWord(state,FPEOLDVECT,ARMul_ReadWord(state,4)) ; /* copy old illegal instr vector */ + ARMul_WriteWord(state,4,FPENEWVECT(ARMul_ReadWord(state,i-4))) ; /* install new vector */ + ARMul_ConsolePrint (state, ", FPE") ; + +/* #endif /* ASIM */ +#endif /* VALIDATE */ +#endif /* NOOS */ + + return(TRUE) ; +} + +void +ARMul_OSExit (ARMul_State *state) +{ + free((char *)state->OSptr); +} + + +/***************************************************************************\ +* Return the last Operating System Error. * +\***************************************************************************/ + +ARMword +ARMul_OSLastErrorP (ARMul_State *state) +{ + return ((struct OSblock *)state->OSptr)->ErrorP; +} + +#if 1 /* CYGNUS LOCAL */ +/* This is the cygnus way of doing it, which makes it simple to do our tests */ + +static int translate_open_mode[] = +{ + O_RDONLY, /* "r" */ + O_RDONLY+O_BINARY, /* "rb" */ + O_RDWR, /* "r+" */ + O_RDWR +O_BINARY, /* "r+b" */ + O_WRONLY +O_CREAT+O_TRUNC, /* "w" */ + O_WRONLY+O_BINARY+O_CREAT+O_TRUNC, /* "wb" */ + O_RDWR +O_CREAT+O_TRUNC, /* "w+" */ + O_RDWR +O_BINARY+O_CREAT+O_TRUNC, /* "w+b" */ + O_WRONLY +O_APPEND+O_CREAT,/* "a" */ + O_WRONLY+O_BINARY+O_APPEND+O_CREAT,/* "ab" */ + O_RDWR +O_APPEND+O_CREAT,/* "a+" */ + O_RDWR +O_BINARY+O_APPEND+O_CREAT /* "a+b" */ +}; + +static void +SWIWrite0 (ARMul_State *state, ARMword addr) +{ + ARMword temp; + struct OSblock* OSptr = (struct OSblock*) state->OSptr; + + while ((temp = ARMul_ReadByte (state, addr++)) != 0) + (void) fputc ((char) temp, stderr); + + OSptr->ErrorNo = errno; +} + +static void +WriteCommandLineTo (ARMul_State *state, ARMword addr) +{ + ARMword temp; + char *cptr = state->CommandLine; + if (cptr == NULL) + cptr = "\0"; + do { + temp = (ARMword) *cptr++; + ARMul_WriteByte (state, addr++, temp); + } while (temp != 0); +} + +static void +SWIopen (ARMul_State *state, ARMword name, ARMword SWIflags) +{ + struct OSblock* OSptr = (struct OSblock*)state->OSptr; + char dummy[2000]; + int flags; + int i; + + for (i = 0; + dummy[i] = ARMul_ReadByte (state, name + i); + i++) + ; + + /* Now we need to decode the Demon open mode */ + flags = translate_open_mode[SWIflags]; + + /* Filename ":tt" is special: it denotes stdin/out */ + if (strcmp (dummy, ":tt") == 0) + { + if (flags == O_RDONLY) /* opening tty "r" */ + state->Reg[0] = 0; /* stdin */ + else + state->Reg[0] = 1; /* stdout */ + } + else + { + state->Reg[0] = (int) open (dummy, flags); + OSptr->ErrorNo = errno; + } +} + +static void +SWIread (ARMul_State *state, ARMword f, ARMword ptr, ARMword len) +{ + struct OSblock* OSptr = (struct OSblock*) state->OSptr; + int res; + int i; + char *local = malloc (len); + + res = read (f, local, len); + if (res > 0) + for (i = 0; i < res; i++) + ARMul_WriteByte (state, ptr + i, local[i]); + free (local); + state->Reg[0] = res == -1 ? -1 : len - res; + OSptr->ErrorNo = errno; +} + +static void +SWIwrite (ARMul_State *state, ARMword f, ARMword ptr, ARMword len) +{ + struct OSblock* OSptr = (struct OSblock*) state->OSptr; + int res; + int i; + char *local = malloc (len); + + for (i = 0; i < len; i++) + { + local[i] = ARMul_ReadByte (state, ptr + i); + } + res = write (f, local, len); + state->Reg[0] = res == -1 ? -1 : len - res; + free (local); + OSptr->ErrorNo = errno; +} + +static void +SWIflen (ARMul_State *state, ARMword fh) +{ + struct OSblock* OSptr = (struct OSblock*) state->OSptr; + ARMword addr; + + if (fh == 0 || fh > FOPEN_MAX) + { + OSptr->ErrorNo = EBADF; + state->Reg[0] = -1L; + return; + } + + addr = lseek (fh, 0, SEEK_CUR); + if (addr < 0) + state->Reg[0] = -1L; + else + { + state->Reg[0] = lseek (fh, 0L, SEEK_END); + (void) lseek (fh, addr, SEEK_SET); + } + + OSptr->ErrorNo = errno; +} + +/***************************************************************************\ +* The emulator calls this routine when a SWI instruction is encuntered. The * +* parameter passed is the SWI number (lower 24 bits of the instruction). * +\***************************************************************************/ + +unsigned +ARMul_OSHandleSWI (ARMul_State *state, ARMword number) +{ + ARMword addr, temp, fildes; + char buffer[BUFFERSIZE], *cptr; + FILE *fptr; + struct OSblock* OSptr = (struct OSblock*)state->OSptr; + + switch (number) + { + case SWI_Read: + SWIread (state, state->Reg[0], state->Reg[1], state->Reg[2]); + return TRUE; + + case SWI_Write: + SWIwrite (state, state->Reg[0], state->Reg[1], state->Reg[2]); + return TRUE; + + case SWI_Open: + SWIopen (state, state->Reg[0],state->Reg[1]); + return TRUE; + + case SWI_Clock : + /* return number of centi-seconds... */ + state->Reg[0] = +#ifdef CLOCKS_PER_SEC + (CLOCKS_PER_SEC >= 100) + ? (ARMword) (clock() / (CLOCKS_PER_SEC / 100)) + : (ARMword) ((clock() * 100) / CLOCKS_PER_SEC) ; +#else + /* presume unix... clock() returns microseconds */ + (ARMword) (clock() / 10000) ; +#endif + OSptr->ErrorNo = errno ; + return(TRUE) ; + + case SWI_Time : + state->Reg[0] = (ARMword)time(NULL) ; + OSptr->ErrorNo = errno ; + return(TRUE) ; + + case SWI_Close: + state->Reg[0] = close (state->Reg[0]); + OSptr->ErrorNo = errno; + return TRUE; + + case SWI_Flen : + SWIflen (state, state->Reg[0]); + return(TRUE) ; + + case SWI_Exit: + state->Emulate = FALSE ; + return TRUE; + + case SWI_Seek: + { + /* We must return non-zero for failure */ + state->Reg[0] = -1 >= lseek (state->Reg[0], + state->Reg[1], + SEEK_SET); + OSptr->ErrorNo = errno; + return TRUE; + } + + case SWI_WriteC : + (void)fputc((int)state->Reg[0],stderr) ; + OSptr->ErrorNo = errno ; + return(TRUE) ; + + case SWI_Write0 : + SWIWrite0 (state, state->Reg[0]); + return(TRUE) ; + + case SWI_GetErrno : + state->Reg[0] = OSptr->ErrorNo ; + return(TRUE) ; + + case SWI_Breakpoint : + state->EndCondition = RDIError_BreakpointReached ; + state->Emulate = FALSE ; + return(TRUE) ; + + case SWI_GetEnv : + state->Reg[0] = ADDRCMDLINE ; + if (state->MemSize) + state->Reg[1] = state->MemSize ; + else + state->Reg[1] = ADDRUSERSTACK ; + + WriteCommandLineTo (state, state->Reg[0]); + return(TRUE) ; + + /* Handle Angel SWIs as well as Demon ones */ + case AngelSWI_ARM: + case AngelSWI_Thumb: + /* R1 is almost always a parameter block */ + addr = state->Reg[1]; + /* R0 is a reason code */ + switch (state->Reg[0]) + { + /* Unimplemented reason codes */ + case AngelSWI_Reason_ReadC: + case AngelSWI_Reason_IsTTY: + case AngelSWI_Reason_TmpNam: + case AngelSWI_Reason_Remove: + case AngelSWI_Reason_Rename: + case AngelSWI_Reason_System: + case AngelSWI_Reason_EnterSVC: + default: + state->Emulate = FALSE; + return(FALSE); + + case AngelSWI_Reason_Clock: + /* return number of centi-seconds... */ + state->Reg[0] = +#ifdef CLOCKS_PER_SEC + (CLOCKS_PER_SEC >= 100) + ? (ARMword) (clock() / (CLOCKS_PER_SEC / 100)) + : (ARMword) ((clock() * 100) / CLOCKS_PER_SEC) ; +#else + /* presume unix... clock() returns microseconds */ + (ARMword) (clock() / 10000) ; +#endif + OSptr->ErrorNo = errno; + return (TRUE); + + case AngelSWI_Reason_Time: + state->Reg[0] = (ARMword) time (NULL); + OSptr->ErrorNo = errno; + return (TRUE); + + case AngelSWI_Reason_WriteC: + (void) fputc ((int) ARMul_ReadByte (state,addr), stderr); + OSptr->ErrorNo = errno; + return (TRUE); + + case AngelSWI_Reason_Write0: + SWIWrite0 (state, addr); + return (TRUE); + + case AngelSWI_Reason_Close: + state->Reg[0] = close (ARMul_ReadWord (state, addr)); + OSptr->ErrorNo = errno; + return (TRUE); + + case AngelSWI_Reason_Seek: + state->Reg[0] = -1 >= lseek (ARMul_ReadWord(state,addr), + ARMul_ReadWord(state,addr+4), + SEEK_SET); + OSptr->ErrorNo = errno; + return (TRUE); + + case AngelSWI_Reason_FLen: + SWIflen (state, ARMul_ReadWord (state, addr)); + return (TRUE); + + case AngelSWI_Reason_GetCmdLine: + WriteCommandLineTo (state, ARMul_ReadWord (state, addr)); + return (TRUE); + + case AngelSWI_Reason_HeapInfo: + /* R1 is a pointer to a pointer */ + addr = ARMul_ReadWord (state, addr); + + /* Pick up the right memory limit */ + if (state->MemSize) + temp = state->MemSize; + else + temp = ADDRUSERSTACK; + + ARMul_WriteWord (state, addr, 0); /* Heap base */ + ARMul_WriteWord (state, addr+4, temp); /* Heap limit */ + ARMul_WriteWord (state, addr+8, temp); /* Stack base */ + ARMul_WriteWord (state, addr+12, temp); /* Stack limit */ + return (TRUE); + + case AngelSWI_Reason_ReportException: + if (state->Reg[1] == ADP_Stopped_ApplicationExit) + state->Reg[0] = 0; + else + state->Reg[0] = -1; + state->Emulate = FALSE ; + return (TRUE); + + case ADP_Stopped_ApplicationExit: + state->Reg[0] = 0; + state->Emulate = FALSE ; + return (TRUE); + + case ADP_Stopped_RunTimeError: + state->Reg[0] = -1; + state->Emulate = FALSE ; + return (TRUE); + + case AngelSWI_Reason_Errno: + state->Reg[0] = OSptr->ErrorNo; + return (TRUE); + + case AngelSWI_Reason_Open: + SWIopen(state, + ARMul_ReadWord(state, addr), + ARMul_ReadWord(state, addr+4)); + return TRUE; + + case AngelSWI_Reason_Read: + SWIread(state, + ARMul_ReadWord(state, addr), + ARMul_ReadWord(state, addr+4), + ARMul_ReadWord(state, addr+8)); + return TRUE; + + case AngelSWI_Reason_Write: + SWIwrite(state, + ARMul_ReadWord(state, addr), + ARMul_ReadWord(state, addr+4), + ARMul_ReadWord(state, addr+8)); + return TRUE; + } + + default : + state->Emulate = FALSE ; + return(FALSE) ; + } +} + +#else /* CYGNUS LOCAL: #if 1 */ + +unsigned +ARMul_OSHandleSWI (ARMul_State *state, ARMword number) +{ +#ifdef NOOS + return(FALSE) ; +#else +#ifdef VALIDATE + switch (number) { + case 0x11 : + state->Emulate = FALSE ; + return(TRUE) ; + case 0x01 : + if (ARM32BITMODE) + ARMul_SetCPSR(state, (ARMul_GetCPSR(state) & 0xffffffc0) | 0x13) ; + else + ARMul_SetCPSR(state, (ARMul_GetCPSR(state) & 0xffffffc0) | 0x3) ; + return(TRUE) ; + default : + return(FALSE) ; + } +#else + ARMword addr, temp ; + char buffer[BUFFERSIZE], *cptr ; + FILE *fptr ; + struct OSblock* OSptr = (struct OSblock*)state->OSptr ; + + switch (number) { + case SWI_WriteC : + (void)fputc((int)state->Reg[0],stderr) ; + OSptr->ErrorNo = errno ; + return(TRUE) ; + + case SWI_Write0 : + addr = state->Reg[0] ; + while ((temp = ARMul_ReadByte(state,addr++)) != 0) + fputc((char)temp,stderr) ; + OSptr->ErrorNo = errno ; + return(TRUE) ; + + case SWI_ReadC : + state->Reg[0] = (ARMword)fgetc(stdin) ; + OSptr->ErrorNo = errno ; + return(TRUE) ; + + case SWI_CLI : + addr = state->Reg[0] ; + getstring(state,state->Reg[0],buffer) ; + state->Reg[0] = (ARMword)system(buffer) ; + OSptr->ErrorNo = errno ; + return(TRUE) ; + + case SWI_GetEnv : + state->Reg[0] = ADDRCMDLINE ; + if (state->MemSize) + state->Reg[1] = state->MemSize ; + else + state->Reg[1] = ADDRUSERSTACK ; + + addr = state->Reg[0] ; + cptr = state->CommandLine ; + if (cptr == NULL) + cptr = "\0" ; + do { + temp = (ARMword)*cptr++ ; + ARMul_WriteByte(state,addr++,temp) ; + } while (temp != 0) ; + return(TRUE) ; + + case SWI_Exit : +#ifdef ASIM + simkernel1_abort_run() ; +#else + state->Emulate = FALSE ; +#endif + return(TRUE) ; + + case SWI_EnterOS : + if (ARM32BITMODE) + ARMul_SetCPSR(state, (ARMul_GetCPSR(state) & 0xffffffc0) | 0x13) ; + else + ARMul_SetCPSR(state, (ARMul_GetCPSR(state) & 0xffffffc0) | 0x3) ; + return(TRUE) ; + + case SWI_GetErrno : + state->Reg[0] = OSptr->ErrorNo ; + return(TRUE) ; + + case SWI_Clock : + /* return muber of centi-seconds... */ + state->Reg[0] = +#ifdef CLOCKS_PER_SEC + (CLOCKS_PER_SEC >= 100) + ? (ARMword) (clock() / (CLOCKS_PER_SEC / 100)) + : (ARMword) ((clock() * 100) / CLOCKS_PER_SEC) ; +#else + /* presume unix... clock() returns microseconds */ + (ARMword) (clock() / 10000) ; +#endif + OSptr->ErrorNo = errno ; + return(TRUE) ; + + case SWI_Time : + state->Reg[0] = (ARMword)time(NULL) ; + OSptr->ErrorNo = errno ; + return(TRUE) ; + + case SWI_Remove : + getstring(state,state->Reg[0],buffer) ; + state->Reg[0] = unlink(buffer) ; + OSptr->ErrorNo = errno ; + return(TRUE) ; + + case SWI_Rename : { + char buffer2[BUFFERSIZE] ; + + getstring(state,state->Reg[0],buffer) ; + getstring(state,state->Reg[1],buffer2) ; + state->Reg[0] = rename(buffer,buffer2) ; + OSptr->ErrorNo = errno ; + return(TRUE) ; + } + + case SWI_Open : { +#if 0 + /* It seems to me that these are in the wrong order + sac@cygnus.com, so I've redone it to use the + flags instead, with the functionality which was already + there -- ahh, perhaps the TRUNC bit is in a different + place on the original host ?*/ + static char* fmode[] = {"r","rb","r+","r+b", + "w","wb","w+","w+b", + "a","ab","a+","a+b", + "r","r","r","r"} /* last 4 are illegal */ ; +#endif + + unsigned type ; + + type = (unsigned)(state->Reg[1] & 3L) ; + getstring(state,state->Reg[0],buffer) ; + if (strcmp(buffer,":tt")==0 && (type == O_RDONLY )) /* opening tty "r" */ + fptr = stdin ; + else if (strcmp(buffer,":tt")==0 && (type == O_WRONLY)) /* opening tty "w" */ + fptr = stderr ; + else + { + switch (type) + { + case O_RDONLY: + fptr = fopen(buffer,"r") ; + break; + case O_WRONLY: + fptr = fopen(buffer,"w") ; + break; + case O_RDWR: + fptr = fopen(buffer,"rw") ; + break; + } + } + + state->Reg[0] = 0 ; + if (fptr != NULL) { + for (temp = 0 ; temp < FOPEN_MAX ; temp++) + if (OSptr->FileTable[temp] == NULL) { + OSptr->FileTable[temp] = fptr ; + OSptr->FileFlags[temp] = type & 1 ; /* preserve the binary bit */ + state->Reg[0] = (ARMword)(temp + 1) ; + break ; + } + if (state->Reg[0] == 0) + OSptr->ErrorNo = EMFILE ; /* too many open files */ + else + OSptr->ErrorNo = errno ; + } + else + OSptr->ErrorNo = errno ; + return(TRUE) ; + } + + case SWI_Close : + temp = state->Reg[0] ; + if (temp == 0 || temp > FOPEN_MAX || OSptr->FileTable[temp - 1] == 0) { + OSptr->ErrorNo = EBADF ; + state->Reg[0] = -1L ; + return(TRUE) ; + } + temp-- ; + fptr = OSptr->FileTable[temp] ; + if (fptr == stdin || fptr == stderr) + state->Reg[0] = 0 ; + else + state->Reg[0] = fclose(fptr) ; + OSptr->FileTable[temp] = NULL ; + OSptr->ErrorNo = errno ; + return(TRUE) ; + + case SWI_Write : { + unsigned size, upto, type ; + char ch ; + + temp = state->Reg[0] ; + if (temp == 0 || temp > FOPEN_MAX || OSptr->FileTable[temp - 1] == 0) { + OSptr->ErrorNo = EBADF ; + state->Reg[0] = -1L ; + return(TRUE) ; + } + temp-- ; + fptr = OSptr->FileTable[temp] ; + type = OSptr->FileFlags[temp] ; + addr = state->Reg[1] ; + size = (unsigned)state->Reg[2] ; + + if (type & READOP) + fseek(fptr,0L,SEEK_CUR) ; + OSptr->FileFlags[temp] = (type & BINARY) | WRITEOP ; ; + while (size > 0) { + if (size >= BUFFERSIZE) + upto = BUFFERSIZE ; + else + upto = size ; + for (cptr = buffer ; (cptr - buffer) < upto ; cptr++) { + ch = (char)ARMul_ReadByte(state,(ARMword)addr++) ; + *cptr = FIXCRLF(type,ch) ; + } + temp = fwrite(buffer,1,upto,fptr) ; + if (temp < upto) { + state->Reg[0] = (ARMword)(size - temp) ; + OSptr->ErrorNo = errno ; + return(TRUE) ; + } + size -= upto ; + } + state->Reg[0] = 0 ; + OSptr->ErrorNo = errno ; + return(TRUE) ; + } + + case SWI_Read : { + unsigned size, upto, type ; + char ch ; + + temp = state->Reg[0] ; + if (temp == 0 || temp > FOPEN_MAX || OSptr->FileTable[temp - 1] == 0) { + OSptr->ErrorNo = EBADF ; + state->Reg[0] = -1L ; + return(TRUE) ; + } + temp-- ; + fptr = OSptr->FileTable[temp] ; + addr = state->Reg[1] ; + size = (unsigned)state->Reg[2] ; + type = OSptr->FileFlags[temp] ; + + if (type & WRITEOP) + fseek(fptr,0L,SEEK_CUR) ; + OSptr->FileFlags[temp] = (type & BINARY) | READOP ; ; + while (size > 0) { + if (isatty_(fptr)) { + upto = (size >= BUFFERSIZE)?BUFFERSIZE:size + 1 ; + if (fgets(buffer, upto, fptr) != 0) + temp = strlen(buffer) ; + else + temp = 0 ; + upto-- ; /* 1 char used for terminating null */ + } + else { + upto = (size>=BUFFERSIZE)?BUFFERSIZE:size ; + temp = fread(buffer,1,upto,fptr) ; + } + for (cptr = buffer ; (cptr - buffer) < temp ; cptr++) { + ch = *cptr ; + ARMul_WriteByte(state,(ARMword)addr++,FIXCRLF(type,ch)) ; + } + if (temp < upto) { + state->Reg[0] = (ARMword)(size - temp) ; + OSptr->ErrorNo = errno ; + return(TRUE) ; + } + size -= upto ; + } + state->Reg[0] = 0 ; + OSptr->ErrorNo = errno ; + return(TRUE) ; + } + + case SWI_Seek : + if (state->Reg[0] == 0 || state->Reg[0] > FOPEN_MAX + || OSptr->FileTable[state->Reg[0] - 1] == 0) { + OSptr->ErrorNo = EBADF ; + state->Reg[0] = -1L ; + return(TRUE) ; + } + fptr = OSptr->FileTable[state->Reg[0] - 1] ; + state->Reg[0] = fseek(fptr,(long)state->Reg[1],SEEK_SET) ; + OSptr->ErrorNo = errno ; + return(TRUE) ; + + case SWI_Flen : + if (state->Reg[0] == 0 || state->Reg[0] > FOPEN_MAX + || OSptr->FileTable[state->Reg[0] - 1] == 0) { + OSptr->ErrorNo = EBADF ; + state->Reg[0] = -1L ; + return(TRUE) ; + } + fptr = OSptr->FileTable[state->Reg[0] - 1] ; + addr = (ARMword)ftell(fptr) ; + if (fseek(fptr,0L,SEEK_END) < 0) + state->Reg[0] = -1 ; + else { + state->Reg[0] = (ARMword)ftell(fptr) ; + (void)fseek(fptr,addr,SEEK_SET) ; + } + OSptr->ErrorNo = errno ; + return(TRUE) ; + + case SWI_IsTTY : + if (state->Reg[0] == 0 || state->Reg[0] > FOPEN_MAX + || OSptr->FileTable[state->Reg[0] - 1] == 0) { + OSptr->ErrorNo = EBADF ; + state->Reg[0] = -1L ; + return(TRUE) ; + } + fptr = OSptr->FileTable[state->Reg[0] - 1] ; + state->Reg[0] = isatty_(fptr) ; + OSptr->ErrorNo = errno ; + return(TRUE) ; + + case SWI_TmpNam :{ + ARMword size ; + + addr = state->Reg[0] ; + temp = state->Reg[1] & 0xff ; + size = state->Reg[2] ; + if (OSptr->tempnames[temp] == NULL) { + if ((OSptr->tempnames[temp] = malloc(L_tmpnam)) == NULL) { + state->Reg[0] = 0 ; + return(TRUE) ; + } + (void)tmpnam(OSptr->tempnames[temp]) ; + } + cptr = OSptr->tempnames[temp] ; + if (strlen(cptr) > state->Reg[2]) + state->Reg[0] = 0 ; + else + do { + ARMul_WriteByte(state,addr++,*cptr) ; + } while (*cptr++ != 0) ; + OSptr->ErrorNo = errno ; + return(TRUE) ; + } + + case SWI_InstallHandler: + { ARMword handlerp = ADDRSOFHANDLERS + state->Reg[0] * 8; + ARMword oldr1 = ARMul_ReadWord(state, handlerp), + oldr2 = ARMul_ReadWord(state, handlerp + 4); + ARMul_WriteWord(state, handlerp, state->Reg[1]); + ARMul_WriteWord(state, handlerp + 4, state->Reg[2]); + state->Reg[1] = oldr1; + state->Reg[2] = oldr2; + return(TRUE); + } + + case SWI_GenerateError: + ARMul_Abort(state, ARMSWIV) ; + if (state->Emulate) + ARMul_SetR15(state, ARMul_ReadWord(state, ADDRSOFTVECTORS + ARMErrorV)); + return(TRUE); + +/* SWI's 0x9x unwind the state of the CPU after an abort of type x */ + + case 0x90: /* Branch through zero */ + { ARMword oldpsr = ARMul_GetCPSR(state) ; + ARMul_SetCPSR(state, (oldpsr & 0xffffffc0) | 0x13) ; + ARMul_SetSPSR(state, SVC32MODE, oldpsr) ; + state->Reg[14] = 0; + goto TidyCommon; + } + + case 0x98: /* Error */ + { ARMword errorp = state->Reg[0], + regp = state->Reg[1]; + unsigned i; + ARMword errorpsr = ARMul_ReadWord(state, regp + 16*4); + for (i = 0; i < 15; i++) + ARMul_SetReg(state,errorpsr,i,ARMul_ReadWord(state, regp + i*4L)) ; + state->Reg[14] = ARMul_ReadWord(state, regp + 15*4L); + state->Reg[10] = errorp; + ARMul_SetSPSR(state,state->Mode,errorpsr) ; + OSptr->ErrorP = errorp; + goto TidyCommon; + } + + case 0x94: /* Data abort */ + { ARMword addr = state->Reg[14] - 8; + ARMword cpsr = ARMul_GetCPSR(state) ; + if (ARM26BITMODE) + addr = addr & 0x3fffffc ; + ARMul_SetCPSR(state,ARMul_GetSPSR(state,cpsr)) ; + UnwindDataAbort(state, addr); + if (addr >= FPESTART && addr < FPEEND) { /* in the FPE */ + ARMword sp, spsr ; + unsigned i ; + + sp = state->Reg[13] ; + state->Reg[13] += 64 ; /* fix the aborting mode sp */ + state->Reg[14] = ARMul_ReadWord(state,sp + 60) ; /* and its lr */ + spsr = ARMul_GetSPSR(state,state->Mode) ; + state->Mode = ARMul_SwitchMode(state, state->Mode, spsr); + for (i = 0 ; i < 15 ; i++) { + ARMul_SetReg(state,spsr,i,ARMul_ReadWord(state,sp)) ; + sp += 4 ; + } + ARMul_SetCPSR(state,cpsr) ; + state->Reg[14] = ARMul_ReadWord(state,sp) + 4 ; /* botch it */ + ARMul_SetSPSR(state,state->Mode,spsr) ; + } + else + ARMul_SetCPSR(state,cpsr) ; + + /* and fall through to correct r14 */ + } + case 0x95: /* Address Exception */ + state->Reg[14] -= 4; + case 0x91: /* Undefined instruction */ + case 0x92: /* SWI */ + case 0x93: /* Prefetch abort */ + case 0x96: /* IRQ */ + case 0x97: /* FIQ */ + state->Reg[14] -= 4; + TidyCommon: + if (state->VectorCatch & (1 << (number - 0x90))) { + ARMul_SetR15(state, state->Reg[14] + 8) ; /* the 8 is the pipelining the the RDI will undo */ + ARMul_SetCPSR(state,ARMul_GetSPSR(state,ARMul_GetCPSR(state))) ; + if (number == 0x90) + state->EndCondition = 10 ; /* Branch through Zero Error */ + else + state->EndCondition = (unsigned)number - 0x8f; + state->Emulate = FALSE ; + } + else { + ARMword sp = state->Reg[13]; + ARMul_WriteWord(state, sp - 4, state->Reg[14]); + ARMul_WriteWord(state, sp - 8, state->Reg[12]); + ARMul_WriteWord(state, sp - 12, state->Reg[11]); + ARMul_WriteWord(state, sp - 16, state->Reg[10]); + state->Reg[13] = sp - 16; + state->Reg[11] = ADDRSOFHANDLERS + 8 * (number - 0x90); + } + return(TRUE); + +/* SWI's 0x8x pass an abort of type x to the debugger if a handler returns */ + + case 0x80: case 0x81: case 0x82: case 0x83: + case 0x84: case 0x85: case 0x86: case 0x87: case 0x88: + { ARMword sp = state->Reg[13]; + state->Reg[10] = ARMul_ReadWord(state, sp); + state->Reg[11] = ARMul_ReadWord(state, sp + 4); + state->Reg[12] = ARMul_ReadWord(state, sp + 8); + state->Reg[14] = ARMul_ReadWord(state, sp + 12); + state->Reg[13] = sp + 16; + ARMul_SetR15(state, state->Reg[14] + 8) ; /* the 8 is the pipelining the the RDI will undo */ + ARMul_SetCPSR(state,ARMul_GetSPSR(state,ARMul_GetCPSR(state))) ; + if (number == 0x80) + state->EndCondition = 10 ; /* Branch through Zero Error */ + else + state->EndCondition = (unsigned)number - 0x7f; + state->Emulate = FALSE ; + return(TRUE); + } + + default : + state->Emulate = FALSE ; + return(FALSE) ; + } +#endif +#endif + } +#endif /* CYGNUS LOCAL: #if 1 */ + +#ifndef NOOS +#ifndef ASIM + +/***************************************************************************\ +* The emulator calls this routine when an Exception occurs. The second * +* parameter is the address of the relevant exception vector. Returning * +* FALSE from this routine causes the trap to be taken, TRUE causes it to * +* be ignored (so set state->Emulate to FALSE!). * +\***************************************************************************/ + +unsigned +ARMul_OSException (ARMul_State *state, ARMword vector, ARMword pc) +{ /* don't use this here */ + return(FALSE) ; +} + +#endif + +/***************************************************************************\ +* Unwind a data abort * +\***************************************************************************/ + +static void +UnwindDataAbort (ARMul_State *state, ARMword addr) +{ + ARMword instr = ARMul_ReadWord(state, addr); + ARMword rn = BITS(16, 19); + ARMword itype = BITS(24, 27); + ARMword offset; + if (rn == 15) return; + if (itype == 8 || itype == 9) { + /* LDM or STM */ + unsigned long regs = BITS(0, 15); + offset = 0; + if (!BIT(21)) return; /* no wb */ + for (; regs != 0; offset++) + regs ^= (regs & -regs); + if (offset == 0) offset = 16; + } else if (itype == 12 || /* post-indexed CPDT */ + (itype == 13 && BIT(21))) { /* pre_indexed CPDT with WB */ + offset = BITS(0, 7); + } else + return; + + if (BIT(23)) + state->Reg[rn] -= offset * 4; + else + state->Reg[rn] += offset * 4; +} + +/***************************************************************************\ +* Copy a string from the debuggee's memory to the host's * +\***************************************************************************/ + +static void +getstring (ARMul_State *state, ARMword from, char *to) +{ + do + { + *to = (char) ARMul_ReadByte (state, from++); + } while (*to++ != '\0'); +} + +#endif /* NOOS */ diff --git a/sim/arm/armos.h b/sim/arm/armos.h new file mode 100644 index 0000000..ca1f05e --- /dev/null +++ b/sim/arm/armos.h @@ -0,0 +1,95 @@ +/* armos.h -- ARMulator OS definitions: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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. */ + +/***************************************************************************\ +* Define the initial layout of memory * +\***************************************************************************/ + +#define ADDRSUPERSTACK 0x800L /* supervisor stack space */ +#define ADDRUSERSTACK 0x80000L /* default user stack start */ +#define ADDRSOFTVECTORS 0x840L /* soft vectors are here */ +#define ADDRCMDLINE 0xf00L /* command line is here after a SWI GetEnv */ +#define ADDRSOFHANDLERS 0xad0L /* address and workspace for installed handlers */ +#define SOFTVECTORCODE 0xb80L /* default handlers */ + +/***************************************************************************\ +* SWI numbers * +\***************************************************************************/ + +#define SWI_WriteC 0x0 +#define SWI_Write0 0x2 +#define SWI_ReadC 0x4 +#define SWI_CLI 0x5 +#define SWI_GetEnv 0x10 +#define SWI_Exit 0x11 +#define SWI_EnterOS 0x16 + +#define SWI_GetErrno 0x60 +#define SWI_Clock 0x61 +#define SWI_Time 0x63 +#define SWI_Remove 0x64 +#define SWI_Rename 0x65 +#define SWI_Open 0x66 + +#define SWI_Close 0x68 +#define SWI_Write 0x69 +#define SWI_Read 0x6a +#define SWI_Seek 0x6b +#define SWI_Flen 0x6c + +#define SWI_IsTTY 0x6e +#define SWI_TmpNam 0x6f +#define SWI_InstallHandler 0x70 +#define SWI_GenerateError 0x71 + +#define SWI_Breakpoint 0x180000 /* see gdb's tm-arm.h */ + +#define AngelSWI_ARM 0x123456 +#define AngelSWI_Thumb 0xAB + +/* The reason codes: */ +#define AngelSWI_Reason_Open (0x01) +#define AngelSWI_Reason_Close (0x02) +#define AngelSWI_Reason_WriteC (0x03) +#define AngelSWI_Reason_Write0 (0x04) +#define AngelSWI_Reason_Write (0x05) +#define AngelSWI_Reason_Read (0x06) +#define AngelSWI_Reason_ReadC (0x07) +#define AngelSWI_Reason_IsTTY (0x09) +#define AngelSWI_Reason_Seek (0x0A) +#define AngelSWI_Reason_FLen (0x0C) +#define AngelSWI_Reason_TmpNam (0x0D) +#define AngelSWI_Reason_Remove (0x0E) +#define AngelSWI_Reason_Rename (0x0F) +#define AngelSWI_Reason_Clock (0x10) +#define AngelSWI_Reason_Time (0x11) +#define AngelSWI_Reason_System (0x12) +#define AngelSWI_Reason_Errno (0x13) +#define AngelSWI_Reason_GetCmdLine (0x15) +#define AngelSWI_Reason_HeapInfo (0x16) +#define AngelSWI_Reason_EnterSVC (0x17) +#define AngelSWI_Reason_ReportException (0x18) +#define ADP_Stopped_ApplicationExit ((2 << 16) + 38) +#define ADP_Stopped_RunTimeError ((2 << 16) + 34) + +#define FPESTART 0x2000L +#define FPEEND 0x8000L +#define FPEOLDVECT FPESTART + 0x100L + 8L * 16L + 4L /* stack + 8 regs + fpsr */ +#define FPENEWVECT(addr) 0xea000000L + ((addr) >> 2) - 3L /* branch from 4 to 0x2400 */ + +extern unsigned long fpecode[] ; +extern unsigned long fpesize ; diff --git a/sim/arm/armrdi.c b/sim/arm/armrdi.c new file mode 100644 index 0000000..348c7be --- /dev/null +++ b/sim/arm/armrdi.c @@ -0,0 +1,1044 @@ +/* armrdi.c -- ARMulator RDI interface: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 <string.h> +#include <ctype.h> +#include "armdefs.h" +#include "armemu.h" +#include "armos.h" +#include "dbg_cp.h" +#include "dbg_conf.h" +#include "dbg_rdi.h" +#include "dbg_hif.h" +#include "communicate.h" + +/***************************************************************************\ +* Declarations * +\***************************************************************************/ + +#define Watch_AnyRead (RDIWatch_ByteRead+RDIWatch_HalfRead+RDIWatch_WordRead) +#define Watch_AnyWrite (RDIWatch_ByteWrite+RDIWatch_HalfWrite+RDIWatch_WordWrite) + +static unsigned FPRegsAddr ; /* last known address of FPE regs */ +#define FPESTART 0x2000L +#define FPEEND 0x8000L + +#define IGNORE(d) (d = d) +#ifdef RDI_VERBOSE +#define TracePrint(s) \ + if (rdi_log & 1) ARMul_DebugPrint s +#else +#define TracePrint(s) +#endif + +static ARMul_State *state = NULL ; +static unsigned BreaksSet ; /* The number of breakpoints set */ + +static int rdi_log = 0 ; /* debugging ? */ + +#define LOWEST_RDI_LEVEL 0 +#define HIGHEST_RDI_LEVEL 1 +static int MYrdi_level = LOWEST_RDI_LEVEL; + +typedef struct BreakNode BreakNode; +typedef struct WatchNode WatchNode; + +struct BreakNode { /* A breakpoint list node */ + BreakNode *next ; + ARMword address ; /* The address of this breakpoint */ + unsigned type ; /* The type of comparison */ + ARMword bound ; /* The other address for a range */ + ARMword inst; + }; + +struct WatchNode { /* A watchpoint list node */ + WatchNode *next ; + ARMword address ; /* The address of this watchpoint */ + unsigned type ; /* The type of comparison */ + unsigned datatype ; /* The type of access to watch for */ + ARMword bound ; /* The other address for a range */ + }; + +BreakNode *BreakList = NULL ; +WatchNode *WatchList = NULL ; + +void ARMul_DebugPrint_i(const Dbg_HostosInterface *hostif, const char *format, ...) +{ va_list ap; + va_start(ap, format); + hostif->dbgprint(hostif->dbgarg, format, ap); + va_end(ap); +} + +void ARMul_DebugPrint(ARMul_State *state, const char *format, ...) +{ va_list ap; + va_start(ap, format); + if(!(rdi_log & 8)) + state->hostif->dbgprint(state->hostif->dbgarg, format, ap); + va_end(ap); +} + +#define CONSOLE_PRINT_MAX_LEN 128 + +void ARMul_ConsolePrint(ARMul_State *state, const char *format, ...) +{ + va_list ap; + int ch; + char *str, buf[CONSOLE_PRINT_MAX_LEN]; + int i, j; + ARMword junk; + + va_start(ap, format); + vsprintf(buf, format, ap); + + for (i = 0; buf[i] ;i++); /* The string is i chars long */ + + str = buf; + while (i >= 32) { + MYwrite_char(kidmum[1], RDP_OSOp); + MYwrite_word(kidmum[1], SWI_Write0); + MYwrite_char(kidmum[1], OS_SendString); + MYwrite_char(kidmum[1], 32); /* Send string 32bytes at a time */ + for (j = 0; j < 32; j++, str++) + MYwrite_char(kidmum[1], *str); + wait_for_osreply(&junk); + i -= 32; + } + + if (i > 0) { + MYwrite_char(kidmum[1], RDP_OSOp); + MYwrite_word(kidmum[1], SWI_Write0); + MYwrite_char(kidmum[1], OS_SendString); + MYwrite_char(kidmum[1], (unsigned char) i); /* Send remainder of string */ + for (j = 0; j < i; j++, str++) + MYwrite_char(kidmum[1], *str); + wait_for_osreply(&junk); + } + + va_end (ap); + return; + +/* str = buf; */ +/* while ((ch=*str++) != 0) */ +/* state->hostif->writec(state->hostif->hostosarg, ch); */ +} + +void ARMul_DebugPause(ARMul_State *state) +{ + if(!(rdi_log & 8)) + state->hostif->dbgpause(state->hostif->dbgarg); +} + +/***************************************************************************\ +* RDI_open * +\***************************************************************************/ + +static void InitFail(int exitcode, char const *which) { + ARMul_ConsolePrint(state, "%s interface failed to initialise. Exiting\n", + which); + exit(exitcode); +} + +static void RDIInit(unsigned type) +{if (type == 0) { /* cold start */ + state->CallDebug = state->MemReadDebug = state->MemWriteDebug = 0 ; + BreaksSet = 0 ; + } + } + +#define UNKNOWNPROC 0 + +typedef struct { char name[16]; unsigned val; } Processor; + +Processor const p_arm2 = {"ARM2", ARM2}; +Processor const p_arm2as = {"ARM2AS", ARM2as}; +Processor const p_arm61 = {"ARM61", ARM61}; +Processor const p_arm3 = {"ARM3", ARM3}; +Processor const p_arm6 = {"ARM6", ARM6}; +Processor const p_arm60 = {"ARM60", ARM60}; +Processor const p_arm600 = {"ARM600", ARM600}; +Processor const p_arm610 = {"ARM610", ARM610}; +Processor const p_arm620 = {"ARM620", ARM620}; +Processor const p_unknown= {"", UNKNOWNPROC}; + +Processor const *const processors[] = { + &p_arm6, /* default: must come first */ + &p_arm2, + &p_arm2as, + &p_arm61, + &p_arm3, + &p_arm60, + &p_arm600, + &p_arm610, + &p_arm620, + &p_unknown +}; + +typedef struct ProcessorConfig ProcessorConfig; +struct ProcessorConfig { + long id[2]; + ProcessorConfig const *self; + long count; + Processor const * const *processors; +}; + +ProcessorConfig const processorconfig = { + { ((((((long)'x' << 8) | ' ') << 8) | 'c') << 8) | 'p', + ((((((long)'u' << 8) | 's') << 8) | ' ') << 8) | 'x' + }, + &processorconfig, + 16, + processors +}; + +static int RDI_open(unsigned type, const Dbg_ConfigBlock *config, + const Dbg_HostosInterface *hostif, + struct Dbg_MCState *dbg_state) +/* Initialise everything */ +{int virgin = (state == NULL); + IGNORE(dbg_state); + +#ifdef RDI_VERBOSE + if (rdi_log & 1) { + if (virgin) + ARMul_DebugPrint_i(hostif, "RDI_open: type = %d\n",type) ; + else + ARMul_DebugPrint(state, "RDI_open: type = %d\n",type) ; + } +#endif + + if (type & 1) { /* Warm start */ + ARMul_Reset(state) ; + RDIInit(1) ; + } + else { + if (virgin) { + ARMul_EmulateInit(); + state = ARMul_NewState(); + state->hostif = hostif; + { int req = config->processor; + unsigned processor = processors[req]->val; + ARMul_SelectProcessor(state, processor); + ARMul_Reset(state); + ARMul_ConsolePrint(state, "ARMulator V1.50, %s", processors[req]->name); + } + if (ARMul_MemoryInit(state,config->memorysize) == FALSE) + InitFail(1, "Memory"); + if (config->bytesex != RDISex_DontCare) + state->bigendSig = config->bytesex ; + if (ARMul_CoProInit(state) == FALSE) + InitFail(2, "Co-Processor"); + if (ARMul_OSInit(state) == FALSE) + InitFail(3, "Operating System"); + } + ARMul_Reset(state) ; + RDIInit(0) ; + } + if (type & 2) { /* Reset the comms link */ + /* what comms link ? */ + } + if (virgin && (type & 1) == 0) /* Cold start */ + ARMul_ConsolePrint(state, ", %s endian.\n", + state->bigendSig ? "Big" : "Little"); + + if (config->bytesex == RDISex_DontCare) + return(state->bigendSig ? RDIError_BigEndian : RDIError_LittleEndian); + else + return(RDIError_NoError) ; +} + +/***************************************************************************\ +* RDI_close * +\***************************************************************************/ + +static int RDI_close(void) +{ + TracePrint((state, "RDI_close\n")); + ARMul_OSExit(state) ; + ARMul_CoProExit(state) ; + ARMul_MemoryExit(state) ; + return(RDIError_NoError) ; + } + +/***************************************************************************\ +* RDI_read * +\***************************************************************************/ + +static int RDI_read(ARMword source, void *dest, unsigned *nbytes) +{unsigned i ; + char *memptr = (char *)dest ; + + TracePrint((state, "RDI_read: source=%.8lx dest=%p nbytes=%.8x\n", + source, dest, *nbytes)); + + for (i=0 ; i < *nbytes ; i++) + *memptr++ = (char)ARMul_ReadByte(state,source++) ; + if (state->abortSig) { + state->abortSig = LOW ; + return(RDIError_DataAbort) ; + } + return(RDIError_NoError) ; + } + +/***************************************************************************\ +* RDI_write * +\***************************************************************************/ + +static int RDI_write(const void *source, ARMword dest, unsigned *nbytes) +{unsigned i ; + char *memptr = (char *)source ; + + TracePrint((state, "RDI_write: source=%p dest=%.8lx nbytes=%.8x\n", + source, dest, *nbytes)); + + for (i=0 ; i < *nbytes ; i++) + ARMul_WriteByte(state,(ARMword)dest++,(ARMword)*memptr++) ; + + if (state->abortSig) { + state->abortSig = LOW ; + return(RDIError_DataAbort) ; + } + return(RDIError_NoError) ; + } + +/***************************************************************************\ +* RDI_CPUread * +\***************************************************************************/ + +static int RDI_CPUread(unsigned mode, unsigned long mask, ARMword buffer[]) +{unsigned i , upto ; + + if (mode == RDIMode_Curr) + mode = (unsigned)(ARMul_GetCPSR(state) & MODEBITS) ; + + for (upto = 0, i = 0 ; i < 15 ; i++) + if (mask & (1L << i)){ + buffer[upto++] = ARMul_GetReg(state,mode,i) ; + } + + if (mask & RDIReg_R15) { + buffer[upto++] = ARMul_GetR15(state) ; + } + + if (mask & RDIReg_PC) { + buffer[upto++] = ARMul_GetPC(state) ; + } + + if (mask & RDIReg_CPSR) + buffer[upto++] = ARMul_GetCPSR(state) ; + + if (mask & RDIReg_SPSR) + buffer[upto++] = ARMul_GetSPSR(state,mode) ; + + TracePrint((state, "RDI_CPUread: mode=%.8x mask=%.8lx", mode, mask)); +#ifdef RDI_VERBOSE + if (rdi_log & 1) { + for (upto = 0, i = 0 ; i <= 20 ; i++) + if (mask & (1L << i)) { + ARMul_DebugPrint(state, "%c%.8lx",upto%4==0?'\n':' ',buffer[upto]) ; + upto++ ; + } + ARMul_DebugPrint(state, "\n") ; + } +#endif + + return(RDIError_NoError) ; +} + +/***************************************************************************\ +* RDI_CPUwrite * +\***************************************************************************/ + +static int RDI_CPUwrite(unsigned mode, unsigned long mask, ARMword const buffer[]) +{int i, upto; + + + TracePrint((state, "RDI_CPUwrite: mode=%.8x mask=%.8lx", mode, mask)); +#ifdef RDI_VERBOSE + if (rdi_log & 1) { + for (upto = 0, i = 0 ; i <= 20 ; i++) + if (mask & (1L << i)) { + ARMul_DebugPrint(state, "%c%.8lx",upto%4==0?'\n':' ',buffer[upto]) ; + upto++ ; + } + ARMul_DebugPrint(state, "\n") ; + } +#endif + + if (mode == RDIMode_Curr) + mode = (unsigned)(ARMul_GetCPSR(state) & MODEBITS) ; + + for (upto = 0, i = 0 ; i < 15 ; i++) + if (mask & (1L << i)) + ARMul_SetReg(state,mode,i,buffer[upto++]) ; + + if (mask & RDIReg_R15) + ARMul_SetR15(state,buffer[upto++]) ; + + if (mask & RDIReg_PC) { + + ARMul_SetPC(state,buffer[upto++]) ; + } + if (mask & RDIReg_CPSR) + ARMul_SetCPSR(state,buffer[upto++]) ; + + if (mask & RDIReg_SPSR) + ARMul_SetSPSR(state,mode,buffer[upto++]) ; + + return(RDIError_NoError) ; +} + +/***************************************************************************\ +* RDI_CPread * +\***************************************************************************/ + +static int RDI_CPread(unsigned CPnum, unsigned long mask, ARMword buffer[]) +{ARMword fpregsaddr, word[4] ; + + unsigned r, w ; + unsigned upto ; + + if (CPnum != 1 && CPnum != 2) { + unsigned char const *rmap = state->CPRegWords[CPnum]; + if (rmap == NULL) + return(RDIError_UnknownCoPro) ; + for (upto = 0, r = 0 ; r < rmap[-1] ; r++) + if (mask & (1L << r)) { + (void)state->CPRead[CPnum](state, r, &buffer[upto]); + upto += rmap[r]; + } + TracePrint((state, "RDI_CPread: CPnum=%d mask=%.8lx", CPnum, mask)); +#ifdef RDI_VERBOSE + if (rdi_log & 1) { + w = 0; + for (upto = 0, r = 0; r < rmap[-1]; r++) + if (mask & (1L << r)) { + int words = rmap[r]; + ARMul_DebugPrint(state, "%c%2d", (w >= 4 ? (w = 0, '\n') : ' '), r); + while (--words >= 0) { + ARMul_DebugPrint(state, " %.8lx", buffer[upto++]); + w++; + } + } + ARMul_DebugPrint(state, "\n") ; + } +#endif + return RDIError_NoError; + } + +#ifdef NOFPE + return RDIError_UnknownCoPro; + +#else + if (FPRegsAddr == 0) { + fpregsaddr = ARMul_ReadWord(state, 4L) ; + if ((fpregsaddr & 0xff800000) != 0xea000000) /* Must be a forward branch */ + return RDIError_UnknownCoPro; + fpregsaddr = ((fpregsaddr & 0xffffff) << 2) + 8 ; /* address in __fp_decode - 4 */ + if ((fpregsaddr < FPESTART) || (fpregsaddr >= FPEEND)) + return RDIError_UnknownCoPro; + fpregsaddr = ARMul_ReadWord(state, fpregsaddr) ; /* pointer to fp registers */ + FPRegsAddr = fpregsaddr ; + } + else + fpregsaddr = FPRegsAddr ; + + if (fpregsaddr == 0) return RDIError_UnknownCoPro; + for (upto = 0, r = 0 ; r < 8 ; r++) + if (mask & (1L << r)) { + for (w = 0 ; w < 4 ; w++) + word[w] = ARMul_ReadWord(state,fpregsaddr + (ARMword)r * 16 + (ARMword)w * 4) ; + switch ((int)(word[3] >> 29)) { + case 0 : + case 2 : + case 4 : + case 6 : /* its unpacked, convert to extended */ + buffer[upto++] = 2 ; /* mark as extended */ + buffer[upto++] = (word[3] & 0x7fff) | (word[0] & 0x80000000) ; /* exp and sign */ + buffer[upto++] = word[1] ; /* mantissa 1 */ + buffer[upto++] = word[2] ; /* mantissa 2 */ + break ; + case 1 : /* packed single */ + buffer[upto++] = 0 ; /* mark as single */ + buffer[upto++] = word[0] ; /* sign, exp and mantissa */ + buffer[upto++] = word[1] ; /* padding */ + buffer[upto++] = word[2] ; /* padding */ + break ; + case 3 : /* packed double */ + buffer[upto++] = 1 ; /* mark as double */ + buffer[upto++] = word[0] ; /* sign, exp and mantissa1 */ + buffer[upto++] = word[1] ; /* mantissa 2 */ + buffer[upto++] = word[2] ; /* padding */ + break ; + case 5 : /* packed extended */ + buffer[upto++] = 2 ; /* mark as extended */ + buffer[upto++] = word[0] ; /* sign and exp */ + buffer[upto++] = word[1] ; /* mantissa 1 */ + buffer[upto++] = word[2] ; /* mantissa 2 */ + break ; + case 7 : /* packed decimal */ + buffer[upto++] = 3 ; /* mark as packed decimal */ + buffer[upto++] = word[0] ; /* sign, exp and mantissa1 */ + buffer[upto++] = word[1] ; /* mantissa 2 */ + buffer[upto++] = word[2] ; /* mantissa 3 */ + break ; + } + } + if (mask & (1L << r)) + buffer[upto++] = ARMul_ReadWord(state,fpregsaddr + 128) ; /* fpsr */ + if (mask & (1L << (r+1) )) + buffer[upto++] = 0 ; /* fpcr */ + + TracePrint((state, "RDI_CPread: CPnum=%d mask=%.8lx\n", CPnum, mask)); +#ifdef RDI_VERBOSE + if (rdi_log & 1) { + for (upto = 0, r = 0 ; r < 9 ; r++) + if (mask & (1L << r)) { + if (r != 8) { + ARMul_DebugPrint(state, "%08lx ",buffer[upto++]) ; + ARMul_DebugPrint(state, "%08lx ",buffer[upto++]) ; + ARMul_DebugPrint(state, "%08lx ",buffer[upto++]) ; + } + ARMul_DebugPrint(state, "%08lx\n",buffer[upto++]) ; + } + ARMul_DebugPrint(state, "\n") ; + } +#endif + return(RDIError_NoError) ; +#endif /* NOFPE */ + } + +/***************************************************************************\ +* RDI_CPwrite * +\***************************************************************************/ + +static int RDI_CPwrite(unsigned CPnum, unsigned long mask, ARMword const buffer[]) +{unsigned r ; + unsigned upto ; + ARMword fpregsaddr; + + if (CPnum != 1 && CPnum != 2) { + unsigned char const *rmap = state->CPRegWords[CPnum]; + if (rmap == NULL) + return(RDIError_UnknownCoPro) ; + TracePrint((state, "RDI_CPwrite: CPnum=%d mask=%.8lx", CPnum, mask)); +#ifdef RDI_VERBOSE + if (rdi_log & 1) { + int w = 0; + for (upto = 0, r = 0; r < rmap[-1]; r++) + if (mask & (1L << r)) { + int words = rmap[r]; + ARMul_DebugPrint(state, "%c%2d", (w >= 4 ? (w = 0, '\n') : ' '), r); + while (--words >= 0) { + ARMul_DebugPrint(state, " %.8lx", buffer[upto++]); + w++; + } + } + ARMul_DebugPrint(state, "\n") ; + } +#endif + for (upto = 0, r = 0; r < rmap[-1]; r++) + if (mask & (1L << r)) { + (void)state->CPWrite[CPnum](state, r, &buffer[upto]); + upto += rmap[r]; + } + return RDIError_NoError; + } + +#ifdef NOFPE + return RDIError_UnknownCoPro; + +#else + TracePrint((state, "RDI_CPwrite: CPnum=%d mask=%.8lx", CPnum, mask)); +#ifdef RDI_VERBOSE + if (rdi_log & 1) { + for (upto = 0, r = 0 ; r < 9 ; r++) + if (mask & (1L << r)) { + if (r != 8) { + ARMul_DebugPrint(state, "%08lx ",buffer[upto++]) ; + ARMul_DebugPrint(state, "%08lx ",buffer[upto++]) ; + ARMul_DebugPrint(state, "%08lx ",buffer[upto++]) ; + } + ARMul_DebugPrint(state, "%08lx\n",buffer[upto++]) ; + } + ARMul_DebugPrint(state, "\n") ; + } +#endif + + if (FPRegsAddr == 0) { + fpregsaddr = ARMul_ReadWord(state, 4L) ; + if ((fpregsaddr & 0xff800000) != 0xea000000) /* Must be a forward branch */ + return RDIError_UnknownCoPro; + fpregsaddr = ((fpregsaddr & 0xffffff) << 2) + 8 ; /* address in __fp_decode - 4 */ + if ((fpregsaddr < FPESTART) || (fpregsaddr >= FPEEND)) + return RDIError_UnknownCoPro; + fpregsaddr = ARMul_ReadWord(state, fpregsaddr) ; /* pointer to fp registers */ + FPRegsAddr = fpregsaddr ; + } + else + fpregsaddr = FPRegsAddr ; + + if (fpregsaddr == 0) return RDIError_UnknownCoPro; + for (upto = 0, r = 0 ; r < 8 ; r++) + if (mask & (1L << r)) { + ARMul_WriteWord(state,fpregsaddr + (ARMword)r * 16,buffer[upto+1]) ; + ARMul_WriteWord(state,fpregsaddr + (ARMword)r * 16 + 4,buffer[upto+2]) ; + ARMul_WriteWord(state,fpregsaddr + (ARMword)r * 16 + 8,buffer[upto+3]) ; + ARMul_WriteWord(state,fpregsaddr + (ARMword)r * 16 + 12,(buffer[upto] * 2 + 1) << 29) ; /* mark type */ + upto += 4 ; + } + if (mask & (1L << r)) + ARMul_WriteWord(state,fpregsaddr + 128,buffer[upto++]) ; /* fpsr */ + return(RDIError_NoError) ; +#endif /* NOFPE */ +} + +static void deletebreaknode(BreakNode **prevp) { + BreakNode *p = *prevp; + *prevp = p->next; + ARMul_WriteWord(state, p->address, p->inst); + free((char *)p); + BreaksSet-- ; + state->CallDebug-- ; +} + +static int removebreak(ARMword address, unsigned type) +{ BreakNode *p, **prevp = &BreakList; + for (; (p = *prevp) != NULL ; prevp = &p->next) + if (p->address == address && p->type == type) { + deletebreaknode(prevp); + return TRUE; + } + return FALSE; +} + +/* This routine installs a breakpoint into the breakpoint table */ + +static BreakNode *installbreak(ARMword address, unsigned type, ARMword bound) +{ BreakNode *p = (BreakNode *)malloc(sizeof(BreakNode)); + p->next = BreakList; + BreakList = p; + p->address = address; + p->type = type; + p->bound = bound; + p->inst = ARMul_ReadWord(state, address); + ARMul_WriteWord(state, address, 0xee000000L); + return p; +} + +/***************************************************************************\ +* RDI_setbreak * +\***************************************************************************/ + +static int RDI_setbreak(ARMword address, unsigned type, ARMword bound, + PointHandle *handle) +{ BreakNode *p; + TracePrint((state, "RDI_setbreak: address=%.8lx type=%d bound=%.8lx\n", + address, type, bound)); + + removebreak(address, type); + p = installbreak(address, type, bound); + BreaksSet++ ; + state->CallDebug++ ; + *handle = (PointHandle)p; + TracePrint((state, " returns %.8lx\n", *handle)); + return RDIError_NoError; +} + +/***************************************************************************\ +* RDI_clearbreak * +\***************************************************************************/ + +static int RDI_clearbreak(PointHandle handle) +{ TracePrint((state, "RDI_clearbreak: address=%.8lx\n", handle)); + { BreakNode *p, **prevp = &BreakList; + for (; (p = *prevp) != NULL; prevp = &p->next) + if (p == (BreakNode *)handle) break; + if (p == NULL) return RDIError_NoSuchPoint; + deletebreaknode(prevp); + return RDIError_NoError; + } +} + +/***************************************************************************\ +* Internal functions for breakpoint table manipulation * +\***************************************************************************/ + +static void deletewatchnode(WatchNode **prevp) +{ WatchNode *p = *prevp; + if (p->datatype & Watch_AnyRead) state->MemReadDebug--; + if (p->datatype & Watch_AnyWrite) state->MemWriteDebug--; + *prevp = p->next; + free((char *)p); +} + +int removewatch(ARMword address, unsigned type) +{ WatchNode *p, **prevp = &WatchList; + for (; (p = *prevp) != NULL ; prevp = &p->next) + if (p->address == address && p->type == type) { /* found a match */ + deletewatchnode(prevp); + return TRUE; + } + return FALSE; /* never found a match */ +} + +static WatchNode *installwatch(ARMword address, unsigned type, unsigned datatype, + ARMword bound) +{ WatchNode *p = (WatchNode *)malloc(sizeof(WatchNode)); + p->next = WatchList; + WatchList = p; + p->address = address; + p->type = type; + p->datatype = datatype; + p->bound = bound; + return p; +} + +/***************************************************************************\ +* RDI_setwatch * +\***************************************************************************/ + +static int RDI_setwatch(ARMword address, unsigned type, unsigned datatype, + ARMword bound, PointHandle *handle) +{ WatchNode *p; + TracePrint((state, "RDI_setwatch: address=%.8lx type=%d datatype=%d bound=%.8lx", + address, type, datatype, bound)); + + if (!state->CanWatch) return RDIError_UnimplementedMessage; + + removewatch(address, type); + p = installwatch(address, type, datatype, bound); + if (datatype & Watch_AnyRead) state->MemReadDebug++; + if (datatype & Watch_AnyWrite) state->MemWriteDebug++; + *handle = (PointHandle)p; + TracePrint((state, " returns %.8lx\n", *handle)); + return RDIError_NoError; +} + +/***************************************************************************\ +* RDI_clearwatch * +\***************************************************************************/ + +static int RDI_clearwatch(PointHandle handle) +{ TracePrint((state, "RDI_clearwatch: address=%.8lx\n", handle)); + { WatchNode *p, **prevp = &WatchList; + for (; (p = *prevp) != NULL; prevp = &p->next) + if (p == (WatchNode *)handle) break; + if (p == NULL) return RDIError_NoSuchPoint; + deletewatchnode(prevp); + return RDIError_NoError; + } +} + +/***************************************************************************\ +* RDI_execute * +\***************************************************************************/ + +static int RDI_execute(PointHandle *handle) +{ + TracePrint((state, "RDI_execute\n")); + if (rdi_log & 4) { + state->CallDebug++ ; + state->Debug = TRUE ; + } + state->EndCondition = RDIError_NoError ; + state->StopHandle = 0; + + ARMul_DoProg(state); + + *handle = state->StopHandle; + state->Reg[15] -= 8 ; /* undo the pipeline */ + if (rdi_log & 4) { + state->CallDebug-- ; + state->Debug = FALSE ; + } + return(state->EndCondition) ; +} + +/***************************************************************************\ +* RDI_step * +\***************************************************************************/ + +static int RDI_step(unsigned ninstr, PointHandle *handle) +{ + + TracePrint((state, "RDI_step\n")); + if (ninstr != 1) return RDIError_UnimplementedMessage; + if (rdi_log & 4) { + state->CallDebug++ ; + state->Debug = TRUE ; + } + state->EndCondition = RDIError_NoError ; + state->StopHandle = 0; + ARMul_DoInstr(state) ; + *handle = state->StopHandle; + state->Reg[15] -= 8 ; /* undo the pipeline */ + if (rdi_log & 4) { + state->CallDebug-- ; + state->Debug = FALSE ; + } + return(state->EndCondition) ; +} + +/***************************************************************************\ +* RDI_info * +\***************************************************************************/ + +static int RDI_info(unsigned type, ARMword *arg1, ARMword *arg2) +{ + switch (type) { + case RDIInfo_Target: + TracePrint((state, "RDI_Info_Target\n")); + /* Emulator, speed 10**5 IPS */ + *arg1 = 5 | HIGHEST_RDI_LEVEL << 5 | LOWEST_RDI_LEVEL << 8; + *arg2 = 1298224434; + return RDIError_NoError; + + case RDIInfo_Points: + { ARMword n = RDIPointCapability_Comparison | RDIPointCapability_Range | + RDIPointCapability_Mask | RDIPointCapability_Status; + TracePrint((state, "RDI_Info_Points\n")); + if (state->CanWatch) n |= (Watch_AnyRead+Watch_AnyWrite) << 2; + *arg1 = n; + return RDIError_NoError; + } + + case RDIInfo_Step: + TracePrint((state, "RDI_Info_Step\n")); + *arg1 = RDIStep_Single; + return RDIError_NoError; + + case RDIInfo_MMU: + TracePrint((state, "RDI_Info_MMU\n")); + *arg1 = 1313820229 ; + return RDIError_NoError; + + case RDISignal_Stop: + TracePrint((state, "RDISignal_Stop\n")); + state->CallDebug++ ; + state->EndCondition = RDIError_UserInterrupt ; + return RDIError_NoError; + + case RDIVector_Catch: + TracePrint((state, "RDIVector_Catch %.8lx\n", *arg1)); + state->VectorCatch = (unsigned)*arg1 ; + return RDIError_NoError; + + case RDISet_Cmdline: + TracePrint((state, "RDI_Set_Cmdline %s\n", (char *)arg1)); + state->CommandLine = (char *)malloc((unsigned)strlen((char *)arg1)+1) ; + (void)strcpy(state->CommandLine,(char *)arg1) ; + return RDIError_NoError; + + case RDICycles: + TracePrint((state, "RDI_Info_Cycles\n")); + arg1[0] = 0; + arg1[1] = state->NumInstrs; + arg1[2] = 0; + arg1[3] = state->NumScycles; + arg1[4] = 0; + arg1[5] = state->NumNcycles; + arg1[6] = 0; + arg1[7] = state->NumIcycles; + arg1[8] = 0; + arg1[9] = state->NumCcycles; + arg1[10] = 0; + arg1[11] = state->NumFcycles; + return RDIError_NoError; + + case RDIErrorP: + *arg1 = ARMul_OSLastErrorP(state); + TracePrint((state, "RDI_ErrorP returns %ld\n", *arg1)); + return RDIError_NoError; + + case RDIInfo_DescribeCoPro: + { int cpnum = *(int *)arg1; + struct Dbg_CoProDesc *cpd = (struct Dbg_CoProDesc *)arg2; + int i; + unsigned char const *map = state->CPRegWords[cpnum]; + if (map == NULL) return RDIError_UnknownCoPro; + for (i = 0; i < cpd->entries; i++) { + unsigned r, w = cpd->regdesc[i].nbytes / sizeof(ARMword); + for (r = cpd->regdesc[i].rmin; r <= cpd->regdesc[i].rmax; r++) + if (map[r] != w) return RDIError_BadCoProState; + } + return RDIError_NoError; + } + + case RDIInfo_RequestCoProDesc: + { int cpnum = *(int *)arg1; + struct Dbg_CoProDesc *cpd = (struct Dbg_CoProDesc *)arg2; + int i = -1, lastw = -1, r; + unsigned char const *map; + if ((unsigned)cpnum >= 16) return RDIError_UnknownCoPro; + map = state->CPRegWords[cpnum]; + if (map == NULL) return RDIError_UnknownCoPro; + for (r = 0; r < map[-1]; r++) { + int words = map[r]; + if (words == lastw) + cpd->regdesc[i].rmax = r; + else { + if (++i >= cpd->entries) return RDIError_BufferFull; + cpd->regdesc[i].rmax = cpd->regdesc[i].rmin = r; + cpd->regdesc[i].nbytes = words * sizeof(ARMword); + cpd->regdesc[i].access = Dbg_Access_Readable+Dbg_Access_Writable; + } + } + cpd->entries = i+1; + return RDIError_NoError; + } + + case RDIInfo_Log: + *arg1 = (ARMword)rdi_log; + return RDIError_NoError; + + case RDIInfo_SetLog: + rdi_log = (int)*arg1; + return RDIError_NoError; + + case RDIInfo_CoPro: + return RDIError_NoError; + + case RDIPointStatus_Watch: + { WatchNode *p, *handle = (WatchNode *)*arg1; + for (p = WatchList; p != NULL; p = p->next) + if (p == handle) { + *arg1 = -1; + *arg2 = 1; + return RDIError_NoError; + } + return RDIError_NoSuchPoint; + } + + case RDIPointStatus_Break: + { BreakNode *p, *handle = (BreakNode *)*arg1; + for (p = BreakList; p != NULL; p = p->next) + if (p == handle) { + *arg1 = -1; + *arg2 = 1; + return RDIError_NoError; + } + return RDIError_NoSuchPoint; + } + + case RDISet_RDILevel: + if (*arg1 < LOWEST_RDI_LEVEL || *arg1 > HIGHEST_RDI_LEVEL) + return RDIError_IncompatibleRDILevels; + MYrdi_level = *arg1; + return RDIError_NoError; + + default: + return RDIError_UnimplementedMessage; + + } +} + +/***************************************************************************\ +* The emulator calls this routine at the beginning of every cycle when the * +* CallDebug flag is set. The second parameter passed is the address of the * +* currently executing instruction (i.e Program Counter - 8), the third * +* parameter is the instruction being executed. * +\***************************************************************************/ + +ARMword ARMul_Debug(ARMul_State *state, ARMword pc, ARMword instr) +{ + + if (state->EndCondition == RDIError_UserInterrupt) { + TracePrint((state, "User interrupt at %.8lx\n", pc)); + state->CallDebug--; + state->Emulate = STOP; + } else { + BreakNode *p = BreakList; + for (; p != NULL ; p = p->next) { + switch (p->type) { + case RDIPoint_EQ: if (pc == p->address) break; continue; + case RDIPoint_GT: if (pc > p->address) break; continue; + case RDIPoint_GE: if (pc >= p->address) break; continue; + case RDIPoint_LT: if (pc < p->address) break; continue; + case RDIPoint_LE: if (pc <= p->address) break; continue; + case RDIPoint_IN: if (p->address <= pc && pc < p->address+p->bound) break; + continue; + case RDIPoint_OUT:if (p->address > pc || pc >= p->address+p->bound) break; + continue; + case RDIPoint_MASK:if ((pc & p->bound) == p->address) break; continue; + } + /* found a match */ + TracePrint((state, "Breakpoint reached at %.8lx\n", pc)); + state->EndCondition = RDIError_BreakpointReached ; + state->Emulate = STOP; + state->StopHandle = (ARMword)p; + break; + } + } + return instr; +} + +void ARMul_CheckWatch(ARMul_State *state, ARMword addr, int access) +{ WatchNode *p; + for (p = WatchList; p != NULL; p = p->next) + if (p->datatype & access) { + switch (p->type) { + case RDIPoint_EQ: if (addr == p->address) break; continue; + case RDIPoint_GT: if (addr > p->address) break; continue; + case RDIPoint_GE: if (addr >= p->address) break; continue; + case RDIPoint_LT: if (addr < p->address) break; continue; + case RDIPoint_LE: if (addr <= p->address) break; continue; + case RDIPoint_IN: if (p->address <= addr && addr < p->address+p->bound) break; + continue; + case RDIPoint_OUT:if (p->address > addr || addr >= p->address+p->bound) break; + continue; + case RDIPoint_MASK:if ((addr & p->bound) == p->address) break; continue; + } + /* found a match */ + TracePrint((state, "Watchpoint at %.8lx accessed\n", addr)); + state->EndCondition = RDIError_WatchpointAccessed; + state->Emulate = STOP; + state->StopHandle = (ARMword)p; + return; + } +} + +static RDI_NameList const *RDI_cpunames() { + return (RDI_NameList const *)&processorconfig.count; +} + +const struct RDIProcVec armul_rdi = { + "ARMUL", + RDI_open, + RDI_close, + RDI_read, + RDI_write, + RDI_CPUread, + RDI_CPUwrite, + RDI_CPread, + RDI_CPwrite, + RDI_setbreak, + RDI_clearbreak, + RDI_setwatch, + RDI_clearwatch, + RDI_execute, + RDI_step, + RDI_info, + + 0, /*pointinq*/ + 0, /*addconfig*/ + 0, /*loadconfigdata*/ + 0, /*selectconfig*/ + 0, /*drivernames*/ + + RDI_cpunames +}; + diff --git a/sim/arm/armsupp.c b/sim/arm/armsupp.c new file mode 100644 index 0000000..67edd95 --- /dev/null +++ b/sim/arm/armsupp.c @@ -0,0 +1,712 @@ +/* armsupp.c -- ARMulator support code: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 "armdefs.h" +#include "armemu.h" + +/***************************************************************************\ +* Definitions for the support routines * +\***************************************************************************/ + +ARMword ARMul_GetReg(ARMul_State *state, unsigned mode, unsigned reg) ; +void ARMul_SetReg(ARMul_State *state, unsigned mode, unsigned reg, ARMword value) ; +ARMword ARMul_GetPC(ARMul_State *state) ; +ARMword ARMul_GetNextPC(ARMul_State *state) ; +void ARMul_SetPC(ARMul_State *state, ARMword value) ; +ARMword ARMul_GetR15(ARMul_State *state) ; +void ARMul_SetR15(ARMul_State *state, ARMword value) ; + +ARMword ARMul_GetCPSR(ARMul_State *state) ; +void ARMul_SetCPSR(ARMul_State *state, ARMword value) ; +void ARMul_FixCPSR(ARMul_State *state, ARMword instr, ARMword rhs) ; +ARMword ARMul_GetSPSR(ARMul_State *state, ARMword mode) ; +void ARMul_SetSPSR(ARMul_State *state, ARMword mode, ARMword value) ; +void ARMul_FixSPSR(ARMul_State *state, ARMword instr, ARMword rhs) ; + +void ARMul_CPSRAltered(ARMul_State *state) ; +void ARMul_R15Altered(ARMul_State *state) ; + +ARMword ARMul_SwitchMode(ARMul_State *state,ARMword oldmode, ARMword newmode) ; +static ARMword ModeToBank(ARMul_State *state,ARMword mode) ; + +unsigned ARMul_NthReg(ARMword instr, unsigned number) ; + +void ARMul_NegZero(ARMul_State *state, ARMword result) ; +void ARMul_AddCarry(ARMul_State *state, ARMword a, ARMword b, ARMword result) ; +void ARMul_AddOverflow(ARMul_State *state, ARMword a, ARMword b, ARMword result) ; +void ARMul_SubCarry(ARMul_State *state, ARMword a, ARMword b, ARMword result) ; +void ARMul_SubOverflow(ARMul_State *state, ARMword a, ARMword b, ARMword result) ; + +void ARMul_LDC(ARMul_State *state,ARMword instr,ARMword address) ; +void ARMul_STC(ARMul_State *state,ARMword instr,ARMword address) ; +void ARMul_MCR(ARMul_State *state,ARMword instr, ARMword source) ; +ARMword ARMul_MRC(ARMul_State *state,ARMword instr) ; +void ARMul_CDP(ARMul_State *state,ARMword instr) ; +void ARMul_UndefInstr(ARMul_State *state,ARMword instr) ; +unsigned IntPending(ARMul_State *state) ; + +ARMword ARMul_Align(ARMul_State *state, ARMword address, ARMword data) ; + +void ARMul_ScheduleEvent(ARMul_State *state, unsigned long delay, + unsigned (*what)()) ; +void ARMul_EnvokeEvent(ARMul_State *state) ; +unsigned long ARMul_Time(ARMul_State *state) ; +static void EnvokeList(ARMul_State *state, unsigned long from, unsigned long to) ; + +struct EventNode { /* An event list node */ + unsigned (*func)() ; /* The function to call */ + struct EventNode *next ; + } ; + +/***************************************************************************\ +* This routine returns the value of a register from a mode. * +\***************************************************************************/ + +ARMword ARMul_GetReg(ARMul_State *state, unsigned mode, unsigned reg) +{mode &= MODEBITS ; + if (mode != state->Mode) + return(state->RegBank[ModeToBank(state,(ARMword)mode)][reg]) ; + else + return(state->Reg[reg]) ; +} + +/***************************************************************************\ +* This routine sets the value of a register for a mode. * +\***************************************************************************/ + +void ARMul_SetReg(ARMul_State *state, unsigned mode, unsigned reg, ARMword value) +{mode &= MODEBITS ; + if (mode != state->Mode) + state->RegBank[ModeToBank(state,(ARMword)mode)][reg] = value ; + else + state->Reg[reg] = value ; +} + +/***************************************************************************\ +* This routine returns the value of the PC, mode independently. * +\***************************************************************************/ + +ARMword ARMul_GetPC(ARMul_State *state) +{if (state->Mode > SVC26MODE) + return(state->Reg[15]) ; + else + return(R15PC) ; +} + +/***************************************************************************\ +* This routine returns the value of the PC, mode independently. * +\***************************************************************************/ + +ARMword ARMul_GetNextPC(ARMul_State *state) +{if (state->Mode > SVC26MODE) + return(state->Reg[15] + isize) ; + else + return((state->Reg[15] + isize) & R15PCBITS) ; +} + +/***************************************************************************\ +* This routine sets the value of the PC. * +\***************************************************************************/ + +void ARMul_SetPC(ARMul_State *state, ARMword value) +{if (ARMul_MODE32BIT) + state->Reg[15] = value & PCBITS ; + else + state->Reg[15] = R15CCINTMODE | (value & R15PCBITS) ; + FLUSHPIPE ; +} + +/***************************************************************************\ +* This routine returns the value of register 15, mode independently. * +\***************************************************************************/ + +ARMword ARMul_GetR15(ARMul_State *state) +{if (state->Mode > SVC26MODE) + return(state->Reg[15]) ; + else + return(R15PC | ECC | ER15INT | EMODE) ; +} + +/***************************************************************************\ +* This routine sets the value of Register 15. * +\***************************************************************************/ + +void ARMul_SetR15(ARMul_State *state, ARMword value) +{ + if (ARMul_MODE32BIT) + state->Reg[15] = value & PCBITS ; + else { + state->Reg[15] = value ; + ARMul_R15Altered(state) ; + } + FLUSHPIPE ; +} + +/***************************************************************************\ +* This routine returns the value of the CPSR * +\***************************************************************************/ + +ARMword ARMul_GetCPSR(ARMul_State *state) +{ + return(CPSR) ; + } + +/***************************************************************************\ +* This routine sets the value of the CPSR * +\***************************************************************************/ + +void ARMul_SetCPSR(ARMul_State *state, ARMword value) +{state->Cpsr = CPSR ; + SETPSR(state->Cpsr,value) ; + ARMul_CPSRAltered(state) ; + } + +/***************************************************************************\ +* This routine does all the nasty bits involved in a write to the CPSR, * +* including updating the register bank, given a MSR instruction. * +\***************************************************************************/ + +void ARMul_FixCPSR(ARMul_State *state, ARMword instr, ARMword rhs) +{state->Cpsr = CPSR ; + if (state->Bank==USERBANK) { /* Only write flags in user mode */ + if (BIT(19)) { + SETCC(state->Cpsr,rhs) ; + } + } + else { /* Not a user mode */ + if (BITS(16,19)==9) SETPSR(state->Cpsr,rhs) ; + else if (BIT(16)) SETINTMODE(state->Cpsr,rhs) ; + else if (BIT(19)) SETCC(state->Cpsr,rhs) ; + } + ARMul_CPSRAltered(state) ; + } + +/***************************************************************************\ +* Get an SPSR from the specified mode * +\***************************************************************************/ + +ARMword ARMul_GetSPSR(ARMul_State *state, ARMword mode) +{ARMword bank = ModeToBank(state,mode & MODEBITS) ; + if (bank == USERBANK || bank == DUMMYBANK) + return(CPSR) ; + else + return(state->Spsr[bank]) ; +} + +/***************************************************************************\ +* This routine does a write to an SPSR * +\***************************************************************************/ + +void ARMul_SetSPSR(ARMul_State *state, ARMword mode, ARMword value) +{ARMword bank = ModeToBank(state,mode & MODEBITS) ; + if (bank != USERBANK && bank !=DUMMYBANK) + state->Spsr[bank] = value ; +} + +/***************************************************************************\ +* This routine does a write to the current SPSR, given an MSR instruction * +\***************************************************************************/ + +void ARMul_FixSPSR(ARMul_State *state, ARMword instr, ARMword rhs) +{if (state->Bank != USERBANK && state->Bank !=DUMMYBANK) { + if (BITS(16,19)==9) SETPSR(state->Spsr[state->Bank],rhs) ; + else if (BIT(16)) SETINTMODE(state->Spsr[state->Bank],rhs) ; + else if (BIT(19)) SETCC(state->Spsr[state->Bank],rhs) ; + } +} + +/***************************************************************************\ +* This routine updates the state of the emulator after the Cpsr has been * +* changed. Both the processor flags and register bank are updated. * +\***************************************************************************/ + +void ARMul_CPSRAltered(ARMul_State *state) +{ARMword oldmode ; + + if (state->prog32Sig == LOW) + state->Cpsr &= (CCBITS | INTBITS | R15MODEBITS) ; + oldmode = state->Mode ; + if (state->Mode != (state->Cpsr & MODEBITS)) { + state->Mode = ARMul_SwitchMode(state,state->Mode,state->Cpsr & MODEBITS) ; + state->NtransSig = (state->Mode & 3)?HIGH:LOW ; + } + + ASSIGNINT(state->Cpsr & INTBITS) ; + ASSIGNN((state->Cpsr & NBIT) != 0) ; + ASSIGNZ((state->Cpsr & ZBIT) != 0) ; + ASSIGNC((state->Cpsr & CBIT) != 0) ; + ASSIGNV((state->Cpsr & VBIT) != 0) ; +#ifdef MODET + ASSIGNT((state->Cpsr & TBIT) != 0); +#endif + + if (oldmode > SVC26MODE) { + if (state->Mode <= SVC26MODE) { + state->Emulate = CHANGEMODE ; + state->Reg[15] = ECC | ER15INT | EMODE | R15PC ; + } + } + else { + if (state->Mode > SVC26MODE) { + state->Emulate = CHANGEMODE ; + state->Reg[15] = R15PC ; + } + else + state->Reg[15] = ECC | ER15INT | EMODE | R15PC ; + } + +} + +/***************************************************************************\ +* This routine updates the state of the emulator after register 15 has * +* been changed. Both the processor flags and register bank are updated. * +* This routine should only be called from a 26 bit mode. * +\***************************************************************************/ + +void ARMul_R15Altered(ARMul_State *state) +{ + if (state->Mode != R15MODE) { + state->Mode = ARMul_SwitchMode(state,state->Mode,R15MODE) ; + state->NtransSig = (state->Mode & 3)?HIGH:LOW ; + } + if (state->Mode > SVC26MODE) + state->Emulate = CHANGEMODE ; + ASSIGNR15INT(R15INT) ; + ASSIGNN((state->Reg[15] & NBIT) != 0) ; + ASSIGNZ((state->Reg[15] & ZBIT) != 0) ; + ASSIGNC((state->Reg[15] & CBIT) != 0) ; + ASSIGNV((state->Reg[15] & VBIT) != 0) ; +} + +/***************************************************************************\ +* This routine controls the saving and restoring of registers across mode * +* changes. The regbank matrix is largely unused, only rows 13 and 14 are * +* used across all modes, 8 to 14 are used for FIQ, all others use the USER * +* column. It's easier this way. old and new parameter are modes numbers. * +* Notice the side effect of changing the Bank variable. * +\***************************************************************************/ + +ARMword ARMul_SwitchMode(ARMul_State *state,ARMword oldmode, ARMword newmode) +{unsigned i ; + + oldmode = ModeToBank(state,oldmode) ; + state->Bank = ModeToBank(state,newmode) ; + if (oldmode != state->Bank) { /* really need to do it */ + switch (oldmode) { /* save away the old registers */ + case USERBANK : + case IRQBANK : + case SVCBANK : + case ABORTBANK : + case UNDEFBANK : if (state->Bank == FIQBANK) + for (i = 8 ; i < 13 ; i++) + state->RegBank[USERBANK][i] = state->Reg[i] ; + state->RegBank[oldmode][13] = state->Reg[13] ; + state->RegBank[oldmode][14] = state->Reg[14] ; + break ; + case FIQBANK : for (i = 8 ; i < 15 ; i++) + state->RegBank[FIQBANK][i] = state->Reg[i] ; + break ; + case DUMMYBANK : for (i = 8 ; i < 15 ; i++) + state->RegBank[DUMMYBANK][i] = 0 ; + break ; + + } + switch (state->Bank) { /* restore the new registers */ + case USERBANK : + case IRQBANK : + case SVCBANK : + case ABORTBANK : + case UNDEFBANK : if (oldmode == FIQBANK) + for (i = 8 ; i < 13 ; i++) + state->Reg[i] = state->RegBank[USERBANK][i] ; + state->Reg[13] = state->RegBank[state->Bank][13] ; + state->Reg[14] = state->RegBank[state->Bank][14] ; + break ; + case FIQBANK : for (i = 8 ; i < 15 ; i++) + state->Reg[i] = state->RegBank[FIQBANK][i] ; + break ; + case DUMMYBANK : for (i = 8 ; i < 15 ; i++) + state->Reg[i] = 0 ; + break ; + } /* switch */ + } /* if */ + return(newmode) ; +} + +/***************************************************************************\ +* Given a processor mode, this routine returns the register bank that * +* will be accessed in that mode. * +\***************************************************************************/ + +static ARMword ModeToBank(ARMul_State *state, ARMword mode) +{static ARMword bankofmode[] = {USERBANK, FIQBANK, IRQBANK, SVCBANK, + DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK, + DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK, + DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK, + USERBANK, FIQBANK, IRQBANK, SVCBANK, + DUMMYBANK, DUMMYBANK, DUMMYBANK, ABORTBANK, + DUMMYBANK, DUMMYBANK, DUMMYBANK, UNDEFBANK + } ; + + if (mode > UNDEF32MODE) + return(DUMMYBANK) ; + else + return(bankofmode[mode]) ; + } + +/***************************************************************************\ +* Returns the register number of the nth register in a reg list. * +\***************************************************************************/ + +unsigned ARMul_NthReg(ARMword instr, unsigned number) +{unsigned bit, upto ; + + for (bit = 0, upto = 0 ; upto <= number ; bit++) + if (BIT(bit)) upto++ ; + return(bit - 1) ; +} + +/***************************************************************************\ +* Assigns the N and Z flags depending on the value of result * +\***************************************************************************/ + +void ARMul_NegZero(ARMul_State *state, ARMword result) +{ + if (NEG(result)) { SETN ; CLEARZ ; } + else if (result == 0) { CLEARN ; SETZ ; } + else { CLEARN ; CLEARZ ; } ; + } + +/***************************************************************************\ +* Assigns the C flag after an addition of a and b to give result * +\***************************************************************************/ + +void ARMul_AddCarry(ARMul_State *state, ARMword a,ARMword b,ARMword result) +{ + ASSIGNC( (NEG(a) && NEG(b)) || + (NEG(a) && POS(result)) || + (NEG(b) && POS(result)) ) ; + } + +/***************************************************************************\ +* Assigns the V flag after an addition of a and b to give result * +\***************************************************************************/ + +void ARMul_AddOverflow(ARMul_State *state, ARMword a,ARMword b,ARMword result) +{ + ASSIGNV( (NEG(a) && NEG(b) && POS(result)) || + (POS(a) && POS(b) && NEG(result)) ) ; + } + +/***************************************************************************\ +* Assigns the C flag after an subtraction of a and b to give result * +\***************************************************************************/ + +void ARMul_SubCarry(ARMul_State *state, ARMword a,ARMword b,ARMword result) +{ +ASSIGNC( (NEG(a) && POS(b)) || + (NEG(a) && POS(result)) || + (POS(b) && POS(result)) ) ; +} + +/***************************************************************************\ +* Assigns the V flag after an subtraction of a and b to give result * +\***************************************************************************/ + +void ARMul_SubOverflow(ARMul_State *state,ARMword a,ARMword b,ARMword result) +{ +ASSIGNV( (NEG(a) && POS(b) && POS(result)) || + (POS(a) && NEG(b) && NEG(result)) ) ; +} + +/***************************************************************************\ +* This function does the work of generating the addresses used in an * +* LDC instruction. The code here is always post-indexed, it's up to the * +* caller to get the input address correct and to handle base register * +* modification. It also handles the Busy-Waiting. * +\***************************************************************************/ + +void ARMul_LDC(ARMul_State *state,ARMword instr,ARMword address) +{unsigned cpab ; + ARMword data ; + + UNDEF_LSCPCBaseWb ; + if (ADDREXCEPT(address)) { + INTERNALABORT(address) ; + } + cpab = (state->LDC[CPNum])(state,ARMul_FIRST,instr,0) ; + while (cpab == ARMul_BUSY) { + ARMul_Icycles(state,1,0) ; + if (IntPending(state)) { + cpab = (state->LDC[CPNum])(state,ARMul_INTERRUPT,instr,0) ; + return ; + } + else + cpab = (state->LDC[CPNum])(state,ARMul_BUSY,instr,0) ; + } + if (cpab == ARMul_CANT) { + CPTAKEABORT ; + return ; + } + cpab = (state->LDC[CPNum])(state,ARMul_TRANSFER,instr,0) ; + data = ARMul_LoadWordN(state,address) ; + BUSUSEDINCPCN ; + if (BIT(21)) + LSBase = state->Base ; + cpab = (state->LDC[CPNum])(state,ARMul_DATA,instr,data) ; + while (cpab == ARMul_INC) { + address += 4 ; + data = ARMul_LoadWordN(state,address) ; + cpab = (state->LDC[CPNum])(state,ARMul_DATA,instr,data) ; + } + if (state->abortSig || state->Aborted) { + TAKEABORT ; + } + } + +/***************************************************************************\ +* This function does the work of generating the addresses used in an * +* STC instruction. The code here is always post-indexed, it's up to the * +* caller to get the input address correct and to handle base register * +* modification. It also handles the Busy-Waiting. * +\***************************************************************************/ + +void ARMul_STC(ARMul_State *state,ARMword instr,ARMword address) +{unsigned cpab ; + ARMword data ; + + UNDEF_LSCPCBaseWb ; + if (ADDREXCEPT(address) || VECTORACCESS(address)) { + INTERNALABORT(address) ; + } + cpab = (state->STC[CPNum])(state,ARMul_FIRST,instr,&data) ; + while (cpab == ARMul_BUSY) { + ARMul_Icycles(state,1,0) ; + if (IntPending(state)) { + cpab = (state->STC[CPNum])(state,ARMul_INTERRUPT,instr,0) ; + return ; + } + else + cpab = (state->STC[CPNum])(state,ARMul_BUSY,instr,&data) ; + } + if (cpab == ARMul_CANT) { + CPTAKEABORT ; + return ; + } +#ifndef MODE32 + if (ADDREXCEPT(address) || VECTORACCESS(address)) { + INTERNALABORT(address) ; + } +#endif + BUSUSEDINCPCN ; + if (BIT(21)) + LSBase = state->Base ; + cpab = (state->STC[CPNum])(state,ARMul_DATA,instr,&data) ; + ARMul_StoreWordN(state,address,data) ; + while (cpab == ARMul_INC) { + address += 4 ; + cpab = (state->STC[CPNum])(state,ARMul_DATA,instr,&data) ; + ARMul_StoreWordN(state,address,data) ; + } + if (state->abortSig || state->Aborted) { + TAKEABORT ; + } + } + +/***************************************************************************\ +* This function does the Busy-Waiting for an MCR instruction. * +\***************************************************************************/ + +void ARMul_MCR(ARMul_State *state,ARMword instr, ARMword source) +{unsigned cpab ; + + cpab = (state->MCR[CPNum])(state,ARMul_FIRST,instr,source) ; + while (cpab == ARMul_BUSY) { + ARMul_Icycles(state,1,0) ; + if (IntPending(state)) { + cpab = (state->MCR[CPNum])(state,ARMul_INTERRUPT,instr,0) ; + return ; + } + else + cpab = (state->MCR[CPNum])(state,ARMul_BUSY,instr,source) ; + } + if (cpab == ARMul_CANT) + ARMul_Abort(state,ARMul_UndefinedInstrV) ; + else { + BUSUSEDINCPCN ; + ARMul_Ccycles(state,1,0) ; + } + } + +/***************************************************************************\ +* This function does the Busy-Waiting for an MRC instruction. * +\***************************************************************************/ + +ARMword ARMul_MRC(ARMul_State *state,ARMword instr) +{unsigned cpab ; + ARMword result = 0 ; + + cpab = (state->MRC[CPNum])(state,ARMul_FIRST,instr,&result) ; + while (cpab == ARMul_BUSY) { + ARMul_Icycles(state,1,0) ; + if (IntPending(state)) { + cpab = (state->MRC[CPNum])(state,ARMul_INTERRUPT,instr,0) ; + return(0) ; + } + else + cpab = (state->MRC[CPNum])(state,ARMul_BUSY,instr,&result) ; + } + if (cpab == ARMul_CANT) { + ARMul_Abort(state,ARMul_UndefinedInstrV) ; + result = ECC ; /* Parent will destroy the flags otherwise */ + } + else { + BUSUSEDINCPCN ; + ARMul_Ccycles(state,1,0) ; + ARMul_Icycles(state,1,0) ; + } + return(result) ; +} + +/***************************************************************************\ +* This function does the Busy-Waiting for an CDP instruction. * +\***************************************************************************/ + +void ARMul_CDP(ARMul_State *state,ARMword instr) +{unsigned cpab ; + + cpab = (state->CDP[CPNum])(state,ARMul_FIRST,instr) ; + while (cpab == ARMul_BUSY) { + ARMul_Icycles(state,1,0) ; + if (IntPending(state)) { + cpab = (state->CDP[CPNum])(state,ARMul_INTERRUPT,instr) ; + return ; + } + else + cpab = (state->CDP[CPNum])(state,ARMul_BUSY,instr) ; + } + if (cpab == ARMul_CANT) + ARMul_Abort(state,ARMul_UndefinedInstrV) ; + else + BUSUSEDN ; +} + +/***************************************************************************\ +* This function handles Undefined instructions, as CP isntruction * +\***************************************************************************/ + +void ARMul_UndefInstr(ARMul_State *state,ARMword instr) +{ + ARMul_Abort(state,ARMul_UndefinedInstrV) ; +} + +/***************************************************************************\ +* Return TRUE if an interrupt is pending, FALSE otherwise. * +\***************************************************************************/ + +unsigned IntPending(ARMul_State *state) +{ + if (state->Exception) { /* Any exceptions */ + if (state->NresetSig == LOW) { + ARMul_Abort(state,ARMul_ResetV) ; + return(TRUE) ; + } + else if (!state->NfiqSig && !FFLAG) { + ARMul_Abort(state,ARMul_FIQV) ; + return(TRUE) ; + } + else if (!state->NirqSig && !IFLAG) { + ARMul_Abort(state,ARMul_IRQV) ; + return(TRUE) ; + } + } + return(FALSE) ; + } + +/***************************************************************************\ +* Align a word access to a non word boundary * +\***************************************************************************/ + +ARMword ARMul_Align(ARMul_State *state, ARMword address, ARMword data) +{/* this code assumes the address is really unaligned, + as a shift by 32 is undefined in C */ + + address = (address & 3) << 3 ; /* get the word address */ + return( ( data >> address) | (data << (32 - address)) ) ; /* rot right */ +} + +/***************************************************************************\ +* This routine is used to call another routine after a certain number of * +* cycles have been executed. The first parameter is the number of cycles * +* delay before the function is called, the second argument is a pointer * +* to the function. A delay of zero doesn't work, just call the function. * +\***************************************************************************/ + +void ARMul_ScheduleEvent(ARMul_State *state, unsigned long delay, unsigned (*what)()) +{unsigned long when ; + struct EventNode *event ; + + if (state->EventSet++ == 0) + state->Now = ARMul_Time(state) ; + when = (state->Now + delay) % EVENTLISTSIZE ; + event = (struct EventNode *)malloc(sizeof(struct EventNode)) ; + event->func = what ; + event->next = *(state->EventPtr + when) ; + *(state->EventPtr + when) = event ; +} + +/***************************************************************************\ +* This routine is called at the beginning of every cycle, to envoke * +* scheduled events. * +\***************************************************************************/ + +void ARMul_EnvokeEvent(ARMul_State *state) +{static unsigned long then ; + + then = state->Now ; + state->Now = ARMul_Time(state) % EVENTLISTSIZE ; + if (then < state->Now) /* schedule events */ + EnvokeList(state,then,state->Now) ; + else if (then > state->Now) { /* need to wrap around the list */ + EnvokeList(state,then,EVENTLISTSIZE-1L) ; + EnvokeList(state,0L,state->Now) ; + } + } + +static void EnvokeList(ARMul_State *state, unsigned long from, unsigned long to) +/* envokes all the entries in a range */ +{struct EventNode *anevent ; + + for (; from <= to ; from++) { + anevent = *(state->EventPtr + from) ; + while (anevent) { + (anevent->func)(state) ; + state->EventSet-- ; + anevent = anevent->next ; + } + *(state->EventPtr + from) = NULL ; + } + } + +/***************************************************************************\ +* This routine is returns the number of clock ticks since the last reset. * +\***************************************************************************/ + +unsigned long ARMul_Time(ARMul_State *state) +{return(state->NumScycles + state->NumNcycles + + state->NumIcycles + state->NumCcycles + state->NumFcycles) ; +} diff --git a/sim/arm/armvirt.c b/sim/arm/armvirt.c new file mode 100644 index 0000000..57ebedf --- /dev/null +++ b/sim/arm/armvirt.c @@ -0,0 +1,491 @@ +/* armvirt.c -- ARMulator virtual memory interace: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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. */ + +/* This file contains a complete ARMulator memory model, modelling a +"virtual memory" system. A much simpler model can be found in armfast.c, +and that model goes faster too, but has a fixed amount of memory. This +model's memory has 64K pages, allocated on demand from a 64K entry page +table. The routines PutWord and GetWord implement this. Pages are never +freed as they might be needed again. A single area of memory may be +defined to generate aborts. */ + +#include "armopts.h" +#include "armdefs.h" + +#ifdef VALIDATE /* for running the validate suite */ +#define TUBE 48 * 1024 * 1024 /* write a char on the screen */ +#define ABORTS 1 +#endif + +#define ABORTS + +#ifdef ABORTS /* the memory system will abort */ +/* For the old test suite Abort between 32 Kbytes and 32 Mbytes + For the new test suite Abort between 8 Mbytes and 26 Mbytes */ +/* #define LOWABORT 32 * 1024 +#define HIGHABORT 32 * 1024 * 1024 */ +#define LOWABORT 8 * 1024 * 1024 +#define HIGHABORT 26 * 1024 * 1024 + +#endif + +#define NUMPAGES 64 * 1024 +#define PAGESIZE 64 * 1024 +#define PAGEBITS 16 +#define OFFSETBITS 0xffff + +/***************************************************************************\ +* Get a Word from Virtual Memory, maybe allocating the page * +\***************************************************************************/ + +static ARMword +GetWord (ARMul_State * state, ARMword address) +{ + ARMword page; + ARMword offset; + ARMword ** pagetable; + ARMword * pageptr; + + page = address >> PAGEBITS; + offset = (address & OFFSETBITS) >> 2; + pagetable = (ARMword **) state->MemDataPtr; + pageptr = *(pagetable + page); + + if (pageptr == NULL) + { + pageptr = (ARMword *) malloc (PAGESIZE); + + if (pageptr == NULL) + { + perror ("ARMulator can't allocate VM page"); + exit (12); + } + + *(pagetable + page) = pageptr; + } + + return *(pageptr + offset); +} + +/***************************************************************************\ +* Put a Word into Virtual Memory, maybe allocating the page * +\***************************************************************************/ + +static void +PutWord (ARMul_State * state, ARMword address, ARMword data) +{ + ARMword page; + ARMword offset; + ARMword ** pagetable; + ARMword * pageptr; + + page = address >> PAGEBITS; + offset = (address & OFFSETBITS) >> 2; + pagetable = (ARMword **)state->MemDataPtr; + pageptr = *(pagetable + page); + + if (pageptr == NULL) + { + pageptr = (ARMword *) malloc (PAGESIZE); + if (pageptr == NULL) + { + perror ("ARMulator can't allocate VM page"); + exit(13); + } + + *(pagetable + page) = pageptr; + } + + *(pageptr + offset) = data; +} + +/***************************************************************************\ +* Initialise the memory interface * +\***************************************************************************/ + +unsigned +ARMul_MemoryInit (ARMul_State * state, unsigned long initmemsize) +{ + ARMword ** pagetable; + unsigned page; + + if (initmemsize) + state->MemSize = initmemsize; + + pagetable = (ARMword **) malloc (sizeof (ARMword) * NUMPAGES); + + if (pagetable == NULL) + return FALSE; + + for (page = 0 ; page < NUMPAGES ; page++) + *(pagetable + page) = NULL; + + state->MemDataPtr = (unsigned char *)pagetable; + + ARMul_ConsolePrint (state, ", 4 Gb memory"); + + return TRUE; +} + +/***************************************************************************\ +* Remove the memory interface * +\***************************************************************************/ + +void +ARMul_MemoryExit (ARMul_State * state) +{ + ARMword page; + ARMword ** pagetable; + ARMword * pageptr; + + pagetable = (ARMword **)state->MemDataPtr; + for (page = 0 ; page < NUMPAGES ; page++) + { + pageptr = *(pagetable + page); + if (pageptr != NULL) + free ((char *)pageptr); + } + free ((char *)pagetable); + return; +} + +/***************************************************************************\ +* ReLoad Instruction * +\***************************************************************************/ + +ARMword +ARMul_ReLoadInstr (ARMul_State * state, ARMword address, ARMword isize) +{ +#ifdef ABORTS + if (address >= LOWABORT && address < HIGHABORT) + { + ARMul_PREFETCHABORT (address); + return ARMul_ABORTWORD; + } + else + { + ARMul_CLEARABORT; + } +#endif + + if ((isize == 2) && (address & 0x2)) + { + /* We return the next two halfwords: */ + ARMword lo = GetWord (state, address); + ARMword hi = GetWord (state, address + 4); + + if (state->bigendSig == HIGH) + return (lo << 16) | (hi >> 16); + else + return ((hi & 0xFFFF) << 16) | (lo >> 16); + } + + return GetWord (state, address); +} + +/***************************************************************************\ +* Load Instruction, Sequential Cycle * +\***************************************************************************/ + +ARMword +ARMul_LoadInstrS (ARMul_State * state, ARMword address, ARMword isize) +{ + state->NumScycles ++; + +#ifdef HOURGLASS + if (( state->NumScycles & HOURGLASS_RATE ) == 0) + { + HOURGLASS; + } +#endif + + return ARMul_ReLoadInstr (state, address, isize); +} + +/***************************************************************************\ +* Load Instruction, Non Sequential Cycle * +\***************************************************************************/ + +ARMword +ARMul_LoadInstrN (ARMul_State * state, ARMword address, ARMword isize) +{ + state->NumNcycles ++; + + return ARMul_ReLoadInstr (state, address, isize); +} + +/***************************************************************************\ +* Read Word (but don't tell anyone!) * +\***************************************************************************/ + +ARMword +ARMul_ReadWord (ARMul_State * state, ARMword address) +{ +#ifdef ABORTS + if (address >= LOWABORT && address < HIGHABORT) + { + ARMul_DATAABORT (address); + return ARMul_ABORTWORD; + } + else + { + ARMul_CLEARABORT; + } +#endif + + return GetWord (state, address); +} + +/***************************************************************************\ +* Load Word, Sequential Cycle * +\***************************************************************************/ + +ARMword +ARMul_LoadWordS (ARMul_State * state, ARMword address) +{ + state->NumScycles ++; + + return ARMul_ReadWord (state, address); +} + +/***************************************************************************\ +* Load Word, Non Sequential Cycle * +\***************************************************************************/ + +ARMword +ARMul_LoadWordN (ARMul_State * state, ARMword address) +{ + state->NumNcycles ++; + + return ARMul_ReadWord (state, address); +} + +/***************************************************************************\ +* Load Halfword, (Non Sequential Cycle) * +\***************************************************************************/ + +ARMword +ARMul_LoadHalfWord (ARMul_State * state, ARMword address) +{ + ARMword temp, offset; + + state->NumNcycles ++; + + temp = ARMul_ReadWord (state, address); + offset = (((ARMword)state->bigendSig * 2) ^ (address & 2)) << 3; /* bit offset into the word */ + + return (temp >> offset) & 0xffff; +} + +/***************************************************************************\ +* Read Byte (but don't tell anyone!) * +\***************************************************************************/ + +ARMword +ARMul_ReadByte (ARMul_State * state, ARMword address) +{ + ARMword temp, offset; + + temp = ARMul_ReadWord (state, address); + offset = (((ARMword)state->bigendSig * 3) ^ (address & 3)) << 3; /* bit offset into the word */ + + return (temp >> offset & 0xffL); +} + +/***************************************************************************\ +* Load Byte, (Non Sequential Cycle) * +\***************************************************************************/ + +ARMword +ARMul_LoadByte (ARMul_State * state, ARMword address) +{ + state->NumNcycles ++; + + return ARMul_ReadByte (state, address); +} + +/***************************************************************************\ +* Write Word (but don't tell anyone!) * +\***************************************************************************/ + +void +ARMul_WriteWord (ARMul_State * state, ARMword address, ARMword data) +{ +#ifdef ABORTS + if (address >= LOWABORT && address < HIGHABORT) + { + ARMul_DATAABORT (address); + return; + } + else + { + ARMul_CLEARABORT; + } +#endif + + PutWord (state, address, data); +} + +/***************************************************************************\ +* Store Word, Sequential Cycle * +\***************************************************************************/ + +void +ARMul_StoreWordS (ARMul_State * state, ARMword address, ARMword data) +{ + state->NumScycles ++; + + ARMul_WriteWord (state, address, data); +} + +/***************************************************************************\ +* Store Word, Non Sequential Cycle * +\***************************************************************************/ + +void +ARMul_StoreWordN (ARMul_State * state, ARMword address, ARMword data) +{ + state->NumNcycles ++; + + ARMul_WriteWord (state, address, data); +} + +/***************************************************************************\ +* Store HalfWord, (Non Sequential Cycle) * +\***************************************************************************/ + +void +ARMul_StoreHalfWord (ARMul_State * state, ARMword address, ARMword data) +{ + ARMword temp, offset; + + state->NumNcycles ++; + +#ifdef VALIDATE + if (address == TUBE) + { + if (data == 4) + state->Emulate = FALSE; + else + (void) putc ((char)data, stderr); /* Write Char */ + return; + } +#endif + + temp = ARMul_ReadWord (state, address); + offset = (((ARMword)state->bigendSig * 2) ^ (address & 2)) << 3; /* bit offset into the word */ + + PutWord (state, address, (temp & ~(0xffffL << offset)) | ((data & 0xffffL) << offset)); +} + +/***************************************************************************\ +* Write Byte (but don't tell anyone!) * +\***************************************************************************/ + +void +ARMul_WriteByte (ARMul_State * state, ARMword address, ARMword data) +{ + ARMword temp, offset; + + temp = ARMul_ReadWord (state, address); + offset = (((ARMword)state->bigendSig * 3) ^ (address & 3)) << 3; /* bit offset into the word */ + + PutWord (state, address, (temp & ~(0xffL << offset)) | ((data & 0xffL) << offset)); +} + +/***************************************************************************\ +* Store Byte, (Non Sequential Cycle) * +\***************************************************************************/ + +void +ARMul_StoreByte (ARMul_State * state, ARMword address, ARMword data) +{ + state->NumNcycles ++; + +#ifdef VALIDATE + if (address == TUBE) + { + if (data == 4) + state->Emulate = FALSE; + else + (void) putc ((char)data,stderr); /* Write Char */ + return; + } +#endif + + ARMul_WriteByte (state, address, data); +} + +/***************************************************************************\ +* Swap Word, (Two Non Sequential Cycles) * +\***************************************************************************/ + +ARMword +ARMul_SwapWord (ARMul_State * state, ARMword address, ARMword data) +{ + ARMword temp; + + state->NumNcycles ++; + + temp = ARMul_ReadWord (state, address); + + state->NumNcycles ++; + + PutWord (state, address, data); + + return temp; +} + +/***************************************************************************\ +* Swap Byte, (Two Non Sequential Cycles) * +\***************************************************************************/ + +ARMword +ARMul_SwapByte (ARMul_State * state, ARMword address, ARMword data) +{ + ARMword temp; + + temp = ARMul_LoadByte (state, address); + ARMul_StoreByte (state, address, data); + + return temp; +} + +/***************************************************************************\ +* Count I Cycles * +\***************************************************************************/ + +void +ARMul_Icycles (ARMul_State * state, unsigned number, ARMword address) +{ + state->NumIcycles += number; + ARMul_CLEARABORT; +} + +/***************************************************************************\ +* Count C Cycles * +\***************************************************************************/ + +void +ARMul_Ccycles (ARMul_State * state, unsigned number, ARMword address) +{ + state->NumCcycles += number; + ARMul_CLEARABORT; +} + + + diff --git a/sim/arm/bag.c b/sim/arm/bag.c new file mode 100644 index 0000000..f4b9661 --- /dev/null +++ b/sim/arm/bag.c @@ -0,0 +1,141 @@ +/* bag.c -- ARMulator support code: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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. */ + +/********************************************************************/ +/* bag.c: */ +/* Offers a data structure for storing and getting pairs of number. */ +/* The numbers are stored together, put one can be looked up by */ +/* quoting the other. If a new pair is entered and one of the */ +/* numbers is a repeat of a previous pair, then the previos pair */ +/* is deleted. */ +/********************************************************************/ + +#include "bag.h" + +#define HASH_TABLE_SIZE 256 +#define hash(x) (((x)&0xff)^(((x)>>8)&0xff)^(((x)>>16)&0xff)^(((x)>>24)&0xff)) + +typedef struct hashentry { + struct hashentry *next; + int first; + int second; +} Hashentry; + +Hashentry *lookupbyfirst[HASH_TABLE_SIZE]; +Hashentry *lookupbysecond[HASH_TABLE_SIZE]; + +void addtolist(Hashentry **add, long first, long second) { + while (*add) add = &((*add)->next); + /* Malloc will never fail? :o( */ + (*add) = (Hashentry *) malloc(sizeof(Hashentry)); + (*add)->next = (Hashentry *) 0; + (*add)->first = first; + (*add)->second = second; +} + +void killwholelist(Hashentry *p) { + Hashentry *q; + + while (p) { + q = p; + p = p->next; + free(q); + } +} + +void removefromlist(Hashentry **p, long first, long second) { + Hashentry *q; + + while (*p) { + if ((*p)->first == first) { + q = (*p)->next; + free(*p); + *p = q; + return; + } + p = &((*p)->next); + } +} + +void BAG_putpair(long first, long second) { + long junk; + + if (BAG_getfirst(&junk, second) != NO_SUCH_PAIR) + BAG_killpair_bysecond(second); + addtolist(&lookupbyfirst[hash(first)], first, second); + addtolist(&lookupbysecond[hash(second)], first, second); +} + +Bag_error BAG_getfirst(long *first, long second) { + Hashentry *look; + + look = lookupbysecond[hash(second)]; + while(look) if (look->second == second) { + *first = look->first; + return NO_ERROR; + } + return NO_SUCH_PAIR; +} + +Bag_error BAG_getsecond(long first, long *second) { + Hashentry *look; + + look = lookupbyfirst[hash(first)]; + while(look) { + if (look->first == first) { + *second = look->second; + return NO_ERROR; + } + look = look->next; + } + return NO_SUCH_PAIR; +} + +Bag_error BAG_killpair_byfirst(long first) { + long second; + + if (BAG_getsecond(first, &second) == NO_SUCH_PAIR) + return NO_SUCH_PAIR; + removefromlist(&lookupbyfirst[hash(first)], first, second); + removefromlist(&lookupbysecond[hash(second)], first, second); + return NO_ERROR; +} + +Bag_error BAG_killpair_bysecond(long second) { + long first; + + if (BAG_getfirst(&first, second) == NO_SUCH_PAIR) + return NO_SUCH_PAIR; + removefromlist(&lookupbyfirst[hash(first)], first, second); + removefromlist(&lookupbysecond[hash(second)], first, second); + return NO_ERROR; +} + +void BAG_newbag() { + int i; + + for (i = 0; i < 256; i++) { + killwholelist(lookupbyfirst[i]); + killwholelist(lookupbysecond[i]); + lookupbyfirst[i] = lookupbysecond[i] = (Hashentry *) 0; + } +} + + + + + diff --git a/sim/arm/bag.h b/sim/arm/bag.h new file mode 100644 index 0000000..8914e96 --- /dev/null +++ b/sim/arm/bag.h @@ -0,0 +1,42 @@ +/* bag.h -- ARMulator support code: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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. */ + +/********************************************************************/ +/* bag.h: */ +/* Header file for bag.c */ +/* Offers a data structure for storing and getting pairs of number. */ +/* The numbers are stored together, put one can be looked up by */ +/* quoting the other. If a new pair is entered and one of the */ +/* numbers is a repeat of a previous pair, then the previos pair */ +/* is deleted. */ +/********************************************************************/ + +typedef enum { + NO_ERROR, + DELETED_OLD_PAIR, + NO_SUCH_PAIR, +} Bag_error; + +void BAG_putpair(long first, long second); + +void BAG_newbag(void); +Bag_error BAG_killpair_byfirst(long first); +Bag_error BAG_killpair_bysecond(long second); + +Bag_error BAG_getfirst(long *first, long second); +Bag_error BAG_getsecond(long first, long *second); + diff --git a/sim/arm/communicate.c b/sim/arm/communicate.c new file mode 100644 index 0000000..55ee2f3 --- /dev/null +++ b/sim/arm/communicate.c @@ -0,0 +1,221 @@ +/* communicate.c -- ARMulator RDP comms code: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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. */ + +/**************************************************************************/ +/* Functions to read and write characters or groups of characters */ +/* down sockets or pipes. Those that return a value return -1 on failure */ +/* and 0 on success. */ +/**************************************************************************/ + +#include <sys/time.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> + +#include "armdefs.h" + +/* The socket to the debugger */ +int debugsock; + +/* The maximum number of file descriptors */ +extern int nfds; + +/* The socket handle */ +extern int sockethandle; + +/* Read and Write routines down a pipe or socket */ + +/****************************************************************/ +/* Read an individual character. */ +/* All other read functions rely on this one. */ +/* It waits 15 seconds until there is a character available: if */ +/* no character is available, then it timeouts and returns -1. */ +/****************************************************************/ +int MYread_char(int sock, unsigned char *c) { + int i; + fd_set readfds; + struct timeval timeout= {15, 0}; + struct sockaddr_in isa; + + retry: + + FD_ZERO(&readfds); + FD_SET(sock, &readfds); + + i = select(nfds, &readfds, + (fd_set *) 0, + (fd_set *) 0, + &timeout); + + if (i < 0) { + perror("select"); + exit(1); + } + + if (!i) { + fprintf(stderr, "read: Timeout\n"); + return -1; + } + + if ((i = read(sock, c, 1)) < 1) { + if (!i && sock == debugsock) { + fprintf(stderr, "Connection with debugger severed.\n"); + /* This shouldn't be necessary for a detached armulator, but + the armulator cannot be cold started a second time, so + this is probably preferable to locking up. */ + return -1; + fprintf(stderr, "Waiting for connection from debugger..."); + debugsock = accept(sockethandle, &isa, &i); + if (debugsock < 0) { /* Now we are in serious trouble... */ + perror("accept"); + return -1; + } + fprintf(stderr, " done.\nConnection Established.\n"); + sock = debugsock; + goto retry; + } + perror("read"); + return -1; + } + +#ifdef DEBUG + if (sock == debugsock) fprintf(stderr, "<%02x ", *c); +#endif + + return 0; +} + +/****************************************************************/ +/* Read an individual character. */ +/* It waits until there is a character available. Returns -1 if */ +/* an error occurs. */ +/****************************************************************/ +int MYread_charwait(int sock, unsigned char *c) { + int i; + fd_set readfds; + struct sockaddr_in isa; + + retry: + + FD_ZERO(&readfds); + FD_SET(sock, &readfds); + + i = select(nfds, &readfds, + (fd_set *) 0, + (fd_set *) 0, + (struct timeval *) 0); + + if (i < 0) { + perror("select"); + exit(-1); + } + + if ((i = read(sock, c, 1)) < 1) { + if (!i && sock == debugsock) { + fprintf(stderr, "Connection with debugger severed.\n"); + return -1; + fprintf(stderr, "Waiting for connection from debugger..."); + debugsock = accept(sockethandle, &isa, &i); + if (debugsock < 0) { /* Now we are in serious trouble... */ + perror("accept"); + return -1; + } + fprintf(stderr, " done.\nConnection Established.\n"); + sock = debugsock; + goto retry; + } + perror("read"); + return -1; + } + +#ifdef DEBUG + if (sock == debugsock) fprintf(stderr, "<%02x ", *c); +#endif + + return 0; +} + +void MYwrite_char(int sock, unsigned char c) { + + if (write(sock, &c, 1) < 1) + perror("write"); +#ifdef DEBUG + if (sock == debugsock) fprintf(stderr, ">%02x ", c); +#endif +} + +int MYread_word(int sock, ARMword *here) { + unsigned char a, b, c, d; + + if (MYread_char(sock, &a) < 0) return -1; + if (MYread_char(sock, &b) < 0) return -1; + if (MYread_char(sock, &c) < 0) return -1; + if (MYread_char(sock, &d) < 0) return -1; + *here = a | b << 8 | c << 16 | d << 24; + return 0; +} + +void MYwrite_word(int sock, ARMword i) { + MYwrite_char(sock, i & 0xff); + MYwrite_char(sock, (i & 0xff00) >> 8); + MYwrite_char(sock, (i & 0xff0000) >> 16); + MYwrite_char(sock, (i & 0xff000000) >> 24); +} + +void MYwrite_string(int sock, char *s) { + int i; + for (i = 0; MYwrite_char(sock, s[i]), s[i]; i++); +} + +int MYread_FPword(int sock, char *putinhere) { + int i; + for (i = 0; i < 16; i++) + if (MYread_char(sock, &putinhere[i]) < 0) return -1; + return 0; +} + +void MYwrite_FPword(int sock, char *fromhere) { + int i; + for (i = 0; i < 16; i++) + MYwrite_char(sock, fromhere[i]); +} + +/* Takes n bytes from source and those n bytes */ +/* down to dest */ +int passon(int source, int dest, int n) { + char *p; + int i; + + p = (char *) malloc(n); + if (!p) { + perror("Out of memory\n"); + exit(1); + } + if (n) { + for (i = 0; i < n; i++) + if (MYread_char(source, &p[i]) < 0) return -1; + +#ifdef DEBUG + if (dest == debugsock) + for (i = 0; i < n; i++) fprintf(stderr, ")%02x ", (unsigned char) p[i]); +#endif + + write(dest, p, n); + } + free(p); + return 0; +} diff --git a/sim/arm/communicate.h b/sim/arm/communicate.h new file mode 100644 index 0000000..0630fe4 --- /dev/null +++ b/sim/arm/communicate.h @@ -0,0 +1,37 @@ +/* communicate.h -- ARMulator comms support defns: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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. */ + +int MYread_char(int sock, unsigned char *c); +void MYwrite_char(int sock, unsigned char c); +int MYread_word(int sock, ARMword *here); +void MYwrite_word(int sock, ARMword i); +void MYwrite_string(int sock, char *s); +int MYread_FPword(int sock, char *putinhere); +void MYwrite_FPword(int sock, char *fromhere); +int passon(int source, int dest, int n); + +int wait_for_osreply(ARMword *reply); /* from kid.c */ + +#define OS_SendNothing 0x0 +#define OS_SendChar 0x1 +#define OS_SendWord 0x2 +#define OS_SendString 0x3 + +/* The pipes between the two processes */ +extern int mumkid[2]; +extern int kidmum[2]; + diff --git a/sim/arm/config.in b/sim/arm/config.in new file mode 100644 index 0000000..1f87a2b --- /dev/null +++ b/sim/arm/config.in @@ -0,0 +1,158 @@ +/* config.in. Generated automatically from configure.in by autoheader. */ + +/* Define if using alloca.c. */ +#undef C_ALLOCA + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. + This function is required for alloca.c support on those systems. */ +#undef CRAY_STACKSEG_END + +/* Define if you have alloca, as a function or macro. */ +#undef HAVE_ALLOCA + +/* Define if you have <alloca.h> and it should be used (not on Ultrix). */ +#undef HAVE_ALLOCA_H + +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define as __inline if that's what the C compiler calls it. */ +#undef inline + +/* Define to `long' if <sys/types.h> doesn't define. */ +#undef off_t + +/* Define if you need to in order for stat and other things to work. */ +#undef _POSIX_SOURCE + +/* Define as the return type of signal handlers (int or void). */ +#undef RETSIGTYPE + +/* Define to `unsigned' if <sys/types.h> doesn't define. */ +#undef size_t + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown + */ +#undef STACK_DIRECTION + +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if NLS is requested. */ +#undef ENABLE_NLS + +/* Define as 1 if you have gettext and don't want to use GNU gettext. */ +#undef HAVE_GETTEXT + +/* Define as 1 if you have the stpcpy function. */ +#undef HAVE_STPCPY + +/* Define if your locale.h file contains LC_MESSAGES. */ +#undef HAVE_LC_MESSAGES + +/* Define if you have the __argz_count function. */ +#undef HAVE___ARGZ_COUNT + +/* Define if you have the __argz_next function. */ +#undef HAVE___ARGZ_NEXT + +/* Define if you have the __argz_stringify function. */ +#undef HAVE___ARGZ_STRINGIFY + +/* Define if you have the __setfpucw function. */ +#undef HAVE___SETFPUCW + +/* Define if you have the dcgettext function. */ +#undef HAVE_DCGETTEXT + +/* Define if you have the getcwd function. */ +#undef HAVE_GETCWD + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have the getrusage function. */ +#undef HAVE_GETRUSAGE + +/* Define if you have the munmap function. */ +#undef HAVE_MUNMAP + +/* Define if you have the putenv function. */ +#undef HAVE_PUTENV + +/* Define if you have the setenv function. */ +#undef HAVE_SETENV + +/* Define if you have the setlocale function. */ +#undef HAVE_SETLOCALE + +/* Define if you have the sigaction function. */ +#undef HAVE_SIGACTION + +/* Define if you have the stpcpy function. */ +#undef HAVE_STPCPY + +/* Define if you have the strcasecmp function. */ +#undef HAVE_STRCASECMP + +/* Define if you have the strchr function. */ +#undef HAVE_STRCHR + +/* Define if you have the time function. */ +#undef HAVE_TIME + +/* Define if you have the <argz.h> header file. */ +#undef HAVE_ARGZ_H + +/* Define if you have the <fcntl.h> header file. */ +#undef HAVE_FCNTL_H + +/* Define if you have the <fpu_control.h> header file. */ +#undef HAVE_FPU_CONTROL_H + +/* Define if you have the <limits.h> header file. */ +#undef HAVE_LIMITS_H + +/* Define if you have the <locale.h> header file. */ +#undef HAVE_LOCALE_H + +/* Define if you have the <malloc.h> header file. */ +#undef HAVE_MALLOC_H + +/* Define if you have the <nl_types.h> header file. */ +#undef HAVE_NL_TYPES_H + +/* Define if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define if you have the <sys/param.h> header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define if you have the <sys/resource.h> header file. */ +#undef HAVE_SYS_RESOURCE_H + +/* Define if you have the <sys/time.h> header file. */ +#undef HAVE_SYS_TIME_H + +/* Define if you have the <time.h> header file. */ +#undef HAVE_TIME_H + +/* Define if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define if you have the <values.h> header file. */ +#undef HAVE_VALUES_H diff --git a/sim/arm/configure b/sim/arm/configure new file mode 100755 index 0000000..e646fa8 --- /dev/null +++ b/sim/arm/configure @@ -0,0 +1,3892 @@ +#! /bin/sh + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +sim_inline="-DDEFAULT_INLINE=0" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# This file is derived from `gettext.m4'. The difference is that the +# included macros assume Cygnus-style source and build trees. + +# Macro to add for using GNU gettext. +# Ulrich Drepper <drepper@cygnus.com>, 1995. +# +# This file file be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +# serial 3 + + + + + +# Search path for a program which passes the given test. +# Ulrich Drepper <drepper@cygnus.com>, 1996. +# +# This file file be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +# serial 1 + + + +# Check whether LC_MESSAGES is available in <locale.h>. +# Ulrich Drepper <drepper@cygnus.com>, 1995. +# +# This file file be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +# serial 1 + + + +# Check to see if we're running under Cygwin32, without using +# AC_CANONICAL_*. If so, set output variable CYGWIN32 to "yes". +# Otherwise set it to "no". + + + +# Check to see if we're running under Win32, without using +# AC_CANONICAL_*. If so, set output variable EXEEXT to ".exe". +# Otherwise set it to "". + + + + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.12.2 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --disable-nls do not use Native Language Support" +ac_help="$ac_help + --with-included-gettext use the GNU gettext library included here" +ac_help="$ac_help + --enable-maintainer-mode Enable developer functionality." +ac_help="$ac_help + --enable-sim-bswap Use Host specific BSWAP instruction." +ac_help="$ac_help + --enable-sim-cflags=opts Extra CFLAGS for use in building simulator" +ac_help="$ac_help + --enable-sim-debug=opts Enable debugging flags" +ac_help="$ac_help + --enable-sim-stdio Specify whether to use stdio for console input/output." +ac_help="$ac_help + --enable-sim-trace=opts Enable tracing flags" +ac_help="$ac_help + --enable-sim-profile=opts Enable profiling flags" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.12.2" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=Makefile.in + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:677: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext <<EOF +#line 692 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:698: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext <<EOF +#line 709 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:715: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext <<EOF +#line 726 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:732: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:757: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6 +echo "configure:784: checking for POSIXized ISC" >&5 +if test -d /etc/conf/kconfig.d && + grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1 +then + echo "$ac_t""yes" 1>&6 + ISC=yes # If later tests want to check for ISC. + cat >> confdefs.h <<\EOF +#define _POSIX_SOURCE 1 +EOF + + if test "$GCC" = yes; then + CC="$CC -posix" + else + CC="$CC -Xp" + fi +else + echo "$ac_t""no" 1>&6 + ISC= +fi + +echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 +echo "configure:805: checking for ANSI C header files" >&5 +if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 810 "configure" +#include "confdefs.h" +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:818: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + ac_cv_header_stdc=yes +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +cat > conftest.$ac_ext <<EOF +#line 835 "configure" +#include "confdefs.h" +#include <string.h> +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +cat > conftest.$ac_ext <<EOF +#line 853 "configure" +#include "confdefs.h" +#include <stdlib.h> +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +if test "$cross_compiling" = yes; then + : +else + cat > conftest.$ac_ext <<EOF +#line 874 "configure" +#include "confdefs.h" +#include <ctype.h> +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } + +EOF +if { (eval echo configure:885: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + : +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_header_stdc=no +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_header_stdc" 1>&6 +if test $ac_cv_header_stdc = yes; then + cat >> confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF + +fi + +echo $ac_n "checking for working const""... $ac_c" 1>&6 +echo "configure:909: checking for working const" >&5 +if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 914 "configure" +#include "confdefs.h" + +int main() { + +/* Ultrix mips cc rejects this. */ +typedef int charset[2]; const charset x; +/* SunOS 4.1.1 cc rejects this. */ +char const *const *ccp; +char **p; +/* NEC SVR4.0.2 mips cc rejects this. */ +struct point {int x, y;}; +static struct point const zero = {0,0}; +/* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in an arm + of an if-expression whose if-part is not a constant expression */ +const char *g = "string"; +ccp = &g + (g ? g-g : 0); +/* HPUX 7.0 cc rejects these. */ +++ccp; +p = (char**) ccp; +ccp = (char const *const *) p; +{ /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; +} +{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; +} +{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; +} +{ /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; +} +{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; +} + +; return 0; } +EOF +if { (eval echo configure:963: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_const=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_c_const=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_c_const" 1>&6 +if test $ac_cv_c_const = no; then + cat >> confdefs.h <<\EOF +#define const +EOF + +fi + +echo $ac_n "checking for inline""... $ac_c" 1>&6 +echo "configure:984: checking for inline" >&5 +if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat > conftest.$ac_ext <<EOF +#line 991 "configure" +#include "confdefs.h" + +int main() { +} $ac_kw foo() { +; return 0; } +EOF +if { (eval echo configure:998: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_inline=$ac_kw; break +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +done + +fi + +echo "$ac_t""$ac_cv_c_inline" 1>&6 +case "$ac_cv_c_inline" in + inline | yes) ;; + no) cat >> confdefs.h <<\EOF +#define inline +EOF + ;; + *) cat >> confdefs.h <<EOF +#define inline $ac_cv_c_inline +EOF + ;; +esac + +echo $ac_n "checking for off_t""... $ac_c" 1>&6 +echo "configure:1024: checking for off_t" >&5 +if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1029 "configure" +#include "confdefs.h" +#include <sys/types.h> +#if STDC_HEADERS +#include <stdlib.h> +#include <stddef.h> +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_off_t=yes +else + rm -rf conftest* + ac_cv_type_off_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_type_off_t" 1>&6 +if test $ac_cv_type_off_t = no; then + cat >> confdefs.h <<\EOF +#define off_t long +EOF + +fi + +echo $ac_n "checking for size_t""... $ac_c" 1>&6 +echo "configure:1057: checking for size_t" >&5 +if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1062 "configure" +#include "confdefs.h" +#include <sys/types.h> +#if STDC_HEADERS +#include <stdlib.h> +#include <stddef.h> +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_size_t=yes +else + rm -rf conftest* + ac_cv_type_size_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_type_size_t" 1>&6 +if test $ac_cv_type_size_t = no; then + cat >> confdefs.h <<\EOF +#define size_t unsigned +EOF + +fi + +# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works +# for constant arguments. Useless! +echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 +echo "configure:1092: checking for working alloca.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1097 "configure" +#include "confdefs.h" +#include <alloca.h> +int main() { +char *p = alloca(2 * sizeof(int)); +; return 0; } +EOF +if { (eval echo configure:1104: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_header_alloca_h=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_alloca_h=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_header_alloca_h" 1>&6 +if test $ac_cv_header_alloca_h = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_ALLOCA_H 1 +EOF + +fi + +echo $ac_n "checking for alloca""... $ac_c" 1>&6 +echo "configure:1125: checking for alloca" >&5 +if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1130 "configure" +#include "confdefs.h" + +#ifdef __GNUC__ +# define alloca __builtin_alloca +#else +# ifdef _MSC_VER +# include <malloc.h> +# define alloca _alloca +# else +# if HAVE_ALLOCA_H +# include <alloca.h> +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +char *alloca (); +# endif +# endif +# endif +# endif +#endif + +int main() { +char *p = (char *) alloca(1); +; return 0; } +EOF +if { (eval echo configure:1158: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_func_alloca_works=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_func_alloca_works=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_func_alloca_works" 1>&6 +if test $ac_cv_func_alloca_works = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_ALLOCA 1 +EOF + +fi + +if test $ac_cv_func_alloca_works = no; then + # The SVR3 libPW and SVR4 libucb both contain incompatible functions + # that cause trouble. Some versions do not even contain alloca or + # contain a buggy version. If you still want to use their alloca, + # use ar to extract alloca.o from them instead of compiling alloca.c. + ALLOCA=alloca.${ac_objext} + cat >> confdefs.h <<\EOF +#define C_ALLOCA 1 +EOF + + +echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 +echo "configure:1190: checking whether alloca needs Cray hooks" >&5 +if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1195 "configure" +#include "confdefs.h" +#if defined(CRAY) && ! defined(CRAY2) +webecray +#else +wenotbecray +#endif + +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "webecray" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_os_cray=yes +else + rm -rf conftest* + ac_cv_os_cray=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_os_cray" 1>&6 +if test $ac_cv_os_cray = yes; then +for ac_func in _getb67 GETB67 getb67; do + echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1220: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1225 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1248: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<EOF +#define CRAY_STACKSEG_END $ac_func +EOF + + break +else + echo "$ac_t""no" 1>&6 +fi + +done +fi + +echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 +echo "configure:1275: checking stack direction for C alloca" >&5 +if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_c_stack_direction=0 +else + cat > conftest.$ac_ext <<EOF +#line 1283 "configure" +#include "confdefs.h" +find_stack_direction () +{ + static char *addr = 0; + auto char dummy; + if (addr == 0) + { + addr = &dummy; + return find_stack_direction (); + } + else + return (&dummy > addr) ? 1 : -1; +} +main () +{ + exit (find_stack_direction() < 0); +} +EOF +if { (eval echo configure:1302: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_c_stack_direction=1 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_c_stack_direction=-1 +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_cv_c_stack_direction" 1>&6 +cat >> confdefs.h <<EOF +#define STACK_DIRECTION $ac_cv_c_stack_direction +EOF + +fi + +for ac_hdr in unistd.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1327: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1332 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1337: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_func in getpagesize +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1366: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1371 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1394: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +echo $ac_n "checking for working mmap""... $ac_c" 1>&6 +echo "configure:1419: checking for working mmap" >&5 +if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_mmap_fixed_mapped=no +else + cat > conftest.$ac_ext <<EOF +#line 1427 "configure" +#include "confdefs.h" + +/* Thanks to Mike Haertel and Jim Avera for this test. + Here is a matrix of mmap possibilities: + mmap private not fixed + mmap private fixed at somewhere currently unmapped + mmap private fixed at somewhere already mapped + mmap shared not fixed + mmap shared fixed at somewhere currently unmapped + mmap shared fixed at somewhere already mapped + For private mappings, we should verify that changes cannot be read() + back from the file, nor mmap's back from the file at a different + address. (There have been systems where private was not correctly + implemented like the infamous i386 svr4.0, and systems where the + VM page cache was not coherent with the filesystem buffer cache + like early versions of FreeBSD and possibly contemporary NetBSD.) + For shared mappings, we should conversely verify that changes get + propogated back to all the places they're supposed to be. + + Grep wants private fixed already mapped. + The main things grep needs to know about mmap are: + * does it exist and is it safe to write into the mmap'd area + * how to use it (BSD variants) */ +#include <sys/types.h> +#include <fcntl.h> +#include <sys/mman.h> + +/* This mess was copied from the GNU getpagesize.h. */ +#ifndef HAVE_GETPAGESIZE +# ifdef HAVE_UNISTD_H +# include <unistd.h> +# endif + +/* Assume that all systems that can run configure have sys/param.h. */ +# ifndef HAVE_SYS_PARAM_H +# define HAVE_SYS_PARAM_H 1 +# endif + +# ifdef _SC_PAGESIZE +# define getpagesize() sysconf(_SC_PAGESIZE) +# else /* no _SC_PAGESIZE */ +# ifdef HAVE_SYS_PARAM_H +# include <sys/param.h> +# ifdef EXEC_PAGESIZE +# define getpagesize() EXEC_PAGESIZE +# else /* no EXEC_PAGESIZE */ +# ifdef NBPG +# define getpagesize() NBPG * CLSIZE +# ifndef CLSIZE +# define CLSIZE 1 +# endif /* no CLSIZE */ +# else /* no NBPG */ +# ifdef NBPC +# define getpagesize() NBPC +# else /* no NBPC */ +# ifdef PAGESIZE +# define getpagesize() PAGESIZE +# endif /* PAGESIZE */ +# endif /* no NBPC */ +# endif /* no NBPG */ +# endif /* no EXEC_PAGESIZE */ +# else /* no HAVE_SYS_PARAM_H */ +# define getpagesize() 8192 /* punt totally */ +# endif /* no HAVE_SYS_PARAM_H */ +# endif /* no _SC_PAGESIZE */ + +#endif /* no HAVE_GETPAGESIZE */ + +#ifdef __cplusplus +extern "C" { void *malloc(unsigned); } +#else +char *malloc(); +#endif + +int +main() +{ + char *data, *data2, *data3; + int i, pagesize; + int fd; + + pagesize = getpagesize(); + + /* + * First, make a file with some known garbage in it. + */ + data = malloc(pagesize); + if (!data) + exit(1); + for (i = 0; i < pagesize; ++i) + *(data + i) = rand(); + umask(0); + fd = creat("conftestmmap", 0600); + if (fd < 0) + exit(1); + if (write(fd, data, pagesize) != pagesize) + exit(1); + close(fd); + + /* + * Next, try to mmap the file at a fixed address which + * already has something else allocated at it. If we can, + * also make sure that we see the same garbage. + */ + fd = open("conftestmmap", O_RDWR); + if (fd < 0) + exit(1); + data2 = malloc(2 * pagesize); + if (!data2) + exit(1); + data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1); + if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_FIXED, fd, 0L)) + exit(1); + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data2 + i)) + exit(1); + + /* + * Finally, make sure that changes to the mapped area + * do not percolate back to the file as seen by read(). + * (This is a bug on some variants of i386 svr4.0.) + */ + for (i = 0; i < pagesize; ++i) + *(data2 + i) = *(data2 + i) + 1; + data3 = malloc(pagesize); + if (!data3) + exit(1); + if (read(fd, data3, pagesize) != pagesize) + exit(1); + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data3 + i)) + exit(1); + close(fd); + unlink("conftestmmap"); + exit(0); +} + +EOF +if { (eval echo configure:1567: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_func_mmap_fixed_mapped=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_func_mmap_fixed_mapped=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6 +if test $ac_cv_func_mmap_fixed_mapped = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_MMAP 1 +EOF + +fi + + +# autoconf.info says this should be called right after AC_INIT. + + +ac_aux_dir= +for ac_dir in `cd $srcdir;pwd`/../.. $srcdir/`cd $srcdir;pwd`/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../.. $srcdir/`cd $srcdir;pwd`/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Do some error checking and defaulting for the host and target type. +# The inputs are: +# configure --host=HOST --target=TARGET --build=BUILD NONOPT +# +# The rules are: +# 1. You are not allowed to specify --host, --target, and nonopt at the +# same time. +# 2. Host defaults to nonopt. +# 3. If nonopt is not specified, then host defaults to the current host, +# as determined by config.guess. +# 4. Target and build default to nonopt. +# 5. If nonopt is not specified, then target and build default to host. + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +case $host---$target---$nonopt in +NONE---*---* | *---NONE---* | *---*---NONE) ;; +*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; +esac + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:1640: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking target system type""... $ac_c" 1>&6 +echo "configure:1661: checking target system type" >&5 + +target_alias=$target +case "$target_alias" in +NONE) + case $nonopt in + NONE) target_alias=$host_alias ;; + *) target_alias=$nonopt ;; + esac ;; +esac + +target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` +target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$target" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:1679: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +test "$host_alias" != "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + +if test "$program_transform_name" = s,x,x,; then + program_transform_name= +else + # Double any \ or $. echo might interpret backslashes. + cat <<\EOF_SED > conftestsed +s,\\,\\\\,g; s,\$,$$,g +EOF_SED + program_transform_name="`echo $program_transform_name|sed -f conftestsed`" + rm -f conftestsed +fi +test "$program_prefix" != NONE && + program_transform_name="s,^,${program_prefix},; $program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" + +# sed with no file args requires a program. +test "$program_transform_name" = "" && program_transform_name="s,x,x," + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1723: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1752: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1802: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:1833: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext <<EOF +#line 1843 "configure" +#include "confdefs.h" +main(){return(0);} +EOF +if { (eval echo configure:1847: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:1867: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:1872: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1881: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:1900: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:1943: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +# Put a plausible default for CC_FOR_BUILD in Makefile. +if test "x$cross_compiling" = "xno"; then + CC_FOR_BUILD='$(CC)' +else + CC_FOR_BUILD=gcc +fi + + + + +AR=${AR-ar} + +# Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2009: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +ALL_LINGUAS= + + for ac_hdr in argz.h limits.h locale.h nl_types.h malloc.h string.h \ +unistd.h values.h sys/param.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2043: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2048 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2053: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + for ac_func in getcwd munmap putenv setenv setlocale strchr strcasecmp \ +__argz_count __argz_stringify __argz_next +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:2083: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2088 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2111: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + + if test "${ac_cv_func_stpcpy+set}" != "set"; then + for ac_func in stpcpy +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:2140: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2145 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2168: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + fi + if test "${ac_cv_func_stpcpy}" = "yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_STPCPY 1 +EOF + + fi + + if test $ac_cv_header_locale_h = yes; then + echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6 +echo "configure:2202: checking for LC_MESSAGES" >&5 +if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2207 "configure" +#include "confdefs.h" +#include <locale.h> +int main() { +return LC_MESSAGES +; return 0; } +EOF +if { (eval echo configure:2214: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + am_cv_val_LC_MESSAGES=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + am_cv_val_LC_MESSAGES=no +fi +rm -f conftest* +fi + +echo "$ac_t""$am_cv_val_LC_MESSAGES" 1>&6 + if test $am_cv_val_LC_MESSAGES = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_LC_MESSAGES 1 +EOF + + fi + fi + echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6 +echo "configure:2235: checking whether NLS is requested" >&5 + # Check whether --enable-nls or --disable-nls was given. +if test "${enable_nls+set}" = set; then + enableval="$enable_nls" + USE_NLS=$enableval +else + USE_NLS=yes +fi + + echo "$ac_t""$USE_NLS" 1>&6 + + + USE_INCLUDED_LIBINTL=no + + if test "$USE_NLS" = "yes"; then + cat >> confdefs.h <<\EOF +#define ENABLE_NLS 1 +EOF + + echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6 +echo "configure:2255: checking whether included gettext is requested" >&5 + # Check whether --with-included-gettext or --without-included-gettext was given. +if test "${with_included_gettext+set}" = set; then + withval="$with_included_gettext" + nls_cv_force_use_gnu_gettext=$withval +else + nls_cv_force_use_gnu_gettext=no +fi + + echo "$ac_t""$nls_cv_force_use_gnu_gettext" 1>&6 + + nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" + if test "$nls_cv_force_use_gnu_gettext" != "yes"; then + nls_cv_header_intl= + nls_cv_header_libgt= + CATOBJEXT=NONE + + ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for libintl.h""... $ac_c" 1>&6 +echo "configure:2274: checking for libintl.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2279 "configure" +#include "confdefs.h" +#include <libintl.h> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2284: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6 +echo "configure:2301: checking for gettext in libc" >&5 +if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2306 "configure" +#include "confdefs.h" +#include <libintl.h> +int main() { +return (int) gettext ("") +; return 0; } +EOF +if { (eval echo configure:2313: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + gt_cv_func_gettext_libc=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + gt_cv_func_gettext_libc=no +fi +rm -f conftest* +fi + +echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6 + + if test "$gt_cv_func_gettext_libc" != "yes"; then + echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6 +echo "configure:2329: checking for bindtextdomain in -lintl" >&5 +ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lintl $LIBS" +cat > conftest.$ac_ext <<EOF +#line 2337 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char bindtextdomain(); + +int main() { +bindtextdomain() +; return 0; } +EOF +if { (eval echo configure:2348: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6 +echo "configure:2364: checking for gettext in libintl" >&5 +if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2369 "configure" +#include "confdefs.h" + +int main() { +return (int) gettext ("") +; return 0; } +EOF +if { (eval echo configure:2376: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + gt_cv_func_gettext_libintl=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + gt_cv_func_gettext_libintl=no +fi +rm -f conftest* +fi + +echo "$ac_t""$gt_cv_func_gettext_libintl" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + fi + + if test "$gt_cv_func_gettext_libc" = "yes" \ + || test "$gt_cv_func_gettext_libintl" = "yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_GETTEXT 1 +EOF + + # Extract the first word of "msgfmt", so it can be a program name with args. +set dummy msgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2404: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$MSGFMT" in + /*) + ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then + ac_cv_path_MSGFMT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no" + ;; +esac +fi +MSGFMT="$ac_cv_path_MSGFMT" +if test -n "$MSGFMT"; then + echo "$ac_t""$MSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + if test "$MSGFMT" != "no"; then + for ac_func in dcgettext +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:2438: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2443 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2466: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + # Extract the first word of "gmsgfmt", so it can be a program name with args. +set dummy gmsgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2493: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$GMSGFMT" in + /*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_GMSGFMT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" + ;; +esac +fi +GMSGFMT="$ac_cv_path_GMSGFMT" +if test -n "$GMSGFMT"; then + echo "$ac_t""$GMSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + # Extract the first word of "xgettext", so it can be a program name with args. +set dummy xgettext; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2528: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$XGETTEXT" in + /*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then + ac_cv_path_XGETTEXT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" + ;; +esac +fi +XGETTEXT="$ac_cv_path_XGETTEXT" +if test -n "$XGETTEXT"; then + echo "$ac_t""$XGETTEXT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + cat > conftest.$ac_ext <<EOF +#line 2560 "configure" +#include "confdefs.h" + +int main() { +extern int _nl_msg_cat_cntr; + return _nl_msg_cat_cntr +; return 0; } +EOF +if { (eval echo configure:2568: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + CATOBJEXT=.gmo + DATADIRNAME=share +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CATOBJEXT=.mo + DATADIRNAME=lib +fi +rm -f conftest* + INSTOBJEXT=.mo + fi + fi + +else + echo "$ac_t""no" 1>&6 +fi + + + + if test "$CATOBJEXT" = "NONE"; then + nls_cv_use_gnu_gettext=yes + fi + fi + + if test "$nls_cv_use_gnu_gettext" = "yes"; then + INTLOBJS="\$(GETTOBJS)" + # Extract the first word of "msgfmt", so it can be a program name with args. +set dummy msgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2600: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$MSGFMT" in + /*) + ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then + ac_cv_path_MSGFMT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="msgfmt" + ;; +esac +fi +MSGFMT="$ac_cv_path_MSGFMT" +if test -n "$MSGFMT"; then + echo "$ac_t""$MSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + # Extract the first word of "gmsgfmt", so it can be a program name with args. +set dummy gmsgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2634: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$GMSGFMT" in + /*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_GMSGFMT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" + ;; +esac +fi +GMSGFMT="$ac_cv_path_GMSGFMT" +if test -n "$GMSGFMT"; then + echo "$ac_t""$GMSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + # Extract the first word of "xgettext", so it can be a program name with args. +set dummy xgettext; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2669: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$XGETTEXT" in + /*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then + ac_cv_path_XGETTEXT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" + ;; +esac +fi +XGETTEXT="$ac_cv_path_XGETTEXT" +if test -n "$XGETTEXT"; then + echo "$ac_t""$XGETTEXT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + USE_INCLUDED_LIBINTL=yes + CATOBJEXT=.gmo + INSTOBJEXT=.mo + DATADIRNAME=share + INTLDEPS='$(top_builddir)/../intl/libintl.a' + INTLLIBS=$INTLDEPS + LIBS=`echo $LIBS | sed -e 's/-lintl//'` + nls_cv_header_intl=libintl.h + nls_cv_header_libgt=libgettext.h + fi + + if test "$XGETTEXT" != ":"; then + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + echo "$ac_t""found xgettext programs is not GNU xgettext; ignore it" 1>&6 + XGETTEXT=":" + fi + fi + + # We need to process the po/ directory. + POSUB=po + else + DATADIRNAME=share + nls_cv_header_intl=libintl.h + nls_cv_header_libgt=libgettext.h + fi + + # If this is used in GNU gettext we have to set USE_NLS to `yes' + # because some of the sources are only built for this goal. + if test "$PACKAGE" = gettext; then + USE_NLS=yes + USE_INCLUDED_LIBINTL=yes + fi + + for lang in $ALL_LINGUAS; do + GMOFILES="$GMOFILES $lang.gmo" + POFILES="$POFILES $lang.po" + done + + + + + + + + + + + + + + + if test "x$CATOBJEXT" != "x"; then + if test "x$ALL_LINGUAS" = "x"; then + LINGUAS= + else + echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6 +echo "configure:2759: checking for catalogs to be installed" >&5 + NEW_LINGUAS= + for lang in ${LINGUAS=$ALL_LINGUAS}; do + case "$ALL_LINGUAS" in + *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; + esac + done + LINGUAS=$NEW_LINGUAS + echo "$ac_t""$LINGUAS" 1>&6 + fi + + if test -n "$LINGUAS"; then + for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done + fi + fi + + if test $ac_cv_header_locale_h = yes; then + INCLUDE_LOCALE_H="#include <locale.h>" + else + INCLUDE_LOCALE_H="\ +/* The system does not provide the header <locale.h>. Take care yourself. */" + fi + + + if test -f $srcdir/po2tbl.sed.in; then + if test "$CATOBJEXT" = ".cat"; then + ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6 +echo "configure:2787: checking for linux/version.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2792 "configure" +#include "confdefs.h" +#include <linux/version.h> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2797: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + msgformat=linux +else + echo "$ac_t""no" 1>&6 +msgformat=xopen +fi + + + sed -e '/^#/d' $srcdir/$msgformat-msg.sed > po2msg.sed + fi + sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \ + $srcdir/po2tbl.sed.in > po2tbl.sed + fi + + if test "$PACKAGE" = "gettext"; then + GT_NO="#NO#" + GT_YES= + else + GT_NO= + GT_YES="#YES#" + fi + + + + MKINSTALLDIRS="\$(srcdir)/../../mkinstalldirs" + + + l= + + + if test -d $srcdir/po; then + test -d po || mkdir po + if test "x$srcdir" != "x."; then + if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then + posrcprefix="$srcdir/" + else + posrcprefix="../$srcdir/" + fi + else + posrcprefix="../" + fi + rm -f po/POTFILES + sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ + < $srcdir/po/POTFILES.in > po/POTFILES + fi + + +# Check for common headers. +# FIXME: Seems to me this can cause problems for i386-windows hosts. +# At one point there were hardcoded AC_DEFINE's if ${host} = i386-*-windows*. +for ac_hdr in stdlib.h string.h strings.h unistd.h time.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2866: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2871 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2876: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in sys/time.h sys/resource.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2906: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2911 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2916: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_hdr in fcntl.h fpu_control.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2946: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2951 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2956: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + +for ac_func in getrusage time sigaction __setfpucw +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:2985: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2990 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3013: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + +# Check for socket libraries +echo $ac_n "checking for bind in -lsocket""... $ac_c" 1>&6 +echo "configure:3040: checking for bind in -lsocket" >&5 +ac_lib_var=`echo socket'_'bind | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3048 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char bind(); + +int main() { +bind() +; return 0; } +EOF +if { (eval echo configure:3059: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo socket | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <<EOF +#define $ac_tr_lib 1 +EOF + + LIBS="-lsocket $LIBS" + +else + echo "$ac_t""no" 1>&6 +fi + +echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6 +echo "configure:3087: checking for gethostbyname in -lnsl" >&5 +ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lnsl $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3095 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname(); + +int main() { +gethostbyname() +; return 0; } +EOF +if { (eval echo configure:3106: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo nsl | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <<EOF +#define $ac_tr_lib 1 +EOF + + LIBS="-lnsl $LIBS" + +else + echo "$ac_t""no" 1>&6 +fi + + +. ${srcdir}/../../bfd/configure.host + + + +USE_MAINTAINER_MODE=no +# Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then + enableval="$enable_maintainer_mode" + case "${enableval}" in + yes) MAINT="" USE_MAINTAINER_MODE=yes ;; + no) MAINT="#" ;; + *) { echo "configure: error: "--enable-maintainer-mode does not take a value"" 1>&2; exit 1; }; MAINT="#" ;; +esac +if test x"$silent" != x"yes" && test x"$MAINT" = x""; then + echo "Setting maintainer mode" 6>&1 +fi +else + MAINT="#" +fi + + + +# Check whether --enable-sim-bswap or --disable-sim-bswap was given. +if test "${enable_sim_bswap+set}" = set; then + enableval="$enable_sim_bswap" + case "${enableval}" in + yes) sim_bswap="-DWITH_BSWAP=1 -DUSE_BSWAP=1";; + no) sim_bswap="-DWITH_BSWAP=0";; + *) { echo "configure: error: "--enable-sim-bswap does not take a value"" 1>&2; exit 1; }; sim_bswap="";; +esac +if test x"$silent" != x"yes" && test x"$sim_bswap" != x""; then + echo "Setting bswap flags = $sim_bswap" 6>&1 +fi +else + sim_bswap="" +fi + + + +# Check whether --enable-sim-cflags or --disable-sim-cflags was given. +if test "${enable_sim_cflags+set}" = set; then + enableval="$enable_sim_cflags" + case "${enableval}" in + yes) sim_cflags="-O2 -fomit-frame-pointer";; + trace) { echo "configure: error: "Please use --enable-sim-debug instead."" 1>&2; exit 1; }; sim_cflags="";; + no) sim_cflags="";; + *) sim_cflags=`echo "${enableval}" | sed -e "s/,/ /g"`;; +esac +if test x"$silent" != x"yes" && test x"$sim_cflags" != x""; then + echo "Setting sim cflags = $sim_cflags" 6>&1 +fi +else + sim_cflags="" +fi + + + +# Check whether --enable-sim-debug or --disable-sim-debug was given. +if test "${enable_sim_debug+set}" = set; then + enableval="$enable_sim_debug" + case "${enableval}" in + yes) sim_debug="-DDEBUG=7 -DWITH_DEBUG=7";; + no) sim_debug="-DDEBUG=0 -DWITH_DEBUG=0";; + *) sim_debug="-DDEBUG='(${enableval})' -DWITH_DEBUG='(${enableval})'";; +esac +if test x"$silent" != x"yes" && test x"$sim_debug" != x""; then + echo "Setting sim debug = $sim_debug" 6>&1 +fi +else + sim_debug="" +fi + + + +# Check whether --enable-sim-stdio or --disable-sim-stdio was given. +if test "${enable_sim_stdio+set}" = set; then + enableval="$enable_sim_stdio" + case "${enableval}" in + yes) sim_stdio="-DWITH_STDIO=DO_USE_STDIO";; + no) sim_stdio="-DWITH_STDIO=DONT_USE_STDIO";; + *) { echo "configure: error: "Unknown value $enableval passed to --enable-sim-stdio"" 1>&2; exit 1; }; sim_stdio="";; +esac +if test x"$silent" != x"yes" && test x"$sim_stdio" != x""; then + echo "Setting stdio flags = $sim_stdio" 6>&1 +fi +else + sim_stdio="" +fi + + + +# Check whether --enable-sim-trace or --disable-sim-trace was given. +if test "${enable_sim_trace+set}" = set; then + enableval="$enable_sim_trace" + case "${enableval}" in + yes) sim_trace="-DTRACE=1 -DWITH_TRACE=-1";; + no) sim_trace="-DTRACE=0 -DWITH_TRACE=0";; + [-0-9]*) + sim_trace="-DTRACE='(${enableval})' -DWITH_TRACE='(${enableval})'";; + [a-z]*) + sim_trace="" + for x in `echo "$enableval" | sed -e "s/,/ /g"`; do + if test x"$sim_trace" = x; then + sim_trace="-DWITH_TRACE='(TRACE_$x" + else + sim_trace="${sim_trace}|TRACE_$x" + fi + done + sim_trace="$sim_trace)'" ;; +esac +if test x"$silent" != x"yes" && test x"$sim_trace" != x""; then + echo "Setting sim trace = $sim_trace" 6>&1 +fi +else + sim_trace="" +fi + + + +# Check whether --enable-sim-profile or --disable-sim-profile was given. +if test "${enable_sim_profile+set}" = set; then + enableval="$enable_sim_profile" + case "${enableval}" in + yes) sim_profile="-DPROFILE=1 -DWITH_PROFILE=-1";; + no) sim_profile="-DPROFILE=0 -DWITH_PROFILE=0";; + [-0-9]*) + sim_profile="-DPROFILE='(${enableval})' -DWITH_PROFILE='(${enableval})'";; + [a-z]*) + sim_profile="" + for x in `echo "$enableval" | sed -e "s/,/ /g"`; do + if test x"$sim_profile" = x; then + sim_profile="-DWITH_PROFILE='(PROFILE_$x" + else + sim_profile="${sim_profile}|PROFILE_$x" + fi + done + sim_profile="$sim_profile)'" ;; +esac +if test x"$silent" != x"yes" && test x"$sim_profile" != x""; then + echo "Setting sim profile = $sim_profile" 6>&1 +fi +else + sim_profile="" +fi + + + +echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 +echo "configure:3282: checking return type of signal handlers" >&5 +if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3287 "configure" +#include "confdefs.h" +#include <sys/types.h> +#include <signal.h> +#ifdef signal +#undef signal +#endif +#ifdef __cplusplus +extern "C" void (*signal (int, void (*)(int)))(int); +#else +void (*signal ()) (); +#endif + +int main() { +int i; +; return 0; } +EOF +if { (eval echo configure:3304: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_type_signal=void +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_type_signal=int +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_type_signal" 1>&6 +cat >> confdefs.h <<EOF +#define RETSIGTYPE $ac_cv_type_signal +EOF + + + +echo $ac_n "checking for executable suffix""... $ac_c" 1>&6 +echo "configure:3324: checking for executable suffix" >&5 +if eval "test \"`echo '$''{'am_cv_exeext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$CYGWIN32" = yes; then +am_cv_exeext=.exe +else +cat > am_c_test.c << 'EOF' +int main() { +/* Nothing needed here */ +} +EOF +${CC-cc} -o am_c_test $CFLAGS $CPPFLAGS $LDFLAGS am_c_test.c $LIBS 1>&5 +am_cv_exeext=`ls am_c_test.* | grep -v am_c_test.c | sed -e s/am_c_test//` +rm -f am_c_test* +fi + +test x"${am_cv_exeext}" = x && am_cv_exeext=no +fi +EXEEXT="" +test x"${am_cv_exeext}" != xno && EXEEXT=${am_cv_exeext} +echo "$ac_t""${am_cv_exeext}" 1>&6 + + +sim_link_files= +sim_link_links= + +sim_link_links=tconfig.h +if test -f ${srcdir}/tconfig.in +then + sim_link_files=tconfig.in +else + sim_link_files=../common/tconfig.in +fi + +# targ-vals.def points to the libc macro description file. +case "${target}" in +*-*-*) TARG_VALS_DEF=../common/nltvals.def ;; +esac +sim_link_files="${sim_link_files} ${TARG_VALS_DEF}" +sim_link_links="${sim_link_links} targ-vals.def" + + + +for ac_hdr in unistd.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:3372: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 3377 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:3382: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set) 2>&1 | grep ac_space` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.12.2" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile.sim:Makefile.in Make-common.sim:../common/Make-common.in .gdbinit:../common/gdbinit.in config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS <<EOF + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@sim_environment@%$sim_environment%g +s%@sim_alignment@%$sim_alignment%g +s%@sim_assert@%$sim_assert%g +s%@sim_bitsize@%$sim_bitsize%g +s%@sim_endian@%$sim_endian%g +s%@sim_hostendian@%$sim_hostendian%g +s%@sim_float@%$sim_float%g +s%@sim_scache@%$sim_scache%g +s%@sim_default_model@%$sim_default_model%g +s%@sim_hw_cflags@%$sim_hw_cflags%g +s%@sim_hw_objs@%$sim_hw_objs%g +s%@sim_hw@%$sim_hw%g +s%@sim_inline@%$sim_inline%g +s%@sim_packages@%$sim_packages%g +s%@sim_regparm@%$sim_regparm%g +s%@sim_reserved_bits@%$sim_reserved_bits%g +s%@sim_smp@%$sim_smp%g +s%@sim_stdcall@%$sim_stdcall%g +s%@sim_xor_endian@%$sim_xor_endian%g +s%@build_warnings@%$build_warnings%g +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@target@%$target%g +s%@target_alias@%$target_alias%g +s%@target_cpu@%$target_cpu%g +s%@target_vendor@%$target_vendor%g +s%@target_os@%$target_os%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g +s%@CC@%$CC%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@CC_FOR_BUILD@%$CC_FOR_BUILD%g +s%@HDEFINES@%$HDEFINES%g +s%@AR@%$AR%g +s%@RANLIB@%$RANLIB%g +s%@SET_MAKE@%$SET_MAKE%g +s%@CPP@%$CPP%g +s%@ALLOCA@%$ALLOCA%g +s%@USE_NLS@%$USE_NLS%g +s%@MSGFMT@%$MSGFMT%g +s%@GMSGFMT@%$GMSGFMT%g +s%@XGETTEXT@%$XGETTEXT%g +s%@USE_INCLUDED_LIBINTL@%$USE_INCLUDED_LIBINTL%g +s%@CATALOGS@%$CATALOGS%g +s%@CATOBJEXT@%$CATOBJEXT%g +s%@DATADIRNAME@%$DATADIRNAME%g +s%@GMOFILES@%$GMOFILES%g +s%@INSTOBJEXT@%$INSTOBJEXT%g +s%@INTLDEPS@%$INTLDEPS%g +s%@INTLLIBS@%$INTLLIBS%g +s%@INTLOBJS@%$INTLOBJS%g +s%@POFILES@%$POFILES%g +s%@POSUB@%$POSUB%g +s%@INCLUDE_LOCALE_H@%$INCLUDE_LOCALE_H%g +s%@GT_NO@%$GT_NO%g +s%@GT_YES@%$GT_YES%g +s%@MKINSTALLDIRS@%$MKINSTALLDIRS%g +s%@l@%$l%g +s%@MAINT@%$MAINT%g +s%@sim_bswap@%$sim_bswap%g +s%@sim_cflags@%$sim_cflags%g +s%@sim_debug@%$sim_debug%g +s%@sim_stdio@%$sim_stdio%g +s%@sim_trace@%$sim_trace%g +s%@sim_profile@%$sim_profile%g +s%@EXEEXT@%$EXEEXT%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"Makefile.sim:Makefile.in Make-common.sim:../common/Make-common.in .gdbinit:../common/gdbinit.in"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then +EOF +cat >> $CONFIG_STATUS <<EOF + CONFIG_HEADERS="config.h:config.in" +EOF +cat >> $CONFIG_STATUS <<\EOF +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + cat $ac_file_inputs > conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. And first: +# Protect against being on the right side of a sed subst in config.status. +# Protect against being in an unquoted here document in config.status. +rm -f conftest.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >> conftest.vals <<\EOF +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + +EOF + +cat >> $CONFIG_STATUS <<EOF +ac_sources="$sim_link_files" +ac_dests="$sim_link_links" +EOF + +cat >> $CONFIG_STATUS <<\EOF +srcdir=$ac_given_srcdir +while test -n "$ac_sources"; do + set $ac_dests; ac_dest=$1; shift; ac_dests=$* + set $ac_sources; ac_source=$1; shift; ac_sources=$* + + echo "linking $srcdir/$ac_source to $ac_dest" + + if test ! -r $srcdir/$ac_source; then + { echo "configure: error: $srcdir/$ac_source: File not found" 1>&2; exit 1; } + fi + rm -f $ac_dest + + # Make relative symlinks. + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dest_dir=`echo $ac_dest|sed 's%/[^/][^/]*$%%'` + if test "$ac_dest_dir" != "$ac_dest" && test "$ac_dest_dir" != .; then + # The dest file is in a subdirectory. + test ! -d "$ac_dest_dir" && mkdir "$ac_dest_dir" + ac_dest_dir_suffix="/`echo $ac_dest_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dest_dir_suffix. + ac_dots=`echo $ac_dest_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dest_dir_suffix= ac_dots= + fi + + case "$srcdir" in + [/$]*) ac_rel_source="$srcdir/$ac_source" ;; + *) ac_rel_source="$ac_dots$srcdir/$ac_source" ;; + esac + + # Make a symlink if possible; otherwise try a hard link. + if ln -s $ac_rel_source $ac_dest 2>/dev/null || + ln $srcdir/$ac_source $ac_dest; then : + else + { echo "configure: error: can not link $ac_dest to $srcdir/$ac_source" 1>&2; exit 1; } + fi +done +EOF +cat >> $CONFIG_STATUS <<EOF + +EOF +cat >> $CONFIG_STATUS <<\EOF +case "x$CONFIG_FILES" in + xMakefile*) + echo "Merging Makefile.sim+Make-common.sim into Makefile ..." + rm -f Makesim1.tmp Makesim2.tmp Makefile + sed -n -e '/^## COMMON_PRE_/,/^## End COMMON_PRE_/ p' <Make-common.sim >Makesim1.tmp + sed -n -e '/^## COMMON_POST_/,/^## End COMMON_POST_/ p' <Make-common.sim >Makesim2.tmp + sed -e '/^## COMMON_PRE_/ r Makesim1.tmp' \ + -e '/^## COMMON_POST_/ r Makesim2.tmp' \ + <Makefile.sim >Makefile + rm -f Makefile.sim Make-common.sim Makesim1.tmp Makesim2.tmp + ;; + esac + case "x$CONFIG_HEADERS" in xconfig.h:config.in) echo > stamp-h ;; esac + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + + diff --git a/sim/arm/configure.in b/sim/arm/configure.in new file mode 100644 index 0000000..033b0bc --- /dev/null +++ b/sim/arm/configure.in @@ -0,0 +1,10 @@ +dnl Process this file with autoconf to produce a configure script. +sinclude(../common/aclocal.m4) +AC_PREREQ(2.5)dnl +AC_INIT(Makefile.in) + +SIM_AC_COMMON + +AC_CHECK_HEADERS(unistd.h) + +SIM_AC_OUTPUT diff --git a/sim/arm/dbg_conf.h b/sim/arm/dbg_conf.h new file mode 100644 index 0000000..c0e486f --- /dev/null +++ b/sim/arm/dbg_conf.h @@ -0,0 +1,48 @@ +/* dbg_conf.h -- ARMulator debug interface: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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. */ + +#ifndef Dbg_Conf__h + +#define Dbg_Conf__h + +typedef struct Dbg_ConfigBlock { + int bytesex; + long memorysize; + int serialport; /*) remote connection parameters */ + int seriallinespeed; /*) (serial connection) */ + int parallelport; /*) ditto */ + int parallellinespeed; /*) (parallel connection) */ + int processor; /* processor the armulator is to emulate (eg ARM60) */ + int rditype; /* armulator / remote processor */ + int drivertype; /* parallel / serial / etc */ + char const *configtoload; + int flags; +} Dbg_ConfigBlock; + +#define Dbg_ConfigFlag_Reset 1 + +typedef struct Dbg_HostosInterface Dbg_HostosInterface; +/* This structure allows access by the (host-independent) C-library support + module of armulator or pisd (armos.c) to host-dependent functions for + which there is no host-independent interface. Its contents are unknown + to the debugger toolbox. + The assumption is that, in a windowed system, fputc(stderr) for example + may not achieve the desired effect of the character appearing in some + window. + */ + +#endif diff --git a/sim/arm/dbg_cp.h b/sim/arm/dbg_cp.h new file mode 100644 index 0000000..9f2f93d --- /dev/null +++ b/sim/arm/dbg_cp.h @@ -0,0 +1,62 @@ +/* dbg_cp.h -- ARMulator debug interface: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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. */ + +#ifndef Dbg_CP__h + +#define Dbg_CP__h + +#define Dbg_Access_Readable 1 +#define Dbg_Access_Writable 2 +#define Dbg_Access_CPDT 4 /* else CPRT */ + +typedef struct { + unsigned short rmin, rmax; + /* a single description can be used for a range of registers with + the same properties *accessed via CPDT instructions* + */ + unsigned char nbytes; /* size of register */ + unsigned char access; /* see above (Access_xxx) */ + union { + struct { /* CPDT instructions do not allow the coprocessor much freedom: + only bit 22 ('N') and 12-15 ('CRd') are free for the + coprocessor to use as it sees fit. + */ + unsigned char nbit; + unsigned char rdbits; + } cpdt; + struct { /* CPRT instructions have much more latitude. The bits fixed + by the ARM are 24..31 (condition mask & opcode) + 20 (direction) + 8..15 (cpnum, arm register) + 4 (CPRT not CPDO) + leaving 14 bits free to the coprocessor (fortunately + falling within two bytes). + */ + unsigned char read_b0, read_b1, + write_b0, write_b1; + } cprt; + } accessinst; +} Dbg_CoProRegDesc; + +struct Dbg_CoProDesc { + int entries; + Dbg_CoProRegDesc regdesc[1/* really nentries */]; +}; + +#define Dbg_CoProDesc_Size(n) (sizeof(struct Dbg_CoProDesc) + (n-1)*sizeof(Dbg_CoProRegDesc)) + +#endif diff --git a/sim/arm/dbg_hif.h b/sim/arm/dbg_hif.h new file mode 100644 index 0000000..727b759 --- /dev/null +++ b/sim/arm/dbg_hif.h @@ -0,0 +1,47 @@ +/* dbg_hif.h -- ARMulator debug interface: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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. */ + +#ifdef __STDC__ +# include <stdarg.h> +#else +# include <varargs.h> +#endif + +typedef void Hif_DbgPrint(void *arg, const char *format, va_list ap); +typedef void Hif_DbgPause(void *arg); + +typedef void Hif_WriteC(void *arg, int c); +typedef int Hif_ReadC(void *arg); +typedef int Hif_Write(void *arg, char const *buffer, int len); +typedef char *Hif_GetS(void *arg, char *buffer, int len); + +typedef void Hif_RDIResetProc(void *arg); + +struct Dbg_HostosInterface { + Hif_DbgPrint *dbgprint; + Hif_DbgPause *dbgpause; + void *dbgarg; + + Hif_WriteC *writec; + Hif_ReadC *readc; + Hif_Write *write; + Hif_GetS *gets; + void *hostosarg; + + Hif_RDIResetProc *reset; + void *resetarg; +}; diff --git a/sim/arm/dbg_rdi.h b/sim/arm/dbg_rdi.h new file mode 100644 index 0000000..4ef41e5 --- /dev/null +++ b/sim/arm/dbg_rdi.h @@ -0,0 +1,323 @@ +/* dbg_rdi.h -- ARMulator RDI interface: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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. */ + +#ifndef dbg_rdi__h +#define dbg_rdi__h + +/***************************************************************************\ +* Error Codes * +\***************************************************************************/ + +#define RDIError_NoError 0 + +#define RDIError_Reset 1 +#define RDIError_UndefinedInstruction 2 +#define RDIError_SoftwareInterrupt 3 +#define RDIError_PrefetchAbort 4 +#define RDIError_DataAbort 5 +#define RDIError_AddressException 6 +#define RDIError_IRQ 7 +#define RDIError_FIQ 8 +#define RDIError_Error 9 +#define RDIError_BranchThrough0 10 + +#define RDIError_NotInitialised 128 +#define RDIError_UnableToInitialise 129 +#define RDIError_WrongByteSex 130 +#define RDIError_UnableToTerminate 131 +#define RDIError_BadInstruction 132 +#define RDIError_IllegalInstruction 133 +#define RDIError_BadCPUStateSetting 134 +#define RDIError_UnknownCoPro 135 +#define RDIError_UnknownCoProState 136 +#define RDIError_BadCoProState 137 +#define RDIError_BadPointType 138 +#define RDIError_UnimplementedType 139 +#define RDIError_BadPointSize 140 +#define RDIError_UnimplementedSize 141 +#define RDIError_NoMorePoints 142 +#define RDIError_BreakpointReached 143 +#define RDIError_WatchpointAccessed 144 +#define RDIError_NoSuchPoint 145 +#define RDIError_ProgramFinishedInStep 146 +#define RDIError_UserInterrupt 147 +#define RDIError_CantSetPoint 148 +#define RDIError_IncompatibleRDILevels 149 + +#define RDIError_CantLoadConfig 150 +#define RDIError_BadConfigData 151 +#define RDIError_NoSuchConfig 152 +#define RDIError_BufferFull 153 +#define RDIError_OutOfStore 154 +#define RDIError_NotInDownload 155 +#define RDIError_PointInUse 156 +#define RDIError_BadImageFormat 157 +#define RDIError_TargetRunning 158 + +#define RDIError_LittleEndian 240 +#define RDIError_BigEndian 241 +#define RDIError_SoftInitialiseError 242 + +#define RDIError_InsufficientPrivilege 253 +#define RDIError_UnimplementedMessage 254 +#define RDIError_UndefinedMessage 255 + +/***************************************************************************\ +* RDP Message Numbers * +\***************************************************************************/ + +#define RDP_Start (unsigned char)0x0 +#define RDP_End (unsigned char)0x1 +#define RDP_Read (unsigned char)0x2 +#define RDP_Write (unsigned char)0x3 +#define RDP_CPUread (unsigned char)0x4 +#define RDP_CPUwrite (unsigned char)0x5 +#define RDP_CPread (unsigned char)0x6 +#define RDP_CPwrite (unsigned char)0x7 +#define RDP_SetBreak (unsigned char)0xa +#define RDP_ClearBreak (unsigned char)0xb +#define RDP_SetWatch (unsigned char)0xc +#define RDP_ClearWatch (unsigned char)0xd +#define RDP_Execute (unsigned char)0x10 +#define RDP_Step (unsigned char)0x11 +#define RDP_Info (unsigned char)0x12 +#define RDP_OSOpReply (unsigned char)0x13 + +#define RDP_AddConfig (unsigned char)0x14 +#define RDP_LoadConfigData (unsigned char)0x15 +#define RDP_SelectConfig (unsigned char)0x16 +#define RDP_LoadAgent (unsigned char)0x17 + +#define RDP_Stopped (unsigned char)0x20 +#define RDP_OSOp (unsigned char)0x21 +#define RDP_Fatal (unsigned char)0x5e +#define RDP_Return (unsigned char)0x5f +#define RDP_Reset (unsigned char)0x7f + +/***************************************************************************\ +* Other RDI values * +\***************************************************************************/ + +#define RDISex_Little 0 /* the byte sex of the debuggee */ +#define RDISex_Big 1 +#define RDISex_DontCare 2 + +#define RDIPoint_EQ 0 /* the different types of break/watchpoints */ +#define RDIPoint_GT 1 +#define RDIPoint_GE 2 +#define RDIPoint_LT 3 +#define RDIPoint_LE 4 +#define RDIPoint_IN 5 +#define RDIPoint_OUT 6 +#define RDIPoint_MASK 7 + +#define RDIPoint_Inquiry 64 /* ORRed with point type in extended RDP */ +#define RDIPoint_Handle 128 /* messages */ + +#define RDIWatch_ByteRead 1 /* types of data accesses to watch for */ +#define RDIWatch_HalfRead 2 +#define RDIWatch_WordRead 4 +#define RDIWatch_ByteWrite 8 +#define RDIWatch_HalfWrite 16 +#define RDIWatch_WordWrite 32 + +#define RDIReg_R15 (1L << 15) /* mask values for CPU */ +#define RDIReg_PC (1L << 16) +#define RDIReg_CPSR (1L << 17) +#define RDIReg_SPSR (1L << 18) +#define RDINumCPURegs 19 + +#define RDINumCPRegs 10 /* current maximum */ + +#define RDIMode_Curr 255 + +/* Bits set in return value from RDIInfo_Target */ +#define RDITarget_LogSpeed 0x0f +#define RDITarget_HW 0x10 /* else emulator */ +#define RDITarget_AgentMaxLevel 0xe0 +#define RDITarget_AgentLevelShift 5 +#define RDITarget_DebuggerMinLevel 0x700 +#define RDITarget_DebuggerLevelShift 8 +#define RDITarget_CanReloadAgent 0x800 +#define RDITarget_CanInquireLoadSize 0x1000 + +/* Bits set in return value from RDIInfo_Step */ +#define RDIStep_Multiple 1 +#define RDIStep_PCChange 2 +#define RDIStep_Single 4 + +/* Bits set in return value from RDIInfo_Points */ +#define RDIPointCapability_Comparison 1 +#define RDIPointCapability_Range 2 +/* 4 to 128 are RDIWatch_xx{Read,Write} left-shifted by two */ +#define RDIPointCapability_Mask 256 +#define RDIPointCapability_Status 512 /* Point status enquiries available */ + +/* RDI_Info subcodes */ +#define RDIInfo_Target 0 +#define RDIInfo_Points 1 +#define RDIInfo_Step 2 +#define RDIInfo_MMU 3 +#define RDIInfo_DownLoad 4 /* Inquires whether configuration download + and selection is available. + */ +#define RDIInfo_SemiHosting 5 /* Inquires whether RDISemiHosting_* RDI_Info + calls are available. + */ +#define RDIInfo_CoPro 6 /* Inquires whether CoPro RDI_Info calls are + available. + */ +#define RDIInfo_Icebreaker 7 + +/* The next two are only to be used if the value returned by RDIInfo_Points */ +/* has RDIPointCapability_Status set. */ +#define RDIPointStatus_Watch 0x80 +#define RDIPointStatus_Break 0x81 + +#define RDISignal_Stop 0x100 + +#define RDIVector_Catch 0x180 + +/* The next four are only to be used if RDIInfo_Semihosting returned no error */ +#define RDISemiHosting_SetState 0x181 +#define RDISemiHosting_GetState 0x182 +#define RDISemiHosting_SetVector 0x183 +#define RDISemiHosting_GetVector 0x184 + +/* The next two are only to be used if RDIInfo_Icebreaker returned no error */ +#define RDIIcebreaker_GetLocks 0x185 +#define RDIIcebreaker_SetLocks 0x186 + +/* Only if RDIInfo_Target returned RDITarget_CanInquireLoadSize */ +#define RDIInfo_GetLoadSize 0x187 + +#define RDICycles 0x200 +#define RDICycles_Size 48 +#define RDIErrorP 0x201 + +#define RDISet_Cmdline 0x300 +#define RDISet_RDILevel 0x301 +#define RDISet_Thread 0x302 + +/* The next two are only to be used if RDIInfo_CoPro returned no error */ +#define RDIInfo_DescribeCoPro 0x400 +#define RDIInfo_RequestCoProDesc 0x401 + +#define RDIInfo_Log 0x800 +#define RDIInfo_SetLog 0x801 + +typedef unsigned long PointHandle; +typedef unsigned long ThreadHandle; +#define RDINoPointHandle ((PointHandle)-1L) +#define RDINoHandle ((ThreadHandle)-1L) + +struct Dbg_ConfigBlock; +struct Dbg_HostosInterface; +struct Dbg_MCState; +typedef int rdi_open_proc(unsigned type, struct Dbg_ConfigBlock const *config, + struct Dbg_HostosInterface const *i, + struct Dbg_MCState *dbg_state); +typedef int rdi_close_proc(void); +typedef int rdi_read_proc(ARMword source, void *dest, unsigned *nbytes); +typedef int rdi_write_proc(const void *source, ARMword dest, unsigned *nbytes); +typedef int rdi_CPUread_proc(unsigned mode, unsigned long mask, ARMword *state); +typedef int rdi_CPUwrite_proc(unsigned mode, unsigned long mask, ARMword const *state); +typedef int rdi_CPread_proc(unsigned CPnum, unsigned long mask, ARMword *state); +typedef int rdi_CPwrite_proc(unsigned CPnum, unsigned long mask, ARMword const *state); +typedef int rdi_setbreak_proc(ARMword address, unsigned type, ARMword bound, + PointHandle *handle); +typedef int rdi_clearbreak_proc(PointHandle handle); +typedef int rdi_setwatch_proc(ARMword address, unsigned type, unsigned datatype, + ARMword bound, PointHandle *handle); +typedef int rdi_clearwatch_proc(PointHandle handle); +typedef int rdi_execute_proc(PointHandle *handle); +typedef int rdi_step_proc(unsigned ninstr, PointHandle *handle); +typedef int rdi_info_proc(unsigned type, ARMword *arg1, ARMword *arg2); +typedef int rdi_pointinq_proc(ARMword *address, unsigned type, + unsigned datatype, ARMword *bound); + +typedef enum { + RDI_ConfigCPU, + RDI_ConfigSystem +} RDI_ConfigAspect; + +typedef enum { + RDI_MatchAny, + RDI_MatchExactly, + RDI_MatchNoEarlier +} RDI_ConfigMatchType; + +typedef int rdi_addconfig_proc(unsigned long nbytes); +typedef int rdi_loadconfigdata_proc(unsigned long nbytes, char const *data); +typedef int rdi_selectconfig_proc(RDI_ConfigAspect aspect, char const *name, + RDI_ConfigMatchType matchtype, unsigned versionreq, + unsigned *versionp); + +typedef char *getbufferproc(void *getbarg, unsigned long *sizep); +typedef int rdi_loadagentproc(ARMword dest, unsigned long size, getbufferproc *getb, void *getbarg); + +typedef struct { + int itemmax; + char const * const *names; +} RDI_NameList; + +typedef RDI_NameList const *rdi_namelistproc(void); + +typedef int rdi_errmessproc(char *buf, int buflen, int errno); + +struct RDIProcVec { + char rditypename[12]; + + rdi_open_proc *open; + rdi_close_proc *close; + rdi_read_proc *read; + rdi_write_proc *write; + rdi_CPUread_proc *CPUread; + rdi_CPUwrite_proc *CPUwrite; + rdi_CPread_proc *CPread; + rdi_CPwrite_proc *CPwrite; + rdi_setbreak_proc *setbreak; + rdi_clearbreak_proc *clearbreak; + rdi_setwatch_proc *setwatch; + rdi_clearwatch_proc *clearwatch; + rdi_execute_proc *execute; + rdi_step_proc *step; + rdi_info_proc *info; + /* V2 RDI */ + rdi_pointinq_proc *pointinquiry; + + /* These three useable only if RDIInfo_DownLoad returns no error */ + rdi_addconfig_proc *addconfig; + rdi_loadconfigdata_proc *loadconfigdata; + rdi_selectconfig_proc *selectconfig; + + rdi_namelistproc *drivernames; + rdi_namelistproc *cpunames; + + rdi_errmessproc *errmess; + + /* Only if RDIInfo_Target returns a value with RDITarget_LoadAgent set */ + rdi_loadagentproc *loadagent; +}; + +#endif + + + + + + diff --git a/sim/arm/gdbhost.c b/sim/arm/gdbhost.c new file mode 100644 index 0000000..4d93842 --- /dev/null +++ b/sim/arm/gdbhost.c @@ -0,0 +1,107 @@ +/* gdbhost.c -- ARMulator RDP to gdb comms code: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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. */ + +/***********************************************************/ +/* Functions that communicate info back to the debugger... */ +/***********************************************************/ + +#include <stdio.h> +#include <stdarg.h> +#include "armdefs.h" +#include "communicate.h" +#include "dbg_rdi.h" +#include "armos.h" + +#define OS_SendNothing 0x0 +#define OS_SendChar 0x1 +#define OS_SendWord 0x2 +#define OS_SendString 0x3 + +/* Defined in kid.c */ +extern int wait_for_osreply(ARMword *reply); + +/* A pipe for handling SWI return values that goes straight from the */ +/* parent to the ARMulator host interface, bypassing the childs RDP */ +/* to RDI interpreter */ +int DebuggerARMul[2]; + +/* The pipes between the two processes */ +int mumkid[2]; +int kidmum[2]; + +void myprint (void *arg, const char *format, va_list ap) +{ +#ifdef DEBUG + fprintf (stderr, "Host: myprint\n"); +#endif + vfprintf (stderr, format, ap); +} + + +/* Waits for a keypress on the debuggers' keyboard */ +void mypause (void *arg) +{ +#ifdef DEBUG + fprintf (stderr, "Host: mypause\n"); +#endif +} /* I do love exciting functions */ + +void mywritec(void *arg, int c) +{ +#ifdef DEBUG + fprintf(stderr, "Mywrite : %c\n", c); +#endif + MYwrite_char(kidmum[1], RDP_OSOp); /* OS Operation Request Message */ + MYwrite_word(kidmum[1], SWI_WriteC); /* Print... */ + MYwrite_char(kidmum[1], OS_SendChar); /* ...a single character */ + MYwrite_char(kidmum[1], (unsigned char) c); + + wait_for_osreply((ARMword *) 0); +} + +int myreadc(void *arg) +{ + char c; + ARMword x; + +#ifdef DEBUG + fprintf(stderr, "Host: myreadc\n"); +#endif + MYwrite_char(kidmum[1], RDP_OSOp); /* OS Operation Request Message */ + MYwrite_word(kidmum[1], SWI_ReadC); /* Read... */ + MYwrite_char(kidmum[1], OS_SendNothing); + + c = wait_for_osreply(&x); + return (x); +} + + +int mywrite(void *arg, char const *buffer, int len) +{ +#ifdef DEBUG + fprintf(stderr, "Host: mywrite\n"); +#endif + return 0; +} + +char *mygets(void *arg, char *buffer, int len) +{ +#ifdef DEBUG + fprintf(stderr, "Host: mygets\n"); +#endif + return buffer; +} diff --git a/sim/arm/gdbhost.h b/sim/arm/gdbhost.h new file mode 100644 index 0000000..e1bfd24 --- /dev/null +++ b/sim/arm/gdbhost.h @@ -0,0 +1,23 @@ +/* gdbhost.h -- ARMulator to gdb interface: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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. */ + +void myprint(void *arg, const char *format, va_list ap); +void mypause(void *arg); +void mywritec(void *arg, int c); +int myreadc(void *arg); +int mywrite(void *arg, char const *buffer, int len); +char *mygets(void *arg, char *buffer, int len); diff --git a/sim/arm/kid.c b/sim/arm/kid.c new file mode 100644 index 0000000..10e3f358 --- /dev/null +++ b/sim/arm/kid.c @@ -0,0 +1,510 @@ +/* kid.c -- ARMulator RDP/RDI interface: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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. */ + +/*****************************************************************/ +/* The child process continues here... */ +/* It waits on a pipe from the parent and translates the RDP */ +/* messages into RDI calls to the ARMulator passing RDP replies */ +/* back up a pipe to the parent. */ +/*****************************************************************/ + +#include <sys/types.h> +#include <signal.h> + +#include "armdefs.h" +#include "dbg_conf.h" +#include "dbg_hif.h" +#include "dbg_rdi.h" +#include "gdbhost.h" +#include "communicate.h" + +/* The pipes between the two processes */ +extern int mumkid[2]; +extern int kidmum[2]; + +/* The maximum number of file descriptors */ +extern int nfds; + +/* The machine name */ +#define MAXHOSTNAMELENGTH 64 +extern char localhost[MAXHOSTNAMELENGTH + 1]; + +/* The socket number */ +extern unsigned int socketnumber; + +/* RDI interface */ +extern const struct RDIProcVec armul_rdi; + +static int MYrdp_level = 0; + +static int rdi_state = 0; + +/**************************************************************/ +/* Signal handler that terminates excecution in the ARMulator */ +/**************************************************************/ +void kid_handlesignal(int sig) { +#ifdef DEBUG + fprintf(stderr, "Terminate ARMulator excecution\n"); +#endif + if (sig != SIGUSR1) { + fprintf(stderr, "Unsupported signal.\n"); + return; + } + armul_rdi.info(RDISignal_Stop, (unsigned long *) 0, (unsigned long *) 0); +} + +/********************************************************************/ +/* Waits on a pipe from the socket demon for RDP and */ +/* acts as an RDP to RDI interpreter on the front of the ARMulator. */ +/********************************************************************/ +void kid() { + char *p, *q; + int i, j, k; + long outofthebag; + unsigned char c, d, message; + ARMword x, y, z; + struct sigaction action; + PointHandle point; + Dbg_ConfigBlock config; + Dbg_HostosInterface hostif; + struct Dbg_MCState *MCState; + char command_line[256]; + struct fd_set readfds; + + /* Setup a signal handler for SIGUSR1 */ + action.sa_handler = kid_handlesignal; + action.sa_mask = 0; + action.sa_flags = 0; + + sigaction(SIGUSR1, &action, (struct sigaction *) 0); + + while (1) + { + /* Wait for ever */ + FD_ZERO(&readfds); + FD_SET(mumkid[0], &readfds); + + i = select(nfds, &readfds, + (fd_set *) 0, + (fd_set *) 0, + (struct timeval *) 0); + + if (i < 0) { + perror("select"); + } + + if (read(mumkid[0], &message, 1) < 1) { + perror("read"); + } + + switch (message) { + case RDP_Start : + /* Open and/or Initialise */ + BAG_newbag(); + + MYread_char(mumkid[0], &c); /* type */ + MYread_word(mumkid[0], &x); /* memorysize */ + if (c & 0x2) MYread_char(mumkid[0], &d); /* speed */ + config.processor = 0; + config.memorysize = x; + config.bytesex = (c & 0x4) ? RDISex_Big : RDISex_Little; + if (c & 0x8) config.bytesex = RDISex_DontCare; + + hostif.dbgprint = myprint; + hostif.dbgpause = mypause; + hostif.dbgarg = stdout; + hostif.writec = mywritec; + hostif.readc = myreadc; + hostif.write = mywrite; + hostif.gets = mygets; + hostif.reset = mypause; /* do nothing */ + hostif.resetarg = "Do I love resetting or what!\n"; + + if (rdi_state) + { + /* we have restarted, so kill off the existing run. */ + /* armul_rdi.close(); */ + } + i = armul_rdi.open(c & 0x3, &config, &hostif, MCState); + rdi_state = 1; + + MYwrite_char(kidmum[1], RDP_Return); + MYwrite_char(kidmum[1], (unsigned char) i); + + x = ~0x4; + armul_rdi.info(RDIVector_Catch, &x, 0); + + break; + + case RDP_End : + /* Close and Finalise */ + i = armul_rdi.close(); + rdi_state = 0; + MYwrite_char(kidmum[1], RDP_Return); + MYwrite_char(kidmum[1], (unsigned char) i); + break; + + case RDP_Read : + /* Read Memory Address */ + MYread_word(mumkid[0], &x); /* address */ + MYread_word(mumkid[0], &y); /* nbytes */ + p = (char *) malloc(y); + i = armul_rdi.read(x, p, (unsigned *) &y); + MYwrite_char(kidmum[1], RDP_Return); + for (k = 0; k < y; k++) + MYwrite_char(kidmum[1], p[k]); + free(p); + MYwrite_char(kidmum[1], (unsigned char) i); + if (i) + MYwrite_word(kidmum[1], y); /* number of bytes sent without error */ + break; + + case RDP_Write : + /* Write Memory Address */ + MYread_word(mumkid[0], &x); /* address */ + MYread_word(mumkid[0], &y); /* nbytes */ + p = (char *) malloc(y); + for (k = 0; k < y; k++) + MYread_char(mumkid[0], &p[k]); + i = armul_rdi.write(p, x, (unsigned *) &y); + free(p); + MYwrite_char(kidmum[1], RDP_Return); + MYwrite_char(kidmum[1], (unsigned char) i); + if (i) + MYwrite_word(kidmum[1], y); /* number of bytes sent without error */ + break; + + case RDP_CPUread : + /* Read CPU State */ + MYread_char(mumkid[0], &c); /* mode */ + MYread_word(mumkid[0], &x); /* mask */ + p = (char *) malloc(4 * RDINumCPURegs); + i = armul_rdi.CPUread(c, x, (ARMword *) p); + MYwrite_char(kidmum[1], RDP_Return); + for (k = 1, j = 0; k != 0x80000000; k *= 2) + if (k & x) MYwrite_word(kidmum[1], ((ARMword *) p)[j++]); + free(p); + if (i) MYwrite_char(kidmum[1], (unsigned char) j); + MYwrite_char(kidmum[1], (unsigned char) i); + break; + + case RDP_CPUwrite : + /* Write CPU State */ + MYread_char(mumkid[0], &c); /* mode */ + MYread_word(mumkid[0], &x); /* mask */ + + p = (char *) malloc(4 * RDINumCPURegs); + for (k = 1, j = 0; k != 0x80000000; k *= 2) + if (k & x) MYread_word(mumkid[0], &(((ARMword *) p)[j++])); + i = armul_rdi.CPUwrite(c, x, (ARMword *) p); + MYwrite_char(kidmum[1], RDP_Return); + MYwrite_char(kidmum[1], (unsigned char) i); + free(p); + break; + + case RDP_CPread : + /* Read Co-Processor State */ + MYread_char(mumkid[0], &c); /* CPnum */ + MYread_word(mumkid[0], &x); /* mask */ + p = q = (char *) malloc(16 * RDINumCPRegs); + i = armul_rdi.CPread(c, x, (ARMword *) p); + MYwrite_char(kidmum[1], RDP_Return); + for (k = 1, j = 0; k != 0x80000000; k *= 2, j++) + if (k & x) { + if ((c == 1 || c == 2) && k <= 128) { + MYwrite_FPword(kidmum[1], q); + q += 16; + } + else { + MYwrite_word(kidmum[1], *q); + q += 4; + } + } + free(p); + if (i) MYwrite_char(kidmum[1], (unsigned char) j); + MYwrite_char(kidmum[1], (unsigned char) i); + break; + + case RDP_CPwrite : + /* Write Co-Processor State */ + MYread_char(mumkid[0], &c); /* CPnum */ + MYread_word(mumkid[0], &x); /* mask */ + p = q = (char *) malloc(16 * RDINumCPURegs); + for (k = 1, j = 0; k != 0x80000000; k *= 2, j++) + if (k & x) { + if ((c == 1 || c == 2) && k <= 128) { + MYread_FPword(kidmum[1], q); + q += 16; + } + else { + MYread_word(mumkid[0], (ARMword *) q); + q += 4; + } + } + i = armul_rdi.CPwrite(c, x, (ARMword *) p); + MYwrite_char(kidmum[1], RDP_Return); + MYwrite_char(kidmum[1], (unsigned char) i); + free(p); + break; + + case RDP_SetBreak : + /* Set Breakpoint */ + MYread_word(mumkid[0], &x); /* address */ + MYread_char(mumkid[0], &c); /* type */ + if ((c & 0xf) >= 5) MYread_word(mumkid[0], &y); /* bound */ + i = armul_rdi.setbreak(x, c, y, &point); + if (!MYrdp_level) BAG_putpair((long) x, (long) point); + MYwrite_char(kidmum[1], RDP_Return); + if (MYrdp_level) MYwrite_word(kidmum[1], point); + MYwrite_char(kidmum[1], (unsigned char) i); + break; + + case RDP_ClearBreak : + /* Clear Breakpoint */ + MYread_word(mumkid[0], &point); /* PointHandle */ + if (!MYrdp_level) { + BAG_getsecond((long) point, &outofthebag); /* swap pointhandle for address */ + BAG_killpair_byfirst(outofthebag); + point = outofthebag; + } + i = armul_rdi.clearbreak(point); + MYwrite_char(kidmum[1], RDP_Return); + MYwrite_char(kidmum[1], (unsigned char) i); + break; + + case RDP_SetWatch : + /* Set Watchpoint */ + MYread_word(mumkid[0], &x); /* address */ + MYread_char(mumkid[0], &c); /* type */ + MYread_char(mumkid[0], &d); /* datatype */ + if ((c & 0xf) >= 5) MYread_word(mumkid[0], &y); /* bound */ + i = armul_rdi.setwatch(x, c, d, y, &point); + MYwrite_char(kidmum[1], RDP_Return); + MYwrite_word(kidmum[1], point); + MYwrite_char(kidmum[1], (unsigned char) i); + break; + + case RDP_ClearWatch : + /* Clear Watchpoint */ + MYread_word(mumkid[0], &point); /* PointHandle */ + i = armul_rdi.clearwatch(point); + MYwrite_char(kidmum[1], RDP_Return); + MYwrite_char(kidmum[1], (unsigned char) i); + break; + + case RDP_Execute : + /* Excecute */ + + MYread_char(mumkid[0], &c); /* return */ + +#ifdef DEBUG + fprintf(stderr, "Starting execution\n"); +#endif + i = armul_rdi.execute(&point); +#ifdef DEBUG + fprintf(stderr, "Completed execution\n"); +#endif + MYwrite_char(kidmum[1], RDP_Return); + if (c & 0x80) MYwrite_word(kidmum[1], point); + MYwrite_char(kidmum[1], (unsigned char) i); + break; + + case RDP_Step : + /* Step */ + MYread_char(mumkid[0], &c); /* return */ + MYread_word(mumkid[0], &x); /* ninstr */ + point = 0x87654321; + i = armul_rdi.step(x, &point); + MYwrite_char(kidmum[1], RDP_Return); + if (c & 0x80) MYwrite_word(kidmum[1], point); + MYwrite_char(kidmum[1], (unsigned char) i); + break; + + case RDP_Info: + /* Info */ + MYread_word (mumkid[0], &x); + switch (x) + { + case RDIInfo_Target: + i = armul_rdi.info (RDIInfo_Target, &y, &z); + MYwrite_char (kidmum[1], RDP_Return); + MYwrite_word (kidmum[1], y); /* Loads of info... */ + MYwrite_word (kidmum[1], z); /* Model */ + MYwrite_char (kidmum[1], (unsigned char) i); + break; + + case RDISet_RDILevel: + MYread_word (mumkid[0], &x); /* arg1, debug level */ + i = armul_rdi.info (RDISet_RDILevel, &x, 0); + if (i == RDIError_NoError) + MYrdp_level = x; + MYwrite_char (kidmum[1], RDP_Return); + MYwrite_char (kidmum[1], (unsigned char) i); + break; + + case RDISet_Cmdline: + for (p = command_line; MYread_char (mumkid[0], p), *p; p++) + ; /* String */ + i = armul_rdi.info (RDISet_Cmdline, + (unsigned long *) command_line, 0); + MYwrite_char (kidmum[1], RDP_Return); + MYwrite_char (kidmum[1], (unsigned char) i); + break; + + case RDIInfo_Step: + i = armul_rdi.info (RDIInfo_Step, &x, 0); + MYwrite_char (kidmum[1], RDP_Return); + MYwrite_word (kidmum[1], x); + MYwrite_char (kidmum[1], (unsigned char) i); + break; + + case RDIVector_Catch: + MYread_word (mumkid[0], &x); + i = armul_rdi.info (RDIVector_Catch, &x, 0); + MYwrite_char (kidmum[1], RDP_Return); + MYwrite_char (kidmum[1], i); + break; + + case RDIInfo_Points: + i = armul_rdi.info (RDIInfo_Points, &x, 0); + MYwrite_char (kidmum[1], RDP_Return); + MYwrite_word (kidmum[1], x); + MYwrite_char (kidmum[1], (unsigned char) i); + break; + + default: + fprintf (stderr, "Unsupported info code %d\n", x); + break; + } + break; + + case RDP_OSOpReply: + /* OS Operation Reply */ + MYwrite_char (kidmum[1], RDP_Fatal); + break; + + case RDP_Reset: + /* Reset */ + for (i = 0; i < 50; i++) + MYwrite_char(kidmum[1], RDP_Reset); + p = (char *) malloc(MAXHOSTNAMELENGTH + 5 + 20); + sprintf(p, "Running on %s:%d\n", localhost, socketnumber); + MYwrite_string(kidmum[1], p); + free(p); + + break; + default: + fprintf (stderr, "Oh dear: Something is seriously wrong :-(\n"); + /* Hmm.. bad RDP operation */ + break; + } + } +} + + +/* Handles memory read operations until an OS Operation Reply Message is */ +/* encounterd. It then returns the byte info value (0, 1, or 2) and fills */ +/* in 'putinr0' with the data if appropriate. */ +int wait_for_osreply(ARMword *reply) +{ + char *p, *q; + int i, j, k; + unsigned char c, d, message; + ARMword x, y, z; + struct sigaction action; + PointHandle point; + Dbg_ConfigBlock config; + Dbg_HostosInterface hostif; + struct Dbg_MCState *MCState; + char command_line[256]; + struct fd_set readfds; + +#ifdef DEBUG + fprintf(stderr, "wait_for_osreply ().\n"); +#endif + + /* Setup a signal handler for SIGUSR1 */ + action.sa_handler = kid_handlesignal; + action.sa_mask = 0; + action.sa_flags = 0; + + sigaction(SIGUSR1, &action, (struct sigaction *) 0); + + while (1) + { + /* Wait for ever */ + FD_ZERO(&readfds); + FD_SET(mumkid[0], &readfds); + + i = select(nfds, &readfds, + (fd_set *) 0, + (fd_set *) 0, + (struct timeval *) 0); + + if (i < 0) { + perror("select"); + } + + if (read(mumkid[0], &message, 1) < 1) { + perror("read"); + } + + switch (message) { + case RDP_Read : + /* Read Memory Address */ + MYread_word(mumkid[0], &x); /* address */ + MYread_word(mumkid[0], &y); /* nbytes */ + p = (char *) malloc(y); + i = armul_rdi.read(x, p, (unsigned *) &y); + MYwrite_char(kidmum[1], RDP_Return); + for (k = 0; k < y; k++) + MYwrite_char(kidmum[1], p[k]); + free(p); + MYwrite_char(kidmum[1], (unsigned char) i); + if (i) + MYwrite_word(kidmum[1], y); /* number of bytes sent without error */ + break; + + case RDP_Write : + /* Write Memory Address */ + MYread_word(mumkid[0], &x); /* address */ + MYread_word(mumkid[0], &y); /* nbytes */ + p = (char *) malloc(y); + for (k = 0; k < y; k++) + MYread_char(mumkid[0], &p[k]); + i = armul_rdi.write(p, x, (unsigned *) &y); + free(p); + MYwrite_char(kidmum[1], RDP_Return); + MYwrite_char(kidmum[1], (unsigned char) i); + if (i) + MYwrite_word(kidmum[1], y); /* number of bytes sent without error */ + break; + + case RDP_OSOpReply : + /* OS Operation Reply */ + MYread_char(mumkid[0], &c); + if (c == 1) MYread_char(mumkid[0], (char *) reply); + if (c == 2) MYread_word(mumkid[0], reply); + return c; + break; + + default : + fprintf(stderr, "HELP! Unaccounted-for message during OS request. \n"); + MYwrite_char(kidmum[1], RDP_Fatal); + } + } +} diff --git a/sim/arm/main.c b/sim/arm/main.c new file mode 100644 index 0000000..f012b28 --- /dev/null +++ b/sim/arm/main.c @@ -0,0 +1,183 @@ +/* main.c -- top level of ARMulator: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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. */ + +/**********************************************************************/ +/* Forks the ARMulator and hangs on a socket passing on RDP messages */ +/* down a pipe to the ARMulator which translates them into RDI calls. */ +/**********************************************************************/ + +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <signal.h> +#include <netdb.h> +#include <unistd.h> + +#include "armdefs.h" +#include "dbg_rdi.h" +#include "dbg_conf.h" + +#define MAXHOSTNAMELENGTH 64 + +/* Read and write routines down sockets and pipes */ + +void MYread_chars(int sock, void *p, int n); +unsigned char MYread_char(int sock); +ARMword MYread_word(int sock); +void MYread_FPword(int sock, char *putinhere); + +void MYwrite_word(int sock, ARMword i); +void MYwrite_string(int sock, char *s); +void MYwrite_FPword(int sock, char *fromhere); +void MYwrite_char(int sock, unsigned char c); + +void passon(int source, int dest, int n); + + +/* Mother and child processes */ +void parent (void); +void kid(void); + +/* The child process id. */ +pid_t child; + +/* The socket to the debugger */ +int debugsock; + +/* The pipes between the two processes */ +int mumkid[2]; +int kidmum[2]; + +/* A pipe for handling SWI return values that goes straight from the */ +/* parent to the ARMulator host interface, bypassing the childs RDP */ +/* to RDI interpreter */ +int DebuggerARMul[2]; + +/* The maximum number of file descriptors */ +int nfds; + +/* The socket handle */ +int sockethandle; + +/* The machine name */ +char localhost[MAXHOSTNAMELENGTH + 1]; + +/* The socket number */ +unsigned int socketnumber; + +/**************************************************************/ +/* Takes one argument: the socket number. */ +/* Opens a socket to the debugger, and once opened spawns the */ +/* ARMulator and sets up a couple of pipes. */ +/**************************************************************/ +int main(int argc, char *argv[]) { + int i; + struct sockaddr_in devil, isa; + struct hostent *hp; + + + if (argc == 1) { + fprintf(stderr, "No socket number\n"); + return 1; + } + + sscanf(argv[1], "%d", &socketnumber); + if (!socketnumber || socketnumber > 0xffff) { + fprintf(stderr, "Invalid socket number: %d\n", socketnumber); + return 1; + } + + gethostname(localhost, MAXHOSTNAMELENGTH); + hp = gethostbyname(localhost); + if (!hp) { + fprintf(stderr, "Cannot get local host info\n"); + return 1; + } + + /* Open a socket */ + sockethandle = socket(hp->h_addrtype, SOCK_STREAM, 0); + if (sockethandle < 0) { + perror("socket"); + return 1; + } + + devil.sin_family = hp->h_addrtype; + devil.sin_port = htons(socketnumber); + devil.sin_addr.s_addr = 0; + for(i = 0; i < sizeof(devil.sin_zero); i++) devil.sin_zero[i] = '\000'; + memcpy(&devil.sin_addr, hp->h_addr_list[0], hp->h_length); + + if (bind(sockethandle, &devil, sizeof(devil)) < 0) { + perror("bind"); + return 1; + } + + /* May only accept one debugger at once */ + + if (listen(sockethandle, 0)) { + perror("listen"); + return 1; + } + + fprintf(stderr, "Waiting for connection from debugger..."); + + debugsock = accept(sockethandle, &isa, &i); + if (debugsock < 0) { + perror("accept"); + return 1; + } + + fprintf(stderr, " done.\nConnection Established.\n"); + + nfds = getdtablesize(); + + if (pipe(mumkid)) { + perror("pipe"); + return 1; + } + if (pipe(kidmum)) { + perror("pipe"); + return 1; + } + + if (pipe(DebuggerARMul)) { + perror("pipe"); + return 1; + } + +#ifdef DEBUG + fprintf(stderr, "Created pipes ok\n"); +#endif + + child = fork(); + +#ifdef DEBUG + fprintf(stderr, "fork() ok\n"); +#endif + + if (child == 0) kid (); + if (child != -1) parent (); + + perror("fork"); + return 1; +} + + + + diff --git a/sim/arm/parent.c b/sim/arm/parent.c new file mode 100644 index 0000000..21da643 --- /dev/null +++ b/sim/arm/parent.c @@ -0,0 +1,483 @@ +/* parent.c -- ARMulator RDP comms code: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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. */ + +/*****************************************************************/ +/* The Parent process continues here... */ +/* It waits on the socket and passes on RDP messages down a pipe */ +/* to the ARMulator RDP to RDI interpreter. */ +/*****************************************************************/ + +#include <stdio.h> +#include <sys/types.h> +#include <signal.h> +#include "time.h" +#include "armdefs.h" +#include "dbg_rdi.h" +#include "communicate.h" + +/* The socket to the debugger */ +extern int debugsock; + +/* The pipes between the two processes */ +extern int mumkid[2]; +extern int kidmum[2]; + +/* A pipe for handling SWI return values that goes straight from the */ +/* parent to the ARMulator host interface, bypassing the child's RDP */ +/* to RDI interpreter */ +extern int DebuggerARMul[2]; + +/* The maximum number of file descriptors */ +extern int nfds; + +/* The child process id. */ +extern pid_t child; + +void +parent () +{ + int i, j, k; + unsigned char message, CPnum, exreturn; + ARMword mask, nbytes, messagetype; + unsigned char c, d; + ARMword x, y; + int virgin = 1; + struct fd_set readfds; + +#ifdef DEBUG + fprintf (stderr, "parent ()...\n"); +#endif + + panic_error: + + if (!virgin) + { +#ifdef DEBUG + fprintf(stderr, "Arghh! What is going on?\n"); +#endif + kill (child, SIGHUP); + MYwrite_char(debugsock, RDP_Reset); + } + + virgin = 0; + + while (1) + { + + /* Wait either for the ARMulator or the debugger */ + + FD_ZERO (&readfds); + FD_SET (kidmum[0], &readfds); /* Wait for messages from ARMulator */ + FD_SET (debugsock, &readfds); /* Wait for messages from debugger */ + +#ifdef DEBUG + fprintf (stderr, "Waiting for ARMulator or debugger... "); +#endif + + while ((i = select (nfds, &readfds, (fd_set *) 0, (fd_set *) 0, 0)) < 0) + { + perror ("select"); + } + +#ifdef DEBUG + fprintf(stderr, "(%d/2)", i); +#endif + + if (FD_ISSET (debugsock, &readfds)) { +#ifdef DEBUG + fprintf (stderr, "->debugger\n"); +#endif + + /* Inside this rather large if statement with simply pass on a complete + message to the ARMulator. The reason we need to pass messages on one + at a time is that we have to know whether the message is an OSOpReply + or an info(stop), so that we can take different action in those + cases. */ + + if (MYread_char (debugsock, &message)) + goto panic_error; + + switch (message) + { + case RDP_Start: + /* Open and/or Initialise */ +#ifdef DEBUG + fprintf (stderr, "RDP Open\n"); +#endif + if (MYread_char(debugsock, &c)) /* type */ + goto panic_error; + + if (MYread_word(debugsock, &x)) /* memory size */ + goto panic_error; + + MYwrite_char (mumkid[1], message); + MYwrite_char (mumkid[1], c); + MYwrite_word (mumkid[1], x); + if (c & 0x2) + { + passon (debugsock, mumkid[1], 1); /* speed */ + } + break; + + case RDP_End: + /* Close and Finalise */ +#ifdef DEBUG + fprintf(stderr, "RDP Close\n"); +#endif + MYwrite_char (mumkid[1], message); + break; + + case RDP_Read: + /* Read Memory Address */ +#ifdef DEBUG + fprintf (stderr, "RDP Read Memory\n"); +#endif + MYwrite_char (mumkid[1], message); + if (passon (debugsock, mumkid[1], 4)) + goto panic_error; /* address */ + if (MYread_word(debugsock, &nbytes)) + goto panic_error; /* nbytes */ + MYwrite_word (mumkid[1], nbytes); + break; + + case RDP_Write : + /* Write Memory Address */ +#ifdef DEBUG + fprintf (stderr, "RDP Write Memory\n"); +#endif + if (MYread_word (debugsock, &x)) + goto panic_error; /* address */ + + if (MYread_word (debugsock, &y)) + goto panic_error; /* nbytes */ + + MYwrite_char (mumkid[1], message); + MYwrite_word (mumkid[1], x); + MYwrite_word (mumkid[1], y); + passon (debugsock, mumkid[1], y); /* actual data */ + break; + + case RDP_CPUread: + /* Read CPU State */ +#ifdef DEBUG + fprintf (stderr, "RDP Read CPU\n"); +#endif + if (MYread_char(debugsock, &c)) + goto panic_error; /* mode */ + + if (MYread_word (debugsock, &mask)) + goto panic_error; /* mask */ + + MYwrite_char (mumkid[1], message); + MYwrite_char (mumkid[1], c); + MYwrite_word (mumkid[1], mask); + break; + + case RDP_CPUwrite : + /* Write CPU State */ +#ifdef DEBUG + fprintf (stderr, "RDP Write CPU\n"); +#endif + if (MYread_char (debugsock, &c)) + goto panic_error; /* mode */ + + if (MYread_word (debugsock, &x)) + goto panic_error; /* mask */ + + MYwrite_char (mumkid[1], message); + MYwrite_char (mumkid[1], c); + MYwrite_word (mumkid[1], x); + for (k = 1, j = 0; k != 0x80000000; k *= 2, j++) + if ((k & x) + && passon(debugsock, mumkid[1], 4)) + goto panic_error; + break; + + case RDP_CPread: + /* Read Co-Processor State */ +#ifdef DEBUG + fprintf (stderr, "RDP Read CP state\n"); +#endif + if (MYread_char (debugsock, &CPnum)) + goto panic_error; + + if (MYread_word (debugsock, &mask)) + goto panic_error; + + MYwrite_char (mumkid[1], message); + MYwrite_char (mumkid[1], CPnum); + MYwrite_word (mumkid[1], mask); + break; + + case RDP_CPwrite: + /* Write Co-Processor State */ +#ifdef DEBUG + fprintf(stderr, "RDP Write CP state\n"); +#endif + if (MYread_char (debugsock, &CPnum)) + goto panic_error; + + if (MYread_word (debugsock, &mask)) + goto panic_error; + + MYwrite_char (mumkid[1], message); + MYwrite_char (mumkid[1], c); + MYwrite_char (mumkid[1], x); + for (k = 1, j = 0; k != 0x80000000; k *= 2, j++) + if (k & x) + { + if ((c == 1 || c == 2) && k <= 128) + { + /* FP register = 12 bytes + 4 bytes format */ + if (passon(debugsock, mumkid[1], 16)) + goto panic_error; + } + else + { + /* Normal register = 4 bytes */ + if (passon(debugsock, mumkid[1], 4)) + goto panic_error; + } + } + break; + + case RDP_SetBreak: + /* Set Breakpoint */ +#ifdef DEBUG + fprintf (stderr, "RDP Set Breakpoint\n"); +#endif + if (MYread_word (debugsock, &x)) + goto panic_error; /* address */ + + if (MYread_char (debugsock, &c)) + goto panic_error; /* type */ + + MYwrite_char (mumkid[1], message); + MYwrite_word (mumkid[1], x); + MYwrite_char (mumkid[1], c); + if (((c & 0xf) >= 5) + && passon(debugsock, mumkid[1], 4)) + goto panic_error; /* bound */ + break; + + case RDP_ClearBreak: + /* Clear Breakpoint */ +#ifdef DEBUG + fprintf (stderr, "RDP Clear Breakpoint\n"); +#endif + MYwrite_char (mumkid[1], message); + if (passon (debugsock, mumkid[1], 4)) + goto panic_error; /* point */ + break; + + case RDP_SetWatch: + /* Set Watchpoint */ +#ifdef DEBUG + fprintf (stderr, "RDP Set Watchpoint\n"); +#endif + if (MYread_word (debugsock, &x)) + goto panic_error; /* address */ + + if (MYread_char(debugsock, &c)) + goto panic_error; /* type */ + + if (MYread_char (debugsock, &d)) + goto panic_error; /* datatype */ + + MYwrite_char (mumkid[1], message); + MYwrite_word (mumkid[1], x); + MYwrite_char (mumkid[1], c); + MYwrite_char (mumkid[1], d); + if (((c & 0xf) >= 5) + && passon(debugsock, mumkid[1], 4)) + goto panic_error; /* bound */ + break; + + case RDP_ClearWatch: + /* Clear Watchpoint */ +#ifdef DEBUG + fprintf (stderr, "RDP Clear Watchpoint\n"); +#endif + MYwrite_char (mumkid[1], message); + if (passon (debugsock, mumkid[1], 4)) + goto panic_error; /* point */ + break; + + case RDP_Execute: + /* Excecute */ +#ifdef DEBUG + fprintf (stderr, "RDP Execute\n"); +#endif + + /* LEAVE THIS ONE 'TIL LATER... */ + /* NEED TO WORK THINGS OUT */ + + /* NO ASCYNCHROUS RUNNING */ + + if (MYread_char(debugsock, &c)) + goto panic_error; /* return */ + + /* Remember incase bit 7 is set and we have to send back a word */ + exreturn = c; + + MYwrite_char(mumkid[1], message); + MYwrite_char(mumkid[1], c); + break; + + case RDP_Step: + /* Step */ +#ifdef DEBUG + fprintf (stderr, "RDP Step\n"); +#endif + + if (MYread_char(debugsock, &c)) + goto panic_error; /* return */ + + if (MYread_word(debugsock, &x)) + goto panic_error; /* ninstr */ + + MYwrite_char (mumkid[1], message); + MYwrite_char (mumkid[1], c); + MYwrite_word (mumkid[1], x); + break; + + case RDP_Info: + /* Info */ +#ifdef DEBUG + fprintf (stderr, "RDP Info\n"); +#endif + /* INFO TARGET, SET RDI LEVEL */ + if (MYread_word (debugsock, &messagetype)) + goto panic_error; /* info */ + + switch (messagetype) + { + case RDIInfo_Target: + MYwrite_char (mumkid[1], message); + MYwrite_word (mumkid[1], messagetype); + break; + + case RDISet_RDILevel: + MYwrite_char (mumkid[1], message); + MYwrite_word (mumkid[1], messagetype); + if (passon (debugsock, mumkid[1], 1)) + goto panic_error; /* argument */ + break; + + case RDISet_Cmdline: + /* Got to pass on a string argument */ + MYwrite_char (mumkid[1], message); + MYwrite_word (mumkid[1], messagetype); + do + { + if (MYread_char (debugsock, &c)) + goto panic_error; + + MYwrite_char (mumkid[1], c); + } while (c); + break; + + case RDISignal_Stop: + kill (child, SIGUSR1); + MYwrite_char (debugsock, RDP_Return); + MYwrite_char (debugsock, RDIError_UserInterrupt); + break; + + case RDIVector_Catch: + MYread_word (debugsock, &x); + MYwrite_char (mumkid[1], message); + MYwrite_word (mumkid[1], messagetype); + MYwrite_word (mumkid[1], x); + break; + + case RDIInfo_Step: + MYwrite_char (mumkid[1], message); + MYwrite_word (mumkid[1], messagetype); + break; + + case RDIInfo_Points: + MYwrite_char (mumkid[1], message); + MYwrite_word (mumkid[1], messagetype); + break; + + default: + fprintf (stderr, "Unrecognized RDIInfo request %d\n", + messagetype); + goto panic_error; + } + break; + + case RDP_OSOpReply: + /* OS Operation Reply */ +#ifdef DEBUG + fprintf (stderr, "RDP OS Reply\n"); +#endif + MYwrite_char (mumkid[1], message); + if (MYread_char (debugsock, &message)) + goto panic_error; + MYwrite_char (mumkid[1], message); + switch(message) + { + case 0: /* return value i.e. nothing else.*/ + break; + + case 1: /* returns a byte... */ + if (MYread_char(debugsock, &c)) + goto panic_error; + + MYwrite_char (mumkid[1], c); + break; + + case 2: /* returns a word... */ + if (MYread_word(debugsock, &x)) + goto panic_error; + + MYwrite_word (mumkid[1], x); + break; + } + break; + + case RDP_Reset: + /* Reset */ +#ifdef DEBUG + fprintf (stderr, "RDP Reset\n"); +#endif + MYwrite_char (mumkid[1], message); + break; + + default: + /* Hmm.. bad RDP operation */ + fprintf (stderr, "RDP Bad RDP request (%d)\n", message); + MYwrite_char (debugsock, RDP_Return); + MYwrite_char (debugsock, RDIError_UnimplementedMessage); + break; + } + } + + if (FD_ISSET (kidmum[0], &readfds)) + { +#ifdef DEBUG + fprintf (stderr, "->ARMulator\n"); +#endif + /* Anything we get from the ARMulator has to go to the debugger... */ + /* It is that simple! */ + + passon (kidmum[0], debugsock, 1); + } + } +} + diff --git a/sim/arm/tconfig.in b/sim/arm/tconfig.in new file mode 100644 index 0000000..04f702d --- /dev/null +++ b/sim/arm/tconfig.in @@ -0,0 +1,17 @@ +/* ARM target configuration file. */ + +/* Define this if the simulator supports profiling. + See the mips simulator for an example. + This enables the `-p foo' and `-s bar' options. + The target is required to provide sim_set_profile{,_size}. */ +/* #define SIM_HAVE_PROFILE */ + +/* Define this if the simulator uses an instruction cache. + See the h8/300 simulator for an example. + This enables the `-c size' option to set the size of the cache. + The target is required to provide sim_set_simcache_size. */ +/* #define SIM_HAVE_SIMCACHE */ + +/* Define this if the target cpu is bi-endian + and the simulator supports it. */ +#define SIM_HAVE_BIENDIAN diff --git a/sim/arm/thumbemu.c b/sim/arm/thumbemu.c new file mode 100644 index 0000000..eaf6e0c --- /dev/null +++ b/sim/arm/thumbemu.c @@ -0,0 +1,455 @@ +/* thumbemu.c -- Thumb instruction emulation. + Copyright (C) 1996, Cygnus Software Technologies Ltd. + + 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. */ + +/* We can provide simple Thumb simulation by decoding the Thumb +instruction into its corresponding ARM instruction, and using the +existing ARM simulator. */ + +#ifndef MODET /* required for the Thumb instruction support */ +#if 1 +#error "MODET needs to be defined for the Thumb world to work" +#else +#define MODET (1) +#endif +#endif + +#include "armdefs.h" +#include "armemu.h" + +/* Decode a 16bit Thumb instruction. The instruction is in the low + 16-bits of the tinstr field, with the following Thumb instruction + held in the high 16-bits. Passing in two Thumb instructions allows + easier simulation of the special dual BL instruction. */ + +tdstate +ARMul_ThumbDecode (state,pc,tinstr,ainstr) + ARMul_State *state; + ARMword pc; + ARMword tinstr; + ARMword *ainstr; +{ + tdstate valid = t_decoded; /* default assumes a valid instruction */ + ARMword next_instr; + + if (state->bigendSig) + { + next_instr = tinstr & 0xFFFF; + tinstr >>= 16; + } + else + { + next_instr = tinstr >> 16; + tinstr &= 0xFFFF; + } + +#if 1 /* debugging to catch non updates */ + *ainstr = 0xDEADC0DE; +#endif + + switch ((tinstr & 0xF800) >> 11) + { + case 0: /* LSL */ + case 1: /* LSR */ + case 2: /* ASR */ + /* Format 1 */ + *ainstr = 0xE1B00000 /* base opcode */ + | ((tinstr & 0x1800) >> (11 - 5)) /* shift type */ + | ((tinstr & 0x07C0) << (7 - 6)) /* imm5 */ + | ((tinstr & 0x0038) >> 3) /* Rs */ + | ((tinstr & 0x0007) << 12); /* Rd */ + break; + case 3: /* ADD/SUB */ + /* Format 2 */ + { + ARMword subset[4] = { + 0xE0900000, /* ADDS Rd,Rs,Rn */ + 0xE0500000, /* SUBS Rd,Rs,Rn */ + 0xE2900000, /* ADDS Rd,Rs,#imm3 */ + 0xE2500000 /* SUBS Rd,Rs,#imm3 */ + }; + /* It is quicker indexing into a table, than performing switch + or conditionals: */ + *ainstr = subset[(tinstr & 0x0600) >> 9] /* base opcode */ + | ((tinstr & 0x01C0) >> 6) /* Rn or imm3 */ + | ((tinstr & 0x0038) << (16 - 3)) /* Rs */ + | ((tinstr & 0x0007) << (12 - 0)); /* Rd */ + } + break; + case 4: /* MOV */ + case 5: /* CMP */ + case 6: /* ADD */ + case 7: /* SUB */ + /* Format 3 */ + { + ARMword subset[4] = { + 0xE3B00000, /* MOVS Rd,#imm8 */ + 0xE3500000, /* CMP Rd,#imm8 */ + 0xE2900000, /* ADDS Rd,Rd,#imm8 */ + 0xE2500000, /* SUBS Rd,Rd,#imm8 */ + }; + *ainstr = subset[(tinstr & 0x1800) >> 11] /* base opcode */ + | ((tinstr & 0x00FF) >> 0) /* imm8 */ + | ((tinstr & 0x0700) << (16 - 8)) /* Rn */ + | ((tinstr & 0x0700) << (12 - 8)); /* Rd */ + } + break ; + case 8: /* Arithmetic and high register transfers */ + /* TODO: Since the subsets for both Format 4 and Format 5 + instructions are made up of different ARM encodings, we could + save the following conditional, and just have one large + subset. */ + if ((tinstr & (1 << 10)) == 0) + { + /* Format 4 */ + struct { + ARMword opcode; + enum {t_norm,t_shift,t_neg,t_mul} otype; + } subset[16] = { + {0xE0100000, t_norm}, /* ANDS Rd,Rd,Rs */ + {0xE0300000, t_norm}, /* EORS Rd,Rd,Rs */ + {0xE1B00010, t_shift}, /* MOVS Rd,Rd,LSL Rs */ + {0xE1B00030, t_shift}, /* MOVS Rd,Rd,LSR Rs */ + {0xE1B00050, t_shift}, /* MOVS Rd,Rd,ASR Rs */ + {0xE0B00000, t_norm}, /* ADCS Rd,Rd,Rs */ + {0xE0D00000, t_norm}, /* SBCS Rd,Rd,Rs */ + {0xE1B00070, t_shift}, /* MOVS Rd,Rd,ROR Rs */ + {0xE1100000, t_norm}, /* TST Rd,Rs */ + {0xE2700000, t_neg}, /* RSBS Rd,Rs,#0 */ + {0xE1500000, t_norm}, /* CMP Rd,Rs */ + {0xE1700000, t_norm}, /* CMN Rd,Rs */ + {0xE1900000, t_norm}, /* ORRS Rd,Rd,Rs */ + {0xE0100090, t_mul}, /* MULS Rd,Rd,Rs */ + {0xE1D00000, t_norm}, /* BICS Rd,Rd,Rs */ + {0xE1F00000, t_norm} /* MVNS Rd,Rs */ + }; + *ainstr = subset[(tinstr & 0x03C0)>>6].opcode; /* base */ + switch (subset[(tinstr & 0x03C0)>>6].otype) + { + case t_norm: + *ainstr |= ((tinstr & 0x0007) << 16) /* Rn */ + | ((tinstr & 0x0007) << 12) /* Rd */ + | ((tinstr & 0x0038) >> 3); /* Rs */ + break; + case t_shift: + *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */ + | ((tinstr & 0x0007) >> 0) /* Rm */ + | ((tinstr & 0x0038) << (8 - 3)); /* Rs */ + break; + case t_neg: + *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */ + | ((tinstr & 0x0038) << (16 - 3)); /* Rn */ + break; + case t_mul: + *ainstr |= ((tinstr & 0x0007) << 16) /* Rd */ + | ((tinstr & 0x0007) << 8) /* Rs */ + | ((tinstr & 0x0038) >> 3); /* Rm */ + break; + } + } + else + { + /* Format 5 */ + ARMword Rd = ((tinstr & 0x0007) >> 0); + ARMword Rs = ((tinstr & 0x0038) >> 3); + if (tinstr & (1 << 7)) + Rd += 8; + if (tinstr & (1 << 6)) + Rs += 8; + switch ((tinstr & 0x03C0) >> 6) + { + case 0x1: /* ADD Rd,Rd,Hs */ + case 0x2: /* ADD Hd,Hd,Rs */ + case 0x3: /* ADD Hd,Hd,Hs */ + *ainstr = 0xE0800000 /* base */ + | (Rd << 16) /* Rn */ + | (Rd << 12) /* Rd */ + | (Rs << 0); /* Rm */ + break; + case 0x5: /* CMP Rd,Hs */ + case 0x6: /* CMP Hd,Rs */ + case 0x7: /* CMP Hd,Hs */ + *ainstr = 0xE1500000 /* base */ + | (Rd << 16) /* Rn */ + | (Rd << 12) /* Rd */ + | (Rs << 0); /* Rm */ + break; + case 0x9: /* MOV Rd,Hs */ + case 0xA: /* MOV Hd,Rs */ + case 0xB: /* MOV Hd,Hs */ + *ainstr = 0xE1A00000 /* base */ + | (Rd << 16) /* Rn */ + | (Rd << 12) /* Rd */ + | (Rs << 0); /* Rm */ + break; + case 0xC: /* BX Rs */ + case 0xD: /* BX Hs */ + *ainstr = 0xE12FFF10 /* base */ + | ((tinstr & 0x0078) >> 3); /* Rd */ + break; + case 0x0: /* UNDEFINED */ + case 0x4: /* UNDEFINED */ + case 0x8: /* UNDEFINED */ + case 0xE: /* UNDEFINED */ + case 0xF: /* UNDEFINED */ + valid = t_undefined; + break; + } + } + break; + case 9: /* LDR Rd,[PC,#imm8] */ + /* Format 6 */ + *ainstr = 0xE59F0000 /* base */ + | ((tinstr & 0x0700) << (12 - 8)) /* Rd */ + | ((tinstr & 0x00FF) << (2 - 0)); /* off8 */ + break; + case 10: + case 11: + /* TODO: Format 7 and Format 8 perform the same ARM encoding, so + the following could be merged into a single subset, saving on + the following boolean: */ + if ((tinstr & (1 << 9)) == 0) + { + /* Format 7 */ + ARMword subset[4] = { + 0xE7800000, /* STR Rd,[Rb,Ro] */ + 0xE7C00000, /* STRB Rd,[Rb,Ro] */ + 0xE7900000, /* LDR Rd,[Rb,Ro] */ + 0xE7D00000 /* LDRB Rd,[Rb,Ro] */ + }; + *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */ + | ((tinstr & 0x0007) << (12 - 0)) /* Rd */ + | ((tinstr & 0x0038) << (16 - 3)) /* Rb */ + | ((tinstr & 0x01C0) >> 6); /* Ro */ + } + else + { + /* Format 8 */ + ARMword subset[4] = { + 0xE18000B0, /* STRH Rd,[Rb,Ro] */ + 0xE19000D0, /* LDRSB Rd,[Rb,Ro] */ + 0xE19000B0, /* LDRH Rd,[Rb,Ro] */ + 0xE19000F0 /* LDRSH Rd,[Rb,Ro] */ + }; + *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */ + | ((tinstr & 0x0007) << (12 - 0)) /* Rd */ + | ((tinstr & 0x0038) << (16 - 3)) /* Rb */ + | ((tinstr & 0x01C0) >> 6); /* Ro */ + } + break; + case 12: /* STR Rd,[Rb,#imm5] */ + case 13: /* LDR Rd,[Rb,#imm5] */ + case 14: /* STRB Rd,[Rb,#imm5] */ + case 15: /* LDRB Rd,[Rb,#imm5] */ + /* Format 9 */ + { + ARMword subset[4] = { + 0xE5800000, /* STR Rd,[Rb,#imm5] */ + 0xE5900000, /* LDR Rd,[Rb,#imm5] */ + 0xE5C00000, /* STRB Rd,[Rb,#imm5] */ + 0xE5D00000 /* LDRB Rd,[Rb,#imm5] */ + }; + /* The offset range defends on whether we are transferring a + byte or word value: */ + *ainstr = subset[(tinstr & 0x1800) >> 11] /* base */ + | ((tinstr & 0x0007) << (12 - 0)) /* Rd */ + | ((tinstr & 0x0038) << (16 - 3)) /* Rb */ + | ((tinstr & 0x07C0) >> + (6 - ((tinstr & (1 << 12)) ? 0 : 2))); /* off5 */ + } + break; + case 16: /* STRH Rd,[Rb,#imm5] */ + case 17: /* LDRH Rd,[Rb,#imm5] */ + /* Format 10 */ + *ainstr = ((tinstr & (1 << 11)) /* base */ + ? 0xE1D000B0 /* LDRH */ + : 0xE1C000B0) /* STRH */ + | ((tinstr & 0x0007) << (12 - 0)) /* Rd */ + | ((tinstr & 0x0038) << (16 - 3)) /* Rb */ + | ((tinstr & 0x01C0) >> (6 - 1)) /* off5, low nibble */ + | ((tinstr & 0x0600) >> (9 - 8)); /* off5, high nibble */ + break; + case 18: /* STR Rd,[SP,#imm8] */ + case 19: /* LDR Rd,[SP,#imm8] */ + /* Format 11 */ + *ainstr = ((tinstr & (1 << 11)) /* base */ + ? 0xE59D0000 /* LDR */ + : 0xE58D0000) /* STR */ + | ((tinstr & 0x0700) << (12 - 8)) /* Rd */ + | ((tinstr & 0x00FF) << 2); /* off8 */ + break; + case 20: /* ADD Rd,PC,#imm8 */ + case 21: /* ADD Rd,SP,#imm8 */ + /* Format 12 */ + if ((tinstr & (1 << 11)) == 0) + { + /* NOTE: The PC value used here should by word aligned */ + /* We encode shift-left-by-2 in the rotate immediate field, + so no shift of off8 is needed. */ + *ainstr = 0xE28F0F00 /* base */ + | ((tinstr & 0x0700) << (12 - 8)) /* Rd */ + | (tinstr & 0x00FF); /* off8 */ + } + else + { + /* We encode shift-left-by-2 in the rotate immediate field, + so no shift of off8 is needed. */ + *ainstr = 0xE28D0F00 /* base */ + | ((tinstr & 0x0700) << (12 - 8)) /* Rd */ + | (tinstr & 0x00FF); /* off8 */ + } + break; + case 22: + case 23: + if ((tinstr & 0x0F00) == 0x0000) + { + /* Format 13 */ + /* NOTE: The instruction contains a shift left of 2 + equivalent (implemented as ROR #30): */ + *ainstr = ((tinstr & (1 << 7)) /* base */ + ? 0xE24DDF00 /* SUB */ + : 0xE28DDF00) /* ADD */ + | (tinstr & 0x007F); /* off7 */ + } + else + { + /* Format 14 */ + ARMword subset[4] = { + 0xE92D0000, /* STMDB sp!,{rlist} */ + 0xE92D4000, /* STMDB sp!,{rlist,lr} */ + 0xE8BD0000, /* LDMIA sp!,{rlist} */ + 0xE8BD8000 /* LDMIA sp!,{rlist,pc} */ + }; + *ainstr = subset[((tinstr & (1 << 11)) >> 10) + | ((tinstr & (1 << 8)) >> 8)] /* base */ + | (tinstr & 0x00FF); /* mask8 */ + } + break; + case 24: /* STMIA */ + case 25: /* LDMIA */ + /* Format 15 */ + *ainstr = ((tinstr & (1 << 11)) /* base */ + ? 0xE8B00000 /* LDMIA */ + : 0xE8A00000) /* STMIA */ + | ((tinstr & 0x0700) << (16 - 8)) /* Rb */ + | (tinstr & 0x00FF); /* mask8 */ + break; + case 26: /* Bcc */ + case 27: /* Bcc/SWI */ + if ((tinstr & 0x0F00) == 0x0F00) + { + /* Format 17 : SWI */ + *ainstr = 0xEF000000; + /* Breakpoint must be handled specially. */ + if ((tinstr & 0x00FF) == 0x18) + *ainstr |= ((tinstr & 0x00FF) << 16); + else + *ainstr |= (tinstr & 0x00FF); + } + else if ((tinstr & 0x0F00) != 0x0E00) + { + /* Format 16 */ + int doit = FALSE; + /* TODO: Since we are doing a switch here, we could just add + the SWI and undefined instruction checks into this + switch to same on a couple of conditionals: */ + switch ((tinstr & 0x0F00) >> 8) { + case EQ : doit=ZFLAG ; + break ; + case NE : doit=!ZFLAG ; + break ; + case VS : doit=VFLAG ; + break ; + case VC : doit=!VFLAG ; + break ; + case MI : doit=NFLAG ; + break ; + case PL : doit=!NFLAG ; + break ; + case CS : doit=CFLAG ; + break ; + case CC : doit=!CFLAG ; + break ; + case HI : doit=(CFLAG && !ZFLAG) ; + break ; + case LS : doit=(!CFLAG || ZFLAG) ; + break ; + case GE : doit=((!NFLAG && !VFLAG) || (NFLAG && VFLAG)) ; + break ; + case LT : doit=((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) ; + break ; + case GT : doit=((!NFLAG && !VFLAG && !ZFLAG) || (NFLAG && VFLAG && !ZFLAG)) ; + break ; + case LE : doit=((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG ; + break ; + } + if (doit) { + state->Reg[15] = pc + 4 + + (((tinstr & 0x7F) << 1) + | ((tinstr & (1 << 7)) ? 0xFFFFFF00 : 0)); + FLUSHPIPE; + } + valid = t_branch; + } + else /* UNDEFINED : cc=1110(AL) uses different format */ + valid = t_undefined; + break; + case 28: /* B */ + /* Format 18 */ + state->Reg[15] = pc + 4 + + (((tinstr & 0x3FF) << 1) + | ((tinstr & (1 << 10)) ? 0xFFFFF800 : 0)); + FLUSHPIPE; + valid = t_branch; + break; + case 29: /* UNDEFINED */ + valid = t_undefined; + break; + case 30: /* BL instruction 1 */ + /* Format 19 */ + /* There is no single ARM instruction equivalent for this Thumb + instruction. To keep the simulation simple (from the user + perspective) we check if the following instruction is the + second half of this BL, and if it is we simulate it + immediately. */ + state->Reg[14] = state->Reg[15] \ + + (((tinstr & 0x07FF) << 12) \ + | ((tinstr & (1 << 10)) ? 0xFF800000 : 0)); + valid = t_branch; /* in-case we don't have the 2nd half */ + tinstr = next_instr; /* move the instruction down */ + if (((tinstr & 0xF800) >> 11) != 31) + break; /* exit, since not correct instruction */ + /* else we fall through to process the second half of the BL */ + pc += 2; /* point the pc at the 2nd half */ + case 31: /* BL instruction 2 */ + /* Format 19 */ + /* There is no single ARM instruction equivalent for this + instruction. Also, it should only ever be matched with the + fmt19 "BL instruction 1" instruction. However, we do allow + the simulation of it on its own, with undefined results if + r14 is not suitably initialised.*/ + { + ARMword tmp = (pc + 2); + state->Reg[15] = (state->Reg[14] + ((tinstr & 0x07FF) << 1)); + state->Reg[14] = (tmp | 1); + valid = t_branch; + FLUSHPIPE; + } + break; + } + + return valid; +} diff --git a/sim/arm/wrapper.c b/sim/arm/wrapper.c new file mode 100644 index 0000000..4038004 --- /dev/null +++ b/sim/arm/wrapper.c @@ -0,0 +1,467 @@ +/* run front end support for arm + Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. + +This file is part of ARM SIM. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* This file provides the interface between the simulator and run.c and gdb + (when the simulator is linked with gdb). + All simulator interaction should go through this file. */ + +#include <stdio.h> +#include <stdarg.h> +#include <bfd.h> +#include <signal.h> +#include "callback.h" +#include "remote-sim.h" +#include "armdefs.h" +#include "armemu.h" +#include "dbg_rdi.h" + +host_callback *sim_callback; + +static struct ARMul_State *state; + +/* Who is using the simulator. */ +static SIM_OPEN_KIND sim_kind; + +/* argv[0] */ +static char *myname; + +/* Memory size in bytes. */ +static int mem_size = (1 << 21); + +/* Non-zero to display start up banner, and maybe other things. */ +static int verbosity; + +/* Non-zero to set big endian mode. */ +static int big_endian; + +static void +init () +{ + static int done; + + if (!done) + { + ARMul_EmulateInit(); + state = ARMul_NewState (); + state->bigendSig = (big_endian ? HIGH : LOW); + ARMul_MemoryInit(state, mem_size); + ARMul_OSInit(state); + ARMul_CoProInit(state); + state->verbose = verbosity; + done = 1; + } +} + +/* Set verbosity level of simulator. + This is not intended to produce detailed tracing or debugging information. + Just summaries. */ +/* FIXME: common/run.c doesn't do this yet. */ + +void +sim_set_verbose (v) + int v; +{ + verbosity = v; +} + +/* Set the memory size to SIZE bytes. + Must be called before initializing simulator. */ +/* FIXME: Rename to sim_set_mem_size. */ + +void +sim_size (size) + int size; +{ + mem_size = size; +} + +void +ARMul_ConsolePrint (ARMul_State * state, const char *format,...) +{ + va_list ap; + + if (state->verbose) + { + va_start (ap, format); + vprintf (format, ap); + va_end (ap); + } +} + +ARMword +ARMul_Debug (ARMul_State * state, ARMword pc, ARMword instr) +{ + +} + +int +sim_write (sd, addr, buffer, size) + SIM_DESC sd; + SIM_ADDR addr; + unsigned char *buffer; + int size; +{ + int i; + init (); + for (i = 0; i < size; i++) + { + ARMul_WriteByte (state, addr+i, buffer[i]); + } + return size; +} + +int +sim_read (sd, addr, buffer, size) + SIM_DESC sd; + SIM_ADDR addr; + unsigned char *buffer; + int size; +{ + int i; + init (); + for (i = 0; i < size; i++) + { + buffer[i] = ARMul_ReadByte (state, addr + i); + } + return size; +} + +int +sim_trace (sd) + SIM_DESC sd; +{ + (*sim_callback->printf_filtered) (sim_callback, "This simulator does not support tracing\n"); + return 1; +} + +int +sim_stop (sd) + SIM_DESC sd; +{ + return 0; +} + +void +sim_resume (sd, step, siggnal) + SIM_DESC sd; + int step, siggnal; +{ + state->EndCondition = 0; + + if (step) + { + state->Reg[15] = ARMul_DoInstr (state); + if (state->EndCondition == 0) + state->EndCondition = RDIError_BreakpointReached; + } + else + { +#if 1 /* JGS */ + state->NextInstr = RESUME; /* treat as PC change */ +#endif + state->Reg[15] = ARMul_DoProg (state); + } + + FLUSHPIPE; +} + +SIM_RC +sim_create_inferior (sd, abfd, argv, env) + SIM_DESC sd; + struct _bfd *abfd; + char **argv; + char **env; +{ + int argvlen=0; + char **arg; + + if (abfd != NULL) + ARMul_SetPC (state, bfd_get_start_address (abfd)); + else + ARMul_SetPC (state, 0); /* ??? */ + +#if 1 /* JGS */ + /* We explicitly select a processor capable of supporting the ARM + 32bit mode, and then we force the simulated CPU into the 32bit + User mode: */ + ARMul_SelectProcessor(state, ARM600); + ARMul_SetCPSR(state, USER32MODE); +#endif + + if (argv != NULL) + { + /* + ** Set up the command line (by laboriously stringing together the + ** environment carefully picked apart by our caller...) + */ + /* Free any old stuff */ + if (state->CommandLine != NULL) + { + free(state->CommandLine); + state->CommandLine = NULL; + } + + /* See how much we need */ + for (arg = argv; *arg != NULL; arg++) + argvlen += strlen(*arg)+1; + + /* allocate it... */ + state->CommandLine = malloc(argvlen+1); + if (state->CommandLine != NULL) + { + arg = argv; + state->CommandLine[0]='\0'; + for (arg = argv; *arg != NULL; arg++) + { + strcat(state->CommandLine, *arg); + strcat(state->CommandLine, " "); + } + } + } + + if (env != NULL) + { + /* Now see if there's a MEMSIZE spec in the environment */ + while (*env) + { + if (strncmp(*env, "MEMSIZE=", sizeof("MEMSIZE=")-1)==0) + { + unsigned long top_of_memory; + char *end_of_num; + + /* Set up memory limit */ + state->MemSize = strtoul(*env + sizeof("MEMSIZE=")-1, &end_of_num, 0); + } + env++; + } + } + + return SIM_RC_OK; +} + +void +sim_info (sd, verbose) + SIM_DESC sd; + int verbose; +{ +} + + +static int +frommem (state, memory) + struct ARMul_State *state; + unsigned char *memory; +{ + if (state->bigendSig == HIGH) + { + return (memory[0] << 24) + | (memory[1] << 16) + | (memory[2] << 8) + | (memory[3] << 0); + } + else + { + return (memory[3] << 24) + | (memory[2] << 16) + | (memory[1] << 8) + | (memory[0] << 0); + } +} + + +static void +tomem (state, memory, val) + struct ARMul_State *state; + unsigned char *memory; + int val; +{ + if (state->bigendSig == HIGH) + { + memory[0] = val >> 24; + memory[1] = val >> 16; + memory[2] = val >> 8; + memory[3] = val >> 0; + } + else + { + memory[3] = val >> 24; + memory[2] = val >> 16; + memory[1] = val >> 8; + memory[0] = val >> 0; + } +} + +int +sim_store_register (sd, rn, memory, length) + SIM_DESC sd; + int rn; + unsigned char *memory; + int length; +{ + init (); + ARMul_SetReg(state, state->Mode, rn, frommem (state, memory)); + return -1; +} + +int +sim_fetch_register (sd, rn, memory, length) + SIM_DESC sd; + int rn; + unsigned char *memory; + int length; +{ + ARMword regval; + + init (); + if (rn < 16) + regval = ARMul_GetReg(state, state->Mode, rn); + else if (rn == 25) /* FIXME: use PS_REGNUM from gdb/config/arm/tm-arm.h */ + regval = ARMul_GetCPSR(state); + else + regval = 0; /* FIXME: should report an error */ + tomem (state, memory, regval); + return -1; +} + +SIM_DESC +sim_open (kind, ptr, abfd, argv) + SIM_OPEN_KIND kind; + host_callback *ptr; + struct _bfd *abfd; + char **argv; +{ + sim_kind = kind; + myname = argv[0]; + sim_callback = ptr; + + /* Decide upon the endian-ness of the processor. + If we can, get the information from the bfd itself. + Otherwise look to see if we have been given a command + line switch that tells us. Otherwise default to little endian. */ + if (abfd != NULL) + big_endian = bfd_big_endian (abfd); + else if (argv[1] != NULL) + { + int i; + + /* Scan for endian-ness switch. */ + for (i = 0; (argv[i] != NULL) && (argv[i][0] != 0); i++) + if (argv[i][0] == '-' && argv[i][1] == 'E') + { + char c; + + if ((c = argv[i][2]) == 0) + { + ++i; + c = argv[i][0]; + } + + switch (c) + { + case 0: + sim_callback->printf_filtered + (sim_callback, "No argument to -E option provided\n"); + break; + + case 'b': + case 'B': + big_endian = 1; + break; + + case 'l': + case 'L': + big_endian = 0; + break; + + default: + sim_callback->printf_filtered + (sim_callback, "Unrecognised argument to -E option\n"); + break; + } + } + } + + return (SIM_DESC) 1; +} + +void +sim_close (sd, quitting) + SIM_DESC sd; + int quitting; +{ + /* nothing to do */ +} + +SIM_RC +sim_load (sd, prog, abfd, from_tty) + SIM_DESC sd; + char *prog; + bfd *abfd; + int from_tty; +{ + extern bfd *sim_load_file (); /* ??? Don't know where this should live. */ + bfd *prog_bfd; + + prog_bfd = sim_load_file (sd, myname, sim_callback, prog, abfd, + sim_kind == SIM_OPEN_DEBUG, + 0, sim_write); + if (prog_bfd == NULL) + return SIM_RC_FAIL; + ARMul_SetPC (state, bfd_get_start_address (prog_bfd)); + if (abfd == NULL) + bfd_close (prog_bfd); + return SIM_RC_OK; +} + +void +sim_stop_reason (sd, reason, sigrc) + SIM_DESC sd; + enum sim_stop *reason; + int *sigrc; +{ + if (state->EndCondition == 0) + { + *reason = sim_exited; + *sigrc = state->Reg[0] & 255; + } + else + { + *reason = sim_stopped; + if (state->EndCondition == RDIError_BreakpointReached) + *sigrc = SIGTRAP; + else + *sigrc = 0; + } +} + +void +sim_do_command (sd, cmd) + SIM_DESC sd; + char *cmd; +{ + (*sim_callback->printf_filtered) (sim_callback, "This simulator does not accept any commands.\n"); +} + + +void +sim_set_callbacks (ptr) + host_callback *ptr; +{ + sim_callback = ptr; +} |