Can any one explain the function #define x( a, b) \ ({ _asm_volatile....

i am trying to change a arduino lenardo program to make it work on Arduino DUE. Can any one explain the following function:

#define mult_shf_s16x16( a, b)
({
int prod, val1=a, val2=b;
asm volatile ( \
"muls %B1, %B2 \n\t"
"mov %B0, r0 \n\t" \
"mul %A1, %A2 \n\t" \
"mov %A0, r1 \n\t" \
"mulsu %B1, %A2 \n\t" \
"add %A0, r0 \n\t" \
"adc %B0, r1 \n\t" \
"mulsu %B2, %A1 \n\t" \
"add %A0, r0 \n\t" \
"adc %B0, r1 \n\t" \
"clr r1 \n\t" \
: "=&d" (prod)
: "a" (val1), "a" (val2)
);
prod;
})

I believe it's origins are from here:

https://coolarduino.wordpress.com/2012/03/24/radix-4-fft-integer-math/

and it's part of his fft algorithm. It looks like he has a DUE library version.

It's a macro to fast multiply a and b and return the product on an 8 bit AVR (all AVR's are 8 bit).

On a Due you would just multiply the values.

Try to make your Due integers 32-bit for speed, that's the native word length for that chip.

It may be specifically a custom function to multiply a signed int by an unsigned int.

You can look up the definition of muls and mulsu, the explanation is not very clear.

If you are going to run the code on the due I would replace it with regular arithmetic using standard 32 bit ints.

The 2 low bytes multiply unsigned (and carry) then the 2 high bytes multiply signed (and add) which takes 4 bytes that I know of. I don't completely follow the syntax so I'm guessing on what I see.

This is, in general, the fastest way on 8-bit AVRs using avr-gcc to multiply two ints and produce a long
result. Otherwise the compiler only knows about casting the ints to longs and then
doing long x long multiply which is much slower.

Don't worry about it, just use * on the Due. For this particular function I think the semantics
you want are

  ((a * b) >> 16)

but I might be wrong - context should make it clear.

Due is native 32 bit. Just use longs.

Forth language has a scaling word (command) */ that multiplies 2 16 bit ints into a 32 bit space then divides by a 3rd 16 bit int and leaves a 16 bit result.

What do %A0 %A1 %A2 etc refer to?

And besides, our compiler does a good job of optimizing. It probably knows more about the Due than I do.

What do %A0 %A1 %A2 etc refer to?

These refer to the method by which the piece of assembler code knows where to get the values it is going to multiply.

There is an explanation somewhere online of how embedded assembly language works.