corso di laurea in Ingegneria Informatica Massimo Trubia di calcolatori/leo/Laboratorio...
Transcript of corso di laurea in Ingegneria Informatica Massimo Trubia di calcolatori/leo/Laboratorio...
UNIVERSITA DI CATANIAFacolta di Ingegneria
corso di laurea in Ingegneria Informatica
Massimo Trubia
PROGETTO E IMPLEMENTAZIONE DI UN MODELLO DIFLOATING POINT UNIT IN UN SIMULATORE DI CPU MIPS64
Tesi di Laurea
Relatore:Chiar.mo Prof. V. Catania
Correlatori:Ing. F. FazzinoIng. D. Patti
Anno Accademico 2006/2007
Indice
1 Introduzione 2
1.1 Obiettivo della tesi . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.1 EduMIPS64 . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Contributi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3 Panoramica della tesi . . . . . . . . . . . . . . . . . . . . . . . . . 4
2 L’architettura MIPS64 5
2.1 Storia dei processori RISC . . . . . . . . . . . . . . . . . . . . . . 5
2.2 Architettura Load/Store . . . . . . . . . . . . . . . . . . . . . . . 7
2.3 Registri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.4 Indirizzamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.5 Instruction set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.5.1 Formati delle istruzioni . . . . . . . . . . . . . . . . . . . . 9
2.5.2 Raggruppamento per funzionalita . . . . . . . . . . . . . . 11
2.6 Pipelining . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.6.1 Implementazione di una pipeline a cinque stadi . . . . . . 16
2.6.2 Dipendenze . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.6.3 Hazard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
I
3 La floating point unit dei processori MIPS64 23
3.1 Numeri in virgola mobile . . . . . . . . . . . . . . . . . . . . . . . 23
3.2 Standard IEEE 754-1985 . . . . . . . . . . . . . . . . . . . . . . . 24
3.2.1 Memorizzazione di un numero floating point . . . . . . . . 25
3.2.2 Valori speciali . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.2.3 Eccezioni . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.2.4 Arrotondamenti . . . . . . . . . . . . . . . . . . . . . . . . 30
3.2.5 Operazioni floating point . . . . . . . . . . . . . . . . . . . 31
3.3 Floating point unit e standard IEEE 754 . . . . . . . . . . . . . . 34
3.4 Registri floating point . . . . . . . . . . . . . . . . . . . . . . . . 35
3.4.1 FCSR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.4.2 Altri registri . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3.5 Instruction set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.5.1 Trasferimento dati . . . . . . . . . . . . . . . . . . . . . . 38
3.5.2 Aritmetiche . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.5.3 Conversione . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.5.4 Spostamento operandi formattati . . . . . . . . . . . . . . 40
3.5.5 Salto condizionale . . . . . . . . . . . . . . . . . . . . . . . 40
3.6 Pipelining . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.6.1 Concorrenza sul register file . . . . . . . . . . . . . . . . . 42
3.6.2 Rilevamento degli hazard . . . . . . . . . . . . . . . . . . . 43
3.6.3 Pipeline FP del MIPS R4000 . . . . . . . . . . . . . . . . 44
4 La floating point unit di EduMIPS64 46
4.1 Operazioni floating point . . . . . . . . . . . . . . . . . . . . . . . 46
4.1.1 Gestore delle eccezioni sincrone . . . . . . . . . . . . . . . 48
II
4.1.2 Addizione . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
4.1.3 Moltiplicazione . . . . . . . . . . . . . . . . . . . . . . . . 50
4.1.4 Divisione . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
4.2 Registri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.2.1 FCSR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.3 Instruction set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
4.3.1 Classe Instruction . . . . . . . . . . . . . . . . . . . . . . . 57
4.3.2 Classi base dell’instruction set . . . . . . . . . . . . . . . . 58
4.3.3 Ereditarieta dalla classe ComputationalInstructions . . . . 59
4.3.4 Ereditarieta dalla classe FlowControlInstructions . . . . . 65
4.3.5 Ereditarieta dalla classe LDSTInstructions . . . . . . . . . 66
4.4 Pipelining . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
4.4.1 Pipeline floating point . . . . . . . . . . . . . . . . . . . . 67
4.4.2 File di configurazione della FPU . . . . . . . . . . . . . . . 68
4.4.3 Interazione tra CPU ed FPU . . . . . . . . . . . . . . . . . 69
5 Conclusioni 78
A Manuale utente della FPU di EduMIPS64 80
A.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
A.2 Valori speciali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
A.2.1 NaN o Invalid Operation . . . . . . . . . . . . . . . . . . . 81
A.2.2 Zeri o Underflow . . . . . . . . . . . . . . . . . . . . . . . 81
A.2.3 Infiniti od Overflow . . . . . . . . . . . . . . . . . . . . . . 82
A.2.4 Infiniti o Divide by zero . . . . . . . . . . . . . . . . . . . 82
A.3 Configurazione delle eccezioni . . . . . . . . . . . . . . . . . . . . 82
III
A.4 Direttiva .double . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
A.5 Registro FCSR . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
A.6 Instruction set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
IV
Elenco delle figure
2.1 Formati dell’ISA MIPS64 . . . . . . . . . . . . . . . . . . . . . . . 10
2.2 Pipeline di EduMIPS64 . . . . . . . . . . . . . . . . . . . . . . . . 16
3.1 Formato dei numeri FP in doppia precisione . . . . . . . . . . . . 25
3.2 Formato dei numeri FP in singola precisione . . . . . . . . . . . . 25
3.3 Mantisse prima della moltiplicazione . . . . . . . . . . . . . . . . 32
3.4 Risultato del prodotto fra le mantisse prima della normalizzazione 32
3.5 Prodotto normalizzato prima dell’arrotondamento . . . . . . . . . 32
3.6 Mantisse prima dell’addizione . . . . . . . . . . . . . . . . . . . . 33
3.7 Risultato della somma delle mantisse prima della normalizzazione 34
3.8 Mantissa normalizzata prima dell’arrotondamento . . . . . . . . . 34
3.9 Registro FCSR . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.10 Pipeline a 5 stadi . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.11 Register file di un processore MIPS64 . . . . . . . . . . . . . . . . 42
4.1 Sommatore floating point (R1+R2=R3) . . . . . . . . . . . . . . 50
4.2 Moltiplicatore floating point . . . . . . . . . . . . . . . . . . . . . 52
4.3 Divisore floating point . . . . . . . . . . . . . . . . . . . . . . . . 52
4.4 Diagramma delle classi dei registri di EduMIPS64 . . . . . . . . . 54
4.5 Modalita di accesso alla classe FCSRRegister . . . . . . . . . . . . 54
V
4.6 Classe Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
4.7 Classi base dell’istruction set . . . . . . . . . . . . . . . . . . . . . 59
4.8 Classi ereditate da ComputationalInstructions . . . . . . . . . . . 60
4.9 Ereditarieta dalla classe FlowControlInstructions . . . . . . . . . 65
4.10 Ereditarieta dalla classe LDSTInstructions . . . . . . . . . . . . . 66
4.11 Diagramma UML delle classi della pipeline FP . . . . . . . . . . . 68
A.1 Configurazione delle trap per le eccezioni IEEE . . . . . . . . . . 83
A.2 Opzione che maschera le eccezioni sincrone(disabilita tutte le trap) 83
A.3 Finestra che notifica la trap . . . . . . . . . . . . . . . . . . . . . 83
A.4 Registro FCSR in EduMIPS64 . . . . . . . . . . . . . . . . . . . . 85
A.5 Configurazione modalita di arrotondamento . . . . . . . . . . . . 90
VI
Elenco delle tabelle
2.1 Campi delle istruzioni . . . . . . . . . . . . . . . . . . . . . . . . 11
3.1 Dati di conversione decimale/single . . . . . . . . . . . . . . . . . 26
3.2 Parametri di formato dello standard IEEE 754 . . . . . . . . . . . 26
3.3 Rappresentazione dei valori speciali . . . . . . . . . . . . . . . . . 27
3.4 Istruzioni di trasferimento dati . . . . . . . . . . . . . . . . . . . . 39
3.5 Istruzioni aritmetiche . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.6 Istruzioni di conversione . . . . . . . . . . . . . . . . . . . . . . . 40
3.7 Istruzioni di spostamento degli operandi formattati . . . . . . . . 40
3.8 Istruzioni di salto condizionale . . . . . . . . . . . . . . . . . . . . 40
3.9 Operazioni primitive della pipeline FP dell’R4000 . . . . . . . . . 45
3.10 Operazioni FP dell’R4000 . . . . . . . . . . . . . . . . . . . . . . 45
3.11 Stalli nelle unita funzionali . . . . . . . . . . . . . . . . . . . . . . 45
A.1 Esempi sui tipi di arrotondamento . . . . . . . . . . . . . . . . . . 90
VII
Listati
4.1 Scrittura dei codici condizionali sull’FCSR . . . . . . . . . . . . . 55
4.2 Scrittura dei bit di causa sull’FCSR . . . . . . . . . . . . . . . . . 55
4.3 Metodo che memorizza i dati della GUI sull’FCSR . . . . . . . . . 56
4.4 Porzione della funzione che effettua il confronto tra registri . . . . 63
4.5 Invocazione metodo EX e gestione eccezioni sincrone . . . . . . . 73
4.6 Gestione dello stadio ID . . . . . . . . . . . . . . . . . . . . . . . 76
1
Capitolo 1
Introduzione
1.1 Obiettivo della tesi
Nei corsi universitari in cui si studiano le architetture dei calcolatori si usano,
come ausilio didattico, simulatori che modellano in modo realistico questi sistemi.
In particolare, studiando vari tipi di processori e le istruzioni in codice Assembly
che essi possono elaborare, i simulatori assumono un ruolo preponderante, in
quanto consentono l’ispezione dei valori delle celle di memoria, dei registri e della
pipeline, mentre le istruzioni sono processate; valutano statistiche di calcolo, ed
eseguono diverse altre operazioni.
Di seguito sono elencati alcuni motivi per i quali, tra i vari tipi di processori,
sempre piu spesso nei corsi universitari e nelle scuole tecniche si studiano le ar-
chitetture MIPS. I progettisti hanno realizzato un set di istruzioni ”pulito”: le
istruzioni sono divise in soli tre tipi (R, I e J) che saranno illustrati nei capitoli
successivi. I processori RISC sono intrinsecamente piu semplici rispetto ai CISC,
e da non trascurare e il fatto che MIPS e dominante nelle applicazioni embedded,
come fotocamere digitali, TV digitali, consolle da gioco, router di rete e cosı via.
2
CAPITOLO 1. INTRODUZIONE
1.1.1 EduMIPS64
EduMIPS64 e originariamente nato come semplice porting GPL1 a Java Swing
del simulatore WinMIPS64. Il gruppo di sviluppatori di EduMIPS64 aveva deciso,
nella prima meta del 2006, di dar vita ad un progetto per creare un programma
con interfaccia utente molto simile a WinMIPS64, quest’ultimo eseguibile solo
su Microsoft Windows2, disponibile agli utenti di tutte le piattaforme in quanto
totalmente riprogettato in Java.
Il programma e cresciuto molto rapidamente grazie al continuo supporto dei
vecchi sviluppatori, che lo hanno reso sempre piu robusto, e alla crescita del grup-
po, alimentato dagli allievi autori di tesine del corso di Laboratorio di Calcolatori.
Tale supporto ha reso, in meno di un anno, il simulatore abbastanza stabile per
essere utilizzato nei corsi di Laboratorio di Calcolatori dell’Universita di Catania.
EduMIPS64 non ha ancora raggiunto la versione 1.0 perche e stata finora as-
sente la FPU (Floating Point Unit), componente essenziale di un simulatore di
CPU. L’obiettivo di questa tesi e la progettazione di un modello che emuli il copro-
cessore 1 floating point delle moderne architetture MIPS64 e la sua integrazione
in EduMIPS64.
1.2 Contributi
La FPU implementata modella con buona approssimazione concettuale la reale
architettura di un processore MIPS64; tuttavia, per evidenti esigenze di ottimiz-
zazione nei calcoli, sono state impiegate alcune classi gia presenti nel Java Runtime
Environment 1.5.
1GPL - General Public License2WinMIPS64 e stato scritto in Microsoft Visual C++
3
CAPITOLO 1. INTRODUZIONE
L’implementazione delle eccezioni sincrone floating point, definite dallo stan-
dard IEEE 754, sfrutta il gestore degli interrupt gia presente in EduMIPS64 e
sviluppato in un precedente lavoro di tesi.
Tutto il codice scritto per questa tesi sara integrato nella versione 1.0 del
simulatore, tuttavia, fino all’uscita di questa versione, e possibile provare le nuove
funzionalita apportate scaricando, dal sito ufficiale [3], la versione svn.
1.3 Panoramica della tesi
Nel Capitolo 2 viene discussa l’archittettura delle CPU MIPS64. Si parla,
in particolare, dei dettagli implementativi di registri, memoria e pipeline. Nel
capitolo 3 viene illustrata la floating point unit di questo tipo di CPU e il modo
in cui e implementato lo standard IEEE 754 per che regola l’aritmetica floating
point dei calcolatori. Si approfondiscono le problematiche insite nel pipelining
delle istruzioni floating point, utilizzando come metro di paragone la pipeline del
processore R4000. Nel Capitolo 4 si parla della floating point unit di EduMIPS64
e dei relativi dettagli progettuali. Vengono illustrate le soluzioni alle piu comuni
problematiche del pipelining, evidenziando le modifiche apportate al codice del
simulatore per simulare l’esecuzione delle istruzioni floating point. Nell’Appendice
A e presente il manuale utente della floating point unit di EduMIPS64; essa
verra estratta e inserita, come capitolo, nel Manuale utente di EduMIPS64 per la
versione 1.0 del simulatore.
4
Capitolo 2
L’architettura MIPS64
In questo capitolo viene illustrata l’architettura dei processori MIPS64. Dopo
una breve prospettiva storica che si puo approfondire in [12], riguardante l’evoluzione
di queste CPU, vengono illustrati i 32 registri general-purpose e come essi coadiu-
vano l’indirizzamento in memoria. Nel Paragrafo 2.5 viene fornita una panorami-
ca dell’instruction set ISA MIPS64, mostrando il raggruppamento funzionale delle
istruzioni. Dal Paragrafo 2.6 sono illustrati gli stadi e la struttura di una pipeline a
5 stadi. Successivamente si parla delle problematiche dovute alla sovrapposizione
dell’esecuzione delle istruzioni e come esse vengono risolte limitando parzialmente
la sovrapposizione.
2.1 Storia dei processori RISC
L’architettura dominante nel mercato dei PC e denominata CISC (Complex
Instruction Set Computer): tale nome deriva dalla natura complessa del set di
istruzioni (ISA)1.
Istruzioni complesse supportano operazioni e strutture dati usate dai linguaggi
1ISA - Instruction set architecture
5
CAPITOLO 2. L’ARCHITETTURA MIPS64
di alto livello (HLLs)2, ma la loro lunghezza cresce a dismisura dal momento che
esse devono includere ad esempio gli indirizzi degli operandi in memoria. Tutto
cio complica la decodifica , lo scheduling e il pipelining delle stesse.
Nei primi anni ’80 si inizio a pensare a set di istruzioni piu semplici e fu coniato
il termine RISC (Reduced Instruction Set Computer), anche se l’obiettivo non era
ridurre il numero di istruzioni, bensı la complessita.
L’origine dei processori RISC si puo ricondurre a tre progetti: l’IBM 801, il
RISC di Berkeley, e il MIPS di Standford; essi riscossero grande successo per via
dei vantaggi delle loro performance rispetto alle tradizionali architetture.
L’IBM 801 fu soltanto un progetto sperimentale, mentre gli altri due ebbero
successivi sviluppi. Nel 1980, Patterson e i suoi colleghi dell’Universita di Berke-
ley costruirono due computer chiamati RISC-I e RISC-II, i quali supportavano in
memoria istruzioni a 16 e 32 bit. Nel 1981, Hennessy e i suoi colleghi pubblicarono
una descrizione del MIPS Standford. Quest’ ultimo presentava un efficiente pipe-
lining e uno scheduling compiler-assisted della pipeline, entrambi aspetti originali
dell’architettura MIPS.
L’ISA MIPS si e evoluto nel tempo rispetto all’originale MIPS I, attraverso
l’ISA MIPS V, fino alle attuali architetture MIPS32 e MIPS64. I punti di svolta
si presentarono nel MIPS III, con l’aggiunta di interi e indirizzi a 64 bit, e nelle
versioni MIPS IV-V, con netti miglioramenti delle operazioni floating point, del
codice generato e dello spostamento dati.
L’architettura MIPS32 e basata sull’ISA MIPS II, con l’aggiunta di istruzioni
MIPS III,MIPS IV e MIPS V. Invece l’architettura MIPS64 si basa sull’ISA MIPS
V e gode della compatibilita all’indietro con MIPS32.
2HLLs - Higher-Level Languages
6
CAPITOLO 2. L’ARCHITETTURA MIPS64
In conclusione, entrambe le architetture forniscono un sostanziale vantaggio nel
compromesso costo/prestazioni risultato dei miglioramenti ottenuti in discipline
contigue: tecnologia VLSI, organizzazione delle CPU, progettazione di sistemi
operativi e compilatori.
2.2 Architettura Load/Store
I processori MIPS usano il design load/store per eliminare i lunghi tempi di
accesso alla memoria. Generalmente occorre piu tempo ad eseguire un’operazione
in memoria di quanto ne sia necessario se gli operandi si trovassero gia nei registri.
Sfruttando questo principio i processori vengono dotati di diversi registri on-chip
in modo che le operazioni vengano eseguite solo su di essi. L’accesso in memoria
e comunque garantito esclusivamente tramite l’uso di apposite istruzioni di load
e store. Tale tecnica consente di ridurre il numero di accessi alla memoria e
semplificare drasticamente il set di istruzioni.
2.3 Registri
L’architettura MIPS64 e costituita da 32 registri general-purpose (GPR) og-
nuno di 64 bit, due dei quali vengono usati per funzioni speciali; il registro 0,
chiamato anche $zero, e cablato in hardware e serve a fornire lo zero stesso, men-
tre il registro 31, detto anche $ra, e usato per memorizzare l’indirizzo di ritorno
di una chiamata a procedura. Altri due registri speciali, LO e HI, vengono usati
nelle operazioni di moltiplicazione e divisione, per memorizzarne i risultati. Nel-
la moltiplicazione tra interi di 64 bit e prodotto un risultato lungo 128 bit, la
cui meta piu significativa e posta nel registro HI, e l’altra nel registro LO. Nella
7
CAPITOLO 2. L’ARCHITETTURA MIPS64
divisione intera, invece, il quoziente e memorizzato in LO, e il resto nel registro
HI.
E pratica comune, come si e visto per i registri speciali, usare dei nomi
mnemonici o alias in luogo del numero del registro. Gli alias per i 32 registri
general-purpose sono nell’ordine: zero, at, v0, v1, a0, a1, a2, a3, t0, t1, t2, t3, t4,
t5, t6, t7, s0, s1, s2, s3, s4, s5, s6, s7, t8, t9, k0, k1, gp, sp, fp, ra. Convenzional-
mente, si consiglia di usare i registri $v0 e $v1 per ritornare i risultati da una
procedura, e i registri da $a0 ad $a3 per passare, al piu, quattro argomenti alle
procedure; i rimanenti argomenti vengono passati mediante stack. I registri da $t0
a $t7 sono temporanei e non dovrebbero essere riservati a chiamate di procedura,
al contrario dei registri da $s0 ad $s7, che, essendo callee-saved, sono riservati a
questo scopo. L’ultimo fra i piu importanti e $sp, che punta alla cima dello stack.
Per l’utilizzo degli altri registri consultare [10].
2.4 Indirizzamento
La modalita di indirizzamento si riferisce a come gli operandi sono specificati.
Nelle architetture MIPS l’indirizzo di memoria di un operando e calcolato som-
mando il contenuto di un registro ad una costante. L’indirizzo si puo generalizzare
con la notazione offset(base), dove base e il nome del registro nel formato Rx3 o
$alias, al quale verra sommato un offset, cioe un numero con segno di 16 bit.
Segue un esempio di un’istruzione dell’ISA MIPS64 che consente il caricamento
dei dati della prima cella di memoria sul registro R8:
LD $t0, 0($zero);per i nomi degli alias vedere 4.2.
L’accesso in memoria e regolamentato dai vincoli di allineamento. La memoria
3x - intero compreso tra 0 e 31
8
CAPITOLO 2. L’ARCHITETTURA MIPS64
e composta da doubleword (64 bit). Ogni doubleword e composta da due word (32
bit) affiancate, formate a loro volta da due halfword (16 bit) ciascuna. Le halfword,
infine, sono costituite ognuna da due byte. In funzione di queste definizioni, gli
accessi alle doubleword devono prevedere indirizzi divisibili per 8, quelli alle word
divisibili per 4, quelli alle halfword per 2 e quelli ai byte indirizzi qualunque entro
i limiti di dimensione della memoria.
Nonostante ne sia sconsigliato l’utilizzo, se non per applicazioni particolari,
gli istruction set MIPS32 e MIPS64 mettono a disposizione alcune istruzioni di
load-store non allineato che riguardano solo doubleword e word: LWL, LWR, SWL,
SWR, LDL, LDR, SDL, SDR.
2.5 Instruction set
Come accennato in precedenza, i processori RISC hanno degli istruction set
piu semplici rispetto alle macchine CISC. Cio e dovuto a diversi fattori, tra cui:
il fatto che tutte le operazioni sui registri ne cambiano interamente il valore; il
fatto che le sole operazioni che accedono alla memoria sono le load e le store; il
numero limitato di istruzioni e l’uniformita della loro lunghezza, fissata a 32 bit
per i processori MIPS. Tutti questi aspetti consentono di realizzare solo pochi
formati predefiniti per le istruzioni.
2.5.1 Formati delle istruzioni
L’ISA MIPS64 prevede tre formati di istruzioni, illustrati in Figura 2.1:
• Immediate (I-type): E il formato usato da tutte le istruzioni load-store. Il
valore immediato e uno short, e viene usato sia nelle operazioni aritme-
tiche, alle quali si vuole fornire come operando un piccolo numero senza
9
CAPITOLO 2. L’ARCHITETTURA MIPS64
caricarlo prima in un registro, sia nelle istruzioni di salto, che possono in-
crementare/decrementare il PC di un offset a 18 bit, ovvero saltare in una
finestra di 128 Kbytes(PC-relative branches). Per evitare questa limitazione
nel salto si usano le istruzioni J-Type.
• Jump (J-type): Un campo di 26 bit di questo formato viene combinato con
i bit di ordine piu alto del PC per ottenere l’indirizzo assoluto. Formando
l’indirizzo a cui saltare mediante questa concatenazione, piuttosto che som-
mare un offset al PC, si ha il vantaggio di muoversi in una regione di 256
MB (PC-region branch).
• Register (R-type): E il formato usato dalle istruzioni aritmetiche e logiche,
nonche dalle istruzioni di salto, che utilizzano un registro contenente l’indi-
rizzo di memoria a cui saltare.
Figura 2.1: Formati dell’ISA MIPS64
10
CAPITOLO 2. L’ARCHITETTURA MIPS64
Campo Descrizione Dim. bitopcode codice binario dell’istruzione 6rd registro di destinazione 5rs registro sorgente 5rt registro target (sorgente o destinazione) 5immediate immediato con segno usato per operandi logici,
aritmetici con segno, offset e salti PC-relative 16inst index fornisce i 26 bit che vengono traslati di due a
sinistra per dare i 28 bit meno significatividell’indirizzo di destinazione del salto. 26
sa entita dello shift 5function usato per specificare funzioni all’interno
dell’opcode SPECIAL 6
Tabella 2.1: Campi delle istruzioni
2.5.2 Raggruppamento per funzionalita
Le istruzioni dell’ISA MIPS64 possono anche essere raggruppate secondo questi
gruppi funzionali:
- Load e Store
- Computazionali
- Jump e Branch
- Multiformi
- Coprocessore
per ulteriori approfondimenti sulle singole istruzioni una lista completa e disponi-
bile in [8].
Load e Store
Le istruzioni Load e Store sono le uniche a poter spostare dati dalla memo-
ria ai registri e viceversa. Per ogni unita di dati (si veda il paragrafo 2.4) es-
11
CAPITOLO 2. L’ARCHITETTURA MIPS64
istono almeno un’istruzione di caricamento con segno, una senza segno, e una di
memorizzazione dell’unita stessa.
Alcune istruzioni speciali consentono di selezionare le modalita di indirizza-
mento (per esempio, SDXC1 nella FPU) e di effettuare aggiornamenti atomi-
ci delle celle di memoria (per esempio, lettura-modifica-scrittura - LL/SC) per
implementare meccanismi di sincronizzazione come semafori e mutex.
Computazionali
A questa categoria appartengono le istruzioni che eseguono l’aritmetica a com-
plemento a 2 su interi rappresentati con questa notazione. Le istruzioni di somma
e sottrazione in cui compare il termine ”unsigned”, contrariamente al significato
del termine, non sono soggette alla verifica dell’overflow.
Sono incluse anche delle versioni unsigned di divisione e moltiplicazione, e una
serie di istruzioni che effettuano operazioni logiche e di shift. Le operazioni logiche
non sono sensibili alla lunghezza del registro.
Le istruzioni computazionali possono essere raggruppate in tre categorie: ALU
immediate, ALU a due operandi, ALU a tre operandi, istruzioni di shift, istruzioni
di divisione e moltiplicazione. L’operando immediato e trattato come un valore
con segno per le istruzioni aritmetiche e di confronto, e come valore logico per le
istruzioni di questo tipo.
Jump e Branch
Le istruzioni che consentono di effettuare un salto PC-relative (si veda il para-
grafo 2.5) sono condizionali, in quanto e possibile definire un test la cui verita
da il via al salto, mentre quelle che saltano in una PC-region sono dette uncon-
12
CAPITOLO 2. L’ARCHITETTURA MIPS64
ditional, e la maggior parte della loro lunghezza e riservata alla memorizzazione
dell’indirizzo di destinazione.
L’ultima tipologia e il salto assoluto, praticato sia sostituendo al PC l’indirizzo
in un registro puntato dall’istruzione, sia eseguendo, oltre a questa azione, il
salvataggio in un registro (di solito R31) del PC, per consentirne successivamente
il recupero a seguito di una chiamata ad una procedura.
I salti hanno un ritardo architetturale di un’istruzione, e l’istruzione immedia-
tamente dopo quella di salto si dice essere nel branch delay slot. Se l’istruzione di
salto e una branch, allora quella nel delay slot verra anch’essa eseguita; se quella
di salto e un’istruzione branch-likely, l’istruzione nel delay slot non verra eseguita
se il salto non avverra (branch not taken).
Varie
Appartengono a questo gruppo le istruzioni di eccezione (SYSCALL, TRAP
e BREAK), quelle di spostamento condizionale, ed infine l’istruzione NOP. Le
istruzioni di eccezione trasferiscono il controllo al gestore delle eccezioni nel kernel.
Esistono due tipi di eccezioni: conditional e unconditional. Le prime vengono
lanciate dalle istruzioni di trap (per esempio TEQ,TGE, TLT), le seconde vengono
lanciate dalle system call e dalle istruzioni di breakpoint (BREAK,SYSCALL).
L’istruzione SYSCALL non definisce con precisione i servizi che il sistema ope-
rativo deve fornire, ma essa contiene un codice recuperabile dal gestore delle
eccezioni per invocare un’opportuna system call. Per ulteriori informazioni sulla
SYSCALL implementata in EduMIPS64 consultare [1].
L’ISA MIPS64 include istruzioni per lo spostamento condizionato di un GPR4
4GPR - General Purpose Register
13
CAPITOLO 2. L’ARCHITETTURA MIPS64
in un altro, basato sul valore di un terzo GPR (per esempio MOVF,MOVZ). Per
gli spostamenti condizionali floating point si veda il Paragrafo A.6.
L’istruzione NOP e attualmente codificata come una istruzione all-zero, ed
effettua una non-operazione. E interpretata dall’hardware come SLL r0,r0,0 e
viene generalmente usata per riempire i delay slots e le sequenze di allineamento.
Coprocessore
I coprocessori sono unita di esecuzione alternative alla CPU. L’architettura
MIPS ne prevede quattro numerati da 0 a 3 (CP0 a CP3); essi vengono abilitati
mediante operazioni privilegiate fornite dal System Control Coprocessor (CP0).
Il coprocessore 0 serve, dunque, al controllo del sistema, mentre gli altri tre sono
usati per la FPU.
Le istruzioni coprocessore si dividono in due gruppi: istruzioni load e store,
che hanno il compito di scrivere e leggere i registri di un dato coprocessore (per
esempio LDCz,SDCz con z=1 o z=2), e le istruzioni coprocessor-specific, definite
interamente dal coprocessore in uso.
2.6 Pipelining
Ciascuna istruzione dell’ISA MIPS64, nell’ipotesi in cui non avvenisse il pipe-
lining, verrebbe elaborata in 5 cicli di clock successivi del processore:
1. Instruction Fetch(IF): il PC viene prima inviato alla memoria per prele-
vare l’istruzione corrente, poi aggiornato aggiungendo 4 al suo valore (ogni
istruzione e lunga 4 byte).
2. Instruction Decode(ID): L’istruzione e decodificata, e vengono rilevati i re-
gistri sorgenti dal register file. In questo ciclo viene effettuato il test di
14
CAPITOLO 2. L’ARCHITETTURA MIPS64
uguaglianza per un eventuale salto; viene inoltre esteso, se richiesto, il segno
dell’offset, e calcolata la destinazione del possibile salto aggiungendo l’offset
al PC gia incrementato.
3. Execution(EX): L’ALU lavora sugli operandi preparati nel precedente ciclo.
Se l’istruzione comporta l’accesso in memoria, e calcolato l’ indirizzo effet-
tivo come somma di base e offset; se ha due registri sorgenti, viene letto
l’opcode ed effettuata la relativa operazione sugli operandi; se, infine, pre-
senta un immediato e un registro sorgente, e necessario estendere il segno
dell’immediato prima di effettuare l’operazione.
4. Memory Access (MEM): Se l’istruzione e una load, la memoria effettua una
lettura usando l’indirizzo effettivo calcolato nel ciclo precedente; se e una
store, invece, scrive i dati del registro sorgente nella locazione all’indirizzo
calcolato.
5. Write-back (WB): In questo ciclo, per le istruzioni che implicano la scrittura
sui registri e per quelle di caricamento, si effettua la scrittura dei risultati.
Per l’esecuzione in pipeline di istruzioni che effettuano operazioni aritmetiche
su operandi in virgola mobile, di per se piu complesse rispetto alle operazioni in-
tere, che richiedono un solo ciclo di clock per lo stadio EX, si usufruisce delle varie
unita funzionali della floating point unit residente su un coprocessore dedicato.
In particolare, l’addizionatore esegue lo stadio EX di somme e sottrazioni in 4
cicli, il moltiplicatore esegue il prodotto in 7 cicli, e il divisore effettua la divisione
in 24 cicli (si veda la Figura 2.2). Nel capitolo successivo si approfondiranno le
problematiche del pipelining di istruzioni floating point.
15
CAPITOLO 2. L’ARCHITETTURA MIPS64
Figura 2.2: Pipeline di EduMIPS64
2.6.1 Implementazione di una pipeline a cinque stadi
Nonostante l’esecuzione di ogni istruzione continui ad impiegare 5 cicli per
essere completata, si puo apportare un miglioramento all’algoritmo di esecuzione
precedente sfruttando il fatto che, durante ogni ciclo di clock, l’hardware puo
iniziare ad eseguire una nuova istruzione, e contemporaneamente delle porzioni
diverse di altre 5, purche le risorse usate non siano le stesse. Ad esempio, l’ALU
non puo eseguire il calcolo di un indirizzo di memoria ed effettuare contempo-
raneamente una sottrazione.
In base a quanto detto, si possono fare le seguenti considerazioni:
- dal momento che gli accessi in memoria avvengono sia nello stadio IF, in cui
vengono prelevate le istruzioni, che in MEM, in cui si opera la scrittura/let-
tura dei dati, occorre dividere la memoria dati da quella delle istruzioni.
- Il register file, o banco registri, e usato sia in ID che in WB, rispettivamente
in lettura e in scrittura; per tale ragione occorre separare le due operazioni,
16
CAPITOLO 2. L’ARCHITETTURA MIPS64
realizzando nel primo mezzo ciclo di clock la scrittura, e nel secondo mezzo
ciclo la lettura del file.
- Per iniziare una nuova istruzione ad ogni tick di clock, durante lo stadio
IF, si deve incrementare il PC, e calcolare l’indirizzo di destinazione del
salto che si potrebbe verificare in ID. Un altro problema, che sara affrontato
successivamente, e che, nel caso di istruzione di salto, il PC verra modificato
soltanto nello stadio ID.
- Per assicurare che le istruzioni in stadi differenti della pipeline non inter-
feriscano tra loro, vengono usati dei pipeline registers (per esempio EX/MEM,
MEM/WB), che riportano i risultati dell’esecuzione di uno stadio come
ingressi per il successivo stadio.
- La realizzazione di una pipeline incrementa il numero di istruzioni com-
pletate per unita di tempo, ma non riduce il tempo di esecuzione di una
singola istruzione. L’idea di creare una sovrapposizione nell’esecuzione delle
istruzioni, risalente al 1985, prende il nome di Instruction-Level Parallelism
(ILP); si vedra tuttavia nel paragrafo 2.6.3 che, per via degli hazard, le
prestazioni ottenute con questa tecnica sono inferiori a quelle che si otter-
rebbero con una pipeline ideale (un ciclo per istruzione ovvero CPI=1).
2.6.2 Dipendenze
Per comprendere fino a che punto l’Instruction-Level Parallelism puo essere
sfruttato, occorre determinare come un’istruzione puo dipendere da un’altra.
Soltanto se non c’e alcuna dipendenza le istruzioni possono essere eseguite let-
17
CAPITOLO 2. L’ARCHITETTURA MIPS64
teralmente in parallelo, altrimenti si ha una parziale sovrapposizione e dev’essere
mantenuto l’ordine di esecuzione.
Si hanno tre tipi di dipendenza:
• Dati: quando il risultato prodotto da un’istruzione dev’essere usato da un’al-
tra istruzione, si puo allargare questo principio ad n istruzioni, creando una
catena di n-1 dipendenze dati. Nell’esempio sottostante si evince la dipen-
denza della DSUB dalla DADD: DSUB non puo leggere gli operandi (R1,R5)
finche il valore memorizzato in R1 non diventi valido (DADD raggiunge lo
stadio WB e scrive R1).
DADD R1 , R2 , R3DSUB R4 , R1 , R5
• Nomi: quando due istruzioni usano lo stesso registro o la stessa cella di
memoria nonostante non ci sia un flusso dati tra esse. Si ha un’antidipendenza
dati se un’istruzione deve leggere un registro/cella appena scritto da un’al-
tra istruzione, una dipendenza di output se due istruzioni devono scrivere
sullo stesso registro/cella. In entrambi i casi l’ordine di esecuzione delle
istruzioni dev’essere mantenuto, per garantire, rispettivamente, di aver let-
to il valore appena aggiornato, e scritto per ultimo il registro/cella. Anche
se molto simile alla dipendenza dati, la dipendenza nomi puo essere risol-
ta con una tecnica chiamata register renaming, nella quale si utilizzano dei
registri non permanentemente associati all’architettura, ma dinamicamente
allocati quando richiesto.
Nell’esempio che segue, scritto in pseudocodice assembly MIPS, e illustrata
una dipendenza nomi e come questa puo essere risolta rinominando il registro
in conflitto;
18
CAPITOLO 2. L’ARCHITETTURA MIPS64
MUL R2 , R2 , R3 ; R2 = R2 ∗ R3ADD R4 , R2 , 1 ; R4 = R2 + 1ADD R2 , R3 , 1 ; R2 = R3 + 1DIV R5 , R2 , R4 ; R5 = R2 / R4
L’istruzione 3 non puo andare avanti finche la 1 non ha terminato, perche
c’e una dipendenza di output fra le istruzioni 1 e 3 (entrambe scrivono su
R2). Esiste anche un’antidipendenza dati tra le istruzioni 2 e 3 (l’istruzione
3 sovrascrive uno degli argomenti della 2). Se rinominasse il registro R2,
creandone tre versioni cronologiche diverse (R21,R22,R23)
MUL R21 , R20 , R3ADD R4 , R21 , 1ADD R22 , R3 , 1DIV R5 , R22 , R4
l’istruzione 3 potrebbe eseguire subito, perche si servirebbe di un registro di-
verso da quello delle istruzioni 1 e 2. Per ulteriori approfondimenti sui meto-
di di implementazione di questa tecnica, come i buffer di riordino, consultare
[2]
• Controlli: quando l’esecuzione di un’istruzione dipende dal verificarsi di
qualche condizione. Un semplice esempio usato in [5] ne agevola la com-
prensione:
i f p1{S1 ;
}i f p2{
S2 ;}
S1 e control dipendent da p1, ed S2 e control dipendent da p2, ma non da p1.
L’esecuzione delle istruzioni nell’ordine assicura, dunque, che un’istruzione
che si trova prima di un salto condizionato (branch) venga eseguita prima
19
CAPITOLO 2. L’ARCHITETTURA MIPS64
del salto stesso; analogamente, un’istruzione che e control dipendent da un
branch non viene eseguita finche il salto non va nella sua direzione.
2.6.3 Hazard
Un hazard si puo definire come una situazione di allarme per cui, essendosi
verificata una dipendenza fra istruzioni molto vicine, se si continua ad eseguire le
istruzioni con la massima sovrapposizione prevista dal pipelining c’e il rischio di
un errore durante il flusso di esecuzione del programma
In queste circostanze puo essere necessario introdurre uno stallo per alcune
istruzioni fino a quando l’hazard non venga risolto. Quando un’istruzione subisce
uno stallo, anche quelle emesse successivamente devono essere fermate, mentre le
istruzioni emesse prima possono continuare l’esecuzione.
Hazard strutturale
Un hazard strutturale si verifica quando due o piu istruzioni si contendono
una risorsa non duplicabile, per cui la pipeline deve fermare alcune istruzioni
finche l’unita richiesta non diventi disponibile. Questo tipo di hazard si verifica
sia per le unita funzionali che non sono fully-pipelined, ovvero non applicano il
pipelining delle istruzioni in quanto ne possono elaborare una alla volta (il divisore
floating point ne e un esempio), sia per i riferimenti contemporanei alla memoria
condivisa. Nel paragrafo 4.4 vengono approfonditi i dettagli progettuali della
pipeline, tenendo in grande considerazione l’eventualita di hazard strutturali.
Data hazard
Un data hazard si verifica quando, in presenza di una dipendenza dati, potrebbe
essere cambiato l’ordine di accesso agli operandi coinvolti nella dipendenza. Se
20
CAPITOLO 2. L’ARCHITETTURA MIPS64
questo si verificasse, l’ordine di esecuzione delle istruzioni differirebbe rispetto a
quello di un processore che non implementa la pipeline. I data hazard, a seconda
dell’ordine di lettura o scrittura degli operandi, si distinguono in tre categorie:
1. RAW (read after write): e l’hazard piu comune, corrispondente ad una
dipendenza dati. Si verifica quando un’istruzione legge una sorgente prima
che questa venga scritta, ottenendone cosı il valore non aggiornato.
2. WAW (write after write): Un’istruzione scrive un operando non attendendo
che lo faccia prima un’altra istruzione che la precede, nel registro viene
scritto cosı il valore piu obsoleto.
Questo hazard corrisponde ad una dipendenza di output e si verifica, come
si vedra nel capitolo successivo, con l’utilizzo delle unita funzionali della
floating point unit. Un altro caso e quando si applica il riordinamento delle
istruzioni, approfondito in [5].
3. WAR (write after read): Si verifica quando un’istruzione scrive una des-
tinazione prima che questa venga letta da un’istruzione che la precede:
quest’ultima legge cosı il nuovo valore. Tale hazard corrisponde al caso
di antidipendenza, ma non puo mai verificarsi nelle pipeline che prevedono
le letture in ID e le scritture in WB.
Control hazard
Quando un’istruzione di branch viene eseguita, il valore del PC potrebbe es-
sere incrementato soltanto di 4 (branch not taken - salto non avvenuto); oppure,
potrebbe assumere il valore dell’indirizzo dell’istruzione puntata dal salto (branch
taken). Se il branch e taken si effettua il fetch dell’istruzione puntata5; cio in-
5L’esecuzione dello stadio IF e in se uno stallo
21
CAPITOLO 2. L’ARCHITETTURA MIPS64
vece non e necessario se il branch e not taken, in quanto il fetch dell’istruzione
successiva e implicito nella dinamica della pipeline.
22
Capitolo 3
La floating point unit deiprocessori MIPS64
In questo capitolo, dopo una breve panoramica sull’aritmetica floating point,
che puo essere approfondita in [9, 11, 4], e dello standard IEEE 754, si discute
dell’architettura della floating point unit di un processore MIPS64, e il modo in
cui essa si adegua al suddetto standard. Nel Paragrafo 4.2 si parla dei registri
floating point, del registro di controllo FCSR e di altri registri speciali della FPU.
Nel Paragrafo 3.5 vengono illustrate solo le istruzioni floating point di interesse
per questa tesi, raggruppate secondo categorie funzionali. Dopo questa panora-
mica, nel Paragrafo 3.6, vengono introdotte le problematiche relative al pipelining
delle istruzioni floating point. Alla fine del capitolo si fa cenno alla pipeline del
processore MIPS R4000 [6].
3.1 Numeri in virgola mobile
In ambito scientifico si e soliti trattare numeri molto grandi o molto piccoli,
che non possono essere manipolati con l’aritmetica in virgola fissa1. Mediante
la notazione scientifica, lo stesso numero puo essere scritto in modi diversi: per
1Quella che prevede la virgola a destra della cifra meno significativa
23
CAPITOLO 3. LA FLOATING POINT UNIT DEI PROCESSORI MIPS64
esempio la distanza della Luna dalla Terra in Km si puo esprimere sia come
38.44 × 104, che come 3.844 × 105 (3.844 e la mantissa e 5 l’esponente);
quest’ultima forma e detta normalizzata. I calcolatori memorizzano i numeri in
virgola mobile in un’equivalente notazione scientifica con base 2; lo stesso numero
viene dunque arrotondato e trattato da un computer come 1.4663696× 218.
Dal momento che, in decimale, la mantissa si puo espandere in serie di potenze
(∑∞
n=0 anxn), ponendo la variabile argomento x = 10−1
1.4663696 = 1 + 4× 10−1 + 6× 10−2 + 6× 10−3 + 3× 10−4 + 6× 10−5 + ...
analoga cosa si puo fare per scriverne l’equivalente binario, ponendo x = 2−1.
1.01110111011001 = 1 + 0× 2−1 + 1× 2−2 + 1× 2−3 + 1× 2−4 + 0× 2−5 + ...
Nel paragrafo successivo si vedra la rappresentazione di questo numero secondo
lo standard IEEE 754.
3.2 Standard IEEE 754-1985
Circa trent’anni fa, nell’ambito dell’aritmetica floating point implementata
nel software dei microprocessori, regnava la totale anarchia. Venivano utilizzate
numerose rappresentazioni dei numeri in virgola mobile, con diverse grandezze,
precisioni, modi di arrotondamento ed eccezioni. Nel 1977 il Prof. W.Kahan
dell’universita di Berkeley, ottenne il permesso a partecipare alla realizzazione
di uno standard che mettesse fine a tale confusione, preparo una bozza chiama-
ta ”K-C-S”. Dopo un’estenuante battaglia con la DEC, che aveva gia messo sul
mercato i processori VAX, la bozza fu sottoposta a varie revisioni di compro-
messo, fino a quando il gruppo di lavoro 754 la invio al comitato degli standard
24
CAPITOLO 3. LA FLOATING POINT UNIT DEI PROCESSORI MIPS64
dei microprocessori della IEEE. Denominata IEEE 754-1985 for Binary Floating-
Point Arithmetic, la bozza rettificata divenne lo standard de facto, usato tuttora
nell’aritmetica floating point.
3.2.1 Memorizzazione di un numero floating point
Lo standard IEEE 754 specifica tre formati di numeri floating point: single
(32 bit), double (64 bit) e double-extended (maggiore di 10 byte). Come visto nel
precedente paragrafo, ogni numero e rappresentato con la notazione
mantissa× 2esponente
ma l’esponente non e mai memorizzato come numero con segno, bensı polarizzato.
Con tale tecnica viene aggiunta all’esponente una costante di polarizzazione(bias),
che consente di traslare nel semiasse positivo dei numeri interi l’intervallo di valori
che l’esponente puo assumere2. Cosı facendo, il confronto fra numeri floating point
puo essere realizzato con lo stesso hardware che manipola i numeri interi.
Figura 3.1: Formato dei numeri FP in doppia precisione
Figura 3.2: Formato dei numeri FP in singola precisione
I numeri nel formato IEEE normalizzati soddisfano la relazione 1 ≤ mantissa < 2.
Sfruttando tale proprieta, la mantissa si presenta sempre nella forma 1, xx..x3, per
cui si puo non salvare il suo bit piu significativo poiche vale sempre 1(hidden bit).
2Il valore di esponente 1 e il piu negativo assumibile con lo spazio dati a disposizione3Per errori di traduzione mantissa e intesa sia col suo vero significato (significand), sia come
la sua parte decimale che e quella memorizzata nei formati IEEE754(fraction)
25
CAPITOLO 3. LA FLOATING POINT UNIT DEI PROCESSORI MIPS64
Valore decimale Valore binario
Campo della mantissa 0.4663696 01110111011001000000000Campo dell’esponente 18 + 127 10010001Campo del segno 0 0Numero memorizzato 1.4663696× 218 0 10010001 01110111011001000000000
Tabella 3.1: Dati di conversione decimale/single
Per scrivere in formato single il numero del precedente esempio, la cui man-
tissa binaria e 1.01110111011001 e l’esponente 18, tenendo conto che la costante
di polarizzazione per i single e 127 e il numero dev’essere espresso nella forma
1.mantissa× 2esponente−127, si hanno i risultati della Tabella 3.1.
Single Single extended Double Double extended
Bit di precisione 24 ≥ 32 53 ≥ 64Esponente massimo (Emax) 127 ≥ 1023 1023 ≥ 16383Esponente minimo (Emin) -126 ≤ −1022 -1022 ≤ −16382Bias 127 1023
Tabella 3.2: Parametri di formato dello standard IEEE 754
3.2.2 Valori speciali
I numeri piu piccolo e piu grande assumibili dall’esponente polarizzato4 (per i
single 0 e 255) vengono usati per rappresentare valori speciali. Quando l’esponente
polarizzato vale 255, se il campo mantissa contiene solo zeri, il numero rappresen-
ta l’infinito positivo o negativo a seconda del segno, mentre se esso contiene un
valore diverso da zero, il numero rapprenta un NaN (Not a Number), usato per
fornire un risultato alle operazioni matematiche non valide (per esempio 0 ×∞oppure 0
0). Nei processori MIPS il bit piu significativo della mantissa ne deter-
mina la tipologia (Quit NaN oppure Signalling NaN). Quando entrambi i campi
4L’esponente polarizzato e detto biased in quanto e ottenuto dalla somma tra l’esponente ela costante di polarizzazione(bias)
26
CAPITOLO 3. LA FLOATING POINT UNIT DEI PROCESSORI MIPS64
dell’esponente polarizzato e della mantissa valgono zero il numero rappresenta lo
zero5. Ii numeri denormals rappresentano un ultimo tipo di valore speciale. In
molti sistemi floating point, un numero piu piccolo di 1.0 × 2Emin non puo es-
sere rappresentato, e dunque considerato uguale a zero. Lo standard IEEE 754
prevede la rappresentazione di questi numeri, la cui mantissa e minore di uno,
per avvicinarsi all’eccezione di underflow (si veda il paragrafo 3.2.3) in modo
graduale.
I numeri denormals vengono rappresentati con la notazione 0.mantissa× 2Emin ,
in essi il campo dell’esponente vale zero, mentre la mantissa qualunque valore
diverso da zero.
E da notare che, se l’esponente non polarizzato appartiene all’intervallo [Emin, Emax],
la mantissa e normalizzata, (scritta nella forma 1,xx..x) e il bit nascosto vale 1;
mentre per poter rappresentare i numeri denormals, il bit nascosto e 0 e il campo
dell’esponente assume il valore piu piccolo in assoluto (Emin− 1), che polarizzato
equivale a zero.
Campo esponente Campo mantissa Valore rappresentato
e = Emin − 1 m = 0 ±0e = Emin − 1 m 6= 0 0.m× 2Emin
Emin ≤ e ≤ Emax – 1.m× 2e
e = Emax + 1 m = 0 ±∞e = Emax + 1 m = 0xx..x,m 6= 0 Quiet NaNe = Emax + 1 m = 1xx..x Signalling NaN
Tabella 3.3: Rappresentazione dei valori speciali
5Anche se cio puo sembrare banale si rifletta sul fatto che non esiste soluzione all’equazione1, ..× 2x = 0
27
CAPITOLO 3. LA FLOATING POINT UNIT DEI PROCESSORI MIPS64
3.2.3 Eccezioni
Una delle piu importanti regole fornite dallo standard IEEE 754 e che il
calcolo, se espressamente voluto, puo continuare nonostante sia stato prodotto un
risultato ”eccezionale”:
- Indeterminato: prodotto, per esempio, da operazioni del tipo 00
oppure 0×∞
- Infinito: come per il risultato di una divisione per zero
- Troppo grande in valore assoluto: una moltiplicazione tra numeri grandi
potrebbe avere per risultato un numero non rappresentabile data la sua
grandezza (overflow)
- Troppo piccolo in valore assoluto: la rappresentazione di un tale numero e
problematica per via della perdita di precisione (underflow)
- Inaccurato: come per la rappresentazione di 13
che necessita di un arroton-
damento tra i vari possibili
Le cinque eccezioni previste dallo standard sono: operazione non valida, divisione
per zero (Divide by zero), underflow, overflow e numero inesatto(Inexact).
Operazione non valida
Alcune delle operazioni aritmetiche non valide che forniscono come risultato
NaN sono:
√x, x < 0 0×∞ 0.0
0.0∞∞ ∞−∞
Nella floating point unit dei processori MIPS64 e utilizzato uno speciale re-
gistro chiamato FCSR, descritto nel paragrafo 3.4.1, il quale memorizza delle
28
CAPITOLO 3. LA FLOATING POINT UNIT DEI PROCESSORI MIPS64
informazioni sullo stato delle eccezioni. In esso si trovano le flag di abilitazione
delle trap relative alle 5 eccezioni, e le flag che indicano se qualcuna di queste si
e mai verificata e non e stata ancora rimossa. Quando la flag dell’FCSR relativa
all’attivazione della trap dell’eccezione Operazione non valida e posta a 0, nessuna
trap si verifica, e il valore QNaN dev’essere fornito come risultato.
Divisione per zero
Questa eccezione si verifica quando, in una divisione, il divisore e zero e il
dividendo diverso da zero. Se la relativa trap non e attiva viene generato un
valore infinito con segno.
Underflow
Come visto nella precedente sezione, i numeri dell’intervallo ±1.0×2Emin sono
rappresentati usando mantisse minori di uno. Tale processo, che inizia con la
formazione di numeri denormals, e chiamato underflow graduale e termina con
l’eccezione stessa quando si raggiunge il piu piccolo numero rappresentabile in
valore assoluto.
Overflow
L’eccezione di overflow e segnalata quando il risultato di un’operazione e piu
grande di quello che puo essere rappresentato, cio e dovuto all’intervallo ristretto
dell’esponente. Tale eccezione non viene segnalata quando uno degli operandi e
infinito per via della correttezza dell’aritmetica tra infiniti.
Numero inesatto(Inexact)
Viene segnalata quando il risultato di un’operazione aritmetica ha infinite
cifre decimali (per esempio 13), esso dunque dev’essere arrotondato. La trap del-
29
CAPITOLO 3. LA FLOATING POINT UNIT DEI PROCESSORI MIPS64
l’eccezione inexact e disabilitata e la relativa flag ignorata dalla maggior parte del
software che lavora con numeri floating point, per tale ragione e stato ritenuto
non necessaria la sua implementazione in EduMIPS64.
3.2.4 Arrotondamenti
Le rappresentazioni floating point hanno una base β e una precisione p. Se
β = 10 e p = 3 il numero 0.1 verrebbe rappresentato come 1.00× 10−1. Se β = 2
e p = 24 lo stesso numero non puo essere rappresentato esattamente, ma in modo
approssimato (1.10011001100110011001101 × 2−4), dove per approssimazione si
intende una funzione che dipende dalla modalita di arrotondamento e dalle cifre
successive alla p-esima della mantissa.
Lo standard IEEE 754 prevede 4 modalita di arrotondamento (Hp:β = 10, p = 1):
- Al piu vicino: arrotonda al piu vicino valore rappresentabile. Se la distanza
da due valori rappresentabili e la stessa, il risultato e arrotondato a quello
pari (2.6 ∼= 3, 3.4 ∼= 3, 4.5 ∼= 4, 5.5 ∼= 6).
- Verso lo zero: arrotonda al numero, preso in valore assoluto, piu vicino
allo zero; cio equivale a troncarne la parte decimale (−3.9 ∼= −3,−3.1 ∼=−3, 4.1 ∼= 4, 4.9 ∼= 4)
- Verso l’infinito positivo: arrotonda al valore rappresentabile piu vicino ma
non piu piccolo del numero da arrotondare (−2.8 ∼= −2,−2.1 ∼= −2, 6.1 ∼=7, 6.9 ∼= 7).
- Verso l’infinito negativo: arrotonda al valore rappresentabile piu vicino ma
non piu grande del numero da arrotondare (−2.8 ∼= −3,−2.1 ∼= −3, 6.1 ∼=6, 6.9 ∼= 6)
30
CAPITOLO 3. LA FLOATING POINT UNIT DEI PROCESSORI MIPS64
3.2.5 Operazioni floating point
Le operazioni possono essere eseguite soltanto fra numeri floating point dello
stesso tipo, altrimenti il risultato e UNPREDICTABLE. Supponiamo di rappre-
sentare il generico numero floating point in base 2 con la notazione
Fi = (−1)Si · 1.f · 2Ei−bias
dove Si e il segno del numero floating point, f e la parte decimale (fraction)
della mantissa Mi, ed Ei = Esigni + bias e l’esponente polarizzato. Si noti che
Esigni e l’esponente naturale (con segno). Infine sia p il numero di bit necessario
a rappresentare la mantissa, compreso il bit nascosto.
Moltiplicazione
Si vuole calcolare il prodotto
F3 = F1 × F2 = (−1)S1 · (−1)S2 · (M1 ·M2)× 2E1+E2−bias
Si calcola E3 sommando gli esponenti polarizzati E1 ed E2, si sottrae successiva-
mente la costante di polarizzazione (per i single 127, per i double 1023). Ci si puo
convincere di tale operazione in quanto
E3 = Esign3 + bias = Esign
1 +Esign2 + bias = Esign
1 + bias+Esign2 + bias− bias = E1 +E2− bias
Se i segni S1 ed S2 concordano allora S3 e positivo, altrimenti e negativo. Si
moltiplicano le due mantisse M1 ed M2, ottenendo una mantissa di 2p bit che
dovra essere arrotondata a p bit.
Si normalizza il prodotto se il bit piu significativo (carry out bit o Cout) e 1,
ovvero si sposta la virgola a sinistra6 incrementando l’esponente. Si valuta dunque
se si e verificata una condizione di eccezione.
6Cio equivale a traslare i bit a destra (right shift)
31
CAPITOLO 3. LA FLOATING POINT UNIT DEI PROCESSORI MIPS64
Si arrotonda il prodotto se l’espressione logica R(M0+S) e vera, dove M0 ed R
rappresentano il p−esimo e il (p+1)esimo bit del prodotto normalizzato partendo
dall’estrema sinistra della mantissa, e il bit S (sticky) e la somma logica di tutti
i bit alla destra di R. Se la condizione di arrotondamento e vera, viene aggiunto
1 al p−esimo bit del prodotto normalizzato. In quest’ultimo caso, se i bit piu
significativi sono pari a 1, l’arrotondamento puo generare un riporto, quindi si
deve rifare la normalizzazione.
Figura 3.3: Mantisse prima della moltiplicazione
Figura 3.4: Risultato del prodotto fra le mantisse prima della normalizzazione
Figura 3.5: Prodotto normalizzato prima dell’arrotondamento
Addizione o sottrazione
Si effettua il confronto degli esponenti e se ne calcola il valore assoluto della
differenza. Si tiene conto che l’esponente piu grande e quello piu probabile per il
risultato.
32
CAPITOLO 3. LA FLOATING POINT UNIT DEI PROCESSORI MIPS64
Si sposta il punto decimale della mantissa del numero col minore esponente di
un numero di posti pari alla differenza tra i due esponenti. Due dei bit traslati e
non piu visibili della mantissa allineata vengono chiamati guardia (G) e round (R).
Cosı per mantisse di p bit, l’effettiva grandezza delle mantisse allineate dev’essere
p + 2 bit. Si aggiunge un terzo bit chiamato sticky (S) all’estrema destra della
mantissa allineata; questo bit e dato dalla somma logica di tutti i bit alla destra
di R.
Si sommano (sottraggono per la sottrazione) le due mantisse usando un som-
matore di p + 3 bit. Si chiami il risultato di tale operazione SOMMA.
Si controlla il bit piu significativo di SOMMA per un eventuale riporto durante
l’addizione. In questo caso, si sposta la virgola di SOMMA incrementando l’espo-
nente di 1. Per la sottrazione si deve controllare se ci sono zeri non significativi
alla sinistra del bit piu significativo, in questo caso si deve traslare SOMMA verso
sinistra fino a che il bit piu significativo del risultato e 1, sottraendo il relativo
valore dall’esponente. Si valutano le condizioni di eccezione.
Si arrotonda il risultato se la condizione logica R(M0 + S) e vera, dove le tre
variabili hanno lo stesso significato illustrato per la moltiplicazione. Nel caso in
cui i p bit piu significativi fossero 1 si ha lo stesso epilogo della moltiplicazione.
Figura 3.6: Mantisse prima dell’addizione
33
CAPITOLO 3. LA FLOATING POINT UNIT DEI PROCESSORI MIPS64
Figura 3.7: Risultato della somma delle mantisse prima della normalizzazione
Figura 3.8: Mantissa normalizzata prima dell’arrotondamento
3.3 Floating point unit e standard IEEE 754
L’implementazione dello standard IEEE 754 nelle architetture di CPU presenta
due grosse problematiche.
La prima e che il pipelining diventa molto difficoltoso dal momento che de-
vono essere intercettati i risultati ”eccezionali”. Nel normale funzionamento di
una CPU, quando si verifica una condizione di eccezione IEEE vengono prodotti
i relativi risultati speciali, o eventualmente si puo verificare una trap; successi-
vamente e richiesto che tutte le istruzioni precedenti a quella che ha provocato
l’eccezione forniscano i risultati, e che tutte le istruzioni successive eseguano come
se niente fosse accaduto. Tali requisiti pongono un limite all’implementazione
dell’ILP per le istruzioni floating point, e cio e dovuto al fatto che esse non pos-
sono affrontare lo stadio di esecuzione in un solo ciclo di clock. Quindi prima di
eseguirne una si deve essere a conoscenza del fatto che essa non provochera un’ec-
cezione, nel caso contrario i risultati di un’altra istruzione, che nel frattempo ha
iniziato o sta finendo di usare una qualunque unita funzionale, verrebbero corrotti.
In fase di fetch degli operandi, l’istruzione che provochera l’eccezione dev’essere
fermata finche il conflitto termina. Per risolvere tale inconveniente l’ISA MIPS
34
CAPITOLO 3. LA FLOATING POINT UNIT DEI PROCESSORI MIPS64
IV introduce un meccanismo di ”rilassamento” delle eccezioni sincrone. Cio rende
il modello computazionale non completamente compatibile con i dettami dello
standard.
La seconda problematica e dovuta al fatto che i risultati eccezionali possono
essere riutilizzati come operandi. Le floating point unit MIPS hanno grossi pro-
blemi a gestire questi valori in quanto esse sono costituite da una componente di
hardware che gestisce la maggior parte delle operazioni, e soltanto nei pochi casi
in cui essa fallisce interviene il software. Quest’ultimo viene richiamato mediante
un’eccezione non IEEE chiamata unimplemented operation, dopodiche il codice
dell’eccezione passa ad un relativo gestore per le applicazioni floating point. Nella
maggior parte dei casi, l’eccezione unimplemented operation si ha al verificarsi di
un’eccezione IEEE.
3.4 Registri floating point
Le CPU MIPS64, oltre ad essere dotate di 32 registri general-purpose, possiedono
32 registri floating point (FPR) da 64 bit ciascuno, i cui nomi vanno da F0 a F31.
Ogni registro puo memorizzare numeri sia in formato single, occupando i 32 bit
piu bassi, che numeri double usando l’intero registro. Un’ulteriore tipologia di
dati memorizzati e chiamata paired-single, costituita da due single affiancati in un
unico registro.
3.4.1 FCSR
Come gia accennato nel Paragrafo 3.2.3, i processori MIPS64 sono dotati di
uno speciale registro chiamato FCSR(Floating Point Control and Status Register)
di 32 bit che controlla le operazioni della floating point unit.
35
CAPITOLO 3. LA FLOATING POINT UNIT DEI PROCESSORI MIPS64
Il registro FCSR ha le seguenti funzioni: seleziona la modalita di arrotonda-
mento, abilita le trap per le eccezioni IEEE, riporta qualunque eccezione IEEE si
sia verificata durante l’esecuzione delle ultime istruzioni e indica i risultati delle
istruzioni di confronto.
Figura 3.9: Registro FCSR
Di seguito sono elencate le funzioni dei singoli campi di questo registro:
FCC : Codici condizionali floating point. Essi memorizzano il risultato delle
istruzioni di confronto (per esempio C.LT.D) e vengono verificati dalle istruzioni di
branch (per esempio BC1F) e da quelle di spostamento condizionale (per esempio
MOVT). Si veda il Paragrafo A.6 per comprenderne l’utilizzo con queste istruzioni.
FS(Flush to Zero): Quando vale uno, i risultati denormalizzati vengono ”por-
tati a zero” invece di essere rappresentati con la relativa notazione speciale.
Impl : Disponibile per funzionalita aggiuntive della floating point unit.
0 : Riservato per utilizzi futuri. Non presente in EduMIPS64.
Cause: Bit di causa. Indicano se durante l’esecuzione dell’ultima istruzione
si e verificata una condizione di eccezione IEEE. Tali bit vengono scritti per ogni
operazione floating point appena eseguita. Il bit relativo all’eccezione viene posto
a uno se si e verificata quella condizione di eccezione, avviando, se abilitata, la trap
corrispondente. Il bit viene posto a zero se non c’e alcuna condizione di eccezione.
Se si e verificata una trap, prima di continuare l’esecuzione del programma, si
deve riportare a zero il relativo bit. I nomi mnemonici dei bit, usati anche per i
36
CAPITOLO 3. LA FLOATING POINT UNIT DEI PROCESSORI MIPS64
campi Enables e Flags, sono i seguenti: V (Operazione non valida), Z (Divisione
per zero), O (Overflow), U (Underflow), I (Inexact).
Enables : Bit di abilitazione trap. Gestiscono l’attivazione o la disattivazione
delle trap relative alle condizioni di eccezione IEEE. La trap si verifica solo se
entrambi i bit del campo Cause e del campo Enables appartenenti alla stessa
eccezione sono posti a uno.
Flags : Bit di eccezione mascherata. Questo campo mostra le condizioni di
eccezione che si sono verificate per le istruzioni completate. I bit vengono posti a
uno solo quando si e appena verificata una condizione di eccezione IEEE, ma non
si e avuta alcuna trap in quanto questa era disabilitata dal campo Enables.
RM :Modalita di arrotondamento. I due bit di questo campo vengono usati per
definire quale delle quattro modalita di arrotondamento, viste nel Paragrafo 3.2.4,
e usata, codificandola con un numero da 0 a 3.
Riassumendo l’attivita di gestione delle eccezioni di una cpu MIPS64, al verifi-
carsi di una condizione di eccezione IEEE vengono attivati i relativi bit del campo
Cause. Si effettua il controllo del campo Enables; se il bit dell’eccezione e attivo
si disabilita nuovamente il bit del campo Cause e si ha una trap, se al contrario il
bit dell’eccezione non e attivo si disabilita nuovamente il bit del campo Cause, e
si pone a 1 il bit del campo Flag in quanto non si ha la trap. Per ulteriori dettagli
sul registro FCSR consultare [7].
3.4.2 Altri registri
Esistono altri registri che costituiscono un’alternativa al registro FCSR. Tut-
tavia non e stata ritenuta necessaria la loro presenza nel simulatore.
- FCCR (Floating point Condition Code Register): e un modo alternativo per
37
CAPITOLO 3. LA FLOATING POINT UNIT DEI PROCESSORI MIPS64
leggere e scrivere i codici condizionali che appaiono nel registro FCSR.
- FEXR (Floating point Exceptions Register): e un registro in cui compaiono
soltanto i campi Cause e Flags del registro FCSR.
- FENR(Floating point ENables Register): presenta le flag di abilitazione delle
trap relative alle eccezioni IEEE, il campo FS e quello per impostare gli
arrotondamenti.
3.5 Instruction set
Le istruzioni dell’ISA MIPS64 possono essere raggruppate secondo i sei grup-
pi funzionali elencati di seguito. Per ragioni di brevita, verranno menzionate
soltanto le istruzioni implementate in EduMIPS64, i cui dettagli progettuali sono
approfonditi nel Paragrafo 4.3. Per un elenco completo consultare [8].
3.5.1 Trasferimento dati
L’architettura della FPU e anch’essa load/store, ovvero tutti i calcoli vengono
eseguiti sui valori presenti nei registri. I dati sono trasferiti senza che ne venga
effettuato alcun controllo di formato, per cui non e possibile alcuna eccezione
IEEE. Si hanno diversi tipi di trasferimento: dagli FPR alla memoria, e viceversa,
vengono trasferite solo word e doubleword. Lo stesso vale anche per i trasferimenti
tra gli FPR e i GPR, mentre per i trasferimenti tra i registri di controllo della
FPU (per esempio l’FCSR) e i GPR sono implicate soltanto word. Come per
le istruzioni intere di caricamento, anche quelle floating point devono riferirsi a
dati ”naturalmente allineati”, altrimenti si verifica l’eccezione Address Error. La
FPU, oltre ad utilizzare l’indirizzamento register+offset visto nel Paragrafo 2.4,
puo utilizzare anche una modalita diversa chiamata register+register.
38
CAPITOLO 3. LA FLOATING POINT UNIT DEI PROCESSORI MIPS64
Nome Descrizione
LDC1 Carica una cella di memoria (doubleword) in un FPRLWC1 Carica una semicella (word) di memoria in un FPRSDC1 Memorizza una doubleword da un FPR alla memoriaSWC1 Memorizza una word da un FPR alla memoriaDMFC1 Copia una doubleword da un FPR ad un GPRDMTC1 Copia una doubleword da un GPR ad un FPRMFC1 Copia una word da un FPR ad un GPRMTC1 Copia una word da un GPR ad un FPR
Tabella 3.4: Istruzioni di trasferimento dati
3.5.2 Aritmetiche
Operano su unita dati formattate, e i risultati della maggior parte delle opera-
zioni floating point e soggetta al rispetto dello standard IEEE 754. I calcoli sono
eseguiti con precisione infinita, e successivamente i risultati vengono arrotondati
al formato specificato usando la modalita di arrotondamento corrente.
Nome Descrizione
ADD.D Addizione doubleDIV.D Divisione doubleMUL.D Moltiplicazione doubleSUB.D Sottrazione doubleC.cond.D Verifica il predicato cond tra due FPR
Tabella 3.5: Istruzioni aritmetiche
3.5.3 Conversione
Eseguono conversioni da numeri in virgola mobile a numeri in virgola fissa
e viceversa. Ciascuna istruzione converte valori da uno specifico formato ad un
altro (per esempio CVT.L.D converte un double in un long). Alcune istruzioni con-
sentono di specificare la modalita di arrotondamento da utilizzare, altre prelevano
tale informazione dal registro FCSR.
39
CAPITOLO 3. LA FLOATING POINT UNIT DEI PROCESSORI MIPS64
Nome Descrizione
CVT.D.formato Converte numeri a virgola fissa in double(formato ∈ {L,W}, L = Long, W = int)
CVT.L.D Converte un double in un longCVT.W.D Converte un double in un int
Tabella 3.6: Istruzioni di conversione
3.5.4 Spostamento operandi formattati
Copiano valori tra gli FPR. Alcune istruzioni di questa categoria ( spostamento
condizionale) effettuano la copia verificando prima una condizione (zero di un
registro, condizione booleana); altre la effettuano in modo incondizionato. Nessun
controllo viene eseguito sul formato del registro sorgente, che puo quindi non essere
formattato secondo uno dei tipi floating point.
Nome Descrizione
MOV.D Sposta valori double tra FPRMOVF.D Sposta valori double se il codice condizionale e veroMOVT.D Sposta valori double se il codice condizionale e falsoMOVN.D Sposta valori double tra FPR se un GPR e diverso da 0MOVZ.D Sposta valori double tra FPR se un GPR e uguale a 0
Tabella 3.7: Istruzioni di spostamento degli operandi formattati
3.5.5 Salto condizionale
Anche la FPU e dotata di istruzioni che effettuano salti PC-relative (si veda
il Paragrafo 2.5.1) dopo aver verificato i codici condizionali del registro FCSR.
Nome Descrizione
BC1F Salta se il codice condizionale dell’FCSR e falso(FCSR(cc) = falso, cc ∈ [0, 7])
BC1T Salta se il codice condizionale dell’FCSR e vero
Tabella 3.8: Istruzioni di salto condizionale
40
CAPITOLO 3. LA FLOATING POINT UNIT DEI PROCESSORI MIPS64
3.6 Pipelining
Nella Figura 3.10 e illustrata la struttura di una pipeline a 5 stadi che suppor-
ta il pipelining delle istruzioni floating point. Il moltiplicatore (M) e l’addiziona-
tore (A) floating point sono ”fully pipelined” poiche possono praticare l’ILP sulle
istruzioni che li occupano; queste unita funzionali hanno una latenza rispettiva-
mente di 7 e 4 stadi. Il divisore (DIV) non esegue il pipelining, ma necessita
comunque di 24 cicli per completare il calcolo.
A causa della diramazione nello stadio ID, occorre realizzare connessioni sepa-
rate con gli stadi EX,A1,M1 e DIV; per cui si utilizzano i pipeline registers ID/EX,
ID/A1, ID/M1 e ID/DIV. Come accennato nel Paragrafo 3.3, l’ILP delle istruzioni
Figura 3.10: Pipeline a 5 stadi
floating point e difficile da realizzare; si possono verificare stalli strutturali perche
le unita funzionali che non effettuano il pipelining (divisore) potrebbero non essere
disponibili, o anche per altri motivi illustrati nel paragrafo 3.6.1. Inoltre, poiche
le istruzioni floating point hanno un tempo di esecuzione differente, lo stadio WB
41
CAPITOLO 3. LA FLOATING POINT UNIT DEI PROCESSORI MIPS64
potrebbe essere raggiunto in modo disordinato rispetto al flusso di esecuzione;
sono possibili quindi dipendenze di output con successivi stalli WAW. Il numero
di stalli RAW, infine, e considerevole per via della lunga latenza delle operazioni
floating point.
3.6.1 Concorrenza sul register file
Il register file di un processore MIPS64, illustrato nella Figura 3.11, comprende
il set di 32 registri da 64 bit e la logica che controlla le operazioni di scrittura e
lettura. Ipotizzando che esso abbia solamente una porta di scrittura, le operazioni
floating point che scrivono su un registro nello stesso ciclo di clock andranno in
conflitto. Aumentare il numero di porte di scrittura non e una soluzione adeguata
perche esse sarebbero raramente utilizzate. Il problema viene risolto in due modi
differenti: il primo e quello di prevedere, nello stadio ID, se si verifichera un
conflitto di questo tipo, ed eventualmente fermare un’istruzione nel secondo stadio
della pipeline. Il vantaggio e aver seguito il principio secondo cui tutti gli hazard
devono essere prevenuti nello stadio ID. Lo svantaggio e l’utilizzo di uno shift
register e della logica di controllo dei conflitti sul register file.
Figura 3.11: Register file di un processore MIPS64
42
CAPITOLO 3. LA FLOATING POINT UNIT DEI PROCESSORI MIPS64
Il secondo metodo consiste nell’inserire uno stallo quando le istruzioni in con-
flitto accedono allo stadio MEM o WB. Generalmente viene data maggiore prior-
ita all’istruzione che ha latenza maggiore; l’ordine di priorita e dunque divisione,
moltiplicazione, addizione/sottrazione e istruzione intera. Il vantaggio e la facilita
di verificare l’hazard strutturale direttamente all’uscita dello stadio di esecuzione,
e di concedere l’ingresso allo stadio successivo solo all’istruzione con maggiore
priorita. Lo svantaggio e introdurre una maggiore complessita nel controllo della
pipeline, questo perche gli hazard strutturali possono ora verificarsi in due punti
differenti di essa. La complicazione e dovuta al fatto che, fermando le istruzioni
che occupano gli stadi EX,M7 o A4, si devono fermare anche quelle che le seguono.
3.6.2 Rilevamento degli hazard
Se la pipeline rileva gli hazard nello stadio ID, prima che un’istruzione possa
essere ”emessa”, devono essere eseguiti dei controlli sui tre hazard che possono
verificarsi:
- Hazard strutturali: non considerando il caso di stallo strutturale visto nel
paragrafo precedente, l’unico altro caso che si possa verificare riguarda il
divisore. Prima di fare avanzare una divisione, si deve attendere che questa
unita funzionale non sia occupata, e la porta di scrittura del registro di
destinazione disponibile quando richiesto.
- Hazard RAW: si deve attendere affinche i registri sorgenti dell’istruzione
diventino validi.
- Hazard WAW: si deve attendere affinche il registro di destinazione venga
scritto da un’altra istruzione che sta ancora affrontando gli stadi A1..A4 e
M1..M7.
43
CAPITOLO 3. LA FLOATING POINT UNIT DEI PROCESSORI MIPS64
3.6.3 Pipeline FP del MIPS R4000
Il processore R4000 implementa l’ISA MIPS64, ma non usa una pipeline a 5
stadi, bensı a 8. Gli stadi supplementari, oltre a permettere frequenze di clock
elevate, servono a ”spalmare” su due cicli la lentezza nell’accesso alla cache; questa
strategia, usata nelle moderne pipeline, e chiamata superpipelining.
La FPU e composta dalle tre unita funzionali illustrate nella Figura 3.10.
L’addizionatore, oltre ad essere impiegato per le somme e le sottrazioni, e usato
nello stadio finale di moltiplicazione e divisione.
La generica unita funzionale puo eseguire una varieta di 8 operazioni primitive,
le quali vengono combinate in vari modi per realizzare le operazioni floating point.
Nella tabella 3.11 sono illustrate le fasi del pipelining di una MUL.D seguita da
una ADD.D.
Si supponga che le due istruzioni non presentino alcuna dipendenza; nonos-
tante cio, la moltiplicazione, nel suo settimo stadio di esecuzione (N+A), che
avviene nel ciclo 6, usa l’addizionatore. La ADD.D, dovendo anch’essa farne uso
(stadi A+R ed S+A), deve attendere per due cicli fino a che la MUL.D abbia
terminato anche lo stadio R.
44
CAPITOLO 3. LA FLOATING POINT UNIT DEI PROCESSORI MIPS64
Stadio Unita funzionale Descrizione
A Addizionatore Somma delle mantisseD Divisore Divisione FPE Moltiplicatore Test delle eccezioniM Moltiplicatore Primo stadio moltiplicazioneN Moltiplicatore Secondo stadio moltiplicazioneR Addizionatore ArrotondamentoS Addizionatore Shift degli operandiU ”Spacchettamento” numeri FP
Tabella 3.9: Operazioni primitive della pipeline FP dell’R4000
Istruzione FP Latenza (cicli) Stadi pipeline
Addizione, sottrazione 4 U, S+A, A+R, R+SMoltiplicazione 8 U, E+M,M,M,M,N,N+A,RDivisione 36 U, A,R,D27,D+A,D+R,D+A,D+R,A,RConfronto 3 U,A,R
Tabella 3.10: Operazioni FP dell’R4000
Istr. Stato 0 1 2 3 4 5 6 7 8
MUL.DEsec. U E+M M M M N N+A RADD.DEsec. U S+A A+R R+S
Esec. U S+A A+R R+SEsec. U S+A A+R R+SStallo U S+A A+R R+SStallo U S+A A+R R+S
Tabella 3.11: Stalli nelle unita funzionali
45
Capitolo 4
La floating point unit diEduMIPS64
In questo capitolo vengono illustrate le scelte progettuali nella costruzione di
un modello ad oggetti che simuli le dinamiche della floating point unit di un’ar-
chitettura MIPS64. Nel paragrafo 4.1 viene introdotto il gruppo computazionale
floating point, comprendente le funzioni primitive che eseguono le quattro opera-
zioni fondamentali e gli oggetti che modellano il luogo in cui esse avvengono: le
unita funzionali della FPU. Nel Paragrafo 4.2 si parla delle classi che modellano
i registri floating point e l’FCSR. Nel Paragrafo 4.3 viene illustrata l’estensione
dell’istruction set, implementata in EduMIPS64, con le istruzioni floating point e i
relativi dettagli progettuali. Infine, nel Paragrafo 4.4, si parla della pipeline float-
ing point di EduMIPS64, e come questa interagisce con la pipeline gia esistente
nel formare un’unica pipeline.
4.1 Operazioni floating point
In EduMIPS64 e stato ritenuto necessario, per esigenze di ottimizzazione nel-
l’esecuzione delle quattro operazioni fondamentali floating point, l’utilizzo di classi
46
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
presenti nel Java Runtime Environment 1.5.
In particolare, si e evitato lo stretto accoppiamento tra il tipo di dato piu
grande utilizzato nel simulatore (double), e la classe che lo modella (Double).
Si usa, al contrario, la classe BigDecimal, che permette di rappresentare numeri
decimali con segno a precisione arbitraria, e di scegliere la modalita di arrotonda-
mento mediante l’ausilio della classe MathContext ; fornisce, inoltre, metodi che
eseguono le quattro operazioni fondamentali su due oggetti BigDecimal.
Nonostante queste grosse potenzialita, la classe BigDecimal presenta delle li-
mitazioni: essa non e conforme, per due motivi, ai requisiti richiesti per la proget-
tazione di un modello computazionale floating point da integrare nel simulatore.
1. Il costruttore BigDecimal (double val) genera l’eccezione NumberFor-
matException, restituendo il messaggio di uscita
java.lang.NumberFormatException: Infinite or NaN
sia che ad esso si passi un qualunque infinito (es. Double.POSITIVE INFINITY),
sia un NaN (Double.NaN). Questo fatto, oltre a rendere praticamente in-
distinguibili i valori speciali infinito positivo, infinito negativo, QNaN ed
SNaN, fa dedurre che non e possibile creare un oggetto BigDecimal che
rappresenti tutti i valori speciali IEEE.
2. La classe Double non presenta attributi statici che rappresentano gli zeri.
Non essendo possibile distinguere uno zero positivo da uno negativo, non lo
e neanche creare un oggetto BigDecimal che lo rappresenti.
A causa dell’inefficienza delle due classi Double e BigDecimal, nelle routine
delle operazioni e stato implementato uno strato funzionale intermedio. Esso si
47
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
occupa di intercettare gli eventuali valori speciali degli operandi ed eventualmente
restituire il relativo risultato ”speciale”; il gestore delle eccezioni sincrone inter-
viene solo se, per una certa eccezione IEEE, e attivata la relativa trap. Della classe
BigDecimal vengono usati, quindi, soltanto i metodi che eseguono le operazioni.
Al contrario delle architetture reali, in cui lo stadio di esecuzione delle istruzioni
floating point non puo essere concluso in un solo ciclo di clock, in EduMIPS64 le
quattro operazioni floating point vengono eseguite in un’unica chiamata di proce-
dura, anche se viene simulata la latenza dovuta al pipelining delle istruzioni nelle
unita funzionali.
Ogni istruzione aritmetica FP, quando giunge nell’unita funzionale che le com-
pete, usufruisce dei metodi statici offerti dalla classe FPInstructionUtils. Inizial-
mente, il metodo EX dell’istruzione invoca il metodo specifico dell’operazione
aritmetica da eseguire, passando a quest’ultimo il valore binario dei due registri
con gli operandi (per esempio doubleSum(F1,F2)); dopo il controllo degli operan-
di, se il metodo invocato non ha ceduto il controllo al gestore delle eccezioni1, ne
ha prodotto e ritornato alcun valore speciale, passa il risultato decimale dell’oper-
azione al metodo doubleToBin(), che lo converte in binario secondo lo standard
IEEE 754 e lo ritorna al chiamante (il metodo EX dell’istruzione FP).
4.1.1 Gestore delle eccezioni sincrone
I metodi statici della classe FPInstructionUtils eseguono le quattro operazio-
ni floating point fondamentali. Essi, in determinate circostanze, terminano in
anticipo l’esecuzione perche e stato generato un valore speciale oppure perche si
1Trasferire il controllo al gestore delle eccezioni significa lanciare un’eccezione sincrona nelmetodo; essa viene poi catturata dalla CPU e gestita opportunamente (visualizzazione graficadel messaggio di eccezione)
48
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
deve passare il controllo al gestore delle eccezioni sincrone; quest’ultimo e stato
sviluppato in un precedente lavoro di tesi.
Le eccezioni previste dallo standard IEEE 754, e viste nel Paragrafo 3.2.3,
sono implementate in EduMIPS64 estendendo la classe SynchronousException.
Le 4 nuove eccezioni java che modellano quelle IEEE (escludendo l’eccezione
non implementata Inexact) sono: FPOverflowException, FPUnderflowException,
FPInvalidOperationException, FPDivideByZeroException.
4.1.2 Addizione
La somma tra due numeri floating point viene realizzata, come accennato in
precedenza, chiamando il metodo statico doubleSum() che, a sua volta, si serve
del metodo doubleToBin() per ritornare il risultato binario della somma. Per
evitare ripetizioni, si omettera la descrizione della sottrazione; essa viene esegui-
ta dal metodo statico doubleSubtraction() e presenta le stesse problematiche
dell’addizione. Il metodo doubleSum() esegue queste operazioni:
- Verifica se le stringhe binarie degli operandi passati corrispondono ai pat-
tern di QNaN ed SNaN. In questo caso viene attivato il bit di causa V del
registro FCSR e, se la trap per l’eccezione Invalid Operation e attivata, si
passa il controllo al gestore delle eccezioni sincrone, lanciando l’eccezione
FPInvalidOperationException. Nel caso opposto viene generato e ritornato
al metodo chiamante (EX() dell’istruzione di somma) un QNaN che verra
memorizzato nel registro di destinazione.
- Verifica se gli operandi sono due infiniti di segno opposto, eventualmente si
agisce con l’eccezione Invalid Operation, come visto in precedenza.
49
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
- Verifica se uno dei due operandi e infinito e l’altro diverso da un XNaN, in
questo caso viene ritornato alla funzione chiamante un infinito con un segno
opportuno.
- Viene eseguita la somma col metodo BigDecimal::add() e il risultato deci-
male ottenuto viene passato al metodo FPInstructionUtils::doubleToBin()
- Il metodo doubleToBin() verifica che il numero decimale possa essere rap-
presentato in double; vengono dunque effettuati i controlli di underflow ed
overflow. Se si ha una condizione di overflow, puo essere ritornato un oppor-
tuno infinito (trap disattivate) o generata l’eccezione FPOverflowException.
La stessa cosa avviene per l’underflow, (FPUnderflowException) con la sola
differenza che i numeri eventualmente ritornati sono zeri positivi o negativi.
Figura 4.1: Sommatore floating point (R1+R2=R3)
4.1.3 Moltiplicazione
Il prodotto fra due numeri floating point e realizzato mediante l’invocazione
del metodo doubleMultiplication(). Esso accetta, analogamente al metodo
doubleSum(), i valori binari dei registri con gli operandi, passando il risultato
50
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
decimale al metodo doubleToBin(); questo provvede a ritornare una stringa bi-
naria pronta ad essere memorizzata. Il metodo doubleMultiplication() effettua
le seguenti operazioni:
- Verifica se le stringhe binarie degli operandi passati corrispondono ai pattern
di QNaN ed SNaN. E procede nel modo illustrato per l’addizione.
- Verifica se gli operandi sono uno zero e un infinito, agendo, eventualmente,
con l’eccezione Invalid Operation vista in precedenza.
- Verifica se uno dei due operandi e infinito e l’altro diverso da un XNaN, in
questo caso viene ritornato alla funzione chiamante un infinito con un segno
opportuno.
- Verifica se entrambi gli operandi sono zeri e ne effettua il prodotto dei segni
ritornando un opportuno zero.
- Viene eseguito il prodotto col metodo BigDecimal::multiply() e il risul-
tato viene passato al metodo FPInstructionUtils::doubleToBin() .
- Il metodo doubleToBin() agisce come spiegato per l’addizione.
Nella Figura 4.2 e illustrato il blocco relativo al prodotto, da sostituire nella
Figura 4.1
4.1.4 Divisione
La divisione fra due numeri floating point e realizzata mediante l’invocazione
del metodo doubleDivision(). Esso esegue le seguenti operazioni:
- Verifica i pattern XNaN, il rapporto tra infiniti, e il rapporto tra zeri.
Procede come spiegato al primo punto dell’addizione.
51
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
Figura 4.2: Moltiplicatore floating point
- Verifica se il dividendo e un qualunque zero e il divisore un valore diverso
da un XNaN, fornendo un opportuno zero come valore di ritorno.
- Verifica se il divisore e un qualunque zero e fornisce un opportuno infinito op-
pure, se attivata, la trap dell’eccezione Divide by zero(FPDivideByZeroException).
- Verifica se il dividendo e un infinito e, escludendo il caso del primo punto,
fornisce un opportuno infinito
- Viene eseguito il prodotto col metodo BigDecimal::divide() e il risultato
e passato al metodo doubleToBin() che agisce nel modo spiegato prima.
Figura 4.3: Divisore floating point
52
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
4.2 Registri
I register file della CPU e della FPU, visti nel Paragrafo 3.6.1, sono modellati,
in EduMIPS64, da vettori di 32 oggetti istanziati dalle classi Register e Regis-
terFP ; una serie di metodi presenti nella classe CPU (es. getRegisterFP())
simula, invece, la logica di controllo per la lettura e la scrittura dei singoli registri.
I registri floating point utilizzano la stessa classe base di quelli general-purpose
(FixedBitset2); da questa si ereditano le classi BitSet64FP e RegisterFP, come
illustrato nella Figura 4.4. Entrambe le classi Register ed FPRegister sono dotate
di due semafori: il primo e di scrittura e simula l’abilitatore della porta di scrit-
tura del register file3. Durante la decodifica, ogni istruzione che, nello stadio WB,
scrivera il registro deve incrementare il valore di tale semaforo, consentendo di
rilevare e prevenire l’hazard per le istruzioni che eseguiranno la stessa operazione.
Il secondo semaforo (di WAW) serve, invece, ad anticipare lo sblocco di un registro
per evitare che cio avvenga nello stadio WB; questo argomento verra approfondito
nel Paragrafo 4.3.
4.2.1 FCSR
Il registro FCSR e rappresentato dalla classe FCSRRegister, che estende la
classe BitSet32 e costutuisce un membro privato della classe CPU. Le scritture
e le letture di tale registro passano sempre per la classe CPU; se esse vengono
effettuate dal suo interno, si accede direttamente al membro, altrimenti CPU
fornisce l’interfaccia di accesso esclusivamente ad un numero ridotto di metodi
2Questa classe e usata per modellare un set di bit affiancati il cui numero e specificato dallaclasse che la estende
3A differenza di un’architettura reale, dove per la porta di scrittura passano tutti i dati scrittinel banco di registri, nel simulatore ogni scrittura viene eseguita mediante un metodo della cpuche aggiorna il vettore dei registri
53
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
Figura 4.4: Diagramma delle classi dei registri di EduMIPS64
Figura 4.5: Modalita di accesso alla classe FCSRRegister
(si veda la Figura 4.5). I metodi del tipo setFCSRnomecampo richiedono, come
parametri, una stringa denominata tag, che rappresenta il nome mnemonico del
bit da modificare (V,Z,O,U,I), e il valore binario da assegnare al bit.
Dopo la descrizione di questo registro, fatta nel Paragrafo 3.4.1, si vedranno
ora i dettagli implementativi dei singoli campi in EduMIPS64. Di seguito vengono
riportati soltanto i campi presenti nel simulatore.
FCC : Codici condizionali floating point. Le istruzioni di confronto, illustrate
nel Paragrafo A.6, utilizzano come parametro un immediato di 3 bit; questo
54
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
permette di descrivere 8 possibili destinazioni, nel registro FCSR, per la memo-
rizzazione del risultato booleano del confronto. Come si e visto nella Figura 3.9,
il campo FCC, per ragione di compatibilita con le vecchie architetture, presenta
un bit di discontinuita occupato dal campo FS. Il metodo che permette di scri-
vere i codici condizionali su questo registro e visto nel Listato 4.1, si tenga in
considerazione che la classe FCSRRegister numera i bit da 0 a 31 partendo dalla
sinistra.
public void setFCSRConditionCode ( int cc , int condition ) {f ina l int FCC0=8;f ina l int DISCONTINUITY=1;f ina l int OFFSET=FCC0−DISCONTINUITY ;i f (cc==0)
setBits ( String . valueOf ( condition ) , FCC0 ) ;else
setBits ( String . valueOf ( condition ) , OFFSET−cc ) ;}
Listato 4.1: Scrittura dei codici condizionali sull’FCSR
Cause: Bit di causa. Il funzionamento di questo campo e molto simile a quello
dell’architettura MIPS64. L’unica differenza sta nel fatto che l’azione di reset del
bit relativo all’eccezione, che avviene subito prima la trap o la scrittura del campo
flag, non viene effettuata. I bit vengono lasciati a 1 per darne visione all’ambiente
”user-mode”, che altrimenti non sarebbe cosciente del cambiamento di tali bit. Il
metodo mediante cui i bit di causa vengono cambiati e visto nel Listato 4.3; ad
esso viene passata una stringa che identifica il nome mnemonico del bit da variare,
e il valore binario che il bit deve assumere. Metodi analoghi vengono usati per
modificare i campi Enables e Flags.
public void setFCSRCause ( String tag , int value ){i f ( tag . compareTo ("V")==0)
setBits ( String . valueOf ( value ) , 1 5 ) ;else i f ( tag . compareTo ("Z")==0)
55
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
setBits ( String . valueOf ( value ) , 1 6 ) ;else i f ( tag . compareTo ("O")==0)
setBits ( String . valueOf ( value ) , 1 7 ) ;else i f ( tag . compareTo ("U")==0)
setBits ( String . valueOf ( value ) , 1 8 ) ;else i f ( tag . compareTo ("I")==0) // non implementata
setBits ( String . valueOf ( value ) , 1 9 ) ;}
Listato 4.2: Scrittura dei bit di causa sull’FCSR
Enables :Bit di abilitazione trap. L’attivazione di questi bit, effettuata con un
metodo simile a quello del listato precedente, e pilotata da una finestra di con-
figurazione nella GUI (Graphic User Interface), che sara vista nel Paragrafo A.3.
Tale finestra si serve del suo file di configurazione (edumips64.conf) per mostrare
all’utente, tra le altre cose, lo stato di attivazione delle trap; per ogni ciclo di
esecuzione, la classe CPU preleva le nuove configurazioni dalla finestra e li scrive
nell’FCSR con il Listato 4.3 della classe FCSRRegister.
public void setFPExceptions ( CPU . FPExceptions exceptionName ,boolean value ){
switch ( exceptionName ){case DIVIDE_BY_ZERO :
setFCSREnables ("Z" , value ? 1 : 0 ) ;break ;
case OVERFLOW :setFCSREnables ("O" , value ? 1 : 0 ) ;break ;
case UNDERFLOW :setFCSREnables ("U" , value ? 1 : 0 ) ;break ;
case INVALID_OPERATION :setFCSREnables ("V" , value ? 1 : 0 ) ;
}}
Listato 4.3: Metodo che memorizza i dati della GUI sull’FCSR
Flags : Bit di eccezione mascherata. Questi bit vengono attivati nello stesso
56
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
modo previsto dall’architettura MIPS64, e vengono posti a zero soltanto con la
funzione di reset della CPU, effettuata per ogni nuovo programma eseguito. Si
noti che in EduMIPS64, dal momento che non e implementata l’eccezione Inexact,
l’attivazione di questi bit e indice della generazione, per via di un’eccezione IEEE
la cui trap era disattivata dal campo Enables, di un valore speciale. E probabile,
dunque, che la computazione portera a risultati non previsti rispetto al normale
flusso di esecuzione del programma.
RM :Modalita di arrotondamento. EduMIPS64 implementa le quattro modalita
di arrotondamento usate nei processori MIPS64. Per eseguire le istruzioni di
conversione da un numero double a uno long (CVT.L.D) viene usato il metodo
FPInstructionUtils::doubleToBigInteger(). Tale metodo permette di tron-
care la parte decimale di un double utilizzando la modalita di arrotondamento
corrente.
4.3 Instruction set
Dopo una breve panoramica su alcune delle istruzioni dell’ISA MIPS64, elen-
cate nel Paragrafo 3.5, si affrontano adesso i dettagli progettuali dell’instruction
set in EduMIPS64.
4.3.1 Classe Instruction
La classe Instruction non e stata sviluppata in questo lavoro di tesi; tuttavia,
per comprendere come la libreria di classi delle istruzioni floating point e usa-
ta dal simulatore, nella Figura 4.6 ne viene proposto il diagramma UML, in
cui sono stati aggiunti solo attributi e metodi piu rilevanti. Il metodo statico
buildInstruction() implementa il design pattern Factory, mediante il quale
57
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
Figura 4.6: Classe Instruction
viene definita l’interfaccia per specificare quale oggetto istruzione istanziare; le
classi invocano, a tal fine, il metodo factory (buildInstruction()), passando ad
esso il nome dell’istruzione.
La classe Parser, responsabile della lettura e dell’interpretazione dei file sorgen-
ti (.s), e maggiore utilizzatrice dell’interfaccia, istanzia inizialmente le istruzioni,
passa loro, col metodo setParams(), i parametri richiesti, e infine le memorizza
in memoria.
La classe CPU utilizza una struttura dati mediante cui simula la pipeline a 5
stadi. Per ogni istruzione passata dalla memoria alla struttura, invoca il metodo
corrispondente allo stadio della pipeline(IF(),ID(),EX(),MEM(),WB()); per tale
ragione ogni istruzione deve fornire tutti i 5 metodi.
4.3.2 Classi base dell’instruction set
Per riutilizzare il codice esistente del simulatore, le nuove classi dell’instruc-
tion set della FPU hanno la stessa radice delle istruzioni intere; per cui ereditano
dalle tre classi base ComputationalInstructions, FlowControlInstructions e LD-
STInstructions. Dalla prima ereditano tutte le classi che modellano le istruzioni
58
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
aritmetiche, di spostamento dati tra registri e condizionali; dalla seconda tutte
le istruzioni che effettuano branch e dalla terza tutte le istruzioni load e store.
Nei paragrafi che seguono saranno omessi tutti i riferimenti alle istruzioni floating
point che manipolano operandi single; il loro sviluppo non e previsto in questo
lavoro di tesi, anche se nei raggruppamenti effettuati esse sono implicitamente
incluse4.
Figura 4.7: Classi base dell’istruction set
4.3.3 Ereditarieta dalla classe ComputationalInstructions
La classe astratta ComputationalInstructions concretizza soltanto il meto-
do IF(); il codice del metodo scrive l’informazione di fetch del sottoinsime di
istruzioni derivate da questa classe sul trace file, che viene successivamente in-
viato al simulatore di cache Dinero. Gli altri quattro metodi restano astratti
perche vengono implementati nelle sottoclassi. Come si vede dalla Figura 4.8,
le classi che ereditano da ComputationalInstructions sono: FPArithmeticInstruc-
tions, FPC cond DInstructions, FPFormattedOperandMoveInstructions, FPCon-
versionFCSRInstructions, FPConditionalCC DMoveInstructions, FPConditionaZe-
rosMoveInstructions e infine FPMoveToAndFromInstructions.
4Sono tutte quelle istruzioni il cui parametro X, visto piu avanti, vale S
59
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
Figura 4.8: Classi ereditate da ComputationalInstructions
FPArithmeticInstructions
Questa classe descrive il modello generale delle istruzioni aritmetiche float-
ing point. Vengono risolte le problematiche dovute alla presenza di due registri
sorgenti che potrebbero non essere da subito validi (devono essere scritti prima
di poter essere letti), e un registro di destinazione che deve essere scritto man-
tenendo l’ordine di esecuzione, non sempre garantito dalle computazioni floating
point. I metodi della classe, tutti implementati tranne EX(), vengono ereditati
dalle istruzioni aritmetiche che la estendono. Si consideri, per fissare le idee,
una generica istruzione in aritmetica double con sintassi ISTR.D fd,fs,ft. Le
operazioni eseguite nel metodo ID() sono le seguenti:
- si verifica se i registri sorgenti fs ed ft sono validi; se il loro semaforo e in-
crementato, si sta verificando una dipendenza dati tra le istruzioni, quindi
si verifica lo stallo RAW; la classe CPU ferma l’istruzione corrente nel-
la pipeline, eseguendo in continuazione il metodo ID() fino a quando la
dipendenza non sara risolta.
- si copiano i valori dei registri sorgenti su due registri ausiliari, affinche i dati
letti nello stadio ID vengano trasmessi da uno stadio all’altro della pipeline.
Questa azione simula il funzionamento dei pipeline registers, illustrati nel
Paragrafo 2.6.1.
60
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
- si verifica se il semaforo di scrittura del registro di destinazione fd e incre-
mentato, in questo caso si sta verificando una dipendenza di output, a cui
seguira lo stallo WAW.
- si incrementa il semaforo di scrittura e di WAW del registro fd
Nel metodo MEM() si e scelto di eseguire il decremento del semaforo di WAW;
questa azione consente alle istruzioni, la cui esecuzione era stata fermata per via
di una dipendenza di output, di proseguire nonostante il registro su cui dovranno
scrivere sia ancora bloccato. Cio e permesso perche le istruzioni a lunga latenza,
cioe quelle ereditate da questa classe, possono scambiarsi l’ordine di esecuzione5
soltanto nelle unita funzionali della floating point; uscendo da esse (stadio MEM),
l’ordine non puo essere piu variato perche il percorso di esecuzione non e piu
multiplo.
Con il metodo WB(), il risultato memorizzato in un registro ausiliario viene
scritto in fd, e il suo semaforo viene decrementato. Infine, con il metodo pack(),
viene generato il codice binario a 32 bit dell’istruzione, a partire dai parametri da
essa gestiti. Per una guida esaustiva sul formato della codifica di ogni istruzione
dell’ISA MIPS64 consultare [8].
Dalla classe FPArithmeticInstructions vengono ereditate le quattro istruzioni
che implementano le operazioni fondamentali:ADD.D, SUB.D, MUL.D e DIV.D, il-
lustrate nel Paragrafo A.6.
FPC cond DInstructions
Da questa classe vengono ereditate le istruzioni condizionali floating point.
A differenza delle istruzioni intere, che si servono dei registri per memorizzare il
5Una divisione FP che occupa il divisore al ciclo n lo lascera al ciclo n+24, mentreun’addizione che occupa l’addizionatore nel ciclo n+1 lo lascera nel ciclo n+5
61
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
valore booleano di un confronto (per esempio SLT), le istruzioni floating point
utilizzano il registro FCSR per tener traccia di questa informazione.
La classe implementa tutti i metodi della classe Instruction. Il metodo ID()
effettua la lettura dei registri sorgenti se questi sono validi, altrimenti lancia l’ec-
cezione RAWException, che causa uno stallo della pipeline. Questa classe e tra le
poche a presentare anche l’implementazione del metodo EX(), che generalmente e
eseguita al livello dell’istruzione. Si e fatta questa scelta perche si usa una funzione
a cui si passano due registri e il predicato da verificare, ottenendone il risultato
booleano; l’istruzione ha solo il compito di specificare quale predicato dev’essere
verificato.
Si supponga di servirsi della terna di flag [less, equal, unordered] per
descrivere un determinato predicato di confronto. Per fissare le idee, il predicato
non ordinato6 o uguale verrebbe indicato con la notazione [falso,vero,vero].
Si supponga, adesso, di caratterizzare ogni istruzione che effettua un confron-
to con una maschera della verita relativa al predicato da verificare; la terna di
flag viene, quindi, codificata in binario in un determinato campo dell’istruzione,
e nel caso specifico il numero memorizzato e 011. Si indichi la generica cifra
di questo numero con la notazione condi, i ∈ [0, 2]. Se si vogliono confrontare
i due registri fs ed ft, si devono valutare i valori booleani delle flag della terna
[less=(fs<ft),equal=(fs==ft),unordered=(unordered(fs,ft))], e successi-
vamente effettuare la ”messa in AND” della terna, in binario, con la maschera
della verita.
Sia isXNaN() una funzione che verifica se un FPR contiene i valori speciali
SNaN o QNaN, cc l’identificativo del bit nel campo FCC del registro FCSR, in
6I valori QNaN ed SNaN non appartengono ad alcuna metrica, quindi non possono essereconfrontati ne tra di essi ne con numeri reali
62
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
cui verra memorizzato il risultato del confronto, e FCSR setFCC() la funzione
che esegue quest’ultima operazione. Nel Listato 4.4 e illustrata una porzione, in
pseudocodice, della funzione di confronto.
i f ( isXNaN ( FPR [ fs ] ) | | isXNaN ( FPR [ ft ] ) )less=fa l seequal=fa l seunordered=true
elseless=(fs<ft )equal=(fs= =ft )unordered=fa l se
end i fcondition=(cond [ 0 ] and less )or ( cond [ 1 ] and equal )
or ( cond [ 2 ] and unordered )FCSR_setFCC (cc , condition )
Listato 4.4: Porzione della funzione che effettua il confronto tra registri
Si e ritenuta sufficiente l’implementazione di solo due istruzioni di confronto:
C.LT.D e C.EQ.D, illustrate nel Paragrafo A.6.
FPFormattedOperandMoveInstructions
Questa classe modella il sottoinsieme di istruzioni per lo spostamento degli
operandi formattati ; esso e costituito dalla sola istruzione MOV.D7, che si occupa
dello spostamento dei dati da un FPR all’altro in modo incondizionato. La sintassi
di questa istruzione e MOV.D fd,fs; il metodo ID() controlla la disponibilita per
la scrittura di fd, facendo fermare l’istruzione nel caso di dipendenze dati o di
output. Gli altri metodi eseguono le solite operazioni.
7Se fossero implementate le istruzioni che manipolano operandi single apparterrebbe a questogruppo anche l’istruzione MOV.S
63
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
FPConversionFCSRInstructions
Le istruzioni di conversione ereditano dalla classe FPConversionFCSRInstruc-
tions, non presente nella Figura 4.8, a sua volta ereditata dalla classe FPFormat-
tedOperandMoveInstructions, per via dell’analogia del lavoro compiuto su due
registri. La generica istruzione di questo gruppo ha la forma CVT.X.Y fs,fd
con (X,Y ) ∈ ({L,W,D}, {L,W,D}), X 6= Y, L = long, W = int,D = double;
tuttavia diverse coppie sono state omesse dall’instruction set.
FPConditionalCC DMoveInstructions
Le istruzioni che effettuano lo spostamento degli operandi formattati in modo
condizionale, leggendo il codice FCC del registro FCSR, sono modellate da questa
classe. La notazione generica per le istruzioni e MOVX.D fd,fs,cc, dove X si
riferisce al predicato da verificare (F=falso, T=true) affinche la condizione sia
vera; per ulteriori dettagli consultare il Paragrafo A.6. La classe implementa tutti
i metodi di Instruction; in particolare EX(), usando l’informazione del predicato
da verificare (F,T), specificata al livello dell’istruzione, accede al registro FCSR
e se riscontra la condizione di verita; effettua, poi, la copia di fs in un registro
ausiliario. Tale registro viene infine copiato su fd nello stadio WB.
FPConditionalZerosMoveInstructions
Questa classe modella le istruzioni che effettuano lospostamento degli operandi
formattati, copiando valori tra FPR se un GPR contiene, o meno, il valore zero.
La generica istruzione di questa categoria e MOVX.D fd,fs,rt, dove X si riferisce
al predicato da verificare; se e Z, lo spostamento avviene quando il registro rt vale
zero, se vale N lo spostamento avviene sul ”Non zero” di questo registro.
Vengono implementati tutti i metodi tranne EX(); l’unica differenza con le
64
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
Figura 4.9: Ereditarieta dalla classe FlowControlInstructions
altre classi e dovuta al fatto che il metodo ID(), oltre a leggere il registro fs, legge
il registro intero rt, che pilota l’esito dello spostamento.
FPMoveToAndFromInstructions
Il sottoinsieme di istruzioni di trasferimento dati, che si occupa di copiare valo-
ri da un GPR ad un FPR e viceversa, e modellato da questa classe. Le istruzioni
non ereditano direttamente da essa, ma da due sue sottoclassi: FPMoveToIn-
structions ed FPMoveFromInstructions. Dalla prima si ereditano le istruzioni
che trasferiscono word o doubleword dai GPR agli FPR (MTC1,DMTC1), dalla
seconda le istruzioni che effettuano l’operazione inversa (MFC1,DMFC1).
4.3.4 Ereditarieta dalla classe FlowControlInstructions
Anche la classe astratta FlowControlInstructions concretizza soltanto il meto-
do IF(), che esegue l’operazione accennata in precedenza per le istruzioni di
branch e jump. L’unica classe che eredita da FlowControlInstructions e FPCon-
ditionalBranchesInstructions, come si vede dalla Figura 4.9. Questa classe non
presenta l’implementazione dei metodi di Instruction, ma dichiara le costanti per
l’operazione di packing8. Le istruzioni ereditate da questa classe hanno il formato
8Questa operazione e eseguita col metodo pack() illustrato nelle istruzioni aritmetiche
65
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
BC1X cc,offset, dove X e il predicato da verificare 9(F=falso, T=true) prima di
eseguire un salto PC-relative.
4.3.5 Ereditarieta dalla classe LDSTInstructions
Le istruzioni floating point di load ereditano dalla classe FPLoading, la quale
implementa tutti i metodi di Instruction tranne EX(). La generica istruzione ha
la notazione LXC1 ft,offset(base), dove X puo assumere i valori D, per caricare
nel registro floating point una doubleword, e W per caricare una word nei 32 bit
piu bassi del registro.
Figura 4.10: Ereditarieta dalla classe LDSTInstructions
Il metodo ID() effettua le seguenti operazioni:
- verifica se e possibile leggere dal registro base, ed eventualmente lancia
l’eccezione RAWException per segnalare la dipendenza alla classe CPU.
- calcola l’indirizzo effettivo come somma di base e offset, salvandone il valore
in un registro ausiliario
- verifica se esiste una dipendenza di output, lanciando eventualmente l’ec-
cezione WAWException
9Se il bit cc nel campo FCC del registro FCSR e X avviene il salto
66
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
- incrementa i semafori di scrittura e di WAW del registro ft
Il metodo MEM() effettua solamente il decremento del semaforo di WAW, mentre
WB() effettua sia la scrittura sul registro ft che il relativo sblocco.
Le istruzioni floating point di store ereditano dalla classe FPStoring, e gene-
ricamente sono descritte dal pattern SXC1 ft,offset(base), con X che puo as-
sumere i valori di cui sopra. Il metodo ID() si differenzia da quello delle istruzioni
di load perche determina gli eventuali blocchi inerenti alla lettura dei registri base
ed ft ; infatti, al contrario del caso precedente, il registro ft o la sua word destra
devono essere copiati in una cella di memoria che, in EduMIPS64, non prevede il
blocco.
4.4 Pipelining
Prima dello sviluppo della FPU, la pipeline di EduMIPS64 implementava l’ILP
per le sole istruzioni intere. Non essendo presenti le istruzioni floating point, non
erano previste ne dipendenze di output che portassero agli stalli WAW, ne contese
tra unita funzionali, perche si seguiva un percorso di esecuzione unico per tutte
le istruzioni. L’introduzione della pipeline floating point, e la sua interazione con
la pipeline intera, presenta le complicazioni illustrate nel Paragrafo 3.6.
4.4.1 Pipeline floating point
Il modello ad oggetti che simula il funzionamento della pipeline FP implemen-
ta il design pattern Facade, il quale consente di ridurre l’accoppiamento tra un
insieme di classi strettamente correlate (unita funzionali), e il resto del sistema.
La classe ”facciata” fornisce un’interfaccia di alto livello verso un sottosistema, in-
67
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
Figura 4.11: Diagramma UML delle classi della pipeline FP
vocando i metodi delle classi di basso livello; essa e ”opaca”, nel senso che le classi
che usano il sistema non possono accedere a quelle di basso livello direttamente.
Nella Figura 4.11 e mostrata la classe ”facciata”, ovvero FPPipeline, che co-
ordina le operazioni di accesso alle tre unita funzionali da parte della classe CPU.
Le tre unita funzionali, rappresentate dalle classi Adder,Multiplier e Divider, im-
plementano l’interfaccia FPFunctionalUnit, la quale specifica i 5 metodi mediante
cui e assicurata la loro connessione con la classe FPPipeline.
4.4.2 File di configurazione della FPU
La nuova pipeline di EduMIPS64, comprensiva di quella intera e quella floating
point, richiede un adeguamento funzionale rispetto all’aggiunta di nuove istruzioni
dell’ISA MIPS64. Particolare interesse e rivolto a due tipi di istruzioni: aritme-
tiche FP e di terminazione del programma. Le prime devono essere note al-
la classe CPU, che deve spostarle dallo stadio ID alle relative unita funzionali.
Le seconde devono essere riconosciute per impedir loro di fermare la pipeline
68
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
in anticipo (prima che essa si svuoti); nel successivo paragrafo si affronteranno
meglio queste problematiche. La classe FPUConfigurator, invocata nel contrut-
tore della CPU, effettua il parsing del file fpu.properties, contenente linee del tipo
<tag>istruzione</tag>, e carica le due liste
knownFPInstructions e terminatingInstructionsOPCodes. La prima contiene
i nomi delle istruzioni aritmetiche FP, la seconda gli opcode10 delle istruzioni di
terminazione.
4.4.3 Interazione tra CPU ed FPU
EduMIPS64 si avvale di 2 thread che, in modo approssimativo, separano la
gestione della GUI da quella delle operazioni di calcolo. Il thread che si occupa di
”far lavorare” la CPU si chiama CPUGUIThread. Esso e in attivita per la durata
del singolo ciclo, successivamente va in stato di attesa fino a che l’utente non da
il comando per eseguire il ciclo successivo. Per ogni ciclo, questa classe invoca il
metodo step() della classe CPU, in cui si eseguono delle operazioni iniziali:
1. Si aggiornano, attivandole o disattivandole, le trap per le 4 eccezioni IEEE.
Poiche esse sono configurabili dall’utente, le informazioni sul loro stato
vengono prelevate da una struttura dati11 che configura la GUI.
2. Nello stesso modo illustrato prima, si configura la modalita di arrondamento,
aggiornando i bit RM del registro FCSR.
3. Si esegue lo stadio WB.
10L’opcode e un campo del codice binario dell’istruzione che la identifica univocamente in unISA
11La classe Config fornisce i metodi per caricare, leggere o scrivere una hashmap javacontenente le configurazioni della GUI
69
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
Successivamente, per ogni istruzione nella pipeline, si invocano i metodi dello
stadio corrispondente12. Ciascuna sezione di codice che si occupa dell’invocazione
dei metodi delle istruzioni, ha subito profondi cambiamenti per risolvere le pro-
blematiche insite nell’ILP delle istruzioni floating point. L’unico stadio che non
presenta alcuna modifica e IF, per tale ragione e stato omesso dalla trattazione
che segue.
Stadio WB
Il metodo WB delle istruzioni di terminazione (HALT e SYSCALL 0) invoca l’ec-
cezione HaltException, che imposta lo stato della CPU ad HALTED. Nell’ottica
di una pipeline intera, questa logica non causa problemi; le istruzioni di termi-
nazione attraversano la pipeline intera e, poiche sono le ultime ad essere eseguite
in un programma, possono segnalare alla CPU di fermare la pipeline.
Trattare invece con le istruzioni floating point a lunga latenza, al contrario,
rende possibili nuovi scenari. Una qualunque istruzione aritmetica floating point,
subito seguita da una di terminazione, uscira dalla pipeline diversi cicli dopo
quella di terminazione; la latenza delle unita funzionali provoca, cioe, l’inversione
dell’ordine di uscita dalla pipeline delle istruzioni.
Nella nuova situazione, il metodo WB delle istruzioni, che potrebbe contenere
anche del codice che fa terminare la pipeline (istruzioni di terminazione), non puo
essere eseguito senza un preventivo controllo. Nel listato che segue, la variabile
booleana notWBable viene sommata logicamente alle condizioni che devono ve-
rificarsi per non eseguire il metodo WB() dell’istruzione: l’istruzione in WB e di
terminazione e qualche unita funzionale sta ancora calcolando, oppure, mantenen-
12Se ad esempio un’istruzione e al terzo posto dell’hash map che rappresenta la pipeline intera,si invoca il metodo EX()
70
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
do la prima condizione, le unita funzionali non lavorano, ma un’istruzione occupa
lo stadio MEM.
boolean notWBable=fa l se ;notWBable=notWBable | | ( terminatorInstrInWB && ! fpPipe . isEmpty ( ) ) ;notWBable=notWBable | | ( terminatorInstrInWB && fpPipe . isEmpty ( ) &&
pipe . get ( PipeStatus . MEM ) . getName () !=" " ) ;i f ( ! notWBable )
pipe . get ( PipeStatus . WB ) . WB ( ) ;
Un ultimo problema da risolvere e come fermare la pipeline appena ”escono”
tutte le istruzioni, dal momento che si e praticamente ignorata l’istruzione di ter-
minazione. La soluzione era gia presente nel codice del simulatore; l’esecuzione
dello stadio ID delle istruzioni di terminazione provoca il cambiamento di stato
della CPU da RUNNING a STOPPING. E sufficiente rilevare questo cambiamen-
to per lanciare l’eccezione HaltException dopo aver verificato che la pipeline e
effettivamente vuota.
i f ( arePipelinesEmpties ( ) && getStatus()==CPUStatus . STOPPING ) {setStatus ( CPU . CPUStatus . HALTED ) ;throw new HaltException ( ) ;}
Stadio MEM
A questo stadio non sono state apportate importanti modifiche. L’unico cam-
biamento riguarda la ”messa a null” dell’oggetto puntato dalla chiave MEM nel-
l’hash map che simula la pipeline. Tale azione e richiesta perche l’esecuzione di
un qualunque stadio diverso da WB e permesso solo se e garantito lo spostamento
successivo in avanti dell’oggetto istruzione13. Per esempio, l’istruzione in EX puo
essere eseguita solo se MEM vale null. Se questo non e possibile, piu avanti sono
mostrate le tecniche per risolvere il problema.
13Se un’istruzione non potra essere spostata in avanti al successivo ciclo di clock, vuol direche si verifichera uno stallo strutturale
71
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
currentPipeStatus = PipeStatus . MEM ;i f ( pipe . get ( PipeStatus . MEM )!= null )
pipe . get ( PipeStatus . MEM ) . MEM ( ) ;pipe . put ( PipeStatus . WB , pipe . get ( PipeStatus . MEM ) ) ;pipe . put ( PipeStatus . MEM , null ) ;
Stadio EX
La difficolta nella gestione di questo stadio e dovuta al fatto che si deve
prevedere se, nel ciclo successivo, avverra un hazard strutturale, perche piu istruzioni14
giungono allo stadio MEM contemporaneamente.
Le condizioni sufficienti affinche si verifichi un hazard strutturale di questo
tipo, nel ciclo n + 1, sono che nel ciclo n:
- un’istruzione intera occupa lo stadio EX, e almeno un’istruzione aritmetica
floating point si trova negli stadi A4,M7,DIV24
- nessuna istruzione intera occupa lo stadio EX, ma almeno due istruzioni
aritmetiche FP occupano due degli stadi A4,M7,DIV24.
Come si e visto, il verificarsi di un hazard strutturale, dovuto al conflitto sullo
stadio MEM, e da addebitare esclusivamente alle istruzioni aritmetiche floating
che concorrono tra esse, o con l’istruzione intera, per occupare questo stadio.
Il sistema di previsione di questi hazard si deve quindi basare sul controllo della
pipeline floating point. La classe FPPipeline, vista nel Paragrafo 4.4.1, fornisce
il metodo getInstruction(), al quale viene passato come parametro uno due
possibili valori booleani SIMUL MODE ENABLED o SIMUL MODE DISABLED. Col primo
parametro, il metodo simula le operazioni della pipeline FP ottenute col ciclo di
clock n + 1, senza apportare alcuna modifica all’interno di essa (non si spostano
14Lo stadio MEM e condiviso dall’istruzione intera che ha appena eseguito EX, e dalleeventuali istruzioni aritmetiche FP che escono dalle unita funzionali
72
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
le istruzioni in avanti). Se l’oggetto ritornato e un’istruzione, e non un null,
nel ciclo n + 1 esso pretendera di occupare lo stadio MEM. Passando al metodo il
booleano SIMUL MODE DISABLED, invece, l’eventuale istruzione candidata ad uscire
dalla pipeline FP viene definitivamente estratta, e la sua precedente posizione
posta a null.
La prima modifica, apportata nella classe CPU al livello della gestione del-
lo stadio EX per le istruzioni intere, riguarda l’esecuzione in modo condiziona-
to del codice estente; quest’ultimo invoca il metodo EX() delle istruzioni intere
catturando le eventuali eccezioni sincrone e gestendole.
try {currentPipeStatus = PipeStatus . EX ;// se l o s t a d i o EX e non vuoto s i invoca EX() d e l l ’ i s t r u z i o n ei f ( pipe . get ( PipeStatus . EX )!= null )
pipe . get ( PipeStatus . EX ) . EX ( ) ;}catch ( SynchronousException e ) {
i f ( masked )// qualunque trap non puo avven i re perch e l ’ e cce z ione// s incrona e mascherataedumips64 . Main . logger . exception ("[MASKED] " + e . getCode ( ) ) ;
else {i f ( terminate ){
//programma terminato se l ’ e cce z ione e non mascherataedumips64 . Main . logger . log ("Terminazione" ) ;throw new SynchronousException (e . getCode ( ) ) ;
} else// i l programma cont inua ad e s e gu i r e anche se// l ’ e cce z ione e non mascherata
syncex = e . getCode ( ) ;}
}
Listato 4.5: Invocazione metodo EX e gestione eccezioni sincrone
Se il metodo getInstruction(SIMUL MODE ENABLED), invocato dalla classe CPU
sulla classe FPPipeline, ritorna null, viene eseguito il codice del Listato 4.5, pas-
73
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
sando l’istruzione intera in MEM. In questo caso, nessuna istruzione, nel ciclo che
si sta eseguendo15 (n+1), uscira dalle unita funzionali, e non si verifichera alcuno
stallo strutturale.
Se il metodo, invece, restituisce un’oggetto istruzione diverso da una bubble16,
nel ciclo corrente (n + 1) si potrebbe verificare uno stallo strutturale. Prima di
eseguire il codice del listato devono effettuarsi queste operazioni:
- se lo stadio EX e occupato da un’istruzione che non sia una bubble, oppure
se le istruzioni aritmetiche FP, che nel ciclo n+1 usciranno dalla pipeline FP
(fpPipe), sono piu di una, si deve incrementare il contatore memoryStalls,
il quale tiene il conto degli hazard strutturali in cui e implicata la memoria.
i f ( ( pipe . get ( PipeStatus . EX )!= null &&! ( pipe . get ( PipeStatus . EX ) . getName ( ) . compareTo (" " )==0)) | |fpPipe . getNReadyToExitInstr ()>1)
memoryStalls++;
- col metodo getInstruction(SIMUL MODE DISABLED), si ottiene l’istruzione
FP della quale si invochera il metodo EX()
instr=fpPipe . getInstruction ( SIMUL_MODE_DISABLED ) ;
Dopo queste operazioni si puo eseguire un codice analogo a quello del Listato 4.5.
instr=fpPipe . getInstruction ( SIMUL_MODE_DISABLED ) ;try {
currentPipeStatus = PipeStatus . EX ;instr . EX ( ) ;. . . .
Un’ultima operazione, che conclude lo stadio EX, consiste nel far traslare le
istruzioni nella pipeline FP invocando il metodo FPPipeline::step().
15Si conosce lo stato della pipeline apportato dal ciclo n, e ci si trova dentro il ciclo (n+1);ma ancora non e stato apportato alcun cambiamento allo stato del ciclo n
16Istruzione usata per riempire gli spazi vuoti della pipeline
74
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
Stadio ID
Prima di introdurre la pipeline FP, il codice della classe CPU spostava qualunque
istruzione dallo stadio ID a quello EX. La gestione delle istruzioni aritmetiche
floating point, che sono le uniche ad utilizzare la pipeline FP, introduce la pos-
sibilita che l’istruzione in ID debba essere ”deviata” verso le unita funzionali. Il
discriminante per le due modalita di esecuzione e la presenza dell’istruzione, che si
trova in ID, nella lista delle istruzioni aritmetiche FP (knownFPInstructions). Se
l’istruzione e di quest’ultimo tipo, si effettuano le seguenti operazioni: si invoca,
in modalita simulazione, il metodo putInstruction() della classe FPPipeline pas-
sandogli l’oggetto istruzione in ID. Se non viene restituito alcun codice di errore,
nel ciclo n + 1 non ci sara alcuno stallo strutturale (il divisore non e occupato); si
invoca quindi il metodo ID() dell’istruzione in questo stadio, e successivamente
il metodo putInstruction in modo non simulativo. Se, al contrario, viene resti-
tuito un codice di errore, si aprono due possibili scenari: si sta inserendo una
divisione nel divisore ma questo e gia occupato; non essendo fully pipelined, viene
lanciata l’eccezione FPDividerNotAvailableException(). Oppure, si sta inserendo
un’istruzione diversa dalla divisione in una delle altre due unita funzionali che non
la puo accettare; cio e dovuto al fatto che si ha un ”ingorgo” di istruzioni, causato
da una serie di hazard strutturali successivi per la non disponibilita memoria. Si
supponga, per esempio, questa sequenza di istruzioni non affette da dipendenze:
MUL.D,MUL.D,MUL.D,ADD.D,ADD.D,ADD.D,ADD.D,ADD.D
l’ultima ADD.D non puo accedere da subito alla pipeline FP perche l’addizionatore
ha tutti gli stadi pieni, e le istruzioni che li occupano saranno fermate all’altra
estremita fino a che tutte le MUL.D, che hanno maggiore priorita, libereran-
no il moltiplicatore. Fino a quando permane questa situazione, viene lanciata
75
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
l’eccezione FPFunctionalUnitNotAvailableException, per fermare il fetch di nuove
istruzioni e la parte iniziale della pipeline.
Se l’istruzione e invece intera, si deve affrontare un problema simile a quel-
lo visto in precedenza. Le istruzioni intere, avendo la minore priorita ad ac-
quisire l’accesso allo stadio MEM quando concorrono con le istruzioni FP, sono
piu soggette ad essere fermate nello stadio EX. Dell’istruzione in ID, quindi, non
si puo invocare il relativo metodo fino a che quella in EX non viene spostata.
Durante questo intervallo, devono essere fermati i fetch e la parte sinistra della
pipeline con l’eccezione EXNotAvailableException. Segue il Listato 4.6 che illustra
quanto e stato detto.
currentPipeStatus = PipeStatus . ID ;i f ( pipe . get ( PipeStatus . ID )!= null ) {
i f ( knownFPInstructions . contains ( pipe . get ( PipeStatus . ID ) . getName ( ) ) ) {// l ’ i s t r u z i o n e e a r i tme t i c a f l o a t i n g po in ti f ( fpPipe . putInstruction ( pipe . get ( PipeStatus . ID ) , SIMUL_MODE_ENABLED)==0){
//L ’ un i t a f un z i ona l e e l i b e r apipe . get ( PipeStatus . ID ) . ID ( ) ;fpPipe . putInstruction ( pipe . get ( PipeStatus . ID ) , SIMUL_MODE_DISABLED ) ;pipe . put ( PipeStatus . ID , null ) ;
} else {//L ’ un i t a f un z i ona l e e occupatai f ( pipe . get ( PipeStatus . ID ) . getName ( ) . compareToIgnoreCase ("DIV.D")==0)
// s t a l l o s t r u t t u r a l e perch e i l d i v i s o r e e occupatothrow new FPDividerNotAvailableException ( ) ;
else// s top f e t c h perch e c ’ e ingorgothrow new FPFunctionalUnitNotAvailableException ( ) ;
}}
else {// l ’ i s t r u z i o n e in ID e i n t e r ai f ( pipe . get ( PipeStatus . EX)==null | |pipe . get ( PipeStatus . EX ) . getName ( ) . compareTo (" ")==0) {
// l o s t a d i o EX e d i s p o n i b i l e ad a c c e t t a r e un ’ i s t r u z i o n e ( vuoto o b o l l a )pipe . get ( PipeStatus . ID ) . ID ( ) ;pipe . put ( PipeStatus . EX , pipe . get ( PipeStatus . ID ) ) ;pipe . put ( PipeStatus . ID , null ) ;
76
CAPITOLO 4. LA FLOATING POINT UNIT DI EDUMIPS64
}else {
// l o s t a d i o EX e occupatothrow new EXNotAvailableException ( ) ;
}}
}
Listato 4.6: Gestione dello stadio ID
77
Capitolo 5
Conclusioni
In questa tesi sono state illustrate le scelte progettuali per la costruzione
di un’infrastruttura ad oggetti, in Java, che modella i componenti hardware e
software di una floating point unit, da integrare in un simulatore di CPU MIPS64.
Il simulatore in questione e EduMIPS64; la FPU in esso sviluppata si basa
su un modello generico di processore MIPS64, di cui non si conosce a priori la
strategia computatazionale mediante cui le operazioni floating point vengono ese-
guite. Per tale ragione, sono stati trascurati alcuni dettagli implementativi della
pipeline che riguardano i conflitti tra le unita funzionali. Un interessante svilup-
po di questa tesi sarebbe, oltre completare l’instruction set implementando le
istruzioni floating point in singola precisione, progettare una piattaforma che con-
figuri sia la pipeline ad emulare un modello specifico di processore MIPS64, che
l’istruction set ad essere eseguito con i relativi stadi. Cio consentirebbe di colmare
ulteriormente il divario tra simulatore e architettura reale.
Tutto il codice scritto per questa tesi sara integrato nella versione 1.0 di Edu-
MIPS64, tuttavia, fino all’uscita di questa versione, e possibile provare le nuove
funzionalita apportate scaricando, dal sito ufficiale [3], la versione svn.
Il codice e rilasciato sotto la licenza GNU General Public License (GPL), come
78
CAPITOLO 5. CONCLUSIONI
tra l’altro l’intero progetto EduMIPS64.
79
Appendice A
Manuale utente della FPU diEduMIPS64
A.1 Introduzione
Questa appendice completa il Manuale utente di EduMIPS64[1] con il capitolo
relativo all’utilizzo della floating point unit. Esso verra integrato nel manuale a
partire dalla versione 1.0 del simulatore. Nel Paragrafo A.2 viene introdotto il
formato double, i valori speciali definiti dallo standard IEEE754, e le condizioni
di eccezioni che i calcoli floating point possono provocare.
Nel Paragrafo A.3 viene illustrato come EduMIPS64 consente di attivare e
disattivare le trap relative alle condizioni di eccezione IEEE.
Nel Paragrafo A.4 si parla del modo in cui i valori double e i valori speciali
vengono accettati da EduMIPS64 per essere caricati in memoria.
Nel Paragrafo A.5 e introdotto il registro FCSR, usato dalla FPU per autoge-
stirsi. In esso vengono memorizzate le informazioni riguardanti l’arrotondamento,
i codici condizionali e le politiche di gestione delle eccezioni IEEE.
Infine, nel Paragrafo A.6 sono elencate tutte le istruzioni dell’ISA MIPS64
implementate in EduMIPS64.
80
APPENDICE A. MANUALE UTENTE DELLA FPU DI EDUMIPS64
A.2 Valori speciali
L’aritmetica in virgola mobile dei calcolatori e caratterizzata dal fatto che,
anche in presenza di un’operazione matematica non valida, si potrebbe scegliere
di continuare la computazione ignorando quanto e accaduto. In questo scenario,
operazioni come divisioni tra zeri, oppure radici quadrate di numeri negativi de-
vono generare comunque un risultato che, non essendo un numero (Not a Num-
ber), e trattato come qualcosa di diverso. Prima di continuare questa trattazione,
vengono definiti i numeri in virgola mobile (floating point) a doppia precisione.
Vengono chiamati double e possono rappresentare valori compresi nel dominio
[−1.79E308,−4.94E − 324] ∪ {0} ∪ [4.94E − 324, 1.79E308].
A.2.1 NaN o Invalid Operation
Lo standard IEEE 754, il quale regolamenta la manipolazione dei numeri float-
ing point nei calcolatori, ha definito che le operazioni matematiche non valide
possono sia provocare una segnalazione durante l’esecuzione del programma (trap
per la condizione di eccezione IEEE Invalid Operation), che fornire, come risul-
tato, il valore speciale QNaN (Quit Not a Number). Un altro valore NaN, che
genera incondizionatamente la stessa trap appena viene rilevato come operando,
e SNaN (Signalling NaN). Tale valore e raramente utilizzato nelle applicazioni, e
storicamente e stato usato per inizializzare le variabili.
A.2.2 Zeri o Underflow
Un altro valore speciale definito dallo standard e lo zero. Dal momento che
il formato double non include lo zero nel dominio dei valori rappresentati, esso e
considerato alla stregua di un valore speciale. Esistono uno zero positivo e uno
81
APPENDICE A. MANUALE UTENTE DELLA FPU DI EDUMIPS64
negativo: quando si tenta di rappresentare un valore negativo molto vicino allo
zero, ma fuori dal dominio rappresentabile dai double (∈]− 4.94E − 324, 0[),
e si desidera a tutti i costi un risultato (non una trap per la condizione di eccezione
Underflow), allora il numero restituito e −0. Analogamente, viene restituito +0
se si tenta di rappresentare un numero nell’intervallo [0, 4.94E − 324[, e non si e
preferito avere la stessa trap.
A.2.3 Infiniti od Overflow
Quando si tenta di rappresentare un numero estremamente grande (∈]1.79E308, +∞[),
o estrememente piccolo (∈]−∞,−1.79E308[), al di fuori cioe del dominio rappre-
sentabile dal formato double, vengono restituiti i valori speciali +∞, nel primo
caso, e −∞ nel secondo caso. In alternativa, si puo avere una trap per via della
condizione di eccezione Overflow.
A.2.4 Infiniti o Divide by zero
Gli infiniti potrebbero anche essere restituiti da una divisione per zero, nelle
quali si effettua il prodotto tra il segno dello zero e quello del divisore, per restituire
un opportuno infinito. Nel caso in cui non si voglia alcun valore restituito, si
verifica la trap per la condizione di eccezione Divide by zero.
A.3 Configurazione delle eccezioni
EduMIPS64 consente di abilitare o disabilitare le trap relative alle 4 delle 5
condizioni di eccezione IEEE, implementate dalla scheda Eccezioni FPU della
finestra Configura→ Impostazioni. Se esse sono disabilitate, verra fornito un
risultato per qualunque operazione speciale la FPU effettui (si veda il Paragrafo
A.2). Nel caso illustrato in Figura A.1, in cui alcune caselle di controllo sono
82
APPENDICE A. MANUALE UTENTE DELLA FPU DI EDUMIPS64
spuntate, se la CPU non maschera le eccezioni sincrone nel simulatore (Figura
A.2), verra simulata una trap relativa alla condizione di eccezione IEEE che si e
verificata (Figura A.3).
Figura A.1: Configurazione delle trap per le eccezioni IEEE
Figura A.2: Opzione che maschera le eccezioni sincrone(disabilita tutte le trap)
Figura A.3: Finestra che notifica la trap
83
APPENDICE A. MANUALE UTENTE DELLA FPU DI EDUMIPS64
A.4 Direttiva .double
La direttiva .double, da inserire nella sezione .data del file sorgente (.s),
consente di allocare una cella della memoria di EduMIPS64, dove inserire un
valore formattato double. Le sintassi valide del comando sono
nome_variabile : . double numero_doublenome_variabile : . double parola_chiave
dove numero double puo essere rappresentato sia in forma estesa (1.0,0.003),
oppure in notazione scientifica (3.7E-12,0.5E32). Invece, parola chiave puo
assumere i valori POSITIVEINFINITY, NEGATIVEINFINITY,
POSITIVEZERO, NEGATIVEZERO, SNAN e QNAN, consentendo l’inserimento diretto
in memoria dei valori speciali.
A.5 Registro FCSR
L’FCSR(Floating point Control Status Register) e il registro che controlla i
diversi aspetti funzionali della FPU. Esso e lungo 32 bit e, fino alla ridisegnazione
grafica di EduMIPS64, sara posto nella finestra delle statistiche. Il campo FCC
e costituito da 8 bit, identificati con numeri da 0 a 7. Le istruzioni condizionali
(C.EQ.D,C.LT.D) lo utilizzano per memorizzare il risultato booleano di un con-
fronto tra due registri. I campi Cause, Enables e Flag gestiscono la dinamica
delle eccezioni IEEE, illustrate nel Paragrafo A.2. Essi sono costituiti, ognuno,
da 5 bit identificati con le lettere V (Invalid operation), Z (Divide by zero), O
(Overflow),U (Underflow) e I (Inexact); quest’ultimo bit non viene al momento
utilizzato.
Il campo Cause indica se si e verificata una qualunque eccezione IEEE durante
la simulazione, presentando un 1 nel relativo bit. E utile quando si esegue un
84
APPENDICE A. MANUALE UTENTE DELLA FPU DI EDUMIPS64
Figura A.4: Registro FCSR in EduMIPS64
programma dall’inizio alla fine senza fermarlo, per determinare se si e verificata
una qualunque eccezione.
Il campo Enable mostra le eccezioni IEEE per le quali e attiva la trap. I
bit di questo campo vengono modificati, anche senza resettare il simulatore, dalla
finestra di configurazione della Figura A.1.
Il campo Flag mostra le eccezioni IEEE che si sono verificate ma, non avendo
la relativa trap attivata, hanno fornito come risultato dei valori speciali, illustrati
nel Paragrafo A.2.
Il campo RM mostra la modalita di arrotondamento corrente usata, in Edu-
MIPS64, per le istruzioni che convertono numeri floating point in interi (si veda
l’istruzione CVT.L.D per ulteriori dettagli).
A.6 Instruction set
Per una consultazione efficiente, le istruzioni dell’ISA MIPS64, implementate
in EduMIPS64, vengono elencate in ordine alfabetico. Le operazioni eseguite ven-
85
APPENDICE A. MANUALE UTENTE DELLA FPU DI EDUMIPS64
gono rappresentate mediante uno pseudocodice in cui l’i−esima cella di memoria
e indicata con memory[i], i bit del campo FCC del registro FCSR mediante
FCSR FCC[cc], con cc ∈ [0, 7]. In alcune istruzioni, per evitare ambiguita, i re-
gistri sono indicati come GPR[i] e FPR[i], con i ∈ [0, 31], ma nella maggior
parte dei casi essi vengono indicati qualitativamente con la notazione rx o fx,
dove x ∈ {d, s, t}. Le tre lettere servono solo a distinguere, al piu, tre regi-
stri per ogni istruzione. Infine, i valori ritornati dalle operazioni di conversione
vengono indicati con la notazione convert tipoconversione(registro[,tipo
arrotondamento]), dove il parametro tra parentesi quadre e presente solo in
certe circostanze.
Per prendere confidenza con le istruzioni floating point, alcuni file sorgenti
possono essere scaricati dal link
http://www.edumips.org/attachment/wiki/Upload/FPUMaxSamples.rar.
ADD.D
Sintassi: ADD.D fd, fs, ft
Descrizione: fd = fs + ft
Eccezioni: Le trap di Overflow e Underflow vengono generate se il risul-tato non puo essere rappresentato secondo lo standard IEEE754. Invalid Operation e generata se fs o ft contengonoQNaN o SNaN, o se viene eseguita un’operazione non valida(+∞−∞).
86
APPENDICE A. MANUALE UTENTE DELLA FPU DI EDUMIPS64
BC1F
Sintassi: BC1F cc, offset
Descrizione: if FCSR FCC[cc] == 0 then branch
Verifica se il valore booleano FCSR FCC[cc] e falso ed effet-tua, in tal caso, un salto PC-relative. Questa istruzione puoaccedere al registro FCSR solo in lettura; l’informazione de-v’essere scritta da una precedente istruzione condizionale deltipo C.condizione.D.
Esempio: C.EQ.D 7,f1,f2
BC1F 7,label
In questo esempio C.EQ.D verifica l’uguaglianza tra i registrif1 ed f2, scrivendo il risultato booleano del confronto nel bit7 del campo FCC del registro FCSR. Dopodiche BC1F verificase quel bit vale 0 (falso) e salta a label.
BC1T
Sintassi: BC1T cc, offset
Descrizione: if FCSR FCC[cc] == 1 then branch
Verifica se il valore booleano FCSR FCC[cc] e vero ed effet-tua, in tal caso, un salto PC-relative. Questa istruzione puoaccedere al registro FCSR solo in lettura; l’informazione de-v’essere scritta da una precedente istruzione condizionale deltipo C.condizione.D.
Esempio: C.EQ.D 7,f1,f2
BC1T 7,label
In questo esempio, C.EQ.D verifica l’uguaglianza tra i registrif1 ed f2, scrivendo il risultato booleano del confronto nel bit7 del campo FCC del registro FCSR. Dopodiche BC1T verificase quel bit vale 1 (vero) e salta a label.
87
APPENDICE A. MANUALE UTENTE DELLA FPU DI EDUMIPS64
C.EQ.D
Sintassi: C.EQ.D cc, fs, ft
Descrizione: FCSR FCC[cc] = (fs==ft)
Verifica il predicato ”uguale a” tra i due registri fs ed ft e salvail risultato booleano in FCSR FCC[cc]. Questo valore verrautilizzato da un’istruzione successiva per effettuare un saltocondizionato (branch) o un movimento di dati condizionatotra registri floating point.
Esempio: C.EQ.D 2,f1,f2
MOVT.D f8,f9,2
In questo esempio C.EQ.D verifica l’uguaglianza tra i registrif1 ed f2, scrivendo il risultato booleano del confronto nel bit 2del campo FCC del registro FCSR. Dopodiche MOVT.D verificase quel bit vale 1 (vero), e copia il registro f9 su f8.
Eccezioni: Invalid Operation e lanciata quando fs o ft contengono valoriQNaN (se attiva, si ha una trap) o SNaN(si ha sempre unatrap).
C.LT.D
Sintassi: C.LT.D cc, fs, ft
Descrizione: FCSR FCC[cc] = (fs<ft)
Verifica il predicato ”minore di”(Less Than) tra i due regi-stri fs ed ft, e salva il risultato booleano in FCSR FCC[cc].Questo valore verra utilizzato da un’istruzione successiva, pereffettuare un salto condizionato (branch), o per un movimentodi dati condizionato tra registri floating point.
Esempio: C.LT.D 2,f1,f2
BC1T 2,target
In questo esempio, C.LT.D verifica se f1 e minore di f2, scriven-do il risultato booleano del confronto nel bit 2 del campo FCCdel registro FCSR. Dopodiche, BC1T verifica se quel bit vale 1(vero), e salta a target
Eccezioni: Invalid Operation e lanciata quando fs o ft contengono valoriQNaN (se attiva, si ha una trap) o SNaN(si ha sempre unatrap).
88
APPENDICE A. MANUALE UTENTE DELLA FPU DI EDUMIPS64
CVT.D.L
Sintassi: CVT.D.L fd, fs
Descrizione: fd = convert longToDouble(fs)
Converte un long in un doubleEsempio: DMTC1 r6,f5
CVT.D.L f5,f5
In questo esempio, DMTC1 copia il valore del GPR r6 nell’FPRf5. Successivamente, CVT.D.L converte il numero in f5 da longa double.Supponendo r6 = 52, dopo l’esecuzione di DMTC1, l’equiva-lente binario di 52 viene copiato nel registro f5 (f5 non contieneancora il valore 52.0 perche non e stato formattato ancoracome double). Dopo l’esecuzione di CVT.D.L, f5 = 52.0.
Eccezioni: Invalid Operation e lanciata quando fs contiene QNaN,SNaNo Infinito
CVT.D.W
Sintassi: CVT.D.W fd, fs
Descrizione: fd = convert IntToDouble(fs)
Converte un int in un doubleEsempio: MTC1 r6,f5
CVT.D.W f5,f5
In questo esempio, MTC1 copia i 32 bit piu bassi del GPR r6nell’FPR f5. Successivamente, CVT.D.W, leggendo prima f5come int, lo sovrascrive in double.Supponendo r6=0xAAAAAAAABBBBBBBB, dopo l’esecuzione diMTC1 si ha che f5=0xXXXXXXXXBBBBBBBB; si noti che i suoi32 bit piu alti (XX..X) sono UNDEFINED (non sono statisovrascritti). CVT.D.W legge f5 come int (f5=-1145324613),formattandolo poi in double (f5=0xC1D1111111400000=-1.145324613E9).
Eccezioni: Invalid Operation e lanciata quando fs contiene QNaN,SNaNo Infinito
89
APPENDICE A. MANUALE UTENTE DELLA FPU DI EDUMIPS64
CVT.L.D
Sintassi: CVT.L.D fd, fs
Descrizione: fd = convert doubleToLong(fs, CurrentRoundingMode)
Converte, dapprima arrotondandolo, un double in un longEsempio: CVT.L.D f5,f5
DMFC1 r6,f5
In questo esempio, CVT.L.D converte il double in f5 in unlong. Dopodiche, DMFC1 copia l’FPR f5 nel GPR r6. Il risul-tato di questa istruzione dipende dalla modalita di arroton-damento corrente, che viene impostata dalla scheda Arroton-damenti FPU della finestra Configura → Impostazioni, comein Figura A.5.
Eccezioni: Invalid Operation e lanciata quando fs vale Infinito, XNaN, oil risultato e fuori dall’intervallo dei long [−263, 263 − 1]
Figura A.5: Configurazione modalita di arrotondamento
Tipo Campo RM Registro f5 Registro r6
Al piu vicino 0 6.4 6Al piu vicino 0 6.8 7Al piu vicino 0 6.5 6 (al pari)Al piu vicino 0 7.5 8 (al pari)Verso lo zero 1 7.1 7Verso lo zero 1 -2.3 -2Verso +∞ 2 4.2 5Verso +∞ 2 -3.9 -3Verso −∞ 3 4.2 4Verso −∞ 3 -3.9 -4
Tabella A.1: Esempi sui tipi di arrotondamento
90
APPENDICE A. MANUALE UTENTE DELLA FPU DI EDUMIPS64
CVT.W.D
Sintassi: CVT.W.D fd, fs
Descrizione: fd = convert DoubleToInt(fs, CurrentRoundingMode)
Converte un double in un int utilizzando la modalita diarrotondamento corrente, illustrata per l’istruzione CVT.L.D
Eccezioni: Invalid Operation e lanciata quando fs e Infinito, XNaN,o il risultato e fuori dall’intervallo degli interi con segno[−231, 231 − 1]
DIV.D
Sintassi: DIV.D fd, fs, ft
Descrizione: fd = fs ÷ ft
Eccezioni: Le trap di Overflow e Underflow vengono generate se il risul-tato non puo essere rappresentato secondo lo standard IEEE754. Invalid Operation e generata se fs o ft contengonoQNaN o SNaN, o se viene eseguita un’operazione non vali-da (0 ÷ 0,∞ ÷∞). Divide by zero e generata se e eseguitauna divisione per zero che non ha per dividendo un XNaN(5÷ 0).
DMFC1
Sintassi: DMFC1 rt,fs
Descrizione: rt = fs
Copia l’intero contenuto binario dell’FPR fs nel GPR rt. Nes-sun controllo di formato viene eseguito su fs prima dellacopia.
DMTC1
Sintassi: DMTC1 rt, fs
Descrizione: fs = rt
Copia il contenuto binario del GPR rt nell’ FPR fs.
L.D (”DEPRECATED”: retrocompabitibilita con WinMIPS64)
Sintassi: L.D ft, offset(base)
Descrizione: memory[GPR[base] + offset]
Carica una doubleword (64 bit) dalla memoria all’FPR ft.Questa istruzione non appartiene all’ISA MIPS64; si consiglial’utilizzo di LDC1.
91
APPENDICE A. MANUALE UTENTE DELLA FPU DI EDUMIPS64
LDC1
Sintassi: LDC1 ft, offset(base)
Descrizione: memory[GPR[base] + offset]
Carica una doubleword (64 bit) dalla memoria all’FPR ft
LWC1
Sintassi: LWC1 ft, offset(base)
Descrizione: memory[GPR[base] + offset]
Carica una doubleword (64 bit) dalla memoria all’FPR ft
MFC1
Sintassi: MFC1 rt, fs
Descrizione: rt = readInt(fs)
Legge l’FPR fs come int e scrive il GPR rt come longEsempio: MFC1 r6,f5
SD r6,inmemoria(R0)
Si supponga f5=0xAAAAAAAABBBBBBBB; MFC1 legge f5 comeint, cioe i 32 bit piu bassi (interpreta BBBBBBBB come-1145324613), e lo scrive in r6 (64 bit). Dopo l’esecuzione diMFC1, r6=0xFFFFFFFFBBBBBBBB, che equivale a -1145324613
leggendo questo registro come long. Quindi in memoria, purutilizzando l’istruzione SD, verra scritta una doubleword convalore -1145324613. Questa operazione di conversione e chia-mata estensione del segno, il cui approfondimento esula dagliscopi di questo manuale.
MOVF.D
Sintassi: MOVF.D fd, fs, cc
Descrizione: if FCSR FCC[cc] == 0 then fd=fs
Verifica se la condizione di confronto booleana in FC-SR FCC[cc] e falsa e copia fs su fd. Nessun controllo sulformato viene realizzato su fs.
MOVT.D
Sintassi: MOVT.D fd, fs, cc
Descrizione: if FCSR FCC[cc] == 1 then fd=fs
Verifica se la condizione di confronto booleana in FC-SR FCC[cc] e vera, e copia fs su fd. Nessun controllo sulformato viene realizzato su fs.
92
APPENDICE A. MANUALE UTENTE DELLA FPU DI EDUMIPS64
MOV.D
Sintassi: MOV.D fd, fs
Descrizione: fd = fs
Copia fs su fd senza alcun controllo del formato di fs
MOVN.D
Sintassi: MOVN.D fd, fs, rt
Descrizione: if rt != 0 then fd=fs
Copia fs su fd, senza alcun controllo del formato di fs, se ilGPR rt e diverso da zero
MOVZ.D
Sintassi: MOVZ.D fd, fs, rt
Descrizione: if rt == 0 then fd=fs
Copia fs su fd, senza alcun controllo del formato di fs, se il ilGPR rt e uguale a zero
MTC1
Sintassi: MTC1 rt, fs
Descrizione: fs = rt0..31
Copia la word piu bassa di rt scrivendola sull’FPR fsEsempio: MTC1 r6,f5
Si supponga r5=0xAAAAAAAABBBBBBBB; MTC1 legge i 32 bit piubassi di r5 copiandoli nei 32 bit piu bassi di f5. Dopo l’ese-cuzione di MTC1, f5=0xXXXXXXXXBBBBBBBB; si noti che i suoi32 bit piu alti (XX..X) sono UNDEFINED (non sono statisovrascritti).
MUL.D
Sintassi: MUL.D fd, fs, ft
Descrizione: fd = fs×ftEccezioni: Overflow e Underflow vengono generati se il risultato non puo
essere rappresentato secondo lo standard IEEE754. InvalidOperation e generata se fs o ft contiene QNaN o SNaN, o sesi effettua un’operazione non valida (0×∞, QNaN×numero)
93
APPENDICE A. MANUALE UTENTE DELLA FPU DI EDUMIPS64
S.D (”DEPRECATED”: retrocompabitibilita con WinMIPS64)
Sintassi: S.D ft, offset(base)
Descrizione: memory[base+ offset] = ft
Copia la doubleword (64 bit) dell’FPR ft in memoria.
SDC1
Sintassi: SDC1 ft, offset(base)
Descrizione: memory[base+ offset] = ft
Salva la doubleword (64 bit) dell’FPR ft in memoria.
SUB.D
Sintassi: SUB.D fd, fs, ft
Descrizione: fd = fs-ft
Eccezioni: Overflow and Underflow vengono generati se il risultato nonpuo essere rappresentato secondo lo standard IEEE754. In-valid Operation e generata se fs o ft contengono QNaN oSNaN, o se viene eseguita un’operazione non valida (∞−∞).
SWC1
Sintassi: SWC1 ft, offset(base)
Descrizione: memory[base+ offset] = ft
Salva la word (32 bit) dell’FPR ft in memoria.
94
Bibliografia
[1] Andrea Spadaccini - traduzione italiana di Simona Ullo. Manuale utente
di EduMIPS64. http://www.edumips.org/attachment/wiki/Upload/Manual-
it.pdf.
[2] Dr. N. A. Harman, Department of Computer Science, Univer-
sity of Wales Swansea. High Performance Microprocessors.
http://www.cs.swan.ac.uk/csneal/.
[3] Gruppo di sviluppo di EduMIPS64. Sito web ufficiale.
http://www.edumips.org.
[4] Israel Koren - University of Massachussetts, Amherst. Computer Arithmetic
Algorithms. A K Peters Natick, Massachusetts, Second edition, 2002.
[5] John L. Hennessy, David A. Patterson. Computer Architecture - A
quantitative approach. Morgan Kaufmann, Third edition, 2002.
[6] MIPS Technologies Inc. MIPS R4000 Microprocessor Users Manual.
http://cag.csail.mit.edu/raw/documents/R4400 Uman book Ed2.pdf, 1994.
[7] MIPS Technologies Inc. MIPS64 Architecture For Programmers Volume I:
Introduction to MIPS64 Architecture. http://www.mips.com, Luglio 2005.
95
BIBLIOGRAFIA
[8] MIPS Technologies Inc. MIPS64 Architecture for Programmers Volume II:
The MIPS64 Instruction Set. http://www.mips.com, Luglio 2005.
[9] Morgan Kaufmann. See MIPS Run.
[10] Sivarama Dandamundi. Guide to RISC processors. Springer, 2005.
[11] Sun Microsystems, Inc. What Every Computer Scientist Should Know About
Floating-Point Arithmetic. http://docs-pdf.sun.com/800-7895/800-7895.pdf,
Giugno 1992.
[12] William N.Joy Co-Founder, and Vice President for Research Sun Microsys-
tems,Inc. RISC: Academic Interplay Drives Computer Performance Forward.
http://www.cs.washington.edu.
96