From 3877a1459be9bdeb20ae891b3f68220b837a81cb Mon Sep 17 00:00:00 2001 From: DJ Delorie Date: Fri, 6 Jun 2008 19:18:15 +0000 Subject: * Makefile.in: Add Timer A support. * cpu.h (m32c_opcode_pc): New. (in_gdb): New. * gdb-if.c (sim_open): Add Timer A support. Support unbuffered console. * int.c (trigger_interrupt): Manage the U flag properly. (trigger_based_interrupt): Likewise. (trigger_fixed_interrupt): New. (trigger_peripheral_interrupt): New. * int.h (trigger_peripheral_interrupt): New. * m32c.opc: Use m32c_opcode_pc throughout, as needed. (decode_m32c): Detect jump-to-zero with traceback. (BRK): Try to do the right thing, keeping track of whether we're in gdb or not, and if the user has provided a handler or not. (GBRK): Alternate break opcode for gdb, in case the user's app needs to use BRK for itself. (BRK2): Implement. * main.c: Add Timer A support. Support TCP-based console. (setup_tcp_console): New. (main): Add Timer A support. Support TCP-based console. * mem.c: Add Timer A support. Support TCP-based console. (mem_ptr): Enhance NULL pointer detection. (stdin_ready): New. (m32c_sim_restore_console): New. (mem_get_byte): Check for console input ready. (update_timer_a): New. * r8c.opc (SSTR): Use r0l, not r0h. (REIT): Fix return frame logic. * reg.c (print_flags): New. (trace_register_changes): Use it. (m32c_dump_all_registers): New. * timer_a.h: New. * load.c: Fix indentation. * trace.c: Fix indentation. * trace.h: Fix indentation. --- sim/m32c/m32c.opc | 77 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 19 deletions(-) (limited to 'sim/m32c/m32c.opc') diff --git a/sim/m32c/m32c.opc b/sim/m32c/m32c.opc index da77f95..9f5bd4a 100644 --- a/sim/m32c/m32c.opc +++ b/sim/m32c/m32c.opc @@ -49,8 +49,8 @@ getbyte () #define GETBYTE() (op[opi++] = getbyte()) -#define UNSUPPORTED() unsupported("unsupported", orig_pc) -#define NOTYET() unsupported("unimplemented", orig_pc) +#define UNSUPPORTED() unsupported("unsupported", m32c_opcode_pc) +#define NOTYET() unsupported("unimplemented", m32c_opcode_pc) static void unsupported (char *tag, int orig_pc) @@ -390,12 +390,14 @@ shift_op (srcdest sd, int arith, int count, int setc) set_flags (FLAGBIT_O, o ? FLAGBIT_O : 0); } +static int pcs[16]; +static int ipcs = 0; + int decode_m32c() { unsigned char op[40]; int opi; - int orig_pc; int v, a, b; long long ll; srcdest sc, dc; @@ -411,9 +413,20 @@ decode_m32c() next_opcode: opi = 0; - orig_pc = get_reg (pc); + m32c_opcode_pc = get_reg (pc); + + tprintf("trace: decode pc = %06x\n", m32c_opcode_pc); - tprintf("trace: decode pc = %06x\n", orig_pc); + if (m32c_opcode_pc == 0) + { + int i; + printf("Abort: PC is zero, here from:\n"); + for (i=0; i<4; i++) + printf(" 0x%06x\n", pcs[(ipcs+15-i)%16]); + return M32C_MAKE_HIT_BREAK (); + } + pcs[ipcs++] = m32c_opcode_pc; + ipcs %= 16; /** VARY sss 000 001 010 011 100 */ /** VARY ddd 000 001 010 011 100 */ @@ -564,7 +577,7 @@ next_opcode: if ((v & (w ? 0xffff : 0xff)) != 0) { tprintf("jmp: %x + 2 + %d = ", get_reg (pc), a); - put_reg (pc, orig_pc + 2 + a); + put_reg (pc, m32c_opcode_pc + 2 + a); tprintf("%x\n", get_reg (pc)); } @@ -666,16 +679,41 @@ next_opcode: /* We report the break to our caller with the PC still pointing at the breakpoint instruction. */ - put_reg (pc, orig_pc); - if (verbose) + put_reg (pc, m32c_opcode_pc); + if (verbose || 1) printf("[break]\n"); + if (in_gdb || (regs.r_intbl == 0 && regs.r_intbh == 0)) + return M32C_MAKE_HIT_BREAK (); + if (mem_get_qi (0xFFFFE7) == 0xff) + trigger_based_interrupt (0); + else + trigger_fixed_interrupt (0xFFFFE4); + + /** 1111 1110 GBRK */ + + /* This alternate break, which is not part of the chip's opcode set, + is here in case you need to debug a program that itself uses the + chip's BRK opcode. You'll need to modify your copy of GDB to use + this opcode instead of the real BRK. */ + + /* GDB Break. */ + /* We report the break to our caller with the PC still pointing at the + breakpoint instruction. */ + put_reg (pc, m32c_opcode_pc); + if (verbose || 1) + printf("[gdb break]\n"); return M32C_MAKE_HIT_BREAK (); - /** 0000 1000 BRK */ + /** 0000 1000 BRK2 */ if (verbose) printf("[break2]\n"); - return M32C_MAKE_HIT_BREAK (); + if (in_gdb) + return M32C_MAKE_HIT_BREAK (); + if (mem_get_qi (0xFFFFE7) == 0xff) + trigger_based_interrupt (0); + else + trigger_fixed_interrupt (0xFFFFE4); /** 1101 ddd0 dd11 1bit BSET dest */ @@ -988,12 +1026,12 @@ next_opcode: prefix (0, 0, 0); v = sign_ext (IMM(1), 8); if (condition_true (ccc*2+c)) - put_reg (pc, orig_pc + 1 + v); + put_reg (pc, m32c_opcode_pc + 1 + v); /** 01dd 101d JMP.S label */ prefix (0, 0, 0); - put_reg (pc, orig_pc + (dd*2+d) + 2); + put_reg (pc, m32c_opcode_pc + (dd*2+d) + 2); /** 1011 1011 JMP.B label */ @@ -1005,13 +1043,13 @@ next_opcode: printf("[jmp-to-self detected as exit]\n"); return M32C_MAKE_HIT_BREAK (); } - put_reg (pc, orig_pc + 1 + imm); + put_reg (pc, m32c_opcode_pc + 1 + imm); /** 1100 1110 JMP.W label */ prefix (0, 0, 0); imm = sign_ext (IMM(2), 16); - put_reg (pc, orig_pc + 1 + imm); + put_reg (pc, m32c_opcode_pc + 1 + imm); /** 1100 1100 JMP.A label */ @@ -1025,7 +1063,7 @@ next_opcode: sc = decode_src23 (sss, ss, 2); a = get_src (sc); a = sign_ext (a, 16); - put_reg (pc, orig_pc + a); + put_reg (pc, m32c_opcode_pc + a); /** 1000 sss0 ss00 0001 JMPI.A src */ @@ -1047,7 +1085,7 @@ next_opcode: imm = sign_ext (IMM(2), 16); put_reg (sp, get_reg (sp) - 4); mem_put_si (get_reg (sp), get_reg (pc)); - put_reg (pc, orig_pc + imm + 1); + put_reg (pc, m32c_opcode_pc + imm + 1); /** 1100 1101 JSR.A label */ @@ -1065,7 +1103,7 @@ next_opcode: a = sign_ext (a, 16); put_reg (sp, get_reg (sp) - 4); mem_put_si (get_reg (sp), get_reg (pc)); - put_reg (pc, orig_pc + a); + put_reg (pc, m32c_opcode_pc + a); /** 1001 sss0 ss00 0001 JSRI.A src */ @@ -1917,12 +1955,13 @@ next_opcode: a = get_reg (a1); b = get_reg (r3); + v = get_reg (w ? r0 : r0l); for (;b;) { if (w) - mem_put_hi(a, r0); + mem_put_hi(a, v); else - mem_put_qi(a, r0 & 0xff); + mem_put_qi(a, v); a += w ? 2 : 1; b --; } -- cgit v1.1