/* * 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 Export; import API.BuildParams; import API.ExportInterface; import API.Utils; import common.Block; import common.Code; import common.Instruction; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import targets.mips.Descriprion; import targets.mips.MipsTemplateDescription; import targets.mips.MipsUpdateAddressMiddleware; /** * MipS tranSlation * * @author EUGENIO CARVALHO */ public class MultCoreJun implements ExportInterface { private Code target; @Override public void Exec(Code IR, Code Target) throws Exception { // return; try { this.target = Target; Code newCode; System.out.println("Export MIPSJUN"); Long stackBaseAddress = 0L, updateBaseAddress = 0L, size; String id, initFunction, blockName, format, cacheBlockSize = BuildParams.GetFirst("cacheBlockSize"), base = BuildParams.GetFirst("outputDirectory"); String[] parts; Block func; JSONObject profile; MipsUpdateAddressMiddleware uap = new MipsUpdateAddressMiddleware(); ArrayList p = BuildParams.Get("profile"); if (!p.isEmpty()) { JSONArray pobject = (JSONArray) new JSONParser().parse(p.get(0)); for (Object pro : pobject) { profile = (JSONObject) pro; id = (String) profile.get("id"); initFunction = (String) profile.get("initFunction"); parts = initFunction.replace(")", "").split("\\("); blockName = parts[0]; // Busca o bloco inicial referenciado pelo usuario func = Target.Blocks().get(blockName); if (profile.containsKey("stackBaseAddress")) { stackBaseAddress = (Long) profile.get("stackBaseAddress"); } else { // System.out.println("stackBaseAddress:(" + stackBaseAddress + ")(" + MaxStackSize(func) + ")"); size = MaxStackSize(func); updateBaseAddress = stackBaseAddress - size - fixCacheBlockSize(size, Long.parseLong(cacheBlockSize)); } // Cria um novo codigo para armazenas as instruções do core newCode = NewCode(id); // Copia o bloco da funcao e todos os blocos que gerem dependencia CopyBlock(newCode, func, parts, stackBaseAddress, true); // Atualiza os enderecos de salto do codigo uap.Exec(newCode, null); format = (String) profile.get("filename"); if (format == null) { throw new Exception("Arquivo de saida para o core `" + id + "` não definido!"); } SaveMips(newCode, base + "\\" + String.format(format, "mips")); SaveDec(newCode, base + "\\" + String.format(format, "dec")); stackBaseAddress = updateBaseAddress; // ExecuteCode(newCode); // break; // System.out.println("value::" + code); } // System.out.println("params:" + getIR().ast.getCompileParams().GetLists()); // System.out.println("params:" + p); } // } catch (ParseException ex) { // Logger.getLogger(MultCoreJun.class.getName()).log(Level.SEVERE, null, ex); } catch (Exception ex) { Logger.getLogger(MultCoreJun.class.getName()).log(Level.SEVERE, null, ex); } } protected Long fixCacheBlockSize(Long size, Long sizeOfBlock) { Long t = sizeOfBlock; while (true) { if (sizeOfBlock > size) { break; } sizeOfBlock += t; } return sizeOfBlock - size; } protected void SaveMips(Code newCode, String filename) throws Exception { Utils.WriteFile(filename, newCode.Dump()); } protected void SaveDec(Code newCode, String filename) throws Exception { String code = "", tmp; for (Map.Entry x : newCode.stmts.entrySet()) { for (Instruction instr : x.getValue().Instructions()) { tmp = instr.Get("inst.dec"); if (tmp.equals("")) { continue; } code = code.concat(Long.parseLong(tmp) + "\n"); } } Utils.WriteFile(filename, code); } protected Code CopyBlock(Code newCode, Block func, String[] funcCall, Long stackBaseAddress, boolean main) throws Exception { // Instruction Ninst; int index = 1; String blockName = funcCall[0]; newCode.OpenBlock(blockName); Block block = newCode.Block(); // Carrega os argumentos da chamada if (funcCall.length > 1) { // System.out.println("Tinha parametro:" + funcCall[1]); String[] args = funcCall[1].split(","); int i = 0; for (String arg : args) { // Ninst = new Instruction(); // Variaveis.List(); // System.out.println("Variaveis.Get(arg):" + Variaveis.Get("main." + args)); block.Add(Descriprion.Instruction("addiu") .Set("rs", "zero") .Set("rt", "a" + (i++)) .Set("offset", arg)); } index += args.length; } for (Instruction inst : func.Instructions()) { block.Add(inst.copy()); } if (main) { LinkedList instructions = newCode.Block().Instructions(); // Atualiza o offset da pilha Instruction first = instructions.get(index); // System.out.println("CopyBlock[" + stackBaseAddress + "||" + first.getLong("offset") + "]"); first.Set("offset", first.getLong("offset") + stackBaseAddress); // System.out.println("instructions.Get(0);" + first); // Atualiza a ultima instrucao de um retorno para ra -> stop block.Remove(instructions.get(instructions.size() - 1)); block.Add(Descriprion.Instruction("stop") .Set("comment", "end of programa")); } newCode.CloseBlock(); // Adiciona as funcoes que geram dependencias HashMap tb = target.Blocks(); ArrayList deps = tb.get(blockName).GetDependences(); if (!deps.isEmpty()) { for (String dep : deps) { CopyBlock(newCode, tb.get(dep), new String[]{dep}, 0l, false); } } return newCode; } protected Code NewCode(String id) throws Exception { return new Code(id).Template(new MipsTemplateDescription()); } protected Long MaxStackSize(Block blk) { HashMap tb = target.Blocks(); // System.out.println("data:" + blk.Context()); Long childSize = 0L, tmpChildSize; ArrayList deps = blk.GetDependences(); if (!deps.isEmpty()) { for (String dep : deps) { tmpChildSize = MaxStackSize(tb.get(dep)); if (tmpChildSize > childSize) { childSize = tmpChildSize; } } } // System.out.println("MaxStackSize:" + size + "|" + childSize); return blk.Context().Size() + childSize; } }