t
ограничение
Согласно документации GCC https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html#Machine-Constraints
t
Вершина стека с плавающей запятой 80387(% st (0)).
Итак, мы можем сделать:
#include <assert.h>
int main(void) {
double io = 4.0;
__asm__ (
"fsqrt"
: "+t" (io)
:
:
);
assert(io == 2.0);
return 0;
}
GitHub upstream .
Переподготовка: +
означает, что io
будет использоваться как для ввода, так и для вывода.
Протестировано в Ubuntu 19.04.
Сборка GNU GAS ARM поддерживает это
Например, в ARMv8:
main.c
#include <assert.h>
int main(void) {
float my_float = 1.5;
__asm__ (
"fmov s0, 1.0;"
"fadd %s[my_float], %s[my_float], s0;"
: [my_float] "+w" (my_float)
:
: "s0"
);
assert(my_float == 2.5);
}
GitHub upstream .
Скомпилируйте и запустите:
aarch64-linux-gnu-gcc -o main.out -static -std=gnu99 main.c
qemu-aarch64 ./main.out
Модификатор %s
упоминается по адресу: ARMv8, встроенная сборка выходных данных с плавающей запятой
Он также работает в ARMv7.
Однако по некоторым причинам он работает только для плавающихточечные инструкции, такие как fmov
, например, следующая попытка ARMv7 не удается собрать:
mov r0, 1.5
с ошибкой:
Error: garbage following instruction -- `mov r0,1.5'
предположительно, потому что она использует инструкцию mov
, которая действуетна регистры общего назначения вместо плавающих рoint of.
Однако, возможно, это не имеет большого значения, так как по большей части вы просто хотите выполнить свои операции с плавающей запятой в ваших регистрах с плавающей запятой, а затем выполните fcmp
, а затем vmrs
какin:
vmov s0, 1.5
vmov s1, 2.5
fadds s2, s0, s1
vmov s3, 4.0
/* Compare two floating point registers. Stores results in fpscr:
* (floating point status and control register).
*/
vcmp.f32 s2, s3
/* Move the nzcv bits from fpscr to apsr */
vmrs apsr_nzcv, fpscr
/* This branch uses the Z bit of apsr, which was set accordingly. */
beq theyre_equal
GitHub upstream .
Меня не перестает удивлять, как GNU GAS имеет слегка различающийся синтаксис для каждой арки!
Iоднако не удалось найти синтаксис с шестнадцатеричным литералом: Как использовать шестнадцатеричные литералы с плавающей точкой в GNU GAS?
Протестировано в Ubuntu 18.04.