diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt index 0c5419214..720a3b8e2 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt @@ -1070,11 +1070,20 @@ $repeatLabel lda $counterVar val saveA = evalBytevalueWillClobberA(ptrAndIndex.first) || evalBytevalueWillClobberA(ptrAndIndex.second) if(saveA) out(" pha") - assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y) // TODO TMP_REG_ISSUE_89 - if(saveA) - out(" pla") - out(" sta (P8ZP_SCRATCH_W2),y") + if(ptrAndIndex.second.isSimple) { + assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.UWORD, null) + assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y) + if(saveA) + out(" pla") + out(" sta (P8ZP_SCRATCH_W2),y") + } else { + pushCpuStack(DataType.UBYTE, ptrAndIndex.second) + assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.UWORD, null) + restoreRegisterStack(CpuRegister.Y, true) + if(saveA) + out(" pla") + out(" sta (P8ZP_SCRATCH_W2),y") + } } } else { if(pointervar!=null && isZpVar(pointervar)) { @@ -1082,9 +1091,16 @@ $repeatLabel lda $counterVar out(" lda (${asmSymbolName(pointervar)}),y") } else { // copy the pointer var to zp first - assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y) // TODO TMP_REG_ISSUE_89 - out(" lda (P8ZP_SCRATCH_W2),y") + if(ptrAndIndex.second.isSimple) { + assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.UWORD, null) + assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y) + out(" lda (P8ZP_SCRATCH_W2),y") + } else { + pushCpuStack(DataType.UBYTE, ptrAndIndex.second) + assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.UWORD, null) + restoreRegisterStack(CpuRegister.Y, false) + out(" lda (P8ZP_SCRATCH_W2),y") + } } } return true @@ -1578,8 +1594,14 @@ $repeatLabel lda $counterVar if(byteJumpForSimpleRightOperand(left, right, ::code)) return - assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) - assignExpressionToRegister(left, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 + if(left.isSimple) { + assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) + assignExpressionToRegister(left, RegisterOrPair.A) + } else { + pushCpuStack(DataType.UBYTE, left) + assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) + out(" pla") + } return code("P8ZP_SCRATCH_B1") } @@ -1613,8 +1635,14 @@ $repeatLabel lda $counterVar if(byteJumpForSimpleRightOperand(left, right, ::code)) return - assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) - assignExpressionToRegister(left, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 + if(left.isSimple) { + assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) + assignExpressionToRegister(left, RegisterOrPair.A) + } else { + pushCpuStack(DataType.UBYTE, left) + assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) + out(" pla") + } return code("P8ZP_SCRATCH_B1") } @@ -1650,8 +1678,15 @@ $repeatLabel lda $counterVar if(wordJumpForSimpleRightOperands(left, right, ::code)) return - assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(left, RegisterOrPair.AY) // TODO TMP_REG_ISSUE_89 + if(left.isSimple) { + assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) + assignExpressionToRegister(left, RegisterOrPair.AY) + } else { + pushCpuStack(DataType.UWORD, left) + assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) + restoreRegisterStack(CpuRegister.Y, false) + restoreRegisterStack(CpuRegister.A, false) + } return out(" jsr prog8_lib.reg_less_uw | beq $jumpIfFalseLabel") } @@ -1689,8 +1724,15 @@ $repeatLabel lda $counterVar if(wordJumpForSimpleRightOperands(left, right, ::code)) return - assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(left, RegisterOrPair.AY) // TODO TMP_REG_ISSUE_89 + if(left.isSimple) { + assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.WORD, null) + assignExpressionToRegister(left, RegisterOrPair.AY) + } else { + pushCpuStack(DataType.WORD, left) + assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.WORD, null) + restoreRegisterStack(CpuRegister.Y, false) + restoreRegisterStack(CpuRegister.A, false) + } return out(" jsr prog8_lib.reg_less_w | beq $jumpIfFalseLabel") } @@ -1729,8 +1771,14 @@ $repeatLabel lda $counterVar if(byteJumpForSimpleRightOperand(left, right, ::code)) return - assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) - assignExpressionToRegister(left, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 + if(left.isSimple) { + assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) + assignExpressionToRegister(left, RegisterOrPair.A) + } else { + pushCpuStack(DataType.UBYTE, left) + assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) + out(" pla") + } return code("P8ZP_SCRATCH_B1") } @@ -1766,8 +1814,14 @@ $repeatLabel lda $counterVar if(byteJumpForSimpleRightOperand(left, right, ::code)) return - assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) - assignExpressionToRegister(left, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 + if(left.isSimple) { + assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.BYTE, null) + assignExpressionToRegister(left, RegisterOrPair.A) + } else { + pushCpuStack(DataType.BYTE, left) + assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.BYTE, null) + out(" pla") + } return code("P8ZP_SCRATCH_B1") } @@ -1809,8 +1863,15 @@ $repeatLabel lda $counterVar if(wordJumpForSimpleRightOperands(left, right, ::code)) return - assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(left, RegisterOrPair.AY) // TODO TMP_REG_ISSUE_89 + if(left.isSimple) { + assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) + assignExpressionToRegister(left, RegisterOrPair.AY) + } else { + pushCpuStack(DataType.UWORD, left) + assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) + restoreRegisterStack(CpuRegister.Y, false) + restoreRegisterStack(CpuRegister.A, false) + } return code("P8ZP_SCRATCH_W2+1", "P8ZP_SCRATCH_W2") } @@ -1853,8 +1914,15 @@ $repeatLabel lda $counterVar if(wordJumpForSimpleLeftOperand(left, right, ::code)) return - assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(right, RegisterOrPair.AY) // TODO TMP_REG_ISSUE_89 + if(right.isSimple) { + assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.WORD, null) + assignExpressionToRegister(right, RegisterOrPair.AY) + } else { + pushCpuStack(DataType.WORD, right) + assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.WORD, null) + restoreRegisterStack(CpuRegister.Y, false) + restoreRegisterStack(CpuRegister.A, false) + } return out(" jsr prog8_lib.reg_less_w | beq $jumpIfFalseLabel") } @@ -1894,8 +1962,14 @@ $repeatLabel lda $counterVar if(byteJumpForSimpleRightOperand(left, right, ::code)) return - assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) - assignExpressionToRegister(left, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 + if(left.isSimple) { + assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) + assignExpressionToRegister(left, RegisterOrPair.A) + } else { + pushCpuStack(DataType.UBYTE, left) + assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) + out(" pla") + } return code("P8ZP_SCRATCH_B1") } @@ -1931,8 +2005,14 @@ $repeatLabel lda $counterVar if(byteJumpForSimpleRightOperand(left, right, ::code)) return - assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) - assignExpressionToRegister(left, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 + if(left.isSimple) { + assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.BYTE, null) + assignExpressionToRegister(left, RegisterOrPair.A) + } else { + pushCpuStack(DataType.BYTE, left) + assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.BYTE, null) + out(" pla") + } return code("P8ZP_SCRATCH_B1") } @@ -1976,8 +2056,15 @@ $repeatLabel lda $counterVar if(wordJumpForSimpleRightOperands(left, right, ::code)) return - assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(left, RegisterOrPair.AY) // TODO TMP_REG_ISSUE_89 + if(left.isSimple) { + assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) + assignExpressionToRegister(left, RegisterOrPair.AY) + } else { + pushCpuStack(DataType.UWORD, left) + assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) + restoreRegisterStack(CpuRegister.Y, false) + restoreRegisterStack(CpuRegister.A, false) + } return out(" jsr prog8_lib.reg_lesseq_uw | beq $jumpIfFalseLabel") } @@ -2024,8 +2111,15 @@ $repeatLabel lda $counterVar return code(asmVariableName(left)) } - assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(right, RegisterOrPair.AY) // TODO TMP_REG_ISSUE_89 + if(right.isSimple) { + assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.WORD, null) + assignExpressionToRegister(right, RegisterOrPair.AY) + } else { + pushCpuStack(DataType.WORD, right) + assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.WORD, null) + restoreRegisterStack(CpuRegister.Y, false) + restoreRegisterStack(CpuRegister.A, false) + } return out(" jsr prog8_lib.reg_lesseq_w | beq $jumpIfFalseLabel") } @@ -2061,8 +2155,14 @@ $repeatLabel lda $counterVar if(byteJumpForSimpleRightOperand(left, right, ::code)) return - assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) - assignExpressionToRegister(left, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 + if(left.isSimple) { + assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) + assignExpressionToRegister(left, RegisterOrPair.A) + } else { + pushCpuStack(DataType.UBYTE, left) + assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) + out(" pla") + } return code("P8ZP_SCRATCH_B1") } @@ -2095,8 +2195,14 @@ $repeatLabel lda $counterVar if(byteJumpForSimpleRightOperand(left, right, ::code)) return - assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) - assignExpressionToRegister(left, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 + if(left.isSimple) { + assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.BYTE, null) + assignExpressionToRegister(left, RegisterOrPair.A) + } else { + pushCpuStack(DataType.BYTE, left) + assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.BYTE, null) + out(" pla") + } return code("P8ZP_SCRATCH_B1") } @@ -2131,8 +2237,15 @@ $repeatLabel lda $counterVar if(wordJumpForSimpleRightOperands(left, right, ::code)) return - assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(right, RegisterOrPair.AY) // TODO TMP_REG_ISSUE_89 + if(right.isSimple) { + assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null) + assignExpressionToRegister(right, RegisterOrPair.AY) + } else { + pushCpuStack(DataType.UWORD, right) + assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null) + restoreRegisterStack(CpuRegister.Y, false) + restoreRegisterStack(CpuRegister.A, false) + } return out(" jsr prog8_lib.reg_lesseq_uw | beq $jumpIfFalseLabel") } @@ -2170,8 +2283,15 @@ $repeatLabel lda $counterVar if(wordJumpForSimpleRightOperands(left, right, ::code)) return - assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(left, RegisterOrPair.AY) // TODO TMP_REG_ISSUE_89 + if(left.isSimple) { + assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.WORD, null) + assignExpressionToRegister(left, RegisterOrPair.AY) + } else { + pushCpuStack(DataType.WORD, left) + assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.WORD, null) + restoreRegisterStack(CpuRegister.Y, false) + restoreRegisterStack(CpuRegister.A, false) + } return out(" jsr prog8_lib.reg_lesseq_w | beq $jumpIfFalseLabel") } @@ -2206,8 +2326,17 @@ $repeatLabel lda $counterVar if(byteJumpForSimpleRightOperand(left, right, ::code)) return - assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) - assignExpressionToRegister(left, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 + if(left.isSimple) { + assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) + assignExpressionToRegister(left, RegisterOrPair.A) + } else if(right.isSimple) { + assignExpressionToVariable(left, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) + assignExpressionToRegister(right, RegisterOrPair.A) + } else { + pushCpuStack(DataType.UBYTE, left) + assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) + restoreRegisterStack(CpuRegister.A, false) + } out(" cmp P8ZP_SCRATCH_B1 | bne $jumpIfFalseLabel") } @@ -2243,8 +2372,17 @@ $repeatLabel lda $counterVar if(byteJumpForSimpleRightOperand(left, right, ::code)) return - assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) - assignExpressionToRegister(left, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 + if(left.isSimple) { + assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) + assignExpressionToRegister(left, RegisterOrPair.A) + } else if(right.isSimple) { + assignExpressionToVariable(left, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) + assignExpressionToRegister(right, RegisterOrPair.A) + } else { + pushCpuStack(DataType.UBYTE, left) + assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) + restoreRegisterStack(CpuRegister.A, false) + } return code("P8ZP_SCRATCH_B1") } @@ -2310,8 +2448,20 @@ $repeatLabel lda $counterVar """) } else -> { - assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(left, RegisterOrPair.AY) // TODO TMP_REG_ISSUE_89 + if(left.isSimple) { + assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) + assignExpressionToRegister(left, RegisterOrPair.AY) + } else if(right.isSimple) { + assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null) + assignExpressionToRegister(right, RegisterOrPair.AY) + } else { + pushCpuStack(DataType.UWORD, left) + assignExpressionToRegister(right, RegisterOrPair.AY) + out(" sta P8ZP_SCRATCH_REG") + popCpuStack(DataType.UWORD, "P8ZP_SCRATCH_W2") + out(" lda P8ZP_SCRATCH_REG") + // TODO optimize this path..... CMP_OPT + } out(""" cmp P8ZP_SCRATCH_W2 bne $jumpIfFalseLabel @@ -2386,8 +2536,20 @@ $repeatLabel lda $counterVar +""") } else -> { - assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) - assignExpressionToRegister(left, RegisterOrPair.AY) // TODO TMP_REG_ISSUE_89 + if(left.isSimple) { + assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) + assignExpressionToRegister(left, RegisterOrPair.AY) + } else if (right.isSimple) { + assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null) + assignExpressionToRegister(right, RegisterOrPair.AY) + } else { + pushCpuStack(DataType.UWORD, left) + assignExpressionToRegister(right, RegisterOrPair.AY) + out(" sta P8ZP_SCRATCH_REG") + popCpuStack(DataType.UWORD, "P8ZP_SCRATCH_W2") + out(" lda P8ZP_SCRATCH_REG") + // TODO optimize this path..... CMP_OPT + } out(""" cmp P8ZP_SCRATCH_W2 bne + @@ -2868,17 +3030,27 @@ $repeatLabel lda $counterVar } } + internal fun popCpuStack(dt: DataType, targetAsmVarName: String) { + when(dt) { + in ByteDatatypes -> out(" pla | sta $targetAsmVarName") + in WordDatatypes -> out(" pla | sta $targetAsmVarName+1 | pla | sta $targetAsmVarName") + else -> throw AssemblyError("can't pop $dt") + } + } + internal fun pushCpuStack(dt: DataType, value: Expression) { val signed = value.inferType(program).oneOf(DataType.BYTE, DataType.WORD) if(dt in ByteDatatypes) { assignExpressionToRegister(value, RegisterOrPair.A, signed) out(" pha") - } else { + } else if(dt in WordDatatypes) { assignExpressionToRegister(value, RegisterOrPair.AY, signed) if (isTargetCpu(CpuType.CPU65c02)) out(" pha | phy") else out(" pha | tya | pha") + } else { + throw AssemblyError("can't push $dt") } } diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt index af79b9b14..7ee7ef7df 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt @@ -254,15 +254,27 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, asmgen.assignExpressionToRegister(arg1, RegisterOrPair.A) asmgen.out(" cmp ${arg2.addressExpression.constValue(program)!!.number.toHex()}") } else { - asmgen.assignExpressionToVariable(arg2, "P8ZP_SCRATCH_B1", DataType.UBYTE, (fcall as Node).definingSubroutine) - asmgen.assignExpressionToRegister(arg1, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 - asmgen.out(" cmp P8ZP_SCRATCH_B1") + if(arg1.isSimple) { + asmgen.assignExpressionToVariable(arg2, "P8ZP_SCRATCH_B1", DataType.UBYTE, (fcall as Node).definingSubroutine) + asmgen.assignExpressionToRegister(arg1, RegisterOrPair.A) + asmgen.out(" cmp P8ZP_SCRATCH_B1") + } else { + asmgen.pushCpuStack(DataType.UBYTE, arg1) + asmgen.assignExpressionToVariable(arg2, "P8ZP_SCRATCH_B1", DataType.UBYTE, (fcall as Node).definingSubroutine) + asmgen.out(" pla | cmp P8ZP_SCRATCH_B1") + } } } else -> { - asmgen.assignExpressionToVariable(arg2, "P8ZP_SCRATCH_B1", DataType.UBYTE, (fcall as Node).definingSubroutine) - asmgen.assignExpressionToRegister(arg1, RegisterOrPair.A) // TODO TMP_REG_ISSUE_89 - asmgen.out(" cmp P8ZP_SCRATCH_B1") + if(arg1.isSimple) { + asmgen.assignExpressionToVariable(arg2, "P8ZP_SCRATCH_B1", DataType.UBYTE, (fcall as Node).definingSubroutine) + asmgen.assignExpressionToRegister(arg1, RegisterOrPair.A) + asmgen.out(" cmp P8ZP_SCRATCH_B1") + } else { + asmgen.pushCpuStack(DataType.UBYTE, arg1) + asmgen.assignExpressionToVariable(arg2, "P8ZP_SCRATCH_B1", DataType.UBYTE, (fcall as Node).definingSubroutine) + asmgen.out(" pla | cmp P8ZP_SCRATCH_B1") + } } } } else @@ -288,13 +300,25 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, +""") } else -> { - asmgen.assignExpressionToVariable(arg2, "P8ZP_SCRATCH_W1", DataType.UWORD, (fcall as Node).definingSubroutine) - asmgen.assignExpressionToRegister(arg1, RegisterOrPair.AY) // TODO TMP_REG_ISSUE_89 - asmgen.out(""" - cpy P8ZP_SCRATCH_W1+1 - bne + - cmp P8ZP_SCRATCH_W1 -+""") + if(arg1.isSimple) { + asmgen.assignExpressionToVariable(arg2, "P8ZP_SCRATCH_W1", DataType.UWORD, (fcall as Node).definingSubroutine) + asmgen.assignExpressionToRegister(arg1, RegisterOrPair.AY) + asmgen.out(""" + cpy P8ZP_SCRATCH_W1+1 + bne + + cmp P8ZP_SCRATCH_W1 + +""") + } else { + asmgen.pushCpuStack(DataType.UWORD, arg1) + asmgen.assignExpressionToVariable(arg2, "P8ZP_SCRATCH_W1", DataType.UWORD, (fcall as Node).definingSubroutine) + asmgen.restoreRegisterStack(CpuRegister.Y, false) + asmgen.restoreRegisterStack(CpuRegister.A, false) + asmgen.out(""" + cpy P8ZP_SCRATCH_W1+1 + bne + + cmp P8ZP_SCRATCH_W1 + +""") + } } } } else diff --git a/docs/source/todo.rst b/docs/source/todo.rst index bd022e46a..8735f62bf 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,7 +3,8 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- attempt to fix the expression codegen bug with reused temp vars (github #89) search for 'TMP_REG_ISSUE_89' +- optimize cmp's that can use the variable directly out(" cmp $..... +- optimize cmp word equal/notequal search for CMP_OPT - 6502 codegen: make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as ``p8v_``? Or not worth it (most 3 letter opcodes as variables are nonsensical anyway) then we can get rid of the instruction lists in the machinedefinitions as well. This is already no problem at all in the IR codegen. - create BSS section in output program and put StStaticVariables in there with bss=true. Don't forget to add init code to zero out everything that was put in bss. If array in bss->only zero ONCE! So requires self-modifying code diff --git a/examples/test.p8 b/examples/test.p8 index 29d163b4e..53672cb17 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,12 +1,66 @@ %import textio -%zeropage basicsafe +%zeropage dontuse + main { bool[1] expected = [ true ] + uword[1] expectedw = [4242 ] sub get() -> bool { - txt.print("get() called. ") + %asm {{ + stz P8ZP_SCRATCH_W1 + stz P8ZP_SCRATCH_W1+1 + stz P8ZP_SCRATCH_W2 + stz P8ZP_SCRATCH_W2+1 + stz P8ZP_SCRATCH_REG + stz P8ZP_SCRATCH_B1 + }} return true } + sub same() -> bool { + %asm {{ + stz P8ZP_SCRATCH_W1 + stz P8ZP_SCRATCH_W1+1 + stz P8ZP_SCRATCH_W2 + stz P8ZP_SCRATCH_W2+1 + stz P8ZP_SCRATCH_REG + stz P8ZP_SCRATCH_B1 + }} + return true + } + + sub getw() -> uword { + %asm {{ + stz P8ZP_SCRATCH_W1 + stz P8ZP_SCRATCH_W1+1 + stz P8ZP_SCRATCH_W2 + stz P8ZP_SCRATCH_W2+1 + stz P8ZP_SCRATCH_REG + stz P8ZP_SCRATCH_B1 + }} + return 4242 + } + sub samew() -> uword { + %asm {{ + stz P8ZP_SCRATCH_W1 + stz P8ZP_SCRATCH_W1+1 + stz P8ZP_SCRATCH_W2 + stz P8ZP_SCRATCH_W2+1 + stz P8ZP_SCRATCH_REG + stz P8ZP_SCRATCH_B1 + }} + return 4242 + } + sub one() -> ubyte { + %asm {{ + stz P8ZP_SCRATCH_W1 + stz P8ZP_SCRATCH_W1+1 + stz P8ZP_SCRATCH_W2 + stz P8ZP_SCRATCH_W2+1 + stz P8ZP_SCRATCH_REG + stz P8ZP_SCRATCH_B1 + }} + return 1 + } sub start() { if get() == expected[0] @@ -19,5 +73,96 @@ main { txt.print("ok\n") else txt.print("fail\n") + + if getw() == expectedw[0] + txt.print("ok\n") + else + txt.print("fail\n") + + ; this is working fine: + if expectedw[0] == getw() + txt.print("ok\n") + else + txt.print("fail\n") + + ; unquals + + if get() != expected[0] + txt.print("fail\n") + else + txt.print("ok\n") + + ; this is working fine: + if expected[0] != get() + txt.print("fail\n") + else + txt.print("ok\n") + + if getw() != expectedw[0] + txt.print("fail\n") + else + txt.print("ok\n") + + ; this is working fine: + if expectedw[0] != getw() + txt.print("fail\n") + else + txt.print("ok\n") + + ; now with 2 non-simple operands: + if get() == same() + txt.print("ok\n") + else + txt.print("fail\n") + + ; this is working fine: + if same() == get() + txt.print("ok\n") + else + txt.print("fail\n") + + if getw() == samew() + txt.print("ok\n") + else + txt.print("fail\n") + + ; this is working fine: + if samew() == getw() + txt.print("ok\n") + else + txt.print("fail\n") + + ; unquals + + if get() != same() + txt.print("fail\n") + else + txt.print("ok\n") + + ; this is working fine: + if same() != get() + txt.print("fail\n") + else + txt.print("ok\n") + + if getw() != samew() + txt.print("fail\n") + else + txt.print("ok\n") + + ; this is working fine: + if samew() != getw() + txt.print("fail\n") + else + txt.print("ok\n") + + + ; pointer stuff + uword ptr = $4000 + @(ptr+one()) = 42 + if @(ptr+one()) == 42 + txt.print("ok\n") + else + txt.print("fail\n") } }