Para entender os formatos de instruções do MIPS I, você precisa entender o pipeline do MIPS e também pensar na tecnologia de implementação da CPU por volta de 1985. Se você olhar o diagrama (você conhece esse), verá que a leitura do arquivo de registro está na Estágio de identificação, logo após o IF.
Para os fins de uma instrução do tipo R, o estágio ID precisa executar as seguintes tarefas:
- Determine que na verdade é uma instrução do tipo R.
- Nesse caso, diga ao arquivo de registro para carregar valores dos registros.
Para os fins desta discussão, é a primeira tarefa em que você precisa pensar. Se houver muito trabalho de decodificação de instruções que você precisa fazer para resolver, mesmo se precisar de algum valor dos registros, isso aumenta o atraso antes que você possa iniciar as leituras do registro. Também aumenta a complexidade do estágio de ID. Ao reservar um único código de operação para todas as instruções do tipo R, você reduz a complexidade ao mínimo.
Parece um pouco estranho que você dedique cinco bits apenas à mudança. Eu posso pensar em algumas explicações possíveis. Uma é que simplifica o roteamento (esses cinco bits são SEMPRE alimentados diretamente no arquivo de registro, esses cinco bits são SEMPRE alimentados no shifter de barril, esses seis bits são SEMPRE encaminhados para a ULA para determinar qual função executar).
Eles podem estar pensando em introduzir instruções combinadas de mudança de esquerda e adição no futuro. Presumivelmente, isso teria a forma:
$d = $s + ($t << shamt)
2s+ 1s
Hoje, provavelmente não pensamos duas vezes em ter um estágio de decodificação mais complexo, especialmente porque os acessos a arquivos de registro tendem a acontecer mais tarde no pipeline de uma CPU superscalar típica. Muitas CPUs modernas até decodificam grosseiramente as instruções no momento em que uma instrução é inserida no cache L1 . Você torna as linhas do cache I um pouco mais largas para armazenar informações extras (graças à Lei de Moore, você tem muitos transistores a serem desperdiçados) para tornar a decodificação "adequada" das instruções mais simples e rápida.
Uma razão pela qual eles provavelmente queriam manter o campo opcode o menor possível é para que não penalizasse indevidamente as instruções do tipo J. Como você provavelmente sabe, as instruções do tipo J usam endereçamento pseudo-direto. Para o benefício de qualquer um que esteja tocando em casa, explicarei brevemente.
O campo de endereço de uma instrução do tipo J é 26 bits. Como as instruções estão sempre alinhadas em 4 bytes, você não precisa armazenar os dois bits menos significativos, o que significa que você possui efetivamente 28 bits de endereço. No entanto, o espaço de endereço no MIPS I é de 32 bits. Portanto, os quatro bits principais do local do salto são retirados do contador do programa.
Isso significa que você não pode pular diretamente para um local onde os quatro bits mais significativos do local do PC são diferentes. Você precisaria fazer um salto de três instruções mais caro em um registro de rascunho:
lui $r,target >> 16
ori $r,$r,target & 0xFFFF
jr $r
Hoje não é tão ruim assim, mas em 1985 são muitos ciclos de relógio.
Roubar um pouco do campo de endereço reduziria ainda mais o alcance efetivo de um salto direto. Você pode ver como esse preço pode ser alto demais para pagar.