⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isa.c

📁 深入理解计算机系统 的lab
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 + -