У меня вопрос: имеет ли смысл инструкция FADDP ST(0), ST(1)
на ассемблере?
Насколько я знаю, в этой инструкции мы складываем ST(0) и ST(1) и записываем результат в ST(0), после чего ST(0) удаляется.
С ST(0) в качестве пункта назначения? Во-первых, его невозможно закодировать: felixcloutier.com/x86/fadd:faddp:fiadd
faddp st(0), st(1)
даже не кодируется в машинный код.
Вы правы, это было бы бесполезно (кроме возбуждения исключений FP), поэтому архитекторы 8087 не включили код операции faddp st(0), st(i)
.
Есть опкоды для 3 форм fadd с регистровым источником:
D8 C0+i
FADD ST(0), ST(i)
DC C0+i
FADD ST(i), ST(0)
DE C0+i
FADDP ST(i), ST(0)
faddp st(0), st(i)
Таким образом, faddp st(0), st(0)
кодируется, но бесполезен, используя код операции faddp st(i), st(0)
, где назначением может быть любой регистр, включая бесполезный случай st(0)
, но источник фиксируется как st(0)
.
Самый дешевый способ вытолкнуть стек на 1 без каких-либо дополнительных действий — это fstp st(0)
. http://www.ray.masmcode.com/tutorial/fpuchap4.htm#fstp
(А стоимость инструкций см. https://agner.org/optimize/ . https://uops.info/ не тестировал устаревшие инструкции x87, хотя у него есть некоторые данные IACA для некоторых из их.)
Если вы действительно хотите добавить число и отказаться от результата, например. чтобы вызвать исключения FP перед возвратом из функции математической библиотеки, которая использовала целочисленные битовые манипуляции, вы можете эмулировать этот faddp с помощью
; Emulate faddp st(0), st(1), e.g. for raising FP exceptions
fadd st(0), st(1)
fstp st(0)
Это не только не имеет смысла, его даже не существует.