aboutsummaryrefslogtreecommitdiff
path: root/sim/mips
diff options
context:
space:
mode:
authorStan Shebs <shebs@codesourcery.com>1999-04-16 01:35:26 +0000
committerStan Shebs <shebs@codesourcery.com>1999-04-16 01:35:26 +0000
commitc906108c21474dfb4ed285bcc0ac6fe02cd400cc (patch)
treea0015aa5cedc19ccbab307251353a41722a3ae13 /sim/mips
parentcd946cff9ede3f30935803403f06f6ed30cad136 (diff)
downloadgdb-c906108c21474dfb4ed285bcc0ac6fe02cd400cc.zip
gdb-c906108c21474dfb4ed285bcc0ac6fe02cd400cc.tar.gz
gdb-c906108c21474dfb4ed285bcc0ac6fe02cd400cc.tar.bz2
Initial creation of sourceware repositorygdb-4_18-branchpoint
Diffstat (limited to 'sim/mips')
-rw-r--r--sim/mips/ChangeLog2046
-rw-r--r--sim/mips/Makefile.in293
-rw-r--r--sim/mips/acconfig.h15
-rw-r--r--sim/mips/config.in174
-rwxr-xr-xsim/mips/configure4890
-rw-r--r--sim/mips/configure.in170
-rw-r--r--sim/mips/dv-tx3904cpu.c246
-rw-r--r--sim/mips/dv-tx3904irc.c413
-rw-r--r--sim/mips/dv-tx3904sio.c621
-rw-r--r--sim/mips/dv-tx3904tmr.c698
-rw-r--r--sim/mips/interp.c3228
-rw-r--r--sim/mips/m16.dc25
-rw-r--r--sim/mips/m16.igen1236
-rw-r--r--sim/mips/m16run.c74
-rw-r--r--sim/mips/mips.dc16
-rw-r--r--sim/mips/mips.igen3895
-rw-r--r--sim/mips/sim-main.c579
-rw-r--r--sim/mips/sim-main.h785
-rw-r--r--sim/mips/tconfig.in31
-rw-r--r--sim/mips/tx.igen41
-rw-r--r--sim/mips/vr.igen78
21 files changed, 19554 insertions, 0 deletions
diff --git a/sim/mips/ChangeLog b/sim/mips/ChangeLog
new file mode 100644
index 0000000..bb8ac40
--- /dev/null
+++ b/sim/mips/ChangeLog
@@ -0,0 +1,2046 @@
+1999-02-05 Frank Ch. Eigler <fche@cygnus.com>
+
+ * dv-tx3904sio.c (tx3904sio_tickle): After a polled I/O from the
+ CPU, start periodic background I/O polls.
+ (tx3904sio_poll): New function: periodic I/O poller.
+
+1998-12-30 Frank Ch. Eigler <fche@cygnus.com>
+
+ * mips.igen (BREAK): Call signal_exception instead of sim_engine_halt.
+
+Tue Dec 29 16:03:53 1998 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * configure.in, configure (mips64vr5*-*-*): Added missing ;; in
+ case statement.
+
+1998-12-29 Frank Ch. Eigler <fche@cygnus.com>
+
+ * interp.c (sim_open): Allocate jm3904 memory in smaller chunks.
+ (load_word): Call SIM_CORE_SIGNAL hook on error.
+ (signal_exception): Call SIM_CPU_EXCEPTION_TRIGGER hook before
+ starting. For exception dispatching, pass PC instead of NULL_CIA.
+ (decode_coproc): Use COP0_BADVADDR to store faulting address.
+ * sim-main.h (COP0_BADVADDR): Define.
+ (SIM_CORE_SIGNAL): Define hook to call mips_core_signal.
+ (SIM_CPU_EXCEPTION*): Define hooks to call mips_cpu_exception*().
+ (_sim_cpu): Add exc_* fields to store register value snapshots.
+ * mips.igen (*): Replace memory-related SignalException* calls
+ with references to SIM_CORE_SIGNAL hook.
+
+ * dv-tx3904irc.c (tx3904irc_port_event): printf format warning
+ fix.
+ * sim-main.c (*): Minor warning cleanups.
+
+1998-12-24 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * m16.igen (DADDIU5): Correct type-o.
+
+Mon Dec 21 10:34:48 1998 Andrew Cagney <cagney@chook>
+
+ * mips.igen (do_ddiv, do_ddivu): Pacify GCC. Update hi/lo via tmp
+ variables.
+
+Wed Dec 16 18:20:28 1998 Andrew Cagney <cagney@chook>
+
+ * Makefile.in (SIM_EXTRA_CFLAGS): No longer need to add .../newlib
+ to include path.
+ (interp.o): Add dependency on itable.h
+ (oengine.c, gencode): Delete remaining references.
+ (BUILT_SRC_FROM_GEN): Clean up.
+
+1998-12-16 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * vr4run.c: New.
+ * Makefile.in (SIM_HACK_OBJ,HACK_OBJS,HACK_GEN_SRCS,libhack.a,
+ tmp-hack,tmp-m32-hack,tmp-m16-hack,tmp-itable-hack,
+ tmp-run-hack) : New.
+ * m16.igen (LD,DADDIU,DADDUI5,DADJSP,DADDIUSP,DADDI,DADDU,DSUBU,
+ DSLL,DSRL,DSRA,DSLLV,DSRAV,DMULT,DMULTU,DDIV,DDIVU,JALX32,JALX):
+ Drop the "64" qualifier to get the HACK generator working.
+ Use IMMEDIATE rather than IMMED. Use SHAMT rather than SHIFT.
+ * mips.igen (do_daddiu,do_ddiv,do_divu): Remove the 64-only
+ qualifier to get the hack generator working.
+ (do_dsll,do_dsllv,do_dsra,do_dsrl,do_dsrlv): New.
+ (DSLL): Use do_dsll.
+ (DSLLV): Use do_dsllv.
+ (DSRA): Use do_dsra.
+ (DSRL): Use do_dsrl.
+ (DSRLV): Use do_dsrlv.
+ (BC1): Move *vr4100 to get the HACK generator working.
+ (CxC1, DMxC1, MxC1,MACCU,MACCHI,MACCHIU): Rename to
+ get the HACK generator working.
+ (MACC) Rename to get the HACK generator working.
+ (DMACC,MACCS,DMACCS): Add the 64.
+
+1998-12-12 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * mips.igen (BC1): Renamed to BC1a and BC1b to avoid conflicts.
+ * sim-main.h (SizeFGR): Handle TARGET_ENABLE_FR.
+
+1998-12-11 Gavin Romig-Koch <gavin@cygnus.com>
+
+ * mips/interp.c (DEBUG): Cleanups.
+
+1998-12-10 Frank Ch. Eigler <fche@cygnus.com>
+
+ * dv-tx3904sio.c (tx3904sio_io_read_buffer): Endianness fixes.
+ (tx3904sio_tickle): fflush after a stdout character output.
+
+1998-12-03 Frank Ch. Eigler <fche@cygnus.com>
+
+ * interp.c (sim_close): Uninstall modules.
+
+Wed Nov 25 13:41:03 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * sim-main.h, interp.c (sim_monitor): Change to global
+ function.
+
+Wed Nov 25 17:33:24 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (vr4100): Only include vr4100 instructions in
+ simulator.
+ * configure: Re-generate.
+ * m16.igen (*): Tag all mips16 instructions as also being vr4100.
+
+Mon Nov 23 18:20:36 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (SIM_CFLAGS): Do not define WITH_IGEN.
+ * sim-main.h, sim-main.c, interp.c: Delete #if WITH_IGEN keeping
+ true alternative.
+
+ * configure.in (sim_default_gen, sim_use_gen): Replace with
+ sim_gen.
+ (--enable-sim-igen): Delete config option. Always using IGEN.
+ * configure: Re-generate.
+
+ * Makefile.in (gencode): Kill, kill, kill.
+ * gencode.c: Ditto.
+
+Mon Nov 23 18:07:36 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in: Configure mips64vr4100-elf nee mips64vr41* as a 64
+ bit mips16 igen simulator.
+ * configure: Re-generate.
+
+ * mips.igen (check_div_hilo, check_mult_hilo, check_mf_hilo): Mark
+ as part of vr4100 ISA.
+ * vr.igen: Mark all instructions as 64 bit only.
+
+Mon Nov 23 17:07:37 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (get_cell, sim_monitor, fetch_str, CoProcPresent):
+ Pacify GCC.
+
+Mon Nov 23 13:23:40 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in: Configure mips-lsi-elf nee mips*lsi* as a
+ mipsIII/mips16 igen simulator. Fix sim_gen VS sim_igen typos.
+ * configure: Re-generate.
+
+ * m16.igen (BREAK): Define breakpoint instruction.
+ (JALX32): Mark instruction as mips16 and not r3900.
+ * mips.igen (C.cond.fmt): Fix typo in instruction format.
+
+ * sim-main.h (PENDING_FILL): Wrap C statements in do/while.
+
+Sat Nov 7 09:54:38 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gencode.c (build_instruction - BREAK): For MIPS16, handle BREAK
+ insn as a debug breakpoint.
+
+ * sim-main.h (PENDING_SLOT_BIT): Fix, was incorrectly defined as
+ pending.slot_size.
+ (PENDING_SCHED): Clean up trace statement.
+ (PENDING_SCHED): Increment PENDING_IN and PENDING_TOTAL.
+ (PENDING_FILL): Delay write by only one cycle.
+ (PENDING_FILL): For FSRs, write fmt_uninterpreted to FPR_STATE.
+
+ * sim-main.c (pending_tick): Clean up trace statements. Add trace
+ of pending writes.
+ (pending_tick): Fix sizes in switch statements, 4 & 8 instead of
+ 32 & 64.
+ (pending_tick): Move incrementing of index to FOR statement.
+ (pending_tick): Only update PENDING_OUT after a write has occured.
+
+ * configure.in: Add explicit mips-lsi-* target. Use gencode to
+ build simulator.
+ * configure: Re-generate.
+
+ * interp.c (sim_engine_run OLD): Delete explicit call to
+ PENDING_TICK. Now called via ENGINE_ISSUE_PREFIX_HOOK.
+
+Sat Oct 30 09:49:10 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * dv-tx3904cpu.c (deliver_tx3904cpu_interrupt): Add dummy
+ interrupt level number to match changed SignalExceptionInterrupt
+ macro.
+
+Fri Oct 9 18:02:25 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * interp.c: #include "itable.h" if WITH_IGEN.
+ (get_insn_name): New function.
+ (sim_open): Initialize CPU_INSN_NAME,CPU_MAX_INSNS.
+ * sim-main.h (MAX_INSNS,INSN_NAME): Delete.
+
+Mon Sep 14 12:36:44 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * configure: Rebuilt to inhale new common/aclocal.m4.
+
+Tue Sep 1 15:39:18 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * dv-tx3904sio.c: Include sim-assert.h.
+
+Tue Aug 25 12:49:46 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * dv-tx3904sio.c: New file: tx3904 serial I/O module.
+ * configure.in: Add dv-tx3904sio, dv-sockser for tx39 target.
+ Reorganize target-specific sim-hardware checks.
+ * configure: rebuilt.
+ * interp.c (sim_open): For tx39 target boards, set
+ OPERATING_ENVIRONMENT, add tx3904sio devices.
+ * tconfig.in: For tx39 target, set SIM_HANDLES_LMA for loading
+ ROM executables. Install dv-sockser into sim-modules list.
+
+ * dv-tx3904irc.c: Compiler warning clean-up.
+ * dv-tx3904tmr.c: Compiler warning clean-up. Remove particularly
+ frequent hw-trace messages.
+
+Fri Jul 31 18:14:16 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * vr.igen (MulAcc): Identify as a vr4100 specific function.
+
+Sat Jul 25 16:03:14 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (IGEN_INCLUDE): Add vr.igen.
+
+ * vr.igen: New file.
+ (MAC/MADD16, DMAC/DMADD16): Implement using code from gencode.c.
+ * mips.igen: Define vr4100 model. Include vr.igen.
+Mon Jun 29 09:21:07 1998 Gavin Koch <gavin@cygnus.com>
+
+ * mips.igen (check_mf_hilo): Correct check.
+
+Wed Jun 17 12:20:49 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * sim-main.h (interrupt_event): Add prototype.
+
+ * dv-tx3904tmr.c (tx3904tmr_io_write_buffer): Delete unused
+ register_ptr, register_value.
+ (deliver_tx3904tmr_tick): Fix types passed to printf fmt.
+
+ * sim-main.h (tracefh): Make extern.
+
+Tue Jun 16 14:39:00 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * dv-tx3904tmr.c: Deschedule timer event after dispatching.
+ Reduce unnecessarily high timer event frequency.
+ * dv-tx3904cpu.c: Ditto for interrupt event.
+
+Wed Jun 10 13:22:32 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * interp.c (decode_coproc): For TX39, add stub COP0 register #7,
+ to allay warnings.
+ (interrupt_event): Made non-static.
+
+ * dv-tx3904tmr.c (deliver_tx3904tmr_tick): Correct accidental
+ interchange of configuration values for external vs. internal
+ clock dividers.
+
+Tue Jun 9 12:46:24 1998 Ian Carmichael <iancarm@cygnus.com>
+
+ * mips.igen (BREAK): Moved code to here for
+ simulator-reserved break instructions.
+ * gencode.c (build_instruction): Ditto.
+ * interp.c (signal_exception): Code moved from here. Non-
+ reserved instructions now use exception vector, rather
+ than halting sim.
+ * sim-main.h: Moved magic constants to here.
+
+Tue Jun 9 12:29:50 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * dv-tx3904cpu.c (deliver_*_interrupt,*_port_event): Set the CAUSE
+ register upon non-zero interrupt event level, clear upon zero
+ event value.
+ * dv-tx3904irc.c (*_port_event): Handle deactivated interrupt signal
+ by passing zero event value.
+ (*_io_{read,write}_buffer): Endianness fixes.
+ * dv-tx3904tmr.c (*_io_{read,write}_buffer): Endianness fixes.
+ (deliver_*_tick): Reduce sim event interval to 75% of count interval.
+
+ * interp.c (sim_open): Added jmr3904pal board type that adds PAL-based
+ serial I/O and timer module at base address 0xFFFF0000.
+
+Tue Jun 9 11:52:29 1998 Gavin Koch <gavin@cygnus.com>
+
+ * mips.igen (SWC1) : Correct the handling of ReverseEndian
+ and BigEndianCPU.
+
+Tue Jun 9 11:40:57 1998 Gavin Koch <gavin@cygnus.com>
+
+ * configure.in (mips_fpu_bitsize) : Set this correctly for 32-bit mips
+ parts.
+ * configure: Update.
+
+Thu Jun 4 15:37:33 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * dv-tx3904tmr.c: New file - implements tx3904 timer.
+ * dv-tx3904{irc,cpu}.c: Mild reformatting.
+ * configure.in: Include tx3904tmr in hw_device list.
+ * configure: Rebuilt.
+ * interp.c (sim_open): Instantiate three timer instances.
+ Fix address typo of tx3904irc instance.
+
+Tue Jun 2 15:48:02 1998 Ian Carmichael <iancarm@cygnus.com>
+
+ * interp.c (signal_exception): SystemCall exception now uses
+ the exception vector.
+
+Mon Jun 1 18:18:26 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * interp.c (decode_coproc): For TX39, add stub COP0 register #3,
+ to allay warnings.
+
+Fri May 29 11:40:39 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (sim_igen_filter): Match mips*tx39 not mipst*tx39.
+
+Mon May 25 20:47:45 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * dv-tx3904cpu.c, dv-tx3904irc.c: Rename *_callback to *_method.
+
+ * dv-tx3904cpu.c, dv-tx3904irc.c: Include hw-main.h and
+ sim-main.h. Declare a struct hw_descriptor instead of struct
+ hw_device_descriptor.
+
+Mon May 25 12:41:38 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips.igen (do_store_left, do_load_left): Compute nr of left and
+ right bits and then re-align left hand bytes to correct byte
+ lanes. Fix incorrect computation in do_store_left when loading
+ bytes from second word.
+
+Fri May 22 13:34:20 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (SIM_AC_OPTION_HARDWARE): Only enable when tx3904.
+ * interp.c (sim_open): Only create a device tree when HW is
+ enabled.
+
+ * dv-tx3904irc.c (tx3904irc_finish): Pacify GCC.
+ * interp.c (signal_exception): Ditto.
+
+Thu May 21 14:24:11 1998 Gavin Koch <gavin@cygnus.com>
+
+ * gencode.c: Mark BEGEZALL as LIKELY.
+
+Thu May 21 18:57:19 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * sim-main.h (ALU32_END): Sign extend 32 bit results.
+ * mips.igen (ADD, SUB, ADDI, DADD, DSUB): Trace.
+
+Mon May 18 18:22:42 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * configure.in (SIM_AC_OPTION_HARDWARE): Added common hardware
+ modules. Recognize TX39 target with "mips*tx39" pattern.
+ * configure: Rebuilt.
+ * sim-main.h (*): Added many macros defining bits in
+ TX39 control registers.
+ (SignalInterrupt): Send actual PC instead of NULL.
+ (SignalNMIReset): New exception type.
+ * interp.c (board): New variable for future use to identify
+ a particular board being simulated.
+ (mips_option_handler,mips_options): Added "--board" option.
+ (interrupt_event): Send actual PC.
+ (sim_open): Make memory layout conditional on board setting.
+ (signal_exception): Initial implementation of hardware interrupt
+ handling. Accept another break instruction variant for simulator
+ exit.
+ (decode_coproc): Implement RFE instruction for TX39.
+ (mips.igen): Decode RFE instruction as such.
+ * configure.in (tx3904cpu,tx3904irc): Added devices for tx3904.
+ * interp.c: Define "jmr3904" and "jmr3904debug" board types and
+ bbegin to implement memory map.
+ * dv-tx3904cpu.c: New file.
+ * dv-tx3904irc.c: New file.
+
+Wed May 13 14:40:11 1998 Gavin Koch <gavin@cygnus.com>
+
+ * mips.igen (check_mt_hilo): Create a separate r3900 version.
+
+Wed May 13 14:11:46 1998 Gavin Koch <gavin@cygnus.com>
+
+ * tx.igen (madd,maddu): Replace calls to check_op_hilo
+ with calls to check_div_hilo.
+
+Wed May 13 09:59:27 1998 Gavin Koch <gavin@cygnus.com>
+
+ * mips/mips.igen (check_op_hilo,check_mult_hilo,check_div_hilo):
+ Replace check_op_hilo with check_mult_hilo and check_div_hilo.
+ Add special r3900 version of do_mult_hilo.
+ (do_dmultx,do_mult,do_multu): Replace calls to check_op_hilo
+ with calls to check_mult_hilo.
+ (do_ddiv,do_ddivu,do_div,do_divu): Replace calls to check_op_hilo
+ with calls to check_div_hilo.
+
+Tue May 12 15:22:11 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (SUBTARGET_R3900): Define for mipstx39 target.
+ Document a replacement.
+
+Fri May 8 17:48:19 1998 Ian Carmichael <iancarm@cygnus.com>
+
+ * interp.c (sim_monitor): Make mon_printf work.
+
+Wed May 6 19:42:19 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * sim-main.h (INSN_NAME): New arg `cpu'.
+
+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:01 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:20 1998 Tom Tromey <tromey@cygnus.com>
+
+ * configure.in: Don't call sinclude.
+
+Fri Apr 24 11:35:01 1998 Andrew Cagney <cagney@chook.cygnus.com>
+
+ * mips.igen (do_store_left): Pass 0 not NULL to store_memory.
+
+Tue Apr 21 11:59:50 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips.igen (ERET): Implement.
+
+ * interp.c (decode_coproc): Return sign-extended EPC.
+
+ * mips.igen (ANDI, LUI, MFC0): Add tracing code.
+
+ * interp.c (signal_exception): Do not ignore Trap.
+ (signal_exception): On TRAP, restart at exception address.
+ (HALT_INSTRUCTION, HALT_INSTRUCTION_MASK): Define.
+ (signal_exception): Update.
+ (sim_open): Patch V_COMMON interrupt vector with an abort sequence
+ so that TRAP instructions are caught.
+
+Mon Apr 20 11:26:55 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * sim-main.h (struct hilo_access, struct hilo_history): Define,
+ contains HI/LO access history.
+ (struct _sim_cpu): Make hiaccess and loaccess of type hilo_access.
+ (HIACCESS, LOACCESS): Delete, replace with
+ (HIHISTORY, LOHISTORY): New macros.
+ (CHECKHILO): Delete all, moved to mips.igen
+
+ * gencode.c (build_instruction): Do not generate checks for
+ correct HI/LO register usage.
+
+ * interp.c (old_engine_run): Delete checks for correct HI/LO
+ register usage.
+
+ * mips.igen (check_mt_hilo, check_mf_hilo, check_op_hilo,
+ check_mf_cycles): New functions.
+ (do_mfhi, do_mflo, "mthi", "mtlo", do_ddiv, do_ddivu, do_div,
+ do_divu, domultx, do_mult, do_multu): Use.
+
+ * tx.igen ("madd", "maddu"): Use.
+
+Wed Apr 15 18:31:54 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips.igen (DSRAV): Use function do_dsrav.
+ (SRAV): Use new function do_srav.
+
+ * m16.igen (BEQZ, BNEZ): Compare GPR[TRX] not GPR[RX].
+ (B): Sign extend 11 bit immediate.
+ (EXT-B*): Shift 16 bit immediate left by 1.
+ (ADDIU*): Don't sign extend immediate value.
+
+Wed Apr 15 10:32:15 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * m16run.c (sim_engine_run): Restore CIA after handling an event.
+
+ * sim-main.h (DELAY_SLOT, NULLIFY_NEXT_INSTRUCTION): For IGEN, use
+ functions.
+
+ * mips.igen (delayslot32, nullify_next_insn): New functions.
+ (m16.igen): Always include.
+ (do_*): Add more tracing.
+
+ * m16.igen (delayslot16): Add NIA argument, could be called by a
+ 32 bit MIPS16 instruction.
+
+ * interp.c (ifetch16): Move function from here.
+ * sim-main.c (ifetch16): To here.
+
+ * sim-main.c (ifetch16, ifetch32): Update to match current
+ implementations of LH, LW.
+ (signal_exception): Don't print out incorrect hex value of illegal
+ instruction.
+
+Wed Apr 15 00:17:25 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * m16run.c (sim_engine_run): Use IMEM16 and IMEM32 to fetch an
+ instruction.
+
+ * m16.igen: Implement MIPS16 instructions.
+
+ * mips.igen (do_addiu, do_addu, do_and, do_daddiu, do_daddu,
+ do_ddiv, do_ddivu, do_div, do_divu, do_dmultx, do_dmultu, do_srav,
+ do_dsubu, do_mfhi, do_mflo, do_mult, do_multu, do_nor, do_or,
+ do_sll, do_sllv, do_slt, do_slti, do_sltiu, do_sltu, do_sra,
+ do_srl, do_srlv, do_subu, do_xor, do_xori): New functions. Move
+ bodies of corresponding code from 32 bit insn to these. Also used
+ by MIPS16 versions of functions.
+
+ * sim-main.h (RAIDX, T8IDX, T8, SPIDX): Define.
+ (IMEM16): Drop NR argument from macro.
+
+Sat Apr 4 22:39:50 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (SIM_OBJS): Add sim-main.o.
+
+ * sim-main.h (address_translation, load_memory, store_memory,
+ cache_op, sync_operation, prefetch, ifetch32, pending_tick): Mark
+ as INLINE_SIM_MAIN.
+ (pr_addr, pr_uword64): Declare.
+ (sim-main.c): Include when H_REVEALS_MODULE_P.
+
+ * interp.c (address_translation, load_memory, store_memory,
+ cache_op, sync_operation, prefetch, ifetch32, pending_tick): Move
+ from here.
+ * sim-main.c: To here. Fix compilation problems.
+
+ * configure.in: Enable inlining.
+ * configure: Re-config.
+
+Sat Apr 4 20:36:25 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure: Regenerated to track ../common/aclocal.m4 changes.
+
+Fri Apr 3 04:32:35 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips.igen: Include tx.igen.
+ * Makefile.in (IGEN_INCLUDE): Add tx.igen.
+ * tx.igen: New file, contains MADD and MADDU.
+
+ * interp.c (load_memory): When shifting bytes, use LOADDRMASK not
+ the hardwired constant `7'.
+ (store_memory): Ditto.
+ (LOADDRMASK): Move definition to sim-main.h.
+
+ mips.igen (MTC0): Enable for r3900.
+ (ADDU): Add trace.
+
+ mips.igen (do_load_byte): Delete.
+ (do_load, do_store, do_load_left, do_load_write, do_store_left,
+ do_store_right): New functions.
+ (SW*, LW*, SD*, LD*, SH, LH, SB, LB): Use.
+
+ configure.in: Let the tx39 use igen again.
+ configure: Update.
+
+Thu Apr 2 10:59:39 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (sim_monitor): get_mem_info returns a 4 byte quantity,
+ not an address sized quantity. Return zero for cache sizes.
+
+Wed Apr 1 23:47:53 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips.igen (r3900): r3900 does not support 64 bit integer
+ operations.
+
+Mon Mar 30 14:46:05 1998 Gavin Koch <gavin@cygnus.com>
+
+ * configure.in (mipstx39*-*-*): Use gencode simulator rather
+ than igen one.
+ * configure : Rebuild.
+
+Fri Mar 27 16:15:52 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure: Regenerated to track ../common/aclocal.m4 changes.
+
+Fri Mar 27 15:01:50 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (mips_option_handler): Iterate over MAX_NR_PROCESSORS.
+
+Wed Mar 25 16:44:27 1998 Ian Carmichael <iancarm@cygnus.com>
+
+ * configure: Regenerated to track ../common/aclocal.m4 changes.
+ * config.in: 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 25 10:05:46 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (Max, Min): Comment out functions. Not yet used.
+
+Wed Mar 18 12:38:12 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure: Regenerated to track ../common/aclocal.m4 changes.
+
+Tue Mar 17 19:05:20 1998 Frank Ch. Eigler <fche@cygnus.com>
+
+ * Makefile.in (MIPS_EXTRA_LIBS, SIM_EXTRA_LIBS): Added
+ configurable settings for stand-alone simulator.
+
+ * configure.in: Added X11 search, just in case.
+
+ * configure: Regenerated.
+
+Wed Mar 11 14:09:10 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (sim_write, sim_read, load_memory, store_memory):
+ Replace sim_core_*_map with read_map, write_map, exec_map resp.
+
+Tue Mar 3 13:58:43 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * sim-main.h (GETFCC): Return an unsigned value.
+
+Tue Mar 3 13:21:37 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips.igen (DIV): Fix check for -1 / MIN_INT.
+ (DADD): Result destination is RD not RT.
+
+Fri Feb 27 13:49:49 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * sim-main.h (HIACCESS, LOACCESS): Always define.
+
+ * mdmx.igen (Maxi, Mini): Rename Max, Min.
+
+ * interp.c (sim_info): Delete.
+
+Fri Feb 27 18:41:01 1998 Doug Evans <devans@canuck.cygnus.com>
+
+ * interp.c (DECLARE_OPTION_HANDLER): Use it.
+ (mips_option_handler): New argument `cpu'.
+ (sim_open): Update call to sim_add_option_table.
+
+Wed Feb 25 18:56:22 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips.igen (CxC1): Add tracing.
+
+Fri Feb 20 17:43:21 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * sim-main.h (Max, Min): Declare.
+
+ * interp.c (Max, Min): New functions.
+
+ * mips.igen (BC1): Add tracing.
+
+Thu Feb 19 14:50:00 1998 John Metzler <jmetzler@cygnus.com>
+
+ * interp.c Added memory map for stack in vr4100
+
+Thu Feb 19 10:21:21 1998 Gavin Koch <gavin@cygnus.com>
+
+ * interp.c (load_memory): Add missing "break"'s.
+
+Tue Feb 17 12:45:35 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (sim_store_register, sim_fetch_register): Pass in
+ length parameter. Return -1.
+
+Tue Feb 10 11:57:40 1998 Ian Carmichael <iancarm@cygnus.com>
+
+ * interp.c: Added hardware init hook, fixed warnings.
+
+Sat Feb 7 17:16:20 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (itable.h itable.c): Depend on SIM_@sim_gen@_ALL.
+
+Tue Feb 3 11:36:02 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (ifetch16): New function.
+
+ * sim-main.h (IMEM32): Rename IMEM.
+ (IMEM16_IMMED): Define.
+ (IMEM16): Define.
+ (DELAY_SLOT): Update.
+
+ * m16run.c (sim_engine_run): New file.
+
+ * m16.igen: All instructions except LB.
+ (LB): Call do_load_byte.
+ * mips.igen (do_load_byte): New function.
+ (LB): Call do_load_byte.
+
+ * mips.igen: Move spec for insn bit size and high bit from here.
+ * Makefile.in (tmp-igen, tmp-m16): To here.
+
+ * m16.dc: New file, decode mips16 instructions.
+
+ * Makefile.in (SIM_NO_ALL): Define.
+ (tmp-m16): Generate both 16 bit and 32 bit simulator engines.
+
+Tue Feb 3 11:28:00 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (mips_fpu_bitsize): For tx39, restrict floating
+ point unit to 32 bit registers.
+ * configure: Re-generate.
+
+Sun Feb 1 15:47:14 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (sim_use_gen): Make IGEN the default simulator
+ generator for generic 32 and 64 bit mips targets.
+ * configure: Re-generate.
+
+Sun Feb 1 16:52:37 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * sim-main.h (SizeFGR): Determine from floating-point and not gpr
+ bitsize.
+
+ * interp.c (sim_fetch_register, sim_store_register): Read/write
+ FGR from correct location.
+ (sim_open): Set size of FGR's according to
+ WITH_TARGET_FLOATING_POINT_BITSIZE.
+
+ * sim-main.h (FGR): Store floating point registers in a separate
+ array.
+
+Sun Feb 1 16:47:51 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure: Regenerated to track ../common/aclocal.m4 changes.
+
+Tue Feb 3 00:10:50 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (ColdReset): Call PENDING_INVALIDATE.
+
+ * sim-main.h (ENGINE_ISSUE_PREFIX_HOOK): Call PENDING_TICK.
+
+ * interp.c (pending_tick): New function. Deliver pending writes.
+
+ * sim-main.h (PENDING_FILL, PENDING_TICK, PENDING_SCHED,
+ PENDING_BIT, PENDING_INVALIDATE): Re-write pipeline code so that
+ it can handle mixed sized quantites and single bits.
+
+Mon Feb 2 17:43:15 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (oengine.h): Do not include when building with IGEN.
+ (sim_open): Replace GPRLEN by WITH_TARGET_WORD_BITSIZE.
+ (sim_info): Ditto for PROCESSOR_64BIT.
+ (sim_monitor): Replace ut_reg with unsigned_word.
+ (*): Ditto for t_reg.
+ (LOADDRMASK): Define.
+ (sim_open): Remove defunct check that host FP is IEEE compliant,
+ using software to emulate floating point.
+ (value_fpr, ...): Always compile, was conditional on HASFPU.
+
+Sun Feb 1 11:15:29 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * sim-main.h (sim_state): Make the cpu array MAX_NR_PROCESSORS in
+ size.
+
+ * interp.c (SD, CPU): Define.
+ (mips_option_handler): Set flags in each CPU.
+ (interrupt_event): Assume CPU 0 is the one being iterrupted.
+ (sim_close): Do not clear STATE, deleted anyway.
+ (sim_write, sim_read): Assume CPU zero's vm should be used for
+ data transfers.
+ (sim_create_inferior): Set the PC for all processors.
+ (sim_monitor, store_word, load_word, mips16_entry): Add cpu
+ argument.
+ (mips16_entry): Pass correct nr of args to store_word, load_word.
+ (ColdReset): Cold reset all cpu's.
+ (signal_exception): Pass cpu to sim_monitor & mips16_entry.
+ (sim_monitor, load_memory, store_memory, signal_exception): Use
+ `CPU' instead of STATE_CPU.
+
+
+ * sim-main.h: Replace uses of STATE_CPU with CPU. Replace sd with
+ SD or CPU_.
+
+ * sim-main.h (signal_exception): Add sim_cpu arg.
+ (SignalException*): Pass both SD and CPU to signal_exception.
+ * interp.c (signal_exception): Update.
+
+ * sim-main.h (value_fpr, store_fpr, dotrace, ifetch32), interp.c:
+ Ditto
+ (sync_operation, prefetch, cache_op, store_memory, load_memory,
+ address_translation): Ditto
+ (decode_coproc, cop_lw, cop_ld, cop_sw, cop_sd): Ditto.
+
+Sat Jan 31 18:15:41 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure: Regenerated to track ../common/aclocal.m4 changes.
+
+Sat Jan 31 14:49:24 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (sim_engine_run): Add `nr_cpus' argument.
+
+ * mips.igen (model): Map processor names onto BFD name.
+
+ * sim-main.h (CPU_CIA): Delete.
+ (SET_CIA, GET_CIA): Define
+
+Wed Jan 21 16:16:27 1998 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * sim-main.h (GPR_SET): Define, used by igen when zeroing a
+ regiser.
+
+ * configure.in (default_endian): Configure a big-endian simulator
+ by default.
+ * configure: Re-generate.
+
+Mon Jan 19 22:26:29 1998 Doug Evans <devans@seba>
+
+ * configure: Regenerated to track ../common/aclocal.m4 changes.
+
+Mon Jan 5 20:38:54 1998 Mark Alexander <marka@cygnus.com>
+
+ * interp.c (sim_monitor): Handle Densan monitor outbyte
+ and inbyte functions.
+
+1997-12-29 Felix Lee <flee@cygnus.com>
+
+ * interp.c (sim_engine_run): msvc cpp barfs on #if (a==b!=c).
+
+Wed Dec 17 14:48:20 1997 Jeffrey A Law (law@cygnus.com)
+
+ * Makefile.in (tmp-igen): Arrange for $zero to always be
+ reset to zero after every instruction.
+
+Mon Dec 15 23:17:11 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure: Regenerated to track ../common/aclocal.m4 changes.
+ * config.in: Ditto.
+
+Wed Dec 10 17:10:45 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mips.igen (MSUB): Fix to work like MADD.
+ * gencode.c (MSUB): Similarly.
+
+Thu Dec 4 09:21:05 1997 Doug Evans <devans@canuck.cygnus.com>
+
+ * configure: Regenerated to track ../common/aclocal.m4 changes.
+
+Wed Nov 26 11:00:23 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips.igen (LWC1): Correct assembler - lwc1 not swc1.
+
+Sun Nov 23 01:45:20 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * sim-main.h (sim-fpu.h): Include.
+
+ * interp.c (convert, SquareRoot, Recip, Divide, Multiply, Sub,
+ Add, Negate, AbsoluteValue, Equal, Less, Infinity, NaN): Rewrite
+ using host independant sim_fpu module.
+
+Thu Nov 20 19:56:22 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (signal_exception): Report internal errors with SIGABRT
+ not SIGQUIT.
+
+ * sim-main.h (C0_CONFIG): New register.
+ (signal.h): No longer include.
+
+ * interp.c (decode_coproc): Allow access C0_CONFIG to register.
+
+Tue Nov 18 15:33:48 1997 Doug Evans <devans@canuck.cygnus.com>
+
+ * Makefile.in (SIM_OBJS): Use $(SIM_NEW_COMMON_OBJS).
+
+Fri Nov 14 11:56:48 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips.igen: Tag vr5000 instructions.
+ (ANDI): Was missing mipsIV model, fix assembler syntax.
+ (do_c_cond_fmt): New function.
+ (C.cond.fmt): Handle mips I-III which do not support CC field
+ separatly.
+ (bc1): Handle mips IV which do not have a delaed FCC separatly.
+ (SDR): Mask paddr when BigEndianMem, not the converse as specified
+ in IV3.2 spec.
+ (DMULT, DMULTU): Force use of hosts 64bit multiplication. Handle
+ vr5000 which saves LO in a GPR separatly.
+
+ * configure.in (enable-sim-igen): For vr5000, select vr5000
+ specific instructions.
+ * configure: Re-generate.
+
+Wed Nov 12 14:42:52 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (SIM_OBJS): Add sim-fpu module.
+
+ * interp.c (store_fpr), sim-main.h: Add separate fmt_uninterpreted_32 and
+ fmt_uninterpreted_64 bit cases to switch. Convert to
+ fmt_formatted,
+
+ * sim-main.h (ENGINE_ISSUE_PREFIX_HOOK): Define,
+
+ * mips.igen (SWR): Mask paddr when BigEndianMem, not the converse
+ as specified in IV3.2 spec.
+ (MTC1, DMTC1): Call StoreFPR to store the GPR in the FPR.
+
+Tue Nov 11 12:38:23 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips.igen: Delay slot branches add OFFSET to NIA not CIA.
+ (MFC0, MTC0, SWC1, LWC1, SDC1, LDC1): Implement.
+ (MTC1, MFC1, DMTC1, DMFC1, CFC1, CTC1): Implement separate non
+ PENDING_FILL versions of instructions. Simplify.
+ (X): New function.
+ (MULT, MULTU): Implement separate RD==0 and RD!=0 versions of
+ instructions.
+ (BEQZ, ..., SLT, SLTI, TLT, TLE, TLI, ...): Explicitly cast GPR to
+ a signed value.
+ (MTHI, MFHI): Disable code checking HI-LO.
+
+ * sim-main.h (dotrace,tracefh), interp.c: Make dotrace & tracefh
+ global.
+ (NULLIFY_NEXT_INSTRUCTION): Call dotrace.
+
+Thu Nov 6 16:36:35 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gencode.c (build_mips16_operands): Replace IPC with cia.
+
+ * interp.c (sim_monitor, signal_exception, cache_op, store_fpr,
+ value_fpr, cop_ld, cop_lw, cop_sw, cop_sd, decode_coproc): Replace
+ IPC to `cia'.
+ (UndefinedResult): Replace function with macro/function
+ combination.
+ (sim_engine_run): Don't save PC in IPC.
+
+ * sim-main.h (IPC): Delete.
+
+
+ * interp.c (signal_exception, store_word, load_word,
+ address_translation, load_memory, store_memory, cache_op,
+ prefetch, sync_operation, ifetch, value_fpr, store_fpr, convert,
+ cop_lw, cop_ld, cop_sw, cop_sd, decode_coproc, sim_monitor): Add
+ current instruction address - cia - argument.
+ (sim_read, sim_write): Call address_translation directly.
+ (sim_engine_run): Rename variable vaddr to cia.
+ (signal_exception): Pass cia to sim_monitor
+
+ * sim-main.h (SignalException, LoadWord, StoreWord, CacheOp,
+ Prefetch, SyncOperation, ValueFPR, StoreFPR, Convert, COP_LW,
+ COP_LD, COP_SW, COP_SD, DecodeCoproc): Update.
+
+ * sim-main.h (SignalExceptionSimulatorFault): Delete definition.
+ * interp.c (sim_open): Replace SignalExceptionSimulatorFault with
+ SIM_ASSERT.
+
+ * interp.c (signal_exception): Pass restart address to
+ sim_engine_restart.
+
+ * Makefile.in (semantics.o, engine.o, support.o, itable.o,
+ idecode.o): Add dependency.
+
+ * sim-main.h (SIM_ENGINE_HALT_HOOK, SIM_ENGINE_RESUME_HOOK):
+ Delete definitions
+ (DELAY_SLOT): Update NIA not PC with branch address.
+ (NULLIFY_NEXT_INSTRUCTION): Set NIA to instruction after next.
+
+ * mips.igen: Use CIA not PC in branch calculations.
+ (illegal): Call SignalException.
+ (BEQ, ADDIU): Fix assembler.
+
+Wed Nov 5 12:19:56 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * m16.igen (JALX): Was missing.
+
+ * configure.in (enable-sim-igen): New configuration option.
+ * configure: Re-generate.
+
+ * sim-main.h (MAX_INSNS, INSN_NAME): Define.
+
+ * interp.c (load_memory, store_memory): Delete parameter RAW.
+ (sim_read, sim_write): Use sim_core_{read,write}_buffer directly
+ bypassing {load,store}_memory.
+
+ * sim-main.h (ByteSwapMem): Delete definition.
+
+ * Makefile.in (SIM_OBJS): Add sim-memopt module.
+
+ * interp.c (sim_do_command, sim_commands): Delete mips specific
+ commands. Handled by module sim-options.
+
+ * sim-main.h (SIM_HAVE_FLATMEM): Undefine, use sim-core.o module.
+ (WITH_MODULO_MEMORY): Define.
+
+ * interp.c (sim_info): Delete code printing memory size.
+
+ * interp.c (mips_size): Nee sim_size, delete function.
+ (power2): Delete.
+ (monitor, monitor_base, monitor_size): Delete global variables.
+ (sim_open, sim_close): Delete code creating monitor and other
+ memory regions. Use sim-memopts module, via sim_do_commandf, to
+ manage memory regions.
+ (load_memory, store_memory): Use sim-core for memory model.
+
+ * interp.c (address_translation): Delete all memory map code
+ except line forcing 32 bit addresses.
+
+Wed Nov 5 11:21:11 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * sim-main.h (WITH_TRACE): Delete definition. Enables common
+ trace options.
+
+ * interp.c (logfh, logfile): Delete globals.
+ (sim_open, sim_close): Delete code opening & closing log file.
+ (mips_option_handler): Delete -l and -n options.
+ (OPTION mips_options): Ditto.
+
+ * interp.c (OPTION mips_options): Rename option trace to dinero.
+ (mips_option_handler): Update.
+
+Wed Nov 5 09:35:59 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (fetch_str): New function.
+ (sim_monitor): Rewrite using sim_read & sim_write.
+ (sim_open): Check magic number.
+ (sim_open): Write monitor vectors into memory using sim_write.
+ (MONITOR_BASE, MONITOR_SIZE, MEM_SIZE): Define.
+ (sim_read, sim_write): Simplify - transfer data one byte at a
+ time.
+ (load_memory, store_memory): Clarify meaning of parameter RAW.
+
+ * sim-main.h (isHOST): Defete definition.
+ (isTARGET): Mark as depreciated.
+ (address_translation): Delete parameter HOST.
+
+ * interp.c (address_translation): Delete parameter HOST.
+
+Wed Oct 29 11:13:56 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips.igen:
+
+ * Makefile.in (IGEN_INCLUDE): Files included by mips.igen.
+ (tmp-igen, tmp-m16): Depend on IGEN_INCLUDE.
+
+Tue Oct 28 11:06:47 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mips.igen: Add model filter field to records.
+
+Mon Oct 27 17:53:59 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (SIM_NO_CFLAGS): Define. Define WITH_IGEN=0.
+
+ interp.c (sim_engine_run): Do not compile function sim_engine_run
+ when WITH_IGEN == 1.
+
+ * configure.in (sim_igen_flags, sim_m16_flags): Set according to
+ target architecture.
+
+ Makefile.in (tmp-igen, tmp-m16): Drop -F and -M options to
+ igen. Replace with configuration variables sim_igen_flags /
+ sim_m16_flags.
+
+ * m16.igen: New file. Copy mips16 insns here.
+ * mips.igen: From here.
+
+Mon Oct 27 13:53:59 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (SIM_NO_OBJ): Define, move SIM_M16_OBJ, SIM_IGEN_OBJ
+ to top.
+ (tmp-igen, tmp-m16): Pass -I srcdir to igen.
+
+Sat Oct 25 16:51:40 1997 Gavin Koch <gavin@cygnus.com>
+
+ * gencode.c (build_instruction): Follow sim_write's lead in using
+ BigEndianMem instead of !ByteSwapMem.
+
+Fri Oct 24 17:41:49 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (sim_gen): Dependent on target, select type of
+ generator. Always select old style generator.
+
+ configure: Re-generate.
+
+ Makefile.in (tmp-igen, tmp-m16, clean-m16, clean-igen): New
+ targets.
+ (SIM_M16_CFLAGS, SIM_M16_ALL, SIM_M16_OBJ, BUILT_SRC_FROM_M16,
+ SIM_IGEN_CFLAGS, SIM_IGEN_ALL, SIM_IGEN_OBJ, BUILT_SRC_FROM_IGEN,
+ IGEN_TRACE, IGEN_INSN, IGEN_DC): Define
+ (SIM_EXTRA_CFLAGS, SIM_EXTRA_ALL, SIM_OBJS): Add member
+ SIM_@sim_gen@_*, set by autoconf.
+
+Wed Oct 22 12:52:06 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * sim-main.h (NULLIFY_NEXT_INSTRUCTION, DELAY_SLOT): Define.
+
+ * interp.c (ColdReset): Remove #ifdef HASFPU, check
+ CURRENT_FLOATING_POINT instead.
+
+ * interp.c (ifetch32): New function. Fetch 32 bit instruction.
+ (address_translation): Raise exception InstructionFetch when
+ translation fails and isINSTRUCTION.
+
+ * interp.c (sim_open, sim_write, sim_monitor, store_word,
+ sim_engine_run): Change type of of vaddr and paddr to
+ address_word.
+ (address_translation, prefetch, load_memory, store_memory,
+ cache_op): Change type of vAddr and pAddr to address_word.
+
+ * gencode.c (build_instruction): Change type of vaddr and paddr to
+ address_word.
+
+Mon Oct 20 15:29:04 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * sim-main.h (ALU64_END, ALU32_END): Use ALU*_OVERFLOW_RESULT
+ macro to obtain result of ALU op.
+
+Tue Oct 21 17:39:14 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (sim_info): Call profile_print.
+
+Mon Oct 20 13:31:20 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (SIM_OBJS): Add sim-profile.o module.
+
+ * sim-main.h (WITH_PROFILE): Do not define, defined in
+ common/sim-config.h. Use sim-profile module.
+ (simPROFILE): Delete defintion.
+
+ * interp.c (PROFILE): Delete definition.
+ (mips_option_handler): Delete 'p', 'y' and 'x' profile options.
+ (sim_close): Delete code writing profile histogram.
+ (mips_set_profile, mips_set_profile_size, writeout16, writeout32):
+ Delete.
+ (sim_engine_run): Delete code profiling the PC.
+
+Mon Oct 20 13:31:20 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * sim-main.h (SIGNEXTEND): Force type of result to unsigned_word.
+
+ * interp.c (sim_monitor): Make register pointers of type
+ unsigned_word*.
+
+ * sim-main.h: Make registers of type unsigned_word not
+ signed_word.
+
+Thu Oct 16 10:31:39 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (sync_operation): Rename from SyncOperation, make
+ global, add SD argument.
+ (prefetch): Rename from Prefetch, make global, add SD argument.
+ (decode_coproc): Make global.
+
+ * sim-main.h (SyncOperation, DecodeCoproc, Pefetch): Define.
+
+ * gencode.c (build_instruction): Generate DecodeCoproc not
+ decode_coproc calls.
+
+ * interp.c (SETFCC, GETFCC, PREVCOC1): Move to sim-main.h
+ (SizeFGR): Move to sim-main.h
+ (simHALTEX, simHALTIN, simTRACE, simPROFILE, simDELAYSLOT,
+ simSIGINT, simJALDELAYSLOT): Move to sim-main.h
+ (FP_FLAGS, FP_ENABLE, FP_CAUSE, IR, UF, OF, DZ, IO, UO): Move to
+ sim-main.h.
+ (FP_FS, FP_MASK_RM, FP_SH_RM, FP_RM_NEAREST, FP_RM_TOPINF,
+ FP_RM_TOMINF, GETRM): Move to sim-main.h.
+ (Uncached, CachedNoncoherent, CachedCoherent, Cached,
+ isINSTRUCTION, ..., AccessLength_BYTE, ...): Move to sim-main.h.
+ (UserMode, BigEndianMem, ByteSwapMem, ReverseEndian,
+ BigEndianCPU, status_KSU_mask, ...). Moved to sim-main.h
+
+ * sim-main.h (ALU32_END, ALU64_END): Define. When overflow raise
+ exception.
+ (sim-alu.h): Include.
+ (NULLIFY_NIA, NULL_CIA, CPU_CIA): Define.
+ (sim_cia): Typedef to instruction_address.
+
+Thu Oct 16 10:31:41 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (interp.o): Rename generated file engine.c to
+ oengine.c.
+
+ * interp.c: Update.
+
+Thu Oct 16 10:31:40 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gencode.c (build_instruction): Use FPR_STATE not fpr_state.
+
+Thu Oct 16 10:31:39 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gencode.c (build_instruction): For "FPSQRT", output correct
+ number of arguments to Recip.
+
+Tue Oct 14 17:38:18 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (interp.o): Depends on sim-main.h
+
+ * interp.c (mips16_entry, ColdReset,dotrace): Add SD argument. Use GPR not registers.
+
+ * sim-main.h (sim_cpu): Add registers, register_widths, fpr_state,
+ ipc, dspc, pending_*, hiaccess, loaccess, state, dsstate fields.
+ (REGISTERS, REGISTER_WIDTHS, FPR_STATE, IPC, DSPC, PENDING_*,
+ STATE, DSSTATE): Define
+ (GPR, FGRIDX, ..): Define.
+
+ * interp.c (registers, register_widths, fpr_state, ipc, dspc,
+ pending_*, hiaccess, loaccess, state, dsstate): Delete globals.
+ (GPR, FGRIDX, ...): Delete macros.
+
+ * interp.c: Update names to match defines from sim-main.h
+
+Tue Oct 14 15:11:45 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (sim_monitor): Add SD argument.
+ (sim_warning): Delete. Replace calls with calls to
+ sim_io_eprintf.
+ (sim_error): Delete. Replace calls with sim_io_error.
+ (open_trace, writeout32, writeout16, getnum): Add SD argument.
+ (mips_set_profile): Rename from sim_set_profile. Add SD argument.
+ (mips_set_profile_size): Rename from sim_set_profile_size. Add SD
+ argument.
+ (mips_size): Rename from sim_size. Add SD argument.
+
+ * interp.c (simulator): Delete global variable.
+ (callback): Delete global variable.
+ (mips_option_handler, sim_open, sim_write, sim_read,
+ sim_store_register, sim_fetch_register, sim_info, sim_do_command,
+ sim_size,sim_monitor): Use sim_io_* not callback->*.
+ (sim_open): ZALLOC simulator struct.
+ (PROFILE): Do not define.
+
+Tue Oct 14 13:35:48 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (sim_open), support.h: Replace CHECKSIM macro found in
+ support.h with corresponding code.
+
+ * sim-main.h (word64, uword64), support.h: Move definition to
+ sim-main.h.
+ (WORD64LO, WORD64HI, SET64LO, SET64HI, WORD64, UWORD64): Ditto.
+
+ * support.h: Delete
+ * Makefile.in: Update dependencies
+ * interp.c: Do not include.
+
+Tue Oct 14 13:35:48 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (address_translation, load_memory, store_memory,
+ cache_op): Rename to from AddressTranslation et.al., make global,
+ add SD argument
+
+ * sim-main.h (AddressTranslation, LoadMemory, StoreMemory,
+ CacheOp): Define.
+
+ * interp.c (SignalException): Rename to signal_exception, make
+ global.
+
+ * interp.c (Interrupt, ...): Move definitions to sim-main.h.
+
+ * sim-main.h (SignalException, SignalExceptionInterrupt,
+ SignalExceptionInstructionFetch, SignalExceptionAddressStore,
+ SignalExceptionAddressLoad, SignalExceptionSimulatorFault,
+ SignalExceptionIntegerOverflow, SignalExceptionCoProcessorUnusable):
+ Define.
+
+ * interp.c, support.h: Use.
+
+Tue Oct 14 13:19:20 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (ValueFPR, StoreFPR), sim-main.h: Make global, rename
+ to value_fpr / store_fpr. Add SD argument.
+ (NaN, Infinity, Less, Equal, AbsoluteValue, Negate, Add, Sub,
+ Multiply, Divide, Recip, SquareRoot, Convert): Make global.
+
+ * sim-main.h (ValueFPR, StoreFPR): Define.
+
+Tue Oct 14 13:06:55 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (sim_engine_run): Check consistency between configure
+ WITH_TARGET_WORD_BITSIZE and WITH_FLOATING_POINT and gensim GPRLEN
+ and HASFPU.
+
+ * configure.in (mips_bitsize): Configure WITH_TARGET_WORD_BITSIZE.
+ (mips_fpu): Configure WITH_FLOATING_POINT.
+ (mips_endian): Configure WITH_TARGET_ENDIAN.
+ * configure: Update.
+
+Fri Oct 3 09:28:00 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure: Regenerated to track ../common/aclocal.m4 changes.
+
+Mon Sep 29 14:45:00 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * configure: Regenerated.
+
+Fri Sep 26 12:48:18 1997 Mark Alexander <marka@cygnus.com>
+
+ * interp.c: Allow Debug, DEPC, and EPC registers to be examined in GDB.
+
+Thu Sep 25 11:15:22 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gencode.c (print_igen_insn_models): Assume certain architectures
+ include all mips* instructions.
+ (print_igen_insn_format): Use data_size==-1 as marker for MIPS16
+ instruction.
+
+ * Makefile.in (tmp.igen): Add target. Generate igen input from
+ gencode file.
+
+ * gencode.c (FEATURE_IGEN): Define.
+ (main): Add --igen option. Generate output in igen format.
+ (process_instructions): Format output according to igen option.
+ (print_igen_insn_format): New function.
+ (print_igen_insn_models): New function.
+ (process_instructions): Only issue warnings and ignore
+ instructions when no FEATURE_IGEN.
+
+Wed Sep 24 17:38:57 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (COP_SD, COP_LD): Add UNUSED to pacify GCC for some
+ MIPS targets.
+
+Tue Sep 23 11:04:38 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure: Regenerated to track ../common/aclocal.m4 changes.
+
+Tue Sep 23 10:19:51 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (SIM_ALIGNMENT, SIM_ENDIAN, SIM_HOSTENDIAN,
+ SIM_RESERVED_BITS): Delete, moved to common.
+ (SIM_EXTRA_CFLAGS): Update.
+
+Mon Sep 22 11:46:20 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in: Configure non-strict memory alignment.
+ * 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.
+
+Sat Sep 20 14:07:28 1997 Gavin Koch <gavin@cygnus.com>
+
+ * gencode.c (SDBBP,DERET): Added (3900) insns.
+ (RFE): Turn on for 3900.
+ * interp.c (DebugBreakPoint,DEPC,Debug,Debug_*): Added.
+ (dsstate): Made global.
+ (SUBTARGET_R3900): Added.
+ (CANCELDELAYSLOT): New.
+ (SignalException): Ignore SystemCall rather than ignore and
+ terminate. Add DebugBreakPoint handling.
+ (decode_coproc): New insns RFE, DERET; and new registers Debug
+ and DEPC protected by SUBTARGET_R3900.
+ (sim_engine_run): Use CANCELDELAYSLOT rather than clearing
+ bits explicitly.
+ * Makefile.in,configure.in: Add mips subtarget option.
+ * configure: Update.
+
+Fri Sep 19 09:33:27 1997 Gavin Koch <gavin@cygnus.com>
+
+ * gencode.c: Add r3900 (tx39).
+
+
+Tue Sep 16 15:52:04 1997 Gavin Koch <gavin@cygnus.com>
+
+ * gencode.c (build_instruction): Don't need to subtract 4 for
+ JALR, just 2.
+
+Tue Sep 16 11:32:28 1997 Gavin Koch <gavin@cygnus.com>
+
+ * interp.c: Correct some HASFPU problems.
+
+Mon Sep 15 17:36:15 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure: Regenerated to track ../common/aclocal.m4 changes.
+
+Fri Sep 12 12:01:39 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (mips_options): Fix samples option short form, should
+ be `x'.
+
+Thu Sep 11 09:35:29 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (sim_info): Enable info code. Was just returning.
+
+Tue Sep 9 17:30:57 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (decode_coproc): Clarify warning about unsuported MTC0,
+ MFC0.
+
+Tue Sep 9 16:28:28 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gencode.c (build_instruction): Use SIGNED64 for 64 bit
+ constants.
+ (build_instruction): Ditto for LL.
+
+Thu Sep 4 17:21:23 1997 Doug Evans <dje@seba>
+
+ * configure: Regenerated to track ../common/aclocal.m4 changes.
+
+Wed Aug 27 18:13:22 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure: Regenerated to track ../common/aclocal.m4 changes.
+ * config.in: Ditto.
+
+Wed Aug 27 14:12:27 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (sim_open): Add call to sim_analyze_program, update
+ call to sim_config.
+
+Tue Aug 26 10:40:07 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (sim_kill): Delete.
+ (sim_create_inferior): Add ABFD argument. Set PC from same.
+ (sim_load): Move code initializing trap handlers from here.
+ (sim_open): To here.
+ (sim_load): Delete, use sim-hload.c.
+
+ * Makefile.in (SIM_OBJS): Add sim-hload.o module.
+
+Mon Aug 25 17:50:22 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure: Regenerated to track ../common/aclocal.m4 changes.
+ * config.in: Ditto.
+
+Mon Aug 25 15:59:48 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (sim_open): Add ABFD argument.
+ (sim_load): Move call to sim_config from here.
+ (sim_open): To here. Check return status.
+
+Fri Jul 25 15:00:45 1997 Gavin Koch <gavin@cygnus.com>
+
+ * gencode.c (build_instruction): Two arg MADD should
+ not assign result to $0.
+
+Thu Jun 26 12:13:17 1997 Angela Marie Thomas (angela@cygnus.com)
+
+ * sim/mips/configure: Change default_sim_endian to 0 (bi-endian)
+ * sim/mips/configure.in: Regenerate.
+
+Wed Jul 9 10:29:21 1997 Andrew Cagney <cagney@critters.cygnus.com>
+
+ * interp.c (SUB_REG_UW, SUB_REG_SW, SUB_REG_*): Use more explicit
+ signed8, unsigned8 et.al. types.
+
+ * interp.c (SUB_REG_FETCH): Handle both little and big endian
+ hosts when selecting subreg.
+
+Wed Jul 2 11:54:10 1997 Jeffrey A Law (law@cygnus.com)
+
+ * interp.c (sim_engine_run): Reset the ZERO register to zero
+ regardless of FEATURE_WARN_ZERO.
+ * gencode.c (FEATURE_WARNINGS): Remove FEATURE_WARN_ZERO.
+
+Wed Jun 4 10:43:14 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (decode_coproc): Implement MTC0 N, CAUSE.
+ (SignalException): For BreakPoints ignore any mode bits and just
+ save the PC.
+ (SignalException): Always set the CAUSE register.
+
+Tue Jun 3 05:00:33 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (SignalException): Clear the simDELAYSLOT flag when an
+ exception has been taken.
+
+ * interp.c: Implement the ERET and mt/f sr instructions.
+
+Sat May 31 00:44:16 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (SignalException): Don't bother restarting an
+ interrupt.
+
+Fri May 30 23:41:48 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (SignalException): Really take an interrupt.
+ (interrupt_event): Only deliver interrupts when enabled.
+
+Tue May 27 20:08:06 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (sim_info): Only print info when verbose.
+ (sim_info) Use sim_io_printf for output.
+
+Tue May 27 14:22:23 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (CoProcPresent): Add UNUSED attribute - not used by all
+ mips architectures.
+
+Tue May 27 14:22:23 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (sim_do_command): Check for common commands if a
+ simulator specific command fails.
+
+Thu May 22 09:32:03 1997 Gavin Koch <gavin@cygnus.com>
+
+ * interp.c (sim_engine_run): ifdef out uses of simSTOP, simSTEP
+ and simBE when DEBUG is defined.
+
+Wed May 21 09:08:10 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (interrupt_event): New function. Pass exception event
+ onto exception handler.
+
+ * configure.in: Check for stdlib.h.
+ * configure: Regenerate.
+
+ * gencode.c (build_instruction): Add UNUSED attribute to tempS
+ variable declaration.
+ (build_instruction): Initialize memval1.
+ (build_instruction): Add UNUSED attribute to byte, bigend,
+ reverse.
+ (build_operands): Ditto.
+
+ * interp.c: Fix GCC warnings.
+ (sim_get_quit_code): Delete.
+
+ * configure.in: Add INLINE, ENDIAN, HOSTENDIAN and WARNINGS.
+ * Makefile.in: Ditto.
+ * configure: Re-generate.
+
+ * Makefile.in (SIM_OBJS): Add sim-watch.o module.
+
+Tue May 20 15:08:56 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (mips_option_handler): New function parse argumes using
+ sim-options.
+ (myname): Replace with STATE_MY_NAME.
+ (sim_open): Delete check for host endianness - performed by
+ sim_config.
+ (simHOSTBE, simBE): Delete, replaced by sim-endian flags.
+ (sim_open): Move much of the initialization from here.
+ (sim_load): To here. After the image has been loaded and
+ endianness set.
+ (sim_open): Move ColdReset from here.
+ (sim_create_inferior): To here.
+ (sim_open): Make FP check less dependant on host endianness.
+
+ * Makefile.in (SIM_RUN_OBJS): Set to nrun.o - use new version or
+ run.
+ * interp.c (sim_set_callbacks): Delete.
+
+ * interp.c (membank, membank_base, membank_size): Replace with
+ STATE_MEMORY, STATE_MEM_SIZE, STATE_MEM_BASE.
+ (sim_open): Remove call to callback->init. gdb/run do this.
+
+ * interp.c: Update
+
+ * sim-main.h (SIM_HAVE_FLATMEM): Define.
+
+ * interp.c (big_endian_p): Delete, replaced by
+ current_target_byte_order.
+
+Tue May 20 13:55:00 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (host_read_long, host_read_word, host_swap_word,
+ host_swap_long): Delete. Using common sim-endian.
+ (sim_fetch_register, sim_store_register): Use H2T.
+ (pipeline_ticks): Delete. Handled by sim-events.
+ (sim_info): Update.
+ (sim_engine_run): Update.
+
+Tue May 20 13:42:03 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (sim_stop_reason): Move code determining simEXCEPTION
+ reason from here.
+ (SignalException): To here. Signal using sim_engine_halt.
+ (sim_stop_reason): Delete, moved to common.
+
+Tue May 20 10:19:48 1997 Andrew Cagney <cagney@b2.cygnus.com>
+
+ * interp.c (sim_open): Add callback argument.
+ (sim_set_callbacks): Delete SIM_DESC argument.
+ (sim_size): Ditto.
+
+Mon May 19 18:20:38 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (SIM_OBJS): Add common modules.
+
+ * interp.c (sim_set_callbacks): Also set SD callback.
+ (set_endianness, xfer_*, swap_*): Delete.
+ (host_read_word, host_read_long, host_swap_word, host_swap_long):
+ Change to functions using sim-endian macros.
+ (control_c, sim_stop): Delete, use common version.
+ (simulate): Convert into.
+ (sim_engine_run): This function.
+ (sim_resume): Delete.
+
+ * interp.c (simulation): New variable - the simulator object.
+ (sim_kind): Delete global - merged into simulation.
+ (sim_load): Cleanup. Move PC assignment from here.
+ (sim_create_inferior): To here.
+
+ * sim-main.h: New file.
+ * interp.c (sim-main.h): Include.
+
+Thu Apr 24 00:39:51 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * configure: Regenerated to track ../common/aclocal.m4 changes.
+
+Wed Apr 23 17:32:19 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * tconfig.in (SIM_HAVE_BIENDIAN): Define.
+
+Mon Apr 21 17:16:13 1997 Gavin Koch <gavin@cygnus.com>
+
+ * gencode.c (build_instruction): DIV instructions: check
+ for division by zero and integer overflow before using
+ host's division operation.
+
+Thu Apr 17 03:18:14 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in (SIM_OBJS): Add sim-load.o.
+ * interp.c: #include bfd.h.
+ (target_byte_order): Delete.
+ (sim_kind, myname, big_endian_p): New static locals.
+ (sim_open): Set sim_kind, myname. Move call to set_endianness to
+ after argument parsing. Recognize -E arg, set endianness accordingly.
+ (sim_load): Return SIM_RC. New arg abfd. Call sim_load_file to
+ load file into simulator. Set PC from bfd.
+ (sim_create_inferior): Return SIM_RC. Delete arg start_address.
+ (set_endianness): Use big_endian_p instead of target_byte_order.
+
+Wed Apr 16 17:55:37 1997 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * interp.c (sim_size): Delete prototype - conflicts with
+ definition in remote-sim.h. Correct definition.
+
+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>
+
+ * interp.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.
+
+Tue Mar 25 11:38:22 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * interp.c (sim_open): Set optind to 0 before calling getopt.
+
+Wed Mar 19 01:14:00 1997 Andrew Cagney <cagney@kremvax.cygnus.com>
+
+ * configure: Regenerated to track ../common/aclocal.m4 changes.
+
+Mon Mar 17 10:52:59 1997 Gavin Koch <gavin@cetus.cygnus.com>
+
+ * interp.c : Replace uses of pr_addr with pr_uword64
+ where the bit length is always 64 independent of SIM_ADDR.
+ (pr_uword64) : added.
+
+Mon Mar 17 15:10:07 1997 Andrew Cagney <cagney@kremvax.cygnus.com>
+
+ * configure: Re-generate.
+
+Fri Mar 14 10:34:11 1997 Michael Meissner <meissner@cygnus.com>
+
+ * configure: Regenerate to track ../common/aclocal.m4 changes.
+
+Thu Mar 13 12:51:36 1997 Doug Evans <dje@canuck.cygnus.com>
+
+ * interp.c (sim_open): New SIM_DESC result. Argument is now
+ in argv form.
+ (other sim_*): New SIM_DESC argument.
+
+Mon Feb 24 22:47:14 1997 Dawn Perchik <dawn@cygnus.com>
+
+ * interp.c: Fix printing of addresses for non-64-bit targets.
+ (pr_addr): Add function to print address based on size.
+
+Wed Feb 19 14:42:09 1997 Mark Alexander <marka@cygnus.com>
+
+ * interp.c (simopen): Add support for LSI MiniRISC PMON vectors.
+
+Thu Feb 13 14:08:30 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gencode.c (build_mips16_operands): Correct computation of base
+ address for extended PC relative instruction.
+
+Thu Feb 6 17:16:15 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * interp.c (mips16_entry): Add support for floating point cases.
+ (SignalException): Pass floating point cases to mips16_entry.
+ (ValueFPR): Don't restrict fmt_single and fmt_word to even
+ registers.
+ (StoreFPR): Likewise. Also, don't clobber fpr + 1 for fmt_single
+ or fmt_word.
+ (COP_LW): Pass fmt_word rather than fmt_uninterpreted to StoreFPR,
+ and then set the state to fmt_uninterpreted.
+ (COP_SW): Temporarily set the state to fmt_word while calling
+ ValueFPR.
+
+Tue Feb 4 16:48:25 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * gencode.c (build_instruction): The high order may be set in the
+ comparison flags at any ISA level, not just ISA 4.
+
+Tue Feb 4 13:33:30 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.
+
+Fri Jan 31 11:11:45 1997 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Rebuild after change to aclocal.m4.
+
+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 Jan 8 12:39:03 1997 Jim Wilson <wilson@cygnus.com>
+
+ * gencode.c (build_instruction): Use BigEndianCPU instead of
+ ByteSwapMem.
+
+Thu Jan 02 22:23:04 1997 Mark Alexander <marka@cygnus.com>
+
+ * interp.c (sim_monitor): Make output to stdout visible in
+ wingdb's I/O log window.
+
+Tue Dec 31 07:04:00 1996 Mark Alexander <marka@cygnus.com>
+
+ * support.h: Undo previous change to SIGTRAP
+ and SIGQUIT values.
+
+Mon Dec 30 17:36:06 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * interp.c (store_word, load_word): New static functions.
+ (mips16_entry): New static function.
+ (SignalException): Look for mips16 entry and exit instructions.
+ (simulate): Use the correct index when setting fpr_state after
+ doing a pending move.
+
+Sun Dec 29 09:37:18 1996 Mark Alexander <marka@cygnus.com>
+
+ * interp.c: Fix byte-swapping code throughout to work on
+ both little- and big-endian hosts.
+
+Sun Dec 29 09:18:32 1996 Mark Alexander <marka@cygnus.com>
+
+ * support.h: Make definitions of SIGTRAP and SIGQUIT consistent
+ with gdb/config/i386/xm-windows.h.
+
+Fri Dec 27 22:48:51 1996 Mark Alexander <marka@cygnus.com>
+
+ * gencode.c (build_instruction): Work around MSVC++ code gen bug
+ that messes up arithmetic shifts.
+
+Fri Dec 20 11:04:05 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * support.h: Use _WIN32 instead of __WIN32__. Also add defs for
+ SIGTRAP and SIGQUIT for _WIN32.
+
+Thu Dec 19 14:07:27 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gencode.c (build_instruction) [MUL]: Cast operands to word64, to
+ force a 64 bit multiplication.
+ (build_instruction) [OR]: In mips16 mode, don't do anything if the
+ destination register is 0, since that is the default mips16 nop
+ instruction.
+
+Mon Dec 16 14:59:38 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gencode.c (MIPS16_DECODE): SWRASP is I8, not RI.
+ (build_endian_shift): Don't check proc64.
+ (build_instruction): Always set memval to uword64. Cast op2 to
+ uword64 when shifting it left in memory instructions. Always use
+ the same code for stores--don't special case proc64.
+
+ * gencode.c (build_mips16_operands): Fix base PC value for PC
+ relative operands.
+ (build_instruction): Call JALDELAYSLOT rather than DELAYSLOT for a
+ jal instruction.
+ * interp.c (simJALDELAYSLOT): Define.
+ (JALDELAYSLOT): Define.
+ (INDELAYSLOT, INJALDELAYSLOT): Define.
+ (simulate): Clear simJALDELAYSLOT when simDELAYSLOT is cleared.
+
+Tue Dec 24 22:11:20 1996 Angela Marie Thomas (angela@cygnus.com)
+
+ * interp.c (sim_open): add flush_cache as a PMON routine
+ (sim_monitor): handle flush_cache by ignoring it
+
+Wed Dec 11 13:53:51 1996 Jim Wilson <wilson@cygnus.com>
+
+ * gencode.c (build_instruction): Use !ByteSwapMem instead of
+ BigEndianMem.
+ * interp.c (CONFIG, config_EP_{mask,shift,D,DxxDxx, config_BE): Delete.
+ (BigEndianMem): Rename to ByteSwapMem and change sense.
+ (BigEndianCPU, sim_write, LoadMemory, StoreMemory): Change
+ BigEndianMem references to !ByteSwapMem.
+ (set_endianness): New function, with prototype.
+ (sim_open): Call set_endianness.
+ (sim_info): Use simBE instead of BigEndianMem.
+ (xfer_direct_word, xfer_direct_long, swap_direct_word,
+ swap_direct_long, xfer_big_word, xfer_big_long, xfer_little_word,
+ xfer_little_long, swap_word, swap_long): Delete unnecessary MSC_VER
+ ifdefs, keeping the prototype declaration.
+ (swap_word): Rewrite correctly.
+ (ColdReset): Delete references to CONFIG. Delete endianness related
+ code; moved to set_endianness.
+
+Tue Dec 10 11:32:04 1996 Jim Wilson <wilson@cygnus.com>
+
+ * gencode.c (build_instruction, case JUMP): Truncate PC to 32 bits.
+ * interp.c (CHECKHILO): Define away.
+ (simSIGINT): New macro.
+ (membank_size): Increase from 1MB to 2MB.
+ (control_c): New function.
+ (sim_resume): Rename parameter signal to signal_number. Add local
+ variable prev. Call signal before and after simulate.
+ (sim_stop_reason): Add simSIGINT support.
+ (sim_warning, sim_error, dotrace, SignalException): Define as stdarg
+ functions always.
+ (sim_warning): Delete call to SignalException. Do call printf_filtered
+ if logfh is NULL.
+ (AddressTranslation): Add #ifdef DEBUG around debugging message and
+ a call to sim_warning.
+
+Wed Nov 27 11:53:50 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gencode.c (process_instructions): If ! proc64, skip DOUBLEWORD
+ 16 bit instructions.
+
+Tue Nov 26 11:53:12 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ Add support for mips16 (16 bit MIPS implementation):
+ * gencode.c (inst_type): Add mips16 instruction encoding types.
+ (GETDATASIZEINSN): Define.
+ (MIPS_DECODE): Add REG flag to dsllv, dsrav, and dsrlv. Add
+ jalx. Add LEFT flag to mfhi and mflo. Add RIGHT flag to mthi and
+ mtlo.
+ (MIPS16_DECODE): New table, for mips16 instructions.
+ (bitmap_val): New static function.
+ (struct mips16_op): Define.
+ (mips16_op_table): New table, for mips16 operands.
+ (build_mips16_operands): New static function.
+ (process_instructions): If PC is odd, decode a mips16
+ instruction. Break out instruction handling into new
+ build_instruction function.
+ (build_instruction): New static function, broken out of
+ process_instructions. Check modifiers rather than flags for SHIFT
+ bit count and m[ft]{hi,lo} direction.
+ (usage): Pass program name to fprintf.
+ (main): Remove unused variable this_option_optind. Change
+ ``*loptarg++'' to ``loptarg++''.
+ (my_strtoul): Parenthesize && within ||.
+ * interp.c (LoadMemory): Accept a halfword pAddr if vAddr is odd.
+ (simulate): If PC is odd, fetch a 16 bit instruction, and
+ increment PC by 2 rather than 4.
+ * configure.in: Add case for mips16*-*-*.
+ * configure: Rebuild.
+
+Fri Nov 22 08:49:36 1996 Mark Alexander <marka@cygnus.com>
+
+ * interp.c: Allow -t to enable tracing in standalone simulator.
+ Fix garbage output in trace file and error messages.
+
+Wed Nov 20 01:54:37 1996 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.in: Delete stuff moved to ../common/Make-common.in.
+ (SIM_{OBJS,EXTRA_CFLAGS,EXTRA_CLEAN}): Define.
+ * configure.in: Simplify using macros in ../common/aclocal.m4.
+ * configure: Regenerated.
+ * tconfig.in: New file.
+
+Tue Nov 12 13:34:00 1996 Dawn Perchik <dawn@cygnus.com>
+
+ * interp.c: Fix bugs in 64-bit port.
+ Use ansi function declarations for msvc compiler.
+ Initialize and test file pointer in trace code.
+ Prevent duplicate definition of LAST_EMED_REGNUM.
+
+Tue Oct 15 11:07:06 1996 Mark Alexander <marka@cygnus.com>
+
+ * interp.c (xfer_big_long): Prevent unwanted sign extension.
+
+Thu Sep 26 17:35:00 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * interp.c (SignalException): Check for explicit terminating
+ breakpoint value.
+ * gencode.c: Pass instruction value through SignalException()
+ calls for Trap, Breakpoint and Syscall.
+
+Thu Sep 26 11:35:17 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * interp.c (SquareRoot): Add HAVE_SQRT check to ensure sqrt() is
+ only used on those hosts that provide it.
+ * configure.in: Add sqrt() to list of functions to be checked for.
+ * config.in: Re-generated.
+ * configure: Re-generated.
+
+Fri Sep 20 15:47:12 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gencode.c (process_instructions): Call build_endian_shift when
+ expanding STORE RIGHT, to fix swr.
+ * support.h (SIGNEXTEND): If the sign bit is not set, explicitly
+ clear the high bits.
+ * interp.c (Convert): Fix fmt_single to fmt_long to not truncate.
+ Fix float to int conversions to produce signed values.
+
+Thu Sep 19 15:34:17 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * gencode.c (MIPS_DECODE): Set UNSIGNED for multu instruction.
+ (process_instructions): Correct handling of nor instruction.
+ Correct shift count for 32 bit shift instructions. Correct sign
+ extension for arithmetic shifts to not shift the number of bits in
+ the type. Fix 64 bit multiply high word calculation. Fix 32 bit
+ unsigned multiply. Fix ldxc1 and friends to use coprocessor 1.
+ Fix madd.
+ * interp.c (CHECKHILO): Don't set HIACCESS, LOACCESS, or HLPC.
+ It's OK to have a mult follow a mult. What's not OK is to have a
+ mult follow an mfhi.
+ (Convert): Comment out incorrect rounding code.
+
+Mon Sep 16 11:38:16 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * interp.c (sim_monitor): Improved monitor printf
+ simulation. Tidied up simulator warnings, and added "--log" option
+ for directing warning message output.
+ * gencode.c: Use sim_warning() rather than WARNING macro.
+
+Thu Aug 22 15:03:12 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (gencode): Depend upon gencode.o, getopt.o, and
+ getopt1.o, rather than on gencode.c. Link objects together.
+ Don't link against -liberty.
+ (gencode.o, getopt.o, getopt1.o): New targets.
+ * gencode.c: Include <ctype.h> and "ansidecl.h".
+ (AND): Undefine after including "ansidecl.h".
+ (ULONG_MAX): Define if not defined.
+ (OP_*): Don't define macros; now defined in opcode/mips.h.
+ (main): Call my_strtoul rather than strtoul.
+ (my_strtoul): New static function.
+
+Wed Jul 17 18:12:38 1996 Stu Grossman (grossman@critters.cygnus.com)
+
+ * gencode.c (process_instructions): Generate word64 and uword64
+ instead of `long long' and `unsigned long long' data types.
+ * interp.c: #include sysdep.h to get signals, and define default
+ for SIGBUS.
+ * (Convert): Work around for Visual-C++ compiler bug with type
+ conversion.
+ * support.h: Make things compile under Visual-C++ by using
+ __int64 instead of `long long'. Change many refs to long long
+ into word64/uword64 typedefs.
+
+Wed Jun 26 12:24:55 1996 Jason Molenda (crash@godzilla.cygnus.co.jp)
+
+ * Makefile.in (bindir, libdir, datadir, mandir, infodir, includedir,
+ INSTALL_PROGRAM, INSTALL_DATA): Use autoconf-set values.
+ (docdir): Removed.
+ * configure.in (AC_PREREQ): autoconf 2.5 or higher.
+ (AC_PROG_INSTALL): Added.
+ (AC_PROG_CC): Moved to before configure.host call.
+ * configure: Rebuilt.
+
+Wed Jun 5 08:28:13 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * configure.in: Define @SIMCONF@ depending on mips target.
+ * configure: Rebuild.
+ * Makefile.in (run): Add @SIMCONF@ to control simulator
+ construction.
+ * gencode.c: Change LOADDRMASK to 64bit memory model only.
+ * interp.c: Remove some debugging, provide more detailed error
+ messages, update memory accesses to use LOADDRMASK.
+
+Mon Jun 3 11:55:03 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure.in: Add calls to AC_CONFIG_HEADER, AC_CHECK_HEADERS,
+ AC_CHECK_LIB, and AC_CHECK_FUNCS. Change AC_OUTPUT to set
+ stamp-h.
+ * configure: Rebuild.
+ * config.in: New file, generated by autoheader.
+ * interp.c: Include "config.h". Include <stdlib.h>, <string.h>,
+ and <strings.h> if they exist. Replace #ifdef sun with #ifdef
+ HAVE_ANINT and HAVE_AINT, as appropriate.
+ * Makefile.in (run): Use @LIBS@ rather than -lm.
+ (interp.o): Depend upon config.h.
+ (Makefile): Just rebuild Makefile.
+ (clean): Remove stamp-h.
+ (mostlyclean): Make the same as clean, not as distclean.
+ (config.h, stamp-h): New targets.
+
+Fri May 10 00:41:17 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * interp.c (ColdReset): Fix boolean test. Make all simulator
+ globals static.
+
+Wed May 8 15:12:58 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * interp.c (xfer_direct_word, xfer_direct_long,
+ swap_direct_word, swap_direct_long, xfer_big_word,
+ xfer_big_long, xfer_little_word, xfer_little_long,
+ swap_word,swap_long): Added.
+ * interp.c (ColdReset): Provide function indirection to
+ host<->simulated_target transfer routines.
+ * interp.c (sim_store_register, sim_fetch_register): Updated to
+ make use of indirected transfer routines.
+
+Fri Apr 19 15:48:24 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * gencode.c (process_instructions): Ensure FP ABS instruction
+ recognised.
+ * interp.c (AbsoluteValue): Add routine. Also provide simple PMON
+ system call support.
+
+Wed Apr 10 09:51:38 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * interp.c (sim_do_command): Complain if callback structure not
+ initialised.
+
+Thu Mar 28 13:50:51 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * interp.c (Convert): Provide round-to-nearest and round-to-zero
+ support for Sun hosts.
+ * Makefile.in (gencode): Ensure the host compiler and libraries
+ used for cross-hosted build.
+
+Wed Mar 27 14:42:12 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * interp.c, gencode.c: Some more (TODO) tidying.
+
+Thu Mar 7 11:19:33 1996 James G. Smith <jsmith@cygnus.co.uk>
+
+ * gencode.c, interp.c: Replaced explicit long long references with
+ WORD64HI, WORD64LO, SET64HI and SET64LO macro calls.
+ * support.h (SET64LO, SET64HI): Macros added.
+
+Wed Feb 21 12:16:21 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * configure: Regenerate with autoconf 2.7.
+
+Tue Jan 30 08:48:18 1996 Fred Fish <fnf@cygnus.com>
+
+ * interp.c (LoadMemory): Enclose text following #endif in /* */.
+ * support.h: Remove superfluous "1" from #if.
+ * support.h (CHECKSIM): Remove stray 'a' at end of line.
+
+Mon Dec 4 11:44:40 1995 Jamie Smith <jsmith@cygnus.com>
+
+ * interp.c (StoreFPR): Control UndefinedResult() call on
+ WARN_RESULT manifest.
+
+Fri Dec 1 16:37:19 1995 James G. Smith <jsmith@cygnus.co.uk>
+
+ * gencode.c: Tidied instruction decoding, and added FP instruction
+ support.
+
+ * interp.c: Added dineroIII, and BSD profiling support. Also
+ run-time FP handling.
+
+Sun Oct 22 00:57:18 1995 James G. Smith <jsmith@pasanda.cygnus.co.uk>
+
+ * Changelog, Makefile.in, README.Cygnus, configure, configure.in,
+ gencode.c, interp.c, support.h: created.
diff --git a/sim/mips/Makefile.in b/sim/mips/Makefile.in
new file mode 100644
index 0000000..3e4bd5f
--- /dev/null
+++ b/sim/mips/Makefile.in
@@ -0,0 +1,293 @@
+# Makefile template for Configure for the MIPS simulator.
+# Written by Cygnus Support.
+
+## COMMON_PRE_CONFIG_FRAG
+
+srcdir=@srcdir@
+srcroot=$(srcdir)/../../
+
+# Object files created by various simulator generators.
+
+
+SIM_IGEN_OBJ = \
+ support.o \
+ itable.o \
+ semantics.o \
+ idecode.o \
+ icache.o \
+ @mips_igen_engine@ \
+ irun.o \
+
+
+SIM_M16_OBJ = \
+ m16_support.o \
+ m16_semantics.o \
+ m16_idecode.o \
+ m16_icache.o \
+ \
+ m32_support.o \
+ m32_semantics.o \
+ m32_idecode.o \
+ m32_icache.o \
+ \
+ itable.o \
+ m16run.o \
+
+
+MIPS_EXTRA_OBJS = @mips_extra_objs@
+MIPS_EXTRA_LIBS = @mips_extra_libs@
+
+SIM_OBJS = \
+ $(SIM_@sim_gen@_OBJ) \
+ $(SIM_NEW_COMMON_OBJS) \
+ $(MIPS_EXTRA_OBJS) \
+ interp.o \
+ sim-main.o \
+ sim-hload.o \
+ sim-engine.o \
+ sim-stop.o \
+ sim-resume.o \
+ sim-reason.o \
+
+
+# List of flags to always pass to $(CC).
+SIM_SUBTARGET=@SIM_SUBTARGET@
+SIM_EXTRA_CFLAGS = $(SIM_SUBTARGET)
+
+SIM_EXTRA_CLEAN = clean-extra
+
+SIM_EXTRA_ALL = $(SIM_@sim_gen@_ALL)
+
+SIM_EXTRA_LIBS = $(MIPS_EXTRA_LIBS)
+
+# List of main object files for `run'.
+SIM_RUN_OBJS = nrun.o
+
+
+
+## COMMON_POST_CONFIG_FRAG
+
+interp.o: $(srcdir)/interp.c config.h sim-main.h itable.h
+
+
+../igen/igen:
+ cd ../igen && $(MAKE)
+
+IGEN_TRACE= # -G omit-line-numbers # -G trace-rule-selection -G trace-rule-rejection -G trace-entries # -G trace-all
+IGEN_INSN=$(srcdir)/mips.igen
+IGEN_DC=$(srcdir)/mips.dc
+M16_DC=$(srcdir)/m16.dc
+IGEN_INCLUDE=\
+ $(srcdir)/m16.igen \
+ $(srcdir)/tx.igen \
+ $(srcdir)/vr.igen \
+
+# NB: Since these can be built by a number of generators, care
+# must be taken to ensure that they are only dependant on
+# one of those generators.
+BUILT_SRC_FROM_GEN = \
+ itable.h \
+ itable.c \
+
+SIM_IGEN_ALL = tmp-igen
+SIM_M16_ALL = tmp-m16
+
+$(BUILT_SRC_FROM_GEN): $(SIM_@sim_gen@_ALL)
+
+
+
+BUILT_SRC_FROM_IGEN = \
+ icache.h \
+ icache.c \
+ idecode.h \
+ idecode.c \
+ semantics.h \
+ semantics.c \
+ model.h \
+ model.c \
+ support.h \
+ support.c \
+ engine.h \
+ engine.c \
+ irun.c \
+
+$(BUILT_SRC_FROM_IGEN): tmp-igen
+
+tmp-igen: $(IGEN_INSN) $(IGEN_DC) ../igen/igen $(IGEN_INCLUDE)
+ cd ../igen && $(MAKE)
+ ../igen/igen \
+ $(IGEN_TRACE) \
+ -I $(srcdir) \
+ -Werror \
+ -Wnodiscard \
+ @sim_igen_flags@ \
+ -G gen-direct-access \
+ -G gen-zero-r0 \
+ -B 32 \
+ -H 31 \
+ -i $(IGEN_INSN) \
+ -o $(IGEN_DC) \
+ -x \
+ -n icache.h -hc tmp-icache.h \
+ -n icache.c -c tmp-icache.c \
+ -n semantics.h -hs tmp-semantics.h \
+ -n semantics.c -s tmp-semantics.c \
+ -n idecode.h -hd tmp-idecode.h \
+ -n idecode.c -d tmp-idecode.c \
+ -n model.h -hm tmp-model.h \
+ -n model.c -m tmp-model.c \
+ -n support.h -hf tmp-support.h \
+ -n support.c -f tmp-support.c \
+ -n itable.h -ht tmp-itable.h \
+ -n itable.c -t tmp-itable.c \
+ -n engine.h -he tmp-engine.h \
+ -n engine.c -e tmp-engine.c \
+ -n irun.c -r tmp-irun.c
+ $(srcdir)/../../move-if-change tmp-icache.h icache.h
+ $(srcdir)/../../move-if-change tmp-icache.c icache.c
+ $(srcdir)/../../move-if-change tmp-idecode.h idecode.h
+ $(srcdir)/../../move-if-change tmp-idecode.c idecode.c
+ $(srcdir)/../../move-if-change tmp-semantics.h semantics.h
+ $(srcdir)/../../move-if-change tmp-semantics.c semantics.c
+ $(srcdir)/../../move-if-change tmp-model.h model.h
+ $(srcdir)/../../move-if-change tmp-model.c model.c
+ $(srcdir)/../../move-if-change tmp-support.h support.h
+ $(srcdir)/../../move-if-change tmp-support.c support.c
+ $(srcdir)/../../move-if-change tmp-itable.h itable.h
+ $(srcdir)/../../move-if-change tmp-itable.c itable.c
+ $(srcdir)/../../move-if-change tmp-engine.h engine.h
+ $(srcdir)/../../move-if-change tmp-engine.c engine.c
+ $(srcdir)/../../move-if-change tmp-irun.c irun.c
+ touch tmp-igen
+
+semantics.o: sim-main.h semantics.c $(SIM_EXTRA_DEPS)
+engine.o: sim-main.h engine.c $(SIM_EXTRA_DEPS)
+support.o: sim-main.h support.c $(SIM_EXTRA_DEPS)
+idecode.o: sim-main.h idecode.c $(SIM_EXTRA_DEPS)
+itable.o: sim-main.h itable.c $(SIM_EXTRA_DEPS)
+
+
+
+
+BUILT_SRC_FROM_M16 = \
+ m16_icache.h \
+ m16_icache.c \
+ m16_idecode.h \
+ m16_idecode.c \
+ m16_semantics.h \
+ m16_semantics.c \
+ m16_model.h \
+ m16_model.c \
+ m16_support.h \
+ m16_support.c \
+ \
+ m32_icache.h \
+ m32_icache.c \
+ m32_idecode.h \
+ m32_idecode.c \
+ m32_semantics.h \
+ m32_semantics.c \
+ m32_model.h \
+ m32_model.c \
+ m32_support.h \
+ m32_support.c \
+
+$(BUILT_SRC_FROM_M16): tmp-m16
+
+tmp-m16: $(IGEN_INSN) $(IGEN_DC) ../igen/igen $(IGEN_INCLUDE)
+ cd ../igen && $(MAKE)
+ ../igen/igen \
+ $(IGEN_TRACE) \
+ -I $(srcdir) \
+ -Werror \
+ -Wnodiscard \
+ @sim_m16_flags@ \
+ -G gen-direct-access \
+ -G gen-zero-r0 \
+ -B 16 \
+ -H 15 \
+ -i $(IGEN_INSN) \
+ -o $(M16_DC) \
+ -P m16_ \
+ -x \
+ -n m16_icache.h -hc tmp-icache.h \
+ -n m16_icache.c -c tmp-icache.c \
+ -n m16_semantics.h -hs tmp-semantics.h \
+ -n m16_semantics.c -s tmp-semantics.c \
+ -n m16_idecode.h -hd tmp-idecode.h \
+ -n m16_idecode.c -d tmp-idecode.c \
+ -n m16_model.h -hm tmp-model.h \
+ -n m16_model.c -m tmp-model.c \
+ -n m16_support.h -hf tmp-support.h \
+ -n m16_support.c -f tmp-support.c \
+ #
+ $(srcdir)/../../move-if-change tmp-icache.h m16_icache.h
+ $(srcdir)/../../move-if-change tmp-icache.c m16_icache.c
+ $(srcdir)/../../move-if-change tmp-idecode.h m16_idecode.h
+ $(srcdir)/../../move-if-change tmp-idecode.c m16_idecode.c
+ $(srcdir)/../../move-if-change tmp-semantics.h m16_semantics.h
+ $(srcdir)/../../move-if-change tmp-semantics.c m16_semantics.c
+ $(srcdir)/../../move-if-change tmp-model.h m16_model.h
+ $(srcdir)/../../move-if-change tmp-model.c m16_model.c
+ $(srcdir)/../../move-if-change tmp-support.h m16_support.h
+ $(srcdir)/../../move-if-change tmp-support.c m16_support.c
+ ../igen/igen \
+ $(IGEN_TRACE) \
+ -I $(srcdir) \
+ -Werror \
+ -Wnodiscard \
+ @sim_igen_flags@ \
+ -G gen-direct-access \
+ -G gen-zero-r0 \
+ -B 32 \
+ -H 31 \
+ -i $(IGEN_INSN) \
+ -o $(IGEN_DC) \
+ -P m32_ \
+ -x \
+ -n m32_icache.h -hc tmp-icache.h \
+ -n m32_icache.c -c tmp-icache.c \
+ -n m32_semantics.h -hs tmp-semantics.h \
+ -n m32_semantics.c -s tmp-semantics.c \
+ -n m32_idecode.h -hd tmp-idecode.h \
+ -n m32_idecode.c -d tmp-idecode.c \
+ -n m32_model.h -hm tmp-model.h \
+ -n m32_model.c -m tmp-model.c \
+ -n m32_support.h -hf tmp-support.h \
+ -n m32_support.c -f tmp-support.c \
+ #
+ $(srcdir)/../../move-if-change tmp-icache.h m32_icache.h
+ $(srcdir)/../../move-if-change tmp-icache.c m32_icache.c
+ $(srcdir)/../../move-if-change tmp-idecode.h m32_idecode.h
+ $(srcdir)/../../move-if-change tmp-idecode.c m32_idecode.c
+ $(srcdir)/../../move-if-change tmp-semantics.h m32_semantics.h
+ $(srcdir)/../../move-if-change tmp-semantics.c m32_semantics.c
+ $(srcdir)/../../move-if-change tmp-model.h m32_model.h
+ $(srcdir)/../../move-if-change tmp-model.c m32_model.c
+ $(srcdir)/../../move-if-change tmp-support.h m32_support.h
+ $(srcdir)/../../move-if-change tmp-support.c m32_support.c
+ ../igen/igen \
+ $(IGEN_TRACE) \
+ -I $(srcdir) \
+ -Werror \
+ -Wnodiscard \
+ -Wnowidth \
+ @sim_igen_flags@ @sim_m16_flags@ \
+ -G gen-direct-access \
+ -G gen-zero-r0 \
+ -i $(IGEN_INSN) \
+ -n itable.h -ht tmp-itable.h \
+ -n itable.c -t tmp-itable.c \
+ #
+ $(srcdir)/../../move-if-change tmp-itable.h itable.h
+ $(srcdir)/../../move-if-change tmp-itable.c itable.c
+ touch tmp-m16
+
+
+clean-extra:
+ rm -f $(BUILT_SRC_FROM_GEN)
+ rm -f $(BUILT_SRC_FROM_IGEN)
+ rm -f $(BUILT_SRC_FROM_M16)
+ rm -f tmp-*
+ rm -f m16* m32* itable*
+
diff --git a/sim/mips/acconfig.h b/sim/mips/acconfig.h
new file mode 100644
index 0000000..f9b87a1
--- /dev/null
+++ b/sim/mips/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/mips/config.in b/sim/mips/config.in
new file mode 100644
index 0000000..dbd6508
--- /dev/null
+++ b/sim/mips/config.in
@@ -0,0 +1,174 @@
+/* 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 if your processor stores words with the most significant
+ byte first (like Motorola and SPARC, unlike Intel and VAX). */
+#undef WORDS_BIGENDIAN
+
+/* 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 aint function. */
+#undef HAVE_AINT
+
+/* Define if you have the anint function. */
+#undef HAVE_ANINT
+
+/* 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 sqrt function. */
+#undef HAVE_SQRT
+
+/* 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
+
+/* Define if you have the m library (-lm). */
+#undef HAVE_LIBM
diff --git a/sim/mips/configure b/sim/mips/configure
new file mode 100755
index 0000000..58be065
--- /dev/null
+++ b/sim/mips/configure
@@ -0,0 +1,4890 @@
+#! /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"
+ac_help="$ac_help
+ --enable-sim-inline=inlines Specify which functions should be inlined."
+ac_help="$ac_help
+ --enable-sim-alignment=align Specify strict, nonstrict or forced alignment of memory accesses."
+ac_help="$ac_help
+ --enable-sim-hostendian=end Specify host byte endian orientation."
+ac_help="$ac_help
+ --enable-build-warnings[=LIST] Enable build-time compiler warnings"
+ac_help="$ac_help
+ --enable-sim-endian=endian Specify target byte endian orientation."
+ac_help="$ac_help
+ --enable-sim-bitsize=N Specify target bitsize (32 or 64)."
+ac_help="$ac_help
+ --enable-sim-float Specify that the target processor has floating point hardware."
+ac_help="$ac_help
+ --enable-sim-smp=n Specify number of processors to configure for (default ${default_sim_smp})."
+ac_help="$ac_help
+ --enable-sim-hardware=LIST Specify the hardware to be included in the build."
+ac_help="$ac_help
+ --with-x use the X Window System"
+ac_help="$ac_help
+ --with-sim-gpu2=path Use GPU2 library under given directory"
+ac_help="$ac_help
+ --with-x use the X Window System"
+ac_help="$ac_help
+ --with-sim-funit=path Use target FP library under given directory"
+
+# 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:705: 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 720 "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:726: \"$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 737 "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:743: \"$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 754 "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:760: \"$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:785: 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:812: 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:833: 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 838 "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:846: \"$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 863 "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 881 "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 902 "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:913: \"$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:937: 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 942 "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:991: \"$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:1012: 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 1019 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:1026: \"$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:1052: 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 1057 "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:1085: 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 1090 "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:1120: 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 1125 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int main() {
+char *p = alloca(2 * sizeof(int));
+; return 0; }
+EOF
+if { (eval echo configure:1132: \"$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:1153: 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 1158 "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:1186: \"$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:1218: 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 1223 "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:1248: 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 1253 "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:1276: \"$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:1303: 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 1311 "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:1330: \"$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:1355: 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 1360 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1365: \"$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:1394: 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 1399 "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:1422: \"$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:1447: 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 1455 "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:1595: \"$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:1668: 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:1689: 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:1707: 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:1751: 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:1780: 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:1830: 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:1861: 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 1871 "configure"
+#include "confdefs.h"
+main(){return(0);}
+EOF
+if { (eval echo configure:1875: \"$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:1895: 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:1900: 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:1909: \"$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:1928: 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:1971: 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:2037: 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:2071: 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 2076 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2081: \"$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:2111: 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 2116 "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:2139: \"$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:2168: 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 2173 "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:2196: \"$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:2230: 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 2235 "configure"
+#include "confdefs.h"
+#include <locale.h>
+int main() {
+return LC_MESSAGES
+; return 0; }
+EOF
+if { (eval echo configure:2242: \"$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:2263: 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:2283: 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:2302: 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 2307 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2312: \"$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:2329: 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 2334 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:2341: \"$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:2357: 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 2365 "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:2376: \"$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:2392: 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 2397 "configure"
+#include "confdefs.h"
+
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:2404: \"$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:2432: 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:2466: 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 2471 "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:2494: \"$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:2521: 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:2556: 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 2588 "configure"
+#include "confdefs.h"
+
+int main() {
+extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr
+; return 0; }
+EOF
+if { (eval echo configure:2596: \"$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:2628: 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:2662: 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:2697: 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:2787: 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:2815: 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 2820 "configure"
+#include "confdefs.h"
+#include <linux/version.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2825: \"$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:2894: 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 2899 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2904: \"$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:2934: 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 2939 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2944: \"$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:2974: 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 2979 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2984: \"$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 dlfcn.h errno.h sys/stat.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:3014: 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 3019 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3024: \"$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:3053: 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 3058 "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:3081: \"$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:3108: 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 3116 "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:3127: \"$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:3155: 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 3163 "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:3174: \"$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:3350: 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 3355 "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:3372: \"$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:3392: 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"
+
+
+
+
+default_sim_inline=""
+# Check whether --enable-sim-inline or --disable-sim-inline was given.
+if test "${enable_sim_inline+set}" = set; then
+ enableval="$enable_sim_inline"
+ sim_inline=""
+case "$enableval" in
+ no) sim_inline="-DDEFAULT_INLINE=0";;
+ 0) sim_inline="-DDEFAULT_INLINE=0";;
+ yes | 2) sim_inline="-DDEFAULT_INLINE=ALL_C_INLINE";;
+ 1) sim_inline="-DDEFAULT_INLINE=INLINE_LOCALS";;
+ *) for x in `echo "$enableval" | sed -e "s/,/ /g"`; do
+ new_flag=""
+ case "$x" in
+ *_INLINE=*) new_flag="-D$x";;
+ *=*) new_flag=`echo "$x" | sed -e "s/=/_INLINE=/" -e "s/^/-D/"`;;
+ *_INLINE) new_flag="-D$x=ALL_C_INLINE";;
+ *) new_flag="-D$x""_INLINE=ALL_C_INLINE";;
+ esac
+ if test x"$sim_inline" = x""; then
+ sim_inline="$new_flag"
+ else
+ sim_inline="$sim_inline $new_flag"
+ fi
+ done;;
+esac
+if test x"$silent" != x"yes" && test x"$sim_inline" != x""; then
+ echo "Setting inline flags = $sim_inline" 6>&1
+fi
+else
+
+if test "x$cross_compiling" = "xno"; then
+ if test x"$GCC" != "x" -a x"${default_sim_inline}" != "x" ; then
+ sim_inline="${default_sim_inline}"
+ if test x"$silent" != x"yes"; then
+ echo "Setting inline flags = $sim_inline" 6>&1
+ fi
+ else
+ sim_inline=""
+ fi
+else
+ sim_inline="-DDEFAULT_INLINE=0"
+fi
+fi
+
+wire_alignment="NONSTRICT_ALIGNMENT"
+default_alignment=""
+
+# Check whether --enable-sim-alignment or --disable-sim-alignment was given.
+if test "${enable_sim_alignment+set}" = set; then
+ enableval="$enable_sim_alignment"
+ case "${enableval}" in
+ strict | STRICT) sim_alignment="-DWITH_ALIGNMENT=STRICT_ALIGNMENT";;
+ nonstrict | NONSTRICT) sim_alignment="-DWITH_ALIGNMENT=NONSTRICT_ALIGNMENT";;
+ forced | FORCED) sim_alignment="-DWITH_ALIGNMENT=FORCED_ALIGNMENT";;
+ yes) if test x"$wire_alignment" != x; then
+ sim_alignment="-DWITH_ALIGNMENT=${wire_alignment}"
+ else
+ if test x"$default_alignment" != x; then
+ sim_alignment="-DWITH_ALIGNMENT=${default_alignment}"
+ else
+ echo "No hard-wired alignment for target $target" 1>&6
+ sim_alignment="-DWITH_ALIGNMENT=0"
+ fi
+ fi;;
+ no) if test x"$default_alignment" != x; then
+ sim_alignment="-DWITH_DEFAULT_ALIGNMENT=${default_alignment}"
+ else
+ if test x"$wire_alignment" != x; then
+ sim_alignment="-DWITH_DEFAULT_ALIGNMENT=${wire_alignment}"
+ else
+ echo "No default alignment for target $target" 1>&6
+ sim_alignment="-DWITH_DEFAULT_ALIGNMENT=0"
+ fi
+ fi;;
+ *) { echo "configure: error: "Unknown value $enableval passed to --enable-sim-alignment"" 1>&2; exit 1; }; sim_alignment="";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_alignment" != x""; then
+ echo "Setting alignment flags = $sim_alignment" 6>&1
+fi
+else
+ if test x"$default_alignment" != x; then
+ sim_alignment="-DWITH_DEFAULT_ALIGNMENT=${default_alignment}"
+else
+ if test x"$wire_alignment" != x; then
+ sim_alignment="-DWITH_ALIGNMENT=${wire_alignment}"
+ else
+ sim_alignment=
+ fi
+fi
+fi
+
+
+# Check whether --enable-sim-hostendian or --disable-sim-hostendian was given.
+if test "${enable_sim_hostendian+set}" = set; then
+ enableval="$enable_sim_hostendian"
+ case "${enableval}" in
+ no) sim_hostendian="-DWITH_HOST_BYTE_ORDER=0";;
+ b*|B*) sim_hostendian="-DWITH_HOST_BYTE_ORDER=BIG_ENDIAN";;
+ l*|L*) sim_hostendian="-DWITH_HOST_BYTE_ORDER=LITTLE_ENDIAN";;
+ *) { echo "configure: error: "Unknown value $enableval for --enable-sim-hostendian"" 1>&2; exit 1; }; sim_hostendian="";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_hostendian" != x""; then
+ echo "Setting hostendian flags = $sim_hostendian" 6>&1
+fi
+else
+
+if test "x$cross_compiling" = "xno"; then
+ echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
+echo "configure:3545: checking whether byte ordering is bigendian" >&5
+if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_bigendian=unknown
+# See if sys/param.h defines the BYTE_ORDER macro.
+cat > conftest.$ac_ext <<EOF
+#line 3552 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:3563: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+cat > conftest.$ac_ext <<EOF
+#line 3567 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:3578: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_bigendian=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_bigendian=no
+fi
+rm -f conftest*
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+if test $ac_cv_c_bigendian = unknown; then
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3598 "configure"
+#include "confdefs.h"
+main () {
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long l;
+ char c[sizeof (long)];
+ } u;
+ u.l = 1;
+ exit (u.c[sizeof (long) - 1] == 1);
+}
+EOF
+if { (eval echo configure:3611: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_bigendian=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_bigendian=yes
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_c_bigendian" 1>&6
+if test $ac_cv_c_bigendian = yes; then
+ cat >> confdefs.h <<\EOF
+#define WORDS_BIGENDIAN 1
+EOF
+
+fi
+
+ if test $ac_cv_c_bigendian = yes; then
+ sim_hostendian="-DWITH_HOST_BYTE_ORDER=BIG_ENDIAN"
+ else
+ sim_hostendian="-DWITH_HOST_BYTE_ORDER=LITTLE_ENDIAN"
+ fi
+else
+ sim_hostendian="-DWITH_HOST_BYTE_ORDER=0"
+fi
+fi
+
+
+# Check whether --enable-build-warnings or --disable-build-warnings was given.
+if test "${enable_build_warnings+set}" = set; then
+ enableval="$enable_build_warnings"
+ build_warnings="-Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations"
+case "${enableval}" in
+ yes) ;;
+ no) build_warnings="-w";;
+ ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+ build_warnings="${build_warnings} ${t}";;
+ *,) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+ build_warnings="${t} ${build_warnings}";;
+ *) build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+esac
+if test x"$silent" != x"yes" && test x"$build_warnings" != x""; then
+ echo "Setting warning flags = $build_warnings" 6>&1
+fi
+else
+ build_warnings=""
+fi
+
+
+# DEPRECATED
+#
+# Instead of defining a `subtarget' macro, code should be checking
+# the value of {STATE,CPU}_ARCHITECTURE to identify the architecture
+# in question.
+#
+case "${target}" in
+ mips*tx39*) SIM_SUBTARGET="-DSUBTARGET_R3900=1";;
+ *) SIM_SUBTARGET="";;
+esac
+
+
+
+
+#
+# Select the byte order of the target
+#
+mips_endian=
+default_endian=
+case "${target}" in
+ mips64el*-*-*) mips_endian=LITTLE_ENDIAN ;;
+ mips64*-*-*) default_endian=BIG_ENDIAN ;;
+ mips16*-*-*) default_endian=BIG_ENDIAN ;;
+ mips*-*-*) default_endian=BIG_ENDIAN ;;
+ *) default_endian=BIG_ENDIAN ;;
+esac
+
+wire_endian="$mips_endian"
+default_endian="$default_endian"
+# Check whether --enable-sim-endian or --disable-sim-endian was given.
+if test "${enable_sim_endian+set}" = set; then
+ enableval="$enable_sim_endian"
+ case "${enableval}" in
+ b*|B*) sim_endian="-DWITH_TARGET_BYTE_ORDER=BIG_ENDIAN";;
+ l*|L*) sim_endian="-DWITH_TARGET_BYTE_ORDER=LITTLE_ENDIAN";;
+ yes) if test x"$wire_endian" != x; then
+ sim_endian="-DWITH_TARGET_BYTE_ORDER=${wire_endian}"
+ else
+ if test x"$default_endian" != x; then
+ sim_endian="-DWITH_TARGET_BYTE_ORDER=${default_endian}"
+ else
+ echo "No hard-wired endian for target $target" 1>&6
+ sim_endian="-DWITH_TARGET_BYTE_ORDER=0"
+ fi
+ fi;;
+ no) if test x"$default_endian" != x; then
+ sim_endian="-DWITH_DEFAULT_TARGET_BYTE_ORDER=${default_endian}"
+ else
+ if test x"$wire_endian" != x; then
+ sim_endian="-DWITH_DEFAULT_TARGET_BYTE_ORDER=${wire_endian}"
+ else
+ echo "No default endian for target $target" 1>&6
+ sim_endian="-DWITH_DEFAULT_TARGET_BYTE_ORDER=0"
+ fi
+ fi;;
+ *) { echo "configure: error: "Unknown value $enableval for --enable-sim-endian"" 1>&2; exit 1; }; sim_endian="";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_endian" != x""; then
+ echo "Setting endian flags = $sim_endian" 6>&1
+fi
+else
+ if test x"$default_endian" != x; then
+ sim_endian="-DWITH_DEFAULT_TARGET_BYTE_ORDER=${default_endian}"
+else
+ if test x"$wire_endian" != x; then
+ sim_endian="-DWITH_TARGET_BYTE_ORDER=${wire_endian}"
+ else
+ sim_endian=
+ fi
+fi
+fi
+
+
+
+
+#
+# Select the bitsize of the target
+#
+mips_addr_bitsize=
+case "${target}" in
+ mips64*-*-*) mips_bitsize=64 ; mips_msb=63 ;;
+ mips16*-*-*) mips_bitsize=64 ; mips_msb=63 ;;
+ mips*-*-*) mips_bitsize=32 ; mips_msb=31 ;;
+ *) mips_bitsize=64 ; mips_msb=63 ;;
+esac
+wire_word_bitsize="$mips_bitsize"
+wire_word_msb="$mips_msb"
+wire_address_bitsize="$mips_addr_bitsize"
+wire_cell_bitsize=""
+# Check whether --enable-sim-bitsize or --disable-sim-bitsize was given.
+if test "${enable_sim_bitsize+set}" = set; then
+ enableval="$enable_sim_bitsize"
+ sim_bitsize=
+case "${enableval}" in
+ 64,63 | 64,63,* ) sim_bitsize="-DWITH_TARGET_WORD_BITSIZE=64 -DWITH_TARGET_WORD_MSB=63";;
+ 32,31 | 32,31,* ) sim_bitsize="-DWITH_TARGET_WORD_BITSIZE=32 -DWITH_TARGET_WORD_MSB=31";;
+ 64,0 | 64,0,* ) sim_bitsize="-DWITH_TARGET_WORD_BITSIZE=32 -DWITH_TARGET_WORD_MSB=0";;
+ 32,0 | 64,0,* ) sim_bitsize="-DWITH_TARGET_WORD_BITSIZE=32 -DWITH_TARGET_WORD_MSB=0";;
+ 32) if test x"$wire_word_msb" != x -a x"$wire_word_msb" != x0; then
+ sim_bitsize="-DWITH_TARGET_WORD_BITSIZE=32 -DWITH_TARGET_WORD_MSB=31"
+ else
+ sim_bitsize="-DWITH_TARGET_WORD_BITSIZE=32 -DWITH_TARGET_WORD_MSB=0"
+ fi ;;
+ 64) if test x"$wire_word_msb" != x -a x"$wire_word_msb" != x0; then
+ sim_bitsize="-DWITH_TARGET_WORD_BITSIZE=64 -DWITH_TARGET_WORD_MSB=63"
+ else
+ sim_bitsize="-DWITH_TARGET_WORD_BITSIZE=64 -DWITH_TARGET_WORD_MSB=0"
+ fi ;;
+ *) { echo "configure: error: "--enable-sim-bitsize was given $enableval. Expected 32 or 64"" 1>&2; exit 1; } ;;
+esac
+# address bitsize
+tmp=`echo "${enableval}" | sed -e "s/^[0-9]*,*[0-9]*,*//"`
+case x"${tmp}" in
+ x ) ;;
+ x32 | x32,* ) sim_bitsize="${sim_bitsize} -DWITH_TARGET_ADDRESS_BITSIZE=32" ;;
+ x64 | x64,* ) sim_bitsize="${sim_bitsize} -DWITH_TARGET_ADDRESS_BITSIZE=64" ;;
+ * ) { echo "configure: error: "--enable-sim-bitsize was given address size $enableval. Expected 32 or 64"" 1>&2; exit 1; } ;;
+esac
+# cell bitsize
+tmp=`echo "${enableval}" | sed -e "s/^[0-9]*,*[0-9*]*,*[0-9]*,*//"`
+case x"${tmp}" in
+ x ) ;;
+ x32 | x32,* ) sim_bitsize="${sim_bitsize} -DWITH_TARGET_CELL_BITSIZE=32" ;;
+ x64 | x64,* ) sim_bitsize="${sim_bitsize} -DWITH_TARGET_CELL_BITSIZE=64" ;;
+ * ) { echo "configure: error: "--enable-sim-bitsize was given cell size $enableval. Expected 32 or 64"" 1>&2; exit 1; } ;;
+esac
+if test x"$silent" != x"yes" && test x"$sim_bitsize" != x""; then
+ echo "Setting bitsize flags = $sim_bitsize" 6>&1
+fi
+else
+ sim_bitsize=""
+if test x"$wire_word_bitsize" != x; then
+ sim_bitsize="$sim_bitsize -DWITH_TARGET_WORD_BITSIZE=$wire_word_bitsize"
+fi
+if test x"$wire_word_msb" != x; then
+ sim_bitsize="$sim_bitsize -DWITH_TARGET_WORD_MSB=$wire_word_msb"
+fi
+if test x"$wire_address_bitsize" != x; then
+ sim_bitsize="$sim_bitsize -DWITH_TARGET_ADDRESS_BITSIZE=$wire_address_bitsize"
+fi
+if test x"$wire_cell_bitsize" != x; then
+ sim_bitsize="$sim_bitsize -DWITH_TARGET_CELL_BITSIZE=$wire_cell_bitsize"
+fi
+fi
+
+
+
+
+#
+# Select the floating hardware support of the target
+#
+mips_fpu=HARDWARE_FLOATING_POINT
+mips_fpu_bitsize=
+case "${target}" in
+ mips*tx39*) mips_fpu=HARD_FLOATING_POINT
+ mips_fpu_bitsize=32
+ ;;
+ mips64*-*-*) mips_fpu=HARD_FLOATING_POINT ;;
+ mips16*-*-*) mips_fpu=HARD_FLOATING_POINT ;;
+ mips*-*-*) mips_fpu=HARD_FLOATING_POINT ; mips_fpu_bitsize=32 ;;
+ *) mips_fpu=HARD_FLOATING_POINT ;;
+esac
+
+default_sim_float="$mips_fpu"
+default_sim_float_bitsize="$mips_fpu_bitsize"
+# Check whether --enable-sim-float or --disable-sim-float was given.
+if test "${enable_sim_float+set}" = set; then
+ enableval="$enable_sim_float"
+ case "${enableval}" in
+ yes | hard) sim_float="-DWITH_FLOATING_POINT=HARD_FLOATING_POINT";;
+ no | soft) sim_float="-DWITH_FLOATING_POINT=SOFT_FLOATING_POINT";;
+ 32) sim_float="-DWITH_FLOATING_POINT=HARD_FLOATING_POINT -DWITH_TARGET_FLOATING_POINT_BITSIZE=32";;
+ 64) sim_float="-DWITH_FLOATING_POINT=HARD_FLOATING_POINT -DWITH_TARGET_FLOATING_POINT_BITSIZE=64";;
+ *) { echo "configure: error: "Unknown value $enableval passed to --enable-sim-float"" 1>&2; exit 1; }; sim_float="";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_float" != x""; then
+ echo "Setting float flags = $sim_float" 6>&1
+fi
+else
+
+sim_float=
+if test x"${default_sim_float}" != x""; then
+ sim_float="-DWITH_FLOATING_POINT=${default_sim_float}"
+fi
+if test x"${default_sim_float_bitsize}" != x""; then
+ sim_float="$sim_float -DWITH_TARGET_FLOATING_POINT_BITSIZE=${default_sim_float_bitsize}"
+fi
+
+fi
+
+
+
+
+#
+# Select the level of SMP support
+#
+case "${target}" in
+ *) mips_smp=0 ;;
+esac
+
+default_sim_smp="$mips_smp"
+# Check whether --enable-sim-smp or --disable-sim-smp was given.
+if test "${enable_sim_smp+set}" = set; then
+ enableval="$enable_sim_smp"
+ case "${enableval}" in
+ yes) sim_smp="-DWITH_SMP=5" ; sim_igen_smp="-N 5";;
+ no) sim_smp="-DWITH_SMP=0" ; sim_igen_smp="-N 0";;
+ *) sim_smp="-DWITH_SMP=$enableval" ; sim_igen_smp="-N $enableval";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_smp" != x""; then
+ echo "Setting smp flags = $sim_smp" 6>&1
+fi
+else
+ sim_smp="-DWITH_SMP=${default_sim_smp}" ; sim_igen_smp="-N ${default_sim_smp}"
+if test x"$silent" != x"yes"; then
+ echo "Setting smp flags = $sim_smp" 6>&1
+fi
+fi
+
+
+
+
+#
+# Select the IGEN architecture
+#
+sim_gen=IGEN
+sim_igen_machine="-M mipsIV"
+sim_m16_machine="-M mips16"
+sim_igen_filter="32,64,f"
+sim_m16_filter="16"
+case "${target}" in
+ mips*tx39*) sim_gen=IGEN
+ sim_igen_filter="32,f"
+ sim_igen_machine="-M r3900"
+ ;;
+ mips64vr43*-*-*) sim_gen=IGEN
+ sim_igen_machine="-M mipsIV"
+ ;;
+ mips64vr5*-*-*) sim_gen=IGEN
+ sim_igen_machine="-M vr5000"
+ ;;
+ mips64vr41*) sim_gen=M16
+ sim_igen_machine="-M vr4100"
+ sim_m16_machine="-M vr4100"
+ sim_igen_filter="32,64,f"
+ sim_m16_filter="16"
+ ;;
+ mips64*-*-*) sim_igen_filter="32,64,f"
+ sim_gen=IGEN
+ ;;
+ mips16*-*-*) sim_gen=M16
+ sim_igen_filter="32,64,f"
+ sim_m16_filter="16"
+ ;;
+ mips*lsi*) sim_gen=M16
+ sim_igen_machine="-M mipsIII,mips16"
+ sim_m16_machine="-M mips16,mipsIII"
+ sim_igen_filter="32,f"
+ sim_m16_filter="16"
+ ;;
+ mips*-*-*) sim_gen=IGEN
+ sim_igen_filter="32,f"
+ ;;
+esac
+sim_igen_flags="-F ${sim_igen_filter} ${sim_igen_machine} ${sim_igen_smp}"
+sim_m16_flags=" -F ${sim_m16_filter} ${sim_m16_machine} ${sim_igen_smp}"
+
+
+
+
+
+#
+# Add simulated hardware devices
+#
+hw_enabled=no
+case "${target}" in
+ mips*tx39*)
+ hw_enabled=yes
+ hw_extra_devices="tx3904cpu tx3904irc tx3904tmr tx3904sio"
+ mips_extra_objs="dv-sockser.o"
+ SIM_SUBTARGET="$SIM_SUBTARGET -DTARGET_TX3904=1"
+ ;;
+ *)
+ mips_extra_objs=""
+ ;;
+esac
+
+if test x"$hw_enabled" = x"yes"; then
+ sim_hw_p=yes
+else
+ sim_hw_p=no
+fi
+if test "$hw_devices"; then
+ hardware="core pal glue"
+else
+ hardware="core pal glue $hw_extra_devices"
+fi
+sim_hw_cflags="-DWITH_HW=1"
+sim_hw="$hardware"
+sim_hw_objs="\$(SIM_COMMON_HW_OBJS) `echo $sim_hw | sed -e 's/\([^ ][^ ]*\)/dv-\1.o/g'`"
+# Check whether --enable-sim-hardware or --disable-sim-hardware was given.
+if test "${enable_sim_hardware+set}" = set; then
+ enableval="$enable_sim_hardware"
+
+case "${enableval}" in
+ yes) sim_hw_p=yes;;
+ no) sim_hw_p=no;;
+ ,*) sim_hw_p=yes; hardware="${hardware} `echo ${enableval} | sed -e 's/,/ /'`";;
+ *,) sim_hw_p=yes; hardware="`echo ${enableval} | sed -e 's/,/ /'` ${hardware}";;
+ *) sim_hw_p=yes; hardware="`echo ${enableval} | sed -e 's/,/ /'`"'';;
+esac
+if test "$sim_hw_p" != yes; then
+ sim_hw_objs=
+ sim_hw_cflags="-DWITH_HW=0"
+ sim_hw=
+else
+ sim_hw_cflags="-DWITH_HW=1"
+ # remove duplicates
+ sim_hw=""
+ sim_hw_objs="\$(SIM_COMMON_HW_OBJS)"
+ for i in x $hardware ; do
+ case " $f " in
+ x) ;;
+ *" $i "*) ;;
+ *) sim_hw="$sim_hw $i" ; sim_hw_objs="$sim_hw_objs dv-$i.o";;
+ esac
+ done
+fi
+if test x"$silent" != x"yes" && test "$sim_hw_p" = "yes"; then
+ echo "Setting hardware to $sim_hw_cflags, $sim_hw, $sim_hw_objs"
+fi
+else
+
+if test "$sim_hw_p" != yes; then
+ sim_hw_objs=
+ sim_hw_cflags="-DWITH_HW=0"
+ sim_hw=
+fi
+if test x"$silent" != x"yes"; then
+ echo "Setting hardware to $sim_hw_cflags, $sim_hw, $sim_hw_objs"
+fi
+fi
+
+
+
+
+# Choose simulator engine
+case "${target}" in
+ *) mips_igen_engine="engine.o"
+ ;;
+esac
+
+
+
+# If we find X, set shell vars x_includes and x_libraries to the
+# paths, otherwise set no_x=yes.
+# Uses ac_ vars as temps to allow command line to override cache and checks.
+# --without-x overrides everything else, but does not touch the cache.
+echo $ac_n "checking for X""... $ac_c" 1>&6
+echo "configure:4125: checking for X" >&5
+
+# Check whether --with-x or --without-x was given.
+if test "${with_x+set}" = set; then
+ withval="$with_x"
+ :
+fi
+
+# $have_x is `yes', `no', `disabled', or empty when we do not yet know.
+if test "x$with_x" = xno; then
+ # The user explicitly disabled X.
+ have_x=disabled
+else
+ if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then
+ # Both variables are already set.
+ have_x=yes
+ else
+if eval "test \"`echo '$''{'ac_cv_have_x'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # One or both of the vars are not set, and there is no cached value.
+ac_x_includes=NO ac_x_libraries=NO
+rm -fr conftestdir
+if mkdir conftestdir; then
+ cd conftestdir
+ # Make sure to not put "make" in the Imakefile rules, since we grep it out.
+ cat > Imakefile <<'EOF'
+acfindx:
+ @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"'
+EOF
+ if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then
+ # GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+ eval `${MAKE-make} acfindx 2>/dev/null | grep -v make`
+ # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR.
+ for ac_extension in a so sl; do
+ if test ! -f $ac_im_usrlibdir/libX11.$ac_extension &&
+ test -f $ac_im_libdir/libX11.$ac_extension; then
+ ac_im_usrlibdir=$ac_im_libdir; break
+ fi
+ done
+ # Screen out bogus values from the imake configuration. They are
+ # bogus both because they are the default anyway, and because
+ # using them would break gcc on systems where it needs fixed includes.
+ case "$ac_im_incroot" in
+ /usr/include) ;;
+ *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes="$ac_im_incroot" ;;
+ esac
+ case "$ac_im_usrlibdir" in
+ /usr/lib | /lib) ;;
+ *) test -d "$ac_im_usrlibdir" && ac_x_libraries="$ac_im_usrlibdir" ;;
+ esac
+ fi
+ cd ..
+ rm -fr conftestdir
+fi
+
+if test "$ac_x_includes" = NO; then
+ # Guess where to find include files, by looking for this one X11 .h file.
+ test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h
+
+ # First, try using that file with no special directory specified.
+cat > conftest.$ac_ext <<EOF
+#line 4187 "configure"
+#include "confdefs.h"
+#include <$x_direct_test_include>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4192: \"$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*
+ # We can compile using X headers with no special include directory.
+ac_x_includes=
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ # Look for the header file in a standard set of common directories.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+ for ac_dir in \
+ /usr/X11/include \
+ /usr/X11R6/include \
+ /usr/X11R5/include \
+ /usr/X11R4/include \
+ \
+ /usr/include/X11 \
+ /usr/include/X11R6 \
+ /usr/include/X11R5 \
+ /usr/include/X11R4 \
+ \
+ /usr/local/X11/include \
+ /usr/local/X11R6/include \
+ /usr/local/X11R5/include \
+ /usr/local/X11R4/include \
+ \
+ /usr/local/include/X11 \
+ /usr/local/include/X11R6 \
+ /usr/local/include/X11R5 \
+ /usr/local/include/X11R4 \
+ \
+ /usr/X386/include \
+ /usr/x386/include \
+ /usr/XFree86/include/X11 \
+ \
+ /usr/include \
+ /usr/local/include \
+ /usr/unsupported/include \
+ /usr/athena/include \
+ /usr/local/x11r5/include \
+ /usr/lpp/Xamples/include \
+ \
+ /usr/openwin/include \
+ /usr/openwin/share/include \
+ ; \
+ do
+ if test -r "$ac_dir/$x_direct_test_include"; then
+ ac_x_includes=$ac_dir
+ break
+ fi
+ done
+fi
+rm -f conftest*
+fi # $ac_x_includes = NO
+
+if test "$ac_x_libraries" = NO; then
+ # Check for the libraries.
+
+ test -z "$x_direct_test_library" && x_direct_test_library=Xt
+ test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc
+
+ # See if we find them without any special options.
+ # Don't add to $LIBS permanently.
+ ac_save_LIBS="$LIBS"
+ LIBS="-l$x_direct_test_library $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4261 "configure"
+#include "confdefs.h"
+
+int main() {
+${x_direct_test_function}()
+; return 0; }
+EOF
+if { (eval echo configure:4268: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ LIBS="$ac_save_LIBS"
+# We can link X programs with no special library path.
+ac_x_libraries=
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ LIBS="$ac_save_LIBS"
+# First see if replacing the include by lib works.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+for ac_dir in `echo "$ac_x_includes" | sed s/include/lib/` \
+ /usr/X11/lib \
+ /usr/X11R6/lib \
+ /usr/X11R5/lib \
+ /usr/X11R4/lib \
+ \
+ /usr/lib/X11 \
+ /usr/lib/X11R6 \
+ /usr/lib/X11R5 \
+ /usr/lib/X11R4 \
+ \
+ /usr/local/X11/lib \
+ /usr/local/X11R6/lib \
+ /usr/local/X11R5/lib \
+ /usr/local/X11R4/lib \
+ \
+ /usr/local/lib/X11 \
+ /usr/local/lib/X11R6 \
+ /usr/local/lib/X11R5 \
+ /usr/local/lib/X11R4 \
+ \
+ /usr/X386/lib \
+ /usr/x386/lib \
+ /usr/XFree86/lib/X11 \
+ \
+ /usr/lib \
+ /usr/local/lib \
+ /usr/unsupported/lib \
+ /usr/athena/lib \
+ /usr/local/x11r5/lib \
+ /usr/lpp/Xamples/lib \
+ /lib/usr/lib/X11 \
+ \
+ /usr/openwin/lib \
+ /usr/openwin/share/lib \
+ ; \
+do
+ for ac_extension in a so sl; do
+ if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then
+ ac_x_libraries=$ac_dir
+ break 2
+ fi
+ done
+done
+fi
+rm -f conftest*
+fi # $ac_x_libraries = NO
+
+if test "$ac_x_includes" = NO || test "$ac_x_libraries" = NO; then
+ # Didn't find X anywhere. Cache the known absence of X.
+ ac_cv_have_x="have_x=no"
+else
+ # Record where we found X for the cache.
+ ac_cv_have_x="have_x=yes \
+ ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries"
+fi
+fi
+ fi
+ eval "$ac_cv_have_x"
+fi # $with_x != no
+
+if test "$have_x" != yes; then
+ echo "$ac_t""$have_x" 1>&6
+ no_x=yes
+else
+ # If each of the values was on the command line, it overrides each guess.
+ test "x$x_includes" = xNONE && x_includes=$ac_x_includes
+ test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries
+ # Update the cache value to reflect the command line values.
+ ac_cv_have_x="have_x=yes \
+ ac_x_includes=$x_includes ac_x_libraries=$x_libraries"
+ echo "$ac_t""libraries $x_libraries, headers $x_includes" 1>&6
+fi
+
+mips_extra_libs=""
+
+
+for ac_hdr in string.h strings.h stdlib.h stdlib.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:5155: 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 5160 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:5165: \"$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 fabs in -lm""... $ac_c" 1>&6
+echo "configure:5192: checking for fabs in -lm" >&5
+ac_lib_var=`echo m'_'fabs | 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="-lm $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5200 "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 fabs();
+
+int main() {
+fabs()
+; return 0; }
+EOF
+if { (eval echo configure:5211: \"$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 m | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lm $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+for ac_func in aint anint sqrt
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:5241: 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 5246 "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:5269: \"$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
+
+
+
+
+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%@SIM_SUBTARGET@%$SIM_SUBTARGET%g
+s%@sim_igen_flags@%$sim_igen_flags%g
+s%@sim_m16_flags@%$sim_m16_flags%g
+s%@sim_gen@%$sim_gen%g
+s%@mips_extra_objs@%$mips_extra_objs%g
+s%@mips_igen_engine@%$mips_igen_engine%g
+s%@mips_extra_libs@%$mips_extra_libs%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/mips/configure.in b/sim/mips/configure.in
new file mode 100644
index 0000000..89959fe
--- /dev/null
+++ b/sim/mips/configure.in
@@ -0,0 +1,170 @@
+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
+
+dnl Options available in this module
+SIM_AC_OPTION_INLINE()
+SIM_AC_OPTION_ALIGNMENT(NONSTRICT_ALIGNMENT)
+SIM_AC_OPTION_HOSTENDIAN
+SIM_AC_OPTION_WARNINGS
+
+# DEPRECATED
+#
+# Instead of defining a `subtarget' macro, code should be checking
+# the value of {STATE,CPU}_ARCHITECTURE to identify the architecture
+# in question.
+#
+case "${target}" in
+ mips*tx39*) SIM_SUBTARGET="-DSUBTARGET_R3900=1";;
+ *) SIM_SUBTARGET="";;
+esac
+AC_SUBST(SIM_SUBTARGET)
+
+
+
+#
+# Select the byte order of the target
+#
+mips_endian=
+default_endian=
+case "${target}" in
+ mips64el*-*-*) mips_endian=LITTLE_ENDIAN ;;
+ mips64*-*-*) default_endian=BIG_ENDIAN ;;
+ mips16*-*-*) default_endian=BIG_ENDIAN ;;
+ mips*-*-*) default_endian=BIG_ENDIAN ;;
+ *) default_endian=BIG_ENDIAN ;;
+esac
+SIM_AC_OPTION_ENDIAN($mips_endian,$default_endian)
+
+
+
+#
+# Select the bitsize of the target
+#
+mips_addr_bitsize=
+case "${target}" in
+ mips64*-*-*) mips_bitsize=64 ; mips_msb=63 ;;
+ mips16*-*-*) mips_bitsize=64 ; mips_msb=63 ;;
+ mips*-*-*) mips_bitsize=32 ; mips_msb=31 ;;
+ *) mips_bitsize=64 ; mips_msb=63 ;;
+esac
+SIM_AC_OPTION_BITSIZE($mips_bitsize,$mips_msb,$mips_addr_bitsize)
+
+
+
+#
+# Select the floating hardware support of the target
+#
+mips_fpu=HARDWARE_FLOATING_POINT
+mips_fpu_bitsize=
+case "${target}" in
+ mips*tx39*) mips_fpu=HARD_FLOATING_POINT
+ mips_fpu_bitsize=32
+ ;;
+ mips64*-*-*) mips_fpu=HARD_FLOATING_POINT ;;
+ mips16*-*-*) mips_fpu=HARD_FLOATING_POINT ;;
+ mips*-*-*) mips_fpu=HARD_FLOATING_POINT ; mips_fpu_bitsize=32 ;;
+ *) mips_fpu=HARD_FLOATING_POINT ;;
+esac
+SIM_AC_OPTION_FLOAT($mips_fpu,$mips_fpu_bitsize)
+
+
+
+#
+# Select the level of SMP support
+#
+case "${target}" in
+ *) mips_smp=0 ;;
+esac
+SIM_AC_OPTION_SMP($mips_smp)
+
+
+
+#
+# Select the IGEN architecture
+#
+sim_gen=IGEN
+sim_igen_machine="-M mipsIV"
+sim_m16_machine="-M mips16"
+sim_igen_filter="32,64,f"
+sim_m16_filter="16"
+case "${target}" in
+ mips*tx39*) sim_gen=IGEN
+ sim_igen_filter="32,f"
+ sim_igen_machine="-M r3900"
+ ;;
+ mips64vr43*-*-*) sim_gen=IGEN
+ sim_igen_machine="-M mipsIV"
+ ;;
+ mips64vr5*-*-*) sim_gen=IGEN
+ sim_igen_machine="-M vr5000"
+ ;;
+ mips64vr41*) sim_gen=M16
+ sim_igen_machine="-M vr4100"
+ sim_m16_machine="-M vr4100"
+ sim_igen_filter="32,64,f"
+ sim_m16_filter="16"
+ ;;
+ mips64*-*-*) sim_igen_filter="32,64,f"
+ sim_gen=IGEN
+ ;;
+ mips16*-*-*) sim_gen=M16
+ sim_igen_filter="32,64,f"
+ sim_m16_filter="16"
+ ;;
+ mips*lsi*) sim_gen=M16
+ sim_igen_machine="-M mipsIII,mips16"
+ sim_m16_machine="-M mips16,mipsIII"
+ sim_igen_filter="32,f"
+ sim_m16_filter="16"
+ ;;
+ mips*-*-*) sim_gen=IGEN
+ sim_igen_filter="32,f"
+ ;;
+esac
+sim_igen_flags="-F ${sim_igen_filter} ${sim_igen_machine} ${sim_igen_smp}"
+sim_m16_flags=" -F ${sim_m16_filter} ${sim_m16_machine} ${sim_igen_smp}"
+AC_SUBST(sim_igen_flags)
+AC_SUBST(sim_m16_flags)
+AC_SUBST(sim_gen)
+
+
+#
+# Add simulated hardware devices
+#
+hw_enabled=no
+case "${target}" in
+ mips*tx39*)
+ hw_enabled=yes
+ hw_extra_devices="tx3904cpu tx3904irc tx3904tmr tx3904sio"
+ mips_extra_objs="dv-sockser.o"
+ SIM_SUBTARGET="$SIM_SUBTARGET -DTARGET_TX3904=1"
+ ;;
+ *)
+ mips_extra_objs=""
+ ;;
+esac
+SIM_AC_OPTION_HARDWARE($hw_enabled,$hw_devices,$hw_extra_devices)
+AC_SUBST(mips_extra_objs)
+
+
+# Choose simulator engine
+case "${target}" in
+ *) mips_igen_engine="engine.o"
+ ;;
+esac
+AC_SUBST(mips_igen_engine)
+
+
+AC_PATH_X
+mips_extra_libs=""
+AC_SUBST(mips_extra_libs)
+
+AC_CHECK_HEADERS(string.h strings.h stdlib.h stdlib.h)
+AC_CHECK_LIB(m, fabs)
+AC_CHECK_FUNCS(aint anint sqrt)
+
+SIM_AC_OUTPUT
diff --git a/sim/mips/dv-tx3904cpu.c b/sim/mips/dv-tx3904cpu.c
new file mode 100644
index 0000000..07b8521
--- /dev/null
+++ b/sim/mips/dv-tx3904cpu.c
@@ -0,0 +1,246 @@
+/* This file is part of the program GDB, the GNU debugger.
+
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+
+#include "sim-main.h"
+#include "hw-main.h"
+
+/* DEVICE
+
+
+ tx3904cpu - tx3904 cpu virtual device
+
+
+ DESCRIPTION
+
+
+ Implements the external tx3904 functionality. This includes the
+ delivery of of interrupts generated from other devices and the
+ handling of device specific registers.
+
+
+ PROPERTIES
+
+ none
+
+
+ PORTS
+
+
+ reset (input)
+
+ Currently ignored.
+
+
+ nmi (input)
+
+ Deliver a non-maskable interrupt to the processor.
+
+
+ level (input)
+
+ Deliver a maskable interrupt of given level, corresponding to
+ IP[5:0], to processor.
+
+
+
+ BUGS
+
+
+ When delivering an interrupt, this code assumes that there is only
+ one processor (number 0).
+
+ This code does not attempt to be efficient at handling pending
+ interrupts. It simply schedules the interrupt delivery handler
+ every instruction cycle until all pending interrupts go away. An
+ alternative implementation might modify instructions that change
+ the PSW and have them check to see if the change makes an interrupt
+ delivery possible.
+
+ */
+
+
+
+struct tx3904cpu {
+ /* Pending interrupts for delivery by event handler */
+ int pending_reset, pending_nmi, pending_level;
+ struct hw_event* event;
+};
+
+
+
+/* input port ID's */
+
+enum {
+ RESET_PORT,
+ NMI_PORT,
+ LEVEL_PORT,
+};
+
+
+static const struct hw_port_descriptor tx3904cpu_ports[] = {
+
+ /* interrupt inputs */
+ { "reset", RESET_PORT, 0, input_port, },
+ { "nmi", NMI_PORT, 0, input_port, },
+ { "level", LEVEL_PORT, 0, input_port, },
+
+ { NULL, },
+};
+
+
+/* Finish off the partially created hw device. Attach our local
+ callbacks. Wire up our port names etc */
+
+static hw_port_event_method tx3904cpu_port_event;
+
+
+
+static void
+tx3904cpu_finish (struct hw *me)
+{
+ struct tx3904cpu *controller;
+
+ controller = HW_ZALLOC (me, struct tx3904cpu);
+ set_hw_data (me, controller);
+ set_hw_ports (me, tx3904cpu_ports);
+ set_hw_port_event (me, tx3904cpu_port_event);
+
+ /* Initialize the pending interrupt flags */
+ controller->pending_level = 0;
+ controller->pending_reset = 0;
+ controller->pending_nmi = 0;
+ controller->event = NULL;
+}
+
+
+
+/* An event arrives on an interrupt port */
+
+static void
+deliver_tx3904cpu_interrupt (struct hw *me,
+ void *data)
+{
+ struct tx3904cpu *controller = hw_data (me);
+ SIM_DESC sd = hw_system (me);
+ sim_cpu *cpu = STATE_CPU (sd, 0); /* NB: fix CPU 0. */
+ address_word cia = CIA_GET (cpu);
+
+#define CPU cpu
+#define SD current_state
+
+ if (controller->pending_reset)
+ {
+ controller->pending_reset = 0;
+ HW_TRACE ((me, "reset pc=0x%08lx", (long) CIA_GET (cpu)));
+ SignalExceptionNMIReset();
+ }
+ else if (controller->pending_nmi)
+ {
+ controller->pending_nmi = 0;
+ HW_TRACE ((me, "nmi pc=0x%08lx", (long) CIA_GET (cpu)));
+ SignalExceptionNMIReset();
+ }
+ else if (controller->pending_level)
+ {
+ HW_TRACE ((me, "interrupt level=%d pc=0x%08lx sr=0x%08lx",
+ controller->pending_level,
+ (long) CIA_GET (cpu), (long) SR));
+
+ /* Clear CAUSE register. It may stay this way if the interrupt
+ was cleared with a negative pending_level. */
+ CAUSE &= ~ (cause_IP_mask << cause_IP_shift);
+
+ if(controller->pending_level > 0) /* interrupt set */
+ {
+ /* set hardware-interrupt subfields of CAUSE register */
+ CAUSE |= (controller->pending_level & cause_IP_mask) << cause_IP_shift;
+
+ /* check for enabled / unmasked interrupts */
+ if((SR & status_IEc) &&
+ (controller->pending_level & ((SR >> status_IM_shift) & status_IM_mask)))
+ {
+ controller->pending_level = 0;
+ SignalExceptionInterrupt(0 /* dummy value */);
+ }
+ else
+ {
+ /* reschedule soon */
+ if(controller->event != NULL)
+ hw_event_queue_deschedule(me, controller->event);
+ controller->event =
+ hw_event_queue_schedule (me, 1, deliver_tx3904cpu_interrupt, NULL);
+ }
+ } /* interrupt set */
+ }
+#undef CPU cpu
+#undef SD current_state
+}
+
+
+static void
+tx3904cpu_port_event (struct hw *me,
+ int my_port,
+ struct hw *source,
+ int source_port,
+ int level)
+{
+ struct tx3904cpu *controller = hw_data (me);
+
+ switch (my_port)
+ {
+ case RESET_PORT:
+ controller->pending_reset = 1;
+ HW_TRACE ((me, "port-in reset"));
+ break;
+
+ case NMI_PORT:
+ controller->pending_nmi = 1;
+ HW_TRACE ((me, "port-in nmi"));
+ break;
+
+ case LEVEL_PORT:
+ /* level == 0 means that the interrupt was cleared */
+ if(level == 0)
+ controller->pending_level = -1; /* signal end of interrupt */
+ else
+ controller->pending_level = level;
+ HW_TRACE ((me, "port-in level=%d", level));
+ break;
+
+ default:
+ hw_abort (me, "bad switch");
+ break;
+ }
+
+ /* Schedule an event to be delivered immediately after current
+ instruction. */
+ if(controller->event != NULL)
+ hw_event_queue_deschedule(me, controller->event);
+ controller->event =
+ hw_event_queue_schedule (me, 0, deliver_tx3904cpu_interrupt, NULL);
+}
+
+
+const struct hw_descriptor dv_tx3904cpu_descriptor[] = {
+ { "tx3904cpu", tx3904cpu_finish, },
+ { NULL },
+};
diff --git a/sim/mips/dv-tx3904irc.c b/sim/mips/dv-tx3904irc.c
new file mode 100644
index 0000000..8b84e5c
--- /dev/null
+++ b/sim/mips/dv-tx3904irc.c
@@ -0,0 +1,413 @@
+/* This file is part of the program GDB, the GNU debugger.
+
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+
+#include "sim-main.h"
+#include "hw-main.h"
+
+
+/* DEVICE
+
+
+ tx3904irc - tx3904 interrupt controller
+
+
+ DESCRIPTION
+
+
+ Implements the tx3904 interrupt controller described in the tx3904
+ user guide. It does not include the interrupt detection circuit
+ that preprocesses the eight external interrupts, so assumes that
+ each event on an input interrupt port signals a new interrupt.
+ That is, it implements edge- rather than level-triggered
+ interrupts.
+
+ This implementation does not support multiple concurrent
+ interrupts.
+
+
+ PROPERTIES
+
+
+ reg <base> <length>
+
+ Base of IRC control register bank. <length> must equal 0x20.
+ Registers offsets: 0: ISR: interrupt status register
+ 4: IMR: interrupt mask register
+ 16: ILR0: interrupt level register 3..0
+ 20: ILR1: interrupt level register 7..4
+ 24: ILR2: interrupt level register 11..8
+ 28: ILR3: interrupt level register 15..12
+
+
+
+ PORTS
+
+
+ ip (output)
+
+ Interrupt priority port. An event is generated when an interrupt
+ of a sufficient priority is passed through the IRC. The value
+ associated with the event is the interrupt level (16-31), as given
+ for bits IP[5:0] in the book TMPR3904F Rev. 2.0, pg. 11-3. Note
+ that even though INT[0] is tied externally to IP[5], we simulate
+ it as passing through the controller.
+
+ An output level of zero signals the clearing of a level interrupt.
+
+
+ int0-7 (input)
+
+ External interrupts. Level = 0 -> level interrupt cleared.
+
+
+ dmac0-3 (input)
+
+ DMA internal interrupts, correspond to DMA channels 0-3. Level = 0 -> level interrupt cleared.
+
+
+ sio0-1 (input)
+
+ SIO internal interrupts. Level = 0 -> level interrupt cleared.
+
+
+ tmr0-2 (input)
+
+ Timer internal interrupts. Level = 0 -> level interrupt cleared.
+
+ */
+
+
+
+
+
+/* register numbers; each is one word long */
+enum
+{
+ ISR_REG = 0,
+ IMR_REG = 1,
+ ILR0_REG = 4,
+ ILR1_REG = 5,
+ ILR2_REG = 6,
+ ILR3_REG = 7,
+};
+
+
+/* port ID's */
+
+enum
+{
+ /* inputs, ordered to correspond to interrupt sources 0..15 */
+ INT1_PORT = 0, INT2_PORT, INT3_PORT, INT4_PORT, INT5_PORT, INT6_PORT, INT7_PORT,
+ DMAC3_PORT, DMAC2_PORT, DMAC1_PORT, DMAC0_PORT, SIO0_PORT, SIO1_PORT,
+ TMR0_PORT, TMR1_PORT, TMR2_PORT,
+
+ /* special INT[0] port */
+ INT0_PORT,
+
+ /* reset */
+ RESET_PORT,
+
+ /* output */
+ IP_PORT
+};
+
+
+static const struct hw_port_descriptor tx3904irc_ports[] = {
+
+ /* interrupt output */
+
+ { "ip", IP_PORT, 0, output_port, },
+
+ /* interrupt inputs (as names) */
+ /* in increasing order of level number */
+
+ { "int1", INT1_PORT, 0, input_port, },
+ { "int2", INT2_PORT, 0, input_port, },
+ { "int3", INT3_PORT, 0, input_port, },
+ { "int4", INT4_PORT, 0, input_port, },
+ { "int5", INT5_PORT, 0, input_port, },
+ { "int6", INT6_PORT, 0, input_port, },
+ { "int7", INT7_PORT, 0, input_port, },
+
+ { "dmac3", DMAC3_PORT, 0, input_port, },
+ { "dmac2", DMAC2_PORT, 0, input_port, },
+ { "dmac1", DMAC1_PORT, 0, input_port, },
+ { "dmac0", DMAC0_PORT, 0, input_port, },
+
+ { "sio0", SIO0_PORT, 0, input_port, },
+ { "sio1", SIO1_PORT, 0, input_port, },
+
+ { "tmr0", TMR0_PORT, 0, input_port, },
+ { "tmr1", TMR1_PORT, 0, input_port, },
+ { "tmr2", TMR2_PORT, 0, input_port, },
+
+ { "reset", RESET_PORT, 0, input_port, },
+ { "int0", INT0_PORT, 0, input_port, },
+
+ { NULL, },
+};
+
+
+#define NR_SOURCES (TMR3_PORT - INT1_PORT + 1) /* 16: number of interrupt sources */
+
+
+/* The interrupt controller register internal state. Note that we
+ store state using the control register images, in host endian
+ order. */
+
+struct tx3904irc {
+ address_word base_address; /* control register base */
+ unsigned_4 isr;
+#define ISR_SET(c,s) ((c)->isr &= ~ (1 << (s)))
+ unsigned_4 imr;
+#define IMR_GET(c) ((c)->imr)
+ unsigned_4 ilr[4];
+#define ILR_GET(c,s) LSEXTRACTED32((c)->ilr[(s)/4], (s) % 4 * 8 + 2, (s) % 4 * 8)
+};
+
+
+
+/* Finish off the partially created hw device. Attach our local
+ callbacks. Wire up our port names etc */
+
+static hw_io_read_buffer_method tx3904irc_io_read_buffer;
+static hw_io_write_buffer_method tx3904irc_io_write_buffer;
+static hw_port_event_method tx3904irc_port_event;
+
+static void
+attach_tx3904irc_regs (struct hw *me,
+ struct tx3904irc *controller)
+{
+ unsigned_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain one addr/size entry");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space,
+ &attach_address,
+ me);
+ hw_unit_size_to_attach_size (hw_parent (me),
+ &reg.size,
+ &attach_size, me);
+
+ hw_attach_address (hw_parent (me), 0,
+ attach_space, attach_address, attach_size,
+ me);
+
+ controller->base_address = attach_address;
+}
+
+
+static void
+tx3904irc_finish (struct hw *me)
+{
+ struct tx3904irc *controller;
+
+ controller = HW_ZALLOC (me, struct tx3904irc);
+ set_hw_data (me, controller);
+ set_hw_io_read_buffer (me, tx3904irc_io_read_buffer);
+ set_hw_io_write_buffer (me, tx3904irc_io_write_buffer);
+ set_hw_ports (me, tx3904irc_ports);
+ set_hw_port_event (me, tx3904irc_port_event);
+
+ /* Attach ourself to our parent bus */
+ attach_tx3904irc_regs (me, controller);
+
+ /* Initialize to reset state */
+ controller->isr = 0x0000ffff;
+ controller->imr = 0;
+ controller->ilr[0] =
+ controller->ilr[1] =
+ controller->ilr[2] =
+ controller->ilr[3] = 0;
+}
+
+
+
+/* An event arrives on an interrupt port */
+
+static void
+tx3904irc_port_event (struct hw *me,
+ int my_port,
+ struct hw *source_dev,
+ int source_port,
+ int level)
+{
+ struct tx3904irc *controller = hw_data (me);
+
+ /* handle deactivated interrupt */
+ if(level == 0)
+ {
+ HW_TRACE ((me, "interrupt cleared on port %d", my_port));
+ hw_port_event(me, IP_PORT, 0);
+ return;
+ }
+
+ switch (my_port)
+ {
+ case INT0_PORT:
+ {
+ int ip_number = 32; /* compute IP[5:0] */
+ HW_TRACE ((me, "port-event INT[0]"));
+ hw_port_event(me, IP_PORT, ip_number);
+ break;
+ }
+
+ case INT1_PORT: case INT2_PORT: case INT3_PORT: case INT4_PORT:
+ case INT5_PORT: case INT6_PORT: case INT7_PORT: case DMAC3_PORT:
+ case DMAC2_PORT: case DMAC1_PORT: case DMAC0_PORT: case SIO0_PORT:
+ case SIO1_PORT: case TMR0_PORT: case TMR1_PORT: case TMR2_PORT:
+ {
+ int source = my_port - INT1_PORT;
+
+ HW_TRACE ((me, "interrupt asserted on port %d", source));
+ ISR_SET(controller, source);
+ if(ILR_GET(controller, source) > IMR_GET(controller))
+ {
+ int ip_number = 16 + source; /* compute IP[4:0] */
+ HW_TRACE ((me, "interrupt level %d", ILR_GET(controller,source)));
+ hw_port_event(me, IP_PORT, ip_number);
+ }
+ break;
+ }
+
+ case RESET_PORT:
+ {
+ HW_TRACE ((me, "reset"));
+ controller->isr = 0x0000ffff;
+ controller->imr = 0;
+ controller->ilr[0] =
+ controller->ilr[1] =
+ controller->ilr[2] =
+ controller->ilr[3] = 0;
+ break;
+ }
+
+ case IP_PORT:
+ hw_abort (me, "Event on output port %d", my_port);
+ break;
+
+ default:
+ hw_abort (me, "Event on unknown port %d", my_port);
+ break;
+ }
+}
+
+
+/* generic read/write */
+
+static unsigned
+tx3904irc_io_read_buffer (struct hw *me,
+ void *dest,
+ int space,
+ unsigned_word base,
+ unsigned nr_bytes)
+{
+ struct tx3904irc *controller = hw_data (me);
+ unsigned byte;
+
+ HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));
+ for (byte = 0; byte < nr_bytes; byte++)
+ {
+ address_word address = base + byte;
+ int reg_number = (address - controller->base_address) / 4;
+ int reg_offset = (address - controller->base_address) % 4;
+ unsigned_4 register_value; /* in target byte order */
+
+ /* fill in entire register_value word */
+ switch (reg_number)
+ {
+ case ISR_REG: register_value = controller->isr; break;
+ case IMR_REG: register_value = controller->imr; break;
+ case ILR0_REG: register_value = controller->ilr[0]; break;
+ case ILR1_REG: register_value = controller->ilr[1]; break;
+ case ILR2_REG: register_value = controller->ilr[2]; break;
+ case ILR3_REG: register_value = controller->ilr[3]; break;
+ default: register_value = 0;
+ }
+
+ /* write requested byte out */
+ register_value = H2T_4(register_value);
+ memcpy ((char*) dest + byte, ((char*)& register_value)+reg_offset, 1);
+ }
+
+ return nr_bytes;
+}
+
+
+
+static unsigned
+tx3904irc_io_write_buffer (struct hw *me,
+ const void *source,
+ int space,
+ unsigned_word base,
+ unsigned nr_bytes)
+{
+ struct tx3904irc *controller = hw_data (me);
+ unsigned byte;
+
+ HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes));
+ for (byte = 0; byte < nr_bytes; byte++)
+ {
+ address_word address = base + byte;
+ int reg_number = (address - controller->base_address) / 4;
+ int reg_offset = (address - controller->base_address) % 4;
+ unsigned_4* register_ptr;
+ unsigned_4 register_value;
+
+ /* fill in entire register_value word */
+ switch (reg_number)
+ {
+ case ISR_REG: register_ptr = & controller->isr; break;
+ case IMR_REG: register_ptr = & controller->imr; break;
+ case ILR0_REG: register_ptr = & controller->ilr[0]; break;
+ case ILR1_REG: register_ptr = & controller->ilr[1]; break;
+ case ILR2_REG: register_ptr = & controller->ilr[2]; break;
+ case ILR3_REG: register_ptr = & controller->ilr[3]; break;
+ default: register_ptr = & register_value; /* used as a dummy */
+ }
+
+ /* HW_TRACE ((me, "reg %d pre: %08lx", reg_number, (long) *register_ptr)); */
+
+ /* overwrite requested byte */
+ register_value = H2T_4(* register_ptr);
+ memcpy (((char*)&register_value)+reg_offset, (const char*)source + byte, 1);
+ * register_ptr = T2H_4(register_value);
+
+ /* HW_TRACE ((me, "post: %08lx", (long) *register_ptr)); */
+ }
+ return nr_bytes;
+}
+
+
+const struct hw_descriptor dv_tx3904irc_descriptor[] = {
+ { "tx3904irc", tx3904irc_finish, },
+ { NULL },
+};
diff --git a/sim/mips/dv-tx3904sio.c b/sim/mips/dv-tx3904sio.c
new file mode 100644
index 0000000..a1e3ddb
--- /dev/null
+++ b/sim/mips/dv-tx3904sio.c
@@ -0,0 +1,621 @@
+/* This file is part of the program GDB, the GNU debugger.
+
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+
+#include "sim-main.h"
+#include "hw-main.h"
+#include "dv-sockser.h"
+#include "sim-assert.h"
+
+
+/* DEVICE
+
+
+ tx3904sio - tx3904 serial I/O
+
+
+ DESCRIPTION
+
+
+ Implements one tx3904 serial I/O controller described in the tx3904
+ user guide. Three instances are required for SIO0 and SIO1 within
+ the tx3904, at different base addresses.
+
+ Both internal and system clocks are synthesized as divided versions
+ of the simulator clock.
+
+ There is no support for:
+ - CTS/RTS flow control
+ - baud rate emulation - use infinite speed instead
+ - general frame format - use 8N1
+ - multi-controller system
+ - DMA - use interrupt-driven or polled-I/O instead
+
+
+ PROPERTIES
+
+
+ reg <base> <length>
+
+ Base of SIO control register bank. <length> must equal 0x100.
+ Register offsets: 0: SLCR: line control register
+ 4: SLSR: line status register
+ 8: SDICR: DMA/interrupt control register
+ 12: SDISR: DMA/interrupt status register
+ 16: SFCR: FIFO control register
+ 20: SBGR: baud rate control register
+ 32: transfer FIFO buffer
+ 48: transfer FIFO buffer
+
+ backend {tcp | stdio}
+
+ Use dv-sockser TCP-port backend or stdio for backend. Default: stdio.
+
+
+
+ PORTS
+
+
+ int (output)
+
+ Interrupt port. An event is generated when a timer interrupt
+ occurs.
+
+
+ reset (input)
+
+ Reset port.
+
+ */
+
+
+
+/* static functions */
+
+struct tx3904sio_fifo;
+
+static void tx3904sio_tickle(struct hw*);
+static int tx3904sio_fifo_nonempty(struct hw*, struct tx3904sio_fifo*);
+static char tx3904sio_fifo_pop(struct hw*, struct tx3904sio_fifo*);
+static void tx3904sio_fifo_push(struct hw*, struct tx3904sio_fifo*, char);
+static void tx3904sio_fifo_reset(struct hw*, struct tx3904sio_fifo*);
+static void tx3904sio_poll(struct hw*, void* data);
+
+
+/* register numbers; each is one word long */
+enum
+{
+ SLCR_REG = 0,
+ SLSR_REG = 1,
+ SDICR_REG = 2,
+ SDISR_REG = 3,
+ SFCR_REG = 4,
+ SBGR_REG = 5,
+ TFIFO_REG = 8,
+ SFIFO_REG = 12,
+};
+
+
+
+/* port ID's */
+
+enum
+ {
+ RESET_PORT,
+ INT_PORT,
+};
+
+
+static const struct hw_port_descriptor tx3904sio_ports[] =
+{
+ { "int", INT_PORT, 0, output_port, },
+ { "reset", RESET_PORT, 0, input_port, },
+ { NULL, },
+};
+
+
+
+/* Generic FIFO */
+struct tx3904sio_fifo
+{
+ int size, used;
+ unsigned_1 *buffer;
+};
+
+
+
+/* The timer/counter register internal state. Note that we store
+ state using the control register images, in host endian order. */
+
+struct tx3904sio
+{
+ address_word base_address; /* control register base */
+ enum {sio_tcp, sio_stdio} backend; /* backend */
+
+ struct tx3904sio_fifo rx_fifo, tx_fifo; /* FIFOs */
+
+ unsigned_4 slcr;
+#define SLCR_WR_MASK 0xe17f0000U
+#define SLCR_SET_BYTE(c,o,b) ((c)->slcr = SLCR_WR_MASK & (((c)->slcr & ~LSMASK32((o)*8+7,(o)*8)) | ((b)<< (o)*8)))
+ unsigned_4 slsr;
+#define SLSR_WR_MASK 0x00000000 /* UFER/UPER/UOER unimplemented */
+ unsigned_4 sdicr;
+#define SDICR_WR_MASK 0x000f0000U
+#define SDICR_SET_BYTE(c,o,b) ((c)->sdicr = SDICR_WR_MASK & (((c)->sdicr & ~LSMASK32((o)*8+7,(o)*8)) | ((b)<< (o)*8)))
+#define SDICR_GET_SDMAE(c) ((c)->sdicr & 0x00080000)
+#define SDICR_GET_ERIE(c) ((c)->sdicr & 0x00040000)
+#define SDICR_GET_TDIE(c) ((c)->sdicr & 0x00020000)
+#define SDICR_GET_RDIE(c) ((c)->sdicr & 0x00010000)
+ unsigned_4 sdisr;
+#define SDISR_WR_MASK 0x00070000U
+#define SDISR_SET_BYTE(c,o,b) ((c)->sdisr = SDISR_WR_MASK & (((c)->sdisr & ~LSMASK32((o)*8+7,(o)*8)) | ((b)<< (o)*8)))
+#define SDISR_GET_TDIS(c) ((c)->sdisr & 0x00020000)
+#define SDISR_SET_TDIS(c) ((c)->sdisr |= 0x00020000)
+#define SDISR_GET_RDIS(c) ((c)->sdisr & 0x00010000)
+#define SDISR_SET_RDIS(c) ((c)->sdisr |= 0x00010000)
+ unsigned_4 sfcr;
+#define SFCR_WR_MASK 0x001f0000U
+#define SFCR_SET_BYTE(c,o,b) ((c)->sfcr = SFCR_WR_MASK & (((c)->sfcr & ~LSMASK32((o)*8+7,(o)*8)) | ((b)<< (o)*8)))
+#define SFCR_GET_TFRST(c) ((c)->sfcr & 0x00040000)
+#define SFCR_GET_RFRST(c) ((c)->sfcr & 0x00020000)
+#define SFCR_GET_FRSTE(c) ((c)->sfcr & 0x00010000)
+ unsigned_4 sbgr;
+#define SBGR_WR_MASK 0x03ff0000U
+#define SBGR_SET_BYTE(c,o,b) ((c)->sbgr = SBGR_WR_MASK & (((c)->sbgr & ~LSMASK32((o)*8+7,(o)*8)) | ((b)<< (o)*8)))
+
+ /* Periodic I/O polling */
+ struct hw_event* poll_event;
+};
+
+
+
+/* Finish off the partially created hw device. Attach our local
+ callbacks. Wire up our port names etc */
+
+static hw_io_read_buffer_method tx3904sio_io_read_buffer;
+static hw_io_write_buffer_method tx3904sio_io_write_buffer;
+static hw_port_event_method tx3904sio_port_event;
+
+
+static void
+attach_tx3904sio_regs (struct hw *me,
+ struct tx3904sio *controller)
+{
+ unsigned_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain one addr/size entry");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space,
+ &attach_address,
+ me);
+ hw_unit_size_to_attach_size (hw_parent (me),
+ &reg.size,
+ &attach_size, me);
+
+ hw_attach_address (hw_parent (me), 0,
+ attach_space, attach_address, attach_size,
+ me);
+
+ if(hw_find_property(me, "backend") != NULL)
+ {
+ const char* value = hw_find_string_property(me, "backend");
+ if(! strcmp(value, "tcp"))
+ controller->backend = sio_tcp;
+ else if(! strcmp(value, "stdio"))
+ controller->backend = sio_stdio;
+ else
+ hw_abort(me, "illegal value for backend parameter `%s': use tcp or stdio", value);
+ }
+
+ controller->base_address = attach_address;
+}
+
+
+static void
+tx3904sio_finish (struct hw *me)
+{
+ struct tx3904sio *controller;
+
+ controller = HW_ZALLOC (me, struct tx3904sio);
+ set_hw_data (me, controller);
+ set_hw_io_read_buffer (me, tx3904sio_io_read_buffer);
+ set_hw_io_write_buffer (me, tx3904sio_io_write_buffer);
+ set_hw_ports (me, tx3904sio_ports);
+ set_hw_port_event (me, tx3904sio_port_event);
+
+ /* Preset defaults */
+ controller->backend = sio_stdio;
+
+ /* Attach ourself to our parent bus */
+ attach_tx3904sio_regs (me, controller);
+
+ /* Initialize to reset state */
+ tx3904sio_fifo_reset(me, & controller->rx_fifo);
+ tx3904sio_fifo_reset(me, & controller->tx_fifo);
+ controller->slsr = controller->sdicr
+ = controller->sdisr = controller->sfcr
+ = controller->sbgr = 0;
+ controller->slcr = 0x40000000; /* set TWUB */
+ controller->sbgr = 0x03ff0000; /* set BCLK=3, BRD=FF */
+ controller->poll_event = NULL;
+}
+
+
+
+/* An event arrives on an interrupt port */
+
+static void
+tx3904sio_port_event (struct hw *me,
+ int my_port,
+ struct hw *source,
+ int source_port,
+ int level)
+{
+ struct tx3904sio *controller = hw_data (me);
+
+ switch (my_port)
+ {
+ case RESET_PORT:
+ {
+ HW_TRACE ((me, "reset"));
+
+ tx3904sio_fifo_reset(me, & controller->rx_fifo);
+ tx3904sio_fifo_reset(me, & controller->tx_fifo);
+ controller->slsr = controller->sdicr
+ = controller->sdisr = controller->sfcr
+ = controller->sbgr = 0;
+ controller->slcr = 0x40000000; /* set TWUB */
+ controller->sbgr = 0x03ff0000; /* set BCLK=3, BRD=FF */
+ /* Don't interfere with I/O poller. */
+ break;
+ }
+
+ default:
+ hw_abort (me, "Event on unknown port %d", my_port);
+ break;
+ }
+}
+
+
+/* generic read/write */
+
+static unsigned
+tx3904sio_io_read_buffer (struct hw *me,
+ void *dest,
+ int space,
+ unsigned_word base,
+ unsigned nr_bytes)
+{
+ struct tx3904sio *controller = hw_data (me);
+ unsigned byte;
+
+ HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));
+
+ /* tickle fifos */
+ tx3904sio_tickle(me);
+
+ for (byte = 0; byte < nr_bytes; byte++)
+ {
+ address_word address = base + byte;
+ int reg_number = (address - controller->base_address) / 4;
+ int reg_offset = (address - controller->base_address) % 4;
+ unsigned_4 register_value; /* in target byte order */
+
+ /* fill in entire register_value word */
+ switch (reg_number)
+ {
+ case SLCR_REG: register_value = controller->slcr; break;
+ case SLSR_REG: register_value = controller->slsr; break;
+ case SDICR_REG: register_value = controller->sdicr; break;
+ case SDISR_REG: register_value = controller->sdisr; break;
+ case SFCR_REG: register_value = controller->sfcr; break;
+ case SBGR_REG: register_value = controller->sbgr; break;
+ case TFIFO_REG: register_value = 0; break;
+ case SFIFO_REG:
+ /* consume rx fifo for MS byte */
+ if(reg_offset == 0 && tx3904sio_fifo_nonempty(me, & controller->rx_fifo))
+ register_value = (tx3904sio_fifo_pop(me, & controller->rx_fifo) << 24);
+ else
+ register_value = 0;
+ break;
+ default: register_value = 0;
+ }
+
+ /* write requested byte out */
+ register_value = H2T_4(register_value);
+ /* HW_TRACE ((me, "byte %d %02x", reg_offset, ((char*)& register_value)[reg_offset])); */
+ memcpy ((char*) dest + byte, ((char*)& register_value)+reg_offset, 1);
+ }
+
+ return nr_bytes;
+}
+
+
+
+static unsigned
+tx3904sio_io_write_buffer (struct hw *me,
+ const void *source,
+ int space,
+ unsigned_word base,
+ unsigned nr_bytes)
+{
+ struct tx3904sio *controller = hw_data (me);
+ unsigned byte;
+
+ HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes));
+ for (byte = 0; byte < nr_bytes; byte++)
+ {
+ address_word address = base + byte;
+ unsigned_1 write_byte = ((const unsigned char*) source)[byte];
+ int reg_number = (address - controller->base_address) / 4;
+ int reg_offset = 3 - (address - controller->base_address) % 4;
+
+ /* HW_TRACE ((me, "byte %d %02x", reg_offset, write_byte)); */
+
+ /* fill in entire register_value word */
+ switch (reg_number)
+ {
+ case SLCR_REG:
+ SLCR_SET_BYTE(controller, reg_offset, write_byte);
+ break;
+
+ case SLSR_REG: /* unwriteable */ break;
+
+ case SDICR_REG:
+ {
+ unsigned_4 last_int, next_int;
+
+ /* deassert interrupt upon clear */
+ last_int = controller->sdisr & controller->sdicr;
+ /* HW_TRACE ((me, "sdicr - sdisr %08x sdicr %08x",
+ controller->sdisr, controller->sdicr)); */
+ SDICR_SET_BYTE(controller, reg_offset, write_byte);
+ /* HW_TRACE ((me, "sdicr + sdisr %08x sdicr %08x",
+ controller->sdisr, controller->sdicr)); */
+ next_int = controller->sdisr & controller->sdicr;
+
+ if(SDICR_GET_SDMAE(controller))
+ hw_abort(me, "Cannot support DMA-driven sio.");
+
+ if(~last_int & next_int) /* any bits set? */
+ hw_port_event(me, INT_PORT, 1);
+ if(last_int & ~next_int) /* any bits cleared? */
+ hw_port_event(me, INT_PORT, 0);
+ }
+ break;
+
+ case SDISR_REG:
+ {
+ unsigned_4 last_int, next_int;
+
+ /* deassert interrupt upon clear */
+ last_int = controller->sdisr & controller->sdicr;
+ /* HW_TRACE ((me, "sdisr - sdisr %08x sdicr %08x",
+ controller->sdisr, controller->sdicr)); */
+ SDISR_SET_BYTE(controller, reg_offset, write_byte);
+ /* HW_TRACE ((me, "sdisr + sdisr %08x sdicr %08x",
+ controller->sdisr, controller->sdicr)); */
+ next_int = controller->sdisr & controller->sdicr;
+
+ if(~last_int & next_int) /* any bits set? */
+ hw_port_event(me, INT_PORT, 1);
+ if(last_int & ~next_int) /* any bits cleared? */
+ hw_port_event(me, INT_PORT, 0);
+ }
+ break;
+
+ case SFCR_REG:
+ SFCR_SET_BYTE(controller, reg_offset, write_byte);
+ if(SFCR_GET_FRSTE(controller))
+ {
+ if(SFCR_GET_TFRST(controller)) tx3904sio_fifo_reset(me, & controller->tx_fifo);
+ if(SFCR_GET_RFRST(controller)) tx3904sio_fifo_reset(me, & controller->rx_fifo);
+ }
+ break;
+
+ case SBGR_REG:
+ SBGR_SET_BYTE(controller, reg_offset, write_byte);
+ break;
+
+ case SFIFO_REG: /* unwriteable */ break;
+
+ case TFIFO_REG:
+ if(reg_offset == 3) /* first byte */
+ tx3904sio_fifo_push(me, & controller->tx_fifo, write_byte);
+ break;
+
+ default:
+ HW_TRACE ((me, "write to illegal register %d", reg_number));
+ }
+ } /* loop over bytes */
+
+ /* tickle fifos */
+ tx3904sio_tickle(me);
+
+ return nr_bytes;
+}
+
+
+
+
+
+
+/* Send enqueued characters from tx_fifo and trigger TX interrupt.
+Receive characters into rx_fifo and trigger RX interrupt. */
+void
+tx3904sio_tickle(struct hw *me)
+{
+ struct tx3904sio* controller = hw_data(me);
+ int c;
+ char cc;
+ unsigned_4 last_int, next_int;
+
+ /* HW_TRACE ((me, "tickle backend: %02x", controller->backend)); */
+ switch(controller->backend)
+ {
+ case sio_tcp:
+
+ while(tx3904sio_fifo_nonempty(me, & controller->tx_fifo))
+ {
+ cc = tx3904sio_fifo_pop(me, & controller->tx_fifo);
+ dv_sockser_write(hw_system(me), cc);
+ HW_TRACE ((me, "tcp output: %02x", cc));
+ }
+
+ c = dv_sockser_read(hw_system(me));
+ while(c != -1)
+ {
+ cc = (char) c;
+ HW_TRACE ((me, "tcp input: %02x", cc));
+ tx3904sio_fifo_push(me, & controller->rx_fifo, cc);
+ c = dv_sockser_read(hw_system(me));
+ }
+ break;
+
+ case sio_stdio:
+
+ while(tx3904sio_fifo_nonempty(me, & controller->tx_fifo))
+ {
+ cc = tx3904sio_fifo_pop(me, & controller->tx_fifo);
+ sim_io_write_stdout(hw_system(me), & cc, 1);
+ sim_io_flush_stdout(hw_system(me));
+ HW_TRACE ((me, "stdio output: %02x", cc));
+ }
+
+ c = sim_io_poll_read(hw_system(me), 0 /* stdin */, & cc, 1);
+ while(c == 1)
+ {
+ HW_TRACE ((me, "stdio input: %02x", cc));
+ tx3904sio_fifo_push(me, & controller->rx_fifo, cc);
+ c = sim_io_poll_read(hw_system(me), 0 /* stdin */, & cc, 1);
+ }
+
+ break;
+
+ default:
+ hw_abort(me, "Illegal backend mode: %d", controller->backend);
+ }
+
+ /* Update RDIS / TDIS flags */
+ last_int = controller->sdisr & controller->sdicr;
+ /* HW_TRACE ((me, "tickle - sdisr %08x sdicr %08x", controller->sdisr, controller->sdicr)); */
+ if(tx3904sio_fifo_nonempty(me, & controller->rx_fifo))
+ SDISR_SET_RDIS(controller);
+ if(! tx3904sio_fifo_nonempty(me, & controller->tx_fifo))
+ SDISR_SET_TDIS(controller);
+ next_int = controller->sdisr & controller->sdicr;
+ /* HW_TRACE ((me, "tickle + sdisr %08x sdicr %08x", controller->sdisr, controller->sdicr)); */
+
+ if(~last_int & next_int) /* any bits set? */
+ hw_port_event(me, INT_PORT, 1);
+ if(last_int & ~next_int) /* any bits cleared? */
+ hw_port_event(me, INT_PORT, 0);
+
+ /* Add periodic polling for this port, if it's not already going. */
+ if(controller->poll_event == NULL)
+ {
+ controller->poll_event = hw_event_queue_schedule (me, 1000,
+ tx3904sio_poll, NULL);
+
+ }
+}
+
+
+
+
+int
+tx3904sio_fifo_nonempty(struct hw* me, struct tx3904sio_fifo* fifo)
+{
+ /* HW_TRACE ((me, "fifo used: %d", fifo->used)); */
+ return(fifo->used > 0);
+}
+
+
+char
+tx3904sio_fifo_pop(struct hw* me, struct tx3904sio_fifo* fifo)
+{
+ char it;
+ ASSERT(fifo->used > 0);
+ ASSERT(fifo->buffer != NULL);
+ it = fifo->buffer[0];
+ memcpy(& fifo->buffer[0], & fifo->buffer[1], fifo->used - 1);
+ fifo->used --;
+ /* HW_TRACE ((me, "pop fifo -> %02x", it)); */
+ return it;
+}
+
+
+void
+tx3904sio_fifo_push(struct hw* me, struct tx3904sio_fifo* fifo, char it)
+{
+ /* HW_TRACE ((me, "push %02x -> fifo", it)); */
+ if(fifo->size == fifo->used) /* full */
+ {
+ int next_size = fifo->size * 2 + 16;
+ char* next_buf = zalloc(next_size);
+ memcpy(next_buf, fifo->buffer, fifo->used);
+
+ if(fifo->buffer != NULL) zfree(fifo->buffer);
+ fifo->buffer = next_buf;
+ fifo->size = next_size;
+ }
+
+ fifo->buffer[fifo->used] = it;
+ fifo->used ++;
+}
+
+
+void
+tx3904sio_fifo_reset(struct hw* me, struct tx3904sio_fifo* fifo)
+{
+ /* HW_TRACE ((me, "reset fifo")); */
+ fifo->used = 0;
+ fifo->size = 0;
+ zfree(fifo->buffer);
+ fifo->buffer = 0;
+}
+
+
+void
+tx3904sio_poll(struct hw* me, void* ignored)
+{
+ struct tx3904sio* controller = hw_data (me);
+ tx3904sio_tickle (me);
+ hw_event_queue_deschedule (me, controller->poll_event);
+ controller->poll_event = hw_event_queue_schedule (me, 1000,
+ tx3904sio_poll, NULL);
+}
+
+
+
+const struct hw_descriptor dv_tx3904sio_descriptor[] = {
+ { "tx3904sio", tx3904sio_finish, },
+ { NULL },
+};
diff --git a/sim/mips/dv-tx3904tmr.c b/sim/mips/dv-tx3904tmr.c
new file mode 100644
index 0000000..c1c7b8c
--- /dev/null
+++ b/sim/mips/dv-tx3904tmr.c
@@ -0,0 +1,698 @@
+/* This file is part of the program GDB, the GNU debugger.
+
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+
+#include "sim-main.h"
+#include "hw-main.h"
+
+
+/* DEVICE
+
+
+ tx3904tmr - tx3904 timer
+
+
+ DESCRIPTION
+
+
+ Implements one tx3904 timer/counter described in the tx3904
+ user guide. Three instances are required for TMR0, TMR1, and
+ TMR3 within the tx3904, at different base addresses.
+
+ Both internal and system clocks are synthesized as divided versions
+ of the simulator clock.
+
+ There is no support for:
+ - edge sensitivity of external clock
+ - different mode restrictions for TMR0..2
+ - level interrupts (interrupts are treated as events that occur at edges)
+
+
+
+ PROPERTIES
+
+
+ reg <base> <length>
+
+ Base of TMR control register bank. <length> must equal 0x100.
+ Register offsets: 0: TCR: timer control register
+ 4: TISR: timer interrupt status register
+ 8: CPRA: compare register A
+ 12: CPRB: compare register B
+ 16: ITMR: interval timer mode register
+ 32: CCDR: divider register
+ 48: PMGR: pulse generator mode register
+ 64: WTMR: watchdog timer mode register
+ 240: TRR: timer read register
+
+
+ clock <ticks>
+
+ Rate of timer clock signal. This number is the number of simulator
+ ticks per clock signal tick. Default 1.
+
+
+ ext <ticks>
+
+ Rate of "external input clock signal", the other clock input of the
+ timer. It uses the same scale as above. Default 100.
+
+
+
+ PORTS
+
+
+ int (output)
+
+ Interrupt port. An event is generated when a timer interrupt
+ occurs.
+
+
+ ff (output)
+
+ Flip-flop output, corresponds to the TMFFOUT port. An event is
+ generated when flip-flop changes value. The integer associated
+ with the event is 1/0 according to flip-flop value.
+
+
+ reset (input)
+
+ Reset port.
+
+ */
+
+
+
+/* static functions */
+
+static void deliver_tx3904tmr_tick (struct hw *me, void *data);
+
+
+/* register numbers; each is one word long */
+enum
+{
+ TCR_REG = 0,
+ TISR_REG = 1,
+ CPRA_REG = 2,
+ CPRB_REG = 3,
+ ITMR_REG = 4,
+ CCDR_REG = 8,
+ PMGR_REG = 12,
+ WTMR_REG = 16,
+ TRR_REG = 60
+};
+
+
+
+/* port ID's */
+
+enum
+ {
+ RESET_PORT,
+ INT_PORT,
+ FF_PORT
+};
+
+
+static const struct hw_port_descriptor tx3904tmr_ports[] =
+{
+ { "int", INT_PORT, 0, output_port, },
+ { "ff", FF_PORT, 0, output_port, },
+ { "reset", RESET_PORT, 0, input_port, },
+ { NULL, },
+};
+
+
+
+/* The timer/counter register internal state. Note that we store
+ state using the control register images, in host endian order. */
+
+struct tx3904tmr {
+ address_word base_address; /* control register base */
+ unsigned_4 clock_ticks, ext_ticks; /* clock frequencies */
+ signed_8 last_ticks; /* time at last deliver_*_tick call */
+ signed_8 roundoff_ticks; /* sim ticks unprocessed during last tick call */
+ int ff; /* pulse generator flip-flop value: 1/0 */
+ struct hw_event* event; /* last scheduled event */
+
+ unsigned_4 tcr;
+#define GET_TCR_TCE(c) (((c)->tcr & 0x80) >> 7)
+#define GET_TCR_CCDE(c) (((c)->tcr & 0x40) >> 6)
+#define GET_TCR_CRE(c) (((c)->tcr & 0x20) >> 5)
+#define GET_TCR_CCS(c) (((c)->tcr & 0x04) >> 2)
+#define GET_TCR_TMODE(c) (((c)->tcr & 0x03) >> 0)
+ unsigned_4 tisr;
+#define SET_TISR_TWIS(c) ((c)->tisr |= 0x08)
+#define SET_TISR_TPIBS(c) ((c)->tisr |= 0x04)
+#define SET_TISR_TPIAS(c) ((c)->tisr |= 0x02)
+#define SET_TISR_TIIS(c) ((c)->tisr |= 0x01)
+ unsigned_4 cpra;
+ unsigned_4 cprb;
+ unsigned_4 itmr;
+#define GET_ITMR_TIIE(c) (((c)->itmr & 0x8000) >> 15)
+#define SET_ITMR_TIIE(c,v) BLIT32((c)->itmr, 15, (v) ? 1 : 0)
+#define GET_ITMR_TZCE(c) (((c)->itmr & 0x0001) >> 0)
+#define SET_ITMR_TZCE(c,v) BLIT32((c)->itmr, 0, (v) ? 1 : 0)
+ unsigned_4 ccdr;
+#define GET_CCDR_CDR(c) (((c)->ccdr & 0x07) >> 0)
+ unsigned_4 pmgr;
+#define GET_PMGR_TPIBE(c) (((c)->pmgr & 0x8000) >> 15)
+#define SET_PMGR_TPIBE(c,v) BLIT32((c)->pmgr, 15, (v) ? 1 : 0)
+#define GET_PMGR_TPIAE(c) (((c)->pmgr & 0x4000) >> 14)
+#define SET_PMGR_TPIAE(c,v) BLIT32((c)->pmgr, 14, (v) ? 1 : 0)
+#define GET_PMGR_FFI(c) (((c)->pmgr & 0x0001) >> 0)
+#define SET_PMGR_FFI(c,v) BLIT32((c)->pmgr, 0, (v) ? 1 : 0)
+ unsigned_4 wtmr;
+#define GET_WTMR_TWIE(c) (((c)->wtmr & 0x8000) >> 15)
+#define SET_WTMR_TWIE(c,v) BLIT32((c)->wtmr, 15, (v) ? 1 : 0)
+#define GET_WTMR_WDIS(c) (((c)->wtmr & 0x0080) >> 7)
+#define SET_WTMR_WDIS(c,v) BLIT32((c)->wtmr, 7, (v) ? 1 : 0)
+#define GET_WTMR_TWC(c) (((c)->wtmr & 0x0001) >> 0)
+#define SET_WTMR_TWC(c,v) BLIT32((c)->wtmr, 0, (v) ? 1 : 0)
+ unsigned_4 trr;
+};
+
+
+
+/* Finish off the partially created hw device. Attach our local
+ callbacks. Wire up our port names etc */
+
+static hw_io_read_buffer_method tx3904tmr_io_read_buffer;
+static hw_io_write_buffer_method tx3904tmr_io_write_buffer;
+static hw_port_event_method tx3904tmr_port_event;
+
+static void
+attach_tx3904tmr_regs (struct hw *me,
+ struct tx3904tmr *controller)
+{
+ unsigned_word attach_address;
+ int attach_space;
+ unsigned attach_size;
+ reg_property_spec reg;
+
+ if (hw_find_property (me, "reg") == NULL)
+ hw_abort (me, "Missing \"reg\" property");
+
+ if (!hw_find_reg_array_property (me, "reg", 0, &reg))
+ hw_abort (me, "\"reg\" property must contain one addr/size entry");
+
+ hw_unit_address_to_attach_address (hw_parent (me),
+ &reg.address,
+ &attach_space,
+ &attach_address,
+ me);
+ hw_unit_size_to_attach_size (hw_parent (me),
+ &reg.size,
+ &attach_size, me);
+
+ hw_attach_address (hw_parent (me), 0,
+ attach_space, attach_address, attach_size,
+ me);
+
+ if(hw_find_property(me, "clock") != NULL)
+ controller->clock_ticks = (unsigned_4) hw_find_integer_property(me, "clock");
+
+ if(hw_find_property(me, "ext") != NULL)
+ controller->ext_ticks = (unsigned_4) hw_find_integer_property(me, "ext");
+
+ controller->base_address = attach_address;
+}
+
+
+static void
+tx3904tmr_finish (struct hw *me)
+{
+ struct tx3904tmr *controller;
+
+ controller = HW_ZALLOC (me, struct tx3904tmr);
+ set_hw_data (me, controller);
+ set_hw_io_read_buffer (me, tx3904tmr_io_read_buffer);
+ set_hw_io_write_buffer (me, tx3904tmr_io_write_buffer);
+ set_hw_ports (me, tx3904tmr_ports);
+ set_hw_port_event (me, tx3904tmr_port_event);
+
+ /* Preset clock dividers */
+ controller->clock_ticks = 1;
+ controller->ext_ticks = 100;
+
+ /* Attach ourself to our parent bus */
+ attach_tx3904tmr_regs (me, controller);
+
+ /* Initialize to reset state */
+ controller->tcr =
+ controller->itmr =
+ controller->ccdr =
+ controller->pmgr =
+ controller->wtmr =
+ controller->tisr =
+ controller->trr = 0;
+ controller->cpra = controller->cprb = 0x00FFFFFF;
+ controller->ff = 0;
+ controller->last_ticks = controller->roundoff_ticks = 0;
+ controller->event = NULL;
+}
+
+
+
+/* An event arrives on an interrupt port */
+
+static void
+tx3904tmr_port_event (struct hw *me,
+ int my_port,
+ struct hw *source,
+ int source_port,
+ int level)
+{
+ struct tx3904tmr *controller = hw_data (me);
+
+ switch (my_port)
+ {
+ case RESET_PORT:
+ {
+ HW_TRACE ((me, "reset"));
+
+ /* preset flip-flop to FFI value */
+ controller->ff = GET_PMGR_FFI(controller);
+
+ controller->tcr =
+ controller->itmr =
+ controller->ccdr =
+ controller->pmgr =
+ controller->wtmr =
+ controller->tisr =
+ controller->trr = 0;
+ controller->cpra = controller->cprb = 0x00FFFFFF;
+ controller->last_ticks = controller->roundoff_ticks = 0;
+ if(controller->event != NULL)
+ hw_event_queue_deschedule(me, controller->event);
+ controller->event = NULL;
+ break;
+ }
+
+ default:
+ hw_abort (me, "Event on unknown port %d", my_port);
+ break;
+ }
+}
+
+
+/* generic read/write */
+
+static unsigned
+tx3904tmr_io_read_buffer (struct hw *me,
+ void *dest,
+ int space,
+ unsigned_word base,
+ unsigned nr_bytes)
+{
+ struct tx3904tmr *controller = hw_data (me);
+ unsigned byte;
+
+ HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));
+ for (byte = 0; byte < nr_bytes; byte++)
+ {
+ address_word address = base + byte;
+ int reg_number = (address - controller->base_address) / 4;
+ int reg_offset = 3 - (address - controller->base_address) % 4;
+ unsigned_4 register_value; /* in target byte order */
+
+ /* fill in entire register_value word */
+ switch (reg_number)
+ {
+ case TCR_REG: register_value = controller->tcr; break;
+ case TISR_REG: register_value = controller->tisr; break;
+ case CPRA_REG: register_value = controller->cpra; break;
+ case CPRB_REG: register_value = controller->cprb; break;
+ case ITMR_REG: register_value = controller->itmr; break;
+ case CCDR_REG: register_value = controller->ccdr; break;
+ case PMGR_REG: register_value = controller->pmgr; break;
+ case WTMR_REG: register_value = controller->wtmr; break;
+ case TRR_REG: register_value = controller->trr; break;
+ default: register_value = 0;
+ }
+
+ /* write requested byte out */
+ memcpy ((char*) dest + byte, ((char*)& register_value)+reg_offset, 1);
+ }
+
+ return nr_bytes;
+}
+
+
+
+static unsigned
+tx3904tmr_io_write_buffer (struct hw *me,
+ const void *source,
+ int space,
+ unsigned_word base,
+ unsigned nr_bytes)
+{
+ struct tx3904tmr *controller = hw_data (me);
+ unsigned byte;
+
+ HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes));
+ for (byte = 0; byte < nr_bytes; byte++)
+ {
+ address_word address = base + byte;
+ unsigned_1 write_byte = ((const char*) source)[byte];
+ int reg_number = (address - controller->base_address) / 4;
+ int reg_offset = 3 - (address - controller->base_address) % 4;
+
+ /* fill in entire register_value word */
+ switch (reg_number)
+ {
+ case TCR_REG:
+ if(reg_offset == 0) /* first byte */
+ {
+ /* update register, but mask out NOP bits */
+ controller->tcr = (unsigned_4) (write_byte & 0xef);
+
+ /* Reset counter value if timer suspended and CRE is set. */
+ if(GET_TCR_TCE(controller) == 0 &&
+ GET_TCR_CRE(controller) == 1)
+ controller->trr = 0;
+ }
+ /* HW_TRACE ((me, "tcr: %08lx", (long) controller->tcr)); */
+ break;
+
+ case ITMR_REG:
+ if(reg_offset == 1) /* second byte */
+ {
+ SET_ITMR_TIIE(controller, write_byte & 0x80);
+ }
+ else if(reg_offset == 0) /* first byte */
+ {
+ SET_ITMR_TZCE(controller, write_byte & 0x01);
+ }
+ /* HW_TRACE ((me, "itmr: %08lx", (long) controller->itmr)); */
+ break;
+
+ case CCDR_REG:
+ if(reg_offset == 0) /* first byte */
+ {
+ controller->ccdr = write_byte & 0x07;
+ }
+ /* HW_TRACE ((me, "ccdr: %08lx", (long) controller->ccdr)); */
+ break;
+
+ case PMGR_REG:
+ if(reg_offset == 1) /* second byte */
+ {
+ SET_PMGR_TPIBE(controller, write_byte & 0x80);
+ SET_PMGR_TPIAE(controller, write_byte & 0x40);
+ }
+ else if(reg_offset == 0) /* first byte */
+ {
+ SET_PMGR_FFI(controller, write_byte & 0x01);
+ }
+ /* HW_TRACE ((me, "pmgr: %08lx", (long) controller->pmgr)); */
+ break;
+
+ case WTMR_REG:
+ if(reg_offset == 1) /* second byte */
+ {
+ SET_WTMR_TWIE(controller, write_byte & 0x80);
+ }
+ else if(reg_offset == 0) /* first byte */
+ {
+ SET_WTMR_WDIS(controller, write_byte & 0x80);
+ SET_WTMR_TWC(controller, write_byte & 0x01);
+ }
+ /* HW_TRACE ((me, "wtmr: %08lx", (long) controller->wtmr)); */
+ break;
+
+ case TISR_REG:
+ if(reg_offset == 0) /* first byte */
+ {
+ /* All bits must be zero in given byte, according to
+ spec. */
+
+ /* Send an "interrupt off" event on the interrupt port */
+ if(controller->tisr != 0) /* any interrupts active? */
+ {
+ hw_port_event(me, INT_PORT, 0);
+ }
+
+ /* clear interrupt status register */
+ controller->tisr = 0;
+ }
+ /* HW_TRACE ((me, "tisr: %08lx", (long) controller->tisr)); */
+ break;
+
+ case CPRA_REG:
+ if(reg_offset < 3) /* first, second, or third byte */
+ {
+ MBLIT32(controller->cpra, (reg_offset*8)+7, (reg_offset*8), write_byte);
+ }
+ /* HW_TRACE ((me, "cpra: %08lx", (long) controller->cpra)); */
+ break;
+
+ case CPRB_REG:
+ if(reg_offset < 3) /* first, second, or third byte */
+ {
+ MBLIT32(controller->cprb, (reg_offset*8)+7, (reg_offset*8), write_byte);
+ }
+ /* HW_TRACE ((me, "cprb: %08lx", (long) controller->cprb)); */
+ break;
+
+ default:
+ HW_TRACE ((me, "write to illegal register %d", reg_number));
+ }
+ } /* loop over bytes */
+
+ /* Schedule a timer event in near future, so we can increment or
+ stop the counter, to respond to register updates. */
+ hw_event_queue_schedule(me, 1, deliver_tx3904tmr_tick, NULL);
+
+ return nr_bytes;
+}
+
+
+
+/* Deliver a clock tick to the counter. */
+static void
+deliver_tx3904tmr_tick (struct hw *me,
+ void *data)
+{
+ struct tx3904tmr *controller = hw_data (me);
+ SIM_DESC sd = hw_system (me);
+ signed_8 this_ticks = sim_events_time(sd);
+
+ signed_8 warp;
+ signed_8 divisor;
+ signed_8 quotient, remainder;
+
+ /* compute simulation ticks between last tick and this tick */
+ if(controller->last_ticks != 0)
+ warp = this_ticks - controller->last_ticks + controller->roundoff_ticks;
+ else
+ {
+ controller->last_ticks = this_ticks; /* initialize */
+ warp = controller->roundoff_ticks;
+ }
+
+ if(controller->event != NULL)
+ hw_event_queue_deschedule(me, controller->event);
+ controller->event = NULL;
+
+ /* Check whether the timer ticking is enabled at this moment. This
+ largely a function of the TCE bit, but is also slightly
+ mode-dependent. */
+ switch((int) GET_TCR_TMODE(controller))
+ {
+ case 0: /* interval */
+ /* do not advance counter if TCE = 0 or if holding at count = CPRA */
+ if(GET_TCR_TCE(controller) == 0 ||
+ controller->trr == controller->cpra)
+ return;
+ break;
+
+ case 1: /* pulse generator */
+ /* do not advance counter if TCE = 0 */
+ if(GET_TCR_TCE(controller) == 0)
+ return;
+ break;
+
+ case 2: /* watchdog */
+ /* do not advance counter if TCE = 0 and WDIS = 1 */
+ if(GET_TCR_TCE(controller) == 0 &&
+ GET_WTMR_WDIS(controller) == 1)
+ return;
+ break;
+
+ case 3: /* disabled */
+ /* regardless of TCE, do not advance counter */
+ return;
+ }
+
+ /* In any of the above cases that return, a subsequent register
+ write will be needed to restart the timer. A tick event is
+ scheduled by any register write, so it is more efficient not to
+ reschedule dummy events here. */
+
+
+ /* find appropriate divisor etc. */
+ if(GET_TCR_CCS(controller) == 0) /* internal system clock */
+ {
+ /* apply internal clock divider */
+ if(GET_TCR_CCDE(controller)) /* divisor circuit enabled? */
+ divisor = controller->clock_ticks * (1 << (1 + GET_CCDR_CDR(controller)));
+ else
+ divisor = controller->clock_ticks;
+ }
+ else
+ {
+ divisor = controller->ext_ticks;
+ }
+
+ /* how many times to increase counter? */
+ quotient = warp / divisor;
+ remainder = warp % divisor;
+
+ /* NOTE: If the event rescheduling code works properly, the quotient
+ should never be larger than 1. That is, we should receive events
+ here at least as frequently as the simulated counter is supposed
+ to decrement. So the remainder (-> roundoff_ticks) will slowly
+ accumulate, with the quotient == 0. Once in a while, quotient
+ will equal 1. */
+
+ controller->roundoff_ticks = remainder;
+ controller->last_ticks = this_ticks;
+ while(quotient > 0) /* Is it time to increment counter? */
+ {
+ /* next 24-bit counter value */
+ unsigned_4 next_trr = (controller->trr + 1) % (1 << 24);
+ quotient --;
+
+ switch((int) GET_TCR_TMODE(controller))
+ {
+ case 0: /* interval timer mode */
+ {
+ /* Current or next counter value matches CPRA value? The
+ first case covers counter holding at maximum before
+ reset. The second case covers normal counting
+ behavior. */
+ if(controller->trr == controller->cpra ||
+ next_trr == controller->cpra)
+ {
+ /* likely hold CPRA value */
+ if(controller->trr == controller->cpra)
+ next_trr = controller->cpra;
+
+ SET_TISR_TIIS(controller);
+
+ /* Signal an interrupt if it is enabled with TIIE,
+ and if we just arrived at CPRA. Don't repeatedly
+ interrupt if holding due to TZCE=0 */
+ if(GET_ITMR_TIIE(controller) &&
+ next_trr != controller->trr)
+ {
+ hw_port_event(me, INT_PORT, 1);
+ }
+
+ /* Reset counter? */
+ if(GET_ITMR_TZCE(controller))
+ {
+ next_trr = 0;
+ }
+ }
+ }
+ break;
+
+ case 1: /* pulse generator mode */
+ {
+ /* first trip point */
+ if(next_trr == controller->cpra)
+ {
+ /* flip flip-flop & report */
+ controller->ff ^= 1;
+ hw_port_event(me, FF_PORT, controller->ff);
+ SET_TISR_TPIAS(controller);
+
+ /* signal interrupt */
+ if(GET_PMGR_TPIAE(controller))
+ {
+ hw_port_event(me, INT_PORT, 1);
+ }
+
+ }
+ /* second trip point */
+ else if(next_trr == controller->cprb)
+ {
+ /* flip flip-flop & report */
+ controller->ff ^= 1;
+ hw_port_event(me, FF_PORT, controller->ff);
+ SET_TISR_TPIBS(controller);
+
+ /* signal interrupt */
+ if(GET_PMGR_TPIBE(controller))
+ {
+ hw_port_event(me, INT_PORT, 1);
+ }
+
+ /* clear counter */
+ next_trr = 0;
+ }
+ }
+ break;
+
+ case 2: /* watchdog timer mode */
+ {
+ /* watchdog timer expiry */
+ if(next_trr == controller->cpra)
+ {
+ SET_TISR_TWIS(controller);
+
+ /* signal interrupt */
+ if(GET_WTMR_TWIE(controller))
+ {
+ hw_port_event(me, INT_PORT, 1);
+ }
+
+ /* clear counter */
+ next_trr = 0;
+ }
+ }
+ break;
+
+ case 3: /* disabled */
+ default:
+ }
+
+ /* update counter and report */
+ controller->trr = next_trr;
+ /* HW_TRACE ((me, "counter trr %ld tisr %lx",
+ (long) controller->trr, (long) controller->tisr)); */
+ } /* end quotient loop */
+
+ /* Reschedule a timer event in near future, so we can increment the
+ counter again. Set the event about 75% of divisor time away, so
+ we will experience roughly 1.3 events per counter increment. */
+ controller->event = hw_event_queue_schedule(me, divisor*3/4, deliver_tx3904tmr_tick, NULL);
+}
+
+
+
+
+const struct hw_descriptor dv_tx3904tmr_descriptor[] = {
+ { "tx3904tmr", tx3904tmr_finish, },
+ { NULL },
+};
diff --git a/sim/mips/interp.c b/sim/mips/interp.c
new file mode 100644
index 0000000..75bc54b
--- /dev/null
+++ b/sim/mips/interp.c
@@ -0,0 +1,3228 @@
+/*> interp.c <*/
+/* Simulator for the MIPS architecture.
+
+ This file is part of the MIPS sim
+
+ THIS SOFTWARE IS NOT COPYRIGHTED
+
+ Cygnus offers the following for use in the public domain. Cygnus
+ makes no warranty with regard to the software or it's performance
+ and the user accepts the software "AS IS" with all faults.
+
+ CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
+ THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+ $Revision$
+ $Date$
+
+NOTEs:
+
+The IDT monitor (found on the VR4300 board), seems to lie about
+register contents. It seems to treat the registers as sign-extended
+32-bit values. This cause *REAL* problems when single-stepping 64-bit
+code on the hardware.
+
+*/
+
+/* The TRACE manifests enable the provision of extra features. If they
+ are not defined then a simpler (quicker) simulator is constructed
+ without the required run-time checks, etc. */
+#if 1 /* 0 to allow user build selection, 1 to force inclusion */
+#define TRACE (1)
+#endif
+
+#include "bfd.h"
+#include "sim-main.h"
+#include "sim-utils.h"
+#include "sim-options.h"
+#include "sim-assert.h"
+#include "sim-hw.h"
+
+#include "itable.h"
+
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <ansidecl.h>
+#include <ctype.h>
+#include <limits.h>
+#include <math.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+
+#include "getopt.h"
+#include "libiberty.h"
+#include "bfd.h"
+#include "callback.h" /* GDB simulator callback interface */
+#include "remote-sim.h" /* GDB simulator interface */
+
+#include "sysdep.h"
+
+#ifndef PARAMS
+#define PARAMS(x)
+#endif
+
+char* pr_addr PARAMS ((SIM_ADDR addr));
+char* pr_uword64 PARAMS ((uword64 addr));
+
+
+/* Within interp.c we refer to the sim_state and sim_cpu directly. */
+#define CPU cpu
+#define SD sd
+
+
+/* The following reserved instruction value is used when a simulator
+ trap is required. NOTE: Care must be taken, since this value may be
+ used in later revisions of the MIPS ISA. */
+
+#define RSVD_INSTRUCTION (0x00000005)
+#define RSVD_INSTRUCTION_MASK (0xFC00003F)
+
+#define RSVD_INSTRUCTION_ARG_SHIFT 6
+#define RSVD_INSTRUCTION_ARG_MASK 0xFFFFF
+
+
+/* Bits in the Debug register */
+#define Debug_DBD 0x80000000 /* Debug Branch Delay */
+#define Debug_DM 0x40000000 /* Debug Mode */
+#define Debug_DBp 0x00000002 /* Debug Breakpoint indicator */
+
+/*---------------------------------------------------------------------------*/
+/*-- GDB simulator interface ------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+
+static void ColdReset PARAMS((SIM_DESC sd));
+
+/*---------------------------------------------------------------------------*/
+
+
+
+#define DELAYSLOT() {\
+ if (STATE & simDELAYSLOT)\
+ sim_io_eprintf(sd,"Delay slot already activated (branch in delay slot?)\n");\
+ STATE |= simDELAYSLOT;\
+ }
+
+#define JALDELAYSLOT() {\
+ DELAYSLOT ();\
+ STATE |= simJALDELAYSLOT;\
+ }
+
+#define NULLIFY() {\
+ STATE &= ~simDELAYSLOT;\
+ STATE |= simSKIPNEXT;\
+ }
+
+#define CANCELDELAYSLOT() {\
+ DSSTATE = 0;\
+ STATE &= ~(simDELAYSLOT | simJALDELAYSLOT);\
+ }
+
+#define INDELAYSLOT() ((STATE & simDELAYSLOT) != 0)
+#define INJALDELAYSLOT() ((STATE & simJALDELAYSLOT) != 0)
+
+#define K0BASE (0x80000000)
+#define K0SIZE (0x20000000)
+#define K1BASE (0xA0000000)
+#define K1SIZE (0x20000000)
+#define MONITOR_BASE (0xBFC00000)
+#define MONITOR_SIZE (1 << 11)
+#define MEM_SIZE (2 << 20)
+
+
+#if defined(TRACE)
+static char *tracefile = "trace.din"; /* default filename for trace log */
+FILE *tracefh = NULL;
+static void open_trace PARAMS((SIM_DESC sd));
+#endif /* TRACE */
+
+static const char * get_insn_name (sim_cpu *, int);
+
+/* simulation target board. NULL=canonical */
+static char* board = NULL;
+
+
+static DECLARE_OPTION_HANDLER (mips_option_handler);
+
+enum {
+ OPTION_DINERO_TRACE = OPTION_START,
+ OPTION_DINERO_FILE,
+ OPTION_BOARD
+};
+
+
+static SIM_RC
+mips_option_handler (sd, cpu, opt, arg, is_command)
+ SIM_DESC sd;
+ sim_cpu *cpu;
+ int opt;
+ char *arg;
+ int is_command;
+{
+ int cpu_nr;
+ switch (opt)
+ {
+ case OPTION_DINERO_TRACE: /* ??? */
+#if defined(TRACE)
+ /* Eventually the simTRACE flag could be treated as a toggle, to
+ allow external control of the program points being traced
+ (i.e. only from main onwards, excluding the run-time setup,
+ etc.). */
+ for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
+ {
+ sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
+ if (arg == NULL)
+ STATE |= simTRACE;
+ else if (strcmp (arg, "yes") == 0)
+ STATE |= simTRACE;
+ else if (strcmp (arg, "no") == 0)
+ STATE &= ~simTRACE;
+ else if (strcmp (arg, "on") == 0)
+ STATE |= simTRACE;
+ else if (strcmp (arg, "off") == 0)
+ STATE &= ~simTRACE;
+ else
+ {
+ fprintf (stderr, "Unrecognized dinero-trace option `%s'\n", arg);
+ return SIM_RC_FAIL;
+ }
+ }
+ return SIM_RC_OK;
+#else /* !TRACE */
+ fprintf(stderr,"\
+Simulator constructed without dinero tracing support (for performance).\n\
+Re-compile simulator with \"-DTRACE\" to enable this option.\n");
+ return SIM_RC_FAIL;
+#endif /* !TRACE */
+
+ case OPTION_DINERO_FILE:
+#if defined(TRACE)
+ if (optarg != NULL) {
+ char *tmp;
+ tmp = (char *)malloc(strlen(optarg) + 1);
+ if (tmp == NULL)
+ {
+ sim_io_printf(sd,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg);
+ return SIM_RC_FAIL;
+ }
+ else {
+ strcpy(tmp,optarg);
+ tracefile = tmp;
+ sim_io_printf(sd,"Placing trace information into file \"%s\"\n",tracefile);
+ }
+ }
+#endif /* TRACE */
+ return SIM_RC_OK;
+
+ case OPTION_BOARD:
+ {
+ if (arg)
+ {
+ board = zalloc(strlen(arg) + 1);
+ strcpy(board, arg);
+ }
+ return SIM_RC_OK;
+ }
+ }
+
+ return SIM_RC_OK;
+}
+
+
+static const OPTION mips_options[] =
+{
+ { {"dinero-trace", optional_argument, NULL, OPTION_DINERO_TRACE},
+ '\0', "on|off", "Enable dinero tracing",
+ mips_option_handler },
+ { {"dinero-file", required_argument, NULL, OPTION_DINERO_FILE},
+ '\0', "FILE", "Write dinero trace to FILE",
+ mips_option_handler },
+ { {"board", required_argument, NULL, OPTION_BOARD},
+ '\0', "none" /* rely on compile-time string concatenation for other options */
+
+#define BOARD_JMR3904 "jmr3904"
+ "|" BOARD_JMR3904
+#define BOARD_JMR3904_PAL "jmr3904pal"
+ "|" BOARD_JMR3904_PAL
+#define BOARD_JMR3904_DEBUG "jmr3904debug"
+ "|" BOARD_JMR3904_DEBUG
+
+ , "Customize simulation for a particular board.", mips_option_handler },
+
+ { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
+};
+
+
+int interrupt_pending;
+
+void
+interrupt_event (SIM_DESC sd, void *data)
+{
+ sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
+ address_word cia = CIA_GET (cpu);
+ if (SR & status_IE)
+ {
+ interrupt_pending = 0;
+ SignalExceptionInterrupt (1); /* interrupt "1" */
+ }
+ else if (!interrupt_pending)
+ sim_events_schedule (sd, 1, interrupt_event, data);
+}
+
+
+/*---------------------------------------------------------------------------*/
+/*-- Device registration hook -----------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+static void device_init(SIM_DESC sd) {
+#ifdef DEVICE_INIT
+ extern void register_devices(SIM_DESC);
+ register_devices(sd);
+#endif
+}
+
+/*---------------------------------------------------------------------------*/
+/*-- GDB simulator interface ------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+
+SIM_DESC
+sim_open (kind, cb, abfd, argv)
+ SIM_OPEN_KIND kind;
+ host_callback *cb;
+ struct _bfd *abfd;
+ char **argv;
+{
+ SIM_DESC sd = sim_state_alloc (kind, cb);
+ sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
+
+ SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+
+ /* FIXME: watchpoints code shouldn't need this */
+ STATE_WATCHPOINTS (sd)->pc = &(PC);
+ STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
+ STATE_WATCHPOINTS (sd)->interrupt_handler = interrupt_event;
+
+ /* Initialize the mechanism for doing insn profiling. */
+ CPU_INSN_NAME (cpu) = get_insn_name;
+ CPU_MAX_INSNS (cpu) = nr_itable_entries;
+
+ STATE = 0;
+
+ if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
+ return 0;
+ sim_add_option_table (sd, NULL, mips_options);
+
+
+ /* getopt will print the error message so we just have to exit if this fails.
+ FIXME: Hmmm... in the case of gdb we need getopt to call
+ print_filtered. */
+ if (sim_parse_args (sd, argv) != SIM_RC_OK)
+ {
+ /* Uninstall the modules to avoid memory leaks,
+ file descriptor leaks, etc. */
+ sim_module_uninstall (sd);
+ return 0;
+ }
+
+ /* handle board-specific memory maps */
+ if (board == NULL)
+ {
+ /* Allocate core managed memory */
+
+ /* the monitor */
+ sim_do_commandf (sd, "memory region 0x%lx,0x%lx", MONITOR_BASE, MONITOR_SIZE);
+ /* For compatibility with the old code - under this (at level one)
+ are the kernel spaces K0 & K1. Both of these map to a single
+ smaller sub region */
+ sim_do_command(sd," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
+ sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
+ K1BASE, K0SIZE,
+ MEM_SIZE, /* actual size */
+ K0BASE);
+
+ device_init(sd);
+ }
+
+#if (WITH_HW)
+ if (board != NULL
+ && (strcmp(board, BOARD_JMR3904) == 0 ||
+ strcmp(board, BOARD_JMR3904_PAL) == 0 ||
+ strcmp(board, BOARD_JMR3904_DEBUG) == 0))
+ {
+ /* match VIRTUAL memory layout of JMR-TX3904 board */
+ int i;
+
+ /* --- environment --- */
+
+ STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
+
+ /* --- memory --- */
+
+ /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
+ sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
+ 0x9FC00000,
+ 4 * 1024 * 1024, /* 4 MB */
+ 0xBFC00000);
+
+ /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
+ sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
+ 0x80000000,
+ 4 * 1024 * 1024, /* 4 MB */
+ 0xA0000000);
+
+ /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
+ for (i=0; i<8; i++) /* 32 MB total */
+ {
+ unsigned size = 4 * 1024 * 1024; /* 4 MB */
+ sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
+ 0x88000000 + (i * size),
+ size,
+ 0xA8000000 + (i * size));
+ }
+
+ /* Dummy memory regions for unsimulated devices */
+
+ sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFE010, 0x00c); /* EBIF */
+ sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFF9000, 0x200); /* EBIF */
+ sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFF500, 0x300); /* PIO */
+
+ /* --- simulated devices --- */
+ sim_hw_parse (sd, "/tx3904irc@0xffffc000/reg 0xffffc000 0x20");
+ sim_hw_parse (sd, "/tx3904cpu");
+ sim_hw_parse (sd, "/tx3904tmr@0xfffff000/reg 0xfffff000 0x100");
+ sim_hw_parse (sd, "/tx3904tmr@0xfffff100/reg 0xfffff100 0x100");
+ sim_hw_parse (sd, "/tx3904tmr@0xfffff200/reg 0xfffff200 0x100");
+ sim_hw_parse (sd, "/tx3904sio@0xfffff300/reg 0xfffff300 0x100");
+ {
+ /* FIXME: poking at dv-sockser internals, use tcp backend if
+ --sockser_addr option was given.*/
+ extern char* sockser_addr;
+ if(sockser_addr == NULL)
+ sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend stdio");
+ else
+ sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend tcp");
+ }
+ sim_hw_parse (sd, "/tx3904sio@0xfffff400/reg 0xfffff400 0x100");
+ sim_hw_parse (sd, "/tx3904sio@0xfffff400/backend stdio");
+
+ /* -- device connections --- */
+ sim_hw_parse (sd, "/tx3904irc > ip level /tx3904cpu");
+ sim_hw_parse (sd, "/tx3904tmr@0xfffff000 > int tmr0 /tx3904irc");
+ sim_hw_parse (sd, "/tx3904tmr@0xfffff100 > int tmr1 /tx3904irc");
+ sim_hw_parse (sd, "/tx3904tmr@0xfffff200 > int tmr2 /tx3904irc");
+ sim_hw_parse (sd, "/tx3904sio@0xfffff300 > int sio0 /tx3904irc");
+ sim_hw_parse (sd, "/tx3904sio@0xfffff400 > int sio1 /tx3904irc");
+
+ /* add PAL timer & I/O module */
+ if(! strcmp(board, BOARD_JMR3904_PAL))
+ {
+ /* the device */
+ sim_hw_parse (sd, "/pal@0xffff0000");
+ sim_hw_parse (sd, "/pal@0xffff0000/reg 0xffff0000 64");
+
+ /* wire up interrupt ports to irc */
+ sim_hw_parse (sd, "/pal@0x31000000 > countdown tmr0 /tx3904irc");
+ sim_hw_parse (sd, "/pal@0x31000000 > timer tmr1 /tx3904irc");
+ sim_hw_parse (sd, "/pal@0x31000000 > int int0 /tx3904irc");
+ }
+
+ if(! strcmp(board, BOARD_JMR3904_DEBUG))
+ {
+ /* -- DEBUG: glue interrupt generators --- */
+ sim_hw_parse (sd, "/glue@0xffff0000/reg 0xffff0000 0x50");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int0 int0 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int1 int1 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int2 int2 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int3 int3 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int4 int4 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int5 int5 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int6 int6 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int7 int7 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int8 dmac0 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int9 dmac1 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int10 dmac2 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int11 dmac3 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int12 sio0 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int13 sio1 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int14 tmr0 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int15 tmr1 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int16 tmr2 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int17 nmi /tx3904cpu");
+ }
+
+ device_init(sd);
+ }
+#endif
+
+
+ /* check for/establish the a reference program image */
+ if (sim_analyze_program (sd,
+ (STATE_PROG_ARGV (sd) != NULL
+ ? *STATE_PROG_ARGV (sd)
+ : NULL),
+ abfd) != SIM_RC_OK)
+ {
+ sim_module_uninstall (sd);
+ return 0;
+ }
+
+ /* Configure/verify the target byte order and other runtime
+ configuration options */
+ if (sim_config (sd) != SIM_RC_OK)
+ {
+ sim_module_uninstall (sd);
+ return 0;
+ }
+
+ if (sim_post_argv_init (sd) != SIM_RC_OK)
+ {
+ /* Uninstall the modules to avoid memory leaks,
+ file descriptor leaks, etc. */
+ sim_module_uninstall (sd);
+ return 0;
+ }
+
+ /* verify assumptions the simulator made about the host type system.
+ This macro does not return if there is a problem */
+ SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
+ SIM_ASSERT (sizeof(word64) == (8 * sizeof(char)));
+
+ /* This is NASTY, in that we are assuming the size of specific
+ registers: */
+ {
+ int rn;
+ for (rn = 0; (rn < (LAST_EMBED_REGNUM + 1)); rn++)
+ {
+ if (rn < 32)
+ cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
+ else if ((rn >= FGRIDX) && (rn < (FGRIDX + NR_FGR)))
+ cpu->register_widths[rn] = WITH_TARGET_FLOATING_POINT_BITSIZE;
+ else if ((rn >= 33) && (rn <= 37))
+ cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
+ else if ((rn == SRIDX)
+ || (rn == FCR0IDX)
+ || (rn == FCR31IDX)
+ || ((rn >= 72) && (rn <= 89)))
+ cpu->register_widths[rn] = 32;
+ else
+ cpu->register_widths[rn] = 0;
+ }
+
+
+ }
+
+#if defined(TRACE)
+ if (STATE & simTRACE)
+ open_trace(sd);
+#endif /* TRACE */
+
+ /* Write an abort sequence into the TRAP (common) exception vector
+ addresses. This is to catch code executing a TRAP (et.al.)
+ instruction without installing a trap handler. */
+ {
+ unsigned32 halt[2] = { 0x2404002f /* addiu r4, r0, 47 */,
+ HALT_INSTRUCTION /* BREAK */ };
+ H2T (halt[0]);
+ H2T (halt[1]);
+ sim_write (sd, 0x80000000, (char *) halt, sizeof (halt));
+ sim_write (sd, 0x80000180, (char *) halt, sizeof (halt));
+ sim_write (sd, 0x80000200, (char *) halt, sizeof (halt));
+ sim_write (sd, 0xBFC00200, (char *) halt, sizeof (halt));
+ sim_write (sd, 0xBFC00380, (char *) halt, sizeof (halt));
+ sim_write (sd, 0xBFC00400, (char *) halt, sizeof (halt));
+ }
+
+
+ /* Write the monitor trap address handlers into the monitor (eeprom)
+ address space. This can only be done once the target endianness
+ has been determined. */
+ {
+ unsigned loop;
+ /* Entry into the IDT monitor is via fixed address vectors, and
+ not using machine instructions. To avoid clashing with use of
+ the MIPS TRAP system, we place our own (simulator specific)
+ "undefined" instructions into the relevant vector slots. */
+ for (loop = 0; (loop < MONITOR_SIZE); loop += 4)
+ {
+ address_word vaddr = (MONITOR_BASE + loop);
+ unsigned32 insn = (RSVD_INSTRUCTION | (((loop >> 2) & RSVD_INSTRUCTION_ARG_MASK) << RSVD_INSTRUCTION_ARG_SHIFT));
+ H2T (insn);
+ sim_write (sd, vaddr, (char *)&insn, sizeof (insn));
+ }
+ /* The PMON monitor uses the same address space, but rather than
+ branching into it the address of a routine is loaded. We can
+ cheat for the moment, and direct the PMON routine to IDT style
+ instructions within the monitor space. This relies on the IDT
+ monitor not using the locations from 0xBFC00500 onwards as its
+ entry points.*/
+ for (loop = 0; (loop < 24); loop++)
+ {
+ address_word vaddr = (MONITOR_BASE + 0x500 + (loop * 4));
+ unsigned32 value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */
+ switch (loop)
+ {
+ case 0: /* read */
+ value = 7;
+ break;
+ case 1: /* write */
+ value = 8;
+ break;
+ case 2: /* open */
+ value = 6;
+ break;
+ case 3: /* close */
+ value = 10;
+ break;
+ case 5: /* printf */
+ value = ((0x500 - 16) / 8); /* not an IDT reason code */
+ break;
+ case 8: /* cliexit */
+ value = 17;
+ break;
+ case 11: /* flush_cache */
+ value = 28;
+ break;
+ }
+ /* FIXME - should monitor_base be SIM_ADDR?? */
+ value = ((unsigned int)MONITOR_BASE + (value * 8));
+ H2T (value);
+ sim_write (sd, vaddr, (char *)&value, sizeof (value));
+
+ /* The LSI MiniRISC PMON has its vectors at 0x200, not 0x500. */
+ vaddr -= 0x300;
+ sim_write (sd, vaddr, (char *)&value, sizeof (value));
+ }
+ }
+
+
+
+ return sd;
+}
+
+#if defined(TRACE)
+static void
+open_trace(sd)
+ SIM_DESC sd;
+{
+ tracefh = fopen(tracefile,"wb+");
+ if (tracefh == NULL)
+ {
+ sim_io_eprintf(sd,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile);
+ tracefh = stderr;
+ }
+}
+#endif /* TRACE */
+
+/* Return name of an insn, used by insn profiling. */
+static const char *
+get_insn_name (sim_cpu *cpu, int i)
+{
+ return itable[i].name;
+}
+
+void
+sim_close (sd, quitting)
+ SIM_DESC sd;
+ int quitting;
+{
+#ifdef DEBUG
+ printf("DBG: sim_close: entered (quitting = %d)\n",quitting);
+#endif
+
+
+ /* "quitting" is non-zero if we cannot hang on errors */
+
+ /* shut down modules */
+ sim_module_uninstall (sd);
+
+ /* Ensure that any resources allocated through the callback
+ mechanism are released: */
+ sim_io_shutdown (sd);
+
+#if defined(TRACE)
+ if (tracefh != NULL && tracefh != stderr)
+ fclose(tracefh);
+ tracefh = NULL;
+#endif /* TRACE */
+
+ /* FIXME - free SD */
+
+ return;
+}
+
+
+int
+sim_write (sd,addr,buffer,size)
+ SIM_DESC sd;
+ SIM_ADDR addr;
+ unsigned char *buffer;
+ int size;
+{
+ int index;
+ sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
+
+ /* Return the number of bytes written, or zero if error. */
+#ifdef DEBUG
+ sim_io_printf(sd,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr),size);
+#endif
+
+ /* We use raw read and write routines, since we do not want to count
+ the GDB memory accesses in our statistics gathering. */
+
+ for (index = 0; index < size; index++)
+ {
+ address_word vaddr = (address_word)addr + index;
+ address_word paddr;
+ int cca;
+ if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isSTORE, &paddr, &cca, isRAW))
+ break;
+ if (sim_core_write_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1)
+ break;
+ }
+
+ return(index);
+}
+
+int
+sim_read (sd,addr,buffer,size)
+ SIM_DESC sd;
+ SIM_ADDR addr;
+ unsigned char *buffer;
+ int size;
+{
+ int index;
+ sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
+
+ /* Return the number of bytes read, or zero if error. */
+#ifdef DEBUG
+ sim_io_printf(sd,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr),size);
+#endif /* DEBUG */
+
+ for (index = 0; (index < size); index++)
+ {
+ address_word vaddr = (address_word)addr + index;
+ address_word paddr;
+ int cca;
+ if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isLOAD, &paddr, &cca, isRAW))
+ break;
+ if (sim_core_read_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1)
+ break;
+ }
+
+ return(index);
+}
+
+int
+sim_store_register (sd,rn,memory,length)
+ SIM_DESC sd;
+ int rn;
+ unsigned char *memory;
+ int length;
+{
+ sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
+ /* NOTE: gdb (the client) stores registers in target byte order
+ while the simulator uses host byte order */
+#ifdef DEBUG
+ sim_io_printf(sd,"sim_store_register(%d,*memory=0x%s);\n",rn,pr_addr(*((SIM_ADDR *)memory)));
+#endif /* DEBUG */
+
+ /* Unfortunately this suffers from the same problem as the register
+ numbering one. We need to know what the width of each logical
+ register number is for the architecture being simulated. */
+
+ if (cpu->register_widths[rn] == 0)
+ {
+ sim_io_eprintf(sd,"Invalid register width for %d (register store ignored)\n",rn);
+ return 0;
+ }
+
+
+
+ if (rn >= FGRIDX && rn < FGRIDX + NR_FGR)
+ {
+ if (cpu->register_widths[rn] == 32)
+ {
+ cpu->fgr[rn - FGRIDX] = T2H_4 (*(unsigned32*)memory);
+ return 4;
+ }
+ else
+ {
+ cpu->fgr[rn - FGRIDX] = T2H_8 (*(unsigned64*)memory);
+ return 8;
+ }
+ }
+
+ if (cpu->register_widths[rn] == 32)
+ {
+ cpu->registers[rn] = T2H_4 (*(unsigned32*)memory);
+ return 4;
+ }
+ else
+ {
+ cpu->registers[rn] = T2H_8 (*(unsigned64*)memory);
+ return 8;
+ }
+
+ return 0;
+}
+
+int
+sim_fetch_register (sd,rn,memory,length)
+ SIM_DESC sd;
+ int rn;
+ unsigned char *memory;
+ int length;
+{
+ sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
+ /* NOTE: gdb (the client) stores registers in target byte order
+ while the simulator uses host byte order */
+#ifdef DEBUG
+#if 0 /* FIXME: doesn't compile */
+ sim_io_printf(sd,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn,pr_addr(registers[rn]));
+#endif
+#endif /* DEBUG */
+
+ if (cpu->register_widths[rn] == 0)
+ {
+ sim_io_eprintf (sd, "Invalid register width for %d (register fetch ignored)\n",rn);
+ return 0;
+ }
+
+
+
+ /* Any floating point register */
+ if (rn >= FGRIDX && rn < FGRIDX + NR_FGR)
+ {
+ if (cpu->register_widths[rn] == 32)
+ {
+ *(unsigned32*)memory = H2T_4 (cpu->fgr[rn - FGRIDX]);
+ return 4;
+ }
+ else
+ {
+ *(unsigned64*)memory = H2T_8 (cpu->fgr[rn - FGRIDX]);
+ return 8;
+ }
+ }
+
+ if (cpu->register_widths[rn] == 32)
+ {
+ *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn]));
+ return 4;
+ }
+ else
+ {
+ *(unsigned64*)memory = H2T_8 ((unsigned64)(cpu->registers[rn]));
+ return 8;
+ }
+
+ return 0;
+}
+
+
+SIM_RC
+sim_create_inferior (sd, abfd, argv,env)
+ SIM_DESC sd;
+ struct _bfd *abfd;
+ char **argv;
+ char **env;
+{
+
+#ifdef DEBUG
+#if 0 /* FIXME: doesn't compile */
+ printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
+ pr_addr(PC));
+#endif
+#endif /* DEBUG */
+
+ ColdReset(sd);
+
+ if (abfd != NULL)
+ {
+ /* override PC value set by ColdReset () */
+ int cpu_nr;
+ for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
+ {
+ sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
+ CIA_SET (cpu, (unsigned64) bfd_get_start_address (abfd));
+ }
+ }
+
+#if 0 /* def DEBUG */
+ if (argv || env)
+ {
+ /* We should really place the argv slot values into the argument
+ registers, and onto the stack as required. However, this
+ assumes that we have a stack defined, which is not
+ necessarily true at the moment. */
+ char **cptr;
+ sim_io_printf(sd,"sim_create_inferior() : passed arguments ignored\n");
+ for (cptr = argv; (cptr && *cptr); cptr++)
+ printf("DBG: arg \"%s\"\n",*cptr);
+ }
+#endif /* DEBUG */
+
+ return SIM_RC_OK;
+}
+
+void
+sim_do_command (sd,cmd)
+ SIM_DESC sd;
+ char *cmd;
+{
+ if (sim_args_command (sd, cmd) != SIM_RC_OK)
+ sim_io_printf (sd, "Error: \"%s\" is not a valid MIPS simulator command.\n",
+ cmd);
+}
+
+/*---------------------------------------------------------------------------*/
+/*-- Private simulator support interface ------------------------------------*/
+/*---------------------------------------------------------------------------*/
+
+/* Read a null terminated string from memory, return in a buffer */
+static char *
+fetch_str (SIM_DESC sd,
+ address_word addr)
+{
+ char *buf;
+ int nr = 0;
+ char null;
+ while (sim_read (sd, addr + nr, &null, 1) == 1 && null != 0)
+ nr++;
+ buf = NZALLOC (char, nr + 1);
+ sim_read (sd, addr, buf, nr);
+ return buf;
+}
+
+/* Simple monitor interface (currently setup for the IDT and PMON monitors) */
+void
+sim_monitor (SIM_DESC sd,
+ sim_cpu *cpu,
+ address_word cia,
+ unsigned int reason)
+{
+#ifdef DEBUG
+ printf("DBG: sim_monitor: entered (reason = %d)\n",reason);
+#endif /* DEBUG */
+
+ /* The IDT monitor actually allows two instructions per vector
+ slot. However, the simulator currently causes a trap on each
+ individual instruction. We cheat, and lose the bottom bit. */
+ reason >>= 1;
+
+ /* The following callback functions are available, however the
+ monitor we are simulating does not make use of them: get_errno,
+ isatty, lseek, rename, system, time and unlink */
+ switch (reason)
+ {
+
+ case 6: /* int open(char *path,int flags) */
+ {
+ char *path = fetch_str (sd, A0);
+ V0 = sim_io_open (sd, path, (int)A1);
+ zfree (path);
+ break;
+ }
+
+ case 7: /* int read(int file,char *ptr,int len) */
+ {
+ int fd = A0;
+ int nr = A2;
+ char *buf = zalloc (nr);
+ V0 = sim_io_read (sd, fd, buf, nr);
+ sim_write (sd, A1, buf, nr);
+ zfree (buf);
+ }
+ break;
+
+ case 8: /* int write(int file,char *ptr,int len) */
+ {
+ int fd = A0;
+ int nr = A2;
+ char *buf = zalloc (nr);
+ sim_read (sd, A1, buf, nr);
+ V0 = sim_io_write (sd, fd, buf, nr);
+ zfree (buf);
+ break;
+ }
+
+ case 10: /* int close(int file) */
+ {
+ V0 = sim_io_close (sd, (int)A0);
+ break;
+ }
+
+ case 2: /* Densan monitor: char inbyte(int waitflag) */
+ {
+ if (A0 == 0) /* waitflag == NOWAIT */
+ V0 = (unsigned_word)-1;
+ }
+ /* Drop through to case 11 */
+
+ case 11: /* char inbyte(void) */
+ {
+ char tmp;
+ if (sim_io_read_stdin (sd, &tmp, sizeof(char)) != sizeof(char))
+ {
+ sim_io_error(sd,"Invalid return from character read");
+ V0 = (unsigned_word)-1;
+ }
+ else
+ V0 = (unsigned_word)tmp;
+ break;
+ }
+
+ case 3: /* Densan monitor: void co(char chr) */
+ case 12: /* void outbyte(char chr) : write a byte to "stdout" */
+ {
+ char tmp = (char)(A0 & 0xFF);
+ sim_io_write_stdout (sd, &tmp, sizeof(char));
+ break;
+ }
+
+ case 17: /* void _exit() */
+ {
+ sim_io_eprintf (sd, "sim_monitor(17): _exit(int reason) to be coded\n");
+ sim_engine_halt (SD, CPU, NULL, NULL_CIA, sim_exited,
+ (unsigned int)(A0 & 0xFFFFFFFF));
+ break;
+ }
+
+ case 28 : /* PMON flush_cache */
+ break;
+
+ case 55: /* void get_mem_info(unsigned int *ptr) */
+ /* in: A0 = pointer to three word memory location */
+ /* out: [A0 + 0] = size */
+ /* [A0 + 4] = instruction cache size */
+ /* [A0 + 8] = data cache size */
+ {
+ unsigned_4 value = MEM_SIZE /* FIXME STATE_MEM_SIZE (sd) */;
+ unsigned_4 zero = 0;
+ H2T (value);
+ sim_write (sd, A0 + 0, (char *)&value, 4);
+ sim_write (sd, A0 + 4, (char *)&zero, 4);
+ sim_write (sd, A0 + 8, (char *)&zero, 4);
+ /* sim_io_eprintf (sd, "sim: get_mem_info() depreciated\n"); */
+ break;
+ }
+
+ case 158 : /* PMON printf */
+ /* in: A0 = pointer to format string */
+ /* A1 = optional argument 1 */
+ /* A2 = optional argument 2 */
+ /* A3 = optional argument 3 */
+ /* out: void */
+ /* The following is based on the PMON printf source */
+ {
+ address_word s = A0;
+ char c;
+ signed_word *ap = &A1; /* 1st argument */
+ /* This isn't the quickest way, since we call the host print
+ routine for every character almost. But it does avoid
+ having to allocate and manage a temporary string buffer. */
+ /* TODO: Include check that we only use three arguments (A1,
+ A2 and A3) */
+ while (sim_read (sd, s++, &c, 1) && c != '\0')
+ {
+ if (c == '%')
+ {
+ char tmp[40];
+ enum {FMT_RJUST, FMT_LJUST, FMT_RJUST0, FMT_CENTER} fmt = FMT_RJUST;
+ int width = 0, trunc = 0, haddot = 0, longlong = 0;
+ while (sim_read (sd, s++, &c, 1) && c != '\0')
+ {
+ if (strchr ("dobxXulscefg%", c))
+ break;
+ else if (c == '-')
+ fmt = FMT_LJUST;
+ else if (c == '0')
+ fmt = FMT_RJUST0;
+ else if (c == '~')
+ fmt = FMT_CENTER;
+ else if (c == '*')
+ {
+ if (haddot)
+ trunc = (int)*ap++;
+ else
+ width = (int)*ap++;
+ }
+ else if (c >= '1' && c <= '9')
+ {
+ address_word t = s;
+ unsigned int n;
+ while (sim_read (sd, s++, &c, 1) == 1 && isdigit (c))
+ tmp[s - t] = c;
+ tmp[s - t] = '\0';
+ n = (unsigned int)strtol(tmp,NULL,10);
+ if (haddot)
+ trunc = n;
+ else
+ width = n;
+ s--;
+ }
+ else if (c == '.')
+ haddot = 1;
+ }
+ switch (c)
+ {
+ case '%':
+ sim_io_printf (sd, "%%");
+ break;
+ case 's':
+ if ((int)*ap != 0)
+ {
+ address_word p = *ap++;
+ char ch;
+ while (sim_read (sd, p++, &ch, 1) == 1 && ch != '\0')
+ sim_io_printf(sd, "%c", ch);
+ }
+ else
+ sim_io_printf(sd,"(null)");
+ break;
+ case 'c':
+ sim_io_printf (sd, "%c", (int)*ap++);
+ break;
+ default:
+ if (c == 'l')
+ {
+ sim_read (sd, s++, &c, 1);
+ if (c == 'l')
+ {
+ longlong = 1;
+ sim_read (sd, s++, &c, 1);
+ }
+ }
+ if (strchr ("dobxXu", c))
+ {
+ word64 lv = (word64) *ap++;
+ if (c == 'b')
+ sim_io_printf(sd,"<binary not supported>");
+ else
+ {
+ sprintf (tmp, "%%%s%c", longlong ? "ll" : "", c);
+ if (longlong)
+ sim_io_printf(sd, tmp, lv);
+ else
+ sim_io_printf(sd, tmp, (int)lv);
+ }
+ }
+ else if (strchr ("eEfgG", c))
+ {
+ double dbl = *(double*)(ap++);
+ sprintf (tmp, "%%%d.%d%c", width, trunc, c);
+ sim_io_printf (sd, tmp, dbl);
+ trunc = 0;
+ }
+ }
+ }
+ else
+ sim_io_printf(sd, "%c", c);
+ }
+ break;
+ }
+
+ default:
+ sim_io_error (sd, "TODO: sim_monitor(%d) : PC = 0x%s\n",
+ reason, pr_addr(cia));
+ break;
+ }
+ return;
+}
+
+/* Store a word into memory. */
+
+static void
+store_word (SIM_DESC sd,
+ sim_cpu *cpu,
+ address_word cia,
+ uword64 vaddr,
+ signed_word val)
+{
+ address_word paddr;
+ int uncached;
+
+ if ((vaddr & 3) != 0)
+ SignalExceptionAddressStore ();
+ else
+ {
+ if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
+ isTARGET, isREAL))
+ {
+ const uword64 mask = 7;
+ uword64 memval;
+ unsigned int byte;
+
+ paddr = (paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2));
+ byte = (vaddr & mask) ^ (BigEndianCPU << 2);
+ memval = ((uword64) val) << (8 * byte);
+ StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr, vaddr,
+ isREAL);
+ }
+ }
+}
+
+/* Load a word from memory. */
+
+static signed_word
+load_word (SIM_DESC sd,
+ sim_cpu *cpu,
+ address_word cia,
+ uword64 vaddr)
+{
+ if ((vaddr & 3) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, cpu, cia, read_map, AccessLength_WORD+1, vaddr, read_transfer, sim_core_unaligned_signal);
+ }
+ else
+ {
+ address_word paddr;
+ int uncached;
+
+ if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
+ isTARGET, isREAL))
+ {
+ const uword64 mask = 0x7;
+ const unsigned int reverse = ReverseEndian ? 1 : 0;
+ const unsigned int bigend = BigEndianCPU ? 1 : 0;
+ uword64 memval;
+ unsigned int byte;
+
+ paddr = (paddr & ~mask) | ((paddr & mask) ^ (reverse << 2));
+ LoadMemory (&memval,NULL,uncached, AccessLength_WORD, paddr, vaddr,
+ isDATA, isREAL);
+ byte = (vaddr & mask) ^ (bigend << 2);
+ return SIGNEXTEND (((memval >> (8 * byte)) & 0xffffffff), 32);
+ }
+ }
+
+ return 0;
+}
+
+/* Simulate the mips16 entry and exit pseudo-instructions. These
+ would normally be handled by the reserved instruction exception
+ code, but for ease of simulation we just handle them directly. */
+
+static void
+mips16_entry (SIM_DESC sd,
+ sim_cpu *cpu,
+ address_word cia,
+ unsigned int insn)
+{
+ int aregs, sregs, rreg;
+
+#ifdef DEBUG
+ printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn);
+#endif /* DEBUG */
+
+ aregs = (insn & 0x700) >> 8;
+ sregs = (insn & 0x0c0) >> 6;
+ rreg = (insn & 0x020) >> 5;
+
+ /* This should be checked by the caller. */
+ if (sregs == 3)
+ abort ();
+
+ if (aregs < 5)
+ {
+ int i;
+ signed_word tsp;
+
+ /* This is the entry pseudo-instruction. */
+
+ for (i = 0; i < aregs; i++)
+ store_word (SD, CPU, cia, (uword64) (SP + 4 * i), GPR[i + 4]);
+
+ tsp = SP;
+ SP -= 32;
+
+ if (rreg)
+ {
+ tsp -= 4;
+ store_word (SD, CPU, cia, (uword64) tsp, RA);
+ }
+
+ for (i = 0; i < sregs; i++)
+ {
+ tsp -= 4;
+ store_word (SD, CPU, cia, (uword64) tsp, GPR[16 + i]);
+ }
+ }
+ else
+ {
+ int i;
+ signed_word tsp;
+
+ /* This is the exit pseudo-instruction. */
+
+ tsp = SP + 32;
+
+ if (rreg)
+ {
+ tsp -= 4;
+ RA = load_word (SD, CPU, cia, (uword64) tsp);
+ }
+
+ for (i = 0; i < sregs; i++)
+ {
+ tsp -= 4;
+ GPR[i + 16] = load_word (SD, CPU, cia, (uword64) tsp);
+ }
+
+ SP += 32;
+
+ if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
+ {
+ if (aregs == 5)
+ {
+ FGR[0] = WORD64LO (GPR[4]);
+ FPR_STATE[0] = fmt_uninterpreted;
+ }
+ else if (aregs == 6)
+ {
+ FGR[0] = WORD64LO (GPR[5]);
+ FGR[1] = WORD64LO (GPR[4]);
+ FPR_STATE[0] = fmt_uninterpreted;
+ FPR_STATE[1] = fmt_uninterpreted;
+ }
+ }
+
+ PC = RA;
+ }
+
+}
+
+/*-- trace support ----------------------------------------------------------*/
+
+/* The TRACE support is provided (if required) in the memory accessing
+ routines. Since we are also providing the architecture specific
+ features, the architecture simulation code can also deal with
+ notifying the TRACE world of cache flushes, etc. Similarly we do
+ not need to provide profiling support in the simulator engine,
+ since we can sample in the instruction fetch control loop. By
+ defining the TRACE manifest, we add tracing as a run-time
+ option. */
+
+#if defined(TRACE)
+/* Tracing by default produces "din" format (as required by
+ dineroIII). Each line of such a trace file *MUST* have a din label
+ and address field. The rest of the line is ignored, so comments can
+ be included if desired. The first field is the label which must be
+ one of the following values:
+
+ 0 read data
+ 1 write data
+ 2 instruction fetch
+ 3 escape record (treated as unknown access type)
+ 4 escape record (causes cache flush)
+
+ The address field is a 32bit (lower-case) hexadecimal address
+ value. The address should *NOT* be preceded by "0x".
+
+ The size of the memory transfer is not important when dealing with
+ cache lines (as long as no more than a cache line can be
+ transferred in a single operation :-), however more information
+ could be given following the dineroIII requirement to allow more
+ complete memory and cache simulators to provide better
+ results. i.e. the University of Pisa has a cache simulator that can
+ also take bus size and speed as (variable) inputs to calculate
+ complete system performance (a much more useful ability when trying
+ to construct an end product, rather than a processor). They
+ currently have an ARM version of their tool called ChARM. */
+
+
+void
+dotrace (SIM_DESC sd,
+ sim_cpu *cpu,
+ FILE *tracefh,
+ int type,
+ SIM_ADDR address,
+ int width,
+ char *comment,...)
+{
+ if (STATE & simTRACE) {
+ va_list ap;
+ fprintf(tracefh,"%d %s ; width %d ; ",
+ type,
+ pr_addr(address),
+ width);
+ va_start(ap,comment);
+ vfprintf(tracefh,comment,ap);
+ va_end(ap);
+ fprintf(tracefh,"\n");
+ }
+ /* NOTE: Since the "din" format will only accept 32bit addresses, and
+ we may be generating 64bit ones, we should put the hi-32bits of the
+ address into the comment field. */
+
+ /* TODO: Provide a buffer for the trace lines. We can then avoid
+ performing writes until the buffer is filled, or the file is
+ being closed. */
+
+ /* NOTE: We could consider adding a comment field to the "din" file
+ produced using type 3 markers (unknown access). This would then
+ allow information about the program that the "din" is for, and
+ the MIPs world that was being simulated, to be placed into the
+ trace file. */
+
+ return;
+}
+#endif /* TRACE */
+
+/*---------------------------------------------------------------------------*/
+/*-- simulator engine -------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+
+static void
+ColdReset (SIM_DESC sd)
+{
+ int cpu_nr;
+ for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
+ {
+ sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
+ /* RESET: Fixed PC address: */
+ PC = (unsigned_word) UNSIGNED64 (0xFFFFFFFFBFC00000);
+ /* The reset vector address is in the unmapped, uncached memory space. */
+
+ SR &= ~(status_SR | status_TS | status_RP);
+ SR |= (status_ERL | status_BEV);
+
+ /* Cheat and allow access to the complete register set immediately */
+ if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT
+ && WITH_TARGET_WORD_BITSIZE == 64)
+ SR |= status_FR; /* 64bit registers */
+
+ /* Ensure that any instructions with pending register updates are
+ cleared: */
+ PENDING_INVALIDATE();
+
+ /* Initialise the FPU registers to the unknown state */
+ if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
+ {
+ int rn;
+ for (rn = 0; (rn < 32); rn++)
+ FPR_STATE[rn] = fmt_uninterpreted;
+ }
+
+ }
+}
+
+
+
+
+/* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
+/* Signal an exception condition. This will result in an exception
+ that aborts the instruction. The instruction operation pseudocode
+ will never see a return from this function call. */
+
+void
+signal_exception (SIM_DESC sd,
+ sim_cpu *cpu,
+ address_word cia,
+ int exception,...)
+{
+ /* int vector; */
+
+#ifdef DEBUG
+ sim_io_printf(sd,"DBG: SignalException(%d) PC = 0x%s\n",exception,pr_addr(cia));
+#endif /* DEBUG */
+
+ /* Ensure that any active atomic read/modify/write operation will fail: */
+ LLBIT = 0;
+
+ /* Save registers before interrupt dispatching */
+#ifdef SIM_CPU_EXCEPTION_TRIGGER
+ SIM_CPU_EXCEPTION_TRIGGER(sd, cpu, cia);
+#endif
+
+ switch (exception) {
+
+ case DebugBreakPoint :
+ if (! (Debug & Debug_DM))
+ {
+ if (INDELAYSLOT())
+ {
+ CANCELDELAYSLOT();
+
+ Debug |= Debug_DBD; /* signaled from within in delay slot */
+ DEPC = cia - 4; /* reference the branch instruction */
+ }
+ else
+ {
+ Debug &= ~Debug_DBD; /* not signaled from within a delay slot */
+ DEPC = cia;
+ }
+
+ Debug |= Debug_DM; /* in debugging mode */
+ Debug |= Debug_DBp; /* raising a DBp exception */
+ PC = 0xBFC00200;
+ sim_engine_restart (SD, CPU, NULL, NULL_CIA);
+ }
+ break;
+
+ case ReservedInstruction :
+ {
+ va_list ap;
+ unsigned int instruction;
+ va_start(ap,exception);
+ instruction = va_arg(ap,unsigned int);
+ va_end(ap);
+ /* Provide simple monitor support using ReservedInstruction
+ exceptions. The following code simulates the fixed vector
+ entry points into the IDT monitor by causing a simulator
+ trap, performing the monitor operation, and returning to
+ the address held in the $ra register (standard PCS return
+ address). This means we only need to pre-load the vector
+ space with suitable instruction values. For systems were
+ actual trap instructions are used, we would not need to
+ perform this magic. */
+ if ((instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION)
+ {
+ sim_monitor (SD, CPU, cia, ((instruction >> RSVD_INSTRUCTION_ARG_SHIFT) & RSVD_INSTRUCTION_ARG_MASK) );
+ /* NOTE: This assumes that a branch-and-link style
+ instruction was used to enter the vector (which is the
+ case with the current IDT monitor). */
+ sim_engine_restart (SD, CPU, NULL, RA);
+ }
+ /* Look for the mips16 entry and exit instructions, and
+ simulate a handler for them. */
+ else if ((cia & 1) != 0
+ && (instruction & 0xf81f) == 0xe809
+ && (instruction & 0x0c0) != 0x0c0)
+ {
+ mips16_entry (SD, CPU, cia, instruction);
+ sim_engine_restart (sd, NULL, NULL, NULL_CIA);
+ }
+ /* else fall through to normal exception processing */
+ sim_io_eprintf(sd,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia));
+ }
+
+ default:
+ /* Store exception code into current exception id variable (used
+ by exit code): */
+
+ /* TODO: If not simulating exceptions then stop the simulator
+ execution. At the moment we always stop the simulation. */
+
+#ifdef SUBTARGET_R3900
+ /* update interrupt-related registers */
+
+ /* insert exception code in bits 6:2 */
+ CAUSE = LSMASKED32(CAUSE, 31, 7) | LSINSERTED32(exception, 6, 2);
+ /* shift IE/KU history bits left */
+ SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 3, 0), 5, 2);
+
+ if (STATE & simDELAYSLOT)
+ {
+ STATE &= ~simDELAYSLOT;
+ CAUSE |= cause_BD;
+ EPC = (cia - 4); /* reference the branch instruction */
+ }
+ else
+ EPC = cia;
+
+ if (SR & status_BEV)
+ PC = (signed)0xBFC00000 + 0x180;
+ else
+ PC = (signed)0x80000000 + 0x080;
+#else
+ /* See figure 5-17 for an outline of the code below */
+ if (! (SR & status_EXL))
+ {
+ CAUSE = (exception << 2);
+ if (STATE & simDELAYSLOT)
+ {
+ STATE &= ~simDELAYSLOT;
+ CAUSE |= cause_BD;
+ EPC = (cia - 4); /* reference the branch instruction */
+ }
+ else
+ EPC = cia;
+ /* FIXME: TLB et.al. */
+ /* vector = 0x180; */
+ }
+ else
+ {
+ CAUSE = (exception << 2);
+ /* vector = 0x180; */
+ }
+ SR |= status_EXL;
+ /* Store exception code into current exception id variable (used
+ by exit code): */
+
+ if (SR & status_BEV)
+ PC = (signed)0xBFC00200 + 0x180;
+ else
+ PC = (signed)0x80000000 + 0x180;
+#endif
+
+ switch ((CAUSE >> 2) & 0x1F)
+ {
+ case Interrupt:
+ /* Interrupts arrive during event processing, no need to
+ restart */
+ return;
+
+ case NMIReset:
+ /* Ditto */
+#ifdef SUBTARGET_3900
+ /* Exception vector: BEV=0 BFC00000 / BEF=1 BFC00000 */
+ PC = (signed)0xBFC00000;
+#endif SUBTARGET_3900
+ return;
+
+ case TLBModification:
+ case TLBLoad:
+ case TLBStore:
+ case AddressLoad:
+ case AddressStore:
+ case InstructionFetch:
+ case DataReference:
+ /* The following is so that the simulator will continue from the
+ exception handler address. */
+ sim_engine_halt (SD, CPU, NULL, PC,
+ sim_stopped, SIM_SIGBUS);
+
+ case ReservedInstruction:
+ case CoProcessorUnusable:
+ PC = EPC;
+ sim_engine_halt (SD, CPU, NULL, PC,
+ sim_stopped, SIM_SIGILL);
+
+ case IntegerOverflow:
+ case FPE:
+ sim_engine_halt (SD, CPU, NULL, PC,
+ sim_stopped, SIM_SIGFPE);
+
+ case BreakPoint:
+ sim_engine_halt (SD, CPU, NULL, PC, sim_stopped, SIM_SIGTRAP);
+ break;
+
+ case SystemCall:
+ case Trap:
+ sim_engine_restart (SD, CPU, NULL, PC);
+ break;
+
+ case Watch:
+ PC = EPC;
+ sim_engine_halt (SD, CPU, NULL, PC,
+ sim_stopped, SIM_SIGTRAP);
+
+ default : /* Unknown internal exception */
+ PC = EPC;
+ sim_engine_halt (SD, CPU, NULL, PC,
+ sim_stopped, SIM_SIGABRT);
+
+ }
+
+ case SimulatorFault:
+ {
+ va_list ap;
+ char *msg;
+ va_start(ap,exception);
+ msg = va_arg(ap,char *);
+ va_end(ap);
+ sim_engine_abort (SD, CPU, NULL_CIA,
+ "FATAL: Simulator error \"%s\"\n",msg);
+ }
+ }
+
+ return;
+}
+
+
+
+#if defined(WARN_RESULT)
+/* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
+/* This function indicates that the result of the operation is
+ undefined. However, this should not affect the instruction
+ stream. All that is meant to happen is that the destination
+ register is set to an undefined result. To keep the simulator
+ simple, we just don't bother updating the destination register, so
+ the overall result will be undefined. If desired we can stop the
+ simulator by raising a pseudo-exception. */
+#define UndefinedResult() undefined_result (sd,cia)
+static void
+undefined_result(sd,cia)
+ SIM_DESC sd;
+ address_word cia;
+{
+ sim_io_eprintf(sd,"UndefinedResult: PC = 0x%s\n",pr_addr(cia));
+#if 0 /* Disabled for the moment, since it actually happens a lot at the moment. */
+ state |= simSTOP;
+#endif
+ return;
+}
+#endif /* WARN_RESULT */
+
+/*-- FPU support routines ---------------------------------------------------*/
+
+/* Numbers are held in normalized form. The SINGLE and DOUBLE binary
+ formats conform to ANSI/IEEE Std 754-1985. */
+/* SINGLE precision floating:
+ * seeeeeeeefffffffffffffffffffffff
+ * s = 1bit = sign
+ * e = 8bits = exponent
+ * f = 23bits = fraction
+ */
+/* SINGLE precision fixed:
+ * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+ * s = 1bit = sign
+ * i = 31bits = integer
+ */
+/* DOUBLE precision floating:
+ * seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
+ * s = 1bit = sign
+ * e = 11bits = exponent
+ * f = 52bits = fraction
+ */
+/* DOUBLE precision fixed:
+ * siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+ * s = 1bit = sign
+ * i = 63bits = integer
+ */
+
+/* Extract sign-bit: */
+#define FP_S_s(v) (((v) & ((unsigned)1 << 31)) ? 1 : 0)
+#define FP_D_s(v) (((v) & ((uword64)1 << 63)) ? 1 : 0)
+/* Extract biased exponent: */
+#define FP_S_be(v) (((v) >> 23) & 0xFF)
+#define FP_D_be(v) (((v) >> 52) & 0x7FF)
+/* Extract unbiased Exponent: */
+#define FP_S_e(v) (FP_S_be(v) - 0x7F)
+#define FP_D_e(v) (FP_D_be(v) - 0x3FF)
+/* Extract complete fraction field: */
+#define FP_S_f(v) ((v) & ~((unsigned)0x1FF << 23))
+#define FP_D_f(v) ((v) & ~((uword64)0xFFF << 52))
+/* Extract numbered fraction bit: */
+#define FP_S_fb(b,v) (((v) & (1 << (23 - (b)))) ? 1 : 0)
+#define FP_D_fb(b,v) (((v) & (1 << (52 - (b)))) ? 1 : 0)
+
+/* Explicit QNaN values used when value required: */
+#define FPQNaN_SINGLE (0x7FBFFFFF)
+#define FPQNaN_WORD (0x7FFFFFFF)
+#define FPQNaN_DOUBLE (((uword64)0x7FF7FFFF << 32) | 0xFFFFFFFF)
+#define FPQNaN_LONG (((uword64)0x7FFFFFFF << 32) | 0xFFFFFFFF)
+
+/* Explicit Infinity values used when required: */
+#define FPINF_SINGLE (0x7F800000)
+#define FPINF_DOUBLE (((uword64)0x7FF00000 << 32) | 0x00000000)
+
+#define RMMODE(v) (((v) == FP_RM_NEAREST) ? "Round" : (((v) == FP_RM_TOZERO) ? "Trunc" : (((v) == FP_RM_TOPINF) ? "Ceil" : "Floor")))
+#define DOFMT(v) (((v) == fmt_single) ? "single" : (((v) == fmt_double) ? "double" : (((v) == fmt_word) ? "word" : (((v) == fmt_long) ? "long" : (((v) == fmt_unknown) ? "<unknown>" : (((v) == fmt_uninterpreted) ? "<uninterpreted>" : (((v) == fmt_uninterpreted_32) ? "<uninterpreted_32>" : (((v) == fmt_uninterpreted_64) ? "<uninterpreted_64>" : "<format error>"))))))))
+
+uword64
+value_fpr (SIM_DESC sd,
+ sim_cpu *cpu,
+ address_word cia,
+ int fpr,
+ FP_formats fmt)
+{
+ uword64 value = 0;
+ int err = 0;
+
+ /* Treat unused register values, as fixed-point 64bit values: */
+ if ((fmt == fmt_uninterpreted) || (fmt == fmt_unknown))
+#if 1
+ /* If request to read data as "uninterpreted", then use the current
+ encoding: */
+ fmt = FPR_STATE[fpr];
+#else
+ fmt = fmt_long;
+#endif
+
+ /* For values not yet accessed, set to the desired format: */
+ if (FPR_STATE[fpr] == fmt_uninterpreted) {
+ FPR_STATE[fpr] = fmt;
+#ifdef DEBUG
+ printf("DBG: Register %d was fmt_uninterpreted. Now %s\n",fpr,DOFMT(fmt));
+#endif /* DEBUG */
+ }
+ if (fmt != FPR_STATE[fpr]) {
+ sim_io_eprintf(sd,"FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",fpr,DOFMT(FPR_STATE[fpr]),DOFMT(fmt),pr_addr(cia));
+ FPR_STATE[fpr] = fmt_unknown;
+ }
+
+ if (FPR_STATE[fpr] == fmt_unknown) {
+ /* Set QNaN value: */
+ switch (fmt) {
+ case fmt_single:
+ value = FPQNaN_SINGLE;
+ break;
+
+ case fmt_double:
+ value = FPQNaN_DOUBLE;
+ break;
+
+ case fmt_word:
+ value = FPQNaN_WORD;
+ break;
+
+ case fmt_long:
+ value = FPQNaN_LONG;
+ break;
+
+ default:
+ err = -1;
+ break;
+ }
+ } else if (SizeFGR() == 64) {
+ switch (fmt) {
+ case fmt_single:
+ case fmt_word:
+ value = (FGR[fpr] & 0xFFFFFFFF);
+ break;
+
+ case fmt_uninterpreted:
+ case fmt_double:
+ case fmt_long:
+ value = FGR[fpr];
+ break;
+
+ default :
+ err = -1;
+ break;
+ }
+ } else {
+ switch (fmt) {
+ case fmt_single:
+ case fmt_word:
+ value = (FGR[fpr] & 0xFFFFFFFF);
+ break;
+
+ case fmt_uninterpreted:
+ case fmt_double:
+ case fmt_long:
+ if ((fpr & 1) == 0) { /* even registers only */
+#ifdef DEBUG
+ printf("DBG: ValueFPR: FGR[%d] = %s, FGR[%d] = %s\n",
+ fpr+1, pr_uword64( (uword64) FGR[fpr+1] ),
+ fpr, pr_uword64( (uword64) FGR[fpr] ));
+#endif
+ value = ((((uword64)FGR[fpr+1]) << 32) | (FGR[fpr] & 0xFFFFFFFF));
+ } else {
+ SignalException(ReservedInstruction,0);
+ }
+ break;
+
+ default :
+ err = -1;
+ break;
+ }
+ }
+
+ if (err)
+ SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR()");
+
+#ifdef DEBUG
+ printf("DBG: ValueFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR() = %d\n",fpr,DOFMT(fmt),pr_uword64(value),pr_addr(cia),SizeFGR());
+#endif /* DEBUG */
+
+ return(value);
+}
+
+void
+store_fpr (SIM_DESC sd,
+ sim_cpu *cpu,
+ address_word cia,
+ int fpr,
+ FP_formats fmt,
+ uword64 value)
+{
+ int err = 0;
+
+#ifdef DEBUG
+ printf("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR() = %d,\n",fpr,DOFMT(fmt),pr_uword64(value),pr_addr(cia),SizeFGR());
+#endif /* DEBUG */
+
+ if (SizeFGR() == 64) {
+ switch (fmt) {
+ case fmt_uninterpreted_32:
+ fmt = fmt_uninterpreted;
+ case fmt_single :
+ case fmt_word :
+ FGR[fpr] = (((uword64)0xDEADC0DE << 32) | (value & 0xFFFFFFFF));
+ FPR_STATE[fpr] = fmt;
+ break;
+
+ case fmt_uninterpreted_64:
+ fmt = fmt_uninterpreted;
+ case fmt_uninterpreted:
+ case fmt_double :
+ case fmt_long :
+ FGR[fpr] = value;
+ FPR_STATE[fpr] = fmt;
+ break;
+
+ default :
+ FPR_STATE[fpr] = fmt_unknown;
+ err = -1;
+ break;
+ }
+ } else {
+ switch (fmt) {
+ case fmt_uninterpreted_32:
+ fmt = fmt_uninterpreted;
+ case fmt_single :
+ case fmt_word :
+ FGR[fpr] = (value & 0xFFFFFFFF);
+ FPR_STATE[fpr] = fmt;
+ break;
+
+ case fmt_uninterpreted_64:
+ fmt = fmt_uninterpreted;
+ case fmt_uninterpreted:
+ case fmt_double :
+ case fmt_long :
+ if ((fpr & 1) == 0) { /* even register number only */
+ FGR[fpr+1] = (value >> 32);
+ FGR[fpr] = (value & 0xFFFFFFFF);
+ FPR_STATE[fpr + 1] = fmt;
+ FPR_STATE[fpr] = fmt;
+ } else {
+ FPR_STATE[fpr] = fmt_unknown;
+ FPR_STATE[fpr + 1] = fmt_unknown;
+ SignalException(ReservedInstruction,0);
+ }
+ break;
+
+ default :
+ FPR_STATE[fpr] = fmt_unknown;
+ err = -1;
+ break;
+ }
+ }
+#if defined(WARN_RESULT)
+ else
+ UndefinedResult();
+#endif /* WARN_RESULT */
+
+ if (err)
+ SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR()");
+
+#ifdef DEBUG
+ printf("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",fpr,pr_uword64(FGR[fpr]),DOFMT(fmt));
+#endif /* DEBUG */
+
+ return;
+}
+
+int
+NaN(op,fmt)
+ uword64 op;
+ FP_formats fmt;
+{
+ int boolean = 0;
+ switch (fmt) {
+ case fmt_single:
+ case fmt_word:
+ {
+ sim_fpu wop;
+ sim_fpu_32to (&wop, op);
+ boolean = sim_fpu_is_nan (&wop);
+ break;
+ }
+ case fmt_double:
+ case fmt_long:
+ {
+ sim_fpu wop;
+ sim_fpu_64to (&wop, op);
+ boolean = sim_fpu_is_nan (&wop);
+ break;
+ }
+ default:
+ fprintf (stderr, "Bad switch\n");
+ abort ();
+ }
+
+#ifdef DEBUG
+printf("DBG: NaN: returning %d for 0x%s (format = %s)\n",boolean,pr_addr(op),DOFMT(fmt));
+#endif /* DEBUG */
+
+ return(boolean);
+}
+
+int
+Infinity(op,fmt)
+ uword64 op;
+ FP_formats fmt;
+{
+ int boolean = 0;
+
+#ifdef DEBUG
+ printf("DBG: Infinity: format %s 0x%s\n",DOFMT(fmt),pr_addr(op));
+#endif /* DEBUG */
+
+ switch (fmt) {
+ case fmt_single:
+ {
+ sim_fpu wop;
+ sim_fpu_32to (&wop, op);
+ boolean = sim_fpu_is_infinity (&wop);
+ break;
+ }
+ case fmt_double:
+ {
+ sim_fpu wop;
+ sim_fpu_64to (&wop, op);
+ boolean = sim_fpu_is_infinity (&wop);
+ break;
+ }
+ default:
+ printf("DBG: TODO: unrecognised format (%s) for Infinity check\n",DOFMT(fmt));
+ break;
+ }
+
+#ifdef DEBUG
+ printf("DBG: Infinity: returning %d for 0x%s (format = %s)\n",boolean,pr_addr(op),DOFMT(fmt));
+#endif /* DEBUG */
+
+ return(boolean);
+}
+
+int
+Less(op1,op2,fmt)
+ uword64 op1;
+ uword64 op2;
+ FP_formats fmt;
+{
+ int boolean = 0;
+
+ /* Argument checking already performed by the FPCOMPARE code */
+
+#ifdef DEBUG
+ printf("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
+#endif /* DEBUG */
+
+ /* The format type should already have been checked: */
+ switch (fmt) {
+ case fmt_single:
+ {
+ sim_fpu wop1;
+ sim_fpu wop2;
+ sim_fpu_32to (&wop1, op1);
+ sim_fpu_32to (&wop2, op2);
+ boolean = sim_fpu_is_lt (&wop1, &wop2);
+ break;
+ }
+ case fmt_double:
+ {
+ sim_fpu wop1;
+ sim_fpu wop2;
+ sim_fpu_64to (&wop1, op1);
+ sim_fpu_64to (&wop2, op2);
+ boolean = sim_fpu_is_lt (&wop1, &wop2);
+ break;
+ }
+ default:
+ fprintf (stderr, "Bad switch\n");
+ abort ();
+ }
+
+#ifdef DEBUG
+ printf("DBG: Less: returning %d (format = %s)\n",boolean,DOFMT(fmt));
+#endif /* DEBUG */
+
+ return(boolean);
+}
+
+int
+Equal(op1,op2,fmt)
+ uword64 op1;
+ uword64 op2;
+ FP_formats fmt;
+{
+ int boolean = 0;
+
+ /* Argument checking already performed by the FPCOMPARE code */
+
+#ifdef DEBUG
+ printf("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
+#endif /* DEBUG */
+
+ /* The format type should already have been checked: */
+ switch (fmt) {
+ case fmt_single:
+ {
+ sim_fpu wop1;
+ sim_fpu wop2;
+ sim_fpu_32to (&wop1, op1);
+ sim_fpu_32to (&wop2, op2);
+ boolean = sim_fpu_is_eq (&wop1, &wop2);
+ break;
+ }
+ case fmt_double:
+ {
+ sim_fpu wop1;
+ sim_fpu wop2;
+ sim_fpu_64to (&wop1, op1);
+ sim_fpu_64to (&wop2, op2);
+ boolean = sim_fpu_is_eq (&wop1, &wop2);
+ break;
+ }
+ default:
+ fprintf (stderr, "Bad switch\n");
+ abort ();
+ }
+
+#ifdef DEBUG
+ printf("DBG: Equal: returning %d (format = %s)\n",boolean,DOFMT(fmt));
+#endif /* DEBUG */
+
+ return(boolean);
+}
+
+uword64
+AbsoluteValue(op,fmt)
+ uword64 op;
+ FP_formats fmt;
+{
+ uword64 result = 0;
+
+#ifdef DEBUG
+ printf("DBG: AbsoluteValue: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
+#endif /* DEBUG */
+
+ /* The format type should already have been checked: */
+ switch (fmt) {
+ case fmt_single:
+ {
+ sim_fpu wop;
+ unsigned32 ans;
+ sim_fpu_32to (&wop, op);
+ sim_fpu_abs (&wop, &wop);
+ sim_fpu_to32 (&ans, &wop);
+ result = ans;
+ break;
+ }
+ case fmt_double:
+ {
+ sim_fpu wop;
+ unsigned64 ans;
+ sim_fpu_64to (&wop, op);
+ sim_fpu_abs (&wop, &wop);
+ sim_fpu_to64 (&ans, &wop);
+ result = ans;
+ break;
+ }
+ default:
+ fprintf (stderr, "Bad switch\n");
+ abort ();
+ }
+
+ return(result);
+}
+
+uword64
+Negate(op,fmt)
+ uword64 op;
+ FP_formats fmt;
+{
+ uword64 result = 0;
+
+#ifdef DEBUG
+ printf("DBG: Negate: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
+#endif /* DEBUG */
+
+ /* The format type should already have been checked: */
+ switch (fmt) {
+ case fmt_single:
+ {
+ sim_fpu wop;
+ unsigned32 ans;
+ sim_fpu_32to (&wop, op);
+ sim_fpu_neg (&wop, &wop);
+ sim_fpu_to32 (&ans, &wop);
+ result = ans;
+ break;
+ }
+ case fmt_double:
+ {
+ sim_fpu wop;
+ unsigned64 ans;
+ sim_fpu_64to (&wop, op);
+ sim_fpu_neg (&wop, &wop);
+ sim_fpu_to64 (&ans, &wop);
+ result = ans;
+ break;
+ }
+ default:
+ fprintf (stderr, "Bad switch\n");
+ abort ();
+ }
+
+ return(result);
+}
+
+uword64
+Add(op1,op2,fmt)
+ uword64 op1;
+ uword64 op2;
+ FP_formats fmt;
+{
+ uword64 result = 0;
+
+#ifdef DEBUG
+ printf("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
+#endif /* DEBUG */
+
+ /* The registers must specify FPRs valid for operands of type
+ "fmt". If they are not valid, the result is undefined. */
+
+ /* The format type should already have been checked: */
+ switch (fmt) {
+ case fmt_single:
+ {
+ sim_fpu wop1;
+ sim_fpu wop2;
+ sim_fpu ans;
+ unsigned32 res;
+ sim_fpu_32to (&wop1, op1);
+ sim_fpu_32to (&wop2, op2);
+ sim_fpu_add (&ans, &wop1, &wop2);
+ sim_fpu_to32 (&res, &ans);
+ result = res;
+ break;
+ }
+ case fmt_double:
+ {
+ sim_fpu wop1;
+ sim_fpu wop2;
+ sim_fpu ans;
+ unsigned64 res;
+ sim_fpu_64to (&wop1, op1);
+ sim_fpu_64to (&wop2, op2);
+ sim_fpu_add (&ans, &wop1, &wop2);
+ sim_fpu_to64 (&res, &ans);
+ result = res;
+ break;
+ }
+ default:
+ fprintf (stderr, "Bad switch\n");
+ abort ();
+ }
+
+#ifdef DEBUG
+ printf("DBG: Add: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
+#endif /* DEBUG */
+
+ return(result);
+}
+
+uword64
+Sub(op1,op2,fmt)
+ uword64 op1;
+ uword64 op2;
+ FP_formats fmt;
+{
+ uword64 result = 0;
+
+#ifdef DEBUG
+ printf("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
+#endif /* DEBUG */
+
+ /* The registers must specify FPRs valid for operands of type
+ "fmt". If they are not valid, the result is undefined. */
+
+ /* The format type should already have been checked: */
+ switch (fmt) {
+ case fmt_single:
+ {
+ sim_fpu wop1;
+ sim_fpu wop2;
+ sim_fpu ans;
+ unsigned32 res;
+ sim_fpu_32to (&wop1, op1);
+ sim_fpu_32to (&wop2, op2);
+ sim_fpu_sub (&ans, &wop1, &wop2);
+ sim_fpu_to32 (&res, &ans);
+ result = res;
+ }
+ break;
+ case fmt_double:
+ {
+ sim_fpu wop1;
+ sim_fpu wop2;
+ sim_fpu ans;
+ unsigned64 res;
+ sim_fpu_64to (&wop1, op1);
+ sim_fpu_64to (&wop2, op2);
+ sim_fpu_sub (&ans, &wop1, &wop2);
+ sim_fpu_to64 (&res, &ans);
+ result = res;
+ }
+ break;
+ default:
+ fprintf (stderr, "Bad switch\n");
+ abort ();
+ }
+
+#ifdef DEBUG
+ printf("DBG: Sub: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
+#endif /* DEBUG */
+
+ return(result);
+}
+
+uword64
+Multiply(op1,op2,fmt)
+ uword64 op1;
+ uword64 op2;
+ FP_formats fmt;
+{
+ uword64 result = 0;
+
+#ifdef DEBUG
+ printf("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
+#endif /* DEBUG */
+
+ /* The registers must specify FPRs valid for operands of type
+ "fmt". If they are not valid, the result is undefined. */
+
+ /* The format type should already have been checked: */
+ switch (fmt) {
+ case fmt_single:
+ {
+ sim_fpu wop1;
+ sim_fpu wop2;
+ sim_fpu ans;
+ unsigned32 res;
+ sim_fpu_32to (&wop1, op1);
+ sim_fpu_32to (&wop2, op2);
+ sim_fpu_mul (&ans, &wop1, &wop2);
+ sim_fpu_to32 (&res, &ans);
+ result = res;
+ break;
+ }
+ case fmt_double:
+ {
+ sim_fpu wop1;
+ sim_fpu wop2;
+ sim_fpu ans;
+ unsigned64 res;
+ sim_fpu_64to (&wop1, op1);
+ sim_fpu_64to (&wop2, op2);
+ sim_fpu_mul (&ans, &wop1, &wop2);
+ sim_fpu_to64 (&res, &ans);
+ result = res;
+ break;
+ }
+ default:
+ fprintf (stderr, "Bad switch\n");
+ abort ();
+ }
+
+#ifdef DEBUG
+ printf("DBG: Multiply: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
+#endif /* DEBUG */
+
+ return(result);
+}
+
+uword64
+Divide(op1,op2,fmt)
+ uword64 op1;
+ uword64 op2;
+ FP_formats fmt;
+{
+ uword64 result = 0;
+
+#ifdef DEBUG
+ printf("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
+#endif /* DEBUG */
+
+ /* The registers must specify FPRs valid for operands of type
+ "fmt". If they are not valid, the result is undefined. */
+
+ /* The format type should already have been checked: */
+ switch (fmt) {
+ case fmt_single:
+ {
+ sim_fpu wop1;
+ sim_fpu wop2;
+ sim_fpu ans;
+ unsigned32 res;
+ sim_fpu_32to (&wop1, op1);
+ sim_fpu_32to (&wop2, op2);
+ sim_fpu_div (&ans, &wop1, &wop2);
+ sim_fpu_to32 (&res, &ans);
+ result = res;
+ break;
+ }
+ case fmt_double:
+ {
+ sim_fpu wop1;
+ sim_fpu wop2;
+ sim_fpu ans;
+ unsigned64 res;
+ sim_fpu_64to (&wop1, op1);
+ sim_fpu_64to (&wop2, op2);
+ sim_fpu_div (&ans, &wop1, &wop2);
+ sim_fpu_to64 (&res, &ans);
+ result = res;
+ break;
+ }
+ default:
+ fprintf (stderr, "Bad switch\n");
+ abort ();
+ }
+
+#ifdef DEBUG
+ printf("DBG: Divide: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
+#endif /* DEBUG */
+
+ return(result);
+}
+
+uword64 UNUSED
+Recip(op,fmt)
+ uword64 op;
+ FP_formats fmt;
+{
+ uword64 result = 0;
+
+#ifdef DEBUG
+ printf("DBG: Recip: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
+#endif /* DEBUG */
+
+ /* The registers must specify FPRs valid for operands of type
+ "fmt". If they are not valid, the result is undefined. */
+
+ /* The format type should already have been checked: */
+ switch (fmt) {
+ case fmt_single:
+ {
+ sim_fpu wop;
+ sim_fpu ans;
+ unsigned32 res;
+ sim_fpu_32to (&wop, op);
+ sim_fpu_inv (&ans, &wop);
+ sim_fpu_to32 (&res, &ans);
+ result = res;
+ break;
+ }
+ case fmt_double:
+ {
+ sim_fpu wop;
+ sim_fpu ans;
+ unsigned64 res;
+ sim_fpu_64to (&wop, op);
+ sim_fpu_inv (&ans, &wop);
+ sim_fpu_to64 (&res, &ans);
+ result = res;
+ break;
+ }
+ default:
+ fprintf (stderr, "Bad switch\n");
+ abort ();
+ }
+
+#ifdef DEBUG
+ printf("DBG: Recip: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
+#endif /* DEBUG */
+
+ return(result);
+}
+
+uword64
+SquareRoot(op,fmt)
+ uword64 op;
+ FP_formats fmt;
+{
+ uword64 result = 0;
+
+#ifdef DEBUG
+ printf("DBG: SquareRoot: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
+#endif /* DEBUG */
+
+ /* The registers must specify FPRs valid for operands of type
+ "fmt". If they are not valid, the result is undefined. */
+
+ /* The format type should already have been checked: */
+ switch (fmt) {
+ case fmt_single:
+ {
+ sim_fpu wop;
+ sim_fpu ans;
+ unsigned32 res;
+ sim_fpu_32to (&wop, op);
+ sim_fpu_sqrt (&ans, &wop);
+ sim_fpu_to32 (&res, &ans);
+ result = res;
+ break;
+ }
+ case fmt_double:
+ {
+ sim_fpu wop;
+ sim_fpu ans;
+ unsigned64 res;
+ sim_fpu_64to (&wop, op);
+ sim_fpu_sqrt (&ans, &wop);
+ sim_fpu_to64 (&res, &ans);
+ result = res;
+ break;
+ }
+ default:
+ fprintf (stderr, "Bad switch\n");
+ abort ();
+ }
+
+#ifdef DEBUG
+ printf("DBG: SquareRoot: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
+#endif /* DEBUG */
+
+ return(result);
+}
+
+#if 0
+uword64
+Max (uword64 op1,
+ uword64 op2,
+ FP_formats fmt)
+{
+ int cmp;
+ unsigned64 result;
+
+#ifdef DEBUG
+ printf("DBG: Max: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
+#endif /* DEBUG */
+
+ /* The registers must specify FPRs valid for operands of type
+ "fmt". If they are not valid, the result is undefined. */
+
+ /* The format type should already have been checked: */
+ switch (fmt)
+ {
+ case fmt_single:
+ {
+ sim_fpu wop1;
+ sim_fpu wop2;
+ sim_fpu_32to (&wop1, op1);
+ sim_fpu_32to (&wop2, op2);
+ cmp = sim_fpu_cmp (&wop1, &wop2);
+ break;
+ }
+ case fmt_double:
+ {
+ sim_fpu wop1;
+ sim_fpu wop2;
+ sim_fpu_64to (&wop1, op1);
+ sim_fpu_64to (&wop2, op2);
+ cmp = sim_fpu_cmp (&wop1, &wop2);
+ break;
+ }
+ default:
+ fprintf (stderr, "Bad switch\n");
+ abort ();
+ }
+
+ switch (cmp)
+ {
+ case SIM_FPU_IS_SNAN:
+ case SIM_FPU_IS_QNAN:
+ result = op1;
+ case SIM_FPU_IS_NINF:
+ case SIM_FPU_IS_NNUMBER:
+ case SIM_FPU_IS_NDENORM:
+ case SIM_FPU_IS_NZERO:
+ result = op2; /* op1 - op2 < 0 */
+ case SIM_FPU_IS_PINF:
+ case SIM_FPU_IS_PNUMBER:
+ case SIM_FPU_IS_PDENORM:
+ case SIM_FPU_IS_PZERO:
+ result = op1; /* op1 - op2 > 0 */
+ default:
+ fprintf (stderr, "Bad switch\n");
+ abort ();
+ }
+
+#ifdef DEBUG
+ printf("DBG: Max: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
+#endif /* DEBUG */
+
+ return(result);
+}
+#endif
+
+#if 0
+uword64
+Min (uword64 op1,
+ uword64 op2,
+ FP_formats fmt)
+{
+ int cmp;
+ unsigned64 result;
+
+#ifdef DEBUG
+ printf("DBG: Min: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
+#endif /* DEBUG */
+
+ /* The registers must specify FPRs valid for operands of type
+ "fmt". If they are not valid, the result is undefined. */
+
+ /* The format type should already have been checked: */
+ switch (fmt)
+ {
+ case fmt_single:
+ {
+ sim_fpu wop1;
+ sim_fpu wop2;
+ sim_fpu_32to (&wop1, op1);
+ sim_fpu_32to (&wop2, op2);
+ cmp = sim_fpu_cmp (&wop1, &wop2);
+ break;
+ }
+ case fmt_double:
+ {
+ sim_fpu wop1;
+ sim_fpu wop2;
+ sim_fpu_64to (&wop1, op1);
+ sim_fpu_64to (&wop2, op2);
+ cmp = sim_fpu_cmp (&wop1, &wop2);
+ break;
+ }
+ default:
+ fprintf (stderr, "Bad switch\n");
+ abort ();
+ }
+
+ switch (cmp)
+ {
+ case SIM_FPU_IS_SNAN:
+ case SIM_FPU_IS_QNAN:
+ result = op1;
+ case SIM_FPU_IS_NINF:
+ case SIM_FPU_IS_NNUMBER:
+ case SIM_FPU_IS_NDENORM:
+ case SIM_FPU_IS_NZERO:
+ result = op1; /* op1 - op2 < 0 */
+ case SIM_FPU_IS_PINF:
+ case SIM_FPU_IS_PNUMBER:
+ case SIM_FPU_IS_PDENORM:
+ case SIM_FPU_IS_PZERO:
+ result = op2; /* op1 - op2 > 0 */
+ default:
+ fprintf (stderr, "Bad switch\n");
+ abort ();
+ }
+
+#ifdef DEBUG
+ printf("DBG: Min: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
+#endif /* DEBUG */
+
+ return(result);
+}
+#endif
+
+uword64
+convert (SIM_DESC sd,
+ sim_cpu *cpu,
+ address_word cia,
+ int rm,
+ uword64 op,
+ FP_formats from,
+ FP_formats to)
+{
+ sim_fpu wop;
+ sim_fpu_round round;
+ unsigned32 result32;
+ unsigned64 result64;
+
+#ifdef DEBUG
+#if 0 /* FIXME: doesn't compile */
+ printf("DBG: Convert: mode %s : op 0x%s : from %s : to %s : (PC = 0x%s)\n",RMMODE(rm),pr_addr(op),DOFMT(from),DOFMT(to),pr_addr(IPC));
+#endif
+#endif /* DEBUG */
+
+ switch (rm)
+ {
+ case FP_RM_NEAREST:
+ /* Round result to nearest representable value. When two
+ representable values are equally near, round to the value
+ that has a least significant bit of zero (i.e. is even). */
+ round = sim_fpu_round_near;
+ break;
+ case FP_RM_TOZERO:
+ /* Round result to the value closest to, and not greater in
+ magnitude than, the result. */
+ round = sim_fpu_round_zero;
+ break;
+ case FP_RM_TOPINF:
+ /* Round result to the value closest to, and not less than,
+ the result. */
+ round = sim_fpu_round_up;
+ break;
+
+ case FP_RM_TOMINF:
+ /* Round result to the value closest to, and not greater than,
+ the result. */
+ round = sim_fpu_round_down;
+ break;
+ default:
+ round = 0;
+ fprintf (stderr, "Bad switch\n");
+ abort ();
+ }
+
+ /* Convert the input to sim_fpu internal format */
+ switch (from)
+ {
+ case fmt_double:
+ sim_fpu_64to (&wop, op);
+ break;
+ case fmt_single:
+ sim_fpu_32to (&wop, op);
+ break;
+ case fmt_word:
+ sim_fpu_i32to (&wop, op, round);
+ break;
+ case fmt_long:
+ sim_fpu_i64to (&wop, op, round);
+ break;
+ default:
+ fprintf (stderr, "Bad switch\n");
+ abort ();
+ }
+
+ /* Convert sim_fpu format into the output */
+ /* The value WOP is converted to the destination format, rounding
+ using mode RM. When the destination is a fixed-point format, then
+ a source value of Infinity, NaN or one which would round to an
+ integer outside the fixed point range then an IEEE Invalid
+ Operation condition is raised. */
+ switch (to)
+ {
+ case fmt_single:
+ sim_fpu_round_32 (&wop, round, 0);
+ sim_fpu_to32 (&result32, &wop);
+ result64 = result32;
+ break;
+ case fmt_double:
+ sim_fpu_round_64 (&wop, round, 0);
+ sim_fpu_to64 (&result64, &wop);
+ break;
+ case fmt_word:
+ sim_fpu_to32i (&result32, &wop, round);
+ result64 = result32;
+ break;
+ case fmt_long:
+ sim_fpu_to64i (&result64, &wop, round);
+ break;
+ default:
+ result64 = 0;
+ fprintf (stderr, "Bad switch\n");
+ abort ();
+ }
+
+#ifdef DEBUG
+ printf("DBG: Convert: returning 0x%s (to format = %s)\n",pr_addr(result64),DOFMT(to));
+#endif /* DEBUG */
+
+ return(result64);
+}
+
+
+/*-- co-processor support routines ------------------------------------------*/
+
+static int UNUSED
+CoProcPresent(unsigned int coproc_number)
+{
+ /* Return TRUE if simulator provides a model for the given co-processor number */
+ return(0);
+}
+
+void
+cop_lw (SIM_DESC sd,
+ sim_cpu *cpu,
+ address_word cia,
+ int coproc_num,
+ int coproc_reg,
+ unsigned int memword)
+{
+ switch (coproc_num)
+ {
+ case 1:
+ if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
+ {
+#ifdef DEBUG
+ printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword,pr_addr(memword));
+#endif
+ StoreFPR(coproc_reg,fmt_word,(uword64)memword);
+ FPR_STATE[coproc_reg] = fmt_uninterpreted;
+ break;
+ }
+
+ default:
+#if 0 /* this should be controlled by a configuration option */
+ sim_io_printf(sd,"COP_LW(%d,%d,0x%08X) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,memword,pr_addr(cia));
+#endif
+ break;
+ }
+
+ return;
+}
+
+void
+cop_ld (SIM_DESC sd,
+ sim_cpu *cpu,
+ address_word cia,
+ int coproc_num,
+ int coproc_reg,
+ uword64 memword)
+{
+
+#ifdef DEBUG
+ printf("DBG: COP_LD: coproc_num = %d, coproc_reg = %d, value = 0x%s : PC = 0x%s\n", coproc_num, coproc_reg, pr_uword64(memword), pr_addr(cia) );
+#endif
+
+ switch (coproc_num) {
+ case 1:
+ if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
+ {
+ StoreFPR(coproc_reg,fmt_uninterpreted,memword);
+ break;
+ }
+
+ default:
+#if 0 /* this message should be controlled by a configuration option */
+ sim_io_printf(sd,"COP_LD(%d,%d,0x%s) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(memword),pr_addr(cia));
+#endif
+ break;
+ }
+
+ return;
+}
+
+
+
+
+unsigned int
+cop_sw (SIM_DESC sd,
+ sim_cpu *cpu,
+ address_word cia,
+ int coproc_num,
+ int coproc_reg)
+{
+ unsigned int value = 0;
+
+ switch (coproc_num)
+ {
+ case 1:
+ if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
+ {
+ FP_formats hold;
+ hold = FPR_STATE[coproc_reg];
+ FPR_STATE[coproc_reg] = fmt_word;
+ value = (unsigned int)ValueFPR(coproc_reg,fmt_uninterpreted);
+ FPR_STATE[coproc_reg] = hold;
+ break;
+ }
+
+ default:
+#if 0 /* should be controlled by configuration option */
+ sim_io_printf(sd,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
+#endif
+ break;
+ }
+
+ return(value);
+}
+
+uword64
+cop_sd (SIM_DESC sd,
+ sim_cpu *cpu,
+ address_word cia,
+ int coproc_num,
+ int coproc_reg)
+{
+ uword64 value = 0;
+ switch (coproc_num)
+ {
+ case 1:
+ if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
+ {
+ value = ValueFPR(coproc_reg,fmt_uninterpreted);
+ break;
+ }
+
+ default:
+#if 0 /* should be controlled by configuration option */
+ sim_io_printf(sd,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
+#endif
+ break;
+ }
+
+ return(value);
+}
+
+
+
+
+void
+decode_coproc (SIM_DESC sd,
+ sim_cpu *cpu,
+ address_word cia,
+ unsigned int instruction)
+{
+ int coprocnum = ((instruction >> 26) & 3);
+
+ switch (coprocnum)
+ {
+ case 0: /* standard CPU control and cache registers */
+ {
+ int code = ((instruction >> 21) & 0x1F);
+ int rt = ((instruction >> 16) & 0x1F);
+ int rd = ((instruction >> 11) & 0x1F);
+ int tail = instruction & 0x3ff;
+ /* R4000 Users Manual (second edition) lists the following CP0
+ instructions:
+ CODE><-RT><RD-><--TAIL--->
+ DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
+ DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
+ MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
+ MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
+ TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
+ TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
+ TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
+ TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
+ CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
+ ERET Exception return (VR4100 = 01000010000000000000000000011000)
+ */
+ if (((code == 0x00) || (code == 0x04)) && tail == 0)
+ {
+ /* M[TF]C0 - 32 bit word */
+
+ switch (rd) /* NOTEs: Standard CP0 registers */
+ {
+ /* 0 = Index R4000 VR4100 VR4300 */
+ /* 1 = Random R4000 VR4100 VR4300 */
+ /* 2 = EntryLo0 R4000 VR4100 VR4300 */
+ /* 3 = EntryLo1 R4000 VR4100 VR4300 */
+ /* 4 = Context R4000 VR4100 VR4300 */
+ /* 5 = PageMask R4000 VR4100 VR4300 */
+ /* 6 = Wired R4000 VR4100 VR4300 */
+ /* 8 = BadVAddr R4000 VR4100 VR4300 */
+ /* 9 = Count R4000 VR4100 VR4300 */
+ /* 10 = EntryHi R4000 VR4100 VR4300 */
+ /* 11 = Compare R4000 VR4100 VR4300 */
+ /* 12 = SR R4000 VR4100 VR4300 */
+#ifdef SUBTARGET_R3900
+ case 3:
+ /* 3 = Config R3900 */
+ case 7:
+ /* 7 = Cache R3900 */
+ case 15:
+ /* 15 = PRID R3900 */
+
+ /* ignore */
+ break;
+
+ case 8:
+ /* 8 = BadVAddr R4000 VR4100 VR4300 */
+ if (code == 0x00)
+ GPR[rt] = COP0_BADVADDR;
+ else
+ COP0_BADVADDR = GPR[rt];
+ break;
+
+#endif /* SUBTARGET_R3900 */
+ case 12:
+ if (code == 0x00)
+ GPR[rt] = SR;
+ else
+ SR = GPR[rt];
+ break;
+ /* 13 = Cause R4000 VR4100 VR4300 */
+ case 13:
+ if (code == 0x00)
+ GPR[rt] = CAUSE;
+ else
+ CAUSE = GPR[rt];
+ break;
+ /* 14 = EPC R4000 VR4100 VR4300 */
+ case 14:
+ if (code == 0x00)
+ GPR[rt] = (signed_word) (signed_address) EPC;
+ else
+ EPC = GPR[rt];
+ break;
+ /* 15 = PRId R4000 VR4100 VR4300 */
+#ifdef SUBTARGET_R3900
+ /* 16 = Debug */
+ case 16:
+ if (code == 0x00)
+ GPR[rt] = Debug;
+ else
+ Debug = GPR[rt];
+ break;
+#else
+ /* 16 = Config R4000 VR4100 VR4300 */
+ case 16:
+ if (code == 0x00)
+ GPR[rt] = C0_CONFIG;
+ else
+ C0_CONFIG = GPR[rt];
+ break;
+#endif
+#ifdef SUBTARGET_R3900
+ /* 17 = Debug */
+ case 17:
+ if (code == 0x00)
+ GPR[rt] = DEPC;
+ else
+ DEPC = GPR[rt];
+ break;
+#else
+ /* 17 = LLAddr R4000 VR4100 VR4300 */
+#endif
+ /* 18 = WatchLo R4000 VR4100 VR4300 */
+ /* 19 = WatchHi R4000 VR4100 VR4300 */
+ /* 20 = XContext R4000 VR4100 VR4300 */
+ /* 26 = PErr or ECC R4000 VR4100 VR4300 */
+ /* 27 = CacheErr R4000 VR4100 */
+ /* 28 = TagLo R4000 VR4100 VR4300 */
+ /* 29 = TagHi R4000 VR4100 VR4300 */
+ /* 30 = ErrorEPC R4000 VR4100 VR4300 */
+ GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */
+ /* CPR[0,rd] = GPR[rt]; */
+ default:
+ if (code == 0x00)
+ GPR[rt] = (signed_word) (signed32) COP0_GPR[rd];
+ else
+ COP0_GPR[rd] = GPR[rt];
+#if 0
+ if (code == 0x00)
+ sim_io_printf(sd,"Warning: MFC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt,rd, (unsigned)cia);
+ else
+ sim_io_printf(sd,"Warning: MTC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt,rd, (unsigned)cia);
+#endif
+ }
+ }
+ else if (code == 0x10 && (tail & 0x3f) == 0x18)
+ {
+ /* ERET */
+ if (SR & status_ERL)
+ {
+ /* Oops, not yet available */
+ sim_io_printf(sd,"Warning: ERET when SR[ERL] set not handled yet");
+ PC = EPC;
+ SR &= ~status_ERL;
+ }
+ else
+ {
+ PC = EPC;
+ SR &= ~status_EXL;
+ }
+ }
+ else if (code == 0x10 && (tail & 0x3f) == 0x10)
+ {
+ /* RFE */
+#ifdef SUBTARGET_R3900
+ /* TX39: Copy IEp/KUp -> IEc/KUc, and IEo/KUo -> IEp/KUp */
+
+ /* shift IE/KU history bits right */
+ SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 5, 2), 3, 0);
+
+ /* TODO: CACHE register */
+#endif /* SUBTARGET_R3900 */
+ }
+ else if (code == 0x10 && (tail & 0x3f) == 0x1F)
+ {
+ /* DERET */
+ Debug &= ~Debug_DM;
+ DELAYSLOT();
+ DSPC = DEPC;
+ }
+ else
+ sim_io_eprintf(sd,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction,pr_addr(cia));
+ /* TODO: When executing an ERET or RFE instruction we should
+ clear LLBIT, to ensure that any out-standing atomic
+ read/modify/write sequence fails. */
+ }
+ break;
+
+ case 2: /* co-processor 2 */
+ {
+ int handle = 0;
+
+
+ if(! handle)
+ {
+ sim_io_eprintf(sd, "COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
+ instruction,pr_addr(cia));
+ }
+ }
+ break;
+
+ case 1: /* should not occur (FPU co-processor) */
+ case 3: /* should not occur (FPU co-processor) */
+ SignalException(ReservedInstruction,instruction);
+ break;
+ }
+
+ return;
+}
+
+
+/* This code copied from gdb's utils.c. Would like to share this code,
+ but don't know of a common place where both could get to it. */
+
+/* Temporary storage using circular buffer */
+#define NUMCELLS 16
+#define CELLSIZE 32
+static char*
+get_cell (void)
+{
+ static char buf[NUMCELLS][CELLSIZE];
+ static int cell=0;
+ if (++cell>=NUMCELLS) cell=0;
+ return buf[cell];
+}
+
+/* Print routines to handle variable size regs, etc */
+
+/* Eliminate warning from compiler on 32-bit systems */
+static int thirty_two = 32;
+
+char*
+pr_addr(addr)
+ SIM_ADDR addr;
+{
+ char *paddr_str=get_cell();
+ switch (sizeof(addr))
+ {
+ case 8:
+ sprintf(paddr_str,"%08lx%08lx",
+ (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
+ break;
+ case 4:
+ sprintf(paddr_str,"%08lx",(unsigned long)addr);
+ break;
+ case 2:
+ sprintf(paddr_str,"%04x",(unsigned short)(addr&0xffff));
+ break;
+ default:
+ sprintf(paddr_str,"%x",addr);
+ }
+ return paddr_str;
+}
+
+char*
+pr_uword64(addr)
+ uword64 addr;
+{
+ char *paddr_str=get_cell();
+ sprintf(paddr_str,"%08lx%08lx",
+ (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
+ return paddr_str;
+}
+
+
+void
+mips_core_signal (SIM_DESC sd,
+ sim_cpu *cpu,
+ sim_cia cia,
+ unsigned map,
+ int nr_bytes,
+ address_word addr,
+ transfer_type transfer,
+ sim_core_signals sig)
+{
+ const char *copy = (transfer == read_transfer ? "read" : "write");
+ address_word ip = CIA_ADDR (cia);
+
+ switch (sig)
+ {
+ case sim_core_unmapped_signal:
+ sim_io_eprintf (sd, "mips-core: %d byte %s to unmapped address 0x%lx at 0x%lx\n",
+ nr_bytes, copy,
+ (unsigned long) addr, (unsigned long) ip);
+ COP0_BADVADDR = addr;
+ SignalExceptionDataReference();
+ break;
+
+ case sim_core_unaligned_signal:
+ sim_io_eprintf (sd, "mips-core: %d byte %s to unaligned address 0x%lx at 0x%lx\n",
+ nr_bytes, copy,
+ (unsigned long) addr, (unsigned long) ip);
+ COP0_BADVADDR = addr;
+ if(transfer == read_transfer)
+ SignalExceptionAddressLoad();
+ else
+ SignalExceptionAddressStore();
+ break;
+
+ default:
+ sim_engine_abort (sd, cpu, cia,
+ "mips_core_signal - internal error - bad switch");
+ }
+}
+
+
+void
+mips_cpu_exception_trigger(SIM_DESC sd, sim_cpu* cpu, address_word cia)
+{
+ ASSERT(cpu != NULL);
+
+ if(cpu->exc_suspended > 0)
+ sim_io_eprintf(sd, "Warning, nested exception triggered (%d)\n", cpu->exc_suspended);
+
+ PC = cia;
+ memcpy(cpu->exc_trigger_registers, cpu->registers, sizeof(cpu->exc_trigger_registers));
+ cpu->exc_suspended = 0;
+}
+
+void
+mips_cpu_exception_suspend(SIM_DESC sd, sim_cpu* cpu, int exception)
+{
+ ASSERT(cpu != NULL);
+
+ if(cpu->exc_suspended > 0)
+ sim_io_eprintf(sd, "Warning, nested exception signal (%d then %d)\n",
+ cpu->exc_suspended, exception);
+
+ memcpy(cpu->exc_suspend_registers, cpu->registers, sizeof(cpu->exc_suspend_registers));
+ memcpy(cpu->registers, cpu->exc_trigger_registers, sizeof(cpu->registers));
+ cpu->exc_suspended = exception;
+}
+
+void
+mips_cpu_exception_resume(SIM_DESC sd, sim_cpu* cpu, int exception)
+{
+ ASSERT(cpu != NULL);
+
+ if(exception == 0 && cpu->exc_suspended > 0)
+ {
+ /* warn not for breakpoints */
+ if(cpu->exc_suspended != sim_signal_to_host(sd, SIM_SIGTRAP))
+ sim_io_eprintf(sd, "Warning, resuming but ignoring pending exception signal (%d)\n",
+ cpu->exc_suspended);
+ }
+ else if(exception != 0 && cpu->exc_suspended > 0)
+ {
+ if(exception != cpu->exc_suspended)
+ sim_io_eprintf(sd, "Warning, resuming with mismatched exception signal (%d vs %d)\n",
+ cpu->exc_suspended, exception);
+
+ memcpy(cpu->registers, cpu->exc_suspend_registers, sizeof(cpu->registers));
+ }
+ else if(exception != 0 && cpu->exc_suspended == 0)
+ {
+ sim_io_eprintf(sd, "Warning, ignoring spontanous exception signal (%d)\n", exception);
+ }
+ cpu->exc_suspended = 0;
+}
+
+
+/*---------------------------------------------------------------------------*/
+/*> EOF interp.c <*/
diff --git a/sim/mips/m16.dc b/sim/mips/m16.dc
new file mode 100644
index 0000000..292587c
--- /dev/null
+++ b/sim/mips/m16.dc
@@ -0,0 +1,25 @@
+# most instructions
+# ------ options ------ : Fst : Lst : ff : fl : fe : word : --- fmt --- : model ...
+# { : mask : value : word }
+
+# Top level - create a very big switch statement.
+
+ padded-switch,combine : 15 : 11 : : : : : :
+
+ switch,combine : 10 : 8 : : : : : :
+
+ switch,combine : 4 : 0 : : : : : :
+
+ switch,combine : 7 : 5 : : : : : :
+
+
+# Extended instructions, decode the same way
+
+ padded-switch,combine : 15 : 11 : : : : 1 : :
+
+ switch,combine : 10 : 8 : : : : 1 : :
+
+ switch,combine : 4 : 0 : : : : 1 : :
+
+ switch,combine : 7 : 5 : : : : 1 : :
+
diff --git a/sim/mips/m16.igen b/sim/mips/m16.igen
new file mode 100644
index 0000000..9b36ff9
--- /dev/null
+++ b/sim/mips/m16.igen
@@ -0,0 +1,1236 @@
+// -*- C -*-
+//
+//
+// MIPS Architecture:
+//
+// CPU Instruction Set (mips16)
+//
+
+// The instructions in this section are ordered according
+// to http://www.sgi.com/MIPS/arch/MIPS16/mips16.pdf.
+
+
+// The MIPS16 codes registers in a special way, map from one to the other.
+// :<type>:<flags>:<models>:<typedef>:<name>:<field>:<expression>
+:compute:::int:TRX:RX:((RX < 2) ? (16 + RX) \: RX)
+:compute:::int:TRY:RY:((RY < 2) ? (16 + RY) \: RY)
+:compute:::int:TRZ:RZ:((RZ < 2) ? (16 + RZ) \: RZ)
+:compute:::int:SHIFT:SHAMT:((SHAMT == 0) ? 8 \: SHAMT)
+
+:compute:::int:SHAMT:SHAMT_4_0,S5:(LSINSERTED (S5, 5, 5) | SHAMT_4_0)
+
+:compute:::address_word:IMMEDIATE:IMM_25_21,IMM_20_16,IMMED_15_0:(LSINSERTED (IMM_25_21, 25, 21) | LSINSERTED (IMM_20_16, 20, 16) | LSINSERTED (IMMED_15_0, 15, 0))
+:compute:::int:R32:R32L,R32H:((R32H << 3) | R32L)
+
+:compute:::address_word:IMMEDIATE:IMM_10_5,IMM_15_11,IMM_4_0:(LSINSERTED (IMM_10_5, 10, 5) | LSINSERTED (IMM_15_11, 15, 11) | LSINSERTED (IMM_4_0, 4, 0))
+
+:compute:::address_word:IMMEDIATE:IMM_10_4,IMM_14_11,IMM_3_0:(LSINSERTED (IMM_10_4, 10, 4) | LSINSERTED (IMM_14_11, 14, 11) | LSINSERTED (IMM_3_0, 3, 0))
+
+
+// Load and Store Instructions
+
+
+10000,3.RX,3.RY,5.IMMED:RRI:16::LB
+"lb r<TRY>, <IMMED> (r<TRX>)"
+*mips16:
+*vr4100:
+{
+ GPR[TRY] = EXTEND8 (do_load (SD_, AccessLength_BYTE, GPR[TRX], IMMED));
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 10000,3.RX,3.RY,5.IMM_4_0:EXT-RRI:16::LB
+"lb r<TRY>, <IMMEDIATE> (r<TRX>)"
+*mips16:
+*vr4100:
+{
+ GPR[TRY] = EXTEND8 (do_load (SD_, AccessLength_BYTE, GPR[TRX], EXTEND16 (IMMEDIATE)));
+}
+
+
+
+10100,3.RX,3.RY,5.IMMED:RRI:16::LBU
+"lbu r<TRY>, <IMMED> (r<TRX>)"
+*mips16:
+*vr4100:
+{
+ GPR[TRY] = do_load (SD_, AccessLength_BYTE, GPR[TRX], IMMED);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 10100,3.RX,3.RY,5.IMM_4_0:EXT-RRI:16::LBU
+"lbu r<TRY>, <IMMEDIATE> (r<TRX>)"
+*mips16:
+*vr4100:
+{
+ GPR[TRY] = do_load (SD_, AccessLength_BYTE, GPR[TRX], EXTEND16 (IMMEDIATE));
+}
+
+
+
+10001,3.RX,3.RY,5.IMMED:RRI:16::LH
+"lh r<TRY>, <IMMED> (r<TRX>)"
+*mips16:
+*vr4100:
+{
+ GPR[TRY] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[TRX], IMMED << 1));
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 10001,3.RX,3.RY,5.IMM_4_0:EXT-RRI:16::LH
+"lh r<TRY>, <IMMEDIATE> (r<TRX>)"
+*mips16:
+*vr4100:
+{
+ GPR[TRY] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[TRX], EXTEND16 (IMMEDIATE)));
+}
+
+
+
+10101,3.RX,3.RY,5.IMMED:RRI:16::LHU
+"lhu r<TRY>, <IMMED> (r<TRX>)"
+*mips16:
+*vr4100:
+{
+ GPR[TRY] = do_load (SD_, AccessLength_HALFWORD, GPR[TRX], IMMED << 1);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 10101,3.RX,3.RY,5.IMM_4_0:EXT-RRI:16::LHU
+"lhu r<TRY>, <IMMEDIATE> (r<TRX>)"
+*mips16:
+*vr4100:
+{
+ GPR[TRY] = do_load (SD_, AccessLength_HALFWORD, GPR[TRX], EXTEND16 (IMMEDIATE));
+}
+
+
+
+10011,3.RX,3.RY,5.IMMED:RRI:16::LW
+"lw r<TRY>, <IMMED> (r<TRX>)"
+*mips16:
+*vr4100:
+{
+ GPR[TRY] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[TRX], IMMED << 2));
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 10011,3.RX,3.RY,5.IMM_4_0:EXT-RRI:16::LW
+"lw r<TRY>, <IMMEDIATE> (r<TRX>)"
+*mips16:
+*vr4100:
+{
+ GPR[TRY] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[TRX], EXTEND16 (IMMEDIATE)));
+}
+
+
+
+10110,3.RX,8.IMMED:RI:16::LWPC
+"lw r<TRX>, <IMMED> (PC)"
+*mips16:
+*vr4100:
+{
+ GPR[TRX] = EXTEND32 (do_load (SD_, AccessLength_WORD,
+ basepc (SD_) & ~3, IMMED << 2));
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 10110,3.RX,000,5.IMM_4_0:EXT-RI:16::LWPC
+"lw r<TRX>, <IMMEDIATE> (PC)"
+*mips16:
+*vr4100:
+{
+ GPR[TRX] = EXTEND32 (do_load (SD_, AccessLength_WORD, basepc (SD_) & ~3, EXTEND16 (IMMEDIATE)));
+}
+
+
+
+10010,3.RX,8.IMMED:RI:16::LWSP
+"lw r<TRX>, <IMMED> (SP)"
+*mips16:
+*vr4100:
+{
+ GPR[TRX] = EXTEND32 (do_load (SD_, AccessLength_WORD, SP, IMMED << 2));
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 10010,3.RX,000,5.IMM_4_0:EXT-RI:16::LWSP
+"lw r<TRX>, <IMMEDIATE> (SP)"
+*mips16:
+*vr4100:
+{
+ GPR[TRX] = EXTEND32 (do_load (SD_, AccessLength_WORD, SP, EXTEND16 (IMMEDIATE)));
+}
+
+
+
+10111,3.RX,3.RY,5.IMMED:RRI:16::LWU
+"lwu r<TRY>, <IMMED> (r<TRX>)"
+*mips16:
+*vr4100:
+{
+ GPR[TRY] = do_load (SD_, AccessLength_WORD, GPR[TRX], IMMED << 2);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 10111,3.RX,3.RY,5.IMM_4_0:EXT-RRI:16::LWU
+"lwu r<TRY>, <IMMEDIATE> (r<TRX>)"
+*mips16:
+*vr4100:
+{
+ GPR[TRY] = do_load (SD_, AccessLength_WORD, GPR[TRX], EXTEND16 (IMMEDIATE));
+}
+
+
+
+00111,3.RX,3.RY,5.IMMED:RRI:16::LD
+"ld r<TRY>, <IMMED> (r<TRX>)"
+*mips16:
+*vr4100:
+{
+ GPR[TRY] = do_load (SD_, AccessLength_DOUBLEWORD, GPR[TRX], IMMED << 3);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 00111,3.RX,3.RY,5.IMM_4_0:EXT-RRI:16::LD
+"ld r<TRY>, <IMMEDIATE> (r<TRX>)"
+*mips16:
+*vr4100:
+{
+ GPR[TRY] = do_load (SD_, AccessLength_DOUBLEWORD, GPR[TRX], EXTEND16 (IMMEDIATE));
+}
+
+
+
+11111,100,3.RY,5.IMMED:RI64:16::LDPC
+"ld r<TRY>, <IMMED> (PC)"
+*mips16:
+*vr4100:
+{
+ GPR[TRY] = do_load (SD_, AccessLength_DOUBLEWORD,
+ basepc (SD_) & ~7, IMMED << 3);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 11111,100,3.RY,5.IMM_4_0:EXT-RI64:16::LDPC
+"ld r<TRY>, <IMMEDIATE> (PC)"
+*mips16:
+*vr4100:
+{
+ GPR[TRY] = do_load (SD_, AccessLength_DOUBLEWORD, basepc (SD_) & ~7, EXTEND16 (IMMEDIATE));
+}
+
+
+
+11111,000,3.RY,5.IMMED:RI64:16::LDSP
+"ld r<TRY>, <IMMED> (SP)"
+*mips16:
+*vr4100:
+{
+ GPR[TRY] = do_load (SD_, AccessLength_DOUBLEWORD, SP, IMMED << 3);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 11111,000,3.RY,5.IMM_4_0:EXT-RI64:16::LDSP
+"ld r<TRY>, <IMMEDIATE> (SP)"
+*mips16:
+*vr4100:
+{
+ GPR[TRY] = do_load (SD_, AccessLength_DOUBLEWORD, SP, EXTEND16 (IMMEDIATE));
+}
+
+
+
+11000,3.RX,3.RY,5.IMMED:RRI:16::SB
+"sb r<TRY>, <IMMED> (r<TRX>)"
+*mips16:
+*vr4100:
+{
+ do_store (SD_, AccessLength_BYTE, GPR[TRX], IMMED, GPR[TRY]);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 11000,3.RX,3.RY,5.IMM_4_0:EXT-RRI:16::SB
+"sb r<TRY>, <IMMEDIATE> (r<TRX>)"
+*mips16:
+*vr4100:
+{
+ do_store (SD_, AccessLength_BYTE, GPR[TRX], EXTEND16 (IMMEDIATE), GPR[TRY]);
+}
+
+
+
+11001,3.RX,3.RY,5.IMMED:RRI:16::SH
+"sh r<TRY>, <IMMED> (r<TRX>)"
+*mips16:
+*vr4100:
+{
+ do_store (SD_, AccessLength_HALFWORD, GPR[TRX], IMMED << 1, GPR[TRY]);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 11001,3.RX,3.RY,5.IMM_4_0:EXT-RRI:16::SH
+"sh r<TRY>, <IMMEDIATE> (r<TRX>)"
+*mips16:
+*vr4100:
+{
+ do_store (SD_, AccessLength_HALFWORD, GPR[TRX], EXTEND16 (IMMEDIATE), GPR[TRY]);
+}
+
+
+
+11011,3.RX,3.RY,5.IMMED:RRI:16::SW
+"sw r<TRY>, <IMMED> (r<TRX>)"
+*mips16:
+*vr4100:
+{
+ do_store (SD_, AccessLength_WORD, GPR[TRX], IMMED << 2, GPR[TRY]);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 11011,3.RX,3.RY,5.IMM_4_0:EXT-RRI:16::SW
+"sw r<TRY>, <IMMEDIATE> (r<TRX>)"
+*mips16:
+*vr4100:
+{
+ do_store (SD_, AccessLength_WORD, GPR[TRX], EXTEND16 (IMMEDIATE), GPR[TRY]);
+}
+
+
+
+11010,3.RX,8.IMMED:RI:16::SWSP
+"sw r<TRX>, <IMMED> (SP)"
+*mips16:
+*vr4100:
+{
+ do_store (SD_, AccessLength_WORD, SP, IMMED << 2, GPR[TRX]);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 11010,3.RX,000,5.IMM_4_0:EXT-RI:16::SWSP
+"sw r<TRX>, <IMMEDIATE> (SP)"
+*mips16:
+*vr4100:
+{
+ do_store (SD_, AccessLength_WORD, SP, EXTEND16 (IMMEDIATE), GPR[TRX]);
+}
+
+
+
+01100,010,8.IMMED:I8:16::SWRASP
+"sw r<RAIDX>, <IMMED> (SP)"
+*mips16:
+*vr4100:
+{
+ do_store (SD_, AccessLength_WORD, SP, IMMED << 2, RA);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 01100,010,000,5.IMM_4_0:EXT-I8:16::SWRASP
+"sw r<RAIDX>, <IMMEDIATE> (SP)"
+*mips16:
+*vr4100:
+{
+ do_store (SD_, AccessLength_WORD, SP, EXTEND16 (IMMEDIATE), RA);
+}
+
+
+
+01111,3.RX,3.RY,5.IMMED:RRI:16::SD
+"sd r<TRY>, <IMMED> (r<TRX>)"
+*mips16:
+*vr4100:
+{
+ do_store (SD_, AccessLength_DOUBLEWORD, GPR[TRX], IMMED << 3, GPR[TRY]);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 01111,3.RX,3.RY,5.IMM_4_0:EXT-RRI:16::SD
+"sd r<TRY>, <IMMEDIATE> (r<TRX>)"
+*mips16:
+*vr4100:
+{
+ do_store (SD_, AccessLength_DOUBLEWORD, GPR[TRX], EXTEND16 (IMMEDIATE), GPR[TRY]);
+}
+
+
+
+11111,001,3.RY,5.IMMED:RI64:16::SDSP
+"sd r<TRY>, <IMMED> (SP)"
+*mips16:
+*vr4100:
+{
+ do_store (SD_, AccessLength_DOUBLEWORD, SP, IMMED << 3, GPR[TRY]);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 11111,001,3.RY,5.IMM_4_0:EXT-RI64:16::SDSP
+"sd r<TRY>, <IMMEDIATE> (SP)"
+*mips16:
+*vr4100:
+{
+ do_store (SD_, AccessLength_DOUBLEWORD, SP, EXTEND16 (IMMEDIATE), GPR[TRY]);
+}
+
+
+
+11111,010,8.IMMED:I64:16::SDRASP
+"sd r<RAIDX>, <IMMED> (SP)"
+*mips16:
+*vr4100:
+{
+ do_store (SD_, AccessLength_DOUBLEWORD, SP, IMMED << 3, RA);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 11111,010,000,5.IMM_4_0:EXT-I64:16::SDRASP
+"sd r<RAIDX>, <IMMEDIATE> (SP)"
+*mips16:
+*vr4100:
+{
+ do_store (SD_, AccessLength_DOUBLEWORD, SP, EXTEND16 (IMMEDIATE), RA);
+}
+
+
+
+// ALU Immediate Instructions
+
+
+01101,3.RX,8.IMMED:RI:16::LI
+"li r<TRX>, <IMMED>"
+*mips16:
+*vr4100:
+{
+ do_ori (SD_, 0, TRX, IMMED);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 01101,3.RX,000,5.IMM_4_0:EXT-RI:16::LI
+"li r<TRX>, <IMMEDIATE>"
+*mips16:
+*vr4100:
+{
+ do_ori (SD_, 0, TRX, IMMEDIATE);
+}
+
+
+
+01000,3.RX,3.RY,0,4.IMMED:RRI-A:16::ADDIU
+"addiu r<TRY>, r<TRX>, <IMMED>"
+*mips16:
+*vr4100:
+{
+ do_addiu (SD_, TRX, TRY, EXTEND4 (IMMED));
+}
+
+11110,7.IMM_10_4,4.IMM_14_11 + 01000,3.RX,3.RY,0,4.IMM_3_0:EXT-RRI-A:16::ADDIU
+"addiu r<TRY>, r<TRX>, <IMMEDIATE>"
+*mips16:
+*vr4100:
+{
+ do_addiu (SD_, TRX, TRY, EXTEND15 (IMMEDIATE));
+}
+
+
+
+01001,3.RX,8.IMMED:RI:16::ADDIU8
+"addiu r<TRX>, <IMMED>"
+*mips16:
+*vr4100:
+{
+ do_addiu (SD_, TRX, TRX, EXTEND8 (IMMED));
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 01001,3.RX,000,5.IMM_4_0:EXT-RI:16::ADDIU8
+"addiu r<TRX>, <IMMEDIATE>"
+*mips16:
+*vr4100:
+{
+ do_addiu (SD_, TRX, TRX, EXTEND16 (IMMEDIATE));
+}
+
+
+
+01100,011,8.IMMED:I8:16::ADJSP
+"addiu SP, <IMMED>"
+*mips16:
+*vr4100:
+{
+ do_addiu (SD_, SPIDX, SPIDX, EXTEND8 (IMMED) << 3);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 01100,011,000,5.IMM_4_0:EXT-I8:16::ADJSP
+"addiu SP, <IMMEDIATE>"
+*mips16:
+*vr4100:
+{
+ do_addiu (SD_, SPIDX, SPIDX, EXTEND16 (IMMEDIATE));
+}
+
+
+
+00001,3.RX,8.IMMED:RI:16::ADDIUPC
+"addiu r<TRX>, PC, <IMMED>"
+*mips16:
+*vr4100:
+{
+ unsigned32 temp = (basepc (SD_) & ~3) + (IMMED << 2);
+ GPR[TRX] = EXTEND32 (temp);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 00001,3.RX,000,5.IMM_4_0:EXT-RI:16::ADDIUPC
+"addiu r<TRX>, PC, <IMMEDIATE>"
+*mips16:
+*vr4100:
+{
+ unsigned32 temp = (basepc (SD_) & ~3) + EXTEND16 (IMMEDIATE);
+ GPR[TRX] = EXTEND32 (temp);
+}
+
+
+
+00000,3.RX,8.IMMED:RI:16::ADDIUSP
+"addiu r<TRX>, SP, <IMMED>"
+*mips16:
+*vr4100:
+{
+ do_addiu (SD_, SPIDX, TRX, IMMED << 2);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 00000,3.RX,000,5.IMM_4_0:EXT-RI:16::ADDIUSP
+"addiu r<TRX>, SP, <IMMEDIATE>"
+*mips16:
+*vr4100:
+{
+ do_addiu (SD_, SPIDX, TRX, EXTEND16 (IMMEDIATE));
+}
+
+
+
+01000,3.RX,3.RY,1,4.IMMED:RRI-A:16::DADDIU
+"daddiu r<TRY>, r<TRX>, <IMMED>"
+*mips16:
+*vr4100:
+{
+ do_daddiu (SD_, TRX, TRY, EXTEND4 (IMMED));
+}
+
+11110,7.IMM_10_4,4.IMM_14_11 + 01000,3.RX,3.RY,1,4.IMM_3_0:EXT-RRI-A:16::DADDIU
+"daddiu r<TRY>, r<TRX>, <IMMEDIATE>"
+*mips16:
+*vr4100:
+{
+ do_daddiu (SD_, TRX, TRY, EXTEND15 (IMMEDIATE));
+}
+
+
+
+11111,101,3.RY,5.IMMED:RI64:16::DADDIU5
+"daddiu r<TRY>, <IMMED>"
+*mips16:
+*vr4100:
+{
+ do_daddiu (SD_, TRY, TRY, EXTEND5 (IMMED));
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 11111,101,3.RY,5.IMM_4_0:EXT-RI64:16::DADDIU5
+"daddiu r<TRY>, <IMMEDIATE>"
+*mips16:
+*vr4100:
+{
+ do_daddiu (SD_, TRY, TRY, EXTEND16 (IMMEDIATE));
+}
+
+
+
+11111,011,8.IMMED:I64:16::DADJSP
+"daddiu SP, <IMMED>"
+*mips16:
+*vr4100:
+{
+ do_daddiu (SD_, SPIDX, SPIDX, EXTEND8 (IMMED) << 3);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 11111,011,000,5.IMM_4_0:EXT-I64:16::DADJSP
+"daddiu SP, <IMMEDIATE>"
+*mips16:
+*vr4100:
+{
+ do_daddiu (SD_, SPIDX, SPIDX, EXTEND16 (IMMEDIATE));
+}
+
+
+
+11111,110,3.RY,5.IMMED:RI64:16::DADDIUPC
+"daddiu r<TRY>, PC, <IMMED>"
+*mips16:
+*vr4100:
+{
+ GPR[TRY] = (basepc (SD_) & ~3) + (IMMED << 2);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 11111,110,3.RY,5.IMM_4_0:EXT-RI64:16::DADDIUPC
+"daddiu r<TRY>, PC, <IMMEDIATE>"
+*mips16:
+*vr4100:
+{
+ GPR[TRY] = (basepc (SD_) & ~3) + EXTEND16 (IMMEDIATE);
+}
+
+
+
+11111,111,3.RY,5.IMMED:RI64:16::DADDIUSP
+"daddiu r<TRY>, SP, <IMMED>"
+*mips16:
+*vr4100:
+{
+ do_daddiu (SD_, SPIDX, TRY, IMMED << 2);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 11111,111,3.RY,5.IMM_4_0:EXT-RI64:16::DADDIUSP
+"daddiu r<TRY>, SP, <IMMEDIATE>"
+*mips16:
+*vr4100:
+{
+ do_daddiu (SD_, SPIDX, TRY, EXTEND16 (IMMEDIATE));
+}
+
+
+
+01010,3.RX,8.IMMED:RI:16::SLTI
+"slti r<TRX>, <IMMED>"
+*mips16:
+*vr4100:
+{
+ do_slti (SD_, TRX, T8IDX, IMMED);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 01010,3.RX,000,5.IMM_4_0:EXT-RI:16::SLTI
+"slti r<TRX>, <IMMEDIATE>"
+*mips16:
+*vr4100:
+{
+ do_slti (SD_, TRX, T8IDX, IMMEDIATE);
+}
+
+
+
+01011,3.RX,8.IMMED:RI:16::SLTIU
+"sltiu r<TRX>, <IMMED>"
+*mips16:
+*vr4100:
+{
+ do_sltiu (SD_, TRX, T8IDX, IMMED);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 01011,3.RX,000,5.IMM_4_0:EXT-RI:16::SLTIU
+"sltiu r<TRX>, <IMMEDIATE>"
+*mips16:
+*vr4100:
+{
+ do_sltiu (SD_, TRX, T8IDX, IMMEDIATE);
+}
+
+
+
+11101,3.RX,3.RY,01010:RR:16::CMP
+"sltiu r<TRX>, r<TRY>"
+*mips16:
+*vr4100:
+{
+ do_xor (SD_, TRX, TRY, T8IDX);
+}
+
+
+01110,3.RX,8.IMMED:RI:16::CMPI
+"sltiu r<TRX>, <IMMED>"
+*mips16:
+*vr4100:
+{
+ do_xori (SD_, TRX, T8IDX, IMMED);
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 01110,3.RX,000,5.IMM_4_0:EXT-RI:16::CMPI
+"sltiu r<TRX>, <IMMEDIATE>"
+*mips16:
+*vr4100:
+{
+ do_xori (SD_, TRX, T8IDX, IMMEDIATE);
+}
+
+
+
+// Two/Three Operand, Register-Type
+
+
+
+11100,3.RX,3.RY,3.RZ,01:RRR:16::ADDU
+"addu r<TRZ>, r<TRX>, r<TRY>"
+*mips16:
+*vr4100:
+{
+ do_addu (SD_, TRX, TRY, TRZ);
+}
+
+
+
+11100,3.RX,3.RY,3.RZ,11:RRR:16::SUBU
+"subu r<TRZ>, r<TRX>, r<TRY>"
+*mips16:
+*vr4100:
+{
+ do_subu (SD_, TRX, TRY, TRZ);
+}
+
+11100,3.RX,3.RY,3.RZ,00:RRR:16::DADDU
+"daddu r<TRZ>, r<TRX>, r<TRY>"
+*mips16:
+*vr4100:
+{
+ do_daddu (SD_, TRX, TRY, TRZ);
+}
+
+
+
+11100,3.RX,3.RY,3.RZ,10:RRR:16::DSUBU
+"dsubu r<TRZ>, r<TRX>, r<TRY>"
+*mips16:
+*vr4100:
+{
+ do_dsubu (SD_, TRX, TRY, TRZ);
+}
+
+
+
+11101,3.RX,3.RY,00010:RR:16::SLT
+"slt r<TRX>, r<TRY>"
+*mips16:
+*vr4100:
+{
+ do_slt (SD_, TRX, TRY, T8IDX);
+}
+
+
+
+11101,3.RX,3.RY,00011:RR:16::SLTU
+"sltu r<TRX>, r<TRY>"
+*mips16:
+*vr4100:
+{
+ do_sltu (SD_, TRX, TRY, T8IDX);
+}
+
+
+
+11101,3.RX,3.RY,01011:RR:16::NEG
+"neg r<TRX>, r<TRY>"
+*mips16:
+*vr4100:
+{
+ do_subu (SD_, 0, TRY, TRX);
+}
+
+
+
+11101,3.RX,3.RY,01100:RR:16::AND
+"and r<TRX>, r<TRY>"
+*mips16:
+*vr4100:
+{
+ do_and (SD_, TRX, TRY, TRX);
+}
+
+
+
+11101,3.RX,3.RY,01101:RR:16::OR
+"or r<TRX>, r<TRY>"
+*mips16:
+*vr4100:
+{
+ do_or (SD_, TRX, TRY, TRX);
+}
+
+
+
+11101,3.RX,3.RY,01110:RR:16::XOR
+"xor r<TRX>, r<TRY>"
+*mips16:
+*vr4100:
+{
+ do_xor (SD_, TRX, TRY, TRX);
+}
+
+
+
+11101,3.RX,3.RY,01111:RR:16::NOT
+"not r<TRX>, r<TRY>"
+*mips16:
+*vr4100:
+{
+ do_nor (SD_, 0, TRY, TRX);
+}
+
+
+
+01100,111,3.RY,5.R32:I8_MOVR32:16::MOVR32
+"move r<TRY>, r<R32>"
+*mips16:
+*vr4100:
+{
+ do_or (SD_, R32, 0, TRY);
+}
+
+
+
+01100,101,3.R32L,2.R32H,3.RZ:I8_MOV32R:16::MOV32R
+"move r<R32>, r<TRZ>"
+*mips16:
+*vr4100:
+{
+ do_or (SD_, TRZ, 0, R32);
+}
+
+
+
+00110,3.RX,3.RY,3.SHAMT,00:SHIFT:16::SLL
+"sll r<TRX>, r<TRY>, <SHIFT>"
+*mips16:
+*vr4100:
+{
+ do_sll (SD_, TRY, TRX, SHIFT);
+}
+
+11110,5.SHAMT,0,00000 + 00110,3.RX,3.RY,000,00:EXT-SHIFT:16::SLL
+"sll r<TRX>, r<TRY>, <SHIFT>"
+*mips16:
+*vr4100:
+{
+ do_sll (SD_, TRY, TRX, SHAMT);
+}
+
+
+
+00110,3.RX,3.RY,3.SHAMT,10:SHIFT:16::SRL
+"srl r<TRX>, r<TRY>, <SHIFT>"
+*mips16:
+*vr4100:
+{
+ do_srl (SD_, TRY, TRX, SHIFT);
+}
+
+11110,5.SHAMT,0,00000 + 00110,3.RX,3.RY,000,10:EXT-SHIFT:16::SRL
+"srl r<TRX>, r<TRY>, <SHIFT>"
+*mips16:
+*vr4100:
+{
+ do_srl (SD_, TRY, TRX, SHAMT);
+}
+
+
+
+00110,3.RX,3.RY,3.SHAMT,11:SHIFT:16::SRA
+"sra r<TRX>, r<TRY>, <SHIFT>"
+*mips16:
+*vr4100:
+{
+ do_sra (SD_, TRY, TRX, SHIFT);
+}
+
+11110,5.SHAMT,0,00000 + 00110,3.RX,3.RY,000,11:EXT-SHIFT:16::SRA
+"sra r<TRX>, r<TRY>, <SHIFT>"
+*mips16:
+*vr4100:
+{
+ do_sra (SD_, TRY, TRX, SHAMT);
+}
+
+
+
+11101,3.RX,3.RY,00100:RR:16::SLLV
+"sllv r<TRY>, r<TRX>"
+*mips16:
+*vr4100:
+{
+ do_sllv (SD_, TRX, TRY, TRY);
+}
+
+
+11101,3.RX,3.RY,00110:RR:16::SRLV
+"srlv r<TRY>, r<TRX>"
+*mips16:
+*vr4100:
+{
+ do_srlv (SD_, TRX, TRY, TRY);
+}
+
+
+11101,3.RX,3.RY,00111:RR:16::SRAV
+"srav r<TRY>, r<TRX>"
+*mips16:
+*vr4100:
+{
+ do_srav (SD_, TRX, TRY, TRY);
+}
+
+
+00110,3.RX,3.RY,3.SHAMT,01:SHIFT:16::DSLL
+"dsll r<TRY>, r<TRX>, <SHIFT>"
+*mips16:
+*vr4100:
+{
+ do_dsll (SD_, TRY, TRX, SHIFT);
+}
+
+11110,5.SHAMT_4_0,1.S5,00000 + 00110,3.RX,3.RY,000,01:EXT-SHIFT:16::DSLL
+"dsll r<TRY>, r<TRX>, <SHAMT>"
+*mips16:
+*vr4100:
+{
+ do_dsll (SD_, TRY, TRX, SHAMT);
+}
+
+
+
+11101,3.SHAMT,3.RY,01000:SHIFT64:16::DSRL
+"dsrl r<TRY>, <SHIFT>"
+*mips16:
+*vr4100:
+{
+ do_dsrl (SD_, TRY, TRY, SHIFT);
+}
+
+11110,5.SHAMT_4_0,1.S5,00000 + 11101,000,3.RY,01000:EXT-SHIFT64:16::DSRL
+"dsrl r<TRY>, <SHAMT>"
+*mips16:
+*vr4100:
+{
+ do_dsrl (SD_, TRY, TRY, SHAMT);
+}
+
+
+
+11101,3.SHAMT,3.RY,10011:SHIFT64:16::DSRA
+"dsra r<TRY>, <SHIFT>"
+*mips16:
+*vr4100:
+{
+ do_dsra (SD_, TRY, TRY, SHIFT);
+}
+
+11110,5.SHAMT_4_0,1.S5,00000 + 11101,000,3.RY,10011:EXT-SHIFT64:16::DSRA
+"dsra r<TRY>, <SHAMT>"
+*mips16:
+*vr4100:
+{
+ do_dsra (SD_, TRY, TRY, SHAMT);
+}
+
+
+
+11101,3.RX,3.RY,10100:RR:16::DSLLV
+"dsllv r<TRY>, r<TRX>"
+*mips16:
+*vr4100:
+{
+ do_dsllv (SD_, TRX, TRY, TRY);
+}
+
+
+11101,3.RX,3.RY,10110:RR:16::DSRLV
+"dsrlv r<TRY>, r<TRX>"
+*mips16:
+*vr4100:
+{
+ do_dsrlv (SD_, TRX, TRY, TRY);
+}
+
+
+11101,3.RX,3.RY,10111:RR:16::DSRAV
+"dsrav r<TRY>, r<TRX>"
+*mips16:
+*vr4100:
+{
+ do_dsrav (SD_, TRX, TRY, TRY);
+}
+
+
+// Multiply /Divide Instructions
+
+
+11101,3.RX,3.RY,11000:RR:16::MULT
+"mult r<TRX>, r<TRY>"
+*mips16:
+*vr4100:
+{
+ do_mult (SD_, TRX, TRY, 0);
+}
+
+
+11101,3.RX,3.RY,11001:RR:16::MULTU
+"multu r<TRX>, r<TRY>"
+*mips16:
+*vr4100:
+{
+ do_multu (SD_, TRX, TRY, 0);
+}
+
+
+11101,3.RX,3.RY,11010:RR:16::DIV
+"div r<TRX>, r<TRY>"
+*mips16:
+*vr4100:
+{
+ do_div (SD_, TRX, TRY);
+}
+
+
+11101,3.RX,3.RY,11011:RR:16::DIVU
+"divu r<TRX>, r<TRY>"
+*mips16:
+*vr4100:
+{
+ do_divu (SD_, TRX, TRY);
+}
+
+
+11101,3.RX,000,10000:RR:16::MFHI
+"mfhi r<TRX>"
+*mips16:
+*vr4100:
+{
+ do_mfhi (SD_, TRX);
+}
+
+
+11101,3.RX,000,10010:RR:16::MFLO
+"mflo r<TRX>"
+*mips16:
+*vr4100:
+{
+ do_mflo (SD_, TRX);
+}
+
+
+11101,3.RX,3.RY,11100:RR:16::DMULT
+"dmult r<TRX>, r<TRY>"
+*mips16:
+*vr4100:
+{
+ do_dmult (SD_, TRX, TRY, 0);
+}
+
+
+11101,3.RX,3.RY,11101:RR:16::DMULTU
+"dmultu r<TRX>, r<TRY>"
+*mips16:
+*vr4100:
+{
+ do_dmultu (SD_, TRX, TRY, 0);
+}
+
+
+11101,3.RX,3.RY,11110:RR:16::DDIV
+"ddiv r<TRX>, r<TRY>"
+*mips16:
+*vr4100:
+{
+ do_ddiv (SD_, TRX, TRY);
+}
+
+
+11101,3.RX,3.RY,11111:RR:16::DDIVU
+"ddivu r<TRX>, r<TRY>"
+*mips16:
+*vr4100:
+{
+ do_ddivu (SD_, TRX, TRY);
+}
+
+
+// Jump and Branch Instructions
+
+
+
+// Issue instruction in delay slot of branch
+:function:::address_word:delayslot16:address_word nia, address_word target
+{
+ instruction_word delay_insn;
+ sim_events_slip (SD, 1);
+ DSPC = CIA; /* save current PC somewhere */
+ STATE |= simDELAYSLOT;
+ delay_insn = IMEM16 (nia); /* NOTE: mips16 */
+ idecode_issue (CPU_, delay_insn, (nia));
+ STATE &= ~simDELAYSLOT;
+ return target;
+}
+
+// compute basepc dependant on us being in a delay slot
+:function:::address_word:basepc:
+{
+ if (STATE & simDELAYSLOT)
+ {
+ return DSPC; /* return saved address of preceeding jmp */
+ }
+ else
+ {
+ return CIA;
+ }
+}
+
+
+// JAL
+00011,0,5.IMM_20_16,5.IMM_25_21 + 16.IMMED_15_0:JAL:16::JAL
+"jal <IMMEDIATE>"
+*mips16:
+*vr4100:
+{
+ address_word region = (NIA & MASK (63, 28));
+ RA = NIA + 2; /* skip 16 bit delayslot insn */
+ NIA = delayslot16 (SD_, NIA, (region | (IMMEDIATE << 2))) | 1;
+}
+
+
+
+// JALX - 32 and 16 bit versions.
+
+011101,26.IMMED:JALX:32::JALX32
+"jalx <IMMED>"
+*mips16:
+*vr4100:
+{
+ address_word region = (NIA & MASK (63, 28));
+ RA = NIA + 4; /* skip 32 bit delayslot insn */
+ NIA = delayslot32 (SD_, (region | (IMMED << 2)) | 1);
+}
+
+00011,1,5.IMM_20_16,5.IMM_25_21 + 16.IMMED_15_0:JALX:16::JALX16
+"jalx <IMMEDIATE>"
+*mips16:
+*vr4100:
+{
+ address_word region = (NIA & MASK (63, 28));
+ RA = NIA + 2; /* 16 bit INSN */
+ NIA = delayslot16 (SD_, NIA, (region | (IMMEDIATE << 2)) & ~1);
+}
+
+
+
+11101,3.RX,000,00000:RR:16::JR
+"jr r<TRX>"
+*mips16:
+*vr4100:
+{
+ NIA = delayslot16 (SD_, NIA, GPR[TRX]);
+}
+
+
+11101,000,001,00000:RR:16::JRRA
+"jrra"
+*mips16:
+*vr4100:
+{
+ NIA = delayslot16 (SD_, NIA, RA);
+}
+
+
+
+11101,3.RX,010,00000:RR:16::JALR
+"jalr r<TRX>"
+*mips16:
+*vr4100:
+{
+ RA = NIA + 2;
+ NIA = delayslot16 (SD_, NIA, GPR[TRX]);
+}
+
+
+
+00100,3.RX,8.IMMED:RI:16::BEQZ
+"beqz r<TRX>, <IMMED>"
+*mips16:
+*vr4100:
+{
+ if (GPR[TRX] == 0)
+ NIA = (NIA + (EXTEND8 (IMMED) << 1));
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 00100,3.RX,000,5.IMM_4_0:EXT-RI:16::BEQZ
+"beqz r<TRX>, <IMMEDIATE>"
+*mips16:
+*vr4100:
+{
+ if (GPR[TRX] == 0)
+ NIA = (NIA + (EXTEND16 (IMMEDIATE) << 1));
+}
+
+
+
+00101,3.RX,8.IMMED:RI:16::BNEZ
+"bnez r<TRX>, <IMMED>"
+*mips16:
+*vr4100:
+{
+ if (GPR[TRX] != 0)
+ NIA = (NIA + (EXTEND8 (IMMED) << 1));
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 00101,3.RX,000,5.IMM_4_0:EXT-RI:16::BNEZ
+"bnez r<TRX>, <IMMEDIATE>"
+*mips16:
+*vr4100:
+{
+ if (GPR[TRX] != 0)
+ NIA = (NIA + (EXTEND16 (IMMEDIATE) << 1));
+}
+
+
+
+01100,000,8.IMMED:I8:16::BTEQZ
+"bteqz <IMMED>"
+*mips16:
+*vr4100:
+{
+ if (T8 == 0)
+ NIA = (NIA + (EXTEND8 (IMMED) << 1));
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 01100,000,000,5.IMM_4_0:EXT-I8:16::BTEQZ
+"bteqz <IMMEDIATE>"
+*mips16:
+*vr4100:
+{
+ if (T8 == 0)
+ NIA = (NIA + (EXTEND16 (IMMEDIATE) << 1));
+}
+
+
+
+01100,001,8.IMMED:I8:16::BTNEZ
+"btnez <IMMED>"
+*mips16:
+*vr4100:
+{
+ if (T8 != 0)
+ NIA = (NIA + (EXTEND8 (IMMED) << 1));
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 01100,001,000,5.IMM_4_0:EXT-I8:16::BTNEZ
+"btnez <IMMEDIATE>"
+*mips16:
+*vr4100:
+{
+ if (T8 != 0)
+ NIA = (NIA + (EXTEND16 (IMMEDIATE) << 1));
+}
+
+
+
+00010,11.IMMED:I:16::B
+"b <IMMED>"
+*mips16:
+*vr4100:
+{
+ NIA = (NIA + (EXTEND11 (IMMED) << 1));
+}
+
+11110,6.IMM_10_5,5.IMM_15_11 + 00010,6.0,5.IMM_4_0:EXT-I:16::B
+"b <IMMEDIATE>"
+*mips16:
+*vr4100:
+{
+ NIA = (NIA + (EXTEND16 (IMMEDIATE) << 1));
+}
+
+
+
+11101,3.RX,3.RY,00101:RR:16::BREAK
+"break"
+*mips16:
+*vr4100:
+{
+ if (STATE & simDELAYSLOT)
+ PC = cia - 2; /* reference the branch instruction */
+ else
+ PC = cia;
+ sim_engine_halt (SD, CPU, NULL, cia, sim_stopped, SIM_SIGTRAP);
+}
diff --git a/sim/mips/m16run.c b/sim/mips/m16run.c
new file mode 100644
index 0000000..8a5d607
--- /dev/null
+++ b/sim/mips/m16run.c
@@ -0,0 +1,74 @@
+/* This file is part of the program psim.
+
+ Copyright (C) 1998, Andrew Cagney <cagney@highland.com.au>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#include "sim-main.h"
+#include "m16_idecode.h"
+#include "m32_idecode.h"
+#include "bfd.h"
+
+
+#define SD sd
+#define CPU cpu
+
+void
+sim_engine_run (SIM_DESC sd,
+ int next_cpu_nr,
+ int nr_cpus, /* ignore */
+ int siggnal) /* ignore */
+{
+ sim_cpu *cpu = STATE_CPU (sd, next_cpu_nr);
+ address_word cia = CIA_GET (cpu);
+
+ while (1)
+ {
+ address_word nia;
+
+#if defined (ENGINE_ISSUE_PREFIX_HOOK)
+ ENGINE_ISSUE_PREFIX_HOOK ();
+#endif
+
+ if ((cia & 1))
+ {
+ m16_instruction_word instruction_0 = IMEM16 (cia);
+ nia = m16_idecode_issue (sd, instruction_0, cia);
+ }
+ else
+ {
+ m32_instruction_word instruction_0 = IMEM32 (cia);
+ nia = m32_idecode_issue (sd, instruction_0, cia);
+ }
+
+#if defined (ENGINE_ISSUE_POSTFIX_HOOK)
+ ENGINE_ISSUE_POSTFIX_HOOK ();
+#endif
+
+ /* Update the instruction address */
+ cia = nia;
+
+ /* process any events */
+ if (sim_events_tick (sd))
+ {
+ CIA_SET (CPU, cia);
+ sim_events_process (sd);
+ cia = CIA_GET (CPU);
+ }
+
+ }
+}
diff --git a/sim/mips/mips.dc b/sim/mips/mips.dc
new file mode 100644
index 0000000..98da024
--- /dev/null
+++ b/sim/mips/mips.dc
@@ -0,0 +1,16 @@
+# most instructions
+# ------ options ------ : Fst : Lst : ff : fl : fe : word : --- fmt --- : model ...
+# { : mask : value : word }
+
+# Top level - create a very big switch statement.
+
+ padded-switch,combine : 31 : 26 : : : : : :
+
+ switch,combine : 5 : 0 : : : : : :
+
+ switch,combine : 20 : 16 : : : : : :
+
+ switch,combine : 25 : 21 : : : : : :
+
+ switch,combine : 10 : 6 : : : : : :
+
diff --git a/sim/mips/mips.igen b/sim/mips/mips.igen
new file mode 100644
index 0000000..bfc209a
--- /dev/null
+++ b/sim/mips/mips.igen
@@ -0,0 +1,3895 @@
+// -*- C -*-
+//
+// In mips.igen, the semantics for many of the instructions were created
+// using code generated by gencode. Those semantic segments could be
+// greatly simplified.
+//
+// <insn> ::=
+// <insn-word> { "+" <insn-word> }
+// ":" <format-name>
+// ":" <filter-flags>
+// ":" <options>
+// ":" <name>
+// <nl>
+// { <insn-model> }
+// { <insn-mnemonic> }
+// <code-block>
+//
+
+
+// IGEN config - mips16
+// :option:16::insn-bit-size:16
+// :option:16::hi-bit-nr:15
+:option:16::insn-specifying-widths:true
+:option:16::gen-delayed-branch:false
+
+// IGEN config - mips32/64..
+// :option:32::insn-bit-size:32
+// :option:32::hi-bit-nr:31
+:option:32::insn-specifying-widths:true
+:option:32::gen-delayed-branch:false
+
+
+// Generate separate simulators for each target
+// :option:::multi-sim:true
+
+
+// Models known by this simulator
+:model:::mipsI:mips3000:
+:model:::mipsII:mips6000:
+:model:::mipsIII:mips4000:
+:model:::mipsIV:mips8000:
+:model:::mips16:mips16:
+:model:::r3900:mips3900:
+:model:::vr4100:mips4100:
+:model:::vr5000:mips5000:
+
+
+
+// Pseudo instructions known by IGEN
+:internal::::illegal:
+{
+ SignalException (ReservedInstruction, 0);
+}
+
+
+// Pseudo instructions known by interp.c
+// For grep - RSVD_INSTRUCTION, RSVD_INSTRUCTION_MASK
+000000,5.*,5.*,5.*,5.OP,000101:SPECIAL:32::RSVD
+"rsvd <OP>"
+{
+ SignalException (ReservedInstruction, instruction_0);
+}
+
+
+
+// Helper:
+//
+// Simulate a 32 bit delayslot instruction
+//
+
+:function:::address_word:delayslot32:address_word target
+{
+ instruction_word delay_insn;
+ sim_events_slip (SD, 1);
+ DSPC = CIA;
+ CIA = CIA + 4; /* NOTE not mips16 */
+ STATE |= simDELAYSLOT;
+ delay_insn = IMEM32 (CIA); /* NOTE not mips16 */
+ idecode_issue (CPU_, delay_insn, (CIA));
+ STATE &= ~simDELAYSLOT;
+ return target;
+}
+
+:function:::address_word:nullify_next_insn32:
+{
+ sim_events_slip (SD, 1);
+ dotrace (SD, CPU, tracefh, 2, CIA + 4, 4, "load instruction");
+ return CIA + 8;
+}
+
+// Helper:
+//
+// Check that an access to a HI/LO register meets timing requirements
+//
+// The following requirements exist:
+//
+// - A MT {HI,LO} update was not immediatly preceeded by a MF {HI,LO} read
+// - A OP {HI,LO} update was not immediatly preceeded by a MF {HI,LO} read
+// - A MF {HI,LO} read was not corrupted by a preceeding MT{LO,HI} update
+// corruption occures when MT{LO,HI} is preceeded by a OP {HI,LO}.
+//
+
+:function:::int:check_mf_cycles:hilo_history *history, signed64 time, const char *new
+{
+ if (history->mf.timestamp + 3 > time)
+ {
+ sim_engine_abort (SD, CPU, CIA, "HILO: %s: %s at 0x%08lx too close to MF at 0x%08lx\n",
+ itable[MY_INDEX].name,
+ new, (long) CIA,
+ (long) history->mf.cia);
+ return 0;
+ }
+ return 1;
+}
+
+:function:::int:check_mt_hilo:hilo_history *history
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+{
+ signed64 time = sim_events_time (SD);
+ int ok = check_mf_cycles (SD_, history, time, "MT");
+ history->mt.timestamp = time;
+ history->mt.cia = CIA;
+ return ok;
+}
+
+:function:::int:check_mt_hilo:hilo_history *history
+*r3900:
+{
+ signed64 time = sim_events_time (SD);
+ history->mt.timestamp = time;
+ history->mt.cia = CIA;
+ return 1;
+}
+
+
+:function:::int:check_mf_hilo:hilo_history *history, hilo_history *peer
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ signed64 time = sim_events_time (SD);
+ int ok = 1;
+ if (peer != NULL
+ && peer->mt.timestamp > history->op.timestamp
+ && history->mt.timestamp < history->op.timestamp
+ && ! (history->mf.timestamp > history->op.timestamp
+ && history->mf.timestamp < peer->mt.timestamp)
+ && ! (peer->mf.timestamp > history->op.timestamp
+ && peer->mf.timestamp < peer->mt.timestamp))
+ {
+ /* The peer has been written to since the last OP yet we have
+ not */
+ sim_engine_abort (SD, CPU, CIA, "HILO: %s: MF at 0x%08lx following OP at 0x%08lx corrupted by MT at 0x%08lx\n",
+ itable[MY_INDEX].name,
+ (long) CIA,
+ (long) history->op.cia,
+ (long) peer->mt.cia);
+ ok = 0;
+ }
+ history->mf.timestamp = time;
+ history->mf.cia = CIA;
+ return ok;
+}
+
+
+
+:function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+{
+ signed64 time = sim_events_time (SD);
+ int ok = (check_mf_cycles (SD_, hi, time, "OP")
+ && check_mf_cycles (SD_, lo, time, "OP"));
+ hi->op.timestamp = time;
+ lo->op.timestamp = time;
+ hi->op.cia = CIA;
+ lo->op.cia = CIA;
+ return ok;
+}
+
+// The r3900 mult and multu insns _can_ be exectuted immediatly after
+// a mf{hi,lo}
+:function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo
+*r3900:
+{
+ /* FIXME: could record the fact that a stall occured if we want */
+ signed64 time = sim_events_time (SD);
+ hi->op.timestamp = time;
+ lo->op.timestamp = time;
+ hi->op.cia = CIA;
+ lo->op.cia = CIA;
+ return 1;
+}
+
+
+:function:::int:check_div_hilo:hilo_history *hi, hilo_history *lo
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ signed64 time = sim_events_time (SD);
+ int ok = (check_mf_cycles (SD_, hi, time, "OP")
+ && check_mf_cycles (SD_, lo, time, "OP"));
+ hi->op.timestamp = time;
+ lo->op.timestamp = time;
+ hi->op.cia = CIA;
+ lo->op.cia = CIA;
+ return ok;
+}
+
+
+
+
+
+//
+// Mips Architecture:
+//
+// CPU Instruction Set (mipsI - mipsIV)
+//
+
+
+
+000000,5.RS,5.RT,5.RD,00000,100000:SPECIAL:32::ADD
+"add r<RD>, r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
+ {
+ ALU32_BEGIN (GPR[RS]);
+ ALU32_ADD (GPR[RT]);
+ ALU32_END (GPR[RD]);
+ }
+ TRACE_ALU_RESULT (GPR[RD]);
+}
+
+
+
+001000,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDI
+"addi r<RT>, r<RS>, IMMEDIATE"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ TRACE_ALU_INPUT2 (GPR[RS], EXTEND16 (IMMEDIATE));
+ {
+ ALU32_BEGIN (GPR[RS]);
+ ALU32_ADD (EXTEND16 (IMMEDIATE));
+ ALU32_END (GPR[RT]);
+ }
+ TRACE_ALU_RESULT (GPR[RT]);
+}
+
+
+
+:function:::void:do_addiu:int rs, int rt, unsigned16 immediate
+{
+ TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
+ GPR[rt] = EXTEND32 (GPR[rs] + EXTEND16 (immediate));
+ TRACE_ALU_RESULT (GPR[rt]);
+}
+
+001001,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDIU
+"addiu r<RT>, r<RS>, <IMMEDIATE>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_addiu (SD_, RS, RT, IMMEDIATE);
+}
+
+
+
+:function:::void:do_addu:int rs, int rt, int rd
+{
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ GPR[rd] = EXTEND32 (GPR[rs] + GPR[rt]);
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+000000,5.RS,5.RT,5.RD,00000,100001:SPECIAL:32::ADDU
+"addu r<RD>, r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_addu (SD_, RS, RT, RD);
+}
+
+
+
+:function:::void:do_and:int rs, int rt, int rd
+{
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ GPR[rd] = GPR[rs] & GPR[rt];
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+000000,5.RS,5.RT,5.RD,00000,100100:SPECIAL:32::AND
+"and r<RD>, r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_and (SD_, RS, RT, RD);
+}
+
+
+
+001100,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ANDI
+"and r<RT>, r<RS>, <IMMEDIATE>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ TRACE_ALU_INPUT2 (GPR[RS], IMMEDIATE);
+ GPR[RT] = GPR[RS] & IMMEDIATE;
+ TRACE_ALU_RESULT (GPR[RT]);
+}
+
+
+
+000100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQ
+"beq r<RS>, r<RT>, <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ address_word offset = EXTEND16 (OFFSET) << 2;
+ check_branch_bug ();
+ if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
+ {
+ mark_branch_bug (NIA+offset);
+ DELAY_SLOT (NIA + offset);
+ }
+}
+
+
+
+010100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQL
+"beql r<RS>, r<RT>, <OFFSET>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ address_word offset = EXTEND16 (OFFSET) << 2;
+ check_branch_bug ();
+ if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
+ {
+ mark_branch_bug (NIA+offset);
+ DELAY_SLOT (NIA + offset);
+ }
+ else
+ NULLIFY_NEXT_INSTRUCTION ();
+}
+
+
+
+000001,5.RS,00001,16.OFFSET:REGIMM:32::BGEZ
+"bgez r<RS>, <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ address_word offset = EXTEND16 (OFFSET) << 2;
+ check_branch_bug ();
+ if ((signed_word) GPR[RS] >= 0)
+ {
+ mark_branch_bug (NIA+offset);
+ DELAY_SLOT (NIA + offset);
+ }
+}
+
+
+
+000001,5.RS!31,10001,16.OFFSET:REGIMM:32::BGEZAL
+"bgezal r<RS>, <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ address_word offset = EXTEND16 (OFFSET) << 2;
+ check_branch_bug ();
+ RA = (CIA + 8);
+ if ((signed_word) GPR[RS] >= 0)
+ {
+ mark_branch_bug (NIA+offset);
+ DELAY_SLOT (NIA + offset);
+ }
+}
+
+
+
+000001,5.RS!31,10011,16.OFFSET:REGIMM:32::BGEZALL
+"bgezall r<RS>, <OFFSET>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ address_word offset = EXTEND16 (OFFSET) << 2;
+ check_branch_bug ();
+ RA = (CIA + 8);
+ /* NOTE: The branch occurs AFTER the next instruction has been
+ executed */
+ if ((signed_word) GPR[RS] >= 0)
+ {
+ mark_branch_bug (NIA+offset);
+ DELAY_SLOT (NIA + offset);
+ }
+ else
+ NULLIFY_NEXT_INSTRUCTION ();
+}
+
+
+
+000001,5.RS,00011,16.OFFSET:REGIMM:32::BGEZL
+"bgezl r<RS>, <OFFSET>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ address_word offset = EXTEND16 (OFFSET) << 2;
+ check_branch_bug ();
+ if ((signed_word) GPR[RS] >= 0)
+ {
+ mark_branch_bug (NIA+offset);
+ DELAY_SLOT (NIA + offset);
+ }
+ else
+ NULLIFY_NEXT_INSTRUCTION ();
+}
+
+
+
+000111,5.RS,00000,16.OFFSET:NORMAL:32::BGTZ
+"bgtz r<RS>, <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ address_word offset = EXTEND16 (OFFSET) << 2;
+ check_branch_bug ();
+ if ((signed_word) GPR[RS] > 0)
+ {
+ mark_branch_bug (NIA+offset);
+ DELAY_SLOT (NIA + offset);
+ }
+}
+
+
+
+010111,5.RS,00000,16.OFFSET:NORMAL:32::BGTZL
+"bgtzl r<RS>, <OFFSET>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ address_word offset = EXTEND16 (OFFSET) << 2;
+ check_branch_bug ();
+ /* NOTE: The branch occurs AFTER the next instruction has been
+ executed */
+ if ((signed_word) GPR[RS] > 0)
+ {
+ mark_branch_bug (NIA+offset);
+ DELAY_SLOT (NIA + offset);
+ }
+ else
+ NULLIFY_NEXT_INSTRUCTION ();
+}
+
+
+
+000110,5.RS,00000,16.OFFSET:NORMAL:32::BLEZ
+"blez r<RS>, <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ address_word offset = EXTEND16 (OFFSET) << 2;
+ check_branch_bug ();
+ /* NOTE: The branch occurs AFTER the next instruction has been
+ executed */
+ if ((signed_word) GPR[RS] <= 0)
+ {
+ mark_branch_bug (NIA+offset);
+ DELAY_SLOT (NIA + offset);
+ }
+}
+
+
+
+010110,5.RS,00000,16.OFFSET:NORMAL:32::BLEZL
+"bgezl r<RS>, <OFFSET>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ address_word offset = EXTEND16 (OFFSET) << 2;
+ check_branch_bug ();
+ if ((signed_word) GPR[RS] <= 0)
+ {
+ mark_branch_bug (NIA+offset);
+ DELAY_SLOT (NIA + offset);
+ }
+ else
+ NULLIFY_NEXT_INSTRUCTION ();
+}
+
+
+
+000001,5.RS,00000,16.OFFSET:REGIMM:32::BLTZ
+"bltz r<RS>, <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ address_word offset = EXTEND16 (OFFSET) << 2;
+ check_branch_bug ();
+ if ((signed_word) GPR[RS] < 0)
+ {
+ mark_branch_bug (NIA+offset);
+ DELAY_SLOT (NIA + offset);
+ }
+}
+
+
+
+000001,5.RS!31,10000,16.OFFSET:REGIMM:32::BLTZAL
+"bltzal r<RS>, <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ address_word offset = EXTEND16 (OFFSET) << 2;
+ check_branch_bug ();
+ RA = (CIA + 8);
+ /* NOTE: The branch occurs AFTER the next instruction has been
+ executed */
+ if ((signed_word) GPR[RS] < 0)
+ {
+ mark_branch_bug (NIA+offset);
+ DELAY_SLOT (NIA + offset);
+ }
+}
+
+
+
+000001,5.RS!31,10010,16.OFFSET:REGIMM:32::BLTZALL
+"bltzall r<RS>, <OFFSET>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ address_word offset = EXTEND16 (OFFSET) << 2;
+ check_branch_bug ();
+ RA = (CIA + 8);
+ if ((signed_word) GPR[RS] < 0)
+ {
+ mark_branch_bug (NIA+offset);
+ DELAY_SLOT (NIA + offset);
+ }
+ else
+ NULLIFY_NEXT_INSTRUCTION ();
+}
+
+
+
+000001,5.RS,00010,16.OFFSET:REGIMM:32::BLTZL
+"bltzl r<RS>, <OFFSET>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ address_word offset = EXTEND16 (OFFSET) << 2;
+ check_branch_bug ();
+ /* NOTE: The branch occurs AFTER the next instruction has been
+ executed */
+ if ((signed_word) GPR[RS] < 0)
+ {
+ mark_branch_bug (NIA+offset);
+ DELAY_SLOT (NIA + offset);
+ }
+ else
+ NULLIFY_NEXT_INSTRUCTION ();
+}
+
+
+
+000101,5.RS,5.RT,16.OFFSET:NORMAL:32::BNE
+"bne r<RS>, r<RT>, <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ address_word offset = EXTEND16 (OFFSET) << 2;
+ check_branch_bug ();
+ if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
+ {
+ mark_branch_bug (NIA+offset);
+ DELAY_SLOT (NIA + offset);
+ }
+}
+
+
+
+010101,5.RS,5.RT,16.OFFSET:NORMAL:32::BNEL
+"bnel r<RS>, r<RT>, <OFFSET>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ address_word offset = EXTEND16 (OFFSET) << 2;
+ check_branch_bug ();
+ if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
+ {
+ mark_branch_bug (NIA+offset);
+ DELAY_SLOT (NIA + offset);
+ }
+ else
+ NULLIFY_NEXT_INSTRUCTION ();
+}
+
+
+
+000000,20.CODE,001101:SPECIAL:32::BREAK
+"break"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ /* Check for some break instruction which are reserved for use by the simulator. */
+ unsigned int break_code = instruction_0 & HALT_INSTRUCTION_MASK;
+ if (break_code == (HALT_INSTRUCTION & HALT_INSTRUCTION_MASK) ||
+ break_code == (HALT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))
+ {
+ sim_engine_halt (SD, CPU, NULL, cia,
+ sim_exited, (unsigned int)(A0 & 0xFFFFFFFF));
+ }
+ else if (break_code == (BREAKPOINT_INSTRUCTION & HALT_INSTRUCTION_MASK) ||
+ break_code == (BREAKPOINT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))
+ {
+ if (STATE & simDELAYSLOT)
+ PC = cia - 4; /* reference the branch instruction */
+ else
+ PC = cia;
+ SignalException(BreakPoint, instruction_0);
+ }
+
+ else
+ {
+ /* If we get this far, we're not an instruction reserved by the sim. Raise
+ the exception. */
+ SignalException(BreakPoint, instruction_0);
+ }
+}
+
+
+
+
+
+
+000000,5.RS,5.RT,5.RD,00000,101100:SPECIAL:64::DADD
+"dadd r<RD>, r<RS>, r<RT>"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ /* this check's for overflow */
+ TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
+ {
+ ALU64_BEGIN (GPR[RS]);
+ ALU64_ADD (GPR[RT]);
+ ALU64_END (GPR[RD]);
+ }
+ TRACE_ALU_RESULT (GPR[RD]);
+}
+
+
+
+011000,5.RS,5.RT,16.IMMEDIATE:NORMAL:64::DADDI
+"daddi r<RT>, r<RS>, <IMMEDIATE>"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ TRACE_ALU_INPUT2 (GPR[RS], EXTEND16 (IMMEDIATE));
+ {
+ ALU64_BEGIN (GPR[RS]);
+ ALU64_ADD (EXTEND16 (IMMEDIATE));
+ ALU64_END (GPR[RT]);
+ }
+ TRACE_ALU_RESULT (GPR[RT]);
+}
+
+
+
+:function:::void:do_daddiu:int rs, int rt, unsigned16 immediate
+{
+ TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
+ GPR[rt] = GPR[rs] + EXTEND16 (immediate);
+ TRACE_ALU_RESULT (GPR[rt]);
+}
+
+011001,5.RS,5.RT,16.IMMEDIATE:NORMAL:64::DADDIU
+"daddu r<RT>, r<RS>, <IMMEDIATE>"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ do_daddiu (SD_, RS, RT, IMMEDIATE);
+}
+
+
+
+:function:::void:do_daddu:int rs, int rt, int rd
+{
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ GPR[rd] = GPR[rs] + GPR[rt];
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+000000,5.RS,5.RT,5.RD,00000,101101:SPECIAL:64::DADDU
+"daddu r<RD>, r<RS>, r<RT>"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ do_daddu (SD_, RS, RT, RD);
+}
+
+
+
+:function:::void:do_ddiv:int rs, int rt
+{
+ check_div_hilo (SD_, HIHISTORY, LOHISTORY);
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ {
+ signed64 n = GPR[rs];
+ signed64 d = GPR[rt];
+ signed64 hi;
+ signed64 lo;
+ if (d == 0)
+ {
+ lo = SIGNED64 (0x8000000000000000);
+ hi = 0;
+ }
+ else if (d == -1 && n == SIGNED64 (0x8000000000000000))
+ {
+ lo = SIGNED64 (0x8000000000000000);
+ hi = 0;
+ }
+ else
+ {
+ lo = (n / d);
+ hi = (n % d);
+ }
+ HI = hi;
+ LO = lo;
+ }
+ TRACE_ALU_RESULT2 (HI, LO);
+}
+
+000000,5.RS,5.RT,0000000000011110:SPECIAL:64::DDIV
+"ddiv r<RS>, r<RT>"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ do_ddiv (SD_, RS, RT);
+}
+
+
+
+:function:::void:do_ddivu:int rs, int rt
+{
+ check_div_hilo (SD_, HIHISTORY, LOHISTORY);
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ {
+ unsigned64 n = GPR[rs];
+ unsigned64 d = GPR[rt];
+ unsigned64 hi;
+ unsigned64 lo;
+ if (d == 0)
+ {
+ lo = SIGNED64 (0x8000000000000000);
+ hi = 0;
+ }
+ else
+ {
+ lo = (n / d);
+ hi = (n % d);
+ }
+ HI = hi;
+ LO = lo;
+ }
+ TRACE_ALU_RESULT2 (HI, LO);
+}
+
+000000,5.RS,5.RT,0000000000,011111:SPECIAL:64::DDIVU
+"ddivu r<RS>, r<RT>"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ do_ddivu (SD_, RS, RT);
+}
+
+
+
+:function:::void:do_div:int rs, int rt
+{
+ check_div_hilo (SD_, HIHISTORY, LOHISTORY);
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ {
+ signed32 n = GPR[rs];
+ signed32 d = GPR[rt];
+ if (d == 0)
+ {
+ LO = EXTEND32 (0x80000000);
+ HI = EXTEND32 (0);
+ }
+ else if (n == SIGNED32 (0x80000000) && d == -1)
+ {
+ LO = EXTEND32 (0x80000000);
+ HI = EXTEND32 (0);
+ }
+ else
+ {
+ LO = EXTEND32 (n / d);
+ HI = EXTEND32 (n % d);
+ }
+ }
+ TRACE_ALU_RESULT2 (HI, LO);
+}
+
+000000,5.RS,5.RT,0000000000011010:SPECIAL:32::DIV
+"div r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_div (SD_, RS, RT);
+}
+
+
+
+:function:::void:do_divu:int rs, int rt
+{
+ check_div_hilo (SD_, HIHISTORY, LOHISTORY);
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ {
+ unsigned32 n = GPR[rs];
+ unsigned32 d = GPR[rt];
+ if (d == 0)
+ {
+ LO = EXTEND32 (0x80000000);
+ HI = EXTEND32 (0);
+ }
+ else
+ {
+ LO = EXTEND32 (n / d);
+ HI = EXTEND32 (n % d);
+ }
+ }
+ TRACE_ALU_RESULT2 (HI, LO);
+}
+
+000000,5.RS,5.RT,0000000000011011:SPECIAL:32::DIVU
+"divu r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_divu (SD_, RS, RT);
+}
+
+
+
+:function:::void:do_dmultx:int rs, int rt, int rd, int signed_p
+{
+ unsigned64 lo;
+ unsigned64 hi;
+ unsigned64 m00;
+ unsigned64 m01;
+ unsigned64 m10;
+ unsigned64 m11;
+ unsigned64 mid;
+ int sign;
+ unsigned64 op1 = GPR[rs];
+ unsigned64 op2 = GPR[rt];
+ check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ /* make signed multiply unsigned */
+ sign = 0;
+ if (signed_p)
+ {
+ if (op1 < 0)
+ {
+ op1 = - op1;
+ ++sign;
+ }
+ if (op2 < 0)
+ {
+ op2 = - op2;
+ ++sign;
+ }
+ }
+ /* multuply out the 4 sub products */
+ m00 = ((unsigned64) VL4_8 (op1) * (unsigned64) VL4_8 (op2));
+ m10 = ((unsigned64) VH4_8 (op1) * (unsigned64) VL4_8 (op2));
+ m01 = ((unsigned64) VL4_8 (op1) * (unsigned64) VH4_8 (op2));
+ m11 = ((unsigned64) VH4_8 (op1) * (unsigned64) VH4_8 (op2));
+ /* add the products */
+ mid = ((unsigned64) VH4_8 (m00)
+ + (unsigned64) VL4_8 (m10)
+ + (unsigned64) VL4_8 (m01));
+ lo = U8_4 (mid, m00);
+ hi = (m11
+ + (unsigned64) VH4_8 (mid)
+ + (unsigned64) VH4_8 (m01)
+ + (unsigned64) VH4_8 (m10));
+ /* fix the sign */
+ if (sign & 1)
+ {
+ lo = -lo;
+ if (lo == 0)
+ hi = -hi;
+ else
+ hi = -hi - 1;
+ }
+ /* save the result HI/LO (and a gpr) */
+ LO = lo;
+ HI = hi;
+ if (rd != 0)
+ GPR[rd] = lo;
+ TRACE_ALU_RESULT2 (HI, LO);
+}
+
+:function:::void:do_dmult:int rs, int rt, int rd
+{
+ do_dmultx (SD_, rs, rt, rd, 1);
+}
+
+000000,5.RS,5.RT,0000000000011100:SPECIAL:64::DMULT
+"dmult r<RS>, r<RT>"
+*mipsIII,mipsIV:
+*vr4100:
+{
+ do_dmult (SD_, RS, RT, 0);
+}
+
+000000,5.RS,5.RT,5.RD,00000011100:SPECIAL:64::DMULT
+"dmult r<RS>, r<RT>":RD == 0
+"dmult r<RD>, r<RS>, r<RT>"
+*vr5000:
+{
+ do_dmult (SD_, RS, RT, RD);
+}
+
+
+
+:function:::void:do_dmultu:int rs, int rt, int rd
+{
+ do_dmultx (SD_, rs, rt, rd, 0);
+}
+
+000000,5.RS,5.RT,0000000000011101:SPECIAL:64::DMULTU
+"dmultu r<RS>, r<RT>"
+*mipsIII,mipsIV:
+*vr4100:
+{
+ do_dmultu (SD_, RS, RT, 0);
+}
+
+000000,5.RS,5.RT,5.RD,00000011101:SPECIAL:64::DMULTU
+"dmultu r<RD>, r<RS>, r<RT>":RD == 0
+"dmultu r<RS>, r<RT>"
+*vr5000:
+{
+ do_dmultu (SD_, RS, RT, RD);
+}
+
+:function:::void:do_dsll:int rt, int rd, int shift
+{
+ GPR[rd] = GPR[rt] << shift;
+}
+
+:function:::void:do_dsllv:int rs, int rt, int rd
+{
+ int s = MASKED64 (GPR[rs], 5, 0);
+ GPR[rd] = GPR[rt] << s;
+}
+
+
+00000000000,5.RT,5.RD,5.SHIFT,111000:SPECIAL:64::DSLL
+"dsll r<RD>, r<RT>, <SHIFT>"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ do_dsll (SD_, RT, RD, SHIFT);
+}
+
+
+00000000000,5.RT,5.RD,5.SHIFT,111100:SPECIAL:64::DSLL32
+"dsll32 r<RD>, r<RT>, <SHIFT>"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ int s = 32 + SHIFT;
+ GPR[RD] = GPR[RT] << s;
+}
+
+000000,5.RS,5.RT,5.RD,00000010100:SPECIAL:64::DSLLV
+"dsllv r<RD>, r<RT>, r<RS>"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ do_dsllv (SD_, RS, RT, RD);
+}
+
+:function:::void:do_dsra:int rt, int rd, int shift
+{
+ GPR[rd] = ((signed64) GPR[rt]) >> shift;
+}
+
+
+00000000000,5.RT,5.RD,5.SHIFT,111011:SPECIAL:64::DSRA
+"dsra r<RD>, r<RT>, <SHIFT>"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ do_dsra (SD_, RT, RD, SHIFT);
+}
+
+
+00000000000,5.RT,5.RD,5.SHIFT,111111:SPECIAL:64::DSRA32
+"dsra32 r<RT>, r<RD>, <SHIFT>"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ int s = 32 + SHIFT;
+ GPR[RD] = ((signed64) GPR[RT]) >> s;
+}
+
+
+:function:::void:do_dsrav:int rs, int rt, int rd
+{
+ int s = MASKED64 (GPR[rs], 5, 0);
+ TRACE_ALU_INPUT2 (GPR[rt], s);
+ GPR[rd] = ((signed64) GPR[rt]) >> s;
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+000000,5.RS,5.RT,5.RD,00000010111:SPECIAL:64::DSRAV
+"dsra32 r<RT>, r<RD>, r<RS>"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ do_dsrav (SD_, RS, RT, RD);
+}
+
+:function:::void:do_dsrl:int rt, int rd, int shift
+{
+ GPR[rd] = (unsigned64) GPR[rt] >> shift;
+}
+
+
+00000000000,5.RT,5.RD,5.SHIFT,111010:SPECIAL:64::DSRL
+"dsrl r<RD>, r<RT>, <SHIFT>"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ do_dsrl (SD_, RT, RD, SHIFT);
+}
+
+
+00000000000,5.RT,5.RD,5.SHIFT,111110:SPECIAL:64::DSRL32
+"dsrl32 r<RD>, r<RT>, <SHIFT>"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ int s = 32 + SHIFT;
+ GPR[RD] = (unsigned64) GPR[RT] >> s;
+}
+
+
+:function:::void:do_dsrlv:int rs, int rt, int rd
+{
+ int s = MASKED64 (GPR[rs], 5, 0);
+ GPR[rd] = (unsigned64) GPR[rt] >> s;
+}
+
+
+
+000000,5.RS,5.RT,5.RD,00000010110:SPECIAL:64::DSRLV
+"dsrl32 r<RD>, r<RT>, r<RS>"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ do_dsrlv (SD_, RS, RT, RD);
+}
+
+
+000000,5.RS,5.RT,5.RD,00000101110:SPECIAL:64::DSUB
+"dsub r<RD>, r<RS>, r<RT>"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
+ {
+ ALU64_BEGIN (GPR[RS]);
+ ALU64_SUB (GPR[RT]);
+ ALU64_END (GPR[RD]);
+ }
+ TRACE_ALU_RESULT (GPR[RD]);
+}
+
+
+:function:::void:do_dsubu:int rs, int rt, int rd
+{
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ GPR[rd] = GPR[rs] - GPR[rt];
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+000000,5.RS,5.RT,5.RD,00000101111:SPECIAL:64::DSUBU
+"dsubu r<RD>, r<RS>, r<RT>"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ do_dsubu (SD_, RS, RT, RD);
+}
+
+
+000010,26.INSTR_INDEX:NORMAL:32::J
+"j <INSTR_INDEX>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ /* NOTE: The region used is that of the delay slot NIA and NOT the
+ current instruction */
+ address_word region = (NIA & MASK (63, 28));
+ DELAY_SLOT (region | (INSTR_INDEX << 2));
+}
+
+
+000011,26.INSTR_INDEX:NORMAL:32::JAL
+"jal <INSTR_INDEX>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ /* NOTE: The region used is that of the delay slot and NOT the
+ current instruction */
+ address_word region = (NIA & MASK (63, 28));
+ GPR[31] = CIA + 8;
+ DELAY_SLOT (region | (INSTR_INDEX << 2));
+}
+
+000000,5.RS,00000,5.RD,00000001001:SPECIAL:32::JALR
+"jalr r<RS>":RD == 31
+"jalr r<RD>, r<RS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ address_word temp = GPR[RS];
+ GPR[RD] = CIA + 8;
+ DELAY_SLOT (temp);
+}
+
+
+000000,5.RS,000000000000000001000:SPECIAL:32::JR
+"jr r<RS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ DELAY_SLOT (GPR[RS]);
+}
+
+
+:function:::unsigned_word:do_load:unsigned access, address_word base, address_word offset
+{
+ address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
+ address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
+ address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
+ unsigned int byte;
+ address_word paddr;
+ int uncached;
+ unsigned64 memval;
+ address_word vaddr;
+
+ vaddr = base + offset;
+ if ((vaddr & access) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, STATE_CPU (SD, 0), cia, read_map, access+1, vaddr, read_transfer, sim_core_unaligned_signal);
+ }
+ AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL);
+ paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
+ LoadMemory (&memval, NULL, uncached, access, paddr, vaddr, isDATA, isREAL);
+ byte = ((vaddr & mask) ^ bigendiancpu);
+ return (memval >> (8 * byte));
+}
+
+
+100000,5.BASE,5.RT,16.OFFSET:NORMAL:32::LB
+"lb r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ GPR[RT] = EXTEND8 (do_load (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (OFFSET)));
+}
+
+
+100100,5.BASE,5.RT,16.OFFSET:NORMAL:32::LBU
+"lbu r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ GPR[RT] = do_load (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (OFFSET));
+}
+
+
+110111,5.BASE,5.RT,16.OFFSET:NORMAL:64::LD
+"ld r<RT>, <OFFSET>(r<BASE>)"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ GPR[RT] = EXTEND64 (do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
+}
+
+
+1101,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDCz
+"ldc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ COP_LD (ZZ, RT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
+}
+
+
+
+
+011010,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDL
+"ldl r<RT>, <OFFSET>(r<BASE>)"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ GPR[RT] = do_load_left (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
+}
+
+
+011011,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDR
+"ldr r<RT>, <OFFSET>(r<BASE>)"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ GPR[RT] = do_load_right (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
+}
+
+
+100001,5.BASE,5.RT,16.OFFSET:NORMAL:32::LH
+"lh r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ GPR[RT] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (OFFSET)));
+}
+
+
+100101,5.BASE,5.RT,16.OFFSET:NORMAL:32::LHU
+"lhu r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ GPR[RT] = do_load (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (OFFSET));
+}
+
+
+110000,5.BASE,5.RT,16.OFFSET:NORMAL:32::LL
+"ll r<RT>, <OFFSET>(r<BASE>)"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ unsigned32 instruction = instruction_0;
+ signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+ int destreg = ((instruction >> 16) & 0x0000001F);
+ signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+ {
+ address_word vaddr = ((unsigned64)op1 + offset);
+ address_word paddr;
+ int uncached;
+ if ((vaddr & 3) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, read_transfer, sim_core_unaligned_signal);
+ }
+ else
+ {
+ if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+ {
+ unsigned64 memval = 0;
+ unsigned64 memval1 = 0;
+ unsigned64 mask = 0x7;
+ unsigned int shift = 2;
+ unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+ unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+ unsigned int byte;
+ paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+ LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL);
+ byte = ((vaddr & mask) ^ (bigend << shift));
+ GPR[destreg] = (SIGNEXTEND(((memval >> (8 * byte)) & 0xFFFFFFFF),32));
+ LLBIT = 1;
+ }
+ }
+ }
+}
+
+
+110100,5.BASE,5.RT,16.OFFSET:NORMAL:64::LLD
+"lld r<RT>, <OFFSET>(r<BASE>)"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ unsigned32 instruction = instruction_0;
+ signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+ int destreg = ((instruction >> 16) & 0x0000001F);
+ signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+ {
+ address_word vaddr = ((unsigned64)op1 + offset);
+ address_word paddr;
+ int uncached;
+ if ((vaddr & 7) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, read_transfer, sim_core_unaligned_signal);
+ }
+ else
+ {
+ if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+ {
+ unsigned64 memval = 0;
+ unsigned64 memval1 = 0;
+ LoadMemory(&memval,&memval1,uncached,AccessLength_DOUBLEWORD,paddr,vaddr,isDATA,isREAL);
+ GPR[destreg] = memval;
+ LLBIT = 1;
+ }
+ }
+ }
+}
+
+
+001111,00000,5.RT,16.IMMEDIATE:NORMAL:32::LUI
+"lui r<RT>, <IMMEDIATE>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ TRACE_ALU_INPUT1 (IMMEDIATE);
+ GPR[RT] = EXTEND32 (IMMEDIATE << 16);
+ TRACE_ALU_RESULT (GPR[RT]);
+}
+
+
+100011,5.BASE,5.RT,16.OFFSET:NORMAL:32::LW
+"lw r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ GPR[RT] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET)));
+}
+
+
+1100,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWCz
+"lwc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ COP_LW (ZZ, RT, do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET)));
+}
+
+
+:function:::unsigned_word:do_load_left:unsigned access, address_word base, address_word offset, unsigned_word rt
+{
+ address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
+ address_word reverseendian = (ReverseEndian ? -1 : 0);
+ address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
+ unsigned int byte;
+ unsigned int word;
+ address_word paddr;
+ int uncached;
+ unsigned64 memval;
+ address_word vaddr;
+ int nr_lhs_bits;
+ int nr_rhs_bits;
+ unsigned_word lhs_mask;
+ unsigned_word temp;
+
+ vaddr = base + offset;
+ AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL);
+ paddr = (paddr ^ (reverseendian & mask));
+ if (BigEndianMem == 0)
+ paddr = paddr & ~access;
+
+ /* compute where within the word/mem we are */
+ byte = ((vaddr ^ bigendiancpu) & access); /* 0..access */
+ word = ((vaddr ^ bigendiancpu) & (mask & ~access)) / (access + 1); /* 0..1 */
+ nr_lhs_bits = 8 * byte + 8;
+ nr_rhs_bits = 8 * access - 8 * byte;
+ /* nr_lhs_bits + nr_rhs_bits == 8 * (accesss + 1) */
+
+ /* fprintf (stderr, "l[wd]l: 0x%08lx%08lx 0x%08lx%08lx %d:%d %d+%d\n",
+ (long) ((unsigned64) vaddr >> 32), (long) vaddr,
+ (long) ((unsigned64) paddr >> 32), (long) paddr,
+ word, byte, nr_lhs_bits, nr_rhs_bits); */
+
+ LoadMemory (&memval, NULL, uncached, byte, paddr, vaddr, isDATA, isREAL);
+ if (word == 0)
+ {
+ /* GPR{31..32-NR_LHS_BITS} = memval{NR_LHS_BITS-1..0} */
+ temp = (memval << nr_rhs_bits);
+ }
+ else
+ {
+ /* GPR{31..32-NR_LHS_BITS = memval{32+NR_LHS_BITS..32} */
+ temp = (memval >> nr_lhs_bits);
+ }
+ lhs_mask = LSMASK (nr_lhs_bits + nr_rhs_bits - 1, nr_rhs_bits);
+ rt = (rt & ~lhs_mask) | (temp & lhs_mask);
+
+ /* fprintf (stderr, "l[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx & 0x%08lx%08lx -> 0x%08lx%08lx\n",
+ (long) ((unsigned64) memval >> 32), (long) memval,
+ (long) ((unsigned64) temp >> 32), (long) temp,
+ (long) ((unsigned64) lhs_mask >> 32), (long) lhs_mask,
+ (long) (rt >> 32), (long) rt); */
+ return rt;
+}
+
+
+100010,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWL
+"lwl r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ GPR[RT] = EXTEND32 (do_load_left (SD_, AccessLength_WORD, GPR[BASE], EXTEND32 (OFFSET), GPR[RT]));
+}
+
+
+:function:::unsigned_word:do_load_right:unsigned access, address_word base, address_word offset, unsigned_word rt
+{
+ address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
+ address_word reverseendian = (ReverseEndian ? -1 : 0);
+ address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
+ unsigned int byte;
+ address_word paddr;
+ int uncached;
+ unsigned64 memval;
+ address_word vaddr;
+
+ vaddr = base + offset;
+ AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL);
+ /* NOTE: SPEC is wrong, has `BigEndianMem == 0' not `BigEndianMem != 0' */
+ paddr = (paddr ^ (reverseendian & mask));
+ if (BigEndianMem != 0)
+ paddr = paddr & ~access;
+ byte = ((vaddr & mask) ^ (bigendiancpu & mask));
+ /* NOTE: SPEC is wrong, had `byte' not `access - byte'. See SW. */
+ LoadMemory (&memval, NULL, uncached, access - (access & byte), paddr, vaddr, isDATA, isREAL);
+ /* printf ("lr: 0x%08lx %d@0x%08lx 0x%08lx\n",
+ (long) paddr, byte, (long) paddr, (long) memval); */
+ {
+ unsigned_word screen = LSMASK (8 * (access - (byte & access) + 1) - 1, 0);
+ rt &= ~screen;
+ rt |= (memval >> (8 * byte)) & screen;
+ }
+ return rt;
+}
+
+
+100110,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWR
+"lwr r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ GPR[RT] = EXTEND32 (do_load_right (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]));
+}
+
+
+100111,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWU
+"lwu r<RT>, <OFFSET>(r<BASE>)"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ GPR[RT] = do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET));
+}
+
+
+:function:::void:do_mfhi:int rd
+{
+ check_mf_hilo (SD_, HIHISTORY, LOHISTORY);
+ TRACE_ALU_INPUT1 (HI);
+ GPR[rd] = HI;
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+000000,0000000000,5.RD,00000,010000:SPECIAL:32::MFHI
+"mfhi r<RD>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_mfhi (SD_, RD);
+}
+
+
+
+:function:::void:do_mflo:int rd
+{
+ check_mf_hilo (SD_, LOHISTORY, HIHISTORY);
+ TRACE_ALU_INPUT1 (LO);
+ GPR[rd] = LO;
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+000000,0000000000,5.RD,00000,010010:SPECIAL:32::MFLO
+"mflo r<RD>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_mflo (SD_, RD);
+}
+
+
+
+000000,5.RS,5.RT,5.RD,00000001011:SPECIAL:32::MOVN
+"movn r<RD>, r<RS>, r<RT>"
+*mipsIV:
+*vr5000:
+{
+ if (GPR[RT] != 0)
+ GPR[RD] = GPR[RS];
+}
+
+
+
+000000,5.RS,5.RT,5.RD,00000001010:SPECIAL:32::MOVZ
+"movz r<RD>, r<RS>, r<RT>"
+*mipsIV:
+*vr5000:
+{
+ if (GPR[RT] == 0)
+ GPR[RD] = GPR[RS];
+}
+
+
+
+000000,5.RS,000000000000000,010001:SPECIAL:32::MTHI
+"mthi r<RS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ check_mt_hilo (SD_, HIHISTORY);
+ HI = GPR[RS];
+}
+
+
+
+000000,5.RS,000000000000000010011:SPECIAL:32::MTLO
+"mtlo r<RS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ check_mt_hilo (SD_, LOHISTORY);
+ LO = GPR[RS];
+}
+
+
+
+:function:::void:do_mult:int rs, int rt, int rd
+{
+ signed64 prod;
+ check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ prod = (((signed64)(signed32) GPR[rs])
+ * ((signed64)(signed32) GPR[rt]));
+ LO = EXTEND32 (VL4_8 (prod));
+ HI = EXTEND32 (VH4_8 (prod));
+ if (rd != 0)
+ GPR[rd] = LO;
+ TRACE_ALU_RESULT2 (HI, LO);
+}
+
+000000,5.RS,5.RT,00000,00000011000:SPECIAL:32::MULT
+"mult r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+{
+ do_mult (SD_, RS, RT, 0);
+}
+
+
+000000,5.RS,5.RT,5.RD,00000011000:SPECIAL:32::MULT
+"mult r<RD>, r<RS>, r<RT>"
+*vr5000:
+*r3900:
+{
+ do_mult (SD_, RS, RT, RD);
+}
+
+
+:function:::void:do_multu:int rs, int rt, int rd
+{
+ unsigned64 prod;
+ check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ prod = (((unsigned64)(unsigned32) GPR[rs])
+ * ((unsigned64)(unsigned32) GPR[rt]));
+ LO = EXTEND32 (VL4_8 (prod));
+ HI = EXTEND32 (VH4_8 (prod));
+ if (rd != 0)
+ GPR[rd] = LO;
+ TRACE_ALU_RESULT2 (HI, LO);
+}
+
+000000,5.RS,5.RT,00000,00000011001:SPECIAL:32::MULTU
+"multu r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+{
+ do_multu (SD_, RS, RT, 0);
+}
+
+000000,5.RS,5.RT,5.RD,00000011001:SPECIAL:32::MULTU
+"multu r<RD>, r<RS>, r<RT>"
+*vr5000:
+*r3900:
+{
+ do_multu (SD_, RS, RT, 0);
+}
+
+
+:function:::void:do_nor:int rs, int rt, int rd
+{
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ GPR[rd] = ~ (GPR[rs] | GPR[rt]);
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+000000,5.RS,5.RT,5.RD,00000,100111:SPECIAL:32::NOR
+"nor r<RD>, r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_nor (SD_, RS, RT, RD);
+}
+
+
+:function:::void:do_or:int rs, int rt, int rd
+{
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ GPR[rd] = (GPR[rs] | GPR[rt]);
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+000000,5.RS,5.RT,5.RD,00000,100101:SPECIAL:32::OR
+"or r<RD>, r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_or (SD_, RS, RT, RD);
+}
+
+
+
+:function:::void:do_ori:int rs, int rt, unsigned immediate
+{
+ TRACE_ALU_INPUT2 (GPR[rs], immediate);
+ GPR[rt] = (GPR[rs] | immediate);
+ TRACE_ALU_RESULT (GPR[rt]);
+}
+
+001101,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ORI
+"ori r<RT>, r<RS>, <IMMEDIATE>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_ori (SD_, RS, RT, IMMEDIATE);
+}
+
+
+110011,5.RS,nnnnn,16.OFFSET:NORMAL:32::PREF
+*mipsIV:
+*vr5000:
+{
+ unsigned32 instruction = instruction_0;
+ signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+ int hint = ((instruction >> 16) & 0x0000001F);
+ signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+ {
+ address_word vaddr = ((unsigned64)op1 + offset);
+ address_word paddr;
+ int uncached;
+ {
+ if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+ Prefetch(uncached,paddr,vaddr,isDATA,hint);
+ }
+ }
+}
+
+:function:::void:do_store:unsigned access, address_word base, address_word offset, unsigned_word word
+{
+ address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
+ address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
+ address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
+ unsigned int byte;
+ address_word paddr;
+ int uncached;
+ unsigned64 memval;
+ address_word vaddr;
+
+ vaddr = base + offset;
+ if ((vaddr & access) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, STATE_CPU(SD, 0), cia, read_map, access+1, vaddr, write_transfer, sim_core_unaligned_signal);
+ }
+ AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL);
+ paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
+ byte = ((vaddr & mask) ^ bigendiancpu);
+ memval = (word << (8 * byte));
+ StoreMemory (uncached, access, memval, 0, paddr, vaddr, isREAL);
+}
+
+
+101000,5.BASE,5.RT,16.OFFSET:NORMAL:32::SB
+"sb r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_store (SD_, AccessLength_BYTE, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
+}
+
+
+111000,5.BASE,5.RT,16.OFFSET:NORMAL:32::SC
+"sc r<RT>, <OFFSET>(r<BASE>)"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ unsigned32 instruction = instruction_0;
+ signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+ signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+ signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+ {
+ address_word vaddr = ((unsigned64)op1 + offset);
+ address_word paddr;
+ int uncached;
+ if ((vaddr & 3) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer, sim_core_unaligned_signal);
+ }
+ else
+ {
+ if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+ {
+ unsigned64 memval = 0;
+ unsigned64 memval1 = 0;
+ unsigned64 mask = 0x7;
+ unsigned int byte;
+ paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));
+ byte = ((vaddr & mask) ^ (BigEndianCPU << 2));
+ memval = ((unsigned64) op2 << (8 * byte));
+ if (LLBIT)
+ {
+ StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
+ }
+ GPR[(instruction >> 16) & 0x0000001F] = LLBIT;
+ }
+ }
+ }
+}
+
+
+111100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SCD
+"scd r<RT>, <OFFSET>(r<BASE>)"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ unsigned32 instruction = instruction_0;
+ signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+ signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+ signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+ {
+ address_word vaddr = ((unsigned64)op1 + offset);
+ address_word paddr;
+ int uncached;
+ if ((vaddr & 7) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, write_transfer, sim_core_unaligned_signal);
+ }
+ else
+ {
+ if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+ {
+ unsigned64 memval = 0;
+ unsigned64 memval1 = 0;
+ memval = op2;
+ if (LLBIT)
+ {
+ StoreMemory(uncached,AccessLength_DOUBLEWORD,memval,memval1,paddr,vaddr,isREAL);
+ }
+ GPR[(instruction >> 16) & 0x0000001F] = LLBIT;
+ }
+ }
+ }
+}
+
+
+111111,5.BASE,5.RT,16.OFFSET:NORMAL:64::SD
+"sd r<RT>, <OFFSET>(r<BASE>)"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
+}
+
+
+1111,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDCz
+"sdc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), COP_SD (ZZ, RT));
+}
+
+
+101100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDL
+"sdl r<RT>, <OFFSET>(r<BASE>)"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ do_store_left (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
+}
+
+
+101101,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDR
+"sdr r<RT>, <OFFSET>(r<BASE>)"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ do_store_right (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
+}
+
+
+101001,5.BASE,5.RT,16.OFFSET:NORMAL:32::SH
+"sh r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_store (SD_, AccessLength_HALFWORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
+}
+
+
+:function:::void:do_sll:int rt, int rd, int shift
+{
+ unsigned32 temp = (GPR[rt] << shift);
+ TRACE_ALU_INPUT2 (GPR[rt], shift);
+ GPR[rd] = EXTEND32 (temp);
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+00000000000,5.RT,5.RD,5.SHIFT,000000:SPECIAL:32::SLL
+"sll r<RD>, r<RT>, <SHIFT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_sll (SD_, RT, RD, SHIFT);
+}
+
+
+:function:::void:do_sllv:int rs, int rt, int rd
+{
+ int s = MASKED (GPR[rs], 4, 0);
+ unsigned32 temp = (GPR[rt] << s);
+ TRACE_ALU_INPUT2 (GPR[rt], s);
+ GPR[rd] = EXTEND32 (temp);
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+000000,5.RS,5.RT,5.RD,00000000100:SPECIAL:32::SLLV
+"sllv r<RD>, r<RT>, r<RS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_sllv (SD_, RS, RT, RD);
+}
+
+
+:function:::void:do_slt:int rs, int rt, int rd
+{
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ GPR[rd] = ((signed_word) GPR[rs] < (signed_word) GPR[rt]);
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+000000,5.RS,5.RT,5.RD,00000101010:SPECIAL:32::SLT
+"slt r<RD>, r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_slt (SD_, RS, RT, RD);
+}
+
+
+:function:::void:do_slti:int rs, int rt, unsigned16 immediate
+{
+ TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
+ GPR[rt] = ((signed_word) GPR[rs] < (signed_word) EXTEND16 (immediate));
+ TRACE_ALU_RESULT (GPR[rt]);
+}
+
+001010,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::SLTI
+"slti r<RT>, r<RS>, <IMMEDIATE>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_slti (SD_, RS, RT, IMMEDIATE);
+}
+
+
+:function:::void:do_sltiu:int rs, int rt, unsigned16 immediate
+{
+ TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
+ GPR[rt] = ((unsigned_word) GPR[rs] < (unsigned_word) EXTEND16 (immediate));
+ TRACE_ALU_RESULT (GPR[rt]);
+}
+
+001011,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::SLTIU
+"sltiu r<RT>, r<RS>, <IMMEDIATE>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_sltiu (SD_, RS, RT, IMMEDIATE);
+}
+
+
+
+:function:::void:do_sltu:int rs, int rt, int rd
+{
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ GPR[rd] = ((unsigned_word) GPR[rs] < (unsigned_word) GPR[rt]);
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+000000,5.RS,5.RT,5.RD,00000101011:SPECIAL:32::SLTU
+"sltu r<RD>, r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_sltu (SD_, RS, RT, RD);
+}
+
+
+:function:::void:do_sra:int rt, int rd, int shift
+{
+ signed32 temp = (signed32) GPR[rt] >> shift;
+ TRACE_ALU_INPUT2 (GPR[rt], shift);
+ GPR[rd] = EXTEND32 (temp);
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+000000,00000,5.RT,5.RD,5.SHIFT,000011:SPECIAL:32::SRA
+"sra r<RD>, r<RT>, <SHIFT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_sra (SD_, RT, RD, SHIFT);
+}
+
+
+
+:function:::void:do_srav:int rs, int rt, int rd
+{
+ int s = MASKED (GPR[rs], 4, 0);
+ signed32 temp = (signed32) GPR[rt] >> s;
+ TRACE_ALU_INPUT2 (GPR[rt], s);
+ GPR[rd] = EXTEND32 (temp);
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+000000,5.RS,5.RT,5.RD,00000000111:SPECIAL:32::SRAV
+"srav r<RD>, r<RT>, r<RS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_srav (SD_, RS, RT, RD);
+}
+
+
+
+:function:::void:do_srl:int rt, int rd, int shift
+{
+ unsigned32 temp = (unsigned32) GPR[rt] >> shift;
+ TRACE_ALU_INPUT2 (GPR[rt], shift);
+ GPR[rd] = EXTEND32 (temp);
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+000000,00000,5.RT,5.RD,5.SHIFT,000010:SPECIAL:32::SRL
+"srl r<RD>, r<RT>, <SHIFT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_srl (SD_, RT, RD, SHIFT);
+}
+
+
+:function:::void:do_srlv:int rs, int rt, int rd
+{
+ int s = MASKED (GPR[rs], 4, 0);
+ unsigned32 temp = (unsigned32) GPR[rt] >> s;
+ TRACE_ALU_INPUT2 (GPR[rt], s);
+ GPR[rd] = EXTEND32 (temp);
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+000000,5.RS,5.RT,5.RD,00000000110:SPECIAL:32::SRLV
+"srlv r<RD>, r<RT>, r<RS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_srlv (SD_, RS, RT, RD);
+}
+
+
+000000,5.RS,5.RT,5.RD,00000100010:SPECIAL:32::SUB
+"sub r<RD>, r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
+ {
+ ALU32_BEGIN (GPR[RS]);
+ ALU32_SUB (GPR[RT]);
+ ALU32_END (GPR[RD]);
+ }
+ TRACE_ALU_RESULT (GPR[RD]);
+}
+
+
+:function:::void:do_subu:int rs, int rt, int rd
+{
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ GPR[rd] = EXTEND32 (GPR[rs] - GPR[rt]);
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+000000,5.RS,5.RT,5.RD,00000100011:SPECIAL:32::SUBU
+"subu r<RD>, r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_subu (SD_, RS, RT, RD);
+}
+
+
+101011,5.BASE,5.RT,16.OFFSET:NORMAL:32::SW
+"sw r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*r3900:
+*vr5000:
+{
+ do_store (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
+}
+
+
+1110,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWCz
+"swc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_store (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), COP_SW (ZZ, RT));
+}
+
+
+
+:function:::void:do_store_left:unsigned access, address_word base, address_word offset, unsigned_word rt
+{
+ address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
+ address_word reverseendian = (ReverseEndian ? -1 : 0);
+ address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
+ unsigned int byte;
+ unsigned int word;
+ address_word paddr;
+ int uncached;
+ unsigned64 memval;
+ address_word vaddr;
+ int nr_lhs_bits;
+ int nr_rhs_bits;
+
+ vaddr = base + offset;
+ AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL);
+ paddr = (paddr ^ (reverseendian & mask));
+ if (BigEndianMem == 0)
+ paddr = paddr & ~access;
+
+ /* compute where within the word/mem we are */
+ byte = ((vaddr ^ bigendiancpu) & access); /* 0..access */
+ word = ((vaddr ^ bigendiancpu) & (mask & ~access)) / (access + 1); /* 0..1 */
+ nr_lhs_bits = 8 * byte + 8;
+ nr_rhs_bits = 8 * access - 8 * byte;
+ /* nr_lhs_bits + nr_rhs_bits == 8 * (accesss + 1) */
+ /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx 0x%08lx%08lx %d:%d %d+%d\n",
+ (long) ((unsigned64) vaddr >> 32), (long) vaddr,
+ (long) ((unsigned64) paddr >> 32), (long) paddr,
+ word, byte, nr_lhs_bits, nr_rhs_bits); */
+
+ if (word == 0)
+ {
+ memval = (rt >> nr_rhs_bits);
+ }
+ else
+ {
+ memval = (rt << nr_lhs_bits);
+ }
+ /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx\n",
+ (long) ((unsigned64) rt >> 32), (long) rt,
+ (long) ((unsigned64) memval >> 32), (long) memval); */
+ StoreMemory (uncached, byte, memval, 0, paddr, vaddr, isREAL);
+}
+
+
+101010,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWL
+"swl r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_store_left (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
+}
+
+
+:function:::void:do_store_right:unsigned access, address_word base, address_word offset, unsigned_word rt
+{
+ address_word mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
+ address_word reverseendian = (ReverseEndian ? -1 : 0);
+ address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
+ unsigned int byte;
+ address_word paddr;
+ int uncached;
+ unsigned64 memval;
+ address_word vaddr;
+
+ vaddr = base + offset;
+ AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL);
+ paddr = (paddr ^ (reverseendian & mask));
+ if (BigEndianMem != 0)
+ paddr &= ~access;
+ byte = ((vaddr & mask) ^ (bigendiancpu & mask));
+ memval = (rt << (byte * 8));
+ StoreMemory (uncached, access - (access & byte), memval, 0, paddr, vaddr, isREAL);
+}
+
+101110,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWR
+"swr r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_store_right (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET), GPR[RT]);
+}
+
+
+000000000000000000000,5.STYPE,001111:SPECIAL:32::SYNC
+"sync":STYPE == 0
+"sync <STYPE>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ SyncOperation (STYPE);
+}
+
+
+000000,20.CODE,001100:SPECIAL:32::SYSCALL
+"syscall <CODE>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ SignalException(SystemCall, instruction_0);
+}
+
+
+000000,5.RS,5.RT,10.CODE,110100:SPECIAL:32::TEQ
+"teq r<RS>, r<RT>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
+ SignalException(Trap, instruction_0);
+}
+
+
+000001,5.RS,01100,16.IMMEDIATE:REGIMM:32::TEQI
+"teqi r<RS>, <IMMEDIATE>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ if ((signed_word) GPR[RS] == (signed_word) EXTEND16 (IMMEDIATE))
+ SignalException(Trap, instruction_0);
+}
+
+
+000000,5.RS,5.RT,10.CODE,110000:SPECIAL:32::TGE
+"tge r<RS>, r<RT>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ if ((signed_word) GPR[RS] >= (signed_word) GPR[RT])
+ SignalException(Trap, instruction_0);
+}
+
+
+000001,5.RS,01000,16.IMMEDIATE:REGIMM:32::TGEI
+"tgei r<RS>, <IMMEDIATE>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ if ((signed_word) GPR[RS] >= (signed_word) EXTEND16 (IMMEDIATE))
+ SignalException(Trap, instruction_0);
+}
+
+
+000001,5.RS,01001,16.IMMEDIATE:REGIMM:32::TGEIU
+"tgeiu r<RS>, <IMMEDIATE>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ if ((unsigned_word) GPR[RS] >= (unsigned_word) EXTEND16 (IMMEDIATE))
+ SignalException(Trap, instruction_0);
+}
+
+
+000000,5.RS,5.RT,10.CODE,110001:SPECIAL:32::TGEU
+"tgeu r<RS>, r<RT>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ if ((unsigned_word) GPR[RS] >= (unsigned_word) GPR[RT])
+ SignalException(Trap, instruction_0);
+}
+
+
+000000,5.RS,5.RT,10.CODE,110010:SPECIAL:32::TLT
+"tlt r<RS>, r<RT>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ if ((signed_word) GPR[RS] < (signed_word) GPR[RT])
+ SignalException(Trap, instruction_0);
+}
+
+
+000001,5.RS,01010,16.IMMEDIATE:REGIMM:32::TLTI
+"tlti r<RS>, <IMMEDIATE>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ if ((signed_word) GPR[RS] < (signed_word) EXTEND16 (IMMEDIATE))
+ SignalException(Trap, instruction_0);
+}
+
+
+000001,5.RS,01011,16.IMMEDIATE:REGIMM:32::TLTIU
+"tltiu r<RS>, <IMMEDIATE>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ if ((unsigned_word) GPR[RS] < (unsigned_word) EXTEND16 (IMMEDIATE))
+ SignalException(Trap, instruction_0);
+}
+
+
+000000,5.RS,5.RT,10.CODE,110011:SPECIAL:32::TLTU
+"tltu r<RS>, r<RT>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ if ((unsigned_word) GPR[RS] < (unsigned_word) GPR[RT])
+ SignalException(Trap, instruction_0);
+}
+
+
+000000,5.RS,5.RT,10.CODE,110110:SPECIAL:32::TNE
+"tne r<RS>, r<RT>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
+ SignalException(Trap, instruction_0);
+}
+
+
+000001,5.RS,01110,16.IMMEDIATE:REGIMM:32::TNEI
+"tne r<RS>, <IMMEDIATE>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ if ((signed_word) GPR[RS] != (signed_word) EXTEND16 (IMMEDIATE))
+ SignalException(Trap, instruction_0);
+}
+
+
+:function:::void:do_xor:int rs, int rt, int rd
+{
+ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+ GPR[rd] = GPR[rs] ^ GPR[rt];
+ TRACE_ALU_RESULT (GPR[rd]);
+}
+
+000000,5.RS,5.RT,5.RD,00000100110:SPECIAL:32::XOR
+"xor r<RD>, r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_xor (SD_, RS, RT, RD);
+}
+
+
+:function:::void:do_xori:int rs, int rt, unsigned16 immediate
+{
+ TRACE_ALU_INPUT2 (GPR[rs], immediate);
+ GPR[rt] = GPR[rs] ^ immediate;
+ TRACE_ALU_RESULT (GPR[rt]);
+}
+
+001110,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::XORI
+"xori r<RT>, r<RS>, <IMMEDIATE>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_xori (SD_, RS, RT, IMMEDIATE);
+}
+
+
+//
+// MIPS Architecture:
+//
+// FPU Instruction Set (COP1 & COP1X)
+//
+
+
+:%s::::FMT:int fmt
+{
+ switch (fmt)
+ {
+ case fmt_single: return "s";
+ case fmt_double: return "d";
+ case fmt_word: return "w";
+ case fmt_long: return "l";
+ default: return "?";
+ }
+}
+
+:%s::::X:int x
+{
+ switch (x)
+ {
+ case 0: return "f";
+ case 1: return "t";
+ default: return "?";
+ }
+}
+
+:%s::::TF:int tf
+{
+ if (tf)
+ return "t";
+ else
+ return "f";
+}
+
+:%s::::ND:int nd
+{
+ if (nd)
+ return "l";
+ else
+ return "";
+}
+
+:%s::::COND:int cond
+{
+ switch (cond)
+ {
+ case 00: return "f";
+ case 01: return "un";
+ case 02: return "eq";
+ case 03: return "ueq";
+ case 04: return "olt";
+ case 05: return "ult";
+ case 06: return "ole";
+ case 07: return "ule";
+ case 010: return "sf";
+ case 011: return "ngle";
+ case 012: return "seq";
+ case 013: return "ngl";
+ case 014: return "lt";
+ case 015: return "nge";
+ case 016: return "le";
+ case 017: return "ngt";
+ default: return "?";
+ }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,000101:COP1:32,f::ABS.fmt
+"abs.%s<FMT> f<FD>, f<FS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ if ((format != fmt_single) && (format != fmt_double))
+ SignalException(ReservedInstruction,instruction);
+ else
+ StoreFPR(destreg,format,AbsoluteValue(ValueFPR(fs,format),format));
+ }
+}
+
+
+
+010001,10,3.FMT,5.FT,5.FS,5.FD,000000:COP1:32,f::ADD.fmt
+"add.%s<FMT> f<FD>, f<FS>, f<FT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int ft = ((instruction >> 16) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ if ((format != fmt_single) && (format != fmt_double))
+ SignalException(ReservedInstruction, instruction);
+ else
+ StoreFPR(destreg,format,Add(ValueFPR(fs,format),ValueFPR(ft,format),format));
+ }
+}
+
+
+
+// BC1F
+// BC1FL
+// BC1T
+// BC1TL
+
+010001,01000,3.0,1.ND,1.TF,16.OFFSET:COP1S:32,f::BC1a
+"bc1%s<TF>%s<ND> <OFFSET>"
+*mipsI,mipsII,mipsIII:
+{
+ check_branch_bug ();
+ TRACE_BRANCH_INPUT (PREVCOC1());
+ if (PREVCOC1() == TF)
+ {
+ address_word dest = NIA + (EXTEND16 (OFFSET) << 2);
+ TRACE_BRANCH_RESULT (dest);
+ mark_branch_bug (dest);
+ DELAY_SLOT (dest);
+ }
+ else if (ND)
+ {
+ TRACE_BRANCH_RESULT (0);
+ NULLIFY_NEXT_INSTRUCTION ();
+ }
+ else
+ {
+ TRACE_BRANCH_RESULT (NIA);
+ }
+}
+
+010001,01000,3.CC,1.ND,1.TF,16.OFFSET:COP1S:32,f::BC1b
+"bc1%s<TF>%s<ND> <OFFSET>":CC == 0
+"bc1%s<TF>%s<ND> <CC>, <OFFSET>"
+*mipsIV:
+*vr5000:
+#*vr4100:
+*r3900:
+{
+ check_branch_bug ();
+ if (GETFCC(CC) == TF)
+ {
+ address_word dest = NIA + (EXTEND16 (OFFSET) << 2);
+ mark_branch_bug (dest);
+ DELAY_SLOT (dest);
+ }
+ else if (ND)
+ {
+ NULLIFY_NEXT_INSTRUCTION ();
+ }
+}
+
+
+
+
+
+
+// C.EQ.S
+// C.EQ.D
+// ...
+
+:function:::void:do_c_cond_fmt:int fmt, int ft, int fs, int cc, int cond, instruction_word insn
+{
+ if ((fmt != fmt_single) && (fmt != fmt_double))
+ SignalException (ReservedInstruction, insn);
+ else
+ {
+ int less;
+ int equal;
+ int unordered;
+ int condition;
+ unsigned64 ofs = ValueFPR (fs, fmt);
+ unsigned64 oft = ValueFPR (ft, fmt);
+ if (NaN (ofs, fmt) || NaN (oft, fmt))
+ {
+ if (FCSR & FP_ENABLE (IO))
+ {
+ FCSR |= FP_CAUSE (IO);
+ SignalExceptionFPE ();
+ }
+ less = 0;
+ equal = 0;
+ unordered = 1;
+ }
+ else
+ {
+ less = Less (ofs, oft, fmt);
+ equal = Equal (ofs, oft, fmt);
+ unordered = 0;
+ }
+ condition = (((cond & (1 << 2)) && less)
+ || ((cond & (1 << 1)) && equal)
+ || ((cond & (1 << 0)) && unordered));
+ SETFCC (cc, condition);
+ }
+}
+
+010001,10,3.FMT,5.FT,5.FS,3.0,00,11,4.COND:COP1:32::C.cond.fmta
+"c.%s<COND>.%s<FMT> f<FS>, f<FT>"
+*mipsI,mipsII,mipsIII:
+{
+ do_c_cond_fmt (SD_, FMT, FT, FS, 0, COND, instruction_0);
+}
+
+010001,10,3.FMT,5.FT,5.FS,3.CC,00,11,4.COND:COP1:32::C.cond.fmtb
+"c.%s<COND>.%s<FMT> f<FS>, f<FT>":CC == 0
+"c.%s<COND>.%s<FMT> <CC>, f<FS>, f<FT>"
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_c_cond_fmt (SD_, FMT, FT, FS, CC, COND, instruction_0);
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,001010:COP1:64::CEIL.L.fmt
+"ceil.l.%s<FMT> f<FD>, f<FS>"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ if ((format != fmt_single) && (format != fmt_double))
+ SignalException(ReservedInstruction,instruction);
+ else
+ StoreFPR(destreg,fmt_long,Convert(FP_RM_TOPINF,ValueFPR(fs,format),format,fmt_long));
+ }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,001110:COP1:32::CEIL.W
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ if ((format != fmt_single) && (format != fmt_double))
+ SignalException(ReservedInstruction,instruction);
+ else
+ StoreFPR(destreg,fmt_word,Convert(FP_RM_TOPINF,ValueFPR(fs,format),format,fmt_word));
+ }
+}
+
+
+// CFC1
+// CTC1
+010001,00,X,10,5.RT,5.FS,00000000000:COP1Sa:32::CxC1
+"c%s<X>c1 r<RT>, f<FS>"
+*mipsI:
+*mipsII:
+*mipsIII:
+{
+ if (X)
+ {
+ if (FS == 0)
+ PENDING_FILL((FS + FCR0IDX),VL4_8(GPR[RT]));
+ else if (FS == 31)
+ PENDING_FILL((FS + FCR31IDX),VL4_8(GPR[RT]));
+ /* else NOP */
+ PENDING_FILL(COCIDX,0); /* special case */
+ }
+ else
+ { /* control from */
+ if (FS == 0)
+ PENDING_FILL(RT,SIGNEXTEND(FCR0,32));
+ else if (FS == 31)
+ PENDING_FILL(RT,SIGNEXTEND(FCR31,32));
+ /* else NOP */
+ }
+}
+010001,00,X,10,5.RT,5.FS,00000000000:COP1Sb:32::CxC1
+"c%s<X>c1 r<RT>, f<FS>"
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ if (X)
+ {
+ /* control to */
+ TRACE_ALU_INPUT1 (GPR[RT]);
+ if (FS == 0)
+ {
+ FCR0 = VL4_8(GPR[RT]);
+ TRACE_ALU_RESULT (FCR0);
+ }
+ else if (FS == 31)
+ {
+ FCR31 = VL4_8(GPR[RT]);
+ SETFCC(0,((FCR31 & (1 << 23)) ? 1 : 0));
+ TRACE_ALU_RESULT (FCR31);
+ }
+ else
+ {
+ TRACE_ALU_RESULT0 ();
+ }
+ /* else NOP */
+ }
+ else
+ { /* control from */
+ if (FS == 0)
+ {
+ TRACE_ALU_INPUT1 (FCR0);
+ GPR[RT] = SIGNEXTEND (FCR0, 32);
+ }
+ else if (FS == 31)
+ {
+ TRACE_ALU_INPUT1 (FCR31);
+ GPR[RT] = SIGNEXTEND (FCR31, 32);
+ }
+ TRACE_ALU_RESULT (GPR[RT]);
+ /* else NOP */
+ }
+}
+
+
+//
+// FIXME: Does not correctly differentiate between mips*
+//
+010001,10,3.FMT,00000,5.FS,5.FD,100001:COP1:32::CVT.D.fmt
+"cvt.d.%s<FMT> f<FD>, f<FS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ if ((format == fmt_double) | 0)
+ SignalException(ReservedInstruction,instruction);
+ else
+ StoreFPR(destreg,fmt_double,Convert(GETRM(),ValueFPR(fs,format),format,fmt_double));
+ }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,100101:COP1:64::CVT.L.fmt
+"cvt.l.%s<FMT> f<FD>, f<FS>"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ if ((format == fmt_long) | ((format == fmt_long) || (format == fmt_word)))
+ SignalException(ReservedInstruction,instruction);
+ else
+ StoreFPR(destreg,fmt_long,Convert(GETRM(),ValueFPR(fs,format),format,fmt_long));
+ }
+}
+
+
+//
+// FIXME: Does not correctly differentiate between mips*
+//
+010001,10,3.FMT,00000,5.FS,5.FD,100000:COP1:32::CVT.S.fmt
+"cvt.s.%s<FMT> f<FD>, f<FS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ if ((format == fmt_single) | 0)
+ SignalException(ReservedInstruction,instruction);
+ else
+ StoreFPR(destreg,fmt_single,Convert(GETRM(),ValueFPR(fs,format),format,fmt_single));
+ }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,100100:COP1:32::CVT.W.fmt
+"cvt.w.%s<FMT> f<FD>, f<FS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ if ((format == fmt_word) | ((format == fmt_long) || (format == fmt_word)))
+ SignalException(ReservedInstruction,instruction);
+ else
+ StoreFPR(destreg,fmt_word,Convert(GETRM(),ValueFPR(fs,format),format,fmt_word));
+ }
+}
+
+
+010001,10,3.FMT,5.FT,5.FS,5.FD,000011:COP1:32::DIV.fmt
+"div.%s<FMT> f<FD>, f<FS>, f<FT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int ft = ((instruction >> 16) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ if ((format != fmt_single) && (format != fmt_double))
+ SignalException(ReservedInstruction,instruction);
+ else
+ StoreFPR(destreg,format,Divide(ValueFPR(fs,format),ValueFPR(ft,format),format));
+ }
+}
+
+
+// DMFC1
+// DMTC1
+010001,00,X,01,5.RT,5.FS,00000000000:COP1Sa:64::DMxC1
+"dm%s<X>c1 r<RT>, f<FS>"
+*mipsIII:
+{
+ if (X)
+ {
+ if (SizeFGR() == 64)
+ PENDING_FILL((FS + FGRIDX),GPR[RT]);
+ else if ((FS & 0x1) == 0)
+ {
+ PENDING_FILL(((FS + 1) + FGRIDX),VH4_8(GPR[RT]));
+ PENDING_FILL((FS + FGRIDX),VL4_8(GPR[RT]));
+ }
+ }
+ else
+ {
+ if (SizeFGR() == 64)
+ PENDING_FILL(RT,FGR[FS]);
+ else if ((FS & 0x1) == 0)
+ PENDING_FILL(RT,(SET64HI(FGR[FS+1]) | FGR[FS]));
+ else
+ PENDING_FILL(RT,SET64HI(0xDEADC0DE) | 0xBAD0BAD0);
+ }
+}
+010001,00,X,01,5.RT,5.FS,00000000000:COP1Sb:64::DMxC1
+"dm%s<X>c1 r<RT>, f<FS>"
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ if (X)
+ {
+ if (SizeFGR() == 64)
+ StoreFPR (FS, fmt_uninterpreted_64, GPR[RT]);
+ else if ((FS & 0x1) == 0)
+ StoreFPR (FS, fmt_uninterpreted_64, SET64HI (FGR[FS+1]) | FGR[FS]);
+ }
+ else
+ {
+ if (SizeFGR() == 64)
+ GPR[RT] = FGR[FS];
+ else if ((FS & 0x1) == 0)
+ GPR[RT] = SET64HI (FGR[FS+1]) | FGR[FS];
+ else
+ GPR[RT] = SET64HI (0xDEADC0DE) | 0xBAD0BAD0;
+ }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,001011:COP1:64::FLOOR.L.fmt
+"floor.l.%s<FMT> f<FD>, f<FS>"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ if ((format != fmt_single) && (format != fmt_double))
+ SignalException(ReservedInstruction,instruction);
+ else
+ StoreFPR(destreg,fmt_long,Convert(FP_RM_TOMINF,ValueFPR(fs,format),format,fmt_long));
+ }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,001111:COP1:32::FLOOR.W.fmt
+"floor.w.%s<FMT> f<FD>, f<FS>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ if ((format != fmt_single) && (format != fmt_double))
+ SignalException(ReservedInstruction,instruction);
+ else
+ StoreFPR(destreg,fmt_word,Convert(FP_RM_TOMINF,ValueFPR(fs,format),format,fmt_word));
+ }
+}
+
+
+110101,5.BASE,5.FT,16.OFFSET:COP1:64::LDC1
+"ldc1 f<FT>, <OFFSET>(r<BASE>)"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ COP_LD (1, FT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET)));
+}
+
+
+010011,5.BASE,5.INDEX,5.0,5.FD,000001:COP1X:64::LDXC1
+"ldxc1 f<FD>, r<INDEX>(r<BASE>)"
+*mipsIV:
+*vr5000:
+{
+ COP_LD (1, FD, do_load (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX]));
+}
+
+
+
+110001,5.BASE,5.FT,16.OFFSET:COP1:32::LWC1
+"lwc1 f<FT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ COP_LW (1, FT, do_load (SD_, AccessLength_WORD, GPR[BASE], EXTEND16 (OFFSET)));
+}
+
+
+010011,5.BASE,5.INDEX,5.0,5.FD,000000:COP1X:32::LWXC1
+"lwxc1 f<FD>, r<INDEX>(r<BASE>)"
+*mipsIV:
+*vr5000:
+{
+ COP_LW (1, FD, do_load (SD_, AccessLength_WORD, GPR[BASE], GPR[INDEX]));
+}
+
+
+
+//
+// FIXME: Not correct for mips*
+//
+010011,5.FR,5.FT,5.FS,5.FD,100,001:COP1X:32,f::MADD.D
+"madd.d f<FD>, f<FR>, f<FS>, f<FT>"
+*mipsIV:
+*vr5000:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int ft = ((instruction >> 16) & 0x0000001F);
+ int fr = ((instruction >> 21) & 0x0000001F);
+ {
+ StoreFPR(destreg,fmt_double,Add(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double));
+ }
+}
+
+
+010011,5.FR,5.FT,5.FS,5.FD,100,000:COP1X:32,f::MADD.S
+"madd.s f<FD>, f<FR>, f<FS>, f<FT>"
+*mipsIV:
+*vr5000:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int ft = ((instruction >> 16) & 0x0000001F);
+ int fr = ((instruction >> 21) & 0x0000001F);
+ {
+ StoreFPR(destreg,fmt_single,Add(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single));
+ }
+}
+
+
+// MFC1
+// MTC1
+010001,00,X,00,5.RT,5.FS,00000000000:COP1Sa:32::MxC1
+"m%s<X>c1 r<RT>, f<FS>"
+*mipsI:
+*mipsII:
+*mipsIII:
+{
+ if (X)
+ { /*MTC1*/
+ if (SizeFGR() == 64)
+ PENDING_FILL ((FS + FGRIDX), (SET64HI(0xDEADC0DE) | VL4_8(GPR[RT])));
+ else
+ PENDING_FILL ((FS + FGRIDX), VL4_8(GPR[RT]));
+ }
+ else /*MFC1*/
+ PENDING_FILL (RT, SIGNEXTEND(FGR[FS],32));
+}
+010001,00,X,00,5.RT,5.FS,00000000000:COP1Sb:32::MxC1
+"m%s<X>c1 r<RT>, f<FS>"
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ int fs = FS;
+ if (X)
+ /*MTC1*/
+ StoreFPR (FS, fmt_uninterpreted_32, VL4_8 (GPR[RT]));
+ else /*MFC1*/
+ GPR[RT] = SIGNEXTEND(FGR[FS],32);
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,000110:COP1:32::MOV.fmt
+"mov.%s<FMT> f<FD>, f<FS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ StoreFPR(destreg,format,ValueFPR(fs,format));
+ }
+}
+
+
+// MOVF
+000000,5.RS,3.CC,0,1.TF,5.RD,00000000001:SPECIAL:32::MOVtf
+"mov%s<TF> r<RD>, r<RS>, <CC>"
+*mipsIV:
+*vr5000:
+{
+ if (GETFCC(CC) == TF)
+ GPR[RD] = GPR[RS];
+}
+
+
+// MOVF.fmt
+010001,10,3.FMT,3.CC,0,1.TF,5.FS,5.FD,010001:COP1:32::MOVtf.fmt
+"mov%s<TF>.%s<FMT> f<FD>, f<FS>, <CC>"
+*mipsIV:
+*vr5000:
+{
+ unsigned32 instruction = instruction_0;
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ if (GETFCC(CC) == TF)
+ StoreFPR (FD, format, ValueFPR (FS, format));
+ else
+ StoreFPR (FD, format, ValueFPR (FD, format));
+ }
+}
+
+
+010001,10,3.FMT,5.RT,5.FS,5.FD,010011:COP1:32::MOVN.fmt
+*mipsIV:
+*vr5000:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ StoreFPR(destreg,format,ValueFPR(fs,format));
+ }
+}
+
+
+// MOVT see MOVtf
+
+
+// MOVT.fmt see MOVtf.fmt
+
+
+
+010001,10,3.FMT,5.RT,5.FS,5.FD,010010:COP1:32::MOVZ.fmt
+"movz.%s<FMT> f<FD>, f<FS>, r<RT>"
+*mipsIV:
+*vr5000:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ StoreFPR(destreg,format,ValueFPR(fs,format));
+ }
+}
+
+
+// MSUB.fmt
+010011,5.FR,5.FT,5.FS,5.FD,101,001:COP1X:32::MSUB.D
+"msub.d f<FD>, f<FR>, f<FS>, f<FT>"
+*mipsIV:
+*vr5000:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int ft = ((instruction >> 16) & 0x0000001F);
+ int fr = ((instruction >> 21) & 0x0000001F);
+ {
+ StoreFPR(destreg,fmt_double,Sub(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double));
+ }
+}
+
+
+// MSUB.fmt
+010011,5.FR,5.FT,5.FS,5.FD,101000:COP1X:32::MSUB.S
+"msub.s f<FD>, f<FR>, f<FS>, f<FT>"
+*mipsIV:
+*vr5000:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int ft = ((instruction >> 16) & 0x0000001F);
+ int fr = ((instruction >> 21) & 0x0000001F);
+ {
+ StoreFPR(destreg,fmt_single,Sub(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single));
+ }
+}
+
+
+// MTC1 see MxC1
+
+
+010001,10,3.FMT,5.FT,5.FS,5.FD,000010:COP1:32::MUL.fmt
+"mul.%s<FMT> f<FD>, f<FS>, f<FT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int ft = ((instruction >> 16) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ if ((format != fmt_single) && (format != fmt_double))
+ SignalException(ReservedInstruction,instruction);
+ else
+ StoreFPR(destreg,format,Multiply(ValueFPR(fs,format),ValueFPR(ft,format),format));
+ }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,000111:COP1:32::NEG.fmt
+"neg.%s<FMT> f<FD>, f<FS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ if ((format != fmt_single) && (format != fmt_double))
+ SignalException(ReservedInstruction,instruction);
+ else
+ StoreFPR(destreg,format,Negate(ValueFPR(fs,format),format));
+ }
+}
+
+
+// NMADD.fmt
+010011,5.FR,5.FT,5.FS,5.FD,110001:COP1X:32::NMADD.D
+"nmadd.d f<FD>, f<FR>, f<FS>, f<FT>"
+*mipsIV:
+*vr5000:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int ft = ((instruction >> 16) & 0x0000001F);
+ int fr = ((instruction >> 21) & 0x0000001F);
+ {
+ StoreFPR(destreg,fmt_double,Negate(Add(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double),fmt_double));
+ }
+}
+
+
+// NMADD.fmt
+010011,5.FR,5.FT,5.FS,5.FD,110000:COP1X:32::NMADD.S
+"nmadd.s f<FD>, f<FR>, f<FS>, f<FT>"
+*mipsIV:
+*vr5000:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int ft = ((instruction >> 16) & 0x0000001F);
+ int fr = ((instruction >> 21) & 0x0000001F);
+ {
+ StoreFPR(destreg,fmt_single,Negate(Add(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single),fmt_single));
+ }
+}
+
+
+// NMSUB.fmt
+010011,5.FR,5.FT,5.FS,5.FD,111001:COP1X:32::NMSUB.D
+"nmsub.d f<FD>, f<FR>, f<FS>, f<FT>"
+*mipsIV:
+*vr5000:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int ft = ((instruction >> 16) & 0x0000001F);
+ int fr = ((instruction >> 21) & 0x0000001F);
+ {
+ StoreFPR(destreg,fmt_double,Negate(Sub(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double),fmt_double));
+ }
+}
+
+
+// NMSUB.fmt
+010011,5.FR,5.FT,5.FS,5.FD,111000:COP1X:32::NMSUB.S
+"nmsub.s f<FD>, f<FR>, f<FS>, f<FT>"
+*mipsIV:
+*vr5000:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int ft = ((instruction >> 16) & 0x0000001F);
+ int fr = ((instruction >> 21) & 0x0000001F);
+ {
+ StoreFPR(destreg,fmt_single,Negate(Sub(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single),fmt_single));
+ }
+}
+
+
+010011,5.BASE,5.INDEX,5.HINT,00000001111:COP1X:32::PREFX
+"prefx <HINT>, r<INDEX>(r<BASE>)"
+*mipsIV:
+*vr5000:
+{
+ unsigned32 instruction = instruction_0;
+ int fs = ((instruction >> 11) & 0x0000001F);
+ signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+ signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+ {
+ address_word vaddr = ((unsigned64)op1 + (unsigned64)op2);
+ address_word paddr;
+ int uncached;
+ if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+ Prefetch(uncached,paddr,vaddr,isDATA,fs);
+ }
+}
+
+010001,10,3.FMT,00000,5.FS,5.FD,010101:COP1:32::RECIP.fmt
+*mipsIV:
+"recip.%s<FMT> f<FD>, f<FS>"
+*vr5000:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ if ((format != fmt_single) && (format != fmt_double))
+ SignalException(ReservedInstruction,instruction);
+ else
+ StoreFPR(destreg,format,Recip(ValueFPR(fs,format),format));
+ }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,001000:COP1:64::ROUND.L.fmt
+"round.l.%s<FMT> f<FD>, f<FS>"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ if ((format != fmt_single) && (format != fmt_double))
+ SignalException(ReservedInstruction,instruction);
+ else
+ StoreFPR(destreg,fmt_long,Convert(FP_RM_NEAREST,ValueFPR(fs,format),format,fmt_long));
+ }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,001100:COP1:32::ROUND.W.fmt
+"round.w.%s<FMT> f<FD>, f<FS>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ if ((format != fmt_single) && (format != fmt_double))
+ SignalException(ReservedInstruction,instruction);
+ else
+ StoreFPR(destreg,fmt_word,Convert(FP_RM_NEAREST,ValueFPR(fs,format),format,fmt_word));
+ }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,010110:COP1:32::RSQRT.fmt
+*mipsIV:
+"rsqrt.%s<FMT> f<FD>, f<FS>"
+*vr5000:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ if ((format != fmt_single) && (format != fmt_double))
+ SignalException(ReservedInstruction,instruction);
+ else
+ StoreFPR(destreg,format,Recip(SquareRoot(ValueFPR(fs,format),format),format));
+ }
+}
+
+
+111101,5.BASE,5.FT,16.OFFSET:COP1:64::SDC1
+"sdc1 f<FT>, <OFFSET>(r<BASE>)"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], EXTEND16 (OFFSET), COP_SD (1, FT));
+}
+
+
+010011,5.BASE,5.INDEX,5.FS,00000001001:COP1X:64::SDXC1
+"ldxc1 f<FS>, r<INDEX>(r<BASE>)"
+*mipsIV:
+*vr5000:
+{
+ do_store (SD_, AccessLength_DOUBLEWORD, GPR[BASE], GPR[INDEX], COP_SD (1, FS));
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,000100:COP1:32::SQRT.fmt
+"sqrt.%s<FMT> f<FD>, f<FS>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ if ((format != fmt_single) && (format != fmt_double))
+ SignalException(ReservedInstruction,instruction);
+ else
+ StoreFPR(destreg,format,(SquareRoot(ValueFPR(fs,format),format)));
+ }
+}
+
+
+010001,10,3.FMT,5.FT,5.FS,5.FD,000001:COP1:32::SUB.fmt
+"sub.%s<FMT> f<FD>, f<FS>, f<FT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int ft = ((instruction >> 16) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ if ((format != fmt_single) && (format != fmt_double))
+ SignalException(ReservedInstruction,instruction);
+ else
+ StoreFPR(destreg,format,Sub(ValueFPR(fs,format),ValueFPR(ft,format),format));
+ }
+}
+
+
+
+111001,5.BASE,5.FT,16.OFFSET:COP1:32::SWC1
+"swc1 f<FT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ unsigned32 instruction = instruction_0;
+ signed_word offset = EXTEND16 (OFFSET);
+ int destreg UNUSED = ((instruction >> 16) & 0x0000001F);
+ signed_word op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)];
+ {
+ address_word vaddr = ((uword64)op1 + offset);
+ address_word paddr;
+ int uncached;
+ if ((vaddr & 3) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, CPU, cia, read_map, AccessLength_WORD+1, vaddr, write_transfer, sim_core_unaligned_signal);
+ }
+ else
+ {
+ if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+ {
+ uword64 memval = 0;
+ uword64 memval1 = 0;
+ uword64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
+ address_word reverseendian = (ReverseEndian ?(mask ^ AccessLength_WORD): 0);
+ address_word bigendiancpu = (BigEndianCPU ?(mask ^ AccessLength_WORD): 0);
+ unsigned int byte;
+ paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
+ byte = ((vaddr & mask) ^ bigendiancpu);
+ memval = (((uword64)COP_SW(((instruction >> 26) & 0x3),destreg)) << (8 * byte));
+ StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
+ }
+ }
+ }
+}
+
+
+010011,5.BASE,5.INDEX,5.FS,00000,001000:COP1X:32::SWXC1
+"swxc1 f<FS>, r<INDEX>(r<BASE>)"
+*mipsIV:
+*vr5000:
+{
+ unsigned32 instruction = instruction_0;
+ int fs = ((instruction >> 11) & 0x0000001F);
+ signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+ signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+ {
+ address_word vaddr = ((unsigned64)op1 + op2);
+ address_word paddr;
+ int uncached;
+ if ((vaddr & 3) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer, sim_core_unaligned_signal);
+ }
+ else
+ {
+ if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+ {
+ unsigned64 memval = 0;
+ unsigned64 memval1 = 0;
+ unsigned64 mask = 0x7;
+ unsigned int byte;
+ paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));
+ byte = ((vaddr & mask) ^ (BigEndianCPU << 2));
+ memval = (((unsigned64)COP_SW(1,fs)) << (8 * byte));
+ {
+ StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
+ }
+ }
+ }
+ }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,001001:COP1:64::TRUNC.L.fmt
+"trunc.l.%s<FMT> f<FD>, f<FS>"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ if ((format != fmt_single) && (format != fmt_double))
+ SignalException(ReservedInstruction,instruction);
+ else
+ StoreFPR(destreg,fmt_long,Convert(FP_RM_TOZERO,ValueFPR(fs,format),format,fmt_long));
+ }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,001101:COP1:32::TRUNC.W
+"trunc.w.%s<FMT> f<FD>, f<FS>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ unsigned32 instruction = instruction_0;
+ int destreg = ((instruction >> 6) & 0x0000001F);
+ int fs = ((instruction >> 11) & 0x0000001F);
+ int format = ((instruction >> 21) & 0x00000007);
+ {
+ if ((format != fmt_single) && (format != fmt_double))
+ SignalException(ReservedInstruction,instruction);
+ else
+ StoreFPR(destreg,fmt_word,Convert(FP_RM_TOZERO,ValueFPR(fs,format),format,fmt_word));
+ }
+}
+
+
+//
+// MIPS Architecture:
+//
+// System Control Instruction Set (COP0)
+//
+
+
+010000,01000,00000,16.OFFSET:COP0:32::BC0F
+"bc0f <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+
+
+010000,01000,00010,16.OFFSET:COP0:32::BC0FL
+"bc0fl <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+
+
+010000,01000,00001,16.OFFSET:COP0:32::BC0T
+"bc0t <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+
+
+010000,01000,00011,16.OFFSET:COP0:32::BC0TL
+"bc0tl <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+
+
+101111,5.BASE,5.OP,16.OFFSET:NORMAL:32::CACHE
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+*r3900:
+{
+ unsigned32 instruction = instruction_0;
+ signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+ int hint = ((instruction >> 16) & 0x0000001F);
+ signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+ {
+ address_word vaddr = (op1 + offset);
+ address_word paddr;
+ int uncached;
+ if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+ CacheOp(hint,vaddr,paddr,instruction);
+ }
+}
+
+
+010000,10000,000000000000000,111001:COP0:32::DI
+"di"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+
+
+010000,10000,000000000000000,111000:COP0:32::EI
+"ei"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+
+
+010000,10000,000000000000000,011000:COP0:32::ERET
+"eret"
+*mipsIII:
+*mipsIV:
+*vr4100:
+*vr5000:
+{
+ if (SR & status_ERL)
+ {
+ /* Oops, not yet available */
+ sim_io_printf (SD, "Warning: ERET when SR[ERL] set not supported");
+ NIA = EPC;
+ SR &= ~status_ERL;
+ }
+ else
+ {
+ NIA = EPC;
+ SR &= ~status_EXL;
+ }
+}
+
+
+010000,00000,5.RT,5.RD,00000,6.REGX:COP0:32::MFC0
+"mfc0 r<RT>, r<RD> # <REGX>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*r3900:
+*vr4100:
+*vr5000:
+{
+ TRACE_ALU_INPUT0 ();
+ DecodeCoproc (instruction_0);
+ TRACE_ALU_RESULT (GPR[RT]);
+}
+
+010000,00100,5.RT,5.RD,00000,6.REGX:COP0:32::MTC0
+"mtc0 r<RT>, r<RD> # <REGX>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*r3900:
+*vr4100:
+*vr5000:
+{
+ DecodeCoproc (instruction_0);
+}
+
+
+010000,10000,000000000000000,010000:COP0:32::RFE
+"rfe"
+*mipsI,mipsII,mipsIII,mipsIV:
+*r3900:
+*vr4100:
+*vr5000:
+{
+ DecodeCoproc (instruction_0);
+}
+
+
+0100,ZZ!0!1!3,5.COP_FUN0!8,5.COP_FUN1,16.COP_FUN2:NORMAL:32::COPz
+"cop<ZZ> <COP_FUN0><COP_FUN1><COP_FUN2>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*r3900:
+{
+ DecodeCoproc (instruction_0);
+}
+
+
+
+010000,10000,000000000000000,001000:COP0:32::TLBP
+"tlbp"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+
+
+010000,10000,000000000000000,000001:COP0:32::TLBR
+"tlbr"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+
+
+010000,10000,000000000000000,000010:COP0:32::TLBWI
+"tlbwi"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+
+
+010000,10000,000000000000000,000110:COP0:32::TLBWR
+"tlbwr"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr4100:
+*vr5000:
+
+
+:include:::m16.igen
+:include:::tx.igen
+:include:::vr.igen
+
diff --git a/sim/mips/sim-main.c b/sim/mips/sim-main.c
new file mode 100644
index 0000000..58e63dc
--- /dev/null
+++ b/sim/mips/sim-main.c
@@ -0,0 +1,579 @@
+/* Copyright (C) 1998, Cygnus Solutions
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+
+#ifndef SIM_MAIN_C
+#define SIM_MAIN_C
+
+#include "sim-main.h"
+#include "sim-assert.h"
+
+
+/*---------------------------------------------------------------------------*/
+/*-- simulator engine -------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+
+
+/* Description from page A-22 of the "MIPS IV Instruction Set" manual
+ (revision 3.1) */
+/* Translate a virtual address to a physical address and cache
+ coherence algorithm describing the mechanism used to resolve the
+ memory reference. Given the virtual address vAddr, and whether the
+ reference is to Instructions ot Data (IorD), find the corresponding
+ physical address (pAddr) and the cache coherence algorithm (CCA)
+ used to resolve the reference. If the virtual address is in one of
+ the unmapped address spaces the physical address and the CCA are
+ determined directly by the virtual address. If the virtual address
+ is in one of the mapped address spaces then the TLB is used to
+ determine the physical address and access type; if the required
+ translation is not present in the TLB or the desired access is not
+ permitted the function fails and an exception is taken.
+
+ NOTE: Normally (RAW == 0), when address translation fails, this
+ function raises an exception and does not return. */
+
+INLINE_SIM_MAIN
+(int)
+address_translation (SIM_DESC sd,
+ sim_cpu * cpu,
+ address_word cia,
+ address_word vAddr,
+ int IorD,
+ int LorS,
+ address_word * pAddr,
+ int *CCA,
+ int raw)
+{
+ int res = -1; /* TRUE : Assume good return */
+
+#ifdef DEBUG
+ sim_io_printf (sd, "AddressTranslation(0x%s,%s,%s,...);\n", pr_addr (vAddr), (IorD ? "isDATA" : "isINSTRUCTION"), (LorS ? "iSTORE" : "isLOAD"));
+#endif
+
+ /* Check that the address is valid for this memory model */
+
+ /* For a simple (flat) memory model, we simply pass virtual
+ addressess through (mostly) unchanged. */
+ vAddr &= 0xFFFFFFFF;
+
+ *pAddr = vAddr; /* default for isTARGET */
+ *CCA = Uncached; /* not used for isHOST */
+
+ return (res);
+}
+
+
+
+/* Description from page A-23 of the "MIPS IV Instruction Set" manual
+ (revision 3.1) */
+/* Prefetch data from memory. Prefetch is an advisory instruction for
+ which an implementation specific action is taken. The action taken
+ may increase performance, but must not change the meaning of the
+ program, or alter architecturally-visible state. */
+
+INLINE_SIM_MAIN (void)
+prefetch (SIM_DESC sd,
+ sim_cpu *cpu,
+ address_word cia,
+ int CCA,
+ address_word pAddr,
+ address_word vAddr,
+ int DATA,
+ int hint)
+{
+#ifdef DEBUG
+ sim_io_printf(sd,"Prefetch(%d,0x%s,0x%s,%d,%d);\n",CCA,pr_addr(pAddr),pr_addr(vAddr),DATA,hint);
+#endif /* DEBUG */
+
+ /* For our simple memory model we do nothing */
+ return;
+}
+
+/* Description from page A-22 of the "MIPS IV Instruction Set" manual
+ (revision 3.1) */
+/* Load a value from memory. Use the cache and main memory as
+ specified in the Cache Coherence Algorithm (CCA) and the sort of
+ access (IorD) to find the contents of AccessLength memory bytes
+ starting at physical location pAddr. The data is returned in the
+ fixed width naturally-aligned memory element (MemElem). The
+ low-order two (or three) bits of the address and the AccessLength
+ indicate which of the bytes within MemElem needs to be given to the
+ processor. If the memory access type of the reference is uncached
+ then only the referenced bytes are read from memory and valid
+ within the memory element. If the access type is cached, and the
+ data is not present in cache, an implementation specific size and
+ alignment block of memory is read and loaded into the cache to
+ satisfy a load reference. At a minimum, the block is the entire
+ memory element. */
+INLINE_SIM_MAIN (void)
+load_memory (SIM_DESC SD,
+ sim_cpu *CPU,
+ address_word cia,
+ uword64* memvalp,
+ uword64* memval1p,
+ int CCA,
+ unsigned int AccessLength,
+ address_word pAddr,
+ address_word vAddr,
+ int IorD)
+{
+ uword64 value = 0;
+ uword64 value1 = 0;
+
+#ifdef DEBUG
+ sim_io_printf(sd,"DBG: LoadMemory(%p,%p,%d,%d,0x%s,0x%s,%s)\n",memvalp,memval1p,CCA,AccessLength,pr_addr(pAddr),pr_addr(vAddr),(IorD ? "isDATA" : "isINSTRUCTION"));
+#endif /* DEBUG */
+
+#if defined(WARN_MEM)
+ if (CCA != uncached)
+ sim_io_eprintf(sd,"LoadMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA);
+#endif /* WARN_MEM */
+
+ if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK)
+ {
+ /* In reality this should be a Bus Error */
+ sim_io_error (SD, "LOAD AccessLength of %d would extend over %d bit aligned boundary for physical address 0x%s\n",
+ AccessLength,
+ (LOADDRMASK + 1) << 3,
+ pr_addr (pAddr));
+ }
+
+#if defined(TRACE)
+ dotrace (SD, CPU, tracefh,((IorD == isDATA) ? 0 : 2),(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"load%s",((IorD == isDATA) ? "" : " instruction"));
+#endif /* TRACE */
+
+ /* Read the specified number of bytes from memory. Adjust for
+ host/target byte ordering/ Align the least significant byte
+ read. */
+
+ switch (AccessLength)
+ {
+ case AccessLength_QUADWORD :
+ {
+ unsigned_16 val = sim_core_read_aligned_16 (CPU, NULL_CIA, read_map, pAddr);
+ value1 = VH8_16 (val);
+ value = VL8_16 (val);
+ break;
+ }
+ case AccessLength_DOUBLEWORD :
+ value = sim_core_read_aligned_8 (CPU, NULL_CIA,
+ read_map, pAddr);
+ break;
+ case AccessLength_SEPTIBYTE :
+ value = sim_core_read_misaligned_7 (CPU, NULL_CIA,
+ read_map, pAddr);
+ break;
+ case AccessLength_SEXTIBYTE :
+ value = sim_core_read_misaligned_6 (CPU, NULL_CIA,
+ read_map, pAddr);
+ break;
+ case AccessLength_QUINTIBYTE :
+ value = sim_core_read_misaligned_5 (CPU, NULL_CIA,
+ read_map, pAddr);
+ break;
+ case AccessLength_WORD :
+ value = sim_core_read_aligned_4 (CPU, NULL_CIA,
+ read_map, pAddr);
+ break;
+ case AccessLength_TRIPLEBYTE :
+ value = sim_core_read_misaligned_3 (CPU, NULL_CIA,
+ read_map, pAddr);
+ break;
+ case AccessLength_HALFWORD :
+ value = sim_core_read_aligned_2 (CPU, NULL_CIA,
+ read_map, pAddr);
+ break;
+ case AccessLength_BYTE :
+ value = sim_core_read_aligned_1 (CPU, NULL_CIA,
+ read_map, pAddr);
+ break;
+ default:
+ abort ();
+ }
+
+#ifdef DEBUG
+ printf("DBG: LoadMemory() : (offset %d) : value = 0x%s%s\n",
+ (int)(pAddr & LOADDRMASK),pr_uword64(value1),pr_uword64(value));
+#endif /* DEBUG */
+
+ /* See also store_memory. Position data in correct byte lanes. */
+ if (AccessLength <= LOADDRMASK)
+ {
+ if (BigEndianMem)
+ /* for big endian target, byte (pAddr&LOADDRMASK == 0) is
+ shifted to the most significant byte position. */
+ value <<= (((LOADDRMASK - (pAddr & LOADDRMASK)) - AccessLength) * 8);
+ else
+ /* For little endian target, byte (pAddr&LOADDRMASK == 0)
+ is already in the correct postition. */
+ value <<= ((pAddr & LOADDRMASK) * 8);
+ }
+
+#ifdef DEBUG
+ printf("DBG: LoadMemory() : shifted value = 0x%s%s\n",
+ pr_uword64(value1),pr_uword64(value));
+#endif /* DEBUG */
+
+ *memvalp = value;
+ if (memval1p) *memval1p = value1;
+}
+
+
+/* Description from page A-23 of the "MIPS IV Instruction Set" manual
+ (revision 3.1) */
+/* Store a value to memory. The specified data is stored into the
+ physical location pAddr using the memory hierarchy (data caches and
+ main memory) as specified by the Cache Coherence Algorithm
+ (CCA). The MemElem contains the data for an aligned, fixed-width
+ memory element (word for 32-bit processors, doubleword for 64-bit
+ processors), though only the bytes that will actually be stored to
+ memory need to be valid. The low-order two (or three) bits of pAddr
+ and the AccessLength field indicates which of the bytes within the
+ MemElem data should actually be stored; only these bytes in memory
+ will be changed. */
+
+INLINE_SIM_MAIN (void)
+store_memory (SIM_DESC SD,
+ sim_cpu *CPU,
+ address_word cia,
+ int CCA,
+ unsigned int AccessLength,
+ uword64 MemElem,
+ uword64 MemElem1, /* High order 64 bits */
+ address_word pAddr,
+ address_word vAddr)
+{
+#ifdef DEBUG
+ sim_io_printf(sd,"DBG: StoreMemory(%d,%d,0x%s,0x%s,0x%s,0x%s)\n",CCA,AccessLength,pr_uword64(MemElem),pr_uword64(MemElem1),pr_addr(pAddr),pr_addr(vAddr));
+#endif /* DEBUG */
+
+#if defined(WARN_MEM)
+ if (CCA != uncached)
+ sim_io_eprintf(sd,"StoreMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA);
+#endif /* WARN_MEM */
+
+ if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK)
+ sim_io_error (SD, "STORE AccessLength of %d would extend over %d bit aligned boundary for physical address 0x%s\n",
+ AccessLength,
+ (LOADDRMASK + 1) << 3,
+ pr_addr(pAddr));
+
+#if defined(TRACE)
+ dotrace (SD, CPU, tracefh,1,(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"store");
+#endif /* TRACE */
+
+#ifdef DEBUG
+ printf("DBG: StoreMemory: offset = %d MemElem = 0x%s%s\n",(unsigned int)(pAddr & LOADDRMASK),pr_uword64(MemElem1),pr_uword64(MemElem));
+#endif /* DEBUG */
+
+ /* See also load_memory. Position data in correct byte lanes. */
+ if (AccessLength <= LOADDRMASK)
+ {
+ if (BigEndianMem)
+ /* for big endian target, byte (pAddr&LOADDRMASK == 0) is
+ shifted to the most significant byte position. */
+ MemElem >>= (((LOADDRMASK - (pAddr & LOADDRMASK)) - AccessLength) * 8);
+ else
+ /* For little endian target, byte (pAddr&LOADDRMASK == 0)
+ is already in the correct postition. */
+ MemElem >>= ((pAddr & LOADDRMASK) * 8);
+ }
+
+#ifdef DEBUG
+ printf("DBG: StoreMemory: shift = %d MemElem = 0x%s%s\n",shift,pr_uword64(MemElem1),pr_uword64(MemElem));
+#endif /* DEBUG */
+
+ switch (AccessLength)
+ {
+ case AccessLength_QUADWORD :
+ {
+ unsigned_16 val = U16_8 (MemElem1, MemElem);
+ sim_core_write_aligned_16 (CPU, NULL_CIA, write_map, pAddr, val);
+ break;
+ }
+ case AccessLength_DOUBLEWORD :
+ sim_core_write_aligned_8 (CPU, NULL_CIA,
+ write_map, pAddr, MemElem);
+ break;
+ case AccessLength_SEPTIBYTE :
+ sim_core_write_misaligned_7 (CPU, NULL_CIA,
+ write_map, pAddr, MemElem);
+ break;
+ case AccessLength_SEXTIBYTE :
+ sim_core_write_misaligned_6 (CPU, NULL_CIA,
+ write_map, pAddr, MemElem);
+ break;
+ case AccessLength_QUINTIBYTE :
+ sim_core_write_misaligned_5 (CPU, NULL_CIA,
+ write_map, pAddr, MemElem);
+ break;
+ case AccessLength_WORD :
+ sim_core_write_aligned_4 (CPU, NULL_CIA,
+ write_map, pAddr, MemElem);
+ break;
+ case AccessLength_TRIPLEBYTE :
+ sim_core_write_misaligned_3 (CPU, NULL_CIA,
+ write_map, pAddr, MemElem);
+ break;
+ case AccessLength_HALFWORD :
+ sim_core_write_aligned_2 (CPU, NULL_CIA,
+ write_map, pAddr, MemElem);
+ break;
+ case AccessLength_BYTE :
+ sim_core_write_aligned_1 (CPU, NULL_CIA,
+ write_map, pAddr, MemElem);
+ break;
+ default:
+ abort ();
+ }
+
+ return;
+}
+
+
+INLINE_SIM_MAIN (unsigned32)
+ifetch32 (SIM_DESC SD,
+ sim_cpu *CPU,
+ address_word cia,
+ address_word vaddr)
+{
+ /* Copy the action of the LW instruction */
+ address_word mask = LOADDRMASK;
+ address_word access = AccessLength_WORD;
+ address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
+ address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
+ unsigned int byte;
+ address_word paddr;
+ int uncached;
+ unsigned64 memval;
+
+ if ((vaddr & access) != 0)
+ SignalExceptionInstructionFetch ();
+ AddressTranslation (vaddr, isINSTRUCTION, isLOAD, &paddr, &uncached, isTARGET, isREAL);
+ paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
+ LoadMemory (&memval, NULL, uncached, access, paddr, vaddr, isINSTRUCTION, isREAL);
+ byte = ((vaddr & mask) ^ bigendiancpu);
+ return (memval >> (8 * byte));
+}
+
+
+INLINE_SIM_MAIN (unsigned16)
+ifetch16 (SIM_DESC SD,
+ sim_cpu *CPU,
+ address_word cia,
+ address_word vaddr)
+{
+ /* Copy the action of the LH instruction */
+ address_word mask = LOADDRMASK;
+ address_word access = AccessLength_HALFWORD;
+ address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
+ address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
+ unsigned int byte;
+ address_word paddr;
+ int uncached;
+ unsigned64 memval;
+
+ if ((vaddr & access) != 0)
+ SignalExceptionInstructionFetch ();
+ AddressTranslation (vaddr, isINSTRUCTION, isLOAD, &paddr, &uncached, isTARGET, isREAL);
+ paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
+ LoadMemory (&memval, NULL, uncached, access, paddr, vaddr, isINSTRUCTION, isREAL);
+ byte = ((vaddr & mask) ^ bigendiancpu);
+ return (memval >> (8 * byte));
+}
+
+
+
+/* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
+/* Order loads and stores to synchronise shared memory. Perform the
+ action necessary to make the effects of groups of synchronizable
+ loads and stores indicated by stype occur in the same order for all
+ processors. */
+INLINE_SIM_MAIN (void)
+sync_operation (SIM_DESC sd,
+ sim_cpu *cpu,
+ address_word cia,
+ int stype)
+{
+#ifdef DEBUG
+ sim_io_printf(sd,"SyncOperation(%d) : TODO\n",stype);
+#endif /* DEBUG */
+ return;
+}
+
+INLINE_SIM_MAIN (void)
+cache_op (SIM_DESC SD,
+ sim_cpu *CPU,
+ address_word cia,
+ int op,
+ address_word pAddr,
+ address_word vAddr,
+ unsigned int instruction)
+{
+#if 1 /* stop warning message being displayed (we should really just remove the code) */
+ static int icache_warning = 1;
+ static int dcache_warning = 1;
+#else
+ static int icache_warning = 0;
+ static int dcache_warning = 0;
+#endif
+
+ /* If CP0 is not useable (User or Supervisor mode) and the CP0
+ enable bit in the Status Register is clear - a coprocessor
+ unusable exception is taken. */
+#if 0
+ sim_io_printf(SD,"TODO: Cache availability checking (PC = 0x%s)\n",pr_addr(cia));
+#endif
+
+ switch (op & 0x3) {
+ case 0: /* instruction cache */
+ switch (op >> 2) {
+ case 0: /* Index Invalidate */
+ case 1: /* Index Load Tag */
+ case 2: /* Index Store Tag */
+ case 4: /* Hit Invalidate */
+ case 5: /* Fill */
+ case 6: /* Hit Writeback */
+ if (!icache_warning)
+ {
+ sim_io_eprintf(SD,"Instruction CACHE operation %d to be coded\n",(op >> 2));
+ icache_warning = 1;
+ }
+ break;
+
+ default:
+ SignalException(ReservedInstruction,instruction);
+ break;
+ }
+ break;
+
+ case 1: /* data cache */
+ switch (op >> 2) {
+ case 0: /* Index Writeback Invalidate */
+ case 1: /* Index Load Tag */
+ case 2: /* Index Store Tag */
+ case 3: /* Create Dirty */
+ case 4: /* Hit Invalidate */
+ case 5: /* Hit Writeback Invalidate */
+ case 6: /* Hit Writeback */
+ if (!dcache_warning)
+ {
+ sim_io_eprintf(SD,"Data CACHE operation %d to be coded\n",(op >> 2));
+ dcache_warning = 1;
+ }
+ break;
+
+ default:
+ SignalException(ReservedInstruction,instruction);
+ break;
+ }
+ break;
+
+ default: /* unrecognised cache ID */
+ SignalException(ReservedInstruction,instruction);
+ break;
+ }
+
+ return;
+}
+
+
+INLINE_SIM_MAIN (void)
+pending_tick (SIM_DESC SD,
+ sim_cpu *CPU,
+ address_word cia)
+{
+ if (PENDING_TRACE)
+ sim_io_eprintf (SD, "PENDING_DRAIN - 0x%lx - pending_in = %d, pending_out = %d, pending_total = %d\n", (unsigned long) cia, PENDING_IN, PENDING_OUT, PENDING_TOTAL);
+ if (PENDING_OUT != PENDING_IN)
+ {
+ int loop;
+ int index = PENDING_OUT;
+ int total = PENDING_TOTAL;
+ if (PENDING_TOTAL == 0)
+ sim_engine_abort (SD, CPU, cia, "PENDING_DRAIN - Mis-match on pending update pointers\n");
+ for (loop = 0, index = PENDING_OUT;
+ (loop < total);
+ loop++, index = (index + 1) % PSLOTS)
+ {
+ if (PENDING_SLOT_DEST[index] != NULL)
+ {
+ PENDING_SLOT_DELAY[index] -= 1;
+ if (PENDING_SLOT_DELAY[index] == 0)
+ {
+ if (PENDING_TRACE)
+ sim_io_eprintf (SD, "PENDING_DRAIN - drained - index %d, dest 0x%lx, bit %d, val 0x%lx, size %d\n",
+ index,
+ (unsigned long) PENDING_SLOT_DEST[index],
+ PENDING_SLOT_BIT[index],
+ (unsigned long) PENDING_SLOT_VALUE[index],
+ PENDING_SLOT_SIZE[index]);
+ if (PENDING_SLOT_BIT[index] >= 0)
+ switch (PENDING_SLOT_SIZE[index])
+ {
+ case 4:
+ if (PENDING_SLOT_VALUE[index])
+ *(unsigned32*)PENDING_SLOT_DEST[index] |=
+ BIT32 (PENDING_SLOT_BIT[index]);
+ else
+ *(unsigned32*)PENDING_SLOT_DEST[index] &=
+ BIT32 (PENDING_SLOT_BIT[index]);
+ break;
+ case 8:
+ if (PENDING_SLOT_VALUE[index])
+ *(unsigned64*)PENDING_SLOT_DEST[index] |=
+ BIT64 (PENDING_SLOT_BIT[index]);
+ else
+ *(unsigned64*)PENDING_SLOT_DEST[index] &=
+ BIT64 (PENDING_SLOT_BIT[index]);
+ break;
+ }
+ else
+ switch (PENDING_SLOT_SIZE[index])
+ {
+ case 4:
+ *(unsigned32*)PENDING_SLOT_DEST[index] =
+ PENDING_SLOT_VALUE[index];
+ break;
+ case 8:
+ *(unsigned64*)PENDING_SLOT_DEST[index] =
+ PENDING_SLOT_VALUE[index];
+ break;
+ }
+ if (PENDING_OUT == index)
+ {
+ PENDING_SLOT_DEST[index] = NULL;
+ PENDING_OUT = (PENDING_OUT + 1) % PSLOTS;
+ PENDING_TOTAL--;
+ }
+ }
+ else if (PENDING_TRACE && PENDING_SLOT_DELAY[index] > 0)
+ sim_io_eprintf (SD, "PENDING_DRAIN - queued - index %d, delay %d, dest 0x%lx, bit %d, val 0x%lx, size %d\n",
+ index, PENDING_SLOT_DELAY[index],
+ (unsigned long) PENDING_SLOT_DEST[index],
+ PENDING_SLOT_BIT[index],
+ (unsigned long) PENDING_SLOT_VALUE[index],
+ PENDING_SLOT_SIZE[index]);
+
+ }
+ }
+ }
+}
+
+
+#endif
diff --git a/sim/mips/sim-main.h b/sim/mips/sim-main.h
new file mode 100644
index 0000000..6b6a6f9
--- /dev/null
+++ b/sim/mips/sim-main.h
@@ -0,0 +1,785 @@
+/* MIPS Simulator definition.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+
+This file is part of GDB, the GNU debugger.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef SIM_MAIN_H
+#define SIM_MAIN_H
+
+/* This simulator doesn't cache the Current Instruction Address */
+/* #define SIM_ENGINE_HALT_HOOK(SD, LAST_CPU, CIA) */
+/* #define SIM_ENGINE_RESUME_HOOK(SD, LAST_CPU, CIA) */
+
+#define SIM_HAVE_BIENDIAN
+
+
+/* hobble some common features for moment */
+#define WITH_WATCHPOINTS 1
+#define WITH_MODULO_MEMORY 1
+
+
+#define SIM_CORE_SIGNAL(SD,CPU,CIA,MAP,NR_BYTES,ADDR,TRANSFER,ERROR) \
+mips_core_signal ((SD), (CPU), (CIA), (MAP), (NR_BYTES), (ADDR), (TRANSFER), (ERROR))
+
+#include "sim-basics.h"
+
+typedef address_word sim_cia;
+
+#include "sim-base.h"
+
+
+/* Depreciated macros and types for manipulating 64bit values. Use
+ ../common/sim-bits.h and ../common/sim-endian.h macros instead. */
+
+typedef signed64 word64;
+typedef unsigned64 uword64;
+
+#define WORD64LO(t) (unsigned int)((t)&0xFFFFFFFF)
+#define WORD64HI(t) (unsigned int)(((uword64)(t))>>32)
+#define SET64LO(t) (((uword64)(t))&0xFFFFFFFF)
+#define SET64HI(t) (((uword64)(t))<<32)
+#define WORD64(h,l) ((word64)((SET64HI(h)|SET64LO(l))))
+#define UWORD64(h,l) (SET64HI(h)|SET64LO(l))
+
+/* Sign-extend the given value (e) as a value (b) bits long. We cannot
+ assume the HI32bits of the operand are zero, so we must perform a
+ mask to ensure we can use the simple subtraction to sign-extend. */
+#define SIGNEXTEND(e,b) \
+ ((unsigned_word) \
+ (((e) & ((uword64) 1 << ((b) - 1))) \
+ ? (((e) & (((uword64) 1 << (b)) - 1)) - ((uword64)1 << (b))) \
+ : ((e) & (((((uword64) 1 << ((b) - 1)) - 1) << 1) | 1))))
+
+/* Check if a value will fit within a halfword: */
+#define NOTHALFWORDVALUE(v) ((((((uword64)(v)>>16) == 0) && !((v) & ((unsigned)1 << 15))) || (((((uword64)(v)>>32) == 0xFFFFFFFF) && ((((uword64)(v)>>16) & 0xFFFF) == 0xFFFF)) && ((v) & ((unsigned)1 << 15)))) ? (1 == 0) : (1 == 1))
+
+
+
+/* Floating-point operations: */
+
+#include "sim-fpu.h"
+
+/* FPU registers must be one of the following types. All other values
+ are reserved (and undefined). */
+typedef enum {
+ fmt_single = 0,
+ fmt_double = 1,
+ fmt_word = 4,
+ fmt_long = 5,
+ /* The following are well outside the normal acceptable format
+ range, and are used in the register status vector. */
+ fmt_unknown = 0x10000000,
+ fmt_uninterpreted = 0x20000000,
+ fmt_uninterpreted_32 = 0x40000000,
+ fmt_uninterpreted_64 = 0x80000000U,
+} FP_formats;
+
+unsigned64 value_fpr PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int fpr, FP_formats));
+#define ValueFPR(FPR,FMT) value_fpr (SD, CPU, cia, (FPR), (FMT))
+
+void store_fpr PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int fpr, FP_formats fmt, unsigned64 value));
+#define StoreFPR(FPR,FMT,VALUE) store_fpr (SD, CPU, cia, (FPR), (FMT), (VALUE))
+
+int NaN PARAMS ((unsigned64 op, FP_formats fmt));
+int Infinity PARAMS ((unsigned64 op, FP_formats fmt));
+int Less PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
+int Equal PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
+unsigned64 AbsoluteValue PARAMS ((unsigned64 op, FP_formats fmt));
+unsigned64 Negate PARAMS ((unsigned64 op, FP_formats fmt));
+unsigned64 Add PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
+unsigned64 Sub PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
+unsigned64 Multiply PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
+unsigned64 Divide PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
+unsigned64 Recip PARAMS ((unsigned64 op, FP_formats fmt));
+unsigned64 SquareRoot PARAMS ((unsigned64 op, FP_formats fmt));
+unsigned64 Max PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
+unsigned64 Min PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
+unsigned64 convert PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int rm, unsigned64 op, FP_formats from, FP_formats to));
+#define Convert(rm,op,from,to) \
+convert (SD, CPU, cia, rm, op, from, to)
+
+/* Macro to update FPSR condition-code field. This is complicated by
+ the fact that there is a hole in the index range of the bits within
+ the FCSR register. Also, the number of bits visible depends on the
+ MIPS ISA version being supported. */
+
+#define SETFCC(cc,v) {\
+ int bit = ((cc == 0) ? 23 : (24 + (cc)));\
+ FCSR = ((FCSR & ~(1 << bit)) | ((v) << bit));\
+}
+#define GETFCC(cc) (((((cc) == 0) ? (FCSR & (1 << 23)) : (FCSR & (1 << (24 + (cc))))) != 0) ? 1U : 0)
+
+/* This should be the COC1 value at the start of the preceding
+ instruction: */
+#define PREVCOC1() ((STATE & simPCOC1) ? 1 : 0)
+
+#ifdef TARGET_ENABLE_FR
+/* FIXME: this should be enabled for all targets, but needs testing first. */
+#define SizeFGR() (((WITH_TARGET_FLOATING_POINT_BITSIZE) == 64) \
+ ? ((SR & status_FR) ? 64 : 32) \
+ : (WITH_TARGET_FLOATING_POINT_BITSIZE))
+#else
+#define SizeFGR() (WITH_TARGET_FLOATING_POINT_BITSIZE)
+#endif
+
+/* Standard FCRS bits: */
+#define IR (0) /* Inexact Result */
+#define UF (1) /* UnderFlow */
+#define OF (2) /* OverFlow */
+#define DZ (3) /* Division by Zero */
+#define IO (4) /* Invalid Operation */
+#define UO (5) /* Unimplemented Operation */
+
+/* Get masks for individual flags: */
+#if 1 /* SAFE version */
+#define FP_FLAGS(b) (((unsigned)(b) < 5) ? (1 << ((b) + 2)) : 0)
+#define FP_ENABLE(b) (((unsigned)(b) < 5) ? (1 << ((b) + 7)) : 0)
+#define FP_CAUSE(b) (((unsigned)(b) < 6) ? (1 << ((b) + 12)) : 0)
+#else
+#define FP_FLAGS(b) (1 << ((b) + 2))
+#define FP_ENABLE(b) (1 << ((b) + 7))
+#define FP_CAUSE(b) (1 << ((b) + 12))
+#endif
+
+#define FP_FS (1 << 24) /* MIPS III onwards : Flush to Zero */
+
+#define FP_MASK_RM (0x3)
+#define FP_SH_RM (0)
+#define FP_RM_NEAREST (0) /* Round to nearest (Round) */
+#define FP_RM_TOZERO (1) /* Round to zero (Trunc) */
+#define FP_RM_TOPINF (2) /* Round to Plus infinity (Ceil) */
+#define FP_RM_TOMINF (3) /* Round to Minus infinity (Floor) */
+#define GETRM() (int)((FCSR >> FP_SH_RM) & FP_MASK_RM)
+
+
+
+
+
+
+/* HI/LO register accesses */
+
+/* For some MIPS targets, the HI/LO registers have certain timing
+ restrictions in that, for instance, a read of a HI register must be
+ separated by at least three instructions from a preceeding read.
+
+ The struct below is used to record the last access by each of A MT,
+ MF or other OP instruction to a HI/LO register. See mips.igen for
+ more details. */
+
+typedef struct _hilo_access {
+ signed64 timestamp;
+ address_word cia;
+} hilo_access;
+
+typedef struct _hilo_history {
+ hilo_access mt;
+ hilo_access mf;
+ hilo_access op;
+} hilo_history;
+
+
+
+
+/* Integer ALU operations: */
+
+#include "sim-alu.h"
+
+#define ALU32_END(ANS) \
+ if (ALU32_HAD_OVERFLOW) \
+ SignalExceptionIntegerOverflow (); \
+ (ANS) = (signed32) ALU32_OVERFLOW_RESULT
+
+
+#define ALU64_END(ANS) \
+ if (ALU64_HAD_OVERFLOW) \
+ SignalExceptionIntegerOverflow (); \
+ (ANS) = ALU64_OVERFLOW_RESULT;
+
+
+
+
+
+/* The following is probably not used for MIPS IV onwards: */
+/* Slots for delayed register updates. For the moment we just have a
+ fixed number of slots (rather than a more generic, dynamic
+ system). This keeps the simulator fast. However, we only allow
+ for the register update to be delayed for a single instruction
+ cycle. */
+#define PSLOTS (8) /* Maximum number of instruction cycles */
+
+typedef struct _pending_write_queue {
+ int in;
+ int out;
+ int total;
+ int slot_delay[PSLOTS];
+ int slot_size[PSLOTS];
+ int slot_bit[PSLOTS];
+ void *slot_dest[PSLOTS];
+ unsigned64 slot_value[PSLOTS];
+} pending_write_queue;
+
+#ifndef PENDING_TRACE
+#define PENDING_TRACE 0
+#endif
+#define PENDING_IN ((CPU)->pending.in)
+#define PENDING_OUT ((CPU)->pending.out)
+#define PENDING_TOTAL ((CPU)->pending.total)
+#define PENDING_SLOT_SIZE ((CPU)->pending.slot_size)
+#define PENDING_SLOT_BIT ((CPU)->pending.slot_bit)
+#define PENDING_SLOT_DELAY ((CPU)->pending.slot_delay)
+#define PENDING_SLOT_DEST ((CPU)->pending.slot_dest)
+#define PENDING_SLOT_VALUE ((CPU)->pending.slot_value)
+
+/* Invalidate the pending write queue, all pending writes are
+ discarded. */
+
+#define PENDING_INVALIDATE() \
+memset (&(CPU)->pending, 0, sizeof ((CPU)->pending))
+
+/* Schedule a write to DEST for N cycles time. For 64 bit
+ destinations, schedule two writes. For floating point registers,
+ the caller should schedule a write to both the dest register and
+ the FPR_STATE register. When BIT is non-negative, only BIT of DEST
+ is updated. */
+
+#define PENDING_SCHED(DEST,VAL,DELAY,BIT) \
+ do { \
+ if (PENDING_SLOT_DEST[PENDING_IN] != NULL) \
+ sim_engine_abort (SD, CPU, cia, \
+ "PENDING_SCHED - buffer overflow\n"); \
+ if (PENDING_TRACE) \
+ sim_io_eprintf (SD, "PENDING_SCHED - 0x%lx - dest 0x%lx, val 0x%lx, bit %d, size %d, pending_in %d, pending_out %d, pending_total %d\n", \
+ (unsigned long) cia, (unsigned long) &(DEST), \
+ (unsigned long) (VAL), (BIT), (int) sizeof (DEST),\
+ PENDING_IN, PENDING_OUT, PENDING_TOTAL); \
+ PENDING_SLOT_DELAY[PENDING_IN] = (DELAY) + 1; \
+ PENDING_SLOT_DEST[PENDING_IN] = &(DEST); \
+ PENDING_SLOT_VALUE[PENDING_IN] = (VAL); \
+ PENDING_SLOT_SIZE[PENDING_IN] = sizeof (DEST); \
+ PENDING_SLOT_BIT[PENDING_IN] = (BIT); \
+ PENDING_IN = (PENDING_IN + 1) % PSLOTS; \
+ PENDING_TOTAL += 1; \
+ } while (0)
+
+#define PENDING_WRITE(DEST,VAL,DELAY) PENDING_SCHED(DEST,VAL,DELAY,-1)
+#define PENDING_BIT(DEST,VAL,DELAY,BIT) PENDING_SCHED(DEST,VAL,DELAY,BIT)
+
+#define PENDING_TICK() pending_tick (SD, CPU, cia)
+
+#define PENDING_FLUSH() abort () /* think about this one */
+#define PENDING_FP() abort () /* think about this one */
+
+/* For backward compatibility */
+#define PENDING_FILL(R,VAL) \
+do { \
+ if ((R) >= FGRIDX && (R) < FGRIDX + NR_FGR) \
+ { \
+ PENDING_SCHED(FGR[(R) - FGRIDX], VAL, 1, -1); \
+ PENDING_SCHED(FPR_STATE[(R) - FGRIDX], fmt_uninterpreted, 1, -1); \
+ } \
+ else \
+ PENDING_SCHED(GPR[(R)], VAL, 1, -1); \
+} while (0)
+
+
+
+struct _sim_cpu {
+
+
+ /* The following are internal simulator state variables: */
+#define CIA_GET(CPU) ((CPU)->registers[PCIDX] + 0)
+#define CIA_SET(CPU,CIA) ((CPU)->registers[PCIDX] = (CIA))
+ address_word dspc; /* delay-slot PC */
+#define DSPC ((CPU)->dspc)
+
+#define DELAY_SLOT(TARGET) NIA = delayslot32 (SD_, (TARGET))
+#define NULLIFY_NEXT_INSTRUCTION() NIA = nullify_next_insn32 (SD_)
+
+
+ /* State of the simulator */
+ unsigned int state;
+ unsigned int dsstate;
+#define STATE ((CPU)->state)
+#define DSSTATE ((CPU)->dsstate)
+
+/* Flags in the "state" variable: */
+#define simHALTEX (1 << 2) /* 0 = run; 1 = halt on exception */
+#define simHALTIN (1 << 3) /* 0 = run; 1 = halt on interrupt */
+#define simTRACE (1 << 8) /* 0 = do nothing; 1 = trace address activity */
+#define simPCOC0 (1 << 17) /* COC[1] from current */
+#define simPCOC1 (1 << 18) /* COC[1] from previous */
+#define simDELAYSLOT (1 << 24) /* 0 = do nothing; 1 = delay slot entry exists */
+#define simSKIPNEXT (1 << 25) /* 0 = do nothing; 1 = skip instruction */
+#define simSIGINT (1 << 28) /* 0 = do nothing; 1 = SIGINT has occured */
+#define simJALDELAYSLOT (1 << 29) /* 1 = in jal delay slot */
+
+#define ENGINE_ISSUE_PREFIX_HOOK() \
+ { \
+ /* Perform any pending writes */ \
+ PENDING_TICK(); \
+ /* Set previous flag, depending on current: */ \
+ if (STATE & simPCOC0) \
+ STATE |= simPCOC1; \
+ else \
+ STATE &= ~simPCOC1; \
+ /* and update the current value: */ \
+ if (GETFCC(0)) \
+ STATE |= simPCOC0; \
+ else \
+ STATE &= ~simPCOC0; \
+ }
+
+
+/* This is nasty, since we have to rely on matching the register
+ numbers used by GDB. Unfortunately, depending on the MIPS target
+ GDB uses different register numbers. We cannot just include the
+ relevant "gdb/tm.h" link, since GDB may not be configured before
+ the sim world, and also the GDB header file requires too much other
+ state. */
+
+#ifndef TM_MIPS_H
+#define LAST_EMBED_REGNUM (89)
+#define NUM_REGS (LAST_EMBED_REGNUM + 1)
+
+
+#endif
+
+
+enum float_operation
+ {
+ FLOP_ADD, FLOP_SUB, FLOP_MUL, FLOP_MADD,
+ FLOP_MSUB, FLOP_MAX=10, FLOP_MIN, FLOP_ABS,
+ FLOP_ITOF0=14, FLOP_FTOI0=18, FLOP_NEG=23
+ };
+
+/* To keep this default simulator simple, and fast, we use a direct
+ vector of registers. The internal simulator engine then uses
+ manifests to access the correct slot. */
+
+ unsigned_word registers[LAST_EMBED_REGNUM + 1];
+
+ int register_widths[NUM_REGS];
+#define REGISTERS ((CPU)->registers)
+
+#define GPR (&REGISTERS[0])
+#define GPR_SET(N,VAL) (REGISTERS[(N)] = (VAL))
+
+ /* While space is allocated for the floating point registers in the
+ main registers array, they are stored separatly. This is because
+ their size may not necessarily match the size of either the
+ general-purpose or system specific registers */
+#define NR_FGR (32)
+#define FGRIDX (38)
+ fp_word fgr[NR_FGR];
+#define FGR ((CPU)->fgr)
+
+#define LO (REGISTERS[33])
+#define HI (REGISTERS[34])
+#define PCIDX 37
+#define PC (REGISTERS[PCIDX])
+#define CAUSE (REGISTERS[36])
+#define SRIDX (32)
+#define SR (REGISTERS[SRIDX]) /* CPU status register */
+#define FCR0IDX (71)
+#define FCR0 (REGISTERS[FCR0IDX]) /* really a 32bit register */
+#define FCR31IDX (70)
+#define FCR31 (REGISTERS[FCR31IDX]) /* really a 32bit register */
+#define FCSR (FCR31)
+#define Debug (REGISTERS[86])
+#define DEPC (REGISTERS[87])
+#define EPC (REGISTERS[88])
+#define COCIDX (LAST_EMBED_REGNUM + 2) /* special case : outside the normal range */
+
+ /* All internal state modified by signal_exception() that may need to be
+ rolled back for passing moment-of-exception image back to gdb. */
+ unsigned_word exc_trigger_registers[LAST_EMBED_REGNUM + 1];
+ unsigned_word exc_suspend_registers[LAST_EMBED_REGNUM + 1];
+ int exc_suspended;
+
+#define SIM_CPU_EXCEPTION_TRIGGER(SD,CPU,CIA) mips_cpu_exception_trigger(SD,CPU,CIA)
+#define SIM_CPU_EXCEPTION_SUSPEND(SD,CPU,EXC) mips_cpu_exception_suspend(SD,CPU,EXC)
+#define SIM_CPU_EXCEPTION_RESUME(SD,CPU,EXC) mips_cpu_exception_resume(SD,CPU,EXC)
+
+ unsigned_word c0_config_reg;
+#define C0_CONFIG ((CPU)->c0_config_reg)
+
+/* The following are pseudonyms for standard registers */
+#define ZERO (REGISTERS[0])
+#define V0 (REGISTERS[2])
+#define A0 (REGISTERS[4])
+#define A1 (REGISTERS[5])
+#define A2 (REGISTERS[6])
+#define A3 (REGISTERS[7])
+#define T8IDX 24
+#define T8 (REGISTERS[T8IDX])
+#define SPIDX 29
+#define SP (REGISTERS[SPIDX])
+#define RAIDX 31
+#define RA (REGISTERS[RAIDX])
+
+ /* While space is allocated in the main registers arrray for some of
+ the COP0 registers, that space isn't sufficient. Unknown COP0
+ registers overflow into the array below */
+
+#define NR_COP0_GPR 32
+ unsigned_word cop0_gpr[NR_COP0_GPR];
+#define COP0_GPR ((CPU)->cop0_gpr)
+#define COP0_BADVADDR ((unsigned32)(COP0_GPR[8]))
+
+ /* Keep the current format state for each register: */
+ FP_formats fpr_state[32];
+#define FPR_STATE ((CPU)->fpr_state)
+
+ pending_write_queue pending;
+
+ /* LLBIT = Load-Linked bit. A bit of "virtual" state used by atomic
+ read-write instructions. It is set when a linked load occurs. It
+ is tested and cleared by the conditional store. It is cleared
+ (during other CPU operations) when a store to the location would
+ no longer be atomic. In particular, it is cleared by exception
+ return instructions. */
+ int llbit;
+#define LLBIT ((CPU)->llbit)
+
+
+/* The HIHISTORY and LOHISTORY timestamps are used to ensure that
+ corruptions caused by using the HI or LO register too close to a
+ following operation is spotted. See mips.igen for more details. */
+
+ hilo_history hi_history;
+#define HIHISTORY (&(CPU)->hi_history)
+ hilo_history lo_history;
+#define LOHISTORY (&(CPU)->lo_history)
+
+#define check_branch_bug()
+#define mark_branch_bug(TARGET)
+
+
+
+ sim_cpu_base base;
+};
+
+
+/* MIPS specific simulator watch config */
+
+void watch_options_install PARAMS ((SIM_DESC sd));
+
+struct swatch {
+ sim_event *pc;
+ sim_event *clock;
+ sim_event *cycles;
+};
+
+
+/* FIXME: At present much of the simulator is still static */
+struct sim_state {
+
+ struct swatch watch;
+
+ sim_cpu cpu[MAX_NR_PROCESSORS];
+#if (WITH_SMP)
+#define STATE_CPU(sd,n) (&(sd)->cpu[n])
+#else
+#define STATE_CPU(sd,n) (&(sd)->cpu[0])
+#endif
+
+
+ sim_state_base base;
+};
+
+
+
+/* Status information: */
+
+/* TODO : these should be the bitmasks for these bits within the
+ status register. At the moment the following are VR4300
+ bit-positions: */
+#define status_KSU_mask (0x18) /* mask for KSU bits */
+#define status_KSU_shift (3) /* shift for field */
+#define ksu_kernel (0x0)
+#define ksu_supervisor (0x1)
+#define ksu_user (0x2)
+#define ksu_unknown (0x3)
+
+#define SR_KSU ((SR & status_KSU_mask) >> status_KSU_shift)
+
+#define status_IE (1 << 0) /* Interrupt enable */
+#define status_EIE (1 << 16) /* Enable Interrupt Enable */
+#define status_EXL (1 << 1) /* Exception level */
+#define status_RE (1 << 25) /* Reverse Endian in user mode */
+#define status_FR (1 << 26) /* enables MIPS III additional FP registers */
+#define status_SR (1 << 20) /* soft reset or NMI */
+#define status_BEV (1 << 22) /* Location of general exception vectors */
+#define status_TS (1 << 21) /* TLB shutdown has occurred */
+#define status_ERL (1 << 2) /* Error level */
+#define status_IM7 (1 << 15) /* Timer Interrupt Mask */
+#define status_RP (1 << 27) /* Reduced Power mode */
+
+/* Specializations for TX39 family */
+#define status_IEc (1 << 0) /* Interrupt enable (current) */
+#define status_KUc (1 << 1) /* Kernel/User mode */
+#define status_IEp (1 << 2) /* Interrupt enable (previous) */
+#define status_KUp (1 << 3) /* Kernel/User mode */
+#define status_IEo (1 << 4) /* Interrupt enable (old) */
+#define status_KUo (1 << 5) /* Kernel/User mode */
+#define status_IM_mask (0xff) /* Interrupt mask */
+#define status_IM_shift (8)
+#define status_NMI (1 << 20) /* NMI */
+#define status_NMI (1 << 20) /* NMI */
+
+#define cause_BD ((unsigned)1 << 31) /* L1 Exception in branch delay slot */
+#define cause_BD2 (1 << 30) /* L2 Exception in branch delay slot */
+#define cause_CE_mask 0x30000000 /* Coprocessor exception */
+#define cause_CE_shift 28
+#define cause_EXC2_mask 0x00070000
+#define cause_EXC2_shift 16
+#define cause_IP7 (1 << 15) /* Interrupt pending */
+#define cause_SIOP (1 << 12) /* SIO pending */
+#define cause_IP3 (1 << 11) /* Int 0 pending */
+#define cause_IP2 (1 << 10) /* Int 1 pending */
+
+#define cause_EXC_mask (0x1c) /* Exception code */
+#define cause_EXC_shift (2)
+
+#define cause_SW0 (1 << 8) /* Software interrupt 0 */
+#define cause_SW1 (1 << 9) /* Software interrupt 1 */
+#define cause_IP_mask (0x3f) /* Interrupt pending field */
+#define cause_IP_shift (10)
+
+#define cause_set_EXC(x) CAUSE = (CAUSE & ~cause_EXC_mask) | ((x << cause_EXC_shift) & cause_EXC_mask)
+#define cause_set_EXC2(x) CAUSE = (CAUSE & ~cause_EXC2_mask) | ((x << cause_EXC2_shift) & cause_EXC2_mask)
+
+
+/* NOTE: We keep the following status flags as bit values (1 for true,
+ 0 for false). This allows them to be used in binary boolean
+ operations without worrying about what exactly the non-zero true
+ value is. */
+
+/* UserMode */
+#ifdef SUBTARGET_R3900
+#define UserMode ((SR & status_KUc) ? 1 : 0)
+#else
+#define UserMode ((((SR & status_KSU_mask) >> status_KSU_shift) == ksu_user) ? 1 : 0)
+#endif /* SUBTARGET_R3900 */
+
+/* BigEndianMem */
+/* Hardware configuration. Affects endianness of LoadMemory and
+ StoreMemory and the endianness of Kernel and Supervisor mode
+ execution. The value is 0 for little-endian; 1 for big-endian. */
+#define BigEndianMem (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
+/*(state & simBE) ? 1 : 0)*/
+
+/* ReverseEndian */
+/* This mode is selected if in User mode with the RE bit being set in
+ SR (Status Register). It reverses the endianness of load and store
+ instructions. */
+#define ReverseEndian (((SR & status_RE) && UserMode) ? 1 : 0)
+
+/* BigEndianCPU */
+/* The endianness for load and store instructions (0=little;1=big). In
+ User mode this endianness may be switched by setting the state_RE
+ bit in the SR register. Thus, BigEndianCPU may be computed as
+ (BigEndianMem EOR ReverseEndian). */
+#define BigEndianCPU (BigEndianMem ^ ReverseEndian) /* Already bits */
+
+
+
+/* Exceptions: */
+
+/* NOTE: These numbers depend on the processor architecture being
+ simulated: */
+enum ExceptionCause {
+ Interrupt = 0,
+ TLBModification = 1,
+ TLBLoad = 2,
+ TLBStore = 3,
+ AddressLoad = 4,
+ AddressStore = 5,
+ InstructionFetch = 6,
+ DataReference = 7,
+ SystemCall = 8,
+ BreakPoint = 9,
+ ReservedInstruction = 10,
+ CoProcessorUnusable = 11,
+ IntegerOverflow = 12, /* Arithmetic overflow (IDT monitor raises SIGFPE) */
+ Trap = 13,
+ FPE = 15,
+ DebugBreakPoint = 16,
+ Watch = 23,
+ NMIReset = 31,
+
+
+/* The following exception code is actually private to the simulator
+ world. It is *NOT* a processor feature, and is used to signal
+ run-time errors in the simulator. */
+ SimulatorFault = 0xFFFFFFFF
+};
+
+#define TLB_REFILL (0)
+#define TLB_INVALID (1)
+
+
+/* The following break instructions are reserved for use by the
+ simulator. The first is used to halt the simulation. The second
+ is used by gdb for break-points. NOTE: Care must be taken, since
+ this value may be used in later revisions of the MIPS ISA. */
+#define HALT_INSTRUCTION_MASK (0x03FFFFC0)
+
+#define HALT_INSTRUCTION (0x03ff000d)
+#define HALT_INSTRUCTION2 (0x0000ffcd)
+
+
+#define BREAKPOINT_INSTRUCTION (0x0005000d)
+#define BREAKPOINT_INSTRUCTION2 (0x0000014d)
+
+
+
+void interrupt_event (SIM_DESC sd, void *data);
+
+void signal_exception (SIM_DESC sd, sim_cpu *cpu, address_word cia, int exception, ...);
+#define SignalException(exc,instruction) signal_exception (SD, CPU, cia, (exc), (instruction))
+#define SignalExceptionInterrupt(level) signal_exception (SD, CPU, cia, Interrupt, level)
+#define SignalExceptionInstructionFetch() signal_exception (SD, CPU, cia, InstructionFetch)
+#define SignalExceptionAddressStore() signal_exception (SD, CPU, cia, AddressStore)
+#define SignalExceptionAddressLoad() signal_exception (SD, CPU, cia, AddressLoad)
+#define SignalExceptionDataReference() signal_exception (SD, CPU, cia, DataReference)
+#define SignalExceptionSimulatorFault(buf) signal_exception (SD, CPU, cia, SimulatorFault, buf)
+#define SignalExceptionFPE() signal_exception (SD, CPU, cia, FPE)
+#define SignalExceptionIntegerOverflow() signal_exception (SD, CPU, cia, IntegerOverflow)
+#define SignalExceptionCoProcessorUnusable() signal_exception (SD, CPU, cia, CoProcessorUnusable)
+#define SignalExceptionNMIReset() signal_exception (SD, CPU, cia, NMIReset)
+#define SignalExceptionTLBRefillStore() signal_exception (SD, CPU, cia, TLBStore, TLB_REFILL)
+#define SignalExceptionTLBRefillLoad() signal_exception (SD, CPU, cia, TLBLoad, TLB_REFILL)
+#define SignalExceptionTLBInvalidStore() signal_exception (SD, CPU, cia, TLBStore, TLB_INVALID)
+#define SignalExceptionTLBInvalidLoad() signal_exception (SD, CPU, cia, TLBLoad, TLB_INVALID)
+#define SignalExceptionTLBModification() signal_exception (SD, CPU, cia, TLBModification)
+
+/* Co-processor accesses */
+
+void cop_lw PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int coproc_num, int coproc_reg, unsigned int memword));
+void cop_ld PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int coproc_num, int coproc_reg, uword64 memword));
+unsigned int cop_sw PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int coproc_num, int coproc_reg));
+uword64 cop_sd PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int coproc_num, int coproc_reg));
+
+#define COP_LW(coproc_num,coproc_reg,memword) \
+cop_lw (SD, CPU, cia, coproc_num, coproc_reg, memword)
+#define COP_LD(coproc_num,coproc_reg,memword) \
+cop_ld (SD, CPU, cia, coproc_num, coproc_reg, memword)
+#define COP_SW(coproc_num,coproc_reg) \
+cop_sw (SD, CPU, cia, coproc_num, coproc_reg)
+#define COP_SD(coproc_num,coproc_reg) \
+cop_sd (SD, CPU, cia, coproc_num, coproc_reg)
+
+
+void decode_coproc PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, unsigned int instruction));
+#define DecodeCoproc(instruction) \
+decode_coproc (SD, CPU, cia, (instruction))
+
+void sim_monitor (SIM_DESC sd, sim_cpu *cpu, address_word cia, unsigned int arg);
+
+
+
+/* Memory accesses */
+
+/* The following are generic to all versions of the MIPS architecture
+ to date: */
+
+/* Memory Access Types (for CCA): */
+#define Uncached (0)
+#define CachedNoncoherent (1)
+#define CachedCoherent (2)
+#define Cached (3)
+
+#define isINSTRUCTION (1 == 0) /* FALSE */
+#define isDATA (1 == 1) /* TRUE */
+#define isLOAD (1 == 0) /* FALSE */
+#define isSTORE (1 == 1) /* TRUE */
+#define isREAL (1 == 0) /* FALSE */
+#define isRAW (1 == 1) /* TRUE */
+/* The parameter HOST (isTARGET / isHOST) is ignored */
+#define isTARGET (1 == 0) /* FALSE */
+/* #define isHOST (1 == 1) TRUE */
+
+/* The "AccessLength" specifications for Loads and Stores. NOTE: This
+ is the number of bytes minus 1. */
+#define AccessLength_BYTE (0)
+#define AccessLength_HALFWORD (1)
+#define AccessLength_TRIPLEBYTE (2)
+#define AccessLength_WORD (3)
+#define AccessLength_QUINTIBYTE (4)
+#define AccessLength_SEXTIBYTE (5)
+#define AccessLength_SEPTIBYTE (6)
+#define AccessLength_DOUBLEWORD (7)
+#define AccessLength_QUADWORD (15)
+
+#define LOADDRMASK (WITH_TARGET_WORD_BITSIZE == 64 \
+ ? AccessLength_DOUBLEWORD /*7*/ \
+ : AccessLength_WORD /*3*/)
+#define PSIZE (WITH_TARGET_ADDRESS_BITSIZE)
+
+
+INLINE_SIM_MAIN (int) address_translation PARAMS ((SIM_DESC sd, sim_cpu *, address_word cia, address_word vAddr, int IorD, int LorS, address_word *pAddr, int *CCA, int raw));
+#define AddressTranslation(vAddr,IorD,LorS,pAddr,CCA,host,raw) \
+address_translation (SD, CPU, cia, vAddr, IorD, LorS, pAddr, CCA, raw)
+
+INLINE_SIM_MAIN (void) load_memory PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, uword64* memvalp, uword64* memval1p, int CCA, unsigned int AccessLength, address_word pAddr, address_word vAddr, int IorD));
+#define LoadMemory(memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw) \
+load_memory (SD, CPU, cia, memvalp, memval1p, CCA, AccessLength, pAddr, vAddr, IorD)
+
+INLINE_SIM_MAIN (void) store_memory PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int CCA, unsigned int AccessLength, uword64 MemElem, uword64 MemElem1, address_word pAddr, address_word vAddr));
+#define StoreMemory(CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw) \
+store_memory (SD, CPU, cia, CCA, AccessLength, MemElem, MemElem1, pAddr, vAddr)
+
+INLINE_SIM_MAIN (void) cache_op PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int op, address_word pAddr, address_word vAddr, unsigned int instruction));
+#define CacheOp(op,pAddr,vAddr,instruction) \
+cache_op (SD, CPU, cia, op, pAddr, vAddr, instruction)
+
+INLINE_SIM_MAIN (void) sync_operation PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int stype));
+#define SyncOperation(stype) \
+sync_operation (SD, CPU, cia, (stype))
+
+INLINE_SIM_MAIN (void) prefetch PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int CCA, address_word pAddr, address_word vAddr, int DATA, int hint));
+#define Prefetch(CCA,pAddr,vAddr,DATA,hint) \
+prefetch (SD, CPU, cia, CCA, pAddr, vAddr, DATA, hint)
+
+INLINE_SIM_MAIN (unsigned32) ifetch32 PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, address_word vaddr));
+#define IMEM32(CIA) ifetch32 (SD, CPU, (CIA), (CIA))
+INLINE_SIM_MAIN (unsigned16) ifetch16 PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, address_word vaddr));
+#define IMEM16(CIA) ifetch16 (SD, CPU, (CIA), ((CIA) & ~1))
+#define IMEM16_IMMED(CIA,NR) ifetch16 (SD, CPU, (CIA), ((CIA) & ~1) + 2 * (NR))
+
+void dotrace PARAMS ((SIM_DESC sd, sim_cpu *cpu, FILE *tracefh, int type, SIM_ADDR address, int width, char *comment, ...));
+extern FILE *tracefh;
+
+INLINE_SIM_MAIN (void) pending_tick PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia));
+extern SIM_CORE_SIGNAL_FN mips_core_signal;
+
+char* pr_addr PARAMS ((SIM_ADDR addr));
+char* pr_uword64 PARAMS ((uword64 addr));
+
+
+void mips_cpu_exception_trigger(SIM_DESC sd, sim_cpu* cpu, address_word pc);
+void mips_cpu_exception_suspend(SIM_DESC sd, sim_cpu* cpu, int exception);
+void mips_cpu_exception_resume(SIM_DESC sd, sim_cpu* cpu, int exception);
+
+
+#if H_REVEALS_MODULE_P (SIM_MAIN_INLINE)
+#include "sim-main.c"
+#endif
+
+#endif
diff --git a/sim/mips/tconfig.in b/sim/mips/tconfig.in
new file mode 100644
index 0000000..e8062a3
--- /dev/null
+++ b/sim/mips/tconfig.in
@@ -0,0 +1,31 @@
+/* mips target configuration file. */
+
+/* See sim-hload.c. We properly handle LMA. */
+#ifdef TARGET_TX3904
+#define SIM_HANDLES_LMA 1
+
+/* FIXME: This is unnecessarily necessary: */
+#include "ansidecl.h"
+#include "callback.h"
+#include "remote-sim.h"
+#include "sim-module.h"
+
+MODULE_INSTALL_FN dv_sockser_install;
+#define MODULE_LIST dv_sockser_install,
+#endif
+
+/* Define this if the simulator supports profiling.
+ See the mips simulator for an example.
+ This enables the `-p foo' and `-s bar' options.
+ The target is required to provide sim_set_profile{,_size}. */
+#define SIM_HAVE_PROFILE
+
+/* Define this if the simulator uses an instruction cache.
+ See the h8/300 simulator for an example.
+ This enables the `-c size' option to set the size of the cache.
+ The target is required to provide sim_set_simcache_size. */
+/* #define SIM_HAVE_SIMCACHE */
+
+/* Define this if the target cpu is bi-endian
+ and the simulator supports it. */
+#define SIM_HAVE_BIENDIAN
diff --git a/sim/mips/tx.igen b/sim/mips/tx.igen
new file mode 100644
index 0000000..1727ecc
--- /dev/null
+++ b/sim/mips/tx.igen
@@ -0,0 +1,41 @@
+// -*- C -*-
+//
+// toshiba specific instructions.
+//
+
+011100,5.RS,5.RT,5.RD,00000000000:MMINORM:::MADD
+"madd r<RS>, r<RT>":RD == 0
+"madd r<RD>, r<RS>, r<RT>"
+*r3900
+{
+ signed64 prod = (U8_4 (VL4_8 (HI), VL4_8 (LO))
+ + ((signed64) EXTEND32 (GPR[RT])
+ * (signed64) EXTEND32 (GPR[RS])));
+ check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+ TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
+ LO = EXTEND32 (prod);
+ HI = EXTEND32 (VH4_8 (prod));
+ TRACE_ALU_RESULT2 (HI, LO);
+ if(RD != 0 )
+ GPR[RD] = LO;
+}
+
+
+011100,5.RS,5.RT,5.RD,00000000001:MMINORM:::MADDU
+"maddu r<RS>, r<RT>":RD == 0
+"maddu r<RD>, r<RS>, r<RT>"
+*r3900
+{
+ unsigned64 prod = (U8_4 (VL4_8 (HI), VL4_8 (LO))
+ + ((unsigned64) VL4_8 (GPR[RS])
+ * (unsigned64) VL4_8 (GPR[RT])));
+ check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+ TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
+ LO = EXTEND32 (prod);
+ HI = EXTEND32 (VH4_8 (prod));
+ TRACE_ALU_RESULT2 (HI, LO);
+ if(RD != 0)
+ GPR[RD] = LO;
+}
+
+
diff --git a/sim/mips/vr.igen b/sim/mips/vr.igen
new file mode 100644
index 0000000..863bb55
--- /dev/null
+++ b/sim/mips/vr.igen
@@ -0,0 +1,78 @@
+// -*- C -*-
+//
+// NEC specific instructions
+//
+
+// Integer Instructions
+// --------------------
+//
+// MulAcc is the Multiply Accumulator.
+// This register is mapped on the the HI and LO registers.
+// Upper 32 bits of MulAcc is mapped on to lower 32 bits of HI register.
+// Lower 32 bits of MulAcc is mapped on to lower 32 bits of LO register.
+
+
+:function:::unsigned64:MulAcc:
+*vr4100:
+{
+ unsigned64 result = U8_4 (HI, LO);
+ return result;
+}
+
+:function:::void:SET_MulAcc:unsigned64 value
+*vr4100:
+{
+ /* 64 bit specific */
+ *AL4_8 (&HI) = VH4_8 (value);
+ *AL4_8 (&LO) = VL4_8 (value);
+}
+
+:function:::signed64:SignedMultiply:signed32 l, signed32 r
+*vr4100:
+{
+ signed64 result = (signed64) l * (signed64) r;
+ return result;
+}
+
+:function:::unsigned64:UnsignedMultiply:unsigned32 l, unsigned32 r
+*vr4100:
+{
+ unsigned64 result = (unsigned64) l * (unsigned64) r;
+ return result;
+}
+
+:function:::unsigned64:Low32Bits:unsigned64 value
+*vr4100:
+{
+ unsigned64 result = (signed64) (signed32) VL4_8 (value);
+ return result;
+}
+
+:function:::unsigned64:High32Bits:unsigned64 value
+*vr4100:
+{
+ unsigned64 result = (signed64) (signed32) VH4_8 (value);
+ return result;
+}
+
+
+
+// Multiply, Accumulate
+000000,5.RS,5.RT,00000,00000,101000::64::MAC
+"mac r<RS>, r<RT>"
+*vr4100:
+{
+ SET_MulAcc (SD_, MulAcc (SD_) + SignedMultiply (SD_, GPR[RS], GPR[RT]));
+}
+
+
+// D-Multiply, Accumulate
+000000,5.RS,5.RT,00000,00000,101001::64::DMAC
+"dmac r<RS>, r<RT>"
+*vr4100:
+{
+ LO = LO + SignedMultiply (SD_, GPR[RS], GPR[RT]);
+}
+
+
+