X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=sim%2Fh8300%2Fcompile.c;h=0d307577ae332b753205f5b8ac11d8646985356c;hb=b86015eaa50eb4b44a7055a5114262e94040213a;hp=f416695277d40e1cfb43c423b5f426dedc32cbb8;hpb=9f70f8ec0400d4011d748ea813414819bbb5fdf7;p=binutils-gdb.git diff --git a/sim/h8300/compile.c b/sim/h8300/compile.c index f416695277d..0d307577ae3 100644 --- a/sim/h8300/compile.c +++ b/sim/h8300/compile.c @@ -53,7 +53,7 @@ static void set_simcache_size (SIM_DESC, int); #define X(op, size) (op * 4 + size) -#define SP (h8300hmode ? SL : SW) +#define SP (h8300hmode && !h8300_normal_mode ? SL : SW) #define h8_opcodes ops #define DEFINE_TABLE @@ -510,6 +510,7 @@ enum { POLL_QUIT_INTERVAL = 0x80000 }; int h8300hmode = 0; int h8300smode = 0; +int h8300_normal_mode = 0; int h8300sxmode = 0; static int memory_size; @@ -539,7 +540,7 @@ bitfrom (int x) case L_32: return SL; case L_P: - return h8300hmode ? SL : SW; + return (h8300hmode && !h8300_normal_mode)? SL : SW; } return 0; } @@ -575,9 +576,9 @@ lvalue (SIM_DESC sd, int x, int rn, unsigned int *val) static int cmdline_location() { - if (h8300smode) + if (h8300smode && !h8300_normal_mode) return 0xffff00L; - else if (h8300hmode) + else if (h8300hmode && !h8300_normal_mode) return 0x2ff00L; else return 0xff00L; @@ -606,6 +607,10 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst) (q->available == AV_H8H && !h8300hmode)) continue; + cst[0] = cst[1] = cst[2] = 0; + reg[0] = reg[1] = reg[2] = 0; + rdisp[0] = rdisp[1] = rdisp[2] = 0; + while (1) { op_type looking_for = *nib; @@ -770,26 +775,11 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst) (looking_for & MODE) == INDEXB || (looking_for & MODE) == INDEXW || (looking_for & MODE) == INDEXL) - { switch (looking_for & SIZE) { case L_2: cst[opnum] = thisnib & 3; - - /* DISP2 special treatment. */ - if ((looking_for & MODE) == DISP) - { - switch (OP_SIZE (q->how)) { - default: break; - case SW: - cst[opnum] *= 2; - break; - case SL: - cst[opnum] *= 4; - break; - } - } break; case L_8: cst[opnum] = SEXTCHAR (data[len / 2]); @@ -818,7 +808,9 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst) (looking_for & SIZE) == L_16U) { cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1]; - if ((looking_for & SIZE) != L_16U) + /* Immediates are always unsigned. */ + if ((looking_for & SIZE) != L_16U && + (looking_for & MODE) != IMM) cst[opnum] = (short) cst[opnum]; /* Sign extend. */ } else if (looking_for & ABSJMP) @@ -846,8 +838,10 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst) } else if ((looking_for & MODE) == VECIND) { - /* FIXME: Multiplier should be 2 for "normal" mode. */ - cst[opnum] = ((data[1] & 0x7f) + 0x80) * 4; + if(h8300_normal_mode) + cst[opnum] = ((data[1] & 0x7f) + 0x80) * 2; + else + cst[opnum] = ((data[1] & 0x7f) + 0x80) * 4; cst[opnum] += h8_get_vbr (sd); /* Add vector base reg. */ } else if ((looking_for & SIZE) == L_32) @@ -1024,7 +1018,7 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst) p->literal = 0; if (OP_KIND (q->how) == O_JSR || OP_KIND (q->how) == O_JMP) - if (lvalue (sd, p->type, p->reg, &p->type)) + if (lvalue (sd, p->type, p->reg, (unsigned int *)&p->type)) goto end; } else if ((x & MODE) == ABS) @@ -1056,7 +1050,7 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst) p->literal = cst[opnum]; if (OP_KIND (q->how) == O_JSR || OP_KIND (q->how) == O_JMP) - if (lvalue (sd, p->type, p->reg, &p->type)) + if (lvalue (sd, p->type, p->reg, (unsigned int *)&p->type)) goto end; } else if ((x & MODE) == PCREL) @@ -1070,31 +1064,64 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst) p->type = X (OP_IMM, SP); p->literal = cst[opnum]; } - else if ((x & MODE) == INDEXB || - (x & MODE) == INDEXW || - (x & MODE) == INDEXL || - (x & MODE) == DISP) + else if ((x & MODE) == INDEXB) { - /* Use the instruction to determine - the operand size. */ - switch (x & MODE) { - case INDEXB: - p->type = X (OP_INDEXB, OP_SIZE (q->how)); - break; - case INDEXW: - p->type = X (OP_INDEXW, OP_SIZE (q->how)); - break; - case INDEXL: - p->type = X (OP_INDEXL, OP_SIZE (q->how)); - break; - case DISP: - p->type = X (OP_DISP, OP_SIZE (q->how)); - break; - } - + p->type = X (OP_INDEXB, OP_SIZE (q->how)); + p->literal = cst[opnum]; + p->reg = rdisp[opnum]; + } + else if ((x & MODE) == INDEXW) + { + p->type = X (OP_INDEXW, OP_SIZE (q->how)); + p->literal = cst[opnum]; + p->reg = rdisp[opnum]; + } + else if ((x & MODE) == INDEXL) + { + p->type = X (OP_INDEXL, OP_SIZE (q->how)); p->literal = cst[opnum]; p->reg = rdisp[opnum]; } + else if ((x & MODE) == DISP) + { + /* Yuck -- special for mova args. */ + if (strncmp (q->name, "mova", 4) == 0 && + (x & SIZE) == L_2) + { + /* Mova can have a DISP2 dest, with an + INDEXB or INDEXW src. The multiplier + for the displacement value is determined + by the src operand, not by the insn. */ + + switch (OP_KIND (dst->src.type)) + { + case OP_INDEXB: + p->type = X (OP_DISP, SB); + p->literal = cst[opnum]; + break; + case OP_INDEXW: + p->type = X (OP_DISP, SW); + p->literal = cst[opnum] * 2; + break; + default: + goto fail; + } + } + else + { + p->type = X (OP_DISP, OP_SIZE (q->how)); + p->literal = cst[opnum]; + /* DISP2 is special. */ + if ((x & SIZE) == L_2) + switch (OP_SIZE (q->how)) + { + case SB: break; + case SW: p->literal *= 2; break; + case SL: p->literal *= 4; break; + } + } + p->reg = rdisp[opnum]; + } else if (x & CTRL) { switch (reg[opnum]) @@ -1750,9 +1777,9 @@ init_pointers (SIM_DESC sd) littleendian.i = 1; - if (h8300smode) + if (h8300smode && !h8300_normal_mode) memory_size = H8300S_MSIZE; - else if (h8300hmode) + else if (h8300hmode && !h8300_normal_mode) memory_size = H8300H_MSIZE; else memory_size = H8300_MSIZE; @@ -1864,7 +1891,7 @@ case O (name, SB): \ goto end; \ if (fetch (sd, &code->src, &tmp)) \ goto end; \ - m = 1 << tmp; \ + m = 1 << (tmp & 7); \ op; \ if (s) \ if (store (sd, &code->dst,ea)) \ @@ -1926,7 +1953,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) } oldmask = h8_get_mask (sd); - if (!h8300hmode) + if (!h8300hmode || h8300_normal_mode) h8_set_mask (sd, 0xffff); do { @@ -1977,8 +2004,47 @@ sim_resume (SIM_DESC sd, int step, int siggnal) (mova/b, mova/w, mova/l). 4) Add literal value of 1st argument (src). 5) Store result in 3rd argument (op3). + */ + + /* Alas, since this is the only instruction with 3 arguments, + decode doesn't handle them very well. Some fix-up is required. + + a) The size of dst is determined by whether src is + INDEXB or INDEXW. */ + if (OP_KIND (code->src.type) == OP_INDEXB) + code->dst.type = X (OP_KIND (code->dst.type), SB); + else if (OP_KIND (code->src.type) == OP_INDEXW) + code->dst.type = X (OP_KIND (code->dst.type), SW); + + /* b) If op3 == null, then this is the short form of the insn. + Dst is the dispreg of src, and op3 is the 32-bit form + of the same register. */ + + if (code->op3.type == 0) + { + /* Short form: src == INDEXB/INDEXW, dst == op3 == 0. + We get to compose dst and op3 as follows: + + op3 is a 32-bit register, ID == src.reg. + dst is the same register, but 8 or 16 bits + depending on whether src is INDEXB or INDEXW. + */ + + code->op3.type = X (OP_REG, SL); + code->op3.reg = code->src.reg; + code->op3.literal = 0; + + if (OP_KIND (code->src.type) == OP_INDEXB) + { + code->dst.type = X (OP_REG, SB); + code->dst.reg = code->op3.reg + 8; + } + else + code->dst.type = X (OP_REG, SW); + } + if (fetch (sd, &code->dst, &ea)) goto end; @@ -2503,7 +2569,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) { if (h8300smode) h8_set_exr (sd, (trace << 7) | intMask); - res = h8_get_exr (sd); + rd = h8_get_exr (sd); } else goto illegal; @@ -2730,7 +2796,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) /* Setting char_ptr_size to the sizeof (char *) on the different architectures. */ - if (h8300hmode || h8300smode) + if ((h8300hmode || h8300smode) && !h8300_normal_mode) { char_ptr_size = 4; } @@ -2799,7 +2865,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) for (i = 0; i < no_of_args; i++) { /* Saving the argv pointer. */ - if (h8300hmode || h8300smode) + if ((h8300hmode || h8300smode) && !h8300_normal_mode) { SET_MEMORY_L (argv_ptrs_location, argv_ptrs[i]); } @@ -2815,7 +2881,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) /* Required by POSIX, Setting 0x0 at the end of the list of argv pointers. */ - if (h8300hmode || h8300smode) + if ((h8300hmode || h8300smode) && !h8300_normal_mode) { SET_MEMORY_L (old_sp, 0x0); } @@ -2854,7 +2920,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) /* Setting filename_ptr to first argument of open, */ /* and trying to get mode. */ - if (h8300sxmode || h8300hmode || h8300smode) + if ((h8300sxmode || h8300hmode || h8300smode) && !h8300_normal_mode) { filename_ptr = GET_L_REG (0); mode = GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM) + 4); @@ -2905,8 +2971,8 @@ sim_resume (SIM_DESC sd, int step, int siggnal) int read_return = 0; /* Return value from callback to read. */ - fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0); - buf_size = h8300hmode ? GET_L_REG (2) : GET_W_REG (2); + fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0); + buf_size = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2); char_ptr = (char *) malloc (sizeof (char) * buf_size); @@ -2940,9 +3006,9 @@ sim_resume (SIM_DESC sd, int step, int siggnal) int write_return; /* Return value from callback to write. */ int i = 0; /* Loop counter */ - fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0); - char_ptr = h8300hmode ? GET_L_REG (1) : GET_W_REG (1); - len = h8300hmode ? GET_L_REG (2) : GET_W_REG (2); + fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0); + char_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1); + len = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2); /* Allocating space for the characters to be written. */ ptr = (char *) malloc (sizeof (char) * len); @@ -2972,9 +3038,9 @@ sim_resume (SIM_DESC sd, int step, int siggnal) int origin; /* Origin */ int lseek_return; /* Return value from callback to lseek. */ - fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0); - offset = h8300hmode ? GET_L_REG (1) : GET_W_REG (1); - origin = h8300hmode ? GET_L_REG (2) : GET_W_REG (2); + fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0); + offset = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1); + origin = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2); /* Callback lseek and return offset. */ lseek_return = @@ -2990,7 +3056,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) int fd; /* File descriptor */ int close_return; /* Return value from callback to close. */ - fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0); + fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0); /* Callback close and return. */ close_return = sim_callback->close (sim_callback, fd); @@ -3008,10 +3074,10 @@ sim_resume (SIM_DESC sd, int step, int siggnal) int stat_ptr; /* Pointer to stat record. */ char *temp_stat_ptr; /* Temporary stat_rec pointer. */ - fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0); + fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0); /* Setting stat_ptr to second argument of stat. */ - stat_ptr = h8300hmode ? GET_L_REG (1) : GET_W_REG (1); + stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1); /* Callback stat and return. */ fstat_return = sim_callback->fstat (sim_callback, fd, &stat_rec); @@ -3060,7 +3126,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) int i = 0; /* Loop Counter */ /* Setting filename_ptr to first argument of open. */ - filename_ptr = h8300hmode ? GET_L_REG (0) : GET_W_REG (0); + filename_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0); /* Trying to find the length of the filename. */ temp_char = GET_MEMORY_B (h8_get_reg (sd, 0)); @@ -3084,7 +3150,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) /* Setting stat_ptr to second argument of stat. */ /* stat_ptr = h8_get_reg (sd, 1); */ - stat_ptr = h8300hmode ? GET_L_REG (1) : GET_W_REG (1); + stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1); /* Callback stat and return. */ stat_return = @@ -3151,10 +3217,10 @@ sim_resume (SIM_DESC sd, int step, int siggnal) if (fetch2 (sd, &code->dst, &rd)) goto end; - if (code->src.type == X (OP_IMM, SB)) + if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0) + ea = 1; /* unary op */ + else /* binary op */ fetch (sd, &code->src, &ea); - else - ea = 1; if (code->opcode == O (O_SHLL, SB)) { @@ -3175,10 +3241,10 @@ sim_resume (SIM_DESC sd, int step, int siggnal) if (fetch2 (sd, &code->dst, &rd)) goto end; - if (code->src.type == X (OP_IMM, SW)) - fetch (sd, &code->src, &ea); + if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0) + ea = 1; /* unary op */ else - ea = 1; + fetch (sd, &code->src, &ea); if (code->opcode == O (O_SHLL, SW)) { @@ -3199,10 +3265,10 @@ sim_resume (SIM_DESC sd, int step, int siggnal) if (fetch2 (sd, &code->dst, &rd)) goto end; - if (code->src.type == X (OP_IMM, SL)) - fetch (sd, &code->src, &ea); + if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0) + ea = 1; /* unary op */ else - ea = 1; + fetch (sd, &code->src, &ea); if (code->opcode == O (O_SHLL, SL)) { @@ -3492,7 +3558,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) call: tmp = h8_get_reg (sd, SP_REGNUM); - if (h8300hmode) + if (h8300hmode && !h8300_normal_mode) { tmp -= 4; SET_MEMORY_L (tmp, code->next_pc); @@ -3524,7 +3590,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) h8_set_exr (sd, GET_MEMORY_L (tmp)); tmp += 4; } - if (h8300hmode) + if (h8300hmode && !h8300_normal_mode) { h8_set_ccr (sd, GET_MEMORY_L (tmp)); tmp += 4; @@ -3547,7 +3613,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) rts: tmp = h8_get_reg (sd, SP_REGNUM); - if (h8300hmode) + if (h8300hmode && !h8300_normal_mode) { pc = GET_MEMORY_L (tmp); tmp += 4; @@ -3575,6 +3641,17 @@ sim_resume (SIM_DESC sd, int step, int siggnal) sim_engine_set_run_state (sd, sim_exited, SIM_WEXITSTATUS (h8_get_reg (sd, 0))); } +#if 0 + /* Unfortunately this won't really work, because + when we take a breakpoint trap, R0 has a "random", + user-defined value. Don't see any immediate solution. */ + else if (SIM_WIFSTOPPED (h8_get_reg (sd, 0))) + { + /* Pass the stop signal up to gdb. */ + sim_engine_set_run_state (sd, sim_stopped, + SIM_WSTOPSIG (h8_get_reg (sd, 0))); + } +#endif else { /* Treat it as a sigtrap. */ @@ -3584,16 +3661,26 @@ sim_resume (SIM_DESC sd, int step, int siggnal) 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); - + goto end; /* res is vector number. */ + + tmp = h8_get_reg (sd, SP_REGNUM); + if(h8300_normal_mode) + { + tmp -= 2; + SET_MEMORY_W (tmp, code->next_pc); + tmp -= 2; + SET_MEMORY_W (tmp, h8_get_ccr (sd)); + } + else + { + 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; @@ -3602,8 +3689,10 @@ sim_resume (SIM_DESC sd, int step, int siggnal) h8_set_reg (sd, SP_REGNUM, tmp); - /* FIXME: "normal" mode should use 2-byte ptrs. */ - pc = GET_MEMORY_L (0x20 + res * 4); + if(h8300_normal_mode) + pc = GET_MEMORY_L (0x10 + res * 2); /* Vector addresses are 0x10,0x12,0x14 and 0x16 */ + else + pc = GET_MEMORY_L (0x20 + res * 4); goto end; case O (O_BPT, SN): @@ -3800,13 +3889,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) fetch (sd, &code->dst, &rd)) goto end; - /* FIXME: is this the right place to be doing sign extend? */ - if (OP_KIND (code->src.type) == OP_IMM && - (ea & 8) != 0) - ea |= 0xfff0; - else - ea = SEXTSHORT (ea); - + ea = SEXTSHORT (ea); res = SEXTSHORT (ea * SEXTSHORT (rd)); n = res & 0x8000; @@ -3821,11 +3904,6 @@ sim_resume (SIM_DESC sd, int step, int siggnal) fetch (sd, &code->dst, &rd)) goto end; - /* FIXME: is this the right place to be doing sign extend? */ - if (OP_KIND (code->src.type) == OP_IMM && - (ea & 8) != 0) - ea |= 0xfffffff0; - res = ea * rd; n = res & 0x80000000; @@ -3839,11 +3917,6 @@ sim_resume (SIM_DESC sd, int step, int siggnal) fetch (sd, &code->dst, &rd)) goto end; - /* FIXME: is this the right place to be doing sign extend? */ - if (OP_KIND (code->src.type) == OP_IMM && - (ea & 8) != 0) - ea |= 0xfffffff0; - /* Compute upper 32 bits of the 64-bit result. */ res = (((long long) ea) * ((long long) rd)) >> 32; @@ -3899,13 +3972,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) fetch (sd, &code->dst, &rd)) goto end; - /* FIXME: is this the right place to be doing sign extend? */ - if (OP_KIND (code->src.type) == OP_IMM && - (ea & 8) != 0) - ea |= 0xfffffff0; - else - ea = SEXTCHAR (ea); - + ea = SEXTCHAR (ea); res = ea * SEXTCHAR (rd); n = res & 0x8000; @@ -3920,13 +3987,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) fetch (sd, &code->dst, &rd)) goto end; - /* FIXME: is this the right place to be doing sign extend? */ - if (OP_KIND (code->src.type) == OP_IMM && - (ea & 8) != 0) - ea |= 0xfff0; - else - ea = SEXTSHORT (ea); - + ea = SEXTSHORT (ea); res = ea * SEXTSHORT (rd & 0xffff); n = res & 0x80000000; @@ -4017,11 +4078,6 @@ sim_resume (SIM_DESC sd, int step, int siggnal) fetch (sd, &code->dst, &rd)) goto end; - /* FIXME: is this the right place to be doing sign extend? */ - if (OP_KIND (code->src.type) == OP_IMM && - (ea & 8) != 0) - ea |= 0xfffffff0; - if (ea) { res = SEXTSHORT (rd) / SEXTSHORT (ea); @@ -4043,11 +4099,6 @@ sim_resume (SIM_DESC sd, int step, int siggnal) fetch (sd, &code->dst, &rd)) goto end; - /* FIXME: is this the right place to be doing sign extend? */ - if (OP_KIND (code->src.type) == OP_IMM && - (ea & 8) != 0) - ea |= 0xfffffff0; - if (ea) { res = rd / ea; @@ -4119,13 +4170,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) goto end; rd = SEXTSHORT (rd); - - /* FIXME: is this the right place to be doing sign extend? */ - if (OP_KIND (code->src.type) == OP_IMM && - (ea & 8) != 0) - ea |= 0xfffffff0; - else - ea = SEXTCHAR (ea); + ea = SEXTCHAR (ea); if (ea) { @@ -4150,12 +4195,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) fetch (sd, &code->dst, &rd)) goto end; - /* FIXME: is this the right place to be doing sign extend? */ - if (OP_KIND (code->src.type) == OP_IMM && - (ea & 8) != 0) - ea |= 0xfffffff0; - else - ea = SEXTSHORT (ea); + ea = SEXTSHORT (ea); if (ea) { @@ -4632,7 +4672,10 @@ sim_store_register (SIM_DESC sd, int rn, unsigned char *value, int length) switch (rn) { case PC_REGNUM: - h8_set_pc (sd, intval); + if(h8300_normal_mode) + h8_set_pc (sd, shortval); /* PC for Normal mode is 2 bytes */ + else + h8_set_pc (sd, intval); break; default: (*sim_callback->printf_filtered) (sim_callback, @@ -4743,7 +4786,8 @@ sim_fetch_register (SIM_DESC sd, int rn, unsigned char *buf, int length) longreg = 1; break; } - if (h8300hmode || longreg) + /* In Normal mode PC is 2 byte, but other registers are 4 byte */ + if ((h8300hmode || longreg) && !(rn == PC_REGNUM && h8300_normal_mode)) { buf[0] = v >> 24; buf[1] = v >> 16; @@ -4840,6 +4884,8 @@ set_h8300h (unsigned long machine) This function being replaced by a sim_open:ARGV configuration option. */ + h8300hmode = h8300smode = h8300sxmode = h8300_normal_mode = 0; + if (machine == bfd_mach_h8300sx || machine == bfd_mach_h8300sxn) h8300sxmode = 1; @@ -4848,6 +4894,9 @@ set_h8300h (unsigned long machine) if (machine == bfd_mach_h8300h || machine == bfd_mach_h8300hn || h8300smode) h8300hmode = 1; + + if(machine == bfd_mach_h8300hn || machine == bfd_mach_h8300sn || machine == bfd_mach_h8300sxn) + h8300_normal_mode = 1; } /* Cover function of sim_state_free to free the cpu buffers as well. */ @@ -4957,7 +5006,7 @@ sim_load (SIM_DESC sd, char *prog, bfd *abfd, int from_tty) if (abfd != NULL) prog_bfd = abfd; else - prog_bfd = bfd_openr (prog, "coff-h8300"); + prog_bfd = bfd_openr (prog, NULL); if (prog_bfd != NULL) { /* Set the cpu type. We ignore failure from bfd_check_format @@ -4983,9 +5032,9 @@ sim_load (SIM_DESC sd, char *prog, bfd *abfd, int from_tty) switching between H8/300 and H8/300H programs without exiting gdb. */ - if (h8300smode) + if (h8300smode && !h8300_normal_mode) memory_size = H8300S_MSIZE; - else if (h8300hmode) + else if (h8300hmode && !h8300_normal_mode) memory_size = H8300H_MSIZE; else memory_size = H8300_MSIZE; @@ -5001,6 +5050,7 @@ sim_load (SIM_DESC sd, char *prog, bfd *abfd, int from_tty) calloc (sizeof (char), memory_size)); h8_set_cache_idx_buf (sd, (unsigned short *) calloc (sizeof (short), memory_size)); + sd->memory_size = memory_size; h8_set_eightbit_buf (sd, (unsigned char *) calloc (sizeof (char), 256)); /* `msize' must be a power of two. */