ir: fix any() all() reverse() sort() on memory mapped arrays and on byte arrays

This commit is contained in:
Irmen de Jong 2023-07-07 17:19:06 +02:00
parent 71261525e8
commit 90c4b00f74
4 changed files with 32 additions and 17 deletions

View File

@ -1,6 +1,5 @@
package prog8.codegen.intermediate package prog8.codegen.intermediate
import prog8.code.StStaticVariable
import prog8.code.ast.* import prog8.code.ast.*
import prog8.code.core.AssemblyError import prog8.code.core.AssemblyError
import prog8.code.core.DataType import prog8.code.core.DataType
@ -119,9 +118,9 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
private fun funcAny(call: PtBuiltinFunctionCall): ExpressionCodeResult { private fun funcAny(call: PtBuiltinFunctionCall): ExpressionCodeResult {
val arrayName = call.args[0] as PtIdentifier val arrayName = call.args[0] as PtIdentifier
val array = codeGen.symbolTable.lookup(arrayName.name) as StStaticVariable // TODO FIX/TEST for memory mapped array val arrayLength = codeGen.symbolTable.getLength(arrayName.name)
val syscall = val syscall =
when (array.dt) { when (arrayName.type) {
DataType.ARRAY_UB, DataType.ARRAY_UB,
DataType.ARRAY_B -> IMSyscall.ANY_BYTE DataType.ARRAY_B -> IMSyscall.ANY_BYTE
DataType.ARRAY_UW, DataType.ARRAY_UW,
@ -133,16 +132,16 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val tr = exprGen.translateExpression(call.args[0]) val tr = exprGen.translateExpression(call.args[0])
addToResult(result, tr, tr.resultReg, -1) addToResult(result, tr, tr.resultReg, -1)
val lengthReg = codeGen.registers.nextFree() val lengthReg = codeGen.registers.nextFree()
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = lengthReg, immediate = array.length), null) addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = lengthReg, immediate = arrayLength), null)
result += codeGen.makeSyscall(syscall, listOf(IRDataType.WORD to tr.resultReg, IRDataType.BYTE to lengthReg), IRDataType.BYTE to tr.resultReg) result += codeGen.makeSyscall(syscall, listOf(IRDataType.WORD to tr.resultReg, IRDataType.BYTE to lengthReg), IRDataType.BYTE to tr.resultReg)
return ExpressionCodeResult(result, IRDataType.BYTE, tr.resultReg, -1) return ExpressionCodeResult(result, IRDataType.BYTE, tr.resultReg, -1)
} }
private fun funcAll(call: PtBuiltinFunctionCall): ExpressionCodeResult { private fun funcAll(call: PtBuiltinFunctionCall): ExpressionCodeResult {
val arrayName = call.args[0] as PtIdentifier val arrayName = call.args[0] as PtIdentifier
val array = codeGen.symbolTable.lookup(arrayName.name) as StStaticVariable // TODO FIX/TEST for memory mapped array val arrayLength = codeGen.symbolTable.getLength(arrayName.name)
val syscall = val syscall =
when(array.dt) { when(arrayName.type) {
DataType.ARRAY_UB, DataType.ARRAY_UB,
DataType.ARRAY_B -> IMSyscall.ALL_BYTE DataType.ARRAY_B -> IMSyscall.ALL_BYTE
DataType.ARRAY_UW, DataType.ARRAY_UW,
@ -154,7 +153,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val tr = exprGen.translateExpression(call.args[0]) val tr = exprGen.translateExpression(call.args[0])
addToResult(result, tr, tr.resultReg, -1) addToResult(result, tr, tr.resultReg, -1)
val lengthReg = codeGen.registers.nextFree() val lengthReg = codeGen.registers.nextFree()
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = lengthReg, immediate = array.length), null) addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = lengthReg, immediate = arrayLength), null)
result += codeGen.makeSyscall(syscall, listOf(IRDataType.WORD to tr.resultReg, IRDataType.BYTE to lengthReg), IRDataType.BYTE to tr.resultReg) result += codeGen.makeSyscall(syscall, listOf(IRDataType.WORD to tr.resultReg, IRDataType.BYTE to lengthReg), IRDataType.BYTE to tr.resultReg)
return ExpressionCodeResult(result, IRDataType.BYTE, tr.resultReg, -1) return ExpressionCodeResult(result, IRDataType.BYTE, tr.resultReg, -1)
} }
@ -287,9 +286,9 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
private fun funcReverse(call: PtBuiltinFunctionCall): ExpressionCodeResult { private fun funcReverse(call: PtBuiltinFunctionCall): ExpressionCodeResult {
val arrayName = call.args[0] as PtIdentifier val arrayName = call.args[0] as PtIdentifier
val array = codeGen.symbolTable.lookup(arrayName.name) as StStaticVariable // TODO FIX/TEST for memory mapped array val arrayLength = codeGen.symbolTable.getLength(arrayName.name)
val syscall = val syscall =
when(array.dt) { when(arrayName.type) {
DataType.ARRAY_UB, DataType.ARRAY_B, DataType.STR -> IMSyscall.REVERSE_BYTES DataType.ARRAY_UB, DataType.ARRAY_B, DataType.STR -> IMSyscall.REVERSE_BYTES
DataType.ARRAY_UW, DataType.ARRAY_W -> IMSyscall.REVERSE_WORDS DataType.ARRAY_UW, DataType.ARRAY_W -> IMSyscall.REVERSE_WORDS
DataType.ARRAY_F -> IMSyscall.REVERSE_FLOATS DataType.ARRAY_F -> IMSyscall.REVERSE_FLOATS
@ -300,16 +299,16 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val tr = exprGen.translateExpression(call.args[0]) val tr = exprGen.translateExpression(call.args[0])
addToResult(result, tr, tr.resultReg, -1) addToResult(result, tr, tr.resultReg, -1)
val lengthReg = codeGen.registers.nextFree() val lengthReg = codeGen.registers.nextFree()
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = lengthReg, immediate = if(array.dt==DataType.STR) array.length!!-1 else array.length), null) addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = lengthReg, immediate = if(arrayName.type==DataType.STR) arrayLength!!-1 else arrayLength), null)
result += codeGen.makeSyscall(syscall, listOf(IRDataType.WORD to tr.resultReg, IRDataType.BYTE to lengthReg), null) result += codeGen.makeSyscall(syscall, listOf(IRDataType.WORD to tr.resultReg, IRDataType.BYTE to lengthReg), null)
return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1) return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
} }
private fun funcSort(call: PtBuiltinFunctionCall): ExpressionCodeResult { private fun funcSort(call: PtBuiltinFunctionCall): ExpressionCodeResult {
val arrayName = call.args[0] as PtIdentifier val arrayName = call.args[0] as PtIdentifier
val array = codeGen.symbolTable.lookup(arrayName.name) as StStaticVariable // TODO FIX/TEST for memory mapped array val arrayLength = codeGen.symbolTable.getLength(arrayName.name)
val syscall = val syscall =
when(array.dt) { when(arrayName.type) {
DataType.ARRAY_UB -> IMSyscall.SORT_UBYTE DataType.ARRAY_UB -> IMSyscall.SORT_UBYTE
DataType.ARRAY_B -> IMSyscall.SORT_BYTE DataType.ARRAY_B -> IMSyscall.SORT_BYTE
DataType.ARRAY_UW -> IMSyscall.SORT_UWORD DataType.ARRAY_UW -> IMSyscall.SORT_UWORD
@ -323,7 +322,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val tr = exprGen.translateExpression(call.args[0]) val tr = exprGen.translateExpression(call.args[0])
addToResult(result, tr, tr.resultReg, -1) addToResult(result, tr, tr.resultReg, -1)
val lengthReg = codeGen.registers.nextFree() val lengthReg = codeGen.registers.nextFree()
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = lengthReg, immediate = if(array.dt==DataType.STR) array.length!!-1 else array.length), null) addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = lengthReg, immediate = if(arrayName.type==DataType.STR) arrayLength!!-1 else arrayLength), null)
result += codeGen.makeSyscall(syscall, listOf(IRDataType.WORD to tr.resultReg, IRDataType.BYTE to lengthReg), null) result += codeGen.makeSyscall(syscall, listOf(IRDataType.WORD to tr.resultReg, IRDataType.BYTE to lengthReg), null)
return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1) return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
} }

View File

@ -1,8 +1,7 @@
TODO TODO
==== ====
- Fix possible ST type error: // TODO FIX/TEST for memory mapped array - Fix expericodegen errors (assem, rockrunners)
- Fix expericodegen errors (chess, assem, musicdemo, rockrunners)
... ...

View File

@ -16,6 +16,23 @@ main {
txt.print_ub(44 in othercells) txt.print_ub(44 in othercells)
txt.print_ub('a' in name) txt.print_ub('a' in name)
txt.print_ub('e' in name) txt.print_ub('e' in name)
txt.nl()
txt.print_ub(all(othercells)) ;; TODO fix vm ALL() !
txt.print_ub(any(othercells))
othercells[3] = 0
txt.print_ub(all(othercells)) ;; TODO fix vm ALL() !
txt.print_ub(any(othercells))
reverse(othercells)
sort(othercells)
txt.nl()
txt.print_ub(all(cells))
txt.print_ub(any(cells))
cells[3] = 0
txt.print_ub(all(cells))
txt.print_ub(any(cells))
reverse(cells)
sort(cells)
} }
sub command() { sub command() {

View File

@ -286,7 +286,7 @@ object SysCalls {
val (addressV, lengthV) = getArgValues(callspec.arguments, vm) val (addressV, lengthV) = getArgValues(callspec.arguments, vm)
val address = (addressV as UShort).toInt() val address = (addressV as UShort).toInt()
val length = (lengthV as UByte).toInt() val length = (lengthV as UByte).toInt()
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2) val addresses = IntProgression.fromClosedRange(address, address+length-1, 1)
if(addresses.any { vm.memory.getUB(it).toInt()!=0 }) if(addresses.any { vm.memory.getUB(it).toInt()!=0 })
returnValue(callspec.returns!!, 1, vm) returnValue(callspec.returns!!, 1, vm)
else else
@ -316,7 +316,7 @@ object SysCalls {
val (addressV, lengthV) = getArgValues(callspec.arguments, vm) val (addressV, lengthV) = getArgValues(callspec.arguments, vm)
val address = (addressV as UShort).toInt() val address = (addressV as UShort).toInt()
val length = (lengthV as UByte).toInt() val length = (lengthV as UByte).toInt()
val addresses = IntProgression.fromClosedRange(address, address+length*2-2, 2) val addresses = IntProgression.fromClosedRange(address, address+length-1, 1)
if(addresses.all { vm.memory.getUB(it).toInt()!=0 }) if(addresses.all { vm.memory.getUB(it).toInt()!=0 })
returnValue(callspec.returns!!, 1, vm) returnValue(callspec.returns!!, 1, vm)
else else