2010-08-23 2 views
9

Я реализую КИХ-фильтр на процессоре ARM9 и пытаюсь использовать инструкцию SMLAL.Использование многопользовательской инструкции по сборке Inline Assembly в C++

Первоначально у меня был реализован следующий фильтр, и он отлично работал, за исключением того, что этот метод использует слишком большую вычислительную мощность для использования в нашем приложении.

uint32_t DDPDataAcq::filterSample_8k(uint32_t sample) 
{ 
    // This routine is based on the fir_double_z routine outline by Grant R Griffin 
    // - www.dspguru.com/sw/opendsp/alglib.htm 
    int i = 0; 
    int64_t accum = 0; 
    const int32_t *p_h = hCoeff_8K; 
    const int32_t *p_z = zOut_8K + filterState_8K; 


    /* Cast the sample to a signed 32 bit int 
    * We need to preserve the signdness of the number, so if the 24 bit 
    * sample is negative we need to move the sign bit up to the MSB and pad the number 
    * with 1's to preserve 2's compliment. 
    */ 
    int32_t s = sample; 
    if (s & 0x800000) 
     s |= ~0xffffff; 

    // store input sample at the beginning of the delay line as well as ntaps more 
    zOut_8K[filterState_8K] = zOut_8K[filterState_8K+NTAPS_8K] = s; 

    for (i =0; i<NTAPS_8K; ++i) 
    { 
     accum += (int64_t)(*p_h++) * (int64_t)(*p_z++); 
    } 

    //convert the 64 bit accumulator back down to 32 bits 
    int32_t a = (int32_t)(accum >> 9); 


    // decrement state, wrapping if below zero 
    if (--filterState_8K < 0) 
     filterState_8K += NTAPS_8K; 

    return a; 
} 

, которые я пытался заменить многократно аккумулировать встраиваемую сборку, поскольку GCC не использует инструкцию MAC даже с включенной оптимизацией. Я заменил на петлю со следующим:

uint32_t accum_low = 0; 
int32_t accum_high = 0; 

for (i =0; i<NTAPS_4K; ++i) 
{ 
    __asm__ __volatile__("smlal %0,%1,%2,%3;" 
     :"+r"(accum_low),"+r"(accum_high) 
     :"r"(*p_h++),"r"(*p_z++)); 
} 

accum = (int64_t)accum_high << 32 | (accum_low); 

Выход теперь я получаю, используя инструкцию SMLAL не отфильтрованные данные я ожидал. Я получаю случайные значения, которые, похоже, не имеют никакого шаблона или соединения с исходным сигналом или данными, которые я ожидаю.

У меня такое чувство, что я делаю что-то неправильно, разбивая 64-разрядный аккумулятор на верхний и нижний регистры для инструкции, или я неправильно их совмещаю. В любом случае я не уверен, почему я не могу получить правильный результат, заменив код C на встроенную сборку.

+0

Почему вы просто не используете библиотеку DSP? –

+4

Какую версию компилятора вы используете? Я попытался скомпилировать ваш код C только с помощью GCC 4.4.3, используя параметры -O3 -march = armv5te, и он сгенерировал команды smlal. –

+0

Я использую 4.3.2. Я не знал, что вы можете указать такой флаг -march. Как только я добавил его, GCC также производил сборку, на которую я надеялся. Благодаря! –

ответ

3

Какая версия компилятора вы используете? Я попытался скомпилировать ваш код C только с помощью GCC 4.4.3, используя параметры -O3 -march = armv5te, и он сгенерировал команды smlal.

Смежные вопросы