Génération de code assembleur

Voici le cours correspondant. La solution est donnée par les fichiers ltl2linI.ml et lin2asm.ml.

Présentation

Le sujet est donné par l’archive td9.tar.gz.

Il vous reste deux traductions à implémenter dans le petit compilateur:

  1. de LTL vers LIN: linéarisation du code;
  2. de LIN vers ASM: réalisation des trames de pile.

Les langages LIN et ASM sont décrits dans LIN.mli et ASM.mli.

Vous allez compléter les fichiers ltl2linI.ml et lin2asm.ml.

Linéarisation du code

Il s’agit de compléter le fichier ltl2linI.ml, dont l’interface est donnée par ltl2linI.mli. Encore une fois, ce module prend la forme d’un foncteur, ce qui signifie que vous pouvez supposer données les fonctions suivantes:

  1. fetch associe à une étiquette l l’instruction correspondante dans le programme LTL que l’on souhaite traduire;
  2. translate_instruction traduit une instruction LTL en une instruction LIN; on notera que cette traduction provoque une perte d’information, puisqu’une instruction LTL porte un ou deux successeurs explicites, tandis que l’instruction LIN correspondante aura zéro ou un successeurs explicites;
  3. generate produit une instruction LIN; un programme LIN, c’est-à-dire une suite d’instructions LIN, est obtenu via une suite d’appels à generate;
  4. l’appel require l, où l est une étiquette, demande que l’instruction ILabel l soit conservée dans le programme LIN obtenu; en effet, par défaut, toutes les instructions ILabel produites via generate sont supprimées;
  5. les fonctions mark et marked permettent de marquer une étiquette et de déterminer si une étiquette est marquée; elles facilitent le parcours du graphe de flot de contrôle.

Si vous le souhaitez, vous pouvez consulter ltl2lin.ml pour voir comment ces fonctions sont implémentées. Il n’y a là rien de très compliqué.

On vous demande d’écrire la fonction visit, qui parcourt le graphe de flot de contrôle en profondeur d’abord, et engendre pendant ce parcours une suite d’instructions LIN.

Vous pouvez tester à l’aide de la commande make lin, et visualiser le code produit avec:

# ./compilo -dlin <programme>

Réalisation des trames de pile

Il s’agit de compléter le fichier lin2asm.ml.

Les deux problèmes posés par cette traduction sont les suivants:

  1. les instructions INewFrame et IDeleteFrame doivent être remplacées par des décrémentations et incrémentations du registre $sp;
  2. les slots symboliques utilisés pour faire référence aux emplacements de pile doivent être remplacés par des décalages (offsets) relatifs à $sp.

Pour effectuer cette traduction, il est nécessaire de comprendre l’organisation des trames de pile dans le petit compilateur. Celle-ci est décrite par un long commentaire en haut du fichier lin2asm.ml. La figure suivante récapitule cette organisation et son évolution lors d’un appel de fonction de f à g:

Lorsque vous aurez complété les cinq fonctions à trou, vous pourrez tester votre code via make test, et visualiser le code produit avec:

# ./compilo -dasm <programme>

Bravo, vous avez maintenant – du moins je l’espère – une vision d’ensemble du fonctionnement d’un compilateur d’un langage procédural vers un langage assembleur.


Ce document a été traduit de LATEX par HEVEA