Architecture MIPS

architecture de processeur

L'architecture MIPS (de l'anglais : microprocessor without interlocked pipeline stages) est une architecture de processeur de type Reduced instruction set computer (RISC) développée par la société MIPS Technologies (alors appelée MIPS Computer Systems), basée à Mountain View en Californie.

Architecture MIPS
Présentation
Type

Les processeurs fabriqués selon cette architecture ont surtout été utilisés dans les systèmes SGI. On les retrouve aussi dans plusieurs systèmes embarqués, comme les ordinateurs de poche, les routeurs Cisco et les consoles de jeux vidéo (Nintendo 64 et Sony PlayStation, PlayStation 2 et PSP).

Vers la fin des années 1990, on estimait que les processeurs dérivés de l'architecture MIPS occupaient le tiers des processeurs RISC produits.

De nos jours cette architecture reste populaire dans le marché de l'informatique embarquée où elle subit une intense concurrence de la part de l'architecture ARM.

Les MIPS sont aussi présents dans des routeurs ou des NAS, mais ils deviennent aussi de plus en plus rares dans ce domaine face à la concurrence des ARM, PowerPC et x86 basse consommation.

Malgré tout, les MIPS reviennent peu à peu dans le marché de l'informatique à haute performance grâce aux recherches menées par la Chine avec les processeurs Loongson qui ont été utilisés pour la création du supercalculateur Dawning 5000L et 6000.

En 2015, la Russie annonce vouloir remplacer les processeurs conçus par des sociétés des États-Unis par des processeurs locaux dans les systèmes informatiques nationaux. Les processeurs d'architecture MIPS, Baikal T1 de la société russe spécialisée dans les supercalculateurs T-Platforms (en) sont alors choisis. Leur conception est soutenue par le conglomérat de la défense Rostec et co-financée par l'entreprise publique russe Rosnano (Роснано)[1].

Architecture

modifier
 
MIPS 4400.
 

Les premières versions de l'architecture MIPS étaient 32-bits (autant au niveau des registres que des chemins de données), mais par la suite, des versions 64-bits sont apparues.

Le R4000 sorti en 1991 serait le premier processeur 64 bits. Il a été supporté par Microsoft de Windows NT 3.1 jusqu'à Windows NT 4.0

Il existe plusieurs jeux d'instructions MIPS qui sont rétrocompatibles (backward compatible) : MIPS I, MIPS II, MIPS III, MIPS IV, et MIPS V ainsi que MIPS32 et MIPS64. MIPS32 et MIPS64, qui se basent sur MIPS II et MIPS V, ont été introduits comme jeux d'instructions normalisés. Des extensions sont aussi disponibles telles que : MIPS-3D, une unité à virgule flottante (FPU) simplifiée de type SIMD pour les calculs 3D de base, MDMX, qui pousse plus loin l'utilisation des instructions SIMD et qui permet l'utilisation de registres à virgule flottante de 64 bits, MIPS16, qui compresse le flot d'instructions pour diminuer la taille des programmes (créée en réponse au codage Thumb introduit dans l'architecture ARM), et plus récemment, MIPS MT, qui permet le traitement de deux processus simultanément par un seul cœur de manière similaire à l'Hyper-Threading présent dans les récents processeurs d'Intel.

Les jeux d'instructions de base (en particulier MIPS I) sont si simples et efficaces qu'un bon nombre de cours d'architecture des ordinateurs, autant dans les universités que les écoles techniques, portent sur l'étude de l'architecture MIPS.

Exemple de code

modifier

Voici une implémentation des indicatrices d'Euler en assembleur MIPS :

 .text
 .globl main
	  main:
		  la $a0, query		# Load Address : charge l'adresse de la requête
		  li $v0, 4		# Load Immediate : charge la valeur
		  syscall		# appel du système d’exploitation
		  li $v0, 5		# lit l’entrée
		  syscall
		  move $t0, $v0	      	# stocke la valeur dans une variable temporaire
		        	      	# stocke les valeurs de base dans $t1, $t2
		  sub $t1, $t0, 1     	# $t1 itère de m-1 à 1
		  li $t2, 0          	# $t2 maintient un compteur des premiers entre eux inférieurs à m
		
	 tot:
		 blez $t1, done  				#termination condition
		 move $a0, $t0					#Chargement d'argument
		 move $a1, $t1   				#Chargement d'argument
		 jal gcd						#Appel de la fonction GCD
		 sub $t3, $v0, 1 					
		 beqz $t3, inc   				#vérifie si gcd est égal à un
		 addi $t1, $t1, -1				#décremante l'itérateur
		 b tot 
		
	  inc:
		  addi $t2, $t2, 1				#incremente le conteur
		  addi $t1, $t1, -1				#décremente l'iterateur
	 	  b tot

	  gcd:							#definition récursive
	         addi $sp, $sp, -12
         	 sw $a1, 8($sp)
 		 sw $a0, 4($sp)
                 sw $ra, 0($sp)
 		 move $v0, $a0					
		 beqz $a1, gcd_return			        #termination condition
		 move $t4, $a0					#calcul de GCD
		 move $a0, $a1
	 	 remu $a1, $t4, $a1
 		 jal gcd
		 lw $a1, 8($sp)
		 lw $a0, 4($sp)

	 gcd_return:
		 lw $ra, 0($sp)
		 addi $sp, $sp, 12
		 jr $ra
		
	 done:							 #imprime (affiche) le resultat
								 #en premier le message
		 la $a0, result_msg
		 li $v0, 4
		 syscall
								 #après la valeur
		 move $a0, $t2
		 li $v0, 1
		 syscall
								 #exit
		 li $v0, 10
		 syscall
		
  .data
	 query: .asciiz "Input m =  "
	 result_msg: .asciiz "Totient(m) =  "

Registres

modifier

Description des registres généraux

modifier

Il y a 32 registres généraux[2].

Le registre 0 ($zero) est toujours égal à zero.

Le registre 1 ($at) est réservé par l'assembleur.

Les registres 2 et 3 ($v0 et $v1) permettent de stocker des résultats des fonctions[3].

Les registres 4 à 7 ($a0 à $a3) permettent de stocker les 4 premiers arguments du sous-programme [3].

Les registres 8 à 15 ($t0 à t7) sont des registres temporaires.

Les registres 16 à 23 ($s0 à s7) sont des registres sauvegardés et utilisés plus tard[3].

Les registres 24 et 25 ($t8 et $t9) sont des registres temporaires.

Les registres 26 et 27 ($k0 et $k1) sont des registres réservés au système.

Le registre 28 ($gp) correspond au global pointer.

Le registre 29 ($sp) correspond au stack pointer.

Le registre 30 ($fp) correspond au frame pointer.

Le registre 31 ($ra) correspond à l'adresse de retour.


Description de quelques registres particuliers

modifier

Parmi les registres spéciaux, on peut parler des registres lo (où on trouve les résultats des divisions et des multiplications) et hi (où on trouve le reste lors des divisions)[4].

Dans le cas où le résultat d'une multiplication serait sur 64 bits, les 32 bits supérieurs seraient stockés dans hi et les 32 bits inférieurs seraient stockés dans lo [4]. On peut récupérer les valeurs de hi et lo avec respectivement, les instructions mfhi et mflo[4].

Par exemple pour les divisions, on peut donner l'exemple suivant :

addi $t3, $0, 37
addi $t4, $0, 2
div $t3, $t4
mflo $t0 #équivaut à 37 / 2 équivaut à 18 (le quotient)
mfhi $t1 #équivaut à 37 % 2 équivaut à 1 (le reste)

Et pour les multiplications, on peut donner l'exemple suivant :

addi $t3, $0, 37
addi $t4, $0, 2
mult $t3, $t4
mflo $t1 #on y trouve le produit mais il faut que le produit soit sur 32 bits

Voir aussi

modifier

Articles connexes

modifier

Liens externes

modifier

Simulateurs

modifier
  • (en) MARS : simulateur MIPS écrit en langage Java
  • (en) SPIM : simulateur de processeur MIPS R2000 et MIPS R3000 (jeu d'instructions MIPS I)
  • (en) KOYOTE : simulateur visuel de processeur RISC simplifié (basé sur MIPS R2000)

Références

modifier