static int arg (int bytes) { int rv = 0; argp++; if (A16) { switch (argp) { case 1: if (bytes == 1) return get_reg (r1l); if (bytes == 2) return get_reg (r1); break; case 2: if (bytes == 2) return get_reg (r2); break; } } else { switch (argp) { case 1: if (bytes == 1) return get_reg (r0l); if (bytes == 2) return get_reg (r0); break; } } if (bytes == 0) bytes = 2; switch (bytes) { case 1: rv = mem_get_qi (get_reg (sp) + stackp); if (A24) stackp++; break; case 2: rv = mem_get_hi (get_reg (sp) + stackp); break; case 3: rv = mem_get_psi (get_reg (sp) + stackp); if (A24) stackp++; break; case 4: rv = mem_get_si (get_reg (sp) + stackp); break; } stackp += bytes; return rv; }
int get_bit (srcdest sd) { int b; if (sd.mem) b = mem_get_qi (sd.u.addr) & sd.mask; else b = get_reg (sd.u.reg) & sd.mask; return b ? 1 : 0; }
static int disp8 () { int rv; int tsave = trace; if (trace == 1) trace = 0; rv = mem_get_qi (get_reg (pc)); regs.r_pc++; trace = tsave; return rv; }
static void read_target (char *buffer, int address, int count, int asciiz) { char byte; while (count > 0) { byte = mem_get_qi (address++); *buffer++ = byte; if (asciiz && (byte == 0)) return; count--; } }
static int sim_dis_read (bfd_vma memaddr, bfd_byte * ptr, unsigned int length, struct disassemble_info *info) { int i; if (rx_big_endian) { /* See load.c for an explanation of this. */ for (i=0; i<length; i++) ptr[i] = mem_get_qi ((memaddr + i) ^ 3); } else mem_get_blk (memaddr, ptr, length); return 0; }
void put_bit (srcdest sd, int val) { int b; if (sd.mem) b = mem_get_qi (sd.u.addr); else b = get_reg (sd.u.reg); if (val) b |= sd.mask; else b &= ~sd.mask; if (sd.mem) mem_put_qi (sd.u.addr, b); else put_reg (sd.u.reg, b); }
int get_src (srcdest sd) { int v; if (sd.mem) { switch (sd.bytes) { case 1: v = mem_get_qi (sd.u.addr); break; case 2: v = mem_get_hi (sd.u.addr); break; case 3: v = mem_get_psi (sd.u.addr); break; case 4: v = mem_get_si (sd.u.addr); break; default: abort (); } } else { v = get_reg (sd.u.reg); switch (sd.bytes) { case 1: v &= 0xff; break; case 2: v &= 0xffff; break; case 3: v &= 0xffffff; break; } } return v; }
int sim_read (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length) { int i; check_desc (sd); if (mem == 0) return 0; execution_error_clear_last_error (); for (i = 0; i < length; i++) { bfd_vma addr = mem + i; int do_swap = addr_in_swap_list (addr); buf[i] = mem_get_qi (addr ^ (do_swap ? 3 : 0)); if (execution_error_get_last_error () != SIM_ERR_NONE) return i; } return length; }
void sim_disasm_one (void) { static int initted = 0; static asymbol **symtab = 0; static int symcount = 0; static int last_sym = -1; static struct disassemble_info info; int storage, sym, bestaddr; int min, max, i; static asection *code_section = 0; static bfd_vma code_base = 0; asection *s; int save_trace = trace; static const char *prev_filename = ""; static int prev_lineno = 0; const char *filename; const char *functionname; unsigned int lineno; int mypc = get_reg (pc); if (current_bfd == 0) return; trace = 0; if (!initted) { initted = 1; memset (&info, 0, sizeof (info)); INIT_DISASSEMBLE_INFO (info, stdout, op_printf); info.read_memory_func = sim_dis_read; info.arch = bfd_get_arch (current_bfd); info.mach = bfd_get_mach (current_bfd); if (info.mach == 0) { info.arch = bfd_arch_m32c; info.mach = default_machine; } disassemble_init_for_target (&info); storage = bfd_get_symtab_upper_bound (current_bfd); if (storage > 0) { symtab = (asymbol **) malloc (storage); symcount = bfd_canonicalize_symtab (current_bfd, symtab); symcount = remove_useless_symbols (symtab, symcount); qsort (symtab, symcount, sizeof (asymbol *), compare_symbols); } for (s = current_bfd->sections; s; s = s->next) { if (s->flags & SEC_CODE || code_section == 0) { code_section = s; code_base = bfd_section_lma (current_bfd, s); break; } } } filename = functionname = 0; lineno = 0; if (bfd_find_nearest_line (current_bfd, code_section, symtab, mypc - code_base, &filename, &functionname, &lineno)) { if (filename && functionname && lineno) { if (lineno != prev_lineno || strcmp (prev_filename, filename)) { char *the_line = load_file_and_line (filename, lineno); const char *slash = strrchr (filename, '/'); if (!slash) slash = filename; else slash++; printf ("========================================" "=====================================\n"); printf ("\033[37;41m %s:%d: \033[33;40m %s\033[K\033[0m\n", slash, lineno, the_line); } prev_lineno = lineno; prev_filename = filename; } } { min = -1; max = symcount; while (min < max - 1) { bfd_vma sa; sym = (min + max) / 2; sa = bfd_asymbol_value (symtab[sym]); /*printf("checking %4d %08x %s\n", sym, sa, bfd_asymbol_name (symtab[sym])); */ if (sa > mypc) max = sym; else if (sa < mypc) min = sym; else { min = sym; break; } } if (min != -1 && min != last_sym) { bestaddr = bfd_asymbol_value (symtab[min]); printf ("\033[43;30m%s", bfd_asymbol_name (symtab[min])); if (bestaddr != mypc) printf ("+%d", mypc - bestaddr); printf (":\t\t\t\033[0m\n"); last_sym = min; #if 0 if (trace == 1) if (strcmp (bfd_asymbol_name (symtab[min]), "abort") == 0 || strcmp (bfd_asymbol_name (symtab[min]), "exit") == 0) trace = 0; #endif } } opbuf[0] = 0; printf ("\033[33m%06x: ", mypc); max = print_insn_m32c (mypc, &info); for (i = 0; i < max; i++) printf ("%02x", mem_get_qi (mypc + i)); for (; i < 6; i++) printf (" "); printf ("%-16s ", opbuf); printf ("\033[0m\n"); trace = save_trace; }
void sim_disasm_one (void) { static int last_sym = -1; static const char * prev_filename = ""; static int prev_lineno = 0; const char * filename; const char * functionname; unsigned int lineno; int sym, bestaddr; int min, max, i; int save_trace = trace; int mypc = get_reg (pc); if (! sim_get_current_source_location (& filename, & functionname, & lineno)) return; trace = 0; if (filename && functionname && lineno) { if (lineno != prev_lineno || strcmp (prev_filename, filename)) { char * the_line = load_file_and_line (filename, lineno); const char * slash = strrchr (filename, '/'); if (!slash) slash = filename; else slash++; printf ("========================================" "=====================================\n"); printf ("\033[37;41m %s:%d: \033[33;40m %s\033[K\033[0m\n", slash, lineno, the_line); } prev_lineno = lineno; prev_filename = filename; } min = -1; max = symcount; while (min < max - 1) { bfd_vma sa; sym = (min + max) / 2; sa = bfd_asymbol_value (symtab[sym]); /*printf("checking %4d %08x %s\n", sym, sa, bfd_asymbol_name (symtab[sym])); */ if (sa > mypc) max = sym; else if (sa < mypc) min = sym; else { min = sym; break; } } if (min != -1 && min != last_sym) { bestaddr = bfd_asymbol_value (symtab[min]); printf ("\033[43;30m%s", bfd_asymbol_name (symtab[min])); if (bestaddr != mypc) printf ("+%d", mypc - bestaddr); printf (":\t\t\t\033[0m\n"); last_sym = min; #if 0 if (trace == 1) if (strcmp (bfd_asymbol_name (symtab[min]), "abort") == 0 || strcmp (bfd_asymbol_name (symtab[min]), "exit") == 0) trace = 0; #endif } opbuf[0] = 0; #ifdef CYCLE_ACCURATE printf ("\033[33m %04u %06x: ", (int)(regs.cycle_count % 10000), mypc); #else printf ("\033[33m %06x: ", mypc); #endif max = print_insn_rx (mypc, & info); for (i = 0; i < max; i++) { if (rx_big_endian) printf ("%02x", mem_get_qi ((mypc + i) ^ 3)); else printf ("%02x", mem_get_qi (mypc + i)); } do { printf (" "); i ++; } while (i < 6); printf ("%-16s ", opbuf); printf ("\033[0m\n"); trace = save_trace; }