TargetGen.java 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. /*
  2. * To change this license header, choose License Headers in Project Properties.
  3. * To change this template file, choose Tools | Templates
  4. * and open the template in the editor.
  5. */
  6. package API;
  7. import common.Block;
  8. import common.Code;
  9. import common.DataLayout;
  10. import common.Instruction;
  11. import common.IvannosysTargetArch;
  12. import java.util.ArrayList;
  13. import java.util.HashMap;
  14. import java.util.Iterator;
  15. import java.util.LinkedList;
  16. import java.util.Map;
  17. import java.util.Set;
  18. import java.util.logging.Level;
  19. import java.util.logging.Logger;
  20. /**
  21. *
  22. * @author EUGENIO CARVALHO
  23. */
  24. public abstract class TargetGen implements IvannosysTargetArch {
  25. protected HashMap<String, ExportInterface> exportMethods = new HashMap<>();
  26. protected Code target;
  27. protected Code IR;
  28. protected Instruction prev = null, next = null;
  29. protected Instruction currentIrInstruction;
  30. protected Instruction currentTargetInstruction;
  31. public TargetGen(String id) {
  32. BaseGenInit(id);
  33. }
  34. /**
  35. * Like Sprintf
  36. *
  37. * @param format
  38. * @param args
  39. * @return
  40. */
  41. protected String F(String format, Object... args) {
  42. return String.format(format, args);
  43. }
  44. /**
  45. * Retorna o contexto do bloco atual
  46. *
  47. * @return
  48. */
  49. public DataLayout Context() {
  50. return Context("");
  51. }
  52. /**
  53. * Retorna o contexto do bloco atual <br>
  54. * Se var contem "G" retorna o contexto global
  55. *
  56. * @param var
  57. * @return
  58. */
  59. public DataLayout Context(String var) {
  60. if (var.contains("G")) {
  61. return IR.GlobalContext();
  62. }
  63. return IR.Block().Context();
  64. }
  65. public common.Offset Offset(String var) throws Exception {
  66. return Context(var).Offset(var);
  67. }
  68. public void BaseGenInit(String id) {
  69. target = new Code(id);
  70. }
  71. public Code getTarget() {
  72. return target;
  73. }
  74. public void setTarget(Code target) {
  75. this.target = target;
  76. }
  77. public Code getIR() {
  78. return IR;
  79. }
  80. public ExportInterface GetExportMethod(String id) throws Exception {
  81. id = id.trim();
  82. if (!exportMethods.containsKey(id)) {
  83. Set<String> set = exportMethods.keySet();
  84. String[] valids = new String[set.size()];
  85. set.toArray(valids);
  86. throw new Exception(String.format(
  87. "O método de exportação '%s' não foi definido no alvo '%s'. Métodos disponiveis: %s",
  88. id,
  89. target.Name(),
  90. Utils.Join(valids, ", ")));
  91. }
  92. return exportMethods.get(id);
  93. }
  94. public HashMap<String, ExportInterface> GetExportMethods() {
  95. return exportMethods;
  96. }
  97. public IvannosysTargetArch Init(Code tac) throws Exception {
  98. // Verifica se o codigo gerado vai ser util caso contrario aborta o processo;
  99. ArrayList<String> methods = BuildParams.Get("export");
  100. if (methods.isEmpty()) {
  101. throw new Exception(String.format("Nenhum método de exportação definido para o alvo '%s'", target.Name()));
  102. }
  103. IR = tac;
  104. // target.GlobalContext().copy(tac.GlobalContext());
  105. target.Parent = IR;
  106. return this;
  107. }
  108. protected Instruction Add(Instruction inst) throws Exception {
  109. if (currentIrInstruction != null) {
  110. inst.Set("tac.position", currentIrInstruction.Get("block.position"));
  111. }
  112. target.Block().Add(inst);
  113. currentTargetInstruction = inst;
  114. return inst;
  115. }
  116. public TargetGen AddExportOption(String id, ExportInterface exp) {
  117. exportMethods.put(id.trim(), exp);
  118. return this;
  119. }
  120. @Override
  121. public IvannosysTargetArch Format() {
  122. try {
  123. String code = target.Dump();
  124. System.out.println("Target[" + target.Name() + "]:\n" + code);
  125. } catch (Exception ex) {
  126. Logger.getLogger(TargetGen.class.getName()).log(Level.SEVERE, null, ex);
  127. }
  128. return this;
  129. }
  130. @Override
  131. public IvannosysTargetArch Compile() {
  132. try {
  133. // Traduz o codigo intermediario para o alvo
  134. Translate();
  135. } catch (Exception ex) {
  136. Logger.getLogger(TargetGen.class.getName()).log(Level.SEVERE, null, ex);
  137. }
  138. return this;
  139. }
  140. protected void Translate() throws Exception {
  141. String targetID = target.Name(), id;
  142. target.Parent = IR;
  143. Block block;
  144. Middleware.Trigger(target, targetID, "before.translate");
  145. for (Map.Entry<String, Block> b : IR.Blocks().entrySet()) {
  146. id = b.getKey();
  147. block = b.getValue();
  148. if (block.Type() == Block.TYPE_CTRL) {
  149. continue;
  150. }
  151. IR.Use(id);
  152. target.OpenBlock(id);
  153. Middleware.Trigger(target, targetID, "before.translate.block");
  154. Prolog(id);
  155. TranslateBlock(block);
  156. Epilog(id);
  157. target.CloseBlock();
  158. Middleware.Trigger(target, targetID, "after.translate.block");
  159. }
  160. target.UpdatePositions();
  161. Middleware.Trigger(target, targetID, "after.translate");
  162. }
  163. @Override
  164. public IvannosysTargetArch Export() throws Exception {
  165. ArrayList<String> methods = BuildParams.Get("export");
  166. for (String method : methods) {
  167. GetExportMethod(method).Exec(IR, target);
  168. }
  169. return this;
  170. }
  171. protected void TranslateBlock(Block b) throws Exception {
  172. // System.out.println("Translate block:" + b.getName() + "::" + b.Instructions().size());
  173. LinkedList<Instruction> instructions = b.Instructions();
  174. Integer index = 0, limit = instructions.size(), nextIndex;
  175. for (Iterator<Instruction> it = instructions.iterator(); it.hasNext();) {
  176. currentIrInstruction = it.next();
  177. nextIndex = index + 1;
  178. next = (nextIndex < limit) ? instructions.get(nextIndex) : null;
  179. // System.out.println("Translate: " + inst.Get("global.position") + "::read["
  180. // + inst.Get("reg.dst.load")
  181. // + "|"
  182. // + inst.Get("reg.p1.load")
  183. // + "|"
  184. // + inst.Get("reg.p2.load")
  185. // + "] >> write["
  186. // + inst.Get("reg.dst.store")
  187. // + "|"
  188. // + inst.Get("reg.p1.store")
  189. // + "|"
  190. // + inst.Get("reg.p2.store")
  191. // + "]"
  192. // + inst.Get("type")
  193. // );
  194. //
  195. switch (currentIrInstruction.Get("type")) {
  196. case "alloc":
  197. break;
  198. case "label":
  199. if (!currentIrInstruction.Get("label").equals(getTarget().Block().getName())) {
  200. TranslateLabel(currentIrInstruction);
  201. }
  202. break;
  203. case "assign":
  204. TranslateAssign(currentIrInstruction);
  205. break;
  206. case "unary":
  207. TranslateUnary(currentIrInstruction);
  208. break;
  209. case "copy":
  210. TranslateCopy(currentIrInstruction);
  211. break;
  212. case "jump":
  213. TranslateJump(currentIrInstruction);
  214. break;
  215. case "call":
  216. TranslateCall(currentIrInstruction);
  217. break;
  218. case "return":
  219. TranslateReturn(currentIrInstruction);
  220. break;
  221. case "push_param":
  222. TranslatePushParam(currentIrInstruction);
  223. break;
  224. case "push_return":
  225. TranslatePushReturn(currentIrInstruction);
  226. break;
  227. case "pop_return":
  228. TranslatePopReturn(currentIrInstruction);
  229. break;
  230. case "pop_param":
  231. TranslatePopParam(currentIrInstruction);
  232. break;
  233. case "branch":
  234. TranslateBranch(currentIrInstruction);
  235. break;
  236. case "indexed_assign":
  237. TranslateIndexedAssignment(currentIrInstruction);
  238. break;
  239. case "pointer_assign":
  240. TranslatePointerAssignment(currentIrInstruction);
  241. break;
  242. case "store":
  243. TranslateStore(currentIrInstruction);
  244. break;
  245. case "load":
  246. TranslateLoad(currentIrInstruction);
  247. break;
  248. default:
  249. throw new Exception(String.format("TAC instruction type '%s' not defined", currentIrInstruction.Get("type")));
  250. }
  251. prev = currentIrInstruction;
  252. index++;
  253. }
  254. }
  255. protected Instruction Next() {
  256. return next;
  257. }
  258. protected Instruction Prev() {
  259. return prev;
  260. }
  261. }