Собираю проект в Keil ARM 5.16a для STM32F407 с максимальной оптимизацией по скорости Otime, O3.
По мере написания проекта столкнулся со странным поведением, при максимальной оптимизации O3 программа иногда идёт иногда нет, зависит от порядка расположения переменных, функций. Если поменять их порядок местами, то иногда удаётся получить работающий код при O3.
Опытным путём через #pragma optimize был выявлен проблемный кусок: им оказалась точка входа в main(). Если всё заоптимизировать с O3, но точку входа в main сделать O1 (выше может не пойти), то будет работать:
Код
#pragma push
#pragma Otime
#pragma O3
//Тут переменные, функции , константы, макросы............
//Точка входа в main с уровнем оптимизации не более O1, если поставить выше, то в некоторых случаях может не заработать. Глюк Keil ???
#pragma push
#pragma Otime
#pragma O1
int main(void)
{
#pragma push
#pragma Otime
#pragma O3
//тут программа.........
#pragma pop
}
#pragma pop
#pragma pop
#pragma Otime
#pragma O3
//Тут переменные, функции , константы, макросы............
//Точка входа в main с уровнем оптимизации не более O1, если поставить выше, то в некоторых случаях может не заработать. Глюк Keil ???
#pragma push
#pragma Otime
#pragma O1
int main(void)
{
#pragma push
#pragma Otime
#pragma O3
//тут программа.........
#pragma pop
}
#pragma pop
#pragma pop
С чем может быть связано такое поведение?
2)
Использую CMSIS-овскую функцию __REV16(), в ассемблерном листинге она вставляется в виде перехода на функцию, а не как одна ассемблерная инструкция.
Причем остальные типа: __REV() , __CLZ() встраиваются в виде инструкций.
Заменил __REV16() на :
Код
inline u32 rev16(u32 x)
{
__asm("REV16 x,x");
return x;
}
{
__asm("REV16 x,x");
return x;
}
и в листинге идёт вставка ассемблерной инструкции без перехода как на функцию.
Получается, что используя CMSIS , доверяй, но проверяй?