|
как побороть WinAVR?, и заставить просто скомпиллить как написано |
|
|
|
Aug 7 2008, 17:01
|
Частый гость
 
Группа: Участник
Сообщений: 152
Регистрация: 18-03-06
Пользователь №: 15 366

|
написана функция:
volatile int32_t _corr[2 * 8];//result of correlations volatile uint8_t _corr_index;//index for sample table int8_t PROGMEM _dtmf_samples[] = {...};
int8_t d = ADCH; for( uint8_t i = 16; i--; ) { int16_t mul = d * pgm_read_byte( &_dtmf_samples[_corr_index] ); _corr[i] += mul; }
в результате генерится совершенно безобразный код. умножение производится в 32-х битном виде, хотя явно написано умножение 2-х байтов включена оптимизация O3
если массив объявить как int8_t, то умножение делается для 2-х байтов, но!!!! используется mul вместо muls (хотя написано, что величины знаковые!!!) и в результате он зануляет старший байт, даже если идет приведение результата операции к int16_t
как побороть WinAVR?
что хочется: сделать знаковое умножение 2-х байтов, получить 16-ти битное значение. затем расширить его до 32-х бит, сложить с 32-х битной величиной из массива и запомнить в массиве результат.
и еще: ткните, плиз, носом где понятно написано как делать ассемблерные вставки. собственно, непонятно, как из асма взять данные из Сишной переменной и в нужную Сишную переменную отдать
|
|
|
|
|
 |
Ответов
|
Aug 8 2008, 06:37
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(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
|
|
|
|
|
Aug 8 2008, 07:25
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(aesok @ Aug 8 2008, 10:37)  Макрос 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:
Можно на написать asm вставку для 8-битного умножения signed на unsigned. У него массив в PROGMEM int8_t !!! Надо просто привести тип до умножения и будет счастье... Код (int8_t)pgm_read_byte(&_dtmf_samples[idx]) или написать макрос для чтения int8_t: Код #define pgm_read_sbyte(x) ((int8_t)pgm_read_byte(x))
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Aug 8 2008, 08:49
|
Частый гость
 
Группа: Участник
Сообщений: 152
Регистрация: 18-03-06
Пользователь №: 15 366

|
спасибо за ответы, я ошибся написав, что он делает 32 битное умножение, сорри, он делает 16-битное с 32-х битным результатом. при этом делает 3 умножения вместо 1! явное приведение типов при умножении к знаковым не помогает - перепробовал все, что пришло в голову.
Os оптимизация работает плохо. попробуйте, например, написать код: uint16_t d = ...; d >>= 1; d >>= 1; d >>= 1;
и посмотрите что он накомпиллит. с O3 тоже не сахар, но все получше код получается. //================================== в общем, к сожалению, в итоге я так и не понял, как сделать так, чтобы компиллятор сначала умножил два 8-ми битовых знаковых числа, затем получившееся 16-ти битное значение сложил 32-х битным. Использую WinAVR20080610 в паре с AVR studio 4.14
volatile int32_t _corr[2 * 8];//result of correlations volatile uint8_t _corr_index;//index for sample table int8_t PROGMEM _dtmf_samples[] = {...};
int8_t d = ADCH; for( uint8_t i = 16; i--; ) { int16_t mul = (int8_t)d * (int8_t)pgm_read_byte( &_dtmf_samples[_corr_index] ); _corr[i] += (int32_t)mul; }
такой код не приводит к желаемому результату
Сообщение отредактировал VDV - Aug 8 2008, 09:08
|
|
|
|
|
Aug 8 2008, 13:04
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(VDV @ Aug 8 2008, 12:49)  такой код не приводит к желаемому результату -O3: Код mul r22,r14 ; movw r24,r0 mul r22,r15 add r25,r0 mul r23,r14 add r25,r0 clr r1 -Os: Код muls r30,r16 ; movw r24,r0 clr r1 Анатолий.
|
|
|
|
Сообщений в этой теме
VDV как побороть WinAVR? Aug 7 2008, 17:01 aesok Цитата(VDV @ Aug 7 2008, 21:01) в результ... Aug 7 2008, 19:36 demiurg_spb Цитата(VDV @ Aug 7 2008, 21:01) что хочет... Aug 7 2008, 20:20 777777 Цитата(VDV @ Aug 7 2008, 21:01) ткните, п... Aug 8 2008, 04:36 AHTOXA Цитата(777777 @ Aug 8 2008, 10:36) Ассемб... Aug 8 2008, 05:59   ReAl Цитата(VDV @ Aug 8 2008, 11:49) Os оптими... Aug 8 2008, 13:13 VDV мда....
ни с О3 ни с Os код нормально не генерит т... Aug 8 2008, 13:39 aesok Цитата(VDV @ Aug 8 2008, 17:39) блин, а у... Aug 8 2008, 14:04  VDV Цитата(aesok @ Aug 8 2008, 18:04) НЕВЕРЮ... Aug 8 2008, 14:14   aesok Цитата(VDV @ Aug 8 2008, 18:14)
А вот Э... Aug 8 2008, 14:20 VDV код приведен для пояснения смысла проблемы, а не о... Aug 8 2008, 14:57 AHTOXA Цитата(VDV @ Aug 8 2008, 20:57) проигрышь... Aug 8 2008, 16:02 _Pasha Цитата(777777 @ Aug 8 2008, 08:36) Что не... Aug 9 2008, 08:53
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|