[an error occurred while processing this directive]
IAR-C for PIC16: Глава 2. Изучаем компилятор (повтор с пропавшей страницы)
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено Baser 12 ноября 2002 г. 13:06


В Главе 1 я описывал проблемы несовместимости с HT-PICC. Теперь посмотрим, что там
наворотил компилятор.

1. Сходу удивил листинг. Когда компилятор располагает код последовательно
(не меняет порядок следования) всё нормально: строка на Си - код на Асме. Но когда
компилятор решит, что лучше расположить код опосля другого, то все: сначало идет
чистый текст на Си (по 50-100 строчек в моем случае), а потом, совсем в другом
месте листинга сплошной код на асме. Как следствие, понять что чему соответствует
очень сложно. Причем вариации настроек оптимизации на вид листинга нисколько не
влияли. На что мне не нравиться HT-PICC-ый листинг который "глотает" половину
Сишного текста, но IAR-овцы смогли их переплюнуть.

2. Для затравки попробовал рекомендованную Puh-ом конструкцию для команды swapf x:
a = a << 4 | a >> 4; // которую HT-PICC понимал на ура. ИАР её понял "дословно",
итог - 9 команд. Но это отнесем на существование в HT-PICC "домашних заготовок",
что само по себе очень неплохо.

3. Битовые структуры нужно описывать очень аккуратно. Описание структуры
(как я сначала написал в первой главе) и if c битами типа:
struct {
unsigned Flag1 :1;
...
unsigned FlagN :1;
};
if (Flag1 | FlagN) {
...}
особенно, если в структуре больше 8-и флагов приводит к чудовищному коду:
регистр флагов многократно переписывается во временные регистры, сдвигается,
xor-ится и т.д. и т.п. вместо положенных 3-х,4-х команд.
Помогает следующее описание и ручное разделение структур по 8 бит:
struct {
unsigned char Flag1 :1;
...
unsigned char Flag8 :1;
};
Получается намного лучше, хотя тоже достаточно коряво:
MOVLW 0
BTFSC _A_Flag1,0
MOVLW 1
BTFSC _A_Flag1,7
MOVLW 1
XORLW 0
BTFSC STATUS,2
GOTO ...

4. На pointers тоже нужно обратить пристальное внимание. Их значительно больше,
чем в HT-PICC и они сильно отличаются. Краткое обсуждение по этому поводу уже
было (здесь).
Добавлю только, что основное отличие при перетаскивании Сишного текста с HT-PICC
на IAR заключается в значениях по умолчанию.
Для HT-PICC значение data pointer по умолчанию это однобайтный указатель на банк0,
а для IAR-а это трехбайтовый указатель на любые данные.
Т.е., даже если описывается временный указатель на временную переменную из банка0,
нужно описывать его как:
unsigned char __bank0 *ptr;
иначе он будет трехбайтовым!

5. Заметил сильное увлечение временными регистрами в операциях, где HT-PICC
обходится теми регистрами, с которыми в данный момент работает (т.е. нет оптимиза-
ции по тому, используется в дальнейшем значение данного регистра или нет).
(Functions can always use ?A0 to ?A3, ?B0 to ?B3, ?C0 to ?C3 and ?D0 to ?D3
without saving them).
Вообще оптимизация оставляет желать лучшего. Причем это даже не очень сильно
бросается в глаза. Но каждая 3...5-я строчка Сишного текста после компиляции
разворачивается в код, на 1,2,3 команды длиннее, чем у HT-PICC. Все это суммарно
и выливается в довольно большие цифры. Справедливости ради нужно сказать, что
были замеченны парочка конструкций, намного лучше компилируемые IAR-ом. Но на
общем фоне они погоды не делали. С уверенностью можно сказать, что среди
разработчиков компилятора от IAR нет людей, когда-либо писавших на ассемблере
PIC-ов.

6. Вектор прерываний тоже реализован не лучшим образом (он же единственный,
поэтому должен быть тщательно "вылизан"). При входе в прерывание автоматически
сохраняются ПОЧТИ ВСЕ предусмотренные временные регистры общего назначения
независимо от того применяются они в прерывании или нет (регистры ?A0 to ?A3,
?B0 to ?B3, ?C0 to ?C3 and ?E0 - 13 штук!) плюс FSR.
В то же время сохранение регистров Work, Status и PCLATH автоматом не производится
и отдается на откуп программисту (выдается Warning(Pic017)).

7. Автоматическое размещение глобальных переменных по банкам ОЗУ отсутствует,
всё в ручную, впрочем как и в HT-PICC. Есть полезная фича, которой нет в HT-PICC:
можно указать, в каком банке ОЗУ функция будет размещать временные переменные.
Зато существенно отличается размещение функций по страницам программной
памяти. Про повадки HT-PICC я уже упоминал (вот здесь).
Добавлю, что для HT-PICC объявление функции extern на местоположение не влияет.
HT-PICC по умолчанию размещает все сам, причем делает это достаточно хорошо.
Функции, размещенные в пределах одной объектной секции, вызываются без лишней
переустановки битов PCLATH. Разместить какую-либо функцию по указанному адресу
вроде бы можно, но эта возможность зарыта настолько глубоко, что мне разобраться
с ней не хватило терпения.
В IAR-С все обстоит гораздо хуже. Оптимизация автоматического размещения
отсутствует как класс, средств для ручного размещения и оптимизации тоже замечено
не было. Все функции нельзя хранить в одном файле, должен быть как минимум один
файл с Сишным текстом на одну страницу программной памяти PIC-а, т.к. компилятор
не умеет дробить файл на отдельные функции. Объявление функции extern на местопо-
ложение тоже не влияет. При вызове любой функции компилятор ВСЕГДА переустанавли-
вает биты PCLATH.
Как минус отмечу отсутствие в .map файле дерева вызовов подпрограмм.

8. После коррекции битовых структур (п.3) и переделки указателей на однобайтовые
размер кода сократился на 10% и окончательные результаты стали выглядеть так:
HT-PICC v7.87 PL2 - 6553 bytes flash, 281 bytes SRAM, 11 секунд сборки проекта;
IAR-C v2.21A - 8001 bytes flash, 273 bytes SRAM, 30 секунд сборки проекта;
Наверно, если ещё внимательно поразбираться, можно выиграть ещё пару процентов,
но даже 15% оверхеда показатель наглядный!

ВЫВОДЫ: При отличной IDE, большем наборе ключевых слов для управления размещением
переменных, большем выборе указателей, более удобному языку описания сегментов,
собственно компилятор и линкер IAR-а пока довольно значительно уступает HT-PICC
по качеству оптимизации. А для семейства PIC16 это является главным критерием.
Так что переходить на текущую версию EWPIC16 (v.2.21A/WIN) не советую, рановато!
Лучше пользоваться убожищем MPLAB вкупе с отличным компилятором, чем превосходной
IDE от IAR с посредственной генерацией кода!

p.s.Будет время, может быть ещё напишу про симулятор C-SPY...


Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru