summaryrefslogtreecommitdiff
path: root/sim/d30v/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'sim/d30v/cpu.c')
-rw-r--r--sim/d30v/cpu.c172
1 files changed, 172 insertions, 0 deletions
diff --git a/sim/d30v/cpu.c b/sim/d30v/cpu.c
new file mode 100644
index 00000000000..c14a951c15d
--- /dev/null
+++ b/sim/d30v/cpu.c
@@ -0,0 +1,172 @@
+/* Mitsubishi Electric Corp. D30V Simulator.
+ Copyright (C) 1997, 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 _CPU_C_
+#define _CPU_C_
+
+#include "sim-main.h"
+
+
+int
+is_wrong_slot (SIM_DESC sd,
+ address_word cia,
+ itable_index index)
+{
+ switch (STATE_CPU (sd, 0)->unit)
+ {
+ case memory_unit:
+ return !itable[index].option[itable_option_mu];
+ case integer_unit:
+ return !itable[index].option[itable_option_iu];
+ case any_unit:
+ return 0;
+ default:
+ sim_engine_abort (sd, STATE_CPU (sd, 0), cia,
+ "internal error - is_wrong_slot - bad switch");
+ return -1;
+ }
+}
+
+int
+is_condition_ok (SIM_DESC sd,
+ address_word cia,
+ int cond)
+{
+ switch (cond)
+ {
+ case 0x0:
+ return 1;
+ case 0x1:
+ return PSW_VAL(PSW_F0);
+ case 0x2:
+ return !PSW_VAL(PSW_F0);
+ case 0x3:
+ return PSW_VAL(PSW_F1);
+ case 0x4:
+ return !PSW_VAL(PSW_F1);
+ case 0x5:
+ return PSW_VAL(PSW_F0) && PSW_VAL(PSW_F1);
+ case 0x6:
+ return PSW_VAL(PSW_F0) && !PSW_VAL(PSW_F1);
+ case 0x7:
+ sim_engine_abort (sd, STATE_CPU (sd, 0), cia,
+ "is_condition_ok - bad instruction condition bits");
+ return 0;
+ default:
+ sim_engine_abort (sd, STATE_CPU (sd, 0), cia,
+ "internal error - is_condition_ok - bad switch");
+ return -1;
+ }
+}
+
+/* If --trace-call, trace calls, remembering the current state of
+ registers. */
+
+typedef struct _call_stack {
+ struct _call_stack *prev;
+ registers regs;
+} call_stack;
+
+static call_stack *call_stack_head = (call_stack *)0;
+static int call_depth = 0;
+
+void call_occurred (SIM_DESC sd,
+ sim_cpu *cpu,
+ address_word cia,
+ address_word nia)
+{
+ call_stack *ptr = ZALLOC (call_stack);
+ ptr->regs = cpu->regs;
+ ptr->prev = call_stack_head;
+ call_stack_head = ptr;
+
+ trace_one_insn (sd, cpu, nia, 1, "", 0, "call",
+ "Depth %3d, Return 0x%.8lx, Args 0x%.8lx 0x%.8lx",
+ ++call_depth, (unsigned long)cia+8, (unsigned long)GPR[2],
+ (unsigned long)GPR[3]);
+}
+
+/* If --trace-call, trace returns, checking if any saved register was changed. */
+
+void return_occurred (SIM_DESC sd,
+ sim_cpu *cpu,
+ address_word cia,
+ address_word nia)
+{
+ char buffer[1024];
+ char *buf_ptr = buffer;
+ call_stack *ptr = call_stack_head;
+ int regno;
+ char *prefix = ", Registers that differ: ";
+
+ *buf_ptr = '\0';
+ for (regno = 34; regno <= 63; regno++) {
+ if (cpu->regs.general_purpose[regno] != ptr->regs.general_purpose[regno]) {
+ sprintf (buf_ptr, "%sr%d", prefix, regno);
+ buf_ptr += strlen (buf_ptr);
+ prefix = " ";
+ }
+ }
+
+ if (cpu->regs.accumulator[1] != ptr->regs.accumulator[1]) {
+ sprintf (buf_ptr, "%sa1", prefix);
+ buf_ptr += strlen (buf_ptr);
+ prefix = " ";
+ }
+
+ trace_one_insn (sd, cpu, cia, 1, "", 0, "return",
+ "Depth %3d, Return 0x%.8lx, Ret. 0x%.8lx 0x%.8lx%s",
+ call_depth--, (unsigned long)nia, (unsigned long)GPR[2],
+ (unsigned long)GPR[3], buffer);
+
+ call_stack_head = ptr->prev;
+ zfree (ptr);
+}
+
+
+/* Read/write functions for system call interface. */
+int
+d30v_read_mem (host_callback *cb,
+ struct cb_syscall *sc,
+ unsigned long taddr,
+ char *buf,
+ int bytes)
+{
+ SIM_DESC sd = (SIM_DESC) sc->p1;
+ sim_cpu *cpu = STATE_CPU (sd, 0);
+
+ return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes);
+}
+
+int
+d30v_write_mem (host_callback *cb,
+ struct cb_syscall *sc,
+ unsigned long taddr,
+ const char *buf,
+ int bytes)
+{
+ SIM_DESC sd = (SIM_DESC) sc->p1;
+ sim_cpu *cpu = STATE_CPU (sd, 0);
+
+ return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
+}
+
+#endif /* _CPU_C_ */