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.

tables.c 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. /*
  2. ----------------------------------------
  3. | Adresse | Registre | Modifié |
  4. ----------------------------------------
  5. | | | |
  6. | | | |
  7. | | | |
  8. | i | 0x777756b8 | int |
  9. | size | 0x777756b8 | int |
  10. ----------------------------------------
  11. */
  12. #include "tables.h"
  13. #include <stdlib.h>
  14. #define NB_REG 16
  15. #define MEM_SIZE 256
  16. #define NB_INSTRUCTIONS 256
  17. #define MEM_INST_SIZE 256
  18. #define NB_BITS_INSTRUCTION 8
  19. #define NB_BITS 8
  20. int traduction_JMP[NB_INSTRUCTIONS];
  21. struct str_instruction {
  22. enum instruction_t instruction;
  23. int param1;
  24. int param2;
  25. int param3;
  26. };
  27. int last_instruction = 0;
  28. struct str_instruction buffer[3*NB_INSTRUCTIONS];
  29. void add_instruction(enum instruction_t inst, int param1, int param2, int param3) {
  30. struct str_instruction my_instruction = {inst, param1, param2, param3};
  31. buffer[last_instruction] = my_instruction;
  32. last_instruction++;
  33. }
  34. void write_asm(FILE * file) {
  35. int i = 0;
  36. while (i<MEM_INST_SIZE) {
  37. if (buffer[i].instruction == ADD) {
  38. fprintf(file, "ADD %d %d %d\n", buffer[i].param1, buffer[i].param2, buffer[i].param3);
  39. } else if (buffer[i].instruction == NOP) {
  40. fprintf(file, "NOP 0 0 0\n");
  41. } else if (buffer[i].instruction == SUB) {
  42. fprintf(file, "SUB %d %d %d\n", buffer[i].param1, buffer[i].param2, buffer[i].param3);
  43. } else if (buffer[i].instruction == MUL) {
  44. fprintf(file, "MUL %d %d %d\n", buffer[i].param1, buffer[i].param2, buffer[i].param3);
  45. } else if (buffer[i].instruction == DIV) {
  46. fprintf(file, "DIV %d %d %d\n", buffer[i].param1, buffer[i].param2, buffer[i].param3);
  47. } else if (buffer[i].instruction == AFC) {
  48. fprintf(file, "AFC %d %d\n", buffer[i].param1, buffer[i].param2);
  49. } else if (buffer[i].instruction == CPY) {
  50. fprintf(file, "CPY %d %d\n", buffer[i].param1, buffer[i].param2);
  51. } else if (buffer[i].instruction == LOAD) {
  52. fprintf(file, "LOAD %d %d\n", buffer[i].param1, buffer[i].param2);
  53. } else if (buffer[i].instruction == STORE) {
  54. fprintf(file, "STORE %d %d\n", buffer[i].param1, buffer[i].param2);
  55. } else {
  56. printf("Error: unexpected instruction: %d\n", buffer[i].instruction);
  57. exit(1);
  58. }
  59. i++;
  60. }
  61. }
  62. void int_2_bin(char * buff, int n) {
  63. int _m = n;
  64. for (int i = 0; i < 32; i++) {
  65. buff[31 - i] = ((_m & (1 << 31)) ? '1' : '0');
  66. _m = _m << 1;
  67. }
  68. }
  69. void convert_to_binary_on_N(int value, int N, char * buff) {
  70. char tampon[33];
  71. int_2_bin(tampon, value);
  72. int i;
  73. for (i = N-1; i>=0; i--) {
  74. buff[N-1-i] = tampon[i];
  75. }
  76. buff[N] = '\0';
  77. }
  78. void write_instruction_binary(FILE * file, struct str_instruction instr, int compact, int printSeparator) {
  79. char buff1[33];
  80. char buff2[33];
  81. char buff3[33];
  82. char buff4[33];
  83. convert_to_binary_on_N(instr.instruction, NB_BITS_INSTRUCTION, buff1);
  84. convert_to_binary_on_N(instr.param1, NB_BITS, buff2);
  85. convert_to_binary_on_N(instr.param2, NB_BITS, buff3);
  86. convert_to_binary_on_N(instr.param3, NB_BITS, buff4);
  87. if (compact) {
  88. fprintf(file, "%s%s%s%s", buff1, buff2, buff3, buff4);
  89. } else {
  90. fprintf(file, "\"%s%s%s%s\"", buff1, buff2, buff3, buff4);
  91. if (printSeparator) {
  92. fprintf(file, ", ");
  93. }
  94. }
  95. }
  96. void write_code_machine(FILE * file) {
  97. int i = MEM_INST_SIZE - 1;
  98. fprintf(file, "signal memory: MEMORY_TYPE := (");
  99. while (i >= 0) {
  100. write_instruction_binary(file, buffer[i], 0, i != 0);
  101. i--;
  102. }
  103. fprintf(file, ");");
  104. }
  105. void write_code_machine_compact(FILE * file) {
  106. fprintf(file, "\"");
  107. int i = MEM_INST_SIZE - 1;
  108. while (i >= 0) {
  109. write_instruction_binary(file, buffer[i], 1, 0);
  110. i--;
  111. }
  112. fprintf(file, "\"\n");
  113. }
  114. struct case_adresse {
  115. int adresse;
  116. int registre;
  117. char modifie;
  118. };
  119. struct case_adresse tableau[MEM_SIZE];
  120. int registres[NB_REG];
  121. void init (void) {
  122. int i;
  123. struct case_adresse case_courante = {0, -1, 0};
  124. for (i=0; i<MEM_SIZE; i++) {
  125. case_courante.adresse = i;
  126. tableau[i] = case_courante;
  127. }
  128. for (i=0; i<NB_REG; i++) {
  129. registres[i] = 0;
  130. }
  131. struct str_instruction nop = {NOP, 0, 0, 0};
  132. for (i=0; i<MEM_INST_SIZE; i++) {
  133. buffer[i] = nop;
  134. }
  135. }
  136. void print_case_adresse(struct case_adresse case_courante) {
  137. printf("{addr : %d ; reg : %d ; modi : %d}\n", case_courante.adresse, case_courante.registre, (int)case_courante.modifie);
  138. }
  139. void print() {
  140. int i;
  141. for (i=0; i<MEM_SIZE; i++) {
  142. print_case_adresse(tableau[i]);
  143. }
  144. }
  145. struct case_adresse get_info(int adresse) {
  146. return tableau[adresse];
  147. }
  148. int get_adresse (int registre) {
  149. int i = 0;
  150. while (i < MEM_SIZE && tableau[i].registre != registre) {
  151. i++;
  152. }
  153. if (i == MEM_SIZE) {
  154. return -1;
  155. } else {
  156. return tableau[i].adresse;
  157. }
  158. }
  159. void set_registre(int adresse, int registre) {
  160. tableau[adresse].registre = registre;
  161. }
  162. void set_modifie(int adresse, char modifie) {
  163. tableau[adresse].modifie = modifie;
  164. }
  165. void increment_time() {
  166. int i;
  167. for (i=0; i<NB_REG; i++) {
  168. registres[i]++;
  169. }
  170. }
  171. void refresh_registre(int registre) {
  172. registres[registre] = 0;
  173. }
  174. int get_register() {
  175. int i;
  176. int index_max = 0;
  177. for (i=0; i<NB_REG; i++) {
  178. if (registres[index_max] < registres[i]) {
  179. index_max = i;
  180. }
  181. }
  182. return index_max;
  183. }
  184. int get_reg_write(int adresse, int * added_instruction) {
  185. if (adresse == -1) {
  186. int dispo = get_register();
  187. int previous_addr = get_adresse(dispo);
  188. if (previous_addr != -1) {
  189. struct case_adresse ancienne_case = get_info(previous_addr);
  190. if (ancienne_case.modifie == 1) {
  191. add_instruction(STORE, previous_addr, dispo, 0);
  192. *added_instruction = (*added_instruction) + 1;
  193. set_modifie(previous_addr, 0);
  194. }
  195. set_registre(previous_addr, -1);
  196. }
  197. return dispo;
  198. } else {
  199. set_modifie(adresse, 1);
  200. struct case_adresse ma_case = get_info(adresse);
  201. if (ma_case.registre == -1) {
  202. int dispo = get_register();
  203. int previous_addr = get_adresse(dispo);
  204. if (previous_addr != -1) {
  205. struct case_adresse ancienne_case = get_info(previous_addr);
  206. if (ancienne_case.modifie == 1) {
  207. *added_instruction = (*added_instruction) + 1;
  208. add_instruction(STORE, previous_addr, dispo, 0);
  209. set_modifie(previous_addr, 0);
  210. }
  211. set_registre(previous_addr, -1);
  212. }
  213. set_registre(adresse, dispo);
  214. refresh_registre(dispo);
  215. return dispo;
  216. } else {
  217. refresh_registre(ma_case.registre);
  218. return ma_case.registre;
  219. }
  220. }
  221. }
  222. int get_reg_read(int adresse, int * added_instruction) {
  223. struct case_adresse ma_case = get_info(adresse);
  224. if (ma_case.registre == -1) {
  225. int dispo = get_register();
  226. int previous_addr = get_adresse(dispo);
  227. if (previous_addr != -1) {
  228. struct case_adresse ancienne_case = get_info(previous_addr);
  229. if (ancienne_case.modifie == 1) {
  230. *added_instruction = (*added_instruction) + 1;
  231. add_instruction(STORE, previous_addr, dispo, 0);
  232. set_modifie(previous_addr, 0);
  233. }
  234. set_registre(previous_addr, -1);
  235. }
  236. *added_instruction = (*added_instruction) + 1;
  237. add_instruction(LOAD, dispo, adresse, 0);
  238. set_registre(adresse, dispo);
  239. refresh_registre(dispo);
  240. return dispo;
  241. } else {
  242. refresh_registre(ma_case.registre);
  243. return ma_case.registre;
  244. }
  245. }
  246. void unlink(int adresse) {
  247. set_registre(adresse, -1);
  248. }
  249. int flush_and_init() {
  250. int i;
  251. int added_instruction = 0;
  252. for (i = 0; i<MEM_SIZE; i++) {
  253. if (tableau[i].registre != -1) {
  254. if (tableau[i].modifie == 0) {
  255. tableau[i].registre = -1;
  256. } else {
  257. add_instruction(STORE, i, tableau[i].registre, 0);
  258. added_instruction++;
  259. tableau[i].registre = -1;
  260. tableau[i].modifie = 0;
  261. }
  262. }
  263. }
  264. for (i=0; i<NB_REG; i++) {
  265. registres[i] = 0;
  266. }
  267. return added_instruction;
  268. }
  269. void new_instruction(int nb_inst) {
  270. static int last_intruction_adresse = 0;
  271. static int current_instruction = 0;
  272. traduction_JMP[current_instruction] = last_intruction_adresse;
  273. current_instruction++;
  274. last_intruction_adresse += nb_inst;
  275. }