No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

as.y 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. %union {
  2. int nombre;
  3. }
  4. %{
  5. #include "../Tables/tables.h"
  6. #include <stdio.h>
  7. FILE * file;
  8. FILE * file2;
  9. %}
  10. %token tMUL tDIV tADD tSUB tINF tSUP tEQU
  11. %token tAFC tCPY tAFCA
  12. %token tREAD tWR
  13. %token tJMP tJMF
  14. %token tGET tPRI tPRIC
  15. %token tCALL tRET
  16. %token tSTOP
  17. %token<nombre> tNB
  18. %%
  19. // Un programme est une suite d'au moins une instruction
  20. Programme : Instruction Programme;
  21. Programme : Instruction;
  22. // Liste de toutes les instructions et conversion
  23. // MUL, ADD, DIV.... -> 3 arguments
  24. 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)
  25. int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts
  26. int reg_src1 = get_reg_read($3, &added_instruction); // On demande un registre en lecture pour l'argument B de l'instruction (adresse)
  27. // On passe l'adresse de la variable added_instruction pour savoir combien d'instruction ont été rajoutées
  28. int reg_src2 = get_reg_read($4, &added_instruction); // On demande un registre en lecture pour l'argument C de l'instruction (adresse)
  29. // On passe l'adresse de la variable added_instruction pour savoir combien d'instruction ont été rajoutées
  30. int reg_dest = get_reg_write($2, &added_instruction); // On demande un registre en écriture pour l'argument A de l'instruction (adresse)
  31. // On le fait après la demande en lecture TOUJOURS DEMANDER L'ECRITURE APRES LA LECTURE
  32. add_instruction(MUL, reg_dest, reg_src1, reg_src2); // On ajoute la traduction de l'instruction MUL
  33. new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées
  34. Instruction : tADD tNB tNB tNB {increment_time();
  35. int added_instruction = 0;
  36. int reg_src1 = get_reg_read($3, &added_instruction);
  37. int reg_src2 = get_reg_read($4, &added_instruction);
  38. int reg_dest = get_reg_write($2, &added_instruction);
  39. add_instruction(ADD, reg_dest, reg_src1, reg_src2);
  40. new_instruction(added_instruction + 1);};
  41. Instruction : tDIV tNB tNB tNB {increment_time();
  42. int added_instruction = 0;
  43. int reg_src1 = get_reg_read($3, &added_instruction);
  44. int reg_src2 = get_reg_read($4, &added_instruction);
  45. int reg_dest = get_reg_write($2, &added_instruction);
  46. add_instruction(DIV, reg_dest, reg_src1, reg_src2);
  47. new_instruction(added_instruction + 1);};
  48. Instruction : tSUB tNB tNB tNB {increment_time();
  49. int added_instruction = 0;
  50. int reg_src1 = get_reg_read($3, &added_instruction);
  51. int reg_src2 = get_reg_read($4, &added_instruction);
  52. int reg_dest = get_reg_write($2, &added_instruction);
  53. add_instruction(SUB, reg_dest, reg_src1, reg_src2);
  54. new_instruction(added_instruction + 1);};
  55. Instruction : tINF tNB tNB tNB {increment_time();
  56. int added_instruction = 0;
  57. int reg_src1 = get_reg_read($3, &added_instruction);
  58. int reg_src2 = get_reg_read($4, &added_instruction);
  59. int reg_dest = get_reg_write($2, &added_instruction);
  60. add_instruction(INF, reg_dest, reg_src1, reg_src2);
  61. new_instruction(added_instruction + 1);};
  62. Instruction : tSUP tNB tNB tNB {increment_time();
  63. int added_instruction = 0;
  64. int reg_src1 = get_reg_read($3, &added_instruction);
  65. int reg_src2 = get_reg_read($4, &added_instruction);
  66. int reg_dest = get_reg_write($2, &added_instruction);
  67. add_instruction(SUP, reg_dest, reg_src1, reg_src2);
  68. new_instruction(added_instruction + 1);};
  69. Instruction : tEQU tNB tNB tNB {increment_time();
  70. int added_instruction = 0;
  71. int reg_src1 = get_reg_read($3, &added_instruction);
  72. int reg_src2 = get_reg_read($4, &added_instruction);
  73. int reg_dest = get_reg_write($2, &added_instruction);
  74. add_instruction(EQU, reg_dest, reg_src1, reg_src2);
  75. new_instruction(added_instruction + 1);};
  76. // AFC @ val -> AFC Ri val
  77. 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)
  78. int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts
  79. int reg_dest = get_reg_write($2, &added_instruction); // On demande un registre en écriture pour l'argument A de l'instruction (adresse)
  80. add_instruction(AFC, reg_dest, $3, 0); // On ajoute la traduction de l'instruction AFC
  81. new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées
  82. // CPY @ @ -> CPY Ri Rj
  83. 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)
  84. int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts
  85. int reg_src = get_reg_read($3, &added_instruction); // On demande un registre en lecture pour l'argument B de l'instruction (adresse)
  86. // On passe l'adresse de la variable added_instruction pour savoir combien d'instruction ont été rajoutées
  87. int reg_dest = get_reg_write($2, &added_instruction); // On demande un registre en écriture pour l'argument A de l'instruction (adresse)
  88. // On le fait après la demande en lecture TOUJOURS DEMANDER L'ECRITURE APRES LA LECTURE
  89. add_instruction(CPY, reg_dest, reg_src, 0); // On ajoute la traduction de l'instruction CPY
  90. new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées
  91. // AFCA @ val -> AFC Rlamda val; STOREA @ Rlamda
  92. 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)
  93. int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts
  94. int reg_aux = get_reg_write(-1, &added_instruction); // On demande un registre en écriture
  95. // On ne veut pas un registre associé a une adresse, juste un buffer d'où le -1
  96. add_instruction(AFC, reg_aux, $3, 0); // On affecte la valeur dans un registre lamda, elle sera tout de suite enregistré en mémoire
  97. 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)
  98. unlink($2); // On casse l'eventuel lien entre l'adresse et un registre
  99. // Si un registre était déjà associé a cette adresse, la valeur qu'il contient est obsolète, on le libère
  100. new_instruction(added_instruction + 2);}; // On déclare le nombre d'instruction ajoutées
  101. // JMP Ins -> JMP Ins
  102. 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)
  103. add_instruction(JMP, $2, 0, 0); // On traduit le JMP sans rien changer
  104. new_instruction(1);}; // On déclare le nombre d'instruction ajoutées
  105. // JMF @ Ins -> AFC Rlamda 0; SUB Rlamda Rlamda Ri; JMZ Ins
  106. 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)
  107. int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts
  108. int reg_src = get_reg_read($2, &added_instruction); // On demande un registre en lecture pour l'argument A de l'instruction (adresse)
  109. int reg_aux = get_reg_write(-1, &added_instruction); // On demande un registre en écriture
  110. // On ne veut pas un registre associé a une adresse, juste un buffer d'où le -1
  111. add_instruction(AFC, reg_aux, 0, 0); // On affecte 0 à un registre
  112. 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
  113. add_instruction(JMZ, $3, 0, 0); // On ajoute le JMZ
  114. new_instruction(added_instruction + 3);}; // On déclare le nombre d'instruction ajoutées
  115. // READ @1 @2 -> LOADI @1 @2
  116. 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)
  117. int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts
  118. int reg_addr = get_reg_read($3, &added_instruction); // On demande un registre en lecture pour l'adresse de la lecture en mémore
  119. int reg_dest = get_reg_write($2, &added_instruction); // On demande un registre en écriture pour loader la valeur depuis la mémoire
  120. add_instruction(LOADI, reg_dest, reg_addr, 0); // On traduit le READ
  121. new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées
  122. // WR @1 @2 -> STOREI @1 @2
  123. 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)
  124. int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts
  125. int reg_addr = get_reg_read($2, &added_instruction); // On demande un registre en lecture pour l'adresse de l'écriture en mémore
  126. int reg_value = get_reg_read($3, &added_instruction); // On demande un registre en lecture pour la valeur à écrire en mémoire
  127. add_instruction(STOREI, reg_addr, reg_value, 0); // On traduit le WR
  128. new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées
  129. // GET @ -> GET Ri
  130. 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)
  131. int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts
  132. int reg_dest = get_reg_write($2, &added_instruction); // On demande un registre en ecriture pour écrire la valeur lue
  133. add_instruction(GET, reg_dest, 0, 0); // On traduit le GET
  134. new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées
  135. // PRI @ -> PRI Ri
  136. 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)
  137. int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts
  138. int reg_src = get_reg_read($2, &added_instruction); // On demande un registre en lecture pour sortir la valeur à afficher
  139. add_instruction(PRI, reg_src, 0, 0); // On traduit le PRI
  140. new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées
  141. // PRIC @ -> PRIC Ri
  142. Instruction : tPRIC tNB {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU)
  143. int added_instruction = 0; // On initialise le compteur d'instruction ajoutées (pour la traduction des sauts
  144. int reg_src = get_reg_read($2, &added_instruction); // On demande un registre en lecture pour sortir la valeur à afficher
  145. add_instruction(PRIC, reg_src, 0, 0); // On traduit le PRIC
  146. new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées
  147. // CALL Ins Val -> CALL Ins Val
  148. 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)
  149. int added_instruction = flush_and_init(file); // On Store tous les registre en mémoire et réinitialise les correspondances
  150. add_instruction(CALL, $2, $3, 0); // On traduit le CALL
  151. new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées
  152. // RET -> RET
  153. Instruction : tRET {increment_time(); // On incrémente le temps, c'est a dire, une instruction de plus a été traduite (pour la politique LRU)
  154. int added_instruction = flush_and_init(file); // On Store tous les registre en mémoire et réinitialise les correspondances
  155. add_instruction(RET, 0, 0, 0); // On traduit le RET
  156. new_instruction(added_instruction + 1);}; // On déclare le nombre d'instruction ajoutées
  157. // STOP Val -> STOP -> Val
  158. 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)
  159. add_instruction(STOP, $2, 0, 0); // On traduit le STOP
  160. new_instruction(1);}; // On déclare le nombre d'instruction ajoutées
  161. %%
  162. int main(void) {
  163. file = fopen("output.asm", "w");
  164. file2 = fopen("output.bin", "w");
  165. init();
  166. yyparse();
  167. write_asm(file);
  168. write_code_machine(file2, 0);
  169. return 0;
  170. }