diff --git a/MakefileInst b/MakefileInst index dd53dc6..8f2c074 100644 --- a/MakefileInst +++ b/MakefileInst @@ -1,4 +1,4 @@ -OBJS=emul_inst_exec.o emul_inst_decipher.o emul_reg.o emul_mem.o emul_io_std.o +OBJS=emul_inst_exec.o emul_inst_decipher.o emul_reg.o emul_mem.o emul_label.o emul_io_std.o CC=gcc PROGRAM=emulexec diff --git a/emul_inst_decipher.c b/emul_inst_decipher.c index 4908754..2e39d0e 100644 --- a/emul_inst_decipher.c +++ b/emul_inst_decipher.c @@ -3,6 +3,7 @@ #include #include #include +#include "emul_io_std.h" /* typedef struct { @@ -32,7 +33,7 @@ { MOVE, "move" } }; -#define REG_COUNT 30 +#define REG_COUNT 31 emul_reg_t reg_dict[REG_COUNT] = { { Szero, "$zero" }, // Zero register { Sat , "$at" }, // using asem @@ -63,62 +64,102 @@ { Sgp , "$gp" }, // grobal { Ssp , "$sp" }, // stack { Sfp , "$fp" }, // frame - { Sra , "$ra" } // return address + { Sra , "$ra" }, // return address + { Spc , "$pc" } // return address }; -#define PSEUDO_COUNT 4 +#define PSEUDO_COUNT 11 emul_pseudo_t pseudo_dict[REG_COUNT] = { { DUMP , ":DUMP" }, { MEMCAT , ":MEMCAT" }, { MEMCATW , ":MEMCATW" }, - { REGCAT , ":REGCAT" } + { REGCAT , ":REGCAT" }, + { LABEL , ":LABEL" }, + { RUN , ":RUN" }, + { STEP , ":STEP" }, + { INPUT , ":INPUT" }, + { OUTPUT , ":OUTPUT" }, + { CRLF , ":CRLF" }, + { EXIT , ":EXIT" } }; -static FILE *fp; +static char program[LOAD_LINE_HEIGHT_MAX][LOAD_LINE_WIDTH_MAX]; +static int program_line_current; // *_update_pc()により更新される +static int program_line_max; // *_load()を呼び出したときにのみ更新 void emul_inst_dec_init() { } -int emul_inst_dec_load(char *filename) { - if ((fp = fopen(filename, "r")) == NULL) { - fprintf(stderr, "%s is can not open\n", filename); - return 0; - } - return 1; +void emul_inst_dec_set_pc(int pc) { + program_line_current = pc; } -void emul_inst_dec_close() { + +void emul_inst_dec_update_pc() { + int pc; + // プログラムカウンタ取得 + pc = emul_reg_get(emul_inst_dec_get_operand("$pc\0")); + // 呼び出すアドレスにプログラムカウンタを設定 + emul_inst_dec_set_pc(pc); + // プログラムカウンタをインクリメント + emul_reg_set(emul_inst_dec_get_operand("$pc\0"), pc+1); +} + +int emul_inst_dec_load(const char *filename) { + FILE *fp; + int line; + emul_out_std_debug("Now opening file $s...\n", filename); + if ((fp = fopen(filename, "r")) == NULL) { + emul_out_std_err("%s is can not open\n", filename); + return 0; + } + + emul_out_std_debug("Now loading file $s...\n", filename); + program_line_current = 0; + line = 0; + while ( fgets(program[line], LOAD_LINE_WIDTH_MAX, fp) != NULL ) { + emul_out_std_debug("Now loading file line %d\n", line); + emul_out_std_debug(">>%s\n", program[line]); + line++; + } + program_line_max = line; fclose(fp); + emul_out_std_debug("Finish loading! line=%d\n", program_line_max); + return 1; } int emul_inst_dec_get_token(char *token) { - static char line[LOAD_LINE_MAX] = ""; + static char line[LOAD_LINE_WIDTH_MAX] = {0}; static char *current = line; int fShift; int i; do { - fShift = 0; - // 読み込んだ行の先頭が印字可能文字になるようにシフト - while ( *current != '\0' && isspace(*current) ) current++; + fShift = 0; + // 読み込んだ行の先頭が印字可能文字になるようにシフト + while ( *current != '\0' && isspace(*current) ) current++; - // 読み込みを開始する先頭がヌルなら新しい行を読み込む - if ( *current == '\0' ) { - // 読み込める行がない場合終了 - if ( fgets(line, LOAD_LINE_MAX, fp) == NULL) return 0; - // currentにセット - current = line; - // 読み込み下場合はシフトフラグをセット - fShift = 1; - } + // 読み込みを開始する先頭がヌルなら新しい行を読み込む + if ( *current == '\0' ) { + // 読み込める行がない場合終了 + if ( !(program_line_current < program_line_max) ) return 0; + // 次の行を読み込むためPCを更新 + emul_inst_dec_update_pc(); + // 次の行を読み込むためcurrentのポインタをリセット + current = line; + // currentにセット + strcpy(current, program[program_line_current]); + // 読み込みを行った場合はシフトフラグをセット + fShift = 1; + } } while(fShift); // 新しい行を読み込んだ場合もう一度シフトを行う // 次のスペース(もしくは'\0')が現れるまで読み込み i = 0; while ( !isspace(*current) ) { - token[i] = *current; - i++, current++; // インクリメントに注意する + token[i] = *current; + i++, current++; // インクリメントに注意する } token[i] = '\0'; return 1; @@ -127,10 +168,10 @@ // Example: // ASM: add St0, Ss0, Ss1 // RETURN: add -int emul_inst_dec_get_opecode(char *op) { +int emul_inst_dec_get_opecode(const char *token) { int i; for (i = 0; i < ISA_COUNT; i++) { - if ( strcmp(isa_dict[i].string, op) == 0 ) { + if ( strcmp(isa_dict[i].string, token) == 0 ) { return isa_dict[i].opecode; } } @@ -142,10 +183,10 @@ // RETURN: St0 // RETURN: Ss0 // RETURN: Ss1 -int emul_inst_dec_get_operand(char *op) { +int emul_inst_dec_get_operand(const char *token) { int i; for (i = 0; i < REG_COUNT; i++) { - if ( strcmp(reg_dict[i].string, op) == 0 ) { + if ( strcmp(reg_dict[i].string, token) == 0 ) { return reg_dict[i].operand; } } @@ -173,10 +214,10 @@ } // 疑似コード -int emul_inst_dec_get_pseudo(char *ps) { +int emul_inst_dec_get_pseudo(const char *token) { int i; for (i = 0; i < PSEUDO_COUNT; i++) { - if ( strcmp(pseudo_dict[i].string, ps) == 0 ) { + if ( strcmp(pseudo_dict[i].string, token) == 0 ) { return pseudo_dict[i].pseudo; } } diff --git a/emul_inst_decipher.h b/emul_inst_decipher.h index cf43bad..11b9b24 100644 --- a/emul_inst_decipher.h +++ b/emul_inst_decipher.h @@ -5,7 +5,8 @@ #include "emul_inst_pseudo.h" #include "emul_reg.h" -#define LOAD_LINE_MAX 1024 +#define LOAD_LINE_WIDTH_MAX 128 +#define LOAD_LINE_HEIGHT_MAX 1024 #define LOAD_TOKEN_MAX 32 typedef struct { @@ -25,9 +26,11 @@ void emul_inst_dec_init(); -int emul_inst_dec_load(char *filename); +int emul_inst_dec_load(const char *filename); -void emul_inst_dec_close(); +void emul_inst_dec_set_pc(int pc); + +void emul_inst_dec_update_pc(); int emul_inst_dec_get_token(char *token); @@ -39,7 +42,7 @@ * Example: * ASM: add St0, Ss0, Ss1 * RETURN: add */ -int emul_inst_dec_get_opecode(char *); +int emul_inst_dec_get_opecode(const char *token); /* Summary: * 通常トークンを*_get_opecodeに渡して結果を得るが, @@ -53,7 +56,7 @@ // RETURN: St0 // RETURN: Ss0 // RETURN: Ss1 -int emul_inst_dec_get_operand(char *); +int emul_inst_dec_get_operand(const char *token); int emul_inst_dec_get_next_operand(); @@ -61,7 +64,7 @@ int emul_inst_dec_get_next_immediate(); // 疑似コード -int emul_inst_dec_get_pseudo(char *); +int emul_inst_dec_get_pseudo(const char *token); int emul_inst_dec_get_next_pseudo(); #endif diff --git a/emul_inst_decipher.o b/emul_inst_decipher.o deleted file mode 100644 index 5b025d7..0000000 --- a/emul_inst_decipher.o +++ /dev/null Binary files differ diff --git a/emul_inst_exec.c b/emul_inst_exec.c index 7875382..eda7199 100644 --- a/emul_inst_exec.c +++ b/emul_inst_exec.c @@ -1,109 +1,135 @@ #include "emul_inst_exec.h" #include "emul_io_std.h" +#include -int emul_inst_exec_loadfile(char *filename) { +int emul_inst_exec_load(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_out_std_debug(" : add r0[%d], r1[%d], r2[%d];\n", emul_reg_get(r0), emul_reg_get(r1), emul_reg_get(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); + emul_out_std_debug("Execute: add r0[%d], r1[%d], r2[%d];\n", emul_reg_get(r0), emul_reg_get(r1), emul_reg_get(r2)); } void emul_inst_exec_addi(int r0, int r1, int im) { + emul_out_std_debug(" : addi r0[%d], r1[%d], im[%d];\n", emul_reg_get(r0), emul_reg_get(r1), 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); + emul_out_std_debug("Execute: addi r0[%d], r1[%d], im[%d];\n", emul_reg_get(r0), emul_reg_get(r1), im); } void emul_inst_exec_sub(int r0, int r1, int r2) { + emul_out_std_debug(" : sub r0[%d], r1[%d], r2[%d];\n", emul_reg_get(r0), emul_reg_get(r1), emul_reg_get(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); + emul_out_std_debug("Execute: sub r0[%d], r1[%d], r2[%d];\n", emul_reg_get(r0), emul_reg_get(r1), emul_reg_get(r2)); } void emul_inst_exec_slt(int r0, int r1, int r2) { + emul_out_std_debug(" : slt r0[%d], r1[%d], r2[%d];\n", emul_reg_get(r0), emul_reg_get(r1), emul_reg_get(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); + emul_out_std_debug("Execute: slt r0[%d], r1[%d], r2[%d];\n", emul_reg_get(r0), emul_reg_get(r1), emul_reg_get(r2)); } void emul_inst_exec_slti(int r0, int r1, int im) { + emul_out_std_debug(" : slti r0[%d], r1[%d], im[%d];\n", emul_reg_get(r0), emul_reg_get(r1), 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); + emul_out_std_debug("Execute: slti r0[%d], r1[%d], im[%d];\n", emul_reg_get(r0), emul_reg_get(r1), im); } void emul_inst_exec_seq(int r0, int r1, int r2) { + emul_out_std_debug(" : seq r0[%d], r1[%d], r2[%d];\n", emul_reg_get(r0), emul_reg_get(r1), emul_reg_get(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); + emul_out_std_debug("Execute: seq r0[%d], r1[%d], r2[%d];\n", emul_reg_get(r0), emul_reg_get(r1), emul_reg_get(r2)); } void emul_inst_exec_sge(int r0, int r1, int r2) { + emul_out_std_debug(" : sge r0[%d], r1[%d], r2[%d];\n", emul_reg_get(r0), emul_reg_get(r1), emul_reg_get(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); + emul_out_std_debug("Execute: sge r0[%d], r1[%d], r2[%d];\n", emul_reg_get(r0), emul_reg_get(r1), emul_reg_get(r2)); } void emul_inst_exec_sgt(int r0, int r1, int r2) { + emul_out_std_debug(" : sgt r0[%d], r1[%d], r2[%d];\n", emul_reg_get(r0), emul_reg_get(r1), emul_reg_get(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); + emul_out_std_debug("Execute: sgt r0[%d], r1[%d], r2[%d];\n", emul_reg_get(r0), emul_reg_get(r1), emul_reg_get(r2)); } void emul_inst_exec_sle(int r0, int r1, int r2) { + emul_out_std_debug(" : sle r0[%d], r1[%d], r2[%d];\n", emul_reg_get(r0), emul_reg_get(r1), emul_reg_get(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); + emul_out_std_debug("Execute: sle r0[%d], r1[%d], r2[%d];\n", emul_reg_get(r0), emul_reg_get(r1), emul_reg_get(r2)); } void emul_inst_exec_sne(int r0, int r1, int r2) { + emul_out_std_debug(" : sne r0[%d], r1[%d], r2[%d];\n", emul_reg_get(r0), emul_reg_get(r1), emul_reg_get(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); + emul_out_std_debug("Execute: sne r0[%d], r1[%d], r2[%d];\n", emul_reg_get(r0), emul_reg_get(r1), emul_reg_get(r2)); } void emul_inst_exec_j(int target) { + emul_out_std_debug(" : j target[%d];\n", 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_beq(int r0, int r1, char *label) { + emul_out_std_debug(" : beq r0[%d] r1[%d] label[%d];\n", emul_reg_get(r0), emul_reg_get(r1), label); + if (emul_reg_get(r0) == emul_reg_get(r1)) { + emul_reg_set( Spc, emul_label_resolve(label) ); + } + emul_out_std_debug("Execute: beq r0[%d] r1[%d] label[%d];\n", emul_reg_get(r0), emul_reg_get(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_bne(int r0, int r1, char *label) { + int getted_address = -1; + emul_out_std_debug(" : bne r0[%d] r1[%d] label[%s]>>PC(%d);\n", emul_reg_get(r0), emul_reg_get(r1), label, getted_address); + if (emul_reg_get(r0) != emul_reg_get(r1)) { + getted_address = emul_label_resolve(label); + emul_reg_set( Spc, getted_address ); + } else { + getted_address = -1; + } + emul_out_std_debug("Execute: bne r0[%d] r1[%d] label[%s]>>PC(%d);\n", emul_reg_get(r0), emul_reg_get(r1), label, getted_address); } void emul_inst_exec_lw(int r0, int address) { + emul_out_std_debug(" : lw r0[%d] address[%d];\n", emul_reg_get(r0), address); emul_reg_set(r0, emul_mem_get_word(address)); - emul_out_std_debug("Execute: lw r0[%d] address[%d];\n", r0, address); + emul_out_std_debug("Execute: lw r0[%d] address[%d];\n", emul_reg_get(r0), address); } void emul_inst_exec_sw(int r0, int address) { + emul_out_std_debug(" : sw r0[%d] address[%d];\n", emul_reg_get(r0), address); emul_mem_set_word(address, emul_reg_get(r0)); - emul_out_std_debug("Execute: sw r0[%d] address[%d];\n", r0, address); + emul_out_std_debug("Execute: sw r0[%d] address[%d];\n", emul_reg_get(r0), address); } /* オペコード解読処理群 - END */ /* 疑似コード解読処理群 - START */ -/* :DUMP +/* :DUMP