ref: d128c76aca17cf3b340c48175d8cdfaaeff40657
author: sirjofri <[email protected]>
date: Sun Feb 4 13:47:37 EST 2024
adds files (roughly working spirvd)
--- /dev/null
+++ b/README
@@ -1,0 +1,19 @@
+GPUFS cpu implementation and Spir-V disassembler
+
+EVERYTHING CURRENTLY IS A BIG TODO!
+
+
+
+GPU filesystem (gpufs; TODO)
+
+gpufs [ -d ]
+
+-d enables debugging
+
+
+
+Spir-V disassembler (spirvd)
+
+spirvd [ -d ] < shaderbin > shaderasm
+
+-d enables debugging
--- /dev/null
+++ b/gpufs.c
@@ -1,0 +1,35 @@
+#include <u.h>
+#include <libc.h>
+#include "vm.h"
+
+int debug = 0;
+int disassemble = 0;
+
+u32int magic = 0x07230203;
+
+u32int testprog[2048];
+
+void
+main(int argc, char **argv)
+{
+ int r = 0;
+
+ ARGBEGIN{
+ case 'd':
+ debug++;
+ break;
+ }ARGEND;
+
+ if (argc) {
+ r = open(argv[0], OREAD);
+ }
+
+ read(r, testprog, 2048);
+
+ if (*testprog != magic) {
+ fprint(2, "bad magic! got: %x\n", *testprog);
+ return;
+ }
+
+ vmrun(testprog+1);
+}
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,10 @@
+</$objtype/mkfile
+
+TARG=\
+ gpufs\
+ spirvd\
+
+</sys/src/cmd/mkmany
+
+$O.gpufs: gpufs.$O vm.$O ops.$O names.$O
+$O.spirvd: spirvd.$O vm.$O ops.$O names.$O
--- /dev/null
+++ b/names.c
@@ -1,0 +1,29 @@
+#include <u.h>
+#include <libc.h>
+#include "names.h"
+
+Name *names = nil;
+
+void
+nameadd(uint id, char *name)
+{
+ Name *n;
+
+ n = malloc(sizeof(Name));
+ n->name = strdup(name);
+ n->id = id;
+ n->next = names;
+ names = n;
+}
+
+char*
+namelookup(uint id)
+{
+ Name *n;
+
+ for (n = names; n; n = n->next) {
+ if (n->id == id)
+ return n->name;
+ }
+ return nil;
+}
--- /dev/null
+++ b/names.h
@@ -1,0 +1,9 @@
+typedef struct Name Name;
+struct Name {
+ uint id;
+ char *name;
+ Name *next;
+};
+
+void nameadd(uint id, char *name);
+char *namelookup(uint id);
--- /dev/null
+++ b/ops.c
@@ -1,0 +1,100 @@
+#include <u.h>
+#include <libc.h>
+#include "vm.h"
+#include "ops.h"
+#include "names.h"
+
+extern int debug;
+extern int disassemble;
+
+void
+printresult(int should, uint varid)
+{
+ char *s;
+
+ if (!should) {
+ print("%10s ", " ");
+ return;
+ }
+ s = smprint("$%d", varid);
+ print("%10s = ", s);
+ free(s);
+}
+
+void
+OpTypeFloat(Frame *f, u32int)
+{
+ u32int varid = *(f->pc+1);
+ u32int tlen = *(f->pc+2);
+
+ if (disassemble) {
+ printresult(1, varid);
+ print("OpTypeFloat %d\n", tlen);
+ return;
+ }
+}
+
+void
+OpTypeInt(Frame *f, u32int)
+{
+ u32int varid = *(f->pc+1);
+ u32int tlen = *(f->pc+2);
+
+ if (disassemble) {
+ printresult(1, varid);
+ print("OpTypeInt %d\n", tlen);
+ return;
+ }
+}
+
+void
+OpName(Frame *f, u32int)
+{
+ u32int varid = *(f->pc+1);
+ char *varname = (char*)(f->pc+2);
+
+ nameadd(varid, varname);
+
+ if (disassemble) {
+ printresult(0, 0);
+ print("OpName $%d \"%s\"\n", varid, varname);
+ return;
+ }
+}
+
+void
+OpNop(Frame*, u32int)
+{
+ if (disassemble) {
+ printresult(0, 0);
+ print("OpNop\n");
+ }
+}
+
+Op oplist[] = {
+ { 5, OpName },
+ { 21, OpTypeInt },
+ { 22, OpTypeFloat },
+ { nil, OpNop },
+};
+
+int
+oplookup(u32int code, void (**f)(Frame*,u32int))
+{
+ Op *o;
+ u32int c = code & 0x0000ffff;
+ if (c == 0) {
+ *f = OpNop;
+ return 1;
+ }
+
+ for (o = oplist; o->opcode; o++) {
+ if (c == o->opcode) {
+ *f = o->f;
+ return 1;
+ }
+ }
+
+ werrstr("operation (%d) not supported!", c);
+ return 0;
+}
--- /dev/null
+++ b/ops.h
@@ -1,0 +1,7 @@
+typedef struct Op Op;
+struct Op {
+ u32int opcode;
+ void (*f)(Frame*,u32int);
+};
+
+int oplookup(u32int code, void (**f)(Frame*,u32int));
--- /dev/null
+++ b/spirvd.c
@@ -1,0 +1,35 @@
+#include <u.h>
+#include <libc.h>
+#include "vm.h"
+
+int debug = 0;
+int disassemble = 1;
+
+u32int magic = 0x07230203;
+
+u32int testprog[2048];
+
+void
+main(int argc, char **argv)
+{
+ int r = 0;
+
+ ARGBEGIN{
+ case 'd':
+ debug++;
+ break;
+ }ARGEND;
+
+ if (argc) {
+ r = open(argv[0], OREAD);
+ }
+
+ read(r, testprog, 2048);
+
+ if (*testprog != magic) {
+ fprint(2, "bad magic! got: %x\n", *testprog);
+ return;
+ }
+
+ vmrun(testprog+1);
+}
--- /dev/null
+++ b/vm.c
@@ -1,0 +1,68 @@
+#include <u.h>
+#include <libc.h>
+#include "vm.h"
+#include "ops.h"
+
+extern int debug;
+
+Frame *stack = nil;
+
+u32int
+runinst(u32int *ptr)
+{
+ u32int len, opcode;
+ void (*func)(Frame*,u32int);
+
+ opcode = (*ptr) & 0x0000ffff;
+ len = ((*ptr) & 0xffff0000) >> 16;
+
+ if (oplookup(opcode, &func)) {
+ func(stack, len);
+
+ // if (func) changes pc, ignore it
+ if (ptr == stack->pc) {
+ stack->pc += len;
+ }
+ return len;
+ }
+ fprint(2, "error: %r\n");
+ return 0;
+}
+
+void
+runstack(u32int *ptr)
+{
+ Frame *n = malloc(sizeof(Frame));
+
+ n->next = stack;
+ stack = n;
+ stack->pc = ptr;
+
+ while (runinst(stack->pc)) {
+ ;
+ }
+}
+
+void
+retstack(void)
+{
+ Frame *p, *c;
+
+ p = stack->next;
+ c = stack;
+
+ if (!p)
+ goto fin;
+
+ stack = p;
+
+fin:
+ free(c);
+}
+
+void
+vmrun(u32int *ptr)
+{
+ stack = nil; // TODO clean stack
+ runstack(ptr);
+}
--- /dev/null
+++ b/vm.h
@@ -1,0 +1,9 @@
+typedef struct Frame Frame;
+struct Frame {
+ u32int *pc;
+ Frame *next;
+};
+
+void vmrun(u32int *ptr);
+void runstack(u32int *ptr);
+void retstack(void);