preparing for new array copy codegen

This commit is contained in:
Irmen de Jong 2024-02-09 00:03:35 +01:00
parent 68669dbef0
commit e941d2665a
6 changed files with 71 additions and 23 deletions

View File

@ -81,6 +81,7 @@ val BuiltinFunctions: Map<String, FSignature> = mapOf(
// cmp returns a status in the carry flag, but not a proper return value
"cmp" to FSignature(false, listOf(FParam("value1", IntegerDatatypesNoBool), FParam("value2", NumericDatatypesNoBool)), null),
"prog8_lib_stringcompare" to FSignature(true, listOf(FParam("str1", arrayOf(DataType.STR)), FParam("str2", arrayOf(DataType.STR))), DataType.BYTE),
"prog8_lib_arraycopy" to FSignature(false, listOf(FParam("source", ArrayDatatypes), FParam("target", ArrayDatatypes)), null),
"prog8_lib_square_byte" to FSignature(true, listOf(FParam("value", arrayOf(DataType.BYTE, DataType.UBYTE))), DataType.UBYTE),
"prog8_lib_square_word" to FSignature(true, listOf(FParam("value", arrayOf(DataType.WORD, DataType.UWORD))), DataType.UWORD),
"abs" to FSignature(true, listOf(FParam("value", NumericDatatypesNoBool)), null),

View File

@ -71,12 +71,35 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
"prog8_lib_stringcompare" -> funcStringCompare(fcall, resultRegister)
"prog8_lib_square_byte" -> funcSquare(fcall, DataType.UBYTE, resultRegister)
"prog8_lib_square_word" -> funcSquare(fcall, DataType.UWORD, resultRegister)
"prog8_lib_arraycopy" -> funcArrayCopy(fcall)
else -> throw AssemblyError("missing asmgen for builtin func ${fcall.name}")
}
return BuiltinFunctions.getValue(fcall.name).returnType
}
private fun funcArrayCopy(fcall: PtBuiltinFunctionCall) {
val source = fcall.args[0] as PtIdentifier
val target = fcall.args[1] as PtIdentifier
// outputAddressAndLengthOfArray(source) // address goes in P8ZP_SCRATCH_W1, number of elements in A
// outputAddressAndLengthOfArray(target) // address goes in P8ZP_SCRATCH_W1, number of elements in A
if(source.type in SplitWordArrayTypes && target.type in SplitWordArrayTypes) {
TODO("split to split array copy $source, $target")
}
else if(source.type in SplitWordArrayTypes) {
require(target.type==DataType.ARRAY_UW || target.type==DataType.ARRAY_W)
TODO("split array to normal array copy $source -> $target")
}
else if(target.type in SplitWordArrayTypes) {
require(source.type==DataType.ARRAY_UW || source.type==DataType.ARRAY_W)
TODO("normal array to split array copy $source -> $target")
}
else {
// normal array to array copy
TODO("normal array to array copy $source -> $target")
}
}
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) {

View File

@ -48,10 +48,34 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
"prog8_lib_stringcompare" -> funcStringCompare(call)
"prog8_lib_square_byte" -> funcSquare(call, IRDataType.BYTE)
"prog8_lib_square_word" -> funcSquare(call, IRDataType.WORD)
"prog8_lib_arraycopy" -> funcArrayCopy(call)
else -> throw AssemblyError("missing builtinfunc for ${call.name}")
}
}
private fun funcArrayCopy(call: PtBuiltinFunctionCall): ExpressionCodeResult {
val source = call.args[0] as PtIdentifier
val target = call.args[1] as PtIdentifier
val sourceLength = codeGen.symbolTable.getLength(source.name)
val targetLength = codeGen.symbolTable.getLength(target.name)
require(sourceLength==targetLength)
if(source.type in SplitWordArrayTypes && target.type in SplitWordArrayTypes) {
TODO("split to split array copy $source, $target")
}
else if(source.type in SplitWordArrayTypes) {
require(target.type==DataType.ARRAY_UW || target.type==DataType.ARRAY_W)
TODO("split array to normal array copy $source -> $target")
}
else if(target.type in SplitWordArrayTypes) {
require(source.type==DataType.ARRAY_UW || source.type==DataType.ARRAY_W)
TODO("normal array to split array copy $source -> $target")
}
else {
// normal array to array copy
TODO("normal array to array copy $source -> $target")
}
}
private fun funcSquare(call: PtBuiltinFunctionCall, resultType: IRDataType): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>()
val valueTr = exprGen.translateExpression(call.args[0])

View File

@ -26,6 +26,22 @@ internal class CodeDesugarer(val program: Program, private val errors: IErrorRep
// - pointer[word] replaced by @(pointer+word)
// - @(&var) and @(&var+1) replaced by lsb(var) and msb(var) if var is a word
// - flatten chained assignments
// - replace array assignments by a call to the builtin function that does this: prog8_lib_arraycopy
override fun after(assignment: Assignment, parent: Node): Iterable<IAstModification> {
val targetArray = assignment.target.identifier?.targetVarDecl(program)
val sourceArray = (assignment.value as? IdentifierReference)?.targetVarDecl(program)
if(targetArray?.isArray==true && sourceArray?.isArray==true) {
val copy = FunctionCallStatement(
IdentifierReference(listOf("prog8_lib_arraycopy"), assignment.position),
mutableListOf(
IdentifierReference(listOf(sourceArray.name), assignment.position),
IdentifierReference(listOf(targetArray.name), assignment.position)
), true, assignment.position)
return listOf(IAstModification.ReplaceNode(assignment, copy, parent))
}
return noModifications
}
override fun before(breakStmt: Break, parent: Node): Iterable<IAstModification> {
fun jumpAfter(stmt: Statement): Iterable<IAstModification> {

View File

@ -1,7 +1,9 @@
package prog8.compiler.astprocessing
import prog8.ast.*
import prog8.ast.expressions.*
import prog8.ast.expressions.ArrayLiteral
import prog8.ast.expressions.BinaryExpression
import prog8.ast.expressions.IdentifierReference
import prog8.ast.statements.*
import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstModification
@ -258,27 +260,7 @@ internal class StatementReorderer(
errors.err("element size mismatch", assign.position)
}
}
if(!errors.noErrors())
return noModifications
if(sourceVar.splitArray && targetVar.splitArray)
TODO("copy split to split array")
if(sourceVar.splitArray)
TODO("copy from split source array to normal")
if(targetVar.splitArray)
TODO("copy from normal to split source array")
val numelements = targetVar.arraysize!!.constIndex()!!
val eltsize = program.memsizer.memorySize(ArrayToElementTypes.getValue(sourceVar.datatype))
val memcopy = FunctionCallStatement(IdentifierReference(listOf("sys", "memcopy"), assign.position),
mutableListOf(
AddressOf(sourceIdent, null, assign.position),
AddressOf(identifier, null, assign.position),
NumericLiteral.optimalInteger(numelements*eltsize, assign.position)
), false, assign.position
)
return listOf(IAstModification.ReplaceNode(assign, memcopy, assign.parent))
return noModifications
}
private fun copyStringValue(assign: Assignment): List<IAstModification> {

View File

@ -1,7 +1,9 @@
TODO
====
fix TODO's to assign from and to split arrays (StatementReorderer) -- cannot use simple single memcopy here (6502 + IR)
fix bug: txt.setchr(x, y, @(bytes+$1000)) bytes++ doesn't fill the whole screen only the first 256 bytes or something
fix TODO's to assign from and to split arrays (BuiltinFuncGen + BuiltinFunctionAsmGen) -- cannot use simple single memcopy here (6502 + IR)
assembler, imageviewer is bigger than before (since commit "added string.lstripped() and string.ltrimmed()" )
(after merge in boolean): move all "OperatorXinplace" from expressionGen to AssignmentGen, see if we can get rid of the Result return type.