ref: cbbb6280961fd5a120d2a5a765bd483fbfc86af7
author: sirjofri <[email protected]>
date: Sat Feb 3 17:59:18 EST 2024
adds files
--- /dev/null
+++ b/asm.c
@@ -1,0 +1,195 @@
+#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;
+ slen = BUF4(slen);
+ numwords += slen;
+ }
+ }
+
+ 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);
+}
--- /dev/null
+++ b/asm.h
@@ -1,0 +1,23 @@
+typedef struct Inst Inst;
+struct Inst {
+ int type;
+ union {
+ Symbol *var;
+ uint op;
+ double f;
+ int i;
+ char *str;
+ };
+};
+
+extern int debug;
+
+void a_result(Symbol *var);
+void a_op(uint op);
+void a_var(Symbol *var);
+void a_float(double f);
+void a_int(int i);
+void a_str(char *str);
+
+void a_init(void);
+void assemble(void);
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,21 @@
+</$objtype/mkfile
+
+LFLAGS=-9
+
+TARG=\
+ spirva\
+
+OFILES=\
+ y.tab.$O\
+ lex.yy.$O\
+ sym.$O\
+ asm.$O\
+ ops.$O\
+
+YFILES=\
+ spirva.y\
+
+LFILES=\
+ spirva.l\
+
+</sys/src/cmd/mkone
--- /dev/null
+++ b/ops.c
@@ -1,0 +1,34 @@
+#include <u.h>
+#include <libc.h>
+#include "ops.h"
+
+Ops ops[] = {
+ { "OpNop", 0 },
+ { nil, nil },
+};
+
+uint
+o_lookup(char *n)
+{
+ Ops *o;
+
+ for (o = ops; o->opname; o++) {
+ if (strcmp(o->opname, n) == 0) {
+ return o->op;
+ }
+ }
+ return 0;
+}
+
+char*
+o_find(uint op)
+{
+ Ops *o;
+
+ for (o = ops; o->opname; o++) {
+ if (o->op == op) {
+ return o->opname;
+ }
+ }
+ return nil;
+}
--- /dev/null
+++ b/ops.h
@@ -1,0 +1,8 @@
+typedef struct Ops Ops;
+struct Ops {
+ char *opname;
+ uint op;
+};
+
+uint o_lookup(char *n);
+char *o_find(uint op);
--- /dev/null
+++ b/spirva.l
@@ -1,0 +1,48 @@
+%{
+#include "sym.h"
+#include "y.tab.h"
+#include "ops.h"
+%}
+
+WS [ \t]
+ANUM [A-Za-z0-9_]
+INT -?[0-9]+
+FLOAT -?([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)
+
+%%
+
+\;.*$ {}
+
+Op[A-Za-z0-9]+ {
+ yylval.op = o_lookup(yytext);
+ return OP;
+}
+
+\${ANUM}+ {
+ yylval.sym = symfind(strdup(yytext));
+ return SYM;
+}
+
+{INT} {
+ yylval.i = atoi(yytext);
+ return INT;
+}
+
+{FLOAT} {
+ yylval.f = atof(yytext);
+ return FLOAT;
+}
+
+{ANUM}+ {
+ yylval.str = strdup(yytext);
+ return STR;
+}
+
+\" { return '"'; }
+
+=|\n { return yytext[0]; }
+
+{WS} { }
+
+%%
+/* code */
--- /dev/null
+++ b/spirva.y
@@ -1,0 +1,80 @@
+%{
+#include <u.h>
+#include "sym.h"
+#include "asm.h"
+
+int debug;
+
+extern int yylex(void);
+extern int yyparse(void);
+%}
+%union {
+ uint op;
+ double f;
+ int i;
+ Symbol *sym;
+ char *str;
+}
+%token <sym> SYM
+%token <op> OP
+%token <f> FLOAT
+%token <i> INT
+%token <str> STR
+%right '='
+%%
+list: /* nothing */
+ | list '\n'
+ | list SYM '=' oplist '\n' { a_result($2); asm(); }
+ | list oplist '\n' { asm(); }
+ ;
+
+oplist: OP arglist { a_op($1); }
+ ;
+
+arglist: /* nothing */
+ | arglist arg
+ ;
+
+arg: SYM { a_var($1); }
+ | INT { a_int($1); }
+ | FLOAT { a_float($1); }
+ | str
+ ;
+
+str: '"' STR '"' { a_str($2); }
+%%
+ /* end of grammar */
+#include <libc.h>
+#include <bio.h>
+
+void
+init(void) {
+ a_init();
+}
+
+void
+asm(void) {
+ assemble();
+}
+
+void
+main(int argc, char **argv)
+{
+ ARGBEGIN{
+ case 'd':
+ debug++;
+ break;
+ }ARGEND;
+
+ u32int magic = 0x07230203;
+ write(1, &magic, sizeof(u32int));
+
+ for (init(); yyparse(); init())
+ asm();
+}
+
+void
+yyerror(char *s)
+{
+ fprint(2, "error: %s\n", s);
+}
--- /dev/null
+++ b/sym.c
@@ -1,0 +1,46 @@
+#include <u.h>
+#include <libc.h>
+#include "sym.h"
+
+Symbol* syms = nil;
+uint id;
+
+Symbol*
+symfind(char *name)
+{
+ Symbol *s;
+
+ if (!syms) {
+ syms = malloc(sizeof(Symbol));
+ syms->name = name;
+ syms->next = nil;
+ syms->id = id = 0;
+ return syms;
+ }
+
+ s = syms;
+ while (s) {
+ if (strcmp(s->name, name) == 0) {
+ return s;
+ }
+ if (!s->next) {
+ s->next = malloc(sizeof(Symbol));
+ s = s->next;
+ s->next = nil;
+ s->name = name;
+ s->id = ++id;
+ return s;
+ }
+ s = s->next;
+ }
+ return nil;
+}
+
+void
+printsyms()
+{
+ Symbol *s;
+ for (s = syms; s; s = s->next) {
+ print("symbol: %s (%d)\n", s->name, s->id);
+ }
+}
--- /dev/null
+++ b/sym.h
@@ -1,0 +1,9 @@
+typedef struct Symbol Symbol;
+struct Symbol {
+ char *name;
+ uint id;
+ Symbol *next;
+};
+
+Symbol *symfind(char *name);
+void printsyms(void);