Перейти к содержанию
    

Недокументированные возможности IAR

Просматривал хидер pgmspace.h и обратил внимание на модификаторы __x_z и __z, в мануале на компилятор про их назаначение ничего не нашел (или плохо искал?...), в апликашках они тоже вроде бы не встречаются. Решил попробовать использовать их наугад, написал простенький код на С++ (описал две одинаковых функции одна с __x_z, другая без, исходный код и результат компиляции см. в присоединенных файлах), скомпилировал, оказалось что код функции с модификатором компактнее (за счет ИМХО более рационального использования регистров-указателей) и выполняется быстрей (на 30% в данном примере). Вопросы: кто, что о них (модификаторах) знает (особенности их использования)? Какие мысли есть о том, почему ИАР ничего не пишет о них ( ведь ИМХО вещ вроде бы полезная)?

modifikaori.rar

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Просматривал хидер pgmspace.h и обратил внимание на модификаторы __x_z и __z, в мануале на компилятор про их назаначение ничего не нашел (или плохо искал?...), в апликашках они тоже вроде бы не встречаются. Решил попробовать использовать их наугад, написал простенький код на С++ (описал две одинаковых функции одна с __x_z, другая без, исходный код и результат компиляции см. в присоединенных файлах), скомпилировал, оказалось что код функции с модификатором компактнее (за счет ИМХО более рационального использования регистров-указателей) и выполняется быстрей (на 30% в данном примере). Вопросы: кто, что о них (модификаторах) знает (особенности их использования)? Какие мысли есть о том, почему ИАР ничего не пишет о них ( ведь ИМХО вещ вроде бы полезная)?

Если в объявлении функции присутствует модификатор __z, или, __x или комбинированный, то передача параметров в такую функцию будет производиться не через пару r16:17, через пару, образующую соответсвующий указатель (z или x). Особенно это рулит для функций-членов классов, в которых первым параметром всегда скрыто передается указатель this. Но есть случаи, когда так делать не выгодно, несколько лет назад спрашивал у саппорта, но уже не помню, чем они обосновали отказ от повсеместного использования такой схемы передачи параметров. Что-то типа того, что в большинстве случаев при передаче первым параметром не указателя потребуется дополнительное копирование для освобождения Z-указателя. Конечно, можно было бы сделать более гибкую схему, чтобы компилятор соображал, если указатель, то передавать его через Z, если не указатель, то через 16:17. Но до этого они не дошли, делать не стали. Считают, что и так неплохо.

 

Т.ч. никто не мешает использовать обсуждаемые квалификаторы. Есть только два минуса - 1) переносимость; 2) нет гарантий, что в очередной версии эти вещи не уберут или не изменят их функциональность. Хотя вероятность этого, имхо, стремится к нулю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для улучшения скорости и компактности некоторых функций, особенно static, применяю эти квалификаторы.

О ни действительно в руководствах ничего нет.

Некоторые замеченные особенности:

- квалификаторы действуют только на указатели, в остальных случаях игнорируются;

- не существует квалификатора __z_x ;) ;

- ...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для улучшения скорости и компактности некоторых функций, особенно static, применяю эти квалификаторы.

О ни действительно в руководствах ничего нет.

Некоторые замеченные особенности:

- квалификаторы действуют только на указатели, в остальных случаях игнорируются;

- не существует квалификатора __z_x ;) ;

- ...

 

Cуществует и __z_x и __x_z - соответственно, как передавать первый и второй указатель.

 

По поводу только указателей - если очень надо, преобразуй например int в void * и передай, а потом наоборот.

 

На форуме "Точка опоры" я писал про недокумментированные фичи иара, всякие "__raw", "__no_return" и прочее. Поищи там, давненько дело было.

 

Также есть еще SBRA и CBRA - это коммады какие-то AVR, иар их может использовать. Что за хрень - не знаю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...По поводу только указателей - если очень надо, преобразуй например int в void * и передай, а потом наоборот.

В том то и дело, что кроме головной боли такие преобразования не принесут, а выигрыша никакого.

На форуме "Точка опоры" я писал про недокумментированные фичи иара, всякие "__raw", "__no_return" и прочее. Поищи там, давненько дело было.

Хорошие фичи, применяю.

__raw - в прерываниях, обслуживаемых ОСРВ (там свои функции сохранения/восстановления контекста);

__no_return - в бутлоадере (немного сокращает размер).

Также есть еще SBRA и CBRA - это коммады какие-то AVR, иар их может использовать. Что за хрень - не знаю.

Ни в стандартном, ни в расширенном наборе (по крайней мере для ATmega) таких инструкций нет. Что имели в виду ИАРовцы - не понятно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хорошие фичи, применяю.

__raw - в прерываниях, обслуживаемых ОСРВ (там свои функции сохранения/восстановления контекста);

А что в EWAVR тоже __raw включили? В 4.10А я специально смотрел, не было там (не нашел ни в доке, ни в перечне ключей компилятора).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А что в EWAVR тоже __raw включили? В 4.10А я специально смотрел, не было там (не нашел ни в доке, ни в перечне ключей компилятора).

В 4.11А точно есть, и (как выяснилось :( ) даже документирован, правда в самом мануале на компилятор про этот квалификатор ничего нет, а вот в файлах ...\avr\doc\iccavr.htm и ...\avr\doc\manuals.htm он описан... Смутно вспоминаю, что ранее кто-то здесь задавал вопрос: как отключить сохранение регистров в функции обслуживания прерывания если в ней вызывается функция... теперь появилась возможность сделать это корректно...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как то пытался переписывать порты под вытесняющие ОСи на чистом С в иар для мсп430.

__no_return не оказывает никакого эффекта. Т.е. компилятор не ругается, но и рет не подавляет.

Плюс __interrupt разрешают применять только для обработчиков прерываний, так что красота не получается пока :glare:

 

__no_return - в бутлоадере (немного сокращает размер).

 

Подавляет ret, тем самым позволяет на С создавать конструкции типа "несколько точек входа на одну точку выхода", я правильно понимаю?

И почему в бутлоадере? Это как-то связанно с АВР или больше нигде не возникает необходимость в подобном механизме?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

.....

Подавляет ret, тем самым позволяет на С создавать конструкции типа "несколько точек входа на одну точку выхода", я правильно понимаю?

И почему в бутлоадере? Это как-то связанно с АВР или больше нигде не возникает необходимость в подобном механизме?

 

Подавляет не ret. Подавляет сохранение регистров. Но как-то отличается от __root. Особо не разбирался.

 

По поводу гемороя с передачей значений как указатели. Используя такой метод (с __x_z) можно за раз передать в функцию не 8 (R16-R23), а 12 (R16,R23,X,Z) байт БЕЗ ИСПОЛЬЗОВАНИЯ СТЕКА. В некоторых случаях очень удобно и позволяет повысить производительность. Единственное, нельзя сделать функцию с _z в любой комбинации, если используется вызов данной функции по указателю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Подавляет не ret. Подавляет сохранение регистров. Но как-то отличается от __root. Особо не разбирался.

Непонятно (по поводу __noreturn), если я правильно перевел, этот квалификатор указывает компилятору, что программа после выполнения функции не возвращается к точке ее вызова (если я не прав поправьте), в этом случае ИМХО функция уже вроде как не функция (заметил, что после добавления __noreturn переход на функцию осуществляется при помощи RJMP) и как следствие регистры уже не сохраняются (но это вторично)... И какое отношение __root имеет к сохранению регистров?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Подавляет ret, тем самым позволяет на С создавать конструкции типа "несколько точек входа на одну точку выхода", я правильно понимаю?

Не правильно. Это лишь означает, что функция не будет иметь возврата, а значит, что не нужно сохранять контекст в начале и восстанавливать его в конце (т. к. конца функции нет). Это обычно функция main().

И почему в бутлоадере? Это как-то связанно с АВР или больше нигде не возникает необходимость в подобном механизме?

Бутлоадер желательно впихнуть в как можно меньшую область из 8, 4, 2, 1 кБайт.

Поэтому экономия на сохранении\восстановлении контекста может в этом помочь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а значит, что не нужно сохранять контекст в начале и восстанавливать его в конце (т. к. конца функции нет). Это обычно функция main().

Заманчиво было :-(, кроме main() это еще все 'задачи'. Попробовал __noreturn и __root на

IAR ARM ANSI C/C++ Compiler V4.30A-P050906/W32

Слова худого не сказал в ответ, но и не сделал абсолютно ничего - сохранение контекста

осталось :-(. Похоже было, но похерено.

Изменено пользователем zltigo

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для задач я обычно применяю __task.

Помогает однозначно.

Что касается __root, то он скорее предназначен для переменных, оптимизация которых нежелательна.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Подавляет не ret. Подавляет сохранение регистров. Но как-то отличается от __root. Особо не разбирался.

Непонятно (по поводу __noreturn), если я правильно перевел, этот квалификатор указывает компилятору, что программа после выполнения функции не возвращается к точке ее вызова (если я не прав поправьте), в этом случае ИМХО функция уже вроде как не функция (заметил, что после добавления __noreturn переход на функцию осуществляется при помощи RJMP) и как следствие регистры уже не сохраняются (но это вторично)... И какое отношение __root имеет к сохранению регистров?

 

Очень странно. Какой у вас компилер и версия?

У меня мсп430 3.30

 

итак:

__raw и __task подавляют сохранение/восстановление регистров в для "прерывательных" и "обычных" функций

__interrupt -заменяет рет на ирет

__root обязывает компилятор/линкер включать функцию в объектный/бинарный файл, даже если на нее нет ни одной ссылки

__noreturn keyword can be used on a function to inform the compiler that the function will not return. Т.е. не будет возврата из функции - будет выполняться следующий по порядку оператор. О подавлении/сохранении регистров ни слова. Точно так же очень сомнительно выглядит вызов функции по jmp. По крайней мере мсп430 3.30 вызывает __noreturn функцию через call. Чесно предупреждает, что больше не сможет вернуться в точку вызова :cranky: . Но т.к. не подавляет ret в вызываемой функции, благополучно возвращается в точку вызова :tongue:

 

На мсп430 3.30 __noreturn не делает ничего. Т.е. ret не подавляется, а регистры сохраняются. Все остальные extended keywords работают корректно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Очень странно. Какой у вас компилер и версия?

У меня мсп430 3.30

 

итак:

__raw и __task подавляют сохранение/восстановление регистров в для "прерывательных" и "обычных" функций

__interrupt -заменяет рет на ирет

__root обязывает компилятор/линкер включать функцию в объектный/бинарный файл, даже если на нее нет ни одной ссылки

__noreturn keyword can be used on a function to inform the compiler that the function will not return. Т.е. не

Эксперимент:

IAR ARM ANSI C/C++ Compiler V4.30A-P050906/W32

__raw и __task - знать не знает, ведать не ведает таких :-(. Ругается долго и мучительно (вообще с локализацией ошибки IAR далеко не в первых рядах).

__interrupt - тоже не знает, но не беда, ибо __irq имеет место быть...

__root - не ругается, ну может и работает, как описано

__noreturn - не делает ничего.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...