/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package targets.mips; import API.Api; import API.Utils; import common.RegistroBase; import java.util.ArrayList; import java.util.HashMap; import templates.FunctionInterface; import templates.Functions; /** * * @author EUGENIO CARVALHO */ public class MipsTemplate implements templates.TemplateDescription { public HashMap Formats() throws Exception { String base = "{[HEX(global.position,G.addressLen,' ')]': '}{[INSTDEC()]}{[T(1)]}{[inst]' '}", end = "{[T(1)]}{'.'[tac.position]'.'}{'--'[comment]}"; return new HashMap() { { put("S", base + end); put("label", "' '{[HEX(global.reference.position,8,0)]}{[INSTDEC()]}{' <'[label]'>:'"); // Template para instrucoes do tipo J put("J", base + "{[rs]}{[LM(label,'hex')]}" + end); // Template para instrucoes do tipo R put("R0", base + "{[rd]','}{[rs]','}{[rt]}" + end); put("R1", base + "{[rs]','}{[rt]}" + end); put("R2", base + "{[rs]}" + end); put("R3", base + "{[rt]','}{[rs]}" + end); put("R4", base + "{[rd]','}{[rt]','}{[sa]} " + end); put("R5", base + "{[rd]}" + end); // Template para instrucoes do tipo I put("I0", base + "{[rt]','}{[rs]','}{[LM(label,'hex')]|[offset]|[rd]}" + end); //[rs:sp,rt:7,rd:sp] // SW,LW put("I1", base + "{[rt]','}{[OFFSET(offset,rs)]}" + end); // Templates avulsos put("PSEUDO", base); // Templates para instrucoes binarias put("bin.R", "{[codop]}{[RBIN(rs,5)]}{[RBIN(rt,5)]}{[RBIN(rd,5)]}{[BIN(sa,5)]}{[func]}"); put("bin.I", "{[codop]}{[RBIN(rs,5)]}{[RBIN(rt,5)]}{[BIN(offset,16)]}"); put("bin.J", "{[codop]}{[target]}"); put("bin.S", "{[txt]}"); } }; } public HashMap Functions() throws Exception { return new HashMap() { { put("OFFSET", (ctx, args) -> args.get(0) + "(" + args.get(1) + ")"); put("INSTHEX", (ctx, args) -> MipsTemplate.ConvertBin("hex", ctx, args)); put("INSTDEC", (ctx, args) -> MipsTemplate.ConvertBin("dec", ctx, args)); put("INSTBIN", (ctx, args) -> MipsTemplate.INSTBIN(ctx, args)); put("RBIN", (ctx, args) -> { String reg = args.get(0); if (reg.equals("")) { reg = "0"; } if (!Utils.IsNumber(reg)) { reg = Mips.Register(reg); } return Api.num2bin(reg, Integer.parseInt(args.get(1))); }); put("LM", (ctx, args) -> { if (args.get(0).equals("")) { return ""; } String label = args.get(0).trim(); if (label.equals("")) { return label; } // System.out.println("RUN LM: " + args + ctx); String prefix = "G."; String format = (args.size() > 1) ? args.get(1) : "dec", // Corresponde ao nome do label que marca o inicio do bloco base = ctx.Get(prefix + "label." + label).split("\\+")[0], // Corresponde ao endereco do label base (decimal) baseAddress = ctx.Get(prefix + base), // Corresponde a posicao do label destino (decimal) laddress = ctx.Get(prefix + label); // System.out.printf("TemplateListener:{%s\n %s\n %s\n %s\n}\n", base, baseAddress, label, laddress); int value = Integer.parseInt(laddress); int fromStart = value - Integer.parseInt(baseAddress); switch (ctx.Get("type")) { case "I": // (bne...) Salta para posicao em relacao ao pc atual // System.out.println("TemplateListenerLabel::" + base + "|" + laddress + "|" + baseAddress + "|\n" + ctx); // System.out.println("I Branch:{{\n" + base // + "\n:" + Integer.parseInt(ctx.Get(base)) // + "\n:" + label // + "\n:" + value // + "\n:" + FormatNum(value, format) // + "\n}}"); // System.out.println("Tranalate>>>>>>>>> I:[" + address + "]" + ctx); // address -= Integer.parseInt(ctx.Get("block.position")); break; case "J": // (j | jal) Salta para o endereco de destino // System.out.println(">>>>" + label + ":" + format + ":" + value + ":" + FormatNum(value, format)); // address = valueint; break; default: System.out.println(String.format("Label type '%s' not defined", ctx.Get("type"))); } // address = address * this.AddressGap; // value = value * this.AddressGap; // System.out.println("============LaBEL:" + label + ":" + format + ":" + value + ":" + base); // System.out.println("============LaBEL:" + value + ":" + address); return laddress.trim().equals("") ? "" : (Utils.FormatNum(value, format) + " <" + base + "+0x" + Utils.FormatNum(fromStart, format) + ">"); }); } }; } // Shared functions protected static String ConvertBin(String inst, RegistroBase ctx, ArrayList args) { try { Integer size; String bin = MipsTemplate.INSTBIN(ctx, args); if (Utils.Empty(bin)) { return ""; } Long bin2long = Long.parseLong(bin, 2); // System.out.println("CONVERTbin:" + bin + "\nbin2long:" + bin2long); switch (inst) { case "hex": size = 8; bin = Long.toString(bin2long, 16); break; case "dec": size = 10; bin = "" + bin2long; break; default: throw new Exception(String.format("Conversão para o tipo '%s' não definida.", inst)); } String result = Utils.Pad(bin, "0", "", size); ctx.Set("inst." + inst, result); return result; } catch (Exception e) { if (ctx.Get("inst").equals("bgtz")) { System.out.println("hex-Error:" + e.getMessage()); } System.out.println(e.getMessage()); e.printStackTrace(); return "error!"; } } protected static String INSTBIN(RegistroBase ctx, ArrayList args) throws Exception { String type = ctx.Get("type"); if (type.equals("label")) { return ""; } long shift; // switch (type) { case "S": // (j | jal) Salta para o endereco de destino // System.out.println("instbin:" + ctx); break; case "J": // (j | jal) Salta para o endereco de destino // System.out.println("JUMP:" + ctx.Get(ctx.Get("label")) + ":" // + (Long.parseLong(ctx.Get(ctx.Get("label")), 10) >> 2)); shift = (Long.parseLong(ctx.Get("G." + ctx.Get("label")), 10) >> 2); ctx.Set("target", Functions.BIN("" + shift, 26)); break; case "I": // (bne...) Salta para posicao em relacao ao pc atual + 4 // System.out.println("BIN iiiiii" + ctx); // shift = (Long.parseLong(ctx.Get(ctx.Get("label")), 10) >> 2); // ctx.Set("target", BIN("" + shift, 26)); // if (ctx.Get("offset").equals("") && !ctx.Get("label").equals("")) { // // int target = Integer.parseInt(ctx.Get(ctx.Get("label"))); // int position = Integer.parseInt(ctx.Get("global.position")) + 1; // //// System.out.println("INSTBIN:->" + FormatNum(target - position, "hex")); // ctx.Set("offset", (target - position) + ""); // // } // System.out.println("INSTBIN[" + type + ":" + bin + "]:" + ctx); break; case "R": // (bne...) Salta para posicao em relacao ao pc atual // System.out.println("INSTBIN[" + type + "]:" + ctx); break; default: } String bin = templates.Template.FormatRender("bin." + type).Render(ctx); ctx.Set("inst.bin", bin); // System.out.println("bin." + type + "::" + bin); return bin; } } // @Override // public String Render(RegistroBase ctx) { // // if (tpls.isEmpty()) { // tpls.put("bin.R", New("{[codop]}{[RBIN(rs,5)]}{[RBIN(rt,5)]}{[RBIN(rd,5)]}{[BIN(sa,5)]}{[func]}", ctx)); // tpls.put("bin.I", New("{[codop]}{[RBIN(rs,5)]}{[RBIN(rt,5)]}{[BIN(offset,16)]}", ctx)); // tpls.put("bin.J", New("{[codop]}{[target]}", ctx)); // tpls.put("bin.S", New("{[txt]}", ctx)); // } // // TemplateFunctions listener = new TemplateFunctions(ctx, ctx); //// listener.AddressGap = 4; // listener.templates = tpls; // // walker.walk(listener, tree); // // return listener.toString(); // } // @Override // public TPLInterface New(String tpl, RegistroBase ctx) { // return new Template(tpl, ctx); // }