Newer
Older
emul / emul_inst_decipher.c
#include "emul_inst_decipher.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

/*
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);
}