diff --git a/compiler/src/prog8/ast/processing/AstChecker.kt b/compiler/src/prog8/ast/processing/AstChecker.kt index 531e3ebb1..6346d1234 100644 --- a/compiler/src/prog8/ast/processing/AstChecker.kt +++ b/compiler/src/prog8/ast/processing/AstChecker.kt @@ -857,7 +857,7 @@ internal class AstChecker(private val program: Program, } } if(target.name=="swap") { - // swap() is a bit weird because this one is translated into a sequence of bytecodes, instead of being an actual function call + // swap() is a bit weird because this one is translated into a operations directly, instead of being a function call val dt1 = args[0].inferType(program)!! val dt2 = args[1].inferType(program)!! if (dt1 != dt2) diff --git a/compiler/src/prog8/ast/processing/StatementReorderer.kt b/compiler/src/prog8/ast/processing/StatementReorderer.kt index d9d506c6a..533bc2148 100644 --- a/compiler/src/prog8/ast/processing/StatementReorderer.kt +++ b/compiler/src/prog8/ast/processing/StatementReorderer.kt @@ -298,7 +298,6 @@ internal class StatementReorderer(private val program: Program): IAstModifyingVi } } is BuiltinFunctionStatementPlaceholder -> { - // if(sub.name in setOf("lsl", "lsr", "rol", "ror", "rol2", "ror2", "memset", "memcopy", "memsetw", "swap")) val func = BuiltinFunctions.getValue(sub.name) if(func.pure) { // non-pure functions don't get automatic typecasts because sometimes they act directly on their parameters diff --git a/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt b/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt index 68f50d3aa..7b32d11b0 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt @@ -582,7 +582,7 @@ internal class AsmGen2(val program: Program, } } - private fun translate(stmt: Statement) { + internal fun translate(stmt: Statement) { outputSourceLine(stmt) when(stmt) { is VarDecl, is StructDecl, is NopStatement -> {} @@ -2172,7 +2172,7 @@ $endLabel""") } } - private fun assignFromEvalResult(target: AssignTarget) { + internal fun assignFromEvalResult(target: AssignTarget) { val targetIdent = target.identifier when { target.register!=null -> { @@ -2580,7 +2580,34 @@ $endLabel""") targetArrayIdx!=null -> { val index = targetArrayIdx.arrayspec.index val targetName = asmIdentifierName(targetArrayIdx.identifier) - TODO("assign float 0.0 to array $targetName [ $index ]") + if(index is NumericLiteralValue) { + val indexValue = index.number.toInt() * MachineDefinition.Mflpt5.MemorySize + out(""" + lda #0 + sta $targetName+$indexValue + sta $targetName+$indexValue+1 + sta $targetName+$indexValue+2 + sta $targetName+$indexValue+3 + sta $targetName+$indexValue+4 + """) + } else { + translateExpression(index) + out(""" + inx + lda $ESTACK_LO_HEX,x + asl a + asl a + clc + adc $ESTACK_LO_HEX,x + tay + lda #0 + sta $targetName,y + sta $targetName+1,y + sta $targetName+2,y + sta $targetName+3,y + sta $targetName+4,y + """) // TODO use a subroutine for this + } } else -> TODO("assign float 0.0 to $target") } @@ -2608,7 +2635,18 @@ $endLabel""") val arrayVarName = asmIdentifierName(targetArrayIdx.identifier) if(index is NumericLiteralValue) { val indexValue = index.number.toInt() * MachineDefinition.Mflpt5.MemorySize - out(" lda #<$arrayVarName+$indexValue | ldy #>$arrayVarName+$indexValue | jsr c64flt.pop_float") + out(""" + lda $constFloat + sta $arrayVarName+$indexValue + lda $constFloat+1 + sta $arrayVarName+$indexValue+1 + lda $constFloat+2 + sta $arrayVarName+$indexValue+2 + lda $constFloat+3 + sta $arrayVarName+$indexValue+3 + lda $constFloat+4 + sta $arrayVarName+$indexValue+4 + """) } else { translateArrayIndexIntoA(targetArrayIdx) out(""" diff --git a/compiler/src/prog8/compiler/target/c64/codegen2/AsmOptimizer.kt b/compiler/src/prog8/compiler/target/c64/codegen2/AsmOptimizer.kt index 8ed6aad5a..a20e5cac6 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen2/AsmOptimizer.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen2/AsmOptimizer.kt @@ -89,7 +89,6 @@ fun optimizeUselessStackByteWrites(linesByFour: List>> lines[1].value.trim()=="dex" && lines[2].value.trim()=="inx" && lines[3].value.trim()=="lda $ESTACK_LO_HEX,x") { - removeLines.add(lines[0].index) removeLines.add(lines[1].index) removeLines.add(lines[2].index) removeLines.add(lines[3].index) diff --git a/compiler/src/prog8/compiler/target/c64/codegen2/BuiltinFunctionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen2/BuiltinFunctionsAsmGen.kt index 7a9b8d5c9..20cfe5455 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen2/BuiltinFunctionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen2/BuiltinFunctionsAsmGen.kt @@ -7,6 +7,9 @@ import prog8.ast.base.DataType import prog8.ast.base.Register import prog8.ast.base.WordDatatypes import prog8.ast.expressions.* +import prog8.ast.statements.AssignTarget +import prog8.ast.statements.Assignment +import prog8.ast.statements.DirectMemoryWrite import prog8.ast.statements.FunctionCallStatement import prog8.compiler.CompilationOptions import prog8.compiler.Zeropage @@ -67,6 +70,17 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, else -> throw AssemblyError("weird type") } } + "swap" -> { + val first = fcall.arglist[0] + val second = fcall.arglist[1] + asmgen.translateExpression(first) + asmgen.translateExpression(second) + // pop in reverse order + val firstTarget = AssignTarget.fromExpr(first) + val secondTarget = AssignTarget.fromExpr(second) + asmgen.assignFromEvalResult(firstTarget) + asmgen.assignFromEvalResult(secondTarget) + } // TODO: any(f), all(f), max(f), min(f), sum(f) "sin", "cos", "tan", "atan", "ln", "log2", "sqrt", "rad", diff --git a/examples/test.p8 b/examples/test.p8 index 86634d0a8..326933643 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,17 +1,57 @@ %import c64utils %import c64lib +%import c64flt %zeropage dontuse + main { sub start() { - for ubyte ub1 in 10 to 20 { - for ubyte ub2 in ub1 to 30 { - c64scr.print_ub(ub2) - c64.CHROUT(',') - } - c64.CHROUT('\n') - } + ubyte ub1 = 123 + ubyte ub2 = 222 + uword uw = 1111 + uword uw2 = 2222 + word[] warr = [1111, 2222] + float[] farr = [1.111, 2.222] + + c64scr.print_ub(ub1) + c64.CHROUT(',') + c64scr.print_ub(ub2) + c64.CHROUT('\n') + c64scr.print_uw(uw) + c64.CHROUT(',') + c64scr.print_uw(uw2) + c64.CHROUT('\n') + c64scr.print_w(warr[0]) + c64.CHROUT(',') + c64scr.print_w(warr[1]) + c64.CHROUT('\n') + c64flt.print_f(farr[0]) + c64.CHROUT(',') + c64flt.print_f(farr[1]) + c64.CHROUT('\n') + + swap(ub1, ub2) + swap(uw,uw2) + swap(warr[0], warr[1]) + swap(farr[0], farr[1]) ; TODO CRASHES + + c64scr.print_ub(ub1) + c64.CHROUT(',') + c64scr.print_ub(ub2) + c64.CHROUT('\n') + c64scr.print_uw(uw) + c64.CHROUT(',') + c64scr.print_uw(uw2) + c64.CHROUT('\n') + c64scr.print_w(warr[0]) + c64.CHROUT(',') + c64scr.print_w(warr[1]) + c64.CHROUT('\n') + c64flt.print_f(farr[0]) + c64.CHROUT(',') + c64flt.print_f(farr[1]) + c64.CHROUT('\n') } } diff --git a/examples/testarrays.p8 b/examples/testarrays.p8 index 793e0a33b..9f505035c 100644 --- a/examples/testarrays.p8 +++ b/examples/testarrays.p8 @@ -2,6 +2,10 @@ %zeropage basicsafe %option enable_floats +; TODO complete codegeneration for all lines in this + + + main { sub start() { @@ -117,28 +121,28 @@ main { muwarray[2] = uw mflarray[2] = fl -; s1[A] = ub -; s2[A] = ub -; barray[A] = bb -; ubarray[A] = ub -; warray[A] = ww -; uwarray[A] = uw -; flarray[A] = fl -; -; s1[bb] = ub -; s2[bb] = ub -; barray[bb] = bb -; ubarray[bb] = ub -; warray[bb] = ww -; uwarray[bb] = uw -; flarray[bb] = fl -; -; s1[bb*3] = ub -; s2[bb*3] = ub -; barray[bb*3] = bb -; ubarray[bb*3] = ub -; warray[bb*3] = ww -; uwarray[bb*3] = uw -; flarray[bb*3] = fl + s1[A] = ub + s2[A] = ub + barray[A] = bb + ubarray[A] = ub + warray[A] = ww + uwarray[A] = uw + flarray[A] = fl + + s1[bb] = ub + s2[bb] = ub + barray[bb] = bb + ubarray[bb] = ub + warray[bb] = ww + uwarray[bb] = uw + flarray[bb] = fl + + s1[bb*3] = ub + s2[bb*3] = ub + barray[bb*3] = bb + ubarray[bb*3] = ub + warray[bb*3] = ww + uwarray[bb*3] = uw + flarray[bb*3] = fl } }