2003-06-18 Michael Snyder <msnyder@redhat.com>

* 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.
This commit is contained in:
Michael Snyder
2003-06-19 02:14:14 +00:00
parent 18ad32b593
commit 9f70f8ec04
2 changed files with 168 additions and 90 deletions

View File

@ -1,3 +1,17 @@
2003-06-18 Michael Snyder <msnyder@redhat.com>
* 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 <vinschen@redhat.com> 2003-06-18 Corinna Vinschen <vinschen@redhat.com>
* sim-main.h (enum h8_regnum): Turn around order of MACH, MACL * sim-main.h (enum h8_regnum): Turn around order of MACH, MACL

View File

@ -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 * 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) \ h8_set_ccr (SD, (I << 7) | (UI << 6) | (H << 5) | (U << 4) \
| (N << 3) | (Z << 2) | (V << 1) | C) | (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__ #ifdef __CHAR_IS_SIGNED__
#define SEXTCHAR(x) ((char) (x)) #define SEXTCHAR(x) ((char) (x))
#endif #endif
@ -590,6 +602,7 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
unsigned int len = 0; unsigned int len = 0;
if ((q->available == AV_H8SX && !h8300sxmode) || if ((q->available == AV_H8SX && !h8300sxmode) ||
(q->available == AV_H8S && !h8300smode) ||
(q->available == AV_H8H && !h8300hmode)) (q->available == AV_H8H && !h8300hmode))
continue; continue;
@ -831,6 +844,12 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
{ {
cst[opnum] = data[1]; 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) else if ((looking_for & SIZE) == L_32)
{ {
int i = len / 2; 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; cst[opnum] = data[len / 2] & 0xff;
} }
} }
else if ((looking_for & SIZE) == L_2)
{
cst[opnum] = thisnib & 3;
}
else if ((looking_for & SIZE) == L_3 || else if ((looking_for & SIZE) == L_3 ||
(looking_for & SIZE) == L_3NZ) (looking_for & SIZE) == L_3NZ)
{ {
@ -1025,7 +1048,8 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
else else
p->reg = ZERO_REGNUM;; p->reg = ZERO_REGNUM;;
} }
else if ((x & MODE) == MEMIND) else if ((x & MODE) == MEMIND ||
(x & MODE) == VECIND)
{ {
/* Size doesn't matter. */ /* Size doesn't matter. */
p->type = X (OP_MEM, SB); 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; p->type = OP_EXR;
} }
else else
printf ("Hmmmm %x...\n", x); printf ("Hmmmm 0x%x...\n", x);
args++; args++;
} }
@ -1158,7 +1182,7 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
return; return;
} }
else else
printf ("Don't understand %x \n", looking_for); printf ("Don't understand 0x%x \n", looking_for);
} }
len++; len++;
@ -1893,14 +1917,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
} }
/* Get Status Register (flags). */ /* Get Status Register (flags). */
c = (h8_get_ccr (sd) >> 0) & 1; GETSR (sd);
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;
if (h8300smode) /* Get exr. */ if (h8300smode) /* Get exr. */
{ {
@ -2197,7 +2214,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
goto end; goto end;
goto just_flags_log32; goto just_flags_log32;
case O (O_MOVMD, SB): /* movsd.b */ case O (O_MOVMD, SB): /* movmd.b */
ea = GET_W_REG (4); ea = GET_W_REG (4);
if (ea == 0) if (ea == 0)
ea = 0x10000; ea = 0x10000;
@ -2212,7 +2229,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
} }
goto next; goto next;
case O (O_MOVMD, SW): /* movsd.b */ case O (O_MOVMD, SW): /* movmd.w */
ea = GET_W_REG (4); ea = GET_W_REG (4);
if (ea == 0) if (ea == 0)
ea = 0x10000; ea = 0x10000;
@ -2227,7 +2244,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
} }
goto next; goto next;
case O (O_MOVMD, SL): /* movsd.b */ case O (O_MOVMD, SL): /* movmd.l */
ea = GET_W_REG (4); ea = GET_W_REG (4);
if (ea == 0) if (ea == 0)
ea = 0x10000; ea = 0x10000;
@ -3463,17 +3480,13 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
case O (O_JMP, SL): case O (O_JMP, SL):
case O (O_JMP, SB): /* jmp */ case O (O_JMP, SB): /* jmp */
case O (O_JMP, SW): case O (O_JMP, SW):
{
fetch (sd, &code->src, &pc); fetch (sd, &code->src, &pc);
goto end; goto end;
}
case O (O_JSR, SN): case O (O_JSR, SN):
case O (O_JSR, SL): case O (O_JSR, SL):
case O (O_JSR, SB): /* jsr, jump to subroutine */ case O (O_JSR, SB): /* jsr, jump to subroutine */
case O (O_JSR, SW): case O (O_JSR, SW):
{
int tmp;
if (fetch (sd, &code->src, &pc)) if (fetch (sd, &code->src, &pc))
goto end; goto end;
call: call:
@ -3492,7 +3505,6 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
h8_set_reg (sd, SP_REGNUM, tmp); h8_set_reg (sd, SP_REGNUM, tmp);
goto end; goto end;
}
case O (O_BSR, SW): case O (O_BSR, SW):
case O (O_BSR, SL): case O (O_BSR, SL):
@ -3502,10 +3514,37 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
pc = code->next_pc + res; pc = code->next_pc + res;
goto call; goto call;
case O (O_RTS, SN): /* rts, return from subroutine */ case O (O_RTE, SN): /* rte, return from exception */
{ rte:
int tmp; /* Pops exr and ccr before pc -- otherwise identical to rts. */
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;
}
GETSR (sd);
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); tmp = h8_get_reg (sd, SP_REGNUM);
if (h8300hmode) if (h8300hmode)
@ -3521,7 +3560,6 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
h8_set_reg (sd, SP_REGNUM, tmp); h8_set_reg (sd, SP_REGNUM, tmp);
goto end; goto end;
}
case O (O_ILL, SB): /* illegal */ case O (O_ILL, SB): /* illegal */
sim_engine_set_run_state (sd, sim_stopped, SIGILL); sim_engine_set_run_state (sd, sim_stopped, SIGILL);
@ -3544,6 +3582,30 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
} }
goto end; 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): case O (O_BPT, SN):
sim_engine_set_run_state (sd, sim_stopped, SIGTRAP); sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
goto end; goto end;
@ -3898,9 +3960,8 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
goto next; goto next;
case O (O_TAS, SB): /* tas, (test and set?) */ case O (O_TAS, SB): /* tas (test and set) */
if (!h8300smode || code->src.type != X (OP_REG, SL)) if (!h8300sxmode) /* h8sx can use any register. */
goto illegal;
switch (code->src.reg) switch (code->src.reg)
{ {
case R0_REGNUM: case R0_REGNUM:
@ -3911,6 +3972,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
default: default:
goto illegal; goto illegal;
} }
if (fetch (sd, &code->src, &res)) if (fetch (sd, &code->src, &res))
goto end; goto end;
if (store (sd, &code->src, res | 0x80)) if (store (sd, &code->src, res | 0x80))
@ -4023,7 +4085,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
res = 0; res = 0;
} }
if (store (sd, &code->dst, (res & 0xffff) | (tmp << 8))) if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
goto end; goto end;
goto next; goto next;
@ -4190,25 +4252,33 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
goto next; goto next;
case O (O_LDM, SL): /* ldm, load from memory */ 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; int nregs, firstreg, i;
nregs = GET_MEMORY_B (pc + 1); nregs = ((GET_MEMORY_B (pc + 1) >> 4) & 0xf);
nregs >>= 4; firstreg = code->dst.reg & 0xf;
nregs &= 0xf;
firstreg = code->dst.reg;
firstreg &= 0xf;
for (i = firstreg; i >= firstreg - nregs; i--) 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, i, GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM)));
h8_set_reg (sd, SP_REGNUM, h8_get_reg (sd, SP_REGNUM) + 4); h8_set_reg (sd, SP_REGNUM, h8_get_reg (sd, SP_REGNUM) + 4);
} }
} }
switch (code->opcode) {
case O (O_RTEL, SN):
goto rte;
case O (O_RTSL, SN):
goto rts;
case O (O_LDM, SL):
goto next; goto next;
default:
goto illegal;
}
case O (O_DAA, SB): case O (O_DAA, SB):
/* Decimal Adjust Addition. This is for BCD arithmetic. */ /* 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) && if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) &&
!h && (0 <= (res & 0xf) && (res & 0xf) <= 9)) !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
res = res; /* Value added == 0. */ 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)) code->dst.type == X (OP_CCR, SW))
{ {
h8_set_ccr (sd, res); h8_set_ccr (sd, res);
/* Get Status Register (flags). */ GETSR (sd);
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;
} }
else if (h8300smode && else if (h8300smode &&
(code->dst.type == X (OP_EXR, SB) || (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); init_pointers (sd);
switch (rn) switch (rn)
{ {
case PC_REGNUM:
h8_set_pc (sd, intval);
break;
default: default:
(*sim_callback->printf_filtered) (sim_callback, (*sim_callback->printf_filtered) (sim_callback,
"sim_store_register: bad regnum %d.\n", "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: case R7_REGNUM:
h8_set_reg (sd, rn, intval); h8_set_reg (sd, rn, intval);
break; break;
case PC_REGNUM:
h8_set_pc (sd, intval);
break;
case CCR_REGNUM: case CCR_REGNUM:
h8_set_ccr (sd, intval); h8_set_ccr (sd, intval);
break; break;
@ -4607,9 +4669,11 @@ sim_store_register (SIM_DESC sd, int rn, unsigned char *value, int length)
case CYCLE_REGNUM: case CYCLE_REGNUM:
h8_set_cycles (sd, longval); h8_set_cycles (sd, longval);
break; break;
case INST_REGNUM: case INST_REGNUM:
h8_set_insts (sd, longval); h8_set_insts (sd, longval);
break; break;
case TICK_REGNUM: case TICK_REGNUM:
h8_set_ticks (sd, longval); h8_set_ticks (sd, longval);
break; break;
@ -4776,7 +4840,7 @@ set_h8300h (unsigned long machine)
This function being replaced by a sim_open:ARGV configuration This function being replaced by a sim_open:ARGV configuration
option. */ option. */
if (machine == bfd_mach_h8300sx) if (machine == bfd_mach_h8300sx || machine == bfd_mach_h8300sxn)
h8300sxmode = 1; h8300sxmode = 1;
if (machine == bfd_mach_h8300s || machine == bfd_mach_h8300sn || h8300sxmode) if (machine == bfd_mach_h8300s || machine == bfd_mach_h8300sn || h8300sxmode)