Forum général.général un peu d'assembleur SPARC

Posté par  (site web personnel) .
Étiquettes : aucune
0
6
mai
2005
Hello,

sous x86 j'ai ce code :
inline int ftoi(double x) {
// double to int (rounded towards nearest integer)
int i;
__asm {
fld x
fitsp i
}
return i;
}

qui marche tres bien puisque le mode d'arrondi par defaut est celui qui va bien (contrairement a celui du C qui est la troncature). voila, je voudrais le porter sous SPARC, que dois-je faire ?
j'ai des doutes avec l'arrondis par defaut et la suite d'instructions :

ld x, %f31
fdtoi %f31, %f30
stdf %f30, i

est-ce que cela marcherait ?
  • # meuh

    Posté par  (site web personnel) . Évalué à 2.

    le plus simple si tu n'as un besoin critique de performance c'est quand même de le faire en C... genre "x > 0 ? (int)(x + 0.5) : (int)(x - 0.5)"
    • [^] # Re: meuh

      Posté par  (site web personnel) . Évalué à 2.

      justement si c'est en assembleur, c'est pour être rapide.
      (d'ailleurs ton code est faux :
      i = (int)( x - 0.5) < (int)x ? (int)x :(int) x+1
      ce qui revient à dire : si x moins sa troncature est > 0.5 rajoute 1)
      • [^] # Re: meuh

        Posté par  . Évalué à 0.

        as-tu essayé de compiler ce bout de code C
        sous sparc, et de regarder ce que le compilateur (gcc?)
        donne ?
      • [^] # Re: meuh

        Posté par  . Évalué à 2.

        Ton code était déjà faux à la base. Le fait que tu fasses de l'assembleur inline ne change pas le rounding mode courant. Tu dis "contrairement a celui du C qui est la troncature", tu obtiendras aussi la troncature via ta fonction ftoi(). AFAIK, fist[p] utilise le rounding mode courant. Donc, si c'est la troncature, tu obtiens la troncature. IIRC sur SPARC, fdtoi utilises le mode courant aussi, ce qui est logique.

        Autre chose, la syntaxe que tu donnes ne correspond pas à celle supportée par GCC sur x86. Maintenant, tu demandes pour du SPARC. On va supposer que tu utilises GCC car avec le compilo de Sun, ça se passe différemment.

        Par ailleurs, le code que tu proposes, outre le fait qu'il soit faux était sous-optimal vu que tu semblais vouloir passer les paramètres et retour par mémoire.

        Pour faire ce que tu veux, je te suggère.

        static inline long ftoi_nearest(double x) {
        int i, old_mode = fegetround();
        fesetround(FE_TONEAREST);
        i = lrint(x);
        fesetround(old_mode);
        return i;
        }

        après, tu optimises comme tu veux, si c'est possible.

        Par exemple, si tu as un noyau de code où tu veux absolument ce mode là, tu n'as cas faire les changements de mode autour et utiliser lrint, ou bien les instructions assembleur dédiées vu que maintenant tu seras certain de ton mode d'arrondi.
        • [^] # Re: meuh

          Posté par  (site web personnel) . Évalué à 2.

          le premier code fonctionne correctement (enfin sous vc++ sous windows), je ne l'ai pas testé encore sous linux. en tous cas merci, c'est très clair comme explication.
          • [^] # Re: meuh

            Posté par  . Évalué à 2.

            Plus simple : utilises les instrutions lrint() ou lrintf(), qui font partie du standard C99.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.