123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305 |
- /*
- * 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 API;
- import common.Block;
- import common.Code;
- import common.DataLayout;
- import common.Instruction;
- import common.IvannosysTargetArch;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.LinkedList;
- import java.util.Map;
- import java.util.Set;
- import java.util.logging.Level;
- import java.util.logging.Logger;
- /**
- *
- * @author EUGENIO CARVALHO
- */
- public abstract class TargetGen implements IvannosysTargetArch {
- protected HashMap<String, ExportInterface> exportMethods = new HashMap<>();
- protected Code target;
- protected Code IR;
- protected Instruction prev = null, next = null;
- protected Instruction currentIrInstruction;
- protected Instruction currentTargetInstruction;
- public TargetGen(String id) {
- BaseGenInit(id);
- }
- /**
- * Like Sprintf
- *
- * @param format
- * @param args
- * @return
- */
- protected String F(String format, Object... args) {
- return String.format(format, args);
- }
- /**
- * Retorna o contexto do bloco atual
- *
- * @return
- */
- public DataLayout Context() {
- return Context("");
- }
- /**
- * Retorna o contexto do bloco atual <br>
- * Se var contem "G" retorna o contexto global
- *
- * @param var
- * @return
- */
- public DataLayout Context(String var) {
- if (var.contains("G")) {
- return IR.GlobalContext();
- }
- return IR.Block().Context();
- }
- public common.Offset Offset(String var) throws Exception {
- return Context(var).Offset(var);
- }
- public void BaseGenInit(String id) {
- target = new Code(id);
- }
- public Code getTarget() {
- return target;
- }
- public void setTarget(Code target) {
- this.target = target;
- }
- public Code getIR() {
- return IR;
- }
- public ExportInterface GetExportMethod(String id) throws Exception {
- id = id.trim();
- if (!exportMethods.containsKey(id)) {
- Set<String> set = exportMethods.keySet();
- String[] valids = new String[set.size()];
- set.toArray(valids);
- throw new Exception(String.format(
- "O método de exportação '%s' não foi definido no alvo '%s'. Métodos disponiveis: %s",
- id,
- target.Name(),
- Utils.Join(valids, ", ")));
- }
- return exportMethods.get(id);
- }
- public HashMap<String, ExportInterface> GetExportMethods() {
- return exportMethods;
- }
- public IvannosysTargetArch Init(Code tac) throws Exception {
- // Verifica se o codigo gerado vai ser util caso contrario aborta o processo;
- ArrayList<String> methods = BuildParams.Get("export");
- if (methods.isEmpty()) {
- throw new Exception(String.format("Nenhum método de exportação definido para o alvo '%s'", target.Name()));
- }
- IR = tac;
- // target.GlobalContext().copy(tac.GlobalContext());
- target.Parent = IR;
- return this;
- }
- protected Instruction Add(Instruction inst) throws Exception {
- if (currentIrInstruction != null) {
- inst.Set("tac.position", currentIrInstruction.Get("block.position"));
- }
- target.Block().Add(inst);
- currentTargetInstruction = inst;
- return inst;
- }
- public TargetGen AddExportOption(String id, ExportInterface exp) {
- exportMethods.put(id.trim(), exp);
- return this;
- }
- @Override
- public IvannosysTargetArch Format() {
- try {
- String code = target.Dump();
- System.out.println("Target[" + target.Name() + "]:\n" + code);
- } catch (Exception ex) {
- Logger.getLogger(TargetGen.class.getName()).log(Level.SEVERE, null, ex);
- }
- return this;
- }
- @Override
- public IvannosysTargetArch Compile() {
- try {
- // Traduz o codigo intermediario para o alvo
- Translate();
- } catch (Exception ex) {
- Logger.getLogger(TargetGen.class.getName()).log(Level.SEVERE, null, ex);
- }
- return this;
- }
- protected void Translate() throws Exception {
- String targetID = target.Name(), id;
- target.Parent = IR;
- Block block;
- Middleware.Trigger(target, targetID, "before.translate");
- for (Map.Entry<String, Block> b : IR.Blocks().entrySet()) {
- id = b.getKey();
- block = b.getValue();
- if (block.Type() == Block.TYPE_CTRL) {
- continue;
- }
- IR.Use(id);
- target.OpenBlock(id);
- Middleware.Trigger(target, targetID, "before.translate.block");
- Prolog(id);
- TranslateBlock(block);
- Epilog(id);
- target.CloseBlock();
- Middleware.Trigger(target, targetID, "after.translate.block");
- }
- target.UpdatePositions();
- Middleware.Trigger(target, targetID, "after.translate");
- }
- @Override
- public IvannosysTargetArch Export() throws Exception {
- ArrayList<String> methods = BuildParams.Get("export");
- for (String method : methods) {
- GetExportMethod(method).Exec(IR, target);
- }
- return this;
- }
- protected void TranslateBlock(Block b) throws Exception {
- // System.out.println("Translate block:" + b.getName() + "::" + b.Instructions().size());
- LinkedList<Instruction> instructions = b.Instructions();
- Integer index = 0, limit = instructions.size(), nextIndex;
- for (Iterator<Instruction> it = instructions.iterator(); it.hasNext();) {
- currentIrInstruction = it.next();
- nextIndex = index + 1;
- next = (nextIndex < limit) ? instructions.get(nextIndex) : null;
- // System.out.println("Translate: " + inst.Get("global.position") + "::read["
- // + inst.Get("reg.dst.load")
- // + "|"
- // + inst.Get("reg.p1.load")
- // + "|"
- // + inst.Get("reg.p2.load")
- // + "] >> write["
- // + inst.Get("reg.dst.store")
- // + "|"
- // + inst.Get("reg.p1.store")
- // + "|"
- // + inst.Get("reg.p2.store")
- // + "]"
- // + inst.Get("type")
- // );
- //
- switch (currentIrInstruction.Get("type")) {
- case "alloc":
- break;
- case "label":
- if (!currentIrInstruction.Get("label").equals(getTarget().Block().getName())) {
- TranslateLabel(currentIrInstruction);
- }
- break;
- case "assign":
- TranslateAssign(currentIrInstruction);
- break;
- case "unary":
- TranslateUnary(currentIrInstruction);
- break;
- case "copy":
- TranslateCopy(currentIrInstruction);
- break;
- case "jump":
- TranslateJump(currentIrInstruction);
- break;
- case "call":
- TranslateCall(currentIrInstruction);
- break;
- case "return":
- TranslateReturn(currentIrInstruction);
- break;
- case "push_param":
- TranslatePushParam(currentIrInstruction);
- break;
- case "push_return":
- TranslatePushReturn(currentIrInstruction);
- break;
- case "pop_return":
- TranslatePopReturn(currentIrInstruction);
- break;
- case "pop_param":
- TranslatePopParam(currentIrInstruction);
- break;
- case "branch":
- TranslateBranch(currentIrInstruction);
- break;
- case "indexed_assign":
- TranslateIndexedAssignment(currentIrInstruction);
- break;
- case "pointer_assign":
- TranslatePointerAssignment(currentIrInstruction);
- break;
- case "store":
- TranslateStore(currentIrInstruction);
- break;
- case "load":
- TranslateLoad(currentIrInstruction);
- break;
- default:
- throw new Exception(String.format("TAC instruction type '%s' not defined", currentIrInstruction.Get("type")));
- }
- prev = currentIrInstruction;
- index++;
- }
- }
- protected Instruction Next() {
- return next;
- }
- protected Instruction Prev() {
- return prev;
- }
- }
|