diff --git a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/FunctionCallAsmGen.kt b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/FunctionCallAsmGen.kt index 57a478495..8cbb3383f 100644 --- a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/FunctionCallAsmGen.kt +++ b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/FunctionCallAsmGen.kt @@ -327,8 +327,10 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg val target: AsmAssignTarget = if(parameter.value.type in ByteDatatypes && (register==RegisterOrPair.AX || register == RegisterOrPair.AY || register==RegisterOrPair.XY || register in Cx16VirtualRegisters)) AsmAssignTarget(TargetStorageKind.REGISTER, program, asmgen, parameter.value.type, sub, register = register) - else - AsmAssignTarget.fromRegisters(register, false, sub, program, asmgen) + else { + val signed = parameter.value.type == DataType.BYTE || parameter.value.type == DataType.WORD + AsmAssignTarget.fromRegisters(register, signed, sub, program, asmgen) + } val src = if(valueDt in PassByReferenceDatatypes) { if(value is IdentifierReference) { val addr = AddressOf(value, Position.DUMMY) diff --git a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt index ae2e92cfd..7a0f06a7c 100644 --- a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt +++ b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt @@ -29,6 +29,13 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen translateNormalAssignment(assign) } + internal fun virtualRegsToVariables(origtarget: AsmAssignTarget): AsmAssignTarget { + return if(origtarget.kind==TargetStorageKind.REGISTER && origtarget.register in Cx16VirtualRegisters) { + AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, origtarget.datatype, origtarget.scope, + variableAsmName = "cx16.${origtarget.register!!.name.lowercase()}", origAstTarget = origtarget.origAstTarget) + } else origtarget + } + fun translateNormalAssignment(assign: AsmAssignment) { if(assign.isAugmentable) { augmentableAsmGen.translate(assign) @@ -258,11 +265,12 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen assign.target, false, program.memsizer, assign.position )) + val target = virtualRegsToVariables(assign.target) when(value.operator) { "+" -> {} - "-" -> augmentableAsmGen.inplaceNegate(assign.target, assign.target.datatype) - "~" -> augmentableAsmGen.inplaceInvert(assign.target, assign.target.datatype) - "not" -> augmentableAsmGen.inplaceBooleanNot(assign.target, assign.target.datatype) + "-" -> augmentableAsmGen.inplaceNegate(target, target.datatype) + "~" -> augmentableAsmGen.inplaceInvert(target, target.datatype) + "not" -> augmentableAsmGen.inplaceBooleanNot(target, target.datatype) else -> throw AssemblyError("invalid prefix operator") } } @@ -1067,7 +1075,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen adc #<${target.asmVarname} bcc + iny -+ jsr floats.copy_float""") ++ jsr floats.copy_float""") } else -> throw AssemblyError("weird dt") } diff --git a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AugmentableAssignmentAsmGen.kt b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AugmentableAssignmentAsmGen.kt index b62111925..b440dd25d 100644 --- a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AugmentableAssignmentAsmGen.kt +++ b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/assignment/AugmentableAssignmentAsmGen.kt @@ -9,6 +9,7 @@ import prog8.compiler.target.AssemblyError import prog8.compiler.target.cpu6502.codegen.AsmGen import prog8.compilerinterface.CpuType + internal class AugmentableAssignmentAsmGen(private val program: Program, private val assignmentAsmGen: AssignmentAsmGen, private val asmgen: AsmGen @@ -20,15 +21,16 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, when (val value = assign.source.expression!!) { is PrefixExpression -> { // A = -A , A = +A, A = ~A, A = not A + val target = assignmentAsmGen.virtualRegsToVariables(assign.target) val itype = value.inferType(program) if(!itype.isKnown) throw AssemblyError("unknown dt") val type = itype.getOr(DataType.UNDEFINED) when (value.operator) { "+" -> {} - "-" -> inplaceNegate(assign.target, type) - "~" -> inplaceInvert(assign.target, type) - "not" -> inplaceBooleanNot(assign.target, type) + "-" -> inplaceNegate(target, type) + "~" -> inplaceInvert(target, type) + "not" -> inplaceBooleanNot(target, type) else -> throw AssemblyError("invalid prefix operator") } } @@ -148,7 +150,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, private fun inplaceModification(target: AsmAssignTarget, operator: String, origValue: Expression) { - // the asm-gen code can deal with situations where you want to assign a byte into a word. // it will create the most optimized code to do this (so it type-extends for us). // But we can't deal with writing a word into a byte - explicit typeconversion is required @@ -1158,7 +1159,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, sta $name lda P8ZP_SCRATCH_W2+1 sta $name+1 - """) } + """) + } "<<" -> { asmgen.out(""" ldy $otherName diff --git a/docs/source/todo.rst b/docs/source/todo.rst index a601eacaf..008864581 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,6 +3,8 @@ TODO For next compiler release (7.4) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Figure out in asmsub6502ArgsHaveRegisterClobberRisk if prefixexpression is clobbering or not + Use GoSub to call subroutines (statements): - [DONE] allow separate assigns to subroutine's parameter variables / registers