|
Недокументированные возможности IAR, extended keywords __x_z, __z? |
|
|
|
Dec 16 2005, 10:12
|

Знающий
   
Группа: Свой
Сообщений: 697
Регистрация: 26-07-05
Из: Могилев
Пользователь №: 7 095

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

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(Old1 @ Dec 16 2005, 16:12)  Просматривал хидер pgmspace.h и обратил внимание на модификаторы __x_z и __z, в мануале на компилятор про их назаначение ничего не нашел (или плохо искал?...), в апликашках они тоже вроде бы не встречаются. Решил попробовать использовать их наугад, написал простенький код на С++ (описал две одинаковых функции одна с __x_z, другая без, исходный код и результат компиляции см. в присоединенных файлах), скомпилировал, оказалось что код функции с модификатором компактнее (за счет ИМХО более рационального использования регистров-указателей) и выполняется быстрей (на 30% в данном примере). Вопросы: кто, что о них (модификаторах) знает (особенности их использования)? Какие мысли есть о том, почему ИАР ничего не пишет о них ( ведь ИМХО вещ вроде бы полезная)? Если в объявлении функции присутствует модификатор __z, или, __x или комбинированный, то передача параметров в такую функцию будет производиться не через пару r16:17, через пару, образующую соответсвующий указатель (z или x). Особенно это рулит для функций-членов классов, в которых первым параметром всегда скрыто передается указатель this. Но есть случаи, когда так делать не выгодно, несколько лет назад спрашивал у саппорта, но уже не помню, чем они обосновали отказ от повсеместного использования такой схемы передачи параметров. Что-то типа того, что в большинстве случаев при передаче первым параметром не указателя потребуется дополнительное копирование для освобождения Z-указателя. Конечно, можно было бы сделать более гибкую схему, чтобы компилятор соображал, если указатель, то передавать его через Z, если не указатель, то через 16:17. Но до этого они не дошли, делать не стали. Считают, что и так неплохо. Т.ч. никто не мешает использовать обсуждаемые квалификаторы. Есть только два минуса - 1) переносимость; 2) нет гарантий, что в очередной версии эти вещи не уберут или не изменят их функциональность. Хотя вероятность этого, имхо, стремится к нулю.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Dec 16 2005, 11:02
|

Шаман
     
Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221

|
Для улучшения скорости и компактности некоторых функций, особенно static, применяю эти квалификаторы. О ни действительно в руководствах ничего нет. Некоторые замеченные особенности: - квалификаторы действуют только на указатели, в остальных случаях игнорируются; - не существует квалификатора __z_x  ; - ...
|
|
|
|
|
Dec 16 2005, 14:08
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата(IgorKossak @ Dec 16 2005, 13:02)  Для улучшения скорости и компактности некоторых функций, особенно static, применяю эти квалификаторы. О ни действительно в руководствах ничего нет. Некоторые замеченные особенности: - квалификаторы действуют только на указатели, в остальных случаях игнорируются; - не существует квалификатора __z_x  ; - ... Cуществует и __z_x и __x_z - соответственно, как передавать первый и второй указатель. По поводу только указателей - если очень надо, преобразуй например int в void * и передай, а потом наоборот. На форуме "Точка опоры" я писал про недокумментированные фичи иара, всякие "__raw", "__no_return" и прочее. Поищи там, давненько дело было. Также есть еще SBRA и CBRA - это коммады какие-то AVR, иар их может использовать. Что за хрень - не знаю.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Dec 16 2005, 15:43
|

Шаман
     
Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221

|
Цитата(Rst7 @ Dec 16 2005, 16:08)  ...По поводу только указателей - если очень надо, преобразуй например int в void * и передай, а потом наоборот. В том то и дело, что кроме головной боли такие преобразования не принесут, а выигрыша никакого. Цитата(Rst7 @ Dec 16 2005, 16:08)  На форуме "Точка опоры" я писал про недокумментированные фичи иара, всякие "__raw", "__no_return" и прочее. Поищи там, давненько дело было. Хорошие фичи, применяю. __raw - в прерываниях, обслуживаемых ОСРВ (там свои функции сохранения/восстановления контекста); __no_return - в бутлоадере (немного сокращает размер). Цитата(Rst7 @ Dec 16 2005, 16:08)  Также есть еще SBRA и CBRA - это коммады какие-то AVR, иар их может использовать. Что за хрень - не знаю. Ни в стандартном, ни в расширенном наборе (по крайней мере для ATmega) таких инструкций нет. Что имели в виду ИАРовцы - не понятно.
|
|
|
|
|
Dec 17 2005, 03:58
|
Местный
  
Группа: Свой
Сообщений: 437
Регистрация: 27-08-04
Пользователь №: 551

|
Как то пытался переписывать порты под вытесняющие ОСи на чистом С в иар для мсп430. __no_return не оказывает никакого эффекта. Т.е. компилятор не ругается, но и рет не подавляет. Плюс __interrupt разрешают применять только для обработчиков прерываний, так что красота не получается пока Цитата(IgorKossak @ Dec 16 2005, 19:43)  __no_return - в бутлоадере (немного сокращает размер). Подавляет ret, тем самым позволяет на С создавать конструкции типа "несколько точек входа на одну точку выхода", я правильно понимаю? И почему в бутлоадере? Это как-то связанно с АВР или больше нигде не возникает необходимость в подобном механизме?
|
|
|
|
|
Dec 17 2005, 07:40
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата(ig_z @ Dec 17 2005, 05:58)  ..... Подавляет ret, тем самым позволяет на С создавать конструкции типа "несколько точек входа на одну точку выхода", я правильно понимаю? И почему в бутлоадере? Это как-то связанно с АВР или больше нигде не возникает необходимость в подобном механизме? Подавляет не ret. Подавляет сохранение регистров. Но как-то отличается от __root. Особо не разбирался. По поводу гемороя с передачей значений как указатели. Используя такой метод (с __x_z) можно за раз передать в функцию не 8 (R16-R23), а 12 (R16,R23,X,Z) байт БЕЗ ИСПОЛЬЗОВАНИЯ СТЕКА. В некоторых случаях очень удобно и позволяет повысить производительность. Единственное, нельзя сделать функцию с _z в любой комбинации, если используется вызов данной функции по указателю.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Dec 19 2005, 08:08
|

Шаман
     
Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221

|
Цитата(ig_z @ Dec 17 2005, 05:58)  Подавляет ret, тем самым позволяет на С создавать конструкции типа "несколько точек входа на одну точку выхода", я правильно понимаю? Не правильно. Это лишь означает, что функция не будет иметь возврата, а значит, что не нужно сохранять контекст в начале и восстанавливать его в конце (т. к. конца функции нет). Это обычно функция main(). Цитата(ig_z @ Dec 17 2005, 05:58)  И почему в бутлоадере? Это как-то связанно с АВР или больше нигде не возникает необходимость в подобном механизме? Бутлоадер желательно впихнуть в как можно меньшую область из 8, 4, 2, 1 кБайт. Поэтому экономия на сохранении\восстановлении контекста может в этом помочь.
|
|
|
|
|
Dec 19 2005, 11:57
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(IgorKossak @ Dec 19 2005, 10:08)  а значит, что не нужно сохранять контекст в начале и восстанавливать его в конце (т. к. конца функции нет). Это обычно функция main(). Заманчиво было :-(, кроме main() это еще все 'задачи'. Попробовал __noreturn и __root на IAR ARM ANSI C/C++ Compiler V4.30A-P050906/W32 Слова худого не сказал в ответ, но и не сделал абсолютно ничего - сохранение контекста осталось :-(. Похоже было, но похерено.
Сообщение отредактировал zltigo - Dec 19 2005, 12:02
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Dec 19 2005, 15:36
|
Местный
  
Группа: Свой
Сообщений: 437
Регистрация: 27-08-04
Пользователь №: 551

|
Цитата(Old1 @ Dec 19 2005, 11:34)  Цитата(Rst7 @ Dec 17 2005, 11:40)  Подавляет не 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. Чесно предупреждает, что больше не сможет вернуться в точку вызова  . Но т.к. не подавляет ret в вызываемой функции, благополучно возвращается в точку вызова На мсп430 3.30 __noreturn не делает ничего. Т.е. ret не подавляется, а регистры сохраняются. Все остальные extended keywords работают корректно.
|
|
|
|
|
Dec 19 2005, 16:20
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(ig_z @ Dec 19 2005, 17:36)  Очень странно. Какой у вас компилер и версия? У меня мсп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 - не делает ничего.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|