dlite.c
来自「一个很有名的硬件模拟器。可以模拟CPU」· C语言 代码 · 共 2,262 行 · 第 1/4 页
C
2,262 行
/* match arguments for *CMD */ for (i=0, arg_cnt=0; i<MAX_ARGS && cmd->arg_strs[i] != NULL; i++, arg_cnt++) { int optional, access, modifiers; char *arg, arg_type, *err_str; struct eval_value_t val; /* skip any whitespace before argument */ while (*p == ' ' || *p == '\t' || *p == '\n') p++; arg = cmd->arg_strs[i]; arg_type = arg[0]; optional = (arg[1] == '?'); if (*p == '\0') { if (optional) { /* all arguments parsed */ break; } else return "missing an argument"; } endp = p; switch (arg_type) { case 'm': err_str = modifier_parser(p, &endp, &modifiers); if (err_str) return err_str; args[arg_cnt].as_modifier = modifiers; break; case 'a': local_regs = regs; val = eval_expr(dlite_evaluator, p, &endp); if (eval_error) return eval_err_str[eval_error]; args[arg_cnt].as_value = val; break; case 'c': local_regs = regs; val = eval_expr(dlite_evaluator, p, &endp); if (eval_error) return eval_err_str[eval_error]; args[arg_cnt].as_value = val; break; case 'e': local_regs = regs; val = eval_expr(dlite_evaluator, p, &endp); if (eval_error) return eval_err_str[eval_error]; args[arg_cnt].as_value = val; break; case 't': access = 0; while (*p != '\0' && *p != '\n' && *p != ' ' && *p != '\t') { switch (*p) { case 'r': access |= ACCESS_READ; break; case 'w': access |= ACCESS_WRITE; break; case 'x': access |= ACCESS_EXEC; break; default: return "bad access type specifier (use r|w|x)"; } p++; } endp = p; args[arg_cnt].as_access = access; break; case 'i': local_regs = regs; val = eval_expr(dlite_evaluator, p, &endp); if (eval_error) return eval_err_str[eval_error]; args[arg_cnt].as_value = val; break; case 's': q = args[arg_cnt].as_str; while (*p != ' ' && *p != '\t' && *p != '\0') *q++ = *p++; *q = '\0'; endp = p; break; default: panic("bogus argument type: `%c'", arg_type); } p = endp; } /* skip any whitespace before any trailing argument */ while (*p == ' ' || *p == '\t' || *p == '\n') p++; /* check for any orphan arguments */ if (*p != '\0') return "too many arguments"; /* if we reach here, all arguments were parsed correctly, call handler */ return cmd->cmd_fn(arg_cnt, args, regs, mem);}/* print expression value VAL using modifiers MODIFIERS */static char * /* err str, NULL for no err */print_val(int modifiers, /* print modifiers */ struct eval_value_t val) /* expr value to print */{ char *format = "", *prefix = "", radix, buf[512]; /* fill in any default size */ if ((modifiers & MOD_SIZES) == 0) { /* compute default size */ switch (val.type) { case et_int: modifiers |= MOD_WORD; break; case et_uint: modifiers |= MOD_WORD; break; case et_addr:#ifdef HOST_HAS_QWORD if (sizeof(md_addr_t) > 4) modifiers |= MOD_QWORD; else#endif /* HOST_HAS_QWORD */ modifiers |= MOD_WORD; break;#ifdef HOST_HAS_QWORD case et_qword: modifiers |= MOD_QWORD; break; case et_sqword: modifiers |= MOD_QWORD; break;#endif /* HOST_HAS_QWORD */ case et_float: modifiers |= MOD_FLOAT; break; case et_double: modifiers |= MOD_DOUBLE; break; case et_symbol: default: return "bad print value"; } } if (((modifiers & MOD_SIZES) & ((modifiers & MOD_SIZES) - 1)) != 0) return "multiple size specifiers"; /* fill in any default format */ if ((modifiers & MOD_FORMATS) == 0) { /* compute default size */ switch (val.type) { case et_int: modifiers |= MOD_DECIMAL; break; case et_uint: modifiers |= MOD_UNSIGNED; break; case et_addr: modifiers |= MOD_HEX; break;#ifdef HOST_HAS_QWORD case et_qword: modifiers |= MOD_UNSIGNED; break; case et_sqword: modifiers |= MOD_DECIMAL; break;#endif /* HOST_HAS_QWORD */ case et_float: /* use default format */break; case et_double: /* use default format */break; case et_symbol: default: return "bad print value"; } } if (((modifiers & MOD_FORMATS) & ((modifiers & MOD_FORMATS) - 1)) != 0) return "multiple format specifiers"; /* decode modifiers */ if (modifiers & (MOD_BYTE|MOD_HALF|MOD_WORD|MOD_QWORD)) { if (modifiers & MOD_DECIMAL) radix = 'd'; else if (modifiers & MOD_UNSIGNED) radix = 'u'; else if (modifiers & MOD_OCTAL) radix = 'o'; else if (modifiers & MOD_HEX) radix = 'x'; else if (modifiers & MOD_BINARY) return "binary format not yet implemented"; else panic("no default integer format"); if (modifiers & MOD_BYTE) { if (modifiers & MOD_OCTAL) { prefix = "0"; format = "03"; } else if (modifiers & MOD_HEX) { prefix = "0x"; format = "02"; } else { prefix = ""; format = ""; } sprintf(buf, "%s%%%s%c", prefix, format, radix); myfprintf(stdout, buf, eval_as_uint(val)); } else if (modifiers & MOD_HALF) { if (modifiers & MOD_OCTAL) { prefix = "0"; format = "06"; } else if (modifiers & MOD_HEX) { prefix = "0x"; format = "04"; } else { prefix = ""; format = ""; } sprintf(buf, "%s%%%s%c", prefix, format, radix); myfprintf(stdout, buf, eval_as_uint(val)); } else if (modifiers & MOD_WORD) { if (modifiers & MOD_OCTAL) { prefix = "0"; format = "011"; } else if (modifiers & MOD_HEX) { prefix = "0x"; format = "08"; } else { prefix = ""; format = ""; } sprintf(buf, "%s%%%s%c", prefix, format, radix); myfprintf(stdout, buf, eval_as_uint(val)); }#ifdef HOST_HAS_QWORD else if (modifiers & MOD_QWORD) { if (modifiers & MOD_OCTAL) { prefix = "0"; format = "022"; } else if (modifiers & MOD_HEX) { prefix = "0x"; format = "016"; } else { prefix = ""; format = ""; } sprintf(buf, "%s%%%sl%c", prefix, format, radix); myfprintf(stdout, buf, eval_as_qword(val)); }#endif /* HOST_HAS_QWORD */ } else if (modifiers & MOD_FLOAT) fprintf(stdout, "%f", (double)eval_as_float(val)); else if (modifiers & MOD_DOUBLE) fprintf(stdout, "%f", eval_as_double(val)); else if (modifiers & MOD_CHAR) fprintf(stdout, "`%c'", eval_as_uint(val)); else if (modifiers & MOD_STRING) return "string format not yet implemented"; else /* no format specified, default to value type format */ panic("no default format"); /* no error */ return NULL;}/* default memory state accessor */char * /* err str, NULL for no err */dlite_mem_obj(struct mem_t *mem, /* memory space to access */ int is_write, /* access type */ md_addr_t addr, /* address to access */ char *p, /* input/output buffer */ int nbytes) /* size of access */{ enum mem_cmd cmd; if (!is_write) cmd = Read; else cmd = Write;#if 0 char *errstr; errstr = mem_valid(cmd, addr, nbytes, /* !declare */FALSE); if (errstr) return errstr;#endif /* else, no error, access memory */ mem_access(mem, cmd, addr, p, nbytes); /* no error */ return NULL;}/* default machine state accessor */char * /* err str, NULL for no err */dlite_mstate_obj(FILE *stream, /* output stream */ char *cmd, /* optional command string */ struct regs_t *regs, /* registers to access */ struct mem_t *mem) /* memory to access */{ /* nada */ fprintf(stream, "No machine state.\n"); /* no error */ return NULL;}/* scroll terminator, wait for user to press return */static voiddlite_pause(void){ char buf[512]; fprintf(stdout, "Press <return> to continue..."); fflush(stdout); fgets(buf, 512, stdin);}/* print help information for DLite command CMD */static voidprint_help(struct dlite_cmd_t *cmd) /* command to describe */{ int i; /* print command name */ fprintf(stdout, " %s ", cmd->cmd_str); /* print arguments of command */ for (i=0; i < MAX_ARGS && cmd->arg_strs[i] != NULL; i++) { int optional; char *arg, arg_type; arg = cmd->arg_strs[i]; arg_type = arg[0]; optional = (arg[1] == '?'); if (optional) fprintf(stdout, "{"); else fprintf(stdout, "<"); switch (arg_type) { case 'm': fprintf(stdout, "/modifiers"); break; case 'a': fprintf(stdout, "addr"); break; case 'c': fprintf(stdout, "count"); break; case 'e': fprintf(stdout, "expr"); break; case 't': fprintf(stdout, "r|w|x"); break; case 'i': fprintf(stdout, "id"); break; case 's': fprintf(stdout, "string"); break; default: panic("bogus argument type: `%c'", arg_type); } if (optional) fprintf(stdout, "}"); else fprintf(stdout, ">"); fprintf(stdout, " "); } fprintf(stdout, "\n"); /* print command description */ fprintf(stdout, " %s\n", cmd->help_str);}/* print help messages for all (or single) DLite debugger commands */static char * /* err str, NULL for no err */dlite_help(int nargs, union arg_val_t args[], /* command arguments */ struct regs_t *regs, /* registers to access */ struct mem_t *mem) /* memory to access */{ struct dlite_cmd_t *cmd; if (nargs != 0 && nargs != 1) return "too many arguments"; if (nargs == 1) { /* print help for specified commands */ for (cmd=cmd_db; cmd->cmd_str != NULL; cmd++) { if (!strcmp(cmd->cmd_str, args[0].as_str)) break; } if (!cmd->cmd_str) return "command unknown"; print_help(cmd); } else { /* print help for all commands */ for (cmd=cmd_db; cmd->cmd_str != NULL; cmd++) { /* `---' specifies a good point for a scroll pause */ if (!strcmp(cmd->cmd_str, "---")) dlite_pause(); else print_help(cmd); } fprintf (stdout, "\n"); if (dlite_help_tail) fprintf (stdout, "%s\n", dlite_help_tail); } /* no error */ return NULL;}/* print version information for simulator */static char * /* err str, NULL for no err */dlite_version(int nargs, union arg_val_t args[],/* command arguments */ struct regs_t *regs, /* registers to access */ struct mem_t *mem) /* memory to access */{ if (nargs != 0) return "too many arguments"; /* print simulator version info */ fprintf(stdout, "The SimpleScalar/%s Tool Set, version %d.%d of %s.\n", VER_TARGET, VER_MAJOR, VER_MINOR, VER_UPDATE); fprintf(stdout, "Copyright (c) 1994-1998 by Todd M. Austin. All Rights Reserved.\n"); /* no error */ return NULL;}/* terminate simulation with statistics */static char * /* err str, NULL for no err */dlite_terminate(int nargs, union arg_val_t args[],/* command arguments */ struct regs_t *regs, /* registers to access */ struct mem_t *mem) /* memory to access */{ if (nargs != 0) return "too many arguments"; fprintf(stdout, "DLite: terminating simulation...\n"); longjmp(sim_exit_buf, /* exitcode */1); /* no error */ return NULL;}/* quit the simulator, omit any stats dump */static char * /* err str, NULL for no err */dlite_quit(int nargs, union arg_val_t args[], /* command arguments */ struct regs_t *regs, /* registers to access */ struct mem_t *mem) /* memory to access */{ if (nargs != 0) return "too many arguments"; fprintf(stdout, "DLite: exiting simulator...\n"); exit(1); /* no error */ return NULL;}/* continue executing program (possibly at specified address) */static char * /* err str, NULL for no err */dlite_cont(int nargs, union arg_val_t args[], /* command arguments */ struct regs_t *regs, /* registers to access */ struct mem_t *mem) /* memory to access */{ struct eval_value_t val; if (!f_dlite_reg_obj || !f_dlite_mem_obj) panic("DLite is not configured"); if (nargs != 0 && nargs != 1) return "too many arguments"; if (nargs == 1) { /* continue from specified address, check address */ if (!EVAL_INTEGRAL(args[0].as_value.type)) return "address argument must be an integral type"; /* reset PC */ val.type = et_addr; val.value.as_addr = eval_as_addr(args[0].as_value); f_dlite_reg_obj(regs, /* is_write */TRUE, rt_PC, 0, &val); myfprintf(stdout, "DLite: continuing execution @ 0x%08p...\n", val.value.as_addr); } /* signal end of main debugger loop, and continuation of prog execution */ dlite_active = FALSE; dlite_return = TRUE; /* no error */ return NULL;}/* step program one instruction */static char * /* err str, NULL for no err */dlite_step(int nargs, union arg_val_t args[], /* command arguments */ struct regs_t *regs, /* registers to access */ struct mem_t *mem) /* memory to access */{ if (nargs != 0) return "too many arguments"; /* signal on instruction step */ dlite_active = TRUE; dlite_return = TRUE; /* no error */ return NULL;}#if 0 /* NYI *//* step program one instruction in current procedure */static char * /* err str, NULL for no err */dlite_next(int nargs, union arg_val_t args[]) /* command arguments */{ if (nargs != 0) return "too many arguments"; /* signal on instruction step */ dlite_step_cnt = 1;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?