Hi all,
I am quite new to use the C5509A with assembly code.
I have the following piece of C code which is one of the bottlenecks in my algorithm:
// D[15:12] for IF0 (left) and IF1 (right)
pBuf = *pRaw++;
wLeft = ( (pBuf & 0xF000) >> 12) << 12;
wRight = ( (pBuf & 0x0F00) >> 8) << 12;
// D[11: 8] for IF0 (left) and IF1 (right)
wLeft |= ( (pBuf & 0x00F0) >> 4) << 8;
wRight |= ( (pBuf & 0x000F) >> 0) << 8;
// D[ 7: 4] for IF0 (left) and IF1 (right)
pBuf = *pRaw++;
wLeft |= ( (pBuf & 0xF000) >> 12) << 4;
wRight |= ( (pBuf & 0x0F00) >> 8) << 4;
// D[ 7: 4] for IF0 (left) and IF1 (right)
wLeft |= ( (pBuf & 0x00F0) >> 4) << 0;
wRight |= ( (pBuf & 0x000F) >> 0) << 0;
// store
*pLeft++ = wLeft,
*pRight++ = wRight;
This piece is inside of a loop with 4096 iterations. pBuf, pRaw, wLeft, wRight, pLeft and pRight are all Uint16. I would have like to optimize this code using the power of C55x assembly. I have first analyzed the compiler's assembly output in release mode (but with Full-Debug Information turned on in order to easily locate the code). In my opinion, the compiler's optimizations look quite fine to me (see below if needed).
But how can I optimize this code, where to begin? I think just using simple assembly instructions there's not a lot to do. I bet if I could employ parallelism this might give it quite a boost. I have started to think how I could re-arrange the sequences, usage of registers and accumulators, but I got lost very quickly.
Could anyone please give me some Ideas how to handle this problem (how to get started, some specific tricks and workarounds, other hints)?
Thank you for all your help.
Best regards,
Andreas
; wLeft |= ( (pBuf & 0x00F0) >> 4) << 8;
MOV *AR2,AC0
MOV *AR2,AR1 || SFTL AC0,#4,AC0
AND #61440,AR1,AR1
AND #3840,AC0,AR4
OR AR4,AR1
; wRight |= ( (pBuf & 0x000F) >> 0) << 8;
MOV *AR2+,AR4
AND #61440,AC0,AC0
AND #15,AR4,AC1
OR AC1 << #8, AC0
; pBuf = *pRaw++;
MOV *AR2+,AC1
; wLeft |= ( (pBuf & 0xF000) >> 12) << 4;
BFXTR #65280,AC1,AR4
AND #65520,AR4,AR4
OR AR4,AR1
; wRight |= ( (pBuf & 0x0F00) >> 8) << 4;
BFXTR #65520,AC1,AR4
AND #240,AR4,AR7
OR AR7,AC0
; wLeft |= ( (pBuf & 0x00F0) >> 4) << 0;
AND #15,AR4,AR4
OR AR4,AR1
; wRight |= ( (pBuf & 0x000F) >> 0) << 0;
AND #15,AC1,AR4
OR AR4,AC0
; *pLeft++ = wLeft,
MOV AR1,*AR3+
MOV AC0,*AR0+