|
Глюки IAR ARM 5.4, Глючная оптимизация в IAR ARM 5.4 |
|
|
|
Jan 18 2010, 14:35
|
Группа: Участник
Сообщений: 10
Регистрация: 21-12-06
Из: Питер
Пользователь №: 23 756

|
Привет всем! Неожиданно проявилась проблема с IAR. После перехода на версию 5.4 Full девайс на LPC1766 стал глючить. Оптимизация - High/Balanced. Анализ выявил следующее. Заглючила строка сравнивающая старшее и младшее слово Код INT32U kc=key_code; // key_code тоже INT32U if(!(0xFFFF&(kc^(kc>>16)))) {...} Компилятор породил следущий код Код \ 0000013C 080C LSRS R0,R1,#+16 // в R1 находится kc \ 0000013E 91EA000F TEQ R1,R0 \ 00000142 4DD1 BNE.N ??__int_display_2 Очевидно, что 0xFFFF проигнорирован напрочь. Простая перестановка его в конец ничего не изменила. Однако, после некоторых манипуляций, конструкция была изменена на Код if((0xFFFF&kc)==(kc>>16)){...} Что породило уже рабочую последовательность Код \ 0000013C 88B2 UXTH R0,R1 // в R1 находится kc \ 0000013E B0EB114F CMP R0,R1, LSR #+16 \ 00000142 4DD1 BNE.N ??__int_display_2 Я, конечно, понимаю, что в IAR люди работают и ничего человеческое им не чуждо. Посмотрел на сайте и скачал Evalution версии 5.41, однако ничего не изменилось!!!! На мой взгляд, оба варианта сравнения идентичны по сути. Может быть первоначальный вариант и не столь очевиден, НО компилятора это не должно касаться. Такого рода конструкций в проге куча. Что же теперь, всё перепроверять на понятность и адекватность компилятора? Печально, но я IARу раньше доверял как родному. Суть вопроса - версию 5.4 в топку или я чего-то не не понимаю? Заранее благодарен.
|
|
|
|
|
Jan 18 2010, 18:02
|
Группа: Участник
Сообщений: 10
Регистрация: 21-12-06
Из: Питер
Пользователь №: 23 756

|
Доброго времени суток. Посмотрел в старой копии, что генерировал 5.3. В R3 находится значение kc. Код \ 0000012A 83EA1342 EOR R2,R3,R3, LSR #+16 \ 0000012E 92B2 UXTH R2,R2 \ 00000130 002A CMP R2,#+0 \ 00000132 54D1 BNE.N ??__int_display_3 Немного длиннее, но, главное, все корректно. Следовательно в 5.4 "улучшили" чего-то. Учитывая, что у меня trial, писать в IAR бесполезно, а с моим знанием английского ещё и безсмысленно. Так что, любители новых версий IAR будьте осторожны - не выбрасывайте 5.3. Удачи!
Сообщение отредактировал Ytrnj - Jan 18 2010, 18:03
|
|
|
|
|
Jan 18 2010, 22:25
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(KRS @ Jan 18 2010, 23:40)  Дело в том что для INT32 операция сдвига вправо расширяет знак! Согласно стандарту результат операции сдвига вправа отрицательного числа вообще отдан на откуп компилятору. Сам был немало удивлен. Я тоже подумал об этой причине, но в последний момент успел заметить U.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 18 2010, 23:00
|

Профессионал
    
Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555

|
действительно с XORом какой то глюк! При проверке на 0 Код volatile int beep; void test1(unsigned a) { if ((a ^ (a >> 16)) & 0xffff) beep = 1; }
void test2(unsigned a) { if ((a ^ (a >> 1)) & 0xffff) beep = 1; }
unsigned test3(unsigned a) { return ((a ^ (a >> 16)) & 0xffff);
}
void test4(unsigned a, unsigned b) { if ((a ^ (b >> 16)) & 0xffff) beep = 1; }
void test5(unsigned a, unsigned b) { if ((a ^ (b >> 1)) & 0xffff) beep = 1; }
void test6(unsigned a, unsigned b) { if (((a & 0xffff) ^ (b >> 16))) beep = 1; }
void test7(unsigned a) { if (((a & 0xffff) ^ (a >> 16))) beep = 1; }
void test8(unsigned a) { if (((a & 0xffff) ^ (a >> 1))) beep = 1; }
void test9(unsigned a, unsigned b) { if (((a & 0xffff) ^ (b >> 1))) beep = 1; } Все эти функции кроме 3, 8, 9 компилируются с ошибкой! Код 2 void test1(unsigned a) 3 { 4 if ((a ^ (a >> 16)) & 0xffff) \ test1: \ 00000000 010C LSRS R1,R0,#+16 \ 00000002 90EA010F TEQ R0,R1 \ 00000006 02D0 BEQ.N ??test1_0 5 beep = 1; \ 00000008 .... LDR.N R0,??DataTable7 ;; beep \ 0000000A 0121 MOVS R1,#+1 \ 0000000C 0160 STR R1,[R0, #+0] 6 } \ ??test1_0: \ 0000000E 7047 BX LR ;; return 7
\ In section .text, align 2, keep-with-next 8 void test2(unsigned a) 9 { 10 if ((a ^ (a >> 1)) & 0xffff) \ test2: \ 00000000 4108 LSRS R1,R0,#+1 \ 00000002 90EA010F TEQ R0,R1 \ 00000006 02D0 BEQ.N ??test2_0 11 beep = 1; \ 00000008 .... LDR.N R0,??DataTable7 ;; beep \ 0000000A 0121 MOVS R1,#+1 \ 0000000C 0160 STR R1,[R0, #+0] 12 } \ ??test2_0: \ 0000000E 7047 BX LR ;; return 13
\ In section .text, align 2, keep-with-next 14 unsigned test3(unsigned a) 15 { 16 return ((a ^ (a >> 16)) & 0xffff); \ test3: \ 00000000 80EA1040 EOR R0,R0,R0, LSR #+16 \ 00000004 80B2 UXTH R0,R0 \ 00000006 7047 BX LR ;; return 17 18 } 19
\ In section .text, align 2, keep-with-next 20 void test4(unsigned a, unsigned b) 21 { 22 if ((a ^ (b >> 16)) & 0xffff) \ test4: \ 00000000 090C LSRS R1,R1,#+16 \ 00000002 90EA010F TEQ R0,R1 \ 00000006 02D0 BEQ.N ??test4_0 23 beep = 1; \ 00000008 .... LDR.N R0,??DataTable7 ;; beep \ 0000000A 0121 MOVS R1,#+1 \ 0000000C 0160 STR R1,[R0, #+0] 24 } \ ??test4_0: \ 0000000E 7047 BX LR ;; return 25
\ In section .text, align 2, keep-with-next 26 void test5(unsigned a, unsigned b) 27 { 28 if ((a ^ (b >> 1)) & 0xffff) \ test5: \ 00000000 4908 LSRS R1,R1,#+1 \ 00000002 90EA010F TEQ R0,R1 \ 00000006 02D0 BEQ.N ??test5_0 29 beep = 1; \ 00000008 .... LDR.N R0,??DataTable7 ;; beep \ 0000000A 0121 MOVS R1,#+1 \ 0000000C 0160 STR R1,[R0, #+0] 30 } \ ??test5_0: \ 0000000E 7047 BX LR ;; return 31
\ In section .text, align 2, keep-with-next 32 void test6(unsigned a, unsigned b) 33 { 34 if (((a & 0xffff) ^ (b >> 16))) \ test6: \ 00000000 090C LSRS R1,R1,#+16 \ 00000002 90EA010F TEQ R0,R1 \ 00000006 02D0 BEQ.N ??test6_0 35 beep = 1; \ 00000008 .... LDR.N R0,??DataTable7 ;; beep \ 0000000A 0121 MOVS R1,#+1 \ 0000000C 0160 STR R1,[R0, #+0] 36 } \ ??test6_0: \ 0000000E 7047 BX LR ;; return 37
\ In section .text, align 2, keep-with-next 38 void test7(unsigned a) 39 { 40 if (((a & 0xffff) ^ (a >> 16))) \ test7: \ 00000000 010C LSRS R1,R0,#+16 \ 00000002 90EA010F TEQ R0,R1 \ 00000006 02D0 BEQ.N ??test7_0 41 beep = 1; \ 00000008 .... LDR.N R0,??DataTable7 ;; beep \ 0000000A 0121 MOVS R1,#+1 \ 0000000C 0160 STR R1,[R0, #+0] 42 } \ ??test7_0: \ 0000000E 7047 BX LR ;; return 43
\ In section .text, align 2, keep-with-next 44 void test8(unsigned a) 45 { 46 if (((a & 0xffff) ^ (a >> 1))) \ test8: \ 00000000 81B2 UXTH R1,R0 \ 00000002 91EA500F TEQ R1,R0, LSR #+1 \ 00000006 02D0 BEQ.N ??test8_0 47 beep = 1; \ 00000008 .... LDR.N R0,??DataTable7 ;; beep \ 0000000A 0121 MOVS R1,#+1 \ 0000000C 0160 STR R1,[R0, #+0] 48 } \ ??test8_0: \ 0000000E 7047 BX LR ;; return 49
\ In section .text, align 2, keep-with-next 50 void test9(unsigned a, unsigned b) 51 { 52 if (((a & 0xffff) ^ (b >> 1))) \ test9: \ 00000000 80B2 UXTH R0,R0 \ 00000002 90EA510F TEQ R0,R1, LSR #+1 \ 00000006 02D0 BEQ.N ??test9_0 53 beep = 1; \ 00000008 .... LDR.N R0,??DataTable7 ;; beep \ 0000000A 0121 MOVS R1,#+1 \ 0000000C 0160 STR R1,[R0, #+0] 54 } \ ??test9_0: \ 0000000E 7047 BX LR ;; return
|
|
|
|
|
Jan 19 2010, 07:14
|
Группа: Участник
Сообщений: 10
Регистрация: 21-12-06
Из: Питер
Пользователь №: 23 756

|
Цитата(KRS @ Jan 19 2010, 03:00)  действительно с XORом какой то глюк! При проверке на 0 ... Все эти функции кроме 3, 8, 9 компилируются с ошибкой! ... Фундаментальный подход. Внушает. Убедился - не в моих руках дело. Сношу 5.4 и жду 5.5. Спасибо всем, кто откликнулся. KRS - персональное "БОЛЬШОЕ СПАСИБО". Мне кажется, это серьезная проблема для IAR. Странно, если они о ней ещё не знают. После скачивания Evalution на мыло пришло какое-то сообщение от IAR, можно в ответ послать им письмо с примерами от KRS (если KRS не возражает). Удачи всем.
Сообщение отредактировал Ytrnj - Jan 19 2010, 07:15
|
|
|
|
|
Jan 19 2010, 09:33
|

Профессионал
    
Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555

|
Цитата(IgorKossak @ Jan 19 2010, 12:22)  Проверяли только XOR или другие операции тоже? Другие вроде ок! Да и с XOR ок, только проверка на 0 глючит! А такой код Код if ((a ^ (a >> 16)) & 0xffff) return (a ^ (a >> 16)) & 0xffff; вообще смешно компилируется! Проверка остается кривой, потом выражение почти заново считается для возврата. Код 1 unsigned test(unsigned a) { 2 if ((a ^ (a >> 16)) & 0xffff) \ test: \ 00000000 010C LSRS R1,R0,#+16 \ 00000002 90EA010F TEQ R0,R1 \ 00000006 02D0 BEQ.N ??test_0 3 return (a ^ (a >> 16)) & 0xffff; \ 00000008 4840 EORS R0,R1,R0 \ 0000000A 80B2 UXTH R0,R0 \ 0000000C 7047 BX LR 4 return 1; \ ??test_0: \ 0000000E 0120 MOVS R0,#+1 \ 00000010 7047 BX LR ;; return 5 }
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|