diff --git a/src/nasm/C3a2nasm.java b/src/nasm/C3a2nasm.java index 3475c263e0ed28dadc53ba44d68bec1baa85e2df..c03757895d2ed834a3355b6f50c159c409ffea9b 100644 --- a/src/nasm/C3a2nasm.java +++ b/src/nasm/C3a2nasm.java @@ -10,204 +10,297 @@ public class C3a2nasm implements C3aVisitor <NasmOperand> { private TsItemFct currentFct; private NasmRegister esp; private NasmRegister ebp; - private NasmLabel label; - - public C3a2nasm(C3a c3a, Ts tableGlobale){ - this.c3a = c3a; - nasm = new Nasm(tableGlobale); - nasm.setTempCounter(c3a.getTempCounter()); - this.tableGlobale = tableGlobale; - this.currentFct = null; - esp = new NasmRegister(-1); - esp.colorRegister(Nasm.REG_ESP); + public C3a2nasm(C3a c3a, Ts tableGlobale) { + this.c3a = c3a; + nasm = new Nasm(tableGlobale); + nasm.setTempCounter(c3a.getTempCounter()); - ebp = new NasmRegister(-1); - ebp.colorRegister(Nasm.REG_EBP); + this.tableGlobale = tableGlobale; + this.currentFct = null; + esp = new NasmRegister(-1); + esp.colorRegister(Nasm.REG_ESP); + + ebp = new NasmRegister(-1); + ebp.colorRegister(Nasm.REG_EBP); + + NasmOperand res; + for (C3aInst c3aInst : c3a.listeInst) { + // System.out.println("<" + c3aInst.getClass().getSimpleName() + ">"); + res = c3aInst.accept(this); + } } - public Nasm getNasm(){return nasm;} + public Nasm getNasm() { + return nasm; + } + /*-------------------------------------------------------------------------------------------------------------- + transforme une opérande trois adresses en une opérande asm selon les règles suivantes : - public NasmOperand visit(C3a c3a){ - return null; + C3aConstant -> NasmConstant + C3aTemp -> NasmRegister + C3aLabel -> NasmLabel + C3aFunction -> NasmLabel + C3aVar -> NasmAddress + --------------------------------------------------------------------------------------------------------------*/ + + + @Override + public NasmOperand visit(C3aInstCall inst) { + NasmOperand label = (inst.label != null) ? inst.label.accept(this) : null; + nasm.ajouteInst(new NasmSub(label, esp, new NasmConstant(4), "allocation mémoire pour la valeur de retour")); + nasm.ajouteInst(new NasmCall(null, new NasmLabel(inst.op1.val.identif), "")); + nasm.ajouteInst(new NasmPop(null, inst.result.accept(this), "récupération de la valeur de retour")); + if (inst.op1.val.nbArgs > 0) + nasm.ajouteInst(new NasmAdd(null, esp, new NasmConstant(inst.op1.val.nbArgs * 4), "désallocation des arguments")); + return inst.result.accept(this); } - public NasmOperand visit(C3aInstAdd inst){ - NasmOperand label = (inst.label != null) ? - inst.label.accept(this) - : null; - nasm.ajouteInst(new NasmMov(label, - inst.result.accept(this), - inst.op1.accept(this), "")); - nasm.ajouteInst(new NasmAdd(null, - inst.result.accept(this), - inst.op2.accept(this), "")); + + @Override + public NasmOperand visit(C3aInstFBegin inst) { + currentFct = inst.val; + nasm.ajouteInst(new NasmPush(new NasmLabel(currentFct.identif), ebp, "sauvegarde la valeur de ebp")); + nasm.ajouteInst(new NasmMov(null, ebp, esp, "nouvelle valeur de ebp")); + NasmRegister regeax = nasm.newRegister(); + NasmRegister regebx = nasm.newRegister(); + NasmRegister regecx = nasm.newRegister(); + NasmRegister regedx = nasm.newRegister(); + regeax.colorRegister(Nasm.REG_EAX); + regebx.colorRegister(Nasm.REG_EBX); + regecx.colorRegister(Nasm.REG_ECX); + regedx.colorRegister(Nasm.REG_EDX); + nasm.ajouteInst(new NasmPush(null, regeax, "sauvegarde de eax")); + nasm.ajouteInst(new NasmPush(null, regebx, "sauvegarde de ebx")); + nasm.ajouteInst(new NasmPush(null, regecx, "sauvegarde de ecx")); + nasm.ajouteInst(new NasmPush(null, regedx, "sauvegarde de edx")); + nasm.ajouteInst(new NasmSub(null, esp, new NasmConstant(currentFct.table.getAdrVarCourante()), "allocation des variables locales")); return null; } - public NasmOperand visit(C3aInstCall inst){ - NasmOperand label = (inst.label != null) ? inst.label.accept(this):null; - NasmOperand addr = inst.result.accept(this); - nasm.ajouteInst(new NasmCall(label,addr,"")); + + @Override + public NasmOperand visit(C3aInst inst) { return null; } - private NasmOperand getLabelFromC3aInst(C3aInst inst) { - return new NasmLabel(inst.label.toString()); - } - public NasmOperand visit(C3aInstFBegin inst){ + + + @Override + public NasmOperand visit(C3aInstMult inst) { NasmOperand label = (inst.label != null) ? inst.label.accept(this) : null; - nasm.ajouteInst(new NasmInst() { - @Override - void addLabel(String formatInst, NasmOperand label) { - super.addLabel(formatInst, label); - } - }); + NasmOperand oper1 = inst.op1.accept(this); + NasmOperand oper2 = inst.op2.accept(this); + NasmOperand dest = inst.result.accept(this); + nasm.ajouteInst(new NasmMov(label, dest, oper1, "")); + nasm.ajouteInst(new NasmMul(null, dest, oper2, "")); return null; } - public NasmOperand visit(C3aInst inst){ + + @Override + public NasmOperand visit(C3aInstRead inst) { NasmOperand label = (inst.label != null) ? inst.label.accept(this) : null; - NasmOperand addr = inst.label.accept(this); - NasmOperand destination = inst.label.accept(this); - NasmOperand source = inst.label.accept(this); - nasm.ajouteInst(new NasmInst() { - void addLabel(String formatInst, NasmOperand label) { - super.addLabel(formatInst, label); - } - }); + NasmRegister regeax = nasm.newRegister(); + regeax.colorRegister(Nasm.REG_EAX); + nasm.ajouteInst(new NasmMov(label, regeax, new NasmLabel("sinput"), "")); + nasm.ajouteInst(new NasmCall(null, new NasmLabel("readline"), "")); + nasm.ajouteInst(new NasmCall(null, new NasmLabel("atoi"), "")); + nasm.ajouteInst(new NasmMov(null, inst.result.accept(this), regeax, "")); return null; } - public NasmOperand visit(C3aInstJumpIfLess inst){ - NasmOperand label = (inst.label != null) ? inst.label.accept(this): null; + + @Override + public NasmOperand visit(C3aInstSub inst) { + NasmOperand label = (inst.label != null) ? inst.label.accept(this) : null; NasmOperand oper1 = inst.op1.accept(this); NasmOperand oper2 = inst.op2.accept(this); - NasmOperand result = inst.result.accept(this); - nasm.ajouteInst(new NasmCmp(label,oper1,oper2,"")); - nasm.ajouteInst(new NasmJle(null, result, "")); + NasmOperand dest = inst.result.accept(this); + nasm.ajouteInst(new NasmMov(label, dest, oper1, "")); + nasm.ajouteInst(new NasmSub(null, dest, oper2, "")); return null; } - public NasmOperand visit(C3aInstMult inst){ + + @Override + public NasmOperand visit(C3aInstDiv inst) { NasmOperand label = (inst.label != null) ? inst.label.accept(this) : null; - nasm.ajouteInst(new NasmMov(label, inst.result.accept(this), inst.op1.accept(this),"")); - nasm.ajouteInst(new NasmMul(null, inst.result.accept(this), inst.op2.accept(this),"")); - return null; + NasmRegister regeax = nasm.newRegister(); + NasmRegister regedx = nasm.newRegister(); + regeax.colorRegister(Nasm.REG_EAX); + regedx.colorRegister(Nasm.REG_EDX); + nasm.ajouteInst(new NasmMov(label, regedx, new NasmConstant(0), "mise à 0 des bits de poids fort du dividende")); + nasm.ajouteInst(new NasmMov(null, regeax, inst.op1.accept(this), "affectation des bits de poids faible du dividende")); + nasm.ajouteInst(new NasmMov(null, inst.result.accept(this), inst.op2.accept(this), "")); + nasm.ajouteInst(new NasmDiv(null, inst.result.accept(this), "")); + nasm.ajouteInst(new NasmMov(null, regedx, regedx, "rend explicite l'utilisation de edx pour ne pas que sa valeur soit modifiée")); + nasm.ajouteInst(new NasmMov(null, inst.result.accept(this), regeax, "")); + return regeax; } - public NasmOperand visit(C3aInstRead inst){ - nasm.ajouteInst(new NasmMov (getLabelFromC3aInst(inst), - nasm.newRegister(), - new NasmLabel("sinput"), "")); - nasm.ajouteInst(new NasmCall(null, - new NasmLabel("readline"), "")); - nasm.ajouteInst(new NasmCall(null, - new NasmLabel("atoi"), "")); - nasm.ajouteInst(new NasmMov (null, - inst.result.accept(this), - nasm.newRegister() , "")); + @Override + public NasmOperand visit(C3a c3a) { return null; } - - public NasmOperand visit(C3aInstSub inst){ + @Override + public NasmOperand visit(C3aInstAdd inst) { NasmOperand label = (inst.label != null) ? inst.label.accept(this) : null; - nasm.ajouteInst(new NasmMov(label, inst.result.accept(this), inst.op1.accept(this),"")); - nasm.ajouteInst(new NasmSub(null, inst.result.accept(this), inst.op2.accept(this),"")); - return null; - } - public NasmOperand visit(C3aInstAffect inst) { - NasmOperand label = (inst.label != null) ? inst.label.accept(this): null; NasmOperand oper1 = inst.op1.accept(this); - NasmOperand result = inst.result.accept(this); - nasm.ajouteInst(new NasmMov(label, inst.result.accept(this), inst.op1.accept(this),"")); - nasm.ajouteInst(new NasmInst() { - void addLabel(String formatInst, NasmOperand label) { - super.addLabel(formatInst, label); - } - }); + NasmOperand oper2 = inst.op2.accept(this); + NasmOperand dest = inst.result.accept(this); + nasm.ajouteInst(new NasmMov(label, dest, oper1, "")); + nasm.ajouteInst(new NasmAdd(null, dest, oper2, "")); return null; } - // à revoir - public NasmOperand visit(C3aInstDiv inst){ + @Override + public NasmOperand visit(C3aInstAffect inst) { NasmOperand label = (inst.label != null) ? inst.label.accept(this) : null; - nasm.ajouteInst(new NasmMov(label, inst.result.accept(this), inst.op1.accept(this),"")); - nasm.ajouteInst(new NasmDiv(null, inst.result.accept(this), inst.op2.accept(this),"")); + NasmOperand op1 = inst.op1.accept(this); + NasmOperand op2 = inst.result.accept(this); + nasm.ajouteInst(new NasmMov(label, op2, op1, "#Affectation")); return null; } - //à revoir - public NasmOperand visit(C3aInstFEnd inst){ + + + @Override + public NasmOperand visit(C3aInstFEnd inst) { NasmOperand label = (inst.label != null) ? inst.label.accept(this) : null; - nasm.ajouteInst(new NasmInst() { - void addLabel(String formatInst, NasmOperand label) { - super.addLabel(formatInst, label); - } - }); + nasm.ajouteInst(new NasmAdd(label, esp, new NasmConstant(currentFct.table.getAdrVarCourante()), "désallocation des variables locales")); + NasmRegister regeax = nasm.newRegister(); + NasmRegister regebx = nasm.newRegister(); + NasmRegister regecx = nasm.newRegister(); + NasmRegister regedx = nasm.newRegister(); + regeax.colorRegister(Nasm.REG_EAX); + regebx.colorRegister(Nasm.REG_EBX); + regecx.colorRegister(Nasm.REG_ECX); + regedx.colorRegister(Nasm.REG_EDX); + nasm.ajouteInst(new NasmPop(null, regedx, "#restaure edx")); + nasm.ajouteInst(new NasmPop(null, regecx, "#restaure ecx")); + nasm.ajouteInst(new NasmPop(null, regebx, "#restaure ebx")); + nasm.ajouteInst(new NasmPop(null, regeax, "#restaure eax")); + nasm.ajouteInst(new NasmPop(null, ebp, "#restaure la valeur de ebp")); + nasm.ajouteInst(new NasmRet(null, "")); return null; } - public NasmOperand visit(C3aInstJumpIfEqual inst){ - NasmOperand label = (inst.label != null) ? inst.label.accept(this): null; - NasmOperand oper1 = inst.op1.accept(this); - NasmOperand oper2 = inst.op2.accept(this); - NasmOperand result = inst.result.accept(this); - nasm.ajouteInst(new NasmCmp(label,oper1,oper2,"")); - nasm.ajouteInst(new NasmJe(null, result, "")); - return null; - } - public NasmOperand visit(C3aInstJumpIfNotEqual inst){ - NasmOperand label = (inst.label != null) ? inst.label.accept(this): null; - NasmOperand oper1 = inst.op1.accept(this); - NasmOperand oper2 = inst.op2.accept(this); - NasmOperand result = inst.result.accept(this); - nasm.ajouteInst(new NasmCmp(label,oper1,oper2,"")); - nasm.ajouteInst(new NasmJne(null, result, "")); + + @Override + public NasmOperand visit(C3aInstJumpIfLess inst) { + NasmOperand label = (inst.label != null) ? inst.label.accept(this) : null; + NasmOperand op = nasm.newRegister(); + nasm.ajouteInst(new NasmMov(label, op, inst.op1.accept(this), "")); + nasm.ajouteInst(new NasmCmp(null, op, inst.op2.accept(this), "")); + nasm.ajouteInst(new NasmJl(null, inst.result.accept(this), "")); return null; } - public NasmOperand visit(C3aInstJump inst){ - NasmOperand label = (inst.label != null) ? inst.label.accept(this):null; - NasmOperand addr = inst.result.accept(this); - nasm.ajouteInst(new NasmJmp(label,addr,"")); + + @Override + public NasmOperand visit(C3aInstJumpIfEqual inst) { + NasmOperand label = (inst.label != null) ? inst.label.accept(this) : null; + NasmOperand op = nasm.newRegister(); + nasm.ajouteInst(new NasmMov(label, op, inst.op1.accept(this), "")); + nasm.ajouteInst(new NasmCmp(null, op, inst.op2.accept(this), "")); + nasm.ajouteInst(new NasmJe(null, inst.result.accept(this), "")); return null; } - public NasmOperand visit(C3aInstParam inst){ - NasmOperand label = (inst.label != null) ? inst.label.accept(this): null; - NasmOperand addr = inst.label.accept(this); - NasmOperand destination = inst.label.accept(this); - NasmOperand source = inst.label.accept(this); - nasm.ajouteInst(new NasmMov(label, addr, destination, source, "")); + + @Override + public NasmOperand visit(C3aInstJumpIfNotEqual inst) { return null; } - public NasmOperand visit(C3aInstReturn inst){ - NasmOperand label = (inst.label != null) ? inst.label.accept(this): null; - nasm.ajouteInst(new NasmRet(label, "")); + + @Override + public NasmOperand visit(C3aInstJump inst) { + NasmOperand label = (inst.label != null) ? inst.label.accept(this) : null; + nasm.ajouteInst(new NasmJmp(label, inst.result.accept(this), "")); return null; } - public NasmOperand visit(C3aInstWrite inst){ - nasm.ajouteInst(new NasmMov (getLabelFromC3aInst(inst))); - nasm.ajouteInst(new NasmCall(null, new NasmLabel("iprintLF"), "")); + + @Override + public NasmOperand visit(C3aInstParam inst) { + NasmOperand label = (inst.label != null) ? inst.label.accept(this) : null; + nasm.ajouteInst(new NasmPush(label, inst.op1.accept(this), "#Param")); return null; } - public NasmOperand visit(C3aInstStop inst){ + + @Override + public NasmOperand visit(C3aInstReturn inst) { + NasmOperand label = (inst.label != null) ? inst.label.accept(this) : null; + NasmOperand op = inst.op1.accept(this); + nasm.ajouteInst(new NasmMov(label, new NasmAddress(ebp, NasmSize.DWORD), op, "retour valeur")); return null; } - public NasmOperand visit(C3aConstant oper){ + @Override + public NasmOperand visit(C3aInstWrite inst) { + NasmOperand label = (inst.label != null) ? inst.label.accept(this) : null; + NasmOperand op = inst.op1.accept(this); + NasmRegister regeax = nasm.newRegister(); + regeax.colorRegister(Nasm.REG_EAX); + nasm.ajouteInst(new NasmMov(label, regeax, op, "#Write 1")); + nasm.ajouteInst(new NasmCall(null, new NasmLabel("iprintLF"), "#Write 2")); return null; } - public NasmOperand visit(C3aBooleanConstant oper){ + + @Override + public NasmOperand visit(C3aInstStop inst) { + NasmRegister registerebx = nasm.newRegister(); + registerebx.colorRegister(Nasm.REG_EBX); + NasmRegister registereax = nasm.newRegister(); + registereax.colorRegister(Nasm.REG_EAX); + nasm.ajouteInst(new NasmMov(null, registerebx, new NasmConstant(0), "#valeur de retour du programme")); + nasm.ajouteInst(new NasmMov(null, registereax, new NasmConstant(1), "#code de sortie")); + nasm.ajouteInst(new NasmInt(null, "#sys call")); return null; } - public NasmOperand visit(C3aLabel oper){ - return new NasmLabel("l" + label.number); + + @Override + public NasmOperand visit(C3aConstant oper) { + return new NasmConstant(oper.val); } - public NasmOperand visit(C3aTemp oper){ - return null; + + @Override + public NasmOperand visit(C3aBooleanConstant oper) { + return new NasmConstant(oper.val ? 1 : 0); } - public NasmOperand visit(C3aVar oper){ - return null; + @Override + public NasmOperand visit(C3aLabel oper) { + return new NasmLabel("l" + oper.number); } - public NasmOperand visit(C3aFunction oper){ - return null; + + public NasmOperand visit(C3aTemp temp) { + return new NasmRegister(temp.num); } + @Override + public NasmOperand visit(C3aVar oper) { + C3aOperand index = oper.index; + if (index == null) { + if (oper.item.portee == tableGlobale) { + return new NasmAddress(new NasmLabel(oper.item.getIdentif()), NasmSize.DWORD); + } else { + if (oper.item.isParam) { + int indexOfParam = (oper.item.getAdresse() / 4); + return new NasmAddress(new NasmExpPlus(ebp, new NasmConstant(8 + 4 * (oper.item.portee.getAdrArgCourante() / 4 - indexOfParam))), NasmSize.DWORD); + } else { + int indexOfVar = (oper.item.getAdresse() / 4) + 1; + return new NasmAddress(new NasmExpMinus(ebp, new NasmConstant(4 * indexOfVar)), NasmSize.DWORD); + } + } + } else { + NasmRegister r = nasm.newRegister(); + nasm.ajouteInst(new NasmMov(null, r, oper.index.accept(this), "")); + nasm.ajouteInst(new NasmMul(null, r, new NasmConstant(4), "")); + if (oper.item.portee == tableGlobale) { + return new NasmAddress(new NasmExpPlus(new NasmLabel(oper.item.getIdentif()), r), NasmSize.DWORD); + } else { + return null; + } + } + } + + @Override + public NasmOperand visit(C3aFunction oper) { + return new NasmLabel(oper.val.identif); + } }