mirror of
https://github.com/irmen/prog8.git
synced 2025-02-19 11:31:07 +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 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),
|
"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_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_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),
|
"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),
|
"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_stringcompare" -> funcStringCompare(fcall, resultRegister)
|
||||||
"prog8_lib_square_byte" -> funcSquare(fcall, DataType.UBYTE, resultRegister)
|
"prog8_lib_square_byte" -> funcSquare(fcall, DataType.UBYTE, resultRegister)
|
||||||
"prog8_lib_square_word" -> funcSquare(fcall, DataType.UWORD, 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}")
|
else -> throw AssemblyError("missing asmgen for builtin func ${fcall.name}")
|
||||||
}
|
}
|
||||||
|
|
||||||
return BuiltinFunctions.getValue(fcall.name).returnType
|
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?) {
|
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) {
|
||||||
|
@ -48,10 +48,34 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
"prog8_lib_stringcompare" -> funcStringCompare(call)
|
"prog8_lib_stringcompare" -> funcStringCompare(call)
|
||||||
"prog8_lib_square_byte" -> funcSquare(call, IRDataType.BYTE)
|
"prog8_lib_square_byte" -> funcSquare(call, IRDataType.BYTE)
|
||||||
"prog8_lib_square_word" -> funcSquare(call, IRDataType.WORD)
|
"prog8_lib_square_word" -> funcSquare(call, IRDataType.WORD)
|
||||||
|
"prog8_lib_arraycopy" -> funcArrayCopy(call)
|
||||||
else -> throw AssemblyError("missing builtinfunc for ${call.name}")
|
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 {
|
private fun funcSquare(call: PtBuiltinFunctionCall, resultType: IRDataType): ExpressionCodeResult {
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
val valueTr = exprGen.translateExpression(call.args[0])
|
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)
|
// - pointer[word] replaced by @(pointer+word)
|
||||||
// - @(&var) and @(&var+1) replaced by lsb(var) and msb(var) if var is a word
|
// - @(&var) and @(&var+1) replaced by lsb(var) and msb(var) if var is a word
|
||||||
// - flatten chained assignments
|
// - 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> {
|
override fun before(breakStmt: Break, parent: Node): Iterable<IAstModification> {
|
||||||
fun jumpAfter(stmt: Statement): Iterable<IAstModification> {
|
fun jumpAfter(stmt: Statement): Iterable<IAstModification> {
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package prog8.compiler.astprocessing
|
package prog8.compiler.astprocessing
|
||||||
|
|
||||||
import prog8.ast.*
|
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.statements.*
|
||||||
import prog8.ast.walk.AstWalker
|
import prog8.ast.walk.AstWalker
|
||||||
import prog8.ast.walk.IAstModification
|
import prog8.ast.walk.IAstModification
|
||||||
@ -258,27 +260,7 @@ internal class StatementReorderer(
|
|||||||
errors.err("element size mismatch", assign.position)
|
errors.err("element size mismatch", assign.position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return noModifications
|
||||||
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))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun copyStringValue(assign: Assignment): List<IAstModification> {
|
private fun copyStringValue(assign: Assignment): List<IAstModification> {
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
TODO
|
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()" )
|
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.
|
(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