Il nous faut enfin distinguer les deux instructions à l’aide de ifun, il faut pour cela modifier instruction_set
dans misc/isa.c : pour MRMOVL, on passe 1 au lieu de 0 comme deuxième paramètre de HPACK.
Puisque l’on a changé les opcodes, il faut recompiler tous les fichiers .yo pour utiliser la nouvelle
numérotation ! Pour simplifier, lancez make clean dans le répertoire sim, puis make pour tout recompiler.
Compilez un programme qui contient à la fois l’instruction rmmovl et mrmovl, pour vérifier en lisant le
fichier .yo qu’elles utilisent désormais le même icode, avec pour l’une ifun = 0 et pour l’autre ifun = 1.
Question 2
Il s’agit maintenant de corriger le fichier HCL. En effet, puisque MRMOVL et RMMOVL sont désormais
confondus, il s’agit maintenant de les distinguer dans les quelques cas où ils ne doivent pas avoir le
même comportement. Notamment, il faut indiquer à l’étage mémoire dans quel cas il faut lire et dans
quel cas il faut écrire. Par exemple, pour mem_read, on enlève MRMOVL de la syntaxe icode in, et l’on
ajoute || (icode == MRMOVL) à droite, et du coup à l’intérieur de la parenthèse on peut ajouter comme
condition que ifun doit être égal à 1. Complétez de même mem_write et dstM.
Question 3
Il faut également corriger la version pipelinée. Les modifications sont les mêmes, il faudra simplement
aussi ajouter la définition de intsig D_ifun
(bonus) Factorisation de push/pop/call/ret
push/pop/call/ret se ressemblent beaucoup. Il pourrait être utile d’en factoriser certaines, en les
distinguant simplement à l’aide du champ ifun auquel on donnerait des valeurs différentes. En regardant
les similitudes dans le code HCL, est-il intéressant de factoriser par paires push/pop et call/ret, ou
bien par paires push/call et pop/ret, ou bien encore le quadruplet entier push/pop/call/ret ?
Réalisez la factorisation.
Exercice 2 : Ajout de l’instruction loop
L’instruction loop label est équivalente à la combinaison des deux instructions isubl 1,%ecx ; jne label
sauf qu’elle ne modifie pas les cc. Elle décrémente donc le registre %ecx puis branche à l’étiquette label
si %ecx n’a pas atteint 0. Elle est donc typiquement utilisée pour effectuer des boucles for.
Assembleur
Tout d’abord, modifiez l’assembleur pour que cette instruction soit reconnue et générée par celui-ci.
Modifiez les fichiers yas-grammar.lex,misc/isa.h et misc/isa.c (seulement instruction_set) pour
ajouter la nouvelle instruction (on pourra s’inspirer de call), on définira un nouvel opcode I_LOOP, avec
un ifun égal à 0.
Vérifiez que l’assembleur compile correctement un code source de test que vous créerez pour l’occasion,
et que le code machine généré (lisez le fichier .yo généré) est bien le bon, avec le bon opcode et ifun=0,
et la constante de l’étiquette bien placée.
Séquentiel
Modifiez ensuite le fichier HCL pour implémenter loop : corrigez d’abord la version séquentielle, il
faut d’abord ajouter une ligne intsig LOOP et une ligne intsig RECX en vous inspirant des autres, puis
traiter le cas LOOP dans les différents blocs.
Notez que pour new_pc, on n’utilisera pas le booléen Bch (car loop n’est pas censé modifier les cc),
mais valE != 0.
Testez votre implémentation en vérifiant bien dans chaque étage du processeur que le comportement
est bien celui qui est voulu.
2