Цитата(VDV @ Aug 7 2008, 21:01)

int8_t d = ADCH;
for( uint8_t i = 16; i--; )
{
int16_t mul = d * pgm_read_byte( &_dtmf_samples[_corr_index] );
_corr[i] += mul;
}
Макрос pgm_read_byte возвращает значение типа uint8_t (unsigned char),
переменная d имеет int8_t то есть signed char. Не смотря на то что AVR
имеет команду MULSU, avr-gcc ее не использует и вместо умножения (s)8 * (u)8
= 16, выполняет умножение 16*16=16. 8-битные умножения signed на signed и
unsigned на unsigned выполняются как 8 * 8 = 16. Вы можете попробовать
изменить тип d на uint8_t и для умножения компилятор сгенерирует код с
использованием инструкции MUL:
Код
mul r30,r16; 30 umulqihi3 [length = 3]
movw r24,r0
clr r1
Вот патч для GCC для выполнения умножения 8-битных signed на unsigned с
помощью MULSU.
Код
Index: gcc/config/avr/avr.md
===================================================================
--- gcc/config/avr/avr.md (revision 134646)
+++ gcc/config/avr/avr.md (working copy)
@@ -906,6 +920,17 @@
[(set_attr "length" "3")
(set_attr "cc" "clobber")])
+(define_insn "usmulqihi3"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
+ (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
+ "AVR_HAVE_MUL"
+ "mulsu %2,%1
+ movw %0,r0
+ clr r1"
+ [(set_attr "length" "3")
+ (set_attr "cc" "clobber")])
+
(define_expand "mulhi3"
[(set (match_operand:HI 0 "register_operand" "")
(mult:HI (match_operand:HI 1 "register_operand" "")
Можно на написать aыm вставку для 8-битного умножения signed на unsigned.
Анатолий.
Сообщение отредактировал aesok - Aug 8 2008, 06:49