From 9f70f8ec0400d4011d748ea813414819bbb5fdf7 Mon Sep 17 00:00:00 2001 From: Michael Snyder Date: Thu, 19 Jun 2003 02:14:14 +0000 Subject: 2003-06-18 Michael Snyder * compile.c: Replace "Hitachi" with "Renesas". (decode): Distinguish AV_H8S from AV_H8H. (sim_resume): H8SX can use any register for TAS. (decode): Add support for VECIND. (sim_resume): Implement rte/l and rts/l. (GETSR): New macro (actually old macro reincarnated). (decode): Add handling for IMM2. (sim_resume): Drop extra block around jmp, jsr, rts. Add handling for trapa and rte. For divxu.b, change 0xffff mask to 0xff. (set_h8300h): Add bfd_mach_h8300sxn machine. --- sim/h8300/ChangeLog | 14 +++ sim/h8300/compile.c | 242 +++++++++++++++++++++++++++++++++------------------- 2 files changed, 167 insertions(+), 89 deletions(-) (limited to 'sim/h8300') diff --git a/sim/h8300/ChangeLog b/sim/h8300/ChangeLog index b4e0655..cd81e6e 100644 --- a/sim/h8300/ChangeLog +++ b/sim/h8300/ChangeLog @@ -1,3 +1,17 @@ +2003-06-18 Michael Snyder + + * compile.c: Replace "Hitachi" with "Renesas". + (decode): Distinguish AV_H8S from AV_H8H. + (sim_resume): H8SX can use any register for TAS. + (decode): Add support for VECIND. + (sim_resume): Implement rte/l and rts/l. + (GETSR): New macro (actually old macro reincarnated). + (decode): Add handling for IMM2. + (sim_resume): Drop extra block around jmp, jsr, rts. + Add handling for trapa and rte. + For divxu.b, change 0xffff mask to 0xff. + (set_h8300h): Add bfd_mach_h8300sxn machine. + 2003-06-18 Corinna Vinschen * sim-main.h (enum h8_regnum): Turn around order of MACH, MACL diff --git a/sim/h8300/compile.c b/sim/h8300/compile.c index e82fe63..f416695 100644 --- a/sim/h8300/compile.c +++ b/sim/h8300/compile.c @@ -1,5 +1,5 @@ /* - * Simulator for the Hitachi H8/300 architecture. + * Simulator for the Renesas (formerly Hitachi) H8/300 architecture. * * Written by Steve Chamberlain of Cygnus Support. sac@cygnus.com * @@ -484,6 +484,18 @@ enum { POLL_QUIT_INTERVAL = 0x80000 }; h8_set_ccr (SD, (I << 7) | (UI << 6) | (H << 5) | (U << 4) \ | (N << 3) | (Z << 2) | (V << 1) | C) +#define GETSR(SD) \ + /* Get Status Register (flags). */ \ + c = (h8_get_ccr (sd) >> 0) & 1; \ + v = (h8_get_ccr (sd) >> 1) & 1; \ + nz = !((h8_get_ccr (sd) >> 2) & 1); \ + n = (h8_get_ccr (sd) >> 3) & 1; \ + u = (h8_get_ccr (sd) >> 4) & 1; \ + h = (h8_get_ccr (sd) >> 5) & 1; \ + ui = ((h8_get_ccr (sd) >> 6) & 1); \ + intMaskBit = (h8_get_ccr (sd) >> 7) & 1 + + #ifdef __CHAR_IS_SIGNED__ #define SEXTCHAR(x) ((char) (x)) #endif @@ -590,6 +602,7 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst) unsigned int len = 0; if ((q->available == AV_H8SX && !h8300sxmode) || + (q->available == AV_H8S && !h8300smode) || (q->available == AV_H8H && !h8300hmode)) continue; @@ -831,6 +844,12 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst) { cst[opnum] = data[1]; } + else if ((looking_for & MODE) == VECIND) + { + /* FIXME: Multiplier should be 2 for "normal" mode. */ + cst[opnum] = ((data[1] & 0x7f) + 0x80) * 4; + cst[opnum] += h8_get_vbr (sd); /* Add vector base reg. */ + } else if ((looking_for & SIZE) == L_32) { int i = len / 2; @@ -885,6 +904,10 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst) cst[opnum] = data[len / 2] & 0xff; } } + else if ((looking_for & SIZE) == L_2) + { + cst[opnum] = thisnib & 3; + } else if ((looking_for & SIZE) == L_3 || (looking_for & SIZE) == L_3NZ) { @@ -1025,7 +1048,8 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst) else p->reg = ZERO_REGNUM;; } - else if ((x & MODE) == MEMIND) + else if ((x & MODE) == MEMIND || + (x & MODE) == VECIND) { /* Size doesn't matter. */ p->type = X (OP_MEM, SB); @@ -1104,7 +1128,7 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst) p->type = OP_EXR; } else - printf ("Hmmmm %x...\n", x); + printf ("Hmmmm 0x%x...\n", x); args++; } @@ -1158,7 +1182,7 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst) return; } else - printf ("Don't understand %x \n", looking_for); + printf ("Don't understand 0x%x \n", looking_for); } len++; @@ -1893,14 +1917,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) } /* Get Status Register (flags). */ - c = (h8_get_ccr (sd) >> 0) & 1; - v = (h8_get_ccr (sd) >> 1) & 1; - nz = !((h8_get_ccr (sd) >> 2) & 1); - n = (h8_get_ccr (sd) >> 3) & 1; - u = (h8_get_ccr (sd) >> 4) & 1; - h = (h8_get_ccr (sd) >> 5) & 1; - ui = ((h8_get_ccr (sd) >> 6) & 1); - intMaskBit = (h8_get_ccr (sd) >> 7) & 1; + GETSR (sd); if (h8300smode) /* Get exr. */ { @@ -2197,7 +2214,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) goto end; goto just_flags_log32; - case O (O_MOVMD, SB): /* movsd.b */ + case O (O_MOVMD, SB): /* movmd.b */ ea = GET_W_REG (4); if (ea == 0) ea = 0x10000; @@ -2212,7 +2229,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) } goto next; - case O (O_MOVMD, SW): /* movsd.b */ + case O (O_MOVMD, SW): /* movmd.w */ ea = GET_W_REG (4); if (ea == 0) ea = 0x10000; @@ -2227,7 +2244,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) } goto next; - case O (O_MOVMD, SL): /* movsd.b */ + case O (O_MOVMD, SL): /* movmd.l */ ea = GET_W_REG (4); if (ea == 0) ea = 0x10000; @@ -3463,36 +3480,31 @@ sim_resume (SIM_DESC sd, int step, int siggnal) case O (O_JMP, SL): case O (O_JMP, SB): /* jmp */ case O (O_JMP, SW): - { - fetch (sd, &code->src, &pc); - goto end; - } + fetch (sd, &code->src, &pc); + goto end; case O (O_JSR, SN): case O (O_JSR, SL): case O (O_JSR, SB): /* jsr, jump to subroutine */ case O (O_JSR, SW): - { - int tmp; - if (fetch (sd, &code->src, &pc)) - goto end; - call: - tmp = h8_get_reg (sd, SP_REGNUM); + if (fetch (sd, &code->src, &pc)) + goto end; + call: + tmp = h8_get_reg (sd, SP_REGNUM); - if (h8300hmode) - { - tmp -= 4; - SET_MEMORY_L (tmp, code->next_pc); - } - else - { - tmp -= 2; - SET_MEMORY_W (tmp, code->next_pc); - } - h8_set_reg (sd, SP_REGNUM, tmp); + if (h8300hmode) + { + tmp -= 4; + SET_MEMORY_L (tmp, code->next_pc); + } + else + { + tmp -= 2; + SET_MEMORY_W (tmp, code->next_pc); + } + h8_set_reg (sd, SP_REGNUM, tmp); - goto end; - } + goto end; case O (O_BSR, SW): case O (O_BSR, SL): @@ -3502,26 +3514,52 @@ sim_resume (SIM_DESC sd, int step, int siggnal) pc = code->next_pc + res; goto call; - case O (O_RTS, SN): /* rts, return from subroutine */ - { - int tmp; + case O (O_RTE, SN): /* rte, return from exception */ + rte: + /* Pops exr and ccr before pc -- otherwise identical to rts. */ + tmp = h8_get_reg (sd, SP_REGNUM); - tmp = h8_get_reg (sd, SP_REGNUM); + if (h8300smode) /* pop exr */ + { + h8_set_exr (sd, GET_MEMORY_L (tmp)); + tmp += 4; + } + if (h8300hmode) + { + h8_set_ccr (sd, GET_MEMORY_L (tmp)); + tmp += 4; + pc = GET_MEMORY_L (tmp); + tmp += 4; + } + else + { + h8_set_ccr (sd, GET_MEMORY_W (tmp)); + tmp += 2; + pc = GET_MEMORY_W (tmp); + tmp += 2; + } - if (h8300hmode) - { - pc = GET_MEMORY_L (tmp); - tmp += 4; - } - else - { - pc = GET_MEMORY_W (tmp); - tmp += 2; - } + GETSR (sd); + h8_set_reg (sd, SP_REGNUM, tmp); + goto end; - h8_set_reg (sd, SP_REGNUM, tmp); - goto end; - } + case O (O_RTS, SN): /* rts, return from subroutine */ + rts: + tmp = h8_get_reg (sd, SP_REGNUM); + + if (h8300hmode) + { + pc = GET_MEMORY_L (tmp); + tmp += 4; + } + else + { + pc = GET_MEMORY_W (tmp); + tmp += 2; + } + + h8_set_reg (sd, SP_REGNUM, tmp); + goto end; case O (O_ILL, SB): /* illegal */ sim_engine_set_run_state (sd, sim_stopped, SIGILL); @@ -3544,6 +3582,30 @@ sim_resume (SIM_DESC sd, int step, int siggnal) } goto end; + case O (O_TRAPA, SB): /* trapa */ + if (fetch (sd, &code->src, &res)) + goto end; /* res is vector number. */ + + tmp = h8_get_reg (sd, SP_REGNUM); + tmp -= 4; + SET_MEMORY_L (tmp, code->next_pc); + tmp -= 4; + SET_MEMORY_L (tmp, h8_get_ccr (sd)); + intMaskBit = 1; + BUILDSR (sd); + + if (h8300smode) + { + tmp -= 4; + SET_MEMORY_L (tmp, h8_get_exr (sd)); + } + + h8_set_reg (sd, SP_REGNUM, tmp); + + /* FIXME: "normal" mode should use 2-byte ptrs. */ + pc = GET_MEMORY_L (0x20 + res * 4); + goto end; + case O (O_BPT, SN): sim_engine_set_run_state (sd, sim_stopped, SIGTRAP); goto end; @@ -3898,19 +3960,19 @@ sim_resume (SIM_DESC sd, int step, int siggnal) goto next; - case O (O_TAS, SB): /* tas, (test and set?) */ - if (!h8300smode || code->src.type != X (OP_REG, SL)) - goto illegal; - switch (code->src.reg) - { - case R0_REGNUM: - case R1_REGNUM: - case R4_REGNUM: - case R5_REGNUM: - break; - default: - goto illegal; - } + case O (O_TAS, SB): /* tas (test and set) */ + if (!h8300sxmode) /* h8sx can use any register. */ + switch (code->src.reg) + { + case R0_REGNUM: + case R1_REGNUM: + case R4_REGNUM: + case R5_REGNUM: + break; + default: + goto illegal; + } + if (fetch (sd, &code->src, &res)) goto end; if (store (sd, &code->src, res | 0x80)) @@ -4023,7 +4085,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) res = 0; } - if (store (sd, &code->dst, (res & 0xffff) | (tmp << 8))) + if (store (sd, &code->dst, (res & 0xff) | (tmp << 8))) goto end; goto next; @@ -4190,25 +4252,33 @@ sim_resume (SIM_DESC sd, int step, int siggnal) goto next; case O (O_LDM, SL): /* ldm, load from memory */ + case O (O_RTEL, SN): /* rte/l, ldm plus rte */ + case O (O_RTSL, SN): /* rts/l, ldm plus rts */ { int nregs, firstreg, i; - nregs = GET_MEMORY_B (pc + 1); - nregs >>= 4; - nregs &= 0xf; - firstreg = code->dst.reg; - firstreg &= 0xf; + nregs = ((GET_MEMORY_B (pc + 1) >> 4) & 0xf); + firstreg = code->dst.reg & 0xf; for (i = firstreg; i >= firstreg - nregs; i--) { h8_set_reg (sd, i, GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM))); h8_set_reg (sd, SP_REGNUM, h8_get_reg (sd, SP_REGNUM) + 4); } } - goto next; + switch (code->opcode) { + case O (O_RTEL, SN): + goto rte; + case O (O_RTSL, SN): + goto rts; + case O (O_LDM, SL): + goto next; + default: + goto illegal; + } case O (O_DAA, SB): /* Decimal Adjust Addition. This is for BCD arithmetic. */ - res = GET_B_REG (code->src.reg); + res = GET_B_REG (code->src.reg); /* FIXME fetch? */ if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) && !h && (0 <= (res & 0xf) && (res & 0xf) <= 9)) res = res; /* Value added == 0. */ @@ -4274,15 +4344,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) code->dst.type == X (OP_CCR, SW)) { h8_set_ccr (sd, res); - /* Get Status Register (flags). */ - c = (h8_get_ccr (sd) >> 0) & 1; - v = (h8_get_ccr (sd) >> 1) & 1; - nz = !((h8_get_ccr (sd) >> 2) & 1); - n = (h8_get_ccr (sd) >> 3) & 1; - u = (h8_get_ccr (sd) >> 4) & 1; - h = (h8_get_ccr (sd) >> 5) & 1; - ui = ((h8_get_ccr (sd) >> 6) & 1); - intMaskBit = (h8_get_ccr (sd) >> 7) & 1; + GETSR (sd); } else if (h8300smode && (code->dst.type == X (OP_EXR, SB) || @@ -4569,6 +4631,9 @@ sim_store_register (SIM_DESC sd, int rn, unsigned char *value, int length) init_pointers (sd); switch (rn) { + case PC_REGNUM: + h8_set_pc (sd, intval); + break; default: (*sim_callback->printf_filtered) (sim_callback, "sim_store_register: bad regnum %d.\n", @@ -4583,9 +4648,6 @@ sim_store_register (SIM_DESC sd, int rn, unsigned char *value, int length) case R7_REGNUM: h8_set_reg (sd, rn, intval); break; - case PC_REGNUM: - h8_set_pc (sd, intval); - break; case CCR_REGNUM: h8_set_ccr (sd, intval); break; @@ -4607,9 +4669,11 @@ sim_store_register (SIM_DESC sd, int rn, unsigned char *value, int length) case CYCLE_REGNUM: h8_set_cycles (sd, longval); break; + case INST_REGNUM: h8_set_insts (sd, longval); break; + case TICK_REGNUM: h8_set_ticks (sd, longval); break; @@ -4776,7 +4840,7 @@ set_h8300h (unsigned long machine) This function being replaced by a sim_open:ARGV configuration option. */ - if (machine == bfd_mach_h8300sx) + if (machine == bfd_mach_h8300sx || machine == bfd_mach_h8300sxn) h8300sxmode = 1; if (machine == bfd_mach_h8300s || machine == bfd_mach_h8300sn || h8300sxmode) -- cgit v1.1