📄 cgen.c
字号:
/* Declare the input pointers and init them */ for (e = 0; e < f->nip; e++) { line(f, "%s *ip%d = (%s *)inp[%d];", a->ords[f->ipt[e]].name, e, a->ords[f->ipt[e]].name, e); } /* Declare the output pointers and init them */ for (e = 0; e < f->nop; e++) { line(f, "%s *op%d = (%s *)outp[%d];", a->ords[f->opt[e]].name, e, a->ords[f->opt[e]].name, e); } /* Declare and intialise the end pointer */ line(f, "%s *ep = ip0 + npix * %d ;", a->ords[f->ipt[0]].name, g->in.chi[0]); /* Declare and initialise the input table pointers */ for (e = 0; e < g->id; e++) line(f,"pointer it%d = (pointer)p->in_tables[%d];",e,e); /* Declare and initialise the output table pointers */ for (e = 0; e < g->od; e++) line(f,"pointer ot%d = (pointer)p->out_tables[%d];",e,e); if (!t->sort) { /* Declare and initialise the Simplex weighting base pointer */ line(f,"pointer sw_base = (pointer)p->sw_table;"); } /* Declare and initialise the Interpolation multidim base pointer */ line(f,"pointer im_base = (pointer)p->im_table;"); /* Figure out whether input channel reads can be used directly as table offsets */ t->it_ix = 1; /* Default use input table lookup to extract value */ if (g->in.packed != 0) t->it_ix = 0; /* Extract will be done explicitly */ for (e = 0; e < g->id; e++) { int ee = (g->in.pint != 0) ? 0 : e; /* bpch index */ if ((g->in.bov[e] + g->in.bpv[e]) <= 12) continue; /* Table can do extract */ if (g->in.bov[e] != 0 || g->in.bpv[e] != g->in.bpch[ee]) { t->it_ix = 0; /* Extract will be done explicitly */ break; } } /* ------------------------------- */#ifdef VERBOSE printf("Starting pixel processing loop\n"); fflush(stdout);#endif /* VERBOSE */ /* Start the pixel processing loop */ cr(f); sline(f, "for(;ip0 < ep;"); for (e = 0; e < f->nip; e++) mline(f, " ip%d += %d,", e, g->in.chi[e]); for (e = 0; e < f->nop; e++) mline(f, " op%d += %d%s", e, g->out.chi[e], ((e+1) < f->nop) ? "," : ""); eline(f, ") {"); inc(f); /* Declare output value accumulator(s) */ for (i = 0; i < t->im_fn; i++) { line(f,"%s ova%d; /* Output value accumulator */",a->ords[f->iafvt].name,i); } for (; i < f->ian; i++) { line(f,"%s ova%d; /* Output value partial accumulator */",a->ords[f->iapvt].name,i); } /* Context around interp/Simplex table lookup */ line(f, "{"); inc(f); if (!t->sort) line(f,"pointer swp;"); /* Declare Simplex weighting pointer */ line(f,"pointer imp;"); /* Declare Interpolation multidim pointer */ /* Declare the input weighting/vertex offset variables */ if (t->sort) { for (e = 0; e < g->id; e++) { if (t->wo_xs) { line(f,"%s we%d; /* Weighting value variable */", a->ords[f->wevt].name, e); line(f,"%s vo%d; /* Vertex offset variable */", a->ords[f->vovt].name, e); } else { line(f,"%s wo%d; /* Weighting value and vertex offset variable */", a->ords[f->wovt].name, e); } } } /* Context around input table processing */ line(f, "{"); inc(f); /* Declare the table index variables/input weighting/vertex offset variables */ if (t->sort) { if (!t->it_xs) line(f,"%s ti; /* Input table entry variable */",a->ords[f->itvt].name); line(f,"%s ti_i; /* Interpolation index variable */",a->ords[f->ixvt].name); } else { if (t->it_xs) { line(f,"%s ti_s; /* Simplex index variable */",a->ords[f->sxvt].name); line(f,"%s ti_i; /* Interpolation index variable */",a->ords[f->ixvt].name); } else { line(f,"%s ti; /* Simplex+Interpolation index variable */",a->ords[f->itvt].name); } } if (g->in.packed != 0) /* We need to unpack from a single read */ line(f,"%s rdv; /* Read value */",a->ords[f->ipt[0]].name); if (t->it_ix == 0) { int bv = 0; for (e = 0; e < f->nip; e++) { /* Find largest input type */ if (f->ipt[e] > bv) bv = f->ipt[e]; } bv = nord(f, bv); line(f,"%s chv; /* Channel value */",a->ords[bv].name); f->chv_bits = a->ords[bv].bits; } cr(f);#ifdef VERBOSE printf("Read code\n"); fflush(stdout);#endif /* VERBOSE */ /* For all the input channels */ for (e = 0; e < g->id; e++) { char rde[50]; /* Read expression */ char toff[50]; /* Table offset expression */ int ee = (g->in.pint != 0) ? 0 : e; /* bpch index */ if (g->in.pint != 0) /* Pixel interleaved */ sprintf(rde,"ip0[%d]",e); /* Offset from single pointer */ else sprintf(rde,"*ip%d",e); /* Pointer per channel */ if (g->in.packed != 0) { if (e == 0) line(f,"rdv = %s;",rde); /* Do single read */ sprintf(rde,"rdv"); /* Use read value for extraction */ } if (t->it_ix == 0) { if (g->in.bov[e] == 0 ) { /* No offset */ if (g->in.bpv[e] == g->in.bpch[ee]) /* No mask */ line(f,"chv = %s;",rde); else /* Just mask */ line(f,"chv = (%s & %s);",rde, hmask(g->in.bpv[e])); } else { /* Offset */ if ((g->in.bov[e] + g->in.bpv[e]) == g->in.bpch[ee]) line(f,"chv = (%s >> %d);",rde, g->in.bov[e]); else { /* Offset and mask */ if (a->shfm || g->in.bpv[e] > 32) { /* Extract using just shifts */ line(f,"chv = ((%s << %d) >> %d);", rde, f->chv_bits - g->in.bpv[e] - g->in.bov[e], f->chv_bits - g->in.bpv[e]); } else { /* Extract using shift and mask */ line(f,"chv = ((%s >> %d) & %s);", rde, g->in.bov[e], hmask(g->in.bpv[e])); } } } sprintf(toff,"chv"); } else { /* No extraction */ sprintf(toff,"%s",rde); } if (t->sort) { if (t->it_xs) { line(f,"ti_i %s= IT_IX(it%d, %s);", e ? "+" : " ", e, toff); if (t->wo_xs) { line(f,"we%d = IT_WE(it%d, %s);", e, e, toff); line(f,"vo%d = IT_VO(it%d, %s);", e, e, toff); } else { line(f,"wo%d = IT_WO(it%d, %s);", e, e, toff); } } else { /* All three combined */ line(f,"ti = IT_IT(it%d, %s);", e, toff); if (a->shfm || t->wo_ab > 32) { /* Extract using just shifts */ line(f,"wo%d = ((ti << %d) >> %d); " "/* Extract weighting/vertex offset value */", e, a->ords[f->wovt].bits - t->wo_ab, a->ords[f->wovt].bits - t->wo_ab); line(f,"ti_i %s= (ti >> %d); " "/* Extract interpolation table value */", e ? "+" : " ", t->wo_ab); } else { /* Extract using shift and mask */ line(f,"wo%d = (ti & %s); " "/* Extract weighting/vertex offset value */", e, hmask(t->wo_ab)); line(f,"ti_i %s= (ti >> %d); " "/* Extract interpolation table value */", e ? "+" : " ", t->wo_ab); } } } else { /* Simplex */ if (t->it_xs) { /* ~~~~ should toff be forced to be a temp variable ?? */ /* (ie. force use of rde (above) if t->it_xs is nonz) */ line(f,"ti_i %s= IT_IX(it%d, %s);", e ? "+" : " ", e, toff); line(f,"ti_s %s= IT_SX(it%d, %s);", e ? "+" : " ", e, toff); } else { line(f,"ti %s= IT_IT(it%d, %s);", e ? "+" : " ", e, toff); } } }#ifdef VERBOSE printf("Index extraction code\n"); fflush(stdout);#endif /* VERBOSE */ cr(f); if (t->sort) { /* Extract Simplex and Interpolation indexes from accumulator */ line(f,"imp = im_base + IM_O(ti_i); /* Compute interp. table entry pointer */"); } else { if (t->it_xs) { /* Extract Simplex and Interpolation indexes from accumulator */ line(f,"swp = sw_base + SW_O(ti_s); /* Compute simplex table entry pointer */"); line(f,"imp = im_base + IM_O(ti_i); /* Compute interp. table entry pointer */"); } else { line(f,"imp = im_base + IM_O(ti >> %d); " "/* Extract interp. index and comp. entry */", t->sx_ab); if (a->shfm || t->sx_ab > 32) { /* Extract using just shifts */ line(f,"swp = sw_base + SW_O((ti << %d) >> %d); " "/* Extract simplex index & comp. entry */", a->ords[f->itvt].bits - t->sx_ab, a->ords[f->itvt].bits - t->sx_ab); } else { /* Extract using shift and mask */ line(f,"swp = sw_base + SW_O(ti & %s); " "/* Extract simplex index and comp. entry */", hmask(t->sx_ab)); } } } /* Do the explicit sort now */ if (t->sort) { cr(f); /* Sort from largest to smallest using a selection sort */ /* Use simple sequence for the moment. More elaborate sequence */ /* may allow other optimisations. */ line(f,"/* Sort weighting values and vertex offset values */"); for (i = 0; i < (g->id-1); i++) { for (e = i+1; e < g->id; e++) { if (t->wo_xs) line(f,"CEX(we%d, vo%d, we%d, vo%d);",i,i,e,e); else line(f,"CEX(wo%d, wo%d);",i,e); } } } /* End of input table processing context */ dec(f); line(f,"}"); line(f,"{"); /* Context around vertex lookup and accumulation */ inc(f); /* Declare vertex offset and weight variables */ if (t->sort && t->wo_xs == 0) { line(f,"%s nvof; /* Next vertex offset value */",a->ords[f->vovt].name); } else { if (!t->wo_xs) /* If combined in table */ line(f,"%s vowr; /* Vertex offset/weight value */",a->ords[f->wovt].name); } line(f,"%s vof; /* Vertex offset value */",a->ords[f->vovt].name); line(f,"%s vwe; /* Vertex weighting */",a->ords[f->wevt].name); if (timp && t->im_fn > 1) line(f,"pointer timp; /* Temporary interpolation table pointer */"); cr(f);#ifdef VERBOSE printf("Vertex offset and weight code\n"); fflush(stdout);#endif /* VERBOSE */ /* For each vertex in the simplex */ for (e = 0; e < (g->id +1); e++) { if (t->sort) { if (e == 0) { line(f,"vof = 0; /* First vertex offset is 0 */"); } else { if (t->wo_xs) line(f,"vof += vo%d; /* Move to next vertex */",e-1); else line(f,"vof += nvof; /* Move to next vertex */"); } /* Extract the vertex offset and weight values from the sorted input values */ if (e < g->id && !t->wo_xs) { if (a->shfm || t->vo_ab > 32) { /* Extract using just shifts */ line(f,"nvof = ((wo%d << %d) >> %d); " "/* Extract offset value */", e, a->ords[f->vovt].bits - t->vo_ab, a->ords[f->vovt].bits - t->vo_ab); line(f,"wo%d = (wo%d >> %d); " " /* Extract weighting value */", e, e, t->vo_ab); } else { /* Extract using shift and mask */ line(f,"nvof = (wo%d & %s); " "/* Extract offset value */", e, hmask(t->vo_ab)); line(f,"wo%d = (wo%d >> %d); " " /* Extract weighting value */", e, e, t->vo_ab); } } /* Compute the weighting value */ if (!t->wo_xs) { if (e == 0) { line(f,"vwe = %d - wo%d; /* Baricentric weighting */", 1 << g->prec, e); } else if (e < g->id) { line(f,"vwe = wo%d - wo%d; /* Baricentric weighting */", e-1, e); } else { line(f,"vwe = wo%d; /* Baricentric weighting */", e-1); } } else { if (e == 0) { line(f,"vwe = %d - we%d; /* Baricentric weighting */", 1 << g->prec, e); } else if (e < g->id) { line(f,"vwe = we%d - we%d; /* Baricentric weighting */", e-1, e); } else { line(f,"vwe = we%d; /* Baricentric weighting */", e-1); } } } else { /* Not sort */ /* Read the vertex offset and weight values from the simplex table */ if (t->wo_xs) { /* If separate */ line(f,"vof = SX_VO(swp, %d); /* Read vertex offset value */", e); line(f,"vwe = SX_WE(swp, %d); /* Read vertex weighting value */", e); } else { /* If combined in table */ line(f,"vowr = SX_WO(swp, %d); /* Read vertex offset+weighting values */", e); if (a->shfm || t->vo_ab > 32) { /* Extract using just shifts */ line(f,"vof = ((vowr << %d) >> %d); " "/* Extract offset value */", a->ords[f->vovt].bits - t->vo_ab, a->ords[f->vovt].bits - t->vo_ab); line(f,"vwe = (vowr >> %d); " "/* Extract weighting value */", t->vo_ab); } else { /* Extract using shift and mask */ line(f,"vof = (vowr & %s); " "/* Extract offset value */", hmask(t->vo_ab)); line(f,"vwe = (vowr >> %d); " "/* Extract weighting value */", t->vo_ab); } } } /* Lookup the vertex value, weight it, and accumulate it into output value */ if (timp && t->im_fn > 1) line(f,"timp = IM_TP(imp, vof); /* Vertex address */"); for (i = 0; i < f->ian; i++) { /* For each output accumulation chunk */ if (i < t->im_fn) { /* Full entry */ if (!timp || t->im_fn == 1) line(f,"ova%d %s= IM_FE(imp, vof, %d) * vwe; " "/* Accumulate weighted output values */", i, e ? "+" : " ", i); else line(f,"ova%d %s= IM_FE(timp, %d) * vwe; " "/* Accumulate weighted output values */", i, e ? "+" : " ", i); } else /* One partial entry */ line(f,"ova%d %s= IM_PE(imp, vof) * vwe; " "/* Accumulate last weighted output values */", i, e ? "+" : " "); } } dec(f); line(f, "}"); /* End of output value lookup context */ dec(f); line(f, "}"); /* End of output value accumulation context */ /* Start of output lookup and write */ line(f,"{"); inc(f);#ifdef VERBOSE printf("Output table code\n"); fflush(stdout);#endif /* VERBOSE */ { char wre[50]; /* Write destination expression */ if (g->out.packed != 0) /* We need to pack results into a single write */ line(f,"%s wrv; /* Write value */",a->ords[f->ipt[0]].name); /* Declare temporary to hold index into output lookup table */ line(f,"%s oti; /* Vertex offset value */",a->ords[f->otit].name); /* For each accumulator value */ /* (Assume they are in output order for the moment ?) */ for (e = i = 0; i < f->ian; i++) { /* For each output accumulation chunk */ int vpa = i < t->im_fn ? t->im_fv : t->im_pv; /* Chanel values per accumulator */ int oat = i < t->im_fn ? f->iafvt : f->iapvt; /* Output accumulator type */ int ee; /* Relative e to this accumulator */ /* For each output value in this accumulator */ for (ee = 0; ee < vpa && e < g->od; ee++, e++) { int off, size; /* Bits to be extracted */ /* Extract wanted 8 bits from the 8.8 bit result in accumulator */ off = ee * f->iaovb + (f->iaovb - g->prec); size = g->prec; if (e == 0 || g->out.packed == 0) { if (g->out.pint != 0) /* Pixel interleaved */ sprintf(wre,"op0[%d]",e); /* Offset from single pointer */ else sprintf(wre,"*op%d",e); /* Pointer per channel */ } if (a->shfm || size > 32) { /* Extract using just shifts */ line(f,"oti = ((ova%d << %d) >> %d); " "/* Extract integer part of result */", i, a->ords[oat].bits - off - size, a->ords[oat].bits - size); } else { /* Extract using shift and mask */ line(f,"oti = ((ova%d >> %d) & %s); " "/* Extract integer part of result */", i, off, hmask(size)); } /* Lookup in output table and write to destination */ if (g->out.packed != 0) { line(f,"wrv %s= OT_E(ot%d, oti);", e ? "+" : "", e); } else { line(f,"%s = OT_E(ot%d, oti); /* Write result */", wre, e); } } } if (g->out.packed != 0) { /* Write out the accumulated value */ line(f,"%s = wrv; /* Write result */", wre); } } /* The end of the output lookup and write */ dec(f); line(f, "}");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -