J'ai deux valeurs de 16 bits signées dans un mot de 32 bits, et j'ai besoin de les déplacer à droite (diviser) sur une valeur constante (cela peut être de 1 à 6) et saturer en octet (0..0xFF).Rapide Saturer et décaler deux demi-mots dans ARM asm
Par exemple,
- 0x FFE1 00AA avec changement = 5 doit devenir 0x 0000 0005;
- 0x 2345 1234 doit devenir 0x 00FF 0091
Je suis en train de saturer les valeurs en même temps, quelque chose comme ce pseudo-code:
AND RT, R0, 0x80008000; - mask high bits to get negatives
ORR RT, RT, LSR #1
ORR RT, RT, LSR #2
ORR RT, RT, LSR #4
ORR RT, RT, LSR #8; - now its expanded signs in each halfword
MVN RT, RT
AND R0, RT; now negative values are zero
; here something to saturate high overflow and shift after
mais le code que je reçois est très moche et lent. :) Le meilleur (le plus rapide) que j'ai maintenant la saturation séparée chaque moitié, comme ceci:
MOV RT, R0, LSL #16
MOVS RT, RT, ASR #16+5
MOVMI RT, #0
CMP RT, RT, #256
MOVCS RT, #255
MOVS R0, R0, ASR #16+5
MOVMI R0, #0
CMP R0, R0, #256
MOVCS R0, #255
ORR R0, RT, R0, LSL #16
Mais il est 10 cycles. :(Peut-il être plus rapide
ps: plus tard je l'ai trouvé USAT16 instructions pour, mais il est seulement pour ARMv6 Et je besoin du code pour travailler sur ARMv5TE et ARMv4
Edit..: maintenant je récrire mon premier code.
ANDS RT, 0x10000, R0 << 1; // 0x10000 is in register. Sign (HI) moves to C flag, Sign (LO) is masked
SUBNE RT, RT, 1; // Mask LO with 0xFFFF if it's negative
SUBCS RT, RT, 0x10000; // Mask HI with 0xFFFF if it's negative
BIC R0, R0, RT; // Negatives are 0 now. The mask can be used as XOR too
TST R0, 0xE0000000; // check HI overflow
ORRNE R0, R0, 0x1FE00000 // set HI to 0xFF (shifted) if so
TST R0, 0x0000E000 // check LO overflow
ORRNE R0, R0, 0x00001FE0 // set LO to 0xFF if so
AND R0, 0x00FF00FF, R0 >> 5; // 0x00FF00FF is in register
mais il est pas beau
Avez-vous il essayé d'écrire en C, puis voir ce que le compilateur produit? –
Steve, je ne sais pas comment l'écrire en C sans traitement séparé des moitiés. Mais mon cerveau crée quelques idées :) L'un d'entre eux est "masque XOR". Il doit contenir 0 (dans chaque moitié individuellement), si le nombre est OK. Si le nombre est négatif, il se contiendra. Un débordement positif, il contiendra le numéro^0xFFFF. Donc le résultat sera source^mask. Mais n'a pas d'idées, comment le faire simultanément – zxcat