O ARM passou por uma progressão:
- Uma arquitetura de instruções de 32 bits, que possuía código mais volumoso do que muitas outras arquiteturas, mas que poderia ser decodificada rapidamente e realizar muitas operações com menos instruções do que as arquiteturas concorrentes
- Uma arquitetura de formato de instrução dupla, que pode alternar entre o conjunto de instruções ARM agradável e poderoso (mas infelizmente um pouco inchado) e um conjunto de instruções "Thumb" de 16 bits menos poderoso (mas muito mais compacto). Cada instrução Thumb tinha uma instrução ARM correspondente, minimizando um pouco a necessidade dos programadores aprenderem dois conjuntos de instruções.
- Uma arquitetura Thumb2, que adicionou instruções de duas palavras ao conjunto de instruções Thumb, produzindo o que é em geral uma situação em que todos saem ganhando: o código ARM típico conteria uma mistura de instruções que só estavam disponíveis no ARM e instruções que estariam disponíveis no Thumb mas teve que ser representado como 32 bits de qualquer maneira; no Thumb2, esse código obtém os benefícios de espaço de substituir algumas das instruções de 32 bits pelas de 16 bits.
- Uma arquitetura somente Thumb, que é mais limitadora do que eu gostaria, mas que é menor e mais barata que qualquer outra.
A arquitetura ARM permite que algumas operações bastante sofisticadas sejam executadas muito rapidamente - muito mais rapidamente do que em qualquer outro chip. Por exemplo (usando o ARM7-TDMI):
ldrh r0, [r10, # ADDR_BUS_OFS]; Leia o barramento de endereço do sistema de destino (13 bits)
ldrb r1, [r9, r0, lsr # 8]; Use bits superiores para procurar endereços em uma tabela de manipuladores
adicione pc, r9, r1 lsl # 2; Vá para o manipulador apropriado
Cada manipulador é armazenado como um byte, que fornece 1/4 do deslocamento do endereço desde o início da tabela. O efeito líquido é que, uma vez que o conteúdo do barramento de endereços foi buscado, são necessários apenas seis ciclos (duas instruções) para pular para um manipulador com base nos cinco bits superiores dos recuperados, usando uma tabela de salto de 32 bytes.
O código THUMB correspondente seria mais como:
; Supondo que não precisamos de r6 / r7 para mais nada, eles são reatribuídos a partir de r9 / r10
ldrh r0, [r7, # ADDR_BUS_OFS]
mov r1, r0
LSR R1, R1, # 8; THUMB requer que a origem e o destino sejam os mesmos
ldrb r1, [r6, r1]
LS1 R1, R1, # 1; Poderia usar shift-left-two, se os endereços de destino estivessem alinhados com a palavra completa
adicionar pc, r1
Tudo bem do ponto de vista da densidade de código, já que as instruções são apenas metade do tamanho dos originais, mas levariam nove ciclos após a busca, em vez de seis. Em um aplicativo em que o barramento sendo monitorado funcionará em sua própria velocidade, independentemente de o ARM ter gerenciado ou não, as instruções mais rápidas do ARM são uma grande vantagem.
Aliás, Thumb2 é binário compatível com Thumb, o que facilita o uso de ferramentas anteriores, mas significa que existem algumas coisas que ela não pode fazer tão bem quanto o ARM original. Por exemplo, no ARM, era possível "rotacionar" um bitmap 8x8 mantido em quatro registradores usando cerca de 3 instruções por dois bits:
movs r0, r4, lsl # 25; Coloque o bit superior do LSB em C e o próximo bit em N
orrcs r6, # 0x00000001
orrmi r6, # 0x00000100
No Thumb2, seria necessário adicionar instruções condicionais explícitas:
movs r0, r4, lsl # 25; Coloque o bit superior do LSB em C e o próximo bit em N
itcs
orrcs r6, # 0x00000001
itmi
orrmi r6, # 0x00000100
Redução líquida de 33% na eficiência de tempo e espaço em comparação com o ARM; é provavelmente o pior exemplo de código Thumb menos eficiente que o ARM, e mesmo isso não é exatamente horrível.
Uma outra pequena desvantagem do Thumb2 em comparação com o ARM: no código ARM, todas as instruções começam nos limites da palavra completa, facilitando a análise estática. No Thumb2, as instruções podem iniciar arbitrariamente nos limites da meia palavra e ultrapassar os limites da palavra completa. A análise estática pode, portanto, ser muito mais difícil.