;;  Copyright 1987 by NeXT Inc.
;;  Author - John Strawn 
;;      
;;  Modification history
;;  --------------------
;;      06/22/87/jms - initial file created from DSPAPSRC/template
;;      07/06/87/jms - changed to reflect different underbar standard
;;      02/15/88/jms - change neg A to tst A in initialization
;;      02/23/88/jms - cosmetic changes to code and documentation
;;      
;;  ------------------------------ DOCUMENTATION ---------------------------
;;  NAME
;;      sveubar (AP macro) - vector element sum - sum vector to a scalar
;;      
;;  SYNOPSIS
;;      include 'stdmacros' ; load standard DSP macro package
;;      sveubar pf,ic,sinp,ainp0,iinp0,sout,aout0,cnt0; invoke ap macro sveubar
;;      
;;  MACRO ARGUMENTS
;;      pf      =   global label prefix (any text unique to invoking macro)
;;      ic      =   instance count (such that pf\_sveubar_\ic is globally unique)
;;      sinp    =   input vector memory space ('x' or 'y')
;;      ainp0   =   initial input vector memory address
;;      iinp0   =   initial increment for input vector address
;;      sout    =   output vector memory space ('x' or 'y')
;;      aout0   =   initial address for output scalar
;;      cnt0    =   initial element count
;;      
;;  DSP MEMORY ARGUMENTS
;;      Access      Description                     Initialization
;;      ------      -----------                     --------------
;;      x:(R_X)+    Input Vector base address       ainp0
;;      x:(R_X)+    Input Address increment         iinp0
;;      x:(R_X)+    Output                          aout0
;;      x:(R_X)+    element count                   cnt0
;;      
;;  DESCRIPTION
;;      The sveubar array-processor macro computes the sum of the elements
;;      of vector ainp. In pseudo-C notation:
;;      
;;      ainp    =   x:(R_X)+;
;;      iinp    =   x:(R_X)+;
;;      aout    =   x:(R_X)+;
;;      cnt     =   x:(R_X)+;
;;      
;;      aout = 0;
;;      for (n=0;n<cnt;n++) {
;;          sout:aout += ainp[n*iinp];
;;      }
;;      
;;  MEMORY USE
;;      11 program memory locations
;;      4  x-memory arguments
;;      
;;  EXECUTION TIME PER SAMPLE 
;;      24 DSP clock cycles = 120 nsec. loop setup time + 
;;      2 DSP clock cycles = 100 nsec for each element in vector
;;      
;;  DSPWRAP ARGUMENT INFO
;;      sveubar (prefix)pf,(instance)ic,
;;          (dspace)sinp,ainp0,iinp0,
;;          (dspace)sout,aout0,cnt0
;;      
;;  DSPWRAP C SYNTAX
;;      ierr    =   DSPsveubar(A,i,B,n);    /* vector element sum:
;;          A   =   destination vector base address in DSP memory
;;          iy  =   A address increment
;;          B   =   address of output
;;          n   =   element count           */
;;      
;;  CALLING DSP PROGRAM TEMPLATE    ; see also DSPAPSRC/test/tsveubar.asm
;;      include 'stdmacros'         ; utility macros
;;      beg_ap  'tsveubar'           ; begin ap main program
;;      beg_yeb                     ; allocate input vector
;;          tsveubar_vec    dc  1,2,3
;;      end_yeb
;;      new_xeb sum1,1,0            ; allocate space for output
;;      sveubar ap,1,y,tsveubar_vec,1,x,sum1,3
;;      end_ap  'tsveubar'           ; end of ap main program
;;      end
;;      
;;  TEST PROGRAM
;;      DSPAPSRC/test/tsveubar.asm
;;      
;;  SOURCE
;;      DSPAPSRC/sveubar.asm
;;      
;;  REGISTER USE
;;      A       test for cnt == 0 
;;      B       sum of vector elements
;;      X0      current addend
;;      X1      cnt
;;      R_I1    running pointer to input vector terms
;;      N_I1    increment for input vector
;;      R_O     pointer to ouptut term
;;      
        beg_def 'sveubar'   ; standard macro definition-file begin
sveubar macro pf,ic,sinp,ainp0,iinp0,sout,aout0,cnt0
        beg_mac 'sveubar'   ; standard macro begin

        ; argument definitions
        new_xarg    pf\_sveubar_\ic\_,ainp,ainp0    ; input address arg
        new_xarg    pf\_sveubar_\ic\_,iinp,iinp0    ; input increment arg
        new_xarg    pf\_sveubar_\ic\_,aout,aout0    ; output address arg
        new_xarg    pf\_sveubar_\ic\_,cnt,cnt0      ; element count arg

        ; get inputs 
        move            x:(R_X)+,R_I1
        move            x:(R_X)+,N_I1
        move            x:(R_X)+,R_O    ; output address goes to R_O
        move            x:(R_X)+,A      ; cnt goes to A

        ; set up loop and pipelining
        clr     B       A,X1            ; copy cnt0 into X1
        tst     A       B,X0            ; clear X0
        jeq     pf\_sveubar_\ic\_l1     ; guard against cnt=0

        ; inner loop 
        rep     X1
            add     X0,B    sinp:(R_I1)+N_I1,X0 ; sum elements
        add     X0,B                            ; pick up last one   
pf\_sveubar_\ic\_l1         
        move            B,sout:(R_O)            ; B=0 when cnt=0
        end_mac 'sveubar'
        endm
        end_def 'sveubar'

