ref: 5139c2e98511dfeb47b909e1dee53ab5106eba14
dir: /5552a.c/
#include "port.h" #include "5552.h" char* readin(char *in, int len) { memset(in, 1, len); for(int i = 0 ; i < len || in+i ; i++) read(1, in+i, 1); return in; } void asmtobin(char *in) { int tmp = 0, len; char *buf; len = strlen(in); for(int i = 0 ; i < len && in[i] ; i++) { if(in[i] == '\t') continue; else if(in[i] == '\n' || in[i] == '\0') { buf[tmp++] = '\0'; tmp = 0; tobin(buf); } buf[tmp++] = in[i]; } } void tobin(char *line) { int *inst, *arg1, *arg2; match(line, inst, arg1, arg2); } int matchinst(char *s) { int inst = -1; if(!strcmp(s, "DRD")) inst = DRD; if(!strcmp(s, "DWR")) inst = DWR; if(!strcmp(s, "NOT")) inst = NOT; if(!strcmp(s, "AND")) inst = AND; if(!strcmp(s, "NOR")) inst = NOR; if(!strcmp(s, "XOR")) inst = XOR; if(!strcmp(s, "ADD")) inst = ADD; if(!strcmp(s, "SUB")) inst = SUB; if(!strcmp(s, "INC")) inst = INC; if(!strcmp(s, "DEC")) inst = DEC; if(!strcmp(s, "MUL")) inst = MUL; if(!strcmp(s, "DIV")) inst = DIV; if(!strcmp(s, "SHR")) inst = SHR; if(!strcmp(s, "SHL")) inst = SHL; if(!strcmp(s, "JMP")) inst = JMP; if(inst == -1) sysfatal("No instruction found for %s", s); return inst; } void addlabel(char *name) { for(int i = 0 ; i < lc ; i++) { if(!strcmp(labels[i].name, name)) sysfatal("duplicate label %s\t "prev pc: %x\t" "curr pc: %x", name, labels[i].pc, pc); } labels[lc].name = name; labels[lc].pc = pc; lc++; } void matchline(char *line) { int len, spaces[2], scount = 0; len = strlen(line); for(int i = 0 ; i < len ; i++) { if(line[i] == ' ') { if(scount < 2) spaces[scount++] = i; else { fprint(2, "Too many spaces in the line:\n" "\t%s\n\t", line); for(int j = 0 ; j < i ; j++) fprint(2, " "); fprint(2, "^\n"); sysfatal("Too many spaces."); } } else if(line[i] == ':' && line[i+1] == '\n' && scount == 0) { addlabel(line); return; } } for(int i = 0 ; i < scount ; i++) line[spaces[i]] = '\0'; program[pc].inst = matchinst(line); if(scount == 1) program[pc].arg1 = atoi(line+spaces[0]); else if(scount == 2) program[pc].arg2 = atoi(line+spaces[1]); pc++ } void lint(void) { int res, totalres[2] = {0, 0}; for(int i = 0 ; i < pc ; i++) { res = lintop(program[i]); if(res & WARN) totalres[WARN]++; if(res & ERR) totalres[ERR]++; } if(totalres[WARN] || totalres[ERR]) fprint(2, "%d warnnings and %d errors detected\n", totalres[WARN], totalres[ERR]); } int lintop(int linenumber) { Op op = program[linenumber]; for(int i ; i < sizeof(instructions) / sizeof(Inst) ; i++) { if(op.inst == instructions[i].inst) return instructions[i].lint(op.mode, op.arg1, op.arg2); } } void asm(int flags) { asm2bin(input); if(flags & SFLAG) { for(int i = 0 ; i < pc ; i++) { write(0, program[i].inst, sizeof(Word)); write(0, program[i].mode, sizeof(Word)); write(0, program[i].arg1, sizeof(Word)); write(0, program[i].arg2, sizeof(Word)); } } } int main(int argc, char* argv[]) { unsigned int inst, a, b, c; char string[32], op[4]; while(scanf("%s %[^\n;]%*c", op, string) > 0) { sscanf(string, "%u %u %u", &a, &b, &c); if(!strcmp(op, "DIE")) inst = DIE; if(!strcmp(op, "OUT")) inst = OUT; if(!strcmp(op, "NOT")) inst = NOT; if(!strcmp(op, "AND")) inst = AND; if(!strcmp(op, "NOR")) inst = NOR; if(!strcmp(op, "XOR")) inst = XOR; if(!strcmp(op, "SUB")) inst = SUB; if(!strcmp(op, "ADD")) inst = ADD; if(!strcmp(op, "SHR")) inst = SHR; if(!strcmp(op, "SHL")) inst = SHL; if(!strcmp(op, "PUT")) inst = PUT; if(!strcmp(op, "MOV")) inst = MOV; if(!strcmp(op, "LDM")) inst = LDM; if(!strcmp(op, "NTH")) inst = NTH; switch(inst) { /* no args */ case DIE: printf("%u\n", inst); break; /* one arg */ case NOT: case OUT: printf("%u %u\n", inst, a); break; /* two args */ case PUT: case MOV: case LDM: printf("%u %u %u\n", inst, a, b); break; /* three args */ case AND: case NOR: case XOR: case SUB: case SHL: case SHR: case ADD: case NTH: printf("%u %u %u %u\n", inst, a, b, c); break; /* should this ever happen? */ default: fprintf(stderr, "unkown instr.\n"); return -1; } } return 0; }