TListenerMips.java 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  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 target.mips;
  7. import API.Api;
  8. import API.Utils;
  9. import java.util.ArrayList;
  10. import java.util.HashMap;
  11. import template.TPLInterface;
  12. import template.TemplateCtx;
  13. import template.TemplateParser;
  14. /**
  15. *
  16. * @author EUGENIO CARVALHO
  17. */
  18. class TListenerMips extends template.TListener {
  19. public HashMap<String, TPLInterface> templates;
  20. // public int AddressGap = 1;
  21. public TListenerMips(TemplateCtx ctx, TemplateCtx gctx) {
  22. super(ctx, gctx);
  23. }
  24. @Override
  25. public void exitCall(TemplateParser.CallContext ctx) {
  26. ArrayList<String> arguments = ExecCall(ctx);
  27. if (Utils.Empty(this.returnCall)) {
  28. switch (ctx.ID().getText()) {
  29. case "OFFSET":
  30. this.returnCall = OFFSET(arguments);
  31. break;
  32. case "INSTHEX":
  33. this.returnCall = INSTHEX(arguments);
  34. break;
  35. case "INSTDEC":
  36. this.returnCall = INSTDEC(arguments);
  37. break;
  38. case "INSTBIN":
  39. this.returnCall = INSTBIN(arguments);
  40. break;
  41. case "BIN":
  42. this.returnCall = BIN(arguments);
  43. case "RBIN":
  44. this.returnCall = RBIN(arguments);
  45. break;
  46. }
  47. }
  48. }
  49. public String OFFSET(ArrayList<String> args) {
  50. return args.get(0) + "(" + args.get(1) + ")";
  51. }
  52. @Override
  53. protected String L(ArrayList<String> arguments) {
  54. String label = arguments.get(0).trim();
  55. if (label.equals("")) {
  56. return label;
  57. }
  58. String format = (arguments.size() > 1) ? arguments.get(1) : "dec",
  59. // Corresponde ao nome do label que marca o inicio do bloco
  60. base = gctx.G("label." + label).split("\\+")[0],
  61. // Corresponde ao endereco do label base (decimal)
  62. baseAddress = gctx.G(base),
  63. // Corresponde a posicao do label destino (decimal)
  64. laddress = gctx.G(label);
  65. System.out.printf("TemplateListener:{%s\n %s\n %s\n %s\n}\n", base, baseAddress, label, laddress);
  66. int value = Integer.parseInt(laddress);
  67. int fromStart = value - Integer.parseInt(baseAddress);
  68. switch (ctx.G("type")) {
  69. case "I": // (bne...) Salta para posicao em relacao ao pc atual
  70. // System.out.println("TemplateListenerLabel::" + base + "|" + laddress + "|" + baseAddress + "|\n" + ctx);
  71. // System.out.println("I Branch:{{\n" + base
  72. // + "\n:" + Integer.parseInt(gctx.G(base))
  73. // + "\n:" + label
  74. // + "\n:" + value
  75. // + "\n:" + FormatNum(value, format)
  76. // + "\n}}");
  77. // System.out.println("Tranalate>>>>>>>>> I:[" + address + "]" + ctx);
  78. // address -= Integer.parseInt(ctx.G("block.position"));
  79. break;
  80. case "J": // (j | jal) Salta para o endereco de destino
  81. // System.out.println(">>>>" + label + ":" + format + ":" + value + ":" + FormatNum(value, format));
  82. // address = valueint;
  83. break;
  84. default:
  85. System.out.println(String.format("Label type '%s' not defined", ctx.G("type")));
  86. }
  87. // address = address * this.AddressGap;
  88. // value = value * this.AddressGap;
  89. // System.out.println("============LaBEL:" + label + ":" + format + ":" + value + ":" + base);
  90. // System.out.println("============LaBEL:" + value + ":" + address);
  91. return laddress.trim().equals("")
  92. ? ""
  93. : (FormatNum(value, format) + " <" + base + "+0x" + FormatNum(fromStart, format) + ">");
  94. }
  95. // Converte um binario para hex
  96. protected String INSTHEX(ArrayList<String> arguments) {
  97. try {
  98. String bin = INSTBIN(arguments);
  99. if (Utils.Empty(bin)) {
  100. return "";
  101. }
  102. String hex = PAD(Long.toString(Long.parseLong(bin, 2), 16), "0", 8);
  103. ctx.Set("inst.hex", hex);
  104. return hex;
  105. } catch (Exception e) {
  106. if (ctx.G("inst").equals("bgtz")) {
  107. System.out.println("hex-Error:" + e.getMessage());
  108. e.printStackTrace();
  109. }
  110. return "error!";
  111. }
  112. }
  113. // 100111101111011111111111111000 == addiu sp,sp,-8
  114. protected String INSTDEC(ArrayList<String> arguments) {
  115. try {
  116. String bin = INSTBIN(arguments);
  117. if (Utils.Empty(bin)) {
  118. return "";
  119. }
  120. // System.out.println("Convertendo bin :" + arguments + ":" + bin + ":dec:" + Long.parseLong(bin, 2));
  121. String dec = PAD("" + Long.parseLong(bin, 2), "0", 10);
  122. ctx.Set("inst.dec", dec);
  123. return dec;
  124. } catch (Exception e) {
  125. if (ctx.G("inst").equals("bgtz")) {
  126. System.out.println("hex-Error:" + e.getMessage());
  127. e.printStackTrace();
  128. }
  129. return "error!";
  130. }
  131. }
  132. protected String INSTBIN(ArrayList<String> arguments) {
  133. String type = ctx.G("type");
  134. if (type.equals("label")) {
  135. return "";
  136. }
  137. long shift;
  138. //
  139. switch (type) {
  140. case "S": // (j | jal) Salta para o endereco de destino
  141. // System.out.println("instbin:" + ctx);
  142. break;
  143. case "J": // (j | jal) Salta para o endereco de destino
  144. // System.out.println("JUMP:" + gctx.G(ctx.G("label")) + ":"
  145. // + (Long.parseLong(gctx.G(ctx.G("label")), 10) >> 2));
  146. shift = (Long.parseLong(gctx.G(ctx.G("label")), 10) >> 2);
  147. ctx.Set("target", BIN("" + shift, 26));
  148. break;
  149. case "I": // (bne...) Salta para posicao em relacao ao pc atual + 4
  150. // System.out.println("BIN iiiiii" + ctx);
  151. // shift = (Long.parseLong(gctx.G(ctx.G("label")), 10) >> 2);
  152. // ctx.Set("target", BIN("" + shift, 26));
  153. // if (ctx.G("offset").equals("") && !ctx.G("label").equals("")) {
  154. //
  155. // int target = Integer.parseInt(gctx.G(ctx.G("label")));
  156. // int position = Integer.parseInt(ctx.G("global.position")) + 1;
  157. //
  158. //// System.out.println("INSTBIN:->" + FormatNum(target - position, "hex"));
  159. // ctx.Set("offset", (target - position) + "");
  160. //
  161. // }
  162. // System.out.println("INSTBIN[" + type + ":" + bin + "]:" + ctx);
  163. break;
  164. case "R": // (bne...) Salta para posicao em relacao ao pc atual
  165. // System.out.println("INSTBIN[" + type + "]:" + ctx);
  166. break;
  167. default:
  168. }
  169. String bin = templates.get("bin." + type).Render(ctx);
  170. ctx.Set("inst.bin", bin);
  171. // System.out.println("bin." + type + "::" + bin);
  172. return bin;
  173. }
  174. protected String BIN(ArrayList<String> arguments) {
  175. // System.out.println("BIN(" + arguments + ")");
  176. return BIN(arguments.get(0), arguments.get(1));
  177. }
  178. protected String BIN(String val, String pad) {
  179. return BIN(val, Integer.parseInt(pad));
  180. }
  181. protected String BIN(String val, int pad) {
  182. return Api.num2bin(val, pad);
  183. }
  184. protected String RBIN(ArrayList<String> arguments) {
  185. // System.out.println("RBIN(" + arguments + ")");
  186. String reg = arguments.get(0);
  187. if (reg.equals("")) {
  188. reg = "0";
  189. }
  190. if (!Utils.isNumber(reg)) {
  191. reg = Mips.Register(reg);
  192. }
  193. return Api.num2bin(reg, Integer.parseInt(arguments.get(1)));
  194. }
  195. }