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

 
 
 
Reply to this topicStart new topic
> По-моему, глюк компилятора
Непомнящий Евген...
сообщение Nov 11 2007, 05:13
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Компилятор IAR AVR 4.30.1.3
Процессор ATMEGA2560
С++, максимальная оптимизация по скорости.
Полный текст приведен во вложении, там же lst - файл.
Проблема в функции tpzBINtoBCD, в следующем ее фрагменте:
Код
while(true)
{
   bool isLim = res.loc == bcd;  
   ...
}

res.loc и bcd - это объекты типа TBCDLocation (фактически - "указатель на тетраду байта", т.е. указатель на байт + признак старший\младший). Оператор == для них перегружен так:
Код
INLINE bool TBCDLocation::operator==(const TBCDLocation& b)
{
  return buf==b.buf && isFH==b.isFH;
}

Впрочем, если "проинлайнить" его руками, т.е. написать bool isLim = res.loc.buf == bcd.buf && res.loc.isFH==bcd.isFH - ничего не изменится.
Так вот, этот кусочек компилится так:
Код
250:                  bool isLim = res.loc == bcd;  
+0000011A:   1502        CP      R16,R2           Compare
+0000011B:   0513        CPC     R17,R3           Compare with carry
+0000011C:   F429        BRNE    PC+0x06          Branch if not equal
+0000011D:   2F12        MOV     R17,R18          Copy register       <<<<<
+0000011E:   1514        CP      R17,R4           Compare
+0000011F:   F411        BRNE    PC+0x03          Branch if not equal
+00000120:   E0E1        LDI     R30,0x01         Load immediate
+00000121:   C001        RJMP    PC+0x0002        Relative jump
+00000122:   E0E0        LDI     R30,0x00         Load immediate
+00000123:   2E5E        MOV     R5,R30           Copy register

res.loc лежит в трех регистрах: 17,16 - указатель на байт и 18 - признак старший\младший.
В указанной строчке 17 регистр перетирается 18-м и больше нигде не восстанавливается. Соответственно, при следующем обращении к res.loc получается бяка.
Если переписать функцию tpzBINtoBCD так, чтобы loc и isOverflow лежали в отдельных переменных и "собирались вместе" перед return, все прекрасно работает (этот вариант функции закомментирован в прилагаемом файле).
При этом получается такой ассемблерный код:
Код
313:                  bool isLim = msBCD == bcd;  
+00000112:   1768        CP      R22,R24          Compare
+00000113:   0779        CPC     R23,R25          Compare with carry
+00000114:   F421        BRNE    PC+0x05          Branch if not equal
+00000115:   16BB        CP      R11,R27          Compare
+00000116:   F411        BRNE    PC+0x03          Branch if not equal
+00000117:   E0E1        LDI     R30,0x01         Load immediate
+00000118:   C001        RJMP    PC+0x0002        Relative jump
+00000119:   E0E0        LDI     R30,0x00         Load immediate
+0000011A:   2E3E        MOV     R3,R30           Copy register

С точностью до номеров регистров все так же, как и выше, но нехорошего MOV уже нет.
Без оптимизации все работает и в первом варианте.

PS. программка тестовая, соответственно прерывания не включались.
PPS. пробовал скомпилировать под ATMEGA128 - проблема осталась.
Прикрепленные файлы
Прикрепленный файл  _.rar ( 9.13 килобайт ) Кол-во скачиваний: 23
 
Go to the top of the page
 
+Quote Post
rezident
сообщение Nov 11 2007, 13:19
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



А вы не пробовали пользоваться скобками, чтобы более доступно объяснить компилятору, чего же вы от него хотите?
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Nov 12 2007, 05:10
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Цитата(rezident @ Nov 11 2007, 16:19) *
А вы не пробовали пользоваться скобками, чтобы более доступно объяснить компилятору, чего же вы от него хотите?


Не понял вашего предложения: a==b && c==d - сначала проверка на равенство, потом and. Счас ради интереса попробовал ( a ==b ) && (c == d), не помогло.

Сообщение отредактировал Непомнящий Евгений - Nov 12 2007, 05:11
Go to the top of the page
 
+Quote Post
alexander55
сообщение Nov 12 2007, 05:57
Сообщение #4


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(Непомнящий Евгений @ Nov 12 2007, 08:10) *
Не понял вашего предложения: a==b && c==d - сначала проверка на равенство, потом and. Счас ради интереса попробовал ( a ==b ) && (c == d), не помогло.

Имеется ввиду
INLINE bool TBCDLocation::operator==(const TBCDLocation& cool.gif
{
return ((buf==b.buf) && (isFH==b.isFH));
}
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Nov 12 2007, 09:49
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Цитата(alexander55 @ Nov 12 2007, 08:57) *
Имеется ввиду
INLINE bool TBCDLocation::operator==(const TBCDLocation& b )
{
return ((buf==b.buf) && (isFH==b.isFH));
}


Я собственно это и сделал. Ничего не дало. Да и с какой радости должно дать - приоритет == больше, чем у &&.
Go to the top of the page
 
+Quote Post
alexander55
сообщение Nov 12 2007, 10:19
Сообщение #6


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(Непомнящий Евгений @ Nov 12 2007, 12:49) *
Я собственно это и сделал. Ничего не дало. Да и с какой радости должно дать - приоритет == больше, чем у &&.

Когда, что-то не работает проверяется все. Попробуйте отключить оптимизацию для начала.
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Nov 12 2007, 10:42
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Цитата(alexander55 @ Nov 12 2007, 13:19) *
Когда, что-то не работает проверяется все. Попробуйте отключить оптимизацию для начала.

Без оптимизации работает. Второй вариант работает и с оптимизацией и без, собственно им я и пользуюсь. Просто странно как-то. Первый раз напоролся на четкий глюк smile.gif
Go to the top of the page
 
+Quote Post
alexander55
сообщение Nov 12 2007, 11:22
Сообщение #8


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(Непомнящий Евгений @ Nov 12 2007, 13:42) *
Без оптимизации работает. Второй вариант работает и с оптимизацией и без, собственно им я и пользуюсь. Просто странно как-то. Первый раз напоролся на четкий глюк smile.gif

Попробуйте убрать inline.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 16:31
Рейтинг@Mail.ru


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