ref: a0d30aba763788d63e47878756cbd4e5cc6f6798
dir: /asm.c/
#include <u.h> #include <libc.h> #include "sym.h" #include "asm.h" #include "y.tab.h" #include "ops.h" #define NIL 0 Inst res; Inst op; Inst args[10]; int argptr = 0; int lstrlen(int len) { int nlen = len + 1; return (nlen)%4 == 0 ? (nlen/4) : (nlen/4)+1; } void a_init() { res.type = NIL; op.type = NIL; for (int i = 0; i < argptr; i++) { if (args[i].type == STR) { free(args[i].str); } } argptr = 0; } void assemble(void) { u32int output[128]; u32int* optr; u32int numwords = 0; int slen; Inst in; if (res.type == SYM) { numwords++; } if (op.type == OP) { numwords++; } else { fprint(2, "error: no Op to assemble!\n"); } for (int i = 0; i < argptr; i++) { in = args[i]; switch (in.type) { case NIL: case OP: fprint(2, "warning: strange situation!\n"); break; case SYM: case FLOAT: case INT: numwords++; break; case STR: slen = strlen(in.str) + 1; // padded string length as words (u32int) numwords += slen%4 ? (slen/4 + 1) : slen/4; } } if (debug) { fprint(2, "%d: ", numwords); fprint(2, " %10s =", res.type ? res.var->name : ""); fprint(2, " %s", op.type ? o_find(op.op) : nil); for (int i = 0; i < argptr; i++) { in = args[i]; switch (in.type) { case NIL: case OP: fprint(2, " X"); break; case SYM: fprint(2, " %s", in.var->name); break; case FLOAT: fprint(2, " %f", in.f); break; case INT: fprint(2, " %d", in.i); break; case STR: fprint(2, " \"%s\"", in.str); break; } } fprint(2, "\n"); } optr = output; *optr = (u32int)(numwords<<16 | op.op); optr++; if (res.type == SYM) { *optr = (u32int)res.var->id; optr++; } for (int i = 0; i < argptr; i++) { in = args[i]; switch (in.type) { case SYM: *optr = (u32int)in.var->id; optr++; break; case FLOAT: *optr = (u32int)in.f; optr++; break; case INT: *optr = (u32int)in.i; optr++; break; case STR: slen = strlen(in.str); memset(optr, 0, lstrlen(slen)*4); memcpy(optr, in.str, slen); optr += lstrlen(slen); break; } } slen = optr - output; write(1, output, slen*sizeof(u32int)); a_init(); } void arg(Inst s) { if (argptr >= 10) { sysfatal("error: too many arguments!\n"); } args[argptr++] = s; } void a_result(Symbol *var) { res.type = SYM; res.var = var; } void a_op(uint inop) { op.type = OP; op.op = inop; } void a_var(Symbol *sym) { Inst a; a.type = SYM; a.var = sym; arg(a); } void a_float(double f) { Inst a; a.type = FLOAT; a.f = f; arg(a); } void a_int(int i) { Inst a; a.type = INT; a.i = i; arg(a); } void a_str(char *str) { Inst a; a.type = STR; a.str = str; arg(a); } void a_keyword(char *str) { Inst a; a.type = INT; a.i = k_lookup(str); arg(a); }