diff --git a/compiler/res/prog8lib/c64/floats.asm b/compiler/res/prog8lib/c64/floats.asm index 3999bfaf1..bd05a1101 100644 --- a/compiler/res/prog8lib/c64/floats.asm +++ b/compiler/res/prog8lib/c64/floats.asm @@ -380,6 +380,69 @@ neg_f .proc rts .pend +var_fac1_less_f .proc + ; -- is the float in FAC1 < the variable AY? + stx P8ZP_SCRATCH_REG + jsr FCOMP + ldx P8ZP_SCRATCH_REG + cmp #255 + beq + + lda #0 + rts ++ lda #1 + rts + .pend + +var_fac1_lesseq_f .proc + ; -- is the float in FAC1 <= the variable AY? + stx P8ZP_SCRATCH_REG + jsr FCOMP + ldx P8ZP_SCRATCH_REG + cmp #0 + beq + + cmp #255 + beq + + lda #0 + rts ++ lda #1 + rts + .pend + +var_fac1_greater_f .proc + ; -- is the float in FAC1 > the variable AY? + stx P8ZP_SCRATCH_REG + jsr FCOMP + ldx P8ZP_SCRATCH_REG + cmp #1 + beq + + lda #0 ++ rts + .pend + +var_fac1_greatereq_f .proc + ; -- is the float in FAC1 >= the variable AY? + stx P8ZP_SCRATCH_REG + jsr FCOMP + ldx P8ZP_SCRATCH_REG + cmp #0 + beq + + cmp #1 + beq + + lda #0 + rts ++ lda #1 + rts + .pend + +var_fac1_notequal_f .proc + ; -- are the floats numbers in FAC1 and the variable AY *not* identical? + stx P8ZP_SCRATCH_REG + jsr FCOMP + ldx P8ZP_SCRATCH_REG + and #1 + rts + .pend + vars_equal_f .proc ; -- are the mflpt5 numbers in P8ZP_SCRATCH_W1 and AY identical? sta P8ZP_SCRATCH_W2 diff --git a/compiler/src/prog8/compiler/target/IAssemblyGenerator.kt b/compiler/src/prog8/compiler/target/IAssemblyGenerator.kt index 50992f2ce..752dcb65c 100644 --- a/compiler/src/prog8/compiler/target/IAssemblyGenerator.kt +++ b/compiler/src/prog8/compiler/target/IAssemblyGenerator.kt @@ -7,6 +7,7 @@ internal interface IAssemblyGenerator { } internal const val generatedLabelPrefix = "_prog8_label_" +internal const val subroutineFloatEvalResultVar = "_prog8_float_eval_result" internal interface IAssemblyProgram { val name: String diff --git a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt index dd8288f19..2186c004e 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt @@ -8,6 +8,7 @@ import prog8.ast.base.* import prog8.ast.expressions.* import prog8.ast.statements.* import prog8.compiler.* +import prog8.compiler.target.* import prog8.compiler.target.CompilationTarget import prog8.compiler.target.CpuType import prog8.compiler.target.IAssemblyGenerator @@ -800,7 +801,7 @@ internal class AsmGen(private val program: Program, if(sub.asmGenInfo.usedRegsaveY) out("_prog8_regsaveY .byte 0") if(sub.asmGenInfo.usedFloatEvalResultVar) - out("_prog8_float_eval_result .byte 0,0,0,0,0") + out("$subroutineFloatEvalResultVar .byte 0,0,0,0,0") vardecls2asm(sub.statements) out(" .pend\n") } diff --git a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt index d86ee616b..267ca0556 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt @@ -17,6 +17,7 @@ import prog8.compiler.target.c64.codegen.assignment.AsmAssignTarget import prog8.compiler.target.c64.codegen.assignment.AsmAssignment import prog8.compiler.target.c64.codegen.assignment.SourceStorageKind import prog8.compiler.target.c64.codegen.assignment.TargetStorageKind +import prog8.compiler.target.subroutineFloatEvalResultVar import prog8.compiler.toHex import prog8.functions.FSignature @@ -1033,7 +1034,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val } else -> { scope.asmGenInfo.usedFloatEvalResultVar = true - val variable = IdentifierReference(listOf("_prog8_float_eval_result"), value.position) + val variable = IdentifierReference(listOf(subroutineFloatEvalResultVar), value.position) val addr = AddressOf(variable, value.position) addr.linkParents(value) asmgen.assignExpressionToVariable(value, asmgen.asmVariableName(variable), DataType.FLOAT, scope) diff --git a/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt index 003d0303e..8bbd4fcf8 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt @@ -9,6 +9,7 @@ import prog8.ast.statements.Subroutine import prog8.compiler.AssemblyError import prog8.compiler.target.CompilationTarget import prog8.compiler.target.CpuType +import prog8.compiler.target.subroutineFloatEvalResultVar import prog8.compiler.toHex import prog8.functions.BuiltinFunctions import kotlin.math.absoluteValue @@ -215,11 +216,15 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge jsr floats.vars_less_f beq $jumpIfFalseLabel""") } else { - if (asmgen.options.slowCodegenWarnings) - println("warning: slow stack evaluation used (e1): '<' at ${left.position}") // TODO float via func args? - translateExpression(left) - translateExpression(right) - asmgen.out(" jsr floats.less_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") + val subroutine = left.definingSubroutine()!! + subroutine.asmGenInfo.usedFloatEvalResultVar = true + asmgen.assignExpressionToVariable(right, subroutineFloatEvalResultVar, DataType.FLOAT, subroutine) + asmgen.assignExpressionToRegister(left, RegisterOrPair.FAC1) + asmgen.out(""" + lda #<$subroutineFloatEvalResultVar + ldy #>$subroutineFloatEvalResultVar + jsr floats.var_fac1_less_f + beq $jumpIfFalseLabel""") } } @@ -256,11 +261,15 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge jsr floats.vars_lesseq_f beq $jumpIfFalseLabel""") } else { - if (asmgen.options.slowCodegenWarnings) - println("warning: slow stack evaluation used (e1): '<=' at ${left.position}") // TODO float via func args? - translateExpression(left) - translateExpression(right) - asmgen.out(" jsr floats.lesseq_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") + val subroutine = left.definingSubroutine()!! + subroutine.asmGenInfo.usedFloatEvalResultVar = true + asmgen.assignExpressionToVariable(right, subroutineFloatEvalResultVar, DataType.FLOAT, subroutine) + asmgen.assignExpressionToRegister(left, RegisterOrPair.FAC1) + asmgen.out(""" + lda #<$subroutineFloatEvalResultVar + ldy #>$subroutineFloatEvalResultVar + jsr floats.var_fac1_lesseq_f + beq $jumpIfFalseLabel""") } } @@ -297,11 +306,15 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge jsr floats.vars_less_f beq $jumpIfFalseLabel""") } else { - if (asmgen.options.slowCodegenWarnings) - println("warning: slow stack evaluation used (e1): '>' at ${left.position}") // TODO float via func args? - translateExpression(left) - translateExpression(right) - asmgen.out(" jsr floats.greater_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") + val subroutine = left.definingSubroutine()!! + subroutine.asmGenInfo.usedFloatEvalResultVar = true + asmgen.assignExpressionToVariable(right, subroutineFloatEvalResultVar, DataType.FLOAT, subroutine) + asmgen.assignExpressionToRegister(left, RegisterOrPair.FAC1) + asmgen.out(""" + lda #<$subroutineFloatEvalResultVar + ldy #>$subroutineFloatEvalResultVar + jsr floats.var_fac1_greater_f + beq $jumpIfFalseLabel""") } } @@ -338,11 +351,15 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge jsr floats.vars_lesseq_f beq $jumpIfFalseLabel""") } else { - if (asmgen.options.slowCodegenWarnings) - println("warning: slow stack evaluation used (e1): '>=' at ${left.position}") // TODO float via func args - translateExpression(left) - translateExpression(right) - asmgen.out(" jsr floats.greatereq_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") + val subroutine = left.definingSubroutine()!! + subroutine.asmGenInfo.usedFloatEvalResultVar = true + asmgen.assignExpressionToVariable(right, subroutineFloatEvalResultVar, DataType.FLOAT, subroutine) + asmgen.assignExpressionToRegister(left, RegisterOrPair.FAC1) + asmgen.out(""" + lda #<$subroutineFloatEvalResultVar + ldy #>$subroutineFloatEvalResultVar + jsr floats.var_fac1_greatereq_f + beq $jumpIfFalseLabel""") } } @@ -1115,11 +1132,15 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge jsr floats.vars_equal_f beq $jumpIfFalseLabel""") } else { - if (asmgen.options.slowCodegenWarnings) - println("warning: slow stack evaluation used (e22): '==' at ${left.position}") // TODO float via func args? - translateExpression(left) - translateExpression(right) - asmgen.out(" jsr floats.equal_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") + val subroutine = left.definingSubroutine()!! + subroutine.asmGenInfo.usedFloatEvalResultVar = true + asmgen.assignExpressionToVariable(right, subroutineFloatEvalResultVar, DataType.FLOAT, subroutine) + asmgen.assignExpressionToRegister(left, RegisterOrPair.FAC1) + asmgen.out(""" + lda #<$subroutineFloatEvalResultVar + ldy #>$subroutineFloatEvalResultVar + jsr floats.var_fac1_notequal_f + bne $jumpIfFalseLabel""") } } @@ -1196,11 +1217,15 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge jsr floats.vars_equal_f bne $jumpIfFalseLabel""") } else { - if (asmgen.options.slowCodegenWarnings) - println("warning: slow stack evaluation used (e23): '!=' at ${left.position}") // TODO float via func args? - translateExpression(left) - translateExpression(right) - asmgen.out(" jsr floats.notequal_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") + val subroutine = left.definingSubroutine()!! + subroutine.asmGenInfo.usedFloatEvalResultVar = true + asmgen.assignExpressionToVariable(right, subroutineFloatEvalResultVar, DataType.FLOAT, subroutine) + asmgen.assignExpressionToRegister(left, RegisterOrPair.FAC1) + asmgen.out(""" + lda #<$subroutineFloatEvalResultVar + ldy #>$subroutineFloatEvalResultVar + jsr floats.var_fac1_notequal_f + beq $jumpIfFalseLabel""") } } diff --git a/examples/test.p8 b/examples/test.p8 index e6510372f..4d6e2087b 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -7,52 +7,43 @@ main { sub start() { - ubyte[] ubarray = [1,2,3,4] - byte[] barray = [1,2,3,4] - uword[] uwarray = [1,2,3,4] - word[] warray = [1,2,3,4] - float[] farray = [1.1,2.2,3.3,4.4] + float fl = 2.0 + float cf = 1.5 - ubyte ub - byte bb - uword uw - word ww - float fl + if fl == cf+0.5 + txt.print(".\n") + else + txt.print("!\n") + if fl != cf+0.5 + txt.print("!\n") + else + txt.print(".\n") - fl = func(33) - floats.print_f(fl) - txt.chrout('\n') + if fl < cf+0.5 + txt.print("!\n") + else + txt.print(".\n") - const ubyte i = 2 - const ubyte j = 3 + if fl <= cf+0.5 + txt.print(".\n") + else + txt.print("!\n") - ub = ubarray[i] - txt.print_ub(ub) - txt.chrout('\n') + if fl > cf+0.5 + txt.print("!\n") + else + txt.print(".\n") - bb = barray[i] - txt.print_b(bb) - txt.chrout('\n') + if fl >= cf+0.5 + txt.print(".\n") + else + txt.print("!\n") - uw = uwarray[i] - txt.print_uw(uw) - txt.chrout('\n') - - ww = warray[i] - txt.print_w(ww) - txt.chrout('\n') - - fl = farray[i] - floats.print_f(fl) - txt.chrout('\n') - - test_stack.test() - txt.chrout('\n') } - sub func(ubyte w) -> float { - w = w*99 - return 3344.55 + sub func(float fa) -> float { + fa = fa*99.0 + return fa + 1.0 } }