Перейти к содержанию
    

бага в оптимизаторе ICCAVR 3.20D

Я использую еще версию 3.20, но самую последнию версию компилера 3.20D

Тут неожиданно всплыла бага оптимизатора.

 

Самый короткий способ получить

#include <iom128.h>
__no_init __regvar volatile unsigned char test@14;

void test_failed(void)
{
    test = 0x0f;
    while(1) {
        PORTA = 0;
        PORTA = 0x0f;
    }
}

В листинге получаем

   4          void test_failed(void)
   \                     test_failed:
      5          {
   \   00000000                              REQUIRE ?Register_R14_is_global_regvar
      6              test = 0x0f;
   \   00000000   E00F                       LDI     R16,15
   \   00000002   2EE0                       MOV     R14,R16
      7              while(1) {
      8                  PORTA = 0;
   \                     ??test_failed_0:
   \   00000004   E000                       LDI     R16,0
   \   00000006   BB0B                       OUT     0x1B,R16
      9                  PORTA = 0x0f;
   \   00000008   BAEB                       OUT     0x1B,R14
   \   0000000A   CFFC                       RJMP    ??test_failed_0
     10              }
     11          }

 

А т.к. test используется в прерываниях...

У меня в проекте в одном месте есть похожее присваивание, а дальше регистр только в прерываниях используется...

 

У себя обошел примерно так:

void test_ok(void)
{
    volatile unsigned char dummy;
    dummy = 0x0f;
    test = dummy;
    while(1) {
        PORTA = 0;
        PORTA = 0x0f;
    }
}

     13          void test_ok(void)
   \                     test_ok:
     14          {
   \   00000000                              REQUIRE ?Register_R14_is_global_regvar
   \   00000000   95CA                       DEC     R28
     15              volatile unsigned char dummy;
     16              dummy = 0x0f;
   \   00000002   E00F                       LDI     R16,15
   \   00000004   8308                       ST      Y,R16
     17              test = dummy;
   \   00000006   8108                       LD      R16,Y
   \   00000008   2EE0                       MOV     R14,R16
     18              while(1) {
     19                  PORTA = 0;
   \                     ??test_ok_0:
   \   0000000A   E000                       LDI     R16,0
   \   0000000C   BB0B                       OUT     0x1B,R16
     20                  PORTA = 0x0f;
   \   0000000E   E00F                       LDI     R16,15
   \   00000010   BB0B                       OUT     0x1B,R16
   \   00000012   CFFB                       RJMP    ??test_ok_0
     21              }
     22          }

Как видно из второго листинга, с обычным volatile работает нормально сохраняет константу, потом загружает обратно, потом в регистр запихивает.

 

У меня тут валялся еще 4.11A тот же эффект.

Пропадает еще если вызывается хотя бы одна функция между присваиваниями.

Изменено пользователем KRS

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, реальная бага... :07:

Нечто похожее есть при работе с одинаковыми константами на WinAVR2006..., правда

там это не приводит к столь катастрофическим последствиям, там это проявляется просто в генрации

очень неоптимального кода.

 

В Вашем конкретном случае спасет замена:

test = 0x0f;

на

test = 0x0e;

test++;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В Вашем конкретном случае спасет замена:

test = 0x0f;

на

test = 0x0e;

test++;

К сожаленю это не атомарная опреация.

она транслируется в две mov r14, r16 inc r14

Атомарными получаются присваивания констант (кроме 1 она транслируется в clr inc).

Установка бита, очистка бита транслируется в ( set / clt bld ) таким образом можно передавать и считывать флаги в/из прерывания.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я использую еще версию 3.20, но самую последнию версию компилера 3.20D

Тут неожиданно всплыла бага оптимизатора.

...

У меня тут валялся еще 4.11A тот же эффект.

Проверил на 4.21А - тот же эффект. Проявляется на уровнях оптимизации Medium и High.

При уровнях None и Low все нормально, из регистра значение не берет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

и 4.30A тоже. Блин, неприятно.

 

Может кто, у кого есть EWAVR купленный, поставит их в известность? Или прислушаются и так?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

и 4.30A тоже. Блин, неприятно.

Может кто, у кого есть EWAVR купленный, поставит их в известность? Или прислушаются и так?

ИМХО, прислушаются и так...

Самым правильным, наверное, автору топика стоило бы зарегестрится на IAR, скачать еволюшен

версию, откомпилить примеры и послать в IAR листинг.

Может и какой бонус от IAR отвалится... :)

Тока регестриться лучше на частное лицо, на всякий случай...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, виноват. :( Это действительно бага. Правда в хэлпе сказано, что

 

The Global register variables are treated as a non-triggering volatile.

 

Если честно, "non-triggering volatile" не осознал.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Баг. Путает константу с переменной :(

 

Неа, забивает на волшебное слово volatile.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Неа, забивает на волшебное слово volatile.

 

Это он вам как бы говорит, что воровать как бы нехорошо.

Изменено пользователем IgorKossak

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Либо смайликов наставь, либо покажи что генерит лицензионный. А то пукнуть в воду и я могу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

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

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...