refactoring asmassignment code blocks into utility functions

This commit is contained in:
Irmen de Jong 2020-11-15 15:04:23 +01:00
parent 5c9e0c9f51
commit 5ebaaff64b
5 changed files with 41 additions and 63 deletions

View File

@ -14,11 +14,8 @@ import prog8.compiler.target.IAssemblyGenerator
import prog8.compiler.target.IAssemblyProgram
import prog8.compiler.target.c64.AssemblyProgram
import prog8.compiler.target.c64.Petscii
import prog8.compiler.target.c64.codegen.assignment.AsmAssignSource
import prog8.compiler.target.c64.codegen.assignment.AsmAssignTarget
import prog8.compiler.target.c64.codegen.assignment.AsmAssignment
import prog8.compiler.target.c64.codegen.assignment.AssignmentAsmGen
import prog8.compiler.target.c64.codegen.assignment.TargetStorageKind
import prog8.compiler.target.generatedLabelPrefix
import prog8.functions.BuiltinFunctions
import prog8.functions.FSignature
@ -201,11 +198,7 @@ internal class AsmGen(private val program: Program,
private fun assignInitialValueToVar(decl: VarDecl, variableName: List<String>) {
val asmName = asmVariableName(variableName)
val asgn = AsmAssignment(
AsmAssignSource.fromAstSource(decl.value!!, program, this),
AsmAssignTarget(TargetStorageKind.VARIABLE, program, this, decl.datatype, decl.definingSubroutine(), variableAsmName = asmName),
false, decl.position)
assignmentAsmGen.translateNormalAssignment(asgn)
assignmentAsmGen.assignExpressionToVariable(decl.value!!, asmName, decl.datatype, decl.definingSubroutine())
}
private var generatedLabelSequenceNumber: Int = 0
@ -752,6 +745,12 @@ internal class AsmGen(private val program: Program,
internal fun translateNormalAssignment(assign: AsmAssignment) =
assignmentAsmGen.translateNormalAssignment(assign)
internal fun assignExpressionToRegister(expr: Expression, register: RegisterOrPair) =
assignmentAsmGen.assignExpressionToRegister(expr, register)
internal fun assignExpressionToVariable(expr: Expression, asmVarName: String, dt: DataType, scope: Subroutine?) =
assignmentAsmGen.assignExpressionToVariable(expr, asmVarName, dt, scope)
private fun translateSubroutine(sub: Subroutine) {
out("")
outputSourceLine(sub)
@ -1163,16 +1162,12 @@ $label nop""")
val sub = ret.definingSubroutine()!!
val returnType = sub.returntypes.single()
val returnReg = sub.asmReturnvaluesRegisters.single()
val returnValueTarget =
when {
returnReg.registerOrPair!=null -> AsmAssignTarget.fromRegisters(returnReg.registerOrPair, sub, program, this)
else -> throw AssemblyError("normal subroutines can't return value in status register directly")
}
if(returnReg.registerOrPair==null)
throw AssemblyError("normal subroutines can't return value in status register directly")
when (returnType) {
in IntegerDatatypes -> {
val src = AsmAssignSource.fromAstSource(returnvalue, program, this)
assignmentAsmGen.translateNormalAssignment(AsmAssignment(src, returnValueTarget, false, ret.position))
assignmentAsmGen.assignExpressionToRegister(returnvalue, returnReg.registerOrPair)
}
DataType.FLOAT -> {
// return the float value via FAC1
@ -1192,8 +1187,7 @@ $label nop""")
else -> {
// all else take its address and assign that also to AY register pair
val addrofValue = AddressOf(returnvalue as IdentifierReference, returnvalue.position)
val src = AsmAssignSource.fromAstSource(addrofValue, program, this)
assignmentAsmGen.translateNormalAssignment(AsmAssignment(src, returnValueTarget, false, ret.position))
assignmentAsmGen.assignExpressionToRegister(addrofValue, returnReg.registerOrPair)
}
}
}

View File

@ -101,18 +101,9 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
when(func.name) {
"memset" -> {
// use the ROM function of the Cx16
var src = AsmAssignSource.fromAstSource(fcall.args[0], program, asmgen)
var tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, DataType.UWORD, null, variableAsmName = "cx16.r0")
var assign = AsmAssignment(src, tgt, false, Position.DUMMY)
asmgen.translateNormalAssignment(assign)
src = AsmAssignSource.fromAstSource(fcall.args[1], program, asmgen)
tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, DataType.UWORD, null, variableAsmName = "cx16.r1")
assign = AsmAssignment(src, tgt, false, Position.DUMMY)
asmgen.translateNormalAssignment(assign)
src = AsmAssignSource.fromAstSource(fcall.args[2], program, asmgen)
tgt = AsmAssignTarget(TargetStorageKind.REGISTER, program, asmgen, DataType.UBYTE, null, register = RegisterOrPair.A)
assign = AsmAssignment(src, tgt, false, Position.DUMMY)
asmgen.translateNormalAssignment(assign)
asmgen.assignExpressionToVariable(fcall.args[0], "cx16.r0", DataType.UWORD, scope)
asmgen.assignExpressionToVariable(fcall.args[1], "cx16.r1", DataType.UWORD, scope)
asmgen.assignExpressionToRegister(fcall.args[2], RegisterOrPair.A)
val sub = (fcall as FunctionCallStatement).definingSubroutine()!!
asmgen.saveRegister(CpuRegister.X, false, sub)
asmgen.out(" jsr cx16.memory_fill")
@ -129,18 +120,9 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
}
// use the ROM function of the Cx16
var src = AsmAssignSource.fromAstSource(fcall.args[0], program, asmgen)
var tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, DataType.UWORD, null, variableAsmName = "cx16.r0")
var assign = AsmAssignment(src, tgt, false, Position.DUMMY)
asmgen.translateNormalAssignment(assign)
src = AsmAssignSource.fromAstSource(fcall.args[1], program, asmgen)
tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, DataType.UWORD, null, variableAsmName = "cx16.r1")
assign = AsmAssignment(src, tgt, false, Position.DUMMY)
asmgen.translateNormalAssignment(assign)
src = AsmAssignSource.fromAstSource(fcall.args[2], program, asmgen)
tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, DataType.UWORD, null, variableAsmName = "cx16.r2")
assign = AsmAssignment(src, tgt, false, Position.DUMMY)
asmgen.translateNormalAssignment(assign)
asmgen.assignExpressionToVariable(fcall.args[0], "cx16.r0", DataType.UWORD, scope)
asmgen.assignExpressionToVariable(fcall.args[1], "cx16.r1", DataType.UWORD, scope)
asmgen.assignExpressionToVariable(fcall.args[2], "cx16.r2", DataType.UWORD, scope)
val sub = (fcall as FunctionCallStatement).definingSubroutine()!!
asmgen.saveRegister(CpuRegister.X, false, sub)
asmgen.out(" jsr cx16.memory_copy")
@ -995,10 +977,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
if (resultToStack)
asmgen.out(" sta P8ESTACK_LO,x | dex")
} else {
val src = AsmAssignSource.fromAstSource(fcall.args.single(), program, asmgen)
val tgt = AsmAssignTarget.fromRegisters(RegisterOrPair.AY, null, program, asmgen)
val assign = AsmAssignment(src, tgt, false, (fcall as Node).position)
asmgen.translateNormalAssignment(assign)
asmgen.assignExpressionToRegister(fcall.args.single(), RegisterOrPair.AY)
if (resultToStack)
asmgen.out(" tya | sta P8ESTACK_LO,x | dex")
else
@ -1019,10 +998,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
if (resultToStack)
asmgen.out(" sta P8ESTACK_LO,x | dex")
} else {
val src = AsmAssignSource.fromAstSource(fcall.args.single(), program, asmgen)
val tgt = AsmAssignTarget.fromRegisters(RegisterOrPair.AY, null, program, asmgen)
val assign = AsmAssignment(src, tgt, false, (fcall as Node).position)
asmgen.translateNormalAssignment(assign)
asmgen.assignExpressionToRegister(fcall.args.single(), RegisterOrPair.AY)
if (resultToStack)
asmgen.out(" sta P8ESTACK_LO,x | dex")
}

View File

@ -9,10 +9,6 @@ import prog8.ast.statements.Subroutine
import prog8.compiler.AssemblyError
import prog8.compiler.target.CompilationTarget
import prog8.compiler.target.CpuType
import prog8.compiler.target.c64.codegen.assignment.AsmAssignSource
import prog8.compiler.target.c64.codegen.assignment.AsmAssignTarget
import prog8.compiler.target.c64.codegen.assignment.AsmAssignment
import prog8.compiler.target.c64.codegen.assignment.TargetStorageKind
import prog8.compiler.toHex
import prog8.functions.BuiltinFunctions
import kotlin.math.absoluteValue
@ -1730,14 +1726,8 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
}
private fun translateCompareStrings(s1: Expression, operator: String, s2: Expression) {
var src = AsmAssignSource.fromAstSource(s1, program, asmgen)
var tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, DataType.UWORD, null, variableAsmName = "prog8_lib.strcmp_expression._arg_s1")
var assign = AsmAssignment(src, tgt, false, Position.DUMMY)
asmgen.translateNormalAssignment(assign)
src = AsmAssignSource.fromAstSource(s2, program, asmgen)
tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, DataType.UWORD, null, variableAsmName = "prog8_lib.strcmp_expression._arg_s2")
assign = AsmAssignment(src, tgt, false, Position.DUMMY)
asmgen.translateNormalAssignment(assign)
asmgen.assignExpressionToVariable(s1, "prog8_lib.strcmp_expression._arg_s1", DataType.UWORD, null)
asmgen.assignExpressionToVariable(s2, "prog8_lib.strcmp_expression._arg_s2", DataType.UWORD, null)
asmgen.out(" jsr prog8_lib.strcmp_expression") // result of compare is in A
when(operator) {
"==" -> asmgen.out(" and #1 | eor #1 | sta P8ESTACK_LO,x")

View File

@ -1289,4 +1289,18 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
}
}
}
internal fun assignExpressionToRegister(expr: Expression, register: RegisterOrPair) {
val src = AsmAssignSource.fromAstSource(expr, program, asmgen)
val tgt = AsmAssignTarget.fromRegisters(register, null, program, asmgen)
val assign = AsmAssignment(src, tgt, false, expr.position)
translateNormalAssignment(assign)
}
internal fun assignExpressionToVariable(expr: Expression, asmVarName: String, dt: DataType, scope: Subroutine?) {
val src = AsmAssignSource.fromAstSource(expr, program, asmgen)
val tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, dt, scope, variableAsmName = asmVarName)
val assign = AsmAssignment(src, tgt, false, expr.position)
translateNormalAssignment(assign)
}
}

View File

@ -1,11 +1,15 @@
%import textio
%zeropage basicsafe
main {
sub start() {
; TODO breakpoint label is no longer outputted by 64tass ...
%breakpoint
str s1 = "irmen"
str s2 = "hello"
txt.print_ub(s1==s2)
txt.print_ub(s1!=s2)
testX()
}