fix expression result register of square, callfar, string compare functions in certain situations

This commit is contained in:
Irmen de Jong 2023-11-26 22:55:17 +01:00
parent 1dff59e1d6
commit 533090a68e
3 changed files with 38 additions and 28 deletions

View File

@ -81,26 +81,32 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
"rsave" -> funcRsave() "rsave" -> funcRsave()
"rrestore" -> funcRrestore() "rrestore" -> funcRrestore()
"cmp" -> funcCmp(fcall) "cmp" -> funcCmp(fcall)
"callfar" -> funcCallFar(fcall) "callfar" -> funcCallFar(fcall, resultRegister)
"prog8_lib_stringcompare" -> funcStringCompare(fcall) "prog8_lib_stringcompare" -> funcStringCompare(fcall, resultRegister)
"prog8_lib_square_byte" -> funcSquare(fcall, DataType.UBYTE) "prog8_lib_square_byte" -> funcSquare(fcall, DataType.UBYTE, resultRegister)
"prog8_lib_square_word" -> funcSquare(fcall, DataType.UWORD) "prog8_lib_square_word" -> funcSquare(fcall, DataType.UWORD, resultRegister)
else -> throw AssemblyError("missing asmgen for builtin func ${fcall.name}") else -> throw AssemblyError("missing asmgen for builtin func ${fcall.name}")
} }
return BuiltinFunctions.getValue(fcall.name).returnType 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. // square of word value is faster with dedicated routine, square of byte just use the regular multiplication routine.
when (resultType) { when (resultType) {
DataType.UBYTE -> { DataType.UBYTE -> {
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.A) asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.A)
asmgen.out(" tay | jsr math.multiply_bytes") 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 -> { DataType.UWORD -> {
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY) asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY)
asmgen.out(" jsr math.square") asmgen.out(" jsr math.square")
if(resultRegister!=null) {
assignAsmGen.assignRegisterpairWord(AsmAssignTarget.fromRegisters(resultRegister, false, fcall.position, null, asmgen), RegisterOrPair.AY)
}
} }
else -> { else -> {
throw AssemblyError("optimized square only for integer types") throw AssemblyError("optimized square only for integer types")
@ -140,9 +146,12 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
sty $remainderVar+1""") 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.assignWordOperandsToAYAndVar(fcall.args[0], fcall.args[1], "P8ZP_SCRATCH_W2")
asmgen.out(" jsr prog8_lib.strcmp_mem") 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() { private fun funcRsave() {
@ -182,7 +191,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
plp""") plp""")
} }
private fun funcCallFar(fcall: PtBuiltinFunctionCall) { private fun funcCallFar(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?) {
if(asmgen.options.compTarget.name != "cx16") if(asmgen.options.compTarget.name != "cx16")
throw AssemblyError("callfar only works on cx16 target at this time") throw AssemblyError("callfar only works on cx16 target at this time")
@ -196,6 +205,9 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
+ .word 0 + .word 0
+ .byte 0""") + .byte 0""")
// note that by convention the values in A+Y registers are now the return value of the call. // 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) { private fun funcCmp(fcall: PtBuiltinFunctionCall) {

View File

@ -2,15 +2,6 @@
TODO 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 .... - [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
... ...

View File

@ -1,19 +1,26 @@
%import textio %import textio
%import string %import floats
%zeropage basicsafe %zeropage basicsafe
main { main {
sub start() { sub start() {
str[] names = [iso:"irmen", iso:"jurrian", iso:"houtzaagmolen 41", iso:"the Quick Brown Fox jumps Over the LAZY dog!"] ubyte b = 4
ubyte b2 = 4
; txt.iso() uword w = 4
uword w2 = 4
uword name float c
for name in names { %asm {{
txt.print_ub(string.hash(name)) nop
txt.spc() }}
txt.print(name) c += b*b
txt.nl() floats.print_f(c)
} txt.nl()
c=0
%asm {{
nop
}}
c += w*w
floats.print_f(c)
txt.nl()
} }
} }