Example #1
0
/* complex addition helper */
static void sig_caddsub(uint16 addsub,OPS op)
{
OP a,b,c,d,p1,p2;

a = ReadOp(RE(op[1].word), fp_f);                  /* read 1st op */
b = ReadOp(IM(op[1].word), fp_f);
c = ReadOp(RE(op[2].word), fp_f);                  /* read 2nd op */
d = ReadOp(IM(op[2].word), fp_f);
(void)fp_exec(addsub,&p1, a, c);                   /* add real */
(void)fp_exec(addsub,&p2, b, d);                   /* add imag */
WriteOp(RE(op[0].word), p1, fp_f);                 /* write result */
WriteOp(IM(op[0].word), p2, fp_f);                 /* write result */
}
Example #2
0
static void vis_minmax(OPS op,OPSIZE opsize,t_bool domax,t_bool doabs)
{
OP v1,vmxmn,res;
int16 delta = opsize==fp_f ? 2 : 4;
uint32 mxmnaddr = op[0].word;
uint32 v1addr = op[1].word;
int16 ix1 = INT16(op[2].word) * delta;
int16 n = INT16(op[3].word);
int16 i,mxmn,sign;
uint16 subop = 020 | (opsize==fp_f ? 0 : 2);

if (n <= 0) return;
mxmn = 0;                                                /* index of maxmin element */
vmxmn = ReadOp(v1addr,opsize);                           /* initialize with first element */
if (doabs) vis_abs(&vmxmn,opsize);                       /* ABS(v[1]) if requested */

for (i = 0; i<n; i++) {
    v1 = ReadOp(v1addr,opsize);                          /* get v[i] */
    if (doabs) vis_abs(&v1,opsize);                      /* build ABS(v[i]) if requested */
    (void)fp_exec(subop,&res,vmxmn,v1);                  /* subtract vmxmn - v1[i] */
    sign = GET_MSIGN(&res);                              /* !=0 if vmxmn < v1[i] */
    if ((domax && sign) ||                               /* new max value found */
        (!domax && !sign)) {                             /* new min value found */
        mxmn = i;
       vmxmn = v1;                                       /* save the new max/min value */
       }
    v1addr += ix1;                                       /* point to next element */
    }
res.word = mxmn+1;                                       /* adjust to one-based FTN array */
WriteOp(mxmnaddr, res, in_s);                            /* save result */
}
Example #3
0
	bool AddFile(const std::string& file, const std::string src_md5, const std::string dst_md5)
	{
		if(!WriteOp()) return false;
		printf("file %s\n", file.c_str());

		int bzerror;
		unsigned short len = file.size();
		BZ2_bzWrite(&bzerror, _bzpatch, &len, sizeof(len));
		if(bzerror!=BZ_OK) return false;
		BZ2_bzWrite(&bzerror, _bzpatch, (void*)file.c_str(), len);
		if(bzerror!=BZ_OK) return false;

		len = (unsigned short)src_md5.size();
		BZ2_bzWrite(&bzerror, _bzpatch, &len, sizeof(len));
		if(bzerror!=BZ_OK) return false;
		BZ2_bzWrite(&bzerror, _bzpatch, (void*)src_md5.c_str(), len);
		if(bzerror!=BZ_OK) return false;

		len = (unsigned short)dst_md5.size();
		BZ2_bzWrite(&bzerror, _bzpatch, &len, sizeof(len));
		if(bzerror!=BZ_OK) return false;
		BZ2_bzWrite(&bzerror, _bzpatch, (void*)dst_md5.c_str(), len);
		if(bzerror!=BZ_OK) return false;

		return true;
	}
Example #4
0
static void vis_vpiv(OPS op, OPSIZE opsize)
{
OP s,v1,v2,v3;
int16 delta = opsize==fp_f ? 2 : 4;
uint32 saddr = op[0].word;
uint32 v1addr = op[1].word;
int16 ix1 = INT16(op[2].word) * delta;
uint32 v2addr = op[3].word;
int16 ix2 = INT16(op[4].word) * delta;
uint32 v3addr = op[5].word;
int16 ix3 = INT16(op[6].word) * delta;
int16 i, n = INT16(op[7].word);
int16 oplen = opsize==fp_f ? 0 : 2;

if (n <= 0) return;
s = ReadOp(saddr,opsize);
/* calculates v3[k] = s * v1[i] + v2[j] for incrementing i,j,k */
for (i=0; i<n; i++) {
    v1 = ReadOp(v1addr, opsize);
    (void)fp_exec(040+oplen, ACCUM, s ,v1);              /* ACCU := s*v1 */
    v2 = ReadOp(v2addr, opsize);
    (void)fp_exec(004+oplen,&v3,v2,NOP);                 /* v3 := v2 + s*v1 */
    WriteOp(v3addr, v3, opsize);                         /* write result */
    v1addr += ix1;                                       /* forward to next array elements */
    v2addr += ix2;
    v3addr += ix3;
    }
}
Example #5
0
static void vis_vdot(OPS op,OPSIZE opsize)
{
OP v1,v2,dot = zero;
int16 delta = opsize==fp_f ? 2 : 4;
uint32 daddr = op[0].word;
uint32 v1addr = op[1].word;
int16 ix1 = INT16(op[2].word) * delta;
uint32 v2addr = op[3].word;
int16 ix2 = INT16(op[4].word) * delta;
int16 i,n = INT16(op[5].word);

if (n <= 0) return;
/* calculates dot = dot + v1[i]*v2[j] for incrementing i,j */
for (i=0; i<n; i++) {
    v1 = ReadOp(v1addr, opsize);
    if (opsize==fp_f) (void)fp_cvt(&v1,fp_f,fp_t);       /* cvt to DBLE(v1) */
    v2 = ReadOp(v2addr, opsize);
    if (opsize==fp_f) (void)fp_cvt(&v2,fp_f,fp_t);       /* cvt to DBLE(v2) */
    (void)fp_exec(042,ACCUM, v1, v2);                    /* ACCU := v1 * v2 */
    (void)fp_exec(006,&dot,dot,NOP);                     /* dot := dot + v1*v2 */
    v1addr += ix1;                                       /* forward to next array elements */
    v2addr += ix2;
    }
if (opsize==fp_f)
    (void)vis_trunc(&dot,dot);                           /* truncate to SNGL(sumnrm) */
WriteOp(daddr, dot, opsize);                             /* write result */
}
Example #6
0
	bool AddOperatorEnd()
	{
		if(!WriteOp()) return false;
		printf("-end\n");
		int bzerror;
		unsigned char code = OPERATOR_END;
		BZ2_bzWrite(&bzerror, _bzpatch, &code, sizeof(code));
		return true;
	}
Example #7
0
static void vis_movswp(OPS op, OPSIZE opsize, t_bool doswp)
{
OP v1,v2;
int16 delta = opsize==fp_f ? 2 : 4;
uint32 v1addr = op[0].word;
int16 ix1 = INT16(op[1].word) * delta;
uint32 v2addr = op[2].word;
int16 ix2 = INT16(op[3].word) * delta;
int16 i,n = INT16(op[4].word);

if (n <= 0) return;
for (i=0; i<n; i++) {
    v1 = ReadOp(v1addr, opsize);
    v2 = ReadOp(v2addr, opsize);
    WriteOp(v2addr, v1, opsize);                         /* v2 := v1 */
    if (doswp) WriteOp(v1addr, v2, opsize);              /* v1 := v2 */
    v1addr += ix1;                                       /* forward to next array elements */
    v2addr += ix2;
    }
}
Example #8
0
	bool AddOperatorCopy(size_t size, size_t offset)
	{
		if(_Op!=OPERATOR_COPY)
		{
			if(!WriteOp()) return false;
			_size = 0;
			_offset = offset;
			_Op = OPERATOR_COPY;
		}
		else
		{
			if(_size+_offset!=offset)
			{
				if(!WriteOp()) return false;
				_size = 0;
				_offset = offset;
			}
		}

		_size += size;
		return true;
	}
Example #9
0
	bool DelFile(const std::string& file)
	{
		if(!WriteOp()) return false;
		printf("file %s delete\n", file.c_str());
		unsigned short len = file.size();
		int bzerror;
		BZ2_bzWrite(&bzerror, _bzpatch, &len, sizeof(len));
		if(bzerror!=BZ_OK) return false;
		BZ2_bzWrite(&bzerror, _bzpatch, "*", 1);
		if(bzerror!=BZ_OK) return false;
		BZ2_bzWrite(&bzerror, _bzpatch, (void*)file.c_str(), len);
		if(bzerror!=BZ_OK) return false;
		return true;
	}
Example #10
0
/* butterfly operation helper */
static void sig_btrfy(uint32 re,uint32 im,OP wr,OP wi,uint32 k, uint32 n2)
{
/*
 * v(k)-------->o-->o----> v(k)
 *               \ /
 *                x
 *               / \
 * v(k+N/2)---->o-->o----> v(k+N/2)
 *           Wn   -1
 *
 */

OP p1,p2,p3,p4;
OP v1r = ReadOp(re+k, fp_f);                       /* read v1 */
OP v1i = ReadOp(im+k, fp_f);
OP v2r = ReadOp(re+k+n2, fp_f);                    /* read v2 */
OP v2i = ReadOp(im+k+n2, fp_f);

/* (p1,p2) := cmul(w,v2) */
(void)fp_exec(040, &p1, wr, v2r);                  /* S7,8 p1 := wr*v2r */
(void)fp_exec(040, ACCUM, wi, v2i);                /* ACCUM := wi*v2i */
(void)fp_exec(024, &p1, p1, NOP);                  /* S7,S8 p1 := wr*v2r-wi*v2i ==real(w*v2) */
(void)fp_exec(040, &p2, wi, v2r);                  /* S9,10 p2 := wi*v2r */
(void)fp_exec(040, ACCUM, wr, v2i);                /* ACCUM := wr*v2i */
(void)fp_exec(004, &p2, p2, NOP);                  /* S9,10 p2 := wi*v2r+wr*v2i ==imag(w*v2) */
/* v2 := v1 - (p1,p2) */
(void)fp_exec(020, &p3, v1r, p1);                  /* v2r := v1r-real(w*v2) */
(void)fp_exec(020, &p4, v1i, p2);                  /* v2i := v1i-imag(w*v2) */
WriteOp(re+k+n2, p3, fp_f);                        /* write v2r */
WriteOp(im+k+n2, p4, fp_f);                        /* write v2i */
/* v1 := v1 + (p1,p2) */
(void)fp_exec(0, &p3, v1r, p1);                    /* v1r := v1r+real(w*v2) */
(void)fp_exec(0, &p4, v1i, p2);                    /* v1i := v1i+imag(w*v2) */
WriteOp(re+k, p3, fp_f);                           /* write v1r */
WriteOp(im+k, p4, fp_f);                           /* write v1i */
O = 0;
}
Example #11
0
void WriteRelationPostfix(FILE *f,
			  CONST struct Instance *relinst,
			  CONST struct Instance *ref)
{
  CONST struct relation *r;
  enum Expr_enum type;

  r = GetInstanceRelation(relinst,&type);
  if (type!=e_token) {
    FPRINTF(ASCERR,"Invalid relation type in WriteRelationPostfix\n");
    return;
  }

  switch(RelationRelop(r)){
  case e_equal:
  case e_notequal:
  case e_less:
  case e_greater:
  case e_lesseq:
  case e_greatereq:
    WriteSidePF(f,r,1,ref);
    PUTC(' ',f);
    WriteSidePF(f,r,0,ref);
    PUTC(' ',f);
    WriteOp(f,RelationRelop(r));
    break;
  case e_maximize:
  case e_minimize:
    WriteOp(f,RelationRelop(r));
    PUTC(' ',f);
    WriteSidePF(f,r,1,ref);
    break;
  default:
    FPRINTF(ASCERR,"Unexpected Relop in WriteRelationPostfix\n");
    break;
  }
}
Example #12
0
/* helper for bit reversal
 * idx is 0-based already */
static void sig_bitrev(uint32 re,uint32 im, uint32 idx, uint32 log2n, int sz)
{
uint32 i, org=idx, rev = 0;
OP v1r,v1i,v2r,v2i;

for (i=0; i<log2n; i++) {                          /* swap bits of idx */
    rev = (rev<<1) | (org & 1);                    /* into rev */
    org >>= 1;
}

if (rev < idx) return;                             /* avoid swapping same pair twice in loop */

idx *= sz;                                         /* adjust for element size */
rev *= sz;                                         /* (REAL*4 vs COMPLEX*8) */

v1r = ReadOp(re+idx, fp_f);                        /* read 1st element */
v1i = ReadOp(im+idx, fp_f);
v2r = ReadOp(re+rev, fp_f);                        /* read 2nd element */
v2i = ReadOp(im+rev, fp_f);
WriteOp(re+idx, v2r, fp_f);                        /* swap elements */
WriteOp(im+idx, v2i, fp_f);
WriteOp(re+rev, v1r, fp_f);
WriteOp(im+rev, v1i, fp_f);
}
Example #13
0
	bool AddOperatorAppend(size_t size, size_t _patch_offset)
	{
		if(!WriteOp()) return false;

		printf("-append %d %d\n", size, _patch_offset);

		int bzerror;
		unsigned char code = OPERATOR_APPEND;
		BZ2_bzWrite(&bzerror, _bzpatch, &code, sizeof(code));
		if(bzerror!=BZ_OK) return false;
		BZ2_bzWrite(&bzerror, _bzpatch, &size, 4);
		if(bzerror!=BZ_OK) return false;
		BZ2_bzWrite(&bzerror, _bzpatch, &_patch_offset, 4);
		if(bzerror!=BZ_OK) return false;
		return true;
	}
Example #14
0
static void vis_vabs(OPS op, OPSIZE opsize)
{
OP v1;
int16 delta = opsize==fp_f ? 2 : 4;
uint32 v1addr = op[0].word;
int16 ix1 = INT16(op[1].word) * delta;
uint32 v2addr = op[2].word;
int32 ix2 = INT16(op[3].word) * delta;
int16 i,n = INT16(op[4].word);

if (n <= 0) return;
/* calculates v2[j] = ABS(v1[i]) for incrementing i,j */
for (i=0; i<n; i++) {
    v1 = ReadOp(v1addr, opsize);
    vis_abs(&v1,opsize);                                 /* make absolute value */
    WriteOp(v2addr, v1, opsize);                         /* write result */
    v1addr += ix1;                                       /* forward to next array elements */
    v2addr += ix2;
    }
}
Example #15
0
/* handle the scalar/vector base ops */
static void vis_svop(uint32 subcode, OPS op, OPSIZE opsize)
{
OP v1,v2;
int16 delta = opsize==fp_f ? 2 : 4;
OP s = ReadOp(op[0].word,opsize);
uint32 v1addr = op[1].word;
int16 ix1 = INT16(op[2].word) * delta;
uint32 v2addr = op[3].word;
int16 ix2 = INT16(op[4].word) * delta;
int16 i, n = INT16(op[5].word);
uint16 fpuop = (uint16) (subcode & 060) | (opsize==fp_f ? 0 : 2);

if (n <= 0) return;
for (i=0; i<n; i++) {
    v1 = ReadOp(v1addr, opsize);
    (void)fp_exec(fpuop, &v2, s ,v1);
    WriteOp(v2addr, v2, opsize);
    v1addr += ix1;
    v2addr += ix2;
    }
}
Example #16
0
static
void WriteTerm(FILE *f,
	       CONST struct relation *rel,
	       CONST struct relation_term *term,
	       CONST struct Instance *inst)
{
  struct Instance *cur_var;
  switch(RelationTermType(term)){
  case e_var:
    cur_var = RelationVariable(rel,TermVarNumber(term));
    WriteInstanceName(f,cur_var,inst);
    break;
  case e_func:
    FPRINTF(f,FuncName(TermFunc(term)));
    break;
  case e_int:
    FPRINTF(f,"%ld",TermInteger(term));
    break;
  case e_zero:
    FPRINTF(f,"%g",0.0);
    break;
  case e_real:
    FPRINTF(f,"%g",TermReal(term));
    break;
  case e_plus:
  case e_minus:
  case e_times:
  case e_divide:
  case e_power:
  case e_ipower:
    WriteOp(f,RelationTermType(term));
    break;
  case e_uminus:
    FPRINTF(f,"NEG");
    break;
  default:
    ASC_PANIC("Unknown term type in WriteTerm.\n");
    break;
  }
}
Example #17
0
static void vis_vsmnm(OPS op,OPSIZE opsize,t_bool doabs)
{
uint16 fpuop;
OP v1,sumnrm = zero;
int16 delta = opsize==fp_f ? 2 : 4;
uint32 saddr = op[0].word;
uint32 v1addr = op[1].word;
int16 ix1 = INT16(op[2].word) * delta;
int16 i,n = INT16(op[3].word);

if (n <= 0) return;
/* calculates sumnrm = sumnrm + DBLE(v1[i]) resp DBLE(ABS(v1[i])) for incrementing i */
for (i=0; i<n; i++) {
    v1 = ReadOp(v1addr, opsize);
    if (opsize==fp_f) (void)fp_cvt(&v1,fp_f,fp_t);       /* cvt to DBLE(v1) */
    fpuop = (doabs && GET_MSIGN(&v1)) ? 022 : 002;       /* use subtract for NRM && V1<0 */
    (void)fp_exec(fpuop,&sumnrm, sumnrm, v1);            /* accumulate */
    v1addr += ix1;                                       /* forward to next array elements */
    }
if (opsize==fp_f)
    (void)vis_trunc(&sumnrm,sumnrm);                     /* truncate to SNGL(sumnrm) */
WriteOp(saddr, sumnrm, opsize);                          /* write result */
}
Example #18
0
int ExpandNode( NODE *n, int lastop )
{
int needParen = 0;

  if( n == 0 ) return lastop;

  if( ( n->left ) &&
      ( PRI[ n->left->type ] < PRI[ n->type ] ) )
      needParen = 1;

  if( needParen ) {
    WriteOp( crtop );
    WriteSymbol( O_PAREN );
  }
  lastop = ExpandNode( n->left, lastop );
  if( needParen ) WriteSymbol( C_PAREN );

  switch( n->type ) {
    case ADD:  
    case SUB:   
    case MUL:   
    case DIV:   
    case POW:   crtop = n->type;
                break;
    case NONE:  printf("ERROR - null element"); 
    		break;
    case CONST: 
    case ELM:
    case VELM:
    case MELM:
    case EELM:
		switch( crtop ) {
		  case MUL: case DIV: case POW:
		    WriteOp( crtop );
		    if ( n->sign == -1 ) {
		      WriteSymbol( O_PAREN );
		      WriteOp( SUB );
		      ExpandElm( n );
		      WriteSymbol( C_PAREN );
		    } else {
		      ExpandElm( n );
		    }
		    break;
		  case ADD:  if( n->sign == -1 )
			       crtop = SUB;
			     WriteOp( crtop );
			     ExpandElm( n );
			     break;
		  case SUB:  if( n->sign == -1 )
			       crtop = ADD;
			     WriteOp( crtop );
			     ExpandElm( n );
			     break;
		  case NONE: if( n->sign == -1 )
			       WriteOp( SUB );
			     ExpandElm( n );
			     break;
		}
		break;
  }

  if( ( n->right ) &&
      ( PRI[ n->right->type ] <= PRI[ n->type ] ) )
      needParen = 1; 

  if( needParen ) {
    WriteOp( crtop );
    WriteSymbol( O_PAREN );
  }  
  lastop = ExpandNode( n->right, n->type );
  if( needParen ) WriteSymbol( C_PAREN );
  return lastop;
}
Example #19
0
static void SetBank(byte address) {
    if ((address & BANK_MASK) != Enc28j60Bank) {
        WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_BSEL1|ECON1_BSEL0);
        Enc28j60Bank = address & BANK_MASK;
        WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, Enc28j60Bank>>5);
    }
Example #20
0
bool BinLog::Open()
{
    const char *data = get_localinfo("amxmodx_datadir", "addons/amxmodx/data");
    char path[255];
    build_pathname_r(path, sizeof(path)-1, "%s/binlogs", data);

    if (!DirExists(path))
    {
        mkdir(path
#if defined(__linux__) || defined(__APPLE__)
              , 0755
#endif
             );
        if (!DirExists(path))
            return false;
    }

    char file[255];
    build_pathname_r(file, sizeof(file)-1, "%s/binlogs/lastlog", data);

    unsigned int lastcntr = 0;
    FILE *lastlog = fopen(file, "rb");
    if (lastlog)
    {
        if (fread(&lastcntr, sizeof(int), 1, lastlog) != 1)
            lastcntr = 0;
        fclose(lastlog);
    }
    lastlog = fopen(file, "wb");
    if (lastlog)
    {
        lastcntr++;
        fwrite(&lastcntr, sizeof(int), 1, lastlog);
        fclose(lastlog);
    }
    build_pathname_r(file, sizeof(file)-1, "%s/binlogs/binlog%04d.blg", data, lastcntr);
    m_logfile = file;

    /**
    * it's now safe to create the binary log
    */
    FILE *fp = fopen(m_logfile.chars(), "wb");
    if (!fp)
        return false;

    int magic = BINLOG_MAGIC;
    short vers = BINLOG_VERSION;
    char c = sizeof(time_t);
    fwrite(&magic, sizeof(int), 1, fp);
    fwrite(&vers, sizeof(short), 1, fp);
    fwrite(&c, sizeof(char), 1, fp);

    WritePluginDB(fp);
    fclose(fp);

    m_state = true;

    WriteOp(BinLog_Start, -1);

    return true;
}
Example #21
0
void BinLog::Close()
{
    WriteOp(BinLog_End, -1);
    m_state = false;
}
Example #22
0
t_stat cpu_signal (uint32 IR, uint32 intrq)
{
t_stat reason = SCPE_OK;
OPS op;
OP a,b,c,d,p1,p2,p3,p4,m1,m2,wr,wi;
uint32 entry, v, idx1, idx2;
int32 exc, exd;

entry = IR & 017;                                  /* mask to entry point */

if (op_signal [entry] != OP_N) {
    reason = cpu_ops (op_signal [entry], op, intrq);    /* get instruction operands */
    if (reason != SCPE_OK)                              /* evaluation failed? */
        return reason;                                  /* return reason for failure */
    }

switch (entry) {                                   /* decode IR<3:0> */
    case 000:                                      /* BITRV (OP_AAKK) */
        /* BITRV
         * bit reversal for FFT
         *   JSB BITRV
         *   DEF ret(,I)   return address
         *   DEF vect,I    base address of array
         *   DEF idx,I     index bitmap to be reversed (one-based)
         *   DEF nbits,I   number of bits of index
         *
         * Given a complex*8 vector of nbits (power of 2), this calculates:
         * swap( vect[idx], vect[rev(idx)]) where rev(i) is the bitreversed value of i */
        sig_bitrev(op[1].word, op[1].word+2, op[2].word-1, op[3].word, 4);
        PR = op[0].word & VAMASK;
        break;

    case 001:                                      /* BTRFY (OP_AAFFKK) */
        /* BTRFY - butterfly operation
         *   JSB BTRFY
         *   DEF ret(,I)   return address
         *   DEF vect(,I)  complex*8 vector
         *   DEF wr,I      real part of W
         *   DEF wi,I      imag part of W
         *   DEF node,I    index of 1st op (1 based)
         *   DEF lmax,I    offset to 2nd op (0 based) */
        sig_btrfy(op[1].word, op[1].word+2,
                  op[2], op[3],
                  2*(op[4].word-1), 2*op[5].word);
        PR = op[0].word & VAMASK;
        break;

    case 002:                                      /* UNSCR (OP_AAFFKK) */
        /* UNSCR unscramble for phasor MPY
         *   JSB UNSCR
         *   DEF ret(,I)
         *   DEF vector,I
         *   DEF WR
         *   DEF WI
         *   DEF idx1,I
         *   DEF idx2,I */
        v = op[1].word;
        idx1 = 2 * (op[4].word - 1);
        idx2 = 2 * (op[5].word - 1);
        wr = op[2];                               /* read WR */
        wi = op[3];                               /* read WI */
        p1 = ReadOp(RE(v + idx1), fp_f);          /* S1 VR[idx1] */
        p2 = ReadOp(RE(v + idx2), fp_f);          /* S2 VR[idx2] */
        p3 = ReadOp(IM(v + idx1), fp_f);          /* S9 VI[idx1] */
        p4 = ReadOp(IM(v + idx2), fp_f);          /* S10 VI[idx2] */
        c = sig_scadd(000, TRUE, p3, p4);         /* S5,6 0.5*(p3+p4) */
        d = sig_scadd(020, TRUE, p2, p1);         /* S7,8 0.5*(p2-p1) */
        sig_cmul(&m1, &m2, wr, wi, c, d);         /* (WR,WI) * (c,d) */
        c = sig_scadd(000, TRUE, p1, p2);         /* 0.5*(p1+p2) */
        d = sig_scadd(020, TRUE, p3, p4);         /* 0.5*(p3-p4) */
        (void)fp_exec(000, &p1, c, m1);           /* VR[idx1] := 0.5*(p1+p2) + real(W*(c,d)) */
        WriteOp(RE(v + idx1), p1, fp_f);
        (void)fp_exec(000, &p2, d, m2);           /* VI[idx1] := 0.5*(p3-p4) + imag(W*(c,d)) */
        WriteOp(IM(v + idx1), p2, fp_f);
        (void)fp_exec(020, &p1, c, m1);           /* VR[idx2] := 0.5*(p1+p2) - imag(W*(c,d)) */
        WriteOp(RE(v + idx2), p1, fp_f);
        (void)fp_exec(020, &p2, d, m2);           /* VI[idx2] := 0.5*(p3-p4) - imag(W*(c,d)) */
        WriteOp(IM(v + idx2), p2, fp_f);
        PR = op[0].word & VAMASK;
        break;

    case 003:                                      /* PRSCR (OP_AAFFKK) */
        /* PRSCR unscramble for phasor MPY
         *   JSB PRSCR
         *   DEF ret(,I)
         *   DEF vector,I
         *   DEF WR
         *   DEF WI
         *   DEF idx1,I
         *   DEF idx2,I */
        v = op[1].word;
        idx1 = 2 * (op[4].word - 1);
        idx2 = 2 * (op[5].word - 1);
        wr = op[2];                               /* read WR */
        wi = op[3];                               /* read WI */
        p1 = ReadOp(RE(v + idx1), fp_f);          /* VR[idx1] */
        p2 = ReadOp(RE(v + idx2), fp_f);          /* VR[idx2] */
        p3 = ReadOp(IM(v + idx1), fp_f);          /* VI[idx1] */
        p4 = ReadOp(IM(v + idx2), fp_f);          /* VI[idx2] */
        c = sig_scadd(020, FALSE, p1, p2);        /* p1-p2 */
        d = sig_scadd(000, FALSE, p3, p4);        /* p3+p4 */
        sig_cmul(&m1,&m2, wr, wi, c, d);          /* (WR,WI) * (c,d) */
        c = sig_scadd(000, FALSE, p1, p2);        /* p1+p2 */
        d = sig_scadd(020, FALSE, p3,p4);         /* p3-p4 */
        (void)fp_exec(020, &p1, c, m2);           /* VR[idx1] := (p1-p2) - imag(W*(c,d)) */
        WriteOp(RE(v + idx1), p1, fp_f);
        (void)fp_exec(000, &p2, d, m1);           /* VI[idx1] := (p3-p4) + real(W*(c,d)) */
        WriteOp(IM(v + idx1), p2, fp_f);
        (void)fp_exec(000, &p1, c, m2);           /* VR[idx2] := (p1+p2) + imag(W*(c,d)) */
        WriteOp(RE(v + idx2), p1, fp_f);
        (void)fp_exec(020, &p2, m1, d);           /* VI[idx2] := imag(W*(c,d)) - (p3-p4) */
        WriteOp(IM(v + idx2), p2, fp_f);
        PR = op[0].word & VAMASK;
        break;

    case 004:                                      /* BITR1 (OP_AAAKK) */
        /* BITR1
         * bit reversal for FFT, alternative version
         *   JSB BITR1
         *   DEF ret(,I)   return address if already swapped
         *   DEF revect,I  base address of real vect
         *   DEF imvect,I  base address of imag vect
         *   DEF idx,I     index bitmap to be reversed (one-based)
         *   DEF nbits,I   number of bits of index
         *
         * Given a complex*8 vector of nbits (power of 2), this calculates:
         * swap( vect[idx], vect[rev(idx)]) where rev(i) is the bitreversed value of i
         *
         * difference to BITRV is that BITRV uses complex*8, and BITR1 uses separate real*4
         * vectors for Real and Imag parts */
        sig_bitrev(op[1].word, op[2].word, op[3].word-1, op[4].word, 2);
        PR = op[0].word & VAMASK;
        break;


    case 005:                                      /* BTRF1 (OP_AAAFFKK) */
        /* BTRF1 - butterfly operation with real*4 vectors
         *   JSB BTRF1
         *   DEF ret(,I)   return address
         *   DEF rvect,I   real part of vector
         *   DEF ivect,I   imag part of vector
         *   DEF wr,I      real part of W
         *   DEF wi,I      imag part of W
         *   DEF node,I    index (1 based)
         *   DEF lmax,I    index (0 based) */
        sig_btrfy(op[1].word, op[2].word,
                  op[3], op[4],
                  op[5].word-1, op[6].word);
        PR = op[0].word & VAMASK;
        break;

    case 006:                                      /* .CADD (OP_AAA) */
        /* .CADD Complex addition
         *   JSB .CADD
         *   DEF result,I
         *   DEF oprd1,I
         *   DEF oprd2,I
         * complex addition is: (a+bi) + (c+di) => (a+c) + (b+d)i */
        sig_caddsub(000,op);
        break;

    case 007:                                      /* .CSUB (OP_AAA) */
        /* .CSUB Complex subtraction
         *   JSB .CSUB
         *   DEF result,I
         *   DEF oprd1,I
         *   DEF oprd2,I
         * complex subtraction is: (a+bi) - (c+di) => (a - c) + (b - d)i */
        sig_caddsub(020,op);
        break;

    case 010:                                      /* .CMUL (OP_AAA) */
        /* .CMPY Complex multiplication
         * call:
         *   JSB .CMPY
         *   DEF result,I
         *   DEF oprd1,I
         *   DEF oprd2,I
         * complex multiply is: (a+bi)*(c+di) => (ac-bd) + (ad+bc)i */
        a = ReadOp(RE(op[1].word), fp_f);          /* read 1st op */
        b = ReadOp(IM(op[1].word), fp_f);
        c = ReadOp(RE(op[2].word), fp_f);          /* read 2nd op */
        d = ReadOp(IM(op[2].word), fp_f);
        sig_cmul(&p1, &p2, a, b, c, d);
        WriteOp(RE(op[0].word), p1, fp_f);         /* write real result */
        WriteOp(IM(op[0].word), p2, fp_f);         /* write imag result */
        break;

    case 011:                                      /* .CDIV (OP_AAA) */
        /* .CDIV Complex division
         * call:
         *   JSB .CDIV
         *   DEF result,I
         *   DEF oprd1,I
         *   DEF oprd2,I
         * complex division is: (a+bi)/(c+di) => ((ac+bd) + (bc-ad)i)/(c^2+d^2) */
        a = ReadOp(RE(op[1].word), fp_f);          /* read 1st op */
        b = ReadOp(IM(op[1].word), fp_f);
        c = ReadOp(RE(op[2].word), fp_f);          /* read 2nd op */
        d = ReadOp(IM(op[2].word), fp_f);
        (void)fp_unpack (NULL, &exc, c, fp_f);     /* get exponents */
        (void)fp_unpack (NULL, &exd, d, fp_f);
        if (exc < exd) {                           /* ensure c/d < 1 */
            p1 = a; a = c; c = p1;                 /* swap dividend and divisor */
            p1 = b; b = d; d = p1;
        }
        (void)fp_exec(060, &p1, d, c);             /* p1,accu := d/c */
        (void)fp_exec(044, ACCUM, d, NOP);         /* ACCUM := dd/c */
        (void)fp_exec(004, &p2, c, NOP);           /* p2 := c + dd/c */
        (void)fp_exec(040, ACCUM, b, p1);          /* ACCUM := bd/c */
        (void)fp_exec(004, ACCUM, a, NOP);         /* ACCUM := a + bd/c */
        (void)fp_exec(070, &p3, NOP, p2);          /* p3 := (a+bd/c)/(c+dd/c) == (ac+bd)/(cc+dd) */
        WriteOp(RE(op[0].word), p3, fp_f);         /* Write real result */
        (void)fp_exec(040, ACCUM, a, p1);          /* ACCUM := ad/c */
        (void)fp_exec(030, ACCUM, NOP, b);         /* ACCUM := ad/c - b */
        if (exd < exc) {                           /* was not swapped? */
            (void)fp_exec(024, ACCUM, zero, NOP);  /* ACCUM := -ACCUM */
        }
        (void)fp_exec(070, &p3, NOP, p2);          /* p3 := (b-ad/c)/(c+dd/c) == (bc-ad)/cc+dd) */
        WriteOp(IM(op[0].word), p3, fp_f);         /* Write imag result */
        break;

    case 012:                                      /* CONJG (OP_AAA) */
        /* CONJG build A-Bi from A+Bi
         * call:
         *   JSB CONJG
         *   DEF RTN
         *   DEF res,I    result
         *   DEF arg,I    input argument */
        a = ReadOp(RE(op[2].word), fp_f);          /* read real */
        b = ReadOp(IM(op[2].word), fp_f);          /* read imag */
        (void)fp_pcom(&b, fp_f);                   /* negate imag */
        WriteOp(RE(op[1].word), a, fp_f);          /* write real */
        WriteOp(IM(op[1].word), b, fp_f);          /* write imag */
        break;

    case 013:                                      /* ..CCM (OP_A) */
        /* ..CCM complement complex
         * call
         *   JSB ..CCM
         *   DEF arg
         * build (-RE,-IM)
         */
        v = op[0].word;
        a = ReadOp(RE(v), fp_f);                   /* read real */
        b = ReadOp(IM(v), fp_f);                   /* read imag */
        (void)fp_pcom(&a, fp_f);                   /* negate real */
        (void)fp_pcom(&b, fp_f);                   /* negate imag */
        WriteOp(RE(v), a, fp_f);                   /* write real */
        WriteOp(IM(v), b, fp_f);                   /* write imag */
        break;

    case 014:                                       /* AIMAG (OP_AA) */
        /* AIMAG return the imaginary part in AB
         *   JSB AIMAG
         *   DEF *+2
         *   DEF cplx(,I)
         * returns: AB imaginary part of complex number */
        a = ReadOp(IM(op[1].word), fp_f);           /* read imag */
        AR = a.fpk[0];                              /* move MSB to A */
        BR = a.fpk[1];                              /* move LSB to B */
        break;

    case 015:                                       /* CMPLX (OP_AFF) */
        /* CMPLX form a complex number
         *   JSB CMPLX
         *   DEF *+4
         *   DEF result,I  complex number
         *   DEF repart,I  real value
         *   DEF impart,I  imaginary value */
        WriteOp(RE(op[1].word), op[2], fp_f);       /* write real part */
        WriteOp(IM(op[1].word), op[3], fp_f);       /* write imag part */
        break;

    case 017:                                       /* [slftst] (OP_N) */
        XR = 2;                                     /* firmware revision */
        SR = 0102077;                               /* test passed code */
        PR = (PR + 1) & VAMASK;                     /* P+2 return for firmware w/SIGNAL1000 */
        break;

    case 016:                                       /* invalid */
    default:                                        /* others unimplemented */
        reason = STOP (cpu_ss_unimpl);
        }

return reason;
}