signed saturation
ManAtWork
Posts: 2,176
What is the best method to limit the range of a 32 bit signed value to 16 bit signed? I'm looking for the reverse of the SIGNX instruction. Of course, I could do
Is there a more elegant method?
FLES x,##$00007FFF FGES x,##$FFFF8000but that would require 4 longwords and 8 clocks. No big deal if only needed once. But I'll probably need this a lot (digital filtering).
TESTB x,#31 wc BITC x,#16<<5+15Is shorter and faster. ...EDIT: and doesn't work, unfortunatelly.
Is there a more elegant method?
Comments
Doing scaling instead would be a little more guess work on suitable scale factors but does improve things. Only do the final clipping at output stage so then it can't wrap around due to forced truncation. I'd be inclined to try using the cordic and stick with 32-bit working data as much as possible. But for the fastest option maybe SCAS might be what you want. Although, that does require starting from 16-bit source data in the first place.
That's what the TESTB, BITC sequence does, but it doesn't deliver the desired result:
If the 32 bit result is 32780 or $0000800C then the output is 12 or $0000000C rather than the desired 32767 or $00007FFF.
My follow-up questions are: What is the maximum predicted excursion from 16 bit range? What can be done earlier to prevent excursions, and are the consequences worth the trade-off?
I'm still not sure what approach I use for the filtering. MUL/ADD is fastest but I don't know if 16 bits resolution is sufficient. 32 bits resolution and using the cordic might have some advantages but the CORDIC unit doesn't (directly) support signed multiplication. If one factor is constant I could use the trick of doing a rotation with arcsin(factor) instead of a multiplication which supports negative numbers.
The P2 might even have enough power to use (software) floating point math. In this case I don't have to worry about scaling, overflows and clipping at all and only have to limit the final output.
BTW, a nice trick is that FLE also works on floating point numbers but only if they are positive.