📄 isa.c
字号:
ovf = ((int)argA > 0 == (int)argB < 0) && ((int)val < 0 != (int)argB < 0); break; case A_AND: case A_XOR: ovf = FALSE; break; default: ovf = FALSE; } return PACK_CC(zero,sign,ovf); }char *cc_names[8] = { "Z=0 S=0 O=0", "Z=0 S=0 O=1", "Z=0 S=1 O=0", "Z=0 S=1 O=1", "Z=1 S=0 O=0", "Z=1 S=0 O=1", "Z=1 S=1 O=0", "Z=1 S=1 O=1"};char *cc_name(cc_t c){ int ci = c; if (ci < 0 || ci > 7) return "???????????"; else return cc_names[c];}/* Exception types */char *exc_names[] = { "BUB", "AOK", "HLT", "ADR", "INS", "PIP" };char *exc_name(exc_t e){ if (e < 0 || e > EXC_PIPE) return "Invalid Exception"; return exc_names[e];}/**************** Implementation of ISA model ************************/state_ptr new_state(int memlen){ state_ptr result = (state_ptr) malloc(sizeof(state_rec)); result->pc = 0; result->r = init_reg(); result->m = init_mem(memlen); result->cc = DEFAULT_CC; return result;}void free_state(state_ptr s){ free_reg(s->r); free_mem(s->m); free((void *) s);}state_ptr copy_state(state_ptr s) { state_ptr result = (state_ptr) malloc(sizeof(state_rec)); result->pc = s->pc; result->r = copy_reg(s->r); result->m = copy_mem(s->m); result->cc = s->cc; return result;}bool_t diff_state(state_ptr olds, state_ptr news, FILE *outfile) { bool_t diff = FALSE; if (olds->pc != news->pc) { diff = TRUE; if (outfile) { fprintf(outfile, "pc:\t0x%.8x\t0x%.8x\n", olds->pc, news->pc); } } if (olds->cc != news->cc) { diff = TRUE; if (outfile) { fprintf(outfile, "cc:\t%s\t%s\n", cc_name(olds->cc), cc_name(news->cc)); } } if (diff_reg(olds->r, news->r, outfile)) diff = TRUE; if (diff_mem(olds->m, news->m, outfile)) diff = TRUE; return diff;}/* Branch logic */bool_t take_branch(cc_t cc, jump_t bcond) { bool_t zf = GET_ZF(cc); bool_t sf = GET_SF(cc); bool_t of = GET_OF(cc); bool_t jump = FALSE; switch(bcond) { case J_YES: jump = TRUE; break; case J_LE: jump = (sf^of)|zf; break; case J_L: jump = sf^of; break; case J_E: jump = zf; break; case J_NE: jump = zf^1; break; case J_GE: jump = sf^of^1; break; case J_G: jump = (sf^of^1)&(zf^1); break; default: jump = FALSE; break; } return jump;}/* Execute single instruction. Return exception condition. */exc_t step_state(state_ptr s, FILE *error_file){ word_t argA, argB; byte_t byte0 = 0; byte_t byte1 = 0; itype_t hi0; alu_t lo0; reg_id_t hi1 = REG_NONE; reg_id_t lo1 = REG_NONE; bool_t ok1 = TRUE; word_t cval; word_t okc = TRUE; word_t val, dval; bool_t need_regids; bool_t need_imm; word_t ftpc = s->pc; if (!get_byte_val(s->m, ftpc, &byte0)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } ftpc++; hi0 = HI4(byte0); lo0 = LO4(byte0); need_regids = (hi0 == I_RRMOVL || hi0 == I_ALU || hi0 == I_PUSHL || hi0 == I_POPL || hi0 == I_IRMOVL || hi0 == I_RMMOVL || hi0 == I_MRMOVL || hi0 == I_IADDL); if (need_regids) { ok1 = get_byte_val(s->m, ftpc, &byte1); ftpc++; hi1 = HI4(byte1); lo1 = LO4(byte1); } need_imm = (hi0 == I_IRMOVL || hi0 == I_RMMOVL || hi0 == I_MRMOVL || hi0 == I_JMP || hi0 == I_CALL || hi0 == I_IADDL); if (need_imm) { okc = get_word_val(s->m, ftpc, &cval); ftpc += 4; } switch (hi0) { case I_NOP: s->pc = ftpc; break; case I_HALT: s->pc = ftpc; return EXC_HALT; break; case I_RRMOVL: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } if (hi1 >= 8) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, hi1); return EXC_INSTR; } if (lo1 >= 8) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, lo1); return EXC_INSTR; } val = get_reg_val(s->r, hi1); set_reg_val(s->r, lo1, val); s->pc = ftpc; break; case I_IRMOVL: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } if (!okc) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address", s->pc); return EXC_INSTR; } if (lo1 >= 8) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, lo1); return EXC_INSTR; } set_reg_val(s->r, lo1, cval); s->pc = ftpc; break; case I_RMMOVL: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } if (!okc) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_INSTR; } if (hi1 >= 8) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, hi1); return EXC_INSTR; } if (lo1 < 8) cval += get_reg_val(s->r, lo1); val = get_reg_val(s->r, hi1); if (!set_word_val(s->m, cval, val)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid data address 0x%x\n", s->pc, cval); return EXC_ADDR; } s->pc = ftpc; break; case I_MRMOVL: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } if (!okc) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction addres\n", s->pc); return EXC_INSTR; } if (hi1 >= 8) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, hi1); return EXC_INSTR; } if (lo1 < 8) cval += get_reg_val(s->r, lo1); if (!get_word_val(s->m, cval, &val)) return EXC_ADDR; set_reg_val(s->r, hi1, val); s->pc = ftpc; break; case I_ALU: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } argA = get_reg_val(s->r, hi1); argB = get_reg_val(s->r, lo1); val = compute_alu(lo0, argA, argB); set_reg_val(s->r, lo1, val); s->cc = compute_cc(lo0, argA, argB); s->pc = ftpc; break; case I_JMP: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } if (!okc) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } if (take_branch(s->cc, lo0)) s->pc = cval; else s->pc = ftpc; break; case I_CALL: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } if (!okc) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } val = get_reg_val(s->r, REG_ESP) - 4; set_reg_val(s->r, REG_ESP, val); if (!set_word_val(s->m, val, ftpc)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid stack address 0x%x\n", s->pc, val); return EXC_ADDR; } s->pc = cval; break; case I_RET: /* Return Instruction. Pop address from stack */ dval = get_reg_val(s->r, REG_ESP); if (!get_word_val(s->m, dval, &val)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid stack address 0x%x\n", s->pc, dval); return EXC_ADDR; } set_reg_val(s->r, REG_ESP, dval + 4); s->pc = val; break; case I_PUSHL: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } if (hi1 >= 8) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, hi1); return EXC_INSTR; } val = get_reg_val(s->r, hi1); dval = get_reg_val(s->r, REG_ESP) - 4; set_reg_val(s->r, REG_ESP, dval); if (!set_word_val(s->m, dval, val)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid stack address 0x%x\n", s->pc, dval); return EXC_ADDR; } s->pc = ftpc; break; case I_POPL: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } if (hi1 >= 8) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, hi1); return EXC_INSTR; } dval = get_reg_val(s->r, REG_ESP); set_reg_val(s->r, REG_ESP, dval+4); if (!get_word_val(s->m, dval, &val)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid stack address 0x%x\n", s->pc, dval); return EXC_ADDR; } set_reg_val(s->r, hi1, val); s->pc = ftpc; break; case I_LEAVE: dval = get_reg_val(s->r, REG_EBP); set_reg_val(s->r, REG_ESP, dval+4); if (!get_word_val(s->m, dval, &val)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid stack address 0x%x\n", s->pc, dval); return EXC_ADDR; } set_reg_val(s->r, REG_EBP, val); s->pc = ftpc; break; case I_IADDL: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } if (!okc) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address", s->pc); return EXC_INSTR; } if (lo1 >= 8) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, lo1); return EXC_INSTR; } argB = get_reg_val(s->r, lo1); val = argB + cval; set_reg_val(s->r, lo1, val); s->cc = compute_cc(A_ADD, cval, argB); s->pc = ftpc; break; default: if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction %.2x\n", s->pc, byte0); return EXC_INSTR; } return EXC_NONE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -