Как я могу переместить 80-битное число с плавающей запятой с двойной точностью из памяти в XMM0 в сборке AT&T

Я написал ассемблерную функцию AT&T для вычисления интеграла. Мне нужно передать его как возвращаемое значение, поскольку оно вызывается кодом, написанным на C. Мне удалось вернуть его как одинарную точность float и двойную точность double. Но я знаю, что могу вычислить его с 80-битной двойной расширенной точностью, и я бы хотел передать его в C.

Предположим, что значение, которое я хочу передать, указано в регистре FPU, на который указывает TOP. Вот как я вызываю функции.

Для поплавка:

//C
double  integ_fo=integ_asm_fpu_fl();

#asm
...  
fstps   max        # Fpu STore and Pop Short <- short for 32-bit
movss   max, %xmm0 # MOVe Scalar Single precision   

Для двойного:

//C
double  integ_do=integ_asm_fpu_do();

#asm
...  
fstpl   max        # Fpu STore and Pop Long <- long for 64-bit
movsd   max, %xmm0 # MOVe Scalar Dingle precision 

Теперь мой вопрос: как мне завершить следующий код, чтобы C мог читать long double из регистра %XMM0.

Для длинного двойника:

//C
long double  integ_lo=integ_asm_fpu_lo();

#asm
...  
fstpt   max        # FPU Store and Pop exTended <- extended for 80-bit

Что мне делать после этого? Как мне переместить 80 бит из max в %XMM0?


person bowl    schedule 04.05.2016    source источник
comment
Я хотел бы сравнить точность и время выполнения моего кода для режима одинарной, двойной и двойной расширенной точности. Хотя я могу запускать код в двойном расширении и считать часы, я также хотел бы распечатать (через «printf (%Ld,integral);» и проверить результат.   -  person bowl    schedule 04.05.2016
comment
Какое соглашение о вызовах применяется здесь? Правила для длинных двойных различаются. Для x64 linux вы возвращаете их в ST(0)   -  person harold    schedule 04.05.2016
comment
Спасибо, Гарольд. Ответьте мне, чтобы я мог отметить ваш ответ.   -  person bowl    schedule 04.05.2016
comment
Вы не можете переместить 80-битное число с плавающей запятой в XMM0. Регистры XMM поддерживают только 32-битные и 64-битные числа с плавающей запятой. Как сказал Харлод, вам нужно следовать соглашению о вызовах для вашей операционной системы, которая должна обеспечивать какой-то другой механизм.   -  person Ross Ridge    schedule 04.05.2016
comment
Спасибо. Пожалуйста, ответь на вопрос, @harold, чтобы я мог отметить твой ответ.   -  person bowl    schedule 04.05.2016
comment
У меня действительно нет ничего полезного для правильного ответа, кроме того, вы действительно используете x64 linux? (это была всего лишь моя догадка)   -  person harold    schedule 04.05.2016
comment
Да, @harold, я использую x64 Linux. Извините, не уточнил.   -  person bowl    schedule 04.05.2016


Ответы (1)


Ваша предпосылка неверна:

как я могу выполнить следующий код, чтобы C мог читать long double из регистра% XMM0.

sysv abi возвращает не long double в регистре xmm0, а st0. Соответствующая часть документации:

64-битная мантисса аргументов типа long double принадлежит классу X87, 16-битная экспонента плюс 6 байтов заполнения принадлежит классу X87UP.

Если класс X87UP, значение возвращается вместе с предыдущим значением X87 в %st0.

По-видимому, у вас уже есть значение в st0, поэтому вам не нужно ничего делать, просто оставьте его там, что означает удаление fstpt в вашем примере.

person Jester    schedule 04.05.2016