Eigentlich sollte das schon gut auf C-Ebene gehen (wenn auch nicht so Effizient wie per asm).
z.B. eine fix-Mul, die 2 Werte (interpretiert als unsigned mit 8 Bit Vor- und Nachkomma) multipliziert:
Code:/*static inline*/ uint16_t fmul (uint16_t a, uint16_t b) { return (uint16_t) ((uint32_t) a*b >> 16); }Das ist schon mal deutlich effizienter als float (aber natürlich auch was anderesCode:.global fmul .type fmul, @function fmul: /* prologue: frame size=0 */ /* prologue end (size=0) */ movw r18,r22 ; 4 *movhi/1 [length = 1] clr r26 ; 12 zero_extendhisi2/1 [length = 2] clr r27 clr r20 ; 13 zero_extendhisi2/1 [length = 2] clr r21 movw r22,r24 ; 14 *movsi/1 [length = 2] movw r24,r26 rcall __mulsi3 ; 16 *mulsi3_call [length = 1] movw r26,r24 ; 17 *movsi/1 [length = 2] movw r24,r22 movw r24,r26 ; 35 *lshrsi3_const/2 [length = 3] clr r26 clr r27 /* epilogue: frame size=0 */ ret /* epilogue end (size=1) */ /* function fmul size 14 (13) */ .size fmul, .-fmul 00000094 <__mulsi3>: 94: 62 9f mul r22, r18 96: d0 01 movw r26, r0 98: 73 9f mul r23, r19 9a: f0 01 movw r30, r0 9c: 82 9f mul r24, r18 9e: e0 0d add r30, r0 a0: f1 1d adc r31, r1 a2: 64 9f mul r22, r20 a4: e0 0d add r30, r0 a6: f1 1d adc r31, r1 a8: 92 9f mul r25, r18 aa: f0 0d add r31, r0 ac: 83 9f mul r24, r19 ae: f0 0d add r31, r0 b0: 74 9f mul r23, r20 b2: f0 0d add r31, r0 b4: 65 9f mul r22, r21 b6: f0 0d add r31, r0 b8: 99 27 eor r25, r25 ba: 72 9f mul r23, r18 bc: b0 0d add r27, r0 be: e1 1d adc r30, r1 c0: f9 1f adc r31, r25 c2: 63 9f mul r22, r19 c4: b0 0d add r27, r0 c6: e1 1d adc r30, r1 c8: f9 1f adc r31, r25 ca: bd 01 movw r22, r26 cc: cf 01 movw r24, r30 ce: 11 24 eor r1, r1 d0: 08 95 ret)
Zum weiteren Optimieren kann man ja von dem Code ausgehen und weitere Kenntnise ausnutzen (z.B. welche Register in mulsi3 Anfangs 0 sind, das spart das Löschen, und man kann z.B. statt dessen __zero_reg__ draufaddieren.







Zitieren
Lesezeichen