diff --git a/MakefileInst b/MakefileInst new file mode 100644 index 0000000..0e82e6f --- /dev/null +++ b/MakefileInst @@ -0,0 +1,15 @@ +OBJS=emul_inst_exec.o emul_inst_decipher.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.c b/emul.c index 98298c4..6af6ce9 100644 --- a/emul.c +++ b/emul.c @@ -4,12 +4,5 @@ int main(void) { emul_reg_init(); - emul_open_file("test.txt", "w+"); - emul_out_file('a'); - emul_out_file('a'); - emul_out_file('a'); - emul_out_file('a'); - emul_out_file('a'); - emul_out_file('a'); - emul_close_file(); + } diff --git a/emul_inst_decipher.c b/emul_inst_decipher.c index 5b238d6..c9745a4 100644 --- a/emul_inst_decipher.c +++ b/emul_inst_decipher.c @@ -1,5 +1,6 @@ #include "emul_inst_decipher.h" #include +#include /* typedef struct { @@ -8,50 +9,120 @@ } emul_isa_t; */ -emul_isa_t isa_dict[] { - { ADD, "add" }, +#define ISA_COUNT 23 +emul_isa_t isa_dict[ISA_COUNT] = { + { ADD , "add" }, { ADDI, "addi" }, - { SUB, "sub" }, - - { SLT, "slt" }, + { 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" }, - + { SEQ , "seq" }, + { SGE , "sge" }, + { SGT , "sgt" }, + { SLE , "sle" }, + { SNE , "sne" }, + { B , "b" }, + { BEQ , "beq" }, + { BNE , "bne" }, + { J , "j" }, + { LW , "lw" }, + { SW , "sw" }, { MOVE, "move" } }; -FILE *fp; +#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() { } -void emul_inst_dec_load(char *filename) { - if ((fp = open(filename_cache, "r")) == NULL) { - fprintf(stderr, "%s is can not open", filename); +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() { - +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: @@ -59,5 +130,25 @@ // RETURN: St0 // RETURN: Ss0 // RETURN: Ss1 -int emul_inst_dec_get_operand() { +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); } diff --git a/emul_inst_decipher.h b/emul_inst_decipher.h index d34621d..b09568b 100644 --- a/emul_inst_decipher.h +++ b/emul_inst_decipher.h @@ -1,30 +1,44 @@ #ifndef EMUL_INST_DECIPHER__ -#ifndef EMUL_INST_DECIPHER__ +#define EMUL_INST_DECIPHER__ #include "emul_inst_isa.h" -#include "emul_io_file" +#include "emul_reg.h" + +#define LOAD_LINE_MAX 1024 +#define LOAD_TOKEN_MAX 32 typedef struct { - int opecode; - int string; + 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(); -void emul_inst_dec_load(char *filename); +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(); +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(); +int emul_inst_dec_get_operand(char *); + +int emul_inst_dec_get_next_operand(); #endif diff --git a/emul_inst_exec.c b/emul_inst_exec.c new file mode 100644 index 0000000..4c55829 --- /dev/null +++ b/emul_inst_exec.c @@ -0,0 +1,114 @@ +#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) { + printf("Execute: add r0[%d], r1[%d], r2[%d];\n", r0, r1, r2); +} + +void emul_inst_exec_sub(int r0, int r1, int r2) { + printf("Execute: sub r0[%d], r1[%d], r2[%d];\n", r0, r1, r2); +} +/* オペコード解読処理群 - 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: + // 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 : + // break; + //case SLTI: + // break; + //case SEQ : + // break; + //case SGE : + // break; + //case SGT : + // break; + //case SLE : + // break; + //case SNE : + // break; + //case B : + // break; + //case BEQ : + // break; + //case BNE : + // break; + //case J : + // break; + //case LW : + // break; + //case SW : + // 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関数を終わるまで呼び出せばよい + return ; +} + +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; +} diff --git a/emul_inst_exec.h b/emul_inst_exec.h new file mode 100644 index 0000000..b9acf03 --- /dev/null +++ b/emul_inst_exec.h @@ -0,0 +1,21 @@ +#ifndef EMUL_INST_EXEC__ +#define EMUL_INST_EXEC__ + +#include "emul_inst_decipher.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_isa.h b/emul_inst_isa.h index 3bd115b..ec57cb0 100644 --- a/emul_inst_isa.h +++ b/emul_inst_isa.h @@ -1,7 +1,11 @@ #ifndef EMUL_INST_ISA__ #define EMUL_INST_ISA__ -enum EMUL_ISA { +typedef enum { + // 翻訳のための擬似オペコード + OPECODE_DECODE_ERROR, + + // オペコード ADD, ADDI, AND, @@ -96,7 +100,7 @@ SYSCALL, BREAK, NOP -} +} EMUL_ISA; #endif diff --git a/emul_reg.h b/emul_reg.h index 5967c93..cdb6e59 100644 --- a/emul_reg.h +++ b/emul_reg.h @@ -1,46 +1,51 @@ #ifndef EMUL_REG__ #define EMUL_REG__ -#define Szero 0 // Zero register +typedef enum { + // 翻訳のための擬似オペランド + OPERAND_DECODE_ERROR, -#define Sat 1 // using asem + Szero, // Zero register -#define Sv0 2 // return -#define Sv1 3 + Sat, // using asem -#define Sa0 4 // argment -#define Sa1 5 -#define Sa2 6 -#define Sa3 7 + Sv0, // return + Sv1, -#define St0 8 // temp -#define St1 9 -#define St2 10 -#define St3 11 -#define St4 12 -#define St5 13 -#define St6 14 -#define St7 15 + Sa0, // argment + Sa1, + Sa2, + Sa3, -#define Ss0 16 // var -#define Ss1 17 -#define Ss2 18 -#define Ss3 19 -#define Ss4 20 -#define Ss5 21 -#define Ss6 22 -#define Ss7 23 + St0, // temp + St1, + St2, + St3, + St4, + St5, + St6, + St7, -#define Sk0 26 // kernel -#define Sk1 27 + Ss0, // var + Ss1, + Ss2, + Ss3, + Ss4, + Ss5, + Ss6, + Ss7, -#define Sgp 28 // grobal + Sk0, // kernel + Sk1, -#define Ssp 29 // stack + Sgp, // grobal -#define Sfp 30 // frame + Ssp, // stack -#define Sra 31 // return address + Sfp, // frame + + Sra // return address +} EMUL_REG; int reg[32]; diff --git a/test_asm/test.asm b/test_asm/test.asm new file mode 100644 index 0000000..d4fc288 --- /dev/null +++ b/test_asm/test.asm @@ -0,0 +1,2 @@ +add $t0 $s0 $s1 +sub $s4 $t0 $s3