2010-01-18 10 views
1

J'essaie actuellement d'écrire un programme pour l'unité VFP de l'iPhone en utilisant le code d'assemblage ARM. Le VFP peut faire des calculs en virgule flottante, mais AFAIK pas d'arithmétique entière. Cependant, il peut convertir un flottant en un entier signé (4 octets). En outre, selon ce QuickReference: http://www.voti.nl/hvu/arm/ARMquickref.pdf il semble qu'il ne supporte pas les opérations de décalageAssemblage: convertir la valeur du point flottant en octet signé

ce que je voudrais faire est de convertir 4 flotteurs dont je suis sûr que chacun est plus grand que -127 et inférieur à 127 en 4 octets signés. Si j'avais des opérations de décalage disponibles, je pourrais convertir le flottant en entier signé, puis décaler la valeur de 12 octets vers la gauche (8 et 4 octets pour les deux prochaines valeurs respectivement) et le bit OU tous les quatre ensemble .

Toutefois, étant donné que le décalage n'est pas disponible, j'ai besoin de trouver un autre moyen de le faire. Aussi - je ne peux pas utiliser arithmétique entière (donc je ne peux pas multiplier l'entier déjà converti par 2^n afin de décaler mais je dois travailler sur le flotteur à la place).

Quelqu'un sait comment je pourrais y parvenir?

btw pour ceux qui connaissent l'architecture ARM - je ne veux pas passer aux instructions Thumb, car cela se fait dans une boucle opérant sur de nombreux éléments et je ne veux pas basculer entre les instructions de pouce et bras à l'intérieur boucle (puisque c'est cher)

Merci!

modifier:

autre question: comment puis-je normaliser un vecteur avec trois éléments?

Répondre

2

Vous voulez l'instruction VFP ftosis, qui convertit une valeur FP simple précision en un entier de 4 octets. Si vous disposez de quatre flotteurs dans s0-s3, puis après avoir fait:

ftosis s0, s0 
ftosis s1, s1 
ftosis s2, s2 
ftosis s3, s3 

vous avez quatre 4 entiers d'octets dans s0-s3, qui peuvent être stockées dans la mémoire avec jointive un fstm.

Sur un processeur ARM prenant en charge NEON, vous pouvez utiliser vcvt.s32.f32 q0, q0 pour effectuer quatre conversions avec une instruction.


Modifier pour répondre à votre question de suivi, voici une fonction simple exemple qui prend en entrée un pointeur sur quatre flotteurs en mémoire et renvoie les valeurs converties emballés en un seul int32_t:

_floatToPackedInt: 
    fldmias r0, {s4-s7} 
    ftosizs s0, s4 
    ftosizs s1, s5 
    ftosizs s2, s6 
    ftosizs s3, s7 
    fmrrs r0, r1, {s0,s1} 
    fmrrs r2, r3, {s2,s3} 
    uxtb  r0, r0 
    uxtb  r1, r1 
    uxtb  r2, r2 
    orr  r0, r0, r1, lsl #8 
    orr  r0, r0, r2, lsl #16 
    orr  r0, r0, r3, lsl #24 
    bx  lr 

Je n'ai pas vraiment fait d'effort pour régler ceci, car vous ne voudriez pas faire des conversions de cette façon si elles étaient critiques pour la performance; vous préférez soit opérer sur de grandes baies de valeurs, et canaliser ce code de sorte que plusieurs conversions soient en cours de vol simultanément, soit l'entrelacer avec d'autres opérations qui font également un travail utile.

Vous pouvez également insérer ssat s avant le uxtb s pour que les valeurs hors limites soient saturées au lieu de l'emballage.

De plus, sachez que ce code aura des performances médiocres sur les cœurs ARMv7; vous voudrez certainement utiliser les opérations vectorielles NEON sur cette plate-forme.

+0

oui je sais cela - mais le problème est la conversion de int signé à octet signé! à la fin, je ne veux pas avoir 4 entiers 4byte, mais 4 octets signés 1 octet dans un seul registre – genesys

+0

Désolé; il n'était pas du tout clair que c'est ce que vous vouliez de votre question ("alors décalez la valeur de 12 octets vers la gauche", etc). Vous pouvez le faire directement sur NEON, mais sur les cœurs ARM qui ont uniquement VFP, vous devrez replacer les valeurs converties dans les registres généraux et les réduire en octets. –

+0

en êtes-vous sûr? il ya bitwise OU - donc je pense peut-être que je pourrais construire quelque chose en utilisant l'arithmétique à virgule flottante. Si j'avais mon float dans l'intervalle de -127 <= f <= 127, ne pourrais-je pas le multiplier par # 4096 (= 2^12) et le convertir en int en utilisant ftosis? cela n'entraînerait-il pas la même chose que de déplacer l'int converti de 12 bits vers la gauche? - Sinon, peut-être pourriez-vous me répondre ma deuxième question? (voir la modification dans la question ci-dessus) – genesys

Questions connexes