Cool instructions
on this page, I will describe some instructions I found interesting on the AVR32 CPUs.
BFTEXU and SUBHS
Those two instructions are powerfull. BFTEXU allows you to extract 'n' bits starting at position 'm' in register 'X' and store the result in register 'Y' at position 0 and pad the rest with zeros. Basically, it does all that for you in 1 cycle only:
bfextu r5,r8,5,4
is the same as:
mov r5,r8
lsr r5,5
mov r8,0x0F
and.w r5,r8
SUBHS r,i will substract 'i' from 'r' and store the result in 'r' only if the carry flag is cleared. Otherwise, it will behave as a NOP. Knowing this, it would be easy to write a function that converts a 32bit number into its ascii representation. Assume that the follwing function takes 'r8' as the input number and we will output each char on the serial port from the MSB to LSB
swap.b r8
mov r4,4 ; we will do 4 iterations, one for each byte
1: bfextu r5,r8,4,4 ; get me the high nibble
sub r5,-48 ; substracting -48 is the same as adding 48 right?
cp r5,58 ; is the ascii char over '9'?
subhs r5,-7 ; if ascii overflowed '9', then add 7 to make it a letter
rcall sendSerial
bfextu r5,r8,0,4 ; get me the low nibble
sub r5,-48 ; substracting -48 is the same as adding 48 right?
cp r5,58 ; is the ascii char over '9'?
subhs r5,-7 ; if ascii overflowed '9', then add 7 to make it a letter
rcall sendSerial
lsr r8,8
sub r4,1
brne 1b
BREV
When writing an FFT on a x86 architecture, you dream of having access to such an instruction. BREV allows you to transform 00000000000000000000000000100110 into 01100100000000000000000000000000. It is a bit reversal. I just did that in one cycle only with one instruction. Can you imagine doing that in C? looping through each bit, making shifts, 'OR' etc...
BLD
BLD r,n lets you take bit 'n' from register 'r' and store it in the carry flag. Having this in the carry flag lets you make a conditional branch the way you like without even having to compare anything. Without that instruction, you would need to 'AND' the register with a bit mask, compare the result with 0 and branch conditionally. With BLD, I don't even have to change any registers and I save "AND" step.