From 5b4e5290c4c840f79722691c584cafc5c4223db0 Mon Sep 17 00:00:00 2001 From: schodet Date: Sun, 7 Nov 2004 12:49:10 +0000 Subject: Fixed and tested mul_f824. --- n/asserv/src/dsp.c | 83 ++++++++++++++++++++++++++--------------------- n/asserv/src/dsp_check.pl | 36 ++++++++++++++++++++ 2 files changed, 82 insertions(+), 37 deletions(-) (limited to 'n/asserv') diff --git a/n/asserv/src/dsp.c b/n/asserv/src/dsp.c index 2e940db..bb81fdb 100644 --- a/n/asserv/src/dsp.c +++ b/n/asserv/src/dsp.c @@ -48,7 +48,7 @@ dsp_add_sat_i16i16 (int16_t a, int16_t b) return a; } -/** Multiply signed 16 by fixed unsigned 8.8. */ +/** Multiply signed 16 by unsigned 8.8, return signed 16. */ extern inline int16_t dsp_mul_i16f88 (int16_t a, uint16_t b) { @@ -68,7 +68,7 @@ dsp_mul_i16f88 (int16_t a, uint16_t b) return r; } -/** Multiply f8.24 by f8.24. */ +/** Multiply signed 8.24 by signed 8.24, return signed 8.24. */ int32_t dsp_mul_f824 (int32_t a, int32_t b) { @@ -76,77 +76,86 @@ dsp_mul_f824 (int32_t a, int32_t b) ar = a; br = b; int32_t r; + int8_t z; asm ("" - "clr r2\n\t" + "clr %1\n\t" /* Low dword (>> 8, with 8 guards). */ - "mul %A1, %B2\n\t" + "mul %A2, %B3\n\t" "movw %A0, r0\n\t" "clr %C0\n\t" "clr %D0\n\t" - "mul %A1, %A2\n\t" + "mul %A2, %A3\n\t" "add %A0, r1\n\t" - "adc %B0, r2\n\t" - "adc %C0, r2\n\t" - "mul %B1, %A2\n\t" + "adc %B0, %1\n\t" + "adc %C0, %1\n\t" + "mul %B2, %A3\n\t" "add %A0, r0\n\t" "adc %B0, r1\n\t" - "adc %C0, r2\n\t" - "mul %A1, %C2\n\t" + "adc %C0, %1\n\t" + "mul %A2, %C3\n\t" "add %B0, r0\n\t" "adc %C0, r1\n\t" - "adc %D0, r2\n\t" - "mul %B1, %B2\n\t" + "adc %D0, %1\n\t" + "mul %B2, %B3\n\t" "add %B0, r0\n\t" "adc %C0, r1\n\t" - "adc %D0, r2\n\t" - "mul %C1, %A2\n\t" + "adc %D0, %1\n\t" + "mul %C2, %A3\n\t" "add %B0, r0\n\t" "adc %C0, r1\n\t" - "adc %D0, r2\n\t" + "adc %D0, %1\n\t" /* Shift. */ "movw %A0, %C0\n\t" /* Upper word. */ - "mulsu %D2, %C1\n\t" + "mulsu %D3, %C2\n\t" "movw %C0, r0\n\t" - "mulsu %D2, %A1\n\t" + "mulsu %D3, %A2\n\t" + "sbc %C0, %1\n\t" + "sbc %D0, %1\n\t" "add %A0, r0\n\t" "adc %B0, r1\n\t" - "adc %C0, r2\n\t" - "adc %D0, r2\n\t" - "mul %B1, %C2\n\t" + "adc %C0, %1\n\t" + "adc %D0, %1\n\t" + "mul %B2, %C3\n\t" "add %A0, r0\n\t" "adc %B0, r1\n\t" - "adc %C0, r2\n\t" - "adc %D0, r2\n\t" - "mul %C1, %B2\n\t" + "adc %C0, %1\n\t" + "adc %D0, %1\n\t" + "mul %C2, %B3\n\t" "add %A0, r0\n\t" "adc %B0, r1\n\t" - "adc %C0, r2\n\t" - "adc %D0, r2\n\t" - "mulsu %D1, %A2\n\t" + "adc %C0, %1\n\t" + "adc %D0, %1\n\t" + "mulsu %D2, %A3\n\t" + "sbc %C0, %1\n\t" + "sbc %D0, %1\n\t" "add %A0, r0\n\t" "adc %B0, r1\n\t" - "adc %C0, r2\n\t" - "adc %D0, r2\n\t" - "mulsu %D2, %B1\n\t" + "adc %C0, %1\n\t" + "adc %D0, %1\n\t" + "mulsu %D3, %B2\n\t" + "sbc %D0, %1\n\t" "add %B0, r0\n\t" "adc %C0, r1\n\t" - "adc %D0, r2\n\t" - "mul %C1, %C2\n\t" + "adc %D0, %1\n\t" + "mul %C2, %C3\n\t" "add %B0, r0\n\t" "adc %C0, r1\n\t" - "adc %D0, r2\n\t" - "mulsu %D1, %B2\n\t" + "adc %D0, %1\n\t" + "mulsu %D2, %B3\n\t" + "sbc %D0, %1\n\t" "add %B0, r0\n\t" "adc %C0, r1\n\t" - "adc %D0, r2\n\t" - "mulsu %D1, %C2\n\t" + "adc %D0, %1\n\t" + "mulsu %D2, %C3\n\t" "add %C0, r0\n\t" "adc %D0, r1\n\t" - "muls %D1, %D2\n\t" + "muls %D2, %D3\n\t" "add %D0, r0\n\t" "clr r1\n\t" - : "=&r" (r) : "a" (ar), "a" (br) : "r0", "r2"); + : "=&r" (r), "=r" (z) : "a" (ar), "a" (br) : "r0"); return r; } +/** Compute cosinus. */ + diff --git a/n/asserv/src/dsp_check.pl b/n/asserv/src/dsp_check.pl index 69384e2..738d32e 100644 --- a/n/asserv/src/dsp_check.pl +++ b/n/asserv/src/dsp_check.pl @@ -24,6 +24,27 @@ sub check_mul } } +sub check_mul_f824 +{ + my ($a, $b, $r) = @_; + $a = $a / (1 << 24); + $b = $b / (1 << 24); + my $m = floor ($a * $b * (1 << 24)); + if ($m > (1 << 31) - 1 || $m < -(1 << 31)) + { + print "overflow $a * $b = $r ($m)\n"; + } + elsif ($m == $r) + { + print "pass $a * $b = $r\n"; + } + else + { + print "fail $a * $b = $r ($m)\n"; + $fail = 1; + } +} + while (<>) { chomp; @@ -39,6 +60,21 @@ while (<>) check_mul $a, $b, $r; check_mul -$a, $b, $R; } + if (/^A (-?\d+)$/) + { + my $a = $1; + $_ = <>; chomp; + next unless (/^B (-?\d+)$/); + my $b = $1; + $_ = <>; chomp; + next unless (/^r (-?\d+)$/); + my $r = $1; + $_ = <>; chomp; + next unless (/^R (-?\d+)$/); + my $R = $1; + check_mul_f824 $a, $b, $r; + check_mul_f824 -$a, $b, $R; + } } if ($fail) -- cgit v1.2.3