Sto scrivendo un compilatore e devo emettere il codice per le condizioni di ramificazione sui valori float. Ad esempio, per compilare questo tipo di codice:Qual è il modo migliore per eseguire la ramificazione tramite Intel SSE?
if(a <= b){
//1. DO something
} else {
//2. Do something else
}
Quando a e b sono variabili float. Devo solo saltare a 2 se la condizione non è vera, altrimenti cadere a 1. Sto considerando qui l'ottimizzazione a livello di compilatore considerando ciò che è in 1 e 2.
Ho bisogno di qualcosa che funzioni con tutti gli operatori di confronto >,> =, <, < =, == e! =
Un modo che ho trovato per fare il confronto è quello di utilizzare CMPLTSD (e altre istruzioni equivalenti per gli altri operatori relazionali). Ma con quello, devo usare un registro SSE soprattutto per il risultato e poi devo spostare il suo valore su un registro generale (eax per esempio) e infine confrontare il valore con 0.
Ho anche visto che il L'istruzione UCOMISD dovrebbe impostare correttamente i flag, ma a quanto pare non funziona come pensavo.
Quindi, qual è il modo migliore per gestire un codice del genere? Ci sono istruzioni migliori della prima soluzione che ho?
Nel migliore dei casi, la soluzione generale a questo problema. Se possibile, mi piacerebbe che il codice si comportasse allo stesso modo di quando si fanno i confronti sugli interi (etichetta cmp a, b; jge). Naturalmente, preferirei le istruzioni più veloci per raggiungere questo obiettivo.
Il modo migliore per farlo * dipende da ciò che si sta facendo *. Come in, cosa c'è dentro il blocco '// DO something'? "Il modo migliore" spesso dipende dall'intera immagine, non dal tentativo di tradurre il codice riga per riga. – jalf
Ho aggiunto dettagli al post per rispondere alle tue due domande. –
Se si desidera effettivamente diramazione, UCOMISD (che in realtà è SSE2) sembra essere la risposta, qual è il problema? Il risultato non ordinato? – harold