diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt index 22f0f01fd..27f98d4d5 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt @@ -447,11 +447,11 @@ class AsmGen(internal val program: Program, internal fun translateBuiltinFunctionCallExpression(bfc: BuiltinFunctionCall, resultToStack: Boolean, resultRegister: RegisterOrPair?) = builtinFunctionsAsmGen.translateFunctioncallExpression(bfc, resultToStack, resultRegister) - internal fun translateBuiltinFunctionCallExpression(name: String, args: List, scope: Subroutine): DataType = - builtinFunctionsAsmGen.translateFunctioncall(name, args, false, scope) + private fun translateBuiltinFunctionCallExpression(name: String, singleArg:AsmAssignSource, scope: Subroutine): DataType = + builtinFunctionsAsmGen.translateUnaryFunctioncall(name, singleArg, false, scope) - internal fun translateBuiltinFunctionCallStatement(name: String, args: List, scope: Subroutine) = - builtinFunctionsAsmGen.translateFunctioncall(name, args, true, scope) + private fun translateBuiltinFunctionCallStatement(name: String, singleArg: AsmAssignSource, scope: Subroutine) = + builtinFunctionsAsmGen.translateUnaryFunctioncall(name, singleArg, true, scope) internal fun translateFunctionCall(functionCallExpr: FunctionCallExpression, isExpression: Boolean) = functioncallAsmGen.translateFunctionCall(functionCallExpr, isExpression) @@ -2887,14 +2887,14 @@ $repeatLabel lda $counterVar } } - private fun translateUnaryFunctionCallWithArgSource(target: IdentifierReference, arg: AsmAssignSource, isStatement: Boolean, scope: Subroutine): DataType { + private fun translateUnaryFunctionCallWithArgSource(target: IdentifierReference, singleArg: AsmAssignSource, isStatement: Boolean, scope: Subroutine): DataType { when(val targetStmt = target.targetStatement(program)!!) { is BuiltinFunctionPlaceholder -> { return if(isStatement) { - translateBuiltinFunctionCallStatement(targetStmt.name, listOf(arg), scope) + translateBuiltinFunctionCallStatement(targetStmt.name, singleArg, scope) DataType.UNDEFINED } else { - translateBuiltinFunctionCallExpression(targetStmt.name, listOf(arg), scope) + translateBuiltinFunctionCallExpression(targetStmt.name, singleArg, scope) } } is Subroutine -> { @@ -2903,7 +2903,7 @@ $repeatLabel lda $counterVar // argument via registers val argRegister = targetStmt.asmParameterRegisters.single().registerOrPair!! val assignArgument = AsmAssignment( - arg, + singleArg, AsmAssignTarget.fromRegisters(argRegister, argDt in SignedDatatypes, scope, program, this), false, program.memsizer, target.position ) @@ -2919,7 +2919,7 @@ $repeatLabel lda $counterVar else -> throw AssemblyError("invalid dt") } AsmAssignment( - arg, + singleArg, AsmAssignTarget(TargetStorageKind.REGISTER, program, this, argDt, scope, register = paramReg), false, program.memsizer, target.position ) @@ -2927,7 +2927,7 @@ $repeatLabel lda $counterVar // arg goes via parameter variable val argVarName = asmVariableName(targetStmt.scopedName + targetStmt.parameters.single().name) AsmAssignment( - arg, + singleArg, AsmAssignTarget(TargetStorageKind.VARIABLE, program, this, argDt, scope, argVarName), false, program.memsizer, target.position ) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt index 51af7ab54..f858f9f0b 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt @@ -29,21 +29,21 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, translateFunctioncall(fcall, func, discardResult = true, resultToStack = false, resultRegister = null) } - internal fun translateFunctioncall(name: String, args: List, isStatement: Boolean, scope: Subroutine): DataType { + internal fun translateUnaryFunctioncall(name: String, singleArg: AsmAssignSource, isStatement: Boolean, scope: Subroutine): DataType { val func = BuiltinFunctions.getValue(name) - val argExpressions = args.map { src -> - when(src.kind) { - SourceStorageKind.LITERALNUMBER -> src.number!! - SourceStorageKind.EXPRESSION -> src.expression!! - SourceStorageKind.ARRAY -> src.array!! + val argExpression = + when(singleArg.kind) { + SourceStorageKind.LITERALNUMBER -> singleArg.number!! + SourceStorageKind.EXPRESSION -> singleArg.expression!! + SourceStorageKind.ARRAY -> singleArg.array!! else -> { // TODO make it so that we can assign efficiently from something else as an expression....namely: register(s) // this is useful in pipe expressions for instance, to skip the use of a temporary variable // but for now, just assign it to a temporary variable and use that as a source - val tempvar = asmgen.getTempVarName(src.datatype) + val tempvar = asmgen.getTempVarName(singleArg.datatype) val assignTempvar = AsmAssignment( - src, - AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, src.datatype, scope, variableAsmName = asmgen.asmVariableName(tempvar)), + singleArg, + AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, singleArg.datatype, scope, variableAsmName = asmgen.asmVariableName(tempvar)), false, program.memsizer, Position.DUMMY ) assignAsmGen.translateNormalAssignment(assignTempvar) @@ -53,7 +53,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, ident } } - }.toMutableList() + val argExpressions = mutableListOf(argExpression); val fcall = BuiltinFunctionCall(IdentifierReference(listOf(name), Position.DUMMY), argExpressions, Position.DUMMY) fcall.linkParents(scope) translateFunctioncall(fcall, func, discardResult = false, resultToStack = false, null) diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 444552718..b3a88f44e 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -27,7 +27,6 @@ Compiler: - writeAssembly(): make it possible to actually get rid of the VarDecl nodes by fixing the rest of the code mentioned there. - make everything an expression? (get rid of Statements. Statements are expressions with void return types?). - allow "xxx" * constexpr (where constexpr is not a number literal), now gives expression error not same type -- for the pipe operator: make it 100% syntactic sugar so there's no need for asm codegen like translatePipeExpression - make it possible to inline non-asmsub routines that just contain a single statement (return, functioncall, assignment) but this requires all identifiers in the inlined expression to be changed to fully scoped names. If we can do that why not perhaps also able to inline multi-line subroutines? Why would it be limited to just 1 line? Maybe to protect against code bloat. @@ -35,7 +34,7 @@ Compiler: - simplifyConditionalExpression() should not split expression if it still results in stack-based evaluation, but how does it know? - simplifyConditionalExpression() sometimes introduces needless assignment to r9 tempvar (scenario sought) - consider adding McCarthy evaluation to shortcircuit and and or expressions. First do ifs by splitting them up? Then do expressions that compute a value? -- use more of Result<> and Either<> to handle errors/ nulls better? +- use more of Result<> to handle errors/ nulls better? - make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as ``p8v_``? Or not worth it (most 3 letter opcodes as variables are nonsensical anyway) then we can get rid of the instruction lists in the machinedefinitions as well? - [problematic due to 64tass:] add a compiler option to not remove unused subroutines. this allows for building library programs. But this won't work with 64tass's .proc ... @@ -69,9 +68,11 @@ Optimizations: - VariableAllocator: can we think of a smarter strategy for allocating variables into zeropage, rather than first-come-first-served - translateFunctioncall() in BuiltinFunctionsAsmGen: should be able to assign parameters to a builtin function directly from register(s), this will make the use of a builtin function in a pipe expression more efficient without using a temporary variable + aa = startvalue(1) |> sin8u() |> cos8u() |> sin8u() |> cos8u() + versus: aa = cos8u(sin8u(cos8u(sin8u(startvalue(1))))) <--- this one contains no sta cx16.r9L in between. - AssignmentAsmGen.assignExpression() -> better code gen for assigning boolean comparison expressions - when a for loop's loopvariable isn't referenced in the body, and the iterations are known, replace the loop by a repeatloop but we have no efficient way right now to see if the body references a variable. +- AssignmentAsmGen: "real optimized code for comparison expressions that yield a boolean result value" - automatically convert if statements that test for multiple values (if X==1 or X==2..) to if X in [1,2,..] statements, instead of just a warning. - introduce byte-index operator to avoid index multiplications in loops over arrays? see github issue #4 -- AssignmentAsmGen: "real optimized code for comparison expressions that yield a boolean result value"