10. Инструкции с плавающей точкой

Эти инструкции поддерживают использование сопроцессора ARM с плавающей точкой (на платформах, таких как OpenMV Cam, которые им оснащены). FPU имеет 32 регистра, известных как s0-s31, каждый из которых может хранить число с плавающей точкой одинарной точности. Данные можно передавать между регистрами FPU и регистрами ядра ARM с помощью инструкции vmov.

Обратите внимание, что MicroPython не поддерживает передачу чисел с плавающей точкой в функции ассемблера, и вы также не можете поместить число с плавающей точкой в r0 и ожидать разумного результата. Есть два способа это обойти. Первый – использовать массивы, а второй – передавать и/или возвращать целые числа и преобразовывать в числа с плавающей точкой и обратно в коде.

10.1. Соглашения документа

Обозначения: Sd, Sm, Sn обозначают регистры FPU, Rd, Rm, Rn обозначают регистры ядра ARM. Последние могут быть любыми регистрами ядра ARM, хотя регистры R13-R15 вряд ли уместны в этом контексте.

10.2. Арифметика

  • vadd(Sd, Sn, Sm) Sd = Sn + Sm

  • vsub(Sd, Sn, Sm) Sd = Sn - Sm

  • vneg(Sd, Sm) Sd = -Sm

  • vmul(Sd, Sn, Sm) Sd = Sn * Sm

  • vdiv(Sd, Sn, Sm) Sd = Sn / Sm

  • vsqrt(Sd, Sm) Sd = sqrt(Sm)

Регистры могут совпадать: vmul(S0, S0, S0) выполнит S0 = S0*S0

10.3. Перемещение между регистрами ядра ARM и FPU

  • vmov(Sd, Rm) Sd = Rm

  • vmov(Rd, Sm) Rd = Sm

FPU имеет регистр, известный как FPSCR, аналогичный APSR ядра ARM, который хранит коды условий плюс другие данные. Следующие инструкции предоставляют доступ к нему.

  • vmrs(APSR_nzcv, FPSCR)

Перемещает флаги N, Z, C и V с плавающей точкой во флаги N, Z, C и V регистра APSR.

Это делается после такой инструкции, как сравнение FPU, чтобы коды условий можно было проверить ассемблерным кодом. Ниже приведена более общая форма инструкции.

  • vmrs(Rd, FPSCR) Rd = FPSCR

10.4. Перемещение между регистром FPU и памятью

  • vldr(Sd, [Rn, offset]) Sd = [Rn + offset]

  • vstr(Sd, [Rn, offset]) [Rn + offset] = Sd

Где [Rn + offset] обозначает адрес памяти, полученный сложением Rn со смещением. Оно задаётся в байтах. Поскольку каждое значение с плавающей точкой занимает 32-битное слово, при доступе к массивам чисел с плавающей точкой смещение всегда должно быть кратно четырём байтам.

10.5. Сравнение данных

  • vcmp(Sd, Sm)

Сравнивает значения в Sd и Sm и устанавливает флаги N, Z, C и V регистра FPU. За этим обычно следует vmrs(APSR_nzcv, FPSCR), чтобы результаты можно было проверить.

10.6. Преобразование между целым числом и числом с плавающей точкой

  • vcvt_f32_s32(Sd, Sm) Sd = float(Sm)

  • vcvt_s32_f32(Sd, Sm) Sd = int(Sm)