Skip to content

Instantly share code, notes, and snippets.

@nullpo-head
Created November 4, 2014 18:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nullpo-head/c31f595d225d5a9c6a47 to your computer and use it in GitHub Desktop.
Save nullpo-head/c31f595d225d5a9c6a47 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
#include "fpu_c.h"
#include "print.h"
#include <signal.h>
#include <math.h>
int mypow(int n, int m){
int ret=n;
while(m-1 > 0){
ret = ret*n;
m--;
}
if(m==0) ret=1;
return(ret);
}
int two_ten(char *binary, int len, int flag){
int ret=0,i;
if(binary[0] == '1' && flag == 1){
for(i=1; i<len; i++)
if(binary[i] == '0')
ret += mypow(2,len-i-1);
ret++;
ret = -ret;
}
else
for(i=0; i<len; i++){
if(binary[i] == '1')
ret += mypow(2,len-i-1);
}
return(ret);
}
void nan_err(float f,int address)
{
if (isnan(f)||isinf(f)){
if (isnan(f))printf("NaN detected\n");
if (isinf(f))printf("Inf detected\n");
//print_reg();
debug_flag = BREAK;
printf("binary file address : %d\tassembly infomation:%s\n",address,comment[address]);
}
}
void reg_stop(int num)
{
int i;
for (i=0;i<32;i++)
{
if (res[i]==num)
{
debug_flag = BREAK;
print_reg();
printf("binary file address : %d\tassembly infomation:%s\n",address,comment[address]);
break;
}
}
}
iset *insert_iset(iset *is, char *bit){
iset *tmp;
char op[8], rs[8],rt[8],im[24],target[32],
rd[8],shamt[8],funct[8],f_op[8];
memset(op, '\0', 8);
memcpy(op, bit, 6);
tmp = (iset *)malloc(sizeof(iset));
tmp->op = two_ten(op, 6, 0);
switch(tmp->op){
case 0: //R-type add,sub,and,or,xor,sll,srl,jr,jalr
memcpy(rs, bit+6, 5);
memcpy(rt, bit+11, 5);
memcpy(rd, bit+16, 5);
memcpy(shamt, bit+21, 5);
memcpy(funct, bit+26, 6);
tmp->rs = two_ten(rs, 5, 0);
tmp->rt = two_ten(rt, 5, 0);
tmp->rd = two_ten(rd, 5, 0);
tmp->shamt = two_ten(shamt,5, 0);
tmp->funct = two_ten(funct,6, 0);
break;
case 2: //J-type j
case 3: //jal
memcpy(target, bit+6, 26);
tmp->target = two_ten(target, 26, 1);
break;
case 15: //I-type li
case 35: //lw
case 43: //sw
case 8: //addi
case 13: //ori
case 4: //beq
case 5: //bne
case 7: //bgtz
case 6: //blez
case 24: //read
case 25: //write
case 49: //lwc1
case 57: //swc1
memcpy(rs, bit+6, 5);
memcpy(rt, bit+11, 5);
memcpy(im, bit+16, 16);
tmp->rs = two_ten(rs, 5, 0);
tmp->rt = two_ten(rt, 5, 0);
tmp->im = two_ten(im,16, 1);
break;
case 17: //F-type
memcpy(f_op,bit+6,5);
tmp->f_op= two_ten(f_op,5,0);
switch (tmp->f_op)
{
case 0://mfc1
memcpy(rt,bit+11,5);
memcpy(rs,bit+16,5);
tmp->rt = two_ten(rt,5,0);
tmp->rs = two_ten(rs,5,0);
break;
case 4://mtc1
memcpy(rt,bit+11,5);
memcpy(rs,bit+16,5);
tmp->rt = two_ten(rt,5,0);
tmp->rs = two_ten(rs,5,0);
break;
case 8://fBranch
memcpy(funct,bit+15,1);
memcpy(im,bit+16,16);
tmp->funct = two_ten(funct,1,0);
tmp->im = two_ten(im,16,1);
break;
case 16://fR-type fabs,fmov,fneg,finv,compare,fadd,fsub,fmul,fdiv
memcpy(rt,bit+11,5);
memcpy(rs,bit+16,5);
memcpy(rd,bit+21,5);
memcpy(funct,bit+26,6);
tmp->rt = two_ten(rt,5,0);
tmp->rs = two_ten(rs,5,0);
tmp->rd = two_ten(rd,5,0);
tmp->funct = two_ten(funct,6,0);
break;
default:
fprintf(stderr,"Insert Error float instruction\n");
break;
}
break;
default:
fprintf(stderr,"Insert Error\n");
debug_flag = BREAK;
break;
}
return(tmp);
}
int exec_iset(iset *is,int address,char *comment){
char io[4];
int sign = SIGNBIT;
switch(is->op){
case 0:
switch(is->funct){
case 32: //add
res[is->rd] = res[is->rs] + res[is->rt];
if(print_asm || debug_flag == STEP)printf("add\tr%d, r%d, r%d\n",is->rd,is->rs,is->rt);
p_3(is->rd,is->rs,is->rt);
break;
case 34: //sub
res[is->rd] = res[is->rs] - res[is->rt];
if(print_asm || debug_flag == STEP)printf("sub\tr%d, r%d, r%d\n",is->rd,is->rs,is->rt);
p_3(is->rd,is->rs,is->rt);
break;
case 39: //nor
res[is->rd] = ~(res[is->rs] | res[is->rt]);
if(print_asm || debug_flag == STEP)printf("nor\tr%d, r%d, r%d\n",is->rd,is->rs,is->rt);
p_3(is->rd,is->rs,is->rt);
break;
case 36: //and
res[is->rd] = res[is->rs] & res[is->rt];
if(print_asm || debug_flag == STEP)printf("and\tr%d, r%d, r%d\n",is->rd,is->rs,is->rt);
p_3(is->rd,is->rs,is->rt);
break;
case 37: //or
res[is->rd] = res[is->rs] | res[is->rt];
if(print_asm || debug_flag == STEP)printf("or\tr%d, r%d, r%d\n",is->rd,is->rs,is->rt);
p_3(is->rd,is->rs,is->rt);
break;
case 38: //xor**
res[is->rd] = res[is->rs] ^ res[is->rt];
if(print_asm || debug_flag == STEP)printf("xor\tr%d, r%d, r%d\n",is->rd,is->rs,is->rt);
p_3(is->rd,is->rs,is->rt);
break;
case 0: //sll
res[is->rd] = res[is->rt] << (is->shamt);
if(print_asm || debug_flag == STEP)printf("sll\tr%d, r%d, %d\n",is->rd,is->rt,is->shamt);
p_2(is->rd,is->rt);
break;
case 2: //srl
sign = SIGNBIT & res[is->rt];
if(print_asm || debug_flag == STEP)printf("%d\n",is->shamt);
res[is->rd] = sign | (ab(res[is->rt]) >> (is->shamt));
if(print_asm || debug_flag == STEP)printf("srl\tr%d, r%d, %d\n",is->rd,is->rt,is->shamt);
p_2(is->rd,is->rt);
break;
case 3: //sra
res[is->rd] = res[is->rt] >> (is->shamt);
if(print_asm || debug_flag == STEP)printf("sra\tr%d, r%d, %d\n",is->rd,is->rt,is->shamt);
p_2(is->rd,is->rt);
break;
case 8: //jr
address = res[is->rs] - 1;
if(print_asm || debug_flag == STEP)printf("jr\tr%d\n",is->rs);
p_1(is->rs);
break;
case 9: //jalr
res[is->rd] = address + 1;
address = res[is->rs] - 1;
if(print_asm || debug_flag == STEP)printf("jalr\tr%d\n",is->rs);
p_1(is->rs);
break;
}
break;
case 15: //lui
res[is->rt] = is->im << 16;
if(print_asm || debug_flag == STEP)printf("lui\tr%d, %d\n",is->rt,is->im);
p_1(is->rt);
break;
case 35: //lw
if(print_asm || debug_flag == STEP)printf("lw\tr%d, %d, r%d\n",is->rt,is->im,is->rs);
p_2(is->rt,is->rs);
if(print_asm || debug_flag == STEP)printf("memory %d:%d\n",is->im+res[is->rs],mem[is->im+res[is->rs]]);
res[is->rt] = mem[(is->im)+res[is->rs]];
break;
case 43: //sw
mem[(is->im)+res[is->rs]] = res[is->rt];
if(print_asm || debug_flag == STEP)printf("sw\tr%d, %d, r%d\n",is->rt,is->im,is->rs);
p_2(is->rt,is->rs);
break;
case 49: //lwc1
fres[is->rt].i = mem[(is->im)+res[is->rs]];
if(print_asm || debug_flag == STEP)printf("lwc1\tf%d, %d, r%d\n",is->rt,is->im,is->rs);
p_1(is->rs);
pf_1(is->rt);
break;
case 57: //swc1
mem[(is->im)+res[is->rs]] = fres[is->rt].i;
if(print_asm || debug_flag == STEP)printf("swc1\tf%d, %d, r%d\n",is->rt,is->im,is->rs);
p_1(is->rs);
pf_1(is->rt);
break;
case 8: //addi
res[is->rt] = res[is->rs] + is->im;
if(print_asm || debug_flag == STEP)printf("addi\tr%d, r%d, %d\n",is->rt,is->rs,is->im);
p_2(is->rt,is->rs);
break;
case 13: //ori
res[is->rt] = res[is->rs] | (0xFFFF & is->im);
if(print_asm || debug_flag == STEP)printf("ori\tr%d, r%d, %d\n",is->rt,is->rs,is->im);
p_2(is->rt,is->rs);
break;
case 2: //j
address = is->target - 1;
if(print_asm || debug_flag == STEP)printf("j\t%d\n",is->target);
if(print_asm || debug_flag == STEP)printf("\n");
break;
case 3: //jal
res[31] = address + 1;
address = is->target - 1;
if(print_asm || debug_flag == STEP)printf("jal\t%d\n",is->target);
if(print_asm || debug_flag == STEP)printf("\n");
break;
case 4: //beq
if(res[is->rs] == res[is->rt])
address += is->im;
if(print_asm || debug_flag == STEP)printf("beq\tr%d, r%d, %d\n",is->rs,is->rt,is->target);
p_2(is->rs,is->rt);
break;
case 5: //bne
if(res[is->rs] != res[is->rt])
address += is->im;
if(print_asm || debug_flag == STEP)printf("bne\tr%d, r%d, %d\n",is->rs,is->rt,is->target);
p_2(is->rs,is->rt);
break;
case 7: //bgt
if(res[is->rs] > res[is->rt])
address += is->im;
if(print_asm || debug_flag == STEP)printf("bgt\tr%d, r%d, %d\n",is->rs,is->rt,is->target);
p_2(is->rs,is->rt);
break;
case 6: //ble
if(res[is->rs] <= res[is->rt])
address += is->im;
if(print_asm || debug_flag == STEP)printf("ble\tr%d, r%d, %d\n",is->rs,is->rt,is->target);
p_2(is->rs,is->rt);
break;
case 24: //read
memcpy(io,&res[is->rt],4);
fread(io,sizeof(char),1,fp_in);
readbyte++;
memcpy(&(res[is->rt]),io,4);
if(print_asm || debug_flag == STEP)printf("%d,%d,%d,%d\n",io[3],io[2],io[1],io[0]);
if(print_asm || debug_flag == STEP)printf("read\tr%d\n",is->rt);
p_1(is->rt);
break;
case 25: //write
if(print_asm || debug_flag == STEP)printf("write\tr%d\n",is->rt);
p_1(is->rt);
memcpy(io,&res[is->rt],4);
if(print_asm || debug_flag == STEP)printf("ASCII:%c,%c,%c,%c\n",io[3],io[2],io[1],io[0]);
fwrite(io,sizeof(char),1,fp_out);
break;
case 17: //F-type
switch (is->f_op)
{
case 0://mfc1
res[is->rt] = fres[is->rs].i;
if(print_asm || debug_flag == STEP)printf("mfc1\tr%d, f%d\n",is->rt,is->rs);
p_1(is->rt);
pf_1(is->rs);
break;
case 4://mtc1
(fres[is->rs]).i = res[is->rt];
if(print_asm || debug_flag == STEP)printf("mtc1\tr%d, f%d\n",is->rt,is->rs);
p_1(is->rt);
pf_1(is->rs);
nan_err(fres[is->rs].f,address);
break;
case 8://fBranch
if (is->funct)
{
if(cond)
address += is->im;
if(print_asm || debug_flag == STEP)printf("bc1t\t%d\n",is->im);
}
else
{
if(cond!=0)
address += is->im;
if(print_asm || debug_flag == STEP)printf("bc1f\t%d\n",is->im);
}
break;
case 16://fR-type
switch(is->funct)
{
case 0://fadd
if (enable_fpu)
{
fres[is->rd].i = fadd(fres[is->rs].i, fres[is->rt].i);
if(print_asm)printf("add.s\tf%d, f%d, f%d\n",is->rd,is->rs,is->rt);
}
else
{
fres[is->rd].f =fres[is->rs].f + fres[is->rt].f;
if(print_asm || debug_flag == STEP)printf("add.s\tf%d, f%d, f%d\n",is->rd,is->rs,is->rt);
}
pf_3(is->rd,is->rs,is->rt);
nan_err(fres[is->rd].f,address);
break;
case 1://fsub
if (enable_fpu)
{
fres[is->rd].i = fadd(fres[is->rs].i, -fres[is->rt].i);
if(print_asm)printf("sub.s\tf%d, f%d, f%d\n",is->rd,is->rs,is->rt);
}
else
{
fres[is->rd].f =fres[is->rs].f - fres[is->rt].f;
if(print_asm || debug_flag == STEP)printf("sub.s\tf%d, f%d, f%d\n",is->rd,is->rs,is->rt);
}
pf_3(is->rd,is->rs,is->rt);
nan_err(fres[is->rd].f,address);
break;
case 2://fmul
if (enable_fpu)
{
fres[is->rd].i = fmul(fres[is->rs].i, fres[is->rt].i);
if(print_asm)printf("mul.s\tf%d, f%d, f%d\n",is->rd,is->rs,is->rt);
}
else
{
fres[is->rd].f =fres[is->rs].f * fres[is->rt].f;
if(print_asm || debug_flag == STEP)printf("mul.s\tf%d, f%d, f%d\n",is->rd,is->rs,is->rt);
}
pf_3(is->rd,is->rs,is->rt);
nan_err(fres[is->rd].f,address);
break;
case 3://fdiv
if (enable_fpu)
fres[is->rd].i = fmul(fres[is->rs].i, finv(fres[is->rt].i));
else
fres[is->rd].f = fres[is->rs].f / fres[is->rt].f;
if(print_asm || debug_flag == STEP)
printf("div.s\tf%d, f%d, f%d\n",is->rd,is->rs,is->rt);
pf_3(is->rd,is->rs,is->rt);
nan_err(fres[is->rd].f,address);
break;
case 5://fabs
fres[is->rd].f = abs(fres[is->rs].f);
if(print_asm || debug_flag == STEP)printf("abs.s\tf%d, f%d\n",is->rd,is->rs);
pf_2(is->rd,is->rs);
nan_err(fres[is->rd].f,address);
break;
case 6://fmov
fres[is->rd].f = fres[is->rs].f;
if(print_asm || debug_flag == STEP)printf("move.s\tf%d, f%d\n",is->rd,is->rs);
pf_2(is->rd,is->rs);
nan_err(fres[is->rd].f,address);
break;
case 7://fneg
if (enable_fpu)
{
fres[is->rd].i = fneg(fres[is->rs].i);
if(print_asm)printf("neg.s\tf%d, f%d\n",is->rd,is->rs);
}
else
{
fres[is->rd].f = -fres[is->rs].f;
if(print_asm || debug_flag == STEP)printf("neg.s\tf%d, f%d\n",is->rd,is->rs);
}
pf_2(is->rd,is->rs);
nan_err(fres[is->rd].f,address);
break;
case 8://finv
if (enable_fpu)
{
fres[is->rd].i = finv(fres[is->rs].i);
if(print_asm)printf("inv.s\tf%d, f%d\n",is->rd,is->rs);
}
else
{
fres[is->rd].f = 1/fres[is->rs].f;
if(print_asm || debug_flag == STEP)printf("inv.s\tf%d, f%d\n",is->rd,is->rs);
}
pf_2(is->rd,is->rs);
nan_err(fres[is->rd].f,address);
break;
case 50://c.oeq
if (fres[is->rs].f == fres[is->rt].f) cond = 1;
else cond = 0;
if(print_asm || debug_flag == STEP)printf("c.oeq\tf%d, f%d\n",is->rs,is->rt);
pf_2(is->rs,is->rt);
break;
case 52://c.olt
if (fres[is->rs].f < fres[is->rt].f) cond = 1;
else cond = 0;
if(print_asm || debug_flag == STEP)printf("c.olt\tf%d, f%d\n",is->rs,is->rt);
pf_2(is->rs,is->rt);
break;
case 54://c.ole
if (fres[is->rs].f <= fres[is->rt].f) cond = 1;
else cond = 0;
if(print_asm || debug_flag == STEP)printf("c.ole\tf%d, f%d\n",is->rs,is->rt);
pf_2(is->rs,is->rt);
break;
default:
fprintf(stderr,"Exec Error fR-type\n");
fscanf(stdin,"%n",stop);
debug_flag = BREAK;
break;
}
break;
default:
fprintf(stderr,"Exec Error probably Float instruction\n");
fscanf(stdin,"%n",stop);
debug_flag = BREAK;
break;
}
break;
default:
fprintf(stderr,"Exec Error unknown instruction\n");
fscanf(stdin,"%n",stop);
debug_flag = BREAK;
break;
}
if(print_asm || debug_flag == STEP)printf("binary file address : %d\tassembly infomation:%s\n",address,comment);
return(address);
}
int find(int address,int breakpoint[1024],int size)
{
int i;
for(i=0;i<size;i++)
if (address == breakpoint[i])return i+1;
return 0;
}
void input_command(int address)
{
int i,j;
char *p;
while(1)
{
fprintf(stderr,"Stop at %d\n",address);
scanf("%s",command);
if (strcmp("r",command)==0||strcmp("run",command)==0)
{
debug_flag = RUN;
break;
}
if (strcmp("s",command)==0||strcmp("step",command)==0)
{
debug_flag = STEP;
break;
}
if (strcmp("q",command)==0||strcmp("quit",command)==0)
{
debug_flag = QUIT;
break;
}
if (strcmp("b",command)==0||strcmp("break",command)==0)
{
scanf("%d",&i);
breakpoint[number_of_breakpoint] = i;
fprintf(stderr,"Set Breakpoint:%d\n",i);
number_of_breakpoint++;
}
else if (strcmp("d",command)==0||strcmp("delete",command)==0)
{
scanf("%d",&i);
breakpoint[find(i,breakpoint,number_of_breakpoint)-1]=breakpoint[number_of_breakpoint-1];
breakpoint[number_of_breakpoint-1]=-1;
number_of_breakpoint--;
fprintf(stderr,"Delete Breakpoint:%d\n",i);
}
else if (strcmp("o",command)==0||strcmp("op",command)==0)
{
scanf("%d",&i);
if (i)print_asm = 1;
else print_asm = 0;
fprintf(stderr,"Print operations\n");
}
else if (strcmp("ba",command)==0||strcmp("breakassembly",command)==0)
{
scanf("%d",&i);
p = comment[i];
for (j=0;j<64;j++)
{
if (*p==':'){
p++;
sscanf(p,"%d",&i);
break;
}
p++;
}
breakpoint[number_of_breakpoint] = i;
fprintf(stderr,"Set Breakpoint in assembly:%d\n",i);
number_of_breakpoint++;
}
else if (strcmp("i",command)==0||strcmp("info",command)==0)
{
print_reg();
if(print_asm)printf("binary file address : %d\tassembly infomation:%s\n",address,comment[address]);
fprintf(stderr,"By now the program read %d bytes.\n",readbyte);
}
else fprintf(stderr,"unknown command.\n");
}
}
void handler(int sig)
{
printf("SEGMENTATION FAULT\n");
print_reg();
printf("binary file address : %d\tassembly infomation:%s\n",address,comment[address]);
debug_flag = BREAK;
exit(1);
}
void handlebreak(int sig)
{
debug_flag = BREAK;
}
int main(int argc, char *argv[]){
int i,line=0;
FILE *fp;
char buf[1024];
int pre_address = -1;
int bit;
for(i=0; i<MAX_NUM; i++)
res[i] = 0;
//SEGVの時のアクション設定
struct sigaction sigact;
sigact.sa_flags = 0;
sigact.sa_handler = handler;
sigaction(SIGSEGV,&sigact,NULL);
//SIGINT
sigact.sa_handler = handlebreak;
sigaction(SIGINT,&sigact,NULL);
//出力ファイルの設定
strcpy(buf,argv[1]);
strcat(buf,"_ans");
//各種ファイルのオープン
fp = fopen(argv[1], "r");
if(fp == NULL){
fprintf(stderr, "file does not open.\n");
return -1;
}
fp_in = fopen(argv[2], "r");
if(fp_in == NULL){
fprintf(stderr, "input file does not open.\n");
return -1;
}
fp_out = fopen(buf,"wb");
while (fgets(buf, MAX_NUM + 64, fp) != NULL)//命令メモリに読み込み
{
bit = 0;
for(i = 0; i < 32; i++)
{
bit = bit << 1;
if (buf[i]=='1')bit++;
}
mem[line] = bit;
//printf("memory %d:\t%d\n",line,mem[line]);
sscanf(buf,"%s #%s",isetmem[line],comment[line]);
imem[line] = insert_iset(imem[line],isetmem[line]);
line++;
}
fclose(fp);
input_command(address);
for(address=0; address<line; address++){
if (find(address,breakpoint,number_of_breakpoint))debug_flag = BREAK;
if (debug_flag == BREAK)input_command(address);
if (debug_flag == QUIT)break;
//is = insert_iset(is,isetmem[address]);
address = exec_iset(imem[address],address,comment[address]);
reg_stop(reg_val);
//printf("\n%s, address:%d\n",isetmem[address], address);
//printf("\n");
if (pre_address == address)break; //終了判定
pre_address = address;
if (debug_flag == STEP)debug_flag = BREAK;
}
return(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment