ref: 5781e4d2a29054abc5d659e9ca867604cba4513f
dir: /cops.c/
#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;
}