Se ho il seguente codice C++ per confrontare due interi senza segno a 128 bit, con linea amd-64 asm:In estensione asm in stile GCC, è possibile generare un valore booleano "virtualizzato", ad es. la bandiera del carry?
struct uint128_t {
uint64_t lo, hi;
};
inline bool operator< (const uint128_t &a, const uint128_t &b)
{
uint64_t temp;
bool result;
__asm__(
"cmpq %3, %2;"
"sbbq %4, %1;"
"setc %0;"
: // outputs:
/*0*/"=r,1,2"(result),
/*1*/"=r,r,r"(temp)
: // inputs:
/*2*/"r,r,r"(a.lo),
/*3*/"emr,emr,emr"(b.lo),
/*4*/"emr,emr,emr"(b.hi),
"1"(a.hi));
return result;
}
Poi sarà inline molto efficiente, ma con un difetto. Il valore di ritorno viene eseguito tramite l'"interfaccia" di un registro generale con un valore di 0 o 1. Questo aggiunge due o tre istruzioni aggiuntive non necessarie e riduce l'operazione di confronto che altrimenti sarebbe completamente ottimizzata. Il codice generato sarà simile a questo:
mov r10, [r14]
mov r11, [r14+8]
cmp r10, [r15]
sbb r11, [r15+8]
setc al
movzx eax, al
test eax, eax
jnz is_lessthan
Se uso "SBB% 0,% 0" con un valore di ritorno "int" invece di "SETC% 0" con un valore di ritorno "bool", c'è ancora due ulteriori istruzioni:
mov r10, [r14]
mov r11, [r14+8]
cmp r10, [r15]
sbb r11, [r15+8]
sbb eax, eax
test eax, eax
jnz is_lessthan
Quello che voglio è questo:
mov r10, [r14]
mov r11, [r14+8]
cmp r10, [r15]
sbb r11, [r15+8]
jc is_lessthan
GCC in linea esteso asm è meraviglioso, in caso contrario. Ma voglio che sia buono come una funzione intrinseca, in ogni modo. Voglio essere in grado di restituire direttamente un valore booleano sotto forma dello stato di un flag o flag di CPU, senza doverlo "renderizzare" in un registro generale.
E 'possibile, o GCC (e il compilatore Intel C++, che consente anche di utilizzare questa forma di asm in linea) deve essere modificato o anche refactored per renderlo possibile?
Inoltre, mentre ci sono - c'è un altro modo in cui la mia formulazione dell'operatore di confronto potrebbe essere migliorata?
A partire dal 2013, non sembra ancora possibile fare direttamente. Ma ecco un bug report del 2011 che parla della desiderabilità di una tale funzionalità: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611. Si collega a un thread del kernel Linux del 2001 che desidera anche una cosa del genere: http: //lkml.indiana.edu/hypermail/linux/kernel/0.111,2/0256.html. –