* Makefile.in : Add new machine m32r2.
* m32r2.c : New file for m32r2.
* mloop2.in : Ditto
* model2.c : Ditto
* sem2-switch.c : Ditto
* m32r-sim.h : Add EVB register.
* sim-if.h : Ditto
* sim-main.h : Ditto
* traps.c : Ditto
+2003-12-02 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * Makefile.in : Add new machine m32r2.
+ * m32r2.c : New file for m32r2.
+ * mloop2.in : Ditto
+ * model2.c : Ditto
+ * sem2-switch.c : Ditto
+ * m32r-sim.h : Add EVB register.
+ * sim-if.h : Ditto
+ * sim-main.h : Ditto
+ * traps.c : Ditto
+
2003-09-08 Dave Brolley <brolley@redhat.com>
On behalf of Doug Evans <dje@sebabeach.org>
M32R_OBJS = m32r.o cpu.o decode.o sem.o model.o mloop.o
M32RX_OBJS = m32rx.o cpux.o decodex.o modelx.o mloopx.o
+M32R2_OBJS = m32r2.o cpu2.o decode2.o model2.o mloop2.o
CONFIG_DEVICES = dv-sockser.o
CONFIG_DEVICES =
sim-if.o arch.o \
$(M32R_OBJS) \
$(M32RX_OBJS) \
+ $(M32R2_OBJS) \
traps.o devices.o \
$(CONFIG_DEVICES)
semx.o: semx.c $(M32RXF_INCLUDE_DEPS)
modelx.o: modelx.c $(M32RXF_INCLUDE_DEPS)
+# M32R2 objs
+
+M32R2F_INCLUDE_DEPS = \
+ $(CGEN_MAIN_CPU_DEPS) \
+ cpu2.h decode2.h eng2.h
+
+m32r2.o: m32r2.c $(M32R2F_INCLUDE_DEPS)
+
+# FIXME: Use of `mono' is wip.
+mloop2.c eng2.h: stamp-2mloop
+stamp-2mloop: $(srcdir)/../common/genmloop.sh mloop2.in Makefile
+ $(SHELL) $(srccom)/genmloop.sh \
+ -mono -no-fast -pbb -parallel-write -switch sem2-switch.c \
+ -cpu m32r2f -infile $(srcdir)/mloop2.in
+ $(SHELL) $(srcroot)/move-if-change eng.hin eng2.h
+ $(SHELL) $(srcroot)/move-if-change mloop.cin mloop2.c
+ touch stamp-2mloop
+mloop2.o: mloop2.c sem2-switch.c $(M32R2F_INCLUDE_DEPS)
+
+cpu2.o: cpu2.c $(M32R2F_INCLUDE_DEPS)
+decode2.o: decode2.c $(M32R2F_INCLUDE_DEPS)
+sem2.o: sem2.c $(M32R2F_INCLUDE_DEPS)
+model2.o: model2.c $(M32R2F_INCLUDE_DEPS)
+
m32r-clean:
rm -f mloop.c eng.h stamp-mloop
rm -f mloopx.c engx.h stamp-xmloop
- rm -f stamp-arch stamp-cpu stamp-xcpu
+ rm -f mloop2.c eng2.h stamp-2mloop
+ rm -f stamp-arch stamp-cpu stamp-xcpu stamp-2cpu
rm -f tmp-*
# cgen support, enable with --enable-cgen-maint
EXTRAFILES="$(CGEN_CPU_SEMSW)"
touch stamp-xcpu
cpux.h semx-switch.c modelx.c decodex.c decodex.h: $(CGEN_MAINT) stamp-xcpu
+
+stamp-2cpu: $(CGEN_READ_SCM) $(CGEN_CPU_SCM) $(CGEN_DECODE_SCM) $(CGEN_CPU_DIR)/m32r.cpu
+ $(MAKE) cgen-cpu-decode $(CGEN_FLAGS_TO_PASS) \
+ cpu=m32r2f mach=m32r2 SUFFIX=2 \
+ archfile=$(CGEN_CPU_DIR)/m32r.cpu \
+ FLAGS="with-scache with-profile=fn" \
+ EXTRAFILES="$(CGEN_CPU_SEMSW)"
+ touch stamp-2cpu
+cpu2.h sem2-switch.c model2.c decode2.c decode2.h: $(CGEN_MAINT) stamp-2cpu
+
#define ACC1H_REGNUM 25
#define BBPSW_REGNUM 26
#define BBPC_REGNUM 27
+#define EVB_REGNUM 28
extern int m32r_decode_gdb_ctrl_regnum (int);
FIXME: Eventually move to cgen. */
#define GET_H_SM() ((CPU (h_psw) & 0x80) != 0)
+extern SI a_m32r_h_gr_get (SIM_CPU *, UINT);
+extern void a_m32r_h_gr_set (SIM_CPU *, UINT, SI);
+extern USI a_m32r_h_cr_get (SIM_CPU *, UINT);
+extern void a_m32r_h_cr_set (SIM_CPU *, UINT, USI);
+
extern USI m32rbf_h_cr_get_handler (SIM_CPU *, UINT);
extern void m32rbf_h_cr_set_handler (SIM_CPU *, UINT, USI);
-#define GET_H_CR(regno) \
- XCONCAT2 (WANT_CPU,_h_cr_get_handler) (current_cpu, (regno))
-#define SET_H_CR(regno, val) \
- XCONCAT2 (WANT_CPU,_h_cr_set_handler) (current_cpu, (regno), (val))
extern UQI m32rbf_h_psw_get_handler (SIM_CPU *);
extern void m32rbf_h_psw_set_handler (SIM_CPU *, UQI);
-#define GET_H_PSW() \
- XCONCAT2 (WANT_CPU,_h_psw_get_handler) (current_cpu)
-#define SET_H_PSW(val) \
- XCONCAT2 (WANT_CPU,_h_psw_set_handler) (current_cpu, (val))
extern DI m32rbf_h_accum_get_handler (SIM_CPU *);
extern void m32rbf_h_accum_set_handler (SIM_CPU *, DI);
-#define GET_H_ACCUM() \
- XCONCAT2 (WANT_CPU,_h_accum_get_handler) (current_cpu)
-#define SET_H_ACCUM(val) \
- XCONCAT2 (WANT_CPU,_h_accum_set_handler) (current_cpu, (val))
+extern USI m32rxf_h_cr_get_handler (SIM_CPU *, UINT);
+extern void m32rxf_h_cr_set_handler (SIM_CPU *, UINT, USI);
+extern UQI m32rxf_h_psw_get_handler (SIM_CPU *);
+extern void m32rxf_h_psw_set_handler (SIM_CPU *, UQI);
+extern DI m32rxf_h_accum_get_handler (SIM_CPU *);
+extern void m32rxf_h_accum_set_handler (SIM_CPU *, DI);
+
+extern DI m32rxf_h_accums_get_handler (SIM_CPU *, UINT);
+extern void m32rxf_h_accums_set_handler (SIM_CPU *, UINT, DI);
\f
/* Misc. profile data. */
\f
/* Additional execution support. */
+/* Result of semantic function is one of
+ - next address, branch only
+ - NEW_PC_SKIP, sc/snc insn
+ - NEW_PC_2, 2 byte non-branch non-sc/snc insn
+ - NEW_PC_4, 4 byte non-branch insn
+ The special values have bit 1 set so it's cheap to distinguish them.
+ This works because all cti's are defined to zero the bottom two bits
+ Note that the m32rx no longer doesn't implement its semantics with
+ functions, so this isn't used. It's kept around should it be needed
+ again. */
+/* FIXME: replace 0xffff0001 with 1? */
+#define NEW_PC_BASE 0xffff0001
+#define NEW_PC_SKIP NEW_PC_BASE
+#define NEW_PC_2 (NEW_PC_BASE + 2)
+#define NEW_PC_4 (NEW_PC_BASE + 4)
+#define NEW_PC_BRANCH_P(addr) (((addr) & 1) == 0)
+
+/* Modify "next pc" support to handle parallel execution.
+ This is for the non-pbb case. The m32rx no longer implements this.
+ It's kept around should it be needed again. */
+#if defined (WANT_CPU_M32RXF) && ! WITH_SCACHE_PBB_M32RXF
+#undef SEM_NEXT_VPC
+#define SEM_NEXT_VPC(abuf, len) (NEW_PC_BASE + (len))
+#undef SEM_SKIP_INSN
+#define SEM_SKIP_INSN(cpu, sc, vpcvar, yes) FIXME
+#endif
\f
/* Hardware/device support.
??? Will eventually want to move device stuff to config files. */
/* Start address and length of all device support. */
#define M32R_DEVICE_ADDR 0xff000000
-#define M32R_DEVICE_LEN 0x00ffffff
+#define M32R_DEVICE_LEN 0x01000000
/* sim_core_attach device argument. */
extern device m32r_devices;
case BPC_REGNUM : return H_CR_BPC;
case BBPSW_REGNUM : return H_CR_BBPSW;
case BBPC_REGNUM : return H_CR_BBPC;
+ case EVB_REGNUM : return H_CR_CR5;
}
abort ();
}
int
m32rbf_fetch_register (SIM_CPU *current_cpu, int rn, unsigned char *buf, int len)
{
+ int mach = MACH_NUM (CPU_MACH (current_cpu));
+
if (rn < 16)
SETTWI (buf, a_m32r_h_gr_get (current_cpu, rn));
else
case BPC_REGNUM :
case BBPSW_REGNUM :
case BBPC_REGNUM :
+ case EVB_REGNUM :
SETTWI (buf, a_m32r_h_cr_get (current_cpu,
m32r_decode_gdb_ctrl_regnum (rn)));
break;
case PC_REGNUM :
- SETTWI (buf, a_m32r_h_pc_get (current_cpu));
+ if (mach == MACH_M32R)
+ SETTWI (buf, m32rbf_h_pc_get (current_cpu));
+ else if (mach == MACH_M32RX)
+ SETTWI (buf, m32rxf_h_pc_get (current_cpu));
+ else
+ SETTWI (buf, m32r2f_h_pc_get (current_cpu));
break;
case ACCL_REGNUM :
- SETTWI (buf, GETLODI (a_m32r_h_accum_get (current_cpu)));
+ if (mach == MACH_M32R)
+ SETTWI (buf, GETLODI (m32rbf_h_accum_get (current_cpu)));
+ else if (mach == MACH_M32RX)
+ SETTWI (buf, GETLODI (m32rxf_h_accum_get (current_cpu)));
+ else
+ SETTWI (buf, GETLODI (m32r2f_h_accum_get (current_cpu)));
break;
case ACCH_REGNUM :
- SETTWI (buf, GETHIDI (a_m32r_h_accum_get (current_cpu)));
+ if (mach == MACH_M32R)
+ SETTWI (buf, GETHIDI (m32rbf_h_accum_get (current_cpu)));
+ else if (mach == MACH_M32RX)
+ SETTWI (buf, GETHIDI (m32rxf_h_accum_get (current_cpu)));
+ else
+ SETTWI (buf, GETHIDI (m32r2f_h_accum_get (current_cpu)));
break;
default :
return 0;
int
m32rbf_store_register (SIM_CPU *current_cpu, int rn, unsigned char *buf, int len)
{
+ int mach = MACH_NUM (CPU_MACH (current_cpu));
+
if (rn < 16)
a_m32r_h_gr_set (current_cpu, rn, GETTWI (buf));
else
case BPC_REGNUM :
case BBPSW_REGNUM :
case BBPC_REGNUM :
+ case EVB_REGNUM :
a_m32r_h_cr_set (current_cpu,
m32r_decode_gdb_ctrl_regnum (rn),
GETTWI (buf));
break;
case PC_REGNUM :
- a_m32r_h_pc_set (current_cpu, GETTWI (buf));
+ if (mach == MACH_M32R)
+ m32rbf_h_pc_set (current_cpu, GETTWI (buf));
+ else if (mach == MACH_M32RX)
+ m32rxf_h_pc_set (current_cpu, GETTWI (buf));
+ else
+ m32r2f_h_pc_set (current_cpu, GETTWI (buf));
break;
case ACCL_REGNUM :
{
- DI val = a_m32r_h_accum_get (current_cpu);
+ DI val;
+ if (mach == MACH_M32R)
+ val = m32rbf_h_accum_get (current_cpu);
+ else if (mach == MACH_M32RX)
+ val = m32rxf_h_accum_get (current_cpu);
+ else
+ val = m32r2f_h_accum_get (current_cpu);
SETLODI (val, GETTWI (buf));
- a_m32r_h_accum_set (current_cpu, val);
+ if (mach == MACH_M32R)
+ m32rbf_h_accum_set (current_cpu, val);
+ else if (mach == MACH_M32RX)
+ m32rxf_h_accum_set (current_cpu, val);
+ else
+ m32r2f_h_accum_set (current_cpu, val);
break;
}
case ACCH_REGNUM :
{
- DI val = a_m32r_h_accum_get (current_cpu);
+ DI val;
+ if (mach == MACH_M32R)
+ val = m32rbf_h_accum_get (current_cpu);
+ else if (mach == MACH_M32RX)
+ val = m32rxf_h_accum_get (current_cpu);
+ else
+ val = m32r2f_h_accum_get (current_cpu);
SETHIDI (val, GETTWI (buf));
- a_m32r_h_accum_set (current_cpu, val);
+ if (mach == MACH_M32R)
+ m32rbf_h_accum_set (current_cpu, val);
+ else if (mach == MACH_M32RX)
+ m32rxf_h_accum_set (current_cpu, val);
+ else
+ m32r2f_h_accum_set (current_cpu, val);
break;
}
default :
return -1; /*FIXME*/
}
\f
+/* Cover fns for mach independent register accesses. */
+
+SI
+a_m32r_h_gr_get (SIM_CPU *current_cpu, UINT regno)
+{
+ switch (MACH_NUM (CPU_MACH (current_cpu)))
+ {
+#ifdef HAVE_CPU_M32RBF
+ case MACH_M32R :
+ return m32rbf_h_gr_get (current_cpu, regno);
+#endif
+#ifdef HAVE_CPU_M32RXF
+ case MACH_M32RX :
+ return m32rxf_h_gr_get (current_cpu, regno);
+#endif
+#ifdef HAVE_CPU_M32R2F
+ case MACH_M32R2 :
+ return m32r2f_h_gr_get (current_cpu, regno);
+#endif
+ default :
+ abort ();
+ }
+}
+
+void
+a_m32r_h_gr_set (SIM_CPU *current_cpu, UINT regno, SI newval)
+{
+ switch (MACH_NUM (CPU_MACH (current_cpu)))
+ {
+#ifdef HAVE_CPU_M32RBF
+ case MACH_M32R :
+ m32rbf_h_gr_set (current_cpu, regno, newval);
+ break;
+#endif
+#ifdef HAVE_CPU_M32RXF
+ case MACH_M32RX :
+ m32rxf_h_gr_set (current_cpu, regno, newval);
+ break;
+#endif
+#ifdef HAVE_CPU_M32RXF
+ case MACH_M32R2 :
+ m32r2f_h_gr_set (current_cpu, regno, newval);
+ break;
+#endif
+ default :
+ abort ();
+ }
+}
+
+USI
+a_m32r_h_cr_get (SIM_CPU *current_cpu, UINT regno)
+{
+ switch (MACH_NUM (CPU_MACH (current_cpu)))
+ {
+#ifdef HAVE_CPU_M32RBF
+ case MACH_M32R :
+ return m32rbf_h_cr_get (current_cpu, regno);
+#endif
+#ifdef HAVE_CPU_M32RXF
+ case MACH_M32RX :
+ return m32rxf_h_cr_get (current_cpu, regno);
+#endif
+#ifdef HAVE_CPU_M32R2F
+ case MACH_M32R2 :
+ return m32r2f_h_cr_get (current_cpu, regno);
+#endif
+ default :
+ abort ();
+ }
+}
+
+void
+a_m32r_h_cr_set (SIM_CPU *current_cpu, UINT regno, USI newval)
+{
+ switch (MACH_NUM (CPU_MACH (current_cpu)))
+ {
+#ifdef HAVE_CPU_M32RBF
+ case MACH_M32R :
+ m32rbf_h_cr_set (current_cpu, regno, newval);
+ break;
+#endif
+#ifdef HAVE_CPU_M32RXF
+ case MACH_M32RX :
+ m32rxf_h_cr_set (current_cpu, regno, newval);
+ break;
+#endif
+#ifdef HAVE_CPU_M32RXF
+ case MACH_M32R2 :
+ m32r2f_h_cr_set (current_cpu, regno, newval);
+ break;
+#endif
+ default :
+ abort ();
+ }
+}
+\f
USI
m32rbf_h_cr_get_handler (SIM_CPU *current_cpu, UINT cr)
{
PROFILE_LABEL_WIDTH, "Parallel insns:",
sim_add_commas (buf, sizeof (buf),
CPU_M32R_MISC_PROFILE (cpu)->parallel_count));
+ if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_m32r2)
+ sim_io_printf (sd, " %-*s %s\n\n",
+ PROFILE_LABEL_WIDTH, "Parallel insns:",
+ sim_add_commas (buf, sizeof (buf),
+ CPU_M32R_MISC_PROFILE (cpu)->parallel_count));
}
}
+
/* Main header for the m32r. */
#ifndef SIM_MAIN_H
go after here. Oh for a better language. */
#if defined (WANT_CPU_M32RBF)
M32RBF_CPU_DATA cpu_data;
+#elif defined (WANT_CPU_M32RXF)
+ M32RXF_CPU_DATA cpu_data;
+#elif defined (WANT_CPU_M32R2F)
+ M32R2F_CPU_DATA cpu_data;
#endif
};
\f
#include "sim-main.h"
#include "targ-vals.h"
-/* The semantic code invokes this for invalid (unrecognized) instructions. */
+#define TRAP_FLUSH_CACHE 12
+/* The semantic code invokes this for invalid (unrecognized) instructions.
+ CIA is the address with the invalid insn.
+ VPC is the virtual pc of the following insn. */
-void
-sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia)
+SEM_PC
+sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
{
SIM_DESC sd = CPU_STATE (current_cpu);
else
#endif
sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL);
+ return vpc;
}
/* Process an address exception. */
{
a_m32r_h_cr_set (current_cpu, H_CR_BBPC,
a_m32r_h_cr_get (current_cpu, H_CR_BPC));
- a_m32r_h_bpsw_set (current_cpu, a_m32r_h_psw_get (current_cpu));
- /* sm not changed */
- a_m32r_h_psw_set (current_cpu, a_m32r_h_psw_get (current_cpu) & 0x80);
+ if (MACH_NUM (CPU_MACH (current_cpu)) == MACH_M32R)
+ {
+ m32rbf_h_bpsw_set (current_cpu, m32rbf_h_psw_get (current_cpu));
+ /* sm not changed */
+ m32rbf_h_psw_set (current_cpu, m32rbf_h_psw_get (current_cpu) & 0x80);
+ }
+ else if (MACH_NUM (CPU_MACH (current_cpu)) == MACH_M32RX)
+ {
+ m32rxf_h_bpsw_set (current_cpu, m32rxf_h_psw_get (current_cpu));
+ /* sm not changed */
+ m32rxf_h_psw_set (current_cpu, m32rxf_h_psw_get (current_cpu) & 0x80);
+ }
+ else
+ {
+ m32r2f_h_bpsw_set (current_cpu, m32r2f_h_psw_get (current_cpu));
+ /* sm not changed */
+ m32r2f_h_psw_set (current_cpu, m32r2f_h_psw_get (current_cpu) & 0x80);
+ }
a_m32r_h_cr_set (current_cpu, H_CR_BPC, cia);
sim_engine_restart (CPU_STATE (current_cpu), current_cpu, NULL,
if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
{
/* The new pc is the trap vector entry.
- We assume there's a branch there to some handler. */
- USI new_pc = EIT_TRAP_BASE_ADDR + num * 4;
+ We assume there's a branch there to some handler.
+ Use cr5 as EVB (EIT Vector Base) register. */
+ /* USI new_pc = EIT_TRAP_BASE_ADDR + num * 4; */
+ USI new_pc = a_m32r_h_cr_get (current_cpu, 5) + 0x40 + num * 4;
return new_pc;
}
sim_stopped, SIM_SIGTRAP);
break;
+ case TRAP_FLUSH_CACHE:
+ /* Do nothing. */
+ break;
+
default :
{
- USI new_pc = EIT_TRAP_BASE_ADDR + num * 4;
+ /* USI new_pc = EIT_TRAP_BASE_ADDR + num * 4; */
+ /* Use cr5 as EVB (EIT Vector Base) register. */
+ USI new_pc = a_m32r_h_cr_get (current_cpu, 5) + 0x40 + num * 4;
return new_pc;
}
}