%union { int nombre; } %{ #include "../Tables/tables.h" #include FILE * file; FILE * file2; %} %token tMUL tDIV tADD tSUB tINF tSUP tEQU %token tAFC tCPY tAFCA %token tREAD tWR %token tJMP tJMF %token tGET tPRI %token tCALL tRET %token tSTOP %token tNB %% // Un programme est une suite d'au moins une instruction Programme : Instruction Programme; Programme : Instruction; // Liste de toutes les instructions et conversion // MUL, ADD, DIV.... -> 3 arguments Instruction : tMUL tNB tNB tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU) int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts int reg_src1 = get_reg_read($3, &added_instruction); // On demande un registre en lecture pour l'argument B de l'instruction (adresse) // On passe l'adresse de la variable added_instruction pour savoir combien d'instruction ont été rajoutées int reg_src2 = get_reg_read($4, &added_instruction); // On demande un registre en lecture pour l'argument C de l'instruction (adresse) // On passe l'adresse de la variable added_instruction pour savoir combien d'instruction ont été rajoutées int reg_dest = get_reg_write($2, &added_instruction); // On demande un registre en écriture pour l'argument A de l'instruction (adresse) // On le fait après la demande en lecture TOUJOURS DEMANDER L'ECRITURE APRES LA LECTURE add_instruction(MUL, reg_dest, reg_src1, reg_src2); // On ajoute la traduction de l'instruction MUL new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées Instruction : tADD tNB tNB tNB {increment_time(); int added_instruction = 0; int reg_src1 = get_reg_read($3, &added_instruction); int reg_src2 = get_reg_read($4, &added_instruction); int reg_dest = get_reg_write($2, &added_instruction); add_instruction(ADD, reg_dest, reg_src1, reg_src2); new_instruction(added_instruction + 1);}; Instruction : tDIV tNB tNB tNB {increment_time(); int added_instruction = 0; int reg_src1 = get_reg_read($3, &added_instruction); int reg_src2 = get_reg_read($4, &added_instruction); int reg_dest = get_reg_write($2, &added_instruction); add_instruction(DIV, reg_dest, reg_src1, reg_src2); new_instruction(added_instruction + 1);}; Instruction : tSUB tNB tNB tNB {increment_time(); int added_instruction = 0; int reg_src1 = get_reg_read($3, &added_instruction); int reg_src2 = get_reg_read($4, &added_instruction); int reg_dest = get_reg_write($2, &added_instruction); add_instruction(SUB, reg_dest, reg_src1, reg_src2); new_instruction(added_instruction + 1);}; Instruction : tINF tNB tNB tNB {increment_time(); int added_instruction = 0; int reg_src1 = get_reg_read($3, &added_instruction); int reg_src2 = get_reg_read($4, &added_instruction); int reg_dest = get_reg_write($2, &added_instruction); add_instruction(INF, reg_dest, reg_src1, reg_src2); new_instruction(added_instruction + 1);}; Instruction : tSUP tNB tNB tNB {increment_time(); int added_instruction = 0; int reg_src1 = get_reg_read($3, &added_instruction); int reg_src2 = get_reg_read($4, &added_instruction); int reg_dest = get_reg_write($2, &added_instruction); add_instruction(SUP, reg_dest, reg_src1, reg_src2); new_instruction(added_instruction + 1);}; Instruction : tEQU tNB tNB tNB {increment_time(); int added_instruction = 0; int reg_src1 = get_reg_read($3, &added_instruction); int reg_src2 = get_reg_read($4, &added_instruction); int reg_dest = get_reg_write($2, &added_instruction); add_instruction(EQU, reg_dest, reg_src1, reg_src2); new_instruction(added_instruction + 1);}; // AFC @ val -> AFC Ri val Instruction : tAFC tNB tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU) int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts int reg_dest = get_reg_write($2, &added_instruction); // On demande un registre en écriture pour l'argument A de l'instruction (adresse) add_instruction(AFC, reg_dest, $3, 0); // On ajoute la traduction de l'instruction AFC new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées // CPY @ @ -> CPY Ri Rj Instruction : tCPY tNB tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU) int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts int reg_src = get_reg_read($3, &added_instruction); // On demande un registre en lecture pour l'argument B de l'instruction (adresse) // On passe l'adresse de la variable added_instruction pour savoir combien d'instruction ont été rajoutées int reg_dest = get_reg_write($2, &added_instruction); // On demande un registre en écriture pour l'argument A de l'instruction (adresse) // On le fait après la demande en lecture TOUJOURS DEMANDER L'ECRITURE APRES LA LECTURE add_instruction(CPY, reg_dest, reg_src, 0); // On ajoute la traduction de l'instruction CPY new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées // AFCA @ val -> AFC Rlamda val; STOREA @ Rlamda Instruction : tAFCA tNB tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU) int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts int reg_aux = get_reg_write(-1, &added_instruction); // On demande un registre en écriture // On ne veut pas un registre associé a une adresse, juste un buffer d'où le -1 add_instruction(AFC, reg_aux, $3, 0); // On affecte la valeur dans un registre lamda, elle sera tout de suite enregistré en mémoire add_instruction(STOREA, $2, reg_aux, 0); // On store la valeur en mémoire (avec un STOREA car AFCA, nous sommes donc obligé de le faire tout de suite) unlink($2); // On casse l'eventuel lien entre l'adresse et un registre // Si un registre était déjà associé a cette adresse, la valeur qu'il contient est obsolète, on le libère new_instruction(added_instruction + 2);}; // On déclare le nombre d'instruction ajoutées // JMP Ins -> JMP Ins Instruction : tJMP tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU) add_instruction(JMP, $2, 0, 0); // On traduit le JMP sans rien changer new_instruction(1);}; // On déclare le nombre d'instruction ajoutées // JMF @ Ins -> AFC Rlamda 0; SUB Rlamda Rlamda Ri; JMZ Ins Instruction : tJMF tNB tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU) int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts int reg_src = get_reg_read($2, &added_instruction); // On demande un registre en lecture pour l'argument A de l'instruction (adresse) int reg_aux = get_reg_write(-1, &added_instruction); // On demande un registre en écriture // On ne veut pas un registre associé a une adresse, juste un buffer d'où le -1 add_instrcution(AFC, reg_aux, 0, 0); // On affecte 0 à un registre add_instruction(SUB, reg_aux, reg_aux, reg_src); // On Soustrait la valeur à 0, flag 0 levé si la valeur vallait 0 donc condition fausse add_instruction(JMZ, $3, 0, 0); // On ajoute le JMZ new_instruction(added_instruction + 3);}; // On déclare le nombre d'instruction ajoutées // READ @1 @2 -> LOADI @1 @2 Instruction : tREAD tNB tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU) int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts int reg_addr = get_reg_read($3, &added_instruction); // On demande un registre en lecture pour l'adresse de la lecture en mémore int reg_dest = get_reg_write($2, &added_instruction); // On demande un registre en écriture pour loader la valeur depuis la mémoire add_instruction(LOADI, reg_dest, reg_addr, 0); // On traduit le READ new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées // WR @1 @2 -> STOREI @1 @2 Instruction : tWR tNB tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU) int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts int reg_addr = get_reg_read($2, &added_instruction); // On demande un registre en lecture pour l'adresse de l'écriture en mémore int reg_value = get_reg_read($3, &added_instruction); // On demande un registre en lecture pour la valeur à écrire en mémoire add_instruction(STOREI, reg_addr, reg_value, 0); // On traduit le WR new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées // GET @ -> GET Ri Instruction : tGET tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU) int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts int reg_dest = get_reg_write($2, &added_instruction); // On demande un registre en ecriture pour écrire la valeur lue add_instruction(GET, reg_dest, 0, 0); // On traduit le GET new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées // PRI @ -> PRI Ri Instruction : tPRI tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU) int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts int reg_src = get_reg_read($2, &added_instruction); // On demande un registre en lecture pour sortir la valeur à afficher add_instruction(PRI, reg_src, 0, 0); // On traduit le PRI new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées // CALL Ins Val -> CALL Ins Val Instruction : tCALL tNB tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU) int added_instruction = flush_and_init(file); // On Store tous les registre en mémoire et réinitialise les correspondances add_instruction(CALL, $2, $3, 0); // On traduit le CALL new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées // RET -> RET Instruction : tRET {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU) int added_instruction = flush_and_init(file); // On Store tous les registre en mémoire et réinitialise les correspondances add_instruction(RET, 0, 0, 0); // On traduit le RET new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées // STOP Val -> STOP -> Val Instruction : tSTOP tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU) add_instruction(STOP, $2, 0, 0); // On traduit le STOP new_instruction(1);}; // On déclare le nombre d'instruction ajoutées %% int main(void) { file = fopen("output.asm", "w"); file2 = fopen("output.bin", "w"); init(); yyparse(); write_asm(file); write_code_machine(file2, 0); return 0; }