📄 cgen.c
字号:
t->wo_xs = 0; t->wo_es = a->ords[combt].bits/8; /* entry size in bytes for each entry */ t->wo_ab = a->ords[combt].bits; /* bits in weightig + offset */ t->we_ab = f->wemnb; /* bits available for weighting */ t->vo_ab = t->wo_ab - t->we_ab; /* Allow all spare bits to vertex offset */ t->wo_eo = t->ix_es; /* entry offset in input table */ t->it_ts += t->wo_es; /* Final input table size */ f->woet = combt; /* Variable type for accessing combined entry */ f->wovt = nord(f, combt); /* Variable type holding weight/offset read value */ if ((f->wevt = findnord(f, t->we_ab)) < 0) { fprintf(stderr,"Can't find variable size to hold weighting factor\n"); exit(-1); } if ((f->vovt = findnord(f, t->vo_ab)) < 0) { fprintf(stderr,"Can't find variable size to hold vertex offset index\n"); exit(-1); } } }#ifdef VERBOSE /* Summarise the input table arrangements */ printf("\n"); printf("Input table structure:\n"); printf(" Input value re-ordering is ["); for (e = 0; e < g->id; e++) printf("%s%d",e > 0 ? " " : "", t->it_map[e]); printf("]\n"); printf(" Input table entry size = %d bytes\n",t->it_ts); if (t->it_ix) { printf(" Input table extracts value from read values\n"); if (t->wo_xs) { printf(" Separate Interp., Weighting and Offset values\n"); printf(" Interp. index is at offset %d, size %d bytes\n",t->ix_eo, t->ix_es); printf(" Weighting is at offset %d, size %d bytes\n",t->we_eo, t->we_es); printf(" Vertex offset is at offset %d, size %d bytes\n",t->vo_eo, t->vo_es); } else { printf(" Separate Interp. index and Weightint+Offset value\n"); printf(" Interp. index is at offset %d, size %d bytes\n",t->ix_eo, t->ix_es); printf(" Weighting+Offset is at offset %d, size %d bytes\n",t->wo_eo, t->wo_es); printf(" Weighting = %d bits\n",t->we_ab); printf(" Vertex offset = %d bits\n",t->vo_ab); } } else { printf(" Combined InterpIndex+Weighting+Voffset values\n"); printf(" Values are stored in size %d bytes\n",t->it_ts); printf(" Interp. index = %d bits\n",t->ix_ab); printf(" Weighting = %d bits\n",t->we_ab); printf(" Vertex offset = %d bits\n",t->vo_ab); }#endif /* VERBOSE */ } else { /* Simplex table */ /* If we are going to use a simplex table, figure out how we */ /* will store the weighting value and vertex offset values in it, */ /* as well as the size of index we'll need to address it. */ int wit, oft, bigt; /* weighting type, offset type, biggest type */ int combt; /* Combined type */ int sepbits, combits; /* Total separate, combined bits */ /* See if we can fit them into separately readable entries, or whether */ /* they should be combined to minimise overall table size. */ if ((wit = findord(f, f->wemnb)) < 0) { fprintf(stderr,"Can't find entry size to hold weighting factor\n"); exit(-1); } if ((oft = findord(f, f->vomnb)) < 0) { fprintf(stderr,"Can't find entry size to hold vertex offset index\n"); exit(-1); } bigt = wit > oft ? wit : oft; /* Bigest separate type */ if ((combt = findord(f, f->wemnb + f->vomnb)) < 0) {/* Combined isn't possible */ sepbits = 2 * a->ords[bigt].bits; /* Total separate bits */ combits = sepbits; /* Force separate entries */ } else { sepbits = 2 * a->ords[bigt].bits; /* Total separate bits */ combits = a->ords[combt].bits; /* Total combined bits */ } if (sepbits <= combits) { /* We will use separate entries */ t->wo_xs = 1; t->we_es = a->ords[bigt].bits/8; /* size in bytes for weighting entry */ t->we_ab = a->ords[bigt].bits; /* bits available for weighting */ t->we_eo = 0; /* Entry offset in simplex table */ t->vo_es = a->ords[bigt].bits/8; /* size in bytes for vertex offset entry */ t->vo_ab = a->ords[bigt].bits; /* bits available for vertex offset */ t->vo_eo = t->we_es; /* Entry offset in simplex table */ t->wo_es = t->we_es + t->vo_es; /* Total entry size for each vertex */ t->sm_ts = (g->id + 1) * (t->we_es + t->vo_es) ; /* Total size in bytes */ f->weet = bigt; /* Variable type for accessing weighting entry */ f->voet = bigt; /* Variable type for accessing vertex offset entry */ f->wevt = nord(f, wit); /* Variable type for holding weight value */ f->vovt = nord(f, oft); /* Variable type for holding offset value */ } else { /* We will combine the two entries */ t->wo_xs = 0; t->wo_es = a->ords[combt].bits/8; /* entry size in bytes for each entry */ t->wo_ab = a->ords[combt].bits; /* bits in weightig + offset */ t->we_ab = f->wemnb; /* bits available for weighting */ t->vo_ab = t->wo_ab - t->we_ab; /* Allow all spare bits to vertex offset */ t->wo_eo = 0; /* entry offset in simplex table */ t->sm_ts = (g->id + 1) * t->wo_es; /* Total size in bytes */ f->woet = combt; /* Variable type for accessing combined entry */ f->wovt = nord(f, combt); /* Variable type holding weight/offset read value */ if ((f->wevt = findnord(f, t->we_ab)) < 0) { fprintf(stderr,"Can't find variable size to hold weighting factor\n"); exit(-1); } if ((f->vovt = findnord(f, t->vo_ab)) < 0) { fprintf(stderr,"Can't find variable size to hold vertex offset index\n"); exit(-1); } } /* Compute the number of bits needed to hold an index into */ /* the simplex table (index is in terms of table entry size). */ /* This value is used to figure out the room needed in the input */ /* table to accumulate the simplex cube base offset value. (SW_O macro) */ f->sxmnb = calc_bits(g->id, g->stres);#ifdef VERBOSE /* Summarise the simplex table arrangements */ printf("\n"); printf("Simplex table structure:\n"); printf(" Minimum bits needed to index table %d\n", f->sxmnb); printf(" Total simplex entry size %d bytes to hold %d entries\n",t->sm_ts, g->id+1); if (t->wo_xs) { printf(" Separate entries for offset and weight\n"); printf(" Weighting entry size %d bytes\n",t->we_es); printf(" Offset entry size %d bytes\n",t->vo_es); } else { printf(" Combined offset and weight entries in %d bytes\n",t->wo_es); printf(" Weighting entry size %d bits\n",t->we_ab); printf(" Offset entry size %d bits\n",t->vo_ab); } printf(" Vertex offset scale factor %d\n", t->vo_om);#endif /* VERBOSE */ /* We known how big the interpolation and simplex */ /* tables indexes are going to be, so complete figuring out */ /* how big the input table entries have to be. */ if ((f->itet = findord(f, f->sxmnb + f->ixmnb)) >= 0) {/* size to read */ int rem; /* Remainder bits */ t->it_xs = 0; /* Combined simplex+interp index */ t->it_ab = a->ords[f->itet].bits; /* Bits in combined input entry */ rem = t->it_ab - f->sxmnb - f->ixmnb; t->sx_ab = f->sxmnb + rem/2; /* simplex index bits actually available */ t->ix_ab = t->it_ab - t->sx_ab; /* interp index bits actually available */ t->it_ts = a->ords[f->itet].bits/8; /* total size in bytes */ f->itvt = nord(f, f->itet); /* Variable type */ if ((f->sxvt = findnord(f, t->sx_ab)) < 0) { fprintf(stderr,"Simplex index variable size can't be handled\n"); exit(-1); } if ((f->ixvt = findnord(f, t->ix_ab)) < 0) { fprintf(stderr,"Interp index variable size can't be handled\n"); exit(-1); } } else { /* Separate entries */ int bbits; /* Largest number of bits needed */ t->it_xs = 1; /* Separate simplex+interp indexes */ bbits = f->sxmnb > f->ixmnb ? f->sxmnb : f->ixmnb; /* Allocate same size for both so that total structure size is power of 2 */ if ((f->sxet = f->ixet = findord(f, bbits)) < 0) { fprintf(stderr,"Interp/Simplex index entry size can't be handled\n"); exit(-1); } t->sx_ab = a->ords[f->sxet].bits; /* Actual bits available */ t->sx_es = t->sx_ab/8; /* Entry size in bytes */ t->ix_ab = a->ords[f->ixet].bits; t->ix_es = t->sx_ab/8; t->it_ts = t->sx_es + t->ix_es; /* total size in bytes */ t->sx_eo = 0; /* simplex index offset in bytes */ t->ix_eo = t->sx_es; /* interp. index offset in bytes */ f->sxvt = nord(f, f->sxet); /* Variable type */ f->ixvt = nord(f, f->ixet); /* Variable type */ }#ifdef VERBOSE /* Summarise the input table arrangements */ printf("\n"); printf("Input table structure:\n"); if (t->it_ix) { printf(" Input table extracts value from read values\n"); } else { printf(" Value extraction read values is explicit\n"); } printf(" Input value re-ordering is ["); for (e = 0; e < g->id; e++) printf("%s%d",e > 0 ? " " : "", t->it_map[e]); printf("]\n"); printf(" Input table entry size = %d bytes\n",t->it_ts); if (t->it_xs) { printf(" Separate Interp. and Simplex index values\n"); printf(" Interp. index is at offset %d, size %d bytes\n",t->ix_eo, t->ix_es); printf(" Simplex index is at offset %d, size %d bytes\n",t->sx_eo, t->sx_es); } else { printf(" Combined Interp. and Simplex index values\n"); printf(" Values are size %d bytes\n",t->it_ts); printf(" Interp. index = %d bits\n",t->ix_ab); printf(" Simplex index = %d bits\n",t->sx_ab); }#endif /* VERBOSE */ } /* Figure out output table stuff */ { /* A variable to hold the index into an output table */ if ((f->otit = findord(f, g->prec)) < 0) { fprintf(stderr,"Can't find output table index size\n"); exit(-1); } f->otit = nord(f,f->otit); /* Make temp variable natural size */ if (g->out.pint != 0) /* Pixel interleaved */ f->nop = 1; else f->nop = g->od; /* Figure out the output pointer types */ f->otvt = 0; /* Output table value type */ for (e = 0; e < f->nop; e++) { if ((f->opt[e] = findord(f, g->out.bpch[e])) < 0) { fprintf(stderr,"Output channel size can't be handled\n"); exit(-1); } if (f->opt[e] > f->otvt) f->otvt = f->opt[e]; /* Make value type big enough for any channel size */ } t->ot_ts = a->ords[f->otvt].bits/8; /* Output table entry size in bytes */ /* Setup information on data placement in output table enries */ for (e = 0; e < g->od; e++) { t->ot_off[e] = g->out.bov[e]; /* Transfer info from generation spec. */ t->ot_bits[e] = g->out.bpv[e]; } }#ifdef VERBOSE /* Summarise the output table arrangements */ printf(" Output value re-ordering is ["); for (e = 0; e < g->od; e++) printf("%s%d",e > 0 ? " " : "", t->im_map[e]); printf("]\n"); printf("\n"); printf("Output table structure:\n"); printf(" Entry size = %d bytes\n",t->ot_ts); printf(" Output value placement within each enry is:\n"); for (e = 0; e < f->nop; e++) { printf(" %d: Offset %d bits, size %d bits\n", e, t->ot_off[e], t->ot_bits[e]); }#endif /* VERBOSE */ /* Compute the maximum interpolation table resolution we will be able to handle */ { int res, ores; res = calc_res(g->id, t->ix_ab); ores = calc_ores(g->id, t->vo_ab, t->vo_om); f->ixmxres = res < ores ? res : ores; } /* Compute the maximum simplex table resolution we will be able to handle */ if (t->sort) { f->sxmxres = 0; } else { f->sxmxres = calc_res(g->id, t->sx_ab); }#ifdef VERBOSE printf("Emitting introductory code\n"); fflush(stdout);#endif /* VERBOSE */ /* Start of code generation */ doheader(f); /* Output the header comments */ /* We need an include file */ line(f,"#ifndef IMDI_INCLUDED"); line(f,"#include <memory.h>"); line(f,"#include \"imdi_imp.h\""); line(f,"#define IMDI_INCLUDED"); line(f,"#endif /* IMDI_INCLUDED */"); cr(f); /* Declare our explicit pointer type */ line(f,"#ifndef DEFINED_pointer"); line(f,"#define DEFINED_pointer"); line(f,"typedef unsigned char * pointer;"); line(f,"#endif"); cr(f); /* Declare our explicit structure access macros */#ifdef VERBOSE printf("Declaring macros\n"); fflush(stdout);#endif /* VERBOSE */ /* Macros for accessing input table entries */ if (t->sort) { if (t->it_xs) { line(f,"/* Input table interp. index */"); line(f,"#define IT_IX(p, off) *((%s *)((p) + %d + (off) * %d))", a->ords[f->ixet].name, t->ix_eo, t->it_ts); cr(f); if (t->wo_xs) { line(f,"/* Input table input weighting enty */"); line(f,"#define IT_WE(p, off) *((%s *)((p) + %d + (off) * %d))", a->ords[f->weet].name, t->we_eo, t->it_ts); cr(f); line(f,"/* Input table input offset value enty */"); line(f,"#define IT_VO(p, off) *((%s *)((p) + %d + (off) * %d))", a->ords[f->voet].name, t->vo_eo, t->it_ts); cr(f); } else { line(f,"/* Input table input weighting/offset value enty */"); line(f,"#define IT_WO(p, off) *((%s *)((p) + %d + (off) * %d))", a->ords[f->woet].name, t->wo_eo, t->it_ts); cr(f); } } else { line(f,"/* Input table interp index, weighting and vertex offset */"); line(f,"#define IT_IT(p, off) *((%s *)((p) + %d + (off) * %d))", a->ords[f->itet].name, 0, t->it_ts); cr(f); } /* Macro to conditionally exchange two varibles */ /* Doing this in place using an xor seems to be fastest */ /* on most architectures. */ line(f,"/* Conditional exchange for sorting */"); if (t->wo_xs) { line(f,"#define CEX(A, AA, B, BB) if (A < B) { \\"); line(f," A ^= B; B ^= A; A ^= B; AA ^= BB; BB ^= AA; AA ^= BB; }"); } else line(f,"#define CEX(A, B) if (A < B) { A ^= B; B ^= A; A ^= B; }"); cr(f); } else { /* Simplex table */ if (t->it_xs) { line(f,"/* Input table interp. index */"); line(f,"#define IT_IX(p, off) *((%s *)((p) + %d + (off) * %d))", a->ords[f->ixet].name, t->ix_eo, t->it_ts); cr(f); line(f,"/* Input table simplex index enty */"); line(f,"#define IT_SX(p, off) *((%s *)((p) + %d + (off) * %d))", a->ords[f->sxet].name, t->sx_eo, t->it_ts); cr(f); } else { line(f,"/* Input table inter & simplex indexes */"); line(f,"#define IT_IT(p, off) *((%s *)((p) + %d + (off) * %d))", a->ords[f->itet].name, 0, t->it_ts); cr(f); } } if (!t->sort) { /* Macro for computing a simplex table entry */ line(f,"/* Simplex weighting table access */"); line(f,"#define SW_O(off) ((off) * %d)", t->sm_ts); cr(f); /* Macros for accessing the contents of the simplex table */ if (t->wo_xs) { /* If separate */ line(f,"/* Simplex table - get weighting value */"); line(f,"#define SX_WE(p, v) *((%s *)((p) + (v) * %d + %d))", a->ords[f->weet].name, t->wo_es, t->we_eo); cr(f); line(f,"/* Simplex table - get offset value */"); line(f,"#define SX_VO(p, v) *((%s *)((p) + (v) * %d + %d))", a->ords[f->voet].name, t->wo_es, t->vo_eo); cr(f); } else { /* Combined */ line(f,"/* Simplex table - get weighting/offset value */"); line(f,"#define SX_WO(p, v) *((%s *)((p) + (v) * %d))", a->ords[f->woet].name, t->wo_es); cr(f); } } /* Macro for computing an interpolation table entry */ line(f,"/* Interpolation multi-dim. table access */"); line(f,"#define IM_O(off) ((off) * %d)", t->im_ts); cr(f); /* Macro for accessing an entry in the interpolation table */ line(f,"/* Interpolation table - get vertex values */"); if (t->im_fn > 0) { /* Arguments to macro are cell base address, vertex offset, data offset */ if (f->imfvt == f->iafvt) { /* Table and accumulator are the same size */ if (!timp || t->im_fn == 1) line(f,"#define IM_FE(p, v, c) *((%s *)((p) + (v) * %d + (c) * %d))", a->ords[f->imfvt].name, t->im_oc, t->im_fs); else { line(f,"#define IM_TP(p, v) ((p) + (v) * %d)", t->im_oc); line(f,"#define IM_FE(p, c) *((%s *)((p) + (c) * %d))", a->ords[f->imfvt].name, t->im_fs); } } else { /* Expand single table entry to accumulator size */ if (!timp || t->im_fn == 1) line(f,"#define IM_FE(p, v, c) ((%s)*((%s *)((p) + (v) * %d + (c) * %d)))", a->ords[f->iafvt].name, a->ords[f->imfvt].name, t->im_oc, t->im_fs); else { line(f,"#define IM_TP(p, v) ((p) + (v) * %d)", t->im_oc); line(f,"#define IM_FE(p, c) ((%s)*((%s *)((p) + (c) * %d)))", a->ords[f->iafvt].name, a->ords[f->imfvt].name, t->im_fs); } } } if (t->im_pn > 0) { /* Arguments to macro are cell base address, vertex offset */ /* There is no data offset since there can be only be one partial entry */ if (f->imfvt == f->iafvt) /* Table and accumulator are the same size */ line(f,"#define IM_PE(p, v) *((%s *)((p) + %d + (v) * %d))", a->ords[f->impvt].name, t->im_fn * t->im_fs, t->im_oc); else /* Expand single table entry to accumulator size */ line(f,"#define IM_PE(p, v) ((%s)*((%s *)((p) + %d + (v) * %d)))", a->ords[f->iafvt].name, a->ords[f->impvt].name, t->im_fn * t->im_fs, t->im_oc); } cr(f); /* Macro for accessing an output table entry */ line(f,"/* Output table indexes */"); line(f,"#define OT_E(p, off) *((%s *)((p) + (off) * %d))", a->ords[f->otvt].name, t->ot_ts); cr(f); /* =============================================== */#ifdef VERBOSE printf("Starting interpolation function\n"); fflush(stdout);#endif /* VERBOSE */ /* Declare the function */ line(f,"void"); line(f, "imdi_k%d(",index); line(f, "imdi *s, /* imdi context */"); line(f, "void **outp, /* pointer to output pointers */"); line(f, "void **inp, /* pointer to input pointers */"); line(f, "unsigned int npix /* Number of pixels to process */"); line(f, ") {"); inc(f); /* We need access to the imdi_imp */ line(f, "imdi_imp *p = (imdi_imp *)(s->impl);");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -