Liste des Instructions Sparc

2éme partie: instructions du FPU


L'unité virgule flottante du Sparc est, comme son camarade entier, RISC. Les opérations disponibles sont donc plutôt limitées : (En fait les références mémoires et les branchements sont plutoôt du ressort du CPU, le FPU se contentant de fournir les registres et les codes conditionnels... j'ai mis ça ici juste pour le classement)

Les types disponibles

Les quatre types suivants sont supportés : Les tailles de ces types :
integer 4 octets 1 registre
single 4 octets 1 registre
double 8 octets (64 bits) 2 registres
quad 16 octets (128 bits) 4 registres

Les registres

Le fpu posséde 32 registres %f0 à %f31 de 32 bits chacun. Contrairement aux registres entiers, ils sont communs à toutes les procédures et ne sont pas concernés par le mécanisme de fenêtre.

Il y a aussi le registre de statut %fsr (accessible comme les autres par st et ld).

Lorsqu'on fait une opération sur ces registres, et que plusieurs registres sont necessaires pour stocker un flottant (double ou quad), le registre à fournir comme opérande est le premier des 2 ou 4 qui contient le nombre (comme pour les ldd et std). De plus, ils sont contraints à l'alignement : le registre de la première moitié d'un double doit être de numéro pair.

Accès mémoire

On utilise simplement les instructions ld et st comme avec les registres entiers : ld [adresse],%fpi, st %fpi,[adresse]. Notez qu'il n'y a pas de ldub et autre sth ! En revanche on utilise beaucoup plus ldd et std, car les flottants prennent plus de place (un ldd permet de charger un double en une fois).

Conversions de types

Les instructions de conversion sont de la forme FxTOy freg1,freg2
où x et y sont les types de départ et d'arrivée.
instruction from.. to..
fitos integer single
fitod integer double
fitoq integer quad
fstoi single integer
fstod double
fstoq quad
fdtoi double integer
fdtos single
fdtoq quad
fqtoi quad integer
fqtos single
fqtod double

Transfert

fmovs freg1,freg2 copie freg1 dans freg2
Il n'y a bien sûr pas de fmovd,fmovq, puisque ce serait une copie simultanée de plusieurs registres ! On doit donc faire
fmovs freg1,freg2
fmovs freg1+1,freg2+1

Opérations

fnegs %freg1,%freg2 Le registre freg2 reçoit l'opposé du single stocké dans freg1.
single -> single
fabss %freg1,%freg2%f2=|%f1|
single -> single
sqrts %freg1,%freg2 %f2=racine carrée de %f1
single -> single
sqrtd %freg1,%freg2 %f2=racine carrée de %f1
double -> double
sqrtq %freg1,%freg2 %f2=racine carrée de %f1
quad -> quad
fadds %f1,%f2,%f3%f3=%f1+%f2
(single X single) -> single
faddd %f1,%f2,%f3%f3=%f1+%f2
(double X double) -> double
faddq %f1,%f2,%f3%f3=%f1+%f2
(quad X quad) -> quad
fsubs %f1,%f2,%f3%f3=%f1-%f2
(single X single) -> single
fsubd %f1,%f2,%f3%f3=%f1-%f2
(double X double) -> double
fsubq %f1,%f2,%f3%f3=%f1-%f2
(quad X quad) -> quad
fmuls %f1,%f2,%f3%f3=%f1*%f2
(single X single) -> single
fmuld %f1,%f2,%f3.sp4p%f3=%f1*%f2
(double X double) -> double
fmulq %f1,%f2,%f3.sp4p%f3=%f1*%f2
(quad X quad) -> quad
fdivs %f1,%f2,%f3%f3=%f1/%f2
(single X single) -> single
fdivd %f1,%f2,%f3%f3=%f1/%f2
(double X double) -> double
fdivq %f1,%f2,%f3%f3=%f1/%f2
(quad X quad) -> quad
fdmulq %f1,%f2,%f3%f3=%f1*%f2
(double X double) -> quad
fsmuld %f1,%f2,%f3%f3=%f1*%f2
(single X single) -> double
fcmps %f1,%f2compare deux single
(genere une exception si "unordered")
fcmpd %f1,%f2compare deux double
(genere une exception si "unordered")
fcmpq %f1,%f2compare deux quad
(genere une exception si "unordered")
fcmped %f1,%f2compare ?
fcmpeq %f1,%f2compare ?

Branchements conditionnels

Les branchements suivent la méme syntaxe que les branchements normaux: fbcc label, ou fbcc,a label. Ces instructions n'exploitent que le résultat d'un fcmp ou fcmpe.
fbn
fbu
fbg
fbug
fbl
fbul
fblg
fbne
fbe
fbue
fbge
fbuge
fble
fbule
fbo
fba