Il ARM ha subito una progressione:
- Un'architettura con istruzioni a 32 bit, che aveva un codice più voluminoso rispetto a molte altre architetture, ma che poteva essere decodificata rapidamente e poteva eseguire molte operazioni con meno istruzioni rispetto alle architetture concorrenti
- Un'architettura in formato a doppia istruzione, che potrebbe alternare tra il set di istruzioni ARM bello e potente (ma purtroppo un po 'gonfio) e un set di istruzioni "Thumb" a 16 bit meno potente (ma molto più compatto). Ogni istruzione Thumb aveva un'istruzione ARM corrispondente, minimizzando in qualche modo la necessità per i programmatori di apprendere due set di istruzioni.
- Un'architettura Thumb2, che ha aggiunto istruzioni di due parole al set di istruzioni Thumb, producendo ciò che è per lo più un win-win: il tipico codice ARM conterrebbe un mix di istruzioni che erano disponibili solo nel ARM, e istruzioni che sarebbero state disponibili in Thumb ma doveva comunque essere rappresentato come 32 bit; in Thumb2, tale codice ottiene i vantaggi in termini di spazio della sostituzione di alcune delle istruzioni a 32 bit con quelle a 16 bit.
- Un'architettura solo per il pollice, che è più limitante di quanto mi piacerebbe, ma che è più piccola ed economica di tutte le altre.
L'architettura ARM consente di eseguire alcune operazioni piuttosto sofisticate molto rapidamente, molto più rapidamente rispetto a qualsiasi altro chip. Ad esempio (utilizzando ARM7-TDMI):
ldrh r0, [r10, # ADDR_BUS_OFS]; Lettura bus indirizzo sistema di destinazione (13 bit)
ldrb r1, [r9, r0, lsr # 8]; Utilizzare i bit superiori per cercare l'indirizzo in una tabella di gestori
aggiungi pc, r9, r1 lsl # 2; Vai al gestore appropriato
Ogni gestore è memorizzato come byte, che fornisce 1/4 dello spostamento dell'indirizzo dall'inizio della tabella. L'effetto netto è che una volta recuperati i contenuti del bus degli indirizzi, sono necessari solo sei cicli (due istruzioni) per passare a un gestore basato sui cinque bit superiori del recuperato, utilizzando una tabella di salto a 32 byte.
Il codice THUMB corrispondente sarebbe più simile a:
; Supponendo che non abbiamo bisogno di r6 / r7 per nient'altro, sono riassegnati da r9 / r10
ldrh r0, [r7, # ADDR_BUS_OFS]
mov r1, r0
lsr r1, r1, # 8; THUMB richiede che la sorgente e la destinazione siano uguali
ldrb r1, [r6, r1]
lsl r1, r1, # 1; Potrebbe usare shift-left-two, se gli indirizzi target fossero allineati a una parola intera
aggiungi pc, r1
Va bene dal punto di vista della densità del codice, dato che le istruzioni sono grandi solo la metà degli originali, ma richiederebbero nove cicli dopo il recupero anziché sei. In un'applicazione in cui il bus monitorato funzionerà alla propria velocità indipendentemente dal fatto che ARM sia riuscito a gestirlo, le istruzioni ARM più veloci sono un grande vantaggio.
Per inciso, Thumb2 è binario compatibile con Thumb, il che facilita l'uso di strumenti precedenti, ma significa che ci sono alcune cose che non può fare così come il ARM originale. Ad esempio, in ARM, si potrebbe "ruotare" una bitmap 8x8 contenuta in quattro registri usando circa 3 istruzioni per due bit:
mov r0, r4, lsl # 25; Inserisci il bit superiore di LSB in C e il bit successivo in N
orrcs r6, # 0x00000001
orrmi r6, # 0x00000100
In Thumb2, sarebbe necessario aggiungere istruzioni condizionali esplicite:
mov r0, r4, lsl # 25; Inserisci il bit superiore di LSB in C e il bit successivo in N
ITC
orrcs r6, # 0x00000001
ITMI
orrmi r6, # 0x00000100
Riduzione netta del 33% in termini di tempo ed efficienza dello spazio rispetto a ARM; questo è probabilmente un esempio nel caso peggiore in cui il codice Thumb sia meno efficiente di ARM, e anche questo non è esattamente orribile.
Un altro piccolo svantaggio di Thumb2 rispetto a ARM: nel codice ARM, tutte le istruzioni iniziano a confini di parole intere, facilitando l'analisi statica. In Thumb2, le istruzioni possono iniziare arbitrariamente a limiti di mezza parola e a cavallo di limiti di parole intere. L'analisi statica può quindi essere molto più difficile.