# MMIX

MMIX, prononcé /ɛm.mɪks/ et usuellement typographié dans une police à chasse fixe (MMIX), est à la fois un jeu d'instructions 64-bit RISC et une architecture informatique conçus par Donald Knuth, avec une aide importante de John LeRoy Hennessy, un des concepteurs de l'architecture MIPS, et de Richard L. Sites, un des concepteurs de l’architecture Alpha. Knuth lui-même présente ce projet en ces mots :
   « MMIX est un ordinateur destiné à illustrer les aspects de la programmation au niveau machine. Dans mes livres The Art of Computer Programming, il remplace MIX, une machine répliquant le style des années 1960, laquelle jouait un tel rôle... J'ai tenté de concevoir MMIX de façon que son langage machine soit simple, élégant et facile à apprendre. En parallèle, j'ai fait attention d'inclure toutes les complexités nécessaires pour obtenir une haute performance dans la pratique, de sorte que MMIX pourrait en principe être construit et peut-être faire concurrence à certains des langages généraux les plus rapides disponibles commercialement$^,$ »

## Architecture

En termes d’architecture informatique MMIX est un ordinateur RISC 64 bits, avec 256 registres 64 bits généraux et 32 registres 64 bits à usage spécifique. MMIX est une machine gros-boutiste avec des instructions 32 bits et un espace d’adressage virtuel 64 bits. Son jeu d'instructions comprend 256 codes opérations, dont un est réservé pour un potentiel usage futur. Les nombres à virgule flottante sont implémentés conformément au standard IEEE 754.

### Instructions

Les instructions de MMIX sont toutes définies et utilisables à partir de leur code opération, qui est un nombre d’un octet, généralement noté sous forme hexadécimale. Cependant pour améliorer la lisibilité du code assembleur, une étiquette mnémotechnique unique est associé à chacun des codes. Ainsi l’étiquette ADD est équivalente à l’instruction numéro 20$_{16}$, qui est le code opérateur de l’addition. La plupart des instructions sont de la forme opérateur X Y Z, où opérateur spécifie l’instruction, X est un registre servant d’accumulateur, c’est-à-dire utilisé pour stoker le résultat de l’instruction, et Y et Z désignent les registres servant d’opérandes à l’instruction. Par exemple ADD $0,$1,3 signifie affecter à $0 la Somme (arithmétique) du nombre stocké dans le registre $1 et du nombre 3.
La plupart des instructions peuvent prendre soit des valeurs immédiates, soit utiliser le contenu d’un registre ; ainsi un seul mnémonique peut correspondre à un ou deux codes opérations.
Typiquement, les programmes MMIX sont construits en utilisant le langage Assembleur MMIXAL. L’exemple ci-dessous est un programme écrit en MMIXAL qui affiche Hello world :

### Registres

Dans une puce d'architecture MMIX il y a 256 registres généraux, auxquels on accède par leurs références notées de $0 à $255 et 32 registres spéciaux. Deux des registres spéciaux, rL et rG, déterminent quels sont les registres locaux et lesquels sont globaux. Tous les registres, de $0 à $(rL-1) sont des registres locaux. Les registres de [rL] à [rG]-1 sont des registres marginaux qui retournent toujours 0 s'ils sont utilisés comme source dans une opération. Utiliser un registre marginal en tant que destination d’une opération déclenchera une incrémentation automatique de rL pour inclure ce registre. Tous les registres de [rG] à $255 sont appelés registres globaux et ne sont pas sauvegardés sur la pile de registre.

#### Pile de registre local

La pile de registre local fournit à chaque procédure ses propres registres locaux rL, notés de $0 à $(rL - 1). Si une procédure est appelée, les registres locaux sont ajoutés sur la pile. Les arguments de la procédure sont placés dans les registres locaux restants. Quand une procédure se termine, elle retire les registres précédemment ajoutés. Comme il n’y a que 256 registres physiques, il peut être nécessaire de stocker une partie de la pile en mémoire. Cette action est implémentée avec les registres spéciaux rO et rS qui enregistrent quelle partie de la pile de registre local est en mémoire et quelle partie est toujours dans les registres physiques locaux. Le registre de pile assure également la liaison rapide de procédures (en).

#### Registres spéciaux

Les 32 registres spéciaux de l'architecture physique sont définis comme suit :
* rB, le registre d'amorçage (déclencheur), avec un b comme dans l’anglais bootstrap : lorsqu’un déclenchement se produit, rB est affecté de la valeur stockée dans le registre $255 et le registre $255 est affecté de la valeur stockée dans le registre rJ, sauvegardant ainsi rJ dans un registre général.
* rD, le registre de dividende : La division entière non signée utilise ce registre en tant que moitié gauche du numérateur (dividende) codé sur 128 bits qui est à diviser par le dénominateur (diviseur).
* rE, le registre epsilon, ou registre de la marge d’erreur : Utilisé dans la comparaison de nombres à virgule flottante tolérant une marge d'erreur
* rH, nommé registre himult : Le terme himult, prononcé /haɪ.mʌlt/, est la contraction de l’anglais high multiplication, littéralement haute multiplication, où haute suggère la partie contenant les bits de poids les plus forts d’un nombre stocké dont la représentation est distribuée sur plusieurs registres distincts. Ce registre est utilisé pour stocker la moitié droite du produit de la multiplication entière non signé.
* rJ, le registre de retour de saut, avec un j comme dans l’anglais jump : Ce registre est utilisé par PUSH et POP pour sauvegarder l’adresse de la prochaine instruction au retour d’un PUSH.
* rM est le registre de masque de multiplexage Ce registre est utilisé par les instructions multiplexes MUX et MUXI.
* rR est le registre de reste : Il est affecté de la valeur du reste lors des divisions exécutées par DIV, DIVI, DIVU, DIVUI ou FDIV.
* rBB, le registre d’amorçage du noyau, avec BB comme bootstrap bis : Lors d’une capture par l’instruction TRAP, trap désignant un dispositif de capture en anglais, rBB est affecté du registre $255 et le registre $255 est affecté de la valeur stockée dans rJ, sauvegardant ainsi rJ dans un registre général.
* rC, le compteur de cycle : Il est incrémenté à chaque cycle.
* rN, le registre de numéro de série : Une constante qui identifie le processeur MMIX courant.
* rO, le registre d’offset de la pile Ce registre est utilisé pour implémenter la pile de registre.
* rS, avec un s comme stack, pile en anglais : C’est le registre utilisé pour stocker un pointeur vers l’adresse courante de la pile.
* rI, le compteur d’interval : Il est décrémenté à chaque cycle et déclenche une interruption lorsqu’il atteint zéro.
* rT, avec un t comme trap, dispositif de capture en anglais : Il est utilisé pour stocker l’adresse du vecteur de déclencheur.
* rTT, avec un t également en référence à l’anglais trap, mais il s’agit cette fois du registre de déclencheur dynamique (dynamic trap adress register) Il est utilisé pour stocker l’adresse du vecteur de déclencheur.
* rK, le registre de masque d’interruption, interrupt mask register en anglais : Ce registre est utilisé pour enclencher et déclencher des interruptions spécifiques.
* rQ, le registre de requête d'interruption : Il est utilisé pour enregistrer les interruptions au fur et à mesure de leurs survenues.
* rU, le compteur d'utilisation : Le compte du nombre d'instructions exécutées est stocké dans ce registre.
* rV, le registre de traduction virtuelle : Il est utilisé pour la traduction entre adresses virtuelles et physiques. Il mémorise le nombre de segments, la taille allouée pour chaque segment, la position de la racine de la table des pages et le nombre d'espaces d'adresses (en).
* rG, le registre de seuil global : Toutes les références de registres généraux codées avec un nombre supérieur ou égal au seuil défini par rG font référence à des registres globaux.
* rL, le registre de seuil local : Toutes les références de registres généraux codées avec un nombre strictement inférieur au seuil défini par rL font référence à des registres locaux.
* rA le registre de statut arithmétique : Ce registre est utilisé pour la gestion des exceptions arithmétiques : enregistrement, enclenchement et déclenchement. Ces exceptions incluent notamment le dépassement arithmétique (en) et la division par zéro.
* rF le registre de positionnement d'erreur : Lorsque le système détecte qu'une instruction ne s'est pas exécutée correctement, l'adresse de l'instruction est stockée dans ce registre. Le mnémotechnique f est lié à l'anglais failure location register, où failure location register peut être traduit par échec. En français on peut se référer aux mots fredaine ou faux-pas.
* rP, le registre de prédiction : Il est utilisé par l'instruction CSWAP de permutation conditionnelle.
* rW, le registre de lieu d'interruption : Ce registre est utilisé lors d’un déclenchement pour stocker l’adresse de l’instruction après celle qui a été interrompue. Le W fait référence au nom anglais where-interrupted register, littéralement le registre où-interrompue.
* rX, le registre d’exécution (déclencheur) : Ce registre est utilisé lors de déclenchement pour stocker l’instruction qui a été interrompue.
* rY l’opérande Y (déclencheur) : Ce registre est utilisé, lors d’un déclenchement, pour stocker la première opérande de l’instruction. Y fait référence au nom générique usuel en mathématique.
* rZ l’opérande Z (déclencheur) : Ce registre est utilisé, lors d’un déclenchement, pour stocker le premier opérande de l’instruction. Z fait référence au nom générique usuel en mathématique.
* rWW, le registre de lieu d'interruption (capture) : Il est utilisé, lors d’une capture, pour stocker l’adresse de l’instruction après celle qui a été interrompue. Le W fait référence au mot where, comme précédemment.
* rXX, le registre d’exécution (capture) : Il est utilisé, lors d’une capture, pour stocker l’instruction qui a été interrompue.
* rYY, l’opérande Y (capture) : Il est utilisé, lors d’une capture, pour stocker l’opérande Y de l’instruction interrompue.
* rZZ, l’opérande Z (capture) : Il est utilisé, lors d’une capture, pour stocker l’opérande Z de l’instruction interrompue.

## Implémentation matérielle

Il n’existe actuellement aucune implémentation matérielle de l’architecture à jeu d’instruction MMIX. Cependant, le projet fpgammix l'implémente en Verilog, ce qui ouvre la possibilité de l’utiliser dans un circuit logique programmable.

## Outils logiciels

L’architecture de jeu d’instruction MMIX est utilisable à travers tout une panoplie d’outils logiciels pour la recherche en développement logiciel et en architecture d’ordinateur.

### Simulateurs et assembleurs

Knuth a développé un ensemble de logiciels nommé MMIXware comprenant un simulateur comportemental simple de la machine, et MMIXAL, un logiciel d’assemblage, une suite de tests, des programmes d’exemples, une documentation complète, et un simulateur de pipeline de l’architecture MMIX.
Andrew Pochinsky, membre de l’équipe du centre de recherche théorique en physique du Massachusetts Institute of Technology a développé MMIXX, un paquet implémentant un serveur graphique basé sur X11. Elle peut être combiné avec la machine virtuelle de MMIXware pour fournir un affichage de 640×480 pixels en vraie couleur pour Linux et Unix.

### Compilateur

Le projet GNU Compiler Collection (GCC) comprend une partie envers de MMIX pour ses compilateurs C/C++, initialement développé par Hans-Peter Nilsson, et qui fait partie de la distribution standard du projet depuis la fin 2001. Il continue d’être activement développé et maintenu par des volontaires.
L’ensemble des outils existant devraient théoriquement permettre de compiler, construire et amorcer un noyau de système d’exploitation comme Linux sur un processeur MMIX si une implémentation matériel venait à exister.
* (en) Manuel d’installation des outils MMIX pour GCC rédigé par Hans-Peter Nilsson.
* (en) Liste des options spécifiques à MMIX dans GCC.
* (en) §9.25. Liste des fonctionnalités spécifiques à MMIX dans as l’assembleur GNU .