Достучаться до регистров FPU в Cortex M4F

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Вымогатель припоя
Сообщения: 671
Зарегистрирован: Вт июн 29, 2010 12:31:49

Сообщение TripleKill »

В Keil можно вытаскивать и заносить данные в регистры контроллера, предварительно огласив последние:

Код: Выделить всё

register long R0 __asm("r0");
register long R1 __asm("r1");
Однако с FPU-регистрами (S0 и далее) такая тема не прокатывает. Может, кто-нибудь знает, как их правильно огласить?
Или компилятор вообще не знает про них?

Спасибо.
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Сообщение menzoda »

А может тогда уж на ассемблере эту часть кода сделать?
Реклама
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

А компилятор знает, что ему надо код для Cortex M4F делать? Может компилер отдельно настраивается на Cortex M4, а поддержка FPU включается отдельным крыжиком где-нибудь в настройках.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Вымогатель припоя
Сообщения: 671
Зарегистрирован: Вт июн 29, 2010 12:31:49

Сообщение TripleKill »

Знает. При любых сишных операциях с float в дебагере видно, что задействуются регистры FPU. Ну и в настройках компилера есть галочка "Use FPU".
Заделать на асме пробовал, только компилер ругается на слово return в асм-коде. Асм-вставки внутри сишных функций не поддерживаются, т.к. генерится thumb-код. Иначе говоря, асм-функции могут быть оформлены лишь как самостоятельные. Подсунутая после гуглежа #pragma arm для попытки задействовать вставки компилеру тоже не нравится.
Галочку "generate thumb code" в настройках убирал, результата нет.

P.S. Вылезла такая ошибка, что архитектура не поддерживает arm-инструкции, только thumb.
Реклама
Эиком - электронные компоненты и радиодетали
Вымогатель припоя
Аватара пользователя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Сообщение menzoda »

TripleKill писал(а):компилер ругается на слово return в асм-коде
Стоп. У тебя не получилось сделать асм-функцию вызываемую из си-кода? Или такое решение тебе в принципе не подходит и тебе нужны всякие инлайн асмы, прагмы и т.п.?

Если первое, то я не так давно делал для Cortex M4 асм-функцию для вызова из си, вычисляющую синус (делал как-раз в Keil). Могу дать исходники.
Реклама
Вымогатель припоя
Сообщения: 671
Зарегистрирован: Вт июн 29, 2010 12:31:49

Сообщение TripleKill »

Сделать вызываемую асм-функцию получилось. Не получилось сделать асм-функцию, возвращающую значение.
Может, она по умолчанию какой-то регистр выплёвывает, если её прописать не void, а, например, int?
Т.е., возвращаясь к теме, как заставить асм-функцию с возвращаемым типом float выплюнуть содержимое S0/S1?
На исходники бы взглянул)
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Сообщение menzoda »

У меня даже Keil'овский проект остался. По идее должен работать. http://ge.tt/9lInvQO/v/0?c

Плюс, можешь почитать брошюрку Procedure Call Standard for the ARM® Architecture. Там подробно описано через какие регистры передаются параметры, через какие возвращаются, какие можно изменять, какие нужно сохранять и т.д. http://infocenter.arm.com/help/topic/co ... _aapcs.pdf

Еще можешь написать какую-нибудь простую функцию на Си, которая, например, получает float, прибавляет единицу, и возвращает float. А потом посмотреть в какой набор команд она скомпилировалась, и от него уже плясать.
Вымогатель припоя
Сообщения: 671
Зарегистрирован: Вт июн 29, 2010 12:31:49

Сообщение TripleKill »

Спасибо. Кажется, дело сдвинулось с мёртвой точки. Возвращается то, что к концу процедуры находится в R0/S0.
Интересно, а можно ли заставить функцию вернуть множественные значения, передавая ей выходные переменные как параметры?
Например, как-нибудь так:

Код: Выделить всё

MyProc(&In1, &In2, &Out1, &Out2);
In - входные переменные, Out - выходные (инициализированы в главном коде, но модифицируются процедурой).
Вымогатель припоя
Аватара пользователя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Сообщение menzoda »

Да, конечно, можно. Сделай как я говорил - напиши простую Си функцию с требуемым прототипом. Пускай она выполняет какие-нибудь элементарные действия с переданными ей параметрам, например, просто копирует входные в выходные. Скомпилируй и посмотри ассемблер - увидишь, как нужно обращаться с параметрами, передаваемыми по указателю. Сам то я такие ассемблерные функции не использовал, поэтому, как ассемблер работает с адресами, я сказать не могу, нужно смотреть.

После того, как разберешся, можешь поиграться с настройками оптимизации, ибо без оной ассемблер генерирует хоть и понятный, прямолинейный, но не самый оптимальный код.

Если нет необходимости сохранять входные параметры после вызова функции, можно передавать и получать данные через одни и те же переменные. Код ассемблера должен выглядеть проще, все же меньше параметров.

Код: Выделить всё

MyProc(&InOut1, &InOut2);
Вымогатель припоя
Сообщения: 671
Зарегистрирован: Вт июн 29, 2010 12:31:49

Сообщение TripleKill »

Ясно, спасибо, попробую.
Кстати, пока гуглил, наткнулся на неплохой имхо туториал по основам С++: http://www.cplusplus.com/doc/tutorial/
Хоть и на инглише, зато всё подробно, с картинками)
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Так это плюсы, зачем они тут?
Вымогатель припоя
Сообщения: 671
Зарегистрирован: Вт июн 29, 2010 12:31:49

Сообщение TripleKill »

Нечто общее между С и С++ всё равно есть)
Ответить

Вернуться в «ARM»