aboutsummaryrefslogtreecommitdiff
path: root/sim/sparc/sparc32.c
diff options
context:
space:
mode:
Diffstat (limited to 'sim/sparc/sparc32.c')
-rw-r--r--sim/sparc/sparc32.c568
1 files changed, 0 insertions, 568 deletions
diff --git a/sim/sparc/sparc32.c b/sim/sparc/sparc32.c
deleted file mode 100644
index 6e7205a..0000000
--- a/sim/sparc/sparc32.c
+++ /dev/null
@@ -1,568 +0,0 @@
-/* sparc32 simulator support code
- Copyright (C) 1999 Cygnus Solutions. */
-
-#define WANT_CPU sparc32
-#define WANT_CPU_SPARC32
-
-#include "sim-main.h"
-#include <signal.h>
-#include "libiberty.h"
-#include "bfd.h"
-#include "cgen-mem.h"
-#include "cgen-ops.h"
-#include "targ-vals.h"
-
-static void sparc32_init_regwins (SIM_CPU *current_cpu);
-static void sparc32_set_psr_no_cwp (SIM_CPU *current_cpu, USI newval);
-
-/* gdb register access support.
- The contents of BUF are in target byte order. */
-
-int
-sparc32_fetch_register (SIM_CPU *current_cpu, int rn, unsigned char *buf, int len)
-{
- if (rn < 32)
- {
- SETTSI (buf, a_sparc_h_gr_get (current_cpu, rn));
- }
- else
- switch (rn)
- {
- case SPARC32_PC_REGNUM :
- SETTSI (buf, a_sparc_h_pc_get (current_cpu));
- break;
- case SPARC32_NPC_REGNUM :
- {
- USI npc = a_sparc_h_npc_get (current_cpu);
-#if 0 /* experiment */
- if (npc == NPC_NO_DELAY_INSN)
- npc = a_sparc_h_pc_get (current_cpu) + 4;
-#endif
- SETTSI (buf, npc);
- break;
- }
- default :
- return 0;
- }
-
- return -1; /*FIXME*/
-}
-
-/* gdb register access support.
- The contents of BUF are in target byte order. */
-
-int
-sparc32_store_register (SIM_CPU *current_cpu, int rn, unsigned char *buf, int len)
-{
- if (rn < 32)
- {
- a_sparc_h_gr_set (current_cpu, rn, GETTSI (buf));
- }
- else
- switch (rn)
- {
- case SPARC32_PC_REGNUM :
- a_sparc_h_pc_set (current_cpu, GETTSI (buf));
- break;
- case SPARC32_NPC_REGNUM :
- a_sparc_h_npc_set (current_cpu, GETTSI (buf));
- break;
- default :
- return 0;
- }
-
- return -1; /*FIXME*/
-}
-
-/* Initialization. */
-
-/* Initialize the program counter. */
-
-void
-sparc32_init_pc (SIM_CPU *current_cpu, SI pc, SI npc)
-{
- SET_H_PC (pc);
- SET_H_NPC (npc);
-}
-
-/* Do a pseudo power-on-reset.
- USERLAND_P is non-zero to prepare to run a user-land program. */
-
-void
-sparc32_cold_reset (SIM_CPU *current_cpu, int userland_p)
-{
- int i;
-
- /* Initialize the PSR.
- This has to be careful as we just want to initialize the CWP, we don't
- want to "set" it (which causes the old window to be "swapped out").
- ??? impl,ver need better values. */
- sparc32_set_psr_no_cwp (current_cpu, 0 | PSR_S);
-
- /* Initialize cwp directly (bypassing SET_H_CWP and SET_H_PSR) as we just
- want to initialize things, not "swap" the current window out. */
- CPU (h_cwp) = 0;
- sparc32_init_regwins (current_cpu);
-
- /* Mark the last window as invalid. This creates a distinguishable end
- of register window stack. The last window is window 1 (mask 2) as
- saves decrement CWP.
- Note that the last and first window overlap. */
- SET_H_WIM (2);
-
- sparc32_init_pc (current_cpu, 0, 4);
-
- for (i = 0; i < 32; ++i)
- SET_H_GR (i, 0);
- SET_H_FSR (0);
-}
-
-/* Do a warm reset (the reset trap). */
-
-void
-sparc32_warm_reset (SIM_CPU *current_cpu)
-{
- /* FIXME: unimplemented yet */
-}
-
-/* Special purpose registers. */
-
-/* The PSR.
- ??? add ability to specify a register as a set of bitfields. */
-
-USI
-sparc32_get_h_psr_handler (SIM_CPU *current_cpu)
-{
- USI val;
- val = CPU (h_psr) & (PSR_IMPL | PSR_VER);
- val |= GET_H_ICC_C () ? PSR_C : 0;
- val |= GET_H_ICC_N () ? PSR_N : 0;
- val |= GET_H_ICC_V () ? PSR_V : 0;
- val |= GET_H_ICC_Z () ? PSR_Z : 0;
- val |= GET_H_EC () ? PSR_EC : 0;
- val |= GET_H_EF () ? PSR_EF : 0;
- val |= (GET_H_PIL () & 0xf) << 8;
- val |= GET_H_S () ? PSR_S : 0;
- val |= GET_H_PS () ? PSR_PS : 0;
- val |= GET_H_ET () ? PSR_ET : 0;
- val |= GET_H_CWP ();
- return val;
-}
-
-/* Utility to set everything in the PSR except CWP
- (needed by sparc32_cold_reset). */
-
-static void
-sparc32_set_psr_no_cwp (SIM_CPU *current_cpu, USI newval)
-{
- SET_H_ICC_C ((newval & PSR_C) != 0);
- SET_H_ICC_N ((newval & PSR_N) != 0);
- SET_H_ICC_V ((newval & PSR_V) != 0);
- SET_H_ICC_Z ((newval & PSR_Z) != 0);
- SET_H_EC ((newval & PSR_EC) != 0);
- SET_H_EF ((newval & PSR_EF) != 0);
- SET_H_PIL ((newval & PSR_PIL) >> 8);
- SET_H_S ((newval & PSR_S) != 0);
- SET_H_PS ((newval & PSR_PS) != 0);
- SET_H_ET ((newval & PSR_ET) != 0);
-}
-
-void
-sparc32_set_h_psr_handler (SIM_CPU *current_cpu, USI newval)
-{
- sparc32_set_psr_no_cwp (current_cpu, newval);
- SET_H_CWP (newval & PSR_CWP);
-}
-
-/* Register window support. */
-
-/* Allocate space for the register window mechanism.
- This version doesn't have much to do.
- Other register window implementations have more to do. */
-
-void
-sparc32_alloc_regwins (SIM_CPU *current_cpu, int nwindows)
-{
- /* nothing to do in current window implementation */
-}
-
-void
-sparc32_free_regwins (SIM_CPU *current_cpu)
-{
- /* nothing to do in current window implementation */
-}
-
-/* Initialize the register window control registers for running
- user programs. */
-
-static void
-sparc32_init_regwins (SIM_CPU *current_cpu)
-{
- /* nothing to do in current window implementation */
-}
-
-/* Assign a new value to CWP.
- SET_H_CWP calls this.
-
- This swaps out the current values of the o/l/i regs from `current_regs'
- and swaps in the new values. */
-
-void
-sparc32_set_h_cwp_handler (SIM_CPU *current_cpu, int new)
-{
- int old = GET_H_CWP ();
-
- if (new < 0 || new >= GET_NWINDOWS ())
- abort ();
-
- CPU (h_cwp) = new;
-
- /* Swap current values out of `current_regs'.
- Do this even if old == new. */
- sparc32_swapout_regwin (current_cpu, old);
-
- /* Swap new values into `current_regs'. */
- if (old != new)
- sparc32_swapin_regwin (current_cpu, new);
-}
-
-/* Swap out the values in `current_regs'. */
-
-void
-sparc32_swapout_regwin (SIM_CPU *current_cpu, int win)
-{
- int n = 8 * sizeof (SI);
-
- memcpy (REAL_OREGS (current_cpu, win), CURRENT_OREGS (current_cpu), n);
- memcpy (REAL_LREGS (current_cpu, win), CURRENT_LREGS (current_cpu), n);
- memcpy (REAL_IREGS (current_cpu, win), CURRENT_IREGS (current_cpu), n);
-}
-
-/* Swap int values for `current_regs'. */
-
-void
-sparc32_swapin_regwin (SIM_CPU *current_cpu, int win)
-{
- int n = 8 * sizeof (SI);
-
- memcpy (CURRENT_OREGS (current_cpu), REAL_OREGS (current_cpu, win), n);
- memcpy (CURRENT_LREGS (current_cpu), REAL_LREGS (current_cpu, win), n);
- memcpy (CURRENT_IREGS (current_cpu), REAL_IREGS (current_cpu, win), n);
-}
-
-/* Create a new window. We assume there is room. */
-
-void
-sparc32_save_regwin (SIM_CPU *current_cpu)
-{
- SET_H_CWP (NEXT_WIN (GET_H_CWP ()));
-}
-
-/* Pop a window. We assume no traps possible. */
-
-void
-sparc32_restore_regwin (SIM_CPU *current_cpu)
-{
- SET_H_CWP (PREV_WIN (GET_H_CWP ()));
-}
-
-/* Flush the register windows to memory.
- This is necessary, for example, when we want to walk the stack in gdb.
- NO_ERRORS_P is non-zero if memory faults must be avoided. This is important
- when returning to gdb, the processor has "stopped".
-
- ??? At present we only handle user programs. */
-
-void
-sparc32_flush_regwins (SIM_CPU *current_cpu, IADDR pc, int no_errors_p)
-{
- int i, win;
- int count = GET_NWINDOWS ();
-
- /* Flush the current window cache. */
- sparc32_swapout_regwin (current_cpu, GET_H_CWP ());
-
- /* For each register window that is marked valid, flush it to memory.
- We start at the current window and move upwards on the stack. */
-
- for (i = 0, win = GET_H_CWP (); i < count; i++, win = PREV_WIN (win))
- {
- /* Don't go passed an invalid window. */
- if (! WINDOW_VALID_P (win, GET_H_WIM ()))
- break;
- sparc32_flush_regwin (current_cpu, pc, win, no_errors_p);
- }
-}
-
-void
-sparc32_flush_regwin (SIM_CPU *cpu, IADDR pc, int win, int no_errors_p)
-{
- int i;
- USI sp,fp,addr;
- /* Fetch pointers to lregs and iregs for this frame. */
- SI *lregs = REAL_LREGS (cpu, win);
- SI *iregs = REAL_IREGS (cpu, win);
- SIM_DESC sd = CPU_STATE (cpu);
-
- /* Fetch values of sp,fp for this frame. */
- sp = REAL_OREGS (cpu, win) [6];
- fp = REAL_IREGS (cpu, win) [6];
-
- /* Exit early if there'd be a memory fault but we can't have any errors. */
- if (no_errors_p)
- {
- /* Check if sp and fp indicate a proper save may not have been done. */
- if (fp <= sp
- || fp - sp < 8 * sizeof (SI))
- return;
- /* sp misaligned? */
- if (sp & 3)
- return;
- }
-
- /* Use sim_core_write_aligned_N here to handle endian conversions. */
-
- addr = sp;
- for (i = 0; i < 8; i++)
- {
- if (no_errors_p)
- {
- char reg[4];
- SETTSI (reg, lregs[i]);
- if (sim_core_write_buffer (sd, cpu, write_map, reg, addr, 4) == 0)
- return;
- }
- else
- sim_core_write_aligned_4 (cpu, pc, write_map, addr, lregs[i]);
- addr += 4;
- }
- for (i = 0; i < 8; i++)
- {
- if (no_errors_p)
- {
- char reg[4];
- SETTSI (reg, lregs[i]);
- if (sim_core_write_buffer (sd, cpu, write_map, reg, addr, 4) == 0)
- return;
- }
- else
- sim_core_write_aligned_4 (cpu, pc, write_map, addr, iregs[i]);
- addr += 4;
- }
-}
-
-void
-sparc32_load_regwin (SIM_CPU *cpu, IADDR pc, int win)
-{
- int i;
- /* Fetch value of sp for this frame. */
- SI addr = REAL_OREGS (cpu, win) [6];
- /* Fetch pointers to lregs and iregs for this frame. */
- SI *lregs = REAL_LREGS (cpu, win);
- SI *iregs = REAL_IREGS (cpu, win);
-
- /* Use sim_core_read_aligned_N here to handle endian conversions. */
-
- for (i = 0; i < 8; i++)
- {
- lregs[i] = sim_core_read_aligned_4 (cpu, pc, read_map, addr);
- addr += 4;
- }
- for (i = 0; i < 8; i++)
- {
- iregs[i] = sim_core_read_aligned_4 (cpu, pc, read_map, addr);
- addr += 4;
- }
-}
-
-/* Save/restore insns. */
-
-/* Handle the save instruction. */
-
-SI
-sparc32_do_save (SIM_CPU *current_cpu, IADDR pc, SI rs1, SI rs2_simm13)
-{
- SI rd;
- int oldwin,newwin,wim;
-
- /* FIXME: Watch for stack overflow if user prog. */
-
- /* Determine new window number and see if its bit is set in the
- Window Invalid Mask. */
- oldwin = GET_H_CWP ();
- newwin = NEXT_WIN (oldwin);
- wim = GET_H_WIM ();
- if (! WINDOW_VALID_P (newwin, wim))
- sparc32_window_overflow (current_cpu, pc);
-
- /* `rs1' and `rs2_simm13' are based on the old window (which we want) */
- rd = rs1 + rs2_simm13;
-
- /* Switch to the new window. */
- sparc32_save_regwin (current_cpu);
-
- if (TRACE_INSN_P (current_cpu)) /* FIXME */
- {
- trace_result (current_cpu, "sp", 'x', GET_H_GR (H_GR__SP));
- trace_result (current_cpu, "fp", 'x', GET_H_GR (H_GR__FP));
- trace_result (current_cpu, "cwp", 'x', GET_H_CWP ());
- }
-
- /* `rd' will be saved in the new window by the semantic code. */
- return rd;
-}
-
-/* Handle the restore instruction. */
-
-SI
-sparc32_do_restore (SIM_CPU *current_cpu, IADDR pc, SI rs1, SI rs2_simm13)
-{
- SI rd;
- int oldwin,newwin,wim;
-
- /* Determine new window number and see if its bit is set in the
- Window Invalid Mask. */
- oldwin = GET_H_CWP ();
- newwin = PREV_WIN (oldwin);
- wim = GET_H_WIM ();
- if (! WINDOW_VALID_P (newwin, wim))
- sparc32_window_underflow (current_cpu, pc);
-
- /* `rs1' and `rs2_simm13' are based on the old window (which we want) */
- rd = rs1 + rs2_simm13;
-
- /* Switch to the previous window. */
- sparc32_restore_regwin (current_cpu);
-
- if (TRACE_INSN_P (current_cpu)) /* FIXME */
- {
- trace_result (current_cpu, "sp", 'x', GET_H_GR (H_GR__SP));
- trace_result (current_cpu, "fp", 'x', GET_H_GR (H_GR__FP));
- trace_result (current_cpu, "cwp", 'x', GET_H_CWP ());
- }
-
- /* `rd' will be saved in the new window by the semantic code. */
- return rd;
-}
-
-/* ASI accesses. */
-
-#define DEFINE_GETMEM(mode, size) \
-mode \
-XCONCAT3 (GETMEM,mode,ASI) (SIM_CPU *cpu, IADDR pc, ADDR a, INT asi) \
-{ \
- return 0; /* FIXME:wip */ \
-}
-
-DEFINE_GETMEM (QI, 1)
-DEFINE_GETMEM (UQI, 1)
-DEFINE_GETMEM (HI, 2)
-DEFINE_GETMEM (UHI, 2)
-DEFINE_GETMEM (SI, 4)
-DEFINE_GETMEM (USI, 4)
-DEFINE_GETMEM (DI, 8)
-DEFINE_GETMEM (UDI, 8)
-
-#undef DEFINE_GETMEM
-
-#define DEFINE_SETMEM(mode, size) \
-void \
-XCONCAT3 (SETMEM,mode,ASI) (SIM_CPU *cpu, IADDR pc, ADDR a, INT asi, mode newval) \
-{ \
- return; /* FIXME:wip */ \
-}
-
-DEFINE_SETMEM (QI, 1)
-DEFINE_SETMEM (UQI, 1)
-DEFINE_SETMEM (HI, 2)
-DEFINE_SETMEM (UHI, 2)
-DEFINE_SETMEM (SI, 4)
-DEFINE_SETMEM (USI, 4)
-DEFINE_SETMEM (DI, 8)
-DEFINE_SETMEM (UDI, 8)
-
-#undef SETMEM
-
-/* ldstub, swap insns */
-
-void
-sparc32_do_ldstub (SIM_CPU *current_cpu, IADDR pc, INT rd_regno,
- SI rs1, SI rs2_simm13, INT asi)
-{
-}
-
-void
-sparc32_do_swap (SIM_CPU *current_cpu, IADDR pc, INT rd_regno,
- SI rs1, SI rs2_simm13, INT asi)
-{
-}
-
-/* Profiling support. */
-
-#if WITH_PROFILE_MODEL_P
-
-/* FIXME: Some of these should be inline or macros. Later. */
-
-void
-sparc32_model_mark_get_h_gr (SIM_CPU *cpu, ARGBUF *abuf)
-{
-}
-
-void
-sparc32_model_mark_set_h_gr (SIM_CPU *cpu, ARGBUF *abuf)
-{
-}
-
-void
-sparc32_model_mark_busy_reg (SIM_CPU *cpu, ARGBUF *abuf)
-{
-}
-
-void
-sparc32_model_mark_unbusy_reg (SIM_CPU *cpu, ARGBUF *abuf)
-{
-}
-
-/* Initialize cycle counting for an insn.
- FIRST_P is non-zero if this is the first insn in a set of parallel
- insns. */
-
-void
-sparc32_model_insn_before (SIM_CPU *cpu, int first_p)
-{
-}
-
-/* Record the cycles computed for an insn.
- LAST_P is non-zero if this is the last insn in a set of parallel insns,
- and we update the total cycle count.
- CYCLES is the cycle count of the insn. */
-
-void
-sparc32_model_insn_after (SIM_CPU *cpu, int last_p, int cycles)
-{
-}
-
-int
-sparc32_model_sparc32_def_u_exec (SIM_CPU *cpu, const IDESC *idesc,
- int unit_num, int referenced)
-{
- return idesc->timing->units[unit_num].done;
-}
-
-#endif /* WITH_PROFILE_MODEL_P */
-
-/* Debugging stuff. */
-
-/* Pretty print the control and integer registers.
- This can be invoked with the user-defined "dump" command in gdb. */
-
-void
-sim_debug_dump ()
-{
- extern SIM_DESC current_state;
- host_callback *cb = STATE_CALLBACK (current_state);
- SIM_CPU *current_cpu = STATE_CPU (current_state, 0);
-
- sim_cb_printf (cb, "CPU Registers\n");
- sim_cb_printf (cb, "CWP:%4d WIM:%4d\n", GET_H_CWP (), GET_H_WIM ());
-}