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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Что это фича или баг?, avr-gcc 4.1.2 WinAvr 20070525
xelax
сообщение Dec 1 2008, 07:46
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



Столкнулся с очень интересным эффектом. Есть два кода, с моей точки зрения, которые должны работать идентично. Но первый случай не работает, второй работает безупречно.
Код
tty ? (UDR1 = data) : (UDR0 = data);

disasm code:
+000023EA:   91E010C5    LDS     R30,0x10C5       Load direct from data space
+000023EC:   91F010C6    LDS     R31,0x10C6       Load direct from data space
+000023EE:   0FE9            ADD     R30,R25          Add without carry
+000023EF:   1DF1            ADC     R31,R1           Add with carry
+000023F0:   8180            LDD     R24,Z+0          Load indirect with

+000023F1:   938000CE    STS     0x00CE,R24       Store direct to data space
+000023F3:   918000CE    LDS     R24,0x00CE       Load direct from data space



Код
if (tty > 0)
    UDR1 = data;
  else
    UDR0 = data;

disasm come:
+000023E8:   91E010C5    LDS     R30,0x10C5       Load direct from data space
+000023EA:   91F010C6    LDS     R31,0x10C6       Load direct from data space
+000023EC:   0FE9           ADD     R30,R25          Add without carry
+000023ED:   1DF1          ADC     R31,R1           Add with carry
+000023EE:   8180           LDD     R24,Z+0          Load indirect with

+000023EF:   938000CE    STS     0x00CE,R24       Store direct to data space




При дизасме в первом случае, вижу на мой взгляд абсолютно бесполезную строчку
Код
LDS     R24,0x00CE       Load direct from data space

но которая(мне кажется) ломает функционал uart начисто (проявляется следующим образом: из регистра приёмника вычитывается байт, который был вычитан до этого. То есть вижу иногда в общем пакете по два одинаковых байта).

Кто-нибудь может пояснить значение этой строчки??? Рботающий и неработающий коды отличаются только ей. И чем собственно коснтрукция ? : ; для компилятора отличается от if else? 07.gif
Go to the top of the page
 
+Quote Post
forever failure
сообщение Dec 1 2008, 08:00
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 256
Регистрация: 6-03-05
Из: Екатеринбург
Пользователь №: 3 112



В первом случае в условии проверка на ненулевое значение, а во втором - на положительное. Может в этом разница ?
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Dec 1 2008, 08:09
Сообщение #3


Знающий
****

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



Цитата(xelax @ Dec 1 2008, 10:46) *
И чем собственно коснтрукция ? : ; для компилятора отличается от if else? 07.gif


? : возвращает результат, if else - нет. Больше вроде бы ничем.

Собственно в строчке LDS R24,0x00CE , насколько я понял, и возвращается результат операции UDR1 = data.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Dec 1 2008, 08:10
Сообщение #4


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(xelax @ Dec 1 2008, 11:46) *
но которая(мне кажется) ломает функционал uart начисто

Нескромный вопрос: tty у Вас volatile? Просто не могу себе представить ситуацию, когда селектором устройств является не volatile переменная...
Go to the top of the page
 
+Quote Post
xelax
сообщение Dec 1 2008, 08:21
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



Цитата(forever failure @ Dec 1 2008, 11:00) *
В первом случае в условии проверка на ненулевое значение, а во втором - на положительное. Может в этом разница ?


Да собственно говоря в if можно и на равенство 0 проверять, асм будет такой же (постоянство радует smile.gif ).

Меня просто напрягает, свободное обращение с регистром уарта UDR. Ведь и запись и чтение этого регистра запускают определённые физические процессы в уарте. А тут захотелось ему, он взял и вычитал значение из этого регистра в R24. Неприятное явление.

ЗЫ В IAR и тот и другой случаи работают нормально.

Цитата(Непомнящий Евгений @ Dec 1 2008, 11:09) *
? : возвращает результат, if else - нет. Больше вроде бы ничем.

Собственно в строчке LDS R24,0x00CE , насколько я понял, и возвращается результат операции UDR1 = data.



0x00CE это адрес UDR регистра, я не понимаю как это строчка может сообщать о результате операции. 07.gif

Цитата(_Pasha @ Dec 1 2008, 11:10) *
Нескромный вопрос: tty у Вас volatile? Просто не могу себе представить ситуацию, когда селектором устройств является не volatile переменная...



К моему стыду действительно не volatile. Эта переменная часть структуры, описывающей уарт
Код
typedef struct
{
  /** \brief tty - One of the defines UART_CHANNEL_0 or UART_CHANNEL_1.
  Which defines a number of UART. */
  uint8_t tty;
......
.....
.....
} UartDescriptor_t;
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Dec 1 2008, 08:23
Сообщение #6


Знающий
****

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



Цитата(xelax @ Dec 1 2008, 11:18) *
0x00CE это адрес UDR регистра, я не понимаю как это строчка может сообщать о результате операции. 07.gif


Ну вероятно GGC полагает, что результатом операции a=b является значение "a" после операции присваивания. А "а" у вас - UDR1 - вероятно помеченный volatile или еще как-то. Вот его значение и вычитывается...

И еще вопросик - я не въеду, где в приведенном вами дизасме происходит сравнение tty c 0? Или вы привели только кусочек?
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Dec 1 2008, 09:03
Сообщение #7


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(xelax @ Dec 1 2008, 12:21) *
я не понимаю как это строчка может сообщать о результате операции. 07.gif


Код
tty ? (UDR1 = data) : (UDR0 = data);

Выполняется (UDR1 = data) и результат выражения - это значение UDR1, которое надо предварительно прочитать, из-за того, что оно описано volatile. А то, что результат больше никому не нужен - это уже совсем другая история.

Мораль: хочешь, чтобы оно просто записало в порт, так и скажи компилеру, а проктология - не компьютерная наука. smile.gif
Так что это фича. И лишнее доказательство того, что компилер не может оградить программиста от ошибок.
Go to the top of the page
 
+Quote Post
xelax
сообщение Dec 1 2008, 09:12
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



Цитата(Непомнящий Евгений @ Dec 1 2008, 11:23) *
И еще вопросик - я не въеду, где в приведенном вами дизасме происходит сравнение tty c 0? Или вы привели только кусочек?


Да это кусок был...

вот более полная версия smile.gif, с сравнением :
Код
  7c:    90 91 00 00     lds    r25, 0x0000
  80:    80 91 00 00     lds    r24, 0x0000
  84:    89 17                   cp    r24, r25
  86:    01 f0                   breq    .+0      ;
  88:    e0 91 00 00     lds    r30, 0x0000
  8c:    f0 91 00 00     lds    r31, 0x0000
  90:    e9 0f                   add    r30, r25
  92:    f1 1d                   adc    r31, r1
  94:    80 81                   ld    r24, Z
  96:    80 93 ce 00     sts    0x00CE, r24


Это дизасм библиотечки, так что нет всех адресов laughing.gif

Ок. В принципе понял свою ошибку.
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Dec 1 2008, 09:15
Сообщение #9


Знающий
****

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



Цитата(_Pasha @ Dec 1 2008, 12:03) *
Выполняется (UDR1 = data) и результат выражения - это значение UDR1, которое надо предварительно прочитать, из-за того, что оно описано volatile. А то, что результат больше никому не нужен - это уже совсем другая история.


Кстати, по-идее даже просто запись UDR1=data должна приводить к вычитыванию UDR1 smile.gif

Т.е. получается что на один шаг оптимизатор срабатывает (выкидывая чтение в данном случае), а вот на два шага - в случае tty ? UDR1 = data : UDR0 = data - уже нет...
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Dec 1 2008, 09:28
Сообщение #10


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Непомнящий Евгений @ Dec 1 2008, 13:15) *
Т.е. получается что на один шаг оптимизатор срабатывает (выкидывая чтение в данном случае), а вот на два шага - в случае tty ? UDR1 = data : UDR0 = data - уже нет...

Вот автор сказал, что ИАР выкинул лишнее чтение, а мне грустно: если компилер таким изящным манером исправил логическую ошибку программиста (согласитесь, ошибка ведь была), то где гарантия, что не бывает обратных ситуаций, т.е. абсолютно правильные с точки зрения логики действия программера цензурируются оптимизатором и это рождает ошибку.
В общем, я все больше начинаю понимать gcc smile.gif
Go to the top of the page
 
+Quote Post
xelax
сообщение Dec 1 2008, 09:54
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



Цитата(_Pasha @ Dec 1 2008, 12:28) *
Вот автор сказал, что ИАР выкинул лишнее чтение, а мне грустно: если компилер таким изящным манером исправил логическую ошибку программиста (согласитесь, ошибка ведь была), то где гарантия, что не бывает обратных ситуаций, т.е. абсолютно правильные с точки зрения логики действия программера цензурируются оптимизатором и это рождает ошибку.
В общем, я все больше начинаю понимать gcc smile.gif


А собственно компилятор ошибок и не исправляет, если уж на то пошло. А скорее всего это строчки убираются в процессе оптимизации. Так что я бы не стал обвинять ни iar ни gcc.

Просто как показала практика у iar оптимизация тщательней делается smile.gif
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Dec 1 2008, 10:30
Сообщение #12


Знающий
****

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



Цитата(_Pasha @ Dec 1 2008, 12:28) *
Вот автор сказал, что ИАР выкинул лишнее чтение...
В общем, я все больше начинаю понимать gcc smile.gif


Я собственно имел в виду, что обе строчки
Код
UDR1 = data;

tty ? UDR1 = data : UDR0 = data;


Должны приводить к вычитыванию UDR1...

Только в первом случае это чтение оптимизится, а во втором нет...
Go to the top of the page
 
+Quote Post
msalov
сообщение Dec 1 2008, 10:33
Сообщение #13


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



Цитата(xelax @ Dec 1 2008, 11:54) *
А собственно компилятор ошибок и не исправляет, если уж на то пошло. А скорее всего это строчки убираются в процессе оптимизации. Так что я бы не стал обвинять ни iar ни gcc.

Просто как показала практика у iar оптимизация тщательней делается smile.gif

Никакая оптимизация не должна выкидывать чтение volatile переменной. Обсуждение было в теме http://electronix.ru/forum/index.php?showtopic=54275
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Dec 1 2008, 10:44
Сообщение #14


Знающий
****

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



Цитата(gotty @ Dec 1 2008, 13:33) *
Никакая оптимизация не должна выкидывать чтение volatile переменной.

Ну тогда получается, что конструкции вида
Код
РЕГИСТР = значение;

должны приводить к записи регистра и его последующему чтению. Т.е. запись регистра без чтения на С вообще невозможна smile.gif
Go to the top of the page
 
+Quote Post
xelax
сообщение Dec 1 2008, 10:51
Сообщение #15


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



Цитата(gotty @ Dec 1 2008, 13:44) *
Никакая оптимизация не должна выкидывать чтение volatile переменной.


Зачем доводить идею до абсурда.

Цитата(Непомнящий Евгений @ Dec 1 2008, 13:44) *
Код
РЕГИСТР = значение;

должны приводить к записи регистра и его последующему чтению. Т.е. запись регистра без чтения на С вообще невозможна smile.gif


А в случае с уартом в avr, будет полная неразбериха в линии. smile.gif
И ещё смысл делать read для write-only регистров sad.gif
Go to the top of the page
 
+Quote Post

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

 


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


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