diff options
author | Andrew Cagney <cagney@redhat.com> | 1997-12-08 03:22:58 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 1997-12-08 03:22:58 +0000 |
commit | bc6df23d1457c9c5e9616f737659d68d7fef6e50 (patch) | |
tree | 939e443924f25f220bb46be291d4b15852230d73 /sim/d10v | |
parent | 0a5875fc63c256f0daa9db6ed9a35257ab3db247 (diff) | |
download | gdb-bc6df23d1457c9c5e9616f737659d68d7fef6e50.zip gdb-bc6df23d1457c9c5e9616f737659d68d7fef6e50.tar.gz gdb-bc6df23d1457c9c5e9616f737659d68d7fef6e50.tar.bz2 |
For "trap", IBT and RIE exceptions, mask all PSW.SM. NB: Stepping
through an exception may not work correctly.
For GDB reads/writes to the control registers, ensure the cpu state is
updated correctly.
Diffstat (limited to 'sim/d10v')
-rw-r--r-- | sim/d10v/ChangeLog | 36 | ||||
-rw-r--r-- | sim/d10v/d10v_sim.h | 60 | ||||
-rw-r--r-- | sim/d10v/simops.c | 156 |
3 files changed, 165 insertions, 87 deletions
diff --git a/sim/d10v/ChangeLog b/sim/d10v/ChangeLog index a541633..fb75328 100644 --- a/sim/d10v/ChangeLog +++ b/sim/d10v/ChangeLog @@ -1,3 +1,39 @@ +Mon Dec 8 12:58:33 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * simops.c (OP_5F00): From Martin Hunt <hunt@cygnus.com>. Change + reserved trap from 0 to 15. Add trap emulation code for 0-14. + + * interp.c (sim_resume): From Martin Hunt <hunt@cygnus.com>. Check + IBA for SDBT. + + * d10v_sim.h (AE_VECTOR_START, RIE_VECTOR_START, + SDBT_VECTOR_START, TRAP_VECTOR_START): Define. + + * simops.c (OP_5F00): For "trap", mask out all but SM bit in PSW, + use move_to_cr. + (OP_5F00): For "trap", update BPSW with move_to_cr. + +Fri Dec 5 15:31:17 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * d10v_sim.h (enum): Enumerate CR register names. + (enum): Enumerate PSW bit values. + (PSW): Obtain value uing move_from_cr. + (MOD_S, MOD_E, BPSW): Make r-values. + (move_from_cr, move_to_cr): Declare functions. + + * interp.c (sim_fetch_register, sim_store_register): Use + move_from_cr and move_to_cr for CR register transfers. + + * simops.c (move_from_cr, move_to_cr): New functions. + (OP_5F40): Move BPSW to PSW using move_to_cr and move_from_cr. + (OP_5600): For "mvtc", use function move_to_cr. + (OP_5200): For "mvfc", use function move_from_cr. + +Fri Dec 5 13:33:14 1997 Andrew Cagney <cagney@b1.cygnus.com> + + * simops.c (OP_5600): For "mvtc" MOD_E and MOD_S, ensure that the + LSbit is zero. + Thu Dec 4 09:21:05 1997 Doug Evans <devans@canuck.cygnus.com> * configure: Regenerated to track ../common/aclocal.m4 changes. diff --git a/sim/d10v/d10v_sim.h b/sim/d10v/d10v_sim.h index 1fd2d8a..b05a60a 100644 --- a/sim/d10v/d10v_sim.h +++ b/sim/d10v/d10v_sim.h @@ -109,16 +109,48 @@ extern bfd_vma text_start; extern bfd_vma text_end; extern bfd *prog_bfd; -#define PC (State.cregs[2]) -#define PSW (State.cregs[0]) -#define BPSW (State.cregs[1]) -#define BPC (State.cregs[3]) -#define RPT_C (State.cregs[7]) -#define RPT_S (State.cregs[8]) -#define RPT_E (State.cregs[9]) -#define MOD_S (State.cregs[10]) -#define MOD_E (State.cregs[11]) -#define IBA (State.cregs[14]) +enum +{ + PSW_CR = 0, + BPSW_CR = 1, + PC_CR = 2, + BPC_CR = 3, + RPT_C_CR = 7, + RPT_S_CR = 8, + RPT_E_CR = 9, + MOD_S_CR = 10, + MOD_E_CR = 11, + IBA_CR = 14, +}; + +enum +{ + PSW_SM_BIT = 0x8000, + PSW_EA_BIT = 0x2000, + PSW_DB_BIT = 0x1000, + PSW_DM_BIT = 0x0800, + PSW_IE_BIT = 0x0400, + PSW_RP_BIT = 0x0200, + PSW_MD_BIT = 0x0100, + PSW_FX_BIT = 0x0080, + PSW_ST_BIT = 0x0040, + PSW_F0_BIT = 0x0008, + PSW_F1_BIT = 0x0004, + PSW_C_BIT = 0x0001, +}; + +/* See simopsc.:move_to_cr() for registers that can not be read-from + or assigned-to directly */ +#define PC (State.cregs[PC_CR]) +#define PSW (move_from_cr (PSW_CR)) +#define BPSW (0 + State.cregs[PSW_CR]) +#define BPC (State.cregs[BPC_CR]) +#define RPT_C (State.cregs[RPT_C_CR]) +#define RPT_S (State.cregs[RPT_E_CR]) +#define RPT_E (State.cregs[RPT_E_CR]) +#define MOD_S (0 + State.cregs[MOD_S_CR]) +#define MOD_E (0 + State.cregs[MOD_E_CR]) +#define IBA (State.cregs[IBA_CR]) #define SIG_D10V_STOP -1 #define SIG_D10V_EXIT -2 @@ -194,3 +226,11 @@ extern void write_longlong PARAMS ((uint8 *addr, int64 data)); #define SET_DMAP(x) SW(0xff04,x) #define JMP(x) { PC = (x); State.pc_changed = 1; } + +#define AE_VECTOR_START 0xffc3 +#define RIE_VECTOR_START 0xffc2 +#define SDBT_VECTOR_START 0xffd5 +#define TRAP_VECTOR_START 0xffc4 /* vector for trap 0 */ + +extern void move_to_cr PARAMS ((int cr, reg_t val)); +extern reg_t move_from_cr PARAMS ((int cr)); diff --git a/sim/d10v/simops.c b/sim/d10v/simops.c index b085c14..de6b2ab 100644 --- a/sim/d10v/simops.c +++ b/sim/d10v/simops.c @@ -43,6 +43,76 @@ enum op_types { OP_R2R3 }; + +void +move_to_cr (int cr, reg_t val) +{ + switch (cr) + { + case PSW_CR: + State.SM = (val & PSW_SM_BIT) != 0; + State.EA = (val & PSW_EA_BIT) != 0; + State.DB = (val & PSW_DB_BIT) != 0; + State.DM = (val & PSW_DM_BIT) != 0; + State.IE = (val & PSW_IE_BIT) != 0; + State.RP = (val & PSW_RP_BIT) != 0; + State.MD = (val & PSW_MD_BIT) != 0; + State.FX = (val & PSW_FX_BIT) != 0; + State.ST = (val & PSW_ST_BIT) != 0; + State.F0 = (val & PSW_F0_BIT) != 0; + State.F1 = (val & PSW_F1_BIT) != 0; + State.C = (val & PSW_C_BIT) != 0; + if (State.ST && !State.FX) + { + (*d10v_callback->printf_filtered) + (d10v_callback, + "ERROR at PC 0x%x: ST can only be set when FX is set.\n", + PC<<2); + State.exception = SIGILL; + } + State.cregs[PSW_CR] = (val & ~0x4032); + break; + case BPSW_CR: + State.cregs[BPSW_CR] = (val & ~0x4032); + break; + case MOD_S_CR: + case MOD_E_CR: + State.cregs[cr] = (val & ~0x1); + break; + default: + State.cregs[cr] = val; + break; + } +} + +reg_t +move_from_cr (int cr) +{ + reg_t val = 0; + switch (cr) + { + case PSW_CR: + if (State.SM) val |= PSW_SM_BIT; + if (State.EA) val |= PSW_EA_BIT; + if (State.DB) val |= PSW_DB_BIT; + if (State.DM) val |= PSW_DM_BIT; + if (State.IE) val |= PSW_IE_BIT; + if (State.RP) val |= PSW_RP_BIT; + if (State.MD) val |= PSW_MD_BIT; + if (State.FX) val |= PSW_FX_BIT; + if (State.ST) val |= PSW_ST_BIT; + if (State.F0) val |= PSW_F0_BIT; + if (State.F1) val |= PSW_F1_BIT; + if (State.C) val |= PSW_C_BIT; + break; + default: + val = State.cregs[cr]; + break; + } + return val; +} + + #ifdef DEBUG static void trace_input_func PARAMS ((char *name, enum op_types in1, @@ -1704,24 +1774,7 @@ void OP_5200 () { trace_input ("mvfc", OP_REG_OUTPUT, OP_CR, OP_VOID); - if (OP[1] == 0) - { - /* PSW is treated specially */ - PSW = 0; - if (State.SM) PSW |= 0x8000; - if (State.EA) PSW |= 0x2000; - if (State.DB) PSW |= 0x1000; - if (State.DM) PSW |= 0x800; - if (State.IE) PSW |= 0x400; - if (State.RP) PSW |= 0x200; - if (State.MD) PSW |= 0x100; - if (State.FX) PSW |= 0x80; - if (State.ST) PSW |= 0x40; - if (State.F0) PSW |= 8; - if (State.F1) PSW |= 4; - if (State.C) PSW |= 1; - } - State.regs[OP[0]] = State.cregs[OP[1]]; + State.regs[OP[0]] = move_from_cr (OP[1]); trace_output (OP_REG); } @@ -1761,30 +1814,7 @@ void OP_5600 () { trace_input ("mvtc", OP_REG, OP_CR_OUTPUT, OP_VOID); - State.cregs[OP[1]] = State.regs[OP[0]]; - if (OP[1] == 0) - { - /* PSW is treated specially */ - State.SM = (PSW & 0x8000) ? 1 : 0; - State.EA = (PSW & 0x2000) ? 1 : 0; - State.DB = (PSW & 0x1000) ? 1 : 0; - State.DM = (PSW & 0x800) ? 1 : 0; - State.IE = (PSW & 0x400) ? 1 : 0; - State.RP = (PSW & 0x200) ? 1 : 0; - State.MD = (PSW & 0x100) ? 1 : 0; - State.FX = (PSW & 0x80) ? 1 : 0; - State.ST = (PSW & 0x40) ? 1 : 0; - State.F0 = (PSW & 8) ? 1 : 0; - State.F1 = (PSW & 4) ? 1 : 0; - State.C = PSW & 1; - if (State.ST && !State.FX) - { - (*d10v_callback->printf_filtered) (d10v_callback, - "ERROR at PC 0x%x: ST can only be set when FX is set.\n", - PC<<2); - State.exception = SIGILL; - } - } + move_to_cr (OP[1], State.regs[OP[0]]); trace_output (OP_CR_REVERSE); } @@ -2033,7 +2063,7 @@ OP_5F40 () { trace_input ("rte", OP_VOID, OP_VOID, OP_VOID); PC = BPC; - PSW = BPSW; + move_to_cr (PSW_CR, BPSW); trace_output (OP_VOID); } @@ -2621,42 +2651,14 @@ OP_5F00 () switch (OP[0]) { default: -#if 0 - (*d10v_callback->printf_filtered) (d10v_callback, "Unknown trap code %d\n", OP[0]); - State.exception = SIGILL; -#else - /* Use any other traps for batch debugging. */ { - int i; - static int first_time = 1; - - if (first_time) - { - first_time = 0; - (*d10v_callback->printf_filtered) (d10v_callback, "Trap # PC "); - for (i = 0; i < 16; i++) - (*d10v_callback->printf_filtered) (d10v_callback, " %sr%d", (i > 9) ? "" : " ", i); - (*d10v_callback->printf_filtered) (d10v_callback, " a0 a1 f0 f1 c\n"); - } - - (*d10v_callback->printf_filtered) (d10v_callback, "Trap %2d 0x%.4x:", (int)OP[0], (int)PC); - - for (i = 0; i < 16; i++) - (*d10v_callback->printf_filtered) (d10v_callback, " %.4x", (int) State.regs[i]); - - for (i = 0; i < 2; i++) - (*d10v_callback->printf_filtered) (d10v_callback, " %.2x%.8lx", - ((int)(State.a[i] >> 32) & 0xff), - ((unsigned long)State.a[i]) & 0xffffffff); - - (*d10v_callback->printf_filtered) (d10v_callback, " %d %d %d\n", - State.F0 != 0, State.F1 != 0, State.C != 0); - (*d10v_callback->flush_stdout) (d10v_callback); - break; + uint16 vec = OP[0] + TRAP_VECTOR_START; + BPC = PC + 1; + move_to_cr (BPSW_CR, PSW); + move_to_cr (PSW_CR, PSW & PSW_SM_BIT); + JMP (vec); } -#endif - - case 0: /* old system call trap, to be deleted */ + break; case 15: /* new system call trap */ /* Trap 15 is used for simulating low-level I/O */ { |