shithub: gpufs

ref: 5781e4d2a29054abc5d659e9ca867604cba4513f
dir: /cops.c/

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

extern int debug;

#define DPRINT(m) if (debug) fprint(2, (m));

int
lstrlen(int len)
{
	int nlen = len + 1;
	return (nlen)%4 == 0 ? (nlen/4) : (nlen/4)+1;
}


// true if updated
int
updatenitems(Shader *s, long id)
{
	if (id >= s->maxitems)
		return 0;
	if (id < s->nitems)
		return 1;
	s->nitems = id + 1;
	return 1;
}

void
OpTypeVoid(Frame *f, u32int)
{
	DPRINT("OpTypeVoid\n");
}

void
OpTypeFloat(Frame *f, u32int)
{
	u32int varid = *(f->pc+1);
	u32int tlen = *(f->pc+2);
	
	DPRINT("OpTypeFloat\n");
}

void
OpTypeInt(Frame *f, u32int)
{
	u32int varid = *(f->pc+1);
	u32int tlen = *(f->pc+2);
	
	DPRINT("OpTypeInt\n");
}

void
OpName(Frame *f, u32int)
{ DPRINT("OpName\n"); return; }

void
OpNop(Frame*, u32int)
{ DPRINT("OpNop\n"); return; }

void
OpEntryPoint(Frame* f, u32int len)
{
	if (f->ctxt.type == COMPILE) {
		EntryPoint *p;
		Shader *s;
		u32int emodel = f->pc[1];
		u32int epoint = f->pc[2];
		char *name = (char*)&f->pc[3];
		int l = lstrlen(strlen(name)) + 3;
		u32int *argv = &f->pc[l];
		u32int argc = len - l;
		
		DPRINT("OpEntryPoint\n");
		
		// only support GLCompute shaders
		if (emodel != 5)
			return;
		
		s = f->ctxt.c.shader;
		p = malloc(sizeof(EntryPoint));
		p->name = strdup(name);
		p->func = epoint;
		
		if (s->entrypoints) {
			p->next = s->entrypoints;
			s->entrypoints = p;
		} else {
			p->next = nil;
			s->entrypoints = p;
		}
		return;
	}
	return;
}

void
OpTypeFunction(Frame *f, u32int len)
{
	if (f->ctxt.type == COMPILE) {
		Shader *s = f->ctxt.c.shader;
		u32int varid = f->pc[1];
		u32int rettype = f->pc[2];
		u32int *argv = &f->pc[3];
		u32int argc = len - 3;
		
		DPRINT("OpTypeFunction\n");
		
		// TODO error!
		if (!updatenitems(s, varid))
			return;
		
		s->items[varid].type = TTYPE;
		s->items[varid].t.optype = 33;
	}
	DPRINT("OpTypeFunction\n");
	return;
}

void
OpFunction(Frame *f, u32int len)
{
	if (f->ctxt.type == COMPILE) {
		Shader *s = f->ctxt.c.shader;
		u32int result = f->pc[1];
		u32int retvar = f->pc[2];
		u32int fctl = f->pc[3];
		u32int ftype = f->pc[4];
		
		DPRINT("OpFunction\n");
		
		// TODO error!
		if (!updatenitems(s, result))
			return;
		
		s->items[result].type = TFUNCTION;
		s->items[result].f.rettype = retvar;
		s->items[result].f.label = -1;
		s->lastfunction = result;
		return;
	}
	// TODO: new stack should be done in OpCallFunction
	DPRINT("OpFunction\n");
	return;
}

void
OpFunctionEnd(Frame *f, u32int len)
{
	DPRINT("OpFunctionEnd\n");
	
	if (f->ctxt.type == COMPILE)
		return;
	
	// pop stack (test)
	*f->ctxt.r.frameptr = f->next;
	free(f);

	return;
}

void
OpLabel(Frame *f, u32int len)
{
	DPRINT("OpLabel\n");
	if (f->ctxt.type == COMPILE) {
		Shader *s = f->ctxt.c.shader;
		u32int retvar = f->pc[1];
		
		if (!updatenitems(s, retvar))
			return;
		
		s->items[retvar].type = TLABEL;
		s->items[retvar].l.ptr = &f->pc[len + 1];
		
		if (debug) {
			fprint(2, "Label: %p\n", s->items[retvar].l.ptr);
		}
		
		if (s->lastfunction >= 0) {
			s->items[s->lastfunction].f.label = retvar;
			s->lastfunction = -1;
		}
		return;
	}
	return;
}

Op oplist[] = {
	{    5, OpName },
	{   15, OpEntryPoint },
	{   19, OpTypeVoid },
	{   21, OpTypeInt },
	{   22, OpTypeFloat },
	{   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;
}