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>
* 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
*
@ -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 (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 (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);
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_RTE, SN): /* rte, return from exception */
rte:
/* 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 */
{
int tmp;
rts:
tmp = h8_get_reg (sd, SP_REGNUM);
tmp = h8_get_reg (sd, SP_REGNUM);
if (h8300hmode)
{
pc = GET_MEMORY_L (tmp);
tmp += 4;
}
else
{
pc = GET_MEMORY_W (tmp);
tmp += 2;
}
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;
}
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)