📄 dlite.c
字号:
/* execute DLite command string CMD */static char * /* err str, NULL if no err */dlite_exec(char *cmd_str) /* command string */{ int i, arg_cnt; struct dlite_cmd_t *cmd; char cmd_buf[512], *p, *q, *endp; union arg_val_t args[MAX_ARGS]; p = cmd_str; q = cmd_buf; /* skip any whitespace before argument */ while (*p == ' ' || *p == '\t' || *p == '\n') p++; /* anything left? */ if (*p == '\0') { /* NOP, no error */ return NULL; } /* copy out command name string */ while (*p != '\0' && *p != '\n' && *p != ' ' && *p != '\t' && *p != '/') *q++ = *p++; *q = '\0'; /* find matching command */ for (cmd=cmd_db; cmd->cmd_str != NULL; cmd++) { if (!strcmp(cmd->cmd_str, cmd_buf)) break; } if (cmd->cmd_str == NULL) return "unknown command"; /* 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': 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': 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': 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': 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);}/* 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]; /* decode modifiers */ if (modifiers & (MOD_BYTE|MOD_HALF|MOD_WORD)) { if (modifiers & MOD_BYTE) { if (modifiers & (MOD_HALF|MOD_WORD|MOD_FLOAT|MOD_DOUBLE|MOD_CHAR|MOD_STRING)) return "multiple format type specifiers"; if (modifiers & MOD_OCTAL) { prefix = "0"; format = "03"; } else if (modifiers & MOD_HEX) { prefix = "0x"; format = "02"; } else { prefix = ""; format = ""; } } else if (modifiers & MOD_HALF) { if (modifiers & (MOD_BYTE|MOD_WORD|MOD_FLOAT|MOD_DOUBLE|MOD_CHAR|MOD_STRING)) return "multiple format type specifiers"; if (modifiers & MOD_OCTAL) { prefix = "0"; format = "06"; } else if (modifiers & MOD_HEX) { prefix = "0x"; format = "04"; } else { prefix = ""; format = ""; } } else if (modifiers & MOD_WORD) { if (modifiers & (MOD_BYTE|MOD_HALF|MOD_FLOAT|MOD_DOUBLE|MOD_CHAR|MOD_STRING)) return "multiple format type specifiers"; if (modifiers & MOD_OCTAL) { prefix = "0"; format = "011"; } else if (modifiers & MOD_HEX) { prefix = "0x"; format = "08"; } else { prefix = ""; format = ""; } } /* one of the above will hit */ if (modifiers & MOD_DECIMAL) { if (modifiers & (MOD_UDECIMAL|MOD_OCTAL|MOD_HEX|MOD_BINARY)) return "multiple format radix specifiers"; radix = 'd'; } else if (modifiers & MOD_UDECIMAL) { if (modifiers & (MOD_DECIMAL|MOD_OCTAL|MOD_HEX|MOD_BINARY)) return "multiple format radix specifiers"; radix = 'u'; } else if (modifiers & MOD_OCTAL) { if (modifiers & (MOD_DECIMAL|MOD_UDECIMAL|MOD_HEX|MOD_BINARY)) return "multiple format radix specifiers"; radix = 'o'; } else if (modifiers & MOD_HEX) { if (modifiers & (MOD_DECIMAL|MOD_UDECIMAL|MOD_OCTAL|MOD_BINARY)) return "multiple format radix specifiers"; radix = 'x'; } else if (modifiers & MOD_BINARY) { if (modifiers & (MOD_DECIMAL|MOD_UDECIMAL|MOD_OCTAL|MOD_HEX)) return "multiple format radix specifiers"; radix = '1'; /* FIXME: NYI */ return "binary format not yet implemented"; } else { /* default type is MOD_DECIMAL */ modifiers |= MOD_DECIMAL; return print_val(modifiers, val); } sprintf(buf, "%s%%%s%c", prefix, format, radix); fprintf(stdout, buf, eval_as_uint(val)); } else if (modifiers & MOD_FLOAT) { if (modifiers & (MOD_BYTE|MOD_HALF|MOD_WORD|MOD_DOUBLE|MOD_CHAR|MOD_STRING)) return "multiple format type specifiers"; fprintf(stdout, "%f", (double)eval_as_float(val)); } else if (modifiers & MOD_DOUBLE) { if (modifiers & (MOD_BYTE|MOD_HALF|MOD_WORD|MOD_FLOAT|MOD_CHAR|MOD_STRING)) return "multiple format type specifiers"; fprintf(stdout, "%f", eval_as_double(val)); } else if (modifiers & MOD_CHAR) { if (modifiers & (MOD_BYTE|MOD_HALF|MOD_WORD|MOD_FLOAT|MOD_DOUBLE|MOD_STRING)) return "multiple format type specifiers"; fprintf(stdout, "`%c'", eval_as_uint(val)); } else if (modifiers & MOD_STRING) { if (modifiers & (MOD_BYTE|MOD_HALF|MOD_WORD|MOD_FLOAT|MOD_DOUBLE|MOD_CHAR)) return "multiple format type specifiers"; /* FIXME: NYI */ return "string format not yet implemented"; } else { /* default modifier matches VAL type */ switch (val.type) { case et_int: modifiers |= MOD_WORD; break; case et_uint: modifiers |= MOD_WORD; break; case et_float: modifiers |= MOD_FLOAT; break; case et_double: modifiers |= MOD_DOUBLE; break; case et_symbol: default: modifiers |= MOD_WORD; break; } return print_val(modifiers, val); } /* no error */ return NULL;}/* default register state accessor */char * /* err str, NULL for no err */dlite_reg_obj(enum dlite_access_t at, /* access type */ enum dlite_reg_t rt, /* reg bank to probe */ int reg, /* register number */ union dlite_reg_val_t *val) /* input, output */{ if (reg < 0 || reg >= SS_NUM_REGS) return "register number out of range"; if (at == at_read || at == at_write) { switch (rt) { case rt_gpr: if (at == at_read) val->as_word = regs_R[reg]; else regs_R[reg] = val->as_word; break; case rt_lpr: if (at == at_read) val->as_word = regs_F.l[reg]; else regs_F.l[reg] = val->as_word; break; case rt_fpr: if (at == at_read) val->as_float = regs_F.f[reg]; else regs_F.f[reg] = val->as_float; break; case rt_dpr: /* 1/2 as many regs in this mode */ if (reg < 0 || reg >= SS_NUM_REGS/2) return "register number out of range"; if (at == at_read) val->as_double = regs_F.d[reg]; else regs_F.d[reg] = val->as_double; break; case rt_hi: if (at == at_read) val->as_word = regs_HI; else regs_HI = val->as_word; break; case rt_lo: if (at == at_read) val->as_word = regs_LO; else regs_LO = val->as_word; break; case rt_FCC: if (at == at_read) val->as_condition = regs_FCC; else regs_FCC = val->as_condition; break; case rt_PC: if (at == at_read) val->as_address = regs_PC; else regs_PC = val->as_address; break; default: panic("bogus register bank"); } } else panic("bogus access type"); /* no error */ return NULL;}/* default memory state accessor */char * /* err str, NULL for no err */dlite_mem_obj(enum dlite_access_t at, /* access type */ SS_ADDR_TYPE addr, /* address to access */ char *p, /* input/output buffer */ int nbytes) /* size of access */{ char *errstr; enum mem_cmd cmd; if (at == at_read) cmd = Read; else if (at == at_write) cmd = Write; else panic("bogus access type"); errstr = mem_valid(cmd, addr, nbytes, /* !declare */FALSE); if (errstr) return errstr; /* else, no error, access memory */ mem_access(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 */{ /* 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, "{"); 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, "}"); 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 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) 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 */{ if (nargs != 0) return "too many arguments"; /* print simulator version info */ fprintf(stdout, "The SimpleScalar Tool Set, version %d.%d of %s.\n", VER_MAJOR, VER_MINOR, VER_UPDATE); fprintf(stdout, "Copyright (c) 1994-1996 by Todd M. Austin. All Rights Reserved.\n"); /* no error */ return NULL;}/* terminate simulation with statistics */static char * /* err str, NULL for no err */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -