Сергей Борщ 136 20 апреля, 2009 Опубликовано 20 апреля, 2009 · Жалоба Пишет "c:\mspgcc\msp430\include\msp430\iostructures.h|136|syntax error before "asm"|"Подозреваю, что надо включить с99 с гнутыми расширениями: -std=gnu99 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 27 20 апреля, 2009 Опубликовано 20 апреля, 2009 · Жалоба Итак, свершилось чудо! Было: switch_even_in_range(TBIV, &&def, &&l2, &&l4, &&l6, &&l8, &&l10, &&l12 ) { l2: pxTimerB1ccr1expired(); break; l4: pxTimerB1ccr2expired(); break; l6: (void)pxMBPortCBTimerExpired(); //break; l8: //pxTimerB1ccr4expired(); l10: //pxTimerB1ccr5expired(); l12: //pxTimerB1ccr6expired(); def: } Стало: 00002b36 <Timerb_ccr1>: 2b36: 0f 12 push r15; 2b38: 0e 12 push r14; 2b3a: 0d 12 push r13; 2b3c: 0c 12 push r12; 2b3e: 1f 42 1e 01 mov &0x011e,r15;0x011e 2b42: 3f 50 04 02 add #516, r15;#0x0204 2b46: 20 4f br @r15; 2b48: 92 12 42 04 call &0x0442; 2b4c: 06 3c jmp $+14 ;abs 0x2b5a 2b4e: 05 3c jmp $+12 ;abs 0x2b5a 2b50: 92 12 20 04 call &0x0420; 2b54: 02 3c jmp $+6 ;abs 0x2b5a 2b56: 92 12 22 04 call &0x0422; 2b5a: 3c 41 pop r12; 2b5c: 3d 41 pop r13; 2b5e: 3e 41 pop r14; 2b60: 3f 41 pop r15; 2b62: 00 13 reti свитч выродился в 2 команды (а нельзя ли в одну?) Непонятно, почему в середине 2 джампа подряд Подозреваю, что надо включить с99 с гнутыми расширениями: -std=gnu99 Спасибо, так прокатило. Счас ещё попробую вариант klen'а с таблицей указателей на функции. 00002b44 <Timerb_ccr1>: 2b44: 0f 12 push r15 ; 2b46: 0e 12 push r14 ; 2b48: 0d 12 push r13 ; 2b4a: 0c 12 push r12 ; 2b4c: 1f 42 1e 01 mov &0x011e,r15;0x011e 2b50: 0f 5f rla r15 ; 2b52: 0f 5f rla r15 ; 2b54: 9f 12 04 02 call 516(r15) ; 2b58: 3c 41 pop r12 ; 2b5a: 3d 41 pop r13 ; 2b5c: 3e 41 pop r14 ; 2b5e: 3f 41 pop r15 ; 2b60: 00 13 reti Вот это я понимаю, оптимизация! Спасибо всем за участие, почерпнул для себя много нового Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 27 20 апреля, 2009 Опубликовано 20 апреля, 2009 · Жалоба Прочитал - таки в книжке про опции компилятора, многое встало на свои места. Поколдовал немного с -fdata-sections и -ffunctions-sections и на -O3 получил код, по размеру не уступающий ИАРовскому. Так что GCC - rules! Где бы вот ещё Гриффитса в бумаге достать, а то с экрана читать неудобно Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 27 22 апреля, 2009 Опубликовано 22 апреля, 2009 · Жалоба Мда... Вчера полдня боролся непонятно с чем, пока не поменял свой супероптимизированный свич на стандартный... И ведь вроде всё правильно делает, но программу уносит в неведомые дали, всё виснет на ходу... Будем искать... Кстати, большим открытием для меня было, что static const sw[] формируется не в флеше, как было бы логично, а в ОЗУ. Пришлось его насильно запихнуть в флешь ( __attribute__(( section(".text") )) ) Ещё один фокус: static inline void PulseRecharge() не инлайнится внутрь обработчика прерывания, пока его принудительно туда не запихнёшь static inline void PulseRecharge()__attribute__((always_inline)); Это если они в одном модуле, а если в разных, то не лезет ни в какую! ####### Глянул diff-ом, разницы никакой не заметил, за исключением того что все адреса немного сползли из-за изменения размеров функции и добавления таблицы переходов... В общем, полный абзац. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 27 22 апреля, 2009 Опубликовано 22 апреля, 2009 · Жалоба нашёл у Гриффитса такой абзац: Похоже, действительно всё перекашивается... Пробовал -lno-gcse, не помогло... Эх, хорошая была идея... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 136 22 апреля, 2009 Опубликовано 22 апреля, 2009 · Жалоба Ещё один фокус: static inline void PulseRecharge() не инлайнится внутрь обработчика прерывания, пока его принудительно туда не запихнёшь static inline void PulseRecharge()__attribute__((always_inline)); Это если они в одном модуле, а если в разных, то не лезет ни в какую! Логично. Компилятор ведь не видит тела функции и не знает, какой же код вставлять в точку вызова. Поэтому инлайн-функции можно размещать в заголовочных файлах. По поводу атрибута - не могу сказать, почему компилятор без него решил не встраивать - у него свои критерии. Эта функция используется только в одном месте? Можно поиграться с -finline-functions-called-once и --param max-inline-insns-single. А что мешает сделать #define inline inline __attribute__((always_inline))? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alx2 0 22 апреля, 2009 Опубликовано 22 апреля, 2009 · Жалоба Кстати, большим открытием для меня было, что static const sw[] формируется не в флеше, как было бы логично, а в ОЗУ. Пришлось его насильно запихнуть в флешь ( __attribute__(( section(".text") )) ) Подозреваю, что у msp не фон-неймановская архитектура, и для доступа к ОЗУ и ПЗУ должен использоваться разный код. А gcc не поддерживает "универсальных" указателей (типа трехбайтных указателей в IAR'овском компиляторе для MCS51). Поэтмоу все данные размещаются в ОЗУ. При явном размещении данных в .text необходимо так же явно указывать компилятору, что читать объект требуется особым образом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 27 22 апреля, 2009 Опубликовано 22 апреля, 2009 · Жалоба Подозреваю, что у msp не фон-неймановская архитектура, и для доступа к ОЗУ и ПЗУ должен использоваться разный код. Да нет, как раз-таки с этим всё нормально. Для чтения совершенно безразлично, флешь это, ОЗУ или регистры периферии. Всё расположено линейно в едином пространстве адресов. Вот AVR - там да, без пузыря во флешь не залезешь... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alx2 0 23 апреля, 2009 Опубликовано 23 апреля, 2009 · Жалоба Да нет, как раз-таки с этим всё нормально. Для чтения совершенно безразлично, флешь это, ОЗУ или регистры периферии. Всё расположено линейно в едином пространстве адресов. Тогда странно. Для ARM gcc размещает константные объекты, как и положено, в .rodata. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Fvwm 0 30 сентября, 2015 Опубликовано 30 сентября, 2015 · Жалоба для gcc-4.9.x (последний msp430-gcc на ti.com v4.9.3): int asm_goto_example(int x) { // switch (__even_in_range(x, 10)) asm goto ("add.w %0, PC\n\t" "jmp %l[case_0]\n\t" "jmp %l[case_2]\n\t" "jmp %l[case_4]\n\t" "jmp %l[case_6]\n\t" "jmp %l[case_8]\n\t" : : "r"(x) : :case_0,case_2,case_4,case_6,case_8); // case 10: x ^= __LINE__; goto case_break; case_0: // case 0: x ^= __LINE__; goto case_break; case_2: // case 0: x ^= __LINE__; goto case_break; case_4: // case 0: x ^= __LINE__; goto case_break; case_6: // case 0: x ^= __LINE__; goto case_break; case_8: // case 0: x ^= __LINE__; case_break: // switch end return ~x; } asm получается такой же как и у техасского cl430: add.w R12, PC jmp .L38 jmp .L39 jmp .L40 jmp .L41 jmp .L42 XOR.W #146, R12 .LVL52: BR #.L43 .L38: XOR.W #150, R12 .LVL53: BR #.L43 .L39: XOR.W #154, R12 .LVL54: BR #.L43 .L40: XOR.W #158, R12 .LVL55: BR #.L43 .L41: XOR.W #162, R12 .LVL56: BR #.L43 .L42: XOR.W #166, R12 .LVL57: .L43: INV.W R12 .LVL58: RET Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться