9
votes

Obtenir un compilateur pour générer une instruction ADC

Y a-t-il un moyen d'obtenir SLIG, GCC ou VS pour générer des instructions ADC (ajoutez-vous avec transport) uniquement à l'aide de Standard-C ++ (98/11/14)? (Edit: Je veux dire en mode x64, désolé si ce n'était pas clair.)


12 commentaires

Ce sont des compilateurs C


@Taylor: "GCC" et "Visual Studio" sont les noms des collections de compilateur contenant des compilateurs C ++ entre autres. Clang est un compilateur C ++.


@Benvoigt Oh, alors je suppose que cela a du sens.


FWIW, en x64, j'ai jamais pu être capable d'obtenir n'importe quel compilateur de générer adc sans assemblage en ligne.


Y a-t-il une raison particulière que vous voulez faire cela?


Vous pouvez jouer avec l'explorateur GCC, peut-être que cela vous mènera quelque part.


L'ensemble du point de C ou C ++ est d'isoler le programmeur de l'assemblage spécifique à la plate-forme. Les normes C ou C ++ ne mentionnent jamais ADC (qui est un détail de mise en œuvre) afin que la réponse soit nul . Rien ne garantit qu'un processeur particulier fournit une instruction ADC ...


Un no non. mais , il peut y avoir des extensions de compilateur susceptibles de générer un, par exemple, __ Basculin_Addc fonctions.


@syam je n'ai jamais voulu une garantie. Je suis juste à la recherche d'exemples de code qui incluent suffisamment de conseils pour l'optimiseur pour générer une instruction ADC.


@Olicharlesworth Oui, j'aimerais mettre en œuvre des arithmétiques de précision arbitraires efficaces dans Iso-C ++, mais je ne pense pas que ce soit possible pour le moment.


Le problème est également lié à Stackoverflow.com/Questtions/56101507/...


Le problème est également lié à Stackoverflow.com/Questtions/56101507/...


3 Réponses :


1
votes

Si vous compilez une addition signée 64 bits pour x86 ( intz_t in c ++ 11), le code compilé contiendra une instruction adc .

EDIT: CODE Exemple: xxx

sur x86, l'addition est implémentée à l'aide d'une instruction Ajouter suivie d'un instruction adc . Sur x64, seule une seule instruction Ajouter est utilisée.


2 commentaires

Pouvez-vous donner une fonction d'exemple minimale? Je ne l'ai jamais vu dans aucun de mes binaires, seulement lea (Q) et similaire.


S'il vous plaît voir mon édition, j'aurais dû inclure cela avant. L'arrière-plan ici est de voir s'il est possible de construire une entière arbitraire efficace arithmétique en standard-C ++. :)



2
votes

Il y a un type __ int128_t code> disponible sur GCC pour AMD64 et d'autres cibles 64 bits, qui utilisera une paire de ajouter code> / ADC code> Ajout simple. (Voir le lien Godbolt ci-dessous).

En outre, ce code ISO C pur peut compiler à un ADC: P>

    mov     rax, rdi  # a, a
    add     rax, rsi  # a, b
    adc     rax, 0    # a,
    ret


2 commentaires

J'allais ajouter que je pense que -Funsafe-math-math-optimisations pourrait tuer ce total si bloc, mais cela ne semble pas. Je pense que C pourrait permettre une telle optimisation, cependant, alors regarde là-bas.


Un emballage non signé est bien défini en C / C ++, en tant qu'iertiper binaire. Il est garanti de fonctionner correctement. -Funsafe-Math-Optimisations n'affecte que le comportement des points flottants. Peut-être que vous envisagez d'avoir un comportement indéfini en integer -fwrapv le rend bien défini (comme le complément de 2 2), mais est pas activé par défaut.



3
votes

Si votre code fait une comparaison et ajoute le résultat de la comparaison à quelque chose, un ADC est généralement émis par GCC 5 (Incidemment, GCC 4.8 n'émet pas d'un ADC ici). Par exemple, xxx

assemble à xxx

Cependant, il est un peu délicat pour obtenir GCC pour vraiment émettre un adc < / code>.


2 commentaires

Yup, il est difficile d'obtenir GCC d'émettre ADC pour incréments conditionnels comme ce qui précède. Je pense GCC a un peephole ou une autre étape qui prend un ADC avec un 0 immédiat et se transforme en un (généralement pire sur le matériel moderne) < Code> Xor EAX, EAX; Setb al; Ajouter ..., EAX Séquence. Par exemple, si vous supprimez b de ce qui précède, il est (A + (C La séquence naturelle serait d'utiliser un adc avec 0 mais GCC fait l'étrange seteb chose. Idem pour expression ternaire comme a + = (c . Cependant, si vous faites a + = (c ou toute autre valeur elcone-one-one It fait utilise ADC EAX, 2 .


Donc, il ne semble que lorsque 0 serait l'immédiat que cela fait cette étrangeté. De plus, si vous utilisez une branche, comme si (c il utilise adc ! J'ai essayé de nombreux exemples sur Godbolt .