diff --git a/compiler/res/prog8lib/c64/floats.asm b/compiler/res/prog8lib/c64/floats.asm index 45ffe745d..b64dcb1c3 100644 --- a/compiler/res/prog8lib/c64/floats.asm +++ b/compiler/res/prog8lib/c64/floats.asm @@ -380,6 +380,36 @@ neg_f .proc rts .pend +vars_equal_f .proc + ; -- are the mflpt5 numbers in P8ZP_SCRATCH_W1 and AY identical? + sta P8ZP_SCRATCH_W2 + sty P8ZP_SCRATCH_W2+1 + ldy #0 + lda (P8ZP_SCRATCH_W1),y + cmp (P8ZP_SCRATCH_W2),y + bne _false + iny + lda (P8ZP_SCRATCH_W1),y + cmp (P8ZP_SCRATCH_W2),y + bne _false + iny + lda (P8ZP_SCRATCH_W1),y + cmp (P8ZP_SCRATCH_W2),y + bne _false + iny + lda (P8ZP_SCRATCH_W1),y + cmp (P8ZP_SCRATCH_W2),y + bne _false + iny + lda (P8ZP_SCRATCH_W1),y + cmp (P8ZP_SCRATCH_W2),y + bne _false + lda #1 + rts +_false lda #0 + rts + .pend + equal_f .proc ; -- are the two mflpt5 numbers on the stack identical? inx diff --git a/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt index 98233f9c9..22e931993 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt @@ -136,72 +136,44 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } "<" -> { when(dt) { - DataType.UBYTE -> translateUbyteLessJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) - DataType.BYTE -> translateByteLessJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) - DataType.UWORD -> translateUwordLessJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) - DataType.WORD -> translateWordLessJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) - DataType.FLOAT -> { - // todo via func args - if(asmgen.options.slowCodegenWarnings) - println("warning: slow stack evaluation used (e1): '<' at ${left.position}") // TODO float - translateExpression(left) - translateExpression(right) - asmgen.out(" jsr floats.less_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") - } + DataType.UBYTE -> translateUbyteLessJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) + DataType.BYTE -> translateByteLessJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) + DataType.UWORD -> translateUwordLessJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) + DataType.WORD -> translateWordLessJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) + DataType.FLOAT -> translateFloatLessJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) DataType.STR -> translateStringLessJump(left as IdentifierReference, right as IdentifierReference, jumpIfFalseLabel) else -> throw AssemblyError("weird operand datatype") } } "<=" -> { when(dt) { - DataType.UBYTE -> translateUbyteLessOrEqualJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) - DataType.BYTE -> translateByteLessOrEqualJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) - DataType.UWORD -> translateUwordLessOrEqualJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) - DataType.WORD -> translateWordLessOrEqualJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) - DataType.FLOAT -> { - // todo via func args - if(asmgen.options.slowCodegenWarnings) - println("warning: slow stack evaluation used (e1): '<=' at ${left.position}") // TODO float - translateExpression(left) - translateExpression(right) - asmgen.out(" jsr floats.lesseq_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") - } + DataType.UBYTE -> translateUbyteLessOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) + DataType.BYTE -> translateByteLessOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) + DataType.UWORD -> translateUwordLessOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) + DataType.WORD -> translateWordLessOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) + DataType.FLOAT -> translateFloatLessOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) DataType.STR -> translateStringLessOrEqualJump(left as IdentifierReference, right as IdentifierReference, jumpIfFalseLabel) else -> throw AssemblyError("weird operand datatype") } } ">" -> { when(dt) { - DataType.UBYTE -> translateUbyteGreaterJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) - DataType.BYTE -> translateByteGreaterJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) - DataType.UWORD -> translateUwordGreaterJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) - DataType.WORD -> translateWordGreaterJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) - DataType.FLOAT -> { - // todo via func args - if(asmgen.options.slowCodegenWarnings) - println("warning: slow stack evaluation used (e1): '>' at ${left.position}") // TODO float - translateExpression(left) - translateExpression(right) - asmgen.out(" jsr floats.greater_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") - } + DataType.UBYTE -> translateUbyteGreaterJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) + DataType.BYTE -> translateByteGreaterJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) + DataType.UWORD -> translateUwordGreaterJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) + DataType.WORD -> translateWordGreaterJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) + DataType.FLOAT -> translateFloatGreaterJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) DataType.STR -> translateStringGreaterJump(left as IdentifierReference, right as IdentifierReference, jumpIfFalseLabel) else -> throw AssemblyError("weird operand datatype") } } ">=" -> { when(dt) { - DataType.UBYTE -> translateUbyteGreaterOrEqualJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) - DataType.BYTE -> translateByteGreaterOrEqualJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) - DataType.UWORD -> translateUwordGreaterOrEqualJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) - DataType.WORD -> translateWordGreaterOrEqualJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel) - DataType.FLOAT -> { - // todo via func args - if(asmgen.options.slowCodegenWarnings) - println("warning: slow stack evaluation used (e1): '>=' at ${left.position}") // TODO float - translateExpression(left) - translateExpression(right) - asmgen.out(" jsr floats.greatereq_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") - } + DataType.UBYTE -> translateUbyteGreaterOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) + DataType.BYTE -> translateByteGreaterOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) + DataType.UWORD -> translateUwordGreaterOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) + DataType.WORD -> translateWordGreaterOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) + DataType.FLOAT -> translateFloatGreaterOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel) DataType.STR -> translateStringGreaterOrEqualJump(left as IdentifierReference, right as IdentifierReference, jumpIfFalseLabel) else -> throw AssemblyError("weird operand datatype") } @@ -209,6 +181,38 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + private fun translateFloatLessJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { + 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") + } + + private fun translateFloatLessOrEqualJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { + 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") + } + + private fun translateFloatGreaterJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { + 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") + } + + private fun translateFloatGreaterOrEqualJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { + 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") + } + private fun translateUbyteLessJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { if(rightConstVal!=null) { if(leftConstVal!=null) { @@ -946,12 +950,25 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } - // todo via func args - if(asmgen.options.slowCodegenWarnings) - println("warning: slow stack evaluation used (e22): '==' at ${left.position}") // TODO float - translateExpression(left) - translateExpression(right) - asmgen.out(" jsr floats.equal_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") + if(left is IdentifierReference && right is IdentifierReference) { + val leftName = asmgen.asmVariableName(left) + val rightName = asmgen.asmVariableName(right) + asmgen.out(""" + lda #<$leftName + ldy #>$leftName + sta P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 + lda #<$rightName + ldy #>$rightName + 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") + } } private fun translateFloatNotEqualsJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { @@ -995,12 +1012,25 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } - // todo via func args - if(asmgen.options.slowCodegenWarnings) - println("warning: slow stack evaluation used (e23): '!=' at ${left.position}") // TODO float - translateExpression(left) - translateExpression(right) - asmgen.out(" jsr floats.notequal_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") + if(left is IdentifierReference && right is IdentifierReference) { + val leftName = asmgen.asmVariableName(left) + val rightName = asmgen.asmVariableName(right) + asmgen.out(""" + lda #<$leftName + ldy #>$leftName + sta P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 + lda #<$rightName + ldy #>$rightName + 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") + } } private fun translateStringEqualsJump(left: IdentifierReference, right: IdentifierReference, jumpIfFalseLabel: String) { diff --git a/examples/test.p8 b/examples/test.p8 index b9cb20684..db114e158 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -11,13 +11,13 @@ main { byte ub2 byte bb1 byte bb2 - uword uw1 - uword uw2 + float uw1 + float uw2 word ww1 word ww2 - uw1 = $1000 - uw2 = $1100 + uw1 = 1.1 + uw2 = 2.2 if uw1