Hier mal ein schöner Vergleich:
Code:
uint16_t fmac16(uint16_t op1, uint16_t op2, uint16_t op3)
{
uint16_t result;
// range checkto prevent overflow. It is necessary that at least one
// operand's high byte is != 0x80
op1 = (op1 != 0x8000)
? (op2 = (op2 != 0x80) ? op2 : 0x81), op1
: 0x8100;
asm volatile (
"fmuls %B1, %B2" "\n\t" // take high byte of op1 and op2 only
"add r0, %A3" "\n\t" // do a 16 bit add
"adc r1, %B3" "\n\t"
"movw %0, r0" "\n\t"
"brvc 0f" "\n\t" // check for overflow (pos/neg) @see fadd8
"ldi %A0, 0xff" "\n\t"
"ldi %B0, 0x7f" "\n\t"
"brcc 0f" "\n\t"
"ldi %A0, 0x00" "\n\t"
"ldi %B0, 0x80" "\n\t"
"0:" "\n\t"
: "=&a" (result)
: "a" (op1), "a" (op2), "a" (op3)
: "r0", "r1"
);
return result;
}
Für die eigentliche MAC Operation werde hier nur 5 Takte benötigt (fmul, add, adc und movw).
Eine direkte Implementierung in C
Code:
uint16_t op161;
uint16_t op162;
uint16_t op163;
uint16_t result16;
op161 = 0x8000;
op162 = 0x8000;
op163 = 0x7000;
result16 = op161*op162+op163; // <- Das hier
Ist als Assembler Code schon erheblich länger:
Code:
mul r18,r24
movw r20,r0
mul r18,r25
add r21,r0
mul r19,r24
add r21,r0
clr r1
movw r18,r20
ldd r24,Y+9
ldd r25,Y+10
add r24,r18
adc r25,r19
und benötigt 17 Takte, wobei die +/- Überlaufprüfung nochmal erheblich komplexer wäre.
Lesezeichen