diff options
Diffstat (limited to 'sim/erc32')
-rw-r--r-- | sim/erc32/ChangeLog | 576 | ||||
-rw-r--r-- | sim/erc32/Makefile.in | 75 | ||||
-rw-r--r-- | sim/erc32/NEWS | 108 | ||||
-rw-r--r-- | sim/erc32/README.erc32 | 130 | ||||
-rw-r--r-- | sim/erc32/README.gdb | 67 | ||||
-rw-r--r-- | sim/erc32/README.sis | 356 | ||||
-rw-r--r-- | sim/erc32/acconfig.h | 15 | ||||
-rw-r--r-- | sim/erc32/config.in | 158 | ||||
-rwxr-xr-x | sim/erc32/configure | 3932 | ||||
-rw-r--r-- | sim/erc32/configure.in | 13 | ||||
-rw-r--r-- | sim/erc32/end.c | 26 | ||||
-rw-r--r-- | sim/erc32/erc32.c | 1888 | ||||
-rw-r--r-- | sim/erc32/exec.c | 2041 | ||||
-rw-r--r-- | sim/erc32/float.c | 212 | ||||
-rw-r--r-- | sim/erc32/func.c | 1162 | ||||
-rw-r--r-- | sim/erc32/help.c | 40 | ||||
-rw-r--r-- | sim/erc32/interf.c | 526 | ||||
-rw-r--r-- | sim/erc32/sis.c | 310 | ||||
-rw-r--r-- | sim/erc32/sis.h | 217 | ||||
-rw-r--r-- | sim/erc32/startsim | 4 |
20 files changed, 11856 insertions, 0 deletions
diff --git a/sim/erc32/ChangeLog b/sim/erc32/ChangeLog new file mode 100644 index 0000000..b908a50 --- /dev/null +++ b/sim/erc32/ChangeLog @@ -0,0 +1,576 @@ +1999-02-11 Hugo Tyson <hmt@cygnus.co.uk> + + * exec.c (dispatch_instruction): + Correct the sense of the + if (!sparclite) { + sregs->trap = TRAP_UNIMP; + break; + } + clause that has been pasted around: it's correct in the SCAN and + DIVScc (divide step) cases (where it was probably originally + written?), but reversed in the SDIV, SDIVcc, UDIV, UDIVcc cases + ie. instructions only in the SPARC V8 or SPARClite 86x + architectures. It was also present when not required for SMUL, + SMULcc, UMUL, UMULcc instructions that are present in all + architectures. + +1999-01-25 Hugo Tyson <hmt@cygnus.co.uk> + + * interf.c (run_sim): Fix a bug in the main loop's handling of + annulled delay slot instructions. There is precedent for this + change; the _other_ main loop in sis.c gets it right according to + my reading of the code. + + The bug is: if an interrupt happens when the next instruction + (at sregs->pc) is annulled, the trap is taken (by execute_trap()) + with the current values of PC and NPC, so when the trap returns, + the annulled instruction is indeed executed. Another giveaway is + that the annul flag is cleared in execute_trap(): the information + is demonstrably discarded. + + The solution is: perform annulling before looking for traps, in + fact it's neater to do annulling, see if there's an interrupt and + if not, do the instruction, then handle traps be they generated by + interrupts pending or by the instruction we might just have done. + That's what the sis.c one does. + +1999-01-20 Hugo Tyson <hmt@cygnus.co.uk> + + * sis.h: Add asr17 register for support of SparcLITE (at least the + Hitachi ones I find before me) + + * exec.c (dispatch_instruction): Case WRY: Allow write of asr17 if + sparclite. Other ASR numbers than 17 or 0 (Y) trap out. + Case RDY: Allow read of asr17 if sparclite. Other ASRs ditto. + (execute_trap): Do single-vector-trapping if asr17 bit 0 is set. + (init_regs): Initialize y and asr17. + NB: In instruction-set space, the Y register is asr0; the + instructions have different names for human reasons only. + + * sis.c: + * interf.c: Set boolean mode variable dumbio if invoked with + argument "-dumbio" and mention it of verbose. + * erc32.c: if "dumbio" is set, do not assume that there is a + terminal type device attached to stdin/stdout. Do not set + buffering or mess with tcsetattr or do any read operations in + order to make UART interrupts; not input data is supported. + This is necessary to allow the sim to be used within the eCos + testing infrastructure where stdin/stdout are pipes to a TCL + program; the sim hangs otherwise. + +Thu Jul 23 07:17:03 1998 Mark Alexander <marka@cygnus.com> + + * exec.c (dispatch_instruction): Add SPARClite 'scan' instruction. + +Tue Jul 7 21:12:41 1998 Mark Alexander <marka@cygnus.com> + + * func.c (bfd_load): Add special handling of a.out executables. + +Sat Jun 13 08:33:25 1998 Mark Alexander <marka@cygnus.com> + + * func.c (bfd_load): Print correct endianness. + * interf.c (run_sim): Print debugging information if verbosity level + is greater than 2. + (sim_open): Repeated -v options now increment verbosity level. + (sim_store_register): Handle little-endian case. + (flush_window): Print debugging information if verbosity level + is greater then 2. + +Tue Jun 2 15:20:35 1998 Mark Alexander <marka@cygnus.com> + + * interf.c (sim_open): Use revamped memory_read, which makes + byte-swapping unnecessary. Add -sparclite-board option for + emulating RAM found on typical SPARClite boards. Print + error message for unrecognized option. + * erc32.c: Change RAM address and size from constants to variables, + to allow emulation of SPARClite board RAM. + (fetch_bytes, store_bytes): New helper functions for revamped + mememory_read and memory_write. + (memory_read, memory_write): Rewrite to store bytes in target + byte order instead of storing words in host byte order; this + greatly simplifies support of little-endian programs. + (get_mem_ptr): Remove unnecessary byte parameter. + (sis_memory_write, sis_memory_read): Store words in target + byte order instead of host byte order. + (byte_swap_words): Remove, no longer needed. + * sis.h ((byte_swap_words): Remove declaration, no longer needed. + (memory_read): Add new sz parameter. + * sis.c (run_sim): Use revamped memory_read, which makes + byte-swapping unnecessary. + * exec.c (dispatch_instruction): Use revamped memory_read, which + makes byte-swapping and double-word fetching unnecessary. + * func.c (sparclite_board): Declare new variable. + (get_regi): Handle little-endian data. + (bfd_load): Recognize little-endian SPARClite as having + little-endian data. + +Fri May 22 14:23:16 1998 Mark Alexander <marka@cygnus.com> + + * erc32.c (port_init): Print messages only if sis_verbose is true. + * func.c (bfd_load): Ditto. + * interf.c (sim_open): Ditto. + +Thu May 14 23:10:48 1998 Mark Alexander <marka@cygnus.com> + + * sis.h (uint64, int64): Define. + * exec.c (SDIV, SDIVCC, UDIV, UDIVCC): Define new opcodes. + * (mul64): Simplify calculation of negative result. + * (div64): New helper function for 64-bit division. + * (dispatch_instruction): Add emulation of SDIV, SDIVCC, UDIV, + and UDIVCC. + +Wed May 13 14:59:54 1998 Mark Alexander <marka@cygnus.com> + + * erc32.c (close_port): Don't close stdin; it kills GDB. + (byte_swap_words): New function. + * sis.h: (byte_swap_words): Declare. + * interf.c (run_sim): Always fetch instructions as big-endian. + * sis.c (run_sim): Ditto. + +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:17 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:19:52 1998 Tom Tromey <tromey@cygnus.com> + + * configure.in: Don't call sinclude. + +Sat Apr 18 12:00:16 1998 Mark Alexander <marka@cygnus.com> + + * func.c (disp_fpu): Fix build problem on big-endian hosts. + +Wed Apr 8 19:33:34 1998 Mark Alexander <marka@cygnus.com> + + * erc32.c (sim_stop): Handle SIGINT gracefully. + * interf.c (sim_open): Don't catch SIGINT; GDB will do that for us. + +Wed Apr 8 18:29:40 1998 Mark Alexander <marka@cygnus.com> + + * exec.c (dispatch_instruction): Change how carry out is calculated + in DIVSCC. Add emulation of SMULCC, UMUL, and UMULCC. + +Sat Apr 4 20:36:25 1998 Andrew Cagney <cagney@b1.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Wed Apr 1 21:19:18 1998 Mark Alexander <marka@cygnus.com> + + * end.c: Update to version 2.7.5, fix compiler warnings and bugs. + * erc32.c: Ditto. + * exec.c: Ditto. + * float.c: Ditto. + * func.c: Ditto. + * help.c: Ditto. + * interf.c: Ditto. + * sis.c: Ditto. + * sis.h: Ditto. + +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 Feb 17 12:41:11 1998 Andrew Cagney <cagney@b1.cygnus.com> + + * interf.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. + +Thu Dec 4 09:21:05 1997 Doug Evans <devans@canuck.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +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. + +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:38:20 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * float.c (__setfpucw): Compile on any i386 target. Not just NT. + + * interf.c (sim_kill): Delete. + (sim_create_inferior): Add ABFD argument. Initialize PC from ABFD + argument. + (sim_load): Don't save start address. + (start_address): Delete variable. + +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 16:19:49 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * interf.c (sim_open): Add ABFD argument. Change ARGV to PARGV. + +Mon Jun 30 11:45:25 1997 Doug Evans <dje@canuck.cygnus.com> + + * Makefile.in (install-sis): Change $(srcdir)/sis to sis. + +Wed May 28 09:46:13 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * interf.c (sim_set_callbacks): Drop SD argument - not applicable. + (sim_open): Add callback arg, save it. + +Thu Apr 24 00:39:51 1997 Doug Evans <dje@canuck.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Tue Apr 22 11:05:01 1997 Doug Evans <dje@canuck.cygnus.com> + + * interf.c (sim_open): Undo patch to add -E support. + +Thu Apr 17 03:03:56 1997 Doug Evans <dje@canuck.cygnus.com> + + * interf.c (sim_open): Ignore -E arg. + (start_address): New static local. + (sim_load): Return SIM_RC. New arg abfd. Set start_address from bfd. + (sim_create_inferior): Return SIM_RC. Delete arg start_address. + +Tue Apr 15 15:16:11 1997 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (install-sis): Depend upon installdirs. Use + $(program_transform_name) directly, rather than using + $(INSTALL_XFORM). + +Mon Apr 7 15:45:02 1997 Andrew Cagney <cagney@kremvax.cygnus.com> + + * configure: Regenerated to track ../common/aclocal.m4 changes. + * config.in: Ditto. + +Wed Apr 2 15:06:28 1997 Doug Evans <dje@canuck.cygnus.com> + + * interf.c (sim_open): New arg `kind'. + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Wed Apr 2 14:34:19 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. + +Thu Mar 13 12:46:04 1997 Doug Evans <dje@canuck.cygnus.com> + + * interf.c (sim_open): New SIM_DESC result. Argument is now in + argv form. + (other sim_*): New SIM_DESC argument. + +Tue Feb 4 13:35:20 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 Dec 4 18:25:04 1996 Rob Savoye <rob@chinadoll.cygnus.com> + + * interf.c (run_sim): Stop the simulator and reset the stdio after + breakpoints. + +Tue Dec 3 11:54:37 1996 Rob Savoye <rob@chinadoll.cygnus.com> + + * configure.in: Look for libtermcap.a. + * Makefile.in: Only link in -ltermcap if it exists. + * erc32.c: Update to version 2.6a. Fix uart handling. + * exec.c: Update to version 2.6a. Add sparclite support. + * float.c: Update to version 2.6a. Convert comments to + preprocessor warnings. Add __setfpucw() for i385 hosts so floating + point exceptions work on win32. + * func.c: Update to version 2.6a. Fix uart handling, add support + for user error traps. + * help.c: Update to version 2.6a. Add help note on user error + traps. + * interf.c: Update to version 2.6a. Fix uart handling, and add + sparclite support. + * examples/gccx: Use sparclite cross compiler, not native gcc. + * examples/srt0.S: Use "mov" rather than "wr" for manipulating + the psr register. + +Mon Nov 25 08:28:10 1996 Fred Fish <fnf@cygnus.com> + + * Makefile.in (run.o): Remove this rule, it hides the one in + ../common/Make-common.in that correctly references the source + in the sibling ../common directory. + +Wed Nov 20 01:30:12 1996 Doug Evans <dje@canuck.cygnus.com> + + * Makefile.in: Delete stuff moved to ../common/Make-common.in. + (SIM_{OBJS,EXTRA_LIBS,EXTRA_LIBDEPS,EXTRA_ALL,EXTRA_INSTALL}): Define. + (SIM_{EXTRA_CLEAN,EXTRA_CFLAGS}): Define. + * configure.in: Simplify using macros in ../common/aclocal.m4. + Call AC_CHECK_HEADERS(stdlib.h). + * configure: Regenerated. + * config.in: New file. + * func.c (sim_set_callbacks): Delete, moved to + * interf.c (sim_set_callbacks): here. + (sim_callback): New global. + Rewrite all calls to printf_filtered to go through callback. + (sim_size,sim_trace): New functions. + (sim_{insert,remove}_breakpoint): #if 0 out. + * sis.c: #include "config.h". #include <stdlib.h> if present. + (main): Coerce fprintf arg to INIT_DISASSEMBLE_INFO to fprintf_ftype. + * sis.h: #include "callback.h". + * run.c: Deleted, using one in ../common now. + +Thu Oct 3 16:12:03 1996 Jason Molenda (crash@godzilla.cygnus.co.jp) + + * Makefile.in (clean): Move config.log to distclean. + +Wed Oct 2 16:57:57 1996 Jason Molenda (crash@godzilla.cygnus.co.jp) + + * Makefile.in (clean): Also remove config.log. + +Sat Sep 14 00:00:46 1996 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (CC_FOR_BUILD): New variable. + (AR, AR_FLAGS, BISON, MAKEINFO): Remove duplicate variables. + (RANLIB, CC): Likewise. + (end): Use $(CC_FOR_BUILD), not $(CC). + * configure.in: Set CC_FOR_BUILD. + * configure: Rebuild. + +Sun Sep 8 14:04:37 1996 Stu Grossman (grossman@critters.cygnus.com) + + * erc32.c (port_init): Disable this for __GO32__ (got no pty's + there either...). + +Mon Aug 12 17:04:58 1996 Stu Grossman (grossman@critters.cygnus.com) + + * erc32.c: Don't include sys/ioctl.h or sys/file.h. They aren't + necessary. + * (port_init): Don't even *try* to open pty's under _WIN32. + * Use SIM_ADDR, not caddr_t for declaring vars that hold addresses. + * float.c: Get rid of #warning. Makes Microsoft C barf. + * interf.c (sim_open): Cast fprintf to (fprintf_ftype) to fix + compiler warning. + * (sim_load sim_create_inferior sim_read): Use prototypes only in + decls, not defs. + * Get rid of enum sim_stop. It's defined in remote-sim.h. + * (sim_stop_reason): Define SIGTRAP if _WIN32. + * sis.h: Include ansidecl.h and remote-sim.h. + +Wed Jul 3 16:05:23 1996 Stu Grossman (grossman@critters.cygnus.com) + + * erc32.c (mec_reset mec_read mec_write memory_read memory_write), + sis.h: Get rid of all uses of long long's. + * (close_port read_uart write_uart uarta_tx): Don't seg fault + when can't open pty's. + * exec.c: Add two new instructions: smul, and divscc. + * interf.c (flush_windows): New routine to flush the register + windows out to the stack just before returning to GDB. Makes + backtraces work much better. + +Wed Jun 26 12:19:11 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, oldincludedir): Removed. + * configure.in (AC_PREREQ): autoconf 2.5 or higher. + (AC_PROG_INSTALL): Added. + * configure: Rebuilt. + +Mon Jun 24 14:19:07 1996 Ian Lance Taylor <ian@cygnus.com> + + * configure.in: Call AC_PROG_CC before running configure.host. + * configure: Rebuild with autoconf 2.10. + +Tue Jun 4 10:37:12 1996 Tom Tromey <tromey@csk3.cygnus.com> + + * Makefile.in (install): Don't check to see if tooldir exists. + Make $(tooldir) and $(tooldir)/bin. + +Mon Jun 3 12:33:38 1996 Ian Lance Taylor <ian@cygnus.com> + + * Makefile.in (end.h): Use explicit ./ when running end. + +Sun May 19 21:05:31 1996 Rob Savoye <rob@chinadoll.cygnus.com> + + * func.c(bfd_load): Don't try to print the filename if the pfbd is + NULL. + * interf.c(sim_load): Pass the whole string, not just the first + byte. + +Version 2.1 26-02-96 +-------------------- + +* Fixed bug in "go" command. + +version 2.0 05-02-96 +-------------------- + +* Fixed bug in interrupt force register (erc32.c). + +* Change file load function to use bfd_openr. + +* SIS should now be endian independent. + +version 1.8 24-11-95 +-------------------- + +* Fixed FPU timing - some sequences of FPU instructions did not calculate + the resource dependencies right. + +* Corrected STDFQ when qne = 0 (again!). The ftt is set to sequence_error + but no FPU trap is generated. + +version 1.7.1 31-10-95 +-------------------- + +* Corrected STDFQ when qne = 0. Now, a trap is immidiately generated but + the FPU stays in execute mode. + +* Corrected JMPL and RETT timing (these instructions takes two cycles). + + +version 1.7 25-10-95 +-------------------- + +* Interrupt during annuled instruction corrupted return address - fixed. + + +version 1.6.2 25-10-95 +-------------------- + +* Added -DFAST_UART to Makefile + + +version 1.6.1 24-10-95 +-------------------- + +* Fixed bug in STDFQ which caused bus error + + +version 1.6 02-10-95 +-------------------- + +* Modified srt0.s to include code that initiates registers in IU and FPU + and initializes the data segment. The simulator 'load' command does not + longer initialize the data segment! + +* Corrected MEC timer operation; scalers now divide the frequency by + (scaler_value + 1). + +* MEC breakpoints are not checked during store operation + + +version 1.5 14-09-95 +-------------------- + +* Fixed some bugs in the cycle counting for IU & FPU instructions. + +* Fixed bug that allowed an annuled instruction to cause memory exception. + +* The *ws parameter in mem.c should now contain the number of waitstates + required by the memory access (was total number of cycles). + +* The supplied srt0.s now clears the BSS (thanks Joel). + +version 1.4 22-08-95 +-------------------- + +* Added a '-g' switch to enable/disable the GNU readline(), which cause +some problems on solaris 2.x machines. + +* Enabled MEC watchpoint and breakpoint function to mem.c. Performance +may suffer a bit ... + +NOTE: The UARTs are now connected to /dev/ttypc and /dev/ttypd. + +version 1.3 26-07-95 +-------------------- + +* Fixed bug in mulscc instruction (how could that ever have worked?) + +* Fixed bug in UART B (flushed characters on UART A), thanks Paul. + +version 1.2 13-07-95 +-------------------- + +* Fixed bug in interrupt handling (wrong interrupt selected when more that +one interrupt pending) + +* Fixed updating of condition codes during logical instructions (carry and +overflow were not reset) + +* Fixed bug in WRTBR (tt field was wrongly over-written) + +version 1.1 07-07-95 +-------------------- + +* Fixed several bugs in the interrupt handler and callback routines. +(reported by Paul Warren, Alsys) diff --git a/sim/erc32/Makefile.in b/sim/erc32/Makefile.in new file mode 100644 index 0000000..260641a --- /dev/null +++ b/sim/erc32/Makefile.in @@ -0,0 +1,75 @@ +# Makefile template for Configure for the erc32sim library. +# Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc. +# Written by Cygnus Support +# Modified by J.Gaisler ESA/ESTEC +# +# 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 + +TERMCAP_LIB = @TERMCAP@ + +SIM_OBJS = exec.o erc32.o func.o help.o float.o interf.o +SIM_EXTRA_LIBS = ../../readline/libreadline.a $(TERMCAP_LIB) -lm +SIM_EXTRA_LIBDEPS = ../../readline/libreadline.a +SIM_EXTRA_ALL = sis +SIM_EXTRA_INSTALL = install-sis +SIM_EXTRA_CLEAN = clean-sis + +# UARTS run at about 115200 baud (simulator time). Add -DFAST_UART to +# CFLAGS if faster (infinite) UART speed is desired. Might affect the +# behaviour of UART interrupt routines ... +SIM_EXTRA_CFLAGS = -DSTAT -DFAST_UART -DIUREV0 -DMECREV0 + +## COMMON_POST_CONFIG_FRAG + +# `sis' doesn't need interf.o. +SIS_OFILES = exec.o erc32.o func.o help.o float.o + +sis: sis.o $(SIS_OFILES) $(COMMON_OBJS) $(LIBDEPS) + $(CC) $(ALL_CFLAGS) -o sis \ + sis.o $(SIS_OFILES) $(COMMON_OBJS) $(EXTRA_LIBS) + +# FIXME: This computes the build host's endianness, doesn't it? +# There is AC_C_BIGENDIAN but it doesn't handle float endianness. +# [Are int/float endians every different on a sparc?] +end: $(srcdir)/end.c + $(CC_FOR_BUILD) $(srcdir)/end.c -o end +end.h: end + ./end > end.h + +# Copy the files into directories where they will be run. +install-sis: installdirs + n=`echo sis | sed '$(program_transform_name)'`; \ + $(INSTALL_PROGRAM) sis $(bindir)/$$n + +clean-sis: + rm -f sis end end.h + +configure: + @echo "Rebuilding configure..." + if [ x"${srcdir}" = x"@srcdir@" ] ; then \ + srcdir=. ; export srcdir ; \ + else true ; fi ; \ + (cd $${srcdir}; autoconf --localdir=../common) + +# Circumvent Sun Make bug with VPATH. +erc32.o: erc32.c sis.h end.h +exec.o: exec.c sis.h end.h +float.o: float.c sis.h end.h +func.o: func.c +help.o: help.c +interf.o: interf.c sis.h end.h +sis.o: sis.c sis.h end.h diff --git a/sim/erc32/NEWS b/sim/erc32/NEWS new file mode 100644 index 0000000..dd24b7b --- /dev/null +++ b/sim/erc32/NEWS @@ -0,0 +1,108 @@ + +version 2.0 05-02-96 +-------------------- + +* Switched to bfd library. Any supported format (elf, coff, ...) can be used. +* The UART devices can be set through -uart1 and -uart2 switches. +* Switched to GNU readline. +* Added -c option to run batch files at startup +* 'reg' command can show different register windows (eg 'reg w3'). +* Use 'help' for online help on simulator commands + +version 1.8.1 20-01-96 +-------------------- + +* added -mevrev0 switch to simulate MEC rev.0 bugs in timer and uart + +* added -iurev0 switch to simulate IU rev.0 jmpl/restore bug + +* Added sis command 'batch' to run batch files + + +version 1.8 30-10-95 +-------------------- + +* Added s-record support. Use the '-s' switch with sis or the 'load' command. + +* IU load dependencies are now modelled + +version 1.7 30-10-95 +-------------------- + +* Power-down mode implemented in erc32.c. + +* Performance display shows the ratio between simulator-time and real-time. + + +version 1.6.2 25-10-95 +-------------------- + +* The UARTs can now be run at a given speed (simulator time) to better + simulate the behaviour of interrupt routines. The "true mode" is + selected through a compile switch in the makefile. + + +version 1.6 28-09-95 +-------------------- + +* Major reorganisation of the code. mec.c and mem.c merged into erc32.c. + +* The load command does NOT longer load the initialised data at an address + defined by .bdata. This is done in srt0.s using _environ. + +* Additional MEC functionallity added - software reset, memory access + protection and waitstate configuration register. + +* interf.c - a GDB interface added + +* -v switch (verbose) added + +version 1.5 14-09-95 +-------------------- + +* Added a instruction trace buffer, enabled through the 'hist' command. + +* Added a 'perf' command to display statistics such as instruction mix, + CPI, FPU holds etc. + +* Added -nfp switch to disable FPU. + +* Added -freq switch to set simulated frequency. + +version 1.4 22-08-95 +-------------------- + +* A -g is provided for those who have problems with GNU readline(). + +version 1.3 26-07-95 +-------------------- + +* No major news, just a bug fix release ... + + +version 1.2 13-07-95 +-------------------- + +* Added setting of IU registers through the 'reg' command. See README. + +* The GNU readline() function is used for command input. However, a +ctrl-D still kills the simulator ... + + +version 1.1 07-07-95 +-------------------- + + +* Added a 'go' command + +* Added cycle counting for interrupt overhead. + +* Function 'get_mem_ptr' takes one more parameter to avoid segmentation + faults if a.out files are loaded outside the simulated memory. See README. + +* Added user-defined function sim_stop(). + +* Added a reset command. See README. + +* Implemented buffered output for MEC uarts to improve output speed. + diff --git a/sim/erc32/README.erc32 b/sim/erc32/README.erc32 new file mode 100644 index 0000000..f413599 --- /dev/null +++ b/sim/erc32/README.erc32 @@ -0,0 +1,130 @@ + +1. MEC and ERC32 emulation + +The file 'erc32.c' contains a model of the MEC, 512 K rom and 4 M ram. + +The following paragraphs outline the implemented MEC functions. + +1.1 UARTs + +The UARTs are connected to two pseudo-devices, /dev/ttypc and /dev/ttypd. +The following registers are implemeted: + +- UART A RX and TX register (0x01f800e0) +- UART B RX and TX register (0x01f800e4) +- UART status register (0x01f800e8) + +To speed up simulation, the UARTs operate at approximately 115200 baud. +The UARTs generate interrupt 4 and 5 after each received or transmitted +character. The error interrupt is generated if overflow occurs - other +errors cannot occure. + +1.2 Real-time clock and general pupose timer A + +The following registers are implemeted: + +- Real-time clock timer (0x01f80080, read-only) +- Real-time clock scaler program register (0x01f80084, write-only) +- Real-time clock counter program register (0x01f80080, write-only) + +- Genearl pupose timer (0x01f80088, read-only) +- Real-time clock scaler program register (0x01f8008c, write-only) +- General purpose timer counter prog. register (0x01f80088, write-only) + +- Timer control register (0x01f80098, write-only) + +1.3 Interrupt controller + +The interrupt controller is implemented as in the MEC specification with +the exception of the interrupt shape register. Since external interrupts +are not possible, the interrupt shape register is not implemented. The +only internal interrupts that are generated are the real-time clock, +the general purpose timer and UARTs. However, all 15 interrupts +can be tested via the interrupt force register. + +The following registers are implemeted: + +- Interrupt pending register (0x01f80048, read-only) +- Interrupt mask register (0x01f8004c, read-write) +- Interrupt clear register (0x01f80050, write-only) +- Interrupt force register (0x01f80054, read-write) + +1.4 Breakpoint and watchpoint register + +The breakpoint and watchpoint functions are implemented as in the MEC +specification. Traps are correctly generated, and the system fault status +register is updated accordingly. Implemeted registers are: + +- Debug control register (0x01f800c0, read-write) +- Breakpoint register (0x01f800c4, write-only) +- Watchpoint register (0x01f800c8, write-only) +- System fault status register (0x01f800a0, read-write) +- Firts failing address register (0x01f800a4, read-write) + + +1.5 Memory interface + +The following memory areas are valid for the ERC32 simulator: + +0x00000000 - 0x00080000 ROM (512 Kbyte, loaded at start-up) +0x02000000 - 0x02400000 RAM (4 Mbyte, initialised to 0x0) +0x01f80000 - 0x01f800ff MEC registers + +Access to unimplemented MEC registers or non-existing memory will result +in a memory exception trap. However, access to unimplemented MEC registers +in the area 0x01f80000 - 0x01f80100 will not cause a memory exception trap. +The written value will be stored in a register and can be read back. It +does however not affect the function in any way. + +The memory configuartion register is used to define available memory +in the system. The fields RSIZ and PSIZ are used to set RAM and ROM +size, the remaining fields are not used. NOTE: after reset, the MEC +is set to decode 4 Kbyte of ROM and 256 Kbyte of RAM. The memory +configuration register has to be updated to reflect the available memory. + +The waitstate configuration register is used to generate waitstates. +This register must also be updated with the correct configuration after +reset. + +The memory protection scheme is implemented - it is enabled through bit 3 +in the MEC control register. + +The following registers are implemeted: + +- MEC control register (bit 3 only) (0x01f80000, read-write) +- Memory control register (0x01f80010, read-write) +- Waitstate configuration register (0x01f80018, read-write) +- Memory access register 0 (0x01f80020, read-write) +- Memory access register 1 (0x01f80024, read-write) + +1.6 Watchdog + +The watchdog is implemented as in the specification. The input clock is +always the system clock regardsless of WDCS bit in mec configuration +register. + +The following registers are implemeted: + +- Watchdog program and acknowledge register (0x01f80060, write-only) +- Watchdog trap door set register (0x01f80064, write-only) + +1.7 Software reset register + +Implemented as in the specification (0x01f800004, write-only). + +1.8 Power-down mode + +The power-down register (0x01f800008) is implemented as in the specification. +However, if the simulator event queue is empty, power-down mode is not +entered since no interrupt would be generated to exit from the mode. A +Ctrl-C in the simulator window will exit the power-down mode. + +1.9 MEC control register + +The following bits are implemented in the MEC control register: + +Bit Name Function +0 PRD Power-down mode enable +1 SWR Soft reset enable +3 APR Access protection enable + diff --git a/sim/erc32/README.gdb b/sim/erc32/README.gdb new file mode 100644 index 0000000..619fcb3 --- /dev/null +++ b/sim/erc32/README.gdb @@ -0,0 +1,67 @@ +How to use SIS with GDB +----------------------- + +1. Building GDB with SIS + +To build GDB with the SIS/ERC32 simulator, configure with option +'--target sparc-erc32-aout' and build as usual. + +2. Attaching the simulator + +To attach GDB to the simulator, use: + +target sim [options] [files] + +The following options are supported: + + -nfp Disable FPU. FPops will cause an FPU disabled trap. + + -freq <f> Set the simulated "system clock" to <f> MHz. + + -v Verbose mode. + + -nogdb Disable GDB breakpoint handling (see below) + +The listed [files] are expected to be in aout format and will be +loaded in the simulator memory prior. This could be used to load +a boot block at address 0x0 if the application is linked to run +from RAM (0x2000000). + +To start debugging a program type 'load <program>' and debug as +usual. + +The native simulator commands can be reached using the GDB 'sim' +command: + +sim <sis_command> + +Direct simulator commands during a GDB session must be issued +with care not to disturb GDB's operation ... + +For info on supported ERC32 functionality, see README.sis. + + +3. Loading aout files + +The GDB load command loads an aout file into the simulator +memory with the data section starting directly after the text +section regardless of wich start address was specified for the data +at link time! This means that your applications either has to include +a routine that initialise the data segment at the proper address or +link with the data placed directly after the text section. + +A copying routine is fairly simple, just copy all data between +_etext and _data to a memory loaction starting at _environ. This +should be done at the same time as the bss is cleared (in srt0.s). + + +4. GDB breakpoint handling + +GDB inserts breakpoint in the form of the 'ta 1' instruction. The +GDB-integrated simulator will therefore recognize the breakpoint +instruction and return control to GDB. If the application uses +'ta 1', the breakpoint detection can be disabled with the -nogdb +switch. In this case however, GDB breakpoints will not work. + + +Report problems to Jiri Gaisler ESA/ESTEC (jgais@wd.estec.esa.nl) diff --git a/sim/erc32/README.sis b/sim/erc32/README.sis new file mode 100644 index 0000000..b119f03 --- /dev/null +++ b/sim/erc32/README.sis @@ -0,0 +1,356 @@ + +SIS - Sparc Instruction Simulator README file (v2.0, 05-02-1996) +------------------------------------------------------------------- + +1. Introduction + +The SIS is a SPARC V7 architecture simulator. It consist of two parts, +the simulator core and a user defined memory module. The simulator +core executes the instructions while the memory module emulates memory +and peripherals. + +2. Usage + +The simulator is started as follows: + +sis [-uart1 uart_device1] [-uart2 uart_device2] + [-nfp] [-freq frequency] [-c batch_file] [files] + +The default uart devices for SIS are /dev/ptypc and /dev/ptypd. The +-uart[1,2] switch can be used to connect the uarts to other devices. +Use 'tip /dev/ttypc' to connect a terminal emulator to the uarts. +The '-nfp' will disable the simulated FPU, so each FPU instruction will +generate a FPU disabled trap. The '-freq' switch can be used to define +which "frequency" the simulator runs at. This is used by the 'perf' +command to calculated the MIPS figure for a particular configuration. +The give frequency must be an integer indicating the frequency in MHz. + +The -c option indicates that sis commands should be read from 'batch_file' +at startup. + +Files to be loaded must be in one of the supported formats (see INSTALLATION), +and will be loaded into the simulated memory. The file formats are +automatically recognised. + +The script 'startsim' will start the simulator in one xterm window and +open a terminal emulator (tip) connected to the UART A in a second +xterm window. Below is description of commands that are recognized by +the simulator. The command-line is parsed using GNU readline. A command +history of 64 commands is maintained. Use the up/down arrows to recall +previous commands. For more details, see the readline documentation. + +batch <file> + +Execute a batch file of SIS commands. + ++bp <address> + +Adds an breakpoint at address <address>. + +bp + +Prints all breakpoints + +-bp <num> + +Deletes breakpoint <num>. Use 'bp' to see which number is assigned to the +breakpoints. + +cont [inst_count] + +Continue execution at present position, optionally for [inst_count] +instructions. + +dis [addr] [count] + +Disassemble [count] instructions at address [addr]. Default values for +count is 16 and addr is the present address. + +echo <string> + +Print <string> to the simulator window. + +float + +Prints the FPU registers + +go <address> [inst_count] + +The go command will set pc to <address> and npc to <address> + 4, and start +execution. No other initialisation will be done. If inst_count is given, +execution will stop after the specified number of instructions. + +help + +Print a small help menu for the SIS commands. + +hist [trace_length] + +Enable the instruction trace buffer. The 'trace_length' last executed +instructions will be placed in the trace buffer. A 'hist' command without +a trace_length will display the trace buffer. Specifying a zero trace +length will disable the trace buffer. + +load <file_name> + +Loads a file into simulator memory. + +mem [addr] [count] + +Display memory at [addr] for [count] bytes. Same default values as above. + +quit + +Exits the simulator. + +perf [reset] + +The 'perf' command will display various execution statistics. A 'perf reset' +command will reset the statistics. This can be used if statistics shall +be calculated only over a part of the program. The 'run' and 'reset' +command also resets the statistic information. + +reg [reg_name] [value] + +Prints and sets the IU regiters. 'reg' without parameters prints the IU +registers. 'reg [reg_name] [value]' sets the corresponding register to +[value]. Valid register names are psr, tbr, wim, y, g1-g7, o0-o7 and +l0-l7. + +reset + +Performs a power-on reset. This command is equal to 'run 0'. + +run [inst_count] + +Resets the simulator and starts execution from address 0. If an instruction +count is given (inst_count), the simulator will stop after the specified +number of instructions. The event queue is emptied but any set breakpoints +remain. + +step + +Equal to 'trace 1' + +tra [inst_count] + +Starts the simulator at the present position and prints each instruction +it executes. If an instruction count is given (inst_count), the simulator +will stop after the specified number of instructions. + +Typing a 'Ctrl-C' will interrupt a running simulator. + +Short forms of the commands are allowed, e.g 'c' 'co' or 'con' are all +interpreted as 'cont'. + + +3. Simulator core + +The SIS emulates the behavior of the 90C601E and 90C602E sparc IU and +FPU from Matra MHS. These are roughly equivalent to the Cypress C601 +and C602. The simulator is cycle true, i.e a simulator time is +maintained and inremented according the IU and FPU instruction timing. +The parallel execution between the IU and FPU is modelled, as well as +stalls due to operand dependencies (FPU). The core interacts with the +user-defined memory modules through a number of functions. The memory +module must provide the following functions: + +int memory_read(asi,addr,data,ws) +int asi; +unsigned int addr; +unsigned int *data; +int *ws; + +int memory_write(asi,addr,data,sz,ws) +int asi; +unsigned int addr; +unsigned int *data; +int sz; +int *ws; + +int sis_memory_read(addr, data, length) +unsigned int addr; +char *data; +unsigned int length; + +int sis_memory_write(addr, data, length) +unsigned int addr; +char *data; +unsigned int length; + +int init_sim() + +int reset() + +int error_mode(pc) +unsigned int pc; + +memory_read() is used by the simulator to fetch instructions and +operands. The address space identifier (asi) and address is passed as +parameters. The read data should be assigned to the data pointer +(*data) and the number of waitstate to *ws. 'memory_read' should return +0 on success and 1 on failure. A failure will cause a data or +instruction fetch trap. memory_read() always reads one 32-bit word. + +sis_memory_read() is used by the simulator to display and disassemble +memory contants. The function should copy 'length' bytes of the simulated +memory starting at 'addr' to '*data'. +The sis_memory_read() should return 1 on success and 0 on failure. +Failure should only be indicated if access to unimplemented memory is attempted. + +memory_write() is used to write to memory. In addition to the asi +and address parameters, the size of the written data is given by 'sz'. +The pointer *data points to the data to be written. The 'sz' is coded +as follows: + + sz access type + 0 byte + 1 halfword + 2 word + 3 double-word + +If a double word is written, the most significant word is in data[0] and +the least significant in data[1]. + +sis_memory_write() is used by the simulator during loading of programs. +The function should copy 'length' bytes from *data to the simulated +memory starting at 'addr'. sis_memory_write() should return 1 on +success and 0 on failure. Failure should only be indicated if access +to unimplemented memory is attempted. See erc32.c for more details +on how to define the memory emulation functions. + +The 'init_sim' is called once when the simulator is started. This function +should be used to perform initialisations of user defined memory or +peripherals that only have to be done once, such as opening files etc. + +The 'reset' is called every time the simulator is reset, i.e. when a +'run' command is given. This function should be used to simulate a power +on reset of memory and peripherals. + +error_mode() is called by the simulator when the IU goes into error mode, +typically if a trap is caused when traps are disabled. The memory module +can then take actions, such as issue a reset. + +sys_reset() can be called by the memory module to reset the simulator. A +reset will empty the event queue and perform a power-on reset. + +4. Events and interrupts + +The simulator supports an event queue and the generation of processor +interrupts. The following functions are available to the user-defined +memory module: + +event(cfunc,arg,delta) +void (*cfunc)(); +int arg; +unsigned int delta; + +set_int(level,callback,arg) +int level; +void (*callback)(); +int arg; + +clear_int(level) +int level; + +sim_stop() + +The 'event' functions will schedule the execution of the function 'cfunc' +at time 'now + delta' clock cycles. The parameter 'arg' is passed as a +parameter to 'cfunc'. + +The 'set_int' function set the processor interrupt 'level'. When the interrupt +is taken, the function 'callback' is called with the argument 'arg'. This +will also clear the interrupt. An interrupt can be cleared before it is +taken by calling 'clear_int' with the appropriate interrupt level. + +The sim_stop function is called each time the simulator stops execution. +It can be used to flush buffered devices to get a clean state during +single stepping etc. + +See 'erc32.c' for examples on how to use events and interrupts. + +5. Memory module + +The supplied memory module (erc32.c) emulates the functions of memory and +the MEC asic developed for the 90C601/2. It includes the following functions: + +* UART A & B +* Real-time clock +* General purpose timer +* Interrupt controller +* Breakpoint register +* Watchpoint register +* 512 Kbyte ROM +* 4 Mbyte RAM + +See README.erc32 on how the MEC functions are emulated. For a detailed MEC +specification, look at the ERC32 home page at URL: + +http://www.estec.esa.nl/wsmwww/erc32 + +6. Compile and linking programs + +The directory 'examples' contain some code fragments for SIS. +The script gccx indicates how the native sunos gcc and linker can be used +to produce executables for the simulator. To compile and link the provided +'hello.c', type 'gccx hello.c'. This will build the executable 'hello'. +Start the simulator by running 'startsim hello', and issue the command 'run. +After the program is terminated, the IU will be force to error mode through +a software trap and halt. + +The programs are linked with a start-up file, srt0.S. This file includes +the traptable and window underflow/overflow trap routines. + +7. IU and FPU instruction timing. + +The simulator provides cycle true simulation. The following table shows +the emulated instruction timing for 90C601E & 90C602E: + +Instructions Cycles + +jmpl, rett 2 +load 2 +store 3 +load double 3 +store double 4 +other integer ops 1 +fabs 2 +fadds 4 +faddd 4 +fcmps 4 +fcmpd 4 +fdivs 20 +fdivd 35 +fmovs 2 +fmuls 5 +fmuld 9 +fnegs 2 +fsqrts 37 +fsqrtd 65 +fsubs 4 +fsubd 4 +fdtoi 7 +fdots 3 +fitos 6 +fitod 6 +fstoi 6 +fstod 2 + +The parallel operation between the IU and FPU is modelled. This means +that a FPU instruction will execute in parallel with other instructions as +long as no data or resource dependency is detected. See the 90C602E data +sheet for the various types of dependencies. Tracing using the 'trace' +command will display the current simulator time in the left column. This +time indicates when the instruction is fetched. If a dependency is detetected, +the following fetch will be delayed until the conflict is resolved. + +The load dependency in the 90C601E is also modelled - if the destination +register of a load instruction is used by the following instruction, an +idle cycle is inserted. + +8. FPU implementation + +The simulator maps floating-point operations on the hosts floating point +capabilities. This means that accuracy and generation of IEEE exceptions is +host dependent. diff --git a/sim/erc32/acconfig.h b/sim/erc32/acconfig.h new file mode 100644 index 0000000..f9b87a1 --- /dev/null +++ b/sim/erc32/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/erc32/config.in b/sim/erc32/config.in new file mode 100644 index 0000000..1f87a2b --- /dev/null +++ b/sim/erc32/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/erc32/configure b/sim/erc32/configure new file mode 100755 index 0000000..793acef --- /dev/null +++ b/sim/erc32/configure @@ -0,0 +1,3932 @@ +#! /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 stdlib.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 + + +echo $ac_n "checking for main in -ltermcap""... $ac_c" 1>&6 +echo "configure:3410: checking for main in -ltermcap" >&5 +ac_lib_var=`echo termcap'_'main | 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="-ltermcap $LIBS" +cat > conftest.$ac_ext <<EOF +#line 3418 "configure" +#include "confdefs.h" + +int main() { +main() +; return 0; } +EOF +if { (eval echo configure:3425: \"$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 + TERMCAP=-ltermcap +else + echo "$ac_t""no" 1>&6 +TERMCAP="" +fi + + + + + +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 +s%@TERMCAP@%$TERMCAP%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/erc32/configure.in b/sim/erc32/configure.in new file mode 100644 index 0000000..c139f71 --- /dev/null +++ b/sim/erc32/configure.in @@ -0,0 +1,13 @@ +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(stdlib.h) + +AC_CHECK_LIB(termcap, main, TERMCAP=-ltermcap, TERMCAP="") +AC_SUBST(TERMCAP) + +SIM_AC_OUTPUT diff --git a/sim/erc32/end.c b/sim/erc32/end.c new file mode 100644 index 0000000..973fd79 --- /dev/null +++ b/sim/erc32/end.c @@ -0,0 +1,26 @@ +#include <stdio.h> + +int +main() +{ + + unsigned int u1; + char *c; + double d1; + float *f1; + + c = (char *) &u1; + u1 = 0x0F; + if (c[0] == 0x0F) + puts("#define HOST_LITTLE_ENDIAN\n"); + else + puts("#define HOST_BIG_ENDIAN\n"); + + d1 = 1.0; + f1 = (float *) &d1; + if (*((int *) f1) != 0x3ff00000) + puts("#define HOST_LITTLE_ENDIAN_FLOAT\n"); + else + puts("#define HOST_BIG_ENDIAN_FLOAT\n"); + return 0; +} diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c new file mode 100644 index 0000000..0b3f3ac --- /dev/null +++ b/sim/erc32/erc32.c @@ -0,0 +1,1888 @@ +/* + * This file is part of SIS. + * + * SIS, SPARC instruction simulator V2.5 Copyright (C) 1995 Jiri Gaisler, + * European Space Agency + * + * 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., 675 + * Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* The control space devices */ + +#include <sys/types.h> +#include <stdio.h> +#include <termios.h> +#include <sys/fcntl.h> +#include <sys/file.h> +#include <unistd.h> +#include "sis.h" +#include "end.h" +#include "sim-config.h" + +extern int ctrl_c; +extern int32 sis_verbose; +extern int32 sparclite, sparclite_board; +extern int rom8,wrp,uben; +extern char uart_dev1[], uart_dev2[]; + +int dumbio = 0; /* normal, smart, terminal oriented IO by default */ + +/* MEC registers */ +#define MEC_START 0x01f80000 +#define MEC_END 0x01f80100 + +/* Memory exception waitstates */ +#define MEM_EX_WS 1 + +/* ERC32 always adds one waitstate during RAM std */ +#define STD_WS 1 + +#ifdef ERRINJ +extern int errmec; +#endif + +/* The target's byte order is big-endian by default until we load a + little-endian program. */ + +int current_target_byte_order = BIG_ENDIAN; + +#define MEC_WS 0 /* Waitstates per MEC access (0 ws) */ +#define MOK 0 + +/* MEC register addresses */ + +#define MEC_MCR 0x000 +#define MEC_SFR 0x004 +#define MEC_PWDR 0x008 +#define MEC_MEMCFG 0x010 +#define MEC_IOCR 0x014 +#define MEC_WCR 0x018 + +#define MEC_MAR0 0x020 +#define MEC_MAR1 0x024 + +#define MEC_SSA1 0x020 +#define MEC_SEA1 0x024 +#define MEC_SSA2 0x028 +#define MEC_SEA2 0x02C +#define MEC_ISR 0x044 +#define MEC_IPR 0x048 +#define MEC_IMR 0x04C +#define MEC_ICR 0x050 +#define MEC_IFR 0x054 +#define MEC_WDOG 0x060 +#define MEC_TRAPD 0x064 +#define MEC_RTC_COUNTER 0x080 +#define MEC_RTC_RELOAD 0x080 +#define MEC_RTC_SCALER 0x084 +#define MEC_GPT_COUNTER 0x088 +#define MEC_GPT_RELOAD 0x088 +#define MEC_GPT_SCALER 0x08C +#define MEC_TIMER_CTRL 0x098 +#define MEC_SFSR 0x0A0 +#define MEC_FFAR 0x0A4 +#define MEC_ERSR 0x0B0 +#define MEC_DBG 0x0C0 +#define MEC_TCR 0x0D0 + +#define MEC_BRK 0x0C4 +#define MEC_WPR 0x0C8 + +#define MEC_UARTA 0x0E0 +#define MEC_UARTB 0x0E4 +#define MEC_UART_CTRL 0x0E8 +#define SIM_LOAD 0x0F0 + +/* Memory exception causes */ +#define PROT_EXC 0x3 +#define UIMP_ACC 0x4 +#define MEC_ACC 0x6 +#define WATCH_EXC 0xa +#define BREAK_EXC 0xb + +/* Size of UART buffers (bytes) */ +#define UARTBUF 1024 + +/* Number of simulator ticks between flushing the UARTS. */ +/* For good performance, keep above 1000 */ +#define UART_FLUSH_TIME 3000 + +/* MEC timer control register bits */ +#define TCR_GACR 1 +#define TCR_GACL 2 +#define TCR_GASE 4 +#define TCR_GASL 8 +#define TCR_TCRCR 0x100 +#define TCR_TCRCL 0x200 +#define TCR_TCRSE 0x400 +#define TCR_TCRSL 0x800 + +/* New uart defines */ +#define UART_TX_TIME 1000 +#define UART_RX_TIME 1000 +#define UARTA_DR 0x1 +#define UARTA_SRE 0x2 +#define UARTA_HRE 0x4 +#define UARTA_OR 0x40 +#define UARTA_CLR 0x80 +#define UARTB_DR 0x10000 +#define UARTB_SRE 0x20000 +#define UARTB_HRE 0x40000 +#define UARTB_OR 0x400000 +#define UARTB_CLR 0x800000 + +#define UART_DR 0x100 +#define UART_TSE 0x200 +#define UART_THE 0x400 + +/* MEC registers */ + +static char fname[256]; +static int32 find = 0; +static uint32 mec_ssa[2]; /* Write protection start address */ +static uint32 mec_sea[2]; /* Write protection end address */ +static uint32 mec_wpr[2]; /* Write protection control fields */ +static uint32 mec_sfsr; +static uint32 mec_ffar; +static uint32 mec_ipr; +static uint32 mec_imr; +static uint32 mec_isr; +static uint32 mec_icr; +static uint32 mec_ifr; +static uint32 mec_mcr; /* MEC control register */ +static uint32 mec_memcfg; /* Memory control register */ +static uint32 mec_wcr; /* MEC waitstate register */ +static uint32 mec_iocr; /* MEC IO control register */ +static uint32 posted_irq; +static uint32 mec_ersr; /* MEC error and status register */ +static uint32 mec_tcr; /* MEC test comtrol register */ + +static uint32 rtc_counter; +static uint32 rtc_reload; +static uint32 rtc_scaler; +static uint32 rtc_scaler_start; +static uint32 rtc_enabled; +static uint32 rtc_cr; +static uint32 rtc_se; + +static uint32 gpt_counter; +static uint32 gpt_reload; +static uint32 gpt_scaler; +static uint32 gpt_scaler_start; +static uint32 gpt_enabled; +static uint32 gpt_cr; +static uint32 gpt_se; + +static uint32 wdog_scaler; +static uint32 wdog_counter; +static uint32 wdog_rst_delay; +static uint32 wdog_rston; + +enum wdog_type { + init, disabled, enabled, stopped +}; + +static enum wdog_type wdog_status; + + +/* ROM size 1024 Kbyte */ +#define ROM_SZ 0x100000 +#define ROM_MASK 0x0fffff + +/* RAM size 4 Mbyte */ +#define RAM_START 0x02000000 +#define RAM_END 0x02400000 +#define RAM_MASK 0x003fffff + +/* SPARClite boards all seem to have RAM at the same place. */ +#define RAM_START_SLITE 0x40000000 +#define RAM_END_SLITE 0x40400000 +#define RAM_MASK_SLITE 0x003fffff + +/* Memory support variables */ + +static uint32 mem_ramr_ws; /* RAM read waitstates */ +static uint32 mem_ramw_ws; /* RAM write waitstates */ +static uint32 mem_romr_ws; /* ROM read waitstates */ +static uint32 mem_romw_ws; /* ROM write waitstates */ +static uint32 mem_ramstart; /* RAM start */ +static uint32 mem_ramend; /* RAM end */ +static uint32 mem_rammask; /* RAM address mask */ +static uint32 mem_ramsz; /* RAM size */ +static uint32 mem_romsz; /* ROM size */ +static uint32 mem_accprot; /* RAM write protection enabled */ +static uint32 mem_blockprot; /* RAM block write protection enabled */ + +static unsigned char romb[ROM_SZ]; +static unsigned char ramb[RAM_END - RAM_START]; + + +/* UART support variables */ + +static int32 fd1, fd2; /* file descriptor for input file */ +static int32 Ucontrol; /* UART status register */ +static unsigned char aq[UARTBUF], bq[UARTBUF]; +static int32 anum, aind = 0; +static int32 bnum, bind = 0; +static char wbufa[UARTBUF], wbufb[UARTBUF]; +static unsigned wnuma; +static unsigned wnumb; +static FILE *f1in, *f1out, *f2in, *f2out; +static struct termios ioc1, ioc2, iocold1, iocold2; +static int f1open = 0, f2open = 0; + +static char uarta_sreg, uarta_hreg, uartb_sreg, uartb_hreg; +static uint32 uart_stat_reg; +static uint32 uarta_data, uartb_data; + +#ifdef ERA +int era = 0; +int erareg; +#endif + +/* Forward declarations */ + +static void decode_ersr PARAMS ((void)); +#ifdef ERRINJ +static void iucomperr PARAMS ((void)); +#endif +static void mecparerror PARAMS ((void)); +static void decode_memcfg PARAMS ((void)); +static void decode_wcr PARAMS ((void)); +static void decode_mcr PARAMS ((void)); +static void close_port PARAMS ((void)); +static void mec_reset PARAMS ((void)); +static void mec_intack PARAMS ((int32 level)); +static void chk_irq PARAMS ((void)); +static void mec_irq PARAMS ((int32 level)); +static void set_sfsr PARAMS ((uint32 fault, uint32 addr, + uint32 asi, uint32 read)); +static int32 mec_read PARAMS ((uint32 addr, uint32 asi, uint32 *data)); +static int mec_write PARAMS ((uint32 addr, uint32 data)); +static void port_init PARAMS ((void)); +static uint32 read_uart PARAMS ((uint32 addr)); +static void write_uart PARAMS ((uint32 addr, uint32 data)); +static void flush_uart PARAMS ((void)); +static void uarta_tx PARAMS ((void)); +static void uartb_tx PARAMS ((void)); +static void uart_rx PARAMS ((caddr_t arg)); +static void uart_intr PARAMS ((caddr_t arg)); +static void uart_irq_start PARAMS ((void)); +static void wdog_intr PARAMS ((caddr_t arg)); +static void wdog_start PARAMS ((void)); +static void rtc_intr PARAMS ((caddr_t arg)); +static void rtc_start PARAMS ((void)); +static uint32 rtc_counter_read PARAMS ((void)); +static void rtc_scaler_set PARAMS ((uint32 val)); +static void rtc_reload_set PARAMS ((uint32 val)); +static void gpt_intr PARAMS ((caddr_t arg)); +static void gpt_start PARAMS ((void)); +static uint32 gpt_counter_read PARAMS ((void)); +static void gpt_scaler_set PARAMS ((uint32 val)); +static void gpt_reload_set PARAMS ((uint32 val)); +static void timer_ctrl PARAMS ((uint32 val)); +static unsigned char * + get_mem_ptr PARAMS ((uint32 addr, uint32 size)); + +static void fetch_bytes PARAMS ((int asi, unsigned char *mem, + uint32 *data, int sz)); + +static void store_bytes PARAMS ((unsigned char *mem, uint32 *data, int sz)); + +extern int ext_irl; + + +/* One-time init */ + +void +init_sim() +{ + port_init(); +} + +/* Power-on reset init */ + +void +reset() +{ + mec_reset(); + uart_irq_start(); + wdog_start(); +} + +static void +decode_ersr() +{ + if (mec_ersr & 0x01) { + if (!(mec_mcr & 0x20)) { + if (mec_mcr & 0x40) { + sys_reset(); + mec_ersr = 0x8000; + if (sis_verbose) + printf("Error manager reset - IU in error mode\n"); + } else { + sys_halt(); + mec_ersr |= 0x2000; + if (sis_verbose) + printf("Error manager halt - IU in error mode\n"); + } + } else + mec_irq(1); + } + if (mec_ersr & 0x04) { + if (!(mec_mcr & 0x200)) { + if (mec_mcr & 0x400) { + sys_reset(); + mec_ersr = 0x8000; + if (sis_verbose) + printf("Error manager reset - IU comparison error\n"); + } else { + sys_halt(); + mec_ersr |= 0x2000; + if (sis_verbose) + printf("Error manager halt - IU comparison error\n"); + } + } else + mec_irq(1); + } + if (mec_ersr & 0x20) { + if (!(mec_mcr & 0x2000)) { + if (mec_mcr & 0x4000) { + sys_reset(); + mec_ersr = 0x8000; + if (sis_verbose) + printf("Error manager reset - MEC hardware error\n"); + } else { + sys_halt(); + mec_ersr |= 0x2000; + if (sis_verbose) + printf("Error manager halt - MEC hardware error\n"); + } + } else + mec_irq(1); + } +} + +#ifdef ERRINJ +static void +iucomperr() +{ + mec_ersr |= 0x04; + decode_ersr(); +} +#endif + +static void +mecparerror() +{ + mec_ersr |= 0x20; + decode_ersr(); +} + + +/* IU error mode manager */ + +void +error_mode(pc) + uint32 pc; +{ + + mec_ersr |= 0x1; + decode_ersr(); +} + + +/* Check memory settings */ + +static void +decode_memcfg() +{ + if (rom8) mec_memcfg &= ~0x20000; + else mec_memcfg |= 0x20000; + + mem_ramsz = (256 * 1024) << ((mec_memcfg >> 10) & 7); + mem_romsz = (128 * 1024) << ((mec_memcfg >> 18) & 7); + + if (sparclite_board) { + mem_ramstart = RAM_START_SLITE; + mem_ramend = RAM_END_SLITE; + mem_rammask = RAM_MASK_SLITE; + } + else { + mem_ramstart = RAM_START; + mem_ramend = RAM_END; + mem_rammask = RAM_MASK; + } + if (sis_verbose) + printf("RAM start: 0x%x, RAM size: %d K, ROM size: %d K\n", + mem_ramstart, mem_ramsz >> 10, mem_romsz >> 10); +} + +static void +decode_wcr() +{ + mem_ramr_ws = mec_wcr & 3; + mem_ramw_ws = (mec_wcr >> 2) & 3; + mem_romr_ws = (mec_wcr >> 4) & 0x0f; + if (rom8) { + if (mem_romr_ws > 0 ) mem_romr_ws--; + mem_romr_ws = 5 + (4*mem_romr_ws); + } + mem_romw_ws = (mec_wcr >> 8) & 0x0f; + if (sis_verbose) + printf("Waitstates = RAM read: %d, RAM write: %d, ROM read: %d, ROM write: %d\n", + mem_ramr_ws, mem_ramw_ws, mem_romr_ws, mem_romw_ws); +} + +static void +decode_mcr() +{ + mem_accprot = (mec_wpr[0] | mec_wpr[1]); + mem_blockprot = (mec_mcr >> 3) & 1; + if (sis_verbose && mem_accprot) + printf("Memory block write protection enabled\n"); + if (mec_mcr & 0x08000) { + mec_ersr |= 0x20; + decode_ersr(); + } + if (sis_verbose && (mec_mcr & 2)) + printf("Software reset enabled\n"); + if (sis_verbose && (mec_mcr & 1)) + printf("Power-down mode enabled\n"); +} + +/* Flush ports when simulator stops */ + +void +sim_halt() +{ +#ifdef FAST_UART + flush_uart(); +#endif +} + +int +sim_stop(SIM_DESC sd) +{ + ctrl_c = 1; + return 1; +} + +static void +close_port() +{ + if (f1open && f1in != stdin) + fclose(f1in); + if (f2open && f2in != stdin) + fclose(f2in); +} + +void +exit_sim() +{ + close_port(); +} + +static void +mec_reset() +{ + int i; + + find = 0; + for (i = 0; i < 2; i++) + mec_ssa[i] = mec_sea[i] = mec_wpr[i] = 0; + mec_mcr = 0x01350014; + mec_iocr = 0; + mec_sfsr = 0x078; + mec_ffar = 0; + mec_ipr = 0; + mec_imr = 0x7ffe; + mec_isr = 0; + mec_icr = 0; + mec_ifr = 0; + mec_memcfg = 0x10000; + mec_wcr = -1; + mec_ersr = 0; /* MEC error and status register */ + mec_tcr = 0; /* MEC test comtrol register */ + + decode_memcfg(); + decode_wcr(); + decode_mcr(); + + posted_irq = 0; + wnuma = wnumb = 0; + anum = aind = bnum = bind = 0; + + uart_stat_reg = UARTA_SRE | UARTA_HRE | UARTB_SRE | UARTB_HRE; + uarta_data = uartb_data = UART_THE | UART_TSE; + + rtc_counter = 0xffffffff; + rtc_reload = 0xffffffff; + rtc_scaler = 0xff; + rtc_enabled = 0; + rtc_cr = 0; + rtc_se = 0; + + gpt_counter = 0xffffffff; + gpt_reload = 0xffffffff; + gpt_scaler = 0xffff; + gpt_enabled = 0; + gpt_cr = 0; + gpt_se = 0; + + wdog_scaler = 255; + wdog_rst_delay = 255; + wdog_counter = 0xffff; + wdog_rston = 0; + wdog_status = init; + +#ifdef ERA + erareg = 0; +#endif + +} + + + +static void +mec_intack(level) + int32 level; +{ + int irq_test; + + if (sis_verbose) + printf("interrupt %d acknowledged\n", level); + irq_test = mec_tcr & 0x80000; + if ((irq_test) && (mec_ifr & (1 << level))) + mec_ifr &= ~(1 << level); + else + mec_ipr &= ~(1 << level); + chk_irq(); +} + +static void +chk_irq() +{ + int32 i; + uint32 itmp; + int old_irl; + + old_irl = ext_irl; + if (mec_tcr & 0x80000) itmp = mec_ifr; + else itmp = 0; + itmp = ((mec_ipr | itmp) & ~mec_imr) & 0x0fffe; + ext_irl = 0; + if (itmp != 0) { + for (i = 15; i > 0; i--) { + if (((itmp >> i) & 1) != 0) { + if ((sis_verbose) && (i > old_irl)) + printf("IU irl: %d\n", i); + ext_irl = i; + set_int(i, mec_intack, i); + break; + } + } + } +} + +static void +mec_irq(level) + int32 level; +{ + mec_ipr |= (1 << level); + chk_irq(); +} + +static void +set_sfsr(fault, addr, asi, read) + uint32 fault; + uint32 addr; + uint32 asi; + uint32 read; +{ + if ((asi == 0xa) || (asi == 0xb)) { + mec_ffar = addr; + mec_sfsr = (fault << 3) | (!read << 15); + mec_sfsr |= ((mec_sfsr & 1) ^ 1) | (mec_sfsr & 1); + switch (asi) { + case 0xa: + mec_sfsr |= 0x0004; + break; + case 0xb: + mec_sfsr |= 0x1004; + break; + } + } +} + +static int32 +mec_read(addr, asi, data) + uint32 addr; + uint32 asi; + uint32 *data; +{ + + switch (addr & 0x0ff) { + + case MEC_MCR: /* 0x00 */ + *data = mec_mcr; + break; + + case MEC_MEMCFG: /* 0x10 */ + *data = mec_memcfg; + break; + + case MEC_IOCR: + *data = mec_iocr; /* 0x14 */ + break; + + case MEC_SSA1: /* 0x20 */ + *data = mec_ssa[0] | (mec_wpr[0] << 23); + break; + case MEC_SEA1: /* 0x24 */ + *data = mec_sea[0]; + break; + case MEC_SSA2: /* 0x28 */ + *data = mec_ssa[1] | (mec_wpr[1] << 23); + break; + case MEC_SEA2: /* 0x2c */ + *data = mec_sea[1]; + break; + + case MEC_ISR: /* 0x44 */ + *data = mec_isr; + break; + + case MEC_IPR: /* 0x48 */ + *data = mec_ipr; + break; + + case MEC_IMR: /* 0x4c */ + *data = mec_imr; + break; + + case MEC_IFR: /* 0x54 */ + *data = mec_ifr; + break; + + case MEC_RTC_COUNTER: /* 0x80 */ + *data = rtc_counter_read(); + break; + case MEC_RTC_SCALER: /* 0x84 */ + if (rtc_enabled) + *data = rtc_scaler - (now() - rtc_scaler_start); + else + *data = rtc_scaler; + break; + + case MEC_GPT_COUNTER: /* 0x88 */ + *data = gpt_counter_read(); + break; + + case MEC_GPT_SCALER: /* 0x8c */ + if (rtc_enabled) + *data = gpt_scaler - (now() - gpt_scaler_start); + else + *data = gpt_scaler; + break; + + + case MEC_SFSR: /* 0xA0 */ + *data = mec_sfsr; + break; + + case MEC_FFAR: /* 0xA4 */ + *data = mec_ffar; + break; + + case SIM_LOAD: + fname[find] = 0; + if (find == 0) + strcpy(fname, "simload"); + find = bfd_load(fname); + if (find == -1) + *data = 0; + else + *data = 1; + find = 0; + break; + + case MEC_ERSR: /* 0xB0 */ + *data = mec_ersr; + break; + + case MEC_TCR: /* 0xD0 */ + *data = mec_tcr; + break; + + case MEC_UARTA: /* 0xE0 */ + case MEC_UARTB: /* 0xE4 */ + if (asi != 0xb) { + set_sfsr(MEC_ACC, addr, asi, 1); + return (1); + } + *data = read_uart(addr); + break; + + case MEC_UART_CTRL: /* 0xE8 */ + + *data = read_uart(addr); + break; + + default: + set_sfsr(MEC_ACC, addr, asi, 1); + return (1); + break; + } + return (MOK); +} + +static int +mec_write(addr, data) + uint32 addr; + uint32 data; +{ + if (sis_verbose > 1) + printf("MEC write a: %08x, d: %08x\n",addr,data); + switch (addr & 0x0ff) { + + case MEC_MCR: + mec_mcr = data; + decode_mcr(); + if (mec_mcr & 0x08000) mecparerror(); + break; + + case MEC_SFR: + if (mec_mcr & 0x2) { + sys_reset(); + mec_ersr = 0x4000; + if (sis_verbose) + printf(" Software reset issued\n"); + } + break; + + case MEC_IOCR: + mec_iocr = data; + if (mec_iocr & 0xC0C0C0C0) mecparerror(); + break; + + case MEC_SSA1: /* 0x20 */ + if (data & 0xFE000000) mecparerror(); + mec_ssa[0] = data & 0x7fffff; + mec_wpr[0] = (data >> 23) & 0x03; + mem_accprot = mec_wpr[0] || mec_wpr[1]; + if (sis_verbose && mec_wpr[0]) + printf("Segment 1 memory protection enabled (0x02%06x - 0x02%06x)\n", + mec_ssa[0] << 2, mec_sea[0] << 2); + break; + case MEC_SEA1: /* 0x24 */ + if (data & 0xFF800000) mecparerror(); + mec_sea[0] = data & 0x7fffff; + break; + case MEC_SSA2: /* 0x28 */ + if (data & 0xFE000000) mecparerror(); + mec_ssa[1] = data & 0x7fffff; + mec_wpr[1] = (data >> 23) & 0x03; + mem_accprot = mec_wpr[0] || mec_wpr[1]; + if (sis_verbose && mec_wpr[1]) + printf("Segment 2 memory protection enabled (0x02%06x - 0x02%06x)\n", + mec_ssa[1] << 2, mec_sea[1] << 2); + break; + case MEC_SEA2: /* 0x2c */ + if (data & 0xFF800000) mecparerror(); + mec_sea[1] = data & 0x7fffff; + break; + + case MEC_UARTA: + case MEC_UARTB: + if (data & 0xFFFFFF00) mecparerror(); + case MEC_UART_CTRL: + if (data & 0xFF00FF00) mecparerror(); + write_uart(addr, data); + break; + + case MEC_GPT_RELOAD: + gpt_reload_set(data); + break; + + case MEC_GPT_SCALER: + if (data & 0xFFFF0000) mecparerror(); + gpt_scaler_set(data); + break; + + case MEC_TIMER_CTRL: + if (data & 0xFFFFF0F0) mecparerror(); + timer_ctrl(data); + break; + + case MEC_RTC_RELOAD: + rtc_reload_set(data); + break; + + case MEC_RTC_SCALER: + if (data & 0xFFFFFF00) mecparerror(); + rtc_scaler_set(data); + break; + + case MEC_SFSR: /* 0xA0 */ + if (data & 0xFFFF0880) mecparerror(); + mec_sfsr = 0x78; + break; + + case MEC_ISR: + if (data & 0xFFFFE000) mecparerror(); + mec_isr = data; + break; + + case MEC_IMR: /* 0x4c */ + + if (data & 0xFFFF8001) mecparerror(); + mec_imr = data & 0x7ffe; + chk_irq(); + break; + + case MEC_ICR: /* 0x50 */ + + if (data & 0xFFFF0001) mecparerror(); + mec_ipr &= ~data & 0x0fffe; + chk_irq(); + break; + + case MEC_IFR: /* 0x54 */ + + if (mec_tcr & 0x080000) { + if (data & 0xFFFF0001) mecparerror(); + mec_ifr = data & 0xfffe; + chk_irq(); + } + break; + case SIM_LOAD: + fname[find++] = (char) data; + break; + + + case MEC_MEMCFG: /* 0x10 */ + if (data & 0xC0E08000) mecparerror(); + mec_memcfg = data; + decode_memcfg(); + if (mec_memcfg & 0xc0e08000) + mecparerror(); + break; + + case MEC_WCR: /* 0x18 */ + mec_wcr = data; + decode_wcr(); + break; + + case MEC_ERSR: /* 0xB0 */ + if (mec_tcr & 0x100000) + if (data & 0xFFFFEFC0) mecparerror(); + mec_ersr = data & 0x103f; + break; + + case MEC_TCR: /* 0xD0 */ + if (data & 0xFFE1FFC0) mecparerror(); + mec_tcr = data & 0x1e003f; + break; + + case MEC_WDOG: /* 0x60 */ + wdog_scaler = (data >> 16) & 0x0ff; + wdog_counter = data & 0x0ffff; + wdog_rst_delay = data >> 24; + wdog_rston = 0; + if (wdog_status == stopped) + wdog_start(); + wdog_status = enabled; + break; + + case MEC_TRAPD: /* 0x64 */ + if (wdog_status == init) { + wdog_status = disabled; + if (sis_verbose) + printf("Watchdog disabled\n"); + } + break; + + case MEC_PWDR: + if (mec_mcr & 1) + wait_for_irq(); + break; + + default: + set_sfsr(MEC_ACC, addr, 0xb, 0); + return (1); + break; + } + return (MOK); +} + + +/* MEC UARTS */ + +static int ifd1 = -1, ifd2 = -1, ofd1 = -1, ofd2 = -1; + +void +init_stdio() +{ + if (dumbio) + return; /* do nothing */ + if (!ifd1) + tcsetattr(0, TCSANOW, &ioc1); + if (!ifd2) + tcsetattr(0, TCSANOW, &ioc2); +} + +void +restore_stdio() +{ + if (dumbio) + return; /* do nothing */ + if (!ifd1) + tcsetattr(0, TCSANOW, &iocold1); + if (!ifd2) + tcsetattr(0, TCSANOW, &iocold2); +} + +#define DO_STDIO_READ( _fd_, _buf_, _len_ ) \ + ( dumbio \ + ? (0) /* no bytes read, no delay */ \ + : read( _fd_, _buf_, _len_ ) ) + + +static void +port_init() +{ + + if (uben) { + f2in = stdin; + f1in = NULL; + f2out = stdout; + f1out = NULL; + } else { + f1in = stdin; + f2in = NULL; + f1out = stdout; + f2out = NULL; + } + if (uart_dev1[0] != 0) + if ((fd1 = open(uart_dev1, O_RDWR | O_NONBLOCK)) < 0) { + printf("Warning, couldn't open output device %s\n", uart_dev1); + } else { + if (sis_verbose) + printf("serial port A on %s\n", uart_dev1); + f1in = f1out = fdopen(fd1, "r+"); + setbuf(f1out, NULL); + f1open = 1; + } + if (f1in) ifd1 = fileno(f1in); + if (ifd1 == 0) { + if (sis_verbose) + printf("serial port A on stdin/stdout\n"); + if (!dumbio) { + tcgetattr(ifd1, &ioc1); + iocold1 = ioc1; + ioc1.c_lflag &= ~(ICANON | ECHO); + ioc1.c_cc[VMIN] = 0; + ioc1.c_cc[VTIME] = 0; + } + f1open = 1; + } + + if (f1out) { + ofd1 = fileno(f1out); + if (!dumbio && ofd1 == 1) setbuf(f1out, NULL); + } + + if (uart_dev2[0] != 0) + if ((fd2 = open(uart_dev2, O_RDWR | O_NONBLOCK)) < 0) { + printf("Warning, couldn't open output device %s\n", uart_dev2); + } else { + if (sis_verbose) + printf("serial port B on %s\n", uart_dev2); + f2in = f2out = fdopen(fd2, "r+"); + setbuf(f2out, NULL); + f2open = 1; + } + if (f2in) ifd2 = fileno(f2in); + if (ifd2 == 0) { + if (sis_verbose) + printf("serial port B on stdin/stdout\n"); + if (!dumbio) { + tcgetattr(ifd2, &ioc2); + iocold2 = ioc2; + ioc2.c_lflag &= ~(ICANON | ECHO); + ioc2.c_cc[VMIN] = 0; + ioc2.c_cc[VTIME] = 0; + } + f2open = 1; + } + + if (f2out) { + ofd2 = fileno(f2out); + if (!dumbio && ofd2 == 1) setbuf(f2out, NULL); + } + + wnuma = wnumb = 0; + +} + +static uint32 +read_uart(addr) + uint32 addr; +{ + + unsigned tmp; + + tmp = 0; + switch (addr & 0xff) { + + case 0xE0: /* UART 1 */ +#ifndef _WIN32 +#ifdef FAST_UART + + if (aind < anum) { + if ((aind + 1) < anum) + mec_irq(4); + return (0x700 | (uint32) aq[aind++]); + } else { + if (f1open) { + anum = DO_STDIO_READ(ifd1, aq, UARTBUF); + } + if (anum > 0) { + aind = 0; + if ((aind + 1) < anum) + mec_irq(4); + return (0x700 | (uint32) aq[aind++]); + } else { + return (0x600 | (uint32) aq[aind]); + } + + } +#else + tmp = uarta_data; + uarta_data &= ~UART_DR; + uart_stat_reg &= ~UARTA_DR; + return tmp; +#endif +#else + return(0); +#endif + break; + + case 0xE4: /* UART 2 */ +#ifndef _WIN32 +#ifdef FAST_UART + if (bind < bnum) { + if ((bind + 1) < bnum) + mec_irq(5); + return (0x700 | (uint32) bq[bind++]); + } else { + if (f2open) { + bnum = DO_STDIO_READ(ifd2, bq, UARTBUF); + } + if (bnum > 0) { + bind = 0; + if ((bind + 1) < bnum) + mec_irq(5); + return (0x700 | (uint32) bq[bind++]); + } else { + return (0x600 | (uint32) bq[bind]); + } + + } +#else + tmp = uartb_data; + uartb_data &= ~UART_DR; + uart_stat_reg &= ~UARTB_DR; + return tmp; +#endif +#else + return(0); +#endif + break; + + case 0xE8: /* UART status register */ +#ifndef _WIN32 +#ifdef FAST_UART + + Ucontrol = 0; + if (aind < anum) { + Ucontrol |= 0x00000001; + } else { + if (f1open) { + anum = DO_STDIO_READ(ifd1, aq, UARTBUF); + } + if (anum > 0) { + Ucontrol |= 0x00000001; + aind = 0; + mec_irq(4); + } + } + if (bind < bnum) { + Ucontrol |= 0x00010000; + } else { + if (f2open) { + bnum = DO_STDIO_READ(ifd2, bq, UARTBUF); + } + if (bnum > 0) { + Ucontrol |= 0x00010000; + bind = 0; + mec_irq(5); + } + } + + Ucontrol |= 0x00060006; + return (Ucontrol); +#else + return (uart_stat_reg); +#endif +#else + return(0x00060006); +#endif + break; + default: + if (sis_verbose) + printf("Read from unimplemented MEC register (%x)\n", addr); + + } + return (0); +} + +static void +write_uart(addr, data) + uint32 addr; + uint32 data; +{ + unsigned char c; + + c = (unsigned char) data; + switch (addr & 0xff) { + + case 0xE0: /* UART A */ +#ifdef FAST_UART + if (f1open) { + if (wnuma < UARTBUF) + wbufa[wnuma++] = c; + else { + while (wnuma) + wnuma -= fwrite(wbufa, 1, wnuma, f1out); + wbufa[wnuma++] = c; + } + } + mec_irq(4); +#else + if (uart_stat_reg & UARTA_SRE) { + uarta_sreg = c; + uart_stat_reg &= ~UARTA_SRE; + event(uarta_tx, 0, UART_TX_TIME); + } else { + uarta_hreg = c; + uart_stat_reg &= ~UARTA_HRE; + } +#endif + break; + + case 0xE4: /* UART B */ +#ifdef FAST_UART + if (f2open) { + if (wnumb < UARTBUF) + wbufb[wnumb++] = c; + else { + while (wnumb) + wnumb -= fwrite(wbufb, 1, wnumb, f2out); + wbufb[wnumb++] = c; + } + } + mec_irq(5); +#else + if (uart_stat_reg & UARTB_SRE) { + uartb_sreg = c; + uart_stat_reg &= ~UARTB_SRE; + event(uartb_tx, 0, UART_TX_TIME); + } else { + uartb_hreg = c; + uart_stat_reg &= ~UARTB_HRE; + } +#endif + break; + case 0xE8: /* UART status register */ +#ifndef FAST_UART + if (data & UARTA_CLR) { + uart_stat_reg &= 0xFFFF0000; + uart_stat_reg |= UARTA_SRE | UARTA_HRE; + } + if (data & UARTB_CLR) { + uart_stat_reg &= 0x0000FFFF; + uart_stat_reg |= UARTB_SRE | UARTB_HRE; + } +#endif + break; + default: + if (sis_verbose) + printf("Write to unimplemented MEC register (%x)\n", addr); + + } +} + +static void +flush_uart() +{ + while (wnuma && f1open) + wnuma -= fwrite(wbufa, 1, wnuma, f1out); + while (wnumb && f2open) + wnumb -= fwrite(wbufb, 1, wnumb, f2out); +} + + + +static void +uarta_tx() +{ + + while (f1open && fwrite(&uarta_sreg, 1, 1, f1out) != 1); + if (uart_stat_reg & UARTA_HRE) { + uart_stat_reg |= UARTA_SRE; + } else { + uarta_sreg = uarta_hreg; + uart_stat_reg |= UARTA_HRE; + event(uarta_tx, 0, UART_TX_TIME); + } + mec_irq(4); +} + +static void +uartb_tx() +{ + while (f2open && fwrite(&uartb_sreg, 1, 1, f2out) != 1); + if (uart_stat_reg & UARTB_HRE) { + uart_stat_reg |= UARTB_SRE; + } else { + uartb_sreg = uartb_hreg; + uart_stat_reg |= UARTB_HRE; + event(uartb_tx, 0, UART_TX_TIME); + } + mec_irq(5); +} + +static void +uart_rx(arg) + caddr_t arg; +{ + int32 rsize; + char rxd; + + + rsize = 0; + if (f1open) + rsize = DO_STDIO_READ(ifd1, &rxd, 1); + if (rsize > 0) { + uarta_data = UART_DR | rxd; + if (uart_stat_reg & UARTA_HRE) + uarta_data |= UART_THE; + if (uart_stat_reg & UARTA_SRE) + uarta_data |= UART_TSE; + if (uart_stat_reg & UARTA_DR) { + uart_stat_reg |= UARTA_OR; + mec_irq(7); /* UART error interrupt */ + } + uart_stat_reg |= UARTA_DR; + mec_irq(4); + } + rsize = 0; + if (f2open) + rsize = DO_STDIO_READ(ifd2, &rxd, 1); + if (rsize) { + uartb_data = UART_DR | rxd; + if (uart_stat_reg & UARTB_HRE) + uartb_data |= UART_THE; + if (uart_stat_reg & UARTB_SRE) + uartb_data |= UART_TSE; + if (uart_stat_reg & UARTB_DR) { + uart_stat_reg |= UARTB_OR; + mec_irq(7); /* UART error interrupt */ + } + uart_stat_reg |= UARTB_DR; + mec_irq(5); + } + event(uart_rx, 0, UART_RX_TIME); +} + +static void +uart_intr(arg) + caddr_t arg; +{ + read_uart(0xE8); /* Check for UART interrupts every 1000 clk */ + flush_uart(); /* Flush UART ports */ + event(uart_intr, 0, UART_FLUSH_TIME); +} + + +static void +uart_irq_start() +{ +#ifdef FAST_UART + event(uart_intr, 0, UART_FLUSH_TIME); +#else +#ifndef _WIN32 + event(uart_rx, 0, UART_RX_TIME); +#endif +#endif +} + +/* Watch-dog */ + +static void +wdog_intr(arg) + caddr_t arg; +{ + if (wdog_status == disabled) { + wdog_status = stopped; + } else { + + if (wdog_counter) { + wdog_counter--; + event(wdog_intr, 0, wdog_scaler + 1); + } else { + if (wdog_rston) { + printf("Watchdog reset!\n"); + sys_reset(); + mec_ersr = 0xC000; + } else { + mec_irq(15); + wdog_rston = 1; + wdog_counter = wdog_rst_delay; + event(wdog_intr, 0, wdog_scaler + 1); + } + } + } +} + +static void +wdog_start() +{ + event(wdog_intr, 0, wdog_scaler + 1); + if (sis_verbose) + printf("Watchdog started, scaler = %d, counter = %d\n", + wdog_scaler, wdog_counter); +} + + +/* MEC timers */ + + +static void +rtc_intr(arg) + caddr_t arg; +{ + if (rtc_counter == 0) { + + mec_irq(13); + if (rtc_cr) + rtc_counter = rtc_reload; + else + rtc_se = 0; + } else + rtc_counter -= 1; + if (rtc_se) { + event(rtc_intr, 0, rtc_scaler + 1); + rtc_scaler_start = now(); + rtc_enabled = 1; + } else { + if (sis_verbose) + printf("RTC stopped\n\r"); + rtc_enabled = 0; + } +} + +static void +rtc_start() +{ + if (sis_verbose) + printf("RTC started (period %d)\n\r", rtc_scaler + 1); + event(rtc_intr, 0, rtc_scaler + 1); + rtc_scaler_start = now(); + rtc_enabled = 1; +} + +static uint32 +rtc_counter_read() +{ + return (rtc_counter); +} + +static void +rtc_scaler_set(val) + uint32 val; +{ + rtc_scaler = val & 0x0ff; /* eight-bit scaler only */ +} + +static void +rtc_reload_set(val) + uint32 val; +{ + rtc_reload = val; +} + +static void +gpt_intr(arg) + caddr_t arg; +{ + if (gpt_counter == 0) { + mec_irq(12); + if (gpt_cr) + gpt_counter = gpt_reload; + else + gpt_se = 0; + } else + gpt_counter -= 1; + if (gpt_se) { + event(gpt_intr, 0, gpt_scaler + 1); + gpt_scaler_start = now(); + gpt_enabled = 1; + } else { + if (sis_verbose) + printf("GPT stopped\n\r"); + gpt_enabled = 0; + } +} + +static void +gpt_start() +{ + if (sis_verbose) + printf("GPT started (period %d)\n\r", gpt_scaler + 1); + event(gpt_intr, 0, gpt_scaler + 1); + gpt_scaler_start = now(); + gpt_enabled = 1; +} + +static uint32 +gpt_counter_read() +{ + return (gpt_counter); +} + +static void +gpt_scaler_set(val) + uint32 val; +{ + gpt_scaler = val & 0x0ffff; /* 16-bit scaler */ +} + +static void +gpt_reload_set(val) + uint32 val; +{ + gpt_reload = val; +} + +static void +timer_ctrl(val) + uint32 val; +{ + + rtc_cr = ((val & TCR_TCRCR) != 0); + if (val & TCR_TCRCL) { + rtc_counter = rtc_reload; + } + if (val & TCR_TCRSL) { + } + rtc_se = ((val & TCR_TCRSE) != 0); + if (rtc_se && (rtc_enabled == 0)) + rtc_start(); + + gpt_cr = (val & TCR_GACR); + if (val & TCR_GACL) { + gpt_counter = gpt_reload; + } + if (val & TCR_GACL) { + } + gpt_se = (val & TCR_GASE) >> 2; + if (gpt_se && (gpt_enabled == 0)) + gpt_start(); +} + + +/* Retrieve data from target memory. MEM points to location from which + to read the data; DATA points to words where retrieved data will be + stored in host byte order. SZ contains log(2) of the number of bytes + to retrieve, and can be 0 (1 byte), 1 (one half-word), 2 (one word), + or 3 (two words). */ + +static void +fetch_bytes (asi, mem, data, sz) + int asi; + unsigned char *mem; + uint32 *data; + int sz; +{ + if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN + || asi == 8 || asi == 9) { + switch (sz) { + case 3: + data[1] = (((uint32) mem[7]) & 0xff) | + ((((uint32) mem[6]) & 0xff) << 8) | + ((((uint32) mem[5]) & 0xff) << 16) | + ((((uint32) mem[4]) & 0xff) << 24); + /* Fall through to 2 */ + case 2: + data[0] = (((uint32) mem[3]) & 0xff) | + ((((uint32) mem[2]) & 0xff) << 8) | + ((((uint32) mem[1]) & 0xff) << 16) | + ((((uint32) mem[0]) & 0xff) << 24); + break; + case 1: + data[0] = (((uint32) mem[1]) & 0xff) | + ((((uint32) mem[0]) & 0xff) << 8); + break; + case 0: + data[0] = mem[0] & 0xff; + break; + + } + } else { + switch (sz) { + case 3: + data[1] = ((((uint32) mem[7]) & 0xff) << 24) | + ((((uint32) mem[6]) & 0xff) << 16) | + ((((uint32) mem[5]) & 0xff) << 8) | + (((uint32) mem[4]) & 0xff); + /* Fall through to 4 */ + case 2: + data[0] = ((((uint32) mem[3]) & 0xff) << 24) | + ((((uint32) mem[2]) & 0xff) << 16) | + ((((uint32) mem[1]) & 0xff) << 8) | + (((uint32) mem[0]) & 0xff); + break; + case 1: + data[0] = ((((uint32) mem[1]) & 0xff) << 8) | + (((uint32) mem[0]) & 0xff); + break; + case 0: + data[0] = mem[0] & 0xff; + break; + } + } +} + + +/* Store data in target byte order. MEM points to location to store data; + DATA points to words in host byte order to be stored. SZ contains log(2) + of the number of bytes to retrieve, and can be 0 (1 byte), 1 (one half-word), + 2 (one word), or 3 (two words). */ + +static void +store_bytes (mem, data, sz) + unsigned char *mem; + uint32 *data; + int sz; +{ + if (CURRENT_TARGET_BYTE_ORDER == LITTLE_ENDIAN) { + switch (sz) { + case 3: + mem[7] = (data[1] >> 24) & 0xff; + mem[6] = (data[1] >> 16) & 0xff; + mem[5] = (data[1] >> 8) & 0xff; + mem[4] = data[1] & 0xff; + /* Fall through to 2 */ + case 2: + mem[3] = (data[0] >> 24) & 0xff; + mem[2] = (data[0] >> 16) & 0xff; + /* Fall through to 1 */ + case 1: + mem[1] = (data[0] >> 8) & 0xff; + /* Fall through to 0 */ + case 0: + mem[0] = data[0] & 0xff; + break; + } + } else { + switch (sz) { + case 3: + mem[7] = data[1] & 0xff; + mem[6] = (data[1] >> 8) & 0xff; + mem[5] = (data[1] >> 16) & 0xff; + mem[4] = (data[1] >> 24) & 0xff; + /* Fall through to 2 */ + case 2: + mem[3] = data[0] & 0xff; + mem[2] = (data[0] >> 8) & 0xff; + mem[1] = (data[0] >> 16) & 0xff; + mem[0] = (data[0] >> 24) & 0xff; + break; + case 1: + mem[1] = data[0] & 0xff; + mem[0] = (data[0] >> 8) & 0xff; + break; + case 0: + mem[0] = data[0] & 0xff; + break; + + } + } +} + + +/* Memory emulation */ + +int +memory_read(asi, addr, data, sz, ws) + int32 asi; + uint32 addr; + uint32 *data; + int32 sz; + int32 *ws; +{ + int32 mexc; + +#ifdef ERRINJ + if (errmec) { + if (sis_verbose) + printf("Inserted MEC error %d\n",errmec); + set_sfsr(errmec, addr, asi, 1); + if (errmec == 5) mecparerror(); + if (errmec == 6) iucomperr(); + errmec = 0; + return(1); + } +#endif; + + if ((addr >= mem_ramstart) && (addr < (mem_ramstart + mem_ramsz))) { + fetch_bytes (asi, &ramb[addr & mem_rammask], data, sz); + *ws = mem_ramr_ws; + return (0); + } else if ((addr >= MEC_START) && (addr < MEC_END)) { + mexc = mec_read(addr, asi, data); + if (mexc) { + set_sfsr(MEC_ACC, addr, asi, 1); + *ws = MEM_EX_WS; + } else { + *ws = 0; + } + return (mexc); + +#ifdef ERA + + } else if (era) { + if ((addr < 0x100000) || + ((addr>= 0x80000000) && (addr < 0x80100000))) { + fetch_bytes (asi, &romb[addr & ROM_MASK], data, sz); + *ws = 4; + return (0); + } else if ((addr >= 0x10000000) && + (addr < (0x10000000 + (512 << (mec_iocr & 0x0f)))) && + (mec_iocr & 0x10)) { + *data = erareg; + return (0); + } + + } else if (addr < mem_romsz) { + fetch_bytes (asi, &romb[addr], data, sz); + *ws = mem_romr_ws; + return (0); + +#else + } else if (addr < mem_romsz) { + fetch_bytes (asi, &romb[addr], data, sz); + *ws = mem_romr_ws; + return (0); +#endif + + } + + printf("Memory exception at %x (illegal address)\n", addr); + set_sfsr(UIMP_ACC, addr, asi, 1); + *ws = MEM_EX_WS; + return (1); +} + +int +memory_write(asi, addr, data, sz, ws) + int32 asi; + uint32 addr; + uint32 *data; + int32 sz; + int32 *ws; +{ + uint32 byte_addr; + uint32 byte_mask; + uint32 waddr; + uint32 *ram; + int32 mexc; + int i; + int wphit[2]; + +#ifdef ERRINJ + if (errmec) { + if (sis_verbose) + printf("Inserted MEC error %d\n",errmec); + set_sfsr(errmec, addr, asi, 0); + if (errmec == 5) mecparerror(); + if (errmec == 6) iucomperr(); + errmec = 0; + return(1); + } +#endif; + + if ((addr >= mem_ramstart) && (addr < (mem_ramstart + mem_ramsz))) { + if (mem_accprot) { + + waddr = (addr & 0x7fffff) >> 2; + for (i = 0; i < 2; i++) + wphit[i] = + (((asi == 0xa) && (mec_wpr[i] & 1)) || + ((asi == 0xb) && (mec_wpr[i] & 2))) && + ((waddr >= mec_ssa[i]) && ((waddr | (sz == 3)) < mec_sea[i])); + + if (((mem_blockprot) && (wphit[0] || wphit[1])) || + ((!mem_blockprot) && + !((mec_wpr[0] && wphit[0]) || (mec_wpr[1] && wphit[1])) + )) { + if (sis_verbose) + printf("Memory access protection error at 0x%08x\n", addr); + set_sfsr(PROT_EXC, addr, asi, 0); + *ws = MEM_EX_WS; + return (1); + } + } + + store_bytes (&ramb[addr & mem_rammask], data, sz); + + switch (sz) { + case 0: + case 1: + *ws = mem_ramw_ws + 3; + break; + case 2: + *ws = mem_ramw_ws; + break; + case 3: + *ws = 2 * mem_ramw_ws + STD_WS; + break; + } + return (0); + } else if ((addr >= MEC_START) && (addr < MEC_END)) { + if ((sz != 2) || (asi != 0xb)) { + set_sfsr(MEC_ACC, addr, asi, 0); + *ws = MEM_EX_WS; + return (1); + } + mexc = mec_write(addr, *data); + if (mexc) { + set_sfsr(MEC_ACC, addr, asi, 0); + *ws = MEM_EX_WS; + } else { + *ws = 0; + } + return (mexc); + +#ifdef ERA + + } else if (era) { + if ((erareg & 2) && + ((addr < 0x100000) || ((addr >= 0x80000000) && (addr < 0x80100000)))) { + addr &= ROM_MASK; + *ws = sz == 3 ? 8 : 4; + store_bytes (&romb[addr], data, sz); + return (0); + } else if ((addr >= 0x10000000) && + (addr < (0x10000000 + (512 << (mec_iocr & 0x0f)))) && + (mec_iocr & 0x10)) { + erareg = *data & 0x0e; + return (0); + } + + } else if ((addr < mem_romsz) && (mec_memcfg & 0x10000) && (wrp) && + (((mec_memcfg & 0x20000) && (sz > 1)) || + (!(mec_memcfg & 0x20000) && (sz == 0)))) { + + *ws = mem_romw_ws + 1; + if (sz == 3) + *ws += mem_romw_ws + STD_WS; + store_bytes (&romb[addr], data, sz); + return (0); + +#else + } else if ((addr < mem_romsz) && (mec_memcfg & 0x10000) && (wrp) && + (((mec_memcfg & 0x20000) && (sz > 1)) || + (!(mec_memcfg & 0x20000) && (sz == 0)))) { + + *ws = mem_romw_ws + 1; + if (sz == 3) + *ws += mem_romw_ws + STD_WS; + store_bytes (&romb[addr], data, sz); + return (0); + +#endif + + } + + *ws = MEM_EX_WS; + set_sfsr(UIMP_ACC, addr, asi, 0); + return (1); +} + +static unsigned char * +get_mem_ptr(addr, size) + uint32 addr; + uint32 size; +{ + if ((addr + size) < ROM_SZ) { + return (&romb[addr]); + } else if ((addr >= mem_ramstart) && ((addr + size) < mem_ramend)) { + return (&ramb[addr & mem_rammask]); + } + +#ifdef ERA + else if ((era) && ((addr <0x100000) || + ((addr >= (unsigned) 0x80000000) && ((addr + size) < (unsigned) 0x80100000)))) { + return (&romb[addr & ROM_MASK]); + } +#endif + + return ((char *) -1); +} + +int +sis_memory_write(addr, data, length) + uint32 addr; + char *data; + uint32 length; +{ + char *mem; + + if ((mem = get_mem_ptr(addr, length)) == ((char *) -1)) + return (0); + + memcpy(mem, data, length); + return (length); +} + +int +sis_memory_read(addr, data, length) + uint32 addr; + char *data; + uint32 length; +{ + char *mem; + + if ((mem = get_mem_ptr(addr, length)) == ((char *) -1)) + return (0); + + memcpy(data, mem, length); + return (length); +} diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c new file mode 100644 index 0000000..5f1fc0c --- /dev/null +++ b/sim/erc32/exec.c @@ -0,0 +1,2041 @@ +/* + * This file is part of SIS. + * + * SIS, SPARC instruction simulator V1.8 Copyright (C) 1995 Jiri Gaisler, + * European Space Agency + * + * 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., 675 + * Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include "sis.h" +#include "end.h" +#include <math.h> +#include <stdio.h> + +extern int32 sis_verbose, sparclite; +int ext_irl = 0; + +/* Load/store interlock delay */ +#define FLSTHOLD 1 + +/* Load delay (delete if unwanted - speeds up simulation) */ +#define LOAD_DEL 1 + +#define T_LD 2 +#define T_LDD 3 +#define T_ST 3 +#define T_STD 4 +#define T_LDST 4 +#define T_JMPL 2 +#define T_RETT 2 + +#define FSR_QNE 0x2000 +#define FP_EXE_MODE 0 +#define FP_EXC_PE 1 +#define FP_EXC_MODE 2 + +#define FBA 8 +#define FBN 0 +#define FBNE 1 +#define FBLG 2 +#define FBUL 3 +#define FBL 4 +#define FBUG 5 +#define FBG 6 +#define FBU 7 +#define FBA 8 +#define FBE 9 +#define FBUE 10 +#define FBGE 11 +#define FBUGE 12 +#define FBLE 13 +#define FBULE 14 +#define FBO 15 + +#define FCC_E 0 +#define FCC_L 1 +#define FCC_G 2 +#define FCC_U 3 + +#define PSR_ET 0x20 +#define PSR_EF 0x1000 +#define PSR_PS 0x40 +#define PSR_S 0x80 +#define PSR_N 0x0800000 +#define PSR_Z 0x0400000 +#define PSR_V 0x0200000 +#define PSR_C 0x0100000 +#define PSR_CC 0x0F00000 +#define PSR_CWP 0x7 +#define PSR_PIL 0x0f00 + +#define ICC_N (icc >> 3) +#define ICC_Z (icc >> 2) +#define ICC_V (icc >> 1) +#define ICC_C (icc) + +#define FP_PRES (sregs->fpu_pres) + +#define TRAP_IEXC 1 +#define TRAP_UNIMP 2 +#define TRAP_PRIVI 3 +#define TRAP_FPDIS 4 +#define TRAP_WOFL 5 +#define TRAP_WUFL 6 +#define TRAP_UNALI 7 +#define TRAP_FPEXC 8 +#define TRAP_DEXC 9 +#define TRAP_TAG 10 +#define TRAP_DIV0 0x2a + +#define FSR_TT 0x1C000 +#define FP_IEEE 0x04000 +#define FP_UNIMP 0x0C000 +#define FP_SEQ_ERR 0x10000 + +#define BICC_BN 0 +#define BICC_BE 1 +#define BICC_BLE 2 +#define BICC_BL 3 +#define BICC_BLEU 4 +#define BICC_BCS 5 +#define BICC_NEG 6 +#define BICC_BVS 7 +#define BICC_BA 8 +#define BICC_BNE 9 +#define BICC_BG 10 +#define BICC_BGE 11 +#define BICC_BGU 12 +#define BICC_BCC 13 +#define BICC_POS 14 +#define BICC_BVC 15 + +#define INST_SIMM13 0x1fff +#define INST_RS2 0x1f +#define INST_I 0x2000 +#define ADD 0x00 +#define ADDCC 0x10 +#define ADDX 0x08 +#define ADDXCC 0x18 +#define TADDCC 0x20 +#define TSUBCC 0x21 +#define TADDCCTV 0x22 +#define TSUBCCTV 0x23 +#define IAND 0x01 +#define IANDCC 0x11 +#define IANDN 0x05 +#define IANDNCC 0x15 +#define MULScc 0x24 +#define DIVScc 0x1D +#define SMUL 0x0B +#define SMULCC 0x1B +#define UMUL 0x0A +#define UMULCC 0x1A +#define SDIV 0x0F +#define SDIVCC 0x1F +#define UDIV 0x0E +#define UDIVCC 0x1E +#define IOR 0x02 +#define IORCC 0x12 +#define IORN 0x06 +#define IORNCC 0x16 +#define SLL 0x25 +#define SRA 0x27 +#define SRL 0x26 +#define SUB 0x04 +#define SUBCC 0x14 +#define SUBX 0x0C +#define SUBXCC 0x1C +#define IXNOR 0x07 +#define IXNORCC 0x17 +#define IXOR 0x03 +#define IXORCC 0x13 +#define SETHI 0x04 +#define BICC 0x02 +#define FPBCC 0x06 +#define RDY 0x28 +#define RDPSR 0x29 +#define RDWIM 0x2A +#define RDTBR 0x2B +#define SCAN 0x2C +#define WRY 0x30 +#define WRPSR 0x31 +#define WRWIM 0x32 +#define WRTBR 0x33 +#define JMPL 0x38 +#define RETT 0x39 +#define TICC 0x3A +#define SAVE 0x3C +#define RESTORE 0x3D +#define LDD 0x03 +#define LDDA 0x13 +#define LD 0x00 +#define LDA 0x10 +#define LDF 0x20 +#define LDDF 0x23 +#define LDSTUB 0x0D +#define LDSTUBA 0x1D +#define LDUB 0x01 +#define LDUBA 0x11 +#define LDSB 0x09 +#define LDSBA 0x19 +#define LDUH 0x02 +#define LDUHA 0x12 +#define LDSH 0x0A +#define LDSHA 0x1A +#define LDFSR 0x21 +#define ST 0x04 +#define STA 0x14 +#define STB 0x05 +#define STBA 0x15 +#define STD 0x07 +#define STDA 0x17 +#define STF 0x24 +#define STDFQ 0x26 +#define STDF 0x27 +#define STFSR 0x25 +#define STH 0x06 +#define STHA 0x16 +#define SWAP 0x0F +#define SWAPA 0x1F +#define FLUSH 0x3B + +#define SIGN_BIT 0x80000000 + +/* # of cycles overhead when a trap is taken */ +#define TRAP_C 3 + +/* Forward declarations */ + +static uint32 sub_cc PARAMS ((uint32 psr, int32 operand1, int32 operand2, + int32 result)); +static uint32 add_cc PARAMS ((uint32 psr, int32 operand1, int32 operand2, + int32 result)); +static void log_cc PARAMS ((int32 result, struct pstate *sregs)); +static int fpexec PARAMS ((uint32 op3, uint32 rd, uint32 rs1, uint32 rs2, + struct pstate *sregs)); +static int chk_asi PARAMS ((struct pstate *sregs, uint32 *asi, uint32 op3)); + + +extern struct estate ebase; +extern int32 nfp,ift; + +#ifdef ERRINJ +extern uint32 errtt, errftt; +#endif + +static uint32 +sub_cc(psr, operand1, operand2, result) + uint32 psr; + int32 operand1; + int32 operand2; + int32 result; +{ + psr = ((psr & ~PSR_N) | ((result >> 8) & PSR_N)); + if (result) + psr &= ~PSR_Z; + else + psr |= PSR_Z; + psr = (psr & ~PSR_V) | ((((operand1 & ~operand2 & ~result) | + (~operand1 & operand2 & result)) >> 10) & PSR_V); + psr = (psr & ~PSR_C) | ((((~operand1 & operand2) | + ((~operand1 | operand2) & result)) >> 11) & PSR_C); + return (psr); +} + +uint32 +add_cc(psr, operand1, operand2, result) + uint32 psr; + int32 operand1; + int32 operand2; + int32 result; +{ + psr = ((psr & ~PSR_N) | ((result >> 8) & PSR_N)); + if (result) + psr &= ~PSR_Z; + else + psr |= PSR_Z; + psr = (psr & ~PSR_V) | ((((operand1 & operand2 & ~result) | + (~operand1 & ~operand2 & result)) >> 10) & PSR_V); + psr = (psr & ~PSR_C) | ((((operand1 & operand2) | + ((operand1 | operand2) & ~result)) >> 11) & PSR_C); + return(psr); +} + +static void +log_cc(result, sregs) + int32 result; + struct pstate *sregs; +{ + sregs->psr &= ~(PSR_CC); /* Zero CC bits */ + sregs->psr = (sregs->psr | ((result >> 8) & PSR_N)); + if (result == 0) + sregs->psr |= PSR_Z; +} + +/* Add two unsigned 32-bit integers, and calculate the carry out. */ + +static uint32 +add32 (uint32 n1, uint32 n2, int *carry) +{ + uint32 result = n1 + n2; + + *carry = result < n1 || result < n1; + return(result); +} + +/* Multiply two 32-bit integers. */ + +static void +mul64 (uint32 n1, uint32 n2, uint32 *result_hi, uint32 *result_lo, int msigned) +{ + uint32 lo, mid1, mid2, hi, reg_lo, reg_hi; + int carry; + int sign = 0; + + /* If this is a signed multiply, calculate the sign of the result + and make the operands positive. */ + if (msigned) + { + sign = (n1 ^ n2) & SIGN_BIT; + if (n1 & SIGN_BIT) + n1 = -n1; + if (n2 & SIGN_BIT) + n2 = -n2; + + } + + /* We can split the 32x32 into four 16x16 operations. This ensures + that we do not lose precision on 32bit only hosts: */ + lo = ((n1 & 0xFFFF) * (n2 & 0xFFFF)); + mid1 = ((n1 & 0xFFFF) * ((n2 >> 16) & 0xFFFF)); + mid2 = (((n1 >> 16) & 0xFFFF) * (n2 & 0xFFFF)); + hi = (((n1 >> 16) & 0xFFFF) * ((n2 >> 16) & 0xFFFF)); + + /* We now need to add all of these results together, taking care + to propogate the carries from the additions: */ + reg_lo = add32 (lo, (mid1 << 16), &carry); + reg_hi = carry; + reg_lo = add32 (reg_lo, (mid2 << 16), &carry); + reg_hi += (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi); + + /* Negate result if necessary. */ + if (sign) + { + reg_hi = ~ reg_hi; + reg_lo = - reg_lo; + if (reg_lo == 0) + reg_hi++; + } + + *result_lo = reg_lo; + *result_hi = reg_hi; +} + + +/* Divide a 64-bit integer by a 32-bit integer. We cheat and assume + that the host compiler supports long long operations. */ + +static void +div64 (uint32 n1_hi, uint32 n1_low, uint32 n2, uint32 *result, int msigned) +{ + uint64 n1; + + n1 = ((uint64) n1_hi) << 32; + n1 |= ((uint64) n1_low) & 0xffffffff; + + if (msigned) + { + int64 n1_s = (int64) n1; + int32 n2_s = (int32) n2; + n1_s = n1_s / n2_s; + n1 = (uint64) n1_s; + } + else + n1 = n1 / n2; + + *result = (uint32) (n1 & 0xffffffff); +} + + +int +dispatch_instruction(sregs) + struct pstate *sregs; +{ + + uint32 cwp, op, op2, op3, asi, rd, cond, rs1, + rs2; + uint32 ldep, icc; + int32 operand1, operand2, *rdd, result, eicc, + new_cwp; + int32 pc, npc, data, address, ws, mexc, fcc; + int32 ddata[2]; + + sregs->ninst++; + cwp = ((sregs->psr & PSR_CWP) << 4); + op = sregs->inst >> 30; + pc = sregs->npc; + npc = sregs->npc + 4; + op3 = rd = rs1 = operand2 = eicc = 0; + rdd = 0; + if (op & 2) { + + op3 = (sregs->inst >> 19) & 0x3f; + rs1 = (sregs->inst >> 14) & 0x1f; + rd = (sregs->inst >> 25) & 0x1f; + +#ifdef LOAD_DEL + + /* Check if load dependecy is possible */ + if (ebase.simtime <= sregs->ildtime) + ldep = (((op3 & 0x38) != 0x28) && ((op3 & 0x3e) != 0x34) && (sregs->ildreg != 0)); + else + ldep = 0; + if (sregs->inst & INST_I) { + if (ldep && (sregs->ildreg == rs1)) + sregs->hold++; + operand2 = sregs->inst; + operand2 = ((operand2 << 19) >> 19); /* sign extend */ + } else { + rs2 = sregs->inst & INST_RS2; + if (rs2 > 7) + operand2 = sregs->r[(cwp + rs2) & 0x7f]; + else + operand2 = sregs->g[rs2]; + if (ldep && ((sregs->ildreg == rs1) || (sregs->ildreg == rs2))) + sregs->hold++; + } +#else + if (sregs->inst & INST_I) { + operand2 = sregs->inst; + operand2 = ((operand2 << 19) >> 19); /* sign extend */ + } else { + rs2 = sregs->inst & INST_RS2; + if (rs2 > 7) + operand2 = sregs->r[(cwp + rs2) & 0x7f]; + else + operand2 = sregs->g[rs2]; + } +#endif + + if (rd > 7) + rdd = &(sregs->r[(cwp + rd) & 0x7f]); + else + rdd = &(sregs->g[rd]); + if (rs1 > 7) + rs1 = sregs->r[(cwp + rs1) & 0x7f]; + else + rs1 = sregs->g[rs1]; + } + switch (op) { + case 0: + op2 = (sregs->inst >> 22) & 0x7; + switch (op2) { + case SETHI: + rd = (sregs->inst >> 25) & 0x1f; + if (rd > 7) + rdd = &(sregs->r[(cwp + rd) & 0x7f]); + else + rdd = &(sregs->g[rd]); + *rdd = sregs->inst << 10; + break; + case BICC: +#ifdef STAT + sregs->nbranch++; +#endif + icc = sregs->psr >> 20; + cond = ((sregs->inst >> 25) & 0x0f); + switch (cond) { + case BICC_BN: + eicc = 0; + break; + case BICC_BE: + eicc = ICC_Z; + break; + case BICC_BLE: + eicc = ICC_Z | (ICC_N ^ ICC_V); + break; + case BICC_BL: + eicc = (ICC_N ^ ICC_V); + break; + case BICC_BLEU: + eicc = ICC_C | ICC_Z; + break; + case BICC_BCS: + eicc = ICC_C; + break; + case BICC_NEG: + eicc = ICC_N; + break; + case BICC_BVS: + eicc = ICC_V; + break; + case BICC_BA: + eicc = 1; + if (sregs->inst & 0x20000000) + sregs->annul = 1; + break; + case BICC_BNE: + eicc = ~(ICC_Z); + break; + case BICC_BG: + eicc = ~(ICC_Z | (ICC_N ^ ICC_V)); + break; + case BICC_BGE: + eicc = ~(ICC_N ^ ICC_V); + break; + case BICC_BGU: + eicc = ~(ICC_C | ICC_Z); + break; + case BICC_BCC: + eicc = ~(ICC_C); + break; + case BICC_POS: + eicc = ~(ICC_N); + break; + case BICC_BVC: + eicc = ~(ICC_V); + break; + } + if (eicc & 1) { + operand1 = sregs->inst; + operand1 = ((operand1 << 10) >> 8); /* sign extend */ + npc = sregs->pc + operand1; + } else { + if (sregs->inst & 0x20000000) + sregs->annul = 1; + } + break; + case FPBCC: +#ifdef STAT + sregs->nbranch++; +#endif + if (!((sregs->psr & PSR_EF) && FP_PRES)) { + sregs->trap = TRAP_FPDIS; + break; + } + if (ebase.simtime < sregs->ftime) { + sregs->ftime = ebase.simtime + sregs->hold; + } + cond = ((sregs->inst >> 25) & 0x0f); + fcc = (sregs->fsr >> 10) & 0x3; + switch (cond) { + case FBN: + eicc = 0; + break; + case FBNE: + eicc = (fcc != FCC_E); + break; + case FBLG: + eicc = (fcc == FCC_L) || (fcc == FCC_G); + break; + case FBUL: + eicc = (fcc == FCC_L) || (fcc == FCC_U); + break; + case FBL: + eicc = (fcc == FCC_L); + break; + case FBUG: + eicc = (fcc == FCC_G) || (fcc == FCC_U); + break; + case FBG: + eicc = (fcc == FCC_G); + break; + case FBU: + eicc = (fcc == FCC_U); + break; + case FBA: + eicc = 1; + if (sregs->inst & 0x20000000) + sregs->annul = 1; + break; + case FBE: + eicc = !(fcc != FCC_E); + break; + case FBUE: + eicc = !((fcc == FCC_L) || (fcc == FCC_G)); + break; + case FBGE: + eicc = !((fcc == FCC_L) || (fcc == FCC_U)); + break; + case FBUGE: + eicc = !(fcc == FCC_L); + break; + case FBLE: + eicc = !((fcc == FCC_G) || (fcc == FCC_U)); + break; + case FBULE: + eicc = !(fcc == FCC_G); + break; + case FBO: + eicc = !(fcc == FCC_U); + break; + } + if (eicc) { + operand1 = sregs->inst; + operand1 = ((operand1 << 10) >> 8); /* sign extend */ + npc = sregs->pc + operand1; + } else { + if (sregs->inst & 0x20000000) + sregs->annul = 1; + } + break; + + default: + sregs->trap = TRAP_UNIMP; + break; + } + break; + case 1: /* CALL */ +#ifdef STAT + sregs->nbranch++; +#endif + sregs->r[(cwp + 15) & 0x7f] = sregs->pc; + npc = sregs->pc + (sregs->inst << 2); + break; + + case 2: + if ((op3 >> 1) == 0x1a) { + if (!((sregs->psr & PSR_EF) && FP_PRES)) { + sregs->trap = TRAP_FPDIS; + } else { + rs1 = (sregs->inst >> 14) & 0x1f; + rs2 = sregs->inst & 0x1f; + sregs->trap = fpexec(op3, rd, rs1, rs2, sregs); + } + } else { + + switch (op3) { + case TICC: + icc = sregs->psr >> 20; + cond = ((sregs->inst >> 25) & 0x0f); + switch (cond) { + case BICC_BN: + eicc = 0; + break; + case BICC_BE: + eicc = ICC_Z; + break; + case BICC_BLE: + eicc = ICC_Z | (ICC_N ^ ICC_V); + break; + case BICC_BL: + eicc = (ICC_N ^ ICC_V); + break; + case BICC_BLEU: + eicc = ICC_C | ICC_Z; + break; + case BICC_BCS: + eicc = ICC_C; + break; + case BICC_NEG: + eicc = ICC_N; + break; + case BICC_BVS: + eicc = ICC_V; + break; + case BICC_BA: + eicc = 1; + break; + case BICC_BNE: + eicc = ~(ICC_Z); + break; + case BICC_BG: + eicc = ~(ICC_Z | (ICC_N ^ ICC_V)); + break; + case BICC_BGE: + eicc = ~(ICC_N ^ ICC_V); + break; + case BICC_BGU: + eicc = ~(ICC_C | ICC_Z); + break; + case BICC_BCC: + eicc = ~(ICC_C); + break; + case BICC_POS: + eicc = ~(ICC_N); + break; + case BICC_BVC: + eicc = ~(ICC_V); + break; + } + if (eicc & 1) { + sregs->trap = (0x80 | ((rs1 + operand2) & 0x7f)); + } + break; + + case MULScc: + operand1 = + (((sregs->psr & PSR_V) ^ ((sregs->psr & PSR_N) >> 2)) + << 10) | (rs1 >> 1); + if ((sregs->y & 1) == 0) + operand2 = 0; + *rdd = operand1 + operand2; + sregs->y = (rs1 << 31) | (sregs->y >> 1); + sregs->psr = add_cc(sregs->psr, operand1, operand2, *rdd); + break; + case DIVScc: + { + int sign; + uint32 result, remainder; + int c0, y31; + + if (!sparclite) { + sregs->trap = TRAP_UNIMP; + break; + } + + sign = ((sregs->psr & PSR_V) != 0) ^ ((sregs->psr & PSR_N) != 0); + + remainder = (sregs->y << 1) | (rs1 >> 31); + + /* If true sign is positive, calculate remainder - divisor. + Otherwise, calculate remainder + divisor. */ + if (sign == 0) + operand2 = ~operand2 + 1; + result = remainder + operand2; + + /* The SPARClite User's Manual is not clear on how + the "carry out" of the above ALU operation is to + be calculated. From trial and error tests + on the the chip itself, it appears that it is + a normal addition carry, and not a subtraction borrow, + even in cases where the divisor is subtracted + from the remainder. FIXME: get the true story + from Fujitsu. */ + c0 = result < (uint32) remainder + || result < (uint32) operand2; + + if (result & 0x80000000) + sregs->psr |= PSR_N; + else + sregs->psr &= ~PSR_N; + + y31 = (sregs->y & 0x80000000) == 0x80000000; + + if (result == 0 && sign == y31) + sregs->psr |= PSR_Z; + else + sregs->psr &= ~PSR_Z; + + sign = (sign && !y31) || (!c0 && (sign || !y31)); + + if (sign ^ (result >> 31)) + sregs->psr |= PSR_V; + else + sregs->psr &= ~PSR_V; + + if (!sign) + sregs->psr |= PSR_C; + else + sregs->psr &= ~PSR_C; + + sregs->y = result; + + if (rd != 0) + *rdd = (rs1 << 1) | !sign; + } + break; + case SMUL: + { + mul64 (rs1, operand2, &sregs->y, rdd, 1); + } + break; + case SMULCC: + { + uint32 result; + + mul64 (rs1, operand2, &sregs->y, &result, 1); + + if (result & 0x80000000) + sregs->psr |= PSR_N; + else + sregs->psr &= ~PSR_N; + + if (result == 0) + sregs->psr |= PSR_Z; + else + sregs->psr &= ~PSR_Z; + + *rdd = result; + } + break; + case UMUL: + { + mul64 (rs1, operand2, &sregs->y, rdd, 0); + } + break; + case UMULCC: + { + uint32 result; + + mul64 (rs1, operand2, &sregs->y, &result, 0); + + if (result & 0x80000000) + sregs->psr |= PSR_N; + else + sregs->psr &= ~PSR_N; + + if (result == 0) + sregs->psr |= PSR_Z; + else + sregs->psr &= ~PSR_Z; + + *rdd = result; + } + break; + case SDIV: + { + if (sparclite) { + sregs->trap = TRAP_UNIMP; + break; + } + + if (operand2 == 0) { + sregs->trap = TRAP_DIV0; + break; + } + + div64 (sregs->y, rs1, operand2, rdd, 1); + } + break; + case SDIVCC: + { + uint32 result; + + if (sparclite) { + sregs->trap = TRAP_UNIMP; + break; + } + + if (operand2 == 0) { + sregs->trap = TRAP_DIV0; + break; + } + + div64 (sregs->y, rs1, operand2, &result, 1); + + if (result & 0x80000000) + sregs->psr |= PSR_N; + else + sregs->psr &= ~PSR_N; + + if (result == 0) + sregs->psr |= PSR_Z; + else + sregs->psr &= ~PSR_Z; + + /* FIXME: should set overflow flag correctly. */ + sregs->psr &= ~(PSR_C | PSR_V); + + *rdd = result; + } + break; + case UDIV: + { + if (sparclite) { + sregs->trap = TRAP_UNIMP; + break; + } + + if (operand2 == 0) { + sregs->trap = TRAP_DIV0; + break; + } + + div64 (sregs->y, rs1, operand2, rdd, 0); + } + break; + case UDIVCC: + { + uint32 result; + + if (sparclite) { + sregs->trap = TRAP_UNIMP; + break; + } + + if (operand2 == 0) { + sregs->trap = TRAP_DIV0; + break; + } + + div64 (sregs->y, rs1, operand2, &result, 0); + + if (result & 0x80000000) + sregs->psr |= PSR_N; + else + sregs->psr &= ~PSR_N; + + if (result == 0) + sregs->psr |= PSR_Z; + else + sregs->psr &= ~PSR_Z; + + /* FIXME: should set overflow flag correctly. */ + sregs->psr &= ~(PSR_C | PSR_V); + + *rdd = result; + } + break; + case IXNOR: + *rdd = rs1 ^ ~operand2; + break; + case IXNORCC: + *rdd = rs1 ^ ~operand2; + log_cc(*rdd, sregs); + break; + case IXOR: + *rdd = rs1 ^ operand2; + break; + case IXORCC: + *rdd = rs1 ^ operand2; + log_cc(*rdd, sregs); + break; + case IOR: + *rdd = rs1 | operand2; + break; + case IORCC: + *rdd = rs1 | operand2; + log_cc(*rdd, sregs); + break; + case IORN: + *rdd = rs1 | ~operand2; + break; + case IORNCC: + *rdd = rs1 | ~operand2; + log_cc(*rdd, sregs); + break; + case IANDNCC: + *rdd = rs1 & ~operand2; + log_cc(*rdd, sregs); + break; + case IANDN: + *rdd = rs1 & ~operand2; + break; + case IAND: + *rdd = rs1 & operand2; + break; + case IANDCC: + *rdd = rs1 & operand2; + log_cc(*rdd, sregs); + break; + case SUB: + *rdd = rs1 - operand2; + break; + case SUBCC: + *rdd = rs1 - operand2; + sregs->psr = sub_cc(sregs->psr, rs1, operand2, *rdd); + break; + case SUBX: + *rdd = rs1 - operand2 - ((sregs->psr >> 20) & 1); + break; + case SUBXCC: + *rdd = rs1 - operand2 - ((sregs->psr >> 20) & 1); + sregs->psr = sub_cc(sregs->psr, rs1, operand2, *rdd); + break; + case ADD: + *rdd = rs1 + operand2; + break; + case ADDCC: + *rdd = rs1 + operand2; + sregs->psr = add_cc(sregs->psr, rs1, operand2, *rdd); + break; + case ADDX: + *rdd = rs1 + operand2 + ((sregs->psr >> 20) & 1); + break; + case ADDXCC: + *rdd = rs1 + operand2 + ((sregs->psr >> 20) & 1); + sregs->psr = add_cc(sregs->psr, rs1, operand2, *rdd); + break; + case TADDCC: + *rdd = rs1 + operand2; + sregs->psr = add_cc(sregs->psr, rs1, operand2, *rdd); + if ((rs1 | operand2) & 0x3) + sregs->psr |= PSR_V; + break; + case TSUBCC: + *rdd = rs1 - operand2; + sregs->psr = sub_cc (sregs->psr, rs1, operand2, *rdd); + if ((rs1 | operand2) & 0x3) + sregs->psr |= PSR_V; + break; + case TADDCCTV: + *rdd = rs1 + operand2; + result = add_cc(0, rs1, operand2, *rdd); + if ((rs1 | operand2) & 0x3) + result |= PSR_V; + if (result & PSR_V) { + sregs->trap = TRAP_TAG; + } else { + sregs->psr = (sregs->psr & ~PSR_CC) | result; + } + break; + case TSUBCCTV: + *rdd = rs1 - operand2; + result = add_cc (0, rs1, operand2, *rdd); + if ((rs1 | operand2) & 0x3) + result |= PSR_V; + if (result & PSR_V) + { + sregs->trap = TRAP_TAG; + } + else + { + sregs->psr = (sregs->psr & ~PSR_CC) | result; + } + break; + case SLL: + *rdd = rs1 << (operand2 & 0x1f); + break; + case SRL: + *rdd = rs1 >> (operand2 & 0x1f); + break; + case SRA: + *rdd = ((int) rs1) >> (operand2 & 0x1f); + break; + case FLUSH: + if (ift) sregs->trap = TRAP_UNIMP; + break; + case SAVE: + new_cwp = ((sregs->psr & PSR_CWP) - 1) & PSR_CWP; + if (sregs->wim & (1 << new_cwp)) { + sregs->trap = TRAP_WOFL; + break; + } + if (rd > 7) + rdd = &(sregs->r[((new_cwp << 4) + rd) & 0x7f]); + *rdd = rs1 + operand2; + sregs->psr = (sregs->psr & ~PSR_CWP) | new_cwp; + break; + case RESTORE: + + new_cwp = ((sregs->psr & PSR_CWP) + 1) & PSR_CWP; + if (sregs->wim & (1 << new_cwp)) { + sregs->trap = TRAP_WUFL; + break; + } + if (rd > 7) + rdd = &(sregs->r[((new_cwp << 4) + rd) & 0x7f]); + *rdd = rs1 + operand2; + sregs->psr = (sregs->psr & ~PSR_CWP) | new_cwp; + break; + case RDPSR: + if (!(sregs->psr & PSR_S)) { + sregs->trap = TRAP_PRIVI; + break; + } + *rdd = sregs->psr; + break; + case RDY: + if (!sparclite) + *rdd = sregs->y; + else { + int rs1_is_asr = (sregs->inst >> 14) & 0x1f; + if ( 0 == rs1_is_asr ) + *rdd = sregs->y; + else if ( 17 == rs1_is_asr ) + *rdd = sregs->asr17; + else { + sregs->trap = TRAP_UNIMP; + break; + } + } + break; + case RDWIM: + if (!(sregs->psr & PSR_S)) { + sregs->trap = TRAP_PRIVI; + break; + } + *rdd = sregs->wim; + break; + case RDTBR: + if (!(sregs->psr & PSR_S)) { + sregs->trap = TRAP_PRIVI; + break; + } + *rdd = sregs->tbr; + break; + case WRPSR: + if ((sregs->psr & 0x1f) > 7) { + sregs->trap = TRAP_UNIMP; + break; + } + if (!(sregs->psr & PSR_S)) { + sregs->trap = TRAP_PRIVI; + break; + } + sregs->psr = (rs1 ^ operand2) & 0x00f03fff; + break; + case WRWIM: + if (!(sregs->psr & PSR_S)) { + sregs->trap = TRAP_PRIVI; + break; + } + sregs->wim = (rs1 ^ operand2) & 0x0ff; + break; + case WRTBR: + if (!(sregs->psr & PSR_S)) { + sregs->trap = TRAP_PRIVI; + break; + } + sregs->tbr = (sregs->tbr & 0x00000ff0) | + ((rs1 ^ operand2) & 0xfffff000); + break; + case WRY: + if (!sparclite) + sregs->y = (rs1 ^ operand2); + else { + if ( 0 == rd ) + sregs->y = (rs1 ^ operand2); + else if ( 17 == rd ) + sregs->asr17 = (rs1 ^ operand2); + else { + sregs->trap = TRAP_UNIMP; + break; + } + } + break; + case JMPL: + +#ifdef STAT + sregs->nbranch++; +#endif + sregs->icnt = T_JMPL; /* JMPL takes two cycles */ + if (rs1 & 0x3) { + sregs->trap = TRAP_UNALI; + break; + } + *rdd = sregs->pc; + npc = rs1 + operand2; + break; + case RETT: + address = rs1 + operand2; + new_cwp = ((sregs->psr & PSR_CWP) + 1) & PSR_CWP; + sregs->icnt = T_RETT; /* RETT takes two cycles */ + if (sregs->psr & PSR_ET) { + sregs->trap = TRAP_UNIMP; + break; + } + if (!(sregs->psr & PSR_S)) { + sregs->trap = TRAP_PRIVI; + break; + } + if (sregs->wim & (1 << new_cwp)) { + sregs->trap = TRAP_WUFL; + break; + } + if (address & 0x3) { + sregs->trap = TRAP_UNALI; + break; + } + sregs->psr = (sregs->psr & ~PSR_CWP) | new_cwp | PSR_ET; + sregs->psr = + (sregs->psr & ~PSR_S) | ((sregs->psr & PSR_PS) << 1); + npc = address; + break; + + case SCAN: + { + uint32 result, mask; + int i; + + if (!sparclite) { + sregs->trap = TRAP_UNIMP; + break; + } + mask = (operand2 & 0x80000000) | (operand2 >> 1); + result = rs1 ^ mask; + + for (i = 0; i < 32; i++) { + if (result & 0x80000000) + break; + result <<= 1; + } + + *rdd = i == 32 ? 63 : i; + } + break; + + default: + sregs->trap = TRAP_UNIMP; + break; + } + } + break; + case 3: /* Load/store instructions */ + + address = rs1 + operand2; + + if (sregs->psr & PSR_S) + asi = 11; + else + asi = 10; + + if (op3 & 4) { + sregs->icnt = T_ST; /* Set store instruction count */ +#ifdef STAT + sregs->nstore++; +#endif + } else { + sregs->icnt = T_LD; /* Set load instruction count */ +#ifdef STAT + sregs->nload++; +#endif + } + + /* Decode load/store instructions */ + + switch (op3) { + case LDDA: + if (!chk_asi(sregs, &asi, op3)) break; + case LDD: + if (address & 0x7) { + sregs->trap = TRAP_UNALI; + break; + } + if (rd & 1) { + rd &= 0x1e; + if (rd > 7) + rdd = &(sregs->r[(cwp + rd) & 0x7f]); + else + rdd = &(sregs->g[rd]); + } + mexc = memory_read(asi, address, ddata, 3, &ws); + sregs->hold += ws * 2; + sregs->icnt = T_LDD; + if (mexc) { + sregs->trap = TRAP_DEXC; + } else { + rdd[0] = ddata[0]; + rdd[1] = ddata[1]; +#ifdef STAT + sregs->nload++; /* Double load counts twice */ +#endif + } + break; + + case LDA: + if (!chk_asi(sregs, &asi, op3)) break; + case LD: + if (address & 0x3) { + sregs->trap = TRAP_UNALI; + break; + } + mexc = memory_read(asi, address, &data, 2, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; + } else { + *rdd = data; + } + break; + case LDSTUBA: + if (!chk_asi(sregs, &asi, op3)) break; + case LDSTUB: + mexc = memory_read(asi, address, &data, 0, &ws); + sregs->hold += ws; + sregs->icnt = T_LDST; + if (mexc) { + sregs->trap = TRAP_DEXC; + break; + } + *rdd = data; + data = 0x0ff; + mexc = memory_write(asi, address, &data, 0, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; + } +#ifdef STAT + sregs->nload++; +#endif + break; + case LDSBA: + case LDUBA: + if (!chk_asi(sregs, &asi, op3)) break; + case LDSB: + case LDUB: + mexc = memory_read(asi, address, &data, 0, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; + break; + } + if ((op3 == LDSB) && (data & 0x80)) + data |= 0xffffff00; + *rdd = data; + break; + case LDSHA: + case LDUHA: + if (!chk_asi(sregs, &asi, op3)) break; + case LDSH: + case LDUH: + if (address & 0x1) { + sregs->trap = TRAP_UNALI; + break; + } + mexc = memory_read(asi, address, &data, 1, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; + break; + } + if ((op3 == LDSH) && (data & 0x8000)) + data |= 0xffff0000; + *rdd = data; + break; + case LDF: + if (!((sregs->psr & PSR_EF) && FP_PRES)) { + sregs->trap = TRAP_FPDIS; + break; + } + if (address & 0x3) { + sregs->trap = TRAP_UNALI; + break; + } + if (ebase.simtime < sregs->ftime) { + if ((sregs->frd == rd) || (sregs->frs1 == rd) || + (sregs->frs2 == rd)) + sregs->fhold += (sregs->ftime - ebase.simtime); + } + mexc = memory_read(asi, address, &data, 2, &ws); + sregs->hold += ws; + sregs->flrd = rd; + sregs->ltime = ebase.simtime + sregs->icnt + FLSTHOLD + + sregs->hold + sregs->fhold; + if (mexc) { + sregs->trap = TRAP_DEXC; + } else { + sregs->fs[rd] = *((float32 *) & data); + } + break; + case LDDF: + if (!((sregs->psr & PSR_EF) && FP_PRES)) { + sregs->trap = TRAP_FPDIS; + break; + } + if (address & 0x7) { + sregs->trap = TRAP_UNALI; + break; + } + if (ebase.simtime < sregs->ftime) { + if (((sregs->frd >> 1) == (rd >> 1)) || + ((sregs->frs1 >> 1) == (rd >> 1)) || + ((sregs->frs2 >> 1) == (rd >> 1))) + sregs->fhold += (sregs->ftime - ebase.simtime); + } + mexc = memory_read(asi, address, ddata, 3, &ws); + sregs->hold += ws * 2; + sregs->icnt = T_LDD; + if (mexc) { + sregs->trap = TRAP_DEXC; + } else { + rd &= 0x1E; + sregs->flrd = rd; + sregs->fs[rd] = *((float32 *) & ddata[0]); +#ifdef STAT + sregs->nload++; /* Double load counts twice */ +#endif + sregs->fs[rd + 1] = *((float32 *) & ddata[1]); + sregs->ltime = ebase.simtime + sregs->icnt + FLSTHOLD + + sregs->hold + sregs->fhold; + } + break; + case LDFSR: + if (ebase.simtime < sregs->ftime) { + sregs->fhold += (sregs->ftime - ebase.simtime); + } + if (!((sregs->psr & PSR_EF) && FP_PRES)) { + sregs->trap = TRAP_FPDIS; + break; + } + if (address & 0x3) { + sregs->trap = TRAP_UNALI; + break; + } + mexc = memory_read(asi, address, &data, 2, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; + } else { + sregs->fsr = + (sregs->fsr & 0x7FF000) | (data & ~0x7FF000); + set_fsr(sregs->fsr); + } + break; + case STFSR: + if (!((sregs->psr & PSR_EF) && FP_PRES)) { + sregs->trap = TRAP_FPDIS; + break; + } + if (address & 0x3) { + sregs->trap = TRAP_UNALI; + break; + } + if (ebase.simtime < sregs->ftime) { + sregs->fhold += (sregs->ftime - ebase.simtime); + } + mexc = memory_write(asi, address, &sregs->fsr, 2, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; + } + break; + + case STA: + if (!chk_asi(sregs, &asi, op3)) break; + case ST: + if (address & 0x3) { + sregs->trap = TRAP_UNALI; + break; + } + mexc = memory_write(asi, address, rdd, 2, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; + } + break; + case STBA: + if (!chk_asi(sregs, &asi, op3)) break; + case STB: + mexc = memory_write(asi, address, rdd, 0, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; + } + break; + case STDA: + if (!chk_asi(sregs, &asi, op3)) break; + case STD: + if (address & 0x7) { + sregs->trap = TRAP_UNALI; + break; + } + if (rd & 1) { + rd &= 0x1e; + if (rd > 7) + rdd = &(sregs->r[(cwp + rd) & 0x7f]); + else + rdd = &(sregs->g[rd]); + } + mexc = memory_write(asi, address, rdd, 3, &ws); + sregs->hold += ws; + sregs->icnt = T_STD; +#ifdef STAT + sregs->nstore++; /* Double store counts twice */ +#endif + if (mexc) { + sregs->trap = TRAP_DEXC; + break; + } + break; + case STDFQ: + if ((sregs->psr & 0x1f) > 7) { + sregs->trap = TRAP_UNIMP; + break; + } + if (!((sregs->psr & PSR_EF) && FP_PRES)) { + sregs->trap = TRAP_FPDIS; + break; + } + if (address & 0x7) { + sregs->trap = TRAP_UNALI; + break; + } + if (!(sregs->fsr & FSR_QNE)) { + sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_SEQ_ERR; + break; + } + rdd = &(sregs->fpq[0]); + mexc = memory_write(asi, address, rdd, 3, &ws); + sregs->hold += ws; + sregs->icnt = T_STD; +#ifdef STAT + sregs->nstore++; /* Double store counts twice */ +#endif + if (mexc) { + sregs->trap = TRAP_DEXC; + break; + } else { + sregs->fsr &= ~FSR_QNE; + sregs->fpstate = FP_EXE_MODE; + } + break; + case STHA: + if (!chk_asi(sregs, &asi, op3)) break; + case STH: + if (address & 0x1) { + sregs->trap = TRAP_UNALI; + break; + } + mexc = memory_write(asi, address, rdd, 1, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; + } + break; + case STF: + if (!((sregs->psr & PSR_EF) && FP_PRES)) { + sregs->trap = TRAP_FPDIS; + break; + } + if (address & 0x3) { + sregs->trap = TRAP_UNALI; + break; + } + if (ebase.simtime < sregs->ftime) { + if (sregs->frd == rd) + sregs->fhold += (sregs->ftime - ebase.simtime); + } + mexc = memory_write(asi, address, &sregs->fsi[rd], 2, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; + } + break; + case STDF: + if (!((sregs->psr & PSR_EF) && FP_PRES)) { + sregs->trap = TRAP_FPDIS; + break; + } + if (address & 0x7) { + sregs->trap = TRAP_UNALI; + break; + } + rd &= 0x1E; + if (ebase.simtime < sregs->ftime) { + if ((sregs->frd == rd) || (sregs->frd + 1 == rd)) + sregs->fhold += (sregs->ftime - ebase.simtime); + } + mexc = memory_write(asi, address, &sregs->fsi[rd], 3, &ws); + sregs->hold += ws; + sregs->icnt = T_STD; +#ifdef STAT + sregs->nstore++; /* Double store counts twice */ +#endif + if (mexc) { + sregs->trap = TRAP_DEXC; + } + break; + case SWAPA: + if (!chk_asi(sregs, &asi, op3)) break; + case SWAP: + if (address & 0x3) { + sregs->trap = TRAP_UNALI; + break; + } + mexc = memory_read(asi, address, &data, 2, &ws); + sregs->hold += ws; + if (mexc) { + sregs->trap = TRAP_DEXC; + break; + } + mexc = memory_write(asi, address, rdd, 2, &ws); + sregs->hold += ws; + sregs->icnt = T_LDST; + if (mexc) { + sregs->trap = TRAP_DEXC; + break; + } else + *rdd = data; +#ifdef STAT + sregs->nload++; +#endif + break; + + + default: + sregs->trap = TRAP_UNIMP; + break; + } + +#ifdef LOAD_DEL + + if (!(op3 & 4)) { + sregs->ildtime = ebase.simtime + sregs->hold + sregs->icnt; + sregs->ildreg = rd; + if ((op3 | 0x10) == 0x13) + sregs->ildreg |= 1; /* Double load, odd register loaded + * last */ + } +#endif + break; + + default: + sregs->trap = TRAP_UNIMP; + break; + } + sregs->g[0] = 0; + if (!sregs->trap) { + sregs->pc = pc; + sregs->npc = npc; + } + return (0); +} + +#define T_FABSs 2 +#define T_FADDs 4 +#define T_FADDd 4 +#define T_FCMPs 4 +#define T_FCMPd 4 +#define T_FDIVs 20 +#define T_FDIVd 35 +#define T_FMOVs 2 +#define T_FMULs 5 +#define T_FMULd 9 +#define T_FNEGs 2 +#define T_FSQRTs 37 +#define T_FSQRTd 65 +#define T_FSUBs 4 +#define T_FSUBd 4 +#define T_FdTOi 7 +#define T_FdTOs 3 +#define T_FiTOs 6 +#define T_FiTOd 6 +#define T_FsTOi 6 +#define T_FsTOd 2 + +#define FABSs 0x09 +#define FADDs 0x41 +#define FADDd 0x42 +#define FCMPs 0x51 +#define FCMPd 0x52 +#define FCMPEs 0x55 +#define FCMPEd 0x56 +#define FDIVs 0x4D +#define FDIVd 0x4E +#define FMOVs 0x01 +#define FMULs 0x49 +#define FMULd 0x4A +#define FNEGs 0x05 +#define FSQRTs 0x29 +#define FSQRTd 0x2A +#define FSUBs 0x45 +#define FSUBd 0x46 +#define FdTOi 0xD2 +#define FdTOs 0xC6 +#define FiTOs 0xC4 +#define FiTOd 0xC8 +#define FsTOi 0xD1 +#define FsTOd 0xC9 + + +static int +fpexec(op3, rd, rs1, rs2, sregs) + uint32 op3, rd, rs1, rs2; + struct pstate *sregs; +{ + uint32 opf, tem, accex; + int32 fcc; + uint32 ldadj; + + if (sregs->fpstate == FP_EXC_MODE) { + sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_SEQ_ERR; + sregs->fpstate = FP_EXC_PE; + return (0); + } + if (sregs->fpstate == FP_EXC_PE) { + sregs->fpstate = FP_EXC_MODE; + return (TRAP_FPEXC); + } + opf = (sregs->inst >> 5) & 0x1ff; + + /* + * Check if we already have an FPop in the pipe. If so, halt until it is + * finished by incrementing fhold with the remaining execution time + */ + + if (ebase.simtime < sregs->ftime) { + sregs->fhold = (sregs->ftime - ebase.simtime); + } else { + sregs->fhold = 0; + + /* Check load dependencies. */ + + if (ebase.simtime < sregs->ltime) { + + /* Don't check rs1 if single operand instructions */ + + if (((opf >> 6) == 0) || ((opf >> 6) == 3)) + rs1 = 32; + + /* Adjust for double floats */ + + ldadj = opf & 1; + if (!(((sregs->flrd - rs1) >> ldadj) && ((sregs->flrd - rs2) >> ldadj))) + sregs->fhold++; + } + } + + sregs->finst++; + + sregs->frs1 = rs1; /* Store src and dst for dependecy check */ + sregs->frs2 = rs2; + sregs->frd = rd; + + sregs->ftime = ebase.simtime + sregs->hold + sregs->fhold; + + /* SPARC is big-endian - swap double floats if host is little-endian */ + /* This is ugly - I know ... */ + + /* FIXME: should use (CURRENT_HOST_BYTE_ORDER == CURRENT_TARGET_BYTE_ORDER) + but what about machines where float values are different endianness + from integer values? */ + +#ifdef HOST_LITTLE_ENDIAN_FLOAT + rs1 &= 0x1f; + switch (opf) { + case FADDd: + case FDIVd: + case FMULd: + case FSQRTd: + case FSUBd: + case FCMPd: + case FCMPEd: + case FdTOi: + case FdTOs: + sregs->fdp[rs1 | 1] = sregs->fs[rs1 & ~1]; + sregs->fdp[rs1 & ~1] = sregs->fs[rs1 | 1]; + sregs->fdp[rs2 | 1] = sregs->fs[rs2 & ~1]; + sregs->fdp[rs2 & ~1] = sregs->fs[rs2 | 1]; + default: + } +#endif + + clear_accex(); + + switch (opf) { + case FABSs: + sregs->fs[rd] = fabs(sregs->fs[rs2]); + sregs->ftime += T_FABSs; + sregs->frs1 = 32; /* rs1 ignored */ + break; + case FADDs: + sregs->fs[rd] = sregs->fs[rs1] + sregs->fs[rs2]; + sregs->ftime += T_FADDs; + break; + case FADDd: + sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] + sregs->fd[rs2 >> 1]; + sregs->ftime += T_FADDd; + break; + case FCMPs: + case FCMPEs: + if (sregs->fs[rs1] == sregs->fs[rs2]) + fcc = 3; + else if (sregs->fs[rs1] < sregs->fs[rs2]) + fcc = 2; + else if (sregs->fs[rs1] > sregs->fs[rs2]) + fcc = 1; + else + fcc = 0; + sregs->fsr |= 0x0C00; + sregs->fsr &= ~(fcc << 10); + sregs->ftime += T_FCMPs; + sregs->frd = 32; /* rd ignored */ + if ((fcc == 0) && (opf == FCMPEs)) { + sregs->fpstate = FP_EXC_PE; + sregs->fsr = (sregs->fsr & ~0x1C000) | (1 << 14); + } + break; + case FCMPd: + case FCMPEd: + if (sregs->fd[rs1 >> 1] == sregs->fd[rs2 >> 1]) + fcc = 3; + else if (sregs->fd[rs1 >> 1] < sregs->fd[rs2 >> 1]) + fcc = 2; + else if (sregs->fd[rs1 >> 1] > sregs->fd[rs2 >> 1]) + fcc = 1; + else + fcc = 0; + sregs->fsr |= 0x0C00; + sregs->fsr &= ~(fcc << 10); + sregs->ftime += T_FCMPd; + sregs->frd = 32; /* rd ignored */ + if ((fcc == 0) && (opf == FCMPEd)) { + sregs->fpstate = FP_EXC_PE; + sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE; + } + break; + case FDIVs: + sregs->fs[rd] = sregs->fs[rs1] / sregs->fs[rs2]; + sregs->ftime += T_FDIVs; + break; + case FDIVd: + sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] / sregs->fd[rs2 >> 1]; + sregs->ftime += T_FDIVd; + break; + case FMOVs: + sregs->fs[rd] = sregs->fs[rs2]; + sregs->ftime += T_FMOVs; + sregs->frs1 = 32; /* rs1 ignored */ + break; + case FMULs: + sregs->fs[rd] = sregs->fs[rs1] * sregs->fs[rs2]; + sregs->ftime += T_FMULs; + break; + case FMULd: + sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] * sregs->fd[rs2 >> 1]; + sregs->ftime += T_FMULd; + break; + case FNEGs: + sregs->fs[rd] = -sregs->fs[rs2]; + sregs->ftime += T_FNEGs; + sregs->frs1 = 32; /* rs1 ignored */ + break; + case FSQRTs: + if (sregs->fs[rs2] < 0.0) { + sregs->fpstate = FP_EXC_PE; + sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE; + sregs->fsr = (sregs->fsr & 0x1f) | 0x10; + break; + } + sregs->fs[rd] = sqrt(sregs->fs[rs2]); + sregs->ftime += T_FSQRTs; + sregs->frs1 = 32; /* rs1 ignored */ + break; + case FSQRTd: + if (sregs->fd[rs2 >> 1] < 0.0) { + sregs->fpstate = FP_EXC_PE; + sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE; + sregs->fsr = (sregs->fsr & 0x1f) | 0x10; + break; + } + sregs->fd[rd >> 1] = sqrt(sregs->fd[rs2 >> 1]); + sregs->ftime += T_FSQRTd; + sregs->frs1 = 32; /* rs1 ignored */ + break; + case FSUBs: + sregs->fs[rd] = sregs->fs[rs1] - sregs->fs[rs2]; + sregs->ftime += T_FSUBs; + break; + case FSUBd: + sregs->fd[rd >> 1] = sregs->fd[rs1 >> 1] - sregs->fd[rs2 >> 1]; + sregs->ftime += T_FSUBd; + break; + case FdTOi: + sregs->fsi[rd] = (int) sregs->fd[rs2 >> 1]; + sregs->ftime += T_FdTOi; + sregs->frs1 = 32; /* rs1 ignored */ + break; + case FdTOs: + sregs->fs[rd] = (float32) sregs->fd[rs2 >> 1]; + sregs->ftime += T_FdTOs; + sregs->frs1 = 32; /* rs1 ignored */ + break; + case FiTOs: + sregs->fs[rd] = (float32) sregs->fsi[rs2]; + sregs->ftime += T_FiTOs; + sregs->frs1 = 32; /* rs1 ignored */ + break; + case FiTOd: + sregs->fd[rd >> 1] = (float64) sregs->fsi[rs2]; + sregs->ftime += T_FiTOd; + sregs->frs1 = 32; /* rs1 ignored */ + break; + case FsTOi: + sregs->fsi[rd] = (int) sregs->fs[rs2]; + sregs->ftime += T_FsTOi; + sregs->frs1 = 32; /* rs1 ignored */ + break; + case FsTOd: + sregs->fd[rd >> 1] = sregs->fs[rs2]; + sregs->ftime += T_FsTOd; + sregs->frs1 = 32; /* rs1 ignored */ + break; + + default: + sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_UNIMP; + sregs->fpstate = FP_EXC_PE; + } + +#ifdef ERRINJ + if (errftt) { + sregs->fsr = (sregs->fsr & ~FSR_TT) | (errftt << 14); + sregs->fpstate = FP_EXC_PE; + if (sis_verbose) printf("Inserted fpu error %X\n",errftt); + errftt = 0; + } +#endif + + accex = get_accex(); + +#ifdef HOST_LITTLE_ENDIAN_FLOAT + switch (opf) { + case FADDd: + case FDIVd: + case FMULd: + case FSQRTd: + case FSUBd: + case FiTOd: + case FsTOd: + sregs->fs[rd & ~1] = sregs->fdp[rd | 1]; + sregs->fs[rd | 1] = sregs->fdp[rd & ~1]; + default: + } +#endif + if (sregs->fpstate == FP_EXC_PE) { + sregs->fpq[0] = sregs->pc; + sregs->fpq[1] = sregs->inst; + sregs->fsr |= FSR_QNE; + } else { + tem = (sregs->fsr >> 23) & 0x1f; + if (tem & accex) { + sregs->fpstate = FP_EXC_PE; + sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_IEEE; + sregs->fsr = ((sregs->fsr & ~0x1f) | accex); + } else { + sregs->fsr = ((((sregs->fsr >> 5) | accex) << 5) | accex); + } + if (sregs->fpstate == FP_EXC_PE) { + sregs->fpq[0] = sregs->pc; + sregs->fpq[1] = sregs->inst; + sregs->fsr |= FSR_QNE; + } + } + clear_accex(); + + return (0); + + +} + +static int +chk_asi(sregs, asi, op3) + struct pstate *sregs; + uint32 *asi, op3; + +{ + if (!(sregs->psr & PSR_S)) { + sregs->trap = TRAP_PRIVI; + return (0); + } else if (sregs->inst & INST_I) { + sregs->trap = TRAP_UNIMP; + return (0); + } else + *asi = (sregs->inst >> 5) & 0x0ff; + return(1); +} + +int +execute_trap(sregs) + struct pstate *sregs; +{ + int32 cwp; + + if (sregs->trap == 256) { + sregs->pc = 0; + sregs->npc = 4; + sregs->trap = 0; + } else if (sregs->trap == 257) { + return (ERROR); + } else { + + if ((sregs->psr & PSR_ET) == 0) + return (ERROR); + + sregs->tbr = (sregs->tbr & 0xfffff000) | (sregs->trap << 4); + sregs->trap = 0; + sregs->psr &= ~PSR_ET; + sregs->psr |= ((sregs->psr & PSR_S) >> 1); + sregs->annul = 0; + sregs->psr = (((sregs->psr & PSR_CWP) - 1) & 0x7) | (sregs->psr & ~PSR_CWP); + cwp = ((sregs->psr & PSR_CWP) << 4); + sregs->r[(cwp + 17) & 0x7f] = sregs->pc; + sregs->r[(cwp + 18) & 0x7f] = sregs->npc; + sregs->psr |= PSR_S; + sregs->pc = sregs->tbr; + sregs->npc = sregs->tbr + 4; + + if ( 0 != (1 & sregs->asr17) ) { + /* single vector trapping! */ + sregs->pc = sregs->tbr & 0xfffff000; + sregs->npc = sregs->pc + 4; + } + + /* Increase simulator time */ + sregs->icnt = TRAP_C; + + } + + + return (0); + +} + +extern struct irqcell irqarr[16]; + +int +check_interrupts(sregs) + struct pstate *sregs; +{ +#ifdef ERRINJ + if (errtt) { + sregs->trap = errtt; + if (sis_verbose) printf("Inserted error trap 0x%02X\n",errtt); + errtt = 0; + } +#endif + + if ((ext_irl) && (sregs->psr & PSR_ET) && + ((ext_irl == 15) || (ext_irl > (int) ((sregs->psr & PSR_PIL) >> 8)))) { + if (sregs->trap == 0) { + sregs->trap = 16 + ext_irl; + irqarr[ext_irl & 0x0f].callback(irqarr[ext_irl & 0x0f].arg); + return(1); + } + } + return(0); +} + +void +init_regs(sregs) + struct pstate *sregs; +{ + sregs->pc = 0; + sregs->npc = 4; + sregs->trap = 0; + sregs->psr &= 0x00f03fdf; + sregs->psr |= 0x080; /* Set supervisor bit */ + sregs->breakpoint = 0; + sregs->annul = 0; + sregs->fpstate = FP_EXE_MODE; + sregs->fpqn = 0; + sregs->ftime = 0; + sregs->ltime = 0; + sregs->err_mode = 0; + ext_irl = 0; + sregs->g[0] = 0; +#ifdef HOST_LITTLE_ENDIAN_FLOAT + sregs->fdp = (float32 *) sregs->fd; + sregs->fsi = (int32 *) sregs->fs; +#else + sregs->fs = (float32 *) sregs->fd; + sregs->fsi = (int32 *) sregs->fd; +#endif + sregs->fsr = 0; + sregs->fpu_pres = !nfp; + set_fsr(sregs->fsr); + sregs->bphit = 0; + sregs->ildreg = 0; + sregs->ildtime = 0; + + sregs->y = 0; + sregs->asr17 = 0; + + sregs->rett_err = 0; + sregs->jmpltime = 0; +} diff --git a/sim/erc32/float.c b/sim/erc32/float.c new file mode 100644 index 0000000..fe2f41e --- /dev/null +++ b/sim/erc32/float.c @@ -0,0 +1,212 @@ +/* + * This file is part of SIS. + * + * SIS, SPARC instruction simulator. Copyright (C) 1995 Jiri Gaisler, European + * Space Agency + * + * 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., 675 + * Mass Ave, Cambridge, MA 02139, USA. + * + * + * This file implements the interface between the host and the simulated + * FPU. IEEE trap handling is done as follows: + * 1. In the host, all IEEE traps are masked + * 2. After each simulated FPU instruction, check if any exception occured + * by reading the exception bits from the host FPU status register + * (get_accex()). + * 3. Propagate any exceptions to the simulated FSR. + * 4. Clear host exception bits + * + * + * This can also be done using ieee_flags() library routine on sun. + */ + +#include "sis.h" + +/* Forward declarations */ + +extern uint32 _get_sw PARAMS ((void)); +extern uint32 _get_cw PARAMS ((void)); +static void __setfpucw PARAMS ((unsigned short fpu_control)); + +/* This host dependent routine should return the accrued exceptions */ +int +get_accex() +{ +#ifdef sparc + return ((_get_fsr_raw() >> 5) & 0x1F); +#elif i386 + uint32 accx; + + accx = _get_sw() & 0x3f; + accx = ((accx & 1) << 4) | ((accx & 2) >> 1) | ((accx & 4) >> 1) | + (accx & 8) | ((accx & 16) >> 2) | ((accx & 32) >> 5); + return(accx); +#else + return(0); +#warning no fpu trap support for this target +#endif + +} + +/* How to clear the accrued exceptions */ +void +clear_accex() +{ +#ifdef sparc + set_fsr((_get_fsr_raw() & ~0x3e0)); +#elif i386 + asm(" +.text + fnclex + + "); +#else +#warning no fpu trap support for this target +#endif +} + +/* How to map SPARC FSR onto the host */ +void +set_fsr(fsr) +uint32 fsr; +{ +#ifdef sparc + _set_fsr_raw(fsr & ~0x0f800000); +#elif i386 + void __setfpucw(unsigned short fpu_control); + uint32 rawfsr; + + fsr >>= 30; + switch (fsr) { + case 0: + case 2: break; + case 1: fsr = 3; + case 3: fsr = 1; + } + rawfsr = _get_cw(); + rawfsr |= (fsr << 10) | 0x3ff; + __setfpucw(rawfsr); +#else +#warning no fpu trap support for this target +#endif +} + + +/* Host dependent support functions */ + +#ifdef sparc + + asm(" + +.text + .align 4 + .global __set_fsr_raw,_set_fsr_raw +__set_fsr_raw: +_set_fsr_raw: + save %sp,-104,%sp + st %i0,[%fp+68] + ld [%fp+68], %fsr + mov 0,%i0 + ret + restore + + .align 4 + .global __get_fsr_raw + .global _get_fsr_raw +__get_fsr_raw: +_get_fsr_raw: + save %sp,-104,%sp + st %fsr,[%fp+68] + ld [%fp+68], %i0 + ret + restore + + "); + +#elif i386 + + asm(" + +.text + .align 8 +.globl _get_sw,__get_sw +__get_sw: +_get_sw: + pushl %ebp + movl %esp,%ebp + movl $0,%eax + fnstsw %ax + movl %ebp,%esp + popl %ebp + ret + + .align 8 +.globl _get_cw,__get_cw +__get_cw: +_get_cw: + pushl %ebp + movl %esp,%ebp + subw $2,%esp + fnstcw -2(%ebp) + movw -2(%ebp),%eax + movl %ebp,%esp + popl %ebp + ret + + + "); + + +#else +#warning no fpu trap support for this target +#endif + +#if i386 +/* #if defined _WIN32 || defined __GO32__ */ +/* This is so floating exception handling works on NT + These definitions are from the linux fpu_control.h, which + doesn't exist on NT. + + default to: + - extended precision + - rounding to nearest + - exceptions on overflow, zero divide and NaN +*/ +#define _FPU_DEFAULT 0x1372 +#define _FPU_RESERVED 0xF0C0 /* Reserved bits in cw */ + +static void +__setfpucw(unsigned short fpu_control) +{ + volatile unsigned short cw; + + /* If user supplied _fpu_control, use it ! */ + if (!fpu_control) + { + /* use defaults */ + fpu_control = _FPU_DEFAULT; + } + /* Get Control Word */ + __asm__ volatile ("fnstcw %0" : "=m" (cw) : ); + + /* mask in */ + cw &= _FPU_RESERVED; + cw = cw | (fpu_control & ~_FPU_RESERVED); + + /* set cw */ + __asm__ volatile ("fldcw %0" :: "m" (cw)); +} +/* #endif */ +#endif diff --git a/sim/erc32/func.c b/sim/erc32/func.c new file mode 100644 index 0000000..b54beeb --- /dev/null +++ b/sim/erc32/func.c @@ -0,0 +1,1162 @@ +/* + * func.c, misc simulator functions. This file is part of SIS. + * + * SIS, SPARC instruction simulator V1.8 Copyright (C) 1995 Jiri Gaisler, + * European Space Agency + * + * 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., 675 + * Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <signal.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include "sis.h" +#include "end.h" +#include <dis-asm.h> +#include "sim-config.h" + + +#define VAL(x) strtoul(x,(char **)NULL,0) + +extern int current_target_byte_order; +struct disassemble_info dinfo; +struct pstate sregs; +extern struct estate ebase; +int ctrl_c = 0; +int sis_verbose = 0; +char *sis_version = "2.7.5"; +int nfp = 0; +int ift = 0; +int wrp = 0; +int rom8 = 0; +int uben = 0; +int termsave; +int sparclite = 0; /* emulating SPARClite instructions? */ +int sparclite_board = 0; /* emulating SPARClite board RAM? */ +char uart_dev1[128] = ""; +char uart_dev2[128] = ""; +extern int ext_irl; +uint32 last_load_addr = 0; + +#ifdef ERRINJ +uint32 errcnt = 0; +uint32 errper = 0; +uint32 errtt = 0; +uint32 errftt = 0; +uint32 errmec = 0; +#endif + +/* Forward declarations */ + +static int batch PARAMS ((struct pstate *sregs, char *fname)); +static void set_rega PARAMS ((struct pstate *sregs, char *reg, uint32 rval)); +static void disp_reg PARAMS ((struct pstate *sregs, char *reg)); +static uint32 limcalc PARAMS ((float32 freq)); +static void int_handler PARAMS ((int32 sig)); +static void init_event PARAMS ((void)); +static int disp_fpu PARAMS ((struct pstate *sregs)); +static void disp_regs PARAMS ((struct pstate *sregs, int cwp)); +static void disp_ctrl PARAMS ((struct pstate *sregs)); +static void disp_mem PARAMS ((uint32 addr, uint32 len)); + +static int +batch(sregs, fname) + struct pstate *sregs; + char *fname; +{ + FILE *fp; + char lbuf[1024]; + + if ((fp = fopen(fname, "r")) == NULL) { + fprintf(stderr, "couldn't open batch file %s\n", fname); + return (0); + } + while (!feof(fp)) { + lbuf[0] = 0; + fgets(lbuf, 1023, fp); + if ((strlen(lbuf) > 0) && (lbuf[strlen(lbuf) - 1] == '\n')) + lbuf[strlen(lbuf) - 1] = 0; + printf("sis> %s\n", lbuf); + exec_cmd(sregs, lbuf); + } + fclose(fp); + return (1); +} + +void +set_regi(sregs, reg, rval) + struct pstate *sregs; + int32 reg; + uint32 rval; +{ + uint32 cwp; + + cwp = ((sregs->psr & 0x7) << 4); + if ((reg > 0) && (reg < 8)) { + sregs->g[reg] = rval; + } else if ((reg >= 8) && (reg < 32)) { + sregs->r[(cwp + reg) & 0x7f] = rval; + } else if ((reg >= 32) && (reg < 64)) { + sregs->fsi[reg - 32] = rval; + } else { + switch (reg) { + case 64: + sregs->y = rval; + break; + case 65: + sregs->psr = rval; + break; + case 66: + sregs->wim = rval; + break; + case 67: + sregs->tbr = rval; + break; + case 68: + sregs->pc = rval; + break; + case 69: + sregs->npc = rval; + break; + case 70: + sregs->fsr = rval; + set_fsr(rval); + break; + default:break; + } + } +} + +void +get_regi(struct pstate * sregs, int32 reg, char *buf) +{ + uint32 cwp; + uint32 rval = 0; + + cwp = ((sregs->psr & 0x7) << 4); + if ((reg >= 0) && (reg < 8)) { + rval = sregs->g[reg]; + } else if ((reg >= 8) && (reg < 32)) { + rval = sregs->r[(cwp + reg) & 0x7f]; + } else if ((reg >= 32) && (reg < 64)) { + rval = sregs->fsi[reg - 32]; + } else { + switch (reg) { + case 64: + rval = sregs->y; + break; + case 65: + rval = sregs->psr; + break; + case 66: + rval = sregs->wim; + break; + case 67: + rval = sregs->tbr; + break; + case 68: + rval = sregs->pc; + break; + case 69: + rval = sregs->npc; + break; + case 70: + rval = sregs->fsr; + break; + default:break; + } + } + if (current_target_byte_order == BIG_ENDIAN) { + buf[0] = (rval >> 24) & 0x0ff; + buf[1] = (rval >> 16) & 0x0ff; + buf[2] = (rval >> 8) & 0x0ff; + buf[3] = rval & 0x0ff; + } + else { + buf[3] = (rval >> 24) & 0x0ff; + buf[2] = (rval >> 16) & 0x0ff; + buf[1] = (rval >> 8) & 0x0ff; + buf[0] = rval & 0x0ff; + } +} + + +static void +set_rega(sregs, reg, rval) + struct pstate *sregs; + char *reg; + uint32 rval; +{ + uint32 cwp; + int32 err = 0; + + cwp = ((sregs->psr & 0x7) << 4); + if (strcmp(reg, "psr") == 0) + sregs->psr = (rval = (rval & 0x00f03fff)); + else if (strcmp(reg, "tbr") == 0) + sregs->tbr = (rval = (rval & 0xfffffff0)); + else if (strcmp(reg, "wim") == 0) + sregs->wim = (rval = (rval & 0x0ff)); + else if (strcmp(reg, "y") == 0) + sregs->y = rval; + else if (strcmp(reg, "pc") == 0) + sregs->pc = rval; + else if (strcmp(reg, "npc") == 0) + sregs->npc = rval; + else if (strcmp(reg, "fsr") == 0) { + sregs->fsr = rval; + set_fsr(rval); + } else if (strcmp(reg, "g0") == 0) + err = 2; + else if (strcmp(reg, "g1") == 0) + sregs->g[1] = rval; + else if (strcmp(reg, "g2") == 0) + sregs->g[2] = rval; + else if (strcmp(reg, "g3") == 0) + sregs->g[3] = rval; + else if (strcmp(reg, "g4") == 0) + sregs->g[4] = rval; + else if (strcmp(reg, "g5") == 0) + sregs->g[5] = rval; + else if (strcmp(reg, "g6") == 0) + sregs->g[6] = rval; + else if (strcmp(reg, "g7") == 0) + sregs->g[7] = rval; + else if (strcmp(reg, "o0") == 0) + sregs->r[(cwp + 8) & 0x7f] = rval; + else if (strcmp(reg, "o1") == 0) + sregs->r[(cwp + 9) & 0x7f] = rval; + else if (strcmp(reg, "o2") == 0) + sregs->r[(cwp + 10) & 0x7f] = rval; + else if (strcmp(reg, "o3") == 0) + sregs->r[(cwp + 11) & 0x7f] = rval; + else if (strcmp(reg, "o4") == 0) + sregs->r[(cwp + 12) & 0x7f] = rval; + else if (strcmp(reg, "o5") == 0) + sregs->r[(cwp + 13) & 0x7f] = rval; + else if (strcmp(reg, "o6") == 0) + sregs->r[(cwp + 14) & 0x7f] = rval; + else if (strcmp(reg, "o7") == 0) + sregs->r[(cwp + 15) & 0x7f] = rval; + else if (strcmp(reg, "l0") == 0) + sregs->r[(cwp + 16) & 0x7f] = rval; + else if (strcmp(reg, "l1") == 0) + sregs->r[(cwp + 17) & 0x7f] = rval; + else if (strcmp(reg, "l2") == 0) + sregs->r[(cwp + 18) & 0x7f] = rval; + else if (strcmp(reg, "l3") == 0) + sregs->r[(cwp + 19) & 0x7f] = rval; + else if (strcmp(reg, "l4") == 0) + sregs->r[(cwp + 20) & 0x7f] = rval; + else if (strcmp(reg, "l5") == 0) + sregs->r[(cwp + 21) & 0x7f] = rval; + else if (strcmp(reg, "l6") == 0) + sregs->r[(cwp + 22) & 0x7f] = rval; + else if (strcmp(reg, "l7") == 0) + sregs->r[(cwp + 23) & 0x7f] = rval; + else if (strcmp(reg, "i0") == 0) + sregs->r[(cwp + 24) & 0x7f] = rval; + else if (strcmp(reg, "i1") == 0) + sregs->r[(cwp + 25) & 0x7f] = rval; + else if (strcmp(reg, "i2") == 0) + sregs->r[(cwp + 26) & 0x7f] = rval; + else if (strcmp(reg, "i3") == 0) + sregs->r[(cwp + 27) & 0x7f] = rval; + else if (strcmp(reg, "i4") == 0) + sregs->r[(cwp + 28) & 0x7f] = rval; + else if (strcmp(reg, "i5") == 0) + sregs->r[(cwp + 29) & 0x7f] = rval; + else if (strcmp(reg, "i6") == 0) + sregs->r[(cwp + 30) & 0x7f] = rval; + else if (strcmp(reg, "i7") == 0) + sregs->r[(cwp + 31) & 0x7f] = rval; + else + err = 1; + switch (err) { + case 0: + printf("%s = %d (0x%08x)\n", reg, rval, rval); + break; + case 1: + printf("no such regiser: %s\n", reg); + break; + case 2: + printf("cannot set g0\n"); + break; + default: + break; + } + +} + +static void +disp_reg(sregs, reg) + struct pstate *sregs; + char *reg; +{ + if (strncmp(reg, "w",1) == 0) + disp_regs(sregs, VAL(®[1])); +} + +#ifdef ERRINJ + +void +errinj() +{ + int err; + + switch (err = (random() % 12)) { + case 0: errtt = 0x61; break; + case 1: errtt = 0x62; break; + case 2: errtt = 0x63; break; + case 3: errtt = 0x64; break; + case 4: errtt = 0x65; break; + case 5: + case 6: + case 7: errftt = err; + break; + case 8: errmec = 1; break; + case 9: errmec = 2; break; + case 10: errmec = 5; break; + case 11: errmec = 6; break; + } + errcnt++; + if (errper) event(errinj, 0, (random()%errper)); +} + +void +errinjstart() +{ + if (errper) event(errinj, 0, (random()%errper)); +} + +#endif + +static uint32 +limcalc (freq) + float32 freq; +{ + uint32 unit, lim; + double flim; + char *cmd1, *cmd2; + + unit = 1; + lim = -1; + if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { + lim = VAL(cmd1); + if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) { + if (strcmp(cmd2,"us")==0) unit = 1; + if (strcmp(cmd2,"ms")==0) unit = 1000; + if (strcmp(cmd2,"s")==0) unit = 1000000; + } + flim = (double) lim * (double) unit * (double) freq + + (double) ebase.simtime; + if ((flim > ebase.simtime) && (flim < 4294967296.0)) { + lim = (uint32) flim; + } else { + printf("error in expression\n"); + lim = -1; + } + } + return (lim); +} + +int +exec_cmd(sregs, cmd) + char *cmd; + struct pstate *sregs; +{ + char *cmd1, *cmd2; + int32 stat; + uint32 len, i, clen, j; + static uint32 daddr = 0; + char *cmdsave; + + stat = OK; + cmdsave = strdup(cmd); + if ((cmd1 = strtok(cmd, " \t")) != NULL) { + clen = strlen(cmd1); + if (strncmp(cmd1, "bp", clen) == 0) { + for (i = 0; i < sregs->bptnum; i++) { + printf(" %d : 0x%08x\n", i + 1, sregs->bpts[i]); + } + } else if (strncmp(cmd1, "+bp", clen) == 0) { + if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { + sregs->bpts[sregs->bptnum] = VAL(cmd1) & ~0x3; + printf("added breakpoint %d at 0x%08x\n", + sregs->bptnum + 1, sregs->bpts[sregs->bptnum]); + sregs->bptnum += 1; + } + } else if (strncmp(cmd1, "-bp", clen) == 0) { + if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { + i = VAL(cmd1) - 1; + if ((i >= 0) && (i < sregs->bptnum)) { + printf("deleted breakpoint %d at 0x%08x\n", i + 1, + sregs->bpts[i]); + for (; i < sregs->bptnum - 1; i++) { + sregs->bpts[i] = sregs->bpts[i + 1]; + } + sregs->bptnum -= 1; + } + } + } else if (strncmp(cmd1, "batch", clen) == 0) { + if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) { + printf("no file specified\n"); + } else { + batch(sregs, cmd1); + } + } else if (strncmp(cmd1, "cont", clen) == 0) { + if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) { + stat = run_sim(sregs, -1, 0); + } else { + stat = run_sim(sregs, VAL(cmd1), 0); + } + daddr = sregs->pc; + sim_halt(); + } else if (strncmp(cmd1, "debug", clen) == 0) { + if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { + sis_verbose = VAL(cmd1); + } + printf("Debug level = %d\n",sis_verbose); + } else if (strncmp(cmd1, "dis", clen) == 0) { + if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { + daddr = VAL(cmd1); + } + if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) { + len = VAL(cmd2); + } else + len = 16; + printf("\n"); + dis_mem(daddr, len, &dinfo); + printf("\n"); + daddr += len * 4; + } else if (strncmp(cmd1, "echo", clen) == 0) { + if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { + printf("%s\n", (&cmdsave[clen+1])); + } +#ifdef ERRINJ + } else if (strncmp(cmd1, "error", clen) == 0) { + if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { + errper = VAL(cmd1); + if (errper) { + event(errinj, 0, (len = (random()%errper))); + printf("Error injection started with period %d\n",len); + } + } else printf("Injected errors: %d\n",errcnt); +#endif + } else if (strncmp(cmd1, "float", clen) == 0) { + stat = disp_fpu(sregs); + } else if (strncmp(cmd1, "go", clen) == 0) { + if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) { + len = last_load_addr; + } else { + len = VAL(cmd1); + } + sregs->pc = len & ~3; + sregs->npc = sregs->pc + 4; + printf("resuming at 0x%08x\n",sregs->pc); + if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) { + stat = run_sim(sregs, VAL(cmd2), 0); + } else { + stat = run_sim(sregs, -1, 0); + } + daddr = sregs->pc; + sim_halt(); + } else if (strncmp(cmd1, "help", clen) == 0) { + gen_help(); + } else if (strncmp(cmd1, "history", clen) == 0) { + if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { + sregs->histlen = VAL(cmd1); + if (sregs->histbuf != NULL) + free(sregs->histbuf); + sregs->histbuf = (struct histype *) calloc(sregs->histlen, sizeof(struct histype)); + printf("trace history length = %d\n\r", sregs->histlen); + sregs->histind = 0; + + } else { + j = sregs->histind; + for (i = 0; i < sregs->histlen; i++) { + if (j >= sregs->histlen) + j = 0; + printf(" %8d ", sregs->histbuf[j].time); + dis_mem(sregs->histbuf[j].addr, 1, &dinfo); + j++; + } + } + + } else if (strncmp(cmd1, "load", clen) == 0) { + if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { + last_load_addr = bfd_load(cmd1); + while ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) + last_load_addr = bfd_load(cmd1); + } else { + printf("load: no file specified\n"); + } + } else if (strncmp(cmd1, "mem", clen) == 0) { + if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) + daddr = VAL(cmd1); + if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) + len = VAL(cmd2); + else + len = 64; + disp_mem(daddr, len); + daddr += len; + } else if (strncmp(cmd1, "perf", clen) == 0) { + cmd1 = strtok(NULL, " \t\n\r"); + if ((cmd1 != NULL) && + (strncmp(cmd1, "reset", strlen(cmd1)) == 0)) { + reset_stat(sregs); + } else + show_stat(sregs); + } else if (strncmp(cmd1, "quit", clen) == 0) { + exit(0); + } else if (strncmp(cmd1, "reg", clen) == 0) { + cmd1 = strtok(NULL, " \t\n\r"); + cmd2 = strtok(NULL, " \t\n\r"); + if (cmd2 != NULL) + set_rega(sregs, cmd1, VAL(cmd2)); + else if (cmd1 != NULL) + disp_reg(sregs, cmd1); + else { + disp_regs(sregs,sregs->psr); + disp_ctrl(sregs); + } + } else if (strncmp(cmd1, "reset", clen) == 0) { + ebase.simtime = 0; + reset_all(); + reset_stat(sregs); + } else if (strncmp(cmd1, "run", clen) == 0) { + ebase.simtime = 0; + reset_all(); + reset_stat(sregs); + if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) { + stat = run_sim(sregs, -1, 0); + } else { + stat = run_sim(sregs, VAL(cmd1), 0); + } + daddr = sregs->pc; + sim_halt(); + } else if (strncmp(cmd1, "shell", clen) == 0) { + if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) { + system(&cmdsave[clen]); + } + } else if (strncmp(cmd1, "step", clen) == 0) { + stat = run_sim(sregs, 1, 1); + daddr = sregs->pc; + sim_halt(); + } else if (strncmp(cmd1, "tcont", clen) == 0) { + sregs->tlimit = limcalc(sregs->freq); + stat = run_sim(sregs, -1, 0); + daddr = sregs->pc; + sim_halt(); + } else if (strncmp(cmd1, "tgo", clen) == 0) { + if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) { + len = last_load_addr; + } else { + len = VAL(cmd1); + sregs->tlimit = limcalc(sregs->freq); + } + sregs->pc = len & ~3; + sregs->npc = sregs->pc + 4; + printf("resuming at 0x%08x\n",sregs->pc); + stat = run_sim(sregs, -1, 0); + daddr = sregs->pc; + sim_halt(); + } else if (strncmp(cmd1, "tlimit", clen) == 0) { + sregs->tlimit = limcalc(sregs->freq); + if (sregs->tlimit != (uint32) -1) + printf("simulation limit = %u (%.3f ms)\n",(uint32) sregs->tlimit, + sregs->tlimit / sregs->freq / 1000); + } else if (strncmp(cmd1, "tra", clen) == 0) { + if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) { + stat = run_sim(sregs, -1, 1); + } else { + stat = run_sim(sregs, VAL(cmd1), 1); + } + printf("\n"); + daddr = sregs->pc; + sim_halt(); + } else if (strncmp(cmd1, "trun", clen) == 0) { + ebase.simtime = 0; + reset_all(); + reset_stat(sregs); + sregs->tlimit = limcalc(sregs->freq); + stat = run_sim(sregs, -1, 0); + daddr = sregs->pc; + sim_halt(); + } else + printf("syntax error\n"); + } + if (cmdsave != NULL) + free(cmdsave); + return (stat); +} + + +void +reset_stat(sregs) + struct pstate *sregs; +{ + sregs->tottime = 0; + sregs->pwdtime = 0; + sregs->ninst = 0; + sregs->fholdt = 0; + sregs->holdt = 0; + sregs->icntt = 0; + sregs->finst = 0; + sregs->nstore = 0; + sregs->nload = 0; + sregs->nbranch = 0; + sregs->simstart = ebase.simtime; + +} + +void +show_stat(sregs) + struct pstate *sregs; +{ + uint32 iinst; + uint32 stime, tottime; + + if (sregs->tottime == 0) tottime = 1; else tottime = sregs->tottime; + stime = ebase.simtime - sregs->simstart; /* Total simulated time */ +#ifdef STAT + + iinst = sregs->ninst - sregs->finst - sregs->nload - sregs->nstore - + sregs->nbranch; +#endif + + printf("\n Cycles : %9d\n\r", ebase.simtime - sregs->simstart); + printf(" Instructions : %9d\n", sregs->ninst); + +#ifdef STAT + printf(" integer : %9.2f %%\n", 100.0 * (float) iinst / (float) sregs->ninst); + printf(" load : %9.2f %%\n", + 100.0 * (float) sregs->nload / (float) sregs->ninst); + printf(" store : %9.2f %%\n", + 100.0 * (float) sregs->nstore / (float) sregs->ninst); + printf(" branch : %9.2f %%\n", + 100.0 * (float) sregs->nbranch / (float) sregs->ninst); + printf(" float : %9.2f %%\n", + 100.0 * (float) sregs->finst / (float) sregs->ninst); + printf(" Integer CPI : %9.2f\n", + ((float) (stime - sregs->pwdtime - sregs->fholdt - sregs->finst)) + / + (float) (sregs->ninst - sregs->finst)); + printf(" Float CPI : %9.2f\n", + ((float) sregs->fholdt / (float) sregs->finst) + 1.0); +#endif + printf(" Overall CPI : %9.2f\n", + (float) (stime - sregs->pwdtime) / (float) sregs->ninst); + printf("\n ERC32 performance (%4.1f MHz): %5.2f MOPS (%5.2f MIPS, %5.2f MFLOPS)\n", + sregs->freq, sregs->freq * (float) sregs->ninst / (float) (stime - sregs->pwdtime), + sregs->freq * (float) (sregs->ninst - sregs->finst) / + (float) (stime - sregs->pwdtime), + sregs->freq * (float) sregs->finst / (float) (stime - sregs->pwdtime)); + printf(" Simulated ERC32 time : %5.2f ms\n", (float) (ebase.simtime - sregs->simstart) / 1000.0 / sregs->freq); + printf(" Processor utilisation : %5.2f %%\n", 100.0 * (1.0 - ((float) sregs->pwdtime / (float) stime))); + printf(" Real-time / simulator-time : 1/%.2f \n", + ((float) sregs->tottime) / ((float) (stime) / (sregs->freq * 1.0E6))); + printf(" Simulator performance : %d KIPS\n",sregs->ninst/tottime/1000); + printf(" Used time (sys + user) : %3d s\n\n", sregs->tottime); +} + + + +void +init_bpt(sregs) + struct pstate *sregs; +{ + sregs->bptnum = 0; + sregs->histlen = 0; + sregs->histind = 0; + sregs->histbuf = NULL; + sregs->tlimit = -1; +} + +static void +int_handler(sig) + int32 sig; +{ + if (sig != 2) + printf("\n\n Signal handler error (%d)\n\n", sig); + ctrl_c = 1; +} + +void +init_signals() +{ + typedef void (*PFI) (); + static PFI int_tab[2]; + + int_tab[0] = signal(SIGTERM, int_handler); + int_tab[1] = signal(SIGINT, int_handler); +} + + +extern struct disassemble_info dinfo; + +struct estate ebase; +struct evcell evbuf[EVENT_MAX]; +struct irqcell irqarr[16]; + +static int +disp_fpu(sregs) + struct pstate *sregs; +{ + + int i; + float t; + + printf("\n fsr: %08X\n\n", sregs->fsr); + +#ifdef HOST_LITTLE_ENDIAN_FLOAT + for (i = 0; i < 32; i++) + sregs->fdp[i ^ 1] = sregs->fs[i]; +#endif + + for (i = 0; i < 32; i++) { + t = sregs->fs[i]; + printf(" f%02d %08x %14e ", i, sregs->fsi[i], sregs->fs[i]); + if (!(i & 1)) + printf("%14e\n", sregs->fd[i >> 1]); + else + printf("\n"); + } + printf("\n"); + return (OK); +} + +static void +disp_regs(sregs,cwp) + struct pstate *sregs; + int cwp; +{ + + int i; + + cwp = ((cwp & 0x7) << 4); + printf("\n\t INS LOCALS OUTS GLOBALS\n"); + for (i = 0; i < 8; i++) { + printf(" %d: %08X %08X %08X %08X\n", i, + sregs->r[(cwp + i + 24) & 0x7f], + sregs->r[(cwp + i + 16) & 0x7f], sregs->r[(cwp + i + 8) & 0x7f], + sregs->g[i]); + } +} + +static void +disp_ctrl(sregs) + struct pstate *sregs; +{ + + unsigned char i[4]; + + printf("\n psr: %08X wim: %08X tbr: %08X y: %08X\n", + sregs->psr, sregs->wim, sregs->tbr, sregs->y); + sis_memory_read(sregs->pc, i, 4); + printf("\n pc: %08X = %02X%02X%02X%02X ", sregs->pc,i[0],i[1],i[2],i[3]); + print_insn_sparc(sregs->pc, &dinfo); + sis_memory_read(sregs->npc, i, 4); + printf("\n npc: %08X = %02X%02X%02X%02X ",sregs->npc,i[0],i[1],i[2],i[3]); + print_insn_sparc(sregs->npc, &dinfo); + if (sregs->err_mode) + printf("\n IU in error mode"); + printf("\n\n"); +} + +static void +disp_mem(addr, len) + uint32 addr; + uint32 len; +{ + + uint32 i; + unsigned char data[4]; + uint32 mem[4], j; + char *p; + + for (i = addr & ~3; i < ((addr + len) & ~3); i += 16) { + printf("\n %8X ", i); + for (j = 0; j < 4; j++) { + sis_memory_read((i + (j * 4)), data, 4); + printf("%02x%02x%02x%02x ", data[0],data[1],data[2],data[3]); + mem[j] = *((int *) &data); + } + printf(" "); + p = (char *) mem; + for (j = 0; j < 16; j++) { + if (isprint(p[j])) + putchar(p[j]); + else + putchar('.'); + } + } + printf("\n\n"); +} + +void +dis_mem(addr, len, info) + uint32 addr; + uint32 len; + struct disassemble_info *info; +{ + uint32 i; + unsigned char data[4]; + + for (i = addr & -3; i < ((addr & -3) + (len << 2)); i += 4) { + sis_memory_read(i, data, 4); + printf(" %08x %02x%02x%02x%02x ", i, data[0],data[1],data[2],data[3]); + print_insn_sparc(i, info); + if (i >= 0xfffffffc) break; + printf("\n"); + } +} + +int +buffer_read_memory(addr, buffer, size, info) + bfd_vma addr; + bfd_byte *buffer; + int32 size; + struct disassemble_info *info; +{ + if (size == sis_memory_read(addr, buffer, size)) + return (0); + else + return (1); +} + +void +perror_memory(status, addr, info) + int32 status; + bfd_vma addr; + struct disassemble_info *info; +{ + + printf("Could not read address 0x%08x\n", (unsigned int) addr); +} + +void +generic_print_address(addr, info) + bfd_vma addr; + struct disassemble_info *info; +{ + + printf("0x%x", (unsigned int) addr); +} + +/* Just return the given address. */ + +int +generic_symbol_at_address (addr, info) + bfd_vma addr; + struct disassemble_info * info; +{ + return 1; +} + + +/* Add event to event queue */ + +void +event(cfunc, arg, delta) + void (*cfunc) (); + int32 arg; + uint32 delta; +{ + struct evcell *ev1, *evins; + + if (ebase.freeq == NULL) { + printf("Error, too many events in event queue\n"); + return; + } + ev1 = &ebase.eq; + delta += ebase.simtime; + while ((ev1->nxt != NULL) && (ev1->nxt->time <= delta)) { + ev1 = ev1->nxt; + } + if (ev1->nxt == NULL) { + ev1->nxt = ebase.freeq; + ebase.freeq = ebase.freeq->nxt; + ev1->nxt->nxt = NULL; + } else { + evins = ebase.freeq; + ebase.freeq = ebase.freeq->nxt; + evins->nxt = ev1->nxt; + ev1->nxt = evins; + } + ev1->nxt->time = delta; + ev1->nxt->cfunc = cfunc; + ev1->nxt->arg = arg; +} + +#if 0 /* apparently not used */ +void +stop_event() +{ +} +#endif + +void +init_event() +{ + int32 i; + + ebase.eq.nxt = NULL; + ebase.freeq = evbuf; + for (i = 0; i < EVENT_MAX; i++) { + evbuf[i].nxt = &evbuf[i + 1]; + } + evbuf[EVENT_MAX - 1].nxt = NULL; +} + +void +set_int(level, callback, arg) + int32 level; + void (*callback) (); + int32 arg; +{ + irqarr[level & 0x0f].callback = callback; + irqarr[level & 0x0f].arg = arg; +} + +/* Advance simulator time */ + +void +advance_time(sregs) + struct pstate *sregs; +{ + + struct evcell *evrem; + void (*cfunc) (); + uint32 arg, endtime; + +#ifdef STAT + sregs->fholdt += sregs->fhold; + sregs->holdt += sregs->hold; + sregs->icntt += sregs->icnt; +#endif + + endtime = ebase.simtime + sregs->icnt + sregs->hold + sregs->fhold; + + while ((ebase.eq.nxt->time <= (endtime)) && (ebase.eq.nxt != NULL)) { + ebase.simtime = ebase.eq.nxt->time; + cfunc = ebase.eq.nxt->cfunc; + arg = ebase.eq.nxt->arg; + evrem = ebase.eq.nxt; + ebase.eq.nxt = ebase.eq.nxt->nxt; + evrem->nxt = ebase.freeq; + ebase.freeq = evrem; + cfunc(arg); + } + ebase.simtime = endtime; + +} + +uint32 +now() +{ + return(ebase.simtime); +} + + +/* Advance time until an external interrupt is seen */ + +int +wait_for_irq() +{ + struct evcell *evrem; + void (*cfunc) (); + int32 arg, endtime; + + if (ebase.eq.nxt == NULL) + printf("Warning: event queue empty - power-down mode not entered\n"); + endtime = ebase.simtime; + while (!ext_irl && (ebase.eq.nxt != NULL)) { + ebase.simtime = ebase.eq.nxt->time; + cfunc = ebase.eq.nxt->cfunc; + arg = ebase.eq.nxt->arg; + evrem = ebase.eq.nxt; + ebase.eq.nxt = ebase.eq.nxt->nxt; + evrem->nxt = ebase.freeq; + ebase.freeq = evrem; + cfunc(arg); + if (ctrl_c) { + printf("\bwarning: power-down mode interrupted\n"); + break; + } + } + sregs.pwdtime += ebase.simtime - endtime; + return (ebase.simtime - endtime); +} + +int +check_bpt(sregs) + struct pstate *sregs; +{ + int32 i; + + if ((sregs->bphit) || (sregs->annul)) + return (0); + for (i = 0; i < (int32) sregs->bptnum; i++) { + if (sregs->pc == sregs->bpts[i]) + return (BPT_HIT); + } + return (0); +} + +void +reset_all() +{ + init_event(); /* Clear event queue */ + init_regs(&sregs); + reset(); +#ifdef ERRINJ + errinjstart(); +#endif +} + +void +sys_reset() +{ + reset_all(); + sregs.trap = 256; /* Force fake reset trap */ +} + +void +sys_halt() +{ + sregs.trap = 257; /* Force fake halt trap */ +} + +#include "ansidecl.h" + +#ifdef ANSI_PROTOTYPES +#include <stdarg.h> +#else +#include <varargs.h> +#endif + +#include "libiberty.h" +#include "bfd.h" + +#define min(A, B) (((A) < (B)) ? (A) : (B)) +#define LOAD_ADDRESS 0 + +int +bfd_load(fname) + char *fname; +{ + asection *section; + bfd *pbfd; + const bfd_arch_info_type *arch; + + pbfd = bfd_openr(fname, 0); + + if (pbfd == NULL) { + printf("open of %s failed\n", fname); + return (-1); + } + if (!bfd_check_format(pbfd, bfd_object)) { + printf("file %s doesn't seem to be an object file\n", fname); + return (-1); + } + + arch = bfd_get_arch_info (pbfd); + if (bfd_little_endian (pbfd) || arch->mach == bfd_mach_sparc_sparclite_le) + current_target_byte_order = LITTLE_ENDIAN; + else + current_target_byte_order = BIG_ENDIAN; + if (sis_verbose) + printf("file %s is %s-endian.\n", fname, + current_target_byte_order == BIG_ENDIAN ? "big" : "little"); + + if (sis_verbose) + printf("loading %s:", fname); + for (section = pbfd->sections; section; section = section->next) { + if (bfd_get_section_flags(pbfd, section) & SEC_ALLOC) { + bfd_vma section_address; + unsigned long section_size; + const char *section_name; + + section_name = bfd_get_section_name(pbfd, section); + + section_address = bfd_get_section_vma(pbfd, section); + /* + * Adjust sections from a.out files, since they don't carry their + * addresses with. + */ + if (bfd_get_flavour(pbfd) == bfd_target_aout_flavour) { + if (strcmp (section_name, ".text") == 0) + section_address = bfd_get_start_address (pbfd); + else if (strcmp (section_name, ".data") == 0) { + /* Read the first 8 bytes of the data section. + There should be the string 'DaTa' followed by + a word containing the actual section address. */ + struct data_marker + { + char signature[4]; /* 'DaTa' */ + unsigned char sdata[4]; /* &sdata */ + } marker; + bfd_get_section_contents (pbfd, section, &marker, 0, + sizeof (marker)); + if (strncmp (marker.signature, "DaTa", 4) == 0) + { + if (current_target_byte_order == BIG_ENDIAN) + section_address = bfd_getb32 (marker.sdata); + else + section_address = bfd_getl32 (marker.sdata); + } + } + } + + section_size = bfd_section_size(pbfd, section); + + if (sis_verbose) + printf("\nsection %s at 0x%08lx (0x%lx bytes)", + section_name, section_address, section_size); + + /* Text, data or lit */ + if (bfd_get_section_flags(pbfd, section) & SEC_LOAD) { + file_ptr fptr; + + fptr = 0; + + while (section_size > 0) { + char buffer[1024]; + int count; + + count = min(section_size, 1024); + + bfd_get_section_contents(pbfd, section, buffer, fptr, count); + + sis_memory_write(section_address, buffer, count); + + section_address += count; + fptr += count; + section_size -= count; + } + } else /* BSS */ + if (sis_verbose) + printf("(not loaded)"); + } + } + if (sis_verbose) + printf("\n"); + + return(bfd_get_start_address (pbfd)); +} diff --git a/sim/erc32/help.c b/sim/erc32/help.c new file mode 100644 index 0000000..897ee7c --- /dev/null +++ b/sim/erc32/help.c @@ -0,0 +1,40 @@ +#include <stdio.h> +#include "sis.h" + +void +usage() +{ + + printf("usage: sis [-uart1 uart_device1] [-uart2 uart_device2]\n"); + printf("[-nfp] [-freq frequency] [-c batch_file] [files]\n"); + printf("[-sparclite] [-dumbio]\n"); +} + +void +gen_help() +{ + + printf("\n batch <file> execute a batch file of SIS commands\n"); + printf(" +bp <addr> add a breakpoint at <addr>\n"); + printf(" -bp <num> delete breakpoint <num>\n"); + printf(" bp print all breakpoints\n"); + printf(" cont [icnt] continue execution for [icnt] instructions\n"); + printf(" deb <level> set debug level\n"); + printf(" dis [addr] [count] disassemble [count] instructions at address [addr]\n"); + printf(" echo <string> print <string> to the simulator window\n"); +#ifdef ERRINJ + printf(" error <period> inject error traps in IU and FPU\n"); +#endif + printf(" float print the FPU registers\n"); + printf(" go <addr> [icnt] start execution at <addr> for [icnt] instructions\n"); + printf(" hist [trace_length] enable/show trace history\n"); + printf(" load <file_name> load a file into simulator memory\n"); + printf(" mem [addr] [count] display memory at [addr] for [count] bytes\n"); + printf(" quit exit the simulator\n"); + printf(" perf [reset] show/reset performance statistics\n"); + printf(" reg [w<0-7>] show integer registers (or windows, eg 're w2')\n"); + printf(" run [inst_count] reset and start execution for [icnt] instruction\n"); + printf(" step single step\n"); + printf(" tra [inst_count] trace [inst_count] instructions\n"); + printf("\n type Ctrl-C to interrupt execution\n\n"); +} diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c new file mode 100644 index 0000000..d0a781e --- /dev/null +++ b/sim/erc32/interf.c @@ -0,0 +1,526 @@ +/* + * This file is part of SIS. + * + * SIS, SPARC instruction simulator V1.6 Copyright (C) 1995 Jiri Gaisler, + * European Space Agency + * + * 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., 675 + * Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <signal.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <sys/fcntl.h> +#include "sis.h" +#include "bfd.h" +#include <dis-asm.h> +#include "sim-config.h" + +#include "remote-sim.h" + +#ifndef fprintf +extern fprintf(); +#endif + +#define PSR_CWP 0x7 + +#define VAL(x) strtol(x,(char **)NULL,0) + +extern char **buildargv(char *input); + +extern struct disassemble_info dinfo; +extern struct pstate sregs; +extern struct estate ebase; + +extern int current_target_byte_order; +extern int ctrl_c; +extern int nfp; +extern int ift; +extern int rom8; +extern int wrp; +extern int uben; +extern int sis_verbose; +extern char *sis_version; +extern struct estate ebase; +extern struct evcell evbuf[]; +extern struct irqcell irqarr[]; +extern int irqpend, ext_irl; +extern int sparclite; +extern int dumbio; +extern int sparclite_board; +extern int termsave; +extern char uart_dev1[], uart_dev2[]; + +int sis_gdb_break = 1; + +host_callback *sim_callback; + +int +run_sim(sregs, icount, dis) + struct pstate *sregs; + unsigned int icount; + int dis; +{ + int mexc, irq; + + if (sis_verbose) + (*sim_callback->printf_filtered) (sim_callback, "resuming at %x\n", + sregs->pc); + init_stdio(); + sregs->starttime = time(NULL); + irq = 0; + while (!sregs->err_mode & (icount > 0)) { + + sregs->fhold = 0; + sregs->hold = 0; + sregs->icnt = 1; + + if (sregs->psr & 0x080) + sregs->asi = 8; + else + sregs->asi = 9; + +#if 0 /* DELETE ME! for debugging purposes only */ + if (sis_verbose > 1) + if (sregs->pc == 0 || sregs->npc == 0) + printf ("bogus pc or npc\n"); +#endif + mexc = memory_read(sregs->asi, sregs->pc, &sregs->inst, + 2, &sregs->hold); +#if 1 /* DELETE ME! for debugging purposes only */ + if (sis_verbose > 2) + printf("pc %x, np %x, sp %x, fp %x, wm %x, cw %x, i %08x\n", + sregs->pc, sregs->npc, + sregs->r[(((sregs->psr & 7) << 4) + 14) & 0x7f], + sregs->r[(((sregs->psr & 7) << 4) + 30) & 0x7f], + sregs->wim, + sregs->psr & 7, + sregs->inst); +#endif + if (sregs->annul) { + sregs->annul = 0; + sregs->icnt = 1; + sregs->pc = sregs->npc; + sregs->npc = sregs->npc + 4; + } else { + if (ext_irl) irq = check_interrupts(sregs); + if (!irq) { + if (mexc) { + sregs->trap = I_ACC_EXC; + } else { + if ((sis_gdb_break) && (sregs->inst == 0x91d02001)) { + if (sis_verbose) + (*sim_callback->printf_filtered) (sim_callback, + "SW BP hit at %x\n", sregs->pc); + sim_halt(); + restore_stdio(); + clearerr(stdin); + return (BPT_HIT); + } else + dispatch_instruction(sregs); + } + icount--; + } + if (sregs->trap) { + irq = 0; + sregs->err_mode = execute_trap(sregs); + } + } + advance_time(sregs); + if (ctrl_c) { + icount = 0; + } + } + sim_halt(); + sregs->tottime += time(NULL) - sregs->starttime; + restore_stdio(); + clearerr(stdin); + if (sregs->err_mode) + error_mode(sregs->pc); + if (sregs->err_mode) + return (ERROR); + if (sregs->bphit) { + if (sis_verbose) + (*sim_callback->printf_filtered) (sim_callback, + "HW BP hit at %x\n", sregs->pc); + return (BPT_HIT); + } + if (ctrl_c) { + ctrl_c = 0; + return (CTRL_C); + } + return (TIME_OUT); +} + +void +sim_set_callbacks (ptr) + host_callback *ptr; +{ + sim_callback = ptr; +} + +void +sim_size (memsize) + int memsize; +{ +} + +SIM_DESC +sim_open (kind, callback, abfd, argv) + SIM_OPEN_KIND kind; + struct host_callback_struct *callback; + struct _bfd *abfd; + char **argv; +{ + + int argc = 0; + int stat = 1; + int freq = 0; + + sim_callback = callback; + + while (argv[argc]) + argc++; + while (stat < argc) { + if (argv[stat][0] == '-') { + if (strcmp(argv[stat], "-v") == 0) { + sis_verbose++; + } else + if (strcmp(argv[stat], "-nfp") == 0) { + nfp = 1; + } else + if (strcmp(argv[stat], "-ift") == 0) { + ift = 1; + } else + if (strcmp(argv[stat], "-sparclite") == 0) { + sparclite = 1; + } else + if (strcmp(argv[stat], "-sparclite-board") == 0) { + sparclite_board = 1; + } else + if (strcmp(argv[stat], "-dumbio") == 0) { + dumbio = 1; + } else + if (strcmp(argv[stat], "-wrp") == 0) { + wrp = 1; + } else + if (strcmp(argv[stat], "-rom8") == 0) { + rom8 = 1; + } else + if (strcmp(argv[stat], "-uben") == 0) { + uben = 1; + } else + if (strcmp(argv[stat], "-uart1") == 0) { + if ((stat + 1) < argc) + strcpy(uart_dev1, argv[++stat]); + } else + if (strcmp(argv[stat], "-uart2") == 0) { + if ((stat + 1) < argc) + strcpy(uart_dev2, argv[++stat]); + } else + if (strcmp(argv[stat], "-nogdb") == 0) { + sis_gdb_break = 0; + } else + if (strcmp(argv[stat], "-freq") == 0) { + if ((stat + 1) < argc) { + freq = VAL(argv[++stat]); + } + } else { + (*sim_callback->printf_filtered) (sim_callback, + "unknown option %s\n", + argv[stat]); + } + } else + bfd_load(argv[stat]); + stat++; + } + + if (sis_verbose) { + (*sim_callback->printf_filtered) (sim_callback, "\n SIS - SPARC instruction simulator %s\n", sis_version); + (*sim_callback->printf_filtered) (sim_callback, " Bug-reports to Jiri Gaisler ESA/ESTEC (jgais@wd.estec.esa.nl)\n"); + if (nfp) + (*sim_callback->printf_filtered) (sim_callback, "no FPU\n"); + if (sparclite) + (*sim_callback->printf_filtered) (sim_callback, "simulating Sparclite\n"); + if (dumbio) + (*sim_callback->printf_filtered) (sim_callback, "dumb IO (no input, dumb output)\n"); + if (sis_gdb_break == 0) + (*sim_callback->printf_filtered) (sim_callback, "disabling GDB trap handling for breakpoints\n"); + if (freq) + (*sim_callback->printf_filtered) (sim_callback, " ERC32 freq %d Mhz\n", freq); + } + + sregs.freq = freq ? freq : 15; + termsave = fcntl(0, F_GETFL, 0); + INIT_DISASSEMBLE_INFO(dinfo, stdout,(fprintf_ftype)fprintf); + dinfo.endian = BFD_ENDIAN_BIG; + reset_all(); + ebase.simtime = 0; + init_sim(); + init_bpt(&sregs); + reset_stat(&sregs); + + /* Fudge our descriptor for now. */ + return (SIM_DESC) 1; +} + +void +sim_close(sd, quitting) + SIM_DESC sd; + int quitting; +{ + + exit_sim(); + fcntl(0, F_SETFL, termsave); + +}; + +SIM_RC +sim_load(sd, prog, abfd, from_tty) + SIM_DESC sd; + char *prog; + bfd *abfd; + int from_tty; +{ + bfd_load (prog); + return SIM_RC_OK; +} + +SIM_RC +sim_create_inferior(sd, abfd, argv, env) + SIM_DESC sd; + struct _bfd *abfd; + char **argv; + char **env; +{ + bfd_vma start_address = 0; + if (abfd != NULL) + start_address = bfd_get_start_address (abfd); + + ebase.simtime = 0; + reset_all(); + reset_stat(&sregs); + sregs.pc = start_address & ~3; + sregs.npc = sregs.pc + 4; + return SIM_RC_OK; +} + +int +sim_store_register(sd, regno, value, length) + SIM_DESC sd; + int regno; + unsigned char *value; + int length; +{ + /* FIXME: Review the computation of regval. */ + int regval; + if (current_target_byte_order == BIG_ENDIAN) + regval = (value[0] << 24) | (value[1] << 16) + | (value[2] << 8) | value[3]; + else + regval = (value[3] << 24) | (value[2] << 16) + | (value[1] << 8) | value[0]; + set_regi(&sregs, regno, regval); + return -1; +} + + +int +sim_fetch_register(sd, regno, buf, length) + SIM_DESC sd; + int regno; + unsigned char *buf; + int length; +{ + get_regi(&sregs, regno, buf); + return -1; +} + +int +sim_write(sd, mem, buf, length) + SIM_DESC sd; + SIM_ADDR mem; + unsigned char *buf; + int length; +{ + return (sis_memory_write(mem, buf, length)); +} + +int +sim_read(sd, mem, buf, length) + SIM_DESC sd; + SIM_ADDR mem; + unsigned char *buf; + int length; +{ + return (sis_memory_read(mem, buf, length)); +} + +void +sim_info(sd, verbose) + SIM_DESC sd; + int verbose; +{ + show_stat(&sregs); +} + +int simstat = OK; + +void +sim_stop_reason(sd, reason, sigrc) + SIM_DESC sd; + enum sim_stop * reason; + int *sigrc; +{ + + switch (simstat) { + case CTRL_C: + *reason = sim_stopped; + *sigrc = SIGINT; + break; + case OK: + case TIME_OUT: + case BPT_HIT: + *reason = sim_stopped; +#ifdef _WIN32 +#define SIGTRAP 5 +#endif + *sigrc = SIGTRAP; + break; + case ERROR: + *sigrc = 0; + *reason = sim_exited; + } + ctrl_c = 0; + simstat = OK; +} + +/* Flush all register windows out to the stack. Starting after the invalid + window, flush all windows up to, and including the current window. This + allows GDB to do backtraces and look at local variables for frames that + are still in the register windows. Note that strictly speaking, this + behavior is *wrong* for several reasons. First, it doesn't use the window + overflow handlers. It therefore assumes standard frame layouts and window + handling policies. Second, it changes system state behind the back of the + target program. I expect this to mainly pose problems when debugging trap + handlers. +*/ + +static void +flush_windows () +{ + int invwin; + int cwp; + int win; + int ws; + + /* Keep current window handy */ + + cwp = sregs.psr & PSR_CWP; + + /* Calculate the invalid window from the wim. */ + + for (invwin = 0; invwin <= PSR_CWP; invwin++) + if ((sregs.wim >> invwin) & 1) + break; + + /* Start saving with the window after the invalid window. */ + + invwin = (invwin - 1) & PSR_CWP; + + for (win = invwin; ; win = (win - 1) & PSR_CWP) + { + uint32 sp; + int i; + + sp = sregs.r[(win * 16 + 14) & 0x7f]; +#if 1 + if (sis_verbose > 2) { + uint32 fp = sregs.r[(win * 16 + 30) & 0x7f]; + printf("flush_window: win %d, sp %x, fp %x\n", win, sp, fp); + } +#endif + + for (i = 0; i < 16; i++) + memory_write (11, sp + 4 * i, &sregs.r[(win * 16 + 16 + i) & 0x7f], 2, + &ws); + + if (win == cwp) + break; + } +} + +void +sim_resume(SIM_DESC sd, int step, int siggnal) +{ + simstat = run_sim(&sregs, -1, 0); + + if (sis_gdb_break) flush_windows (); +} + +int +sim_trace (sd) + SIM_DESC sd; +{ + /* FIXME: unfinished */ + sim_resume (sd, 0, 0); + return 1; +} + +void +sim_do_command(sd, cmd) + SIM_DESC sd; + char *cmd; +{ + exec_cmd(&sregs, cmd); +} + +#if 0 /* FIXME: These shouldn't exist. */ + +int +sim_insert_breakpoint(int addr) +{ + if (sregs.bptnum < BPT_MAX) { + sregs.bpts[sregs.bptnum] = addr & ~0x3; + sregs.bptnum++; + if (sis_verbose) + (*sim_callback->printf_filtered) (sim_callback, "inserted HW BP at %x\n", addr); + return 0; + } else + return 1; +} + +int +sim_remove_breakpoint(int addr) +{ + int i = 0; + + while ((i < sregs.bptnum) && (sregs.bpts[i] != addr)) + i++; + if (addr == sregs.bpts[i]) { + for (; i < sregs.bptnum - 1; i++) + sregs.bpts[i] = sregs.bpts[i + 1]; + sregs.bptnum -= 1; + if (sis_verbose) + (*sim_callback->printf_filtered) (sim_callback, "removed HW BP at %x\n", addr); + return 0; + } + return 1; +} + +#endif diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c new file mode 100644 index 0000000..7567881 --- /dev/null +++ b/sim/erc32/sis.c @@ -0,0 +1,310 @@ +/* + * This file is part of SIS. + * + * SIS, SPARC instruction simulator. Copyright (C) 1995 Jiri Gaisler, European + * Space Agency + * + * 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., 675 + * Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include "config.h" +#include <signal.h> +#include <string.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <stdio.h> +#include <time.h> +#include <sys/fcntl.h> +#include "sis.h" +#include <dis-asm.h> +#include "sim-config.h" + +#ifndef fprintf +extern fprintf(); +#endif + +#define VAL(x) strtol(x,(char **)NULL,0) + +/* Structures and functions from readline library */ + +typedef struct { + char *line; + char *data; +} HIST_ENTRY; + +extern char * readline PARAMS ((char *prompt)); +extern void using_history PARAMS ((void)); +extern void add_history PARAMS ((char *string)); +extern HIST_ENTRY *remove_history PARAMS ((int which)); + + + +/* Command history buffer length - MUST be binary */ +#define HIST_LEN 64 + +extern struct disassemble_info dinfo; +extern struct pstate sregs; +extern struct estate ebase; + +extern int ctrl_c; +extern int nfp; +extern int ift; +extern int wrp; +extern int rom8; +extern int uben; +extern int sis_verbose; +extern char *sis_version; +extern struct estate ebase; +extern struct evcell evbuf[]; +extern struct irqcell irqarr[]; +extern int irqpend, ext_irl; +extern int termsave; +extern int sparclite; +extern int dumbio; +extern char uart_dev1[]; +extern char uart_dev2[]; +extern uint32 last_load_addr; + +#ifdef ERA +extern int era; +#endif + +int +run_sim(sregs, icount, dis) + struct pstate *sregs; + unsigned int icount; + int dis; +{ + int irq, mexc, deb, asi; + + sregs->starttime = time(NULL); + init_stdio(); + if (sregs->err_mode) icount = 0; + deb = dis || sregs->histlen || sregs->bptnum; + irq = 0; + while (icount > 0) { + + if (sregs->psr & 0x080) + asi = 9; + else + asi = 8; + mexc = memory_read(asi, sregs->pc, &sregs->inst, 2, &sregs->hold); + sregs->icnt = 1; + if (sregs->annul) { + sregs->annul = 0; + sregs->pc = sregs->npc; + sregs->npc = sregs->npc + 4; + } else { + sregs->fhold = 0; + if (ext_irl) irq = check_interrupts(sregs); + if (!irq) { + if (mexc) { + sregs->trap = I_ACC_EXC; + } else { + if (deb) { + if ((sregs->bphit = check_bpt(sregs)) != 0) { + restore_stdio(); + return (BPT_HIT); + } + if (sregs->histlen) { + sregs->histbuf[sregs->histind].addr = sregs->pc; + sregs->histbuf[sregs->histind].time = ebase.simtime; + sregs->histind++; + if (sregs->histind >= sregs->histlen) + sregs->histind = 0; + } + if (dis) { + printf(" %8u ", ebase.simtime); + dis_mem(sregs->pc, 1, &dinfo); + } + } + dispatch_instruction(sregs); + icount--; + } + } + if (sregs->trap) { + irq = 0; + sregs->err_mode = execute_trap(sregs); + if (sregs->err_mode) { + error_mode(sregs->pc); + icount = 0; + } + } + } + advance_time(sregs); + if (ctrl_c || (sregs->tlimit <= ebase.simtime)) { + icount = 0; + if (sregs->tlimit <= ebase.simtime) sregs->tlimit = -1; + } + } + sregs->tottime += time(NULL) - sregs->starttime; + restore_stdio(); + if (sregs->err_mode) + return (ERROR); + if (ctrl_c) { + ctrl_c = 0; + return (CTRL_C); + } + return (TIME_OUT); +} + +int +main(argc, argv) + int argc; + char **argv; +{ + + int cont = 1; + int stat = 1; + int freq = 14; + int copt = 0; + + char *cfile, *bacmd; + char *cmdq[HIST_LEN]; + int cmdi = 0; + int i; + + cfile = 0; + for (i = 0; i < 64; i++) + cmdq[i] = 0; + printf("\n SIS - SPARC intruction simulator %s, copyright Jiri Gaisler 1995\n", sis_version); + printf(" Bug-reports to jgais@wd.estec.esa.nl\n\n"); + while (stat < argc) { + if (argv[stat][0] == '-') { + if (strcmp(argv[stat], "-v") == 0) { + sis_verbose = 1; + } else if (strcmp(argv[stat], "-c") == 0) { + if ((stat + 1) < argc) { + copt = 1; + cfile = argv[++stat]; + } + } else if (strcmp(argv[stat], "-nfp") == 0) + nfp = 1; + else if (strcmp(argv[stat], "-ift") == 0) + ift = 1; + else if (strcmp(argv[stat], "-wrp") == 0) + wrp = 1; + else if (strcmp(argv[stat], "-rom8") == 0) + rom8 = 1; + else if (strcmp(argv[stat], "-uben") == 0) + uben = 1; + else if (strcmp(argv[stat], "-uart1") == 0) { + if ((stat + 1) < argc) + strcpy(uart_dev1, argv[++stat]); + } else if (strcmp(argv[stat], "-uart2") == 0) { + if ((stat + 1) < argc) + strcpy(uart_dev2, argv[++stat]); + } else if (strcmp(argv[stat], "-freq") == 0) { + if ((stat + 1) < argc) + freq = VAL(argv[++stat]); + } else if (strcmp(argv[stat], "-sparclite") == 0) { + sparclite = 1; +#ifdef ERA + } else if (strcmp(argv[stat], "-era") == 0) { + era = 1; +#endif + } else if (strcmp(argv[stat], "-dumbio") == 0) { + dumbio = 1; + } else { + printf("unknown option %s\n", argv[stat]); + usage(); + exit(1); + } + } else { + last_load_addr = bfd_load(argv[stat]); + } + stat++; + } + if (nfp) + printf("FPU disabled\n"); +#ifdef ERA + if (era) + printf("ERA ECC emulation enabled\n"); +#endif + sregs.freq = freq; + + INIT_DISASSEMBLE_INFO(dinfo, stdout, (fprintf_ftype) fprintf); + dinfo.endian = BFD_ENDIAN_BIG; + + termsave = fcntl(0, F_GETFL, 0); + using_history(); + init_signals(); + ebase.simtime = 0; + reset_all(); + init_bpt(&sregs); + init_sim(); +#ifdef STAT + reset_stat(&sregs); +#endif + + if (copt) { + bacmd = (char *) malloc(256); + strcpy(bacmd, "batch "); + strcat(bacmd, cfile); + exec_cmd(&sregs, bacmd); + } + while (cont) { + + if (cmdq[cmdi] != 0) { +#if 0 + remove_history(cmdq[cmdi]); +#else + remove_history(cmdi); +#endif + free(cmdq[cmdi]); + cmdq[cmdi] = 0; + } + cmdq[cmdi] = readline("sis> "); + if (cmdq[cmdi] && *cmdq[cmdi]) + add_history(cmdq[cmdi]); + if (cmdq[cmdi]) + stat = exec_cmd(&sregs, cmdq[cmdi]); + else { + puts("\n"); + exit(0); + } + switch (stat) { + case OK: + break; + case CTRL_C: + printf("\b\bInterrupt!\n"); + case TIME_OUT: + printf(" Stopped at time %d (%.3f ms)\n", ebase.simtime, + ((double) ebase.simtime / (double) sregs.freq) / 1000.0); + break; + case BPT_HIT: + printf("breakpoint at 0x%08x reached\n", sregs.pc); + sregs.bphit = 1; + break; + case ERROR: + printf("IU in error mode (%d)\n", sregs.trap); + stat = 0; + printf(" %8d ", ebase.simtime); + dis_mem(sregs.pc, 1, &dinfo); + break; + default: + break; + } + ctrl_c = 0; + stat = OK; + + cmdi = (cmdi + 1) & (HIST_LEN - 1); + + } + return 0; +} + diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h new file mode 100644 index 0000000..2a895c0 --- /dev/null +++ b/sim/erc32/sis.h @@ -0,0 +1,217 @@ +/* + * This file is part of SIS. + * + * ERC32SIM, SPARC instruction simulator. Copyright (C) 1995 Jiri Gaisler, + * European Space Agency + * + * 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., 675 + * Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include "ansidecl.h" +#include "callback.h" +#include "remote-sim.h" + +#include "end.h" + +#define I_ACC_EXC 1 + +/* Maximum events in event queue */ +#define EVENT_MAX 256 + +/* Maximum # of floating point queue */ +#define FPUQN 1 + +/* Maximum # of breakpoints */ +#define BPT_MAX 256 + +struct histype { + unsigned addr; + unsigned time; +}; + +/* type definitions */ + +typedef short int int16; /* 16-bit signed int */ +typedef unsigned short int uint16; /* 16-bit unsigned int */ +typedef int int32; /* 32-bit signed int */ +typedef unsigned int uint32; /* 32-bit unsigned int */ +typedef float float32; /* 32-bit float */ +typedef double float64; /* 64-bit float */ + +/* FIXME: what about host compilers that don't support 64-bit ints? */ +typedef unsigned long long uint64; /* 64-bit unsigned int */ +typedef long long int64; /* 64-bit signed int */ + +struct pstate { + + float64 fd[16]; /* FPU registers */ +#ifdef HOST_LITTLE_ENDIAN_FLOAT + float32 fs[32]; + float32 *fdp; +#else + float32 *fs; +#endif + int32 *fsi; + uint32 fsr; + int32 fpstate; + uint32 fpq[FPUQN * 2]; + uint32 fpqn; + uint32 ftime; + uint32 flrd; + uint32 frd; + uint32 frs1; + uint32 frs2; + uint32 fpu_pres; /* FPU present (0 = No, 1 = Yes) */ + + uint32 psr; /* IU registers */ + uint32 tbr; + uint32 wim; + uint32 g[8]; + uint32 r[128]; + uint32 y; + uint32 asr17; /* Single vector trapping */ + uint32 pc, npc; + + + uint32 trap; /* Current trap type */ + uint32 annul; /* Instruction annul */ + uint32 data; /* Loaded data */ + uint32 inst; /* Current instruction */ + uint32 asi; /* Current ASI */ + uint32 err_mode; /* IU error mode */ + uint32 breakpoint; + uint32 bptnum; + uint32 bphit; + uint32 bpts[BPT_MAX]; /* Breakpoints */ + + uint32 ltime; /* Load interlock time */ + uint32 hold; /* IU hold cycles in current inst */ + uint32 fhold; /* FPU hold cycles in current inst */ + uint32 icnt; /* Instruction cycles in curr inst */ + + uint32 histlen; /* Trace history management */ + uint32 histind; + struct histype *histbuf; + float32 freq; /* Simulated processor frequency */ + + + uint32 tottime; + uint32 ninst; + uint32 fholdt; + uint32 holdt; + uint32 icntt; + uint32 finst; + uint32 simstart; + uint32 starttime; + uint32 tlimit; /* Simulation time limit */ + uint32 pwdtime; /* Cycles in power-down mode */ + uint32 nstore; /* Number of load instructions */ + uint32 nload; /* Number of store instructions */ + uint32 nannul; /* Number of annuled instructions */ + uint32 nbranch; /* Number of branch instructions */ + uint32 ildreg; /* Destination of last load instruction */ + uint32 ildtime; /* Last time point for load dependency */ + + int rett_err; /* IU in jmpl/restore error state (Rev.0) */ + int jmpltime; +}; + +struct evcell { + void (*cfunc) (); + int32 arg; + uint32 time; + struct evcell *nxt; +}; + +struct estate { + struct evcell eq; + struct evcell *freeq; + uint32 simtime; +}; + +struct irqcell { + void (*callback) (); + int32 arg; +}; + + +#define OK 0 +#define TIME_OUT 1 +#define BPT_HIT 2 +#define ERROR 3 +#define CTRL_C 4 + +/* Prototypes */ + +/* erc32.c */ +extern void init_sim PARAMS ((void)); +extern void reset PARAMS ((void)); +extern void error_mode PARAMS ((uint32 pc)); +extern void sim_halt PARAMS ((void)); +extern void exit_sim PARAMS ((void)); +extern void init_stdio PARAMS ((void)); +extern void restore_stdio PARAMS ((void)); +extern int memory_read PARAMS ((int32 asi, uint32 addr, uint32 *data, + int32 sz, int32 *ws)); +extern int memory_write PARAMS ((int32 asi, uint32 addr, uint32 *data, + int32 sz, int32 *ws)); +extern int sis_memory_write PARAMS ((uint32 addr, char *data, + uint32 length)); +extern int sis_memory_read PARAMS ((uint32 addr, char *data, + uint32 length)); + +/* func.c */ +extern void set_regi PARAMS ((struct pstate *sregs, int32 reg, + uint32 rval)); +extern void get_regi PARAMS ((struct pstate *sregs, int32 reg, char *buf)); +extern int exec_cmd PARAMS ((struct pstate *sregs, char *cmd)); +extern void reset_stat PARAMS ((struct pstate *sregs)); +extern void show_stat PARAMS ((struct pstate *sregs)); +extern void init_bpt PARAMS ((struct pstate *sregs)); +extern void init_signals PARAMS ((void)); + +struct disassemble_info; +extern void dis_mem PARAMS ((uint32 addr, uint32 len, + struct disassemble_info *info)); +extern void event PARAMS ((void (*cfunc) (), int32 arg, uint32 delta)); +extern void set_int PARAMS ((int32 level, void (*callback) (), int32 arg)); +extern void advance_time PARAMS ((struct pstate *sregs)); +extern uint32 now PARAMS ((void)); +extern int wait_for_irq PARAMS ((void)); +extern int check_bpt PARAMS ((struct pstate *sregs)); +extern void reset_all PARAMS ((void)); +extern void sys_reset PARAMS ((void)); +extern void sys_halt PARAMS ((void)); +extern int bfd_load PARAMS ((char *fname)); + +/* exec.c */ +extern int dispatch_instruction PARAMS ((struct pstate *sregs)); +extern int execute_trap PARAMS ((struct pstate *sregs)); +extern int check_interrupts PARAMS ((struct pstate *sregs)); +extern void init_regs PARAMS ((struct pstate *sregs)); + +/* interf.c */ +extern int run_sim PARAMS ((struct pstate *sregs, + unsigned int icount, int dis)); + +/* float.c */ +extern int get_accex PARAMS ((void)); +extern void clear_accex PARAMS ((void)); +extern void set_fsr PARAMS ((uint32 fsr)); + +/* help.c */ +extern void usage PARAMS ((void)); +extern void gen_help PARAMS ((void)); diff --git a/sim/erc32/startsim b/sim/erc32/startsim new file mode 100644 index 0000000..1b9b41c --- /dev/null +++ b/sim/erc32/startsim @@ -0,0 +1,4 @@ +# +xterm -e sis $* & +xterm -e tip /dev/ttypc & + |