2016-05-04 3 views
2

J'ai écrit une fonction d'assemblage AT & pour calculer une intégrale. Je dois le passer comme une valeur de retour comme il est appelé par le code écrit en C. J'ai réussi à le renvoyer comme une seule précision float et une double précision double. Mais je sais que je peux le calculer en double précision étendue de 80 bits et j'aimerais le passer à C.Comment puis-je déplacer un nombre à virgule flottante de 80 bits avec double précision de la mémoire vers XMM0 dans l'assemblage AT & T

Supposons que la valeur que je veux passer soit pointée dans un registre FPU pointé par TOP. Voici comment j'appelle des fonctions.

Pour float:

//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 

Pour double:

//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 

Ma question est maintenant: comment puis-je remplir le code suivant, de sorte que C peut lire long double du registre %XMM0.

Pour long double:

//C 
long double integ_lo=integ_asm_fpu_lo(); 

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

Que dois-je faire après? Comment est-ce que je déplacerais 80 bits de max à %XMM0?

+0

J'aimerais comparer la précision et le temps d'exécution de mon code pour le mode précision simple, double et double extension. Bien que je puisse exécuter du code dans les horloges double-extended et count, je voudrais aussi imprimer (via 'printf ("% Ld, integral);' et valider le résultat – bowl

+3

Quelle convention d'appel s'applique ici? Pour x64 linux, vous les renvoyez dans ST (0) – harold

+0

Thx, harold Répondez-moi, donc je peux marquer votre réponse – bowl

Répondre

4

Votre prémisse est fausse:

comment puis-je remplir le code suivant, de sorte que C peut lire long double de la % XMM0 registre.

Le abi sysv ne retourne pas dans long doublexmm0 registre, mais st0. La partie pertinente de la documentation:

La mantisse de 64 bits d'arguments de type long double appartient à la classe X87, l'exposant de 16 bits plus 6 octets de remplissage appartient à la classe X87UP.

Si la classe est X87UP, la valeur est retournée avec la valeur X87 précédente dans% st0.

Apparemment, vous avez déjà la valeur st0 de sorte que vous ne devez pas faire quoi que ce soit juste le laisser là, ce qui signifie supprimer le fstpt dans votre exemple.