Hallo, gibt es im avr-gcc fertige Funktionen für Addition/Subtraktion von uint16_t mit Saturierung? Ich hätte gerne optimierte Funktionen, die das Carry-Flag nutzen, will meinen eigenen Code aber am liebsten assemblerfrei halten.
avr-gcc kennt zumindest die notwendigen Bezeichner: https://gcc.gnu.org/onlinedocs/gcc/Fixed-Point.html Beitrag "Fixed-Point Support in avr-gcc?" Habe es aber selbst noch nicht verwendet...
Folgendes sollte gehen:
1 | #include <stdfix.h> |
2 | #include <stdint.h> |
3 | |
4 | static inline __attribute__((always_inline)) |
5 | uint16_t add_satu16 (uint16_t a, uint16_t b) |
6 | {
|
7 | unsigned sat fract fa = urbits (a); |
8 | unsigned sat fract fb = urbits (b); |
9 | return bitsur (fa + fb); |
10 | }
|
11 | |
12 | uint16_t add1 (uint16_t a) |
13 | {
|
14 | return add_satu16 (a, 1); |
15 | }
|
16 | |
17 | uint16_t addm1 (uint16_t a) |
18 | {
|
19 | return add_satu16 (a, -1u); |
20 | }
|
21 | |
22 | uint16_t add2 (uint16_t a, uint16_t b) |
23 | {
|
24 | return add_satu16 (a, b); |
25 | }
|
avr-gcc macht daraus:
1 | add1: |
2 | adiw r24,1 |
3 | brcc 0f |
4 | sbc r25,r25 |
5 | mov r24,r25 |
6 | 0: |
7 | ret |
8 | |
9 | addm1: |
10 | sbiw r24,1 |
11 | brcs 0f |
12 | ldi r25,0xff |
13 | mov r24,r25 |
14 | 0: |
15 | ret |
16 | |
17 | add2: |
18 | add r24,r22 |
19 | adc r25,r23 |
20 | brcc 0f |
21 | sbc r25,r25 |
22 | mov r24,r25 |
23 | 0: |
24 | ret |
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.