⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spim.c

📁 用汇编语言编程源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* SPIM S20 MIPS simulator.   Terminal interface for SPIM simulator.   Copyright (C) 1990-2003 by James Larus (larus@cs.wisc.edu).   ALL RIGHTS RESERVED.   Changes for DOS and Windows versions by David A. Carley (dac@cs.wisc.edu)   SPIM is distributed under the following conditions:     You may make copies of SPIM for your own use and modify those copies.     All copies of SPIM must retain my name and copyright notice.     You may not sell SPIM or distributed SPIM in conjunction with a     commerical product or service without the expressed written consent of     James Larus.   THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR   IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR   PURPOSE. *//* $Header: /Software/SPIM/src/spim.c 12    1/04/03 3:31p Larus $*/#include <stdio.h>#include <ctype.h>#include <setjmp.h>#include <signal.h>#ifdef RS/* This is problem on HP Snakes, which define RS in syscall.h */#undef RS#endif#include <sys/types.h>#ifdef _AIX#ifndef NBBY#define NBBY 8#endif#include <sys/select.h>#endif#ifdef DJGPP#define USE_TERMIO#define termio termios#endif#ifndef WIN32#include <sys/time.h>#ifdef USE_TERMIO#ifndef DJGPP#include <termio.h>#endif#include <termios.h>#else#include <sys/ioctl.h>#include <sgtty.h>#endif#endif#ifdef __STDC__#include <stdarg.h>#else#include <varargs.h>#endif#include "spim.h"#include "spim-utils.h"#include "inst.h"#include "mem.h"#include "reg.h"#include "parser.h"#include "sym-tbl.h"#include "scanner.h"#include "y.tab.h"/* Internal functions: */#ifdef __STDC__static void console_to_program (void);static void console_to_spim (void);static void flush_to_newline (void);static int get_opt_int (void);static int parse_spim_command (FILE *file, int redo);static int print_reg (int reg_no);static int print_fp_reg (int reg_no);static int print_reg_from_string (char *reg);static void print_all_regs (int hex_flag);static int read_assembly_command (void);static int str_prefix (char *s1, char *s2, int min_match);static void top_level (void);static int read_token (void);#elsestatic void console_to_program ();static void console_to_spim ();static void flush_to_newline ();static int get_opt_int ();static int parse_spim_command ();static int print_reg ();static int print_fp_reg ();static int print_reg_from_string ();static void print_all_regs ();static int read_assembly_command ();static int str_prefix ();static void top_level ();static int read_token ();#endif/* Exported Variables: *//* Not local, but not export so all files don't need setjmp.h */jmp_buf spim_top_level_env;	/* For ^C */int bare_machine;		/* Non-Zero => simulate bare machine */int delayed_branches;		/* Non-Zero => simulate delayed branches */int delayed_loads;		/* Non-Zero => simulate delayed loads */int accept_pseudo_insts;	/* Non-Zero => parse pseudo instructions  */int quiet;			/* Non-Zero => no warning messages */int source_file;		/* Non-Zero => program is source, not binary */port message_out, console_out, console_in;int mapped_io;			/* Non-zero => activate memory-mapped IO */int pipe_out;int cycle_level;		/* Non-zero => cycle level mode *//* Local variables: */static int load_trap_handler = 1; /* Non-zero => load standard trap handler */char *trap_file = DEFAULT_TRAP_HANDLER;static int console_state_saved;#ifdef USE_TERMIOstatic struct termio saved_console_state;#elsestatic struct sgttyb saved_console_state;#endif#ifdef __STDC__intmain (int argc, char **argv)#elseintmain (argc, argv)     int argc;     char **argv;#endif{  int i;  int assembly_file_read = 0;  int argv_ptr = 0;  console_out.f = stdout;  message_out.f = stdout;  bare_machine = 0;  delayed_branches = 0;  delayed_loads = 0;  accept_pseudo_insts = 1;  quiet = 0;  source_file = 0;  cycle_level = 0;  /* Input comes directly (not through stdio): */  console_in.i = 0;  mapped_io = 0;  write_startup_message ();  if (argc == 2)    {      /* Only one argument better be a file name. */      initialize_world (load_trap_handler ? trap_file : NULL);      assembly_file_read |= !read_assembly_file (argv[++i]);    }  else    for (i = 1; i < argc; i++)      {#ifdef WIN32	/* On Windows, support "/option" as well as "-option" */	if (argv [i][0] == '/')	  argv [i][0] = '-';#endif	if (streq (argv [i], "-bare"))	  {	    bare_machine = 1;	    delayed_branches = 1;	    delayed_loads = 1;	    quiet = 1;	  }	else if (streq (argv [i], "-asm"))	  {	    bare_machine = 0;	    delayed_branches = 0;	    delayed_loads = 0;	  }	else if (streq (argv [i], "-delayed_branches"))	  {	    delayed_branches = 1;	  }	else if (streq (argv [i], "-delayed_loads"))	  {	    delayed_loads = 1;	  }	else if (streq (argv [i], "-pseudo"))	  accept_pseudo_insts = 1;	else if (streq (argv [i], "-nopseudo"))	  accept_pseudo_insts = 0;	else if (streq (argv [i], "-trap"))	  load_trap_handler = 1;	else if (streq (argv [i], "-notrap"))	  load_trap_handler = 0;	else if (streq (argv [i], "-trap_file"))	  {	    trap_file = argv[++i];	    load_trap_handler = 1;	  }	else if (streq (argv [i], "-quiet"))	  quiet = 1;	else if (streq (argv [i], "-noquiet"))	  quiet = 0;	else if (streq (argv [i], "-file"))	  {	    argv_ptr = i + 1;	    if (!assembly_file_read)	      {		initialize_world (load_trap_handler ? trap_file : NULL);	      }	    assembly_file_read |= !read_assembly_file (argv[++i]);	    break;			/* Everything that follows is argv */	  }	else if (streq (argv [i], "-mapped_io"))	  mapped_io = 1;	else if (streq (argv [i], "-nomapped_io"))	  mapped_io = 0;	else if (streq (argv [i], "-stext"))	  initial_text_size = atoi (argv[++i]);	else if (streq (argv [i], "-sdata"))	  initial_data_size = atoi (argv[++i]);	else if (streq (argv [i], "-ldata"))	  initial_data_limit = atoi (argv[++i]);	else if (streq (argv [i], "-sstack"))	  initial_stack_size = atoi (argv[++i]);	else if (streq (argv [i], "-lstack"))	  initial_stack_limit = atoi (argv[++i]);	else if (streq (argv [i], "-sktext"))	  initial_k_text_size = atoi (argv[++i]);	else if (streq (argv [i], "-skdata"))	  initial_k_data_size = atoi (argv[++i]);	else if (streq (argv [i], "-lkdata"))	  initial_k_data_limit = atoi (argv[++i]);	else	  error ("usage: spim -bare/-asm -trap/-notrap -trap_file <file> -quiet/-noquiet -mapped_io/-nomapped_io -file <file> <args>\n");      }  if (!assembly_file_read)    {      initialize_world (load_trap_handler ? trap_file : NULL);      top_level ();    }  else /* assembly_file_read */    {      console_to_program ();      initialize_run_stack (argc - argv_ptr, &argv[argv_ptr]);      if (!setjmp (spim_top_level_env))	{	  char *undefs = undefined_symbol_string ();	  if (undefs != NULL)	    {	      write_output (message_out, "The following symbols are undefined:\n");	      write_output (message_out, undefs);	      write_output (message_out, "\n");	      free (undefs);	    }	  run_program (find_symbol_address (DEFAULT_RUN_LOCATION),		       DEFAULT_RUN_STEPS, 0, 0);	}      console_to_spim ();    }  return (0);}/* Top-level read-eval-print loop for SPIM. */#ifdef __STDC__static voidtop_level (void)#elsestatic voidtop_level ()#endif{  int redo = 0;			/* Non-zero means reexecute last command */  signal (SIGINT, control_c_seen);  while (1)    {      if (!redo)	write_output (message_out, "(spim) ");      if (!setjmp (spim_top_level_env))	redo = parse_spim_command (stdin, redo);      else	redo = 0;      fflush (stdout);      fflush (stderr);    }}#ifdef __STDC__voidcontrol_c_seen (int arg)#elsevoidcontrol_c_seen (arg)int arg;#endif{  console_to_spim ();  write_output (message_out, "\nExecution interrupted\n");  longjmp (spim_top_level_env, 1);}/* SPIM commands */enum {  UNKNOWN_CMD = 0,  EXIT_CMD,  READ_CMD,  RUN_CMD,  STEP_CMD,  PRINT_CMD,  PRINT_SYM_CMD,  PRINT_ALL_REGS_CMD,  REINITIALIZE_CMD,  ASM_CMD,  REDO_CMD,  NOP_CMD,  HELP_CMD,  CONTINUE_CMD,  SET_BKPT_CMD,  DELETE_BKPT_CMD,  LIST_BKPT_CMD,  DUMPNATIVE_TEXT_CMD,  DUMP_TEXT_CMD};/* Parse a SPIM command from the FILE and execute it.  If REDO is non-zero,   don't read a new command; just rexecute the previous one.   Return non-zero if the command was to redo the previous command. */#ifdef __STDC__static intparse_spim_command (FILE *file, int redo)#elsestatic intparse_spim_command (file, redo)     FILE *file;     int redo;#endif{  static int prev_cmd = NOP_CMD; /* Default redo */  static int prev_token;  int cmd;  initialize_scanner (file);  initialize_parser ("<standard input>");  switch (cmd = (redo ? prev_cmd : read_assembly_command ()))    {    case EXIT_CMD:      console_to_spim ();      exit (0);    case READ_CMD:      {	int token = (redo ? prev_token : read_token ());	if (!redo) flush_to_newline ();	if (token == Y_STR)	  {	    read_assembly_file ((char *) yylval.p);	    initialize_scanner (file); /* Reinitialize! */	  }	else	  error ("Must supply a filename to read\n");	prev_cmd = READ_CMD;	return (0);      }    case RUN_CMD:      {	static mem_addr addr;	addr = (redo ? addr : get_opt_int ());	if (addr == 0)	  addr = starting_address ();	initialize_run_stack (0, 0);	console_to_program ();	if (addr)	{	  char *undefs = undefined_symbol_string ();	  if (undefs != NULL)	    {	      write_output (message_out, "The following symbols are undefined:\n");	      write_output (message_out, undefs);	      write_output (message_out, "\n");	      free (undefs);	    }	  if (run_program (addr, DEFAULT_RUN_STEPS, 0, 0))	    write_output (message_out, "Breakpoint encountered at 0x%08x\n",			  PC);	}	console_to_spim ();	prev_cmd = RUN_CMD;	return (0);      }    case CONTINUE_CMD:      {	if (PC != 0)	  {	    console_to_program ();	    if (run_program (PC, DEFAULT_RUN_STEPS, 0, 1))	      write_output (message_out, "Breakpoint encountered at 0x%08x\n",			    PC);	    console_to_spim ();	  }	prev_cmd = CONTINUE_CMD;	return (0);      }    case STEP_CMD:      {	static int steps;	mem_addr addr;	steps = (redo ? steps : get_opt_int ());	addr = starting_address ();	if (steps == 0)	  steps = 1;	if (addr)	  {	    console_to_program ();	    if (run_program (addr, steps, 1, 1))	      write_output (message_out, "Breakpoint encountered at 0x%08x\n",			    PC);	    console_to_spim ();	  }	prev_cmd = STEP_CMD;	return (0);      }    case PRINT_CMD:      {	int token = (redo ? prev_token : read_token ());	static int loc;	if (token == Y_REG)	  {	    if (redo) loc += 1;	    else loc = yylval.i;	    print_reg (loc);	  }	else if (token == Y_FP_REG)	  {	    if (redo) loc += 2;	    else loc = yylval.i;	    print_fp_reg (loc);	  }	else if (token == Y_INT)	  {	    if (redo) loc += 4;	    else loc = yylval.i;	    print_mem (loc);	  }	else if (token == Y_ID)	  {	    if (!print_reg_from_string ((char *) yylval.p))	      {		if (redo) loc += 4;		else loc = find_symbol_address ((char *) yylval.p);		if (loc != 0)		  print_mem (loc);		else		  error ("Unknown label: %s\n", yylval.p);	      }	  }	else	  error ("Print what?\n");	if (!redo) flush_to_newline ();	prev_cmd = PRINT_CMD;	prev_token = token;	return (0);      }    case PRINT_SYM_CMD:      print_symbols ();      if (!redo) flush_to_newline ();      prev_cmd = NOP_CMD;      return (0);    case PRINT_ALL_REGS_CMD:      {	int hex_flag = 0;	int token = (redo ? prev_token : read_token ());	if (token == Y_ID && streq(yylval.p, "hex"))	  hex_flag = 1;	print_all_regs (hex_flag);	if (!redo) flush_to_newline ();	prev_cmd = NOP_CMD;	return (0);      }    case REINITIALIZE_CMD:      flush_to_newline ();      initialize_world (load_trap_handler ? trap_file : NULL);      write_startup_message ();      prev_cmd = NOP_CMD;      return (0);    case ASM_CMD:      yyparse ();      prev_cmd = ASM_CMD;      return (0);    case REDO_CMD:      return (1);    case NOP_CMD:      prev_cmd = NOP_CMD;      return (0);    case HELP_CMD:      if (!redo) flush_to_newline ();      write_output (message_out, "\nSPIM is a MIPS R2000 simulator.\n");      write_output (message_out, "Its top-level commands are:\n");      write_output (message_out, "exit  -- Exit the simulator\n");      write_output (message_out, "quit  -- Exit the simulator\n");      write_output (message_out,		    "read \"FILE\" -- Read FILE of assembly code into memory\n");      write_output (message_out,		    "load \"FILE\" -- Same as read\n");      write_output (message_out,		    "run <ADDR> -- Start the program at optional ADDRESS\n");      write_output (message_out,		    "step <N> -- Step the program for N instructions\n");      write_output (message_out,		    "continue -- Continue program execution without stepping\n");      write_output (message_out, "print $N -- Print register N\n");      write_output (message_out,		    "print $fN -- Print floating point register N\n");      write_output (message_out,		    "print ADDR -- Print contents of memory at ADDRESS\n");      write_output (message_out,		    "print_symbols -- Print all global symbols\n");      write_output (message_out,		    "print_all_regs -- Print all MIPS registers\n");      write_output (message_out,		    "print_all_regs hex -- Print all MIPS registers in hex\n");      write_output (message_out,		    "reinitialize -- Clear the memory and registers\n");      write_output (message_out,		    "breakpoint <ADDR> -- Set a breakpoint at address\n");      write_output (message_out,		    "delete <ADDR> -- Delete all breakpoints at address\n");      write_output (message_out, "list -- List all breakpoints\n");      write_output (message_out, "dump [ \"FILE\" ] -- Dump binary code to spim.dump or FILE in network byte order\n");      write_output (message_out, "dumpnative [ \"FILE\" ] -- Dump binary code to spim.dump or FILE in host byte order\n");      write_output (message_out,		    ". -- Rest of line is assembly instruction to put in memory\n");      write_output (message_out, "<cr> -- Newline reexecutes previous command\n");      write_output (message_out, "? -- Print this message\n");      write_output (message_out,		    "\nMost commands can be abbreviated to their unique prefix\n");      write_output (message_out, "e.g., ex(it), re(ad), l(oad), ru(n), s(tep), p(rint)\n\n");      prev_cmd = HELP_CMD;      return (0);    case SET_BKPT_CMD:    case DELETE_BKPT_CMD:      {	int token = (redo ? prev_token : read_token ());	static mem_addr addr;	if (!redo) flush_to_newline ();	if (token == Y_INT)	  addr = redo ? addr + 4 : (mem_addr)yylval.i;	else if (token == Y_ID)	  addr = redo ? addr + 4 : find_symbol_address ((char *) yylval.p);	else	  error ("Must supply an address for breakpoint\n");	if (cmd == SET_BKPT_CMD)	  add_breakpoint (addr);	else	  delete_breakpoint (addr);	prev_cmd = cmd;	return (0);      }    case LIST_BKPT_CMD:      if (!redo) flush_to_newline ();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -