summaryrefslogtreecommitdiff
path: root/n/avr
diff options
context:
space:
mode:
Diffstat (limited to 'n/avr')
-rw-r--r--n/avr/modules/math/fixed/fixed.h16
-rw-r--r--n/avr/modules/math/fixed/fixed_div_f824.avr.S8
-rw-r--r--n/avr/modules/math/fixed/fixed_mul_f824.avr.S6
-rw-r--r--n/avr/modules/math/fixed/test/Makefile2
-rw-r--r--n/avr/modules/math/fixed/test/test_fixed.c81
5 files changed, 107 insertions, 6 deletions
diff --git a/n/avr/modules/math/fixed/fixed.h b/n/avr/modules/math/fixed/fixed.h
index ab20779..95b1766 100644
--- a/n/avr/modules/math/fixed/fixed.h
+++ b/n/avr/modules/math/fixed/fixed.h
@@ -25,6 +25,8 @@
*
* }}} */
+#ifndef HOST
+
/** Multiply f8.24 by f8.24, return f8.24. */
#define fixed_mul_f824(a, b) ({ \
uint16_t dummy; \
@@ -33,4 +35,18 @@
int32_t
fixed_mul_f824_asm (uint16_t dummy, int32_t a, int32_t b);
+/** Divide f8.24 by f8.24, return f8.24. */
+int32_t
+fixed_div_f824 (int32_t a, int32_t b);
+
+#else /* HOST */
+
+/** Multiply f8.24 by f8.24, return f8.24. */
+#define fixed_mul_f824(a, b) (((uint64_t) (a) * (uint64_t) (b)) >> 24)
+
+/** Divide f8.24 by f8.24, return f8.24. */
+#define fixed_div_f824(a, b) (((uint64_t) (a) << 24) / (uint64_t) (b))
+
+#endif
+
#endif /* fixed_h */
diff --git a/n/avr/modules/math/fixed/fixed_div_f824.avr.S b/n/avr/modules/math/fixed/fixed_div_f824.avr.S
index 76992c3..43f4e0c 100644
--- a/n/avr/modules/math/fixed/fixed_div_f824.avr.S
+++ b/n/avr/modules/math/fixed/fixed_div_f824.avr.S
@@ -23,6 +23,10 @@
;
; }}}
+; Perfs:
+; 1186 cycles in worse case
+; 843 per second, per MHz
+
#define dd3 r25
#define dd2 r24
#define dd1 r23
@@ -44,7 +48,7 @@
#define cnt r16
- .section .text
+ .text
.global fixed_div_f824
.func fixed_div_f824
fixed_div_f824:
@@ -159,4 +163,4 @@ fixed_div_f824:
; Return.
1: pop r16
ret
- .endfunc
+ .endfunc
diff --git a/n/avr/modules/math/fixed/fixed_mul_f824.avr.S b/n/avr/modules/math/fixed/fixed_mul_f824.avr.S
index ab69799..853dcb6 100644
--- a/n/avr/modules/math/fixed/fixed_mul_f824.avr.S
+++ b/n/avr/modules/math/fixed/fixed_mul_f824.avr.S
@@ -51,6 +51,10 @@
; avoided.
; All multiplications results are added together. If the result is negative,
; do the sign extension (the sbc instructions).
+;
+; Perfs:
+; 91 cycles
+; 10989 per second, per MHz
#define dummy1 r25
#define dummy0 r24
@@ -77,7 +81,7 @@
#define z r30
- .section .text
+ .text
.global fixed_mul_f824_asm
.func fixed_mul_f824_asm
fixed_mul_f824_asm:
diff --git a/n/avr/modules/math/fixed/test/Makefile b/n/avr/modules/math/fixed/test/Makefile
index a70ca2d..23be911 100644
--- a/n/avr/modules/math/fixed/test/Makefile
+++ b/n/avr/modules/math/fixed/test/Makefile
@@ -3,7 +3,7 @@ PROGS = test_fixed
test_fixed_SOURCES = test_fixed.c
DOC =
EXTRACTDOC =
-MODULES = uart proto math/fixed
+MODULES = uart proto utils math/fixed math/random
CONFIGFILE = avrconfig.h
# atmega8, atmega8535, atmega128...
AVR_MCU = atmega8
diff --git a/n/avr/modules/math/fixed/test/test_fixed.c b/n/avr/modules/math/fixed/test/test_fixed.c
index d42dda3..d19f63a 100644
--- a/n/avr/modules/math/fixed/test/test_fixed.c
+++ b/n/avr/modules/math/fixed/test/test_fixed.c
@@ -24,21 +24,98 @@
* }}} */
#include "common.h"
#include "modules/math/fixed/fixed.h"
+#include "modules/math/random/random.h"
#include "modules/uart/uart.h"
#include "modules/proto/proto.h"
+#include "modules/utils/utils.h"
#include "io.h"
void
proto_callback (uint8_t cmd, uint8_t size, uint8_t *args)
{
+ uint8_t ap, bp, as, bs;
+ uint16_t i;
+ int32_t al, bl, rl[4];
+ uint32_t patl[] = { 0xa66a6aa6, 0x5a5affff, 0xffcdffcd, 0xffffffff };
+#define patn (sizeof (patl) / sizeof (patl[0]))
+#define c(cmd, size) (cmd << 8 | size)
+ switch (c (cmd, size))
+ {
+ case c ('z', 0):
+ utils_reset ();
+ break;
+ case c ('m', 0):
+ for (ap = 0; ap < patn; ap++)
+ for (bp = 0; bp < patn; bp++)
+ for (as = 0; as < 32; as++)
+ for (bs = 0; bs < 32; bs++)
+ {
+ al = patl[ap] >> as;
+ bl = patl[bp] >> bs;
+ proto_send2d ('a', al, bl);
+ rl[0] = fixed_mul_f824 (al, bl);
+ rl[1] = fixed_mul_f824 (-al, bl);
+ rl[2] = fixed_mul_f824 (al, -bl);
+ rl[3] = fixed_mul_f824 (-al, -bl);
+ proto_send4d ('r', rl[0], rl[1], rl[2], rl[3]);
+ }
+ for (i = 0; i < 64000; i++)
+ {
+ al = random_u32 ();
+ bl = random_u32 ();
+ proto_send2d ('a', al, bl);
+ rl[0] = fixed_mul_f824 (al, bl);
+ rl[1] = fixed_mul_f824 (-al, bl);
+ rl[2] = fixed_mul_f824 (al, -bl);
+ rl[3] = fixed_mul_f824 (-al, -bl);
+ proto_send4d ('r', rl[0], rl[1], rl[2], rl[3]);
+ }
+ break;
+ case c ('d', 0):
+ for (ap = 0; ap < patn; ap++)
+ for (bp = 0; bp < patn; bp++)
+ for (as = 0; as < 32; as++)
+ for (bs = 0; bs < 32; bs++)
+ {
+ al = patl[ap] >> as;
+ bl = patl[bp] >> bs;
+ proto_send2d ('a', al, bl);
+ rl[0] = fixed_div_f824 (al, bl);
+ rl[1] = fixed_div_f824 (-al, bl);
+ rl[2] = fixed_div_f824 (al, -bl);
+ rl[3] = fixed_div_f824 (-al, -bl);
+ proto_send4d ('r', rl[0], rl[1], rl[2], rl[3]);
+ }
+ for (i = 0; i < 64000; i++)
+ {
+ al = random_u32 ();
+ bl = random_u32 ();
+ proto_send2d ('a', al, bl);
+ rl[0] = fixed_div_f824 (al, bl);
+ rl[1] = fixed_div_f824 (-al, bl);
+ rl[2] = fixed_div_f824 (al, -bl);
+ rl[3] = fixed_div_f824 (-al, -bl);
+ proto_send4d ('r', rl[0], rl[1], rl[2], rl[3]);
+ }
+ break;
+ default:
+ proto_send0 ('?');
+ return;
+ }
+ /* When no error acknoledge. */
+ proto_send (cmd, size, args);
+#undef c
}
int
main (void)
{
- volatile int32_t a = 42;
sei ();
uart0_init ();
- fixed_mul_f824 (-a, 0);
proto_send0 ('z');
+ while (1)
+ {
+ uint8_t c = uart0_getc ();
+ proto_accept (c);
+ }
}