L’architettura ARM a 32 bit, come ARMv7-A (che implementa AArch32; vedi la sezione su ARMv8-A per saperne di più), è stata l’architettura più utilizzata nei dispositivi mobili a partire dal 2011.
Dal 1995, l’ARM Architecture Reference Manual è stata la fonte primaria di documentazione sull’architettura del processore ARM e sul set di istruzioni, distinguendo le interfacce che tutti i processori ARM devono supportare (come la semantica delle istruzioni) dai dettagli di implementazione che possono variare. L’architettura si è evoluta nel tempo, e la versione sette dell’architettura, ARMv7, definisce tre “profili” di architettura:
- A-profile, il profilo “Application”, implementato dai core a 32 bit della serie Cortex-A e da alcuni core non ARM
- R-profile, il profilo “Real-time”, implementato dai core della serie Cortex-R
- M-profile, il profilo “Microcontroller”, implementato dalla maggior parte dei core della serie Cortex-M
Anche se i profili di architettura sono stati definiti inizialmente per ARMv7, ARM ha successivamente definito l’architettura ARMv6-M (usata dai Cortex M0/M0+/M1) come un sottoinsieme del profilo ARMv7-M con meno istruzioni.
Modalità della CPUModifica
A parte il profilo M, l’architettura ARM a 32 bit specifica diverse modalità della CPU, a seconda delle caratteristiche dell’architettura implementata. In qualsiasi momento, la CPU può essere in una sola modalità, ma può cambiare modalità a causa di eventi esterni (interrupt) o programmaticamente.
- Modalità utente: L’unica modalità non privilegiata.
- Modalità FIQ: Una modalità privilegiata che viene attivata ogni volta che il processore accetta una richiesta di interrupt veloce.
- Modalità IRQ: Una modalità privilegiata in cui si entra ogni volta che il processore accetta un interrupt.
- Modalità supervisore (svc): Una modalità privilegiata in cui si entra ogni volta che la CPU viene resettata o quando viene eseguita un’istruzione SVC.
- Modalità Abort: Una modalità privilegiata in cui si entra ogni volta che si verifica un’eccezione di interruzione del prefetch o di interruzione dei dati.
- Modalità indefinita: Una modalità privilegiata che viene attivata ogni volta che si verifica un’eccezione per un’istruzione non definita.
- Modalità sistema (ARMv4 e superiore): L’unica modalità privilegiata che non viene attivata da un’eccezione. Si può entrare solo eseguendo un’istruzione che scrive esplicitamente i bit di modalità del Current Program Status Register (CPSR) da un’altra modalità privilegiata (non dalla modalità utente).
- Modalità monitor (ARMv6 e ARMv7 Security Extensions, ARMv8 EL3): Viene introdotta una modalità monitor per supportare l’estensione TrustZone nei core ARM.
- Modalità Hyp (ARMv7 Virtualization Extensions, ARMv8 EL2): Una modalità hypervisor che supporta i requisiti di virtualizzazione Popek e Goldberg per il funzionamento non sicuro della CPU.
- Modalità thread (ARMv6-M, ARMv7-M, ARMv8-M): Una modalità che può essere specificata come privilegiata o non privilegiata. Se viene usato il Main Stack Pointer (MSP) o il Process Stack Pointer (PSP) può anche essere specificato nel registro CONTROL con accesso privilegiato. Questa modalità è progettata per compiti utente in ambiente RTOS ma è tipicamente usata in bare-metal per il super-loop.
- Modalità Handler (ARMv6-M, ARMv7-M, ARMv8-M): Una modalità dedicata alla gestione delle eccezioni (tranne i RESET che sono gestiti in modalità Thread). La modalità Handler usa sempre MSP e lavora a livello privilegiato.
Instruction setEdit
L’implementazione ARM originale (e successive) era cablata senza microcodice, come il molto più semplice processore a 8 bit 6502 usato nei precedenti microcomputer Acorn.
L’architettura ARM a 32 bit (e quella a 64 bit per la maggior parte) include le seguenti caratteristiche RISC:
- Architettura load/store.
- Nessun supporto per gli accessi di memoria non allineati nella versione originale dell’architettura. ARMv6 e successive, eccetto alcune versioni di microcontrollori, supportano accessi non allineati per istruzioni load/store di mezza parola e di una sola parola con alcune limitazioni, come l’atomicità non garantita.
- File di registro uniforme di 16 × 32 bit (incluso il contatore del programma, il puntatore dello stack e il registro di collegamento).
- Larghezza fissa delle istruzioni di 32 bit per facilitare la decodifica e il pipelining, al costo di una minore densità del codice. Più tardi, il set di istruzioni Thumb aggiunse istruzioni a 16 bit e aumentò la densità del codice.
- Esecuzione per lo più a ciclo di clock singolo.
Per compensare il design più semplice, rispetto a processori come l’Intel 80286 e il Motorola 68020, furono usate alcune caratteristiche di design aggiuntive:
- L’esecuzione condizionale della maggior parte delle istruzioni riduce l’overhead di diramazione e compensa la mancanza di un predittore di ramo nei primi chip.
- Le istruzioni aritmetiche alterano i codici di condizione solo quando desiderato.
- Il barrel shifter a 32 bit può essere usato senza penalità di prestazioni con la maggior parte delle istruzioni aritmetiche e dei calcoli di indirizzo.
- Ha potenti modalità di indirizzamento indicizzato.
- Un registro di collegamento supporta rapide chiamate di funzioni foglia.
- Un semplice, ma veloce, sottosistema di interrupt a 2 livelli di priorità ha cambiato banco di registro.
Istruzioni aritmeticheModifica
ARM include operazioni aritmetiche intere per aggiungere, sottrarre e moltiplicare; alcune versioni dell’architettura supportano anche le operazioni di divisione.
ARM supporta moltiplicazioni 32-bit × 32-bit con un risultato a 32-bit o 64-bit, anche se i core Cortex-M0 / M0+ / M1 non supportano risultati a 64-bit. Alcuni core ARM supportano anche moltiplicazioni 16-bit × 16-bit e 32-bit × 16-bit.
Le istruzioni di divisione sono incluse solo nelle seguenti architetture ARM:
- ARMv7-M e ARMv7E-M includono sempre istruzioni di divisione.
- L’architettura ARMv7-R include sempre le istruzioni di divisione nel set di istruzioni Thumb, ma opzionalmente nel suo set di istruzioni a 32 bit.
- L’architettura ARMv7-A include opzionalmente le istruzioni di divisione. Le istruzioni potrebbero non essere implementate, o implementate solo nel set di istruzioni Thumb, o implementate in entrambi i set di istruzioni Thumb e ARM, o implementate se sono incluse le estensioni di virtualizzazione.
RegistersEdit
usr | sys | svc | abt | und | irq | fiq | |
---|---|---|---|---|---|---|---|
R0 | |||||||
R1 | |||||||
R2 | |||||||
R3 | |||||||
R4 | |||||||
R5 | |||||||
R6 | |||||||
R7 | |||||||
R8 | R8_fiq | ||||||
R9 | R9_fiq | ||||||
R10 | R10_fiq | ||||||
R11 | R11_fiq | ||||||
R12 | R12_fiq | ||||||
R13 | R13_svc | R13_abt | R13_und | R13_irq | R13_fiq | ||
R14 | R14_svc | R14_abt | R14_und | R14_irq | R14_irq | R14_fiq | |
R15 | |||||||
CPSR | |||||||
SPSR_svc | SPSR_abt | SPSR_und | SPSR_irq | SPSR_fiq |
I registri da R0 a R7 sono gli stessi in tutte le modalità CPU; non sono mai bancati.
I registri da R8 a R12 sono gli stessi in tutte le modalità della CPU eccetto la modalità FIQ. La modalità FIQ ha i propri registri distinti da R8 a R12.
R13 e R14 sono bancati in tutte le modalità privilegiate della CPU eccetto la modalità sistema. Cioè, ogni modalità in cui si può entrare a causa di un’eccezione ha i propri R13 e R14. Questi registri generalmente contengono rispettivamente il puntatore allo stack e l’indirizzo di ritorno dalle chiamate di funzione.
Alias:
- R13 è indicato anche come SP, il puntatore allo stack.
- R14 è indicato anche come LR, il registro di collegamento.
- R15 è indicato anche come PC, il contatore di programma.
Il Current Program Status Register (CPSR) ha i seguenti 32 bit.
- M (bit 0-4) è il bit di modalità del processore.
- T (bit 5) è il bit di stato Thumb.
- F (bit 6) è il bit di disabilitazione FIQ.
- I (bit 7) è il bit di disabilitazione IRQ.
- A (bit 8) è il bit di disabilitazione dell’interruzione dei dati imprecisi.
- E (bit 9) è il bit di endianness dei dati.
- IT (bit 10-15 e 25-26) è il bit di stato if-then.
- GE (bit 16-19) è il bit greater-than-or-equal-to.
- DNM (bit 20-23) è il bit do not modify.
- J (bit 24) è il bit di stato Java.
- Q (bit 27) è il bit sticky overflow.
- V (bit 28) è il bit di overflow.
- C (bit 29) è il bit di riporto/prestito/estensione.
- Z (bit 30) è il bit di zero.
- N (bit 31) è il bit negativo/meno che.
Esecuzione condizionaleModifica
Quasi ogni istruzione ARM ha una caratteristica di esecuzione condizionale chiamata predicazione, che è implementata con un selettore di codice condizione a 4 bit (il predicato). Per consentire l’esecuzione incondizionata, uno dei codici a quattro bit fa sì che l’istruzione sia sempre eseguita. La maggior parte delle altre architetture di CPU hanno solo codici di condizione sulle istruzioni di diramazione.
Anche se il predicato occupa quattro dei 32 bit del codice di un’istruzione, e quindi riduce significativamente i bit di codifica disponibili per gli spostamenti nelle istruzioni di accesso alla memoria, evita le istruzioni di diramazione quando genera il codice per piccole if
dichiarazioni. Oltre ad eliminare le istruzioni di diramazione stesse, questo preserva la pipeline di fetch/decodifica/esecuzione al costo di un solo ciclo per ogni istruzione saltata.
Un algoritmo che fornisce un buon esempio di esecuzione condizionale è l’algoritmo euclideo basato sulla sottrazione per il calcolo del massimo comune divisore. Nel linguaggio di programmazione C, l’algoritmo può essere scritto come:
int gcd(int a, int b) { while (a != b) // We enter the loop when a<b or a>b, but not when a==b if (a > b) // When a>b we do this a -= b; else // When a<b we do that (no if(a<b) needed since a!=b is checked in while condition) b -= a; return a;}
Lo stesso algoritmo può essere riscritto in un modo più vicino alle istruzioni ARM target come:
loop: // Compare a and b GT = a > b; LT = a < b; NE = a != b; // Perform operations based on flag results if(GT) a -= b; // Subtract *only* if greater-than if(LT) b -= a; // Subtract *only* if less-than if(NE) goto loop; // Loop *only* if compared values were not equal return a;
e codificato in linguaggio assembly come:
; assign a to register r0, b to r1loop: CMP r0, r1 ; set condition "NE" if (a != b), ; "GT" if (a > b), ; or "LT" if (a < b) SUBGT r0, r0, r1 ; if "GT" (Greater Than), a = a-b; SUBLT r1, r1, r0 ; if "LT" (Less Than), b = b-a; BNE loop ; if "NE" (Not Equal), then loop B lr ; if the loop is not entered, we can safely return
che evita i rami intorno alle clausole then
e else
. Se r0
e r1
sono uguali allora nessuna delle istruzioni SUB
sarà eseguita, eliminando la necessità di un ramo condizionale per implementare il controllo while
all’inizio del ciclo, per esempio se fosse stato usato SUBLE
(meno di o uguale).
Uno dei modi in cui il codice Thumb fornisce una codifica più densa è quello di rimuovere il selettore a quattro bit dalle istruzioni non-branch.
Altre caratteristicheModifica
Un’altra caratteristica del set di istruzioni è l’abilità di piegare gli spostamenti e le rotazioni nelle istruzioni di “elaborazione dati” (aritmetica, logica e spostamento del registro), in modo che, per esempio, l’istruzione C
a += (j << 2);
potrebbe essere resa come una singola parola, istruzione a ciclo singolo:
ADD Ra, Ra, Rj, LSL #2
Questo fa sì che il tipico programma ARM sia più denso del previsto con meno accessi alla memoria; quindi la pipeline viene utilizzata in modo più efficiente.
Il processore ARM ha anche caratteristiche raramente viste in altre architetture RISC, come l’indirizzamento relativo al PC (infatti, sull’ARM a 32 bit il PC è uno dei suoi 16 registri) e le modalità di indirizzamento pre- e post-incremento.
Il set di istruzioni ARM è aumentato nel tempo. Alcuni dei primi processori ARM (prima di ARM7TDMI), per esempio, non hanno istruzioni per memorizzare una quantità di due byte.
Pipeline e altri problemi di implementazioneModifica
L’ARM7 e le implementazioni precedenti hanno una pipeline a tre fasi; le fasi sono fetch, decodifica ed esecuzione. I design più performanti, come l’ARM9, hanno pipeline più profonde: Il Cortex-A8 ha tredici stadi. Ulteriori modifiche all’implementazione per prestazioni più elevate includono un adder più veloce e una logica di predizione di ramo più estesa. La differenza tra i core ARM7DI e ARM7DMI, per esempio, era un moltiplicatore migliorato; da qui l’aggiunta della “M”.
CoprocessoriModifica
L’architettura ARM (pre-ARMv8) fornisce un modo non intrusivo di estendere il set di istruzioni usando “coprocessori” che possono essere indirizzati usando istruzioni MCR, MRC, MRRC, MCRR e simili. Lo spazio dei coprocessori è diviso logicamente in 16 coprocessori con numeri da 0 a 15; il coprocessore 15 (cp15) è riservato ad alcune tipiche funzioni di controllo come la gestione delle cache e il funzionamento della MMU sui processori che ne hanno una.
Nelle macchine basate su ARM, le periferiche sono solitamente collegate al processore mappando i loro registri fisici nello spazio di memoria ARM, nello spazio del coprocessore, o collegandosi ad un altro dispositivo (un bus) che a sua volta si collega al processore. Gli accessi ai coprocessori hanno una latenza più bassa, così alcune periferiche – per esempio, un controller di interrupt XScale – sono accessibili in entrambi i modi: attraverso la memoria e attraverso i coprocessori.
In altri casi, i progettisti di chip integrano l’hardware solo usando il meccanismo del coprocessore. Per esempio, un motore di elaborazione delle immagini potrebbe essere un piccolo core ARM7TDMI combinato con un coprocessore che ha operazioni specializzate per supportare uno specifico set di primitive di transcodifica HDTV.
DebuggingEdit
Tutti i moderni processori ARM includono strutture di debug hardware, permettendo ai debugger software di eseguire operazioni come l’arresto, lo stepping e il breakpointing del codice a partire dal reset. Queste strutture sono costruite utilizzando il supporto JTAG, anche se alcuni core più recenti supportano opzionalmente il protocollo “SWD” a due fili di ARM. Nei core ARM7TDMI, la “D” rappresenta il supporto al debug JTAG, e la “I” rappresenta la presenza di un modulo di debug “EmbeddedICE”. Per le generazioni di core ARM7 e ARM9, EmbeddedICE su JTAG era uno standard di debug de facto, anche se non garantito architettonicamente.
L’architettura ARMv7 definisce strutture di debug di base a livello architettonico. Queste includono i breakpoint, i watchpoint e l’esecuzione delle istruzioni in un “Debug Mode”; strutture simili erano disponibili anche con EmbeddedICE. Sono supportati sia il debug in modalità “halt” che quello in modalità “monitor”. L’effettivo meccanismo di trasporto usato per accedere alle strutture di debug non è architettonicamente specificato, ma le implementazioni generalmente includono il supporto JTAG.
C’è un’architettura di debug ARM “CoreSight” separata, che non è architettonicamente richiesta dai processori ARMv7.
Debug Access PortEdit
La Debug Access Port (DAP) è un’implementazione di una ARM Debug Interface.Ci sono due diverse implementazioni supportate, la Serial Wire JTAG Debug Port (SWJ-DP) e la Serial Wire Debug Port (SW-DP).CMSIS-DAP è un’interfaccia standard che descrive come vari software di debug su un PC host possono comunicare tramite USB al firmware in esecuzione su un debugger hardware, che a sua volta parla tramite SWD o JTAG a una CPU ARM Cortex abilitata CoreSight.
Istruzioni di miglioramento DSPModifica
Per migliorare l’architettura ARM per l’elaborazione del segnale digitale e le applicazioni multimediali, sono state aggiunte al set istruzioni DSP. Queste sono significate da una “E” nel nome delle architetture ARMv5TE e ARMv5TEJ. Le varianti E implicano anche T, D, M e I.
Le nuove istruzioni sono comuni nelle architetture di processori di segnali digitali (DSP). Includono variazioni su moltiplicatore-accumulatore firmato, addizione e sottrazione satura, e conteggio degli zeri iniziali.
Estensioni SIMD per multimediaEdit
Introdotto nell’architettura ARMv6, questo era un precursore di Advanced SIMD, noto anche come Neon.
JazelleEdit
Jazelle DBX (Direct Bytecode eXecution) è una tecnica che permette al bytecode Java di essere eseguito direttamente nell’architettura ARM come un terzo stato di esecuzione (e set di istruzioni) accanto agli esistenti ARM e Thumb-mode. Il supporto per questo stato è indicato dalla “J” nell’architettura ARMv5TEJ, e nei nomi dei core ARM9EJ-S e ARM7EJ-S. Il supporto per questo stato è richiesto a partire da ARMv6 (tranne che per il profilo ARMv7-M), anche se i core più recenti includono solo una banale implementazione che non fornisce alcuna accelerazione hardware.
ThumbEdit
Per migliorare la densità del codice compilato, i processori dal ARM7TDMI (rilasciato nel 1994) hanno caratterizzato il set di istruzioni Thumb, che hanno il loro stato. (La “T” in “TDMI” indica la caratteristica Thumb.) Quando è in questo stato, il processore esegue il set di istruzioni Thumb, una codifica compatta a 16 bit per un sottoinsieme del set di istruzioni ARM. La maggior parte delle istruzioni Thumb sono direttamente mappate su normali istruzioni ARM. Il risparmio di spazio deriva dal rendere impliciti alcuni degli operandi delle istruzioni e dal limitare il numero di possibilità rispetto alle istruzioni ARM eseguite nello stato di set di istruzioni ARM.
In Thumb, gli opcodes a 16 bit hanno meno funzionalità. Per esempio, solo i rami possono essere condizionati, e molti opcodes sono limitati ad accedere solo alla metà di tutti i registri general-purpose della CPU. Gli opcodes più corti danno una migliore densità di codice nel complesso, anche se alcune operazioni richiedono istruzioni extra. In situazioni in cui la porta di memoria o la larghezza del bus sono limitate a meno di 32 bit, gli opcodes Thumb più corti permettono un aumento delle prestazioni rispetto al codice ARM a 32 bit, poiché meno codice di programma può dover essere caricato nel processore sulla larghezza di banda di memoria limitata.
A differenza delle architetture di processori con istruzioni di lunghezza variabile (16- o 32-bit), come il Cray-1 e Hitachi SuperH, i set di istruzioni ARM e Thumb esistono indipendentemente uno dall’altro. Gli hardware embedded, come il Game Boy Advance, hanno tipicamente una piccola quantità di RAM accessibile con un datapath completo a 32 bit; la maggior parte è accessibile tramite un datapath secondario a 16 bit o più stretto. In questa situazione, di solito ha senso compilare il codice Thumb e ottimizzare a mano alcune delle sezioni più impegnative per la CPU usando istruzioni ARM a 32 bit, mettendo queste istruzioni più ampie nella memoria accessibile dal bus a 32 bit.
Il primo processore con un decoder di istruzioni Thumb fu l’ARM7TDMI. Tutte le famiglie ARM9 e successive, inclusa XScale, hanno incluso un decoder di istruzioni Thumb. Esso include istruzioni adottate dall’Hitachi SuperH (1992), che è stato concesso in licenza da ARM. Le famiglie di processori più piccole di ARM (Cortex M0 e M1) implementano solo il set di istruzioni Thumb a 16 bit per le massime prestazioni nelle applicazioni a più basso costo.
Thumb-2Edit
La tecnologia Thumb-2 fu introdotta nel core ARM1156, annunciato nel 2003. Thumb-2 estende il limitato set di istruzioni a 16 bit di Thumb con ulteriori istruzioni a 32 bit per dare più ampiezza al set di istruzioni, producendo così un set di istruzioni a lunghezza variabile. Un obiettivo dichiarato per Thumb-2 era quello di raggiungere una densità di codice simile a Thumb con prestazioni simili al set di istruzioni ARM su una memoria a 32 bit.
Thumb-2 estende il set di istruzioni Thumb con la manipolazione di campi di bit, rami di tabella e l’esecuzione condizionale. Allo stesso tempo, il set di istruzioni ARM è stato esteso per mantenere funzionalità equivalenti in entrambi i set di istruzioni. Un nuovo “Unified Assembly Language” (UAL) supporta la generazione di istruzioni Thumb o ARM dallo stesso codice sorgente; le versioni di Thumb viste sui processori ARMv7 sono essenzialmente capaci quanto il codice ARM (inclusa la capacità di scrivere gestori di interrupt). Questo richiede un po’ di attenzione, e l’uso di una nuova istruzione “IT” (if-then), che permette l’esecuzione di fino a quattro istruzioni successive basate su una condizione testata, o sul suo inverso. Quando si compila in codice ARM, questo viene ignorato, ma quando si compila in Thumb genera un’istruzione vera e propria. Per esempio:
; if (r0 == r1)CMP r0, r1ITE EQ ; ARM: no code ... Thumb: IT instruction; then r0 = r2;MOVEQ r0, r2 ; ARM: conditional; Thumb: condition via ITE 'T' (then); else r0 = r3;MOVNE r0, r3 ; ARM: conditional; Thumb: condition via ITE 'E' (else); recall that the Thumb MOV instruction has no bits to encode "EQ" or "NE".
Tutti i chip ARMv7 supportano il set di istruzioni Thumb. Tutti i chip delle serie Cortex-A, Cortex-R e ARM11 supportano sia lo “stato del set di istruzioni ARM” che lo “stato del set di istruzioni Thumb”, mentre i chip della serie Cortex-M supportano solo il set di istruzioni Thumb.
Thumb Execution Environment (ThumbEE)Edit
ThumbEE (erroneamente chiamato Thumb-2EE in alcuni documenti ARM), che è stato commercializzato come Jazelle RCT (Runtime Compilation Target), è stato annunciato nel 2005, apparendo per la prima volta nel processore Cortex-A8. ThumbEE è un quarto stato del set di istruzioni, che apporta piccole modifiche al set di istruzioni esteso Thumb-2. Queste modifiche rendono il set di istruzioni particolarmente adatto al codice generato in fase di esecuzione (ad esempio dalla compilazione JIT) in ambienti di esecuzione gestiti. ThumbEE è un obiettivo per linguaggi come Java, C#, Perl e Python, e permette ai compilatori JIT di produrre codice compilato più piccolo senza impatto sulle prestazioni.
Le nuove caratteristiche fornite da ThumbEE includono controlli automatici dei puntatori nulli su ogni istruzione di caricamento e memorizzazione, un’istruzione per eseguire un controllo dei limiti dell’array e istruzioni speciali che chiamano un gestore. Inoltre, poiché utilizza la tecnologia Thumb-2, ThumbEE fornisce l’accesso ai registri r8-r15 (dove è tenuto lo stato della Jazelle/DBX Java VM). I gestori sono piccole sezioni di codice chiamate frequentemente, comunemente usate per implementare linguaggi di alto livello, come l’allocazione di memoria per un nuovo oggetto. Questi cambiamenti derivano dal riproporre una manciata di opcodes, e dal sapere che il core è nel nuovo stato ThumbEE.
Il 23 novembre 2011, Arm Holdings ha deprecato qualsiasi uso del set di istruzioni ThumbEE, e ARMv8 rimuove il supporto per ThumbEE.
Floating-point (VFP)Edit
La tecnologia VFP (Vector Floating Point) è un’estensione del coprocessore FPU (floating-point unit) all’architettura ARM (implementata diversamente in ARMv8 – coprocessori non definiti). Fornisce a basso costo calcoli in virgola mobile a singola e doppia precisione pienamente conformi allo standard ANSI/IEEE Std 754-1985 per l’aritmetica binaria a virgola mobile. VFP fornisce un calcolo in virgola mobile adatto a un ampio spettro di applicazioni come PDA, smartphone, compressione e decompressione della voce, grafica tridimensionale e audio digitale, stampanti, set-top box e applicazioni automotive. L’architettura VFP doveva supportare l’esecuzione di brevi istruzioni in “modalità vettoriale”, ma queste operavano su ogni elemento vettoriale in modo sequenziale e quindi non offrivano le prestazioni del vero parallelismo vettoriale SIMD (single instruction, multiple data). Questa modalità vettoriale è stata quindi rimossa poco dopo la sua introduzione, per essere sostituita dal molto più potente Advanced SIMD, noto anche come Neon.
Alcuni dispositivi come l’ARM Cortex-A8 hanno un modulo VFPLite ridotto invece di un modulo VFP completo, e richiedono circa dieci volte più cicli di clock per operazione float. L’architettura pre-ARMv8 ha implementato il floating-point/SIMD con l’interfaccia del coprocessore. Altre unità in virgola mobile e/o SIMD trovate nei processori basati su ARM che utilizzano l’interfaccia del coprocessore includono FPA, FPE, iwMMXt, alcune delle quali sono state implementate in software tramite trapping ma avrebbero potuto essere implementate in hardware. Essi forniscono alcune delle stesse funzionalità di VFP ma non sono opcode-compatibili con esso. FPA10 fornisce anche la precisione estesa, ma implementa l’arrotondamento corretto (richiesto da IEEE 754) solo in singola precisione.
VFPv1 Obsoleto VFPv2 Un’estensione opzionale al set di istruzioni ARM nelle architetture ARMv5TE, ARMv5TEJ e ARMv6. VFPv2 ha 16 registri FPU a 64 bit. VFPv3 o VFPv3-D32 Implementato sulla maggior parte dei processori ARMv7 Cortex-A8 e A9. È compatibile all’indietro con VFPv2, eccetto che non può catturare eccezioni in virgola mobile. VFPv3 ha 32 registri FPU a 64 bit come standard, aggiunge istruzioni VCVT per convertire tra scalari, float e doppi, aggiunge la modalità immediata a VMOV in modo che le costanti possano essere caricate nei registri FPU. VFPv3-D16 Come sopra, ma con solo 16 registri FPU a 64 bit. Implementato sui processori Cortex-R4 e R5 e sul Tegra 2 (Cortex-A9). VFPv3-F16 Non comune; supporta la virgola mobile a mezza precisione (16-bit) IEEE754-2008 come formato di memorizzazione. VFPv4 o VFPv4-D32 Implementato sui processori ARMv7 Cortex-A12 e A15, Cortex-A7 opzionalmente ha VFPv4-D32 nel caso di una FPU con Neon. VFPv4 ha 32 registri FPU a 64 bit come standard, aggiunge alle caratteristiche di VFPv3 sia il supporto dell’half-precision come formato di memorizzazione che le istruzioni fuse multiply-accumulate. VFPv4-D16 Come sopra, ma ha solo 16 registri FPU a 64 bit. Implementato sui processori Cortex-A5 e A7 nel caso di una FPU senza Neon. VFPv5-D16-M Implementato su Cortex-M7 quando esiste l’opzione core floating-point a singola e doppia precisione.
In Debian GNU/Linux, e derivati come Ubuntu e Linux Mint, armhf (ARM hard float) si riferisce all’architettura ARMv7 compresa l’estensione hardware aggiuntiva in virgola mobile VFP3-D16 (e Thumb-2) di cui sopra. I pacchetti software e gli strumenti di cross-compilazione usano i suffissi armhf vs. arm/armel per differenziare.
Advanced SIMD (Neon)Edit
L’estensione Advanced SIMD (aka Neon o “MPE” Media Processing Engine) è un set di istruzioni SIMD combinato a 64 e 128 bit che fornisce un’accelerazione standardizzata per applicazioni di elaborazione dei media e dei segnali. Neon è incluso in tutti i dispositivi Cortex-A8, ma è opzionale nei dispositivi Cortex-A9. Neon può eseguire la decodifica audio MP3 su CPU che funzionano a 10 MHz e può eseguire il codec vocale GSM adaptive multi-rate (AMR) a 13 MHz. È dotato di un set di istruzioni completo, file di registro separati e hardware di esecuzione indipendente. Neon supporta 8-, 16-, 32- e 64-bit interi e dati in virgola mobile a singola precisione (32-bit) e operazioni SIMD per gestire l’elaborazione audio e video così come l’elaborazione grafica e di gioco. In Neon, il SIMD supporta fino a 16 operazioni contemporaneamente. L’hardware Neon condivide gli stessi registri in virgola mobile usati in VFP. Dispositivi come ARM Cortex-A8 e Cortex-A9 supportano vettori a 128 bit, ma vengono eseguiti con 64 bit alla volta, mentre i più recenti Cortex-A15 possono eseguire 128 bit alla volta.
Una stranezza di Neon nei dispositivi ARMv7 è che azzera tutti i numeri subnormali, e di conseguenza il compilatore GCC non lo userà a meno che -funsafe-math-optimizations
, che permette di perdere i denormali, sia attivato. Il Neon “Enhanced” definito da ARMv8 non ha questa stranezza, ma a partire da GCC 8.2 lo stesso flag è ancora richiesto per abilitare le istruzioni Neon. D’altra parte, GCC considera Neon sicuro su AArch64 per ARMv8.
ProjectNe10 è il primo progetto open-source di ARM (dal suo inizio; mentre hanno acquisito un progetto più vecchio, ora conosciuto come Mbed TLS). La libreria Ne10 è un insieme di funzioni comuni e utili scritte sia in Neon che in C (per compatibilità). La libreria è stata creata per permettere agli sviluppatori di usare le ottimizzazioni Neon senza imparare Neon, ma serve anche come un insieme di esempi di codice Neon intrinseco e assembly altamente ottimizzato per comuni routine DSP, aritmetiche e di elaborazione delle immagini. Il codice sorgente è disponibile su GitHub.
ARM Helium technologyEdit
Helium è la M-Profile Vector Extension (MVE). Aggiunge più di 150 istruzioni scalari e vettoriali.
Estensioni di sicurezzaModifica
TrustZone (per il profilo Cortex-A)Modifica
Le estensioni di sicurezza, commercializzate come tecnologia TrustZone, sono in ARMv6KZ e architetture di profilo applicativo successive. Fornisce un’alternativa a basso costo all’aggiunta di un altro core di sicurezza dedicato a un SoC, fornendo due processori virtuali supportati da un controllo di accesso basato sull’hardware. Questo permette al core dell’applicazione di passare tra due stati, indicati come mondi (per ridurre la confusione con altri nomi per i domini di capacità), al fine di prevenire la fuga di informazioni dal mondo più fidato al mondo meno fidato. Questo cambio di mondo è generalmente ortogonale a tutte le altre capacità del processore, così ogni mondo può operare indipendentemente dall’altro pur utilizzando lo stesso core. La memoria e le periferiche sono quindi rese consapevoli del mondo operativo del core e possono usarlo per fornire il controllo dell’accesso ai segreti e al codice sul dispositivo.
Tipicamente, un ricco sistema operativo viene eseguito nel mondo meno fidato, con un codice specializzato in sicurezza più piccolo nel mondo più fidato, allo scopo di ridurre la superficie di attacco. Le applicazioni tipiche includono la funzionalità DRM per il controllo dell’uso dei media sui dispositivi basati su ARM, e la prevenzione di qualsiasi uso non approvato del dispositivo.
In pratica, poiché i dettagli specifici di implementazione delle implementazioni proprietarie TrustZone non sono stati divulgati pubblicamente per la revisione, non è chiaro quale livello di garanzia sia fornito per un dato modello di minaccia, ma non sono immuni da attacchi.
Open Virtualization è un’implementazione open source dell’architettura trusted world per TrustZone.
AMD ha concesso in licenza e incorporato la tecnologia TrustZone nella sua Secure Processor Technology. Abilitate in alcuni prodotti, ma non in tutti, le APU di AMD includono un processore Cortex-A5 per gestire l’elaborazione sicura. In effetti, il core Cortex-A5 TrustZone era stato incluso nei precedenti prodotti AMD, ma non è stato abilitato a causa di limiti di tempo.
Samsung Knox usa TrustZone per scopi come il rilevamento di modifiche al kernel.
TrustZone per ARMv8-M (per il profilo Cortex-M)Edit
La Security Extension, commercializzata come TrustZone per la tecnologia ARMv8-M, è stata introdotta nell’architettura ARMv8-M. Pur contenendo concetti simili a TrustZone per ARMv8-A, ha un design architettonico diverso, in quanto la commutazione del mondo viene eseguita utilizzando istruzioni di ramo invece di utilizzare le eccezioni. Supporta anche la gestione sicura degli interrupt interleaved da entrambi i mondi, indipendentemente dallo stato di sicurezza corrente. Insieme queste caratteristiche forniscono chiamate a bassa latenza al mondo sicuro e una gestione degli interrupt reattiva. ARM fornisce uno stack di riferimento di codice del mondo sicuro sotto forma di Trusted Firmware per M e PSA Certified.
No-execute page protectionEdit
A partire da ARMv6, l’architettura ARM supporta la no-execute page protection, che è indicata come XN, per eXecute Never.
Large Physical Address Extension (LPAE)Edit
La Large Physical Address Extension (LPAE), che estende la dimensione dell’indirizzo fisico da 32 bit a 40 bit, è stata aggiunta all’architettura ARMv7-A nel 2011. La dimensione dell’indirizzo fisico è maggiore, 44 bit, nel Cortex-A75 e nel Cortex-A65AE.
ARMv8-R e ARMv8-MEdit
Le architetture ARMv8-R e ARMv8-M, annunciate dopo l’architettura ARMv8-A, condividono alcune caratteristiche con ARMv8-A, ma non includono alcuna istruzione AArch64 a 64 bit.
ARMv8.1-MEdit
L’architettura ARMv8.1-M, annunciata nel febbraio 2019, è un miglioramento dell’architettura ARMv8-M. Porta nuove caratteristiche tra cui:
- Una nuova estensione del set di istruzioni vettoriali. La M-Profile Vector Extension (MVE), o Helium, è per l’elaborazione dei segnali e le applicazioni di apprendimento automatico.
- Miglioramenti aggiuntivi del set di istruzioni per loop e rami (Low Overhead Branch Extension).
- Istruzioni per il supporto dell’half-precision floating-point.
- Miglioramento del set di istruzioni per la gestione TrustZone per la Floating Point Unit (FPU).
- Nuovo attributo di memoria nella Memory Protection Unit (MPU).
- Miglioramenti nel debug tra cui Performance Monitoring Unit (PMU), Unprivileged Debug Extension, e un ulteriore supporto al debug focalizzato sugli sviluppi delle applicazioni di elaborazione dei segnali.
- Estensione di Affidabilità, Disponibilità e Servibilità (RAS).