diff --git a/.idea/modules.xml b/.idea/modules.xml index 122afccff..dbde0842a 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,7 +2,6 @@ - diff --git a/OldCodeGen/OldCodeGen.iml b/OldCodeGen/OldCodeGen.iml deleted file mode 100644 index 768559d7e..000000000 --- a/OldCodeGen/OldCodeGen.iml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/OldCodeGen/src/oldcodegen/AsmGen.kt b/OldCodeGen/src/oldcodegen/AsmGen.kt deleted file mode 100644 index 95eaee845..000000000 --- a/OldCodeGen/src/oldcodegen/AsmGen.kt +++ /dev/null @@ -1,762 +0,0 @@ -package oldcodegen - -/** OLD STACK-VM CODE GEN -- NO LONGER USED **/ - -// note: to put stuff on the stack, we use Absolute,X addressing mode which is 3 bytes / 4 cycles -// possible space optimization is to use zeropage (indirect),Y which is 2 bytes, but 5 cycles - -import prog8.ast.antlr.escape -import prog8.ast.base.DataType -import prog8.ast.base.initvarsSubName -import prog8.ast.statements.ZeropageWish -import prog8.compiler.* -import prog8.compiler.intermediate.Instruction -import prog8.compiler.intermediate.IntermediateProgram -import prog8.compiler.intermediate.LabelInstr -import prog8.compiler.intermediate.Opcode -import prog8.compiler.target.c64.AssemblyProgram -import prog8.compiler.target.c64.MachineDefinition -import prog8.compiler.target.c64.Petscii -import prog8.vm.RuntimeValue -import java.io.File -import kotlin.math.abs - - -class AssemblyError(msg: String) : RuntimeException(msg) - - - -internal fun intVal(valueInstr: Instruction) = valueInstr.arg!!.integerValue() -internal fun hexVal(valueInstr: Instruction) = valueInstr.arg!!.integerValue().toHex() -internal fun hexValPlusOne(valueInstr: Instruction) = (valueInstr.arg!!.integerValue()+1).toHex() -internal fun getFloatConst(value: RuntimeValue): String = - globalFloatConsts[value.numericValue().toDouble()] - ?: throw AssemblyError("should have a global float const for number $value") - -internal val globalFloatConsts = mutableMapOf() - -internal fun signExtendA(into: String) = - """ - ora #$7f - bmi + - lda #0 -+ sta $into - """ - -class AsmGen(private val options: CompilationOptions, private val program: IntermediateProgram, - private val heap: HeapValues, private val zeropage: Zeropage) { - private val assemblyLines = mutableListOf() - private lateinit var block: IntermediateProgram.ProgramBlock - - init { - // Convert invalid label names (such as "") to something that's allowed. - val newblocks = mutableListOf() - for(block in program.blocks) { - val newvars = block.variables.map { IntermediateProgram.Variable(symname(it.scopedname, block), it.value, it.params) }.toMutableList() - val newlabels = block.labels.map { symname(it.key, block) to it.value}.toMap().toMutableMap() - val newinstructions = block.instructions.asSequence().map { - when { - it is LabelInstr -> LabelInstr(symname(it.name, block), it.asmProc) - it.opcode == Opcode.INLINE_ASSEMBLY -> it - else -> - Instruction(it.opcode, it.arg, it.arg2, - callLabel = if (it.callLabel != null) symname(it.callLabel, block) else null, - callLabel2 = if (it.callLabel2 != null) symname(it.callLabel2, block) else null) - } - }.toMutableList() - val newMempointers = block.memoryPointers.map { symname(it.key, block) to it.value }.toMap().toMutableMap() - val newblock = IntermediateProgram.ProgramBlock( - block.name, - block.address, - newinstructions, - newvars, - newMempointers, - newlabels, - force_output = block.force_output) - newblocks.add(newblock) - } - program.blocks.clear() - program.blocks.addAll(newblocks) - - val newAllocatedZp = program.allocatedZeropageVariables.map { symname(it.key, null) to it.value} - program.allocatedZeropageVariables.clear() - program.allocatedZeropageVariables.putAll(newAllocatedZp) - - // make a list of all const floats that are used - for(block in program.blocks) { - for(ins in block.instructions.filter{it.arg?.type== DataType.FLOAT}) { - val float = ins.arg!!.numericValue().toDouble() - if(float !in globalFloatConsts) - globalFloatConsts[float] = "prog8_const_float_${globalFloatConsts.size}" - } - } - } - - fun compileToAssembly(optimize: Boolean): AssemblyProgram { - println("Generating assembly code from intermediate code... ") - - assemblyLines.clear() - header() - for(b in program.blocks) - block2asm(b) - - if(optimize) { - var optimizationsDone = 1 - while (optimizationsDone > 0) { - optimizationsDone = optimizeAssembly(assemblyLines) - } - } - - File("${program.name}.asm").printWriter().use { - for (line in assemblyLines) { it.println(line) } - } - - return AssemblyProgram(program.name) - } - - private fun out(str: String, splitlines: Boolean=true) { - if(splitlines) { - for (line in str.split('\n')) { - val trimmed = if (line.startsWith(' ')) "\t" + line.trim() else line.trim() - // trimmed = trimmed.replace(Regex("^\\+\\s+"), "+\t") // sanitize local label indentation - assemblyLines.add(trimmed) - } - } else assemblyLines.add(str) - } - - - // convert a fully scoped name (defined in the given block) to a valid assembly symbol name - private fun symname(scoped: String, block: IntermediateProgram.ProgramBlock?): String { - if(' ' in scoped) - return scoped - val blockLocal: Boolean - var name = if (block!=null && scoped.startsWith("${block.name}.")) { - blockLocal = true - scoped.substring(block.name.length+1) - } - else { - blockLocal = false - scoped - } - name = name.replace("<", "prog8_").replace(">", "") // take care of the autogenerated invalid (anon) label names - if(name=="-") - return "-" - if(blockLocal) - name = name.replace(".", "_") - else { - val parts = name.split(".", limit=2) - if(parts.size>1) - name = "${parts[0]}.${parts[1].replace(".", "_")}" - } - return name.replace("-", "") - } - - private fun makeFloatFill(flt: MachineDefinition.Mflpt5): String { - val b0 = "$"+flt.b0.toString(16).padStart(2, '0') - val b1 = "$"+flt.b1.toString(16).padStart(2, '0') - val b2 = "$"+flt.b2.toString(16).padStart(2, '0') - val b3 = "$"+flt.b3.toString(16).padStart(2, '0') - val b4 = "$"+flt.b4.toString(16).padStart(2, '0') - return "$b0, $b1, $b2, $b3, $b4" - } - - private fun header() { - val ourName = this.javaClass.name - out("; 6502 assembly code for '${program.name}'") - out("; generated by $ourName on ${Date()}") - out("; assembler syntax is for the 64tasm cross-assembler") - out("; output options: output=${options.output} launcher=${options.launcher} zp=${options.zeropage}") - out("\n.cpu '6502'\n.enc 'none'\n") - - if(program.loadAddress==0) // fix load address - program.loadAddress = if(options.launcher==LauncherType.BASIC) - MachineDefinition.BASIC_LOAD_ADDRESS else MachineDefinition.RAW_LOAD_ADDRESS - - when { - options.launcher == LauncherType.BASIC -> { - if (program.loadAddress != 0x0801) - throw AssemblyError("BASIC output must have load address $0801") - out("; ---- basic program with sys call ----") - out("* = ${program.loadAddress.toHex()}") - val year = Calendar.getInstance().get(Calendar.YEAR) - out(" .word (+), $year") - out(" .null $9e, format(' %d ', _prog8_entrypoint), $3a, $8f, ' prog8 by idj'") - out("+\t.word 0") - out("_prog8_entrypoint\t; assembly code starts here\n") - out(" jsr prog8_lib.init_system") - } - options.output == OutputType.PRG -> { - out("; ---- program without basic sys call ----") - out("* = ${program.loadAddress.toHex()}\n") - out(" jsr prog8_lib.init_system") - } - options.output == OutputType.RAW -> { - out("; ---- raw assembler program ----") - out("* = ${program.loadAddress.toHex()}\n") - } - } - - if(zeropage.exitProgramStrategy!=Zeropage.ExitProgramStrategy.CLEAN_EXIT) { - // disable shift-commodore charset switching and run/stop key - out(" lda #$80") - out(" lda #$80") - out(" sta 657\t; disable charset switching") - out(" lda #239") - out(" sta 808\t; disable run/stop key") - } - - out(" ldx #\$ff\t; init estack pointer") - out(" ; initialize the variables in each block") - for(block in program.blocks) { - val initVarsLabel = block.instructions.firstOrNull { it is LabelInstr && it.name== initvarsSubName } as? LabelInstr - if(initVarsLabel!=null) - out(" jsr ${block.name}.${initVarsLabel.name}") - } - out(" clc") - when(zeropage.exitProgramStrategy) { - Zeropage.ExitProgramStrategy.CLEAN_EXIT -> { - out(" jmp main.start\t; jump to program entrypoint") - } - Zeropage.ExitProgramStrategy.SYSTEM_RESET -> { - out(" jsr main.start\t; call program entrypoint") - out(" jmp (c64.RESET_VEC)\t; cold reset") - } - } - out("") - - // the global list of all floating point constants for the whole program - for(flt in globalFloatConsts) { - val floatFill = makeFloatFill(MachineDefinition.Mflpt5.fromNumber(flt.key)) - out("${flt.value}\t.byte $floatFill ; float ${flt.key}") - } - } - - private fun block2asm(blk: IntermediateProgram.ProgramBlock) { - block = blk - out("\n\n; ---- block: '${block.name}' ----") - if(!blk.force_output) - out("${block.name}\t.proc\n") - if(block.address!=null) { - out(".cerror * > ${block.address?.toHex()}, 'block address overlaps by ', *-${block.address?.toHex()},' bytes'") - out("* = ${block.address?.toHex()}") - } - - // deal with zeropage variables - for(variable in blk.variables) { - val sym = symname(blk.name+"."+variable.scopedname, null) - val zpVar = program.allocatedZeropageVariables[sym] - if(zpVar==null) { - // This var is not on the ZP yet. Attempt to move it there (if it's not a float, those take up too much space) - if(variable.params.zp != ZeropageWish.NOT_IN_ZEROPAGE && - variable.value.type in zeropage.allowedDatatypes - && variable.value.type != DataType.FLOAT) { - try { - val address = zeropage.allocate(sym, variable.value.type, null) - out("${variable.scopedname} = $address\t; auto zp ${variable.value.type}") - // make sure we add the var to the set of zpvars for this block - program.allocatedZeropageVariables[sym] = Pair(address, variable.value.type) - } catch (x: ZeropageDepletedError) { - // leave it as it is. - } - } - } - else { - // it was already allocated on the zp - out("${variable.scopedname} = ${zpVar.first}\t; zp ${zpVar.second}") - } - } - - out("\n; memdefs and kernel subroutines") - memdefs2asm(block) - out("\n; non-zeropage variables") - vardecls2asm(block) - out("") - - val instructionPatternWindowSize = 8 // increase once patterns occur longer than this. - var processed = 0 - - for (ins in block.instructions.windowed(instructionPatternWindowSize, partialWindows = true)) { - if (processed == 0) { - processed = instr2asm(ins) - if (processed == 0) { - // the instructions are not recognised yet and can't be translated into assembly - throw CompilerException("no asm translation found for instruction pattern: $ins") - } - } - processed-- - } - if(!blk.force_output) - out("\n\t.pend\n") - } - - private fun memdefs2asm(block: IntermediateProgram.ProgramBlock) { - for(m in block.memoryPointers) { - out(" ${m.key} = ${m.value.first.toHex()}") - } - } - - private fun vardecls2asm(block: IntermediateProgram.ProgramBlock) { - val uniqueNames = block.variables.map { it.scopedname }.toSet() - if (uniqueNames.size != block.variables.size) - throw AssemblyError("not all variables have unique names") - - // these are the non-zeropage variables. - // first get all the flattened struct members, they MUST remain in order - out("; flattened struct members") - val (structMembers, normalVars) = block.variables.partition { it.params.memberOfStruct!=null } - structMembers.forEach { vardecl2asm(it.scopedname, it.value, it.params) } - - // sort the other variables by type - out("; other variables sorted by type") - val sortedVars = normalVars.sortedBy { it.value.type } - for (variable in sortedVars) { - val sym = symname(block.name + "." + variable.scopedname, null) - if(sym in program.allocatedZeropageVariables) - continue // skip the ones that already belong in the zero page - vardecl2asm(variable.scopedname, variable.value, variable.params) - } - } - - private fun vardecl2asm(varname: String, value: RuntimeValue, parameters: IntermediateProgram.VariableParameters) { - when (value.type) { - DataType.UBYTE -> out("$varname\t.byte 0") - DataType.BYTE -> out("$varname\t.char 0") - DataType.UWORD -> out("$varname\t.word 0") - DataType.WORD -> out("$varname\t.sint 0") - DataType.FLOAT -> out("$varname\t.byte 0,0,0,0,0 ; float") - DataType.STR, DataType.STR_S -> { - val rawStr = heap.get(value.heapId!!).str!! - val bytes = encodeStr(rawStr, value.type).map { "$" + it.toString(16).padStart(2, '0') } - out("$varname\t; ${value.type} \"${escape(rawStr).replace("\u0000", "")}\"") - for (chunk in bytes.chunked(16)) - out(" .byte " + chunk.joinToString()) - } - DataType.ARRAY_UB -> { - // unsigned integer byte arraysize - val data = makeArrayFillDataUnsigned(value) - if (data.size <= 16) - out("$varname\t.byte ${data.joinToString()}") - else { - out(varname) - for (chunk in data.chunked(16)) - out(" .byte " + chunk.joinToString()) - } - } - DataType.ARRAY_B -> { - // signed integer byte arraysize - val data = makeArrayFillDataSigned(value) - if (data.size <= 16) - out("$varname\t.char ${data.joinToString()}") - else { - out(varname) - for (chunk in data.chunked(16)) - out(" .char " + chunk.joinToString()) - } - } - DataType.ARRAY_UW -> { - // unsigned word arraysize - val data = makeArrayFillDataUnsigned(value) - if (data.size <= 16) - out("$varname\t.word ${data.joinToString()}") - else { - out(varname) - for (chunk in data.chunked(16)) - out(" .word " + chunk.joinToString()) - } - } - DataType.ARRAY_W -> { - // signed word arraysize - val data = makeArrayFillDataSigned(value) - if (data.size <= 16) - out("$varname\t.sint ${data.joinToString()}") - else { - out(varname) - for (chunk in data.chunked(16)) - out(" .sint " + chunk.joinToString()) - } - } - DataType.ARRAY_F -> { - // float arraysize - val array = heap.get(value.heapId!!).doubleArray!! - val floatFills = array.map { makeFloatFill(MachineDefinition.Mflpt5.fromNumber(it)) } - out(varname) - for (f in array.zip(floatFills)) - out(" .byte ${f.second} ; float ${f.first}") - } - DataType.STRUCT -> throw AssemblyError("vars of type STRUCT should have been removed because flattened") - } - } - - - private fun encodeStr(str: String, dt: DataType): List { - return when(dt) { - DataType.STR -> { - val bytes = Petscii.encodePetscii(str, true) - bytes.plus(0) - } - DataType.STR_S -> { - val bytes = Petscii.encodeScreencode(str, true) - bytes.plus(0) - } - else -> throw AssemblyError("invalid str type") - } - } - - private fun makeArrayFillDataUnsigned(value: RuntimeValue): List { - val array = heap.get(value.heapId!!).array!! - return when { - value.type== DataType.ARRAY_UB -> - // byte array can never contain pointer-to types, so treat values as all integers - array.map { "$"+it.integer!!.toString(16).padStart(2, '0') } - value.type== DataType.ARRAY_UW -> array.map { - when { - it.integer!=null -> "$"+it.integer.toString(16).padStart(2, '0') - it.addressOf!=null -> symname(it.addressOf.scopedname!!, block) - else -> throw AssemblyError("weird type in array") - } - } - else -> throw AssemblyError("invalid arraysize type") - } - } - - private fun makeArrayFillDataSigned(value: RuntimeValue): List { - val array = heap.get(value.heapId!!).array!! - // note: array of signed value can never contain pointer-to type, so simply accept values as being all integers - return if (value.type == DataType.ARRAY_B || value.type == DataType.ARRAY_W) { - array.map { - if(it.integer!!>=0) - "$"+it.integer.toString(16).padStart(2, '0') - else - "-$"+abs(it.integer).toString(16).padStart(2, '0') - } - } - else throw AssemblyError("invalid arraysize type") - } - - private fun instr2asm(ins: List): Int { - // find best patterns (matching the most of the lines, then with the smallest weight) - val fragments = findPatterns(ins).sortedByDescending { it.segmentSize } - if(fragments.isEmpty()) { - // we didn't find any matching patterns (complex multi-instruction fragments), try simple ones - val firstIns = ins[0] - val singleAsm = simpleInstr2Asm(firstIns, block) - if(singleAsm != null) { - outputAsmFragment(singleAsm) - return 1 - } - return 0 - } - val best = fragments[0] - outputAsmFragment(best.asm) - return best.segmentSize - } - - private fun outputAsmFragment(singleAsm: String) { - if (singleAsm.isNotEmpty()) { - if(singleAsm.startsWith("@inline@")) - out(singleAsm.substring(8), false) - else { - val withNewlines = singleAsm.replace('|', '\n') - out(withNewlines) - } - } - } - - private fun findPatterns(segment: List): List { - val opcodes = segment.map { it.opcode } - val result = mutableListOf() - - // check for operations that modify a single value, by putting it on the stack (and popping it afterwards) - if((opcodes[0]==Opcode.PUSH_VAR_BYTE && opcodes[2]==Opcode.POP_VAR_BYTE) || - (opcodes[0]==Opcode.PUSH_VAR_WORD && opcodes[2]==Opcode.POP_VAR_WORD) || - (opcodes[0]==Opcode.PUSH_VAR_FLOAT && opcodes[2]==Opcode.POP_VAR_FLOAT)) { - if (segment[0].callLabel == segment[2].callLabel) { - val fragment = sameVarOperation(segment[0].callLabel!!, segment[1]) - if (fragment != null) { - fragment.segmentSize = 3 - result.add(fragment) - } - } - } - else if((opcodes[0]==Opcode.PUSH_BYTE && opcodes[1] in setOf(Opcode.INC_INDEXED_VAR_B, Opcode.INC_INDEXED_VAR_UB, - Opcode.INC_INDEXED_VAR_UW, Opcode.INC_INDEXED_VAR_W, Opcode.INC_INDEXED_VAR_FLOAT, - Opcode.DEC_INDEXED_VAR_B, Opcode.DEC_INDEXED_VAR_UB, Opcode.DEC_INDEXED_VAR_W, - Opcode.DEC_INDEXED_VAR_UW, Opcode.DEC_INDEXED_VAR_FLOAT))) { - val fragment = sameConstantIndexedVarOperation(segment[1].callLabel!!, segment[0].arg!!.integerValue(), segment[1]) - if(fragment!=null) { - fragment.segmentSize=2 - result.add(fragment) - } - } - else if((opcodes[0]==Opcode.PUSH_VAR_BYTE && opcodes[1] in setOf(Opcode.INC_INDEXED_VAR_B, Opcode.INC_INDEXED_VAR_UB, - Opcode.INC_INDEXED_VAR_UW, Opcode.INC_INDEXED_VAR_W, Opcode.INC_INDEXED_VAR_FLOAT, - Opcode.DEC_INDEXED_VAR_B, Opcode.DEC_INDEXED_VAR_UB, Opcode.DEC_INDEXED_VAR_W, - Opcode.DEC_INDEXED_VAR_UW, Opcode.DEC_INDEXED_VAR_FLOAT))) { - val fragment = sameIndexedVarOperation(segment[1].callLabel!!, segment[0].callLabel!!, segment[1]) - if(fragment!=null) { - fragment.segmentSize=2 - result.add(fragment) - } - } - else if((opcodes[0]==Opcode.PUSH_MEM_UB && opcodes[2]==Opcode.POP_MEM_BYTE) || - (opcodes[0]==Opcode.PUSH_MEM_B && opcodes[2]==Opcode.POP_MEM_BYTE) || - (opcodes[0]==Opcode.PUSH_MEM_UW && opcodes[2]==Opcode.POP_MEM_WORD) || - (opcodes[0]==Opcode.PUSH_MEM_W && opcodes[2]==Opcode.POP_MEM_WORD) || - (opcodes[0]==Opcode.PUSH_MEM_FLOAT && opcodes[2]==Opcode.POP_MEM_FLOAT)) { - if(segment[0].arg==segment[2].arg) { - val fragment = sameMemOperation(segment[0].arg!!.integerValue(), segment[1]) - if(fragment!=null) { - fragment.segmentSize = 3 - result.add(fragment) - } - } - } - else if((opcodes[0]==Opcode.PUSH_BYTE && opcodes[1]==Opcode.READ_INDEXED_VAR_BYTE && - opcodes[3]==Opcode.PUSH_BYTE && opcodes[4]==Opcode.WRITE_INDEXED_VAR_BYTE) || - (opcodes[0]==Opcode.PUSH_BYTE && opcodes[1]==Opcode.READ_INDEXED_VAR_WORD && - opcodes[3]==Opcode.PUSH_BYTE && opcodes[4]==Opcode.WRITE_INDEXED_VAR_WORD)) { - if(segment[0].arg==segment[3].arg && segment[1].callLabel==segment[4].callLabel) { - val fragment = sameConstantIndexedVarOperation(segment[1].callLabel!!, segment[0].arg!!.integerValue(), segment[2]) - if(fragment!=null){ - fragment.segmentSize = 5 - result.add(fragment) - } - } - } - else if((opcodes[0]==Opcode.PUSH_VAR_BYTE && opcodes[1]==Opcode.READ_INDEXED_VAR_BYTE && - opcodes[3]==Opcode.PUSH_VAR_BYTE && opcodes[4]==Opcode.WRITE_INDEXED_VAR_BYTE) || - (opcodes[0]==Opcode.PUSH_VAR_BYTE && opcodes[1]==Opcode.READ_INDEXED_VAR_WORD && - opcodes[3]==Opcode.PUSH_VAR_BYTE && opcodes[4]==Opcode.WRITE_INDEXED_VAR_WORD)) { - if(segment[0].callLabel==segment[3].callLabel && segment[1].callLabel==segment[4].callLabel) { - val fragment = sameIndexedVarOperation(segment[1].callLabel!!, segment[0].callLabel!!, segment[2]) - if(fragment!=null){ - fragment.segmentSize = 5 - result.add(fragment) - } - } - } - - // add any matching patterns from the big list - for(pattern in Patterns.patterns) { - if(pattern.sequence.size > segment.size || (pattern.altSequence!=null && pattern.altSequence.size > segment.size)) - continue // don't accept patterns that don't fit - val opcodesList = opcodes.subList(0, pattern.sequence.size) - if(pattern.sequence == opcodesList) { - val asm = pattern.asm(segment) - if(asm!=null) - result.add(AsmFragment(asm, pattern.sequence.size)) - } else if(pattern.altSequence!=null) { - val opcodesListAlt = opcodes.subList(0, pattern.altSequence.size) - if(pattern.altSequence == opcodesListAlt) { - val asm = pattern.asm(segment) - if (asm != null) - result.add(AsmFragment(asm, pattern.sequence.size)) - } - } - } - - return result - } - - private fun sameConstantIndexedVarOperation(variable: String, index: Int, ins: Instruction): AsmFragment? { - // an in place operation that consists of a push-value / op / push-index-value / pop-into-indexed-var - return when(ins.opcode) { - Opcode.SHL_BYTE -> AsmFragment(" asl $variable+$index", 8) - Opcode.SHR_UBYTE -> AsmFragment(" lsr $variable+$index", 8) - Opcode.SHR_SBYTE -> AsmFragment(" lda $variable+$index | asl a | ror $variable+$index") - Opcode.SHL_WORD -> AsmFragment(" asl $variable+${index * 2 + 1} | rol $variable+${index * 2}", 8) - Opcode.SHR_UWORD -> AsmFragment(" lsr $variable+${index * 2 + 1} | ror $variable+${index * 2}", 8) - Opcode.SHR_SWORD -> AsmFragment(" lda $variable+${index * 2 + 1} | asl a | ror $variable+${index * 2 + 1} | ror $variable+${index * 2}", 8) - Opcode.ROL_BYTE -> AsmFragment(" rol $variable+$index", 8) - Opcode.ROR_BYTE -> AsmFragment(" ror $variable+$index", 8) - Opcode.ROL_WORD -> AsmFragment(" rol $variable+${index * 2 + 1} | rol $variable+${index * 2}", 8) - Opcode.ROR_WORD -> AsmFragment(" ror $variable+${index * 2 + 1} | ror $variable+${index * 2}", 8) - Opcode.ROL2_BYTE -> AsmFragment(" lda $variable+$index | cmp #\$80 | rol $variable+$index", 8) - Opcode.ROR2_BYTE -> AsmFragment(" lda $variable+$index | lsr a | bcc + | ora #\$80 |+ | sta $variable+$index", 10) - Opcode.ROL2_WORD -> AsmFragment(" asl $variable+${index * 2 + 1} | rol $variable+${index * 2} | bcc + | inc $variable+${index * 2 + 1} |+", 20) - Opcode.ROR2_WORD -> AsmFragment(" lsr $variable+${index * 2 + 1} | ror $variable+${index * 2} | bcc + | lda $variable+${index * 2 + 1} | ora #\$80 | sta $variable+${index * 2 + 1} |+", 30) - Opcode.INC_INDEXED_VAR_B, Opcode.INC_INDEXED_VAR_UB -> AsmFragment(" inc $variable+$index", 2) - Opcode.DEC_INDEXED_VAR_B, Opcode.DEC_INDEXED_VAR_UB -> AsmFragment(" dec $variable+$index", 5) - Opcode.INC_INDEXED_VAR_W, Opcode.INC_INDEXED_VAR_UW -> AsmFragment(" inc $variable+${index * 2} | bne + | inc $variable+${index * 2 + 1} |+") - Opcode.DEC_INDEXED_VAR_W, Opcode.DEC_INDEXED_VAR_UW -> AsmFragment(" lda $variable+${index * 2} | bne + | dec $variable+${index * 2 + 1} |+ | dec $variable+${index * 2}") - Opcode.INC_INDEXED_VAR_FLOAT -> AsmFragment( - """ - lda #<($variable+${index * MachineDefinition.Mflpt5.MemorySize}) - ldy #>($variable+${index * MachineDefinition.Mflpt5.MemorySize}) - jsr c64flt.inc_var_f - """) - Opcode.DEC_INDEXED_VAR_FLOAT -> AsmFragment( - """ - lda #<($variable+${index * MachineDefinition.Mflpt5.MemorySize}) - ldy #>($variable+${index * MachineDefinition.Mflpt5.MemorySize}) - jsr c64flt.dec_var_f - """) - - else -> null - } - } - - private fun sameIndexedVarOperation(variable: String, indexVar: String, ins: Instruction): AsmFragment? { - // an in place operation that consists of a push-value / op / push-index-var / pop-into-indexed-var - val saveX = " stx ${MachineDefinition.C64Zeropage.SCRATCH_B1} |" - val restoreX = " | ldx ${MachineDefinition.C64Zeropage.SCRATCH_B1}" - val loadXWord: String - val loadX: String - - when(indexVar) { - "X" -> { - loadX = "" - loadXWord = " txa | asl a | tax |" - } - "Y" -> { - loadX = " tya | tax |" - loadXWord = " tya | asl a | tax |" - } - "A" -> { - loadX = " tax |" - loadXWord = " asl a | tax |" - } - else -> { - // the indexvar is a real variable, not a register - loadX = " ldx $indexVar |" - loadXWord = " lda $indexVar | asl a | tax |" - } - } - - return when (ins.opcode) { - Opcode.SHL_BYTE -> AsmFragment(" txa | $loadX asl $variable,x | tax", 10) - Opcode.SHR_UBYTE -> AsmFragment(" txa | $loadX lsr $variable,x | tax", 10) - Opcode.SHR_SBYTE -> AsmFragment("$saveX $loadX lda $variable,x | asl a | ror $variable,x $restoreX", 10) - Opcode.SHL_WORD -> AsmFragment("$saveX $loadXWord asl $variable,x | rol $variable+1,x $restoreX", 10) - Opcode.SHR_UWORD -> AsmFragment("$saveX $loadXWord lsr $variable+1,x | ror $variable,x $restoreX", 10) - Opcode.SHR_SWORD -> AsmFragment("$saveX $loadXWord lda $variable+1,x | asl a | ror $variable+1,x | ror $variable,x $restoreX", 10) - Opcode.ROL_BYTE -> AsmFragment(" txa | $loadX rol $variable,x | tax", 10) - Opcode.ROR_BYTE -> AsmFragment(" txa | $loadX ror $variable,x | tax", 10) - Opcode.ROL_WORD -> AsmFragment("$saveX $loadXWord rol $variable,x | rol $variable+1,x $restoreX", 10) - Opcode.ROR_WORD -> AsmFragment("$saveX $loadXWord ror $variable+1,x | ror $variable,x $restoreX", 10) - Opcode.ROL2_BYTE -> AsmFragment("$saveX $loadX lda $variable,x | cmp #\$80 | rol $variable,x $restoreX", 10) - Opcode.ROR2_BYTE -> AsmFragment("$saveX $loadX lda $variable,x | lsr a | bcc + | ora #\$80 |+ | sta $variable,x $restoreX", 10) - Opcode.ROL2_WORD -> AsmFragment(" txa | $loadXWord asl $variable,x | rol $variable+1,x | bcc + | inc $variable,x |+ | tax", 30) - Opcode.ROR2_WORD -> AsmFragment("$saveX $loadXWord lsr $variable+1,x | ror $variable,x | bcc + | lda $variable+1,x | ora #\$80 | sta $variable+1,x |+ $restoreX", 30) - Opcode.INC_INDEXED_VAR_B, Opcode.INC_INDEXED_VAR_UB -> AsmFragment(" txa | $loadX inc $variable,x | tax", 10) - Opcode.DEC_INDEXED_VAR_B, Opcode.DEC_INDEXED_VAR_UB -> AsmFragment(" txa | $loadX dec $variable,x | tax", 10) - Opcode.INC_INDEXED_VAR_W, Opcode.INC_INDEXED_VAR_UW -> AsmFragment("$saveX $loadXWord inc $variable,x | bne + | inc $variable+1,x |+ $restoreX", 10) - Opcode.DEC_INDEXED_VAR_W, Opcode.DEC_INDEXED_VAR_UW -> AsmFragment("$saveX $loadXWord lda $variable,x | bne + | dec $variable+1,x |+ | dec $variable,x $restoreX", 10) - Opcode.INC_INDEXED_VAR_FLOAT -> AsmFragment(" lda #<$variable | ldy #>$variable | $saveX $loadX jsr c64flt.inc_indexed_var_f $restoreX") - Opcode.DEC_INDEXED_VAR_FLOAT -> AsmFragment(" lda #<$variable | ldy #>$variable | $saveX $loadX jsr c64flt.dec_indexed_var_f $restoreX") - - else -> null - } - } - - private fun sameMemOperation(address: Int, ins: Instruction): AsmFragment? { - // an in place operation that consists of push-mem / op / pop-mem - val addr = address.toHex() - val addrHi = (address+1).toHex() - return when(ins.opcode) { - Opcode.SHL_BYTE -> AsmFragment(" asl $addr", 10) - Opcode.SHR_UBYTE -> AsmFragment(" lsr $addr", 10) - Opcode.SHR_SBYTE -> AsmFragment(" lda $addr | asl a | ror $addr", 10) - Opcode.SHL_WORD -> AsmFragment(" asl $addr | rol $addrHi", 10) - Opcode.SHR_UWORD -> AsmFragment(" lsr $addrHi | ror $addr", 10) - Opcode.SHR_SWORD -> AsmFragment(" lda $addrHi | asl a | ror $addrHi | ror $addr", 10) - Opcode.ROL_BYTE -> AsmFragment(" rol $addr", 10) - Opcode.ROR_BYTE -> AsmFragment(" ror $addr", 10) - Opcode.ROL_WORD -> AsmFragment(" rol $addr | rol $addrHi", 10) - Opcode.ROR_WORD -> AsmFragment(" ror $addrHi | ror $addr", 10) - Opcode.ROL2_BYTE -> AsmFragment(" lda $addr | cmp #\$80 | rol $addr", 10) - Opcode.ROR2_BYTE -> AsmFragment(" lda $addr | lsr a | bcc + | ora #\$80 |+ | sta $addr", 10) - Opcode.ROL2_WORD -> AsmFragment(" lda $addr | cmp #\$80 | rol $addr | rol $addrHi", 10) - Opcode.ROR2_WORD -> AsmFragment(" lsr $addrHi | ror $addr | bcc + | lda $addrHi | ora #$80 | sta $addrHi |+", 20) - else -> null - } - } - - private fun sameVarOperation(variable: String, ins: Instruction): AsmFragment? { - // an in place operation that consists of a push-var / op / pop-var - return when(ins.opcode) { - Opcode.SHL_BYTE -> { - when (variable) { - "A" -> AsmFragment(" asl a", 10) - "X" -> AsmFragment(" txa | asl a | tax", 10) - "Y" -> AsmFragment(" tya | asl a | tay", 10) - else -> AsmFragment(" asl $variable", 10) - } - } - Opcode.SHR_UBYTE -> { - when (variable) { - "A" -> AsmFragment(" lsr a", 10) - "X" -> AsmFragment(" txa | lsr a | tax", 10) - "Y" -> AsmFragment(" tya | lsr a | tay", 10) - else -> AsmFragment(" lsr $variable", 10) - } - } - Opcode.SHR_SBYTE -> { - // arithmetic shift right (keep sign bit) - when (variable) { - "A" -> AsmFragment(" cmp #$80 | ror a", 10) - "X" -> AsmFragment(" txa | cmp #$80 | ror a | tax", 10) - "Y" -> AsmFragment(" tya | cmp #$80 | ror a | tay", 10) - else -> AsmFragment(" lda $variable | asl a | ror $variable", 10) - } - } - Opcode.SHL_WORD -> { - AsmFragment(" asl $variable | rol $variable+1", 10) - } - Opcode.SHR_UWORD -> { - AsmFragment(" lsr $variable+1 | ror $variable", 10) - } - Opcode.SHR_SWORD -> { - // arithmetic shift right (keep sign bit) - AsmFragment(" lda $variable+1 | asl a | ror $variable+1 | ror $variable", 10) - } - Opcode.ROL_BYTE -> { - when (variable) { - "A" -> AsmFragment(" rol a", 10) - "X" -> AsmFragment(" txa | rol a | tax", 10) - "Y" -> AsmFragment(" tya | rol a | tay", 10) - else -> AsmFragment(" rol $variable", 10) - } - } - Opcode.ROR_BYTE -> { - when (variable) { - "A" -> AsmFragment(" ror a", 10) - "X" -> AsmFragment(" txa | ror a | tax", 10) - "Y" -> AsmFragment(" tya | ror a | tay", 10) - else -> AsmFragment(" ror $variable", 10) - } - } - Opcode.ROL_WORD -> { - AsmFragment(" rol $variable | rol $variable+1", 10) - } - Opcode.ROR_WORD -> { - AsmFragment(" ror $variable+1 | ror $variable", 10) - } - Opcode.ROL2_BYTE -> { // 8-bit rol - when (variable) { - "A" -> AsmFragment(" cmp #\$80 | rol a", 10) - "X" -> AsmFragment(" txa | cmp #\$80 | rol a | tax", 10) - "Y" -> AsmFragment(" tya | cmp #\$80 | rol a | tay", 10) - else -> AsmFragment(" lda $variable | cmp #\$80 | rol $variable", 10) - } - } - Opcode.ROR2_BYTE -> { // 8-bit ror - when (variable) { - "A" -> AsmFragment(" lsr a | bcc + | ora #\$80 |+", 10) - "X" -> AsmFragment(" txa | lsr a | bcc + | ora #\$80 |+ | tax", 10) - "Y" -> AsmFragment(" tya | lsr a | bcc + | ora #\$80 |+ | tay", 10) - else -> AsmFragment(" lda $variable | lsr a | bcc + | ora #\$80 |+ | sta $variable", 10) - } - } - Opcode.ROL2_WORD -> { - AsmFragment(" lda $variable | cmp #\$80 | rol $variable | rol $variable+1", 10) - } - Opcode.ROR2_WORD -> { - AsmFragment(" lsr $variable+1 | ror $variable | bcc + | lda $variable+1 | ora #\$80 | sta $variable+1 |+", 30) - } - else -> null - } - } - - private class AsmFragment(val asm: String, var segmentSize: Int=0) -} diff --git a/OldCodeGen/src/oldcodegen/AsmPatterns.kt b/OldCodeGen/src/oldcodegen/AsmPatterns.kt deleted file mode 100644 index a35f66af1..000000000 --- a/OldCodeGen/src/oldcodegen/AsmPatterns.kt +++ /dev/null @@ -1,2342 +0,0 @@ -package oldcodegen - -/** OLD STACK-VM CODE GEN -- NO LONGER USED **/ - - -import prog8.ast.base.printWarning -import prog8.compiler.intermediate.Instruction -import prog8.compiler.intermediate.Opcode -import prog8.compiler.target.c64.MachineDefinition -import prog8.compiler.target.c64.MachineDefinition.C64Zeropage -import prog8.compiler.target.c64.MachineDefinition.ESTACK_HI_HEX -import prog8.compiler.target.c64.MachineDefinition.ESTACK_HI_PLUS1_HEX -import prog8.compiler.target.c64.MachineDefinition.ESTACK_LO_HEX -import prog8.compiler.target.c64.MachineDefinition.ESTACK_LO_PLUS1_HEX -import prog8.compiler.toHex - -// note: see https://wiki.nesdev.com/w/index.php/6502_assembly_optimisations - - -internal class AsmPattern(val sequence: List, val altSequence: List?=null, val asm: (List)->String?) - -internal fun loadAFromIndexedByVar(idxVarInstr: Instruction, readArrayInstr: Instruction): String { - // A = readArrayInstr [ idxVarInstr ] - return when (idxVarInstr.callLabel) { - "A" -> " tay | lda ${readArrayInstr.callLabel},y" - "X" -> " txa | tay | lda ${readArrayInstr.callLabel},y" - "Y" -> " lda ${readArrayInstr.callLabel},y" - else -> " ldy ${idxVarInstr.callLabel} | lda ${readArrayInstr.callLabel},y" - } -} - -internal fun loadAYFromWordIndexedByVar(idxVarInstr: Instruction, readArrayInstr: Instruction): String { - // AY = readWordArrayInstr [ idxVarInstr ] - return when(idxVarInstr.callLabel) { - "A" -> - """ - stx ${C64Zeropage.SCRATCH_B1} - asl a - tax - lda ${readArrayInstr.callLabel},x - ldy ${readArrayInstr.callLabel}+1,x - ldx ${C64Zeropage.SCRATCH_B1} - """ - "X" -> - """ - stx ${C64Zeropage.SCRATCH_B1} - txa - asl a - tax - lda ${readArrayInstr.callLabel},x - ldy ${readArrayInstr.callLabel}+1,x - ldx ${C64Zeropage.SCRATCH_B1} - """ - "Y" -> - """ - stx ${C64Zeropage.SCRATCH_B1} - tya - asl a - tax - lda ${readArrayInstr.callLabel},x - ldy ${readArrayInstr.callLabel}+1,x - ldx ${C64Zeropage.SCRATCH_B1} - """ - else -> - """ - stx ${C64Zeropage.SCRATCH_B1} - lda ${idxVarInstr.callLabel} - asl a - tax - lda ${readArrayInstr.callLabel},x - ldy ${readArrayInstr.callLabel}+1,x - ldx ${C64Zeropage.SCRATCH_B1} - """ - } -} - -internal fun storeAToIndexedByVar(idxVarInstr: Instruction, writeArrayInstr: Instruction): String { - // writeArrayInstr [ idxVarInstr ] = A - return when (idxVarInstr.callLabel) { - "A" -> " tay | sta ${writeArrayInstr.callLabel},y" - "X" -> " stx ${C64Zeropage.SCRATCH_B1} | ldy ${C64Zeropage.SCRATCH_B1} | sta ${writeArrayInstr.callLabel},y" - "Y" -> " sta ${writeArrayInstr.callLabel},y" - else -> " ldy ${idxVarInstr.callLabel} | sta ${writeArrayInstr.callLabel},y" - } -} - -internal fun optimizedIntMultiplicationsOnStack(mulIns: Instruction, amount: Int): String? { - - if(mulIns.opcode == Opcode.MUL_B || mulIns.opcode==Opcode.MUL_UB) { - if(amount in setOf(0,1,2,4,8,16,32,64,128,256)) - printWarning("multiplication by power of 2 should have been optimized into a left shift instruction: $mulIns $amount") - if(amount in setOf(3,5,6,7,9,10,11,12,13,14,15,20,25,40)) - return " jsr math.mul_byte_$amount" - if(mulIns.opcode == Opcode.MUL_B && amount in setOf(-3,-5,-6,-7,-9,-10,-11,-12,-13,-14,-15,-20,-25,-40)) - return " jsr prog8_lib.neg_b | jsr math.mul_byte_${-amount}" - } - else if(mulIns.opcode == Opcode.MUL_UW) { - if(amount in setOf(0,1,2,4,8,16,32,64,128,256)) - printWarning("multiplication by power of 2 should have been optimized into a left shift instruction: $mulIns $amount") - if(amount in setOf(3,5,6,7,9,10,12,15,20,25,40)) - return " jsr math.mul_word_$amount" - } - else if(mulIns.opcode == Opcode.MUL_W) { - if(amount in setOf(0,1,2,4,8,16,32,64,128,256)) - printWarning("multiplication by power of 2 should have been optimized into a left shift instruction: $mulIns $amount") - if(amount in setOf(3,5,6,7,9,10,12,15,20,25,40)) - return " jsr math.mul_word_$amount" - if(amount in setOf(-3,-5,-6,-7,-9,-10,-12,-15,-20,-25,-40)) - return " jsr prog8_lib.neg_w | jsr math.mul_word_${-amount}" - } - - return null -} - -object Patterns { - internal val patterns = mutableListOf() - - init { - - // ----------- assignment to BYTE VARIABLE ---------------- - // var = (u)bytevalue -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.POP_VAR_BYTE)) { segment -> - when (segment[1].callLabel) { - "A", "X", "Y" -> - " ld${segment[1].callLabel!!.toLowerCase()} #${hexVal(segment[0])}" - else -> - " lda #${hexVal(segment[0])} | sta ${segment[1].callLabel}" - } -}) - // var = other var -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.POP_VAR_BYTE)) { segment -> - when (segment[1].callLabel) { - "A" -> - when (segment[0].callLabel) { - "A" -> null - "X" -> " txa" - "Y" -> " tya" - else -> " lda ${segment[0].callLabel}" - } - "X" -> - when (segment[0].callLabel) { - "A" -> " tax" - "X" -> null - "Y" -> " tya | tax" - else -> " ldx ${segment[0].callLabel}" - } - "Y" -> - when (segment[0].callLabel) { - "A" -> " tay" - "X" -> " txa | tay" - "Y" -> null - else -> " ldy ${segment[0].callLabel}" - } - else -> - when (segment[0].callLabel) { - "A" -> " sta ${segment[1].callLabel}" - "X" -> " stx ${segment[1].callLabel}" - "Y" -> " sty ${segment[1].callLabel}" - else -> " lda ${segment[0].callLabel} | sta ${segment[1].callLabel}" - } - } -}) - // var = mem (u)byte -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_B, Opcode.POP_VAR_BYTE), - listOf(Opcode.PUSH_MEM_UB, Opcode.POP_VAR_BYTE)) { segment -> - when (segment[1].callLabel) { - "A", "X", "Y" -> " ld${segment[1].callLabel!!.toLowerCase()} ${hexVal(segment[0])}" - else -> " lda ${hexVal(segment[0])} | sta ${segment[1].callLabel}" - } -}) - // var = (u)bytearray[index] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.POP_VAR_BYTE)) { segment -> - val index = intVal(segment[0]) - when (segment[2].callLabel) { - "A", "X", "Y" -> - " ld${segment[2].callLabel!!.toLowerCase()} ${segment[1].callLabel}+$index" - else -> - " lda ${segment[1].callLabel}+$index | sta ${segment[2].callLabel}" - } -}) - // var = (u)bytearray[indexvar] -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.POP_VAR_BYTE)) { segment -> - val loadByteA = loadAFromIndexedByVar(segment[0], segment[1]) - when (segment[2].callLabel) { - "A" -> " $loadByteA" - "X" -> " $loadByteA | tax" - "Y" -> " $loadByteA | tay" - else -> " $loadByteA | sta ${segment[2].callLabel}" - } -}) - // var = (u)bytearray[mem index var] -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_B, Opcode.READ_INDEXED_VAR_BYTE, Opcode.POP_VAR_BYTE), - listOf(Opcode.PUSH_MEM_UB, Opcode.READ_INDEXED_VAR_BYTE, Opcode.POP_VAR_BYTE)) { segment -> - val loadByteA = " ldy ${hexVal(segment[0])} | lda ${segment[1].callLabel},y" - when (segment[2].callLabel) { - "A" -> " $loadByteA" - "X" -> " $loadByteA | tax" - "Y" -> " $loadByteA | tay" - else -> " $loadByteA | sta ${segment[2].callLabel}" - } -}) - - - // ----------- assignment to BYTE MEMORY ---------------- - // mem = (u)byte value -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.POP_MEM_BYTE)) { segment -> - " lda #${hexVal(segment[0])} | sta ${hexVal(segment[1])}" -}) - // mem = (u)bytevar -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.POP_MEM_BYTE)) { segment -> - when (segment[0].callLabel) { - "A" -> " sta ${hexVal(segment[1])}" - "X" -> " stx ${hexVal(segment[1])}" - "Y" -> " sty ${hexVal(segment[1])}" - else -> " lda ${segment[0].callLabel} | sta ${hexVal(segment[1])}" - } -}) - // mem = mem (u)byte -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_B, Opcode.POP_MEM_BYTE), - listOf(Opcode.PUSH_MEM_UB, Opcode.POP_MEM_BYTE)) { segment -> - " lda ${hexVal(segment[0])} | sta ${hexVal(segment[1])}" -}) - // mem = (u)bytearray[index] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.POP_MEM_BYTE)) { segment -> - val address = hexVal(segment[2]) - val index = intVal(segment[0]) - " lda ${segment[1].callLabel}+$index | sta $address" -}) - // mem = (u)bytearray[indexvar] -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.POP_MEM_BYTE)) { segment -> - val loadByteA = loadAFromIndexedByVar(segment[0], segment[1]) - " $loadByteA | sta ${hexVal(segment[2])}" -}) - // mem = (u)bytearray[mem index var] -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_B, Opcode.READ_INDEXED_VAR_BYTE, Opcode.POP_MEM_BYTE), - listOf(Opcode.PUSH_MEM_UB, Opcode.READ_INDEXED_VAR_BYTE, Opcode.POP_MEM_BYTE)) { segment -> - """ - ldy ${hexVal(segment[0])} - lda ${segment[1].callLabel},y - sta ${hexVal(segment[2])} - """ -}) - - - // ----------- assignment to BYTE ARRAY ---------------- - // bytearray[index] = (u)byte value -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> - val index = intVal(segment[1]) - val value = hexVal(segment[0]) - " lda #$value | sta ${segment[2].callLabel}+$index" -}) - // bytearray[index] = (u)bytevar -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> - val index = intVal(segment[1]) - when (segment[0].callLabel) { - "A" -> " sta ${segment[2].callLabel}+$index" - "X" -> " stx ${segment[2].callLabel}+$index" - "Y" -> " sty ${segment[2].callLabel}+$index" - else -> " lda ${segment[0].callLabel} | sta ${segment[2].callLabel}+$index" - } -}) - // bytearray[index] = mem(u)byte -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_B, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE), - listOf(Opcode.PUSH_MEM_UB, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> - val index = intVal(segment[1]) - " lda ${hexVal(segment[0])} | sta ${segment[2].callLabel}+$index" -}) - - // bytearray[index var] = (u)byte value -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> - val storeA = storeAToIndexedByVar(segment[1], segment[2]) - " lda #${hexVal(segment[0])} | $storeA" -}) - // (u)bytearray[index var] = (u)bytevar -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> - val storeA = storeAToIndexedByVar(segment[1], segment[2]) - when (segment[0].callLabel) { - "A" -> " $storeA" - "X" -> " txa | $storeA" - "Y" -> " tya | $storeA" - else -> " lda ${segment[0].callLabel} | $storeA" - } -}) - // (u)bytearray[index var] = mem (u)byte -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_UB, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE), - listOf(Opcode.PUSH_MEM_B, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> - val storeA = storeAToIndexedByVar(segment[1], segment[2]) - " lda ${hexVal(segment[0])} | $storeA" -}) - - // bytearray[index mem] = (u)byte value -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> - """ - lda #${hexVal(segment[0])} - ldy ${hexVal(segment[1])} - sta ${segment[2].callLabel},y - """ -}) - // bytearray[index mem] = (u)byte var -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> - val loadY = " ldy ${hexVal(segment[1])}" - when (segment[0].callLabel) { - "A" -> " $loadY | sta ${segment[2].callLabel},y" - "X" -> " txa | $loadY | sta ${segment[2].callLabel},y" - "Y" -> " tya | $loadY | sta ${segment[2].callLabel},y" - else -> " lda ${segment[0].callLabel} | $loadY | sta ${segment[2].callLabel},y" - } -}) - // bytearray[index mem] = mem(u)byte -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_B, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_BYTE), - listOf(Opcode.PUSH_MEM_UB, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> - """ - ldy ${hexVal(segment[1])} - lda ${hexVal(segment[0])} - sta ${segment[2].callLabel},y - """ -}) - - // (u)bytearray2[index2] = (u)bytearray1[index1] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> - val index1 = intVal(segment[0]) - val index2 = intVal(segment[2]) - " lda ${segment[1].callLabel}+$index1 | sta ${segment[3].callLabel}+$index2" -}) - // (u)bytearray2[index2] = (u)bytearray[indexvar] -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> - val loadByteA = loadAFromIndexedByVar(segment[0], segment[1]) - val index2 = intVal(segment[2]) - " $loadByteA | sta ${segment[3].callLabel}+$index2" -}) - // (u)bytearray[index2] = (u)bytearray[mem ubyte] -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_B, Opcode.READ_INDEXED_VAR_BYTE, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE), - listOf(Opcode.PUSH_MEM_UB, Opcode.READ_INDEXED_VAR_BYTE, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> - val index2 = intVal(segment[2]) - """ - ldy ${hexVal(segment[0])} - lda ${segment[1].callLabel},y - sta ${segment[3].callLabel}+$index2 - """ -}) - - // (u)bytearray2[idxvar2] = (u)bytearray1[index1] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> - val storeA = storeAToIndexedByVar(segment[2], segment[3]) - val index1 = intVal(segment[0]) - " lda ${segment[1].callLabel}+$index1 | $storeA" -}) - // (u)bytearray2[idxvar2] = (u)bytearray1[idxvar] -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> - val loadA = loadAFromIndexedByVar(segment[0], segment[1]) - val storeA = storeAToIndexedByVar(segment[2], segment[3]) - " $loadA | $storeA" -}) - // (u)bytearray2[idxvar2] = (u)bytearray1[mem ubyte] -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_B, Opcode.READ_INDEXED_VAR_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE), - listOf(Opcode.PUSH_MEM_UB, Opcode.READ_INDEXED_VAR_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> - val storeA = storeAToIndexedByVar(segment[2], segment[3]) - " ldy ${hexVal(segment[0])} | lda ${segment[1].callLabel},y | $storeA" -}) - - // (u)bytearray2[index mem] = (u)bytearray[index] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> - val index1 = intVal(segment[0]) - """ - lda ${segment[1].callLabel}+$index1 - ldy ${hexVal(segment[2])} - sta ${segment[3].callLabel},y - """ -}) - - - - // ----------- assignment to WORD VARIABLE ---------------- - // var = wordvalue -patterns.add(AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.POP_VAR_WORD)) { segment -> - val number = hexVal(segment[0]) - """ - lda #<$number - ldy #>$number - sta ${segment[1].callLabel} - sty ${segment[1].callLabel}+1 - """ -}) - // var = ubytevar -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.POP_VAR_WORD)) { segment -> - when (segment[0].callLabel) { - "A" -> " sta ${segment[2].callLabel} | lda #0 | sta ${segment[2].callLabel}+1" - "X" -> " stx ${segment[2].callLabel} | lda #0 | sta ${segment[2].callLabel}+1" - "Y" -> " sty ${segment[2].callLabel} | lda #0 | sta ${segment[2].callLabel}+1" - else -> " lda ${segment[0].callLabel} | sta ${segment[2].callLabel} | lda #0 | sta ${segment[2].callLabel}+1" - } -}) - // var = other var -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.POP_VAR_WORD)) { segment -> - """ - lda ${segment[0].callLabel} - ldy ${segment[0].callLabel}+1 - sta ${segment[1].callLabel} - sty ${segment[1].callLabel}+1 - """ -}) - // var = address-of other var -patterns.add(AsmPattern(listOf(Opcode.PUSH_ADDR_HEAPVAR, Opcode.POP_VAR_WORD)) { segment -> - """ - lda #<${segment[0].callLabel} - ldy #>${segment[0].callLabel} - sta ${segment[1].callLabel} - sty ${segment[1].callLabel}+1 - """ -}) - // var = mem ubyte -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.CAST_UB_TO_UW, Opcode.POP_VAR_WORD)) { segment -> - " lda ${hexVal(segment[0])} | sta ${segment[2].callLabel} | lda #0 | sta ${segment[2].callLabel}+1" -}) - // var = mem (u)word -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_W, Opcode.POP_VAR_WORD), - listOf(Opcode.PUSH_MEM_UW, Opcode.POP_VAR_WORD)) { segment -> - """ - lda ${hexVal(segment[0])} - sta ${segment[1].callLabel} - lda ${hexValPlusOne(segment[0])} - sta ${segment[1].callLabel}+1 - """ -}) - // var = ubytearray[index_byte] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.POP_VAR_WORD)) { segment -> - val index = hexVal(segment[0]) - " lda ${segment[1].callLabel}+$index | sta ${segment[3].callLabel} | lda #0 | sta ${segment[3].callLabel}+1" -}) - // var = ubytearray[index var] -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.POP_VAR_WORD)) { segment -> - val loadA = loadAFromIndexedByVar(segment[0], segment[1]) - " $loadA | sta ${segment[3].callLabel} | lda #0 | sta ${segment[3].callLabel}+1" -}) - // var = ubytearray[index mem] -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_B, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.POP_VAR_WORD), - listOf(Opcode.PUSH_MEM_UB, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.POP_VAR_WORD)) { segment -> - """ - lda ${hexVal(segment[0])} - sta ${segment[3].callLabel} - lda #0 - sta ${segment[3].callLabel}+1 - """ -}) - // var = (u)wordarray[index_byte] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.POP_VAR_WORD)) { segment -> - val index = intVal(segment[0]) * 2 - " lda ${segment[1].callLabel}+$index | sta ${segment[2].callLabel} | lda ${segment[1].callLabel}+${index + 1} | sta ${segment[2].callLabel}+1" -}) - // var = (u)wordarray[index var] -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.POP_VAR_WORD)) { segment -> - val loadAY = loadAYFromWordIndexedByVar(segment[0], segment[1]) - """ - $loadAY - sta ${segment[2].callLabel} - sty ${segment[2].callLabel}+1 - """ -}) - // var = (u)wordarray[index mem] -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_B, Opcode.READ_INDEXED_VAR_WORD, Opcode.POP_VAR_WORD), - listOf(Opcode.PUSH_MEM_UB, Opcode.READ_INDEXED_VAR_WORD, Opcode.POP_VAR_WORD)) { segment -> - """ - lda ${hexVal(segment[0])} - asl a - tay - lda ${segment[1].callLabel},y - sta ${segment[2].callLabel} - lda ${segment[1].callLabel}+1,y - sta ${segment[2].callLabel}+1 - """ -}) - // mem = (u)word value -patterns.add(AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.POP_MEM_WORD)) { segment -> - """ - lda #<${hexVal(segment[0])} - ldy #>${hexVal(segment[0])} - sta ${hexVal(segment[1])} - sty ${hexValPlusOne(segment[1])} - """ -}) - // mem uword = ubyte var -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.POP_MEM_WORD)) { segment -> - when (segment[0].callLabel) { - "A" -> " sta ${hexVal(segment[2])} | lda #0 | sta ${hexValPlusOne(segment[2])}" - "X" -> " stx ${hexVal(segment[2])} | lda #0 | sta ${hexValPlusOne(segment[2])}" - "Y" -> " sty ${hexVal(segment[2])} | lda #0 | sta ${hexValPlusOne(segment[2])}" - else -> " lda ${segment[0].callLabel} || sta ${hexVal(segment[2])} | lda #0 | sta ${hexValPlusOne(segment[2])}" - } -}) - // mem uword = mem ubyte -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.CAST_UB_TO_UW, Opcode.POP_MEM_WORD)) { segment -> - """ - lda ${hexVal(segment[0])} - sta ${hexVal(segment[2])} - lda #0 - sta ${hexValPlusOne(segment[2])} - """ -}) - // mem uword = uword var -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.POP_MEM_WORD)) { segment -> - " lda ${segment[0].callLabel} | ldy ${segment[0].callLabel}+1 | sta ${hexVal(segment[1])} | sty ${hexValPlusOne(segment[1])}" -}) - // mem uword = address-of var -patterns.add(AsmPattern(listOf(Opcode.PUSH_ADDR_HEAPVAR, Opcode.POP_MEM_WORD)) { segment -> - " lda #<${segment[0].callLabel} | ldy #>${segment[0].callLabel} | sta ${hexVal(segment[1])} | sty ${hexValPlusOne(segment[1])}" -}) - // mem (u)word = mem (u)word -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_UW, Opcode.POP_MEM_WORD), - listOf(Opcode.PUSH_MEM_W, Opcode.POP_MEM_WORD)) { segment -> - """ - lda ${hexVal(segment[0])} - ldy ${hexValPlusOne(segment[0])} - sta ${hexVal(segment[1])} - sty ${hexValPlusOne(segment[1])} - """ -}) - // mem uword = ubytearray[index] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.POP_MEM_WORD)) { segment -> - val index = intVal(segment[0]) - """ - lda ${segment[1].callLabel}+$index - ldy #0 - sta ${hexVal(segment[3])} - sty ${hexValPlusOne(segment[3])} - """ -}) - // mem uword = bytearray[index] (sign extended) -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.POP_MEM_WORD)) { segment -> - val index = intVal(segment[0]) - """ - lda ${segment[1].callLabel}+$index - sta ${hexVal(segment[3])} - ${signExtendA(hexValPlusOne(segment[3]))} - """ -}) - // mem uword = bytearray[index var] (sign extended) -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.POP_MEM_WORD)) { segment -> - val loadA = loadAFromIndexedByVar(segment[0], segment[1]) - """ - $loadA - sta ${hexVal(segment[3])} - ${signExtendA(hexValPlusOne(segment[3]))} - """ -}) - // mem uword = bytearray[mem (u)byte] (sign extended) -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_B, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.POP_MEM_WORD), - listOf(Opcode.PUSH_MEM_UB, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.POP_MEM_WORD)) { segment -> - """ - lda ${hexVal(segment[0])} - sta ${hexVal(segment[3])} - ${signExtendA(hexValPlusOne(segment[3]))} - """ -}) - // mem uword = ubytearray[index var] -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.POP_MEM_WORD)) { segment -> - val loadA = loadAFromIndexedByVar(segment[0], segment[1]) - " $loadA | sta ${hexVal(segment[3])} | lda #0 | sta ${hexValPlusOne(segment[3])}" -}) - // mem uword = ubytearray[mem (u)bute] -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_B, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.POP_MEM_WORD), - listOf(Opcode.PUSH_MEM_UB, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.POP_MEM_WORD)) { segment -> - """ - lda ${hexVal(segment[0])} - sta ${hexVal(segment[3])} - lda #0 - sta ${hexValPlusOne(segment[3])} - """ -}) - // mem uword = (u)wordarray[indexvalue] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.POP_MEM_WORD)) { segment -> - val index = intVal(segment[0]) * 2 - """ - lda ${segment[1].callLabel}+$index - ldy ${segment[1].callLabel}+1+$index - sta ${hexVal(segment[2])} - sty ${hexValPlusOne(segment[2])} - """ -}) - // mem uword = (u)wordarray[index var] -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.POP_MEM_WORD)) { segment -> - val loadAY = loadAYFromWordIndexedByVar(segment[0], segment[1]) - """ - $loadAY - sta ${hexVal(segment[2])} - sty ${hexValPlusOne(segment[2])} - """ -}) - // mem uword = (u)wordarray[mem index] -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_B, Opcode.READ_INDEXED_VAR_WORD, Opcode.POP_MEM_WORD), - listOf(Opcode.PUSH_MEM_UB, Opcode.READ_INDEXED_VAR_WORD, Opcode.POP_MEM_WORD)) { segment -> - """ - lda ${hexVal(segment[0])} - asl a - tay - lda ${segment[1].callLabel},y - sta ${hexVal(segment[2])} - lda ${segment[1].callLabel}+1,y - sta ${hexValPlusOne(segment[2])} - """ -}) - // word var = bytevar (sign extended) -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.POP_VAR_WORD)) { segment -> - """ - lda ${segment[0].callLabel} - sta ${segment[2].callLabel} - ${signExtendA(segment[2].callLabel + "+1")} - """ -}) - // mem word = bytevar (sign extended) -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.POP_MEM_WORD)) { segment -> - """ - lda ${segment[0].callLabel} - sta ${hexVal(segment[2])} - ${signExtendA(hexValPlusOne(segment[2]))} - """ -}) - // mem word = mem byte (sign extended) -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.CAST_B_TO_W, Opcode.POP_MEM_WORD)) { segment -> - """ - lda ${hexVal(segment[0])} - sta ${hexVal(segment[2])} - ${signExtendA(hexValPlusOne(segment[2]))} - """ -}) - // var = membyte (sign extended) -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.CAST_B_TO_W, Opcode.POP_VAR_WORD)) { segment -> - """ - lda ${hexVal(segment[0])} - sta ${segment[2].callLabel} - ${signExtendA(segment[2].callLabel + "+1")} - """ -}) - // var = bytearray[index_byte] (sign extended) -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.POP_VAR_WORD)) { segment -> - val index = hexVal(segment[0]) - """ - lda ${segment[1].callLabel}+$index - sta ${segment[3].callLabel} - ${signExtendA(segment[3].callLabel + "+1")} - """ -}) - // var = bytearray[index var] (sign extended) -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.POP_VAR_WORD)) { segment -> - val loadByteA = loadAFromIndexedByVar(segment[0], segment[1]) - """ - $loadByteA - sta ${segment[3].callLabel} - ${signExtendA(segment[3].callLabel + "+1")} - """ -}) - // var = bytearray[mem (u)byte] (sign extended) -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_B, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.POP_VAR_WORD), - listOf(Opcode.PUSH_MEM_UB, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.POP_VAR_WORD)) { segment -> - """ - lda ${hexVal(segment[0])} - sta ${segment[3].callLabel} - ${signExtendA(segment[3].callLabel + "+1")} - """ -}) - - // ----------- assignment to UWORD ARRAY ---------------- - // uwordarray[index] = (u)word value -patterns.add(AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val index = intVal(segment[1]) * 2 - val value = hexVal(segment[0]) - """ - lda #<$value - ldy #>$value - sta ${segment[2].callLabel}+$index - sty ${segment[2].callLabel}+${index + 1} - """ -}) - // uwordarray[index mem] = (u)word value -patterns.add(AsmPattern( - listOf(Opcode.PUSH_WORD, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD), - listOf(Opcode.PUSH_WORD, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val value = hexVal(segment[0]) - """ - lda ${hexVal(segment[1])} - asl a - tay - lda #<$value - sta ${segment[2].callLabel},y - lda #>$value - sta ${segment[2].callLabel}+1,y - """ -}) - // uwordarray[index mem] = mem (u)word -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_UW, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD), - listOf(Opcode.PUSH_MEM_UW, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - """ - lda ${hexVal(segment[1])} - asl a - tay - lda ${hexVal(segment[0])} - sta ${segment[2].callLabel},y - lda ${hexValPlusOne(segment[0])} - sta ${segment[2].callLabel}+1,y - """ -}) - // uwordarray[index mem] = (u)word var -patterns.add(AsmPattern( - listOf(Opcode.PUSH_VAR_WORD, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD), - listOf(Opcode.PUSH_VAR_WORD, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - """ - lda ${hexVal(segment[1])} - asl a - tay - lda ${segment[0].callLabel} - sta ${segment[2].callLabel},y - lda ${segment[0].callLabel}+1 - sta ${segment[2].callLabel}+1,y - """ -}) - // uwordarray[index mem] = address-of var -patterns.add(AsmPattern( - listOf(Opcode.PUSH_ADDR_HEAPVAR, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD), - listOf(Opcode.PUSH_ADDR_HEAPVAR, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - """ - lda ${hexVal(segment[1])} - asl a - tay - lda #<${segment[0].callLabel} - sta ${segment[2].callLabel},y - lda #>${segment[0].callLabel} - sta ${segment[2].callLabel}+1,y - """ -}) - // uwordarray[index] = ubytevar -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val index = intVal(segment[2]) * 2 - when (segment[0].callLabel) { - "A" -> " sta ${segment[3].callLabel}+$index | lda #0 | sta ${segment[3].callLabel}+${index + 1}" - "X" -> " stx ${segment[3].callLabel}+$index | lda #0 | sta ${segment[3].callLabel}+${index + 1}" - "Y" -> " sty ${segment[3].callLabel}+$index | lda #0 | sta ${segment[3].callLabel}+${index + 1}" - else -> " lda ${segment[0].callLabel} | sta ${segment[3].callLabel}+$index | lda #0 | sta ${segment[3].callLabel}+${index + 1}" - } -}) - // wordarray[index] = bytevar (extend sign) -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val index = intVal(segment[2]) * 2 - when (segment[0].callLabel) { - "A" -> - """ - sta ${segment[3].callLabel}+$index - ${signExtendA(segment[3].callLabel + "+${index + 1}")} - """ - "X" -> - """ - txa - sta ${segment[3].callLabel}+$index - ${signExtendA(segment[3].callLabel + "+${index + 1}")} - """ - "Y" -> - """ - tya - sta ${segment[3].callLabel}+$index - ${signExtendA(segment[3].callLabel + "+${index + 1}")} - """ - else -> - """ - lda ${segment[0].callLabel} - sta ${segment[3].callLabel}+$index - ${signExtendA(segment[3].callLabel + "+${index + 1}")} - """ - } -}) - // wordarray[index mem] = bytevar (extend sign) -patterns.add(AsmPattern( - listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD), - listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - when (segment[0].callLabel) { - "A" -> - """ - pha - sty ${C64Zeropage.SCRATCH_B1} - lda ${hexVal(segment[2])} - asl a - tay - pla - sta ${segment[3].callLabel},y - ${signExtendA(segment[3].callLabel + "+1,y")} - """ - "X" -> - """ - stx ${C64Zeropage.SCRATCH_B1} - lda ${hexVal(segment[2])} - asl a - tay - lda ${C64Zeropage.SCRATCH_B1} - sta ${segment[3].callLabel},y - ${signExtendA(segment[3].callLabel + "+1,y")} - """ - "Y" -> - """ - sty ${C64Zeropage.SCRATCH_B1} - lda ${hexVal(segment[2])} - asl a - tay - lda ${C64Zeropage.SCRATCH_B1} - sta ${segment[3].callLabel},y - ${signExtendA(segment[3].callLabel + "+1,y")} - """ - else -> - """ - lda ${hexVal(segment[2])} - asl a - tay - lda ${segment[0].callLabel} - sta ${segment[3].callLabel},y - ${signExtendA(segment[3].callLabel + "+1,y")} - """ - } -}) - // wordarray[memory (u)byte] = ubyte mem -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_B, Opcode.CAST_B_TO_W, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD), - listOf(Opcode.PUSH_MEM_B, Opcode.CAST_B_TO_W, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - """ - lda ${hexVal(segment[2])} - asl a - tay - lda ${hexVal(segment[0])} - sta ${segment[3].callLabel},y - ${signExtendA(segment[3].callLabel + "+1,y")} - """ -}) - // wordarray[index] = mem byte (extend sign) -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.CAST_B_TO_W, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val index = intVal(segment[2]) * 2 - """ - lda ${hexVal(segment[0])} - sta ${segment[3].callLabel}+$index - ${signExtendA(segment[3].callLabel + "+${index + 1}")} - """ -}) - // wordarray2[index2] = bytearray1[index1] (extend sign) -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val index1 = intVal(segment[0]) - val index2 = segment[3].arg!!.integerValue() * 2 - """ - lda ${segment[1].callLabel}+$index1 - sta ${segment[4].callLabel}+$index2 - ${signExtendA(segment[4].callLabel + "+${index2 + 1}")} - """ -}) - // wordarray2[mem (u)byte] = bytearray1[index1] (extend sign) -patterns.add(AsmPattern( - listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD), - listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val index1 = intVal(segment[0]) - """ - lda ${hexVal(segment[3])} - asl a - tay - lda ${segment[1].callLabel}+$index1 - sta ${segment[4].callLabel},y - ${signExtendA(segment[4].callLabel + "+1,y")} - """ -}) - - // wordarray[indexvar] = byte var (sign extended) -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val loadValueOnStack = when (segment[0].callLabel) { - "A" -> " pha" - "X" -> " txa | pha" - "Y" -> " tya | pha" - else -> " lda ${segment[0].callLabel} | pha" - } - val loadIndexY = when (segment[2].callLabel) { - "A" -> " asl a | tay" - "X" -> " txa | asl a | tay" - "Y" -> " tya | asl a | tay" - else -> " lda ${segment[2].callLabel} | asl a | tay" - } - """ - $loadValueOnStack - $loadIndexY - pla - sta ${segment[3].callLabel},y - ${signExtendA(segment[3].callLabel + "+1,y")} - """ -}) - // wordarray[indexvar] = byte mem (sign extended) -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.CAST_B_TO_W, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val loadIndexY = when (segment[2].callLabel) { - "A" -> " asl a | tay" - "X" -> " txa | asl a | tay" - "Y" -> " tya | asl a | tay" - else -> " lda ${segment[2].callLabel} | asl a | tay" - } - """ - $loadIndexY - lda ${hexVal(segment[0])} - sta ${segment[3].callLabel},y - ${signExtendA(segment[3].callLabel + "+1,y")} - """ -}) - // wordarray[index] = mem word -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_W, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val index = intVal(segment[1]) * 2 - """ - lda ${hexVal(segment[0])} - sta ${segment[2].callLabel}+$index - lda ${hexValPlusOne(segment[0])} - sta ${segment[2].callLabel}+$index+1 - """ -}) - // wordarray2[indexvar] = bytearay[index] (sign extended) -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_W, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val index = intVal(segment[0]) - val loadIndex2Y = when (segment[3].callLabel) { - "A" -> " asl a | tay" - "X" -> " txa | asl a | tay" - "Y" -> " tya | asl a | tay" - else -> " lda ${segment[3].callLabel} | asl a | tay" - } - """ - $loadIndex2Y - lda ${segment[1].callLabel}+$index - sta ${segment[4].callLabel},y - lda ${segment[1].callLabel}+$index+1 - sta ${segment[4].callLabel}+1,y - """ -}) - // uwordarray[mem (u)byte] = mem word -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_W, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD), - listOf(Opcode.PUSH_MEM_W, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - """ - lda ${hexVal(segment[1])} - asl a - tay - lda ${hexVal(segment[0])} - sta ${segment[2].callLabel},y - lda ${hexValPlusOne(segment[0])} - sta ${segment[2].callLabel}+1,y - """ -}) - - // uwordarray[index mem] = ubytevar -patterns.add(AsmPattern( - listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD), - listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - when (segment[0].callLabel) { - "A" -> - """ - pha - lda ${hexVal(segment[2])} - asl a - tay - pla - sta ${segment[3].callLabel},y - lda #0 - sta ${segment[3].callLabel}+1,y - """ - "X" -> - """ - lda ${hexVal(segment[2])} - asl a - tay - txa - sta ${segment[3].callLabel},y - lda #0 - sta ${segment[3].callLabel}+1,y - """ - "Y" -> - """ - lda ${hexVal(segment[2])} - asl a - stx ${C64Zeropage.SCRATCH_B1} - tax - tya - sta ${segment[3].callLabel},x - lda #0 - sta ${segment[3].callLabel}+1,x - ldx ${C64Zeropage.SCRATCH_B1} - """ - else -> - """ - lda ${hexVal(segment[2])} - asl a - tay - lda ${segment[0].callLabel} - sta ${segment[3].callLabel},y - lda #0 - sta ${segment[3].callLabel}+1,y - """ - } -}) - // uwordarray[index mem] = ubyte mem -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_UB, Opcode.CAST_UB_TO_UW, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD), - listOf(Opcode.PUSH_MEM_UB, Opcode.CAST_UB_TO_UW, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - """ - lda ${hexVal(segment[2])} - asl a - tay - lda ${hexVal(segment[0])} - sta ${segment[3].callLabel},y - lda #0 - sta ${segment[3].callLabel}+1,y - """ -}) - // uwordarray[index] = mem ubyte -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.CAST_UB_TO_UW, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val index = intVal(segment[2]) * 2 - """ - lda ${hexVal(segment[0])} - sta ${segment[3].callLabel}+$index - lda #0 - sta ${segment[3].callLabel}+${index + 1} - """ -}) - // uwordarray[index] = (u)wordvar -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val index = intVal(segment[1]) * 2 - " lda ${segment[0].callLabel} | sta ${segment[2].callLabel}+$index | lda ${segment[0].callLabel}+1 | sta ${segment[2].callLabel}+${index + 1}" -}) - // uwordarray[index] = address-of var -patterns.add(AsmPattern(listOf(Opcode.PUSH_ADDR_HEAPVAR, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val index = intVal(segment[1]) * 2 - " lda #<${segment[0].callLabel} | ldy #>${segment[0].callLabel} | sta ${segment[2].callLabel}+$index | sty ${segment[2].callLabel}+${index + 1}" -}) - // uwordarray[index] = mem uword -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_UW, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val index = intVal(segment[1]) * 2 - """ - lda ${hexVal(segment[0])} - ldy ${hexValPlusOne(segment[0])} - sta ${segment[2].callLabel}+$index - sty ${segment[2].callLabel}+${index + 1} - """ -}) - // uwordarray2[index2] = ubytearray1[index1] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val index1 = intVal(segment[0]) - val index2 = segment[3].arg!!.integerValue() * 2 - """ - lda ${segment[1].callLabel}+$index1 - sta ${segment[4].callLabel}+$index2 - lda #0 - sta ${segment[4].callLabel}+${index2 + 1} - """ -}) - // uwordarray2[index2] = (u)wordarray1[index1] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val index1 = intVal(segment[0]) - val index2 = intVal(segment[2]) * 2 - """ - lda ${segment[1].callLabel}+$index1 - ldy ${segment[1].callLabel}+${index1 + 1} - sta ${segment[3].callLabel}+$index2 - sta ${segment[3].callLabel}+${index2 + 1} - """ -}) - // uwordarray[indexvar] = (u)word value -patterns.add(AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val value = hexVal(segment[0]) - val loadIndexY = when (segment[1].callLabel) { - "A" -> " asl a | tay" - "X" -> " txa | asl a | tay" - "Y" -> " tya | asl a | tay" - else -> " lda ${segment[1].callLabel} | asl a | tay" - } - " $loadIndexY | lda #<$value | sta ${segment[2].callLabel},y | lda #>$value | sta ${segment[2].callLabel}+1,y" -}) - // uwordarray[indexvar] = ubyte var -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val loadValueOnStack = when (segment[0].callLabel) { - "A" -> " pha" - "X" -> " txa | pha" - "Y" -> " tya | pha" - else -> " lda ${segment[0].callLabel} | pha" - } - val loadIndexY = when (segment[2].callLabel) { - "A" -> " asl a | tay" - "X" -> " txa | asl a | tay" - "Y" -> " tya | asl a | tay" - else -> " lda ${segment[2].callLabel} | asl a | tay" - } - " $loadValueOnStack | $loadIndexY | pla | sta ${segment[3].callLabel},y | lda #0 | sta ${segment[3].callLabel}+1,y" -}) - // uwordarray[indexvar] = uword var -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val loadIndexY = when (segment[1].callLabel) { - "A" -> " asl a | tay" - "X" -> " txa | asl a | tay" - "Y" -> " tya | asl a | tay" - else -> " lda ${segment[1].callLabel} | asl a | tay" - } - " $loadIndexY | lda ${segment[0].callLabel} | sta ${segment[2].callLabel},y | lda ${segment[0].callLabel}+1 | sta ${segment[2].callLabel}+1,y" -}) - // uwordarray[indexvar] = address-of var -patterns.add(AsmPattern(listOf(Opcode.PUSH_ADDR_HEAPVAR, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val loadIndexY = when (segment[1].callLabel) { - "A" -> " asl a | tay" - "X" -> " txa | asl a | tay" - "Y" -> " tya | asl a | tay" - else -> " lda ${segment[1].callLabel} | asl a | tay" - } - " $loadIndexY | lda #<${segment[0].callLabel} | sta ${segment[2].callLabel},y | lda #>${segment[0].callLabel} | sta ${segment[2].callLabel}+1,y" -}) - // uwordarray[indexvar] = mem ubyte -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.CAST_UB_TO_UW, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val loadIndexY = when (segment[2].callLabel) { - "A" -> " asl a | tay" - "X" -> " txa | asl a | tay" - "Y" -> " tya | asl a | tay" - else -> " lda ${segment[2].callLabel} | asl a | tay" - } - " $loadIndexY | lda ${hexVal(segment[0])} | sta ${segment[3].callLabel},y | lda #0 | sta ${segment[3].callLabel}+1,y" -}) - // uwordarray[indexvar] = mem (u)word -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_W, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD), - listOf(Opcode.PUSH_MEM_UW, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val loadIndexY = when (segment[1].callLabel) { - "A" -> " asl a | tay" - "X" -> " txa | asl a | tay" - "Y" -> " tya | asl a | tay" - else -> " lda ${segment[1].callLabel} | asl a | tay" - } - " $loadIndexY | lda ${hexVal(segment[0])} | sta ${segment[2].callLabel},y | lda ${hexValPlusOne(segment[0])} | sta ${segment[2].callLabel}+1,y" -}) - // uwordarray2[indexvar] = ubytearay[index] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val index = intVal(segment[0]) - val loadIndex2Y = when (segment[3].callLabel) { - "A" -> " asl a | tay" - "X" -> " txa | asl a | tay" - "Y" -> " tya | asl a | tay" - else -> " lda ${segment[3].callLabel} | asl a | tay" - } - " $loadIndex2Y | lda ${segment[1].callLabel}+$index | sta ${segment[4].callLabel},y | lda #0 | sta ${segment[4].callLabel}+1,y" -}) - // uwordarray2[indexvar] = uwordarray[index] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val index = intVal(segment[0]) * 2 - val loadIndex2Y = when (segment[2].callLabel) { - "A" -> " asl a | tay" - "X" -> " txa | asl a | tay" - "Y" -> " tya | asl a | tay" - else -> " lda ${segment[2].callLabel} | asl a | tay" - } - " $loadIndex2Y | lda ${segment[1].callLabel}+$index | sta ${segment[3].callLabel},y | lda ${segment[1].callLabel}+${index + 1} | sta ${segment[3].callLabel}+1,y" -}) - // uwordarray2[index mem] = ubytearray1[index1] -patterns.add(AsmPattern( - listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD), - listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_UW, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val index1 = intVal(segment[0]) - """ - lda ${hexVal(segment[3])} - asl a - tay - lda ${segment[1].callLabel}+$index1 - sta ${segment[4].callLabel},y - lda #0 - sta ${segment[4].callLabel}+1,y - """ -}) - // uwordarray2[index mem] = uwordarray1[index1] -patterns.add(AsmPattern( - listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD), - listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val index1 = intVal(segment[0]) - """ - lda ${hexVal(segment[2])} - asl a - tay - lda ${segment[1].callLabel}+$index1 - sta ${segment[3].callLabel},y - lda ${segment[1].callLabel}+${index1 + 1} - sta ${segment[3].callLabel}+1,y - """ -}) - - - // ----------- assignment to FLOAT VARIABLE ---------------- - // floatvar = ubytevar -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_UB_TO_F, Opcode.POP_VAR_FLOAT)) { segment -> - val loadByteA = when (segment[0].callLabel) { - "A" -> "" - "X" -> "txa" - "Y" -> "tya" - else -> "lda ${segment[0].callLabel}" - } - """ - $loadByteA - sta ${C64Zeropage.SCRATCH_B1} - lda #<${segment[2].callLabel} - ldy #>${segment[2].callLabel} - jsr c64flt.ub2float - """ -}) - // floatvar = uwordvar -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.CAST_UW_TO_F, Opcode.POP_VAR_FLOAT)) { segment -> - """ - lda ${segment[0].callLabel} - sta ${C64Zeropage.SCRATCH_W1} - lda ${segment[0].callLabel}+1 - sta ${C64Zeropage.SCRATCH_W1 + 1} - lda #<${segment[2].callLabel} - ldy #>${segment[2].callLabel} - jsr c64flt.uw2float - """ -}) - // floatvar = bytevar -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_B_TO_F, Opcode.POP_VAR_FLOAT)) { segment -> - val loadByteA = when (segment[0].callLabel) { - "A" -> "" - "X" -> "txa" - "Y" -> "tya" - else -> "lda ${segment[0].callLabel}" - } - """ - $loadByteA - sta ${C64Zeropage.SCRATCH_B1} - lda #<${segment[2].callLabel} - ldy #>${segment[2].callLabel} - jsr c64flt.b2float - """ -}) - // floatvar = wordvar -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.CAST_W_TO_F, Opcode.POP_VAR_FLOAT)) { segment -> - """ - lda ${segment[0].callLabel} - sta ${C64Zeropage.SCRATCH_W1} - lda ${segment[0].callLabel}+1 - sta ${C64Zeropage.SCRATCH_W1 + 1} - lda #<${segment[2].callLabel} - ldy #>${segment[2].callLabel} - jsr c64flt.w2float - """ -}) - // floatvar = float value -patterns.add(AsmPattern(listOf(Opcode.PUSH_FLOAT, Opcode.POP_VAR_FLOAT)) { segment -> - val floatConst = getFloatConst(segment[0].arg!!) - """ - lda #<$floatConst - ldy #>$floatConst - sta ${C64Zeropage.SCRATCH_W1} - sty ${C64Zeropage.SCRATCH_W1 + 1} - lda #<${segment[1].callLabel} - ldy #>${segment[1].callLabel} - jsr c64flt.copy_float - """ -}) - // floatvar = float var -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_FLOAT, Opcode.POP_VAR_FLOAT)) { segment -> - """ - lda #<${segment[0].callLabel} - ldy #>${segment[0].callLabel} - sta ${C64Zeropage.SCRATCH_W1} - sty ${C64Zeropage.SCRATCH_W1 + 1} - lda #<${segment[1].callLabel} - ldy #>${segment[1].callLabel} - jsr c64flt.copy_float - """ -}) - // floatvar = mem float -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_FLOAT, Opcode.POP_VAR_FLOAT)) { segment -> - """ - lda #<${hexVal(segment[0])} - ldy #>${hexVal(segment[0])} - sta ${C64Zeropage.SCRATCH_W1} - sty ${C64Zeropage.SCRATCH_W1 + 1} - lda #<${segment[1].callLabel} - ldy #>${segment[1].callLabel} - jsr c64flt.copy_float - """ -}) - // floatvar = mem byte -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.CAST_B_TO_F, Opcode.POP_VAR_FLOAT)) { segment -> - """ - lda ${hexVal(segment[0])} - sta ${C64Zeropage.SCRATCH_B1} - lda #<${segment[2].callLabel} - ldy #>${segment[2].callLabel} - jsr c64flt.b2float - """ -}) - // floatvar = mem ubyte -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.CAST_UB_TO_F, Opcode.POP_VAR_FLOAT)) { segment -> - """ - lda ${hexVal(segment[0])} - sta ${C64Zeropage.SCRATCH_B1} - lda #<${segment[2].callLabel} - ldy #>${segment[2].callLabel} - jsr c64flt.ub2float - """ -}) - // floatvar = mem word -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_W, Opcode.CAST_W_TO_F, Opcode.POP_VAR_FLOAT)) { segment -> - """ - lda ${hexVal(segment[0])} - sta ${C64Zeropage.SCRATCH_W1} - lda ${hexValPlusOne(segment[0])} - sta ${C64Zeropage.SCRATCH_W1 + 1} - lda #<${segment[2].callLabel} - ldy #>${segment[2].callLabel} - jsr c64flt.w2float - """ -}) - // floatvar = mem uword -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_UW, Opcode.CAST_UW_TO_F, Opcode.POP_VAR_FLOAT)) { segment -> - """ - lda ${hexVal(segment[0])} - sta ${C64Zeropage.SCRATCH_W1} - lda ${hexValPlusOne(segment[0])} - sta ${C64Zeropage.SCRATCH_W1 + 1} - lda #<${segment[2].callLabel} - ldy #>${segment[2].callLabel} - jsr c64flt.uw2float - """ -}) - - // floatvar = bytearray[index] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_F, Opcode.POP_VAR_FLOAT)) { segment -> - val index = intVal(segment[0]) - """ - lda ${segment[1].callLabel}+$index - sta ${C64Zeropage.SCRATCH_B1} - lda #<${segment[3].callLabel} - ldy #>${segment[3].callLabel} - jsr c64flt.b2float - """ -}) - // floatvar = ubytearray[index] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_F, Opcode.POP_VAR_FLOAT)) { segment -> - val index = intVal(segment[0]) - """ - lda ${segment[1].callLabel}+$index - sta ${C64Zeropage.SCRATCH_B1} - lda #<${segment[3].callLabel} - ldy #>${segment[3].callLabel} - jsr c64flt.ub2float - """ -}) - // floatvar = wordarray[index] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.CAST_W_TO_F, Opcode.POP_VAR_FLOAT)) { segment -> - val index = intVal(segment[0]) * 2 - """ - lda ${segment[1].callLabel}+$index - ldy ${segment[1].callLabel}+${index + 1} - sta ${C64Zeropage.SCRATCH_W1} - sty ${C64Zeropage.SCRATCH_W1 + 1} - lda #<${segment[3].callLabel} - ldy #>${segment[3].callLabel} - jsr c64flt.w2float - """ -}) - // floatvar = uwordarray[index] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.CAST_UW_TO_F, Opcode.POP_VAR_FLOAT)) { segment -> - val index = intVal(segment[0]) * 2 - """ - lda ${segment[1].callLabel}+$index - ldy ${segment[1].callLabel}+${index + 1} - sta ${C64Zeropage.SCRATCH_W1} - sty ${C64Zeropage.SCRATCH_W1 + 1} - lda #<${segment[3].callLabel} - ldy #>${segment[3].callLabel} - jsr c64flt.uw2float - """ -}) - // floatvar = floatarray[index] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_FLOAT, Opcode.POP_VAR_FLOAT)) { segment -> - val index = intVal(segment[0]) * MachineDefinition.Mflpt5.MemorySize - """ - lda #<${segment[1].callLabel}+$index - ldy #>${segment[1].callLabel}+$index - sta ${C64Zeropage.SCRATCH_W1} - sty ${C64Zeropage.SCRATCH_W1 + 1} - lda #<${segment[2].callLabel} - ldy #>${segment[2].callLabel} - jsr c64flt.copy_float - """ -}) - - // memfloat = float value -patterns.add(AsmPattern(listOf(Opcode.PUSH_FLOAT, Opcode.POP_MEM_FLOAT)) { segment -> - val floatConst = getFloatConst(segment[0].arg!!) - """ - lda #<$floatConst - ldy #>$floatConst - sta ${C64Zeropage.SCRATCH_W1} - sty ${C64Zeropage.SCRATCH_W1 + 1} - lda #<${hexVal(segment[1])} - ldy #>${hexVal(segment[1])} - jsr c64flt.copy_float - """ -}) - // memfloat = float var -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_FLOAT, Opcode.POP_MEM_FLOAT)) { segment -> - """ - lda #<${segment[0].callLabel} - ldy #>${segment[0].callLabel} - sta ${C64Zeropage.SCRATCH_W1} - sty ${C64Zeropage.SCRATCH_W1 + 1} - lda #<${hexVal(segment[1])} - ldy #>${hexVal(segment[1])} - jsr c64flt.copy_float - """ -}) - // memfloat = ubytevar -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_UB_TO_F, Opcode.POP_MEM_FLOAT)) { segment -> - val loadByteA = when (segment[0].callLabel) { - "A" -> "" - "X" -> "txa" - "Y" -> "tya" - else -> "lda ${segment[0].callLabel}" - } - """ - $loadByteA - sta ${C64Zeropage.SCRATCH_B1} - lda #<${hexVal(segment[2])} - ldy #>${hexVal(segment[2])} - jsr c64flt.ub2float - """ -}) - // memfloat = uwordvar -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.CAST_UW_TO_F, Opcode.POP_MEM_FLOAT)) { segment -> - """ - lda ${segment[0].callLabel} - sta ${C64Zeropage.SCRATCH_W1} - lda ${segment[0].callLabel}+1 - sta ${C64Zeropage.SCRATCH_W1 + 1} - lda #<${hexVal(segment[2])} - ldy #>${hexVal(segment[2])} - jsr c64flt.uw2float - """ -}) - // memfloat = bytevar -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CAST_B_TO_F, Opcode.POP_MEM_FLOAT)) { segment -> - val loadByteA = when (segment[0].callLabel) { - "A" -> "" - "X" -> "txa" - "Y" -> "tya" - else -> "lda ${segment[0].callLabel}" - } - """ - $loadByteA - sta ${C64Zeropage.SCRATCH_B1} - lda #<${hexVal(segment[2])} - ldy #>${hexVal(segment[2])} - jsr c64flt.b2float - """ -}) - // memfloat = wordvar -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.CAST_W_TO_F, Opcode.POP_MEM_FLOAT)) { segment -> - """ - lda ${segment[0].callLabel} - sta ${C64Zeropage.SCRATCH_W1} - lda ${segment[0].callLabel}+1 - sta ${C64Zeropage.SCRATCH_W1 + 1} - lda #<${hexVal(segment[2])} - ldy #>${hexVal(segment[2])} - jsr c64flt.w2float - """ -}) - // memfloat = mem byte -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.CAST_B_TO_F, Opcode.POP_MEM_FLOAT)) { segment -> - """ - lda ${hexVal(segment[0])} - sta ${C64Zeropage.SCRATCH_B1} - lda #<${hexVal(segment[2])} - ldy #>${hexVal(segment[2])} - jsr c64flt.b2float - """ -}) - // memfloat = mem ubyte -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.CAST_UB_TO_F, Opcode.POP_MEM_FLOAT)) { segment -> - """ - lda ${hexVal(segment[0])} - sta ${C64Zeropage.SCRATCH_B1} - lda #<${hexVal(segment[2])} - ldy #>${hexVal(segment[2])} - jsr c64flt.ub2float - """ -}) - // memfloat = mem word -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_W, Opcode.CAST_W_TO_F, Opcode.POP_MEM_FLOAT)) { segment -> - """ - lda ${hexVal(segment[0])} - sta ${C64Zeropage.SCRATCH_W1} - lda ${hexValPlusOne(segment[0])} - sta ${C64Zeropage.SCRATCH_W1 + 1} - lda #<${hexVal(segment[2])} - ldy #>${hexVal(segment[2])} - jsr c64flt.w2float - """ -}) - // memfloat = mem uword -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_UW, Opcode.CAST_UW_TO_F, Opcode.POP_MEM_FLOAT)) { segment -> - """ - lda ${hexVal(segment[0])} - sta ${C64Zeropage.SCRATCH_W1} - lda ${hexValPlusOne(segment[0])} - sta ${C64Zeropage.SCRATCH_W1 + 1} - lda #<${hexVal(segment[2])} - ldy #>${hexVal(segment[2])} - jsr c64flt.uw2float - """ -}) - // memfloat = mem float -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_FLOAT, Opcode.POP_MEM_FLOAT)) { segment -> - """ - lda #<${hexVal(segment[0])} - ldy #>${hexVal(segment[0])} - sta ${C64Zeropage.SCRATCH_W1} - sty ${C64Zeropage.SCRATCH_W1 + 1} - lda #<${hexVal(segment[1])} - ldy #>${hexVal(segment[1])} - jsr c64flt.copy_float - """ -}) - // memfloat = bytearray[index] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_B_TO_F, Opcode.POP_MEM_FLOAT)) { segment -> - val index = intVal(segment[0]) - """ - lda ${segment[1].callLabel}+$index - sta ${C64Zeropage.SCRATCH_B1} - lda #<${hexVal(segment[3])} - ldy #>${hexVal(segment[3])} - jsr c64flt.b2float - """ -}) - // memfloat = ubytearray[index] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.CAST_UB_TO_F, Opcode.POP_MEM_FLOAT)) { segment -> - val index = intVal(segment[0]) - """ - lda ${segment[1].callLabel}+$index - sta ${C64Zeropage.SCRATCH_B1} - lda #<${hexVal(segment[3])} - ldy #>${hexVal(segment[3])} - jsr c64flt.ub2float - """ -}) - // memfloat = wordarray[index] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.CAST_W_TO_F, Opcode.POP_MEM_FLOAT)) { segment -> - val index = intVal(segment[0]) * 2 - """ - lda ${segment[1].callLabel}+$index - ldy ${segment[1].callLabel}+${index + 1} - sta ${C64Zeropage.SCRATCH_W1} - sty ${C64Zeropage.SCRATCH_W1 + 1} - lda #<${hexVal(segment[3])} - ldy #>${hexVal(segment[3])} - jsr c64flt.w2float - """ -}) - // memfloat = uwordarray[index] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.CAST_UW_TO_F, Opcode.POP_MEM_FLOAT)) { segment -> - val index = intVal(segment[0]) * 2 - """ - lda ${segment[1].callLabel}+$index - ldy ${segment[1].callLabel}+${index + 1} - sta ${C64Zeropage.SCRATCH_W1} - sty ${C64Zeropage.SCRATCH_W1 + 1} - lda #<${hexVal(segment[3])} - ldy #>${hexVal(segment[3])} - jsr c64flt.uw2float - """ -}) - // memfloat = floatarray[index] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_FLOAT, Opcode.POP_MEM_FLOAT)) { segment -> - val index = intVal(segment[0]) * MachineDefinition.Mflpt5.MemorySize - """ - lda #<${segment[1].callLabel}+$index - ldy #>${segment[1].callLabel}+$index - sta ${C64Zeropage.SCRATCH_W1} - sty ${C64Zeropage.SCRATCH_W1 + 1} - lda #<${hexVal(segment[2])} - ldy #>${hexVal(segment[2])} - jsr c64flt.copy_float - """ -}) - // floatarray[idxbyte] = float -patterns.add(AsmPattern(listOf(Opcode.PUSH_FLOAT, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_FLOAT)) { segment -> - val floatConst = getFloatConst(segment[0].arg!!) - val index = intVal(segment[1]) * MachineDefinition.Mflpt5.MemorySize - """ - lda #<$floatConst - ldy #>$floatConst - sta ${C64Zeropage.SCRATCH_W1} - sty ${C64Zeropage.SCRATCH_W1 + 1} - lda #<(${segment[2].callLabel}+$index) - ldy #>(${segment[2].callLabel}+$index) - jsr c64flt.copy_float - """ -}) - // floatarray[idxbyte] = floatvar -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_FLOAT, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_FLOAT)) { segment -> - val index = intVal(segment[1]) * MachineDefinition.Mflpt5.MemorySize - """ - lda #<${segment[0].callLabel} - ldy #>${segment[0].callLabel} - sta ${C64Zeropage.SCRATCH_W1} - sty ${C64Zeropage.SCRATCH_W1 + 1} - lda #<(${segment[2].callLabel}+$index) - ldy #>(${segment[2].callLabel}+$index) - jsr c64flt.copy_float - """ -}) - // floatarray[idxbyte] = memfloat -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_FLOAT, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_FLOAT)) { segment -> - val index = intVal(segment[1]) * MachineDefinition.Mflpt5.MemorySize - """ - lda #<${hexVal(segment[0])} - ldy #>${hexVal(segment[0])} - sta ${C64Zeropage.SCRATCH_W1} - sty ${C64Zeropage.SCRATCH_W1 + 1} - lda #<(${segment[2].callLabel}+$index) - ldy #>(${segment[2].callLabel}+$index) - jsr c64flt.copy_float - """ -}) - // floatarray[idx2] = floatarray[idx1] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_FLOAT, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_FLOAT)) { segment -> - val index1 = intVal(segment[0]) * MachineDefinition.Mflpt5.MemorySize - val index2 = intVal(segment[2]) * MachineDefinition.Mflpt5.MemorySize - """ - lda #<(${segment[1].callLabel}+$index1) - ldy #>(${segment[1].callLabel}+$index1) - sta ${C64Zeropage.SCRATCH_W1} - sty ${C64Zeropage.SCRATCH_W1 + 1} - lda #<(${segment[3].callLabel}+$index2) - ldy #>(${segment[3].callLabel}+$index2) - jsr c64flt.copy_float - """ -}) - - // ---------- some special operations ------------------ - // var word = AX register pair -patterns.add(AsmPattern(listOf(Opcode.PUSH_REGAX_WORD, Opcode.POP_VAR_WORD)) { segment -> - """ - sta ${segment[1].callLabel} - stx ${segment[1].callLabel}+1 - """ -}) - // var word = AY register pair -patterns.add(AsmPattern(listOf(Opcode.PUSH_REGAY_WORD, Opcode.POP_VAR_WORD)) { segment -> - """ - sta ${segment[1].callLabel} - sty ${segment[1].callLabel}+1 - """ -}) - // var word = XY register pair -patterns.add(AsmPattern(listOf(Opcode.PUSH_REGXY_WORD, Opcode.POP_VAR_WORD)) { segment -> - """ - stx ${segment[1].callLabel} - sty ${segment[1].callLabel}+1 - """ -}) - // mem word = AX register pair -patterns.add(AsmPattern(listOf(Opcode.PUSH_REGAX_WORD, Opcode.POP_MEM_WORD)) { segment -> - """ - sta ${hexVal(segment[1])} - stx ${hexValPlusOne(segment[1])} - """ -}) - // mem word = AY register pair -patterns.add(AsmPattern(listOf(Opcode.PUSH_REGAY_WORD, Opcode.POP_MEM_WORD)) { segment -> - """ - sta ${hexVal(segment[1])} - sty ${hexValPlusOne(segment[1])} - """ -}) - // mem word = XY register pair -patterns.add(AsmPattern(listOf(Opcode.PUSH_REGXY_WORD, Opcode.POP_MEM_WORD)) { segment -> - """ - stx ${hexVal(segment[1])} - sty ${hexValPlusOne(segment[1])} - """ -}) - - // AX register pair = word value -patterns.add(AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.POP_REGAX_WORD)) { segment -> - val value = hexVal(segment[0]) - " lda #<$value | ldx #>$value" -}) - // AY register pair = word value -patterns.add(AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.POP_REGAY_WORD)) { segment -> - val value = hexVal(segment[0]) - " lda #<$value | ldy #>$value" -}) - // XY register pair = word value -patterns.add(AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.POP_REGXY_WORD)) { segment -> - val value = hexVal(segment[0]) - " ldx #<$value | ldy #>$value" -}) - // AX register pair = word var -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.POP_REGAX_WORD)) { segment -> - " lda ${segment[0].callLabel} | ldx ${segment[0].callLabel}+1" -}) - // AY register pair = word var -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.POP_REGAY_WORD)) { segment -> - " lda ${segment[0].callLabel} | ldy ${segment[0].callLabel}+1" -}) - // XY register pair = word var -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.POP_REGXY_WORD)) { segment -> - " ldx ${segment[0].callLabel} | ldy ${segment[0].callLabel}+1" -}) - // AX register pair = mem word -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_UW, Opcode.POP_REGAX_WORD), - listOf(Opcode.PUSH_MEM_W, Opcode.POP_REGAX_WORD)) { segment -> - " lda ${hexVal(segment[0])} | ldx ${hexValPlusOne(segment[0])}" -}) - // AY register pair = mem word -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_UW, Opcode.POP_REGAY_WORD), - listOf(Opcode.PUSH_MEM_W, Opcode.POP_REGAY_WORD)) { segment -> - " lda ${hexVal(segment[0])} | ldy ${hexValPlusOne(segment[0])}" -}) - // XY register pair = mem word -patterns.add(AsmPattern( - listOf(Opcode.PUSH_MEM_UW, Opcode.POP_REGXY_WORD), - listOf(Opcode.PUSH_MEM_W, Opcode.POP_REGXY_WORD)) { segment -> - " ldx ${hexVal(segment[0])} | ldy ${hexValPlusOne(segment[0])}" -}) - - - // byte var = wordvar as (u)byte -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.CAST_W_TO_UB, Opcode.POP_VAR_BYTE), - listOf(Opcode.PUSH_VAR_WORD, Opcode.CAST_W_TO_B, Opcode.POP_VAR_BYTE)) { segment -> - when (segment[2].callLabel) { - "A" -> " lda ${segment[0].callLabel}" - "X" -> " ldx ${segment[0].callLabel}" - "Y" -> " ldy ${segment[0].callLabel}" - else -> " lda ${segment[0].callLabel} | sta ${segment[2].callLabel}" - } -}) - // byte var = uwordvar as (u)byte -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.CAST_UW_TO_UB, Opcode.POP_VAR_BYTE), - listOf(Opcode.PUSH_VAR_WORD, Opcode.CAST_UW_TO_B, Opcode.POP_VAR_BYTE)) { segment -> - when (segment[2].callLabel) { - "A" -> " lda ${segment[0].callLabel}" - "X" -> " ldx ${segment[0].callLabel}" - "Y" -> " ldy ${segment[0].callLabel}" - else -> " lda ${segment[0].callLabel} | sta ${segment[2].callLabel}" - } -}) - // byte var = msb(word var) -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.MSB, Opcode.POP_VAR_BYTE)) { segment -> - when (segment[2].callLabel) { - "A" -> " lda ${segment[0].callLabel}+1" - "X" -> " ldx ${segment[0].callLabel}+1" - "Y" -> " ldy ${segment[0].callLabel}+1" - else -> " lda ${segment[0].callLabel}+1 | sta ${segment[2].callLabel}" - } -}) - // push word var as (u)byte -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.CAST_W_TO_UB), - listOf(Opcode.PUSH_VAR_WORD, Opcode.CAST_W_TO_B)) { segment -> - " lda ${segment[0].callLabel} | sta $ESTACK_LO_HEX,x | dex " -}) - // push uword var as (u)byte -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.CAST_UW_TO_UB), - listOf(Opcode.PUSH_VAR_WORD, Opcode.CAST_UW_TO_B)) { segment -> - " lda ${segment[0].callLabel} | sta $ESTACK_LO_HEX,x | dex " -}) - // push msb(word var) -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.MSB)) { segment -> - " lda ${segment[0].callLabel}+1 | sta $ESTACK_LO_HEX,x | dex " -}) - - // set a register pair to a certain memory address (of a variable) -patterns.add(AsmPattern(listOf(Opcode.PUSH_ADDR_HEAPVAR, Opcode.POP_REGAX_WORD)) { segment -> - " lda #<${segment[0].callLabel} | ldx #>${segment[0].callLabel} " -}) -patterns.add(AsmPattern(listOf(Opcode.PUSH_ADDR_HEAPVAR, Opcode.POP_REGAY_WORD)) { segment -> - " lda #<${segment[0].callLabel} | ldy #>${segment[0].callLabel} " -}) -patterns.add(AsmPattern(listOf(Opcode.PUSH_ADDR_HEAPVAR, Opcode.POP_REGXY_WORD)) { segment -> - " ldx #<${segment[0].callLabel} | ldy #>${segment[0].callLabel} " -}) - - // push memory byte | bytevalue -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.PUSH_BYTE, Opcode.BITOR_BYTE), - listOf(Opcode.PUSH_MEM_UB, Opcode.PUSH_BYTE, Opcode.BITOR_BYTE)) { segment -> - " lda ${hexVal(segment[0])} | ora #${hexVal(segment[1])} | sta $ESTACK_LO_HEX,x | dex " -}) - // push memory byte & bytevalue -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.PUSH_BYTE, Opcode.BITAND_BYTE), - listOf(Opcode.PUSH_MEM_UB, Opcode.PUSH_BYTE, Opcode.BITAND_BYTE)) { segment -> - " lda ${hexVal(segment[0])} | and #${hexVal(segment[1])} | sta $ESTACK_LO_HEX,x | dex " -}) - // push memory byte ^ bytevalue -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.PUSH_BYTE, Opcode.BITXOR_BYTE), - listOf(Opcode.PUSH_MEM_UB, Opcode.PUSH_BYTE, Opcode.BITXOR_BYTE)) { segment -> - " lda ${hexVal(segment[0])} | eor #${hexVal(segment[1])} | sta $ESTACK_LO_HEX,x | dex " -}) - // push var byte | bytevalue -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_BYTE, Opcode.BITOR_BYTE)) { segment -> - " lda ${segment[0].callLabel} | ora #${hexVal(segment[1])} | sta $ESTACK_LO_HEX,x | dex " -}) - // push var byte & bytevalue -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_BYTE, Opcode.BITAND_BYTE)) { segment -> - " lda ${segment[0].callLabel} | and #${hexVal(segment[1])} | sta $ESTACK_LO_HEX,x | dex " -}) - // push var byte ^ bytevalue -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_BYTE, Opcode.BITXOR_BYTE)) { segment -> - " lda ${segment[0].callLabel} | eor #${hexVal(segment[1])} | sta $ESTACK_LO_HEX,x | dex " -}) - - // push memory word | wordvalue -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_W, Opcode.PUSH_WORD, Opcode.BITOR_WORD), - listOf(Opcode.PUSH_MEM_UW, Opcode.PUSH_WORD, Opcode.BITOR_WORD)) { segment -> - """ - lda ${hexVal(segment[0])} - ora #<${hexVal(segment[1])} - sta $ESTACK_LO_HEX,x - lda ${hexValPlusOne(segment[0])} - ora #>${hexVal(segment[1])} - sta $ESTACK_HI_HEX,x - dex - """ -}) - // push memory word & wordvalue -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_W, Opcode.PUSH_WORD, Opcode.BITAND_WORD), - listOf(Opcode.PUSH_MEM_UW, Opcode.PUSH_WORD, Opcode.BITAND_WORD)) { segment -> - """ - lda ${hexVal(segment[0])} - and #<${hexVal(segment[1])} - sta $ESTACK_LO_HEX,x - lda ${hexValPlusOne(segment[0])} - and #>${hexVal(segment[1])} - sta $ESTACK_HI_HEX,x - dex - """ -}) - // push memory word ^ wordvalue -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_W, Opcode.PUSH_WORD, Opcode.BITXOR_WORD), - listOf(Opcode.PUSH_MEM_UW, Opcode.PUSH_WORD, Opcode.BITXOR_WORD)) { segment -> - """ - lda ${hexVal(segment[0])} - eor #<${hexVal(segment[1])} - sta $ESTACK_LO_HEX,x - lda ${hexValPlusOne(segment[0])} - eor #>${hexVal(segment[1])} - sta $ESTACK_HI_HEX,x - dex - """ -}) - // push var word | wordvalue -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.PUSH_WORD, Opcode.BITOR_WORD)) { segment -> - """ - lda ${segment[0].callLabel} - ora #<${hexVal(segment[1])} - sta $ESTACK_LO_HEX,x - lda ${segment[0].callLabel}+1 - ora #>${hexVal(segment[1])} - sta $ESTACK_HI_HEX,x - dex - """ -}) - // push var word & wordvalue -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.PUSH_WORD, Opcode.BITAND_WORD)) { segment -> - """ - lda ${segment[0].callLabel} - and #<${hexVal(segment[1])} - sta $ESTACK_LO_HEX,x - lda ${segment[0].callLabel}+1 - and #>${hexVal(segment[1])} - sta $ESTACK_HI_HEX,x - dex - """ -}) - // push var word ^ wordvalue -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.PUSH_WORD, Opcode.BITXOR_WORD)) { segment -> - """ - lda ${segment[0].callLabel} - eor #<${hexVal(segment[1])} - sta $ESTACK_LO_HEX,x - lda ${segment[0].callLabel}+1 - eor #>${hexVal(segment[1])} - sta $ESTACK_HI_HEX,x - dex - """ -}) - // push var byte & var byte -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.BITAND_BYTE, Opcode.POP_VAR_BYTE)) { segment -> - """ - lda ${segment[0].callLabel} - and ${segment[1].callLabel} - sta ${segment[3].callLabel} - """ -}) - // push var byte | var byte -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.BITOR_BYTE, Opcode.POP_VAR_BYTE)) { segment -> - """ - lda ${segment[0].callLabel} - ora ${segment[1].callLabel} - sta ${segment[3].callLabel} - """ -}) - // push var byte ^ var byte -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.BITXOR_BYTE, Opcode.POP_VAR_BYTE)) { segment -> - """ - lda ${segment[0].callLabel} - eor ${segment[1].callLabel} - sta ${segment[3].callLabel} - """ -}) - // push var word & var word -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.PUSH_VAR_WORD, Opcode.BITAND_WORD, Opcode.POP_VAR_WORD)) { segment -> - """ - lda ${segment[0].callLabel} - and ${segment[1].callLabel} - sta ${segment[3].callLabel} - lda ${segment[0].callLabel}+1 - and ${segment[1].callLabel}+1 - sta ${segment[3].callLabel}+1 - """ -}) - // push var word | var word -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.PUSH_VAR_WORD, Opcode.BITOR_WORD, Opcode.POP_VAR_WORD)) { segment -> - """ - lda ${segment[0].callLabel} - ora ${segment[1].callLabel} - sta ${segment[3].callLabel} - lda ${segment[0].callLabel}+1 - ora ${segment[1].callLabel}+1 - sta ${segment[3].callLabel}+1 - """ -}) - // push var word ^ var word -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.PUSH_VAR_WORD, Opcode.BITXOR_WORD, Opcode.POP_VAR_WORD)) { segment -> - """ - lda ${segment[0].callLabel} - eor ${segment[1].callLabel} - sta ${segment[3].callLabel} - lda ${segment[0].callLabel}+1 - eor ${segment[1].callLabel}+1 - sta ${segment[3].callLabel}+1 - """ -}) - - // bytearray[consti3] = bytearray[consti1] ^ bytearray[consti2] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, - Opcode.BITXOR_BYTE, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> - val i1 = segment[5].arg!!.integerValue() - val i2 = segment[0].arg!!.integerValue() - val i3 = segment[2].arg!!.integerValue() - """ - lda ${segment[1].callLabel}+$i2 - eor ${segment[3].callLabel}+$i3 - sta ${segment[6].callLabel}+$i1 - """ -}) - // warray[consti3] = warray[consti1] ^ warray[consti2] -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, - Opcode.BITXOR_WORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val i1 = segment[5].arg!!.integerValue() * 2 - val i2 = segment[0].arg!!.integerValue() * 2 - val i3 = segment[2].arg!!.integerValue() * 2 - """ - lda ${segment[1].callLabel}+$i2 - eor ${segment[3].callLabel}+$i3 - sta ${segment[6].callLabel}+$i1 - lda ${segment[1].callLabel}+${i2 + 1} - eor ${segment[3].callLabel}+${i3 + 1} - sta ${segment[6].callLabel}+${i1 + 1} - """ -}) - -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.MKWORD)) { segment -> - """ - lda ${segment[0].callLabel} - sta $ESTACK_LO_HEX,x - lda ${segment[1].callLabel} - sta $ESTACK_HI_HEX,x - dex - """ -}) -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.MKWORD)) { segment -> - """ - lda #${hexVal(segment[0])} - sta $ESTACK_LO_HEX,x - lda ${segment[1].callLabel} - sta $ESTACK_HI_HEX,x - dex - """ -}) -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_BYTE, Opcode.MKWORD)) { segment -> - """ - lda ${segment[0].callLabel} - sta $ESTACK_LO_HEX,x - lda #${hexVal(segment[1])} - sta $ESTACK_HI_HEX,x - dex - """ -}) -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.MKWORD, Opcode.POP_VAR_WORD)) { segment -> - """ - lda ${segment[0].callLabel} - sta ${segment[3].callLabel} - lda ${segment[1].callLabel} - sta ${segment[3].callLabel}+1 - """ -}) -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_BYTE, Opcode.MKWORD, Opcode.POP_VAR_WORD)) { segment -> - """ - lda ${segment[0].callLabel} - sta ${segment[3].callLabel} - lda #${hexVal(segment[1])} - sta ${segment[3].callLabel}+1 - """ -}) -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.MKWORD, Opcode.POP_VAR_WORD)) { segment -> - """ - lda #${hexVal(segment[0])} - sta ${segment[3].callLabel} - lda ${segment[1].callLabel} - sta ${segment[3].callLabel}+1 - """ -}) -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.MKWORD, Opcode.CAST_UW_TO_W, Opcode.POP_VAR_WORD)) { segment -> - """ - lda ${segment[0].callLabel} - sta ${segment[4].callLabel} - lda ${segment[1].callLabel} - sta ${segment[4].callLabel}+1 - """ -}) - - // more efficient versions of x+1 and x-1 to avoid pushing the 1 on the stack -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.ADD_B), listOf(Opcode.PUSH_BYTE, Opcode.ADD_UB)) { segment -> - val amount = segment[0].arg!!.integerValue() - if (amount in 1..2) { - " inc $ESTACK_LO_PLUS1_HEX,x | ".repeat(amount) - } else - null -}) -patterns.add(AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.ADD_UW), listOf(Opcode.PUSH_WORD, Opcode.ADD_W)) { segment -> - val amount = segment[0].arg!!.integerValue() - if (amount in 1..2) { - " inc $ESTACK_LO_PLUS1_HEX,x | bne + | inc $ESTACK_HI_PLUS1_HEX,x |+ | ".repeat(amount) - } else - null -}) -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.SUB_B), listOf(Opcode.PUSH_BYTE, Opcode.SUB_UB)) { segment -> - val amount = segment[0].arg!!.integerValue() - if (amount in 1..2) { - " dec $ESTACK_LO_PLUS1_HEX,x | ".repeat(amount) - } else - null -}) -patterns.add(AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.SUB_UW), listOf(Opcode.PUSH_WORD, Opcode.SUB_W)) { segment -> - val amount = segment[0].arg!!.integerValue() - if (amount in 1..2) { - " lda $ESTACK_LO_PLUS1_HEX,x | bne + | dec $ESTACK_HI_PLUS1_HEX,x |+ | dec $ESTACK_LO_PLUS1_HEX,x | ".repeat(amount) - } else - null -}) - - // @todo optimize 8 and 16 bit adds and subs (avoid stack use altogether on most common operations) - -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.CMP_B), listOf(Opcode.PUSH_VAR_BYTE, Opcode.CMP_UB)) { segment -> - // this pattern is encountered as part of the loop bound condition in for loops (var + cmp + jz/jnz) - val cmpval = segment[1].arg!!.integerValue() - when (segment[0].callLabel) { - "A" -> { - " cmp #$cmpval " - } - "X" -> { - " cpx #$cmpval " - } - "Y" -> { - " cpy #$cmpval " - } - else -> { - " lda ${segment[0].callLabel} | cmp #$cmpval " - } - } -}) -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.CMP_W), listOf(Opcode.PUSH_VAR_WORD, Opcode.CMP_UW)) { segment -> - // this pattern is encountered as part of the loop bound condition in for loops (var + cmp + jz/jnz) - """ - lda ${segment[0].callLabel} - cmp #<${hexVal(segment[1])} - bne + - lda ${segment[0].callLabel}+1 - cmp #>${hexVal(segment[1])} - bne + - lda #0 -+ - """ -}) - -patterns.add(AsmPattern(listOf(Opcode.RRESTOREX, Opcode.LINE, Opcode.RSAVEX), listOf(Opcode.RRESTOREX, Opcode.RSAVEX)) { segment -> - """ - sta ${C64Zeropage.SCRATCH_REG} - pla - tax - pha - lda ${C64Zeropage.SCRATCH_REG} - """ -}) - - // various optimizable integer multiplications -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.MUL_B), listOf(Opcode.PUSH_BYTE, Opcode.MUL_UB)) { segment -> - val amount = segment[0].arg!!.integerValue() - val result = optimizedIntMultiplicationsOnStack(segment[1], amount) - result - ?: " lda #${hexVal(segment[0])} | sta $ESTACK_LO_HEX,x | dex | jsr prog8_lib.mul_byte" -}) -patterns.add(AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.MUL_W), listOf(Opcode.PUSH_WORD, Opcode.MUL_UW)) { segment -> - val amount = segment[0].arg!!.integerValue() - val result = optimizedIntMultiplicationsOnStack(segment[1], amount) - if (result != null) result else { - val value = hexVal(segment[0]) - " lda #<$value | sta $ESTACK_LO_HEX,x | lda #>$value | sta $ESTACK_HI_HEX,x | dex | jsr prog8_lib.mul_word" - } -}) - - // various variable or memory swaps -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.POP_VAR_BYTE, Opcode.POP_VAR_BYTE)) { segment -> - val var1 = segment[0].callLabel - val var2 = segment[1].callLabel - val var3 = segment[2].callLabel - val var4 = segment[3].callLabel - if (var1 == var3 && var2 == var4) { - """ - lda $var1 - tay - lda $var2 - sta $var1 - sty $var2 - """ - } else null -}) -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.PUSH_VAR_WORD, Opcode.POP_VAR_WORD, Opcode.POP_VAR_WORD)) { segment -> - val var1 = segment[0].callLabel - val var2 = segment[1].callLabel - val var3 = segment[2].callLabel - val var4 = segment[3].callLabel - if (var1 == var3 && var2 == var4) { - """ - lda $var1 - tay - lda $var2 - sta $var1 - sty $var2 - lda $var1+1 - tay - lda $var2+1 - sta $var1+1 - sty $var2+1 - """ - } else null -}) -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.PUSH_MEM_B, Opcode.POP_MEM_BYTE, Opcode.POP_MEM_BYTE), - listOf(Opcode.PUSH_MEM_UB, Opcode.PUSH_MEM_UB, Opcode.POP_MEM_BYTE, Opcode.POP_MEM_BYTE)) { segment -> - val addr1 = segment[0].arg!!.integerValue() - val addr2 = segment[1].arg!!.integerValue() - val addr3 = segment[2].arg!!.integerValue() - val addr4 = segment[3].arg!!.integerValue() - if (addr1 == addr3 && addr2 == addr4) { - """ - lda ${addr1.toHex()} - tay - lda ${addr2.toHex()} - sta ${addr1.toHex()} - sty ${addr2.toHex()} - """ - } else null -}) -patterns.add(AsmPattern(listOf(Opcode.PUSH_MEM_W, Opcode.PUSH_MEM_W, Opcode.POP_MEM_WORD, Opcode.POP_MEM_WORD), - listOf(Opcode.PUSH_MEM_UW, Opcode.PUSH_MEM_UW, Opcode.POP_MEM_WORD, Opcode.POP_MEM_WORD)) { segment -> - val addr1 = segment[0].arg!!.integerValue() - val addr2 = segment[1].arg!!.integerValue() - val addr3 = segment[2].arg!!.integerValue() - val addr4 = segment[3].arg!!.integerValue() - if (addr1 == addr3 && addr2 == addr4) { - """ - lda ${addr1.toHex()} - tay - lda ${addr2.toHex()} - sta ${addr1.toHex()} - sty ${addr2.toHex()} - lda ${(addr1 + 1).toHex()} - tay - lda ${(addr2 + 1).toHex()} - sta ${(addr1 + 1).toHex()} - sty ${(addr2 + 1).toHex()} - """ - } else null -}) -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, - Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> - val i1 = segment[0].arg!!.integerValue() - val i2 = segment[2].arg!!.integerValue() - val i3 = segment[4].arg!!.integerValue() - val i4 = segment[6].arg!!.integerValue() - val array1 = segment[1].callLabel - val array2 = segment[3].callLabel - val array3 = segment[5].callLabel - val array4 = segment[7].callLabel - if (i1 == i3 && i2 == i4 && array1 == array3 && array2 == array4) { - """ - lda $array1+$i1 - tay - lda $array2+$i2 - sta $array1+$i1 - sty $array2+$i2 - """ - } else null -}) -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, - Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> - val vi1 = segment[0].callLabel - val vi2 = segment[2].callLabel - val vi3 = segment[4].callLabel - val vi4 = segment[6].callLabel - val array1 = segment[1].callLabel - val array2 = segment[3].callLabel - val array3 = segment[5].callLabel - val array4 = segment[7].callLabel - if (vi1 == vi3 && vi2 == vi4 && array1 == array3 && array2 == array4) { - val load1 = loadAFromIndexedByVar(segment[0], segment[1]) - val load2 = loadAFromIndexedByVar(segment[2], segment[3]) - val storeIn1 = storeAToIndexedByVar(segment[0], segment[1]) - val storeIn2 = storeAToIndexedByVar(segment[2], segment[3]) - """ - $load1 - pha - $load2 - $storeIn1 - pla - $storeIn2 - """ - } else null -}) -patterns.add(AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, - Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val i1 = segment[0].arg!!.integerValue() * 2 - val i2 = segment[2].arg!!.integerValue() * 2 - val i3 = segment[4].arg!!.integerValue() * 2 - val i4 = segment[6].arg!!.integerValue() * 2 - val array1 = segment[1].callLabel - val array2 = segment[3].callLabel - val array3 = segment[5].callLabel - val array4 = segment[7].callLabel - if (i1 == i3 && i2 == i4 && array1 == array3 && array2 == array4) { - """ - lda $array1+$i1 - tay - lda $array2+$i2 - sta $array1+$i1 - sty $array2+$i2 - lda $array1+${i1 + 1} - tay - lda $array2+${i2 + 1} - sta $array1+${i1 + 1} - sty $array2+${i2 + 1} - """ - } else null -}) -patterns.add(AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_WORD, - Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val vi1 = segment[0].callLabel - val vi2 = segment[2].callLabel - val vi3 = segment[4].callLabel - val vi4 = segment[6].callLabel - val array1 = segment[1].callLabel - val array2 = segment[3].callLabel - val array3 = segment[5].callLabel - val array4 = segment[7].callLabel - if (vi1 == vi3 && vi2 == vi4 && array1 == array3 && array2 == array4) { - // SCRATCH_B1 = index1 - // SCRATCH_REG = index2 - // SCRATCH_W1 = temp storage of array[index2] - """ - lda ${segment[0].callLabel} - asl a - sta ${C64Zeropage.SCRATCH_B1} - lda ${segment[2].callLabel} - asl a - sta ${C64Zeropage.SCRATCH_REG} - stx ${C64Zeropage.SCRATCH_REG_X} - tax - lda ${segment[3].callLabel},x - ldy ${segment[3].callLabel}+1,x - sta ${C64Zeropage.SCRATCH_W1} - sty ${C64Zeropage.SCRATCH_W1}+1 - ldx ${C64Zeropage.SCRATCH_B1} - lda ${segment[1].callLabel},x - ldy ${segment[1].callLabel}+1,x - ldx ${C64Zeropage.SCRATCH_REG} - sta ${segment[3].callLabel},x - tya - sta ${segment[3].callLabel}+1,x - ldx ${C64Zeropage.SCRATCH_B1} - lda ${C64Zeropage.SCRATCH_W1} - sta ${segment[1].callLabel},x - lda ${C64Zeropage.SCRATCH_W1}+1 - sta ${segment[1].callLabel}+1,x - ldx ${C64Zeropage.SCRATCH_REG_X} - """ - } else null -}) - -patterns.add(AsmPattern(listOf(Opcode.DUP_W, Opcode.CMP_UW), - listOf(Opcode.DUP_W, Opcode.CMP_W)) { segment -> - """ - lda $ESTACK_HI_PLUS1_HEX,x - cmp #>${segment[1].arg!!.integerValue().toHex()} - bne + - lda $ESTACK_LO_PLUS1_HEX,x - cmp #<${segment[1].arg!!.integerValue().toHex()} - ; bne + not necessary? - ; lda #0 not necessary? -+ - """ -}) -patterns.add(AsmPattern(listOf(Opcode.DUP_B, Opcode.CMP_UB), - listOf(Opcode.DUP_B, Opcode.CMP_B)) { segment -> - """ lda $ESTACK_LO_PLUS1_HEX,x | cmp #${segment[1].arg!!.integerValue().toHex()} """ -}) - } -} diff --git a/OldCodeGen/src/oldcodegen/SimpleAsm.kt b/OldCodeGen/src/oldcodegen/SimpleAsm.kt deleted file mode 100644 index c653079cc..000000000 --- a/OldCodeGen/src/oldcodegen/SimpleAsm.kt +++ /dev/null @@ -1,562 +0,0 @@ -package oldcodegen - -/** OLD STACK-VM CODE GEN -- NO LONGER USED **/ - - -import prog8.compiler.CompilerException -import prog8.compiler.intermediate.Instruction -import prog8.compiler.intermediate.IntermediateProgram -import prog8.compiler.intermediate.LabelInstr -import prog8.compiler.intermediate.Opcode -import prog8.compiler.target.c64.MachineDefinition.C64Zeropage -import prog8.compiler.target.c64.MachineDefinition.ESTACK_HI_HEX -import prog8.compiler.target.c64.MachineDefinition.ESTACK_HI_PLUS1_HEX -import prog8.compiler.target.c64.MachineDefinition.ESTACK_LO_HEX -import prog8.compiler.target.c64.MachineDefinition.ESTACK_LO_PLUS1_HEX -import prog8.compiler.target.c64.MachineDefinition.ESTACK_LO_PLUS2_HEX -import prog8.compiler.toHex -import prog8.vm.stackvm.Syscall -import prog8.vm.stackvm.syscallsForStackVm - - -// note: see https://wiki.nesdev.com/w/index.php/6502_assembly_optimisations - - -private var breakpointCounter = 0 - -internal fun simpleInstr2Asm(ins: Instruction, block: IntermediateProgram.ProgramBlock): String? { - // a label 'instruction' is simply translated into a asm label - if(ins is LabelInstr) { - val labelresult = - if(ins.name.startsWith("${block.name}.")) - ins.name.substring(block.name.length+1) - else - ins.name - return if(ins.asmProc) labelresult+"\t\t.proc" else labelresult - } - - // simple opcodes that are translated directly into one or a few asm instructions - return when(ins.opcode) { - Opcode.LINE -> " ;\tsrc line: ${ins.callLabel}" - Opcode.NOP -> " nop" // shouldn't be present anymore though - Opcode.START_PROCDEF -> "" // is done as part of a label - Opcode.END_PROCDEF -> " .pend" - Opcode.TERMINATE -> " brk" - Opcode.SEC -> " sec" - Opcode.CLC -> " clc" - Opcode.SEI -> " sei" - Opcode.CLI -> " cli" - Opcode.CARRY_TO_A -> " lda #0 | adc #0" - Opcode.JUMP -> { - if(ins.callLabel!=null) - " jmp ${ins.callLabel}" - else - " jmp ${hexVal(ins)}" - } - Opcode.CALL -> { - if(ins.callLabel!=null) - " jsr ${ins.callLabel}" - else - " jsr ${hexVal(ins)}" - } - Opcode.RETURN -> " rts" - Opcode.RSAVE -> { - // save cpu status flag and all registers A, X, Y. - // see http://6502.org/tutorials/register_preservation.html - " php | sta ${C64Zeropage.SCRATCH_REG} | pha | txa | pha | tya | pha | lda ${C64Zeropage.SCRATCH_REG}" - } - Opcode.RRESTORE -> { - // restore all registers and cpu status flag - " pla | tay | pla | tax | pla | plp" - } - Opcode.RSAVEX -> " sta ${C64Zeropage.SCRATCH_REG} | txa | pha | lda ${C64Zeropage.SCRATCH_REG}" - Opcode.RRESTOREX -> " sta ${C64Zeropage.SCRATCH_REG} | pla | tax | lda ${C64Zeropage.SCRATCH_REG}" - Opcode.DISCARD_BYTE -> " inx" - Opcode.DISCARD_WORD -> " inx" - Opcode.DISCARD_FLOAT -> " inx | inx | inx" - Opcode.DUP_B -> { - " lda $ESTACK_LO_PLUS1_HEX,x | sta $ESTACK_LO_HEX,x | dex | ;DUP_B " - } - Opcode.DUP_W -> { - " lda $ESTACK_LO_PLUS1_HEX,x | sta $ESTACK_LO_HEX,x | lda $ESTACK_HI_PLUS1_HEX,x | sta $ESTACK_HI_HEX,x | dex " - } - - Opcode.CMP_B, Opcode.CMP_UB -> { - " inx | lda $ESTACK_LO_HEX,x | cmp #${ins.arg!!.integerValue().toHex()} | ;CMP_B " - } - - Opcode.CMP_W, Opcode.CMP_UW -> { - """ - inx - lda $ESTACK_HI_HEX,x - cmp #>${ins.arg!!.integerValue().toHex()} - bne + - lda $ESTACK_LO_HEX,x - cmp #<${ins.arg.integerValue().toHex()} - ; bne + not necessary? - ; lda #0 not necessary? -+ - """ - } - - Opcode.INLINE_ASSEMBLY -> "@inline@" + (ins.callLabel2 ?: "") // All of the inline assembly is stored in the calllabel2 property. the '@inline@' is a special marker to accept it. - Opcode.INCLUDE_FILE -> { - val offset = if(ins.arg==null) "" else ", ${ins.arg.integerValue()}" - val length = if(ins.arg2==null) "" else ", ${ins.arg2.integerValue()}" - " .binary \"${ins.callLabel}\" $offset $length" - } - Opcode.SYSCALL -> { - if (ins.arg!!.numericValue() in syscallsForStackVm.map { it.callNr }) - throw CompilerException("cannot translate vm syscalls to real assembly calls - use *real* subroutine calls instead. Syscall ${ins.arg.numericValue()}") - val call = Syscall.values().find { it.callNr==ins.arg.numericValue() } - when(call) { - Syscall.FUNC_SIN, - Syscall.FUNC_COS, - Syscall.FUNC_ABS, - Syscall.FUNC_TAN, - Syscall.FUNC_ATAN, - Syscall.FUNC_LN, - Syscall.FUNC_LOG2, - Syscall.FUNC_SQRT, - Syscall.FUNC_RAD, - Syscall.FUNC_DEG, - Syscall.FUNC_ROUND, - Syscall.FUNC_FLOOR, - Syscall.FUNC_CEIL, - Syscall.FUNC_RNDF, - Syscall.FUNC_ANY_F, - Syscall.FUNC_ALL_F, - Syscall.FUNC_MAX_F, - Syscall.FUNC_MIN_F, - Syscall.FUNC_SUM_F -> " jsr c64flt.${call.name.toLowerCase()}" - null -> "" - else -> " jsr prog8_lib.${call.name.toLowerCase()}" - } - } - Opcode.BREAKPOINT -> { - breakpointCounter++ - "_prog8_breakpoint_$breakpointCounter\tnop" - } - - Opcode.PUSH_BYTE -> { - " lda #${hexVal(ins)} | sta $ESTACK_LO_HEX,x | dex" - } - Opcode.PUSH_WORD -> { - val value = hexVal(ins) - " lda #<$value | sta $ESTACK_LO_HEX,x | lda #>$value | sta $ESTACK_HI_HEX,x | dex" - } - Opcode.PUSH_FLOAT -> { - val floatConst = getFloatConst(ins.arg!!) - " lda #<$floatConst | ldy #>$floatConst | jsr c64flt.push_float" - } - Opcode.PUSH_VAR_BYTE -> { - when(ins.callLabel) { - "X" -> throw CompilerException("makes no sense to push X, it's used as a stack pointer itself. You should probably not use the X register (or only in trivial assignments)") - "A" -> " sta $ESTACK_LO_HEX,x | dex" - "Y" -> " tya | sta $ESTACK_LO_HEX,x | dex" - else -> " lda ${ins.callLabel} | sta $ESTACK_LO_HEX,x | dex" - } - } - Opcode.PUSH_VAR_WORD -> { - " lda ${ins.callLabel} | sta $ESTACK_LO_HEX,x | lda ${ins.callLabel}+1 | sta $ESTACK_HI_HEX,x | dex" - } - Opcode.PUSH_VAR_FLOAT -> " lda #<${ins.callLabel} | ldy #>${ins.callLabel}| jsr c64flt.push_float" - Opcode.PUSH_MEM_B, Opcode.PUSH_MEM_UB -> { - """ - lda ${hexVal(ins)} - sta $ESTACK_LO_HEX,x - dex - """ - } - Opcode.PUSH_MEM_W, Opcode.PUSH_MEM_UW -> { - """ - lda ${hexVal(ins)} - sta $ESTACK_LO_HEX,x - lda ${hexValPlusOne(ins)} - sta $ESTACK_HI_HEX,x - dex - """ - } - Opcode.PUSH_MEM_FLOAT -> { - " lda #<${hexVal(ins)} | ldy #>${hexVal(ins)}| jsr c64flt.push_float" - } - Opcode.PUSH_MEMREAD -> { - """ - lda $ESTACK_LO_PLUS1_HEX,x - sta (+) +1 - lda $ESTACK_HI_PLUS1_HEX,x - sta (+) +2 -+ lda 65535 ; modified - sta $ESTACK_LO_PLUS1_HEX,x - """ - } - - Opcode.PUSH_REGAY_WORD -> { - " sta $ESTACK_LO_HEX,x | tya | sta $ESTACK_HI_HEX,x | dex " - } - Opcode.PUSH_ADDR_HEAPVAR -> { - " lda #<${ins.callLabel} | sta $ESTACK_LO_HEX,x | lda #>${ins.callLabel} | sta $ESTACK_HI_HEX,x | dex" - } - Opcode.POP_REGAX_WORD -> throw AssemblyError("cannot load X register from stack because it's used as the stack pointer itself") - Opcode.POP_REGXY_WORD -> throw AssemblyError("cannot load X register from stack because it's used as the stack pointer itself") - Opcode.POP_REGAY_WORD -> { - " inx | lda $ESTACK_LO_HEX,x | ldy $ESTACK_HI_HEX,x " - } - - Opcode.READ_INDEXED_VAR_BYTE -> { - """ - ldy $ESTACK_LO_PLUS1_HEX,x - lda ${ins.callLabel},y - sta $ESTACK_LO_PLUS1_HEX,x - """ - } - Opcode.READ_INDEXED_VAR_WORD -> { - """ - lda $ESTACK_LO_PLUS1_HEX,x - asl a - tay - lda ${ins.callLabel},y - sta $ESTACK_LO_PLUS1_HEX,x - lda ${ins.callLabel}+1,y - sta $ESTACK_HI_PLUS1_HEX,x - """ - } - Opcode.READ_INDEXED_VAR_FLOAT -> { - """ - lda #<${ins.callLabel} - ldy #>${ins.callLabel} - jsr c64flt.push_float_from_indexed_var - """ - } - Opcode.WRITE_INDEXED_VAR_BYTE -> { - """ - inx - ldy $ESTACK_LO_HEX,x - inx - lda $ESTACK_LO_HEX,x - sta ${ins.callLabel},y - """ - } - Opcode.WRITE_INDEXED_VAR_WORD -> { - """ - inx - lda $ESTACK_LO_HEX,x - asl a - tay - inx - lda $ESTACK_LO_HEX,x - sta ${ins.callLabel},y - lda $ESTACK_HI_HEX,x - sta ${ins.callLabel}+1,y - """ - } - Opcode.WRITE_INDEXED_VAR_FLOAT -> { - """ - lda #<${ins.callLabel} - ldy #>${ins.callLabel} - jsr c64flt.pop_float_to_indexed_var - """ - } - Opcode.POP_MEM_BYTE -> { - """ - inx - lda $ESTACK_LO_HEX,x - sta ${hexVal(ins)} - """ - } - Opcode.POP_MEM_WORD -> { - """ - inx - lda $ESTACK_LO_HEX,x - sta ${hexVal(ins)} - lda $ESTACK_HI_HEX,x - sta ${hexValPlusOne(ins)} - """ - } - Opcode.POP_MEM_FLOAT -> { - " lda ${hexVal(ins)} | ldy ${hexValPlusOne(ins)} | jsr c64flt.pop_float" - } - Opcode.POP_MEMWRITE -> { - """ - inx - lda $ESTACK_LO_HEX,x - sta (+) +1 - lda $ESTACK_HI_HEX,x - sta (+) +2 - inx - lda $ESTACK_LO_HEX,x -+ sta 65535 ; modified - """ - } - - Opcode.POP_VAR_BYTE -> { - when (ins.callLabel) { - "X" -> throw CompilerException("makes no sense to pop X, it's used as a stack pointer itself") - "A" -> " inx | lda $ESTACK_LO_HEX,x" - "Y" -> " inx | ldy $ESTACK_LO_HEX,x" - else -> " inx | lda $ESTACK_LO_HEX,x | sta ${ins.callLabel}" - } - } - Opcode.POP_VAR_WORD -> { - " inx | lda $ESTACK_LO_HEX,x | ldy $ESTACK_HI_HEX,x | sta ${ins.callLabel} | sty ${ins.callLabel}+1" - } - Opcode.POP_VAR_FLOAT -> { - " lda #<${ins.callLabel} | ldy #>${ins.callLabel} | jsr c64flt.pop_float" - } - - Opcode.INC_VAR_UB, Opcode.INC_VAR_B -> { - when (ins.callLabel) { - "A" -> " clc | adc #1" - "X" -> " inx" - "Y" -> " iny" - else -> " inc ${ins.callLabel}" - } - } - Opcode.INC_VAR_UW, Opcode.INC_VAR_W -> { - " inc ${ins.callLabel} | bne + | inc ${ins.callLabel}+1 |+" - } - Opcode.INC_VAR_F -> { - """ - lda #<${ins.callLabel} - ldy #>${ins.callLabel} - jsr c64flt.inc_var_f - """ - } - Opcode.POP_INC_MEMORY -> { - """ - inx - lda $ESTACK_LO_HEX,x - sta (+) +1 - lda $ESTACK_HI_HEX,x - sta (+) +2 -+ inc 65535 ; modified - """ - } - Opcode.POP_DEC_MEMORY -> { - """ - inx - lda $ESTACK_LO_HEX,x - sta (+) +1 - lda $ESTACK_HI_HEX,x - sta (+) +2 -+ dec 65535 ; modified - """ - } - Opcode.DEC_VAR_UB, Opcode.DEC_VAR_B -> { - when (ins.callLabel) { - "A" -> " sec | sbc #1" - "X" -> " dex" - "Y" -> " dey" - else -> " dec ${ins.callLabel}" - } - } - Opcode.DEC_VAR_UW, Opcode.DEC_VAR_W -> { - " lda ${ins.callLabel} | bne + | dec ${ins.callLabel}+1 |+ | dec ${ins.callLabel}" - } - Opcode.DEC_VAR_F -> { - """ - lda #<${ins.callLabel} - ldy #>${ins.callLabel} - jsr c64flt.dec_var_f - """ - } - Opcode.INC_MEMORY -> " inc ${hexVal(ins)}" - Opcode.DEC_MEMORY -> " dec ${hexVal(ins)}" - Opcode.INC_INDEXED_VAR_B, Opcode.INC_INDEXED_VAR_UB -> " inx | txa | pha | lda $ESTACK_LO_HEX,x | tax | inc ${ins.callLabel},x | pla | tax" - Opcode.DEC_INDEXED_VAR_B, Opcode.DEC_INDEXED_VAR_UB -> " inx | txa | pha | lda $ESTACK_LO_HEX,x | tax | dec ${ins.callLabel},x | pla | tax" - - Opcode.NEG_B -> " jsr prog8_lib.neg_b" - Opcode.NEG_W -> " jsr prog8_lib.neg_w" - Opcode.NEG_F -> " jsr c64flt.neg_f" - Opcode.ABS_B -> " jsr prog8_lib.abs_b" - Opcode.ABS_W -> " jsr prog8_lib.abs_w" - Opcode.ABS_F -> " jsr c64flt.abs_f" - Opcode.POW_F -> " jsr c64flt.pow_f" - Opcode.INV_BYTE -> { - """ - lda $ESTACK_LO_PLUS1_HEX,x - eor #255 - sta $ESTACK_LO_PLUS1_HEX,x - """ - } - Opcode.INV_WORD -> " jsr prog8_lib.inv_word" - Opcode.NOT_BYTE -> " jsr prog8_lib.not_byte" - Opcode.NOT_WORD -> " jsr prog8_lib.not_word" - Opcode.BCS -> { - val label = ins.callLabel ?: hexVal(ins) - " bcs $label" - } - Opcode.BCC -> { - val label = ins.callLabel ?: hexVal(ins) - " bcc $label" - } - Opcode.BNEG -> { - val label = ins.callLabel ?: hexVal(ins) - " bmi $label" - } - Opcode.BPOS -> { - val label = ins.callLabel ?: hexVal(ins) - " bpl $label" - } - Opcode.BVC -> { - val label = ins.callLabel ?: hexVal(ins) - " bvc $label" - } - Opcode.BVS -> { - val label = ins.callLabel ?: hexVal(ins) - " bvs $label" - } - Opcode.BZ -> { - val label = ins.callLabel ?: hexVal(ins) - " beq $label" - } - Opcode.BNZ -> { - val label = ins.callLabel ?: hexVal(ins) - " bne $label" - } - Opcode.JZ -> { - val label = ins.callLabel ?: hexVal(ins) - """ - inx - lda $ESTACK_LO_HEX,x - beq $label - """ - } - Opcode.JZW -> { - val label = ins.callLabel ?: hexVal(ins) - """ - inx - lda $ESTACK_LO_HEX,x - beq $label - lda $ESTACK_HI_HEX,x - beq $label - """ - } - Opcode.JNZ -> { - val label = ins.callLabel ?: hexVal(ins) - """ - inx - lda $ESTACK_LO_HEX,x - bne $label - """ - } - Opcode.JNZW -> { - val label = ins.callLabel ?: hexVal(ins) - """ - inx - lda $ESTACK_LO_HEX,x - bne $label - lda $ESTACK_HI_HEX,x - bne $label - """ - } - Opcode.CAST_B_TO_UB -> "" // is a no-op, just carry on with the byte as-is - Opcode.CAST_UB_TO_B -> "" // is a no-op, just carry on with the byte as-is - Opcode.CAST_W_TO_UW -> "" // is a no-op, just carry on with the word as-is - Opcode.CAST_UW_TO_W -> "" // is a no-op, just carry on with the word as-is - Opcode.CAST_W_TO_UB -> "" // is a no-op, just carry on with the lsb of the word as-is - Opcode.CAST_W_TO_B -> "" // is a no-op, just carry on with the lsb of the word as-is - Opcode.CAST_UW_TO_UB -> "" // is a no-op, just carry on with the lsb of the uword as-is - Opcode.CAST_UW_TO_B -> "" // is a no-op, just carry on with the lsb of the uword as-is - Opcode.CAST_UB_TO_F -> " jsr c64flt.stack_ub2float" - Opcode.CAST_B_TO_F -> " jsr c64flt.stack_b2float" - Opcode.CAST_UW_TO_F -> " jsr c64flt.stack_uw2float" - Opcode.CAST_W_TO_F -> " jsr c64flt.stack_w2float" - Opcode.CAST_F_TO_UB -> " jsr c64flt.stack_float2ub" - Opcode.CAST_F_TO_B -> " jsr c64flt.stack_float2b" - Opcode.CAST_F_TO_UW -> " jsr c64flt.stack_float2uw" - Opcode.CAST_F_TO_W -> " jsr c64flt.stack_float2w" - Opcode.CAST_UB_TO_UW, Opcode.CAST_UB_TO_W -> " lda #0 | sta $ESTACK_HI_PLUS1_HEX,x" // clear the msb - Opcode.CAST_B_TO_UW, Opcode.CAST_B_TO_W -> " lda $ESTACK_LO_PLUS1_HEX,x | ${signExtendA("$ESTACK_HI_PLUS1_HEX,x")}" // sign extend the lsb - Opcode.MSB -> " lda $ESTACK_HI_PLUS1_HEX,x | sta $ESTACK_LO_PLUS1_HEX,x" - Opcode.MKWORD -> " inx | lda $ESTACK_LO_HEX,x | sta $ESTACK_HI_PLUS1_HEX,x " - - Opcode.ADD_UB, Opcode.ADD_B -> { // TODO inline better (pattern with more opcodes) - """ - lda $ESTACK_LO_PLUS2_HEX,x - clc - adc $ESTACK_LO_PLUS1_HEX,x - inx - sta $ESTACK_LO_PLUS1_HEX,x - """ - } - Opcode.SUB_UB, Opcode.SUB_B -> { // TODO inline better (pattern with more opcodes) - """ - lda $ESTACK_LO_PLUS2_HEX,x - sec - sbc $ESTACK_LO_PLUS1_HEX,x - inx - sta $ESTACK_LO_PLUS1_HEX,x - """ - } - Opcode.ADD_W, Opcode.ADD_UW -> " jsr prog8_lib.add_w" - Opcode.SUB_W, Opcode.SUB_UW -> " jsr prog8_lib.sub_w" - Opcode.MUL_B, Opcode.MUL_UB -> " jsr prog8_lib.mul_byte" - Opcode.MUL_W, Opcode.MUL_UW -> " jsr prog8_lib.mul_word" - Opcode.MUL_F -> " jsr c64flt.mul_f" - Opcode.ADD_F -> " jsr c64flt.add_f" - Opcode.SUB_F -> " jsr c64flt.sub_f" - Opcode.DIV_F -> " jsr c64flt.div_f" - Opcode.IDIV_UB -> " jsr prog8_lib.idiv_ub" - Opcode.IDIV_B -> " jsr prog8_lib.idiv_b" - Opcode.IDIV_W -> " jsr prog8_lib.idiv_w" - Opcode.IDIV_UW -> " jsr prog8_lib.idiv_uw" - - Opcode.AND_BYTE -> " jsr prog8_lib.and_b" - Opcode.OR_BYTE -> " jsr prog8_lib.or_b" - Opcode.XOR_BYTE -> " jsr prog8_lib.xor_b" - Opcode.AND_WORD -> " jsr prog8_lib.and_w" - Opcode.OR_WORD -> " jsr prog8_lib.or_w" - Opcode.XOR_WORD -> " jsr prog8_lib.xor_w" - - Opcode.BITAND_BYTE -> " jsr prog8_lib.bitand_b" - Opcode.BITOR_BYTE -> " jsr prog8_lib.bitor_b" - Opcode.BITXOR_BYTE -> " jsr prog8_lib.bitxor_b" - Opcode.BITAND_WORD -> " jsr prog8_lib.bitand_w" - Opcode.BITOR_WORD -> " jsr prog8_lib.bitor_w" - Opcode.BITXOR_WORD -> " jsr prog8_lib.bitxor_w" - - Opcode.REMAINDER_UB -> " jsr prog8_lib.remainder_ub" - Opcode.REMAINDER_UW -> " jsr prog8_lib.remainder_uw" - - Opcode.GREATER_B -> " jsr prog8_lib.greater_b" - Opcode.GREATER_UB -> " jsr prog8_lib.greater_ub" - Opcode.GREATER_W -> " jsr prog8_lib.greater_w" - Opcode.GREATER_UW -> " jsr prog8_lib.greater_uw" - Opcode.GREATER_F -> " jsr c64flt.greater_f" - - Opcode.GREATEREQ_B -> " jsr prog8_lib.greatereq_b" - Opcode.GREATEREQ_UB -> " jsr prog8_lib.greatereq_ub" - Opcode.GREATEREQ_W -> " jsr prog8_lib.greatereq_w" - Opcode.GREATEREQ_UW -> " jsr prog8_lib.greatereq_uw" - Opcode.GREATEREQ_F -> " jsr c64flt.greatereq_f" - - Opcode.EQUAL_BYTE -> " jsr prog8_lib.equal_b" - Opcode.EQUAL_WORD -> " jsr prog8_lib.equal_w" - Opcode.EQUAL_F -> " jsr c64flt.equal_f" - Opcode.NOTEQUAL_BYTE -> " jsr prog8_lib.notequal_b" - Opcode.NOTEQUAL_WORD -> " jsr prog8_lib.notequal_w" - Opcode.NOTEQUAL_F -> " jsr c64flt.notequal_f" - - Opcode.LESS_UB -> " jsr prog8_lib.less_ub" - Opcode.LESS_B -> " jsr prog8_lib.less_b" - Opcode.LESS_UW -> " jsr prog8_lib.less_uw" - Opcode.LESS_W -> " jsr prog8_lib.less_w" - Opcode.LESS_F -> " jsr c64flt.less_f" - - Opcode.LESSEQ_UB -> " jsr prog8_lib.lesseq_ub" - Opcode.LESSEQ_B -> " jsr prog8_lib.lesseq_b" - Opcode.LESSEQ_UW -> " jsr prog8_lib.lesseq_uw" - Opcode.LESSEQ_W -> " jsr prog8_lib.lesseq_w" - Opcode.LESSEQ_F -> " jsr c64flt.lesseq_f" - - Opcode.SHIFTEDL_BYTE -> " asl $ESTACK_LO_PLUS1_HEX,x" - Opcode.SHIFTEDL_WORD -> " asl $ESTACK_LO_PLUS1_HEX,x | rol $ESTACK_HI_PLUS1_HEX,x" - Opcode.SHIFTEDR_SBYTE -> " lda $ESTACK_LO_PLUS1_HEX,x | asl a | ror $ESTACK_LO_PLUS1_HEX,x" - Opcode.SHIFTEDR_UBYTE -> " lsr $ESTACK_LO_PLUS1_HEX,x" - Opcode.SHIFTEDR_SWORD -> " lda $ESTACK_HI_PLUS1_HEX,x | asl a | ror $ESTACK_HI_PLUS1_HEX,x | ror $ESTACK_LO_PLUS1_HEX,x" - Opcode.SHIFTEDR_UWORD -> " lsr $ESTACK_HI_PLUS1_HEX,x | ror $ESTACK_LO_PLUS1_HEX,x" - - else -> null - } -} diff --git a/gradle.properties b/gradle.properties index 3fd555051..73adb4134 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,6 @@ org.gradle.caching=true org.gradle.console=rich org.gradle.parallel=true -org.gradle.jvmargs=-Xmx2500M org.gradle.daemon=true kotlinVersion=1.3.61