From 0f9e87d7bbc79fee4374f500d22b06860f94eafd Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 3 May 2022 23:43:38 +0200 Subject: [PATCH] fixed compiler crash when casting float to integer, fixed float to int cast value error on cx16 --- .../cpu6502/assignment/AssignmentAsmGen.kt | 21 ++++++++++++++----- compiler/res/prog8lib/c128/floats.asm | 8 +++---- compiler/res/prog8lib/c128/floats.p8 | 1 + compiler/res/prog8lib/c64/floats.asm | 8 +++---- compiler/res/prog8lib/c64/floats.p8 | 1 + compiler/res/prog8lib/cx16/floats.p8 | 1 + docs/source/todo.rst | 1 - examples/test.p8 | 16 ++++++++------ 8 files changed, 37 insertions(+), 20 deletions(-) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index e840797ee..2a67860cd 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -560,7 +560,14 @@ internal class AssignmentAsmGen(private val program: Program, } if(target.kind==TargetStorageKind.REGISTER) { - assignExpressionToRegister(value, target.register!!, targetDt==DataType.BYTE || targetDt==DataType.WORD) + if(valueDt==DataType.FLOAT && target.datatype!=DataType.FLOAT) { + // have to typecast the float number on the fly down to an integer + assignExpressionToRegister(value, RegisterOrPair.FAC1, target.datatype in SignedDatatypes) + assignTypeCastedFloatFAC1("P8ZP_SCRATCH_W1", target.datatype) + assignVariableToRegister("P8ZP_SCRATCH_W1", target.register!!, target.datatype in SignedDatatypes) + } else { + assignExpressionToRegister(value, target.register!!, targetDt==DataType.BYTE || targetDt==DataType.WORD) + } return } @@ -2294,10 +2301,14 @@ internal class AssignmentAsmGen(private val program: Program, } internal fun assignExpressionToVariable(expr: Expression, asmVarName: String, dt: DataType, scope: Subroutine?) { - val src = AsmAssignSource.fromAstSource(expr, program, asmgen) - val tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, dt, scope, variableAsmName = asmVarName) - val assign = AsmAssignment(src, tgt, false, program.memsizer, expr.position) - translateNormalAssignment(assign) + if(expr.inferType(program) istype DataType.FLOAT && dt!=DataType.FLOAT) { + throw AssemblyError("can't directly assign a FLOAT expression to an integer variable $expr") + } else { + val src = AsmAssignSource.fromAstSource(expr, program, asmgen) + val tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, dt, scope, variableAsmName = asmVarName) + val assign = AsmAssignment(src, tgt, false, program.memsizer, expr.position) + translateNormalAssignment(assign) + } } internal fun assignVariableToRegister(asmVarName: String, register: RegisterOrPair, signed: Boolean) { diff --git a/compiler/res/prog8lib/c128/floats.asm b/compiler/res/prog8lib/c128/floats.asm index 93437a838..92f6afc0f 100644 --- a/compiler/res/prog8lib/c128/floats.asm +++ b/compiler/res/prog8lib/c128/floats.asm @@ -116,8 +116,8 @@ cast_FAC1_as_w_into_ay .proc ; also used for float 2 b ; -- cast fac1 to word into A/Y stx P8ZP_SCRATCH_REG jsr AYINT - ldy $66 - lda $67 + ldy floats.AYINT_facmo + lda floats.AYINT_facmo+1 ldx P8ZP_SCRATCH_REG rts .pend @@ -168,9 +168,9 @@ stack_float2w .proc ; also used for float2b stx P8ZP_SCRATCH_REG jsr AYINT ldx P8ZP_SCRATCH_REG - lda $66 + lda floats.AYINT_facmo sta P8ESTACK_HI,x - lda $67 + lda floats.AYINT_facmo+1 sta P8ESTACK_LO,x dex rts diff --git a/compiler/res/prog8lib/c128/floats.p8 b/compiler/res/prog8lib/c128/floats.p8 index d891ab8c7..950c538a1 100644 --- a/compiler/res/prog8lib/c128/floats.p8 +++ b/compiler/res/prog8lib/c128/floats.p8 @@ -151,6 +151,7 @@ asmsub FREADUY (ubyte value @Y) { }} } +&uword AYINT_facmo = $66 ; $66/$67 contain result of AYINT %asminclude "library:c128/floats.asm" %asminclude "library:c64/floats_funcs.asm" diff --git a/compiler/res/prog8lib/c64/floats.asm b/compiler/res/prog8lib/c64/floats.asm index 7e57a2bb0..77732d472 100644 --- a/compiler/res/prog8lib/c64/floats.asm +++ b/compiler/res/prog8lib/c64/floats.asm @@ -113,8 +113,8 @@ cast_FAC1_as_w_into_ay .proc ; also used for float 2 b ; -- cast fac1 to word into A/Y stx P8ZP_SCRATCH_REG jsr AYINT - ldy $64 - lda $65 + ldy floats.AYINT_facmo + lda floats.AYINT_facmo+1 ldx P8ZP_SCRATCH_REG rts .pend @@ -165,9 +165,9 @@ stack_float2w .proc ; also used for float2b stx P8ZP_SCRATCH_REG jsr AYINT ldx P8ZP_SCRATCH_REG - lda $64 + lda floats.AYINT_facmo sta P8ESTACK_HI,x - lda $65 + lda floats.AYINT_facmo+1 sta P8ESTACK_LO,x dex rts diff --git a/compiler/res/prog8lib/c64/floats.p8 b/compiler/res/prog8lib/c64/floats.p8 index 24c5c30ec..892faf4ea 100644 --- a/compiler/res/prog8lib/c64/floats.p8 +++ b/compiler/res/prog8lib/c64/floats.p8 @@ -174,6 +174,7 @@ asmsub GETADRAY () clobbers(X) -> uword @ AY { }} } +&uword AYINT_facmo = $64 ; $64/$65 contain result of AYINT %asminclude "library:c64/floats.asm" %asminclude "library:c64/floats_funcs.asm" diff --git a/compiler/res/prog8lib/cx16/floats.p8 b/compiler/res/prog8lib/cx16/floats.p8 index 1df5379ac..7b7c0e5bd 100644 --- a/compiler/res/prog8lib/cx16/floats.p8 +++ b/compiler/res/prog8lib/cx16/floats.p8 @@ -161,6 +161,7 @@ asmsub RND() clobbers(A,X,Y) { }} } +&uword AYINT_facmo = $c6 ; $c6/$c7 contain result of AYINT %asminclude "library:c64/floats.asm" %asminclude "library:c64/floats_funcs.asm" diff --git a/docs/source/todo.rst b/docs/source/todo.rst index a95ea0d2e..788137c65 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,7 +3,6 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- compiler: fix crash when print_ub(float as ubyte) - vm: implement float any, all, reverse, sort - vm: fix test fp calc result being 0 - vm: get rid of intermediate floats.xxx() functions somehow, instead generate the float instructions directly? diff --git a/examples/test.p8 b/examples/test.p8 index 1dc492a47..071ba076e 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -8,17 +8,21 @@ main { sub start() { - float fl = -4.567 + float fl = 42.123 float fl2 = fl / 1.0 - floats.print_f(fl2) + txt.print_ub(fl2 as ubyte) txt.nl() - txt.print_ub(fl2 as ubyte) ; TODO fix crash source dt size must be less or equal to target dt size + txt.print_uw(fl2 as uword) txt.nl() - txt.print_b(fl2 as byte) ; TODO fix crash + byte bb = fl2 as byte + txt.print_b(bb) txt.nl() - txt.print_uw(fl2 as uword) ; TODO fix crash + txt.print_b(fl2 as byte) txt.nl() - txt.print_w(fl2 as word) ; TODO fix crash + txt.print_w(fl2 as word) + txt.nl() + word ww = fl2 as word + txt.print_w(ww) txt.nl() ; txt.print("rad 180 = ")