
/* $Id: saol_core_opcodes.c,v 1.6 1997/11/20 18:36:36 eds Exp $ */
/* $Log: saol_core_opcodes.c,v $
 * Revision 1.6  1997/11/20  18:36:36  eds
 * midicc() core opcode for current SASBF implementation.
 *
 * Revision 1.9  1997/11/15 00:43:17  luked
 * This is the result of the manual merge from the vendor branch for the
 * release tagged Fribourg_after_integration. I (brian) have probably lost
 * some history, but oh well.
 *
 * This contains the integration work by Eric Scheirer (MIT).
 *
 * Revision 1.5  1997/11/10  23:00:32  eds
 * Added fir(), iir(), iirt().
 *
 * Revision 1.4  1997/11/05  20:46:12  eds
 * Added kdump(), adump().
 *
 * Revision 1.3  1997/11/05  14:59:54  eds
 * Added vector parameters/return values/operators.
 * Fixed rates of table info opcodes.
 *
 * Revision 1.2  1997/10/01  15:32:54  eds
 * Added firt() opcode.
 * */
/*********************************************************************

This software module was originally developed by

Eric D. Scheirer (MIT Media Laboratory)

in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard
ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an
implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools
as specified by the MPEG-2 NBC/MPEG-4 Audio standard.  ISO/IEC gives
users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this
software module or modifications thereof for use in hardware or
software products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audio
standards. Those intending to use this software module in hardware or
software products are advised that this use may infringe existing
patents. The original developer of this software module and his/her
company, the subsequent editors and their companies, and ISO/IEC have
no liability for use of this software module or modifications thereof
in an implementation.

This software module is hereby released into the public domain.

***********************************************************************/

#include <stdlib.h>
#include <string.h>
#include "saol.h"
#include "y.tab.h"
#include "saol_co_imp.h"



struct core_opcode_struct core_opcodes[] =  {
  {"int",            OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_int },
  {"frac",           OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_frac },
  {"dbamp",          OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_dbamp },
  {"ampdb",          OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_ampdb },
  {"abs",            OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_abs },
  {"exp",            OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_exp },
  {"log",            OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_log },
  {"sqrt",           OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_sqrt },
  {"sin",            OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_sin },
  {"cos",            OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_cos },
  {"atan",           OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_atan },
  {"pow",           OPCODE,  XSIG,     XSIG,    -1,    -1,    -1,   -1,   -1,                        0, co_atan },
  {"atan",           OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_atan },
  {"log10",           OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_log10 },
  {"asin",           OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_asin },
  {"acos",           OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_cos },
  {"floor",           OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_floor },
  {"ceil",           OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_ceil },
  {"min",           OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   XSIG,                        0, co_min },
  {"max",         OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,     XSIG,                        0, co_max },
  {"pchoct",         OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_pchoct },
  {"cpspch",         OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_cpspch },
  {"pchcps",         OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_pchcps },
  {"cpsoct",         OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_cpsoct },
  {"octcps",         OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_octcps },
  {"pchmidi",        OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_pchmidi },
  {"midipch",        OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_midipch },
  {"octmidi",        OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_octmidi },
  {"midioct",        OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_midioct },
  {"cpsmidi",        OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_cpsmidi },
  {"midicps",        OPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_midicps },
  {"ftlen",          OPCODE, TABLE,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_ftlen },
  {"ftloop",         OPCODE, TABLE,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_ftloop },
  {"ftloopend",      OPCODE, TABLE,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_ftloopend },
  {"ftsr",           OPCODE, TABLE,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_ftsr },
  {"ftbasecps",      OPCODE, TABLE,    -1,    -1,    -1,    -1,   -1,   -1,                        0, co_ftbasecps },
  {"tableread",      OPCODE, TABLE,  XSIG,    -1,    -1,    -1,   -1,   -1,                        0, co_tableread },
  {"tablewrite",     OPCODE, TABLE,  XSIG,  XSIG,    -1,    -1,   -1,   -1,                        0, co_tablewrite },
  {"oscil",         AOPCODE, TABLE,  XSIG, -IVAR,    -1,    -1,   -1,   -1,    sizeof(oscil_storage), co_oscil },
  {"loscil",        AOPCODE, TABLE,  XSIG, -IVAR, -IVAR, -IVAR,   -1,   -1,   sizeof(loscil_storage), co_loscil },
  {"doscil",        AOPCODE, TABLE,    -1,    -1,    -1,    -1,   -1,   -1,   sizeof(doscil_storage), co_doscil },
  {"koscil",        KOPCODE, TABLE,  KSIG, -IVAR,    -1,    -1,   -1,   -1,    sizeof(koscil_storage), co_koscil },
  {"kline",         KOPCODE,  IVAR,  IVAR,  IVAR,    -1,    -1,   -1, IVAR,    sizeof(kline_storage), co_kline },
  {"aline",         AOPCODE,  IVAR,  IVAR,  IVAR,    -1,    -1,   -1, IVAR,    sizeof(aline_storage), co_aline },
  {"kexpon",        KOPCODE,  IVAR,  IVAR,  IVAR,    -1,    -1,   -1, IVAR,   sizeof(kexpon_storage), co_kexpon },
  {"aexpon",        AOPCODE,  IVAR,  IVAR,  IVAR,    -1,    -1,   -1, IVAR,   sizeof(aexpon_storage), co_aexpon },
  {"kphasor",       KOPCODE,  KSIG,    -1,    -1,    -1,    -1,   -1,   -1,  sizeof(kphasor_storage), co_kphasor },
  {"aphasor",       AOPCODE,  XSIG,    -1,    -1,    -1,    -1,   -1,   -1,  sizeof(aphasor_storage), co_aphasor },
  {"pluck",         AOPCODE,  KSIG,  IVAR, TABLE,  IVAR,  IVAR, IVAR,   -1,    sizeof(pluck_storage), co_pluck },
  {"buzz",          AOPCODE,  XSIG,  KSIG,  KSIG,  KSIG,    -1,   -1,   -1,     sizeof(buzz_storage), co_buzz },
  {"fof",           AOPCODE,  XSIG,  XSIG, TABLE, TABLE,  KSIG,   -1,   -1,      sizeof(fof_storage), co_fof },
  {"irand",         IOPCODE,  IVAR,    -1,    -1,    -1,    -1,   -1,   -1,    sizeof(irand_storage), co_irand },
  {"krand",         KOPCODE,  KSIG,    -1,    -1,    -1,    -1,   -1,   -1,    sizeof(krand_storage), co_krand },
  {"arand",         AOPCODE,  ASIG,    -1,    -1,    -1,    -1,   -1,   -1,    sizeof(arand_storage), co_arand },
  {"ilinrand",      IOPCODE,  IVAR,  IVAR,    -1,    -1,    -1,   -1,   -1, sizeof(ilinrand_storage), co_ilinrand },
  {"klinrand",      KOPCODE,  KSIG,  KSIG,    -1,    -1,    -1,   -1,   -1, sizeof(klinrand_storage), co_klinrand },
  {"alinrand",      AOPCODE,  ASIG,  ASIG,    -1,    -1,    -1,   -1,   -1, sizeof(alinrand_storage), co_alinrand },
  {"iexprand",      IOPCODE,  IVAR,    -1,    -1,    -1,    -1,   -1,   -1, sizeof(iexprand_storage), co_iexprand },
  {"kexprand",      KOPCODE,  KSIG,    -1,    -1,    -1,    -1,   -1,   -1, sizeof(kexprand_storage), co_kexprand },
  {"aexprand",      AOPCODE,  ASIG,    -1,    -1,    -1,    -1,   -1,   -1, sizeof(aexprand_storage), co_aexprand },
  {"kpoissonrand",  KOPCODE,  KSIG,    -1,    -1,    -1,    -1,   -1,   -1, sizeof(kpoissonrand_storage), co_kpoissonrand },
  {"apoissonrand",  AOPCODE,  ASIG,    -1,    -1,    -1,    -1,   -1,   -1, sizeof(apoissonrand_storage), co_apoissonrand },
  {"igaussrand",    IOPCODE,  IVAR,  IVAR,    -1,    -1,    -1,   -1,   -1, sizeof(igaussrand_storage), co_igaussrand },
  {"kgaussrand",    KOPCODE,  KSIG,  KSIG,    -1,    -1,    -1,   -1,   -1, sizeof(kgaussrand_storage), co_kgaussrand },
  {"agaussrand",    AOPCODE,  ASIG,  ASIG,    -1,    -1,    -1,   -1,   -1, sizeof(agaussrand_storage), co_agaussrand },
  {"port",          KOPCODE,  KSIG,  KSIG,    -1,    -1,    -1,   -1,   -1,     sizeof(port_storage), co_port },
  {"hipass",        AOPCODE,  ASIG,  KSIG,    -1,    -1,    -1,   -1,   -1,   sizeof(hipass_storage), co_hipass },
  {"lopass",        AOPCODE,  ASIG,  KSIG,    -1,    -1,    -1,   -1,   -1,   sizeof(lopass_storage), co_lopass },
  {"bandpass",      AOPCODE,  ASIG,  KSIG,  KSIG,    -1,    -1,   -1,   -1, sizeof(bandpass_storage), co_bandpass },
  {"bandstop",      AOPCODE,  ASIG,  KSIG,  KSIG,    -1,    -1,   -1,   -1, sizeof(bandstop_storage), co_bandstop },
  {"fft",         SPECIALOP,  ASIG, TABLE, -IVAR, -IVAR, -IVAR,-TABLE,   -1,      sizeof(fft_storage), co_fft },
  {"ifft",          AOPCODE, TABLE, -IVAR, -IVAR, -IVAR,-TABLE,   -1,   -1,     sizeof(ifft_storage), co_ifft },
  {"rms",         SPECIALOP,  ASIG, -IVAR,    -1,    -1,    -1,   -1,   -1,      sizeof(rms_storage), co_rms },
  {"gain",          AOPCODE,  ASIG,  KSIG, -IVAR,    -1,    -1,   -1,   -1,     sizeof(gain_storage), co_gain },
  {"balance",       AOPCODE,  ASIG,  ASIG, -IVAR,    -1,    -1,   -1,   -1,  sizeof(balance_storage), co_balance },
  {"decimate",    SPECIALOP,  ASIG,    -1,    -1,    -1,    -1,   -1,   -1, sizeof(decimate_storage), co_decimate },
  {"upsamp",        AOPCODE,  KSIG,    -1,    -1,    -1,    -1,   -1,   -1,   sizeof(upsamp_storage), co_upsamp },
  {"downsamp",    SPECIALOP,  ASIG,    -1,    -1,    -1,    -1,   -1,   -1, sizeof(downsamp_storage), co_downsamp },
  {"samphold",       OPCODE,  XSIG,  KSIG,    -1,    -1,    -1,   -1,   -1, sizeof(samphold_storage), co_samphold },
  {"delay",         AOPCODE,  ASIG,  IVAR,    -1,    -1,    -1,   -1,   -1,    sizeof(delay_storage), co_delay },
  {"delay1",        AOPCODE,  ASIG,    -1,    -1,    -1,    -1,   -1,   -1,   sizeof(delay1_storage), co_delay1 },
  {"biquad",        AOPCODE,  ASIG,  IVAR,  IVAR,  IVAR,  IVAR, IVAR,   -1,   sizeof(biquad_storage), co_biquad },
  {"fir",           AOPCODE,  ASIG,  KSIG,    -1,    -1,    -1,   -1, KSIG,   sizeof(fir_storage), co_fir },
  {"firt",          AOPCODE,  ASIG, TABLE,  KSIG,    -1,    -1,   -1,   -1,   sizeof(firt_storage), co_firt },
  {"iir",           AOPCODE,  ASIG,  KSIG,    -1,    -1,    -1,   -1, KSIG,   sizeof(iir_storage), co_iir },
  {"iirt",          AOPCODE,  ASIG, TABLE,  TABLE, KSIG,    -1,   -1,   -1,   sizeof(iirt_storage), co_iirt },
  {"fdelay",        AOPCODE,  ASIG,  KSIG,  IVAR,    -1,    -1,   -1,   -1,   sizeof(fdelay_storage), co_fdelay },
  {"comb",          AOPCODE,  ASIG,  IVAR,  IVAR,    -1,    -1,   -1,   -1,     sizeof(comb_storage), co_comb},
  {"allpass",       AOPCODE,  ASIG,  IVAR,  IVAR,    -1,    -1,   -1,   -1,  sizeof(allpass_storage), co_allpass},
  /* things from this point onward are implementation-specific, outside-the-
     standard opcodes */
  {"kdump",         KOPCODE,  KSIG,    -1,    -1,    -1,   -1,   -1,  KSIG,  sizeof(kdump_storage),  co_kdump},
  {"adump",         AOPCODE,  ASIG,    -1,    -1,    -1,   -1,   -1,  ASIG,  sizeof(adump_storage),  co_adump},
  {"midicc",          IOPCODE,  IVAR,  IVAR,  IVAR,    -1,    -1,       -1,   -1,     
   0, co_midicc},
  {"**END",              -1,    -1,    -1,    -1,    -1,    -1,   -1,   -1,                       -1,      NULL }};

/* still need reverb, comp, allpass, allpass1, chorus, flange, spatialize */

void add_sym_table_core_opcodes(sa_decoder *sa,symtable *t) {
  int i=0;

  while (strcmp(core_opcodes[i].name,"**END")) {
    symbol *sym;
    symtable *p;
    opcode_decl *op;
    formalparam_list *fpl;
    formalparam *fp;
    name *n;
    int ct;
    

    fpl = new_formalparam_list();
    n = new_name("<builtin>",1);
    fp = new_formalparam(core_opcodes[i].p1type,n);
    add_formalparam_list(fpl,fp);

    if (core_opcodes[i].p2type != -1) {
      fp = new_formalparam(core_opcodes[i].p2type,n);
      add_formalparam_list(fpl,fp);
    }
    if (core_opcodes[i].p3type != -1) {
      fp = new_formalparam(core_opcodes[i].p3type,n);
      add_formalparam_list(fpl,fp);
    }
    if (core_opcodes[i].p4type != -1) {
      fp = new_formalparam(core_opcodes[i].p4type,n);
      add_formalparam_list(fpl,fp);
    }
    if (core_opcodes[i].p5type != -1) {
      fp = new_formalparam(core_opcodes[i].p5type,n);
      add_formalparam_list(fpl,fp);
    }
    if (core_opcodes[i].p6type != -1) {
      fp = new_formalparam(core_opcodes[i].p6type,n);
      add_formalparam_list(fpl,fp);
    }
      
    op = new_opcode_decl(core_opcodes[i].name,fpl,NULL,NULL,
			 core_opcodes[i].oprate);
    op->sym = new_symtable(sa,0);
    op->width = 1;
    add_sym_table_fplist(op->sym,fpl);

    sym = add_sym_table_name(t,core_opcodes[i].name,core_opcodes[i].oprate,
			     op);

    for (ct=0,p=op->sym;p;ct+=p->s->width,p=p->next)
      p->s->offset = ct;
    
    i++;
  }
}

int opcode_is_varargs(char *name) {
  int i=0;

  while (strcmp(core_opcodes[i].name,"**END") &&
	 strcmp(core_opcodes[i].name,name)) i++;

  if (strcmp(core_opcodes[i].name,"**END"))
    return(core_opcodes[i].varargs);
  else return 0;
}

core_opcode *is_core_opcode(char *name) {
  int i=0;

  while (strcmp(core_opcodes[i].name,"**END") &&
	 strcmp(core_opcodes[i].name,name)) i++;

  if (!strcmp(core_opcodes[i].name,"**END"))
    return NULL;
  else return(&core_opcodes[i]);
}

