VSMSB Documentation
John Strawn
11 August 1987
The vsmsb array-processor macro computes C[k]=A[k]*s - B[k].
Unfortunately, we cannot use
move B[k],a
move A[k],x0
move s,y0
macr -x0,y0,a
for this, because that would produce C[k]= B[k] - A[k]*s.
There are two possibilites for the code:
; main loop
move A[k],x0
mpy x0,y0,a
move B[k],y0
sub y0,a
rnd a
move a,C[k]
That leaves three explicit operations (mpy, sub, rnd) plus three moves.
Here is another:
; overhead
move s,y1
move #1,x0
; main loop
move A[k],x1
mpy x1,y1,a
move B[k],y0
macr -x0,y0,a
move a,C[k]
This is a stupid way to use a mac instruction, but it has the
advantage of combining the subtract with the round operation.
Life is not ideal here. With the code written as above, the product
of B[k] and 1 will appear in the lowest third of the accumulator. To
shift +B[k] into the middle third of the accumulator, as desired, you
must incant
move B[k],y0
move #800000,x0
mpy -x0,y0,a ; accumulator a gets -(-B[k])
Yes, I tested this for the following values in B[k]: 0, 1, 7FFFFF,
80001, FFFFF. This means that the canonical code will *switch* the
minus sign on the macr instruction, yielding
; overhead
move s,y1
move #800000,x0
; main loop
move A[k],x1
mpy x1,y1,a ; A[k]*s
move B[k],y0
macr x0,y0,a ; A[k]*s+(-B[k])
move a,C[k]
Careful examination of all cases showed that there is no
throughput advantage to doubling up, using 2 AC's and calculating
two terms in each pass through the main loop.