Newer
Older
emul / emul_inst_exec.c
#include "emul_inst_exec.h"
#include "emul_io_std.h"

int emul_inst_exec_loadfile(char *filename) {
    return emul_inst_dec_load(filename);
}

void emul_inst_exec_closefile() {
    emul_inst_dec_close();
}

/* オペコード解読処理群 - START */
void emul_inst_exec_add(int r0, int r1, int r2) {
    emul_reg_set(r0, emul_reg_get(r1) + emul_reg_get(r2));
    emul_out_std_debug("Execute: add r0[%d], r1[%d], r2[%d];\n", r0, r1, r2);
}

void emul_inst_exec_addi(int r0, int r1, int im) {
    emul_reg_set(r0, emul_reg_get(r1) + im);
    emul_out_std_debug("Execute: addi r0[%d], r1[%d], im[%d];\n", r0, r1, im);
}

void emul_inst_exec_sub(int r0, int r1, int r2) {
    emul_reg_set(r0, emul_reg_get(r1) - emul_reg_get(r2));
    emul_out_std_debug("Execute: sub r0[%d], r1[%d], r2[%d];\n", r0, r1, r2);
}

void emul_inst_exec_slt(int r0, int r1, int r2) {
    if (emul_reg_get(r1) < emul_reg_get(r2)) emul_reg_set(r0, 1);
    else emul_reg_set(r0, 0);
    emul_out_std_debug("Execute: slt r0[%d], r1[%d], r2[%d];\n", r0, r1, r2);
}

void emul_inst_exec_slti(int r0, int r1, int im) {
    if (emul_reg_get(r1) < im) emul_reg_set(r0, 1);
    else emul_reg_set(r0, 0);
    emul_out_std_debug("Execute: slti r0[%d], r1[%d], im[%d];\n", r0, r1, im);
}

void emul_inst_exec_seq(int r0, int r1, int r2) {
    if (emul_reg_get(r1) == emul_reg_get(r2)) emul_reg_set(r0, 1);
    else emul_reg_set(r0, 0);
    emul_out_std_debug("Execute: seq r0[%d], r1[%d], r2[%d];\n", r0, r1, r2);
}

void emul_inst_exec_sge(int r0, int r1, int r2) {
    if (emul_reg_get(r1) >= emul_reg_get(r2)) emul_reg_set(r0, 1);
    else emul_reg_set(r0, 0);
    emul_out_std_debug("Execute: sge r0[%d], r1[%d], r2[%d];\n", r0, r1, r2);
}

void emul_inst_exec_sgt(int r0, int r1, int r2) {
    if (emul_reg_get(r1) >= emul_reg_get(r2)) emul_reg_set(r0, 1);
    else emul_reg_set(r0, 0);
    emul_out_std_debug("Execute: sgt r0[%d], r1[%d], r2[%d];\n", r0, r1, r2);
}

void emul_inst_exec_sle(int r0, int r1, int r2) {
    if (emul_reg_get(r1) <= emul_reg_get(r2)) emul_reg_set(r0, 1);
    else emul_reg_set(r0, 0);
    emul_out_std_debug("Execute: sle r0[%d], r1[%d], r2[%d];\n", r0, r1, r2);
}

void emul_inst_exec_sne(int r0, int r1, int r2) {
    if (emul_reg_get(r1) != emul_reg_get(r2)) emul_reg_set(r0, 1);
    else emul_reg_set(r0, 0);
    emul_out_std_debug("Execute: sne r0[%d], r1[%d], r2[%d];\n", r0, r1, r2);
}

void emul_inst_exec_j(int target) {
    emul_reg_set(Spc, target);
    emul_out_std_debug("Execute: j target[%d];\n", target);
}

void emul_inst_exec_beq(int r0, int r1, int label) {
    if (emul_reg_get(r0) == emul_reg_get(r1))
        emul_reg_set(Spc, label);
    emul_reg_set(Spc, label);
    emul_out_std_debug("Execute: beq r0[%d] r1[%d] label[%d];\n", r0, r1, label);
}

void emul_inst_exec_bne(int r0, int r1, int label) {
    if (emul_reg_get(r0) != emul_reg_get(r1))
        emul_reg_set(Spc, label);
    emul_out_std_debug("Execute: bne r0[%d] r1[%d] label[%d];\n", r0, r1, label);
}

void emul_inst_exec_lw(int r0, int address) {
    emul_reg_set(r0, emul_mem_get_word(address));
    emul_out_std_debug("Execute: lw r0[%d] address[%d];\n", r0, address);
}

void emul_inst_exec_sw(int r0, int address) {
    emul_mem_set_word(address, emul_reg_get(r0));
    emul_out_std_debug("Execute: sw r0[%d] address[%d];\n", r0, address);
}
/* オペコード解読処理群 - END */


/* 疑似コード解読処理群 - START */

/* :DUMP
 * OUTPUT:
 *   LAST_CMD [OPTION] */
void emul_inst_exec_pseudo_dump(int r) {
    emul_out_std_debug("PseudoExec: DUMP r[%d];\n", r);
}

/* :MEMCAT <ADDRESS>
 * OUTPUT:
 *   ADDRESS = <0xVALUE(8bit)> */
void emul_inst_exec_pseudo_memcat(int address) {
    emul_out_std("0x%02X\n", emul_mem_get(address));
    emul_out_std_debug("PseudoExec: MEMCAT address[%d];\n", address);
}

/* :MEMCATW <ADDRESS>
 * OUTPUT:
 *   ADDRESS = <0xVALUE(32bit)> */
void emul_inst_exec_pseudo_memcatw(int address) {
    emul_out_std("0x%08X\n", emul_mem_get(address));
    emul_out_std_debug("PseudoExec: MEMCATW address[%d];\n", address);
}

/* :REGCAT <REGISTER>
 * OUTPUT:
 *   ADDRESS = <0xVALUE(32bit)> */
void emul_inst_exec_pseudo_regcat(int reg) {
    emul_out_std("0x%08X\n", emul_reg_get(reg));
    emul_out_std_debug("PseudoExec: REGCAT address[%03p];\n", reg);
}

/* 疑似コード解読処理群 - END */


/* Execute pseudocode
 * RETURN:
 *   seccsess: 1
 *   failed  : 0 */
int emul_inst_exec_pseudo(char token[LOAD_TOKEN_MAX]) {
    // execute pseudocode.
    EMUL_PSEUDO ps_id;

    // 疑似コードIDを取得
    ps_id = emul_inst_dec_get_pseudo(token);

    // 例外処理:疑似コードが見つからない
    if ( ps_id == PSEUDO_DECODE_ERROR ) {
        return 0;
    }

    switch( ps_id ) {
    case DUMP:
        emul_inst_exec_pseudo_dump(
	        emul_inst_dec_get_next_operand()
        );
        break;
    case MEMCAT:
        emul_inst_exec_pseudo_memcat(
	        emul_inst_dec_get_next_immediate()
        );
        break;
    case MEMCATW:
        emul_inst_exec_pseudo_memcatw(
            emul_inst_dec_get_next_immediate()
        );
        break;
    case REGCAT:
        emul_inst_exec_pseudo_regcat(
            emul_inst_dec_get_next_operand()
        );
        break;
	default:
	    emul_out_std_debug("[疑似コード]まだ実装してないので待って!\n");
    }

    return 1;
}

/* Execute Step
 * RETURN:
 *   seccsess: 1
 *   failed  : 0 */
int emul_inst_exec_step()
#define COUNT_OPERAND_MAX 3
{
    char token[LOAD_TOKEN_MAX];
    int op_id, oprs[COUNT_OPERAND_MAX];
    int ps_id;

    // トークンを取得
    if ( emul_inst_dec_get_token(token) == 0 ) {
        // 次のトークンが見つからない場合終了
        return 0;
    }
    // オペコードIDを取得
    op_id = emul_inst_dec_get_opecode(token);

    // 例外処理: オペコードが見つからない
    if ( op_id == OPECODE_DECODE_ERROR ) {
        emul_out_std_err("Non exist next operand\n");
        ps_id = emul_inst_dec_get_pseudo(token);
        // 例外処理:疑似コードが見つからない
        if ( ps_id == PSEUDO_DECODE_ERROR ) {
            emul_out_std_err("Non exist next pseudocode\n");
            return 0;
        } else {
            // 疑似コードを実行
            emul_inst_exec_pseudo(token);
            return 1;
        }
    }

    int temp_op[3];
    // オペコード実行
    switch (op_id) {
	case ADD :
	    temp_op[0] = emul_inst_dec_get_next_operand();
	    temp_op[1] = emul_inst_dec_get_next_operand();
	    temp_op[2] = emul_inst_dec_get_next_operand();
	    emul_inst_exec_add(temp_op[0], temp_op[1], temp_op[2]);
	    break;
	case ADDI:
        temp_op[0] = emul_inst_dec_get_next_operand();
        temp_op[1] = emul_inst_dec_get_next_operand();
        temp_op[2] = emul_inst_dec_get_next_immediate();
	    emul_inst_exec_addi(temp_op[0], temp_op[1], temp_op[2]);
	    break;
	case SUB :
	    temp_op[0] = emul_inst_dec_get_next_operand();
	    temp_op[1] = emul_inst_dec_get_next_operand();
	    temp_op[2] = emul_inst_dec_get_next_operand();
	    emul_inst_exec_sub(temp_op[0], temp_op[1], temp_op[2]);
	    break;
	case SLT :
	    temp_op[0] = emul_inst_dec_get_next_operand();
	    temp_op[1] = emul_inst_dec_get_next_operand();
	    temp_op[2] = emul_inst_dec_get_next_operand();
        emul_inst_exec_slt(temp_op[0], temp_op[1], temp_op[2]);
	    break;
	case SLTI:
        temp_op[0] = emul_inst_dec_get_next_operand();
        temp_op[1] = emul_inst_dec_get_next_operand();
        temp_op[2] = emul_inst_dec_get_next_immediate();
        emul_inst_exec_slti(temp_op[0], temp_op[1], temp_op[2]);
	    break;
	case SEQ :
	    temp_op[0] = emul_inst_dec_get_next_operand();
	    temp_op[1] = emul_inst_dec_get_next_operand();
	    temp_op[2] = emul_inst_dec_get_next_operand();
        emul_inst_exec_seq(temp_op[0], temp_op[1], temp_op[2]);
	    break;
    case SGE :
	    temp_op[0] = emul_inst_dec_get_next_operand();
	    temp_op[1] = emul_inst_dec_get_next_operand();
	    temp_op[2] = emul_inst_dec_get_next_operand();
        emul_inst_exec_sge(temp_op[0], temp_op[1], temp_op[2]);
	    break;
    case SGT :
	    temp_op[0] = emul_inst_dec_get_next_operand();
	    temp_op[1] = emul_inst_dec_get_next_operand();
	    temp_op[2] = emul_inst_dec_get_next_operand();
        emul_inst_exec_sgt(temp_op[0], temp_op[1], temp_op[2]);
	    break;
    case SLE :
	    temp_op[0] = emul_inst_dec_get_next_operand();
	    temp_op[1] = emul_inst_dec_get_next_operand();
	    temp_op[2] = emul_inst_dec_get_next_operand();
        emul_inst_exec_sle(temp_op[0], temp_op[1], temp_op[2]);
	    break;
    case SNE :
	    temp_op[0] = emul_inst_dec_get_next_operand();
	    temp_op[1] = emul_inst_dec_get_next_operand();
	    temp_op[2] = emul_inst_dec_get_next_operand();
        emul_inst_exec_sne(temp_op[0], temp_op[1], temp_op[2]);
	    break;
	//case B   :
	//    break;
	case BEQ :
        temp_op[0] = emul_inst_dec_get_next_operand();
        temp_op[1] = emul_inst_dec_get_next_operand();
        temp_op[2] = emul_inst_dec_get_next_immediate();
        emul_inst_exec_beq(temp_op[0], temp_op[1], temp_op[2]);
	    break;
	case BNE :
        temp_op[0] = emul_inst_dec_get_next_operand();
        temp_op[1] = emul_inst_dec_get_next_operand();
        temp_op[2] = emul_inst_dec_get_next_immediate();
        emul_inst_exec_bne(temp_op[0], temp_op[1], temp_op[2]);
	    break;
	case J   :
        temp_op[0] = emul_inst_dec_get_next_immediate();
        emul_inst_exec_j(temp_op[0]);
	    break;
	case LW  :
        temp_op[0] = emul_inst_dec_get_next_operand();
        temp_op[1] = emul_inst_dec_get_next_operand();
        emul_inst_exec_lw(temp_op[0], temp_op[1]);
	    break;
	case SW  :
        temp_op[0] = emul_inst_dec_get_next_operand();
        temp_op[1] = emul_inst_dec_get_next_operand();
        emul_inst_exec_sw(temp_op[0], temp_op[1]);
	    break;
	//case MOVE:
	    //break;
	default:
	    emul_out_std_debug("[オペコード]まだ実装してないので待って!\n");
    }
    //emul_inst_dec_get_operand(token);

    return 1;
}

/* Execute Run All
 * RETURN:
 *   seccsess: 1
 *   failed  : 0 */
int emul_inst_exec_run() {
    // step関数を終わるまで呼び出せばよい
    int exit_code;
    while ( exit_code = emul_inst_exec_step() );
    return exit_code;
}

int main(void) {
    emul_std_debug(0);
    emul_inst_exec_loadfile("test_asm/test.asm");
    emul_reg_init();
    //while ( emul_inst_exec_step() ) {
    //    puts("...Wait for step, please input key enter.");
    //    getchar();
    //}
    emul_inst_exec_run();
    emul_inst_exec_closefile();
    return 0;
}