axe_engine.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904
  1. /*
  2. * Andrea Di Biagio
  3. * Politecnico di Milano, 2007
  4. *
  5. * axe_engine.c
  6. * Formal Languages & Compilers Machine, 2007/2008
  7. *
  8. */
  9. #include <assert.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include "axe_engine.h"
  13. #include "symbol_table.h"
  14. #include "axe_errors.h"
  15. /* global variable errorcode */
  16. int errorcode;
  17. /* Function used when a compare is needed between two labels */
  18. static int compareVariables (void *Var_A, void *Var_B);
  19. /* Finalize the memory associated with an instruction */
  20. static void finalizeInstructions(t_list *instructions);
  21. /* Finalize the data segment */
  22. static void finalizeDataSegment(t_list *dataDirectives);
  23. /* finalize the informations associated with all the variables */
  24. static void finalizeVariables(t_list *variables);
  25. /* Translate the assembler directives (definitions inside the data segment */
  26. static void translateDataSegment(t_program_infos *program, FILE *fp);
  27. /* Translate all the instructions within the code segment */
  28. static void translateCodeSegment(t_program_infos *program, FILE *fp);
  29. /* print out to the file `fp' an opcode */
  30. static void printOpcode(int opcode, FILE *fp);
  31. /* print out to the file `fp' a register information */
  32. static void printRegister(t_axe_register *reg, FILE *fp);
  33. /* add a variable to the program */
  34. static void addVariable(t_program_infos *program, t_axe_variable *variable);
  35. /* create a new variable */
  36. void createVariable(t_program_infos *program, char *ID
  37. , int type, int isArray, int arraySize, int init_val)
  38. {
  39. t_axe_variable *var;
  40. /* test the preconditions */
  41. if (program == NULL)
  42. notifyError(AXE_PROGRAM_NOT_INITIALIZED);
  43. /* initialize a new variable */
  44. var = alloc_variable(ID, type, isArray, arraySize, init_val);
  45. if (var == NULL)
  46. notifyError(AXE_OUT_OF_MEMORY);
  47. /* assign a new label to the newly created variable `var' */
  48. var->labelID = newLabel(program);
  49. /* add the new variable to program */
  50. addVariable(program, var);
  51. }
  52. /* translate each instruction in his assembler symbolic representation */
  53. void translateCodeSegment(t_program_infos *program, FILE *fp)
  54. {
  55. t_list *current_element;
  56. t_axe_instruction *current_instruction;
  57. int _error;
  58. /* preconditions */
  59. if (fp == NULL)
  60. notifyError(AXE_INVALID_INPUT_FILE);
  61. if (program == NULL)
  62. {
  63. _error = fclose(fp);
  64. if (_error == EOF)
  65. notifyError(AXE_FCLOSE_ERROR);
  66. notifyError(AXE_PROGRAM_NOT_INITIALIZED);
  67. }
  68. /* initialize the current_element */
  69. current_element = program->instructions;
  70. /* write the .text directive */
  71. if (current_element != NULL)
  72. {
  73. if (fprintf(fp, "\t.text\n") < 0)
  74. {
  75. _error = fclose(fp);
  76. if (_error == EOF)
  77. notifyError(AXE_FCLOSE_ERROR);
  78. notifyError(AXE_FWRITE_ERROR);
  79. }
  80. }
  81. while (current_element != NULL)
  82. {
  83. /* retrieve the current instruction */
  84. current_instruction = (t_axe_instruction *) LDATA(current_element);
  85. assert(current_instruction != NULL);
  86. assert(current_instruction->opcode != INVALID_OPCODE);
  87. if (current_instruction->labelID != NULL)
  88. {
  89. /* create a string identifier for the label */
  90. if ( fprintf(fp, "L%d : \t"
  91. , (current_instruction->labelID)->labelID ) < 0)
  92. {
  93. _error = fclose(fp);
  94. if (_error == EOF)
  95. notifyError(AXE_FCLOSE_ERROR);
  96. notifyError(AXE_FWRITE_ERROR);
  97. }
  98. }
  99. else
  100. {
  101. /* create a string identifier for the label */
  102. if (fprintf(fp, "\t") < 0)
  103. {
  104. _error = fclose(fp);
  105. if (_error == EOF)
  106. notifyError(AXE_FCLOSE_ERROR);
  107. notifyError(AXE_FWRITE_ERROR);
  108. }
  109. }
  110. /* print the opcode */
  111. printOpcode(current_instruction->opcode, fp);
  112. if ( (current_instruction->opcode == HALT)
  113. || (current_instruction->opcode == NOP) )
  114. {
  115. if (fprintf(fp, "\n") < 0)
  116. {
  117. _error = fclose(fp);
  118. if (_error == EOF)
  119. notifyError(AXE_FCLOSE_ERROR);
  120. notifyError(AXE_FWRITE_ERROR);
  121. }
  122. /* update the current_element */
  123. current_element = LNEXT(current_element);
  124. continue;
  125. }
  126. if (fputc(' ', fp) == EOF)
  127. {
  128. _error = fclose(fp);
  129. if (_error == EOF)
  130. notifyError(AXE_FCLOSE_ERROR);
  131. notifyError(AXE_FWRITE_ERROR);
  132. }
  133. if (current_instruction->reg_1 != NULL)
  134. {
  135. printRegister(current_instruction->reg_1, fp);
  136. if (fputc(' ', fp) == EOF)
  137. {
  138. _error = fclose(fp);
  139. if (_error == EOF)
  140. notifyError(AXE_FCLOSE_ERROR);
  141. notifyError(AXE_FWRITE_ERROR);
  142. }
  143. }
  144. if (current_instruction->reg_2 != NULL)
  145. {
  146. printRegister(current_instruction->reg_2, fp);
  147. if (errorcode != AXE_OK)
  148. return;
  149. if (fputc(' ', fp) == EOF)
  150. {
  151. _error = fclose(fp);
  152. if (_error == EOF)
  153. notifyError(AXE_FCLOSE_ERROR);
  154. notifyError(AXE_FWRITE_ERROR);
  155. }
  156. }
  157. if (current_instruction->reg_3 != NULL)
  158. {
  159. printRegister(current_instruction->reg_3, fp);
  160. if (fprintf(fp, "\n") < 0) {
  161. _error = fclose(fp);
  162. if (_error == EOF)
  163. notifyError(AXE_FCLOSE_ERROR);
  164. notifyError(AXE_FWRITE_ERROR);
  165. }
  166. /* update the current_element */
  167. current_element = LNEXT(current_element);
  168. continue;
  169. }
  170. if (current_instruction->address != NULL)
  171. {
  172. if ((current_instruction->address)->type == ADDRESS_TYPE)
  173. {
  174. if (fprintf(fp, "%d", (current_instruction->address)->addr) < 0)
  175. {
  176. _error = fclose(fp);
  177. if (_error == EOF)
  178. notifyError(AXE_FCLOSE_ERROR);
  179. notifyError(AXE_FWRITE_ERROR);
  180. }
  181. }
  182. else
  183. {
  184. assert((current_instruction->address)->type == LABEL_TYPE);
  185. if ( fprintf(fp, "L%d"
  186. , ((current_instruction->address)->labelID)
  187. ->labelID) < 0)
  188. {
  189. _error = fclose(fp);
  190. if (_error == EOF)
  191. notifyError(AXE_FCLOSE_ERROR);
  192. notifyError(AXE_FWRITE_ERROR);
  193. }
  194. }
  195. if (fprintf(fp, "\n") < 0) {
  196. _error = fclose(fp);
  197. if (_error == EOF)
  198. notifyError(AXE_FCLOSE_ERROR);
  199. notifyError(AXE_FWRITE_ERROR);
  200. }
  201. /* update the current_element */
  202. current_element = LNEXT(current_element);
  203. continue;
  204. }
  205. if (fprintf(fp, "#%d", current_instruction->immediate) < 0)
  206. {
  207. _error = fclose(fp);
  208. if (_error == EOF)
  209. notifyError(AXE_FCLOSE_ERROR);
  210. notifyError(AXE_FWRITE_ERROR);
  211. }
  212. if (fprintf(fp, "\n") < 0) {
  213. _error = fclose(fp);
  214. if (_error == EOF)
  215. notifyError(AXE_FCLOSE_ERROR);
  216. notifyError(AXE_FWRITE_ERROR);
  217. }
  218. /* loop termination condition */
  219. current_element = LNEXT(current_element);
  220. }
  221. }
  222. void translateDataSegment(t_program_infos *program, FILE *fp)
  223. {
  224. t_list *current_element;
  225. t_axe_data *current_data;
  226. int _error;
  227. int fprintf_error;
  228. /* preconditions */
  229. if (fp == NULL)
  230. notifyError(AXE_INVALID_INPUT_FILE);
  231. /* initialize the local variable `fprintf_error' */
  232. fprintf_error = 0;
  233. if (program == NULL)
  234. {
  235. _error = fclose(fp);
  236. if (_error == EOF)
  237. notifyError(AXE_FCLOSE_ERROR);
  238. notifyError(AXE_PROGRAM_NOT_INITIALIZED);
  239. }
  240. /* initialize the value of `current_element' */
  241. current_element = program->data;
  242. /* write the .data directive */
  243. if (current_element != NULL)
  244. {
  245. if (fprintf(fp, "\t.data\n") < 0)
  246. {
  247. _error = fclose(fp);
  248. if (_error == EOF)
  249. notifyError(AXE_FCLOSE_ERROR);
  250. notifyError(AXE_FWRITE_ERROR);
  251. }
  252. }
  253. /* iterate all the elements inside the data segment */
  254. while (current_element != NULL)
  255. {
  256. /* retrieve the current data element */
  257. current_data = (t_axe_data *) LDATA(current_element);
  258. /* assertions */
  259. assert (current_data->directiveType != DIR_INVALID);
  260. /* create a string identifier for the label */
  261. if ( (current_data->labelID != NULL)
  262. && ((current_data->labelID)->labelID != LABEL_UNSPECIFIED) )
  263. {
  264. fprintf_error = fprintf(fp, "L%d : \t"
  265. , (current_data->labelID)->labelID);
  266. }
  267. else
  268. {
  269. fprintf_error = fprintf(fp, "\t");
  270. }
  271. /* test if an error occurred while executing the `fprintf' function */
  272. if (fprintf_error < 0)
  273. {
  274. _error = fclose(fp);
  275. if (_error == EOF)
  276. notifyError(AXE_FCLOSE_ERROR);
  277. notifyError(AXE_FWRITE_ERROR);
  278. }
  279. /* print the directive identifier */
  280. if (current_data->directiveType == DIR_WORD)
  281. {
  282. if (fprintf(fp, ".WORD ") < 0)
  283. {
  284. _error = fclose(fp);
  285. if (_error == EOF)
  286. notifyError(AXE_FCLOSE_ERROR);
  287. notifyError(AXE_FWRITE_ERROR);
  288. }
  289. }
  290. else if (current_data->directiveType == DIR_SPACE)
  291. {
  292. if (fprintf(fp, ".SPACE ") < 0)
  293. {
  294. _error = fclose(fp);
  295. if (_error == EOF)
  296. notifyError(AXE_FCLOSE_ERROR);
  297. notifyError(AXE_FWRITE_ERROR);
  298. }
  299. }
  300. /* print the value associated with the directive */
  301. if (fprintf(fp, "%d\n", current_data->value) < 0)
  302. {
  303. _error = fclose(fp);
  304. if (_error == EOF)
  305. notifyError(AXE_FCLOSE_ERROR);
  306. notifyError(AXE_FWRITE_ERROR);
  307. }
  308. /* loop termination condition */
  309. current_element = LNEXT(current_element);
  310. }
  311. }
  312. void finalizeDataSegment(t_list *dataDirectives)
  313. {
  314. t_list *current_element;
  315. t_axe_data *current_data;
  316. /* nothing to finalize */
  317. if (dataDirectives == NULL)
  318. return;
  319. current_element = dataDirectives;
  320. while(current_element != NULL)
  321. {
  322. /* retrieve the current instruction */
  323. current_data = (t_axe_data *) LDATA(current_element);
  324. if (current_data != NULL)
  325. free_Data(current_data);
  326. current_element = LNEXT(current_element);
  327. }
  328. /* free the list of instructions */
  329. freeList(dataDirectives);
  330. }
  331. void finalizeInstructions(t_list *instructions)
  332. {
  333. t_list *current_element;
  334. t_axe_instruction *current_instr;
  335. /* nothing to finalize */
  336. if (instructions == NULL)
  337. return;
  338. current_element = instructions;
  339. while(current_element != NULL)
  340. {
  341. /* retrieve the current instruction */
  342. current_instr = (t_axe_instruction *) LDATA(current_element);
  343. if (current_instr != NULL)
  344. free_Instruction(current_instr);
  345. current_element = LNEXT(current_element);
  346. }
  347. /* free the list of instructions */
  348. freeList(instructions);
  349. }
  350. int compareVariables (void *Var_A, void *Var_B)
  351. {
  352. t_axe_variable *va;
  353. t_axe_variable *vb;
  354. if (Var_A == NULL)
  355. {
  356. if (Var_B == NULL)
  357. return 1;
  358. }
  359. if (Var_B == NULL)
  360. return 0;
  361. va = (t_axe_variable *) Var_A;
  362. vb = (t_axe_variable *) Var_B;
  363. /* test if the name is the same */
  364. return (!strcmp(va->ID, vb->ID));
  365. }
  366. t_axe_variable * getVariable
  367. (t_program_infos *program, char *ID)
  368. {
  369. t_axe_variable search_pattern;
  370. t_list *elementFound;
  371. /* preconditions */
  372. if (program == NULL)
  373. notifyError(AXE_PROGRAM_NOT_INITIALIZED);
  374. if (ID == NULL)
  375. notifyError(AXE_VARIABLE_ID_UNSPECIFIED);
  376. /* initialize the pattern */
  377. search_pattern.ID = ID;
  378. /* search inside the list of variables */
  379. elementFound = CustomfindElement
  380. (program->variables, &search_pattern, compareVariables);
  381. /* if the element is found return it to the caller. Otherwise return NULL. */
  382. if (elementFound != NULL)
  383. return (t_axe_variable *) LDATA(elementFound);
  384. return NULL;
  385. }
  386. /* initialize an instance of `t_program_infos' */
  387. t_program_infos * allocProgramInfos()
  388. {
  389. t_program_infos *result;
  390. /* initialize the local variable `result' */
  391. result = (t_program_infos *)
  392. _AXE_ALLOC_FUNCTION(sizeof(t_program_infos));
  393. /* verify if an error occurred during the memory allocation
  394. * process */
  395. if (result == NULL)
  396. notifyError(AXE_OUT_OF_MEMORY);
  397. /* initialize the new instance of `result' */
  398. result->variables = NULL;
  399. result->instructions = NULL;
  400. result->data = NULL;
  401. result->current_register = 1; /* we are excluding the register R0 */
  402. result->lmanager = initialize_label_manager();
  403. if (result->lmanager == NULL)
  404. {
  405. finalizeProgramInfos(result);
  406. notifyError(AXE_OUT_OF_MEMORY);
  407. }
  408. result->sy_table = initialize_sy_table();
  409. /* test if the sy_table is a NULL pointer */
  410. if (result->sy_table == NULL)
  411. {
  412. finalizeProgramInfos(result);
  413. notifyError(AXE_OUT_OF_MEMORY);
  414. }
  415. /* postcondition: return an instance of `t_program_infos' */
  416. return result;
  417. }
  418. /* add an instruction at the tail of the list `program->instructions'.
  419. * Returns an error code. */
  420. void addInstruction(t_program_infos *program, t_axe_instruction *instr)
  421. {
  422. /* test the preconditions */
  423. if (program == NULL)
  424. notifyError(AXE_PROGRAM_NOT_INITIALIZED);
  425. if (instr == NULL)
  426. notifyError(AXE_INVALID_INSTRUCTION);
  427. if (program->lmanager == NULL)
  428. notifyError(AXE_INVALID_LABEL_MANAGER);
  429. instr->labelID = assign_label(program->lmanager);
  430. /* update the list of instructions */
  431. program->instructions = addElement(program->instructions, instr, -1);
  432. }
  433. /* reserve a new label identifier for future uses */
  434. t_axe_label * newLabel(t_program_infos *program)
  435. {
  436. /* test the preconditions */
  437. if (program == NULL)
  438. notifyError(AXE_PROGRAM_NOT_INITIALIZED);
  439. if (program->lmanager == NULL)
  440. notifyError(AXE_INVALID_LABEL_MANAGER);
  441. return newLabelID(program->lmanager);
  442. }
  443. /* assign a new label identifier to the next instruction */
  444. t_axe_label * assignLabel(t_program_infos *program, t_axe_label *label)
  445. {
  446. /* test the preconditions */
  447. if (program == NULL)
  448. notifyError(AXE_PROGRAM_NOT_INITIALIZED);
  449. if (program->lmanager == NULL)
  450. notifyError(AXE_INVALID_LABEL_MANAGER);
  451. /* fix the label */
  452. return assignLabelID(program->lmanager, label);
  453. }
  454. /* reserve a new label identifier */
  455. t_axe_label * assignNewLabel(t_program_infos *program)
  456. {
  457. t_axe_label * reserved_label;
  458. /* reserve a new label */
  459. reserved_label = newLabel(program);
  460. if (reserved_label == NULL)
  461. return NULL;
  462. /* fix the label */
  463. return assignLabel(program, reserved_label);
  464. }
  465. void addVariable(t_program_infos *program, t_axe_variable *variable)
  466. {
  467. t_axe_variable *variableFound;
  468. t_axe_data *new_data_info;
  469. int sy_error;
  470. /* test the preconditions */
  471. if (variable == NULL)
  472. notifyError(AXE_INVALID_VARIABLE);
  473. if (program == NULL)
  474. {
  475. free_variable(variable);
  476. notifyError(AXE_PROGRAM_NOT_INITIALIZED);
  477. }
  478. if (variable->ID == NULL)
  479. {
  480. free_variable(variable);
  481. notifyError(AXE_VARIABLE_ID_UNSPECIFIED);
  482. }
  483. if (variable->type == UNKNOWN_TYPE)
  484. {
  485. free_variable(variable);
  486. notifyError(AXE_INVALID_TYPE);
  487. }
  488. if (variable->isArray)
  489. {
  490. if (variable->arraySize <= 0)
  491. {
  492. free_variable(variable);
  493. notifyError(AXE_INVALID_ARRAY_SIZE);
  494. }
  495. }
  496. if (variable->labelID == NULL)
  497. {
  498. free_variable(variable);
  499. notifyError(AXE_INVALID_LABEL);
  500. }
  501. /* we have to test if already exists a variable with the same ID */
  502. variableFound = getVariable(program, variable->ID);
  503. if (variableFound != NULL)
  504. {
  505. free_variable(variable);
  506. notifyError(AXE_VARIABLE_ALREADY_DECLARED);
  507. }
  508. /* now we can add the new variable to the program */
  509. program->variables = addElement(program->variables, variable, -1);
  510. /* create an instance of `t_axe_data' */
  511. if (variable->type == INTEGER_TYPE)
  512. {
  513. if (variable->isArray)
  514. {
  515. new_data_info = alloc_data
  516. (DIR_SPACE, (variable->arraySize * 4), variable->labelID);
  517. if (new_data_info == NULL)
  518. notifyError(AXE_OUT_OF_MEMORY);
  519. }
  520. else
  521. {
  522. new_data_info = alloc_data
  523. (DIR_WORD, variable->init_val, variable->labelID);
  524. if (new_data_info == NULL)
  525. notifyError(AXE_OUT_OF_MEMORY);
  526. }
  527. }
  528. /* update the list of directives */
  529. program->data = addElement(program->data, new_data_info, -1);
  530. /* update the content of the symbol table */
  531. sy_error = putSym(program->sy_table, variable->ID, variable->type);
  532. if (sy_error != SY_TABLE_OK)
  533. notifyError(AXE_SY_TABLE_ERROR);
  534. }
  535. int getNewRegister(t_program_infos *program)
  536. {
  537. int result;
  538. /* test the preconditions */
  539. if (program == NULL)
  540. notifyError(AXE_PROGRAM_NOT_INITIALIZED);
  541. result = program->current_register;
  542. program->current_register++;
  543. /* return the current label identifier */
  544. return result;
  545. }
  546. void finalizeProgramInfos(t_program_infos *program)
  547. {
  548. if (program == NULL)
  549. return;
  550. if (program->variables != NULL)
  551. finalizeVariables(program->variables);
  552. if (program->instructions != NULL)
  553. finalizeInstructions(program->instructions);
  554. if (program->data != NULL)
  555. finalizeDataSegment(program->data);
  556. if (program->lmanager != NULL)
  557. finalize_label_manager(program->lmanager);
  558. if (program->sy_table != NULL)
  559. finalize_sy_table(program->sy_table);
  560. _AXE_FREE_FUNCTION(program);
  561. }
  562. void writeAssembly(t_program_infos *program, char *output_file)
  563. {
  564. FILE *fp;
  565. int _error;
  566. /* test the preconditions */
  567. if (program == NULL)
  568. notifyError(AXE_PROGRAM_NOT_INITIALIZED);
  569. /* If necessary, set the value of `output_file' to "output.asm" */
  570. if (output_file == NULL)
  571. {
  572. /* set "output.o" as output file name */
  573. output_file = "output.asm";
  574. }
  575. #ifndef NDEBUG
  576. fprintf(stdout, "\n\n*******************************************\n");
  577. fprintf(stdout, "INITIALIZING OUTPUT FILE: %s. \n", output_file);
  578. fprintf(stdout, "CODE SEGMENT has a size of %d instructions \n"
  579. , getLength(program->instructions));
  580. fprintf(stdout, "DATA SEGMENT has a size of %d elements \n"
  581. , getLength(program->data));
  582. fprintf(stdout, "NUMBER OF LABELS : %d. \n"
  583. , get_number_of_labels(program->lmanager));
  584. fprintf(stdout, "*******************************************\n\n");
  585. #endif
  586. /* open a new file */
  587. fp = fopen(output_file, "w");
  588. if (fp == NULL)
  589. notifyError(AXE_FOPEN_ERROR);
  590. /* print the data segment */
  591. translateDataSegment(program, fp);
  592. /* print the code segment */
  593. translateCodeSegment(program, fp);
  594. /* close the file and return */
  595. _error = fclose(fp);
  596. if (_error == EOF)
  597. notifyError(AXE_FCLOSE_ERROR);
  598. }
  599. void printOpcode(int opcode, FILE *fp)
  600. {
  601. char *opcode_to_string;
  602. int _error;
  603. /* preconditions: fp must be different from NULL */
  604. if (fp == NULL)
  605. notifyError(AXE_INVALID_INPUT_FILE);
  606. switch(opcode)
  607. {
  608. case ADD : opcode_to_string = "ADD"; break;
  609. case SUB : opcode_to_string = "SUB"; break;
  610. case ANDL : opcode_to_string = "ANDL"; break;
  611. case ORL : opcode_to_string = "ORL"; break;
  612. case EORL : opcode_to_string = "EORL"; break;
  613. case ANDB : opcode_to_string = "ANDB"; break;
  614. case ORB : opcode_to_string = "ORB"; break;
  615. case EORB : opcode_to_string = "EORB"; break;
  616. case MUL : opcode_to_string = "MUL"; break;
  617. case DIV : opcode_to_string = "DIV"; break;
  618. case SHL : opcode_to_string = "SHL"; break;
  619. case SHR : opcode_to_string = "SHR"; break;
  620. case ROTL : opcode_to_string = "ROTL"; break;
  621. case ROTR : opcode_to_string = "ROTR"; break;
  622. case NEG : opcode_to_string = "NEG"; break;
  623. case SPCL : opcode_to_string = "SPCL"; break;
  624. case ADDI : opcode_to_string = "ADDI"; break;
  625. case SUBI : opcode_to_string = "SUBI"; break;
  626. case ANDLI : opcode_to_string = "ANDLI"; break;
  627. case ORLI : opcode_to_string = "ORLI"; break;
  628. case EORLI : opcode_to_string = "EORLI"; break;
  629. case ANDBI : opcode_to_string = "ANDBI"; break;
  630. case ORBI : opcode_to_string = "ORBI"; break;
  631. case EORBI : opcode_to_string = "EORBI"; break;
  632. case MULI : opcode_to_string = "MULI"; break;
  633. case DIVI : opcode_to_string = "DIVI"; break;
  634. case SHLI : opcode_to_string = "SHLI"; break;
  635. case SHRI : opcode_to_string = "SHRI"; break;
  636. case ROTLI : opcode_to_string = "ROTLI"; break;
  637. case ROTRI : opcode_to_string = "ROTRI"; break;
  638. case NOTL : opcode_to_string = "NOTL"; break;
  639. case NOTB : opcode_to_string = "NOTB"; break;
  640. case NOP : opcode_to_string = "NOP"; break;
  641. case MOVA : opcode_to_string = "MOVA"; break;
  642. case JSR : opcode_to_string = "JSR"; break;
  643. case RET : opcode_to_string = "RET"; break;
  644. case HALT : opcode_to_string = "HALT"; break;
  645. case BT : opcode_to_string = "BT"; break;
  646. case BF : opcode_to_string = "BF"; break;
  647. case BHI : opcode_to_string = "BHI"; break;
  648. case BLS : opcode_to_string = "BLS"; break;
  649. case BCC : opcode_to_string = "BCC"; break;
  650. case BCS : opcode_to_string = "BCS"; break;
  651. case BNE : opcode_to_string = "BNE"; break;
  652. case BEQ : opcode_to_string = "BEQ"; break;
  653. case BVC : opcode_to_string = "BVC"; break;
  654. case BVS : opcode_to_string = "BVS"; break;
  655. case BPL : opcode_to_string = "BPL"; break;
  656. case BMI : opcode_to_string = "BMI"; break;
  657. case BGE : opcode_to_string = "BGE"; break;
  658. case BLT : opcode_to_string = "BLT"; break;
  659. case BGT : opcode_to_string = "BGT"; break;
  660. case BLE : opcode_to_string = "BLE"; break;
  661. case LOAD : opcode_to_string = "LOAD"; break;
  662. case STORE : opcode_to_string = "STORE"; break;
  663. case SEQ : opcode_to_string = "SEQ"; break;
  664. case SGE : opcode_to_string = "SGE"; break;
  665. case SGT : opcode_to_string = "SGT"; break;
  666. case SLE : opcode_to_string = "SLE"; break;
  667. case SLT : opcode_to_string = "SLT"; break;
  668. case SNE : opcode_to_string = "SNE"; break;
  669. case AXE_READ : opcode_to_string = "READ"; break;
  670. case AXE_WRITE : opcode_to_string = "WRITE"; break;
  671. default :
  672. /* close the file and return */
  673. _error = fclose(fp);
  674. if (_error == EOF)
  675. notifyError(AXE_FCLOSE_ERROR);
  676. notifyError(AXE_INVALID_OPCODE);
  677. }
  678. /* postconditions */
  679. if (fprintf(fp, "%s", opcode_to_string) < 0)
  680. {
  681. _error = fclose(fp);
  682. if (_error == EOF)
  683. notifyError(AXE_FCLOSE_ERROR);
  684. notifyError(AXE_FWRITE_ERROR);
  685. }
  686. }
  687. void printRegister(t_axe_register *reg, FILE *fp)
  688. {
  689. int _error;
  690. /* preconditions: fp must be different from NULL */
  691. if (fp == NULL)
  692. notifyError(AXE_INVALID_INPUT_FILE);
  693. if (reg == NULL)
  694. {
  695. _error = fclose(fp);
  696. if (_error == EOF)
  697. notifyError(AXE_FCLOSE_ERROR);
  698. notifyError(AXE_INVALID_REGISTER_INFO);
  699. }
  700. if (reg->ID == REG_INVALID)
  701. {
  702. _error = fclose(fp);
  703. if (_error == EOF)
  704. notifyError(AXE_FCLOSE_ERROR);
  705. notifyError(AXE_INVALID_REGISTER_INFO);
  706. }
  707. if (reg->indirect)
  708. {
  709. if (fprintf(fp, "(R%d)", reg->ID) < 0)
  710. {
  711. _error = fclose(fp);
  712. if (_error == EOF)
  713. notifyError(AXE_FCLOSE_ERROR);
  714. notifyError(AXE_FWRITE_ERROR);
  715. }
  716. }
  717. else
  718. {
  719. if (fprintf(fp, "R%d", reg->ID) < 0)
  720. {
  721. _error = fclose(fp);
  722. if (_error == EOF)
  723. notifyError(AXE_FCLOSE_ERROR);
  724. notifyError(AXE_FWRITE_ERROR);
  725. }
  726. }
  727. }
  728. t_axe_label * getLabelFromVariableID(t_program_infos *program, char *ID)
  729. {
  730. t_axe_variable *var;
  731. var = getVariable(program, ID);
  732. if (var == NULL)
  733. return NULL;
  734. /* test the postconditions */
  735. assert(var->labelID != NULL);
  736. return var->labelID;
  737. }
  738. void finalizeVariables(t_list *variables)
  739. {
  740. t_list *current_element;
  741. t_axe_variable *current_var;
  742. if (variables == NULL)
  743. return;
  744. /* initialize the `current_element' */
  745. current_element = variables;
  746. while(current_element != NULL)
  747. {
  748. current_var = (t_axe_variable *) LDATA(current_element);
  749. if (current_var != NULL)
  750. {
  751. if (current_var->ID != NULL)
  752. free(current_var->ID);
  753. _AXE_FREE_FUNCTION(current_var);
  754. }
  755. current_element = LNEXT(current_element);
  756. }
  757. /* free the list of variables */
  758. freeList(variables);
  759. }