diff --git a/MakefileInst b/MakefileInst index 7ca1754..dd53dc6 100644 --- a/MakefileInst +++ b/MakefileInst @@ -1,15 +1,15 @@ -OBJS=emul_inst_exec.o emul_inst_decipher.o emul_reg.o emul_mem.o -CC=gcc -PROGRAM=emulexec - -.SUFFIXES: .c .o - -$(PROGRAM): $(OBJS) - $(CC) -o $(PROGRAM) $^ - -.c.o: - $(CC) -c $< - -.PHONY: clean -clean: - rm -f $(OBJS) $(PROGRAM) +OBJS=emul_inst_exec.o emul_inst_decipher.o emul_reg.o emul_mem.o emul_io_std.o +CC=gcc +PROGRAM=emulexec + +.SUFFIXES: .c .o + +$(PROGRAM): $(OBJS) + $(CC) -o $(PROGRAM) $^ + +.c.o: + $(CC) -c $< + +.PHONY: clean +clean: + rm -f $(OBJS) $(PROGRAM) diff --git a/emul_inst_decipher.c b/emul_inst_decipher.c index 166c873..4908754 100644 --- a/emul_inst_decipher.c +++ b/emul_inst_decipher.c @@ -1,163 +1,190 @@ -#include "emul_inst_decipher.h" -#include -#include -#include -#include - -/* -typedef struct { - int opecode; - int string; -} emul_isa_t; -*/ - -#define ISA_COUNT 23 -emul_isa_t isa_dict[ISA_COUNT] = { - { ADD , "add" }, - { ADDI, "addi" }, - { SUB , "sub" }, - { SLT , "slt" }, - { SLTI, "slti" }, - { SEQ , "seq" }, - { SGE , "sge" }, - { SGT , "sgt" }, - { SLE , "sle" }, - { SNE , "sne" }, - { B , "b" }, - { BEQ , "beq" }, - { BNE , "bne" }, - { J , "j" }, - { LW , "lw" }, - { SW , "sw" }, - { MOVE, "move" } -}; - -#define REG_COUNT 30 -emul_reg_t reg_dict[REG_COUNT] = { - { Szero, "$zero" }, // Zero register - { Sat , "$at" }, // using asem - { Sv0 , "$v0" }, // return - { Sv1 , "$v1" }, - { Sa0 , "$a0" }, // argment - { Sa1 , "$a1" }, - { Sa2 , "$a2" }, - { Sa3 , "$a3" }, - { St0 , "$t0" }, // temp - { St1 , "$t1" }, - { St2 , "$t2" }, - { St3 , "$t3" }, - { St4 , "$t4" }, - { St5 , "$t5" }, - { St6 , "$t6" }, - { St7 , "$t7" }, - { Ss0 , "$s0" }, // var - { Ss1 , "$s1" }, - { Ss2 , "$s2" }, - { Ss3 , "$s3" }, - { Ss4 , "$s4" }, - { Ss5 , "$s5" }, - { Ss6 , "$s6" }, - { Ss7 , "$s7" }, - { Sk0 , "$k0" }, // kernel - { Sk1 , "$k1" }, - { Sgp , "$gp" }, // grobal - { Ssp , "$sp" }, // stack - { Sfp , "$fp" }, // frame - { Sra , "$ra" } // return address -}; - -static FILE *fp; - -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_close() { - fclose(fp); -} - -int emul_inst_dec_get_token(char *token) { - static char line[LOAD_LINE_MAX] = ""; - static char *current = line; - int fShift; - int i; - - do { - 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; - } - } while(fShift); // 新しい行を読み込んだ場合もう一度シフトを行う - - // 次のスペース(もしくは'\0')が現れるまで読み込み - i = 0; - while ( !isspace(*current) ) { - token[i] = *current; - i++, current++; // インクリメントに注意する - } - token[i] = '\0'; - return 1; -} - -// Example: -// ASM: add St0, Ss0, Ss1 -// RETURN: add -int emul_inst_dec_get_opecode(char *op) { - int i; - for (i = 0; i < ISA_COUNT; i++) { - if ( strcmp(isa_dict[i].string, op) == 0 ) { - return isa_dict[i].opecode; - } - } - return OPECODE_DECODE_ERROR; -} - -// Example: -// ASM: add St0, Ss0, Ss1 -// RETURN: St0 -// RETURN: Ss0 -// RETURN: Ss1 -int emul_inst_dec_get_operand(char *op) { - int i; - for (i = 0; i < REG_COUNT; i++) { - if ( strcmp(reg_dict[i].string, op) == 0 ) { - return reg_dict[i].operand; - } - } - return OPERAND_DECODE_ERROR; -} - - -int emul_inst_dec_get_next_opecode() { - char token[LOAD_TOKEN_MAX]; - emul_inst_dec_get_token(token); - return emul_inst_dec_get_opecode(token); -} - -int emul_inst_dec_get_next_operand() { - char token[LOAD_TOKEN_MAX]; - emul_inst_dec_get_token(token); - return emul_inst_dec_get_operand(token); -} - -// immediate -int emul_inst_dec_get_next_immediate() { - char token[LOAD_TOKEN_MAX]; - emul_inst_dec_get_token(token); - return atoi(token); -} +#include "emul_inst_decipher.h" +#include +#include +#include +#include + +/* +typedef struct { + int opecode; + int string; +} emul_isa_t; +*/ + +#define ISA_COUNT 23 +emul_isa_t isa_dict[ISA_COUNT] = { + { ADD , "add" }, + { ADDI, "addi" }, + { SUB , "sub" }, + { SLT , "slt" }, + { SLTI, "slti" }, + { SEQ , "seq" }, + { SGE , "sge" }, + { SGT , "sgt" }, + { SLE , "sle" }, + { SNE , "sne" }, + { B , "b" }, + { BEQ , "beq" }, + { BNE , "bne" }, + { J , "j" }, + { LW , "lw" }, + { SW , "sw" }, + { MOVE, "move" } +}; + +#define REG_COUNT 30 +emul_reg_t reg_dict[REG_COUNT] = { + { Szero, "$zero" }, // Zero register + { Sat , "$at" }, // using asem + { Sv0 , "$v0" }, // return + { Sv1 , "$v1" }, + { Sa0 , "$a0" }, // argment + { Sa1 , "$a1" }, + { Sa2 , "$a2" }, + { Sa3 , "$a3" }, + { St0 , "$t0" }, // temp + { St1 , "$t1" }, + { St2 , "$t2" }, + { St3 , "$t3" }, + { St4 , "$t4" }, + { St5 , "$t5" }, + { St6 , "$t6" }, + { St7 , "$t7" }, + { Ss0 , "$s0" }, // var + { Ss1 , "$s1" }, + { Ss2 , "$s2" }, + { Ss3 , "$s3" }, + { Ss4 , "$s4" }, + { Ss5 , "$s5" }, + { Ss6 , "$s6" }, + { Ss7 , "$s7" }, + { Sk0 , "$k0" }, // kernel + { Sk1 , "$k1" }, + { Sgp , "$gp" }, // grobal + { Ssp , "$sp" }, // stack + { Sfp , "$fp" }, // frame + { Sra , "$ra" } // return address +}; + + +#define PSEUDO_COUNT 4 +emul_pseudo_t pseudo_dict[REG_COUNT] = { + { DUMP , ":DUMP" }, + { MEMCAT , ":MEMCAT" }, + { MEMCATW , ":MEMCATW" }, + { REGCAT , ":REGCAT" } +}; + + +static FILE *fp; + +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_close() { + fclose(fp); +} + +int emul_inst_dec_get_token(char *token) { + static char line[LOAD_LINE_MAX] = ""; + static char *current = line; + int fShift; + int i; + + do { + 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; + } + } while(fShift); // 新しい行を読み込んだ場合もう一度シフトを行う + + // 次のスペース(もしくは'\0')が現れるまで読み込み + i = 0; + while ( !isspace(*current) ) { + token[i] = *current; + i++, current++; // インクリメントに注意する + } + token[i] = '\0'; + return 1; +} + +// Example: +// ASM: add St0, Ss0, Ss1 +// RETURN: add +int emul_inst_dec_get_opecode(char *op) { + int i; + for (i = 0; i < ISA_COUNT; i++) { + if ( strcmp(isa_dict[i].string, op) == 0 ) { + return isa_dict[i].opecode; + } + } + return OPECODE_DECODE_ERROR; +} + +// Example: +// ASM: add St0, Ss0, Ss1 +// RETURN: St0 +// RETURN: Ss0 +// RETURN: Ss1 +int emul_inst_dec_get_operand(char *op) { + int i; + for (i = 0; i < REG_COUNT; i++) { + if ( strcmp(reg_dict[i].string, op) == 0 ) { + return reg_dict[i].operand; + } + } + return OPERAND_DECODE_ERROR; +} + + +int emul_inst_dec_get_next_opecode() { + char token[LOAD_TOKEN_MAX]; + emul_inst_dec_get_token(token); + return emul_inst_dec_get_opecode(token); +} + +int emul_inst_dec_get_next_operand() { + char token[LOAD_TOKEN_MAX]; + emul_inst_dec_get_token(token); + return emul_inst_dec_get_operand(token); +} + +// immediate +int emul_inst_dec_get_next_immediate() { + char token[LOAD_TOKEN_MAX]; + emul_inst_dec_get_token(token); + return atoi(token); +} + +// 疑似コード +int emul_inst_dec_get_pseudo(char *ps) { + int i; + for (i = 0; i < PSEUDO_COUNT; i++) { + if ( strcmp(pseudo_dict[i].string, ps) == 0 ) { + return pseudo_dict[i].pseudo; + } + } + return PSEUDO_DECODE_ERROR; +} + +int emul_inst_dec_get_next_pseudo() { + char token[LOAD_TOKEN_MAX]; + emul_inst_dec_get_token(token); + return emul_inst_dec_get_pseudo(token); +} diff --git a/emul_inst_decipher.h b/emul_inst_decipher.h index fd57f8c..cf43bad 100644 --- a/emul_inst_decipher.h +++ b/emul_inst_decipher.h @@ -1,47 +1,67 @@ -#ifndef EMUL_INST_DECIPHER__ -#define EMUL_INST_DECIPHER__ - -#include "emul_inst_isa.h" -#include "emul_reg.h" - -#define LOAD_LINE_MAX 1024 -#define LOAD_TOKEN_MAX 32 - -typedef struct { - EMUL_ISA opecode; - char string[32]; -} emul_isa_t; - -typedef struct { - EMUL_REG operand; - char string[32]; -} emul_reg_t; - -void emul_inst_dec_init(); - -int emul_inst_dec_load(char *filename); - -void emul_inst_dec_close(); - -int emul_inst_dec_get_token(char *token); - -// Example: -// ASM: add St0, Ss0, Ss1 -// RETURN: add -int emul_inst_dec_get_opecode(char *); - -int emul_inst_dec_get_next_opecode(); - -// Example: -// ASM: add St0, Ss0, Ss1 -// RETURN: St0 -// RETURN: Ss0 -// RETURN: Ss1 -int emul_inst_dec_get_operand(char *); - -int emul_inst_dec_get_next_operand(); - -// immediate -int emul_inst_dec_get_next_immediate(); - -#endif +#ifndef EMUL_INST_DECIPHER__ +#define EMUL_INST_DECIPHER__ + +#include "emul_inst_isa.h" +#include "emul_inst_pseudo.h" +#include "emul_reg.h" + +#define LOAD_LINE_MAX 1024 +#define LOAD_TOKEN_MAX 32 + +typedef struct { + EMUL_ISA opecode; + char string[32]; +} emul_isa_t; + +typedef struct { + EMUL_REG operand; + char string[32]; +} emul_reg_t; + +typedef struct { + EMUL_PSEUDO pseudo; + char string[32]; +} emul_pseudo_t; + +void emul_inst_dec_init(); + +int emul_inst_dec_load(char *filename); + +void emul_inst_dec_close(); + +int emul_inst_dec_get_token(char *token); + +/* Summary: + * 通常トークンを*_get_opecodeに渡して結果を得るが, + * これは*_get_tokenを実行しその結果から結果を得る. + * Note: + * 純粋関数 + * Example: + * ASM: add St0, Ss0, Ss1 + * RETURN: add */ +int emul_inst_dec_get_opecode(char *); + +/* Summary: + * 通常トークンを*_get_opecodeに渡して結果を得るが, + * これは*_get_tokenを実行しその結果から結果を得る. + * Note: + * 破壊的関数*/ +int emul_inst_dec_get_next_opecode(); + +// Example: +// ASM: add St0, Ss0, Ss1 +// RETURN: St0 +// RETURN: Ss0 +// RETURN: Ss1 +int emul_inst_dec_get_operand(char *); + +int emul_inst_dec_get_next_operand(); + +// immediate +int emul_inst_dec_get_next_immediate(); + +// 疑似コード +int emul_inst_dec_get_pseudo(char *); +int emul_inst_dec_get_next_pseudo(); + +#endif diff --git a/emul_inst_decipher.o b/emul_inst_decipher.o new file mode 100644 index 0000000..5b025d7 --- /dev/null +++ b/emul_inst_decipher.o Binary files differ diff --git a/emul_inst_exec.c b/emul_inst_exec.c index 28a71f9..7875382 100644 --- a/emul_inst_exec.c +++ b/emul_inst_exec.c @@ -1,253 +1,337 @@ -#include "emul_inst_exec.h" -#include - -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)); - printf("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); - printf("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)); - printf("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); - printf("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); - printf("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); - printf("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); - printf("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); - printf("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); - printf("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); - printf("Execute: sne r0[%d], r1[%d], r2[%d];\n", r0, r1, r2); -} - -void emul_inst_exec_j(int target) { - emul_reg_set(Spc, target); - printf("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); - printf("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); - printf("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)); - printf("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)); - printf("Execute: sw r0[%d] address[%d];\n", r0, address); -} -/* オペコード解読処理群 - END */ - -/* 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]; - - // トークンを取得 - emul_inst_dec_get_token(token); - // オペコードIDを取得 - op_id = emul_inst_dec_get_opecode(token); - - // 例外処理: オペコードが見つからない - if ( op_id == OPECODE_DECODE_ERROR ) { - printf("Non exist next operand\n"); - return 0; - } - - // オペコード実行 - switch (op_id) { - case ADD : - emul_inst_exec_add( - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_operand() - ); - break; - case ADDI: - emul_inst_exec_addi( - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_immediate() - ); - break; - case SUB : - emul_inst_exec_sub( - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_operand() - ); - break; - case SLT : - emul_inst_exec_slt( - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_operand() - ); - break; - case SLTI: - emul_inst_exec_slti( - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_immediate() - ); - break; - case SEQ : - emul_inst_exec_seq( - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_operand() - ); - break; - case SGE : - emul_inst_exec_sge( - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_operand() - ); - break; - case SGT : - break; - emul_inst_exec_sgt( - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_operand() - ); - case SLE : - emul_inst_exec_sle( - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_operand() - ); - break; - case SNE : - emul_inst_exec_sne( - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_operand() - ); - break; - //case B : - // break; - case BEQ : - emul_inst_exec_beq( - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_immediate() - ); - break; - case BNE : - emul_inst_exec_bne( - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_immediate() - ); - break; - case J : - emul_inst_exec_j( - emul_inst_dec_get_next_immediate() - ); - break; - case LW : - emul_inst_exec_lw( - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_operand() - ); - break; - case SW : - emul_inst_exec_sw( - emul_inst_dec_get_next_operand(), - emul_inst_dec_get_next_operand() - ); - break; - case MOVE: - break; - default: - printf("まだ実装してないので待って!\n"); - } - //emul_inst_dec_get_operand(token); - - return 1; -} - -/* Execute Run All - * RETURN: - * seccsess: 1 - * failed : 0 */ -int emul_inst_exec_run() { - // step関数を終わるまで呼び出せばよい - while (emul_inst_exec_step()); - return 0; -} - -int main(void) { - emul_inst_exec_loadfile("test.asm"); - while ( emul_inst_exec_step() ) { - puts("...Wait for step, please input key enter."); - getchar(); - } - emul_inst_exec_closefile(); - return 0; -} +#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
+ * 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
+ * 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 + * 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; +} diff --git a/emul_inst_exec.h b/emul_inst_exec.h index 1be33b2..94bf45f 100644 --- a/emul_inst_exec.h +++ b/emul_inst_exec.h @@ -1,23 +1,24 @@ -#ifndef EMUL_INST_EXEC__ -#define EMUL_INST_EXEC__ - -#include "emul_inst_decipher.h" -#include "emul_reg.h" -#include "emul_mem.h" - -int emul_inst_exec_loadfile(char*); -void emul_inst_exec_closefile(); - -/* Execute Step - * RETURN: - * seccsess: 1 - * failed : 0 */ -int emul_inst_exec_step(); - -/* Execute Run All - * RETURN: - * seccsess: 1 - * failed : 0 */ -int emul_inst_exec_run(); - -#endif +#ifndef EMUL_INST_EXEC__ +#define EMUL_INST_EXEC__ + +#include "emul_inst_decipher.h" +#include "emul_inst_pseudo.h" +#include "emul_reg.h" +#include "emul_mem.h" + +int emul_inst_exec_loadfile(char*); +void emul_inst_exec_closefile(); + +/* Execute Step + * RETURN: + * seccsess: 1 + * failed : 0 */ +int emul_inst_exec_step(); + +/* Execute Run All + * RETURN: + * seccsess: 1 + * failed : 0 */ +int emul_inst_exec_run(); + +#endif diff --git a/emul_inst_exec.o b/emul_inst_exec.o new file mode 100644 index 0000000..3b4b145 --- /dev/null +++ b/emul_inst_exec.o Binary files differ diff --git a/emul_inst_pseudo.h b/emul_inst_pseudo.h new file mode 100644 index 0000000..b2ec33f --- /dev/null +++ b/emul_inst_pseudo.h @@ -0,0 +1,29 @@ +#ifndef EMUL_INST_PSEUDO__ +#define EMUL_INST_PSEUDO__ + +typedef enum { + PSEUDO_DECODE_ERROR, + + /* :DUMP + * OUTPUT: + * LAST_CMD [OPTION] */ + DUMP, // 最後に実行された命令を表示 + + /* :MEMCAT
+ * OUTPUT: + * ADDRESS = <0xVALUE(8bit)> */ + MEMCAT, // メモリの値を取得 + + /* :MEMCATW
+ * OUTPUT: + * ADDRESS = <0xVALUE(32bit)> */ + MEMCATW, // メモリの値を取得 + + /* :REGCAT + * OUTPUT: + * ADDRESS = <0xVALUE(32bit)> */ + REGCAT // レジスタの値を取得 + +} EMUL_PSEUDO; + +#endif diff --git a/emul_io_std.c b/emul_io_std.c index 83914c1..650be81 100644 --- a/emul_io_std.c +++ b/emul_io_std.c @@ -1,7 +1,50 @@ #include "emul_io_std.h" -void emul_out_std(char c) { - putchar(c); +static int debug_level = 0; + +void emul_std_debug(int level) { + debug_level = level; +} + +//void emul_out_std(char c) { +// putchar(c); +//} +//void emul_out_std(char *str) { +// printf("%s", str); +//} +void emul_out_std(const char *format, ...) { + va_list va; + va_start(va, format); + vprintf(format, va); + va_end(va); +} +//void emul_out_std_err(char c) { +// printf("[Except] %c", c); +//} +//void emul_out_std_err(char *str) { +// printf("[Except] %s", str); +//} +void emul_out_std_err(const char *format, ...) { + if ( debug_level <= 1 ) return ; + va_list va; + va_start(va, format); + printf("[Except] "); + vprintf(format, va); + va_end(va); +} +//void emul_out_std_debug(char c) { +// printf("[Debug] %c", c); +//} +//void emul_out_std_debug(char *str) { +// printf("[Debug] %str", str); +//} +void emul_out_std_debug(const char *format, ...) { + if ( debug_level <= 0 ) return ; + va_list va; + va_start(va, format); + printf("[Debug] "); + vprintf(format, va); + va_end(va); } char emul_cin_std() { diff --git a/emul_io_std.h b/emul_io_std.h index fff1897..304a541 100644 --- a/emul_io_std.h +++ b/emul_io_std.h @@ -2,8 +2,19 @@ #define EMUL_IO_STD__ #include +#include -void emul_out_std(char c); +void emul_std_debug(int level); + +//void emul_out_std(char c); +//void emul_out_std(char *str); +void emul_out_std(const char *format, ...); +//void emul_out_std_err(char c); +//void emul_out_std_err(char *str); +void emul_out_std_err(const char *format, ...); +//void emul_out_std_debug(char c); +//void emul_out_std_debug(char *str); +void emul_out_std_debug(const char *format, ...); char emul_cin_std(); diff --git a/emul_io_std.o b/emul_io_std.o new file mode 100644 index 0000000..aa9c92e --- /dev/null +++ b/emul_io_std.o Binary files differ diff --git a/emul_label.c b/emul_label.c new file mode 100644 index 0000000..1b7cee9 --- /dev/null +++ b/emul_label.c @@ -0,0 +1,3 @@ +#include "emul_label.h" + +EMUL_LABEL label_dict[LABEL_COUNT_MAX]; diff --git a/emul_label.h b/emul_label.h new file mode 100644 index 0000000..3539580 --- /dev/null +++ b/emul_label.h @@ -0,0 +1,15 @@ +#ifndef EMUL_LABEL__ +#define EMUL_LABEL__ + +#define LABEL_COUNT_MAX 100 +#define LABEL_NAME_LENGTH_MAX 128 + +typedef struct { + char name[LABEL_NAME_LENGTH_MAX]; + int address; +} EMUL_LABEL; + +void emul_label_set(char *) { +} + +#endif diff --git a/emul_mem.c b/emul_mem.c index aa81831..9d2eaef 100644 --- a/emul_mem.c +++ b/emul_mem.c @@ -1,19 +1,30 @@ -#include "emul_mem.h" - -char mem[EMUL_MEMSIZE]; - -int emul_mem_get_word(int address) { - int word = 0; - word |= mem[address+0] << 0; - word |= mem[address+1] << 8; - word |= mem[address+2] << 16; - word |= mem[address+3] << 24; - return word; -} - -void emul_mem_set_word(int address, int word) { - mem[address+0] = (char)((word >> 0 ) & 0x000F); - mem[address+1] = (char)((word >> 8 ) & 0x000F); - mem[address+2] = (char)((word >> 16) & 0x000F); - mem[address+3] = (char)((word >> 24) & 0x000F); -} +#include "emul_mem.h" +#include + +static char mem[EMUL_MEMSIZE]; + +int emul_mem_get(int address) { + int word = 0; + word |= mem[address+0] << 0; + return word; +} + +void emul_mem_set(int address, int byte) { + mem[address+0] = (char)((byte >> 0 ) & 0x000F); +} + +int emul_mem_get_word(int address) { + int word = 0; + word |= mem[address+0] << 0; + word |= mem[address+1] << 8; + word |= mem[address+2] << 16; + word |= mem[address+3] << 24; + return word; +} + +void emul_mem_set_word(int address, int word) { + mem[address+0] = (char)((word >> 0 ) & 0x000F); + mem[address+1] = (char)((word >> 8 ) & 0x000F); + mem[address+2] = (char)((word >> 16) & 0x000F); + mem[address+3] = (char)((word >> 24) & 0x000F); +} diff --git a/emul_mem.h b/emul_mem.h index 4682844..eac1949 100644 --- a/emul_mem.h +++ b/emul_mem.h @@ -1,12 +1,17 @@ -#ifndef EMUL_MEM__ -#define EMUL_MEM__ - -#define EMUL_MEMSIZE 1024 - -void add(); - -int emul_mem_get_word(int address); - -void emul_mem_set_word(int address, int word); - -#endif +#ifndef EMUL_MEM__ +#define EMUL_MEM__ + +//#define EMUL_MEMSIZE 4294967296 +#define EMUL_MEMSIZE 1024 + +void add(); + +int emul_mem_get(int address); + +void emul_mem_set(int address, int byte); + +int emul_mem_get_word(int address); + +void emul_mem_set_word(int address, int word); + +#endif diff --git a/emul_mem.o b/emul_mem.o new file mode 100644 index 0000000..da41f9b --- /dev/null +++ b/emul_mem.o Binary files differ diff --git a/emul_reg.c b/emul_reg.c index 53e74fb..7d2cd48 100644 --- a/emul_reg.c +++ b/emul_reg.c @@ -1,15 +1,15 @@ -#include "emul_reg.h" - -int reg[32]; - -void emul_reg_init() { - reg[Szero] = 0; -} - -int emul_reg_get(EMUL_REG r) { - return reg[r]; -} - -void emul_reg_set(EMUL_REG r, int value) { - reg[r] = value; -} +#include "emul_reg.h" + +int reg[32]; + +void emul_reg_init() { + reg[Szero] = 0; +} + +int emul_reg_get(EMUL_REG r) { + return reg[r]; +} + +void emul_reg_set(EMUL_REG r, int value) { + reg[r] = value; +} diff --git a/emul_reg.h b/emul_reg.h index a671f7b..00f6096 100644 --- a/emul_reg.h +++ b/emul_reg.h @@ -1,60 +1,60 @@ -#ifndef EMUL_REG__ -#define EMUL_REG__ - -typedef enum { - // 翻訳のための擬似オペランド - OPERAND_DECODE_ERROR, - - Szero, // Zero register - - Sat, // using asem - - Sv0, // return - Sv1, - - Sa0, // argment - Sa1, - Sa2, - Sa3, - - St0, // temp - St1, - St2, - St3, - St4, - St5, - St6, - St7, - - Ss0, // var - Ss1, - Ss2, - Ss3, - Ss4, - Ss5, - Ss6, - Ss7, - - Sk0, // kernel - Sk1, - - Sgp, // grobal - - Ssp, // stack - - Sfp, // frame - - Sra, // return address - - Spc // program counter -} EMUL_REG; - - -/* initialize register - * this must be called */ -void emul_reg_init(); - -int emul_reg_get(EMUL_REG r); -void emul_reg_set(EMUL_REG r, int value); - -#endif +#ifndef EMUL_REG__ +#define EMUL_REG__ + +typedef enum { + // 翻訳のための擬似オペランド + OPERAND_DECODE_ERROR, + + Szero, // Zero register + + Sat, // using asem + + Sv0, // return + Sv1, + + Sa0, // argment + Sa1, + Sa2, + Sa3, + + St0, // temp + St1, + St2, + St3, + St4, + St5, + St6, + St7, + + Ss0, // var + Ss1, + Ss2, + Ss3, + Ss4, + Ss5, + Ss6, + Ss7, + + Sk0, // kernel + Sk1, + + Sgp, // grobal + + Ssp, // stack + + Sfp, // frame + + Sra, // return address + + Spc // program counter +} EMUL_REG; + + +/* initialize register + * this must be called */ +void emul_reg_init(); + +int emul_reg_get(EMUL_REG r); +void emul_reg_set(EMUL_REG r, int value); + +#endif diff --git a/emul_reg.o b/emul_reg.o new file mode 100644 index 0000000..9c2157d --- /dev/null +++ b/emul_reg.o Binary files differ diff --git a/emulexec.exe b/emulexec.exe new file mode 100644 index 0000000..2eac208 --- /dev/null +++ b/emulexec.exe Binary files differ diff --git a/test_asm/test.asm b/test_asm/test.asm index d4fc288..91be747 100644 --- a/test_asm/test.asm +++ b/test_asm/test.asm @@ -1,2 +1,23 @@ -add $t0 $s0 $s1 -sub $s4 $t0 $s3 +addi $s0 $zero 0 +:REGCAT $s0 + +addi $s0 $s0 1 +:REGCAT $s0 +addi $s0 $s0 1 +:REGCAT $s0 +addi $s0 $s0 1 +:REGCAT $s0 +addi $s0 $s0 1 +:REGCAT $s0 +addi $s0 $s0 1 +:REGCAT $s0 +addi $s0 $s0 1 +:REGCAT $s0 +addi $s0 $s0 1 +:REGCAT $s0 +addi $s0 $s0 1 +:REGCAT $s0 +addi $s0 $s0 1 +:REGCAT $s0 +addi $s0 $s0 1 +:REGCAT $s0 diff --git a/test_asm/test_sw_lw.asm b/test_asm/test_sw_lw.asm new file mode 100644 index 0000000..b6e49fa --- /dev/null +++ b/test_asm/test_sw_lw.asm @@ -0,0 +1,4 @@ +addi $t0 $s0 1 +sw $t0 0 +lw $t1 0 +sub $s4 $t0 $s3