Hier mal ein schöner Vergleich:
Für die eigentliche MAC Operation werde hier nur 5 Takte benötigt (fmul, add, adc und movw).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; }
Eine direkte Implementierung in C
Ist als Assembler Code schon erheblich länger: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
und benötigt 17 Takte, wobei die +/- Überlaufprüfung nochmal erheblich komplexer wäre.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







Zitieren

Lesezeichen