📄 interp.c
字号:
case 0xF8: case 0xF9: case 0xFA: case 0xFB: case 0xFC: case 0xFD: case 0xFE: case 0xFF: /* bsr */ cpu.gr[15] = pc; case 0xF0: case 0xF1: case 0xF2: case 0xF3: case 0xF4: case 0xF5: case 0xF6: case 0xF7: /* br */ { int disp; disp = inst & 0x03FF; if (inst & 0x0400) disp |= 0xFFFFFC00; pc += disp<<1; bonus_cycles++; needfetch = 1; } break; } if (tracing) fprintf (stderr, "\n"); if (needfetch) { /* Do not let him fetch from a bad address! */ if (((uword)pc) >= cpu.asregs.msize) { if (issue_messages) fprintf (stderr, "PC loaded at 0x%x is outside of available memory! (0x%x)\n", oldpc, pc); cpu.asregs.exception = SIGSEGV; } else { ibuf = rlat (pc & 0xFFFFFFFC); needfetch = 0; } } } while (!cpu.asregs.exception); /* Hide away the things we've cached while executing. */ cpu.asregs.pc = pc; cpu.asregs.insts += insts; /* instructions done ... */ cpu.asregs.cycles += insts; /* and each takes a cycle */ cpu.asregs.cycles += bonus_cycles; /* and extra cycles for branches */ cpu.asregs.cycles += memops * memcycles; /* and memop cycle delays */ signal (SIGINT, sigsave);}intsim_write (sd, addr, buffer, size) SIM_DESC sd; SIM_ADDR addr; unsigned char * buffer; int size;{ int i; init_pointers (); memcpy (& cpu.mem[addr], buffer, size); return size;}intsim_read (sd, addr, buffer, size) SIM_DESC sd; SIM_ADDR addr; unsigned char * buffer; int size;{ int i; init_pointers (); memcpy (buffer, & cpu.mem[addr], size); return size;}intsim_store_register (sd, rn, memory, length) SIM_DESC sd; int rn; unsigned char * memory; int length;{ init_pointers (); if (rn < NUM_MCORE_REGS && rn >= 0) { if (length == 4) { long ival; /* misalignment safe */ ival = mcore_extract_unsigned_integer (memory, 4); cpu.asints[rn] = ival; } return 4; } else return 0;}intsim_fetch_register (sd, rn, memory, length) SIM_DESC sd; int rn; unsigned char * memory; int length;{ init_pointers (); if (rn < NUM_MCORE_REGS && rn >= 0) { if (length == 4) { long ival = cpu.asints[rn]; /* misalignment-safe */ mcore_store_unsigned_integer (memory, 4, ival); } return 4; } else return 0;}intsim_trace (sd) SIM_DESC sd;{ tracing = 1; sim_resume (sd, 0, 0); tracing = 0; return 1;}voidsim_stop_reason (sd, reason, sigrc) SIM_DESC sd; enum sim_stop * reason; int * sigrc;{ if (cpu.asregs.exception == SIGQUIT) { * reason = sim_exited; * sigrc = cpu.gr[PARM1]; } else { * reason = sim_stopped; * sigrc = cpu.asregs.exception; }}intsim_stop (sd) SIM_DESC sd;{ cpu.asregs.exception = SIGINT; return 1;}voidsim_info (sd, verbose) SIM_DESC sd; int verbose;{#ifdef WATCHFUNCTIONS int w, wcyc;#endif double virttime = cpu.asregs.cycles / 36.0e6; callback->printf_filtered (callback, "\n\n# instructions executed %10d\n", cpu.asregs.insts); callback->printf_filtered (callback, "# cycles %10d\n", cpu.asregs.cycles); callback->printf_filtered (callback, "# pipeline stalls %10d\n", cpu.asregs.stalls); callback->printf_filtered (callback, "# virtual time taken %10.4f\n", virttime);#ifdef WATCHFUNCTIONS callback->printf_filtered (callback, "\nNumber of watched functions: %d\n", ENDWL); wcyc = 0; for (w = 1; w <= ENDWL; w++) { callback->printf_filtered (callback, "WL = %s %8x\n",WLstr[w],WL[w]); callback->printf_filtered (callback, " calls = %d, cycles = %d\n", WLcnts[w],WLcyc[w]); if (WLcnts[w] != 0) callback->printf_filtered (callback, " maxcpc = %d, mincpc = %d, avecpc = %d\n", WLmax[w],WLmin[w],WLcyc[w]/WLcnts[w]); wcyc += WLcyc[w]; } callback->printf_filtered (callback, "Total cycles for watched functions: %d\n",wcyc);#endif}struct aout{ unsigned char sa_machtype[2]; unsigned char sa_magic[2]; unsigned char sa_tsize[4]; unsigned char sa_dsize[4]; unsigned char sa_bsize[4]; unsigned char sa_syms[4]; unsigned char sa_entry[4]; unsigned char sa_trelo[4]; unsigned char sa_drelo[4];} aout;#define LONG(x) (((x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])#define SHORT(x) (((x)[0]<<8)|(x)[1])SIM_DESCsim_open (kind, cb, abfd, argv) SIM_OPEN_KIND kind; host_callback * cb; struct bfd * abfd; char ** argv;{ int osize = sim_memory_size; myname = argv[0]; callback = cb; if (kind == SIM_OPEN_STANDALONE) issue_messages = 1; /* Discard and reacquire memory -- start with a clean slate. */ sim_size (1); /* small */ sim_size (osize); /* and back again */ set_initial_gprs (); /* Reset the GPR registers. */ /* Fudge our descriptor for now. */ return (SIM_DESC) 1;}voidsim_close (sd, quitting) SIM_DESC sd; int quitting;{ /* nothing to do */}SIM_RCsim_load (sd, prog, abfd, from_tty) SIM_DESC sd; char * prog; bfd * abfd; int from_tty;{ /* Do the right thing for ELF executables; this turns out to be just about the right thing for any object format that: - we crack using BFD routines - follows the traditional UNIX text/data/bss layout - calls the bss section ".bss". */ extern bfd * sim_load_file (); /* ??? Don't know where this should live. */ bfd * prog_bfd; { bfd * handle; asection * s_bss; handle = bfd_openr (prog, 0); /* could be "mcore" */ if (!handle) { printf("``%s'' could not be opened.\n", prog); return SIM_RC_FAIL; } /* Makes sure that we have an object file, also cleans gets the section headers in place. */ if (!bfd_check_format (handle, bfd_object)) { /* wasn't an object file */ bfd_close (handle); printf ("``%s'' is not appropriate object file.\n", prog); return SIM_RC_FAIL; } /* Look for that bss section. */ s_bss = bfd_get_section_by_name (handle, ".bss"); if (!s_bss) { printf("``%s'' has no bss section.\n", prog); return SIM_RC_FAIL; } /* Appropriately paranoid would check that we have a traditional text/data/bss ordering within memory. */ /* figure the end of the bss section */#if 0 printf ("bss section at 0x%08x for 0x%08x bytes\n", (unsigned long) bfd_get_section_vma (handle, s_bss), (unsigned long) bfd_section_size (handle, s_bss));#endif heap_ptr = ((unsigned long) bfd_get_section_vma (handle, s_bss) + (unsigned long) bfd_section_size (handle, s_bss)); /* Clean up after ourselves. */ bfd_close (handle); /* XXX: do we need to free the s_bss and handle structures? */ } /* from sh -- dac */ prog_bfd = sim_load_file (sd, myname, callback, prog, abfd, sim_kind == SIM_OPEN_DEBUG, 0, sim_write); if (prog_bfd == NULL) return SIM_RC_FAIL; target_big_endian = bfd_big_endian (prog_bfd); if (abfd == NULL) bfd_close (prog_bfd); return SIM_RC_OK;}SIM_RCsim_create_inferior (sd, prog_bfd, argv, env) SIM_DESC sd; struct bfd * prog_bfd; char ** argv; char ** env;{ char ** avp; int nargs = 0; int nenv = 0; int s_length; int l; unsigned long strings; unsigned long pointers; unsigned long hi_stack; /* Set the initial register set. */ l = issue_messages; issue_messages = 0; set_initial_gprs (); issue_messages = l; hi_stack = cpu.asregs.msize - 4; cpu.asregs.pc = bfd_get_start_address (prog_bfd); /* Calculate the argument and environment strings. */ s_length = 0; nargs = 0; avp = argv; while (avp && *avp) { l = strlen (*avp) + 1; /* include the null */ s_length += (l + 3) & ~3; /* make it a 4 byte boundary */ nargs++; avp++; } nenv = 0; avp = env; while (avp && *avp) { l = strlen (*avp) + 1; /* include the null */ s_length += (l + 3) & ~ 3;/* make it a 4 byte boundary */ nenv++; avp++; } /* Claim some memory for the pointers and strings. */ pointers = hi_stack - sizeof(word) * (nenv+1+nargs+1); pointers &= ~3; /* must be 4-byte aligned */ cpu.gr[0] = pointers; strings = cpu.gr[0] - s_length; strings &= ~3; /* want to make it 4-byte aligned */ cpu.gr[0] = strings; /* dac fix, the stack address must be 8-byte aligned! */ cpu.gr[0] = cpu.gr[0] - cpu.gr[0] % 8; /* Loop through the arguments and fill them in. */ cpu.gr[PARM1] = nargs; if (nargs == 0) { /* No strings to fill in. */ cpu.gr[PARM2] = 0; } else { cpu.gr[PARM2] = pointers; avp = argv; while (avp && *avp) { /* Save where we're putting it. */ wlat (pointers, strings); /* Copy the string. */ l = strlen (* avp) + 1; strcpy ((char *)(cpu.mem + strings), *avp); /* Bump the pointers. */ avp++; pointers += 4; strings += l+1; } /* A null to finish the list. */ wlat (pointers, 0); pointers += 4; } /* Now do the environment pointers. */ if (nenv == 0) { /* No strings to fill in. */ cpu.gr[PARM3] = 0; } else { cpu.gr[PARM3] = pointers; avp = env; while (avp && *avp) { /* Save where we're putting it. */ wlat (pointers, strings); /* Copy the string. */ l = strlen (* avp) + 1; strcpy ((char *)(cpu.mem + strings), *avp); /* Bump the pointers. */ avp++; pointers += 4; strings += l+1; } /* A null to finish the list. */ wlat (pointers, 0); pointers += 4; } return SIM_RC_OK;}voidsim_kill (sd) SIM_DESC sd;{ /* nothing to do */}voidsim_do_command (sd, cmd) SIM_DESC sd; char * cmd;{ /* Nothing there yet; it's all an error. */ if (cmd != NULL) { char ** simargv = buildargv (cmd); if (strcmp (simargv[0], "watch") == 0) { if ((simargv[1] == NULL) || (simargv[2] == NULL)) { fprintf (stderr, "Error: missing argument to watch cmd.\n"); return; } ENDWL++; WL[ENDWL] = strtol (simargv[2], NULL, 0); WLstr[ENDWL] = strdup (simargv[1]); fprintf (stderr, "Added %s (%x) to watchlist, #%d\n",WLstr[ENDWL], WL[ENDWL], ENDWL); } else if (strcmp (simargv[0], "dumpmem") == 0) { unsigned char * p; FILE * dumpfile; if (simargv[1] == NULL) fprintf (stderr, "Error: missing argument to dumpmem cmd.\n"); fprintf (stderr, "Writing dumpfile %s...",simargv[1]); dumpfile = fopen (simargv[1], "w"); p = cpu.mem; fwrite (p, cpu.asregs.msize-1, 1, dumpfile); fclose (dumpfile); fprintf (stderr, "done.\n"); } else if (strcmp (simargv[0], "clearstats") == 0) { cpu.asregs.cycles = 0; cpu.asregs.insts = 0; cpu.asregs.stalls = 0; ENDWL = 0; } else if (strcmp (simargv[0], "verbose") == 0) { issue_messages = 2; } else { fprintf (stderr,"Error: \"%s\" is not a valid M.CORE simulator command.\n", cmd); } } else { fprintf (stderr, "M.CORE sim commands: \n"); fprintf (stderr, " watch <funcname> <addr>\n"); fprintf (stderr, " dumpmem <filename>\n"); fprintf (stderr, " clearstats\n"); fprintf (stderr, " verbose\n"); }}voidsim_set_callbacks (ptr) host_callback * ptr;{ callback = ptr; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -