Existem algumas vantagens e desvantagens aqui.
Primeiro, queremos que as instruções tenham largura fixa (32 bits). Isso garante que as instruções estejam alinhadas com o bloco de cache e a página, o que simplifica as verificações de presença e permissão de cache e página.
Segundo, queremos que os vários campos de instrução ( opcode
/ source regs
/ immediates
) tenham largura e posição fixas. Isso os torna mais rápidos / menos lógicos para decodificar e são necessários nos estágios iniciais do pipeline. (O destination
registro não é necessário até o final do pipeline, para que possa estar em diferentes locais R
e I
instruções.) A posição e a largura do function
campo são um pouco menos porque isso precisa controlar a função da ULA, mas isso é necessário. no terceiro estágio do pipeline, para que você tenha um pouco de tempo para trabalhar com ele, se necessário.
I
J
J
228.228.I
instruções também são boas para escritores de compilador / vinculador. (No SPARC, onde o campo imediato era de apenas 12 bits, eles tinham que adicionar uma load-high
classe de instrução especial inteira com um imediato de 20 bits.)
26= 64J
R
I
Mas isso deixa espaço de manobra com as R
instruções. Além do código de operação de 6 bits, eles precisam apenas de 15 bits adicionais para a especificação do registro, o que deixa 11 bits para o código de operação estendido e / ou a quantidade de turno.
Você deve pensar no function
campo como sendo um código de operação estendido para a R
instrução. Existe apenas um R
código de operação da instrução, mas existem 64 diferentes functions
que a R
instrução pode executar.
OK. Temos 60 I
instruções diferentes e 64 R
instruções diferentes , então onde devemos colocar as instruções de mudança imediata?
Bem, não apenas existem menos I
instruções, mas também há muito mais coisas que queremos fazer com as I
instruções. Lembre-se de que todas as instruções de ramificação precisam ser I
instruções porque elas têm um deslocamento relativo (imediato). Além disso, todas as instruções de carregamento e armazenamento estão I
no formato MIPS. E, finalmente, precisamos da instrução load-upper-imediato para ser uma I
instrução. Não apenas isso, mas as R
instruções ainda possuem 5 bits adicionais não utilizados (que é o que precisamos para o imediato de um turno imediato nesta arquitetura), portanto, isso incentiva ainda mais a transformar os imediatos do turno em R
instruções especiais (estranhas) .
Muitas dessas decisões são mais arte do que ciência, mas há uma lógica subjacente que pode ser discernida. O objetivo principal não é tornar o número de instruções o menor possível, é criar um desempenho de alto desempenho.pipeline ajustado em um único chip (para que pequenas empresas, como MIPS e Sun estivessem na década de 1980, pudessem competir com a IBM e a DEC). (O nome RISC, inventado por David Patterson, é um tanto infeliz. Ele pegou porque era fofo, não porque "instruções reduzidas" é uma descrição precisa do que as arquiteturas MIPS e SPARC estavam realmente tentando fazer.) instruções largura fixa (e relativamente pequena para que você obtenha um melhor comportamento de cache em I) para tornar a busca, a paginação e a decodificação mais simples e rápidas. Você deseja que as partes da instrução que precisam ser decodificadas mais cedo (oopcode
, as duas fontes de registro e o imediato estendido por sinal) tenham uma largura fixa e uma posição fixa. Você deseja que o imediato seja o maior tempo possível e o maior número possível de instruções, conforme todas as outras restrições.
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:
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:
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:
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.
fonte