📄 mips.c.svn-base
字号:
if (reg < 0 || reg >= MD_NUM_FREGS)
return "register number out of range";
if (!is_write)
{
val->type = et_uint;
val->value.as_uint = regs->regs_F.l[reg];
}
else
regs->regs_F.l[reg] = eval_as_uint(*val);
break;
case rt_fpr:
if (reg < 0 || reg >= MD_NUM_FREGS)
return "register number out of range";
if (!is_write)
{
val->type = et_float;
val->value.as_float = regs->regs_F.f[reg];
}
else
regs->regs_F.f[reg] = eval_as_float(*val);
break;
case rt_dpr:
if (reg < 0 || reg >= MD_NUM_FREGS/2)
return "register number out of range";
if (!is_write)
{
val->type = et_double;
val->value.as_double = regs->regs_F.d[reg];
}
else
regs->regs_F.d[reg] = eval_as_double(*val);
break;
case rt_ctrl:
switch (reg)
{
case /* HI */0:
if (!is_write)
{
val->type = et_uint;
val->value.as_uint = regs->regs_C.hi;
}
else
regs->regs_C.hi = eval_as_uint(*val);
break;
case /* LO */1:
if (!is_write)
{
val->type = et_uint;
val->value.as_uint = regs->regs_C.lo;
}
else
regs->regs_C.lo = eval_as_uint(*val);
break;
case /* FCC */2:
if (!is_write)
{
val->type = et_int;
val->value.as_int = regs->regs_C.fcc;
}
else
regs->regs_C.fcc = eval_as_uint(*val);
break;
default:
return "register number out of range";
}
break;
case rt_PC:
if (!is_write)
{
val->type = et_addr;
val->value.as_addr = regs->regs_PC;
}
else
regs->regs_PC = eval_as_addr(*val);
break;
case rt_NPC:
if (!is_write)
{
val->type = et_addr;
val->value.as_addr = regs->regs_NPC;
}
else
regs->regs_NPC = eval_as_addr(*val);
break;
default:
panic("bogus register bank");
}
/* no error */
return NULL;
}
/* print integer REG(S) to STREAM */
void
md_print_ireg(md_gpr_t regs, int reg, FILE *stream)
{
fprintf(stream, "%4s: %12d/0x%08x",
md_reg_name(rt_gpr, reg), regs[reg], regs[reg]);
}
void
md_print_iregs(md_gpr_t regs, FILE *stream)
{
int i;
for (i=0; i < MD_NUM_IREGS; i += 2)
{
md_print_ireg(regs, i, stream);
fprintf(stream, " ");
md_print_ireg(regs, i+1, stream);
fprintf(stream, "\n");
}
}
/* print floating point REGS to STREAM */
void
md_print_fpreg(md_fpr_t regs, int reg, FILE *stream)
{
fprintf(stream, "%4s: %12d/0x%08x/%f",
md_reg_name(rt_fpr, reg), regs.l[reg], regs.l[reg], regs.f[reg]);
if (/* even? */!(reg & 1))
{
fprintf(stream, " (%4s as double: %f)",
md_reg_name(rt_dpr, reg/2), regs.d[reg/2]);
}
}
void
md_print_fpregs(md_fpr_t regs, FILE *stream)
{
int i;
/* floating point registers */
for (i=0; i < MD_NUM_FREGS; i += 2)
{
md_print_fpreg(regs, i, stream);
fprintf(stream, "\n");
md_print_fpreg(regs, i+1, stream);
fprintf(stream, "\n");
}
}
void
md_print_creg(md_ctrl_t regs, int reg, FILE *stream)
{
/* index is only used to iterate over these registers, hence no enums... */
switch (reg)
{
case 0:
fprintf(stream, "HI: 0x%08x", regs.hi);
break;
case 1:
fprintf(stream, "LO: 0x%08x", regs.lo);
break;
case 2:
fprintf(stream, "FCC: 0x%08x", regs.fcc);
break;
default:
panic("bogus control register index");
}
}
void
md_print_cregs(md_ctrl_t regs, FILE *stream)
{
md_print_creg(regs, 0, stream);
fprintf(stream, " ");
md_print_creg(regs, 1, stream);
fprintf(stream, " ");
md_print_creg(regs, 2, stream);
fprintf(stream, "\n");
}
/* compute CRC of all registers */
word_t
md_crc_regs(struct regs_t *regs)
{
int i;
word_t crc_accum = 0;
for (i=0; i < MD_NUM_IREGS; i++)
crc_accum = crc(crc_accum, regs->regs_R[i]);
for (i=0; i < MD_NUM_FREGS; i++)
crc_accum = crc(crc_accum, regs->regs_F.l[i]);
crc_accum = crc(crc_accum, regs->regs_C.hi);
crc_accum = crc(crc_accum, regs->regs_C.lo);
crc_accum = crc(crc_accum, regs->regs_C.fcc);
crc_accum = crc(crc_accum, regs->regs_PC);
crc_accum = crc(crc_accum, regs->regs_NPC);
return crc_accum;
}
/* xor checksum registers */
word_t
md_xor_regs(struct regs_t *regs)
{
int i;
word_t checksum = 0;
for (i=0; i < MD_NUM_IREGS; i++)
checksum ^= regs->regs_R[i];
for (i=0; i < MD_NUM_FREGS; i++)
checksum ^= regs->regs_F.l[i];
checksum ^= regs->regs_C.hi;
checksum ^= regs->regs_C.lo;
checksum ^= regs->regs_C.fcc;
checksum ^= regs->regs_PC;
checksum ^= regs->regs_NPC;
return checksum;
}
/* enum md_opcode -> opcode flags, used by simulators */
unsigned int md_op2flags[OP_MAX] = {
NA, /* NA */
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3) FLAGS,
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT) NA,
#define CONNECT(OP)
#include "machine.def"
};
/* intialize the inst decoder, this function builds the ISA decode tables */
void
md_init_decoder(void)
{
unsigned long max_offset = 0;
unsigned long offset = 0;
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3) \
if ((MSK)+offset >= MD_MAX_MASK) \
panic("MASK_MAX is too small, index==%d", (MSK)+offset); \
if (md_mask2op[(MSK)+offset]) \
fatal("doubly defined opcode, index==%d,name=%s", (MSK)+offset,NAME);\
md_mask2op[(MSK)+offset]=(OP); max_offset=MAX(max_offset,(MSK)+offset);
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT) \
if ((MSK)+offset >= MD_MAX_MASK) \
panic("MASK_MAX is too small, index==%d,name=%s", (MSK)+offset,NAME);\
if (md_mask2op[(MSK)+offset]) \
fatal("doubly defined opcode, index==%d", (MSK)+offset); \
md_mask2op[(MSK)+offset]=(OP); max_offset=MAX(max_offset,(MSK)+offset);
#define CONNECT(OP) \
offset = max_offset+1; md_opoffset[OP] = offset;
#include "machine.def"
if (max_offset >= MD_MAX_MASK)
panic("MASK_MAX is too small, index==%d", max_offset);
}
/* disassemble a SimpleScalar instruction */
void
md_print_insn(md_inst_t inst, /* instruction to disassemble */
md_addr_t pc, /* addr of inst, used for PC-rels */
FILE *stream) /* output stream */
{
enum md_opcode op;
/* use stderr as default output stream */
if (!stream)
stream = stderr;
/* decode the instruction, assumes predecoded text segment */
MD_SET_OPCODE(op,inst);
/* disassemble the instruction */
if (op == OP_NA || op >= OP_MAX)
{
/* bogus instruction */
fprintf(stream, "<invalid inst: 0x%08x>", inst);
}
else
{
char *s;
fprintf(stream, "%-10s", MD_OP_NAME(op));
s = MD_OP_FORMAT(op);
while (*s) {
switch (*s) {
case 'd':
fprintf(stream, "r%d", RD);
break;
case 's':
fprintf(stream, "r%d", RS);
break;
case 't':
fprintf(stream, "r%d", RT);
break;
case 'b':
fprintf(stream, "r%d", BS);
break;
case 'D':
fprintf(stream, "f%d", FD);
break;
case 'S':
fprintf(stream, "f%d", FS);
break;
case 'T':
fprintf(stream, "f%d", FT);
break;
case 'j':
fprintf(stream, "0x%x", (pc + 4 + (OFS << 2)));
break;
case 'o':
case 'i':
fprintf(stream, "%d", IMM);
break;
case 'H':
fprintf(stream, "%d", SHAMT);
break;
case 'u':
fprintf(stream, "%u", UIMM);
break;
case 'U':
fprintf(stream, "0x%x", UIMM);
break;
case 'J':
fprintf(stream, "0x%x", ((pc & 036000000000) | (TARG << 2)));
break;
case 'B':
fprintf(stream, "0x%x", BCODE);
break;
#if 0 /* FIXME: obsolete... */
case ')':
/* handle pre- or post-inc/dec */
if (SS_COMP_OP == SS_COMP_NOP)
fprintf(stream, ")");
else if (SS_COMP_OP == SS_COMP_POST_INC)
fprintf(stream, ")+");
else if (SS_COMP_OP == SS_COMP_POST_DEC)
fprintf(stream, ")-");
else if (SS_COMP_OP == SS_COMP_PRE_INC)
fprintf(stream, ")^+");
else if (SS_COMP_OP == SS_COMP_PRE_DEC)
fprintf(stream, ")^-");
else if (SS_COMP_OP == SS_COMP_POST_DBL_INC)
fprintf(stream, ")++");
else if (SS_COMP_OP == SS_COMP_POST_DBL_DEC)
fprintf(stream, ")--");
else if (SS_COMP_OP == SS_COMP_PRE_DBL_INC)
fprintf(stream, ")^++");
else if (SS_COMP_OP == SS_COMP_PRE_DBL_DEC)
fprintf(stream, ")^--");
else
panic("bogus SS_COMP_OP");
break;
#endif
default:
/* anything unrecognized, e.g., '.' is just passed through */
fputc(*s, stream);
}
s++;
}
}
}
/* flag of the delay slot */
int is_jump = 0;
/* flag of branch likely delay slot annulling*/
int is_annulled = 0;
/* mmap,handle mmap */
md_addr_t mmap_base = MMAP_START_ADDR;
/* mmap segment size in bytes */
unsigned int mmap_size = 0;
md_addr_t target_PC = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -