diff --git a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecBuilder.java b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecBuilder.java index 3f807e042..8248ca2a3 100644 --- a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecBuilder.java +++ b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecBuilder.java @@ -42,28 +42,13 @@ public class AsmFragmentInstanceSpecBuilder { private int nextMemIdx = 1; private int nextConstIdx = 1; private int nextLabelIdx = 1; - - /** - * Create a fragment instance spec factory for an interrupt routine (entry or exit) - * - * @param interruptTypeComplete The interrupt routine handler name - including "isr_" and "_entry"/_exit" - * @param program The program - * @return the fragment instance spec factory - */ - public static AsmFragmentInstanceSpecBuilder interrupt(String interruptTypeComplete, Program program) { - Map bindings = new HashMap<>(); - String signature = interruptTypeComplete; - ScopeRef codeScope = program.getScope().getRef(); - final AsmFragmentInstanceSpec fragmentInstanceSpec = new AsmFragmentInstanceSpec(program, signature, bindings, codeScope); - return new AsmFragmentInstanceSpecBuilder(program, bindings, fragmentInstanceSpec); - } - + /** * Create a fragment instance spec factory for an indirect call * @return the fragment instance spec factory */ - public static AsmFragmentInstanceSpecBuilder call(StatementCallExecute call, int indirectCallId, Program program) { - return new AsmFragmentInstanceSpecBuilder(call, indirectCallId, program); + public static AsmFragmentInstanceSpec call(StatementCallExecute call, int indirectCallId, Program program) { + return new AsmFragmentInstanceSpecBuilder(call, indirectCallId, program).getAsmFragmentInstanceSpec(); } private AsmFragmentInstanceSpecBuilder(StatementCallExecute call, int indirectCallId, Program program) { @@ -85,12 +70,12 @@ public class AsmFragmentInstanceSpecBuilder { * @param program The program * @return the fragment instance spec factory */ - public static AsmFragmentInstanceSpecBuilder interruptEntry(String interruptType, Program program) { + public static AsmFragmentInstanceSpec interruptEntry(String interruptType, Program program) { Map bindings = new HashMap<>(); String signature = "isr_" + interruptType + "_entry"; ScopeRef codeScope = program.getScope().getRef(); final AsmFragmentInstanceSpec fragmentInstanceSpec = new AsmFragmentInstanceSpec(program, signature, bindings, codeScope); - return new AsmFragmentInstanceSpecBuilder(program, bindings, fragmentInstanceSpec); + return new AsmFragmentInstanceSpecBuilder(program, bindings, fragmentInstanceSpec).getAsmFragmentInstanceSpec(); } /** @@ -100,12 +85,12 @@ public class AsmFragmentInstanceSpecBuilder { * @param program The program * @return the fragment instance spec factory */ - public static AsmFragmentInstanceSpecBuilder interruptExit(String interruptType, Program program) { + public static AsmFragmentInstanceSpec interruptExit(String interruptType, Program program) { Map bindings = new HashMap<>(); String signature = "isr_" + interruptType + "_exit"; ScopeRef codeScope = program.getScope().getRef(); final AsmFragmentInstanceSpec fragmentInstanceSpec = new AsmFragmentInstanceSpec(program, signature, bindings, codeScope); - return new AsmFragmentInstanceSpecBuilder(program, bindings, fragmentInstanceSpec); + return new AsmFragmentInstanceSpecBuilder(program, bindings, fragmentInstanceSpec).getAsmFragmentInstanceSpec(); } private AsmFragmentInstanceSpecBuilder(Program program, Map bindings, AsmFragmentInstanceSpec asmFragmentInstanceSpec) { @@ -115,8 +100,8 @@ public class AsmFragmentInstanceSpecBuilder { } - public static AsmFragmentInstanceSpecBuilder conditionalJump(StatementConditionalJump conditionalJump, ControlFlowBlock block, Program program) { - return new AsmFragmentInstanceSpecBuilder(conditionalJump, block, program); + public static AsmFragmentInstanceSpec conditionalJump(StatementConditionalJump conditionalJump, ControlFlowBlock block, Program program) { + return new AsmFragmentInstanceSpecBuilder(conditionalJump, block, program).getAsmFragmentInstanceSpec(); } private AsmFragmentInstanceSpecBuilder( @@ -130,8 +115,8 @@ public class AsmFragmentInstanceSpecBuilder { this.asmFragmentInstanceSpec = new AsmFragmentInstanceSpec(program, signature, bindings, codeScope); } - public static AsmFragmentInstanceSpecBuilder exprSideEffect(StatementExprSideEffect exprSideEffect, Program program) { - return new AsmFragmentInstanceSpecBuilder(exprSideEffect, program); + public static AsmFragmentInstanceSpec exprSideEffect(StatementExprSideEffect exprSideEffect, Program program) { + return new AsmFragmentInstanceSpecBuilder(exprSideEffect, program).getAsmFragmentInstanceSpec(); } private AsmFragmentInstanceSpecBuilder(StatementExprSideEffect exprSideEffect, Program program) { @@ -142,8 +127,8 @@ public class AsmFragmentInstanceSpecBuilder { this.asmFragmentInstanceSpec = new AsmFragmentInstanceSpec(program, signature, bindings, codeScope); } - public static AsmFragmentInstanceSpecBuilder assignment(StatementAssignment assignment, Program program) { - return new AsmFragmentInstanceSpecBuilder(assignment, program); + public static AsmFragmentInstanceSpec assignment(StatementAssignment assignment, Program program) { + return new AsmFragmentInstanceSpecBuilder(assignment, program).getAsmFragmentInstanceSpec(); } /** @@ -153,8 +138,8 @@ public class AsmFragmentInstanceSpecBuilder { * @param program The program * @return The ASM fragment instance */ - public static AsmFragmentInstanceSpecBuilder makelong4(StatementCall call, Program program) { - return new AsmFragmentInstanceSpecBuilder(call, program); + public static AsmFragmentInstanceSpec makelong4(StatementCall call, Program program) { + return new AsmFragmentInstanceSpecBuilder(call, program).getAsmFragmentInstanceSpec(); } private AsmFragmentInstanceSpecBuilder(StatementCall make4long, Program program) { @@ -190,8 +175,8 @@ public class AsmFragmentInstanceSpecBuilder { this.asmFragmentInstanceSpec = new AsmFragmentInstanceSpec(program, signature, bindings, codeScope); } - public static AsmFragmentInstanceSpecBuilder assignment(LValue lValue, RValue rValue, Program program, ScopeRef codeScopeRef) { - return new AsmFragmentInstanceSpecBuilder(lValue, rValue, program, codeScopeRef); + public static AsmFragmentInstanceSpec assignment(LValue lValue, RValue rValue, Program program, ScopeRef codeScopeRef) { + return new AsmFragmentInstanceSpecBuilder(lValue, rValue, program, codeScopeRef).getAsmFragmentInstanceSpec(); } private AsmFragmentInstanceSpecBuilder(LValue lValue, RValue rValue, Program program, ScopeRef codeScopeRef) { @@ -201,8 +186,8 @@ public class AsmFragmentInstanceSpecBuilder { this.asmFragmentInstanceSpec = new AsmFragmentInstanceSpec(program, signature, bindings, codeScopeRef); } - public static AsmFragmentInstanceSpecBuilder assignmentAlu(StatementAssignment assignment, StatementAssignment assignmentAlu, Program program) { - return new AsmFragmentInstanceSpecBuilder(assignment, assignmentAlu, program); + public static AsmFragmentInstanceSpec assignmentAlu(StatementAssignment assignment, StatementAssignment assignmentAlu, Program program) { + return new AsmFragmentInstanceSpecBuilder(assignment, assignmentAlu, program).getAsmFragmentInstanceSpec(); } private AsmFragmentInstanceSpecBuilder(StatementAssignment assignment, StatementAssignment assignmentAlu, Program program) { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java index 9a774b55d..a2144cfde 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java @@ -848,9 +848,7 @@ public class Pass4CodeGeneration { throw new AsmFragmentInstance.AluNotApplicableException(); } StatementAssignment assignment = (StatementAssignment) statement; - AsmFragmentInstanceSpecBuilder asmFragmentInstanceSpecBuilder = AsmFragmentInstanceSpecBuilder.assignmentAlu(assignment, assignmentAlu, program); - ensureEncoding(asm, asmFragmentInstanceSpecBuilder); - generateAsm(asm, asmFragmentInstanceSpecBuilder.getAsmFragmentInstanceSpec()); + generateAsm(asm, AsmFragmentInstanceSpecBuilder.assignmentAlu(assignment, assignmentAlu, program)); aluState.clear(); return; } @@ -873,23 +871,17 @@ public class Pass4CodeGeneration { if(assignment.getOperator() == null && assignment.getrValue1() == null && isRegisterCopy(lValue, assignment.getrValue2())) { //asm.addComment(lValue.toString(program) + " = " + assignment.getrValue2().toString(program) + " // register copy " + getRegister(lValue)); } else { - AsmFragmentInstanceSpecBuilder asmFragmentInstanceSpecBuilder = AsmFragmentInstanceSpecBuilder.assignment(assignment, program); - ensureEncoding(asm, asmFragmentInstanceSpecBuilder); - generateAsm(asm, asmFragmentInstanceSpecBuilder.getAsmFragmentInstanceSpec()); + generateAsm(asm, AsmFragmentInstanceSpecBuilder.assignment(assignment, program)); } } } else if(statement instanceof StatementConditionalJump) { - AsmFragmentInstanceSpecBuilder asmFragmentInstanceSpecBuilder = AsmFragmentInstanceSpecBuilder.conditionalJump((StatementConditionalJump) statement, block, program); - ensureEncoding(asm, asmFragmentInstanceSpecBuilder); - generateAsm(asm, asmFragmentInstanceSpecBuilder.getAsmFragmentInstanceSpec()); + generateAsm(asm, AsmFragmentInstanceSpecBuilder.conditionalJump((StatementConditionalJump) statement, block, program)); } else if(statement instanceof StatementCall) { StatementCall call = (StatementCall) statement; Procedure procedure = getScope().getProcedure(call.getProcedure()); if(procedure.isDeclaredIntrinsic()) { if(Pass1ByteXIntrinsicRewrite.INTRINSIC_MAKELONG4.equals(procedure.getFullName())) { - AsmFragmentInstanceSpecBuilder asmFragmentInstanceSpecBuilder = AsmFragmentInstanceSpecBuilder.makelong4(call, program); - ensureEncoding(asm, asmFragmentInstanceSpecBuilder); - generateAsm(asm, asmFragmentInstanceSpecBuilder.getAsmFragmentInstanceSpec()); + generateAsm(asm, AsmFragmentInstanceSpecBuilder.makelong4(call, program)); } else { throw new CompileError("Intrinsic procedure not supported " + procedure.toString(program)); } @@ -913,16 +905,12 @@ public class Pass4CodeGeneration { StatementCallExecute call = (StatementCallExecute) statement; RValue procedureRVal = call.getProcedureRVal(); // Generate ASM for a call - AsmFragmentInstanceSpecBuilder asmFragmentInstanceSpecBuilder = AsmFragmentInstanceSpecBuilder.call(call, indirectCallCount++, program); - ensureEncoding(asm, asmFragmentInstanceSpecBuilder); - generateAsm(asm, asmFragmentInstanceSpecBuilder.getAsmFragmentInstanceSpec()); + generateAsm(asm, AsmFragmentInstanceSpecBuilder.call(call, indirectCallCount++, program)); if(!(procedureRVal instanceof ProcedureRef)) { asm.getCurrentChunk().setClobberOverwrite(CpuClobber.CLOBBER_ALL); } } else if(statement instanceof StatementExprSideEffect) { - AsmFragmentInstanceSpecBuilder asmFragmentInstanceSpecBuilder = AsmFragmentInstanceSpecBuilder.exprSideEffect((StatementExprSideEffect) statement, program); - ensureEncoding(asm, asmFragmentInstanceSpecBuilder); - generateAsm(asm, asmFragmentInstanceSpecBuilder.getAsmFragmentInstanceSpec()); + generateAsm(asm, AsmFragmentInstanceSpecBuilder.exprSideEffect((StatementExprSideEffect) statement, program)); } else if(statement instanceof StatementReturn) { Procedure procedure = null; ScopeRef scope = block.getScope(); @@ -972,6 +960,7 @@ public class Pass4CodeGeneration { * @param fragmentInstanceSpec The ASM fragment instance specification */ private void generateAsm(AsmProgram asm, AsmFragmentInstanceSpec fragmentInstanceSpec) { + ensureEncoding(asm, fragmentInstanceSpec); String initialSignature = fragmentInstanceSpec.getSignature(); AsmFragmentInstance fragmentInstance = null; StringBuilder fragmentVariationsTried = new StringBuilder(); @@ -1006,20 +995,20 @@ public class Pass4CodeGeneration { */ private void generateInterruptEntry(AsmProgram asm, Procedure procedure) { final String interruptType = procedure.getInterruptType().toLowerCase(); - AsmFragmentInstanceSpecBuilder entryFragment; + AsmFragmentInstanceSpec entryFragment; String entryName; if(interruptType.contains("clobber")) { entryFragment = AsmFragmentInstanceSpecBuilder.interruptEntry(interruptType.replace("clobber", "all"), program); - entryName = entryFragment.getAsmFragmentInstanceSpec().getSignature().replace("all", "clobber"); + entryName = entryFragment.getSignature().replace("all", "clobber"); } else { entryFragment = AsmFragmentInstanceSpecBuilder.interruptEntry(interruptType, program); - entryName = entryFragment.getAsmFragmentInstanceSpec().getSignature(); + entryName = entryFragment.getSignature(); } try { asm.startChunk(procedure.getRef(), null, "interrupt(" + entryName + ")"); - generateAsm(asm, entryFragment.getAsmFragmentInstanceSpec()); + generateAsm(asm, entryFragment); } catch(AsmFragmentTemplateSynthesizer.UnknownFragmentException e) { - throw new CompileError("Interrupt type not supported " + procedure.getInterruptType() + " int " + procedure.toString() + "\n" + e.getMessage()); + throw new CompileError("Interrupt type not supported " + procedure.getInterruptType() + " int " + procedure + "\n" + e.getMessage()); } } @@ -1031,20 +1020,20 @@ public class Pass4CodeGeneration { */ private void generateInterruptExit(AsmProgram asm, Procedure procedure) { final String interruptType = procedure.getInterruptType().toLowerCase(); - AsmFragmentInstanceSpecBuilder entryFragment; + AsmFragmentInstanceSpec entryFragment; String entryName; if(interruptType.contains("clobber")) { entryFragment = AsmFragmentInstanceSpecBuilder.interruptExit(interruptType.replace("clobber", "all"), program); - entryName = entryFragment.getAsmFragmentInstanceSpec().getSignature().replace("all", "clobber"); + entryName = entryFragment.getSignature().replace("all", "clobber"); } else { entryFragment = AsmFragmentInstanceSpecBuilder.interruptExit(interruptType, program); - entryName = entryFragment.getAsmFragmentInstanceSpec().getSignature(); + entryName = entryFragment.getSignature(); } asm.startChunk(procedure.getRef(), null, "interrupt(" + entryName + ")"); try { - generateAsm(asm, entryFragment.getAsmFragmentInstanceSpec()); + generateAsm(asm, entryFragment); } catch(AsmFragmentTemplateSynthesizer.UnknownFragmentException e) { - throw new CompileError("Interrupt type not supported " + procedure.getInterruptType() + " int " + procedure.toString() + "\n" + e.getMessage()); + throw new CompileError("Interrupt type not supported " + procedure.getInterruptType() + " int " + procedure + "\n" + e.getMessage()); } } @@ -1121,9 +1110,7 @@ public class Pass4CodeGeneration { if(isRegisterCopy(lValue, rValue)) { asm.getCurrentChunk().setFragment("register_copy"); } else { - AsmFragmentInstanceSpecBuilder asmFragmentInstanceSpecBuilder = AsmFragmentInstanceSpecBuilder.assignment(lValue, rValue, program, scope); - ensureEncoding(asm, asmFragmentInstanceSpecBuilder); - generateAsm(asm, asmFragmentInstanceSpecBuilder.getAsmFragmentInstanceSpec()); + generateAsm(asm, AsmFragmentInstanceSpecBuilder.assignment(lValue, rValue, program, scope)); } } transitionSetGenerated(transition); @@ -1132,14 +1119,13 @@ public class Pass4CodeGeneration { } } - /** * Ensure that the current encoding in the ASM matches any encoding in the data to be emitted * * @param asm The ASM program (where any .encoding directive will be emitted) * @param asmFragmentInstance The ASM fragment to be emitted */ - private static void ensureEncoding(AsmProgram asm, AsmFragmentInstanceSpecBuilder asmFragmentInstance) { + private static void ensureEncoding(AsmProgram asm, AsmFragmentInstanceSpec asmFragmentInstance) { asm.ensureEncoding(getEncoding(asmFragmentInstance)); } @@ -1175,7 +1161,7 @@ public class Pass4CodeGeneration { * @param asmFragmentInstance The asm fragment instance to examine * @return Any encoding found inside the constant */ - private static Set getEncoding(AsmFragmentInstanceSpecBuilder asmFragmentInstance) { + private static Set getEncoding(AsmFragmentInstanceSpec asmFragmentInstance) { LinkedHashSet encodings = new LinkedHashSet<>(); Map bindings = asmFragmentInstance.getBindings(); for(Value boundValue : bindings.values()) { @@ -1184,7 +1170,6 @@ public class Pass4CodeGeneration { return encodings; } - /** * Get phi transitions for a specific to-block. * diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4InterruptClobberFix.java b/src/main/java/dk/camelot64/kickc/passes/Pass4InterruptClobberFix.java index ae2b2215d..b6076f8a2 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4InterruptClobberFix.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4InterruptClobberFix.java @@ -1,10 +1,9 @@ package dk.camelot64.kickc.passes; import dk.camelot64.cpufamily6502.CpuClobber; -import dk.camelot64.kickc.asm.*; -import dk.camelot64.kickc.fragment.AsmFragmentInstance; -import dk.camelot64.kickc.fragment.AsmFragmentInstanceSpecBuilder; -import dk.camelot64.kickc.fragment.AsmFragmentTemplateSynthesizer; +import dk.camelot64.kickc.asm.AsmChunk; +import dk.camelot64.kickc.asm.AsmLine; +import dk.camelot64.kickc.asm.AsmProgram; import dk.camelot64.kickc.model.CallGraph; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.symbols.Procedure; @@ -119,7 +118,7 @@ public class Pass4InterruptClobberFix extends Pass2Base { * Prune the interrupt entry/exit fragment removing code handling non-clobbered registers * * @param interruptAsmChunk The AsmFragment representing an interrupt entry/exit - * @param nonClobberedRegisters The non-clobbered registers + * @param clobberedRegisters The clobbered registers */ private void pruneFragmentClobber(AsmChunk interruptAsmChunk, String clobberedRegisters) { final ListIterator asmLineListIterator = interruptAsmChunk.getLines().listIterator();