2016-05-09 5 views
2

Existe-t-il des éléments intrinsèques pour que les compilateurs ARM C effectuent des opérations d'ajout avec report ou est-il nécessaire d'utiliser le langage d'assemblage?Existe-t-il des intrinsèques ARM pour ajouter-avec-transporter en C?

Sur x86, il existe _addcarry_u64 pour ajouter-à-porter. (Il y a aussi le plus récent _addcarryx_u64 pour des applications spéciales.)

+0

Les compilateurs implémentent généralement 'int64_t' sur des machines 32 bits avec' adc', ce qui vous permet de les convertir. GNU C (gcc/clang) sur les plates-formes 64 bits prend généralement en charge '__int128_t'. –

+0

Aarch64 possède une instruction adc utilisée par gcc 5.2. ('adds' /' adc' pour ajouter deux arguments '__int128_t'), mais Aarch64 gcc 4.8 utilise l'instruction [cmov-and-increment' csinc'] (http://infocenter.arm.com/help/index.jsp ? topic =/com.arm.doc.dui0802a/CSINC.html). Voir [la sortie sur godbolt] (https://godbolt.org/g/OujSx4). IDK pourquoi aarch64 gcc 4.8 ne parvient pas à utiliser juste 'adc'. –

+0

Je ne vois pas de fonction gcc '__builtin' pour ajouter-avec-carry :( –

Répondre

3

Il n'y a pas d'intrinsèque avec les versions actuelles de gcc. Un problème est cette communication du «drapeau de report». Toutefois, le backend ARM connaît et définit un ensemble de ADC primitives telles que addsi3_carryin.

Pour example,

unsigned long long big_inc(unsigned long long x) 
{ 
    return ++x; 
} 

est traduit à,

big_inc(unsigned long long): 
     @ args = 0, pretend = 0, frame = 0 
     @ frame_needed = 0, uses_anonymous_args = 0 
     @ link register save eliminated. 
     adds r0, r0, #1 
     adc  r1, r1, #0 
     bx  lr 

Il est toujours instructif de regarder les bibliothèques open source multi-précision lorsque vous avez une question comme ça. Il y a OpenSSL bignum et GNU MP bibliothèques sans aucune recherche. Comme l'intrinsèque n'existe pas, une réponse plus définitive (pour votre travail) dépend exactement de ce que vous voulez réaliser; facteurs premiers, multiplier, ajouter, etc. Vous pouvez toujours utiliser l'assembleur ou plus puissamment utiliser un script qui génère l'assembleur pour votre longueur entière particulière.

+0

Un grand nombre de bibliothèques à usage général vont faire quelque chose comme [périphérique Duff] (https://en.wikipedia.org/wiki/Duff's_device) et courir jusqu'à 'int [] ' pour effectuer une opération, il est souvent possible de combiner l'intérieur de la boucle pour des gains d'efficacité car vous n'avez pas besoin de continuer à charger de la mémoire. Cela dépend de ce que vous voulez faire... –