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