From 533090a68e5307baeec77270a59a71d09115974a Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 26 Nov 2023 22:55:17 +0100 Subject: [PATCH] fix expression result register of square, callfar, string compare functions in certain situations --- .../codegen/cpu6502/BuiltinFunctionsAsmGen.kt | 26 +++++++++++----- docs/source/todo.rst | 9 ------ examples/test.p8 | 31 ++++++++++++------- 3 files changed, 38 insertions(+), 28 deletions(-) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt index 97c48232f..0adfed014 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt @@ -81,26 +81,32 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, "rsave" -> funcRsave() "rrestore" -> funcRrestore() "cmp" -> funcCmp(fcall) - "callfar" -> funcCallFar(fcall) - "prog8_lib_stringcompare" -> funcStringCompare(fcall) - "prog8_lib_square_byte" -> funcSquare(fcall, DataType.UBYTE) - "prog8_lib_square_word" -> funcSquare(fcall, DataType.UWORD) + "callfar" -> funcCallFar(fcall, resultRegister) + "prog8_lib_stringcompare" -> funcStringCompare(fcall, resultRegister) + "prog8_lib_square_byte" -> funcSquare(fcall, DataType.UBYTE, resultRegister) + "prog8_lib_square_word" -> funcSquare(fcall, DataType.UWORD, resultRegister) else -> throw AssemblyError("missing asmgen for builtin func ${fcall.name}") } return BuiltinFunctions.getValue(fcall.name).returnType } - private fun funcSquare(fcall: PtBuiltinFunctionCall, resultType: DataType) { + private fun funcSquare(fcall: PtBuiltinFunctionCall, resultType: DataType, resultRegister: RegisterOrPair?) { // square of word value is faster with dedicated routine, square of byte just use the regular multiplication routine. when (resultType) { DataType.UBYTE -> { asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.A) asmgen.out(" tay | jsr math.multiply_bytes") + if(resultRegister!=null) { + assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister, false, fcall.position, null, asmgen), CpuRegister.A, false, false) + } } DataType.UWORD -> { asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY) asmgen.out(" jsr math.square") + if(resultRegister!=null) { + assignAsmGen.assignRegisterpairWord(AsmAssignTarget.fromRegisters(resultRegister, false, fcall.position, null, asmgen), RegisterOrPair.AY) + } } else -> { throw AssemblyError("optimized square only for integer types") @@ -140,9 +146,12 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, sty $remainderVar+1""") } - private fun funcStringCompare(fcall: PtBuiltinFunctionCall) { + private fun funcStringCompare(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?) { asmgen.assignWordOperandsToAYAndVar(fcall.args[0], fcall.args[1], "P8ZP_SCRATCH_W2") asmgen.out(" jsr prog8_lib.strcmp_mem") + if(resultRegister!=null) { + assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister, false, fcall.position, null, asmgen), CpuRegister.A, false, false) + } } private fun funcRsave() { @@ -182,7 +191,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, plp""") } - private fun funcCallFar(fcall: PtBuiltinFunctionCall) { + private fun funcCallFar(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?) { if(asmgen.options.compTarget.name != "cx16") throw AssemblyError("callfar only works on cx16 target at this time") @@ -196,6 +205,9 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, + .word 0 + .byte 0""") // note that by convention the values in A+Y registers are now the return value of the call. + if(resultRegister!=null) { + assignAsmGen.assignRegisterpairWord(AsmAssignTarget.fromRegisters(resultRegister, false, fcall.position, null, asmgen), RegisterOrPair.AY) + } } private fun funcCmp(fcall: PtBuiltinFunctionCall) { diff --git a/docs/source/todo.rst b/docs/source/todo.rst index ae4eb5225..b79ffce3f 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -2,15 +2,6 @@ TODO ==== -- fix wrong result of: - ubyte b = 4 - float c - %asm {{ - nop - }} - c += b*b - which works if c is a uword instead... - - [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 .... ... diff --git a/examples/test.p8 b/examples/test.p8 index dbba2d187..5732c61af 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,19 +1,26 @@ %import textio -%import string +%import floats %zeropage basicsafe main { sub start() { - str[] names = [iso:"irmen", iso:"jurrian", iso:"houtzaagmolen 41", iso:"the Quick Brown Fox jumps Over the LAZY dog!"] - - ; txt.iso() - - uword name - for name in names { - txt.print_ub(string.hash(name)) - txt.spc() - txt.print(name) - txt.nl() - } + ubyte b = 4 + ubyte b2 = 4 + uword w = 4 + uword w2 = 4 + float c + %asm {{ + nop + }} + c += b*b + floats.print_f(c) + txt.nl() + c=0 + %asm {{ + nop + }} + c += w*w + floats.print_f(c) + txt.nl() } }