From ae24773c92be103cdfef5ffb885425a6ffc6f1f1 Mon Sep 17 00:00:00 2001 From: cagney Date: Sun, 7 Dec 2003 02:27:45 +0000 Subject: [PATCH] 2003-12-02 Kazuhiro Inaoka * 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 --- sim/m32r/ChangeLog | 12 ++++ sim/m32r/Makefile.in | 39 ++++++++++++- sim/m32r/m32r-sim.h | 55 +++++++++++++----- sim/m32r/m32r.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++--- sim/m32r/sim-if.c | 5 ++ sim/m32r/sim-main.h | 5 ++ sim/m32r/traps.c | 45 +++++++++++--- 7 files changed, 291 insertions(+), 31 deletions(-) diff --git a/sim/m32r/ChangeLog b/sim/m32r/ChangeLog index b6d7c244f7..6fb468a078 100644 --- a/sim/m32r/ChangeLog +++ b/sim/m32r/ChangeLog @@ -1,3 +1,15 @@ +2003-12-02 Kazuhiro Inaoka + + * 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 On behalf of Doug Evans diff --git a/sim/m32r/Makefile.in b/sim/m32r/Makefile.in index 18d9d3f7dd..2a22fb8566 100644 --- a/sim/m32r/Makefile.in +++ b/sim/m32r/Makefile.in @@ -22,6 +22,7 @@ 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 = @@ -38,6 +39,7 @@ SIM_OBJS = \ sim-if.o arch.o \ $(M32R_OBJS) \ $(M32RX_OBJS) \ + $(M32R2_OBJS) \ traps.o devices.o \ $(CONFIG_DEVICES) @@ -113,10 +115,35 @@ decodex.o: decodex.c $(M32RXF_INCLUDE_DEPS) 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 @@ -148,3 +175,13 @@ stamp-xcpu: $(CGEN_READ_SCM) $(CGEN_CPU_SCM) $(CGEN_DECODE_SCM) $(CGEN_CPU_DIR)/ 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 + diff --git a/sim/m32r/m32r-sim.h b/sim/m32r/m32r-sim.h index 1dd1878ccd..52b00593da 100644 --- a/sim/m32r/m32r-sim.h +++ b/sim/m32r/m32r-sim.h @@ -34,6 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #define ACC1H_REGNUM 25 #define BBPSW_REGNUM 26 #define BBPC_REGNUM 27 +#define EVB_REGNUM 28 extern int m32r_decode_gdb_ctrl_regnum (int); @@ -41,27 +42,29 @@ 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); /* Misc. profile data. */ @@ -128,6 +131,32 @@ do { \ /* 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 /* Hardware/device support. ??? Will eventually want to move device stuff to config files. */ @@ -189,7 +218,7 @@ do { \ /* 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; diff --git a/sim/m32r/m32r.c b/sim/m32r/m32r.c index 13e71e6320..fc8586c80b 100644 --- a/sim/m32r/m32r.c +++ b/sim/m32r/m32r.c @@ -39,6 +39,7 @@ m32r_decode_gdb_ctrl_regnum (int gdb_regnum) 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 (); } @@ -48,6 +49,8 @@ m32r_decode_gdb_ctrl_regnum (int gdb_regnum) 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 @@ -60,17 +63,33 @@ m32rbf_fetch_register (SIM_CPU *current_cpu, int rn, unsigned char *buf, int len 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; @@ -84,6 +103,8 @@ m32rbf_fetch_register (SIM_CPU *current_cpu, int rn, unsigned char *buf, int len 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 @@ -96,25 +117,53 @@ m32rbf_store_register (SIM_CPU *current_cpu, int rn, unsigned char *buf, int len 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 : @@ -124,6 +173,102 @@ m32rbf_store_register (SIM_CPU *current_cpu, int rn, unsigned char *buf, int len return -1; /*FIXME*/ } +/* 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 (); + } +} + USI m32rbf_h_cr_get_handler (SIM_CPU *current_cpu, UINT cr) { diff --git a/sim/m32r/sim-if.c b/sim/m32r/sim-if.c index 95568cc180..3eea018ebb 100644 --- a/sim/m32r/sim-if.c +++ b/sim/m32r/sim-if.c @@ -240,6 +240,11 @@ print_m32r_misc_cpu (SIM_CPU *cpu, int verbose) 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)); } } diff --git a/sim/m32r/sim-main.h b/sim/m32r/sim-main.h index d076e1520f..6c1063892a 100644 --- a/sim/m32r/sim-main.h +++ b/sim/m32r/sim-main.h @@ -1,3 +1,4 @@ + /* Main header for the m32r. */ #ifndef SIM_MAIN_H @@ -57,6 +58,10 @@ struct _sim_cpu { 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 }; diff --git a/sim/m32r/traps.c b/sim/m32r/traps.c index c81a8626b8..0500407138 100644 --- a/sim/m32r/traps.c +++ b/sim/m32r/traps.c @@ -21,10 +21,13 @@ with this program; if not, write to the Free Software Foundation, Inc., #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); @@ -46,6 +49,7 @@ sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia) else #endif sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL); + return vpc; } /* Process an address exception. */ @@ -59,9 +63,24 @@ m32r_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia, { 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, @@ -119,8 +138,10 @@ m32r_trap (SIM_CPU *current_cpu, PCADDR pc, int num) 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; } @@ -157,9 +178,15 @@ m32r_trap (SIM_CPU *current_cpu, PCADDR pc, int num) 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; } } -- 2.11.0