mirror of
https://github.com/irmen/prog8.git
synced 2025-02-16 07:31:48 +00:00
preparing for new array copy codegen
This commit is contained in:
parent
68669dbef0
commit
e941d2665a
@ -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),
|
||||
|
@ -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) {
|
||||
|
@ -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])
|
||||
|
@ -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> {
|
||||
|
@ -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> {
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user