shithub: gpufs

ref: b7ecf84c597a332ae0c1bb1534b61cfed573c92c
dir: /dops.c/

View raw version
#include <u.h>
#include <libc.h>
#include "vm.h"
#include "ops.h"
#include "names.h"

extern int debug;

char *executionmodel[] = {
	"Vertex",
	"TessellationControl",
	"TessellationEvaluation",
	"Geometry",
	"Fragment",
	"GLCompute",
	"Kernel",
	nil
};

char*
getexecutionmodel(u32int i)
{
	if (i >= sizeof(executionmodel))
		return nil;
	return executionmodel[i];
}

char*
getfunctioncontrol(u32int i)
{
	switch (i) {
	case 0x0: return "None";
	case 0x2: return "DontInline";
	case 0x4: return "Pure";
	case 0x8: return "Const";
	case 0x10000: return "OptNoneINTEL";
	}
	return nil;
}

void
printresult(int should, uint varid)
{
	char *s;
	
	if (!should) {
		print("%10s   ", " ");
		return;
	}
	s = smprint("%%%d", varid);
	print("%10s = ", s);
	free(s);
}

void
OpTypeVoid(Frame *f, u32int)
{
	u32int varid = f->pc[1];
	
	printresult(1, varid);
	print("OpTypeVoid\n");
}

void
OpTypeBool(Frame *f, u32int)
{
	u32int varid = f->pc[1];
	
	printresult(1, varid);
	print("OpTypeBool\n");
}

void
OpTypeInt(Frame *f, u32int)
{
	u32int varid = f->pc[1];
	u32int tlen = f->pc[2];
	
	printresult(1, varid);
	print("OpTypeInt %d\n", tlen);
}

void
OpTypeFloat(Frame *f, u32int)
{
	u32int varid = f->pc[1];
	u32int tlen = f->pc[2];
	
	printresult(1, varid);
	print("OpTypeFloat %d\n", tlen);
}

void
OpTypeVector(Frame *f, u32int)
{
	u32int varid = f->pc[1];
	u32int ttype = f->pc[2];
	u32int tlen = f->pc[3];
	
	printresult(1, varid);
	print("OpTypeFloat %%%d %d\n", ttype, tlen);
}

void
OpTypeMatrix(Frame *f, u32int)
{
	u32int varid = f->pc[1];
	u32int ctype = f->pc[2];
	u32int tlen = f->pc[3];
	
	printresult(1, varid);
	print("OpTypeFloat %%%d %d\n", ctype, tlen);
}

void
OpName(Frame *f, u32int)
{
	u32int varid = f->pc[1];
	char *varname = (char*)&f->pc[2];
	
	nameadd(varid, varname);
	
	printresult(0, 0);
	print("OpName %%%d \"%s\"\n", varid, varname);
}

void
OpNop(Frame*, u32int)
{
	printresult(0, 0);
	print("OpNop\n");
}

void
OpUndef(Frame*, u32int)
{
	printresult(0, 0);
	print("OpUndef\n");
}

void
OpSource(Frame* f, u32int len)
{
	u32int slang = f->pc[1];
	u32int version = f->pc[2];
	u32int file = 0;
	short hasfile = 0;
	char* filename;
	
	if (len > 3) {
		hasfile = 1;
		file = f->pc[3];
	}
	
	printresult(0, 0);
	print("OpSource %d %d", slang, version);
	if (hasfile) {
		filename = strlookup(file);
		print(" %s", filename);
	}
	print("\n");
}

void
OpTypeFunction(Frame *f, u32int len)
{
	u32int varid = f->pc[1];
	u32int rettype = f->pc[2];
	u32int* argv = &f->pc[3];
	u32int argc = len - 3;
	
	printresult(1, varid);
	print("OpTypeFunction %%%d", rettype);
	
	for (int i = 0; i < argc; i++) {
		u32int v = argv[i];
		print(" %%%d", v);
	}
	print("\n");
}

void
OpEntryPoint(Frame *f, u32int len)
{
	u32int emodel = f->pc[1];
	u32int epoint = f->pc[2];
	char *name = (char*)&f->pc[3];
	int l = strlen(name)+1;
	l = (l%4 == 0 ? l/4 : l/4+1);
	u32int *argv = &f->pc[l+3];
	u32int argc = len - (l+2);
	
	printresult(0, 0);
	print("OpEntryPoint %s %%%d \"%s\"", getexecutionmodel(emodel), epoint, name);
	
	for (int i = 0; i < argc; i++) {
		u32int v = argv[i];
		print(" %%%d", v);
	}
	print("\n");
}

void
OpFunction(Frame *f, u32int)
{
	u32int result = f->pc[1];
	u32int retvar = f->pc[2];
	u32int fctl = f->pc[3];
	u32int ftype = f->pc[4];
	
	printresult(1, result);
	print("OpFunction %%%d %s %%%d\n",
		retvar,
		getfunctioncontrol(fctl),
		ftype);
}

void
OpFunctionEnd(Frame*, u32int)
{
	printresult(0, 0);
	print("OpFunctionEnd\n");
}

void
OpLabel(Frame *f, u32int)
{
	u32int retvar = f->pc[1];
	printresult(1, retvar);
	print("OpLabel\n");
}

Op oplist[] = {
	{     1, OpUndef },
	{     3, OpSource },
	{     5, OpName },
	{    15, OpEntryPoint },
	{    19, OpTypeVoid },
	{    20, OpTypeBool },
	{    21, OpTypeInt },
	{    22, OpTypeFloat },
	{    23, OpTypeVector },
	{    24, OpTypeMatrix },
	{    33, OpTypeFunction },
	{    54, OpFunction },
	{    56, OpFunctionEnd },
	{   248, OpLabel },
	{   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;
}