Pour comprendre les formats d'instructions MIPS I, vous devez comprendre le pipeline MIPS et repenser à la technologie d'implémentation du processeur vers 1985. Si vous regardez le diagramme (vous connaissez celui-ci), vous verrez que la lecture du fichier de registre se trouve dans le Étape d'identification, juste après IF.
Aux fins d'une instruction de type R, l'étape ID doit effectuer les tâches suivantes:
- Déterminez qu'il s'agit en fait d' une instruction de type R.
- Si c'est le cas, indiquez au fichier de registre de charger les valeurs à partir des registres.
Aux fins de cette discussion, c'est la première tâche à laquelle vous devez penser. S'il y a beaucoup de travail de décodage d'instructions que vous devez faire pour même déterminer si vous avez besoin de valeurs de registres, cela augmente le délai avant de pouvoir démarrer les lectures de registre. Cela augmente également la complexité de l'étape d'identification. En réservant un seul opcode pour toutes les instructions de type R, vous gardez la complexité au minimum.
Il semble un peu étrange que vous consacriez cinq bits uniquement au décalage. Je peux penser à quelques explications possibles. La première est qu'elle simplifie le routage (ces cinq bits sont TOUJOURS introduits directement dans le fichier de registre, ces cinq bits sont TOUJOURS introduits dans le barillet, ces six bits sont TOUJOURS acheminés vers l'ALU pour déterminer la fonction à exécuter).
Ils ont peut-être pensé à introduire à l'avenir des instructions combinées de décalage vers la gauche et d'ajout. Ce serait probablement sous la forme:
$d = $s + ($t << shamt)
2s+ 1s
Aujourd'hui, nous ne penserions probablement pas à deux fois à avoir une étape de décodage plus complexe, d'autant plus que les accès aux fichiers de registre ont tendance à se produire plus tard dans le pipeline d'un processeur superscalaire typique. De nombreux processeurs modernes effectuent même un décodage d'instructions grossières au moment où une instruction est insérée dans le cache L1 . Vous agrandissez les lignes I-cache de quelques bits pour stocker les informations supplémentaires (grâce à la loi de Moore, vous avez beaucoup de transistors à perdre) pour rendre le décodage des instructions "correct" plus simple et plus rapide.
Une des raisons pour lesquelles ils voulaient probablement garder le champ opcode aussi petit que possible est afin qu'il ne pénalise pas indûment les instructions de type J. Comme vous le savez probablement, les instructions de type J utilisent un adressage pseudo-direct. Pour le bénéfice de tous ceux qui jouent à la maison, je vais l'expliquer brièvement.
Le champ d'adresse d'une instruction de type J est de 26 bits. Comme les instructions sont toujours alignées sur 4 octets, vous n'avez pas besoin de stocker les deux bits les moins significatifs, ce qui signifie que vous avez effectivement 28 bits d'adresse. Cependant, l'espace d'adressage dans MIPS I est de 32 bits. Ainsi, les quatre premiers bits de l'emplacement de saut sont extraits du compteur de programmes.
Cela signifie que vous ne pouvez pas accéder directement à un emplacement où les quatre bits les plus significatifs de l'emplacement du PC sont différents. Vous devriez plutôt effectuer un saut à trois instructions plus cher dans un registre à gratter:
lui $r,target >> 16
ori $r,$r,target & 0xFFFF
jr $r
Ce n'est pas trop mal aujourd'hui, mais en 1985, c'est beaucoup de cycles d'horloge.
Voler un peu du champ d'adresse réduirait encore plus la portée effective d'un saut direct. Vous pouvez voir comment cela pourrait être un prix trop élevé à payer.