L'istruzione di salto incondizionato jump-and-link (jal
) è l'unica istruzione che utilizza il formato di tipo UJ. Questa istruzione consiste in un codice operativo su 7 bit, un registro operando di destinazione su 5 bit e un indirizzo immediato su 20 bit. L'indirizzo di collegamento, che è l'indirizzo dell'istruzione successiva alla jal
, viene scritta nel campo rd. Come per il formato di tipo SB incontrato per le istruzioni condizionali, UJ utilizza una codifica insolita e non può codificare gli indirizzi dispari. Quindi: jal x0, 2000
consente di saltare all'indirizzo 2000 decimale che è in binario uguale a 0111 1101 0000 viene assemblata in questo formato:
Se gli indirizzi del programma trovassero posto in questo campo a 20 bit, risulterebbe che nessun programma potrebbe avere una dimensione superiore a
PC = Registro + Offset del salto
Questa somma consentirebbe a un programma di indirizzare $2^{64}$ posizioni pur continuando a utilizzare i salti condizionati, risolvendo il problema della dimensione dell'indirizzo di salto. La domanda che dobbiamo porci è: quale registro si deve utilizzare? La risposta proviene da una analisi statistica di come i salti condizionati vengono utilizzati: essi si trovano tipicamente nei cicli e nei costrutti _if_, e quindi di solito eseguono salti a istruzioni vicine. Dal momento che il _PC_ contiene l'indirizzo dell'istruzione corrente, si può saltare con un salto condizionato fino a una distanza di $\pm 2^{10}$ word rispetto all'istruzione corrente. Mentre con un salto incondizionato fino a $\pm 2^{18}$ word rispetto all'istruzione corrente, utilizzando il PC come registro da sommare all'indirizzo di salto. Quindi l'equazione sopra diventa:PC = PC + Offset del salto
Il RISC-V utilizza l'indirizzamento relativo al PC per tutti i tipi di salto condizionato e incondizionato, dato che l'indirizzo di destinazione ha un'alta probabilità di essere vicino a quello dell'istruzione di salto. D'altra parte le chiamate a procedura facilmente richiedono di saltare più di $2^{18}$ word, dato che non è garantito che il chiamante si trovi vicino in memoria al chiamato. Quindi RISC-V consente di effettuare salti molto lunghi a uno qualsiasi tra $2^{32}$ indirizzi utilizzando una sequenza di due istruzioni: l'istruzione `lui` ([[Load Up Immediate]]) scrive i bit da 12 a 31 in un registro temporaneo e `jalr` somma i 12 bit meno significativi all'indirizzo contenuto nel registro temporaneo e salta all'indirizzo ottenuto con la somma. Dato che le istruzioni RISC-V sono ampie 4 byte, le istruzioni di salto di RISC-V sono state progettate per ampliare il loro spazio di indirizzamento definendo l'indirizzo relativo al PC ==in termini di numero di _word_ tra l'istruzione corrente di salto e l'istruzione di destinazione di salto==, invece che in termini di numero di byte. In realtà i progettisti hanno previsto anche la possibilità di avere istruzioni di soli 2 byte. Quindi, vengono contate il numero di _half-word_ tra l'istruzione corrente e quella a cui saltare. Per questo gli indirizzi delle istruzioni saranno sempre pari. In tal caso, è possibile escludere sempre l'ultimo bit, poiché sarà sempre il bit 0, che indica che il numero è pari, questo ci consente di utilizzare effettivamente 13 bit per i salti e non 12. Il processore RISC-V in caso di salti, si ricorderà, in caso di salti, di dover aggiungere sempre tale 0. Il range delle istruzioni a cui si può saltare cambia. Non è di $(-2^{12}, 2^{12-1}-1)$, ma di $(-2^{13-1}, 2^{13-1}-1) = (-4096, +4094)$, il numero massimo è 4094 e non 4095, poiché avendo sempre 0 alla fine, avremo l'ultimo numero pari rappresentabile.Si noti come i numeri pari hanno sempre 0 alla fine:
Decimale | Binario |
---|---|
2 | 0010 |
4 | 0100 |
6 | 0110 |
8 | 1000 |
10 | 1010 |
Nelle istruzioni del tipo I, la costante che viene prelevata dall'istruzione stessa è contenuta nel campo immediato dell'istruzione. (Indirizzamento immediato)
Nelle istruzioni del tipo R, l'indirizzamento avviene tramite il campo in cui viene specificato il numero del registro. (Indirizzamento tramite registro)
Nelle istruzioni di caricamento dalla memoria e di scrittura in memoria, l'offset è contenuto nel campo immediato e viene utilizzato per sommarlo all'indirizzo base e trovare l'indirizzo di memoria desiderato. (Indirizzamento tramire base e offset)
Nelle istruzioni di branch sempre nel campo immediato è contenuto l'offset a cui deve saltare il PC, tale offset viene sommato all'indirizzo del PC. (Indirizzamento relativo al PC)