diff -Nru -X /home/ysato/.exclude-diff gdb-5.2.1/gdb/config/h8300/tm-h8300.h gdb-5.2.1.h8sim/gdb/config/h8300/tm-h8300.h --- gdb-5.2.1/gdb/config/h8300/tm-h8300.h 2003-09-06 23:10:09.000000000 +0900 +++ gdb-5.2.1.h8sim/gdb/config/h8300/tm-h8300.h 2003-12-11 00:13:18.000000000 +0900 @@ -36,6 +36,7 @@ GDB_TARGET_IS_H8300 in remote-e7000.c */ extern int h8300hmode; extern int h8300smode; +extern int int32mode; /* Number of bytes in a word */ @@ -59,9 +60,11 @@ extern void h8300_init_extra_frame_info (); #undef TARGET_INT_BIT -#define TARGET_INT_BIT 16 +#define TARGET_INT_BIT (int32mode ? 32:16) #undef TARGET_LONG_BIT #define TARGET_LONG_BIT 32 +#undef TARGET_LONG_LONG_BIT +#define TARGET_LONG_LONG_BIT (int32mode ? 64:32) #undef TARGET_PTR_BIT #define TARGET_PTR_BIT (h8300hmode ? 32:16) @@ -89,7 +92,7 @@ #define INNER_THAN(lhs,rhs) ((lhs) < (rhs)) /*#define BREAKPOINT {0x7A, 0xFF} */ -#define BREAKPOINT {0x01, 0x80} /* Sleep */ +#define BREAKPOINT {0x01, 0x81} /* bkpt(?) */ #define REMOTE_BREAKPOINT { 0x57, 0x30} /* trapa #3 */ /* If your kernel resets the pc after the trap happens you may need to define this before including this file. */ @@ -100,7 +103,7 @@ #define REGISTER_SIZE 4 -#define NUM_REGS 13 +#define NUM_REGS 14 #define REGISTER_BYTES (NUM_REGS * 4) @@ -157,6 +160,7 @@ #define SP_REGNUM 7 /* Contains address of top of stack */ #define CCR_REGNUM 8 /* Contains processor status */ #define PC_REGNUM 9 /* Contains program counter */ +#define EXR_REGNUM 10 /* Contains processor extend status */ /* Extract from an array REGBUF containing the (raw) register state a function return value of type TYPE, and copy that, in virtual format, diff -Nru -X /home/ysato/.exclude-diff gdb-5.2.1/gdb/h8300-tdep.c gdb-5.2.1.h8sim/gdb/h8300-tdep.c --- gdb-5.2.1/gdb/h8300-tdep.c 2003-09-06 23:10:24.000000000 +0900 +++ gdb-5.2.1.h8sim/gdb/h8300-tdep.c 2003-12-11 00:58:24.000000000 +0900 @@ -36,10 +36,10 @@ #include "value.h" #include "regcache.h" -extern int h8300hmode, h8300smode; +extern int h8300hmode, h8300smode, int32mode; #undef NUM_REGS -#define NUM_REGS 11 +#define NUM_REGS (h8300smode ? 12:11) #define UNSIGNED_SHORT(X) ((X) & 0xffff) @@ -63,6 +63,10 @@ {"er0", "er1", "er2", "er3", "er4", "er5", "er6", "sp", "ccr", "pc", "cycles", "tick", "inst"}; +static char *h8300s_register_names[] = +{"er0", "er1", "er2", "er3", "er4", "er5", "er6", + "sp", "ccr", "pc", "exr", "cycles", "tick", "inst"}; + char **h8300_register_names = original_register_names; @@ -731,7 +735,9 @@ static void set_register_names (void) { - if (h8300hmode != 0) + if (h8300smode != 0) + h8300_register_names = h8300s_register_names; + else if (h8300hmode != 0) h8300_register_names = h8300h_register_names; else h8300_register_names = original_register_names; @@ -774,6 +780,23 @@ help_list (setmemorylist, "set memory ", -1, gdb_stdout); } +static void set_intsize(char *args, int from_tty) +{ + int size = 0; + if (args) + size = atoi(args); + switch (size) { + case 16: + int32mode = 0; + break ; + case 32: + int32mode = 1; + break ; + default: + printf_unfiltered ("\"set intsize\" must be followed by 16 or 32\n"); + } +} + /* set_machine_hook is called as the exec file is being opened, but before the symbol file is opened. This allows us to set the h8300hmode flag based on the machine type specified in the exec @@ -818,6 +841,9 @@ add_cmd ("h8300s", class_support, h8300s_command, "Set machine to be H8/300S.", &setmemorylist); + add_cmd ("intsize", no_class, set_intsize, + "set the int size", &setlist); + /* Add a hook to set the machine type when we're loading a file. */ specify_exec_file_hook (set_machine_hook); @@ -828,45 +854,65 @@ void h8300_print_register_hook (int regno) { - if (regno == CCR_REGNUM) + switch (regno) { - /* CCR register */ - int C, Z, N, V; - unsigned char b[REGISTER_SIZE]; - unsigned char l; - read_relative_register_raw_bytes (regno, b); - l = b[REGISTER_VIRTUAL_SIZE (CCR_REGNUM) - 1]; - printf_unfiltered ("\t"); - printf_unfiltered ("I-%d - ", (l & 0x80) != 0); - printf_unfiltered ("H-%d - ", (l & 0x20) != 0); - N = (l & 0x8) != 0; - Z = (l & 0x4) != 0; - V = (l & 0x2) != 0; - C = (l & 0x1) != 0; - printf_unfiltered ("N-%d ", N); - printf_unfiltered ("Z-%d ", Z); - printf_unfiltered ("V-%d ", V); - printf_unfiltered ("C-%d ", C); - if ((C | Z) == 0) - printf_unfiltered ("u> "); - if ((C | Z) == 1) - printf_unfiltered ("u<= "); - if ((C == 0)) - printf_unfiltered ("u>= "); - if (C == 1) - printf_unfiltered ("u< "); - if (Z == 0) - printf_unfiltered ("!= "); - if (Z == 1) - printf_unfiltered ("== "); - if ((N ^ V) == 0) - printf_unfiltered (">= "); - if ((N ^ V) == 1) - printf_unfiltered ("< "); - if ((Z | (N ^ V)) == 0) - printf_unfiltered ("> "); - if ((Z | (N ^ V)) == 1) - printf_unfiltered ("<= "); + case CCR_REGNUM: + { + /* CCR register */ + int C, Z, N, V; + unsigned char b[REGISTER_SIZE]; + unsigned char l; + read_relative_register_raw_bytes (regno, b); + l = b[REGISTER_VIRTUAL_SIZE (CCR_REGNUM) - 1]; + printf_unfiltered ("\t"); + printf_unfiltered ("I-%d - ", (l & 0x80) != 0); + printf_unfiltered ("H-%d - ", (l & 0x20) != 0); + N = (l & 0x8) != 0; + Z = (l & 0x4) != 0; + V = (l & 0x2) != 0; + C = (l & 0x1) != 0; + printf_unfiltered ("N-%d ", N); + printf_unfiltered ("Z-%d ", Z); + printf_unfiltered ("V-%d ", V); + printf_unfiltered ("C-%d ", C); + if ((C | Z) == 0) + printf_unfiltered ("u> "); + if ((C | Z) == 1) + printf_unfiltered ("u<= "); + if ((C == 0)) + printf_unfiltered ("u>= "); + if (C == 1) + printf_unfiltered ("u< "); + if (Z == 0) + printf_unfiltered ("!= "); + if (Z == 1) + printf_unfiltered ("== "); + if ((N ^ V) == 0) + printf_unfiltered (">= "); + if ((N ^ V) == 1) + printf_unfiltered ("< "); + if ((Z | (N ^ V)) == 0) + printf_unfiltered ("> "); + if ((Z | (N ^ V)) == 1) + printf_unfiltered ("<= "); + break; + } + case EXR_REGNUM: + { + if (h8300smode == 0) + break; + unsigned char b[REGISTER_SIZE]; + unsigned char l; + read_relative_register_raw_bytes (regno, b); + l = b[REGISTER_VIRTUAL_SIZE (EXR_REGNUM) - 1]; + printf_unfiltered ("\t"); + printf_unfiltered ("T-%d - - - ", (l & 0x80) != 0); + printf_unfiltered ("I2-%d ", (l & 0x04) != 0); + printf_unfiltered ("I1-%d ", (l & 0x02) != 0); + printf_unfiltered ("I0-%d ", (l & 0x01) != 0); + printf_unfiltered ("INT Level %d ", (l & 0x7)); + break; + } } } diff -Nru -X /home/ysato/.exclude-diff gdb-5.2.1/include/opcode/h8300.h gdb-5.2.1.h8sim/include/opcode/h8300.h --- gdb-5.2.1/include/opcode/h8300.h 2003-09-06 23:10:55.000000000 +0900 +++ gdb-5.2.1.h8sim/include/opcode/h8300.h 2003-09-06 23:08:36.000000000 +0900 @@ -304,7 +304,8 @@ #define O_LDM 85 #define O_STM 86 #define O_STMAC 87 -#define O_LAST 88 +#define O_BKPT 88 +#define O_LAST 89 #define SB 0 #define SW 1 #define SL 2 @@ -375,6 +376,8 @@ EBITOP(O(O_BTST,SB), IMM3|B30,"btst",0x6,0x3,0x7,0xC,0x7,0xE,0x0), BITOP(O(O_BXOR,SB), IMM3|B30,"bxor",0x7,0x5,0x7,0xC,0x7,0xE,0x0), + SOP(O(O_BKPT,SN),2,"bkpt"),{{E,0,0}},{{ 0x0,0x1,0x8,0x1,E,0,0,0,0}} EOP, + TWOOP(O(O_CMP,SB), "cmp.b",0xA,0x1,0xC), WTWOP(O(O_CMP,SW), "cmp.w",0x1,0xD), diff -Nru -X /home/ysato/.exclude-diff gdb-5.2.1/sim/h8300/Makefile.in gdb-5.2.1.h8sim/sim/h8300/Makefile.in --- gdb-5.2.1/sim/h8300/Makefile.in 2003-09-06 23:11:12.000000000 +0900 +++ gdb-5.2.1.h8sim/sim/h8300/Makefile.in 2003-09-06 23:09:02.000000000 +0900 @@ -18,7 +18,7 @@ ## COMMON_PRE_CONFIG_FRAG -SIM_OBJS = compile.o sim-load.o +SIM_OBJS = compile.o sim-load.o io.o ## COMMON_POST_CONFIG_FRAG diff -Nru -X /home/ysato/.exclude-diff gdb-5.2.1/sim/h8300/compile.c gdb-5.2.1.h8sim/sim/h8300/compile.c --- gdb-5.2.1/sim/h8300/compile.c 2003-09-06 23:11:12.000000000 +0900 +++ gdb-5.2.1.h8sim/sim/h8300/compile.c 2004-02-04 02:06:30.000000000 +0900 @@ -67,6 +67,7 @@ #define OP_CCR 7 #define OP_IMM 8 #define OP_ABS 10 +#define OP_EXR 11 #define h8_opcodes ops #define DEFINE_TABLE #include "opcode/h8300.h" @@ -81,7 +82,7 @@ #define HIGH_BYTE(x) (((x) >> 8) & 0xff) #define P(X,Y) ((X << 8) | Y) -#define BUILDSR() cpu.ccr = (N << 3) | (Z << 2) | (V << 1) | C; +#define BUILDSR() cpu.ccr = (cpu.ccr & 0xf0) | (N << 3) | (Z << 2) | (V<<1) | C; #define GETSR() \ c = (cpu.ccr >> 0) & 1;\ @@ -105,6 +106,7 @@ int h8300hmode = 0; int h8300smode = 0; +int int32mode = 0; static int memory_size; @@ -319,6 +321,10 @@ bit = thisnib; } + else if (looking_for & (L_2 | IMM)) + { + plen = 1; + } else if (looking_for == E) { dst->op = q; @@ -407,6 +413,10 @@ { p->type = OP_CCR; } + else if (x & EXR) + { + p->type = OP_EXR; + } else printf ("Hmmmm %x", x); @@ -443,7 +453,7 @@ return; } else - printf ("Don't understand %x \n", looking_for); + printf ("Don't understand %x:%x \n", addr, looking_for); } len++; @@ -485,6 +495,8 @@ cpu.cache_idx[pc] = idx; } +extern int iosimulation(cpu_state_type *cpu,int cycles); +extern void init_ioregs(cpu_state_type *cpu); static unsigned char *breg[18]; static unsigned short *wreg[18]; @@ -515,18 +527,33 @@ (x < memory_size ? (cpu.memory[x]) : (cpu.eightbit[x & 0xff])) #define SET_MEMORY_L(x,y) \ +if (x >= 0x100 && x < memory_size) \ { register unsigned char *_p; register int __y = y; \ _p = (x < memory_size ? cpu.memory+x : cpu.eightbit + (x & 0xff)); \ _p[0] = (__y)>>24; _p[1] = (__y)>>16; \ - _p[2] = (__y)>>8; _p[3] = (__y)>>0;} + _p[2] = (__y)>>8; _p[3] = (__y)>>0;} \ +else \ +{ cpu.state = SIM_STATE_STOPPED; \ + cpu.exception = SIGSEGV; \ +} #define SET_MEMORY_W(x,y) \ +if (x >= 0x100 && x < memory_size) \ { register unsigned char *_p; register int __y = y; \ _p = (x < memory_size ? cpu.memory+x : cpu.eightbit + (x & 0xff)); \ - _p[0] = (__y)>>8; _p[1] =(__y);} + _p[0] = (__y)>>8; _p[1] =(__y);} \ +else \ +{ cpu.state = SIM_STATE_STOPPED; \ + cpu.exception = SIGSEGV; \ +} #define SET_MEMORY_B(x,y) \ - (x < memory_size ? (cpu.memory[(x)] = y) : (cpu.eightbit[x & 0xff] = y)) +if (x >= 0x100 && x < memory_size) { \ + (x < memory_size ? (cpu.memory[(x)] = y) : (cpu.eightbit[x & 0xff] = y)); \ +} else \ +{ cpu.state = SIM_STATE_STOPPED; \ + cpu.exception = SIGSEGV; \ +} int fetch (arg, n) @@ -904,7 +931,7 @@ int m; \ int b; \ if (f) ea = fetch (&code->dst); \ - m=1<< fetch(&code->src); \ + m=1<< (fetch(&code->src) & 7); \ op; \ if(s) store (&code->dst,ea); goto next; \ } @@ -918,12 +945,13 @@ return 1; } + void sim_resume (sd, step, siggnal) SIM_DESC sd; { static int init1; - int cycles = 0; + static int cycles = 0; int insts = 0; int tick_start = get_now (); void (*prev) (); @@ -936,6 +964,8 @@ int pc; int c, nz, v, n; int oldmask; + int vector; + int trace = 0; init_pointers (); prev = signal (SIGINT, control_c); @@ -967,6 +997,12 @@ decoded_inst *code; top: + if (pc>=memory_size) { + cpu.state = SIM_STATE_STOPPED; + cpu.exception = SIGSEGV; + continue ; + } + cidx = cpu.cache_idx[pc]; code = cpu.cache + cidx; @@ -998,6 +1034,38 @@ { cycles += code->cycles; insts++; + if ((vector=iosimulation(&cpu,cycles)) && ((cpu.ccr & 0x80) == 0)) + { + BUILDSR(); + cpu.regs[7]-=4; + SET_MEMORY_L(cpu.regs[7],(cpu.ccr<<24)|pc); + pc=GET_MEMORY_L(vector*(h8300hmode?4:2)); + if (h8300smode) { + int exr; + exr = cpu.exr << 8 | cpu.exr; + cpu.regs[7]-=2; + SET_MEMORY_W(cpu.regs[7],exr); + } + cpu.ccr|=0x80; + goto top; + } + if (h8300smode) { + if (trace) { + int exr; + BUILDSR(); + cpu.regs[7]-=4; + SET_MEMORY_L(cpu.regs[7],(cpu.ccr<<24)|pc); + pc=GET_MEMORY_L(5*4); + exr = cpu.exr << 8 | cpu.exr; + cpu.regs[7]-=2; + SET_MEMORY_W(cpu.regs[7],exr); + cpu.ccr|=0x80; + cpu.exr&=0x7f; + trace = 0; + goto top; + } + trace = (cpu.exr & 0x80); + } } switch (code->opcode) @@ -1066,12 +1134,21 @@ case O (O_MOV_TO_MEM, SB): res = GET_B_REG (code->src.reg); + if ( (code->dst.type == X (OP_DEC, SB)) && + (code->src.reg == code->dst.reg)) + res -= 1; goto log8; case O (O_MOV_TO_MEM, SW): res = GET_W_REG (code->src.reg); + if ( (code->dst.type == X (OP_DEC, SW)) && + (code->src.reg == code->dst.reg)) + res -= 2; goto log16; case O (O_MOV_TO_MEM, SL): res = GET_L_REG (code->src.reg); + if ( (code->dst.type == X (OP_DEC, SL)) && + (code->src.reg == code->dst.reg)) + res -= 4; goto log32; @@ -1171,19 +1248,28 @@ #define GET_CCR(x) BUILDSR();x = cpu.ccr case O (O_ANDC, SB): - GET_CCR (rd); + switch(code->dst.type) { + case OP_CCR: GET_CCR (rd); break; + case OP_EXR: rd = cpu.exr; break; + } ea = code->src.literal; res = rd & ea; goto setc; case O (O_ORC, SB): - GET_CCR (rd); + switch(code->dst.type) { + case OP_CCR: GET_CCR (rd); break; + case OP_EXR: rd = cpu.exr; break; + } ea = code->src.literal; res = rd | ea; goto setc; case O (O_XORC, SB): - GET_CCR (rd); + switch(code->dst.type) { + case OP_CCR: GET_CCR (rd); break; + case OP_EXR: rd = cpu.exr; break; + } ea = code->src.literal; res = rd ^ ea; goto setc; @@ -1355,6 +1441,7 @@ cpu.state = SIM_STATE_STOPPED; cpu.exception = SIGILL; goto end; +#if 0 case O (O_SLEEP, SN): /* FIXME: Doesn't this break for breakpoints when r0 contains just the right (er, wrong) value? */ @@ -1368,6 +1455,35 @@ else cpu.exception = SIGTRAP; goto end; +#endif +#define SIM_WIFEXITED(v) (((v) & 0xff) == 0) +#define SIM_WIFSIGNALED(v) (((v) & 0x7f) > 0 && (((v) & 0x7f) < 0x7f)) + case O (O_SLEEP, SN): + if ((cpu.ccr & 0x80) != 0) + { + cpu.state = SIM_STATE_STOPPED; + cpu.exception = SIGTRAP; + } else + while (cpu.state = SIM_STATE_RUNNING) { + if ((vector=iosimulation(&cpu,cycles)) && !(cpu.ccr & 0x80)) + { + usleep(100); + BUILDSR(); + cpu.regs[7]-=4; + SET_MEMORY_L(cpu.regs[7],(cpu.ccr<<24)|pc+2); + pc=GET_MEMORY_L(vector*(h8300hmode?4:2)); + if (h8300smode) { + int exr; + exr = cpu.exr << 8 | cpu.exr; + cpu.regs[7]-=2; + SET_MEMORY_W(cpu.regs[7],exr); + } + cpu.ccr|=0x80; + goto top; + } + cycles++; + } + goto end; case O (O_BPT, SN): cpu.state = SIM_STATE_STOPPED; cpu.exception = SIGTRAP; @@ -1528,7 +1644,192 @@ } } goto next; - + case O (O_LDC, SB): + { + BUILDSR(); + switch(GET_MEMORY_B(pc)) { + case 0x03: + switch(code->src.type) { + case OP_CCR: cpu.ccr = GET_B_REG(code->src.reg); break; + case OP_EXR: cpu.exr = GET_B_REG(code->src.reg); break; + } + break; + case 0x07: + cpu.ccr = code->src.literal; break; + case 0x01: + { + switch(GET_MEMORY_B(pc+2)) { + case 0x03: + cpu.exr = GET_B_REG(code->src.reg); break; + case 0x07: + cpu.exr = code->src.literal; break; + case 0x69: + switch(code->dst.type) { + case OP_CCR: cpu.ccr = GET_MEMORY_W(GET_L_REG(code->dst.reg)); break; + case OP_EXR: cpu.exr = GET_MEMORY_W(GET_L_REG(code->dst.reg)); break; + } + break; + case 0x6f: + case 0x78: + code->src.type=X(OP_DISP,SW); + switch(code->dst.type) { + case OP_CCR: cpu.ccr = fetch (&code->src); break; + case OP_EXR: cpu.exr = fetch (&code->src); break; + } + break; + case 0x6d: + code->src.type=X(OP_INC,SW); + switch(code->dst.type) { + case OP_CCR: cpu.ccr = fetch (&code->src); break; + case OP_EXR: cpu.exr = fetch (&code->src); break; + } + break; + case 0x6b: + switch(code->dst.type) { + case OP_CCR: cpu.ccr = GET_MEMORY_W(code->src.literal); break; + case OP_EXR: cpu.exr = GET_MEMORY_W(code->src.literal); break; + } + break; + } + } + } + GETSR(); + } + goto next; + case O (O_STC, SB): + { + if (code->src.type == OP_CCR) + BUILDSR(); + switch(GET_MEMORY_B(pc)) { + case 0x02: + switch(code->src.type) { + case OP_CCR: SET_B_REG(code->dst.reg,cpu.ccr); break; + case OP_EXR: SET_B_REG(code->dst.reg,cpu.exr); break; + } + break; + case 0x01: + switch(GET_MEMORY_B(pc+2)) { + case 0x69: + switch(code->src.type) { + case OP_CCR: SET_MEMORY_W(GET_L_REG(code->dst.reg),cpu.ccr); break; + case OP_EXR: SET_MEMORY_W(GET_L_REG(code->dst.reg),cpu.exr); break; + } + break; + case 0x6f: + case 0x78: + code->dst.type=X(OP_DISP,SW); + switch(code->src.type) { + case OP_CCR: store (&code->dst,cpu.ccr); break; + case OP_EXR: store (&code->dst,cpu.exr); break; + } + break; + case 0x6d: + code->dst.type=X(OP_DEC,SW); + switch(code->src.type) { + case OP_CCR: store (&code->dst,cpu.ccr); break; + case OP_EXR: store (&code->dst,cpu.exr); break; + } + break; + case 0x6b: + switch(code->src.type) { + case OP_CCR: SET_MEMORY_W(code->dst.literal,cpu.ccr); break; + case OP_EXR: SET_MEMORY_W(code->dst.literal,cpu.exr); break; + } + break; + } + } + } + goto next; + case O (O_EEPMOV, SB): + { + int cnt=GET_B_REG(4); + if(cnt==0) cnt=0x100; + while(cnt!=0) { + SET_MEMORY_B(cpu.regs[6],GET_MEMORY_B(cpu.regs[5])); + cpu.regs[5]++; + cpu.regs[6]++; + --cnt; + } + SET_B_REG(4,cnt); + } + goto next; + case O (O_EEPMOV, SW): + { + int cnt=GET_W_REG(4); + if(cnt==0) cnt=0x10000; + while(cnt!=0) { + SET_MEMORY_B(cpu.regs[6],GET_MEMORY_B(cpu.regs[5])); + cpu.regs[5]++; + cpu.regs[6]++; + --cnt; + } + SET_W_REG(4,cnt); + } + goto next; + case O (O_RTE, SN): + { + unsigned int frame; + if (h8300smode) { + unsigned int exr; + exr = GET_MEMORY_W (cpu.regs[7]); + exr >>= 8; + exr &= 0xff; + cpu.exr = exr; + cpu.regs[7]+=2; + } + frame = GET_MEMORY_L (cpu.regs[7]); + cpu.ccr=frame>>24; + GETSR(); + pc=frame & 0xffffff; + cpu.regs[7]+=4; + }; + goto end; + case O (O_TRAPA, SB): + { + int v; + v=GET_MEMORY_W(pc)>>4; + v&=3; + BUILDSR(); + cpu.regs[7]-=4; + SET_MEMORY_L(cpu.regs[7],(cpu.ccr<<24)|code->next_pc); + pc=GET_MEMORY_L(v*(h8300hmode?4:2)+0x08*(h8300hmode?4:2)); + cpu.ccr|=0x80; + if (h8300smode) { + int exr; + exr = cpu.exr << 8 | cpu.exr; + cpu.regs[7]-=2; + SET_MEMORY_W(cpu.regs[7],exr); + } + }; + goto end; + case O (O_BKPT, SN): + /* The format of r0 is defined by devo/include/wait.h. */ +#if 0 /* FIXME: Ugh. A breakpoint is the sleep insn. */ + if (WIFEXITED (cpu.regs[0])) + { + cpu.state = SIM_STATE_EXITED; + cpu.exception = WEXITSTATUS (cpu.regs[0]); + } + else if (WIFSTOPPED (cpu.regs[0])) + { + cpu.state = SIM_STATE_STOPPED; + cpu.exception = WSTOPSIG (cpu.regs[0]); + } + else + { + cpu.state = SIM_STATE_SIGNALLED; + cpu.exception = WTERMSIG (cpu.regs[0]); + } +#else + /* FIXME: Doesn't this break for breakpoints when r0 + contains just the right (er, wrong) value? */ + cpu.state = SIM_STATE_STOPPED; + if (! SIM_WIFEXITED (cpu.regs[0]) && SIM_WIFSIGNALED (cpu.regs[0])) + cpu.exception = SIGILL; + else + cpu.exception = SIGTRAP; +#endif + goto end; default: cpu.state = SIM_STATE_STOPPED; cpu.exception = SIGILL; @@ -1538,8 +1839,15 @@ abort (); setc: - cpu.ccr = res; - GETSR (); + switch(code->dst.type) { + case OP_CCR: + cpu.ccr = res; + GETSR (); + break; + case OP_EXR: + cpu.exr = res; + break; + } goto next; condtrue: @@ -1789,6 +2097,7 @@ #define CCR_REGNUM 8 /* Contains processor status */ #define PC_REGNUM 9 /* Contains program counter */ +#define EXR_REGNUM 10 /* Contains processor extend status */ #define CYCLE_REGNUM 10 #define INST_REGNUM 11 @@ -1859,14 +2168,15 @@ switch (rn) { - default: - abort (); case CCR_REGNUM: v = cpu.ccr; break; case PC_REGNUM: v = cpu.pc; break; + case EXR_REGNUM: + v = cpu.exr; + break; case R0_REGNUM: case R1_REGNUM: case R2_REGNUM: @@ -1877,19 +2187,26 @@ case R7_REGNUM: v = cpu.regs[rn]; break; - case CYCLE_REGNUM: - v = cpu.cycles; - longreg = 1; - break; - case TICK_REGNUM: - v = cpu.ticks; - longreg = 1; - break; - case INST_REGNUM: - v = cpu.insts; - longreg = 1; - break; } + if (h8300smode == 0 || rn > (CYCLE_REGNUM+1)) { + if (h8300smode) + rn--; + switch (rn) + { + case CYCLE_REGNUM: + v = cpu.cycles; + longreg = 1; + break; + case TICK_REGNUM: + v = cpu.ticks; + longreg = 1; + break; + case INST_REGNUM: + v = cpu.insts; + longreg = 1; + break; + } + } if (h8300hmode || longreg) { buf[0] = v >> 24; @@ -2016,10 +2333,14 @@ char **argv; { /* FIXME: Much of the code in sim_load can be moved here. */ + char *ptyname; sim_kind = kind; myname = argv[0]; sim_callback = ptr; + if((ptyname=openpty())!=NULL) + (*sim_callback->printf_filtered) (sim_callback, + "SCI0 = %s\n",ptyname); /* Fudge our descriptor. */ return (SIM_DESC) 1; } @@ -2030,6 +2351,7 @@ int quitting; { /* Nothing to do. */ + closepty(); } /* Called by gdb to load a program into memory. */ @@ -2100,6 +2422,7 @@ abort (); cpu.mask = memory_size - 1; + init_ioregs(&cpu); if (sim_load_file (sd, myname, sim_callback, prog, prog_bfd, sim_kind == SIM_OPEN_DEBUG, 0, sim_write) diff -Nru -X /home/ysato/.exclude-diff gdb-5.2.1/sim/h8300/inst.h gdb-5.2.1.h8sim/sim/h8300/inst.h --- gdb-5.2.1/sim/h8300/inst.h 2003-09-06 23:11:12.000000000 +0900 +++ gdb-5.2.1.h8sim/sim/h8300/inst.h 2003-09-06 23:09:03.000000000 +0900 @@ -15,7 +15,7 @@ can only happen when simulating H8/300H programs). We make no attempt to catch overlapping addresses, wrapped addresses, etc etc. */ #define H8300_MSIZE (1<<16) -#define H8300H_MSIZE (1<<18) +#define H8300H_MSIZE (1<<24) #define CSIZE 1000 @@ -67,7 +67,7 @@ unsigned int regs[9]; int pc; int ccr; - + int exr; unsigned char *memory; unsigned char *eightbit; diff -Nru -X /home/ysato/.exclude-diff gdb-5.2.1/sim/h8300/io.c gdb-5.2.1.h8sim/sim/h8300/io.c --- gdb-5.2.1/sim/h8300/io.c 1970-01-01 09:00:00.000000000 +0900 +++ gdb-5.2.1.h8sim/sim/h8300/io.c 2003-12-10 21:33:34.000000000 +0900 @@ -0,0 +1,363 @@ +/* + H8 simulator Internal Peripheral Support +*/ + +#include +#include +#include +#include +#include + +#include "inst.h" + +#define SMR (cpu->memory[sci_base+0]) +#define BRR (cpu->memory[sci_base+1]) +#define SCR (cpu->memory[sci_base+2]) +#define TDR (cpu->memory[sci_base+3]) +#define SSR (cpu->memory[sci_base+4]) +#define RDR (cpu->memory[sci_base+5]) + +#define TCR 0 +#define TCSR 2 +#define TCORA 4 +#define TCORB 6 +#define TCNT 8 + +static int scifd=-1; +static struct termios old_attr; +static unsigned char ssr=0; +static unsigned int sci_base; + +extern int h8300hmode; +extern int h8300smode; + +static void timer8sub(const int base[], unsigned char tcsr[], int cyc, cpu_state_type *cpu, int ch) +{ + static int prescale[3]={8,64,8192}; + const int prescale_div[3]={8,64,8192}; + int tm,cnt,pcnt; + for (pcnt = 0; pcnt < 3; pcnt++) { + prescale[pcnt] -= cyc; + if (prescale[pcnt]<=0) + { + for(tm=0;tmmemory[base[tm]+TCSR] & 0xe0); + if ((cpu->memory[base[tm]+TCR]&0x07) == (pcnt+1)) + { + cnt=++cpu->memory[base[tm]+TCNT]; + if (cnt>=0x100) + { + tcsr[tm]|=0x20; + cnt=0; + } + cpu->memory[base[tm]+TCNT]=cnt; + } + if (cpu->memory[base[tm]+TCNT] >= cpu->memory[base[tm]+TCORA]) + { + tcsr[tm]|=0x40; + if ((cpu->memory[base[tm]+TCR]&0x18) == 0x08) + cpu->memory[base[tm]+TCNT] = 0; + } + if (cpu->memory[base[tm]+TCNT] >= cpu->memory[base[tm]+TCORB]) + { + tcsr[tm]|=0x80; + if ((cpu->memory[base[tm]+TCR]&0x18) == 0x10) + cpu->memory[base[tm]+TCNT] = 0; + } + cpu->memory[base[tm]+TCSR] &= 0x1f; + cpu->memory[base[tm]+TCSR] |= (tcsr[tm] & 0xe0); + } + prescale[pcnt]+=prescale_div[pcnt]; + } + } +} + +static void +h8300h_timer8(cpu_state_type *cpu,int cycles) +{ + static unsigned char tcsr[4]={0x00,0x00,0x00,0x00}; + const int base[4]={0xffff80,0xffff81,0xffff90,0xffff91}; + static unsigned int prev_cycle=0; + int cyc; + cyc=(unsigned int)cycles-prev_cycle; + prev_cycle=cycles; + timer8sub(base,tcsr,cyc,cpu,4); +} + +static void +h8300s_timer8(cpu_state_type *cpu,int cycles) +{ + static unsigned char tcsr[2]={0x00,0x00}; + const int base[2]={0xffffb0,0xffffb1}; + static unsigned int prev_cycle=0; + int cyc; + cyc=(unsigned int)cycles-prev_cycle; + prev_cycle=cycles; + timer8sub(base,tcsr,cyc,cpu,2); +} + +static unsigned int complete_time(cpu_state_type *cpu,int cycles) +{ + int length; + int div[]={1,4,16,64}; + length=(SMR & 0x40)?7:8; + length+=(SMR & 0x20)?1:0; + length+=(SMR & 0x08)?1:0; + length+=2; + return length*32*div[SMR & 0x03]*BRR+cycles; +} + +static void send_data(int txd) +{ + unsigned char dt; + dt=txd; + write(scifd,&dt,1); + fsync(scifd); +} + +static int rcv_data(int *rxd) +{ + unsigned char rd; + if(read(scifd,&rd,1)>0) { + *rxd=rd; + return 1; + } else + return 0; +} + +static int sci(cpu_state_type *cpu,int cycles) +{ + static int tx_end_time=0; + static int rx_end_time=0; + static int data=-1; + ssr &= SSR; + if((SCR & 0x20) && !(ssr & 0x80)) { + send_data(TDR); + ssr |= 0x80; + tx_end_time=complete_time(cpu,cycles); + } + if ((data == -1) && !rcv_data(&data)) + data = -1; + if((data != -1) && (SCR & 0x10) && ((rx_end_time==0) || (rx_end_time-cycles)<0)) { + if(ssr & 0x40) { + ssr |= 0x20; + } else { + RDR=data; + ssr |= 0x40; + data=-1; + } + rx_end_time=complete_time(cpu,cycles); + } + if((tx_end_time>0) && (tx_end_time-cycles)<0) { + if(ssr & 0x80) { + ssr |= 0x04; + } + } + SSR = ssr; +} + +static int +h8300h_intcont(cpu_state_type *cpu) +{ + struct INT_LIST { + int vector; + int isr_adr; + unsigned char isr_mask; + int ier_adr; + unsigned char ier_mask; + } int_table[]= { + {36,0xffff82,0x40,0xffff80,0x40}, + {37,0xffff82,0x80,0xffff80,0x80}, + {38,0xffff83,0x40,0xffff81,0x40}, + {38,0xffff83,0x80,0xffff81,0x40}, + {39,0xffff82,0x20,0xffff80,0x20}, + {39,0xffff83,0x20,0xffff81,0x20}, + {40,0xffff92,0x40,0xffff90,0x40}, + {41,0xffff92,0x80,0xffff90,0x80}, + {42,0xffff93,0x40,0xffff91,0x40}, + {42,0xffff93,0x80,0xffff91,0x40}, + {43,0xffff92,0x20,0xffff90,0x20}, + {43,0xffff93,0x20,0xffff91,0x20}, + {52,0xffffb4,0x38,0xffffb2,0x40}, + {53,0xffffb4,0x40,0xffffb2,0x40}, + {54,0xffffb4,0x80,0xffffb2,0x80}, + {55,0xffffb4,0x04,0xffffb2,0x04} + }; + int irqno; + for (irqno=0;irqnomemory[int_table[irqno].ier_adr]&int_table[irqno].ier_mask) + if(cpu->memory[int_table[irqno].isr_adr]&int_table[irqno].isr_mask) + return int_table[irqno].vector; + } + return 0; +} + +static int +h8300s_intcont(cpu_state_type *cpu) +{ + struct INT_LIST { + int vector; + int isr_adr; + unsigned char isr_mask; + int ier_adr; + unsigned char ier_mask; + } int_table[]= { + {72,0xffffb2,0x40,0xffffb0,0x40}, + {73,0xffffb2,0x80,0xffffb0,0x80}, + {76,0xffffb3,0x40,0xffffb1,0x40}, + {77,0xffffb3,0x80,0xffffb1,0x40}, + {74,0xffffb2,0x20,0xffffb0,0x20}, + {78,0xffffb3,0x20,0xffffb1,0x20}, + {88,0xffff7c,0x38,0xffff7a,0x40}, + {89,0xffff7c,0x40,0xffff7a,0x40}, + {90,0xffff7c,0x80,0xffff7a,0x80}, + {91,0xffff7c,0x04,0xffff7a,0x04} + }; + int irqno; + for (irqno=0;irqnomemory[int_table[irqno].ier_adr]&int_table[irqno].ier_mask) + if(cpu->memory[int_table[irqno].isr_adr]&int_table[irqno].isr_mask) + return int_table[irqno].vector; + } + return 0; +} + +int +iosimulation(cpu_state_type *cpu,int cycles) +{ + if (h8300hmode && !h8300smode) h8300h_timer8(cpu,cycles); + if (h8300smode) h8300s_timer8(cpu,cycles); + sci(cpu,cycles); + if (h8300hmode && !h8300smode) return h8300h_intcont(cpu); + if (h8300smode) return h8300s_intcont(cpu); +} + +void init_ioregs(cpu_state_type *cpu) +{ + struct INITTABLE { + int addr; + short data; + }; + const struct INITTABLE h8300h_reg_ini[] = { + 0xffff80,0x00, + 0xffff81,0x00, + 0xffff82,0x00, + 0xffff83,0x00, + 0xffff84,0xff, + 0xffff85,0xff, + 0xffff86,0xff, + 0xffff87,0xff, + 0xffff88,0x00, + 0xffff89,0x00, + 0xffff90,0x00, + 0xffff91,0x00, + 0xffff92,0x00, + 0xffff93,0x00, + 0xffff94,0xff, + 0xffff95,0xff, + 0xffff96,0xff, + 0xffff97,0xff, + 0xffff98,0x00, + 0xffff99,0x00, + 0xffffb0,0x00, + 0xffffb1,0xff, + 0xffffb2,0x00, + 0xffffb3,0xff, + 0xffffb4,0x84, + 0xffffb8,0x00, + 0xffffb9,0xff, + 0xffffba,0x00, + 0xffffbb,0xff, + 0xffffbc,0x84, + 0xffffc0,0x00, + 0xffffc1,0xff, + 0xffffc2,0x00, + 0xffffc3,0xff, + 0xffffc4,0x84, + }; + const struct INITTABLE h8300s_reg_ini[] = { + 0xffffb0,0x00, + 0xffffb1,0x00, + 0xffffb2,0x00, + 0xffffb3,0x00, + 0xffffb4,0xff, + 0xffffb5,0xff, + 0xffffb6,0xff, + 0xffffb7,0xff, + 0xffffb8,0x00, + 0xffffb9,0x00, + 0xffff78,0x00, + 0xffff79,0xff, + 0xffff7a,0x00, + 0xffff7b,0xff, + 0xffff7c,0x84, + 0xffff80,0x00, + 0xffff81,0xff, + 0xffff82,0x00, + 0xffff83,0xff, + 0xffff84,0x84, + 0xffff88,0x00, + 0xffff89,0xff, + 0xffff8a,0x00, + 0xffff8b,0xff, + 0xffff8c,0x84, + }; + int c; + if (h8300hmode && !h8300smode) { + sci_base=0xffffb0; + for(c=0;cmemory[h8300h_reg_ini[c].addr]=h8300h_reg_ini[c].data; + } + if (h8300smode) { + sci_base=0xffff78; + for(c=0;cmemory[h8300s_reg_ini[c].addr]=h8300s_reg_ini[c].data; + } + ssr = 0x84; +} + +char *openpty(void) +{ + const char nm[]="0123456789ABCDEF"; + static char ptyname[16]; + int c1,c2,fd; + struct termios attr; + fd = open("/dev/ptmx",O_RDWR|O_NONBLOCK); + if(fd >= 0) { + grantpt(fd); + unlockpt(fd); + strncpy(ptyname,(char *)ptsname(fd),sizeof(ptyname)-1); + ptyname[sizeof(ptyname)-1]='\0'; + } else { + for(c1='a';c1<='z';c1++) + for(c2=0;c2= 0) { + scifd=fd; + tcgetattr(scifd,&attr); + memcpy(&old_attr,&attr,sizeof(struct termios)); + attr.c_lflag&=~ICANON; + attr.c_cc[VMIN]=0; + attr.c_cc[VTIME]=0; + tcsetattr(scifd,TCSAFLUSH,&attr); + return ptyname; + } else + return NULL; +} + +void closepty(void) +{ + struct termios attr; + if(scifd!=-1) { + tcsetattr(scifd,TCSAFLUSH,&old_attr); + close(scifd); + } +}