Est-il possible de réécrire ou d'améliorer cette fonction pour ne pas avoir besoin de volatile ou d'un fragment de mémoire générique dans son assemblage en ligne?Réécrire l'assemblage en ligne GCC pour qu'il ne nécessite pas de volatile ou de fragmentation de mémoire
// do stuff with the input Foo structure and write the result to the
// output Bar structure.
static inline void MemFrob(const struct Foo* input, struct Bar* output) {
register const Foo* r0 asm("r0") = input;
register Bar* r1 asm("r1") = output;
__asm__ __volatile__(
"svC#0x0f0000 \n\t"
: "+r" (r0), "+r" (r1)
:
: "r2", "r3", "cc", "memory"
);
}
Pour cette situation particulière, la plate-forme cible est un système ARM7 et le code est compilé avec GCC 5.3.0. L'appel système en cours a la même convention d'appel qu'un appel de fonction C. Après quelques essais et erreurs, je suis arrivé à ce qui précède "qui fonctionne" mais je ne suis pas encore convaincu qu'il est correct et fonctionnera toujours, sous réserve des caprices et des fantaisies du compilateur d'optimisation. Je souhaite pouvoir supprimer le clobber "memory" et dire à GCC quelle mémoire sera modifiée, mais la documentation GCC Extended Asm explique comment affecter des valeurs à des registres spécifiques, puis à des contraintes de mémoire, mais pas si les deux peuvent être combinés. À partir de maintenant, en supprimant le clobber "mémoire" de l'exemple ci-dessus, GCC ne peut pas utiliser la sortie dans le code précédent.
Je voudrais aussi pouvoir supprimer le volatile dans les cas où la sortie n'est pas utilisée. Mais à partir de maintenant, en supprimant volatile de l'exemple ci-dessus, GCC n'émettra pas du tout l'assembly. Ajouter un assemblage en ligne supplémentaire pour déplacer manuellement les paramètres d'appel système dans r0/r1 ou les désincruster en déplaçant le code vers une unité de compilation externe sont des solutions de contournement inutiles que je préfère éviter.
1) Oui, vous pouvez avoir 1 contrainte soit un registre et une autre soit une mémoire, et oui, deux contraintes peuvent se chevaucher. 2) Sans le volatile, gcc voit l'asm comme le moyen de calculer les nouvelles valeurs de 'r0' et' r1'. Mais comme les optimiseurs peuvent voir que les variables 'r0' et' r1' ne sont plus utilisées après l'asm avant qu'elles ne soient hors de portée, l'asm est rejeté. –