/* return a pointer to twiddles (0 if none) starting at mstart out of m */ const R *X(twiddle_shift)(const twid *p, INT mstart) { if (p) { INT ntwiddle, vl; ntwiddle = twlen0(p->r, p->instr, &vl); A((mstart % vl) == 0); return (p->W + (mstart / vl) * ntwiddle); } else { return 0; } }
static R *compute(enum wakefulness wakefulness, const tw_instr *instr, INT n, INT r, INT m) { INT ntwiddle, j, vl; R *W, *W0; const tw_instr *p; triggen *t = X(mktriggen)(wakefulness, n); p = instr; ntwiddle = twlen0(r, p, &vl); A(m % vl == 0); W0 = W = (R *)MALLOC((ntwiddle * (m / vl)) * sizeof(R), TWIDDLES); for (j = 0; j < m; j += vl) { for (p = instr; p->op != TW_NEXT; ++p) { switch (p->op) { case TW_FULL: { INT i; for (i = 1; i < r; ++i) { A((j + (INT)p->v) * i < n); A((j + (INT)p->v) * i > -n); t->cexp(t, (j + (INT)p->v) * i, W); W += 2; } break; } case TW_HALF: { INT i; A((r % 2) == 1); for (i = 1; i + i < r; ++i) { t->cexp(t, MULMOD(i, (j + (INT)p->v), n), W); W += 2; } break; } case TW_COS: { R d[2]; A((j + (INT)p->v) * p->i < n); A((j + (INT)p->v) * p->i > -n); t->cexp(t, (j + (INT)p->v) * (INT)p->i, d); *W++ = d[0]; break; } case TW_SIN: { R d[2]; A((j + (INT)p->v) * p->i < n); A((j + (INT)p->v) * p->i > -n); t->cexp(t, (j + (INT)p->v) * (INT)p->i, d); *W++ = d[1]; break; } case TW_CEXP: A((j + (INT)p->v) * p->i < n); A((j + (INT)p->v) * p->i > -n); t->cexp(t, (j + (INT)p->v) * (INT)p->i, W); W += 2; break; } } } X(triggen_destroy)(t); return W0; }
INT X(twiddle_length)(INT r, const tw_instr *p) { INT vl; return twlen0(r, p, &vl); }