shithub: gpufs

Download patch

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);