bras assembly en ligne dans gcc

J'ai quelques problèmes avec certains assembly en ligne de code. Je sais ce qui doit être fait, mais je m'ennuie de le "comment" !

J'ai cette somme de contrôle de la fonction qui est "presque" de travail :

static unsigned long cksum_unroll( unsigned short **w, int *mlen)
{
  int len;
  unsigned short *w0;
  unsigned long sum=0;

  len = *mlen;
  w0 = *w;

  while( len >= 8) {
    asm volatile (
          "ldmia %[w0]!, {v1, v2}\n\t"
          "adds %[sum], %[sum], v1\n\t"
          "adcs %[sum], %[sum], v2\n\t"
          "adcs %[sum], %[sum], #0"
          : [sum] "+r" (sum) : [w0] "r" (w0)
          );
    len -= 8;
  }
  *mlen = len;
  *w = w0;
  return (sum);
}

Mon problème, je crois, est sur la ligne ": [somme] "+r" (somme) : [w0] "r" (w0)"
Sur la première ligne d'assemblage, w0 est traitée correctement par ldmia (lorsque la ligne est exécutée, les données sont dans r4,r5 et w0 est incrémenté). Mais la valeur incrémentée de w0 n'est pas enregistré quelque part et lorsque le code de la boucle, la valeur d'origine de w0 est à nouveau chargé (voir le code assembleur ci-dessous).
Ma conjecture est que je doit stocker la valeur de w0 sur la ligne ": [somme] "+r" (somme) : [w0] "r" (w0)" mais je ne sais pas comment...

Voici le démontage, le code de la ligne d'assemblage de la partie de la fonction :

Noter que :

len is stored at r11, #-16
w0 is stored at r11, #-20
sum is stored at r11, #-24

Compilé, le code suivant :

asm volatile (
          "ldmia %[w0]!, {v1, v2}\n\t"
          "adds %[sum], %[sum], v1\n\t"
          "adcs %[sum], %[sum], v2\n\t"
          "adcs %[sum], %[sum], #0"
          : [sum] "+r" (sum) : [w0] "r" (w0)
);
len -= 8;

Générer :

00031910:   ldr r3, [r11, #-20]
00031914:   ldr r2, [r11, #-24]
00031918:   mov r4, r2
0003191c:   ldm r3!, {r4, r5}
00031920:   adds r4, r4, r4
00031924:   adcs r4, r4, r5
00031928:   adcs r4, r4, #0
0003192c:   str r4, [r11, #-24]
00031930:   ldr r3, [r11, #-16]
00031934:   sub r3, r3, #8
00031938:   str r3, [r11, #-16]

Comme vous pouvez le voir, je voudrais ajouter quelque chose comme "str r3, [r11, #-20]" entre les lignes 31928 et 3192c parce que quand la boucle du programme à la ligne 31910, r3 est chargé avec la valeur initiale de la résistance r3...

Je pense que c'est une question facile pour la ligne d'assemblage d'experts de l'débordement de pile de la communauté!

En passant, je suis en train de travailler sur un processeur ARM7TDMI (mais cela peut ne pas être pertinente pour cette question...)

Merci d'avance!

EDIT:

De vérifier mon idée, j'ai testé le suivant :

asm volatile ( 
"ldmia %[w0]!, {v1, v2}\n\t" 
"adds %[sum], %[sum], v1\n\t" 
"adcs %[sum], %[sum], v2\n\t" 
"adcs %[sum], %[sum], #0\n\t" 
"str %[w0], [r11, #-20]" 
: [sum] "+r" (sum) : [w0] "r" (w0) 
); 

Et cela fonctionne. C'est peut-être la solution, mais que dois-je utiliser pour remplacer "r11, n ° 20," qui va probablement changer si je modifie la fonction?

De vérifier mon idée, j'ai testé le suivant : asm volatile ( "ldmia %[w0]!, {v1, v2}\n\t" "adds %[sum], %[sum], v1\n\t" "adcs %[sum], %[sum], v2\n\t" "adcs %[sum], %[sum], #0\n\t" "str %[w0], [r11, #-20]" : [sum] "+r" (sum) : [w0] "r" (w0) ); Et cela fonctionne. C'est peut-être la solution, mais que dois-je utiliser pour remplacer "r11, n ° 20," qui va probablement changer si je modifie la fonction?
GCC inline assemblée prend mon mal à la tête (et j'ai déjà on a commencé à cause de certains tapis collant passe à proximité, dans un remodelage), donc je ne peux pas vous donner une aide... Mais je peux point vous l'un des meilleurs docs que j'ai lu sur la façon de traiter avec GCC de l'asm inline, dans le cas où vous n'avez pas rencontré encore: ethernut.de/en/documents/arm-inline-asm.html en bonus, la doc de cibler spécifiquement les BRAS.
Merci pour le lien. Ce web pages était déjà ouvert quand j'ai écrit cette question!

OriginalL'auteur Martin Allard | 2012-02-15