ref: ca99199e72dc182d2801eb591cdf470c707c1e6c
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
#define BUF4(x) ((x)%4 ? ((x)/4 + 1)*4 : (x))
Inst res;
Inst op;
Inst args[10];
int argptr = 0;
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, BUF4(slen));
memcpy(optr, in.str, slen);
optr += slen/4+1;
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 = 0;
arg(a);
}