📄 alpha.c
字号:
{ switch (rt) { case rt_gpr: if (reg < 0 || reg >= MD_NUM_IREGS) return "register number out of range"; if (!is_write) { val->type = et_qword; val->value.as_qword = regs->regs_R[reg]; } else regs->regs_R[reg] = eval_as_qword(*val); break; case rt_lpr: if (reg < 0 || reg >= MD_NUM_FREGS) return "register number out of range"; if (!is_write) { val->type = et_qword; val->value.as_qword = regs->regs_F.q[reg]; } else regs->regs_F.q[reg] = eval_as_qword(*val); break; case rt_fpr: if (reg < 0 || reg >= MD_NUM_FREGS) 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 /* FPCR */0: if (!is_write) { val->type = et_qword; val->value.as_qword = regs->regs_C.fpcr; } else regs->regs_C.fpcr = eval_as_qword(*val); break; case /* UNIQ */1: if (!is_write) { val->type = et_qword; val->value.as_qword = regs->regs_C.uniq; } else regs->regs_C.uniq = eval_as_qword(*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 */voidmd_print_ireg(md_gpr_t regs, int reg, FILE *stream){ myfprintf(stream, "%4s: %16ld/0x%012lx", md_reg_name(rt_gpr, reg), regs[reg], regs[reg]);}voidmd_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 */voidmd_print_fpreg(md_fpr_t regs, int reg, FILE *stream){ myfprintf(stream, "%4s: %16ld/0x%012lx/%f", md_reg_name(rt_fpr, reg), regs.q[reg], regs.q[reg], regs.d[reg]);}voidmd_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"); }}voidmd_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: myfprintf(stream, "FPCR: 0x%012lx", regs.fpcr); break; case 1: myfprintf(stream, "UNIQ: 0x%012lx", regs.uniq); break; default: panic("bogus control register index"); }}voidmd_print_cregs(md_ctrl_t regs, FILE *stream){ md_print_creg(regs, 0, stream); fprintf(stream, " "); md_print_creg(regs, 1, stream); fprintf(stream, "\n");}/* xor checksum registers */word_tmd_xor_regs(struct regs_t *regs){ int i; qword_t checksum = 0; for (i=0; i < (MD_NUM_IREGS-1); i++) checksum ^= regs->regs_R[i]; for (i=0; i < (MD_NUM_FREGS-1); i++) checksum ^= regs->regs_F.q[i]; checksum ^= regs->regs_C.fpcr; checksum ^= regs->regs_C.uniq; checksum ^= regs->regs_PC; checksum ^= regs->regs_NPC; return (word_t)((checksum >> 32) ^ 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 */voidmd_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", (MSK)+offset); \ 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", (MSK)+offset); \ 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 an Alpha instruction */voidmd_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; /* FIXME: %-10s crashes on Suns!!! */ fprintf(stream, "%s ", MD_OP_NAME(op)); s = MD_OP_FORMAT(op); while (*s) { switch (*s) { case 'a': fprintf(stream, "r%d", RA); break; case 'b': fprintf(stream, "r%d", RB); break; case 'c': fprintf(stream, "r%d", RC); break; case 'A': fprintf(stream, "f%d", RA); break; case 'B': fprintf(stream, "f%d", RB); break; case 'C': fprintf(stream, "f%d", RC); break; case 'o': fprintf(stream, "%d", (sword_t)SEXT(OFS)); break; case 'j': myfprintf(stream, "0x%p", pc + (SEXT(OFS) << 2) + 4); break; case 'J': myfprintf(stream, "0x%p", pc + (SEXT21(TARG) << 2) + 4); break; case 'i': fprintf(stream, "%d", (word_t)IMM); break; default: /* anything unrecognized, e.g., '.' is just passed through */ fputc(*s, stream); } s++; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -