コード例 #1
0
ファイル: psim.c プロジェクト: kywe665/ECEn-324
void do_ex_stage()
{
    alu_t alufun = gen_alufun();
    bool_t setcc = gen_set_cc();
    word_t alua, alub;

    alua = gen_aluA();
    alub = gen_aluB();

    e_bcond = 	take_branch(cc, id_ex_curr->ifun);
    
    ex_mem_next->takebranch = id_ex_curr->icode == I_JMP &&
	e_bcond;

    if (id_ex_curr->icode == I_JMP)
	sim_log("Execute: %s instruction, cc = %s, branch %staken\n",
		iname(HPACK(id_ex_curr->icode, id_ex_curr->ifun)),
		cc_name(cc),
		ex_mem_next->takebranch ? "" : "not ");
    
    /* Perform the ALU operation */
    ex_mem_next->vale = compute_alu(alufun, alua, alub);

    {
	byte_t instr = HPACK(id_ex_curr->icode, id_ex_curr->ifun);
	sim_log("Execute: Instruction %s\n",
		iname(instr));
    }

    if (setcc) {
	cc_in = compute_cc(alufun, alua, alub);
	sim_log("Execute: CC cc = %s\n", cc_name(cc_in));
    }

    ex_mem_next->icode = id_ex_curr->icode;
    ex_mem_next->ifun = id_ex_curr->ifun;
    ex_mem_next->vala = gen_new_M_valA();
    ex_mem_next->deste = id_ex_curr->deste;
    ex_mem_next->destm = id_ex_curr->destm;
    ex_mem_next->srca = id_ex_curr->srca;
    ex_mem_next->exception = id_ex_curr->exception;
    ex_mem_next->stage_pc = id_ex_curr->stage_pc;
}
コード例 #2
0
ファイル: psim.c プロジェクト: PiffNP/CSAPP
void do_ex_stage()
{
    alu_t alufun = gen_alufun();
    bool_t setcc = gen_set_cc();
    word_t alua, alub;

    alua = gen_aluA();
    alub = gen_aluB();

    e_bcond = 	cond_holds(cc, id_ex_curr->ifun);
    
    ex_mem_next->takebranch = e_bcond;

    if (id_ex_curr->icode == I_JMP)
      sim_log("\tExecute: instr = %s, cc = %s, branch %staken\n",
	      iname(HPACK(id_ex_curr->icode, id_ex_curr->ifun)),
	      cc_name(cc),
	      ex_mem_next->takebranch ? "" : "not ");
    
    /* Perform the ALU operation */
    word_t aluout = compute_alu(alufun, alua, alub);
    ex_mem_next->vale = aluout;
    sim_log("\tExecute: ALU: %c 0x%x 0x%x --> 0x%x\n",
	    op_name(alufun), alua, alub, aluout);

    if (setcc) {
	cc_in = compute_cc(alufun, alua, alub);
	sim_log("\tExecute: New cc = %s\n", cc_name(cc_in));
    }

    ex_mem_next->icode = id_ex_curr->icode;
    ex_mem_next->ifun = id_ex_curr->ifun;
    ex_mem_next->vala = gen_e_valA();
    ex_mem_next->deste = gen_e_dstE();
    ex_mem_next->destm = id_ex_curr->destm;
    ex_mem_next->srca = id_ex_curr->srca;
    ex_mem_next->status = id_ex_curr->status;
    ex_mem_next->stage_pc = id_ex_curr->stage_pc;

}
コード例 #3
0
ファイル: y86sim.c プロジェクト: tjgykhulj/ICS_Lab
/* 
 * nexti: execute single instruction and return status.
 * args
 *     sim: the y86 image with PC, register and memory
 *
 * return
 *     STAT_AOK: continue
 *     STAT_HLT: halt
 *     STAT_ADR: invalid instruction address, data address, stack address, ...
 *     STAT_INS: invalid instruction, register id, ...
 */
stat_t nexti(y86sim_t *sim)
{
    byte_t codefun = 0;
    itype_t icode;
    alu_t ifun;
    long_t valP = sim->pc;

    /* get code and function (1 byte) */
    if (!get_byte_val(sim->m, valP, &codefun)) {
        err_print("PC = 0x%x, Invalid instruction address", sim->pc);
        return STAT_ADR;
    }
    icode = GET_ICODE(codefun);
    ifun = GET_FUN(codefun);
    valP++;

    /* get registers if needed (1 byte) */

    byte_t  byte;
    long_t  valA, valB, valC, val;
    regid_t  regA, regB;

    if ((icode>1 && icode<7) || icode==I_PUSHL || icode==I_POPL)
    {
	if (!get_byte_val(sim->m, valP, &byte)) {
	  err_print("PC = 0x%x, Invalid data address 0x%x", sim->pc, valC);
	  return STAT_ADR;
	}
	valP++;
	regA = HIGH(byte);
	regB = LOW(byte);
    }

    /* get immediate if needed (4 bytes) */
    if (icode>=3 && icode<=8 && icode!=I_ALU) {
	if (!get_long_val(sim->m, valP, &valC)) {
	  err_print("PC = 0x%x, Invalid data address 0x%x", sim->pc, valC);
	  return STAT_ADR;
	}
	valP+=4;
    }

    /* execute the instruction */
    switch (icode) {
      case I_HALT: /* 0:0 */
        return STAT_HLT;
        break;
      case I_NOP: /* 1:0 */
        sim->pc = valP;
        break;

      case I_RRMOVL:
	sim->pc = valP;
	if (!cond_doit(sim->cc,ifun)) 
	    break;
	val = get_reg_val(sim->r, regA);
	set_reg_val(sim->r, regB, val);
	break;
	/* 2:x regA:regB */
      case I_IRMOVL:
	set_reg_val(sim->r, regB, valC);
	sim->pc = valP;
	break;
	/* 3:0 F:regB imm */
      case I_RMMOVL:
	valC += get_reg_val(sim->r, regB);
	val = get_reg_val(sim->r, regA);
	set_long_val(sim->m, valC, val);
	sim->pc = valP;
	break;
	/* 4:0 regA:regB imm */
      case I_MRMOVL:
	valC += get_reg_val(sim->r, regB);
	if (!get_long_val(sim->m, valC, &val)) {
	  err_print("PC = 0x%x, Invalid data address 0x%x", sim->pc, valC);
	  return STAT_ADR;
	}
	set_reg_val(sim->r, regA, val);
	sim->pc = valP;
	break;
	/* 5:0 regB:regA imm */
      case I_ALU:
	valA = get_reg_val(sim->r,regA);
	valB = get_reg_val(sim->r,regB);
	val = compute_alu(ifun, valA, valB);
	set_reg_val(sim->r, regB, val);
	sim->cc = compute_cc(ifun, valA, valB, val);
	sim->pc = valP;
	break;
	/* 6:x regA:regB */
      case I_JMP:
	sim->pc = (cond_doit(sim->cc,ifun))?valC:valP;
	break;
	/* 7:x imm */
      case I_CALL:
	val = get_reg_val(sim->r, REG_ESP) - 4;
	set_reg_val(sim->r, REG_ESP, val);
	if (!set_long_val(sim->m, val, valP)) {
	  err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, val);
	  return STAT_ADR;
	}
	sim->pc = valC;
	break;
	/* 8:x imm */
      case I_RET: 
	valA = get_reg_val(sim->r, REG_ESP);
	if (!get_long_val(sim->m, valA, &valB)) {
	  err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, valA);
	  return STAT_ADR;
	}
	set_reg_val(sim->r, REG_ESP, valA+4);
	sim->pc = valB;
	break;
	/* 9:0 */
      case I_PUSHL:
	valA = get_reg_val(sim->r, regA);
	val = get_reg_val(sim->r, REG_ESP) - 4;
	set_reg_val(sim->r, REG_ESP, val);
	if (!set_long_val(sim->m, val, valA)) {
	  err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, val);
	  return STAT_ADR;
	}
	sim->pc = valP;
	break;
	/* A:0 regA:F */
      case I_POPL: 
	valA = get_reg_val(sim->r, REG_ESP);
	set_reg_val(sim->r, REG_ESP, valA+4);
	if (!get_long_val(sim->m, valA, &valB)) {
	  err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, valA);
	  return STAT_ADR;
	}
	set_reg_val(sim->r, regA, valB);
	sim->pc = valP;
	break;
	/* B:0 regA:F */
      default:
        err_print("PC = 0x%x, Invalid instruction %.2x", sim->pc, codefun);
        return STAT_INS;
    }
    
    return STAT_AOK;
}
コード例 #4
0
ファイル: cc.cpp プロジェクト: BB90/CommunityDetectionCodes
int cclu(deque<set<int>> &en, const deque<deque<int>> &member_list,
         const deque<deque<int>> &member_matrix, double ca) {
    double cc0 = compute_cc(en);
    cout << "Average Clustering coefficient... " << cc0 << " trying to reach " << ca << endl;
    deque<double> ccs;
    for (int i = 0; i < en.size(); i++)
        ccs.push_back(compute_cc(en, i));
    double min_relative_inc = 1e-6;
    //int number_of_triangles=compute_tot_t(en);
    int num_p = min(int(en.size() / 10), 5);
    while (cc0 < ca) {
        double ccold = cc0;
        for (int y = 0; y < num_p; y++)
            for (int Ai = 0; Ai < en.size(); Ai++) {
                // ************************************************  rewiring
                while (true) {
                    int random_node = irand(en.size() - 1);
                    int a = random_from_set(en[random_node]);
                    deque<int> not_ra;
                    for (set<int>::iterator it_est = en[random_node].begin(); it_est != en[random_node].end(); it_est++)
                        if (en[a].find(*it_est) == en[a].end() && *it_est != a)
                            not_ra.push_back(*it_est);
                    if (not_ra.size() == 0)
                        break;
                    int random_mate = not_ra[irand(not_ra.size() - 1)];
                    bool b1 = they_are_mate(a, random_mate, member_list);
                    deque<int> out_nodes;
                    for (set<int>::iterator it_est = en[a].begin(); it_est != en[a].end(); it_est++)
                        if (they_are_mate(a, *it_est, member_list) == b1)
                            out_nodes.push_back(*it_est);
                    if (out_nodes.size() == 0)
                        break;
                    int t1;
                    int old_node = choose_the_least(en, out_nodes, a, t1);
                    //int old_node=out_nodes[irand(out_nodes.size()-1)];
                    deque<int> not_common;
                    for (set<int>::iterator it_est = en[random_mate].begin(); it_est != en[random_mate].end(); it_est++)
                        if ((old_node != (*it_est)) && (en[old_node].find(*it_est) == en[old_node].end()))
                            if (they_are_mate(*it_est, random_mate, member_list) == b1 &&
                                they_are_mate(*it_est, old_node, member_list) == b1)
                                not_common.push_back(*it_est);
                    if (not_common.size() == 0)
                        break;
                    //int node_h=not_common[irand(not_common.size()-1)];
                    int t2;
                    int node_h = choose_the_least(en, not_common, random_mate, t2);
                    //double c1=common_neighbors(a, old_node, en) + common_neighbors(random_mate, node_h, en);
                    double c1 = t1 + t2;
                    en[a].erase(old_node);
                    en[a].insert(random_mate);
                    en[old_node].erase(a);
                    en[old_node].insert(node_h);
                    en[random_mate].erase(node_h);
                    en[random_mate].insert(a);
                    en[node_h].erase(random_mate);
                    en[node_h].insert(old_node);
                    double c2 = common_neighbors(a, random_mate, en) + common_neighbors(old_node, node_h, en);
                    if (c1 > c2) {
                        en[a].insert(old_node);
                        en[a].erase(random_mate);
                        en[old_node].insert(a);
                        en[old_node].erase(node_h);
                        en[random_mate].insert(node_h);
                        en[random_mate].erase(a);
                        en[node_h].insert(random_mate);
                        en[node_h].erase(old_node);
                    }
                    break;
                }
                // ************************************************  rewiring
            }
        cc0 = compute_cc(en);
        if (cc0 - ccold < min_relative_inc * cc0) {
            cout << "It seems I cannot reach the wished value. I'll stop here..." << endl;
            break;
        }
        num_p = cast_int((ca - cc0) / (cc0 - ccold)) * num_p;
        if (num_p <= 0)
            num_p = 1;
        if (num_p > 50)
            num_p = 50;
        cout << "Average Clustering coefficient... " << cc0 << " trying to reach " << ca << "\t\t expected " << num_p
             << " more step(s) " << endl;
    }
    return 0;
}
コード例 #5
0
ファイル: isa.c プロジェクト: kamneo/Archi_projet_L2
/* 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_ALUI);

    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_JXX || hi0 == I_CALL || hi0 == I_ALUI);

    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;

	#if 0
    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;
	#endif
	
    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_JXX:
	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;
    #if 0
    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;
    #endif
    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;

	#if 0
    case I_ALUI:
	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;
	#endif
	
    default:
	if (error_file)
	    fprintf(error_file,
		    "PC = 0x%x, Invalid instruction %.2x\n", s->pc, byte0);
	return EXC_INSTR;
    }
    return EXC_NONE;
}
コード例 #6
0
ファイル: ssim.c プロジェクト: kywe665/ECEn-324
/* Return resulting exception status */
static exc_t sim_step()
{
    word_t aluA;
    word_t aluB;
    word_t alufun;
    exc_t status = update_state(); /* Update state from last cycle */

    if (plusmode) {
	pc = gen_pc();
    }
    valp = pc;
    if (get_byte_val(mem, valp, &instr)) {
	icode = HI4(instr);
	ifun = LO4(instr);
    } else {
	instr = HPACK(I_NOP,0);
	icode = I_NOP;
	ifun = 0;
	status = EXC_ADDR;
	sim_log("Couldn't fetch at address 0x%x\n", valp);
    }
    valp++;
    if (gen_need_regids()) {
	byte_t regids;
	if (get_byte_val(mem, valp, &regids)) {
	    ra = GET_RA(regids);
	    rb = GET_RB(regids);
	} else {
	    ra = REG_NONE;
	    rb = REG_NONE;
	    status = EXC_ADDR;
	    sim_log("Couldn't fetch at address 0x%x\n", valp);
	}
	valp++;
    } else {
	ra = REG_NONE;
	rb = REG_NONE;
    }

    if (gen_need_valC()) {
	if (get_word_val(mem, valp, &valc)) {
	} else {
	    valc = 0;
	    status = EXC_ADDR;
	    sim_log("Couldn't fetch at address 0x%x\n", valp);
	}
	valp+=4;
    } else {
	valc = 0;
    }

    if (status == EXC_NONE && !gen_instr_valid()) {
	status = EXC_INSTR;
    }

    sim_log("IF: Fetched %s at 0x%x.  ra=%s, rb=%s, valC = 0x%x\n",
	    iname(HPACK(icode,ifun)), pc, reg_name(ra), reg_name(rb), valc);

    if (status == EXC_NONE && icode == I_HALT) {
	status = EXC_HALT;
    }
    
    srcA = gen_srcA();
    if (srcA != REG_NONE) {
	vala = get_reg_val(reg, srcA);
    } else {
	vala = 0;
    }
    
    srcB = gen_srcB();
    if (srcB != REG_NONE) {
	valb = get_reg_val(reg, srcB);
    } else {
	valb = 0;
    }

    destE = gen_dstE();
    destM = gen_dstM();

    aluA = gen_aluA();
    aluB = gen_aluB();
    alufun = gen_alufun();
    vale = compute_alu(alufun, aluA, aluB);
    cc_in = cc;
    if (gen_set_cc())
	cc_in = compute_cc(alufun, aluA, aluB);

    bcond = (icode == I_JMP) && take_branch(cc, ifun);

    mem_addr = gen_mem_addr();
    mem_data = gen_mem_data();

    if (status == EXC_NONE && gen_mem_read()) {
	if (!get_word_val(mem, mem_addr, &valm)) {
	    sim_log("Couldn't read at address 0x%x\n", mem_addr);
	    return EXC_ADDR;
	}
    } else
	valm = 0;

    mem_write = status == EXC_NONE && gen_mem_write();

    if (plusmode) {
	prev_icode_in = icode;
	prev_ifun_in = ifun;
	prev_valc_in = valc;
	prev_valm_in = valm;
	prev_valp_in = valp;
	prev_bcond_in = bcond;
    } else {
	/* Update PC */
	pc_in = gen_new_pc();
    } 
    sim_report();
    return status;
}
コード例 #7
0
ファイル: isa.c プロジェクト: HurSungYun/ArchLab_2016spr
/* Execute single instruction.  Return status. */
stat_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 = 0;
    word_t okc = TRUE;
    word_t val, dval;
    bool_t need_regids;
    bool_t need_imm;
    word_t ftpc = s->pc;  /* Fall-through 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 STAT_ADR;
    }
    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 || hi0 == I_ISUBL);

    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 || hi0 == I_ISUBL);

    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:
	return STAT_HLT;
	break;
    case I_RRMOVL:  /* Both unconditional and conditional moves */
	if (!ok1) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return STAT_ADR;
	}
	if (!reg_valid(hi1)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n",
			s->pc, hi1);
	    return STAT_INS;
	}
	if (!reg_valid(lo1)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n",
			s->pc, lo1);
	    return STAT_INS;
	}
	val = get_reg_val(s->r, hi1);
	if (cond_holds(s->cc, lo0))
	  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 STAT_ADR;
	}
	if (!okc) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address",
			s->pc);
	    return STAT_INS;
	}
	if (!reg_valid(lo1)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n",
			s->pc, lo1);
	    return STAT_INS;
	}
	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 STAT_ADR;
	}
	if (!okc) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return STAT_INS;
	}
	if (!reg_valid(hi1)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n",
			s->pc, hi1);
	    return STAT_INS;
	}
	if (reg_valid(lo1)) 
	    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 STAT_ADR;
	}
	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 STAT_ADR;
	}
	if (!okc) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction addres\n", s->pc);
	    return STAT_INS;
	}
	if (!reg_valid(hi1)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n",
			s->pc, hi1);
	    return STAT_INS;
	}
	if (reg_valid(lo1)) 
	    cval += get_reg_val(s->r, lo1);
	if (!get_word_val(s->m, cval, &val))
	    return STAT_ADR;
	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 STAT_ADR;
	}
	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 STAT_ADR;
	}
	if (!okc) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return STAT_ADR;
	}
	if (cond_holds(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 STAT_ADR;
	}
	if (!okc) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return STAT_ADR;
	}
	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 STAT_ADR;
	}
	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 STAT_ADR;
	}
	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 STAT_ADR;
	}
	if (!reg_valid(hi1)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, hi1);
	    return STAT_INS;
	}
	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 STAT_ADR;
	}
	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 STAT_ADR;
	}
	if (!reg_valid(hi1)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, hi1);
	    return STAT_INS;
	}
	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 STAT_ADR;
	}
	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 STAT_ADR;
	}
	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 STAT_ADR;
	}
	if (!okc) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address",
			s->pc);
	    return STAT_INS;
	}
	if (!reg_valid(lo1)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n",
			s->pc, lo1);
	    return STAT_INS;
	}
	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;
     case I_ISUBL:
	if (!ok1) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address\n", s->pc);
	    return STAT_ADR;
	}
	if (!okc) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid instruction address",
			s->pc);
	    return STAT_INS;
	}
	if (!reg_valid(lo1)) {
	    if (error_file)
		fprintf(error_file,
			"PC = 0x%x, Invalid register ID 0x%.1x\n",
			s->pc, lo1);
	    return STAT_INS;
	}
	argB = get_reg_val(s->r, lo1);
	val = argB - cval;
	set_reg_val(s->r, lo1, val);
	s->cc = compute_cc(A_SUB, cval, argB);
	s->pc = ftpc;
	break;
    default:
	if (error_file)
	    fprintf(error_file,
		    "PC = 0x%x, Invalid instruction %.2x\n", s->pc, byte0);
	return STAT_INS;
    }
    return STAT_AOK;
}
コード例 #8
0
ファイル: ssim.c プロジェクト: Azard/icslabs
/* Return resulting status */
static byte_t sim_step()
{
    word_t aluA;
    word_t aluB;
    word_t alufun;

    status = STAT_AOK;
    imem_error = dmem_error = FALSE;

    update_state(); /* Update state from last cycle */

    if (plusmode) {
	pc = gen_pc();
    }
    valp = pc;
    instr = HPACK(I_NOP, F_NONE);
    imem_error = !get_byte_val(mem, valp, &instr);
    if (imem_error) {
	sim_log("Couldn't fetch at address 0x%x\n", valp);
    }
    imem_icode = HI4(instr);
    imem_ifun = LO4(instr);
    icode = gen_icode();
    ifun  = gen_ifun();
    instr_valid = gen_instr_valid();
    valp++;
    if (gen_need_regids()) {
	byte_t regids;
	if (get_byte_val(mem, valp, &regids)) {
	    ra = GET_RA(regids);
	    rb = GET_RB(regids);
	} else {
	    ra = REG_NONE;
	    rb = REG_NONE;
	    status = STAT_ADR;
	    sim_log("Couldn't fetch at address 0x%x\n", valp);
	}
	valp++;
    } else {
	ra = REG_NONE;
	rb = REG_NONE;
    }

    if (gen_need_valC()) {
	if (get_word_val(mem, valp, &valc)) {
	} else {
	    valc = 0;
	    status = STAT_ADR;
	    sim_log("Couldn't fetch at address 0x%x\n", valp);
	}
	valp+=4;
    } else {
	valc = 0;
    }
    sim_log("IF: Fetched %s at 0x%x.  ra=%s, rb=%s, valC = 0x%x\n",
	    iname(HPACK(icode,ifun)), pc, reg_name(ra), reg_name(rb), valc);

    if (status == STAT_AOK && icode == I_HALT) {
	status = STAT_HLT;
    }
    
    srcA = gen_srcA();
    if (srcA != REG_NONE) {
	vala = get_reg_val(reg, srcA);
    } else {
	vala = 0;
    }
    
    srcB = gen_srcB();
    if (srcB != REG_NONE) {
	valb = get_reg_val(reg, srcB);
    } else {
	valb = 0;
    }

    cond = cond_holds(cc, ifun);

    destE = gen_dstE();
    destM = gen_dstM();

    aluA = gen_aluA();
    aluB = gen_aluB();
    alufun = gen_alufun();
    vale = compute_alu(alufun, aluA, aluB);
    cc_in = cc;
    if (gen_set_cc())
	cc_in = compute_cc(alufun, aluA, aluB);

    bcond =  cond && (icode == I_JMP);

    mem_addr = gen_mem_addr();
    mem_data = gen_mem_data();


    if (gen_mem_read()) {
      dmem_error = dmem_error || !get_word_val(mem, mem_addr, &valm);
      if (dmem_error) {
	sim_log("Couldn't read at address 0x%x\n", mem_addr);
      }
    } else
      valm = 0;

    mem_write = gen_mem_write();
    if (mem_write) {
      /* Do a test read of the data memory to make sure address is OK */
      word_t junk;
      dmem_error = dmem_error || !get_word_val(mem, mem_addr, &junk);
    }

    status = gen_Stat();

    if (plusmode) {
	prev_icode_in = icode;
	prev_ifun_in = ifun;
	prev_valc_in = valc;
	prev_valm_in = valm;
	prev_valp_in = valp;
	prev_bcond_in = bcond;
    } else {
	/* Update PC */
	pc_in = gen_new_pc();
    } 
    sim_report();
    return status;
}
コード例 #9
0
ファイル: y86sim.c プロジェクト: Azard/icslabs
/* 
 * nexti: execute single instruction and return status.
 * args
 *     sim: the y86 image with PC, register and memory
 *
 * return
 *     STAT_AOK: continue
 *     STAT_HLT: halt
 *     STAT_ADR: invalid instruction address
 *     STAT_INS: invalid instruction, register id, data address, stack address, ...
 */
stat_t nexti(y86sim_t *sim)
{
    byte_t codefun = 0;
    itype_t icode;
    alu_t ifun;
    long_t next_pc = sim->pc;
	regid_t rA = REG_NONE;
	regid_t rB = REG_NONE;
	long_t im_value = 0;

    /* get code and function (1 byte) */
    if (!get_byte_val(sim->m, next_pc, &codefun)) {
        err_print("PC = 0x%x, Invalid instruction address", sim->pc);
        return STAT_ADR;
    }
    icode = GET_ICODE(codefun);
    ifun = GET_FUN(codefun);
    next_pc++;

    /* get registers if needed (1 byte) */
	byte_t reg = 0;
	switch (icode)
	{
		case I_RRMOVL:
		case I_IRMOVL:
		case I_RMMOVL:
		case I_MRMOVL:
		case I_ALU:
		case I_PUSHL:
		case I_POPL:
			if(!get_byte_val(sim->m, next_pc, &reg)) {
				err_print("PC = 0x%x, Invalid instruction address", sim->pc);
				return STAT_ADR;
			}
			rA = GET_REGA(reg);
			rB = GET_REGB(reg);
			next_pc++;

		case I_HALT:case I_NOP:case I_JMP:case I_CALL:case I_RET:default:
			break;
	}

    /* get immediate if needed (4 bytes) */
	switch(icode)
	{
		case I_IRMOVL:
		case I_RMMOVL:
		case I_MRMOVL:
		case I_JMP:
		case I_CALL:
			if(!get_long_val(sim->m, next_pc, &im_value)) {
				err_print("PC = 0x%x, Invalid instruction address", sim->pc);				return STAT_ADR;
			}
			next_pc += 4;

		case I_HALT:case I_NOP:case I_RRMOVL:case I_ALU:
		case I_RET:case I_PUSHL:case I_POPL:default:
			break;	
	}

    /* execute the instruction */
    switch (icode) {
      case I_HALT: /* 0:0 */
        return STAT_HLT;
        break;
      case I_NOP: /* 1:0 */
        sim->pc = next_pc;
        break;

      case I_RRMOVL:/* 2:x regA:regB */
		{
			long_t rr_temp = get_reg_val(sim->r, rA);
			if (cond_doit(sim->cc, ifun))	
				set_reg_val(sim->r, rB, rr_temp);
			sim->pc = next_pc;	
			break;
		}

      case I_IRMOVL: /* 3:0 F:regB imm */
		{
			set_reg_val(sim->r, rB, im_value);
			sim->pc = next_pc;
			break;
		}

      case I_RMMOVL: /* 4:0 regA:regB imm */
		{
			long_t rm_temp_rA = get_reg_val(sim->r, rA);
			long_t rm_temp_rB = get_reg_val(sim->r, rB);
			set_long_val(sim->m, im_value+rm_temp_rB, rm_temp_rA);
			sim->pc = next_pc;
			break;
		}

      case I_MRMOVL: /* 5:0 regB:regA imm */
		{ 
			long_t mr_temp_rB = get_reg_val(sim->r, rB);
			long_t temp_val = 0;
			if(!get_long_val(sim->m, im_value+mr_temp_rB, &temp_val))
			{
				err_print("PC = 0x%x, Invalid data address 0x%x", sim->pc, im_value+mr_temp_rB);
				return STAT_ADR;
			}
			set_reg_val(sim->r, rA, temp_val);
			sim->pc = next_pc;
			break;
		}

	  case I_ALU: /* 6:x regA:regB */
		{
			long_t rA_val = get_reg_val(sim->r, rA);
			long_t rB_val = get_reg_val(sim->r, rB);
			long_t alu_result = 0;
			switch (ifun)
			{
				case A_ADD:case A_SUB:case A_AND:case A_XOR:
					alu_result = compute_alu(ifun, rA_val, rB_val);
					set_reg_val(sim->r, rB, alu_result);
					break;
				case A_NONE:default:
					return STAT_INS;
			}
			sim->cc = compute_cc(ifun, rA_val, rB_val, alu_result);
			sim->pc = next_pc;
			break;
		}

      case I_JMP: /* 7:x imm */
		{
			if (cond_doit(sim->cc, ifun))
				sim->pc = im_value;
			else
				sim->pc=next_pc;
			break;

		}
      case I_CALL: /* 8:x imm */
		{
			long_t esp = get_reg_val(sim->r, REG_ESP);
			esp -= 4;
			set_reg_val(sim->r, REG_ESP, esp);
			if (esp < 0)
			{
				err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, esp);
				return STAT_ADR;
			}
			set_long_val(sim->m, esp, next_pc);
			sim->pc = im_value;
			break;
		}

      case I_RET: /* 9:0 */
		{
			long_t esp = get_reg_val(sim->r, REG_ESP);
			long_t return_value = 0;
			if(!get_long_val(sim->m, esp, &return_value))
			{
				err_print("PC = 0x%x, Invalid data address 0x%x", sim->pc, esp);
				return STAT_ADR;
			}
			esp += 4;
			set_reg_val(sim->r, REG_ESP, esp);
			if (esp < 0)
			{
				err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, esp);
				return STAT_ADR;
			}
			sim->pc = return_value;
			break;
		}

      case I_PUSHL: /* A:0 regA:F */
		{
			long_t esp = get_reg_val(sim->r, REG_ESP);
			long_t rA_value  = get_reg_val(sim->r, rA);
			esp -= 4;
			set_reg_val(sim->r, REG_ESP, esp);
			if (esp < 0)
			{
				err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, esp);
				return STAT_ADR;
			}
			set_long_val(sim->m, esp, rA_value);
			sim->pc = next_pc;
			break;
		}

      case I_POPL: /* B:0 regA:F */
		{
			long_t esp = get_reg_val(sim->r, REG_ESP);
			long_t temp_value = 0;
			if(!get_long_val(sim->m, esp, &temp_value))
			{
				err_print("PC = 0x%x, Invalid instruction address", esp);
				return STAT_ADR;
			}
			esp += 4;
			set_reg_val(sim->r, REG_ESP, esp);
			if (esp < 0)
			{
				err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, esp);
				return STAT_ADR;
			}
			set_reg_val(sim->r, rA, temp_value);
			sim->pc = next_pc;
			break;
		}
		
		return STAT_INS; /* unsupported now, replace it with your implementation */
		break;
	  default:
        err_print("PC = 0x%x, Invalid instruction %.2x", sim->pc, codefun);
        return STAT_INS;
    }
    
    return STAT_AOK;
}
コード例 #10
0
/* 
 * nexti: execute single instruction and return status.
 * args
 *     sim: the y64 image with PC, register and memory
 *
 * return
 *     STAT_AOK: continue
 *     STAT_HLT: halt
 *     STAT_ADR: invalid instruction address
 *     STAT_INS: invalid instruction, register id, data address, stack address, ...
 */
stat_t nexti(y64sim_t *sim)
{
    byte_t codefun = 0; /* 1 byte */
    itype_t icode;
    alu_t ifun;
    long_t next_pc = sim->pc;
    
    /* get code and function (1 byte) */
    if (!get_byte_val(sim->m, next_pc, &codefun)) {
        err_print("PC = 0x%lx, Invalid instruction address", sim->pc);
        return STAT_ADR;
    }
    icode = GET_ICODE(codefun);
    ifun = GET_FUN(codefun);
    next_pc++;
	
    /* get registers if needed (1 byte) */
  	byte_t rArB = 0; 
	regid_t rA = REG_ERR, rB = REG_ERR;
	if((icode == I_RRMOVQ) || (icode == I_ALU) || (icode == I_RMMOVQ) || 
					(icode == I_PUSHQ) || (icode == I_POPQ) ||
					(icode == I_IRMOVQ) || (icode == I_MRMOVQ) ){
   		get_byte_val(sim->m, next_pc, &rArB);
		rA = GET_REGA(rArB);
		rB = GET_REGB(rArB);
		next_pc++;
	}

    /* get immediate if needed (8 bytes) */
    long_t valC;
	if(icode == I_IRMOVQ || icode == I_RMMOVQ ||icode == I_MRMOVQ ||
				   	icode == I_JMP || icode == I_CALL){
		get_long_val(sim->m,next_pc,&valC);
		next_pc += 8;
	}

    /* execute the instruction*/
    long_t valA,valB,valE,valM;
   	switch (icode) {
      case I_HALT: /* 0:0 */
	    return STAT_HLT;
	    break;
      case I_NOP: /* 1:0 */
    	sim->pc = next_pc;
    	break;
      case I_RRMOVQ:  /* 2:x regA:regB */
	  	if(!NORM_REG(rA) || !NORM_REG(rB)){
			err_print("PC = 0x%lx, Invalid register id %.2x", sim->pc, rArB);
        	return STAT_INS;
		}
			
	  	valA = get_reg_val(sim->r,rA);
		
		valE = valA + 0;
		if(cond_doit(sim->cc, ifun))
			set_reg_val(sim->r, rB, valE);
		sim->pc = next_pc;
		break;
      case I_IRMOVQ: /* 3:0 F:regB imm */
		
		if(!NORM_REG(rB) || !NONE_REG(rA)){
			err_print("PC = 0x%lx, Invalid register id %.2x", sim->pc, rArB);
        	return STAT_INS;
		}
		valA = get_reg_val(sim->r, rA);
		valB = get_reg_val(sim->r, rB);
		valE = 0 + valC;
		set_reg_val(sim->r, rB, valE);
		sim->pc = next_pc;
		break;
      case I_RMMOVQ: /* 4:0 regA:regB imm */
		
		if(!NORM_REG(rA) || !NORM_REG(rB)){
			err_print("PC = 0x%lx, Invalid register id %.2x", sim->pc, rArB);
        	return STAT_INS;
		}
		valA = get_reg_val(sim->r, rA);
		valB = get_reg_val(sim->r, rB);
		valE = valB + valC;
		if(!set_long_val(sim->m, valE, valA)){
			err_print("PC = 0x%lx, Invalid data address 0x%.8lx", sim->pc, valE);
			return STAT_ADR;
		}
		sim->pc = next_pc;
		break;
      case I_MRMOVQ: /* 5:0 regB:regA imm */
		
		if(!NORM_REG(rA) || !NORM_REG(rB)){
			err_print("PC = 0x%lx, Invalid register id %.2x", sim->pc, rArB);
        	return STAT_INS;
		}
		
		valA = get_reg_val(sim->r, rA);
		valB = get_reg_val(sim->r, rB);
		valE = valB + valC;
		if(!get_long_val(sim->m, valE, &valM)){
			err_print("PC = 0x%lx, Invalid data address 0x%.8lx", sim->pc, valE);
			return STAT_ADR;
		}
		set_reg_val(sim->r, rA, valM);
		sim->pc = next_pc;
		break;
      case I_ALU: /* 6:x regA:regB */
		if(!NORM_REG(rA) || !NORM_REG(rB)){
			err_print("PC = 0x%lx, Invalid register id %.2x", sim->pc, rArB);
        	return STAT_INS;
		}
		valA = get_reg_val(sim->r, rA);
		valB = get_reg_val(sim->r, rB);	
		valE = compute_alu(ifun, valA, valB);
		sim->cc = compute_cc(ifun, valA, valB, valE);
		set_reg_val(sim->r, rB, valE);
		sim->pc = next_pc;
		break;
      case I_JMP: /* 7:x imm */
		if(ifun > 6){
			err_print("PC = 0x%lx, Invalid instruction %.2x", sim->pc, codefun);
    		return STAT_INS;
		}
		sim->pc = cond_doit(sim->cc,ifun)? valC : next_pc;
		break;
      case I_CALL: /* 8:x imm */
		valB = get_reg_val(sim->r, REG_RSP); 
		valE = valB + (-8);
		
		set_reg_val(sim->r, REG_RSP, valE);
		if(!set_long_val(sim->m, valE, next_pc)){
			err_print("PC = 0x%lx, Invalid stack address 0x%.8lx", sim->pc, valE);
    		return STAT_ADR;	
		}
		sim->pc = valC;
		break;
      case I_RET: /* 9:0 */
		valA = get_reg_val(sim->r, REG_RSP);
		valB = valA;
		
		valE = valB + 8;

		get_long_val(sim->m, valA, &valM);
		set_reg_val(sim->r, REG_RSP, valE);
		sim->pc = valM;
		break;
      case I_PUSHQ: /* A:0 regA:F */
		if(!NORM_REG(rA)){
			err_print("PC = 0x%lx, Invalid register id %.2x", sim->pc, rArB);
    		return STAT_INS;
		}
		valA = get_reg_val(sim->r, rA);
		valB = get_reg_val(sim->r, REG_RSP);
		
		valE = valB + (-8);
		
		set_reg_val(sim->r, REG_RSP, valE);
		if(!set_long_val(sim->m, valE, valA)){
			err_print("PC = 0x%lx, Invalid stack address 0x%.8lx", sim->pc, valE);
    		return STAT_ADR;
		}
		sim->pc = next_pc;
		break;
      case I_POPQ: /* B:0 regA:F */
		if(!NORM_REG(rA)){
			err_print("PC = 0x%lx, Invalid register id %.2x", sim->pc, rArB);
    		return STAT_INS;
		}
		valA = get_reg_val(sim->r, REG_RSP);
		valB = valA;

		valE = valB + 8;
		
		get_long_val(sim->m, valA, &valM);
		set_reg_val(sim->r, REG_RSP, valE);
		set_reg_val(sim->r, rA, valM);
		sim->pc = next_pc;
		break;

    //	return STAT_INS; /* unsupported now, replace it with your implementation */
      default:
    	err_print("PC = 0x%lx, Invalid instruction %.2x", sim->pc, codefun);
    	return STAT_INS;
    }
    
    return STAT_AOK;
}