реклама на сайте
подробности

 
 
> Пропуск операции
jorikdima
сообщение Dec 8 2009, 18:33
Сообщение #1


тут может быть ваша реклама
*****

Группа: Свой
Сообщений: 1 164
Регистрация: 15-03-06
Из: Санкт-Петербург/CA
Пользователь №: 15 280



Никак понять не могу почему ИАР (4.21.2 (4.21.2.50066) для MSP430 с аппаратным умножителем) пропускает операцию умножения. Я бывало уже смотрел в сторону этого компилятора косо, но все время неправым оказывался я smile.gif Может и теперь во мне дело.
Однако, вот такой вот код есть.
Код
#include "io430.h"

typedef signed char INT8;
typedef signed short INT16;
typedef signed long INT32;
typedef signed long long INT64;

typedef unsigned char UINT8;
typedef unsigned short UINT16;
typedef unsigned long UINT32;
typedef unsigned long long UINT64;

INT16 FilterSample(const INT16 sample );

const INT16 coeffs[4][2][3] ={
      {{16384, -28354, 16384}, {16384, -28552, 14866}},
      {{16384, -26784, 16384}, {16384, -25180, 11711}},
      {{16384, -20728, 16384}, {16384, -20769, 7916}},
      {{16384, 9571, 16384}, {16384, -16608, 4444}} };

INT16 state[2][2];
INT16 (*coef)[3];

int main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
  
  coef = (INT16(*)[3])&coeffs[0][0][0];

  FilterSample(783);
}


//#pragma optimize = none
INT16 FilterSample(const INT16 sample )
{
    INT32 res = (INT32)coef[0][0] * sample;
    for (UINT8 i = 0; i < 2; i++)
    {      
        INT32 r1 = (INT32)state[0][i] * coef[0][i + 1];
        INT32 r2 = (INT32)state[1][i] * coef[1][i + 1];
        
        res += r1 - r2;        

    }
    res = (INT16)(res >> 14);
        
    return res;
}


Конкретно интересует место
Код
INT32 r1 = (INT32)state[0][i] * coef[0][i + 1];
        INT32 r2 = (INT32)state[1][i] * coef[1][i + 1];
        
        res += r1 - r2;

Тут все просто берется два произведения, берется разность между ними и интегрируется в переменной res.
Так вот листинг этой функции (FilterSample) с включенной оптимизацией выглядит вот так вот:
Код
FilterSample:
004048    120A               push.w  R10
00404A    120B               push.w  R11
00404C    1208               push.w  R8
00404E    1209               push.w  R9
004050    1206               push.w  R6
    INT32 res = (INT32)coef[0][0] * sample;
004052    421A 1108          mov.w   &coef,R10
004056    1202               push.w  SR
004058    C232               dint
00405A    4303               nop
00405C    4AA2 0132          mov.w   @R10,&MPYS
004060    4C82 0138          mov.w   R12,&OP2
004064    421C 013A          mov.w   &RESLO,R12
004068    421D 013C          mov.w   &RESHI,R13
00406C    4132               pop.w   SR
    for (UINT8 i = 0; i < 2; i++)
00406E    403E 1100          mov.w   #0x1100,R14
004072    4A0B               mov.w   R10,R11
004074    522B               add.w   #0x4,R11
        res += r1 - r2;        
004076    1202               push.w  SR
004078    C232               dint
00407A    4303               nop
00407C    4132               pop.w   SR
00407E    580C               add.w   R8,R12
004080    690D               addc.w  R9,R13
004082    1202               push.w  SR
004084    C232               dint
004086    4303               nop
004088    4E92 0004 0132     mov.w   0x4(R14),&MPYS
00408E    4A92 0008 0138     mov.w   0x8(R10),&OP2
004094    4218 013A          mov.w   &RESLO,R8
004098    4219 013C          mov.w   &RESHI,R9
00409C    4132               pop.w   SR
00409E    880C               sub.w   R8,R12
0040A0    790D               subc.w  R9,R13
    for (UINT8 i = 0; i < 2; i++)
0040A2    532A               incd.w  R10
0040A4    532E               incd.w  R14


Почему я вижу только одно умножение??? Соответствующее рассчету r2. А умножение в рассчете r1 отсутствует, причем вся подготовка для него существует (в виде запрета прерывания, сохранение статусного регистра, затем его восстановления).
Я приаттачил проект, если кому интересно, точнее выдержку из рабочего проекта с интересующим кодом.
Интересно следующее, если отключить оптимизацию - работает, есть два умножения. Если включить опцию Hardware multiplier->Use only lib calls то тоже работает. В этом случае компайлер просто вызывает функции с умножением, а не инлайнит их как обычно, но работает.
Почему ИАР не умножает второй раз (точнее первый раз)?
Спасибо.

Прикрепленный файл  mult.rar ( 7.1 килобайт ) Кол-во скачиваний: 95
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th June 2025 - 22:40
Рейтинг@Mail.ru


Страница сгенерированна за 0.0138 секунд с 7
ELECTRONIX ©2004-2016