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 + Smvsub(Sd, Sn, Sm)
Sd = Sn - Smvneg(Sd, Sm)
Sd = -Smvmul(Sd, Sn, Sm)
Sd = Sn * Smvdiv(Sd, Sn, Sm)
Sd = Sn / Smvsqrt(Sd, Sm)
Sd = sqrt(Sm)
Регистры могут совпадать: vmul(S0, S0, S0) выполнит S0 = S0*S0
10.3. Перемещение между регистрами ядра ARM и FPU¶
vmov(Sd, Rm)
Sd = Rmvmov(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)