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
, которая действует на регистры общего назначения, а не на регистры с плавающей запятой.
Однако, возможно, это не имеет большого значения, поскольку по большей части вы просто хотите выполнять операции с плавающей запятой в своих регистрах с плавающей запятой, а затем выполнять fcmp
, за которым следует vmrs
, как в:
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 имеет слегка отличающийся синтаксис для каждой арки!
Однако я не смог найти шестнадцатеричный синтаксис с плавающей запятой: использовать шестнадцатеричные литералы с плавающей запятой в GNU GAS?
Протестировано на Ubuntu 18.04.
person
Ciro Santilli
schedule
20.10.2018
150.0
вst(0)
для вас и скажите, что вы оставите результат вst(0)
: см. stackoverflow.com/questions/37509596/. Оставьтеfld
/fst
компилятору, поэтому ваш ассемблер включает только"fsqrt"
+ некоторые ограничения операнда. - person Peter Cordes   schedule 26.10.2017double y = 150.0; __asm__ ( "fsqrt" : "+t"(y) );
- person Michael Petch   schedule 26.10.2017